Skip to content

Commit

Permalink
Merge pull request #445 from ReactionMechanismGenerator/moveReactionM…
Browse files Browse the repository at this point in the history
…odel

Merge ReactionModel Class. Works for me. (and Travis)
  • Loading branch information
rwest committed Aug 28, 2015
2 parents 0828639 + e23b436 commit 534cf3a
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 139 deletions.
12 changes: 1 addition & 11 deletions rmgpy/reaction.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -99,14 +99,4 @@ cdef class Reaction:
cpdef generatePairs(self)

cpdef copy(self)

################################################################################

cdef class ReactionModel:

cdef public list species
cdef public list reactions

cpdef generateStoichiometryMatrix(self)

################################################################################

126 changes: 0 additions & 126 deletions rmgpy/reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -959,129 +959,3 @@ def copy(self):

return other


################################################################################

class ReactionModel:
"""
A chemical reaction model, composed of a list of species and a list of
reactions involving those species. The attributes are:
=============== =========== ================================================
Attribute Type Description
=============== =========== ================================================
`species` ``list`` The species involved in the reaction model
`reactions` ``list`` The reactions comprising the reaction model
=============== =========== ================================================
"""

def __init__(self, species=None, reactions=None):
self.species = species or []
self.reactions = reactions or []

def __reduce__(self):
"""
A helper function used when pickling an object.
"""
return (ReactionModel, (self.species, self.reactions))

def generateStoichiometryMatrix(self):
"""
Generate the stoichiometry matrix corresponding to the current
reaction system. The stoichiometry matrix is defined such that the
rows correspond to the `index` attribute of each species object, while
the columns correspond to the `index` attribute of each reaction object.
"""
cython.declare(rxn=Reaction, spec=Species, i=cython.int, j=cython.int, nu=cython.int)
from scipy import sparse

# Use dictionary-of-keys format to efficiently assemble stoichiometry matrix
stoichiometry = sparse.dok_matrix((len(self.species), len(self.reactions)), numpy.float64)
for rxn in self.reactions:
j = rxn.index - 1
# Only need to iterate over the species involved in the reaction,
# not all species in the reaction model
for spec in rxn.reactants:
i = spec.index - 1
nu = rxn.getStoichiometricCoefficient(spec)
if nu != 0: stoichiometry[i,j] = nu
for spec in rxn.products:
i = spec.index - 1
nu = rxn.getStoichiometricCoefficient(spec)
if nu != 0: stoichiometry[i,j] = nu

# Convert to compressed-sparse-row format for efficient use in matrix operations
stoichiometry.tocsr()

return stoichiometry

def merge(self, other):
"""
Return a new :class:`ReactionModel` object that is the union of this
model and `other`.
"""
if not isinstance(other, ReactionModel):
raise ValueError('Expected type ReactionModel for other parameter, got {0}'.format(other.__class__))

# Initialize the merged model
finalModel = ReactionModel()

# Put the current model into the merged model as-is
finalModel.species.extend(self.species)
finalModel.reactions.extend(self.reactions)

# Determine which species in other are already in self
commonSpecies = {}; uniqueSpecies = []
for spec in other.species:
for spec0 in finalModel.species:
if spec.isIsomorphic(spec0):
commonSpecies[spec] = spec0
if spec0.label not in ['Ar','N2','Ne','He']:
if not spec0.thermo.isIdenticalTo(spec.thermo):
print 'Species {0} thermo from model 1 did not match that of model 2.'.format(spec.label)

break
else:
uniqueSpecies.append(spec)

# Determine which reactions in other are already in self
commonReactions = {}; uniqueReactions = []
for rxn in other.reactions:
for rxn0 in finalModel.reactions:
if rxn.isIsomorphic(rxn0, eitherDirection=True):
commonReactions[rxn] = rxn0
if not rxn0.kinetics.isIdenticalTo(rxn.kinetics):
print 'Reaction {0} kinetics from model 1 did not match that of model 2.'.format(str(rxn0))
break
else:
uniqueReactions.append(rxn)

# Add the unique species from other to the final model
finalModel.species.extend(uniqueSpecies)

