Trying out a cleaner way knowing when expensive state functions need to be recomputed.

This commit is contained in:
Victor Brunini 2014-03-13 23:50:31 +00:00
parent 89eab1bb48
commit b0ecf96cb6
7 changed files with 197 additions and 108 deletions

View file

@ -2362,6 +2362,9 @@ public:
*/
int m_form_A_Debye;
protected:
virtual void invalidateCachedDataOnStateChange(StateVariable changed_var);
private:
/**
* A_Debye -> this expression appears on the top of the
@ -2394,14 +2397,10 @@ private:
* dw = C_0 * M_0 (density of water) (kg/m3)
* = 1.0E3 at 25C
*/
mutable bool m_A_Debye_valid;
mutable double m_A_Debye;
mutable double m_last_dA_DebyedP_TP;
mutable double m_last_dA_DebyedP_TP_T;
mutable double m_last_dA_DebyedP_TP_P;
mutable double m_last_P;
mutable double m_last_T;
mutable double m_last_A_Debye;
mutable bool m_dA_DebyedP_TP_valid;
mutable double m_dA_DebyedP_TP;
//! Water standard state calculator
/*!
@ -3173,8 +3172,7 @@ private:
* natural logarithm of the molality activity coefficients
*/
void s_update_lnMolalityActCoeff() const;
mutable std::vector<doublereal> m_last_cropped_molalities;
bool cropped_molalities_changed() const;
mutable bool s_update_lnMolalityActCoeff_valid;
//! This function calculates the temperature derivative of the
//! natural logarithm of the molality activity coefficients.
@ -3183,6 +3181,7 @@ private:
* coefficient is on the molality scale. It's derivative is too.
*/
void s_update_dlnMolalityActCoeff_dT() const;
mutable bool s_update_dlnMolalityActCoeff_dT_valid;
/**
* This function calculates the temperature second derivative
@ -3190,6 +3189,7 @@ private:
* coefficients.
*/
void s_update_d2lnMolalityActCoeff_dT2() const;
mutable bool s_update_d2lnMolalityActCoeff_dT2_valid;
/**
* This function calculates the pressure derivative of the
@ -3198,6 +3198,7 @@ private:
* Assumes that the activity coefficients are current.
*/
void s_update_dlnMolalityActCoeff_dP() const;
mutable bool s_update_dlnMolalityActCoeff_dP_valid;
//! This function will be called to update the internally stored
//! natural logarithm of the molality activity coefficients
@ -3270,9 +3271,7 @@ private:
* @param is Ionic strength
*/
void calc_lambdas(double is) const;
//! Track the last ionic strength lambdas were calculated at to avoid unnecessarily recalculating them
mutable double m_last_is;
mutable doublereal m_last_is;
/**
* Calculate etheta and etheta_prime

View file

@ -274,7 +274,11 @@ public:
void set_h_mix(const doublereal hmix) { h_mixing = hmix; }
protected:
void invalidateCachedDataOnStateChange(StateVariable changed_var);
private:
/**
* Value of the reference pressure for all species in this phase.
* The T dependent polynomials are evaluated at the reference
@ -294,12 +298,12 @@ protected:
* Function to call through to m_spthermo->update and fill m_h0_RT,
* m_cp0_R, m_g0_RT, m_s0_R.
*/
bool _updateThermo() const;
void _updateThermo() const;
mutable bool m_updateThermo_valid;
//! Vector containing the last computed activity coefficients at T = m_tlast and r = last_r
mutable std::vector<doublereal> m_last_ac;
//! Last value of r used to update activity coeffs
mutable doublereal m_last_mole_frac_product;
mutable std::vector<doublereal> m_activity_coeffs;
mutable bool m_activity_coeffs_valid;
//! Vector containing the species reference enthalpies at T = m_tlast
mutable vector_fp m_h0_RT;
@ -323,7 +327,6 @@ protected:
int product_species_index;
int reactant_species_index;
private:
// Functions to calculate some of the pieces of the mixing terms.
doublereal s() const;
doublereal fm(const doublereal r) const;

View file

