From b13689c6f2025f50f63a74f8e6f411c9ae92d387 Mon Sep 17 00:00:00 2001 From: Mark Olesen <Mark.Olesen@esi-group.com> Date: Wed, 8 Dec 2021 10:20:07 +0100 Subject: [PATCH] ENH: support optional dimensionSet reading --- src/OpenFOAM/dimensionSet/dimensionSet.C | 2 +- src/OpenFOAM/dimensionSet/dimensionSet.H | 39 +++++- src/OpenFOAM/dimensionSet/dimensionSetIO.C | 112 +++++++++++++----- .../DimensionedField/DimensionedFieldIO.C | 2 +- .../UniformDimensionedField.C | 10 +- 5 files changed, 122 insertions(+), 43 deletions(-) diff --git a/src/OpenFOAM/dimensionSet/dimensionSet.C b/src/OpenFOAM/dimensionSet/dimensionSet.C index 617b3439be0..008e0bfced2 100644 --- a/src/OpenFOAM/dimensionSet/dimensionSet.C +++ b/src/OpenFOAM/dimensionSet/dimensionSet.C @@ -113,7 +113,7 @@ Foam::dimensionSet::dimensionSet(const dimensionSet& ds) bool Foam::dimensionSet::dimensionless() const { - for (const scalar& val : exponents_) + for (const scalar val : exponents_) { // ie, mag(val) > smallExponent if ((val > smallExponent) || (val < -smallExponent)) diff --git a/src/OpenFOAM/dimensionSet/dimensionSet.H b/src/OpenFOAM/dimensionSet/dimensionSet.H index 34c3c00be80..f3f5278e1d9 100644 --- a/src/OpenFOAM/dimensionSet/dimensionSet.H +++ b/src/OpenFOAM/dimensionSet/dimensionSet.H @@ -55,7 +55,7 @@ namespace Foam { // Forward Declarations - +class dictionary; class dimensionSet; class dimensionSets; @@ -130,7 +130,7 @@ private: // Constructors - tokeniser(Istream& is); + explicit tokeniser(Istream& is); // Member Functions @@ -154,8 +154,8 @@ private: }; - //- Reset exponents to nearest integer if close to it. Used to - // handle reading with insufficient precision. + //- Reset exponents to nearest integer if close to it. + // Handles reading with insufficient precision. void round(const scalar tol); dimensionedScalar parse @@ -165,6 +165,7 @@ private: const HashTable<dimensionedScalar>& ) const; + public: // Declare name of the class and its debug switch @@ -212,8 +213,22 @@ public: //- Copy construct dimensionSet(const dimensionSet& ds); - //- Construct from dictionary entry - usually "dimensions". - dimensionSet(const dictionary& dict, const word& entryName); + //- Construct from dictionary entry (usually "dimensions") + // Dimensionless if non-mandatory and not found. + dimensionSet + ( + const word& entryName, //!< Lookup key. LITERAL (not REGEX) + const dictionary& dict, + const bool mandatory = true + ); + + //- Construct from dictionary entry (usually "dimensions") + dimensionSet + ( + const dictionary& dict, + const word& entryName, //!< Lookup key. LITERAL (not REGEX) + const bool mandatory = true + ); //- Construct and return a clone autoPtr<dimensionSet> clone() const @@ -245,6 +260,18 @@ public: // IO + //- Update the dimensions from dictionary entry. + //- FatalIOError if it is found and the number of tokens is incorrect, + //- or it is mandatory and not found. + // + // \return true if the entry was found. + bool readEntry + ( + const word& entryName, //!< Lookup key. LITERAL (not REGEX) + const dictionary& dict, //!< The dictionary + const bool mandatory = true //!< The entry is mandatory + ); + //- Read using provided units. Used only in initial parsing Istream& read ( diff --git a/src/OpenFOAM/dimensionSet/dimensionSetIO.C b/src/OpenFOAM/dimensionSet/dimensionSetIO.C index d978ad90b75..71f9be97509 100644 --- a/src/OpenFOAM/dimensionSet/dimensionSetIO.C +++ b/src/OpenFOAM/dimensionSet/dimensionSetIO.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2019 OpenCFD Ltd. + Copyright (C) 2019-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,21 +26,37 @@ License \*---------------------------------------------------------------------------*/ +#include "dictionary.H" #include "dimensionSet.H" -#include "IOstreams.H" #include "dimensionedScalar.H" +#include "IOstreams.H" #include <limits> // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // -Foam::dimensionSet::dimensionSet(const dictionary& dict, const word& entryName) +Foam::dimensionSet::dimensionSet +( + const word& entryName, + const dictionary& dict, + const bool mandatory +) +: + exponents_(Zero) { - const entry& e = dict.lookupEntry(entryName, keyType::LITERAL); - ITstream& is = e.stream(); + this->readEntry(entryName, dict, mandatory); +} - is >> *this; - e.checkITstream(is); +Foam::dimensionSet::dimensionSet +( + const dictionary& dict, + const word& entryName, + const bool mandatory +) +: + exponents_(Zero) +{ + this->readEntry(entryName, dict, mandatory); } @@ -122,26 +138,24 @@ bool Foam::dimensionSet::tokeniser::valid(char c) Foam::label Foam::dimensionSet::tokeniser::priority(const token& t) { - if (!t.isPunctuation()) + if (t.isPunctuation()) { - return 0; - } - else if - ( - t.pToken() == token::MULTIPLY - || t.pToken() == token::DIVIDE - ) - { - return 2; - } - else if (t.pToken() == '^') - { - return 3; - } - else - { - return 0; + if + ( + t.pToken() == token::MULTIPLY + || t.pToken() == token::DIVIDE + ) + { + return 2; + } + else if (t.pToken() == '^') + { + return 3; + } } + + // Default priority + return 0; } @@ -230,6 +244,8 @@ void Foam::dimensionSet::tokeniser::putBack(const token& t) } +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + void Foam::dimensionSet::round(const scalar tol) { scalar integralPart; @@ -260,7 +276,7 @@ Foam::dimensionedScalar Foam::dimensionSet::parse const HashTable<dimensionedScalar>& readSet ) const { - dimensionedScalar ds("", dimless, 1.0); + dimensionedScalar ds("", dimless, 1); // Get initial token token nextToken(tis.nextToken()); @@ -359,12 +375,12 @@ Foam::dimensionedScalar Foam::dimensionSet::parse { if (nextPrior > lastPrior) { - dimensionedScalar exp(parse(nextPrior, tis, readSet)); + dimensionedScalar expon(parse(nextPrior, tis, readSet)); - ds.dimensions().reset(pow(ds.dimensions(), exp.value())); + ds.dimensions().reset(pow(ds.dimensions(), expon.value())); // Round to nearest integer if close to it ds.dimensions().round(10*smallExponent); - ds.value() = Foam::pow(ds.value(), exp.value()); + ds.value() = Foam::pow(ds.value(), expon.value()); } else { @@ -409,6 +425,38 @@ Foam::dimensionedScalar Foam::dimensionSet::parse } +bool Foam::dimensionSet::readEntry +( + const word& entryName, + const dictionary& dict, + const bool mandatory +) +{ + const entry* eptr = dict.findEntry(entryName, keyType::LITERAL); + + if (eptr) + { + const entry& e = *eptr; + ITstream& is = e.stream(); + + is >> *this; + + e.checkITstream(is); + + return true; + } + else if (mandatory) + { + FatalIOErrorInFunction(dict) + << "Entry '" << entryName << "' not found in dictionary " + << dict.relativeName() << nl + << exit(FatalIOError); + } + + return false; +} + + Foam::Istream& Foam::dimensionSet::read ( Istream& is, @@ -533,7 +581,7 @@ Foam::Istream& Foam::dimensionSet::read // Parse unit - dimensionSet symbolSet(dimless); + dimensionSet symbolSet; // dimless const auto index = symbolPow.find('^'); if (index != std::string::npos) @@ -542,7 +590,7 @@ Foam::Istream& Foam::dimensionSet::read const scalar exponent = readScalar(symbolPow.substr(index+1)); dimensionedScalar s; - s.read(readSet.lookup(symbol), readSet); + s.read(readSet.lookup(symbol, keyType::LITERAL), readSet); symbolSet.reset(pow(s.dimensions(), exponent)); @@ -553,7 +601,7 @@ Foam::Istream& Foam::dimensionSet::read else { dimensionedScalar s; - s.read(readSet.lookup(symbolPow), readSet); + s.read(readSet.lookup(symbolPow, keyType::LITERAL), readSet); symbolSet.reset(s.dimensions()); multiplier *= s.value(); diff --git a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C index ee234c64770..6dd9e2560c5 100644 --- a/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C +++ b/src/OpenFOAM/fields/DimensionedFields/DimensionedField/DimensionedFieldIO.C @@ -38,7 +38,7 @@ void Foam::DimensionedField<Type, GeoMesh>::readField const word& fieldDictEntry ) { - dimensions_.reset(dimensionSet(fieldDict, "dimensions")); + dimensions_.readEntry("dimensions", fieldDict); // Note: oriented state may have already been set on construction // - if so - do not reset by re-reading diff --git a/src/OpenFOAM/fields/UniformDimensionedFields/UniformDimensionedField.C b/src/OpenFOAM/fields/UniformDimensionedFields/UniformDimensionedField.C index 650632e7604..b59ee2b1b91 100644 --- a/src/OpenFOAM/fields/UniformDimensionedFields/UniformDimensionedField.C +++ b/src/OpenFOAM/fields/UniformDimensionedFields/UniformDimensionedField.C @@ -85,8 +85,12 @@ template<class Type> bool Foam::UniformDimensionedField<Type>::readData(Istream& is) { dictionary dict(is); - scalar multiplier; - this->dimensions().read(dict.lookup("dimensions"), multiplier); + scalar multiplier(1); + this->dimensions().read + ( + dict.lookup("dimensions", keyType::LITERAL), + multiplier + ); dict.readEntry("value", this->value()); this->value() *= multiplier; @@ -98,7 +102,7 @@ bool Foam::UniformDimensionedField<Type>::readData(Istream& is) template<class Type> bool Foam::UniformDimensionedField<Type>::writeData(Ostream& os) const { - scalar multiplier; + scalar multiplier(1); os.writeKeyword("dimensions"); this->dimensions().write(os, multiplier) << token::END_STATEMENT << nl; os.writeEntry("value", this->value()/multiplier) << nl; -- GitLab