E3Preptofoam: A Mesh Generator For Openfoam

Download as pdf or txt
Download as pdf or txt
You are on page 1of 54

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 Open-
FOAM”, Mechanical Engineering Technical Report 2015/04, pp 1-66, The Uni-
versity 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 sim-
ulation. 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. setting of fill condition is not required, as this is defined in
case/0/...

• 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 com-
mands 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 cor-
rectly.)
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 de-
fined 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 condi-
tions 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 solu-
tions 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 Open-
FOAM 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 bound-
ary 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 exter-
nal 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

20
4
16
13 7
9 2 3
3
6 2
12 1
8

5
1 k
0 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
(a) Domain used for 2-D example and corre- (b) Blocking strategy for mesh and labels as
sponding boundary conditions. applied by e3prep.

Figure 2: Domain, boundary conditions, blocking strategy, and boundary labels for 2-D example.

5 Examples
5.1 2-D mesh
This example is based on the clippedCavity example (Section 2.1.9 and 2.1.10) from the Open-
FOAM 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

1 # c a v i t y C l i p p e d . py
2 # S im p l e j o b −s p e c i f i c a t i o n file f o r e 3 p r e p . py and e3prepToFoam . py
3 # IJ , 27−Apr−2015
4
5 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 . ”
6 print j o b t i t l e
7
8# 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 .
9 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
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 defining

14
14# t h e c o r n e r nodes , then the l i n e s between t h o s e corners .
15 a = Node ( 0 . 0 , 0 . 0 , l a b e l=”A” )
16 b = Node ( 0 . 6 , 0 . 0 , l a b e l=”B” )
17 c = Node ( 0 . 0 , 0 . 4 , l a b e l=”C” )
18 d = Node ( 0 . 6 , 0 . 4 , l a b e l=”D” )
19 e = Node ( 1 . 0 , 0 . 4 , l a b e l=”E” )
20 f = Node ( 0 . 0 , 1 . 0 , l a b e l=”F” )
21 g = Node ( 0 . 6 , 1 . 0 , l a b e l=”F” )
22 h = Node ( 1 . 0 , 1 . 0 , l a b e l=”F” )
23
24# Define Lines connecting b l o c k s
25 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 )
31
32 # 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 .
33 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” )
36 b l k 1 = Block2D ( make patch ( f g , dg , cd , c f ) , n n i=nx0 , n n j=ny1 ,
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” )
40
41 # 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
42 identify block connections ()
43
44# S e t boundary c o n d i t i o n s .
45 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 ” )
53
54 # command t o w r i t e BC l a b e l s
55 sketch . p r e f e r b c l a b e l s o n f a c e s ()
56
57# p l o t . svg
58 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 )

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 : 754
internal points : 0
faces : 1384
internal faces : 632
cells : 336
f a c e s per c e l l : 6
boundary p a t c h e s : 3
point zones : 0
face zones : 2
c e l l zones : 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 for multiply connected s u r f a c e s . . .


Patch Faces Points Surface topology
FrontBack 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 )
OF wall 00 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 )
OF wall 01 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:

1 /∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++ −∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\


2 | ========= | |
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 // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
17
18 dimensions [ 0 2 −2 0 0 0 0 ] ;
19
20 internalField uniform 0 ;
21
22 boundaryField
23 {
24 FrontBack
25 {
26 type empty ;
27 }
28 OF wall 00
29 {
30 type zeroGradient ;
31 }

17
32 OF wall 01
33 {
34 type zeroGradient ;
35 }
36 }
37
38
39 // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //

1 /∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++ −∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\


2 | ========= | |
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 // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //
17
18 dimensions [ 0 1 −1 0 0 0 0 ] ;
19
20 internalField uniform (0 0 0) ;
21
22 boundaryField
23 {
24 FrontBack
25 {
26 type empty ;
27 }
28 OF wall 00
29 {
30 type fixedValue ;
31 value uniform (1 0 0) ;
32 }
33 OF wall 01
34 {
35 type fixedValue ;
36 value uniform (0 0 0) ;
37 }
38 }
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 Fig-
ure 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

1 # c o n d i v . py
2 # S im p l e j o b −s p e c i f i c a t i o n file f o r e 3 p r e p . py and e3prepToFoam . py
3 # IJ , 27−Apr−2015
4
5 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 . ”
6 print j o b t i t l e
7
8# 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 .
9 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
12
13 # 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
14 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” )
23
24# Define s t r a i g h t Lines
25 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
27

20
28 # 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
29 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 .
36
37 def path1 ( t ) :
38 global R0
39 global L0
40 x = (1+ t ) ∗ L0
41 y = R0 ∗ ( 0 . 7 5 + 0 . 2 5 ∗ np . c o s ( ( t +1.) ∗ np . p i ) )
42 return x , y , 0 .
43
44 # D e f i n e N o z z l e Contours
45 de = PyFunctionPath ( path0 ) ; e f = PyFunctionPath ( path1 )
46
47 # 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 .
48 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” )
53
54 # 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
55 identify block connections ()
56
57# S e t boundary c o n d i t i o n s .
58 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 ” )
62
63 # command t o w r i t e BC l a b e l s
64 sketch . p r e f e r b c l a b e l s o n f a c e s ()
65
66# p l o t . svg
67 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 )

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 for multiply connected s u r f a c e s . . .


