From a641992960236cdb4123489e5226503aac3c069c Mon Sep 17 00:00:00 2001 From: Victor Brunini Date: Wed, 19 Mar 2014 00:14:18 +0000 Subject: [PATCH] Add validate() functions to CachedValue. To both check and update the cached state values. Reduces a lot of code duplication in the use of CachedValues. I'd like to make state1, state2, and stateNum private so that they can only be accessed with one of the validate functions, and also add some asserts to the validate functions that do not use all of the state variables to ensure that the unused ones are set to their default values to prevent the case where the wrong validate() function is called and incorrectly determines that the cached state is valid. First pass at making the state variables private caused a test failure for test_problems/statmech. The m_spthermo->update() call in IdealGasPhase::_updateThermo() throws an exception for this test right now that gets caught in equilibrate(). When using validate() the cached state variable is updated before the m_spthermo->update() call and subsequently it thinks that the thermo does not need to be updated, whereas when cached.state1 is being set after the m_spthermo->update() call it does not get set. The current blessed output for that test is just the text of the exception that gets caught, so I suspect the test may not work as is. --- include/cantera/base/ValueCache.h | 65 ++++++++++++++++++++++++++++ src/thermo/HMWSoln.cpp | 48 +++----------------- src/thermo/MaskellSolidSolnPhase.cpp | 11 +---- 3 files changed, 74 insertions(+), 50 deletions(-) diff --git a/include/cantera/base/ValueCache.h b/include/cantera/base/ValueCache.h index e1f89b897..f64cbc0ae 100644 --- a/include/cantera/base/ValueCache.h +++ b/include/cantera/base/ValueCache.h @@ -33,6 +33,71 @@ struct CachedValue { stateNum(std::numeric_limits::min()) { } + + //! Check whether the currently cached value is valid based on + //! a single state variable. If it is not valid it updates the stored + //! state to the new state in addition to returning false. + bool validate(double state1New) { + if(state1 == state1New) { + return true; + } else { + state1 = state1New; + } + return false; + } + + //! Check whether the currently cached value is valid based on + //! state1 and state2. If it is not valid it updates the stored + //! state to the new state in addition to returning false. + bool validate(double state1New, double state2New) { + if(state1 == state1New && state2 == state2New) { + return true; + } else { + state1 = state1New; + state2 = state2New; + } + return false; + } + + //! Check whether the currently cached value is valid based on + //! state1 and stateNum. If it is not valid it updates the stored + //! state to the new state in addition to returning false. + bool validate(double state1New, int stateNumNew) { + if(state1 == state1New && stateNum == stateNumNew) { + return true; + } else { + state1 = state1New; + stateNum = stateNumNew; + } + return false; + } + + //! Check whether the currently cached value is valid based on + //! stateNum. If it is not valid it updates the stored + //! state to the new state in addition to returning false. + bool validate(int stateNumNew) { + if(stateNum == stateNumNew) { + return true; + } else { + stateNum = stateNumNew; + } + return false; + } + + //! Check whether the currently cached value is valid based on + //! state1, state2, and stateNum. If it is not valid it updates the stored + //! state to the new state in addition to returning false. + bool validate(double state1New, double state2New, int stateNumNew) { + if(state1 == state1New && state2 == state2New && stateNum == stateNumNew) { + return true; + } else { + state1 = state1New; + state2 = state2New; + stateNum = stateNumNew; + } + return false; + } + //! Value of the first state variable for the state at which #value was //! evaluated, e.g. temperature. double state1; diff --git a/src/thermo/HMWSoln.cpp b/src/thermo/HMWSoln.cpp index bcd3e8db6..d8af26919 100644 --- a/src/thermo/HMWSoln.cpp +++ b/src/thermo/HMWSoln.cpp @@ -683,15 +683,9 @@ void HMWSoln::calcDensity() { static const int cacheId = m_cache.getId(); CachedScalar cached = m_cache.getScalar(cacheId); - const doublereal tnow = temperature(); - const doublereal pnow = pressure(); - const int stateNumNow = stateMFNumber(); - if( cached.state1 == tnow && cached.state2 == pnow && cached.stateNum == stateNumNow ) { + if(cached.validate(temperature(), pressure(), stateMFNumber())) { return; } - cached.state1 = tnow; - cached.state2 = pnow; - cached.stateNum = stateNumNow; double* vbar = &m_pp[0]; getPartialMolarVolumes(vbar); @@ -1051,11 +1045,9 @@ double HMWSoln::A_Debye_TP(double tempArg, double presArg) const static const int cacheId = m_cache.getId(); CachedScalar cached = m_cache.getScalar(cacheId); - if(cached.state1 == T && cached.state2 == P) { + if(cached.validate(T, P)) { return m_A_Debye; } - cached.state1 = T; - cached.state2 = P; switch (m_form_A_Debye) { case A_DEBYE_CONST: @@ -1117,11 +1109,9 @@ double HMWSoln::dA_DebyedP_TP(double tempArg, double presArg) const dAdP = 0.0; break; case A_DEBYE_WATER: - if( cached.state1 == T && cached.state2 == P ) { + if(cached.validate(T, P)) { dAdP = cached.value; } else { - cached.state1 = T; - cached.state2 = P; dAdP = m_waterProps->ADebye(T, P, 3); cached.value = dAdP; } @@ -1346,15 +1336,9 @@ void HMWSoln::s_update_lnMolalityActCoeff() const { static const int cacheId = m_cache.getId(); CachedScalar cached = m_cache.getScalar(cacheId); - const doublereal tnow = temperature(); - const doublereal pnow = pressure(); - const int stateNumNow = stateMFNumber(); - if( cached.state1 == tnow && cached.state2 == pnow && cached.stateNum == stateNumNow ) { + if( cached.validate(temperature(), pressure(), stateMFNumber()) ) { return; } - cached.state1 = tnow; - cached.state2 = pnow; - cached.stateNum = stateNumNow; /* * Calculate the molalities. Currently, the molalities @@ -2955,15 +2939,9 @@ void HMWSoln::s_update_dlnMolalityActCoeff_dT() const { static const int cacheId = m_cache.getId(); CachedScalar cached = m_cache.getScalar(cacheId); - const doublereal tnow = temperature(); - const doublereal pnow = pressure(); - const int stateNumNow = stateMFNumber(); - if( cached.state1 == tnow && cached.state2 == pnow && cached.stateNum == stateNumNow ) { + if( cached.validate(temperature(), pressure(), stateMFNumber()) ) { return; } - cached.state1 = tnow; - cached.state2 = pnow; - cached.stateNum = stateNumNow; /* * Zero the unscaled 2nd derivatives @@ -3816,15 +3794,9 @@ void HMWSoln::s_update_d2lnMolalityActCoeff_dT2() const { static const int cacheId = m_cache.getId(); CachedScalar cached = m_cache.getScalar(cacheId); - const doublereal tnow = temperature(); - const doublereal pnow = pressure(); - const int stateNumNow = stateMFNumber(); - if( cached.state1 == tnow && cached.state2 == pnow && cached.stateNum == stateNumNow ) { + if( cached.validate(temperature(), pressure(), stateMFNumber()) ) { return; } - cached.state1 = tnow; - cached.state2 = pnow; - cached.stateNum = stateNumNow; /* * Zero the unscaled 2nd derivatives @@ -4682,15 +4654,9 @@ void HMWSoln::s_update_dlnMolalityActCoeff_dP() const { static const int cacheId = m_cache.getId(); CachedScalar cached = m_cache.getScalar(cacheId); - const doublereal tnow = temperature(); - const doublereal pnow = pressure(); - const int stateNumNow = stateMFNumber(); - if( cached.state1 == tnow && cached.state2 == pnow && cached.stateNum == stateNumNow ) { + if( cached.validate(temperature(), pressure(), stateMFNumber()) ) { return; } - cached.state1 = tnow; - cached.state2 = pnow; - cached.stateNum = stateNumNow; m_dlnActCoeffMolaldP_Unscaled.assign(m_kk, 0.0); s_updatePitzer_dlnMolalityActCoeff_dP(); diff --git a/src/thermo/MaskellSolidSolnPhase.cpp b/src/thermo/MaskellSolidSolnPhase.cpp index 176458af7..d56a0674d 100644 --- a/src/thermo/MaskellSolidSolnPhase.cpp +++ b/src/thermo/MaskellSolidSolnPhase.cpp @@ -156,13 +156,7 @@ getActivityCoefficients(doublereal* ac) const _updateThermo(); static const int cacheId = m_cache.getId(); CachedArray cached = m_cache.getArray(cacheId); - const doublereal tnow = temperature(); - const doublereal pnow = pressure(); - const int stateNumNow = stateMFNumber(); - if( cached.state1 != temperature() || cached.state2 != pressure() || cached.stateNum != stateNumNow ) { - cached.state1 = tnow; - cached.state2 = pnow; - cached.stateNum = stateNumNow; + if( !cached.validate(temperature(), pressure(), stateMFNumber()) ) { cached.value.resize(2); const doublereal r = moleFraction(product_species_index); @@ -336,9 +330,8 @@ void MaskellSolidSolnPhase::_updateThermo() const * Update the thermodynamic functions of the reference state. */ doublereal tnow = temperature(); - if( cached.state1 != tnow ) + if( !cached.validate(tnow) ) { - cached.state1 = tnow; m_spthermo->update(tnow, DATA_PTR(m_cp0_R), DATA_PTR(m_h0_RT), DATA_PTR(m_s0_R)); for (size_t k = 0; k < m_kk; k++) {