Beispiel #1
0
    def convertDuplicatesToMulti(self):
        """
        Merge all marked duplicate reactions in the kinetics library
        into single reactions with multiple kinetics.
        """
        print "trying to find duplicates"
        entries_to_remove = []
        for entry0 in self.entries.values():
            if entry0 in entries_to_remove:
                continue
            reaction0 = entry0.item
            if not reaction0.duplicate:
                continue
            print "Found a duplicate reaction: {0}".format(reaction0)
            duplicates = [entry0]
            for entry in self.entries.values():
                reaction = entry.item
                if reaction0 is reaction:
                    continue
                if reaction0.isIsomorphic(reaction, eitherDirection=False):
                    if reaction0.reversible != reaction.reversible:
                        print "Reactions isomorphic but with different reversibilities"
                        continue
                    duplicates.append(entry)

            assert len(duplicates) > 1
            kineticsList = []
            longDesc = ''

            for entry in duplicates:
                kinetics = entry.data
                kineticsList.append(kinetics)
                Tmin = kinetics.Tmin
                Tmax = kinetics.Tmax
                if kinetics.isPressureDependent():
                    Pmin = kinetics.Pmin
                    Pmax = kinetics.Pmax
                else:
                    Pmin = None
                    Pmax = None
                longDesc += entry.longDesc + '\n'

            if len(kineticsList) == 2 and isinstance(
                    kineticsList[0],
                    ThirdBody) and not isinstance(kineticsList[1], ThirdBody):
                continue
            elif len(kineticsList) == 2 and isinstance(
                    kineticsList[1],
                    ThirdBody) and not isinstance(kineticsList[0], ThirdBody):
                continue

            if all([isinstance(k, Arrhenius) for k in kineticsList]):
                entry0.data = MultiArrhenius(arrhenius=kineticsList,
                                             Tmin=Tmin,
                                             Tmax=Tmax)
            elif all([isinstance(k, PDepArrhenius) for k in kineticsList]):
                entry0.data = MultiPDepArrhenius(arrhenius=kineticsList,
                                                 Tmin=Tmin,
                                                 Tmax=Tmax,
                                                 Pmin=Pmin,
                                                 Pmax=Pmax)
            else:
                logging.warning(
                    'Only Arrhenius and PDepArrhenius kinetics supported for duplicate reactions.'
                )
                continue
            entry0.longDesc = longDesc
            entries_to_remove.extend(duplicates[1:])
        for entry in entries_to_remove:
            print "removing duplicate reaction with index {0}.".format(
                entry.index)
            del (self.entries[entry.index])
        print "NB. the entries have not been renumbered, so these indices are missing."
