Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coordinate labels (Cartesian, cylindrical, polar, spherical) #34

Merged
merged 33 commits into from
Mar 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6e74017
SignedTuple class, for future reference
mhvwerts Mar 26, 2024
76f3013
Entering the 'Upside Down': xvalue -> _xvalue etc. pytest OK.
mhvwerts Mar 26, 2024
8849671
xvalue, yvalue, zvalue as properties
mhvwerts Mar 26, 2024
467168d
rvalue, zvalue for FaceVariable in cylindrical grids
mhvwerts Mar 27, 2024
c76ee47
thetavalue, phivalue as properties of FaceVariable
mhvwerts Mar 27, 2024
8a96334
reorganize
mhvwerts Mar 27, 2024
31f855a
removed copyCellVariable already handled by CellVariable.copy() method
mhvwerts Mar 27, 2024
db8555b
get_CellVariable_profile1D -> CellVariable.plotprofile() method
mhvwerts Mar 27, 2024
e9635ba
get_CellVariable_profile2D -> CellVariable.plotprofile() method
mhvwerts Mar 27, 2024
1cc407a
get_CellVariable_profile3D -> CellVariable.plotprofile() method
mhvwerts Mar 27, 2024
15ebbdb
domainInt() -> CellVariable.domainIntegral()
mhvwerts Mar 27, 2024
ec02b03
cellVolume -> cellVolumes variant
mhvwerts Mar 27, 2024
f5e3530
keep cellLocations intact
mhvwerts Mar 27, 2024
cb96b62
document coordinate labels
mhvwerts Mar 28, 2024
71c5183
Entering the Upside Down again...
mhvwerts Mar 28, 2024
515e296
internal .z becomes ._z
mhvwerts Mar 28, 2024
6437f08
internal .y becomes ._y
mhvwerts Mar 28, 2024
793415e
internal .x becomes _x (pytest OK)
mhvwerts Mar 28, 2024
4dfafca
docstrings for mesh classes and paving the way for conventional coord…
mhvwerts Mar 28, 2024
4144851
__str__() and __repr__() in mesh.py
mhvwerts Mar 28, 2024
1774efd
We have an 'x' coordinate label. Test script still needed.
mhvwerts Mar 28, 2024
1f076b3
Bump version
mhvwerts Mar 28, 2024
1622521
We have an 'r'.
mhvwerts Mar 29, 2024
1a7b24b
Consolidate before refactoring attempt
mhvwerts Mar 29, 2024
7111857
Refactoring of CellSize, CellLocation, FaceLocation code.
mhvwerts Mar 29, 2024
074ff9b
Non standard __repr__() for user-friendliness
mhvwerts Mar 29, 2024
67a1990
We have a 'z'.
mhvwerts Mar 29, 2024
e9bd015
Fix docstring
mhvwerts Mar 29, 2024
d766103
We have a 'y' (plus example scripts working with the new coord. labels)
mhvwerts Mar 29, 2024
5825a37
We have a 'theta' with pytest OK, but we do not test much yet.
mhvwerts Mar 29, 2024
fc8fd19
We have a 'phi' (but again not much tested there).
mhvwerts Mar 29, 2024
5c0a79b
The mesh coordinate labels should probably be read-only.
mhvwerts Mar 29, 2024
286248a
Small correction.
mhvwerts Mar 29, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions docs/coordinate_labels.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Labeling of coordinates


## User (API) coordinate labels and internal labels

*If you are a casual user of this library, you do not need to read this section. It details the inner workings of PyFVTool, but this knowledge is not required to simply use the PyFVTool as a library.*

Internally, PyFVTool always uses an (x, y, z) convention for labeling coordinates, even for cylindrical and spherical grids. This is for historical reasons and efficient coding. Also, these three dimensions are always present, even in the case for 1D and 2D grids.

To avoid confusing situations on the user (API) side, PyFVTool uses conventional coordinate labels towards the user, and then translates these to the appropriate internal labels. Thus, for 1D Cartesian grids, there is (x), for 1D cylindrical grids, there is \(r\), for 2D Cartesian grids, there is (x, y), for 2D cylindrical grids, there is (r, z), and so on.

The 'internal' labeling uses a preceding underscore to distinguish it from the 'user' labeling. This follows the Python convention that indicates that these variables (properties) are internal to PyFVTool (private) and should not be touched by the external user.

Below, the correspondence between the (conventional) user coordinate labels and the internal (underscored) variable names is given for the different meshes.


### Cell and mesh properties

All mesh objects (subclasses of `MeshStructure`) have composite properties `cellsize`, `cellcenters` and `facecenters` which are defined along each of the coordinates defined by the specific grid of the mesh.

