[Python] Add functions for creating Species objects from CTI/XML
This commit is contained in:
parent
64c66437eb
commit
a4ba47594c
5 changed files with 177 additions and 11 deletions
|
|
@ -53,6 +53,17 @@ public:
|
|||
//! Create a new Species object from a 'species' XML_Node.
|
||||
shared_ptr<Species> newSpecies(const XML_Node& species_node);
|
||||
|
||||
//! Generate Species objects for all <species> nodes in an XML document.
|
||||
//!
|
||||
//! The <species> nodes are assumed to be children of the <speciesData> node in
|
||||
//! an XML document with a <ctml> root node, as in the case of XML files
|
||||
//! produced by conversion from CTI files.
|
||||
//!
|
||||
//! This function can be used in combination with get_XML_File and
|
||||
//! get_XML_from_string to get Species objects from either a file or a string,
|
||||
//! respectively, where the string or file is formatted as either CTI or XML.
|
||||
std::vector<shared_ptr<Species> > getSpecies(const XML_Node& node);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ cdef extern from "cantera/thermo/SpeciesThermoFactory.h":
|
|||
cdef CxxSpeciesThermo* CxxNewSpeciesThermo "Cantera::newSpeciesThermoInterpType"\
|
||||
(int, double, double, double, double*) except +
|
||||
|
||||
cdef extern from "cantera/thermo/Species.h":
|
||||
cdef extern from "cantera/thermo/Species.h" namespace "Cantera":
|
||||
cdef cppclass CxxSpecies "Cantera::Species":
|
||||
CxxSpecies()
|
||||
CxxSpecies(string, stdmap[string,double])
|
||||
|
|
@ -64,6 +64,9 @@ cdef extern from "cantera/thermo/Species.h":
|
|||
double charge
|
||||
double size
|
||||
|
||||
cdef shared_ptr[CxxSpecies] CxxNewSpecies "newSpecies" (XML_Node&)
|
||||
cdef vector[shared_ptr[CxxSpecies]] CxxGetSpecies "getSpecies" (XML_Node&)
|
||||
|
||||
cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
|
||||
cdef cppclass CxxThermoPhase "Cantera::ThermoPhase":
|
||||
CxxThermoPhase()
|
||||
|
|
|
|||
|
|
@ -627,6 +627,9 @@ ideal_gas(name='spam', elements='O H',
|
|||
|
||||
|
||||
class TestSpecies(utilities.CanteraTest):
|
||||
def setUp(self):
|
||||
self.gas = ct.Solution('h2o2.xml')
|
||||
|
||||
def test_standalone(self):
|
||||
s = ct.Species('CH4', {'C':1, 'H':4})
|
||||
|
||||
|
|
@ -642,22 +645,82 @@ class TestSpecies(utilities.CanteraTest):
|
|||
self.assertEqual(s.charge, 0.0)
|
||||
|
||||
def test_index_accessor(self):
|
||||
gas = ct.Solution('h2o2.xml')
|
||||
|
||||
for k in range(gas.n_species):
|
||||
s = gas.species(k)
|
||||
self.assertEqual(s.name, gas.species_name(k))
|
||||
for k in range(self.gas.n_species):
|
||||
s = self.gas.species(k)
|
||||
self.assertEqual(s.name, self.gas.species_name(k))
|
||||
|
||||
for m,n in s.composition.items():
|
||||
self.assertEqual(n, gas.n_atoms(k,m))
|
||||
self.assertEqual(n, self.gas.n_atoms(k,m))
|
||||
|
||||
def test_name_accessor(self):
|
||||
gas = ct.Solution('h2o2.xml')
|
||||
|
||||
for name in gas.species_names:
|
||||
s = gas.species(name)
|
||||
for name in self.gas.species_names:
|
||||
s = self.gas.species(name)
|
||||
self.assertEqual(s.name, name)
|
||||
|
||||
def test_fromCti(self):
|
||||
h2_cti = """
|
||||
species(
|
||||
name="H2",
|
||||
atoms="H:2",
|
||||
thermo=(
|
||||
NASA([200.00, 1000.00],
|
||||
[2.344331120E+00, 7.980520750E-03, -1.947815100E-05,
|
||||
2.015720940E-08, -7.376117610E-12, -9.179351730E+02,
|
||||
6.830102380E-01]),
|
||||
NASA([1000.00, 3500.00],
|
||||
[3.337279200E+00, -4.940247310E-05, 4.994567780E-07,
|
||||
-1.795663940E-10, 2.002553760E-14, -9.501589220E+02,
|
||||
-3.205023310E+00])
|
||||
),
|
||||
transport=gas_transport(geom="linear",
|
||||
diam=2.92,
|
||||
well_depth=38.00,
|
||||
polar=0.79,
|
||||
rot_relax=280.00),
|
||||
note = "TPIS78"
|
||||
)"""
|
||||
s1 = self.gas.species('H2')
|
||||
s2 = ct.Species.fromCti(h2_cti)
|
||||
self.assertEqual(s2.name, 'H2')
|
||||
self.assertEqual(s1.composition, s2.composition)
|
||||
self.assertEqual(s1.thermo.cp(350), s2.thermo.cp(350))
|
||||
|
||||
def test_fromXml(self):
|
||||
import xml.etree.ElementTree as ET
|
||||
root = ET.parse('../../build/data/h2o2.xml').getroot()
|
||||
h2_node = root.find('.//species[@name="H2"]')
|
||||
h2_string = ET.tostring(h2_node)
|
||||
|
||||
s1 = self.gas.species('H2')
|
||||
s2 = ct.Species.fromXml(h2_string)
|
||||
|
||||
self.assertEqual(s2.name, 'H2')
|
||||
self.assertEqual(s1.composition, s2.composition)
|
||||
self.assertEqual(s1.thermo.cp(350), s2.thermo.cp(350))
|
||||
|
||||
def test_listFromFile_cti(self):
|
||||
S = ct.Species.listFromFile('h2o2.cti')
|
||||
self.assertEqual({sp.name for sp in S},
|
||||
set(self.gas.species_names))
|
||||
|
||||
def test_listFromFile_xml(self):
|
||||
S = ct.Species.listFromFile('h2o2.xml')
|
||||
self.assertEqual({sp.name for sp in S},
|
||||
set(self.gas.species_names))
|
||||
|
||||
def test_listFromCti(self):
|
||||
S = ct.Species.listFromCti(open('../../build/data/h2o2.cti').read())
|
||||
|
||||
self.assertEqual({sp.name for sp in S},
|
||||
set(self.gas.species_names))
|
||||
|
||||
def test_listFromXml(self):
|
||||
S = ct.Species.listFromXml(open('../../build/data/h2o2.xml').read())
|
||||
|
||||
self.assertEqual({sp.name for sp in S},
|
||||
set(self.gas.species_names))
|
||||
|
||||
|
||||
|
||||
class TestSpeciesThermo(utilities.CanteraTest):
|
||||
def setUp(self):
|
||||
|
|
|
|||
|
|
@ -36,6 +36,80 @@ cdef class Species:
|
|||
self._species = other
|
||||
self.species = self._species.get()
|
||||
|
||||
@staticmethod
|
||||
def fromCti(text):
|
||||
"""
|
||||
Create a Species object from its CTI string representation.
|
||||
"""
|
||||
cxx_species = CxxGetSpecies(deref(CxxGetXmlFromString(stringify(text))))
|
||||
assert cxx_species.size() == 1, cxx_species.size()
|
||||
species = Species(init=False)
|
||||
species._assign(cxx_species[0])
|
||||
return species
|
||||
|
||||
@staticmethod
|
||||
def fromXml(text):
|
||||
"""
|
||||
Create a Species object from its XML string representation.
|
||||
"""
|
||||
cxx_species = CxxNewSpecies(deref(CxxGetXmlFromString(stringify(text))))
|
||||
species = Species(init=False)
|
||||
species._assign(cxx_species)
|
||||
return species
|
||||
|
||||
@staticmethod
|
||||
def listFromFile(filename):
|
||||
"""
|
||||
Create a list of Species objects from all of the species defined in a
|
||||
CTI or XML file.
|
||||
|
||||
Directories on Cantera's input file path will be searched for the
|
||||
specified file.
|
||||
|
||||
In the case of an XML file, the <species> nodes are assumed to be
|
||||
children of the <speciesData> node in a document with a <ctml> root
|
||||
node, as in the XML files produced by conversion from CTI files.
|
||||
"""
|
||||
cxx_species = CxxGetSpecies(deref(CxxGetXmlFile(stringify(filename))))
|
||||
species = []
|
||||
for a in cxx_species:
|
||||
b = Species(init=False)
|
||||
b._assign(a)
|
||||
species.append(b)
|
||||
return species
|
||||
|
||||
@staticmethod
|
||||
def listFromXml(text):
|
||||
"""
|
||||
Create a list of Species objects from all the species defined in an
|
||||
XML string. The <species> nodes are assumed to be children of the
|
||||
<speciesData> node in a document with a <ctml> root node, as in the XML
|
||||
files produced by conversion from CTI files.
|
||||
"""
|
||||
cxx_species = CxxGetSpecies(deref(CxxGetXmlFromString(stringify(text))))
|
||||
species = []
|
||||
for a in cxx_species:
|
||||
b = Species(init=False)
|
||||
b._assign(a)
|
||||
species.append(b)
|
||||
return species
|
||||
|
||||
@staticmethod
|
||||
def listFromCti(text):
|
||||
"""
|
||||
Create a list of Species objects from all the species defined in a CTI
|
||||
string.
|
||||
"""
|
||||
# Currently identical to listFromXml since get_XML_from_string is able
|
||||
# to distinguish between CTI and XML.
|
||||
cxx_species = CxxGetSpecies(deref(CxxGetXmlFromString(stringify(text))))
|
||||
species = []
|
||||
for a in cxx_species:
|
||||
b = Species(init=False)
|
||||
b._assign(a)
|
||||
species.append(b)
|
||||
return species
|
||||
|
||||
property name:
|
||||
def __get__(self):
|
||||
return pystr(self.species.name)
|
||||
|
|
|
|||
|
|
@ -82,4 +82,19 @@ shared_ptr<Species> newSpecies(const XML_Node& species_node)
|
|||
return s;
|
||||
}
|
||||
|
||||
std::vector<shared_ptr<Species> > getSpecies(const XML_Node& node)
|
||||
{
|
||||
std::vector<shared_ptr<Species> > all_species;
|
||||
std::vector<XML_Node*> species_nodes =
|
||||
node.child("speciesData").getChildren("species");
|
||||
|
||||
for (std::vector<XML_Node*>::iterator iter = species_nodes.begin();
|
||||
iter != species_nodes.end();
|
||||
++iter)
|
||||
{
|
||||
all_species.push_back(newSpecies(**iter));
|
||||
}
|
||||
return all_species;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue