[version 14][version 13][version 12][version 11][version 10][version 9][version 8][version 7][version 6]
4.2 Input/output file format
OpenFOAM needs to read a range of data structures such as strings, words, scalars, vectors, tensors, lists and fields. The input/output (I/O) format of files is extremely flexible, following a consistent set of rules that make the files easy to interpret. The OpenFOAM file format is described in the following sections.
4.2.1 General syntax rules
The format resembles C++ code, following the general principles below.
-
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 mainly uses dictionaries to specify data, in which data entries are retrieved by means of keywords. Each keyword entry follows the general format, beginning with the keyword and ending in semi-colon (;).
<keyword> <dataEntry1> … <dataEntryN>;
<keyword> <dataEntry>;
<dictionaryName>
{
… keyword entries …
}
16 17solvers 18{ 19 p 20 { 21 solver GAMG; 22 tolerance 1e-7; 23 relTol 0.01; 24 25 smoother DICGaussSeidel; 26 27 } 28 29 pFinal 30 { 31 $p; 32 relTol 0; 33 } 34 35 "(U|k|epsilon)" 36 { 37 solver smoothSolver; 38 smoother symGaussSeidel; 39 tolerance 1e-05; 40 relTol 0.1; 41 } 42 43 "(U|k|epsilon)Final" 44 { 45 $U; 46 relTol 0; 47 } 48} 49 50PIMPLE 51{ 52 nNonOrthogonalCorrectors 0; 53 nCorrectors 2; 54} 55 56 57// ************************************************************************* //
4.2.3 The data file header
All data files that are read and written by OpenFOAM begin with a dictionary named FoamFile containing a standard set of keyword entries, listed below:
A example header for a controlDict file is shown below.
FoamFile
{
format ascii;
class dictionary;
location "system";
object controlDict;
}
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 ( ). When a user specifies a list in an input file, e.g. the vertices list in a blockMeshDict file, it just includes the vertices keyword and the data in ( ), e.g.
vertices
(
… entries …
);
When OpenFOAM writes out a list, it invariably prefixes it with the number of elements in the list. For example the points file for the mesh in the pizDailySteady case contains the following (abbreviated) list, where 25012 denotes the number of vertex points in the mesh.
25012
(
(-0.0206 0 -0.0005)
(-0.01901716308 0 -0.0005)
… entries …
);
In some cases, when OpenFOAM writes out a list, it further prefixes it with the class name of the list. For example, the inGroups entry in a boundary file of a mesh contains a list where each group name is a word. The entry for the lowerWall patch from the pizDailySteady case is shown below, indicating the List¡word¿ class with a single (1) element.
lowerWall
{
type wall;
inGroups List<word> 1(wall); // Note!
nFaces 250;
startFace 24480;
}
4.2.5 Scalars, vectors and tensors
A scalar
is a single number represented as such in a data file. A
vector contains three values,
expressed using the simple List format so that the vector
is
written:
(1.0 1.1 1.2)
(1 0 0 0 1 0 0 0 1)
(xx xy xz yx yy yz zx zy zz)
(xx xy xz yy yz zz)
4.2.6 Dimensional units
In science, properties are represented in some
chosen units, e.g. mass in
kilograms (
), volume in cubic metres (
), pressure in Pascals
(
).
Algebraic operations must be performed on these properties using
consistent units of measurement. In particular, addition,
subtraction and equality are only physically meaningful for
properties of the same dimensional units. As a safeguard against
implementing a meaningless operation, OpenFOAM attaches dimensions
to field data and physical properties and performs dimension
checking on any operation.
Dimensions are described by the dimensionSet class which are represented with a unique I/O syntax using square brackets, e.g.
[0 2 -1 0 0 0 0]
-
mass, e.g. kilogram (kg), pound-mass (lbm);
-
length, e.g. metre (m), foot (ft);
-
time, e.g. second (s);
-
temperature, e.g. Kelvin (K), degree Rankine (
R); -
quantity, e.g. mole (mol);
-
current, e.g. ampere (A);
-
luminous intensity, e.g. candela (cd).
Dimensional units can alternatively be specified by name, starting with the base units, named mass, length, time, temperature, moles, current, and luminousIntensity. Dimensional units can be expressed using these names, rather than the array of indices, e.g. dimensions of length can be written
[length]
[sqr(length)/time]
[area/time]
[kinematicViscosity]
foamUnits
foamUnits pressure
Dimension [pressure]
+ Dimensions = [mass length^-1 time^-2]
+ Exponents = [1 -1 -2 0 0 0 0]
+ Standard Units = [kg m^-1 s^-2] [Pa]
+ Other Units = [psi] [atm] [kPa] [bar] [MPa]
Dimensions do not themselves suggest any particular set of units, e.g. SI or USCS. Instead, the set of units is specified in the $FOAM_ETC/configDict by the set keyword in the units sub-dictionary. The default set is SI, with two pre-configured alternatives of CGS (centimetre-gram-second) and USCS. The set choice can be overridden as described in section 4.3 . Indeed, an alternative custom unit set can even be specified, with any defined units, mimicking the syntax in the configDict file.
4.2.7 Units and unit conversion
Numerical parameters can be specified with accompanying units, written using their name contained within square brackets, e.g. “[mm]” for millimetre units. Standard available units are listed by running the foamUnits utility as follows.
foamUnits
inlet
{
type fixedValue;
value uniform (1000 0 0) [cm/s];
}
Units can be applied from a different base set to the only being used. For example, a parameter could be specified in [ft/min], i.e. the USCS feet per second, when the set being used in SI. The example below shows the meanVelocity being specified in this way for the flowRateInletVelocity boundary condition.
inlet
{
type flowRateInletVelocity;
meanVelocity 30 [ft/s];
}
inlet
{
type flowRateInletVelocity;
volumetricFlowRate 0.2 [l/s];
}
While the volumetricFlowRate parameter above is specified by a single value, it is in fact an example of a Function1, which is described in section 6.4.4 (about time-varying boundary conditions). A Function1 is function of one variable; in this case the variable is time, allowing the user to prescribe a flow rate that varies in time. The single value syntax is a shorthand to represent a constant Function1.
There is a wide choice of available functions listed in section 6.4.4 . The volumetricFlowRate could, for example, follow a sine wave with a mean value of 0.15 l/s, amplitude 0.05 l/s and frequency 20 mHz with the following configuration
inlet
{
type flowRateInletVelocity;
volumetricFlowRate
{
type sine;
level 0.15 [l/s];
amplitude 0.05 [l/s];
frequency 0.002 [Hz];
}
}
, for example.
For the table
function, the user specifies values at different values of the
function variable. For example, a table entry that specifies a value
of 0.2 at
0.1 s would be represented as (0.1 0.2) in OpenFOAM format.
Imagine we want the volumetricFlowRate to increase from 0 l/s
at
to 0.2 l/s at
s. This could be achieved using a table with two entries, since the
table function interpolates
values linearly between successive data points, and clamps to the
final value at times beyond the last point. The configuration for
this example, below, shows how the optional units works.
inlet
{
type flowRateInletVelocity;
volumetricFlowRate
{
type table;
units ([ms] [l/s]);
values
(
(0 0)
(100 0.2)
);
}
}
While units are generally associated with dimensioned quantities, the following units that are available to perform conversions between dimensionless quantities.
-
angle: fundamental unit is radian “[rad]” with scaled units of degree “[deg]” and rotations “[rot]”.
-
fractions: fundamentally without units, but can be represented by the scaled unit of percentage “[%]”.
Finally, users can define custom units of their own. To do so, they need to add entries to a configDict, discussed in section 4.3 . Essentially, they should follow the instructions to override global controls in section 4.3.1 in which the sample configDict is copied into their case system directory. They can then add custom units to the units section of that file. Below is an example which creates a niche USCS unit, acre-foot per fortnight “[aff]”, sometimes used in irrigation.
units
{
day 24 [hr];
fortnight 14 [day];
chain 22 [yd];
acre 10 [chain^2];
aff 1 [acre*ft/fortnight];
}
4.2.8 Dimensioned types
Most physical properties are defined with their respective dimensions. They are represented by the dimensioned class which strictly includes three components: a word name; a dimensionSet and a value (scalar, vector, etc.). In the distant past, input files would include entries with all three data entries, but over time the word and dimensionSet components have become hard-coded so that the user only needs to supply the value to be read at input.
Since OpenFOAM v14, there are no example cases
with the older input syntax, so the basic input syntax is shown
below for parameters for density
and kinematic viscosity
.
rho 1000;
nu 1e-5;
rho 1000 [kg m^-3];
nu 1e-5 [m^2/s];
, with the
reassurance that the chosen units are appropriate for the given
parameter.
nu 10 [cSt];
4.2.9 Fields
Field files, e.g. U and p, that are read from and written into the time directories, possess their own customised I/O with the following key entries.
-
dimensions: the dimensions of the field, e.g. [pressure] (or [1 -1 -2 0 0 0 0]).
-
internalField: values within the internal field, e.g. within each cell of a mesh.
-
boundaryField: condition (type) and data for each patch of the mesh boundary.
-
sources, optional (usually not used): field values required when a fluid mass (or volume) source is introduced internally, rather than at a boundary, see section 6.2 .
cThis section provides an overview of the basic syntax of the internalField and boundaryField entries in field files. The details of field initialisation, sources and boundary conditions are then presented in Chapter 6 .
For the internalField, there are three way it can be specified, listed below.
-
uniform: typically for initialisation, the field is uniform so can be described by a single value.
-
nonuniform: typically for results that are written out, a list of values in specified, one value for each element of the field.
-
field function: used to initialise a nonuniform field, as described in section 6.1 .
An example of a uniform field, e.g. to initialise kinematic pressure (p), is shown below. The uniform value is 100000 and follows the uniform keyword.
internalField uniform 100000;
internalField uniform 1 [bar];
When results are written out, the field is non-uniform with different values for each element (i.e. cells or faces). The output then uses the nonuniform keyword, followed by a suitable list of values. The abbreviated example below is from an output p file for a mesh of 12225 cells.
internalField nonuniform List<scalar>
12225
(
-4.92806
-5.42676
...
);
The boundaryField is a dictionary containing a set of entries corresponding to each patch listed in the mesh boundary, described in section 5.3 . Each entry in boundaryField is itself a sub-dictionary containing a list of keyword entries, beginning with the mandatory type entry which specifies the patch field condition for the field. Additional keyword entries are then generally required, corresponding to the specified type. They can include field data to specify a property on each patch face, that require the uniform/nonuniform syntax described above.
A selection of patch field conditions in OpenFOAM are described in sections 6.3 , 6.4 , 6.5 and 6.6 . The selection is by no means exhaustive; rather a complete list of boundary conditions can be printed using the foamToC utility (see section 4.7.6 ) with the -scalarBCs and -vectorBCs options, i.e.
foamToC -scalarBCs
foamToC -vectorBCs
A example field file for velocity U, containing simple entries for dimensions, internalField and boundaryField, is shown below:
16 17dimensions [velocity]; 18 19internalField uniform (0 0 0); 20 21boundaryField 22{ 23 inlet 24 { 25 type fixedValue; 26 value uniform (10 0 0); 27 } 28 29 outlet 30 { 31 type zeroGradient; 32 } 33 34 upperWall 35 { 36 type noSlip; 37 } 38 39 lowerWall 40 { 41 type noSlip; 42 } 43 44 frontAndBack 45 { 46 type empty; 47 } 48} 49 50// ************************************************************************* //
4.2.10 Macro expansion
The configuration of case files can benefit from a macro syntax which uses the dollar ($) symbol in front of a keyword to expand the data associated with the keyword. The keyword can relate to any type of entry, e.g. in the following example, grad(U) expands to “cellLimited Gauss linear 1”.
limited cellLimited Gauss linear 1;
grad(U) $limited;
ddtSchemes
{
default Euler;
}
timeScheme $ddtSchemes/default;
xMin -10;
yMin $xMin;
xMax #neg $xMin;
There are further syntax rules for macro expansions:
-
to traverse up one level of sub-dictionary, use the ‘..’ (double-dot) prefix, see below;
-
to traverse up two levels use ‘../..’ prefix, etc.;
-
to traverse to the top level dictionary use the ‘!’ (exclamation mark) prefix (most useful), see below;
-
to traverse into a separate file named otherFile, use ‘otherFile!’, see below;
-
for multiple levels of macro substitution, each specified with the ‘$’ dollar syntax, ‘{}’ brackets are required to protect the expansion, see below.
When accessing parameters from another file, the $FOAM_CASE environment variable is useful to specify the path to the file as described in section 4.2.12 and illustrated below.
a 10;
b a;
c ${$b}; // returns 10, since $b returns "a", and $a returns 10
subdictA
{
a 20;
}
subdictB
{
// double-dot takes scope up 1 level, then into "subdictA" => 20
b $../subdictA/a;
subsubdict
{
// exclamation mark takes scope to top level => 10
b $!a;
// "a" from another file named "otherFile"
c $otherFile!a;
// "a" from another file "otherFile" in the case directory
d ${${FOAM_CASE}/otherFile!a};
}
}
4.2.11 Including files
Directives are commands that begin with the hash (#) symbol which provide further flexibility when configuring case files. There is a set of directive commands for reading a data file from within another data file. If a case requires a single value of pressure of 100 kPa, used in different input files, we could create a file, e.g. named initialConditions, which contains the following entry:
pressure 1e+05;
In order to use this pressure for internal and initial boundary fields, the user could simply include the initialConditions file using the #include directive, then use a macro expansion on the pressure keyword, as follows.
#include "initialConditions"
internalField uniform $pressure;
boundaryField
{
patch1
{
type fixedValue;
value $internalField;
}
}
#include "$FOAM_CASE/constant/initialConditions"
The #include directives can be called with arguments contained in brackets "(…)". They can include parameters using the syntax <parameter>=<value> that are specifically used in macro expansions only. For example if a main contains the following entries,
rhoInf $rho;
UInf $U;
#include "main"(rho=1.2,U=25)
There are then three specialised include directives for functionObjects, fvModels and fvConstraints.
-
#includeFunc: reads a file containing a single functionObject configuration, first searching the case system directory, followed by the $FOAM_ETC directory.
-
#includeModel: reads a file containing a single fvModel configuration, first searching the case constant directory, followed by the $FOAM_ETC directory.
-
#includeConstraint: reads a file containing a single fvConstraint configuration, first searching the case system directory, followed by the $FOAM_ETC directory.
These directives can also be called with arguments contained in brackets "(…)". However, the arguments are treated differently from the previous directives. For the specialised directives, <parameter>=<value> arguments simply add or modify a keyword entry <parameter>, assigning the <value>.
Function arguments are used extensively with the specialised include directives. The following grep command lists several files in the example cases that demonstrate this.
grep -rl '#includeFunc.*(' $FOAM_TUTORIALS
4.2.12 Environment variables
Environment variables can be used 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/pitzDailySteady/0/U"
In addition to environment variables like $FOAM_RUN, set within the operating system, a number of “internal” environment variables are recognised, including the following.
4.2.13 Regular expressions
As discussed, data is looked up from files using keywords. If a particular keyword does not exist, the I/O system will try to match the keyword with any POSIX regular expression, specified inside double-quotations ("…") in the input file.
In some cases, when the I/O system searches for a keyword in a case file, a can be used to match the keyword
When running an application, data is initialised by looking up keywords from dictionaries. The user can either provide an entry with a keyword that directly matches the one being looked up, or can provide a that matches the keyword, specified inside double-quotations ("…").
Regular expressions have an extensive syntax for various matches of text patterns but in OpenFOAM input files there are only two expressions that are generally used. Firstly, ‘.’ denoting “any character”, and ‘*’ denoting “repeated any number of times, including 0 times” is often used in combination to match “any characters”. For example, to specify a noSlip boundary condition for any patch whose name ends Wall…, the user could specify in the boundaryField for U:
".*Wall"
{
type noSlip;
}
"(upper|lower)"
{
type noSlip;
}
4.2.14 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.
4.2.15 Inline calculations
There are further directives that enable calculations from within input files:
-
#stream, for multi-statement calculations, also described below;
-
#codeStream, for complex multi-statement calculations, described in section 4.2.17 ;
-
#codeDict, for creating multiple dictionary entries, described in section 4.2.18 .
In the descriptions above, the term “statement” means a code statement, i.e. one piece of code ending in “;”. It can be thought of as “line”, but a single statement can be split over multiple lines, so “statement” is more precise. Examples of the use of these directives can be found in files in the test/dictionary directory in the OpenFOAM installation.
The #calc directive is used for simple one-line calculations, typically to set a parameter in an input file. An example is found at the beginning of the 0/U in the $FOAM_TUTORIALS/incompressibleFluid/drivaerFastback case.
Uinlet 16;
wheelRadius 0.318;
wheelBase 2.786;
wheelSpeed #calc "$Uinlet / $wheelRadius";
Care is required with calculations involving a division because the “/” character is otherwise used to identify keywords in sub-dictionaries, "$a/b" looks for a keyword b within a sub-dictionary named a. Where a division is required, the user can put spaces around the /, e.g.
a 3.0;
b 2.0;
c #calc "$a / $b";
c #calc "${a}/$b";
For example, the following code calculates
using #calc.
a (1 2 3);
b (1 1 0);
c #calc "$<vector>a & $<vector>b";
a 3;
b 2;
c #calc "$a / $b"; // c = 1, since a and b are integers
a 3;
b 2;
c #calc "$a / $<scalar>b";
c #calc "$<scalar>a / $b";
c #calc "$<scalar>a / $<scalar>b";
nu 10 [cSt];
rho 1000 [kg/m^3];
mu #calc "$<scalar>nu*$<scalar>rho";
// mu #calc "$nu*$rho"; // will not compile
The hash-bracket delimiters, #{…#};, (instead of "…") have the advantages that: a) they support code written across multiple lines; and, b) they avoid problems with string typed variables that may contain quotation marks as in the example below.
s "field";
fieldName #calc
#{
$<string>s + "Name"
#};
os << value;
a (1 2 3);
b (1 1 0);
c #stream
#{
Info<< "Calculating c = " << dict.lookup<vector>("a")
<< " & " << dict.lookup<vector>("b") << endl;
os << ($<vector>a & $<vector>b);
#};
Calculating c = (1 2 3) & (1 1 0)
4.2.16 Multiple inline code entries with #codeBlock
When code is included in an input file, using directives such as #calc and #stream, the code is compiled dynamically into a shared-object library at run-time, which is linked to the running application. The code is written and compiled in a local directory named dynamicCode containing sub-directories for each compiled library. The sub-directory / library names for #calc and #stream code are created using a SHA (secure hash algorithm) string of hexadecimal characters prefixed with an underscore, e.g. _11de73e6b530658843ed2ff917b9c23fc98ab0e7.
The complied code can be found within those directories. The code begins as template files, copied from $FOAM_ETC/codeTemplates. The code written in code blocks, e.g. inside #{…#};, in the input file is then injected into relevant locations within the copied template files. Once copied, the files are compiled.
Normally, an individual library is created by each directive. In some cases, there may be a large number of directives, so generating an individual library for each one can be cumbersome. Instead, to generate a single library, the entries can be placed between a #codeBlock and #endCodeBlock directive. The $FOAM_TUTORIALS/incompressibleFluid/venturiTube example case uses #codeBlock in the system/blockMeshDict file to wrap 8 #calc directives into a single library, as shown below. When generating the mesh for this case, it is clear that only one library is generated.
#codeBlock
radIn #calc "$diameter / 2.0";
boxIn #calc "3.0*$<scalar>radIn / 10.0";
radVen #calc "$<scalar>radIn / 2.0";
boxVen #calc "$<scalar>boxIn / 2.0";
xInSt 0;
xInEnd $diameter;
xVenSt #calc "$<scalar>xInEnd + 1.25*$diameter";
xVenEnd #calc "$<scalar>xVenSt + 0.5*$diameter";
xOutSt #calc "$<scalar>xVenEnd + 2.5*$diameter";
xOutEnd #calc "$<scalar>xOutSt + $diameter";
#endCodeBlock
If the code requires a header file that is not included as standard, it can be included by the #codeInclude directive, which is available withing #codeBlock…#endCodeBlock. Multiple #codeInclude entries are permitted when more than one addition header file is required.
The $FOAM_TUTORIALS/fluid/aerofoilNACA0012Steady example demonstrates this, where the inlet velocity is calculated using an angle of attack using the code below. It uses the transform function from the transform.H header file, to rotate unit vectors by the angle of attack to set the lift and drag directions.
speed 250;
angleOfAttack 5 [deg];
#codeBlock
#codeInclude "transform.H"
angle #calc "$<scalar>angleOfAttack" // unit converted
liftDir #calc "transform(Ry(-$angle), vector(0, 0, 1))";
dragDir #calc "transform(Ry( $angle), vector(1, 0, 0))";
Uinlet #calc "$speed*$<vector>dragDir";
#endCodeBlock
4.2.17 Inline code with #codeStream
The #codeStream directive is like #stream in that: a) it is designed to perform calculations involving more than one code statement; and, b) the resulting calculation is streamed to os, the reference to the Ostream.
But in addition to this, the code in #codeStream is written into a special code block that uses the hash-bracket delimiters, as shown below.
#codeStream
{
code
#{
// ... code here ...
os << value;
#};
}
-
codeInclude: specifies additional C++ #include statements to include code files.
-
codeOptions: specifies any extra compilation flags to be added to EXE_INC in Make/options.
-
codeLibs: specifies any extra compilation flags to be added to LIB_LIBS in Make/options.
All the code blocks are written with hash-bracket delimiters. It is possible to create an empty set of optional code blocks, as shown below, when writing to write a #codeStream entry.
codeInclude
#{
#};
codeOptions
#{
#};
codeLibs
#{
#};
foamFind IOobject.H -coded system/blockMeshDict
codeInclude
#{
#include "IOobject.H"
#};
codeOptions
#{
-I$(LIB_SRC)/finiteVolume/lnInclude
#};
codeLibs
#{
-lfiniteVolume
#};
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 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.18 Inline code with #codeDict
The last of the code-related conditionals is #codeDict. It is broadly similar to #codeStream, with a main code block and optional codeInclude, codeOptions and codeLibs blocks. However, there is one main difference. Instead of streaming values to os (the Ostream), #codeDict is able to add and modify dictionary entries through a non-const reference dict to the dictionary.
Below is an example with #codeDict.
nu 10 [cSt];
rho 1000 [kg/m^3];
#codeDict
{
code
#{
dict.add
(
"mu",
dict.lookup<scalar>("nu")*dict.lookup<scalar>("rho")
);
#};
}
#endCodeBlock
4.2.19 Conditionals
Input files support two conditional directives:
-
#if (…) …#elif (…) …#else …#endif
-
#ifeq (…) …#else …#endif
Note: the syntax for the #if conditional changes in OpenFOAM v14, using (…) to delimit the condition. The condition is something which returns a Boolean (true/false). This is generally provided by some code executed by a #calc directive.
Conditionals are particularly useful in the control files for schemes and solvers/algorithms, fvSchemes and fvSolution respectively, since they can provide different settings based on some condition. A purely hypothetical example for the #if directive is below, where the default Laplacian scheme is different based on the non-orthogonality angle of a face.
laplacianSchemes
{
#if (#calc "$angle < 75")
default Gauss linear corrected;
#else
default Gauss linear limited corrected 0.5;
#endif
}
divSchemes
{
#ifeq ($!ddtSchemes/default steadyState)
div(phi,U) bounded Gauss linearUpwind limited;
turbulence bounded Gauss limitedLinear 1;
#else
div(phi,U) Gauss linearUpwind limited;
turbulence bounded Gauss limitedLinear 1;
#endif
...
}
4.2.20 Checking input parameters
The following three directives help a user check their input parameters.
-
#dump: prints the dictionary (file) contents preceding the directive.
-
#print: prints the dictionary (entire file or sub-dictionary) including all default entries.
-
#exit: causes the application to stop at the point it is read.
A example of the use of #dump and #exit is as follows. Imagine a user is creating a mesh with blockMesh with a parameterised blockMeshDict file, like the one in the $FOAM_TUTORIALS/incompressibleFluid/venturiTube example case. The file (in the system directory) contains a lot of calculated parameters like those beginning
diameter 0.1;
#codeBlock
radIn #calc "$diameter / 2.0";
boxIn #calc "3.0*$<scalar>radIn / 10.0";
...
...
boxInN #neg $boxIn;
radVenN #neg $radVen;
boxVenN #neg $boxVen;
#dump
#exit
vertices
(
...
blockMeshDict
{
diameter 0.1;
radIn 0.05;
boxIn 0.015;
...
...
boxInN -0.015;
radVenN -0.025;
boxVenN -0.0075;
}
The #print directive is extremely useful for revealing default parameters used in a dictionary. A common use of this is revealing the coefficients of a turbulence model. For example, in a case, e.g. $FOAM_TUTORIALS/incompressibleFluid/pitzDaily, the user could add #print to the entire file or within the RAS sub-dictionary. In the latter case, e.g.
simulationType RAS;
RAS
{
model kEpsilon;
turbulence on;
viscosityModel Newtonian;
}
Selecting RAS turbulence model kEpsilon
Selecting generalised Newtonian model Newtonian
constant/momentumTransport!RAS
{
model kEpsilon;
turbulence on;
viscosityModel Newtonian;
/* defaults */
Cmu 0.09;
C1 1.44;
C2 1.92;
C3 0;
sigmak 1;
sigmaEps 1.3;
}
PIMPLE
{
residualControl
{
p 1e-6;
U 1e-5;
"(k|omega|h)" 1e-5;
}
nNonOrthogonalCorrectors 0;
}
system/fvSolution!PIMPLE
{
residualControl
{
p 1e-06;
U 1e-05;
"(k|omega|h)" 1e-05;
}
nNonOrthogonalCorrectors 0;
/* defaults */
models true;
thermophysics true;
flow true;
momentumPredictor true;
transonic false;
consistent false;
nCorrectors 1;
moveMeshOuterCorrectors false;
simpleRho true;
transportPredictionFirst true;
transportCorrectionFinal true;
}

