Ejemplo n.º 1
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
        
        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,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]))
Ejemplo n.º 2
0
    def testListen(self):
        """
        Test that data can be retrieved from an attached ReactionSystem listener.
        """
        #create observable
        reactionSystem = self.rmg.reactionSystems[0]
        reactionSystem.attach(self.listener)

        reactionModel = self.rmg.reactionModel

        self.assertEqual(self.listener.data, [])

        modelSettings = ModelSettings(toleranceMoveToCore=1,
                                      toleranceKeepInEdge=0,
                                      toleranceInterruptSimulation=1)
        simulatorSettings = SimulatorSettings()

        # run simulation:
        terminated, obj, sspcs, srxns = reactionSystem.simulate(
            coreSpecies=reactionModel.core.species,
            coreReactions=reactionModel.core.reactions,
            edgeSpecies=reactionModel.edge.species,
            edgeReactions=reactionModel.edge.reactions,
            surfaceSpecies=[],
            surfaceReactions=[],
            modelSettings=modelSettings,
            simulatorSettings=simulatorSettings,
        )

        self.assertNotEqual(self.listener.data, [])
Ejemplo n.º 3
0
def computeConversion(targetLabel, reactionModel, reactionSystem, atol, rtol):
    """
    Computes the conversion of a target molecule by

    - searching the index of the target species in the core species
    of the global reduction variable
    - resetting the reaction system, initialing with empty variables
    - fetching the initial moles variable y0
    - running the simulation at the conditions stored in the reaction system
    - fetching the computed moles variable y
    - computing conversion
    """

    targetIndex = searchTargetIndex(targetLabel, reactionModel)

    #reset reaction system variables:
    logging.info('No. of rxns in core reactions: {}'.format(len(reactionModel.core.reactions)))
    
    simulatorSettings = SimulatorSettings(atol,rtol)
    
    reactionSystem.initializeModel(\
        reactionModel.core.species, reactionModel.core.reactions,\
        reactionModel.edge.species, reactionModel.edge.reactions, \
        [],[],[],atol=simulatorSettings.atol,rtol=simulatorSettings.rtol,
        sens_atol=simulatorSettings.sens_atol,sens_rtol=simulatorSettings.sens_rtol)

    #get the initial moles:
    y0 = reactionSystem.y.copy()

    #run the simulation:
    simulateOne(reactionModel, atol, rtol, reactionSystem)

    #compute conversion:
    conv = 1 - (reactionSystem.y[targetIndex] / y0[targetIndex])
    return conv
Ejemplo n.º 4
0
    def test_listen(self):
        """
        Test that data can be retrieved from an attached ReactionSystem listener.
        """
        # create observable
        reaction_system = self.rmg.reaction_systems[0]
        reaction_system.attach(self.listener)

        reaction_model = self.rmg.reaction_model

        self.assertEqual(self.listener.data, [])

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

        # run simulation:
        terminated, resurrected, obj, sspcs, srxns, t, conv = reaction_system.simulate(
            core_species=reaction_model.core.species,
            core_reactions=reaction_model.core.reactions,
            edge_species=reaction_model.edge.species,
            edge_reactions=reaction_model.edge.reactions,
            surface_species=[],
            surface_reactions=[],
            model_settings=model_settings,
            simulator_settings=simulator_settings,
        )

        self.assertNotEqual(self.listener.data, [])
Ejemplo n.º 5
0
def simulateOne(reactionModel, atol, rtol, reactionSystem):
    """

    Simulates one reaction system, listener registers results, 
    which are returned at the end.


    The returned data consists of a array of the species names, 
    and the concentration data.

    The concentration data consists of a number of elements for each timestep 
    the solver took to reach the end time of the batch reactor simulation.

    Each element consists of the time and the concentration data of the species at that 
    particular timestep in the order of the species names.

    """

    #register as a listener
    listener = ConcentrationListener()

    coreSpecies = reactionModel.core.species
    regex = r'\([0-9]+\)'  #cut of '(one or more digits)'
    speciesNames = []
    for spc in coreSpecies:
        name = getSpeciesIdentifier(spc)
        name_cutoff = re.split(regex, name)[0]
        speciesNames.append(name_cutoff)

    listener.speciesNames = speciesNames

    reactionSystem.attach(listener)

    pdepNetworks = []
    for source, networks in reactionModel.networkDict.items():
        pdepNetworks.extend(networks)

    simulatorSettings = SimulatorSettings(atol, rtol)
    modelSettings = ModelSettings(toleranceKeepInEdge=0,
                                  toleranceMoveToCore=1,
                                  toleranceInterruptSimulation=1)

    terminated, obj, sspcs, srxns = reactionSystem.simulate(
        coreSpecies=reactionModel.core.species,
        coreReactions=reactionModel.core.reactions,
        edgeSpecies=reactionModel.edge.species,
        edgeReactions=reactionModel.edge.reactions,
        surfaceSpecies=[],
        surfaceReactions=[],
        pdepNetworks=pdepNetworks,
        modelSettings=modelSettings,
        simulatorSettings=simulatorSettings,
    )

    assert terminated

    #unregister as a listener
    reactionSystem.detach(listener)

    return listener.speciesNames, listener.data
