unitConversion: Fixed format of non-named units
Non-named unit conversions are now written in a single set of square brackets, with colons used to separate the sets of exponents and multipliers. So, for example, a named unit conversion of [rpm] gets converted to a non-named [0 0 -1 0 0 0 0 : 0 1 : 0.10472] (i.e., [time^-1 : angle : 0.10472]). Previously, multiple sets of square brackets were used to separate the sections, so the above example would have been written as [0 0 -1 0 0 0 0][0 1][0.10472]. The problem with this is that '][' is not distinguished in the token parser from '] ['. Combined with the fact that the later sections are optional, this makes reading pairs or lists of these objects impossible. The new format is, by comparison, unambiguously delimited in all contexts. This change may break the restart of a case in which unit conversion entries have been written out. It is unlikely to require modification to an initial configuration as named unit conversion entries (such as [rpm] and [MPa] and [l/min]) are unaffected.
This commit is contained in:
@ -227,15 +227,21 @@ public:
|
||||
|
||||
// I/O
|
||||
|
||||
//- Read, assuming the '[' has already been read
|
||||
Istream& readNoBegin(Istream& is);
|
||||
//- Read without the square brackets
|
||||
Istream& readNoBeginOrEnd(Istream& is);
|
||||
|
||||
//- Read
|
||||
Istream& read(Istream& is);
|
||||
|
||||
//- Write without the square brackets
|
||||
Ostream& writeNoBeginOrEnd(Ostream& os) const;
|
||||
|
||||
//- Write
|
||||
Ostream& write(Ostream& os) const;
|
||||
|
||||
//- Write info without the square brackets
|
||||
Ostream& writeInfoNoBeginOrEnd(Ostream& os) const;
|
||||
|
||||
//- Return info proxy
|
||||
inline InfoProxy<dimensionSet> info() const
|
||||
{
|
||||
|
||||
@ -30,7 +30,7 @@ License
|
||||
|
||||
void Foam::dimensionSet::round(const scalar tol)
|
||||
{
|
||||
for (int i=0; i < dimensionSet::nDimensions; ++i)
|
||||
for (int i=0; i<dimensionSet::nDimensions; ++i)
|
||||
{
|
||||
scalar integralPart;
|
||||
scalar fractionalPart = std::modf(exponents_[i], &integralPart);
|
||||
@ -61,59 +61,47 @@ Foam::dimensionSet::dimensionSet(Istream& is)
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::Istream& Foam::dimensionSet::readNoBegin(Istream& is)
|
||||
Foam::Istream& Foam::dimensionSet::readNoBeginOrEnd(Istream& is)
|
||||
{
|
||||
// Read next token
|
||||
token nextToken(is);
|
||||
token nextToken;
|
||||
|
||||
// Peek at the next token
|
||||
is >> nextToken;
|
||||
is.putBack(nextToken);
|
||||
|
||||
// If not a number, then these are named dimensions. Parse.
|
||||
if (!nextToken.isNumber())
|
||||
{
|
||||
// Named dimensions. Parse.
|
||||
is.putBack(nextToken);
|
||||
reset(symbols::parseNoBegin(is, dimless, dimensions()));
|
||||
reset(symbols::parseNoBeginOrEnd(is, dimless, dimensions()));
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
// Otherwise these are numbered dimensions. Read directly...
|
||||
|
||||
// Read first five dimensions
|
||||
for (int i=0; i<dimensionSet::CURRENT; i++)
|
||||
{
|
||||
is >> exponents_[i];
|
||||
}
|
||||
|
||||
// Peek at the next token
|
||||
is >> nextToken;
|
||||
is.putBack(nextToken);
|
||||
|
||||
// If next token is another number then read the last two dimensions
|
||||
// and then read another token for the end of the dimensionSet
|
||||
if (nextToken.isNumber())
|
||||
{
|
||||
is >> exponents_[dimensionSet::CURRENT];
|
||||
is >> exponents_[dimensionSet::LUMINOUS_INTENSITY];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Numbered dimensions. Read directly.
|
||||
|
||||
// Read first five dimensions
|
||||
exponents_[dimensionSet::MASS] = nextToken.number();
|
||||
for (int Dimension=1; Dimension<dimensionSet::CURRENT; Dimension++)
|
||||
{
|
||||
is >> exponents_[Dimension];
|
||||
}
|
||||
|
||||
// Read next token
|
||||
token nextToken(is);
|
||||
|
||||
// If next token is another number then read the last two dimensions
|
||||
// and then read another token for the end of the dimensionSet
|
||||
if (nextToken.isNumber())
|
||||
{
|
||||
exponents_[dimensionSet::CURRENT] = nextToken.number();
|
||||
is >> nextToken;
|
||||
exponents_[dimensionSet::LUMINOUS_INTENSITY] = nextToken.number();
|
||||
is >> nextToken;
|
||||
}
|
||||
else
|
||||
{
|
||||
exponents_[dimensionSet::CURRENT] = 0;
|
||||
exponents_[dimensionSet::LUMINOUS_INTENSITY] = 0;
|
||||
}
|
||||
|
||||
// Check end of dimensionSet
|
||||
if (nextToken != token::END_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR << " in dimensionSet "
|
||||
<< endl << "in stream " << is.info()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
exponents_[dimensionSet::CURRENT] = 0;
|
||||
exponents_[dimensionSet::LUMINOUS_INTENSITY] = 0;
|
||||
}
|
||||
|
||||
// Check state of Istream
|
||||
is.check("Istream& operator>>(Istream&, dimensionSet&)");
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
@ -122,7 +110,6 @@ Foam::Istream& Foam::dimensionSet::read(Istream& is)
|
||||
{
|
||||
// Read beginning of dimensionSet
|
||||
token startToken(is);
|
||||
|
||||
if (startToken != token::BEGIN_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
@ -131,7 +118,42 @@ Foam::Istream& Foam::dimensionSet::read(Istream& is)
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
return readNoBegin(is);
|
||||
readNoBeginOrEnd(is);
|
||||
|
||||
// Read end of dimensionSet
|
||||
token endToken(is);
|
||||
if (endToken != token::END_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR << " in dimensionSet "
|
||||
<< endl << "in stream " << is.info()
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Check state of Istream
|
||||
is.check("Istream& operator>>(Istream&, dimensionSet&)");
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::dimensionSet::writeNoBeginOrEnd(Ostream& os) const
|
||||
{
|
||||
if (dimensionless())
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i=0; i<dimensionSet::nDimensions-1; i++)
|
||||
{
|
||||
os << exponents_[i] << token::SPACE;
|
||||
}
|
||||
|
||||
os << exponents_[dimensionSet::nDimensions-1];
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
@ -139,12 +161,9 @@ Foam::Ostream& Foam::dimensionSet::write(Ostream& os) const
|
||||
{
|
||||
os << token::BEGIN_SQR;
|
||||
|
||||
for (int d=0; d<dimensionSet::nDimensions-1; d++)
|
||||
{
|
||||
os << exponents_[d] << token::SPACE;
|
||||
}
|
||||
writeNoBeginOrEnd(os);
|
||||
|
||||
os << exponents_[dimensionSet::nDimensions-1] << token::END_SQR;
|
||||
os << token::END_SQR;
|
||||
|
||||
// Check state of Ostream
|
||||
os.check("Ostream& operator<<(Ostream&, const dimensionSet&)");
|
||||
@ -153,6 +172,33 @@ Foam::Ostream& Foam::dimensionSet::write(Ostream& os) const
|
||||
}
|
||||
|
||||
|
||||
Foam::Ostream& Foam::dimensionSet::writeInfoNoBeginOrEnd(Ostream& os) const
|
||||
{
|
||||
for (int first=true, i=0; i<dimensionSet::nDimensions; i++)
|
||||
{
|
||||
if (mag(exponents_[i]) > dimensionSet::smallExponent)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
os << token::SPACE;
|
||||
}
|
||||
|
||||
os << dimensionSet::dimensionTypeNames_
|
||||
[static_cast<dimensionSet::dimensionType>(i)];
|
||||
|
||||
if (exponents_[i] != 1)
|
||||
{
|
||||
os << '^' << exponents_[i];
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
void Foam::writeEntry(Ostream& os, const dimensionSet& value)
|
||||
{
|
||||
os << value;
|
||||
@ -185,30 +231,9 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const dimensionSet& dims)
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const InfoProxy<dimensionSet>& ip)
|
||||
{
|
||||
const dimensionSet& dims = ip.t_;
|
||||
|
||||
os << token::BEGIN_SQR;
|
||||
|
||||
for (int first=true, i=0; i<dimensionSet::nDimensions; i++)
|
||||
{
|
||||
if (mag(dims.exponents_[i]) > dimensionSet::smallExponent)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
os << token::SPACE;
|
||||
}
|
||||
|
||||
os << dimensionSet::dimensionTypeNames_
|
||||
[static_cast<dimensionSet::dimensionType>(i)];
|
||||
|
||||
if (dims.exponents_[i] != 1)
|
||||
{
|
||||
os << '^' << dims.exponents_[i];
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
ip.t_.writeInfoNoBeginOrEnd(os);
|
||||
|
||||
os << token::END_SQR;
|
||||
|
||||
|
||||
@ -72,8 +72,8 @@ bool Foam::Function1s::unitConversions::readIfPresent
|
||||
ITstream& is = entryPtr->stream();
|
||||
|
||||
is.readBegin("unitConversions");
|
||||
x.readIfPresent(keyword, dict, is);
|
||||
value.readIfPresent(keyword, dict, is);
|
||||
x.read(keyword, dict, is);
|
||||
value.read(keyword, dict, is);
|
||||
is.readEnd("unitConversions");
|
||||
|
||||
return true;
|
||||
|
||||
@ -90,6 +90,7 @@ Foam::token Foam::symbols::tokeniser::nextToken()
|
||||
if (size_ == 0)
|
||||
{
|
||||
token t(is_);
|
||||
|
||||
if (t.isWord())
|
||||
{
|
||||
splitWord(t.wordToken());
|
||||
@ -175,16 +176,17 @@ bool Foam::symbols::tokeniser::valid(char c)
|
||||
!isspace(c)
|
||||
&& c != '"' // string quote
|
||||
&& c != '\'' // string quote
|
||||
&& c != '/' // div
|
||||
&& c != '/' // divide
|
||||
&& c != ';' // end statement
|
||||
&& c != '{' // beg subdict
|
||||
&& c != '}' // end subdict
|
||||
&& c != '(' // beg expr
|
||||
&& c != ')' // end expr
|
||||
&& c != '[' // beg dim
|
||||
&& c != ']' // end dim
|
||||
&& c != '{' // begin sub-dictionary
|
||||
&& c != '}' // end sub-dictionary
|
||||
&& c != '(' // begin expression
|
||||
&& c != ')' // end expression
|
||||
&& c != '[' // begin dimensions/units
|
||||
&& c != ']' // end dimensions/units
|
||||
&& c != ':' // separate dimensions/units
|
||||
&& c != '^' // power
|
||||
&& c != '*' // mult
|
||||
&& c != '*' // multiply
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@ -124,10 +124,11 @@ Type parseNoBegin
|
||||
const HashTable<Type>& table
|
||||
);
|
||||
|
||||
//- Parse a dimension set or unit conversion, assuming that the '[' has already
|
||||
// been read
|
||||
//- Parse tokens into a dimension set or unit conversion, assuming that the '['
|
||||
// has already been read, and ending before the '[' or ':'. Note that this
|
||||
// will leave the stream with a pushed back token.
|
||||
template<class Type>
|
||||
Type parseNoBegin
|
||||
Type parseNoBeginOrEnd
|
||||
(
|
||||
Istream& is,
|
||||
const Type& identity,
|
||||
|
||||
@ -76,12 +76,19 @@ Type Foam::symbols::parseNoBegin
|
||||
tis.putBack(nextToken);
|
||||
return result;
|
||||
}
|
||||
else if (nextToken.pToken() == token::COLON)
|
||||
{
|
||||
// End the units
|
||||
tis.putBack(nextToken);
|
||||
return result;
|
||||
}
|
||||
else if (nextToken.pToken() == token::BEGIN_LIST)
|
||||
{
|
||||
// Parenthesis. Evaluate the sub-units and multiply.
|
||||
result.reset
|
||||
(
|
||||
result*parseNoBegin(nextPrior, tis, identity, table)
|
||||
result
|
||||
*parseNoBegin(nextPrior, tis, identity, table)
|
||||
);
|
||||
|
||||
// Check that the parentheses end
|
||||
@ -108,7 +115,8 @@ Type Foam::symbols::parseNoBegin
|
||||
// This has priority. Evaluate the next units and multiply.
|
||||
result.reset
|
||||
(
|
||||
result*parseNoBegin(nextPrior, tis, identity, table)
|
||||
result
|
||||
*parseNoBegin(nextPrior, tis, identity, table)
|
||||
);
|
||||
}
|
||||
else
|
||||
@ -127,7 +135,8 @@ Type Foam::symbols::parseNoBegin
|
||||
{
|
||||
result.reset
|
||||
(
|
||||
result/parseNoBegin(nextPrior, tis, identity, table)
|
||||
result
|
||||
/parseNoBegin(nextPrior, tis, identity, table)
|
||||
);
|
||||
}
|
||||
else
|
||||
@ -177,6 +186,7 @@ Type Foam::symbols::parseNoBegin
|
||||
}
|
||||
|
||||
nextToken = tis.nextToken();
|
||||
|
||||
if (nextToken.error())
|
||||
{
|
||||
break;
|
||||
@ -195,7 +205,7 @@ Type Foam::symbols::parseNoBegin
|
||||
|
||||
|
||||
template<class Type>
|
||||
Type Foam::symbols::parseNoBegin
|
||||
Type Foam::symbols::parseNoBeginOrEnd
|
||||
(
|
||||
Istream& is,
|
||||
const Type& identity,
|
||||
@ -204,7 +214,11 @@ Type Foam::symbols::parseNoBegin
|
||||
{
|
||||
symbols::tokeniser tis(is);
|
||||
|
||||
return parseNoBegin(0, tis, identity, table);
|
||||
Type result = parseNoBegin(0, tis, identity, table);
|
||||
|
||||
is.putBack(tis.nextToken());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -219,6 +219,12 @@ public:
|
||||
//- Update
|
||||
void read(const word& keyword, const dictionary&);
|
||||
|
||||
//- Update
|
||||
void read(Istream& is);
|
||||
|
||||
//- Update
|
||||
void read(const word& keyword, const dictionary&, Istream& is);
|
||||
|
||||
//- Update if found in the dictionary
|
||||
bool readIfPresent(const word& keyword, const dictionary&);
|
||||
|
||||
|
||||
@ -47,6 +47,23 @@ void Foam::unitConversion::read(const word& keyword, const dictionary& dict)
|
||||
if (!compare(*this, units, false))
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The units " << units.info() << " of " << keyword
|
||||
<< " in dictionary " << dict.name() << " do not match "
|
||||
<< "the required units " << info()
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
|
||||
reset(units);
|
||||
}
|
||||
|
||||
|
||||
void Foam::unitConversion::read(Istream& is)
|
||||
{
|
||||
const unitConversion units(is);
|
||||
|
||||
if (!compare(*this, units, false))
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "The units " << units.info() << " provided do not match "
|
||||
<< "the required units " << info()
|
||||
<< abort(FatalIOError);
|
||||
@ -56,6 +73,28 @@ void Foam::unitConversion::read(const word& keyword, const dictionary& dict)
|
||||
}
|
||||
|
||||
|
||||
void Foam::unitConversion::read
|
||||
(
|
||||
const word& keyword,
|
||||
const dictionary& dict,
|
||||
Istream& is
|
||||
)
|
||||
{
|
||||
const unitConversion units(is);
|
||||
|
||||
if (!compare(*this, units, false))
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The units " << units.info() << " of " << keyword
|
||||
<< " in dictionary " << dict.name() << " do not match "
|
||||
<< "the required units " << info()
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
|
||||
reset(units);
|
||||
}
|
||||
|
||||
|
||||
bool Foam::unitConversion::readIfPresent
|
||||
(
|
||||
const word& keyword,
|
||||
@ -71,7 +110,8 @@ bool Foam::unitConversion::readIfPresent
|
||||
if (!compare(*this, units, false))
|
||||
{
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The units " << units.info() << " provided do not match "
|
||||
<< "The units " << units.info() << " of " << keyword
|
||||
<< " in dictionary " << dict.name() << " do not match "
|
||||
<< "the required units " << info()
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
@ -102,24 +142,24 @@ bool Foam::unitConversion::readIfPresent(Istream& is)
|
||||
|
||||
if (nextToken != token::BEGIN_SQR) return false;
|
||||
|
||||
unitConversion u(is);
|
||||
const unitConversion units(is);
|
||||
|
||||
if (!unitConversion::compare(u, *this, false))
|
||||
if (!unitConversion::compare(units, *this, false))
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "The units " << u.info() << " provided do not match "
|
||||
<< "The units " << units.info() << " provided do not match "
|
||||
<< "the required units " << info()
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
|
||||
if (debug && (any() || !unitConversion::compare(u, *this, true)))
|
||||
if (debug && (any() || !unitConversion::compare(units, *this, true)))
|
||||
{
|
||||
Info<< "Unit conversion at line " << is.lineNumber()
|
||||
<< " of file " << is.name()
|
||||
<< " with factor " << u.multiplier_ << endl;
|
||||
<< " with factor " << units.multiplier_ << endl;
|
||||
}
|
||||
|
||||
reset(u);
|
||||
reset(units);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -137,25 +177,25 @@ bool Foam::unitConversion::readIfPresent
|
||||
|
||||
if (nextToken != token::BEGIN_SQR) return false;
|
||||
|
||||
unitConversion u(is);
|
||||
const unitConversion units(is);
|
||||
|
||||
if (!unitConversion::compare(u, *this, false))
|
||||
if (!unitConversion::compare(units, *this, false))
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "The units " << u.info() << " of " << keyword
|
||||
FatalIOErrorInFunction(dict)
|
||||
<< "The units " << units.info() << " of " << keyword
|
||||
<< " in dictionary " << dict.name() << " do not match "
|
||||
<< "the required units " << info()
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
|
||||
if (debug && (any() || !unitConversion::compare(u, *this, true)))
|
||||
if (debug && (any() || !unitConversion::compare(units, *this, true)))
|
||||
{
|
||||
Info<< "Unit conversion of " << keyword
|
||||
<< " in dictionary " << dict.name()
|
||||
<< " with factor " << u.multiplier_ << endl;
|
||||
<< " with factor " << units.multiplier_ << endl;
|
||||
}
|
||||
|
||||
reset(u);
|
||||
reset(units);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -165,95 +205,133 @@ bool Foam::unitConversion::readIfPresent
|
||||
|
||||
Foam::Istream& Foam::operator>>(Istream& is, unitConversion& units)
|
||||
{
|
||||
// Read beginning of unitConversion
|
||||
token startToken(is);
|
||||
token nextToken;
|
||||
|
||||
if (startToken != token::BEGIN_SQR)
|
||||
// Read the next delimiting token. This must be the start bracket.
|
||||
is >> nextToken;
|
||||
if (nextToken != token::BEGIN_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::BEGIN_SQR << " in unitConversion"
|
||||
<< endl << "in stream " << is.info()
|
||||
<< exit(FatalIOError);
|
||||
<< endl << "in stream " << is.info() << ", got a "
|
||||
<< nextToken << exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Peek at the next token
|
||||
token nextToken(is);
|
||||
is >> nextToken;
|
||||
is.putBack(nextToken);
|
||||
|
||||
if (!nextToken.isNumber())
|
||||
// If not a number or separator, then these are named units. Parse.
|
||||
if (!nextToken.isNumber() && nextToken != token::COLON)
|
||||
{
|
||||
// Named units. Parse.
|
||||
units.reset(symbols::parseNoBegin(is, unitless, Foam::units()));
|
||||
units.reset(symbols::parseNoBeginOrEnd(is, unitless, Foam::units()));
|
||||
|
||||
// Read the next delimiting token. This must be the end bracket.
|
||||
is >> nextToken;
|
||||
if (nextToken != token::END_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR << " in unitConversion "
|
||||
<< endl << "in stream " << is.info() << ", got a "
|
||||
<< nextToken << exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Check state of Istream
|
||||
is.check("Istream& operator>>(Istream&, unitConversion&)");
|
||||
|
||||
return is;
|
||||
}
|
||||
else
|
||||
|
||||
// Otherwise these are numbered units. Read directly...
|
||||
|
||||
// Read the dimensions
|
||||
units.dimensions_.readNoBeginOrEnd(is);
|
||||
|
||||
// Read the next delimiting token. If a separator, then there are
|
||||
// dimensionless units and a multiplier to read. If it is an end bracket,
|
||||
// then the dimensionless units are zero and the multiplier is one and the
|
||||
// parsing is finished. Otherwise the parsing has failed.
|
||||
is >> nextToken;
|
||||
if (nextToken == token::COLON)
|
||||
{
|
||||
// Read the dimensions
|
||||
units.dimensions_.readNoBegin(is);
|
||||
// Peek at the next token
|
||||
is >> nextToken;
|
||||
is.putBack(nextToken);
|
||||
|
||||
// Read the dimensionless units if present, or set to zero
|
||||
token nextToken;
|
||||
if (!is.eof())
|
||||
{
|
||||
is >> nextToken;
|
||||
}
|
||||
if (nextToken == token::BEGIN_SQR)
|
||||
if (!nextToken.isNumber())
|
||||
{
|
||||
for (int i = 0; i < unitConversion::nDimlessUnits; ++ i)
|
||||
{
|
||||
is >> units.exponents_[i];
|
||||
}
|
||||
|
||||
// Check end of dimensionless units
|
||||
token endToken(is);
|
||||
if (endToken != token::END_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR
|
||||
<< " in unitConversion " << endl << "in stream "
|
||||
<< is.info() << exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Read the multiplier if present, or set to unity
|
||||
token nextToken;
|
||||
if (!is.eof())
|
||||
{
|
||||
is >> nextToken;
|
||||
}
|
||||
if (nextToken == token::BEGIN_SQR)
|
||||
{
|
||||
is >> units.multiplier_;
|
||||
|
||||
// Check end of multiplier
|
||||
token endToken(is);
|
||||
if (endToken != token::END_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR
|
||||
<< " in unitConversion " << endl << "in stream "
|
||||
<< is.info() << exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
units.multiplier_ = 1;
|
||||
if (!nextToken.undefined())
|
||||
{
|
||||
is.putBack(nextToken);
|
||||
}
|
||||
units.exponents_[i] = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < unitConversion::nDimlessUnits; ++ i)
|
||||
{
|
||||
units.exponents_[i] = 0;
|
||||
}
|
||||
units.multiplier_ = 1;
|
||||
if (!nextToken.undefined())
|
||||
{
|
||||
is.putBack(nextToken);
|
||||
is >> units.exponents_[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Read the next delimiting token. If a separator then there is a
|
||||
// multiplier to read. If it is an end bracket then the multiplier is
|
||||
// one and the parsing is finished. Otherwise the parsing has failed.
|
||||
is >> nextToken;
|
||||
if (nextToken == token::COLON)
|
||||
{
|
||||
// Peek at the next token
|
||||
is >> nextToken;
|
||||
is.putBack(nextToken);
|
||||
|
||||
// Read the multiplier if present, or set to unity
|
||||
if (!nextToken.isNumber())
|
||||
{
|
||||
units.multiplier_ = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
is >> units.multiplier_;
|
||||
}
|
||||
|
||||
// Read the next delimiting token. This must be the end bracket.
|
||||
is >> nextToken;
|
||||
if (nextToken != token::END_SQR)
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR << " in unitConversion "
|
||||
<< endl << "in stream " << is.info() << ", got a "
|
||||
<< nextToken << exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
else if (nextToken == token::END_SQR)
|
||||
{
|
||||
units.multiplier_ = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR << " or a " << token::COLON
|
||||
<< " in unitConversion " << endl << "in stream " << is.info()
|
||||
<< ", got a " << nextToken << exit(FatalIOError);
|
||||
}
|
||||
}
|
||||
else if (nextToken == token::END_SQR)
|
||||
{
|
||||
for (int i = 0; i < unitConversion::nDimlessUnits; ++ i)
|
||||
{
|
||||
units.exponents_[i] = 0;
|
||||
}
|
||||
|
||||
units.multiplier_ = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalIOErrorInFunction(is)
|
||||
<< "expected a " << token::END_SQR << " or a " << token::COLON
|
||||
<< " in unitConversion " << endl << "in stream " << is.info()
|
||||
<< ", got a " << nextToken << exit(FatalIOError);
|
||||
}
|
||||
|
||||
// Check state of Istream
|
||||
@ -265,8 +343,11 @@ Foam::Istream& Foam::operator>>(Istream& is, unitConversion& units)
|
||||
|
||||
Foam::Ostream& Foam::operator<<(Ostream& os, const unitConversion& units)
|
||||
{
|
||||
// Write the start
|
||||
os << token::BEGIN_SQR;
|
||||
|
||||
// Write the dimensions
|
||||
os << units.dimensions_;
|
||||
units.dimensions_.writeNoBeginOrEnd(os);
|
||||
|
||||
// Determine if any dimensionless units are non-zero
|
||||
bool nonZeroDimlessUnits = false;
|
||||
@ -280,25 +361,36 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const unitConversion& units)
|
||||
// Determine if the multiplier is non-unity
|
||||
bool nonUnityMultiplier = units.multiplier_ != 1;
|
||||
|
||||
// Write the dimensionless units if any are non-zero or we have a
|
||||
// multiplier to write out afterwards
|
||||
// Write a separator if there is anything to follow
|
||||
if (nonZeroDimlessUnits || nonUnityMultiplier)
|
||||
{
|
||||
os << token::BEGIN_SQR;
|
||||
os << token::SPACE << token::COLON;
|
||||
}
|
||||
|
||||
// Write the dimensionless units if any are non-zero
|
||||
if (nonZeroDimlessUnits)
|
||||
{
|
||||
for (int i = 0; i < unitConversion::nDimlessUnits; ++ i)
|
||||
{
|
||||
if (i) os << token::SPACE;
|
||||
os << units.exponents_[i];
|
||||
os << token::SPACE << units.exponents_[i];
|
||||
}
|
||||
os << token::END_SQR;
|
||||
}
|
||||
|
||||
// Write a separator if there is anything to follow
|
||||
if (nonUnityMultiplier)
|
||||
{
|
||||
os << token::SPACE << token::COLON;
|
||||
}
|
||||
|
||||
// Write the multiplier if it is non-unity
|
||||
if (nonUnityMultiplier)
|
||||
{
|
||||
os << token::BEGIN_SQR << units.multiplier_ << token::END_SQR;
|
||||
os << token::SPACE << units.multiplier_;
|
||||
}
|
||||
|
||||
// Write the end
|
||||
os << token::END_SQR;
|
||||
|
||||
// Check state of Ostream
|
||||
os.check("Ostream& operator<<(Ostream&, const unitConversion&)");
|
||||
|
||||
@ -324,8 +416,11 @@ Foam::Ostream& Foam::operator<<
|
||||
return os << token::BEGIN_SQR << "<none>" << token::END_SQR;
|
||||
}
|
||||
|
||||
// Write the start
|
||||
os << token::BEGIN_SQR;
|
||||
|
||||
// Write the dimensions
|
||||
os << units.dimensions_.info();
|
||||
units.dimensions_.writeInfoNoBeginOrEnd(os);
|
||||
|
||||
// Determine if any dimensionless units are non-zero
|
||||
bool nonZeroDimlessUnits = false;
|
||||
@ -339,43 +434,45 @@ Foam::Ostream& Foam::operator<<
|
||||
// Determine if the multiplier is non-unity
|
||||
bool nonUnityMultiplier = units.multiplier_ != 1;
|
||||
|
||||
// Write the dimensionless units if any are non-zero or we have a
|
||||
// multiplier to write out afterwards
|
||||
// Write a separator if there is anything to follow
|
||||
if (nonZeroDimlessUnits || nonUnityMultiplier)
|
||||
{
|
||||
// Write the dimensionless units
|
||||
os << token::BEGIN_SQR;
|
||||
os << token::SPACE << token::COLON;
|
||||
}
|
||||
|
||||
for (int first=true, i=0; i<unitConversion::nDimlessUnits; i++)
|
||||
// Write the dimensionless units if any are non-zero
|
||||
if (nonZeroDimlessUnits)
|
||||
{
|
||||
for (int i=0; i<unitConversion::nDimlessUnits; i++)
|
||||
{
|
||||
if (mag(units.exponents_[i]) > unitConversion::smallExponent)
|
||||
{
|
||||
if (!first)
|
||||
{
|
||||
os << token::SPACE;
|
||||
}
|
||||
|
||||
os << unitConversion::dimlessUnitTypeNames_
|
||||
os << token::SPACE << unitConversion::dimlessUnitTypeNames_
|
||||
[static_cast<unitConversion::dimlessUnitType>(i)];
|
||||
|
||||
if (units.exponents_[i] != 1)
|
||||
{
|
||||
os << '^' << units.exponents_[i];
|
||||
}
|
||||
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
os << token::END_SQR;
|
||||
// Write a separator if there is anything to follow
|
||||
if (nonUnityMultiplier)
|
||||
{
|
||||
os << token::SPACE << token::COLON;
|
||||
}
|
||||
|
||||
// Write the multiplier if it is non-unity
|
||||
if (nonUnityMultiplier)
|
||||
{
|
||||
os << token::BEGIN_SQR << units.multiplier_ << token::END_SQR;
|
||||
os << token::SPACE << units.multiplier_;
|
||||
}
|
||||
|
||||
// Write the end
|
||||
os << token::END_SQR;
|
||||
|
||||
// Check state of Ostream
|
||||
os.check("Ostream& operator<<(Ostream&, const InfoProxy<unitConversion>&)");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user