From d8e09a9550e64203d9fd8e6e662095bd86d6a817 Mon Sep 17 00:00:00 2001 From: Ingmar Schoegl Date: Sat, 17 Aug 2019 11:54:57 -0500 Subject: [PATCH] [Base] clarify keyword arguments of _SolutionBase initializers * Replace `phaseid` by `phase` * Replace `phases` by `adjacent` * Add deprecation warnings and update unit tests --- interfaces/cython/cantera/base.pyx | 59 +++++++++++++------ .../cython/cantera/test/test_convert.py | 36 +++++------ .../cython/cantera/test/test_kinetics.py | 4 +- interfaces/cython/cantera/test/test_thermo.py | 7 +++ 4 files changed, 67 insertions(+), 39 deletions(-) diff --git a/interfaces/cython/cantera/base.pyx b/interfaces/cython/cantera/base.pyx index a5be061bf..fd08b7d7d 100644 --- a/interfaces/cython/cantera/base.pyx +++ b/interfaces/cython/cantera/base.pyx @@ -6,9 +6,29 @@ from collections import defaultdict as _defaultdict _phase_counts = _defaultdict(int) cdef class _SolutionBase: - def __cinit__(self, infile='', phaseid='', phases=(), origin=None, + def __cinit__(self, infile='', phase='', adjacent=(), origin=None, source=None, yaml=None, thermo=None, species=(), kinetics=None, reactions=(), **kwargs): + + if 'phaseid' in kwargs: + if phase is not '': + raise AttributeError('duplicate specification of phase name') + + warnings.warn("To be removed after Cantera 2.5. " + "Keyword `phaseid` is replaced by `phase`", + DeprecationWarning) + phase = kwargs['phaseid'] + + if 'phases' in kwargs: + if len(adjacent)>0: + raise AttributeError( + 'duplicate specification of adjacent phases') + + warnings.warn("To be removed after Cantera 2.5. " + "Keyword `phases` is replaced by `adjacent`", + DeprecationWarning) + adjacent = kwargs['phases'] + # Shallow copy of an existing Solution (for slicing support) cdef _SolutionBase other if origin is not None: @@ -36,11 +56,11 @@ cdef class _SolutionBase: # Parse inputs if infile.endswith('.yml') or infile.endswith('.yaml') or yaml: - self._init_yaml(infile, phaseid, phases, yaml) + self._init_yaml(infile, phase, adjacent, yaml) elif infile or source: - self._init_cti_xml(infile, phaseid, phases, source) + self._init_cti_xml(infile, phase, adjacent, source) elif thermo and species: - self._init_parts(thermo, species, kinetics, phases, reactions) + self._init_parts(thermo, species, kinetics, adjacent, reactions) else: raise ValueError("Arguments are insufficient to define a phase") @@ -137,7 +157,7 @@ cdef class _SolutionBase: return thermo, kinetics, transport - def _init_yaml(self, infile, phaseid, phases, source): + def _init_yaml(self, infile, phase, adjacent, source): """ Instantiate a set of new Cantera C++ objects from a YAML phase definition @@ -149,7 +169,7 @@ cdef class _SolutionBase: root = AnyMapFromYamlString(stringify(source)) phaseNode = root[stringify("phases")].getMapWhere(stringify("name"), - stringify(phaseid)) + stringify(phase)) # Thermo if isinstance(self, ThermoPhase): @@ -160,19 +180,19 @@ cdef class _SolutionBase: # Kinetics cdef vector[CxxThermoPhase*] v - cdef _SolutionBase phase + cdef _SolutionBase adj if isinstance(self, Kinetics): v.push_back(self.thermo) - for phase in phases: + for adj in adjacent: # adjacent bulk phases for a surface phase - v.push_back(phase.thermo) + v.push_back(adj.thermo) self._kinetics = newKinetics(v, phaseNode, root) self.kinetics = self._kinetics.get() else: self.kinetics = NULL - def _init_cti_xml(self, infile, phaseid, phases, source): + def _init_cti_xml(self, infile, phase, adjacent, source): """ Instantiate a set of new Cantera C++ objects from a CTI or XML phase definition @@ -184,8 +204,8 @@ cdef class _SolutionBase: # Get XML data cdef XML_Node* phaseNode - if phaseid: - phaseNode = rootNode.findID(stringify(phaseid)) + if phase: + phaseNode = rootNode.findID(stringify(phase)) else: phaseNode = rootNode.findByName(stringify('phase')) if phaseNode is NULL: @@ -200,19 +220,19 @@ cdef class _SolutionBase: # Kinetics cdef vector[CxxThermoPhase*] v - cdef _SolutionBase phase + cdef _SolutionBase adj if isinstance(self, Kinetics): v.push_back(self.thermo) - for phase in phases: + for adj in adjacent: # adjacent bulk phases for a surface phase - v.push_back(phase.thermo) + v.push_back(adj.thermo) self.kinetics = newKineticsMgr(deref(phaseNode), v) self._kinetics.reset(self.kinetics) else: self.kinetics = NULL - def _init_parts(self, thermo, species, kinetics, phases, reactions): + def _init_parts(self, thermo, species, kinetics, adjacent, reactions): """ Instantiate a set of new Cantera C++ objects based on a string defining the model type and a list of Species objects. @@ -228,14 +248,15 @@ cdef class _SolutionBase: if not kinetics: kinetics = "none" - cdef ThermoPhase phase + cdef ThermoPhase adj cdef Reaction reaction if isinstance(self, Kinetics): self.kinetics = CxxNewKinetics(stringify(kinetics)) self._kinetics.reset(self.kinetics) self.kinetics.addPhase(deref(self.thermo)) - for phase in phases: - self.kinetics.addPhase(deref(phase.thermo)) + for adj in adjacent: + # adjacent bulk phases for a surface phase + self.kinetics.addPhase(deref(adj.thermo)) self.kinetics.init() self.kinetics.skipUndeclaredThirdBodies(True) for reaction in reactions: diff --git a/interfaces/cython/cantera/test/test_convert.py b/interfaces/cython/cantera/test/test_convert.py index 1d4640232..726f547c2 100644 --- a/interfaces/cython/cantera/test/test_convert.py +++ b/interfaces/cython/cantera/test/test_convert.py @@ -571,8 +571,8 @@ class cti2yamlTest(utilities.CanteraTest): def checkConversion(self, basename, cls=ct.Solution, ctiphases=(), yamlphases=(), **kwargs): - ctiPhase = cls(basename + '.cti', phases=ctiphases, **kwargs) - yamlPhase = cls(basename + '.yaml', phases=yamlphases, **kwargs) + ctiPhase = cls(basename + '.cti', adjacent=ctiphases, **kwargs) + yamlPhase = cls(basename + '.yaml', adjacent=yamlphases, **kwargs) self.assertEqual(ctiPhase.element_names, yamlPhase.element_names) self.assertEqual(ctiPhase.species_names, yamlPhase.species_names) @@ -660,7 +660,7 @@ class cti2yamlTest(utilities.CanteraTest): Path(self.test_work_dir).joinpath('ptcombust.yaml')) ctiGas, yamlGas = self.checkConversion('ptcombust') ctiSurf, yamlSurf = self.checkConversion('ptcombust', ct.Interface, - phaseid='Pt_surf', ctiphases=[ctiGas], yamlphases=[yamlGas]) + phase='Pt_surf', ctiphases=[ctiGas], yamlphases=[yamlGas]) self.checkKinetics(ctiGas, yamlGas, [500, 1200], [1e4, 3e5]) self.checkThermo(ctiSurf, yamlSurf, [400, 800, 1600]) @@ -670,16 +670,16 @@ class cti2yamlTest(utilities.CanteraTest): cti2yaml.convert(Path(self.cantera_data).joinpath('sofc.cti'), Path(self.test_work_dir).joinpath('sofc.yaml')) ctiGas, yamlGas = self.checkConversion('sofc') - ctiMetal, yamlMetal = self.checkConversion('sofc', phaseid='metal') - ctiOxide, yamlOxide = self.checkConversion('sofc', phaseid='oxide_bulk') + ctiMetal, yamlMetal = self.checkConversion('sofc', phase='metal') + ctiOxide, yamlOxide = self.checkConversion('sofc', phase='oxide_bulk') ctiMSurf, yamlMSurf = self.checkConversion('sofc', ct.Interface, - phaseid='metal_surface', ctiphases=[ctiGas, ctiMetal], + phase='metal_surface', ctiphases=[ctiGas, ctiMetal], yamlphases=[yamlGas, yamlMetal]) ctiOSurf, yamlOSurf = self.checkConversion('sofc', ct.Interface, - phaseid='oxide_surface', ctiphases=[ctiGas, ctiOxide], + phase='oxide_surface', ctiphases=[ctiGas, ctiOxide], yamlphases=[yamlGas, yamlOxide]) cti_tpb, yaml_tpb = self.checkConversion('sofc', ct.Interface, - phaseid='tpb', ctiphases=[ctiMetal, ctiMSurf, ctiOSurf], + phase='tpb', ctiphases=[ctiMetal, ctiMSurf, ctiOSurf], yamlphases=[yamlMetal, yamlMSurf, yamlOSurf]) self.checkThermo(ctiMSurf, yamlMSurf, [900, 1000, 1100]) @@ -694,7 +694,7 @@ class cti2yamlTest(utilities.CanteraTest): Path(self.test_work_dir).joinpath('liquidvapor.yaml')) for name in ['water', 'nitrogen', 'methane', 'hydrogen', 'oxygen', 'hfc134a', 'carbondioxide', 'heptane']: - ctiPhase, yamlPhase = self.checkConversion('liquidvapor', phaseid=name) + ctiPhase, yamlPhase = self.checkConversion('liquidvapor', phase=name) self.checkThermo(ctiPhase, yamlPhase, [1.3 * ctiPhase.min_temp, 0.7 * ctiPhase.max_temp]) @@ -717,10 +717,10 @@ class cti2yamlTest(utilities.CanteraTest): def test_diamond(self): cti2yaml.convert(Path(self.cantera_data).joinpath('diamond.cti'), Path(self.test_work_dir).joinpath('diamond.yaml')) - ctiGas, yamlGas = self.checkConversion('diamond', phaseid='gas') - ctiSolid, yamlSolid = self.checkConversion('diamond', phaseid='diamond') + ctiGas, yamlGas = self.checkConversion('diamond', phase='gas') + ctiSolid, yamlSolid = self.checkConversion('diamond', phase='diamond') ctiSurf, yamlSurf = self.checkConversion('diamond', - ct.Interface, phaseid='diamond_100', ctiphases=[ctiGas, ctiSolid], + ct.Interface, phase='diamond_100', ctiphases=[ctiGas, ctiSolid], yamlphases=[yamlGas, yamlSolid]) self.checkThermo(ctiSolid, yamlSolid, [300, 500]) self.checkThermo(ctiSurf, yamlSurf, [330, 490]) @@ -730,16 +730,16 @@ class cti2yamlTest(utilities.CanteraTest): cti2yaml.convert(Path(self.cantera_data).joinpath('lithium_ion_battery.cti'), Path(self.test_work_dir).joinpath('lithium_ion_battery.yaml')) name = 'lithium_ion_battery' - ctiAnode, yamlAnode = self.checkConversion(name, phaseid='anode') - ctiCathode, yamlCathode = self.checkConversion(name, phaseid='cathode') - ctiMetal, yamlMetal = self.checkConversion(name, phaseid='electron') - ctiElyt, yamlElyt = self.checkConversion(name, phaseid='electrolyte') + ctiAnode, yamlAnode = self.checkConversion(name, phase='anode') + ctiCathode, yamlCathode = self.checkConversion(name, phase='cathode') + ctiMetal, yamlMetal = self.checkConversion(name, phase='electron') + ctiElyt, yamlElyt = self.checkConversion(name, phase='electrolyte') ctiAnodeInt, yamlAnodeInt = self.checkConversion(name, - phaseid='edge_anode_electrolyte', + phase='edge_anode_electrolyte', ctiphases=[ctiAnode, ctiMetal, ctiElyt], yamlphases=[yamlAnode, yamlMetal, yamlElyt]) ctiCathodeInt, yamlCathodeInt = self.checkConversion(name, - phaseid='edge_cathode_electrolyte', + phase='edge_cathode_electrolyte', ctiphases=[ctiCathode, ctiMetal, ctiElyt], yamlphases=[yamlCathode, yamlMetal, yamlElyt]) diff --git a/interfaces/cython/cantera/test/test_kinetics.py b/interfaces/cython/cantera/test/test_kinetics.py index 463856645..58d0637ed 100644 --- a/interfaces/cython/cantera/test/test_kinetics.py +++ b/interfaces/cython/cantera/test/test_kinetics.py @@ -185,7 +185,7 @@ class KineticsFromReactions(utilities.CanteraTest): surf2 = ct.Interface(thermo='Surface', kinetics='interface', species=surf_species, reactions=reactions, - phases=[gas]) + adjacent=[gas]) surf1.site_density = surf2.site_density = 5e-9 gas.TP = surf2.TP = surf1.TP = 900, 2*ct.one_atm surf2.concentrations = surf1.concentrations @@ -1032,7 +1032,7 @@ class TestReaction(utilities.CanteraTest): self.assertNear(r1.coverage_deps['H(S)'][2], -6e6) surf2 = ct.Interface(thermo='Surface', species=surf_species, - kinetics='interface', reactions=[r1], phases=[gas]) + kinetics='interface', reactions=[r1], adjacent=[gas]) surf2.site_density = surf1.site_density surf1.coverages = surf2.coverages = 'PT(S):0.7, H(S):0.3' diff --git a/interfaces/cython/cantera/test/test_thermo.py b/interfaces/cython/cantera/test/test_thermo.py index 9f70649be..0c468feaf 100644 --- a/interfaces/cython/cantera/test/test_thermo.py +++ b/interfaces/cython/cantera/test/test_thermo.py @@ -343,6 +343,13 @@ class TestThermoPhase(utilities.CanteraTest): self.assertTrue("To be removed after Cantera 2.5. " in str(w[-1].message)) + with warnings.catch_warnings(record=True) as w: + gas = ct.Solution('h2o2.cti', phaseid='ohmech') + self.assertTrue(len(w) == 1) + self.assertTrue(issubclass(w[-1].category, DeprecationWarning)) + self.assertTrue("To be removed after Cantera 2.5. " + in str(w[-1].message)) + def test_badLength(self): X = np.zeros(5) with self.assertRaisesRegex(ValueError, 'incorrect length'):