dimensionedType: Permit reading dimensions after the value in all contexts

This commit is contained in:
Will Bainbridge
2024-04-17 19:29:01 +01:00
parent c2ec1037d9
commit 26f9c794b4
2 changed files with 73 additions and 113 deletions

View File

@ -33,7 +33,8 @@ template<class Type>
bool Foam::dimensioned<Type>::readDimensions
(
Istream& is,
scalar& multiplier
scalar& multiplier,
const bool haveDims
)
{
token nextToken(is);
@ -44,7 +45,11 @@ bool Foam::dimensioned<Type>::readDimensions
dimensionSet dims(dimless);
dims.read(is, multiplier);
if (dims != dimensions_)
if (!haveDims)
{
dimensions_.reset(dims);
}
else if (dims != dimensions_)
{
FatalIOErrorInFunction(is)
<< "The dimensions " << dims
@ -62,14 +67,19 @@ bool Foam::dimensioned<Type>::readDimensions
template<class Type>
void Foam::dimensioned<Type>::initialise(Istream& is)
bool Foam::dimensioned<Type>::initialise
(
Istream& is,
const bool haveName,
const bool haveDims
)
{
token nextToken(is);
is.putBack(nextToken);
// Check if the original format is used in which the name is provided
// and reset the name to that read
if (nextToken.isWord())
if (!haveName && nextToken.isWord())
{
is >> name_;
}
@ -79,7 +89,7 @@ void Foam::dimensioned<Type>::initialise(Istream& is)
// Read dimensions if they are before the value,
// compare with the argument with current
// and set the multiplier
const bool dimensionsRead = readDimensions(is, multiplier);
const bool dimensionsRead = readDimensions(is, multiplier, haveDims);
is >> value_;
@ -88,10 +98,12 @@ void Foam::dimensioned<Type>::initialise(Istream& is)
// and set the multiplier
if (!dimensionsRead && !is.eof())
{
readDimensions(is, multiplier);
readDimensions(is, multiplier, haveDims);
}
value_ *= multiplier;
return !haveName && nextToken.isWord();
}
@ -112,11 +124,7 @@ Foam::dimensioned<Type>::dimensioned
template<class Type>
Foam::dimensioned<Type>::dimensioned
(
const dimensionSet& dimSet,
const Type& t
)
Foam::dimensioned<Type>::dimensioned(const dimensionSet& dimSet, const Type& t)
:
name_(::Foam::name(t)),
dimensions_(dimSet),
@ -147,31 +155,21 @@ Foam::dimensioned<Type>::dimensioned
template<class Type>
Foam::dimensioned<Type>::dimensioned
(
Istream& is
)
Foam::dimensioned<Type>::dimensioned(Istream& is)
:
dimensions_(dimless)
{
read(is);
initialise(is, false, false);
}
template<class Type>
Foam::dimensioned<Type>::dimensioned
(
const word& name,
Istream& is
)
Foam::dimensioned<Type>::dimensioned(const word& name, Istream& is)
:
name_(name),
dimensions_(dimless)
{
scalar multiplier;
dimensions_.read(is, multiplier);
is >> value_;
value_ *= multiplier;
initialise(is, true, false);
}
@ -187,7 +185,7 @@ Foam::dimensioned<Type>::dimensioned
dimensions_(dimSet),
value_(Zero)
{
initialise(is);
initialise(is, true, true);
}
@ -203,17 +201,16 @@ Foam::dimensioned<Type>::dimensioned
dimensions_(dimSet),
value_(Zero)
{
initialise(dict.lookup(name));
initialise(dict.lookup(name), true, true);
}
template<class Type>
Foam::dimensioned<Type>::dimensioned
()
Foam::dimensioned<Type>::dimensioned()
:
name_("undefined"),
name_("NaN"),
dimensions_(dimless),
value_(Zero)
value_(pTraits<Type>::nan)
{}
@ -349,47 +346,45 @@ void Foam::dimensioned<Type>::replace
template<class Type>
void Foam::dimensioned<Type>::read(const dictionary& dict)
{
initialise(dict.lookup(name_));
initialise(dict.lookup(name_), true, true);
}
template<class Type>
bool Foam::dimensioned<Type>::readIfPresent(const dictionary& dict)
{
return dict.readIfPresent(name_, value_);
const entry* entryPtr = dict.lookupEntryPtr(name_, false, true);
if (entryPtr)
{
initialise(entryPtr->stream(), true, true);
return true;
}
else
{
if (dictionary::writeOptionalEntries)
{
IOInfoInFunction(dict)
<< "Optional entry '" << name_ << "' is not present,"
<< " the default value '" << *this << "' will be used."
<< endl;
}
return false;
}
}
template<class Type>
Foam::Istream& Foam::dimensioned<Type>::read(Istream& is)
{
// If the name is present, read it
token nextToken(is);
is.putBack(nextToken);
if (nextToken.isWord())
{
is >> name_;
}
// Read the dimensions and multiplier
scalar multiplier;
dimensions_.read(is, multiplier);
// Read and scale the value
is >> value_;
value_ *= multiplier;
// If the name is not present, set it
if (!nextToken.isWord())
if (!initialise(is, false, false))
{
name_ = Foam::name(value_);
}
// Check state of Istream
is.check
(
"Istream& dimensioned<Type>::read(Istream& is)"
);
is.check("Istream& dimensioned<Type>::read(Istream& is)");
return is;
}
@ -399,20 +394,14 @@ Foam::Istream& Foam::dimensioned<Type>::read(Istream& is)
template<class Type>
Foam::dimensioned<typename Foam::dimensioned<Type>::cmptType>
Foam::dimensioned<Type>::operator[]
(
const direction d
) const
Foam::dimensioned<Type>::operator[](const direction d) const
{
return component(d);
}
template<class Type>
void Foam::dimensioned<Type>::operator+=
(
const dimensioned<Type>& dt
)
void Foam::dimensioned<Type>::operator+=(const dimensioned<Type>& dt)
{
dimensions_ += dt.dimensions_;
value_ += dt.value_;
@ -420,10 +409,7 @@ void Foam::dimensioned<Type>::operator+=
template<class Type>
void Foam::dimensioned<Type>::operator-=
(
const dimensioned<Type>& dt
)
void Foam::dimensioned<Type>::operator-=(const dimensioned<Type>& dt)
{
dimensions_ -= dt.dimensions_;
value_ -= dt.value_;
@ -431,20 +417,14 @@ void Foam::dimensioned<Type>::operator-=
template<class Type>
void Foam::dimensioned<Type>::operator*=
(
const scalar s
)
void Foam::dimensioned<Type>::operator*=(const scalar s)
{
value_ *= s;
}
template<class Type>
void Foam::dimensioned<Type>::operator/=
(
const scalar s
)
void Foam::dimensioned<Type>::operator/=(const scalar s)
{
value_ /= s;
}
@ -477,6 +457,7 @@ Foam::sqr(const dimensioned<Type>& dt)
);
}
template<class Type>
Foam::dimensioned<Foam::scalar> Foam::magSqr(const dimensioned<Type>& dt)
{
@ -488,6 +469,7 @@ Foam::dimensioned<Foam::scalar> Foam::magSqr(const dimensioned<Type>& dt)
);
}
template<class Type>
Foam::dimensioned<Foam::scalar> Foam::mag(const dimensioned<Type>& dt)
{
@ -515,6 +497,7 @@ Foam::dimensioned<Type> Foam::cmptMultiply
);
}
template<class Type>
Foam::dimensioned<Type> Foam::cmptDivide
(
@ -591,28 +574,7 @@ void Foam::writeEntry(Ostream& os, const dimensioned<Type>& dt)
template<class Type>
Foam::Istream& Foam::operator>>(Istream& is, dimensioned<Type>& dt)
{
token nextToken(is);
is.putBack(nextToken);
// Check if the original format is used in which the name is provided
// and reset the name to that read
if (nextToken.isWord())
{
is >> dt.name_;
is >> nextToken;
is.putBack(nextToken);
}
// If the dimensions are provided reset the dimensions to those read
scalar multiplier = 1.0;
if (nextToken == token::BEGIN_SQR)
{
dt.dimensions_.read(is, multiplier);
}
// Read the value
is >> dt.value_;
dt.value_ *= multiplier;
dt.initialise(is, false, false);
// Check state of Istream
is.check("Istream& operator>>(Istream&, dimensioned<Type>&)");
@ -792,7 +754,6 @@ Foam::operator op \
); \
}
PRODUCT_OPERATOR(outerProduct, *, outer)
PRODUCT_OPERATOR(crossProduct, ^, cross)
PRODUCT_OPERATOR(innerProduct, &, dot)

