OpenFOAM® v1812: New and improved post-processing

20/12/2018

New parallel handling of VTK datasets

The infrastructure for generating VTK output has been fully revamped.

The foamToVTK utility and the vtkWrite function object are now parallel aware and handle multi-region simulations.

The normal output of these is a VTK multi-block (.vtm) file comprising the individual components. As such, the default format has changed to the xml-based VTK formats, i.e..vtm, .vtp, abd .vtu extension. The -legacy option can be used to generate the legacy format if required.

The directory structure used for these .vtm files reflects the internal layout.

[Picture]

myCase_40.vtm
    myCase_40/
    |-- boundary
    |   |-- buildings.vtp
    |   |-- ground.vtp
    |   |-- inlet.vtp
    |   |-- outlet.vtp
    |   - sides.vtp
    |-- boundary.vtm
    - internal.vtu

The .vtm file provides a very lightweight container to organize VTK content and preserves the original numerical ordering of the patches. For convenience, a boundary.vtm file is also generated with the boundary/ directory, which can be convenient when only values on the surface are required.

During creation, a corresponding .vtm.series time-series file is generated for convenient loading in ParaView.

{
  "file-series-version" : "1.0",
  "files" : [
    { "name" : "myCase_00000025.vtm", "time" : 0.125 },
    { "name" : "myCase_00000050.vtm", "time" : 0.25 },
    { "name" : "myCase_00000075.vtm", "time" : 0.375 },
    { "name" : "myCase_00000100.vtm", "time" : 0.50 }
  ]
}

Additionally, all generated files are now provided with a global TimeValue field value, which can accessed from within ParaView:

[Picture]

In previous versions, various tricks were needed to obtain particular special output. Some of the options were changed to provide a better correspondence with vtkWrite and ParaView Catalyst functionObjects, others to provide behaviour more consistent with foamToEnsight. In some cases, the functionality of foamToEnsight was modestly adjusted as well.

Here is a small overview of the changes required to obtain particular special output.

  • Internal mesh only
    • 1806: foamToVTK -noFaceZones -excludePatches ’(".*")’
    • 1812: foamToVTK -no-boundary
  • Boundaries only
    • 1806: foamToVTK -noInternal -noFaceZones
    • 1812: foamToVTK -no-internal
  • No faceZone conversion
    • 1806: foamToVTK -noFaceZones
    • 1812: foamToVTK
  • Convert all faceZones
    • 1806: foamToVTK
    • 1812: foamToVTK -faceZones ’( ".*" )’
  • Selected faceZone conversion
    • 1806: foamToVTK #<-- manually discard unwanted files later
    • 1812: foamToVTK -faceZones myzone

An overview of some of the changes in command-line options can be found in the corresponding foamToVTK -help-compat output:

$ foamToVTK -help-compat

8 compatibility options for foamToVTK

    | Old option                 | New option                 | Comment
    |----------------------------|----------------------------|------------
    | -allPatches                | -one-boundary              | until 1806
    | -noLagrangian              | -no-lagrangian             | until 1806
    | -noPointValues             | -no-point-data             | until 1806
    | -noFaceZones               | ignored                    | after 1806
    | -noLinks                   | ignored                    | after 1806
    | -poly                      | ignored                    | after 1806
    | -useTimeName               | ignored                    | after 1806
    | -xml                       | ignored                    | after 1806
    |----------------------------|----------------------------|------------

Region of interest output

In some cases only a particular region of the simulation is of interest for more in-depth visualisation. The vtkWrite and ensightWrite function objects have been extended to support a flexible region-of-interest selection mechanism. If the selection sub-dictionary is not specified, then the entire mesh will be converted. With a selection sub-dictionary, the initial selection is empty and the user can define their preferred output region. The syntax is based on that of topoSet. For example,

mySubset
{
    type    vtkWrite;
    ...

    selection
    {
        box
        {
            action  use;
            source  box;
            box     (-0.1 -0.01 -0.1) (0.1 0.30 0.1);
        }
        dome
        {
            action  add;
            source  sphere;
            origin  (-0.1 -0.01 -0.1);
            radius  0.25;
        }
        centre
        {
            action  subtract;
            source  sphere;
            origin  (-0.1 -0.01 -0.1);
            radius  0.1;
        }
        ...
    }
}

[Picture]

Source code
$FOAM_SRC/fileFormats/vtk
Examples
$FOAM_TUTORIALS/heatTransfer/chtMultiRegionFoam/multiRegionHeater
$FOAM_TUTORIALS/incompressible/pimpleFoam/RAS/wingMotion/wingMotion2D˙pimpleFoam
$FOAM_TUTORIALS/incompressible/pimpleFoam/laminar/movingCone
$FOAM_TUTORIALS/incompressible/simpleFoam/motorBike
$FOAM_TUTORIALS/incompressible/simpleFoam/windAroundBuildings
$FOAM_TUTORIALS/incompressible/simpleFoam/windAroundBuildings
$FOAM_TUTORIALS/lagrangian/reactingParcelFoam/filter
$FOAM_TUTORIALS/mesh/snappyHexMesh/motorBike˙leakDetection

New function object to compute AMI patch performance

Cases that employ cyclic AMI patches are sensitive to the quality of the AMI interpolation weights. Closer inspection of the weights is now provided by the new AMIWeights function object that writes weight statistics to file during the run and VTK-based surfaces. Statistic per AMI include:

  • patch names
  • whether the patch is parallel-distributed
  • minimum and maximum sum of weights (should be 1 for a perfect match)
  • minumum and maximum interpolation stencil size

Sample output for the $FOAM_TUTORIALS/incompressible/pimpleFoam/RAS/propeller case:

# AMI
# Time  Patch   nbr_patch   distributed  src_min_weight  src_max_weight  src_average_weight src_min_neighbours  src_max_neighbours ...
0.001   AMI1    AMI2        true         9.264461e-01    1.047157e+00    1.000202e+00       1                   9                  ...
0.002   AMI1    AMI2        true         9.392015e-01    1.019850e+00    1.000039e+00       1                   8                  ...
0.003   AMI1    AMI2        true         9.239401e-01    1.049830e+00    1.000198e+00       1                   9                  ...
0.004   AMI1    AMI2        true         9.490245e-01    1.022364e+00    1.000048e+00       1                   9                  ...
0.005   AMI1    AMI2        true         9.216583e-01    1.047407e+00    1.000176e+00       1                   9                  ...
0.006   AMI1    AMI2        true         9.230133e-01    1.021246e+00    1.000040e+00       1                   9                  ...
0.007   AMI1    AMI2        true         9.201124e-01    1.050923e+00    1.000175e+00       1                   9                  ...

If the writeFields entry is set to true VTK files are written that can be used to identify where the sum of the weights is not 1, e.g.:

[Picture]

Source code
$FOAM_SRC/functionObjects/field/AMIWeights
Examples
$FOAM_TUTORIALS/incompressible/pimpleFoam/RAS/propeller

New function object to compute field extents

Quantifying how far a field has spread has been made straightforward using the new fieldExtents function object. It works out the distance between a reference point and the location at which the field exceeds a threshold value. An example for the rivuletPanel test case shows the rate at which the film traverses the panel:

[Picture]

Source code
$FOAM_SRC/functionObjects/field/fieldExtents
Examples
$FOAM_TUTORIALS/lagrangian/reactingParcelFoam/rivuletPanel

Improved residuals function object

The residuals function object has been extended to include the solver type, number of solver iterations and an indicator as to whether the equation was solved to within the specified tolerance. The full capabilities now comprise:

  • residual fields
  • solver type
  • initial residual
  • final residual
  • number of solver iterations
  • convergecnce flag

An example output for the Benard convection test case follows:

# Residuals
# Time          p_rgh_solver    p_rgh_initial   p_rgh_final     p_rgh_iters     p_rgh_converged
50              GAMG    9.294030e-03    4.311920e-05    4   1
100             GAMG    1.168520e-02    3.014190e-05    3   1
150             GAMG    6.986510e-03    1.489130e-05    3   1
200             GAMG    6.059480e-03    5.917190e-05    2   1
...

Source code
$FOAM_SRC/functionObjects/utilities/residuals
Examples
$FOAM_TUTORIALS/heatTransfer/buoyantBoussinesqPimpleFoam/BenardCells

New momentum function object

A new momentum field function object has been added that calculates the linear and (optionally) the angular momentum, reporting integral values and optionally writing the fields. An example usage might be:

momentum1
{
    type            momentum;
    libs            ("libfieldFunctionObjects.so");
    ...
    writeMomentum   yes;
    writePosition   true;
    writeVelocity   true;

    cylindrical     true;
    origin          (0 0 0);
    e1              (1 0 0);
    e3              (0 0 1);
}

Source code
$FOAM_SRC/functionObjects/field/momentum
Examples
$FOAM_TUTORIALS/incompressible/simpleFoam/pipeCyclic

New vtkCloud function object

The vtkCloud function object was introduced in OpenFOAM-v1806, and now extended for OpenFOAM-v1812.

This function object writes Lagrangian data in the VTK PolyData (.vtp) format during a simulation and simultaneous records information about the files written in an auxiliary time-series (.vtp.series) file. The restart behaviour has been improved.

When the vtkCloud is used on a restarted simulation, it parses an existing .series file to obtain a list of files and times and inappropriate entries. These are files that no longer exist in that location, and files associated with simulation times that are in the future, i.e.. we have restarted at an earlier time-step.

For additional information, the generated files now also contain a TimeValue field entry, which can be used directly in ParaView.

The largest change to this function object is the addition of selectors to define a subset of parcels to be exported. Since Lagrangian simulations often times have many more parcels than we can reasonably represent in post-processing visualisation, it can be useful to impose a stride on the output to reduce the overall numbers. Additionally it may be desirable to eliminate very small particles, particles that are moving too slowly etc. To address all the imaginable combinations, a flexible selection mechanism has been added.

The selection framework uses a combination of actions, e.g. add, subtract, subset, invert, etc.., and selection criteria (stride or field-based) to provide a flexible selection mechanism. Here is an example,

// Optional selection mechanism
selection
{
    stride
    {
        // Every 10th parcelId
        action  use;
        source  stride;
        stride  10;
    }

    T
    {
        // Only interested in a narrow temperature range
        action  subset;
        source  field;
        field   T;
        accept  (greater 280) and (less 300);
    }

    diameter
    {
        // No small particles
        action  subset;
        source  field;
        field   d;
        accept  (greater 1e-10);
    }

    Umin
    {
        // Remove slow parcels
        action  subtract;
        source  field;
        field   U;
        accept  (less 0.1);
    }
}

When the parcel selection mechanism is being used, its results are reported in the log. For example,

vtkCloud output Time: 3.2
Applying parcel filtering to 994 parcels
- use stride 4
- subtract field U : (less 0.2)
After filtering using 214/994 parcels

Source code
$FOAM_SRC/functionObjects/lagrangian/dataCloud
Examples
$FOAM_TUTORIALS/lagrangian/coalChemistryFoam/simplifiedSiwek
$FOAM_TUTORIALS/lagrangian/reactingParcelFoam/filter

New dataCloud function object

A new dataCloud function object provides a simple means of extracting parcel positions and a single field, e.g. diameter, as plain ASCII files. This extremely simple file format can be particular useful for using with scripting tools or for importing in a spreadsheet or manipulation.

# x y z d
1.453011682 0.9934118847 0.05 0.0009759297884
1.478081409 0.9845705036 0.05 0.0009735625113
1.482924483 0.0582741528 0.05 0.0009742007613
1.472664559 0.9610647605 0.05 0.0009746270844
...

Like the vtkCloud function object, the dataCloud supports an expressive means of selecting a subset of parcels for export.

Source code
$FOAM_SRC/functionObjects/lagrangian/dataCloud
Examples
$FOAM_TUTORIALS/lagrangian/coalChemistryFoam/simplifiedSiwek
$FOAM_TUTORIALS/lagrangian/reactingParcelFoam/filter

New iso-surface method

The new isoSurfaceTopo surface generation routine can be used as an alternative to the isoSurface and isoSurfaceCell options. Its advantages are

  • it should use less memory and be faster
  • it uses a topological cut along edges to ensure that all cuts use the same point (on local processors)
  • it includes a different filtering which walks the outside of every cut cell and replaces all triangles with a single polygon, supported by common formats e.g. ‘vtk‘, ‘ensight‘
  • the filtering produces a much smoother surface

Typical usage:

isoSurface
{
    type            surfaces;
    libs            ("libsampling.so");
    writeControl    writeTime;

    surfaceFormat   vtk;
    fields          ( p U );

    interpolationScheme cellPoint;

    surfaces
    (
        isoSurfaceTopo
        {
            type            isoSurfaceTopo;
            isoField        p;
            isoValue        0.0;
        }
    );
}

[Picture]

The isoSurfaceCell algorithm on a snappyHexMesh

[Picture]

The isoSurfaceTopo algorithm on a snappyHexMesh

The filtering can occasionally generate non-manifold surfaces, and can be deactivated by setting regularise false.

Following further evaluation, this iso-surface method might replace the isoSurfaceCell option in future releases.

Source code
$FOAM_SRC/sampling/surface/isoSurface