- functionality introduced by openfoam.org to support selective
caching of temporary fields. The purpose is two-fold: to enable
diagnostics and to allow more places to use unregistered fields by
default.
For example to cache the grad(k) field in
cacheTemporaryObjects
(
grad(k)
);
If the name of a field which in never constructed is added to the
cacheTemporaryObjects list a waning message is generated which
includes a useful list of ALL the temporary fields constructed
during the time step
Multiple regions are also supported by specifying individual region
names in a cacheTemporaryObjects dictionary.
cacheTemporaryObjects
{
porous
(
porosityBlockage:UNbr
);
}
functions
{
writePorousObjects
{
type writeObjects;
libs (utilityFunctionObjects);
region porous;
writeControl writeTime;
writeOption anyWrite;
objects (porosityBlockage:UNbr);
}
}
- allow reporting even when profiling is suspended
- consolidate reporting into profilingPstream itself
(avoids code scatter).
Example of possible advanced use for timing only one section of
code:
====
// Profile local operations
profilingPstream::enable();
... do something
// Don't profile elsewhere
profilingPstream::suspend();
====
- separate broadcast times from reduce/gather/scatter time
- separate wait times from all-to-all time
- support invocation counts, split off requests time/count
from others to avoid flooding the counts
- support 'detail' switch to increase the output information.
Format may change in the future
- attributes such as assignable(), coupled() etc
- common patchField types: calculatedType(), zeroGradientType() etc.
This simplifies reference to these types without actually needing a
typed patchField version.
ENH: add some basic patchField types to fieldTypes namespace
- allows more general use of the names
ENH: set extrapolated/calculated from patchInternalField directly
- avoids intermediate tmp
- similar to UPstream::parRun(), the setter returns the previous value.
The accessors are prefixed with 'comm':
Eg, commGlobal(), commWarn(), commWorld(), commSelf().
This distinguishes them from any existing variables (eg, worldComm)
and arguably more similar to MPI_COMM_WORLD etc...
If demand-driven communicators are added in the future, the function
call syntax can help encapsulate that.
Previously:
const label oldWarnComm = UPstream::warnComm;
const label oldWorldComm = UPstream::worldComm;
UPstream::warnComm = myComm;
UPstream::worldComm = myComm;
...
UPstream::warnComm = oldWarnComm;
UPstream::worldComm = oldWorldComm;
Now:
const label oldWarnComm = UPstream::commWarn(myComm);
const label oldWorldComm = UPstream::commWorld(myComm);
...
UPstream::commWarn(oldWarnComm);
UPstream::commWorld(oldWorldComm);
STYLE: check (warnComm >= 0) instead of (warnComm != -1)
ENH: add pTraits and IO for std::int8_t
STYLE: cull some implicitly available includes
- pTraits.H is included by label/scalar etc
- zero.H is included by UList
STYLE: cull redundant forward declarations for Istream/Ostream
- newer naming allows for less confusing code.
Eg,
max(lower) -> clamp_min(lower)
min(upper) -> clamp_max(upper)
- prefer combined method, for few operations.
Eg,
max(lower) + min(upper) -> clamp_range(lower, upper)
The updated naming also helps avoid some obvious coding errors.
Eg,
Re.min(1200.0);
Re.max(18800.0);
instead of
Re.clamp_range(1200.0, 18800.0);
- can also use implicit conversion of zero_one to MinMax<Type> for
this type of code:
lambda_.clamp_range(zero_one{});
- attempted reduction in bookkeeping (commit: 068ab8ccc7) meant that
the worldComm didn't have a group from which sub-communicators could
be spun off.
- do not force reset of PstreamBuffers positions
STYLE: UPstream::globalComm instead of '0'
- field blocking/exclusion added in commit d9ab5d54ef,
but was incorrectly doing a lookup for "blockField" for ensight
although "excludeFields" was documented (and expected).
Now corrected to use "excludeFields"
- reduces clutter. In some cases the Fwd typedefs were also incorrect
STYLE: combine Scalar specialisations into corresponding PatchFields.C
- reduces clutter, simplifies future adjustments
- similar to surface writing formats, also support optional
dictionary of reading options. The main beneficiary of this is the
ensight surface reader:
readOptions
{
ensight
{
masterOnly true;
}
}
This will restrict reading to the master rank. Surfaces and values
read will be broadcast to the other ranks, with the intention of
reducing load on the filesystem.
ENH: add writing of Dimensioned fields for areaWrite functionObject
- can be useful for examining finite-area source terms
Changes / Improvements
- more consistent subsetting, interface
* Extend the use of subset and non-subset collections with uniform
internal getters to ensure that the subset/non-subset versions
are robustly handled.
* operator[](label) and objectIndex(label) for standardized access
to the underlying item, or the original index, regardless of
subsetting or not.
* centres() and centre(label) for representative point cloud
information.
* nDim() returns the object dimensionality (0: point, 1: line, etc)
these can be used to determine how 'fat' each shape may be
and whether bounds(labelList) may contribute any useful information.
* bounds(labelList) to return the full bound box required for
specific items. Eg, the overall bounds for various 3D cells.
- easier construction of non-caching versions. The bounding boxes are
rarely cached, so simpler constructors without the caching bool
are provided.
- expose findNearest (bound sphere) method to allow general use
since this does not actually need a tree.
- static helpers
The boxes() static methods can be used by callers that need to build
their own treeBoundBoxList of common shapes (edge, face, cell)
that are also available as treeData types.
The bounds() static methods can be used by callers to determine the
overall bound-box size prior to constructing an indexedOctree
without writing ad hoc code inplace.
Not implemented for treeDataPrimitivePatch since similiar
functionality is available directly from the PrimitivePatch::box()
method with less typing.
========
BREAKING: cellLabels(), faceLabels(), edgeLabel() access methods
- it was always unsafe to use the treeData xxxLabels() methods without
subsetting elements. However, since the various classes
(treeDataCell, treeDataEdge, etc) automatically provided
an identity lookup, this problem was not apparent.
Use objectIndex(label) to safely de-reference to the original index
and operator[](index) to de-reference to the original object.
- use default initialize boundBox instead of invertedBox
- reset() instead of assigning from invertedBox
- extend (three parameter version) and grow method
- inflate(Random) instead of extend + re-assigning
- the boundBox for a given cell, using the cheapest calculation:
- cellPoints if already available, since this will involve the
fewest number of min/max comparisions.
- otherwise walk the cell faces: via the cell box() method
to avoid creating demand-driven cellPoints etc.
ENH: use direct access to pointHit as point(), use dist(), distSqr()
- if the pointHit has already been checked for hit(), can/should
simply use point() noexcept access subsequently to avoid redundant
checks. Using vector distSqr() methods provides a minor optimization
(no itermediate temporary), but can also make for clearer code.
ENH: copy construct pointIndexHit with different index
- symmetric with constructing from a pointHit with an index
STYLE: prefer pointHit point() instead of rawPoint()
Grid independency studies and grid adaptation for implicit LES/DES are
nontrivial and intractable due to the inherent coupling between spatial
resolution and subgrid-scale modelling.
To enable assessments for LES/DES resolution, a function object of
single-mesh resolution index with three submodels is introduced.
- pattern as per surfaceFieldValue::setFaceZoneFaces()
1. define faceId, facePatchId assuming an internal face
2. if actually a boundary face:
- get facePatchId
- ignore if emptyPolyPatch or coupledPolyPatch (neighbour side)
- get patch relative faceId
This currently seems to be the least amount of code clutter.
ENH: recover some memory my shrinking lists in fluxSummary
BUG: potentially trailing rubbish in the heatExchangerModel lists
- the final resize to length actually used was missing.
Does not affect any released versions
- functionality similar to that provided by foamToEnsight, foamToVTK
which allows blocking out patches (eg, outer walls, inlet/outlet)
that are not particularly interesting to visualize
- since ensight format is always float and also always written
component-wise, perform the double -> float narrowing when
extracting the components. This reduces the amount of data
transferred between processors.
ENH: avoid vtk/ensight parallel communication of empty messages
- since ensight writes by element type (eg, tet, hex, polyhedral) the
individual written field sections will tend to be relatively sparse.
Skip zero-size messages, which should help reduce some of the
synchronization bottlenecks.
ENH: use 'data chunking' when writing ensight files in parallel
- since ensight fields are written on a per-element basis, the
corresponding segment can become rather sparsely distributed. With
'data chunking', we attempt to get as many send/recv messages in
before flushing the buffer for writing. This should make the
sequential send/recv less affected by the IO time.
ENH: allow use of an external buffer when writing ensight components
STYLE: remove last vestiges of autoPtr<ensightFile> for output routines
- consistent with sumOp
ENH: globalIndex with gatherNonLocal tag, and use leading dispatch tags
- useful for gather/write where the master data can be written
separately. Leading vs trailing dispatch tags for more similarity to
other C++ conventions.
- new submodels:
- 'equalBinWidth': groups data into bins of equal widths (previous behaviour)
- 'unequalBinWidth': groups data into bins of unequal widths
- output files per time-step are replaced with a single output file
- silently deprecates the input entries: 'setFormat' and 'formatOptions'