Patch Faces Points Surface topology
Back 200 231 ok ( non−c l o s e d s i n g l y connected )
Front 200 231 ok ( non−c l o s e d s i n g l y connected )
OF inlet 00 10 21 ok ( non−c l o s e d s i n g l y connected )
OF outlet 00 10 21 ok ( non−c l o s e d s i n g l y connected )
OF wall 00 20 42 ok ( non−c l o s e d s i n g l y 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 wedge ;
}
Front
{
type wedge ;
}
OF inlet 00
{
type zeroGradient ;
}
OF outlet 00
{
type zeroGradient ;
}
OF wall 00
{
type 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 wedge ;
}
Front
{
type wedge ;
}
OF inlet 00
{
type fixedValue ;
value uniform (1 0 0) ;
}
OF outlet 00
{
type zeroGradient ;
}
OF wall 00
{
type fixedValue ;
value 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 = 0.0510/2.0 # inner radius


r2 = 0.1016/2.0 # outer radius
h1 = 0.0
h2 = 3 . 0 e−3

# 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 = Vector ( r 1 ∗ cos ( i n i 1 ) , r 1 ∗ sin ( ini1 ) , inih1 )


up1 = Vector ( r 2 ∗ cos ( i n i 1 ) , r 2 ∗ sin ( ini1 ) , inih1 )
up2 = Vector ( r 2 ∗ cos ( i n i 2 ) , r 2 ∗ sin ( ini2 ) , inih1 )
up3 = Vector ( r 1 ∗ cos ( i n i 2 ) , r 1 ∗ sin ( ini2 ) , inih1 )
up4 = Vector ( r 1 ∗ cos ( i n i 1 ) , r 1 ∗ sin ( ini1 ) , inih2 )
up5 = Vector ( r 2 ∗ cos ( i n i 1 ) , r 2 ∗ sin ( ini1 ) , inih2 )
up6 = Vector ( r 2 ∗ cos ( i n i 2 ) , r 2 ∗ sin ( ini2 ) , inih2 )
up7 = Vector ( r 1 ∗ cos ( i n i 2 ) , r 1 ∗ sin ( ini2 ) , inih2 )

up01 = L i n e ( up0 , up1 )


up12 = Arc ( up1 , up2 , c e n t e r b )
up32 = L i n e ( up3 , up2 )
up03 = Arc ( up0 , up3 , c e n t e r b )
up45 = L i n e ( up4 , up5 )

25
up56 = Arc ( up5 , up6 , c e n t e r t )
up76 = L i n e ( up7 , up6 )
up47 = Arc ( up4 , up7 , c e n t e r t )
up04 = L i n e ( up0 , up4 )
up15 = L i n e ( up1 , up5 )
up26 = L i n e ( up2 , up6 )
up37 = L i n e ( up3 , up7 )

return WireFrameVolume ( up01 , up12 , up32 , up03 , up45 , up56 ,


up76 , up47 , up04 , up15 , up26 , up37 )

# set cluster functions


c x = RobertsClusterFunction (1 ,1 ,1.0)
c y = RobertsClusterFunction (1 ,1 ,1.0)
c z = 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 Boundary C o n d i t i o n s
blk0 . b c l i s t [NORTH] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 0 ’ )
blk0 . b c l i s t [ EAST ] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 1 ’ )
blk0 . b c l i s t [SOUTH] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 0 ’ )
blk0 . b c l i s t [WEST] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 2 ’ )
blk0 . b c l i s t [TOP] = ExtrapolateOutBC ( l a b e l= ’ O F w a l l 0 0 ’ )
blk0 . b c 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 zeroGradient ;
}
OF wall 01
{
type fixedValue ;
value uniform 340;
}
OF wall 02
{
type fixedValue ;
value 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 Example-
Book, 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 Uni-
versity of Queensland

7 Appendix
7.1 Addition to e3post.py
Following function has been added to e3post.py to enable conversion of e3prep blocks to cor-
responding 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 ( ” | ======== |
| \ n” )
f p . w r i t e ( ” | \\ / F ield | OpenFOAM: The Open S o u r c e CFD
Toolbox | \ n” )
f p . w r i t e ( ” | \\ / O peration | Version : 2.2.2
| \ n” )
fp . write ( ” | \\ / A nd | Web : www.OpenFOAM. o r g
| \ n” )
fp . write ( ” | \\/ M anipulation| This f i l e g e n e r a t e d by e 3 p o s t .
py | \ n” )
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 id [( 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 ) ]
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 i d [ ( i +1, j
, 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 id [( i , j
+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 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) ]
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
fp4 . write ( ” }\n” )
# East boundary
fp4 . write ( ” e%04d\n” % ( j b ) )
fp4 . write ( ” {\n” )
fp4 . write ( ” type w a l l ; \ n” )
fp4 . write ( ” nFaces %d ; \ n” % (SumOfEF) )
fp4 . write ( ” startFace %d ; \ n” % ( E F s t a r t ) )
fp4 . write ( ” }\n” )
# South boundary
fp4 . write ( ” s%04d\n” % ( j b ) )
fp4 . write ( ” {\n” )
fp4 . write ( ” type w a l l ; \ n” )
fp4 . write ( ” nFaces %d ; \ n” % ( SumOfSF ) )
fp4 . write ( ” startFace %d ; \ n” % ( S F s t a r t ) )
fp4 . write ( ” }\n” )
# Bottom boundary
fp4 . write ( ” b%04d\n” % ( j b ) )
fp4 . write ( ” {\n” )
fp4 . write ( ” type w a l l ; \ n” )
fp4 . write ( ” nFaces %d ; \ n” % (SumOfBF) )
fp4 . write ( ” startFace %d ; \ n” % ( B F s t a r t ) )
fp4 . write ( ” }\n” )
# Top boundary
fp4 . write ( ” t%04d\n” % ( j b ) )
fp4 . write ( ” {\n” )
fp4 . write ( ” type w a l l ; \ n” )
fp4 . write ( ” nFaces %d ; \ n” % (SumOfTF) )
fp4 . write ( ” startFace %d ; \ n” % ( T F s t a r t ) )
fp4 . write ( ” }\n” )
return

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

1 #! / u s r / b i n / env p y t h o n
2 ”””
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
8

9 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 :
10 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

37
12 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
13 4) s t i t c h i n t e r n a l f a c e s
14 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
15 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) :
16 − OF inlet XX
17 − OF outlet XX
18 − OF wall XX
19 − OF symmetry XX
20 − 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 .
21 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 Author : Ingo Jahn 03/02/2015


