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
), numpy.float64) Tdata = numpy.array(columns[0][1:], dtype=numpy.float64) Pdata = numpy.zeros(len(columns) - 1, numpy.float64) for col_num, col in enumerate(columns[1:]): Pdata[col_num] = col[0] for row_num, row in enumerate(col[1:]): kdata[row_num, col_num] = numpy.array(row, dtype=numpy.float64) ########################Fit Chebyshev polynomial to kdata################################################### kunits = {1: 's^-1', 2: 'cm^3/(mol*s)', 3: 'cm^6/(mol^2*s)'}[order] kinetics = Chebyshev().fitToData(Tdata, Pdata * 101325., kdata, kunits, num_Cheb_coeff_1, num_Cheb_coeff_2, Tdata[0], Tdata[-1], Pdata[0] * 101325., Pdata[-1] * 101325.) ########################Output Chebyshev fit to CHEMKIN input file format##################################### # Initialize (and clear!) the output files for the job outputDirectory = os.path.dirname(os.path.abspath(k_data_path)) chemkinFile = os.path.join(outputDirectory, reaction_string.replace(" ", "_") + '.inp') with open(chemkinFile, 'w') as f: pass Tcount = Tdata.shape[0] Pcount = Pdata.shape[0] f = open(chemkinFile, 'a')
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 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)