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.
This commit is contained in:
Victor Brunini 2014-03-19 00:14:18 +00:00
parent 935a20fc87
commit a641992960
3 changed files with 74 additions and 50 deletions

View file

@ -33,6 +33,71 @@ struct CachedValue {
stateNum(std::numeric_limits<int>::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;

View file

@ -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();

View file

@ -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++) {