Ejemplo n.º 6
0
    def testComputeConversion(self):
        rmg = ReduceFunctionalTest.rmg
        target = ReduceFunctionalTest.targets[0]
        reactionModel = rmg.reactionModel

        simulatorSettings = SimulatorSettings()
        atol, rtol = simulatorSettings.atol, simulatorSettings.rtol

        index = 0
        reactionSystem = rmg.reactionSystems[index]

        conv = computeConversion(target, reactionModel, reactionSystem,\
         rmg.simulatorSettingsList[-1].atol, rmg.simulatorSettingsList[-1].rtol)
        self.assertIsNotNone(conv)
Ejemplo n.º 7
0
    def testReduceCompute(self):
        rmg = ReduceFunctionalTest.rmg
        targets = ReduceFunctionalTest.targets
        reactionModel = rmg.reactionModel

        simulatorSettings = SimulatorSettings()
        atol, rtol = simulatorSettings.atol, simulatorSettings.rtol
        index = 0
        reactionSystem = rmg.reactionSystems[index]
        
        observables = computeObservables(targets, reactionModel, reactionSystem, \
            simulatorSettings.atol, simulatorSettings.rtol)

        tols = [0.7, 1e-3, 1e-6]
        for tol in tols:
            conv, importantRxns = reduceModel(tol, targets, reactionModel, rmg, index)
            self.assertIsNotNone(conv)
Ejemplo n.º 8
0
def computeObservables(targets, reactionModel, reactionSystem, atol, rtol):
    """
    Computes the observables of the targets, provided in the function signature.

    Currently, the species mole fractions at the end time of the
    batch reactor simulation are the only observables that can be computed.

    - resetting the reaction system, initialing with empty variables
    - running the simulation at the conditions stored in the reaction system
    """
    simulatorSettings = SimulatorSettings(atol,rtol)
    reactionSystem.initializeModel(\
        reactionModel.core.species, reactionModel.core.reactions,\
        reactionModel.edge.species, reactionModel.edge.reactions, \
        [],[],[],atol=simulatorSettings.atol,rtol=simulatorSettings.rtol,
        sens_atol=simulatorSettings.sens_atol, sens_rtol=simulatorSettings.sens_rtol)

    #run the simulation:
    simulateOne(reactionModel, atol, rtol, reactionSystem)

    observables = computeMoleFractions(targets, reactionModel, reactionSystem)

    return observables
