Skip to content

Commit

Permalink
[Python] Enable modification of user input data fields
Browse files Browse the repository at this point in the history
Data specified this way is stored when writing to YAML files.
  • Loading branch information
speth committed Jun 6, 2021
1 parent 01bf417 commit 941b5dc
Show file tree
Hide file tree
Showing 7 changed files with 123 additions and 1 deletion.
7 changes: 7 additions & 0 deletions interfaces/cython/cantera/_cantera.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ cdef extern from "cantera/base/AnyMap.h" namespace "Cantera":
CxxAnyValue& operator[](string) except +translate_exception
cbool empty()
cbool hasKey(string)
void clear()
void update(CxxAnyMap& other, cbool)
string keys_str()
void applyUnits()

Expand Down Expand Up @@ -135,6 +137,7 @@ cdef extern from "cantera/thermo/SpeciesThermoInterpType.h":
void reportParameters(size_t&, int&, double&, double&, double&, double* const) except +translate_exception
int nCoeffs() except +translate_exception
CxxAnyMap parameters(cbool) except +translate_exception
CxxAnyMap& input()

cdef extern from "cantera/thermo/SpeciesThermoFactory.h":
cdef CxxSpeciesThermo* CxxNewSpeciesThermo "Cantera::newSpeciesThermoInterpType"\
Expand All @@ -154,6 +157,7 @@ cdef extern from "cantera/thermo/Species.h" namespace "Cantera":
double charge
double size
CxxAnyMap parameters(CxxThermoPhase*) except +translate_exception
CxxAnyMap input

cdef shared_ptr[CxxSpecies] CxxNewSpecies "newSpecies" (XML_Node&)
cdef vector[shared_ptr[CxxSpecies]] CxxGetSpecies "getSpecies" (XML_Node&)
Expand Down Expand Up @@ -187,6 +191,7 @@ cdef extern from "cantera/thermo/ThermoPhase.h" namespace "Cantera":
string type()
string phaseOfMatter() except +translate_exception
void getSpeciesParameters(string, CxxAnyMap&) except +translate_exception
CxxAnyMap& input()
string report(cbool, double) except +translate_exception
cbool hasPhaseTransition()
cbool isPure()
Expand Down Expand Up @@ -376,6 +381,7 @@ cdef extern from "cantera/kinetics/Reaction.h" namespace "Cantera":
string type()
void validate() except +translate_exception
CxxAnyMap parameters(cbool) except +translate_exception
CxxAnyMap input
int reaction_type
Composition reactants
Composition products
Expand Down Expand Up @@ -563,6 +569,7 @@ cdef extern from "cantera/transport/TransportData.h" namespace "Cantera":
cdef cppclass CxxTransportData "Cantera::TransportData":
CxxTransportData()
CxxAnyMap parameters(cbool) except +translate_exception
CxxAnyMap input

cdef cppclass CxxGasTransportData "Cantera::GasTransportData" (CxxTransportData):
CxxGasTransportData()
Expand Down
19 changes: 18 additions & 1 deletion interfaces/cython/cantera/base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,22 @@ cdef class _SolutionBase:
def __get__(self):
return anymap_to_dict(self.base.parameters(True))

def update_user_data(self, data):
"""
Add the contents of the provided `dict` as additional fields when generating
YAML phase definition files with `write_yaml` or in the data returned by
`input_data`. Existing keys with matching names are overwritten.
"""
self.thermo.input().update(dict_to_anymap(data), False)

def clear_user_data(self):
"""
Clear all saved input data, so that the data given by `input_data` or
`write_yaml` will only include values generated by Cantera based on the
current object state.
"""
self.thermo.input().clear()

def write_yaml(self, filename, phases=None, units=None, precision=None,
skip_user_defined=None):
"""
Expand All @@ -251,7 +267,8 @@ cdef class _SolutionBase:
the right of the decimal point. The default is 15 digits.
:param skip_user_defined:
If `True`, user-defined fields which are not used by Cantera will
be stripped from the output.
be stripped from the output. These additional contents can also be
controlled using the `update_user_data` and `clear_user_data` functions.
"""
Y = YamlWriter()
Y.add_solution(self)
Expand Down
16 changes: 16 additions & 0 deletions interfaces/cython/cantera/reaction.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,22 @@ cdef class Reaction:
def __get__(self):
return anymap_to_dict(self.reaction.parameters(True))

def update_user_data(self, data):
"""
Add the contents of the provided `dict` as additional fields when generating
YAML phase definition files with `Solution.write_yaml` or in the data returned
by `input_data`. Existing keys with matching names are overwritten.
"""
self.reaction.input.update(dict_to_anymap(data), False)

def clear_user_data(self):
"""
Clear all saved input data, so that the data given by `input_data` or
`Solution.write_yaml` will only include values generated by Cantera based on
the current object state.
"""
self.reaction.input.clear()

def __repr__(self):
return '<{}: {}>'.format(self.__class__.__name__, self.equation)

