v2312: New and improved post-processing
The new abaqusMesh set derives sample positions from file using the Abaqus mesh point format. Example usage:
sets
{
cone25 // user-specified set name
{
type abaqusMesh;
file "abaqusMesh.inp";
// Optional entries
// Scale, e.g. mm to m
scale 0.001;
// Search distance when the sample point is not located in a cell
maxDist 0.25;
...
}
}
Tutorials
- TBA
Source code
The new Abaqus set writer converts OpenFOAM set data to Abaqus format. Example usage:
T
{
type sets;
setFormat abaqus;
fields (T);
sets
{
...
}
}
Optional format options are provided in an abaqus sub-dictionary within the formatOptions dictionary:
formatOptions
{
abaqus
{
format ascii;
// Optional entries
// Custom header: $ entries are substituions
header
(
"** OpenFOAM abaqus output"
"** Project $FOAM_CASE"
"** File $FILE_NAME"
"** $FIELD_NAME Time t=$TIME"
);
// Write geometry in addition to field data
writeGeometry yes;
// Null value when sample value is not found
// Default is scalar::min
nullValue 0;
// Insert additional time sub-directory in the output path
// - yes : postProcessing/<fo-name>/<time>/<file>
// - no : postProcessing/<fo-name>/<file>
useTimeDir no;
// Available when 'useTimeDir' is 'no' to disambiguate file names
// Time base for output file names:
// - 'time' : <base>.inp_<field>.<time>
// - 'iteration' : <base>.inp_<field>.<iteration>
timeBase iteration;
// Optional start counters when using timeBase iteration
writeIndex
(
T 1
);
...
}
}
Tutorials
- TBA
Source code
The patchSeed sampled set now computes sample seeds uniformly across the patch. The earlier implementation sampled the face index uniformly across the patch, with the side effect of a bias towards smaller faces.
streamline5
{
type streamLine;
libs (fieldFunctionObjects);
U U;
fields (U p);
setFormat vtk;
direction forward;
lifeTime 20000;
cloud particleTracks;
seedSampleSet
{
type patchSeed;
axis xyz;
patches ("inlet1");
maxPoints 40;
}
interpolationScheme cellPoint;
trackLength 0.001;
}
Tutorial
Source code
Merge request
- Merge request 647
The new caseInfo function object generates solver and case information at runtime, or as part of post-processing. Data collected includes:
- Meta data: case name, path, number of time directories etc.
- Dictionary entries : extract all/selection from any input dictionaries
- optionally use scoping, e.g. 'solvers/U/solver' to get the U linear solver from fvSolution
- supports wildcards, e.g. if the fvSolution U solver keyword used "(U|k|epsilon)"
- limit selections using 'include' or 'exclude' lists of entry names to include/exclude
- Mesh statistics : number of points, faces, cells; bounds; zone names etc.
- Function object results : e.g. cached values for function objects results
Example usage:
caseInfo1
{
type caseInfo;
libs (utilityFunctionObjects);
writeFormat json; // josn | dictionary
// List of dictionaries - retrieve using 'path' or registered 'name'
dictionaries
{
fvSolution
{
name "fvSolution";
// include all entries by default
}
controlDict
{
path "system/controlDict";
include
(
"application"
"deltaT"
"startTime"
"endTime"
);
}
}
// Extract function object results
functionObjects (pressureDifference sample1);
}
Example output
{
"meta" : {
"case" : "heatExchanger",
"path" : "chtMultiRegionSimpleFoam/heatExchanger",
"regions" : ["air", "porous"],
"nTimes" : 7,
"nProc" : 1
},
"regions" : {
"air" : {
"mesh" : {
"nGeometricD" : 3,
"nSolutionD" : 3,
"nPoints" : 252991,
"nFaces" : 739260,
"nCells" : 243000,
"nPatches" : 4,
"pointZones" : [],
"faceZones" : ["rotorBlades", "baffleFaces"],
"cellZones" : ["cylinder", "innerCylinder", "rotor"],
"boundsMin" : [0, 0, 0],
"boundsMax" : [5.000000e-01, 5.000000e-01, 5.000000e-01],
"clouds" : []
},
"boundary" : {
"types" : {
"walls" : "wall",
"inlet" : "patch",
"outlet" : "patch",
"blades" : "wall"
},
"fields" : {
"alphat" : {
"walls" : "compressible::alphatWallFunction",
"inlet" : "calculated",
"outlet" : "calculated",
"blades" : "compressible::alphatWallFunction"
},
"nut" : {
"walls" : "nutkWallFunction",
"inlet" : "calculated",
"outlet" : "calculated",
"blades" : "nutkWallFunction"
},
"p" : {
"walls" : "calculated",
"inlet" : "calculated",
"outlet" : "calculated",
"blades" : "calculated"
...
Source code
Dynamic Mode Decomposition (DMD) functionality was introduced in OpenFOAM v2006 and later extended in OpenFOAM v2106. With this release, OpenFOAM learns one of the key advantages of DMD: the capability to generate a field based on given modes and their associated dynamics, without the need for any CFD computations at arbitrary intermediate and/or future time points.
This functionality allows users to condense an entire simulation into a few modes and mode dynamics, and subsequently generate fields at any desired time or predict their future states, all without the need for additional CFD analyses.
Another potential advantage is the ability for users to shorten their simulations and forecast the future states of the flow field without the need for extensive simulations. This can be achieved by using the modes and mode dynamics obtained from a shorter-duration simulation.
It should be noted that the quality of results depends on the capabilities of the underlying reduced-order model, and the quality of the input data. To improve the reconstruction results, one needs to make sure that modes are correctly extracted from the flow.
A minimal example by using system/ROMfieldsDict
is as follows:
// Mandatory entries
ROMmodel <word>;
field <word>;
object <word>;
deltaT <scalar>;
time <scalar>;
modes <labelList>;
amplitudes <complexList>;
eigenvalues <complexList>;
// Optional entries
startTime <scalar>;
dimensions <dimensionSet>;
// Inherited entries
...
The illustration below shows the velocity field obtained from the two-dimensional cylinder tutorial, and its reconstruction by using the DMD modes and dynamics without running the simulation:
Source code
- $FOAM_UTILITIES/postProcessing/miscellaneous/createROMfields/createROMfields.C
- $FOAM_UTILITIES/postProcessing/miscellaneous/createROMfields/ROMmodels/DMD/DMD.H
Tutorial
References
- Kiewat, M. (2019). Streaming modal decomposition approaches for vehicle aerodynamics. PhD thesis. Munich: Technical University of Munich. URL:mediatum.ub.tum.de/doc/1482652/1482652.pdf
Attribution
-
OpenCFD would like to acknowledge and thank Marco Kiewat for his contributions, elaborate suggestions and help, and critical recommendations.
Merge request
- Merge request 639
The noise utility now supports a user-defined sampling frequency (keyword: sampleFreq
) as well as the default automatic calculation from the time information. For improved readability, the upper and lower frequency limits are now specified as minFreq
and maxFreq
(the old keywords continue to be supported), i.e.
// Lower frequency limit, default 25 Hz, former name 'fl'
minFreq 25;
// Upper frequency limit, default 10 kHz, former name 'fu'
maxFreq 10000;
// OPTIONAL - Sample frequency
sampleFreq 100;
If the time is assessed to be non-uniform when calculating the frequency from the sampled times, the utility now emits a warning instead of an error since in many cases the non-uniformity is a spurious error when the deltaT is very small.
Source code
- $FOAM_SRC/surfMesh/writers/ensight/ensightSurfaceWriter.H
- $FOAM_SRC/randomProcesses/noise/noiseModels/noiseModel/noiseModel.H
Tutorial
Issue
- Issue 2999
Time values for EnSight writers can now be specified by the user instead of using the default fixed format and precision. For example,
formatOptions
{
ensight
{
timeFormat general; // Format for time directory names (general | fixed | scientific); default scientific
timePrecision 12; // Default = 5
}
}
These new format options are particularly useful when using small time-steps, e.g. in combination with pressure sampling for the noise utility.
Source code
- $FOAM_SRC/surfMesh/writers/ensight/ensightSurfaceWriter.H
- $FOAM_SRC/functionObjects/utilities/ensightWrite/ensightWrite.H
Issue
- Merge request 634
The Lagrangian function object WeberNumber
is introduced for kinematic parcels to monitor the relative importance of a particle's inertia compared to its surface tension.
A minimal example usage is as follows:
cloudFunctions
{
KinematicWeberNumber1
{
// Mandatory entries
type WeberNumber;
sigma <scalar>;
}
...
Source code
Tutorial
Merge request
- Merge request 648
In some workflows the sampled surfaces may depend on quantities such as face zones that appear and disappear during the course of the simulation. So although evaluating for a surface field value on an empty surface would normally indicate a serious error in the setup, in other cases this is expected. The additional keyword empty-surface
allows the user to specify the desired behaviour when an empty surface is encountered.
A minimal example:
surfaceFieldValueFaceZone1
{
type surfaceFieldValue;
libs (fieldFunctionObjects);
...
regionType faceZone;
empty-surface warn; // default | warn | ignore | strict
}
Source code
Issue
- Issue 2966