def test_plog(self): gas1 = ct.Solution('pdep-test.cti') species = ct.Species.listFromFile('pdep-test.cti') r = ct.PlogReaction() r.reactants = {'R1A': 1, 'R1B': 1} r.products = {'P1': 1, 'H': 1} r.rates = [ (0.01 * ct.one_atm, ct.Arrhenius(1.2124e13, -0.5779, 10872.7 * 4184)), (1.0 * ct.one_atm, ct.Arrhenius(4.9108e28, -4.8507, 24772.8 * 4184)), (10.0 * ct.one_atm, ct.Arrhenius(1.2866e44, -9.0246, 39796.5 * 4184)), (100.0 * ct.one_atm, ct.Arrhenius(5.9632e53, -11.529, 52599.6 * 4184)) ] gas2 = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=[r]) gas2.X = gas1.X = 'R1A:0.3, R1B:0.6, P1:0.1' for P in [0.001, 0.01, 0.2, 1.0, 1.1, 9.0, 10.0, 99.0, 103.0]: gas1.TP = gas2.TP = 900, P * ct.one_atm self.assertNear(gas2.forward_rate_constants[0], gas1.forward_rate_constants[0]) self.assertNear(gas2.net_rates_of_progress[0], gas1.net_rates_of_progress[0])
def set_mechanism(self, mech_dict, species_dict={}, bnds=[]): def get_Arrhenius_parameters(entry): A = entry['pre_exponential_factor'] b = entry['temperature_exponent'] Ea = entry['activation_energy'] return A, b, Ea if len(species_dict) == 0: species = self.gas.species() else: species = [] for n in range(len(species_dict)): s_dict = species_dict[n] s = ct.Species(name=s_dict['name'], composition=s_dict['composition'], charge=s_dict['charge'], size=s_dict['size']) thermo = s_dict['type'](s_dict['T_low'], s_dict['T_high'], s_dict['P_ref'], s_dict['coeffs']) s.thermo = thermo species.append(s) # Set kinetics data rxns = [] for rxnIdx in range(len(mech_dict)): if 'ElementaryReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.ElementaryReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) rxn.allow_negative_pre_exponential_factor = True A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs'][0]) rxn.rate = ct.Arrhenius(A, b, Ea) elif 'ThreeBodyReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.ThreeBodyReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs'][0]) rxn.rate = ct.Arrhenius(A, b, Ea) rxn.efficiencies = mech_dict[rxnIdx]['rxnCoeffs'][0][ 'efficiencies'] elif 'PlogReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.PlogReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) rates = [] for plog in mech_dict[rxnIdx]['rxnCoeffs']: pressure = plog['Pressure'] A, b, Ea = get_Arrhenius_parameters(plog) rates.append((pressure, ct.Arrhenius(A, b, Ea))) rxn.rates = rates elif 'FalloffReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.FalloffReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) # high pressure limit A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs']['high_rate']) rxn.high_rate = ct.Arrhenius(A, b, Ea) # low pressure limit A, b, Ea = get_Arrhenius_parameters( mech_dict[rxnIdx]['rxnCoeffs']['low_rate']) rxn.low_rate = ct.Arrhenius(A, b, Ea) # falloff parameters if mech_dict[rxnIdx]['rxnCoeffs']['falloff_type'] == 'Troe': falloff_param = mech_dict[rxnIdx]['rxnCoeffs'][ 'falloff_parameters'] if falloff_param[-1] == 0.0: falloff_param = falloff_param[0:-1] rxn.falloff = ct.TroeFalloff(falloff_param) else: rxn.falloff = ct.SriFalloff( mech_dict[rxnIdx]['rxnCoeffs']['falloff_parameters']) rxn.efficiencies = mech_dict[rxnIdx]['rxnCoeffs'][ 'efficiencies'] elif 'ChebyshevReaction' == mech_dict[rxnIdx]['rxnType']: rxn = ct.ChebyshevReaction(mech_dict[rxnIdx]['reactants'], mech_dict[rxnIdx]['products']) rxn.set_parameters(Tmin=mech_dict['Tmin'], Tmax=mech_dict['Tmax'], Pmin=mech_dict['Pmin'], Pmax=mech_dict['Pmax'], coeffs=mech_dict['coeffs']) rxn.duplicate = mech_dict[rxnIdx]['duplicate'] rxn.reversible = mech_dict[rxnIdx]['reversible'] rxn.allow_negative_orders = True rxn.allow_nonreactant_orders = True rxns.append(rxn) self.gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=species, reactions=rxns) self.set_rate_expression_coeffs(bnds) # set copy of coeffs self.set_thermo_expression_coeffs() # set copy of thermo coeffs
def toCantera(self, speciesList=None, useChemkinIdentifier = False): """ Converts the RMG Reaction object to a Cantera Reaction object with the appropriate reaction class. If useChemkinIdentifier is set to False, the species label is used instead. Be sure that species' labels are unique when setting it False. """ from rmgpy.kinetics import Arrhenius, ArrheniusEP, MultiArrhenius, PDepArrhenius, MultiPDepArrhenius, Chebyshev, ThirdBody, Lindemann, Troe import cantera as ct if speciesList is None: speciesList = [] # Create the dictionaries containing species strings and their stoichiometries # for initializing the cantera reaction object ctReactants = {} for reactant in self.reactants: if useChemkinIdentifier: reactantName = reactant.toChemkin() else: reactantName = reactant.label if reactantName in ctReactants: ctReactants[reactantName] += 1 else: ctReactants[reactantName] = 1 ctProducts = {} for product in self.products: if useChemkinIdentifier: productName = product.toChemkin() else: productName = product.label if productName in ctProducts: ctProducts[productName] += 1 else: ctProducts[productName] = 1 if self.kinetics: if isinstance(self.kinetics, Arrhenius): # Create an Elementary Reaction ctReaction = ct.ElementaryReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, MultiArrhenius): # Return a list of elementary reactions which are duplicates ctReaction = [ct.ElementaryReaction(reactants=ctReactants, products=ctProducts) for arr in self.kinetics.arrhenius] elif isinstance(self.kinetics, PDepArrhenius): ctReaction = ct.PlogReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, MultiPDepArrhenius): ctReaction = [ct.PlogReaction(reactants=ctReactants, products=ctProducts) for arr in self.kinetics.arrhenius] elif isinstance(self.kinetics, Chebyshev): ctReaction = ct.ChebyshevReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, ThirdBody): ctReaction = ct.ThreeBodyReaction(reactants=ctReactants, products=ctProducts) elif isinstance(self.kinetics, Lindemann) or isinstance(self.kinetics, Troe): ctReaction = ct.FalloffReaction(reactants=ctReactants, products=ctProducts) else: raise NotImplementedError('Not able to set cantera kinetics for {0}'.format(self.kinetics)) # Set reversibility, duplicate, and ID attributes if isinstance(ctReaction,list): for rxn in ctReaction: rxn.reversible = self.reversible # Set the duplicate flag to true since this reaction comes from multiarrhenius or multipdeparrhenius rxn.duplicate = True # Set the ID flag to the original rmg index rxn.ID = str(self.index) else: ctReaction.reversible = self.reversible ctReaction.duplicate = self.duplicate ctReaction.ID = str(self.index) self.kinetics.setCanteraKinetics(ctReaction, speciesList) return ctReaction else: raise Exception('Cantera reaction cannot be created because there was no kinetics.')