- makes fileHandler calling resemble Time more closely
ENH: provide natural_sort less/greater functions
- more succinct than (compare < 0) or (compare > 0).
The corresponding wrappers for UList renamed as list_less, etc
but they were only used in unit tests
ENH: handle (-allRegions | -all-regions, ..) directly when retrieving args
- makes handling independent of aliasing order
STYLE: include <string_view> when including <string>
- the standard does not guarantee which headers (if any) actually
include string_view
Ideally wish to delay construction of the finite-area mesh until
updateCoeffs(), when it is actually needed.
This helps avoid difficult to trace errors and avoids inadvertent
parallel communication during construction from a dictionary.
However, lazy evaluation fails at the later stage while attempting
to load the corresponding initial fields, since the timeIndex has
already advanced.
Use the newly introduced regionModels::allowFaModels() switch
to locally enable or disable lazy evaluation as needed.
This allows selective disabling (eg, in post-processing utilities)
where loading the volume field should not activate the associated
regionFaModel and loading a finite-area mesh too (which may not
exist or be defined at that point).
- less typing than before and avoids relying on bash-specific behaviour
(fixes#3448)
ENH: add -region support for cleanFaMesh and cleanPolyMesh
CONFIG: add bash completion help for -area-region
ENH: general improvements for regionProperties
- robustness and failsafe for foamListRegions, regionProperties
- additional global model switches for regionModels
- further hide implementation (cxx ending)
STYLE: better distinction between code/templates for fileFormats/conversion
- for ensight and vtk, a large part of the code is header only.
Make this easier to identify
- add provisional support for selecting MPI_Gatherv
when merging fields in the surface writers.
Uses the 'gatherv' keyword [experimental]
BUG: gatherv/scatterv wrappers used the incorrect data type
- incorrectly checked against UPstream_basic_dataType trait instead of
UPstream_dataType, which resulted in a count mismatch for
user-defined types (eg, vector, tensor,...).
This was not visibly active bug, since previous internal uses of
gatherv were restricted to primitive types.
COMP: make UPstream dataType traits size(...) constexpr
- allows static asserts and/or compile-time selection
of code based on size(1)
- for a non-default mesh region, corresponding files:
system/finite-area/faOptions.<name>
system/finite-area/<name>/faSchemes, etc
if the entries within the faOptions dictionary happen to contain an
"area" entry and it conflicts with what is expected, it will be
rejected when creating the list of options, which helps avoid
unexpected behaviour and simplifies overall handling.
- unlike fvMesh and polyMesh, the faMesh mesh region name is passed
separately into constructors and functions. Thus need the same for
faMeshTools and faMeshSubset.
- ensure that an empty area name is treated like
polyMesh::defaultRegion.
The faMeshRegistry or other registries cannot have an empty name!
- extend the getAllRegionOptions and getAllFaRegionOptions handling
to use the supplied string literals as fallback values.
If regionProperties is missing (or empty) and the -regions/-area-regions
option is supplied with literal names, these will be used directly
instead of being used to filter the regionProperties.
STYLE: support both -all-regions and -allRegions
- in some shell models, only the mechanical properties (rho,E,nu) are
meaningful or just the basic thermal properties
(rho,Cp,kappa,emissivity).
Add a distinction when reading the dictionary entries
if those properties are mandatory and the thermo properties
(eg, molWt, Cp, etc) are optional or not.
This simplifies user input for thermal and vibration shell models.
- activeRequest() checks if given request is still active/pending
- finishedRequest() will now always call MPI_Test when running in
parallel instead of using a fast-path for skipping a null request.
This allows MPI a chance to progress operations even if that
particular request is not active.
- sameProcs() is a convenience wrapper for the following:
* check if indices resolve to the same underlying procs
* check the communicator procs against a list of procs
* to compare two lists of procs.
For example, check if the communicator corresponds to a
host-local communication:
if (UPstream::sameProcs(UPstream::commLocalNode(), myComm)) ...
STYLE: UPstream::Request gets an 'active()' method
- more MPI idiomatic than 'good'
- to avoid the many overload warnings on that platform,
may wish to use
FOAM_EXTRA_CXXFLAGS="-Wno-overloaded-virtual"
GIT: remove some old compilation stub files
- adjust the if/else-if/else-if cascade to have 'if constexpr (..)'
first and the *entire* alternate branch within the following 'else'.
This lets the compiler know that it can safely discarded the other
parts.
This change introduces a large amount of indentation change,
so use `--ignore-space-change` when inspecting.
COMP: reintroduce UList<T>() initialization in List [silence gcc]
COMP: use std::min() instead of direct check [silence gcc]
- gcc complains about possible strict-overflow for this:
```
if (count > len)
{
count = len; // The count truncated by the new length
}
```
Using `count = std::min(count, len);` avoids these (spurious)
warnings without adding a "diagnostic ignored" pragma
STYLE: pass std::pair<int,int> by copy [cheaper]
STYLE: make isdigit() and isspace() tests constexpr
- constexpr and C-locale only vs. the std counterparts
- extend time searching mechanisms to support searching in the case
global path: times(), findClosestTime(), findInstancePath()
- extend IOobject path() and objectPath() methods with
IOobjectOption::Layout variants
The changes are needed for addressing a global file structure
in parallel (#3431)
- add '<=' and '>=' operators that include rounding.
This means that typical code like the following would not have
considered any rounding:
instantList times = ...;
scalar val = ..;
// No rounding!
if (times[i].value() <= val) { ... }
// NEW: with rounding
if (times[i] <= val) { ... }
// old equivalent:
if (times[i].value() <= val || times[i].equal(val)) { ... }
ENH: provide a default stopInstance for fileOperation::findInstance
- makes it more consistent with Time::findInstance and more convenient
to use
STYLE: minor code style changes to TimePaths etc
- enables partial overwriting of content
- make default construct zero-sized, add reserve_exact() method
- improve sizing behaviour of OCharStream.
Since char buffers will approach the INT_MAX size more quickly than
other content, adapt the following strategy:
| Capacity range | Strategy |
|--------------------|------------------------------|
| 0 < N <= 0.25) | fast growth (2) |
| 0.25 < N <= 0.5) | slower growth (1.5) |
| 0.5 < N <= 0.75) | very slow growth (1.25) |
| 0.75 < N | already large - use max |
- improves usability of List as a general dynamic container as member
data without inheritance. Provide the same method for DynamicList
to enable more efficient use.
- additional string_view support for charList: useful when being used
as a character buffer
STYLE: improve allocation handling in List
- consolidate routines. Only assign size after allocation to ensure
that states are always consistent.
- make memory streams header-only (simpler)
- add sub-views and direct seek for span streams
New IOobject convenience methods
- IOobject::instanceValue() : return the IOobject instance as a scalar
value (or 0). Effectively the same as instant(io.instance()).value()
but with far less typing.
- IOobject::fileModificationChecking_masterOnly() : combines checks for
time-stamp and inotify variants
STYLE: minor adjustments for Enum
- can now create an empty entry and add/overwrite with tokens afterwards,
or copy/move construct from a list of tokens.
ENH: provided named token setter methods (disambiguates bool/char/label)
COMP: use 'if constexpr' for FlatOutput
DOC: more description for Field
- num_blocks(), test_set() as per boost
- broadcast(), reduceAnd(), reduceOr() to simplify parallel operations
- matrix-like output for PackedList::writeList()
BUG: Pstream::broadcastList() missing resize on sub-ranks
- latent bug since it was unused in any OpenFOAM code
- the snGradTransformDiag() is used in this type of code:
```
if constexpr (!is_rotational_vectorspace_v<Type>)
{
// Rotational-invariant type
return tmp<Field<Type>>::New(this->size(), pTraits<Type>::one);
}
else
{
return pTraits<Type>::one - snGradTransformDiag();
}
```
This implies that a rotational-invariant form should return 0
and not 1 like the pow(..., 0) does.
This is a backstop for any code that may inadvertently hit it,
but also allows the possibility of having integer indicator fields
without upsetting the compiler.
STYLE: doTransform() logic now uses is_rotational_vectorspace
- a special case of fixedValue with a value of zero:
* non-assignable
* no mapping needed
* value internal coeffs are zero
* value boundary coeffs are zero
- align some of the internal handling with each other and with
CompactListList
ENH: add readContentsSize to IOList, IOField etc.
- sometimes just need to know how many elements are stored on disk
without actually caring about the content. In those cases, can
frequently just get that information from the first label token
without needing to read anything else.
- the logic has been revised to allow list copying with nullptr entries.
These previously would have thrown an error.
- remove PtrList trimTrailingNull() method.
It was unused and would result in inconsistent addressing sizes.
FIX: inconsistent sizing used for DynamicList/PtrDynList clearStorage()
- older code did not reset addressable size prior to clearStorage()
or transfer(). Only a latent bug until memory pools are used.
- can be used in most places where checkType=false is used
ENH: add non-const get() method to HashPtrTable
- allows checking and modification (symmetric with PtrList methods)
STYLE: improve annotations in fileOperations headers
- previously handled stdin redirection as part of the run command but
(as Alexey Matveichev noted) this meant the command would actually
require an `eval` for this to work. Instead redirect before executing
the run command.
- can always use 'echo -e' (bash builtin) in mpirunDebug
CONFIG: add removal of mpirun.files/ to CleanFunctions
- leave mpirun.log/ files untouched, since they may still be useful
for later diagnosis
- provides some additional safety and precludes any recursive searching
ENH: support local directory handling in regionProperties
- allows alternative locations. Eg, for finite-area (#3419)
- since direct streaming of particles is only ever used internally and
never for disk I/O (which is collated by property), mixed precision
will never occur when constructing a particle from a stream.
Due to padding issues, the previous code would have been faulty anyhow.
Thus remove that code and replace with a simple sanity check.
- appears to hit single precision overflow with clang-15 in
face::center(), cellModel::center() and blockMesh createPoints().
The blockMesh might be particularly sensitive, since the points are
frequently defined in millimeters (scaled later), which results
in large intermediate summations.
Similar to primitiveMesh checks, use double precision for these
calculations.
ENH: support vector += and -= from compatible types
- eg, doubleVector += floatVector is now supported.
This streamlines some coding for mixed precision.
- To avoid lots of boilerplate, do not yet attempt to support general
operations such as `operator+(doubleVector, floatVector)`
until they become necessary.
- since pointConstraint is a tuple of (label, vector) not simply use
readRawLabel, readRawScalar since the tuple will also include
trailing padding and/or padding between its members
FIX: remove flawed handling of non-native precision for directionInfo
- packing of (label, vector) makes handling of non-native content
non-trivial (#3412). Content is only streamed, not written to disk,
so replace with a fatalCheck.
- local templates and 'if constexpr' to simplify logic and reduce
reliance on pre-processor defines.
FIX: readScalarOrDefault used scalarToken() not number() token
- will rarely (or never) be triggered, but was inconsistent
- as seen in #3201, using count() based on the ostringstream tellp
is not reliable since it is not updated with reset or copying.
STYLE: minor changes to string/char/span streams
- update docs to only mention string_view
- use auto return, without extra trailing 'decltype'
ENH: add IOstream size check helper methods
* checkNativeSizes() : test only
* fatalCheckNativeSizes() : an assert with FatalIOError
- find patch by name and return pointer to it. Similar to cfindZone()
ENH: robuster PatchFunction1 handling for uniformFixedValuePointPatchField
COMP: use 'if constexpr' with is_contiguous check
STYLE: consistent patch slicing parameters
- slice UList values, not List values
- base DimensionedField on DynamicField instead of Field to allow
convenient resizing
- initial infrastructure for unified GeometricField handling with
the boundaryEvaluate() method
Co-authored-by: <Mark.Olesen@keysight.com>
- regular or forced assignment from `zero` does not need dimension
checking:
Old: U = dimensionedVector(U.dimensions(), Zero);
New: U = Zero;
this eliminates a fair bit of clutter and simplifies new coding
without losing general dimension checking capabilities.
- reserve() did not set the addressable size to the current capacity
before resizing, which meant that the delete[] would not have the
true allocated size. Only affects memory-pool usage (#3381), which
is not yet integrated
ENH: remove unused DynamicList '*_unsafe()' methods
- can result in a mismatch between allocated and addressed sizes,
which becomes important for memory-pool usage.
Triggers function object to execute on the first time step.
Example usage:
minMax1
{
type fieldMinMax;
libs (fieldFunctionObjects);
writeControl onStart;
fields (".*");
}
Ref: EP2608
Correcting bug introduced when trying to keep the old communicator.
We do not need local communicator if all ranks of comm have
some faces. Not all ranks of the already local communicator.
- previous handling of forced inclusion of the master would taint the
logic about single vs multiple ranks.
- be fussier about avoing creation of a local communicator when not
needed.
STYLE: rename internal switch from localComm_ to useLocalComm_
- less confusing (it is a switch, not the communicator itself)
- setting the warnComm is useful for diagnosing multi-world issues but
triggers many false warnings when used in combination with AMI local
communicators.
COMP: unresolved pTraits<long int> for reductions on i586 systems
- now always just use int64_t instead of off_t and time_t
for master reductions.
Note that this is not the only place where the off_t definition
causes compilation issues (cf. fileOperation::broadcastCopy)
- in many cases the local communicator has the same communication
pattern for several timesteps so it can be reused instead of being
recreated. Avoids repeated MPI_Comm_free()/MPI_Comm_group() calls
- STYLE: eliminate bitSet intermediate when determining the sub-ranks
Calculates thrust, drag, torque and lift/drag/pressure coefficients
of single or multiple blades (eg, propeller, turbine blades)
This function object differs from the propellerInfo and forces
function objects in that all forces are calculated within the local
cylindrical coordinate system, which yields thrust and drag values
within the expected reference frame.
The output comprises:
- coefficients per radial bin
- area-weighted total coefficients
- integrated forces and torque
For convenient post-processing, the results are also written in a VTK
(.vtp) output format. All surface results are registered internally,
which makes them available for other function objects.
- originally only listed in functionObjectList, now also list the same
information under namespace functionObjects so it is more likely to
be found. Document the behaviour as a table to make it more
immediately visible than the text form.
- the indices(const wordRes& allow, const wordRes& deny) methods
were not defined consistently with the wordRes::filter handling.
wordRes::filter - allow/deny both empty:
= no filtering (ie, accept everything)
indices(allow,deny) - allow/deny both empty:
= return identity list (NEW behaviour)
= return empty list (OLD behaviour)
Consider the old behaviour a minor bug since the limited number of
callers had their own checks that avoided the poor behaviour.
Example of the inconsistent behaviour:
pbm.indices(wordRes(), wordRes({"non-existent"}))
--> identity list (old, new behaviour)
pbm.indices(wordRes(), wordRes())
--> identity list (new behaviour)
--> empty list (old behaviour)
- tests for list equality with different but compatible data types.
Eg, when comparing lists of int32 and int64 values.
STYLE: pass UList instead of List references into ListOps functors
- avoids intermediate allocation and re-assignment to self (#3374)
BUG: checkMesh (application) with questionable memory handling (#3374)
- move the contents of the new points instead of attempting to transfer
the entire list
COMP: replace mapDistribute specializations with if constexpr handling
- simplify future maintenance
- in messageStream::masterStream(int), it forwarded to stream()
without the communicator, which meant it would incorrectly check
UPstream::master(worldComm) and possibly not produce any output (or
block).
ENH: align MPI_Probe non-blocking handling with header description
- the header states that the commsType is non-blocking or not,
but the implementation actually checked for 'buffered' or not.
STYLE: fix some spacing and some documentation
- use functionObject writeInterval not timeInterval.
No change in behaviour since the missing writeInterval is treated
as '1' anyhow when using 'timeStep' for the writeControl
- consistent use of 'adjustable' vs 'adjustableRunTime'
- prefer '#eval{ vector(...) }' to calling '#eval' multiple times
ENH: improvements for GeometricBoundaryField evaluation
- early termination from evaluate_if() and evaluateCoupled().
- evaluateCoupled() now forwards to evaluate_if() and receives
additional handling for a 'void' parameter type.
BREAKING: extra template parameter for overset correctBoundaryCondition
- the true/false flag as a template parameter instead of as an
argument to use 'if constexpr' code
- encapsulates (foundObject && lookupPatchField) together,
similar to cfindObject
STYLE: remove unnecessary dummy parameters from lookupPatchField
- these were a workaround for a very old gcc bug and are no longer
needed. However, retain the (unneeded) second template parameter to
continue with not breaking existing old code - it has no overhead.
Signature:
void patchInternalField(UList<Type>& pfld) const;
// OLD: void patchInternalField(Field<Type>& pfld) const;
This change is necessary to allow collection into slices of a
larger list.
ENH: add {fa,fv}PatchField::patchNeighbourField(UList<Type>&)
- a retrieval version similar to patchInternalField(...)
STYLE: adjust AMI patch field private method names
- rename private method
patchNeighbourField(...) -> getNeighbourField(...)
to avoid access clashes with public methods
- remove undefined method neighbourSideField()
- the number of false positives has reduced, but in a few remaining
cases, the compiler cannot possibly "know" that the pointer stored
on the registry will outlive the scope of the method (for example)
gcc-13: suppressing these spurious warnings needs to be done at each
caller, which is simply not worth it, since later compiler versions
provide a cleaner solution.
gcc-14: the [[gnu::no_dangling]] attribute on the declaration
lets the compiler know the intent.
- additional FOAM_REAL_GNUC macro (defined in stdFoam.H) to define
the "real" gcc version and ignoring other compilers masquerading
as gcc.
COMP: rename MeshObject code to {cxx,txx}
- avoids issues on case-insensitive filesystems (#3316)
- the output parameter was previously a field and resized according to
the patch size. Now the output parameter must be pre-sized prior to
calling, which makes it possible to collect the patch internal
fields into slices of a larger list.
Signatures:
void patchInternalField
(
const UList<Type>& internalData,
UList<Type>& pfld // OLD: Field<Type>& pfld
) const;
void patchInternalField
(
const UList<Type>& internalData,
const labelUList& addressing,
UList<Type>& pfld // OLD: Field<Type>& pfld
) const;
This low-level change is not expected to affect any user code,
which would normally use a higher-level interface such as from
fvPatchField etc.
- can be used to pre-allocate space for internal+boundary field for
flat addressing (issue #3364).
For example:
DynamicField<Type> fld
(
std::pair<label,label>
(
GeoMesh::size(mesh),
GeoMesh::size(mesh)
+ (extra ? GeoMesh::boundary_size(mesh) : label(0))
)
);
ENH: base changes for GeometricField flags
- FieldBase 'localBoundaryConsistency_' and 'localBoundaryTolerance_'
for central handling of local boundary consistency checks.
- FieldBase 'unifiedGeometricField' for future extensions to GeometricField
- include "contiguous.H" in ListPolicy, which makes it available
whenever UList.H has been included
ENH: return plain List instead of shrinking the DynamicList
- constCast() convenience methods.
This simplies coding in places, especially in solvers
- inline some methods within headers, for better overview/maintenance
- only set DimensionedField default value on construct if not read
- storeOldTimes() does not require const_cast
- makes fvPatch consistent with faPatch etc and can simplify coding
ENH: handle sizing within extrapolateInternal() patch field methods
- reduces reliance on any sub-components
ENH: extend polyBoundaryMesh patch selectors
- indices_if() method with a predicate, or with a patch-type
behaves similarly to findPatchIDs(), but returns a sorted
labelList instead of a labelHashSet
- nFaces_if() method with a predicate return the number of boundary
faces for patches matching the given predicate.
The solverPerformanceDict gets larger due to the addition of a SolverPerformance
data per field at every outer iteration within the same main iteration/time
step.
However, the subsequent functionalities seem to use only the first and last
element of this dictionary per field; therefore, storing the interim values
was revealed to be redundant.
The change removes the interim values by transforming the `List` container
into the `Pair` container, and modifying the relevant algorithms.
- this can be used as an alternative to the (-world) multi-world
option. For example, for calling OpenFOAM applications with MUI
(https://github.com/MxUI/MUI)
- can use -mpi-no-comm-dup to suppress the initial communicator
duplication (to avoid potential deadlock with coupled processes).
This is partly related to comments in merge-request !735
ENH: simplify parsing/removal of local -world option
- can extract the world name in a single pass and also makes the
parsing robuster.
ENH: support regular MPI_Comm_split()
- the two-step method of Allgather + Comm_create_group may not be
expected by other applications (issue #3127) and that can lead to
deadlock, so also add in code for the regular MPI_Comm_split.
Does not support re-sorting keys!
FIX: faulty logic for splitting communicators
- only affected more recent develop branch
- useful to have std::reduce(), std::transform_reduce() available in
more places, so treat like <algorithm> and include in "stdFoam.H"
STYLE: add 'stricter' detection markers for cast of SubList to List etc.
STYLE: remove 'const' qualifier from Foam:one/Foam::zero (in Field)
- previously had special resizing treatment for the corner case when
the addressable size and the new capacity are identical. However,
that particular approach (to minimize copying) meant that the exact
deallocation size would likely be incorrect.
Having the correct deallocation size becomes more important with
alternative allocators.
Introduce resize_copy() protected function to limit the number
of elements copied during the resize.
ENH: provide DynamicList/DynamicField constructor with sizing
- allows fine-grained creation of a DynamicList/DynamicField with a
given size/capacity without an initial value.
COMP: typo in code for DynamicList::push_back() with IndirectList
- for reciprocal values, gMinMax() first and then calculate the
reciprocal, which avoids creating temporaries
STYLE: prefer MinMax to separate min/max accounting
COMP: namespace qualify min/max for deltaT, CourantNo, etc (#3348)
- these already existed for a single value, but now handle the full
field. This is more memory-friendly.
fld.clamp_min(lower); OLD: fld = max(fld, lower);
fld.clamp_max(upper); OLD: fld = min(fld, upper);
- central way to calculate reverse sizes for dynamic containers.
For example;
reserve_size<16, 2>(len, cap); // min-size=16, ratio=2
reserve_size<16, 3, 2>(len, cap); // min-size=16, ratio=1.5
replaces this type of code that was used in several places:
max(SizeMin, max(len, label(2*capacity_)));
The caller will have already checked (len < cap) before deciding
to make this call.
ENH: updates for DynamicList/DynamicField handling
- add reserve_exact() method, which is like reserve() but without any
extra sizing heuristics
- add DynamicField 'reuse' constructors, consistent with Field constructors
- sync allocated size before list destruction.
This may help when using aligned allocation strategies.
Using 'return List<T>(std::move(dynList))' for transfer of content
(with implicit shrinking) into a plain List, and leave copy elision
to do the rest. The implicit transfer (move construct List from
DynamicList) will normally invoke resize (new/delete and moving
elements).
With 'return dynList.shrink()', it will first invoke an internal
resize (new/delete and moving elements), followed by a copy
construct as a plain list.
STYLE: avoid implicit cast to 'const List&' in constructors
- provides an additional hook when linking OSspecific
CONFIG: apply quiet flag to wmkdepend
- suppresses "could not open FileName" warnings in quiet mode
FIX: reinstate selection of strict/non-strict deprecation
- accidentally removed in cf2b305b4f.
- extend with a _STRICTER version as well.
- provide separate float/double UList interfaces, which improves
flexibility (eg, with SPDP)
- sigFpe::fillNan_if() interface, for filling in when using alternative
memory allocators
- previous code used derived string iterators, but these would
be largely ignored anyhow since the underlying std::sub_match
str() method would just yields a std::string anyhow.
The SubStrings::str(size_t) method wasn't used in any code, so now
just use std::string iterators only.
This change simplfies overall handling, since it removes an unneeded
template dependency.
- /usr/bin/{gcc,g++} normally just symlinks to clang/clang++
and may have unknown default flags.
For a gcc toolchain, it would be better to use a homebrew
installation.
For these cases, the compiler will need to be specified with
version=.. in WM_COMPILE_CONTROL.
For example, with "version=14", to select gcc-14, g++-14 from the
homebrew installation.
- needs a slight hack for locating the FlexLexer.h header.
Added into src/OSspecific/POSIX similar to how it is handled
in src/OSspecific/MSwindows
CONFIG: add simple config/detection support for libumpire (Linux)
- new options to set components specified by homebrew.
Sets version as system, path from brew --prefix
-adios-brew, -adios2-brew, -boost-brew, -cgal-brew,
-fftw-brew, -kahip-brew, -metis-brew, -scotch-brew,
-gmp-brew, -mpfr-brew
-with-homebrew
Shortcut for selecting all the above (except gmp, mpfr)
* additional special treatment for GMP and MPFR.
If using non-system locations and not part of the ThirdParty
compiler, they can additionally be set in the CGAL config file:
-gmp-brew, -gmp-path
-mpfr-brew, -mpfr-path
- easier to create type-specific looping in templated code
STYLE: pass 'direction' and 'label' by value instead of reference
COMP: qualify Foam::min() in dense matrix classes
- compiler versions are now sufficient that only the C++ regex
interface is now being used. Can remove the old POSIX code
accordingly.
This change also removes any dependency on the SubStrings class to
manage the matching results.
ENH: remove OpenFOAM dependencies from MacOS addr2line utility
- The register keyword has been removed from c++17 but old flex
versions (version < 2.6.0) produce code including it, leading to
compilation errors when using clang (despite disabling the diagnostic).
gcc compiles but issues warnings.
- use '#define register' as empty as a workaround
STYLE: mark Pstream::scatterList() as deprecated
- this entry point is not directly used anywhere, only the
scatterList_algorithm backend is actually used.
The scatterList() routine is misnomer since it actually works like a
broadcast that skips overwriting the local rank, but only if used in
combination with the gatherList() manual implementation that uses
the same walk pattern.
- can be used to simplify some logic. For example,
if
(
(tok.read(is) && tok.isWord("FoamFile"))
&& (tok.read(is) && tok.isPunctuation(token::BEGIN_BLOCK))
)
...
vs
if
(
(is.good() && (is >> tok) && tok.isWord("FoamFile")) ...
&& (is.good() && (is >> tok) && tok.isPunctuation(token::BEGIN_BLOCK))
) ...
- compiler cannot decide between std::string and std::string_view
when creating from 'const char*' without also supplying the size,
so also supply a 'const char*' constructor.
ENH: additional string_view handling for ITstream and SubStrings
- the 'move' treatment performs a shallow copy but does not alter
the passed parameter. Identical semantics as per std::span.
ENH: constexpr for basic HashTable constructors
STYLE: 'Foam::zero' instead of 'const Foam::zero' for containers
- this is simply a compiler dispatch flag, so the additional 'const'
qualifier is unnecessary
- should ideally avoid SLList in most cases, since it is allocation
intensive and most places can easily use DynamicList or
CircularBuffer instead.
STYLE: use push_uniq instead of deprecated appendUniq method
- mark with a 'normal' deprecation instead of 'strict' deprecation
- the '-no-core' to limit coredumps to zero size
- the '-quick' option, which changes valgrind --leak-check from "full"
to "summary", and implies -no-core as well.
- enforce tcp libfabrics provider under valgrind since valgrind
does not otherwie work nicely with RMA
- fails with MPI_ARG_ERR.
Do not assume that any vendors actually support in-place handling
for MPI_Reduce(), regardless of what their documentation may claim.
- includes intrinsic MPI types, but no component aggregates since we
barely wish to use gatherv/scatterv (slow!) in the first place
and it makes no sense to recalculate the list of counts for
component aggregates which we will never use.
- for known data types (and component aggregates),
and intrisic reduction operation can now use
UPstream::mpiReduce(), UPstream::mpiAllReduce().
This change permits more operations to use MPI calls directly.
eg,
reduce(vec, sumOp<vector>);
now calls mpiAllReduce(..., op_sum) instead of point-to-point,
followed by a broadcast.
Similarly, when called as a simple reduction (not all-reduce)
Pstream::gather(vec, sumOp<vector>);
now calls mpiReduce(..., op_sum) instead of point-to-point
- extend use of MPI calls to list-wise reductions as well
- extend sumReduce() to bundle/unbundle vector-space types,
which lowers overall communication.
Before:
1) send/recv + binary op through a communication tree
2) broadcast
3) all-reduce of the count
Now:
1) pack into a local bundle
2) all-reduce
3) unpack the bundle
- support send/recv of basic types (int32, float, double, ...) in
addition to common OpenFOAM vectorspace types (floatVector,
doubleVector, ...)
This permits sending NUM items of the given types instead of sending
NUM sizeof() bytes.
For a vector (as double): 1 item instead of 24 items (3*8 bytes).
For a tensor (as double): 1 item instead of 72 items (9*8 bytes).
- simplify and rationalize some of the broadcast methods for more code
reuse.
The bottom level UPstream::broadcast is now always to/from "root=0".
This was previously passed as a default parameter, but never used
anything other than '0' in the code. Fixing it as '0' makes it
consistent with the 'top-down' logical for node-based broadcast.
- now distinguish between basic MPI types and user-defined types.
The new front-facing trait UPstream_basic_dataType unwinds components
and other types, but only for MPI fundamental types
(including any aliases)
- additional helper to combine a test for binary operator validity and
basic data type validity, which better expresses intent:
template<class BinaryOp, class T>
UPstream_data_opType;
- relax bit-wise operators to also accept signed integrals
and 'void' generic
- remove unused/unusable broadcast stream constructors/methods
- provide OPBstream::sends() and IPBstream::recvs() methods,
refactored from Pstream::broadcasts. These will always use
serializations, even for contiguous content.
- additional methods to support special handling of zero-sized lists.
For example,
if (UPstream::master(comm))
{
if (list.empty()) OPBstream::send(Foam::zero, comm);
else OPBstream::send(list, comm);
}
else
{
IPBstream is(comm);
if (is.remaining()) { is >> list; }
else { list.clear(); }
}
This avoids serialization of an empty list and the resulting double
broadcast (size + content), using instead a single broadcast (size).
STYLE: more consistency in communicator types (int vs label)
- returns the (start/size) range of the commLocalNode ranks in terms
of the (const) world communicator processors. This allows mapping
back into lists defined in terms of the world ranks.
- similar to what std::copy_n and std::fill_n would do, except with
templated loops. This allows compile-time transcribing with loop
unrolling. For example,
vector vec1 = ..., vec2 = ...;
FixedList<scalar, 6> values;
VectorSpaceOps<3>::copy_n(vec1.begin(), values.begin());
VectorSpaceOps<3>::copy_n(vec2.begin(), values.begin(3))
// do something with all of these values
STYLE: make start index of VectorSpaceOps optional
ENH: add clamped begin(int) versions to FixedList as per UList
The front-end traits:
- UPstream_dataType trait:
This wrapper is unwinds the type to check against base/alias, but also
checks if it is a component aggregate of a supported UPstream data type.
This will be that main entry point for usage.
- UPstream_opType trait:
Provides a mapping of OpenFOAM ops to their MPI equivalent.
The \c opcode_id is the corresponding internal representation.
The lower-level traits (not normally used within coding)
- UPstream_base_dataType trait:
Tests true/false if the specified data type has an internal MPI equivalent.
The \c datatype_id is the corresponding internal enumeration.
Even if this tests as false, it will always return \c type_byte as the
fallback for general contiguous data
- UPstream_alias_dataType trait:
Provides mapping for <int/long/long long,...> to the fundamental 32/64
integrals, since <int/long/long long,...> may not otherwise directly map
on all systems.
NOTE: can use the updates Test-machine-sizes test application to
determine if all data types and aliases are properly defined on
different systems
- this will allow send/recv/broadcast of various data types directly
without reinterpreting as bytes. No performance benefit, but makes
programming more flexible. In addition to the normal MPI types, also
provide some convenient groupings such as double[3], double[9] etc.
- the additional user-defined data types are created on the start of
MPI and removed before shutdown
- previously there were two places that used nProcsSimpleSum for
defining the communication pattern. However, this meant in practice
that filling of linearCommunication_ and treeCommunication_ themselves
where globally controlled.
Now retain the state within commsStructList and use linear/tree
when populating.
- deprecated and replaced (JAN-2023) with a version that uses
UPstream::Request to track the request. This avoids placing a
request on the global list and then having difficulty isolating it
later (or having it cleared out by someone else).
ENH: UPstream::addRequest() now ignores null requests
- avoids placing useless requests on the global list
- replace with plusOp for reductions. The old use didn't necessarily work
well with compiler resolution in all cases.
Simplify to use plusOp (and removed the old version).
[Does not affect very much code...]
COMP: incorrect include ordering for GeometricFieldFunctions
- header was included after the template code
REGRESSION: combineAllGather mapped to incorrect method (81fa7d08ee)
STYLE: use UPstream::commWarn(...) setter method
- eliminates nearly identical code between 'gather' and 'combineGather'
* Normal gather updates by assigning the result of the binary operation.
* Combine gather updates by using a binary operator that modifies
its first parameter in-place
By-product of this refactoring are these new variants:
listGather(), listGatherReduce()
mapGather(), mapGatherReduce()
that mirror the previously existing ones
listCombineGather(), listCombineReduce()
mapCombineGather(), mapCombineReduce()
except that they use the 'regular' binary operator
- the general OpenFOAM way of collecting data often looks like this:
List<scalar> allValues(numProcs);
allValues[myProc] = localValue;
Pstream::gatherList(allValues);
// Now possible like this
List<scalar> allValues(numProcs);
allValues[myProc] = localValue;
UPstream::mpiGather(nullptr, allValues.data_bytes(), sizeof(scalar));
- adjusted Pstream::gatherList accordingly.
Split out the manual implementations, give them new names
(..._tree_algorithm) and make them private.
STYLE: rename UPstream::gather -> UPstream::mpiGatherv
- easier to identify and establishes the connection to the MPI call
- additional startup guard for inter-node/local-node queries (UPstream)
- impose linear communication tree for inter-node/local-node
communicators. Was previously defaulted to a basic tree, but more
consistent to have flat addressing for these types of connections.
- demand-driven UPstream::interNode_offsets() for walking
inter-node ranges instead of creating it manually in various places.
- (style): List<int> instead of labelList for internal commsStruct
since the communication structures are tied to MPI sizes
and not to the OpenFOAM label sizes
- reduce the number of intermediate buffer allocations within
gatherList, scatterList.
- replace gatherValues() with listGatherValues(), which returns the
gathered values instead of passing by argument. This makes it less
fragile and more convenient. Naming as per
Pstream::listGatherValues(), but still retaining the original
parameter order.
- rename inplace 'gather' variant as 'gatherInplace' for clarity.
- changed signature of lowest-level globalIndex::gather routines from
List<Type> to UList<Type> for the output and removed any resizing.
This means that the caller is responsible for ensuring that the
receiving field is adequately sized (on master). This change allows
potential reuse of 'work' arrays etc.
The only code change for using this low-level gather was in
GAMGAgglomeration.
- split/duplicate functionality
- rework inter-node/intra-node handling to allow selection of
splitting based on 'shared' or hostname (default).
- always creates node communicators at startup:
* commInterNode() - between nodes
* commLocalNode() - within a node
- world-comm is now always a duplicate of MPI_COMM_WORLD to provide
better separation from other processes.
NB:
the inter-node comm is a slight exception to other communicators
in that we always retain its list of (global) ranks, even if the
local process is not in that communicator.
This can help when constructing topology-aware patterns.
FIX: non-participating ranks still had knowledge of their potential siblings
- after create by group, the procIDs_ of non-participating ranks
should be empty (except for the inter-node exception)
- using the List containers, and not their low-level data_bytes(),
size_bytes() methods is more convenient and allows future
adjustments to be centralized
ENH: trivial intptr_t wrapper for MPI_Win
STYLE: minor adjustments to mpirunDebug
- 'if constexpr (...)'
* instead of std::enable_if
* terminate template recursion
* compile-time elimination of code
- use C++14 '_t', '_v' versions,
eg, std::is_integral_v<T> instead of std::is_integral<T>::value
- std::begin, std::end, std::void_t instead of prev stdFoam versions
- provide is_contiguous_v<..> as short form of is_contiguous<..>::value
with the additional benefit of removing any cv qualifiers.
ENH: include is_rotational_vectorspace trait
- tests for vector-space and nComponents > 1 (ie, not sphericalTensor)
ENH: improve robustness of pTraits_.. tests by removing cv qualifiers
- as per std::array and FixedList
STYLE: rename Scalar.[CH] -> scalarImpl.[CH] (these are internal files)
- added inclusion guards to protect against bad use
- poor naming (eg, 'exponential.[CH]') within the same set of library
files means that the lnInclude/ contents are inconsistent or partly
meaningless (related to #2520 and !542).
Remedied by adding model-type qualifiers to the file names.
- remove unneeded -Wno-old-style flags with boost/cgal elements
- add nvc equivalent to gcc/clang -Wno-invalid-offsetof
- avoid warnings about set-but-unused variable and change of scoping
STYLE: remove wmake 'CGAL' rule
- was a transitional forward to 'cgal' rule since DEC-2020
Description:
The plicRDF interface reconstruction scheme calculates a reconstructed distance
function (RDF) in all interface cells and their point neighbours.
In point neighbours to interface cells, the RDF is calculated as a weighted
average of the distances to all adjacent interface cell centres with the weight
being the inverse distance to the cell centre.
By using the zoneDistribute class written by Henning Scheufler, the required
stencil data is communicated efficiently for stencil cells living on different
sides of one or more processor patches.
Some of the data required for the RDF reconstruction are cell centre and
interface centre positions. When a stencil extends across a cyclic patch these
positions have so far not been properly transformed in OpenFOAM. This issue is
fixed by the current contribution.
The fix is done by modifying the zoneDistribute class to hold the required
information about zone cells adjacent to cyclic patches. Positions are then
communicated with a new getPosition function which replaces getValue for
position data in the reconstructedDistanceFunction and plicRDF classes.
The implementation does not change the behaviour for cells not on
a cyclic patch and should have insignificant effect on efficiency for these.
The implementation can probably be optimised in terms of efficiency for zone
cells on cyclic patches, but we note that there are generally only very few of
these (interface cells and their point neighbours on cyclic patches) and so
the potential for speedup is expected to be limited.
Current limitations:
- In parallel, the user must constrain the decomposition to preserve cyclic
patches on the same processor, for the implementation to work properly.
- See an example here: tutorials/discInConstantFlowCyclicBCs/system/decomposeParDict
- In the case of parallel rotational cyclics that are split by the decomposition
the current bugfix does not work and therefore throws an error. This is ongoing
work and should be reported and fixed by a future patch.
For further details, please see the modified files and the comments therein:
- $FOAM_SRC/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.H
- $FOAM_SRC/finiteVolume/fvMesh/zoneDistribute/zoneDistribute.C
- $FOAM_SRC/finiteVolume/fvMesh/zoneDistribute/zoneDistributeI.H
- $FOAM_SRC/transportModels/geometricVoF/reconstructedDistanceFunction/reconstructedDistanceFunction.C
- $FOAM_SRC/src/transportModels/geometricVoF/reconstructionSchemes/plicSchemes/plicRDF/plicRDF.C
Co-authored-by: David Müller <> KIT
Co-authored-by: Konstantinos Missios <> Roskilde University
Co-authored-by: Johan Roenby <> Roskilde University and STROMNING
Reverting 267bd1af36 since makes it hard
to run cell-based algorithm on symmetric matrix.
- might become a problem if all discretisation
becomes lowerCSR based and lower() is never
constructed ...
- normally mingw will export *all* symbols, but since the ADF library
explicitly uses __declspec(dllexport) itself we must do the same
otherwise none of our library symbols are exported and linking fails.
- update some code style for conversion/ccm
Accumulates function object result values and renders into a graph in SVG format
Minimal example by using system/controlDict.functions to plot the residuals from
the solverInfo function Object:
residualGraph
{
type graphFunctionObject;
libs (utilityFunctionObjects);
writeControl writeTime;
logScaleX no;
logScaleY yes;
xlabel "Iteration";
ylabel "log10(Initial residual)";
functions
{
line1
{
object solverInfo1;
entry Ux_initial;
}
line2
{
object solverInfo1;
entry Uy_initial;
}
line3
{
object solverInfo1;
entry Uz_initial;
}
line4
{
object solverInfo1;
entry p_initial;
}
}
}
Activated using the [optional] 'shielding' keyword having the options:
- standard: [default] same as v2406 and earlier
- ZDES2020: new option based on the reference:
Deck, S., Renard, N. (2020).
Towards an enhanced protection of attached boundary layers in hybrid
RANS/LES methods.
Journal of Computational Physics, 400, 108970.
DOI:10.1016/j.jcp.2019.108970
Contribution from Marian Fuchs at UpstreamCFD GmbH
Integrated by Andrew Heather OpenCFD Ltd.
Multi-faceZone based blending differencing scheme.
Schemes are set in dictonary format according to:
divSchemes
{
.
.
div(phi,U) Gauss zoneBlended
{
default defaultScheme;
faceZone1 scheme1;
faceZone2 scheme2;
...
faceZoneN schemeN;
}
.
.
}
The default entry specifies the background scheme; additional schemes
can be set per faceZone, e.g. scheme1 is applied to facZone1,
scheme2 is applied to facZone2 etc.
- The edgeInterpolation::makeCorrectionVectors() disables the non-orthogonality
correction if the calculated non-orthogonality coefficient is below 0.1.
However, this activation routine only considers internal edges, and excludes
any processor edges, resulting in inconsistent parallel calculations. This
routine is removed.
- Fatal errors are replaced with zero-valued fields for non-orthogonality-
and skewness-correction routines.
- 1_Inlet_2_Outlet/porosityBased/R_10x-init/reEval: showcases the
initialization of the design variables using topoSet and setFields
- 3DBox/losses-mass-uniformity-SQP-extraVars: showcases the use of the
so-called 'extra variables' in the QP problem which relax it,
allowing its solution even if there is no feasible one
in topology optimisation, through a volScalarfield named alpha.
The order of precedence is (top to bottom):
- values read from time/uniform/topOVars (used also for continuation)
- values read from 0/alpha (can be easily set with topoSet + setFields)
- uniform zero
to Function1, to be able to change their value at runtime. Useful when
constraints are not feasible at the beginning of the optimisation
(frequent in topology optimisation) and we want to leave some room to
the optimiser to not focus heavily on them at the beginning, but respect
them during the last optimisation cycles.
Has a big impact, especially in MMA, when dealing with volume
constraints in topology optimisation.
When using the (optional) convergence criteria for the optimisation
loop, adherence to them is checked in the postUpdate phase of the update
of the design variables. If a line search is used, this means that the
flow equations have been solved anew using the new design variables and
the objective reduction check makes sense. If, however, no line search
is used, the objective reduction check happens immediately after the
update of the design variables and before re-solving the flow equations,
giving a reduction in the objective function and terminating the
optimisation loop prematurely.
Solved by calling the convergence check directly after the solution of
the flow equations, in case of a fixedStepUpdate
Was triggering update of cell-cell stencil (=meshObject) without
corresponding rebuilding of lduAddressing (= oversetFvMeshBase storage).
- added clearOut to oversetFvMesh(Base)
- added call to clearOut when rebuilding stencil
- PLOAD2 is a reasonable default and PLOAD4 output
(currently misused for vectors/tensors) is the exception.
- simplify the specification by using optional PLOAD4, PLOAD2 wordRes
lists to act as allow/deny selectors. In the regular case won't need
to specify anything or perhaps only the PLOAD4 list.
ENH: atomic creation of Nastran files
FIX: inconsistent Nastran surface output format
- use FREE format by default. Previously had an odd mix of SHORT
format when created without options and LONG format (as default)
when created with format options.
- the old logic relied on the presence/absence of a comma to decide
whether to parse as fixed or free format. This logic is faulty when
handling the final (trailing) entry and will generally lead to the
last field being truncated when read in.
Now the caller decides on fixed vs free.
FIX: inconsistent Nastran surface output format
- use FREE format by default. Previously had an odd mix of SHORT
format when created without options and LONG format (as default)
when created with format options.
Creates view factors for the view factor radiation model.
User-selectable models:
- raySearchEngine: model to generate rays, i.e. face-to-face connections
- viewFactorModel: model to compute the view factors
For visualisation, use:
- Write the view factors as a volume field
writeViewFactors yes;
- Write the rays using OBJ format:
writeRays yes; // default = no
Participating patches must be in the \c vewFactorWall group, i.e. using the
\c inGroups entry of the "\<case\>/polyMesh/boundary" file.
\verbatim
myPatch
{
type wall;
inGroups 2(wall viewFactorWall);
...
}
\endverbatim
Reads:
- <constant>/viewFactorsDict : main controls
- <constant>/finalAgglom : agglomeration addressing (from faceAgglomerate)
Generates:
- <constant>/F : view factors (matrix)
- <constant>/mapDist : map used for parallel running
- <constant>/globalFaceFaces : face addressing
- can be useful for various orientation-related geometry or mesh
manipulations during pre-/post-processing:
* combine with linearDirection to achieve better extrusion results.
* orientation of transformations, blockMesh, result projections, ...
STYLE: minor code modernizations
Co-authored-by: Mark Olesen <>
- exprValueFieldTag is an extended version of exprValue,
with additional Field/List uniformity handling
- the exprValueFieldTag reduce() method provides a more efficient
method than using a regular combine operator. Since fields are
usually non-uniform, will mostly only need the bitwise reduce and
not a more expensive gather/combine.
ENH: output of exprValue (scalar type) now includes '.'
- prevents scalar/label ambiguity for values like '100.0', which would
otherwise be written as '100' and thus interpreted as a label value
when re-reading.
Based on the reference
Tomiyama, A., Kataoka, I., Zun, I., Sakaguchi, T. (1998)
Drag coefficients of single bubbles under normal and micro gravity
conditions
JSME International Journal, 41(2), 472-479.
Example usage
subModels
{
particleForces
{
tomiyamaDrag
{
sigma 0.07;
contamination pure; // pure | slight | full
}
}
}
Determines radiation heat flux between patches when using the viewFactor
radiation model.
Example usage
viewFactorHeatFlux1
{
// Mandatory entries (unmodifiable)
type viewFactorHeatFlux;
libs (utilityFunctionObjects);
// Optional entries (runtime modifiable)
qr qr;
}
STYLE: polyPatch cached areaFraction as std::unique_ptr
- more consistent with other demand-driven data.
Getter now returns tmp field instead of const reference.
- the ensightReadFile init() now automatically sets up binary/ascii
(for geometry files) and checks for the transient "BEGIN TIME STEP"
marker. If found, will also populate the file offsets for each of
the timesteps. If no corresponding footer is found (which would be
very inefficient), it simply pretends that there is only a single
time step instead of performing a costly file scan.
- parsing of the ensight case file now also supports the use of
filename numbers:
as an alternative to
filename start number:
filename increment:
- improved parsing robustness of "time values:" entry.
Can now also have contents on the same line as the introducer.
ENH: base-level adjustments for writing transient single-file
- beginGeometry() is now separated out from file creation.
- in append mode, ensightFile and ensightGeoFile will attempt to
parse existing time-step information.
- previous support for file appending (largely unused) always
specified opening with the std::ios_base::app flag.
Now differentiate between append behaviours:
APPEND_APP
~~~~~~~~~~
Corresponds to std::ios_base::app behaviour:
- Existing files will be preserved and a seek-to-end is performed at
every write. With this mode seeks/repositioning within the file
will effectively be ignored on output.
APPEND_ATE
~~~~~~~~~~
Largely approximates std::ios_base::ate behaviour:
- Existing files will be preserved and a seek-to-end is performed
immediately after opening, but not subsequently. Can use seekp()
to overwrite parts of a file.
- evaluate()
the communication type is exposed as a parameter to allow for more
tuning, but default parameter remains defaultCommsType so there is
no change in behaviour for existing code
- evaluate_if()
supports a general selection predicate
- evaluateSelected()
now does initEvaluate() for all patches, waits and then calls
evaluate(). This avoids potential deadlocks when multiple patches
are inter-communicating.
ENH: align DimensionedField reading with GeometricField treatment
- use localIOdictionary to obtain the dictionary contents
ENH: update GeometricField code
- change GeometricField writeData() as primary output method
(not operator<<) for better clarity of purpose
- use unique_ptr for GeometricField demand-driven data
- boundary entries with writeEntry(const word&, ...) instead of
writeEntry(const keyType&, ...) to match with most other
writeEntry() signatures. Also, this content will not be used
to supply regex matched sub-dictionaries.
STYLE: more consistent patch initEvaluate()/evaluate() coding
- delay construction of message buffer
- OStringStream count() method to test if anything has been streamed
STYLE: explicit use of std::ios_base in IOstreams
- document the return information of set flag methods
- can be used with this type of code:
ITstream* streamPtr = dict.findStream(name);
if (streamPtr)
{
auto& is = *streamPtr;
...
}
versus:
const entry* eptr = dict.findEntry(name);
if (eptr && eptr->isStream())
{
auto& is = eptr->stream();
...
}
ENH: add findStream(), streamPtr(), isStream() to dictionary search
- symmetric with findDict(), dictPtr(), isDict() methods
STYLE: use findDict() instead of found() + subDict() pairing
COMP: define is_globalIOobject trait at top of IOobject header
- more visibility, permits reuse for specializations etc.
BUG: streamFunction used uninitialized values for symmetry patches
- related to 8a8b5db977 changes (#3144)
ENH: improve robustness of surface field flattening
- vtk::surfaceFieldWriter
- the maxCommsSize variable is used to 'chunk' large data transfers
(eg, with PstreamBuffers) into a multi-pass send/recv sequence.
The send/recv windows for chunk-wise transfers:
iter data window
---- -----------
0 [0, 1*chunk]
1 [1*chunk, 2*chunk]
2 [2*chunk, 3*chunk]
...
Since we mostly send/recv in bytes, the current internal limit
for MPI counts (INT_MAX) can be hit rather quickly.
The chunking limit should thus also be INT_MAX, but since it is
rather tedious to specify such large numbers, can instead use
maxCommsSize = -1
to specify (INT_MAX-1) as the limit.
The default value of maxCommsSize = 0 (ie, no chunking).
Note
~~~~
In previous versions, the number of chunks was determined by the
sender sizes. This required an additional MPI_Allreduce to establish
an overall consistent number of chunks to walk. This additional
overhead each time meant that maxCommsSize was rarely actually
enabled.
We can, however, instead rely on the send/recv buffers having been
consistently sized and simply walk through the local send/recvs until
no further chunks need to be exchanged. As an additional enhancement,
the message tags are connected to chunking iteration, which allows
the setup of all send/recvs without an intermediate Allwait.
ENH: extend UPstream::probeMessage to use int64 instead of int for sizes
- the timeSelector is often used to select single or multiple times
(eg, for post-processing). However, there are a few applications
where only a *single* time should be selected and set.
These are now covered by this type of use:
timeSelector::addOptions_singleTime(); // Single-time options
...
// Allow override of time from specified time options, or no-op
timeSelector::setTimeIfPresent(runTime, args);
In some cases, if can be desirable to force starting from the
initial Time=0 when no time options have been specified:
// Set time from specified time options, or force start from Time=0
timeSelector::setTimeIfPresent(runTime, args, true);
These changes make a number of includes redundant:
* addTimeOptions.H
* checkConstantOption.H
* checkTimeOption.H
* checkTimeOptions.H
* checkTimeOptionsNoConstant.H
ENH: add time handling to setFields, setAlphaField (#3143)
Co-authored-by: Johan Roenby <>
STYLE: replace instant("constant") with instant(0, "constant")
- avoids relying on atof parse behaviour returning zero
- for example,
string buffer = ...;
SubStrings<string> split;
{
auto colon = buffer.find(':');
if (colon != std::string::npos)
{
split = stringOps::splitSpace(buffer, colon+1);
}
}
Not really possible with a substr() since that would create a new
temporary which then disappears. Similarly awkward to split and
then scan for the ':' to decide how many to discard.
ENH: add pop_front() and pop_back() methods to SubStrings
- the content is trivial enough (a pair of iterators) and the total
number of elements is usually reasonable short so that removal of
elements is inexpensive
For example,
string buffer = ...;
auto split = stringOps::splitSpace(buffer);
if (!split.empty() && split[0].str() == "face")
{
split.pop_front();
}
- ensures more accurate values for message sizes than using
MPI Get_count(), which trucates at INT_MAX
- add more/better error messages when trying to receive messages
that exceed INT_MAX or the char buffer lengths
- "buffered" corresponds to MPI_Bsend (buffered send),
whereas the old name "blocking" is misleading since the
regular MPI_Send also blocks until completion
(ie, buffer can be reused).
ENH: IPstream::read() returns std::streamsize instead of label (#3152)
- previously returned a 'label' but std::streamsize is consistent with
the input parameter and will help with later adjustments.
- use <label> instead of <int> for internal accounting of the message
size, for consistency with the underyling List<char> buffers used.
- improve handling for corner case of IPstream receive with
non-blocking, although this combination is not used anywhere
- robuster and more reliable determination of inserted objects
(previous code could produce false positives).
Now also determine the number of inserted objects within the
constructor (instead of simply storing a bool). This allows reuse
in the address calculations to reduce overheads there.
BUG: dodgy short-circuit logic for insertedObjectLabels()
- as a quick short-circuit it previously created as demand-driven
pointer with a zero elements. However, this meant that if this code
was called first (before any other addressing), subsequent calls to
the addressing would fail.
BUG: bad logic and lookup for faAreaMapper (#3147)
- was using labelHashSet but returning a bool and set using the
addressing using the unfiltered objects!
This is a latent bug since interpolated/inserted faces not
currently supported anyhow.
ENH: use std::unique_ptr for demand-driven data
- manual revert for 44d0fbd594.
Unless required for post-processing the "value" entry should not
written if it is not mandatory for reading.
This is especially crucial with an 'empty' patch field where the
field (size 0) has a different size from the patch.
- the changes made align fvsPatchField behaviour with fvPatchField
- return autoPtr<token::compound> instead of the derived type,
otherwise cannot easily construct a token from it
ENH: additional typed version of refCompoundToken()
- symmetric with typed version of transferCompoundToken()
and isCompound()
- add ITstream::findCompound<Type>() method.
Useful for searching within token streams
- previously automatically skipped the first communicator (which was
assumed to be MPI_COMM_WORLD), but now simply rely on the
internal pendingMPIFree_ to track which communicators have actually
been allocated.
- UPstream::Communicator is similar to UPstream::Request to
wrap/unwrap MPI_Comm. Provides a 'lookup' method to transcribe
the internal OpenFOAM communicator tracking to the opaque wrapped
version.
- provide an 'openfoam_mpi.H' interfacing file, which includes
the <mpi.h> as well as casting routines.
Example (caution: ugly!)
MPI_Comm myComm =
PstreamUtils::Cast::to_mpi
(
UPstream::Communicator::lookup(UPstream::worldComm)
);
- replace point-to-point transmission of the argList args/options with
a broadcast. This is sufficient for most cases (without distributed
roots).
For "normal" cases (non-distributed roots) this will replace the
nProcs-1 messages with a single broadcast.
- for cases with distributed roots, distinguish between a single,
identical root and different roots. An identical root can also be
subsequently handled with a broadcast. Different roots will still
require individual point-to-point communication.
For cases with distributed roots, it will add the overhead of an
additional broadcast.
- adds consistency with regular point-to-point parallel streams.
ENH: add ITstream::tokens() methods
- useful, for example, to disambiguate constructing tokenList from
a ITstream.
ITstream& is = otherDict.lookup("original");
tokenList deepCopy(is); // Error: from Istream or tokenList??
tokenList deepCopy(is.tokens()); // OK: from tokenList
- The internal storage location of finite-area changes from being
piggybacked on the polyMesh registry to a having its own dedicated
registry:
* allows a clearer separation of field types without name clashes.
* prerequisite for supporting multiple finite-area regions (future)
Old Locations:
```
0/Us
constant/faMesh
system/faMeshDefinition
system/faSchemes
system/faSolution
```
New Locations:
```
0/finite-area/Us
constant/finite-area/faMesh
system/finite-area/faMeshDefinition (or system/faMeshDefinition)
system/finite-area/faSchemes
system/finite-area/faSolution
```
NOTES:
The new locations represent a hard change (breaking change) that
is normally to be avoided, but seamless compatibility handling
within the code was found to be unworkable.
The `foamUpgradeFiniteArea` script provides assistance with migration.
As a convenience, the system/faMeshDefinition location continues
to be supported (may be deprecated in the future).
- Delete() will perform a 'checkOut()' which does the following:
* remove the object from the registry
* delete the pointer (if owned by the registry)
- Release() does the following:
* transfer ownership of the pointer (if owned by the registry)
- Store() does the following:
* transfer ownership of the pointer to the registry
ENH: use UPtrList of sorted objects for MeshObject updates
- few allocations and lower overhead than using a HashTable,
ensures the same walk order over the objects (in parallel)
STYLE: adjust meshObject debug statements
STYLE: update code style for phi modification (engine motion)
ENH: pass isMeshUpdate param in fvMesh/polyMesh clearOut() methods
- top-level use of isMeshUpdate parameter to clearOut and
clearAddressing was being inadvertently filtered out
- after the modification of d578d48a4f, the parent was now actually
searched. However, should be returning "constant" and not trigger a
FatalError if the file/directory is not found.
- findStrings, findMatchingStrings now mostly covered by matching
intrinsics in wordRe and wordRes.
Add static wordRes match() and matching() variants
COMP: remove stringListOps include from objectRegistry.H
- was already noted for removal (NOV-2018)
- NewIFstream would read complete remote file to decide if
was collated.
- This limits files to 31bit size
- Instead now have master-only opening of file.
- Still has problem with refinement history/cellLevel etc.
- previously would always return "constant" as the instance for
an optional dir/file that wasn't found.
However, this meant retesting to screen out false positives.
Now support an additional parameter
'bool constant_fallback = ...'
to return "constant" or an empty word.
The method signature changes slightly with a new optional bool
parameter:
//! Return \c "constant" instead of \c "" if the search failed
const bool constant_fallback = true
ENH: code consolidation for findInstancePath
- relocate from Time to TimePaths and provide an additional static
version that is reused in fileOperations
BUG: distributedTriSurfaceMesh:::findLocalInstance broken (#3135)
- was not checking the parent at all.
COMP: remove unused findInstancePath(const fileName&, ..) method
- leave 'readContents' method name for exposed (public) methods.
Generally not a problem, but can confuse the compiler when various
public/private versions are available with the same number of
parameters.
STYLE: adjust meshObject debug statements
- the type/name for field caching were saved as word, but ensight has
things like "tensor symm" etc, which do not parse very well as
'word'. Now save as 'string' type.
Backwards compatibility is OK since a word token will also be
readable as string etc.
- makes string reading consistent with fileName reading.
Related to #3133 to also allow compatibility when reading existing
dictionaries written with unquoted string contents.
- used defunct "processors/" directory naming, and includes are now
addressed by the file-handler anyhow.
ENH: support 'tutorials/Alltest -init'
- for copying/creating test directory without running
- in renumberMesh replace calculation of a subMesh connectivity
with calculation of the full mesh connectivity followed by subsetting
of the full adjacency matrix. This should reduce the overall number of
operations. (MR !669)
- added solidBodyMotionFunctions to topoSet which allows things like
moving cellSet selection for fvOptions etc.
COMP: relocate solidBodyMotionFunctions to meshTools
Co-authored-by: Kutalmis Bercin <>
- provide no_topology() characteristic to avoid triggering potentially
expensive mesh connectivity calculations when they are not required.
- remove/deprecate unused pointField references from the renumber
methods. These appear to have crept in from outer similarities
with decompositionMethod, but have no meaning for renumbering.
- remove/deprecate various unused aggregation renumberings since these
have been previously replaced by pre-calling calcCellCells, or
using bandCompression directly.
- make regionFaceOrder for block-wise renumbering optional and
treat as experimental (ie, default is now disabled).
The original idea was to sort the intra-region and inter-region faces
separately. However, this will mostly lead to non-upper triangular
ordering between regions, which checkMesh and others don't really like.
ENH: add timing information for various renumberMesh stages
ENH: add reset of clockTime and cpuTime increment
- simplifies section-wise timings
ENH: add globalIndex::null() and fieldTypes::processorType conveniences
- provides more central management of these characteristics
- particularly useful in these combinations:
1.
OCharStream buf;
// populate
ISpanStream is(buf.view());
// parse
2.
// read from file
ifile.getLine(str);
ISpanStream is(str);
// parse
These avoid making a copy of the character content, compared to
versions with stringstream:
OStringStream buf;
IStringStream is(buf.str());
- a few places still used listCombineReduce instead of
newer constructs (eg allGatherList) with fewer MPI calls.
- align triangulation handling of turbulentDFSEMInlet and
patchInjectionBase with meshTools/triangulatedPatch
(will ease future code refactoring)
- renumberMesh now has -dry-run, -write-maps, -no-fields,
-renumber-method, -renumber-coeffs options.
* Use -dry-run with -write-maps to visualize the before/after
effects of renumbering (creates a VTK file).
* -no-fields to renumber the mesh only.
This is useful and faster when the input fields are uniform
and the -overwrite option is specified.
* -renumber-method allows a quick means of specifying a different
default renumber method (instead of Cuthill-McKee).
The -renumber-coeffs option allows passing of dictionary content
for the method.
Examples,
// Different ways to specify reverse Cuthill-McKee
* -renumber-method RCM
* -renumber-coeffs 'reverse true;'
* -renumber-method CuthillMcKee
* -renumber-coeffs 'reverse true;'
* -renumber-coeffs 'method CuthillMcKee; reverse true;'
// Other (without dictionary coefficients)
* renumberMesh -renumber-method random
// Other (with dictionary coefficients)
renumberMesh \
-renumber-method spring \
-renumber-coeffs 'maxCo 0.1; maxIter 1000; freezeFraction 0.99;'
// Other (with additional libraries)
renumberMesh -renumber-method zoltan -lib zoltanRenumber
COMP: build zoltan renumbering to MPI-specific location
- zoltan and Sloan renumbering are now longer automatically linked to
the renumberMesh utility but must be separately loaded by a
command-line option or through a dictionary "libs" entry.
ENH: add output cellID for decomposePar -dry-run -cellDist
ENH: eliminate unnecessary duplicate communicator
- in globalMeshData previously had a comm_dup hack to avoid clashes
with deltaCoeffs calculations. However, this was largely due to a
manual implementation of reduce() that used point-to-point
communication. This has since been updated to use an MPI_Allreduce
and now an MPI_Allgather, neither of which need this hack.
- this was previously a UList instead of SubList,
but SubList supports better assignment of values
ENH: add invertOneToManyCompact
- returns a CompactListList<label> instead of labelListList, which
allows for reuse as partitioning table etc and/or slightly reduced
memory overhead
- add convenience forms for common combinations
- avoid allocation for 1:1 identity agglomerations
- support subsetting forms (avoids an intermediate fvMeshSubset)
that also return the cellMap
- refactored to eliminate code duplication between weighted and
unweighted forms
- construct Map/HashTable from key/value lists.
- invertToMap() : like invert() but returns a Map<label>,
which is useful for sparse numbering
- inplaceRenumber() : taking a Map<label> for the mapper
ENH: construct/reset CStringList for list of C-strings
- surfaceWriter TryNew() factory methods for more failure tolerant
handling
- reduce communication for sampledSurfaces.
Track non-empty surfaces as bool, only updated on change
(expire/update).
- use Pstream::listScatterValues() instead of the old hand-rolled
method.
Reduces code and since it is mostly used with primitives it
will use MPI_Scatter directly (see #3087)
COMP: fix some inconsistent masterOp return types
- can use UList signature since the routines do not resize the list
or attempt to broadcast it: useful for SubList handling.
ENH: add IPstream/OPstream send/recv static methods
- related to issue #3095. Some type of geometry is required when
loading "measured" ensight data.
ENH: emit a fallback geometry-box for foamToEnsight
- eg, with "foamToEnsight -no-internal -no-boundary" and lagrangian
- process the contents of the cloud object registry, which enables
output support for calculated values such as Reynolds, Weber numbers
etc.
ENH: select any/all clouds by default instead of defaultCloud
- adds robustness
- the old Pstream::scatter routines (which were largely a misnomer)
have been superseded by various broadcast routines, but were left in
the code with #ifndef/#ifdef Foam_Pstream_scatter_nobroadcast
guards. Now noisily deprecate them, and remove the old manual tree
communication in favour of MPI broadcast and/or
serialize/de-serialize with wrapped Pstream::broadcast
- consolidate various gather methods to include the communication
structure directly. No functional change, but reduces the number of
methods.
ENH: add parallel guard to UPstream::whichCommunication() method
- returns List::null() as the schedule for non-parallel instead
of an inappropriate linear or tree schedule
ENH: Pstream::listGatherValues, Pstream::listScatterValues
- like the existing UPstream versions but supporting non-contiguous
- range(proci) instead of localStart(proci), localSize(proci) combination.
* does the same thing, can be used directly with various other
routines for slicing etc.
Eg,
Foam::identity(globalNumbering.range(myProci))
- globalIndex::calcOffset() instead of constructing a globalIndex and
taking the localStart(). Avoids intermediate resizing and storing of
an offsets table (which is then discarded) as well as the subsequent
lookup into that table
- creates an IOobject at the current time instance (timeName) with
NO_READ/NO_WRITE/NO_REGISTER characteristics.
This generalises and replaces the Cloud fieldIOobject() to simplify
some common use.
// Shorter version (new):
volScalarField fld
(
mesh.newIOobject(name),
...
);
// Longer version:
volScalarField fld
(
IOobject
(
name,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
IOobject::NO_REGISTER
),
...
);
- can be useful when using memory-based streams for buffering,
in which case the name() can be used to specify the filesystem
location instead of the default stream names ("input", "output").
- shape optimisation: SQP failed due to wrong divScheme for the adjoint
equations
- shape optimisation: tutorials designed to show the impact of different flow
conditions were actually using the same U
- topology optimisation: tutorials designed to show the impact of the
flow rate distribution were actually using the same target
fractions
- topology optimisation: updated old fvSolution syntax
- shape optimisation: SQP failed due to wrong divScheme for the adjoint
equations
- shape optimisation: tutorials designed to show the impact of different flow
conditions were actually using the same U
- topology optimisation: tutorials designed to show the impact of the
flow rate distribution were actually using the same target
fractions
- topology optimisation: updated old fvSolution syntax
- had max(std::streamsize, label) but this does not resolve properly
on OSX, so write out in long form instead.
The similar logic in DynamicList is okay since there it compares
max(label, label) instead
2023-12-22 15:10:49 +01:00
13794 changed files with 204969 additions and 75901 deletions
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.