- previously used a Pstream::exit() invoked from the argList
destructor to handle all MPI shutdown, but this has the unfortunate
side-effect of using a fixed return value for the program exit.
Instead use the Pstream::shutdown() method in the destructor and allow
the normal program exit codes as usual. This means that the
following code now works as expected.
```
argList args(...);
if (...)
{
InfoErr<< "some error\n";
return 1;
}
```
- string expansions have supported "${var:-default}" syntax for
several versions, but this did not apply plain dictionary expansions.
Eg, the following did not parse
massFlow ${entry1:-100};
ENH: remove content and length restriction on '${..}' quoted variables
- allows this type of content:
velocity2 ${velocity1:- ( 0 -100 10) };
- accept empty parameter strings for entries. This allows the
following expansion to work as expected:
hex (n1 n2..) ${inletBlock:-} (10 10 10) simpleGrading (1 1 1)
ie, optionally define the cellZone name for a given block
ENH: add single parameter dictionary writeEntry method.
- the dictionary knows its own name (dictName), which can be used
when writing content
Style changes:
- use std algorithm for some stringOps internals
- pass SubStrings iterators by const reference
ENH: special nullptr handling for ISstream getLine
- pass through to istream::ignore to support read and discard
* Support default values for format/compress enum lookups.
- Avoids situations where the preferred default format is not ASCII.
For example, with dictionary input:
format binar;
The typing mistake would previously have caused formatEnum to
default to ASCII. We can now properly control its behaviour.
IOstream::formatEnum
(
dict.get<word>("format"), IOstream::BINARY
);
Allowing us to switch ascii/binary, using BINARY by default even in
the case of spelling mistakes. The mistakes are flagged, but the
return value can be non-ASCII.
* The format/compression lookup behave as pass-through if the lookup
string is empty.
- Allows the following to work without complaint
IOstream::formatEnum
(
dict.getOrDefault("format", word::null), IOstream::BINARY
);
- Or use constructor-like failsafe method
IOstream::formatEnum("format", dict, IOstream::BINARY);
- Apply the same behaviour with setting stream format/compression
from a word.
is.format("binar");
will emit a warning, but leave the stream format UNCHANGED
* Rationalize versionNumber construction
- constexpr constructors where possible.
Default construct is the "currentVersion"
- Construct from token to shift the burden to versionNumber.
Support token as argument to version().
Now:
is.version(headerDict.get<token>("version"));
or failsafe constructor method
is.version
(
IOstreamOption::versionNumber("version", headerDict)
);
Before (controlled input):
is.version
(
IOstreamOption::versionNumber
(
headerDict.get<float>("version")
)
);
Old, uncontrolled input - has been removed:
is.version(headerDict.lookup("version"));
* improve consistency, default behaviour for IOstreamOption construct
- constexpr constructors where possible
- add copy construct with change of format.
- construct IOstreamOption from streamFormat is now non-explicit.
This is a commonly expected result with no ill-effects
- align Switch more with Enum.
Now have find(), found() static methods.
Constructors with failsafe option.
The find() method makes for clearer coding:
OLD
Switch sw(some_string, true); // NB: true = allowBad
if (sw.valid()) ...
NOW
Switch sw = Switch::find(some_string);
if (sw.good()) ...
or
if (Switch::found(some_string)) ...
- improve construct from dictionary to handle all valid token types.
Previously just read in a word.
- Remove asText() method - replaced by c_str() and str() several
versions ago.
- make stream constructors explicit
- remove "using std::ifstream", "using std::iofstream" statements
for a cleaner namespace.
* copy/move assignments for ITstream
* IStringStream: default construct and construct from std::string
instead of Foam::string
- reduce some overhead in masterOFstream
- simplify Pstream handling of string variants (#1525)
- previously the store() method just set the ownedByRegistry flag.
Now ensure that it is indeed registered first.
- support register/store of tmp<> items.
The tmp parameter is not cleared, but changed from PTR to CREF
to allow further use.
The implicit registration allows code simplification using the
GeometricField::New factory method, for example.
Old Code
========
volScalarField* ptr = new volScalarField
(
IOobject
(
fieldName,
mesh.time().timeName(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
true // Register
),
mesh,
dimless,
zeroGradientFvPatchField<scalar>::typeName
);
ptr->store();
New Code
========
auto tptr = volScalarField::New
(
fieldName,
mesh,
dimless,
zeroGradientFvPatchField<scalar>::typeName
);
regIOobject::store(tptr);
or even
regIOobject::store
(
volScalarField::New
(
fieldName,
mesh,
dimless,
zeroGradientFvPatchField<scalar>::typeName
)
);
The collated container ('decomposedBlockData') is always binary
but the 'payload' might be ascii so use that header information
instead of the decomposeBlockData header.
- follows the principle of least surprise if the expansion behaviour
for #eval and expressions (eg, exprFixedValue) are the same. This
is possible now that we harness the regular stringOps::expand()
within exprString::expand()
- synchronize the scalar interval value with the integer version.
This ensures that the interval() method returns the correct
representative value.
- added clear() method to reset to 'always' (pass-through)
- handle zero or negative values as being identical to 1.
As per timeStep control and what the comments suggested.
- drop old outputTime enumeration, since this is covered by the
writeTime enumeration and a corresponding Enum name.
- support construction of a "pass-through" control object that always
executes and add some method to test for these conditions and be able
to output some meaning full information.
Eg,
if (ctrl.execute())
{
if (!ctrl.always())
{
Info<< "Sampling executed based on " << ctrl.type() << nl;
}
...
}
To produce "Sampling executed based on runTime"
- replace stringOps::toScalar with a more generic stringOps::evaluate
method that handles scalars, vectors etc.
- improve #eval to handle various mathematical operations.
Previously only handled scalars. Now produce vectors, tensors etc
for the entries. These tokens are streamed directly into the entry.
- ITstream append() would previously have used the append from the
underlying tokenList, which leaves the tokenIndex untouched and
renders the freshly appended tokens effectively invisible if
interspersed with primitiveEntry::read() that itself uses tokenIndex
when building the list.
The new append() method makes this hidden ITstream bi-directionality
easier to manage. For efficiency, we only append lists
(not individual tokens) and support a 'lazy' resizing that allows
the final resizing to occur later when all tokens have been appended.
- The new ITstream seek() method provides a conveniently means to move
to the end of the list or reposition to the middle.
Using rewind() and using seek(0) are identical.
ENH: added OTstream to output directly to a list of tokens
---
BUG: List::newElem resized incorrectly
- had a simple doubling of the List size without checking that this
would indeed be sufficient for the requested index.
Bug was not triggered since primitiveEntry was the only class using
this call, and it added the tokens sequentially.