Skip to content

Commit

Permalink
[Thermo] Fix silent failures in HP/UV/SV/SP convergence
Browse files Browse the repository at this point in the history
In cases where the specified state was non-physical (i.e. corresponded to a
negative temperature), the iteration would exit when the temperature reached a
small enough value. Computing the error in temperature relative to the current
temperature avoids this problem.

Fixes #264
  • Loading branch information
speth committed Oct 19, 2016
1 parent 89d0c56 commit 5b1a4a6
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
16 changes: 16 additions & 0 deletions interfaces/cython/cantera/test/test_thermo.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,12 @@ def test_setSV_lowT(self):
self.assertNear(self.gas.v, 3 * v1)
self.assertTrue(self.gas.T < self.gas.min_temp)

def test_setSV_low_invalid(self):
self.gas.TPX = 450, 1e5, 'H2:1.0, O2:0.4, AR:3'
self.gas.SV = 4600, None
with self.assertRaises(ct.CanteraError):
self.gas.SV = -1000, None

def test_setSV_highT(self):
"""
Set state in terms of (s,v) when the end temperature is above the
Expand Down Expand Up @@ -675,6 +681,16 @@ def test_setHP_lowT(self):
self.assertNear(self.gas.P, p1)
self.assertTrue(self.gas.T < self.gas.min_temp)

def test_setHP_low_invalid(self):
"""
Set state in terms of (h,p) when the enthalpy would imply a negative
temperature
"""

self.gas.TPX = 300, 101325, 'H2:1.0'
with self.assertRaises(ct.CanteraError):
self.gas.HP = -4e6, 101325

def test_setHP_highT(self):
"""
Set state in terms of (s,v) when the end temperature is above the
Expand Down
8 changes: 4 additions & 4 deletions src/thermo/ThermoPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,9 +409,9 @@ void ThermoPhase::setState_HPorUV(doublereal Htarget, doublereal p,
// Convergence in H
double Herr = Htarget - Hnew;
double acpd = std::max(fabs(cpd), 1.0E-5);
double denom = std::max(fabs(Htarget), acpd * dTtol);
double denom = std::max(fabs(Htarget), acpd * Tnew);
double HConvErr = fabs((Herr)/denom);
if (HConvErr < 0.00001 *dTtol || fabs(dt) < dTtol) {
if (HConvErr < 0.00001 * dTtol || fabs(dt/Tnew) < 0.00001 * dTtol) {
return;
}
}
Expand Down Expand Up @@ -595,9 +595,9 @@ void ThermoPhase::setState_SPorSV(doublereal Starget, doublereal p,
// Convergence in S
double Serr = Starget - Snew;
double acpd = std::max(fabs(cpd), 1.0E-5);
double denom = std::max(fabs(Starget), acpd * dTtol);
double denom = std::max(fabs(Starget), acpd * Tnew);
double SConvErr = fabs((Serr * Tnew)/denom);
if (SConvErr < 0.00001 *dTtol || fabs(dt) < dTtol) {
if (SConvErr < 0.00001 * dTtol || fabs(dt/Tnew) < 0.00001 * dTtol) {
return;
}
}
Expand Down

0 comments on commit 5b1a4a6

Please sign in to comment.