OpenFOAM® v1812: New and improved usability

OpenFOAM® v1812: New and improved usability


Updated co-ordinate systems

Coordinate systems have received an overhaul to make them easier to use and much more versatile.

A local coordinate system is simply a location and orientation in space, combined with information about how values are to be interpreted e.g., cartesian, cylindrical, etc.. but this simplicity was lost in previous versions.

The restructured code makes it easier to add your own specification with a cleaner, less cluttered dictionary specification.

In many cases, a cartesian coordinate is required and its axes are known. In this case the specification is quite compact:

    origin  (0 0 0);
    e2      (0 1 0);
    e3      (0.5 0 0.866025);

However, a more descriptive specification is also available for more complex situations. For example

    type    cylindrical;
    origin  (0 0 0);
        type    axisAngle;
        axis    (0 1 0);
        angle   30;
Within the code we now distinguish between coordinate systems with uniform and non-uniform transformations. A cylindrical coordinate system is an example of a non-uniform transformation, since the rotation matrix is position-independent. This is now accommodated within the coordinate system classes. Position-dependent forward and reverse are now supported, e.g.

outputVector = cs.transform(globalPoint, inputVector);
This is also supported for the transformation of multiple points and values. However, in some circumstances it may be more convenient or more efficient to handle uniform and non-uniform transformations differently. For example,

if (cs.uniform())
    // A single input and a single output
    vector xx = cs.transform(someVector);
    // Non-uniform, so the transformed vector is different for each position
    List<vector> xx = cs.transform(manyPoints, someVector);

Further updates include:

  • The coordinate system transform and invTransform methods now include standard OpenFOAM data types, e.g.scalar, vector, tensor
  • New rotation specification none (an identity rotation)
  • New rotation specification axisAngle, which corresponds to the transformPoints -rotate-angle option. For some cases this can be more intuitive.
  • New shorter names for the existing coordinate rotation specifications; earlier names are supported for backwards compatibility:
    New name Old name
    axes axesRotation
    euler EulerRotation
    starcd STARCDRotation

The updated functionality is used to support local coordinate systems in the new PatchFunction1 class.

Source code

New environment controls

One of the changes that we’ve made in OpenFOAM-v1812 is to alter how we treat the concept of an OpenFOAM version. Until now, we have simply registered this information in the variable within the etc/bashrc and etc/cshrc files and used this value thereafter.

For example, with the following type of entries:

The expected directory names for OpenFOAM and ThirdParty would look like this:

    |-- OpenFOAM-v1812
    - ThirdParty-v1812
And discovery of user configuration (etc) files would follow this same WM_PROJECT_VERSION value.


But what happens in a few months time, when you have patched your version with the latest bug-fix. How do you go about documenting this?

One approach might be to change the version name to reflect the changes. For example,

export WM_PROJECT_VERSION=v1812.update01

But this causes the immediate difficulty that the directory names also need to change:

    |-- OpenFOAM-v1812.update01
    - ThirdParty-v1812.update01
However the real annoyance is with user files, since the change in WM_PROJECT_VERSION means that OpenFOAM is now examining different locations:


Some of these problems can be managed with symbolic links, or some other cleverness. But it makes much more sense to simply change how OpenFOAM treats to meet our requirements and to solve many of these annoyances without requiring workarounds.

The new ground rules

The base level of an OpenFOAM version is now dictated by its API level, which corresponds exactly to the 4-digit numerical value of the OPENFOAM compilation define as given in the OpenFOAM wmake rules. This value is defined for each major release, e.g., 1806, 1812, etc..

This API information is supplemented by a patch level. A release is by definition unpatched, and thus carries a patch value of 0. Any patches thereafter will be recorded in the patch level. The patch level is informative and does not influence how files are found.

With the shipped OpenFOAM-v1812 version, this changes will not be immediately obvious since no changes are required for the user.

This means that file settings are the same,

And the directory names for OpenFOAM and ThirdParty look the same:

|-- OpenFOAM-v1812
- ThirdParty-v1812
However the user configuration files now follow the API value instead of the WM_PROJECT_VERSION value. Which means that an API-versioned directory will be used instead of the older system that relied on the version name:

A closer look may be required to notice the subtle change from v1812 to 1812 in the directory name. However, if we decide to use the same approach as previously shown, we can quickly see the effect of these changes.

Again we’ll decide for some version name that is meaningful for us:

export WM_PROJECT_VERSION=v1812swak
But otherwise not change anything else. The directory names do not need to change:

|-- OpenFOAM-v1812
- ThirdParty-v1812
And since the API is the same, the user files locations are unchanged:


How do I know which version I am currently using?

In previous versions you would probably just use the WM_PROJECT_VERSION environment value, or the build-time information embedded into an application. For example, as displayed from blockMesh -help:

