PhilipCardiff-UCD-Introduction to Meshing in...
Transcript of PhilipCardiff-UCD-Introduction to Meshing in...
Philip Cardiff
Introduction to Meshing in OpenFOAM
Philip Cardiff
!
!
!
!
Assistant Professor Bekaert Lecturer in Materials Processing
School of Mechanical & Materials Engineering University College Dublin
16th - 17th January 2017
Introduction to Meshing in OpenFOAM
5th UK & Éire FOAM/OpenFOAM User Day University College Dublin
Dublin, Ireland
OpenFOAM® is a trademark of OpenCFD (ESI Group). This presentation is not approved or endorsed by OpenCFD or ESI Group, the owner of the OpenFOAM® trademark.
Disclaimer
4
In this training, you will (hopefully) learn: • About meshes in OpenFOAM • How to generate, convert & manipulate meshes in OpenFOAM • How to use the OpenFOAM blockMesh utility • How to modify and create a blockMeshDict • How to import a mesh, created with a third-party software,
into OpenFOAM • How to create a Cartesian mesh using the OpenFOAM snappyHexMesh utility
Learning Objectives
Introduction to meshes in OpenFOAM
6
Types of Meshes
Computational meshes can be broadly categorised into two main types, based on by their connectivity:
• Structured: characterised by repeated regularity of a primitive shape in space, or regular topology. The flow-aligned hexahedral elements provided by structured meshes can improved solution accuracy with minimal number of cells; however, creating the mesh topology can be time-consuming.
• Unstructured: characterised by irregular vertex connectivity with no underlying primitive shape repetition. These meshes are typically more flexible and easier to create, saving time; however, larger numbers of cells may be needed for similar accuracy to structured meshes.
http://www.pointwise.com/theconnector/May-2012/Overset-Fig1-Grid-Types-1512x468.png
7
Checking the quality of the mesh
You can check the quality of the OpenFOAM mesh using: $> checkMesh (we will try this later)
Important mesh properties to consider: • uniformity • aspect ratio • orthogonality • skewness
These mesh metrics will affect the accuracy, robustness and efficiency of the solution method; of course, whether a mesh is good or bad depends on the numerical discretisation.
8
November 28, 1996 12:21 Annual Reviews ROACHE AR23-05
Annu. Rev. Fluid. Mech. 1997. 29:123–60Copyright c� 1997 by Annual Reviews Inc. All rights reserved
QUANTIFICATION OF UNCERTAINTYIN COMPUTATIONAL FLUIDDYNAMICSP. J. RoacheEcodynamics Research Associates, Inc., P.O. Box 9229, Albuquerque,New Mexico 87119
KEY WORDS: numerical uncertainty, verification, validation, error estimation, computationalfluid dynamics
ABSTRACTThis review covers Verification, Validation, Confirmation and related subjects forcomputational fluid dynamics (CFD), including error taxonomies, error estima-tion and banding, convergence rates, surrogate estimators, nonlinear dynamics,and error estimation for grid adaptation vs Quantification of Uncertainty.
IntroductionThe focus of this review is the quantification of uncertainty, the estimationor banding of the numerical error of a final calculation in computational fluiddynamics (CFD) and related fields in computational physics, mathematics, andengineering. By final calculation I mean one considered to be used as is. Themotivation for this calculation is different than that for an error estimate used forthe process of solution-adaptive grid generation. Although the present methodsmay be applicable to grid adaptation, and some of the methods described hereinweremotivated by that problem, the grid adaptation problemhas vastly different(though usually unacknowledged) requirements.The key word is quantification of uncertainty, as opposed to vague and all
too common qualitative assessments. Quantification of uncertainty may alsoinvolve more than just obtaining a good error estimate; in fact, the more conser-vative procedure based on the grid-convergence index (described below) reportsan error band equal to three times an error estimate. Furthermore, I consider
1230066-4189/97/0115-0123$08.00
Ann
u. R
ev. F
luid
Mec
h. 1
997.
29:1
23-1
60. D
ownl
oade
d fr
om w
ww
.ann
ualre
view
s.org
by U
nive
rsity
of L
imer
ick
(UL)
on
05/1
7/13
. For
per
sona
l use
onl
y.
November 28, 1996 12:21 Annual Reviews ROACHE AR23-05
Annu. Rev. Fluid. Mech. 1997. 29:123–60Copyright c� 1997 by Annual Reviews Inc. All rights reserved
QUANTIFICATION OF UNCERTAINTYIN COMPUTATIONAL FLUIDDYNAMICSP. J. RoacheEcodynamics Research Associates, Inc., P.O. Box 9229, Albuquerque,New Mexico 87119
KEY WORDS: numerical uncertainty, verification, validation, error estimation, computationalfluid dynamics
ABSTRACTThis review covers Verification, Validation, Confirmation and related subjects forcomputational fluid dynamics (CFD), including error taxonomies, error estima-tion and banding, convergence rates, surrogate estimators, nonlinear dynamics,and error estimation for grid adaptation vs Quantification of Uncertainty.
IntroductionThe focus of this review is the quantification of uncertainty, the estimationor banding of the numerical error of a final calculation in computational fluiddynamics (CFD) and related fields in computational physics, mathematics, andengineering. By final calculation I mean one considered to be used as is. Themotivation for this calculation is different than that for an error estimate used forthe process of solution-adaptive grid generation. Although the present methodsmay be applicable to grid adaptation, and some of the methods described hereinweremotivated by that problem, the grid adaptation problemhas vastly different(though usually unacknowledged) requirements.The key word is quantification of uncertainty, as opposed to vague and all
too common qualitative assessments. Quantification of uncertainty may alsoinvolve more than just obtaining a good error estimate; in fact, the more conser-vative procedure based on the grid-convergence index (described below) reportsan error band equal to three times an error estimate. Furthermore, I consider
1230066-4189/97/0115-0123$08.00
Ann
u. R
ev. F
luid
Mec
h. 1
997.
29:1
23-1
60. D
ownl
oade
d fr
om w
ww
.ann
ualre
view
s.org
by U
nive
rsity
of L
imer
ick
(UL)
on
05/1
7/13
. For
per
sona
l use
onl
y.
9
Important mesh metrics for OpenFOAM
Aspect ratio is the ratio of the length to the width of a cell; we would like to keep it close to 1.0
Skewness is when the line connecting two adjacent cell-centres does not pass through the face-centre
Non-orthogonality is when the line connecting two adjacent cell-centres is not aligned with the face normal
10
The OpenFOAM mesh format
In general, a mesh consists of: • List of points. Point index is determined from its position in the list • List of faces. A face is an ordered list of points (defines face normal) • List of cells OR owner-neighbour addressing (defines left and right cell for
each face, saving some storage and mesh analysis time) • List of boundary patches, grouping external faces
The OpenFOAM mesh is stored in the constant/polyMesh sub-directory of a case; this polyMesh directory contains files that provide all the information above in order to define the mesh.
Let’s have a brief look at each file that comprise the mesh in OpenFOAM…
11
cavity !"" 0 # $"" … !"" constant # !"" … # $"" polyMesh # !"" points # !"" faces # !"" owner # !"" neighbour # $"" boundary $"" system $"" …
Have a look yourself in the cavity case (remember that you don’t type the “$>” symbol):
$> cd $FOAM_RUN$> cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity .$> cd cavity$> blockMesh$> gedit constant/polyMesh/points$> gedit constant/polyMesh/faces$> gedit constant/polyMesh/owner$> gedit constant/polyMesh/neighbour$> gedit constant/polyMesh/boundary
The OpenFOAM mesh format
12
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.; for example: … (0.0005 -0.001355 0) (0.001 -0.001355 0) (0.0015 -0.001355 0)…
faces - a list of faces, each face being a list of indices to vertices in the points list, where again, the first entry in the list represents face 0, etc.; for example: … 4(103 709 710 104) 4(4 105 711 610) 4(104 710 711 105)…
The OpenFOAM mesh format
13
owner - an internal mesh face straddles two cells; one of these cells is designated the owner of the face and the other is the neighbour. This owner file gives the cell index of the owner cell for each face in the mesh (internal and boundary faces): … 6 7 7…
neighbour - This neighbour file gives the cell index of the neighbour cell for each face in the mesh (only internal faces as boundary faces are only connected to one cell): … 104 7 115…
The OpenFOAM mesh format
14
boundary - a list of so-called patches, where patches are distinct regions of the mesh boundary, so that distinct boundary conditions can be applied to separate regions of the boundary. Each boundary patch definition comprises: a type, the number of faces on the patch, and the index of the first face on the patch (startFace); for example:
…movingWall { type patch; nFaces 20; startFace 760; }…
More details on the OpenFOAM mesh format can be found at: http://cfd.direct/openfoam/user-guide/mesh-description/
The OpenFOAM mesh format
Mesh Generation, Conversion & Manipulation
in OpenFOAM
$> ls $FOAM_UTILITIES/mesh/generation$> ls $FOAM_UTILITIES/mesh/conversion$> ls $FOAM_UTILITIES/mesh/manipulation
16
Similar to other software (e.g. Abaqus, ANSYS, …), there are a number of methods available to create a mesh in OpenFOAM; they can be broadly categorised as:
•generation: creating a mesh using one of the native OpenFOAM meshing utilities e.g. blockMesh, snappyHexMesh, cfMesh, foamyHexMesh, extrudeMesh, etc. A full list of the mesh generation utilities can be found at: $> ls $FOAM_UTILITIES/mesh/generation
•conversion: creating the mesh using third-party software, such as ANSYS, PointWise, ICEM, Gambit, and then using the in-built OpenFOAM mesh conversion utilities to convert it to the OpenFOAM format e.g. fluentMeshToFoam, gmshToFoam, startToFoam, etc. A full list of the mesh conversion utilities can be found at: $> ls $FOAM_UTILITIES/mesh/conversion
Mesh generation, conversion & manipulation
17
•manipulation: Once you have a mesh in OpenFOAM, either generated directly or converted, there are a number of OpenFOAM mesh manipulation utilities for checking and modifying the mesh, if necessary, such as checkMesh, rotateMesh, transformPoints, tetDecomposition, etc. A full list of the mesh manipulation utilities can be found at: $> ls $FOAM_UTILITIES/mesh/manipulation
Mesh generation, conversion & manipulation
How to use the OpenFOAM blockMesh utility
19
One of the most simple yet powerful ways to generate a mesh in OpenFOAM is using the blockMesh utility:
• a simple mesh generator using a multi-block/block-skeleton approach • allows multiple blocks and curved edges • configured by a blockMeshDict file in the system directory of the case • produces a 3-D structured hexahedral mesh; Note: OpenFOAM always uses 3-D
meshes, where 1-D and 2-D are handles using special empty boundary conditions.
There are lots of examples of blockMeshDict files in the tutorials i.e. in the directory $FOAM_TUTORIALS.
Let’s learn about the blockMeshDict file…
The OpenFOAM blockMesh utility
20
block 0
block 3
block 9 block 10
block 1 block 2
block 8
block 11
block 4
block 7
block 5
block 6
One possible multi-block skeleton to create a block-structured mesh of the flow over a cylinder case using the blockMesh utility.
https://www.msi.umn.edu/~chenxy/images/cldrmsh.gif
21
The blockMeshDict file is a text file which tells the blockMesh utility how to generate the mesh. The blockMeshDict is structured as follows:
• a list of vertices is specified • a list of blocks are specified in terms of the vertices: the number of cells and
grading/biasing in each direction of the block are prescribed • Optional: curved edges of the blocks are defined • Boundary patches are defined in terms of faces of the blocks
Let’s look at the blockMeshDict file in the cavity tutorial case, located at cavity/system/blockMeshDict.
Further details on the blockMesh utility can be found at: http://cfd.direct/openfoam/user-guide/blockmesh/#x25-1820005.3.2
The OpenFOAM blockMesh utility
22
Have a look yourself in the cavity case: $> cd $FOAM_RUN$> cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavity .$> cd cavity
Once the blockMeshDict file is setup, then we just type the blockMesh command, the blockMesh utility then reads the blockMeshDict and generates the mesh: $> blockMesh
We can use the gedit text editor to examine the blockMeshDict file: $> gedit system/blockMeshDict
The OpenFOAM blockMesh utility
23
Block structure in the cavity case: there is just one block.
24
convertToMeters 0.1;
vertices( (0 0 0) (1 0 0) (1 1 0) (0 1 0) (0 0 0.1) (1 0 0.1) (1 1 0.1) (0 1 0.1));
All vertex coordinates will be scaled by this factor when creating the mesh e.g. if we defined the geometry in mm, we would set this factor as 0.001.
This is the list of all vertices that will define the corners of the blocks
In this case, we can see that there are 8 points, so there will be only one block (defined later).
Note: all points defined here do not have to be used in blocks, and points can be repeated; if a vertex is not used in a block then it will not affect the mesh in any way.
Note: in C++, a list starts from 0, not 1.
vertex 0vertex 1vertex 2vertex 3vertex 4vertex 5vertex 6vertex 7
blockMeshDict: vertex definition
25
blocks( hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1));
Note: in this case, there is only one block in the mesh, but we can have more.
After the hex keyword, the bracketed 8 numbers represent the vertices of the block; in this case, the block is constructed from the 0th to the 7th vertex (based on the vertices list previously defined).
The order of the these points is critical: • the first 4 vertices describe one plane • the second 4 vertices describe the opposite plane • the resulting (x1, x2, x3) local coordinate must be righted handed: when looking down the Ox3
axis - with O nearest - an arc from the Ox1 axis to the Ox2 axis is in a clockwise direction.
vertex list
plane 1 plane 2
blockMeshDict: block definition
26
blocks( hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1)); vertex list
plane 1 plane 2
The following order would also be correct: (5 4 7 6 1 0 3 2)
However, an incorrect (left-handed block) ordering would be: (1 0 3 2 5 4 7 6)
blockMeshDict: block definition
27
blocks( hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1)); vertex list
plane 1 plane 2
The block local coordinate system is defined by the order in which the vertices are presented in the block definition: • the axis origin is the first entry in the block definition,
vertex 0 in our example; • the x1 direction is described by moving from vertex 0
to vertex 1; • the x2 direction is described by moving from vertex 1
to vertex 2; • vertices 0, 1, 2, 3 define the plane x3 = 0; • vertex 4 is found by moving from vertex 0 in the x3
direction; • vertices 5, 6 and 7 are similarly found by moving in
the x3 direction from vertices 1, 2 and 3 respectively.
blockMeshDict: block definition
28
blocks( hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1));
The second entry specifies the number of cells in x1, x2, and x3 local directions for the block.
In this case, there are 20 cells in the local x1 direction, 20 cells in the local x2 direction and 1 cell in the local x3 direction.
Note: for 1-D or 2-D models in OpenFOAM, we specify one cell in the “empty” (out of plane) direction.
number of cells in each local block direction
blockMeshDict: block definition
29
blocks( hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1));
The third entry gives the cell expansion ratios for each direction in the block: this allows mesh grading/biasing. The ratio is that of the width of the end cell along one edge of a block to the width of the start cell along that edge.
More details can be found in the OpenFOAM User Guide, in particular simpleGrading, edgeGrading and multi-grading.
cell expansion ratios
blockMeshDict: block definition
30
edges();
By default, each edge joining 2 vertices is assumed to be straight; however, any edge may be specified to be curved by entries in a list named edges. The list is optional. There are also other options, such as spline: see the User Guide.
For example, we could change the bottom boundary to be curved using the following definition:
edges( arc 0 1 (0.5 0.1 0) arc 4 5 (0.5 0.1 0.1));
In the cavity case, there are no curved edges
The edge connecting vertices 0 and 1 must go through the point (0.5 0.1 0)
The edge connecting vertices 4 and 5 must go through the point (0.5 0.1 0.1)
blockMeshDict: curved edges
31
The final section of the blockMeshDict consists of the definition of the boundary patches; the boundary is separated into patches/regions, where we will subsequently be able to apply distinct boundary conditions.
boundary( movingWall { type wall; faces
( (3 7 6 2) ); }
start of the boundary definition
boundary patch name; use any name that is convenient
see next slide
Each block face is defined by a list of 4 vertex numbers. The order in which the vertices are given must be such that, looking from inside the block and starting with any vertex, the face must be traversed in a clockwise direction to define the other vertices.
blockMeshDict: boundary
32
• patch: generic type containing no geometric or topological information about the mesh, e.g. used for an inlet or an outlet.
• wall: for patch that coincides with a solid wall, required for some physical modelling, e.g. wall functions in turbulence modelling.
• symmetryPlane: for a planar patch which is a symmetry plane. • symmetry: for any (non-planar) patch which uses the symmetry plane (slip) condition. • empty: for solutions in in 2 (or 1) dimensions (2D/1D), the type used on each patch whose plane is
normal to the 3rd (and 2nd) dimension for which no solution is required. • wedge: for 2 dimensional axi-symmetric cases, e.g. a cylinder, the geometry is specified as a wedge
of small angle and 1 cell thick, running along the centre line, straddling one of the coordinate planes.
• cyclic: enables two patches to be treated as if they are physically connected; used for repeated geometries; one cyclic patch is linked to another through a neighbourPatch keyword in the boundary file; each pair of connecting faces must have similar area to within a tolerance given by the matchTolerance keyword in the boundary file.
• cyclicAMI: like cyclic, but for 2 patches whose faces are non matching; used for sliding interface in rotating geometry cases.
• processor: the type that describes inter-processor boundaries for meshes decomposed for parallel running.
blockMeshDict: boundary types
33
fixedWalls { type wall; faces ( (0 4 7 3) (2 6 5 1) (1 5 4 0) ); }
blockMeshDict: boundary
As we can see, boundary patches can be constructed from multiple block faces.
34
frontAndBack { type empty; faces ( (0 3 2 1) (4 5 6 7) ); });
mergePatchPairs();
end of the boundary definition
See the User Guide for details on the mergePatchPairs option
This patch indicates that the equations will not be solved in this direction i.e. the case will be 2-D
blockMeshDict: boundary
How to modify and create a blockMeshDict
36
Let’s try modifying the blockMeshDict in the cavity case to get a hands-on understanding of the effect of changing the settings; we will take the following steps:
• make a copy of the cavity case • change settings in the blockMeshDict • re-generate the mesh by running the blockMesh utility • examine the effect in ParaView
Video tutorial: see the tutorial videos on the User Meeting website called “blockMesh 2” and “blockMesh 1”, which go through the modification of the blockMeshDict for the cavity and T-Junction cases.
blockMeshDict: try modifying it for yourself…
37
We have now seen how to interpret and edit a blockMeshDict file; next we will learn how to create a blockMeshDict file; we’ll create a T-Junction geometry:
Creating a blockMeshDict for new geometry…
outle
t
3122
2 Dimensions in mm
inletin
let
38
blockMeshDict: T-Junction Pipe
The first step when creating a blockMeshDict is to sketch the block skeleton/arrangement for your geometry; in this case the best block structure is clear; however, the optimal (or any) arrangement is often not trivial.
We can represent this geometry by 4 blocks and 20 block vertices.
Next we will label the vertices and blocks …
(0 0 0)(2 0 0)
(3 0 0)(6 0 0)
(6 2 0)(3 2 0)
(3 4 0)(2 4 0)
(2 2 0)(0 2 0)
(0 0 1)(2 0 1) (3 0 1)
(6 0 1)
(6 2 1)
(3 2 1)
(3 4 1)(2 4 1)
(2 2 1)(0 2 1)
39
We will now define the vertices in the blockMeshDict, where we will specify the coordinates in mm and use the convertToMeters scale factor to convert to m: convertToMeters 0.001;
vertices( (0 0 0) // vertex 0 (2 0 0) // vertex 1 (3 0 0) // vertex 2
(6 0 0) // vertex 3 (6 2 0) // vertex 4 (3 2 0) // vertex 5 (3 4 0) // vertex 6 (2 4 0) // vertex 7
(2 2 0) // vertex 8 (0 2 0) // vertex 9 (0 0 1) // vertex 10 (2 0 1) // vertex 11 (3 0 1) // vertex 12
(6 0 1) // vertex 13 (6 2 1) // vertex 14 (3 2 1) // vertex 15 (3 4 1) // vertex 16 (2 4 1) // vertex 17
(2 2 1) // vertex 18 (0 2 1) // vertex 19);
Note: we will make a copy of the cavity case and change the blockMeshDict to the new T-Junction geometry.
Note 2: the order of vertices here does not make a difference; however, it does affect the subsequent blocks definition.
blockMeshDict: T-Junction Pipe
40
The vertices can be defined in any order; however, this will affect how the how blocks/edges/boundary are defined.
The order of the blocks does not make a difference.
We can see that one way to define the vertices of Block 0 is: (0 1 8 9 10 11 18 19)
What about the other blocks?0
12
3
4
5
67
89
1011 12
14
15
1617
1819
Block 0Block 2
Bloc
k 1
Bloc
k 3
13
blockMeshDict: T-Junction Pipe
41
We can now define the blocks:
blocks( hex (0 1 8 9 10 11 18 19) (20 20 1) simpleGrading (1 1 1) // block 0 hex (1 2 5 8 11 12 15 18) (10 20 1) simpleGrading (1 1 1) // block 1 hex (2 3 4 5 12 13 14 15) (30 20 1) simpleGrading (1 1 1) // block 2 hex (8 5 6 7 18 15 16 17) (10 20 1) simpleGrading (1 1 1) // block 3);
Also there are no curved edges:
edges();
Note: there is more than one way to correctly define each block; can you think of other valid vertex arrangements?
blockMeshDict: T-Junction Pipe
42
Finally we need to define the boundary patches; there will be 5 separate boundary patches:
• inlet1 (larger left inlet) • inlet2 (smaller top inlet) • outlet• walls• frontAndBack
Let’s look at the definition of inlet1; we can see that it is made up of 4 vertices: vertex 0, 9, 10 and 19; we can start at any of the 4 vertices and then move in a clockwise direction when looking from inside the block. 0
12
5
67
89
11 12
15
1617
18
10
19
blockMeshDict: T-Junction Pipe
43
Therefore we can define the inlet1 boundary patch as:
inlet1 { type patch; faces ( (0 10 19 9) ); }
Note: we could also define the faces as: (10 19 9 0) or (19 9 0 10) or (9 0 10 19)
01
2
5
67
89
11 12
15
1617
18
10
19
blockMeshDict: T-Junction Pipe
44
In a similar fashion we can define the inlet2 boundary patch as:
inlet2 { type patch; faces ( (17 16 6 7) ); }
Q: give another valid face definition for inlet2Q2: give an invalid face definition for inlet2
01
2
5
67
89
11 12
15
16
18
10
19
17
blockMeshDict: T-Junction Pipe
45
… and the outlet:
outlet { type patch; faces ( (3 4 14 13) ); }
Note: for inlets and outlets, the “type” is set to “patch”.
blockMeshDict: T-Junction Pipe
46
Unlike the previous patches, the walls boundary patch will have multiple block faces: walls { type wall; faces ( (0 1 11 10) (1 2 12 11) (2 3 13 12) (15 14 4 5) (16 15 5 6) (18 17 7 8) (19 18 8 9) ); }
01
23
4
5
67
89
1011 12
14
15
1617
1819
Notice that walls are set to “type wall;”
13
blockMeshDict: T-Junction Pipe
47
Finally we specify the frontAndBack boundary patch: frontAndBack { type empty; faces ( (10 11 18 19) (11 12 15 18) (12 13 14 15) (18 15 16 17) (9 8 1 0) (8 5 2 1) (5 4 3 2) (7 6 5 8) ); }
01
23
4
5
67
89
1011 12
13
14
15
1617
1819
Notice for 2-D the frontAndBack is set to “type empty;”
blockMeshDict: T-Junction Pipe
48
We have now finished the specification of the blockMeshDict for the T-Junction geometry and mesh; please try to create this mesh for yourself.
Once the blockMeshDict has been finished, then we can generate the mesh by running the blockMesh command in the case directory: $> blockMesh
The view the mesh in ParaView: $> paraFoam
A valid blockMeshDict for this geometry has been uploaded to the User Meeting website for reference if you have any problems.
blockMeshDict: T-Junction Pipe
49
blockMeshDict: tips for resolving errorsFor the inexperienced user, creating a new blockMeshDict can be a time-consuming and error-prone process, in particular the interpretation of the at-first somewhat esoteric error messages.
Over the next few slides, we will discuss useful tips for creating blockMeshDict files with minimal hassle …
50
Tip 1: run the checkMesh utility after creating the mesh After creating the mesh with blockMesh it is important to check the mesh for any errors by running the checkMesh command; blockMesh may not give errors if, for example, a block is incorrectly defined as left-handed; however, checkMesh will indicate that cells are inverted with negative volumes: Checking geometry... Overall domain bounding box (0 0 0) (0.1 0.1 0.01) Mesh has 2 geometric (non-empty/wedge) directions (1 1 0) Mesh has 2 solution (non-empty) directions (1 1 0) All edges aligned with or perpendicular to non-empty directions. Boundary openness (-8.47033e-18 8.47033e-18 5.84453e-17) OK. Max cell openness = 1.35525e-16 OK. Max aspect ratio = 1 OK. Minimum face area = 2.5e-05. Maximum face area = 5e-05. Face area magnitudes OK. ***Zero or negative cell volume detected. Minimum negative volume: -2.5e-07, Number of negative volume cells: 400 <<Writing 400 zero volume cells to set zeroVolumeCells Mesh non-orthogonality Max: 180 average: 180 ***Number of non-orthogonality errors: 760. <<Writing 760 non-orthogonal faces to set nonOrthoFaces ***Error in face pyramids: 2400 faces are incorrectly oriented. <<Writing 1640 faces with incorrect orientation to set wrongOrientedFaces Max skewness = 1.66533e-14 OK. Coupled point location match (average 0) OK.
Failed 3 mesh checks.
blockMeshDict: tips for resolving errors
51
Tip 2: if there are errors in the blocks, check each block one-by-one If after running checkMesh, you receive errors, such as inverted negative volume cells, then often the easiest method to diagnose the problem is to comment out all the blocks (and all boundary patches: see next slide) except one and then run blockMesh followed by checkMesh to see if that particular block is invalid; for example:
blocks( hex (0 1 8 9 10 11 18 19) (20 20 1) simpleGrading (1 1 1) // hex (1 2 5 8 11 12 15 18) (10 20 1) simpleGrading (1 1 1) // hex (2 3 4 5 12 13 14 15) (30 20 1) simpleGrading (1 1 1) // hex (8 5 6 7 18 15 16 17) (10 20 1) simpleGrading (1 1 1));
commented line i.e. blockMesh will ignore these lines
blockMeshDict: tips for resolving errors
52
… and also comment-out all boundary patches when you are checking each block one-by-one:
boundary( // inlet1 // { // type patch; // faces // ( // (0 10 19 9) // ); // }
// … and comment out all the other patches); // Do not comment out this line (end of the boundary section)
Note: the same method can be used for diagnosing problems with boundary patch definitions.
blockMeshDict: tips for resolving errors
53
Tip 3: interpreting blockMesh errors: blockMesh tells us exactly where to look If you receive errors when running blockMesh, the error message will typically explain the source of the problem; consider the following blockMesh error: Creating block mesh topology
--> FOAM FATAL ERROR: face 0 in patch 0 does not have neighbour cell face: 4(3 0 6 2)
From function Foam::labelList Foam::polyMesh::facePatchFaceCells(const faceList&, const labelListList&, const faceListList&, Foam::label) const in file meshes/polyMesh/polyMeshFromShapeMesh.C at line 118.
FOAM aborting
This error states that there is a problem with the 0th face of the 0th patch i.e. go to the first patch in the boundary list and the problem is with its first face.
blockMeshDict: tips for resolving errors
54
What next…?You should now know enough to be able to create a mesh of the geometry below, for the flow over a cylinder in a channel test case; details of the case can be found in: Ferziger and Peric (2000), Computational Method for Fluid Dynamics, Springer. An example of a good multi-block skeleton is shown by the orange dashed lines, though there are many other arrangements.
How to import a third-party software mesh into OpenFOAM
56
Converting third-party meshesIt is possible to create the mesh in software outside of OpenFOAM and then import it. The list of currently available mesh conversion utilities can be found in: $> ls $FOAM_UTILITIES/mesh/conversion
We will look at two cases: • flange - this laplacianFoam test case contains
a flange component mesh in the ANSYS format, which we can covert using the ansysToFoam utility.
• elbow - this icoFoam test case contains an elbow pipe mesh in the ANSYS Fluent format, which we can convert using the fluentMeshToFoam utility.
57
ansysToFoamThe ansysToFoam utility takes an ANSYS “*.ans” file and converts it into the OpenFOAM format (the polyMesh directory in the case constant directory). We can try it out in the laplacianFoam tutorial called flange:
Change directory into the user run directory: $> run
Copy the elbow tutorial case to the current directory: $> cp -r $FOAM_TUTORIALS/basic/laplacianFoam/flange .
Change directory into the flange case: $> cd flange
Convert the ANSYS mesh file (called flange.msh) to the OpenFOAM format:$> ansysToFoam flange.msh
Run the laplacianFoam solver: $> laplacianFoam
Note: the flange case also has an Allrun script
Note: laplacianFoam solves the transient Laplace equation i.e. the transient heat conduction equation
58
59
fluentMeshToFoamThe fluentMeshToFoam utility takes a fluent “*.msh” file and converts it into the OpenFOAM format (the polyMesh directory in the case constant directory). We can try it out in the icoFoam tutorial called elbow:
Change directory into the user run directory: $> run
Copy the elbow tutorial case to the current directory: $> cp -r $FOAM_TUTORIALS/incompressible/icoFoam/elbow .
Change directory into the elbow case: $> cd elbow
Convert the Fluent mesh file (called elbow.msh) to the OpenFOAM format:$> fluentMeshToFoam elbow.msh
Run the icoFoam solver: $> icoFoam
Note: the elbow case also has an Allrun script
60
How to create a Cartesian mesh using the OpenFOAM snappyHexMesh utility
62
Other meshing methods in OpenFOAMWe have seen how to use the blockMesh utility; however, for many cases, particularly complex geometry, it is not possible to create a blockMeshDict. In such cases, snappyHexMesh may be a better choice.
Let’s briefly look at the method used by snappyHexMesh and how to use it. Note: see also cfMesh (http://cfmesh.com) which uses a similar meshing approach.
source: http://www.rccm.co.jp/icem/pukiwiki/index.php?plugin=ref&page=SnappyHexMesh&src=snappying.png
63
snappyHexMeshThe snappyHexMesh utility uses the so-called Cartesian-based meshing approach; in the Cartesian grid method, the whole domain is divided by a hexahedral grid extending through solid walls within the computational domain. Cells inside the flow domain are kept, whereas cells outside the flow domain are discarded; cells that are intersected by the flow domain are then “snapped” to the flow domain boundary geometry.
Cartesian meshing methods are often advantageous over body-fitted methods as they can be fully automated.
Please see the following description of snappyHexMesh: http://cfd.direct/openfoam/user-guide/snappyhexmesh/ Let us now briefly look at the snappyHexMesh meshing process…
64
snappyHexMeshBefore this step, the CAD geometry (STL) must be created in, for example, a CAD programme like SolidWorks, Creo, etc.
65
snappyHexMesh
66
snappyHexMesh
67
snappyHexMesh
68
snappyHexMesh
69
snappyHexMeshWe can try out snappyHexMesh in the simpleFoam motorbike tutorial:
Change directory into the user run directory: $> run
Copy the motorbike tutorial case to the current directory:$> cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/motorBike .
Change directory into the motorbike case:$> cd motorbike
Execute the Allrun script in the motorbike case:$> ./Allrun (this may take a few minutes)
Then examine the case in ParaView.
70
Note on Allrun scriptsSome of the OpenFOAM tutorial cases will have an Allrun script with the commands necessary to run the case; they may also have an Allclean script to reset the case to its original settings; let’s look at the motorbike case Allrun script: #!/bin/sh cd ${0%/*} || exit 1 # Run from this directory
# Source tutorial run functions . $WM_PROJECT_DIR/bin/tools/RunFunctions
# copy motorbike surface from resources directory cp $FOAM_TUTORIALS/resources/geometry/motorBike.obj.gz constant/triSurface/runApplication surfaceFeatureExtract
runApplication blockMesh
runApplication decomposeParrunParallel snappyHexMesh -overwrite
#- For non-parallel running #cp -r 0.orig 0 > /dev/null 2>&1
#- For parallel running ls -d processor* | xargs -I {} rm -rf ./{}/0ls -d processor* | xargs -I {} cp -r 0.orig ./{}/0
runParallel patchSummaryrunParallel potentialFoamrunParallel $(getApplication)
runApplication reconstructParMesh -constantrunApplication reconstructPar -latestTime
71
Philip Cardiff
!
!
!
!
Assistant Professor Bekaert Lecturer in Materials Processing
School of Mechanical & Materials Engineering University College Dublin
16th - 17th January 2017
Introduction to Meshing in OpenFOAM
5th UK & Éire FOAM/OpenFOAM User Day University College Dublin
Dublin, Ireland