@ -551,7 +551,14 @@ public:
throw CanteraError("Phase::setDensity()", "density must be positive");
}
m_dens = density_;
if(density_ != m_last_dens) {
invalidateCachedDataOnStateChange(DENSITY);
m_last_dens = density_;
}
}
private:
mutable doublereal m_last_dens;
public:
//! Set the internally stored molar density (kmol/m^3) of the phase.
//! @param[in] molarDensity Input molar density (kmol/m^3).
@ -565,8 +572,15 @@ public:
"temperature must be positive");
}
m_temp = temp;
if(temp != m_last_temp) {
invalidateCachedDataOnStateChange(TEMPERATURE);
m_last_temp = temp;
}
}
//@}
private:
mutable doublereal m_last_temp;
public:
//! @name Mean Properties
//!@{
@ -690,6 +704,35 @@ public:
}
protected:
//! Virtual function to simplify caching of extensive computations in child classes.
/*!
* The intent is that this virtual function should be called any time a state variable
* of a ThermoPhase class is changed the class can mark any cached data that is expensive to
* compute as invalid. For example:
* class APhase : public Phase
* {
* public:
* void update_activity_coeffs(); // Expensive function that only needs to run on state change
* void update_activity_coeffs_dT(); // Another expensive function
* private:
* // Variables that track whether the state has been changed since the expensive functions
* // were last run to avoid unnecessary work. These will be updated to false by invalidateCachedDataOnStateChange()
* bool m_activity_coeffs_valid;
* bool m_activity_coeffs_dT_valid;
* }
*
* This is somewhat easier to manage than having each individual expensive function track the last T, P, X_i, etc
* that it was calculated at to determine whether it is safe to skip the expensive computation.
*/
enum StateVariable {
PRESSURE,
TEMPERATURE,
SPECIES,
DENSITY,
OTHER
};
virtual void invalidateCachedDataOnStateChange(StateVariable changed_var) {}
//! 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)
@ -741,6 +784,8 @@ private:
mutable vector_fp m_ym;
mutable vector_fp m_y; //!< species mass fractions
mutable vector_fp m_last_y;
bool massFractionsChanged();
vector_fp m_molwts; //!< species molecular weights (kg kmol-1)

View file

@ -1131,6 +1131,7 @@ private:
//! Helper function used by setState_HPorUV and setState_SPorSV.
//! Sets the temperature and (if set_p is true) the pressure.
void setState_conditional_TP(doublereal t, doublereal p, bool set_p);
public:
//@}

View file

