def testGenerateReverseRateCoefficientPDepArrhenius(self): """ Test the Reaction.generateReverseRateCoefficient() method works for the PDepArrhenius format. """ from rmgpy.kinetics import PDepArrhenius arrhenius0 = Arrhenius( A = (1.0e6,"s^-1"), n = 1.0, Ea = (10.0,"kJ/mol"), T0 = (300.0,"K"), Tmin = (300.0,"K"), Tmax = (2000.0,"K"), comment = """This data is completely made up""", ) arrhenius1 = Arrhenius( A = (1.0e12,"s^-1"), n = 1.0, Ea = (20.0,"kJ/mol"), T0 = (300.0,"K"), Tmin = (300.0,"K"), Tmax = (2000.0,"K"), comment = """This data is completely made up""", ) pressures = numpy.array([0.1, 10.0]) arrhenius = [arrhenius0, arrhenius1] Tmin = 300.0 Tmax = 2000.0 Pmin = 0.1 Pmax = 10.0 comment = """This data is completely made up""" original_kinetics = PDepArrhenius( pressures = (pressures,"bar"), arrhenius = arrhenius, Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), Pmin = (Pmin,"bar"), Pmax = (Pmax,"bar"), comment = comment, ) self.reaction2.kinetics = original_kinetics reverseKinetics = self.reaction2.generateReverseRateCoefficient() self.reaction2.kinetics = reverseKinetics # reverse reactants, products to ensure Keq is correctly computed self.reaction2.reactants, self.reaction2.products = self.reaction2.products, self.reaction2.reactants reversereverseKinetics = self.reaction2.generateReverseRateCoefficient() # check that reverting the reverse yields the original Tlist = numpy.arange(Tmin, Tmax, 200.0, numpy.float64) P = 1e5 for T in Tlist: korig = original_kinetics.getRateCoefficient(T, P) krevrev = reversereverseKinetics.getRateCoefficient(T, P) self.assertAlmostEqual(korig / krevrev, 1.0, 0)
def testGenerateReverseRateCoefficientPDepArrhenius(self): """ Test the Reaction.generateReverseRateCoefficient() method works for the PDepArrhenius format. """ from rmgpy.kinetics import PDepArrhenius arrhenius0 = Arrhenius( A=(1.0e6, "s^-1"), n=1.0, Ea=(10.0, "kJ/mol"), T0=(300.0, "K"), Tmin=(300.0, "K"), Tmax=(2000.0, "K"), comment="""This data is completely made up""", ) arrhenius1 = Arrhenius( A=(1.0e12, "s^-1"), n=1.0, Ea=(20.0, "kJ/mol"), T0=(300.0, "K"), Tmin=(300.0, "K"), Tmax=(2000.0, "K"), comment="""This data is completely made up""", ) pressures = numpy.array([0.1, 10.0]) arrhenius = [arrhenius0, arrhenius1] Tmin = 300.0 Tmax = 2000.0 Pmin = 0.1 Pmax = 10.0 comment = """This data is completely made up""" original_kinetics = PDepArrhenius( pressures=(pressures, "bar"), arrhenius=arrhenius, Tmin=(Tmin, "K"), Tmax=(Tmax, "K"), Pmin=(Pmin, "bar"), Pmax=(Pmax, "bar"), comment=comment, ) self.reaction2.kinetics = original_kinetics reverseKinetics = self.reaction2.generateReverseRateCoefficient() self.reaction2.kinetics = reverseKinetics # reverse reactants, products to ensure Keq is correctly computed self.reaction2.reactants, self.reaction2.products = self.reaction2.products, self.reaction2.reactants reversereverseKinetics = self.reaction2.generateReverseRateCoefficient() # check that reverting the reverse yields the original Tlist = numpy.arange(Tmin, Tmax, 200.0, numpy.float64) P = 1e5 for T in Tlist: korig = original_kinetics.getRateCoefficient(T, P) krevrev = reversereverseKinetics.getRateCoefficient(T, P) self.assertAlmostEqual(korig / krevrev, 1.0, 0)
def fitInterpolationModel(self, Tdata, Pdata, kdata, kunits): Tmin = self.Tmin.value_si Tmax = self.Tmax.value_si Pmin = self.Pmin.value_si Pmax = self.Pmax.value_si model = self.interpolationModel[0].lower() if model == 'chebyshev': kinetics = Chebyshev().fitToData( Tdata, Pdata, kdata, kunits, self.interpolationModel[1], self.interpolationModel[2], Tmin, Tmax, Pmin, Pmax, ) elif model == 'pdeparrhenius': kinetics = PDepArrhenius().fitToData(Tdata, Pdata, kdata, kunits) else: raise Exception('Invalid interpolation model {0!r}.'.format( self.interpolationModel[0])) return kinetics
def fit_interpolation_model(self, Tdata, Pdata, kdata, k_units): """Fit an interpolation model to a pressure dependent rate""" Tmin = self.Tmin.value_si Tmax = self.Tmax.value_si Pmin = self.Pmin.value_si Pmax = self.Pmax.value_si model = self.interpolation_model[0].lower() if model == 'chebyshev': kinetics = Chebyshev().fit_to_data(Tdata, Pdata, kdata, k_units, self.interpolation_model[1], self.interpolation_model[2], Tmin, Tmax, Pmin, Pmax) elif model == 'pdeparrhenius': kinetics = PDepArrhenius().fit_to_data(Tdata, Pdata, kdata, k_units) else: raise PressureDependenceError('Invalid interpolation model {0!r}.'.format(self.interpolation_model[0])) return kinetics
def generateReverseRateCoefficient(self): """ Generate and return a rate coefficient model for the reverse reaction. Currently this only works if the `kinetics` attribute is one of several (but not necessarily all) kinetics types. """ cython.declare(Tlist=numpy.ndarray, klist=numpy.ndarray, i=cython.int) supported_types = ( KineticsData.__name__, Arrhenius.__name__, MultiArrhenius.__name__, PDepArrhenius.__name__, MultiPDepArrhenius.__name__, Chebyshev.__name__, ThirdBody.__name__, Lindemann.__name__, Troe.__name__, ) # Get the units for the reverse rate coefficient kunits = getRateCoefficientUnitsFromReactionOrder(len(self.products)) kf = self.kinetics if isinstance(kf, KineticsData): Tlist = kf.Tdata.value_si klist = numpy.zeros_like(Tlist) for i in range(len(Tlist)): klist[i] = kf.getRateCoefficient(Tlist[i]) / self.getEquilibriumConstant(Tlist[i]) kr = KineticsData(Tdata=(Tlist,"K"), kdata=(klist,kunits), Tmin=(numpy.min(Tlist),"K"), Tmax=(numpy.max(Tlist),"K")) return kr elif isinstance(kf, Arrhenius): return self.reverseThisArrheniusRate(kf, kunits) elif isinstance (kf, Chebyshev): Tlist = 1.0/numpy.linspace(1.0/kf.Tmax.value, 1.0/kf.Tmin.value, 50) Plist = numpy.linspace(kf.Pmin.value, kf.Pmax.value, 20) K = numpy.zeros((len(Tlist), len(Plist)), numpy.float64) for Tindex, T in enumerate(Tlist): for Pindex, P in enumerate(Plist): K[Tindex, Pindex] = kf.getRateCoefficient(T, P) / self.getEquilibriumConstant(T) kr = Chebyshev() kr.fitToData(Tlist, Plist, K, kunits, kf.degreeT, kf.degreeP, kf.Tmin.value, kf.Tmax.value, kf.Pmin.value, kf.Pmax.value) return kr elif isinstance(kf, PDepArrhenius): if kf.Tmin is not None and kf.Tmax is not None: Tlist = 1.0/numpy.linspace(1.0/kf.Tmax.value, 1.0/kf.Tmin.value, 50) else: Tlist = 1.0/numpy.arange(0.0005, 0.0035, 0.0001) Plist = kf.pressures.value_si K = numpy.zeros((len(Tlist), len(Plist)), numpy.float64) for Tindex, T in enumerate(Tlist): for Pindex, P in enumerate(Plist): K[Tindex, Pindex] = kf.getRateCoefficient(T, P) / self.getEquilibriumConstant(T) kr = PDepArrhenius() kr.fitToData(Tlist, Plist, K, kunits, kf.arrhenius[0].T0.value) return kr elif isinstance(kf, MultiArrhenius): kr = MultiArrhenius() kr.arrhenius = [] rxn = Reaction(reactants = self.reactants, products = self.products) for kinetics in kf.arrhenius: rxn.kinetics = kinetics kr.arrhenius.append(rxn.generateReverseRateCoefficient()) return kr elif isinstance(kf, MultiPDepArrhenius): kr = MultiPDepArrhenius() kr.arrhenius = [] rxn = Reaction(reactants = self.reactants, products = self.products) for kinetics in kf.arrhenius: rxn.kinetics = kinetics kr.arrhenius.append(rxn.generateReverseRateCoefficient()) return kr elif isinstance(kf, ThirdBody): lowPkunits = getRateCoefficientUnitsFromReactionOrder(len(self.products) + 1) krLow = self.reverseThisArrheniusRate(kf.arrheniusLow, lowPkunits) parameters = kf.__reduce__()[1] # use the pickle helper to get all the other things needed kr = ThirdBody(krLow, *parameters[1:]) return kr elif isinstance(kf, Lindemann): krHigh = self.reverseThisArrheniusRate(kf.arrheniusHigh, kunits) lowPkunits = getRateCoefficientUnitsFromReactionOrder(len(self.products) + 1) krLow = self.reverseThisArrheniusRate(kf.arrheniusLow, lowPkunits) parameters = kf.__reduce__()[1] # use the pickle helper to get all the other things needed kr = Lindemann(krHigh, krLow, *parameters[2:]) return kr elif isinstance(kf, Troe): krHigh = self.reverseThisArrheniusRate(kf.arrheniusHigh, kunits) lowPkunits = getRateCoefficientUnitsFromReactionOrder(len(self.products) + 1) krLow = self.reverseThisArrheniusRate(kf.arrheniusLow, lowPkunits) parameters = kf.__reduce__()[1] # use the pickle helper to get all the other things needed kr = Troe(krHigh, krLow, *parameters[2:]) return kr else: raise ReactionError(("Unexpected kinetics type {0}; should be one of {1}").format(self.kinetics.__class__, supported_types))
def testGenerateReverseRateCoefficientMultiPDepArrhenius(self): """ Test the Reaction.generateReverseRateCoefficient() method works for the MultiPDepArrhenius format. """ from rmgpy.kinetics import PDepArrhenius, MultiPDepArrhenius Tmin = 350. Tmax = 1500. Pmin = 1e-1 Pmax = 1e1 pressures = numpy.array([1e-1,1e1]) comment = 'CH3 + C2H6 <=> CH4 + C2H5 (Baulch 2005)' arrhenius = [ PDepArrhenius( pressures = (pressures,"bar"), arrhenius = [ Arrhenius( A = (9.3e-16,"cm^3/(molecule*s)"), n = 0.0, Ea = (4740*constants.R*0.001,"kJ/mol"), T0 = (1,"K"), Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), comment = comment, ), Arrhenius( A = (9.3e-14,"cm^3/(molecule*s)"), n = 0.0, Ea = (4740*constants.R*0.001,"kJ/mol"), T0 = (1,"K"), Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), comment = comment, ), ], Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), Pmin = (Pmin,"bar"), Pmax = (Pmax,"bar"), comment = comment, ), PDepArrhenius( pressures = (pressures,"bar"), arrhenius = [ Arrhenius( A = (1.4e-11,"cm^3/(molecule*s)"), n = 0.0, Ea = (11200*constants.R*0.001,"kJ/mol"), T0 = (1,"K"), Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), comment = comment, ), Arrhenius( A = (1.4e-9,"cm^3/(molecule*s)"), n = 0.0, Ea = (11200*constants.R*0.001,"kJ/mol"), T0 = (1,"K"), Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), comment = comment, ), ], Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), Pmin = (Pmin,"bar"), Pmax = (Pmax,"bar"), comment = comment, ), ] original_kinetics = MultiPDepArrhenius( arrhenius = arrhenius, Tmin = (Tmin,"K"), Tmax = (Tmax,"K"), Pmin = (Pmin,"bar"), Pmax = (Pmax,"bar"), comment = comment, ) self.reaction2.kinetics = original_kinetics reverseKinetics = self.reaction2.generateReverseRateCoefficient() self.reaction2.kinetics = reverseKinetics # reverse reactants, products to ensure Keq is correctly computed self.reaction2.reactants, self.reaction2.products = self.reaction2.products, self.reaction2.reactants reversereverseKinetics = self.reaction2.generateReverseRateCoefficient() # check that reverting the reverse yields the original Tlist = numpy.arange(Tmin, Tmax, 200.0, numpy.float64) P = 1e5 for T in Tlist: korig = original_kinetics.getRateCoefficient(T, P) krevrev = reversereverseKinetics.getRateCoefficient(T, P) self.assertAlmostEqual(korig / krevrev, 1.0, 0)
def loadFAMEOutput(self, path): """ Load the contents of a FAME ourput file into the MEASURE object. This method assumes that you have already loaded the corresponding input file via :meth:`loadFAMEInput()`. """ def readMeaningfulLine(f): line = f.readline() while line != '': line = line.strip() if len(line) > 0 and line[0] != '#': return line else: line = f.readline() return '' with open(path, 'r') as f: method = readMeaningfulLine(f).strip() Tlist = numpy.array([float(d) for d in readMeaningfulLine(f).strip().split()[2:]]) Plist = numpy.array([float(d) for d in readMeaningfulLine(f).strip().split()[2:]]) model = readMeaningfulLine(f).strip().split() Nspec = int(readMeaningfulLine(f).strip()) Nisom = int(readMeaningfulLine(f).strip()) Nreac = int(readMeaningfulLine(f).strip()) Nprod = int(readMeaningfulLine(f).strip()) Npath = int(readMeaningfulLine(f).strip()) Nnet = int(readMeaningfulLine(f).strip()) assert Nisom == len(self.network.isomers) assert Nreac == len(self.network.reactants) assert Nprod == len(self.network.products) assert Npath == len(self.network.pathReactions) for n in range(Nnet): reac, prod = readMeaningfulLine(f).strip().split() reac = int(reac) - 1; prod = int(prod) - 1 if reac < Nisom: reactants = [self.network.isomers[reac]] elif reac < Nisom + Nreac: reactants = self.network.reactants[reac-Nisom] elif reac < Nisom + Nreac + Nprod: reactants = self.network.products[reac-Nisom-Nreac] else: reactants = [] if prod < Nisom: products = [self.network.isomers[prod]] elif prod < Nisom + Nreac: products = self.network.reactants[prod-Nisom] elif prod < Nisom + Nreac + Nprod: products = self.network.products[prod-Nisom-Nreac] else: products = [] readMeaningfulLine(f) K = numpy.zeros((len(Tlist), len(Plist)), numpy.float64) for t in range(len(Tlist)): K[t,:] = [float(d) for d in readMeaningfulLine(f).strip().split()[1:]] if len(reactants) > 1: # FAME returns k(T,P) values in cm^3/mol*s and s^-1, when # we want m^3/mol*s and s^-1 K /= 1e6 kunits = 'm^3/(mol*s)' else: kunits = 's^-1' if model[0].lower() == 'chebyshev': degreeT = int(model[1]); degreeP = int(model[2]) coeffs = numpy.zeros((degreeT, degreeP), numpy.float64) for t in range(degreeT): coeffs[t,:] = [float(d) for d in readMeaningfulLine(f).strip().split()] if kunits == 'm^3/(mol*s)': coeffs[0,0] -= 6.0 kinetics = Chebyshev(coeffs=coeffs, kunits=kunits, Tmin=self.Tmin, Tmax=self.Tmax, Pmin=self.Pmin, Pmax=self.Pmax) elif model[0].lower() == 'pdeparrhenius': pressures = [] arrhenius = [] for p in range(len(Plist)): P, A, n, Ea = [float(d) for d in readMeaningfulLine(f).strip().split()] if kunits == 'm^3/(mol*s)': A /= 1e6 pressures.append(P) arrhenius.append(Arrhenius( A = (A,kunits), n = n, Ea = (Ea,"J/mol"), T0=(1,"K"), Tmin=self.Tmin, Tmax=self.Tmax )) kinetics = PDepArrhenius(pressures=(pressures,"Pa"), arrhenius=arrhenius, Tmin=self.Tmin, Tmax=self.Tmax, Pmin=self.Pmin, Pmax=self.Pmax) netReaction = Reaction( reactants = reactants, products = products, kinetics = kinetics ) self.network.netReactions.append(netReaction)