Beispiel #2
0
    def testGenerateReverseRateCoefficientMultiPDepArrhenius(self):
        """
        Test the Reaction.generateReverseRateCoefficient() method works for the MultiPDepArrhenius format.
        """
        from rmgpy.kinetics import PDepArrhenius, MultiPDepArrhenius

        Tmin = 350.
        Tmax = 1500.
        Pmin = 1e-1
        Pmax = 1e1
        pressures = numpy.array([1e-1,1e1])
        comment = 'CH3 + C2H6 <=> CH4 + C2H5 (Baulch 2005)'
        arrhenius = [
            PDepArrhenius(
                pressures = (pressures,"bar"),
                arrhenius = [
                    Arrhenius(
                        A = (9.3e-16,"cm^3/(molecule*s)"),
                        n = 0.0,
                        Ea = (4740*constants.R*0.001,"kJ/mol"),
                        T0 = (1,"K"),
                        Tmin = (Tmin,"K"),
                        Tmax = (Tmax,"K"),
                        comment = comment,
                    ),
                    Arrhenius(
                        A = (9.3e-14,"cm^3/(molecule*s)"),
                        n = 0.0,
                        Ea = (4740*constants.R*0.001,"kJ/mol"),
                        T0 = (1,"K"),
                        Tmin = (Tmin,"K"),
                        Tmax = (Tmax,"K"),
                        comment = comment,
                    ),
                ],
                Tmin = (Tmin,"K"), 
                Tmax = (Tmax,"K"), 
                Pmin = (Pmin,"bar"), 
                Pmax = (Pmax,"bar"),
                comment = comment,
            ),
            PDepArrhenius(
                pressures = (pressures,"bar"),
                arrhenius = [
                    Arrhenius(
                        A = (1.4e-11,"cm^3/(molecule*s)"),
                        n = 0.0,
                        Ea = (11200*constants.R*0.001,"kJ/mol"),
                        T0 = (1,"K"),
                        Tmin = (Tmin,"K"),
                        Tmax = (Tmax,"K"),
                        comment = comment,
                    ),
                    Arrhenius(
                        A = (1.4e-9,"cm^3/(molecule*s)"),
                        n = 0.0,
                        Ea = (11200*constants.R*0.001,"kJ/mol"),
                        T0 = (1,"K"),
                        Tmin = (Tmin,"K"),
                        Tmax = (Tmax,"K"),
                        comment = comment,
                    ),
                ],
                Tmin = (Tmin,"K"), 
                Tmax = (Tmax,"K"), 
                Pmin = (Pmin,"bar"), 
                Pmax = (Pmax,"bar"),
                comment = comment,
            ),
        ]  

        original_kinetics = MultiPDepArrhenius(
            arrhenius = arrhenius,
            Tmin = (Tmin,"K"),
            Tmax = (Tmax,"K"),
            Pmin = (Pmin,"bar"),
            Pmax = (Pmax,"bar"),
            comment = comment,
        )

        self.reaction2.kinetics = original_kinetics

        reverseKinetics = self.reaction2.generateReverseRateCoefficient()

        self.reaction2.kinetics = reverseKinetics
        # reverse reactants, products to ensure Keq is correctly computed
        self.reaction2.reactants, self.reaction2.products = self.reaction2.products, self.reaction2.reactants
        reversereverseKinetics = self.reaction2.generateReverseRateCoefficient()

        # check that reverting the reverse yields the original
        Tlist = numpy.arange(Tmin, Tmax, 200.0, numpy.float64)
        P = 1e5
        for T in Tlist:
            korig = original_kinetics.getRateCoefficient(T, P)
            krevrev = reversereverseKinetics.getRateCoefficient(T, P)
            self.assertAlmostEqual(korig / krevrev, 1.0, 0)
