OpenFOAM® v1912: New and improved pre-processing
New expressions syntax
OpenFOAM-v1912 now implements expressions, which use ideas pioneered by swak4Foam (Bernhard Gschaider). By expressions we mean the processing of string-like input as mathematical or field evaluations within OpenFOAM. This addition permeates various parts of OpenFOAM i.e. dictionary syntax, string evaluations, boundary conditions, set fields, and can be expected to grow in the future.
For example, the expressions make it possible to embed mathematical evaluation into regular string expansions:
At its core the expressions functionality uses:
- The Lemon Parser Generator from the SQLite project - see https://www.sqlite.org/lemon.html
- The Ragel State Machine Compiler - see http://www.colm.net/open-source/ragel/
- Source code
- $FOAM_SRC/OpenFOAM/include/m4
$FOAM_SRC/src/OpenFOAM/expressions
$FOAM_SRC/src/finiteVolume/expressions
Inline expressions in dictionaries
A major change for dictionary input is provided by the new #eval directive, which is associated with the addition of expressions. In many case it can directly replace #calc for a significant gain in speed. As a comparison, 10 evaluations of the following reported a time of 16 seconds for #calc versus only 0.02 seconds for #eval.
This capability will change the way you view dictionaries.
split 0.4;
inlet1
{
type flowRateInletVelocity;
massFlowRate constant #eval{ $split * $kgh / 3600 };
}
inlet2
{
type flowRateInletVelocity;
massFlowRate constant #eval{ (1-$split) * $kgh / 3600 };
}
- Source code
- $FOAM_SRC/OpenFOAM/db/dictionary/functionEntries/evalEntry
- Tutorial
- All tutorials that previously used #calc now use #eval.
New expressions-based setFields utility
The expressions support the new utilities setExprFields and setExprBoundaryFields, which serve a similar purpose to the swak4Foam funky utilities of similar names.
Instead of using shapes and selection to set the fields, the setExprFields uses the combination of a condition and an expression. Only when the condition is valid will the result of the expression be applied. For example, the following will adjust the temperature within the defined zone:
(
T
{
field T;
dimensions [0 0 0 1 0 0 0];
constants
{
centre (0.21 0 0.01);
}
variables
(
"radius = 0.1"
);
condition
#{
// Within the radius
(mag(pos() - $[(vector)constants.centre]) < radius)
// but only +ve y!
&& bool(pos((pos() - $[(vector)constants.centre]).y()))
#};
expression
#{
300
+ 200 * (1 - mag(pos() - $[(vector)constants.centre]) / radius)
#};
}
);
The setExprBoundaryFields utility serves a similar purpose for custom modification of boundary field entries.
New set fields utility for PDRFoam
The new PDRsetFields utility computes the tensorial resistances of blockages for use by the PDRFoam solver. The geometry is input in the form of primitive shapes using a PDRsetFieldsDict file, taking the form:
// Replace by the relevant names
obsFileDir "<case>/geometry";
obsFileNames (obstaclesDict);
// legacyObsSpec true;
//
// obsFileNames (position.obs base.obs);
- cylinder
- diagonal beam
- cuboid
- grating
- louvre
- patch
An example set of obstacles is shown below:
- Source code
- $FOAM_UTILITIES//utilities/preProcessing/PDRsetFields
- Tutorial
- $FOAM_UTILITIES/combustion/PDRFoam/pipeLattice
Wall distance output from checkMesh
The checkMesh utility option -writeAllFields has been extended to write the wall distance as a field wallDistance. It requir es the wall distance method to have been selected in system/fvSchemes dictionary:
{
method meshWave;
}
- Source code
- $FOAM_UTILITIES/mesh/manipulation/checkMesh
snappyHexMesh : automatic closure of thin gaps
In meshing complicated geometries there might be thin gaps where the user does not want a mesh. In this release snappyHexMesh allows a per-surface, per-surface-region specification of a blockLevel which specifies the minimum size of a gap to mesh. Any cell inside a gap smaller than this indicated size gets deleted (and consequently there will be no cells in the gap).
The extension is enabled using the following syntax:
{
"gap.*"
{
// Surface-wise min and max refinement level
level (2 2);
// From cell level 2 onwards start checking
// for opposite surfaces
blockLevel 2;
}
}
The blockLevel setting determines
- whether the surface is used at all in the gap detection
- an idealised size of the gap: 2 * cellsize; where cellsize is determined from the initial cell size refined blockLevel times
After all surface refinement snappyHexMesh but before any shell/volume refinement, determine for all cells the nearest two surfaces. If the cell is
- in between two surfaces, or disconnected regions of the same surface
- and the distance between the opposite points is less than the gap size
the cell will get deleted.
The tutorial opposite_walls is a simple block with two surfaces that form a thin gap.