- end_value() corresponds to the infrequently used after() method, but
with naming that corresponds better to iterator naming conventions.
Eg,
List<Type> list = ...;
labelRange range = ...;
std::transform
(
(list.data() + range.begin_value()),
(list.data() + range.end_value()),
outIter,
op
);
- promote min()/max() methods from labelRange to IntRange base class
STYLE: change timeSelector from "is-a" to "has-a" scalarRanges.
- resets min/max to be identical to the specified value,
which can be more convenient (and slightly more efficient) than doing
a full reset followed by add()
- additional MinMax intersects() query, which works like overlaps()
but with exclusive checks at the ends
- provide MinMax::operator&=() to replace (unused) intersect() method
ENH: single/double value reset method for boundBox
- boundBox::operator&=() to replace (rarely used) intersect() method.
Deprecate boundBox::intersect() to avoid confusion with various
intersects() method
COMP: provide triangleFwd.H
- background: for some application it can be useful to have fully
sorted points. i.e., sorted by x, followed by y, followed by z.
The default VectorSpace 'operator<' compares *all*
components. This is seen by the following comparisons
1. a = (-2.2 -3.3 -4.4)
b = (-1.1 -2.2 3.3)
(a < b) : True
Each 'a' component is less than each 'b' component
2. a = (-2.2 -3.3 -4.4)
b = (-2.2 3.3 4.4)
(a < b) : False
The a.x() is not less than b.x()
The static definitions 'less_xyz', 'less_yzx', 'less_zxy'
instead use comparison of the next components as tie breakers
(like a lexicographic sort).
- same type of definition that Pair and Tuple2 use.
a = (-2.2 -3.3 -4.4)
b = (-2.2 3.3 4.4)
vector::less_xyz(a, b) : True
The a.x() == b.x(), but a.y() < b.y()
They can be used directly as comparators:
pointField points = ...;
std::sort(points.begin(), points.end(), vector::less_zxy);
ENH: make VectorSpace named access methods noexcept.
Since the addressing range is restricted to enumerated offsets
(eg, X/Y/Z) into storage, always remains in-range.
Possible to make constexpr with future C++ versions.
STYLE: VectorSpace 'operator>' defined using 'operator<'
- standard rewriting rule
- useful when a characteristic per-face search dimension is required.
With PrimitivePatch we are certain to have consistent evaluations
of the face centre.
STYLE: tag PrimitivePatch compatibility headers as such
STYLE: combine templated/non-templated headers (reduced clutter)
STYLE: use hitPoint(const point&) combined setter
- same as setHit() + setPoint(const point&)
ENH: expose and use labelOctBits::pack method for addressing
- the old List_FOR_ALL macro only remained in use in relatively few
places. Replace with the expanded equivalent and move the looping
parameter out of the macro and give an explicit name (eg, loopLen)
which simplifies the addition of any loop pragmas in the various
TFOR_ALL... macros (for example).
- in places where direct reading from the std::stream is used,
this method can be used to ensure that the OpenFOAM Sstream state
is properly updated from the std::stream.
ENH: restrict stream renaming to ISstream
- non-const access was previously declared at the top-level (IOstream)
but that not only added in potentially odd setting of the static
fileName, but also meant that the OFstream name() could potentially
be altered after opening a file and thus be inconsistent with the
underlying file that had been opened.
Now restrict name modification to ISstream (and ITstream
counterpart). Does not affect any existing valid code.
STYLE: non-default OFstream destructor (for future file staging)
- construct boundBox from Pair<point> of min/max limits,
make sortable
- additional bounding box intersections (linePointRef), add noexcept
- templated access for boundBox hex-corners
(used to avoid temporary point field).
Eg, unrolled plane/bound-box intersection with early exit
- bounding box grow() to expand box by absolute amounts
Eg,
bb.grow(ROOTVSMALL); // Or: bb.grow(point::uniform(ROOTVSMALL));
vs
bb.min() -= point::uniform(ROOTVSMALL);
bb.max() += point::uniform(ROOTVSMALL);
- treeBoundBox bounding box extend with two or three parameters.
The three parameter version includes grow(...) for reduced writing.
Eg,
bb = bb.extend(rndGen, 1e-4, ROOTVSMALL);
vs
bb = bb.extend(rndGen, 1e-4);
bb.min() -= point::uniform(ROOTVSMALL);
bb.max() += point::uniform(ROOTVSMALL);
This also permits use as const variables or parameter passing.
Eg,
const treeBoundBox bb
(
treeBoundBox(some_points).extend(rndGen, 1e-4, ROOTVSMALL)
);
- box method on meshShapes (cell,edge,face,triangle,...)
returns a Pair<point>.
Can be used directly without dependency on boundBox,
but the limits can also passed through to boundBox.
- Direct box calculation for cell, which walks the cell-faces and
mesh-faces. Direct calculation for face (#2609)
- with geometryOrder=1, calculate the edge normals from the adjacent
faces (area-weighted, inverse distance squared) and also
use that for the Le() calculation.
Includes the contributions from processor edge neighbours, so it
should be consistent on both sides.
This new method (consider as 'beta') contrasts with the current
standard method that first calculates area-weighted point normals
and uses the average of them for the edge normal.
Enable for testing either with a controlDict OptimisationSwitch entry
"fa:geometryOrder", or on the command-line:
solverName -opt-switch=fa:geometryOrder=1
- the Le vector is calculated from (edgeVec ^ edgeNorm)
and should be oriented in direction (faceCentre -> edgeCentre).
If, however, the edgeNorm value is bad for any reason, the
cross-product falls apart and Le vector is calculated as a zero
vector!
For these cases, revert to using (faceCentre -> edgeCentre)
as a better approximation than a zero vector.
In the future, will very likely switch calculating the edge normals
directly from the attached faces, instead of from the attached
points as is currently done, which should improve robustness.
ENH: expose fa:geometryOrder as a registered OptimisationSwitch
ENN: reuse polyMesh data (eg, faceCentres) if possible in faMesh
STYLE: add code lambdas and static functions to isolate logic
ENH: extend rmDir to handle removal of empty directories only
- recursively remove directories that only contain other directories
but no other contents. Treats dead links as non-content.
- stem(), replace_name(), replace_ext(), remove_ext() etc
- string::contains() method - similar to C++23 method
Eg,
if (keyword.contains('/')) ...
vs
if (keyword.find('/') != std::string::npos) ...
- construct based on db and mesh information from an existing field
- check movable() instead of isTmp() when reusing fields
STYLE: isolate check for reuse GeometricField into Detail namespace
- code remnant from separate lookup + construct of coordinateSystem
(7b2bcfda0b).
Apply consistent use of coordinateSystem::NewIfPresent to avoid
these types of coding mishaps
- in continuation of #2565 (rotationCentre for surface output formats)
it is helpful to also support READ_IF_PRESENT behaviour for the
'origin' keyword.
This can be safely used wherever the coordinate system definition
is embedded within a sub-dictionary scope.
Eg,
dict1
{
coordinateSystem
{
origin (0 0 0); // now optional here
rotation ...;
}
}
but remains mandatory if constructed without a sub-dict:
dict2
{
origin (0 0 0); // still mandatory
e1 (1 0 0);
e3 (0 0 1);
}
With this change, the "transform" sub-dictionary can written
more naturally:
formatOptions
{
vtk
{
scale 1000; // m -> mm
transform
{
rotationCentre (1 0 0);
rotation axisAngle;
axis (0 0 1);
angle -45;
}
}
}
ENH: simplify handling of "coordinateSystem" dictionary lookups
- coordinateSystems::NewIfPresent method for optional entries:
coordSysPtr_ = coordinateSystem::NewIfPresent(mesh, dict);
Instead of
if (dict.found(coordinateSystem::typeName, keyType::LITERAL))
{
coordSysPtr_ =
coordinateSystem::New
(
mesh_,
dict,
coordinateSystem::typeName
);
}
else
{
coordSysPtr_.reset();
}
ENH: more consistent handling of priorities for binModels, forces (#2598)
- if the dictionaries are overspecified, give a 'coordinateSystem'
entry a higher prioriy than the 'CofR' shortcuts.
Was previously slightly inconsistent between the different models.
- previously had 'mandatory' (bool) for advanced control of reading
dictionary entries but its meaning was unclear in the calling code
without extra code comments.
Now use IOobjectOption::readOption instead, which allows further
options (ie, NO_READ) and is more transparent as to its purpose in
the code than a true/false bool flag was.
This is a minor breaking change (infrequent, advanced usage only)
- minor code cleanup in dictionary lookup methods
- with IOstreamOption there are no cases where we need to construct
top-level streams (eg, IFstream, OFstream) with additional information
about the internal IOstream 'version' (eg, version: 2.0).
Makes it more convenient to open files with a specified
format/compression combination - no clutter of specifying the
version
- avoids redundant dictionary searching
STYLE: remove dictionary lookupOrDefaultCompat wrapper
- deprecated and replaced by getOrDefaultCompat (2019-05).
The function is usually specific to internal keyword upgrading
(version compatibility) and unlikely to exist in any user code.
- read construct from dictionary.
Calling syntax similar to dimensionedType, dimensionedSet,...
Replaces the older getEntry(), getOptional() static methods
- support readIfPresent