From e875da735e060d51adb6c7e627db785e3f008c9e Mon Sep 17 00:00:00 2001 From: Sevy Harris Date: Wed, 8 Nov 2023 13:14:50 -0500 Subject: [PATCH] added to_cantera_kinetics for SurfaceArrhenius and StickingCoefficient --- rmgpy/kinetics/surface.pyx | 78 ++++++++++++++++++++++++++++++++++++++ rmgpy/reaction.py | 8 +++- 2 files changed, 85 insertions(+), 1 deletion(-) diff --git a/rmgpy/kinetics/surface.pyx b/rmgpy/kinetics/surface.pyx index 120cfc006d..17913a799e 100644 --- a/rmgpy/kinetics/surface.pyx +++ b/rmgpy/kinetics/surface.pyx @@ -285,6 +285,36 @@ cdef class StickingCoefficient(KineticsModel): return string + def to_cantera_kinetics(self): + """ + Converts the RMG StickingCoefficient object to a cantera StickingArrheniusRate + + Inputs for both are (A,b,E) where A is dimensionless, b is dimensionless, and E is in J/kmol + + """ + + import cantera as ct + import rmgpy.quantity + + assert type(self._A) == rmgpy.quantity.ScalarQuantity, "A factor must be a ScalarQuantity" + A = self._A.value_si + b = self._n.value_si + E = self._Ea.value_si * 1000 # convert from J/mol to J/kmol + + return ct.StickingArrheniusRate(A, b, E) + + + def set_cantera_kinetics(self, ct_reaction, species_list): + """ + Passes in a cantera Reaction() object and sets its + rate to a Cantera ArrheniusRate object. + """ + import cantera as ct + assert isinstance(ct_reaction.rate, ct.StickingArrheniusRate), "Must have a Cantera StickingArrheniusRate attribute" + + # Set the rate parameter to a cantera Arrhenius object + ct_reaction.rate = self.to_cantera_kinetics() + ################################################################################ cdef class StickingCoefficientBEP(KineticsModel): """ @@ -570,6 +600,54 @@ cdef class SurfaceArrhenius(Arrhenius): return (SurfaceArrhenius, (self.A, self.n, self.Ea, self.T0, self.Tmin, self.Tmax, self.Pmin, self.Pmax, self.coverage_dependence, self.uncertainty, self.comment)) + def to_cantera_kinetics(self): + """ + Converts the RMG SurfaceArrhenius object to a cantera InterfaceArrheniusRate + Inputs are (A,b,E) where A is in units of m^2/kmol/s, b is dimensionless, and E is in J/kmol + + There are no surface falloff reaction types in Cantera, so that isn't implemented here + """ + + import cantera as ct + + rate_units_dimensionality = {'1/s': 0, + 's^-1': 0, + 'm^2/(mol*s)': 1, + 'm^4/(mol^2*s)': 2, + 'cm^2/(mol*s)': 1, + 'cm^4/(mol^2*s)': 2, + 'm^2/(molecule*s)': 1, + 'm^4/(molecule^2*s)': 2, + 'cm^2/(molecule*s)': 1, + 'cm^4/(molecule^2*s)': 2, + } + + if self._T0.value_si != 1: + A = self._A.value_si / (self._T0.value_si) ** self._n.value_si + else: + A = self._A.value_si + + try: + A *= 1000 ** rate_units_dimensionality[self._A.units] + except KeyError: + raise Exception('Arrhenius A-factor units {0} not found among accepted units for converting to ' + 'Cantera Arrhenius object.'.format(self._A.units)) + + b = self._n.value_si + E = self._Ea.value_si * 1000 # convert from J/mol to J/kmol + return ct.InterfaceArrheniusRate(A, b, E) + + def set_cantera_kinetics(self, ct_reaction, species_list): + """ + Passes in a cantera Reaction() object and sets its + rate to a Cantera InterfaceArrheniusRate object. + """ + import cantera as ct + assert isinstance(ct_reaction.rate, ct.InterfaceArrheniusRate), "Must have a Cantera InterfaceArrheniusRate attribute" + + # Set the rate parameter to a cantera Arrhenius object + ct_reaction.rate = self.to_cantera_kinetics() + ################################################################################ cdef class SurfaceArrheniusBEP(ArrheniusEP): diff --git a/rmgpy/reaction.py b/rmgpy/reaction.py index 7484f70d43..db312b859b 100644 --- a/rmgpy/reaction.py +++ b/rmgpy/reaction.py @@ -288,7 +288,10 @@ def to_cantera(self, species_list=None, use_chemkin_identifier=False): if self.kinetics: if isinstance(self.kinetics, Arrhenius): # Create an Elementary Reaction - ct_reaction = ct.Reaction(reactants=ct_reactants, products=ct_products, rate=ct.ArrheniusRate()) + if isinstance(self.kinetics, SurfaceArrhenius): # SurfaceArrhenius inherits from Arrhenius + ct_reaction = ct.Reaction(reactants=ct_reactants, products=ct_products, rate=ct.InterfaceArrheniusRate()) + else: + ct_reaction = ct.Reaction(reactants=ct_reactants, products=ct_products, rate=ct.ArrheniusRate()) elif isinstance(self.kinetics, MultiArrhenius): # Return a list of elementary reactions which are duplicates ct_reaction = [ct.Reaction(reactants=ct_reactants, products=ct_products, rate=ct.ArrheniusRate()) @@ -356,6 +359,9 @@ def to_cantera(self, species_list=None, use_chemkin_identifier=False): reactants=ct_reactants, products=ct_products, rate=rate ) + elif isinstance(self.kinetics, StickingCoefficient): + ct_reaction = ct.Reaction(reactants=ct_reactants, products=ct_products, rate=ct.StickingArrheniusRate()) + else: raise NotImplementedError('Unable to set cantera kinetics for {0}'.format(self.kinetics))