def calcRf(spc, reactions, reactantOrProduct, T, P, coreSpeciesConcentrations, formationOrConsumption): """ Calculates the total rate of formation/consumption of species i. Computes the sum of the rates of formation/consumption of spc for all of the reactions in which spc is a product. if formationOrConsumption == 'formation', spc will be compared to the products of the reaction. Else, spc will be compared to the reactants of the reaction. units of rate: mol/(m^3.s) """ rate = 0.0 for reaction in reactions: molecules = reaction.products if formationOrConsumption == 'formation:' else reaction.reactants labels = [mol.label for mol in molecules] if spc.label in labels: rij = calcRij(reaction, spc, reactantOrProduct, T, P, coreSpeciesConcentrations) rate = rate + rij logging.debug('Rf: {rate}'.format(**locals())) return rate
def assessReaction(rxn, reactionSystems, tolerance, data): """ Returns whether the reaction is important or not in the reactions. It iterates over the reaction systems, and loads the concentration profile of each reaction system. It iterates over a number of samples in profile and evaluates the importance of the reaction at every sample. """ logging.debug('Assessing reaction {}'.format(rxn)) reactions = retrieveReactions() # read in the intermediate state variables for datum, reactionSystem in zip(data, reactionSystems): T, P = reactionSystem.T.value_si, reactionSystem.P.value_si speciesNames, profile = datum # take N evenly spaced indices from the table with simulation results: """ Number of time steps between start and end time of the batch reactor simulation at which the importance of reactions should be evaluated. The more timesteps, the less chance we have to remove an important reactions, but the more simulations need to be carried out. """ timesteps = len(profile) / 2 logging.debug('Evaluating the importance of a reaction at {} time samples.'.format(timesteps)) assert timesteps <= len(profile) indices = map(int, np.linspace(0, len(profile)-1, num = timesteps)) for index in indices: assert profile[index] is not None timepoint, coreSpeciesConcentrations = profile[index] coreSpeciesConcentrations = {key: float(value) for (key, value) in zip(speciesNames, coreSpeciesConcentrations)} for species_i in rxn.reactants: if isImportant(rxn, species_i, reactions, 'reactant', tolerance, T, P, coreSpeciesConcentrations): return True #only continue if the reaction is not important yet. for species_i in rxn.products: if isImportant(rxn, species_i, reactions, 'product', tolerance, T, P, coreSpeciesConcentrations): return True return False
def isImportant(rxn, spc, reactions, reactantOrProduct, tolerance, T, P, coreSpeciesConcentrations): """ This function computes: - Ri = R(spc) - rij = r(rxn) - alpha = ratio of rij / Ri Range of values of alpha: 0 <= alpha <= 1 This function also compares alpha to a user-defined tolerance TOLERANCE. if alpha >= tolerance: this reaction is important for this species. else: this reaction is unimportant for this species. Returns whether or not rxn is important for spc. keep = True remove = False """ rij = calcRij(rxn, spc, reactantOrProduct, T, P, coreSpeciesConcentrations) Ri = calcRi(spc, rij, reactions, reactantOrProduct, T, P, coreSpeciesConcentrations) logging.debug("rij: {rij}, Ri: {Ri}, rxn: {rxn}, species: {spc}, reactant: {reactantOrProduct}, tol: {tolerance}"\ .format(**locals())) if np.any(np.absolute([rij, Ri]) < CLOSE_TO_ZERO): return False else: assert Ri != 0, "rij: {0}, Ri: {1}, rxn: {2}, species: {3}, reactant: {4}".format( rij, Ri, rxn, spc, reactantOrProduct) alpha = rij / Ri if alpha < 0: return False if alpha > tolerance: """ If both values are very close to 1, then the comparison of alpha and the tolerance might sometimes return an unexpected value. When we set the tolerance to a value of 1, we want all the reactions to be unimportant, regardless of the value of alpha. """ if np.allclose([tolerance, alpha], [1.0, 1.0]): return False return True #where tolerance is user specified tolerance elif alpha <= tolerance: return False
def isImportant(rxn, spc, reactions, reactantOrProduct, tolerance, T, P, coreSpeciesConcentrations): """ This function computes: - Ri = R(spc) - rij = r(rxn) - alpha = ratio of rij / Ri Range of values of alpha: 0 <= alpha <= 1 This function also compares alpha to a user-defined tolerance TOLERANCE. if alpha >= tolerance: this reaction is important for this species. else: this reaction is unimportant for this species. Returns whether or not rxn is important for spc. keep = True remove = False """ rij = calcRij(rxn, spc, reactantOrProduct, T, P, coreSpeciesConcentrations) Ri = calcRi(spc, rij, reactions, reactantOrProduct, T, P, coreSpeciesConcentrations) logging.debug("rij: {rij}, Ri: {Ri}, rxn: {rxn}, species: {spc}, reactant: {reactantOrProduct}, tol: {tolerance}"\ .format(**locals())) if np.any(np.absolute([rij, Ri]) < CLOSE_TO_ZERO): return False else: assert Ri != 0, "rij: {0}, Ri: {1}, rxn: {2}, species: {3}, reactant: {4}".format(rij, Ri, rxn, spc, reactantOrProduct) alpha = rij / Ri if alpha < 0: return False if alpha > tolerance : """ If both values are very close to 1, then the comparison of alpha and the tolerance might sometimes return an unexpected value. When we set the tolerance to a value of 1, we want all the reactions to be unimportant, regardless of the value of alpha. """ if np.allclose([tolerance, alpha], [1.0, 1.0]): return False return True #where tolerance is user specified tolerance elif alpha <= tolerance: return False
def findImportantReactions(rmg, tolerance): """ This function: - loops over all the species involved in a specific reaction - decides whether the specific reaction is important for the species. Whenever it is found that a reaction is important for a species, we break the species loop, and keep the reaction in the model. Returns: a list of rxns that can be removed. """ # run the simulation, creating concentration profiles for each reaction system defined in input. simdata = simulateAll(rmg) reduceReactions = retrieveReactions() def chunks(l, n): """Yield successive n-sized chunks from l.""" for i in xrange(0, len(l), n): yield l[i:i+n] CHUNKSIZE = 40 boolean_array = [] for chunk in chunks(reduceReactions,CHUNKSIZE): N = len(chunk) partial_results = list( map_( WorkerWrapper(assessReaction), chunk, [rmg.reactionSystems] * N, [tolerance] * N, [simdata] * N ) ) boolean_array.extend(partial_results) """ Assuming that the order of the reduced reactions array and the core reactions of the reaction model are identical, iterate over the boolean array and retain those reactions of the reaction model that are deemed 'important'. """ importantRxns = [] for isImport, rxn in zip(boolean_array, rmg.reactionModel.core.reactions): logging.debug('Is rxn {rxn} important? {isImport}'.format(**locals())) if isImport: importantRxns.append(rxn) return importantRxns
def findImportantReactions(rmg, tolerance): """ This function: - loops over all the species involved in a specific reaction - decides whether the specific reaction is important for the species. Whenever it is found that a reaction is important for a species, we break the species loop, and keep the reaction in the model. Returns: a list of rxns that can be removed. """ # run the simulation, creating concentration profiles for each reaction system defined in input. simdata = simulateAll(rmg) reduceReactions = retrieveReactions() def chunks(l, n): """Yield successive n-sized chunks from l.""" for i in xrange(0, len(l), n): yield l[i:i+n] CHUNKSIZE = 40 boolean_array = [] for chunk in chunks(reduceReactions,CHUNKSIZE): N = len(chunk) partial_results = list( map_( assessReaction, chunk, [rmg.reactionSystems] * N, [tolerance] * N, [simdata] * N ) ) boolean_array.extend(partial_results) """ Assuming that the order of the reduced reactions array and the core reactions of the reaction model are identical, iterate over the boolean array and retain those reactions of the reaction model that are deemed 'important'. """ importantRxns = [] for isImport, rxn in zip(boolean_array, rmg.reactionModel.core.reactions): logging.debug('Is rxn {rxn} important? {isImport}'.format(**locals())) if isImport: importantRxns.append(rxn) return importantRxns
import sys import signal from rmgpy.scoop_framework.util import logger as logging try: import scoop scoop.DEBUG = False from scoop import futures, _control, utils, shared from scoop._types import FutureQueue from scoop.broker.structs import BrokerInfo except ImportError, e: logging.debug("Could not properly import SCOOP.") subprocesses = [] def cleanSubprocesses(): [a.kill() for a in subprocesses] try: signal.signal(signal.SIGQUIT, cleanSubprocesses) except AttributeError: # SIGQUIT doesn't exist on Windows signal.signal(signal.SIGTERM, cleanSubprocesses)
# ################################################################################ import os import unittest from external.wip import work_in_progress from rmgpy.scoop_framework.framework import TestScoopCommon from rmgpy.scoop_framework.util import logger as logging import rmgpy try: from scoop import futures except ImportError, e: logging.debug("Could not properly import SCOOP.") from .input import load from .reduction import initialize, computeObservables from .optimization import * def funcOptimize(rmg, targets): reactionModel = rmg.reactionModel initialize(rmg.outputDirectory, reactionModel.core.reactions) error = OptimizeTest.error index = 0 reactionSystem = rmg.reactionSystems[index]