OpenFOAM® v1906: New and improved post-processing

27/06/2019

Improvements in runTimePostProcessing

The runTimePostProcessing function object provides a direct VTK insitu visualization alternative to the ParaView/Catalyst interface for well-defined, high throughput workflows.

[Picture]

The revised function object adds many new features:

  • parallel VTK rendering
  • rendering of sampled surfaces that are stored in memory without needing to serialize to a file format
  • direct rendering of patches and clouds without an intermediate sampling stage
  • can now render vector arrows at the face centres of sampled surfaces or mesh patches.
  • for more visually appealing images, the new smooth option can be used, which applies a cell-to-point interpolation of the face data to provide a smoother appearance.
  • direct use of the VTK cutting plane algorithm

Tutorials
$FOAM_TUTORIALS/lagrangian/coalChemistryFoam/simplifiedSiwek
$FOAM_TUTORIALS/incompressible/pimpleFoam/RAS/ellipsekkLOmega
$FOAM_TUTORIALS/incompressible/pisoFoam/LES/motorBike/motorBike
$FOAM_TUTORIALS/incompressible/simpleFoam/windAroundBuildings

New areaWrite function object for finiteArea

The new areaWrite function object supports writing finite area meshes and fields in standard surface output formats, e.g. Ensight, and VTK.

Source code
$FOAM_SRC/functionObjects/utilities/areaWrite
Tutorials
$FOAM_TUTORIALS/finiteArea/surfactantFoam/planeTransport
$WM_PROJECT_DIR/modules/avalanche/tutorials/wolfsgrube

Updated forces and new force coefficient components

The forces and forceCoeffs function objects now report side forces and yaw moments, and the input directions simplified by making use of co-ordinate systems.

Users are now only required to specify an origin with two orthogonal directions, and can be added by the three options shown below:

CofR        (0 0 0); // Centre of rotation
dragDir     (1 0 0);
liftDir     (0 0 1);

origin (0 0 0);
e1     (1 0 0);
e3     (0 0 1); // combinations: (e1, e2) or (e2, e3) or (e3, e1)

coordinateSystem
{
    origin  (0 0 0);
    rotation
    {
        type axes;
        e1 (1 0 0);
        e3 (0 0 1); // combinations: (e1, e2) or (e2, e3) or (e3, e1)
    }
}
Source code
$FOAM_SRC/functionObjects/forces/forces
$FOAM_SRC/functionObjects/forces/forceCoeffs
Solver
$FOAM_TUTORIALS/incompressible/simpleFoam/motorBike

New Lamb vector function object

The new lambVector function object calculates the Lamb vector, defined as the cross product of a velocity vector and vorticity vector. The divergence of the Lamb vector provides a quantitative connection to the spatially localised instantaneous fluid motions, e.g. high- and low-momentum fluid parcels that have the capacity to affect the rate of change of momentum, and to generate forces such as drag.

An example of the usage involving the divergence computation of the lambVector is shown below:

lambVector1
{
    type        lambVector;
    libs        ("libfieldFunctionObjects.so");
    field       U;
}

div1
{
    type        div;
    libs        ("libfieldFunctionObjects.so");
    field       lambVector;
}

Plotting an iso-surface for the channel case shows that the resulting field is able to capture the turbulent content of the flow.

[Picture]

Source code
$FOAM_SRC/functionObjects/field/lambVector
Tutorials
$FOAM_TUTORIALS/incompressible/pimpleFoam/LES/channel395DFSEM
References

New sampling method

A new line sampling method, patchEdgeSet, samples values on patch edges that intersect a user-defined surface. The surface is of the generic searchablePlane type. Typical examples are plane or triSurfaceMesh (triangulated surface)

In below figure the pressure on the top patch has been sampled with a triangulated sphere.

[Picture]

Usage is usually through the sets functionObject:

sets
{
    type                sets;
    libs                ("libsampling.so");
    writeControl        timeStep;
    writeInterval       1;

    fields              ( p U);
    interpolationScheme cellPoint;

    setFormat           vtk;

    sets
    (
        patchEdge
        {
            type        patchEdge;
            axis        x;

            // Selected patches
            patches     (movingWall);

            // Surface type
            surfaceType searchablePlane;

            // Additional info for the surface type
            planeType   pointAndNormal;
            pointAndNormalDict
            {
                point   (1.5 1.5 1.5);
                normal  (0.1 0 1);
            }

            // Reference point for ordering samples
            origin      (0 1 0);
        }
    );
}