# Renumber the unique species (to avoid name conflicts on save)
speciesIndex = 0
for spec in finalModel.species:
if spec.label not in ['Ar','N2','Ne','He']:
spec.index = speciesIndex + 1
speciesIndex += 1

# Make sure unique reactions only refer to species in the final model
for rxn in uniqueReactions:
for i, reactant in enumerate(rxn.reactants):
try:
rxn.reactants[i] = commonSpecies[reactant]
except KeyError:
pass
for i, product in enumerate(rxn.products):
try:
rxn.products[i] = commonSpecies[product]
except KeyError:
pass

# Add the unique reactions from other to the final model
finalModel.reactions.extend(uniqueReactions)

# Return the merged model
return finalModel
76 changes: 76 additions & 0 deletions rmgpy/rmg/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,82 @@ class ReactionModel:
def __init__(self, species=None, reactions=None):
self.species = species or []
self.reactions = reactions or []

def __reduce__(self):
"""
A helper function used when pickling an object.
"""
return (ReactionModel, (self.species, self.reactions))

def merge(self, other):
"""
Return a new :class:`ReactionModel` object that is the union of this
model and `other`.
"""
if not isinstance(other, ReactionModel):
raise ValueError('Expected type ReactionModel for other parameter, got {0}'.format(other.__class__))

# Initialize the merged model
finalModel = ReactionModel()

# Put the current model into the merged model as-is
finalModel.species.extend(self.species)
finalModel.reactions.extend(self.reactions)

# Determine which species in other are already in self
commonSpecies = {}; uniqueSpecies = []
for spec in other.species:
for spec0 in finalModel.species:
if spec.isIsomorphic(spec0):
commonSpecies[spec] = spec0
if spec0.label not in ['Ar','N2','Ne','He']:
if not spec0.thermo.isIdenticalTo(spec.thermo):
print 'Species {0} thermo from model 1 did not match that of model 2.'.format(spec.label)

break
else:
uniqueSpecies.append(spec)

# Determine which reactions in other are already in self
commonReactions = {}; uniqueReactions = []
for rxn in other.reactions:
for rxn0 in finalModel.reactions:
if rxn.isIsomorphic(rxn0, eitherDirection=True):
commonReactions[rxn] = rxn0
if not rxn0.kinetics.isIdenticalTo(rxn.kinetics):
print 'Reaction {0} kinetics from model 1 did not match that of model 2.'.format(str(rxn0))
break
else:
uniqueReactions.append(rxn)

# Add the unique species from other to the final model
finalModel.species.extend(uniqueSpecies)

# Renumber the unique species (to avoid name conflicts on save)
speciesIndex = 0
for spec in finalModel.species:
if spec.label not in ['Ar','N2','Ne','He']:
spec.index = speciesIndex + 1
speciesIndex += 1

# Make sure unique reactions only refer to species in the final model
for rxn in uniqueReactions:
for i, reactant in enumerate(rxn.reactants):
try:
rxn.reactants[i] = commonSpecies[reactant]
except KeyError:
pass
for i, product in enumerate(rxn.products):
try:
rxn.products[i] = commonSpecies[product]
except KeyError:
pass

# Add the unique reactions from other to the final model
finalModel.reactions.extend(uniqueReactions)

# Return the merged model
return finalModel

################################################################################

Expand Down
2 changes: 1 addition & 1 deletion scripts/mergeModels.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import argparse

from rmgpy.chemkin import loadChemkinFile, saveChemkinFile, saveSpeciesDictionary, saveTransportFile
from rmgpy.reaction import ReactionModel
from rmgpy.rmg.model import ReactionModel

################################################################################

Expand Down
2 changes: 1 addition & 1 deletion scripts/standardizeModelSpeciesNames.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import argparse

from rmgpy.chemkin import loadChemkinFile, saveChemkinFile, saveSpeciesDictionary, saveTransportFile
from rmgpy.reaction import ReactionModel
from rmgpy.rmg.model import ReactionModel

################################################################################
if __name__ == '__main__':
Expand Down

0 comments on commit 534cf3a

Please sign in to comment.