OpenFoam8 UserGuide
OpenFoam8 UserGuide
1 Introduction
2 Tutorials
2.1 Lid-driven cavity flow
2.1.1 Pre-processing
2.1.2 Viewing the mesh
2.1.3 Running an application
2.1.4 Post-processing
2.1.5 Increasing the mesh resolution
2.1.6 Introducing mesh grading
2.1.7 Increasing the Reynolds number
2.1.8 High Reynolds number flow
2.1.9 Changing the case geometry
2.1.10 Post-processing the modified geometry
2.2 Stress analysis of a plate with a hole
2.2.1 Mesh generation
2.2.2 Running the code
2.2.3 Post-processing
2.2.4 Exercises
2.3 Breaking of a dam
2.3.1 Mesh generation
2.3.2 Boundary conditions
2.3.3 Setting initial field
2.3.4 Fluid properties
2.3.5 Turbulence modelling
2.3.6 Time step control
2.3.7 Discretisation schemes
2.3.8 Linear-solver control
2.3.9 Running the code
2.3.10 Post-processing
2.3.11 Running in parallel
2.3.12 Post-processing a case run in parallel
3 Applications and libraries
3.1 The programming language of OpenFOAM
3.1.1 Language in general
3.1.2 Object-orientation and C++
3.1.3 Equation representation
3.1.4 Solver codes
3.2 Compiling applications and libraries
3.2.1 Header .H files
3.2.2 Compiling with wmake
3.2.3 Removing dependency lists: wclean
3.2.4 Compiling libraries
3.2.5 Compilation example: the pisoFoam application
3.2.6 Debug messaging and optimisation switches
3.2.7 Linking user-defined libraries to applications
3.3 Running applications
3.4 Running applications in parallel
3.4.1 Decomposition of mesh and initial field data
3.4.2 File input/output in parallel
3.4.3 Running a decomposed case
3.4.4 Distributing data across several disks
3.4.5 Post-processing parallel processed cases
3.5 Standard solvers
3.5.1 ‘Basic’ CFD codes
3.5.2 Incompressible flow
3.5.3 Compressible flow
3.5.4 Multiphase flow
3.5.5 Direct numerical simulation (DNS)
3.5.6 Combustion
3.5.7 Heat transfer and buoyancy-driven flows
3.5.8 Particle-tracking flows
3.5.9 Discrete methods
3.5.10 Electromagnetics
3.5.11 Stress analysis of solids
3.5.12 Finance
3.6 Standard utilities
3.6.1 Pre-processing
3.6.2 Mesh generation
3.6.3 Mesh conversion
3.6.4 Mesh manipulation
3.6.5 Other mesh tools
3.6.6 Post-processing
3.6.7 Post-processing data converters
3.6.8 Surface mesh (e.g. OBJ/STL) tools
3.6.9 Parallel processing
3.6.10 Thermophysical-related utilities
3.6.11 Miscellaneous utilities
4 OpenFOAM cases
4.1 File structure of OpenFOAM cases
4.2 Basic input/output file format
4.2.1 General syntax rules
4.2.2 Dictionaries
4.2.3 The data file header
4.2.4 Lists
4.2.5 Scalars, vectors and tensors
4.2.6 Dimensional units
4.2.7 Dimensioned types
4.2.8 Fields
4.2.9 Macro expansion
4.2.10 Including files
4.2.11 Environment variables
4.2.12 Regular expressions
4.2.13 Keyword ordering
4.2.14 Inline calculations and code
4.2.15 Conditionals
4.3 Global controls
4.3.1 Overriding global controls
4.4 Time and data input/output control
4.4.1 Time control
4.4.2 Data writing
4.4.3 Other settings
4.5 Numerical schemes
4.5.1 Time schemes
4.5.2 Gradient schemes
4.5.3 Divergence schemes
4.5.4 Surface normal gradient schemes
4.5.5 Laplacian schemes
4.5.6 Interpolation schemes
4.6 Solution and algorithm control
4.6.1 Linear solver control
4.6.2 Solution under-relaxation
4.6.3 PISO, SIMPLE and PIMPLE algorithms
4.6.4 Pressure referencing
4.6.5 Other parameters
4.7 Case management tools
4.7.1 File management scripts
4.7.2 foamDictionary and foamSearch
4.7.3 The foamGet script
4.7.4 The foamInfo script
5 Mesh generation and conversion
5.1 Mesh description
5.1.1 Mesh specification and validity constraints
5.1.2 The polyMesh description
5.1.3 Cell shapes
5.1.4 1- and 2-dimensional and axi-symmetric problems
5.2 Boundaries
5.2.1 Geometric (constraint) patch types
5.2.2 Basic boundary conditions
5.2.3 Derived types
5.3 Mesh generation with the blockMesh utility
5.3.1 Writing a blockMeshDict file
5.3.2 Multiple blocks
5.3.3 Projection of vertices, edges and faces
5.3.4 Naming vertices, edges, faces and blocks
5.3.5 Creating blocks with fewer than 8 vertices
5.3.6 Running blockMesh
5.4 Mesh generation with the snappyHexMesh utility
5.4.1 The mesh generation process of snappyHexMesh
5.4.2 Creating the background hex mesh
5.4.3 Cell splitting at feature edges and surfaces
5.4.4 Cell removal
5.4.5 Cell splitting in specified regions
5.4.6 Cell splitting based on local span
5.4.7 Snapping to surfaces
5.4.8 Mesh layers
5.4.9 Mesh quality controls
5.5 Mesh conversion
5.5.1 fluentMeshToFoam
5.5.2 starToFoam
5.5.3 gambitToFoam
5.5.4 ideasToFoam
5.5.5 cfx4ToFoam
5.6 Mapping fields between different geometries
5.6.1 Mapping consistent fields
5.6.2 Mapping inconsistent fields
5.6.3 Mapping parallel cases
6 Post-processing
6.1 ParaView/paraFoam graphical user interface (GUI)
6.1.1 Overview of ParaView/paraFoam
6.1.2 The Parameters panel
6.1.3 The Display panel
6.1.4 The button toolbars
6.1.5 Manipulating the view
6.1.6 Contour plots
6.1.7 Vector plots
6.1.8 Streamlines
6.1.9 Image output
6.1.10 Animation output
6.2 Post-processing command line interface (CLI)
6.2.1 Post-processing functionality
6.2.2 Run-time data processing
6.2.3 The postProcess utility
6.2.4 Solver post-processing
6.3 Sampling and monitoring data
6.3.1 Probing data
6.3.2 Sampling for graphs
6.3.3 Sampling for visualisation
6.3.4 Live monitoring of data
6.4 Third-Party post-processing
6.4.1 Post-processing with Ensight
7 Models and physical properties
7.1 Thermophysical models
7.1.1 Thermophysical and mixture models
7.1.2 Transport model
7.1.3 Thermodynamic models
7.1.4 Composition of each constituent
7.1.5 Equation of state
7.1.6 Selection of energy variable
7.1.7 Thermophysical property data
7.2 Turbulence models
7.2.1 Reynolds-averaged simulation (RAS) modelling
7.2.2 Large eddy simulation (LES) modelling
7.2.3 Model coefficients
7.2.4 Wall functions
7.3 Transport/rheology models
7.3.1 Newtonian model
7.3.2 Bird-Carreau model
7.3.3 Cross Power Law model
7.3.4 Power Law model
7.3.5 Herschel-Bulkley model
7.3.6 Casson model
7.3.7 General strain-rate function
Chapter 1 Introduction
This guide accompanies the release of version 6 of the Open Source Field Operation and
Manipulation (OpenFOAM) C++ libraries. It provides a description of the basic operation of
OpenFOAM, first through a set of tutorial exercises in chapter 2 and later by a more detailed
description of the individual components that make up OpenFOAM.
OpenFOAM is a framework for developing application executables that use packaged
functionality contained within a collection of approximately 100 C++ libraries. OpenFOAM is
shipped with approximately 250 pre-built applications that fall into two categories: solvers, that
are each designed to solve a specific problem in fluid (or continuum) mechanics; and utilities, that
are designed to perform tasks that involve data manipulation. The solvers in OpenFOAM cover
a wide range of problems in fluid dynamics, as described in chapter 3.
Users can extend the collection of solvers, utilities and libraries in OpenFOAM, using some pre-
requisite knowledge of the underlying method, physics and programming techniques involved.
OpenFOAM is supplied with pre- and post-processing environments. The interface to the pre-
and post-processing are themselves OpenFOAM utilities, thereby ensuring consistent data
handling across all environments. The overall structure of OpenFOAM is shown in Figure 1.1.
ls $FOAM_RUN
If a message is returned saying no such directory exists, the user should create the directory by
typing
mkdir -p $FOAM_RUN
The tutorial cases describe the use of the meshing and pre-processing utilities, case setup and
running OpenFOAM solvers and post-processing using ParaView.
Copies of all tutorials are available from the tutorials directory of the OpenFOAM installation. The
tutorials are organised into a set of directories according to the type of flow and then
subdirectories according to solver. For example, all the simpleFoam cases are stored within a
subdirectory incompressible/simpleFoam, where incompressible indicates the type of flow. The user
can copy cases from the tutorials directory into their local run directory as needed. For example
to run the pitzDaily tutorial case for the simpleFoam solver, the user can copy it to the run directory
by typing:
cd $FOAM_RUN
cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily .
2.1.1 Pre-processing
Cases are setup in OpenFOAM by editing case files. Users should select an editor of choice
with which to do this, such as emacs, vi, gedit, nedit, etc. Editing files is possible in OpenFOAM
because the I/O uses a dictionary format with keywords that convey sufficient meaning to be
understood by the users.
A case being simulated involves data for mesh, fields, properties, control parameters, etc. As
described in section 4.1, in OpenFOAM this data is stored in a set of files within a case directory
rather than in a single case file, as in many other CFD packages. The case directory is given a
suitably descriptive name. This tutorial consists of a set of cases located
in $FOAM_TUTORIALS/incompressible/icoFoam/cavity, the first of which is simply named cavity. As a
first step, the user should copy the cavity case directory to their run directory.
cd $FOAM_RUN
cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavity .
cd cavity
The mesh generator supplied with OpenFOAM, blockMesh, generates meshes from a description
specified in an input dictionary, blockMeshDict located in the system (or constant/polyMesh) directory
for a given case. The blockMeshDict entries for this case are as follows:
1/*––––––––––––––––––––––––––––––--*- C++ -*–––––––––––––––––––––––––––––––––-*\\
2 ========= |
3 \\\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\\\ / O peration | Website: https://openfoam.org
5 \\\\ / A nd | Version: 8
6 \\\\/ M anipulation |
7\\*–––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––*/
8FoamFile
9{
10 version 2.0;
11 format ascii;
12 class dictionary;
13 object blockMeshDict;
14}
15// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
16
17convertToMeters 0.1;
18
19vertices
20(
21 (0 0 0)
22 (1 0 0)
23 (1 1 0)
24 (0 1 0)
25 (0 0 0.1)
26 (1 0 0.1)
27 (1 1 0.1)
28 (0 1 0.1)
29);
30
31blocks
32(
33 hex (0 1 2 3 4 5 6 7) (20 20 1) simpleGrading (1 1 1)
34);
35
36edges
37(
38);
39
40boundary
41(
42 movingWall
43 {
44 type wall;
45 faces
46 (
47 (3 7 6 2)
48 );
49 }
50 fixedWalls
51 {
52 type wall;
53 faces
54 (
55 (0 4 7 3)
56 (2 6 5 1)
57 (1 5 4 0)
58 );
59 }
60 frontAndBack
61 {
62 type empty;
63 faces
64 (
65 (0 3 2 1)
66 (4 5 6 7)
67 );
68 }
69);
70
71mergePatchPairs
72(
73);
74
75// ************************************************************************* //
The file first contains header information in the form of a banner (lines 1-7), then file information
contained in a FoamFile sub-dictionary, delimited by curly braces ({…}).For the remainder of the
manual:
For the sake of clarity and to save space, file headers, including the banner and FoamFile sub-
dictionary, will be removed from verbatim quoting of case files
The file first specifies coordinates of the block vertices; it then defines the blocks (here, only 1)
from the vertex labels and the number of cells within it; and finally, it defines the boundary
patches. The user is encouraged to consult section 5.3 to understand the meaning of the entries
in the blockMeshDict file.
The mesh is generated by running blockMesh on this blockMeshDict file. From within the case
directory, this is done, simply by typing in the terminal:
blockMesh
The running status of blockMesh is reported in the terminal window. Any mistakes in the blockMeshDict
file are picked up by blockMesh and the resulting error message directs the user to the line in the file
where the problem occurred. There should be no error messages at this stage.
specifies the dimensions of the field, here kinematic pressure, i.e. (see section 4.2.6 for
more information);
internalField
the internal field data which can be uniform, described by a single value; or nonuniform, where all
the values of the field must be specified (see section 4.2.8 for more information);
boundaryField
the boundary field data that includes boundary conditions and data for all the boundary patches
(see section 4.2.8 for more information).
For this case cavity, the boundary consists of walls only, split into 2 patches named: (1) fixedWalls
for the fixed sides and base of the cavity; (2) movingWall for the moving top of the cavity. As walls,
both are given a zeroGradient boundary condition for p, meaning “the normal gradient of pressure
is zero”. The frontAndBack patch represents the front and back planes of the 2D case and
therefore must be set as empty.
In this case, as in most we encounter, the initial fields are set to be uniform. Here the pressure
is kinematic, and as an incompressible case, its absolute value is not relevant, so is set to uniform
0 for convenience.
The user can similarly examine the velocity field in the 0/U file. The dimensions are those expected
for velocity, the internal field is initialised as uniform zero, which in the case of velocity must be
expressed by 3 vector components, i.e. uniform (0 0 0) (see section 4.2.5 for more information).
The boundary field for velocity requires the same boundary condition for the frontAndBack patch.
The other patches are walls: a no-slip condition is assumed on the fixedWalls, hence
a noSlip condition. The top surface moves at a speed of 1 m/s in the -direction so requires
a fixedValue condition with value of uniform (1 0 0).
where and are the characteristic length and velocity respectively and is the kinematic viscosity.
Here 0.1 m, 1 m/s, so that for 10, 0.01 . The correct file entry for
kinematic viscosity is thus specified below:
17
18nu [0 2 -1 0 0 0 0] 0.01;
19
20
21// ************************************************************************* //
2.1.1.4 Control
Input data relating to the control of time and reading and writing of the solution data are read in
from the controlDict dictionary. The user should view this file; as a case control file, it is located in
the system directory.
The start/stop times and the time step for the run must be set. OpenFOAM offers great flexibility
with time control which is described in full in section 4.4. In this tutorial we wish to start the run
at time which means that OpenFOAM needs to read field data from a directory named 0
— see section 4.1 for more information of the case file structure. Therefore we set
the startFrom keyword to startTime and then specify the startTime keyword to be 0.
For the end time, we wish to reach the steady state solution where the flow is circulating around
the cavity. As a general rule, the fluid should pass through the domain 10 times to reach steady
state in laminar flow. In this case the flow does not pass through this domain as there is no inlet
or outlet, so instead the end time can be set to the time taken for the lid to travel ten times across
the cavity, i.e. 1 s; in fact, with hindsight, we discover that 0.5 s is sufficient so we shall adopt
this value. To specify this end time, we must specify the stopAt keyword as endTime and then set
the endTime keyword to 0.5.
Now we need to set the time step, represented by the keyword deltaT. To achieve temporal
accuracy and numerical stability when running icoFoam, a Courant number of less than 1 is
required. The Courant number is defined for one cell as:
(2.2)
where is the time step, is the magnitude of the velocity through that cell and is the cell size in
the direction of the velocity. The flow velocity varies across the domain and we must
ensure everywhere. We therefore choose based on the worst case:
the maximum corresponding to the combined effect of a large flow velocity and small cell size. Here,
the cell size is fixed across the domain so the maximum will occur next to the lid where the velocity
approaches 1 . The cell size is:
(2.3)
Therefore to achieve a Courant number less than or equal to 1 throughout the domain the time step deltaT
must be set to less than or equal to:
(2.4)
As the simulation progresses we wish to write results at certain intervals of time that we can later view
with a post-processing package. The writeControl keyword presents several options for setting the time
at which the results are written; here we select the timeStep option which specifies that results are written
every th time step where the value is specified under the writeInterval keyword. Let us decide that we
wish to write our results at times 0.1, 0.2,…, 0.5 s. With a time step of 0.005 s, we therefore need to
output results at every 20th time time step and so we set writeInterval to 20.
OpenFOAM creates a new directory named after the current time, e.g. 0.1 s, on each occasion that
it writes a set of data, as discussed in full in section 4.1. In the icoFoam solver, it writes out the
results for each field, U and p, into the time directories. For this case, the entries in the controlDict
are shown below:
17
18application icoFoam;
19
20startFrom startTime;
21
22startTime 0;
23
24stopAt endTime;
25
26endTime 0.5;
27
28deltaT 0.005;
29
30writeControl timeStep;
31
32writeInterval 20;
33
34purgeWrite 0;
35
36writeFormat ascii;
37
38writePrecision 6;
39
40writeCompression off;
41
42timeFormat general;
43
44timePrecision 6;
45
46runTimeModifiable true;
47
48
49// ************************************************************************* //
paraFoam &
Alternatively, it can be launched from another directory location with an optional -case argument
giving the case directory, e.g.
This launches the ParaView window as shown in Figure 6.1. In the Pipeline Browser, the user can
see that ParaView has opened cavity.OpenFOAM, the module for the cavity case. Before clicking
the Apply button, the user needs to select some geometry from the Mesh Parts panel. Because
the case is small, it is easiest to select all the data by checking the box adjacent to the Mesh Parts
panel title, which automatically checks all individual components within the respective panel. The
user should then click the Apply button to load the geometry into ParaView.
The user should then scroll down to the Display panel that controls the visual representation of
the selected module. Within the Display panel the user should do the following as shown in
Figure 2.3:
1. in the Coloring section, select Solid Color;
2. click Edit (in Coloring) and select an appropriate colour e.g. black (for a white background);
3. select Wireframe from the Representation menu. The background colour can be set in
the View Render panel below the Display panel in the Properties window.
Figure 2.3: Viewing the mesh in paraFoam.
Especially the first time the user starts ParaView, it is recommended that they manipulate the
view as described in section 6.1.5. In particular, since this is a 2D case, it is recommended
that Use Parallel Projection is selected near the bottom of the View Render panel, available only with
the Advanced Properties gearwheel button pressed at the top of the Properties window, next to the
search box. View Settings window selected from the Edit menu. The Orientation Axes can be
toggled on and off in the Annotation window or moved by drag and drop with the mouse.
icoFoam
at the command prompt, or with the optional -case argument giving the case directory, e.g.
icoFoam -case $FOAM_RUN/cavity
The progress of the job is written to the terminal window. It tells the user the current time,
maximum Courant number, initial and final residuals for all fields.
2.1.4 Post-processing
As soon as results are written to time directories, they can be viewed using paraFoam. Return to
the paraFoam window and select the Properties panel for the cavity.OpenFOAM case module. If the
correct window panels for the case module do not seem to be present at any time, please ensure
that: cavity.OpenFOAM is highlighted in blue; eye button alongside it is switched on to show the
graphics are enabled;
To prepare paraFoam to display the data of interest, we must first load the data at the required
run time of 0.5 s. If the case was run while ParaView was open, the output data in time directories
will not be automatically loaded within ParaView. To load the data the user should click Refresh
Times at the top Properties window (scroll up the panel if necessary). The time data will be loaded
into ParaView.
In order to view the solution at s, the user can use the VCR Controls or Current Time
Controls to change the current time to 0.5. These are located in the toolbars at the top of
the ParaView window, as shown in Figure 6.4.
In particular, ParaView defaults to using a colour scale of blue to white to red rather than the more
common blue to green to red (rainbow). Therefore the first time that the user executes ParaView,
they may wish to change the colour scale. This can be done by selecting the Choose Preset button
(with the heart icon) in the Color Scale Editor and selecting Blue to Red Rainbow. After clicking
the OK confirmation button, the user can click the Save as Default button at the bottom of the panel
(disk drive symbol) so that ParaView will always adopt this type of colour bar.
The user can also edit the color legend properties, such as text size, font selection and
numbering format for the scale, by clicking the Edit Color Legend Properties to the far right of the
search bar, as shown in Figure 2.6.
2.1.4.3 Contours
Having generated the cutting plane, contours can be created using by applying the Contour filter.
With the Slice module highlighted in the Pipeline Browser, the user should select the Contour filter.
In the Properties panel, the user should select pressure from the Contour By menu.
Under Isosurfaces, the user could delete the default value with the minus button, then add a range
of 10 values. The contours can be displayed with a Wireframe representation if the Coloring is solid
or by a field, e.g. pressure.
Figure 2.7: Properties panel for the Glyph filter.
cd $FOAM_RUN
Note that there is also a convenient alias, named run, that reproduces the command above to change
directory to $FOAM_RUN, simply by typing run.
The cavityFine case can be created by making a new case directory and copying the relevant
directories from the cavity case.
mkdir cavityFine
cp -r cavity/constant cavityFine
cp -r cavity/system cavityFine
The user can then prepare to run the new case by changing into the case directory.
cd cavityFine
Create meshes
interpolating p
interpolating U
End
paraFoam -touch
Now the cavityFine case can be loaded into ParaView by selecting Open from the File menu, and
having navigated to the cavityFine directory, opening cavityFine.OpenFOAM. The user can now
make a vector plot of the results from the refined mesh in ParaView. The plot can be compared
with the cavity case by enabling glyph images for both case simultaneously.
Figure 2.11: Selecting fields for graph plotting.
postProcess -list
The components and mag functions provide useful scalar measures of velocity. When the components
function is executed on a case, e.g. cavity, it reads in the velocity vector field from each time directory
and, in the corresponding time directories, writes scalar fields Ux, Uy and Uz representing the
, and components of velocity.
The user can run postProcess with the components function on both cavity and cavityFine cases. For
example, for the cavity case the user should go into the cavity directory and execute postProcess
as follows:
cd $FOAM_RUN/cavity
postProcess -func "components(U)"
The individual components can be plotted as a graph in ParaView. It is quick, convenient and has
reasonably good control over labelling and formatting, so the printed output is a fairly good
standard. However, to produce graphs for publication, users may prefer to write raw data and
plot it with a dedicated graphing tool, such as gnuplot or Grace/xmgr. To do this, we recommend
using the sampling tools, described in section 6.3.2 and section 2.2.3. Before commencing plotting,
the user needs to load the newly generated Ux, Uy and Uz fields into ParaView. To do this, the
user should click the Refresh Times at the top of the Properties panel for the cavity.OpenFOAM
module which will cause the new fields to be loaded into ParaView and appear in the Volume Fields
window. Ensure the new fields are selected and the changes are applied, i.e. click Apply again if
necessary. Also, data is interpolated incorrectly at boundaries if the boundary regions are
selected in the Mesh Parts panel. Therefore the user should deselect the patches in the Mesh
Parts panel, i.e. movingWall, fixedWall and frontAndBack, and apply the changes.
Now, in order to display a graph in ParaView the user should select the module of
interest, e.g. cavity.OpenFOAM and apply the Plot Over Line filter from the Filter->Data Analysis menu.
This opens up a new XY Plot window below or beside the existing 3D View window.
A PlotOverLine module is created in which the user can specify the end points of the line in
the Properties panel. In this example, the user should position the line vertically up the centre of
the domain, i.e. from to , in the Point1 and Point2 text boxes.
The Resolution can be set to 100.
On clicking Apply, a graph is generated in the XY Plot window. In the Display panel, the user should
set Attribute Mode to Point Data. The Use Data Array option can be selected for the X Axis Data, taking
the arc_length option so that the x-axis of the graph represents distance from the base of the
cavity.
The user can choose the fields to be displayed in the Line Series panel of the Display window.
From the list of scalar fields to be displayed, it can be seen that the magnitude and components
of vector fields are available by default, e.g. displayed as U_X, so that it was not necessary to
create Ux using the components function. Nevertheless, the user should deselect all series
except Ux (or U_x). A square colour box in the adjacent column to the selected series indicates
the line colour. The user can edit this most easily by a double click of the mouse over that
selection.
In order to format the graph, the user should modify the settings below the Line Series panel,
namely Line Color, Line Thickness, Line Style, Marker Style and Chart Axes.
Also the user can click one of the buttons above the top left corner of the XY Plot. The third button,
for example, allows the user to control View Settings in which the user can set title and legend for
each axis, for example. Also, the user can set font, colour and alignment of the axes titles, and
has several options for axis range and labels in linear or logarithmic scales.
Figure 2.12 is a graph produced using ParaView. The user can produce a graph however he/she
wishes. For information, the graph in Figure 2.12 was produced with the options for axes
of: Standard type of Notation; Specify Axis Range selected; titles in Sans Serif 12 font. The graph is
displayed as a set of points rather than a line by activating the Enable Line Series button in
the Display window. Note: if this button appears to be inactive by being “greyed out”, it can be
made active by selecting and deselecting the sets of variables in the Line Series panel. Once
the Enable Line Series button is selected, the Line Style and Marker Style can be adjusted to the
user’s preference.
Figure 2.13: Block structure of the graded mesh for the cavity (block numbers encircled).
The user can view the blockMeshDict file in the system subdirectory of cavityGrade; for
completeness the key elements of the blockMeshDict file are also reproduced below. Each block
now has cells in the and directions and the ratio between largest and smallest cells is .
17convertToMeters 0.1;
18
19vertices
20(
21 (0 0 0)
22 (0.5 0 0)
23 (1 0 0)
24 (0 0.5 0)
25 (0.5 0.5 0)
26 (1 0.5 0)
27 (0 1 0)
28 (0.5 1 0)
29 (1 1 0)
30 (0 0 0.1)
31 (0.5 0 0.1)
32 (1 0 0.1)
33 (0 0.5 0.1)
34 (0.5 0.5 0.1)
35 (1 0.5 0.1)
36 (0 1 0.1)
37 (0.5 1 0.1)
38 (1 1 0.1)
39);
40
41blocks
42(
43 hex (0 1 4 3 9 10 13 12) (10 10 1) simpleGrading (2 2 1)
44 hex (1 2 5 4 10 11 14 13) (10 10 1) simpleGrading (0.5 2 1)
45 hex (3 4 7 6 12 13 16 15) (10 10 1) simpleGrading (2 0.5 1)
46 hex (4 5 8 7 13 14 17 16) (10 10 1) simpleGrading (0.5 0.5 1)
47);
48
49edges
50(
51);
52
53boundary
54(
55 movingWall
56 {
57 type wall;
58 faces
59 (
60 (6 15 16 7)
61 (7 16 17 8)
62 );
63 }
64 fixedWalls
65 {
66 type wall;
67 faces
68 (
69 (3 12 15 6)
70 (0 9 12 3)
71 (0 1 10 9)
72 (1 2 11 10)
73 (2 5 14 11)
74 (5 8 17 14)
75 );
76 }
77 frontAndBack
78 {
79 type empty;
80 faces
81 (
82 (0 3 4 1)
83 (1 4 5 2)
84 (3 6 7 4)
85 (4 7 8 5)
86 (9 10 13 12)
87 (10 11 14 13)
88 (12 13 16 15)
89 (13 14 17 16)
90 );
91 }
92);
93
94mergePatchPairs
95(
96);
97
98// ************************************************************************* //
Once familiar with the blockMeshDict file for this case, the user can execute blockMesh from the
command line. The graded mesh can be viewed as before using paraFoam as described in
section 2.1.2.
2.1.6.2 Changing time and time step
The highest velocities and smallest cells are next to the lid, therefore the highest Courant number
will be generated next to the lid, for reasons given in section 2.1.1.4. It is therefore useful to
estimate the size of the cells next to the lid to calculate an appropriate time step for this case.
When a nonuniform mesh grading is used, blockMesh calculates the cell sizes using a geometric
progression. Along a length , if cells are requested with a ratio of between the last and first
cells, the size of the smallest cell, , is given by:
(2.5)
where is the ratio between one cell size and the next which is given by:
(2.6)
and
(2.7)
For the cavityGrade case the number of cells in each direction in a block is 10, the ratio between largest
and smallest cells is and the block height and width is 0.05 . Therefore the smallest cell length is
3.45 . From Equation 2.2, the time step should be less than 3.45 to maintain a Courant of less
than 1. To ensure that results are written out at convenient time intervals, the time step deltaT should be
reduced to 2.5 and the writeInterval set to 40 so that results are written out every 0.1 s. These settings
can be viewed in the cavityGrade/system/controlDict file.
The startTime needs to be set to that of the final conditions of the case cavityFine, i.e. 0.7.
Since cavity and cavityFine converged well within the prescribed run time, we can set the run time
for case cavityGrade to 0.1 s, i.e. the endTime should be 0.8.
2.1.6.3 Mapping fields
As in section 2.1.5.3, use mapFields to map the final results from case cavityFine onto the mesh
for case cavityGrade. Enter the cavityGrade directory and execute mapFields by:
cd $FOAM_RUN/cavityGrade
mapFields ../cavityFine -consistent
Now run icoFoam from the case directory and monitor the run time information. View the
converged results for this case and compare with other results using post-processing tools
described previously in section 2.1.5.6 and section 2.1.5.7.
run
foamCloneCase -latestTime cavity cavityHighRe
cd cavityHighRe
2.1.7.1 Pre-processing
Go into the cavityHighRe case and edit the transportProperties dictionary in the constant directory.
Since the Reynolds number is required to be increased by a factor of 10, decrease the kinematic
viscosity by a factor of 10, i.e. to . We now run this case by restarting from the
solution at the end of the cavity case run. To do this we can use the option of setting the startFrom
keyword to latestTime so that icoFoam takes as its initial data the values stored in the directory
corresponding to the most recent time, i.e. 0.5. The endTime should be set to 2 s.
enables a command to keep running after the user who issues the command has logged out;
nice
changes the priority of the job in the kernel’s scheduler; a niceness of -20 is the highest priority
and 19 is the lowest priority.
This is useful, for example, if a user wishes to set a case running on a remote machine and does
not wish to monitor it heavily, in which case they may wish to give it low priority on the machine.
In that case the nohup command allows the user to log out of a remote machine he/she is running
on and the job continues running, while nice can set the priority to 19. For our case of interest,
we can execute the command in this manner as follows:
In previous runs you may have noticed that icoFoam stops solving for velocity U quite quickly but
continues solving for pressure p for a lot longer or until the end of the run. In practice, once icoFoam stops
solving for U and the initial residual of p is less than the tolerance set in the fvSolution dictionary
(typically ), the run has effectively converged and can be stopped once the field data has been
written out to a time directory. For example, at convergence a sample of the log file from the run on
the cavityHighRe case appears as follows in which the velocity has already converged after 1.395 s and
initial pressure residuals are small; No Iterations 0 indicates that the solution of U has stopped:
1Time = 1.43
2
3Courant Number mean: 0.221921 max: 0.839902
4smoothSolver: Solving for Ux, Initial residual = 8.73381e-06, Final residual = 8.73381e-06, No Iterations 0
5smoothSolver: Solving for Uy, Initial residual = 9.89679e-06, Final residual = 9.89679e-06, No Iterations 0
6DICPCG: Solving for p, Initial residual = 3.67506e-06, Final residual = 8.62986e-07, No Iterations 4
7time step continuity errors : sum local = 6.57947e-09, global = -6.6679e-19, cumulative = -6.2539e-18
8DICPCG: Solving for p, Initial residual = 2.60898e-06, Final residual = 7.92532e-07, No Iterations 3
9time step continuity errors : sum local = 6.26199e-09, global = -1.02984e-18, cumulative = -7.28374e-18
10ExecutionTime = 0.37 s ClockTime = 0 s
11
12Time = 1.435
13
14Courant Number mean: 0.221923 max: 0.839903
15smoothSolver: Solving for Ux, Initial residual = 8.53935e-06, Final residual = 8.53935e-06, No Iterations 0
16smoothSolver: Solving for Uy, Initial residual = 9.71405e-06, Final residual = 9.71405e-06, No Iterations 0
17DICPCG: Solving for p, Initial residual = 4.0223e-06, Final residual = 9.89693e-07, No Iterations 3
18time step continuity errors : sum local = 8.15199e-09, global = 5.33614e-19, cumulative = -6.75012e-18
19DICPCG: Solving for p, Initial residual = 2.38807e-06, Final residual = 8.44595e-07, No Iterations 3
20time step continuity errors : sum local = 7.48751e-09, global = -4.42707e-19, cumulative = -7.19283e-18
21ExecutionTime = 0.37 s ClockTime = 0 s
2.1.8.1 Pre-processing
Go back to the run directory and copy the cavity case in
the $FOAM_RUN/tutorials/incompressible/pisoFoam/RAS directory (N.B:
the pisoFoam/RAS directory), renaming it cavityRAS to avoid a clash with the existing cavity
tutorial. Go into the new case directory.
run
cp -r $FOAM_TUTORIALS/incompressible/pisoFoam/RAS/cavity cavityRAS
cd cavityRAS
Generate the mesh by running blockMesh as before. Mesh grading towards the wall is not necessary
when using the standard model with wall functions since the flow in the near wall cell is modelled,
rather than having to be resolved.
A range of wall function models is available in OpenFOAM that are applied as boundary
conditions on individual patches. This enables different wall function models to be applied to
different wall regions. The choice of wall function models are specified through the turbulent
viscosity field, in the 0/nut file:
17
18dimensions [0 2 -1 0 0 0 0];
19
20internalField uniform 0;
21
22boundaryField
23{
24 movingWall
25 {
26 type nutkWallFunction;
27 value uniform 0;
28 }
29 fixedWalls
30 {
31 type nutkWallFunction;
32 value uniform 0;
33 }
34 frontAndBack
35 {
36 type empty;
37 }
38}
39
40
41// ************************************************************************* //
This case uses standard wall functions, specified by the nutWallFunction type on the movingWall
and fixedWalls patches. Other wall function models include the rough wall functions, specified
through the nutRoughWallFunction keyword.
The user should now open the field files for and (0/k and 0/epsilon) and examine their
boundary conditions. For a wall boundary condition, is assigned a epsilonWallFunction boundary
condition and a kqRwallFunction boundary condition is assigned to . The latter is a generic
boundary condition that can be applied to any field that are of a turbulent kinetic energy
type, e.g. , or Reynolds Stress . The initial values for and are set using an estimated
fluctuating component of velocity and a turbulent length scale, . and are defined in terms
of these parameters as follows:
(2.10)
where , and are the fluctuating components of velocity in the , and directions
respectively. Let us assume the initial turbulence is isotropic, i.e. , and equal to
5% of the lid velocity and that , is equal to 5% of the box width, 0.1 , then and are given by:
These form the initial conditions for and . The initial conditions for and are and
0 respectively as before.
Turbulence modelling includes a range of methods, e.g. RAS or large-eddy simulation (LES),
that are provided in OpenFOAM. The choice of turbulence modelling method is selectable at
run-time through the simulationType keyword in momentumTransport dictionary (known
as turbulenceProperties prior to OpenFOAM v8). The user can view this file in the constant directory:
17
18simulationType RAS;
19
20RAS
21{
22 model kEpsilon;
23
24 turbulence on;
25
26 printCoeffs on;
27}
28
29// ************************************************************************* //
The options for simulationType are laminar, RAS and LES. With RAS selected in this case, the
choice of RAS modelling is specified in a RAS subdictionary. The turbulence model is selected
by the model entry from a long list of available models that are listed in Section 7.2.1.1.
The kEpsilon model should be selected which is the standard model; the user should also
ensure that turbulence calculation is switched on.
The coefficients for each turbulence model are stored within the respective code with a set of
default values. Setting the optional switch called printCoeffs to on will make the default values be
printed to standard output, i.e. the terminal, when the model is called at run time. The coefficients
are printed out as a sub-dictionary whose name is that of the model name with the
word Coeffs appended, e.g. kEpsilonCoeffs in the case of the kEpsilon model. The coefficients of
the model, e.g. kEpsilon, can be modified by optionally including (copying and pasting) that sub-
dictionary within the RAS sub-dictionary and adjusting values accordingly.
The user should next set the laminar kinematic viscosity in the transportProperties dictionary. To
achieve a Reynolds number of , a kinematic viscosity of is required based on the
Reynolds number definition given in Equation 2.1.
Finally the user should set the startTime, stopTime, deltaT and the writeInterval in the controlDict.
Set deltaT to 0.005 s to satisfy the Courant number restriction and the endTime to 10 s.
run
cp -r $FOAM_TUTORIALS/incompressible/icoFoam/cavity/cavityClipped .
cd cavityClipped
The case consists of the standard cavity geometry but with a square of length removed from the
bottom right of the cavity, according to the blockMeshDict below:
17convertToMeters 0.1;
18
19vertices
20(
21 (0 0 0)
22 (0.6 0 0)
23 (0 0.4 0)
24 (0.6 0.4 0)
25 (1 0.4 0)
26 (0 1 0)
27 (0.6 1 0)
28 (1 1 0)
29
30 (0 0 0.1)
31 (0.6 0 0.1)
32 (0 0.4 0.1)
33 (0.6 0.4 0.1)
34 (1 0.4 0.1)
35 (0 1 0.1)
36 (0.6 1 0.1)
37 (1 1 0.1)
38
39);
40
41blocks
42(
43 hex (0 1 3 2 8 9 11 10) (12 8 1) simpleGrading (1 1 1)
44 hex (2 3 6 5 10 11 14 13) (12 12 1) simpleGrading (1 1 1)
45 hex (3 4 7 6 11 12 15 14) (8 12 1) simpleGrading (1 1 1)
46);
47
48edges
49(
50);
51
52boundary
53(
54 lid
55 {
56 type wall;
57 faces
58 (
59 (5 13 14 6)
60 (6 14 15 7)
61 );
62 }
63 fixedWalls
64 {
65 type wall;
66 faces
67 (
68 (0 8 10 2)
69 (2 10 13 5)
70 (7 15 12 4)
71 (4 12 11 3)
72 (3 11 9 1)
73 (1 9 8 0)
74 );
75 }
76 frontAndBack
77 {
78 type empty;
79 faces
80 (
81 (0 2 3 1)
82 (2 5 6 3)
83 (3 6 7 4)
84 (8 9 11 10)
85 (10 11 14 13)
86 (11 12 15 14)
87 );
88 }
89);
90
91mergePatchPairs
92(
93);
94
95// ************************************************************************* //
Generate the mesh with blockMesh. The patches are set accordingly as in previous cavity cases.
For the sake of clarity in describing the field mapping process, the upper wall patch is
renamed lid, previously the movingWall patch of the original cavity.
In an inconsistent mapping, there is no guarantee that all the field data can be mapped from the
source case. The remaining data must come from field files in the target case itself. Therefore
field data must exist in the time directory of the target case before mapping takes place. In
the cavityClipped case the mapping is set to occur at time 0.5 s, since the startTime is set to 0.5 s
in the controlDict. Therefore the user needs to copy initial field data to that directory, e.g. from time
0:
cp -r 0 0.5
Before mapping the data, the user should view the geometry and fields at 0.5 s.
Now we wish to map the velocity and pressure fields from cavity onto the new fields
of cavityClipped. Since the mapping is inconsistent, we need to edit the mapFieldsDict dictionary,
located in the system directory. The dictionary contains 2 keyword entries: patchMap
and cuttingPatches. The patchMap list contains a mapping of patches from the source fields to the
target fields. It is used if the user wishes a patch in the target field to inherit values from a
corresponding patch in the source field. In cavityClipped, we wish to inherit the boundary values
on the lid patch from movingWall in cavity so we must set the patchMap as:
patchMap
(
lid movingWall
);
The cuttingPatches list contains names of target patches whose values are to be mapped from
the source internal field through which the target patch cuts. In this case, the fixedWalls patch is
a noSlip condition so the internal values cannot be interpolated to the patch. Therefore
the cuttingPatches list can simply be empty:
cuttingPatches
(
);
If the user does wish to interpolate internal values from the source case to the fixedWalls patch in the
target case, a fixedValue boundary condition needs to be specified on the patch, whose value can then
be overridden during the mapping process; the fixedWalls patch then needs to be included in
the cuttingPatches list.
The user should run mapFields, from within the cavityClipped directory:
mapFields ../cavity
The user can view the mapped field as shown in Figure 2.14. The fixedWalls patch has not inherited
values from the source case as we expected. The user can then run the case with icoFoam.
The problem can be approximated as 2-dimensional since the load is applied in the plane of the
plate. In a Cartesian coordinate system there are two possible assumptions to take in regard to
the behaviour of the structure in the third dimension: (1) the plane stress condition, in which the
stress components acting out of the 2D plane are assumed to be negligible; (2) the plane strain
condition, in which the strain components out of the 2D plane are assumed negligible. The plane
stress condition is appropriate for solids whose third dimension is thin as in this case; the plane
strain condition is applicable for solids where the third dimension is thick.
An analytical solution exists for loading of an infinitely large, thin plate with a circular hole. The
solution for the stress normal to the vertical plane of symmetry is
(2.14)
Results from the simulation will be compared with this solution. At the end of the tutorial, the user can:
investigate the sensitivity of the solution to mesh resolution and mesh grading; and, increase the size of
the plate in comparison to the hole to try to estimate the error in comparing the analytical solution for an
infinite plate to the solution of this problem of a finite plate.
Figure 2.17: Block structure of the mesh for the plate with a hole.
The user should change to the run directory and copy the plateHole case into it from
the $FOAM_TUTORIALS/stressAnalysis/solidDisplacementFoam directory. The user should then go
into the plateHole directory and open the blockMeshDict file in an editor, as listed below
17convertToMeters 1;
18
19vertices
20(
21 (0.5 0 0)
22 (1 0 0)
23 (2 0 0)
24 (2 0.707107 0)
25 (0.707107 0.707107 0)
26 (0.353553 0.353553 0)
27 (2 2 0)
28 (0.707107 2 0)
29 (0 2 0)
30 (0 1 0)
31 (0 0.5 0)
32 (0.5 0 0.5)
33 (1 0 0.5)
34 (2 0 0.5)
35 (2 0.707107 0.5)
36 (0.707107 0.707107 0.5)
37 (0.353553 0.353553 0.5)
38 (2 2 0.5)
39 (0.707107 2 0.5)
40 (0 2 0.5)
41 (0 1 0.5)
42 (0 0.5 0.5)
43);
44
45blocks
46(
47 hex (5 4 9 10 16 15 20 21) (10 10 1) simpleGrading (1 1 1)
48 hex (0 1 4 5 11 12 15 16) (10 10 1) simpleGrading (1 1 1)
49 hex (1 2 3 4 12 13 14 15) (20 10 1) simpleGrading (1 1 1)
50 hex (4 3 6 7 15 14 17 18) (20 20 1) simpleGrading (1 1 1)
51 hex (9 4 7 8 20 15 18 19) (10 20 1) simpleGrading (1 1 1)
52);
53
54edges
55(
56 arc 0 5 (0.469846 0.17101 0)
57 arc 5 10 (0.17101 0.469846 0)
58 arc 1 4 (0.939693 0.34202 0)
59 arc 4 9 (0.34202 0.939693 0)
60 arc 11 16 (0.469846 0.17101 0.5)
61 arc 16 21 (0.17101 0.469846 0.5)
62 arc 12 15 (0.939693 0.34202 0.5)
63 arc 15 20 (0.34202 0.939693 0.5)
64);
65
66boundary
67(
68 left
69 {
70 type symmetryPlane;
71 faces
72 (
73 (8 9 20 19)
74 (9 10 21 20)
75 );
76 }
77 right
78 {
79 type patch;
80 faces
81 (
82 (2 3 14 13)
83 (3 6 17 14)
84 );
85 }
86 down
87 {
88 type symmetryPlane;
89 faces
90 (
91 (0 1 12 11)
92 (1 2 13 12)
93 );
94 }
95 up
96 {
97 type patch;
98 faces
99 (
100 (7 8 19 18)
101 (6 7 18 17)
102 );
103 }
104 hole
105 {
106 type patch;
107 faces
108 (
109 (10 5 16 21)
110 (5 0 11 16)
111 );
112 }
113 frontAndBack
114 {
115 type empty;
116 faces
117 (
118 (10 9 4 5)
119 (5 4 1 0)
120 (1 4 3 2)
121 (4 7 6 3)
122 (4 9 8 7)
123 (21 16 15 20)
124 (16 11 12 15)
125 (12 13 14 15)
126 (15 14 17 18)
127 (15 18 19 20)
128 );
129 }
130);
131
132mergePatchPairs
133(
134);
135
136// ************************************************************************* //
Until now, we have only specified straight edges in the geometries of previous tutorials but here
we need to specify curved edges. These are specified under the edges keyword entry which is a
list of non-straight edges. The syntax of each list entry begins with the type of curve,
including arc, simpleSpline, polyLine etc. , described further in section 5.3.1. In this example, all the
edges are circular and so can be specified by the arc keyword entry. The following entries are
the labels of the start and end vertices of the arc and a point vector through which the circular
arc passes.
The blocks in this blockMeshDict do not all have the same orientation. As can be seen in
Figure 2.17 the direction of block 0 is equivalent to the direction for block 4. This means
care must be taken when defining the number and distribution of cells in each block so that the
cells match up at the block faces.
6 patches are defined: one for each side of the plate, one for the hole and one for the front and
back planes. The left and down patches are both a symmetry plane. Since this is a geometric
constraint, it is included in the definition of the mesh, rather than being purely a specification on
the boundary condition of the fields. Therefore they are defined as such using a
special symmetryPlane type as shown in the blockMeshDict.
The frontAndBack patch represents the plane which is ignored in a 2D case. Again this is a
geometric constraint so is defined within the mesh, using the empty type as shown in
the blockMeshDict. For further details of boundary types and geometric constraints, the user
should refer to section 5.2.
The remaining patches are of the regular patch type. The mesh should be generated
using blockMesh and can be viewed in paraFoam as described in section 2.1.2. It should appear
as in Figure 2.18.
Figure 2.18: Mesh of the hole in a plate problem.
Firstly, it can be seen that the displacement initial conditions are set to . The left
and down patches must be both of symmetryPlane type since they are specified as such in the
mesh description in the constant/polyMesh/boundary file. Similarly the frontAndBack patch is
declared empty.
The other patches are traction boundary conditions, set by a specialist traction boundary type.
The traction boundary conditions are specified by a linear combination of: (1) a boundary traction
vector under keyword traction; (2) a pressure that produces a traction normal to the boundary
surface that is defined as negative when pointing out of the surface, under keyword pressure.
The up and hole patches are zero traction so the boundary traction and pressure are set to zero.
For the right patch the traction should be and the pressure should be 0 .
2.2.1.2 Mechanical properties
The physical properties for the case are set in the mechanicalProperties dictionary in the constant
directory. For this problem, we need to specify the mechanical properties of steel given in
Table 2.1. In the mechanical properties dictionary, the user must also set planeStress to yes.
Property Units Keyword Value
Young’s modulus E
In this case we do not want to solve for the thermal equation. Therefore we must set
the thermalStress keyword entry to no in the thermophysicalProperties dictionary.
2.2.1.4 Control
As before, the information relating to the control of the solution procedure are read in from
the controlDict dictionary. For this case, the startTime is 0 . The time step is not important since
this is a steady state case; in this situation it is best to set the time step deltaT to 1 so it simply
acts as an iteration counter for the steady-state case. The endTime, set to 100, then acts as a
limit on the number of iterations. The writeInterval can be set to .
The controlDict entries are as follows:
17
18application solidDisplacementFoam;
19
20startFrom startTime;
21
22startTime 0;
23
24stopAt endTime;
25
26endTime 100;
27
28deltaT 1;
29
30writeControl timeStep;
31
32writeInterval 20;
33
34purgeWrite 0;
35
36writeFormat ascii;
37
38writePrecision 6;
39
40writeCompression off;
41
42timeFormat general;
43
44timePrecision 6;
45
46graphFormat raw;
47
48runTimeModifiable true;
49
50
51// ************************************************************************* //
The fvSolution dictionary in the system directory controls the linear equation solvers and
algorithms used in the solution. The user should first look at the solvers sub-dictionary and notice
that the choice of solver for D is GAMG. The solver tolerance should be set to for this
problem. The solver relative tolerance, denoted by relTol, sets the required reduction in the
residuals within each iteration. It is uneconomical to set a tight (low) relative tolerance within
each iteration since a lot of terms in each equation are explicit and are updated as part of the
segregated iterative procedure. Therefore a reasonable value for the relative tolerance is ,
or possibly even higher, say , or in some cases even (as in this case).
17
18solvers
19{
20 "(D|T)"
21 {
22 solver GAMG;
23 tolerance 1e-06;
24 relTol 0.9;
25 smoother GaussSeidel;
26 nCellsInCoarsestLevel 20;
27 }
28}
29
30stressAnalysis
31{
32 compactNormalStress yes;
33 nCorrectors 1;
34 D 1e-06;
35}
36
37
38// ************************************************************************* //
The fvSolution dictionary contains a sub-dictionary, stressAnalysis that contains some control
parameters specific to the application solver. Firstly there is nCorrectors which specifies the
number of outer loops around the complete system of equations, including traction boundary
conditions within each time step. Since this problem is steady-state, we are performing a set of
iterations towards a converged solution with the ’time step’ acting as an iteration counter. We
can therefore set nCorrectors to 1.
The D keyword specifies a convergence tolerance for the outer iteration loop, i.e. sets a level of
initial residual below which solving will cease. It should be set to the desired solver tolerance
specified earlier, for this problem.
2.2.2 Running the code
The user should run the code here in the background from the command line as specified below,
so he/she can look at convergence information in the log file afterwards.
The user should check the convergence information by viewing the generated log file which shows the
number of iterations and the initial and final residuals of the displacement in each direction being solved.
The final residual should always be less than 0.9 times the initial residual as this iteration tolerance set.
Once both initial residuals have dropped below the convergence tolerance of the run has
converged and can be stopped by killing the batch job.
2.2.3 Post-processing
Post processing can be performed as in section 2.1.4. The solidDisplacementFoam solver outputs
the stress field as a symmetric tensor field sigma. This is consistent with the way variables are
usually represented in OpenFOAM solvers by the mathematical symbol by which they are
represented; in the case of Greek symbols, the variable is named phonetically.
For post-processing individual scalar field components, , etc. , can be generated by
running the postProcess utility as before in section 2.1.5.7, this time on sigma:
Components named sigmaxx, sigmaxy etc. are written to time directories of the case. The stresses
can be viewed in paraFoam as shown in Figure 2.19.
We would like to compare the analytical solution of Equation 2.14 to our solution. We therefore
must output a set of data of along the left edge symmetry plane of our domain. The user
may generate the required graph data using the postProcess utility with the singleGraph function.
Unlike earlier examples of postProcess where no configuration is required, this example includes
a singleGraph file pre-configured in the system directory. The sample line is set
between and , and the fields are specified in the fields list:
9start (0 0.5 0.25);
10end (0 2 0.25);
11fields (sigmaxx);
12
13#includeEtc "caseDicts/postProcessing/graphs/sampleDict.cfg"
14
15setConfig
16{
17 axis y;
18}
19
20// Must be last entry
21#includeEtc "caseDicts/postProcessing/graphs/graph.cfg"
22
23// ************************************************************************* //
Data is written in raw 2 column format into files within time subdirectories of a postProcessing/singleGraph
directory, e.g. the data at s is found within the file singleGraph/100/line_sigmaxx.xy. If the user
has GnuPlot installed they launch it (by typing gnuplot) and then plot both the numerical data and
analytical solution as follows:
run
cp -r $FOAM_TUTORIALS/multiphase/interFoam/laminar/damBreak/damBreak .
Go into the damBreak case directory and generate the mesh running blockMesh as described previously.
The damBreak mesh consist of 5 blocks; the blockMeshDict entries are given below.
17convertToMeters 0.146;
18
19vertices
20(
21 (0 0 0)
22 (2 0 0)
23 (2.16438 0 0)
24 (4 0 0)
25 (0 0.32876 0)
26 (2 0.32876 0)
27 (2.16438 0.32876 0)
28 (4 0.32876 0)
29 (0 4 0)
30 (2 4 0)
31 (2.16438 4 0)
32 (4 4 0)
33 (0 0 0.1)
34 (2 0 0.1)
35 (2.16438 0 0.1)
36 (4 0 0.1)
37 (0 0.32876 0.1)
38 (2 0.32876 0.1)
39 (2.16438 0.32876 0.1)
40 (4 0.32876 0.1)
41 (0 4 0.1)
42 (2 4 0.1)
43 (2.16438 4 0.1)
44 (4 4 0.1)
45);
46
47blocks
48(
49 hex (0 1 5 4 12 13 17 16) (23 8 1) simpleGrading (1 1 1)
50 hex (2 3 7 6 14 15 19 18) (19 8 1) simpleGrading (1 1 1)
51 hex (4 5 9 8 16 17 21 20) (23 42 1) simpleGrading (1 1 1)
52 hex (5 6 10 9 17 18 22 21) (4 42 1) simpleGrading (1 1 1)
53 hex (6 7 11 10 18 19 23 22) (19 42 1) simpleGrading (1 1 1)
54);
55
56edges
57(
58);
59
60boundary
61(
62 leftWall
63 {
64 type wall;
65 faces
66 (
67 (0 12 16 4)
68 (4 16 20 8)
69 );
70 }
71 rightWall
72 {
73 type wall;
74 faces
75 (
76 (7 19 15 3)
77 (11 23 19 7)
78 );
79 }
80 lowerWall
81 {
82 type wall;
83 faces
84 (
85 (0 1 13 12)
86 (1 5 17 13)
87 (5 6 18 17)
88 (2 14 18 6)
89 (2 3 15 14)
90 );
91 }
92 atmosphere
93 {
94 type patch;
95 faces
96 (
97 (8 20 21 9)
98 (9 21 22 10)
99 (10 22 23 11)
100 );
101 }
102);
103
104mergePatchPairs
105(
106);
107
108// ************************************************************************* //
(2.15)
This will be done by running the setFields utility. It requires a setFieldsDict dictionary, located in
the system directory, whose entries for this case are shown below.
17
18defaultFieldValues
19(
20 volScalarFieldValue alpha.water 0
21);
22
23regions
24(
25 boxToCell
26 {
27 box (0 0 -1) (0.1461 0.292 1);
28 fieldValues
29 (
30 volScalarFieldValue alpha.water 1
31 );
32 }
33);
34
35
36// ************************************************************************* //
The defaultFieldValues sets the default value of the fields, i.e. the value the field takes unless
specified otherwise in the regions sub-dictionary. That sub-dictionary contains a list of
subdictionaries containing fieldValues that override the defaults in a specified region. The region
creates a set of points, cells or faces based on some topological constraint.
Here, boxToCell creates a bounding box within a vector minimum and maximum to define the set
of cells of the water region. The phase fraction is defined as 1 in this region.
The setFields utility reads fields from file and, after re-calculating those fields, will write them back
to file. In the damBreak tutorial, the alpha.water field is initially stored as a backup
named alpha.water.orig. A field file with the .orig extension is read in when the actual file does not
exist, so setFields will read alpha.water.orig but write the resulting output to alpha.water
(or alpha.water.gz if compression is switched on). This way the original file is not overwritten, so
can be reused.
The user should therefore execute setFields like any other utility by:
setFields
Using paraFoam, check that the initial alpha.water field corresponds to the desired distribution as in
Figure 2.22.
Kinematic viscosity nu
Density rho
air properties
Kinematic viscosity nu
Gravitational acceleration is uniform across the domain and is specified in a file named g in
the constant directory. Unlike a normal field file, e.g. U and p, g is a uniformDimensionedVectorField
and so simply contains a set of dimensions and a value that represents for this
tutorial:
17
18dimensions [0 1 -2 0 0 0 0];
19value (0 -9.81 0);
20
21
22// ************************************************************************* //
cd $FOAM_RUN/damBreak
interFoam | tee log
The code will now be run interactively, with a copy of output stored in the log file.
2.3.10 Post-processing
Post-processing of the results can now be done in the usual way. The user can monitor the
development of the phase fraction alpha.water in time, e.g. see Figure 2.23.
(a) At .
(b) At .
run
foamCloneCase damBreak damBreakFine
Enter the new case directory and change the blocks description in the blockMeshDict dictionary to
blocks
(
hex (0 1 5 4 12 13 17 16) (46 10 1) simpleGrading (1 1 1)
hex (2 3 7 6 14 15 19 18) (40 10 1) simpleGrading (1 1 1)
hex (4 5 9 8 16 17 21 20) (46 76 1) simpleGrading (1 2 1)
hex (5 6 10 9 17 18 22 21) (4 76 1) simpleGrading (1 2 1)
hex (6 7 11 10 18 19 23 22) (40 76 1) simpleGrading (1 2 1)
);
Here, the entry is presented as printed from the blockMeshDict file; in short the user must change the
mesh densities, e.g. the 46 10 1 entry, and some of the mesh grading entries to 1 2 1. Once the dictionary
is correct, generate the mesh by running blockMesh.
As the mesh has now changed from the damBreak example, the user must re-initialise the phase
field alpha.water in the 0 time directory since it contains a number of elements that is inconsistent
with the new mesh. Note that there is no need to change the U and p_rgh fields since they are
specified as uniform which is independent of the number of elements in the field. We wish to
initialise the field with a sharp interface, i.e. it elements would have or . Updating
the field with mapFields may produce interpolated values at the interface, so it is
better to rerun the setFields utility.
The mesh size is now inconsistent with the number of elements in the alpha.water.gz file in the 0
directory, so the user must delete that file so that the original alpha.water.orig file is used instead.
rm 0/alpha.water.gz
setFields
decomposePar
The terminal output shows that the decomposition is distributed fairly even between the processors.
The user should consult section 3.4 for details of how to run a case in parallel; in this tutorial we
merely present an example of running in parallel. We use the openMPI implementation of the
standard message-passing interface (MPI). As a test here, the user can run in parallel on a
single node, the local host only, by typing:
mpirun -np 4 interFoam -parallel > log &
The user may run on more nodes over a network by creating a file that lists the host names of
the machines on which the case is to be run as described in section 3.4.3. The case should run
in the background and the user can follow its progress by monitoring the log file as usual.
(a) At .
(b) At .
then processor1 will appear as a case module in ParaView. Figure 2.24 shows the mesh from
processor 1 following the decomposition of the domain using the simple method.
Chapter 3 Applications and libraries
We should reiterate from the outset that OpenFOAM is a C++ library used primarily to create
executables, known as applications. OpenFOAM is distributed with a large set of precompiled
applications but users also have the freedom to create their own or modify existing ones.
Applications are split into two main categories:
solvers
that are each designed to solve a specific problem in computational continuum mechanics;
utilities
that perform simple pre-and post-processing tasks, mainly involving data manipulation and
algebraic calculations.
OpenFOAM is divided into a set of precompiled libraries that are dynamically linked during
compilation of the solvers and utilities. Libraries such as those for physical models are supplied
as source code so that users may conveniently add their own models to the libraries. This
chapter gives an overview of solvers, utilities and libraries, their creation, modification,
compilation and execution.
solve
(
fvm::ddt(rho, U)
+ fvm::div(phi, U)
- fvm::laplacian(mu, U)
==
- fvc::grad(p)
);
This and other requirements demand that the principal programming language of OpenFOAM has object-
oriented features such as inheritance, template classes, virtual functions and operator overloading. These
features are not available in many languages that purport to be object-orientated but actually have very
limited object-orientated capability, such as FORTRAN-90. C++, however, possesses all these features
while having the additional advantage that it is widely used with a standard specification so that reliable
compilers are available that produce efficient executables. It is therefore the primary language of
OpenFOAM.
3.1.4 Solver codes
Solver codes are largely procedural since they are a close representation of solution algorithms
and equations, which are themselves procedural in nature. Users do not need a deep knowledge
of object-orientation and C++ programming to write a solver but should know the principles
behind object-orientation and classes, and to have a basic knowledge of some C++ code syntax.
An understanding of the underlying equations, models and solution method and algorithms is far
more important.
There is often little need for a user to immerse themselves in the code of any of the OpenFOAM
classes. The essence of object-orientation is that the user should not have to go through the
code of each class they use; merely the knowledge of the class’ existence and its functionality
are sufficient to use the class. A description of each class, its functions etc. is supplied with the
OpenFOAM distribution in HTML documentation generated with Doxygen
at https://cpp.openfoam.org
3.2 Compiling applications and libraries
Compilation is an integral part of application development that requires careful management
since every piece of code requires its own set instructions to access dependent components of
the OpenFOAM library. In UNIX/Linux systems these instructions are often organised and
delivered to the compiler using the standard UNIXmake utility. OpenFOAM uses its
own wmake compilation script that is based on make but is considerably more versatile and easier
to use (wmake can be used on any code, not only the OpenFOAM library). To understand the
compilation process, we first need to explain certain aspects of C++ and its file structure, shown
schematically in Figure 3.1. A class is defined through a set of instructions such as object
construction, data storage and class member functions. The file that defines these functions —
the class definition — takes a .C extension, e.g. a class nc would be written in the file nc.C. This
file can be compiled independently of other code into a binary executable library file known as a
shared object library with the .so file extension, i.e. nc.so. When compiling a piece of code,
say newApp.C, that uses the nc class, nc.C need not be recompiled, rather newApp.C calls the nc.so
library at runtime. This is known as dynamic linking.
Figure 3.1: Header files, source files, compilation and linking
# include "otherHeader.H";
This causes the compiler to suspend reading from the current file, to read the included file. This
mechanism allows any self-contained piece of code to be put into a header file and included at the
relevant location in the main code in order to improve code readability. For example, in most OpenFOAM
applications the code for creating fields and reading field input data is included in a file createFields.H
which is called at the beginning of the code. In this way, header files are not solely used as class
declarations.
It is wmake that performs the task of maintaining file dependency lists amongst other functions
listed below.
▪ Automatic generation and maintenance of file dependency lists, i.e. lists of files which are
included in the source files and hence on which they depend.
▪ Multi-platform compilation and linkage, handled through appropriate directory structure.
▪ Multi-language compilation and linkage, e.g. C, C++, Java.
▪ Multi-option compilation and linkage, e.g. debug, optimised, parallel and profiling.
▪ Support for source code generation programs, e.g. lex, yacc, IDL, MOC.
▪ Simple syntax for source file lists.
▪ Automatic creation of source file lists for new codes.
▪ Simple handling of multiple shared or static libraries.
▪ Extensible to new machine types.
▪ Extremely portable, works on any machine with: make; sh, ksh or csh; lex, cc.
3.2.2 Compiling with wmake
OpenFOAM applications are organised using a standard convention that the source code of
each application is placed in a directory whose name is that of the application. The top level
source file then takes the application name with the .C extension. For example, the source code
for an application called newApp would reside is a directory newApp and the top level file would
be newApp.C as shown in Figure 3.2.
EXE_INC = \\
-I<directoryPath1> \\
-I<directoryPath2> \\
… \\
-I<directoryPathN>
Notice first that the directory names are preceeded by the -I flag and that the syntax uses the \\ to continue
the EXE_INC across several lines, with no \\ after the final entry.
EXE_LIBS = \\
-L<libraryPath> \\
-l<library1> \\
-l<library2> \\
… \\
-l<libraryN>
To summarise: the directory paths are preceeded by the -L flag, the library names are preceeded by the -
l flag.
newApp.C
EXE = $(FOAM_USER_APPBIN)/newApp
wmake <optionalDirectory>
The <optionalDirectory> is the directory path of the application that is being compiled. Typically, wmake is
executed from within the directory of the application being compiled, in which
case <optionalDirectory> can be omitted.
$WM_PROJECT_INST_DI
R
Full path to installation directory, e.g. $HOME/OpenFOAM
$WM_PROJECT
Name of the project being compiled: OpenFOAM
$WM_PROJECT_VERSIO
N
Version of the project being compiled: 6
$WM_PROJECT_DIR
Full path to locate binary executables of OpenFOAM
release, e.g. $HOME/OpenFOAM/OpenFOAM-6
$WM_PROJECT_USER_D
IR
Full path to locate binary executables of the
user e.g. $HOME/OpenFOAM/${USER}-6
$WM_THIRD_PARTY_DIR
Full path to the ThirdParty software
directory e.g. $HOME/OpenFOAM/ThirdParty-6
Other paths/settings
Machine
$WM_ARCH
architecture: linux, linux64, linuxIa64, linuxARM7, linuxPPC64, linuxPP
C64le
$WM_ARCH_OPTION 32 or 64 bit architecture
$WM_COMPILER
Compiler being used: Gcc - gcc, ICC - Intel, Clang - LLVM Clang
$WM_COMPILE_OPTION
Compilation option: Debug - debugging, Opt optimisation.
$WM_LINK_LANGUAGE
Compiler used to link libraries and executables c++.
Parallel communications library: SYSTEMOPENMPI - system
$WM_MPLIB
version of openMPI, OPENMPI, SYSTEMMPI, MPICH, MPICH-
GM, HPMPI, MPI, QSMPI, SGIMPI.
= $WM_ARCH…
$WM_COMPILER…
$WM_PRECISION_OPTION…
$WM_LABEL_OPTION…
$WM_OPTIONS
$WM_COMPILE_OPTION
e.g. linuxGccDPInt64Opt
$WM_PRECISION_OPTIO
N
Precision of the compiled binares, SP, single precision or DP,
double precision
wclean <optionalDirectory>
Again, the <optionalDirectory> is a path to the directory of the application that is being compiled.
Typically, wclean is executed from within the directory of the application, in which case the path can be
omitted.
The code begins with a brief description of the application contained within comments over 1
line (//) and multiple lines (/*…*/). Following that, the code contains several #
include statements, e.g. # include "fvCFD.H", which causes the compiler to suspend reading from
the current file, pisoFoam.C to read the fvCFD.H. pisoFoam resources the turbulence and transport
model libraries and therefore requires the necessary header files, specified by the EXE_INC = -
I… option, and links to the libraries with the EXE_LIBS = -l… option. The Make/options therefore
contains the following:
1EXE_INC = \\
2 -I$(LIB_SRC)/MomentumTransportModels/momentumTransportModels/lnInclude \\
3 -I$(LIB_SRC)/MomentumTransportModels/incompressible/lnInclude \\
4 -I$(LIB_SRC)/transportModels/lnInclude \\
5 -I$(LIB_SRC)/finiteVolume/lnInclude \\
6 -I$(LIB_SRC)/meshTools/lnInclude \\
7 -I$(LIB_SRC)/sampling/lnInclude
8
9EXE_LIBS = \\
10 -lmomentumTransportModels \\
11 -lincompressibleMomentumTransportModels \\
12 -lincompressibleTransportModels \\
13 -lfiniteVolume \\
14 -lmeshTools \\
15 -lfvOptions \\
16 -lsampling
pisoFoam contains only the pisoFoam.C source and the executable is written to the $FOAM_APPBIN
directory as all standard applications are. The Make/files therefore contains:
1pisoFoam.C
2
3EXE = $(FOAM_APPBIN)/pisoFoam
Following the recommendations of section 3.2.2.3, the user can compile a separate version
of pisoFoam into their local $FOAM_USER_DIR directory by the following:
▪ copying the pisoFoam source code to a local directory, e.g. $FOAM_RUN;
cd $FOAM_RUN
cp -r $FOAM_SOLVERS/incompressible/pisoFoam .
cd pisoFoam
▪ editing the Make/files file as follows;
1pisoFoam.C
2
3EXE = $(FOAM_USER_APPBIN)/pisoFoam
▪ executing wmake.
wmake
The code should compile and produce a message similar to the following
The user can now try recompiling and will receive a message similar to the following to say that the
executable is up to date and compiling is not necessary:
wclean
level
Overall level of debugging messaging for OpenFOAM- - 3
levels 0, 1, 2
lduMatrix
Messaging for solver convergence during a run - 3 levels 0, 1, 2
floatTransfer
If 1, will compact numbers to float precision before transfer;
default is 0
Optimises global sum for parallel processing; sets number of
nProcsSimpleSum
processors above which hierarchical sum is performed rather
than a linear sum (default 16)
libs
(
"libnew1.so"
"libnew2.so"
);
blockMesh -help
If the application is executed from within a case directory, it will operate on that case. Alternatively, the -
case <caseDir> option allows the case to be specified directly so that the application can be executed
from anywhere in the filing system.
Like any UNIX/Linux executable, applications can be run as a background process, i.e. one which
does not have to be completed before the user can give the shell additional commands. If the
user wished to run the blockMesh example as a background process and output the case
progress to a log file, they could enter:
The user has a choice of four methods of decomposition, specified by the method keyword as
described below.
simple
Simple geometric decomposition in which the domain is split into pieces by direction, e.g. 2 pieces
in the direction, 1 in etc.
hierarchical
Hierarchical geometric decomposition which is the same as simple except the user specifies the
order in which the directional split is done, e.g. first in the -direction, then the -direction etc.
scotch
Scotch decomposition which requires no geometric input from the user and attempts to minimise
the number of processor boundaries. The user can specify a weighting for the decomposition
between processors, through an optional processorWeights keyword which can be useful on
machines with differing performance between processors. There is also an optional keyword
entry strategy that controls the decomposition strategy through a complex string supplied to
Scotch. For more information, see the source code
file: $FOAM_SRC/parallel/decompose/scotchDecomp/scotchDecomp.C
manual
Manual decomposition, where the user directly specifies the allocation of each cell to a particular
processor.
For each method there are a set of coefficients specified in a sub-dictionary of decompositionDict,
named <method>Coeffs as shown in the dictionary listing. The full set of keyword entries in
the decomposeParDict dictionary are explained in Table 3.3.
Compulsory entries
Total number of
numberOfSubdomains subdomains
Method of
method decomposition simple/ hierarchical/ scotch/ manual/
simpleCoeffs entries
Number of subdomains
n in , , ( )
hierarchicalCoeffs entries
Number of subdomains
n in , , ( )
scotchCoeffs entries
manualCoeffs entries
decomposePar
While this file structure is well-organised, for large parallel cases, it generates a large number of
files. In very large simulations, users can experience problems including hitting limits on the
number of open files imposed by the operating system.
As an alternative, the collated file format was introduced in OpenFOAM in which the data for
each decomposed field (and mesh) is collated into a single file that is written (and read) on the
master processor. The files are stored in a single directory named processors.
The file writing can be threaded allowing the simulation to continue running while the data is
being written to file — see below for details. NFS (Network File System) is not needed when
using the collated format and, additionally, there is a masterUncollated option to write data with
the original uncollated format without NFS.
The controls for the file handling are in the OptimisationSwitches of the global etc/controlDict file:
OptimisationSwitches
{
...
When using the collated file handling, memory is allocated for the data in the
thread. maxThreadFileBufferSize sets the maximum size of memory that is allocated in bytes. If the data
exceeds this size, the write does not use threading. Note: if threading is not enabled in the MPI, it must
be disabled for collated file handling by setting in the global etc/controlDict file:
maxThreadFileBufferSize 0;
When using the masterUncollated file handling, non-blocking MPI communication requires a
sufficiently large memory buffer on the master node. maxMasterFileBufferSize sets the maximum
size of the buffer. If the data exceeds this size, the system uses scheduled communication.
3.4.3 Running a decomposed case
A decomposed OpenFOAM case is run in parallel using the openMPI implementation of
MPI. openMPI can be run on a local multiprocessor machine very simply but when running on
machines across a network, a file must be created that contains the host names of the machines.
The file can be given any name and located at any path. In the following description we shall
refer to such a file by the generic name, including full path, <machines>.
The <machines> file contains the names of the machines listed one machine per line. The names
must correspond to a fully resolved hostname in the /etc/hosts file of the machine on which
the openMPI is run. The list must contain the name of the machine running the openMPI. Where a
machine node contains more than one processor, the node name may be followed by the
entry cpu= where is the number of processors openMPI should run on that node.
For example, let us imagine a user wishes to run openMPI from machine aaa on the following
machines: aaa; bbb, which has 2 processors; and ccc. The <machines> would contain:
aaa
bbb cpu=2
ccc
An application is run in parallel using mpirun.
distributed yes;
and the roots entry is a list of root paths, <root0>, <root1>, …, for each node
roots
<nRoots>
(
"<root0>"
"<root1>"
…
);
Each of the processor directories should be placed in the case directory at each of the root
paths specified in the decomposeParDict dictionary. The system directory and files within
the constant directory must also be present in each case directory. Note: the files in the constant
directory are needed, but the polyMesh directory is not.
3.4.5 Post-processing parallel processed cases
When post-processing cases that have been run in parallel the user has two options:
▪ reconstruction of the mesh and field data to recreate the complete domain and fields,
which can be post-processed as normal;
▪ post-processing each segment of decomposed domain individually.
3.4.5.1 Reconstructing mesh and data
After a case has been run in parallel, it can be reconstructed for post-processing. The case is
reconstructed by merging the sets of time directories from each processor directory into a single
set of time directories. The reconstructPar utility performs such a reconstruction by executing the
command:
reconstructPar
When the data is distributed across several disks, it must be first copied to the local case directory for
reconstruction.
potentialFoam
Potential flow solver which solves for the velocity potential, to calculate the flux-field, from which
the velocity field is obtained by reconstructing the flux.
scalarTransportFoam
Solves the steady or transient transport equation for a passive scalar.
Steady-state solver for incompressible, turbulent flow of non-Newtonian fluids with optimisation
of duct shape by applying ”blockage” in regions causing pressure loss as estimated using an
adjoint formulation.
boundaryFoam
Steady-state solver for incompressible, 1D turbulent flow, typically to generate boundary layer
conditions at an inlet, for use in a simulation.
icoFoam
Transient solver for incompressible, laminar flow of Newtonian fluids.
nonNewtonianIcoFoam
Transient solver for incompressible, laminar flow of non-Newtonian fluids.
pimpleFoam
Transient solver for incompressible, turbulent flow of Newtonian fluids, with optional mesh motion
and mesh topology changes.
SRFPimpleFoam
Large time-step transient solver for incompressible, turbulent flow in a single rotating frame.
pisoFoam
Transient solver for incompressible, turbulent flow, using the PISO algorithm.
shallowWaterFoam
Transient solver for inviscid shallow-water equations with rotation.
simpleFoam
Steady-state solver for incompressible, turbulent flow, using the SIMPLE algorithm.
porousSimpleFoam
Steady-state solver for incompressible, turbulent flow with implicit or explicit porosity treatment
and support for multiple reference frames (MRF).
SRFSimpleFoam
Steady-state solver for incompressible, turbulent flow of non-Newtonian fluids in a single rotating
frame.
rhoPimpleFoam
Transient solver for turbulent flow of compressible fluids for HVAC and similar applications, with
optional mesh motion and mesh topology changes.
rhoSimpleFoam
Steady-state solver for turbulent flow of compressible fluids.
rhoPorousSimpleFoam
Steady-state solver for turbulent flow of compressible fluids, with implicit or explicit porosity
treatment and optional sources.
Transient cavitation code based on the homogeneous equilibrium model from which the
compressibility of the liquid/vapour ”mixture” is obtained, with optional mesh motion and mesh
topology changes.
compressibleInterFoam
Solver for 2 compressible, non-isothermal immiscible fluids using a VOF (volume of fluid) phase-
fraction based interface capturing approach, with optional mesh motion and mesh topology
changes including adaptive re-meshing.
compressibleInterFilmFoam
Solver for 2 compressible, non-isothermal immiscible fluids using a VOF (volume of fluid) phase-
fraction based interface capturing approach and surface film modelling.
compressibleMultiphaseInterFoam
Solver for compressible, non-isothermal immiscible fluids using a VOF (volume of fluid) phase-
fraction based interface capturing approach.
driftFluxFoam
Solver for 2 incompressible fluids using the mixture approach with the drift-flux approximation for
relative motion of the phases.
interFoam
Solver for 2 incompressible, isothermal immiscible fluids using a VOF (volume of fluid) phase-
fraction based interface capturing approach, with optional mesh motion and mesh topology
changes including adaptive re-meshing.
interMixingFoam
Solver for 3 incompressible fluids, two of which are miscible, using a VOF method to capture the
interface, with optional mesh motion and mesh topology changes including adaptive re-meshing.
interPhaseChangeFoam
Solver for 2 incompressible, isothermal immiscible fluids with phase-change (e.g. cavitation).
Uses a VOF (volume of fluid) phase-fraction based interface capturing approach, with optional
mesh motion and mesh topology changes including adaptive re-meshing.
multiphaseEulerFoam
Solver for a system of many compressible fluid phases including heat-transfer.
multiphaseInterFoam
Solver for incompressible fluids which captures the interfaces and includes surface-tension and
contact-angle effects for each phase, with optional mesh motion and mesh topology changes.
potentialFreeSurfaceFoam
Incompressible Navier-Stokes solver with inclusion of a wave height field to enable single-phase
free-surface approximations, with optional mesh motion and mesh topology changes.
reactingMultiphaseEulerFoam
Solver for a system of any number of compressible fluid phases with a common pressure, but
otherwise separate properties. The type of phase model is run time selectable and can optionally
represent multiple species and in-phase reactions. The phase system is also run time selectable
and can optionally represent different types of momentun, heat and mass transfer.
reactingTwoPhaseEulerFoam
Solver for a system of 2 compressible fluid phases with a common pressure, but otherwise
separate properties. The type of phase model is run time selectable and can optionally represent
multiple species and in-phase reactions. The phase system is also run time selectable and can
optionally represent different types of momentun, heat and mass transfer.
twoLiquidMixingFoam
Solver for mixing 2 incompressible fluids.
twoPhaseEulerFoam
Solver for a system of 2 compressible fluid phases with one phase dispersed, e.g. gas bubbles in
a liquid including heat-transfer.
3.5.6 Combustion
chemFoam
Solver for chemistry problems, designed for use on single cell cases to provide comparison
against other chemistry solvers, that uses a single cell mesh, and fields created from the initial
conditions.
coldEngineFoam
Solver for cold-flow in internal combustion engines.
engineFoam
Transient solver for compressible, turbulent engine flow with a spray particle cloud.
fireFoam
Transient solver for fires and turbulent diffusion flames with reacting particle clouds, surface film
and pyrolysis modelling.
PDRFoam
Solver for compressible premixed/partially-premixed combustion with turbulence modelling.
reactingFoam
Solver for combustion with chemical reactions.
rhoReactingBuoyantFoam
Solver for combustion with chemical reactions using a density based thermodynamics package
with enhanced buoyancy treatment.
rhoReactingFoam
Solver for combustion with chemical reactions using density based thermodynamics package.
XiEngineFoam
Solver for internal combustion engines.
XiFoam
Solver for compressible premixed/partially-premixed combustion with turbulence modelling.
Transient solver for buoyant, turbulent flow of compressible fluids for ventilation and heat-transfer.
buoyantSimpleFoam
Steady-state solver for buoyant, turbulent flow of compressible fluids, including radiation, for
ventilation and heat-transfer.
chtMultiRegionFoam
Solver for steady or transient fluid flow and solid heat conduction, with conjugate heat transfer
between regions, buoyancy effects, turbulence, reactions and radiation modelling.
thermoFoam
Solver for energy transport and thermodynamics on a frozen flow field.
Transient solver for compressible, turbulent flow, with coal and limestone particle clouds, an
energy source, and combustion.
DPMFoam
Transient solver for the coupled transport of a single kinematic particle cloud including the effect
of the volume fraction of particles on the continuous phase, with optional mesh motion and mesh
topology changes.
MPPICFoam
Transient solver for the coupled transport of a single kinematic particle cloud including the effect
of the volume fraction of particles on the continuous phase. Multi-Phase Particle In Cell (MPPIC)
modeling is used to represent collisions without resolving particle-particle interactions, with
optional mesh motion and mesh topology changes.
particleFoam
Transient solver for the passive transport of a single kinematic particle cloud, with optional mesh
motion and mesh topology changes.
reactingParcelFoam
Transient solver for compressible, turbulent flow with a reacting, multiphase particle cloud, and
surface film modelling.
rhoParticleFoam
Transient solver for the passive transport of a particle cloud.
simpleReactingParcelFoam
Steady state solver for compressible, turbulent flow with reacting, multiphase particle clouds and
optional sources/constraints.
sprayFoam
Transient solver for compressible, turbulent flow with a spray particle cloud, with optional mesh
motion and mesh topology changes.
Direct simulation Monte Carlo (DSMC) solver for, transient, multi-species flows.
mdEquilibrationFoam
Solver to equilibrate and/or precondition molecular dynamics systems.
mdFoam
Molecular dynamics solver for fluid dynamics.
3.5.10 Electromagnetics
electrostaticFoam
magneticFoam
Solver for the magnetic field generated by permanent magnets.
mhdFoam
Solver for magnetohydrodynamics (MHD): incompressible, laminar flow of a conducting fluid
under the influence of a magnetic field.
solidEquilibriumDisplacementFoam
Steady-state segregated finite-volume solver of linear-elastic, small-strain deformation of a solid
body, with optional thermal diffusion and thermal stresses.
3.5.12 Finance
financialFoam
Apply a simplified boundary-layer model to the velocity and turbulence fields based on the 1/7th
power-law.
boxTurb
Makes a box of turbulence which conforms to a given energy spectrum and is divergence free.
changeDictionary
Utility to change dictionary entries, e.g. can be used to change the patch type in the field
and polyMesh/boundary files.
createExternalCoupledPatchGeometry
Application to generate the patch geometry (points and faces) for use with
the externalCoupled boundary condition.
dsmcInitialise
faceAgglomerate
Agglomerate boundary faces using the pairPatchAgglomeration algorithm. It writes a map from
the fine to coarse grid.
foamSetupCHT
Sets up a multi-region case using template files for material properties, field and system files.
mapFields
Maps volume fields from one mesh to another, reading and interpolating all fields present in the
time directory of both cases.
mapFieldsPar
Maps volume fields from one mesh to another, reading and interpolating all fields present in the
time directory of both cases. Parallel and non-parallel cases are handled without the need to
reconstruct them first.
mdInitialise
Initialises fields for a molecular dynamics (MD) simulation.
setFields
Set values on a selected set of cells/patchfaces through a dictionary.
setWaves
Applies wave models to the entire domain for case initialisation using level sets for second-order
accuracy.
viewFactorsGen
View factors are calculated based on a face agglomeration array (finalAgglom generated
by faceAgglomerate utility).
wallFunctionTable
extrudeMesh
Extrude mesh from existing patch (by default outwards facing normals; optional flips faces) or
from patch read from file.
extrude2DMesh
Takes 2D mesh (all faces 2 points only, no front and back faces) and creates a 3D mesh by
extruding with specified thickness.
extrudeToRegionMesh
Extrude faceZones (internal or boundary faces) or faceSets (boundary faces only) into a separate
mesh (as a different region).
foamyHexMesh
foamyQuadMesh
Conformal-Voronoi 2D extruding automatic mesher with grid or read initial points and point
position relaxation with optional ”squarification”.
snappyHexMesh
Automatic split hex mesher. Refines and snaps to surface.
Converts an ANSYS input mesh file, exported from I-DEAS, to OpenFOAM format.
cfx4ToFoam
Converts a CFX 4 mesh to OpenFOAM format.
datToFoam
Reads in a datToFoam mesh file and outputs a points file. Used in conjunction with blockMesh.
fluent3DMeshToFoam
Converts a Fluent mesh to OpenFOAM format.
fluentMeshToFoam
Converts a Fluent mesh to OpenFOAM format including multiple region and region boundary
handling.
foamMeshToFluent
Writes out the OpenFOAM mesh in Fluent mesh format.
foamToStarMesh
Reads an OpenFOAM mesh and writes a pro-STAR (v4) bnd/cel/vrt format.
foamToSurface
Reads an OpenFOAM mesh and writes the boundaries in a surface format.
gambitToFoam
Converts a GAMBIT mesh to OpenFOAM format.
gmshToFoam
Reads .msh file as written by Gmsh.
ideasUnvToFoam
I-Deas unv format mesh conversion.
kivaToFoam
Converts a KIVA3v grid to OpenFOAM format.
mshToFoam
Converts .msh file generated by the Adventure system.
netgenNeutralToFoam
Converts neutral file format as written by Netgen v4.4.
ccm26ToFoam
Reads CCM files as written by Prostar/ccm using ccm 2.6 (not 2.4)
plot3dToFoam
Plot3d mesh (ascii/formatted format) converter.
sammToFoam
Converts a Star-CD (v3) SAMM mesh to OpenFOAM format.
star3ToFoam
Converts a Star-CD (v3) pro-STAR mesh into OpenFOAM format.
star4ToFoam
Converts a Star-CD (v4) pro-STAR mesh into OpenFOAM format.
tetgenToFoam
Converts .ele and .node and .face files, written by tetgen.
vtkUnstructuredToFoam
Converts ascii .vtk (legacy format) file generated by vtk/paraview.
writeMeshObj
For mesh debugging: writes mesh as three separate OBJ files which can be viewed with e.g.
javaview.
autoPatch
Divides external faces into patches based on (user supplied) feature angle.
checkMesh
Checks validity of a mesh.
createBaffles
Makes internal faces into boundary faces. Does not duplicate points, unlike mergeOrSplitBaffles.
createPatch
Utility to create patches out of selected boundary faces. Faces come either from existing patches
or from a faceSet.
deformedGeom
Deforms a polyMesh using a displacement field U and a scaling factor supplied as an argument.
flattenMesh
insideCells
Picks up cells with cell centre ’inside’ of surface. Requires surface to be closed and singly
connected.
mergeMeshes
Merges two meshes.
mergeOrSplitBaffles
Detects faces that share points (baffles). Either merge them or duplicate the points.
mirrorMesh
Mirrors a mesh around a given plane.
moveDynamicMesh
Mesh motion and topological mesh changes utility.
moveEngineMesh
Solver for moving meshes for engine calculations.
moveMesh
Solver for moving meshes.
objToVTK
Read obj line (not surface!) file and convert into vtk.
orientFaceZone
Corrects orientation of faceZone.
polyDualMesh
Calculates the dual of a polyMesh. Adheres to all the feature and patch edges.
refineMesh
renumberMesh
Renumbers the cell list in order to reduce the bandwidth, reading and renumbering all fields from
all the time directories.
rotateMesh
Rotates the mesh and fields from the direction n1 to direction n2.
setSet
Manipulate a cell/face/point/ set or zone interactively.
setsToZones
Add pointZones/faceZones/cellZones to the mesh from similar named pointSets/faceSets/cellSets.
singleCellMesh
Reads all fields and maps them to a mesh with all internal faces removed (singleCellFvMesh)
which gets written to region ”singleCell”.
splitMesh
stitchMesh
’Stitches’ a mesh.
subsetMesh
Selects a section of mesh based on a cellSet.
topoSet
Transforms the mesh points in the polyMesh directory according to the translate, rotate and scale
options.
zipUpMesh
Reads in a mesh with hanging vertices and zips up the cells to guarantee that all polyhedral cells
of valid shape are closed.
collapseEdges
Collapses short edges and combines edges that are in line.
combinePatchFaces
Checks for multiple patch faces on same cell and combines them. Multiple patch faces can result
from e.g. removal of refined neighbouring cells, leaving 4 exposed faces with same owner.
modifyMesh
Manipulates mesh elements.
PDRMesh
Mesh and field preparation utility for PDR type simulations.
refineHexMesh
Refines a hex mesh by 2x2x2 cell splitting.
refinementLevel
Tries to figure out what the refinement level is on refined Cartesian meshes. Run BEFORE
snapping.
refineWallLayer
Utility to refine cells next to patches.
removeFaces
Utility to remove faces (combines cells on both sides).
selectCells
Select cells in relation to surface.
splitCells
Utility to split cells with flat faces.
3.6.6 Post-processing
engineCompRatio
Calculate the geometric compression ratio. Note that if you have valves and/or extra volumes it
will not work, since it calculates the volume at BDC and TCD.
noise
Utility to perform noise analysis of pressure data using the noiseFFT library.
pdfPlot
postChannel
Post-processes data from channel flow calculations.
postProcess
Execute the set of functionObjects specified in the selected dictionary (which defaults to
system/controlDict) or on the command-line for the selected set of times on the selected set of
fields.
particleTracks
Generates a VTK file of particle tracks for cases that were computed using a tracked-parcel-type
cloud.
steadyParticleTracks
Generates a VTK file of particle tracks for cases that were computed using a steady-state cloud
NOTE: case must be re-constructed (if running in parallel) before use
temporalInterpolate
Interpolate fields between time-steps e.g. for animation.
foamToEnsight
Translates OpenFOAM data to EnSight format.
foamToEnsightParts
Translates OpenFOAM data to Ensight format. An Ensight part is created for each cellZone and
patch.
foamToTetDualMesh
smapToFoam
Translates a STAR-CD SMAP data file into OpenFOAM field format.
3.6.8 Surface mesh (e.g. OBJ/STL) tools
surfaceAdd
Add two surfaces. Does geometric merge on points. Does not check for overlapping/intersecting
triangles.
surfaceAutoPatch
Patches surface according to feature angle. Like autoPatch.
surfaceBooleanFeatures
Generates the extendedFeatureEdgeMesh for the interface between a boolean operation on two
surfaces. Assumes that the orientation of the surfaces is correct.
surfaceCheck
surfaceClean
Removes baffles - collapses small edges, removing triangles. - converts sliver triangles into split
edges by projecting point onto base of triangle.
surfaceCoarsen
Surface coarsening using ’bunnylod’:
surfaceConvert
Converts from one surface mesh format to another.
surfaceFeatureConvert
Convert between edgeMesh formats.
surfaceFeatures
Identifies features in a surface geometry and writes them to file, based on control parameters
specified by the user.
surfaceFind
Finds nearest face and vertex.
surfaceHookUp
Find close open edges and stitches the surface along them
surfaceInertia
Calculates the inertia tensor, principal axes and moments of a command line specified triSurface.
Inertia can either be of the solid body or of a thin shell.
surfaceLambdaMuSmooth
surfaceMeshConvert
Converts between surface formats with optional scaling or transformations (rotate/translate) on
a coordinateSystem.
surfaceMeshConvertTesting
Converts from one surface mesh format to another, but primarily used for testing functionality.
surfaceMeshExport
Export from surfMesh to various third-party surface formats with optional scaling or
transformations (rotate/translate) on a coordinateSystem.
surfaceMeshImport
Import from various third-party surface formats into surfMesh with optional scaling or
transformations (rotate/translate) on a coordinateSystem.
surfaceMeshInfo
surfaceMeshTriangulate
Extracts surface from a polyMesh. Depending on output surface format triangulates faces.
surfaceOrient
Set normal consistent with respect to a user provided ’outside’ point. If the -inside option is used
the point is considered inside.
surfacePointMerge
Merges points on surface if they are within absolute distance. Since absolute distance use with
care!
surfaceRedistributePar
(Re)distribution of triSurface. Either takes an undecomposed surface or an already decomposed
surface and redistributes it so that each processor has all triangles that overlap its mesh.
surfaceRefineRedGreen
Refine by splitting all three edges of triangle (’red’ refinement). Neighbouring triangles (which are
not marked for refinement get split in half (’green’ refinement). (R. Verfuerth, ”A review of a
posteriori error estimation and adaptive mesh refinement techniques”, Wiley-Teubner, 1996)
surfaceSplitByPatch
Writes regions of triSurface to separate files.
surfaceSplitByTopology
Strips any baffle parts of a surface. A baffle region is one which is reached by walking from an
open edge, and stopping when a multiply connected edge is reached.
surfaceSplitNonManifolds
Takes multiply connected surface and tries to split surface at multiply connected edges by
duplicating points. Introduces concept of - borderEdge. Edge with 4 faces connected to it.
- borderPoint. Point connected to exactly 2 borderEdges. - borderLine. Connected list
of borderEdges.
surfaceSubset
A surface analysis tool which sub-sets the triSurface to choose only a part of interest. Based
on subsetMesh.
surfaceToPatch
Reads surface and applies surface regioning to a mesh. Uses boundaryMesh to do the hard work.
surfaceTransformPoints
Automatically decomposes a mesh and fields of a case for parallel execution of OpenFOAM.
reconstructPar
Reconstructs fields of a case that is decomposed for parallel execution of OpenFOAM.
reconstructParMesh
Reconstructs a mesh using geometric information only.
redistributePar
Redistributes existing decomposed mesh and fields according to the current settings in
the decomposeParDict file.
Calculates the adiabatic flame temperature for a given fuel over a range of unburnt temperatures
and equivalence ratios.
chemkinToFoam
Converts CHEMKINIII thermodynamics and reaction data files into OpenFOAM format.
equilibriumCO
Calculates the equilibrium level of carbon monoxide.
equilibriumFlameT
Calculates the equilibrium flame temperature for a given fuel and pressure for a range of unburnt
gas temperatures and equivalence ratios; the effects of dissociation on O2, H2O and CO2 are
included.
mixtureAdiabaticFlameT
Calculates the adiabatic flame temperature for a given mixture at a given temperature.
foamFormatConvert
Converts all IOobjects associated with a case into the format specified in the controlDict.
foamListTimes
List times using timeSelector.
patchSummary
Writes fields and boundary condition info for each patch at each requested time instance.
Chapter 4 OpenFOAM cases
This chapter deals with the file structure and organisation of OpenFOAM cases. Normally, a user
would assign a name to a case, e.g. the tutorial case of flow in a cavity is simply named cavity.
This name becomes the name of a directory in which all the case files and subdirectories are
stored. The case directories themselves can be located anywhere but we recommend they are
within a run subdirectory of the user’s project directory, i.e. $HOME/OpenFOAM/${USER}-6 as
described at the beginning of chapter 2. One advantage of this is that
the $FOAM_RUN environment variable is set to $HOME/OpenFOAM/${USER}-6/run by default; the
user can quickly move to that directory by executing a preset alias, run, at the command line.
The tutorial cases that accompany the OpenFOAM distribution provide useful examples of the
case directory structures. The tutorials are located in the $FOAM_TUTORIALS directory, reached
quickly by executing the tut alias at the command line. Users can view tutorial examples at their
leisure while reading this chapter.
▪ Files have free form, with no particular meaning assigned to any column and no need to
indicate continuation across lines.
▪ Lines have no particular meaning except to a // comment delimiter which makes
OpenFOAM ignore any text that follows it until the end of line.
▪ A comment over multiple lines is done by enclosing the text between /* and */ delimiters.
4.2.2 Dictionaries
OpenFOAM uses dictionaries as the most common means of specifying data. A dictionary is an entity
that contains data entries that can be retrieved by the I/O by means of keywords. The keyword entries
follow the general format
<keyword> <dataEntry>;
Most OpenFOAM data files are themselves dictionaries containing a set of keyword entries. Dictionaries
provide the means for organising entries into logical categories and can be specified hierarchically so
that any dictionary can itself contain one or more dictionary entries. The format for a dictionary is to
specify the dictionary name followed by keyword entries enclosed in curly braces {} as follows.
<dictionaryName>
{
… keyword entries …
}
4.2.4 Lists
OpenFOAM applications contain lists, e.g. a list of vertex coordinates for a mesh description. Lists are
commonly found in I/O and have a format of their own in which the entries are contained within round
braces ( ). There is also a choice of format preceeding the round braces:
In OpenFOAM, a tensor is a VectorSpace of rank 2 and dimension 3 and therefore the data entries are
always fixed to 9 real numbers. Therefore the identity tensor can be written:
(
100
010
001
)
This example demonstrates the way in which OpenFOAM ignores the line return is so that the entry can
be written over multiple lines. It is treated no differently to listing the numbers on a single line:
(100010001)
The I/O format for a dimensionSet is 7 scalars delimited by square brackets, e.g.
[0 2 -1 0 0 0 0]
where each of the values corresponds to the power of each of the base units of measurement
listed in Table 4.1. The table gives the base units for the Syst�me International (SI) and the
United States Customary System (USCS) but OpenFOAM can be used with any system of units.
All that is required is that the input data is correct for the chosen set of units. It is particularly important
to recognise that OpenFOAM requires some dimensioned physical constants, e.g. the Universal
Gas Constant , for certain calculations, e.g. thermophysical modelling. These dimensioned
constants are specified in a DimensionedConstant sub-dictionary of main controlDict file of the
OpenFOAM installation ($WM_PROJECT_DIR/etc/controlDict). By default these constants are set
in SI units. Those wishing to use the USCS or any other system of units should modify these
constants to their chosen set of units accordingly.
4.2.7 Dimensioned types
Physical properties are typically specified with their associated dimensions. These entries formally have
the format that the following example of a dimensionedScalar demonstrates:
nu nu [0 2 -1 0 0 0 0] 1;
The first nu is the keyword; the second nu is the word name stored in class word, usually chosen to be
the same as the keyword; the next entry is the dimensionSet and the final entry is the scalar value.
The majority of dimensioned keyword lookups set a default for the word name which can
therefore be omitted from the entry, so the more common syntax is:
nu [0 2 -1 0 0 0 0] 1;
4.2.8 Fields
Much of the I/O data in OpenFOAM are tensor fields, e.g. velocity, pressure data, that are read from and
written into the time directories. OpenFOAM writes field data using keyword entries as described in
Table 4.2.
The data begins with an entry for its dimensions. Following that, is the internalField, described in
one of the following ways.
▪ Uniform field a single value is assigned to all elements within the field, taking the form:
internalField uniform <entry>;
▪ Nonuniform field each field element is assigned a unique value from a list, taking the
following form where the token identifier form of list is recommended:
internalField nonuniform <List>;
The boundaryField is a dictionary containing a set of entries whose names correspond to each of
the names of the boundary patches listed in the boundary file in the polyMesh directory. Each patch
entry is itself a dictionary containing a list of keyword entries. The mandatory entry, type,
describes the patch field condition specified for the field. The remaining entries correspond to
the type of patch field condition selected and can typically include field data specifying initial
conditions on patch faces. A selection of patch field conditions available in OpenFOAM are listed
in section 5.2.1, section 5.2.2 and section 5.2.3, with a description and the data that must be
specified with it. Example field dictionary entries for velocity U are shown below:
17dimensions [0 1 -1 0 0 0 0];
18
19internalField uniform (0 0 0);
20
21boundaryField
22{
23 movingWall
24 {
25 type fixedValue;
26 value uniform (1 0 0);
27 }
28
29 fixedWalls
30 {
31 type noSlip;
32 }
33
34 frontAndBack
35 {
36 type empty;
37 }
38}
39
40// ************************************************************************* //
a 10;
b $a;
subdict
{
a 10;
}
b $subdict.a;
▪ to traverse up one level of sub-dictionary, use the ‘.. ’ (double-dot) prefix, see below;
▪ to traverse up two levels use ‘... ’ (triple-dot) prefix, etc. ;
▪ to traverse to the top level dictionary use the ‘:’ (colon) prefix (most useful), see below;
▪ for multiple levels of macro substitution, each specified with the ‘$’ dollar syntax, ‘{}’
brackets are required to protect the expansion, see below.
a 10;
b a;
c ${${b}}; // returns 10, since $b returns "a", and $a returns 10
subdict
{
b $..a; // double-dot takes scope up 1 level, then "a" is available
subsubdict
{
c $:a; // colon takes scope to top level, then "a" is available
}
}
pressure 1e+05;
In order to use this pressure for both the internal and initial boundary fields, the user would simply
include the initialConditions file using the #include directive, then use macro expansions for
the pressure keyword, as follows.
#include "initialConditions"
internalField uniform $pressure;
boundaryField
{
patch1
{
type fixedValue;
value $internalField;
}
}
▪ #include "<path>/<fileName>": reads the file of name <fileName> from an absolute or relative
directory path <path>;
▪ #includeIfPresent "<path>/<fileName>": reads the file if it exists;
▪ #includeEtc "<path>/<fileName>": reads the file of name <fileName> from the directory
path <path>, relative to the $FOAM_ETC directory;
▪ #includeFunc <fileName>: reads the file of name <fileName>, searched from the case system
directory, followed by the $FOAM_ETC directory;
▪ #remove <keywordEntry>: removes any included keyword entry; can take a word or regular
expression;
4.2.11 Environment variables
OpenFOAM recognises the use of environment variables in input files. For example, the $FOAM_RUN
environment variable can be used to identify the run directory, as described in the introduction to
Chapter 2. This could be used to include a file, e.g. by
#include "$FOAM_RUN/pitzDaily/0/U"
In addition to environment variables like $FOAM_RUN, set within the operating system,
OpenFOAM recognises a number of “internal” environment variables, including the following.
▪ $FOAM_CASE: the path and directory of the running case.
▪ $FOAM_CASENAME: the directory name of the running case.
▪ $FOAM_APPLICATION: the name of the running application.
▪ "inlet.*" matches any word beginning inlet…, including inlet itself, because ‘. ’ denotes “any
character” and ‘*’ denotes “repeated any number of times, including 0 times”.
▪ "(inlet|output)" matches inlet and outlet because () specified an expression grouping and | is
an OR operator.
4.2.13 Keyword ordering
The order in which keywords are listed does not matter, except when the same keyword is specified
multiple times. Where the same keyword is duplicated, the last instance is used. The most common
example of a duplicate keyword occurs when a keyword is included from the file or expanded from a
macro, and then overridden. The example below demonstrates this, where pFinal adopts all the keyword
entries, including relTol 0.05 in the p sub-dictionary by the macro expansion $p, then overrides the relTol
entry.
p
{
solver PCG;
preconditioner DIC;
tolerance 1e-6;
relTol 0.05;
}
pFinal
{
$p;
relTol 0;
}
Where a data lookup matches both a keyword and a regular expression, the keyword match
takes precedence irrespective of the order of the entries.
The file contains several calculations that calculate vertex ordinates, e.g. y, z, etc. , from geometry
dimensions, e.g. radius. Calculations include standard C++ functions including unit
conversions, e.g. degToRad, and trigonometric functions, e.g. sin.
The #codeStream directive takes C++ code which is compiled and executed to deliver the
dictionary entry. The code and compilation instructions are specified through the following
keywords.
▪ code: specifies the code, called with arguments OStream& os and const dictionary& dict which
the user can use in the code, e.g. to lookup keyword entries from within the current case
dictionary (file).
▪ codeInclude (optional): specifies additional C++ #include statements to include OpenFOAM
files.
▪ codeOptions (optional): specifies any extra compilation flags to be added to EXE_INC
in Make/options.
▪ codeLibs (optional): specifies any extra compilation flags to be added to LIB_LIBS
in Make/options.
Code, like any string, can be written across multiple lines by enclosing it within hash-bracket
delimiters, i.e. #{…#}. Anything in between these two delimiters becomes a string with all
newlines, quotes, etc. preserved.
An example of #codeStream is given below, where the code in the calculates moment of inertia of
a box shaped geometry.
momentOfInertia #codeStream
{
codeInclude
#{
#include "diagTensor.H"
#};
code
#{
scalar sqrLx = sqr($Lx);
scalar sqrLy = sqr($Ly);
scalar sqrLz = sqr($Lz);
os <<
$mass
*diagTensor(sqrLy + sqrLz, sqrLx + sqrLz, sqrLx + sqrLy)/12.0;
#};
};
4.2.15 Conditionals
Input files support two conditional directives: #if…#else…#endif; and, #ifEq…#else…#endif. The #if
conditional reads a switch that can be generated by a #calc directive, e.g. :
angle 65;
laplacianSchemes
{
#if #calc "${angle} < 75"
default Gauss linear corrected;
#else
default Gauss linear limited corrected 0.5;
#endif
}
The #ifEq compares a word or string, and executes based on a match, e.g. :
ddtSchemes
{
#ifeq ${FOAM_APPLICATION} simpleFoam
default steadyState;
#else
default Euler;
#endif
}
The global controlDict file can be found in the installation within a directory named etc,
represented by the environment variable $FOAM_ETC. The file contains sub-dictionaries for the
following items.
▪ Documentation: for opening documentation in a web browser.
▪ InfoSwitches: controls information printed to standard output, i.e. the terminal.
▪ OptimisationSwitches: for parallel communication and I/O, see section 3.4.2.
▪ DebugSwitches: messaging switches to help debug code failures, as described in
section 3.2.6.
▪ DimensionedConstants: defines fundamental physical constants, e.g. Boltzmann’s
Constant.
▪ DimensionSets: defines a notation for dimensional units, e.g. kg.
foamEtcFile -list
The listed locations include a local $HOME/.OpenFOAM directory and follow a descending order of
precedence, i.e. the last location listed (etc) is lowest precedence.
If a user therefore wished to work permanently in USCS units, they could maintain a controlDict
file in their $HOME/.OpenFOAM directory that includes the following entry.
DimensionedConstants
{
unitSet USCS;
}
OpenFOAM would read the unitSet entry from this file, but read all other controlDict keyword
entries from the global controlDict file.
Alternatively, if a user wished to work on a single case in USCS units, they could add the same
entry into the controlDict file in the system directory for their case. This file is discussed in the next
section.
4.4 Time and data input/output control
The OpenFOAM solvers begin all runs by setting up a database. The database controls I/O and,
since output of data is usually requested at intervals of time during the run, time is an inextricable
part of the database. The controlDict dictionary sets input parameters essential for the creation of
the database. The keyword entries in controlDict are listed in the following sections. Only the time
control and writeInterval entries are mandatory, with the database using default values for any of
the optional entries that are omitted. Example entries from a controlDict dictionary are given
below:
17
18application icoFoam;
19
20startFrom startTime;
21
22startTime 0;
23
24stopAt endTime;
25
26endTime 0.5;
27
28deltaT 0.005;
29
30writeControl timeStep;
31
32writeInterval 20;
33
34purgeWrite 0;
35
36writeFormat ascii;
37
38writePrecision 6;
39
40writeCompression off;
41
42timeFormat general;
43
44timePrecision 6;
45
46runTimeModifiable true;
47
48
49// ************************************************************************* //
Integer representing a limit on the number of time directories that are stored by overwriting time
directories on a cyclic basis. For example, if the simulations starts at = 5s and = 1s, then
with purgeWrite 2;, data is first written into 2 directories, 6 and 7, then when 8 is written, 6 is
deleted, and so on so that only 2 new results directories exists at any time. To disable the purging,
specify purgeWrite 0; (default).
writeFormat
Switch to specify whether files are compressed with gzip when written: on/off (yes/no, true/false)
timeFormat
Switch for whether dictionaries, e.g. controlDict, are re-read during a simulation at the beginning
of each time step, allowing the user to modify parameters during a simulation.
libs
functions
The example shows that the fvSchemes dictionary contains 6 …Schemes subdictionaries
containing keyword entries for each term specified within including: a default entry; other entries
whose names correspond to a word identifier for the particular term specified, e.g. grad(p)
for If a default scheme is specified in a particular …Schemes sub-dictionary, it is assigned to
all of the terms to which the sub-dictionary refers, e.g. specifying a default in gradSchemes sets the
scheme for all gradient terms in the application, e.g. , . When a default is specified, it is
not necessary to specify each specific term itself in that sub-dictionary, i.e. the entries
for grad(p), grad(U) in this example. However, if any of these terms are included, the specified
scheme overrides the default scheme for that term.
Alternatively the user can specify that no default scheme by the none entry, as in the divSchemes
in the example above. In this instance the user is obliged to specify all terms in that sub-
dictionary individually. Setting default to none may appear superfluous since default can be
overridden. However, specifying none forces the user to specify all terms individually which can
be useful to remind the user which terms are actually present in the application.
OpenFOAM includes a vast number of discretisation schemes, from which only a few are
typically recommended for real-world, engineering applications. The user can get help with
scheme selection by interrogating the tutorial cases for example scheme settings. They should
look at the schemes used in relevant cases, e.g. for running a large-eddy simulation (LES), look
at schemes used in tutorials running LES. Additionally, foamSearch provides a useful tool to get
a quick list of schemes used in all the tutorials. For example, to print all the default entries
for ddtSchemes for cases in the $FOAM_TUTORIALS directory, the user can type:
which prints:
default backward;
default CrankNicolson 0.9;
default Euler;
default localEuler;
default none;
default steadyState;
The schemes listed using foamSearch are described in the following sections.
The Gauss entry specifies the standard finite volume discretisation of Gaussian integration which requires
the interpolation of values from cell centres to face centres. The interpolation scheme is then given by
the linear entry, meaning linear interpolation or central differencing.
In some tutorials cases, particular involving poorer quality meshes, the discretisation of specific
gradient terms is overridden to improve boundedness and stability. The terms that are
overridden in those cases are the velocity gradient
They use the cellLimited scheme which limits the gradient such that when cell values are extrapolated to
faces using the calculated gradient, the face values do not fall outside the bounds of values in surrounding
cells. A limiting coefficient is specified after the underlying scheme for which 1 guarantees boundedness
and 0 applies no limiting; 1 is invariably used.
▪ leastSquares: a second-order, least squares distance calculation using all neighbour cells.
▪ Gauss cubic: third-order scheme that appears in the dnsFoam simulation on a regular mesh.
4.5.3 Divergence schemes
The divSchemes sub-dictionary contains divergence terms, i.e. terms of the form …, excluding
Laplacian terms (of the form ). This includes both advection terms, e.g. ,
where velocity provides the advective flux, and other terms, that are often diffusive in
nature, e.g. .
The fact that terms that are fundamentally different reside in one sub-dictionary means that
the default scheme in generally set to none in divSchemes. The non-advective terms then generally
use the Gauss integration with linear interpolation, e.g.
The treatment of advective terms is one of the major challenges in CFD numerics and so the
options are more extensive. The keyword identifier for the advective terms are usually of the
form div(phi,…), where phi generally denotes the (volumetric) flux of velocity on the cell faces for
constant-density flows and the mass flux for compressible flows, e.g. div(phi,U) for the advection
of velocity, div(phi,e) for the advection of internal energy, div(phi,k) for turbulent kinetic energy, etc.
For advection of velocity, the user can run the foamSearch script to extract the div(phi,U) keyword
from all tutorials.
The schemes are all based on Gauss integration, using the flux phi and the advected field being
interpolated to the cell faces by one of a selection of schemes, e.g. linear, linearUpwind, etc. There is
a bounded variant of the discretisation, discussed later.
Ignoring ‘V’-schemes (with keywords ending “V”), and rarely-used schemes such as Gauss cubic
and vanLeerV, the interpolation schemes used in the tutorials are as follows.
▪ linear: second order, unbounded.
▪ linearUpwind: second order, upwind-biased, unbounded (but much less so than linear), that
requires discretisation of the velocity gradient to be specified.
▪ LUST: blended 75% linear/ 25%linearUpwind scheme, that requires discretisation of the
velocity gradient to be specified.
▪ limitedLinear: linear scheme that limits towards upwind in regions of rapidly changing
gradient; requires a coefficient, where 1 is strongest limiting, tending towards linear as the
coefficient tends to 0.
▪ upwind: first-order bounded, generally too inaccurate to be recommended.
Example syntax for these schemes is as follows.
‘V’-schemes are specialised versions of schemes designed for vector fields. They differ from
conventional schemes by calculating a single limiter which is applied to all components of the vectors,
rather than calculating separate limiters for each component of the vector. The ‘V’-schemes’ single limiter
is calculated based on the direction of most rapidly changing gradient, resulting in the strongest limiter
being calculated which is most stable but arguably less accurate. Example syntax is as follows.
The bounded variants of schemes relate to the treatment of the material time derivative which
can be expressed in terms of a spatial time derivative and convection, e.g. for field in
incompressible flow
(4.1)
For numerical solution of incompressible flows, at convergence, at which point the third term
on the right hand side is zero. Before convergence is reached, however, and in some
circumstances, particularly steady-state simulations, it is better to include the third term within a numerical
solution because it helps maintain boundedness of the solution variable and promotes better
convergence. The bounded variant of the Gauss scheme provides this, automatically including the
discretisation of the third-term with the advection term. Example syntax is as follows, as seen
in fvSchemes files for steady-state cases, e.g. for the simpleFoam tutorials
The schemes used for advection of scalar fields are similar to those for advection of velocity,
although in general there is greater emphasis placed on boundedness than accuracy when
selecting the schemes. For example, a search for schemes for advection of internal energy (e)
reveals the following.
In comparison with advection of velocity, there are no cases set up to use linear or linearUpwind. Instead
the limitedLinear and upwind schemes are commonly used, with the additional appearance of vanLeer,
another limited scheme, with less strong limiting than limitedLinear.
There are specialised versions of the limited schemes for scalar fields that are commonly
bounded between 0 and 1, e.g. the laminar flame speed regress variable . A search for the
discretisation used for advection in the laminar flame transport equation yields:
The underlying scheme is limitedLinear, specialised for stronger bounding between 0 and 1 by adding 01
to the name of the scheme.
The multivariateSelection mechanism also exists for grouping multiple equation terms together,
and applying the same limiters on all terms, using the strongest limiter calculated for all terms.
A good example of this is in a set of mass transport equations for fluid species, where it is good
practice to apply the same discretisation to all equations for consistency. The example below
comes from the smallPoolFire3D tutorial in $FOAM_TUTORIALS/combustion/fireFoam/les, in which the
equation for enthalpy is included with the specie mass transport equations in the calculation
of a single limiter.
default corrected;
default limited corrected 0.33;
default limited corrected 0.5;
default orthogonal;
default uncorrected;
The basis of the gradient calculation at a face is to subtract the value at the cell centre on one
side of the face from the value in the centre on the other side and divide by the distance. The
calculation is second-order accurate for the gradient normal to the face if the vector connecting the
cell centres is orthogonal to the face, i.e. they are at right-angles. This is the orthogonal scheme.
Orthogonality requires a regular mesh, typically aligned with the Cartesian co-ordinate system,
which does not normally occur in meshes for real world, engineering geometries. Therefore, to
maintain second-order accuracy, an explicit non-orthogonal correction can be added to the
orthogonal component, known as the corrected scheme. The correction increases in size as the
non-orthogonality, the angle between the cell-cell vector and face normal vector, increases.
As tends towards 90 , e.g. beyond 70 , the explicit correction can be so large to cause a
solution to go unstable. The solution can be stabilised by applying the limited scheme to the
correction which requires a coefficient where
(4.2)
Typically, is chosen to be 0.33 or 0.5, where 0.33 offers greater stability and 0.5 greater accuracy.
The corrected scheme applies under-relaxation in which the implicit orthogonal calculation is
increased by , with an equivalent boost within the non-orthogonal correction.
The uncorrected scheme is equivalent to the corrected scheme, without the non-orthogonal
correction, so includes is like orthogonal but with the under-relaxation.
Generally the uncorrected and orthogonal schemes are only recommended for meshes with very
low non-orthogonality (e.g. maximum 5 ). The corrected scheme is generally recommended, but
for maximum non-orthogonality above 70 , limited may be required. At non-orthogonality above
80 , convergence is generally hard to achieve.
4.5.5 Laplacian schemes
The laplacianSchemes sub-dictionary contains Laplacian terms. A typical Laplacian term
is , the diffusion term in the momentum equations, which corresponds to the
keyword laplacian(nu,U) in laplacianSchemes. The Gauss scheme is the only choice of discretisation
and requires a selection of both an interpolation scheme for the diffusion coefficient, i.e. in our
example, and a surface normal gradient scheme, i.e. . To summarise, the entries required
are:
The user can search for the default scheme for laplacianSchemes in all the cases in
the $FOAM_TUTORIALS directory.
In all cases, the linear interpolation scheme is used for interpolation of the diffusivity. The cases uses the
same array of snGradSchemes based on level on non-orthogonality, as described in section 4.5.4.
fvSolution contains a set of subdictionaries, described in the remainder of this section that
includes: solvers; relaxationFactors; and, PISO, SIMPLE or PIMPLE.
p
{
solver PCG;
preconditioner DIC;
tolerance 1e-06;
relTol 0.05;
}
pFinal
{
$p;
relTol 0;
}
If the case is specified to solve pressure 4 times within one time step, then the first 3 solutions would use
the settings for p with relTol of 0.05, so that the cost of solving each equation is relatively low. Only when
the equation is solved the final (4th) time, it solves to a residual level specified by tolerance (since relTol
is 0, effectively deactivating it) for greater accuracy, but at greater cost.
The agglomeration of cells is performed by the method specified by the agglomerator keyword.
The tutorials all use the default faceAreaPair method, although the MGridGen option is an
alternative method that requires an additional entry specifying the shared object library
for MGridGen:
geometricGamgAgglomerationLibs ("libMGridGenGamgAgglomeration.so");
The agglomeration can be controlled using the following optional entries, most of which default in the
tutorials.
Relaxation factors for under-relaxation of fields are specified within a field sub-dictionary;
relaxation factors for equation under-relaxation are within a equations sub-dictionary. An example
is shown below from tutorial example of simpleFoam, showing typical settings for an
incompressible steady-state solver. The factors are specified for pressure p, pressure U, and
turbulent fields grouped using a regular expression.
54
55relaxationFactors
56{
57 fields
58 {
59 p 0.3;
60 }
61 equations
62 {
63 U 0.7;
64 "(k|omega|epsilon).*" 0.7;
65 }
66}
67
68// ************************************************************************* //
Another example for pimpleFoam, a transient incompressible solver, just uses under-relaxation to
ensure matrix diagonal equality, typical of transient simulations.
60
61relaxationFactors
62{
63 equations
64 {
65 ".*" 1;
66 }
67}
68
69
70// ************************************************************************* //
While all the algorithms solve the same governing equations (albeit in different forms), the
algorithms principally differ in how they loop over the equations. The looping is controlled by
input parameters that are listed below. They are set in a dictionary named after the
algorithm, i.e. SIMPLE, PISO or PIMPLE.
▪ nCorrectors: used by PISO, and PIMPLE, sets the number of times the algorithm solves
the pressure equation and momentum corrector in each step; typically set to 2 or 3.
▪ nNonOrthogonalCorrectors: used by all algorithms, specifies repeated solutions of the
pressure equation, used to update the explicit non-orthogonal correction, described in
section 4.5.4, of the Laplacian term ; typically set to 0 (particularly for
steady-state) or 1.
▪ nOuterCorrectors: used by PIMPLE, it enables looping over the entire system of equations
within on time step, representing the total number of times the system is solved; must
be and is typically set to 1, replicating the PISO algorithm.
▪ momentumPredictor: switch that controls solving of the momentum predictor; typically set
to off for some flows, including low Reynolds number and multiphase.
4.6.4 Pressure referencing
In a closed incompressible system, pressure is relative: it is the pressure range that matters not
the absolute values. In these cases, the solver sets a reference level of pRefValue in cell pRefCell.
These entries are generally stored in the SIMPLE, PISO or PIMPLE sub-dictionary and are used
by those solvers that require them when the case demands it.
4.6.5 Other parameters
The fvSolutions dictionaries in the majority of standard OpenFOAM solver applications contain no
other entries than those described so far in this section. However, in general the fvSolution
dictionary may contain any parameters to control the solvers, algorithms, or in fact anything. If
any parameter or sub-dictionary is missing when an solver is run, it will terminate, printing a
detailed error message. The user can then add missing parameters accordingly.
4.7 Case management tools
There are a set of applications and scripts that help with managing case files and help the user
find and set keyword data entries in case files. The tools are described in the following sections.
lists the time directories for a case, omitting the 0 directory by default; the -rm option deletes the
listed time directories, so that a case can be cleaned of time directories with results by the
following command.
foamListTimes -rm
foamCloneCase
creates a new case, by copying the 0, system and constant directories from an existing case;
executed simply by the following command, where oldCase refers to an existing case directory.
foamCloneCase oldCase newCase
foamCleanPolyMesh
deletes mesh files for a case; useful to execute before regenerating a mesh, particularly
with snappyHexMesh which generates refinement history and other files that might need to be
removed when re-meshing.
foamDictionary system/fvSchemes
Without options, the utility lists all the keyword entries in the file, e.g. as follows for the fvSchemes file in
the pitzDaily tutorial case for simpleFoam.
{
FoamFile
{
version 2;
format ascii;
class dictionary;
location "system";
object fvSchemes;
}
ddtSchemes
{
default steadyState;
}
gradSchemes
{
default Gauss linear;
}
divSchemes
{
default none;
div(phi,U) bounded Gauss linearUpwind grad(U);
div(phi,k) bounded Gauss limitedLinear 1;
div(phi,epsilon) bounded Gauss limitedLinear 1;
div(phi,omega) bounded Gauss limitedLinear 1;
div(phi,v2) bounded Gauss limitedLinear 1;
div((nuEff*dev2(T(grad(U))))) Gauss linear;
div(nonlinearStress) Gauss linear;
}
laplacianSchemes
{
default Gauss linear corrected;
}
interpolationSchemes
{
default linear;
}
snGradSchemes
{
default corrected;
}
wallDist
{
method meshWave;
}
}
The -entry option allows the user to print the entry for a particular keyword, e.g. divSchemes in the
example below
The “. ” syntax allows access to keywords with levels of sub-dictionary. For example,
the div(phi,U) keyword can be accessed within the divSchemes sub-dictionary by the following
command.
The example removes the keyword and terminating semicolon, leaving just the data.
bounded Gauss linearUpwind grad(U)
The example removes the keyword and terminating semicolon, leaving just the data.
bounded Gauss linearUpwind grad(U)
foamDictionary can set entries with the -set option. If the user wishes to change the div(phi,U) to the
upwind scheme, they can enter the following.
foamDictionary can add entries with the -add option. If the user wishes to add an entry named turbulence
to divSchemes with the upwind scheme, they can enter the following.
The foamSearch script, demonstrated extensively in section 4.5, uses foamDictionary functionality
to extract and sort keyword entries from all files of a specified name in a specified dictionary.
The -c option counts the number of entries of each type, e.g. the user could searche for the
choice of solver for the p equation in all the fvSolution files in the tutorials.
The search shows GAMG to be the most common choice in all the tutorials.
59 solver GAMG;
3 solver PBiCG;
18 solver PCG;
5 solver smoothSolver;
run
cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily .
cd pitzDaily
The mesh is generated for the case by going into the case directory and running blockMesh:
cd pitzDaily
blockMesh
The user might decide before running the simulation to configure some automatic post-processing as
described in Section 6.2. For example, the user can list the pre-configured function objects by the
following command:
postProcess -list
From the output, the user could select the flowRatePatch function to monitor the flow rate at the outlet
patch. The flowRatePatch configuration file can be copied into the system directory using foamGet:
foamGet flowRatePatch
The user is presented with both flowRatePatch and flowRatePatch.cfg. The user should select the option
to copy flowRatePatch and the file is copied into the case system directory. In order to monitor the flow
through the outlet patch, the name entry in flowRatePatch file should be set as follows:
name outlet;
The flowRatePatch configuration is then included in the case by adding to the functions sub-dictionary in
the controlDict file:
functions
{
#includeFunc streamlines
#includeFunc flowRatePatch
}
foamInfo simpleFoam
Information for the flowRateInletVelocity boundary condition can similarly be obtained by typing the
following:
foamInfo flowRateInletVelocity
The output includes: the location of the source code header file for this boundary condition; the description
and usage details from the header file; and, a list of example cases that use the boundary condition.
The example usage for volumetric flow rate can be copied to replace the inlet boundary condition
in the pitzDaily example from Section 4.7.3. The volumetric flow rate, equivalent to a uniform flow
speed of 10 m/s, is so the modified inlet patch entry in the U file in the 0
directory should be:
inlet
{
type flowRateInletVelocity;
volumetricFlowRate 2.54e-4;
extrapolateProfile yes;
value uniform (0 0 0);
}
The simpleFoam solver can then be run. The solution at convergence (around 280 steps),
visualised in ParaView, shows a nonuniform velocity profile at the inlet, due to the extrapolateProfile
being switched on. The flow rate at the outlet, from the function object set up in Section 4.7.3, is
written to a surfaceFieldValue.dat file in the postProcessing/flowRatePatch/0 directory. The value
converges towards the inlet flow rate.
Chapter 5 Mesh generation and conversion
This chapter describes all topics relating to the creation of meshes in OpenFOAM:
section 5.1 gives an overview of the ways a mesh may be described in OpenFOAM;
section 5.3 covers the blockMesh utility for generating simple meshes of blocks of hexahedral
cells; section 5.4 covers the snappyHexMesh utility for generating complex meshes of hexahedral
and split-hexahedral cells automatically from triangulated surface geometries;
section 5.5 describes the options available for conversion of a mesh that has been generated
by a third-party product into a format that OpenFOAM can read.
5.1 Mesh description
This section provides a specification of the way the OpenFOAM C++ classes handle a mesh.
The mesh is an integral part of the numerical solution and must satisfy certain criteria to ensure
a valid, and hence accurate, solution. During any run, OpenFOAM checks that the mesh satisfies
a fairly stringent set of validity constraints and will cease running if the constraints are not
satisfied.
By default OpenFOAM defines a mesh of arbitrary polyhedral cells in 3-D, bounded by arbitrary
polygonal faces, i.e. the cells can have an unlimited number of faces where, for each face, there
is no limit on the number of edges nor any restriction on its alignment. A mesh with this general
structure is known in OpenFOAM as a polyMesh. This type of mesh offers great freedom in mesh
generation and manipulation in particular when the geometry of the domain is complex or
changes over time.
5.1.1 Mesh specification and validity constraints
Before describing the OpenFOAM mesh format, we will first set out the validity constraints used
in OpenFOAM. The conditions that a mesh must satisfy are:
5.1.1.1 Points
A point is a location in 3-D space, defined by a vector in units of metres ( ). The points are
compiled into a list and each point is referred to by a label, which represents its position in the
list, starting from zero. The point list cannot contain two different points at an exactly identical position nor
any point that is not part at least one face.
5.1.1.2 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, i.e. you
follow points as you travel around the circumference of the face. 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, i.e. looking towards a face, if the numbering
of the points follows an anti-clockwise path, the normal vector points towards you, as shown in
Figure 5.1.
Figure 5.1: Face area vector from point numbering on the face
Internal faces
Those faces that connect two cells (and it can never be more than two). For each internal face,
the ordering of the point labels is such that the face normal points into the cell with the larger
label, i.e. for cells 2 and 5, the normal points into 5;
Boundary faces
Those belonging to one cell 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.
Faces are generally expected to be convex; at the very least the face centre needs to be inside
the face. Faces are allowed to be warped, i.e. not all points of the face need to be coplanar.
5.1.1.3 Cells
A cell is a list of faces in arbitrary order. Cells must have the properties listed below.
Contiguous
The cells must completely cover the computational domain and must not overlap one another.
Convex
Every cell must be convex and its cell centre inside the cell.
Closed
Every cell must be closed, both geometrically and topologically where:
▪ geometrical closedness requires that when all face area vectors are oriented to
point outwards of the cell, their sum should equal the zero vector to machine
accuracy;
▪ topological closedness requires that all the edges in a cell are used by exactly two
faces of the cell in question.
5.1.1.4 Boundary
A boundary is a list of patches, each of which is associated with a boundary condition. A patch
is a list of face labels which clearly must contain only boundary faces and no internal faces. The
boundary is required to be closed, i.e. the sum all boundary face area vectors equates to zero to
machine tolerance.
5.1.2 The polyMesh description
The constant directory contains a full description of the case polyMesh in a subdirectory polyMesh.
The polyMesh description is based around faces and, as already discussed, internal faces
connect 2 cells and boundary faces address a cell and a boundary patch. Each face is therefore
assigned an ‘owner’ cell and ‘neighbour’ cell so that the connectivity across a given face can
simply be described by the owner and neighbour cell labels. In the case of boundaries, the
connected cell is the owner and the neighbour is assigned the label ‘-1’. With this in mind, the
I/O specification consists of the following files:
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. ;
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. ;
owner
a list of owner cell labels, the index of entry relating directly to the index of the face, so that the
first entry in the list is the owner label for face 0, the second entry is the owner label for face 1,
etc;
neighbour
a list of neighbour cell labels;
boundary
a list of patches, containing a dictionary entry for each patch, declared using the patch name, e.g.
movingWall
{
type patch;
nFaces 20;
startFace 760;
}
The startFace is the index into the face list of the first face in the patch, and nFaces is the number
of faces in the patch.
5.1.3 Cell shapes
While OpenFOAM supports any shapes of cell, other tools and software generally do not.
Therefore conversion of meshes to and from OpenFOAM format often requires the use of
defined cell shapes, such as tetrahedra, hexahedra, etc. The functionality is available in
a cellShape class that uses a set of shapes defined in a cellModels file in the $FOAM_ETC directory.
Cells of a given shape are then defined by the ordering of point labels in accordance with the
numbering scheme contained in the shape model. For reference, the ordering schemes for
points, faces and edges are shown in Table 5.2. Any cell description then consists of two parts:
the name of a cell model and the ordered list of labels. Thus, using the following list of points
(
(0 0 0)
(1 0 0)
(1 1 0)
(0 1 0)
(0 0 0.5)
(1 0 0.5)
(1 1 0.5)
(0 1 0.5)
)
This forms the basis for the input syntax for the blockMesh mesh generator, described in section 5.3.
The user can scan the tutorials for mesh generation configuration files, e.g. blockMeshDict
for blockMesh (see section 5.3) and snappyHexMeshDict for snappyHexMesh (see section 5.4, for
examples of different types being used. The following example provides documentation and lists
cases that use the symmetryPlane condition.
foamInfo -a symmetryPlane
The next example searches for snappyHexMeshDict files that specify the wall condition.
Every patch includes a type entry that specifies the type of boundary condition. They range from
a basic fixedValue condition applied to the inlet, to a complex waveTransmissive condition applied
to the outlet. The patches with non-generic types, e.g. symmetryPlane, defined in boundary, use
consistent boundary condition types in the p file.
The main basic boundary condition types available in OpenFOAM are summarised below using
a patch field named . This is not a complete list; for all types
see $FOAM_SRC/finiteVolume/fields/fvPatchFields/basic.
▪ fixedValue: value of is specified by value.
▪ fixedGradient: normal gradient of ( ) is specified by gradient.
These produce long lists which the user can scan through. If the user wants more information of a
particular condition, they can run the foamInfo script which provides a description of the boundary
condition and lists example cases where it is used. For example, for the totalPressure boundary condition,
run the following.
foamInfo totalPressure
In the following sections we will highlight some particular important, commonly used boundary conditions.
where the user specifies through the p0 keyword. The pressureInletOutletVelocity condition
specifies zeroGradient at all times, except on the tangential component which is set to fixedValue for
inflow, with the tangentialVelocity defaulting to 0.
The idea behind this combination is that the condition is a standard combination in the case of
outflow, but for inflow the normal velocity is allowed to find its own value. Under these
circumstances, a rapid rise in velocity presents a risk of instability, but the rise is moderated by
the reduction of inlet pressure, and hence driving pressure gradient, as the inflow velocity
increases.
The specification of these boundary conditions in the U and p_rgh files, in the damBreak case, are
shown below.
17
18dimensions [0 1 -1 0 0 0 0];
19
20internalField uniform (0 0 0);
21
22boundaryField
23{
24 leftWall
25 {
26 type noSlip;
27 }
28 rightWall
29 {
30 type noSlip;
31 }
32 lowerWall
33 {
34 type noSlip;
35 }
36 atmosphere
37 {
38 type pressureInletOutletVelocity;
39 value uniform (0 0 0);
40 }
41 defaultFaces
42 {
43 type empty;
44 }
45}
46
47
48// ************************************************************************* //
17dimensions [1 -1 -2 0 0 0 0];
18
19internalField uniform 0;
20
21boundaryField
22{
23 leftWall
24 {
25 type fixedFluxPressure;
26 value uniform 0;
27 }
28
29 rightWall
30 {
31 type fixedFluxPressure;
32 value uniform 0;
33 }
34
35 lowerWall
36 {
37 type fixedFluxPressure;
38 value uniform 0;
39 }
40
41 atmosphere
42 {
43 type totalPressure;
44 p0 uniform 0;
45 }
46
47 defaultFaces
48 {
49 type empty;
50 }
51}
52
53// ************************************************************************* //
They include conditions such as uniformFixedValue, which is a fixedValue condition which applies a single
value which is a function of time through a uniformValue keyword entry.
The Function1 is specified by a keyword following the uniformValue entry, followed by parameters
that relate to the particular function. The Function1 options are list below.
▪ constant: constant value.
▪ table: inline list of (time value) pairs; interpolates values linearly between times.
▪ tableFile: as above, but with data supplied in a separate file.
▪ square: square-wave function.
▪ sine: sine function.
▪ one and zero: constant one and zero values.
▪ polynomial: polynomial function using a list (coeff exponent) pairs.
▪ coded: function specified by user coding.
▪ scale: scales a given value function by a scalar scale function; both entries can be
themselves Function1; scale function is often a ramp function (below), with value controlling
the ramp value.
▪ linearRamp, quadraticRamp, halfCosineRamp, quarterCosineRamp and quarterSineRamp:
monotonic ramp functions which ramp from 0 to 1 over specified duration.
▪ reverseRamp: reverses the values of a ramp function, e.g. from 1 to 0.
Examples or a time-varying inlet for a scalar are shown below.
inlet
{
type uniformFixedValue;
uniformValue constant 2;
}
inlet
{
type uniformFixedValue;
uniformValue table ((0 0) (10 2));
}
inlet
{
type uniformFixedValue;
uniformValue polynomial ((1 0) (2 2)); // = 1*t^0 + 2*t^2
}
inlet
{
type uniformFixedValue;
uniformValue
{
type tableFile;
format csv;
nHeaderLine 4; // number of header lines
refColumn 0; // time column index
componentColumns (1); // data column index
separator ","; // optional (defaults to ",")
mergeSeparators no; // merge multiple separators
file "dataTable.csv";
}
}
inlet
{
type uniformFixedValue;
uniformValue
{
type square;
frequency 10;
amplitude 1;
scale 2; // Scale factor for wave
level 1; // Offset
}
}
inlet
{
type uniformFixedValue;
uniformValue
{
type sine;
frequency 10;
amplitude 1;
scale 2; // Scale factor for wave
level 1; // Offset
}
}
inlet
{
type uniformFixedValue;
uniformValue coded;
name pulse;
codeInclude
#{
#include "mathematicalConstants.H"
#};
code
#{
return scalar
(
0.5*(1 - cos(constant::mathematical::twoPi*min(x/0.3, 1)))
);
#};
}
The mesh is generated from a dictionary file named blockMeshDict located in the system
(or constant/polyMesh) directory of a case. blockMesh reads this dictionary, generates the mesh
and writes out the mesh data to points and faces, cells and boundary files in the same directory.
The principle behind blockMesh is to decompose the domain geometry into a set of 1 or more
three dimensional, hexahedral blocks. Edges of the blocks can be straight lines, arcs or splines.
The mesh is ostensibly specified as a number of cells in each direction of the block, sufficient
information for blockMesh to generate the mesh data.
Each block of the geometry is defined by 8 vertices, one at each corner of a hexahedron. The
vertices are written in a list so that each vertex can be accessed using its label, remembering
that OpenFOAM always uses the C++ convention that the first element of the list has label ‘0’.
An example block is shown in Figure 5.4 with each vertex numbered according to the list. The
edge connecting vertices 1 and 5 is curved to remind the reader that curved edges can be
specified in blockMesh.
It is possible to generate blocks with less than 8 vertices by collapsing one or more pairs of
vertices on top of each other, as described in section 5.3.5.
Each block has a local coordinate system that must be right-handed. A right-handed
set of axes is defined such that to an observer looking down the axis, with nearest them,
the arc from a point on the axis to a point on the axis is in a clockwise sense.
The local coordinate system is defined by the order in which the vertices are presented in the
block definition according to:
▪ the axis origin is the first entry in the block definition, vertex 0 in our example;
▪ the direction is described by moving from vertex 0 to vertex 1;
▪ the direction is described by moving from vertex 1 to vertex 2;
▪ vertices 0, 1, 2, 3 define the plane ;
▪ vertex 4 is found by moving from vertex 0 in the direction;
▪ vertices 5,6 and 7 are similarly found by moving in the direction from vertices 1,2 and
3 respectively.
edges
Used to arc 1 4 (0.939 0.342 -0.5)
describe arc or spline edges
hex (0 1 2 3 4
5 6 7)
Ordered list of vertex labels
block and mesh size (10 10 1)
simpleGrading
(1.0 1.0 1.0)
symmetryPlane base
List of patches ( (0 1 2 3) )
patches
convertToMeters 0.001;
means that all coordinates are multiplied by 0.001, i.e. the values quoted in the blockMeshDict file are
in .
vertices
(
( 0 0 0 ) // vertex number 0
( 1 0 0.1) // vertex number 1
( 1.1 1 0.1) // vertex number 2
( 0 1 0.1) // vertex number 3
(-0.1 -0.1 1 ) // vertex number 4
( 1.3 0 1.2) // vertex number 5
( 1.4 1.1 1.3) // vertex number 6
( 0 1 1.1) // vertex number 7
);
5.3.1.2 The edges
Each edge joining 2 vertex points is assumed to be straight by default. However any edge may
be specified to be curved by entries in a list named edges. The list is optional; if the geometry
contains no curved edges, it may be omitted.
Each entry for a curved edge begins with a keyword specifying the type of curve from those
listed in Table 5.2.
Keyword selection Description Additional entries
The keyword is then followed by the labels of the 2 vertices that the edge connects. Following
that, interpolation points must be specified through which the edge passes. For an arc, either of
the following is required: a single interpolation point, which the circular arc will intersect; or an
angle and rotation axis for the arc. For spline, polyLine and BSpline, a list of interpolation points is
required. The line edge is directly equivalent to the option executed by default, and requires no
interpolation points. Note that there is no need to use the line edge but it is included for
completeness. For our example block in Figure 5.4 we specify an arc edge connecting vertices
1 and 5 as follows through the interpolation point :
edges
(
arc 1 5 (1.1 0.0 0.5)
);
For the angle and axis specification of an arc, the syntax is of the form:
edges
(
arc 1 5 25 (0 1 0) // 25 degrees, y-normal
);
blocks
(
hex (0 1 2 3 4 5 6 7) // vertex numbers
(10 10 10) // numbers of cells in each direction
simpleGrading (1 2 3) // cell expansion ratios
);
Vertex numbering
The first entry is the shape identifier of the block, as defined in the $FOAM_ETC-6/cellModels file.
The shape is always hex since the blocks are always hexahedra. There follows a list of vertex
numbers, ordered in the manner described on page 337.
Number of cells
The second entry gives the number of cells in each of the and directions for that block.
simpleGrading
The simple description specifies uniform expansions in the local , and directions
respectively with only 3 expansion ratios, e.g.
simpleGrading (1 2 3)
edgeGrading
The full cell expansion description gives a ratio for each edge of the block, numbered according
to the scheme shown in Figure 5.4 with the arrows representing the direction from first cell…to
last cell e.g.
edgeGrading (1 1 1 1 2 2 2 2 3 3 3 3)
This means the ratio of cell widths along edges 0-3 is 1, along edges 4-7 is 2 and along 8-11 is 3
and is directly equivalent to the simpleGrading example given above.
OpenFOAM v2.4+ includes multi-grading functionality that can divide a block in an given
direction and apply different grading within each division. This multi-grading is specified by
replacing any single value expansion ratio in the grading specification of the block, e.g. “1”, “2”,
“3” in
blocks
(
hex (0 1 2 3 4 5 6 7) (100 300 100)
simpleGrading (1 2 3);
);
▪ split the block into 3 divisions in the -direction, representing 20%, 60% and 20% of the
block length;
▪ include 30% of the total cells in the y-direction (300) in each divisions 1 and 3 and the
remaining 40% in division 2;
▪ apply 1:4 expansion in divisions 1 and 3, and zero expansion in division 2.
We can specify this by replacing the -direction expansion ratio “2” in the example above with
the following:
blocks
(
hex (0 1 2 3 4 5 6 7) (100 300 100)
simpleGrading
(
1 // x-direction expansion ratio
(
(0.2 0.3 4) // 20% y-dir, 30% cells, expansion = 4
(0.6 0.4 1) // 60% y-dir, 40% cells, expansion = 1
(0.2 0.3 0.25) // 20% y-dir, 30% cells, expansion = 0.25 (1/4)
)
3 // z-direction expansion ratio
)
);
Both the fraction of the block and the fraction of the cells are normalized automatically. They can
be specified as percentages, fractions, absolute lengths, etc. and do not need to sum to 100,
1, etc. The example above can be specified using percentages, e.g.
blocks
(
hex (0 1 2 3 4 5 6 7) (100 300 100)
simpleGrading
(
1
(
(20 30 4) // 20%, 30%...
(60 40 1)
(20 30 0.25)
)
3
)
);
Returning to the example block in Figure 5.4, if it has an inlet on the left face, an output on the
right face and the four other faces are walls then the patches could be defined as follows:
boundary // keyword
(
inlet // patch name
{
type patch; // patch type for patch 0
faces
(
(0 4 7 3) // block face in this patch
);
} // end of 0th patch definition
outlet // patch name
{
type patch; // patch type for patch 1
faces
(
(1 2 6 5)
);
}
walls
{
type wall;
faces
(
(0 1 5 4)
(0 3 2 1)
(3 7 6 2)
(4 5 6 7)
);
}
);
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.
When specifying a cyclic patch in blockMesh, the user must specify the name of the related cyclic
patch through the neighbourPatch keyword. For example, a pair of cyclic patches might be
specified as follows:
left
{
type cyclic;
neighbourPatch right;
faces ((0 4 7 3));
}
right
{
type cyclic;
neighbourPatch left;
faces ((1 5 6 2));
}
face matching
the set of faces that comprise a patch from one block are formed from the same set of vertices
as a set of faces patch that comprise a patch from another block;
face merging
a group of faces from a patch from one block are connected to another group of faces from a
patch from another block, to create a new set of internal faces connecting the two blocks.
To connect two blocks with face matching, the two patches that form the connection should
simply be ignored from the patches list. blockMesh then identifies that the faces do not form an
external boundary and combines each collocated pair into a single internal faces that connects
cells from the two blocks.
The alternative, face merging, requires that the block patches to be merged are first defined in
the patches list. Each pair of patches whose faces are to be merged must then be included in an
optional list named mergePatchPairs. The format of mergePatchPairs is:
mergePatchPairs
(
( <masterPatch> <slavePatch> ) // merge patch pair 0
( <masterPatch> <slavePatch> ) // merge patch pair 1
…
)
The pairs of patches are interpreted such that the first patch becomes the master and the second
becomes the slave. The rules for merging are as follows:
▪ the faces of the master patch remain as originally defined, with all vertices in their original
location;
▪ the faces of the slave patch are projected onto the master patch where there is some
separation between slave and master patch;
▪ the location of any vertex of a slave face might be adjusted by blockMesh to eliminate any
face edge that is shorter than a minimum tolerance;
▪ if patches overlap as shown in Figure 5.6, each face that does not merge remains as an
external face of the original patch, on which boundary conditions must then be applied;
▪ if all the faces of a patch are merged, then the patch itself will contain no faces and is
removed.
The consequence is that the original geometry of the slave patch will not necessarily be
completely preserved during merging. Therefore in a case, say, where a cylindrical block is being
connected to a larger block, it would be wise to the assign the master patch to the cylinder, so
that its cylindrical shape is correctly preserved. There are some additional recommendations to
ensure successful merge procedures:
▪ in 2 dimensional geometries, the size of the cells in the third dimension, i.e. out of the 2D
plane, should be similar to the width/height of cells in the 2D plane;
▪ it is inadvisable to merge a patch twice, i.e. include it twice in mergePatchPairs;
▪ where a patch to be merged shares a common edge with another patch to be merged,
both should be declared as a master patch.
5.3.3 Projection of vertices, edges and faces
blockMesh can be configured to create body fitted meshes using projection of vertices, edges and/or
faces onto specified geometry. The functionality can be used to mesh spherical and cylindrical
geometries such as pipes and vessels conveniently. The user can specify within the blockMeshDict file
within an optional geometry dictionary with the same format as used in the snappyHexMeshDict file. For
example to specify a cylinder using the built in geometric type the user could configure with the following:
geometry
{
cylinder
{
type searchableCylinder;
point1 (0 -4 0);
point2 (0 4 0);
radius 0.7;
}
};
The user can then project vertices, edges and/or faces onto the cylinder surface with
the project keyword using example syntax shown below:
vertices
(
project (-1 -0.1 -1) (cylinder)
project ( 1 -0.1 -1) (cylinder)
...
);
edges
(
project 0 1 (cylinder)
...
);
faces
(
project (0 4 7 3) cylinder
...
);
The use of this functionality is demonstrated in tutorials which can be located by searching for
the project keyword in all the blockMeshDict files by:
edges
(
project v0 v1 (cylinder)
...
);
When a name is provided for a given entity, it can be used to replace the index. In the example
about, rather than specify the edge using vertex indices 0 and 1, the names v0 and v1 are used.
5.3.5 Creating blocks with fewer than 8 vertices
It is possible to collapse one or more pair(s) of vertices onto each other in order to create a block
with fewer than 8 vertices. The most common example of collapsing vertices is when creating a
6-sided wedge shaped block for 2-dimensional axi-symmetric cases that use the wedge patch
type described in section 5.2.2. The process is best illustrated by using a simplified version of
our example block shown in Figure 5.7. Let us say we wished to create a wedge shaped block
by collapsing vertex 7 onto 4 and 6 onto 5. This is simply done by exchanging the vertex number
7 by 4 and 6 by 5 respectively so that the block numbering would become:
hex (0 1 2 3 4 5 5 4)
The same applies to the patches with the main consideration that the block face containing the
collapsed vertices, previously (4 5 6 7) now becomes (4 5 5 4). This is a block face of zero area
which creates a patch with no faces in the polyMesh, as the user can see in a boundary file for
such a case. The patch should be specified as empty in the blockMeshDict and the boundary
condition for any fields should consequently be empty also.
5.3.6 Running blockMesh
As described in section 3.3, the following can be executed at the command line to run blockMesh
for a case in the <case> directory:
The blockMeshDict file must exist in the system (or constant/polyMesh) directory.
This can be done simply using blockMesh. The following criteria must be observed when creating
the background mesh:
▪ the mesh must consist purely of hexes;
▪ the cell aspect ratio should be approximately 1, at least near surfaces at which the
subsequent snapping procedure is applied, otherwise the convergence of the snapping
procedure is slow, possibly to the point of failure;
▪ there must be at least one intersection of a cell edge with the tri-surface, i.e. a mesh of
one cell will not work.
The edgeMesh containing the features can be extracted from the tri-surface file using
the surfaceFeatures utility which specifies the tri-surface and controls such as included angle
through a surfaceFeaturesDict configuration file, examples of which can be found in several
tutorials and at $FOAM_ETC/caseDicts/surface/surfaceFeaturesDict. The utility is simply run by
executing the following in a terminal
surfaceFeatures
Following feature refinement, cells are selected for splitting in the locality of specified surfaces
as illustrated in Figure 5.11.
Figure 5.11: Cell splitting by surface in snappyHexMesh meshing process
sphere1
{ // refinement level 5 within 1.0 m
mode distance; // refinement level 3 within 2.0 m
levels ((1.0 5) (2.0 3)); // levels must be ordered nearest first
}
}
closeness
{
pointCloseness yes;
}
The example shows a refinement region inside the pipeWall surface in which a maximum 2 levels
of refinement is guaranteed within a specified distance of 1000 from the wall. The span-based
refinement, specified by the insideSpan mode, enables the user to guarantee at least
40 cellsAcrossSpan, i.e. across the pipe diameter.
5.4.7 Snapping to surfaces
The next stage of the meshing process involves moving cell vertex points onto surface geometry
to remove the jagged castellated surface from the mesh. The process is:
1. displace the vertices in the castellated boundary onto the STL surface;
2. solve for relaxation of the internal mesh with the latest displaced boundary vertices;
3. find the vertices that cause mesh quality parameters to be violated;
4. reduce the displacement of those vertices from their initial value (at 1) and repeat from 2
until mesh quality is satisfied.
The method uses the settings in the snapControls sub-dictionary in snappyHexMeshDict, listed
below.
▪ nSmoothPatch: number of patch smoothing iterations before finding correspondence to
surface (typically 3).
▪ tolerance: ratio of distance for points to be attracted by surface feature point or edge, to
local maximum edge length (typically 2.0).
▪ nSolveIter: number of mesh displacement relaxation iterations (typically 30-100).
▪ nRelaxIter: maximum number of snapping relaxation iterations (typically 5).
An example is illustrated in the schematic in Figure 5.14 (albeit with mesh motion that looks
slightly unrealistic).
The process of mesh layer addition involves shrinking the existing mesh from the boundary and
inserting layers of cells, broadly as follows:
1. the mesh is projected back from the surface by a specified thickness in the direction
normal to the surface;
2. solve for relaxation of the internal mesh with the latest projected boundary vertices;
3. check if validation criteria are satisfied otherwise reduce the projected thickness and
return to 2; if validation cannot be satisfied for any thickness, do not insert layers;
4. if the validation criteria can be satisfied, insert mesh layers;
5. the mesh is checked again; if the checks fail, layers are removed and we return to 2.
The layer addition procedure uses the settings in the addLayersControls sub-dictionary
in snappyHexMeshDict; entries are listed below. The user has the option of 4 different layer
thickness parameters — expansionRatio, finalLayerThickness, firstLayerThickness, thickness — from
which they must specify 2 only; more than 2, and the problem is over-specified.
▪ layers: dictionary specifying layers to be inserted.
▪ relativeSizes: switch that sets whether the specified layer thicknesses are relative to
undistorted cell size outside layer or absolute.
▪ expansionRatio: expansion factor for layer mesh, increase in size from one layer to the
next.
▪ finalLayerThickness: thickness of layer furthest from the wall, usually in combination with
relative sizes according to the relativeSizes entry.
▪ firstLayerThickness: thickness of layer nearest the wall, usually in combination with absolute
sizes according to the relativeSizes entry.
▪ thickness: total thickness of all layers of cells, usually in combination with absolute sizes
according to the
▪ relativeSizes entry.
▪ minThickness: minimum thickness of cell layer, either relative or absolute (as above).
▪ nGrow: number of layers of connected faces that are not grown if points do not get
extruded; helps convergence of layer addition close to features.
▪ featureAngle: angle above which surface is not extruded.
▪ nRelaxIter: maximum number of snapping relaxation iterations (typcially 5).
▪ nSmoothSurfaceNormals: number of smoothing iterations of surface normals (typically 1).
▪ nSmoothNormals: number of smoothing iterations of interior mesh movement direction
(typically 3).
▪ nSmoothThickness: smooth layer thickness over surface patches (typically 10).
▪ maxFaceThicknessRatio: stop layer growth on highly warped cells (typically 0.5).
▪ maxThicknessToMedialRatio: reduce layer growth where ratio thickness to medial distance
is large (typically 0.3)
▪ minMedianAxisAngle: angle used to pick up medial axis points (typically 90).
▪ nBufferCellsNoExtrude: create buffer region for new layer terminations (typically 0).
▪ nLayerIter: overall max number of layer addition iterations (typically 50).
▪ nRelaxedIter: max number of iterations after which the controls in the relaxed sub dictionary
of meshQuality are used (typically 20).
The layers sub-dictionary contains entries for each patch on which the layers are to be applied
and the number of surface layers required. The patch name is used because the layers addition
relates to the existing mesh, not the surface geometry; hence applied to a patch, not a surface
region. An example layers entry is as follows:
layers
{
sphere1_firstSolid
{
nSurfaceLayers 1;
}
maxY
{
nSurfaceLayers 1;
}
}
reads a Fluent.msh mesh file, working for both 2-D and 3-D cases;
starToFoam
5.5.1 fluentMeshToFoam
Fluent writes mesh data to a single file with a .msh extension. The file must be written in ASCII format,
which is not the default option in Fluent. It is possible to convert single-stream Fluent meshes, including
the 2 dimensional geometries. In OpenFOAM, 2 dimensional geometries are currently treated by defining
a mesh in 3 dimensions, where the front and back plane are defined as the empty boundary patch type.
When reading a 2 dimensional Fluent mesh, the converter automatically extrudes the mesh in the third
direction and adds the empty patch, naming it frontAndBackPlanes.
▪ The OpenFOAM converter will attempt to capture the Fluent boundary condition definition
as much as possible; however, since there is no clear, direct correspondence between
the OpenFOAM and Fluent boundary conditions, the user should check the boundary
conditions before running a case.
▪ Creation of axi-symmetric meshes from a 2 dimensional mesh is currently not supported
but can be implemented on request.
▪ Multiple material meshes are not permitted. If multiple fluid materials exist, they will be
converted into a single OpenFOAM mesh; if a solid region is detected, the converter will
attempt to filter it out.
▪ Fluent allows the user to define a patch which is internal to the mesh, i.e. consists of the
faces with cells on both sides. Such patches are not allowed in OpenFOAM and the
converter will attempt to filter them out.
▪ There is currently no support for embedded interfaces and refinement trees.
The procedure of converting a Fluent.msh file is first to create a new OpenFOAM case by creating
the necessary directories/files: the case directory containing a controlDict file in a system
subdirectory. Then at a command prompt the user should execute:
fluentMeshToFoam <meshFile>
where <meshFile> is the name of the .msh file, including the full or relative path.
5.5.2 starToFoam
This section describes how to convert a mesh generated on the STAR-CD code into a form that
can be read by OpenFOAM mesh classes. The mesh can be generated by any of the packages
supplied with STAR-CD, i.e. PROSTAR, SAMM, ProAM and their derivatives. The converter accepts
any single-stream mesh including integral and arbitrary couple matching and all cell types are
supported. The features that the converter does not support are:
▪ multi-stream mesh specification;
▪ baffles, i.e. zero-thickness walls inserted into the domain;
▪ partial boundaries, where an uncovered part of a couple match is considered to be a
boundary face;
▪ sliding interfaces.
For multi-stream meshes, mesh conversion can be achieved by writing each individual stream
as a separate mesh and reassemble them in OpenFOAM.
OpenFOAM adopts a policy of only accepting input meshes that conform to the fairly stringent
validity criteria specified in section 5.1. It will simply not run using invalid meshes and cannot
convert a mesh that is itself invalid. The following sections describe steps that must be taken
when generating a mesh using a mesh generating package supplied with STAR-CD to ensure
that it can be converted to OpenFOAM format. To avoid repetition in the remainder of the section,
the mesh generation tools supplied with STAR-CD will be referred to by the collective name STAR-
CD.
5.5.2.1 General advice on conversion
We strongly recommend that the user run the STAR-CD mesh checking tools before attempting
a starToFoam conversion and, after conversion, the checkMesh utility should be run on the newly
converted mesh. Alternatively, starToFoam may itself issue warnings containing PROSTAR
commands that will enable the user to take a closer look at cells with problems. Problematic
cells and matches should be checked and fixed before attempting to use the mesh with
OpenFOAM. Remember that an invalid mesh will not run with OpenFOAM, but it may run in
another environment that does not impose the validity criteria.
Some problems of tolerance matching can be overcome by the use of a matching tolerance in
the converter. However, there is a limit to its effectiveness and an apparent need to increase the
matching tolerance from its default level indicates that the original mesh suffers from
inaccuracies.
5.5.2.2 Eliminating extraneous data
When mesh generation in is completed, remove any extraneous vertices and compress the cells
boundary and vertex numbering, assuming that fluid cells have been created and all other cells
are discarded. This is done with the following PROSTAR commands:
The CSET should be empty. If this is not the case, examine the cells in CSET and adjust the model. If the
cells are genuinely not desired, they can be removed using the PROSTAR command:
CDEL CSET
Before discarding these unwanted vertices, the unwanted boundary faces have to be collected before
purging:
If the BSET is not empty, the unwanted boundary faces can be deleted using:
BDEL BSET
At this time, the model should contain only the fluid cells and the supporting vertices, as well as
the defined boundary faces. All boundary faces should be fully supported by the vertices of the
cells, if this is not the case, carry on cleaning the geometry until everything is clean.
Internal PROSTAR checking is performed by the last two commands, which may reveal some other
unforeseeable error(s). Also, take note of the scaling factor because PROSTAR only applies the factor
for STAR-CD and not the geometry. If the factor is not 1, use the scalePoints utility in OpenFOAM.
The components of the computational grid must then be written to their own files. This is done
using PROSTAR for boundaries by issuing the command
BWRITE
by default, this writes to a .23 file (versions prior to 3.0) or a .bnd file (versions 3.0 and higher). For cells,
the command
CWRITE
outputs the cells to a .14 or .cel file and for vertices, the command
VWRITE
outputs to file a .15 or .vrt file. The current default setting writes the files in ASCII format. If couples are
present, an additional couple file with the extension .cpl needs to be written out by typing:
CPWRITE
After outputting to the three files, exit PROSTAR or close the files. Look through the panels and
take note of all STAR-CD sub-models, material and fluid properties used – the material properties
and mathematical model will need to be set up by creating and editing OpenFOAM dictionary
files.
The procedure of converting the PROSTAR files is first to create a new OpenFOAM case by
creating the necessary directories. The PROSTAR files must be stored within the same directory
and the user must change the file extensions: from .23, .14 and .15 (below STAR-CD version 3.0),
or .pcs, .cls and .vtx (STAR-CD version 3.0 and above); to .bnd, .cel and .vrt respectively.
5.5.2.6 Problems with the .vrt file
The .vrt file is written in columns of data of specified width, rather than free format. A typical line
of data might be as follows, giving a vertex number followed by the coordinates:
If the ordinates are written in scientific notation and are negative, there may be no space between
values, e.g. :
The starToFoam converter reads the data using spaces to delimit the ordinate values and will therefore
object when reading the previous example. Therefore, OpenFOAM includes a simple
script, foamCorrectVrt to insert a space between values where necessary, i.e. it would convert the
previous example to:
The foamCorrectVrt script should therefore be executed if necessary before running the starToFoam
converter, by typing:
foamCorrectVrt <file>.vrt
5.5.2.7 Converting the mesh to OpenFOAM format
The translator utility starToFoam can now be run to create the boundaries, cells and points files
necessary for a OpenFOAM run:
starToFoam <meshFilePrefix>
where <meshFilePrefix> is the name of the prefix of the mesh files, including the full or relative path. After
the utility has finished running, OpenFOAM boundary types should be specified by editing the boundary
file by hand.
5.5.3 gambitToFoam
GAMBIT writes mesh data to a single file with a .neu extension. The procedure of converting
a GAMBIT.neu file is first to create a new OpenFOAM case, then at a command prompt, the user should
execute:
gambitToFoam <meshFile>
where <meshFile> is the name of the .neu file, including the full or relative path.
The GAMBIT file format does not provide information about type of the boundary patch, e.g. wall,
symmetry plane, cyclic. Therefore all the patches have been created as type patch. Please reset
after mesh conversion as necessary.
5.5.4 ideasToFoam
OpenFOAM can convert a mesh generated by I-DEAS but written out in ANSYS format as a .ans
file. The procedure of converting the .ans file is first to create a new OpenFOAM case, then at a
command prompt, the user should execute:
ideasToFoam <meshFile>
where <meshFile> is the name of the .ans file, including the full or relative path.
5.5.5 cfx4ToFoam
CFX writes mesh data to a single file with a .geo extension. The mesh format in CFX is block-
structured, i.e. the mesh is specified as a set of blocks with glueing information and the vertex locations.
OpenFOAM will convert the mesh and capture the CFX boundary condition as best as possible. The 3
dimensional ‘patch’ definition in CFX, containing information about the porous, solid regions etc. is
ignored with all regions being converted into a single OpenFOAM mesh. CFX supports the concept of a
‘default’ patch, where each external face without a defined boundary condition is treated as a wall. These
faces are collected by the converter and put into a defaultFaces patch in the OpenFOAM mesh and given
the type wall; of course, the patch type can be subsequently changed.
cfx4ToFoam <meshFile>
where <meshFile> is the name of the .geo file, including the full or relative path.
-parallelTarget
if the target case is decomposed for parallel running.
Chapter 6 Post-processing
This chapter describes options for post-processing with OpenFOAM. OpenFOAM is supplied
with a post-processing utility paraFoam that uses ParaView, an open source visualisation
application described in section 6.1.
Other methods of post-processing using third party products are offered,
including EnSight, Fieldview and the post-processing supplied with Fluent.
6.1 ParaView/paraFoam graphical user interface (GUI)
The main post-processing tool provided with OpenFOAM is a reader module to run
with ParaView, an open-source, visualization application. The module is compiled into 2
libraries, PVFoamReader and vtkPVFoam using version 5.4.0 of ParaView supplied with the
OpenFOAM release. It is recommended that this version of ParaView is used, although it is
possible that the latest binary release of the software will run adequately. Further details
about ParaView can be found at http://www.paraview.org. ParaView uses the Visualisation Toolkit
(VTK) as its data processing and rendering engine and can therefore read any data
in VTK format. OpenFOAM includes the foamToVTK utility to convert data from its native format
to VTK format, which means that any VTK-based graphics tools can be used to post-process
OpenFOAM cases. This provides an alternative means for using ParaView with OpenFOAM.
In summary, we recommend the reader module for ParaView as the primary post-processing tool
for OpenFOAM. Alternatively OpenFOAM data can be converted into VTK format to be read
by ParaView or any other VTK-based graphics tools.
6.1.1 Overview of ParaView/paraFoam
paraFoam is a script that launches ParaView using the reader module supplied with OpenFOAM. It is
executed like any of the OpenFOAM utilities either by the single command from within the case directory
or with the -case option with the case path as an argument, e.g. :
Pipeline Browser
lists the modules opened in ParaView, where the selected modules are highlighted in blue and
the graphics for the given module can be enabled/disabled by clicking the eye button alongside;
Properties panel
contains the input selections for the case, such as times, regions and fields; it includes
the Display panel that controls the visual representation of the selected module, e.g. colours;
Other panels
can be selected from the View menu, including the Information panel which gives case statistics
such as mesh geometry and size.
ParaView operates a tree-based structure in which data can be filtered from the top-level case module to
create sets of sub-modules. For example, a contour plot of, say, pressure could be a sub-module of the
case module which contains all the pressure data. The strength of ParaView is that the user can create a
number of sub-modules and display whichever ones they feel to create the desired image or animation.
For example, they may add some solid geometry, mesh and velocity vectors, to a contour plot of pressure,
switching any of the items on and off as necessary.
The general operation of the system is based on the user making a selection and then clicking
the green Apply button in the Properties panel. The additional buttons are: the Reset button which
can be used to reset the GUI if necessary; and, the Delete button that will delete the active
module.
6.1.2 The Parameters panel
The Properties window for the case module includes the Parameters panel that contains the
settings for mesh, fields and global controls.
The controls are described in Figure 6.2. The user can select mesh and field data which is loaded
for all time directories into ParaView. The buttons in the Current Time Controls and VCR
Controls toolbars then select the time data to be displayed, as shown is section 6.1.4.
As with any operation in paraFoam, the user must click Apply after making any changes to any
selections. The Apply button is highlighted in green to alert the user if changes have been made
but not accepted. This method of operation has the advantage of allowing the user to make a
number of selections before accepting them, which is particularly useful in large cases where
data processing is best kept to a minimum.
If new data is written to time directories while the user is running ParaView, the user must load
the additional time directories by checking the Refresh Times button. Where there are occasions
when the case data changes on file and ParaView needs to load the changes, the user can also
check the Update GUI button in the Parameters panel and apply the changes.
6.1.3 The Display panel
The Properties window contains the Display panel that includes the settings for visualising the data
for a given case module.
▪ the data range may not be automatically updated to the max/min limits of a field, so the
user should take care to select Rescale at appropriate intervals, in particular after loading
the initial case module;
▪ clicking the Edit Color Map button, brings up a window in which there are two panels:
1. The Color Scale panel in which the colours within the scale can be chosen. The
standard blue to red colour scale for CFD can be selected by clicking Choose
Preset and selecting Blue to Red Rainbox HSV.
2. The Color Legend panel has a toggle switch for a colour bar legend and contains
settings for the layout of the legend, e.g. font.
▪ the underlying mesh can be represented by selecting Wireframe in the Representation menu
of the Style panel;
▪ the geometry, e.g. a mesh (if Wireframe is selected), can be visualised as a single colour
by selecting Solid Color from the Color By menu and specifying the colour in the Set Ambient
Color window;
▪ the image can be made translucent by editing the value in the Opacity text box (1 = solid,
0 = invisible) in the Style panel.
6.1.4 The button toolbars
ParaView duplicates functionality from pull-down menus at the top of the main window and the major
panels, within the toolbars below the main pull-down menus. The displayed toolbars can be selected
from Toolbars in the main View menu. The default layout with all toolbars is shown in Figure 6.4 with each
toolbar labelled. The function of many of the buttons is clear from their icon and, with tooltips enabled in
the Help menu, the user is given a concise description of the function of any button.
simpleFoam -listFunctionObjects
The list represents the underlying post-processing functionality. Almost all the functionality is packaged
into a set of configured tools that are conveniently integrated within the post-processing CLI. Those tools
are located in $FOAM_ETC/caseDicts/postProcessing and are listed by running postProcess with the -list
option.
postProcess -list
This produces a list of tools that are described in the following sections.
Lambda2
Calculates and writes the second largest eigenvalue of the sum of the square of the symmetrical
and anti-symmetrical parts of the velocity gradient tensor.
MachNo
Calculates the Mach Number field from the velocity field.
PecletNo
Calculates the Peclet Number field from the flux field.
Q
Calculates the second invariant of the velocity gradient tensor.
R
Calculates the Reynolds stress tensor field and stores it on the database.
add
Add a list of fields.
age
Calculates and writes out the time taken for a particle to travel from an inlet to the location.
components
Writes the component scalar fields (e.g. Ux, Uy, Uz) of a field (e.g. U).
ddt
div
Calculates the divergence of a field.
enstrophy
Calculates the enstrophy of the velocity field.
fieldAverage
Calculates and writes the time averages of a given list of fields.
flowType
Calculates and writes the flowType of velocity field where: -1 = rotational flow; 0 = simple shear
flow; +1 = planar extensional flow.
grad
log
Calculates the natural logarithm of the specified scalar field.
mag
Calculates the magnitude of a field.
magSqr
Calculates the magnitude-squared of a field.
phaseMap
Writes the phase-fraction map field alpha.map with incremental value ranges for each phase e.g.,
with values 0 for water, 1 for air, 2 for oil, etc.
randomise
scale
Multiplies a field by a scale factor
shearStress
Calculates the shear stress, outputting the data as a volSymmTensorField.
streamFunction
Writes the stream-function pointScalarField, calculated from the specified flux surfaceScalarField.
subtract
From the first field, subtracts the remaining fields in the list.
totalEnthalpy
Calculates and writes the total enthalpy as the volScalarField .
turbulenceFields
turbulenceIntensity
Calculates and writes the turbulence intensity field I.
vorticity
Calculates the vorticity field, i.e. the curl of the velocity field.
wallHeatFlux
Calculates the heat flux at wall patches, outputting the data as a volVectorField.
wallHeatTransferCoeff
Calculates the estimated incompressible flow heat transfer coefficient at wall patches, outputting
the data as a volScalarField.
wallShearStress
Calculates the shear stress at wall patches, outputting the data as a volVectorField.
writeCellCentres
Writes the cell-centres volVectorField and the three component fields as volScalarFields; useful
for post-processing thresholding.
writeCellVolumes
Writes out specified objects in VTK format, e.g. fields, stored on the case database.
yPlus
Calculates the flow rate through a specified face zone by summing the flux on patch faces. For
solvers where the flux is volumetric, the flow rate is volumetric; where flux is mass flux, the flow
rate is mass flow rate.
flowRatePatch
Calculates the flow rate through a specified patch by summing the flux on patch faces. For solvers
where the flux is volumetric, the flow rate is volumetric; where flux is mass flux, the flow rate is
mass flow rate.
volFlowRateSurface
Calculates volumetric flow rate through a specified triangulated surface by interpolating velocity
onto the triangles and integrating over the surface area. Triangles need to be small (�= cell size)
for an accurate result.
Calculates lift, drag and moment coefficients by summing forces on specified patches for a case
where the solver is compressible (pressure is in units M/(LTˆ2), e.g. Pa).
forceCoeffsIncompressible
Calculates lift, drag and moment coefficients by summing forces on specified patches for a case
where the solver is incompressible (pressure is kinematic, e.g. mˆ2/sˆ2).
forcesCompressible
Calculates pressure and viscous forces over specified patches for a case where the solver is
compressible (pressure is in units M/(LTˆ2), e.g. Pa).
forcesIncompressible
Calculates pressure and viscous forces over specified patches for a case where the solver is
incompressible (pressure is kinematic, e.g. mˆ2/sˆ2).
Writes graph data for specified fields along a line, specified by start and end points.
Calculate intensive fields UMean, translationalT, internalT, overallT from averaged extensive fields
from a DSMC calculation.
Writes out the maximum cell value for one or more fields.
cellMin
Writes out the minimum cell value for one or more fields.
faceMax
Writes out the maximum face value for one or more fields.
faceMin
Writes out the minimum face value for one or more fields.
minMaxComponents
Writes out the minimum and maximum values, by component for non-scalar fields, and the
locations where they occur.
minMaxMagnitude
Writes out the minimum and maximum values, by magnitude for non-scalar fields, and the
locations where they occur.
For specified fields, writes out the initial residuals for the first solution of each time step; for non-
scalar fields (e.g. vectors), writes the largest of the residuals for each component (e.g. x, y, z).
6.2.1.8 Control
stopAtClockTime
Stops the run when the specified clock time in second has been reached and optionally write
results before stopping.
stopAtFile
Stops the run when the file stop is created in the case directory.
time
Writes run time, CPU time and clock time and optionally the CPU and clock times per time step.
writeObjects
Writes out specified objects, e.g. fields, stored on the case database.
pressureDifferenceSurface
Interpolates pressures onto 2 specified triangulated surfaces and calculates the difference
between the average pressures.
staticPressure
Calculates the pressure field in units M/(LTˆ2) (e.g. Pa) from kinematic pressure by scaling by a
specified density.
totalPressureCompressible
Calculates the total pressure field for a case where the solver is compressible (pressure is in units
M/(LTˆ2), e.g. Pa).
totalPressureIncompressible
Calculates the total pressure field for a case where the solver is incompressible (pressure is
kinematic, e.g. mˆ2/sˆ2).
6.2.1.10 Combustion
Qdot
Calculates and outputs the heat release rate for the current combustion model.
XiReactionRate
Writes the turbulent flame-speed and reaction-rate volScalarFields for the Xi-based combustion
models.
6.2.1.11 Probes
boundaryProbes
Writes out values of fields at a cloud of points, interpolated to specified boundary patches.
interfaceHeight
Reports the height of the interface above a set of locations. For each location, it writes the vertical
distance of the interface above both the location and the lowest boundary. It also writes the point
on the interface from which these heights are computed.
internalProbes
Writes out values of fields interpolated to a specified cloud of points.
probes
Writes out values of fields from cells nearest to specified locations.
6.2.1.12 ‘Pluggable’ solvers
particles
phasescalarTransport
Solves a transport equation for a scalar field within one phase of a multiphase simulation.
scalarTransport
Solves a transport equation for a scalar field.
Writes out files of streamlines with interpolated field data in VTK format.
surfaces
Writes out surface files with interpolated field data in VTK format, e.g. cutting planes, iso-surfaces
and patch boundary surfaces.
Firstly, the user should include the flowRatePatch function in functions sub-dictionary in the
case controlDict file, using the #includeFunc directive.
functions
{
#includeFunc flowRatePatch
... other function objects here ...
}
That will include the functionality in the flowRatePatch configuration file, located in the directory hierarchy
beginning with $FOAM_ETC/caseDicts/postProcessing.
The configuration of flowRatePatch requires the name of the patch to be supplied. Option 1 for
doing this is that the user copies the flowRatePatch file into their case system directory.
The foamGet script copies the file conveniently, e.g.
foamGet flowRatePatch
The patch name can be edited in the copied file to be outlet. When the solver is run, it will pick up an
included function in the local case system directory, in precedence
over $FOAM_ETC/caseDicts/postProcessing. The flow rate through the patch will be calculated and written
out into a file within a directory named postProcessing. Option 2 for specifying the patch name is to
provide the name as an argument to the flowRatePatch in the #includeFunc directive, using the
syntax keyword=entry.
functions
{
#includeFunc flowRatePatch(name=outlet)
... other function objects here ...
}
In the case where the keyword is field or fields, only the entry is needed when specifying an
argument to a function. For example, if the user wanted to calculate and write out the magnitude
of velocity into time directories during a simulation they could simply add the following to
the functions sub-dictionary in controlDict.
functions
{
#includeFunc mag(U)
... other function objects here ...
}
This works because the function’s argument U is represented by the keyword field,
see $FOAM_ETC/caseDicts/postProcessing/fields/mag.
Some functions require the setting of many parameters, e.g. forces, forceCoeffs, surfaces, etc. For
those functions, it is more reliable and convenient to copy and configure the function using option
1 (above) rather than through arguments.
6.2.3 The postProcess utility
The user can execute post-processing functions after the simulation is complete using the postProcess
utility. Let us illustrate the use of postProcess using the pitzDaily case from the tutorials directory. The
case can be copied, e.g. into the user’s run directory; the user can then go into the case directory,
generate the mesh with blockMesh and then run simpleFoam
run
cp -r $FOAM_TUTORIALS/incompressible/simpleFoam/pitzDaily .
cd pitzDaily
blockMesh
simpleFoam
Now the user can run execute post-processing functions with postProcess. The -help option provides a
summary of its use.
postProcess -help
Simple functions like mag can be executed using the -func option; text on the command line generally
needs to be quoted ("…") if it contains punctuation characters.
This operation calculates and writes the field of magnitude of velocity into a file named mag(U) in each
time directory. Similarly, the flowRatePatch example can be executed using postProcess.
The error message is telling the user that the pressure field p is not loaded; the same is true of the velocity
field U. For the function to work, both fields can be loaded as comma separated arguments.
Alternatively the user can load a space separated list of fields using the -fields option, which the function
can access.
Both options work effectively because the pressure and velocity data is available directly from the files, p
and U.
Even loading relevant fields, the post-processing fails with the following message.
The message is telling us that the postProcess utility has not constructed the necessary models that the
solver, simpleFoam, used when running the simulation, i.e. a turbulence model. This is a situation where
we need to post-process (as opposed to run-time process) using the solver with the -postProcess option
so that the modelling will be available that the post-processing function needs. Help for this operation can
be printed with the following command.
It can be seen that the options for a solver with -postProcess are the same as when running postProcess
utility. This means that the -func option can be used to execute the wallShearStress function effectively.
Note that no fields need to be supplied, either by function arguments ”(p,U)” or using ”-fields (p
U)”, because simpleFoam itself constructs and stores the required fields. Functions can also be
selected by the #includeFunc directive in functions in the controlDict file, instead of the -func option.
6.3 Sampling and monitoring data
There are a set of general post-processing functions for sampling data across the domain for
graphs and visualisation. Several functions also provide data in a single file, in the form of time
versus values, that can be plotted onto graphs. This time-value data can be monitored during a
simulation with the foamMonitor script.
6.3.1 Probing data
The functions for probing data are boundaryProbes, internalProbes and probes as listed in
section 6.2.1.11. All functions work on the basis that the user provides some point locations and
a list of fields, and the function writes out values of the fields are those locations. The differences
between the functions are as follows.
▪ probes identifies the nearest cells to the probe locations and writes out the cell values;
data is written into a single file in time-value format, suitable for plotting a graph.
▪ boundaryProbes and internalProbes interpolate field data to the probe locations, with the
locations being snapped onto boundaries for boundaryProbes; data sets are written to
separate files at scheduled write times (like fields). data.
Generally probes is more suitable for monitoring values at smaller numbers of locations, whereas
the other functions are typically for sampling at large numbers of locations.
As an example, the user could use the pitzDaily case set up in section 6.2.3. The probes function
is best configured by copying the file to the local system directory using foamGet.
foamGet probes
The user can modify the probeLocations in the probes file as follows.
12
13#includeEtc "caseDicts/postProcessing/probes/probes.cfg"
14
15fields (p U);
16probeLocations
17(
18 (0.01 0 0)
19);
20
21// ************************************************************************* //
The configuration is completed by adding the #includeFunc directive to functions in the controlDict
file.
functions
{
#includeFunc probes
... other function objects here ...
}
When simpleFoam is run, time-value data is written into p and U files in postProcessing/probes/0.
6.3.2 Sampling for graphs
The singleGraph function samples data for graph plotting. To use it, the singleGraph file should be copied
into the system directory to be configured. We will configure it here using the pitzDaily case as before.
The file is simply copied using foamGet.
foamGet singleGraph
The start and end points of the line, along which data is sampled, should be edited; the entries below
provide a vertical line across the full height of the geometry 0.01 m beyond the back step.
13
14start (0.01 0.025 0);
15end (0.01 -0.025 0);
16fields (U p);
17
18// Sampling and I/O settings
19#includeEtc "caseDicts/postProcessing/graphs/sampleDict.cfg"
20
21// Override settings here, e.g.
22// setConfig { type midPoint; }
23
24// Must be last entry
25#includeEtc "caseDicts/postProcessing/graphs/graph.cfg"
26
27// ************************************************************************* //
The configuration is completed by adding the #includeFunc directive to functions in the controlDict
file.
functions
{
#includeFunc singleGraph
... other function objects here ...
}
simpleFoam can be then run; try running simply with the -postProcess option. Distance-value data is
written into files in time directories within postProcessing/singleGraph. The user can quickly display the
data for -component of velocity, in the last time 296, by running gnuplot and plotting values.
gnuplot
gnuplot> set style data linespoints
gnuplot> plot "postProcessing/singleGraph/296/line_U.xy" u 2:1
This shows that the sampling is at uniform distribution of 100 points and that the axis labelling is
based on the distance from the start point. Instead the user may wish to sample at the mid-point
of each cell, using the -ordinate for the axis labelling. This can be done by override the settings
in setConfig in their singleGraph file, as shown below.
13
14start (0.01 -0.025 0);
15end (0.01 0.025 0);
16fields (U p);
17
18// Sampling and I/O settings
19#includeEtc "caseDicts/postProcessing/graphs/sampleDict.cfg"
20
21// Override settings here, e.g.
22setConfig
23{
24 type lineCell;
25 axis y;
26}
27
28// Must be last entry
29#includeEtc "caseDicts/postProcessing/graphs/graph.cfg"
30
31// ************************************************************************* //
foamGet surfaces
The file is configured with a set of example surfaces that includes cutting planes, isosurfaces and patch
surfaces. We can edit the file to produce a cutting plane along the pitzDaily geometry, normal to the -
direction.
16
17#includeEtc "caseDicts/postProcessing/visualization/surfaces.cfg"
18
19fields (p U);
20
21surfaces
22(
23 zNormal
24 {
25 $cuttingPlane;
26 pointAndNormalDict
27 {
28 normalVector $z;
29 }
30 }
31);
32
33// ************************************************************************* //
The function can be included as normal by adding the #includeFunc directive to functions in
the controlDict file. Alternatively, the user could test running the function using the solver post-
processing by the following command.
This produces VTK format files of the cutting plane with pressure and velocity data in time directories in
the postProcessing/surfaces directory. The user can display the cutting plane by
opening ParaView (type paraview), then doing File->Open and selecting one of the
files, e.g. postProcessing/surfaces/296/U_zNormal.vtk as shown in Figure 6.7.
functions
{
#includeFunc residuals
... other function objects here ...
}
The default fields whose residuals are captured are p and U. Should the user wish to configure other
fields, they should make copy the residuals file in their system and edit the fields entry accordingly. All
functions files are within the $FOAM_ETC/caseDicts directory. The residuals file can be located
using foamInfo:
foamInfo residuals
It can then be copied into the system directory conveniently using foamGet:
foamGet residuals
It is advisable to delete the postProcessing directory to avoid duplicate files for each function. The
user can delete the directory, then run simpleFoam in the background.
rm -rf postProcessing
simpleFoam > log &
The user should then run foamMonitor using the -l option for a log scale -axis on the residuals file as
follows. If the command is executed before the simulation is complete, they can see the graph being
updated live.
foamMonitor -l postProcessing/residuals/0/residuals.dat
It produces the graph of residuals for pressure and velocity in Figure 6.8.
foamToEnsight
Translates OpenFOAM data to EnSight format.
foamToEnsightParts
Translates OpenFOAM data to Ensight format. An Ensight part is created for each cellZone and
patch.
foamToTetDualMesh
smapToFoam
Translates a STAR-CD SMAP data file into OpenFOAM field format.
In order to run the EnSight reader, it is necessary to set some environment variables correctly.
The settings are made in the bashrc (or cshrc) file in the $WM_PROJECT_DIR/etc/apps/ensightFoam
directory. The environment variables associated with EnSight are prefixed by $CEI_
or $ENSIGHT7_ and listed in Table 6.1. With a standard user setup, only $CEI_HOME may need
to be set manually, to the path of the EnSight installation.
Environment
variable Description and options
$CEI_HOME
Path where EnSight is installed, eg /usr/local/ensight, added to the
system path by default
Machine architecture, from a choice of names corresponding to the
$CEI_ARCH machine directory names in $CEI_HOME/ensight74/machines; default
settings include linux_2.4 and sgi_6.5_n32
$ENSIGHT7_READER Path that EnSight searches for the user defined libuserd-foam reader
library, set by default to $FOAM_LIBBIN
$ENSIGHT7_INPUT
Set by default to dummy
The principal difficulty in using the EnSight reader lies in the fact that EnSight expects that a case
to be defined by the contents of a particular file, rather than a directory as it is in OpenFOAM.
Therefore in following the instructions for the using the reader below, the user should pay
particular attention to the details of case selection, since EnSight does not permit selection of a
directory name.
1. from the EnSight GUI, the user should select Data (Reader) from the File menu;
2. The user should now be able to select the OpenFOAM from the Format menu; if not, there
is a problem with the configuration described above.
3. The user should find their case directory from the File Selection window, highlight one of
top 2 entries in the Directories box ending in /. or /.. and click (Set) Geometry.
4. The path field should now contain an entry for the case. The (Set) Geometry text box should
contain a ‘/’.
5. The user may now click Okay and EnSight will begin reading the data.
6. When the data is read, a new Data Part Loader window will appear, asking which part(s)
are to be read. The user should select Load all.
7. When the mesh is displayed in the EnSight window the user should close the Data Part
Loader window, since some features of EnSight will not work with this window open.
Chapter 7 Models and physical properties
OpenFOAM includes a large range of solvers each designed for a specific class of problem. The
equations and algorithms differ from one solver to another so that the selection of a solver
involves the user making some initial choices on the modelling for their particular case. The
choice of solver typically involves scanning through their descriptions in section 3.5 to find the
one suitable for the case. It ultimately determines many of the parameters and physical
properties required to define the case but leaves the user with some modelling options that can
be specified at runtime through the entries in dictionary files in the constant directory of a case.
This chapter deals with many of the more common models and associated properties that must
be specified at runtime.
7.1 Thermophysical models
Thermophysical models are concerned with energy, heat and physical properties.
The thermophysicalProperties dictionary is read by any solver that uses the thermophysical model
library. A thermophysical model is constructed in OpenFOAM as a pressure-
temperature system from which other properties are computed. There is one compulsory
dictionary entry called thermoType which specifies the package of thermophysical modelling that
is used in the simulation. OpenFOAM includes a large set of pre-compiled combinations of
modelling, built within the code using C++ templates. This coding approach assembles
thermophysical modelling packages beginning with the equation of state and then adding more
layers of thermophysical modelling that derive properties from the previous layer(s). The
keyword entries in thermoType reflects the multiple layers of modelling and the underlying
framework in which they combined. Below is an example entry for thermoType:
thermoType
{
type hePsiThermo;
mixture pureMixture;
transport const;
thermo hConst;
equationOfState perfectGas;
specie specie;
energy sensibleEnthalpy;
}
Thermophysical model for fixed composition, based on density . The solvers that
construct rhoThermo include
the buoyantSimpleFoam, buoyantPimpleFoam, rhoPorousSimpleFoam, twoPhaseEulerFoam
and thermoFoam.
psiReactionThermo
Thermophysical model for combustion, based on compressibility of unburnt gas . The solvers
that construct psiuReactionThermo include combustion solvers that model combustion based on
laminar flame speed and regress variable, e.g. XiFoam, XiEngineFoam, PDRFoam.
rhoReactionThermo
Thermophysical models for multiple phases. The solvers that construct multiphaseMixtureThermo
include compressible multiphase interface-capturing solvers, e.g. compressibleInterFoam,
and compressibleMultiphaseInterFoam.
The type keyword specifies the underlying thermophysical model. Options are listed below.
▪ hePsiThermo: for solvers that construct psiThermo and psiReactionThermo.
▪ heRhoThermo: for solvers that
construct rhoThermo, rhoReactionThermo and multiphaseMixtureThermo.
▪ heheuPsiThermo: for solvers that construct psiuReactionThermo.
The mixture specifies the mixture composition. The option typically used for thermophysical
models without reactions is pureMixture, which represents a mixture with fixed composition.
When pureMixture is specified, the thermophysical models coefficients are specified within a sub-
dictionary called mixture.
For mixtures with variable composition, required by thermophysical models with reactions,
the reactingMixture option is used. Species and reactions are listed in a chemistry file, specified
by the foamChemistryFile keyword. The reactingMixture model then requires the thermophysical
models coefficients to be specified for each specie within sub-dictionaries named after each
specie, e.g. O2, N2.
For combustion based on laminar flame speed and regress variables, constituents are a set of
mixtures, such as fuel, oxidant and burntProducts. The available mixture models for this
combustion modelling
are homogeneousMixture, inhomogeneousMixture and veryInhomogeneousMixture.
Other models for variable composition
are egrMixture, multiComponentMixture and singleStepReactingMixture.
7.1.2 Transport model
The transport modelling concerns evaluating dynamic viscosity , thermal conductivity and thermal
diffusivity (for internal energy and enthalpy equations). The current transport models are as follows:
const
assumes a constant and Prandtl number which is simply specified by a two
keywords, mu and Pr, respectively.
sutherland
(7.1)
polynomial
(7.2)
logPolynomial
(7.3)
hConst
assumes a constant and a heat of fusion which is simply specified by a two values
, given by keywords Cp and Hf.
eConst
assumes a constant and a heat of fusion which is simply specified by a two values
, given by keywords Cv and Hf.
janaf
calculates as a function of temperature from a set of coefficients taken from JANAF tables
of thermodynamics. The ordered list of coefficients is given in Table 7.1. The function is valid
between a lower and upper limit in temperature and respectively. Two sets of coefficients
are specified, the first set for temperatures above a common temperature (and below ), the
second for temperatures below (and above ). The function relating to temperature is:
(7.4)
In addition, there are constants of integration, and , both at high and low temperature, used
to evaluating and respectively.
hPolynomial
(7.5)
ePolynomial
calculates as a function of temperature by a polynomial of any order :
(7.6)
hPower
calculates as a power of temperature according to:
(7.7)
ePower
calculates as a power of temperature according to:
(7.8)
hTabulated
calculates by interpolating tabulated data of value pairs, e.g. :
Cp ( (200 1005) (400 1020) );
Description Entry Keyword
▪ nMoles: number of moles of component. This entry is only used for combustion modelling
based on regress variable with a homogeneous mixture of reactants; otherwise it is set
to 1.
▪ molWeight in grams per mole of specie.
7.1.5 Equation of state
The following equations of state are available in the thermophysical modelling library.
rhoConst
Constant density:
(7.9)
perfectGas
Perfect gas:
(7.10)
icoTabulated
Tabulated data for an incompressible fluid using value pairs, e.g.
rho ( (200 1010) (400 980) );
incompressiblePerfectGas
Perfect gas for an incompressible fluid:
(7.11)
perfectFluid
Perfect fluid:
(7.12)
linear
Linear equation of state:
(7.13)
adiabaticPerfectFluid
Adiabatic perfect fluid:
(7.14)
where are reference density and pressure respectively, and is a model constant.
Boussinesq
Boussinesq approximation
(7.15)
where is the coeffient of volumetric expansion and is the reference density at reference
temperature .
PengRobinsonGas
Peng Robinson equation of state:
(7.16)
(7.17)
rPolynomial
Reciprocal polynomial equation of state for liquids and solids:
(7.18)
We refer to absolute energy where heat of formation is included, and sensible energy where it is
not. For example absolute enthalpy is related to sensible enthalpy by
(7.19)
where and are the molar fraction and heat of formation, respectively, of specie . In most cases,
we use the sensible form of energy, for which it is easier to account for energy change due to reactions.
Keyword entries for energy therefore include e.g. sensibleEnthalpy, sensibleInternalEnergy
and absoluteEnthalpy.
specie
containing i.e. number of moles, nMoles, of the specie, and molecular weight, molWeight in units
of g/mol;
thermodynamics
transport
containing coefficients for the chosen tranpsort model (see below).
The following is an example entry for a specie named fuel modelled using sutherland transport
and janaf thermodynamics:
fuel
{
specie
{
nMoles 1;
molWeight 16.0428;
}
thermodynamics
{
Tlow 200;
Thigh 6000;
Tcommon 1000;
highCpCoeffs (1.63543 0.0100844 -3.36924e-06 5.34973e-10
-3.15528e-14 -10005.6 9.9937);
lowCpCoeffs (5.14988 -0.013671 4.91801e-05 -4.84744e-08
1.66694e-11 -10246.6 -4.64132);
}
transport
{
As 1.67212e-06;
Ts 170.672;
}
}
The following is an example entry for a specie named air modelled using const transport and hConst
thermodynamics:
air
{
specie
{
nMoles 1;
molWeight 28.96;
}
thermodynamics
{
Cp 1004.5;
Hf 2.544e+06;
}
transport
{
mu 1.8e-05;
Pr 0.7;
}
}
RAS
uses Reynolds-averaged simulation (RAS) modelling;
LES
uses large-eddy simulation (LES) modelling.
simpleFoam -listMomentumTransportModels
With simpleFoam, the incompressible models are listed. The compressible models are listed for a
compressible solver, e.g. rhoSimpleFoam.
The RAS models used in the tutorials can be listed using foamSearch with the following command.
The lists of available models are given in the following sections.
Users can locate tutorials using a particular model, e.g. buoyantKEpsilon, using foamInfo.
foamInfo buoyantKEpsilon
Launder, Reece and Rodi Reynolds-stress turbulence model for incompressible flows.
LamBremhorstKE
Lam and Bremhorst low-Reynolds number k-epsilon turbulence model for incompressible flows.
LaunderSharmaKE
Launder and Sharma low-Reynolds k-epsilon turbulence model for incompressible flows.
LienCubicKE
Lien cubic non-linear low-Reynolds k-epsilon turbulence models for incompressible flows.
LienLeschziner
Lien and Leschziner low-Reynolds number k-epsilon turbulence model for incompressible flows.
RNGkEpsilon
Renormalization group k-epsilon turbulence model for incompressible flows.
SSG
Speziale, Sarkar and Gatski Reynolds-stress turbulence model for incompressible flows.
ShihQuadraticKE
Shih’s quadratic algebraic Reynolds stress k-epsilon turbulence model for incompressible flows
SpalartAllmaras
Spalart-Allmaras one-eqn mixing-length model for incompressible external flows.
kEpsilon
Standard k-epsilon turbulence model for incompressible flows.
kOmega
Standard high Reynolds-number k-omega turbulence model for incompressible flows.
kOmegaSST
Implementation of the k-omega-SST turbulence model for incompressible flows.
kOmegaSSTLM
Langtry-Menter 4-equation transitional SST model based on the k-omega-SST RAS model.
kOmegaSSTSAS
Scale-adaptive URAS model based on the k-omega-SST RAS model.
kkLOmega
Low Reynolds-number k-kl-omega turbulence model for incompressible flows.
qZeta
Gibson and Dafa’Alla’s q-zeta two-equation low-Re turbulence model for incompressible flows
realizableKE
Realizable k-epsilon turbulence model for incompressible flows.
v2f
Lien and Kalitzin’s v2-f turbulence model for incompressible flows, with a limit imposed on the
turbulent viscosity given by Davidson et al.
7.2.1.2 Compressible RAS turbulence models
For compressible flows, the RAS model can be chosen from the list below.
LRR
Launder, Reece and Rodi Reynolds-stress turbulence model for compressible flows.
LaunderSharmaKE
Launder and Sharma low-Reynolds k-epsilon turbulence model for compressible and combusting
flows including rapid distortion theory (RDT) based compression term.
RNGkEpsilon
Renormalization group k-epsilon turbulence model for compressible flows.
SSG
Speziale, Sarkar and Gatski Reynolds-stress turbulence model for compressible flows.
SpalartAllmaras
Spalart-Allmaras one-eqn mixing-length model for compressible external flows.
buoyantKEpsilon
Additional buoyancy generation/dissipation term applied to the k and epsilon equations of the
standard k-epsilon model.
kEpsilon
Standard k-epsilon turbulence model for compressible flows including rapid distortion theory
(RDT) based compression term.
kOmega
Standard high Reynolds-number k-omega turbulence model for compressible flows.
kOmegaSST
Implementation of the k-omega-SST turbulence model for compressible flows.
kOmegaSSTLM
Langtry-Menter 4-equation transitional SST model based on the k-omega-SST RAS model.
kOmegaSSTSAS
Scale-adaptive URAS model based on the k-omega-SST RAS model.
realizableKE
Realizable k-epsilon turbulence model for compressible flows.
v2f
Lien and Kalitzin’s v2-f turbulence model for compressible flows, with a limit imposed on the
turbulent viscosity given by Davidson et al.
7.2.2 Large eddy simulation (LES) modelling
If LES is selected, the choice of LES modelling is specified in a LES sub-dictionary which requires
the following entries.
▪ model: name of LES turbulence model.
▪ delta: name of delta model.
▪ <model>Coeffs: dictionary of coefficients for the respective model, to override the default
coefficients.
▪ <delta>Coeffs: dictionary of coefficients for the delta model.
The LES models used in the tutorials can be listed using foamSearch with the following command.
The lists of available models are given in the following sections.
Smagorinsky
The Smagorinsky SGS model.
SpalartAllmarasDDES
SpalartAllmaras DDES turbulence model for incompressible flows
SpalartAllmarasDES
SpalartAllmarasDES DES turbulence model for incompressible flows
SpalartAllmarasIDDES
SpalartAllmaras IDDES turbulence model for incompressible flows
WALE
The Wall-adapting local eddy-viscosity (WALE) SGS model.
dynamicKEqn
Dynamic one equation eddy-viscosity model
dynamicLagrangian
Dynamic SGS model with Lagrangian averaging
kEqn
One equation eddy-viscosity model
kOmegaSSTDES
Implementation of the k-omega-SST-DES turbulence model for incompressible flows.
7.2.2.2 Compressible LES turbulence models
For compressible flows, the LES model can be chosen from the list below.
DeardorffDiffStress
Smagorinsky
The Smagorinsky SGS model.
SpalartAllmarasDDES
SpalartAllmaras DDES turbulence model for compressible flows
SpalartAllmarasDES
SpalartAllmarasDES DES turbulence model for compressible flows
SpalartAllmarasIDDES
SpalartAllmaras IDDES turbulence model for compressible flows
WALE
The Wall-adapting local eddy-viscosity (WALE) SGS model.
dynamicKEqn
Dynamic one equation eddy-viscosity model
dynamicLagrangian
Dynamic SGS model with Lagrangian averaging
kEqn
One equation eddy-viscosity model
kOmegaSSTDES
Implementation of the k-omega-SST-DES turbulence model for compressible flows.
foamInfo wallFunction
Within each wall function boundary condition the user can over-ride default settings for
, and through optional E, kappa and Cmu keyword entries.
Having selected the particular wall functions on various patches in the nut/mut file, the user
should select epsilonWallFunction on corresponding patches in the epsilon field and kqRwallFunction
on corresponding patches in the turbulent fields k, q and R.
7.3 Transport/rheology models
In OpenFOAM, solvers that do not include energy/heat, include a library of models for viscosity
. The models typically relate viscosity to strain rate and are specified by the user in
the transportProperties dictionary. The available models are listed in the following sections.
7.3.1 Newtonian model
The Newtonian model assumes is constant. Viscosity is specified by a dimensionedScalar
nu in transportProperties, e.g.
transportModel Newtonian;
nu [ 0 2 -1 0 0 0 0 ] 1.5e-05;
Note the units for kinematic viscosity are .
where the coefficient has a default value of 2. An example specification of the model
in transportProperties is:
transportModel BirdCarreau;
BirdCarreauCoeffs
{
nu0 [ 0 2 -1 0 0 0 0 ] 1e-03;
nuInf [ 0 2 -1 0 0 0 0 ] 1e-05;
k [ 0 0 1 0 0 0 0 ] 1;
n [ 0 0 0 0 0 0 0 ] 0.5;
}
(7.21)
transportModel CrossPowerLaw;
CrossPowerLawCoeffs
{
nu0 [ 0 2 -1 0 0 0 0 ] 1e-03;
nuInf [ 0 2 -1 0 0 0 0 ] 1e-05;
m [ 0 0 1 0 0 0 0 ] 1;
n [ 0 0 0 0 0 0 0 ] 0.5;
}
(7.22)
transportModel powerLaw;
powerLawCoeffs
{
nuMax [ 0 2 -1 0 0 0 0 ] 1e-03;
nuMin [ 0 2 -1 0 0 0 0 ] 1e-05;
k [ 0 2 -1 0 0 0 0 ] 1e-05;
n [ 0 0 0 0 0 0 0 ] 1;
}
(7.23)
transportModel HerschelBulkley;
HerschelBulkleyCoeffs
{
nu0 [ 0 2 -1 0 0 0 0 ] 1e-03;
tau0 [ 0 2 -2 0 0 0 0 ] 1;
k [ 0 2 -1 0 0 0 0 ] 1e-05;
n [ 0 0 0 0 0 0 0 ] 1;
}
(7.24)
transportModel Casson;
CassonCoeffs
{
m [ 0 2 -1 0 0 0 0 ] 3.934986e-6;
tau0 [ 0 2 -2 0 0 0 0 ] 2.9032e-6;
nuMax [ 0 2 -1 0 0 0 0 ] 13.3333e-6;
nuMin [ 0 2 -1 0 0 0 0 ] 3.9047e-6;
}
transportModel strainRateFunction;
strainRateFunctionCoeffs
{
function polynomial ((0 0.1) (1 1.3));
}