OpenFOAM needs to read a range of data structures such as strings,
scalars, vectors, tensors, lists and fields. The input/output (I/O) format of
files is designed to be extremely flexible to enable the user to modify the
I/O in OpenFOAM applications as easily as possible. The I/O follows a
simple set of rules that make the files extremely easy to understand, in
contrast to many software packages whose file format may not only be
difficult to understand intuitively but also not be published anywhere. The
description of the OpenFOAM file format is described in the following
sections.
OpenFOAM uses dictionaries as the most common means of specifying data.
A dictionary is an entity that contains as set data entries that can be retrieved by
the I/O by means of keywords. The keyword entries follow the general format
<keyword><dataEntry1> ...<dataEntryN>;
Most entries are single data entries of the form:
<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 the the entries enclosed in curly braces {} as follows
All data files that are read and written by OpenFOAM begin with a dictionary
named FoamFile containing a standard set of keyword entries, listed in 4.1.
Keyword
Description
Entry
version
I/O format version
2.0
format
Data format
ascii / binary
location
Path to the file, in "..."
(optional)
class
OpenFOAM class constructed from the
data file concerned
typically dictionary or a
field, e.g.volVectorField
object
Filename
e.g.controlDict
Table 4.1:
Header keywords entries for data files.
The table provides brief descriptions of each entry, which is probably sufficient
for most entries with the notable exception of class. The class entry
is the name of the C++ class in the OpenFOAM library that will be
constructed from the data in the file. Without knowledge of the underlying code
which calls the file to be read, and knowledge of the OpenFOAM classes,
the user will probably be unable to surmise the class entry correctly.
However, most data files with simple keyword entries are read into an internal
dictionary class and therefore the class entry is dictionary in those
cases.
The following example shows the use of keywords to provide data for a case
using the types of entry described so far. The extract, from an fvSolution
dictionary file, contains 2 dictionaries, solvers and PISO. The solvers dictionary
contains multiple data entries for solver and tolerances for each of the pressure
and velocity equations, represented by the p and U keywords respectively; the
PISO dictionary contains algorithm controls.
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:
simple
the keyword is followed immediately by round braces
<listName> ( ... entries ... );
numbered
the keyword is followed by the number of elements <n> in the list
<listName> <n> ( ... entries ... );
token identifier
the keyword is followed by a class name identifier Label<Type>
where <Type> states what the list contains, e.g. for a list of scalar elements
is
Note that <scalar> in List<scalar> is not a generic name but the actual text that
should be entered.
The simple format is a convenient way of writing a list. The other formats
allow the code to read the data faster since the size of the list can be allocated to
memory in advance of reading the data. The simple format is therefore preferred
for short lists, where read time is minimal, and the other formats are preferred for
long lists.
A scalar is a single number represented as such in a data file. A vector is a
VectorSpace of rank 1 and dimension 3, and since the number of elements is
always fixed to 3, the simple List format is used. Therefore a vector
is written:
(1.0 1.1 1.2)
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, described in ?? of the Programmer’s Guide, can be written:
( 1 0 0 0 1 0 0 0 1 )
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:
In continuum mechanics, 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 tensor
operation.
The I/O format for a dimensionSet is 7 scalars delimited by square brackets,
e.g.
[0 2 -1 0 0 0 0]
No.
Property
SI unit
USCS unit
1
Mass
kilogram (kg)
pound-mass (lbm)
2
Length
metre (m)
foot (ft)
3
Time
-- -- -- -- second (s) -- -- -- --
4
Temperature
Kelvin (K)
degree Rankine (R)
5
Quantity
kilogram-mole (kgmol)
pound-mole (lbmol)
6
Current
-- -- -- -- ampere (A) -- -- -- --
7
Luminous intensity
-- -- -- -- candela (cd) -- -- -- --
Table 4.2:
Base units for SI and USCS
where each of the values corresponds to the power of each of the base units of
measurement listed in 4.2. 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.
Physical properties are typically specified with their associated dimensions.
These entries 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.
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 4.3.
Keyword
Description
Example
dimensions
Dimensions of field
[1 1 -2 0 0 0 0]
internalField
Value of internal field
uniform (1 0 0)
boundaryField
Boundary field
see file listing in 4.2.8
Table 4.3:
Main keywords used in field dictionaries.
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 compulsory 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 5.2 and 5.3 with a description and the data that must be
specified with it. Example field dictionary entries for velocity U are shown
below:
There is additional file syntax that offers great flexibility for the setting
up of OpenFOAM case files, namely directives and macro substitutions.
Directives are commands that can be contained within case files that begin
with the hash (#) symbol. Macro substitutions begin with the dollar ($)
symbol.
At present there are 2 directive commands available in OpenFOAM:
#include "<fileName>"
reads the file of name <fileName>;
#inputMode
has two options: merge, which merges keyword entries in
successive dictionaries, so that a keyword entry specified in one place
will be overridden by a later specification of the same keyword entry;
overwrite, which overwrites the contents of an entire dictionary;
generally, use merge.
For example, let us say a user wishes to set an initial value of pressure once to
be used as the internal field and initial value at a boundary. We could create a
file, e.g. named initialConditions, which contains the following entries:
pressure 1e+05; #inputMode merge
In order to use this pressure for both the internal and initial boundary fields,
the user would simply include the following macro substitutions in the pressure
field file p:
#include "initialConditions" internalField $pressure boundaryField { patch1 { type fixedValue; value $pressure; } }
This is a fairly trivial example that simply demonstrates how this functionality
works. However, the functionality can be used in many, more powerful
ways particularly as a means of generalising case data to suit the user’s
needs. For example, if a user has a set of cases that require the same
RAS turbulence model settings, a single file can be created with those
settings which is simply included in the RASProperties file of each case.
Macro substitutions can extend well beyond a singe value so that, for
example, sets of boundary conditions can be predefined and called by a
single macro. The extent to which such functionality can be used is almost
endless.