def save_compare_html(outputDir, chemkin_path1, species_dict_path1, chemkin_path2, species_dict_path2, read_comments1=True, read_comments2=True): """ Saves a model comparison HTML file based on two sets of chemkin and species dictionary files. """ model1 = ReactionModel() model1.species, model1.reactions = load_chemkin_file( chemkin_path1, species_dict_path1, read_comments=read_comments1) model2 = ReactionModel() model2.species, model2.reactions = load_chemkin_file( chemkin_path2, species_dict_path2, read_comments=read_comments2) common_reactions, unique_reactions1, unique_reactions2 = compare_model_reactions( model1, model2) common_species, unique_species1, unique_species2 = compare_model_species( model1, model2) output_path = outputDir + 'diff.html' save_diff_html(output_path, common_species, unique_species1, unique_species2, common_reactions, unique_reactions1, unique_reactions2)
def convert_chemkin_to_yml(chemkin_path, dictionary_path=None, output="chem.rms"): if dictionary_path: spcs, rxns = load_chemkin_file(chemkin_path, dictionary_path=dictionary_path) else: spcs, rxns = load_chemkin_file(chemkin_path) write_yml(spcs, rxns, path=output)
def test_read_and_write_and_read_template_reaction_family_for_minimal_example( self): """ This example tests if family and templates info can be correctly parsed from comments like '!Template reaction: R_Recombination'. """ folder = os.path.join(os.path.dirname(rmgpy.__file__), 'test_data/chemkin/chemkin_py') chemkin_path = os.path.join(folder, 'minimal', 'chem.inp') dictionary_path = os.path.join(folder, 'minimal', 'species_dictionary.txt') # read original chemkin file species, reactions = load_chemkin_file(chemkin_path, dictionary_path) # ensure correct reading reaction1 = reactions[0] self.assertEqual(reaction1.family, "R_Recombination") self.assertEqual(frozenset('C_methyl;C_methyl'.split(';')), frozenset(reaction1.template)) reaction2 = reactions[1] self.assertEqual(reaction2.family, "H_Abstraction") self.assertEqual(frozenset('C/H3/Cs\H3;C_methyl'.split(';')), frozenset(reaction2.template)) # save_chemkin_file chemkin_save_path = os.path.join(folder, 'minimal', 'chem_new.inp') dictionary_save_path = os.path.join(folder, 'minimal', 'species_dictionary_new.txt') save_chemkin_file(chemkin_save_path, species, reactions, verbose=True, check_for_duplicates=True) save_species_dictionary(dictionary_save_path, species, old_style=False) self.assertTrue(os.path.isfile(chemkin_save_path)) self.assertTrue(os.path.isfile(dictionary_save_path)) # read newly written chemkin file to make sure the entire cycle works _, reactions2 = load_chemkin_file(chemkin_save_path, dictionary_save_path) reaction1_new = reactions2[0] self.assertEqual(reaction1_new.family, reaction1_new.family) self.assertEqual(reaction1_new.template, reaction1_new.template) self.assertEqual(reaction1_new.degeneracy, reaction1_new.degeneracy) reaction2_new = reactions2[1] self.assertEqual(reaction2_new.family, reaction2_new.family) self.assertEqual(reaction2_new.template, reaction2_new.template) self.assertEqual(reaction2_new.degeneracy, reaction2_new.degeneracy) # clean up os.remove(chemkin_save_path) os.remove(dictionary_save_path)
def __init__(self, title='', old_dir='', new_dir='', observables=None, expt_data=None, ck2cti=True): self.title = title self.new_dir = new_dir self.old_dir = old_dir self.conditions = None self.expt_data = expt_data if expt_data else [] self.observables = observables if observables else {} # Detect if the transport file exists old_transport_path = None if os.path.exists(os.path.join(old_dir, 'tran.dat')): old_transport_path = os.path.join(old_dir, 'tran.dat') new_transport_path = None if os.path.exists(os.path.join(new_dir, 'tran.dat')): new_transport_path = os.path.join(new_dir, 'tran.dat') # load the species and reactions from each model old_species_list, old_reaction_list = load_chemkin_file( os.path.join(old_dir, 'chem_annotated.inp'), os.path.join(old_dir, 'species_dictionary.txt'), old_transport_path) new_species_list, new_reaction_list = load_chemkin_file( os.path.join(new_dir, 'chem_annotated.inp'), os.path.join(new_dir, 'species_dictionary.txt'), new_transport_path) self.old_sim = Cantera(species_list=old_species_list, reaction_list=old_reaction_list, output_directory=old_dir) self.new_sim = Cantera(species_list=new_species_list, reaction_list=new_reaction_list, output_directory=new_dir) # load each chemkin file into the cantera model if not ck2cti: self.old_sim.load_model() self.new_sim.load_model() else: self.old_sim.load_chemkin_model(os.path.join( old_dir, 'chem_annotated.inp'), transport_file=old_transport_path, quiet=True) self.new_sim.load_chemkin_model(os.path.join( new_dir, 'chem_annotated.inp'), transport_file=new_transport_path, quiet=True)
def test_use_chemkin_names(self): """ Test that the official chemkin names are used as labels for the created Species objects. """ folder = os.path.join(os.path.dirname(rmgpy.__file__), 'test_data/chemkin/chemkin_py') chemkin_path = os.path.join(folder, 'minimal', 'chem.inp') dictionary_path = os.path.join(folder, 'minimal', 'species_dictionary.txt') # load_chemkin_file species, reactions = load_chemkin_file(chemkin_path, dictionary_path, use_chemkin_names=True) expected = [ 'Ar', 'He', 'Ne', 'N2', 'ethane', 'CH3', 'C2H5', 'C' ] for spc, label in zip(species, expected): self.assertEqual(spc.label, label)
def test_read_and_write_template_reaction_family_for_pdd_example(self): """ This example is mainly to ensure comments like '! Kinetics were estimated in this direction instead of the reverse because:' or '! This direction matched an entry in H_Abstraction, the other was just an estimate.' won't interfere reaction family info retrival. """ folder = os.path.join(os.path.dirname(rmgpy.__file__), 'test_data/chemkin/chemkin_py') chemkin_path = os.path.join(folder, 'pdd', 'chem.inp') dictionary_path = os.path.join(folder, 'pdd', 'species_dictionary.txt') # load_chemkin_file species, reactions = load_chemkin_file(chemkin_path, dictionary_path) reaction1 = reactions[0] self.assertEqual(reaction1.family, "H_Abstraction") reaction2 = reactions[1] self.assertEqual(reaction2.family, "H_Abstraction") # save_chemkin_file chemkin_save_path = os.path.join(folder, 'minimal', 'chem_new.inp') dictionary_save_path = os.path.join(folder, 'minimal', 'species_dictionary_new.txt') save_chemkin_file(chemkin_save_path, species, reactions, verbose=False, check_for_duplicates=False) save_species_dictionary(dictionary_save_path, species, old_style=False) self.assertTrue(os.path.isfile(chemkin_save_path)) self.assertTrue(os.path.isfile(dictionary_save_path)) # clean up os.remove(chemkin_save_path) os.remove(dictionary_save_path)
def setUp(self): """ A function run before each unit test in this class. """ from rmgpy.chemkin import load_chemkin_file folder = os.path.join(os.path.dirname(rmgpy.__file__), 'tools/data/various_kinetics') chemkin_path = os.path.join(folder, 'chem_annotated.inp') dictionary_path = os.path.join(folder, 'species_dictionary.txt') transport_path = os.path.join(folder, 'tran.dat') species, reactions = load_chemkin_file(chemkin_path, dictionary_path, transport_path) self.rmg_ctSpecies = [ spec.to_cantera(use_chemkin_identifier=True) for spec in species ] self.rmg_ctReactions = [] for rxn in reactions: converted_reactions = rxn.to_cantera(species, use_chemkin_identifier=True) if isinstance(converted_reactions, list): self.rmg_ctReactions.extend(converted_reactions) else: self.rmg_ctReactions.append(converted_reactions) job = Cantera() job.load_chemkin_model(chemkin_path, transport_file=transport_path, quiet=True) self.ctSpecies = job.model.species() self.ctReactions = job.model.reactions()
def test_write_bidentate_species(self): """Test that species with 2 or more surface sites get proper formatting""" folder = os.path.join(os.path.dirname(rmgpy.__file__), 'test_data/chemkin/chemkin_py') chemkin_path = os.path.join(folder, 'surface', 'chem-surface.inp') dictionary_path = os.path.join(folder, 'surface', 'species_dictionary.txt') chemkin_save_path = os.path.join(folder, 'surface', 'chem-surface-test.inp') species, reactions = load_chemkin_file(chemkin_path, dictionary_path) surface_atom_count = species[3].molecule[0].get_num_atoms('X') self.assertEqual(surface_atom_count, 3) save_chemkin_surface_file(chemkin_save_path, species, reactions, verbose=False, check_for_duplicates=False) bidentate_test = " CH2OX2(52)/2/ \n" tridentate_test = " CHOX3(61)/3/ \n" with open(chemkin_save_path, "r") as f: for i, line in enumerate(f): if i == 3: bidentate_read = line if i == 4: tridentate_read = line self.assertEqual(bidentate_test.strip(), bidentate_read.strip()) self.assertEqual(tridentate_test.strip(), tridentate_read.strip()) os.remove(chemkin_save_path)
def chemkin_to_kinetic_lib(chem_path, dict_path, name, save_path='', use_chemkin_names=True): """ Convert a CHEMKIN file into a RMG kinetic library given species dictionary and the library name. Args: chem_path (str): The path to the CHEMKIN file dict_path (str): The path to a species dictionary name (str): The name of the new library save_path (str): The path to the saving directory. By default, the library will be saved to RMG-database repository use_chemkin_names (bool): Use the original CHEMKIN species name """ # Load the reactions from the CHEMKIN FILE logging.info('Loading CHEMKIN file %s with species dictionary %s' % (chem_path, dict_path)) _, rxns = load_chemkin_file(chem_path, dict_path, use_chemkin_names=use_chemkin_names) kinetic_lib = KineticsLibrary(name=name) kinetic_lib.entries = {} # Create new entries for i in range(len(rxns)): rxn = rxns[i] entry = Entry( index=i + 1, label=str(rxn), item=rxn, data=rxn.kinetics, ) try: entry.long_desc = 'Originally from reaction library: ' + \ rxn.library + "\n" + rxn.kinetics.comment except AttributeError: entry.long_desc = rxn.kinetics.comment kinetic_lib.entries[i + 1] = entry logging.info('Adding reaction %s in to the kinetic library %s' % (entry.label, name)) # Check for duplicates and convert them to multiArrhenius / multiPdepArrehenius kinetic_lib.check_for_duplicates(mark_duplicates=True) kinetic_lib.convert_duplicates_to_multi() # Save the library if not save_path: save_path = os.path.join(settings['database.directory'], 'kinetics', 'libraries') try: os.makedirs(os.path.join(save_path, name)) except: pass logging.info('Saving the kinetic library to %s' % (os.path.join(save_path, name))) kinetic_lib.save(os.path.join(save_path, name, 'reactions.py')) kinetic_lib.save_dictionary(os.path.join(save_path, name, 'dictionary.txt'))
def main(chemkin, dictionary, output, foreign): model = CoreEdgeReactionModel() model.core.species, model.core.reactions = load_chemkin_file(chemkin, dictionary, read_comments=not foreign, check_duplicates=foreign) output_path = os.path.join(output, 'output.html') species_path = os.path.join(output, 'species') if not os.path.isdir(species_path): os.makedirs(species_path) save_output_html(output_path, model)
def get_models_to_merge(input_model_files): """ Reads input file paths and creates a list of ReactionModel """ models = [] for chemkin, species_path, transport_path in input_model_files: print('Loading model #{0:d}...'.format(len(models) + 1)) model = ReactionModel() model.species, model.reactions = load_chemkin_file(chemkin, species_path, transport_path=transport_path) models.append(model) return models
def createJavaKineticsLibrary(self): """ Generates java reaction library files from your chemkin file. """ from rmgpy.chemkin import load_chemkin_file, save_java_kinetics_library chem_path = os.path.join(self.path, 'chemkin', 'chem.inp') dict_path = os.path.join(self.path, 'RMG_Dictionary.txt') spc_list, rxn_list = load_chemkin_file(chem_path, dict_path) save_java_kinetics_library(self.path, spc_list, rxn_list) return
def test_1(self): """ Test basic functionality of /tools/populate_reactions/ """ from rmgpy.chemkin import load_chemkin_file from rmgpy.rmg.model import ReactionModel input_file = os.path.join(rmgpy.get_path(), 'tools', 'data', 'generate', 'input.py') with open(input_file) as fp: response = self.client.post('/tools/populate_reactions/', {'input_file': fp}) self.assertEqual(response.status_code, 200) folder = os.path.join(settings.MEDIA_ROOT, 'rmg', 'tools', 'populateReactions') # Check if inputs were correctly uploaded py_input = os.path.join(folder, 'input.txt') self.assertTrue(os.path.isfile(py_input), 'RMG input file was not uploaded') # Check if outputs were correctly generated html_output = os.path.join(folder, 'output.html') chem_output = os.path.join(folder, 'chemkin', 'chem.inp') dict_output = os.path.join(folder, 'chemkin', 'species_dictionary.txt') self.assertTrue(os.path.isfile(html_output), 'HTML Output was not generated') self.assertTrue(os.path.isfile(chem_output), 'CHEMKIN file was not generated') self.assertTrue(os.path.isfile(dict_output), 'Species dictionary was not generated') # Check that the output is not empty model = ReactionModel() model.species, model.reactions = load_chemkin_file( chem_output, dict_output) self.assertTrue(model.species, 'No species were generated') self.assertTrue(model.reactions, 'No reactions were generated') shutil.rmtree(folder)
def load_model(self, chemkin_path, dictionary_path, transport_path=None): """ Load a RMG-generated model into the Uncertainty class `chemkin_path`: path to the chem_annotated.inp CHEMKIN mechanism `dictionary_path`: path to the species_dictionary.txt file `transport_path`: 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 load_chemkin_file self.species_list, self.reaction_list = load_chemkin_file( chemkin_path, dictionary_path=dictionary_path, transport_path=transport_path)
def test_reactant_n2_is_reactive_and_gets_right_species_identifier(self): """ Test that after loading chemkin files, species such as N2, which is in the default inert list of RMG, should be treated as reactive species and given right species Identifier when it's reacting in reactions. """ folder = os.path.join(os.path.dirname(rmgpy.__file__), 'test_data/chemkin/chemkin_py') chemkin_path = os.path.join(folder, 'NC', 'chem.inp') dictionary_path = os.path.join(folder, 'NC', 'species_dictionary.txt') # load_chemkin_file species, reactions = load_chemkin_file(chemkin_path, dictionary_path, use_chemkin_names=True) for n2 in species: if n2.label == 'N2': break self.assertTrue(n2.reactive) self.assertEqual(get_species_identifier(n2), 'N2(35)')
def test_save_output_html(self): """ This example is to test if an HTML file can be generated for the provided chemkin model. """ folder = os.path.join(os.path.dirname(__file__), 'test_data/saveOutputHTML/') chemkin_path = os.path.join(folder, 'eg6', 'chem_annotated.inp') dictionary_path = os.path.join(folder, 'eg6', 'species_dictionary.txt') # load_chemkin_file species, reactions = load_chemkin_file(chemkin_path, dictionary_path) # convert it into a reaction model: core = ReactionModel(species, reactions) cerm = CoreEdgeReactionModel(core) out = os.path.join(folder, 'output.html') save_output_html(out, cerm) self.assertTrue(os.path.isfile(out)) os.remove(out) shutil.rmtree(os.path.join(folder, 'species'))
def getKinetics(self): """ Extracts the kinetic data from the chemkin file for plotting purposes. """ from rmgpy.chemkin import load_chemkin_file from rmgpy.kinetics import ArrheniusEP, ArrheniusBM from rmgpy.reaction import Reaction from rmgpy.data.base import Entry kinetics_data_list = [] chem_file = os.path.join(self.path, 'chemkin', 'chem.inp') dict_file = os.path.join(self.path, 'RMG_Dictionary.txt') if self.foreign: read_comments = False else: read_comments = True if os.path.exists(dict_file): spc_list, rxn_list = load_chemkin_file(chem_file, dict_file, read_comments=read_comments) else: spc_list, rxn_list = load_chemkin_file(chem_file, read_comments=read_comments) for reaction in rxn_list: # If the kinetics are ArrheniusEP and ArrheniusBM, replace them with Arrhenius if isinstance(reaction.kinetics, (ArrheniusEP, ArrheniusBM)): reaction.kinetics = reaction.kinetics.to_arrhenius( reaction.get_enthalpy_of_reaction(298)) if os.path.exists(dict_file): 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.get_url() 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 = rxn_list.index(reaction) + 1 forward_kinetics = reaction.kinetics forward = True chemkin = reaction.to_chemkin(spc_list) rev_kinetics = reaction.generate_reverse_rate_coefficient() rev_kinetics.comment = 'Fitted reverse reaction. ' + reaction.kinetics.comment rev_reaction = Reaction(reactants=reaction.products, products=reaction.reactants, kinetics=rev_kinetics) chemkin_rev = rev_reaction.to_chemkin(spc_list) kinetics_data_list.append([ reactants, arrow, products, entry, forward_kinetics, source, href, forward, chemkin, rev_kinetics, chemkin_rev ]) return kinetics_data_list
def test_specific_collider_model(self): """ Test the solver's ability to simulate a model with specific third body species collision efficiencies. """ chem_file = os.path.join(os.path.dirname(__file__), 'files', 'specific_collider_model', 'chem.inp') dictionary_file = os.path.join(os.path.dirname(__file__), 'files', 'specific_collider_model', 'species_dictionary.txt') species_list, reaction_list = load_chemkin_file( chem_file, dictionary_file) smiles_dict = { 'Ar': '[Ar]', 'N2(1)': 'N#N', 'O2': '[O][O]', 'H': '[H]', 'CH3': '[CH3]', 'CH4': 'C' } species_dict = {} for name, smiles in smiles_dict.items(): mol = Molecule(smiles=smiles) for species in species_list: if species.is_isomorphic(mol): species_dict[name] = species break T = 1000 # K P = 10 # Pa initial_mole_fractions = { species_dict['Ar']: 2.0, species_dict['N2(1)']: 1.0, species_dict['O2']: 0.5, species_dict['H']: 0.1, species_dict['CH3']: 0.1, species_dict['CH4']: 0.001 } # Initialize the model rxn_system = SimpleReactor( T, P, initial_mole_fractions=initial_mole_fractions, n_sims=1, termination=None) rxn_system.initialize_model(species_list, reaction_list, [], []) # Advance to time = 0.1 s rxn_system.advance(0.1) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulated_mole_fracs = rxn_system.y / np.sum(rxn_system.y) expected_mole_fracs = np.array([ 0.540394532, 0.270197216, 0.135098608, 0.027019722, 0.027019722, 0.000270202 ]) # order: Ar, N2, O2, H, CH3, CH4 for i in range(len(simulated_mole_fracs)): self.assertAlmostEqual(simulated_mole_fracs[i], expected_mole_fracs[i], 6) # Advance to time = 5 s rxn_system.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN expected_mole_fracs = np.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(simulated_mole_fracs)): self.assertAlmostEqual(simulated_mole_fracs[i], expected_mole_fracs[i], 6) # Try a new set of conditions T = 850 # K P = 200 # Pa initial_mole_fractions = { species_dict['Ar']: 1.0, species_dict['N2(1)']: 0.5, species_dict['O2']: 0.5, species_dict['H']: 0.001, species_dict['CH3']: 0.01, species_dict['CH4']: 0.5 } # Initialize the model rxn_system = SimpleReactor( T, P, initial_mole_fractions=initial_mole_fractions, n_sims=1, termination=None) rxn_system.initialize_model(species_list, reaction_list, [], []) # Advance to time = 5 s rxn_system.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulated_mole_fracs = rxn_system.y / np.sum(rxn_system.y) expected_mole_fracs = np.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(simulated_mole_fracs)): self.assertAlmostEqual(simulated_mole_fracs[i], expected_mole_fracs[i], 6)
def test_collider_model(self): """ Test the solver's ability to simulate a model with collision efficiencies. """ chem_file = os.path.join(os.path.dirname(__file__), 'files', 'collider_model', 'chem.inp') dictionary_file = os.path.join(os.path.dirname(__file__), 'files', 'collider_model', 'species_dictionary.txt') species_list, reaction_list = load_chemkin_file( chem_file, dictionary_file) smiles_dict = { 'H': '[H]', 'HO2': '[O]O', 'O2': '[O][O]', 'Ar': '[Ar]', 'N2': 'N#N', 'CO2': 'O=C=O', 'CH3': '[CH3]', 'CH4': 'C' } species_dict = {} for name, smiles in smiles_dict.items(): mol = Molecule(smiles=smiles) for species in species_list: if species.is_isomorphic(mol): species_dict[name] = species break T = 1000 # K P = 10 # Pa initial_mole_fractions = { species_dict['O2']: 0.5, species_dict['H']: 0.5, species_dict['CO2']: 1.0, species_dict['Ar']: 4.0 } # Initialize the model rxn_system = SimpleReactor( T, P, initial_mole_fractions=initial_mole_fractions, n_sims=1, termination=None) rxn_system.initialize_model(species_list, reaction_list, [], []) # Advance to time = 0.1 s rxn_system.advance(0.1) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulated_mole_fracs = rxn_system.y / np.sum(rxn_system.y) expected_mole_fracs = np.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(simulated_mole_fracs)): self.assertAlmostEqual(simulated_mole_fracs[i], expected_mole_fracs[i]) # Advance to time = 5 s rxn_system.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN expected_mole_fracs = np.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(simulated_mole_fracs)): self.assertAlmostEqual(simulated_mole_fracs[i], expected_mole_fracs[i]) # Try a new set of conditions T = 850 # K P = 200 # Pa initial_mole_fractions = { species_dict['O2']: 0.5, species_dict['H']: 1, species_dict['CO2']: 1, species_dict['N2']: 4, species_dict['CH3']: 1 } # Initialize the model rxn_system = SimpleReactor( T, P, initial_mole_fractions=initial_mole_fractions, n_sims=1, termination=None) rxn_system.initialize_model(species_list, reaction_list, [], []) # Advance to time = 5 s rxn_system.advance(5) # Compare simulated mole fractions with expected mole fractions from CHEMKIN simulated_mole_fracs = rxn_system.y / np.sum(rxn_system.y) expected_mole_fracs = np.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(simulated_mole_fracs)): self.assertAlmostEqual(simulated_mole_fracs[i], expected_mole_fracs[i])
def load_rmg_java_job(input_file, chemkin_file=None, species_dict=None, generate_images=True, use_chemkin_names=False, check_duplicates=True): """ Load the results of an RMG-Java job generated from the given `input_file`. """ warnings.warn("The RMG-Java input is no longer supported and may be" \ "removed in version 2.3.", DeprecationWarning) from rmgpy.rmg.main import RMG 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(input_file=input_file) rmg.load_rmg_java_input(input_file) rmg.output_directory = os.path.abspath(os.path.dirname(input_file)) # Load the final Chemkin model generated by RMG-Java if not chemkin_file: chemkin_file = os.path.join(os.path.dirname(input_file), 'chemkin', 'chem.inp') if not species_dict: species_dict = os.path.join(os.path.dirname(input_file), 'RMG_Dictionary.txt') species_list, reaction_list = load_chemkin_file(chemkin_file, species_dict, use_chemkin_names=use_chemkin_names, check_duplicates=check_duplicates) # Bath gas species don't appear in RMG-Java species dictionary, so handle # those as a special case for species in species_list: if species.label == 'Ar': species.molecule = [Molecule().from_smiles('[Ar]')] elif species.label == 'Ne': species.molecule = [Molecule().from_smiles('[Ne]')] elif species.label == 'He': species.molecule = [Molecule().from_smiles('[He]')] elif species.label == 'N2': species.molecule = [Molecule().from_smiles('N#N')] # Map species in input file to corresponding species in Chemkin file species_dict = {} for spec0 in rmg.initial_species: for species in species_list: if species.is_isomorphic(spec0): species_dict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reaction_list: if not reaction.pairs: reaction.generate_pairs() # Replace species in input file with those in Chemkin file for reaction_system in rmg.reaction_systems: reaction_system.initial_mole_fractions = dict( [(species_dict[spec], frac) for spec, frac in reaction_system.initial_mole_fractions.items()]) for t in reaction_system.termination: if isinstance(t, TerminationConversion): if t.species not in list(species_dict.values()): t.species = species_dict[t.species] # Set reaction model to match model loaded from Chemkin file rmg.reaction_model.core.species = species_list rmg.reaction_model.core.reactions = reaction_list # RMG-Java doesn't generate species images, so draw them ourselves now if generate_images: species_path = os.path.join(os.path.dirname(input_file), 'species') try: os.mkdir(species_path) except OSError: pass for species in species_list: path = os.path.join(species_path + '/{0!s}.png'.format(species)) if not os.path.exists(path): species.molecule[0].draw(str(path)) return rmg
metavar='DICTIONARY', type=str, nargs=1, help='The path of the RMG dictionary file') parser.add_argument('name', metavar='NAME', type=str, nargs=1, help='Name of the chemkin library to be saved') args = parser.parse_args() chemkin_path = args.chemkin_path[0] dictionary_path = args.dictionary_path[0] name = args.name[0] species_list, reaction_list = load_chemkin_file(chemkin_path, dictionary_path) thermo_library = ThermoLibrary(name=name) for i in range(len(species_list)): species = species_list[i] if species.thermo: thermo_library.load_entry( index=i + 1, label=species.label, molecule=species.molecule[0].to_adjacency_list(), thermo=species.thermo, ) else: logging.warning( """Species {0} did not contain any thermo data and was omitted from the thermo library.""".format(str(species)))
elif len(model) == 3: transport = True input_model_files.append((model[0], model[1], model[2])) else: raise Exception output_chemkin_file = 'chem.inp' output_species_dictionary = 'species_dictionary.txt' output_transport_file = 'tran.dat' if transport else None # Load the models to merge models = [] for chemkin, speciesPath, transportPath in input_model_files: print('Loading model #{0:d}...'.format(len(models) + 1)) model = ReactionModel() model.species, model.reactions = load_chemkin_file( chemkin, speciesPath, transport_path=transportPath) models.append(model) all_species = [] species_indices = [[] for i in range(len(models))] for i, model in enumerate(models): species_indices[i] = [] for j, species in enumerate(model.species): for index, species0 in enumerate(all_species): if species0.is_isomorphic(species): species_indices[i].append(index) break else: all_species.append(species) species_indices[i].append(all_species.index(species)) # Reassign species names and labels according to the list of all species in all models
def load_rmg_py_job(input_file, chemkin_file=None, species_dict=None, generate_images=True, use_chemkin_names=False, check_duplicates=True): """ Load the results of an RMG-Py job generated from the given `input_file`. """ from rmgpy.rmg.main import RMG # Load the specified RMG input file rmg = RMG(input_file=input_file) rmg.load_input(input_file) rmg.output_directory = os.path.abspath(os.path.dirname(input_file)) # Load the final Chemkin model generated by RMG if not chemkin_file: chemkin_file = os.path.join(os.path.dirname(input_file), 'chemkin', 'chem.inp') if not species_dict: species_dict = os.path.join(os.path.dirname(input_file), 'chemkin', 'species_dictionary.txt') species_list, reaction_list = load_chemkin_file(chemkin_file, species_dict, use_chemkin_names=use_chemkin_names, check_duplicates=check_duplicates) # Created "observed" versions of all reactive species that are not explicitly # identified as "constant" species for reaction_system in rmg.reaction_systems: if isinstance(reaction_system, MBSampledReactor): observed_species_list = [] for species in species_list: if '_obs' not in species.label and species.reactive: for constant_species in reaction_system.constantSpeciesList: if species.is_isomorphic(constant_species): break else: for species2 in species_list: if species2.label == species.label + '_obs': break else: observedspecies = species.copy(deep=True) observedspecies.label = species.label + '_obs' observed_species_list.append(observedspecies) species_list.extend(observed_species_list) # Map species in input file to corresponding species in Chemkin file species_dict = {} for spec0 in rmg.initial_species: for species in species_list: if species.is_isomorphic(spec0): species_dict[spec0] = species break # Generate flux pairs for each reaction if needed for reaction in reaction_list: if not reaction.pairs: reaction.generate_pairs() # Replace species in input file with those in Chemkin file for reaction_system in rmg.reaction_systems: if isinstance(reaction_system, LiquidReactor): # If there are constant species, map their input file names to # corresponding species in Chemkin file if reaction_system.const_spc_names: const_species_dict = {} for spec0 in rmg.initial_species: for constSpecLabel in reaction_system.const_spc_names: if spec0.label == constSpecLabel: const_species_dict[constSpecLabel] = species_dict[spec0].label break reaction_system.const_spc_names = [const_species_dict[sname] for sname in reaction_system.const_spc_names] reaction_system.initial_concentrations = dict( [(species_dict[spec], conc) for spec, conc in reaction_system.initial_concentrations.items()]) elif isinstance(reaction_system, SurfaceReactor): reaction_system.initial_gas_mole_fractions = dict( [(species_dict[spec], frac) for spec, frac in reaction_system.initial_gas_mole_fractions.items()]) reaction_system.initial_surface_coverages = dict( [(species_dict[spec], frac) for spec, frac in reaction_system.initial_surface_coverages.items()]) else: reaction_system.initial_mole_fractions = dict( [(species_dict[spec], frac) for spec, frac in reaction_system.initial_mole_fractions.items()]) for t in reaction_system.termination: if isinstance(t, TerminationConversion): t.species = species_dict[t.species] if reaction_system.sensitive_species != ['all']: reaction_system.sensitive_species = [species_dict[spec] for spec in reaction_system.sensitive_species] # Set reaction model to match model loaded from Chemkin file rmg.reaction_model.core.species = species_list rmg.reaction_model.core.reactions = reaction_list # Generate species images if generate_images: species_path = os.path.join(os.path.dirname(input_file), 'species') try: os.mkdir(species_path) except OSError: pass for species in species_list: path = os.path.join(species_path, '{0!s}.png'.format(species)) if not os.path.exists(path): species.molecule[0].draw(str(path)) return rmg
def execute(chemkin1, species_dict1, thermo1, chemkin2, species_dict2, thermo2, **kwargs): model1 = ReactionModel() model1.species, model1.reactions = load_chemkin_file(chemkin1, species_dict1, thermo_path=thermo1) model2 = ReactionModel() model2.species, model2.reactions = load_chemkin_file(chemkin2, species_dict2, thermo_path=thermo2) common_species, unique_species1, unique_species2 = compare_model_species( model1, model2) common_reactions, unique_reactions1, unique_reactions2 = compare_model_reactions( model1, model2) try: diff_only = kwargs['diffOnly'] except KeyError: diff_only = False try: common_diff_only = kwargs['commonDiffOnly'] except KeyError: common_diff_only = False if diff_only or common_diff_only: common_species = [x for x in common_species if not identical_thermo(x)] common_reactions = [ x for x in common_reactions if not identical_kinetics(x) ] if common_diff_only: unique_species1 = [] unique_species2 = [] unique_reactions1 = [] unique_reactions2 = [] try: web = kwargs['web'] except KeyError: web = False if not web: logging.info('{0:d} species were found in both models:'.format( len(common_species))) for spec1, spec2 in common_species: logging.info(' {0!s}'.format(spec1)) if spec1.thermo and spec2.thermo: spec1.molecule[0].get_symmetry_number() 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.get_enthalpy(300) / 4184., spec1.thermo.get_entropy(300) / 4.184, spec1.thermo.get_heat_capacity(300) / 4.184, spec1.thermo.get_heat_capacity(400) / 4.184, spec1.thermo.get_heat_capacity(500) / 4.184, spec1.thermo.get_heat_capacity(600) / 4.184, spec1.thermo.get_heat_capacity(800) / 4.184, spec1.thermo.get_heat_capacity(1000) / 4.184, spec1.thermo.get_heat_capacity(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.get_enthalpy(300) / 4184., spec2.thermo.get_entropy(300) / 4.184, spec2.thermo.get_heat_capacity(300) / 4.184, spec2.thermo.get_heat_capacity(400) / 4.184, spec2.thermo.get_heat_capacity(500) / 4.184, spec2.thermo.get_heat_capacity(600) / 4.184, spec2.thermo.get_heat_capacity(800) / 4.184, spec2.thermo.get_heat_capacity(1000) / 4.184, spec2.thermo.get_heat_capacity(1500) / 4.184, )) logging.info( '{0:d} species were only found in the first model:'.format( len(unique_species1))) for spec in unique_species1: logging.info(' {0!s}'.format(spec)) logging.info( '{0:d} species were only found in the second model:'.format( len(unique_species2))) for spec in unique_species2: logging.info(' {0!s}'.format(spec)) logging.info('{0:d} reactions were found in both models:'.format( len(common_reactions))) for rxn1, rxn2 in common_reactions: 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.get_rate_coefficient( 300, 1e5)), math.log10(rxn1.kinetics.get_rate_coefficient( 400, 1e5)), math.log10(rxn1.kinetics.get_rate_coefficient( 500, 1e5)), math.log10(rxn1.kinetics.get_rate_coefficient( 600, 1e5)), math.log10(rxn1.kinetics.get_rate_coefficient( 800, 1e5)), math.log10( rxn1.kinetics.get_rate_coefficient(1000, 1e5)), math.log10( rxn1.kinetics.get_rate_coefficient(1500, 1e5)), math.log10( rxn1.kinetics.get_rate_coefficient(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.get_rate_coefficient( 300, 1e5)), math.log10(rxn2.kinetics.get_rate_coefficient( 400, 1e5)), math.log10(rxn2.kinetics.get_rate_coefficient( 500, 1e5)), math.log10(rxn2.kinetics.get_rate_coefficient( 600, 1e5)), math.log10(rxn2.kinetics.get_rate_coefficient( 800, 1e5)), math.log10( rxn2.kinetics.get_rate_coefficient(1000, 1e5)), math.log10( rxn2.kinetics.get_rate_coefficient(1500, 1e5)), math.log10( rxn2.kinetics.get_rate_coefficient(2000, 1e5)), )) logging.info( '{0:d} reactions were only found in the first model:'.format( len(unique_reactions1))) for rxn in unique_reactions1: logging.info(' {0!s}'.format(rxn)) logging.info( '{0:d} reactions were only found in the second model:'.format( len(unique_reactions2))) for rxn in unique_reactions2: logging.info(' {0!s}'.format(rxn)) logging.info("Saving output in diff.html") try: wd = kwargs['wd'] except KeyError: wd = os.getcwd() output_path = os.path.join(wd, 'diff.html') save_diff_html(output_path, common_species, unique_species1, unique_species2, common_reactions, unique_reactions1, unique_reactions2) logging.info("Finished!") return common_species, unique_species1, unique_species2, common_reactions, unique_reactions1, unique_reactions2