- for workflows with appearing/disappearing patches (for example)
can specify that empty surfaces should be ignored or warned about
instead of raising a FatalError.
Note that this handling is additional to the regular top-level
"errors" specification. So specifying 'strict' will only actually
result in a FatalError if the "errors" does not trap errors.
- "ignore" : any empty surfaces are simply ignored and no
file output (besides the header).
- "warn" : empty surfaces are warned about a few times (10)
and the file output contains a NaN entry
- "strict" : corresponds to the default behaviour.
Throws a FatalError if the surface is empty.
This error may still be caught by the top-level "errors" handling.
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
- 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
- replaced ad hoc handling of formatOptions with coordSetWriter and
surfaceWriter helpers.
Accompanying this change, it is now possible to specify "default"
settings to be inherited, format-specific settings and have a
similar layering with surface-specific overrides.
- snappyHexMesh now conforms to setFormats
Eg,
formatOptions
{
default
{
verbose true;
format binary;
}
vtk
{
precision 10;
}
}
surfaces
{
surf1
{
...
formatOptions
{
ensight
{
scale 1000;
}
}
}
}
- support globalIndex for points/faces as an output parameter,
which allows reuse in subsequent field merge operations.
- make pointMergeMap an optional parameter. This information is not
always required. Eg, if only using gatherAndMerge to combine faces
but without any point fields.
ENH: make globalIndex() noexcept, add globalIndex::clear() method
- previously had 'mandatory' (bool) for advanced control of reading
dictionary entries but its meaning was unclear in the calling code
without extra code comments.
Now use IOobjectOption::readOption instead, which allows further
options (ie, NO_READ) and is more transparent as to its purpose in
the code than a true/false bool flag was.
This is a minor breaking change (infrequent, advanced usage only)
- minor code cleanup in dictionary lookup methods
- noexcept on some Time methods
ENH: pass through is_oriented() method for clearer coding
- use logical and/or/xor instead of bitwise versions (clearer intent)
- Previously, the multiFieldValue function object was limited to operate on
lists of fieldValue function objects.
- Any function objects that generate results can now be used, e.g.
pressureAverage
{
type multiFieldValue;
libs (fieldFunctionObjects);
operation average;
functions
{
inlet
{
type surfaceFieldValue;
operation areaAverage;
regionType patch;
name inlet;
fields (p);
writeFields no;
writeToFile no;
log no;
resultFields (areaAverage(inlet,p));
}
outlet
{
type surfaceFieldValue;
operation areaAverage;
regionType patch;
name outlet;
fields (p);
writeFields no;
writeToFile no;
log no;
}
average
{
type valueAverage;
functionObject testSample1;
fields (average(p));
writeToFile no;
log no;
}
}
}
TUT: cavity: add an example for the multiFieldValue function object
- bundles frequently used 'gather/scatter' patterns more consistently.
- combineAllGather -> combineGather + broadcast
- listCombineAllGather -> listCombineGather + broadcast
- mapCombineAllGather -> mapCombineGather + broadcast
- allGatherList -> gatherList + scatterList
- reduce -> gather + broadcast (ie, allreduce)
- The allGatherList currently wraps gatherList/scatterList, but may be
replaced with a different algorithm in the future.
STYLE: PstreamCombineReduceOps.H is mostly unneeded now
- when writing surface formats (eg, vtk, ensight etc) the sampled
surfaces merge the faces/points originating from different
processors into a single surface (ie, patch gatherAndMerge).
Previous versions of mergePoints simply merged all points possible,
which proves to be rather slow for larger meshes. This has now been
modified to only consider boundary points, which reduces the number
of points to consider. As part of this change, the reference point
is now always equivalent to the min of the bounding box, which
reduces the number of search loops. The merged points retain their
original order.
- inplaceMergePoints version to simplify use and improve code
robustness and efficiency.
ENH: make PrimitivePatch::boundaryPoints() less costly
- if edge addressing does not already exist, it will now simply walk
the local face edges directly to define the boundary points.
This avoids a rather large overhead of the full faceFaces,
edgeFaces, faceEdges addressing.
This operation is now more important since it is used in the revised
patch gatherAndMerge.
ENH: topological merge for mesh-based surfaces in surfaceFieldValue
- lower memory overhead, simpler code and eliminates need for
ListListOps::combineOffset()
- optional handling of local faces/points for re-using in different
contexts
STYLE: labelUList instead of labelList for globalMesh mergePoints
STYLE: adjust verbose information from mergePoints
- also report the current new-point location
Computes a selected operation between multiple \c fieldValue function
objects.
The operation is applied to all results of each \c fieldValue object.
Note
Each object must generate the same number and type of results.
Usage
Minimal example by using \c system/controlDict.functions:
multiFieldValue1
{
// Mandatory entries (unmodifiable)
type multiFieldValue;
libs (fieldFunctionObjects);
// Mandatory entries (runtime modifiable)
operation subtract;
// List of fieldValue function objects as dictionaries
functions
{
region1
{
...
}
region2
{
...
}
...
regionN
{
...
}
}
// Optional (inherited) entries
...
}
where the entries mean:
Property | Description | Type | Req'd | Dflt
type | Type name: multiFieldValue | word | yes | -
libs | Library name: fieldFunctionObjects | word | yes | -
operation | Operation type to apply to values | word | yes | -
functions | List of fieldValue function objects | dict | yes | -
\endtable
Options for the \c operation entry:
add | add
subtract | subtract
min | minimum
max | maximum
average | average
Deprecated fieldValueDelta
- The fieldValueDelta function object was originally written to compute the
difference between two fieldValue-type function objects. The multiFieldValue
object name better describes its purpose whilst being able to operate on an
arbitrary number of fieldValue-type objects.
- ensure surface writing is time-step and nFields aware.
This avoids overwriting (ignoring) previous output fields.
- allow sampled surfaces to be used for weight fields as well.
Not sure why this restriction was still there.
- remove old compatibility reading of orientedFields.
Last used in v1612, now removed.
- only use face sampling. For surfaceFieldValue we can only do
something meaningful with face values.
ENH: modify interface methods for surfaceWriter
- replace direct modification of values with setter methods.
Eg,
old: writer.isPointData() = true;
new: writer.isPointData(true);
This makes it possible to add internal hooks to catch state changes.
ENH: allow post-construction change to sampledSurface interpolation
- rename interpolate() method to isPointData() for consistency with
other classes and to indicate that it is a query.
- additional isPointData(bool) setter method to change the expected
representation type after construction
- remove 'interpolate' restriction on isoSurfacePoint which was
previously flagged as an error but within sampledSurfaces can use
sampleScheme cellPoint and obtain representative samples.
Relax this restriction since this particular iso-surface algorithm
is slated for removal in the foreseeable future.
- setup writer outside the data loop to ensure that the number of
output fields is correct (VTK format).
- ignore 'interpolate' on sampled surfaces to ensure proper
face sampling, never allow point sampling
BUG: incorrect debug-switch for sampledIsoSurface
If the 'writeFields' option is set in surfaceFieldValue, e.g.
surface1
{
type surfaceFieldValue;
libs (fieldFunctionObjects);
operation none;
fields (p);
regionType patch;
name walls;
// Create a surface in VTK format
writeFields yes;
surfaceFormat vtk;
}
... the surface can now be used in runTimePostProcessing, e.g.:
surfaces
{
surfaceFieldValueOutput
{
type functionObjectSurface;
representation surface;
liveObject no;
field p;
colourBy field;
range (0 120000);
functionObject surface1;
}
}
Note: setting 'liveObject' to 'no' to suppress warnings due to the surface
not being retrieved from the object registry (default = 'yes') - this surface
can [currently] only be read from disk.
- weight fields are combined by multiplication
- volFieldValue:
* 0-N scalar fields
- surfaceFieldValue:
* 0-N scalar fields
* 0-1 vector fields
In some cases this can be used to avoid creating additional
fields.
weightFields (rho U);
vs.
derivedFields (rhoU);
weightField rhoU;
- additional "names" entry to specify a word/regex list of selections
For example,
{
type patch;
name inlets;
names ("inlet_[0-9].*" inlet);
}
- if "names" exists AND contains a literal (non-regex) that can be used
as a suitable value for "name", the "name" entry becomes optional.
For example,
{
type patch;
names ("inlet_[0-9].*" inlet);
// inferred name = inlet
}
- reduce some overhead in surfaceFieldValue
TUT: surfaceFieldValue on patches : reactingParcelFoam/verticalChannel
- make handling of verbosity more consistent.
Make all setter return the old value, remove (unused) default
parameter as being counter-intuitive. This makes it easier to
restore the original values.
For example,
const bool oldVerbose = sampler.verbose(false);
...
sampler.verbose(oldVerbose);
- originally (incorrectly) was a Field(0.0), which was generalized
to Field(Zero), but Field() is the correct form
STYLE: rename 'mustGet' to more standard 'mandatory' variable
- with '&&' conditions, often better to check for non-null autoPtr
first (it is cheap)
- check as bool instead of valid() method for cleaner code, especially
when the wrapped item itself has a valid/empty or good.
Also when handling multiple checks.
Now
if (ptr && ptr->valid())
if (ptr1 || ptr2)
instead
if (ptr.valid() && ptr->valid())
if (ptr1.valid() || ptr2.valid())
ENH: update libs of etc/caseDicts/postProcess items
ENH: ensure destructor=default
ENH: ensure constness
ENH: ensure no 'copy construct' and 'no copy assignment' exist
TUT: add examples of function objects with full set
of settings into a TUT if unavailable
TUT: update pisoFoam/RAS/cavity tutorial in terms of usage
- previously introduced `getOrDefault` as a dictionary _get_ method,
now complete the transition and use it everywhere instead of
`lookupOrDefault`. This avoids mixed usage of the two methods that
are identical in behaviour, makes for shorter names, and promotes
the distinction between "lookup" access (ie, return a token stream,
locate and return an entry) and "get" access (ie, the above with
conversion to concrete types such as scalar, label etc).