Fix issues with pure fluids near temperature limits

Fixes Issue 186.
This commit is contained in:
Ray Speth 2013-11-12 23:44:51 +00:00
parent a7bd7c6a7a
commit cd572403df
3 changed files with 55 additions and 18 deletions

View file

@ -128,35 +128,41 @@ public:
//! Specific heat at constant volume [J/kg/K]
virtual double cv() {
double Tsave = T, dt = 1.e-4*T;
set_T(Tsave - dt);
double T1 = std::max(Tmin(), Tsave - dt);
double T2 = std::min(Tmax(), Tsave + dt);
set_T(T1);
double s1 = s();
set_T(Tsave + dt);
set_T(T2);
double s2 = s();
set_T(Tsave);
return T*(s2 - s1)/(2.0*dt);
return T*(s2 - s1)/(T2-T1);
}
//! Specific heat at constant pressure [J/kg/K]
virtual double cp() {
double Tsave = T, dt = 1.e-4*T;
double T1 = std::max(Tmin(), Tsave - dt);
double T2 = std::min(Tmax(), Tsave + dt);
double p0 = P();
Set(PropertyPair::TP, Tsave - dt, p0);
Set(PropertyPair::TP, T1, p0);
double s1 = s();
Set(PropertyPair::TP, Tsave + dt, p0);
Set(PropertyPair::TP, T2, p0);
double s2 = s();
Set(PropertyPair::TP, Tsave, p0);
return T*(s2 - s1)/(2.0*dt);
return T*(s2 - s1)/(T2-T1);
}
virtual double thermalExpansionCoeff() {
double Tsave = T, dt = 1.e-4*T;
double T1 = std::max(Tmin(), Tsave - dt);
double T2 = std::min(Tmax(), Tsave + dt);
double p0 = P();
Set(PropertyPair::TP, Tsave - dt, p0);
Set(PropertyPair::TP, T1, p0);
double v1 = v();
Set(PropertyPair::TP, Tsave + dt, p0);
Set(PropertyPair::TP, T2, p0);
double v2 = v();
Set(PropertyPair::TP, Tsave, p0);
return (v2 - v1)/((v2 + v1)*dt);
return (v2 - v1)/((v2 + v1)*(T2-T1));
}
virtual double isothermalCompressibility() {

View file

@ -18,3 +18,37 @@ class TestPureFluid(utilities.CanteraTest):
self.water.TX = 500, 0.8
self.assertNear(self.water.T, 500)
self.assertNear(self.water.X, 0.8)
def test_set_minmax(self):
self.water.TP = self.water.min_temp, 101325
self.assertNear(self.water.T, self.water.min_temp)
self.water.TP = self.water.max_temp, 101325
self.assertNear(self.water.T, self.water.max_temp)
def check_fd_properties(self, T1, P1, T2, P2, tol):
# Properties which are computed as finite differences
self.water.TP = T1, P1
cp1 = self.water.cp_mass
cv1 = self.water.cv_mass
k1 = self.water.isothermal_compressibility
alpha1 = self.water.thermal_expansion_coeff
self.water.TP = T2, P2
cp2 = self.water.cp_mass
cv2 = self.water.cv_mass
k2 = self.water.isothermal_compressibility
alpha2 = self.water.thermal_expansion_coeff
self.assertNear(cp1, cp2, tol)
self.assertNear(cv1, cv2, tol)
self.assertNear(k1, k2, tol)
self.assertNear(alpha1, alpha2, tol)
def test_properties_near_min(self):
self.check_fd_properties(self.water.min_temp*(1+1e-5), 101325,
self.water.min_temp*(1+1e-4), 101325, 1e-2)
def test_properties_near_max(self):
self.check_fd_properties(self.water.max_temp*(1-1e-5), 101325,
self.water.max_temp*(1-1e-4), 101325, 1e-2)

View file

@ -5,6 +5,7 @@
*/
#include "cantera/tpx/Sub.h"
#include "cantera/base/stringUtils.h"
#include "cantera/base/global.h"
using std::string;
using namespace Cantera;
@ -35,9 +36,9 @@ double Substance::dPsdT()
{
double tsave = T;
double ps1 = Ps();
set_T(T + DeltaT);
T = T + DeltaT;
double dpdt = (Ps() - ps1)/DeltaT;
set_T(tsave);
T = tsave;
return dpdt;
}
@ -387,7 +388,7 @@ int Substance::Lever(int itp, double sat, double val, propertyFlag::type ifunc)
if (sat >= Tcrit()) {
return 0;
}
set_T(sat);
T = sat;
psat = Ps();
} else if (itp == Pgiven) {
if (sat >= Pcrit()) {
@ -506,11 +507,7 @@ void Substance::set_xy(propertyFlag::type ifx, propertyFlag::type ify,
}
v_here += dv;
t_here += dt;
if (t_here >= Tmax()) {
t_here = Tmax() - 0.001;
} else if (t_here <= Tmin()) {
t_here = Tmin() + 0.001;
}
t_here = clip(t_here, Tmin(), Tmax());
if (v_here <= 0.0) {
v_here = 0.0001;
}
@ -580,7 +577,7 @@ void Substance::set_TPp(double Temp, double Pressure)
int LoopCount = 0;
double v_save = 1.0/Rho;
set_T(Temp);
T = Temp;
v_here = vp();
// loop