For instance, the mesh `Grid2D` has `Grid2D.cellsize.x`, `Grid2D.cellsize.y` , `Grid2D.cellcenters.x` and so on. These are the coordinates labeled according to the 'user' convention. They correspond, in this case, to internal variables `._x` and `._y` .

The correspondence between conventional user coordinate labels and the internal variable names is as given in the table.


| |`_x`|`_y` |`_z` |
|-------------------|----|-------|-----|
|`Grid1D` |`x` | | |
|`CylindricalGrid1D`|`r` | | |
|`SphericalGrid1D` |`r` | | |
|`Grid2D` |`x` |`y` | |
|`CylindricalGrid2D`|`r` |`z` | |
|`PolarGrid2D` |`r` |`theta`| |
|`Grid3D` |`x` |`y` |`z` |
|`CylindricalGrid3D`|`r` |`theta`|`z` |
|`SphericalGrid3D` |`r` |`theta`|`phi`|

`SphericalGrid1D` has not yet been implemented.





### FaceVariable

`FaceVariable` objects handle vectorial quantities, defined with respect to the specific mesh coordinate system. Each of the components of the vector is in a separate variable (property) of the object, referred to as xvalue, rvalue and so on. The relation between the conventional user labels of the vector components of the vector and the internal variable names is listed in the table.

| |`_xvalue`|`_yvalue` |`_zvalue` |
|-------------------|---------|------------|----------|
|`Grid1D` |`xvalue` | | |
|`CylindricalGrid1D`|`rvalue` | | |
|`SphericalGrid1D` |`rvalue` | | |
|`Grid2D` |`xvalue` |`yvalue` | |
|`CylindricalGrid2D`|`rvalue` |`zvalue` | |
|`PolarGrid2D` |`rvalue` |`thetavalue`| |
|`Grid3D` |`xvalue` |`yvalue` |`zvalue` |
|`CylindricalGrid3D`|`rvalue` |`thetavalue`|`zvalue` |
|`SphericalGrid3D` |`rvalue` |`thetavalue`|`phivalue`|

`SphericalGrid1D` has not yet been implemented.


