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