OpenFOAM® v2012: New and improved post-processing

23/12/2020

Improved handling of function object failures

If a function-object cannot load, a warning is issued and the object is simply ignored. This is usually desirable as it allows our core simulation to continue and complete on time, and we can perform any necessary work in post-processing. However, what if proper loading of this function-object is essential for the purposes of our simulation?

After a function-object is successfully loaded we normally treat any errors as being fatal. However, what if the failure was caused by a function object that we placed to obtain some additional information, but is not critical enough that we would want our simulation to stop if it failed?

Clearly one size does not fit everyone (or every function-object). This is where the new errors entry can be used. It has four enumerated values:

  • default : construct = warn, runtime = fatal
  • warn : construct = warn, runtime = warn
  • ignore : construct = silent, runtime = silent
  • strict : construct = fatal, runtime = fatal

The errors control can be added at the top-level and/or for individual function objects. For example,

sampling
{
    type    surfaces;
    libs    (sampling);
    errors  warn;   // Would "mostly" like to have these samples
    ...
}

Source code
$FOAM_SRC/OpenFOAM/db/functionObjects/functionObject
$FOAM_SRC/OpenFOAM/db/functionObjects/functionObjectList
$FOAM_APP/test/testFunctionObjects/fakeError

New Abaqus surface input and output

Added support for ABAQUS surface input, which can be defined either in terms of 2D elements, or surfaces of 3D elements. For example,

*ELEMENT, TYPE=C3D4, ELSET=...
1, ...
2, ...

*SURFACE, NAME=Things, TYPE=ELEMENT
1, S1
2, S1
ABAQUS output support has also been added, but with the caveat that the output surfaces will have largely lost their association with any originating 3D elements.

Lagrangian: new patch interaction fields

The new patchInteractionFields cloud function object creates volume fields whose boundaries are used to store patch interaction statistics.

Two new fields are stored on the mesh database and output at write time:

  • <cloud><model>:count - cumulative particle hits
  • <cloud><model>:mass - cumulative mass of hitting particles

Both statistics are accumulated during the entire run, but can be cleared using the optional resetMode entry:

  • none: fields are not reset
  • timeStep: reset at each time step
  • writeTime: reset at each write time

An example usage is given below:

patchInteractionFields1
{
    type            patchInteractionFields;
    resetMode       writeTime;
}
Source code
$FOAM_SRC/lagrangian/intermediate/submodels/CloudFunctionObjects/PatchInteractionFields
Tutorial
$FOAM_TUTORIALS/lagrangian/reactingParcelFoam/filter

New cloud function object: particle histogram

The patchParticleHistogram cloud function object computes a histogram of particle diameters and corresponding number of particles that hit a user-specified list of patches. A minimal working example of this function object is shown below:

patchParticleHistogram1
{
    type             patchParticleHistogram;
    patches          (<patch1> <patch2> ... <patchN>);
    nBins            10;    // Number of histogram bins
    min              0.1;   // Minimum value of histogram data
    max              10.0;  // Maximum value of histogram data
    maxStored
    Parcels 20;
}
A typical output of patchParticleHistogram function object is shown below:

1e-07 - 1e-06    381.9   // 381.9 particles of diameter between 1e-07 and 1e-06
1e-06 - 2e-06    0.0     // 0     particles of diameter between 1e-07 and 2e-06
2e-06 - 3e-06    2.5     // 2.5   particles of diameter between 2e-07 and 3e-06
...
The output file contains two columns where the first corresponds to the bin lower and upper diameter boundaries, and the second the number of particles within the bin.

Source code
$FOAM_SRC/lagrangian/intermediate/submodels/CloudFunctionObjects/PatchParticleHistogram
Tutorial
$FOAM_TUTORIALS/lagrangian/reactingParcelFoam/filter

Updated heat transfer coefficient function object

The heatTransferCoeff function object has been extended to compute the Nusselt number, i.e. the ratio of convective to conductive heat transfer at a boundary in a fluid:

pict\relax \special {t4ht=

where N u  \relax \special {t4ht= is the Nusselt number, h  \relax \special {t4ht= is the convective heat transfer coefficient of the flow, L  \relax \special {t4ht= a characteristic length that defines the scale of the physical system, and κ  \relax \special {t4ht= the thermal conductivity of the fluid.

An example showing the new option is given below:

heatTransferCoeff1
{
    // Mandatory/Optional entries
    type        heatTransferCoeff;
    ...

    // Nusselt-number entries
    L           1.0;
    kappa       1.0;
}

Source code
$FOAM_SRC/functionObjects/field/heatTransferCoeff
Tutorial
$FOAM_TUTORIALS/heatTransfer/buoyantPimpleFoam/hotRoom

New function object: BilgerMixtureFraction

The new BilgerMixtureFraction function object calculates the Bilger mixture-fraction field based on the elemental composition of the mixture. Elements C, H, S and O are considered.

The Bilger mixture-fraction field is the mass mixing ratio of fuel and oxidiser in [kg fuel / kg mixture], and is reportedly invariant to the reaction progress of the mixture, e.g. the same for unburnt and burnt mixtures. The fraction is unity for pure fuel and zero for pure oxidiser.

A minimal working example of this function object can be seen below:

BilgerMixtureFraction1
{
    type                 BilgerMixtureFraction;
    libs                 (fieldFunctionObjects);

    fuel
    {
        fractionBasis    mass;
        CH4              1;
    }

    oxidiser
    {
        fractionBasis    mole;
        O2               0.23;
        N2               0.77;
    }

    phase                <phaseName>;
    result               <resultName>;
}

A set of images of Bilger mixture-fraction field, f_Bilger, is presented below that shows the validation of the method and verification of the implementation from the tutorial
$FOAM_TUTORIALS/combustion/reactingFoam/laminar/counterFlowFlame2D :

[Picture]

[Picture]

Source code
$FOAM_SRC/thermophysicalModels/chemistryModel/functionObjects/BilgerMixtureFraction
Tutorial
$FOAM_TUTORIALS/combustion/reactingFoam/laminar/counterFlowFlame2D
References
  • Bilger, R. W. (1979). Turbulent jet diffusion flames. Energy and Combustion Science, p. 109-131. DOI:10.1016/B978-0-08-024780-9.50011-3
  • Zirwes, T., Zhang, F., Habisreuther, P., Hansinger, M., Bockhorn, H., Pfitzner, M., & Trimis, D. (2019). Quasi-DNS dataset of a piloted flame with inhomogeneous inlet conditions. Flow, Turbulence and Combustion, vol 104, p. 997-1027. DOI:10.1007/s10494-019-00081-5
Attribution
OpenCFD would like to thank Thorsten Zirwes (Karlsruhe Institute of Technology) for his contributions: the base implementation, useful discussions, helpful suggestions, and various validation/verification test cases.
More information
The detailed introduction by Zirwes and useful discussions can be found in Issue #1915 .

Improved surfaceFieldValue function object

The surfaceFieldValue function object can now act on multiple faceZones or patches. The additional names entry is used to specify a word/regex list of selections, e.g.

{
     type    patch;
     name    inlets;
     names   ("inlet_[0-9].*" inlet);
}
It is now also possible to evaluate a surfaceFieldValue faceZone on volume fields.

Tutorial
$FOAM_TUTORIALS/lagrangian/reactingParcelFoam/verticalChannel

Multiple weights

The surfaceFieldValue and volFieldValue function objects now support multiple weight fields, which are combined by multiplication. This can be used as an alternative to creating additional fields, e.g.

weightFields  (rho U);

    // previously
    derivedFields (rhoU);
    weightField   rhoU;

Tutorial
$FOAM_TUTORIALS/compressible/rhoSimpleFoam/squareBend

New planeToFaceZone option for topoSet

The planeToFaceZone feature from openfoam.org selects faces based on cell centres spanning a specified plane. The plane can be defined by a point and normal vector. A minimal working example of this topoSet is given below:

{
    name        <user defined name>;
    type        faceZoneSet;
    action      add;      // (new/add/subtract)

    source      planeToFaceZone;
    point       (<px> <py> <pz>);
    normal      (<nx> <ny> <nz>);

    option      <option>; // (all/closest)
}

Source code
$FOAM_SRC/meshTools/sets/faceZoneSources/planeToFaceZone
Tutorial
$FOAM_TUTORIALS/incompressible/pisoFoam/RAS/cavity
Attribution
The base of the planeToFaceZone has been ported from openfoam.org.

sampledSurfaces : cuttingPlane

The cuttingPlane sampled surface now optionally supports multiple offsets using the new offsets keyword, providing a more convenient and concise syntax when compared to specifying each plane individually. Currently all generated planes are folded into a single surface for output, but this may be adjusted in the future.

[Picture]

An example use case is shown below:

samplePlanes
{
    type    surfaces;
    libs    (sampling);

    writeControl    writeTime;
    surfaceFormat   vtk;
    fields          (U k epsilon nut);

    surfaces
    {
        planes
        {
            type        cuttingPlane;
            planeType   pointAndNormal;
            pointAndNormalDict
            {
                point   (0 0 0);
                normal  (1 0 0);
            }

            // New keyword:
            offsets ( 500 1000 1500 2000 2500 3000 3500 4000 4500 );
        }
    }
}

Source code
$FOAM_SRC/sampling/sampledSurface/sampledCuttingPlane
Tutorial
$FOAM_TUTORIALS/verificationAndValidation/atmosphericModels/HargreavesWright˙2007

sampledSurfaces : IsoSurface

The iso-surface sampling has been revised and rationalised. There are three different methods for generating iso-surfaces and sampling, which are now selectable via the isoMethod. The default method has changed from point to topo. The three methods in summary:

  • point : previous default, this is the oldest. The generated triangles span cell divisions, and generally needs interpolation for correct results.
  • cell : uses a cell-based snapping method during generation. Mostly gives better results than the point method.
  • topo : this is the new default and the newest method. Uses topological cell cutting for more accuracy and consistency. In some cases it may miss some surface features.

For example,

sampling
{
    type        isoSurface;
    isoMethod   topo;  // (point | cell | topo)
    ...
}
Here is a side-by-side comparison of how the different methods appear for a simple sphere test case. A VTK iso-surface is shown as reference, but is not available for selection within OpenFOAM:

[Picture]

The newest iso-surface method in OpenFOAM, the topo method, generates the lowest number of faces.

[Picture]

Additional changes:

  • All three methods now support handling of cellZones and a bounding box (new).
  • The cell and topo methods additionally support a simpleSubMesh method in which the cellZones are handled internally within the algorithm (new). This is faster and more memory efficient. By default this is disabled.
  • All three methods now support sampling of iso-values (new).

Multiple iso-values

The sampled iso-surfaces now support single or multiple iso-values, for functionality and syntax similar to that provided by runTimePostProcessing.

If present, the new isoValues keyword is used in preference to the isoValue keyword, providing a more convenient and concise syntax when compared to specifying each surface individually. Currently all generated surfaces are folded into a single surface for output, but this may be adjusted in the future.

[Picture]

The new isoValues entry has priority over a single isoValue; the rest of the usage is largely unchanged.

sampleIso
{
    type    surfaces;
    libs    (sampling);

    writeControl    writeTime;
    surfaceFormat   vtk;
    fields          (U k epsilon nut);

    surfaces
    {
        envelope
        {
            type        isoSurface;
            isoMethod   topo;
            isoField    k;

            // Single value
            // isoValue   1.30;

            // New keyword:
            isoValues   (1.28 1.29 1.30 1.31 1.32 1.33);
        }
    }
}

Source code
$FOAM_SRC/sampling/sampledSurface/isoSurface
Tutorial
$FOAM_TUTORIALS/verificationAndValidation/atmosphericModels/HargreavesWright˙2007

sampledSurfaces : distanceSurface

In addition to the original purpose of distanceSurface to create a sampled surface at a distance from an input surface, it can now be used to sample at a zero distance from an input surface. In this mode it works much like a cell cutting method for generating surfaces, as illustrated in the following image:

[Picture]

The main challenge with the zero distance mode arises from the edges of the surface and intersection tolerances. If an edge of the surface ends within a cell, cell cutting is performed for the entire cell. This is usually sufficient, but under certain conditions would leak information and cause undesirable effects:

[Picture]

The distance information results in undesirable fringe faces being generated on the outside of the thin walled pipe. From the algorithm’s point of view, this is perfectly reasonable since the cells in question are within very close proximity of the original surface (indeed we cannot be certain that the original surface did not actually penetrate slightly through the wall). However, the result is certainly not what we want.

The user can now specify an additional topology filter within distanceSurface to define how to retain/discard parts of the surface. A proximity check is often the simplest choice for most cases; other filters options include:

proximity (post-filter)
Checks the resulting faces against the original search surface and rejects faces with a distance greater than absProximity.
largestRegion (pre-filter)
Cut cells are checked for topological connectivity and the region with the most number of cut cells is retained. This handles the ”ragged” edge problem.
nearestPoints (pre-filter)
Cut cells split into regions, the regions closest to the user-defined points are retained. Uses maxDistance entry for additional control.

The intermediate results of the proximity filter are as shown in the following:

[Picture]

After filtering, the resulting surface is now as expected. It is important to note that the distance surface works on a volume cell level (it uses an iso-surface algorithm) and thus the resulting surface is independent of the resolution of the original surface.

[Picture]

Compatibility changes

Changed the default distanceSurface iso-surface method from cell to topo as this yields cleaner surfaces with fewer cuts. The isoMethod keyword can be used to select cell/point/topo if they prove better for any particular case.

Source code
$FOAM_SRC/sampling/sampledSurface/distanceSurface
$FOAM_SRC/sampling/surface/distanceSurface
Tutorial
$FOAM_TUTORIALS/compressible/rhoSimpleFoam/squareBend
$FOAM_TUTORIALS/compressible/rhoSimpleFoam/gasMixing/injectorPipe
$FOAM_TUTORIALS/incompressible/simpleFoam/squareBend

Updated searchableSphere

The searchableSphere has been extended to accommodate generalized spheroids. This is triggered when the keyword radius specifies a vector of three different values, e.g.

{
    type    sphere;
    origin  (0 0 0);
    radius  (2 3 4);
}

A regular sphere can be specified as a single radius (as previously) or with three identical radii, e.g.

// A sphere
{
    type    sphere;
    origin  (0 0 0);
    radius  2;
}
// Also a sphere
{
    type    sphere;
    origin  (0 0 0);
    radius  (2 2 2);
}

Searching is optimized for sphere, prolate and oblate spheroids.

[Picture]

This additional capability is especially useful when used as a projection surface for blockMesh or snappyHexMesh when a smooth outer boundary is required, but a regular sphere would not provide the desired distances from the core region.

[Picture]

Source code
$FOAM_SRC/meshTools/searchableSurfaces/searchableSphere
Tutorial
$FOAM_TUTORIALS/heatTransfer/buoyantBoussinesqSimpleFoam/iglooWithFridges
$FOAM_TUTORIALS/mesh/blockMesh/spheroid7Projected
$FOAM_TUTORIALS/mesh/blockMesh/spheroidProjected
Attribution
A contribution from Victor Olesen

Updated searchableDisk

The searchableDisk surface now has an optional innerRadius value to represent annular geometries, e.g.

{
    type        disk;

    origin      (0.45 0 0);
    normal      (1 0 0);
    radius      0.09;
    innerRadius 0.05;
}
Source code
$FOAM_SRC/meshTools/searchableSurfaces/searchableDisk
Tutorial
$FOAM_TUTORIALS/compressible/rhoSimpleFoam/gasMixing/injectorPipe

sampledSurfaces: general

Out-of-range sampling

When sampling onto a meshed surface, the sampling surface may be outside of the mesh region, or simply too far away from the region of interest. The new maxDistance can be used to specify a maximum search distance, and default values for samples that are too distant. If a default value is not specified, a zero value is applied.

maxDistance     0.005;
defaultValue
{
    "p.*"   1e5;
    T       273.15;
    U       (-100 -100 -100);
}

Sampled faceZones

Sampling on faceZones is now supported.