Skip to content

Commit

Permalink
[Thermo] Replace RootFind with Boost in RedlichKwongMFTP
Browse files Browse the repository at this point in the history
As previously implemented, calling densSpinodalLiquid or densSpinodalGas would
crash since the pointer fdpdv_ was uninitialized, and furthermore could not even
be initialized with an instance of the spinodalFunc class because this class was
abstract.

Also fix densSpinodalLiquid and densSpinodalGas to actually calculate the roots
of the equation of state which are used as bounds for the search interval.
  • Loading branch information
speth committed Nov 4, 2016
1 parent 1453358 commit da87260
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 53 deletions.
10 changes: 0 additions & 10 deletions include/cantera/thermo/MixtureFugacityTP.h
Original file line number Diff line number Diff line change
Expand Up @@ -551,14 +551,6 @@ class MixtureFugacityTP : public ThermoPhase

//@}

class spinodalFunc : public ResidEval
{
public:
spinodalFunc(MixtureFugacityTP* tp);
virtual int evalSS(const doublereal t, const doublereal* const y, doublereal* const r);
MixtureFugacityTP* m_tp;
};

protected:
virtual void invalidateCache();

Expand Down Expand Up @@ -604,8 +596,6 @@ class MixtureFugacityTP : public ThermoPhase

//! Temporary storage for dimensionless reference state entropies
mutable vector_fp m_s0_R;

spinodalFunc* fdpdv_;
};
}

Expand Down
14 changes: 0 additions & 14 deletions src/thermo/MixtureFugacityTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,20 +546,6 @@ void MixtureFugacityTP::updateMixingExpressions()
{
}

MixtureFugacityTP::spinodalFunc::spinodalFunc(MixtureFugacityTP* tp) :
m_tp(tp)
{
}

int MixtureFugacityTP::spinodalFunc::evalSS(const doublereal t, const doublereal* const y,
doublereal* const r)
{
doublereal molarVol = y[0];
doublereal pp;
r[0] = m_tp->dpdVCalc(m_tp->temperature(), molarVol, pp);
return 0;
}

int MixtureFugacityTP::corr0(doublereal TKelvin, doublereal pres, doublereal& densLiqGuess,
doublereal& densGasGuess, doublereal& liqGRT, doublereal& gasGRT)
{
Expand Down
60 changes: 31 additions & 29 deletions src/thermo/RedlichKwongMFTP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@
#include "cantera/thermo/RedlichKwongMFTP.h"
#include "cantera/thermo/mix_defs.h"
#include "cantera/thermo/ThermoFactory.h"
#include "cantera/numerics/RootFind.h"
#include "cantera/base/stringUtils.h"
#include "cantera/base/ctml.h"

#include <boost/math/tools/roots.hpp>

using namespace std;
namespace bmt = boost::math::tools;

namespace Cantera
{
Expand Down Expand Up @@ -899,46 +901,46 @@ doublereal RedlichKwongMFTP::densityCalc(doublereal TKelvin, doublereal presPa,

doublereal RedlichKwongMFTP::densSpinodalLiquid() const
{
if (NSolns_ != 3) {
double Vroot[3];
double T = temperature();
int nsol = NicholsSolve(T, pressure(), m_a_current, m_b_current, Vroot);
if (nsol != 3) {
return critDensity();
}
double vmax = Vroot_[1];
double vmin = Vroot_[0];
RootFind rf(fdpdv_);
rf.setPrintLvl(10);
rf.setTol(1.0E-5, 1.0E-10);
rf.setFuncIsGenerallyDecreasing(true);

double vbest = 0.5 * (Vroot_[0]+Vroot_[1]);
double funcNeeded = 0.0;
int status = rf.solve(vmin, vmax, 100, funcNeeded, &vbest);
if (status != ROOTFIND_SUCCESS) {
throw CanteraError(" RedlichKwongMFTP::densSpinodalLiquid() ", "didn't converge");
}
auto resid = [this, T](double v) {
double pp;
return dpdVCalc(T, v, pp);
};

boost::uintmax_t maxiter = 100;
std::pair<double, double> vv = bmt::toms748_solve(
resid, Vroot[0], Vroot[1], bmt::eps_tolerance<double>(48), maxiter);

doublereal mmw = meanMolecularWeight();
return mmw / vbest;
return mmw / (0.5 * (vv.first + vv.second));
}

doublereal RedlichKwongMFTP::densSpinodalGas() const
{
if (NSolns_ != 3) {
double Vroot[3];
double T = temperature();
int nsol = NicholsSolve(T, pressure(), m_a_current, m_b_current, Vroot);
if (nsol != 3) {
return critDensity();
}
double vmax = Vroot_[2];
double vmin = Vroot_[1];
RootFind rf(fdpdv_);
rf.setPrintLvl(10);
rf.setTol(1.0E-5, 1.0E-10);
rf.setFuncIsGenerallyIncreasing(true);

double vbest = 0.5 * (Vroot_[1]+Vroot_[2]);
double funcNeeded = 0.0;
int status = rf.solve(vmin, vmax, 100, funcNeeded, &vbest);
if (status != ROOTFIND_SUCCESS) {
throw CanteraError(" RedlichKwongMFTP::densSpinodalGas() ", "didn't converge");
}
auto resid = [this, T](double v) {
double pp;
return dpdVCalc(T, v, pp);
};

boost::uintmax_t maxiter = 100;
std::pair<double, double> vv = bmt::toms748_solve(
resid, Vroot[1], Vroot[2], bmt::eps_tolerance<double>(48), maxiter);

doublereal mmw = meanMolecularWeight();
return mmw / vbest;
return mmw / (0.5 * (vv.first + vv.second));
}

doublereal RedlichKwongMFTP::pressureCalc(doublereal TKelvin, doublereal molarVol) const
Expand Down

0 comments on commit da87260

Please sign in to comment.