24 ”””
25

26 import o s a s o s
27 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
31

32 shortOptions = ””
33 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

35 def p r i n t U s a g e ( ) :
36 print ” ”
37 print ” Usage : e3prepToFoam . py [−− h e l p ] [−− j o b=<jobFileName >] [−−
create 0 ] ”
38 return
39

40

41 def g e t f o l d e r s ( ) :
42 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
56

57 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 ) :
58 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 flag = 0
60 i f o s . path . e x i s t s ( c a s e d i r+ ’ /0 ’ ) i s not True :
61 flag = 1
62 print ” M i s s i n g /0 d i r e c t o r y ”
63 i f o s . path . e x i s t s ( c a s e d i r+ ’ / system ’ ) i s not True :
64 flag = 1
65 print ” M i s s i n g / system d i r e c t o r y ”
66 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 :
67 flag = 1
68 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 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 :


71 flag = 1
72 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 ”
73 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 :
74 flag = 1
75 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 ”
76 print ’ \n ’
77 return f l a g
78

79

80 def f a c e i n d e x t o s t r i n g ( i n d ) :
81 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
96

97 def g e t j o b c o n f i g d a t a ( j o b ) :
98 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 ] )

39
111 break
112 # f i n d number o f b l o c k s
113 f o r l i n e in f :
114 i f ” n b l o c k ” in l i n e :
115 temp = l i n e . s p l i t ( )
116 n b l o c k = i n t ( temp [ 2 ] )
117 break
118

119 o t h e r b l o c k = np . z e r o s ( ( nblock , 6 ) )
120 o t h e r f a c e = np . z e r o s ( ( nblock , 6 ) )
121 # find connecting blocks
122 f . seek (0 ,0)
123 block = 0
124 face = 0
125 f o r l i n e in f :
126 i f ” o t h e r b l o c k ” in l i n e :
127 temp = l i n e . s p l i t ( )
128 o t h e r b l o c k [ b l o c k , f a c e ] = i n t ( temp [ 2 ] )
129 face = face + 1
130 i f d i m e n s i o n s == 2 :
131 i f f a c e == 4 :
132 o t h e r b l o c k [ b l o c k , 4 ] = −1
133 o t h e r b l o c k [ b l o c k , 5 ] = −1
134 face = 0
135 block = block + 1
136 e l i f d i m e n s i o n s == 3 :
137 i f f a c e == 6 :
138 face = 0
139 block = block + 1
140 # find connecting faces
141 f . seek (0 ,0)
142 block = 0
143 face = 0
144 f o r l i n e in f :
145 i f ” o t h e r f a c e ” in l i n e :
146 temp = l i n e . s p l i t ( )
147 i f temp [ 2 ] == ” none ” :
148 o t h e r f a c e [ b l o c k , f a c e ] = −1
149 e l i f temp [ 2 ] == ” n o r t h ” :
150 o t h e r f a c e [ block , f a c e ] = 0
151 e l i f temp [ 2 ] == ” e a s t ” :
152 o t h e r f a c e [ block , f a c e ] = 1
153 e l i f temp [ 2 ] == ” s o u t h ” :
154 o t h e r f a c e [ block , f a c e ] = 2
155 e l i f temp [ 2 ] == ” west ” :
156 o t h e r f a c e [ block , f a c e ] = 3
157 e l i f temp [ 2 ] == ” top ” :
158 o t h e r f a c e [ block , f a c e ] = 4
159 e l i f temp [ 2 ] == ” bottom ” :
160 o t h e r f a c e [ block , f a c e ] = 5
161 else :
162 print ” E r r o r ”
163 face = face + 1

