- adjointOptimisation : missing link to fileFormats
- snappyHexMesh : add fvMotionSolvers link (#3058)
STYLE: remove remnant -DFULLDEBUG hints
- now more easily covered with wmake -debug ...
- the fileHandler changes included setting cacheLevel(0) to avoid
blocking with redistributePar. However, this meant if clouds
were not uniformly present on all ranks the fileHandler would follow
different code paths and lead to blocking.
Now switch to distributed mode for the lagrangian operations within
redistributePar based on the cacheLevel information.
FIX: avoid triggering a false processor check in argList
- when redistributing to few ranks
Parts of the adjoint optimisation library were re-designed to generalise
the way sensitivity derivatives (SDs) are computed and to allow easier
extension to primal problems other than the ones governed by
incompressible flows. In specific:
- the adjoint solver now holds virtual functions returning the part of
SDs that depends only on the primal and the adjoint fields.
- a new class named designVariables was introduced which, apart from
defining the design variables of the optimisation problem and
providing hooks for updating them in an optimisation loop, provides
the part of the SDs that affects directly the flow residuals (e.g.
geometric variations in shape optimisation, derivatives of source
terms in topology optimisation, etc). The final assembly of the SDs
happens here, with the updated sensitivity class acting as an
intermediate.
With the new structure, when the primal problem changes (for instance,
passive scalars are included), the same design variables and sensitivity
classes can be re-used for all physics, with additional contributions to
the SDs being limited (and contained) to the new adjoint solver to be
implemented. The old code structure would require new SD classes for
each additional primal problem.
As a side-effect, setting up a case has arguably become a bit easier and
more intuitive.
Additional changes include:
---------------------------
- Changes in the formulation and computation of shape sensitivity derivatives
using the E-SI approach. The latter is now derived directly from the
FI approach, with proper discretization for the terms and boundary
conditions that emerge from applying the Gauss divergence theorem used
to transition from FI to E-SI. When E-SI and FI are based on the same
Laplace grid displacement model, they are now numerically equivalent
(the previous formulation proved the theoretical equivalence of the
two approaches but numerical results could differ, depending on the
case).
- Sensitivity maps at faces are now computed based (and are deriving
from) sensitivity maps at points, with a constistent point-to-face
interpolation (requires the differentiation of volPointInterpolation).
- The objective class now allocates only the member pointers that
correspond to the non-zero derivatives of the objective w.r.t. the
flow and geometric quantities, leading to a reduced memory footprint.
Additionally, contributions from volume-based objectives to the
adjoint equations have been re-worked, removing the need for
objectiveManager to be virtual.
- In constrained optimisation, an adjoint solver needs to be present for
each constraint function. For geometric constraints though, no adjoint
equations need to solved. This is now accounted for through the null
adjoint solver and the geometric objectives which do not allocate
adjoint fields for this kind of constraints, reducing memory
requirements and file clutter.
- Refactoring of the updateMethod to collaborate with the new
designVariables. Additionally, all updateMethods can now read and
write restart data in binary, facilitating exact continuation.
Furthermore, code shared by various quasi-Newton methods (BFGS, DBFGS,
LBFGS, SR1) has been organised in the namesake class. Over and above,
an SQP variant capable of tackling inequality constraints has been
added (ISQP, with I indicating that the QP problem in the presence of
inequality constraints is solved through an interior point method).
Inequality constraints can be one-sided (constraint < upper-value)
or double-sided (lower-value < constraint < upper-value).
- Bounds can now be defined for the design variables.
For volumetricBSplines in specific, these can be computed as the
mid-points of the control points and their neighbouring ones. This
usually leads to better-defined optimisation problems and reduces the
chances of an invalid mesh during optimisation.
- Convergence criteria can now be defined for the optimisation loop
which will stop if the relative objective function reduction over
the last objective value is lower than a given threshold and
constraints are satisfied within a give tolerance. If no criteria are
defined, the optimisation will run for the max. given number of cycles
provided in controlDict.
- Added a new grid displacement method based on the p-Laplacian
equation, which seems to outperform other PDE-based approaches.
TUT: updated the shape optimisation tutorials and added a new one
showcasing the use of double-sided constraints, ISQP, applying
no-overlapping constraints to volumetric B-Splines control points
and defining convergence criteria for the optimisation loop.
- enhance POSIX compliance
- apply distinct colours and dash type for each line
- standardize the frame size to 1200x627
- dynamically replace the title with <function-object-name>/<file-name>
- address underscore character issues
- introduce legend components for tensors
- resolve a bug caused by parentheses in tensor files
BUG: particleTrackProperties: correct the typo (fixes#3050)
- on large memory systems (eg, 6TB) the process information
exceeds an 'int' range, so adjust parsing of the /proc/..
to use int64
ENH: update/modernize OSspecific system information
ENH: minor update of profiling code
- std::string, noexcept, lazier evaluations
STYLE: use direct call of memInfo
- use Foam::zero as a dispatch tag
FIX: return moleculeCloud::constProps() List by reference not copy
STYLE: range-for when iterating cloud parcels
STYLE: more consistent typedefs / declarations for Clouds
- better code style and seems to avoid triggering a gcc warning about
possibly uninitialized values
COMP: JSONformatter writeEntry missing a return value
STYLE: accept 'json' for checkMesh write format
- consistent with caseInfo functionObject
- simplifies handling.
* enables unprotecting to avoid accidentally cloning.
* removes the need for dedicated constructor or factory forms.
* simplfies DimensionedField and GeometricField New factory methods
- update objectRegistry management method (internal use)
old: bool cacheTemporaryObject(...)
new: bool is_cacheTemporaryObject(...)
to clarify that it is a query, not a request for caching etc.
- replace typeGlobal() global function with is_globalIOobject
traits for more consistent and easier overriding.
- relocate typeFilePath() global function as a member of IOobject
for consistency with typeHeaderOk.
BUG: faSchemes, fvSchemes not marked as global file types
- caused issues with collated
- static version of polyMesh::meshDir(), which takes a region name
polyMesh::meshDir(regionName)
vs
polyMesh::regionName(regionName)/polyMesh::meshSubDir
STYLE: use polyMesh::regionName(..) instead of comparing to defaultRegion
STYLE: use getOrDefault when retrieving various -region options
FIX: polyMesh::dbDir() now checks registry name, not full path (#3033)
Added -writeChecks <format> option
- writes computed mesh metrics to file in using <format>
- currently supported formats are OpenFOAM dictionary and JSON
- when reading, detect all clouds on all processors and uses this when
reading fields. Similarly, when writing it uses writeOnProc to skip
clouds that are empty on any particular processor.
Co-authored-by: Mark Olesen <>
- provide a globalIndex::calcOffsets() taking an indirect list, which
enables convenient offsets calculation from a variety of inputs.
- new CompactListList unpack variant: copy_unpack()
The copy_unpack() works somewhat like std::copy() in that it writes
the generated sublists to iterator positions, which makes this
type of code possible:
CompactListList<label> compact = ...;
DynamicList<face> extracted;
compact.copy_unpack<face>
(
std::back_inserter(extracted),
labelRange(4, 10)
);
-and-
const label nOldFaces = allFaces.size();
allFaces.resize(allFaces + nNewFaces);
auto iter = allFaces.begin(nOldFaces);
iter = compact.copy_unpack<face>(iter, /* selection 1 */);
...
iter = compact.copy_unpack<face>(iter, /* selection 2 */);
ENH: globalIndex resize()
- can be used to shrink or grow the offsets table.
Any extension of the offsets table corresponds to 'slots'
with 0 local size.
- allows construction of string tokens holding character content.
For example, data that has been serialized and buffered and that
now needs to be written or sent to another process.
- avoids clutter of argList::envGlobalPath() ...
ENH: allow temporary overwriting of output writeFormat
- allows switching for particular output routines
COMP: explicitly use TimePaths methods with Time
- this simplifies any overloading done at a later stage
- this makes it easier to split creation into a two-stage process
as required
- extend handling for polyBoundaryMeshEntries, faBoundaryMeshEntries
with more functionality. Ensure that these are never registered.
ENH: addition writeEntry methods for polyBoundaryMesh
- simplifies streaming and collating into other files
ENH: polyMesh rereading - update owner/neighbour header information
- this avoids accidentally reading the "cells" file if the mesh has
been created with NO_READ and then updated
STYLE: less vertical space when outputting empty PtrList
- combined most of the unweighted and weighted decomposition routines
such that an empty weight field is treated as uniform weighting.
This allows default parameters and cuts down on the number of
decompose methods.
- for topology-driven decomposition, it is now possible to pass in the
owner/neighbour connectivity as a CompactListList directly instead
of first creating a labelListList (which was internally repacked into
a CompactListList in many cases).
However, multiLevelDecomp still uses unpacking (to avoid a larger
reworking of code).
- support direct creation of some methods (eg, random, scotch etc)
without a dictionary
- fix incorrect neighbour face weighting (fixes#3019)
ENH: relocate calcCellCells from decompositionMethod to globalMeshData
- makes it more universally available
- CompactListList::size() corresponds to the number of sub-lists
whereas globalIndex::size() corresponds to the totalSize().
This difference can lead to potential coding errors when switching
between pure addressing (eg globalIndex) and addressing with content
(eg, CompactListList).
Within the source tree, there are no longer any occurances of
globalIndex::size() but it is nonetheless unsafe to change its
meaning now. Instead provide a commonly named length() method that
corresponds to the natural length: ie, the number of offsets minus 1
(with guards).
- add CompactListList::writeMatrix for writing the compact contents
in an unpacked form (eg, for debugging) without actually needing to
unpack into storage.
- provide globalIndex::whichProcID() two-parameter version
with myProcNo as the first argument.
Symmetric with isLocal etc, useful when using a communicator
that is not worldComm.
- usually only need big/little defines (which are now in the Fwd)
and rarely need byte-swapping.
Provide endian.H compatibility include, but foamEndianFwd.H or
foamEndian.H to avoid potential name clashes.
- The pTraits_cmptType returns the data type of 'cmptType' (for
arithmetic and VectorSpace types) or is simply a pass-through.
This can be combined with the pTraits_nComponents for casting.
For example,
function
(
reinterpret_cast<pTraits_cmptType<Type>::type*>(buf.data()),
(buf.size()/pTraits_nComponents<Type>::value)
);
ENH: extend Foam::identityOp so support array indexing (pass-through)
- single() method : simply tests if the globalIndex has nProcs == 1,
which is typically from a gatherNone invocation.
For example,
globalIndex gi;
if (...) gi.reset(localSize);
else gi.reset(globalIndex::gatherNone{}, localSize);
// later...
const label begin = (gi.single() ? 0 : gi.localStart());
const label count = (gi.single() ? gi.totalSize() : gi.localSize());
- add front() and back() methods to return the begin/end ranges,
and begin_value(), end_value() - as per labelRange.
- make more methods noexcept
- calcOffset(), calcRange() helper functions to determine
the processor-local of a numbering range without the overhead of
creating a list of offsets.
For example,
label myOffset = globalIndex::calcOffset(mesh.nCells());
labelRange mySlice = globalIndex::calcRange(mesh.nCells());
- add globalIndex localEnd() as per CompactListList method
STYLE: align looping constructs in CompactListList with List
- make more methods noexcept
- becoming more frequently used and there is no ambiguity in calling
parameters either - identity(label) vs identity(labelUList&).
Provide both int32 and int64 versions.
- now mark methods with strict deprecation, to make it easier to find
their use but without adding extra compilation noise for others
ENH: minor update for Enum methods and iterator
- add warnOnly (failsafe) option for readEntry and getOrDefault
- add good() method to Enum iterator (simliar to HashTable)
- replace unused/fragile Enum find() methods with iterator return
that can be used more generally
- explicit use of UPstream::worldComm in globalIndex methods
for more clarity
- adjust method declaration ordering:
de-emphasize the processor-local convenience methods
- consistent use of leading tag dispatch,
remove unused enum-based dispatch tag
- add begin()/cbegin() with offset (as per List containers)
BUG: missing use of communicator in globalIndex gatherNonLocal
- does not affect any existing code (which all use worldComm anyhow)
- support std::string_view (c++17) or span view (older c++) of stream
buffer contents. This simplifies formatting + reparsing.
Example,
OCharStream os;
os << ...;
ISpanStream is(os.view());
is >> ...;
- additional release() method for ICharStream, OCharStream
that returns the contents as a DynamicList<char> and resets the stream.
- provide a str() method for API compatibility with older
std::ostringstream etc.
- change write(const string&) to write(const std::string&).
This allows output of std::string without an intermediate copy.
- additional writeQuoted method to handle range of char data:
writeQuoted(const char* str, std::streamsize len, bool)
This helps with supporting string_view and span<char>
- add operator<< for stdFoam::span<char> and std::string_view (c++17)
- avoid duplicate code in OBJstream
STYLE: add override keyword for IO stream methods
- changes the addressed list size without affecting list allocation.
Can be useful for the following type of coding pattern:
- pre-allocate a List with some max content length
- populate with some content (likely not the entire pre-allocated size)
- truncate the list to the length of valid content
- process the List
- discard the List
Since the List is being discarded, using resize_unsafe() instead of
resize() avoids an additional allocation with the new size and
copying/moving of the elements.
This programming pattern can also be used when the List is being
returned from a subroutine, and carrying about a bit of unused memory
is less important than avoiding reallocation + copy/move.
If used improperly, it can obviously result in addressing into
unmanaged memory regions (ie, 'unsafe').
- shrink_to_fit()
corresponds to std::vector naming.
For DynamicList it is a *binding* request.
- shrink_unsafe()
simply adjusts the capacity() to match the
current size() without forcing a re-allocation.
Useful when collapsing to a non-dynamic list to avoid reallocation
and copying contents. The memory cleanup will still occur properly
at a later stage.
- DynamicList::swap(List&)
simple recovery of content into a non-dynamic List that also
ensures that the capacity is correctly updated.
STYLE: promote List::capacity() to public visibility (like std::vector)
STYLE: remove unused expandStorage() method
- simply a wrapper for resize(capacity())
- support UList shallowCopy with pointer/size
(eg, for slicing into or from span)
ENH: add SubList::reset() functionality
- allows modification of a SubList after construction.
Previously a SubList had an immutable location after construction
and there was no way to shift or change its location.
BUG: missed special handling for DynamicList<char>::readList (fixes#2974)
- equivalent to List<char>::readList, in which the stream is
temporarily toggled from ASCII to BINARY when reading in a List of
char data.
This specialization was missed when DynamicList<T>::readList() was
fully implemented.
- defines values for EMPTY, UNIFORM, NONUNIFORM and MIXED
that allow bitwise OR reduction and provide an algorithm
for calculating uniformity
ENH: consolidate more efficient uniformity checks in PackedList
ENH: improve linebreak handling when outputting small matrices
- use ignore instead of seekg/tellg to swallow input (robuster)
- check for bad gcount() values
- wrap Foam::fileSize() compressed/uncompressed handling into IFstream.
- improve handling of compressed files in masterUncollatedFileOperation.
Previously read into a string via stream iterators.
Now read chunk-wise into a List of char for fewer reallocations.
- soft renames (ie, old names still available via typedefs) for more
reasonable names and more coverage with std stream variants.
The old names could be a bit cryptic.
For example, uiliststream (== an unallocated/external list storage),
which is written as std::ispanstream for C++23.
Could similarly argue that IListStream is better named as
ICharStream, since it is an input stream of characters and the
internal storage mechanism (List or something else) is mostly
irrelevant.
Extending the coverage to include all std stream variants, and
simply rewrap them for OpenFOAM IOstream types. This simplifies the
inheritance patterns and allows reuse of icharstream/ocharstream as
a drop-in replace for istringstream/ostringstream in other wrappers.
Classes:
* icharstream / ICharStream [old: none / IListStream]
* ocharstream / OCharStream [old: none / OListStream]
* ispanstream / ISpanStream [old: uiliststream / UIListStream]
* ospanstream / OSpanStream [old: none / UOListStream]
Possible new uses : read file contents into a buffer, broadcast
buffer contents to other ranks and then transfer into an icharstream
to be read from. This avoid the multiple intermediate copies that
would be associated when using an istringstream.
- Use size doubling instead of block-wise incremental for ocharstream
(OCharStream). This corresponds to the sizing behaviour as per
std::stringstream (according to gcc-11 includes)
STYLE: drop Foam_IOstream_extras constructors for memory streams
- transitional/legacy constructors but not used in any code
- totalSize() returns retrieve the linear (total) size
(naming as per globalIndex)
- operator[] retrieves the referenced value (linear indexing)
- labels() returns a flattened labelList (as per labelRange itself)
- broadcasts list contiguous content as a two-step process:
1. broadcast the size, and resize for receiver list
2. broadcast contiguous contents (if non-empty)
This avoids serialization/de-serialization memory overhead but at
the expense of an additional broadcast call.
The trade-off of the extra broadcast of the size will be less
important than avoiding a memory peak for large contiguous mesh data.
REVERT: unstable MPI_Mprobe/MPI_Mrecv on intelmpi + PMI-2 (#2796)
- partial revert of commit c6f528588b, for NBX implementation.
Not yet flagged as causing errors here, but eliminated for
consistency.
- simplifies internal handling (like a fileName) and allows the
dictionary name to be used with unambiguous addressing.
The previous dot (.) separator is ambiguous (ie, as dictionary
separator or as part of a keyword).
ENH: foamDictionary report -add/-set to stderr
- selected with '+strict' in WM_COMPILE_CONTROL or 'wmake -strict', it
enables the FOAM_DEPRECATED_STRICT() macro, which can be used to
mark methods that are implicitly deprecated, but are not yet marked
as full deprecated (eg, API modification is too recent, generates
too many warnings). Can be considered a developer option.
- eliminate ClassName in favour of simple debug
- include Apple-specific FPE handling after local definition
to allow for more redefinitions
COMP: remove stray <csignal> includes
- naming like std::map::try_emplace(), it behaves like emplace_set()
if there is no element at the given location otherwise a no-op
ENH: reuse existing HashPtrTable 'slot' when setting pointers
- avoids extra HashTable operations
- the construction of compound tokens is now split into two stages:
- default construct
- read contents
This permits a larger variety of handling.
- the new token::readCompoundToken(..) method allows for simpler
more failsafe invocations.
- forward resize(), read() methods for compound tokens to support
separate read and population.
Top-level refCompoundToken() method for modify access.
ENH: split off a private readCompoundToken() method within ISstream
- this allows overloading and alternative tokenisation handling for
derived classes
- simplifies iteration of ITstream using nRemainingTokens() and skip()
methods or directly as a list of tokens.
The currentToken() method returns const or non-const access to
the token at the current tokenIndex.
The peekToken(label) method provides failsafe read access to tokens
at given locations.
ENH: add primitiveEntry construct with moving a single token
- drop unnecessary Foam::Swap specializations when MoveConstructible
and MoveAssignable already apply. The explicit redirect to swap
member functions was needed before proper move semantics where
added.
Removed specializations: autoPtr, refPtr, tmp, UList.
Retained specialization: DynamicList, FixedList.
Special handling for DynamicList is only to accommodate dissimilar
sizing template parameters (which probably doesn't occur in
practice).
Special handling for FixedList to apply element-wise swapping.
- use std::swap for primitives. No need to mask with Foam::Swap wrapper
- fully implement DynamicList::readList() instead of simply
redirecting to List::readList(). This also benefits DynamicField.
Leverage DynamicList reading to simplify and improve CircularBuffer
reading.
- bracket lists are now read chunk-wise instead of using a
singly-linked list. For integral and vector-space types
(eg, scalar, vector, etc) this avoids intermediate allocations
for each element.
ENH: add CircularBuffer emplace_front/emplace_back
STYLE: isolate to-be-deprecated construct/assign forms
- still have construct/assign FixedList from a C-array.
This is not really needed, can use std::initializer_list
- still have construct/assign List from SLList.
Prefer to avoid these in the future.
DEFEATURE: remove construct/assign FixedList from SLList
- never used
DEFEATURE: remove move construct/assign List from SLList
- now unused. Retain copy construct/assign from SLList for transition
purposes.
- is_vectorspace :
test existence and non-zero value of the Type 'rank' static variable
- pTraits_rank :
value of 'rank' static variable (if it exists), 0 otherwise
- pTraits_nComponents :
value of 'nComponents' static variable (if it exists), 1 otherwise
- pTraits_has_zero :
test for pTraits<T>::zero member, which probably means that it also
has one, min, max members as well
Note that these traits are usable with any classes. For example,
- is_vectorspace<std::string>::value ==> false
- pTraits_nComponents<std::string>::value ==> 1
- pTraits<std::string>::nComponents ==> fails to compile
Thus also allows testing pTraits_rank<...>::value with items
for which pTraits<...>::rank fails to compile.
Eg, cyclicAMIPolyPatch::interpolate called by FaceCellWave with a
wallPoint.
pTraits<wallPoint>::rank ==> fails to compile
is_vectorspace<wallPoint>::value ==> false
GIT: relocate ListLoopM.H to src/OpenFOAM/fields/Fields (future isolation)
- in most cases a parallel-consistent order is required.
Even when the order is not important, it will generally require
fewer allocations to create a UPtrList of entries instead of a
HashTable or even a wordList.