def run_fits_task(pes_grp_rlst, pes_param_dct, rate_paths_dct, mdriver_path, label_dct, pes_mod_dct, spc_mod_dct, thy_dct, tsk_key_dct): """ Run the fits and potentially assume that the rate_paths_dct will come in with all PESs in group """ # Combine all PESs into a string for writing the CKIN file pes_strs = () for pes_inf in pes_grp_rlst.keys(): _inf = (pes_inf[0], str(pes_inf[1] + 1), str(pes_inf[2] + 1)) pes_strs += ('_'.join(_inf), ) tot_fml = '-'.join(pes_strs) # Get the model and sort info from tsk key dct pes_mod = tsk_key_dct['kin_model'] spc_mod = tsk_key_dct['spc_model'] sort_info_lst = filesys.mincnf.sort_info_lst(tsk_key_dct['sort'], thy_dct) ioprinter.obj('vspace') ioprinter.obj('line_dash') # Obtain the rate constants from the MESS files ioprinter.info_message('Reading Rate Constants from MESS outputs', newline=1) rxn_ktp_dct = obtain_multipes_rxn_ktp_dct(rate_paths_dct, pes_param_dct, label_dct, pes_mod_dct, pes_mod) # Fit the rate constants ioprinter.info_message( 'Fitting Rate Constants for PES to Functional Forms', newline=1) ratefit_dct = pes_mod_dct[pes_mod]['rate_fit'] rxn_param_dct, rxn_err_dct = ratefit.fit.fit_rxn_ktp_dct( rxn_ktp_dct, ratefit_dct['fit_method'], pdep_dct=ratefit_dct['pdep_fit'], arrfit_dct=ratefit_dct['arrfit_fit'], chebfit_dct=ratefit_dct['chebfit_fit'], troefit_dct=ratefit_dct['troefit_fit'], ) # Write the reactions block header, which contains model info rxn_block_cmt = writer.ckin.model_header( (spc_mod, ), spc_mod_dct, sort_info_lst=sort_info_lst, refscheme=pes_mod_dct[pes_mod]['therm_fit']['ref_scheme']) # Get the comments dct and write the Chemkin string rxn_cmts_dct = chemkin_io.writer.comments.get_rxn_cmts_dct( rxn_err_dct=rxn_err_dct, rxn_block_cmt=rxn_block_cmt) ckin_str = chemkin_io.writer.mechanism.write_chemkin_file( rxn_param_dct=rxn_param_dct, rxn_cmts_dct=rxn_cmts_dct) # Write the file ckin_path = output_path('CKIN', prefix=mdriver_path) ckin_filename = f'{tot_fml}.ckin' ioformat.pathtools.write_file(ckin_str, ckin_path, ckin_filename)
def _save_conformer(ret, cnf_save_fs, locs, thy_info, zrxn=None, orig_ich='', rid_traj=False, init_zma=None): """ save the conformers that have been found so far # Only go through save procedure if conf not in save # may need to get geo, ene, etc; maybe make function """ saved_locs, saved_geos, saved_enes = _saved_cnf_info(cnf_save_fs, thy_info) inf_obj, _, out_str = ret prog = inf_obj.prog method = inf_obj.method ene = elstruct.reader.energy(prog, method, out_str) geo = elstruct.reader.opt_geometry(prog, out_str) zma = filesys.save.read_job_zma(ret, init_zma=init_zma) # Assess if geometry is properly connected viable = _geo_connected(geo, zrxn) if viable: if zrxn: viable = _ts_geo_viable(zma, zrxn, cnf_save_fs, thy_info) else: viable = _inchi_are_same(orig_ich, geo) # Determine uniqueness of conformer, save if needed if viable: if _geo_unique(geo, ene, saved_geos, saved_enes, zrxn): sym_id = _sym_unique(geo, ene, saved_geos, saved_enes) if sym_id is None: filesys.save.conformer(ret, None, cnf_save_fs, thy_info[1:], zrxn=zrxn, rng_locs=(locs[0], ), tors_locs=(locs[1], )) else: sym_locs = saved_locs[sym_id] filesys.save.sym_indistinct_conformer(geo, cnf_save_fs, locs, sym_locs) # Update the conformer trajectory file ioprinter.obj('vspace') rid = None if rid_traj: rid = locs[0] filesys.mincnf.traj_sort(cnf_save_fs, thy_info, rid=rid)
def random_cute_animal(): """ Print a picture of a fun, cute animal at random """ msg = random.choice([ r""" _,--._ ,' `. |\ / \ /| )o),/ ( ,--, ,--, ) \.(o( /o/// /| |\ \\ \\o\\ / / |\ \( .----, )/ /| \ \\ | | \o`-/ `--' \-'o/ | | \ \ `,' `.' / / \. \ `-' ,'| /\ |`. `-' / ,/ \`. `.__,' / / \ \ `.__,' ,'/ \o\ ,' ,' `. `. /o/ \o`---' ,' `. `---'o/ `.____,' `.____,' """, r""" ,,, ,,, ;" ^; ;' ", ; s$$$$$$$s ; , ss$$$$$$$$$$s ,' ;s$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$ $$$$P""Y$$$Y""W$$$$$ $$$$ 0"$$$"0 $$$$$ $$$$ .$$$$$. $$$$ $$$$$$$$$$$$$$$$$ "Y$$$"'*'"$$$Y" "$$b.d$$" """, r""" _.---~-~-~~-.. .. __. .-~ ~-. ((\ / `}.~ `. \\\\\ { } / \ \\ (\ \\\\~~ } | } \\ \`.-~-^~ } ,-,. | ) \\ (___, ) _} ( : | / / `. `----._-~. _\ \ |_ \ / /- _ -. ~~----~~ \ \| ~~--~~~( + / ~-. '--~. / / \ \ `~-..__ `~__ __/ / _\ ) `~~---' .<___.' .<___/ """]) message(msg) obj('vspace')
def read_spc_data(spc_dct, spc_name, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix, chn_basis_ene_dct, calc_chn_ene=True): """ Determines which block writer to use tau """ ioprinter.obj('line_plus') ioprinter.reading('Reading filesystem info for {}'.format(spc_name), newline=1) vib_model = spc_mod_dct_i['vib']['mod'] tors_model = spc_mod_dct_i['tors']['mod'] spc_dct_i = spc_dct[spc_name] if typ.is_atom(spc_dct_i): inf_dct = atm_data(spc_dct, spc_name, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix) writer = 'atom_block' else: if vib_model == 'tau' or tors_model == 'tau': inf_dct = tau_data(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, saddle=False) writer = 'tau_block' else: inf_dct, chn_basis_ene_dct = mol_data(spc_name, spc_dct, pes_mod_dct_i, spc_mod_dct_i, chn_basis_ene_dct, run_prefix, save_prefix, calc_chn_ene=calc_chn_ene, zrxn=None) writer = 'species_block' # Add writer to inf dct inf_dct['writer'] = writer return inf_dct, chn_basis_ene_dct
def run_messrate_task(rate_paths_dct, pes_inf): """ Run the MESSRATE input file. First tries to run a well-extended file, then tries to run the base file if it exists. Need an overwrite task """ path_dct = rate_paths_dct[pes_inf] for typ in ('wext', 'base'): path = path_dct[typ] mess_inp = os.path.join(path, 'mess.inp') mess_out = os.path.join(path, 'mess.out') if os.path.exists(mess_inp) and not os.path.exists(mess_out): ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message(f'Found MESS input file at {path}') ioprinter.running('MESS input file') autorun.run_script(autorun.SCRIPT_DCT['messrate'], path) break
def make_messrate_str(pes_idx, rxn_lst, pes_model, spc_model, spc_dct, thy_dct, pes_model_dct, spc_model_dct, label_dct, mess_path, run_prefix, save_prefix): """ Combine various MESS strings together to combined MESS rates spc model could become a list for channel combinations """ pes_model_dct_i = pes_model_dct[pes_model] spc_model_dct_i = spc_model_dct[spc_model] # Write the strings for the MESS input file globkey_str = make_header_str( spc_dct, temps=pes_model_dct_i['rate_temps'], pressures=pes_model_dct_i['pressures']) # Write the energy transfer section strings for MESS file etransfer = pes_model_dct_i['glob_etransfer'] energy_trans_str = make_global_etrans_str( rxn_lst, spc_dct, etransfer) # Write the MESS strings for all the PES channels rxn_chan_str, dats, _, _ = make_pes_mess_str( spc_dct, rxn_lst, pes_idx, run_prefix, save_prefix, label_dct, pes_model_dct_i, spc_model_dct_i, spc_model, thy_dct) # Combine strings together mess_inp_str = mess_io.writer.messrates_inp_str( globkey_str, energy_trans_str, rxn_chan_str) # Write the MESS file into the filesystem ioprinter.obj('line_plus') ioprinter.writing('MESS input file', mess_path) ioprinter.debug_message(mess_inp_str) return mess_inp_str, dats
def rpath_tsk(job, spc_dct, spc_name, thy_inf_dct, thy_method_dct, mref_dct, es_keyword_dct, runfs_dct, savefs_dct): """ run a scan over the specified torsional coordinate :param job: :type job: :param spc_dct: :type spc_dct: :param spc_name: :type spc_name: :param thy_dct: :type thy_dct: :param es_keyword_dct: keyword-value pairs for electronic structure tsk :type es_keyword_dct: dict[str:str] :param run_prefix: root-path to the run-filesystem :type run_prefix: str :param save_prefix: root-path to the save-filesystem :type save_prefix: str """ # Get dct for specific species task is run for ts_dct = spc_dct[spc_name] ts_info = rinfo.ts_info(ts_dct['rxn_info']) # # Build various thy and filesystem objects # thy_inf_dct, thy_method_dct, mref_dct, runfs_dct, savefs_dct = thy_dcts( # spc_name, spc_dct[spc_name], thy_dct, es_keyword_dct, # run_prefix, save_prefix) mod_thy_info = thy_inf_dct['mod_runlvl'] mod_ini_thy_info = thy_inf_dct['mod_inplvl'] method_dct = thy_method_dct['runlvl'] ini_method_dct = thy_method_dct['inplvl'] mref_params = mref_dct['runlvl'] # Build filesys objects scn_alg, scn_fs, cnf_fs, cnf_locs = rpath_fs( ts_dct, spc_name, mod_ini_thy_info, es_keyword_dct, runfs_dct['prefix'], savefs_dct['prefix']) print('alg set test', scn_alg) # Run job if job == 'scan': if 'irc' in scn_alg: zmas = irc.launch_point_zmatrices( ts_dct, mod_thy_info, scn_alg, scn_fs, cnf_fs, cnf_locs) for zma in zmas: success = irc.execute_irc( zma, ts_info, mod_ini_thy_info, ini_method_dct, scn_fs[0], scn_fs[1], es_keyword_dct) if success: break else: zma, zrxn, rclass, = ts_dct['zma'], ts_dct['zrxn'], ts_dct['class'] _ = rpath.internal_coordinates_scan( zma, zrxn, ts_info, rclass, method_dct, mref_params, scn_fs[0], scn_fs[1], es_keyword_dct) elif job in ('energy', 'grad', 'hess'): # Set run-time options overwrite = es_keyword_dct['overwrite'] script_str, kwargs = qchem_params(method_dct) # Run along the scan and calculate desired quantities ini_scn_run_fs, ini_scn_save_fs = scn_fs for locs in ini_scn_save_fs[-1].existing(): geo = ini_scn_save_fs[-1].file.geometry.read(locs) ini_scn_run_fs[-1].create(locs) ES_TSKS[job]( None, geo, ts_info, mod_thy_info, ini_scn_run_fs, ini_scn_save_fs, locs, script_str, overwrite, **kwargs) ioprinter.obj('vspace') elif job == 'infene': rpath.inf_sep_ene( ts_dct, thy_inf_dct, mref_dct, savefs_dct, runfs_dct, es_keyword_dct)
ioprinter.program_exit('trans') KTP_TSKS = TSK_LST_DCT.get('ktp') if KTP_TSKS is not None: ioprinter.program_header('ktp') ktpdriver.run( PES_RLST, KTP_TSKS, SPC_DCT, GLOB_DCT, KMOD_DCT, SMOD_DCT, INP_KEY_DCT['run_prefix'], INP_KEY_DCT['save_prefix'] ) ioprinter.program_exit('ktp') PROC_TSKS = TSK_LST_DCT.get('proc') if PROC_TSKS is not None: ioprinter.program_header('proc') PES_IDX = None procdriver.run( PES_RLST, SPC_RLST, PROC_TSKS, SPC_DCT, KMOD_DCT, SMOD_DCT, THY_DCT, INP_KEY_DCT['run_prefix'], INP_KEY_DCT['save_prefix'] ) ioprinter.program_exit('proc') # Exit Program ioprinter.obj('vspace') ioprinter.program_exit('amech')
def run_tsk(tsk, spc_dct, spc_name, thy_dct, proc_keyword_dct, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix): """ run a proc tess task for generating a list of conformer or tau sampling geometries """ # Print the head of the task ioprinter.output_task_header(tsk) ioprinter.obj('line_dash') ioprinter.output_keyword_list(proc_keyword_dct, thy_dct) # Setup csv data dictionary for specific task csv_data = util.set_csv_data(tsk) chn_basis_ene_dct = {} spc_array = [] # print species ioprinter.obj('line_dash') ioprinter.info_message("Species: ", spc_name) # Heat of formation basis molecules and coefficients # is not conformer specific if 'coeffs' in tsk: thy_info = spc_mod_dct_i['geo'][1] filelabel = 'coeffs' filelabel += '_{}'.format(pes_mod_dct_i['thermfit']['ref_scheme']) filelabel += '.csv' label = spc_name basis_dct, _ = basis.prepare_refs( pes_mod_dct_i['thermfit']['ref_scheme'], spc_dct, (spc_name, )) # Get the basis info for the spc of interest spc_basis, coeff_basis = basis_dct[spc_name] coeff_array = [] for spc_i in spc_basis: if spc_i not in spc_array: spc_array.append(spc_i) for spc_i in spc_array: if spc_i in spc_basis: coeff_array.append(coeff_basis[spc_basis.index(spc_i)]) else: coeff_array.append(0) csv_data[label] = [*coeff_array] else: # unpack spc and level info spc_dct_i = spc_dct[spc_name] if proc_keyword_dct['geolvl']: thy_info = tinfo.from_dct(thy_dct.get(proc_keyword_dct['geolvl'])) else: thy_info = spc_mod_dct_i['geo'][1] # Loop over conformers if proc_keyword_dct['geolvl']: _, rng_cnf_locs_lst, rng_cnf_locs_path = util.conformer_list( proc_keyword_dct, save_prefix, run_prefix, spc_dct_i, thy_dct) spc_mod_dct_i, pf_models = None, None else: ret = util.conformer_list_from_models(proc_keyword_dct, save_prefix, run_prefix, spc_dct_i, thy_dct, spc_mod_dct_i, pf_models) _, rng_cnf_locs_lst, rng_cnf_locs_path = ret for locs, locs_path in zip(rng_cnf_locs_lst, rng_cnf_locs_path): label = spc_name + '_' + '_'.join(locs) _, cnf_fs = filesys.build_fs(run_prefix, save_prefix, 'CONFORMER') if 'freq' in tsk: filelabel = 'freq' if spc_mod_dct_i: filelabel += '_m{}'.format(spc_mod_dct_i['harm'][0]) else: filelabel += '_{}'.format(proc_keyword_dct['geolvl']) filelabel += '.csv' if pf_models: pf_filesystems = filesys.models.pf_filesys(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, saddle=False) ret = vib.full_vib_analysis(spc_dct_i, pf_filesystems, spc_mod_dct_i, run_prefix, zrxn=None) freqs, _, tors_zpe, sfactor, torsfreqs, all_freqs = ret csv_data['tfreq'][label] = torsfreqs csv_data['allfreq'][label] = all_freqs csv_data['scalefactor'][label] = [sfactor] else: es_model = util.freq_es_levels(proc_keyword_dct) spc_mod_dct_i = parser.model.pf_level_info( es_model, thy_dct) try: freqs, _, zpe = vib.read_locs_harmonic_freqs( cnf_fs, locs, run_prefix, zrxn=None) except: freqs = [] zpe = 0 tors_zpe = 0.0 spc_data = [] zpe = tors_zpe + (sum(freqs) / 2.0) * phycon.WAVEN2EH if freqs and proc_keyword_dct['scale'] is not None: freqs, zpe = vib.scale_frequencies(freqs, tors_zpe, spc_mod_dct_i, scale_method='3c') spc_data = [locs_path, zpe, *freqs] csv_data['freq'][label] = spc_data elif 'geo' in tsk: filelabel = 'geo' if spc_mod_dct_i: filelabel += '_{}'.format(spc_mod_dct_i['harm']) else: filelabel += '_{}'.format(proc_keyword_dct['geolvl']) filelabel += '.txt' if cnf_fs[-1].file.geometry.exists(locs): geo = cnf_fs[-1].file.geometry.read(locs) energy = cnf_fs[-1].file.energy.read(locs) comment = 'energy: {0:>15.10f}'.format(energy) xyz_str = automol.geom.xyz_string(geo, comment=comment) else: xyz_str = '\t -- Missing --' spc_data = '\n\nSPC: {}\tConf: {}\tPath: {}\n'.format( spc_name, locs, locs_path) + xyz_str csv_data[label] = spc_data elif 'zma' in tsk: filelabel = 'zmat' if spc_mod_dct_i: filelabel += '_{}'.format(spc_mod_dct_i['harm']) else: filelabel += '_{}'.format(proc_keyword_dct['geolvl']) filelabel += '.txt' geo = cnf_fs[-1].file.geometry.read(locs) zma = automol.geom.zmatrix(geo) energy = cnf_fs[-1].file.energy.read(locs) comment = 'energy: {0:>15.10f}\n'.format(energy) zma_str = automol.zmat.string(zma) spc_data = '\n\nSPC: {}\tConf: {}\tPath: {}\n'.format( spc_name, locs, locs_path) + comment + zma_str csv_data[label] = spc_data elif 'ene' in tsk: filelabel = 'ene' if spc_mod_dct_i: filelabel += '_{}'.format(spc_mod_dct_i['harm']) filelabel += '_{}'.format(spc_mod_dct_i['ene']) else: filelabel += '_{}'.format(proc_keyword_dct['geolvl']) filelabel += '_{}'.format(proc_keyword_dct['proplvl']) filelabel += '.csv' energy = None if spc_mod_dct_i: pf_filesystems = filesys.models.pf_filesys(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, saddle=False) energy = ene.electronic_energy(spc_dct_i, pf_filesystems, spc_mod_dct_i, conf=(locs, locs_path, cnf_fs)) else: spc_info = sinfo.from_dct(spc_dct_i) thy_info = tinfo.from_dct( thy_dct.get(proc_keyword_dct['proplvl'])) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) sp_save_fs = autofile.fs.single_point(locs_path) sp_save_fs[-1].create(mod_thy_info[1:4]) # Read the energy sp_path = sp_save_fs[-1].path(mod_thy_info[1:4]) if os.path.exists(sp_path): if sp_save_fs[-1].file.energy.exists( mod_thy_info[1:4]): ioprinter.reading('Energy', sp_path) energy = sp_save_fs[-1].file.energy.read( mod_thy_info[1:4]) csv_data[label] = [locs_path, energy] elif 'enthalpy' in tsk: filelabel = 'enthalpy' if spc_mod_dct_i: filelabel += '_{}'.format(spc_mod_dct_i['harm']) filelabel += '_{}'.format(spc_mod_dct_i['ene']) else: filelabel += '_{}'.format(proc_keyword_dct['geolvl']) filelabel += '_{}'.format(proc_keyword_dct['proplvl']) filelabel = '.csv' energy = None pf_filesystems = filesys.models.pf_filesys(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, saddle=False) ene_abs = ene.read_energy(spc_dct_i, pf_filesystems, spc_mod_dct_i, run_prefix, conf=(locs, locs_path, cnf_fs), read_ene=True, read_zpe=True, saddle=False) hf0k, _, chn_basis_ene_dct, hbasis = basis.enthalpy_calculation( spc_dct, spc_name, ene_abs, chn_basis_ene_dct, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix, pforktp='pf', zrxn=None) spc_basis, coeff_basis = hbasis[spc_name] coeff_array = [] for spc_i in spc_basis: if spc_i not in spc_array: spc_array.append(spc_i) for spc_i in spc_array: if spc_i in spc_basis: coeff_array.append(coeff_basis[spc_basis.index(spc_i)]) else: coeff_array.append(0) csv_data[label] = [locs_path, ene_abs, hf0k, *coeff_array] util.write_csv_data(tsk, csv_data, filelabel, spc_array)
def read_ts_data(spc_dct, tsname, rcts, prds, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix, chn_basis_ene_dct, spc_locs=None): """ Reads all required data from the SAVE filesystem for a transition state. Also sets the writer for appropriately formatting the data into an MESS input file string. All of the data that is read is determined by the models that are described in the pes and spc model dictionaries. :param spc_dct: :type spc_dct: :param tsname: mechanism name of transition state :type tsname: str :param rcts: mechanism names of reactants connected to transition state :type rcts: tuple(str) :param prds: mechanism names of products connected to transition state :type prds: tuple(str) :param pes_mod_dct_i: keyword dict of specific PES model :type pes_mod_dct_i: dict[] :param spc_mod_dct_i: keyword dict of specific species model :type spc_mod_dct_i: dict[] :param run_prefix: root-path to the run-filesystem :type run_prefix: str :param save_prefix: root-path to the save-filesystem :type save_prefix: str :param chn_basis_ene_dct: basis species <names> for mechanism species :type chn_basis_ene_dct: dict[] :rtype: (dict[], dict[]) """ ioprinter.obj('line_plus') ioprinter.reading(f'Reading filesystem info for {tsname}', newline=1) ts_dct = spc_dct[tsname] reac_dcts = [spc_dct[name] for name in rcts] prod_dcts = [spc_dct[name] for name in prds] ts_mod = spc_mod_dct_i['ts'] ts_sadpt, ts_nobar = ts_mod['sadpt'], ts_mod['nobar'] # Get all of the information for the filesystem if not automol.par.is_radrad(ts_dct['class']): # Set up the saddle point keyword sadpt = True search = ts_dct.get('ts_search') if search is not None: if 'vtst' in search: sadpt = False # Build MESS string for TS at a saddle point if ts_sadpt == 'pst': inf_dct = pst_data(ts_dct, reac_dcts, spc_mod_dct_i, run_prefix, save_prefix) writer = 'pst_block' elif ts_sadpt == 'rpvtst': inf_dct = rpvtst_data(ts_dct, reac_dcts, spc_mod_dct_i, run_prefix, save_prefix, sadpt=sadpt) writer = 'rpvtst_block' else: print('Obtaining a ZRXN object from conformer any TS, ' 'shouldn matter') print('-----') pf_filesystems = filesys.models.pf_filesys(spc_dct[tsname], spc_mod_dct_i, run_prefix, save_prefix, True, name=tsname) [cnf_fs, _, min_cnf_locs, _, _] = pf_filesystems['harm'] cnf_path = cnf_fs[-1].path(min_cnf_locs) zma_fs = autofile.fs.zmatrix(cnf_path) zrxn = zma_fs[-1].file.reaction.read((0, )) print('-----') inf_dct, chn_basis_ene_dct = mol_data(tsname, spc_dct, pes_mod_dct_i, spc_mod_dct_i, chn_basis_ene_dct, run_prefix, save_prefix, zrxn=zrxn, spc_locs=spc_locs) writer = 'species_block' else: # Build MESS string for TS with no saddle point if ts_nobar == 'pst': if len(rcts) == 2: inf_dct = pst_data(ts_dct, reac_dcts, spc_mod_dct_i, run_prefix, save_prefix) else: inf_dct = pst_data(ts_dct, prod_dcts, spc_mod_dct_i, run_prefix, save_prefix) writer = 'pst_block' elif ts_nobar == 'rpvtst': inf_dct = rpvtst_data(ts_dct, reac_dcts, spc_mod_dct_i, run_prefix, save_prefix, sadpt=False) writer = 'rpvtst_block' elif ts_nobar == 'vrctst': inf_dct = flux_data(ts_dct, spc_mod_dct_i) writer = 'vrctst_block' # Add writer to inf dct inf_dct['writer'] = writer return inf_dct, chn_basis_ene_dct
def read_ts_data(spc_dct, tsname, rcts, prds, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix, chn_basis_ene_dct, ref_pf_models=(), ref_pf_levels=()): """ Determine which block function to useset block functions """ ioprinter.obj('line_plus') ioprinter.reading('Reading filesystem info for {}'.format(tsname), newline=1) ts_dct = spc_dct[tsname] reac_dcts = [spc_dct[name] for name in rcts] prod_dcts = [spc_dct[name] for name in prds] # Set information for transition states pf_filesystems = filesys.models.pf_filesys(spc_dct[tsname], spc_mod_dct_i, run_prefix, save_prefix, True, name=tsname) [cnf_fs, _, min_cnf_locs, _, _] = pf_filesystems['harm'] cnf_path = cnf_fs[-1].path(min_cnf_locs) zma_fs = autofile.fs.zmatrix(cnf_path) zrxn = zma_fs[-1].file.reaction.read((0, )) ts_mod = spc_mod_dct_i['ts'] ts_sadpt, ts_nobar = ts_mod['sadpt'], ts_mod['nobar'] # Get all of the information for the filesystem if not typ.var_radrad(ts_dct['class']): # Set up the saddle point keyword sadpt = True search = ts_dct.get('ts_search') if search is not None: if 'vtst' in search: sadpt = False # Build MESS string for TS at a saddle point if ts_sadpt == 'pst': inf_dct = pst_data(ts_dct, reac_dcts, spc_mod_dct_i, run_prefix, save_prefix) writer = 'pst_block' elif ts_sadpt == 'rpvtst': inf_dct = rpvtst_data(ts_dct, reac_dcts, spc_mod_dct_i, ref_pf_models, ref_pf_levels, run_prefix, save_prefix, sadpt=sadpt) writer = 'rpvtst_block' else: inf_dct, chn_basis_ene_dct = mol_data(tsname, spc_dct, pes_mod_dct_i, spc_mod_dct_i, chn_basis_ene_dct, run_prefix, save_prefix, zrxn=zrxn) writer = 'species_block' else: # Build MESS string for TS with no saddle point if ts_nobar == 'pst': if len(rcts) == 2: inf_dct = pst_data(ts_dct, reac_dcts, spc_mod_dct_i, run_prefix, save_prefix) else: inf_dct = pst_data(ts_dct, prod_dcts, spc_mod_dct_i, run_prefix, save_prefix) writer = 'pst_block' elif ts_nobar == 'rpvtst': inf_dct = rpvtst_data(ts_dct, reac_dcts, spc_mod_dct_i, run_prefix, save_prefix, sadpt=False) writer = 'rpvtst_block' elif ts_nobar == 'vrctst': inf_dct = flux_data(ts_dct, spc_mod_dct_i) writer = 'vrctst_block' # Add writer to inf dct inf_dct['writer'] = writer return inf_dct, chn_basis_ene_dct
def run(pes_rlst, ktp_tsk_lst, spc_dct, glob_dct, thy_dct, pes_mod_dct, spc_mod_dct, run_prefix, save_prefix): """ main driver for generation of full set of rate constants on a single PES """ # --------------------------------------- # # LOOP OVER ALL OF THE SUBPES in PES_RLST # # --------------------------------------- # for pes_inf, rxn_lst in pes_rlst.items(): # ---------------------------------------------- # # PREPARE INFORMATION TO PASS TO KTPDRIVER TASKS # # ---------------------------------------------- # # Set objects pes_formula, pes_idx, subpes_idx = pes_inf label_dct = None # Print PES Channels that are being run ioprinter.runlst(pes_inf, rxn_lst) # Set paths where files will be written and read mess_path = job_path(run_prefix, 'MESS', 'RATE', pes_formula, locs_idx=subpes_idx) # --------------------------------- # # RUN THE REQUESTED KTPDRIVER TASKS # # --------------------------------- # # Write the MESS file write_rate_tsk = parser.run.extract_task('write_mess', ktp_tsk_lst) if write_rate_tsk is not None: # Get all the info for the task tsk_key_dct = write_rate_tsk[-1] pes_mod = tsk_key_dct['kin_model'] spc_mod = tsk_key_dct['spc_model'] spc_dct, rxn_lst, label_dct = _process(pes_idx, rxn_lst, ktp_tsk_lst, spc_mod_dct, spc_mod, thy_dct, spc_dct, glob_dct, run_prefix, save_prefix) ioprinter.messpf('write_header') mess_inp_str, dats = ktproutines.rates.make_messrate_str( pes_idx, rxn_lst, pes_mod, spc_mod, spc_dct, thy_dct, pes_mod_dct, spc_mod_dct, label_dct, mess_path, run_prefix, save_prefix) autorun.write_input(mess_path, mess_inp_str, aux_dct=dats, input_name='mess.inp') # Run mess to produce rates (currently nothing from tsk lst keys used) run_rate_tsk = parser.run.extract_task('run_mess', ktp_tsk_lst) if run_rate_tsk is not None: ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.running('MESS for the input file', mess_path) autorun.run_script(autorun.SCRIPT_DCT['messrate'], mess_path) # Fit rate output to modified Arrhenius forms, print in ChemKin format run_fit_tsk = parser.run.extract_task('run_fits', ktp_tsk_lst) if run_fit_tsk is not None: # Get all the info for the task tsk_key_dct = run_fit_tsk[-1] spc_mod = tsk_key_dct['spc_model'] pes_mod = tsk_key_dct['kin_model'] ratefit_dct = pes_mod_dct[pes_mod]['rate_fit'] if label_dct is None: spc_dct, rxn_lst, label_dct = _process(pes_idx, rxn_lst, ktp_tsk_lst, spc_mod_dct, spc_mod, thy_dct, spc_dct, run_prefix, save_prefix) ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message( 'Fitting Rate Constants for PES to Functional Forms', newline=1) # Read and fit rates; write to ckin string ratefit_dct = pes_mod_dct[pes_mod]['rate_fit'] ckin_dct = ratefit.fit.fit_ktp_dct( mess_path=mess_path, inp_fit_method=ratefit_dct['fit_method'], pdep_dct=ratefit_dct['pdep_fit'], arrfit_dct=ratefit_dct['arrfit_fit'], chebfit_dct=ratefit_dct['chebfit_fit'], troefit_dct=ratefit_dct['troefit_fit'], label_dct=label_dct, fit_temps=pes_mod_dct[pes_mod]['rate_temps'], fit_pressures=pes_mod_dct[pes_mod]['pressures'], fit_tunit=pes_mod_dct[pes_mod]['temp_unit'], fit_punit=pes_mod_dct[pes_mod]['pressure_unit']) # Write the header part ckin_dct.update( {'header': writer.ckin.model_header((spc_mod, ), spc_mod_dct)}) ckin_path = output_path('CKIN') writer.ckin.write_rxn_file(ckin_dct, pes_formula, ckin_path)
def run(pes_rlst, ktp_tsk_lst, spc_dct, glob_dct, pes_mod_dct, spc_mod_dct, run_prefix, save_prefix): """ Executes all kinetics tasks. :param pes_rlst: species from PESs to run [(PES formula, PES idx, SUP-PES idx) (CHANNEL idx, (REACS, PRODS)) :type pes_rlst: tuple(dict[str: dict]) :param spc_rlst: lst of species to run :type spc_rlst: tuple(dict[str: dict]) :param es_tsk_lst: list of the electronic structure tasks tuple(tuple(obj, tsk, keyword_dict)) :type es_tsk_lst: tuple(tuple(str, str, dict)) :param spc_dct: species information dict[spc_name: spc_information] :type spc_dct: dict[str:dict] :param glob_dct: global information for all species dict[spc_name: spc_information] :type glob_dct: dict[str: dict] :param thy_dct: all of the theory information dict[thy name: inf] :type thy_dct: dict[str:dict] :param run_prefix: root-path to the run-filesystem :type run_prefix: str :param save_prefix: root-path to the save-filesystem :type save_prefix: str """ # --------------------------------------- # # LOOP OVER ALL OF THE SUBPES in PES_RLST # # --------------------------------------- # for pes_inf, rxn_lst in pes_rlst.items(): # ---------------------------------------------- # # PREPARE INFORMATION TO PASS TO KTPDRIVER TASKS # # ---------------------------------------------- # # Set objects pes_formula, pes_idx, subpes_idx = pes_inf label_dct = None # Print PES Channels that are being run ioprinter.runlst(pes_inf, rxn_lst) # Set paths where files will be written and read mess_path = job_path(run_prefix, 'MESS', 'RATE', pes_formula, locs_idx=subpes_idx) # --------------------------------- # # RUN THE REQUESTED KTPDRIVER TASKS # # --------------------------------- # # Write the MESS file write_rate_tsk = parser.run.extract_task('write_mess', ktp_tsk_lst) if write_rate_tsk is not None: # Get all the info for the task tsk_key_dct = write_rate_tsk[-1] pes_mod = tsk_key_dct['kin_model'] spc_mod = tsk_key_dct['spc_model'] spc_dct, rxn_lst, instab_chnls, label_dct = _process( pes_idx, rxn_lst, ktp_tsk_lst, spc_mod_dct, spc_mod, spc_dct, glob_dct, run_prefix, save_prefix) ioprinter.messpf('write_header') # Doesn't give full string mess_inp_str, dats = ktproutines.rates.make_messrate_str( pes_idx, rxn_lst, pes_mod, spc_mod, spc_dct, pes_mod_dct, spc_mod_dct, instab_chnls, label_dct, mess_path, run_prefix, save_prefix, make_lump_well_inp=tsk_key_dct['lump_wells']) autorun.write_input(mess_path, mess_inp_str, aux_dct=dats, input_name='mess.inp') # Run mess to produce rates (currently nothing from tsk lst keys used) run_rate_tsk = parser.run.extract_task('run_mess', ktp_tsk_lst) if run_rate_tsk is not None: ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.running('MESS for the input file', mess_path) autorun.run_script(autorun.SCRIPT_DCT['messrate'], mess_path) # Fit rate output to modified Arrhenius forms, print in ChemKin format run_fit_tsk = parser.run.extract_task('run_fits', ktp_tsk_lst) if run_fit_tsk is not None: # Get all the info for the task tsk_key_dct = run_fit_tsk[-1] spc_mod = tsk_key_dct['spc_model'] pes_mod = tsk_key_dct['kin_model'] ratefit_dct = pes_mod_dct[pes_mod]['rate_fit'] if label_dct is None: spc_dct, rxn_lst, _, label_dct = _process( pes_idx, rxn_lst, ktp_tsk_lst, spc_mod_dct, spc_mod, spc_dct, glob_dct, run_prefix, save_prefix) ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message( 'Fitting Rate Constants for PES to Functional Forms', newline=1) # Read and fit rates; write to ckin string ratefit_dct = pes_mod_dct[pes_mod]['rate_fit'] ckin_dct = ratefit.fit.fit_ktp_dct( mess_path=mess_path, inp_fit_method=ratefit_dct['fit_method'], pdep_dct=ratefit_dct['pdep_fit'], arrfit_dct=ratefit_dct['arrfit_fit'], chebfit_dct=ratefit_dct['chebfit_fit'], troefit_dct=ratefit_dct['troefit_fit'], label_dct=label_dct, fit_temps=pes_mod_dct[pes_mod]['rate_temps'], fit_pressures=pes_mod_dct[pes_mod]['pressures'], fit_tunit=pes_mod_dct[pes_mod]['temp_unit'], fit_punit=pes_mod_dct[pes_mod]['pressure_unit']) # Write the header part ckin_dct.update( {'header': writer.ckin.model_header((spc_mod, ), spc_mod_dct)}) ckin_path = output_path('CKIN') writer.ckin.write_rxn_file(ckin_dct, pes_formula, ckin_path)
def rpath_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ run a scan over the specified torsional coordinates """ # Get dct for specific species task is run for spc_dct_i = spc_dct[spc_name] # Set up coordinate name rxn_coord = es_keyword_dct.get('rxn_coord') if rxn_coord == 'auto': coord_name = ['Rn'] # grab from zrxn object else: # coord_name = coord_name = ['IRC'] # Set the spc_info spc_info = sinfo.from_dct(spc_dct_i) # Modify the theory method_dct = thy_dct.get(es_keyword_dct['runlvl']) ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) thy_info = tinfo.from_dct(method_dct) ini_thy_info = tinfo.from_dct(ini_method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) mod_ini_thy_info = tinfo.modify_orb_label(ini_thy_info, spc_info) # Get options from the dct or es options lst overwrite = es_keyword_dct['overwrite'] # retryfail = es_keyword_dct['retryfail'] # Set up the script script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) # Set the filesystem objects rxn_info = spc_dct_i['rxn_info'] fs_rxn_info = rinfo.sort(rxn_info) # New filesystem objects if coord_name == 'irc': _root = root_locs(spc_dct_i, saddle=True) # ini_cnf_run_fs, ini_cnf_save_fs = build_fs( # run_prefix, save_prefix, 'CONFORMER', # thy_locs=mod_ini_thy_info[1:], # **_root) # cnf_run_fs, cnf_save_fs = build_fs( # run_prefix, save_prefix, 'CONFORMER', # thy_locs=mod_thy_info[1:], # **_root) ini_cnf_run_fs, ini_cnf_save_fs = build_fs( run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_ini_thy_info[1:], **_root) cnf_run_fs, cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_thy_info[1:], **_root) ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_min_locs, ini_pfx_save_path = ini_loc_info # ini_min_rng_locs, ini_min_cnf_locs = ini_min_cnf_locs # ini_min_rng_path, ini_min_cnf_path = ini_min_cnf_path ini_cnf_run_fs[-1].create(ini_min_locs) ini_pfx_run_path = ini_cnf_run_fs[-1].path(ini_min_locs) else: ts_info = (ts_num, ) ini_ts_run_fs, ini_ts_save_fs = build_fs(run_prefix, save_prefix, 'TS', thy_locs=mod_ini_thy_info[1:], **_root) ini_pfx_run_path = ini_ts_run_fs.path(ts_info) ini_pfx_save_path = ini_ts_save_fs.path(ts_info) # Get options from the dct or es options lst overwrite = es_keyword_dct['overwrite'] ini_scn_run_fs, ini_scn_save_fs = build_fs(ini_pfx_run_path, ini_pfx_save_path, 'SCAN', zma_locs=(0, )) ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path) geo = ini_cnf_save_fs[-1].file.geometry.read(ini_min_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) # Run job if job == 'scan': if rcoord == 'auto': pass elif rcoord == 'irc': rpath.irc_scan(geo, spc_info, coord_name, mod_ini_thy_info, ini_method_dct, ini_scn_save_fs, ini_cnf_run_path, overwrite) elif job in ('energy', 'grad', 'hess'): # Script script_str, kwargs = qchem_params(method_dct) # Need to put in something with the IRC idxs for locs in ini_scn_save_fs[-1].existing(): geo_run_path = ini_scn_run_fs[-1].path(locs) geo_save_path = ini_scn_save_fs[-1].path(locs) geo = ini_scn_save_fs[-1].file.geometry.read(locs) zma = None ini_scn_run_fs[-1].create(locs) ES_TSKS[job](zma, geo, spc_info, mod_thy_info, ini_scn_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, **kwargs) ioprinter.obj('vspace') elif job == 'infene': pass
def hr_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ run a scan over the specified torsional coordinates """ spc_dct_i = spc_dct[spc_name] saddle = bool('ts_' in spc_name) # Set the spc_info if not saddle: spc_info = sinfo.from_dct(spc_dct_i) else: spc_info = rinfo.ts_info(spc_dct_i['rxn_info']) # Modify the theory method_dct = thy_dct.get(es_keyword_dct['runlvl']) ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) thy_info = tinfo.from_dct(method_dct) ini_thy_info = tinfo.from_dct(ini_method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) mod_ini_thy_info = tinfo.modify_orb_label(ini_thy_info, spc_info) # Set the filesystem objects _root = root_locs(spc_dct_i, saddle=saddle, name=spc_name) ini_cnf_run_fs, ini_cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_ini_thy_info[1:], **_root) cnf_run_fs, cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_thy_info[1:], **_root) instab_save_fs = () ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_min_locs, ini_cnf_save_path = ini_loc_info # ini_min_rng_locs, ini_min_cnf_locs = ini_min_cnf_locs # ini_min_rng_path, ini_min_cnf_path = ini_min_cnf_path # Create run fs if that directory has been deleted to run the jobs ini_cnf_run_fs[-1].create(ini_min_locs) ini_cnf_run_path = ini_cnf_run_fs[-1].path(ini_min_locs) # Get options from the dct or es options lst overwrite = es_keyword_dct['overwrite'] retryfail = es_keyword_dct['retryfail'] tors_model = es_keyword_dct['tors_model'] # Read zma, geo, and torsions ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path) geo = ini_cnf_save_fs[-1].file.geometry.read(ini_min_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) if ini_zma_save_fs[-1].file.torsions.exists([0]): tors_dct = ini_zma_save_fs[-1].file.torsions.read([0]) torsions = automol.rotor.from_data( zma, tors_dct, ) else: torsions = () # Run the task if any torsions exist if any(torsions): scn = 'SCAN' if 'fa' not in tors_model else 'CSCAN' ini_scn_run_fs, ini_scn_save_fs = build_fs(ini_cnf_run_path, ini_cnf_save_path, scn, zma_locs=(0, )) if job == 'scan': increment = spc_dct_i.get('hind_inc', 30.0 * phycon.DEG2RAD) hr.hindered_rotor_scans(zma, spc_info, mod_thy_info, instab_save_fs, ini_scn_run_fs, ini_scn_save_fs, torsions, tors_model, method_dct, overwrite, saddle=saddle, increment=increment, retryfail=retryfail) # elif job == 'reopt': # # pull stuff from dcts # two_stage = saddle # rxn_class = spc_dct_i['class'] if saddle else '' # mc_nsamp = spc_dct_i['mc_nsamp'] # ethresh = es_keyword_dct['hrthresh'] # # Read and print the potential # sp_fs = autofile.fs.single_point(ini_cnf_save_path) # ref_ene = sp_fs[-1].file.energy.read(mod_ini_thy_info[1:4]) # # ref_ene = ini_cnf_save_fs[-1].file.energy.read(ini_min_cnf_locs) # tors_pots, tors_zmas, tors_paths = {}, {}, {} # for tors_names, tors_grids in zip(run_tors_names, run_tors_grids): # constraint_dct = automol.zmat.build_constraint_dct( # zma, const_names, tors_names) # pot, _, _, _, zmas, paths = filesys.read.potential( # tors_names, tors_grids, # ini_cnf_save_path, # mod_ini_thy_info, ref_ene, # constraint_dct, # read_zma=True) # tors_pots[tors_names] = pot # tors_zmas[tors_names] = zmas # tors_paths[tors_names] = paths # # Check for new minimum conformer # new_min_zma = __.check_hr_pot( # tors_pots, tors_zmas, tors_paths, emax=ethresh) # if new_min_zma is not None: # ioprinter.info_message( # 'Finding new low energy conformer...', newline=1) # conformer.single_conformer( # zma, spc_info, mod_thy_info, # ini_cnf_run_fs, ini_cnf_save_fs, # script_str, overwrite, # retryfail=retryfail, rxn=rxn, **kwargs) elif job in ('energy', 'grad', 'hess', 'vpt2'): # Script (add energy script call) script_str, kwargs = qchem_params(method_dct) run_tors_names = automol.rotor.names(torsions, flat=True) for tors_names in run_tors_names: # Set the constraint dct and filesys for the scan const_names = automol.zmat.set_constraint_names( zma, run_tors_names, tors_model) constraint_dct = automol.zmat.build_constraint_dct( zma, const_names, tors_names) # get the scn_locs, maybe get a function? scn_locs = () for locs in scn_locs: geo_run_path = ini_scn_run_fs[-1].path(locs) geo_save_path = ini_scn_save_fs[-1].path(locs) geo = ini_scn_save_fs[-1].file.geometry.read(locs) zma = ini_scn_save_fs[-1].file.zmatrix.read(locs) ini_scn_run_fs[-1].create(locs) ES_TSKS[job](zma, geo, spc_info, mod_thy_info, ini_scn_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=retryfail, **kwargs) ioprinter.obj('vspace') else: ioprinter.info_message('No torsional modes in the species')
def tau_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ Energies, gradients, and hessians, for set of arbitrarily sampled torsional coordinates with all other coordinates optimized """ spc_dct_i = spc_dct[spc_name] # Set the spc_info spc_info = sinfo.from_dct(spc_dct_i) # Get es options overwrite = es_keyword_dct['overwrite'] retryfail = es_keyword_dct['retryfail'] # scan_increment = spc_dct_i['hind_inc'] nsamp_par = spc_dct_i['tau_nsamp'] # Modify the theory method_dct = thy_dct.get(es_keyword_dct['runlvl']) ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) thy_info = tinfo.from_dct(method_dct) ini_thy_info = tinfo.from_dct(ini_method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) mod_ini_thy_info = tinfo.modify_orb_label(ini_thy_info, spc_info) # Script script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) # Set the filesystem objects for thy info _, ini_cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', spc_locs=spc_info, thy_locs=mod_ini_thy_info[1:]) ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_min_cnf_locs, ini_min_cnf_path = ini_loc_info ini_min_rid, ini_min_cid = ini_min_cnf_locs ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path) geo = ini_cnf_save_fs[-1].file.geometry.read(ini_min_cnf_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) ini_sp_save_fs = autofile.fs.single_point(ini_min_cnf_path) if ini_sp_save_fs[-1].file.energy.exists(mod_ini_thy_info[1:4]): ref_ene = ini_sp_save_fs[-1].file.energy.read(mod_ini_thy_info[1:4]) else: ref_ene = ini_cnf_save_fs[-1].file.energy.read(ini_min_cnf_locs) # Get the tors names ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path) if ini_zma_save_fs[-1].file.torsions.exists([0]): tors_dct = ini_zma_save_fs[-1].file.torsions.read([0]) torsions = automol.rotor.from_data(zma, tors_dct) else: torsions = () saddle = bool('ts_' in spc_name) # Run the task if any torsions exist if torsions and not saddle: # Set up tau filesystem objects tau_run_fs, tau_save_fs = build_fs(run_prefix, save_prefix, 'TAU', spc_locs=spc_info, thy_locs=mod_thy_info[1:]) # db_style = 'jsondb' db_style = 'directory' if db_style == 'jsondb': tau_save_fs[-1].root.create() tau_save_fs[-1].json_create() for locs in tau_save_fs[-1].existing(): if tau_save_fs[-1].file.geometry.exists(locs): geol = tau_save_fs[-1].file.geometry.read(locs) tau_save_fs[-1].json.geometry.write(geol, locs) if tau_save_fs[-1].file.energy.exists(locs): enel = tau_save_fs[-1].file.energy.read(locs) tau_save_fs[-1].json.energy.write(enel, locs) if tau_save_fs[-1].file.geometry_info.exists(locs): geo_infl = tau_save_fs[-1].file.geometry_info.read(locs) tau_save_fs[-1].json.geometry_info.write(geo_infl, locs) if tau_save_fs[-1].file.geometry_input.exists(locs): inp_strl = tau_save_fs[-1].file.geometry_input.read(locs) tau_save_fs[-1].json.geometry_input.write(inp_strl, locs) if tau_save_fs[-1].file.gradient_input.exists(locs): inp_strl = tau_save_fs[-1].file.gradient_input.read(locs) tau_save_fs[-1].json.gradient_input.write(inp_strl, locs) if tau_save_fs[-1].file.hessian_input.exists(locs): inp_strl = tau_save_fs[-1].file.hessian_input.read(locs) tau_save_fs[-1].json.hessian_input.write(inp_strl, locs) if tau_save_fs[-1].file.gradient_info.exists(locs): inf_objl = tau_save_fs[-1].file.gradient_info.read(locs) tau_save_fs[-1].json.gradient_info.write(inf_objl, locs) if tau_save_fs[-1].file.hessian_info.exists(locs): inf_objl = tau_save_fs[-1].file.hessian_info.read(locs) tau_save_fs[-1].json.hessian_info.write(inf_objl, locs) if tau_save_fs[-1].file.gradient.exists(locs): gradl = tau_save_fs[-1].file.gradient.read(locs) tau_save_fs[-1].json.gradient.write(gradl, locs) if tau_save_fs[-1].file.hessian.exists(locs): hessl = tau_save_fs[-1].file.hessian.read(locs) tau_save_fs[-1].json.energy.hessian(hessl, locs) if tau_save_fs[-1].file.zmatrix.exists(locs): zmatl = tau_save_fs[-1].file.zmatrix.read(locs) tau_save_fs[-1].json.zmatrix.write(zmatl, locs) if tau_save_fs[-1].file.harmonic_frequencies.exists(locs): hfreql = tau_save_fs[-1].file.harmonic_frequencies.read( locs) tau_save_fs[-1].json.harmonic_frequencies.write( hfreql, locs) save_path = tau_save_fs[-1].path(locs) sp_save_fs = autofile.fs.single_point(save_path) sp_save_locs = sp_save_fs[-1].existing() save_path = tau_save_fs[-1].root.path() jsp_save_fs = autofile.fs.single_point(save_path, json_layer=locs) for sp_locs in sp_save_locs: if sp_save_fs[-1].file.energy.exists(sp_locs): enel = sp_save_fs[-1].file.energy.read(sp_locs) jsp_save_fs[-1].json.energy.write(enel, sp_locs) if sp_save_fs[-1].file.input.exists(sp_locs): inp_strl = sp_save_fs[-1].file.input.read(sp_locs) jsp_save_fs[-1].json.input.write(inp_strl, sp_locs) if sp_save_fs[-1].file.info.exists(sp_locs): inf_objl = sp_save_fs[-1].file.info.read(sp_locs) jsp_save_fs[-1].json.info.write(inf_objl, sp_locs) if job == 'samp': # Set up the script script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) tors_names = automol.rotor.names(torsions, flat=True) # Run sampling tau.tau_sampling(zma, ref_ene, spc_info, tors_names, nsamp_par, mod_ini_thy_info, tau_run_fs, tau_save_fs, script_str, overwrite, saddle=saddle, **kwargs) elif job in ('energy', 'grad'): # Set up the run scripts script_str, kwargs = qchem_params(method_dct) # Run the job over all the conformers requested by the user for locs in tau_save_fs[-1].existing(): geo_run_path = tau_run_fs[-1].path(locs) if db_style == 'jsondb': geo_save_path = tau_save_fs[-1].root.path() geo = tau_save_fs[-1].json.geometry.read(locs) elif db_style == 'directory': geo_save_path = tau_save_fs[-1].path(locs) geo = tau_save_fs[-1].file.geometry.read(locs) tau_run_fs[-1].create(locs) zma = None ES_TSKS[job](zma, geo, spc_info, mod_thy_info, tau_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=retryfail, **kwargs) ioprinter.obj('vspace') elif job == 'hess': # Add the hessian max hessmax = es_keyword_dct['hessmax'] # Set up the run scripts script_str, kwargs = qchem_params(method_dct) # Run the job over all the conformers requested by the user hess_cnt = 0 for locs in tau_save_fs.existing(): ioprinter.info_message('HESS Number {}'.format(hess_cnt + 1), newline=1) geo_run_path = tau_run_fs[-1].path(locs) if db_style == 'directory': geo_save_path = tau_save_fs[-1].path(locs) if tau_save_fs[-1].file.hessian.exists(locs): ioprinter.existing_path('Hessian', geo_save_path) hess_cnt += 1 continue geo = tau_save_fs[-1].file.geometry.read(locs) elif db_style == 'jsondb': geo_save_path = tau_save_fs[-1].root.path() if tau_save_fs[-1].json.hessian.exists(locs): ioprinter.existing_path('Hessian', geo_save_path) hess_cnt += 1 continue geo = tau_save_fs[-1].json.geometry.read(locs) zma = None tau_run_fs[-1].create(locs) ES_TSKS[job](zma, geo, spc_info, mod_thy_info, tau_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=retryfail, **kwargs) hess_cnt += 1 if hess_cnt == hessmax: break else: ioprinter.info_message('No torsional modes in the species')
def write_messrate_task(pesgrp_num, pes_inf, rxn_lst, tsk_key_dct, pes_param_dct, spc_dct, thy_dct, pes_model_dct, spc_model_dct, unstab_chnls, label_dct, rate_paths_dct, run_prefix, save_prefix): """ Reads and processes all information in the save filesys for all species on the PES that are required for MESS rate calculations, as specified by the model dictionaries built from user input. :param pes_idx: :type pes_idx: int :param rxn_lst: :type rxn_lst: :param pes_model: model for PES conditions for rates from user input :type pes_model: str :param spc_model: model for partition fxns for rates from user input :type spc_model: str :param mess_path: path to write mess file (change since pfx given?) """ _, pes_idx, _ = pes_inf pes_mod = tsk_key_dct['kin_model'] spc_mod = tsk_key_dct['spc_model'] pes_model_dct_i = pes_model_dct[pes_mod] spc_model_dct_i = spc_model_dct[spc_mod] # Write the MESS strings for all the PES channels rxn_chan_str, dats, hot_enes_dct = make_pes_mess_str( spc_dct, rxn_lst, pes_idx, pesgrp_num, unstab_chnls, run_prefix, save_prefix, label_dct, tsk_key_dct, pes_param_dct, thy_dct, pes_model_dct_i, spc_model_dct_i, spc_mod) # Write the strings for the MESS input file globkey_str = make_header_str(spc_dct, rxn_lst, pes_idx, pesgrp_num, pes_param_dct, hot_enes_dct, label_dct, pes_model_dct_i['rate_temps'], pes_model_dct_i['pressures'], tsk_key_dct['float_precision']) # Write the energy transfer section strings for MESS file etransfer = pes_model_dct_i['glob_etransfer'] energy_trans_str = make_global_etrans_str(rxn_lst, spc_dct, etransfer) # Write base MESS input string into the RUN filesystem mess_inp_str = mess_io.writer.messrates_inp_str( globkey_str, rxn_chan_str, energy_trans_str=energy_trans_str, well_lump_str=None) base_mess_path = rate_paths_dct[pes_inf]['base'] ioprinter.obj('line_plus') ioprinter.writing('MESS input file', base_mess_path) ioprinter.debug_message('MESS Input:\n\n' + mess_inp_str) autorun.write_input(base_mess_path, mess_inp_str, aux_dct=dats, input_name='mess.inp') # Write the second MESS string (well extended), if needed if use_well_extension(spc_dct, rxn_lst, pes_idx, tsk_key_dct['use_well_extension']): print('User requested well extension scheme for rates...') # Run the base MESSRATE autorun.run_script(autorun.SCRIPT_DCT['messrate'], base_mess_path) # Write the well-extended MESSRATE file print('Reading the input and output from the base MESSRATE run...') inp_str = ioformat.read_file(base_mess_path, 'mess.inp') out_str = ioformat.read_file(base_mess_path, 'mess.out') aux_str = ioformat.read_file(base_mess_path, 'mess.aux') log_str = ioformat.read_file(base_mess_path, 'mess.log') print('Setting up the well-extended MESSRATE input...') wext_mess_inp_str = ratefit.fit.well_lumped_input_file( inp_str, out_str, aux_str, log_str, pes_model_dct_i['well_extension_pressure'], pes_model_dct_i['well_extension_temp']) wext_mess_path = rate_paths_dct[pes_inf]['wext'] ioprinter.obj('line_plus') ioprinter.writing('MESS input file', base_mess_path) ioprinter.debug_message('MESS Input:\n\n' + mess_inp_str) autorun.write_input(wext_mess_path, wext_mess_inp_str, aux_dct=dats, input_name='mess.inp')
def run_tsk(tsk, obj_queue, proc_keyword_dct, spc_dct, thy_dct, spc_mod_dct_i, pes_mod_dct_i, run_prefix, save_prefix, mdriver_path): """ run a proc tess task for generating a list of conformer or tau sampling geometries """ # Print the head of the task ioprinter.output_task_header(tsk) ioprinter.output_keyword_list(proc_keyword_dct, thy_dct) # Setup csv data dictionary for specific task csv_data = util.set_csv_data(tsk) filelabel, thylabel = util.get_file_label(tsk, pes_mod_dct_i, proc_keyword_dct, spc_mod_dct_i) chn_basis_ene_dct = {} col_array = [] spc_array = [] # Exclude unstable species # These species break certain checks (e.g. no ene exists for geo collect) obj_queue = util.remove_unstable(obj_queue, spc_dct, thy_dct, spc_mod_dct_i, proc_keyword_dct, save_prefix) # obj_queue, ts_miss_data = util.remove_ts_missing( # obj_queue, spc_dct) # obj_queue = util.remove_radrad_ts( # obj_queue, spc_dct) # Set up lists for reporting missing data miss_data = () ts_miss_data = () # Initialize dictionaries to carry strings for writing disp_dct = {} # Begin the loop over the species for spc_name in obj_queue: # info printed to output file ioprinter.obj('line_dash') ioprinter.info_message("Species: ", spc_name) # Heat of formation basis molecules and coefficients # does not require filesystem information if 'coeffs' in tsk: label = spc_name csv_data_i, spc_array = collect.coeffs(spc_name, spc_dct, pes_mod_dct_i, spc_array) csv_data[label] = csv_data_i col_array = spc_array # All other tasks require filesystem information else: # unpack spc and level info for conformers spc_dct_i = spc_dct[spc_name] spc_mod_dct_i = util.choose_theory(proc_keyword_dct, spc_mod_dct_i) ret = util.choose_conformers(spc_name, proc_keyword_dct, spc_mod_dct_i, save_prefix, run_prefix, spc_dct_i, thy_dct) cnf_fs, rng_cnf_locs_lst, rng_cnf_locs_path, mod_thy_info = ret # Add geo to missing data task if locs absent if not rng_cnf_locs_lst: miss_data += ((spc_name, mod_thy_info, 'geometry'), ) # Loop over conformers for locs, locs_path in zip(rng_cnf_locs_lst, rng_cnf_locs_path): miss_data_i = None label = spc_name + ':' + '_'.join(locs) print(label) if 'freq' in tsk and not _skip(spc_name, spc_dct_i): _dat, miss_data_i = collect.frequencies( spc_name, spc_dct_i, spc_mod_dct_i, proc_keyword_dct, thy_dct, cnf_fs, locs, locs_path, run_prefix, save_prefix) if _dat is not None: csv_data_i, csv_data_j, disp_str = _dat csv_data['freq'][label] = csv_data_i tors_freqs, all_freqs, sfactor = csv_data_j if tors_freqs is not None: csv_data['tfreq'][label] = tors_freqs csv_data['allfreq'][label] = all_freqs csv_data['scalefactor'][label] = [sfactor] if disp_str is not None: disp_dct.update({spc_name: disp_str}) elif 'geo' in tsk: csv_data_i, miss_data_i = collect.geometry( spc_name, locs, locs_path, cnf_fs, mod_thy_info) print(csv_data_i) csv_data[label] = csv_data_i elif 'molden' in tsk: csv_data_i, miss_data_i = collect.molden( spc_name, locs, locs_path, cnf_fs, mod_thy_info) print(csv_data_i) csv_data[label] = csv_data_i elif 'zma' in tsk: csv_data_i, miss_data_i = collect.zmatrix( spc_name, locs, locs_path, cnf_fs, mod_thy_info) csv_data[label] = csv_data_i elif 'torsion' in tsk and not _skip(spc_name, spc_dct_i): csv_data_i, miss_data_i = collect.torsions( spc_name, spc_dct_i, spc_mod_dct_i, mod_thy_info, run_prefix, save_prefix) elif 'ene' in tsk: csv_data_i, miss_data_i = collect.energy( spc_name, spc_dct_i, spc_mod_dct_i, proc_keyword_dct, thy_dct, locs, locs_path, cnf_fs, run_prefix, save_prefix) csv_data[label] = csv_data_i elif 'enthalpy' in tsk: ret = collect.enthalpy(spc_name, spc_dct, spc_dct_i, spc_mod_dct_i, pes_mod_dct_i, chn_basis_ene_dct, spc_array, locs, locs_path, cnf_fs, run_prefix, save_prefix) csv_data_i, chn_basis_ene_dct, spc_array = ret csv_data[label] = csv_data_i col_array = spc_array elif 'entropy' in tsk: ret = collect.enthalpy(spc_name, spc_dct, spc_dct_i, spc_mod_dct_i, pes_mod_dct_i, chn_basis_ene_dct, spc_array, locs, locs_path, cnf_fs, run_prefix, save_prefix) csv_data_i, chn_basis_ene_dct, spc_array = ret csv_data[label] = csv_data_i elif 'heat' in tsk: ret = collect.enthalpy(spc_name, spc_dct, spc_dct_i, spc_mod_dct_i, pes_mod_dct_i, chn_basis_ene_dct, spc_array, locs, locs_path, cnf_fs, run_prefix, save_prefix) csv_data_i, chn_basis_ene_dct, spc_array = ret csv_data[label] = csv_data_i elif 'messpf_inp' in tsk: ret = collect.messpf_input(spc_name, spc_dct_i, spc_mod_dct_i, pes_mod_dct_i, locs, locs_path, cnf_fs, run_prefix, save_prefix) csv_data_i, _, miss_data_i = ret print(csv_data_i) csv_data[label] = csv_data_i elif 'pf' in tsk: ret = collect.partition_function(spc_name, spc_dct_i, spc_mod_dct_i, pes_mod_dct_i, locs, locs_path, cnf_fs, run_prefix, save_prefix) csv_data_i, miss_data_i = ret csv_data[label] = csv_data_i[1] col_array = csv_data_i[0] if miss_data_i is not None: miss_data += (miss_data_i, ) # Write a report that details what data is missing missing_data = miss_data + ts_miss_data # Write the csv data into the appropriate file util.write_csv_data(tsk, csv_data, filelabel, col_array, mdriver_path) # Gather data that is provided for each species in files in a dir data_dirs = (('displacements_' + thylabel, disp_dct), ) util.write_data_dirs(data_dirs, mdriver_path) return missing_data
def make_messrate_str(pes_idx, rxn_lst, pes_model, spc_model, spc_dct, pes_model_dct, spc_model_dct, unstab_chnls, label_dct, mess_path, run_prefix, save_prefix, make_lump_well_inp=False): """ Reads and processes all information in the save filesys for all species on the PES, required for MESS rate calculations, as specified by the model dictionaries built from user input. :param pes_idx: :type pes_idx: int :param rxn_lst: :type rxn_lst: :param pes_model: model for PES conditions for rates from user input :type pes_model: str :param spc_model: model for partition fxns for rates from user input :type spc_model: str :param mess_path: path to write mess file (change since pfx given?) """ pes_model_dct_i = pes_model_dct[pes_model] spc_model_dct_i = spc_model_dct[spc_model] # Write the strings for the MESS input file globkey_str = make_header_str(spc_dct, temps=pes_model_dct_i['rate_temps'], pressures=pes_model_dct_i['pressures']) # Write the energy transfer section strings for MESS file etransfer = pes_model_dct_i['glob_etransfer'] energy_trans_str = make_global_etrans_str(rxn_lst, spc_dct, etransfer) # Write the MESS strings for all the PES channels rxn_chan_str, dats, _, _ = make_pes_mess_str(spc_dct, rxn_lst, pes_idx, unstab_chnls, run_prefix, save_prefix, label_dct, pes_model_dct_i, spc_model_dct_i, spc_model) # Generate second string with well lumping if needed if not is_abstraction_pes(spc_dct) and make_lump_well_inp: print('Need to do well lumping scheme') script_str = autorun.SCRIPT_DCT['messrate'] mess_inp_str = autorun.mess.well_lumped_input_file( script_str, mess_path, globkey_str, rxn_chan_str, energy_trans_str=energy_trans_str, aux_dct=dats, input_name='mess.inp', # need dif name for this? output_names=('mess.aux', )) else: mess_inp_str = mess_io.writer.messrates_inp_str( globkey_str, rxn_chan_str, energy_trans_str=energy_trans_str, well_lump_str=None) # Write the MESS file into the filesystem ioprinter.obj('line_plus') ioprinter.writing('MESS input file', mess_path) ioprinter.debug_message('MESS Input:\n\n' + mess_inp_str) return mess_inp_str, dats
def make_pes_mess_str(spc_dct, rxn_lst, pes_idx, run_prefix, save_prefix, label_dct, pes_model_dct_i, spc_model_dct_i, spc_model, thy_dct): """ Write all the MESS input file strings for the reaction channels """ ioprinter.messpf('channel_section') # Initialize empty MESS strings full_well_str, full_bi_str, full_ts_str = '', '', '' full_dat_str_dct = {} pes_ene_dct = {} conn_lst = tuple() # Set the energy and model for the first reference species ioprinter.info_message('\nCalculating reference energy for PES') ref_ene = set_reference_ene( rxn_lst, spc_dct, thy_dct, pes_model_dct_i, spc_model_dct_i, run_prefix, save_prefix, ref_idx=0) # Loop over all the channels and write the MESS strings written_labels = [] basis_energy_dct = {} for rxn in rxn_lst: chnl_idx, (reacs, prods) = rxn ioprinter.obj('vspace') ioprinter.reading('PES electrion structure data') ioprinter.channel(chnl_idx, reacs, prods) # Set the TS name and channel model tsname = 'ts_{:g}_{:g}'.format(pes_idx+1, chnl_idx+1) # Obtain all of the species data if spc_model not in basis_energy_dct: basis_energy_dct[spc_model] = {} # Pass in full ts class chnl_infs, chn_basis_ene_dct = get_channel_data( reacs, prods, tsname, spc_dct, basis_energy_dct[spc_model], pes_model_dct_i, spc_model_dct_i, run_prefix, save_prefix) basis_energy_dct[spc_model].update(chn_basis_ene_dct) # Calculate the relative energies of all spc on the channel chnl_enes = sum_channel_enes(chnl_infs, ref_ene) # Write the mess strings for all spc on the channel mess_strs, dat_str_dct, written_labels = _make_channel_mess_strs( tsname, reacs, prods, spc_dct, label_dct, written_labels, chnl_infs, chnl_enes, spc_model_dct_i) # Append to full MESS strings [well_str, bi_str, ts_str] = mess_strs full_well_str += well_str full_bi_str += bi_str full_ts_str += ts_str full_dat_str_dct.update(dat_str_dct) ioprinter.debug_message('rxn', rxn) ioprinter.debug_message('enes', chnl_enes) ioprinter.debug_message('label dct', label_dct) ioprinter.debug_message('written labels', written_labels) # Combine all the reaction channel strings rxn_chan_str = '\n'.join([full_well_str, full_bi_str, full_ts_str]) return rxn_chan_str, full_dat_str_dct, pes_ene_dct, conn_lst
def collate_properties(tgt_queue, spc_dct, thy_dct, etrans_keyword_dct, save_prefix): """ Write the chemkin string """ bath_name = etrans_keyword_dct['bath'] # Get the base theory info obj thy_info = filesys.inf.get_es_info(etrans_keyword_dct['runlvl'], thy_dct) # Read the epsilon and sigma params for the BATH+BATH interaction cnf_save_fs, min_cnf_locs, etrans_fs, etrans_locs = _etrans_fs( spc_dct, bath_name, bath_name, thy_info, save_prefix) if etrans_fs[-1].file.epsilon.exists(etrans_locs): bb_eps = etrans_fs[-1].file.epsilon.read(etrans_locs) else: bb_eps = None if etrans_fs[-1].file.sigma.exists(etrans_locs): bb_sig = etrans_fs[-1].file.sigma.read(etrans_locs) else: bb_sig = None # Now obtain all the properties for the TGT+TGT interaction for CKIN # Uses simple combining rules for the LJ params trans_dct = {} for tgt_name, _ in tgt_queue: # Build the filesystem objects needed for the TGT+BATH interaction cnf_save_fs, min_cnf_locs, etrans_fs, etrans_locs = _etrans_fs( spc_dct, tgt_name, bath_name, thy_info, save_prefix) # Read the conformer filesystems if cnf_save_fs[-1].file.geometry.exists(min_cnf_locs): geom = cnf_save_fs[-1].file.geometry.read(min_cnf_locs) else: geom = None if cnf_save_fs[-1].file.dipole_moment.exists(min_cnf_locs): vec = cnf_save_fs[-1].file.dipole_moment.read(min_cnf_locs) dip_mom = automol.prop.total_dipole_moment(vec) else: dip_mom = None if cnf_save_fs[-1].file.polarizability.exists(min_cnf_locs): tensor = cnf_save_fs[-1].file.polarizability.read(min_cnf_locs) polar = automol.prop.total_polarizability(tensor) else: polar = None # Read the energy transfer filesystems if etrans_fs[-1].file.epsilon.exists(etrans_locs): tb_eps = etrans_fs[-1].file.epsilon.read(etrans_locs) else: tb_eps = None if etrans_fs[-1].file.sigma.exists(etrans_locs): tb_sig = etrans_fs[-1].file.sigma.read(etrans_locs) else: tb_sig = None # Get the shape index from the geometry shape_idx = _shape_idx(geom) if geom is not None else 2 # Use combine rules for the sigma and epsilon tt_eps = _combine_epsilon(tb_eps, bb_eps) tt_sig = _combine_sigma(tb_sig, bb_sig) # Build dct and append it ot overall dictionary Append info to list dct = { 'shape_idx': shape_idx, 'dipole_moment': dip_mom, 'polarizability': polar, 'epsilon': tt_eps, 'sigma': tt_sig } trans_dct.update({tgt_name: dct}) # Write the string with all of the transport properties transport_str = chemkin_io.writer.transport.properties(trans_dct) ioprinter.debug_message('transport_str\n', transport_str, newline=1) ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message('Writing the CHEMKIN transport file', newline=1) ckin_trans_str = transroutines.write_file() writer.ckin.write_transport_file(ckin_trans_str, ckin_path) return transport_str
def make_pes_mess_str(spc_dct, rxn_lst, pes_idx, pesgrp_num, unstable_chnls, run_prefix, save_prefix, label_dct, tsk_key_dct, pes_param_dct, thy_dct, pes_model_dct_i, spc_model_dct_i, spc_model): """ Write all the MESS input file strings for the reaction channels """ ioprinter.messpf('channel_section') # Initialize data carrying objects and empty MESS strings basis_energy_dct = {} basis_energy_dct[spc_model] = {} full_well_str, full_bi_str, full_ts_str = '', '', '' full_dat_str_dct = {} # Set the energy and model for the first reference species ioprinter.info_message('\nCalculating reference energy for PES') ref_ene, model_basis_energy_dct = set_reference_ene( rxn_lst, spc_dct, tsk_key_dct, basis_energy_dct[spc_model], thy_dct, pes_model_dct_i, spc_model_dct_i, run_prefix, save_prefix, ref_idx=0) basis_energy_dct[spc_model].update(model_basis_energy_dct) print('basis energy dct') print(basis_energy_dct) # Loop over all the channels and write the MESS strings written_labels = [] for rxn in rxn_lst: chnl_idx, (reacs, prods) = rxn ioprinter.obj('vspace') ioprinter.reading('PES electronic structure data') ioprinter.channel(chnl_idx + 1, reacs, prods) # Get the names for all of the configurations of the TS tsname = base_tsname(pes_idx, chnl_idx) tsname_allconfigs = tsnames_in_dct(pes_idx, chnl_idx, spc_dct) # Pass in full ts class chnl_infs, chn_basis_ene_dct = get_channel_data( reacs, prods, tsname_allconfigs, spc_dct, tsk_key_dct, basis_energy_dct[spc_model], thy_dct, pes_model_dct_i, spc_model_dct_i, run_prefix, save_prefix) basis_energy_dct[spc_model].update(chn_basis_ene_dct) # Calculate the relative energies of all spc on the channel chnl_enes = sum_channel_enes(chnl_infs, ref_ene) # Set the hot energies using the relative enes that will be # written into the global key section of MESS input later hot_enes_dct = set_hot_enes(pesgrp_num, reacs, prods, chnl_enes, pes_param_dct, ene_range=None) # Write the mess strings for all spc on the channel mess_strs, dat_str_dct, written_labels = _make_channel_mess_strs( tsname, reacs, prods, pesgrp_num, spc_dct, label_dct, written_labels, pes_param_dct, chnl_infs, chnl_enes, spc_model_dct_i, unstable_chnl=(chnl_idx in unstable_chnls)) # Append to full MESS strings [well_str, bi_str, ts_str] = mess_strs full_well_str += well_str full_bi_str += bi_str full_ts_str += ts_str full_dat_str_dct.update(dat_str_dct) # Combine all the reaction channel strings; remove empty lines rxn_chan_str = '\n'.join([full_well_str, full_bi_str, full_ts_str]) rxn_chan_str = ioformat.remove_empty_lines(rxn_chan_str) return rxn_chan_str, full_dat_str_dct, hot_enes_dct
def _mechdriver_main(tmp_dir): """ Copy of MechDriver bin """ # print header message and host name (probably combine into one function) ioprinter.program_header('amech') ioprinter.random_cute_animal() ioprinter.host_name() # parse all of the input ioprinter.program_header('inp') inp_strs = ioparser.read_amech_input(tmp_dir) thy_dct = ioparser.thy.theory_dictionary(inp_strs['thy']) kmod_dct, smod_dct = ioparser.models.models_dictionary( inp_strs['mod'], thy_dct) inp_key_dct = ioparser.run.input_dictionary(inp_strs['run']) pes_idx_dct, spc_idx_dct = ioparser.run.chem_idxs(inp_strs['run']) tsk_lst_dct = ioparser.run.tasks( inp_strs['run'], inp_strs['mech'], thy_dct) spc_dct, glob_dct = ioparser.spc.species_dictionary( inp_strs['spc'], inp_strs['dat'], inp_strs['geo'], 'csv') pes_dct = ioparser.mech.pes_dictionary( inp_strs['mech'], 'chemkin', spc_dct) pes_rlst, spc_rlst = ioparser.rlst.run_lst( pes_dct, spc_dct, pes_idx_dct, spc_idx_dct) # build the run-save filesystem directories prefix_fs(inp_key_dct['run_prefix'], inp_key_dct['save_prefix']) # run drivers requested by user es_tsks = tsk_lst_dct.get('es') if es_tsks is not None: ioprinter.program_header('es') esdriver.run( pes_rlst, spc_rlst, es_tsks, spc_dct, glob_dct, thy_dct, inp_key_dct['run_prefix'], inp_key_dct['save_prefix'] ) ioprinter.program_exit('es') therm_tsks = tsk_lst_dct.get('thermo') if therm_tsks is not None: ioprinter.program_header('thermo') thermodriver.run( pes_rlst, spc_rlst, therm_tsks, kmod_dct, smod_dct, spc_dct, thy_dct, inp_key_dct['run_prefix'], inp_key_dct['save_prefix'], tmp_dir ) ioprinter.program_exit('thermo') trans_tsks = tsk_lst_dct.get('trans') if trans_tsks is not None: ioprinter.program_header('trans') if pes_dct: transdriver.run( pes_rlst, spc_rlst, trans_tsks, smod_dct, spc_dct, thy_dct, inp_key_dct['run_prefix'], inp_key_dct['save_prefix'] ) ioprinter.program_exit('trans') ktp_tsks = tsk_lst_dct.get('ktp') if ktp_tsks is not None: ioprinter.program_header('ktp') ktpdriver.run( pes_rlst, ktp_tsks, spc_dct, glob_dct, kmod_dct, smod_dct, inp_key_dct['run_prefix'], inp_key_dct['save_prefix'], tmp_dir ) ioprinter.program_exit('ktp') proc_tsks = tsk_lst_dct.get('proc') if proc_tsks is not None: ioprinter.program_header('proc') procdriver.run( pes_rlst, spc_rlst, proc_tsks, spc_dct, thy_dct, kmod_dct, smod_dct, inp_key_dct['run_prefix'], inp_key_dct['save_prefix'], tmp_dir ) ioprinter.program_exit('proc') # exit program ioprinter.obj('vspace') ioprinter.program_exit('amech')
def read_spc_data(spc_dct, spc_name, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix, chn_basis_ene_dct, calc_chn_ene=True, spc_locs=None): """ Reads all required data from the SAVE filesystem for a given species. Also sets the writer for appropriately formatting the data into an MESS input file string. All of the data that is read is determined by the models that are described in the pes and spc model dictionaries. Info and basis species stored in dicts. :param spc_dct: :type spc_dct: :param spc_name: mechanism name of species :type spc_name: str :param pes_mod_dct_i: keyword dict of specific PES model :type pes_mod_dct_i: dict[] :param spc_mod_dct_i: keyword dict of specific species model :type spc_mod_dct_i: dict[] :param run_prefix: root-path to the run-filesystem :type run_prefix: str :param save_prefix: root-path to the save-filesystem :type save_prefix: str :param chn_basis_ene_dct: basis species <names> for mechanism species :type chn_basis_ene_dct: dict[] :rtype: (dict[], dict[]) """ ioprinter.obj('line_plus') ioprinter.reading(f'filesystem info for {spc_name}', newline=1) vib_model = spc_mod_dct_i['vib']['mod'] tors_model = spc_mod_dct_i['tors']['mod'] spc_dct_i = spc_dct[spc_name] if typ.is_atom(spc_dct_i): inf_dct = atm_data(spc_dct, spc_name, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix) writer = 'atom_block' else: if vib_model == 'tau' or 'tau' in tors_model: inf_dct = tau_data(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, saddle=False) writer = 'tau_block' else: inf_dct, chn_basis_ene_dct = mol_data(spc_name, spc_dct, pes_mod_dct_i, spc_mod_dct_i, chn_basis_ene_dct, run_prefix, save_prefix, calc_chn_ene=calc_chn_ene, spc_locs=spc_locs, zrxn=None) writer = 'species_block' # Add writer to inf dct inf_dct['writer'] = writer return inf_dct, chn_basis_ene_dct
def single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=True, zrxn=None, use_locs=None, **kwargs): """ generate single optimized geometry to be saved into a filesystem """ if not _this_conformer_is_running(zma, cnf_run_fs): # Build the filesystem if use_locs is None: rid = autofile.schema.generate_new_ring_id() cid = autofile.schema.generate_new_conformer_id() locs = (rid, cid) else: locs = use_locs cnf_run_fs[-1].create(locs) cnf_run_path = cnf_run_fs[-1].path(locs) run_fs = autofile.fs.run(cnf_run_path) # Run the optimization ioprinter.info_message('Optimizing a single conformer', zrxn) success, ret = es_runner.execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=zma, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, frozen_coordinates=(), saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) if success: inf_obj, _, out_str = ret prog = inf_obj.prog method = inf_obj.method ene = elstruct.reader.energy(prog, method, out_str) geo = elstruct.reader.opt_geometry(prog, out_str) zma = elstruct.reader.opt_zmatrix(prog, out_str) saved_locs, saved_geos, saved_enes = _saved_cnf_info( cnf_save_fs, mod_thy_info) if _geo_unique(geo, ene, saved_geos, saved_enes, zrxn=zrxn): sym_id = _sym_unique(geo, ene, saved_geos, saved_enes) if sym_id is None: if cnf_save_fs[0].file.info.exists(): ioprinter.debug_message('inf_obj path', cnf_save_fs[0].path()) # rinf_obj_s = cnf_save_fs[0].file.info.read() rinf = inf_obj ioprinter.debug_message('inf_obj for r', rinf) # rnsampd = rinf_obj_s.nsamp # rnsampd += 1 # rinf_obj.nsamp = rnsampd else: rinf = autofile.schema.info_objects.conformer_trunk(0) rinf.nsamp = 1 if cnf_save_fs[1].file.info.exists([locs[0]]): cinf_obj_s = cnf_save_fs[1].file.info.read(locs[0]) cinf = inf_obj cnsampd = cinf_obj_s.nsamp cnsampd += 1 cinf.nsamp = cnsampd else: cinf = autofile.schema.info_objects.conformer_branch(0) cinf.nsamp = 1 cnf_save_fs[1].create([locs[0]]) cnf_save_fs[0].file.info.write(rinf) cnf_save_fs[1].file.info.write(cinf, [locs[0]]) filesys.save.conformer(ret, None, cnf_save_fs, mod_thy_info[1:], zrxn=zrxn, rng_locs=(locs[0], ), tors_locs=(locs[1], )) saved_geos.append(geo) saved_enes.append(ene) saved_locs.append(locs) # Update the conformer trajectory file ioprinter.obj('vspace') filesys.mincnf.traj_sort(cnf_save_fs, mod_thy_info) filesys.mincnf.traj_sort(cnf_save_fs, mod_thy_info, locs[0])
def run_tsk(tsk, spc_queue, spc_dct, thy_dct, etrans_keyword_dct, run_prefix, save_prefix): """ Run the task """ # Print the head of the task ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message('Task:', tsk, newline=1) ioprinter.info_message('Options for transport task:', newline=1) for key, val in etrans_keyword_dct.items(): ioprinter.info_message('{} = {}'.format(key, val)) if tsk == 'onedmin': ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message('Obtaining LJ-Params using OneDMin', newline=1) for spc_name, _ in spc_queue: lj.onedmin(spc_name, spc_dct, thy_dct, etrans_keyword_dct, run_prefix, save_prefix) elif tsk == 'write_transport': ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message('Writing the CHEMKIN transport file', newline=1) build.collate_properties(spc_queue, spc_dct, thy_dct, etrans_keyword_dct, save_prefix)
def hr_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ Prepares and executes all electronic structure tasks that generate information for points along hindered-rotor coordinate scans which are launched from some conformer in the save filesystem. For species and transition state conformers. This includes scanning procedures to generate geometries (relaxed) or energies (rigid) points along conformer structures, as well as __ calculations using some saved conformer as input. :param job: :type job: :param spc_dct: :type spc_dct: :param spc_name: :type spc_name: :param thy_dct: :type thy_dct: :param es_keyword_dct: keyword-val pairs for electronic structure task :type es_keyword_dct: dict[str:str] :param run_prefix: root-path to the run-filesystem :type run_prefix: str :param save_prefix: root-path to the save-filesystem :type save_prefix: str """ spc_dct_i = spc_dct[spc_name] saddle = bool('ts_' in spc_name) # Set the spc_info if not saddle: spc_info = sinfo.from_dct(spc_dct_i) else: spc_info = rinfo.ts_info(spc_dct_i['rxn_info']) # Get options from the dct or es options lst overwrite = es_keyword_dct['overwrite'] retryfail = es_keyword_dct['retryfail'] tors_model = es_keyword_dct['tors_model'] # nprocs = es_keyword_dct['nprocs'] nprocs = 1 # Modify the theory method_dct = thy_dct.get(es_keyword_dct['runlvl']) ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) thy_info = tinfo.from_dct(method_dct) ini_thy_info = tinfo.from_dct(ini_method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) mod_ini_thy_info = tinfo.modify_orb_label(ini_thy_info, spc_info) # Set the filesystem objects _root = root_locs(spc_dct_i, saddle=saddle, name=spc_name) _, ini_cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_ini_thy_info[1:], **_root) cnf_run_fs, cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_thy_info[1:], **_root) cnf_range = es_keyword_dct['cnf_range'] hbond_cutoffs = spc_dct_i['hbond_cutoffs'] user_conf_ids = spc_dct_i.get('conf_id') if user_conf_ids is None: cnf_sort_info_lst = _sort_info_lst(es_keyword_dct['sort'], thy_dct, spc_info) ini_min_locs_lst, ini_path_lst = filesys.mincnf.conformer_locators( ini_cnf_save_fs, mod_ini_thy_info, cnf_range=cnf_range, sort_info_lst=cnf_sort_info_lst, hbond_cutoffs=hbond_cutoffs, print_enes=True, nprocs=nprocs) else: ini_min_locs_lst = (user_conf_ids, ) ini_path_lst = (ini_cnf_save_fs[-1].path(user_conf_ids), ) all_run_cnf_locs_lst, _ = filesys.mincnf.conformer_locators( cnf_save_fs, mod_thy_info, cnf_range='all', nprocs=nprocs) ini_to_run_locs_dct = filesys.mincnf.fs_confs_dict(cnf_save_fs, all_run_cnf_locs_lst, ini_cnf_save_fs, ini_min_locs_lst) for ini_min_locs, ini_cnf_save_path in zip(ini_min_locs_lst, ini_path_lst): # Read zma, geo, and torsions ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path) geo = ini_cnf_save_fs[-1].file.geometry.read(ini_min_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) if ini_zma_save_fs[-1].file.torsions.exists([0]): tors_dct = ini_zma_save_fs[-1].file.torsions.read([0]) torsions = automol.rotor.from_data( zma, tors_dct, ) else: torsions = () zrxn = spc_dct_i.get('zrxn', None) # Run the task if any torsions exist if any(torsions): # Find equivalent conformer in the run filesys, if it doesn't exist # run a single conformer to generate it min_locs = ini_to_run_locs_dct[tuple(ini_min_locs)] if min_locs is None: script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) rid = conformer.rng_loc_for_geo(geo, cnf_save_fs) if rid is None: new_rid = autofile.schema.generate_new_ring_id() new_cid = autofile.schema.generate_new_conformer_id() conformer.single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=retryfail, zrxn=zrxn, use_locs=(new_rid, new_cid), **kwargs) min_locs = (new_rid, new_cid) else: new_cid = autofile.schema.generate_new_conformer_id() conformer.single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=retryfail, zrxn=zrxn, use_locs=(rid, new_cid), **kwargs) min_locs = (rid, new_cid) save_locs = cnf_save_fs[-1].existing() if min_locs not in save_locs: locinf = filesys.mincnf.this_conformer_was_run_in_run( zma, cnf_run_fs) _, sym_locs_lst = locinf for sym_locs in sym_locs_lst: if sym_locs in save_locs: min_locs = sym_locs cnf_save_path = cnf_save_fs[-1].path(min_locs) ioprinter.info_message( f'Same conformer saved at {ini_cnf_save_path} ' f'and {cnf_save_path}') # Create run fs if that directory has been deleted to run the jobs # ini_cnf_run_fs[-1].create(ini_min_locs) # ini_cnf_run_path = ini_cnf_run_fs[-1].path(ini_min_locs) cnf_run_fs[-1].create(min_locs) cnf_run_path = cnf_run_fs[-1].path(min_locs) # Get the runlvl zma and torsion info zma_save_fs = autofile.fs.zmatrix(cnf_save_path) geo = cnf_save_fs[-1].file.geometry.read(min_locs) zma = zma_save_fs[-1].file.zmatrix.read((0, )) if zma_save_fs[-1].file.torsions.exists([0]): tors_dct = zma_save_fs[-1].file.torsions.read([0]) torsions = automol.rotor.from_data( zma, tors_dct, ) else: torsions = () if 'fa' in tors_model: scn = 'CSCAN' elif 'f' in tors_model: if len(torsions) > 1: scn = 'CSCAN' else: scn = 'SCAN' else: scn = 'SCAN' # ini_scn_run_fs, ini_scn_save_fs = build_fs( # ini_cnf_run_path, ini_cnf_save_path, scn, # zma_locs=(0,)) scn_run_fs, scn_save_fs = build_fs(cnf_run_path, cnf_save_path, scn, zma_locs=(0, )) if job == 'scan': increment = spc_dct_i.get('hind_inc', 30.0 * phycon.DEG2RAD) hr.hindered_rotor_scans(zma, spc_info, mod_thy_info, scn_run_fs, scn_save_fs, torsions, tors_model, method_dct, overwrite, zrxn=zrxn, saddle=saddle, increment=increment, retryfail=retryfail) elif job == 'reopt': script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) # pull stuff from dcts ethresh = es_keyword_dct['hrthresh'] increment = spc_dct_i.get('hind_inc', 30.0 * phycon.DEG2RAD) zrxn = spc_dct_i.get('zrxn', None) run_tors_names = automol.rotor.names(torsions) run_tors_grids = automol.rotor.grids(torsions, increment=increment) # Set constraints const_names = automol.zmat.set_constraint_names( zma, run_tors_names, tors_model) # Read and print the potential sp_fs = autofile.fs.single_point(cnf_save_path) ref_ene = sp_fs[-1].file.energy.read(mod_thy_info[1:4]) tors_pots, tors_zmas, tors_paths = {}, {}, {} for tors_names, tors_grids in zip(run_tors_names, run_tors_grids): constraint_dct = automol.zmat.constraint_dct( zma, const_names, tors_names) pot, _, _, _, zmas, paths = filesys.read.potential( tors_names, tors_grids, cnf_save_path, mod_thy_info, ref_ene, constraint_dct, read_zma=True) tors_pots[tors_names] = pot tors_zmas[tors_names] = zmas tors_paths[tors_names] = paths # Check for new minimum conformer new_min_zma = hr.check_hr_pot(tors_pots, tors_zmas, tors_paths, emax=ethresh) if new_min_zma is not None: ioprinter.info_message( 'Finding new low energy conformer...', newline=1) new_min_geo = automol.zmat.geometry(new_min_zma) rid = conformer.rng_loc_for_geo(new_min_geo, cnf_save_fs) if rid is None: new_locs = None else: cid = autofile.schema.generate_new_conformer_id() new_locs = (rid, cid) conformer.single_conformer(new_min_zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=retryfail, zrxn=zrxn, use_locs=new_locs, **kwargs) elif job in ('energy', 'grad', 'hess', 'vpt2'): # Script (add energy script call) script_str, kwargs = qchem_params(method_dct) run_tors_names = automol.rotor.names(torsions, flat=True) for tors_names in run_tors_names: # Set the constraint dct and filesys for the scan const_names = automol.zmat.set_constraint_names( zma, run_tors_names, tors_model) constraint_dct = automol.zmat.constraint_dct( zma, const_names, tors_names) # get the scn_locs, maybe get a function? _, scn_locs = scan.scan_locs(scn_save_fs, tors_names, constraint_dct=constraint_dct) for locs in scn_locs: geo = scn_save_fs[-1].file.geometry.read(locs) zma = scn_save_fs[-1].file.zmatrix.read(locs) scn_run_fs[-1].create(locs) ES_TSKS[job](zma, geo, spc_info, mod_thy_info, scn_run_fs, scn_save_fs, locs, run_prefix, script_str, overwrite, zrxn=zrxn, retryfail=retryfail, **kwargs) ioprinter.obj('vspace') else: ioprinter.info_message('No torsional modes in the species')