def _run_statmech(self, arkane_spc, arkane_file, output_file_path=None, use_bac=False, kinetics=False, plot=False): """ A helper function for running an Arkane statmech job `arkane_spc` is the species() function from Arkane's input.py `arkane_file` is the Arkane species file (either .py or YAML form) `output_file_path` is a path to the Arkane output.py file `use_bac` is a bool flag indicating whether or not to use bond additivity corrections `kinetics` is a bool flag indicating whether this specie sis part of a kinetics job, in which case..?? `plot` is a bool flag indicating whether or not to plot a PDF of the calculated thermo properties """ success = True stat_mech_job = StatMechJob(arkane_spc, arkane_file) stat_mech_job.applyBondEnergyCorrections = use_bac and not kinetics and self.model_chemistry if not kinetics or kinetics and self.model_chemistry: # currently we have to use a model chemistry for thermo stat_mech_job.modelChemistry = self.model_chemistry else: # if this is a klinetics computation and we don't have a valid model chemistry, don't bother about it stat_mech_job.applyAtomEnergyCorrections = False stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor( self.model_chemistry) try: stat_mech_job.execute(outputFile=output_file_path, plot=plot) except Exception: success = False return success
def _run_statmech(self, arkane_spc, arkane_file, output_path=None, use_bac=False, kinetics=False, plot=False): """ A helper function for running an Arkane statmech job. Args: arkane_spc (str): An Arkane species() function representor. arkane_file (str): The path to the Arkane species file (either in .py or YAML form). output_path (str): The path to the folder containing the Arkane output.py file. use_bac (bool): A flag indicating whether or not to use bond additivity corrections (True to use). kinetics (bool) A flag indicating whether this specie is part of a kinetics job. plot (bool): A flag indicating whether to plot a PDF of the calculated thermo properties (True to plot) Returns: bool: Whether the job was successful (True for successful). """ success = True stat_mech_job = StatMechJob(arkane_spc, arkane_file) stat_mech_job.applyBondEnergyCorrections = use_bac and not kinetics and self.sp_level if not kinetics or (kinetics and self.sp_level): # currently we have to use a model chemistry for thermo stat_mech_job.modelChemistry = self.sp_level else: # if this is a kinetics computation and we don't have a valid model chemistry, don't bother about it stat_mech_job.applyAtomEnergyCorrections = False # Use the scaling factor if given, else try determining it from Arkane # (defaults to 1 and prints a warning if not found) stat_mech_job.frequencyScaleFactor = self.freq_scale_factor or assign_frequency_scale_factor(self.freq_level) try: stat_mech_job.execute(output_directory=os.path.join(output_path, 'output.py'), plot=plot) except Exception: success = False return success
def load_input_file(path): """ Load the Arkane input file located at `path` on disk, and return a list of the jobs defined in that file. """ global species_dict, transition_state_dict, reaction_dict, network_dict, job_list # Clear module-level variables species_dict, transition_state_dict, reaction_dict, network_dict = dict( ), dict(), dict(), dict() job_list = [] global_context = {'__builtins__': None} local_context = { '__builtins__': None, 'True': True, 'False': False, 'range': range, # Collision 'TransportData': TransportData, 'SingleExponentialDown': SingleExponentialDown, # Kinetics 'Arrhenius': Arrhenius, # Statistical mechanics 'IdealGasTranslation': IdealGasTranslation, 'LinearRotor': LinearRotor, 'NonlinearRotor': NonlinearRotor, 'KRotor': KRotor, 'SphericalTopRotor': SphericalTopRotor, 'HarmonicOscillator': HarmonicOscillator, 'HinderedRotor': HinderedRotor, 'FreeRotor': FreeRotor, # Thermo 'ThermoData': ThermoData, 'Wilhoit': Wilhoit, 'NASA': NASA, 'NASAPolynomial': NASAPolynomial, # Functions 'reaction': reaction, 'species': species, 'transitionState': transitionState, 'network': network, 'database': database, # Jobs 'kinetics': kinetics, 'statmech': statmech, 'thermo': thermo, 'pressureDependence': pressureDependence, 'explorer': explorer, # Miscellaneous 'SMILES': SMILES, 'adjacencyList': adjacencyList, 'InChI': InChI, } load_necessary_databases() with open(path, 'r') as f: try: exec(f.read(), global_context, local_context) except (NameError, TypeError, SyntaxError): logging.error('The input file {0!r} was invalid:'.format(path)) raise model_chemistry = local_context.get('modelChemistry', '').lower() sp_level, freq_level = process_model_chemistry(model_chemistry) author = local_context.get('author', '') if 'frequencyScaleFactor' in local_context: frequency_scale_factor = local_context.get('frequencyScaleFactor') else: logging.debug( 'Tying to assign a frequencyScaleFactor according to the frequency ' 'level of theory {0}'.format(freq_level)) frequency_scale_factor = assign_frequency_scale_factor(freq_level) use_hindered_rotors = local_context.get('useHinderedRotors', True) use_atom_corrections = local_context.get('useAtomCorrections', True) use_bond_corrections = local_context.get('useBondCorrections', False) bac_type = local_context.get('bondCorrectionType', 'p') atom_energies = local_context.get('atomEnergies', None) directory = os.path.dirname(path) for rxn in reaction_dict.values(): rxn.elementary_high_p = True for job in job_list: if isinstance(job, StatMechJob): job.path = os.path.join(directory, job.path) job.modelChemistry = sp_level job.frequencyScaleFactor = frequency_scale_factor job.includeHinderedRotors = use_hindered_rotors job.applyAtomEnergyCorrections = use_atom_corrections job.applyBondEnergyCorrections = use_bond_corrections job.bondEnergyCorrectionType = bac_type job.atomEnergies = atom_energies if isinstance(job, ThermoJob): job.arkane_species.author = author job.arkane_species.level_of_theory = model_chemistry job.arkane_species.frequency_scale_factor = frequency_scale_factor job.arkane_species.use_hindered_rotors = use_hindered_rotors job.arkane_species.use_bond_corrections = use_bond_corrections if atom_energies is not None: job.arkane_species.atom_energies = atom_energies return job_list, reaction_dict, species_dict, transition_state_dict, network_dict
def process(self): """Process ARC outputs and generate thermo and kinetics""" # Thermo: species_list_for_thermo_parity = list() species_for_thermo_lib = list() for species in self.species_dict.values(): if not species.is_ts and 'ALL converged' in self.output[ species.label]['status']: species_for_thermo_lib.append(species) output_file_path = self._generate_arkane_species_file(species) arkane_spc = arkane_species(str(species.label), species.arkane_file) if species.mol_list: arkane_spc.molecule = species.mol_list stat_mech_job = StatMechJob(arkane_spc, species.arkane_file) stat_mech_job.applyBondEnergyCorrections = self.use_bac stat_mech_job.modelChemistry = self.model_chemistry stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor( self.model_chemistry) stat_mech_job.execute(outputFile=output_file_path, plot=False) if species.generate_thermo: thermo_job = ThermoJob(arkane_spc, 'NASA') thermo_job.execute(outputFile=output_file_path, plot=False) species.thermo = arkane_spc.getThermoData() plotter.log_thermo(species.label, path=output_file_path) species.rmg_species = Species(molecule=[species.mol]) species.rmg_species.reactive = True if species.mol_list: species.rmg_species.molecule = species.mol_list # add resonance structures for thermo determination try: species.rmg_thermo = self.rmgdb.thermo.getThermoData( species.rmg_species) except ValueError: logging.info( 'Could not retrieve RMG thermo for species {0}, possibly due to missing 2D structure ' '(bond orders). Not including this species in the parity plots.' .format(species.label)) else: if species.generate_thermo: species_list_for_thermo_parity.append(species) # Kinetics: rxn_list_for_kinetics_plots = list() arkane_spc_dict = dict() # a dictionary with all species and the TSs for rxn in self.rxn_list: logging.info('\n\n') species = self.species_dict[rxn.ts_label] # The TS if 'ALL converged' in self.output[ species.label]['status'] and rxn.check_ts(): self.copy_freq_output_for_ts(species.label) success = True rxn_list_for_kinetics_plots.append(rxn) output_file_path = self._generate_arkane_species_file(species) arkane_ts = arkane_transition_state(str(species.label), species.arkane_file) arkane_spc_dict[species.label] = arkane_ts stat_mech_job = StatMechJob(arkane_ts, species.arkane_file) stat_mech_job.applyBondEnergyCorrections = False if not self.model_chemistry: stat_mech_job.modelChemistry = self.model_chemistry else: stat_mech_job.applyAtomEnergyCorrections = False stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor( self.model_chemistry) stat_mech_job.execute(outputFile=None, plot=False) for spc in rxn.r_species + rxn.p_species: if spc.label not in arkane_spc_dict.keys(): # add an extra character to the arkane_species label to distinguish between species calculated # for thermo and species calculated for kinetics (where we don't want to use BAC) arkane_spc = arkane_species(str(spc.label + '_'), spc.arkane_file) stat_mech_job = StatMechJob(arkane_spc, spc.arkane_file) arkane_spc_dict[spc.label] = arkane_spc stat_mech_job.applyBondEnergyCorrections = False if not self.model_chemistry: stat_mech_job.modelChemistry = self.model_chemistry else: stat_mech_job.applyAtomEnergyCorrections = False stat_mech_job.frequencyScaleFactor = assign_frequency_scale_factor( self.model_chemistry) stat_mech_job.execute(outputFile=None, plot=False) # thermo_job = ThermoJob(arkane_spc, 'NASA') # thermo_job.execute(outputFile=None, plot=False) # arkane_spc.thermo = arkane_spc.getThermoData() rxn.dh_rxn298 = sum([product.thermo.getEnthalpy(298) for product in arkane_spc_dict.values() if product.label in rxn.products])\ - sum([reactant.thermo.getEnthalpy(298) for reactant in arkane_spc_dict.values() if reactant.label in rxn.reactants]) arkane_rxn = arkane_reaction( label=str(rxn.label), reactants=[ str(label + '_') for label in arkane_spc_dict.keys() if label in rxn.reactants ], products=[ str(label + '_') for label in arkane_spc_dict.keys() if label in rxn.products ], transitionState=rxn.ts_label, tunneling='Eckart') kinetics_job = KineticsJob(reaction=arkane_rxn, Tmin=self.t_min, Tmax=self.t_max, Tcount=self.t_count) logging.info('Calculating rate for reaction {0}'.format( rxn.label)) try: kinetics_job.execute(outputFile=output_file_path, plot=False) except ValueError as e: """ ValueError: One or both of the barrier heights of -9.35259 and 62.6834 kJ/mol encountered in Eckart method are invalid. """ logging.error( 'Failed to generate kinetics for {0} with message:\n{1}' .format(rxn.label, e)) success = False if success: rxn.kinetics = kinetics_job.reaction.kinetics plotter.log_kinetics(species.label, path=output_file_path) rxn.rmg_reactions = rmgdb.determine_rmg_kinetics( rmgdb=self.rmgdb, reaction=rxn.rmg_reaction, dh_rxn298=rxn.dh_rxn298) logging.info('\n\n') output_dir = os.path.join(self.project_directory, 'output') if species_list_for_thermo_parity: plotter.draw_thermo_parity_plots(species_list_for_thermo_parity, path=output_dir) libraries_path = os.path.join(output_dir, 'RMG libraries') # species_list = [spc for spc in self.species_dict.values()] plotter.save_thermo_lib(species_for_thermo_lib, path=libraries_path, name=self.project, lib_long_desc=self.lib_long_desc) if rxn_list_for_kinetics_plots: plotter.draw_kinetics_plots(rxn_list_for_kinetics_plots, path=output_dir, t_min=self.t_min, t_max=self.t_max, t_count=self.t_count) libraries_path = os.path.join(output_dir, 'RMG libraries') plotter.save_kinetics_lib(rxn_list=rxn_list_for_kinetics_plots, path=libraries_path, name=self.project, lib_long_desc=self.lib_long_desc) self.clean_output_directory()
with open(path, 'r') as f: try: exec f in global_context, local_context except (NameError, TypeError, SyntaxError), e: logging.error('The input file {0!r} was invalid:'.format(path)) raise model_chemistry = local_context.get('modelChemistry', '') level_of_theory = local_context.get('levelOfTheory', '') author = local_context.get('author', '') if 'frequencyScaleFactor' not in local_context: logging.debug( 'Assigning a frequencyScaleFactor according to the modelChemistry...' ) frequency_scale_factor = assign_frequency_scale_factor(model_chemistry) else: frequency_scale_factor = local_context.get('frequencyScaleFactor') use_hindered_rotors = local_context.get('useHinderedRotors', True) use_atom_corrections = local_context.get('useAtomCorrections', True) use_bond_corrections = local_context.get('useBondCorrections', False) atom_energies = local_context.get('atomEnergies', None) directory = os.path.dirname(path) for rxn in reactionDict.values(): rxn.elementary_high_p = True for job in jobList: if isinstance(job, StatMechJob): job.path = os.path.join(directory, job.path)
'InChI': InChI, } loadNecessaryDatabases() with open(path, 'r') as f: try: exec f in global_context, local_context except (NameError, TypeError, SyntaxError), e: logging.error('The input file {0!r} was invalid:'.format(path)) raise modelChemistry = local_context.get('modelChemistry', '') if 'frequencyScaleFactor' not in local_context: logging.debug('Assigning a frequencyScaleFactor according to the modelChemistry...') frequencyScaleFactor = assign_frequency_scale_factor(modelChemistry) else: frequencyScaleFactor = local_context.get('frequencyScaleFactor') useHinderedRotors = local_context.get('useHinderedRotors', True) useAtomCorrections = local_context.get('useAtomCorrections', True) useBondCorrections = local_context.get('useBondCorrections', False) atomEnergies = local_context.get('atomEnergies', None) directory = os.path.dirname(path) for rxn in reactionDict.values(): rxn.elementary_high_p = True for job in jobList: if isinstance(job, StatMechJob): job.path = os.path.join(directory, job.path)
def loadInputFile(path): """ Load the Arkane input file located at `path` on disk, and return a list of the jobs defined in that file. """ global speciesDict, transitionStateDict, reactionDict, networkDict, jobList # Clear module-level variables speciesDict = {} transitionStateDict = {} reactionDict = {} networkDict = {} jobList = [] global_context = { '__builtins__': None } local_context = { '__builtins__': None, 'True': True, 'False': False, 'range': range, # Collision 'TransportData': TransportData, 'SingleExponentialDown': SingleExponentialDown, # Kinetics 'Arrhenius': Arrhenius, # Statistical mechanics 'IdealGasTranslation': IdealGasTranslation, 'LinearRotor': LinearRotor, 'NonlinearRotor': NonlinearRotor, 'KRotor': KRotor, 'SphericalTopRotor': SphericalTopRotor, 'HarmonicOscillator': HarmonicOscillator, 'HinderedRotor': HinderedRotor, 'FreeRotor':FreeRotor, # Thermo 'ThermoData': ThermoData, 'Wilhoit': Wilhoit, 'NASA': NASA, 'NASAPolynomial': NASAPolynomial, # Functions 'reaction': reaction, 'species': species, 'transitionState': transitionState, 'network': network, 'database': database, # Jobs 'kinetics': kinetics, 'statmech': statmech, 'thermo': thermo, 'pressureDependence': pressureDependence, 'explorer':explorer, # Miscellaneous 'SMILES': SMILES, 'adjacencyList': adjacencyList, 'InChI': InChI, } loadNecessaryDatabases() with open(path, 'r') as f: try: exec f in global_context, local_context except (NameError, TypeError, SyntaxError): logging.error('The input file {0!r} was invalid:'.format(path)) raise model_chemistry = local_context.get('modelChemistry', '') level_of_theory = local_context.get('levelOfTheory', '') author = local_context.get('author', '') if 'frequencyScaleFactor' not in local_context: logging.debug('Assigning a frequencyScaleFactor according to the modelChemistry...') frequency_scale_factor = assign_frequency_scale_factor(model_chemistry) else: frequency_scale_factor = local_context.get('frequencyScaleFactor') use_hindered_rotors = local_context.get('useHinderedRotors', True) use_atom_corrections = local_context.get('useAtomCorrections', True) use_bond_corrections = local_context.get('useBondCorrections', False) atom_energies = local_context.get('atomEnergies', None) directory = os.path.dirname(path) for rxn in reactionDict.values(): rxn.elementary_high_p = True for job in jobList: if isinstance(job, StatMechJob): job.path = os.path.join(directory, job.path) job.modelChemistry = model_chemistry.lower() job.frequencyScaleFactor = frequency_scale_factor job.includeHinderedRotors = use_hindered_rotors job.applyAtomEnergyCorrections = use_atom_corrections job.applyBondEnergyCorrections = use_bond_corrections job.atomEnergies = atom_energies if isinstance(job, ThermoJob): job.arkane_species.author = author job.arkane_species.level_of_theory = level_of_theory if '//' in level_of_theory: level_of_theory_energy = level_of_theory.split('//')[0] if level_of_theory_energy != model_chemistry: # Only log the model chemistry if it isn't identical to the first part of level_of_theory job.arkane_species.model_chemistry = model_chemistry job.arkane_species.frequency_scale_factor = frequency_scale_factor job.arkane_species.use_hindered_rotors = use_hindered_rotors job.arkane_species.use_bond_corrections = use_bond_corrections if atom_energies is not None: job.arkane_species.atom_energies = atom_energies return jobList, reactionDict, speciesDict, transitionStateDict, networkDict