- While a rectilinear mesh can be created with blockMesh, not every mesh
created with blockMesh will satisfy the requirements for being a
rectilinear mesh.
This alternative to blockMesh uses a single block that is aligned
with the xy-z directions and specifications of the control points,
mesh divisions and expansion ratios. For example,
x
{
points ( -13.28 -0.10 6.0 19.19 );
nCells ( 10 12 10 );
ratios ( 0.2 1 5 );
}
y { ... }
z { ... }
With only one block, the boundary patch definition is simple and the
canonical face number is used directly. For example,
inlet
{
type patch;
faces ( 0 );
}
outlet
{
type patch;
faces ( 1 );
}
sides
{
type patch;
faces ( 2 3 );
}
...
- After a mesh is defined, it is trivial to retrieve mesh-related
information such as cell-volume, cell-centres for any i-j-k location
without an actual polyMesh.
STYLE: remove -noFunctionObjects from blockMesh
- no time loop, so function objects cannot be triggered anyhow.
- Extended runTimePostProcessing to include access to "live"
simulation objects such a geometry patches and sampled surfaces
stored on the "functionObjectObjects" registry.
- Add 'live' runTimePostProcessing of cloud data.
Extracts position and fields from the cloud via its objectRegistry writer
- For the "live" simulation objects, there are two new volume filters
that work directly with the OpenFOAM volume fields:
* iso-surface
* cutting planes
Both use the VTK algorithms directly and support multiple values.
Eg, can make multiple iso-levels or multiple planes parallel to each
other.
- When VTK has been compiled with MPI-support, parallel rendering will
be used.
- Additional title text properties (shadow, italic etc)
- Simplified handling of scalar-bar and visibility switches
- Support multiple text positions. Eg, for adding watermark text.
- fits better into the general sampling framework, improves flexibilty
and allows code reduction.
ENH: include surface fields on sampledSurfaces that support it
- implemented as lazy evaluation with an additional update() method.
This avoids unnecessary changes until the values are actually
required.
- apply mesh motion changes for momentum, volFieldValue,
specieReactionRates function objects
- changed the sectorCoeffs keyword to 'point' from 'axisPt'
for more similarity with other dictionaries.
Continue to accept 'axisPt' for compatibility.
- the utility had automatic triangulation removed some time ago, but
never changed its name.
- catch old uses with a surfaceMeshTriangulate deprecated script
- this corresponds to 'never match', which may be useful in combination
with -constant selection.
Eg,
surfaceMeshTriangulate -constant -time none
selects only the constant entry and suppresses any automatic time loop
STYLE: adjust help for the standard -times option
- indicate that times can be comma or space separated, since this is
otherwise not apparent. Don't mention semicolon separators in the help
since that just adds even more clutter.
- support .vtp format for geometry, surface, line, cloud.
- use native reader for handling vtk, vtp, obj, stl surface files.
For other formats, use the MeshedSurface (the surfMesh lib) to
handle reading and Foam::vtk::Tools::Patch to handle the
conversion to vtkPolyData. This combination is more memory efficient.
- update tutorial case to include vtp surface geometry
- this allows more use of the runTimePostProcessing functionObject
that will fail more gracefully if the proper version could not be
built.
The dummy functionObject simply emits a message that it is not available.
- makes the intent clearer and avoids the need for additional
constructor casting. Eg,
labelList(10, Zero) vs. labelList(10, 0)
scalarField(10, Zero) vs. scalarField(10, scalar(0))
vectorField(10, Zero) vs. vectorField(10, vector::zero)
- Now also responds to the contents of the trigger file,
processing action= contents similar to used with external coupling.
Previously it only handled an action that was defined in the
dictionary. With this update, the user can chose a diferent action
simply by echoing the appropriate action string into the trigger
file.
Reports the min|max|average AMI weights to text file and optionally
writes VTK surfaces of the sum of the weights, and mask field for
ACMI patches.
Example usage:
AMIWeights
{
type AMIWeights;
libs ("libfieldFunctionObjects.so");
writeControl writeTime;
writeFields yes;
}
Reference:
Comte-Bellot, G., and Corrsin, S., "Simple Eulerian Time Correlation of
Full- and Narrow-Band Velocity Signals in Grid-Generated, 'Isotropic'
Turbulence," Journal of Fluid Mechanics, Vol. 48, No. 2, 1971,
pp. 273–337.
- Uses the user-specified value for outputTemperature:
{
type externalCoupledTemperature;
outputTemperture fluid; // or wall;
}
Otherwises uses 'wall' as a default (for compatibility) and emits a
warning.
The T.out header now reflects the type of output. Eg,
# Values: area Tfluid qDot htc
- tutorials based on squareBend used Default_Boundary_Region explicitly
defined since they predated the defaultPatch renaming (2008).
The name 'Default_Boundary_Region' was for convenience as the default
name when converting to PROSTAR or CCM formation, but can now be
changed to something more generic.
- define wall boundary conditions for squareBend using a general regex
to allow future splitting of wall types by name.
- check if the first argument corresponds to an OpenFOAM value for
'true' (as per Switch).
True == 't', 'y', 'true', 'yes', 'on'. Everything else is not true.
- when the first argument is '-dict', it initializes the value
with a query via foamDictionary.
Eg,
isTrue -dict mydict -entry parallel
==> value=$(foamDictionary mydict -entry parallel -value)
isTrue $value
a missing entry is silently treated as false.
ENH: add getNumberOfPatchFaces function in RunFunctions
- simple extraction of nFaces from boundary file for given patch/region
- now supports a parcel selection mechanism like vtkCloud,
giving the ability to select a subset of parcels.
For example, a given stride, or removal of parcels with a small
diameter.
Eg,
dataCloud output Time: 3.2
Applying parcel filtering to 994 parcels
- add stride 4
- subtract field U : (less 0.2)
After filtering using 214/994 parcels
- add output precision control for dataCloud
- parallel output.
The output is now postProcessing/<name> for similar reasoning as
mentioned in #866 - better alignment with other function objects, no
collision with foamToVTK output.
- align the input parameters with those of vtkCloud so that we can
specify the ASCII precision and the padding width for the output
file names as well.
- emit TimeValue field, support file series generation
- support internal or boundary meshes, combining the result into a vtm
file.
- can restrict conversion based on zone names, enclosing volumes,
bounding box
- use parallel list writing, beginDataArray methods.
- use static_assert to restrict conversion of non-label integral types
- cache .vtp.series information by fileName instead of by cloud name.
This issues if the output directory changes, and simplifies code.
ENH: emit TimeValue in files generated by vtkCloud
- additional information for passing to ParaView
ENH: vtkCloud output to postProcessing/ (issue #866)
- better alignment with other function objects, no collision with
foamToVTK output.
- deprecate dimensionedType constructors using an Istream in favour of
versions accepting a keyword and a dictionary.
Dictionary entries are almost the exclusive means of read
constructing a dimensionedType. By construct from the dictionary
entry instead of doing a lookup() first, we can detect possible
input errors such as too many tokens as a result of a input syntax
error.
Constructing a dimensionedType from a dictionary entry now has
two forms.
1. dimensionedType(key, dims, dict);
This is the constructor that will normally be used.
It accepts entries with optional leading names and/or
dimensions. If the entry contains dimensions, they are
verified against the expected dimensions and an IOError is
raised if they do not correspond. On conclusion, checks the
token stream for any trailing rubbish.
2. dimensionedType(key, dict);
This constructor is used less frequently.
Similar to the previous description, except that it is initially
dimensionless. If entry contains dimensions, they are used
without further verification. The constructor also includes a
token stream check.
This constructor is useful when the dimensions are entirely
defined from the dictionary input, but also when handling
transition code where the input dimensions are not obvious from
the source.
This constructor can also be handy when obtaining values from
a dictionary without needing to worry about the input dimensions.
For example,
Info<< "rho: " << dimensionedScalar("rho", dict).value() << nl;
This will accept a large range of inputs without hassle.
ENH: consistent handling of dimensionedType for inputs (#1083)
BUG: incorrect Omega dimensions (fixes#2084)
- helps reduce clutter in the topoSetDict files.
Caveats when using this.
The older specification styles using "name" will conflict with the
set name. Eg,
{
name f0
type faceSet;
action add;
source patchToFace;
sourceInfo
{
name inlet;
}
}
would flattened to the following
{
name f0
type faceSet;
action add;
source patchToFace;
name inlet;
}
which overwrites the "name" used for the faceSet.
The solution is to use the updated syntax:
{
name f0
type faceSet;
action add;
source patchToFace;
patch inlet;
}
- old 'DELETE' enum was easily confused with 'REMOVE', which removes
the set, not the elements from the set.
- provide corresponding subtractSet() method
STYLE: HashSet set/unset instead of insert/erase methods in topoSetSource
- simplifies switching to/from bitSet storage
Update of overRhoPimpleDyMFoam and overInterDyMFoam solvers.
Adding corresponding tutorials with best possible settings
The main effort was put on reducing pressure spikes as the
stencil change with hole cells on the background mesh.
- writes positions and a single field (eg, diameter) in plain ASCII files,
suitable for importing in a spreadsheet or manipulation with
scripting tools.
- code integrated from
https://develop.openfoam.com/Community/OpenFOAM-addOns
New name: findObject(), cfindObject()
Old name: lookupObjectPtr()
Return a const pointer or nullptr on failure.
New name: findObject()
Old name: --
Return a non-const pointer or nullptr on failure.
New name: getObjectPtr()
Old name: lookupObjectRefPtr()
Return a non-const pointer or nullptr on failure.
Can be called on a const object and it will perform a
const_cast.
- use these updated names and functionality in more places
NB: The older methods names are deprecated, but continue to be defined.
Description
Calculates the spatial minimum and maximum extents of a field
The extents are derived from the bound box limits after identifying
the locations where field values exceed the user-supplied threshold
value.
Usage
Example of function object specification:
fieldExtents1
{
type fieldExtents;
libs ("libfieldFunctionObjects.so");
...
writeToFile yes;
log yes;
fields (alpha);
threshold 0.5;
patches ();
}
Where the entries comprise:
Property | Description | Required | Default
type | type name: fieldExtents | yes |
writeToFile | write extents data to file | no | yes
log | write extents data to standard output | no | yes
internalField | Process the internal field | no | yes
threshold | Field value to identify extents boundary | yes |
referencePosition | Reference position | no | (0 0 0)
fields | list of fields to process | yes |
patches | list of patches to process | no | <all>
Output data is written to the file \<timeDir\>/fieldExtents.dat
Note
For non-scalar fields, the magnitude of the field is employed and
compared to the threshold value.
Previously the coordinate system functionality was split between
coordinateSystem and coordinateRotation. The coordinateRotation stored
the rotation tensor and handled all tensor transformations.
The functionality has now been revised and consolidated into the
coordinateSystem classes. The sole purpose of coordinateRotation
is now just to provide a selectable mechanism of how to define the
rotation tensor (eg, axis-angle, euler angles, local axes) for user
input, but after providing the appropriate rotation tensor it has
no further influence on the transformations.
--
The coordinateSystem class now contains an origin and a base rotation
tensor directly and various transformation methods.
- The origin represents the "shift" for a local coordinate system.
- The base rotation tensor represents the "tilt" or orientation
of the local coordinate system in general (eg, for mapping
positions), but may require position-dependent tensors when
transforming vectors and tensors.
For some coordinate systems (currently the cylindrical coordinate system),
the rotation tensor required for rotating a vector or tensor is
position-dependent.
The new coordinateSystem and its derivates (cartesian, cylindrical,
indirect) now provide a uniform() method to define if the rotation
tensor is position dependent/independent.
The coordinateSystem transform and invTransform methods are now
available in two-parameter forms for obtaining position-dependent
rotation tensors. Eg,
... = cs.transform(globalPt, someVector);
In some cases it can be useful to use query uniform() to avoid
storage of redundant values.
if (cs.uniform())
{
vector xx = cs.transform(someVector);
}
else
{
List<vector> xx = cs.transform(manyPoints, someVector);
}
Support transform/invTransform for common data types:
(scalar, vector, sphericalTensor, symmTensor, tensor).
====================
Breaking Changes
====================
- These changes to coordinate systems and rotations may represent
a breaking change for existing user coding.
- Relocating the rotation tensor into coordinateSystem itself means
that the coordinate system 'R()' method now returns the rotation
directly instead of the coordinateRotation. The method name 'R()'
was chosen for consistency with other low-level entities (eg,
quaternion).
The following changes will be needed in coding:
Old: tensor rot = cs.R().R();
New: tensor rot = cs.R();
Old: cs.R().transform(...);
New: cs.transform(...);
Accessing the runTime selectable coordinateRotation
has moved to the rotation() method:
Old: Info<< "Rotation input: " << cs.R() << nl;
New: Info<< "Rotation input: " << cs.rotation() << nl;
- Naming consistency changes may also cause code to break.
Old: transformVector()
New: transformPrincipal()
The old method name transformTensor() now simply becomes transform().
====================
New methods
====================
For operations requiring caching of the coordinate rotations, the
'R()' method can be used with multiple input points:
tensorField rots(cs.R(somePoints));
and later
Foam::transformList(rots, someVectors);
The rotation() method can also be used to change the rotation tensor
via a new coordinateRotation definition (issue #879).
The new methods transformPoint/invTransformPoint provide
transformations with an origin offset using Cartesian for both local
and global points. These can be used to determine the local position
based on the origin/rotation without interpreting it as a r-theta-z
value, for example.
================
Input format
================
- Streamline dictionary input requirements
* The default type is cartesian.
* The default rotation type is the commonly used axes rotation
specification (with e1/e2/3), which is assumed if the 'rotation'
sub-dictionary does not exist.
Example,
Compact specification:
coordinateSystem
{
origin (0 0 0);
e2 (0 1 0);
e3 (0.5 0 0.866025);
}
Full specification (also accepts the longer 'coordinateRotation'
sub-dictionary name):
coordinateSystem
{
type cartesian;
origin (0 0 0);
rotation
{
type axes;
e2 (0 1 0);
e3 (0.5 0 0.866025);
}
}
This simplifies the input for many cases.
- Additional rotation specification 'none' (an identity rotation):
coordinateSystem
{
origin (0 0 0);
rotation { type none; }
}
- Additional rotation specification 'axisAngle', which is similar
to the -rotate-angle option for transforming points (issue #660).
For some cases this can be more intuitive.
For example,
rotation
{
type axisAngle;
axis (0 1 0);
angle 30;
}
vs.
rotation
{
type axes;
e2 (0 1 0);
e3 (0.5 0 0.866025);
}
- shorter names (or older longer names) for the coordinate rotation
specification.
euler EulerRotation
starcd STARCDRotation
axes axesRotation
================
Coding Style
================
- use Foam::coordSystem namespace for categories of coordinate systems
(cartesian, cylindrical, indirect). This reduces potential name
clashes and makes a clearer declaration. Eg,
coordSystem::cartesian csys_;
The older names (eg, cartesianCS, etc) remain available via typedefs.
- added coordinateRotations namespace for better organization and
reduce potential name clashes.
- 'signed' input parameter only mandatory for distance > 0.
A distance <= 0 is always signed and the input parameter is ignored.
- Use normal distance when distance == 0. This has no effect when
the surface has no open edges, but improves on rounding issues
around the zero crossing when the surface has open edges.
This may still need future revisiting.
- the original intention was to avoid vtp output when the clouds are
empty anyhow. However, it is useful for post-processing to have
clouds with zero parcels (eg, before the start of injection).
Pruning of empty clouds is now an option in the vtkCloud dictionary
controls, with the default being false (no pruning). This represents
a non-breaking change in behaviour since it generates more output
than previously.
Example,
{
type vtkCloud;
//- Suppress writing of empty clouds (default: false)
prune true;
}
- functionObjectLibs -> libs
- redirectType -> name
- change deprecated writeCompression flags types to Switch.
- cleanup some trailing ';;' from some dictionaries
- for larger problems with a smaller region of interest, can apply a
bounding to limit the size of the ensight geometry and fields created.
Since the implementation uses a fvMeshSubset, there is an additional
per-process memory overhead.
A high output frequency should be avoided with moving meshes, since
this indirectly forces a frequent update of the submesh.
- takes a direct approach of determining which cells are cut and walks
the cell faces directly to build the resulting surface.
- better handling of corner cases.
* Avoids redundant points when the cut passes exactly through a
mesh point.
* Supresses generation of duplicates faces when the plane cut
coincides exactly with a mesh face.
- for severely concave cells where the plane cuts a face multiple times
there is currently no remedial action taken, except to note the
failure and unwind the insertion of the corresponding points and
faces.
- signedDistance() method is like distance() but retains
the positive/negative sign for the side of the plane.
- the sign() method returns the sign as -1,0,+1 integer for
classification purposes where it is important to distinguish between
a zero value and a positive value (eg, for cutting). Optional
tolerance can be supplied to round for zero.
- refactor and inlined simple and frequently used methods.
- add boundBox faceCentre() method, which can be useful for creating
clipping planes from a bounding box.
Relocated treeBoundBox faceNormals to boundBox since they apply
equally there - the meaning of the faces (x-min, x-max, etc)
is the same, even if the point addressing for the faces differs.
- some paraview versions (eg, on windows) don't support float, only double.
This mostly affected the vtkSurfaceWriter.
The foamToVTK is also affected, but since it also supports the XML
output formats (vtp, vtu) these can be used instead.
- improve doxygen entries for searchable surfaces.
- support selection of searchable surfaces with shorter names.
Eg,
type box | cylinder | ...;
vs type searchableBox | searchableCylinder | ...;
- relocate some standard functionality to TimePaths to allow a lighter
means of managing time directories without using the entire Time
mechanism.
- optional enableLibs for Time construction (default is on)
and a corresponding argList::noLibs() and "-no-libs" option
STYLE:
- mark Time::outputTime() as deprecated MAY-2016
- use pre-increment for runTime, although there is no difference in
behaviour or performance.
Correcting thermoSingleLayer.C mask field alpha to avoid heat sources where there is no film.
Tunning fvSolution for alpha for twoPhasePachuka tutorial
- list all regions from constant/regionProperties:
* foamListRegions
- list specific region type from constant/regionProperties:
* foamListRegions fluid
* foamListRegions solid
Within decomposeParDict, it is now possible to specify a different
decomposition method, methods coefficients or number of subdomains
for each region individually.
The top-level numberOfSubdomains remains mandatory, since this
specifies the number of domains for the entire simulation.
The individual regions may use the same number or fewer domains.
Any optional method coefficients can be specified in a general
"coeffs" entry or a method-specific one, eg "metisCoeffs".
For multiLevel, only the method-specific "multiLevelCoeffs" dictionary
is used, and is also mandatory.
----
ENH: shortcut specification for multiLevel.
In addition to the longer dictionary form, it is also possible to
use a shorter notation for multiLevel decomposition when the same
decomposition method applies to each level.
- the dictionary-driven variant of stitchMesh allows sequential
application of 'stitch' operation with requiring intermediate
writing to disk.
- Without arguments:
* stitchMesh uses a system/stitchMeshDict or -dict dict
- With arguments:
* master/slave patches specified on the command-line as in previous
versions.