v2412: New and improved post-processing

New report generation

TOP

The foamReport function object provides a template-based text substitution system to collect OpenFOAM run data. The user-supplied template file can take the form of any plain-text file, e.g. markdown (.md), web (.html) and latex (.tex). Entries supplied using double handlebar syntax {{ENTRY}} are replaced (case insensitive). A set of common built-ins entries beginning with OF_ are provided, e.g.

  • OF_HOST: Host machine name
  • OF_CASE_NAME: Case name
  • OF_API: OpenFOAM API level
  • OF_DATE_START: Date when job was started
  • OF_CASE_PATH: file path to case
  • ...

The full set of built-in and user-supplied keys can be written using the debugKeys entry. User-defined substitutions are listed in dictionary format, where substitution models include:

  • fileRegEx : regular expression from file
  • functionObjectValue : retrieve function object result
  • dictionaryValue : value from dictionary - file-based or from registry lookup
  • environmentVariable : replace keyword with environment variable
  • userValue : replace keyword with user-supplied string:

Example usage based on a markdown template:


foamReport1
{
    // Mandatory entries (unmodifiable)
    type            foamReport;
    libs            (utilityFunctionObjects);

    template        "/myReportTemplate.md";

    substitutions
    {
        divSchemes1
        {
            type        dictionaryValue;
            object      fvSchemes;

            entries
            {
                divSchemes      "divSchemes";
            }
        }
        fvSolution1
        {
            type        dictionaryValue;
            path        "/fvSolution";

            entries
            {
                solver_p        "solvers/p/solver";
                solver_p_tol    "solvers/p/tolerance";
                solver_p_reltol "solvers/p/relTol";
                solver_U        "solvers/U/solver";
                solver_U_tol    "solvers/U/tolerance";
                solver_U_reltol "solvers/U/relTol";
            }
        }
        controlDict1
        {
            type        dictionaryValue;
            path        "/controlDict";

            entries
            {
                initial_deltaT       "deltaT";
            }
        }
        continuityErrors
        {
            type        functionObjectValue;
            functionObject continuityError1;

            entries
            {
                cont_error_local    local;
                cont_error_global   global;
                cont_error_cumulative cumulative;
            }
        }
    }

    // Optional entries (runtime modifiable)

    // Inherited entries
    ...
}

Example markdown-based template file:

# {{OF_EXECUTABLE}} : {{OF_CASE_NAME}} tutorial

- Case: {{OF_CASE_PATH}}
- Submission: {{OF_CLOCK_START}} on {{OF_DATE_START}}
- Report time: {{OF_CLOCK_NOW}} on {{OF_DATE_NOW}}

---

## Run information

| Property       | Value              |
|----------------|--------------------|
| Host           | {{OF_HOST}}        |
| Processors     | {{OF_NPROCS}}      |
| Time steps     | {{OF_TIME_INDEX}}  |
| Initial deltaT | {{initial_deltaT}} |
| Current deltaT | {{OF_TIME_DELTAT}} |
| Execution time | {{executionTime}}  |

---

## OpenFOAM information

| Property       | Value              |
|----------------|--------------------|
| Version        | {{OF_VERSION}}     |
| API            | {{OF_API}}         |
| Patch          | {{OF_PATCH}}       |
| Build          | {{OF_BUILD}}       |
| Architecture   | {{OF_BUILD_ARCH}}  |

---

## Mesh statistics

| Property          | Value                |
|-------------------|----------------------|
| Bounds            | {{OF_MESH_BOUNDS_MIN}}{{OF_MESH_BOUNDS_MAX}} |
| Number of cells   | {{OF_MESH_NCELLS}}   |
| Number of faces   | {{OF_MESH_NFACES}}   |
| Number of points  | {{OF_MESH_NPOINTS}}  |
| Number of patches | {{OF_MESH_NPATCHES}} |

---

## Linear solvers

| Property | Value          | tolerance(rel)   | Tolerance(abs)      |
|----------|----------------|------------------|---------------------|
| p        | `{{solver_p}}` | {{solver_p_tol}} | {{solver_p_reltol}} |
| U        | `{{solver_U}}` | {{solver_u_tol}} | {{solver_u_reltol}} |

---

## Numerical scehemes

The chosen divergence schemes comprised:

~~~
{{divSchemes}}
~~~

---

## Graphs

Residuals

![]({{OF_CASE_PATH}}/postProcessing/residualGraph1/{{OF_TIME}}/residualGraph1.svg)

---

## Results

Forces

![]({{OF_CASE_PATH}}/postProcessing/forceCoeffsGraph1/{{OF_TIME}}/forceCoeffsGraph1.svg)

---

Source code

Tutorial

Merge request

New graph generation

TOP

The graphFunctionObject enables users to generate SVG graphs of function object result values, e.g. to show the evolution residuals, or reduced data such as force coefficients.

A minimal example is shown below:

// Generate the result values
solverInfo1
{
    type            solverInfo;
    libs            (utilityFunctionObjects);
    fields          (U p);
}

// Describe the graph
residualGraph
{
    // Mandatory entries
    libs            (utilityFunctionObjects);

    functions
    {
        //entry
        //{
        //    // Mandatory entries
        //    object      ;
        //    entry       ;
        //
        //    // Optional entries
        //    title       ;      // Default: take from dict name
        //    colour      ; // labels in range 0-255 (255 0 0)
        //    dashes      ;   // (4 1 1)
        //}
        Ux
        {
            object      solverInfo1;
            entry       Ux_initial;
        }
        Uy
        {
            object      solverInfo1;
            entry       Uy_initial;
        }
        Uz
        {
            object      solverInfo1;
            entry       Uz_initial;
        }
        p
        {
            object      solverInfo1;
            entry       p_initial;
        }
    }

    // Optional entries
    //xMin            ;
    //xMax            ;
    //yMin            ;
    //yMax            ;
    //xlabel          ;  // "Iteration";
    //ylabel          ;  // "log10(Initial residual)";
    //width           ;
    //height          ;
    //strokeWidth     ;
    //logScaleX       ;
    //logScaleY       ;
    //drawGrid        ;

    // Inherited entries
    //...
}

Source code

Tutorial

New finite-area function object: surfaceCourantNumber

TOP

A new finite-area function object, surfaceCourantNumber, calculates the surface Courant number field at finite-area face centres.

This represents a conceptual shift from approaches like those used in the liquidFilmFoam solver, where the Courant number is computed at edge centres. By evaluating the Courant number at face centres, surfaceCourantNumber can provide a more localized and potentially more accurate measure for surface-based flow analyses.

A minimal example usage is as follows:

surfaceCourantNumber1
{
    // Mandatory entries
    type        surfaceCourantNumber;
    libs        (regionFaModels);

    // Optional entries
    area        <word>;
    result      <word>;
    phis        <word>;
    rho         <word>;

    // Inherited entries
    ...
}

Source code

Tutorial

Merge request

Improved solver function objects: Outer-loop convergence check

TOP

A convergence check for outer loops has been added to the solver function objects (scalarTransport, energyTransport and electricPotential), enabling the function object to detect and terminate when further iterations are no longer necessary. This improvement can help reduce computational overhead and streamline the solution process by eliminating unnecessary loops once convergence has been achieved.

A minimal example usage is as follows:

scalarTransport1
{
    // Optional entries
    tolerance    <scalar>;
    ...
}

Source code

Merge request