40
164 i f d i m e n s i o n s == 2 :
165 i f f a c e == 4 :
166 o t h e r f a c e [ b l o c k , 4 ] = −1
167 o t h e r f a c e [ b l o c k , 5 ] = −1
168 face = 0
169 block = block + 1
170 e l i f d i m e n s i o n s == 3 :
171 i f f a c e == 6 :
172 face = 0
173 block = block + 1
174 # f i n d boundary l a b e l s
175 f . seek (0 ,0)
176 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 ) ]
177 f o r b l o c k in range ( n b l o c k ) :
178 i f d i m e n s i o n s == 2 :
179 f o r f a c e in range ( 4 ) :
180 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 ” )
181 temp = temp . s p l i t ( )
182 i f len ( temp ) == 3 :
183 L a b e l [ b l o c k ] [ f a c e ] = temp [ 2 ]
184 # p r i n t ” I was h e r e ” , b l o c k , f a c e , temp [ 2 ]
185 else :
186 L a b e l [ b l o c k ] [ f a c e ] = ”EMPTY”
187 L a b e l [ b l o c k ] [ 4 ] = ”EMPTY”
188 L a b e l [ b l o c k ] [ 5 ] = ”EMPTY”
189 i f d i m e n s i o n s == 3 :
190 f o r f a c e in range ( 6 ) :
191 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 ” )
192 temp = temp . s p l i t ( )
193 i f len ( temp ) == 3 :
194 L a b e l [ b l o c k ] [ f a c e ] = temp [ 2 ]
195 # p r i n t ” I was h e r e ” , b l o c k , f a c e , temp [ 2 ]
196 else :
197 L a b e l [ b l o c k ] [ f a c e ] = ”EMPTY”
198 f . close ()
199 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

202 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 ) :


203 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 :

41
216 print ” wrong face index ”
217 fp . seek (0 ,0)
218 f o r num , l i n e in enumerate ( fp , 1 ) :
219 i f p h r a s e in line :
220 break
221 f o r l i n e in f p :
222 i f lo oku p in line :
223 break
224 return l i n e
225

226

227 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 ) :
228 f p . w r i t e ( ”/∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗− C++
−∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗\\\n” )
229 f p . w r i t e ( ” | ======== |
| \ n” )
230 f p . w r i t e ( ” | \\ / F ield | OpenFOAM: The Open S o u r c e CFD
Toolbox | \ n” )
231 f p . w r i t e ( ” | \\ / O peration | Version : 2.2.2
| \ n” )
232 fp . write ( ” | \\ / A nd | Web : www.OpenFOAM. o r g
| \ n” )
233 fp . write ( ” | \\/ M anipulation| This f i l e g e n e r a t e d by e 3 p o s t .
py | \ n” )
234 fp . write ( ”
\∗−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−∗/\
n” )
235 f p . w r i t e ( ” FoamFile \n” )
236 f p . w r i t e ( ” {\n” )
237 fp . write ( ” version 2 . 0 ; \ n” )
238 fp . write ( ” f ormat a s c i i ; \ n” )
239 return
240

241 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 ) :
242 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
246

247 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 ) :
248 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
252

253 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 ) :
254 #
255 # −−−−−−−−−−−−−−−−−−− w r i t i n g f i l e s now −−−−−−−−−−−−−−−−−−−−−−−−−−−−−
256 # points

