This update allows Zoltan to be used by snappyHexMesh to redistribute the mesh
after refinement and sub-setting even if some processors loose all their cells
in the process.
The majority of input parameters now support automatic unit conversion.
Units are specified within square brackets, either before or after the
value. Primitive parameters (e.g., scalars, vectors, tensors, ...),
dimensioned types, fields, Function1-s and Function2-s all support unit
conversion in this way.
Unit conversion occurs on input only. OpenFOAM writes out all fields and
parameters in standard units. It is recommended to use '.orig' files in
the 0 directory to preserve user-readable input if those files are being
modified by pre-processing applications (e.g., setFields).
For example, to specify a volumetric flow rate inlet boundary in litres
per second [l/s], rather than metres-cubed per second [m^3/s], in 0/U:
boundaryField
{
inlet
{
type flowRateInletVelocity;
volumetricFlowRate 0.1 [l/s];
value $internalField;
}
...
}
Or, to specify the pressure field in bar, in 0/p:
internalField uniform 1 [bar];
Or, to convert the parameters of an Arrhenius reaction rate from a
cm-mol-kcal unit system, in constant/chemistryProperties:
reactions
{
methaneReaction
{
type irreversibleArrhenius;
reaction "CH4^0.2 + 2O2^1.3 = CO2 + 2H2O";
A 6.7e12 [(mol/cm^3)^-0.5/s];
beta 0;
Ea 48.4 [kcal/mol];
}
}
Or, to define a time-varying outlet pressure using a CSV file in which
the pressure column is in mega-pascals [MPa], in 0/p:
boundaryField
{
outlet
{
type uniformFixedValue;
value
{
type table;
format csv;
nHeaderLine 1;
units ([s] [MPa]); // <-- new units entry
columns (0 1);
mergeSeparators no;
file "data/pressure.csv";
outOfBounds clamp;
interpolationScheme linear;
}
}
...
}
(Note also that a new 'columns' entry replaces the old 'refColumn' and
'componentColumns'. This is is considered to be more intuitive, and has
a consistent syntax with the new 'units' entry. 'columns' and
'componentColumns' have been retained for backwards compatibility and
will continue to work for the time being.)
Unit definitions can be added in the global or case controlDict files.
See UnitConversions in $WM_PROJECT_DIR/etc/controlDict for examples.
Currently available units include:
Standard: kg m s K kmol A Cd
Derived: Hz N Pa J W g um mm cm km l ml us ms min hr mol
rpm bar atm kPa MPa cal kcal cSt cP % rad rot deg
A user-time unit is also provided if user-time is in operation. This
allows it to be specified locally whether a parameter relates to
real-time or to user-time. For example, to define a mass source that
ramps up from a given engine-time (in crank-angle-degrees [CAD]) over a
duration in real-time, in constant/fvModels:
massSource1
{
type massSource;
points ((1 2 3));
massFlowRate
{
type scale;
scale linearRamp;
start 20 [CAD];
duration 50 [ms];
value 0.1 [g/s];
}
}
Specified units will be checked against the parameter's dimensions where
possible, and an error generated if they are not consistent. For the
dimensions to be available for this check, the code requires
modification, and work propagating this change across OpenFOAM is
ongoing. Unit conversions are still possible without these changes, but
the validity of such conversions will not be checked.
Units are no longer permitted in 'dimensions' entries in field files.
These 'dimensions' entries can now, instead, take the names of
dimensions. The names of the available dimensions are:
Standard: mass length time temperature
moles current luminousIntensity
Derived: area volume rate velocity momentum acceleration density
force energy power pressure kinematicPressure
compressibility gasConstant specificHeatCapacity
kinematicViscosity dynamicViscosity thermalConductivity
volumetricFlux massFlux
So, for example, a 0/epsilon file might specify the dimensions as
follows:
dimensions [energy/mass/time];
And a 0/alphat file might have:
dimensions [thermalConductivity/specificHeatCapacity];
*** Development Notes ***
A unit conversion can construct trivially from a dimension set,
resulting in a "standard" unit with a conversion factor of one. This
means the functions which perform unit conversion on read can be
provided dimension sets or unit conversion objects interchangeably.
A basic `dict.lookup<vector>("Umean")` call will do unit conversion, but
it does not know the parameter's dimensions, so it cannot check the
validity of the supplied units. A corresponding lookup function has been
added in which the dimensions or units can be provided; in this case the
corresponding call would be `dict.lookup<vector>("Umean", dimVelocity)`.
This function enables additional checking and should be used wherever
possible.
Function1-s and Function2-s have had their constructors and selectors
changed so that dimensions/units must be specified by calling code. In
the case of Function1, two unit arguments must be given; one for the
x-axis and one for the value-axis. For Function2-s, three must be
provided.
In some cases, it is desirable (or at least established practice), that
a given non-standard unit be used in the absence of specific
user-defined units. Commonly this includes reading angles in degrees
(rather than radians) and reading times in user-time (rather than
real-time). The primitive lookup functions and Function1 and Function2
selectors both support specifying a non-standard default unit. For
example, `theta_ = dict.lookup<scalar>("theta", unitDegrees)` will read
an angle in degrees by default. If this is done within a model which
also supports writing then the write call must be modified accordingly
so that the data is also written out in degrees. Overloads of writeEntry
have been created for this purpose. In this case, the angle theta should
be written out with `writeEntry(os, "theta", unitDegrees, theta_)`.
Function1-s and Function2-s behave similarly, but with greater numbers
of dimensions/units arguments as before.
The non-standard user-time unit can be accessed by a `userUnits()`
method that has been added to Time. Use of this user-time unit in the
construction of Function1-s should prevent the need for explicit
user-time conversion in boundary conditions and sub-models and similar.
Some models might contain non-typed stream-based lookups of the form
`dict.lookup("p0") >> p0_` (e.g., in a re-read method), or
`Umean_(dict.lookup("Umean"))` (e.g., in an initialiser list). These
calls cannot facilitate unit conversion and are therefore discouraged.
They should be replaced with
`p0_ = dict.lookup<scalar>("p0", dimPressure)` and
`Umean_(dict.lookup<vector>("Umean", dimVelocity))` and similar whenever
they are found.
Constructing the fields in patch order is logical, and preferable to
using the potentially arbitrary order in which the fields are specified
in the field dictionary. It also resolves the issue that the
construction of jump cyclics can fail if the patch fields are not
specified in the same order as the patches.
Omega lower limit bounding is now based on a maximum turbulence viscosity nut
rather than a minimum omega value which improves stability and robustness of
the k-omega models in case of numerical boundedness problems.
The maximum nut value is calculated by multiplying the laminar viscosity by
nutMaxCoeff which defaults to 1e5 but can be set by the user in the
momentumTransport dictionary.
The directFieldMapper has been renamed to forwardFieldMapper, and
instances where generalFieldMapper was used instead of a more simple
forward/direct type have been removed.
The patch-specific mapper interfaces, fvPatchFieldMapper and
pointPatchFieldMapper, have been removed as they did not do anything.
Patch mapping constructors and functions now take a basic fieldMapper
reference.
An fvPatchFieldMapper.H header has been provided to aid backwards
compatability so that existing custom boundary conditions continue to
compile.
Warnings about initialisation of particles with locations outside of the
mesh and about the positional inaccuracy of NCC transfers are now
accumulated and printed once per time-step. This way, the log isn't
obscured by hundreds of such warnings.
Also, the pattern in which warnings are silenced after some arbitrary
number (typically 100) have been issued has been removed. This pattern
means that user viewing the log later in the run may be unaware that a
problem is still present. Accumulated warnings are concise enough that
they do not need to be silenced. They are generated every time-step, and
so remain visible throughout the log.
The functionality necessary to write in a different unit set has been
removed. This was excessivelty complex, never used in practice, and of
little practical usage. Output numeric data, in general, is not designed
to be conveniently user-readable, so it is not important what unit
system it is written in.
and make '-explicitFeatures' the option to use explicitFeatures. When implicitFeatures
is used, a surfaceFeaturesDict file is not written out to the system directory
including blockMeshDict, surfaceFeaturesDict and snappyHexMeshDict, based on the
case surface geometry.
Description
Preconfigures blockMeshDict, surfaceFeaturesDict and snappyHexMeshDict
files based on the case surface geometry files.
Starting from a standard OpenFOAM case, this utility locates surface
geometry files, e.g. OBJ, STL format, in the constant/geometry directory.
It writes out the configuration files for mesh generation with
snappyHexMesh based on assumptions which can be overridden by options on
the command line.
The utility processes the surface geometry files, attempting to anticipate
their intended purpose, trying in particular to recognise whether the
domain represents an external or internal flow. If there is a surface
which is closed, and is either single or surrounds all other surfaces,
then it is assumed that it forms the external boundary of an internal
flow. This assumption is overridden if the bounds of the background mesh
are specified using the '-bounds' option and they are more than 50% larger
than the surface bounds.
Surfaces which form boundaries of the domain may contain named regions
that are intended to become patches in the final mesh. Any surface region
whose name begins with 'inlet' or 'outlet' will become a patch of the same
name in the final mesh. On an external surface (for an internal flow),
regions can be identified as inlets and outlets using the '-inletRegions'
and '-outletRegions' options, respectively. When either option specifies a
single region, the resulting patch name will be specifically 'inlet' or
'outlet', respectively. Surfaces which are contained within the domain,
which do not surround or intersect other surfaces, are assumed by default
to be wall patches. Any closed surface which surrounds another (but not an
external surface) is used to form a cellZone within the mesh. Any surface
can be specifically identified as a cellZone with the '-cellZones' option,
with the additional '-baffles' and '-rotatingZones' options available to
assign a surface to a more specific use.
The background mesh for snappyHexMesh is a single block generated by
blockMesh, configured using a blockMeshDict file. The block bounds are
automatically calculated, but can be overridden by the '-bounds'
option. The number of cells is calculated to produce a fairly small
prototype mesh. The cell density can be overridden by the '-nCells' option
or can be scaled up by an integer factor using the '-refineBackground'
option. When the background mesh is required to form patches in the final
mesh, e.g. for an external flow, the user can specify the names and types
of the patches corresponding to the six block faces using options such as
'-xMinPatch', '-xMaxPatch', etc. The name and type of the default patch,
formed from block faces which are not configured, can also be specified
with the '-defaultPatch' option. The utility provides placeholder entries
for all block faces unless the '-clearBoundary' option is used. A special
'-cylindricalBackground' option generates a cylindrical background mesh,
oriented along the z-axis along x = y = 0.
The snappyHexMesh configuration is generated automatically, applying a set
of defaults to the main configuration parameters. By default, explicit
feature capturing is configured, for which a surfaceFeaturesDict file is
written for the user to generate the features files with the
surfaceFeatures utility. Implicit feature capturing can alternatively be
selected with the '-implicitFeatures' option. Refinement levels can be
controlled with a range of options including: '-refinementLevel' for the
baseline refinement level; '-refinementSurfaces' for levels on specific
surfaces; '-refinementRegions' for levels inside specific surfaces;
'-refinementBoxes' for quick, box-shaped refinement regions specified by
min and max bounds; '-refinementDists' for distance-based refinement; and
'-nCellsBetweenLevels' to control the transition between refinement
levels. A '-layers' option specifies additional layers of cells at wall
boundaries. The insidePoint parameter is set to '(0 0 0)' by default but
can be overridden using the '-insidePoint' option.
Cell-to-cell interpolation has been moved to a hierarchy separate from
meshToMesh, called cellsToCells. The meshToMesh class is now a
combination of a cellsToCells object and multiple patchToPatch objects.
This means that when only cell-to-cell interpolation is needed a basic
cellsToCells object can be selected.
Cell-to-cell and vol-field-to-vol-field interpolation now has two well
defined sets of functions, with a clear distinction in how weights that
do not sum to unity are handled. Non-unity weights are either
normalised, or a left-over field is provided with which to complete the
weighted sum.
The left-over approach is now consistently applied in mapFieldsPar,
across both the internal and patch fields, if mapping onto an existing
field in the target case. Warning are now generated for invalid
combinations of settings, such as mapping between inconsistent meshes
without a pre-existing target field.
All mapping functions now take fields as const references and return tmp
fields. This avoids the pattern in which non-const fields are provided
which relate to the source, and at some point in the function transfer
to the target. This pattern is difficult to reason about and does not
provide any actual computational advantage, as the fields invariably get
re-allocated as part of the process anyway.
MeshToMesh no longer stores the cutting patches. The set of cutting
patches is not needed anywhere except at the point of mapping a field,
so it is now supplied to the mapping functions as an argument.
The meshToMesh topology changer no longer supports cutting patch
information. This did not previously work. Cutting patches either get
generated as calculated, or they require a pre-existing field to specify
their boundary condition. Neither of these options is suitable for a
run-time mesh change.
More code has been shared with patchToPatch, reducing duplication.
The timeName() function simply returns the dimensionedScalar::name() which holds
the user-time name of the current time and now that timeName() is no longer
virtual the dimensionedScalar::name() can be called directly. The timeName()
function implementation is maintained for backward-compatibility.
in particular to support setting constant property fields in the constant
directory.
Usage: setFields [OPTIONS]
options:
-case <dir> specify alternate case directory, default is the cwd
-constant include the 'constant/' dir in the times list
-dict <file> read control dictionary from specified location
-fileHandler <handler>
override the fileHandler
-hostRoots <((host1 dir1) .. (hostN dirN))>
slave root directories (per host) for distributed running
-latestTime select the latest time
-libs '("lib1.so" ... "libN.so")'
pre-load libraries
-noFunctionObjects
do not execute functionObjects
-noZero exclude the '0/' dir from the times list
-parallel run in parallel
-region <name> specify alternative mesh region
-roots <(dir1 .. dirN)>
slave root directories for distributed running
-time <time> specify a single time value to select
-srcDoc display source code in browser
-doc display application documentation in browser
-help print the usage
Lagrangian is now compatible with the meshToMesh topology changer. If a
cloud is being simulated and this topology changer is active, then the
cloud data will be automatically mapped between the specified sequence
of meshes in the same way as the finite volume data. This works both for
serial and parallel simulations.
In addition, mapFieldsPar now also supports mapping of Lagrangian data
when run in parallel.
This reference represents unnecessary storage. The mesh can be obtained
from tracking data or passed to the particle evolution functions by
argument.
In addition, removing the mesh reference makes it possible to construct
as particle from an Istream without the need for an iNew class. This
simplifies stream-based transfer, and makes it possible for particles to
be communicated by a polyDistributionMap.
This reduces duplication and inconsistency between the List, Field, Map,
and PtrList variants. It also allows for future extension to other
container types such as DynamicList.
in which different solver modules can be selected in each region to for complex
conjugate heat-transfer and other combined physics problems such as FSI
(fluid-structure interaction).
For single-region simulations the solver module is selected, instantiated and
executed in the PIMPLE loop in the new foamRun application.
For multi-region simulations the set of solver modules, one for each region, are
selected, instantiated and executed in the multi-region PIMPLE loop of new the
foamMultiRun application.
This provides a very general, flexible and extensible framework for complex
coupled problems by creating more solver modules, either by converting existing
solver applications or creating new ones.
The current set of solver modules provided are:
isothermalFluid
Solver module for steady or transient turbulent flow of compressible
isothermal fluids with optional mesh motion and mesh topology changes.
Created from the rhoSimpleFoam, rhoPimpleFoam and buoyantFoam solvers but
without the energy equation, hence isothermal. The buoyant pressure
formulation corresponding to the buoyantFoam solver is selected
automatically by the presence of the p_rgh pressure field in the start-time
directory.
fluid
Solver module for steady or transient turbulent flow of compressible fluids
with heat-transfer for HVAC and similar applications, with optional
mesh motion and mesh topology changes.
Derived from the isothermalFluid solver module with the addition of the
energy equation from the rhoSimpleFoam, rhoPimpleFoam and buoyantFoam
solvers, thus providing the equivalent functionality of these three solvers.
multicomponentFluid
Solver module for steady or transient turbulent flow of compressible
reacting fluids with optional mesh motion and mesh topology changes.
Derived from the isothermalFluid solver module with the addition of
multicomponent thermophysical properties energy and specie mass-fraction
equations from the reactingFoam solver, thus providing the equivalent
functionality in reactingFoam and buoyantReactingFoam. Chemical reactions
and/or combustion modelling may be optionally selected to simulate reacting
systems including fires, explosions etc.
solid
Solver module for turbulent flow of compressible fluids for conjugate heat
transfer, HVAC and similar applications, with optional mesh motion and mesh
topology changes.
The solid solver module may be selected in solid regions of a CHT case, with
either the fluid or multicomponentFluid solver module in the fluid regions
and executed with foamMultiRun to provide functionality equivalent
chtMultiRegionFoam but in a flexible and extensible framework for future
extension to more complex coupled problems.
All the usual fvModels, fvConstraints, functionObjects etc. are available with
these solver modules to support simulations including body-forces, local sources,
Lagrangian clouds, liquid films etc. etc.
Converting compressibleInterFoam and multiphaseEulerFoam into solver modules
would provide a significant enhancement to the CHT capability and incompressible
solvers like pimpleFoam run in conjunction with solidDisplacementFoam in
foamMultiRun would be useful for a range of FSI problems. Many other
combinations of existing solvers converted into solver modules could prove
useful for a very wide range of complex combined physics simulations.
All tutorials from the rhoSimpleFoam, rhoPimpleFoam, buoyantFoam, reactingFoam,
buoyantReactingFoam and chtMultiRegionFoam solver applications replaced by
solver modules have been updated and moved into the tutorials/modules directory:
modules
├── CHT
│ ├── coolingCylinder2D
│ ├── coolingSphere
│ ├── heatedDuct
│ ├── heatExchanger
│ ├── reverseBurner
│ └── shellAndTubeHeatExchanger
├── fluid
│ ├── aerofoilNACA0012
│ ├── aerofoilNACA0012Steady
│ ├── angledDuct
│ ├── angledDuctExplicitFixedCoeff
│ ├── angledDuctLTS
│ ├── annularThermalMixer
│ ├── BernardCells
│ ├── blockedChannel
│ ├── buoyantCavity
│ ├── cavity
│ ├── circuitBoardCooling
│ ├── decompressionTank
│ ├── externalCoupledCavity
│ ├── forwardStep
│ ├── helmholtzResonance
│ ├── hotRadiationRoom
│ ├── hotRadiationRoomFvDOM
│ ├── hotRoom
│ ├── hotRoomBoussinesq
│ ├── hotRoomBoussinesqSteady
│ ├── hotRoomComfort
│ ├── iglooWithFridges
│ ├── mixerVessel2DMRF
│ ├── nacaAirfoil
│ ├── pitzDaily
│ ├── prism
│ ├── shockTube
│ ├── squareBend
│ ├── squareBendLiq
│ └── squareBendLiqSteady
└── multicomponentFluid
├── aachenBomb
├── counterFlowFlame2D
├── counterFlowFlame2D_GRI
├── counterFlowFlame2D_GRI_TDAC
├── counterFlowFlame2DLTS
├── counterFlowFlame2DLTS_GRI_TDAC
├── cylinder
├── DLR_A_LTS
├── filter
├── hotBoxes
├── membrane
├── parcelInBox
├── rivuletPanel
├── SandiaD_LTS
├── simplifiedSiwek
├── smallPoolFire2D
├── smallPoolFire3D
├── splashPanel
├── verticalChannel
├── verticalChannelLTS
└── verticalChannelSteady
Also redirection scripts are provided for the replaced solvers which call
foamRun -solver <solver module name> or foamMultiRun in the case of
chtMultiRegionFoam for backward-compatibility.
Documentation for foamRun and foamMultiRun:
Application
foamRun
Description
Loads and executes an OpenFOAM solver module either specified by the
optional \c solver entry in the \c controlDict or as a command-line
argument.
Uses the flexible PIMPLE (PISO-SIMPLE) solution for time-resolved and
pseudo-transient and steady simulations.
Usage
\b foamRun [OPTION]
- \par -solver <name>
Solver name
- \par -libs '(\"lib1.so\" ... \"libN.so\")'
Specify the additional libraries loaded
Example usage:
- To run a \c rhoPimpleFoam case by specifying the solver on the
command line:
\verbatim
foamRun -solver fluid
\endverbatim
- To update and run a \c rhoPimpleFoam case add the following entries to
the controlDict:
\verbatim
application foamRun;
solver fluid;
\endverbatim
then execute \c foamRun
Application
foamMultiRun
Description
Loads and executes an OpenFOAM solver modules for each region of a
multiregion simulation e.g. for conjugate heat transfer.
The region solvers are specified in the \c regionSolvers dictionary entry in
\c controlDict, containing a list of pairs of region and solver names,
e.g. for a two region case with one fluid region named
liquid and one solid region named tubeWall:
\verbatim
regionSolvers
{
liquid fluid;
tubeWall solid;
}
\endverbatim
The \c regionSolvers entry is a dictionary to support name substitutions to
simplify the specification of a single solver type for a set of
regions, e.g.
\verbatim
fluidSolver fluid;
solidSolver solid;
regionSolvers
{
tube1 $fluidSolver;
tubeWall1 solid;
tube2 $fluidSolver;
tubeWall2 solid;
tube3 $fluidSolver;
tubeWall3 solid;
}
\endverbatim
Uses the flexible PIMPLE (PISO-SIMPLE) solution for time-resolved and
pseudo-transient and steady simulations.
Usage
\b foamMultiRun [OPTION]
- \par -libs '(\"lib1.so\" ... \"libN.so\")'
Specify the additional libraries loaded
Example usage:
- To update and run a \c chtMultiRegion case add the following entries to
the controlDict:
\verbatim
application foamMultiRun;
regionSolvers
{
fluid fluid;
solid solid;
}
\endverbatim
then execute \c foamMultiRun