@ -38,12 +38,10 @@ HMWSoln::HMWSoln() :
m_TempPitzerRef(298.15),
m_IionicMolalityStoich(0.0),
m_form_A_Debye(A_DEBYE_WATER),
m_A_Debye_valid(false),
m_A_Debye(1.172576), // units = sqrt(kg/gmol)
m_last_dA_DebyedP_TP(-1.0),
m_last_dA_DebyedP_TP_T(-1.0),
m_last_dA_DebyedP_TP_P(-1.0),
m_last_P(-1.0),
m_last_T(-1.0),
m_dA_DebyedP_TP_valid(false),
m_dA_DebyedP_TP(-1.0),
m_waterSS(0),
m_densWaterSS(1000.),
m_waterProps(0),
@ -75,6 +73,10 @@ HMWSoln::HMWSoln() :
CROP_ln_gamma_o_max(3.0),
CROP_ln_gamma_k_min(-5.0),
CROP_ln_gamma_k_max(15.0),
s_update_lnMolalityActCoeff_valid(false),
s_update_dlnMolalityActCoeff_dT_valid(false),
s_update_d2lnMolalityActCoeff_dT2_valid(false),
s_update_dlnMolalityActCoeff_dP_valid(false),
m_last_is(-1.0),
m_debugCalc(0)
{
@ -94,12 +96,10 @@ HMWSoln::HMWSoln(const std::string& inputFile, const std::string& id_) :
m_TempPitzerRef(298.15),
m_IionicMolalityStoich(0.0),
m_form_A_Debye(A_DEBYE_WATER),
m_A_Debye_valid(false),
m_A_Debye(1.172576), // units = sqrt(kg/gmol)
m_last_dA_DebyedP_TP(-1.0),
m_last_dA_DebyedP_TP_T(-1.0),
m_last_dA_DebyedP_TP_P(-1.0),
m_last_P(-1.0),
m_last_T(-1.0),
m_dA_DebyedP_TP_valid(false),
m_dA_DebyedP_TP(-1.0),
m_waterSS(0),
m_densWaterSS(1000.),
m_waterProps(0),
@ -131,6 +131,10 @@ HMWSoln::HMWSoln(const std::string& inputFile, const std::string& id_) :
CROP_ln_gamma_o_max(3.0),
CROP_ln_gamma_k_min(-5.0),
CROP_ln_gamma_k_max(15.0),
s_update_lnMolalityActCoeff_valid(false),
s_update_dlnMolalityActCoeff_dT_valid(false),
s_update_d2lnMolalityActCoeff_dT2_valid(false),
s_update_dlnMolalityActCoeff_dP_valid(false),
m_last_is(-1.0),
m_debugCalc(0)
{
@ -151,12 +155,10 @@ HMWSoln::HMWSoln(XML_Node& phaseRoot, const std::string& id_) :
m_TempPitzerRef(298.15),
m_IionicMolalityStoich(0.0),
m_form_A_Debye(A_DEBYE_WATER),
m_A_Debye_valid(false),
m_A_Debye(1.172576), // units = sqrt(kg/gmol)
m_last_dA_DebyedP_TP(-1.0),
m_last_dA_DebyedP_TP_T(-1.0),
m_last_dA_DebyedP_TP_P(-1.0),
m_last_P(-1.0),
m_last_T(-1.0),
m_dA_DebyedP_TP_valid(false),
m_dA_DebyedP_TP(-1.0),
m_waterSS(0),
m_densWaterSS(1000.),
m_waterProps(0),
@ -188,6 +190,10 @@ HMWSoln::HMWSoln(XML_Node& phaseRoot, const std::string& id_) :
CROP_ln_gamma_o_max(3.0),
CROP_ln_gamma_k_min(-5.0),
CROP_ln_gamma_k_max(15.0),
s_update_lnMolalityActCoeff_valid(false),
s_update_dlnMolalityActCoeff_dT_valid(false),
s_update_d2lnMolalityActCoeff_dT2_valid(false),
s_update_dlnMolalityActCoeff_dP_valid(false),
m_last_is(-1.0),
m_debugCalc(0)
{
@ -208,12 +214,10 @@ HMWSoln::HMWSoln(const HMWSoln& b) :
m_TempPitzerRef(298.15),
m_IionicMolalityStoich(0.0),
m_form_A_Debye(A_DEBYE_WATER),
m_A_Debye_valid(false),
m_A_Debye(1.172576), // units = sqrt(kg/gmol)
m_last_dA_DebyedP_TP(-1.0),
m_last_dA_DebyedP_TP_T(-1.0),
m_last_dA_DebyedP_TP_P(-1.0),
m_last_P(-1.0),
m_last_T(-1.0),
m_dA_DebyedP_TP_valid(false),
m_dA_DebyedP_TP(-1.0),
m_waterSS(0),
m_densWaterSS(1000.),
m_waterProps(0),
@ -245,6 +249,10 @@ HMWSoln::HMWSoln(const HMWSoln& b) :
CROP_ln_gamma_o_max(3.0),
CROP_ln_gamma_k_min(-5.0),
CROP_ln_gamma_k_max(15.0),
s_update_lnMolalityActCoeff_valid(false),
s_update_dlnMolalityActCoeff_dT_valid(false),
s_update_d2lnMolalityActCoeff_dT2_valid(false),
s_update_dlnMolalityActCoeff_dP_valid(false),
m_last_is(-1.0),
m_debugCalc(0)
{
@ -424,12 +432,10 @@ HMWSoln::HMWSoln(int testProb) :
m_TempPitzerRef(298.15),
m_IionicMolalityStoich(0.0),
m_form_A_Debye(A_DEBYE_WATER),
m_A_Debye_valid(false),
m_A_Debye(1.172576), // units = sqrt(kg/gmol)
m_last_dA_DebyedP_TP(-1.0),
m_last_dA_DebyedP_TP_T(-1.0),
m_last_dA_DebyedP_TP_P(-1.0),
m_last_P(-1.0),
m_last_T(-1.0),
m_dA_DebyedP_TP_valid(false),
m_dA_DebyedP_TP(-1.0),
m_waterSS(0),
m_densWaterSS(1000.),
m_waterProps(0),
@ -461,6 +467,10 @@ HMWSoln::HMWSoln(int testProb) :
CROP_ln_gamma_o_max(3.0),
CROP_ln_gamma_k_min(-5.0),
CROP_ln_gamma_k_max(15.0),
s_update_lnMolalityActCoeff_valid(false),
s_update_dlnMolalityActCoeff_dT_valid(false),
s_update_d2lnMolalityActCoeff_dT2_valid(false),
s_update_dlnMolalityActCoeff_dP_valid(false),
m_last_is(-1.0),
m_debugCalc(0)
{
@ -1051,6 +1061,11 @@ doublereal HMWSoln::satPressure(doublereal t) {
double HMWSoln::A_Debye_TP(double tempArg, double presArg) const
{
if(m_A_Debye_valid) {
return m_A_Debye;
}
m_A_Debye_valid = true;
double T = temperature();
double A;
if (tempArg != -1.0) {
@ -1113,22 +1128,17 @@ double HMWSoln::dA_DebyedP_TP(double tempArg, double presArg) const
P = presArg;
}
double dAdP;
const double tol = 1.e-6;
switch (m_form_A_Debye) {
case A_DEBYE_CONST:
dAdP = 0.0;
break;
case A_DEBYE_WATER:
if( std::abs(T - m_last_dA_DebyedP_TP_T) > tol || std::abs(P - m_last_dA_DebyedP_TP_P) > tol )
{
dAdP = m_waterProps->ADebye(T, P, 3);
m_last_dA_DebyedP_TP_T = T;
m_last_dA_DebyedP_TP_P = P;
m_last_dA_DebyedP_TP = dAdP;
}
else
{
dAdP = m_last_dA_DebyedP_TP;
if(!m_dA_DebyedP_TP_valid) {
dAdP = m_waterProps->ADebye(T, P, 3);
m_dA_DebyedP_TP = dAdP;
m_dA_DebyedP_TP_valid = true;
} else {
dAdP = m_dA_DebyedP_TP;
}
break;
default:
@ -1347,30 +1357,13 @@ void HMWSoln::initLengths()
counterIJ_setup();
}
bool HMWSoln::cropped_molalities_changed() const
{
if( m_last_cropped_molalities.size() != m_kk ) {
m_last_cropped_molalities.resize(m_kk);
std::fill(m_last_cropped_molalities.begin(), m_last_cropped_molalities.end(), -1.0);
}
bool result = false;
const doublereal tol = 1.e-12;
for(size_t k=0; k < m_kk; ++k) {
if( std::abs(m_molalitiesCropped[k] - m_last_cropped_molalities[k]) > tol ) {
result = true;
}
}
if(result) {
std::copy( m_molalitiesCropped.begin(), m_molalitiesCropped.end(), m_last_cropped_molalities.begin() );
}
return result;
}
void HMWSoln::s_update_lnMolalityActCoeff() const
{
if(s_update_lnMolalityActCoeff_valid) {
return;
}
s_update_lnMolalityActCoeff_valid = true;
/*
* Calculate the molalities. Currently, the molalities
* may not be current with respect to the contents of the
@ -1383,19 +1376,6 @@ void HMWSoln::s_update_lnMolalityActCoeff() const
*/
calcMolalitiesCropped();
double T = temperature();
double P = pressure();
const doublereal tol = 1.e-12;
if( std::abs(m_A_Debye - m_last_A_Debye) < tol &&
std::abs(T - m_last_T) < tol &&
std::abs(P - m_last_P) < tol &&
!cropped_molalities_changed() ) {
return;
}
m_last_T = T;
m_last_P = P;
m_last_A_Debye = m_A_Debye;
/*
* Calculate the stoichiometric ionic charge. This isn't used in the
* Pitzer formulation.
@ -2964,6 +2944,11 @@ s_updatePitzer_lnMolalityActCoeff() const
void HMWSoln::s_update_dlnMolalityActCoeff_dT() const
{
if(s_update_dlnMolalityActCoeff_dT_valid) {
return;
}
s_update_dlnMolalityActCoeff_dT_valid = true;
/*
* Zero the unscaled 2nd derivatives
*/
@ -3813,6 +3798,11 @@ void HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dT() const
void HMWSoln::s_update_d2lnMolalityActCoeff_dT2() const
{
if(s_update_d2lnMolalityActCoeff_dT2_valid) {
return;
}
s_update_d2lnMolalityActCoeff_dT2_valid = true;
/*
* Zero the unscaled 2nd derivatives
*/
@ -4667,6 +4657,10 @@ void HMWSoln::s_updatePitzer_d2lnMolalityActCoeff_dT2() const
void HMWSoln::s_update_dlnMolalityActCoeff_dP() const
{
if(s_update_dlnMolalityActCoeff_dP_valid) {
return;
}
s_update_dlnMolalityActCoeff_dP_valid = true;
m_dlnActCoeffMolaldP_Unscaled.assign(m_kk, 0.0);
s_updatePitzer_dlnMolalityActCoeff_dP();
@ -5504,10 +5498,10 @@ void HMWSoln::s_updatePitzer_dlnMolalityActCoeff_dP() const
void HMWSoln::calc_lambdas(double is) const
{
const double tol = 1.e-12;
if( std::abs(is - m_last_is) < tol ) {
if( m_last_is == is ) {
return;
}
m_last_is = is;
double aphi, dj, jfunc, jprime, t, x, zprod;
int i, ij, j;
@ -5566,7 +5560,6 @@ void HMWSoln::calc_lambdas(double is) const
#endif
}
}
m_last_is = is;
}
void HMWSoln::calc_thetas(int z1, int z2,
@ -5885,6 +5878,19 @@ doublereal HMWSoln::s_NBS_CLM_dlnMolalityActCoeff_dP() const
return - dAdP * sqrtIs /(1.0 + 1.5 * sqrtIs);
}
void HMWSoln::invalidateCachedDataOnStateChange(StateVariable changed_var)
{
if( changed_var == PRESSURE || changed_var == TEMPERATURE ) {
m_A_Debye_valid = false;
m_dA_DebyedP_TP_valid = false;
}
s_update_lnMolalityActCoeff_valid = false;
s_update_dlnMolalityActCoeff_dT_valid = false;
s_update_d2lnMolalityActCoeff_dT2_valid = false;
s_update_dlnMolalityActCoeff_dP_valid = false;
MolalityVPSSTP::invalidateCachedDataOnStateChange(changed_var);
}
int HMWSoln::debugPrinting()
{
#ifdef DEBUG_MODE

View file

@ -23,8 +23,9 @@ namespace Cantera
MaskellSolidSolnPhase::MaskellSolidSolnPhase() :
m_Pref(OneAtm),
m_Pcurrent(OneAtm),
m_last_ac(2),
m_last_mole_frac_product(-1.0),
m_updateThermo_valid(false),
m_activity_coeffs(2),
m_activity_coeffs_valid(false),
m_h0_RT(2),
m_cp0_R(2),
m_g0_RT(2),
@ -38,8 +39,9 @@ MaskellSolidSolnPhase::MaskellSolidSolnPhase() :
MaskellSolidSolnPhase::MaskellSolidSolnPhase(const MaskellSolidSolnPhase& b) :
m_Pref(OneAtm),
m_Pcurrent(OneAtm),
m_last_ac(2),
m_last_mole_frac_product(-1.0),
m_updateThermo_valid(false),
m_activity_coeffs(2),
m_activity_coeffs_valid(false),
m_h0_RT(2),
m_cp0_R(2),
m_g0_RT(2),
@ -157,10 +159,10 @@ void MaskellSolidSolnPhase::setMolarDensity(const doublereal n)
void MaskellSolidSolnPhase::
getActivityCoefficients(doublereal* ac) const
{
bool temp_changed = _updateThermo();
const doublereal r = moleFraction(product_species_index);
const doublereal tol = 1.e-12;
if( temp_changed || std::abs(r - m_last_mole_frac_product) > tol ) {
_updateThermo();
if( !m_activity_coeffs_valid ) {
m_activity_coeffs_valid = true;
const doublereal r = moleFraction(product_species_index);
const doublereal pval = p(r);
const doublereal fmval = fm(r);
const doublereal rfm = r * fmval;
@ -168,11 +170,10 @@ getActivityCoefficients(doublereal* ac) const
const doublereal A = (std::pow(1 - rfm, pval) * std::pow(rfm, pval) * std::pow(r - rfm, 1 - pval)) /
(std::pow(1 - r - rfm, 1 + pval) * (1 - r));
const doublereal B = pval * h_mixing / RT;
m_last_ac[product_species_index] = A * std::exp(B);
m_last_ac[reactant_species_index] = 1 / (A * r * (1-r) ) * std::exp(-B);
m_last_mole_frac_product = r;
m_activity_coeffs[product_species_index] = A * std::exp(B);
m_activity_coeffs[reactant_species_index] = 1 / (A * r * (1-r) ) * std::exp(-B);
}
std::copy(m_last_ac.begin(), m_last_ac.end(), ac);
std::copy(m_activity_coeffs.begin(), m_activity_coeffs.end(), ac);
}
void MaskellSolidSolnPhase::
@ -323,14 +324,15 @@ void MaskellSolidSolnPhase::initThermoXML(XML_Node& phaseNode, const std::string
VPStandardStateTP::initThermoXML(phaseNode, id_);
}
bool MaskellSolidSolnPhase::_updateThermo() const
void MaskellSolidSolnPhase::_updateThermo() const
{
assert(m_kk == 2);
doublereal tnow = temperature();
if (m_tlast != tnow) {
if (!m_updateThermo_valid) {
m_updateThermo_valid = true;
/*
* Update the thermodynamic functions of the reference state.
*/
doublereal tnow = temperature();
m_spthermo->update(tnow, DATA_PTR(m_cp0_R), DATA_PTR(m_h0_RT),
DATA_PTR(m_s0_R));
m_tlast = tnow;
@ -338,9 +340,7 @@ bool MaskellSolidSolnPhase::_updateThermo() const
m_g0_RT[k] = m_h0_RT[k] - m_s0_R[k];
}
m_tlast = tnow;
return true;
}
return false;
}
doublereal MaskellSolidSolnPhase::s() const
@ -360,4 +360,11 @@ doublereal MaskellSolidSolnPhase::p(const doublereal r) const
return (1 - 2*r) / std::sqrt(sval*sval - 4 * sval * r + 4 * sval * r * r);
}
void MaskellSolidSolnPhase::invalidateCachedDataOnStateChange(StateVariable changed_var)
{
m_updateThermo_valid = false;
m_activity_coeffs_valid = false;
VPStandardStateTP::invalidateCachedDataOnStateChange(changed_var);
}
} // end namespace Cantera

View file

@ -332,6 +332,9 @@ void Phase::setMoleFractions(const doublereal* const x)
*/
m_mmw = sum/norm;
m_stateNum++;
if(massFractionsChanged()) {
invalidateCachedDataOnStateChange(SPECIES);
}
}
void Phase::setMoleFractions_NoNorm(const doublereal* const x)
@ -342,6 +345,9 @@ void Phase::setMoleFractions_NoNorm(const doublereal* const x)
transform(m_ym.begin(), m_ym.begin() + m_kk, m_molwts.begin(),
m_y.begin(), multiplies<double>());
m_stateNum++;
if(massFractionsChanged()) {
invalidateCachedDataOnStateChange(SPECIES);
}
}
void Phase::setMoleFractionsByName(compositionMap& xMap)
@ -376,6 +382,9 @@ void Phase::setMassFractions(const doublereal* const y)
m_ym.begin(), multiplies<double>());
m_mmw = 1.0 / accumulate(m_ym.begin(), m_ym.end(), 0.0);
m_stateNum++;
if(massFractionsChanged()) {
invalidateCachedDataOnStateChange(SPECIES);
}
}
void Phase::setMassFractions_NoNorm(const doublereal* const y)
@ -387,6 +396,9 @@ void Phase::setMassFractions_NoNorm(const doublereal* const y)
sum = accumulate(m_ym.begin(), m_ym.end(), 0.0);
m_mmw = 1.0/sum;
m_stateNum++;
if( massFractionsChanged() ) {
invalidateCachedDataOnStateChange(SPECIES);
}
}
void Phase::setMassFractionsByName(compositionMap& yMap)
@ -409,6 +421,22 @@ void Phase::setMassFractionsByName(const std::string& y)
setMassFractionsByName(c);
}
bool Phase::massFractionsChanged()
{
if(m_last_y.size() != m_kk) {
m_last_y.resize(m_kk);
std::fill(m_last_y.begin(), m_last_y.end(), -1.0);
}
bool result = false;
for(size_t k=0; k < m_kk; ++k) {
if(m_y[k] != m_last_y[k]) {
result = true;
}
}
return result;
}
void Phase::setState_TRX(doublereal t, doublereal dens, const doublereal* x)
{
setMoleFractions(x);