Using: OpenFOAM-v1806.update01 (see
Build: v1806.update01-6592c67716d3
Arch:  "LSB;label=32;scalar=64"
From this information we can guess (or hope) that this is using the 1806 API-level, since those values happen to appear somewhere in the version or build naming.

With the new versioning, the API level becomes part of the build information, as does the current patch level. For the purpose of explanation, imagine reading this document some other time in the future after this version of OpenFOAM has been patched several times. This would be the type of information that blockMesh -help would then display:

Using: OpenFOAM-v1812swak (1812) (see
Build: afadff77f-20181219 (patch=20190401)
Arch:  LSB;label=32;scalar=64

This output contains all of the more interesting information that we need:

item value
version v1812swak
api 1812
commit afadff77f
author date 20181219
patch-level 20190401

As can be seen in this example, the git build information is supplemented by the date when the change was authored, which can be helpful when the repository contains local changes.

If you simply wish to know what the current API and patch levels are, the foamEtcFile script or the new wmakeBuildInfo script can be used with either the -show-api or the -show-patch option. For example,

$ foamEtcFile -show-api

$ foamEtcFile -show-patch
The WM_PROJECT_API environment variable is also defined, but this is for convenience only and may not reflect patching changes made within the currently active environment.

Programmer’s note: The API and build information are accessible internally via variables and methods within the new Foam::foamVersion namespace.

How are things now found?

The name of the OpenFOAM directory is now freely selectable, which means that certain environment variables (FOAM_INST_DIR, WM_PROJECT_INST_DIR) are not required and have no meaning.

The freely selectable directory name and its independence from the value of $WM_PROJECT_VERSION means that you can now safely use interesting combinations. For example:

which is installed as /some/path/openfoam-sandbox1812 with the usual OpenFOAM directory structure:

- openfoam-sandbox1812
    |-- applications
    |-- bin
    |-- doc
    |-- etc
    |   |-- etc/bashrc
    |   - etc/cshrc
    |-- platforms
    |-- src
    - wmake

When this type of flexible naming is possible, the natural question arises as to how the ThirdParty directory is to be found.

ThirdParty directory

OpenFOAM normally ships with a directory of 3rd-party software and build scripts for some 3rd-party software that is either necessary or at least highly useful for OpenFOAM, but which are not necessarily readily available on every operating system or cluster installation.

These 3rd-party sources are normally located in a directory parallel to the OpenFOAM directory. For example,

|-- OpenFOAM-v1812
- ThirdParty-v1812

There are, however, many cases where this simple convention is inadequate:

  • When no additional 3rd party software is actually required (ie, the operating system or cluster installation provides it)
  • When we have changed the OpenFOAM directory name to some arbitrary directory name, e.g. openfoam-sandbox1812, etc..
  • When we would like any additional 3rd party software to be located inside of the OpenFOAM directory to ensure that the installation is encapsulated within a single directory structure. This can be necessary for cluster installations, or may simply be a convenient means of performing a software rollout for individual workstations.
  • When we have many different OpenFOAM directories for testing or developing various different features but wish to use or reuse the same 3rd party software for them all.

The solution for these problems is a newer, more intelligent discovery when locating the ThirdParty directory with the following precedence:

  1. PROJECT/ThirdParty
    • for single-directory installations
  2. PREFIX/ThirdParty-VERSION
    • this corresponds to the traditional approach
  3. PREFIX/ThirdParty-vAPI
    • allows for an updated value of VERSION, e.g., v1812-myCustom, without requiring a renamed ThirdParty. The API value would still be ’1812’ and the original ThirdParty-v1812/ would be found.
  4. PREFIX/ThirdParty-API
    • this is the same as the previous example, but using an unadorned API value. This also makes sense if the chosen version name also uses the unadorned API value in its naming, e.g., 1812-patch190131, 1812.19W03
  5. PREFIX/ThirdParty-common
    • permits maximum reuse for various versions, but only for experienced user who are aware of potential version incompatibilities

If none of these directories are found to be suitable, it reverts to using PROJECT/ThirdParty as a dummy location (even if the directory does not exist). This is a safe fallback value since it is within the OpenFOAM directory structure and can be trusted to have no negative side-effects.

In the above, the following notation has been used:

name value meaning
PREFIX dirname $WM_PROJECT_DIR The OpenFOAM parent directory
API foamEtcFiles -show-api The api or release version
VERSION $WM_PROJECT_VERSION The version we’ve chosen

To reduce the potential of false positive matches (perhaps some other software also uses ThirdParty-xxx for its naming), the directory test is accompanied by a OpenFOAM-specific sanity test. The OpenFOAM ThirdParty directory will contain either a Allwmake file or a platforms/ directory.

Working in groups

When an OpenFOAM cluster installation is being used by several different people or interest groups it can be highly interesting to share common setups or custom libraries and applications. This is where the OpenFOAM site (group) configuration can be quite helpful.

The directory location of OpenFOAM site settings is defined by the WM_PROJECT_SITE environment variable. If this is undefined, the default is to use PROJECT/site (ie, a site directory located within the OpenFOAM directory). In previous versions PREFIX/site was used as a fall-back, but this conflicts with most cluster packaging requirements.

Within this $WM_PROJECT_DIR directory, we can use a directory structure that mirrors elements of the OpenFOAM directory structure, but which also includes a degree of versioning as well:

|-- API
|   |-- bin
|   - etc
|   - platforms
|       |-- bin
|       - lib
|-- bin
- etc

Useful OpenFOAM-related scripts can be placed in the bin directory. If the script can only work with a particular OpenFOAM version, it then makes sense to place it into the API/bin directory accordingly.

Similarly, if particular configurations or setups are useful for several people, it makes sense to locate them centrally as a site (or group) resource. For example,

- etc
    |-- caseDicts
        |-- openmpi
        - paraview
for some jointly useful caseDicts and suitable configurations for openmpi, paraview.

The foamEtcFile -list option provides a good overview of which locations will be searched for configuration files, which uses the following precedence:

  • user:
    • $HOME/.OpenFOAM/API
    • $HOME/.OpenFOAM
  • group:
  • other:
    • WM˙PROJECT˙DIR/etc

If applications and libraries are to be shared within a group, a typical approach is that one person is in charge of administering the the internal code releases. They would compile the code in their normal user directories, which means that it would normally have the user destinations:

For distribution at the group level, these files would be synchronized to the corresponding group directories:


Making changes to the configuration

The first encounter with the OpenFOAM configuration files can be somewhat intimidating. There are indeed quite a few different bits of software related to using OpenFOAM, each of which could be available in different preferred versions, in different possible locations and with different conventions for naming their library directories. Additionally it should allow individual users to make their own configuration choices. Supporting cshell variants for everything adds yet more files to the mix.

Fortunately, the user often only needs to make a few simple changes and can ignore most of the details and we also provide a foamConfigurePaths tool to make multiple common changes directly from the command line.

The configuration files generally contain detailed information about which values they expect, and the user editable part is also clearly marked as such. For example,

# USER EDITABLE PART: Changes made here may be lost with the next upgrade



Nonetheless, before making changes it can be useful to understand where these changes should actually be made (and why). To simplify things, we only discuss POSIX (bash), but most points apply to cshell variants as well.

  1. The main entry point for the OpenFOAM configuration is the etc/bashrc. The initial portion of the file establishes the version and contains some script ”magic” to help us determine where the OpenFOAM directory is located.

    The balance of the file contains some general OpenFOAM-specific settings, which you can use for guidance but in general you should note the following:

    • Changes made to this bashrc file may be lost with the next upgrade
    • Should override via <> file instead of editing this file
  2. The etc/bashrc file (which was our entry point) passes control to the etc/ file, which dispatches the rest of the configuration actions.

The setup of the OpenFOAM environment can be described in terms of a processing tree:

source etc/bashrc  [args]
       |-- constants
       |-- directory discovery magic
       |-- defaults
       |-- define OpenFOAM directory
       - setup
           |-- discovery of ThirdParty locations
           |-- admin overrides ( file)
           |-- user overrides ( file)
           |-- user overrides (arguments)
           |-- settings (compiler, os)
           |-- mpi
           |-- paraview
           |-- mesa / vtk
           |-- boost / CGAL mpi
           |-- scotch
           |-- FFTW
           - aliases

And most locations in this process it is possible for the user to influence the values used by providing an alternative version of the file. For example, simply creating the file $HOME/.OpenFOAM/ will cause it to be found by the foamEtcFile mechanism during sourcing (see foamEtcFile -list for a reminder of which directories is will search).

Most fairly permanent changes that affect the base configuration of OpenFOAM itself (choice of compiler, mpi, data sizes, etc) should normally be defined in the file. These type of changes are important enough that they receive special treatment.

  1. use the base or admin file if available as PROJECT/etc/ This provides the system admin a reliable location to define site-wide settings, such as for compiler and vendor-specific MPI libraries.
  2. use the user or group if it exists.

For quick or temporary changes, the special interpretation of arguments when sourcing the etc/bashrc are quite convenient. This mechanism allows direct setting of variables without needing to edit any files. For example, to source the OpenFOAM environment with a different compiler:

source /path/to/OpenFOAM-v1812  WM_COMPILER=Clang

If the argument does not appear to be an assignment of a variable, it will see if it can be resolved as a file and then source that. This property lets the user bundle some favourite settings and temporarily switch to them. For example, by creating a few predefined configurations:

# file = $HOME/.OpenFOAM/gcc82
export WM_COMPILER_TYPE=ThirdParty
export WM_COMPILER=Gcc82
export WM_LABEL_SIZE=32

# file = $HOME/.OpenFOAM/clang50-int64
export WM_COMPILER_TYPE=ThirdParty
export WM_COMPILER=Clang50
export WM_LABEL_SIZE=64

It is then possible to easily switch between different configurations:

source /path/to/OpenFOAM-v1812  clang50-int64
source /path/to/OpenFOAM-v1812  gcc82

Armed with this information, the user should be able to make adjustments to the OpenFOAM configuration with a good degree of confidence. However, there are also times in which it can be expedient and useful to simply change the entries directly within the OpenFOAM directory as new permanent defaults for all users. This can also be the case for cluster installations where the user will not require the usual flexibility.

For these cases, the foamConfigurePaths tool can be helpful (and powerful). For example, when installing without any OpenFOAM ThirdParty dependencies and additionally setting the OpenFOAM directory to a fixed location (removing any bash discovery magic):

bin/tools/foamConfigurePaths \
    -project-path "/opt/openfoam-1812" \
    -boost boost-system \
    -cgal  cgal-system \
    -fftw  fftw-system \
    -kahip kahip-none \
    -scotch scotch-system \
    -scotch-path /usr/lib64/mpi/gcc/openmpi \

Using this tool has some restrictions:

  • It must be called from the OpenFOAM project directory
  • It is not available in the PATH, since it we wish to avoid any inadvertent use
  • Using this tool to change default gcc, gmp, mpfr versions is not very precise. It will change the gcc version without distinguishing between Gcc48, Gcc82 etc.

New man pages

Further effort has been put into providing easily accessible information and ensuring a smoother transition for any command-line changes.

Each solver and utility supports the usual -help option, which contains short overview of the usage and some possible options. This has been updated to include basic information about the purpose of each solver or utility. This information largely reflects what was already available in the online doxygen format, but is now more readily available.

The usage has been extended to supports the addition of comments for command-line arguments as well as options. This makes it easier to associate information directly with the corresponding argument. For example,

$ surfaceBooleanFeatures -help

Usage: surfaceBooleanFeatures [OPTIONS] <action> <surface1> <surface2>
  <action>          One of (intersection | union | difference)
  <surface1>        The input surface file 1
  <surface2>        The input surface file 2
  -case <dir>       Specify case directory to use (instead of the cwd)

To ensure that the most important information remains easy to find, less frequently used or more advanced options are moved out of the way. The -help-full option shows all of the options.

When compatibility options are available, the -help-compat option will be shown on the usage. Compatibility options allow transparent renaming of options, or removal of options that are no longer applicable.

For example,

$ foamToEnsight -help-compat

2 compatibility options for foamToEnsight

| Old option         | New option        | Comment
| -noLagrangian      | -no-lagrangian    | until 1806
| -noPatches         | -no-boundary      | until 1806

As revealed in the -help-full output, a new -help-man option is now available. This means that every OpenFOAM solver and utility is now capable of presenting its help information in manpage format. This output is not normally viewed directly, but redirected to another location for use with the man(1) system.

The foamCreateManpage tool helps with some of the work, and can be used when packaging OpenFOAM for an operating system installation or on a cluster.

For example,

$ bin/tools/foamCreateManpage -gzip

generates manpage content for all compiled OpenFOAM applications and utilities and places the content under the OpenFOAM doc/man1 directory. When the OpenFOAM environment is refreshed, this directory will be added to the MANPATH variable and make them available to the man(1) system:

$ man blockMesh

Improvements in portability

A few minor changes have been made that should improve the portability of OpenFOAM, most notably for users with WSL (Windows subsystem for Linux). This means that other (non-OpenFOAM) locations in the $PATH may contain whitespace in their names without causing ill-effects.

However, the OpenFOAM directories themselves remain as before, without whitespace in their names. A standard means to avoid this is to create a symbolic link to have a directory without any whitespace.

For example,

cd $HOME
ln -s "/mounted volume/user/workdir"  workdir
cd workdir
# start working with OpenFOAM

With this version, this will now work as expected. OpenFOAM now uses the logical path instead of the physical path when obtaining its internal cwd() value. If required, the old default can be restored by changing an entry in the global controlDict, but should not be necessary.

The difference in the meaning can be simply tested and understood with the shell command:

$ pwd -P  : The old OpenFOAM internal meaning for cwd()
$ pwd -L  : The new OpenFOAM internal meaning for cwd()