203 changes: 121 additions & 82 deletions examples-notebooks/PyFVTool-introduction-demo.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,24 @@
"name": "stdout",
"output_type": "stream",
"text": [
"dims : [10]\n",
"cellsize : x : [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]\n",
"y : [0.]\n",
"z : [0.]\n",
"dims: [10]\n",
"cellsize: _x: [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]\n",
"_y: [0.]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x'}\n",
"\n",
"cellcenters : x : [0.05 0.15 0.25 0.35 0.45 0.55 0.65 0.75 0.85 0.95]\n",
"y : [0.]\n",
"z : [0.]\n",
"cellcenters: _x: [0.05 0.15 0.25 0.35 0.45 0.55 0.65 0.75 0.85 0.95]\n",
"_y: [0.]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x'}\n",
"\n",
"facecenters : x : [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]\n",
"y : [0.]\n",
"z : [0.]\n",
"facecenters: _x: [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]\n",
"_y: [0.]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x'}\n",
"\n",
"corners : [1]\n",
"edges : [1]\n",
"corners: [1]\n",
"edges: [1]\n",
"\n"
]
}
Expand Down Expand Up @@ -102,38 +105,45 @@
" | Grid1D(*args)\n",
" |\n",
" | Mesh based on a 1D Cartesian grid (x)\n",
" | =====================================\n",
" |\n",
" | Method resolution order:\n",
" | Grid1D\n",
" | MeshStructure\n",
" | builtins.object\n",
" | This class can be instantiated in different ways: from a list of cell face\n",
" | locations or from the number of cells and domain length.\n",
" |\n",
" | Methods defined here:\n",
" | Instantiation Options:\n",
" | ----------------------\n",
" | - Grid1D(Nx, Lx)\n",
" | - Grid1D(face_locationsX)\n",
" |\n",
" | __init__(self, *args)\n",
" | Create a Grid1D mesh object from a list of cell face locations or from\n",
" | number of cells and domain length.\n",
" |\n",
" | Parameters\n",
" | ----------\n",
" | Parameters\n",
" | ----------\n",
" | Grid1D(Nx, Lx)\n",
" | Nx : int\n",
" | Number of cells in the x direction.\n",
" | Lx : float\n",
" | Length of the domain in the x direction.\n",
" | face_locations : ndarray\n",
" |\n",
" | Grid1D(face_locationsX)\n",
" | face_locationsX : ndarray\n",
" | Locations of the cell faces in the x direction.\n",
" |\n",
" | Returns\n",
" | -------\n",
" | Examples\n",
" | --------\n",
" | >>> import numpy as np\n",
" | >>> from pyfvtool import Grid1D\n",
" | >>> mesh = Grid1D(10, 10.0)\n",
" | >>> print(mesh)\n",
" |\n",
" | Method resolution order:\n",
" | Grid1D\n",
" | A 1D mesh object.\n",
" | MeshStructure\n",
" | builtins.object\n",
" |\n",
" | Examples\n",
" | --------\n",
" | >>> import numpy as np\n",
" | >>> from pyfvtool import Grid1D\n",
" | >>> mesh = Grid1D(10, 10.0)\n",
" | >>> print(mesh)\n",
" | Methods defined here:\n",
" |\n",
" | __init__(self, *args)\n",
" | Initialize self. See help(type(self)) for accurate signature.\n",
" |\n",
" | __repr__(self)\n",
" | Return repr(self).\n",
Expand All @@ -146,7 +156,18 @@
" | __str__(self)\n",
" | Return str(self).\n",
" |\n",
" | shift_origin(self, x=0.0, y=0.0, z=0.0)\n",
" | cellVolumes(self)\n",
" | Get the volumes of all finite volume cells in the mesh\n",
" |\n",
" | Returns\n",
" | -------\n",
" | np.ndarray\n",
" | containing all cell volumes, arranged according to gridcells\n",
" |\n",
" | TODO: these could perhaps be calculated statically, when initializing\n",
" | the mesh.\n",
" |\n",
" | shift_origin(self, _x=0.0, _y=0.0, _z=0.0)\n",
" |\n",
" | visualize(self)\n",
" |\n",
Expand Down Expand Up @@ -187,13 +208,21 @@
" | __init__(self, dims, cellsize, cellcenters, facecenters, corners, edges)\n",
" | Initialize self. See help(type(self)) for accurate signature.\n",
" |\n",
" | __repr__(self)\n",
" | Return repr(self).\n",
" |\n",
" | __str__(self)\n",
" | Return str(self).\n",
" |\n",
" | shift_origin(self, x=0.0, y=0.0, z=0.0)\n",
" | cellVolumes(self)\n",
" | Get the volumes of all finite volume cells in the mesh\n",
" |\n",
" | Returns\n",
" | -------\n",
" | np.ndarray\n",
" | containing all cell volumes, arranged according to gridcells\n",
" |\n",
" | TODO: these could perhaps be calculated statically, when initializing\n",
" | the mesh.\n",
" |\n",
" | shift_origin(self, _x=0.0, _y=0.0, _z=0.0)\n",
" |\n",
" | visualize(self)\n",
" |\n",
Expand Down Expand Up @@ -293,8 +322,14 @@
"Lx, Ly, Lz = float(1.0), float(2.0), float(3.0)\n",
"m = pf.Grid3D(Nx, Ny, Nz, Lx, Ly, Lz)\n",
"\n",
"X, Y, Z = np.meshgrid(m.cellcenters.x, m.cellcenters.y, m.cellcenters.z, indexing='ij')\n",
"Xf, Yf, Zf = np.meshgrid(m.facecenters.x, m.facecenters.y, m.facecenters.z, indexing='ij')"
"X, Y, Z = np.meshgrid(m.cellcenters.x,\n",
" m.cellcenters.y,\n",
" m.cellcenters.z,\n",
" indexing='ij')\n",
"Xf, Yf, Zf = np.meshgrid(m.facecenters.x,\n",
" m.facecenters.y,\n",
" m.facecenters.z, \n",
" indexing='ij')"
]
},
{
Expand All @@ -303,18 +338,14 @@
"id": "f4c714e3-22ce-4b6d-9056-3b1ab09a5c66",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"x : [0.25 0.75]\n",
"y : [0.33333333 1. 1.66666667]\n",
"z : [0.375 1.125 1.875 2.625]\n"
]
},
{
"data": {
"text/plain": []
"text/plain": [
"_x: [0.25 0.75]\n",
"_y: [0.33333333 1. 1.66666667]\n",
"_z: [0.375 1.125 1.875 2.625]\n",
"coordlabels: {'x': '_x', 'y': '_y', 'z': '_z'}"
]
},
"execution_count": 10,
"metadata": {},
Expand Down Expand Up @@ -391,21 +422,24 @@
"name": "stdout",
"output_type": "stream",
"text": [
"domain : dims : [10]\n",
"cellsize : x : [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]\n",
"y : [0.]\n",
"z : [0.]\n",
"domain : dims: [10]\n",
"cellsize: _x: [0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1]\n",
"_y: [0.]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x'}\n",
"\n",
"cellcenters : x : [0.05 0.15 0.25 0.35 0.45 0.55 0.65 0.75 0.85 0.95]\n",
"y : [0.]\n",
"z : [0.]\n",
"cellcenters: _x: [0.05 0.15 0.25 0.35 0.45 0.55 0.65 0.75 0.85 0.95]\n",
"_y: [0.]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x'}\n",
"\n",
"facecenters : x : [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]\n",
"y : [0.]\n",
"z : [0.]\n",
"facecenters: _x: [0. 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1. ]\n",
"_y: [0.]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x'}\n",
"\n",
"corners : [1]\n",
"edges : [1]\n",
"corners: [1]\n",
"edges: [1]\n",
"\n",
"left : a : [1.]\n",
"b : [0.]\n",
Expand Down Expand Up @@ -508,21 +542,24 @@
"name": "stdout",
"output_type": "stream",
"text": [
"domain : dims : [3 4]\n",
"cellsize : x : [0.33333333 0.33333333 0.33333333 0.33333333 0.33333333]\n",
"y : [0.5 0.5 0.5 0.5 0.5 0.5]\n",
"z : [0.]\n",
"domain : dims: [3 4]\n",
"cellsize: _x: [0.33333333 0.33333333 0.33333333 0.33333333 0.33333333]\n",
"_y: [0.5 0.5 0.5 0.5 0.5 0.5]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x', 'y': '_y'}\n",
"\n",
"cellcenters : x : [0.16666667 0.5 0.83333333]\n",
"y : [0.25 0.75 1.25 1.75]\n",
"z : [0.]\n",
"cellcenters: _x: [0.16666667 0.5 0.83333333]\n",
"_y: [0.25 0.75 1.25 1.75]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x', 'y': '_y'}\n",
"\n",
"facecenters : x : [0. 0.33333333 0.66666667 1. ]\n",
"y : [0. 0.5 1. 1.5 2. ]\n",
"z : [0.]\n",
"facecenters: _x: [0. 0.33333333 0.66666667 1. ]\n",
"_y: [0. 0.5 1. 1.5 2. ]\n",
"_z: [0.]\n",
"coordlabels: {'x': '_x', 'y': '_y'}\n",
"\n",
"corners : [ 0 24 5 29]\n",
"edges : [1]\n",
"corners: [ 0 24 5 29]\n",
"edges: [1]\n",
"\n",
"left : a : [1. 1. 1. 1.]\n",
"b : [0. 0. 0. 0.]\n",
Expand Down Expand Up @@ -1294,14 +1331,9 @@
"\n",
"hfig1, ax1 = plt.subplots()\n",
"\n",
"# xx, uu = pyfvm.utilities.get_CellVariable_profile1D(ci[0])\n",
"# ax1.plot(xx, uu, 'b-', label='initial value')\n",
"ax1.plot(x, ca[0], 'bo', label='initial analytic value')\n",
"ax1.plot(x, ci[0].internalCellValues, 'b-', label='initial numerical value')\n",
"\n",
"\n",
"# xx, uu = pyfvm.utilities.get_CellVariable_profile1D(ci[-1])\n",
"# ax1.plot(xx, uu, 'r-', label='final value')\n",
"ax1.plot(x, ca[-1], 'ro', label='final analytic value')\n",
"ax1.plot(x, ci[-1].internalCellValues, 'r-', label='final numerical value')\n",
"\n",
Expand Down Expand Up @@ -1346,7 +1378,6 @@
" global ci\n",
" global ca\n",
" global Nx\n",
" # line.set_data(*pyfvm.utilities.get_CellVariable_profile1D(ci[ii]))\n",
" line.set_data(x, ci[ii].internalCellValues\n",
" circ.set_data(x, ca[ii]) \n",
" return line, circ\n",
Expand Down Expand Up @@ -1816,15 +1847,15 @@
"source": [
"# Solving a 1D diffusion equation with a fixed concentration \n",
"# at the left boundary and a closed boundary on the right side\n",
"Nx = 20 # number of finite volume cells\n",
"Lx = 1.0 # [m] length of the domain \n",
"Nr = 20 # number of finite volume cells\n",
"Lr = 1.0 # [m] length of the domain \n",
"c_left = 1.0 # left boundary concentration\n",
"c_init = 0.0 # initial concentration\n",
"D_val = 1e-5 # diffusion coefficient (gas phase)\n",
"t_simulation = 3600.0 # [s] simulation time\n",
"dt = 60.0 # [s] time step\n",
"\n",
"m1 = pf.Grid1D(Nx, Lx) # mesh object\n",
"m1 = pf.Grid1D(Nr, Lr) # mesh object\n",
"bc = pf.BoundaryConditions(m1) # Neumann boundary condition by default\n",
"\n",
"# switch the left boundary to Dirichlet: fixed concentration\n",
Expand Down Expand Up @@ -1861,6 +1892,14 @@
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "aa3638aa-3ec4-4302-92f5-fd91ae031834",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
Expand Down
Loading