42
257 fp . write ( ” class d i c t i o n a r y ; \ n” )
258 fp . write ( ” object c r e a t e P a t c h D i c t ; \ n” )
259 f p . w r i t e ( ” }\n” )
260 f p . w r i t e ( ” // ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗
∗ ∗ ∗ ∗ ∗ ∗ ∗ ∗ //\n” )
261 f p . w r i t e ( ” \n” )
262 f p . w r i t e ( ” p o i n t S y n c f a l s e ; \ n” )
263 f p . w r i t e ( ” // P a t c h e s t o c r e a t e . \n” )
264 f p . w r i t e ( ” p a t c h e s \n” )
265 f p . w r i t e ( ” ( \ n” )
266 return
267

268 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 ) :
269 #
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
286

287

288 def w r i t e p h e a d e r ( f p ) :
289 #
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
305

43
306 def w r i t e U h e a d e r ( f p ) :
307 #
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
323

324 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 ) :


325 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
335

336 def w r i t e p B o u n d a r y ( fp , bname , btype ) :


337 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
354

355 def write U Boundary ( fp , bname , btype ) :


356 fp . write ( ” ”+bname+” \n” )

44
357 fp . write ( ” {\n” )
358 i f btype == ” z e r o G r a d i e n t ” :
359 fp . write ( ” type z e r o G r a d i e n t ; \n” )
360 e l i f btype == ”empty” :
361 fp . write ( ” type empty ; \n” )
362 e l i f btype == ” wedge ” :
363 fp . write ( ” type wedge ; \n” )
364 e l i f btype == ” symmetry ” :
365 fp . write ( ” type symmetry ; \n” )
366 e l i f btype == ” f i x e d V a l u e ” :
367 fp . write ( ” type f i x e d V a l u e ; \n” )
368 fp . write ( ” value uni for m ( 0 0 0 ) ; \n” )
369 else :
370 print ( ” Boundary type , ” + btype + ” not r e c o g n i s e d . S e t t i n g empty”
)
371 fp . write ( ” }\n” )
372 return
373

374 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 ) :


375 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” )
378

379 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 )
380 w r i t e c r e a t e P a t c h h e a d e r ( OFFile0 )
381 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 )
382 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 )
383 OFFile0 . c l o s e ( )
384 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”
385 # execute createPatch
386 os . chdir ( c a s e d i r )
387 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 ’ )
388 # move b a c k t o s t a r t i n g d i r e c t o r y
389 os . chdir ( s t a r t d i r )
390 i f f l a g == 0 :
391 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 )
392 else :
393 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 . ” )
394 return
395

396 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 d i r , nblock ) :


397 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 d i r+ ’ / c o n s t a n t / polyMesh / ’ ) , f i l e n a m 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 line :
404 S t r i n g . append ( l i n e + ’; ’)
405 i f ( ’ e ’+ ’ %04d ’ % n ) in line :
406 S t r i n g . append ( l i n e + ’; ’)

45
407 i f ( ’ s ’+ ’ %04d ’ % n ) in line :
408 S t r i n g . append ( l i n e + ’; ’)
409 i f ( ’w ’+ ’ %04d ’ % n ) in line :
410 S t r i n g . append ( l i n e + ’; ’)
411 File . seek (0 ,0)
412 File . close ()
413 return S t r i n g
414

415

416 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 ) :
417 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 )
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

430 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 ) :
431 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” )
434

435 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 )
436 w r i t e c o l l a p s e D i c t h e a d e r ( OFFile0 )
437 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 )
438 OFFile0 . c l o s e ( )
439 print ” c o l l a p s e D i c t has been w r i t t e n . \n”
440 # execute createPatch
441 os . chdir ( c a s e d i r )
442 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 ’ )
443 # move b a c k t o s t a r t i n g d i r e c t o r y
444 os . chdir ( s t a r t d i r )
445 i f f l a g == 0 :
446 print ( ” A l i g n e d e d g e s have been c o l l a p s e d ” )
447 else :
448 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 c l a s s MyError ( E x c e p t i o n ) :
453 def i n i t ( s e l f , value ) :
454 s e l f . value = value
455 def str ( self ) :
456 return repr ( s e l f . v a l u e )
457

458

459 def main ( uoDict ) :

46
460 # c r e a t e s t r i n g t o c o l l e c t warning messages
461 w a r n s t r = ” \n”
462

463 # main f i l e t o be e x e c u t e d
464 jobName = uoDict . g e t ( ”−−j o b ” , ” t e s t ” )
465

466 # s t r i p . py e x t e n s i o n form jobName


467 jobName = jobName . s p l i t ( ’ . ’ )
468 jobName = jobName [ 0 ]
469

470 # 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


471 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 # 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
474 dir flag = check case structure ( case dir , root dir )
475 i f d i r f l a g == 1 :
476 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 # change i n t o e 3 p r e p d i r e c t o r y
479 o s . c h d i r ( ( c a s e d i r+ ’ / e 3 p r e p ’ ) )
480

481 # g e t d a t a from j o b . c o n f i g
482 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 # 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
485 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 ) ) :
486 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 ’ )
487 # 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
488 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 # merging i n d i v i d u a l b l o c k s
493 print ( ’ Working on Case = ’+case name )
494

495 ## move d a t a c u r r e n t l y i n / polMesh


496 #sh . move ( ’ polyMesh ’ , ’ p o l y M e s h o l d ’ )
497 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 # create case f i l e for slave mesh


500 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 f o r b l o c k in range ( nblock −1) :


506 # 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
507 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 # e x e c u t e mergeMeshes command


