ENH: support optional dimensionSet reading
This commit is contained in:
parent
8c98906780
commit
efb187e3f7
@ -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))
|
||||
@ -126,13 +126,15 @@ bool Foam::dimensionSet::dimensionless() const
|
||||
}
|
||||
|
||||
|
||||
const Foam::FixedList<Foam::scalar,7>& Foam::dimensionSet::values() const
|
||||
const Foam::FixedList<Foam::scalar,7>&
|
||||
Foam::dimensionSet::values() const noexcept
|
||||
{
|
||||
return exponents_;
|
||||
}
|
||||
|
||||
|
||||
Foam::FixedList<Foam::scalar,7>& Foam::dimensionSet::values()
|
||||
Foam::FixedList<Foam::scalar,7>&
|
||||
Foam::dimensionSet::values() noexcept
|
||||
{
|
||||
return exponents_;
|
||||
}
|
||||
|
@ -28,10 +28,21 @@ Class
|
||||
Foam::dimensionSet
|
||||
|
||||
Description
|
||||
Dimension set for the base types.
|
||||
Dimension set for the base types, which can be used to implement
|
||||
rigorous dimension checking for algebraic manipulation.
|
||||
|
||||
This type may be used to implement rigorous dimension checking
|
||||
for algebraic manipulation.
|
||||
The dimensions are specified in the following order
|
||||
(SI units for reference only):
|
||||
\table
|
||||
Property | SI Description | SI unit
|
||||
MASS | kilogram | \c kg
|
||||
LENGTH | metre | \c m
|
||||
TIME | second | \c s
|
||||
TEMPERATURE | Kelvin | \c K
|
||||
MOLES | mole | \c mol
|
||||
CURRENT | Ampere | \c A
|
||||
LUMINOUS_INTENSITY | Candela | \c cd
|
||||
\endtable
|
||||
|
||||
SourceFiles
|
||||
dimensionSet.C
|
||||
@ -55,7 +66,7 @@ namespace Foam
|
||||
{
|
||||
|
||||
// Forward Declarations
|
||||
|
||||
class dictionary;
|
||||
class dimensionSet;
|
||||
class dimensionSets;
|
||||
|
||||
@ -79,13 +90,13 @@ public:
|
||||
//- Enumeration for the dimension exponents
|
||||
enum dimensionType
|
||||
{
|
||||
MASS, //!< kilogram kg
|
||||
LENGTH, //!< metre m
|
||||
TIME, //!< second s
|
||||
TEMPERATURE, //!< Kelvin K
|
||||
MOLES, //!< mole mol
|
||||
CURRENT, //!< Ampere A
|
||||
LUMINOUS_INTENSITY //!< Candela Cd
|
||||
MASS, //!< kilogram \c kg
|
||||
LENGTH, //!< metre \c m
|
||||
TIME, //!< second \c s
|
||||
TEMPERATURE, //!< Kelvin \c K
|
||||
MOLES, //!< mole \c mol
|
||||
CURRENT, //!< Ampere \c A
|
||||
LUMINOUS_INTENSITY //!< Candela \c cd
|
||||
};
|
||||
|
||||
|
||||
@ -130,7 +141,7 @@ private:
|
||||
|
||||
// Constructors
|
||||
|
||||
tokeniser(Istream& is);
|
||||
explicit tokeniser(Istream& is);
|
||||
|
||||
|
||||
// Member Functions
|
||||
@ -154,8 +165,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 +176,7 @@ private:
|
||||
const HashTable<dimensionedScalar>&
|
||||
) const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Declare name of the class and its debug switch
|
||||
@ -212,8 +224,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
|
||||
@ -230,13 +256,13 @@ public:
|
||||
//- Return true if it is dimensionless
|
||||
bool dimensionless() const;
|
||||
|
||||
//- Return const access to the exponents as a list
|
||||
const FixedList<scalar,7>& values() const;
|
||||
//- Const access to the exponents as a list
|
||||
const FixedList<scalar,7>& values() const noexcept;
|
||||
|
||||
//- Return non-const access to the exponents as a list
|
||||
FixedList<scalar,7>& values();
|
||||
//- Non-const access to the exponents as a list
|
||||
FixedList<scalar,7>& values() noexcept;
|
||||
|
||||
//- Reset exponents to be dimensionless
|
||||
//- Clear exponents - resets to be dimensionless
|
||||
void clear();
|
||||
|
||||
//- Copy assign the exponents from the dimensionSet
|
||||
@ -245,6 +271,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
|
||||
(
|
||||
@ -303,6 +341,7 @@ public:
|
||||
bool operator/=(const dimensionSet&);
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// IOstream Operators
|
||||
|
@ -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();
|
||||
|
@ -186,7 +186,7 @@ const dimensionSets& writeUnitSet()
|
||||
}
|
||||
|
||||
|
||||
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0);
|
||||
const dimensionSet dimless;
|
||||
|
||||
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0);
|
||||
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0);
|
||||
|
@ -34,7 +34,6 @@ SourceFiles
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef dimensionSets_H
|
||||
#define dimensionSets_H
|
||||
|
||||
@ -85,7 +84,7 @@ extern const dimensionSet dimDynamicViscosity;
|
||||
//- Construction of unit sets
|
||||
class dimensionSets
|
||||
{
|
||||
// Private data
|
||||
// Private Data
|
||||
|
||||
//- Set of dimensions
|
||||
PtrList<dimensionedScalar> units_;
|
||||
@ -111,16 +110,17 @@ public:
|
||||
const wordList& unitNames
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Return the units
|
||||
const PtrList<dimensionedScalar>& units() const
|
||||
const PtrList<dimensionedScalar>& units() const noexcept
|
||||
{
|
||||
return units_;
|
||||
}
|
||||
|
||||
//- Is there a valid inverse of the selected unit
|
||||
bool valid() const
|
||||
bool valid() const noexcept
|
||||
{
|
||||
return valid_;
|
||||
}
|
||||
|
@ -39,8 +39,7 @@ namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
class dimensioned;
|
||||
template<class Type> class dimensioned;
|
||||
|
||||
typedef dimensioned<scalar> dimensionedScalar;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user