Motivation

OpenFOAM has become the de-facto standard Computational Fluid Dynamics (CFD) solver of choice among open-source projects. It offers a rich set of feature and can easily compete with other commercial solvers. In-fact, for most applications, it offers probably more features than can be found in any other CFD solver of similar nature (i.e. general purpose CFD solvers).

To set up a problem in OpenFOAM requires experience, patience and a good collection of resources for consultation. Perhaps the biggest help here are the tutorial cases that come with the default distribution of OpenFOAM. It is common to copy and paste a tutorial case and then adjust it for one’s own flow problem. There is in-fact a dedicated utility script foamCloneCase which can help with this. Using this approach, however, should be regarded as a rather poor practice and is exactly going against the DRY (Don’t repeat yourself) principle in programming terms, where copy and pasting of source code is discouraged as it is difficult to maintain and a potential source of errors (bugs). In-fact, this copy and pasting approach where tutorial cases are adapted for another problem has shown to be error prone, yielding difficult to trace bugs.

On the other hand, this approach is still better than writing a case setup from scratch, which is done in an almost domain specific language (DSL) based on c++. The syntax is difficult to look up, at times, due to a lack of a well written documentation for advanced features (basic features are reasonably well documented) and also difficult to memorise. Thus, copy and pasting of tutorial files becomes an attractive and appealing approach.

This application, the OpenFOAMCaseGenerator, aims to get rid of the copy and pasting approach by producing reproducible case setups that generate all required files to run a case (along with an OpenFOAM-like Allrun bash script to execute all required steps, i.e. pre-processing, solving and post-processing). The settings for each case are stored in a dictionary which can be modified for different simulations.

The idea is very much inspired by build tools such as CMake or Meson, which act as a meta build system for compiled languages such as c/c++ or Fortran. Just as CMake, Meson (or similar meta build systems) produce the actual build script (such as Make or Ninja files) which are then used to perform the actual build, the OpenFOAMCaseGenerator does not interact with OpenFOAM itself but rather perform all required steps to setup a case which can then be used by OpenFOAM, completely eliminating the need to copy and paste tutorial cases from elsewhere.

This is not all, however. OpenFOAM does not make any assumptions about any case and thus requires a lot of boilerplate setup. This offers a really good opportunity to fine tune a specific case but also requires expert knowledge when it comes to setting up a case. Instead of asking for all of these inputs, this case generator offers specific policies instead, which are then used to drive the case setup. For example, instead of providing all required numerical discretisation schemes, the user may choose among several policies (default, robust, accuracy or total-variation diminishing (tvd)). This is a much clearer intend and does not require knowledge about all numerical discretisation schemes. These can still be later modified if needed but a sensible default setup can be achieved in this manner. Another important aspect of the case setup are the boundary conditions, especially for turbulent flow calculations. Here, again, the user expresses only the intent (i.e should walls be resolved or modelled through wall functions, for example, using RANS) and the type of flow (internal or external flow) and the rest of the intitial and boundary conditions are calculated accordingly.

OpenFOAM also offers the ability to inject c++ code directly into the initial and boundary conditions. This can be considered an advanced feature for which little documentation can be found. This case generator, again, provides all the boilerplate code that is required and the user only needs to provide the actual c++ code which will be then inserted in the right place. Example codes are also provided along with this case generator which can be used to understand how to query OpenFOAM for domain specific variables such as the coordinate arrays or the current timestep.

In short, the OpenFOAMCaseGenerator takes all the heavy lifting from the user and provides a reproducible case setup with sensible default options that can be used to setup cases for one’s own calculations.