Beispiel #3
0
    def generateReverseRateCoefficient(self):
        """
        Generate and return a rate coefficient model for the reverse reaction. 
        Currently this only works if the `kinetics` attribute is one of several
        (but not necessarily all) kinetics types.
        """
        cython.declare(Tlist=numpy.ndarray, klist=numpy.ndarray, i=cython.int)

        supported_types = (
                            KineticsData.__name__,
                            Arrhenius.__name__,
                            MultiArrhenius.__name__,
                            PDepArrhenius.__name__,
                            MultiPDepArrhenius.__name__,
                            Chebyshev.__name__,
                            ThirdBody.__name__,
                            Lindemann.__name__,
                            Troe.__name__,
                            )

        # Get the units for the reverse rate coefficient
        kunits = getRateCoefficientUnitsFromReactionOrder(len(self.products))
            
        kf = self.kinetics
        if isinstance(kf, KineticsData):
            
            Tlist = kf.Tdata.value_si
            klist = numpy.zeros_like(Tlist)
            for i in range(len(Tlist)):
                klist[i] = kf.getRateCoefficient(Tlist[i]) / self.getEquilibriumConstant(Tlist[i])
            
            kr = KineticsData(Tdata=(Tlist,"K"), kdata=(klist,kunits), Tmin=(numpy.min(Tlist),"K"), Tmax=(numpy.max(Tlist),"K"))
            return kr
            
        elif isinstance(kf, Arrhenius):
            return self.reverseThisArrheniusRate(kf, kunits)
                    
        elif isinstance (kf, Chebyshev):
            Tlist = 1.0/numpy.linspace(1.0/kf.Tmax.value, 1.0/kf.Tmin.value, 50)
            Plist = numpy.linspace(kf.Pmin.value, kf.Pmax.value, 20)
            K = numpy.zeros((len(Tlist), len(Plist)), numpy.float64)
            for Tindex, T in enumerate(Tlist):
                for Pindex, P in enumerate(Plist):
                    K[Tindex, Pindex] = kf.getRateCoefficient(T, P) / self.getEquilibriumConstant(T)
            kr = Chebyshev()
            kr.fitToData(Tlist, Plist, K, kunits, kf.degreeT, kf.degreeP, kf.Tmin.value, kf.Tmax.value, kf.Pmin.value, kf.Pmax.value)
            return kr
        
        elif isinstance(kf, PDepArrhenius):  
            if kf.Tmin is not None and kf.Tmax is not None:
                Tlist = 1.0/numpy.linspace(1.0/kf.Tmax.value, 1.0/kf.Tmin.value, 50)
            else:
                Tlist = 1.0/numpy.arange(0.0005, 0.0035, 0.0001)
            Plist = kf.pressures.value_si
            K = numpy.zeros((len(Tlist), len(Plist)), numpy.float64)
            for Tindex, T in enumerate(Tlist):
                for Pindex, P in enumerate(Plist):
                    K[Tindex, Pindex] = kf.getRateCoefficient(T, P) / self.getEquilibriumConstant(T)
            kr = PDepArrhenius()
            kr.fitToData(Tlist, Plist, K, kunits, kf.arrhenius[0].T0.value)
            return kr       
        
        elif isinstance(kf, MultiArrhenius):
            kr = MultiArrhenius()
            kr.arrhenius = []            
            rxn = Reaction(reactants = self.reactants, products = self.products)            
            for kinetics in kf.arrhenius:
                rxn.kinetics = kinetics
                kr.arrhenius.append(rxn.generateReverseRateCoefficient())
            return kr
        
        elif isinstance(kf, MultiPDepArrhenius):
            kr = MultiPDepArrhenius()              
            kr.arrhenius = []                
            rxn = Reaction(reactants = self.reactants, products = self.products)            
            for kinetics in kf.arrhenius:
                rxn.kinetics = kinetics
                kr.arrhenius.append(rxn.generateReverseRateCoefficient())
            return kr

        elif isinstance(kf, ThirdBody):
            lowPkunits = getRateCoefficientUnitsFromReactionOrder(len(self.products) + 1)
            krLow = self.reverseThisArrheniusRate(kf.arrheniusLow, lowPkunits)
            parameters = kf.__reduce__()[1]  # use the pickle helper to get all the other things needed
            kr = ThirdBody(krLow, *parameters[1:])
            return kr

        elif isinstance(kf, Lindemann):
            krHigh = self.reverseThisArrheniusRate(kf.arrheniusHigh, kunits)
            lowPkunits = getRateCoefficientUnitsFromReactionOrder(len(self.products) + 1)
            krLow = self.reverseThisArrheniusRate(kf.arrheniusLow, lowPkunits)
            parameters = kf.__reduce__()[1]  # use the pickle helper to get all the other things needed
            kr = Lindemann(krHigh, krLow, *parameters[2:])
            return kr

        elif isinstance(kf, Troe):
            krHigh = self.reverseThisArrheniusRate(kf.arrheniusHigh, kunits)
            lowPkunits = getRateCoefficientUnitsFromReactionOrder(len(self.products) + 1)
            krLow = self.reverseThisArrheniusRate(kf.arrheniusLow, lowPkunits)
            parameters = kf.__reduce__()[1]  # use the pickle helper to get all the other things needed
            kr = Troe(krHigh, krLow, *parameters[2:])
            return kr
        else:
            raise ReactionError(("Unexpected kinetics type {0}; should be one of {1}").format(self.kinetics.__class__, supported_types))
