Skip to content

Commit

Permalink
[Thermo] change default state for IdealSolidSolnPhase
Browse files Browse the repository at this point in the history
- Fixes Cantera#595
  • Loading branch information
Ingmar Schoegl committed Oct 4, 2019
1 parent 4473bc7 commit 2b940d0
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 3 deletions.
6 changes: 6 additions & 0 deletions include/cantera/thermo/IdealSolidSolnPhase.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ class IdealSolidSolnPhase : public ThermoPhase
return "IdealSolidSoln";
}

virtual std::vector<std::string> defaultState() const;
virtual std::vector<std::string> fullStates() const;
virtual std::vector<std::string> partialStates() const;
virtual void saveState(size_t lenstate, doublereal* state) const;
virtual void restoreState(size_t lenstate, const doublereal* state);

//! @name Molar Thermodynamic Properties of the Solution
//! @{

Expand Down
3 changes: 0 additions & 3 deletions include/cantera/thermo/Phase.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ namespace Cantera
* complicated assemblies of %Cantera Phases.
*
* @todo
* - Make the concept of saving state vectors more general, so that it can
* handle other cases where there are additional internal state variables,
* such as the voltage, a potential energy, or a strain field.
* - Specify that the input mole, mass, and volume fraction vectors must sum
* to one on entry to the set state routines. Non-conforming mole/mass
* fraction vectors are not thermodynamically consistent. Moreover, unless
Expand Down
35 changes: 35 additions & 0 deletions interfaces/cython/cantera/thermo.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,17 @@ cdef class ThermoPhase(_SolutionBase):
states = self.thermo.partialStates()
states = [s.decode('utf-8') for s in states]
return {frozenset(k): k for k in states}

def _check_property(self, prop):
"""
Check whether *prop* represents a valid (partial) thermodynamic state
"""
valid = any([prop in self._full_states.values(),
prop in self._partial_states.values()])
if not valid:
raise AttributeError("Setter/getter '{}' is not defined "
"for phase '{}'".format(prop, self.name))
return valid