510 os . chdir ( r o o t d i r )
511 f l a g = o s . system ( ’ mergeMeshes −o v e r w r i t e ’ + case name + ’
slave mesh ’ )
512 i f f l a g == 0 :
513 print ( ’ Block ’ + ’ %04d ’ % b l o c k + ’ and ’ + ’ %04d ’ % ( b l o c k +1)
+ ’ have been merged . ’ )
514 else :
515 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
516 os . chdir ( s t a r t d i r )
517 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 # remove polyMesh from s l a v e m e s h


520 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 # remove s l a v e mesh


523 sh . r m t r e e ( r o o t d i r+ ’ / s l a v e m e s h ’ )
524 # move b a c k t o starting directory
525 os . chdir ( s t a r t dir )
526

527 print ” Merging o f meshes c o m p l e t e . \n \n ”


528

529 # 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


530 i f a x i s y m m e t r i c f l a g == 1 :
531 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”
532 flag = collapse faces ( case dir , start dir )
533

534 #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
535 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
536 if interfaces > 0:
537

538 # move /0 d i r e c t o r y
539 sh . move ( ( c a s e d i r + ’ /0 ’ ) , c a s e d i r + ’ /temp ’ )
540

541 while True :


542 ( b l o c k , f a c e ) = np . where ( o t h e r b l o c k != −1)
543 i f len ( b l o c k ) == 0 :
544 break
545

546 # print ( block , face )


547 o block = other block [ block [ 0 ] , face [ 0 ] ]
548 o face = o t h e r f a c e [ block [ 0 ] , face [ 0 ] ]

48
549

550 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 ] )
551 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 # 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
556 o t h e r b l o c k [ o b l o c k , o f a c e ] = −1
557 o t h e r f a c e [ o b l o c k , o f a c e ] = −1
558 o t h e r b l o c k [ b l o c k [ 0 ] , f a c e [ 0 ] ] = −1
559

560 # e x e c u t e s t i t c h M e s h command
561 os . chdir ( c a s e d i r )
562 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 )
563 # move b a c k t o s t a r t i n g d i r e c t o r y
564 os . chdir ( s t a r t d i r )
565 i f f l a g == 0 :
566 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 . ’ )
567 else :
568 r a i s e MyError ( ’ E r r o r with s t i t c h M e s h . ’ )
569

570 # move /0 d i r e c t o r y b a c k
571 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 # 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
576 i f a x i s y m m e t r i c f l a g == 1 :
577 name = ” C e n t r e l i n e ”
578 c e n t s t r = ””
579 f o r b l o c k in range ( n b l o c k ) :
580 L block = patch Label [ block ]
581 #p r i n t L b l o c k
582 i n d = [ n f o r n , s in enumerate ( L b l o c k ) i f name in s ]
583

584 i f i n d != [ ] :
585 f o r n in i n d :
586 i f n == 0 :
587 cent str = ( c e n t s t r + ’ n ’ + ’ %04d ’ % b l o c k )
588 i f n == 1 :
589 cent str = ( c e n t s t r + ’ e ’ + ’ %04d ’ % b l o c k )
590 i f n == 2 :
591 cent str = ( c e n t s t r + ’ s ’ + ’ %04d ’ % b l o c k )
592 i f n == 3 :
593 cent str = ( c e n t s t r + ’ w ’ + ’ %04d ’ % b l o c k )
594 i f n == 4 :
595 cent str = ( c e n t s t r + ’ t ’ + ’ %04d ’ % b l o c k )
596 i f n == 5 :
597 cent str = ( c e n t s t r + ’ b ’ + ’ %04d ’ % b l o c k )

49
598 print c e n t s t r
599 i f c e n t s t r != ” ” :
600 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 ’ )
601

602 # 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
603 # t o p and bottom f a c e s
604 i f d i m e n s i o n s == 2 :
605 i f a x i s y m m e t r i c f l a g == 0 :
606 # c r e t e empty FrontBack p a t c h
607 patch str = ’ ’
608 f o r i in range ( n b l o c k ) :
609 p a t c h s t r = ( p a t c h s t r+ ’ b ’+ ’ %04d ’ % i + ’ t ’ + ’ %04d ’ % i
)
610 patch name = ’ FrontBack ’
611 p a t c h t y p e = ’ empty ’
612 combine faces ( case dir , start dir , patch str , patch name ,
patch type )
613 e l i f a x i s y m m e t r i c f l a g == 1 :
614 # c r e a t e p a i r o f wedge p a t c h e s
615 patch str = ’ ’
616 f o r i in range ( n b l o c k ) :
617 p a t c h s t r = ( p a t c h s t r+ ’ b ’+ ’ %04d ’ % i)
618 patch name = ’ Back ’
619 p a t c h t y p e = ’ wedge ’
620 combine faces ( case dir , start dir , patch str , patch name ,
patch type )
621 patch str = ’ ’
622 f o r i in range ( n b l o c k ) :
623 p a t c h s t r = ( p a t c h s t r+ ’ t ’+ ’ %04d ’ % i)
624 patch name = ’ Front ’
625 p a t c h t y p e = ’ wedge ’
626 combine faces ( case dir , start dir , patch str , patch name ,
patch type )
627

