def saveCompareHTML(outputDir, chemkinPath1, speciesDictPath1, chemkinPath2, speciesDictPath2, readComments1=True, readComments2=True): """ Saves a model comparison HTML file based on two sets of chemkin and species dictionary files. """ model1 = ReactionModel() model1.species, model1.reactions = loadChemkinFile( chemkinPath1, speciesDictPath1, readComments=readComments1) model2 = ReactionModel() model2.species, model2.reactions = loadChemkinFile( chemkinPath2, speciesDictPath2, readComments=readComments2) commonReactions, uniqueReactions1, uniqueReactions2 = compareModelReactions( model1, model2) commonSpecies, uniqueSpecies1, uniqueSpecies2 = compareModelSpecies( model1, model2) outputPath = outputDir + 'diff.html' saveDiffHTML(outputPath, commonSpecies, uniqueSpecies1, uniqueSpecies2, commonReactions, uniqueReactions1, uniqueReactions2)
def saveCompareHTML(outputDir,chemkinPath1,speciesDictPath1,chemkinPath2,speciesDictPath2): """ Saves a model comparison HTML file based on two sets of chemkin and species dictionary files. """ model1 = ReactionModel() model1.species, model1.reactions = loadChemkinFile(chemkinPath1, speciesDictPath1) model2 = ReactionModel() model2.species, model2.reactions = loadChemkinFile(chemkinPath2, speciesDictPath2) commonReactions, uniqueReactions1, uniqueReactions2 = compareModelReactions(model1, model2) outputPath = outputDir + 'diff.html' speciesList1 = [] speciesList1 = model1.species commonSpeciesList = [] speciesList2 = [] for spec2 in model2.species: for spec1 in speciesList1: if spec2.isIsomorphic(spec1): spec2.label = spec1.label speciesList1.remove(spec1) commonSpeciesList.append(spec2) break else: speciesList2.append(spec2) saveDiffHTML(outputPath, commonSpeciesList,speciesList1,speciesList2,commonReactions,uniqueReactions1,uniqueReactions2)
def getKinetics(self): """ Extracts the kinetic data from the chemkin file for plotting purposes. """ from rmgpy.chemkin import loadChemkinFile from rmgpy.kinetics import ArrheniusEP, Chebyshev from rmgpy.reaction import Reaction from rmgpy.data.base import Entry kineticsDataList = [] chemkinPath= self.path + '/chemkin/chem.inp' dictionaryPath = self.path + 'RMG_Dictionary.txt' if self.Foreign: readComments = False else: readComments = True if os.path.exists(dictionaryPath): speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath, readComments=readComments) else: speciesList, reactionList = loadChemkinFile(chemkinPath, readComments=readComments) for reaction in reactionList: # If the kinetics are ArrheniusEP, replace them with Arrhenius if isinstance(reaction.kinetics, ArrheniusEP): reaction.kinetics = reaction.kinetics.toArrhenius(reaction.getEnthalpyOfReaction(298)) if os.path.exists(dictionaryPath): reactants = ' + '.join([moleculeToInfo(reactant) for reactant in reaction.reactants]) arrow = '⇔' if reaction.reversible else '→' products = ' + '.join([moleculeToInfo(product) for product in reaction.products]) href = reaction.getURL() else: reactants = ' + '.join([reactant.label for reactant in reaction.reactants]) arrow = '⇔' if reaction.reversible else '→' products = ' + '.join([product.label for product in reaction.products]) href = '' source = str(reaction).replace('<=>','=') entry = Entry() entry.result = reactionList.index(reaction)+1 forwardKinetics = reaction.kinetics forward = True chemkin = reaction.toChemkin(speciesList) reverseKinetics = reaction.generateReverseRateCoefficient() reverseKinetics.comment = 'Fitted reverse reaction. ' + reaction.kinetics.comment rev_reaction = Reaction(reactants = reaction.products, products = reaction.reactants, kinetics = reverseKinetics) chemkin_rev = rev_reaction.toChemkin(speciesList) kineticsDataList.append([reactants, arrow, products, entry, forwardKinetics, source, href, forward, chemkin, reverseKinetics, chemkin_rev]) return kineticsDataList
def getKinetics(self): """ Extracts the kinetic data from the chemkin file for plotting purposes. """ from rmgpy.chemkin import loadChemkinFile from rmgpy.kinetics import ArrheniusEP, Chebyshev from rmgpy.reaction import Reaction from rmgpy.data.base import Entry kineticsDataList = [] chemkinPath= os.path.join(self.path, 'chemkin','chem.inp') dictionaryPath = os.path.join(self.path, 'RMG_Dictionary.txt' ) if self.Foreign: readComments = False else: readComments = True if os.path.exists(dictionaryPath): speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath, readComments=readComments) else: speciesList, reactionList = loadChemkinFile(chemkinPath, readComments=readComments) for reaction in reactionList: # If the kinetics are ArrheniusEP, replace them with Arrhenius if isinstance(reaction.kinetics, ArrheniusEP): reaction.kinetics = reaction.kinetics.toArrhenius(reaction.getEnthalpyOfReaction(298)) if os.path.exists(dictionaryPath): reactants = ' + '.join([moleculeToInfo(reactant) for reactant in reaction.reactants]) arrow = '⇔' if reaction.reversible else '→' products = ' + '.join([moleculeToInfo(product) for product in reaction.products]) href = reaction.getURL() else: reactants = ' + '.join([reactant.label for reactant in reaction.reactants]) arrow = '⇔' if reaction.reversible else '→' products = ' + '.join([product.label for product in reaction.products]) href = '' source = str(reaction).replace('<=>','=') entry = Entry() entry.result = reactionList.index(reaction)+1 forwardKinetics = reaction.kinetics forward = True chemkin = reaction.toChemkin(speciesList) reverseKinetics = reaction.generateReverseRateCoefficient() reverseKinetics.comment = 'Fitted reverse reaction. ' + reaction.kinetics.comment rev_reaction = Reaction(reactants = reaction.products, products = reaction.reactants, kinetics = reverseKinetics) chemkin_rev = rev_reaction.toChemkin(speciesList) kineticsDataList.append([reactants, arrow, products, entry, forwardKinetics, source, href, forward, chemkin, reverseKinetics, chemkin_rev]) return kineticsDataList
def __init__(self, title='', oldDir='', newDir='', observables={}, exptData=[], ck2cti=True): self.title = title self.newDir = newDir self.oldDir = oldDir self.conditions = None self.exptData = exptData self.observables = observables # Detect if the transport file exists oldTransportPath = None if os.path.exists(os.path.join(oldDir, 'tran.dat')): oldTransportPath = os.path.join(oldDir, 'tran.dat') newTransportPath = None if os.path.exists(os.path.join(newDir, 'tran.dat')): newTransportPath = os.path.join(newDir, 'tran.dat') # load the species and reactions from each model oldSpeciesList, oldReactionList = loadChemkinFile( os.path.join(oldDir, 'chem_annotated.inp'), os.path.join(oldDir, 'species_dictionary.txt'), oldTransportPath) newSpeciesList, newReactionList = loadChemkinFile( os.path.join(newDir, 'chem_annotated.inp'), os.path.join(newDir, 'species_dictionary.txt'), newTransportPath) self.oldSim = Cantera(speciesList=oldSpeciesList, reactionList=oldReactionList, outputDirectory=oldDir) self.newSim = Cantera(speciesList=newSpeciesList, reactionList=newReactionList, outputDirectory=newDir) # load each chemkin file into the cantera model if not ck2cti: self.oldSim.loadModel() self.newSim.loadModel() else: self.oldSim.loadChemkinModel(os.path.join(oldDir, 'chem_annotated.inp'), transportFile=oldTransportPath, quiet=True) self.newSim.loadChemkinModel(os.path.join(newDir, 'chem_annotated.inp'), transportFile=newTransportPath, quiet=True)
def saveCompareHTML(outputDir,chemkinPath1,speciesDictPath1,chemkinPath2,speciesDictPath2,readComments1=True,readComments2=True): """ Saves a model comparison HTML file based on two sets of chemkin and species dictionary files. """ model1 = ReactionModel() model1.species, model1.reactions = loadChemkinFile(chemkinPath1, speciesDictPath1, readComments = readComments1) model2 = ReactionModel() model2.species, model2.reactions = loadChemkinFile(chemkinPath2, speciesDictPath2, readComments = readComments2) commonReactions, uniqueReactions1, uniqueReactions2 = compareModelReactions(model1, model2) commonSpecies, uniqueSpecies1, uniqueSpecies2 = compareModelSpecies(model1, model2) outputPath = outputDir + 'diff.html' saveDiffHTML(outputPath, commonSpecies, uniqueSpecies1, uniqueSpecies2, commonReactions, uniqueReactions1, uniqueReactions2)
def load_model(self): """Load model from Chemkin file""" self.species, self.reactions = loadChemkinFile(self.chem_path, self.dict_path) self.update_all_labels() self.update_species_dict() self.update_formula_dict()
def setUp(self): """ A function run before each unit test in this class. """ from rmgpy.chemkin import loadChemkinFile folder = os.path.join(os.path.dirname(rmgpy.__file__),'tools/data/various_kinetics') chemkinPath = os.path.join(folder, 'chem_annotated.inp') dictionaryPath = os.path.join(folder, 'species_dictionary.txt') transportPath = os.path.join(folder, 'tran.dat') species, reactions = loadChemkinFile(chemkinPath, dictionaryPath,transportPath) self.rmg_ctSpecies = [spec.toCantera(useChemkinIdentifier = True) for spec in species] self.rmg_ctReactions = [] for rxn in reactions: convertedReactions = rxn.toCantera(species, useChemkinIdentifier = True) if isinstance(convertedReactions,list): self.rmg_ctReactions.extend(convertedReactions) else: self.rmg_ctReactions.append(convertedReactions) job = Cantera() job.loadChemkinModel(chemkinPath, transportFile=transportPath,quiet=True) self.ctSpecies = job.model.species() self.ctReactions = job.model.reactions()
def setUp(self): """ A function run before each unit test in this class. """ from rmgpy.chemkin import loadChemkinFile folder = os.path.join(os.path.dirname(rmgpy.__file__), 'tools/data/various_kinetics') chemkinPath = os.path.join(folder, 'chem_annotated.inp') dictionaryPath = os.path.join(folder, 'species_dictionary.txt') transportPath = os.path.join(folder, 'tran.dat') species, reactions = loadChemkinFile(chemkinPath, dictionaryPath, transportPath) self.rmg_ctSpecies = [ spec.toCantera(useChemkinIdentifier=True) for spec in species ] self.rmg_ctReactions = [] for rxn in reactions: convertedReactions = rxn.toCantera(species, useChemkinIdentifier=True) if isinstance(convertedReactions, list): self.rmg_ctReactions.extend(convertedReactions) else: self.rmg_ctReactions.append(convertedReactions) job = Cantera() job.loadChemkinModel(chemkinPath, transportFile=transportPath, quiet=True) self.ctSpecies = job.model.species() self.ctReactions = job.model.reactions()
def main(chemkin, dictionary, output, foreign): model = CoreEdgeReactionModel() model.core.species, model.core.reactions = loadChemkinFile(chemkin, dictionary, readComments=not foreign) outputPath = os.path.join(output, 'output.html') speciesPath = os.path.join(output, 'species') if not os.path.isdir(speciesPath): os.makedirs(speciesPath) saveOutputHTML(outputPath, model)
def runIgnitionReactionSensitivity(runChemkinJob, inputFile, dictionaryFile): """ Supply a runChemkinJob python function which returns the ignition delay with a chemkin file input. This will run finite difference reaction sensitivities and save them to a csv file. """ from rmgpy.chemkin import loadChemkinFile, saveChemkinFile speciesList, reactionList = loadChemkinFile(inputFile, dictionaryPath=dictionaryFile, readComments=False) num_reactions = len(reactionList) factor_high = 1.05 factor_low = 1. / factor_high worksheet = csv.writer(file('ignition_rxn_sensitivity.csv', 'w')) worksheet.writerow([ 'Index', 'Reaction', 'd[ln k]', 'tau_high', 'tau_low', 'd[ln tau]/d[ln k]' ]) print 'Running reaction sensitivity analysis using finite differences...' for index, reaction in enumerate(reactionList): rxn_index = index + 1 rxn_string = reaction.toChemkin(kinetics=False) print 'At reaction {0} of {1}. {2}'.format(rxn_index, num_reactions, rxn_string) reaction.kinetics.changeRate(factor_high) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose=False) tau_high = runChemkinJob('chem_temp.inp') reaction.kinetics.changeRate(1. / factor_high) # reset the kinetics reaction.kinetics.changeRate(factor_low) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose=False) tau_low = runChemkinJob('chem_temp.inp') reaction.kinetics.changeRate(1. / factor_low) # reset the kinetics if tau_high != 0 and tau_low != 0: sens = numpy.log(tau_high / tau_low) / numpy.log( factor_high / factor_low) else: sens = 0 worksheet.writerow([ rxn_index, rxn_string, numpy.log(factor_high / factor_low), tau_high, tau_low, sens ])
def main(chemkin, dictionary, output, foreign): model = CoreEdgeReactionModel() model.core.species, model.core.reactions = loadChemkinFile( chemkin, dictionary, readComments=not foreign, checkDuplicates=foreign) outputPath = os.path.join(output, 'output.html') speciesPath = os.path.join(output, 'species') if not os.path.isdir(speciesPath): os.makedirs(speciesPath) saveOutputHTML(outputPath, model)
def setUpClass(self): """A function that is run ONCE before all unit tests in this class.""" global database self.database = database self.species, self.reactions = loadChemkinFile( os.path.join(settings['test_data.directory'], 'parsing_data', 'chem_annotated.inp'), os.path.join(settings['test_data.directory'], 'parsing_data', 'species_dictionary.txt') )
def loadRMGPyJob(inputFile, chemkinFile=None, speciesDict=None, generateImages=True): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ from rmgpy.rmg.main import RMG # Load the specified RMG input file rmg = RMG() rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG if not chemkinFile: chemkinFile = os.path.join(os.path.dirname(inputFile), 'chemkin', 'chem.inp') if not speciesDict: speciesDict = os.path.join(os.path.dirname(inputFile), 'chemkin', 'species_dictionary.txt') speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict) # Map species in input file to corresponding species in Chemkin file speciesDict = {} for spec0 in rmg.initialSpecies: for species in speciesList: if species.isIsomorphic(spec0): speciesDict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reactionList: if not reaction.pairs: reaction.generatePairs() # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([(speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems()]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] reactionSystem.sensitiveSpecies = [speciesDict[spec] for spec in reactionSystem.sensitiveSpecies] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList # Generate species images if generateImages: speciesPath = os.path.join(os.path.dirname(inputFile), 'species') try: os.mkdir(speciesPath) except OSError: pass for species in speciesList: path = os.path.join(speciesPath, '{0!s}.png'.format(species)) if not os.path.exists(path): species.molecule[0].draw(str(path)) return rmg
def obtain_cti_file_nicely_named(chemkinfilepath, readComments=True, original_ck_file='chem_annotated.inp'): """ Given a chemkin file path, this method reads in the chemkin file and species dictionary into RMG objects, renames the species more intuitively, and then saves the output as 'input_nicely_named.cti' to the same file path. """ from rmgpy.chemkin import loadChemkinFile import os import soln2cti import cantera as ct chemkinPath = os.path.join(chemkinfilepath, original_ck_file) speciesDictPath = os.path.join(chemkinfilepath, 'species_dictionary.txt') species, reactions = loadChemkinFile(chemkinPath, speciesDictPath, readComments=readComments, useChemkinNames=False) make_string_labels_independent(species) for spec in species: if len(spec.molecule) == 0: print(spec) # convert species ct_species = [ spec.toCantera(useChemkinIdentifier=False) for spec in species ] # convert reactions # since this can return a rxn or list of reactions, this allows to make a list based on the returned type ct_reactions = [] for rxn in reactions: ct_rxn = rxn.toCantera(useChemkinIdentifier=False) if isinstance(ct_rxn, list): ct_reactions.extend(ct_rxn) else: ct_reactions.append(ct_rxn) # save new file gas = ct.Solution(thermo='IdealGas', kinetics='GasKinetics', species=ct_species, reactions=ct_reactions) new_file = soln2cti.write(gas) # move the file to new location os.rename(new_file, os.path.join(chemkinfilepath, 'input_nicely_named.cti')) # save species dictionary dictionary = '' for spec in species: dictionary += spec.toAdjacencyList() + '\n\n' f = open( os.path.join(chemkinfilepath, 'species_dictionary_nicely_named.txt'), 'w') f.write(dictionary) f.close()
def createJavaKineticsLibrary(self): """ Generates java reaction library files from your chemkin file. """ from rmgpy.chemkin import loadChemkinFile, saveJavaKineticsLibrary chemkinPath = os.path.join(self.path, 'chemkin','chem.inp') dictionaryPath = os.path.join(self.path, 'RMG_Dictionary.txt' ) speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath) saveJavaKineticsLibrary(self.path, speciesList, reactionList) return
def get_models_to_merge(input_model_files): """ Reads input file paths and creates a list of ReactionModel """ models = [] for chemkin, speciesPath, transportPath in input_model_files: print 'Loading model #{0:d}...'.format(len(models)+1) model = ReactionModel() model.species, model.reactions = loadChemkinFile(chemkin, speciesPath, transportPath=transportPath) models.append(model) return models
def createJavaKineticsLibrary(self): """ Generates java reaction library files from your chemkin file. """ from rmgpy.chemkin import loadChemkinFile, saveJavaKineticsLibrary chemkinPath = self.path + '/chemkin/chem.inp' dictionaryPath = self.path + 'RMG_Dictionary.txt' speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath) saveJavaKineticsLibrary(self.path, speciesList, reactionList) return
def getKinetics(self): """ Extracts the kinetic data from the chemkin file for plotting purposes. """ from rmgpy.chemkin import loadChemkinFile from rmgpy.kinetics import ArrheniusEP, Chebyshev from rmgpy.reaction import Reaction from rmgpy.data.base import Entry kineticsDataList = [] chemkinPath = self.path + "/chemkin/chem.inp" dictionaryPath = self.path + "RMG_Dictionary.txt" speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath) for reaction in reactionList: # If the kinetics are ArrheniusEP, replace them with Arrhenius if isinstance(reaction.kinetics, ArrheniusEP): reaction.kinetics = reaction.kinetics.toArrhenius(reaction.getEnthalpyOfReaction(298)) reactants = " + ".join([moleculeToInfo(reactant) for reactant in reaction.reactants]) arrow = "⇔" if reaction.reversible else "→" products = " + ".join([moleculeToInfo(reactant) for reactant in reaction.products]) source = str(reaction).replace("<=>", "=") href = reaction.getURL() entry = Entry() entry.result = reactionList.index(reaction) + 1 forwardKinetics = reaction.kinetics forward = True chemkin = reaction.toChemkin(speciesList) reverseKinetics = reaction.generateReverseRateCoefficient() reverseKinetics.comment = "Fitted reverse reaction. " + reaction.kinetics.comment rev_reaction = Reaction(reactants=reaction.products, products=reaction.reactants, kinetics=reverseKinetics) chemkin_rev = rev_reaction.toChemkin(speciesList) kineticsDataList.append( [ reactants, arrow, products, entry, forwardKinetics, source, href, forward, chemkin, reverseKinetics, chemkin_rev, ] ) return kineticsDataList
def runIgnitionThermoSensitivity(runChemkinJob, inputFile, dictionaryFile): """ Supply a runChemkinJob python function which returns the ignition delay with a chemkin file input. This will run finite difference sensitivities to enthalpies and save them to a csv file. """ from rmgpy.chemkin import loadChemkinFile, saveChemkinFile, getSpeciesIdentifier from rmgpy.quantity import Quantity speciesList, reactionList = loadChemkinFile(inputFile, dictionaryPath=dictionaryFile, readComments=False) num_species = len(speciesList) deltaH = Quantity(0.5, 'kcal/mol').value_si worksheet = csv.writer(file('ignition_thermo_sensitivity.csv', 'w')) worksheet.writerow([ 'Species', 'd[del H] (kcal/mol)', 'tau_high', 'tau_low', 'd[ln tau]/d[del H]' ]) print 'Running thermo sensitivity analysis using finite differences...' for index, species in enumerate(speciesList): species_index = index + 1 species_string = getSpeciesIdentifier(species) print 'At species {0} of {1}. {2}'.format(species_index, num_species, species_string) species.thermo.changeBaseEnthalpy(deltaH) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose=False) tau_high = runChemkinJob('chem_temp.inp') species.thermo.changeBaseEnthalpy(-deltaH) # reset the thermo species.thermo.changeBaseEnthalpy(-deltaH) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose=False) tau_low = runChemkinJob('chem_temp.inp') species.thermo.changeBaseEnthalpy(deltaH) # reset the kinetics if tau_high != 0 and tau_low != 0: sens = numpy.log(tau_high / tau_low) / (2 * deltaH) else: sens = 0 worksheet.writerow([species_string, '1', tau_high, tau_low, sens])
def execute(inputModelFiles, **kwargs): try: wd = kwargs['wd'] except KeyError: wd = os.getcwd() transport = kwargs['transport'] outputChemkinFile = os.path.join(wd, 'chem.inp') outputSpeciesDictionary = os.path.join(wd, 'species_dictionary.txt') outputTransportFile = os.path.join(wd, 'tran.dat') if transport else None # Load the models to merge models = [] for chemkin, speciesPath, transportPath in inputModelFiles: print 'Loading model #{0:d}...'.format(len(models) + 1) model = ReactionModel() model.species, model.reactions = loadChemkinFile( chemkin, speciesPath, transportPath=transportPath) models.append(model) finalModel = ReactionModel() for i, model in enumerate(models): print 'Ignoring common species and reactions from model #{0:d}...'.format( i + 1) Nspec0 = len(finalModel.species) Nrxn0 = len(finalModel.reactions) finalModel = finalModel.merge(model) Nspec = len(finalModel.species) Nrxn = len(finalModel.reactions) print 'Added {1:d} out of {2:d} ({3:.1f}%) unique species from model #{0:d}.'.format( i + 1, Nspec - Nspec0, len(model.species), (Nspec - Nspec0) * 100. / len(model.species)) print 'Added {1:d} out of {2:d} ({3:.1f}%) unique reactions from model #{0:d}.'.format( i + 1, Nrxn - Nrxn0, len(model.reactions), (Nrxn - Nrxn0) * 100. / len(model.reactions)) print 'The merged model has {0:d} species and {1:d} reactions'.format( len(finalModel.species), len(finalModel.reactions)) # Save the merged model to disk saveChemkinFile(outputChemkinFile, finalModel.species, finalModel.reactions) saveSpeciesDictionary(outputSpeciesDictionary, finalModel.species) if transport: saveTransportFile(outputTransportFile, finalModel.species) print 'Merged Chemkin file saved to {0}'.format(outputChemkinFile) print 'Merged species dictionary saved to {0}'.format( outputSpeciesDictionary) if transport: print 'Merged transport file saved to {0}'.format(outputTransportFile)
def __init__(self, title='', oldDir='', newDir='', observables = {}, exptData = [], ck2cti=True): self.title=title self.newDir=newDir self.oldDir=oldDir self.conditions=None self.exptData=exptData self.observables=observables # Detect if the transport file exists oldTransportPath = None if os.path.exists(os.path.join(oldDir,'tran.dat')): oldTransportPath = os.path.join(oldDir,'tran.dat') newTransportPath = None if os.path.exists(os.path.join(newDir,'tran.dat')): newTransportPath = os.path.join(newDir,'tran.dat') # load the species and reactions from each model oldSpeciesList, oldReactionList = loadChemkinFile(os.path.join(oldDir,'chem_annotated.inp'), os.path.join(oldDir,'species_dictionary.txt'), oldTransportPath) newSpeciesList, newReactionList = loadChemkinFile(os.path.join(newDir,'chem_annotated.inp'), os.path.join(newDir,'species_dictionary.txt'), newTransportPath) self.oldSim = Cantera(speciesList = oldSpeciesList, reactionList = oldReactionList, outputDirectory = oldDir) self.newSim = Cantera(speciesList = newSpeciesList, reactionList = newReactionList, outputDirectory = newDir) # load each chemkin file into the cantera model if not ck2cti: self.oldSim.loadModel() self.newSim.loadModel() else: self.oldSim.loadChemkinModel(os.path.join(oldDir,'chem_annotated.inp'), transportFile=oldTransportPath, quiet=True) self.newSim.loadChemkinModel(os.path.join(newDir,'chem_annotated.inp'), transportFile=newTransportPath, quiet=True)
def setUpClass(self): from rmgpy.chemkin import loadChemkinFile """A function that is run ONCE before all unit tests in this class.""" global database self.database = database for family in self.database.kinetics.families.values(): family.addKineticsRulesFromTrainingSet(thermoDatabase=self.database.thermo) family.fillKineticsRulesByAveragingUp(verbose=True) self.species, self.reactions = loadChemkinFile(os.path.join(settings['test_data.directory'], 'parsing_data','chem_annotated.inp'), os.path.join(settings['test_data.directory'], 'parsing_data','species_dictionary.txt') )
def createJavaKineticsLibrary(self): """ Generates java reaction library files from your chemkin file. """ import subprocess from rmgpy.chemkin import loadChemkinFile, saveJavaKineticsLibrary chemkinPath = self.path + '/chemkin/chem.inp' dictionaryPath = self.path + 'RMG_Dictionary.txt' speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath) saveJavaKineticsLibrary(self.path, speciesList, reactionList) commands = ['mv', 'RMG_Dictionary.txt', 'species.txt'] subprocess.check_output(commands, cwd=self.path) return
def __init__(self, title='', oldDir='', newDir='', exptData = []): self.title=title self.newDir=newDir self.oldDir=oldDir self.conditions=None self.exptData=exptData # load the species and reactions from each model oldSpeciesList, oldReactionList = loadChemkinFile(os.path.join(oldDir,'chem_annotated.inp'), os.path.join(oldDir,'species_dictionary.txt')) newSpeciesList, newReactionList = loadChemkinFile(os.path.join(newDir,'chem_annotated.inp'), os.path.join(newDir,'species_dictionary.txt')) self.oldSim = Cantera(speciesList = oldSpeciesList, reactionList = oldReactionList, outputDirectory = oldDir) self.newSim = Cantera(speciesList = newSpeciesList, reactionList = newReactionList outputDirectory = newDir) # load each chemkin file into the cantera model self.oldSim.loadChemkinModel(os.path.join(oldDir,'chem_annotated.inp')) self.newSim.loadChemkinModel(os.path.join(newDir,'chem_annotated.inp'))
def loadRMGPyJob(inputFile, chemkinFile, speciesDict=None): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ # Load the specified RMG input file rmg = RMG() rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict, readComments=False) assert speciesList, reactionList # print 'labels from species in the chemkin file:' # for spc in speciesList: # print spc.label # Map species in input file to corresponding species in Chemkin file speciesDict = {} assert rmg.initialSpecies # print 'initial species: ', rmg.initialSpecies #label of initial species must correspond to the label in the chemkin file WITHOUT parentheses. #E.g.: "JP10" not "JP10(1)" for spec0 in rmg.initialSpecies: for species in speciesList: if species.label == spec0.label: speciesDict[spec0] = species break assert speciesDict # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([ (speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems() ]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList # print 'core: ', speciesList return rmg
def main(chemkin): # Load Chemkin file reactionModel = CoreEdgeReactionModel() reactionModel.core.species, reactionModel.core.reactions = loadChemkinFile( chemkin) # Identify reactions to be removed reactionList = reactionModel.core.reactions duplicateReactionsToRemove = [] for index1 in range(len(reactionList)): reaction1 = reactionList[index1] for index2 in range(index1 + 1, len(reactionList)): reaction2 = reactionList[index2] # Check if the two reactions are identical if (reaction1.reactants == reaction2.reactants and reaction1.products == reaction2.products) or ( reaction1.reactants == reaction2.products and reaction1.products == reaction2.reactants): # Identify if exactly 1 of the reactions is a LibraryReaction if isinstance(reaction1, LibraryReaction) != isinstance( reaction2, LibraryReaction): # Mark the non-LibraryReaction to be removed if isinstance(reaction1, LibraryReaction): duplicateReactionsToRemove.append(reaction2) else: duplicateReactionsToRemove.append(reaction1) # Remove the identified reactions for reaction in duplicateReactionsToRemove: reactionList.remove(reaction) # Write new Chemkin file path = 'chem_annotated_new.inp' speciesList = reactionModel.core.species + reactionModel.outputSpeciesList rxnList = reactionModel.core.reactions + reactionModel.outputReactionList with open(chemkin, 'rb') as old, open(path, 'wb') as new: # Copy species and reactions blocks to new Chemkin file line = old.readline() while 'REACTIONS' not in line.upper(): new.write(line) line = old.readline() new.write('REACTIONS KCAL/MOLE MOLES\n\n') rmgpy.chemkin.__chemkin_reaction_count = 0 for rxn in rxnList: new.write( writeKineticsEntry(rxn, speciesList=speciesList, verbose=True)) new.write('\n') new.write('END\n\n') print "New Chemkin file contains {0} reactions.".format( rmgpy.chemkin.__chemkin_reaction_count)
def loadModel(self, chemkinPath, dictionaryPath, transportPath=None): """ Load a RMG-generated model into the Uncertainty class `chemkinPath`: path to the chem_annotated.inp CHEMKIN mechanism `dictionaryPath`: path to the species_dictionary.txt file `transportPath`: path to the tran.dat file (optional) Then create dictionaries stored in self.thermoGroups and self.rateRules containing information about the source of the thermodynamic and kinetic parameters """ from rmgpy.chemkin import loadChemkinFile self.speciesList, self.reactionList = loadChemkinFile(chemkinPath, dictionaryPath=dictionaryPath, transportPath=transportPath)
def setUpClass(self): """A function that is run ONCE before all unit tests in this class.""" global database self.database = database for family in self.database.kinetics.families.values(): family.addKineticsRulesFromTrainingSet( thermoDatabase=self.database.thermo) family.fillKineticsRulesByAveragingUp(verbose=True) self.species, self.reactions = loadChemkinFile( os.path.join(settings['test_data.directory'], 'parsing_data', 'chem_annotated.inp'), os.path.join(settings['test_data.directory'], 'parsing_data', 'species_dictionary.txt'))
def test_1(self): """ Test basic functionality of /tools/populate_reactions/ """ from rmgpy.chemkin import loadChemkinFile from rmgpy.rmg.model import ReactionModel inputFile = os.path.join(rmgpy.getPath(), 'tools', 'data', 'generate', 'input.py') with open(inputFile) as fp: response = self.client.post('/tools/populate_reactions/', {'InputFile': fp}) self.assertEqual(response.status_code, 200) folder = os.path.join(settings.MEDIA_ROOT, 'rmg', 'tools', 'populateReactions') # Check if inputs were correctly uploaded pyInput = os.path.join(folder, 'input.txt') self.assertTrue(os.path.isfile(pyInput), 'RMG input file was not uploaded') # Check if outputs were correctly generated htmlOutput = os.path.join(folder, 'output.html') chemOutput = os.path.join(folder, 'chemkin', 'chem.inp') dictOutput = os.path.join(folder, 'chemkin', 'species_dictionary.txt') self.assertTrue(os.path.isfile(htmlOutput), 'HTML Output was not generated') self.assertTrue(os.path.isfile(chemOutput), 'CHEMKIN file was not generated') self.assertTrue(os.path.isfile(dictOutput), 'Species dictionary was not generated') # Check that the output is not empty model = ReactionModel() model.species, model.reactions = loadChemkinFile( chemOutput, dictOutput) self.assertTrue(model.species, 'No species were generated') self.assertTrue(model.reactions, 'No reactions were generated') shutil.rmtree(folder)
def loadRMGPyJob(inputFile, chemkinFile, speciesDict=None): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ # Load the specified RMG input file rmg = RMG() rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict, readComments=False) assert speciesList, reactionList # print 'labels from species in the chemkin file:' # for spc in speciesList: # print spc.label # Map species in input file to corresponding species in Chemkin file speciesDict = {} assert rmg.initialSpecies # print 'initial species: ', rmg.initialSpecies #label of initial species must correspond to the label in the chemkin file WITHOUT parentheses. #E.g.: "JP10" not "JP10(1)" for spec0 in rmg.initialSpecies: for species in speciesList: if species.label == spec0.label: speciesDict[spec0] = species break assert speciesDict # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([(speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems()]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList # print 'core: ', speciesList return rmg
def __init__(self, chemkin_path, dictionary_path, fragment_smiles_path, temperature, pressure, outputDirectory='temp'): super(OdeSimulator, self).__init__(chemkin_path, dictionary_path, fragment_smiles_path) speciesList, reactionList = loadChemkinFile(chemkin_path, dictionary_path) self.speciesList = speciesList self.reactionList = reactionList self.temperature = temperature # unit: K self.pressure = pressure # unit: bar self.outputDirectory = outputDirectory
def loadRMGPyJob(inputFile, chemkinFile, speciesDict): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ import os.path from rmgpy.chemkin import getSpeciesIdentifier, loadChemkinFile from rmgpy.rmg.main import RMG from rmgpy.solver.base import TerminationTime, TerminationConversion # Load the specified RMG input file rmg = RMG() rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict, readComments=False) # Map species in input file to corresponding species in Chemkin file speciesDict = {} #label of initial species must correspond to the label in the chemkin file WITHOUT parentheses. for spec0 in rmg.initialSpecies: for species in speciesList: if species.label == spec0.label: speciesDict[spec0] = species break # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([ (speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems() ]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList return rmg
def execute(inputModelFiles, **kwargs): try: wd = kwargs['wd'] except KeyError: wd = os.getcwd() transport = kwargs['transport'] outputChemkinFile = os.path.join(wd, 'chem.inp') outputSpeciesDictionary = os.path.join(wd, 'species_dictionary.txt') outputTransportFile = os.path.join(wd, 'tran.dat') if transport else None # Load the models to merge models = [] for chemkin, speciesPath, transportPath in inputModelFiles: print 'Loading model #{0:d}...'.format(len(models)+1) model = ReactionModel() model.species, model.reactions = loadChemkinFile(chemkin, speciesPath, transportPath=transportPath) models.append(model) finalModel = ReactionModel() for i, model in enumerate(models): print 'Ignoring common species and reactions from model #{0:d}...'.format(i+1) Nspec0 = len(finalModel.species) Nrxn0 = len(finalModel.reactions) finalModel = finalModel.merge(model) Nspec = len(finalModel.species) Nrxn = len(finalModel.reactions) print 'Added {1:d} out of {2:d} ({3:.1f}%) unique species from model #{0:d}.'.format(i+1, Nspec - Nspec0, len(model.species), (Nspec - Nspec0) * 100. / len(model.species)) print 'Added {1:d} out of {2:d} ({3:.1f}%) unique reactions from model #{0:d}.'.format(i+1, Nrxn - Nrxn0, len(model.reactions), (Nrxn - Nrxn0) * 100. / len(model.reactions)) print 'The merged model has {0:d} species and {1:d} reactions'.format(len(finalModel.species), len(finalModel.reactions)) # Save the merged model to disk saveChemkinFile(outputChemkinFile, finalModel.species, finalModel.reactions) saveSpeciesDictionary(outputSpeciesDictionary, finalModel.species) if transport: saveTransportFile(outputTransportFile, finalModel.species) print 'Merged Chemkin file saved to {0}'.format(outputChemkinFile) print 'Merged species dictionary saved to {0}'.format(outputSpeciesDictionary) if transport: print 'Merged transport file saved to {0}'.format(outputTransportFile)
def runIgnitionReactionSensitivity(runChemkinJob, inputFile, dictionaryFile): """ Supply a runChemkinJob python function which returns the ignition delay with a chemkin file input. This will run finite difference reaction sensitivities and save them to a csv file. """ from rmgpy.chemkin import loadChemkinFile, saveChemkinFile speciesList, reactionList = loadChemkinFile(inputFile, dictionaryPath = dictionaryFile, readComments = False) num_reactions = len(reactionList) factor_high = 1.05 factor_low = 1. / factor_high worksheet = csv.writer(file('ignition_rxn_sensitivity.csv', 'w')) worksheet.writerow(['Index', 'Reaction', 'd[ln k]','tau_high','tau_low','d[ln tau]/d[ln k]']) logging.info('Running reaction sensitivity analysis using finite differences...') for index, reaction in enumerate(reactionList): rxn_index = index + 1 rxn_string = reaction.toChemkin(kinetics = False) logging.info('At reaction {0} of {1}. {2}'.format(rxn_index, num_reactions, rxn_string)) reaction.kinetics.changeRate(factor_high) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose = False) tau_high = runChemkinJob('chem_temp.inp') reaction.kinetics.changeRate(1./factor_high) # reset the kinetics reaction.kinetics.changeRate(factor_low) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose = False) tau_low = runChemkinJob('chem_temp.inp') reaction.kinetics.changeRate(1./factor_low) # reset the kinetics if tau_high != 0 and tau_low != 0: sens = numpy.log(tau_high / tau_low) / numpy.log(factor_high / factor_low) else: sens = 0 worksheet.writerow([rxn_index, rxn_string, numpy.log(factor_high / factor_low), tau_high, tau_low, sens])
def runIgnitionThermoSensitivity(runChemkinJob, inputFile, dictionaryFile): """ Supply a runChemkinJob python function which returns the ignition delay with a chemkin file input. This will run finite difference sensitivities to enthalpies and save them to a csv file. """ from rmgpy.chemkin import loadChemkinFile, saveChemkinFile, getSpeciesIdentifier from rmgpy.quantity import Quantity speciesList, reactionList = loadChemkinFile(inputFile, dictionaryPath = dictionaryFile, readComments = False) num_species = len(speciesList) deltaH = Quantity(0.5, 'kcal/mol').value_si worksheet = csv.writer(file('ignition_thermo_sensitivity.csv', 'w')) worksheet.writerow(['Species', 'd[del H] (kcal/mol)', 'tau_high', 'tau_low', 'd[ln tau]/d[del H]']) logging.info('Running thermo sensitivity analysis using finite differences...') for index, species in enumerate(speciesList): species_index = index + 1 species_string = getSpeciesIdentifier(species) logging.info('At species {0} of {1}. {2}'.format(species_index, num_species, species_string)) species.thermo.changeBaseEnthalpy(deltaH) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose = False) tau_high = runChemkinJob('chem_temp.inp') species.thermo.changeBaseEnthalpy(-deltaH) # reset the thermo species.thermo.changeBaseEnthalpy(-deltaH) saveChemkinFile('chem_temp.inp', speciesList, reactionList, verbose = False) tau_low = runChemkinJob('chem_temp.inp') species.thermo.changeBaseEnthalpy(deltaH) # reset the kinetics if tau_high != 0 and tau_low != 0: sens = numpy.log(tau_high / tau_low) / (2 * deltaH) else: sens = 0 worksheet.writerow([species_string, '1', tau_high, tau_low, sens])
def loadRMGPyJob(inputFile, chemkinFile, speciesDict): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ import os.path from rmgpy.chemkin import getSpeciesIdentifier, loadChemkinFile from rmgpy.rmg.main import RMG from rmgpy.solver.base import TerminationTime, TerminationConversion # Load the specified RMG input file rmg = RMG() rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict, readComments=False) # Map species in input file to corresponding species in Chemkin file speciesDict = {} #label of initial species must correspond to the label in the chemkin file WITHOUT parentheses. for spec0 in rmg.initialSpecies: for species in speciesList: if species.label == spec0.label: speciesDict[spec0] = species break # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([(speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems()]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList return rmg
def test_1(self): """ Test basic functionality of /tools/populate_reactions/ """ from rmgpy.chemkin import loadChemkinFile from rmgpy.rmg.model import ReactionModel inputFile = os.path.join(rmgpy.getPath(),'tools','data','generate','input.py') with open(inputFile) as fp: response = self.client.post('/tools/populate_reactions/', {'InputFile': fp}) self.assertEqual(response.status_code, 200) folder = os.path.join(settings.MEDIA_ROOT,'rmg','tools','populateReactions') # Check if inputs were correctly uploaded pyInput = os.path.join(folder,'input.txt') self.assertTrue(os.path.isfile(pyInput),'RMG input file was not uploaded') # Check if outputs were correctly generated htmlOutput = os.path.join(folder,'output.html') chemOutput = os.path.join(folder,'chemkin','chem.inp') dictOutput = os.path.join(folder,'chemkin','species_dictionary.txt') self.assertTrue(os.path.isfile(htmlOutput),'HTML Output was not generated') self.assertTrue(os.path.isfile(chemOutput),'CHEMKIN file was not generated') self.assertTrue(os.path.isfile(dictOutput),'Species dictionary was not generated') # Check that the output is not empty model = ReactionModel() model.species, model.reactions = loadChemkinFile(chemOutput, dictOutput) self.assertTrue(model.species,'No species were generated') self.assertTrue(model.reactions, 'No reactions were generated') shutil.rmtree(folder)
def loadRMGPyJob(inputFile): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ # Load the specified RMG input file rmg = RMG() rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG chemkinFile = os.path.join(os.path.dirname(inputFile), 'chemkin', 'chem.inp') speciesDict = os.path.join(os.path.dirname(inputFile), 'chemkin', 'species_dictionary.txt') speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict) # Map species in input file to corresponding species in Chemkin file speciesDict = {} for spec0 in rmg.initialSpecies: for species in speciesList: if species.isIsomorphic(spec0): speciesDict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reactionList: if not reaction.pairs: reaction.generatePairs() # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([(speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems()]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList return rmg
def testSaveOutputHTML(self): """ This example is to test if an HTML file can be generated for the provided chemkin model. """ folder = os.path.join(os.getcwd(),'rmgpy/rmg/test_data/saveOutputHTML/') chemkinPath = os.path.join(folder, 'eg6', 'chem_annotated.inp') dictionaryPath = os.path.join(folder,'eg6', 'species_dictionary.txt') # loadChemkinFile species, reactions = loadChemkinFile(chemkinPath, dictionaryPath) # convert it into a reaction model: core = ReactionModel(species, reactions) cerm = CoreEdgeReactionModel(core) out = os.path.join(folder, 'output.html') saveOutputHTML(out, cerm) self.assertTrue(os.path.isfile(out)) os.remove(out) shutil.rmtree(os.path.join(folder,'species'))
def load_fragment_reactions_from_chemkin(chemkin_path, dictionary_path, fragment_smiles_path): """ This method loads chemkin mechanism and generate fragment reactions in irreversible format. """ speciesList, reactionList = loadChemkinFile(chemkin_path, dictionary_path) # load fragment from smiles-like string fragments = [] with open(fragment_smiles_path) as f_in: for line in f_in: if line.strip() and not line.startswith('#') and ':' in line: label, smiles = [token.strip() for token in line.split(":")] frag = Fragment(label=label).from_SMILES_like_string(smiles) frag.assign_representative_species() frag.species_repr.label = label for prev_frag in fragments: if frag.isIsomorphic(prev_frag): raise Exception( 'Isomorphic duplicate found: {0} and {1}'.format( label, prev_frag.label)) fragments.append(frag) # construct label-key fragment dictionary fragments_dict = {} for frag0 in fragments: if frag0.label not in fragments_dict: fragments_dict[frag0.label] = frag0 else: raise Exception( 'Fragment with duplicated labels found: {0}'.format( frag0.label)) orig_fragrxns = [] for rxn0 in reactionList: fragrxts = [fragments_dict[spec.label] for spec in rxn0.reactants] fragprds = [fragments_dict[spec.label] for spec in rxn0.products] fragpairs = [(fragments_dict[rxt.label], fragments_dict[prod.label]) for rxt, prod in rxn0.pairs] fragrxn = FragmentReaction(index=-1, reactants=fragrxts, products=fragprds, kinetics=rxn0.kinetics, reversible=False, pairs=fragpairs, family=rxn0.family) orig_fragrxns.append(fragrxn) revs_fragrxns = [] for rxn0 in reactionList: fragrxts = [fragments_dict[spec.label] for spec in rxn0.products] fragprds = [fragments_dict[spec.label] for spec in rxn0.reactants] fragpairs = [(fragments_dict[prod.label], fragments_dict[rxt.label]) for rxt, prod in rxn0.pairs] revs_kinetics = rxn0.generateReverseRateCoefficient() fragrxn = FragmentReaction(index=-1, reactants=fragrxts, products=fragprds, kinetics=revs_kinetics, reversible=False, pairs=fragpairs, family=rxn0.family) revs_fragrxns.append(fragrxn) return fragments_dict, orig_fragrxns + revs_fragrxns
def loadRMGPyJob(inputFile, chemkinFile=None, speciesDict=None, generateImages=True, useChemkinNames=False, checkDuplicates=True): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ from rmgpy.rmg.main import RMG # Load the specified RMG input file rmg = RMG(inputFile=inputFile) rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG if not chemkinFile: chemkinFile = os.path.join(os.path.dirname(inputFile), 'chemkin', 'chem.inp') if not speciesDict: speciesDict = os.path.join(os.path.dirname(inputFile), 'chemkin', 'species_dictionary.txt') speciesList, reactionList = loadChemkinFile( chemkinFile, speciesDict, useChemkinNames=useChemkinNames, checkDuplicates=checkDuplicates) # Map species in input file to corresponding species in Chemkin file speciesDict = {} for spec0 in rmg.initialSpecies: for species in speciesList: if species.isIsomorphic(spec0): speciesDict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reactionList: if not reaction.pairs: reaction.generatePairs() # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: if isinstance(reactionSystem, LiquidReactor): # If there are constant species, map their input file names to # corresponding species in Chemkin file if reactionSystem.constSPCNames: constSpeciesDict = {} for spec0 in rmg.initialSpecies: for constSpecLabel in reactionSystem.constSPCNames: if spec0.label == constSpecLabel: constSpeciesDict[constSpecLabel] = speciesDict[ spec0].label break reactionSystem.constSPCNames = [ constSpeciesDict[sname] for sname in reactionSystem.constSPCNames ] reactionSystem.initialConcentrations = dict([ (speciesDict[spec], conc) for spec, conc in reactionSystem.initialConcentrations.iteritems() ]) else: reactionSystem.initialMoleFractions = dict([ (speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems() ]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] if reactionSystem.sensitiveSpecies != ['all']: reactionSystem.sensitiveSpecies = [ speciesDict[spec] for spec in reactionSystem.sensitiveSpecies ] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList # Generate species images if generateImages: speciesPath = os.path.join(os.path.dirname(inputFile), 'species') try: os.mkdir(speciesPath) except OSError: pass for species in speciesList: path = os.path.join(speciesPath, '{0!s}.png'.format(species)) if not os.path.exists(path): species.molecule[0].draw(str(path)) return rmg
elif len(model) == 3: transport = True inputModelFiles.append((model[0], model[1], model[2])) else: raise Exception outputChemkinFile = 'chem.inp' outputSpeciesDictionary = 'species_dictionary.txt' outputTransportFile = 'tran.dat' if transport else None # Load the models to merge models = [] for chemkin, speciesPath, transportPath in inputModelFiles: print 'Loading model #{0:d}...'.format(len(models)+1) model = ReactionModel() model.species, model.reactions = loadChemkinFile(chemkin, speciesPath, transportPath=transportPath) models.append(model) allSpecies = [] speciesIndices = [[] for i in range(len(models))] for i, model in enumerate(models): speciesIndices[i] = [] for j, species in enumerate(model.species): for index, species0 in enumerate(allSpecies): if species0.isIsomorphic(species): speciesIndices[i].append(index) break; else: allSpecies.append(species) speciesIndices[i].append(allSpecies.index(species)) # Reassign species names and labels according to the list of all species in all models
def testColliderModel(self): """ Test the solver's ability to simulate a model with collision efficiencies. """ chemFile = os.path.join(os.path.dirname(__file__), 'files', 'collider_model', 'chem.inp') dictionaryFile = os.path.join(os.path.dirname(__file__), 'files', 'collider_model', 'species_dictionary.txt') speciesList, reactionList = loadChemkinFile(chemFile, dictionaryFile) smilesDict = { 'H': '[H]', 'HO2': '[O]O', 'O2': '[O][O]', 'Ar': '[Ar]', 'N2': 'N#N', 'CO2': 'O=C=O', 'CH3': '[CH3]', 'CH4': 'C' } speciesDict = {} for name, smiles in smilesDict.iteritems(): mol = Molecule(SMILES=smiles) for species in speciesList: if species.isIsomorphic(mol): speciesDict[name] = species break T = 1000 # K P = 10 # Pa initialMoleFractions = { speciesDict['O2']: 0.5, speciesDict['H']: 0.5, speciesDict['CO2']: 1.0, speciesDict['Ar']: 4.0 } # Initialize the model rxnSystem = SimpleReactor(T, P, initialMoleFractions=initialMoleFractions, termination=None) rxnSystem.initializeModel(speciesList, reactionList, [], []) # Advance to time = 0.1 s rxnSystem.advance(0.1) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulatedMoleFracs = rxnSystem.y / numpy.sum(rxnSystem.y) expectedMoleFracs = numpy.array([ 0.6666667, 0, 0, 0, 0.1666667, 0, 0.08333333, 0.08333333, 2.466066000000000E-10, 0, 0, 0, 0, 0 ]) for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i], expectedMoleFracs[i]) # Advance to time = 5 s rxnSystem.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulatedMoleFracs = rxnSystem.y / numpy.sum(rxnSystem.y) expectedMoleFracs = numpy.array([ 0.6666667, 0, 0, 0, 0.1666667, 0, 0.08333332, 0.08333332, 1.233033000000000E-08, 0, 0, 0, 0, 0 ]) for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i], expectedMoleFracs[i]) # Try a new set of conditions T = 850 # K P = 200 # Pa initialMoleFractions = { speciesDict['O2']: 0.5, speciesDict['H']: 1, speciesDict['CO2']: 1, speciesDict['N2']: 4, speciesDict['CH3']: 1 } # Initialize the model rxnSystem = SimpleReactor(T, P, initialMoleFractions=initialMoleFractions, termination=None) rxnSystem.initializeModel(speciesList, reactionList, [], []) # Advance to time = 5 s rxnSystem.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulatedMoleFracs = rxnSystem.y / numpy.sum(rxnSystem.y) expectedMoleFracs = numpy.array([ 0, 0, 0, 0.5487241, 0.137181, 0, 0.1083234, 0.0685777, 1.280687000000000E-05, 0, 0, 0, 0.1083362, 0.02884481 ]) for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i], expectedMoleFracs[i])
help='The path of the chemkin file') parser.add_argument('dictionaryPath', metavar='DICTIONARY', type=str, nargs=1, help='The path of the RMG dictionary file') parser.add_argument('outputDirectory', metavar='OUTPUTDIR', type=str, nargs=1, help='The desired output directory for the library files') parser.add_argument('-r', '--removeH', action='store_true', help='remove explicit hydrogens') args = parser.parse_args() chemkinPath = args.chemkinPath[0] dictionaryPath = args.dictionaryPath[0] outputDir = args.outputDirectory[0] removeH = args.removeH print removeH speciesList, reactionList = loadChemkinFile(chemkinPath, dictionaryPath) # load thermo library entries thermoLibrary = ThermoLibrary() for i in range(len(speciesList)): species = speciesList[i] rdkitmol = species.molecule[0].toRDKitMol(removeHs=False) species.molecule = [Molecule().fromRDKitMol(rdkitmol)]#[0].toAdjacencyList(removeH=False) print species.molecule[0].toAdjacencyList(removeH = removeH) if species.thermo: thermoLibrary.loadEntry(index = i + 1, label = species.label, molecule = species.molecule[0].toAdjacencyList(removeH = removeH), thermo = species.thermo, shortDesc = species.thermo.comment )
def loadRMGJavaJob(inputFile, chemkinFile=None, speciesDict=None): """ Load the results of an RMG-Java job generated from the given `inputFile`. """ from rmgpy.molecule import Molecule # Load the specified RMG-Java input file # This implementation only gets the information needed to generate flux diagrams rmg = RMG() rmg.loadRMGJavaInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG-Java if not chemkinFile: chemkinFile = os.path.join(os.path.dirname(inputFile), 'chemkin', 'chem.inp') if not speciesDict: speciesDict = os.path.join(os.path.dirname(inputFile), 'RMG_Dictionary.txt') speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict) # Bath gas species don't appear in RMG-Java species dictionary, so handle # those as a special case for species in speciesList: if species.label == 'Ar': species.molecule = [Molecule().fromSMILES('[Ar]')] elif species.label == 'Ne': species.molecule = [Molecule().fromSMILES('[Ne]')] elif species.label == 'He': species.molecule = [Molecule().fromSMILES('[He]')] elif species.label == 'N2': species.molecule = [Molecule().fromSMILES('N#N')] # Map species in input file to corresponding species in Chemkin file speciesDict = {} for spec0 in rmg.initialSpecies: for species in speciesList: if species.isIsomorphic(spec0): speciesDict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reactionList: if not reaction.pairs: reaction.generatePairs() # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([(speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems()]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): if t.species not in speciesDict.values(): t.species = speciesDict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList # RMG-Java doesn't generate species images, so draw them ourselves now speciesPath = os.path.join(os.path.dirname(inputFile), 'species') try: os.mkdir(speciesPath) except OSError: pass for species in speciesList: path = os.path.join(speciesPath + '/{0!s}.png'.format(species)) species.molecule[0].draw(str(path)) return rmg
def testParseKinetics(self): from rmgpy.chemkin import loadChemkinFile import rmgpy species, reactions = loadChemkinFile(os.path.join(os.path.dirname(rmgpy.__file__), 'data','kinetics','parsing_data','chem_annotated.inp'), os.path.join(os.path.dirname(rmgpy.__file__), 'data','kinetics','parsing_data','species_dictionary.txt') ) sources = [] for reaction in reactions: sources.append(self.database.kinetics.extractSourceFromComments(reaction)) # Source 0 comes from a kinetics library self.assertTrue('Library' in sources[0]) self.assertEqual(sources[0]['Library'], 'GRI-Mech3.0') reconstructedKinetics = self.database.kinetics.reconstructKineticsFromSource(reactions[0],sources[0],fixBarrierHeight=True) A = reconstructedKinetics.A.value_si n = reconstructedKinetics.n.value_si self.assertAlmostEqual(reactions[0].kinetics.A.value_si,A) self.assertAlmostEqual(reactions[0].kinetics.n.value_si,n) # Source 1 comes from a single exact match to a rate rule self.assertTrue('Rate Rules' in sources[1]) self.assertEqual(sources[1]['Rate Rules'][0],'Disproportionation') rules = sources[1]['Rate Rules'][1]['rules'] self.assertEqual(len(rules),1) self.assertEqual(rules[0][0].label, 'O_pri_rad;Cmethyl_Csrad') reconstructedKinetics = self.database.kinetics.reconstructKineticsFromSource(reactions[1],sources[1],fixBarrierHeight=True) A = reconstructedKinetics.A.value_si n = reconstructedKinetics.n.value_si self.assertAlmostEqual(reactions[1].kinetics.A.value_si,A) self.assertAlmostEqual(reactions[1].kinetics.n.value_si,n) # Source 2 comes from an averaged rate rule that even contains a rate rule from a training reaction self.assertTrue('Rate Rules' in sources[2]) self.assertEqual(sources[2]['Rate Rules'][0],'Disproportionation') expectedRules = ['O2b;O_Csrad', 'O_atom_triplet;O_Csrad', 'CH2_triplet;O_Csrad', 'O_pri_rad;O_Csrad', 'O_rad/NonDeC;O_Csrad','O_rad/NonDeO;O_Csrad', 'Cd_pri_rad;O_Csrad', 'CO_pri_rad;O_Csrad','C_methyl;O_Csrad','C_rad/H2/Cs;O_Csrad','C_rad/H2/Cd;O_Csrad', 'C_rad/H2/O;O_Csrad','C_rad/H/NonDeC;O_Csrad','C_rad/Cs3;O_Csrad','H_rad;O_Csrad'] rules = sources[2]['Rate Rules'][1]['rules'] training = sources[2]['Rate Rules'][1]['training'] actualRuleLabels = [rule.label for rule, weight in rules] self.assertEqual(len(rules),len(expectedRules)) for rule in expectedRules: self.assertTrue(rule in actualRuleLabels) self.assertEqual(len(training),1) self.assertEqual(training[0][1].index,1) # Assert that the index of that training reaction is 1 reconstructedKinetics = self.database.kinetics.reconstructKineticsFromSource(reactions[2],sources[2],fixBarrierHeight=True) A = reconstructedKinetics.A.value_si n = reconstructedKinetics.n.value_si A = round(A, -int(numpy.floor(numpy.log10(abs(A))))+3) # Do some rounding since chemkin format kinetics are rounded n = round(n,3) self.assertAlmostEqual(reactions[2].kinetics.A.value_si,A) self.assertAlmostEqual(reactions[2].kinetics.n.value_si,n) # Source 3 comes from a training reaction match self.assertTrue('Training' in sources[3]) familyLabel = sources[3]['Training'][0] trainingRxn = sources[3]['Training'][1] self.assertEqual(familyLabel,'Disproportionation') self.assertEqual(trainingRxn.label, 'C2H + CH3O <=> C2H2 + CH2O') reconstructedKinetics = self.database.kinetics.reconstructKineticsFromSource(reactions[3],sources[3], fixBarrierHeight=True) A = reconstructedKinetics.A.value_si n = reconstructedKinetics.n.value_si self.assertAlmostEqual(reactions[3].kinetics.A.value_si,A) self.assertAlmostEqual(reactions[3].kinetics.n.value_si,n) # Source 3 comes from a pdep reaction self.assertTrue('PDep' in sources[4]) self.assertEqual(sources[4]['PDep'], 7)
def testColliderModel(self): """ Test the solver's ability to simulate a model with collision efficiencies. """ chemFile = os.path.join(os.path.dirname(__file__),'files','collider_model','chem.inp') dictionaryFile = os.path.join(os.path.dirname(__file__),'files','collider_model','species_dictionary.txt') speciesList, reactionList = loadChemkinFile(chemFile, dictionaryFile) smilesDict = {'H':'[H]','HO2':'[O]O','O2':'[O][O]','Ar':'[Ar]','N2':'N#N','CO2':'O=C=O','CH3':'[CH3]','CH4':'C'} speciesDict = {} for name, smiles in smilesDict.iteritems(): mol = Molecule(SMILES=smiles) for species in speciesList: if species.isIsomorphic(mol): speciesDict[name] = species break T = 1000 # K P = 10 # Pa initialMoleFractions = {speciesDict['O2']:0.5, speciesDict['H']:0.5, speciesDict['CO2']:1.0, speciesDict['Ar']:4.0} # Initialize the model rxnSystem = SimpleReactor(T,P,initialMoleFractions=initialMoleFractions,termination=None) rxnSystem.initializeModel(speciesList, reactionList, [], []) # Advance to time = 0.1 s rxnSystem.advance(0.1) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulatedMoleFracs = rxnSystem.y/numpy.sum(rxnSystem.y) expectedMoleFracs = numpy.array([0.6666667,0,0,0,0.1666667,0, 0.08333333,0.08333333,2.466066000000000E-10,0,0,0,0,0]) for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i],expectedMoleFracs[i]) # Advance to time = 5 s rxnSystem.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN expectedMoleFracs = numpy.array([0.6666667,0,0,0, 0.1666667,0,0.08333332,0.08333332,1.233033000000000E-08,0,0,0,0,0]) for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i],expectedMoleFracs[i]) # Try a new set of conditions T = 850 # K P = 200 # Pa initialMoleFractions = {speciesDict['O2']:0.5, speciesDict['H']:1, speciesDict['CO2']:1, speciesDict['N2']:4, speciesDict['CH3']:1} # Initialize the model rxnSystem = SimpleReactor(T,P,initialMoleFractions=initialMoleFractions,termination=None) rxnSystem.initializeModel(speciesList, reactionList, [], []) # Advance to time = 5 s rxnSystem.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulatedMoleFracs = rxnSystem.y/numpy.sum(rxnSystem.y) expectedMoleFracs = numpy.array([0,0,0,0.5487241, 0.137181,0, 0.1083234, 0.0685777, 1.280687000000000E-05, 0,0,0, 0.1083362, 0.02884481]) for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i],expectedMoleFracs[i])
def loadRMGJavaJob(inputFile, chemkinFile=None, speciesDict=None): """ Load the results of an RMG-Java job generated from the given `inputFile`. """ from rmgpy.molecule import Molecule # Load the specified RMG-Java input file # This implementation only gets the information needed to generate flux diagrams rmg = RMG() rmg.loadRMGJavaInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG-Java if not chemkinFile: chemkinFile = os.path.join(os.path.dirname(inputFile), 'chemkin', 'chem.inp') if not speciesDict: speciesDict = os.path.join(os.path.dirname(inputFile), 'RMG_Dictionary.txt') speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict) # Bath gas species don't appear in RMG-Java species dictionary, so handle # those as a special case for species in speciesList: if species.label == 'Ar': species.molecule = [Molecule().fromSMILES('[Ar]')] elif species.label == 'Ne': species.molecule = [Molecule().fromSMILES('[Ne]')] elif species.label == 'He': species.molecule = [Molecule().fromSMILES('[He]')] elif species.label == 'N2': species.molecule = [Molecule().fromSMILES('N#N')] # Map species in input file to corresponding species in Chemkin file speciesDict = {} for spec0 in rmg.initialSpecies: for species in speciesList: if species.isIsomorphic(spec0): speciesDict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reactionList: if not reaction.pairs: reaction.generatePairs() # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([ (speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems() ]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): if t.species not in speciesDict.values(): t.species = speciesDict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList # RMG-Java doesn't generate species images, so draw them ourselves now speciesPath = os.path.join(os.path.dirname(inputFile), 'species') try: os.mkdir(speciesPath) except OSError: pass for species in speciesList: path = os.path.join(speciesPath + '/{0!s}.png'.format(species)) species.molecule[0].draw(str(path)) return rmg
def loadRMGPyJob(inputFile, chemkinFile=None, speciesDict=None, generateImages=True): """ Load the results of an RMG-Py job generated from the given `inputFile`. """ # Load the specified RMG input file rmg = RMG() rmg.loadInput(inputFile) rmg.outputDirectory = os.path.abspath(os.path.dirname(inputFile)) # Load the final Chemkin model generated by RMG if not chemkinFile: chemkinFile = os.path.join(os.path.dirname(inputFile), 'chemkin', 'chem.inp') if not speciesDict: speciesDict = os.path.join(os.path.dirname(inputFile), 'chemkin', 'species_dictionary.txt') speciesList, reactionList = loadChemkinFile(chemkinFile, speciesDict) # Map species in input file to corresponding species in Chemkin file speciesDict = {} for spec0 in rmg.initialSpecies: for species in speciesList: if species.isIsomorphic(spec0): speciesDict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reactionList: if not reaction.pairs: reaction.generatePairs() # Replace species in input file with those in Chemkin file for reactionSystem in rmg.reactionSystems: reactionSystem.initialMoleFractions = dict([ (speciesDict[spec], frac) for spec, frac in reactionSystem.initialMoleFractions.iteritems() ]) for t in reactionSystem.termination: if isinstance(t, TerminationConversion): t.species = speciesDict[t.species] reactionSystem.sensitiveSpecies = [ speciesDict[spec] for spec in reactionSystem.sensitiveSpecies ] # Set reaction model to match model loaded from Chemkin file rmg.reactionModel.core.species = speciesList rmg.reactionModel.core.reactions = reactionList # Generate species images if generateImages: speciesPath = os.path.join(os.path.dirname(inputFile), 'species') try: os.mkdir(speciesPath) except OSError: pass for species in speciesList: path = os.path.join(speciesPath, '{0!s}.png'.format(species)) if not os.path.exists(path): species.molecule[0].draw(str(path)) return rmg
def testSpecificColliderModel(self): """ Test the solver's ability to simulate a model with specific third body species collision efficiencies. """ chemFile = os.path.join(os.path.dirname(__file__),'files','specific_collider_model','chem.inp') dictionaryFile = os.path.join(os.path.dirname(__file__),'files','specific_collider_model','species_dictionary.txt') speciesList, reactionList = loadChemkinFile(chemFile, dictionaryFile) smilesDict = {'Ar':'[Ar]','N2(1)':'N#N','O2':'[O][O]','H':'[H]','CH3':'[CH3]','CH4':'C'} speciesDict = {} for name, smiles in smilesDict.iteritems(): mol = Molecule(SMILES=smiles) for species in speciesList: if species.isIsomorphic(mol): speciesDict[name] = species break T = 1000 # K P = 10 # Pa initialMoleFractions = {speciesDict['Ar']:2.0, speciesDict['N2(1)']:1.0, speciesDict['O2']:0.5, speciesDict['H']:0.1, speciesDict['CH3']:0.1, speciesDict['CH4']:0.001} # Initialize the model rxnSystem = SimpleReactor(T,P,initialMoleFractions=initialMoleFractions,termination=None) rxnSystem.initializeModel(speciesList, reactionList, [], []) # Advance to time = 0.1 s rxnSystem.advance(0.1) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulatedMoleFracs = rxnSystem.y/numpy.sum(rxnSystem.y) expectedMoleFracs = numpy.array([0.540394532, 0.270197216, 0.135098608, 0.027019722, 0.027019722, 0.000270202]) # order: Ar, N2, O2, H, CH3, CH4 for i in xrange(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i],expectedMoleFracs[i],6) # Advance to time = 5 s rxnSystem.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN expectedMoleFracs = numpy.array([0.540394573, 0.270197287, 0.135098693, 0.027019519, 0.027019519, 0.00027041]) # order: Ar, N2, O2, H, CH3, CH4 for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i],expectedMoleFracs[i],6) # Try a new set of conditions T = 850 # K P = 200 # Pa initialMoleFractions = {speciesDict['Ar']:1.0, speciesDict['N2(1)']:0.5, speciesDict['O2']:0.5, speciesDict['H']:0.001, speciesDict['CH3']:0.01, speciesDict['CH4']:0.5} # Initialize the model rxnSystem = SimpleReactor(T,P,initialMoleFractions=initialMoleFractions,termination=None) rxnSystem.initializeModel(speciesList, reactionList, [], []) # Advance to time = 5 s rxnSystem.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulatedMoleFracs = rxnSystem.y/numpy.sum(rxnSystem.y) expectedMoleFracs = numpy.array([0.398247713, 0.199123907, 0.199123907, 0.000398169, 0.003982398, 0.199123907]) # order: Ar, N2, O2, H, CH3, CH4 for i in range(len(simulatedMoleFracs)): self.assertAlmostEqual(simulatedMoleFracs[i],expectedMoleFracs[i],6)
def execute(chemkin1, speciesDict1, thermo1, chemkin2, speciesDict2, thermo2, **kwargs): model1 = ReactionModel() model1.species, model1.reactions = loadChemkinFile(chemkin1, speciesDict1, thermoPath = thermo1) model2 = ReactionModel() model2.species, model2.reactions = loadChemkinFile(chemkin2, speciesDict2, thermoPath = thermo2) commonSpecies, uniqueSpecies1, uniqueSpecies2 = compareModelSpecies(model1, model2) commonReactions, uniqueReactions1, uniqueReactions2 = compareModelReactions(model1, model2) try: diffOnly = kwargs['diffOnly'] except KeyError: diffOnly = False try: commonDiffOnly = kwargs['commonDiffOnly'] except KeyError: commonDiffOnly = False if diffOnly or commonDiffOnly: commonSpecies = filter(lambda x: not identicalThermo(x), commonSpecies) commonReactions = filter(lambda x: not identicalKinetics(x), commonReactions) if commonDiffOnly: uniqueSpecies1 = [] uniqueSpecies2 = [] uniqueReactions1 = [] uniqueReactions2 = [] try: web = kwargs['web'] except KeyError: web = False if not web: logging.info('{0:d} species were found in both models:'.format(len(commonSpecies))) for spec1, spec2 in commonSpecies: logging.info(' {0!s}'.format(spec1)) if spec1.thermo and spec2.thermo: spec1.molecule[0].getSymmetryNumber() logging.info(' {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f} {8:7.2f}'.format( spec1.thermo.getEnthalpy(300) / 4184., spec1.thermo.getEntropy(300) / 4.184, spec1.thermo.getHeatCapacity(300) / 4.184, spec1.thermo.getHeatCapacity(400) / 4.184, spec1.thermo.getHeatCapacity(500) / 4.184, spec1.thermo.getHeatCapacity(600) / 4.184, spec1.thermo.getHeatCapacity(800) / 4.184, spec1.thermo.getHeatCapacity(1000) / 4.184, spec1.thermo.getHeatCapacity(1500) / 4.184, )) logging.info(' {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f} {8:7.2f}'.format( spec2.thermo.getEnthalpy(300) / 4184., spec2.thermo.getEntropy(300) / 4.184, spec2.thermo.getHeatCapacity(300) / 4.184, spec2.thermo.getHeatCapacity(400) / 4.184, spec2.thermo.getHeatCapacity(500) / 4.184, spec2.thermo.getHeatCapacity(600) / 4.184, spec2.thermo.getHeatCapacity(800) / 4.184, spec2.thermo.getHeatCapacity(1000) / 4.184, spec2.thermo.getHeatCapacity(1500) / 4.184, )) logging.info('{0:d} species were only found in the first model:'.format(len(uniqueSpecies1))) for spec in uniqueSpecies1: logging.info(' {0!s}'.format(spec)) logging.info('{0:d} species were only found in the second model:'.format(len(uniqueSpecies2))) for spec in uniqueSpecies2: logging.info(' {0!s}'.format(spec)) logging.info('{0:d} reactions were found in both models:'.format(len(commonReactions))) for rxn1, rxn2 in commonReactions: logging.info(' {0!s}'.format(rxn1)) if rxn1.kinetics and rxn2.kinetics: logging.info(' {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f}'.format( math.log10(rxn1.kinetics.getRateCoefficient(300, 1e5)), math.log10(rxn1.kinetics.getRateCoefficient(400, 1e5)), math.log10(rxn1.kinetics.getRateCoefficient(500, 1e5)), math.log10(rxn1.kinetics.getRateCoefficient(600, 1e5)), math.log10(rxn1.kinetics.getRateCoefficient(800, 1e5)), math.log10(rxn1.kinetics.getRateCoefficient(1000, 1e5)), math.log10(rxn1.kinetics.getRateCoefficient(1500, 1e5)), math.log10(rxn1.kinetics.getRateCoefficient(2000, 1e5)), )) logging.info(' {0:7.2f} {1:7.2f} {2:7.2f} {3:7.2f} {4:7.2f} {5:7.2f} {6:7.2f} {7:7.2f}'.format( math.log10(rxn2.kinetics.getRateCoefficient(300, 1e5)), math.log10(rxn2.kinetics.getRateCoefficient(400, 1e5)), math.log10(rxn2.kinetics.getRateCoefficient(500, 1e5)), math.log10(rxn2.kinetics.getRateCoefficient(600, 1e5)), math.log10(rxn2.kinetics.getRateCoefficient(800, 1e5)), math.log10(rxn2.kinetics.getRateCoefficient(1000, 1e5)), math.log10(rxn2.kinetics.getRateCoefficient(1500, 1e5)), math.log10(rxn2.kinetics.getRateCoefficient(2000, 1e5)), )) logging.info('{0:d} reactions were only found in the first model:'.format(len(uniqueReactions1))) for rxn in uniqueReactions1: logging.info(' {0!s}'.format(rxn)) logging.info('{0:d} reactions were only found in the second model:'.format(len(uniqueReactions2))) for rxn in uniqueReactions2: logging.info(' {0!s}'.format(rxn)) logging.info("Saving output in diff.html") try: wd = kwargs['wd'] except KeyError: wd = os.getcwd() outputPath = os.path.join(wd, 'diff.html') saveDiffHTML(outputPath, commonSpecies, uniqueSpecies1, uniqueSpecies2, commonReactions, uniqueReactions1, uniqueReactions2) logging.info("Finished!") return commonSpecies, uniqueSpecies1, uniqueSpecies2, commonReactions, uniqueReactions1, uniqueReactions2
parser.add_argument('files', metavar='FILE', type=str, nargs='+', help='the Chemkin files and species dictionaries of each model to merge') args = parser.parse_args() outputChemkinFile = 'chem.inp' outputSpeciesDictionary = 'species_dictionary.txt' assert len(args.files) % 2 == 0 # Load the models to merge models = [] for chemkin, speciesDict in zip(args.files[0::2], args.files[1::2]): print 'Loading model #{0:d}...'.format(len(models)+1) model = ReactionModel() model.species, model.reactions = loadChemkinFile(chemkin, speciesDict) models.append(model) finalModel = ReactionModel() for i, model in enumerate(models): print 'Ignoring common species and reactions from model #{0:d}...'.format(i+1) Nspec0 = len(finalModel.species) Nrxn0 = len(finalModel.reactions) finalModel = finalModel.merge(model) Nspec = len(finalModel.species) Nrxn = len(finalModel.reactions) print 'Added {1:d} out of {2:d} ({3:.1f}%) unique species from model #{0:d}.'.format(i+1, Nspec - Nspec0, len(model.species), (Nspec - Nspec0) * 100. / len(model.species)) print 'Added {1:d} out of {2:d} ({3:.1f}%) unique reactions from model #{0:d}.'.format(i+1, Nrxn - Nrxn0, len(model.reactions), (Nrxn - Nrxn0) * 100. / len(model.reactions))
def run_cantera_job( smiles_dictionary, specie_initial_mol_frac, final_time, temp_initial, initial_p, chemkin_file='', species_dictionary_file='', transport_file=None, reactor_type='IdealGasConstPressureTemperatureReactor', time_units='s', temp_units='K', p_units='atm', species_list=None, reaction_list=None, ): """General function for running Cantera jobs from chemkin files with common defaults =========================== ======================================================================= Input (Required) Description =========================== ======================================================================= smiles_dictionary A dictionary with user names as keys and SMILES strings as values specie_initial_mol_frac A dictionary with user specie names as keys and mol fractions as values final_time Termination time for the simulation temp_initial Initial temperature for the simulation initial_p Initial pressure for the simulation =========================== ======================================================================= Inputs with Defaults Description =========================== ======================================================================= chemkin_file String relative path of the chem.inp or chem_annotated.inp file species_dictionary_file String relative path of species_dictionary file reactor_type String with Cantera reactor type time_units Default is s (min and h are also supported) temp_units Default is K (C is also supported) p_units Default is atm (bar and Pa are also supported) =========================== ======================================================================= Optional Inputs Description =========================== ======================================================================= transport_file String relative path of trans.dat file species_list Output from loadChemkinFile for faster simulation (otherwise generated) reaction_list Output from loadChemkinFile for faster simulation (otherwise generated) =================================================================================================== =========================== ======================================================================= Output Description =========================== ======================================================================= all_data Cantera Simulation Data Object [time, [temp, pressure, spc1, spc2,..]] =================================================================================================== """ logging.info( 'Running a cantera job using the chemkin file {}'.format(chemkin_file)) logging.debug('loading chemkin and species dictionary file') cwd = os.getcwd() if chemkin_file == '': chemkin_file = os.path.join(cwd, 'chem_annotated.inp') if species_dictionary_file == '': species_dictionary_file = os.path.join(cwd, 'species_dictionary.txt') user_species_dictionary = create_species_from_smiles(smiles_dictionary) specie_initial_mol_frac = set_species_mol_fractions( specie_initial_mol_frac, user_species_dictionary) if (not species_list) or (not reaction_list): (species_list, reaction_list) = loadChemkinFile(chemkin_file, species_dictionary_file) name_dictionary = getRMGSpeciesFromUserSpecies( user_species_dictionary.values(), species_list) mol_fractions = {} for (user_name, chemkin_name) in name_dictionary.iteritems(): try: mol_fractions[chemkin_name] = specie_initial_mol_frac[user_name] except KeyError: logging.debug( '{} initial mol fractions set to 0'.format(user_name)) if temp_units == 'C': temp_initial += 273.0 temp_initial = ([temp_initial], 'K') initial_p = ([initial_p], p_units) job = Cantera(speciesList=species_list, reactionList=reaction_list, outputDirectory='') job.loadChemkinModel(chemkin_file, transportFile=transport_file) job.generateConditions([reactor_type], ([final_time], time_units), [mol_fractions], temp_initial, initial_p) logging.debug('Starting Cantera Simulation') all_data = job.simulate() all_data = all_data[0] logging.info('Cantera Simulation Complete') logging.debug('Setting labels to user defined species labels') species_index = {} for i in range(len(species_list)): species_index[species_list[i]] = i + 2 user_index = {} for (user_name, specie) in user_species_dictionary.iteritems(): try: user_index[species_index[name_dictionary[specie]]] = user_name except KeyError: logging.info('{0} is not in the model for {1}'.format( user_name, chemkin_file)) for (indices, user_label) in user_index.iteritems(): try: all_data[1][indices].label = user_label except KeyError: pass return all_data