- use the dictionary 'get' methods instead of readScalar for
additional checking
Unchecked: readScalar(dict.lookup("key"));
Checked: dict.get<scalar>("key");
- In templated classes that also inherit from a dictionary, an additional
'template' keyword will be required. Eg,
this->coeffsDict().template get<scalar>("key");
For this common use case, the predefined getXXX shortcuts may be
useful. Eg,
this->coeffsDict().getScalar("key");
- nBoundaryFaces() is often used and is identical to
(nFaces() - nInternalFaces()).
- forward the mesh nInternalFaces() and nBoundaryFaces() to
polyBoundaryMesh as nFaces() and start() respectively,
for use when operating on a polyBoundaryMesh.
STYLE:
- use identity() function with starting offset when creating boundary maps.
labelList map
(
identity(mesh.nBoundaryFaces(), mesh.nInternalFaces())
);
vs.
labelList map(mesh.nBoundaryFaces());
forAll(map, i)
{
map[i] = mesh.nInternalFaces() + i;
}
- avoids compiler ambiguity when virtual methods such as
IOdictionary::read() exist.
- the method was introduced in 1806, and was thus not yet widely used
- aids with detection of excess tokens (issue #762)
- deprecated dictionary::operator[] in favour of the lookup() method
which offers more flexibilty and clarity of purpose.
Additionally, the read<> and get<> forms should generally be used
instead anyhow.
- affected manually generated legacy output (vtkSetWriter, vtkSurfaceWriter)
- the order emitted by vtkSetWriter remains, but needs to revisited again.
- improves backward compatibility and more naming consistency.
Retain setMany(iter1, iter2) to avoid ambiguity with the
PackedList::set(index, value) method.
- The iterator for a HashSet dereferences directly to its key.
- Eg,
for (const label patchi : patchSet)
{
...
}
vs.
forAllConstIter(labelHashSet, patchSet, iter)
{
const label patchi = iter.key();
...
}
- handling of dead links (find -L -delete unsupported)
- remove ignore case flag on 's/../../i' used in have_scotch script.
It is unneeded and not tolerated by Darwin's sed.
- avoid embedded comments in EXE_INC (Make/options files), which do
not work well with the OSX LLVM cpp.
It strips out the comments but also removes the continuation char.
STYLE: adjust notes about paraview library locations
- generalize some of the library extensions (.so vs .dylib).
Provide as wmake 'sysFunctions'
- added note about unsupported/incomplete system support
- centralize detection of ThirdParty packages into wmake/ subdirectory
by providing a series of scripts in the spirit of GNU autoconfig.
For example,
have_boost, have_readline, have_scotch, ...
Each of the `have_<package>` scripts will generally provide the
following type of functions:
have_<package> # detection
no_<package> # reset
echo_<package> # echoing
and the following type of variables:
HAVE_<package> # unset or 'true'
<package>_ARCH_PATH # root for <package>
<package>_INC_DIR # include directory for <package>
<package>_LIB_DIR # library directory for <package>
This simplifies the calling scripts:
if have_metis
then
wmake metisDecomp
fi
As well as reducing clutter in the corresponding Make/options:
EXE_INC = \
-I$(METIS_INC_DIR) \
-I../decompositionMethods/lnInclude
LIB_LIBS = \
-L$(METIS_LIB_DIR) -lmetis
Any additional modifications (platform-specific or for an external build
system) can now be made centrally.
- IOstreamOption class to encapsulate format, compression, version.
This is ordered to avoid internal padding in the structure, which
reduces several bytes of memory overhead for stream objects
and other things using this combination of data.
Byte-sizes:
old IOstream:48 PstreamBuffers:88 Time:928
new IOstream:24 PstreamBuffers:72 Time:904
====
STYLE: remove support for deprecated uncompressed/compressed selectors
In older versions, the system/controlDict used these types of
specifications:
writeCompression uncompressed;
writeCompression compressed;
As of DEC-2009, these were deprecated in favour of using normal switch
names:
writeCompression true;
writeCompression false;
writeCompression on;
writeCompression off;
Now removed these deprecated names and treat like any other unknown
input and issue a warning. Eg,
Unknown compression specifier 'compressed', assuming no compression
====
STYLE: provide Enum of stream format names (ascii, binary)
====
COMP: fixed incorrect IFstream construct in FIREMeshReader
- spurious bool argument (presumably meant as uncompressed) was being
implicitly converted to a versionNumber. Now caught by making
IOstreamOption::versionNumber constructor explicit.
- bad version specifier in changeDictionary
- both autoPtr and tmp are defined with an implicit construct from
nullptr (but with explicit construct from a pointer to null).
Thus is it safe to use 'nullptr' when returning an empty autoPtr or tmp.
- eliminate iterators from PackedList since they were unused, had
lower performance than direct access and added unneeded complexity.
- eliminate auto-vivify for the PackedList '[] operator.
The set() method provides any required auto-vivification and
removing this ability from the '[]' operator allows for a lower
when accessing the values. Replaced the previous cascade of iterators
with simpler reference class.
PackedBoolList:
- (temporarily) eliminate logic and addition operators since
these contained partially unclear semantics.
- the new test() method tests the value of a single bit position and
returns a bool without any ambiguity caused by the return type
(like the get() method), nor the const/non-const access (like
operator[] has). The name corresponds to what std::bitset uses.
- more consistent use of PackedBoolList test(), set(), unset() methods
for fewer operation and clearer code. Eg,
if (list.test(index)) ... | if (list[index]) ...
if (!list.test(index)) ... | if (list[index] == 0u) ...
list.set(index); | list[index] = 1u;
list.unset(index); | list[index] = 0u;
- deleted the operator=(const labelUList&) and replaced with a setMany()
method for more clarity about the intended operation and to avoid any
potential inadvertent behaviour.
- The bitSet class replaces the old PackedBoolList class.
The redesign provides better block-wise access and reduced method
calls. This helps both in cases where the bitSet may be relatively
sparse, and in cases where advantage of contiguous operations can be
made. This makes it easier to work with a bitSet as top-level object.
In addition to the previously available count() method to determine
if a bitSet is being used, now have simpler queries:
- all() - true if all bits in the addressable range are empty
- any() - true if any bits are set at all.
- none() - true if no bits are set.
These are faster than count() and allow early termination.
The new test() method tests the value of a single bit position and
returns a bool without any ambiguity caused by the return type
(like the get() method), nor the const/non-const access (like
operator[] has). The name corresponds to what std::bitset uses.
The new find_first(), find_last(), find_next() methods provide a faster
means of searching for bits that are set.
This can be especially useful when using a bitSet to control an
conditional:
OLD (with macro):
forAll(selected, celli)
{
if (selected[celli])
{
sumVol += mesh_.cellVolumes()[celli];
}
}
NEW (with const_iterator):
for (const label celli : selected)
{
sumVol += mesh_.cellVolumes()[celli];
}
or manually
for
(
label celli = selected.find_first();
celli != -1;
celli = selected.find_next()
)
{
sumVol += mesh_.cellVolumes()[celli];
}
- When marking up contiguous parts of a bitset, an interval can be
represented more efficiently as a labelRange of start/size.
For example,
OLD:
if (isA<processorPolyPatch>(pp))
{
forAll(pp, i)
{
ignoreFaces.set(i);
}
}
NEW:
if (isA<processorPolyPatch>(pp))
{
ignoreFaces.set(pp.range());
}
This class is largely a pre-C++11 holdover. It is now possible to
simply use move construct/assignment directly.
In a few rare cases (eg, polyMesh::resetPrimitives) it has been
replaced by an autoPtr.
Improve alignment of its behaviour with std::unique_ptr
- element_type typedef
- release() method - identical to ptr() method
- get() method to get the pointer without checking and without releasing it.
- operator*() for dereferencing
Method name changes
- renamed rawPtr() to get()
- renamed rawRef() to ref(), removed unused const version.
Removed methods/operators
- assignment from a raw pointer was deleted (was rarely used).
Can be convenient, but uncontrolled and potentially unsafe.
Do allow assignment from a literal nullptr though, since this
can never leak (and also corresponds to the unique_ptr API).
Additional methods
- clone() method: forwards to the clone() method of the underlying
data object with argument forwarding.
- reset(autoPtr&&) as an alternative to operator=(autoPtr&&)
STYLE: avoid implicit conversion from autoPtr to object type in many places
- existing implementation has the following:
operator const T&() const { return operator*(); }
which means that the following code works:
autoPtr<mapPolyMesh> map = ...;
updateMesh(*map); // OK: explicit dereferencing
updateMesh(map()); // OK: explicit dereferencing
updateMesh(map); // OK: implicit dereferencing
for clarity it may preferable to avoid the implicit dereferencing
- prefer operator* to operator() when deferenced a return value
so it is clearer that a pointer is involve and not a function call
etc Eg, return *meshPtr_; vs. return meshPtr_();
* For most cases, this conversion would be largely unintentional
and also less efficient. If the regex is desirable, the caller
should invoke it explicitly.
For example,
findStrings(regExp(str), listOfStrings);
Or use one of the keyType, wordRe, wordRes variants instead.
If string is to be used as a plain (non-regex) matcher,
this can be directly invoked
findMatchingStrings(str, listOfStrings);
or using the ListOps instead:
findIndices(listOfStrings, str);
* provide function interfaces for keyType.
- Eg instead of using labelHashSet, used HashSet<label> which uses
the string::hash for hashing. Other places inadvertently using the
string::hash instead of Hash<label> for hashing.
STYLE: use Map<..> instead of HashTable<.., label, Hash<label>>
- reduces clutter
- constructor for empty cell/face/point Zones, with contents to be
transferred in later.
- ZoneMesh::operator(const word&) to return existing zone or a new empty one.
- this provides a better typesafe means of locating predefined cell
models than relying on strings. The lookup is now ptr() or ref()
directly. The lookup functions behave like on-demand singletons when
loading "etc/cellModels".
Functionality is now located entirely in cellModel but a forwarding
version of cellModeller is provided for API (but not ABI) compatibility
with older existing user code.
STYLE: use constexpr for cellMatcher constants
- disable automatically upgrading copyrights in files since changes to
not automatically imply a change in copyright. Eg, fixing a typo in
comments, or changing a variable from 'loopI' to 'loopi' etc.
- eliminates the PtrList requirement (more flexible)
COMP: use tmp intermediate for volPointInterpolation return value
- gcc 4.8.5 had some weird issue of otherwise not binding a const-ref.
(in foamVtkInternalWriterTemplates.C)
- with the xml append format it is possible to write raw binary
(instead of base64), but the writer becomes more complicated.
Either needs two passes to create, or need to allocate a block
of space for the header information (like VTK itself does) and
write later.
* internalWriter
* patchWriter
* surfaceMeshWriter
* lagrangianWriter
Also these special purpose ones:
* foamVtkWriteSurfFields
- this shifts responsibility away from caller to the individual writers
for knowing which file formats are supported and which file ending is
appropriate. When the writer receives the output format request,
it can elect to downgrade or otherwise adjust it to what it can
actually manage (eg, legacy vs xml vs xml-append).
But currently still just with legacy format backends.