- 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();
}
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.