property name:
"""
Expand Down Expand Up @@ -1015,8 +1026,10 @@ cdef class ThermoPhase(_SolutionBase):
property TD:
"""Get/Set temperature [K] and density [kg/m^3 or kmol/m^3]."""
def __get__(self):
self._check_property('TD')
return self.T, self.density
def __set__(self, values):
self._check_property('TD')
assert len(values) == 2, 'incorrect number of values'
T = values[0] if values[0] is not None else self.T
D = values[1] if values[1] is not None else self.density
Expand All @@ -1028,8 +1041,10 @@ cdef class ThermoPhase(_SolutionBase):
fractions.
"""
def __get__(self):
self._check_property('TDX')
return self.T, self.density, self.X
def __set__(self, values):
self._check_property('TDX')
assert len(values) == 3, 'incorrect number of values'
T = values[0] if values[0] is not None else self.T
D = values[1] if values[1] is not None else self.density
Expand All @@ -1042,8 +1057,10 @@ cdef class ThermoPhase(_SolutionBase):
fractions.
"""
def __get__(self):
self._check_property('TDY')
return self.T, self.density, self.Y
def __set__(self, values):
self._check_property('TDY')
assert len(values) == 3, 'incorrect number of values'
T = values[0] if values[0] is not None else self.T
D = values[1] if values[1] is not None else self.density
Expand Down Expand Up @@ -1088,8 +1105,10 @@ cdef class ThermoPhase(_SolutionBase):
[m^3/kg or m^3/kmol].
"""
def __get__(self):
self._check_property('UV')
return self.u, self.v
def __set__(self, values):
self._check_property('UV')
assert len(values) == 2, 'incorrect number of values'
U = values[0] if values[0] is not None else self.u
V = values[1] if values[1] is not None else self.v
Expand All @@ -1102,8 +1121,10 @@ cdef class ThermoPhase(_SolutionBase):
[m^3/kg or m^3/kmol], and mole fractions.
"""
def __get__(self):
self._check_property('UVX')
return self.u, self.v, self.X
def __set__(self, values):
self._check_property('UVX')
assert len(values) == 3, 'incorrect number of values'
U = values[0] if values[0] is not None else self.u
V = values[1] if values[1] is not None else self.v
Expand All @@ -1117,8 +1138,10 @@ cdef class ThermoPhase(_SolutionBase):
[m^3/kg or m^3/kmol], and mass fractions.
"""
def __get__(self):
self._check_property('UVY')
return self.u, self.v, self.Y
def __set__(self, values):
self._check_property('UVY')
assert len(values) == 3, 'incorrect number of values'
U = values[0] if values[0] is not None else self.u
V = values[1] if values[1] is not None else self.v
Expand All @@ -1129,8 +1152,10 @@ cdef class ThermoPhase(_SolutionBase):
property DP:
"""Get/Set density [kg/m^3] and pressure [Pa]."""
def __get__(self):
self._check_property('DP')
return self.density, self.P
def __set__(self, values):
self._check_property('DP')
assert len(values) == 2, 'incorrect number of values'
D = values[0] if values[0] is not None else self.density
P = values[1] if values[1] is not None else self.P
Expand All @@ -1139,8 +1164,10 @@ cdef class ThermoPhase(_SolutionBase):
property DPX:
"""Get/Set density [kg/m^3], pressure [Pa], and mole fractions."""
def __get__(self):
self._check_property('DPX')
return self.density, self.P, self.X
def __set__(self, values):
self._check_property('DPX')
assert len(values) == 3, 'incorrect number of values'
D = values[0] if values[0] is not None else self.density
P = values[1] if values[1] is not None else self.P
Expand All @@ -1150,8 +1177,10 @@ cdef class ThermoPhase(_SolutionBase):
property DPY:
"""Get/Set density [kg/m^3], pressure [Pa], and mass fractions."""
def __get__(self):
self._check_property('DPY')
return self.density, self.P, self.Y
def __set__(self, values):
self._check_property('DPY')
assert len(values) == 3, 'incorrect number of values'
D = values[0] if values[0] is not None else self.density
P = values[1] if values[1] is not None else self.P
Expand Down Expand Up @@ -1228,8 +1257,10 @@ cdef class ThermoPhase(_SolutionBase):
m^3/kmol].
"""
def __get__(self):
self._check_property('SV')
return self.s, self.v
def __set__(self, values):
self._check_property('SV')
assert len(values) == 2, 'incorrect number of values'
S = values[0] if values[0] is not None else self.s
V = values[1] if values[1] is not None else self.v
Expand All @@ -1242,8 +1273,10 @@ cdef class ThermoPhase(_SolutionBase):
m^3/kmol], and mole fractions.
"""
def __get__(self):
self._check_property('SVX')
return self.s, self.v, self.X
def __set__(self, values):
self._check_property('SVX')
assert len(values) == 3, 'incorrect number of values'
S = values[0] if values[0] is not None else self.s
V = values[1] if values[1] is not None else self.v
Expand All @@ -1257,8 +1290,10 @@ cdef class ThermoPhase(_SolutionBase):
m^3/kmol], and mass fractions.
"""
def __get__(self):
self._check_property('SVY')
return self.s, self.v, self.Y
def __set__(self, values):
self._check_property('SVY')
assert len(values) == 3, 'incorrect number of values'
S = values[0] if values[0] is not None else self.s
V = values[1] if values[1] is not None else self.v
Expand Down
39 changes: 39 additions & 0 deletions src/thermo/IdealSolidSolnPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,45 @@ IdealSolidSolnPhase::IdealSolidSolnPhase(XML_Node& root, const std::string& id_,
importPhase(root, this);
}

vector<std::string> IdealSolidSolnPhase::defaultState() const
{
const vector<std::string> props = {"T", "P", "Y"};

return props;
}

vector<std::string> IdealSolidSolnPhase::fullStates() const
{
const vector<std::string> states = {"TPX", "TPY", "HPX", "HPY",
"SPX", "SPY"};
return states;
}

vector<std::string> IdealSolidSolnPhase::partialStates() const
{
const vector<std::string> states = {"TP", "HP", "SP"};
return states;
}

void IdealSolidSolnPhase::saveState(size_t lenstate, doublereal* state) const
{
state[0] = temperature();
state[1] = pressure();
getMassFractions(state + 2);
}

void IdealSolidSolnPhase::restoreState(size_t lenstate, const doublereal* state)
{
if (lenstate >= nSpecies() + 2) {
setMassFractions_NoNorm(state + 2);
setTemperature(state[0]);
setPressure(state[1]);
} else {
throw ArraySizeError("IdealSolidSolnPhase::restoreState",
lenstate,nSpecies()+2);
}
}

// Molar Thermodynamic Properties of the Solution

doublereal IdealSolidSolnPhase::enthalpy_mole() const
Expand Down

0 comments on commit 2b940d0

Please sign in to comment.