Note that the resulting points are sorted according to the distance to the provided origin.

Source code
$FOAM_SRC/sampling/sampledSet/patchEdge

New run-time triggers

The run-time control function object was introduced in OpenFOAM-v3.0+ to provide a mechanism to terminate and write a calculation based on a set of run-time conditions. The set of conditions include:

  • average
  • equationInitialResidual
  • equationMaxIter
  • maxDuration
  • minMax
  • minTimeStep

The v1906 release extends what happens when the conditions are satisfied by adding an option to emit ’triggers’. The triggers can be used to start other function objects to provide highly customisable workflows.

The action to perform is controlled by the optional satisfiedAction entry, which can take the values of:

  • end : finalise the calculation. This is the default action to maintain backwards compatibility; and
  • setTrigger : set a trigger, defined as an integer value by the additional trigger entry.

Function object time controls now have an optional controlMode entry to control when the object is active that can be set to:

  • time: active between object’s timeStart and timeEnd
  • trigger: active between object’s triggerStart and triggerEnd
  • timeOrTrigger: active between object’s timeStart and timeEnd OR triggerStart and triggerEnd
  • timeAndTrigger: active between object’s timeStart and timeEnd AND triggerStart and triggerEnd

If the trigger is activated by satisfying a set of run-time conditions, all function objects that are set to start based on that trigger ’index’ will be activated.

Putting this together, it is possible, e.g. to start reporting the minimum and maximum values of all fields and set the calculation to stop 100 iterations after the average the drag coefficient from a forces function object changes by less than 1e-3:

runTimeControl1
{
    type            runTimeControl;
    libs            ("libutilityFunctionObjects.so");
    conditions
    {
        condition1
        {
            type            average;
            functionObject  forceCoeffs1;
            fields          (Cd);
            tolerance       1e-3;
            window          20;
            windowType      exact;
        }
    }
    satisfiedAction setTrigger;
    trigger         1;
}

runTimeControl2
{
    type            runTimeControl;
    libs            ("libutilityFunctionObjects.so");
    controlMode     trigger;
    triggerStart    1;
    conditions
    {
        condition1
        {
            type            maxDuration;
            duration        100;
        }
    }
    satisfiedAction end;
}

fieldMinMax
{
    type            fieldMinMax;
    libs            ("libfieldFunctionObjects.so");
    fields          (".*")
    controlMode     trigger;
    triggerStart    1;
}

Source code
$FOAM_SRC/functionObjects/utilities/runTimeControl
Tutorials
$FOAM_TUTORIALS/incompressible/simpleFoam/simpleCar

Improvements in surface sampling and writing

The infrastructure for surface sampling and writing has received an extensive overhaul for improved functionality and flexibility. In previous versions the surface writers were somewhat awkward when being used within parallel code, but the worst part was that they were entirely stateless. This would be especially noticeable when sampling surfaces and writing in VTK format. The uncoordinated output meant that a separate file would be generated for each sampled field.

Surface writers can now be time-step aware, which allows generation of sampled VTK output with all sampled fields at that timestep.

Any parallel data reduction and any associated bookkeeping is now part of the surface writers themselves, which improves their re-usability and avoids unnecessary and premature data reduction at the sampling stage.

Different output formats are supported on a per-surface basis as well as the ability to optionally store the sampled surfaces and fields onto a registry for reuse by other function objects. It is therefore now possible to simply sample-and-store a surface and use that surface and its values at a later stage in a surfaceFieldValue function object to calculate operations such as min/max etc.

It is now possible to add a colour table to sampled surfaces written in x3d format, which makes for convenient direct import into rendering tools such as blender.

New sample surface options

The sampledSurfaces dictionary entries are backwards compatible, but there are additional features:

  • store
    Request that sample surfaces be stored on an object registry for reuse. For example, by the functionObjectSurface rendering object in runTimePostProcessing.
  • sampleOnExecute
    Request a sample/store operation when the function object execute() is called.
  • surfaces
    This entry can now be a dictionary of entries instead of a list, which can be useful in combination with changeDictionary modification.
  • interpolationScheme
    is now optional. By default it is cellPoint.
  • per-surface specification of surface format and storage requirements. This supports a flexible mix of user requirements.