628 # combine p a t c h e s , b a s e d on b l o c k l a b e l .
629 # Following l a b e l s are supported :
630 # 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)
631 # 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)
632 # OF wall 00 , OF wall 01 , O F w a l l 0 2 ( up t o 09)
633 # OF symmetry 00 , OF symmetry 01 , OF symmetry 02 ( up t o 09)
634

635 N list in = []
636 N list out = [ ]
637 N list wall = []
638 N list sym = [ ]
639

640 f o r i in range ( 1 0 ) :
641 i n n = ( ” O F i n l e t ”+ ’ %02d ’ % i )
642 o u t n = ( ” O F o u t l e t ”+ ’ %02d ’ % i )
643 w a l l n = ( ” OF wall ”+ ’ %02d ’ % i )
644 sym n = ( ” OF symmetry ”+ ’ %02d ’ % i )
645

646 i n l e t s t r = ””

50
647 o u t l e t s t r = ””
648 w a l l s t r = ””
649 sym str = ””
650 f o r b l o c k in range ( n b l o c k ) :
651 L block = patch Label [ block ]
652 #p r i n t L b l o c k
653 i i n d = [ n f o r n , s in enumerate ( L block ) if i n n in s ]
654 o i n d = [ n f o r n , s in enumerate ( L block ) if o u t n in s ]
655 w ind = [ n f o r n , s in enumerate ( L block ) if w a l l n in s ]
656 s i n d = [ n f o r n , s in enumerate ( L block ) if sym n in s ]
657 #p r i n t i i n d != [ ]
658 #p r i n t o i n d != [ ]
659

660 i f i i n d != [ ] :
661 f o r n in i i n d :
662 i f n == 0 :
663 inlet str = ( inlet str + ’ n ’ + ’ %04d ’ % b l o c k )
664 i f n == 1 :
665 inlet str = ( inlet str + ’ e ’ + ’ %04d ’ % b l o c k )
666 i f n == 2 :
667 inlet str = ( inlet str + ’ s ’ + ’ %04d ’ % b l o c k )
668 i f n == 3 :
669 inlet str = ( inlet str + ’ w ’ + ’ %04d ’ % b l o c k )
670 i f n == 4 :
671 inlet str = ( inlet str + ’ t ’ + ’ %04d ’ % b l o c k )
672 i f n == 5 :
673 inlet str = ( inlet str + ’ b ’ + ’ %04d ’ % b l o c k )
674 i f o i n d != [ ] :
675 f o r n in o i n d :
676 i f n == 0 :
677 outlet str = ( outlet str + ’ n ’ + ’ %04d ’ % b l o c k )
678 i f n == 1 :
679 outlet str = ( outlet str + ’ e ’ + ’ %04d ’ % b l o c k )
680 i f n == 2 :
681 outlet str = ( outlet str + ’ s ’ + ’ %04d ’ % b l o c k )
682 i f n == 3 :
683 outlet str = ( outlet str + ’ w ’ + ’ %04d ’ % b l o c k )
684 i f n == 4 :
685 outlet str = ( outlet str + ’ t ’ + ’ %04d ’ % b l o c k )
686 i f n == 5 :
687 outlet str = ( outlet str + ’ b ’ + ’ %04d ’ % b l o c k )
688 i f w ind != [ ] :
689 f o r n in w ind :
690 i f n == 0 :
691 wall str = ( wall str + ’ n ’ + ’ %04d ’ % b l o c k )
692 i f n == 1 :
693 wall str = ( wall str + ’ e ’ + ’ %04d ’ % b l o c k )
694 i f n == 2 :
695 wall str = ( wall str + ’ s ’ + ’ %04d ’ % b l o c k )
696 i f n == 3 :
697 wall str = ( wall str + ’ w ’ + ’ %04d ’ % b l o c k )
698 i f n == 4 :
699 wall str = ( wall str + ’ t ’ + ’ %04d ’ % b l o c k )

51
700 i f n == 5 :
701 wall str = ( wall str + ’ b ’ + ’ %04d ’ % b l o c k )
702 i f s i n d != [ ] :
703 f o r n in s i n d :
704 i f n == 0 :
705 sym str = ( sym str + ’ n ’ + ’ %04d ’ % b l o c k )
706 i f n == 1 :
707 sym str = ( sym str + ’ e ’ + ’ %04d ’ % b l o c k )
708 i f n == 2 :
709 sym str = ( sym str + ’ s ’ + ’ %04d ’ % b l o c k )
710 i f n == 3 :
711 sym str = ( sym str + ’ w ’ + ’ %04d ’ % b l o c k )
712 i f n == 4 :
713 sym str = ( sym str + ’ t ’ + ’ %04d ’ % b l o c k )
714 i f n == 5 :
715 sym str = ( sym str + ’ b ’ + ’ %04d ’ % b l o c k )
716

717