Expand Down
16 changes: 16 additions & 0 deletions interfaces/cython/cantera/speciesthermo.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,22 @@ cdef class SpeciesThermo:
def __get__(self):
return anymap_to_dict(self.spthermo.parameters(True))

def update_user_data(self, data):
"""
Add the contents of the provided `dict` as additional fields when generating
YAML phase definition files with `Solution.write_yaml` or in the data returned
by `input_data`. Existing keys with matching names are overwritten.
"""
self.spthermo.input().update(dict_to_anymap(data), False)

def clear_user_data(self):
"""
Clear all saved input data, so that the data given by `input_data` or
`Solution.write_yaml` will only include values generated by Cantera based on
the current object state.
"""
self.spthermo.input().clear()

def cp(self, T):
"""
Molar heat capacity at constant pressure [J/kmol/K] at temperature *T*.
Expand Down
34 changes: 34 additions & 0 deletions interfaces/cython/cantera/test/test_composite.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,19 @@ def test_input_data_simple(self):
self.assertEqual(data['kinetics'], 'gas')
self.assertEqual(data['transport'], 'mixture-averaged')

def test_input_data_user_modifications(self):
gas = ct.Solution("h2o2.yaml")
data1 = gas.input_data
gas.update_user_data({"foo": True}) # should get overwritten
extra = {"foo": [1.2, 3.4], "bar": [[1, 2], [3, 4]]}
gas.update_user_data(extra)
data2 = gas.input_data
self.assertEqual(extra["foo"], data2["foo"])
self.assertEqual(extra["bar"], data2["bar"])
gas.clear_user_data()
data3 = gas.input_data
self.assertEqual(data1, data3)

def test_input_data_state(self):
gas = ct.Solution('h2o2.yaml', transport_model=None)
data = gas.input_data
Expand Down Expand Up @@ -569,6 +582,27 @@ def test_yaml_inconsistent_species(self):
with self.assertRaisesRegex(ct.CanteraError, "different definitions"):
gas.write_yaml('h2o2-error.yaml', phases=gas2)

def test_yaml_user_data(self):
gas = ct.Solution("h2o2.yaml")
extra = {"spam": {"A": 1, "B": 2}, "eggs": [1, 2.3, 4.5]}
gas.update_user_data(extra)
S = gas.species(2)
S.update_user_data({"foo": "bar"})
S.transport.update_user_data({"baz": 1234.5})
S.thermo.update_user_data({"something": (False, True)})
gas.reaction(5).update_user_data({"baked-beans": True})

gas.write_yaml("h2o2-generated-user-data.yaml")
gas2 = ct.Solution("h2o2-generated-user-data.yaml")
data2 = gas2.species(2).input_data

self.assertEqual(gas2.input_data["spam"], extra["spam"])
self.assertEqual(gas2.input_data["eggs"], extra["eggs"])
self.assertEqual(data2["foo"], "bar")
self.assertEqual(data2["transport"]["baz"], 1234.5)
self.assertEqual(data2["thermo"]["something"], [False, True])
self.assertTrue(gas2.reaction(5).input_data["baked-beans"])


class TestSpeciesSerialization(utilities.CanteraTest):
def test_species_simple(self):
Expand Down
16 changes: 16 additions & 0 deletions interfaces/cython/cantera/thermo.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,22 @@ cdef class Species:
cdef CxxThermoPhase* phase = self._phase.thermo if self._phase else NULL
return anymap_to_dict(self.species.parameters(phase))

def update_user_data(self, data):
"""
Add the contents of the provided `dict` as additional fields when generating
YAML phase definition files with `Solution.write_yaml` or in the data returned
by `input_data`. Existing keys with matching names are overwritten.
"""
self.species.input.update(dict_to_anymap(data), False)

def clear_user_data(self):
"""
Clear all saved input data, so that the data given by `input_data` or
`Solution.write_yaml` will only include values generated by Cantera based on
the current object state.
"""
self.species.input.clear()

def __repr__(self):
return '<Species {}>'.format(self.name)

Expand Down
16 changes: 16 additions & 0 deletions interfaces/cython/cantera/transport.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,22 @@ cdef class GasTransportData:
def __get__(self):
return anymap_to_dict(self.data.parameters(True))

def update_user_data(self, data):
"""
Add the contents of the provided `dict` as additional fields when generating
YAML phase definition files with `Solution.write_yaml` or in the data returned
by `input_data`. Existing keys with matching names are overwritten.
"""
self.data.input.update(dict_to_anymap(data), False)

def clear_user_data(self):
"""
Clear all saved input data, so that the data given by `input_data` or
`Solution.write_yaml` will only include values generated by Cantera based on
the current object state.
"""
self.data.input.clear()

property geometry:
"""
Get/Set the string specifying the molecular geometry. One of `atom`,
Expand Down

0 comments on commit 941b5dc

Please sign in to comment.