7.11. User Defined Postprocessing via userDefinedFields#

In Flow360, users can specify custom expressions to calculate outputs based on some solver variables. These variables can be used in the outputFields of volumeOutput, surfaceOutput, sliceOutput, isoSurfaceOutput and monitorOutput.

We will illustrate how to use this feature using several example.

Note

We provide a complete list of available functions and some guidelines in our knowledge base.

7.11.1. Custom Output Variable#

In this example, we compute the total pressure coefficient for the entire domain of an om6Wing simulation. For the definition of the total pressure coefficient please see here.

First we need to define the expression for total pressure coefficient.

1"userDefinedFields": [
2    {
3        "name": "TotalPressureCoeff",
4        "expression": "double gamma = 1.40; double pow1 = gamma/(gamma-1); double pow2 = (gamma-1) / 2; double MachRefSq = MachRef * MachRef; double Mach = sqrt(primitiveVars[1] * primitiveVars[1] + primitiveVars[2] * primitiveVars[2] + primitiveVars[3] * primitiveVars[3]) / sqrt(gamma * primitiveVars[4] / primitiveVars[0]);  double MachSq = Mach * Mach; TotalPressureCoeff = (gamma*primitiveVars[4]*pow((1+pow2*MachSq),pow1)-pow((1+pow2*MachRefSq),pow1))/(gamma/2*MachRefSq);"
5    }
6]

A statement-by-statement breakdown of the above expression is shown in following table:

Expression

Explanation

double gamma = 1.40;....

A declaration of local variables that can be used in subsequent expression.

double Mach = sqrt(primit....

Still a declaration. But the Mach number is calculated locally even though it is a valid option for outputFields. This is an example that not all the pre-defined output variables are available to be used in the expression.

TotalPressureCoeff = (gamma*pri....

This assigns the final result to the total pressure coefficient.Note that the output variable name in the expression (TotalPressureCoeff) is exactly the same as its name entry in the JSON.

Then we need to add TotalPressureCoeff in one of the outputs. Here we use volumeOutput.

 1"volumeOutput": {
 2	"outputFormat": "paraview",
 3	"animationFrequency": -1,
 4	"animationFrequencyOffset": 0,
 5	"animationFrequencyTimeAverage": -1,
 6	"animationFrequencyTimeAverageOffset": 0,
 7	"computeTimeAverages": false,
 8	"startAverageIntegrationStep": 0,
 9	"outputFields": ["TotalPressureCoeff"]
10}

7.11.2. Custom surface integral#

In Flow360 we have added a new type of monitor which is called surface-integral monitor in addition to the probe monitor which monitor quantities at a set of given coordinates. The surface-integral monitor will try to compute the surface integral of the given variable on given patches. Here we show an example of calculating the pressure force on a no-slip wall as an example.

1"userDefinedFields": [
2    {
3        "name": "PressureForce",
4        "expression": "double prel = primitiveVars[4] - pressureFreestream;  PressureForce[0] = prel * nodeNormals[0]; PressureForce[1] = prel * nodeNormals[1]; PressureForce[2] = prel * nodeNormals[2];"
5    }
6]

Note that the nodeNormals is a vector whose direction is the normal of the given patch at each node and the magnitude is the area associated with the node. Therefore the right hand side of the PressureForce corresponds to the red part of the following equation for pressure force:

(7.11.1)#\[\overrightarrow{\mathbf{f_p}} = \int {\color{Red} \left(p - p_{ref}\right )d\overrightarrow{\mathbf{A}}}\]

where the \(\overrightarrow{\mathbf{f_p}}\) is the pressure force, \(p_{ref}\) is the free steam pressure. Surface integrals for scalar outputs should use magnitude(nodeNormals) instead to include the area (\(dA\)) in integral. Otherwise the result will be a summation of the value over the nodes instead of surface area integral.

And in the monitorOutput section, we have:

 1"monitorOutput": {
 2    "monitors": {
 3        "PressureForceOnWings": {
 4            "type": "surfaceIntegral",
 5            "surfaces": [
 6                "wing1",
 7                "wing2"
 8            ],
 9            "outputFields": [
10                "PressureForce"
11            ]
12        }
13    }
14}

which means that we want PressureForce integral computed on patch wing1 and patch wing2 as a whole.