Beispiel #4
0
    def testGenerateReverseRateCoefficientMultiPDepArrhenius(self):
        """
        Test the Reaction.generateReverseRateCoefficient() method works for the MultiPDepArrhenius format.
        """
        from rmgpy.kinetics import PDepArrhenius, MultiPDepArrhenius

        Tmin = 350.0
        Tmax = 1500.0
        Pmin = 1e-1
        Pmax = 1e1
        pressures = numpy.array([1e-1, 1e1])
        comment = "CH3 + C2H6 <=> CH4 + C2H5 (Baulch 2005)"
        arrhenius = [
            PDepArrhenius(
                pressures=(pressures, "bar"),
                arrhenius=[
                    Arrhenius(
                        A=(9.3e-16, "cm^3/(molecule*s)"),
                        n=0.0,
                        Ea=(4740 * constants.R * 0.001, "kJ/mol"),
                        T0=(1, "K"),
                        Tmin=(Tmin, "K"),
                        Tmax=(Tmax, "K"),
                        comment=comment,
                    ),
                    Arrhenius(
                        A=(9.3e-14, "cm^3/(molecule*s)"),
                        n=0.0,
                        Ea=(4740 * constants.R * 0.001, "kJ/mol"),
                        T0=(1, "K"),
                        Tmin=(Tmin, "K"),
                        Tmax=(Tmax, "K"),
                        comment=comment,
                    ),
                ],
                Tmin=(Tmin, "K"),
                Tmax=(Tmax, "K"),
                Pmin=(Pmin, "bar"),
                Pmax=(Pmax, "bar"),
                comment=comment,
            ),
            PDepArrhenius(
                pressures=(pressures, "bar"),
                arrhenius=[
                    Arrhenius(
                        A=(1.4e-11, "cm^3/(molecule*s)"),
                        n=0.0,
                        Ea=(11200 * constants.R * 0.001, "kJ/mol"),
                        T0=(1, "K"),
                        Tmin=(Tmin, "K"),
                        Tmax=(Tmax, "K"),
                        comment=comment,
                    ),
                    Arrhenius(
                        A=(1.4e-9, "cm^3/(molecule*s)"),
                        n=0.0,
                        Ea=(11200 * constants.R * 0.001, "kJ/mol"),
                        T0=(1, "K"),
                        Tmin=(Tmin, "K"),
                        Tmax=(Tmax, "K"),
                        comment=comment,
                    ),
                ],
                Tmin=(Tmin, "K"),
                Tmax=(Tmax, "K"),
                Pmin=(Pmin, "bar"),
                Pmax=(Pmax, "bar"),
                comment=comment,
            ),
        ]

        original_kinetics = MultiPDepArrhenius(
            arrhenius=arrhenius,
            Tmin=(Tmin, "K"),
            Tmax=(Tmax, "K"),
            Pmin=(Pmin, "bar"),
            Pmax=(Pmax, "bar"),
            comment=comment,
        )

        self.reaction2.kinetics = original_kinetics

        reverseKinetics = self.reaction2.generateReverseRateCoefficient()

        self.reaction2.kinetics = reverseKinetics
        # reverse reactants, products to ensure Keq is correctly computed
        self.reaction2.reactants, self.reaction2.products = self.reaction2.products, self.reaction2.reactants
        reversereverseKinetics = self.reaction2.generateReverseRateCoefficient()

        # check that reverting the reverse yields the original
        Tlist = numpy.arange(Tmin, Tmax, 200.0, numpy.float64)
        P = 1e5
        for T in Tlist:
            korig = original_kinetics.getRateCoefficient(T, P)
            krevrev = reversereverseKinetics.getRateCoefficient(T, P)
            self.assertAlmostEqual(korig / krevrev, 1.0, 0)