View File

@ -46,17 +46,14 @@ namespace Foam
{
// Forward declaration of friend functions and operators
template<class Type> class dimensioned;
class dictionary;
template<class Type>
class dimensioned;
template<class Type>
Istream& operator>>(Istream&, dimensioned<Type>&);
template<class Type>
Ostream& operator<<(Ostream&, const dimensioned<Type>&);
class dictionary;
/*---------------------------------------------------------------------------*\
Class dimensioned Declaration
\*---------------------------------------------------------------------------*/
@ -78,11 +75,16 @@ class dimensioned
// Private Member Functions
//- Read the dimensions if present
bool readDimensions(Istream& is, scalar& multiplier);
//- Read the dimensions if present. Return whether dimensions were read.
bool readDimensions
(
Istream& is,
scalar& multiplier,
const bool haveDims
);
//- Initialise from Istream
void initialise(Istream& is);
//- Initialise from Istream. Return whether the name was read.
bool initialise(Istream& is, const bool haveName, const bool haveDims);
public:
@ -217,11 +219,8 @@ public:
// IOstream Operators
friend Istream& operator>> <Type>
(Istream&, dimensioned<Type>&);
friend Ostream& operator<< <Type>
(Ostream&, const dimensioned<Type>&);
friend Istream& operator>> <Type>(Istream&, dimensioned<Type>&);
friend Ostream& operator<< <Type>(Ostream&, const dimensioned<Type>&);
};