[Python] Implement Species constructors from YAML files/strings
This commit is contained in:
parent
040ffe4711
commit
8037497dd3
6 changed files with 78 additions and 12 deletions
|
|
@ -79,6 +79,9 @@ unique_ptr<Species> newSpecies(const AnyMap& node);
|
|||
//! respectively, where the string or file is formatted as either CTI or XML.
|
||||
std::vector<shared_ptr<Species> > getSpecies(const XML_Node& node);
|
||||
|
||||
//! Generate Species objects for each item (an AnyMap) in `items`.
|
||||
std::vector<shared_ptr<Species>> getSpecies(const AnyValue& items);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ cdef extern from "cantera/thermo/Species.h" namespace "Cantera":
|
|||
|
||||
cdef shared_ptr[CxxSpecies] CxxNewSpecies "newSpecies" (XML_Node&)
|
||||
cdef vector[shared_ptr[CxxSpecies]] CxxGetSpecies "getSpecies" (XML_Node&)
|
||||
cdef shared_ptr[CxxSpecies] CxxNewSpecies "newSpecies" (CxxAnyMap&) except +translate_exception
|
||||
cdef vector[shared_ptr[CxxSpecies]] CxxGetSpecies "getSpecies" (CxxAnyValue&) except +translate_exception
|
||||
|
||||
cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
|
||||
cdef cppclass CxxThermoPhase "Cantera::ThermoPhase":
|
||||
|
|
|
|||
|
|
@ -1022,6 +1022,10 @@ class TestSpecies(utilities.CanteraTest):
|
|||
self.assertEqual({sp.name for sp in S},
|
||||
set(self.gas.species_names))
|
||||
|
||||
def test_listfromFile_yaml(self):
|
||||
S = ct.Species.listFromFile('ideal-gas.yaml')
|
||||
self.assertEqual(S[0].name, 'O2')
|
||||
|
||||
def test_listFromCti(self):
|
||||
p = os.path.dirname(__file__)
|
||||
with open(pjoin(p, '..', 'data', 'h2o2.cti')) as f:
|
||||
|
|
@ -1030,6 +1034,20 @@ class TestSpecies(utilities.CanteraTest):
|
|||
self.assertEqual({sp.name for sp in S},
|
||||
set(self.gas.species_names))
|
||||
|
||||
def test_listFomYaml(self):
|
||||
yaml = '''
|
||||
- name: H2O
|
||||
composition: {H: 2, O: 1}
|
||||
thermo: {model: constant-cp, h0: 100}
|
||||
- name: HO2
|
||||
composition: {H: 1, O: 2}
|
||||
thermo: {model: constant-cp, h0: 200}
|
||||
'''
|
||||
species = ct.Species.listFromYaml(yaml)
|
||||
self.assertEqual(species[0].name, 'H2O')
|
||||
self.assertEqual(species[1].composition, {'H': 1, 'O': 2})
|
||||
self.assertNear(species[0].thermo.h(300), 100)
|
||||
|
||||
def test_listFromXml(self):
|
||||
p = os.path.dirname(__file__)
|
||||
with open(pjoin(p, '..', 'data', 'h2o2.xml')) as f:
|
||||
|
|
|
|||
|
|
@ -37,15 +37,14 @@ cdef class Species:
|
|||
ch4.transport = tran
|
||||
gas = ct.Solution(thermo='IdealGas', species=[ch4])
|
||||
|
||||
The static methods `fromCti`, `fromXml`, `listFromFile`, `listFromCti`, and
|
||||
`listFromXml` can be used to create `Species` objects from existing
|
||||
definitions in the CTI or XML formats. All of the following will produce a
|
||||
list of 53 `Species` objects containing the species defined in the GRI 3.0
|
||||
mechanism::
|
||||
The static methods `fromYaml`, `fromCti`, `fromXml`, `listFromFile`,
|
||||
`listFromYaml`, `listFromCti`, and `listFromXml` can be used to create
|
||||
`Species` objects from existing definitions in the CTI or XML formats.
|
||||
Either of the following will produce a list of 53 `Species` objects
|
||||
containing the species defined in the GRI 3.0 mechanism::
|
||||
|
||||
S = ct.Species.listFromFile('gri30.cti')
|
||||
S = ct.Species.listFromCti(open('path/to/gri30.cti').read())
|
||||
S = ct.Species.listFromXml(open('path/to/gri30.xml').read())
|
||||
S = ct.Species.listFromFile('gri30.yaml')
|
||||
S = ct.Species.listFromYaml(open('path/to/gri30.yaml').read())
|
||||
|
||||
"""
|
||||
def __cinit__(self, *args, init=True, **kwargs):
|
||||
|
|
@ -96,10 +95,21 @@ cdef class Species:
|
|||
return species
|
||||
|
||||
@staticmethod
|
||||
def listFromFile(filename):
|
||||
def fromYaml(text):
|
||||
"""
|
||||
Create a Species object from its YAML string representation.
|
||||
"""
|
||||
cxx_species = CxxNewSpecies(AnyMapFromYamlString(stringify(text)))
|
||||
species = Species(init=False)
|
||||
species._assign(cxx_species)
|
||||
return species
|
||||
|
||||
@staticmethod
|
||||
def listFromFile(filename, section='species'):
|
||||
"""
|
||||
Create a list of Species objects from all of the species defined in a
|
||||
CTI or XML file.
|
||||
YAML, CTI or XML file. For YAML files, return species from the section
|
||||
*section*.
|
||||
|
||||
Directories on Cantera's input file path will be searched for the
|
||||
specified file.
|
||||
|
|
@ -108,7 +118,12 @@ cdef class Species:
|
|||
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))))
|
||||
if filename.lower().split('.')[-1] in ('yml', 'yaml'):
|
||||
root = AnyMapFromYamlFile(stringify(filename))
|
||||
cxx_species = CxxGetSpecies(root[stringify(section)])
|
||||
else:
|
||||
cxx_species = CxxGetSpecies(deref(CxxGetXmlFile(stringify(filename))))
|
||||
|
||||
species = []
|
||||
for a in cxx_species:
|
||||
b = Species(init=False)
|
||||
|
|
@ -148,6 +163,21 @@ cdef class Species:
|
|||
species.append(b)
|
||||
return species
|
||||
|
||||
@staticmethod
|
||||
def listFromYaml(text):
|
||||
"""
|
||||
Create a list of Species objects from all the species defined in a YAML
|
||||
string.
|
||||
"""
|
||||
root = AnyMapFromYamlString(stringify(text))
|
||||
cxx_species = CxxGetSpecies(root[stringify("items")])
|
||||
species = []
|
||||
for a in cxx_species:
|
||||
b = Species(init=False)
|
||||
b._assign(a)
|
||||
species.append(b)
|
||||
return species
|
||||
|
||||
property name:
|
||||
""" The name of the species. """
|
||||
def __get__(self):
|
||||
|
|
|
|||
|
|
@ -149,7 +149,11 @@ struct convert<Cantera::AnyMap> {
|
|||
}
|
||||
static bool decode(const Node& node, Cantera::AnyMap& target) {
|
||||
target.setLoc(node.Mark().line, node.Mark().column);
|
||||
if (!node.IsMap()) {
|
||||
if (node.IsSequence()) {
|
||||
// Convert a top-level list to a map with the key "items"
|
||||
target["items"] = node.as<AnyValue>();
|
||||
return true;
|
||||
} else if (!node.IsMap()) {
|
||||
std::string text = YAML::Dump(node);
|
||||
if (text.size() > 300) {
|
||||
text.resize(300);
|
||||
|
|
|
|||
|
|
@ -127,4 +127,13 @@ std::vector<shared_ptr<Species> > getSpecies(const XML_Node& node)
|
|||
return all_species;
|
||||
}
|
||||
|
||||
std::vector<shared_ptr<Species>> getSpecies(const AnyValue& items)
|
||||
{
|
||||
std::vector<shared_ptr<Species> > all_species;
|
||||
for (const auto& node : items.asVector<AnyMap>()) {
|
||||
all_species.emplace_back(newSpecies(node));
|
||||
}
|
||||
return all_species;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue