Example #1
0
    def test_storeConstantSpeciesNames(self):
        "Test if (i) constant species names are stored in reactor attributes and (ii) if attributes are not mix/equal for multiple conditions generation"

        c0 = {self.C2H5: 0.1, self.CH3: 0.1, self.CH4: 0.4, self.C2H6: 0.4}
        Temp = 1000
        #
        #set up the liquid phase reactor 1
        terminationConversion = []
        terminationTime = None
        sensitivity = []
        sensitivityThreshold = 0.001
        constantSpecies = ["CH4", "C2H6"]
        rxnSystem1 = LiquidReactor(Temp, c0, terminationConversion,
                                   sensitivity, sensitivityThreshold,
                                   constantSpecies)

        #set up the liquid phase reactor 2
        constantSpecies = ["O2", "H2O"]
        rxnSystem2 = LiquidReactor(Temp, c0, terminationConversion,
                                   sensitivity, sensitivityThreshold,
                                   constantSpecies)
        for reactor in [rxnSystem1, rxnSystem2]:
            self.assertIsNotNone(reactor.constSPCNames)

        #check if Constant species are different in each liquid system
        for spc in rxnSystem1.constSPCNames:
            for spc2 in rxnSystem2.constSPCNames:
                self.assertIsNot(
                    spc, spc2,
                    "Constant species declared in two different reactors seem mixed. Species \"{0}\" appears in both systems and should be."
                    .format(spc))
    def testComputeFlux(self):
        """
        Test the liquid batch reactor with a simple kinetic model. 
        """
        
        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'))
        )

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

        c0 = {self.C2H5: 0.1, self.CH3: 0.1, self.CH4: 0.4, self.C2H6: 0.4}

        rxnSystem = LiquidReactor(self.T, c0, 1, termination=[])

        rxnSystem.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)

        tlist = numpy.array([10**(i/10.0) for i in xrange(-130, -49)], numpy.float64)

        # Integrate to get the solution at each time point
        t, y, reactionRates, speciesRates = [], [], [], []
        for t1 in tlist:
            rxnSystem.advance(t1)
            t.append(rxnSystem.t)
            # You must make a copy of y because it is overwritten by DASSL at
            # each call to advance()
            y.append(rxnSystem.y.copy())
            reactionRates.append(rxnSystem.coreReactionRates.copy())
            speciesRates.append(rxnSystem.coreSpeciesRates.copy())

        # Convert the solution vectors to numpy arrays
        t = numpy.array(t, numpy.float64)
        reactionRates = numpy.array(reactionRates, numpy.float64)
        speciesRates = numpy.array(speciesRates, numpy.float64)

        # Check that we're computing the species fluxes correctly
        for i in xrange(t.shape[0]):
            self.assertAlmostEqual(reactionRates[i, 0], speciesRates[i, 0], delta=1e-6*reactionRates[i, 0])
            self.assertAlmostEqual(reactionRates[i, 0], -speciesRates[i, 1], delta=1e-6*reactionRates[i, 0])
            self.assertAlmostEqual(reactionRates[i, 0], -speciesRates[i, 2], delta=1e-6*reactionRates[i, 0])
            self.assertAlmostEqual(reactionRates[i, 0], speciesRates[i, 3], delta=1e-6*reactionRates[i, 0])
        
        # Check that we've reached equilibrium 
        self.assertAlmostEqual(reactionRates[-1, 0], 0.0, delta=1e-2)
Example #3
0
def liquidReactor(temperature,
                  initialConcentrations,
                  terminationConversion=None,
                  terminationTime=None,
                  sensitivity=None,
                  sensitivityThreshold=1e-3):

    logging.debug('Found LiquidReactor reaction system')
    T = Quantity(temperature)
    for spec, conc in initialConcentrations.iteritems():
        concentration = Quantity(conc)
        # check the dimensions are ok
        # convert to mol/m^3 (or something numerically nice? or must it be SI)
        initialConcentrations[spec] = concentration.value_si
    termination = []
    if terminationConversion is not None:
        for spec, conv in terminationConversion.iteritems():
            termination.append(TerminationConversion(speciesDict[spec], conv))
    if terminationTime is not None:
        termination.append(TerminationTime(Quantity(terminationTime)))
    if len(termination) == 0:
        raise InputError(
            'No termination conditions specified for reaction system #{0}.'.
            format(len(rmg.reactionSystems) + 2))

    sensitiveSpecies = []
    if sensitivity:
        for spec in sensitivity:
            sensitiveSpecies.append(speciesDict[spec])
    system = LiquidReactor(T, initialConcentrations, termination,
                           sensitiveSpecies, sensitivityThreshold)
    rmg.reactionSystems.append(system)
Example #4
0
    def test_corespeciesRate(self):
        "Test if a specific core species rate is equal to 0 over time"    
                
        c0={self.C2H5: 0.1, self.CH3: 0.1, self.CH4: 0.4, self.C2H6: 0.4}
        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')))
 
        coreSpecies = [self.CH4,self.CH3,self.C2H6,self.C2H5]
        edgeSpecies = []
        coreReactions = [rxn1]
        edgeReactions = []
        sensitivity=[]
        terminationConversion = []
        sensitivityThreshold=0.001
        ConstSpecies = ["CH4"]
        
        rxnSystem = LiquidReactor(self.T, c0, terminationConversion, sensitivity,sensitivityThreshold,ConstSpecies)
        ##The test regarding the writting of constantSPCindices from input file is check with the previous test.
        rxnSystem.constSPCIndices=[0]
        
        rxnSystem.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)
 
        tlist = numpy.array([10**(i/10.0) for i in range(-130, -49)], numpy.float64)
 
        # Integrate to get the solution at each time point
        t = []; y = []; reactionRates = []; speciesRates = []
        for t1 in tlist:
            rxnSystem.advance(t1)
            t.append(rxnSystem.t)
            self.assertEqual(rxnSystem.coreSpeciesRates[0], 0,"Core species rate has to be equal to 0 for species hold constant. Here it is equal to {0}".format(rxnSystem.coreSpeciesRates[0]))
Example #5
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]))
Example #6
0
    def test_compute_flux(self):
        """
        Test the liquid batch reactor with a simple kinetic model. 
        """

        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')))

        core_species = [self.CH4, self.CH3, self.C2H6, self.C2H5]
        edge_species = []
        core_reactions = [rxn1]
        edge_reactions = []

        c0 = {self.C2H5: 0.1, self.CH3: 0.1, self.CH4: 0.4, self.C2H6: 0.4}

        rxn_system = LiquidReactor(self.T, c0, 1, termination=[])

        rxn_system.initialize_model(core_species, core_reactions, edge_species,
                                    edge_reactions)

        tlist = np.array([10**(i / 10.0) for i in range(-130, -49)],
                         np.float64)

        # Integrate to get the solution at each time point
        t, y, reaction_rates, species_rates = [], [], [], []
        for t1 in tlist:
            rxn_system.advance(t1)
            t.append(rxn_system.t)
            # You must make a copy of y because it is overwritten by DASSL at
            # each call to advance()
            y.append(rxn_system.y.copy())
            reaction_rates.append(rxn_system.core_reaction_rates.copy())
            species_rates.append(rxn_system.core_species_rates.copy())

        # Convert the solution vectors to np arrays
        t = np.array(t, np.float64)
        reaction_rates = np.array(reaction_rates, np.float64)
        species_rates = np.array(species_rates, np.float64)

        # Check that we're computing the species fluxes correctly
        for i in range(t.shape[0]):
            self.assertAlmostEqual(reaction_rates[i, 0],
                                   species_rates[i, 0],
                                   delta=1e-6 * reaction_rates[i, 0])
            self.assertAlmostEqual(reaction_rates[i, 0],
                                   -species_rates[i, 1],
                                   delta=1e-6 * reaction_rates[i, 0])
            self.assertAlmostEqual(reaction_rates[i, 0],
                                   -species_rates[i, 2],
                                   delta=1e-6 * reaction_rates[i, 0])
            self.assertAlmostEqual(reaction_rates[i, 0],
                                   species_rates[i, 3],
                                   delta=1e-6 * reaction_rates[i, 0])

        # Check that we've reached equilibrium
        self.assertAlmostEqual(reaction_rates[-1, 0], 0.0, delta=1e-2)
Example #7
0
    def test_corespeciesRate(self):
        """
        Test if a specific core species rate is equal to 0 over time.
        """
                
        c0 = {self.C2H5: 0.1, self.CH3: 0.1, self.CH4: 0.4, self.C2H6: 0.4}
        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'))
        )
 
        coreSpecies = [self.CH4, self.CH3, self.C2H6, self.C2H5]
        edgeSpecies = []
        coreReactions = [rxn1]
        edgeReactions = []
        sensitivity = []
        terminationConversion = []
        sensitivityThreshold = 0.001
        ConstSpecies = ["CH4"]
        
        rxnSystem = LiquidReactor(self.T, c0, terminationConversion, sensitivity, sensitivityThreshold, ConstSpecies)
        # The test regarding the writing of constantSPCindices from input file is check with the previous test.
        rxnSystem.constSPCIndices = [0]
        
        rxnSystem.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)
 
        tlist = numpy.array([10**(i/10.0) for i in range(-130, -49)], numpy.float64)
 
        # Integrate to get the solution at each time point
        t, y, reactionRates, speciesRates = [], [], [], []
        for t1 in tlist:
            rxnSystem.advance(t1)
            t.append(rxnSystem.t)
            self.assertEqual(rxnSystem.coreSpeciesRates[0], 0, "Core species rate has to be equal to 0 for species hold constant. Here it is equal to {0}".format(rxnSystem.coreSpeciesRates[0]))
Example #8
0
    def test_store_constant_species_names(self):
        """
        Test if (i) constant species names are stored in reactor attributes and
        (ii) if attributes are not mix/equal for multiple conditions generation.
        """

        c0 = {self.C2H5: 0.1, self.CH3: 0.1, self.CH4: 0.4, self.C2H6: 0.4}
        temp = 1000

        # set up the liquid phase reactor 1
        termination_conversion = []
        termination_time = None
        sensitivity = []
        sensitivity_threshold = 0.001
        constant_species = ["CH4", "C2H6"]
        sens_conds = None
        rxn_system1 = LiquidReactor(temp, c0, 4, termination_conversion,
                                    sensitivity, sensitivity_threshold,
                                    sens_conds, constant_species)

        # set up the liquid phase reactor 2
        constant_species = ["O2", "H2O"]
        rxn_system2 = LiquidReactor(temp, c0, 4, termination_conversion,
                                    sensitivity, sensitivity_threshold,
                                    sens_conds, constant_species)
        for reactor in [rxn_system1, rxn_system2]:
            self.assertIsNotNone(reactor.const_spc_names)

        # check if Constant species are different in each liquid system
        for spc in rxn_system1.const_spc_names:
            for spc2 in rxn_system2.const_spc_names:
                self.assertIsNot(
                    spc, spc2,
                    'Constant species declared in two different reactors seem mixed. '
                    'Species "{0}" appears in both systems and should be.'.
                    format(spc))
Example #9
0
    def test_compute_derivative(self):
        rxn_list = [
            Reaction(reactants=[self.C2H6],
                     products=[self.CH3, self.CH3],
                     kinetics=Arrhenius(A=(686.375e6, '1/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.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'))),
        ]

        core_species = [self.CH4, self.CH3, self.C2H6, self.C2H5, self.H2]
        edge_species = []
        core_reactions = rxn_list
        edge_reactions = []
        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
        }

        rxn_system0 = LiquidReactor(self.T, c0, 1, termination=[])
        rxn_system0.initialize_model(core_species, core_reactions,
                                     edge_species, edge_reactions)
        dfdt0 = rxn_system0.residual(0.0, rxn_system0.y,
                                     np.zeros(rxn_system0.y.shape))[0]
        solver_dfdk = rxn_system0.compute_rate_derivative()
        # print 'Solver d(dy/dt)/dk'
        # print solver_dfdk

        integration_time = 1e-8

        model_settings = ModelSettings(tol_keep_in_edge=0,
                                       tol_move_to_core=1,
                                       tol_interrupt_simulation=0)
        simulator_settings = SimulatorSettings()

        rxn_system0.termination.append(TerminationTime(
            (integration_time, 's')))

        rxn_system0.simulate(core_species,
                             core_reactions, [], [], [], [],
                             model_settings=model_settings,
                             simulator_settings=simulator_settings)

        y0 = rxn_system0.y

        dfdk = np.zeros((num_core_species, len(rxn_list)))  # d(dy/dt)/dk

        c0 = {
            self.CH4: 0.2,
            self.CH3: 0.1,
            self.C2H6: 0.35,
            self.C2H5: 0.15,
            self.H2: 0.2
        }

        for i in range(len(rxn_list)):
            k0 = rxn_list[i].get_rate_coefficient(self.T)
            rxn_list[i].kinetics.A.value_si = rxn_list[
                i].kinetics.A.value_si * (1 + 1e-3)
            dk = rxn_list[i].get_rate_coefficient(self.T) - k0

            rxn_system = LiquidReactor(self.T, c0, 1, termination=[])
            rxn_system.initialize_model(core_species, core_reactions,
                                        edge_species, edge_reactions)

            dfdt = rxn_system.residual(0.0, rxn_system.y,
                                       np.zeros(rxn_system.y.shape))[0]
            dfdk[:, i] = (dfdt - dfdt0) / dk

            rxn_system.termination.append(
                TerminationTime((integration_time, 's')))
            model_settings = ModelSettings(tol_keep_in_edge=0,
                                           tol_move_to_core=1,
                                           tol_interrupt_simulation=0)
            simulator_settings = SimulatorSettings()
            rxn_system.simulate(core_species,
                                core_reactions, [], [], [], [],
                                model_settings=model_settings,
                                simulator_settings=simulator_settings)

            rxn_list[i].kinetics.A.value_si = rxn_list[
                i].kinetics.A.value_si / (1 + 1e-3)  # reset A factor

        for i in range(num_core_species):
            for j in range(len(rxn_list)):
                self.assertAlmostEqual(dfdk[i, j],
                                       solver_dfdk[i, j],
                                       delta=abs(1e-3 * dfdk[i, j]))
Example #10
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_compute_derivative(self):
        rxnList = []
        rxnList.append(Reaction(
            reactants=[self.C2H6],
            products=[self.CH3, self.CH3],
            kinetics=Arrhenius(A=(686.375e6, '1/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.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'))
        ))
        
        coreSpecies = [self.CH4, self.CH3, self.C2H6, self.C2H5, self.H2]
        edgeSpecies = []
        coreReactions = rxnList
        edgeReactions = []
        numCoreSpecies = len(coreSpecies)
        
        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, 1, termination=[])
        rxnSystem0.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)
        dfdt0 = rxnSystem0.residual(0.0, rxnSystem0.y, numpy.zeros(rxnSystem0.y.shape))[0]
        solver_dfdk = rxnSystem0.computeRateDerivative()
        # print 'Solver d(dy/dt)/dk'
        # print solver_dfdk
        
        integrationTime = 1e-8
        
        modelSettings = ModelSettings(toleranceKeepInEdge=0, toleranceMoveToCore=1, toleranceInterruptSimulation=0)
        simulatorSettings = SimulatorSettings()
        
        rxnSystem0.termination.append(TerminationTime((integrationTime, 's')))
        
        rxnSystem0.simulate(coreSpecies, coreReactions, [], [], [], [],
                            modelSettings=modelSettings, simulatorSettings=simulatorSettings)

        y0 = rxnSystem0.y
        
        dfdk = numpy.zeros((numCoreSpecies, len(rxnList)))   # d(dy/dt)/dk
        
        c0 = {self.CH4: 0.2, self.CH3: 0.1, self.C2H6: 0.35, self.C2H5: 0.15, self.H2: 0.2}

        for i in xrange(len(rxnList)):
            k0 = rxnList[i].getRateCoefficient(self.T)
            rxnList[i].kinetics.A.value_si = rxnList[i].kinetics.A.value_si*(1+1e-3)               
            dk = rxnList[i].getRateCoefficient(self.T) - k0

            rxnSystem = LiquidReactor(self.T, c0, 1, termination=[])
            rxnSystem.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)

            dfdt = rxnSystem.residual(0.0, rxnSystem.y, numpy.zeros(rxnSystem.y.shape))[0]  
            dfdk[:, i] = (dfdt-dfdt0)/dk

            rxnSystem.termination.append(TerminationTime((integrationTime, 's')))
            modelSettings = ModelSettings(toleranceKeepInEdge=0, toleranceMoveToCore=1, toleranceInterruptSimulation=0)
            simulatorSettings = SimulatorSettings()
            rxnSystem.simulate(coreSpecies, coreReactions, [], [], [], [],
                               modelSettings=modelSettings, simulatorSettings=simulatorSettings)
            
            rxnList[i].kinetics.A.value_si = rxnList[i].kinetics.A.value_si/(1+1e-3)  # reset A factor
            
        for i in xrange(numCoreSpecies):
            for j in xrange(len(rxnList)):
                self.assertAlmostEqual(dfdk[i, j], solver_dfdk[i, j], delta=abs(1e-3*dfdk[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]))
Example #13
0
def liquidReactor(temperature,
                  initialConcentrations,
                  terminationConversion=None,
                  nSimsTerm = 4,
                  terminationTime=None,
                  terminationRateRatio=None,
                  sensitivity=None,
                  sensitivityThreshold=1e-3,
                  sensitivityTemperature=None,
                  sensitivityConcentrations=None,
                  constantSpecies=None):
    
    logging.debug('Found LiquidReactor reaction system')
    
    if not isinstance(temperature,list):
        T = Quantity(temperature)
    else:
        if len(temperature) != 2:
            raise InputError('Temperature and pressure ranges can either be in the form of (number,units) or a list with 2 entries of the same format')
        T = [Quantity(t) for t in temperature]
    
    for spec,conc in initialConcentrations.iteritems():
        if not isinstance(conc,list):
            concentration = Quantity(conc)
            # check the dimensions are ok
            # convert to mol/m^3 (or something numerically nice? or must it be SI)
            initialConcentrations[spec] = concentration.value_si
        else:
            if len(conc) != 2:
                raise InputError("Concentration values must either be in the form of (number,units) or a list with 2 entries of the same format")
            initialConcentrations[spec] = [Quantity(conc[0]),Quantity(conc[1])]
            
    if not isinstance(temperature,list) and all([not isinstance(x,list) for x in initialConcentrations.itervalues()]):
        nSimsTerm=1
        
    termination = []
    if terminationConversion is not None:
        for spec, conv in terminationConversion.iteritems():
            termination.append(TerminationConversion(speciesDict[spec], conv))
    if terminationTime is not None:
        termination.append(TerminationTime(Quantity(terminationTime)))
    if terminationRateRatio is not None:
        termination.append(TerminationRateRatio(terminationRateRatio))
    if len(termination) == 0:
        raise InputError('No termination conditions specified for reaction system #{0}.'.format(len(rmg.reactionSystems)+2))
    
    sensitiveSpecies = []
    if sensitivity:
        for spec in sensitivity:
            sensitiveSpecies.append(speciesDict[spec])
    
    ##chatelak: check the constant species exist
    if constantSpecies is not None:
        logging.debug('  Generation with constant species:')
        for constantSpecie in constantSpecies:
            logging.debug("  {0}".format(constantSpecie))
            if not speciesDict.has_key(constantSpecie):
                raise InputError('Species {0} not found in the input file'.format(constantSpecie))
    
    if not isinstance(T,list):
        sensitivityTemperature = T
    if not any([isinstance(x,list) for x in initialConcentrations.itervalues()]):
        sensitivityConcentrations = initialConcentrations
    if sensitivityConcentrations is None or sensitivityTemperature is None:
        sensConditions = None
    else:
        sensConditions = sensitivityConcentrations
        sensConditions['T'] = Quantity(sensitivityTemperature).value_si
        
    system = LiquidReactor(T, initialConcentrations, nSimsTerm, termination, sensitiveSpecies, sensitivityThreshold, sensConditions, constantSpecies)
    rmg.reactionSystems.append(system)
Example #14
0
    def test_compute_derivative(self):

        rxnList = []
        rxnList.append(Reaction(reactants=[self.C2H6], products=[self.CH3,self.CH3], kinetics=Arrhenius(A=(686.375e6,'1/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.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'))))
        
        
        coreSpecies = [self.CH4,self.CH3,self.C2H6,self.C2H5, self.H2]
        edgeSpecies = []
        coreReactions = rxnList
        edgeReactions = []
        numCoreSpecies = len(coreSpecies)
        
        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)
        dfdt0 = rxnSystem0.residual(0.0, rxnSystem0.y, numpy.zeros(rxnSystem0.y.shape))[0]
        solver_dfdk = rxnSystem0.computeRateDerivative()
        #print 'Solver d(dy/dt)/dk'
        #print solver_dfdk
        
        integrationTime = 1e-8
        rxnSystem0.termination.append(TerminationTime((integrationTime,'s')))
        rxnSystem0.simulate(coreSpecies, coreReactions, [], [], 0, 1, 0)

        y0 = rxnSystem0.y
        
        dfdk = numpy.zeros((numCoreSpecies,len(rxnList)))   # d(dy/dt)/dk
        
        c0={self.CH4:0.2,self.CH3:0.1,self.C2H6:0.35,self.C2H5:0.15, self.H2:0.2}

        for i in xrange(len(rxnList)):
            k0 = rxnList[i].getRateCoefficient(self.T)
            rxnList[i].kinetics.A.value_si = rxnList[i].kinetics.A.value_si*(1+1e-3)               
            dk = rxnList[i].getRateCoefficient(self.T) - k0

            rxnSystem = LiquidReactor(self.T, c0,termination=[])
            rxnSystem.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)

            dfdt = rxnSystem.residual(0.0, rxnSystem.y, numpy.zeros(rxnSystem.y.shape))[0]  
            dfdk[:,i]=(dfdt-dfdt0)/dk          
            
            
            rxnSystem.termination.append(TerminationTime((integrationTime,'s')))
            rxnSystem.simulate(coreSpecies, coreReactions, [], [], 0, 1, 0)
            
            rxnList[i].kinetics.A.value_si = rxnList[i].kinetics.A.value_si/(1+1e-3)  # reset A factor
            
        for i in xrange(numCoreSpecies):
            for j in xrange(len(rxnList)):
                self.assertAlmostEqual(dfdk[i,j], solver_dfdk[i,j], delta=abs(1e-3*dfdk[i,j]))