e3prepToFoam: a mesh generator for OpenFOAM

e3prepToFoam: a mesh generator for OpenFOAM
Mechanical Engineering Technical Report 2015/04
Ingo Jahn; Kan Qin
School of Mechanical and Mining Engineering
The University of Queensland.
May 1, 2015
Abstract
e3prepToFoam.py is a utility to convert structured body-conforming multi-block meshes
from the e3prep/Eilmer format to the OpenFOAM foam format. This report is a user-guide
for the mesh conversion tool and provides several examples to help with the conversion. The
tool can perform the following tasks:
• Convert 2-D Eilmer mesh into 1 cell deep 2-D OpenFOAM foam mesh
• Convert 2-D axysimmetric EIlmer mesh into 1 layer thick wedge shaped OpenFOAM
foam mesh
• Convert 3-D Eilmer mesh into 3-D OpenFOAM foam mesh.
1
Introduction
As part of their code collection the CFCFD Group at the University of Queensland distributes
the multi-block structured mesh generator e3prep. The mesh generator allows the generation of
body conforming grids using simple easily scripted python front end. To utilise these capabilities
with OpenFOAM, the grid conversion tool e3prepToFoam has been created. The tool allows the
conversion of structured multi-block e3prep meshes into the OpenFOAM foam format. The tool
also supports the generation of grouped boundary patches to simplify the boundary condition
definition in OpenFOAM.
This report acts is a user guide and theory guide for e3prepToFoam. It is to be read in
conjunction with the Eilmer user guide [1], which describes the mesh generation using e3prep.
1.1
Compatibility
e3prepToFoam uses functions from the CFCFD Group code collection (Eilmer3), the OpenFOAM
distribution [2], python, and C++. The following dependencies exist:
Eilmer3 e3prepToFoam has been included as part of Eilmer code distribution from November
2014 onwards.
OpenFOAM The utility has been tested with OpenFOAM Vers. 2.3 and OpenFOAM-extended
Vers. 3.1.
However it should be compatible with earlier releases also.
1
python The code has a number of python and C++ dependencies. It is recommended to install
the dependencies list from the CFCFD webpage http://cfcfd.mechmining.uq.edu.au/
getting-started.html
1.2
Citing this tool
When using tho tool in simulations that lead to published works, it is requested that the following
works are cited:
• This report to cover the e3prepToFoam.py mesh conversion tool.
Ingo Jahn, Kan Qin (2015), ”e3prepToFoam: a mesh generator for OpenFOAM”, Mechanical Engineering Technical Report 2015/04, pp 1-66, The University of Queensland
• The following report which covers e3prep.py the underlying code used to generate the
mesh.
PA Jacobs, RJ Gollan, DF Potter (2014), ”The Eilmer3 code: user guide and
example book”, Mechanical Engineering Technical Report 2014/04, pp 1-447,
The University of Queensland
2
Distribution and Installation
e3prepToFoam.py is distributed as part of the code collection maintained by the CFCFD Group
at the University of Queensland [3]. This collection is free software: you can redistribute it and/or
modify it under the terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or any later version. This program collection is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details http://www.gnu.org/licenses/.
The code will be automatically installed during a typical build of Eilmer3. Download and
build instructions are available from the CFCFD webpage http://cfcfd.mechmining.uq.edu.
au/.
2.1
Modifying the code
The working version of e3prepToFoam.py is installed in the $HOME/e3bin directory. If you
perform modifications or improvements to the code please submit an updated version together
with a short description of the changes to the authors. Once reviewed the changes will be included
in future versions of the code.
2
3
Using the Tool
3.1
5-minute version for experienced python, e3prep, and OpenFOAM
Users
If you have used e3prep.py and OpenFOAM before, this for you.
3.1.1
Creating the directory structure
e3prepToFoam.py requires the correct OpenFOAM directory structure to function. Either copy
an existing directory structure from an OpenFOAM example or manually create a directory
structure. Once created add a folder titled e3prep to the root (/case) directory of your simulation. The resulting directory and file structure, required for e3prepToFoam to run correctly
is:
case/
0/
constant/
constant/polyMesh
system/
system/ controlDict ← file required
system/ fvSchemes ← file required
system/ fvSolution ← file required
e3prep/ ← added for e3prepToFoam
All files and directories are required, to ensure correct operation. The directories can be empty,
apart from the 3 files in the /system directory listed above.
3.1.2
Creating your job.py file for e3prep
Within the /case/e3prep/ directory, create your typical job.py file as used for e3prep.py. See
examples in section 5 for more details. The key differences to typical Eilmer meshing are:
• set gdata.dimensions = X with X = 2 or 3
• set gdata.axisymetric_flag = X with X = 0 or 1
• setting of gas model is not required. Actual gas model is defined in case/constant/...
• define blocks as usual.
case/0/...
setting of fill condition is not required, as this is defined in
• include identify_block_connections()
• use following command to label external block faces: blk0.bc_list[EAST] = ExtrapolateOutBC(label="NAME
where NAME is one of the following OF_inlet_nn, OF_outlet_nn, OF_wall_nn, OF_symmetry_nn.
In a 2-D mesh only the north, south, west and east faces need to be labelled. See note
below for more details.
• include sketch.prefer_bc_lables_on_faces() to show face labels in svg sketch.
3
• For 2-D meshes keep code to draw .svg file
Note about boundary conditions:
e3prepToFoam does not define boundary conditions. Instead by labelling the block faces using
the names listed above, where nn can be the numbers 00, 01, . . . 10, thee corresponding block
faces are grouped into a single patch consisting of all the faces for OpenFOAM. The correct
boundary conditions, corresponding to a given patch are then set in OpenFOAM in the case/0
directory.
Optionally: Once the job.py file has been generated, to run the following sequence of commands to view the mesh in paraview.
$ e3prep.py --job=job.py --do-svg --openfoam
$ e3post.py --job=job.py --vtk-xml
$ paraview
3.1.3
Running e3prepToFoam.py
The mesh generation and conversion is performed in two steps using the following commands:
$ e3prep.py --job=job.py --do=svg --openfoam ← creates mesh
$ e3prepToFoam.py --job=job.py [--create_0] ← converts mesh to foam
Running the second command, generates the foam mesh, overwriting any mesh that already exists
within the case/constant/polymesh directory. Adding the --create_0 option additionally
writes files case/0/U and case/0/p corresponding to the boundary face labels defined in the
job.py file. Any existing 0/U and 0/p files are copied to /U.bak and /p.bak. Other initial and
boundary condition files required by the selected solver (e.g. 0/T) need to be generated manually.
At this stage the foam mesh can be viewed using the command:
$ parafoam
Perform the following checks:
• $ checkMesh This provides a quick overview of the quality of the mesh and wether error
occurred in the conversion.
• If patches with names t0000, b0000, n0000, s0000, w0000 or e0000 (where 0000 can be
any 4-digit number) are listed, this indicates that the t-top (b-bottom, n-north, s-south,
w-west, e-east) face of the corresponding block was not labelled in the job.py file.
• Open mesh in paraview ($ paraFoam).
– If paraview crashes when loading mesh, this typically indicates that not all boundary
conditions/initial conditions have been set. (e.g. when performing compressible and
turbulent simulation, files /0/T, /0/nut, etc need to exist for parafoam to work correctly.)
Otherwise de-select all Volume Fields and the mesh alone should load without errors.
– In paraview, check mesh quality, check that external faces have been correctly grouped.
3.1.4
Adjusting the initial fill condition, boundary conditions, gas models, and
other items for OpenFOAM
After the mesh conversion the OpenFOAM simulation is initialised, set-up and started using the
normal OpenFOAM procedure.
4
• Dimensions, initial conditions, and boundary condition for each simulated variable are defined in respective file in the case/0/ directory. Boundary conditions for each grouped face
name defined in the job.py file (e.g. OF_wall_00) must have a corresponding definition.
• Gas and transport properties are set in the case/constant/ directory.
• Simulation properties are set in the case/system/ directory.
5
3.2
Detailed Instructions
Read this section if you are new to python, Eilmer3, or OpenFOAM.
3.2.1
Creating the Directory Structure
e3prepToFoam.py requires the correct OpenFOAM File directory structure to function. The
easiest way approach to generate this is to find an existing OpenFOAM example (or tutorial)
that is similar to the simulation you want to run and to copy the directories. For example to
perform an incompressible simulation using icoFoam you could do the following:
$ of230 ← load the OpenFOAM commands
$ tut ← change to tutorial directroy
$ cd incompressible/icoFoam ← change to directory containing the icoFoam example
$ cp -r cavityClipped/. $FOAM_RUN/cavityClipped ← copy the icoFoam example to your
run directory
$ run ← change to run directory
$ cd cavityClipped ← change to your simulation working directory
$ mkdir e3prep ← create the empty e3prep directory
At the end of this you should have the following directory and file structure. There may be
some extra files in there, but these don’t matter
case/
0/
constant/
constant/polyMesh
system/
system/ controlDict ← file required
system/ fvSchemes ← file required
system/ fvSolution ← file required
e3prep/ ← added for e3prepToFoam
3.2.2
Creating your job.py file for e3prep
Now move to the e3prep directory, where you will create your e3prep mesh.
$ cd e3prep
At this point you can either copy and existing job.py (advised) and modify this or create
your own file. Detailed instructions for the creation of a job.py file and examples are available
in the Eilmer user guide [1]. The job.py file should contain the following parts:
File Header
The file header must include the following lines of code to define the mesh type:
gdata.dimensions =X ← X=2 2-D mesh or X=3 for 3-D mesh
gdata.axisymetric_flag =X ← X=0 for planar 2-D or 3-D or X=1 for 2-D axi-symmetric
6
Block Definition
The core part of the job.py file is the definition paths, which then can be turned into a 2-D
or 3-D block. The Eilmer user guide provides extensive examples for the generation of points
and path segments.
The definition of a typical 2-D block, consisting of north, east, south, west edges defined by
the respective paths (e.g. north_path ) is:
blk0 = Block2D( make patch(north_path, east_path, south_path, west_path),
nni=2, nnj=2, cf_list=[None,]*4)
Do not include definition of boundaries at this point.
After completing the block definitions, include the command
identify_block_connections()
This ensures that the blocks are joint correctly at internal faces.
External Boundary Definition
e3prep or e3prepToFoam does not set boundary conditions for OpenFOAM. Instead it allows
multiple block faces, labelled with one of a list of pre-defined names in job.py to be grouped into
a single boundary patch. The OpenFOAM boundary conditions are then set for each patch in
the case/0 directory after the generation of the foam mesh. Currently the following pre-defined
labels are recognised by e3prepToFoam.
• OF_inlet_00, OF_inlet_01, . . . OF_inlet_10
Suitable for inlets
• OF_outlet_00, OF_outlet_01, . . . OF_outlet_10
Suitable for outlets.
• OF_wall_00, OF_wall_01, . . . OF_wall_10
Suitable for walls.
• OF_symmetry_00, OF_symmetry_01, . . . OF_symmetry_10
Suitable for symmetry planes.
To label faces use the command
blk0.bc_list[EAST] = ExtrapolateOutBC(label="NAME"), where EAST can be any side of the
block and NAME any of the labels from above. Possible blcok sides are: NORTH, EAST, SOUTH, WEST
for 2-D with the addition of TOP and BOTTOM for 3-D. To group multiple faces, simply give them
the same name.
For example add both the north and east face of the block above to the group OF_wall_03, use
the following lines of code:
blk0.bc_list[NORTH] = ExtrapolateOutBC(label="OF_wall_03")
blk0.bc_list[EAST] = ExtrapolateOutBC(label="OF_wall_03")
3.2.3
Running e3prep.py and e3prepToFoam.py
The grid generation and conversion is a 2-stage process.
7
Step 1: Grid Generation
To generate the mesh run:
$ e3prep.py --job=job.py --do=svg --openfoam (from within the e3prep directory)
This will create an e3prep mesh, stored in case/e3prep/grid. If error messages arise in this
stage, fix these before proceeding to the next stage.
Optionally to view the mesh, run
$ e3post.py --job=job.py --vtk-xml
$ paraview
This allows checking of the mesh quality before proceeding to the next step.
Step 2: Grid Conversion
To convert the mesh to the foam format run:
$ e3prepToFoam.py --job=job.py (from within the case/e3prep or case directory)
or $ e3prepToFoam.py --job=job.py --create_0 to auto-generate template boundary conditions for p and U.
WARNING: the --create_0 option replaces existing p and U files and copies the old files to
p.bak and U.bak.
Should running e3prepToFoam fail, a range of on-screen error messages with suggested solutions are provided. Or use the details below:
• Error with mergeMeshes. Try running of230 to load OpenFOAM module
This is typically caused if the OpenFOAM environment hasn’t been loaded and thus OpenFOAM commands are not recognised. Run $ of230 or equivalent command to load the
OpenFOAM environment.
• WARNING: Not all external boundaries were defined in e3prep
The list of block faces (e.g. b0001 is bottom face of block 1) indicate faces on the mesh
external boundaries that have not been given names as described in section 3.2.2.
• WARNING: labels used to define boundary faces do not follow standard OF names
External boundaries were labelled with names that do not match the predefined list. Check
for spelling mistakes and/or change names.
• WARNING: Problem during execution of renumberMesh.
Fixing this error is optional. This error arises if the files in the case/0 directory are missing
or if the patch labels do not match the labels of the the newly generated mesh. The easiest
fix is to re-run with the --create_0 option.
3.2.4
Checking mesh and boundary faces
To check the mesh and the boundary conditions, execute the $ checkMesh command from the
case directory.
The on screen output provides an overview of the mesh. The list of faces should reflect the
external mesh boundaries defined in the job.py file. If there are faces listed with names consisting
of a the letters t, b, n, s, w, e followed by a 4 digit number, this indicates that the corresponding
face of the block identified by the number was not labelled using one of the OpenFOAM names.
If the faces are internal to the mesh, check that identify_block_connections() was included
in job.py.
Further mesh checking is possible using paraview by running the $ paraFoam command from
the case directory.
Before loading the mesh in the paraview GUI, de-select all Volume Fields (e.g. p and U). Then
8
by selecting specific mesh features (E.g. OF wall 00) the corresponding faces that form this
patch can be visualised.
3.2.5
Setting boundary conditions
Boundary conditions for the OpenFOAM simulation are set in the case/0/ directory. In most
cases it is possible to copy file templates from existing OpenFOAM examples.
Incompressible, laminar (e.g. icoFoam)
Running e3prepToFoam with the --create_0 option creates the p or U file required for an
incompressible laminar flow solver, such as icoFoam. The resulting files contain template entries
for all the patches (group of external faces) that were defined using the OF_name_nn labels. To
set up the simulation, simply change the boundary condition to the correct type (e.g. change
zeroGradient to FixedValue) and set the correct boundary values as required.
Other solvers, using more than p and U variable
When using more complex solvers form the OpenFOAM collection initial condition and boundary conditions for additional variables have to be defined. Either modify existing files in case/0
or create new files for each variable. The files must boundaryField definitions for all the external patches grouped using the OF_name_nn names (and FrontBack, Front, Back, Centreline if
present). The p or U files created using --create_0 can be sued as templates.
3.2.6
Adjusting gas models and other items for OpenFOAM
After the mesh conversion the OpenFOAM simulation is set-up and started using the normal
OpenFOAM procedure.
• Gas and transport properties are set in the case/constant/ directory.
• Simulation properties are set in the case/system/ directory.
3.2.7
Running the simulation
At this point you should be ready to run you OpenFOAM simulation.
9
4
Theory behind code
The following sections describe in more detail the theory and steps of the code. As an overview,
the mesh conversion by e3prpToFoam is performed by the following steps:
1. check that suitable directory structure exists
2. execute e3post.py to write individual foam meshes, corresponding to each block generated
by e3prep. Different approaches are used for 3-D, 2-D and axi-symmetric meshes. See 4.1
for details.
3. use OpenFOAM mergeMesh utility to combine individual blocks into single mesh
4. (optional) For axisymmetric meshes, remove zero area faces along centreline
5. use OpenFOAM stichMesh utility to link blocks and remove internal faces
6. (optional) For axisymmetric meshes, automatically group all faces that fall on Centreline
7. (optional) For 2-D meshes automatically group top and bottom faces in group FrontBack
with type empty
8. (optional) For axisymmetric meshes, automatically group top faces in group Front and
bottom faces in group Back with type wedge and faces along x-axis in group Centreline
with type empty.
9. group external faces into patches according to the labels: OF_inlet_nn, OF_outlet_nn,
OF_wall_nn, OF_symmetry_nn, where nn can be numbers 00, 01, . . . 10. See 4.2 for details.
10. (optional) if --create_0 option is used, create /0/p and /0/p files. See 4.3 for details.
11. use OpenFOAM renumberMesh utility to reorder faces and cells for numerical efficiency.
4.1
e3prep → foam block conversion
The conversion of individual e3prep blocks to corresponding foam meshes is carried out by
invoking the --OpenFOAM option of e3post.py. The corresponding code is shown in section 7.1.
Depending on mesh type the following procedures are applied to convert the mesh.
4.1.1
3-D meshes
Eilmer uses a body-fitting structured mesh. A simple 3 × 1 × 2 grid is shown in Figure 1, which
results in 24 vertices (labelled from 0 to 23) and 6 cells (labelled from 0 to 5). This figure is
used to explain how the Eilmer mesh is converted to OpenFOAM format. The OpenFOAM
foam mesh contains 5 files, namely, points, faces, owner, neighbour, and boundary, which are
defined as:
• points
A list of vectors describing the cell vertices, where the first vector in the list represents
vertex 0, the second vector represents vertex 1, etc. Since a structured mesh is used in
Eilmer, the points file is created by sequentially going through the mesh, first in the i
direction, next the j direction and then k direction and writing a corresponding file.
10
23
19
22
18
15
21
5
11
17
14
10
4
20
16
13
7
2
9
3
3
6
12
8
2
1
5
1
0
k
i
4
0
j
Figure 1: Simple structured mesh in Eilmer3.
• faces
A face is an ordered list of points, where a point is referred to by its label. The ordering
of point labels in a face is such that each two neighbouring points are connected by an
edge. Faces are compiled into a list and each face is referred to by its label, representing
its position in the list. The direction of the face normal vector is defined by the right-hand
rule. There are two types of faces within the foam format which must be treated differently
1. Internal face: All faces that connect two cells (and it can never be more than two).
The order of points is selected such, that each face normal points in the positive i, j
or k direction. For example, for the internal face between block 0 and 1 (created by
the four points: 1, 5, 13 and 9) is defined as (1 5 13 9) to ensure that the face normal
vector points in the positive i direction.
2. Boundary face: All faces that belonging to one cell only, since they coincide with the
boundary of the domain. A boundary face is therefore addressed by one cell (only) and
a boundary patch. The ordering of the point labels is such that the face normal points
outside of the computational domain. For example, for the boundary face which is
created by the points: 0 1 9 8, to make sure that the normal vector of this boundary
face points outside of computational domain, the order of points in the label is (0 1 9
8).
Using the above convention all the face labels are written to the faces file.
• owner and neighbour
owner and neighbour files define which cell owns and neighbours each face, respectively.
11
From the definition, owners exist for both internal and boundary faces, but neighbours
only exist for internal face. In Eilmer, cells are numbered in order of i direction first, j
direction next and then k direction. The owner of the specific internal face is defined as
the starting cell based on the right hand rule. For example, for the internal face of (1 5
13 9), its normal vector points from cell 0 to cell 1, in this case, cell 0 is the owner while
cell 1 neighbour and corresponding entries are written to the owner and neighbour files.
For the boundary face of (0 1 9 8), cell 0 is the owner, and there is no neighbour. Here an
entry is only added to the owner file.
• boundary
A list of patches, containing a dictionary entry for each patch. The number of faces and
the starting face for this boundary is provided. Corresponding entries are created for the
six sides of the structured mesh.
These are the typical steps for 3-D mesh conversion from Eilmer3 to OpenFOAM, however,
what if 2-D mesh is generated in Eilmer, how do we convert it into OpenFOAM format since
only 3-D mesh is accepted in OpenFOAM, this will be discussed below.
4.1.2
2-D meshes
Eilmer 2-D meshes are created in the west, east, north, south plane (corresponding to the x-y
plane). To allow conversion of 2-D meshes for simulations in OpenFOAM, which requires a 3-D
mesh, the mesh is first extruded in the downwards direction by 1 × 10−3 m to form a 1 cell deep
3-D mesh. This mesh is then converted as outlined above.
4.1.3
2-D axi-symmetric meshes
Eilmer 2-D axi-symmetric meshes are created in the west, east, north, south plane (corresponding
to the x-y plane). To generate 3-D axi-symmetric mesh as required by OpenFOAM, the Eilmer
mesh is then rotated by ±0.04 rad (2.3◦ ) about the x-axis, to create a wedge shaped, 1 cell wide
mesh centred on the x-y plane. This mesh is then converted as outlined above.
4.2
Grouping of external faces
e3prep or e3prepToFoam does not set boundary conditions. Instead it allows multiple block
faces, labelled with one of a list of pre-defined names in job.py to be grouped into a single
boundary patch. In OpenFOAM boundary conditions are then set for each patch. Currently
the following pre-defined labels are recognised by e3prepToFoam. Depending on type, different
patch types are set.
• OF_inlet_00, OF_inlet_01, . . . OF_inlet_10
Patch is defined with type patch.
• OF_outlet_00, OF_outlet_01, . . . OF_outlet_10
Patch is defined with type patch.
• OF_wall_00, OF_wall_01, . . . OF_wall_10
Patch is defined with type wall.
• OF_symmetry_00, OF_symmetry_01, . . . OF_symmetry_10
Patch is defined with type symmetry.
12
The type of the individual patches can be changed retrospectively by editing the case/constan/polymesh/boundary
file. The names of the individual patches can be changed by editing case/constan/polymesh/boundary
and the respective boundaryField names in the files within the case/0/ directory.
4.3
Creation of boundary conditions (--create 0 option)
If the $ e3prepToFoam.py --job=job.py --create_0 is executed, in addition to converting
the mesh, the initial and boundary condition files for pressure (p) and velocity (U) are created in
the case/0 directory. These files contain dimensions, initial conditions, pre-populated boundary
condition entries for all the labeled external faces, and boundary condition entries for empty
front and rear faces in 2-D meshes.
The p file is initialised as:
• dimensions
[0 2 -2 0 0 0 0] (m2 s−2 ) ← needs to be altered for compressible
• internalField
uniform 0 ← needs to be altered for compressible
• boundaryField template generated based on label type
– OF_inlet, OF_outlet, OF_wall → zeroGradient
– OF_symmetry → symmetry
– FrontBack (automatically set for 2-D) → empty
– Front, Back (automatically set for axi-symmetric) → wedge
– Centreline (automatically set for axi-symmetric) → empty
The U file is initialised as:
• dimensions
[0 1 -1 0 0 0 0] (m s−1 )
• internalField
uniform (0 0 0)
• boundaryField template generated based on label type
– OF_inlet , OF_wall $\rightarrow$ \verbfixedValue’
– OF_outlet’ → zeroGradient
– OF_symmetry → symmetry
– FrontBack (automatically set for 2-D) → empty
– Front, Back (automatically set for axi-symmetric) → wedge
– Centreline (automatically set for axi-symmetric) → empty
If the extra variables are solved, additional files need to be created in the case/0/ directory.
The p and U files can be used as templates.
13
(b) Blocking strategy for mesh and labels as
applied by e3prep.
(a) Domain used for 2-D example and corresponding boundary conditions.
Figure 2: Domain, boundary conditions, blocking strategy, and boundary labels for 2-D example.
5
5.1
Examples
2-D mesh
This example is based on the clippedCavity example (Section 2.1.9 and 2.1.10) from the OpenFOAM Manual [2]. The first step is to copy the existing OpenFOAM cavityClipped example
and to create the e3prep directory (see section 3.2.1).
Meshing
The domain is a rectangle with a quarter missing as shown in Figure 2(a). All lower walls are
stationary and the top wall is moving to the right with a velocity of 1 m /s. For meshing using
e3prep the mesh is split into 3 blocks as shown in Figure 2(b). The external walls are split into
2 groups:
OF_wall_00 for the moving lid
OF_wall_01 for the remaining walls.
The corresponding grid generation file cavityClipped.py is
# c a v i t y C l i p p e d . py
# S im p l e j o b −s p e c i f i c a t i o n
3 # IJ , 27−Apr−2015
1
2
file
f o r e 3 p r e p . py and e3prepToFoam . py
4
5
6
j o b t i t l e = ” c a v i t y C l i p p e d example f o r e3prepToFoam . ”
print j o b t i t l e
7
# We can s e t i n d i v i d u a l a t t r i b u t e s o f t h e g l o b a l d a t a o b j e c t .
gdata . d i m e n s i o n s = 2
10 gdata . t i t l e = j o b t i t l e
11 gdata . a x i s y m m e t r i c f l a g = 0
8
9
12
13
# S e t up 3 r e c t a n g l e s i n t h e ( x , y )−p l a n e by f i r s t
14
defining
#
a
16 b
17 c
18 d
19 e
20 f
21 g
22 h
14
15
t h e c o r n e r nodes
= Node ( 0 . 0 , 0 . 0 ,
= Node ( 0 . 6 , 0 . 0 ,
= Node ( 0 . 0 , 0 . 4 ,
= Node ( 0 . 6 , 0 . 4 ,
= Node ( 1 . 0 , 0 . 4 ,
= Node ( 0 . 0 , 1 . 0 ,
= Node ( 0 . 6 , 1 . 0 ,
= Node ( 1 . 0 , 1 . 0 ,
, then the l i n e s between t h o s e corners .
l a b e l=”A” )
l a b e l=”B” )
l a b e l=”C” )
l a b e l=”D” )
l a b e l=”E” )
l a b e l=”F” )
l a b e l=”F” )
l a b e l=”F” )
23
# Define Lines connecting b l o c k s
ab = L i n e ( a , b ) # h o r i z o n t a l l i n e s ( l o w e s t l e v e l )
26 cd = L i n e ( c , d ) ; de = L i n e ( d , e ) # h o r i z o n t a l
l i n e s ( mid l e v e l )
27 f g = L i n e ( f , g ) ; gh = L i n e ( g , h ) # h o r i z o n t a l
l i n e s ( top l e v e l )
28 ac = L i n e ( a , c ) ;
c f = Line ( c , f ) # v e r t i c a l l i n e s ( l e f t )
29 bd = L i n e ( b , d ) ; dg = L i n e ( d , g ) # v e r t i c a l
l i n e s ( mid )
30 eh = L i n e ( e , h ) # v e r t i c a l
lines ( right )
24
25
31
# Define the blocks , with p a r t i c u l a r d i s c r e t i s a t i o n .
nx0 = 1 2 ; nx1 = 8 ; ny0 = 8 ; ny1 = 12
34 b l k 0 = Block2D ( make patch ( cd , bd , ab , ac ) , n n i=nx0 , n n j=ny0 ,
35
l a b e l=”BLOCK−0” )
c f ) , n n i=nx0 , n n j=ny1 ,
36 b l k 1 = Block2D ( make patch ( f g , dg , cd ,
37
l a b e l=”BLOCK−1” )
38 b l k 2 = Block2D ( make patch ( gh , eh , de , dg ) , n n i=nx1 , n n j=ny1 ,
39
l a b e l=”BLOCK−2” )
32
33
40
41
42
# Cammand t o i d e n t i f y i n t e r n a l f a c e c o n n e c t i o n s
identify block connections ()
43
# S e t boundary c o n d i t i o n s .
b l k 1 . b c l i s t [WEST] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 1 ” ) # l a b e l l i n g w a l l B/C
46 b l k 0 . b c l i s t [WEST] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 1 ” )
47 b l k 0 . b c l i s t [SOUTH] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 1 ” )
48 b l k 0 . b c l i s t [ EAST ] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 1 ” )
49 b l k 2 . b c l i s t [SOUTH] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 1 ” )
50 b l k 2 . b c l i s t [ EAST ] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 1 ” )
51 b l k 1 . b c l i s t [NORTH] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 0 ” )
52 b l k 2 . b c l i s t [NORTH] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 0 ” )
44
45
53
54
55
# command t o w r i t e BC l a b e l s
sketch . p r e f e r b c l a b e l s o n f a c e s ()
56
# p l o t . svg
s k e t c h . x a x i s ( − 0 . 0 5 , 1 . 0 5 , 0 . 2 , −0.05)
59 s k e t c h . y a x i s ( − 0 . 0 5 , 1 . 0 5 , 0 . 2 ,
−0.05)
60 s k e t c h . window ( − 0 . 0 5 , −0.05 , 1 . 0 5 , 1 . 0 5 , 0 . 0 5 , 0 . 0 5 , 0 . 1 7 , 0 . 1 7 )
57
58
The grid generation and grid conversion is performed using the commands (from the e3prep
directory):
e3prep.py --job=cavity3.py --do=svg --openfoam
e3prepToFoam.py --job=cavity3.py --create_0
Running checkMesh provides following summary of the grid:
C r e a t e polyMesh f o r time = 0
Time = 0
Mesh s t a t s
15
points :
internal points :
faces :
internal faces :
cells :
f a c e s per c e l l :
boundary p a t c h e s :
point zones :
face zones :
c e l l zones :
754
0
1384
632
336
6
3
0
2
0
O v e r a l l number o f c e l l s o f each type :
hexahedra :
336
prisms :
0
wedges :
0
pyramids :
0
t e t wedges :
0
tetrahedra :
0
polyhedra :
0
Checking t o p o l o g y . . .
Boundary d e f i n i t i o n OK.
C e l l t o f a c e a d d r e s s i n g OK.
P o i n t u s a g e OK.
Upper t r i a n g u l a r o r d e r i n g OK.
Face v e r t i c e s OK.
Number o f r e g i o n s : 1 (OK) .
Checking patch t o p o l o g y
Patch
FrontBack
OF wall 00
OF wall 01
for multiply connected s u r f a c e s . . .
Faces
Points
Surface topology
672
754
ok ( non−c l o s e d s i n g l y c o n n e c t e d )
20
42
ok ( non−c l o s e d s i n g l y c o n n e c t e d )
60
122
ok ( non−c l o s e d s i n g l y c o n n e c t e d )
Checking geometry . . .
O v e r a l l domain bounding box ( 0 0 0 ) ( 1 1 0 . 0 0 1 )
Mesh ( non−empty , non−wedge ) d i r e c t i o n s ( 1 1 0 )
Mesh ( non−empty ) d i r e c t i o n s ( 1 1 0 )
A l l e d g e s a l i g n e d with or p e r p e n d i c u l a r t o non−empty d i r e c t i o n s .
Boundary o p e n n e s s ( 1 . 3 6 8 1 3 e −19 −2.01195 e −19 −3.88871 e −17) OK.
Max c e l l o p e n n e s s = 8 . 6 7 3 6 2 e −17 OK.
Max a s p e c t r a t i o = 1 OK.
Minimum f a c e a r e a = 5 e −05. Maximum f a c e a r e a = 0 . 0 0 2 5 .
Face a r e a magnitudes
OK.
Min volume = 2 . 5 e −06. Max volume = 2 . 5 e −06. T o t a l volume = 0 . 0 0 0 8 4 .
Cell
volumes OK.
Mesh non−o r t h o g o n a l i t y Max : 0 a v e r a g e : 0
Non−o r t h o g o n a l i t y c h e c k OK.
Face pyramids OK.
Max s k e w n e s s = 1 e −09 OK.
Coupled p o i n t l o c a t i o n match ( a v e r a g e 0 ) OK.
Mesh OK.
End
As can be seen the external faces of the mesh are defined by 3 patches:
FrontBack → front and back face of single cell deep 3-D mesh used by OpenFOAM for 2-D
simulations
OF_wall_00 → moving lid
16
Figure 3: Parts of the mesh visualised in Paraview.
OF_wall_01 → stationary walls at left, bottom, right.
Figure 3 shows visualisation of various mesh components in paraview.
Boundary Conditions
Next the boundary conditions are set in the p and U files. Templates with the correct patch
names have already been create by running the --create_0 option. For the p file all faces are
set to zeroGradient. For the U file the moving lid is set to (1 0 0) and the stationary walls
are set to (0 0 0). The corresponding files are:
/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++ −∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\
| =========
|
|
3 | \\
/ F ield
| OpenFOAM: The Open S o u r c e CFD Toolbox
|
4 |
\\
/
O peration
| Version :
2.3.0
|
5 |
\\ /
A nd
| Web :
www.OpenFOAM. o r g
|
6 |
\\/
M anipulation
|
|
7 \∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/
8 FoamFile
9 {
10
version
2.0;
11
format
ascii ;
12
class
volScalarField ;
13
location
”0” ;
14
object
p;
15 }
16 // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
1
2
17
18
dimensions
[ 0 2 −2 0 0 0 0 ] ;
internalField
uniform 0 ;
19
20
21
22
23
24
25
26
27
28
29
30
31
boundaryField
{
FrontBack
{
type
}
OF wall 00
{
type
}
empty ;
zeroGradient ;
17
OF wall 01
{
type
}
32
33
34
35
36
zeroGradient ;
}
37
38
39
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++ −∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\
| =========
|
|
3 | \\
/ F ield
| OpenFOAM: The Open S o u r c e CFD Toolbox
|
4 |
\\
/
O peration
| Version :
2.3.0
|
5 |
\\ /
A nd
| Web :
www.OpenFOAM. o r g
|
6 |
\\/
M anipulation
|
|
7 \∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/
8 FoamFile
9 {
10
version
2.0;
11
format
ascii ;
12
class
volVectorField ;
13
location
”0” ;
14
object
U;
15 }
16 // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
1
2
17
18
dimensions
[ 0 1 −1 0 0 0 0 ] ;
internalField
uniform (0 0 0) ;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
boundaryField
{
FrontBack
{
type
}
OF wall 00
{
type
value
}
OF wall 01
{
type
value
}
}
empty ;
fixedValue ;
uniform (1 0 0) ;
fixedValue ;
uniform (0 0 0) ;
39
40
41
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
Running the simualtion
The simulation can now be run using the $ icoFoam command. The pressure and velocity
field obtained from the simulation are shown in Figure 4
18
(a) Pressure Field.
(b) Velocity Vectors coloured by magnitude.
Figure 4: Solution of the clippedCavity 2-D example.
19
Figure 5: Fluid domain and block structure for 2-D axi-symmetric convergent-divergent nozzle
5.2
2-D axi-symmetric mesh
This example is based on a convergent divergent nozzle with sinusoidal shape as shown in Figure 5. The nozzle has a length of 2 × L0 = 2 m and starting radius of R0 = 1 m. The nozzle
contour is defined as R = R0 (0.75 + 0.25 cos (x π))
Meshing
The external walls are split into 3 groups:
OF_wall_00 for the outer radius
OF_inlet_00 for inlet (left end)
OF_oulet_00 for inlet (right end)
The corresponding grid generation file condiv.py is
# c o n d i v . py
# S im p l e j o b −s p e c i f i c a t i o n
3 # IJ , 27−Apr−2015
1
2
file
f o r e 3 p r e p . py and e3prepToFoam . py
4
5
6
j o b t i t l e = ” c o n d i v a Convergent−D i v e r g e n t N o z z l e example f o r e3prepToFoam . ”
print j o b t i t l e
7
# We can s e t i n d i v i d u a l a t t r i b u t e s o f t h e g l o b a l d a t a o b j e c t .
gdata . d i m e n s i o n s = 2
10 gdata . t i t l e = j o b t i t l e
11 gdata . a x i s y m m e t r i c f l a g = 1 # s e t e q u a l 1 as a x i −symmetric
8
9
12
# D e f i n e v a r i a b l e s f o r p a r a m e t r i c geometry d e f i n i t i o n
R0 = 1 .
15 L0 = 1 .
16 # S e t up t h e c o r n e r nodes , t h e n t h e
l i n e s between t h o s e corners .
17 a = Node ( 0 . 0
, 0 . 0 , l a b e l=”A” )
18 b = Node ( L0
, 0 . 0 , l a b e l=”B” )
19 c = Node ( 2 . ∗L0 , 0 . 0 ,
l a b e l=”C” )
20 d = Node ( 0 . 0
, R0 , l a b e l=”D” )
21 e = Node ( L0
, 0 . 5 ∗ R0 , l a b e l=”E” )
22 f = Node ( 2 . 0 ∗ L0 , R0 ,
l a b e l=”F” )
13
14
23
# Define s t r a i g h t Lines
ab = L i n e ( a , b ) ; bc = L i n e ( b , c ) # C e n t r e l i n e
26 ad = L i n e ( a , d ) ; be = L i n e ( b , e ) ;
c f = Line ( c , f ) # v e r t i c a l l i n e s
24
25
27
20
# u s e PyFunctionPath t o d e f i n e n o z z l e c o n t o u r
import numpy a s np
30 def path0 ( t ) :
31
global R0
32
global L0
33
x = t ∗ L0
34
y = R0 ∗ ( 0 . 7 5 + 0 . 2 5 ∗ np . c o s ( t ∗ np . p i ) )
35
return x , y , 0 .
28
29
36
37
38
39
40
41
42
def path1 ( t ) :
global R0
global L0
x = (1+ t ) ∗ L0
y = R0 ∗ ( 0 . 7 5 + 0 . 2 5 ∗ np . c o s ( ( t +1.) ∗ np . p i ) )
return x , y , 0 .
43
44
45
# D e f i n e N o z z l e Contours
de = PyFunctionPath ( path0 ) ; e f = PyFunctionPath ( path1 )
46
# Define the blocks , with p a r t i c u l a r d i s c r e t i s a t i o n .
nx0 = 1 0 ; nx1 = 1 0 ; ny0 = 10
49 b l k 0 = Block2D ( make patch ( de , be , ab , ad ) , n n i=nx0 , n n j=ny0 ,
50
f i l l c o n d i t i o n = i n i t i a l , l a b e l=”BLOCK−0” )
51 b l k 1 = Block2D ( make patch ( e f , c f , bc , be ) , n n i=nx1 , n n j=ny0 ,
52
f i l l c o n d i t i o n = i n i t i a l , l a b e l=”BLOCK−1” )
47
48
53
54
55
# Command t o i d e n t i f y i n t e r n a l f a c e c o n n e c t i o n s
identify block connections ()
56
# S e t boundary c o n d i t i o n s .
b l k 0 . b c l i s t [WEST] = ExtrapolateOutBC ( l a b e l=” O F i n l e t 0 0 ” ) # l a b e l l i n g w a l l B/C
59 b l k 0 . b c l i s t [NORTH] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 0 ” )
60 b l k 1 . b c l i s t [NORTH] = ExtrapolateOutBC ( l a b e l=” O F w a l l 0 0 ” )
61 b l k 1 . b c l i s t [ EAST ] = ExtrapolateOutBC ( l a b e l=” O F o u t l e t 0 0 ” )
57
58
62
63
64
# command t o w r i t e BC l a b e l s
sketch . p r e f e r b c l a b e l s o n f a c e s ()
65
# p l o t . svg
s k e t c h . x a x i s ( 0 . 0 , 2 . 0 , 0 . 2 , −0.05)
68 s k e t c h . y a x i s ( 0 . 0 ,
1 . 0 , 0 . 2 , −0.05)
69 s k e t c h . window ( − 0 . 0 5 , −0.05 , 1 . 0 5 , 2 . 0 5 , 0 . 0 5 , 0 . 0 5 , 0 . 1 7 , 0 . 2 7 )
66
67
The grid generation and grid conversion is performed using the commands (from the e3prep
directory):
e3prep.py --job=condiv.py --do=svg
e3prepToFoam.py --job=condiv.py --create_0
Running checkMesh provides following summary of the grid faces/patches:
Checking patch t o p o l o g y
Patch
Back
Front
OF inlet 00
OF outlet 00
OF wall 00
for multiply connected s u r f a c e s . . .
Faces
Points
Surface topology
200
231
ok ( non−c l o s e d s i n g l y
200
231
ok ( non−c l o s e d s i n g l y
10
21
ok ( non−c l o s e d s i n g l y
10
21
ok ( non−c l o s e d s i n g l y
20
42
ok ( non−c l o s e d s i n g l y
connected )
connected )
connected )
connected )
connected )
As can be seen from the output, a Front and Back patch has been added.
21
Boundary Conditions
Next the boundary conditions are set in the p and U files. Templates with the correct patch
names have already been create by running the --create_0 option. For the p file all faces are
set to zeroGradient. For the U file the inlet is set to uniform (1 0 0), the stationary walls are
set to uniform (0 0 0) and the outlet is set to zeroGradient. The corresponding files are:
/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++ −∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\
| =========
|
|
| \\
/ F ield
| OpenFOAM: The Open S o u r c e CFD Toolbox
|
|
\\
/
O peration
| Version :
2.3.0
|
|
\\ /
A nd
| Web :
www.OpenFOAM. o r g
|
|
\\/
M anipulation
|
|
\∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/
FoamFile
{
version
2.0;
format
ascii ;
class
volScalarField ;
location
”0” ;
object
p;
}
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
dimensions
[ 0 2 −2 0 0 0 0 ] ;
internalField
uniform 0 ;
boundaryField
{
Back
{
type
}
Front
{
type
}
OF inlet 00
{
type
}
OF outlet 00
{
type
}
OF wall 00
{
type
}
}
wedge ;
wedge ;
zeroGradient ;
zeroGradient ;
zeroGradient ;
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++ −∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\
| =========
|
|
| \\
/ F ield
| OpenFOAM: The Open S o u r c e CFD Toolbox
|
22
|
\\
/
O peration
| Version :
2.3.0
|
|
\\ /
A nd
| Web :
www.OpenFOAM. o r g
|
|
\\/
M anipulation
|
|
\∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/
FoamFile
{
version
2.0;
format
ascii ;
class
volVectorField ;
location
”0” ;
object
U;
}
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
dimensions
[ 0 1 −1 0 0 0 0 ] ;
internalField
uniform (0 0 0) ;
boundaryField
{
Back
{
type
}
Front
{
type
}
OF inlet 00
{
type
value
}
OF outlet 00
{
type
}
OF wall 00
{
type
value
}
}
wedge ;
wedge ;
fixedValue ;
uniform (1 0 0) ;
zeroGradient ;
fixedValue ;
uniform (0 0 0) ;
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
Mesh and Results
The resulting mesh and solution, as viewed in paraview is shown in Figure 6.
23
(a) Mesh showing inlet, back wegde face, and outer
wall.
(b) Pressure Field.
(c) Velocity Vectors coloured by magnitude.
Figure 6: Mesh and resulting Flow Field of the Convergent-Divergent Nozzle 2-D Axisymmetric
example.
24
5.3
3-D mesh
This example is the heat conduction analysis through a thrust disk. This disk has a inner radius
of 25.4 mm and an outer radius of 50.8 mm, and the fixed temperature is set to west and east
boundary patch, while others are regarded as adiabatic wall.
5.3.1
Meshing
The external wall boundaries are splited into 3 groups:
OF_wall_00 for the adiabatic wall
OF_wall_01 for the west boundary patch
OF_wall_02 for the east boundary patch
The corresponding grid generation file rotor.py is
# Mesh g e n e r a t i o n o f r o t o r
# f o r OpenFOAM s i m u l a t i o n
from math import pi , s i n , cos , s q r t
import numpy
# C o n t r o l Parameter
gdata . d i m e n s i o n s = 3
gdata . t i t l e = ” F o i l t h r u s t b e a r i n g −−Rotor ”
# D e f i n e Geometry
r omega = 2∗ p i ∗ 2 1 0 0 0 . 0 / 6 0 . 0
theta0 = 0.0
theta1 = 15.0/180.0∗ pi
theta2 = 60.0/180.0∗ pi
r1
r2
h1
h2
=
=
=
=
0.0510/2.0
0.1016/2.0
0.0
3 . 0 e−3
# inner radius
# outer radius
# D e f i n e p a r a m e t r i c volume
def makeSimpleBox ( i n i a n g u l a r 1 , i n i a n g u l a r 2 , i n i h 1 , i n i h 2 , r 1 , r 2 ) :
inih1 = ini h1
inih2 = ini h2
ini1 = ini angular1
ini2 = ini angular2
c e n t e r b = Node ( 0 . 0 , 0 . 0 , i n i h 1 )
c e n t e r t = Node ( 0 . 0 , 0 . 0 , i n i h 2 )
up0
up1
up2
up3
up4
up5
up6
up7
=
=
=
=
=
=
=
=
up01
up12
up32
up03
up45
=
=
=
=
=
Vector ( r
Vector ( r
Vector ( r
Vector ( r
Vector ( r
Vector ( r
Vector ( r
Vector ( r
1 ∗ cos ( i n i 1 )
2 ∗ cos ( i n i 1 )
2 ∗ cos ( i n i 2 )
1 ∗ cos ( i n i 2 )
1 ∗ cos ( i n i 1 )
2 ∗ cos ( i n i 1 )
2 ∗ cos ( i n i 2 )
1 ∗ cos ( i n i 2 )
,
,
,
,
,
,
,
,
r
r
r
r
r
r
r
r
1 ∗ sin ( ini1 )
2 ∗ sin ( ini1 )
2 ∗ sin ( ini2 )
1 ∗ sin ( ini2 )
1 ∗ sin ( ini1 )
2 ∗ sin ( ini1 )
2 ∗ sin ( ini2 )
1 ∗ sin ( ini2 )
L i n e ( up0 , up1 )
Arc ( up1 , up2 , c e n t e r b )
L i n e ( up3 , up2 )
Arc ( up0 , up3 , c e n t e r b )
L i n e ( up4 , up5 )
25
,
,
,
,
,
,
,
,
inih1 )
inih1 )
inih1 )
inih1 )
inih2 )
inih2 )
inih2 )
inih2 )
up56
up76
up47
up04
up15
up26
up37
=
=
=
=
=
=
=
Arc ( up5 , up6 , c e n t e r t )
L i n e ( up7 , up6 )
Arc ( up4 , up7 , c e n t e r t )
L i n e ( up0 , up4 )
L i n e ( up1 , up5 )
L i n e ( up2 , up6 )
L i n e ( up3 , up7 )
return WireFrameVolume ( up01 , up12 , up32 , up03 , up45 , up56 ,
up76 , up47 , up04 , up15 , up26 , up37 )
#
c
c
c
set
x =
y =
z =
cluster functions
RobertsClusterFunction (1 ,1 ,1.0)
RobertsClusterFunction (1 ,1 ,1.0)
RobertsClusterFunction (1 ,1 ,1.0)
## b l o c k 0
pvolume0 = makeSimpleBox ( t h e t a 0 , t h e t a 2 , h1 , h2 , r1 , r 2 )
cflist0 = [c x ,c y ,c x ,c y ,c x ,c y ,c x ,c y , c z , c z , c z , c z ];
nx0 = 48 ; ny0= 4 8 ; nz0= 1 0 ;
b l k 0= Block3D ( l a b e l=” r o t o r −0” , n n i=nx0 , n n j=ny0 , nnk=nz0 ,
p a r a m e t r i c v o l u m e=pvolume0 ,
c f l i s t=c f l i s t 0 )
# label
blk0 . b c
blk0 . b c
blk0 . b c
blk0 . b c
blk0 . b c
blk0 . b c
Boundary C o n d i t i o n s
l i s t [NORTH] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 0 ’ )
l i s t [ EAST ] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 1 ’ )
l i s t [SOUTH] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 0 ’ )
l i s t [WEST] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 2 ’ )
l i s t [TOP] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 0 ’ )
l i s t [BOTTOM] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 0 ’ )
sketch . p r e f e r b c l a b e l s o n f a c e s ()
identify block connections ()
The command generatating mesh file is shown in prep-simulation.sh, please note that this
is a 3-D mesh case, the option of --do-svg is only woking for 2-D using e3prep.py. Also, this
3-D mesh is for the heat conduction analysis, the temperature boundary field is only needed in
this case, so the option of --create_0 using e3prepToFoam.py is ignored here.
#! / b i n / b a s h − l
e 3 p r e p . py −−j o b=r o t o r −−openfoam
e3prepToFoam . py −−j o b=r o t o r
5.3.2
Boundary Conditions
Next the boundary conditions are set in the T file. Since the --create_0 option can only
generate p and U for pressure and velocity, respectively, the temperature T file needs to be added
manually, which is shown below. For this T file, the adiabatic wall are set to zeroGradient, the
west boundary patch is set to a fixed temperature of 300 K, while the east boundary patch is set
to a fixed temperature of 340 K.
26
/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++ −∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\
| =========
|
|
| \\
/ F ield
| OpenFOAM: The Open Source CFD Toolbox
|
|
\\
/
O peration
| Version :
2.2.2
|
|
\\ /
A nd
| Web :
www.OpenFOAM. o r g
|
|
\\/
M anipulation
|
|
\∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/
FoamFile
{
version
2.0;
format
ascii ;
class
volScalarField ;
location
”0” ;
object
T;
}
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
dimensions
[0 0 0 1 0 0 0 ] ;
internalField
uniform 300;
boundaryField
{
OF wall 00
{
type
}
OF wall 01
{
type
value
}
OF wall 02
{
type
value
}
}
zeroGradient ;
fixedValue ;
uniform 340;
fixedValue ;
uniform 300;
// ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
5.3.3
Mesh and Results
For the heat conduction analysis of this thrust disk, the solver called laplacianFoam is used,
and the resulting mesh and solution, as viewed in paraview is shown in Figure 7.
27
(a) Mesh for thrust disk.
(b) Temperature field for thrust disk.
Figure 7: Mesh and resulting temperature field of the thrust disk: 3-D example.
28
6
References
References
[1] P.A. Jacobs, R.J. Gollan, D.F. Potter, 2014, The Eilmer3 Code: User Guide and ExampleBook, Mechanical Engineering Report 2014/05, The University of Queensland
[2] OpenFOAM The Open Source CFD Toolbox, Userguide, Version 2.3.1, 3r December 2014,
www.foam.sourceforge.net/docs/Guides-a4/UserGuide.pdf OpenFOAM Foundation
[3] CFCFD, The Compressible Flow Project http://cfcfd.mechmining.uq.edu.au The University of Queensland
7
7.1
Appendix
Addition to e3post.py
Following function has been added to e3post.py to enable conversion of e3prep blocks to corresponding individual foam meshes.
Additions to e3_post.py. This part calls the write_OpenFOAM_files() function to perform
the mesh conversion.
i f uoDict . h a s k e y ( ”−−OpenFOAM” ) :
c o n f i g F i l e N a m e = rootName + ” . c o n f i g ”
cp = C o n f i g P a r s e r . C o n f i g P a r s e r ( )
cp . r e a d ( c o n f i g F i l e N a m e )
a x i s y m m e t r i c f l a g = cp . g e t ( ” g l o b a l d a t a ” , ” a x i s y m m e t r i c f l a g ” )
if verbosity level > 0:
print ” w r i t i n g OpenFOAM g r i d , 2−D o r 3−D”
i f a x i s y m m e t r i c f l a g == 1 :
print ” c r e a t i n g a x i s y m m e t r i c OpenFOAM g r i d ”
g r i d , f l o w , d i m e n s i o n s = r e a d a l l b l o c k s ( rootName , nblock ,
t i n d x , z i p F i l e s , movingGrid )
a d d a u x i l i a r y v a r i a b l e s ( nblock , f l o w , uoDict , omegaz ,
aux var names , c o m p u t e v a r s )
write OpenFOAM files ( rootName , nblock , g r i d , f l o w ,
axisymmetric flag )
Additions to e3_flow.py. This part converts the e3prep block into an unstructured foam
mesh and writes the corresponding mesh files.
#
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
# OpenFOAM−r e l a t e d f u n c t i o n s by Jason (Kan) Qin , J u l y 2 0 1 4 .
def write general OpenFOAM header ( f p ) :
f p . w r i t e ( ”/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++
−∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\\\n” )
29
f p . w r i t e ( ” | ========
f p . w r i t e ( ” | \\
Toolbox
f p . w r i t e ( ” | \\
fp . write ( ” |
\\
|
/ F ield
| \ n” )
/
O peration
/
| \ n” )
| OpenFOAM: The Open S o u r c e CFD
| Version :
| \ n” )
| Web :
A nd
| \ n” )
M anipulation
| \ n” )
2.2.2
www.OpenFOAM. o r g
fp . write ( ” |
\\/
| This f i l e g e n e r a t e d by e 3 p o s t .
py
fp . write ( ”
\∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/\
n” )
f p . w r i t e ( ” FoamFile \n” )
f p . w r i t e ( ” {\n” )
fp . write ( ”
version
2 . 0 ; \ n” )
fp . write ( ”
f ormat
a s c i i ; \ n” )
return
def write general OpenFOAM bottom ( f p ) :
f p . w r i t e ( ” ) \n” )
f p . w r i t e ( ” \n” )
f p . w r i t e ( ” //
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
//\n” )
return
def w r i t e O p e n F O A M u n s t r u c t u r e d f i l e ( fp0 , fp1 , fp2 , fp3 , fp4 , jb , g r i d ,
flow , a x i f l a g ) :
”””
Write t h e OpenFOAM format data from a s i n g l e b l o c k
a s an u n s t r u c t u r e d g r i d o f f i n i t e −volume c e l l s .
S i n c e OpenFOAM o n l y a c c e p t 3D g r i d , t h i s t o o l can be o p e r a t e d i n t h e
f o l l o w i n g 3 modes :
a ) 3D g r i d from E i l m e r −−> 3D foam g r i d
b ) 2D g r i d from E i l m e r −−> 3D foam g r i d with width 0 . 0 0 1 meter
c ) 2D a x i −symmetric g r i d from E i l m e r −−> 3D foam g r i d with a n g l e
+/−0.04 r a d i a n s
: param f p 0 : r e f e r e n c e t o t h e f i l e o b j e c t : p o i n t s
: param f p 1 : r e f e r e n c e t o t h e f i l e o b j e c t : f a c e s
: param f p 2 : r e f e r e n c e t o t h e f i l e o b j e c t : owner
: param f p 3 : r e f e r e n c e t o t h e f i l e o b j e c t : n e i g h b o u r
: param f p 4 : r e f e r e n c e t o t h e f i l e o b j e c t : boundary
: param g r i d : s i n g l e −b l o c k g r i d o f v e r t i c e s
: param f l o w : s i n g l e −b l o c k o f c e l l −c e n t r e f l o w data
: param a x i f l a g : i n t e g r
”””
n i o = g r i d . n i ; n j o = g r i d . n j ; nko = g r i d . nk
n i f = f l o w . n i ; n j f = f l o w . n j ; n k f = f l o w . nk
two D = ( nko == 1 )
i f two D :
nko = 2
30
z set = [0 , 0.001]
SumOfPoints = n i o ∗ n j o ∗ nko
SumOfCells = n i f ∗ n j f ∗ n k f
#
# cells
cells number = 0
c e l l s i d = {}
f o r k in range ( nko −1) :
f o r j in range ( njo −1) :
f o r i in range ( nio −1) :
c e l l s i d [ ( i , j , k) ] = cells number
c e l l s n u m b e r += 1
# points
vtxs number = 0
v t x s i d = {}
f o r k in range ( nko ) :
f o r j in range ( n j o ) :
f o r i in range ( n i o ) :
v t x s i d [ ( i , j , k ) ] = vtxs number
vtxs number += 1
# faces
face number = 0
# s e a r c h i n g i n t e r n a l f a c e s a t k−d i r e c t i o n
i f two D == F a l s e :
f o r k in range ( 1 , nko −1) :
f o r j in range ( njo −1) :
f o r i in range ( nio −1) :
f a c e n u m b e r += 1
# s e a r c h i n g i n t e r n a l f a c e s a t j −d i r e c t i o n
f o r j in range ( 1 , njo −1) :
f o r k in range ( nko −1) :
f o r i in range ( nio −1) :
f a c e n u m b e r += 1
# s e a r c h i n g i n t e r n a l f a c e s a t i −d i r e c t i o n
f o r i in range ( 1 , nio −1) :
f o r k in range ( nko −1) :
f o r j in range ( njo −1) :
f a c e n u m b e r += 1
S u m O fI n te r na l Fa c es = f a c e n u m b e r
# s e a r c h i n g boundary f a c e s a t NORTH f a c e s
NF start = face number
f o r i in range ( nio −1) :
f o r k in range ( nko −1) :
f a c e n u m b e r += 1
NF end = f a c e n u m b e r
SumOfNF = NF end − N F s t a r t
# s e a r c h i n g boundary f a c e s a t WEST f a c e s
WF start = f a c e n u m b e r
f o r k in range ( nko −1) :
f o r j in range ( njo −1) :
f a c e n u m b e r += 1
WF end = f a c e n u m b e r
31
SumOfWF = WF end − WF start
# s e a r c h i n g boundary f a c e s a t EAST f a c e s
EF start = face number
f o r k in range ( nko −1) :
f o r j in range ( njo −1) :
f a c e n u m b e r += 1
EF end = f a c e n u m b e r
SumOfEF = EF end − E F s t a r t
# s e a r c h i n g boundary f a c e s a t SOUTH f a c e s
SF st ar t = face number
f o r i in range ( nio −1) :
f o r k in range ( nko −1) :
f a c e n u m b e r += 1
SF end = f a c e n u m b e r
SumOfSF = SF end − S F s t a r t
# s e a r c h i n g boundary f a c e s a t BOTTOM f a c e s
BF start = face number
f o r i in range ( nio −1) :
f o r j in range ( njo −1) :
f a c e n u m b e r += 1
BF end = f a c e n u m b e r
SumOfBF = BF end − B F s t a r t
# s e a r c h i n g boundary f a c e s a t TOP f a c e s
TF start = face number
f o r i in range ( nio −1) :
f o r j in range ( njo −1) :
f a c e n u m b e r += 1
TF end = f a c e n u m b e r
SumOfTF = TF end − T F s t a r t
SumOfFaces = f a c e n u m b e r
#
# −−−−−−−−−−−−−−−−−−− w r i t i n g f i l e s now −−−−−−−−−−−−−−−−−−−−−−−−−−−−−
# points
fp0 . write ( ”
class
v e c t o r F i e l d ; \ n” )
fp0 . write ( ”
location
\” c o n s t a n t / polyMesh \ ” ; \ n” )
fp0 . write ( ”
object
p o i n t s ; \ n” )
f p 0 . w r i t e ( ” }\n” )
f p 0 . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
f p 0 . w r i t e ( ” \n” )
f p 0 . w r i t e ( ” \n” )
f p 0 . w r i t e ( ”%d\n” % ( SumOfPoints ) )
f p 0 . w r i t e ( ” ( \ n” )
f o r k in range ( nko ) :
f o r j in range ( n j o ) :
f o r i in range ( n i o ) :
i f two D :
i f f l o a t ( a x i f l a g ) == 1 :
x , y , z = uflowz ( grid . x [ i , j , 0 ] ) , uflowz ( grid . y [ i , j
, 0 ] ) , uflowz ( grid . z [ i , j , 0 ] )
i f k == 0 :
y = y ∗ 0.99920010666097792 # = cos (0.04)
z = y ∗ −0.039989334186634161 # = s i n ( 0 . 0 4 )
32
else :
y = y ∗ 0.99920010666097792 # = cos (0.04)
z = y ∗ 0.039989334186634161 # = sin (0.04)
else :
x , y , z = uflowz ( grid . x [ i , j , 0 ] ) , uflowz ( grid . y [ i , j
, 0 ] ) , uflowz ( grid . z [ i , j , 0 ] )
i f k == 1 :
z = z set [1]
else :
x , y , z = uflowz ( grid . x [ i , j , k ] ) , uflowz ( grid . y [ i , j , k ] ) ,
uflowz ( grid . z [ i , j , k ] )
f p 0 . w r i t e ( ”(%e %e %e ) \n” % ( x , y , z ) )
# f a c e s , owner and n e i g h b o u r
# f a c e s header
fp1 . write ( ”
class
f a c e L i s t ; \ n” )
fp1 . write ( ”
location
\” c o n s t a n t / polyMesh \ ” ; \ n” )
fp1 . write ( ”
object
f a c e s ; \ n” )
f p 1 . w r i t e ( ” }\n” )
f p 1 . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
f p 1 . w r i t e ( ” \n” )
f p 1 . w r i t e ( ” \n” )
f p 1 . w r i t e ( ”%d\n” % ( SumOfFaces ) )
f p 1 . w r i t e ( ” ( \ n” )
# owner h e a d e r
fp2 . write ( ”
class
l a b e l L i s t ; \ n” )
fp2 . write ( ”
note
\” n P o i n t s : %d n C e l l s : %d nFaces : %d
n I n t e r n a l F a c e s : %d \ ” ; \ n” %
( SumOfPoints , SumOfCells , SumOfFaces , Su m Of I nt e rn a lF a ce s ) )
fp2 . write ( ”
location
\” c o n s t a n t / polyMesh \ ” ; \ n” )
fp2 . write ( ”
object
owner ; \ n” )
f p 2 . w r i t e ( ” }\n” )
f p 2 . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
f p 2 . w r i t e ( ” \n” )
f p 2 . w r i t e ( ” \n” )
f p 2 . w r i t e ( ”%d\n” % ( SumOfFaces ) )
f p 2 . w r i t e ( ” ( \ n” )
# neighbour header
fp3 . write ( ”
class
l a b e l L i s t ; \ n” )
fp3 . write ( ”
note
\” n P o i n t s : %d n C e l l s : %d nFaces : %d
n I n t e r n a l F a c e s : %d \ ” ; \ n” %
( SumOfPoints , SumOfCells , SumOfFaces , Su m Of I nt e rn a lF a ce s ) )
fp3 . write ( ”
location
\” c o n s t a n t / polyMesh \ ” ; \ n” )
fp3 . write ( ”
object
n e i g h b o u r ; \ n” )
f p 3 . w r i t e ( ” }\n” )
f p 3 . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
f p 3 . w r i t e ( ” \n” )
f p 3 . w r i t e ( ” \n” )
f p 3 . w r i t e ( ”%d\n” % ( Su m Of I nt e rn a lF a ce s ) )
f p 3 . w r i t e ( ” ( \ n” )
#
33
# s e a r c h i n g i n t e r n a l f a c e s a t i −d i r e c t i o n
f o r i in range ( 1 , nio −1) :
f o r j in range ( njo −1) :
f o r k in range ( nko −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s i d [ ( i
, j +1,k ) ] , v t x s i d [ ( i , j +1,k+1) ] , v t x s i d [ ( i , j , k+1) ] ) )
o w n e r i d = c e l l s i d [ ( i −1, j , k ) ]
neighbour id = c e l l s i d [ ( i , j , k) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
f p 3 . w r i t e ( ”%d\n” % ( n e i g h b o u r i d ) )
# s e a r c h i n g i n t e r n a l f a c e s a t j −d i r e c t i o n
f o r j in range ( 1 , njo −1) :
f o r i in range ( nio −1) :
f o r k in range ( nko −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s i d [ ( i
, j , k+1) ] , v t x s i d [ ( i +1, j , k+1) ] , v t x s i d [ ( i +1, j , k ) ] ) )
o w n e r i d = c e l l s i d [ ( i , j −1 ,k ) ]
neighbour id = c e l l s i d [ ( i , j , k) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
f p 3 . w r i t e ( ”%d\n” % ( n e i g h b o u r i d ) )
# s e a r c h i n g i n t e r n a l f a c e s a t k−d i r e c t i o n
i f two D == F a l s e :
f o r k in range ( 1 , nko −1) :
f o r i in range ( nio −1) :
f o r j in range ( njo −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] ,
v t x s i d [ ( i +1, j , k ) ] , v t x s i d [ ( i +1, j +1,k ) ] , v t x s i d [ ( i ,
j +1,k ) ] ) )
o w n e r i d = c e l l s i d [ ( i , j , k−1) ]
neighbour id = c e l l s i d [ ( i , j , k) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
f p 3 . w r i t e ( ”%d\n” % ( n e i g h b o u r i d ) )
#
# s e a r c h i n g boundary f a c e s a t NORTH
j = njo −1
f o r i in range ( nio −1) :
f o r k in range ( nko −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s i d [ ( i , j , k
+1) ] , v t x s i d [ ( i +1, j , k+1) ] , v t x s i d [ ( i +1, j , k ) ] ) )
o w n e r i d = c e l l s i d [ ( i , j −1,k ) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
# s e a r c h i n g boundary f a c e s a t WEST f a c e s
i = 0
f o r k in range ( nko −1) :
f o r j in range ( njo −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s i d [ ( i , j , k
+1) ] , v t x s i d [ ( i , j +1,k+1) ] , v t x s i d [ ( i , j +1,k ) ] ) )
owner id = c e l l s i d [ ( i , j , k) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
# s e a r c h i n g boundary f a c e s a t EAST f a c e s
i = nio −1
f o r k in range ( nko −1) :
f o r j in range ( njo −1) :
34
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s
+1 ,k ) ] , v t x s i d [ ( i , j +1,k+1) ] , v t x s i d [ ( i , j , k+1) ] ) )
o w n e r i d = c e l l s i d [ ( i −1, j , k ) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
# s e a r c h i n g boundary f a c e s a t SOUTH f a c e s
j = 0
f o r i in range ( nio −1) :
f o r k in range ( nko −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s
, k ) ] , v t x s i d [ ( i +1, j , k+1) ] , v t x s i d [ ( i , j , k+1) ] ) )
owner id = c e l l s i d [ ( i , j , k) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
# s e a r c h i n g boundary f a c e s a t BOTTOM f a c e s
k = 0
f o r i in range ( nio −1) :
f o r j in range ( njo −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s
+1 ,k ) ] , v t x s i d [ ( i +1, j +1,k ) ] , v t x s i d [ ( i +1, j , k ) ] ) )
owner id = c e l l s i d [ ( i , j , k) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
# s e a r c h i n g boundary f a c e s a t TOP f a c e s
k = nko−1
f o r i in range ( nio −1) :
f o r j in range ( njo −1) :
f p 1 . w r i t e ( ”4(%d %d %d %d ) \n” % ( v t x s i d [ ( i , j , k ) ] , v t x s
, k ) ] , v t x s i d [ ( i +1, j +1,k ) ] , v t x s i d [ ( i , j +1,k ) ] ) )
o w n e r i d = c e l l s i d [ ( i , j , k−1) ]
f p 2 . w r i t e ( ”%d\n” % ( o w n e r i d ) )
#
# B ound aries
fp4 . write ( ”
class
polyBoundaryMesh ; \ n” )
fp4 . write ( ”
location
\” c o n s t a n t / polyMesh \ ” ; \ n” )
fp4 . write ( ”
object
boundary ; \ n” )
f p 4 . w r i t e ( ” }\n” )
f p 4 . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
f p 4 . w r i t e ( ” \n” )
f p 4 . w r i t e ( ” \n” )
f p 4 . w r i t e ( ” 6\n” )
f p 4 . w r i t e ( ” ( \ n” )
# North boundary
fp4 . write ( ”
n%04d\n” % ( j b ) )
fp4 . write ( ”
{\n” )
fp4 . write ( ”
type
w a l l ; \ n” )
fp4 . write ( ”
nFaces
%d ; \ n” % (SumOfNF) )
fp4 . write ( ”
startFace
%d ; \ n” % ( N F s t a r t ) )
fp4 . write ( ”
}\n” )
# West boundary
fp4 . write ( ”
w%04d\n” % ( j b ) )
fp4 . write ( ”
{\n” )
fp4 . write ( ”
type
w a l l ; \ n” )
fp4 . write ( ”
nFaces
%d ; \ n” % (SumOfWF) )
fp4 . write ( ”
startFace
%d ; \ n” % ( WF start ) )
35
id [( i , j
i d [ ( i +1, j
id [( i , j
i d [ ( i +1, j
∗ ∗ ∗ ∗ ∗
fp4 . write ( ”
}\n” )
# East boundary
fp4 . write ( ”
e%04d\n” % ( j b ) )
fp4 . write ( ”
{\n” )
fp4 . write ( ”
type
fp4 . write ( ”
nFaces
fp4 . write ( ”
startFace
fp4 . write ( ”
}\n” )
# South boundary
fp4 . write ( ”
s%04d\n” % ( j b ) )
fp4 . write ( ”
{\n” )
fp4 . write ( ”
type
fp4 . write ( ”
nFaces
fp4 . write ( ”
startFace
fp4 . write ( ”
}\n” )
# Bottom boundary
fp4 . write ( ”
b%04d\n” % ( j b ) )
fp4 . write ( ”
{\n” )
fp4 . write ( ”
type
fp4 . write ( ”
nFaces
fp4 . write ( ”
startFace
fp4 . write ( ”
}\n” )
# Top boundary
fp4 . write ( ”
t%04d\n” % ( j b ) )
fp4 . write ( ”
{\n” )
fp4 . write ( ”
type
fp4 . write ( ”
nFaces
fp4 . write ( ”
startFace
fp4 . write ( ”
}\n” )
return
w a l l ; \ n” )
%d ; \ n” % (SumOfEF) )
%d ; \ n” % ( E F s t a r t ) )
w a l l ; \ n” )
%d ; \ n” % ( SumOfSF ) )
%d ; \ n” % ( S F s t a r t ) )
w a l l ; \ n” )
%d ; \ n” % (SumOfBF) )
%d ; \ n” % ( B F s t a r t ) )
w a l l ; \ n” )
%d ; \ n” % (SumOfTF) )
%d ; \ n” % ( T F s t a r t ) )
def write OpenFOAM files ( rootName , nblock , g r i d , f l o w , a x i f l a g ) :
”””
Writes t h e g r i d f i l e s f o r OpenFOAM, s u p p o r t 2−D and 3−D c a s e s .
: param rootName : s p e c i f i c f i l e names a r e b u i l t by adding b i t s t o t h i s
name
: param n b l o c k : i n t e g e r
: param g r i d : l i s t o f S t r u c t u r e d G r i d o b j e c t s
: param f l o w : l i s t o f S t r u c t u r e d G r i d F l o w o b j e c t s
: param a x i f l a g : i n t e g e r
”””
p l o t P a t h = ” foam ”
i f not o s . access ( plotPath , o s . F OK) :
o s . makedirs ( p l o t P a t h )
f o r j b in range ( n b l o c k ) :
s u b p l o t P a t h = p l o t P a t h +(” /b%04d” % ( j b ) )
i f not o s . access ( subplotPath , o s . F OK) :
o s . makedirs ( s u b p l o t P a t h )
#
fileName0 = ” points ”
f i l e N a m e 0 = o s . path . j o i n ( subplotPath , f i l e N a m e 0 )
OFFile0 = open ( fileName0 , ”wb” )
36
fileName1 = ” f a c e s ”
f i l e N a m e 1 = o s . path . j o i n ( subplotPath , f i l e N a m e 1 )
OFFile1 = open ( fileName1 , ”wb” )
f i l e N a m e 2 = ” owner ”
f i l e N a m e 2 = o s . path . j o i n ( subplotPath , f i l e N a m e 2 )
OFFile2 = open ( fileName2 , ”wb” )
fileName3 = ” neighbour ”
f i l e N a m e 3 = o s . path . j o i n ( subplotPath , f i l e N a m e 3 )
OFFile3 = open ( fileName3 , ”wb” )
f i l e N a m e 4 = ” boundary ”
f i l e N a m e 4 = o s . path . j o i n ( subplotPath , f i l e N a m e 4 )
OFFile4 = open ( fileName4 , ”wb” )
#
write general OpenFOAM header ( OFFile0 )
write general OpenFOAM header ( OFFile1 )
write general OpenFOAM header ( OFFile2 )
write general OpenFOAM header ( OFFile3 )
write general OpenFOAM header ( OFFile4 )
#
w r i t e O p e n F O A M u n s t r u c t u r e d f i l e ( OFFile0 , OFFile1 , OFFile2 , OFFile3
, OFFile4 , jb , g r i d [ j b ] , f l o w [ j b ] , a x i f l a g )
#
write general OpenFOAM bottom ( OFFile0 )
write general OpenFOAM bottom ( OFFile1 )
write general OpenFOAM bottom ( OFFile2 )
write general OpenFOAM bottom ( OFFile3 )
write general OpenFOAM bottom ( OFFile4 )
#
OFFile0 . c l o s e ( )
OFFile1 . c l o s e ( )
OFFile2 . c l o s e ( )
OFFile3 . c l o s e ( )
OFFile4 . c l o s e ( )
return
7.2
Source Code e3prepToFoam.py
#! / u s r / b i n / env p y t h o n
”””
3 Fu ncti on t o
a u t o m a t i c a l l y c o n v e r t e 3 p r e p output t o OpenFoam mesh .
4 Can p e r form
f o l l o w i n g 3 mesh c o n v e r s i o n s :
5
− 2D E i l m e r t o e q u i v a l e n t 2D OpenFoam mesh
6
− 2D E i l m e r a x i s y m e t r i c , t o e q u i v a l e n t OpenFoam a x i s y m m e t r i c mesh
7
− 3D E i l m e r t o e q u i v a l e n t 3D OpenFoam mesh
1
2
8
The s c r i p t p e r f o r m s t h e f o l l o w i n g t a s k s :
1 ) c he c k a p p r o p r i a t e OpenFoam F i l e S t r u c t u r e e x i t s
11 2 )
e x e c u t e e 3 p o s t . py −−openFoam t o g e n e r a t e i n d i v i d u a l u n s t r u c t u r e d OF
meshes f o r each E i l m e r b l o c k . These meshes a r e s t o r e d i n / foam / bxxxx
corresponding to r e s p e c t i v e blocks
9
10
37
12
13
14
15
16
17
18
19
20
21
3 ) combines t h e i n d i v i d u a l b l o c k s i n t o a s i n g l e u n s t r u c t u r e d OpenFoam mesh
4) s t i t c h i n t e r n a l f a c e s
5 ) f o r 2D combine f r o n t and back f a c e s o f mesh ( Top and Bottom i n t h e
e 3 p r e p b l o c k s ) t o form ”empty” o r ” wedge ” type p a c t h e s
6 ) group b o u n d a r i e s d e f i n e d i n j o b . py based on t h e r e s p e c t i v e names . The
f o l l o w i n g boundary names a r e r e c o g n i s e d ( r e p l a c e XX by 0 1 , 0 2 , 0 3 , 0 4 ,
05 ,06 , 07 , 08 , 09 , 10) :
− OF inlet XX
− OF outlet XX
− OF wall XX
− OF symmetry XX
− Anything e l s e w i l l r e t a i n i t s name and be s e t a s ” patch ” . D u p l i c a t e
names may c a u s e e r r o r s .
7 ) o p t i o n a l l y a /0/p and /0/U f i l e c o n t a i n i n g p r e s s u r e and v e l o c i t y
boundary c o n d i t i o n s i s c r e a t e d .
22
23
24
Author : Ingo Jahn 03/02/2015
”””
25
import o s a s o s
import numpy a s np
28 import s h u t i l
a s sh
29 from g e t o p t import g e t o p t
30 import s y s
as sys
26
27
31
32
33
shortOptions = ””
l o n g O p t i o n s = [ ” h e l p ” , ” j o b=” , ” c r e a t e 0 ” ]
34
def p r i n t U s a g e ( ) :
print ” ”
37
print ” Usage : e3prepToFoam . py [−− h e l p ] [−− j o b=<jobFileName >] [−−
create 0 ] ”
38
return
35
36
39
40
def g e t f o l d e r s ( ) :
print ’ O b t a i n i n g d i r e c t o r y from which code i s e x e c u t e d ’
43
s t a r t d i r = o s . getcwd ( )
44
str2 = start dir . split ( ’/ ’ )
45
n = len ( s t r 2 )
46
s t r 3 = s t r 2 [ n−1]
47
i f s t r 3 == ’ e 3 p r e p ’ :
48
c a s e d i r = o s . path . dirname ( s t a r t d i r )
49
r o o t d i r = o s . path . dirname ( c a s e d i r )
50
case name = s t r 2 [ n−2]
51
else :
52
case dir = start dir
53
r o o t d i r = o s . path . dirname ( c a s e d i r )
54
case name = s t r 2 [ n−1]
55
return r o o t d i r , c a s e d i r , s t a r t d i r , case name
41
42
56
57
58
def c h e c k c a s e s t r u c t u r e ( c a s e d i r , r o o t d i r ) :
print ’ Checking i f c o r r e c t OpenFOAM c a s e s t r u c t u r e e x i s t s \n ’
38
59
60
61
62
63
64
65
66
67
68
flag = 0
i f o s . path . e x i s t s ( c a s e d i r+ ’ /0 ’ ) i s not True :
flag = 1
print ” M i s s i n g /0 d i r e c t o r y ”
i f o s . path . e x i s t s ( c a s e d i r+ ’ / system ’ ) i s not True :
flag = 1
print ” M i s s i n g / system d i r e c t o r y ”
i f o s . path . e x i s t s ( c a s e d i r+ ’ / c o n s t a n t ’ ) i s not True :
flag = 1
print ” M i s s i n g / c o n s t a n t d i r e c t o r y ”
69
70
71
72
73
74
75
76
77
i f o s . path . e x i s t s ( c a s e d i r+ ’ / c o n s t a n t / polyMesh ’ ) i s not True :
flag = 1
print ” M i s s i n g / c o n s t a n t / polyMesh d i r e c t o r y ”
i f o s . path . e x i s t s ( r o o t d i r+ ’ / s l a v e m e s h ’ ) i s True :
flag = 1
print ” F o l d e r . . / s l a v e m e s h / a l r e a d y e x i s t s \n D e l e t e t h i s f o l d e r
and t r y a g a i n ”
print ’ \n ’
return f l a g
78
79
def f a c e i n d e x t o s t r i n g ( i n d ) :
i f i n d == 0 :
82
return ’ n ’
83
e l i f i n d == 1 :
84
return ’ e ’
85
e l i f i n d == 2 :
86
return ’ s ’
87
e l i f i n d == 3 :
88
return ’w ’
89
e l i f i n d == 4 :
90
return ’ t ’
91
e l i f i n d == 5 :
92
return ’ b ’
93
else :
94
print ’ E r r o r ’
95
return
80
81
96
def g e t j o b c o n f i g d a t a ( j o b ) :
print ’ E x t r a c t i n g r e q u i r e d v a r i a b l e s from j o b . c o n f i g ’
99
f = open ( ( j o b + ’ . c o n f i g ’ ) , ’ r ’ )
100
# f i n d dimensions
101
f o r l i n e in f :
102
i f ” d i m e n s i o n s ” in l i n e :
103
temp = l i n e . s p l i t ( )
104
d i m e n s i o n s = i n t ( temp [ 2 ] )
105
break
106
# d i f f e r e n t i a t e b e t w e e n a x i s y m m e t r i c and 2−D c a s e s
107
f o r l i n e in f :
108
i f ” a x i s y m m e t r i c f l a g ” in l i n e :
109
temp = l i n e . s p l i t ( )
110
a x i s y m m e t r i c f l a g = i n t ( temp [ 2 ] )
97
98
39
111
112
113
114
115
116
117
break
# f i n d number o f b l o c k s
f o r l i n e in f :
i f ” n b l o c k ” in l i n e :
temp = l i n e . s p l i t ( )
n b l o c k = i n t ( temp [ 2 ] )
break
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
o t h e r b l o c k = np . z e r o s ( ( nblock , 6 ) )
o t h e r f a c e = np . z e r o s ( ( nblock , 6 ) )
# find connecting blocks
f . seek (0 ,0)
block = 0
face = 0
f o r l i n e in f :
i f ” o t h e r b l o c k ” in l i n e :
temp = l i n e . s p l i t ( )
o t h e r b l o c k [ b l o c k , f a c e ] = i n t ( temp [ 2 ] )
face = face + 1
i f d i m e n s i o n s == 2 :
i f f a c e == 4 :
o t h e r b l o c k [ b l o c k , 4 ] = −1
o t h e r b l o c k [ b l o c k , 5 ] = −1
face = 0
block = block + 1
e l i f d i m e n s i o n s == 3 :
i f f a c e == 6 :
face = 0
block = block + 1
# find connecting faces
f . seek (0 ,0)
block = 0
face = 0
f o r l i n e in f :
i f ” o t h e r f a c e ” in l i n e :
temp = l i n e . s p l i t ( )
i f temp [ 2 ] == ” none ” :
o t h e r f a c e [ b l o c k , f a c e ] = −1
e l i f temp [ 2 ] == ” n o r t h ” :
o t h e r f a c e [ block , f a c e ] = 0
e l i f temp [ 2 ] == ” e a s t ” :
o t h e r f a c e [ block , f a c e ] = 1
e l i f temp [ 2 ] == ” s o u t h ” :
o t h e r f a c e [ block , f a c e ] = 2
e l i f temp [ 2 ] == ” west ” :
o t h e r f a c e [ block , f a c e ] = 3
e l i f temp [ 2 ] == ” top ” :
o t h e r f a c e [ block , f a c e ] = 4
e l i f temp [ 2 ] == ” bottom ” :
o t h e r f a c e [ block , f a c e ] = 5
else :
print ” E r r o r ”
face = face + 1
40
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
i f d i m e n s i o n s == 2 :
i f f a c e == 4 :
o t h e r f a c e [ b l o c k , 4 ] = −1
o t h e r f a c e [ b l o c k , 5 ] = −1
face = 0
block = block + 1
e l i f d i m e n s i o n s == 3 :
i f f a c e == 6 :
face = 0
block = block + 1
# f i n d boundary l a b e l s
f . seek (0 ,0)
L a b e l = [ [ None f o r i in range ( 6 ) ] f o r i in range ( n b l o c k ) ]
f o r b l o c k in range ( n b l o c k ) :
i f d i m e n s i o n s == 2 :
f o r f a c e in range ( 4 ) :
temp = f i n d b o u n d a r y i n f o ( f , b l o c k , f a c e , ” l a b e l ” )
temp = temp . s p l i t ( )
i f len ( temp ) == 3 :
L a b e l [ b l o c k ] [ f a c e ] = temp [ 2 ]
# p r i n t ” I was h e r e ” , b l o c k , f a c e , temp [ 2 ]
else :
L a b e l [ b l o c k ] [ f a c e ] = ”EMPTY”
L a b e l [ b l o c k ] [ 4 ] = ”EMPTY”
L a b e l [ b l o c k ] [ 5 ] = ”EMPTY”
i f d i m e n s i o n s == 3 :
f o r f a c e in range ( 6 ) :
temp = f i n d b o u n d a r y i n f o ( f , b l o c k , f a c e , ” l a b e l ” )
temp = temp . s p l i t ( )
i f len ( temp ) == 3 :
L a b e l [ b l o c k ] [ f a c e ] = temp [ 2 ]
# p r i n t ” I was h e r e ” , b l o c k , f a c e , temp [ 2 ]
else :
L a b e l [ b l o c k ] [ f a c e ] = ”EMPTY”
f . close ()
return ( nblock , d i m e n s i o n s , a x i s y m m e t r i c f l a g , o t h e r b l o c k , o t h e r f a c e ,
Label )
200
201
def f i n d b o u n d a r y i n f o ( fp , b l o c k , f a c e , l ook up ) :
i f f a c e == 0 :
204
p h r a s e = ( ” [ b l o c k / ”+s t r ( b l o c k )+” / f a c e / n o r t h ] ” )
205
e l i f f a c e == 1 :
206
p h r a s e = ( ” [ b l o c k / ”+s t r ( b l o c k )+” / f a c e / e a s t ] ” )
207
e l i f f a c e == 2 :
208
p h r a s e = ( ” [ b l o c k / ”+s t r ( b l o c k )+” / f a c e / s o u t h ] ” )
209
e l i f f a c e == 3 :
210
p h r a s e = ( ” [ b l o c k / ”+s t r ( b l o c k )+” / f a c e / west ] ” )
211
e l i f f a c e == 4 :
212
p h r a s e = ( ” [ b l o c k / ”+s t r ( b l o c k )+” / f a c e / top ] ” )
213
e l i f f a c e == 5 :
214
p h r a s e = ( ” [ b l o c k / ”+s t r ( b l o c k )+” / f a c e / bottom ] ” )
215
else :
202
203
41
216
217
218
219
220
221
222
223
224
print ” wrong
fp . seek (0 ,0)
f o r num , l i n e in
i f p h r a s e in
break
f o r l i n e in f p :
i f lo oku p in
break
return l i n e
face index ”
enumerate ( fp , 1 ) :
line :
line :
225
226
def w r i t e g e n e r a l O p e n F o a m h e a d e r ( f p ) :
f p . w r i t e ( ”/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++
−∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\\\n” )
229
f p . w r i t e ( ” | ========
|
227
228
231
f p . w r i t e ( ” | \\
Toolbox
f p . w r i t e ( ” | \\
232
fp . write ( ” |
230
233
234
235
236
237
238
239
\\
/ F ield
| \ n” )
/
O peration
/
| \ n” )
| OpenFOAM: The Open S o u r c e CFD
| Version :
| \ n” )
| Web :
A nd
| \ n” )
M anipulation
| \ n” )
2.2.2
www.OpenFOAM. o r g
fp . write ( ” |
\\/
| This f i l e g e n e r a t e d by e 3 p o s t .
py
fp . write ( ”
\∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/\
n” )
f p . w r i t e ( ” FoamFile \n” )
f p . w r i t e ( ” {\n” )
fp . write ( ”
version
2 . 0 ; \ n” )
fp . write ( ”
f ormat
a s c i i ; \ n” )
return
240
def w r i t e g e n e r a l O p e n F o a m b o t t o m r o u n d ( f p ) :
f p . w r i t e ( ” ) ; \ n” )
243
f p . w r i t e ( ” \n” )
244
f p . w r i t e ( ” //
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
//\n” )
245
return
241
242
246
def w r i t e g e n e r a l O p e n F o a m b o t t o m c u r l y ( f p ) :
f p . w r i t e ( ” } ; \ n” )
249
f p . w r i t e ( ” \n” )
250
f p . w r i t e ( ” //
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
//\n” )
251
return
247
248
252
def w r i t e c r e a t e P a t c h h e a d e r ( f p ) :
#
255
# −−−−−−−−−−−−−−−−−−− w r i t i n g f i l e s now −−−−−−−−−−−−−−−−−−−−−−−−−−−−−
256
# points
253
254
42
257
258
259
260
261
262
263
264
265
266
fp . write ( ”
class
d i c t i o n a r y ; \ n” )
fp . write ( ”
object
c r e a t e P a t c h D i c t ; \ n” )
f p . w r i t e ( ” }\n” )
f p . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
f p . w r i t e ( ” \n” )
f p . w r i t e ( ” p o i n t S y n c f a l s e ; \ n” )
f p . w r i t e ( ” // P a t c h e s t o c r e a t e . \n” )
f p . w r i t e ( ” p a t c h e s \n” )
f p . w r i t e ( ” ( \ n” )
return
267
def w r i t e c o l l a p s e D i c t h e a d e r ( f p ) :
#
270
# −−−−−−−−−−−−−−−−−−− w r i t i n g f i l e s now −−−−−−−−−−−−−−−−−−−−−−−−−−−−−
271
# points
272
fp . write ( ”
class
d i c t i o n a r y ; \ n” )
273
fp . write ( ”
object
c o l l a p s e D i c t ; \ n” )
274
f p . w r i t e ( ” }\n” )
275
f p . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
276
f p . w r i t e ( ” \n” )
277
f p . w r i t e ( ” c o l l a p s e E d g e s C o e f f s \n” )
278
f p . w r i t e ( ” {\n” )
279
f p . w r i t e ( ” // Edges s h o r t e r than t h i s a b s o l u t e v a l u e w i l l be merged \n” )
280
fp . write ( ”
minimumEdgeLength
1 e −10;\n” )
281
f p . w r i t e ( ” \n” )
282
f p . w r i t e ( ” // The maximum a n g l e between two e d g e s t h a t s h a r e a p o i n t
a t t a c h e d t o \n” )
283
f p . w r i t e ( ” // no o t h e r e d g e s \n” )
284
f p . w r i t e ( ”maximumMergeAngle
5 ; \ n” )
285
return
268
269
286
287
def w r i t e p h e a d e r ( f p ) :
#
290
# −−−−−−−−−−−−−−−−−−− w r i t i n g f i l e s now −−−−−−−−−−−−−−−−−−−−−−−−−−−−−
291
# points
292
fp . write ( ”
class
v o l S c a l a r F i e l d ; \ n” )
293
fp . write ( ”
location
\ ” 0 \ ” ; \ n” )
294
fp . write ( ”
object
p ; \ n” )
295
f p . w r i t e ( ” }\n” )
296
f p . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
297
f p . w r i t e ( ” \n” )
298
fp . write ( ” dimensions
[ 0 2 −2 0 0 0 0 ] ; \ n” )
299
f p . w r i t e ( ” \n” )
300
fp . write ( ” i n t e r n a l F i e l d
un ifo rm 0 ; \ n” )
301
f p . w r i t e ( ” \n” )
302
f p . w r i t e ( ” b o u n d a r y F i e l d \n” )
303
f p . w r i t e ( ” { \n” )
304
return
288
289
305
43
def w r i t e U h e a d e r ( f p ) :
#
308
# −−−−−−−−−−−−−−−−−−− w r i t i n g f i l e s now −−−−−−−−−−−−−−−−−−−−−−−−−−−−−
309
# points
310
fp . write ( ”
class
v o l V e c t o r F i e l d ; \ n” )
311
fp . write ( ”
location
\ ” 0 \ ” ; \ n” )
312
fp . write ( ”
object
U; \ n” )
313
f p . w r i t e ( ” }\n” )
314
f p . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
315
f p . w r i t e ( ” \n” )
316
fp . write ( ” dimensions
[ 0 1 −1 0 0 0 0 ] ; \ n” )
317
f p . w r i t e ( ” \n” )
318
fp . write ( ” i n t e r n a l F i e l d
un ifo rm ( 0 0 0 ) ; \ n” )
319
f p . w r i t e ( ” \n” )
320
f p . w r i t e ( ” b o u n d a r y F i e l d \n” )
321
f p . w r i t e ( ” { \n” )
322
return
306
307
323
def w r i t e p a t c h e s ( fp , i n p u t p a t c h s t r , output name , o u t p u t t y p e ) :
fp . write ( ”
{\n” )
326
fp . write (( ”
name ” + output name +” ; \ n” ) ) ;
327
fp . write ( ”
p a t c h I n f o \n” )
328
fp . write ( ”
{\n” )
329
fp . write (( ”
type ”+o u t p u t t y p e+” ; \ n” ) )
330
fp . write ( ”
}\n” )
331
fp . write ( ”
constructFrom p a t c h e s ; \ n” )
332
fp . write ( ”
p a t c h e s ( ”+i n p u t p a t c h s t r+” ) ; \ n” )
333
fp . write ( ”
}\n” )
334
return
324
325
335
def w r i t e p B o u n d a r y ( fp , bname , btype ) :
fp . write ( ”
”+bname+” \n” )
338
fp . write ( ”
{\n” )
339
i f btype == ” z e r o G r a d i e n t ” :
340
fp . write ( ”
type
z e r o G r a d i e n t ; \n” )
341
e l i f btype == ”empty” :
342
fp . write ( ”
type
empty ; \n” )
343
e l i f btype == ” wedge ” :
344
fp . write ( ”
type
wedge ; \n” )
345
e l i f btype == ” symmetry ” :
346
fp . write ( ”
type
symmetry ; \n” )
347
e l i f btype == ” f i x e d V a l u e ” :
348
fp . write ( ”
type
f i x e d V a l u e ; \n” )
349
fp . write ( ”
value
0 ; \n” )
350
else :
351
print ( ” Boundary type , ” + btype + ” not r e c o g n i s e d . S e t t i n g empty”
)
352
fp . write ( ”
}\n” )
353
return
336
337
354
355
356
def write U Boundary ( fp , bname , btype ) :
fp . write ( ”
”+bname+” \n” )
44
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
fp . write ( ”
{\n” )
i f btype == ” z e r o G r a d i e n t ” :
fp . write ( ”
type
e l i f btype == ”empty” :
fp . write ( ”
type
e l i f btype == ” wedge ” :
fp . write ( ”
type
e l i f btype == ” symmetry ” :
fp . write ( ”
type
e l i f btype == ” f i x e d V a l u e ” :
fp . write ( ”
type
fp . write ( ”
value
else :
print ( ” Boundary type , ”
)
fp . write ( ”
}\n” )
return
z e r o G r a d i e n t ; \n” )
empty ; \n” )
wedge ; \n” )
symmetry ; \n” )
f i x e d V a l u e ; \n” )
uni for m ( 0 0 0 ) ; \n” )
+ btype + ” not r e c o g n i s e d . S e t t i n g empty”
373
def c o m b i n e f a c e s ( c a s e d i r , s t a r t d i r , p a t c h s t r , patch name , p a t c h t y p e ) :
file createPatchDict = ” createPatchDict ”
376
f i l e c r e a t e P a t c h D i c t = o s . path . j o i n ( ( c a s e d i r+ ’ / system ’ ) ,
file createPatchDict )
377
OFFile0 = open ( f i l e c r e a t e P a t c h D i c t , ”wb” )
374
375
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
w r i t e g e n e r a l O p e n F o a m h e a d e r ( OFFile0 )
w r i t e c r e a t e P a t c h h e a d e r ( OFFile0 )
w r i t e p a t c h e s ( OFFile0 , p a t c h s t r , patch name , p a t c h t y p e )
w r i t e g e n e r a l O p e n F o a m b o t t o m r o u n d ( OFFile0 )
OFFile0 . c l o s e ( )
print ” c r e a t e P a t c h D i c t has been w r i t t e n . \n”
# execute createPatch
os . chdir ( c a s e d i r )
f l a g = o s . system ( ’ c r e a t e P a t c h −o v e r w r i t e ’ )
# move b a c k t o s t a r t i n g d i r e c t o r y
os . chdir ( s t a r t d i r )
i f f l a g == 0 :
print ( ”The f o l l o w i n g b o u n d a r i e s ” +p a t c h s t r+ ” have been combined
t o form Patch : ” +patch name+ ” with t h e type : ” + p a t c h t y p e )
else :
r a i s e MyError ( ” Problem d u r i n g e x e c u t i o n o f c r e a t e P a a t c h . ” )
return
395
def c h e c k f o r u n d e f i n e d f a c e s ( c a s e
f i l e n a m e = ” boundary ”
398
f i l e n a m e = o s . path . j o i n ( ( c a s e
399
F i l e = open ( f i l e n a m e , ” r ” )
400
String = [ ]
401
f o r n in range ( n b l o c k ) :
402
f o r l i n e in F i l e :
403
i f ( ’ n ’+ ’ %04d ’ % n ) in
404
S t r i n g . append ( l i n e
405
i f ( ’ e ’+ ’ %04d ’ % n ) in
406
S t r i n g . append ( l i n e
396
d i r , nblock ) :
397
d i r+ ’ / c o n s t a n t / polyMesh / ’ ) , f i l e n a m e )
line :
+ ’; ’)
line :
+ ’; ’)
45
407
408
409
410
411
412
413
i f ( ’ s ’+ ’ %04d ’ % n ) in
S t r i n g . append ( l i n e
i f ( ’w ’+ ’ %04d ’ % n ) in
S t r i n g . append ( l i n e
File . seek (0 ,0)
File . close ()
return S t r i n g
line :
+ ’; ’)
line :
+ ’; ’)
414
415
def c h e c k f o r u n d e f i n e d l a b e l s ( p a t c h L a b e l ) :
A = [ item f o r s u b l i s t in p a t c h L a b e l f o r item in s u b l i s t ]
418
A = set (A)
419
S t r i n g = [ ’EMPTY’ , ’ C e n t r e l i n e ’ ]
420
f o r i in range ( 1 0 ) :
421
S t r i n g . append ( ” O F i n l e t ”+ ’ %02d ’ % i )
422
S t r i n g . append ( ” O F o u t l e t ”+ ’ %02d ’ % i )
423
S t r i n g . append ( ” OF wall ”+ ’ %02d ’ % i )
424
S t r i n g . append ( ” OF symmetry ”+ ’ %02d ’ % i )
425
S t r i n g = set ( S t r i n g )
416
417
426
427
return l i s t (A. d i f f e r e n c e ( S t r i n g ) )
428
429
def c o l l a p s e f a c e s ( c a s e d i r , s t a r t d i r ) :
fn = ” c o l l a p s e D i c t ”
432
f n = o s . path . j o i n ( ( c a s e d i r+ ’ / system ’ ) , f n )
433
OFFile0 = open ( fn , ”wb” )
430
431
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
w r i t e g e n e r a l O p e n F o a m h e a d e r ( OFFile0 )
w r i t e c o l l a p s e D i c t h e a d e r ( OFFile0 )
w r i t e g e n e r a l O p e n F o a m b o t t o m c u r l y ( OFFile0 )
OFFile0 . c l o s e ( )
print ” c o l l a p s e D i c t has been w r i t t e n . \n”
# execute createPatch
os . chdir ( c a s e d i r )
f l a g = o s . system ( ’ c o l l a p s e E d g e s −o v e r w r i t e ’ )
# move b a c k t o s t a r t i n g d i r e c t o r y
os . chdir ( s t a r t d i r )
i f f l a g == 0 :
print ( ” A l i g n e d e d g e s have been c o l l a p s e d ” )
else :
r a i s e MyError ( ” Problem d u r i n g e x e c u t i o n o f c o l l a p s e E d g e s . ” )
449
450
return f l a g
451
452
453
454
455
456
c l a s s MyError ( E x c e p t i o n ) :
def
i n i t ( s e l f , value ) :
s e l f . value = value
def
str ( self ) :
return repr ( s e l f . v a l u e )
457
458
459
def main ( uoDict ) :
46
460
461
# c r e a t e s t r i n g t o c o l l e c t warning messages
w a r n s t r = ” \n”
462
463
464
# main f i l e t o be e x e c u t e d
jobName = uoDict . g e t ( ”−−j o b ” , ” t e s t ” )
465
466
467
468
# s t r i p . py e x t e n s i o n form jobName
jobName = jobName . s p l i t ( ’ . ’ )
jobName = jobName [ 0 ]
469
470
471
# e s t a b l i s h case , r o o t , and s t a r t d i r e c t o r y
r o o t d i r , c a s e d i r , s t a r t d i r , case name = g e t f o l d e r s ( )
472
473
474
475
476
# check t h a t c o r r e c t d i r e c t o r y s t r u c t u r e e x i s t s
dir flag = check case structure ( case dir , root dir )
i f d i r f l a g == 1 :
r a i s e MyError ( ’ERROR: I n c o r r e c t D i r e c t o r y S t r u c t u r e . e3preToFoam
must be run i n s i d e an OpenFoam c a s e with a p p r o p r i a t e sub−
d i r e c t o r i e s . \ nSee e r r o r message above and c r e a t e m i s s i n g
f o l d e r s o r copy from e x i s t i n g c a s e . \nOnce f o l d e r s have been
c r e a t e d , re−run . ’ )
477
478
479
# change i n t o e 3 p r e p d i r e c t o r y
o s . c h d i r ( ( c a s e d i r+ ’ / e 3 p r e p ’ ) )
480
481
482
# g e t d a t a from j o b . c o n f i g
nblock , d i m e n s i o n s , a x i s y m m e t r i c f l a g , o t h e r b l o c k , o t h e r f a c e ,
p a t c h L a b e l = g e t j o b c o n f i g d a t a ( jobName )
483
484
485
486
487
488
# c h e c k t h a t c o m b i n a t i o n o f d i e m n s i o n s and a x i −s y m e t r i c f l a g i s
appropriate
i f not ( ( ( d i m e n s i o n s == 2 or d i m e n s i o n s == 3 ) and a x i s y m m e t r i c f l a g ==
0 ) or ( d i m e n s i o n s == 2 and a x i s y m m e t r i c f l a g == 1 ) ) :
r a i s e MyError ( ’ERROR: Combination o f d i m e n s i o n s and
a x i s y m m e t r i c f l a g i s not s u p p o r t e d ’ )
# run e 3 p o s t t o g e n e r a t e /foam f o l d e r c o n t a i n i n g meshes f o r r e s p e c t i v e
block
o s . system ( ( ” e 3 p o s t . py −−j o b=” + jobName + ” −−OpenFoam” ) )
489
490
print ’ e 3 p o s t has been e x e c u t e d and i n d i v i d u a l foam meshes have been
g e n e r a t e d f o r each b l o c k \n \n ’
491
492
493
# merging i n d i v i d u a l b l o c k s
print ( ’ Working on Case = ’+case name )
494
495
496
497
## move d a t a c u r r e n t l y i n / polMesh
#sh . move ( ’ polyMesh ’ , ’ p o l y M e s h o l d ’ )
sh . r m t r e e ( c a s e d i r + ’ / c o n s t a n t / polyMesh ’ )
498
499
500
# create case f i l e for slave mesh
sh . c o p y t r e e ( c a s e d i r , ( r o o t d i r+ ’ / s l a v e m e s h ’ ) )
501
502
# copy Master mesh d a t a i n t o r e q u i r e d f o l d e r
47
503
sh . c o p y t r e e ( ( c a s e d i r+ ’ / e 3 p r e p / foam / b0000 / ’ ) , c a s e d i r+ ’ / c o n s t a n t /
polyMesh ’ )
504
505
506
507
f o r b l o c k in range ( nblock −1) :
# copy c o r r e c t s l a v e m e s h i n t o s l a b e m e s h c a s e
sh . c o p y t r e e ( ( c a s e d i r+ ’ / e 3 p r e p / foam /b ’+ ’ %04d ’ % ( b l o c k +1) + ’ / ’ ) ,
r o o t d i r+ ’ / s l a v e m e s h / c o n s t a n t / polyMesh ’ )
508
509
510
511
512
513
514
515
516
517
# e x e c u t e mergeMeshes command
os . chdir ( r o o t d i r )
f l a g = o s . system ( ’ mergeMeshes −o v e r w r i t e ’ + case name + ’
slave mesh ’ )
i f f l a g == 0 :
print ( ’ Block ’ + ’ %04d ’ % b l o c k + ’ and ’ + ’ %04d ’ % ( b l o c k +1)
+ ’ have been merged . ’ )
else :
sh . r m t r e e ( r o o t d i r+ ’ / s l a v e m e s h ’ ) # removing s l a v e m e s h
directory before exiting
os . chdir ( s t a r t d i r )
r a i s e MyError ( ’ E r r o r with mergeMeshes . \n Try r u n n i n g o f 2 3 0 t o
l o a d OpenFOAM module ’ )
518
519
520
# remove polyMesh from s l a v e m e s h
sh . r m t r e e ( r o o t d i r+ ’ / s l a v e m e s h / c o n s t a n t / polyMesh ’ )
521
522
523
524
525
# remove s l a v e
sh . r m t r e e ( r o o t
# move b a c k t o
os . chdir ( s t a r t
mesh
d i r+ ’ / s l a v e m e s h ’ )
starting directory
dir )
526
527
print ” Merging o f meshes c o m p l e t e . \n \n ”
528
529
530
531
532
# Remove f a c e s w i t h z e r o area , p o s i t i o n e d a l o n g c e n t r e l i n e
i f a x i s y m m e t r i c f l a g == 1 :
print ”Removing z e r o Area f a c e s a l o n g c e n t r e l i n e . \n”
flag = collapse faces ( case dir , start dir )
533
534
535
536
#i d e n t i f y number o f b l o c k c o n n e c t i o n s
i n t e r f a c e s = len ( o t h e r b l o c k [ np . where ( o t h e r b l o c k != −1) ] ) # c o u n t s 2 x
i n t e r n a l c o n n e c t i o n s , as s e e n by o t h e r b l o c k s
if interfaces > 0:
537
538
539
# move /0 d i r e c t o r y
sh . move ( ( c a s e d i r + ’ /0 ’ ) , c a s e d i r + ’ /temp ’ )
540
541
542
543
544
while True :
( b l o c k , f a c e ) = np . where ( o t h e r b l o c k != −1)
i f len ( b l o c k ) == 0 :
break
545
546
547
548
# print ( block , face )
o block = other block [ block [ 0 ] , face [ 0 ] ]
o face = o t h e r f a c e [ block [ 0 ] , face [ 0 ] ]
48
549
550
551
c u r r e n t f a c e n a m e = ( f a c e i n d e x t o s t r i n g ( f a c e [ 0 ] ) + ’ %04d ’ %
block [ 0 ] )
o t h e r f a c e n a m e = ( f a c e i n d e x t o s t r i n g ( o f a c e ) + ’ %04d ’ %
o block )
552
553
# p r i n t ( current facename , other facename )
554
555
556
557
558
# o v e r w r i t e matching f a c e i n o t h e r b l o c k
o t h e r b l o c k [ o b l o c k , o f a c e ] = −1
o t h e r f a c e [ o b l o c k , o f a c e ] = −1
o t h e r b l o c k [ b l o c k [ 0 ] , f a c e [ 0 ] ] = −1
559
560
561
562
563
564
565
566
567
568
# e x e c u t e s t i t c h M e s h command
os . chdir ( c a s e d i r )
f l a g = o s . system ( ’ s t i t c h M e s h −o v e r w r i t e −p e r f e c t ’ +
current facename + ’ ’ + other facename )
# move b a c k t o s t a r t i n g d i r e c t o r y
os . chdir ( s t a r t d i r )
i f f l a g == 0 :
print ( ’ Face ’ + c u r r e n t f a c e n a m e + ’ and ’ +
o t h e r f a c e n a m e + ’ have been s t i t c h e d . ’ )
else :
r a i s e MyError ( ’ E r r o r with s t i t c h M e s h . ’ )
569
570
571
# move /0 d i r e c t o r y b a c k
sh . move ( ( c a s e d i r + ’ /temp ’ ) , c a s e d i r + ’ /0 ’ )
572
573
print ” S t i t c h i n g o f i n t e r n a l Faces c o m p l e t e . \n \n”
574
575
576
577
578
579
580
581
582
# Group a l l b o u n d a r i e s w i t h C e n t r e l i n e l a b e l as c o r r e s p o n d i n g p a t c h
i f a x i s y m m e t r i c f l a g == 1 :
name = ” C e n t r e l i n e ”
c e n t s t r = ””
f o r b l o c k in range ( n b l o c k ) :
L block = patch Label [ block ]
#p r i n t L b l o c k
i n d = [ n f o r n , s in enumerate ( L b l o c k ) i f name in s ]
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
i f i n d != [ ] :
f o r n in i n d :
i f n == 0 :
cent str
i f n == 1 :
cent str
i f n == 2 :
cent str
i f n == 3 :
cent str
i f n == 4 :
cent str
i f n == 5 :
cent str
= ( c e n t s t r + ’ n ’ + ’ %04d ’ % b l o c k )
= ( c e n t s t r + ’ e ’ + ’ %04d ’ % b l o c k )
= ( c e n t s t r + ’ s ’ + ’ %04d ’ % b l o c k )
= ( c e n t s t r + ’ w ’ + ’ %04d ’ % b l o c k )
= ( c e n t s t r + ’ t ’ + ’ %04d ’ % b l o c k )
= ( c e n t s t r + ’ b ’ + ’ %04d ’ % b l o c k )
49
print c e n t s t r
i f c e n t s t r != ” ” :
c o m b i n e f a c e s ( c a s e d i r , s t a r t d i r , c e n t s t r , name , ’ empty ’ )
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
# do a u t o m a t i c p a t c h c o m b i n a t i o n
# t o p and bottom f a c e s
i f d i m e n s i o n s == 2 :
i f a x i s y m m e t r i c f l a g == 0 :
# c r e t e empty FrontBack p a t c h
patch str = ’ ’
f o r i in range ( n b l o c k ) :
p a t c h s t r = ( p a t c h s t r+ ’ b ’+ ’ %04d ’ %
)
patch name = ’ FrontBack ’
p a t c h t y p e = ’ empty ’
combine faces ( case dir , start dir , patch str
patch type )
e l i f a x i s y m m e t r i c f l a g == 1 :
# c r e a t e p a i r o f wedge p a t c h e s
patch str = ’ ’
f o r i in range ( n b l o c k ) :
p a t c h s t r = ( p a t c h s t r+ ’ b ’+ ’ %04d ’ %
patch name = ’ Back ’
p a t c h t y p e = ’ wedge ’
combine faces ( case dir , start dir , patch str
patch type )
patch str = ’ ’
f o r i in range ( n b l o c k ) :
p a t c h s t r = ( p a t c h s t r+ ’ t ’+ ’ %04d ’ %
patch name = ’ Front ’
p a t c h t y p e = ’ wedge ’
combine faces ( case dir , start dir , patch str
patch type )
i + ’ t ’ + ’ %04d ’ % i
, patch name ,
i)
, patch name ,
i)
, patch name ,
627
628
629
630
631
632
633
#
#
#
#
#
#
combine p a t c h e s , b a s e d on b l o c k l a b e l .
Following l a b e l s are supported :
O F i n l e t 0 0 , O F i n l e t 0 1 , O F i n l e t 0 2 ( up t o 09)
O F o u t l e t 0 0 , O F o u t l e t 0 1 , O F o u t l e t 0 2 ( up t o 09)
OF wall 00 , OF wall 01 , O F w a l l 0 2 ( up t o 09)
OF symmetry 00 , OF symmetry 01 , OF symmetry 02 ( up t o 09)
N
N
N
N
list
list
list
list
634
635
636
637
638
in = []
out = [ ]
wall = []
sym = [ ]
639
640
641
642
643
644
f o r i in range ( 1 0 ) :
i n n = ( ” O F i n l e t ”+ ’ %02d ’ % i )
o u t n = ( ” O F o u t l e t ”+ ’ %02d ’ % i )
w a l l n = ( ” OF wall ”+ ’ %02d ’ % i )
sym n = ( ” OF symmetry ”+ ’ %02d ’ % i )
645
646
i n l e t s t r = ””
50
647
648
649
650
651
652
653
654
655
656
657
658
o u t l e t s t r = ””
w a l l s t r = ””
sym str = ””
f o r b l o c k in range ( n b l o c k ) :
L block = patch Label [ block ]
#p r i n t L b l o c k
i i n d = [ n f o r n , s in enumerate ( L
o i n d = [ n f o r n , s in enumerate ( L
w ind = [ n f o r n , s in enumerate ( L
s i n d = [ n f o r n , s in enumerate ( L
#p r i n t i i n d != [ ]
#p r i n t o i n d != [ ]
block )
block )
block )
block )
if
if
if
if
i n n in s ]
o u t n in s ]
w a l l n in s ]
sym n in s ]
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
i f i i n d != [ ] :
f o r n in i i n d :
i f n == 0 :
inlet str = ( inlet str +
i f n == 1 :
inlet str = ( inlet str +
i f n == 2 :
inlet str = ( inlet str +
i f n == 3 :
inlet str = ( inlet str +
i f n == 4 :
inlet str = ( inlet str +
i f n == 5 :
inlet str = ( inlet str +
i f o i n d != [ ] :
f o r n in o i n d :
i f n == 0 :
outlet str = ( outlet str
i f n == 1 :
outlet str = ( outlet str
i f n == 2 :
outlet str = ( outlet str
i f n == 3 :
outlet str = ( outlet str
i f n == 4 :
outlet str = ( outlet str
i f n == 5 :
outlet str = ( outlet str
i f w ind != [ ] :
f o r n in w ind :
i f n == 0 :
wall str = ( wall str + ’
i f n == 1 :
wall str = ( wall str + ’
i f n == 2 :
wall str = ( wall str + ’
i f n == 3 :
wall str = ( wall str + ’
i f n == 4 :
wall str = ( wall str + ’
51
’ n ’ + ’ %04d ’ % b l o c k )
’ e ’ + ’ %04d ’ % b l o c k )
’ s ’ + ’ %04d ’ % b l o c k )
’ w ’ + ’ %04d ’ % b l o c k )
’ t ’ + ’ %04d ’ % b l o c k )
’ b ’ + ’ %04d ’ % b l o c k )
+ ’ n ’ + ’ %04d ’ % b l o c k )
+ ’ e ’ + ’ %04d ’ % b l o c k )
+ ’ s ’ + ’ %04d ’ % b l o c k )
+ ’ w ’ + ’ %04d ’ % b l o c k )
+ ’ t ’ + ’ %04d ’ % b l o c k )
+ ’ b ’ + ’ %04d ’ % b l o c k )
n ’ + ’ %04d ’ % b l o c k )
e ’ + ’ %04d ’ % b l o c k )
s ’ + ’ %04d ’ % b l o c k )
w ’ + ’ %04d ’ % b l o c k )
t ’ + ’ %04d ’ % b l o c k )
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
i f n == 5 :
wall str = ( wall str
i f s i n d != [ ] :
f o r n in s i n d :
i f n == 0 :
sym str = ( sym str +
i f n == 1 :
sym str = ( sym str +
i f n == 2 :
sym str = ( sym str +
i f n == 3 :
sym str = ( sym str +
i f n == 4 :
sym str = ( sym str +
i f n == 5 :
sym str = ( sym str +
+ ’ b ’ + ’ %04d ’ % b l o c k )
’ n ’ + ’ %04d ’ % b l o c k )
’ e ’ + ’ %04d ’ % b l o c k )
’ s ’ + ’ %04d ’ % b l o c k )
’ w ’ + ’ %04d ’ % b l o c k )
’ t ’ + ’ %04d ’ % b l o c k )
’ b ’ + ’ %04d ’ % b l o c k )
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
print i n l e t s t r , o u t l e t s t r , w a l l s t r , s y m s t r
i f i n l e t s t r != ” ” :
c o m b i n e f a c e s ( c a s e d i r , s t a r t d i r , i n l e t s t r , i n n , ’ patch ’ )
N l i s t i n . append ( i n n )
i f o u t l e t s t r != ” ” :
c o m b i n e f a c e s ( c a s e d i r , s t a r t d i r , o u t l e t s t r , out n , ’ patch ’ )
N l i s t o u t . append ( o u t n )
i f w a l l s t r != ” ” :
combine faces ( case dir , s t a r t d i r , w a l l s t r , wall n , ’ wall ’ )
N l i s t w a l l . append ( w a l l n )
i f s y m s t r != ” ” :
c o m b i n e f a c e s ( c a s e d i r , s t a r t d i r , s y m s t r , sym n , ’ symmetry ’ )
N l i s t s y m . append ( sym n )
731
732
733
734
# c h e c k i f t h e r e a r e p a t c h e s r e m a i n i n g t h a t h a v e n t been d e f i n e d .
String1 = c h e c k f o r u n d e f i n e d f a c e s ( c a s e d i r , nblock )
String2 = c h e c k f o r u n d e f i n e d l a b e l s ( patch Label )
735
736
737
i f not ( S t r i n g 1 == [ ] ) :
w a r n s t r = w a r n s t r + ’WARNING: Not a l l e x t e r n a l b o u n d a r i e s were
d e f i n e d i n e 3 p r e p \n ’ + ’ Check t h e s e f a c e s : ’ + S t r i n g 1 + ’ \n ’
738
739
740
i f not ( S t r i n g 2 == [ ] ) :
w a r n s t r = w a r n s t r + ’WARNING: l a b e l s used t o d e f i n e boundary
f a c e s do not f o l l o w s t a n d a r d OF names \n ’ + ’ Check t h e s e l a b e l s
: ’ + S t r i n g 2 + ’ \n ’
741
742
743
# Option t o c r e a t e t e m p l a t e e n t r i e s f o r / 0 .
i f uoDict . h a s k e y ( ”−−c r e a t e 0 ” ) :
744
745
746
747
748
# c h e c k i f /0/ p f i l e e x i s t s
i f o s . path . i s f i l e ( c a s e d i r+ ’ /0/ ’+ ’ p ’ ) == 1 :
sh . c o p y f i l e ( c a s e d i r+ ’ /0/ ’+ ’ p ’ , c a s e d i r+ ’ /0/ ’+ ’ p . bak ’ )
w a r n s t r = w a r n s t r + ”WARNING: E x i s t i n g copy o f /0/p has been
c o p i e d t o /0/p . bak \n”
52
749
750
751
752
# c h e c k i f /0/U f i l e e x i s t s
i f o s . path . i s f i l e ( c a s e d i r+ ’ /0/ ’+ ’U ’ ) == 1 :
sh . c o p y f i l e ( c a s e d i r+ ’ /0/ ’+ ’U ’ , c a s e d i r+ ’ /0/ ’+ ’U. bak ’ )
w a r n s t r = w a r n s t r + ”WARNING: E x i s t i n g copy o f /0/U has been
c o p i e d t o /0/U. bak \n”
753
754
755
756
757
# U and p
these
file name
file name
OFFile0 =
t e m p l a t e a r e c r e a t e d . The o t h e r s can be d u p l i c a t e d form
= ”p”
= o s . path . j o i n ( ( c a s e d i r+ ’ /0/ ’ ) , f i l e n a m e )
open ( f i l e n a m e , ”wb” )
758
759
760
w r i t e g e n e r a l O p e n F o a m h e a d e r ( OFFile0 )
w r i t e p h e a d e r ( OFFile0 )
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
f o r n in range ( len ( N l i s t i n ) ) :
w r i t e p B o u n d a r y ( OFFile0 , N l i s t i n [ n ] , ’ z e r o G r a d i e n t ’ )
f o r n in range ( len ( N l i s t o u t ) ) :
w r i t e p B o u n d a r y ( OFFile0 , N l i s t o u t [ n ] , ’ z e r o G r a d i e n t ’ )
f o r n in range ( len ( N l i s t w a l l ) ) :
w r i t e p B o u n d a r y ( OFFile0 , N l i s t w a l l [ n ] , ’ z e r o G r a d i e n t ’ )
f o r n in range ( len ( N l i s t s y m ) ) :
w r i t e p B o u n d a r y ( OFFile0 , N l i s t s y m [ n ] , ’ symmetry ’ )
i f d i m e n s i o n s == 2 :
i f a x i s y m m e t r i c f l a g == 0 :
w r i t e p B o u n d a r y ( OFFile0 , ’ FrontBack ’ , ’ empty ’ )
else :
w r i t e p B o u n d a r y ( OFFile0 , ’ Front ’ , ’ wedge ’ )
w r i t e p B o u n d a r y ( OFFile0 , ’ Back ’ , ’ wedge ’ )
w r i t e p B o u n d a r y ( OFFile0 , ’ C e n t r e l i n e ’ , ’ empty ’ )
777
778
779
780
w r i t e g e n e r a l O p e n F o a m b o t t o m c u r l y ( OFFile0 )
OFFile0 . c l o s e ( )
print ” /0/p has been w r i t t e n . \n”
781
782
783
784
f i l e n a m e = ”U”
f i l e n a m e = o s . path . j o i n ( ( c a s e d i r+ ’ /0/ ’ ) , f i l e n a m e )
OFFile0 = open ( f i l e n a m e , ”wb” )
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
w r i t e g e n e r a l O p e n F o a m h e a d e r ( OFFile0 )
w r i t e U h e a d e r ( OFFile0 )
f o r n in range ( len ( N l i s t i n ) ) :
write U Boundary ( OFFile0 , N l i s t i n [ n ] , ’ f i x e d V a l u e ’ )
f o r n in range ( len ( N l i s t o u t ) ) :
write U Boundary ( OFFile0 , N l i s t o u t [ n ] , ’ z e r o G r a d i e n t ’ )
f o r n in range ( len ( N l i s t w a l l ) ) :
write U Boundary ( OFFile0 , N l i s t w a l l [ n ] , ’ z e r o G r a d i e n t ’ )
f o r n in range ( len ( N l i s t s y m ) ) :
write U Boundary ( OFFile0 , N l i s t s y m [ n ] , ’ symmetry ’ )
i f d i m e n s i o n s == 2 :
i f a x i s y m m e t r i c f l a g == 0 :
write U Boundary ( OFFile0 , ’ FrontBack ’ , ’ empty ’ )
else :
53
write U Boundary ( OFFile0 , ’ Front ’ , ’ wedge ’ )
write U Boundary ( OFFile0 , ’ Back ’ , ’ wedge ’ )
write U Boundary ( OFFile0 , ’ C e n t r e l i n e ’ , ’ empty ’ )
800
801
802
803
w r i t e g e n e r a l O p e n F o a m b o t t o m c u r l y ( OFFile0 )
OFFile0 . c l o s e ( )
print ” /0/U has been w r i t t e n . \n”
804
805
806
807
808
# Re−o r d e r numbering o f f a c e s / c e l l s f o r n u m e r i c a l e f f i c i e n c y
# e x e c u t e renumberMesh
os . chdir ( c a s e d i r )
f l a g = o s . system ( ’ renumberMesh −o v e r w r i t e ’ )
# move b a c k t o s t a r t i n g d i r e c t o r y
os . chdir ( s t a r t d i r )
i f f l a g != 0 :
r a i s e MyError ( ” Problem d u r i n g e x e c u t i o n o f renumberMesh . ” )
809
810
811
812
813
814
815
816
817
print w a r n s t r
818
819
820
821
822
if
name
== ” m a i n ” :
u s e r O p t i o n s = g e t o p t ( s y s . argv [ 1 : ] , s h o r t O p t i o n s , l o n g O p t i o n s )
uoDict = dict ( u s e r O p t i o n s [ 0 ] )
823
824
825
826
i f len ( u s e r O p t i o n s [ 0 ] ) == 0 or uoDict . h a s k e y ( ”−−h e l p ” ) :
printUsage ()
sys . exit (1)
827
828
829
830
831
832
833
834
835
836
try :
main ( uoDict )
print ” \n \n”
print ”SUCESS : The multi −b l o c k mesh c r e a t e d by e 3 p r e p . py has been
c o n v e r t e d i n t o a s i n g l e Polymesh f o r u s e with OpenFoam . ”
print ” \n \n”
except MyError a s e :
print ” This run o f e3prepToFoam . py has gone bad . ”
print e . v a l u e
sys . exit (1)
54