718 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
719 i f i n l e t s t r != ” ” :
720 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 ’ )
721 N l i s t i n . append ( i n n )
722 i f o u t l e t s t r != ” ” :
723 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 ’ )
724 N l i s t o u t . append ( o u t n )
725 i f w a l l s t r != ” ” :
726 combine faces ( case dir , s t a r t d i r , w a l l s t r , wall n , ’ wall ’ )
727 N l i s t w a l l . append ( w a l l n )
728 i f s y m s t r != ” ” :
729 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 ’ )
730 N l i s t s y m . append ( sym n )
731

732 # 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 .
733 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 )
734 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 i f not ( S t r i n g 1 == [ ] ) :
737 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 i f not ( S t r i n g 2 == [ ] ) :
740 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 # 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 .
743 i f uoDict . h a s k e y ( ”−−c r e a t e 0 ” ) :
744

745 # c h e c k i f /0/ p f i l e e x i s t s
746 i f o s . path . i s f i l e ( c a s e d i r+ ’ /0/ ’+ ’ p ’ ) == 1 :
747 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 ’ )
748 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 # c h e c k i f /0/U f i l e e x i s t s
750 i f o s . path . i s f i l e ( c a s e d i r+ ’ /0/ ’+ ’U ’ ) == 1 :
751 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 ’ )
752 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 # U and p 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


these
755 file name = ”p”
756 file name = o s . path . j o i n ( ( c a s e d i r+ ’ /0/ ’ ) , f i l e n a m e )
757 OFFile0 = open ( f i l e n a m e , ”wb” )
758

759 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 )
760 w r i t e p h e a d e r ( OFFile0 )
761

762 f o r n in range ( len ( N l i s t i n ) ) :


763 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 ’ )
764 f o r n in range ( len ( N l i s t o u t ) ) :
765 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 ’ )
766 f o r n in range ( len ( N l i s t w a l l ) ) :
767 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 ’ )
768 f o r n in range ( len ( N l i s t s y m ) ) :
769 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 ’ )
770 i f d i m e n s i o n s == 2 :
771 i f a x i s y m m e t r i c f l a g == 0 :
772 w r i t e p B o u n d a r y ( OFFile0 , ’ FrontBack ’ , ’ empty ’ )
773 else :
774 w r i t e p B o u n d a r y ( OFFile0 , ’ Front ’ , ’ wedge ’ )
775 w r i t e p B o u n d a r y ( OFFile0 , ’ Back ’ , ’ wedge ’ )
776 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 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 )
779 OFFile0 . c l o s e ( )
780 print ” /0/p has been w r i t t e n . \n”
781

782 f i l e n a m e = ”U”
783 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 )
784 OFFile0 = open ( f i l e n a m e , ”wb” )
785

786 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 )
787 w r i t e U h e a d e r ( OFFile0 )
788 f o r n in range ( len ( N l i s t i n ) ) :
789 write U Boundary ( OFFile0 , N l i s t i n [ n ] , ’ f i x e d V a l u e ’ )
790 f o r n in range ( len ( N l i s t o u t ) ) :
791 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 ’ )
792 f o r n in range ( len ( N l i s t w a l l ) ) :
793 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 ’ )
794 f o r n in range ( len ( N l i s t s y m ) ) :
795 write U Boundary ( OFFile0 , N l i s t s y m [ n ] , ’ symmetry ’ )
796 i f d i m e n s i o n s == 2 :
797 i f a x i s y m m e t r i c f l a g == 0 :
798 write U Boundary ( OFFile0 , ’ FrontBack ’ , ’ empty ’ )
799 else :

53
800 write U Boundary ( OFFile0 , ’ Front ’ , ’ wedge ’ )
801 write U Boundary ( OFFile0 , ’ Back ’ , ’ wedge ’ )
802 write U Boundary ( OFFile0 , ’ C e n t r e l i n e ’ , ’ empty ’ )
803

804 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 )
805 OFFile0 . c l o s e ( )
806 print ” /0/U has been w r i t t e n . \n”
807

808

809 # 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


810 # e x e c u t e renumberMesh
811 os . chdir ( c a s e d i r )
812 f l a g = o s . system ( ’ renumberMesh −o v e r w r i t e ’ )
813 # move b a c k t o s t a r t i n g d i r e c t o r y
814 os . chdir ( s t a r t d i r )
815 i f f l a g != 0 :
816 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 . ” )
817

818 print w a r n s t r
819

820 if name == ” m a i n ” :
821 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 )
822 uoDict = dict ( u s e r O p t i o n s [ 0 ] )
823

824 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 ” ) :


825 printUsage ()
826 sys . exit (1)
827

828 try :
829 main ( uoDict )
830 print ” \n \n”
831 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 . ”
832 print ” \n \n”
833 except MyError a s e :
834 print ” This run o f e3prepToFoam . py has gone bad . ”
835 print e . v a l u e
836 sys . exit (1)

54

You might also like