- New solver linkage requirements
- Deprecation and Removal
- Changes in behaviour
- Changes in locations
- Container changes
- String handling / predicates
- Sorted Iteration
- Field handling
- Convenience Functions
- MPI / Pstream changes
New solver linkage requirements
As a side-effect of restructuring improvements for (multiphase and
thermal-coupled) solvers, a new thermoTools
library has been
introduced. This library currently embodies various derived boundary
conditions, but is expected to be extended in the future.
To ensure that the boundary conditions are available in your own
solvers, the thermoTools
library should be included wherever the
compressibleTurbulenceModels
library is currently linked (in the
respective Make/options file). In most cases it will be sufficent to
simply adjust the EXE_LIBS
entry without needing to adjust the
EXE_INC
entry.
For example,
- old Make/options
EXE_LIBS = ... \ ... -lcompressibleTurbulenceModels \ -lcompressibleTransportModels \ ...
- new Make/options
EXE_LIBS = ... \ ... -lcompressibleTurbulenceModels \ -lthermoTools \ -lcompressibleTransportModels \ ...
- in special cases with compilation for old/new OpenFOAM versions,
the library linkage can be isolated as follows:
#if (OPENFOAM >= 2206) LIB_THERMO_TOOLS := -lthermoTools #else LIB_THERMO_TOOLS := #endif EXE_LIBS = ... \ ... -lcompressibleTurbulenceModels \ $(LIB_THERMO_TOOLS) \ -lcompressibleTransportModels \ ...
Deprecation and Removal
Deprecated Methods
- The OS system methods
domainName
and the fully-qualified version ofhostName
are now deprecated. These functions are unused within in the OpenFOAM code-base and have the following deficiencies:- the POSIX versions use the deprecated
gethostbyname()
function - the Windows versions never worked at all
- the POSIX versions use the deprecated
Removed Methods
-
Removed the unused
IOobject::isHeaderClassName(const word&)
method. It is preferable/recommended to use the template typed versions instead since they provide better compile-time diagnostics. String-based checking is still possible if desired:(io.headerClassName() == "foo") //<- OLD: io.isHeaderClassName("foo")
In some cases, the new
IOobject::hasHeaderClass()
method, which is equivalent to(!headerClassName().empty())
can provide a useful test for checking if reading was successful. -
The
IOobject::isHeaderClass()
method has been shortened fromIOobject::isHeaderClassName()
-
Removed the deprecated
fvMeshSubset::setLargeCellSubset()
method. This was compile-time deprecated since JUL-2018, now removed.
Renamed Methods
-
The
lessEqOp
andgreaterEqOp
op names have been changed to remove ambiguitity in meaning, since there are other forms (eg,plusEqOp
) where theEq
implies an assigment (eg,+=
) and not the comparison type.old op name new op name meaning lessEqOp lessEqualOp <=
greaterEqOp greaterEqualOp >=
The name change better reflects the purpose and also aligns more with C++ <functional> names such as
std::less_equal
andstd::greater_equal
.
Changes in behaviour
-
As part of a minor de-clutter of
List
,DynamicList
,DynamicField
etc constructing fromSortableList
and move assignment fromSortableList
has been removed. Both were never used and can simply handled by applyingshrink()
beforehand and treating like a normal list if needed. In generalSortList
provides a lighter sorting container for many cases. -
Any list
append()
methods that previously return a reference to self are nowvoid
, which makes it much easier and more consistent when deriving sub-classes. Having them return self was an unnecessary feature (design mistake) since chaining appends do not actually occur anywhere and wouldn't be relied upon for fear of incidentally slicing on any derived classes.
Changes in locations
Coordinate systems
The classes defining coordinate systems and coordinate rotations have migrated from src/meshTools to src/OpenFOAM. This permits their use in surfMesh core classes. This relocation will not affect any linkage requirements.
Foam::sort, Foam::sortedOrder
To simplify inter-dependencies and use, the declaration for the
commonly used Foam::sortedOrder
has migrated from ListOps.H
to
List.H
. Similarly, the pointer-list version of Foam::sort
has
migrated from PtrListOps.H
to UPtrList.H
.
The PtrListOps::less
and PtrListOps::greater
wrappers are now
found as UPtrList::less
and UPtrList::greater
, respectively, which
aligns them with the UList::less
and UList::greater
pendants.
fvMeshSubset (+ fvMeshSubsetter)
The fvMeshSubset
class has been refactored into core functionality
(the fvMeshSubset
class) and extended functionality (the new
fvMeshSubsetter
class).
-
The core mapping (interpolate) functionality with direct handling of subsetting in
fvMeshSubset
, which does not use dynamicMesh topology changes. ThefvMeshSubset
is now located under src/finiteVolume instead of src/dynamicMesh. -
A specialised two-step subsetting is now relegated to the
fvMeshSubsetter
class, which does use dynamicMesh topology changes. This class is located under src/dynamicMesh.
This split of definitions is not expected to require any changes for
user compilation since the core (fvMeshSubset
) will already found in
src/finiteVolume and the new specialised two-step subsetting is very
rarely used (currently only used by the subsetMesh application
itself).
The fvMeshSubset
now has an additional optimised construct/reset for
zero-sized (dummy) sub-meshes, which inherently have no exposed faces
and no parallel synchronization.
Container changes
CircularBuffer
The new CircularBuffer
container handles a simple list of objects
that as a circular buffer (a FIFO, a LIFO or anything in between)
without the alloc/free overhead associated with a linked-list
approach.
CompactListList
The CompactListList
has been revised to require a single template
parameter only. The old secondary Container
template parameter has
been eliminated. For creation, the pack()
factory methods should be
used. The unpack()
method replaces and improves the old operator()
access. The familiar-looking values()
, data()
and cdata()
methods allow read-access to the compact internal list data.
IndirectList
The IndirectList
class has been extended to include some factory
methods:
-
uniq()
creates an IndirectList with duplicated entries filtered out -
subset()
creates an IndirectList with positions that satisfy a condition predicate. -
subset_if()
creates an IndirectList with values that satisfy a given predicate.
Note that an indirect subset will be cheaper than creating a subset copy of the original data, and also allows modification.
String handling / predicates
-
The
wordRe
has been made slightly leaner. The regex is now encapsulated by a pointer, which reduces size and overhead when it represents a literal string. -
Consolidated
wordRes
allow/deny filtering, also wrapped as awordRes::filter
functor. This enables direct support ofwordRes::filter
in stringListOps and allow/deny when loading cloud fields to a registry. -
Added an
identityOp
, which is similar tonoOp
was defined, but with perfect forwarding. Its behaviour is largely equivalent to the C++20std::identity
definition. -
Added simple
labelRange
predicatesgt0
,ge0
,lt0
,le0
that mirrorscalarRange
tests. These have a lower overhead than usinglabelMinMax::ge(0)
etc since it does not create an intermediate (is stateless) and can be used as a constexpr.
Sorted Iteration
-
The
HashTable
,HashSet
,Map
, IOobjectListand
objectRegistryclasses have been extended to include a
sorted()` method.The
sorted()
andcsorted()
methods provides a leaner and more convenient means of traversing hashed content in a consistent order, without the extra step of creating asortedToc()
. Thesorted()
method works by sorting a list of pointers to the respective entries and will always have a lower overhead than a table-of-contents approach (which uses full copies of the keys). It will also avoid secondary checks when accessing the entry values.- Can now write this:
HashTable<someType> table = ...; for (const auto& iter : table.sorted()) { Info<< iter.key() << " => " << iter.val() << nl; }
- instead of previously:
HashTable<someType> table = ...; for (const word& key : table.sortedToc()) //<- Additional overhead for full copy of keys! { // Note: incurs a secondary lookup! Info<< key << " => " << table[key] << nl; }
- Can now write this:
NB: The HashTable iteration key()
entry is now declared as
const
since it is immutable.
Field handling
Vector methods
-
The
vector::normalise
method now supports optional tolerance, for cases where tolerances other than ROOTVSMALL are preferable. -
The new
vector::removeCollinear
method is useful when working with geometries where it is frequently necessary to have a normal vector without any collinear components. TheremoveCollinear
method provides for clearer, compacter code:vector edgeNorm = ...; const vector edgeDirn = e.unitVec(points()); edgeNorm.removeCollinear(edgeDirn); edgeNorm.normalise();
instead of
vector edgeNorm = ...; const vector edgeDirn = e.unitVec(points()); edgeNorm -= edgeDirn*(edgeDirn & edgeNorm); edgeNorm /= mag(edgeNorm) + ROOTVSMALL;
Field normalise
-
The
Field
container (and associated classes such asGeometricField
) now has anormalise()
method. For most field types this is simply a no-op, but for fields ofvector
andsolveVector
this corresponds tovector::normalise
, but applied to each element.It will normalise each element with divide-by-zero protection, without the overhead of creating an intermediate field (or extra code lines).
fld.normalise();
instead of
fld /= mag(fld) + VSMALL;
Wrapped IO output classes
Some derived regIOobject wrappers have been added for writing data by
reference without copying. These wrapper classes use a refPtr
to
reference external content. Reading into external locations is not
implemented (no current requirement for that).
base class | wrapped class |
---|---|
IOField | IOFieldRef |
IOList | IOListRef |
IOmapDistributePolyMesh | IOmapDistributePolyMeshRef |
Example use:
labelList addressing = ...;
io.rename("cellProcAddressing");
IOListRef<label>(io, addressing).write();
or,
primitivePatch patch = ...;
IOFieldRef<vector>(io, patch.localPoints()).write();
Convenience Functions
-
added a polyMesh filtering
regionName()
- static and non-static methods.- when dealing with mesh regions it is common to filter out or
remove the defaultRegion name (ie, "region0").
Can now do that conveniently from the polyMesh itself or as a static
function. Simply use this
const word& regionDir = polyMesh::regionName(regionName); // or const word& regionDir = mesh.regionName();
const word& regionDir = ( regionName != polyMesh::defaultRegion ? regionName : word::null );
(polyMesh::regionName(regionName)/polyMesh::meshSubDir) (mesh.regionName()/polyMesh::meshSubDir)
- when dealing with mesh regions it is common to filter out or
remove the defaultRegion name (ie, "region0").
Can now do that conveniently from the polyMesh itself or as a static
function. Simply use this