- the behaviour of std::rename with overwriting an existing file is
implementation dependent:
- POSIX: it overwrites.
- Windows: it does not overwrite.
- for Windows need to use the ::MoveFileEx() routine for overwriting.
More investigation is needed for proper handling of very long names.
- unfriend HashSet, HashTable IO operators
- global min(), max(), minMax() functions taking a labelHashSet and an
optional limit. For example,
labelHashSet set = ...;
Info<< "min is " << min(set) << nl;
Info<< "max (non-negative) " << max(set, 0) << nl;
- make HashTable iterator '->' dereferencing more consistent by also
supporting non-pointer types as well.
- read HashTable values in-situ to avoid copying
ENH: define addition/subtraction operations for scalar and complex
- required since construct complex from scalar is explicit
- additional tests in Test-complex
- forces c++DBUG='-DFULLDEBUG -g -O0' for the compilation, to allow
localized debugging during development without file editing and
while retaining the WM_COMPILE_OPTION (eg, Opt)
Note that switching between 'wmake' and 'wmake -debug' will not
cause existing targets to be rebuilt. As before, these are driven by
the dependencies. An intermediate wclean may thus be required.
- generalize identity matrix constructors for non-scalar types
- add constructors using labelPair for the row/column sizing information.
For a SquareMatrix, this provides an unambiguous parameter resolution.
- reuse assignment operators
STYLE: adjust matrix comments
- add iterators, begin/end, empty() methods for STL behaviour.
Use standard algorithms where possible
* std::fill, std::copy
* std::min_element, std::max_element
- access methods consistent with other OpenFOAM containers:
* data(), cdata(), uniform()
- Use ListPolicy to impose output line breaks
- Can recover matrix storage for re-use elsewhere.
For example, to populate values with 2D i-j addressing and later
release it as flat linear storage.
- construct/assign moveable
- added minMax() function for Matrix
- additional inplace +=, -=, *=, /= operations
- add named methods at() and rowData() to Matrix.
Allows a better distinction between linear and row-based addressing
- low-level matrix solve on List/UList instead of Field
- can be used to check the validity of input values.
Example:
dict.getCheck<label>("nIters", greaterOp1<label>(0));
dict.getCheck<scalar>("relax", scalarMinMax::zero_one());
- use 'get' prefix for more regular dictionary methods.
Eg, getOrDefault() as alternative to lookupOrDefault()
- additional ops for convenient construction of predicates
ENH: make dictionary writeOptionalEntries integer
- allow triggering of Fatal if default values are used
ENH: additional scalarRange static methods: ge0, gt0, zero_one
- use GREAT instead of VGREAT for internal placeholders
- additional MinMax static methods: gt, le
- adjust naming of quaternion 'rotationSequence' to be 'eulerOrder'
to reflect its purpose.
- provide rotation matrices directly for these rotation orders in
coordinateRotations::euler for case in which the rotation tensor
is required but not a quaternion.
- support move insert/set and emplace insertion.
These adjustments can be used for improved memory efficiency, and
allow hash tables of non-copyable objects (eg, std::unique_ptr).
- extend special HashTable output treatment to include pointer-like
objects such as autoPtr and unique_ptr.
ENH: HashTable::at() method with checking. Fatal if entry does not exist.
All remote contributions to interpolation stencils now
get added as 'processor' type lduInterfaces. This guarantees
a consistent matrix, e.g. initial residual is normalised to 1.
Second change is the normalisation of the interpolation discretisation
which uses the diagonal from the unmodified equation. This helps
GAMG.
- previously would have different SHA1 depending on whether the
string was a C-string, a C++-string or if the SHA1 was calculated
directly or via the OSHA1stream.
- SHA1("string")
- OSHA1stream << "string";
- OSHA1stream << string("string");
By avoiding string quoting on output, they now all deliver the same
result. This also means that the following will no longer change the SHA1
content, since it does not add anything:
osha<< string() << string() << string() << string();
This would have previously add a pair of double quotes each time!
- Eg, with surface writers now in surfMesh, there are fewer libraries
depending on conversion and sampling.
COMP: regularize linkage ordering and avoid some implicit linkage (#1238)
- extracts values from the arch "LSB;label=32;scalar=64" header entry
to provision for managing dissimilar primitive sizes.
Compensate for the additional IOobject members by narrowing the types
for the (objectState, readOption, writeOption) enumerations
- use an IndirectListBase class for various indirect list types.
- new SortList type
In some places the SortList can be used as a lightweight alternative
to SortableList to have the convenience of bundling data and sort
indices together, but while operating on existing data lists.
In other situations, it can be useful as an alternative to
sortedOrder. For example,
pointField points = ...;
labelList order;
sortedOrder(points, order);
forAll(order, i)
{
points[order[i]] = ...;
}
Can be replaced with the following (with the same memory overhead)
pointField points = ...;
SortList<point> sortedPoints(points);
for (point& pt : sortedPoints)
{
pt = ...;
}
- new SliceList type (#1220), which can be used for stride-based
addressing into existing lists
- this is somewhat like labelRange, but with a stride.
Can be used to define slices (of lists, fields, ..) or as a range specifier
for a for-loop. For example,
for (label i : sliceRange(0, 10, 3))
{
...
}
- this adds support for various STL operations including
* sorting, filling, find min/max element etc.
* for-range iteration
STYLE: use constexpr for VectorSpace rank
- having whitespace in fileName can be somewhat fragile since it means
that the fileName components do not necessarily correspond to a
'Foam::word'. But in many cases it will work provided that spaces
are not present in the final portion of the simulation directory
itself.
InfoSwitches
{
// Allow space character in fileName (use with caution)
allowSpaceInFileName 0;
}
- now use doClean=true as default for fileName::validate(). Was false.
Unlike fileName::clean() this requires no internal string rewrite
since the characters are being copied. Also handle any path
separator transformations (ie, backslash => forward slash) at the
same time. This makes it resemble the std::filesystem a bit more.
- operators are still incomplete, as are dimensioned fields,
field-fields etc.
- split complexFields into separate complexField, complexVectorField files
- add construction from and conversion to std::complex, which allows
easier wrapping of functions
- add Foam:: functions for complex versions of sin, cos, ...
- was historically defined as (1 1), but it is more consistent with
the concept of one to have a real component only.
Now defined as (1 0): 1+0i
STYLE: remove obscure '!' operator for complex conjugate
- either use the member function or the '~' operator
- These are not defined in the C++ standard for cmath, so allow for
compilation without them. Will need to provide replacements in the
future or rework.
- new regExpCxx wrapper for C++11 regex support with drop-in
compatibility with existing code.
- regExpPosix (was regExp), for future phase out in favour of regExpCxx.
- The regExp header will continue to be used for defining an
appropriate typedef corresponding to the preferred implementation.
- PtrDynList support for move append list:
can be used to concatenate pointer lists into a single one
- include resize in PtrDynList squeezeNull as being a natural
combination
- support sorting operations for pointer lists (PtrListOps)
- remove writeGeometry() in favour of write() and make it pure virtual
so that all writers must explicitly deal with it.
- establish proxy extension at construction time and treated as an
invariant thereafter. This avoids potentially surprising changes in
behaviour when writing.
- this is a simple container for fields with i-j-k addressing.
It does not support field operations directly, but is primarily
intended to be used when assembling field information with i-j-k
logic. After assembly, the field can be transferred to a regular
field for normal operations. Eg,
IjkField<scalar> assemble({15, 16, 200});
// .. fill in i-j-k fields
Field<scalar> final(std::move(assemble));
assemble.clear(); // be pedantic
...
- While a rectilinear mesh can be created with blockMesh, not every mesh
created with blockMesh will satisfy the requirements for being a
rectilinear mesh.
This alternative to blockMesh uses a single block that is aligned
with the xy-z directions and specifications of the control points,
mesh divisions and expansion ratios. For example,
x
{
points ( -13.28 -0.10 6.0 19.19 );
nCells ( 10 12 10 );
ratios ( 0.2 1 5 );
}
y { ... }
z { ... }
With only one block, the boundary patch definition is simple and the
canonical face number is used directly. For example,
inlet
{
type patch;
faces ( 0 );
}
outlet
{
type patch;
faces ( 1 );
}
sides
{
type patch;
faces ( 2 3 );
}
...
- After a mesh is defined, it is trivial to retrieve mesh-related
information such as cell-volume, cell-centres for any i-j-k location
without an actual polyMesh.
STYLE: remove -noFunctionObjects from blockMesh
- no time loop, so function objects cannot be triggered anyhow.
- PtrList::release() method.
Similar to autoPtr and unique_ptr and clearer in purpose than
using set(i,nullptr)
- Construct from List of pointers, taking ownership.
Useful when upgrading code. Eg,
List<polyPatch*> oldList = ...;
PtrList<polyPatch> newList(oldList);
...
BUG: incorrect resizing method names (PtrDynList) in previously unused code
- previously just removed duplicate literals, but now remove any
duplicates.
- Replace previous wordHashSet implementation with a linear search
instead. The lists are normally fairly small and mostly just have
unique entries anyhow. This reduces the overall overhead.
- previously had a single pointer/value zeros (8 bytes), this meant
that the reinterpret cast to a List would yield a reference that
could be unsafe under certain conditions.
Eg,
const labelList& myList = labelList::null();
Info<< myList.size() << nl; // OK since size is the first parameter
SubList<label>(myList, 0); // Unsafe
The SubList usage is unsafe since it passes in pointer and size into
the underlying UList. However, the pointer from the labelList::null()
will be whatever happens to be around in memory immediately after the
NullObject singleton. This is mostly not a problem if the List size
is always checked, but does mean that the data pointer is rather
dubious.
- Increase the size of the nullObject singleton to 32 bytes of zeros
to ensure that most reinterpret casting will not result in objects
that reference arbitrary memory.
The 32-byte data size is rather arbitrary, but covers most basic
containers.
- Global functions are unary or combining binary functions, which are
defined in MinMax.H (MinMaxOps.H).
There are also global reduction functions (gMinMax, gMinMaxMag)
as well as supporting 'Op' classes:
- minMaxOp, minMaxEqOp, minMaxMagOp, minMaxMagEqOp
Since the result of the functions represents a content reduction
into a single MinMax<T> value (a min/max pair), field operations
returning a field simply do not make sense.
- Implemented for lists, fields, field-fields, DimensionedField,
GeometricField (parallel reducing, with boundaries).
- Since the minMax evaluates during its operation, this makes it more
efficient for cases where both min/max values are required since it
avoids looping twice through the data.
* Changed GeometricField writeMinMax accordingly.
ENH: clip as field function
- clipping provides a more efficient, single-pass operation to apply
lower/upper limits on single or multiple values.
Examples,
scalarMinMax limiter(0, 1);
limiter.clip(value)
-> returns a const-ref to the value if within the range, or else
returns the appropriate lower/upper limit
limiter.inplaceClip(value)
-> Modifies the value if necessary to be within lower/upper limit
Function calls
clip(value, limiter)
-> returns a copy after applying lower/upper limit
clip(values, limiter)
-> returns a tmp<Field> of clipped values
- in some circumstances we need to pass a bool value upwards to the
caller and know if the true/false value was set based on real input
or is a default value.
Eg, in the object::read() we might normally have
enabled_(dict.readIfPresent(key, true));
but would lose information about why the value is true/false.
We can change that by using
enabled_(dict.readIfPresent<Switch>(key, Switch::DEFAULT_ON));
After which we can use this information is testing.
if
(
child.enabled().nonDefault()
? child.enabled()
: parent.enabled()
)
{ ... }
And thus enable output if the parent requested it explicitly or by
default and it has not been explicitly disabled in the child.
No difference when testing as a bool and the text representation
of DEFAULT_ON / DEFAULT_OFF will simply be "true" / "false".
ENH: add construction of Switch from dictionary (similar to Enum)
- introduced a ListPolicy details to make the transition between
a short list (space separated) and a long list (newline separated)
more configurable.
We suppress line breaks for commonly used types that often have
short content: (word, wordRes, keyType).
- a valid() method (same as !empty() call) for consistency with other
containers and data types
- a centre() method (same as midpoint() method) for consistency with
other OpenFOAM geometric entities
- provide a lookupOrDefault constructor form, since this is a fairly
commonly used requirement and simplifies the calling sequence.
Before
dimensionedScalar rhoMax
(
dimensionedScalar::lookupOrDefault
(
"rhoMax",
pimple.dict(),
dimDensity,
GREAT
)
);
After
dimensionedScalar rhoMax("rhoMax", dimDensity, GREAT, pimple.dict());
- read, readIfPresent methods with alternative lookup names.
- Mark the Istream related constructors with compile-time deprecated
warnings.
BUG: read, readIfPresent methods not handling optional dimensions (#1148)
- can be used as a more natural test on the iterator.
For example, with
HashTable<..> table;
auto iter = table.find(...);
Following are now all equivalent:
1. if (iter != table.end()) ...
2. if (iter.found()) ...
3. if (iter) ...
- similar to autoPtr and unique_ptr. Returns the pointer value without
any checks. This provides a simple way for use to use either
an autoPtr or a tmp for local memory management without accidentally
stealing the pointer.
Eg,
volVectorField* ptr;
tmp<volVectorField> tempField;
if (someField.valid())
{
ptr = someField.get();
}
else
{
tempField.reset(new volVectorField(....));
ptr = tmpField.get();
}
const volVectorField& withField = *ptr;
STYLE: make more tmp methods noexcept