Added a mole fraction State change capability.
This commit is contained in:
parent
d3ffe3bd95
commit
66a7fcc92d
2 changed files with 539 additions and 472 deletions
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
*
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*
|
||||
|
|
@ -28,15 +28,26 @@ using namespace std;
|
|||
|
||||
namespace Cantera {
|
||||
|
||||
State::State() : m_kk(0), m_temp(0.0), m_dens(0.001), m_mmw(0.0) {}
|
||||
State::State() :
|
||||
m_kk(0),
|
||||
m_temp(0.0),
|
||||
m_dens(0.001),
|
||||
m_mmw(0.0),
|
||||
m_stateNum(-1)
|
||||
{
|
||||
}
|
||||
|
||||
State::~State() {}
|
||||
State::~State()
|
||||
{
|
||||
}
|
||||
|
||||
State::State(const State& right) :
|
||||
m_kk(0),
|
||||
m_temp(0.0),
|
||||
m_dens(0.001),
|
||||
m_mmw(0.0) {
|
||||
m_mmw(0.0),
|
||||
m_stateNum(-1)
|
||||
{
|
||||
/*
|
||||
* Call the assignment operator.
|
||||
*/
|
||||
|
|
@ -63,174 +74,214 @@ namespace Cantera {
|
|||
m_y = right.m_y;
|
||||
m_molwts = right.m_molwts;
|
||||
m_rmolwts = right.m_rmolwts;
|
||||
m_stateNum = -1;
|
||||
/*
|
||||
* Return the reference to the current object
|
||||
*/
|
||||
return *this;
|
||||
}
|
||||
|
||||
doublereal State::moleFraction(int k) const {
|
||||
if (k >= 0 && k < m_kk) {
|
||||
return m_ym[k] * m_mmw;
|
||||
}
|
||||
else {
|
||||
throw CanteraError("State:moleFraction",
|
||||
"illegal species index number");
|
||||
}
|
||||
doublereal State::moleFraction(const int k) const {
|
||||
if (k >= 0 && k < m_kk) {
|
||||
return m_ym[k] * m_mmw;
|
||||
}
|
||||
else {
|
||||
throw CanteraError("State:moleFraction",
|
||||
"illegal species index number");
|
||||
}
|
||||
}
|
||||
|
||||
void State::setMoleFractions(const doublereal* const x) {
|
||||
doublereal sum = dot(x, x + m_kk, m_molwts.begin());
|
||||
doublereal rsum = 1.0/sum;
|
||||
transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rsum));
|
||||
transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
|
||||
m_y.begin(), multiplies<double>());
|
||||
doublereal norm = accumulate(x, x + m_kk, 0.0);
|
||||
m_mmw = sum/norm;
|
||||
|
||||
//! Call a routine to determin whether state has changed.
|
||||
stateMFChangeCalc();
|
||||
}
|
||||
|
||||
void State::setMoleFractions_NoNorm(const doublereal* const x) {
|
||||
m_mmw = dot(x, x + m_kk, m_molwts.begin());
|
||||
doublereal rmmw = 1.0/m_mmw;
|
||||
transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rmmw));
|
||||
transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
|
||||
m_y.begin(), multiplies<double>());
|
||||
|
||||
//! Call a routine to determin whether state has changed.
|
||||
stateMFChangeCalc();
|
||||
}
|
||||
|
||||
doublereal State::massFraction(const int k) const {
|
||||
if (k >= 0 && k < m_kk) {
|
||||
return m_y[k];
|
||||
}
|
||||
else {
|
||||
throw CanteraError("State:massFraction",
|
||||
"illegal species index number");
|
||||
}
|
||||
}
|
||||
|
||||
doublereal State::concentration(const int k) const {
|
||||
if (k >= 0 && k < m_kk) {
|
||||
return m_y[k] * m_dens * m_rmolwts[k] ;
|
||||
}
|
||||
else {
|
||||
throw CanteraError("State:massFraction",
|
||||
"illegal species index number");
|
||||
}
|
||||
}
|
||||
|
||||
void State::setMassFractions(const doublereal* const y) {
|
||||
doublereal norm = 0.0, sum = 0.0;
|
||||
//cblas_dcopy(m_kk, y, 1, m_y.begin(), 1);
|
||||
norm = accumulate(y, y + m_kk, 0.0);
|
||||
copy(y, y + m_kk, m_y.begin());
|
||||
scale(y, y + m_kk, m_y.begin(), 1.0/norm);
|
||||
// for (k = 0; k != m_kk; ++k) {
|
||||
// norm += y[k];
|
||||
// m_y[k] = y[k];
|
||||
//}
|
||||
|
||||
//scale(m_kk, 1.0/norm, m_y.begin());
|
||||
transform(m_y.begin(), m_y.begin() + m_kk, m_rmolwts.begin(),
|
||||
m_ym.begin(), multiplies<double>());
|
||||
sum = accumulate(m_ym.begin(), m_ym.begin() + m_kk, 0.0);
|
||||
// for (k = 0; k != m_kk; ++k) {
|
||||
// m_ym[k] = m_y[k] * m_rmolwts[k];
|
||||
// sum += m_ym[k];
|
||||
// }
|
||||
m_mmw = 1.0/sum;
|
||||
|
||||
//! Call a routine to determin whether state has changed.
|
||||
stateMFChangeCalc();
|
||||
}
|
||||
|
||||
void State::setMassFractions_NoNorm(const doublereal* const y) {
|
||||
doublereal sum = 0.0;
|
||||
copy(y, y + m_kk, m_y.begin());
|
||||
transform(m_y.begin(), m_y.end(), m_rmolwts.begin(), m_ym.begin(),
|
||||
multiplies<double>());
|
||||
sum = accumulate(m_ym.begin(), m_ym.end(), 0.0);
|
||||
//for (k = 0; k != m_kk; ++k) {
|
||||
// m_y[k] = y[k];
|
||||
// m_ym[k] = m_y[k] * m_rmolwts[k];
|
||||
// sum += m_ym[k];
|
||||
//}
|
||||
m_mmw = 1.0/sum;
|
||||
|
||||
//! Call a routine to determine whether state has changed.
|
||||
stateMFChangeCalc();
|
||||
}
|
||||
|
||||
doublereal State::sum_xlogx() const {
|
||||
return m_mmw* Cantera::sum_xlogx(m_ym.begin(), m_ym.end()) + log(m_mmw);
|
||||
}
|
||||
|
||||
doublereal State::sum_xlogQ(doublereal* Q) const {
|
||||
return m_mmw * Cantera::sum_xlogQ(m_ym.begin(), m_ym.end(), Q);
|
||||
}
|
||||
|
||||
doublereal State::molarDensity() const {
|
||||
return density()/meanMolecularWeight();
|
||||
}
|
||||
|
||||
void State::setConcentrations(const doublereal* const c) {
|
||||
int k;
|
||||
doublereal sum = 0.0, norm = 0.0;
|
||||
for (k = 0; k != m_kk; ++k) {
|
||||
sum += c[k]*m_molwts[k];
|
||||
norm += c[k];
|
||||
}
|
||||
m_mmw = sum/norm;
|
||||
setDensity(sum);
|
||||
doublereal rsum = 1.0/sum;
|
||||
for (k = 0; k != m_kk; ++k) {
|
||||
m_ym[k] = c[k] * rsum;
|
||||
m_y[k] = m_ym[k] * m_molwts[k];
|
||||
}
|
||||
|
||||
void State::setMoleFractions(const doublereal* x) {
|
||||
doublereal sum = 0.0, norm = 0.0;
|
||||
sum = dot(x, x + m_kk, m_molwts.begin());
|
||||
doublereal rsum = 1.0/sum;
|
||||
transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rsum));
|
||||
transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
|
||||
m_y.begin(), multiplies<double>());
|
||||
norm = accumulate(x, x + m_kk, 0.0);
|
||||
//for (k = 0; k != m_kk; ++k) {
|
||||
// m_ym[k] = x[k] / sum;
|
||||
// m_y[k] = m_molwts[k]*m_ym[k];
|
||||
// norm += x[k];
|
||||
//}
|
||||
m_mmw = sum/norm;
|
||||
//! Call a routine to determin whether state has changed.
|
||||
stateMFChangeCalc();
|
||||
}
|
||||
|
||||
const doublereal* State::moleFractdivMMW() const {
|
||||
return &m_ym[0];
|
||||
}
|
||||
|
||||
void State::getConcentrations(doublereal* const c) const {
|
||||
scale(m_ym.begin(), m_ym.end(), c, m_dens);
|
||||
}
|
||||
|
||||
doublereal State::mean_X(const doublereal* const Q) const {
|
||||
return m_mmw*std::inner_product(m_ym.begin(), m_ym.end(), Q, 0.0);
|
||||
}
|
||||
|
||||
doublereal State::mean_Y(const doublereal* const Q) const {
|
||||
return dot(m_y.begin(), m_y.end(), Q);
|
||||
}
|
||||
|
||||
void State::getMoleFractions(doublereal* const x) const {
|
||||
scale(m_ym.begin(), m_ym.end(), x, m_mmw);
|
||||
}
|
||||
|
||||
void State::getMassFractions(doublereal* const y) const {
|
||||
copy(m_y.begin(), m_y.end(), y);
|
||||
}
|
||||
|
||||
void State::setMolarDensity(const doublereal molarDensity) {
|
||||
m_dens = molarDensity*meanMolecularWeight();
|
||||
}
|
||||
|
||||
inline void State::stateMFChangeCalc(bool forcerChange) {
|
||||
// Right now we assume that the mole fractions have changed every time
|
||||
// the function is called
|
||||
m_stateNum++;
|
||||
if (m_stateNum > 1000000) m_stateNum = -10000000;
|
||||
}
|
||||
|
||||
|
||||
void State::init(const array_fp& mw) {
|
||||
m_kk = mw.size();
|
||||
m_molwts.resize(m_kk);
|
||||
m_rmolwts.resize(m_kk);
|
||||
m_y.resize(m_kk, 0.0);
|
||||
m_ym.resize(m_kk, 0.0);
|
||||
copy(mw.begin(), mw.end(), m_molwts.begin());
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
if (m_molwts[k] < 0.0) {
|
||||
throw CanteraError("State::init",
|
||||
"negative molecular weight for species number "+int2str(k));
|
||||
}
|
||||
/*
|
||||
* Some surface phases may define species representing
|
||||
* empty sites that have zero molecular weight. Give them
|
||||
* a very small molecular weight to avoid dividing by
|
||||
* zero.
|
||||
*/
|
||||
if (m_molwts[k] < Tiny) m_molwts[k] = Tiny;
|
||||
m_rmolwts[k] = 1.0/m_molwts[k];
|
||||
}
|
||||
|
||||
void State::setMoleFractions_NoNorm(const doublereal* x) {
|
||||
m_mmw = dot(x, x + m_kk, m_molwts.begin());
|
||||
doublereal rmmw = 1.0/m_mmw;
|
||||
transform(x, x + m_kk, m_ym.begin(), timesConstant<double>(rmmw));
|
||||
transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
|
||||
m_y.begin(), multiplies<double>());
|
||||
}
|
||||
/*
|
||||
* Now that we have resized the State object, let's fill it with
|
||||
* a valid mass fraction vector that sums to one. The State object
|
||||
* should never have a mass fraction vector that doesn't sum to one.
|
||||
* We will assume that species 0 has a mass fraction of 1.0 and
|
||||
* mass fraction of all other species is 0.0.
|
||||
*/
|
||||
m_y[0] = 1.0;
|
||||
m_ym[0] = m_y[0] * m_rmolwts[0];
|
||||
m_mmw = 1.0 / m_ym[0];
|
||||
}
|
||||
|
||||
doublereal State::massFraction(int k) const {
|
||||
if (k >= 0 && k < m_kk) {
|
||||
return m_y[k];
|
||||
}
|
||||
else {
|
||||
throw CanteraError("State:massFraction",
|
||||
"illegal species index number");
|
||||
}
|
||||
}
|
||||
// True if the number of species has been set and fixed
|
||||
bool State::ready() const {
|
||||
return (m_kk > 0);
|
||||
}
|
||||
|
||||
doublereal State::concentration(int k) const {
|
||||
if (k >= 0 && k < m_kk) {
|
||||
return m_y[k] * m_dens * m_rmolwts[k] ;
|
||||
}
|
||||
else {
|
||||
throw CanteraError("State:massFraction",
|
||||
"illegal species index number");
|
||||
}
|
||||
}
|
||||
|
||||
void State::setMassFractions(const doublereal* y) {
|
||||
doublereal norm = 0.0, sum = 0.0;
|
||||
//cblas_dcopy(m_kk, y, 1, m_y.begin(), 1);
|
||||
norm = accumulate(y, y + m_kk, 0.0);
|
||||
copy(y, y + m_kk, m_y.begin());
|
||||
scale(y, y + m_kk, m_y.begin(), 1.0/norm);
|
||||
// for (k = 0; k != m_kk; ++k) {
|
||||
// norm += y[k];
|
||||
// m_y[k] = y[k];
|
||||
//}
|
||||
|
||||
//scale(m_kk, 1.0/norm, m_y.begin());
|
||||
transform(m_y.begin(), m_y.begin() + m_kk, m_rmolwts.begin(),
|
||||
m_ym.begin(), multiplies<double>());
|
||||
sum = accumulate(m_ym.begin(), m_ym.begin() + m_kk, 0.0);
|
||||
// for (k = 0; k != m_kk; ++k) {
|
||||
// m_ym[k] = m_y[k] * m_rmolwts[k];
|
||||
// sum += m_ym[k];
|
||||
//}
|
||||
m_mmw = 1.0/sum;
|
||||
}
|
||||
|
||||
void State::setMassFractions_NoNorm(const doublereal* y) {
|
||||
doublereal sum = 0.0;
|
||||
copy(y, y + m_kk, m_y.begin());
|
||||
transform(m_y.begin(), m_y.end(), m_rmolwts.begin(), m_ym.begin(),
|
||||
multiplies<double>());
|
||||
sum = accumulate(m_ym.begin(), m_ym.end(), 0.0);
|
||||
//for (k = 0; k != m_kk; ++k) {
|
||||
// m_y[k] = y[k];
|
||||
// m_ym[k] = m_y[k] * m_rmolwts[k];
|
||||
// sum += m_ym[k];
|
||||
//}
|
||||
m_mmw = 1.0/sum;
|
||||
}
|
||||
|
||||
doublereal State::sum_xlogx() const {
|
||||
return m_mmw* Cantera::sum_xlogx(m_ym.begin(), m_ym.end()) + log(m_mmw);
|
||||
}
|
||||
|
||||
doublereal State::sum_xlogQ(doublereal* Q) const {
|
||||
return m_mmw * Cantera::sum_xlogQ(m_ym.begin(), m_ym.end(), Q);
|
||||
}
|
||||
|
||||
void State::setConcentrations(const doublereal* c) {
|
||||
int k;
|
||||
doublereal sum = 0.0, norm = 0.0;
|
||||
for (k = 0; k != m_kk; ++k) {
|
||||
sum += c[k]*m_molwts[k];
|
||||
norm += c[k];
|
||||
}
|
||||
m_mmw = sum/norm;
|
||||
setDensity(sum);
|
||||
doublereal rsum = 1.0/sum;
|
||||
for (k = 0; k != m_kk; ++k) {
|
||||
m_ym[k] = c[k] * rsum;
|
||||
m_y[k] = m_ym[k] * m_molwts[k];
|
||||
}
|
||||
}
|
||||
|
||||
void State::getConcentrations(doublereal* c) const {
|
||||
scale(m_ym.begin(), m_ym.end(), c, m_dens);
|
||||
}
|
||||
|
||||
doublereal State::mean_Y(const doublereal* Q) const {
|
||||
return dot(m_y.begin(), m_y.end(), Q);
|
||||
}
|
||||
|
||||
void State::getMoleFractions(doublereal* x) const {
|
||||
scale(m_ym.begin(), m_ym.end(), x, m_mmw);
|
||||
}
|
||||
|
||||
void State::getMassFractions(doublereal* y) const {
|
||||
copy(m_y.begin(), m_y.end(), y);
|
||||
}
|
||||
|
||||
void State::init(const array_fp& mw) {
|
||||
m_kk = mw.size();
|
||||
m_molwts.resize(m_kk);
|
||||
m_rmolwts.resize(m_kk);
|
||||
m_y.resize(m_kk, 0.0);
|
||||
m_ym.resize(m_kk, 0.0);
|
||||
copy(mw.begin(), mw.end(), m_molwts.begin());
|
||||
for (int k = 0; k < m_kk; k++) {
|
||||
if (m_molwts[k] < 0.0) {
|
||||
throw CanteraError("State::init",
|
||||
"negative molecular weight for species number "+int2str(k));
|
||||
}
|
||||
/*
|
||||
* Some surface phases may define species representing
|
||||
* empty sites that have zero molecular weight. Give them
|
||||
* a very small molecular weight to avoid dividing by
|
||||
* zero.
|
||||
*/
|
||||
if (m_molwts[k] < Tiny) m_molwts[k] = Tiny;
|
||||
m_rmolwts[k] = 1.0/m_molwts[k];
|
||||
}
|
||||
|
||||
/*
|
||||
* Now that we have resized the State object, let's fill it with
|
||||
* a valid mass fraction vector that sums to one. The State object
|
||||
* should never have a mass fraction vector that doesn't sum to one.
|
||||
* We will assume that species 0 has a mass fraction of 1.0 and
|
||||
* mass fraction of all other species is 0.0.
|
||||
*/
|
||||
m_y[0] = 1.0;
|
||||
m_ym[0] = m_y[0] * m_rmolwts[0];
|
||||
m_mmw = 1.0 / m_ym[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
*/
|
||||
|
||||
/*
|
||||
* $Author$
|
||||
* $Date$
|
||||
* $Revision$
|
||||
*
|
||||
|
|
@ -60,357 +59,374 @@ namespace Cantera {
|
|||
*
|
||||
* @ingroup phases
|
||||
*/
|
||||
class State {
|
||||
class State {
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
State();
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
State();
|
||||
|
||||
/**
|
||||
* Destructor. Since no memory is allocated by methods of this
|
||||
* class, the destructor does nothing.
|
||||
*/
|
||||
virtual ~State();
|
||||
/**
|
||||
* Destructor. Since no memory is allocated by methods of this
|
||||
* class, the destructor does nothing.
|
||||
*/
|
||||
virtual ~State();
|
||||
|
||||
/**
|
||||
* Copy Constructor for the State Class
|
||||
*
|
||||
* @param right Reference to the class to be copied.
|
||||
*/
|
||||
State(const State& right);
|
||||
/**
|
||||
* Copy Constructor for the State Class
|
||||
*
|
||||
* @param right Reference to the class to be copied.
|
||||
*/
|
||||
State(const State& right);
|
||||
|
||||
/**
|
||||
* Assignment operator for the state class.
|
||||
*
|
||||
* @param right Reference to the class to be copied.
|
||||
*/
|
||||
State& operator=(const State& right);
|
||||
/**
|
||||
* Assignment operator for the state class.
|
||||
*
|
||||
* @param right Reference to the class to be copied.
|
||||
*/
|
||||
State& operator=(const State& right);
|
||||
|
||||
|
||||
/// @name Species Information
|
||||
///
|
||||
/// The only thing class State knows about the species is their
|
||||
/// molecular weights.
|
||||
//@{
|
||||
/// @name Species Information
|
||||
///
|
||||
/// The only thing class State knows about the species is their
|
||||
/// molecular weights.
|
||||
//@{
|
||||
|
||||
/// Return a read-only reference to the array of molecular
|
||||
/// weights.
|
||||
const array_fp& molecularWeights() const { return m_molwts; }
|
||||
/// Return a read-only reference to the array of molecular
|
||||
/// weights.
|
||||
const array_fp& molecularWeights() const { return m_molwts; }
|
||||
|
||||
|
||||
//@}
|
||||
/// @name Composition
|
||||
//@{
|
||||
//@}
|
||||
/// @name Composition
|
||||
//@{
|
||||
|
||||
|
||||
//! Get the species mole fraction vector.
|
||||
/*!
|
||||
* @param x On return, x contains the mole fractions. Must have a
|
||||
* length greater than or equal to the number of species.
|
||||
*/
|
||||
void getMoleFractions(doublereal* x) const;
|
||||
//! Get the species mole fraction vector.
|
||||
/*!
|
||||
* @param x On return, x contains the mole fractions. Must have a
|
||||
* length greater than or equal to the number of species.
|
||||
*/
|
||||
void getMoleFractions(doublereal* const x) const;
|
||||
|
||||
|
||||
//! The mole fraction of species k.
|
||||
/*!
|
||||
* If k is ouside the valid
|
||||
* range, an exception will be thrown. Note that it is
|
||||
* somewhat more efficent to call getMoleFractions if the
|
||||
* mole fractions of all species are desired.
|
||||
* @param k species index
|
||||
*/
|
||||
doublereal moleFraction(int k) const;
|
||||
//! The mole fraction of species k.
|
||||
/*!
|
||||
* If k is ouside the valid
|
||||
* range, an exception will be thrown. Note that it is
|
||||
* somewhat more efficent to call getMoleFractions if the
|
||||
* mole fractions of all species are desired.
|
||||
* @param k species index
|
||||
*/
|
||||
doublereal moleFraction(const int k) const;
|
||||
|
||||
/**
|
||||
* Set the mole fractions to the specified values, and then
|
||||
* normalize them so that they sum to 1.0.
|
||||
* @param x Array of unnormalized mole fraction values (input).
|
||||
* Must have a length greater than or equal to the number of
|
||||
* species.
|
||||
*
|
||||
* @param x Input vector of mole fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMoleFractions(const doublereal* x);
|
||||
/**
|
||||
* Set the mole fractions to the specified values, and then
|
||||
* normalize them so that they sum to 1.0.
|
||||
* @param x Array of unnormalized mole fraction values (input).
|
||||
* Must have a length greater than or equal to the number of
|
||||
* species.
|
||||
*
|
||||
* @param x Input vector of mole fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMoleFractions(const doublereal* const x);
|
||||
|
||||
/**
|
||||
* Set the mole fractions to the specified values without
|
||||
* normalizing. This is useful when the normalization
|
||||
* condition is being handled by some other means, for example
|
||||
* by a constraint equation as part of a larger set of
|
||||
* equations.
|
||||
*
|
||||
* @param x Input vector of mole fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMoleFractions_NoNorm(const doublereal* x);
|
||||
/**
|
||||
* Set the mole fractions to the specified values without
|
||||
* normalizing. This is useful when the normalization
|
||||
* condition is being handled by some other means, for example
|
||||
* by a constraint equation as part of a larger set of
|
||||
* equations.
|
||||
*
|
||||
* @param x Input vector of mole fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMoleFractions_NoNorm(const doublereal* const x);
|
||||
|
||||
/**
|
||||
* Get the species mass fractions.
|
||||
* @param y On return, y
|
||||
* contains the mass fractions. Array \a y must have a length
|
||||
* greater than or equal to the number of species.
|
||||
*
|
||||
* @param y Output vector of mass fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
void getMassFractions(doublereal* y) const;
|
||||
/**
|
||||
* Get the species mass fractions.
|
||||
* @param y On return, y
|
||||
* contains the mass fractions. Array \a y must have a length
|
||||
* greater than or equal to the number of species.
|
||||
*
|
||||
* @param y Output vector of mass fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
void getMassFractions(doublereal* const y) const;
|
||||
|
||||
//! Mass fraction of species k.
|
||||
/*!
|
||||
* If k is outside the valid
|
||||
* range, an exception will be thrown. Note that it is
|
||||
* somewhat more efficent to call getMassFractions if the
|
||||
* mass fractions of all species are desired.
|
||||
*
|
||||
* @param k species index
|
||||
*/
|
||||
doublereal massFraction(int k) const;
|
||||
//! Mass fraction of species k.
|
||||
/*!
|
||||
* If k is outside the valid
|
||||
* range, an exception will be thrown. Note that it is
|
||||
* somewhat more efficent to call getMassFractions if the
|
||||
* mass fractions of all species are desired.
|
||||
*
|
||||
* @param k species index
|
||||
*/
|
||||
doublereal massFraction(const int k) const;
|
||||
|
||||
/**
|
||||
* Set the mass fractions to the specified values, and then
|
||||
* normalize them so that they sum to 1.0.
|
||||
* @param y Array of unnormalized mass fraction values (input).
|
||||
* Must have a length greater than or equal to the number of
|
||||
* species.
|
||||
*
|
||||
* @param y Input vector of mass fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMassFractions(const doublereal* y);
|
||||
/**
|
||||
* Set the mass fractions to the specified values, and then
|
||||
* normalize them so that they sum to 1.0.
|
||||
* @param y Array of unnormalized mass fraction values (input).
|
||||
* Must have a length greater than or equal to the number of
|
||||
* species.
|
||||
*
|
||||
* @param y Input vector of mass fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMassFractions(const doublereal* const y);
|
||||
|
||||
/**
|
||||
* Set the mass fractions to the specified values without
|
||||
* normalizing. This is useful when the normalization
|
||||
* condition is being handled by some other means, for example
|
||||
* by a constraint equation as part of a larger set of
|
||||
* equations.
|
||||
*
|
||||
* @param y Input vector of mass fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMassFractions_NoNorm(const doublereal* y);
|
||||
/**
|
||||
* Set the mass fractions to the specified values without
|
||||
* normalizing. This is useful when the normalization
|
||||
* condition is being handled by some other means, for example
|
||||
* by a constraint equation as part of a larger set of
|
||||
* equations.
|
||||
*
|
||||
* @param y Input vector of mass fractions.
|
||||
* Length is m_kk.
|
||||
*/
|
||||
virtual void setMassFractions_NoNorm(const doublereal* const y);
|
||||
|
||||
/**
|
||||
* Get the species concentrations (kmol/m^3). @param c On
|
||||
* return, \a c contains the concentrations for all species.
|
||||
* Array \a c must have a length greater than or equal to the
|
||||
* number of species.
|
||||
*/
|
||||
void getConcentrations(doublereal* c) const;
|
||||
/**
|
||||
* Get the species concentrations (kmol/m^3). @param c On
|
||||
* return, \a c contains the concentrations for all species.
|
||||
* Array \a c must have a length greater than or equal to the
|
||||
* number of species.
|
||||
*/
|
||||
void getConcentrations(doublereal* const c) const;
|
||||
|
||||
/**
|
||||
* Concentration of species k. If k is outside the valid
|
||||
* range, an exception will be thrown.
|
||||
*
|
||||
* @param k Index of species
|
||||
*/
|
||||
doublereal concentration(int k) const;
|
||||
/**
|
||||
* Concentration of species k. If k is outside the valid
|
||||
* range, an exception will be thrown.
|
||||
*
|
||||
* @param k Index of species
|
||||
*/
|
||||
doublereal concentration(const int k) const;
|
||||
|
||||
/**
|
||||
* Set the concentrations to the specified values within the
|
||||
* phase.
|
||||
*
|
||||
* @param c The input vector to this routine is in dimensional
|
||||
* units. For volumetric phases c[k] is the
|
||||
* concentration of the kth species in kmol/m3.
|
||||
* For surface phases, c[k] is the concentration
|
||||
* in kmol/m2. The length of the vector is the number
|
||||
* of species in the phase.
|
||||
*/
|
||||
virtual void setConcentrations(const doublereal* c);
|
||||
/**
|
||||
* Set the concentrations to the specified values within the
|
||||
* phase.
|
||||
*
|
||||
* @param c The input vector to this routine is in dimensional
|
||||
* units. For volumetric phases c[k] is the
|
||||
* concentration of the kth species in kmol/m3.
|
||||
* For surface phases, c[k] is the concentration
|
||||
* in kmol/m2. The length of the vector is the number
|
||||
* of species in the phase.
|
||||
*/
|
||||
virtual void setConcentrations(const doublereal* const c);
|
||||
|
||||
/**
|
||||
* Returns a read-only pointer to the start of the
|
||||
* massFraction array
|
||||
*/
|
||||
const doublereal* massFractions() const { return &m_y[0]; }
|
||||
/**
|
||||
* Returns a read-only pointer to the start of the
|
||||
* massFraction array
|
||||
*/
|
||||
const doublereal* massFractions() const {
|
||||
return &m_y[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a read-only pointer to the start of the
|
||||
* moleFraction/MW array. This array is the array of mole
|
||||
* fractions, each divided by the mean molecular weight.
|
||||
*/
|
||||
const doublereal* moleFractdivMMW() const { return &m_ym[0];}
|
||||
/**
|
||||
* Returns a read-only pointer to the start of the
|
||||
* moleFraction/MW array. This array is the array of mole
|
||||
* fractions, each divided by the mean molecular weight.
|
||||
*/
|
||||
const doublereal* moleFractdivMMW() const;
|
||||
|
||||
//@}
|
||||
|
||||
/// @name Mean Properties
|
||||
//@{
|
||||
/**
|
||||
* Evaluate the mole-fraction-weighted mean of Q:
|
||||
* \f[ \sum_k X_k Q_k. \f]
|
||||
* Array Q should contain pure-species molar property
|
||||
* values.
|
||||
*
|
||||
* @param Q input vector of length m_kk that is to be averaged.
|
||||
* @return
|
||||
* mole-freaction-weighted mean of Q
|
||||
*/
|
||||
doublereal mean_X(const doublereal* const Q) const;
|
||||
|
||||
/**
|
||||
* Evaluate the mass-fraction-weighted mean of Q:
|
||||
* \f[ \sum_k Y_k Q_k \f]
|
||||
*
|
||||
* @param Q Array Q contains a vector of species property values in mass units.
|
||||
* @return
|
||||
* Return value containing the mass-fraction-weighted mean of Q.
|
||||
*/
|
||||
doublereal mean_Y(const doublereal* const Q) const;
|
||||
|
||||
/**
|
||||
* The mean molecular weight. Units: (kg/kmol)
|
||||
*/
|
||||
doublereal meanMolecularWeight() const {
|
||||
return m_mmw;
|
||||
}
|
||||
|
||||
//! Evaluate \f$ \sum_k X_k \log X_k \f$.
|
||||
/*!
|
||||
* @return
|
||||
* returns the indicated sum. units are dimensionless.
|
||||
*/
|
||||
doublereal sum_xlogx() const;
|
||||
|
||||
//! Evaluate \f$ \sum_k X_k \log Q_k \f$.
|
||||
/*!
|
||||
* @param Q Vector of length m_kk to take the log average of
|
||||
* @return Returns the indicated sum.
|
||||
*/
|
||||
doublereal sum_xlogQ(doublereal* const Q) const;
|
||||
//@}
|
||||
|
||||
/// @name Thermodynamic Properties
|
||||
/// Class State only stores enough thermodynamic data to
|
||||
/// specify the state. In addition to composition information,
|
||||
/// it stores the temperature and
|
||||
/// mass density.
|
||||
//@{
|
||||
|
||||
/// Temperature (K).
|
||||
doublereal temperature() const {
|
||||
return m_temp;
|
||||
}
|
||||
|
||||
/// Density (kg/m^3).
|
||||
virtual doublereal density() const {
|
||||
return m_dens;
|
||||
}
|
||||
|
||||
/// Molar density (kmol/m^3).
|
||||
doublereal molarDensity() const;
|
||||
|
||||
//! Set the internally storred density (kg/m^3) of the phase
|
||||
/*!
|
||||
* Note the density of a phase is an indepedent variable.
|
||||
*
|
||||
* @param density Input density (kg/m^3).
|
||||
*/
|
||||
virtual void setDensity(const doublereal density) {
|
||||
m_dens = density;
|
||||
}
|
||||
|
||||
//! Set the internally storred molar density (kmol/m^3) of the phase.
|
||||
/*!
|
||||
* @param molarDensity Input molar density (kmol/m^3).
|
||||
*/
|
||||
virtual void setMolarDensity(const doublereal molarDensity);
|
||||
|
||||
//! Set the temperature (K).
|
||||
/*!
|
||||
* This function sets the internally storred temperature of the phase.
|
||||
*
|
||||
* @param temp Temperature in kelvin
|
||||
*/
|
||||
virtual void setTemperature(const doublereal temp) {
|
||||
m_temp = temp;
|
||||
}
|
||||
//@}
|
||||
|
||||
//! True if the number species has been set
|
||||
bool ready() const;
|
||||
|
||||
|
||||
//@}
|
||||
void stateMFChangeCalc(bool forceChange = false);
|
||||
|
||||
/// @name Mean Properties
|
||||
//@{
|
||||
/**
|
||||
* Evaluate the mole-fraction-weighted mean of Q:
|
||||
* \f[ \sum_k X_k Q_k. \f]
|
||||
* Array Q should contain pure-species molar property
|
||||
* values.
|
||||
*
|
||||
* @param Q input vector of length m_kk that is to be averaged.
|
||||
* @return
|
||||
* mole-freaction-weighted mean of Q
|
||||
*/
|
||||
doublereal mean_X(const doublereal* Q) const {
|
||||
return m_mmw*std::inner_product(m_ym.begin(), m_ym.end(), Q, 0.0);
|
||||
}
|
||||
//! Return the state number
|
||||
int stateMFNumber() const;
|
||||
|
||||
/**
|
||||
* Evaluate the mass-fraction-weighted mean of Q:
|
||||
* \f[ \sum_k Y_k Q_k \f]
|
||||
*
|
||||
* @param Q Array Q contains a vector of species property values in mass units.
|
||||
* @return
|
||||
* Return value containing the mass-fraction-weighted mean of Q.
|
||||
*/
|
||||
doublereal mean_Y(const doublereal* Q) const;
|
||||
protected:
|
||||
|
||||
/**
|
||||
* The mean molecular weight. Units: (kg/kmol)
|
||||
*/
|
||||
doublereal meanMolecularWeight() const {
|
||||
return m_mmw;
|
||||
}
|
||||
|
||||
//! Evaluate \f$ \sum_k X_k \log X_k \f$.
|
||||
/*!
|
||||
* @return
|
||||
* returns the indicated sum. units are dimensionless.
|
||||
*/
|
||||
doublereal sum_xlogx() const;
|
||||
|
||||
//! Evaluate \f$ \sum_k X_k \log Q_k \f$.
|
||||
/*!
|
||||
* @param Q Vector of length m_kk to take the log average of
|
||||
* @return Returns the indicated sum.
|
||||
*/
|
||||
doublereal sum_xlogQ(doublereal* Q) const;
|
||||
//@}
|
||||
|
||||
/// @name Thermodynamic Properties
|
||||
/// Class State only stores enough thermodynamic data to
|
||||
/// specify the state. In addition to composition information,
|
||||
/// it stores the temperature and
|
||||
/// mass density.
|
||||
//@{
|
||||
|
||||
/// Temperature (K).
|
||||
doublereal temperature() const { return m_temp; }
|
||||
|
||||
/// Density (kg/m^3).
|
||||
virtual doublereal density() const { return m_dens; }
|
||||
|
||||
/// Molar density (kmol/m^3).
|
||||
doublereal molarDensity() const {
|
||||
return density()/meanMolecularWeight();
|
||||
}
|
||||
|
||||
//! Set the internally storred density (kg/m^3) of the phase
|
||||
/*!
|
||||
* Note the density of a phase is an indepedent variable.
|
||||
*
|
||||
* @param density Input density (kg/m^3).
|
||||
*/
|
||||
virtual void setDensity(doublereal density) {
|
||||
m_dens = density;
|
||||
}
|
||||
|
||||
//! Set the internally storred molar density (kmol/m^3) of the phase.
|
||||
/*!
|
||||
* @param molarDensity Input molar density (kmol/m^3).
|
||||
*/
|
||||
virtual void setMolarDensity(doublereal molarDensity) {
|
||||
m_dens = molarDensity*meanMolecularWeight();
|
||||
}
|
||||
|
||||
//! Set the temperature (K).
|
||||
/*!
|
||||
* This function sets the internally storred temperature of the phase.
|
||||
*
|
||||
* @param temp Temperature in kelvin
|
||||
*/
|
||||
virtual void setTemperature(doublereal temp) {
|
||||
m_temp = temp;
|
||||
}
|
||||
//@}
|
||||
|
||||
//! True if the number species has been set
|
||||
bool ready() const { return (m_kk > 0); }
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Initialize. Make a local copy of the vector of
|
||||
* molecular weights, and resize the composition arrays to
|
||||
* the appropriate size. The only information an instance of
|
||||
* State has about the species is their molecular weights.
|
||||
*
|
||||
* @param mw Vector of molecular weights of the species.
|
||||
*/
|
||||
void init(const array_fp& mw); //, density_is_independent = true);
|
||||
/**
|
||||
* @internal
|
||||
* Initialize. Make a local copy of the vector of
|
||||
* molecular weights, and resize the composition arrays to
|
||||
* the appropriate size. The only information an instance of
|
||||
* State has about the species is their molecular weights.
|
||||
*
|
||||
* @param mw Vector of molecular weights of the species.
|
||||
*/
|
||||
void init(const array_fp& mw); //, density_is_independent = true);
|
||||
|
||||
/**
|
||||
* m_kk is the number of species in the phase
|
||||
*/
|
||||
int m_kk;
|
||||
/**
|
||||
* m_kk is the number of species in the phase
|
||||
*/
|
||||
int m_kk;
|
||||
|
||||
//! Set the molecular weight of a single species to a given value
|
||||
/*!
|
||||
* @param k id of the species
|
||||
* @param mw Molecular Weight (kg kmol-1)
|
||||
*/
|
||||
void setMolecularWeight(int k, double mw) {
|
||||
m_molwts[k] = mw;
|
||||
m_rmolwts[k] = 1.0/mw;
|
||||
}
|
||||
//! Set the molecular weight of a single species to a given value
|
||||
/*!
|
||||
* @param k id of the species
|
||||
* @param mw Molecular Weight (kg kmol-1)
|
||||
*/
|
||||
void setMolecularWeight(const int k, const double mw) {
|
||||
m_molwts[k] = mw;
|
||||
m_rmolwts[k] = 1.0/mw;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
/**
|
||||
* Temperature. This is an independent variable
|
||||
* units = Kelvin
|
||||
*/
|
||||
doublereal m_temp;
|
||||
/**
|
||||
* Temperature. This is an independent variable
|
||||
* units = Kelvin
|
||||
*/
|
||||
doublereal m_temp;
|
||||
|
||||
/**
|
||||
* Density. This is an independent variable except in
|
||||
* the incompressible degenerate case. Thus,
|
||||
* the pressure is determined from this variable
|
||||
* not the other way round.
|
||||
* units = kg m-3
|
||||
*/
|
||||
doublereal m_dens;
|
||||
/**
|
||||
* Density. This is an independent variable except in
|
||||
* the incompressible degenerate case. Thus,
|
||||
* the pressure is determined from this variable
|
||||
* not the other way round.
|
||||
* units = kg m-3
|
||||
*/
|
||||
doublereal m_dens;
|
||||
|
||||
/**
|
||||
* m_mmw is the mean molecular weight of the mixture
|
||||
* (kg kmol-1)
|
||||
*/
|
||||
doublereal m_mmw;
|
||||
/**
|
||||
* m_mmw is the mean molecular weight of the mixture
|
||||
* (kg kmol-1)
|
||||
*/
|
||||
doublereal m_mmw;
|
||||
|
||||
/**
|
||||
* m_ym[k] = mole fraction of species k divided by the
|
||||
* mean molecular weight of mixture.
|
||||
*/
|
||||
mutable array_fp m_ym;
|
||||
/**
|
||||
* m_ym[k] = mole fraction of species k divided by the
|
||||
* mean molecular weight of mixture.
|
||||
*/
|
||||
mutable array_fp m_ym;
|
||||
|
||||
/**
|
||||
* m_y[k] = mass fraction of species k
|
||||
*/
|
||||
mutable array_fp m_y;
|
||||
/**
|
||||
* m_y[k] = mass fraction of species k
|
||||
*/
|
||||
mutable array_fp m_y;
|
||||
|
||||
/**
|
||||
* m_molwts[k] = molecular weight of species k (kg kmol-1)
|
||||
*/
|
||||
array_fp m_molwts;
|
||||
/**
|
||||
* m_molwts[k] = molecular weight of species k (kg kmol-1)
|
||||
*/
|
||||
array_fp m_molwts;
|
||||
|
||||
/**
|
||||
* m_rmolwts[k] = inverse of the molecular weight of species k
|
||||
* units = kmol kg-1.
|
||||
*/
|
||||
array_fp m_rmolwts;
|
||||
/**
|
||||
* m_rmolwts[k] = inverse of the molecular weight of species k
|
||||
* units = kmol kg-1.
|
||||
*/
|
||||
array_fp m_rmolwts;
|
||||
|
||||
};
|
||||
//! State Change variable
|
||||
/*!
|
||||
* Whenever the mole fraction vector changes, this int is
|
||||
* incremented.
|
||||
*/
|
||||
int m_stateNum;
|
||||
|
||||
};
|
||||
|
||||
|
||||
inline int State::stateMFNumber() const {
|
||||
return m_stateNum;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue