Пример #1
0
    def test_jacobian(self):
        """
        Unit test for the jacobian function:
        Solve a reaction system and check if the analytical jacobian matches the finite difference jacobian

        """

        coreSpecies = [self.CH4,self.CH3,self.C2H6,self.C2H5]
        edgeSpecies = []

        rxn1 = Reaction(reactants=[self.C2H6,self.CH3], products=[self.C2H5,self.CH4], kinetics=Arrhenius(A=(686.375*6,'m^3/(mol*s)'), n=4.40721, Ea=(7.82799,'kcal/mol'), T0=(298.15,'K')))
        coreReactions = [rxn1]
        edgeReactions = []
        numCoreSpecies = len(coreSpecies)

        rxnList = []
        rxnList.append(Reaction(reactants=[self.C2H6], products=[self.CH3,self.CH3], kinetics=Arrhenius(A=(686.375*6,'1/s'), n=4.40721, Ea=(7.82799,'kcal/mol'), T0=(298.15,'K'))))
        rxnList.append(Reaction(reactants=[self.CH3,self.CH3], products=[self.C2H6], kinetics=Arrhenius(A=(686.375*6,'m^3/(mol*s)'), n=4.40721, Ea=(7.82799,'kcal/mol'), T0=(298.15,'K'))))
        
        rxnList.append(Reaction(reactants=[self.C2H6,self.CH3], products=[self.C2H5,self.CH4], kinetics=Arrhenius(A=(46.375*6,'m^3/(mol*s)'), n=3.40721, Ea=(6.82799,'kcal/mol'), T0=(298.15,'K'))))        
        rxnList.append(Reaction(reactants=[self.C2H5,self.CH4], products=[self.C2H6,self.CH3], kinetics=Arrhenius(A=(46.375*6,'m^3/(mol*s)'), n=3.40721, Ea=(6.82799,'kcal/mol'), T0=(298.15,'K'))))        
        
        rxnList.append(Reaction(reactants=[self.C2H5,self.CH4], products=[self.CH3,self.CH3,self.CH3], kinetics=Arrhenius(A=(246.375*6,'m^3/(mol*s)'), n=1.40721, Ea=(3.82799,'kcal/mol'), T0=(298.15,'K'))))       
        rxnList.append(Reaction(reactants=[self.CH3,self.CH3,self.CH3], products=[self.C2H5,self.CH4], kinetics=Arrhenius(A=(246.375*6,'m^6/(mol^2*s)'), n=1.40721, Ea=(3.82799,'kcal/mol'), T0=(298.15,'K'))))#        
        
        rxnList.append(Reaction(reactants=[self.C2H6,self.CH3,self.CH3], products=[self.C2H5,self.C2H5,self.H2], kinetics=Arrhenius(A=(146.375*6,'m^6/(mol^2*s)'), n=2.40721, Ea=(8.82799,'kcal/mol'), T0=(298.15,'K'))))
        rxnList.append(Reaction(reactants=[self.C2H5,self.C2H5,self.H2], products=[self.C2H6,self.CH3,self.CH3], kinetics=Arrhenius(A=(146.375*6,'m^6/(mol^2*s)'), n=2.40721, Ea=(8.82799,'kcal/mol'), T0=(298.15,'K'))))
        
        rxnList.append(Reaction(reactants=[self.C2H6,self.C2H6], products=[self.CH3,self.CH4,self.C2H5], kinetics=Arrhenius(A=(1246.375*6,'m^3/(mol*s)'), n=0.40721, Ea=(8.82799,'kcal/mol'), T0=(298.15,'K'))))
        rxnList.append(Reaction(reactants=[self.CH3,self.CH4,self.C2H5], products=[self.C2H6,self.C2H6], kinetics=Arrhenius(A=(46.375*6,'m^6/(mol^2*s)'), n=0.10721, Ea=(8.82799,'kcal/mol'), T0=(298.15,'K'))))
        

        for rxn in rxnList:
            coreSpecies = [self.CH4,self.CH3,self.C2H6,self.C2H5,self.H2]
            edgeSpecies = []
            coreReactions = [rxn]
            
            c0={self.CH4:0.2,self.CH3:0.1,self.C2H6:0.35,self.C2H5:0.15, self.H2:0.2}
            rxnSystem0 = LiquidReactor(self.T, c0,termination=[])
            rxnSystem0.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)
            dydt0 = rxnSystem0.residual(0.0, rxnSystem0.y, numpy.zeros(rxnSystem0.y.shape))[0]
            
            dN = .000001*sum(rxnSystem0.y)
            dN_array = dN*numpy.eye(numCoreSpecies)
            
            dydt = []
            for i in xrange(numCoreSpecies):
                rxnSystem0.y[i] += dN 
                dydt.append(rxnSystem0.residual(0.0, rxnSystem0.y, numpy.zeros(rxnSystem0.y.shape))[0])
                rxnSystem0.y[i] -= dN  # reset y to original y0
            
            # Let the solver compute the jacobian       
            solverJacobian = rxnSystem0.jacobian(0.0, rxnSystem0.y, dydt0, 0.0)     
            # Compute the jacobian using finite differences
            jacobian = numpy.zeros((numCoreSpecies, numCoreSpecies))
            for i in xrange(numCoreSpecies):
                for j in xrange(numCoreSpecies):
                    jacobian[i,j] = (dydt[j][i]-dydt0[i])/dN
                    self.assertAlmostEqual(jacobian[i,j], solverJacobian[i,j], delta=abs(1e-4*jacobian[i,j]))
Пример #2
0
    def test_jacobian(self):
        """
        Unit test for the jacobian function:
        Solve a reaction system and check if the analytical jacobian matches
        the finite difference jacobian.
        """

        core_species = [self.CH4, self.CH3, self.C2H6, self.C2H5, self.H2]
        edge_species = []
        num_core_species = len(core_species)
        c0 = {
            self.CH4: 0.2,
            self.CH3: 0.1,
            self.C2H6: 0.35,
            self.C2H5: 0.15,
            self.H2: 0.2
        }
        edge_reactions = []

        rxn_list = [
            Reaction(reactants=[self.C2H6],
                     products=[self.CH3, self.CH3],
                     kinetics=Arrhenius(A=(686.375 * 6, '1/s'),
                                        n=4.40721,
                                        Ea=(7.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.CH3, self.CH3],
                     products=[self.C2H6],
                     kinetics=Arrhenius(A=(686.375 * 6, 'm^3/(mol*s)'),
                                        n=4.40721,
                                        Ea=(7.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.C2H6, self.CH3],
                     products=[self.C2H5, self.CH4],
                     kinetics=Arrhenius(A=(46.375 * 6, 'm^3/(mol*s)'),
                                        n=3.40721,
                                        Ea=(6.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.C2H5, self.CH4],
                     products=[self.C2H6, self.CH3],
                     kinetics=Arrhenius(A=(46.375 * 6, 'm^3/(mol*s)'),
                                        n=3.40721,
                                        Ea=(6.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.C2H5, self.CH4],
                     products=[self.CH3, self.CH3, self.CH3],
                     kinetics=Arrhenius(A=(246.375 * 6, 'm^3/(mol*s)'),
                                        n=1.40721,
                                        Ea=(3.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.CH3, self.CH3, self.CH3],
                     products=[self.C2H5, self.CH4],
                     kinetics=Arrhenius(A=(246.375 * 6, 'm^6/(mol^2*s)'),
                                        n=1.40721,
                                        Ea=(3.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.C2H6, self.CH3, self.CH3],
                     products=[self.C2H5, self.C2H5, self.H2],
                     kinetics=Arrhenius(A=(146.375 * 6, 'm^6/(mol^2*s)'),
                                        n=2.40721,
                                        Ea=(8.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.C2H5, self.C2H5, self.H2],
                     products=[self.C2H6, self.CH3, self.CH3],
                     kinetics=Arrhenius(A=(146.375 * 6, 'm^6/(mol^2*s)'),
                                        n=2.40721,
                                        Ea=(8.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.C2H6, self.C2H6],
                     products=[self.CH3, self.CH4, self.C2H5],
                     kinetics=Arrhenius(A=(1246.375 * 6, 'm^3/(mol*s)'),
                                        n=0.40721,
                                        Ea=(8.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
            Reaction(reactants=[self.CH3, self.CH4, self.C2H5],
                     products=[self.C2H6, self.C2H6],
                     kinetics=Arrhenius(A=(46.375 * 6, 'm^6/(mol^2*s)'),
                                        n=0.10721,
                                        Ea=(8.82799, 'kcal/mol'),
                                        T0=(298.15, 'K'))),
        ]

        # Analytical Jacobian for reaction 6
        def jacobian_rxn6(c, kf, kr, s):
            c1, c2, c3, c4 = c[s[1]], c[s[2]], c[s[3]], c[s[4]]
            jaco = np.zeros((5, 5))

            jaco[1, 1] = -4 * kf * c1 * c2
            jaco[1, 2] = -2 * kf * c1 * c1
            jaco[1, 3] = 4 * kr * c3 * c4
            jaco[1, 4] = 2 * kr * c3 * c3
            jaco[2, 1:] = 0.5 * jaco[1, 1:]
            jaco[3, 1:] = -jaco[1, 1:]
            jaco[4, 1:] = -0.5 * jaco[1, 1:]
            return jaco

        # Analytical Jacobian for reaction 7
        def jacobian_rxn7(c, kf, kr, s):
            c1, c2, c3, c4 = c[s[1]], c[s[2]], c[s[3]], c[s[4]]
            jaco = np.zeros((5, 5))

            jaco[1, 1] = -4 * kr * c1 * c2
            jaco[1, 2] = -2 * kr * c1 * c1
            jaco[1, 3] = 4 * kf * c3 * c4
            jaco[1, 4] = 2 * kf * c3 * c3
            jaco[2, 1:] = 0.5 * jaco[1, 1:]
            jaco[3, 1:] = -jaco[1, 1:]
            jaco[4, 1:] = -0.5 * jaco[1, 1:]
            return jaco

        for rxn_num, rxn in enumerate(rxn_list):
            core_reactions = [rxn]

            rxn_system0 = LiquidReactor(self.T, c0, 1, termination=[])
            rxn_system0.initialize_model(core_species, core_reactions,
                                         edge_species, edge_reactions)
            dydt0 = rxn_system0.residual(0.0, rxn_system0.y,
                                         np.zeros(rxn_system0.y.shape))[0]

            dN = .000001 * sum(rxn_system0.y)

            # Let the solver compute the jacobian
            solver_jacobian = rxn_system0.jacobian(0.0, rxn_system0.y, dydt0,
                                                   0.0)

            if rxn_num not in (6, 7):
                dydt = []
                for i in range(num_core_species):
                    rxn_system0.y[i] += dN
                    dydt.append(
                        rxn_system0.residual(0.0, rxn_system0.y,
                                             np.zeros(rxn_system0.y.shape))[0])
                    rxn_system0.y[i] -= dN  # reset y

                # Compute the jacobian using finite differences
                jacobian = np.zeros((num_core_species, num_core_species))
                for i in range(num_core_species):
                    for j in range(num_core_species):
                        jacobian[i, j] = (dydt[j][i] - dydt0[i]) / dN
                        self.assertAlmostEqual(jacobian[i, j],
                                               solver_jacobian[i, j],
                                               delta=abs(1e-4 *
                                                         jacobian[i, j]))
            # The forward finite difference is very unstable for reactions
            # 6 and 7. Use Jacobians calculated by hand instead.
            elif rxn_num == 6:
                kforward = rxn.get_rate_coefficient(self.T)
                kreverse = kforward / rxn.get_equilibrium_constant(self.T)
                jacobian = jacobian_rxn6(c0, kforward, kreverse, core_species)
                for i in range(num_core_species):
                    for j in range(num_core_species):
                        self.assertAlmostEqual(jacobian[i, j],
                                               solver_jacobian[i, j],
                                               delta=abs(1e-4 *
                                                         jacobian[i, j]))
            elif rxn_num == 7:
                kforward = rxn.get_rate_coefficient(self.T)
                kreverse = kforward / rxn.get_equilibrium_constant(self.T)
                jacobian = jacobian_rxn7(c0, kforward, kreverse, core_species)
                for i in range(num_core_species):
                    for j in range(num_core_species):
                        self.assertAlmostEqual(jacobian[i, j],
                                               solver_jacobian[i, j],
                                               delta=abs(1e-4 *
                                                         jacobian[i, j]))
    def test_jacobian(self):
        """
        Unit test for the jacobian function:
        Solve a reaction system and check if the analytical jacobian matches
        the finite difference jacobian.
        """

        coreSpecies = [self.CH4, self.CH3, self.C2H6, self.C2H5, self.H2]
        edgeSpecies = []
        numCoreSpecies = len(coreSpecies)
        c0 = {self.CH4: 0.2, self.CH3: 0.1, self.C2H6: 0.35, self.C2H5: 0.15, self.H2: 0.2}
        edgeReactions = []

        rxnList = []
        rxnList.append(Reaction(
            reactants=[self.C2H6],
            products=[self.CH3, self.CH3],
            kinetics=Arrhenius(A=(686.375*6, '1/s'), n=4.40721, Ea=(7.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        rxnList.append(Reaction(
            reactants=[self.CH3, self.CH3],
            products=[self.C2H6],
            kinetics=Arrhenius(A=(686.375*6, 'm^3/(mol*s)'), n=4.40721, Ea=(7.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        
        rxnList.append(Reaction(
            reactants=[self.C2H6, self.CH3],
            products=[self.C2H5, self.CH4],
            kinetics=Arrhenius(A=(46.375*6, 'm^3/(mol*s)'), n=3.40721, Ea=(6.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        rxnList.append(Reaction(
            reactants=[self.C2H5, self.CH4],
            products=[self.C2H6, self.CH3],
            kinetics=Arrhenius(A=(46.375*6, 'm^3/(mol*s)'), n=3.40721, Ea=(6.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        
        rxnList.append(Reaction(
            reactants=[self.C2H5, self.CH4],
            products=[self.CH3, self.CH3, self.CH3],
            kinetics=Arrhenius(A=(246.375*6, 'm^3/(mol*s)'), n=1.40721, Ea=(3.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        rxnList.append(Reaction(
            reactants=[self.CH3, self.CH3, self.CH3],
            products=[self.C2H5, self.CH4],
            kinetics=Arrhenius(A=(246.375*6, 'm^6/(mol^2*s)'), n=1.40721, Ea=(3.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        
        rxnList.append(Reaction(
            reactants=[self.C2H6, self.CH3, self.CH3],
            products=[self.C2H5, self.C2H5, self.H2],
            kinetics=Arrhenius(A=(146.375*6, 'm^6/(mol^2*s)'), n=2.40721, Ea=(8.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        rxnList.append(Reaction(
            reactants=[self.C2H5, self.C2H5, self.H2],
            products=[self.C2H6, self.CH3, self.CH3],
            kinetics=Arrhenius(A=(146.375*6, 'm^6/(mol^2*s)'), n=2.40721, Ea=(8.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))

        rxnList.append(Reaction(
            reactants=[self.C2H6, self.C2H6],
            products=[self.CH3, self.CH4, self.C2H5],
            kinetics=Arrhenius(A=(1246.375*6, 'm^3/(mol*s)'), n=0.40721, Ea=(8.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))
        rxnList.append(Reaction(
            reactants=[self.CH3, self.CH4, self.C2H5],
            products=[self.C2H6, self.C2H6],
            kinetics=Arrhenius(A=(46.375*6, 'm^6/(mol^2*s)'), n=0.10721, Ea=(8.82799, 'kcal/mol'), T0=(298.15, 'K'))
        ))

        # Analytical Jacobian for reaction 6
        def jacobian_rxn6(c, kf, kr, s):
            c1, c2, c3, c4 = c[s[1]], c[s[2]], c[s[3]], c[s[4]]
            J = numpy.zeros((5, 5))

            J[1, 1] = -4 * kf * c1 * c2
            J[1, 2] = -2 * kf * c1 * c1
            J[1, 3] = 4 * kr * c3 * c4
            J[1, 4] = 2 * kr * c3 * c3
            J[2, 1:] = 0.5 * J[1, 1:]
            J[3, 1:] = -J[1, 1:]
            J[4, 1:] = -0.5 * J[1, 1:]
            return J

        # Analytical Jacobian for reaction 7
        def jacobian_rxn7(c, kf, kr, s):
            c1, c2, c3, c4 = c[s[1]], c[s[2]], c[s[3]], c[s[4]]
            J = numpy.zeros((5, 5))

            J[1, 1] = -4 * kr * c1 * c2
            J[1, 2] = -2 * kr * c1 * c1
            J[1, 3] = 4 * kf * c3 * c4
            J[1, 4] = 2 * kf * c3 * c3
            J[2, 1:] = 0.5 * J[1, 1:]
            J[3, 1:] = -J[1, 1:]
            J[4, 1:] = -0.5 * J[1, 1:]
            return J

        for rxn_num, rxn in enumerate(rxnList):
            coreReactions = [rxn]

            rxnSystem0 = LiquidReactor(self.T, c0, 1, termination=[])
            rxnSystem0.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)
            dydt0 = rxnSystem0.residual(0.0, rxnSystem0.y, numpy.zeros(rxnSystem0.y.shape))[0]
            
            dN = .000001*sum(rxnSystem0.y)

            # Let the solver compute the jacobian
            solverJacobian = rxnSystem0.jacobian(0.0, rxnSystem0.y, dydt0, 0.0)

            if rxn_num not in (6, 7):
                dydt = []
                for i in xrange(numCoreSpecies):
                    rxnSystem0.y[i] += dN
                    dydt.append(rxnSystem0.residual(0.0, rxnSystem0.y, numpy.zeros(rxnSystem0.y.shape))[0])
                    rxnSystem0.y[i] -= dN  # reset y

                # Compute the jacobian using finite differences
                jacobian = numpy.zeros((numCoreSpecies, numCoreSpecies))
                for i in xrange(numCoreSpecies):
                    for j in xrange(numCoreSpecies):
                        jacobian[i, j] = (dydt[j][i]-dydt0[i])/dN
                        self.assertAlmostEqual(jacobian[i, j], solverJacobian[i, j], delta=abs(1e-4*jacobian[i, j]))
            # The forward finite difference is very unstable for reactions
            # 6 and 7. Use Jacobians calculated by hand instead.
            elif rxn_num == 6:
                kforward = rxn.getRateCoefficient(self.T)
                kreverse = kforward / rxn.getEquilibriumConstant(self.T)
                jacobian = jacobian_rxn6(c0, kforward, kreverse, coreSpecies)
                for i in xrange(numCoreSpecies):
                    for j in xrange(numCoreSpecies):
                        self.assertAlmostEqual(jacobian[i, j], solverJacobian[i, j], delta=abs(1e-4*jacobian[i, j]))
            elif rxn_num == 7:
                kforward = rxn.getRateCoefficient(self.T)
                kreverse = kforward / rxn.getEquilibriumConstant(self.T)
                jacobian = jacobian_rxn7(c0, kforward, kreverse, coreSpecies)
                for i in xrange(numCoreSpecies):
                    for j in xrange(numCoreSpecies):
                        self.assertAlmostEqual(jacobian[i, j], solverJacobian[i, j], delta=abs(1e-4*jacobian[i, j]))