Added a mole fraction State change capability.

This commit is contained in:
Harry Moffat 2009-02-15 17:33:06 +00:00
parent d3ffe3bd95
commit 66a7fcc92d
2 changed files with 539 additions and 472 deletions

View file

@ -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];
}
}

View file

@ -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;
}
}