Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add to_cantera_kinetics for SurfaceArrhenius and StickingCoefficient kinetics classes #2597

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 78 additions & 0 deletions rmgpy/kinetics/surface.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down Expand Up @@ -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):
Expand Down
8 changes: 7 additions & 1 deletion rmgpy/reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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))

Expand Down
Loading