Ejemplo n.º 9
0
    def sensitivityAnalysis(self,
                            initialMoleFractions,
                            sensitiveSpecies,
                            T,
                            P,
                            terminationTime,
                            sensitivityThreshold=1e-3,
                            number=10,
                            fileformat='.png'):
        """
        Run sensitivity analysis using the RMG solver in a single ReactionSystem object
        
        initialMoleFractions is a dictionary with Species objects as keys and mole fraction initial conditions
        sensitiveSpecies is a list of sensitive Species objects
        number is the number of top species thermo or reaction kinetics desired to be plotted
        """

        from rmgpy.solver import SimpleReactor, TerminationTime
        from rmgpy.quantity import Quantity
        from rmgpy.tools.simulate import plot_sensitivity
        from rmgpy.rmg.listener import SimulationProfileWriter, SimulationProfilePlotter
        from rmgpy.rmg.settings import ModelSettings, SimulatorSettings
        T = Quantity(T)
        P = Quantity(P)
        termination = [TerminationTime(Quantity(terminationTime))]

        reactionSystem = SimpleReactor(T, P, initialMoleFractions, termination,
                                       sensitiveSpecies, sensitivityThreshold)

        # Create the csv worksheets for logging sensitivity
        util.makeOutputSubdirectory(self.outputDirectory, 'solver')
        sensWorksheet = []
        reactionSystemIndex = 0
        for spec in reactionSystem.sensitiveSpecies:
            csvfilePath = os.path.join(
                self.outputDirectory, 'solver',
                'sensitivity_{0}_SPC_{1}.csv'.format(reactionSystemIndex + 1,
                                                     spec.index))
            sensWorksheet.append(csvfilePath)

        reactionSystem.attach(
            SimulationProfileWriter(self.outputDirectory, reactionSystemIndex,
                                    self.speciesList))
        reactionSystem.attach(
            SimulationProfilePlotter(self.outputDirectory, reactionSystemIndex,
                                     self.speciesList))

        simulatorSettings = SimulatorSettings()  #defaults

        modelSettings = ModelSettings()  #defaults
        modelSettings.fluxToleranceMoveToCore = 0.1
        modelSettings.fluxToleranceInterrupt = 1.0
        modelSettings.fluxToleranceKeepInEdge = 0.0

        reactionSystem.simulate(
            coreSpecies=self.speciesList,
            coreReactions=self.reactionList,
            edgeSpecies=[],
            edgeReactions=[],
            surfaceSpecies=[],
            surfaceReactions=[],
            modelSettings=modelSettings,
            simulatorSettings=simulatorSettings,
            sensitivity=True,
            sensWorksheet=sensWorksheet,
        )

        plot_sensitivity(self.outputDirectory,
                         reactionSystemIndex,
                         reactionSystem.sensitiveSpecies,
                         number=number,
                         fileformat=fileformat)
    def testSolve(self):
        """
        Test the simple batch reactor with a simple kinetic model. Here we
        choose a kinetic model consisting of the hydrogen abstraction reaction
        CH4 + C2H5 <=> CH3 + C2H6.
        """
        CH4 = Species(
            molecule=[Molecule().fromSMILES("C")],
            thermo=ThermoData(Tdata=([300,400,500,600,800,1000,1500],"K"), Cpdata=([ 8.615, 9.687,10.963,12.301,14.841,16.976,20.528],"cal/(mol*K)"), H298=(-17.714,"kcal/mol"), S298=(44.472,"cal/(mol*K)"))
            )
        CH3 = Species(
            molecule=[Molecule().fromSMILES("[CH3]")],
            thermo=ThermoData(Tdata=([300,400,500,600,800,1000,1500],"K"), Cpdata=([ 9.397,10.123,10.856,11.571,12.899,14.055,16.195],"cal/(mol*K)"), H298=(  9.357,"kcal/mol"), S298=(45.174,"cal/(mol*K)"))
            )
        C2H6 = Species(
            molecule=[Molecule().fromSMILES("CC")],
            thermo=ThermoData(Tdata=([300,400,500,600,800,1000,1500],"K"), Cpdata=([12.684,15.506,18.326,20.971,25.500,29.016,34.595],"cal/(mol*K)"), H298=(-19.521,"kcal/mol"), S298=(54.799,"cal/(mol*K)"))
            )
        C2H5 = Species(
            molecule=[Molecule().fromSMILES("C[CH2]")],
            thermo=ThermoData(Tdata=([300,400,500,600,800,1000,1500],"K"), Cpdata=([11.635,13.744,16.085,18.246,21.885,24.676,29.107],"cal/(mol*K)"), H298=( 29.496,"kcal/mol"), S298=(56.687,"cal/(mol*K)"))
            )
        

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

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

        T = 1000; P = 1.0e5
        rxnSystem = SimpleReactor(T, P, initialMoleFractions={C2H5: 0.1, CH3: 0.1, CH4: 0.4, C2H6: 0.4}, termination=[])

        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)
            # 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)
        y = numpy.array(y, numpy.float64)
        reactionRates = numpy.array(reactionRates, numpy.float64)
        speciesRates = numpy.array(speciesRates, numpy.float64)
        V = constants.R * rxnSystem.T.value_si * numpy.sum(y) / rxnSystem.P.value_si       

        # Check that we're computing the species fluxes correctly
        for i in range(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)
        
        #######        
        # Unit test for the jacobian function:
        # Solve a reaction system and check if the analytical jacobian matches the finite difference jacobian
        
        H2 = Species(
            molecule=[Molecule().fromSMILES("[H][H]")],
            thermo=ThermoData(Tdata=([300,400,500,600,800,1000,1500],"K"), Cpdata=([6.89,6.97,6.99,7.01,7.08,7.22,7.72],"cal/(mol*K)"), H298=( 0,"kcal/mol"), S298=(31.23,"cal/(mol*K)"))
            )
        
        rxnList = []
        rxnList.append(Reaction(reactants=[C2H6], products=[CH3,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=[CH3,CH3], products=[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=[C2H6,CH3], products=[C2H5,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=[C2H5,CH4], products=[C2H6,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=[C2H5,CH4], products=[CH3,CH3,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=[CH3,CH3,CH3], products=[C2H5,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=[C2H6,CH3,CH3], products=[C2H5,C2H5,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=[C2H5,C2H5,H2], products=[C2H6,CH3,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=[C2H6,C2H6], products=[CH3,CH4,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=[CH3,CH4,C2H5], products=[C2H6,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 = [CH4,CH3,C2H6,C2H5,H2]
            edgeSpecies = []
            coreReactions = [rxn]
            
            rxnSystem0 = SimpleReactor(T,P,initialMoleFractions={CH4:0.2,CH3:0.1,C2H6:0.35,C2H5:0.15, H2:0.2},termination=[])
            rxnSystem0.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions)
            dydt0 = rxnSystem0.residual(0.0, rxnSystem0.y, numpy.zeros(rxnSystem0.y.shape))[0]
            numCoreSpecies = len(coreSpecies)
            dN = .000001*sum(rxnSystem0.y)
            dN_array = dN*numpy.eye(numCoreSpecies)
            
            dydt = []
            for i in range(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 range(numCoreSpecies):
                for j in range(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]))
        
        #print 'Solver jacobian'
        #print solverJacobian
        #print 'Numerical jacobian'
        #print jacobian
        
        ###
        # Unit test for the compute rate derivative
        rxnList = []
        rxnList.append(Reaction(reactants=[C2H6], products=[CH3,CH3], kinetics=Arrhenius(A=(686.375e6,'1/s'), n=4.40721, Ea=(7.82799,'kcal/mol'), T0=(298.15,'K')))) 
        rxnList.append(Reaction(reactants=[C2H6,CH3], products=[C2H5,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=[C2H6,CH3,CH3], products=[C2H5,C2H5,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 = [CH4,CH3,C2H6,C2H5,H2]
        edgeSpecies = []
        coreReactions = rxnList
        
        rxnSystem0 = SimpleReactor(T,P,initialMoleFractions={CH4:0.2,CH3:0.1,C2H6:0.35,C2H5:0.15, H2:0.2},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')))
        modelSettings = ModelSettings(toleranceKeepInEdge = 0,toleranceMoveToCore=1,toleranceInterruptSimulation=0)
        simulatorSettings = SimulatorSettings()
        rxnSystem0.simulate(coreSpecies, coreReactions, [], [], [],[], modelSettings = modelSettings, simulatorSettings=simulatorSettings)

        y0 = rxnSystem0.y
        
        dfdk = numpy.zeros((numCoreSpecies,len(rxnList)))   # d(dy/dt)/dk
        
        for i in range(len(rxnList)):
            k0 = rxnList[i].getRateCoefficient(T,P)
            rxnList[i].kinetics.A.value_si = rxnList[i].kinetics.A.value_si*(1+1e-3)               
            dk = rxnList[i].getRateCoefficient(T,P) - k0

            rxnSystem = SimpleReactor(T,P,initialMoleFractions={CH4:0.2,CH3:0.1,C2H6:0.35,C2H5:0.15, H2:0.2},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 range(numCoreSpecies):
            for j in range(len(rxnList)):
                self.assertAlmostEqual(dfdk[i,j], solver_dfdk[i,j], delta=abs(1e-3*dfdk[i,j]))
Ejemplo n.º 11
0
    def sensitivity_analysis(self,
                             initial_mole_fractions,
                             sensitive_species,
                             T,
                             P,
                             termination_time,
                             sensitivity_threshold=1e-3,
                             number=10,
                             fileformat='.png'):
        """
        Run sensitivity analysis using the RMG solver in a single ReactionSystem object
        
        initial_mole_fractions is a dictionary with Species objects as keys and mole fraction initial conditions
        sensitive_species is a list of sensitive Species objects
        number is the number of top species thermo or reaction kinetics desired to be plotted
        """

        from rmgpy.solver import SimpleReactor, TerminationTime
        from rmgpy.quantity import Quantity
        from rmgpy.rmg.listener import SimulationProfileWriter, SimulationProfilePlotter
        from rmgpy.rmg.settings import ModelSettings, SimulatorSettings
        T = Quantity(T)
        P = Quantity(P)
        termination = [TerminationTime(Quantity(termination_time))]

        reaction_system = SimpleReactor(
            T=T,
            P=P,
            initial_mole_fractions=initial_mole_fractions,
            termination=termination,
            sensitive_species=sensitive_species,
            sensitivity_threshold=sensitivity_threshold)

        # Create the csv worksheets for logging sensitivity
        util.make_output_subdirectory(self.output_directory, 'solver')
        sens_worksheet = []
        reaction_system_index = 0
        for spec in reaction_system.sensitive_species:
            csvfile_path = os.path.join(
                self.output_directory, 'solver',
                'sensitivity_{0}_SPC_{1}.csv'.format(reaction_system_index + 1,
                                                     spec.index))
            sens_worksheet.append(csvfile_path)

        reaction_system.attach(
            SimulationProfileWriter(self.output_directory,
                                    reaction_system_index, self.species_list))
        reaction_system.attach(
            SimulationProfilePlotter(self.output_directory,
                                     reaction_system_index, self.species_list))

        simulator_settings = SimulatorSettings()  # defaults

        model_settings = ModelSettings()  # defaults
        model_settings.tol_move_to_core = 0.1
        model_settings.tol_interrupt_simulation = 1.0
        model_settings.tol_keep_in_edge = 0.0

        reaction_system.simulate(
            core_species=self.species_list,
            core_reactions=self.reaction_list,
            edge_species=[],
            edge_reactions=[],
            surface_species=[],
            surface_reactions=[],
            model_settings=model_settings,
            simulator_settings=simulator_settings,
            sensitivity=True,
            sens_worksheet=sens_worksheet,
        )

        plot_sensitivity(self.output_directory,
                         reaction_system_index,
                         reaction_system.sensitive_species,
                         number=number,
                         fileformat=fileformat)
Ejemplo n.º 12
0
def simulate(reactionModel, reactionSystem, settings=None):
    """
    Generate and return a set of core and edge species and reaction fluxes
    by simulating the given `reactionSystem` using the given `reactionModel`.
    """
    global maximumNodeCount, maximumEdgeCount, timeStep, concentrationTolerance, speciesRateTolerance
    # Allow user defined settings for flux diagram generation if given
    if settings:
        maximumNodeCount = settings['maximumNodeCount']
        maximumEdgeCount = settings['maximumEdgeCount']
        timeStep = settings['timeStep']
        concentrationTolerance = settings['concentrationTolerance']
        speciesRateTolerance = settings['speciesRateTolerance']

    coreSpecies = reactionModel.core.species
    coreReactions = reactionModel.core.reactions
    edgeSpecies = reactionModel.edge.species
    edgeReactions = reactionModel.edge.reactions

    #    numCoreSpecies = len(coreSpecies)
    #    numCoreReactions = len(coreReactions)
    #    numEdgeSpecies = len(edgeSpecies)
    #    numEdgeReactions = len(edgeReactions)

    speciesIndex = {}
    for index, spec in enumerate(coreSpecies):
        speciesIndex[spec] = index

    simulatorSettings = SimulatorSettings(atol=absoluteTolerance,
                                          rtol=relativeTolerance)

    reactionSystem.initializeModel(coreSpecies,
                                   coreReactions,
                                   edgeSpecies,
                                   edgeReactions, [], [], [],
                                   atol=simulatorSettings.atol,
                                   rtol=simulatorSettings.rtol,
                                   sens_atol=simulatorSettings.sens_atol,
                                   sens_rtol=simulatorSettings.sens_rtol)

    # Copy the initial conditions to use in evaluating conversions
    y0 = reactionSystem.y.copy()

    time = []
    coreSpeciesConcentrations = []
    coreReactionRates = []
    edgeReactionRates = []

    nextTime = initialTime
    terminated = False
    iteration = 0
    while not terminated:
        # Integrate forward in time to the next time point
        reactionSystem.advance(nextTime)

        iteration += 1

        time.append(reactionSystem.t)
        coreSpeciesConcentrations.append(
            reactionSystem.coreSpeciesConcentrations)
        coreReactionRates.append(reactionSystem.coreReactionRates)
        edgeReactionRates.append(reactionSystem.edgeReactionRates)

        # Finish simulation if any of the termination criteria are satisfied
        for term in reactionSystem.termination:
            if isinstance(term, TerminationTime):
                if reactionSystem.t > term.time.value_si:
                    terminated = True
                    break
            elif isinstance(term, TerminationConversion):
                index = speciesIndex[term.species]
                if (y0[index] -
                        reactionSystem.y[index]) / y0[index] > term.conversion:
                    terminated = True
                    break

        # Increment destination step time if necessary
        if reactionSystem.t >= 0.9999 * nextTime:
            nextTime *= timeStep

    time = numpy.array(time)
    coreSpeciesConcentrations = numpy.array(coreSpeciesConcentrations)
    coreReactionRates = numpy.array(coreReactionRates)
    edgeReactionRates = numpy.array(edgeReactionRates)

    return time, coreSpeciesConcentrations, coreReactionRates, edgeReactionRates
Ejemplo n.º 13
0
def simulate(reactionModel, reactionSystem, settings=None):
    """
    Generate and return a set of core and edge species and reaction fluxes
    by simulating the given `reactionSystem` using the given `reactionModel`.
    """
    global timeStep
    # Allow user defined settings for flux diagram generation if given
    if settings:
        timeStep = settings.get('timeStep', timeStep)
    
    coreSpecies = reactionModel.core.species
    coreReactions = reactionModel.core.reactions
    edgeSpecies = reactionModel.edge.species
    edgeReactions = reactionModel.edge.reactions
    
    speciesIndex = {}
    for index, spec in enumerate(coreSpecies):
        speciesIndex[spec] = index
    
    simulatorSettings = SimulatorSettings(atol=absoluteTolerance,rtol=relativeTolerance)

    # Enable constant species for LiquidReactor
    if isinstance(reactionSystem, LiquidReactor):
        if reactionSystem.constSPCNames is not None:
            reactionSystem.get_constSPCIndices(coreSpecies)

    reactionSystem.initializeModel(coreSpecies, coreReactions, edgeSpecies, edgeReactions,
                                   atol=simulatorSettings.atol, rtol=simulatorSettings.rtol,
                                   sens_atol=simulatorSettings.sens_atol, sens_rtol=simulatorSettings.sens_rtol,conditions=None)

    # Copy the initial conditions to use in evaluating conversions
    y0 = reactionSystem.y.copy()

    time = []
    coreSpeciesConcentrations = []
    coreReactionRates = []
    edgeReactionRates = []

    nextTime = initialTime
    terminated = False
    while not terminated:
        # Integrate forward in time to the next time point
        reactionSystem.advance(nextTime)
        
        time.append(reactionSystem.t)
        coreSpeciesConcentrations.append(reactionSystem.coreSpeciesConcentrations)
        coreReactionRates.append(reactionSystem.coreReactionRates)
        edgeReactionRates.append(reactionSystem.edgeReactionRates)
        
        # Finish simulation if any of the termination criteria are satisfied
        for term in reactionSystem.termination:
            if isinstance(term, TerminationTime):
                if reactionSystem.t > term.time.value_si:
                    terminated = True
                    break
            elif isinstance(term, TerminationConversion):
                index = speciesIndex[term.species]
                if (y0[index] - reactionSystem.y[index]) / y0[index] > term.conversion:
                    terminated = True
                    break

        # Increment destination step time if necessary
        if reactionSystem.t >= 0.9999 * nextTime:
            nextTime *= timeStep

    time = numpy.array(time)
    coreSpeciesConcentrations = numpy.array(coreSpeciesConcentrations)
    coreReactionRates = numpy.array(coreReactionRates)
    edgeReactionRates = numpy.array(edgeReactionRates)
    
    return time, coreSpeciesConcentrations, coreReactionRates, edgeReactionRates
Ejemplo n.º 14
0
def simulator(atol, rtol, sens_atol=1e-6, sens_rtol=1e-4):
    rmg.simulatorSettingsList.append(SimulatorSettings(atol, rtol, sens_atol, sens_rtol))