[Python] Add ability to create ThermoPhase objects from Species
This makes it possible to create a phase without ever generating a CTI or XML description. Does not yet work with phase types that require additional parameters.
This commit is contained in:
parent
9fdf7c0c59
commit
dc3af8a58d
3 changed files with 56 additions and 11 deletions
|
|
@ -84,6 +84,11 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
|
|||
cbool getElementPotentials(double*) except +
|
||||
void equilibrate(string, string, double, int, int, int, int) except +
|
||||
|
||||
# initialization
|
||||
void addUndefinedElements() except +
|
||||
cbool addSpecies(shared_ptr[CxxSpecies]) except +
|
||||
void initThermo() except +
|
||||
|
||||
# basic thermodynamic properties
|
||||
double temperature() except +
|
||||
double pressure() except +
|
||||
|
|
@ -387,9 +392,11 @@ cdef extern from "cantera/zeroD/ReactorNet.h":
|
|||
cdef extern from "cantera/thermo/ThermoFactory.h" namespace "Cantera":
|
||||
cdef CxxThermoPhase* newPhase(string, string) except +
|
||||
cdef CxxThermoPhase* newPhase(XML_Node&) except +
|
||||
cdef CxxThermoPhase* newThermoPhase(string) except +
|
||||
|
||||
cdef extern from "cantera/kinetics/KineticsFactory.h" namespace "Cantera":
|
||||
cdef CxxKinetics* newKineticsMgr(XML_Node&, vector[CxxThermoPhase*]) except +
|
||||
cdef CxxKinetics* CxxNewKinetics "Cantera::newKineticsMgr" (string) except +
|
||||
|
||||
cdef extern from "cantera/transport/TransportFactory.h" namespace "Cantera":
|
||||
cdef CxxTransport* newDefaultTransportMgr(CxxThermoPhase*) except +
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
cdef class _SolutionBase:
|
||||
def __cinit__(self, infile='', phaseid='', phases=(), origin=None,
|
||||
source=None, **kwargs):
|
||||
source=None, thermo=None, species=(), **kwargs):
|
||||
# Shallow copy of an existing Solution (for slicing support)
|
||||
cdef _SolutionBase other
|
||||
if origin is not None:
|
||||
|
|
@ -18,13 +18,31 @@ cdef class _SolutionBase:
|
|||
self._selected_species = other._selected_species.copy()
|
||||
return
|
||||
|
||||
# Instantiate a set of new Cantera C++ objects
|
||||
if infile or source:
|
||||
self._init_cti_xml(infile, phaseid, phases, source)
|
||||
elif thermo and species:
|
||||
self._init_parts(thermo, species)
|
||||
else:
|
||||
raise ValueError("Arguments are insufficient to define a phase")
|
||||
|
||||
# Initialization of transport is deferred to Transport.__init__
|
||||
self.transport = NULL
|
||||
|
||||
self._selected_species = np.ndarray(0, dtype=np.integer)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if isinstance(self, Transport):
|
||||
assert self.transport is not NULL
|
||||
|
||||
def _init_cti_xml(self, infile, phaseid, phases, source):
|
||||
"""
|
||||
Instantiate a set of new Cantera C++ objects from a CTI or XML
|
||||
phase definition
|
||||
"""
|
||||
if infile:
|
||||
rootNode = CxxGetXmlFile(stringify(infile))
|
||||
elif source:
|
||||
rootNode = CxxGetXmlFromString(stringify(source))
|
||||
else:
|
||||
raise ValueError('No phase definition provided')
|
||||
|
||||
# Get XML data
|
||||
cdef XML_Node* phaseNode
|
||||
|
|
@ -54,14 +72,21 @@ cdef class _SolutionBase:
|
|||
else:
|
||||
self.kinetics = NULL
|
||||
|
||||
# Initialization of transport is deferred to Transport.__init__
|
||||
self.transport = NULL
|
||||
def _init_parts(self, thermo, species):
|
||||
"""
|
||||
Instantiate a set of new Cantera C++ objects based on a string defining
|
||||
the model type and a list of Species objects.
|
||||
"""
|
||||
self.thermo = newThermoPhase(stringify(thermo))
|
||||
self.thermo.addUndefinedElements()
|
||||
cdef Species S
|
||||
for S in species:
|
||||
self.thermo.addSpecies(S._species)
|
||||
self.thermo.initThermo()
|
||||
|
||||
self._selected_species = np.ndarray(0, dtype=np.integer)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
if isinstance(self, Transport):
|
||||
assert self.transport is not NULL
|
||||
if isinstance(self, Kinetics):
|
||||
# Not yet implemented
|
||||
self.kinetics = CxxNewKinetics(stringify("none"))
|
||||
|
||||
def __getitem__(self, selection):
|
||||
copy = self.__class__(origin=self)
|
||||
|
|
|
|||
|
|
@ -620,6 +620,19 @@ ideal_gas(name='spam', elements='O H',
|
|||
gas = ct.Solution(source=xml_def)
|
||||
self.check(gas, 'spam', 350, 2e6, 2, 1)
|
||||
|
||||
def test_import_from_species(self):
|
||||
gas1 = ct.Solution('h2o2.xml')
|
||||
gas1.TPX = 350, 101325, 'H2:0.3, O2:0.7'
|
||||
gas1.equilibrate('HP')
|
||||
|
||||
species = ct.Species.listFromFile('h2o2.xml')
|
||||
gas2 = ct.ThermoPhase(thermo='IdealGas', species=species)
|
||||
gas2.TPX = 350, 101325, 'H2:0.3, O2:0.7'
|
||||
gas2.equilibrate('HP')
|
||||
self.assertEqual(gas1.n_elements, gas2.n_elements)
|
||||
self.assertEqual(gas1.species_names, gas2.species_names)
|
||||
self.assertNear(gas1.T, gas2.T)
|
||||
self.assertArrayNear(gas1.X, gas2.X)
|
||||
|
||||
def test_checkReactionBalance(self):
|
||||
with self.assertRaises(Exception):
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue