def test_fitToData(self): """ Test the Arrhenius.fitToData() method. """ Tdata = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) kdata = numpy.array( [self.arrhenius.getRateCoefficient(T) for T in Tdata]) arrhenius = Arrhenius().fitToData(Tdata, kdata, kunits="m^3/(mol*s)") self.assertEqual(float(self.arrhenius.T0.value_si), 1) for T, k in zip(Tdata, kdata): self.assertAlmostEqual(k, arrhenius.getRateCoefficient(T), delta=1e-6 * k) self.assertAlmostEqual(arrhenius.A.value_si, self.arrhenius.A.value_si, delta=1e0) self.assertAlmostEqual(arrhenius.n.value_si, self.arrhenius.n.value_si, 1, 4) self.assertAlmostEqual(arrhenius.Ea.value_si, self.arrhenius.Ea.value_si, 2) self.assertAlmostEqual(arrhenius.T0.value_si, self.arrhenius.T0.value_si, 4)
def test_get_kinetic_isotope_effect_simple(self): reactant_pair = [ Species().from_smiles("C"), Species().from_smiles("[H]") ] product_pair = [ Species().from_smiles("[H][H]"), Species().from_smiles("[CH3]") ] rxn_unlabeled = TemplateReaction(reactants=reactant_pair, products=product_pair, family='H_Abstraction', kinetics=Arrhenius(A=(1e5, 'cm^3/(mol*s)'), Ea=(0, 'J/mol'))) rxn_labeled = TemplateReaction(reactants=[ Species().from_adjacency_list(""" 1 C u0 p0 c0 i13 {2,S} {3,S} {4,S} {5,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 H u0 p0 c0 {1,S} 5 H u0 p0 c0 {1,S} """), Species().from_adjacency_list(""" multiplicity 2 1 H u1 p0 c0 """) ], products=[ Species().from_adjacency_list(""" 1 H u0 p0 c0 {2,S} 2 H u0 p0 c0 {1,S} """), Species().from_adjacency_list(""" multiplicity 2 1 C u1 p0 c0 i13 {2,S} {3,S} {4,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 H u0 p0 c0 {1,S} """) ], family='H_Abstraction', kinetics=Arrhenius(A=(1e5, 'cm^3/(mol*s)'), Ea=(0, 'J/mol'))) rxn_cluster = [[rxn_labeled, rxn_unlabeled]] apply_kinetic_isotope_effect_simple(rxn_cluster, self.database.kinetics) expected_kie = ((1 / 1.008 + 1 / (13.01 + 1.008)) / (1 / 1.008 + 1 / (12.01 + 1.008)))**0.5 self.assertAlmostEqual(rxn_cluster[0][0].kinetics.A.value, 1e5 * expected_kie, places=-1)
def test_fitToData(self): """ Test the Arrhenius.fitToData() method. """ Tdata = numpy.array([300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500]) kdata = numpy.array([self.arrhenius.getRateCoefficient(T) for T in Tdata]) arrhenius = Arrhenius().fitToData(Tdata, kdata, kunits="m^3/(mol*s)") self.assertEqual(float(self.arrhenius.T0.value_si), 1) for T, k in zip(Tdata, kdata): self.assertAlmostEqual(k, arrhenius.getRateCoefficient(T), delta=1e-6 * k) self.assertAlmostEqual(arrhenius.A.value_si, self.arrhenius.A.value_si, delta=1e0) self.assertAlmostEqual(arrhenius.n.value_si, self.arrhenius.n.value_si, 1, 4) self.assertAlmostEqual(arrhenius.Ea.value_si, self.arrhenius.Ea.value_si, 2) self.assertAlmostEqual(arrhenius.T0.value_si, self.arrhenius.T0.value_si, 4)
def setUp(self): """ A function run before each unit test in this class. """ self.arrheniusHigh = Arrhenius( A=(1.39e+16, "cm^3/(mol*s)"), n=-0.534, Ea=(2.243, "kJ/mol"), T0=(1, "K"), ) self.arrheniusLow = Arrhenius( A=(2.62e+33, "cm^6/(mol^2*s)"), n=-4.76, Ea=(10.21, "kJ/mol"), T0=(1, "K"), ) self.alpha = 0.783 self.T3 = 74 self.T1 = 2941 self.T2 = 6964 self.efficiencies = { "C": 3, "C(=O)=O": 2, "CC": 3, "O": 6, "[Ar]": 0.7, "[C]=O": 1.5, "[H][H]": 2 } self.Tmin = 300. self.Tmax = 2000. self.Pmin = 0.01 self.Pmax = 100. self.comment = """H + CH3 -> CH4""" self.troe = Troe( arrheniusHigh=self.arrheniusHigh, arrheniusLow=self.arrheniusLow, alpha=self.alpha, T3=(self.T3, "K"), T1=(self.T1, "K"), T2=(self.T2, "K"), Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), efficiencies=self.efficiencies, comment=self.comment, )
def atkinson_get_arrhenius(self, reaction): """ Estimates the reaction rate for alkoxy decomposition given an RMG reaction from R_Addition_multiplebond family using species with proper labeling. The reaction object will be in the oposite direction with the product being alkoxy radical Returns an RMG kineticsdata object The method originates from Atkinson 2007 """ from rmgpy.kinetics.arrhenius import Arrhenius A = 5e13 #s-1 b = 0.40 #get radical species for lookup of a value tree_entry = get_group_entry(reaction, self.a_value_tree) a = tree_entry.data if a is None: raise TypeError('The node {} had no data'.format(tree_entry)) #get heat of reaction deltaH = reaction.getEnthalpyOfReaction(298) # j/mol deltaH /= 4184 #kcal/mol Ea = a - b * deltaH # get deneracy A *= reaction.degeneracy return Arrhenius(A=(A, 's^-1'), Ea=(Ea, 'kcal/mol'))
def test_ensure_reaction_direction_with_multiple_ts(self): """Tests that ensure reaction direction can handle multiple transition states""" family = self.database.kinetics.families['intra_H_migration'] r = Molecule().from_smiles("[CH2]CCC") p = Molecule().from_smiles("C[CH]CC") rxn = TemplateReaction(reactants=[r], products=[p]) family.add_atom_labels_for_reaction(reaction=rxn) rxn.template = family.get_reaction_template_labels(reaction=rxn) rxn.degeneracy = family.calculate_degeneracy(rxn) rxn.family = 'intra_H_migration' rxn.kinetics = Arrhenius(A=(1, 's^-1')) ri = Molecule().from_adjacency_list(""" multiplicity 2 1 C u1 p0 c0 {2,S} {3,S} {4,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 C u0 p0 c0 i13 {1,S} {5,S} {7,S} {8,S} 5 C u0 p0 c0 i13 {4,S} {6,S} {9,S} {10,S} 6 C u0 p0 c0 {5,S} {11,S} {12,S} {13,S} 7 H u0 p0 c0 {4,S} 8 H u0 p0 c0 {4,S} 9 H u0 p0 c0 {5,S} 10 H u0 p0 c0 {5,S} 11 H u0 p0 c0 {6,S} 12 H u0 p0 c0 {6,S} 13 H u0 p0 c0 {6,S} """) pi = Molecule().from_adjacency_list(""" multiplicity 2 1 C u0 p0 c0 {2,S} {6,S} {7,S} {8,S} 2 C u1 p0 c0 i13 {1,S} {3,S} {4,S} 3 H u0 p0 c0 {2,S} 4 C u0 p0 c0 i13 {2,S} {5,S} {9,S} {10,S} 5 C u0 p0 c0 {4,S} {11,S} {12,S} {13,S} 6 H u0 p0 c0 {1,S} 7 H u0 p0 c0 {1,S} 8 H u0 p0 c0 {1,S} 9 H u0 p0 c0 {4,S} 10 H u0 p0 c0 {4,S} 11 H u0 p0 c0 {5,S} 12 H u0 p0 c0 {5,S} 13 H u0 p0 c0 {5,S} """) rxni = TemplateReaction(reactants=[pi], products=[ri], pairs=[[pi, ri]]) family.add_atom_labels_for_reaction(reaction=rxni) rxni.template = family.get_reaction_template_labels(reaction=rxni) rxn_cluster = [rxn, rxni] ensure_reaction_direction(rxn_cluster) self.assertEqual(rxn_cluster[0].degeneracy, 2) self.assertEqual(rxn_cluster[1].degeneracy, 2) self.assertIn('R2Hall', rxn_cluster[0].template) self.assertIn('R2Hall', rxn_cluster[1].template) self.assertAlmostEqual( rxn_cluster[0].kinetics.get_rate_coefficient(298), rxn_cluster[1].kinetics.get_rate_coefficient(298))
def vereecken_get_arrhenius(self, reaction): """ Estimates the reaction rate for alkoxy decomposition given an RMG reaction from R_Addition_multiplebond family using species with proper labeling. The reaction object will be in the oposite direction with the product being alkoxy radical Returns an RMG kineticsdata object The method originates from Atkinson 2007 """ from rmgpy.kinetics.arrhenius import Arrhenius A = 1.8e13 #s-1 n = 1.7 T0 = 298 #get alkoxy alkoxy = reaction.products[0].molecule[0] groups = vereecken_get_groups(alkoxy) #print alkoxy #print groups Eb = calculate_Eb(groups) # get deneracy A *= reaction.degeneracy return Arrhenius(A=(A, 's^-1'), n=n, T0=(T0, 'K'), Ea=(Eb, 'kcal/mol'))
def generateKinetics(self,Tlist=None): """ Generate the kinetics data for the reaction and fit it to a modified Arrhenius model. """ kineticsClass = 'Arrhenius' tunneling = self.reaction.transitionState.tunneling if isinstance(tunneling, Wigner) and tunneling.frequency is None: tunneling.frequency = (self.reaction.transitionState.frequency.value_si,"cm^-1") elif isinstance(tunneling, Eckart) and tunneling.frequency is None: tunneling.frequency = (self.reaction.transitionState.frequency.value_si,"cm^-1") tunneling.E0_reac = (sum([reactant.conformer.E0.value_si for reactant in self.reaction.reactants])*0.001,"kJ/mol") tunneling.E0_TS = (self.reaction.transitionState.conformer.E0.value_si*0.001,"kJ/mol") tunneling.E0_prod = (sum([product.conformer.E0.value_si for product in self.reaction.products])*0.001,"kJ/mol") elif tunneling is not None: raise ValueError('Unknown tunneling model {0!r}.'.format(tunneling)) logging.info('Generating {0} kinetics model for {0}...'.format(kineticsClass, self.reaction)) if Tlist is None: Tlist = 1000.0/numpy.arange(0.4, 3.35, 0.05) klist = numpy.zeros_like(Tlist) for i in range(Tlist.shape[0]): klist[i] = self.reaction.calculateTSTRateCoefficient(Tlist[i]) order = len(self.reaction.reactants) klist *= 1e6 ** (order-1) self.kunits = {1: 's^-1', 2: 'cm^3/(mol*s)', 3: 'cm^6/(mol^2*s)'}[order] self.Kequnits = {2:'mol^2/cm^6', 1:'mol/cm^3', 0:' ', -1:'cm^3/mol', -2:'cm^6/mol^2'}[len(self.reaction.products)-len(self.reaction.reactants)] self.krunits = {1: 's^-1', 2: 'cm^3/(mol*s)', 3: 'cm^6/(mol^2*s)'}[len(self.reaction.products)] self.reaction.kinetics = Arrhenius().fitToData(Tlist, klist, kunits=self.kunits)
def mereau_get_arrhenius(self, reaction): """ Estimates the reaction rate for alkoxy decomposition given an RMG reaction from R_Addition_multiplebond family using species with proper labeling. The reaction object will be in the oposite direction with the product being alkoxy radical Returns an RMG kineticsdata object The method originates from Atkinson 2007 """ from rmgpy.kinetics.arrhenius import Arrhenius A = 1e14 #s-1 IP = get_IP_of_reaction(reaction) n_H = get_n_H(reaction.products[0].molecule[0]) Ea = 2.5 * IP + 2.1 * n_H - 10.4 # get deneracy A *= reaction.degeneracy return Arrhenius(A=(A, 's^-1'), Ea=(Ea, 'kcal/mol'))
def setUp(self): """ A function run before each unit test in this class. """ self.arrheniusLow = Arrhenius( A=(2.62e+33, "cm^6/(mol^2*s)"), n=-4.76, Ea=(10.21, "kJ/mol"), T0=(1, "K"), ) self.efficiencies = { "C": 3, "C(=O)=O": 2, "CC": 3, "O": 6, "[Ar]": 0.7, "[C]=O": 1.5, "[H][H]": 2 } self.Tmin = 300. self.Tmax = 2000. self.Pmin = 0.01 self.Pmax = 100. self.comment = """H + CH3 -> CH4""" self.thirdBody = ThirdBody( arrheniusLow=self.arrheniusLow, Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), efficiencies=self.efficiencies, comment=self.comment, )
def orlando_get_arrhenius(self,reaction): """ Estimates the reaction rate for alkoxy decomposition given an RMG reaction from R_Addition_multiplebond family using species with proper labeling. The reaction object will be in the oposite direction with the product being alkoxy radical Returns an RMG kineticsdata object The method originates from Atkinson 2007 """ from rmgpy.kinetics.arrhenius import Arrhenius A = 1e14 #s-1 IP = get_IP_of_reaction(reaction) #get heat of reaction deltaH = reaction.getEnthalpyOfReaction(298) # j/mol deltaH /=4184 #kcal/mol Ea = 2.4 * IP - 0.58*deltaH -11.8 # get deneracy A *= reaction.degeneracy return Arrhenius(A=(A,'s^-1'),Ea=(Ea,'kcal/mol'))
def reverseThisArrheniusRate(self, kForward, reverseUnits): """ Reverses the given kForward, which must be an Arrhenius type. You must supply the correct units for the reverse rate. The equilibrium constant is evaluated from the current reaction instance (self). """ cython.declare(kf=Arrhenius, kr=Arrhenius) cython.declare(Tlist=numpy.ndarray, klist=numpy.ndarray, i=cython.int) kf = kForward assert isinstance(kf, Arrhenius), "Only reverses Arrhenius rates" Tlist = 1.0 / numpy.arange(0.0005, 0.0034, 0.0001) # 294 K to 2000 K # Determine the values of the reverse rate coefficient k_r(T) at each temperature klist = numpy.zeros_like(Tlist) for i in range(len(Tlist)): klist[i] = kf.getRateCoefficient(Tlist[i]) / self.getEquilibriumConstant(Tlist[i]) kr = Arrhenius() kr.fitToData(Tlist, klist, reverseUnits, kf.T0.value_si) return kr
def setUp(self): """ A function run before each unit test in this class. """ self.A = 1.0e12 self.n = 0.5 self.Ea = 41.84 self.T0 = 1. self.Tmin = 300. self.Tmax = 3000. self.comment = 'C2H6' self.arrhenius = Arrhenius( A=(self.A, "cm^3/(mol*s)"), n=self.n, Ea=(self.Ea, "kJ/mol"), T0=(self.T0, "K"), Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, )
def reverseThisArrheniusRate(self, kForward, reverseUnits): """ Reverses the given kForward, which must be an Arrhenius type. You must supply the correct units for the reverse rate. The equilibrium constant is evaluated from the current reaction instance (self). """ cython.declare(kf=Arrhenius, kr=Arrhenius) cython.declare(Tlist=numpy.ndarray, klist=numpy.ndarray, i=cython.int) kf = kForward assert isinstance(kf, Arrhenius), "Only reverses Arrhenius rates" if kf.Tmin is not None and kf.Tmax is not None: Tlist = 1.0/numpy.linspace(1.0/kf.Tmax.value_si, 1.0/kf.Tmin.value_si, 50) else: Tlist = 1.0 / numpy.arange(0.0005, 0.0034, 0.0001) # 294 K to 2000 K # Determine the values of the reverse rate coefficient k_r(T) at each temperature klist = numpy.zeros_like(Tlist) for i in range(len(Tlist)): klist[i] = kf.getRateCoefficient(Tlist[i]) / self.getEquilibriumConstant(Tlist[i]) kr = Arrhenius() kr.fitToData(Tlist, klist, reverseUnits, kf.T0.value_si) return kr
def test_generate_isotope_reactions_limited_labeling(self): """ shows that all isotope reactions are created with generateIsotopeReactions with limits of two isotopes per molecule """ max_number_labels = 1 methyl = Species().from_smiles('[CH3]') methyl_isotopologues = [methyl] + generate_isotopomers( methyl, max_number_labels) methane = Species().from_smiles('C') methane_isotopologues = [methane] + generate_isotopomers( methane, max_number_labels) ethyl = Species().from_smiles('C[CH2]') ethyl_isotopologues = [ethyl] + generate_isotopomers( ethyl, max_number_labels) ethane = Species().from_smiles('CC') ethane_isotopologues = [ethane] + generate_isotopomers( ethane, max_number_labels) self.assertEqual(len(methyl_isotopologues), 2) self.assertEqual(len(methane_isotopologues), 2) self.assertEqual(len(ethane_isotopologues), 2) self.assertEqual(len(ethyl_isotopologues), 3) reaction = TemplateReaction(reactants=[ethyl, methane], products=[ethane, methyl], family='H_Abstraction', template=['C/H4', 'Y_rad'], degeneracy=4) reaction.kinetics = Arrhenius(A=(1e5, 'cm^3/(mol*s)'), Ea=(0, 'J/mol')) isotope_list = [ methyl_isotopologues, methane_isotopologues, ethyl_isotopologues, ethane_isotopologues ] new_reactions = generate_isotope_reactions([reaction], isotope_list) self.assertEqual(len(new_reactions), 6) degeneracies_found = set() for rxn in new_reactions: self.assertEqual(rxn.template, reaction.template) degeneracies_found.add(rxn.degeneracy) self.assertIsNotNone( rxn.kinetics, 'kinetics not obtained for reaction {}.'.format(rxn)) self.assertAlmostEqual( reaction.kinetics.get_rate_coefficient(298), rxn.kinetics.get_rate_coefficient(298) * reaction.degeneracy / rxn.degeneracy) self.assertEqual(degeneracies_found, set([4]))
def setUp(self): """ A function run before each unit test in this class. """ self.Tmin = 350. self.Tmax = 1500. self.comment = 'Comment' self.arrhenius = [ Arrhenius( A=(9.3e-14, "cm^3/(molecule*s)"), n=0.0, Ea=(4740 * constants.R * 0.001, "kJ/mol"), T0=(1, "K"), Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.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=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, ), ] self.kinetics = MultiArrhenius( arrhenius=self.arrhenius, Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, ) self.single_kinetics = MultiArrhenius( arrhenius=self.arrhenius[:1], Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, )
def setUp(self): """ A function run before each unit test in this class. """ self.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""", ) self.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""", ) self.pressures = numpy.array([0.1, 10.0]) self.arrhenius = [self.arrhenius0, self.arrhenius1] self.Tmin = 300.0 self.Tmax = 2000.0 self.Pmin = 0.1 self.Pmax = 10.0 self.comment = """This data is completely made up""" self.kinetics = PDepArrhenius( pressures=(self.pressures, "bar"), arrhenius=self.arrhenius, Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), comment=self.comment, )
def get_arrhenius_from_param(params, settings, arrh_type='Arrhenius'): """ Get Arrhenius object given params and settings Args: params (dict) : A dictionary contains the information about A factor, n, Ea, T0 and multiplier settings (dict): A dictionary contains the information about variable units, T and P range, description arrh_type (str): The type of Arrhenius object to be added, supporting Arrhenius, MultiArrhenius, and PdepArrehnius Returns: (Arrhenius object): The Arrhenius object generated """ args = {} if 'Tmin' in settings and settings['Tmin']: args['Tmin'] = (settings['Tmin'], settings['T_unit']) if 'Tmax' in settings and settings['Tmax']: args['Tmax'] = (settings['Tmax'], settings['T_unit']) if 'Pmin' in settings and settings['Pmin']: args['Pmin'] = (settings['Pmin'], settings['P_unit']) if 'Pmax' in settings and settings['Pmax']: args['Pmax'] = (settings['Pmax'], settings['P_unit']) if 'comment' in settings and settings['comment']: args['comment'] = settings['comment'] if arrh_type == 'Arrhenius': args['A'] = (params['A'], settings['A_unit']) args['n'] = params['n'] args['Ea'] = (params['Ea'], settings['E_unit']) if 'T0' in params and params['T0']: args['T0'] = (params['T0'], settings['T_unit']) if 'uncertainty' in params and params['uncertainty']: args['uncertainty'] = params['uncertainty'] return Arrhenius(**args) elif arrh_type == 'MultiArrhenius': args['arrhenius'] = params['arrhenius'] return MultiArrhenius(**args) elif arrh_type == 'PdepArrhenius': args['arrhenius'] = params['arrhenius'] args['pressures'] = (params['pressures'], settings['P_unit']) if 'highPlimit' and params['highPlimit']: args['highPlimit'] = params['highPlimit'] return PDepArrhenius(**args)
def setUp(self): """ A function run before each unit test in this class. """ self.A = 1.0e12 self.n = 0.5 self.Ea = 41.84 self.T0 = 1.0 self.Tmin = 300.0 self.Tmax = 3000.0 self.comment = "C2H6" self.arrhenius = Arrhenius( A=(self.A, "cm^3/(mol*s)"), n=self.n, Ea=(self.Ea, "kJ/mol"), T0=(self.T0, "K"), Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, )
def generate_kinetics(self): """ Generate the kinetics data for the reaction and fit it to a modified Arrhenius model. """ if isinstance(self.reaction.kinetics, Arrhenius): return None self.usedTST = True kinetics_class = 'Arrhenius' tunneling = self.reaction.transition_state.tunneling if isinstance(tunneling, Wigner) and tunneling.frequency is None: tunneling.frequency = (self.reaction.transition_state.frequency.value_si, "cm^-1") elif isinstance(tunneling, Eckart) and tunneling.frequency is None: tunneling.frequency = (self.reaction.transition_state.frequency.value_si, "cm^-1") tunneling.E0_reac = (sum([reactant.conformer.E0.value_si for reactant in self.reaction.reactants]) * 0.001, "kJ/mol") tunneling.E0_TS = (self.reaction.transition_state.conformer.E0.value_si * 0.001, "kJ/mol") tunneling.E0_prod = (sum([product.conformer.E0.value_si for product in self.reaction.products]) * 0.001, "kJ/mol") elif tunneling is not None: if tunneling.frequency is not None: # Frequency was given by the user pass else: raise ValueError('Unknown tunneling model {0!r} for reaction {1}.'.format(tunneling, self.reaction)) logging.debug('Generating {0} kinetics model for {1}...'.format(kinetics_class, self.reaction)) klist = np.zeros_like(self.Tlist.value_si) for i, t in enumerate(self.Tlist.value_si): klist[i] = self.reaction.calculate_tst_rate_coefficient(t) order = len(self.reaction.reactants) klist *= 1e6 ** (order - 1) self.k_units = {1: 's^-1', 2: 'cm^3/(mol*s)', 3: 'cm^6/(mol^2*s)'}[order] self.K_eq_units = {2: 'mol^2/cm^6', 1: 'mol/cm^3', 0: ' ', -1: 'cm^3/mol', -2: 'cm^6/mol^2'}[ len(self.reaction.products) - len(self.reaction.reactants)] self.k_r_units = {1: 's^-1', 2: 'cm^3/(mol*s)', 3: 'cm^6/(mol^2*s)'}[len(self.reaction.products)] self.reaction.kinetics = Arrhenius().fit_to_data(self.Tlist.value_si, klist, kunits=self.k_units, three_params=self.three_params) self.reaction.elementary_high_p = True
def test_ensure_reaction_direction(self): """ Tests that the direction of the reaction is constant for every isotopomer """ # get reactions methyl = Species().from_smiles('[CH3]') methyli = Species().from_adjacency_list(""" multiplicity 2 1 C u1 p0 c0 i13 {2,S} {3,S} {4,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 H u0 p0 c0 {1,S} """) methane = Species().from_smiles('C') methanei = Species().from_adjacency_list(""" 1 C u0 p0 c0 i13 {2,S} {3,S} {4,S} {5,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 H u0 p0 c0 {1,S} 5 H u0 p0 c0 {1,S} """) dipropyl = Species().from_smiles('[CH2]C[CH2]') dipropyli = Species().from_adjacency_list(""" multiplicity 3 1 C u1 p0 c0 {2,S} {3,S} {4,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 C u0 p0 c0 {1,S} {5,S} {8,S} {9,S} 5 C u1 p0 c0 i13 {4,S} {6,S} {7,S} 6 H u0 p0 c0 {5,S} 7 H u0 p0 c0 {5,S} 8 H u0 p0 c0 {4,S} 9 H u0 p0 c0 {4,S} """) propyl = Species().from_smiles('CC[CH2]') propyli = Species().from_adjacency_list(""" multiplicity 2 1 C u1 p0 c0 i13 {2,S} {3,S} {4,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 C u0 p0 c0 {1,S} {5,S} {6,S} {7,S} 5 C u0 p0 c0 {4,S} {8,S} {9,S} {10,S} 6 H u0 p0 c0 {4,S} 7 H u0 p0 c0 {4,S} 8 H u0 p0 c0 {5,S} 9 H u0 p0 c0 {5,S} 10 H u0 p0 c0 {5,S} """) propyl.label = 'propyl' propyli.label = 'propyli' dipropyl.label = 'dipropyl' dipropyli.label = 'dipropyli' methyl.label = 'methyl' methyli.label = 'methyli' methane.label = 'methane' methanei.label = 'methanei' # make reactions rxn1 = TemplateReaction(reactants=[dipropyl, methane], products=[methyl, propyl], kinetics=Arrhenius(A=(1., 'cm^3/(mol*s)'), Ea=(2., 'kJ/mol'), n=0.), family='H_Abstraction', template=['a', 'c'], degeneracy=8, pairs=[[methane, methyl], [dipropyl, propyl]]) rxn2 = TemplateReaction(reactants=[methyli, propyl], products=[methanei, dipropyl], kinetics=Arrhenius(A=(1e-20, 'cm^3/(mol*s)'), Ea=(2., 'kJ/mol'), n=0.), family='H_Abstraction', template=['b', 'd'], degeneracy=3, pairs=[[methyli, methanei], [propyl, dipropyl]]) rxn3 = TemplateReaction(reactants=[methane, dipropyli], products=[methyl, propyli], kinetics=Arrhenius(A=(0.5, 'cm^3/(mol*s)'), Ea=(2., 'kJ/mol'), n=0.), family='H_Abstraction', template=['a', 'c'], degeneracy=4, pairs=[[methane, methyl], [dipropyli, propyli]]) rxn4 = TemplateReaction(reactants=[methyli, propyli], products=[methanei, dipropyli], kinetics=Arrhenius(A=(1e-20, 'cm^3/(mol*s)'), Ea=(2., 'kJ/mol'), n=0.), family='H_Abstraction', template=['d', 'b'], degeneracy=3, pairs=[[methyli, methanei], [propyli, dipropyli]]) rxns = [rxn1, rxn2, rxn3, rxn4] # call method ensure_reaction_direction(rxns) for rxn in rxns: # ensure there is a methane in reactants for each reaction self.assertTrue(any([compare_isotopomers(methane, reactant) for reactant in rxn.reactants]), msg='ensureReactionDirection didnt flip the proper reactants and products') # ensure kinetics is correct if any([dipropyli.is_isomorphic(reactant) for reactant in rxn.reactants]): self.assertAlmostEqual(rxn.kinetics.A.value, 0.5, msg='The A value returned, {0}, is incorrect. ' 'Check the reactions degeneracy and how A.value is obtained. ' 'The reaction is:{1}'.format(rxn.kinetics.A.value, rxn)) else: self.assertAlmostEqual(rxn.kinetics.A.value, 1., msg='The A value returned, {0}, is incorrect. ' 'Check the reactions degeneracy and how A.value is obtained. ' 'The reaction is:{1}'.format(rxn.kinetics.A.value, rxn))
class TestArrhenius(unittest.TestCase): """ Contains unit tests of the :class:`Arrhenius` class. """ def setUp(self): """ A function run before each unit test in this class. """ self.A = 1.0e12 self.n = 0.5 self.Ea = 41.84 self.T0 = 1. self.Tmin = 300. self.Tmax = 3000. self.comment = 'C2H6' self.arrhenius = Arrhenius( A=(self.A, "cm^3/(mol*s)"), n=self.n, Ea=(self.Ea, "kJ/mol"), T0=(self.T0, "K"), Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, ) def test_A(self): """ Test that the Arrhenius A property was properly set. """ self.assertAlmostEqual(self.arrhenius.A.value_si * 1e6, self.A, delta=1e0) def test_n(self): """ Test that the Arrhenius n property was properly set. """ self.assertAlmostEqual(self.arrhenius.n.value_si, self.n, 6) def test_Ea(self): """ Test that the Arrhenius Ea property was properly set. """ self.assertAlmostEqual(self.arrhenius.Ea.value_si * 0.001, self.Ea, 6) def test_T0(self): """ Test that the Arrhenius T0 property was properly set. """ self.assertAlmostEqual(self.arrhenius.T0.value_si, self.T0, 6) def test_Tmin(self): """ Test that the Arrhenius Tmin property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmin.value_si, self.Tmin, 6) def test_Tmax(self): """ Test that the Arrhenius Tmax property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmax.value_si, self.Tmax, 6) def test_comment(self): """ Test that the Arrhenius comment property was properly set. """ self.assertEqual(self.arrhenius.comment, self.comment) def test_isTemperatureValid(self): """ Test the Arrhenius.isTemperatureValid() method. """ Tdata = numpy.array( [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]) validdata = numpy.array( [False, True, True, True, True, True, True, True, True, True], numpy.bool) for T, valid in zip(Tdata, validdata): valid0 = self.arrhenius.isTemperatureValid(T) self.assertEqual(valid0, valid) def test_getRateCoefficient(self): """ Test the Arrhenius.getRateCoefficient() method. """ Tlist = numpy.array( [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]) kexplist = numpy.array([ 1.6721e-4, 6.8770e1, 5.5803e3, 5.2448e4, 2.0632e5, 5.2285e5, 1.0281e6, 1.7225e6, 2.5912e6, 3.6123e6 ]) for T, kexp in zip(Tlist, kexplist): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-4 * kexp) def test_changeT0(self): """ Test the Arrhenius.changeT0() method. """ Tlist = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) k0list = numpy.array( [self.arrhenius.getRateCoefficient(T) for T in Tlist]) self.arrhenius.changeT0(300) self.assertEqual(self.arrhenius.T0.value_si, 300) for T, kexp in zip(Tlist, k0list): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-6 * kexp) def test_fitToData(self): """ Test the Arrhenius.fitToData() method. """ Tdata = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) kdata = numpy.array( [self.arrhenius.getRateCoefficient(T) for T in Tdata]) arrhenius = Arrhenius().fitToData(Tdata, kdata, kunits="m^3/(mol*s)") self.assertEqual(float(self.arrhenius.T0.value_si), 1) for T, k in zip(Tdata, kdata): self.assertAlmostEqual(k, arrhenius.getRateCoefficient(T), delta=1e-6 * k) self.assertAlmostEqual(arrhenius.A.value_si, self.arrhenius.A.value_si, delta=1e0) self.assertAlmostEqual(arrhenius.n.value_si, self.arrhenius.n.value_si, 1, 4) self.assertAlmostEqual(arrhenius.Ea.value_si, self.arrhenius.Ea.value_si, 2) self.assertAlmostEqual(arrhenius.T0.value_si, self.arrhenius.T0.value_si, 4) def test_pickle(self): """ Test that an Arrhenius object can be pickled and unpickled with no loss of information. """ import cPickle arrhenius = cPickle.loads(cPickle.dumps(self.arrhenius, -1)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment) def test_repr(self): """ Test that an Arrhenius object can be reconstructed from its repr() output with no loss of information. """ arrhenius = None exec('arrhenius = {0!r}'.format(self.arrhenius)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment) def test_changeRate(self): """ Test the Arrhenius.changeRate() method. """ Tlist = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) k0list = numpy.array( [self.arrhenius.getRateCoefficient(T) for T in Tlist]) self.arrhenius.changeRate(2) for T, kexp in zip(Tlist, k0list): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(2 * kexp, kact, delta=1e-6 * kexp)
class TestArrhenius(unittest.TestCase): """ Contains unit tests of the :class:`Arrhenius` class. """ def setUp(self): """ A function run before each unit test in this class. """ self.A = 1.0e12 self.n = 0.5 self.Ea = 41.84 self.T0 = 1. self.Tmin = 300. self.Tmax = 3000. self.comment = 'C2H6' self.arrhenius = Arrhenius( A = (self.A,"cm^3/(mol*s)"), n = self.n, Ea = (self.Ea,"kJ/mol"), T0 = (self.T0,"K"), Tmin = (self.Tmin,"K"), Tmax = (self.Tmax,"K"), comment = self.comment, ) def test_A(self): """ Test that the Arrhenius A property was properly set. """ self.assertAlmostEqual(self.arrhenius.A.value_si * 1e6, self.A, delta=1e0) def test_n(self): """ Test that the Arrhenius n property was properly set. """ self.assertAlmostEqual(self.arrhenius.n.value_si, self.n, 6) def test_Ea(self): """ Test that the Arrhenius Ea property was properly set. """ self.assertAlmostEqual(self.arrhenius.Ea.value_si * 0.001, self.Ea, 6) def test_T0(self): """ Test that the Arrhenius T0 property was properly set. """ self.assertAlmostEqual(self.arrhenius.T0.value_si, self.T0, 6) def test_Tmin(self): """ Test that the Arrhenius Tmin property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmin.value_si, self.Tmin, 6) def test_Tmax(self): """ Test that the Arrhenius Tmax property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmax.value_si, self.Tmax, 6) def test_comment(self): """ Test that the Arrhenius comment property was properly set. """ self.assertEqual(self.arrhenius.comment, self.comment) def test_isTemperatureValid(self): """ Test the Arrhenius.isTemperatureValid() method. """ Tdata = numpy.array([200,400,600,800,1000,1200,1400,1600,1800,2000]) validdata = numpy.array([False,True,True,True,True,True,True,True,True,True], numpy.bool) for T, valid in zip(Tdata, validdata): valid0 = self.arrhenius.isTemperatureValid(T) self.assertEqual(valid0, valid) def test_getRateCoefficient(self): """ Test the Arrhenius.getRateCoefficient() method. """ Tlist = numpy.array([200,400,600,800,1000,1200,1400,1600,1800,2000]) kexplist = numpy.array([1.6721e-4, 6.8770e1, 5.5803e3, 5.2448e4, 2.0632e5, 5.2285e5, 1.0281e6, 1.7225e6, 2.5912e6, 3.6123e6]) for T, kexp in zip(Tlist, kexplist): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-4*kexp) def test_changeT0(self): """ Test the Arrhenius.changeT0() method. """ Tlist = numpy.array([300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500]) k0list = numpy.array([self.arrhenius.getRateCoefficient(T) for T in Tlist]) self.arrhenius.changeT0(300) self.assertEqual(self.arrhenius.T0.value_si, 300) for T, kexp in zip(Tlist, k0list): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-6*kexp) def test_fitToData(self): """ Test the Arrhenius.fitToData() method. """ Tdata = numpy.array([300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500]) kdata = numpy.array([self.arrhenius.getRateCoefficient(T) for T in Tdata]) arrhenius = Arrhenius().fitToData(Tdata, kdata, kunits="m^3/(mol*s)") self.assertEqual(float(self.arrhenius.T0.value_si), 1) for T, k in zip(Tdata, kdata): self.assertAlmostEqual(k, arrhenius.getRateCoefficient(T), delta=1e-6*k) self.assertAlmostEqual(arrhenius.A.value_si, self.arrhenius.A.value_si, delta=1e0) self.assertAlmostEqual(arrhenius.n.value_si, self.arrhenius.n.value_si, 1, 4) self.assertAlmostEqual(arrhenius.Ea.value_si, self.arrhenius.Ea.value_si, 2) self.assertAlmostEqual(arrhenius.T0.value_si, self.arrhenius.T0.value_si, 4) def test_pickle(self): """ Test that an Arrhenius object can be pickled and unpickled with no loss of information. """ import cPickle arrhenius = cPickle.loads(cPickle.dumps(self.arrhenius,-1)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment) def test_repr(self): """ Test that an Arrhenius object can be reconstructed from its repr() output with no loss of information. """ arrhenius = None exec('arrhenius = {0!r}'.format(self.arrhenius)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment) def test_changeRate(self): """ Test the Arrhenius.changeRate() method. """ Tlist = numpy.array([300,400,500,600,700,800,900,1000,1100,1200,1300,1400,1500]) k0list = numpy.array([self.arrhenius.getRateCoefficient(T) for T in Tlist]) self.arrhenius.changeRate(2) for T, kexp in zip(Tlist, k0list): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(2*kexp, kact, delta=1e-6*kexp) def test_toCanteraKinetics(self): """ Test that the Arrhenius cantera object can be set properly within a cantera ElementaryReaction object """ ctArrhenius = self.arrhenius.toCanteraKinetics() self.assertAlmostEqual(ctArrhenius.pre_exponential_factor, 1e9,6) self.assertAlmostEqual(ctArrhenius.temperature_exponent, 0.5) self.assertAlmostEqual(ctArrhenius.activation_energy, 41.84e6) def test_toArrheniusEP(self): """ Tests that the Arrhenius object can be converted to ArrheniusEP """ arrRate = self.arrhenius.getRateCoefficient(500) arrEP = self.arrhenius.toArrheniusEP() arrEPRate = arrEP.getRateCoefficient(500,10) # the second number should not matter self.assertAlmostEqual(arrRate,arrEPRate) def test_toArrheniusEP_with_alpha_and_Hrxn(self): """ Tests that the Arrhenius object can be converted to ArrheniusEP given parameters """ hrxn = 5 arrRate = self.arrhenius.getRateCoefficient(500) arrEP = self.arrhenius.toArrheniusEP(alpha=1, dHrxn=hrxn) self.assertAlmostEqual(1.,arrEP.alpha.value_si) arrEPRate = arrEP.getRateCoefficient(500,hrxn) self.assertAlmostEqual(arrRate,arrEPRate) def test_toArrheniusEP_throws_error_with_just_alpha(self): with self.assertRaises(Exception): self.arrhenius.toArrheniusEP(alpha=1)
class TestPDepArrhenius(unittest.TestCase): """ Contains unit tests of the :class:`PDepArrhenius` class. """ def setUp(self): """ A function run before each unit test in this class. """ self.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""", ) self.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""", ) self.pressures = numpy.array([0.1, 10.0]) self.arrhenius = [self.arrhenius0, self.arrhenius1] self.Tmin = 300.0 self.Tmax = 2000.0 self.Pmin = 0.1 self.Pmax = 10.0 self.comment = """This data is completely made up""" self.kinetics = PDepArrhenius( pressures=(self.pressures, "bar"), arrhenius=self.arrhenius, Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), comment=self.comment, ) def test_pressures(self): """ Test that the PDepArrhenius pressures property was properly set. """ self.assertEqual(len(self.kinetics.pressures.value_si), 2) for i in range(2): self.assertAlmostEqual(self.kinetics.pressures.value_si[i] * 1e-5, self.pressures[i], 4) def test_arrhenius(self): """ Test that the PDepArrhenius arrhenius property was properly set. """ self.assertEqual(len(self.kinetics.arrhenius), 2) for i in range(2): self.assertAlmostEqual(self.kinetics.arrhenius[i].A.value, self.arrhenius[i].A.value, delta=1e0) self.assertEqual(self.kinetics.arrhenius[i].A.units, self.arrhenius[i].A.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].n.value, self.arrhenius[i].n.value, 4) self.assertAlmostEqual(self.kinetics.arrhenius[i].Ea.value, self.arrhenius[i].Ea.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Ea.units, self.arrhenius[i].Ea.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].T0.value, self.arrhenius[i].T0.value, 4) self.assertEqual(self.kinetics.arrhenius[i].T0.units, self.arrhenius[i].T0.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Tmin.value, self.arrhenius[i].Tmin.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Tmin.units, self.arrhenius[i].Tmin.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Tmax.value, self.arrhenius[i].Tmax.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Tmax.units, self.arrhenius[i].Tmax.units) self.assertEqual(self.kinetics.arrhenius[i].comment, self.arrhenius[i].comment) def test_Tmin(self): """ Test that the PDepArrhenius Tmin property was properly set. """ self.assertAlmostEqual(self.kinetics.Tmin.value_si, self.Tmin, 6) def test_Tmax(self): """ Test that the PDepArrhenius Tmax property was properly set. """ self.assertAlmostEqual(self.kinetics.Tmax.value_si, self.Tmax, 6) def test_Pmin(self): """ Test that the PDepArrhenius Pmin property was properly set. """ self.assertAlmostEqual(self.kinetics.Pmin.value_si * 1e-5, self.Pmin, 6) def test_Pmax(self): """ Test that the PDepArrhenius Pmax property was properly set. """ self.assertAlmostEqual(self.kinetics.Pmax.value_si * 1e-5, self.Pmax, 6) def test_comment(self): """ Test that the PDepArrhenius comment property was properly set. """ self.assertEqual(self.kinetics.comment, self.comment) def test_isPressureDependent(self): """ Test the PDepArrhenius.isPressureDependent() method. """ self.assertTrue(self.kinetics.isPressureDependent()) def test_getRateCoefficient(self): """ Test the PDepArrhenius.getRateCoefficient() method. """ P = 1e4 for T in [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500]: k0 = self.kinetics.getRateCoefficient(T, P) k1 = self.arrhenius0.getRateCoefficient(T) self.assertAlmostEqual(k0, k1, delta=1e-6 * k1) P = 1e6 for T in [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500]: k0 = self.kinetics.getRateCoefficient(T, P) k1 = self.arrhenius1.getRateCoefficient(T) self.assertAlmostEqual(k0, k1, delta=1e-6 * k1) P = 1e5 for T in [300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500]: k0 = self.kinetics.getRateCoefficient(T, P) k1 = math.sqrt(self.arrhenius0.getRateCoefficient(T) * self.arrhenius1.getRateCoefficient(T)) self.assertAlmostEqual(k0, k1, delta=1e-6 * k1) def test_fitToData(self): """ Test the PDepArrhenius.fitToData() method. """ Tdata = numpy.array([300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500], numpy.float) Pdata = numpy.array([1e4, 3e4, 1e5, 3e5, 1e6], numpy.float) kdata = numpy.zeros([len(Tdata), len(Pdata)], numpy.float) for t in range(len(Tdata)): for p in range(len(Pdata)): kdata[t, p] = self.kinetics.getRateCoefficient(Tdata[t], Pdata[p]) kinetics = PDepArrhenius().fitToData(Tdata, Pdata, kdata, kunits="s^-1") for t in range(len(Tdata)): for p in range(len(Pdata)): self.assertAlmostEqual( kinetics.getRateCoefficient(Tdata[t], Pdata[p]), kdata[t, p], delta=1e-6 * kdata[t, p] ) def test_pickle(self): """ Test that a PDepArrhenius object can be successfully pickled and unpickled with no loss of information. """ import cPickle kinetics = cPickle.loads(cPickle.dumps(self.kinetics)) Narrh = 2 self.assertEqual(len(self.kinetics.pressures.value), Narrh) self.assertEqual(len(kinetics.pressures.value), Narrh) self.assertEqual(len(self.kinetics.arrhenius), Narrh) self.assertEqual(len(kinetics.arrhenius), Narrh) for i in range(Narrh): self.assertAlmostEqual(self.kinetics.pressures.value[i], kinetics.pressures.value[i], 4) self.assertAlmostEqual(self.kinetics.arrhenius[i].A.value, kinetics.arrhenius[i].A.value, delta=1e0) self.assertEqual(self.kinetics.arrhenius[i].A.units, kinetics.arrhenius[i].A.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].n.value, kinetics.arrhenius[i].n.value) self.assertAlmostEqual(self.kinetics.arrhenius[i].T0.value, kinetics.arrhenius[i].T0.value, 4) self.assertEqual(self.kinetics.arrhenius[i].T0.units, kinetics.arrhenius[i].T0.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Ea.value, kinetics.arrhenius[i].Ea.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Ea.units, kinetics.arrhenius[i].Ea.units) self.assertAlmostEqual(self.kinetics.Tmin.value, kinetics.Tmin.value, 4) self.assertEqual(self.kinetics.Tmin.units, kinetics.Tmin.units) self.assertAlmostEqual(self.kinetics.Tmax.value, kinetics.Tmax.value, 4) self.assertEqual(self.kinetics.Tmax.units, kinetics.Tmax.units) self.assertAlmostEqual(self.kinetics.Pmin.value, kinetics.Pmin.value, 4) self.assertEqual(self.kinetics.Pmin.units, kinetics.Pmin.units) self.assertAlmostEqual(self.kinetics.Pmax.value, kinetics.Pmax.value, 4) self.assertEqual(self.kinetics.Pmax.units, kinetics.Pmax.units) self.assertEqual(self.kinetics.comment, kinetics.comment) def test_repr(self): """ Test that a PDepArrhenius object can be successfully reconstructed from its repr() output with no loss of information. """ kinetics = None exec("kinetics = {0!r}".format(self.kinetics)) Narrh = 2 self.assertEqual(len(self.kinetics.pressures.value), Narrh) self.assertEqual(len(kinetics.pressures.value), Narrh) self.assertEqual(len(self.kinetics.arrhenius), Narrh) self.assertEqual(len(kinetics.arrhenius), Narrh) for i in range(Narrh): self.assertAlmostEqual(self.kinetics.pressures.value[i], kinetics.pressures.value[i], 4) self.assertAlmostEqual(self.kinetics.arrhenius[i].A.value, kinetics.arrhenius[i].A.value, delta=1e0) self.assertEqual(self.kinetics.arrhenius[i].A.units, kinetics.arrhenius[i].A.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].n.value, kinetics.arrhenius[i].n.value) self.assertAlmostEqual(self.kinetics.arrhenius[i].T0.value, kinetics.arrhenius[i].T0.value, 4) self.assertEqual(self.kinetics.arrhenius[i].T0.units, kinetics.arrhenius[i].T0.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Ea.value, kinetics.arrhenius[i].Ea.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Ea.units, kinetics.arrhenius[i].Ea.units) self.assertAlmostEqual(self.kinetics.Tmin.value, kinetics.Tmin.value, 4) self.assertEqual(self.kinetics.Tmin.units, kinetics.Tmin.units) self.assertAlmostEqual(self.kinetics.Tmax.value, kinetics.Tmax.value, 4) self.assertEqual(self.kinetics.Tmax.units, kinetics.Tmax.units) self.assertAlmostEqual(self.kinetics.Pmin.value, kinetics.Pmin.value, 4) self.assertEqual(self.kinetics.Pmin.units, kinetics.Pmin.units) self.assertAlmostEqual(self.kinetics.Pmax.value, kinetics.Pmax.value, 4) self.assertEqual(self.kinetics.Pmax.units, kinetics.Pmax.units) self.assertEqual(self.kinetics.comment, kinetics.comment)
def write_output(self, output_directory): """ Save the results of the kinetics job to the `output.py` file located in `output_directory`. """ reaction = self.reaction ks, k0s, k0_revs, k_revs = [], [], [], [] logging.info('Saving kinetics for {0}...'.format(reaction)) order = len(self.reaction.reactants) factor = 1e6**(order - 1) f = open(os.path.join(output_directory, 'output.py'), 'a') if self.usedTST: # If TST is not used, eg. it was given in 'reaction', then this will throw an error. f.write( '# ======= =========== =========== =========== ===============\n' ) f.write('# Temp. k (TST) Tunneling k (TST+T) Units\n') f.write( '# ======= =========== =========== =========== ===============\n' ) if self.Tlist is None: t_list = np.array([300, 400, 500, 600, 800, 1000, 1500, 2000]) else: t_list = self.Tlist.value_si for T in t_list: tunneling = reaction.transition_state.tunneling reaction.transition_state.tunneling = None try: k0 = reaction.calculate_tst_rate_coefficient(T) * factor except SpeciesError: k0 = 0 reaction.transition_state.tunneling = tunneling try: k = reaction.calculate_tst_rate_coefficient(T) * factor kappa = k / k0 except (SpeciesError, ZeroDivisionError): k = reaction.get_rate_coefficient(T) kappa = 0 logging.info( "The species in reaction {0} do not have adequate information for TST, " "using default kinetics values.".format(reaction)) tunneling = reaction.transition_state.tunneling ks.append(k) k0s.append(k0) f.write( '# {0:4g} K {1:11.3e} {2:11g} {3:11.3e} {4}\n'.format( T, k0, kappa, k, self.k_units)) f.write( '# ======= =========== =========== =========== ===============\n' ) f.write('\n\n') f.write( '# ======= ============ =========== ============ ============= =========\n' ) f.write( '# Temp. Kc (eq) Units k_rev (TST) k_rev (TST+T) Units\n' ) f.write( '# ======= ============ =========== ============ ============= =========\n' ) # Initialize Object for Converting Units if self.K_eq_units != ' ': keq_unit_converter = quantity.Units( self.K_eq_units).get_conversion_factor_from_si() else: keq_unit_converter = 1 for n, T in enumerate(t_list): k = ks[n] k0 = k0s[n] K_eq = keq_unit_converter * reaction.get_equilibrium_constant( T) # returns SI units k0_rev = k0 / K_eq k_rev = k / K_eq k0_revs.append(k0_rev) k_revs.append(k_rev) f.write( '# {0:4g} K {1:11.3e} {2} {3:11.3e} {4:11.3e} {5}\n' .format(T, K_eq, self.K_eq_units, k0_rev, k_rev, self.k_r_units)) f.write( '# ======= ============ =========== ============ ============= =========\n' ) f.write('\n\n') kinetics_0_rev = Arrhenius().fit_to_data(t_list, np.array(k0_revs), kunits=self.k_r_units) kinetics_rev = Arrhenius().fit_to_data(t_list, np.array(k_revs), kunits=self.k_r_units) f.write('# k_rev (TST) = {0} \n'.format(kinetics_0_rev)) f.write('# k_rev (TST+T) = {0} \n\n'.format(kinetics_rev)) # Reaction path degeneracy is INCLUDED in the kinetics itself! rxn_str = 'kinetics(label={0!r}, kinetics={1!r})'.format( reaction.label, reaction.kinetics) f.write('{0}\n\n'.format(prettify(rxn_str))) f.close()
class TestArrhenius(unittest.TestCase): """ Contains unit tests of the :class:`Arrhenius` class. """ def setUp(self): """ A function run before each unit test in this class. """ self.A = 1.0e12 self.n = 0.5 self.Ea = 41.84 self.T0 = 1. self.Tmin = 300. self.Tmax = 3000. self.comment = 'C2H6' self.arrhenius = Arrhenius( A=(self.A, "cm^3/(mol*s)"), n=self.n, Ea=(self.Ea, "kJ/mol"), T0=(self.T0, "K"), Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, ) def test_A(self): """ Test that the Arrhenius A property was properly set. """ self.assertAlmostEqual(self.arrhenius.A.value_si * 1e6, self.A, delta=1e0) def test_n(self): """ Test that the Arrhenius n property was properly set. """ self.assertAlmostEqual(self.arrhenius.n.value_si, self.n, 6) def test_Ea(self): """ Test that the Arrhenius Ea property was properly set. """ self.assertAlmostEqual(self.arrhenius.Ea.value_si * 0.001, self.Ea, 6) def test_T0(self): """ Test that the Arrhenius T0 property was properly set. """ self.assertAlmostEqual(self.arrhenius.T0.value_si, self.T0, 6) def test_Tmin(self): """ Test that the Arrhenius Tmin property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmin.value_si, self.Tmin, 6) def test_Tmax(self): """ Test that the Arrhenius Tmax property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmax.value_si, self.Tmax, 6) def test_comment(self): """ Test that the Arrhenius comment property was properly set. """ self.assertEqual(self.arrhenius.comment, self.comment) def test_isTemperatureValid(self): """ Test the Arrhenius.isTemperatureValid() method. """ Tdata = numpy.array( [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]) validdata = numpy.array( [False, True, True, True, True, True, True, True, True, True], numpy.bool) for T, valid in zip(Tdata, validdata): valid0 = self.arrhenius.isTemperatureValid(T) self.assertEqual(valid0, valid) def test_getRateCoefficient(self): """ Test the Arrhenius.getRateCoefficient() method. """ Tlist = numpy.array( [200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]) kexplist = numpy.array([ 1.6721e-4, 6.8770e1, 5.5803e3, 5.2448e4, 2.0632e5, 5.2285e5, 1.0281e6, 1.7225e6, 2.5912e6, 3.6123e6 ]) for T, kexp in zip(Tlist, kexplist): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-4 * kexp) def test_changeT0(self): """ Test the Arrhenius.changeT0() method. """ Tlist = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) k0list = numpy.array( [self.arrhenius.getRateCoefficient(T) for T in Tlist]) self.arrhenius.changeT0(300) self.assertEqual(self.arrhenius.T0.value_si, 300) for T, kexp in zip(Tlist, k0list): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-6 * kexp) def test_fitToData(self): """ Test the Arrhenius.fitToData() method. """ Tdata = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) kdata = numpy.array( [self.arrhenius.getRateCoefficient(T) for T in Tdata]) arrhenius = Arrhenius().fitToData(Tdata, kdata, kunits="m^3/(mol*s)") self.assertEqual(float(self.arrhenius.T0.value_si), 1) for T, k in zip(Tdata, kdata): self.assertAlmostEqual(k, arrhenius.getRateCoefficient(T), delta=1e-6 * k) self.assertAlmostEqual(arrhenius.A.value_si, self.arrhenius.A.value_si, delta=1e0) self.assertAlmostEqual(arrhenius.n.value_si, self.arrhenius.n.value_si, 1, 4) self.assertAlmostEqual(arrhenius.Ea.value_si, self.arrhenius.Ea.value_si, 2) self.assertAlmostEqual(arrhenius.T0.value_si, self.arrhenius.T0.value_si, 4) def test_pickle(self): """ Test that an Arrhenius object can be pickled and unpickled with no loss of information. """ import cPickle arrhenius = cPickle.loads(cPickle.dumps(self.arrhenius, -1)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment) def test_repr(self): """ Test that an Arrhenius object can be reconstructed from its repr() output with no loss of information. """ arrhenius = None exec('arrhenius = {0!r}'.format(self.arrhenius)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment) def test_changeRate(self): """ Test the Arrhenius.changeRate() method. """ Tlist = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) k0list = numpy.array( [self.arrhenius.getRateCoefficient(T) for T in Tlist]) self.arrhenius.changeRate(2) for T, kexp in zip(Tlist, k0list): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(2 * kexp, kact, delta=1e-6 * kexp) def test_toCanteraKinetics(self): """ Test that the Arrhenius cantera object can be set properly within a cantera ElementaryReaction object """ ctArrhenius = self.arrhenius.toCanteraKinetics() self.assertAlmostEqual(ctArrhenius.pre_exponential_factor, 1e9, 6) self.assertAlmostEqual(ctArrhenius.temperature_exponent, 0.5) self.assertAlmostEqual(ctArrhenius.activation_energy, 41.84e6) def test_toArrheniusEP(self): """ Tests that the Arrhenius object can be converted to ArrheniusEP """ arrRate = self.arrhenius.getRateCoefficient(500) arrEP = self.arrhenius.toArrheniusEP() arrEPRate = arrEP.getRateCoefficient( 500, 10) # the second number should not matter self.assertAlmostEqual(arrRate, arrEPRate) def test_toArrheniusEP_with_alpha_and_Hrxn(self): """ Tests that the Arrhenius object can be converted to ArrheniusEP given parameters """ hrxn = 5 arrRate = self.arrhenius.getRateCoefficient(500) arrEP = self.arrhenius.toArrheniusEP(alpha=1, dHrxn=hrxn) self.assertAlmostEqual(1., arrEP.alpha.value_si) arrEPRate = arrEP.getRateCoefficient(500, hrxn) self.assertAlmostEqual(arrRate, arrEPRate) def test_toArrheniusEP_throws_error_with_just_alpha(self): with self.assertRaises(Exception): self.arrhenius.toArrheniusEP(alpha=1)
class TestPDepArrhenius(unittest.TestCase): """ Contains unit tests of the :class:`PDepArrhenius` class. """ def setUp(self): """ A function run before each unit test in this class. """ self.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""", ) self.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""", ) self.pressures = numpy.array([0.1, 10.0]) self.arrhenius = [self.arrhenius0, self.arrhenius1] self.Tmin = 300.0 self.Tmax = 2000.0 self.Pmin = 0.1 self.Pmax = 10.0 self.comment = """This data is completely made up""" self.kinetics = PDepArrhenius( pressures=(self.pressures, "bar"), arrhenius=self.arrhenius, Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), comment=self.comment, ) def test_pressures(self): """ Test that the PDepArrhenius pressures property was properly set. """ self.assertEqual(len(self.kinetics.pressures.value_si), 2) for i in range(2): self.assertAlmostEqual(self.kinetics.pressures.value_si[i] * 1e-5, self.pressures[i], 4) def test_arrhenius(self): """ Test that the PDepArrhenius arrhenius property was properly set. """ self.assertEqual(len(self.kinetics.arrhenius), 2) for i in range(2): self.assertAlmostEqual(self.kinetics.arrhenius[i].A.value, self.arrhenius[i].A.value, delta=1e0) self.assertEqual(self.kinetics.arrhenius[i].A.units, self.arrhenius[i].A.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].n.value, self.arrhenius[i].n.value, 4) self.assertAlmostEqual(self.kinetics.arrhenius[i].Ea.value, self.arrhenius[i].Ea.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Ea.units, self.arrhenius[i].Ea.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].T0.value, self.arrhenius[i].T0.value, 4) self.assertEqual(self.kinetics.arrhenius[i].T0.units, self.arrhenius[i].T0.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Tmin.value, self.arrhenius[i].Tmin.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Tmin.units, self.arrhenius[i].Tmin.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Tmax.value, self.arrhenius[i].Tmax.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Tmax.units, self.arrhenius[i].Tmax.units) self.assertEqual(self.kinetics.arrhenius[i].comment, self.arrhenius[i].comment) def test_Tmin(self): """ Test that the PDepArrhenius Tmin property was properly set. """ self.assertAlmostEqual(self.kinetics.Tmin.value_si, self.Tmin, 6) def test_Tmax(self): """ Test that the PDepArrhenius Tmax property was properly set. """ self.assertAlmostEqual(self.kinetics.Tmax.value_si, self.Tmax, 6) def test_Pmin(self): """ Test that the PDepArrhenius Pmin property was properly set. """ self.assertAlmostEqual(self.kinetics.Pmin.value_si * 1e-5, self.Pmin, 6) def test_Pmax(self): """ Test that the PDepArrhenius Pmax property was properly set. """ self.assertAlmostEqual(self.kinetics.Pmax.value_si * 1e-5, self.Pmax, 6) def test_comment(self): """ Test that the PDepArrhenius comment property was properly set. """ self.assertEqual(self.kinetics.comment, self.comment) def test_isPressureDependent(self): """ Test the PDepArrhenius.isPressureDependent() method. """ self.assertTrue(self.kinetics.isPressureDependent()) def test_getRateCoefficient(self): """ Test the PDepArrhenius.getRateCoefficient() method. """ P = 1e4 for T in [ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]: k0 = self.kinetics.getRateCoefficient(T, P) k1 = self.arrhenius0.getRateCoefficient(T) self.assertAlmostEqual(k0, k1, delta=1e-6 * k1) P = 1e6 for T in [ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]: k0 = self.kinetics.getRateCoefficient(T, P) k1 = self.arrhenius1.getRateCoefficient(T) self.assertAlmostEqual(k0, k1, delta=1e-6 * k1) P = 1e5 for T in [ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]: k0 = self.kinetics.getRateCoefficient(T, P) k1 = math.sqrt( self.arrhenius0.getRateCoefficient(T) * self.arrhenius1.getRateCoefficient(T)) self.assertAlmostEqual(k0, k1, delta=1e-6 * k1) def test_fitToData(self): """ Test the PDepArrhenius.fitToData() method. """ Tdata = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ], numpy.float) Pdata = numpy.array([1e4, 3e4, 1e5, 3e5, 1e6], numpy.float) kdata = numpy.zeros([len(Tdata), len(Pdata)], numpy.float) for t in range(len(Tdata)): for p in range(len(Pdata)): kdata[t, p] = self.kinetics.getRateCoefficient( Tdata[t], Pdata[p]) kinetics = PDepArrhenius().fitToData(Tdata, Pdata, kdata, kunits="s^-1") for t in range(len(Tdata)): for p in range(len(Pdata)): self.assertAlmostEqual(kinetics.getRateCoefficient( Tdata[t], Pdata[p]), kdata[t, p], delta=1e-6 * kdata[t, p]) def test_pickle(self): """ Test that a PDepArrhenius object can be successfully pickled and unpickled with no loss of information. """ import cPickle kinetics = cPickle.loads(cPickle.dumps(self.kinetics, -1)) Narrh = 2 self.assertEqual(len(self.kinetics.pressures.value), Narrh) self.assertEqual(len(kinetics.pressures.value), Narrh) self.assertEqual(len(self.kinetics.arrhenius), Narrh) self.assertEqual(len(kinetics.arrhenius), Narrh) for i in range(Narrh): self.assertAlmostEqual(self.kinetics.pressures.value[i], kinetics.pressures.value[i], 4) self.assertAlmostEqual(self.kinetics.arrhenius[i].A.value, kinetics.arrhenius[i].A.value, delta=1e0) self.assertEqual(self.kinetics.arrhenius[i].A.units, kinetics.arrhenius[i].A.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].n.value, kinetics.arrhenius[i].n.value) self.assertAlmostEqual(self.kinetics.arrhenius[i].T0.value, kinetics.arrhenius[i].T0.value, 4) self.assertEqual(self.kinetics.arrhenius[i].T0.units, kinetics.arrhenius[i].T0.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Ea.value, kinetics.arrhenius[i].Ea.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Ea.units, kinetics.arrhenius[i].Ea.units) self.assertAlmostEqual(self.kinetics.Tmin.value, kinetics.Tmin.value, 4) self.assertEqual(self.kinetics.Tmin.units, kinetics.Tmin.units) self.assertAlmostEqual(self.kinetics.Tmax.value, kinetics.Tmax.value, 4) self.assertEqual(self.kinetics.Tmax.units, kinetics.Tmax.units) self.assertAlmostEqual(self.kinetics.Pmin.value, kinetics.Pmin.value, 4) self.assertEqual(self.kinetics.Pmin.units, kinetics.Pmin.units) self.assertAlmostEqual(self.kinetics.Pmax.value, kinetics.Pmax.value, 4) self.assertEqual(self.kinetics.Pmax.units, kinetics.Pmax.units) self.assertEqual(self.kinetics.comment, kinetics.comment) def test_repr(self): """ Test that a PDepArrhenius object can be successfully reconstructed from its repr() output with no loss of information. """ kinetics = None exec('kinetics = {0!r}'.format(self.kinetics)) Narrh = 2 self.assertEqual(len(self.kinetics.pressures.value), Narrh) self.assertEqual(len(kinetics.pressures.value), Narrh) self.assertEqual(len(self.kinetics.arrhenius), Narrh) self.assertEqual(len(kinetics.arrhenius), Narrh) for i in range(Narrh): self.assertAlmostEqual(self.kinetics.pressures.value[i], kinetics.pressures.value[i], 4) self.assertAlmostEqual(self.kinetics.arrhenius[i].A.value, kinetics.arrhenius[i].A.value, delta=1e0) self.assertEqual(self.kinetics.arrhenius[i].A.units, kinetics.arrhenius[i].A.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].n.value, kinetics.arrhenius[i].n.value) self.assertAlmostEqual(self.kinetics.arrhenius[i].T0.value, kinetics.arrhenius[i].T0.value, 4) self.assertEqual(self.kinetics.arrhenius[i].T0.units, kinetics.arrhenius[i].T0.units) self.assertAlmostEqual(self.kinetics.arrhenius[i].Ea.value, kinetics.arrhenius[i].Ea.value, 4) self.assertEqual(self.kinetics.arrhenius[i].Ea.units, kinetics.arrhenius[i].Ea.units) self.assertAlmostEqual(self.kinetics.Tmin.value, kinetics.Tmin.value, 4) self.assertEqual(self.kinetics.Tmin.units, kinetics.Tmin.units) self.assertAlmostEqual(self.kinetics.Tmax.value, kinetics.Tmax.value, 4) self.assertEqual(self.kinetics.Tmax.units, kinetics.Tmax.units) self.assertAlmostEqual(self.kinetics.Pmin.value, kinetics.Pmin.value, 4) self.assertEqual(self.kinetics.Pmin.units, kinetics.Pmin.units) self.assertAlmostEqual(self.kinetics.Pmax.value, kinetics.Pmax.value, 4) self.assertEqual(self.kinetics.Pmax.units, kinetics.Pmax.units) self.assertEqual(self.kinetics.comment, kinetics.comment) def test_changeRate(self): """ Test the PDepArrhenius.changeRate() method. """ Tlist = numpy.array([ 300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500 ]) k0list = numpy.array( [self.kinetics.getRateCoefficient(T, 1e5) for T in Tlist]) self.kinetics.changeRate(2) for T, kexp in zip(Tlist, k0list): kact = self.kinetics.getRateCoefficient(T, 1e5) self.assertAlmostEqual(2 * kexp, kact, delta=1e-6 * kexp)
def setUp(self): """ A method that is run before each unit test in this class. """ self.nC4H10O = Species( label='n-C4H10O', conformer=Conformer( E0=(-317.807, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(74.07, "g/mol")), NonlinearRotor(inertia=([41.5091, 215.751, 233.258], "amu*angstrom^2"), symmetry=1), HarmonicOscillator(frequencies=([ 240.915, 341.933, 500.066, 728.41, 809.987, 833.93, 926.308, 948.571, 1009.3, 1031.46, 1076, 1118.4, 1184.66, 1251.36, 1314.36, 1321.42, 1381.17, 1396.5, 1400.54, 1448.08, 1480.18, 1485.34, 1492.24, 1494.99, 1586.16, 2949.01, 2963.03, 2986.19, 2988.1, 2995.27, 3026.03, 3049.05, 3053.47, 3054.83, 3778.88 ], "cm^-1")), HinderedRotor(inertia=(0.854054, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.25183, -1.37378, -2.8379, 0.0305112, 0.0028088 ], [ 0.458307, 0.542121, -0.599366, -0.00283925, 0.0398529 ]], "kJ/mol")), HinderedRotor( inertia=(8.79408, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.26871, -0.59533, -8.15002, -0.294325, -0.145357 ], [1.1884, 0.99479, -0.940416, -0.186538, 0.0309834]], "kJ/mol")), HinderedRotor(inertia=(7.88153, "amu*angstrom^2"), symmetry=1, fourier=([[ -4.67373, 2.03735, -6.25993, -0.27325, -0.048748 ], [ -0.982845, 1.76637, -1.57619, 0.474364, -0.000681718 ]], "kJ/mol")), HinderedRotor(inertia=(2.81525, "amu*angstrom^2"), symmetry=3, barrier=(2.96807, "kcal/mol")), ], spin_multiplicity=1, optical_isomers=1, ), molecular_weight=(74.07, "g/mol"), transport_data=TransportData(sigma=(5.94, 'angstrom'), epsilon=(559, 'K')), energy_transfer_model=SingleExponentialDown( alpha0=(447.5 * 0.011962, "kJ/mol"), T0=(300, "K"), n=0.85), ) self.nC4H10O.from_smiles('CCCCO') self.nC4H8 = Species( label='n-C4H8', conformer=Conformer( E0=(-17.8832, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(56.06, "g/mol")), NonlinearRotor(inertia=([22.2748, 122.4, 125.198], "amu*angstrom^2"), symmetry=1), HarmonicOscillator(frequencies=([ 308.537, 418.67, 636.246, 788.665, 848.906, 936.762, 979.97, 1009.48, 1024.22, 1082.96, 1186.38, 1277.55, 1307.65, 1332.87, 1396.67, 1439.09, 1469.71, 1484.45, 1493.19, 1691.49, 2972.12, 2994.31, 3018.48, 3056.87, 3062.76, 3079.38, 3093.54, 3174.52 ], "cm^-1")), HinderedRotor(inertia=(5.28338, "amu*angstrom^2"), symmetry=1, fourier=([[ -0.579364, -0.28241, -4.46469, 0.143368, 0.126756 ], [ 1.01804, -0.494628, -0.00318651, -0.245289, 0.193728 ]], "kJ/mol")), HinderedRotor( inertia=(2.60818, "amu*angstrom^2"), symmetry=3, fourier=([[ 0.0400372, 0.0301986, -6.4787, -0.0248675, -0.0324753 ], [0.0312541, 0.0538, -0.493785, 0.0965968, 0.125292]], "kJ/mol")), ], spin_multiplicity=1, optical_isomers=1, ), ) self.nC4H8.from_smiles('CCC=C') self.H2O = Species( label='H2O', conformer=Conformer( E0=(-269.598, 'kJ/mol'), modes=[ IdealGasTranslation(mass=(18.01, "g/mol")), NonlinearRotor(inertia=([0.630578, 1.15529, 1.78586], "amu*angstrom^2"), symmetry=2), HarmonicOscillator( frequencies=([1622.09, 3771.85, 3867.85], "cm^-1")), ], spin_multiplicity=1, optical_isomers=1, ), ) self.H2O.from_smiles('O') self.N2 = Species( label='N2', molecular_weight=(28.04, "g/mol"), transport_data=TransportData(sigma=(3.41, "angstrom"), epsilon=(124, "K")), energy_transfer_model=None, ) self.N2.from_smiles('N#N') logging.error('to TS') self.TS = TransitionState( label='TS', conformer=Conformer( E0=(-42.4373, "kJ/mol"), modes=[ IdealGasTranslation(mass=(74.07, "g/mol")), NonlinearRotor(inertia=([40.518, 232.666, 246.092], "u*angstrom**2"), symmetry=1, quantum=False), HarmonicOscillator(frequencies=([ 134.289, 302.326, 351.792, 407.986, 443.419, 583.988, 699.001, 766.1, 777.969, 829.671, 949.753, 994.731, 1013.59, 1073.98, 1103.79, 1171.89, 1225.91, 1280.67, 1335.08, 1373.9, 1392.32, 1417.43, 1469.51, 1481.61, 1490.16, 1503.73, 1573.16, 2972.85, 2984.3, 3003.67, 3045.78, 3051.77, 3082.37, 3090.44, 3190.73, 3708.52 ], "kayser")), HinderedRotor(inertia=(2.68206, "amu*angstrom^2"), symmetry=3, barrier=(3.35244, "kcal/mol")), HinderedRotor(inertia=(9.77669, "amu*angstrom^2"), symmetry=1, fourier=([[ 0.208938, -1.55291, -4.05398, -0.105798, -0.104752 ], [ 2.00518, -0.020767, -0.333595, 0.137791, -0.274578 ]], "kJ/mol")), ], spin_multiplicity=1, optical_isomers=1, ), frequency=(-2038.34, 'cm^-1'), ) self.reaction = Reaction(label='dehydration', reactants=[self.nC4H10O], products=[self.nC4H8, self.H2O], transition_state=self.TS, kinetics=Arrhenius(A=(0.0387, 'm^3/(mol*s)'), n=2.7, Ea=(2.6192e4, 'J/mol'), T0=(1, 'K'))) self.network = Network( label='n-butanol', isomers=[Configuration(self.nC4H10O)], reactants=[], products=[Configuration(self.nC4H8, self.H2O)], path_reactions=[self.reaction], bath_gas={self.N2: 1.0}, ) self.pdepnetwork = deepcopy(self.network) self.pdepnetwork.__class__ = PDepNetwork self.pdepnetwork.source = [self.pdepnetwork.isomers[0].species[0]] self.pdepnetwork.index = 1 self.pdepnetwork.explored = []
def test_process_duplicate_reactions(self): """ Test that duplicate reactions are handled correctly when loading a Chemkin file. """ s1 = Species().from_smiles('CC') s2 = Species().from_smiles('[CH3]') s3 = Species().from_smiles('[OH]') s4 = Species().from_smiles('C[CH2]') s5 = Species().from_smiles('O') r1 = Reaction(reactants=[s1], products=[s2, s2], duplicate=False, kinetics=Arrhenius()) r2 = Reaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Arrhenius()) r3 = Reaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Arrhenius()) r4 = Reaction(reactants=[s1, s3], products=[s4, s5], duplicate=False, kinetics=Arrhenius()) r5 = LibraryReaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Arrhenius(), library='lib1') r6 = LibraryReaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Arrhenius(), library='lib2') r7 = LibraryReaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Chebyshev(), library='lib1') r8 = LibraryReaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Arrhenius(), library='lib1') r9 = LibraryReaction( reactants=[s1, s3], products=[s4, s5], duplicate=False, kinetics=MultiArrhenius( arrhenius=[Arrhenius(), Arrhenius()]), library='lib1') reaction_list_with_duplicate = [r1, r2, r3] reaction_list_with_duplicate2 = [r1, r2, r3] reaction_list_unmarked_duplicate = [r1, r2, r4] reaction_list_unequal_libraries = [r1, r5, r6] reaction_list_mixed_kinetics = [r1, r5, r7] reaction_list_mergeable = [r1, r5, r8] reaction_list_merged = [r1, r9] # Test that duplicates are not removed for non-library reactions _process_duplicate_reactions(reaction_list_with_duplicate) self.assertEqual(reaction_list_with_duplicate, reaction_list_with_duplicate2) # Test that unmarked duplicate reactions are detected if both # reactions are p-dep or p-indep self.assertRaisesRegexp(ChemkinError, 'Encountered unmarked duplicate reaction', _process_duplicate_reactions, reaction_list_unmarked_duplicate) # Test that unequal libraries are recognized self.assertRaisesRegexp(ChemkinError, 'from different libraries', _process_duplicate_reactions, reaction_list_unequal_libraries) # Test that an error is raised for reactions with kinetics # that cannot be merged self.assertRaisesRegexp(ChemkinError, 'Mixed kinetics for duplicate reaction', _process_duplicate_reactions, reaction_list_mixed_kinetics) # Test that duplicate library reactions are merged successfully _process_duplicate_reactions(reaction_list_mergeable) self.assertEqual(len(reaction_list_mergeable), len(reaction_list_merged)) self.assertEqual(reaction_list_mergeable[0], reaction_list_merged[0]) rtest = reaction_list_mergeable[1] rtrue = reaction_list_merged[1] self.assertEqual(rtest.reactants, rtrue.reactants) self.assertEqual(rtest.products, rtrue.products) self.assertEqual(rtest.duplicate, rtrue.duplicate) self.assertEqual(rtest.library, rtrue.library) self.assertTrue(isinstance(rtest.kinetics, MultiArrhenius)) self.assertTrue( all(isinstance(k, Arrhenius) for k in rtest.kinetics.arrhenius))
def test_mark_duplicate_reactions(self): """Test that we can properly mark duplicate reactions for Chemkin.""" s1 = Species().from_smiles('CC') s2 = Species().from_smiles('[CH3]') s3 = Species().from_smiles('[OH]') s4 = Species().from_smiles('C[CH2]') s5 = Species().from_smiles('O') s6 = Species().from_smiles('[H]') # Try initializing with duplicate=False reaction_list = [ Reaction(reactants=[s1], products=[s2, s2], duplicate=False, kinetics=Arrhenius()), Reaction(reactants=[s1], products=[s2, s2], duplicate=False, kinetics=Arrhenius()), Reaction(reactants=[s1, s3], products=[s4, s5], duplicate=False, kinetics=Arrhenius()), Reaction(reactants=[s1, s3], products=[s4, s5], duplicate=False, kinetics=Chebyshev()), Reaction(reactants=[s1], products=[s4, s6], duplicate=False, kinetics=Arrhenius(), reversible=False), Reaction(reactants=[s1], products=[s4, s6], duplicate=False, kinetics=Arrhenius(), reversible=False), Reaction(reactants=[s5], products=[s3, s6], duplicate=False, kinetics=Arrhenius(), reversible=False), Reaction(reactants=[s3, s6], products=[s5], duplicate=False, kinetics=Arrhenius(), reversible=False), ] expected_flags = [True, True, False, False, True, True, False, False] mark_duplicate_reactions(reaction_list) duplicate_flags = [rxn.duplicate for rxn in reaction_list] self.assertEqual(duplicate_flags, expected_flags) # Try initializing with duplicate=True reaction_list = [ Reaction(reactants=[s1], products=[s2, s2], duplicate=True, kinetics=Arrhenius()), Reaction(reactants=[s1], products=[s2, s2], duplicate=True, kinetics=Arrhenius()), Reaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Arrhenius()), Reaction(reactants=[s1, s3], products=[s4, s5], duplicate=True, kinetics=Chebyshev()), Reaction(reactants=[s1], products=[s4, s6], duplicate=True, kinetics=Arrhenius(), reversible=False), Reaction(reactants=[s1], products=[s4, s6], duplicate=True, kinetics=Arrhenius(), reversible=False), Reaction(reactants=[s5], products=[s3, s6], duplicate=True, kinetics=Arrhenius(), reversible=False), Reaction(reactants=[s3, s6], products=[s5], duplicate=True, kinetics=Arrhenius(), reversible=False), ] mark_duplicate_reactions(reaction_list) duplicate_flags = [rxn.duplicate for rxn in reaction_list] self.assertEqual(duplicate_flags, expected_flags)
def setUp(self): """ A function run before each unit test in this class. """ self.Tmin = 350. self.Tmax = 1500. self.Pmin = 1e-1 self.Pmax = 1e1 self.pressures = numpy.array([1e-1, 1e1]) self.comment = 'CH3 + C2H6 <=> CH4 + C2H5 (Baulch 2005)' self.arrhenius = [ PDepArrhenius( pressures=(self.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=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.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=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, ), ], Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), comment=self.comment, ), PDepArrhenius( pressures=(self.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=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.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=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, ), ], Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), comment=self.comment, ), ] self.kinetics = MultiPDepArrhenius( arrhenius=self.arrhenius, Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), Pmin=(self.Pmin, "bar"), Pmax=(self.Pmax, "bar"), comment=self.comment, )
def setUpClass(cls): r = Species().from_smiles('[CH3]') r.label = '[CH3]' p = Species().from_smiles('CC') p.label = 'CC' cls.reaction = Reaction(reactants=[r, r], products=[p], kinetics=Arrhenius(A=(8.26e+17, 'cm^3/(mol*s)'), n=-1.4, Ea=(1, 'kcal/mol'), T0=(1, 'K'))) cls.comments_list = [ """ Reaction index: Chemkin #1; RMG #1 Template reaction: R_Recombination Exact match found for rate rule (C_methyl;C_methyl) Multiplied by reaction path degeneracy 0.5 """, """ Reaction index: Chemkin #2; RMG #4 Template reaction: H_Abstraction Estimated using template (C/H3/Cs;C_methyl) for rate rule (C/H3/Cs\H3;C_methyl) Multiplied by reaction path degeneracy 6 """, """ Reaction index: Chemkin #13; RMG #8 Template reaction: H_Abstraction Flux pairs: [CH3], CC; [CH3], CC; Estimated using an average for rate rule [C/H3/Cs\H3;C_rad/H2/Cs] Multiplied by reaction path degeneracy 6.0 """, """ Reaction index: Chemkin #17; RMG #31 Template reaction: H_Abstraction Flux pairs: [CH3], CC; [CH3], CC; Estimated using average of templates [C/H3/Cs;H_rad] + [C/H3/Cs\H3;Y_rad] for rate rule [C/H3/Cs\H3;H_rad] Multiplied by reaction path degeneracy 6.0 """, """ Reaction index: Chemkin #69; RMG #171 Template reaction: intra_H_migration Flux pairs: [CH3], CC; [CH3], CC; Estimated using average of templates [R3H_SS;O_rad_out;Cs_H_out_2H] + [R3H_SS_Cs;Y_rad_out;Cs_H_out_2H] for rate rule [R3H_SS_Cs;O_rad_out;Cs_H_out_2H] Multiplied by reaction path degeneracy 3.0 """, """ Reaction index: Chemkin #3; RMG #243 Template reaction: Disproportionation Flux pairs: [CH3], CC; [CH3], CC; Average of [Average of [O2b;O_Csrad] + Average of [O_atom_triplet;O_Csrad + CH2_triplet;O_Csrad] + Average of [Average of [Ct_rad/Ct;O_Csrad from training reaction 0] + Average of [O_pri_rad;O_Csrad + Average of [O_rad/NonDeC;O_Csrad + O_rad/NonDeO;O_Csrad]] + Average of [Cd_pri_rad;O_Csrad] + Average of [CO_pri_rad;O_Csrad] + Average of [C_methyl;O_Csrad + Average of [C_rad/H2/Cs;O_Csrad + C_rad/H2/Cd;O_Csrad + C_rad/H2/O;O_Csrad] + Average of [C_rad/H/NonDeC;O_Csrad] + Average of [Average of [C_rad/Cs3;O_Csrad]]] + H_rad;O_Csrad]] Estimated using template [Y_rad_birad_trirad_quadrad;O_Csrad] for rate rule [CH_quartet;O_Csrad] """, """ Reaction index: Chemkin #4; RMG #303 Template reaction: Disproportionation Flux pairs: [CH3], CC; [CH3], CC; Matched reaction 0 C2H + CH3O <=> C2H2 + CH2O in Disproportionation/training """, """ Reaction index: Chemkin #51; RMG #136 Template reaction: H_Abstraction Flux pairs: [CH3], CC; [CH3], CC; Estimated using an average for rate rule [C/H3/Cd\H_Cd\H2;C_rad/H2/Cs] Euclidian distance = 0 Multiplied by reaction path degeneracy 3.0 """, """ Reaction index: Chemkin #32; RMG #27 Template reaction: R_Recombination Flux pairs: [CH3], CC; [CH3], CC; Matched reaction 20 CH3 + CH3 <=> C2H6 in R_Recombination/training This reaction matched rate rule [C_methyl;C_methyl] """, """ Reaction index: Chemkin #2; RMG #4 Template reaction: R_Recombination Flux pairs: [CH3], CC; [CH3], CC; From training reaction 21 used for C_rad/H2/Cs;C_methyl Exact match found for rate rule [C_rad/H2/Cs;C_methyl] Euclidian distance = 0 """ ] cls.template_list = [['C_methyl', 'C_methyl'], ['C/H3/Cs\H3', 'C_methyl'], ['C/H3/Cs\H3', 'C_rad/H2/Cs'], ['C/H3/Cs\H3', 'H_rad'], ['R3H_SS_Cs', 'O_rad_out', 'Cs_H_out_2H'], ['CH_quartet', 'O_Csrad'], None, ['C/H3/Cd\H_Cd\H2', 'C_rad/H2/Cs'], ['C_methyl', 'C_methyl'], ['C_rad/H2/Cs', 'C_methyl']] cls.family_list = [ 'R_Recombination', 'H_Abstraction', 'H_Abstraction', 'H_Abstraction', 'intra_H_migration', 'Disproportionation', 'Disproportionation', 'H_Abstraction', 'R_Recombination', 'R_Recombination', ] cls.degeneracy_list = [0.5, 6, 6, 6, 3, 1, 1, 3, 1, 1] cls.expected_lines = [4, 4, 5, 5, 5, 5, 4, 6, 5, 6]
def save(self, outputFile): """ Save the results of the kinetics job to the file located at `path` on disk. """ reaction = self.reaction ks = [] k0s = [] k0revs = [] krevs = [] logging.info('Saving kinetics for {0}...'.format(reaction)) order = len(self.reaction.reactants) factor = 1e6 ** (order-1) f = open(outputFile, 'a') f.write('# ======= =========== =========== =========== ===============\n') f.write('# Temp. k (TST) Tunneling k (TST+T) Units\n') f.write('# ======= =========== =========== =========== ===============\n') if self.Tlist is None: Tlist = [300,400,500,600,800,1000,1500,2000] else: Tlist =self.Tlist.value_si for T in Tlist: tunneling = reaction.transitionState.tunneling reaction.transitionState.tunneling = None k0 = reaction.calculateTSTRateCoefficient(T) * factor reaction.transitionState.tunneling = tunneling k = reaction.calculateTSTRateCoefficient(T) * factor tunneling = reaction.transitionState.tunneling kappa = k / k0 ks.append(k) k0s.append(k0) f.write('# {0:4g} K {1:11.3e} {2:11g} {3:11.3e} {4}\n'.format(T, k0, kappa, k, self.kunits)) f.write('# ======= =========== =========== =========== ===============\n') f.write('\n\n') f.write('# ======= ============ =========== ============ ============= =========\n') f.write('# Temp. Kc (eq) Units krev (TST) krev (TST+T) Units\n') f.write('# ======= ============ =========== ============ ============= =========\n') for n,T in enumerate(Tlist): k = ks[n] k0 = k0s[n] Keq = reaction.getEquilibriumConstant(T) k0rev = k0/Keq krev = k/Keq k0revs.append(k0rev) krevs.append(krev) f.write('# {0:4g} K {1:11.3e} {2} {3:11.3e} {4:11.3e} {5}\n'.format(T, Keq, self.Kequnits, k0rev, krev, self.krunits)) f.write('# ======= ============ =========== ============ ============= =========\n') f.write('\n\n') kinetics0rev = Arrhenius().fitToData(Tlist, numpy.array(k0revs), kunits=self.krunits) kineticsrev = Arrhenius().fitToData(Tlist, numpy.array(krevs), kunits=self.krunits) f.write('# krev (TST) = {0} \n'.format(kinetics0rev)) f.write('# krev (TST+T) = {0} \n\n'.format(kineticsrev)) # Reaction path degeneracy is INCLUDED in the kinetics itself! string = 'kinetics(label={0!r}, kinetics={1!r})'.format(reaction.label, reaction.kinetics) f.write('{0}\n\n'.format(prettify(string))) f.close() # Also save the result to chem.inp f = open(os.path.join(os.path.dirname(outputFile), 'chem.inp'), 'a') reaction = self.reaction kinetics = reaction.kinetics string = '{0!s:51} {1:9.3e} {2:9.3f} {3:9.3f}\n'.format( reaction, kinetics.A.value_si * factor, kinetics.n.value_si, kinetics.Ea.value_si / 4184., ) f.write('{0}\n'.format(string)) f.close()
def save(self, outputFile): """ Save the results of the kinetics job to the file located at `path` on disk. """ reaction = self.reaction ks = [] k0s = [] k0revs = [] krevs = [] logging.info('Saving kinetics for {0}...'.format(reaction)) order = len(self.reaction.reactants) factor = 1e6 ** (order-1) f = open(outputFile, 'a') if self.usedTST: # If TST is not used, eg. it was given in 'reaction', then this will throw an error. f.write('# ======= =========== =========== =========== ===============\n') f.write('# Temp. k (TST) Tunneling k (TST+T) Units\n') f.write('# ======= =========== =========== =========== ===============\n') if self.Tlist is None: Tlist = numpy.array([300,400,500,600,800,1000,1500,2000]) else: Tlist =self.Tlist.value_si for T in Tlist: tunneling = reaction.transitionState.tunneling reaction.transitionState.tunneling = None try: k0 = reaction.calculateTSTRateCoefficient(T) * factor except SpeciesError: k0 = 0 reaction.transitionState.tunneling = tunneling try: k = reaction.calculateTSTRateCoefficient(T) * factor kappa = k / k0 except (SpeciesError,ZeroDivisionError): k = reaction.getRateCoefficient(T) kappa = 0 logging.info("The species in reaction {} do not have adequate information for TST, using default kinetics values.".format(reaction)) tunneling = reaction.transitionState.tunneling ks.append(k) k0s.append(k0) f.write('# {0:4g} K {1:11.3e} {2:11g} {3:11.3e} {4}\n'.format(T, k0, kappa, k, self.kunits)) f.write('# ======= =========== =========== =========== ===============\n') f.write('\n\n') f.write('# ======= ============ =========== ============ ============= =========\n') f.write('# Temp. Kc (eq) Units krev (TST) krev (TST+T) Units\n') f.write('# ======= ============ =========== ============ ============= =========\n') # Initialize Object for Converting Units if self.Kequnits != ' ': keq_unit_converter = quantity.Units(self.Kequnits).getConversionFactorFromSI() else: keq_unit_converter = 1 for n,T in enumerate(Tlist): k = ks[n] k0 = k0s[n] Keq = keq_unit_converter * reaction.getEquilibriumConstant(T) # getEquilibriumConstant returns SI units k0rev = k0/Keq krev = k/Keq k0revs.append(k0rev) krevs.append(krev) f.write('# {0:4g} K {1:11.3e} {2} {3:11.3e} {4:11.3e} {5}\n'.format(T, Keq, self.Kequnits, k0rev, krev, self.krunits)) f.write('# ======= ============ =========== ============ ============= =========\n') f.write('\n\n') kinetics0rev = Arrhenius().fitToData(Tlist, numpy.array(k0revs), kunits=self.krunits) kineticsrev = Arrhenius().fitToData(Tlist, numpy.array(krevs), kunits=self.krunits) f.write('# krev (TST) = {0} \n'.format(kinetics0rev)) f.write('# krev (TST+T) = {0} \n\n'.format(kineticsrev)) # Reaction path degeneracy is INCLUDED in the kinetics itself! string = 'kinetics(label={0!r}, kinetics={1!r})'.format(reaction.label, reaction.kinetics) f.write('{0}\n\n'.format(prettify(string))) f.close() # Also save the result to chem.inp f = open(os.path.join(os.path.dirname(outputFile), 'chem.inp'), 'a') reaction = self.reaction kinetics = reaction.kinetics string = '' if reaction.kinetics.comment: for line in reaction.kinetics.comment.split("\n"): string += "! {0}\n".format(line) string += '{0!s:51} {1:9.3e} {2:9.3f} {3:9.3f}\n'.format( reaction, kinetics.A.value_si * factor, kinetics.n.value_si, kinetics.Ea.value_si / 4184., ) f.write('{0}\n'.format(string)) f.close() # We're saving a YAML file for TSs iff structures of the respective reactant/s and product/s are known if all ([spc.molecule is not None and len(spc.molecule) for spc in self.reaction.reactants + self.reaction.products]): self.arkane_species.update_species_attributes(self.reaction.transitionState) self.arkane_species.reaction_label = reaction.label self.arkane_species.reactants = [{'label': spc.label, 'adjacency_list': spc.molecule[0].toAdjacencyList()} for spc in self.reaction.reactants] self.arkane_species.products = [{'label': spc.label, 'adjacency_list': spc.molecule[0].toAdjacencyList()} for spc in self.reaction.products] self.arkane_species.save_yaml(path=os.path.dirname(outputFile))
class TestArrhenius(unittest.TestCase): """ Contains unit tests of the :class:`Arrhenius` class. """ def setUp(self): """ A function run before each unit test in this class. """ self.A = 1.0e12 self.n = 0.5 self.Ea = 41.84 self.T0 = 1.0 self.Tmin = 300.0 self.Tmax = 3000.0 self.comment = "C2H6" self.arrhenius = Arrhenius( A=(self.A, "cm^3/(mol*s)"), n=self.n, Ea=(self.Ea, "kJ/mol"), T0=(self.T0, "K"), Tmin=(self.Tmin, "K"), Tmax=(self.Tmax, "K"), comment=self.comment, ) def test_A(self): """ Test that the Arrhenius A property was properly set. """ self.assertAlmostEqual(self.arrhenius.A.value_si * 1e6, self.A, delta=1e0) def test_n(self): """ Test that the Arrhenius n property was properly set. """ self.assertAlmostEqual(self.arrhenius.n.value_si, self.n, 6) def test_Ea(self): """ Test that the Arrhenius Ea property was properly set. """ self.assertAlmostEqual(self.arrhenius.Ea.value_si * 0.001, self.Ea, 6) def test_T0(self): """ Test that the Arrhenius T0 property was properly set. """ self.assertAlmostEqual(self.arrhenius.T0.value_si, self.T0, 6) def test_Tmin(self): """ Test that the Arrhenius Tmin property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmin.value_si, self.Tmin, 6) def test_Tmax(self): """ Test that the Arrhenius Tmax property was properly set. """ self.assertAlmostEqual(self.arrhenius.Tmax.value_si, self.Tmax, 6) def test_comment(self): """ Test that the Arrhenius comment property was properly set. """ self.assertEqual(self.arrhenius.comment, self.comment) def test_isTemperatureValid(self): """ Test the Arrhenius.isTemperatureValid() method. """ Tdata = numpy.array([200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]) validdata = numpy.array([False, True, True, True, True, True, True, True, True, True], numpy.bool) for T, valid in zip(Tdata, validdata): valid0 = self.arrhenius.isTemperatureValid(T) self.assertEqual(valid0, valid) def test_getRateCoefficient(self): """ Test the Arrhenius.getRateCoefficient() method. """ Tlist = numpy.array([200, 400, 600, 800, 1000, 1200, 1400, 1600, 1800, 2000]) kexplist = numpy.array( [1.6721e-4, 6.8770e1, 5.5803e3, 5.2448e4, 2.0632e5, 5.2285e5, 1.0281e6, 1.7225e6, 2.5912e6, 3.6123e6] ) for T, kexp in zip(Tlist, kexplist): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-4 * kexp) def test_changeT0(self): """ Test the Arrhenius.changeT0() method. """ Tlist = numpy.array([300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500]) k0list = numpy.array([self.arrhenius.getRateCoefficient(T) for T in Tlist]) self.arrhenius.changeT0(300) self.assertEqual(self.arrhenius.T0.value_si, 300) for T, kexp in zip(Tlist, k0list): kact = self.arrhenius.getRateCoefficient(T) self.assertAlmostEqual(kexp, kact, delta=1e-6 * kexp) def test_fitToData(self): """ Test the Arrhenius.fitToData() method. """ Tdata = numpy.array([300, 400, 500, 600, 700, 800, 900, 1000, 1100, 1200, 1300, 1400, 1500]) kdata = numpy.array([self.arrhenius.getRateCoefficient(T) for T in Tdata]) arrhenius = Arrhenius().fitToData(Tdata, kdata, kunits="m^3/(mol*s)") self.assertEqual(float(self.arrhenius.T0.value_si), 1) for T, k in zip(Tdata, kdata): self.assertAlmostEqual(k, arrhenius.getRateCoefficient(T), delta=1e-6 * k) self.assertAlmostEqual(arrhenius.A.value_si, self.arrhenius.A.value_si, delta=1e0) self.assertAlmostEqual(arrhenius.n.value_si, self.arrhenius.n.value_si, 1, 4) self.assertAlmostEqual(arrhenius.Ea.value_si, self.arrhenius.Ea.value_si, 2) self.assertAlmostEqual(arrhenius.T0.value_si, self.arrhenius.T0.value_si, 4) def test_pickle(self): """ Test that an Arrhenius object can be pickled and unpickled with no loss of information. """ import cPickle arrhenius = cPickle.loads(cPickle.dumps(self.arrhenius)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment) def test_repr(self): """ Test that an Arrhenius object can be reconstructed from its repr() output with no loss of information. """ arrhenius = None exec("arrhenius = {0!r}".format(self.arrhenius)) self.assertAlmostEqual(self.arrhenius.A.value, arrhenius.A.value, delta=1e0) self.assertEqual(self.arrhenius.A.units, arrhenius.A.units) self.assertAlmostEqual(self.arrhenius.n.value, arrhenius.n.value, 4) self.assertAlmostEqual(self.arrhenius.Ea.value, arrhenius.Ea.value, 4) self.assertEqual(self.arrhenius.Ea.units, arrhenius.Ea.units) self.assertAlmostEqual(self.arrhenius.T0.value, arrhenius.T0.value, 4) self.assertEqual(self.arrhenius.T0.units, arrhenius.T0.units) self.assertAlmostEqual(self.arrhenius.Tmin.value, arrhenius.Tmin.value, 4) self.assertEqual(self.arrhenius.Tmin.units, arrhenius.Tmin.units) self.assertAlmostEqual(self.arrhenius.Tmax.value, arrhenius.Tmax.value, 4) self.assertEqual(self.arrhenius.Tmax.units, arrhenius.Tmax.units) self.assertEqual(self.arrhenius.comment, arrhenius.comment)
def test_generate_isotope_reactions(self): """ shows that all isotope reactions are created with generateIsotopeReactions """ methyl = Species().from_smiles('[CH3]') methyli = Species().from_adjacency_list(""" multiplicity 2 1 C u1 p0 c0 i13 {2,S} {3,S} {4,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 H u0 p0 c0 {1,S} """) methane = Species().from_adjacency_list(""" 1 C u0 p0 c0 {2,S} {3,S} {4,S} {5,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 H u0 p0 c0 {1,S} 5 H u0 p0 c0 {1,S} """) methanei = Species().from_adjacency_list(""" 1 C u0 p0 c0 i13 {2,S} {3,S} {4,S} {5,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} 4 H u0 p0 c0 {1,S} 5 H u0 p0 c0 {1,S} """) craigie = Species().from_adjacency_list(""" multiplicity 3 1 C u2 p0 c0 {2,S} {3,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} """) craigiei = Species().from_adjacency_list(""" multiplicity 3 1 C u2 p0 c0 i13 {2,S} {3,S} 2 H u0 p0 c0 {1,S} 3 H u0 p0 c0 {1,S} """) reaction = TemplateReaction(reactants=[methyl, methyl], products=[methane, craigie], family='H_Abstraction', template=['Xrad_H', 'Y_rad'], degeneracy=3) reaction.kinetics = Arrhenius(A=(1e5, 'cm^3/(mol*s)'), Ea=(0, 'J/mol')) isotope_list = [[methyl, methyli], [methane, methanei], [craigie, craigiei]] new_reactions = generate_isotope_reactions([reaction], isotope_list) self.assertEqual(len(new_reactions), 4) degeneracies_found = set() for rxn in new_reactions: self.assertEqual(rxn.template, reaction.template) degeneracies_found.add(rxn.degeneracy) self.assertIsNotNone(rxn.kinetics, 'kinetics not obtained for reaction {}.'.format(rxn)) self.assertAlmostEqual(reaction.kinetics.get_rate_coefficient(298), rxn.kinetics.get_rate_coefficient(298) * reaction.degeneracy / rxn.degeneracy) self.assertEqual(degeneracies_found, set([3]))