Merge branch 'master' of ssh://dm/home/dm4/OpenFOAM/OpenFOAM-dev

This commit is contained in:
Henry
2012-10-08 10:36:51 +01:00
10 changed files with 1183 additions and 160 deletions

View File

@ -981,15 +981,29 @@ DimensionSets
Cd Cd [ 0 0 0 0 0 0 1 ] 1.0;
// Derived units
Pa Pa [ kg^1 m^-2 ] 1.0;
Hz Hz [ s^-1 ] 1.0;
N N [ kg m s^-2 ] 1.0;
Pa Pa [ N m^-2 ] 1.0;
J J [ N m ] 1.0;
W W [ J s^-1 ] 1.0;
// Scaled units
mm mm [ kg^1 m^-2 ] 1e-3;
// Some non-symbolic ones
area area [m^2] 1.0;
volume volume [m^3] 1.0;
density density [ kg m^-3 ] 1.0;
acceleration acceleration [ m s^-2 ] 1.0;
kinematicPressure kinematicPressure [ Pa density^-1 ] 1.0;
// Scaled units. Only allowed in dymensionedType (dimensionedScalar,
// dimensionedVector etc.) and UniformDimensionedField, not
// in DimensionedField or GeometricField
cm cm [ m ] 1e-2;
mm mm [ m ] 1e-3;
km km [ m ] 1e3;
// Set of units used for printing. Can be any basic or derived
// but not scaled (only supported for dimensionedScalar, etc)
writeUnits (kg m s K mol A Cd);
//writeUnits (kg m s K mol A Cd);
}
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -105,83 +105,6 @@ void Foam::dimensionSet::reset(const dimensionSet& ds)
}
Foam::string Foam::dimensionSet::asText() const
{
OStringStream buf;
bool Dimensionless = true;
for (int Dimension=0; Dimension < dimensionSet::nDimensions-1; ++Dimension)
{
const scalar& expt = exponents_[Dimension];
if (expt < smallExponent && expt > -smallExponent)
{
continue;
}
if (Dimensionless)
{
Dimensionless = false;
}
else
{
buf << ' ';
}
// note: currently only handle SI
switch (Dimension)
{
case MASS:
buf << "kg";
break;
case LENGTH:
buf << "m";
break;
case TIME:
buf << "s";
break;
case TEMPERATURE:
buf << "K";
break;
case MOLES:
buf << "mol";
break;
case CURRENT:
buf << "A";
break;
case LUMINOUS_INTENSITY:
buf << "Cd";
break;
default:
buf << "??"; // this shouldn't be - flag as being weird
break;
}
if (expt != 1)
{
buf << '^' << expt;
}
}
if (Dimensionless)
{
return "none";
}
else
{
return buf.str();
}
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
Foam::scalar Foam::dimensionSet::operator[](const dimensionType type) const
@ -196,6 +119,18 @@ Foam::scalar& Foam::dimensionSet::operator[](const dimensionType type)
}
Foam::scalar Foam::dimensionSet::operator[](const label type) const
{
return exponents_[type];
}
Foam::scalar& Foam::dimensionSet::operator[](const label type)
{
return exponents_[type];
}
bool Foam::dimensionSet::operator==(const dimensionSet& ds) const
{
for (int Dimension=0; Dimension < nDimensions; ++Dimension)

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -40,10 +40,12 @@ SourceFiles
#ifndef dimensionSet_H
#define dimensionSet_H
#include "scalar.H"
#include "bool.H"
#include "dimensionedScalarFwd.H"
#include "className.H"
#include "scalarField.H"
#include "PtrList.H"
#include "HashTable.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -53,6 +55,7 @@ namespace Foam
// Forward declaration of friend functions and operators
class dimensionSet;
class dimensionSets;
// Friend functions
@ -140,6 +143,64 @@ public:
private:
// Private classes
class tokeniser
{
// Private data
Istream& is_;
List<token> tokens_;
label start_;
label size_;
// Private Member Functions
void push(const token&);
token pop();
void unpop(const token&);
public:
// Constructors
tokeniser(Istream&);
// Member Functions
Istream& stream()
{
return is_;
}
bool hasToken() const;
token nextToken();
void putBack(const token&);
void splitWord(const word&);
static bool valid(char c);
static label priority(const token& t);
};
dimensionedScalar parse
(
const label lastPrior,
tokeniser& tis,
const HashTable<dimensionedScalar>&
) const;
// private data
// dimensionSet stored as an array of dimension exponents
@ -189,14 +250,56 @@ public:
void reset(const dimensionSet&);
//- Return a text representation for added readability
string asText() const;
// I/O
//- Read using provided units. Used only in initial parsing
Istream& read
(
Istream& is,
scalar& multiplier,
const dictionary&
);
//- Read using provided units
Istream& read
(
Istream& is,
scalar& multiplier,
const HashTable<dimensionedScalar>&
);
//- Read using system units
Istream& read
(
Istream& is,
scalar& multiplier
);
//- Write using provided units
Ostream& write
(
Ostream& os,
scalar& multiplier,
const dimensionSets&
) const;
//- Write using system units
Ostream& write
(
Ostream& os,
scalar& multiplier
) const;
// Member operators
scalar operator[](const dimensionType) const;
scalar& operator[](const dimensionType);
scalar operator[](const label) const;
scalar& operator[](const label);
bool operator==(const dimensionSet&) const;
bool operator!=(const dimensionSet&) const;

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -25,6 +25,7 @@ License
#include "dimensionSet.H"
#include "IOstreams.H"
#include "dimensionedScalar.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -34,46 +35,670 @@ Foam::dimensionSet::dimensionSet(Istream& is)
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::dimensionSet::tokeniser::tokeniser(Istream& is)
:
is_(is),
tokens_(100),
start_(0),
size_(0)
{}
Foam::Istream& Foam::operator>>(Istream& is, dimensionSet& dset)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::dimensionSet::tokeniser::push(const token& t)
{
// Read begining of dimensionSet
if (token(is) != token::BEGIN_SQR)
label end = (start_+size_)%tokens_.size();
tokens_[end] = t;
if (size_ == tokens_.size())
{
Info<< "expected a " << token::BEGIN_SQR << " in dimensionSet"
<< endl << "in stream " << is.info() << endl;
start_ = tokens_.fcIndex(start_);
}
else
{
size_++;
}
}
Foam::token Foam::dimensionSet::tokeniser::pop()
{
token t = tokens_[start_];
start_ = tokens_.fcIndex(start_);
--size_;
return t;
}
void Foam::dimensionSet::tokeniser::unpop(const token& t)
{
++size_;
start_ = tokens_.rcIndex(start_);
tokens_[start_] = t;
}
bool Foam::dimensionSet::tokeniser::hasToken() const
{
return size_ || is_.good();
}
bool Foam::dimensionSet::tokeniser::valid(char c)
{
return
(
!isspace(c)
&& c != '"' // string quote
&& c != '\'' // string quote
&& c != '/' // div
&& c != ';' // end statement
&& c != '{' // beg subdict
&& c != '}' // end subdict
&& c != '(' // beg expr
&& c != ')' // end expr
&& c != '[' // beg dim
&& c != ']' // end dim
&& c != '^' // power
&& c != '*' // mult
);
}
Foam::label Foam::dimensionSet::tokeniser::priority(const token& t)
{
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;
}
}
void Foam::dimensionSet::tokeniser::splitWord(const word& w)
{
size_t start = 0;
for (size_t i=0; i<w.size(); ++i)
{
if (!valid(w[i]))
{
if (i > start)
{
word subWord = w(start, i-start);
if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
{
push(token(readLabel(IStringStream(subWord)())));
}
else
{
push(token(subWord));
}
}
if (w[i] != token::SPACE)
{
if (isdigit(w[i]))
{
push(token(readLabel(IStringStream(w[i])())));
}
else
{
push(token::punctuationToken(w[i]));
}
}
start = i+1;
}
}
if (start < w.size())
{
word subWord = w(start, w.size()-start);
if (isdigit(subWord[0]) || subWord[0] == token::SUBTRACT)
{
push(token(readLabel(IStringStream(subWord)())));
}
else
{
push(token(subWord));
}
}
}
Foam::token Foam::dimensionSet::tokeniser::nextToken()
{
if (size_ == 0)
{
token t(is_);
if (t.isWord())
{
splitWord(t.wordToken());
return pop();
}
else
{
return t;
}
}
else
{
return pop();
}
}
void Foam::dimensionSet::tokeniser::putBack(const token& t)
{
if (size_ == 0)
{
push(t);
}
else
{
unpop(t);
}
}
Foam::dimensionedScalar Foam::dimensionSet::parse
(
const label lastPrior,
tokeniser& tis,
const HashTable<dimensionedScalar>& readSet
) const
{
dimensionedScalar ds("", dimless, 1.0);
// Get initial token
token nextToken(tis.nextToken());
// Store type of last token read. Used to detect two consecutive
// symbols and assume multiplication
bool haveReadSymbol = false;
while (true)
{
if (nextToken.isWord())
{
const word& unitName = nextToken.wordToken();
const dimensionedScalar& unitDim = readSet[unitName];
ds.dimensions() *= unitDim.dimensions();
ds.value() *= unitDim.value();
haveReadSymbol = true;
}
else if (nextToken.isNumber())
{
// no dimensions, just value
ds.value() *= nextToken.number();
haveReadSymbol = true;
}
else if (nextToken.isPunctuation())
{
label nextPrior = tokeniser::priority(nextToken);
if (nextToken.pToken() == token::BEGIN_SQR)
{
// No idea when this will happen
tis.putBack(nextToken);
return ds;
}
else if (nextToken.pToken() == token::END_SQR)
{
tis.putBack(nextToken);
return ds;
}
else if (nextToken.pToken() == token::BEGIN_LIST)
{
dimensionedScalar sub(parse(nextPrior, tis, readSet));
token t = tis.nextToken();
if (!t.isPunctuation() || t.pToken() != token::END_LIST)
{
FatalIOErrorIn
(
"dimensionSet::parse"
"(const label, tokeniser&"
", const HashTable<dimensionedScalar>&)",
tis.stream()
) << "Illegal token " << t << exit(FatalIOError);
}
ds.dimensions() *= sub.dimensions();
ds.value() *= sub.value();
haveReadSymbol = true;
}
else if (nextToken.pToken() == token::END_LIST)
{
tis.putBack(nextToken);
return ds;
}
else if (nextToken.pToken() == token::MULTIPLY)
{
if (nextPrior > lastPrior)
{
dimensionedScalar sub(parse(nextPrior, tis, readSet));
ds.dimensions() *= sub.dimensions();
ds.value() *= sub.value();
}
else
{
// Restore token
tis.putBack(nextToken);
return ds;
}
haveReadSymbol = false;
}
else if (nextToken.pToken() == token::DIVIDE)
{
if (nextPrior > lastPrior)
{
dimensionedScalar sub(parse(nextPrior, tis, readSet));
ds.dimensions() /= sub.dimensions();
ds.value() /= sub.value();
}
else
{
tis.putBack(nextToken);
return ds;
}
haveReadSymbol = false;
}
else if (nextToken.pToken() == '^')
{
if (nextPrior > lastPrior)
{
dimensionedScalar exp(parse(nextPrior, tis, readSet));
ds.dimensions().reset(pow(ds.dimensions(), exp.value()));
ds.value() = Foam::pow(ds.value(), exp.value());
}
else
{
tis.putBack(nextToken);
return ds;
}
haveReadSymbol = false;
}
else
{
FatalIOErrorIn
(
"dimensionSet::parse"
"(const label, tokeniser&"
", const HashTable<dimensionedScalar>&)",
tis.stream()
) << "Illegal token " << nextToken << exit(FatalIOError);
}
}
else
{
FatalIOErrorIn
(
"dimensionSet::parse"
"(const label, tokeniser&"
", const HashTable<dimensionedScalar>&)",
tis.stream()
) << "Illegal token " << nextToken << exit(FatalIOError);
}
if (!tis.hasToken())
{
break;
}
nextToken = tis.nextToken();
if (nextToken.error())
{
break;
}
if (haveReadSymbol && (nextToken.isWord() || nextToken.isNumber()))
{
// Two consecutive symbols. Assume multiplication
tis.putBack(nextToken);
nextToken = token(token::MULTIPLY);
}
}
// Read first five dimensions
for (int Dimension=0; Dimension<dimensionSet::CURRENT; Dimension++)
return ds;
}
Foam::Istream& Foam::dimensionSet::read
(
Istream& is,
scalar& multiplier,
const HashTable<dimensionedScalar>& readSet
)
{
multiplier = 1.0;
// Read begining of dimensionSet
token startToken(is);
if (startToken != token::BEGIN_SQR)
{
is >> dset.exponents_[Dimension];
FatalIOErrorIn
(
"dimensionSet::read"
"(Istream&, scalar&, const HashTable<dimensionedScalar>&)",
is
) << "expected a " << token::BEGIN_SQR << " in dimensionSet"
<< endl << "in stream " << is.info()
<< exit(FatalIOError);
}
// Read next token
token nextToken(is);
// If next token is another number
// read last two dimensions
// and then read another token for the end of the dimensionSet
if (nextToken.isNumber())
if (!nextToken.isNumber())
{
dset.exponents_[dimensionSet::CURRENT] = nextToken.number();
is >> dset.exponents_[dimensionSet::LUMINOUS_INTENSITY];
is >> nextToken;
is.putBack(nextToken);
tokeniser tis(is);
dimensionedScalar ds(parse(0, tis, readSet));
multiplier = ds.value();
for (int i=0; i < dimensionSet::nDimensions; ++i)
{
exponents_[i] += ds.dimensions()[i];
}
}
else
{
dset.exponents_[dimensionSet::CURRENT] = 0;
dset.exponents_[dimensionSet::LUMINOUS_INTENSITY] = 0;
// 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
// read 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)
{
FatalIOErrorIn
(
"dimensionSet::read"
"(Istream&, scalar&, const HashTable<dimensionedScalar>&)",
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::Istream& Foam::dimensionSet::read
(
Istream& is,
scalar& multiplier
)
{
return read(is, multiplier, unitSet());
}
Foam::Istream& Foam::dimensionSet::read
(
Istream& is,
scalar& multiplier,
const dictionary& readSet
)
{
multiplier = 1.0;
// Read begining of dimensionSet
token startToken(is);
if (startToken != token::BEGIN_SQR)
{
FatalIOErrorIn
(
"dimensionSet::read"
"(Istream&, scalar&, const dictionary&)",
is
) << "expected a " << token::BEGIN_SQR << " in dimensionSet"
<< endl << "in stream " << is.info()
<< exit(FatalIOError);
}
// Check end of dimensionSet
if (nextToken != token::END_SQR)
// Read next token
token nextToken(is);
if (nextToken.isWord())
{
Info<< "expected a " << token::END_SQR << " in dimensionSet"
<< endl << "in stream " << is.info() << endl;
bool continueParsing = true;
do
{
word symbolPow = nextToken.wordToken();
if (symbolPow[symbolPow.size()-1] == token::END_SQR)
{
symbolPow = symbolPow(0, symbolPow.size()-1);
continueParsing = false;
}
// Parse unit
dimensionSet symbolSet(dimless);
size_t index = symbolPow.find('^');
if (index != string::npos)
{
word symbol = symbolPow(0, index);
word exp = symbolPow(index+1, symbolPow.size()-index+1);
scalar exponent = readScalar(IStringStream(exp)());
dimensionedScalar s;
s.read(readSet[symbol], readSet);
symbolSet.reset(pow(s.dimensions(), exponent));
multiplier *= Foam::pow(s.value(), exponent);
}
else
{
dimensionedScalar s;
s.read(readSet[symbolPow], readSet);
symbolSet.reset(s.dimensions());
multiplier *= s.value();
}
// Add dimensions without checking
for (int i=0; i < dimensionSet::nDimensions; ++i)
{
exponents_[i] += symbolSet[i];
}
if (continueParsing)
{
nextToken = token(is);
if (!nextToken.isWord() || nextToken == token::END_SQR)
{
continueParsing = false;
}
}
}
while (continueParsing);
}
else
{
// 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
// read 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)
{
FatalIOErrorIn
(
"dimensionSet::read"
"(Istream&, scalar&, const dictionary&)",
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::write
(
Ostream& os,
scalar& multiplier,
const dimensionSets& writeUnits
) const
{
multiplier = 1.0;
os << token::BEGIN_SQR;
if (writeUnits.valid())
{
scalarField exponents(dimensionSet::nDimensions);
for (int d=0; d<dimensionSet::nDimensions; d++)
{
exponents[d] = exponents_[d];
}
writeUnits.coefficients(exponents);
bool hasPrinted = false;
forAll(exponents, i)
{
if (mag(exponents[i]) > smallExponent)
{
const dimensionedScalar& ds = writeUnits.units()[i];
if (hasPrinted)
{
os << token::SPACE;
}
hasPrinted = true;
os << ds.name();
if (mag(exponents[i]-1) > smallExponent)
{
os << '^' << exponents[i];
multiplier *= Foam::pow(ds.value(), exponents[i]);
}
else
{
multiplier *= ds.value();
}
}
}
}
else
{
for (int d=0; d<dimensionSet::nDimensions-1; d++)
{
os << exponents_[d] << token::SPACE;
}
os << exponents_[dimensionSet::nDimensions-1];
}
os << token::END_SQR;
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const dimensionSet&)");
return os;
}
Foam::Ostream& Foam::dimensionSet::write
(
Ostream& os,
scalar& multiplier
) const
{
return write(os, multiplier, writeUnitSet());
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, dimensionSet& dset)
{
scalar multiplier;
dset.read(is, multiplier);
if (mag(multiplier-1.0) > dimensionSet::smallExponent)
{
FatalIOErrorIn("Foam::operator>>(Istream&, dimensionSet&)", is)
<< "Cannot use scaled units in dimensionSet"
<< exit(FatalIOError);
}
// Check state of Istream
@ -85,13 +710,8 @@ Foam::Istream& Foam::operator>>(Istream& is, dimensionSet& dset)
Foam::Ostream& Foam::operator<<(Ostream& os, const dimensionSet& dset)
{
os << token::BEGIN_SQR;
for (int Dimension=0; Dimension<dimensionSet::nDimensions-1; Dimension++)
{
os << dset.exponents_[Dimension] << token::SPACE;
}
os << dset.exponents_[dimensionSet::nDimensions-1] << token::END_SQR;
scalar multiplier;
dset.write(os, multiplier);
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const dimensionSet&)");

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,34 +24,210 @@ License
\*---------------------------------------------------------------------------*/
#include "dimensionSet.H"
#include "dimensionedScalar.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const Foam::dimensionSet Foam::dimless(0, 0, 0, 0, 0, 0, 0);
namespace Foam
{
const Foam::dimensionSet Foam::dimMass(1, 0, 0, 0, 0, 0, 0);
const Foam::dimensionSet Foam::dimLength(0, 1, 0, 0, 0, 0, 0);
const Foam::dimensionSet Foam::dimTime(0, 0, 1, 0, 0, 0, 0);
const Foam::dimensionSet Foam::dimTemperature(0, 0, 0, 1, 0, 0, 0);
const Foam::dimensionSet Foam::dimMoles(0, 0, 0, 0, 1, 0, 0);
const Foam::dimensionSet Foam::dimCurrent(0, 0, 0, 0, 0, 1, 0);
const Foam::dimensionSet Foam::dimLuminousIntensity(0, 0, 0, 0, 0, 0, 1);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
const Foam::dimensionSet Foam::dimArea(sqr(dimLength));
const Foam::dimensionSet Foam::dimVolume(pow3(dimLength));
const Foam::dimensionSet Foam::dimVol(dimVolume);
dictionary* dimensionSystemsPtr_(NULL);
const Foam::dimensionSet Foam::dimVelocity(dimLength/dimTime);
const Foam::dimensionSet Foam::dimAcceleration(dimVelocity/dimTime);
dictionary& dimensionSystems()
{
return debug::switchSet
(
"DimensionSets",
dimensionSystemsPtr_
);
}
const Foam::dimensionSet Foam::dimDensity(dimMass/dimVolume);
const Foam::dimensionSet Foam::dimForce(dimMass*dimAcceleration);
const Foam::dimensionSet Foam::dimEnergy(dimForce*dimLength);
const Foam::dimensionSet Foam::dimPower(dimEnergy/dimTime);
const Foam::dimensionSet Foam::dimPressure(dimForce/dimArea);
const Foam::dimensionSet Foam::dimGasConstant(dimEnergy/dimMass/dimTemperature);
const Foam::dimensionSet Foam::dimSpecificHeatCapacity(dimGasConstant);
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
autoPtr<HashTable<dimensionedScalar> > unitSetPtr_;
autoPtr<dimensionSets> writeUnitSetPtr_;
const HashTable<dimensionedScalar>& unitSet()
{
if (!unitSetPtr_.valid())
{
const dictionary& dict = dimensionSystems();
if (!dict.found("unitSet"))
{
FatalIOErrorIn("unitSet()", dict)
<< "Cannot find unitSet in dictionary " << dict.name()
<< exit(FatalIOError);
}
const word unitSetCoeffs(word(dict.lookup("unitSet")) + "Coeffs");
if (!dict.found(unitSetCoeffs))
{
FatalIOErrorIn("unitSet()", dict)
<< "Cannot find " << unitSetCoeffs << " in dictionary "
<< dict.name() << exit(FatalIOError);
}
const dictionary& unitDict = dict.subDict(unitSetCoeffs);
unitSetPtr_.reset
(
new HashTable<dimensionedScalar>(unitDict.size())
);
forAllConstIter(dictionary, unitDict, iter)
{
if (iter().keyword() != "writeUnits")
{
dimensionedScalar dt;
dt.read(iter().stream(), unitDict);
bool ok = unitSetPtr_->insert(iter().keyword(), dt);
if (!ok)
{
FatalIOErrorIn("unitSet()", dict)
<< "Duplicate unit " << iter().keyword()
<< " in DimensionSets dictionary"
<< exit(FatalIOError);
}
}
}
wordList writeUnitNames
(
unitDict.lookupOrDefault<wordList>
(
"writeUnits",
wordList(0)
)
);
writeUnitSetPtr_.reset
(
new dimensionSets
(
unitSetPtr_(),
writeUnitNames
)
);
if (writeUnitNames.size() != 0 && writeUnitNames.size() != 7)
{
FatalIOErrorIn("unitSet()", dict)
<< "Cannot find entry \"writeUnits\" in " << unitDict.name()
<< " or it is not a wordList of size 7"
<< exit(FatalIOError);
}
}
return unitSetPtr_();
}
const dimensionSets& writeUnitSet()
{
if (!writeUnitSetPtr_.valid())
{
(void)unitSet();
}
return writeUnitSetPtr_();
}
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0);
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0);
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0);
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0);
const dimensionSet dimTemperature(0, 0, 0, 1, 0, 0, 0);
const dimensionSet dimMoles(0, 0, 0, 0, 1, 0, 0);
const dimensionSet dimCurrent(0, 0, 0, 0, 0, 1, 0);
const dimensionSet dimLuminousIntensity(0, 0, 0, 0, 0, 0, 1);
const dimensionSet dimArea(sqr(dimLength));
const dimensionSet dimVolume(pow3(dimLength));
const dimensionSet dimVol(dimVolume);
const dimensionSet dimVelocity(dimLength/dimTime);
const dimensionSet dimAcceleration(dimVelocity/dimTime);
const dimensionSet dimDensity(dimMass/dimVolume);
const dimensionSet dimForce(dimMass*dimAcceleration);
const dimensionSet dimEnergy(dimForce*dimLength);
const dimensionSet dimPower(dimEnergy/dimTime);
const dimensionSet dimPressure(dimForce/dimArea);
const dimensionSet dimGasConstant(dimEnergy/dimMass/dimTemperature);
const dimensionSet dimSpecificHeatCapacity(dimGasConstant);
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dimensionSets::dimensionSets
(
const HashTable<dimensionedScalar>& units,
const wordList& unitNames
)
:
units_(unitNames.size()),
conversion_(unitNames.size()),
conversionPivots_(unitNames.size()),
valid_(false)
{
forAll(unitNames, i)
{
units_.set
(
i,
new dimensionedScalar
(
units[unitNames[i]]
)
);
}
if (unitNames.size() == 7)
{
valid_ = true;
// Determine conversion from basic units to write units
for (label rowI = 0; rowI < conversion_.n(); rowI++)
{
scalar* row = conversion_[rowI];
for (label columnI = 0; columnI < conversion_.m(); columnI++)
{
const dimensionedScalar& dSet = units_[columnI];
row[columnI] = dSet.dimensions()[rowI];
}
}
conversionPivots_.setSize(conversion_.n());
LUDecompose(conversion_, conversionPivots_);
//- possibly some optimisation here to detect identity matri
//if
//(
// conversionPivots_ == identity(conversionPivots_.size())
// && conversion_ == I)
//)
//{
// identity_ = true;
//}
}
}
void Foam::dimensionSets::coefficients(scalarField& exponents) const
{
LUBacksubstitute(conversion_, conversionPivots_, exponents);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -36,6 +36,10 @@ SourceFiles
#ifndef dimensionSets_H
#define dimensionSets_H
#include "scalarMatrices.H"
#include "dimensionedScalarFwd.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -69,6 +73,65 @@ extern const dimensionSet dimGasConstant;
extern const dimensionSet dimSpecificHeatCapacity;
class dimensionSets
{
// Private data
//- Set of dimensions
PtrList<dimensionedScalar> units_;
//- LU decomposition of dimensions
scalarSquareMatrix conversion_;
//- See above
labelList conversionPivots_;
//- Is LU decomposition valid
bool valid_;
public:
// Constructors
//- Construct from all units and set of units to use for inversion
// (writing)
dimensionSets
(
const HashTable<dimensionedScalar>&,
const wordList& unitNames
);
// Member functions
//- Return the units
const PtrList<dimensionedScalar>& units() const
{
return units_;
}
//- Is there a valid inverse of the selected unit
bool valid() const
{
return valid_;
}
//- (if valid) obtain set of coefficients of unitNames
void coefficients(scalarField&) const;
};
//- Top level dictionary
dictionary& dimensionSystems();
//- Set of all dimensions
const HashTable<dimensionedScalar>& unitSet();
//- Set of units
const dimensionSets& writeUnitSet();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View File

@ -97,10 +97,10 @@ dimensioned<Type>::dimensioned
Istream& is
)
:
name_(is),
dimensions_(is),
value_(pTraits<Type>(is))
{}
dimensions_(dimless)
{
read(is);
}
template <class Type>
@ -111,9 +111,13 @@ dimensioned<Type>::dimensioned
)
:
name_(name),
dimensions_(is),
value_(pTraits<Type>(is))
{}
dimensions_(dimless)
{
scalar multiplier;
dimensions_.read(is, multiplier);
is >> value_;
value_ *= multiplier;
}
template <class Type>
@ -141,24 +145,29 @@ dimensioned<Type>::dimensioned
}
// If the dimensions are provided compare with the argument
scalar multiplier = 1.0;
if (nextToken == token::BEGIN_SQR)
{
dimensionSet dims(is);
dimensionSet dims(dimless);
dims.read(is, multiplier);
if (dims != dimensions_)
{
FatalErrorIn
FatalIOErrorIn
(
"dimensioned<Type>::dimensioned"
"(const word&, const dimensionSet&, Istream&)"
"(const word&, const dimensionSet&, Istream&)",
is
) << "The dimensions " << dims
<< " provided do not match the required dimensions "
<< dimensions_
<< abort(FatalError);
<< abort(FatalIOError);
}
}
is >> value_;
value_ *= multiplier;
}
@ -247,6 +256,83 @@ bool dimensioned<Type>::readIfPresent(const dictionary& dict)
}
template <class Type>
Foam::Istream& dimensioned<Type>::read(Istream& is, const dictionary& readSet)
{
// Read name
is >> name_;
// Read dimensionSet + multiplier
scalar mult;
dimensions_.read(is, mult, readSet);
// Read value
is >> value_;
value_ *= mult;
// Check state of Istream
is.check
(
"Istream& dimensioned<Type>::read(Istream& is, const dictionary&)"
);
return is;
}
template <class Type>
Foam::Istream& dimensioned<Type>::read
(
Istream& is,
const HashTable<dimensionedScalar>& readSet
)
{
// Read name
is >> name_;
// Read dimensionSet + multiplier
scalar mult;
dimensions_.read(is, mult, readSet);
// Read value
is >> value_;
value_ *= mult;
// Check state of Istream
is.check
(
"Istream& dimensioned<Type>::read"
"(Istream& is, const HashTable<dimensionedScalar>&)"
);
return is;
}
template <class Type>
Foam::Istream& dimensioned<Type>::read(Istream& is)
{
// Read name
is >> name_;
// Read dimensionSet + multiplier
scalar mult;
dimensions_.read(is, mult);
// Read value
is >> value_;
value_ *= mult;
// Check state of Istream
is.check
(
"Istream& dimensioned<Type>::read(Istream& is)"
);
return is;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template <class Type>
@ -414,13 +500,15 @@ Istream& operator>>(Istream& is, dimensioned<Type>& dt)
}
// If the dimensions are provided reset the dimensions to those read
scalar multiplier = 1.0;
if (nextToken == token::BEGIN_SQR)
{
is >> dt.dimensions_;
dt.dimensions_.read(is, multiplier);
}
// Read the value
is >> dt.value_;
dt.value_ *= multiplier;
// Check state of Istream
is.check("Istream& operator>>(Istream&, dimensioned<Type>&)");
@ -432,10 +520,17 @@ Istream& operator>>(Istream& is, dimensioned<Type>& dt)
template <class Type>
Ostream& operator<<(Ostream& os, const dimensioned<Type>& dt)
{
// do a stream write op for a dimensions()et
os << dt.name() << token::SPACE
<< dt.dimensions() << token::SPACE
<< dt.value();
// Write the name
os << dt.name() << token::SPACE;
// Write the dimensions
scalar mult;
dt.dimensions().write(os, mult);
os << token::SPACE;
// Write the value
os << dt.value()/mult;
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const dimensioned<Type>&)");

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -163,6 +163,17 @@ public:
bool readIfPresent(const dictionary&);
// I/O
//- Read using provided units. Only used during startup.
Istream& read(Istream& is, const dictionary&);
//- Read using provided units
Istream& read(Istream& is, const HashTable<dimensionedScalar>&);
//- Read using system units
Istream& read(Istream& is);
// Member operators
//- Return a component as a dimensioned<cmptType>

View File

@ -48,8 +48,10 @@ Foam::UniformDimensionedField<Type>::UniformDimensionedField
)
{
dictionary dict(readStream(typeName));
this->dimensions().reset(dict.lookup("dimensions"));
scalar multiplier;
this->dimensions().read(dict.lookup("dimensions"), multiplier);
dict.lookup("value") >> this->value();
this->value() *= multiplier;
}
}
@ -75,8 +77,10 @@ Foam::UniformDimensionedField<Type>::UniformDimensionedField
dimensioned<Type>(regIOobject::name(), dimless, pTraits<Type>::zero)
{
dictionary dict(readStream(typeName));
this->dimensions().reset(dict.lookup("dimensions"));
scalar multiplier;
this->dimensions().read(dict.lookup("dimensions"), multiplier);
dict.lookup("value") >> this->value();
this->value() *= multiplier;
}
@ -92,9 +96,11 @@ Foam::UniformDimensionedField<Type>::~UniformDimensionedField()
template<class Type>
bool Foam::UniformDimensionedField<Type>::writeData(Ostream& os) const
{
os.writeKeyword("dimensions") << this->dimensions() << token::END_STATEMENT
scalar multiplier;
os.writeKeyword("dimensions");
this->dimensions().write(os, multiplier) << token::END_STATEMENT
<< nl;
os.writeKeyword("value") << this->value() << token::END_STATEMENT
os.writeKeyword("value") << this->value()/multiplier << token::END_STATEMENT
<< nl << nl;
return (os.good());

View File

@ -113,7 +113,7 @@ bool Foam::radiation::radiationModel::read()
lookup("radiation") >> radiation_;
coeffs_ = subDict(type() + "Coeffs");
lookupOrDefault<label>("solverFreq", 1) >> solverFreq_;
solverFreq_ = lookupOrDefault<label>("solverFreq", 1);
solverFreq_ = max(1, solverFreq_);
return true;