diff --git a/environment.yml b/environment.yml index a5e272232d..6dcd5db2a4 100644 --- a/environment.yml +++ b/environment.yml @@ -25,7 +25,6 @@ name: rmg_env channels: - conda-forge - - cantera - rmg dependencies: # System-level dependencies - we could install these at the OS level @@ -46,7 +45,7 @@ dependencies: # external software tools for chemistry - conda-forge::coolprop - - cantera::cantera =2.6 + - conda-forge::cantera >= 3 - conda-forge::mopac # see https://github.com/ReactionMechanismGenerator/RMG-Py/pull/2639#issuecomment-2050292972 - conda-forge::cclib >=1.6.3,<1.9 @@ -59,7 +58,7 @@ dependencies: - conda-forge::cython >=0.25.2 - conda-forge::scikit-learn - conda-forge::scipy >=1.9 - - conda-forge::numpy >=1.10.0 + - conda-forge::numpy >=1.10.0,<2 - conda-forge::pydot - conda-forge::jinja2 - conda-forge::jupyter diff --git a/rmgpy/kinetics/falloff.pyx b/rmgpy/kinetics/falloff.pyx index 12290667be..192833090a 100644 --- a/rmgpy/kinetics/falloff.pyx +++ b/rmgpy/kinetics/falloff.pyx @@ -122,11 +122,11 @@ cdef class ThirdBody(PDepKineticsModel): def set_cantera_kinetics(self, ct_reaction, species_list): """ - Sets the kinetics and efficiencies for a cantera `ThreeBodyReaction` object + Sets the kinetics and efficiencies for a cantera Reaction representing a Three Body Rate """ import cantera as ct - assert isinstance(ct_reaction, ct.ThreeBodyReaction), "Must be a Cantera ThreeBodyReaction object" - ct_reaction.efficiencies = PDepKineticsModel.get_cantera_efficiencies(self, species_list) + # assert ct_reaction.third_body is not None, "Cantera Reaction must have third_body attribute" + ct_reaction.third_body.efficiencies = PDepKineticsModel.get_cantera_efficiencies(self, species_list) self.arrheniusLow.set_cantera_kinetics(ct_reaction, species_list) ################################################################################ @@ -398,7 +398,7 @@ cdef class Troe(PDepKineticsModel): """ import cantera as ct assert isinstance(ct_reaction.rate, ct.TroeRate), "Must have a Cantera TroeRate attribute" - ct_reaction.efficiencies = PDepKineticsModel.get_cantera_efficiencies(self, species_list) + ct_reaction.third_body.efficiencies = PDepKineticsModel.get_cantera_efficiencies(self, species_list) ct_reaction.rate = self.to_cantera_kinetics() def to_cantera_kinetics(self): diff --git a/rmgpy/reaction.py b/rmgpy/reaction.py index 1997824afc..ec742be959 100644 --- a/rmgpy/reaction.py +++ b/rmgpy/reaction.py @@ -347,21 +347,22 @@ def to_cantera(self, species_list=None, use_chemkin_identifier=False): ct_reaction = ct.Reaction(reactants=ct_reactants, products=ct_products, rate=ct.ChebyshevRate()) elif isinstance(self.kinetics, ThirdBody): + # Cantera 3 doesn't have a ThirdBody class, only third body attribute in the normal class if ct_collider is not None: - ct_reaction = ct.ThreeBodyReaction(reactants=ct_reactants, products=ct_products, third_body=ct_collider) - else: - ct_reaction = ct.ThreeBodyReaction(reactants=ct_reactants, products=ct_products) + ct_reaction = ct.Reaction(reactants=ct_reactants, products=ct_products, third_body=ct_collider, rate=ct.ArrheniusRate()) + else: # provide the default collider (if we don't have one) to establish this as a ThirdBody reaction + ct_reaction = ct.Reaction(reactants=ct_reactants, products=ct_products, third_body=ct.ThirdBody(), rate=ct.ArrheniusRate()) elif isinstance(self.kinetics, Troe): if ct_collider is not None: - ct_reaction = ct.FalloffReaction( + ct_reaction = ct.Reaction( reactants=ct_reactants, products=ct_products, - tbody=ct_collider, + third_body=ct_collider, rate=ct.TroeRate() ) else: - ct_reaction = ct.FalloffReaction( + ct_reaction = ct.Reaction( reactants=ct_reactants, products=ct_products, rate=ct.TroeRate() @@ -369,14 +370,14 @@ def to_cantera(self, species_list=None, use_chemkin_identifier=False): elif isinstance(self.kinetics, Lindemann): if ct_collider is not None: - ct_reaction = ct.FalloffReaction( + ct_reaction = ct.Reaction( reactants=ct_reactants, products=ct_products, - tbody=ct_collider, + third_body=ct_collider, rate=ct.LindemannRate() ) else: - ct_reaction = ct.FalloffReaction( + ct_reaction = ct.Reaction( reactants=ct_reactants, products=ct_products, rate=ct.LindemannRate() diff --git a/rmgpy/tools/canteramodel.py b/rmgpy/tools/canteramodel.py index 15d26c2947..28cca1253d 100644 --- a/rmgpy/tools/canteramodel.py +++ b/rmgpy/tools/canteramodel.py @@ -840,20 +840,15 @@ def check_equivalent_falloff(fall1, fall2): for j in range(ct_rxn1.rate.data.shape[1]): assert check_nearly_equal(ct_rxn1.rate.data[i, j], ct_rxn2.rate.data[i, j], dE), \ "Similar Chebyshev coefficients" - - elif isinstance(ct_rxn1, ct.ThreeBodyReaction): - assert ct_rxn1.default_efficiency == ct_rxn2.default_efficiency, "Same default efficiency" - assert ct_rxn1.efficiencies == ct_rxn2.efficiencies, "Same efficiencies" - - elif isinstance(ct_rxn1, ct.FalloffReaction): - assert ct_rxn1.default_efficiency == ct_rxn2.default_efficiency, "Same default efficiency" - assert ct_rxn1.efficiencies == ct_rxn2.efficiencies, "Same efficiencies" - if ct_rxn1.falloff or ct_rxn2.falloff: - check_equivalent_falloff(ct_rxn1.falloff, ct_rxn2.falloff) - if ct_rxn1.high_rate or ct_rxn2.high_rate: - check_equivalent_arrhenius(ct_rxn1.high_rate, ct_rxn2.high_rate) - if ct_rxn1.low_rate or ct_rxn2.low_rate: - check_equivalent_arrhenius(ct_rxn1.low_rate, ct_rxn2.low_rate) + else: + assert ct_rxn1.default_efficiency == ct_rxn2.default_efficiency, "Same default efficiency" + assert ct_rxn1.efficiencies == ct_rxn2.efficiencies, "Same efficiencies" + if ct_rxn1.falloff or ct_rxn2.falloff: + check_equivalent_falloff(ct_rxn1.falloff, ct_rxn2.falloff) + if ct_rxn1.high_rate or ct_rxn2.high_rate: + check_equivalent_arrhenius(ct_rxn1.high_rate, ct_rxn2.high_rate) + if ct_rxn1.low_rate or ct_rxn2.low_rate: + check_equivalent_arrhenius(ct_rxn1.low_rate, ct_rxn2.low_rate) except Exception as e: print("Cantera reaction {0} failed equivalency check on: {1}".format(ct_rxn1, e)) diff --git a/test/rmgpy/reactionTest.py b/test/rmgpy/reactionTest.py index 4e1cc0cc50..bf4653088b 100644 --- a/test/rmgpy/reactionTest.py +++ b/test/rmgpy/reactionTest.py @@ -2954,7 +2954,7 @@ def test_pdep_arrhenius(self): # Check that the reaction string is the same assert repr(converted_obj) == repr(ct_obj) # Check that the Arrhenius rates are identical - assert str(converted_obj.rates) == str(ct_obj.rates) + assert str(converted_obj.rate.rates) == str(ct_obj.rate.rates) def test_multi_pdep_arrhenius(self): """ @@ -2975,7 +2975,7 @@ def test_multi_pdep_arrhenius(self): # Check that the reaction string is the same assert repr(converted_rxn) == repr(ct_rxn) # Check that the Arrhenius rates are identical - assert str(converted_rxn.rates) == str(ct_rxn.rates) + assert str(converted_rxn.rate.rates) == str(ct_rxn.rate.rates) def test_chebyshev(self): """ @@ -2996,18 +2996,18 @@ def test_falloff(self): assert round(abs(ct_troe.rate.low_rate.pre_exponential_factor - self.ct_troe.rate.low_rate.pre_exponential_factor), 3) == 0 assert ct_troe.rate.low_rate.temperature_exponent == self.ct_troe.rate.low_rate.temperature_exponent assert ct_troe.rate.low_rate.activation_energy == self.ct_troe.rate.low_rate.activation_energy - assert ct_troe.efficiencies == self.ct_troe.efficiencies + assert ct_troe.third_body.efficiencies == self.ct_troe.third_body.efficiencies ct_third_body = self.thirdBody.to_cantera(self.species_list, use_chemkin_identifier=True) assert type(ct_third_body.rate) == type(self.ct_thirdBody.rate) assert round(abs(ct_third_body.rate.pre_exponential_factor - self.ct_thirdBody.rate.pre_exponential_factor), 3) == 0 assert ct_third_body.rate.temperature_exponent == self.ct_thirdBody.rate.temperature_exponent assert ct_third_body.rate.activation_energy == self.ct_thirdBody.rate.activation_energy - assert ct_third_body.efficiencies == self.ct_thirdBody.efficiencies + assert ct_third_body.third_body.efficiencies == self.ct_thirdBody.third_body.efficiencies ct_lindemann = self.lindemann.to_cantera(self.species_list, use_chemkin_identifier=True) assert type(ct_lindemann.rate) == type(self.ct_lindemann.rate) - assert ct_lindemann.efficiencies == self.ct_lindemann.efficiencies + assert ct_lindemann.third_body.efficiencies == self.ct_lindemann.third_body.efficiencies assert str(ct_lindemann.rate.low_rate) == str(self.ct_lindemann.rate.low_rate) assert str(ct_lindemann.rate.high_rate) == str(self.ct_lindemann.rate.high_rate) diff --git a/test/rmgpy/speciesTest.py b/test/rmgpy/speciesTest.py index 6c2f558b21..dcbdd43453 100644 --- a/test/rmgpy/speciesTest.py +++ b/test/rmgpy/speciesTest.py @@ -458,24 +458,24 @@ def test_cantera(self): rmg_ct_species = rmg_species.to_cantera(use_chemkin_identifier=True) - ct_species = ct.Species.fromCti( - """species(name=u'Ar', - atoms='Ar:1', - thermo=(NASA([200.00, 1000.00], - [ 2.50000000E+00, 0.00000000E+00, 0.00000000E+00, - 0.00000000E+00, 0.00000000E+00, -7.45375000E+02, - 4.37967000E+00]), - NASA([1000.00, 6000.00], - [ 2.50000000E+00, 0.00000000E+00, 0.00000000E+00, - 0.00000000E+00, 0.00000000E+00, -7.45375000E+02, - 4.37967000E+00])), - transport=gas_transport(geom='atom', - diam=3.33, - well_depth=136.501, - dipole=2.0, - polar=1.0, - rot_relax=15.0))""" - ) + ct_species = ct.Species.from_yaml(""" +name: Ar +composition: {Ar: 1} +thermo: + model: NASA7 + temperature-ranges: [200.0, 1000.0, 6000.0] + data: + - [2.5, 0.0, 0.0, 0.0, 0.0, -745.375, 4.37967] + - [2.5, 0.0, 0.0, 0.0, 0.0, -745.375, 4.37967] +transport: + model: gas + geometry: atom + diameter: 3.33 + well-depth: 136.501 + dipole: 2.0 + polarizability: 1.0 + rotational-relaxation: 15.0 +""") assert type(rmg_ct_species) == type(ct_species) assert rmg_ct_species.name == ct_species.name assert rmg_ct_species.composition == ct_species.composition diff --git a/test/rmgpy/transportDataTest.py b/test/rmgpy/transportDataTest.py index 59dee0a542..ab7f244430 100644 --- a/test/rmgpy/transportDataTest.py +++ b/test/rmgpy/transportDataTest.py @@ -161,16 +161,20 @@ def test_to_cantera(self): rmg_ct_transport = transport.to_cantera() import cantera as ct - ct_species = ct.Species.fromCti( - """species(name=u'Ar', - atoms='Ar:1', - transport=gas_transport(geom='atom', - diam=3.33, - well_depth=136.501, - dipole=2.0, - polar=1.0, - rot_relax=15.0))""" - ) + ct_species = ct.Species.from_yaml(""" +name: Ar +composition: {Ar: 1} +thermo: + model: constant-cp +transport: + model: gas + geometry: atom + diameter: 3.33 + well-depth: 136.501 + dipole: 2.0 + polarizability: 1.0 + rotational-relaxation: 15.0 +""") ct_transport = ct_species.transport