Exemple #1
0
    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]))
Exemple #2
0
 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,
     )
Exemple #3
0
 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,
     )
Exemple #4
0
    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)
Exemple #5
0
    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.reaction.kinetics = Arrhenius().fitToData(Tlist,
                                                       klist,
                                                       kunits=self.kunits)
Exemple #6
0
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)
Exemple #7
0
 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
Exemple #8
0
 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,
     )
Exemple #9
0
    def generateKinetics(self, Tlist=None):
        """
        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
        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:
            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(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)
        self.reaction.elementary_high_p = True
Exemple #10
0
    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
Exemple #11
0
    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]))
Exemple #12
0
    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))
Exemple #13
0
    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]
Exemple #14
0
    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)
Exemple #15
0
    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))
Exemple #16
0
 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,
     )
Exemple #17
0
    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))
Exemple #18
0
    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()
Exemple #19
0
    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 = []
Exemple #20
0
    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()
Exemple #21
0
    for row_num, row in enumerate(col[3:]):
        kdata[row_num, col_num] = numpy.array(row, dtype=numpy.float64)

########################Fit Modified Arrhenius expression to each column of kdata###################################################

kinetics = []
kunits = []

for rxn_number in range(kdata.shape[1]):
    kunits.append({
        1: 's^-1',
        2: 'cm^3/(mol*s)',
        3: 'cm^6/(mol^2*s)'
    }[order[rxn_number]])
    kinetics.append(Arrhenius().fitToData(Tdata,
                                          kdata[:, rxn_number],
                                          kunits=kunits[rxn_number],
                                          threeParams=threeParams))

########################Output Modified Arrhenius fit to CHEMKIN input file format#####################################
# Initialize (and clear!) the output files for the job
outputDirectory = os.path.dirname(os.path.abspath(k_data_path))

chemkinFile = os.path.join(outputDirectory,
                           system_name.replace(" ", "_") + '.inp')

with open(chemkinFile, 'w') as f:
    pass

Tcount = Tdata.shape[0]
reactioncount = kdata.shape[1]