def get_high_level_energy(spc_info, thy_low_level, thy_high_level, save_prefix, saddle=False): """ get high level energy at low level optimized geometry """ if saddle: spc_save_path = save_prefix else: spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) orb_restr = fsorb.orbital_restriction(spc_info, thy_low_level) thy_low_level = thy_low_level[1:3] thy_low_level.append(orb_restr) ll_save_fs = autofile.fs.theory(spc_save_path) ll_save_path = ll_save_fs.leaf.path(thy_low_level) if saddle: ll_save_fs = autofile.fs.ts(ll_save_path) ll_save_fs.trunk.create() ll_save_path = ll_save_fs.trunk.path() cnf_save_fs = autofile.fs.conformer(ll_save_path) min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs) if not min_cnf_locs: print('ERROR: No minimum conformer geometry for ', 'this species {}'.format(spc_info[0])) return 0.0 cnf_save_path = cnf_save_fs.leaf.path(min_cnf_locs) orb_restr = fsorb.orbital_restriction(spc_info, thy_high_level) thy_high_level = thy_high_level[1:3] thy_high_level.append(orb_restr) sp_save_fs = autofile.fs.single_point(cnf_save_path) sp_save_fs.leaf.create(thy_high_level) if os.path.exists(sp_save_fs.leaf.path(thy_high_level)): min_ene = sp_save_fs.leaf.file.energy.read(thy_high_level) else: print('No energy at path') min_ene = None return min_ene
def get_thermo_paths(spc_save_path, spc_info, har_level): """ set up the path for saving the pf input and output currently using the harmonic theory directory for this because there is no obvious place to save this information for a random assortment of har_level, tors_level, vpt2_level """ orb_restr = fsorb.orbital_restriction(spc_info, har_level) har_levelp = har_level[1:3] har_levelp.append(orb_restr) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(har_levelp) thy_save_path = thy_save_fs.leaf.path(har_levelp) bld_locs = ['PF', 0] bld_save_fs = autofile.fs.build(thy_save_path) bld_save_fs.leaf.create(bld_locs) pf_path = bld_save_fs.leaf.path(bld_locs) # prepare NASA polynomials bld_locs = ['NASA_POLY', 0] bld_save_fs.leaf.create(bld_locs) nasa_path = bld_save_fs.leaf.path(bld_locs) print('Build Path for Partition Functions') print(pf_path) return pf_path, nasa_path
def set_model_filesys(thy_save_fs, spc_info, level, saddle=False): """ Gets filesystem objects for torsional calculations """ # Set the level for the model levelp = level[0:3] levelp.append(fsorb.orbital_restriction(spc_info, level)) # Get the save fileystem path save_path = thy_save_fs.leaf.path(levelp[1:4]) if saddle: save_fs = autofile.fs.ts(save_path) save_fs.trunk.create() save_path = save_fs.trunk.path() # Get the fs object and the locs cnf_save_fs = autofile.fs.conformer(save_path) min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs) # Get the save path for the conformers if min_cnf_locs: cnf_save_path = cnf_save_fs.leaf.path(min_cnf_locs) else: cnf_save_path = '' return cnf_save_fs, cnf_save_path, min_cnf_locs, save_path
def run_rates(header_str, energy_trans_str, well_str, bim_str, ts_str, tsdct, rxn_save_path, model_dct, thy_dct, run_model): """ Generate k(T,P) by first compiling all the MESS strings and then running MESS """ pf_levels = lmech.set_es_model_info(model_dct['es'], thy_dct)[0] ts_info = (tsdct['ich'], tsdct['chg'], tsdct['mul']) orb_restr = fsorb.orbital_restriction(ts_info, thy_info) ref_level = thy_info[1:3] ref_level.append(orb_restr) print('ref level test:', ref_level) thy_save_fs = autofile.fs.theory(rxn_save_path) thy_save_fs.leaf.create(ref_level) thy_save_path = thy_save_fs.leaf.path(ref_level) mess_inp_str = '\n'.join( [header_str, energy_trans_str, well_str, bim_str, ts_str]) print('mess input file') print(mess_inp_str) bld_locs = ['MESS', 0] bld_save_fs = autofile.fs.build(thy_save_path) bld_save_fs.leaf.create(bld_locs) mess_path = bld_save_fs.leaf.path(bld_locs) print('Build Path for MESS rate files:') print(mess_path) with open(os.path.join(mess_path, 'mess.inp'), 'w') as mess_file: mess_file.write(mess_inp_str) script.run_script(script.MESSRATE, mess_path) return mess_path
def get_thy_save_fs(save_prefix, spc_info, thy_info): """ create theory save filesystem """ orb_restr = fsorb.orbital_restriction( spc_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) spc_save_path = get_spc_save_path(save_prefix, spc_info) thy_save_fs = autofile.fs.theory(spc_save_path) return thy_save_fs, thy_lvl
def find_barrierless_transition_state(ts_info, ts_zma, ts_dct, spc_dct, grid, dist_name, rxn_run_path, rxn_save_path, rad_rad_ts, multi_info, ini_thy_info, thy_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess, **opt_kwargs): """ Run TS finder for barrierless reactions """ # run mep scan # multi_info = ['molpro2015', 'caspt2', 'cc-pvtz', 'RR'] multi_info = ['molpro2015', 'caspt2', 'cc-pvdz', 'RR'] orb_restr = fsorb.orbital_restriction(ts_info, multi_info) multi_level = multi_info[0:3] multi_level.append(orb_restr) thy_run_fs = autofile.fs.theory(rxn_run_path) thy_run_fs.leaf.create(multi_level[1:4]) thy_run_path = thy_run_fs.leaf.path(multi_level[1:4]) thy_save_fs = autofile.fs.theory(rxn_save_path) thy_save_fs.leaf.create(multi_level[1:4]) thy_save_path = thy_save_fs.leaf.path(multi_level[1:4]) scn_run_fs = autofile.fs.scan(thy_run_path) scn_save_fs = autofile.fs.scan(thy_save_path) ts_formula = automol.geom.formula(automol.zmatrix.geometry(ts_zma)) grid1 = grid[0] grid2 = grid[1] grid = numpy.append(grid[0], grid[1]) high_mul = ts_dct['high_mul'] print('starting multiref scan:', scn_run_fs.trunk.path()) # Set the active space num_act_orb, num_act_elc = variational.wfn.active_space( ts_dct, spc_dct, high_mul) # Run PST, VTST, VRC-TST based on RAD_RAD_TS model if rad_rad_ts.lower() == 'pst': pass elif rad_rad_ts.lower() == 'vtst': geo, zma, final_dist = variational.vtst.run_vtst_scan( ts_zma, ts_formula, ts_info, ts_dct, spc_dct, high_mul, grid1, grid2, dist_name, multi_level, num_act_orb, num_act_elc, multi_info, ini_thy_info, thy_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess, **opt_kwargs) elif rad_rad_ts.lower() == 'vrctst': # vrctst.calc_vrctst_rates() pass return geo, zma, final_dist
def get_thy_run_path(run_prefix, spc_info, thy_info): """ create theory run path """ orb_restr = fsorb.orbital_restriction( spc_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) spc_run_path = get_spc_run_path(run_prefix, spc_info) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_lvl) thy_run_path = thy_run_fs.leaf.path(thy_lvl) return thy_run_path
def reagent_energies(save_prefix, rgt_ichs, rgt_chgs, rgt_muls, thy_level): """ reagent energies """ enes = [] for rgt_ich, rgt_chg, rgt_mul in zip(rgt_ichs, rgt_chgs, rgt_muls): spc_save_fs = autofile.fs.species(save_prefix) rgt_info = [rgt_ich, rgt_chg, rgt_mul] spc_save_path = spc_save_fs.leaf.path(rgt_info) orb_restr = fsorb.orbital_restriction(rgt_info, thy_level) thy_lvl = thy_level[0:3] thy_lvl.append(orb_restr) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_path = thy_save_fs.leaf.path(thy_lvl[1:4]) cnf_save_fs = autofile.fs.conformer(thy_save_path) min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs) ene = cnf_save_fs.leaf.file.energy.read(min_cnf_locs) enes.append(ene) return enes
def get_geos( spcs, spc_dct, ini_thy_info, save_prefix, run_prefix, kickoff_size, kickoff_backward, projrot_script_str): """get geos for reactants and products using the initial level of theory """ spc_geos = [] cnf_save_fs_lst = [] for spc in spcs: spc_info = [spc_dct[spc]['ich'], spc_dct[spc]['chg'], spc_dct[spc]['mul']] orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info) ini_thy_level = ini_thy_info[0:3] ini_thy_level.append(orb_restr) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) ini_thy_save_fs = autofile.fs.theory(spc_save_path) ini_thy_save_path = ini_thy_save_fs.leaf.path(ini_thy_level[1:4]) ini_thy_run_fs = autofile.fs.theory(spc_run_path) ini_thy_run_path = ini_thy_run_fs.leaf.path(ini_thy_level[1:4]) cnf_save_fs = autofile.fs.conformer(ini_thy_save_path) cnf_save_fs_lst.append(cnf_save_fs) cnf_run_fs = autofile.fs.conformer(ini_thy_run_path) min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs) if min_cnf_locs: geo = cnf_save_fs.leaf.file.geometry.read(min_cnf_locs) else: run_fs = autofile.fs.run(ini_thy_run_path) run_fs.trunk.create() tmp_ini_fs = [None, ini_thy_save_fs] tmp_fs = [spc_save_fs, spc_run_fs, ini_thy_save_fs, ini_thy_run_fs, cnf_save_fs, cnf_run_fs, run_fs] geo = geom.reference_geometry( spc_dct[spc], ini_thy_level, ini_thy_level, tmp_fs, tmp_ini_fs, kickoff_size, kickoff_backward, projrot_script_str, overwrite=False) spc_geos.append(geo) return spc_geos, cnf_save_fs_lst
def find_ts(spc_dct, ts_dct, ts_zma, ini_thy_info, thy_info, run_prefix, save_prefix, overwrite, rad_rad_ts='vtst'): """ find the ts geometry """ # Set various TS information using the dictionary typ = ts_dct['class'] dist_info = ts_dct['dist_info'] grid = ts_dct['grid'] bkp_ts_class_data = ts_dct['bkp_data'] rad_rad = ('radical radical' in typ) low_spin = ('low spin' in typ) print('prepping ts scan for:', typ) [_, _, rxn_run_path, rxn_save_path] = ts_dct['rxn_fs'] ts_info = (ts_dct['ich'], ts_dct['chg'], ts_dct['mul']) _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(*thy_info[0:2]) orb_restr = fsorb.orbital_restriction(ts_info, thy_info) ref_level = thy_info[0:3] ref_level.append(orb_restr) thy_run_fs = autofile.fs.theory(rxn_run_path) thy_run_fs.leaf.create(ref_level[1:4]) thy_run_path = thy_run_fs.leaf.path(ref_level[1:4]) thy_save_fs = autofile.fs.theory(rxn_save_path) thy_save_fs.leaf.create(ref_level[1:4]) thy_save_path = thy_save_fs.leaf.path(ref_level[1:4]) scn_run_fs = autofile.fs.scan(thy_run_path) scn_save_fs = autofile.fs.scan(thy_save_path) ts_run_fs = autofile.fs.ts(thy_run_path) ts_run_fs.trunk.create() ts_run_path = ts_run_fs.trunk.path() run_fs = autofile.fs.run(ts_run_path) ts_save_fs = autofile.fs.ts(thy_save_path) ts_save_fs.trunk.create() ts_save_path = ts_save_fs.trunk.path() cnf_run_fs = autofile.fs.conformer(ts_run_path) cnf_save_fs = autofile.fs.conformer(ts_save_path) cnf_save_fs.trunk.create() # Unpack the dist info dist_name, _, update_guess, brk_name = dist_info # Get TS from filesys or get it from some procedure min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs) if min_cnf_locs and not overwrite: check_filesys_for_ts(ts_dct, ts_zma, cnf_save_fs, overwrite, typ, dist_info, dist_name, bkp_ts_class_data) else: filesys = [ None, None, ts_run_fs, ts_save_fs, cnf_run_fs, cnf_save_fs, None, None, scn_run_fs, scn_save_fs, run_fs ] print('running ts scan:') if rad_rad and low_spin and 'elimination' not in ts_dct['class']: print('Running Scan for Barrierless TS:') find_barrierless_transition_state( ts_info, ts_zma, ts_dct, spc_dct, grid, dist_name, rxn_run_path, rxn_save_path, rad_rad_ts, ini_thy_info, thy_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess, **opt_kwargs) # Have code analyze the path and switch to a sadpt finder if needed else: print('Running Scan for Fixed TS:') max_zma = run_sadpt_scan(typ, grid, dist_name, brk_name, ts_zma, ts_info, ref_level, scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess, **opt_kwargs) geo, zma, final_dist = find_sadpt_transition_state( opt_script_str, run_fs, max_zma, ts_info, ref_level, overwrite, ts_save_path, ts_save_fs, dist_name, dist_info, filesys, **opt_kwargs) return geo, zma, final_dist
def set_fs(spc_dct, spc, thy_info, run_prefix, save_prefix, setfs_chk=True, ini_fs=False): """ set up filesystem """ # Build the species filesys objs [spc_info, spc_run_fs, spc_save_fs, spc_run_path, spc_save_path] = set_spc_fs( spc_dct, spc, run_prefix, save_prefix) # Initialize the filesystems thy_run_fs = None thy_run_path = None thy_save_fs = None thy_save_path = None cnf_run_fs = None cnf_save_fs = None tau_run_fs = None tau_save_fs = None thy_level = thy_info scn_run_fs = None scn_save_fs = None # Build the theory filesys obj thy_level = thy_info orb_restr = fsorb.orbital_restriction( spc_info, thy_info) thy_level = thy_info[0:3] thy_level.append(orb_restr) thy_run_fs = autofile.fs.theory(spc_run_path) thy_save_fs = autofile.fs.theory(spc_save_path) if setfs_chk: if 'ts_' in spc: thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) thy_save_fs.leaf.create(thy_level[1:4]) thy_save_path = thy_save_fs.leaf.path(thy_level[1:4]) thy_run_fs = autofile.fs.ts(thy_run_path) thy_run_fs.trunk.create() thy_run_path = thy_run_fs.trunk.path() thy_save_fs = autofile.fs.ts(thy_save_path) thy_save_fs.trunk.create() thy_save_path = thy_save_fs.trunk.path() else: thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) thy_save_fs.leaf.create(thy_level[1:4]) thy_save_path = thy_save_fs.leaf.path(thy_level[1:4]) cnf_run_fs = autofile.fs.conformer(thy_run_path) cnf_save_fs = autofile.fs.conformer(thy_save_path) tau_run_fs = autofile.fs.tau(thy_run_path) tau_save_fs = autofile.fs.tau(thy_save_path) min_cnf_locs = fsmin.min_energy_conformer_locators( cnf_save_fs) if min_cnf_locs: min_cnf_run_path = cnf_run_fs.leaf.path(min_cnf_locs) min_cnf_save_path = cnf_save_fs.leaf.path(min_cnf_locs) scn_run_fs = autofile.fs.conformer(min_cnf_run_path) scn_save_fs = autofile.fs.conformer(min_cnf_save_path) # filesys = [spc_run_fs, spc_save_fs, thy_run_fs, thy_save_fs, # cnf_run_fs, cnf_save_fs, tau_run_fs, tau_save_fs, # scn_run_fs, scn_save_fs] # Add run fs if needed if not ini_fs: filesys = [spc_run_fs, spc_save_fs, thy_run_fs, thy_save_fs, cnf_run_fs, cnf_save_fs, tau_run_fs, tau_save_fs, scn_run_fs, scn_save_fs] run_fs = autofile.fs.run(thy_run_path) run_fs.trunk.create() filesys.append(run_fs) else: filesys = [thy_run_fs, thy_save_fs, cnf_run_fs, cnf_save_fs, tau_run_fs, tau_save_fs, scn_run_fs, scn_save_fs] return filesys, thy_level
def fake_species_block(spc_dct_i, spc_dct_j, spc_info_i, spc_info_j, spc_model, pf_levels, save_prefix_i, save_prefix_j): """ prepare a fake species block corresponding to the van der Waals well between two fragments """ [_, _, harm_level, _, sym_level, tors_level] = pf_levels tors_model, vib_model, sym_model = spc_model # prepare the four sets of file systems orb_restr = fsorb.orbital_restriction(spc_info_i, harm_level) har_levelp_i = harm_level[0:3] har_levelp_i.append(orb_restr) orb_restr = fsorb.orbital_restriction(spc_info_j, harm_level) har_levelp_j = harm_level[0:3] har_levelp_j.append(orb_restr) # Set theory filesystem used throughout thy_save_fs_i = autofile.fs.theory(save_prefix_i) thy_save_fs_j = autofile.fs.theory(save_prefix_j) # Set the filesystem objects for the two species harmfs_i = set_model_filesys(thy_save_fs_i, spc_info_i, harm_level, saddle=False) harmfs_j = set_model_filesys(thy_save_fs_j, spc_info_j, harm_level, saddle=False) [harm_cnf_save_fs_i, _, harm_min_cnf_locs_i, _] = harmfs_i [harm_cnf_save_fs_j, _, harm_min_cnf_locs_j, _] = harmfs_j if sym_level: symfs_i = set_model_filesys(thy_save_fs_i, spc_info_i, sym_level, saddle=False) symfs_j = set_model_filesys(thy_save_fs_j, spc_info_j, sym_level, saddle=False) [sym_cnf_save_fs_i, _, sym_min_cnf_locs_i, _] = symfs_i [sym_cnf_save_fs_j, _, sym_min_cnf_locs_j, _] = symfs_j if tors_level: torsfs_i = set_model_filesys(thy_save_fs_i, spc_info_i, tors_level[0], saddle=False) torsfs_j = set_model_filesys(thy_save_fs_j, spc_info_j, tors_level[0], saddle=False) [ tors_cnf_save_fs_i, tors_cnf_save_path_i, tors_min_cnf_locs_i, tors_save_path_i ] = torsfs_i [ tors_cnf_save_fs_j, tors_cnf_save_path_j, tors_min_cnf_locs_j, tors_save_path_j ] = torsfs_j spc_str = '' # Get the combined electronic energy levels elec_levels = messfutil.combine_elec_levels(spc_dct_i, spc_dct_j) # Determine the species symmetry factor using the given model saddle = False dist_names = [] tors_names = [] frm_bnd_key = [] brk_bnd_key = [] sym_factor_i = sym.symmetry_factor(sym_model, spc_dct_i, spc_info_i, dist_names, saddle, frm_bnd_key, brk_bnd_key, tors_names, tors_cnf_save_fs_i, tors_min_cnf_locs_i, sym_cnf_save_fs_i, sym_min_cnf_locs_i) sym_factor_j = sym.symmetry_factor(sym_model, spc_dct_j, spc_info_j, dist_names, saddle, frm_bnd_key, brk_bnd_key, tors_names, tors_cnf_save_fs_j, tors_min_cnf_locs_j, sym_cnf_save_fs_j, sym_min_cnf_locs_j) sym_factor = sym_factor_i * sym_factor_j # Get the freqs freqs = pfmodels.set_fake_freqs(harm_min_cnf_locs_i, harm_min_cnf_locs_j, harm_cnf_save_fs_i, harm_cnf_save_fs_j) geo = pfmodels.combine_geos_in_fake_well(harm_min_cnf_locs_i, harm_min_cnf_locs_j, harm_cnf_save_fs_i, harm_cnf_save_fs_j) if vib_model == 'harm' and tors_model == 'rigid': _, freqs_i, _ = pfmodels.vib_harm_tors_rigid(spc_info_i, harm_min_cnf_locs_i, harm_cnf_save_fs_i, saddle=saddle) _, freqs_j, _ = pfmodels.vib_harm_tors_rigid(spc_info_j, harm_min_cnf_locs_j, harm_cnf_save_fs_j, saddle=saddle) freqs += freqs_i + freqs_j hind_rot_str = "" if vib_model == 'harm' and tors_model == '1dhr': if messfutil.is_atom(harm_min_cnf_locs_i, harm_cnf_save_fs_i): freqs_i = [] hr_str_i = '' symf_i = sym_factor_i else: _, freqs_i, _, hr_str_i, _ = pfmodels.vib_harm_tors_1dhr( harm_min_cnf_locs_i, harm_cnf_save_fs_i, tors_min_cnf_locs_i, tors_cnf_save_fs_i, tors_save_path_i, tors_cnf_save_path_i, spc_dct_i, spc_info_i, frm_bnd_key, brk_bnd_key, sym_factor_i, elec_levels, saddle=False) if messfutil.is_atom(harm_min_cnf_locs_j, harm_cnf_save_fs_j): freqs_j = [] hr_str_j = '' symf_j = sym_factor_j else: _, freqs_j, _, hr_str_j, _ = pfmodels.vib_harm_tors_1dhr( harm_min_cnf_locs_j, harm_cnf_save_fs_j, tors_min_cnf_locs_j, tors_cnf_save_fs_j, tors_save_path_j, tors_cnf_save_path_j, spc_dct_j, spc_info_j, frm_bnd_key, brk_bnd_key, sym_factor_j, elec_levels, saddle=False) freqs += list(freqs_i) + list(freqs_j) hind_rot_str = hr_str_i + hr_str_j sym_factor = symf_i * symf_j core = mess_io.writer.core_rigidrotor(geo, sym_factor) spc_str = mess_io.writer.molecule(core, freqs, elec_levels, hind_rot=hind_rot_str) return spc_str
def vtst_with_no_saddle_block(ts_dct, ts_label, reac_label, prod_label, spc_ene, rct_zpe, projrot_script_str, multi_info): """ prepare the mess input string for a variational TS that does not have a saddle point. Do it by calling the species block for each grid point in the scan file system """ ts_info = ['', ts_dct['chg'], ts_dct['mul']] orb_restr = fsorb.orbital_restriction(ts_info, multi_info) multi_level = multi_info[0:3] multi_level.append(orb_restr) rxn_save_path = ts_dct['rxn_fs'][3] thy_save_fs = autofile.fs.theory(rxn_save_path) thy_save_fs.leaf.create(multi_level[1:4]) thy_save_path = thy_save_fs.leaf.path(multi_level[1:4]) scn_save_fs = autofile.fs.scan(thy_save_path) # Read the scan save filesystem to get the molecular info sym_factor = 1. irc_pt_strs = [] proj_rotors_str = '' pot = [] elec_levels = [[0., ts_dct['mul']]] grid = ts_dct['grid'] grid = numpy.append(grid[0], grid[1]) dist_name = ts_dct['dist_info'][0] # Read the infinite separation energy inf_locs = [[dist_name], [1000.]] inf_sep_ene = scn_save_fs.leaf.file.energy.read(inf_locs) grid[::-1].sort() for idx, grid_val in enumerate(grid): # Set the filesystem locators for each grid point locs = [[dist_name], [grid_val]] # Get geometry, energy, and vibrational freqs if not scn_save_fs.leaf.file.geometry.exists(locs): continue else: geom = scn_save_fs.leaf.file.geometry.read(locs) if not scn_save_fs.leaf.file.energy.exists(locs): continue else: ene = scn_save_fs.leaf.file.energy.read(locs) if not scn_save_fs.leaf.file.hessian.exists(locs): continue else: hess = scn_save_fs.leaf.file.hessian.read(locs) scn_save_path = scn_save_fs.leaf.path(locs) freqs, _, _ = pfmodels.projrot_freqs_1(geom, hess, pot, proj_rotors_str, projrot_script_str, scn_save_path, saddle=True) # Calculate standard harmonic ZPVE zpe = sum(freqs) * phycon.WAVEN2KCAL / 2. # Calcuate infinite separation ZPVE # Assumes the ZPVE = ZPVE(1st grid pt) as an approximation if idx == 0: rct_zpe = zpe # Calculate the reference energies erel = (ene - inf_sep_ene) * phycon.EH2KCAL erel_zpe_corr = erel + zpe - rct_zpe eref_abs = erel_zpe_corr + spc_ene # Iniialize the header of the string irc_pt_str = '!----------------------------------------------- \n' irc_pt_str += '! IRC Point {0}\n'.format(str(idx + 1)) # Write the MESS string for the molecule section for each irc point core = mess_io.writer.mol_data.core_rigidrotor(geom, sym_factor, interp_emax='') irc_pt_str += mess_io.writer.species.molecule(core, freqs, elec_levels, hind_rot='', xmat=None, rovib_coups='', rot_dists='') # Append the zero energy for the molecule irc_pt_str += (' ZeroEnergy[kcal/mol] ', '{0:<8.2f}\n'.format(eref_abs)) if grid_val != grid[-1]: irc_pt_str += 'End \n' # Append string to list irc_pt_strs.append(irc_pt_str) # Write the MESS string for the entire variational section variational_str = mess_io.writer.rxnchan.ts_variational( ts_label, reac_label, prod_label, irc_pt_strs) return variational_str
def infinite_separation_energy(spc_1_info, spc_2_info, ts_info, high_mul, ref_zma, ini_thy_info, thy_info, multi_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs, locs, overwrite=False, num_act_elc=None, num_act_orb=None): """ Obtain the infinite separation energy from the multireference energy at a given reference point, the high-spin low-spin splitting at that reference point, and the high level energy for the high spin state at the reference geometry and for the fragments """ # Initialize infinite sep energy inf_sep_ene = -1.0e12 # set up all the file systems for the TS # start with the geo and reference theory info geo_run_path = scn_run_fs.leaf.path(locs) geo_save_path = scn_save_fs.leaf.path(locs) geo = scn_save_fs.leaf.file.geometry.read(locs) sp_run_fs = autofile.fs.single_point(geo_run_path) sp_save_fs = autofile.fs.single_point(geo_save_path) # get the multi reference ene for low spin state for the ref point on scan # file system for low spin multireference calculation multi_info[0] = 'molpro2015' multi_info[1] = 'caspt2' # ultimately the above should be properly passed prog = multi_info[0] method = multi_info[1] # get the multi reference energy for high spin state for ref point on scan hs_info = (ts_info[0], ts_info[1], high_mul) orb_restr = fsorb.orbital_restriction(hs_info, multi_info) multi_lvl = multi_info[0:3] multi_lvl.append(orb_restr) hs_run_fs = autofile.fs.high_spin(geo_run_path) hs_save_fs = autofile.fs.high_spin(geo_save_path) hs_run_fs.leaf.create(multi_lvl[1:4]) hs_save_fs.leaf.create(multi_lvl[1:4]) hs_mr_run_path = hs_run_fs.leaf.path(multi_lvl[1:4]) hs_mr_save_path = hs_save_fs.leaf.path(multi_lvl[1:4]) run_mr_fs = autofile.fs.run(hs_mr_run_path) mr_script_str, _, mr_kwargs, _ = runpar.run_qchem_par(prog, method) if num_act_elc is None and num_act_orb is None: num_act_elc = high_mul num_act_orb = num_act_elc ts_formula = automol.geom.formula(automol.zmatrix.geometry(ref_zma)) cas_opt, _ = ts.cas_options_2(hs_info, ts_formula, num_act_elc, num_act_orb, high_mul) guess_str = ts.multiref_wavefunction_guess(high_mul, ref_zma, hs_info, multi_lvl, [cas_opt]) guess_lines = guess_str.splitlines() mr_kwargs['casscf_options'] = cas_opt mr_kwargs['mol_options'] = ['nosym'] mr_kwargs['gen_lines'] = {1: guess_lines} ret = driver.read_job( job='energy', run_fs=run_mr_fs, ) if ret: print(" - Reading high spin multi reference energy from output...") inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) hs_save_fs.leaf.file.energy.write(ene, multi_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4]) if not hs_save_fs.leaf.file.energy.exists(multi_lvl[1:4]) or overwrite: print(" - Running high spin multi reference energy ...") driver.run_job( job='energy', script_str=mr_script_str, run_fs=run_mr_fs, geom=geo, spc_info=hs_info, thy_level=multi_lvl, overwrite=overwrite, **mr_kwargs, ) ret = driver.read_job( job='energy', run_fs=run_mr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading high spin multi reference energy from output...") hs_mr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving high spin multi reference energy...") print(" - Save path: {}".format(hs_mr_save_path)) hs_save_fs.leaf.file.energy.write(hs_mr_ene, multi_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4]) else: print('ERROR: high spin multi reference energy job fails: ', 'Energy is needed to evaluate infinite separation energy') return inf_sep_ene else: hs_mr_ene = hs_save_fs.leaf.file.energy.read(multi_lvl[1:4]) # file system for high spin single ireference calculation thy_info = ['molpro2015', 'ccsd(t)-f12', 'cc-pvdz-f12', 'RR'] orb_restr = fsorb.orbital_restriction(hs_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) hs_run_fs.leaf.create(thy_lvl[1:4]) hs_save_fs.leaf.create(thy_lvl[1:4]) hs_sr_run_path = hs_run_fs.leaf.path(thy_lvl[1:4]) hs_sr_save_path = hs_save_fs.leaf.path(thy_lvl[1:4]) run_sr_fs = autofile.fs.run(hs_sr_run_path) sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_lvl[0:2]) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret: print(" - Reading high spin single reference energy from output...") inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) hs_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) if not hs_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite: print(" - Running high spin single reference energy ...") errors, options_mat = runpar.set_molpro_options_mat(hs_info, geo) driver.run_job( job='energy', script_str=sp_script_str, run_fs=run_sr_fs, geom=geo, spc_info=hs_info, thy_level=thy_lvl, errors=errors, options_mat=options_mat, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading high spin single ref energy from output...") hs_sr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving high spin single reference energy...") print(" - Save path: {}".format(hs_sr_save_path)) hs_save_fs.leaf.file.energy.write(hs_sr_ene, thy_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) else: print('ERROR: High spin single reference energy job fails: ', 'Energy is needed to evaluate infinite separation energy') return inf_sep_ene else: hs_sr_ene = hs_save_fs.leaf.file.energy.read(thy_lvl[1:4]) # get the single reference energy for each of the reactant configurations spc_ene = [] spc_infos = [spc_1_info, spc_2_info] for spc_info in spc_infos: # set up the file systems for the reactants one by one spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info) ini_thy_lvl = ini_thy_info[0:3] ini_thy_lvl.append(orb_restr) orb_restr = fsorb.orbital_restriction(spc_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) ini_thy_run_fs = autofile.fs.theory(spc_run_path) ini_thy_run_fs.leaf.create(ini_thy_lvl[1:4]) ini_thy_run_path = ini_thy_run_fs.leaf.path(ini_thy_lvl[1:4]) ini_thy_save_fs = autofile.fs.theory(spc_save_path) ini_thy_save_fs.leaf.create(ini_thy_lvl[1:4]) ini_thy_save_path = ini_thy_save_fs.leaf.path(ini_thy_lvl[1:4]) ini_cnf_run_fs = autofile.fs.conformer(ini_thy_run_path) ini_cnf_save_fs = autofile.fs.conformer(ini_thy_save_path) min_cnf_locs = fsmin.min_energy_conformer_locators(ini_cnf_save_fs) min_cnf_run_path = ini_cnf_run_fs.leaf.path(min_cnf_locs) min_cnf_save_path = ini_cnf_save_fs.leaf.path(min_cnf_locs) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_lvl[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(thy_lvl[1:4]) geo = ini_cnf_save_fs.leaf.file.geometry.read(min_cnf_locs) sp_run_fs = autofile.fs.single_point(min_cnf_run_path) sp_run_fs.leaf.create(thy_lvl[1:4]) sp_save_fs = autofile.fs.single_point(min_cnf_save_path) sp_save_fs.leaf.create(thy_lvl[1:4]) sp_sr_run_path = sp_run_fs.leaf.path(thy_lvl[1:4]) sp_sr_save_path = sp_save_fs.leaf.path(thy_lvl[1:4]) print('sp_sr_run_path') print(sp_sr_run_path) run_sr_fs = autofile.fs.run(sp_sr_run_path) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret: print(" - Reading single reference energy for", "{} from output...".format(spc_info[0])) inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) sp_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4]) sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) if not sp_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite: print(" - Running single reference energy for", "{} from output...".format(spc_info[0])) driver.run_job( job='energy', script_str=sp_script_str, run_fs=run_sr_fs, geom=geo, spc_info=spc_info, thy_level=thy_lvl, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading single reference energy for ", "{} from output...".format(spc_info[0])) sp_sr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving single reference energy for ", "{} from output...".format(spc_info[0])) print(" - Save path: {}".format(sp_sr_save_path)) sp_save_fs.leaf.file.energy.write(sp_sr_ene, thy_lvl[1:4]) sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) else: print('ERROR: Single reference energy job fails', 'for {}: '.format(spc_info[0]), 'Energy needed to evaluate infinite separation energy') return inf_sep_ene else: sp_sr_ene = sp_save_fs.leaf.file.energy.read(thy_lvl[1:4]) spc_ene.append(sp_sr_ene) inf_sep_ene = spc_ene[0] + spc_ene[1] - hs_sr_ene + hs_mr_ene return inf_sep_ene
def find_vdw(ts_name, spc_dct, thy_info, ini_thy_info, vdw_params, nsamp_par, run_prefix, save_prefix, kickoff_size, kickoff_backward, overwrite): """ Find van der Waals structures for all the pairs of species in a reaction list """ projrot_script_str = script.PROJROT new_vdws = [] _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(*thy_info[:2]) mul = spc_dct[ts_name]['low_mul'] vdw_names_lst = [] if vdw_params[0]: vdw_names_lst.append([sorted(spc_dct[ts_name]['reacs']), mul, 'r']) if vdw_params[1]: vdw_names_lst.append([sorted(spc_dct[ts_name]['prods']), mul, 'p']) for names, ts_mul, label in vdw_names_lst: if len(names) < 2: print('Cannot find van der Waals well for unimolecular', 'reactant or product') ichs = list(map(lambda name: spc_dct[name]['ich'], names)) chgs = list(map(lambda name: spc_dct[name]['chg'], names)) muls = list(map(lambda name: spc_dct[name]['mul'], names)) # theory prog = thy_info[0] method = thy_info[1] _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(prog, method) geos = [(), ()] ntaudof = 0. for i, (nam, ich, chg, mul) in enumerate(zip(names, ichs, chgs, muls)): spc_info = [ich, chg, mul] orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info) ini_thy_level = ini_thy_info[0:3] ini_thy_level.append(orb_restr) orb_restr = fsorb.orbital_restriction(spc_info, thy_info) thy_level = thy_info[0:3] thy_level.append(orb_restr) spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(thy_level[1:4]) thy_save_path = thy_save_fs.leaf.path(thy_level[1:4]) run_fs = autofile.fs.run(thy_run_path) ini_thy_save_fs = autofile.fs.theory(spc_save_path) ini_thy_save_fs.leaf.create(ini_thy_level[1:4]) cnf_run_fs = autofile.fs.conformer(thy_run_path) cnf_save_fs = autofile.fs.conformer(thy_save_path) ini_filesys = [None, ini_thy_save_fs] filesys = [ spc_run_fs, spc_save_fs, thy_run_fs, thy_save_fs, cnf_run_fs, cnf_save_fs, None, None, None, None, run_fs ] geo = geom.reference_geometry( spc_dct[nam], thy_level, ini_thy_level, filesys, ini_filesys, kickoff_size=kickoff_size, kickoff_backward=kickoff_backward, projrot_script_str=projrot_script_str, overwrite=overwrite) geos[i] = geo gra = automol.geom.graph(geo) ntaudof += len( automol.graph.rotational_bond_keys(gra, with_h_rotors=False)) nsamp = util.nsamp_init(nsamp_par, ntaudof) geo1, geo2 = geos geo1 = automol.geom.mass_centered(geo1) geo2 = automol.geom.mass_centered(geo2) min_ene = 0. for idx in range(int(nsamp)): print('Optimizing vdw geometry {}/{}'.format(idx + 1, nsamp)) angs1 = numpy.multiply(numpy.random.rand(3), [1 * numpy.pi, 2 * numpy.pi, 2 * numpy.pi]) angs2 = numpy.multiply(numpy.random.rand(3), [1 * numpy.pi, 2 * numpy.pi, 2 * numpy.pi]) angs12 = numpy.multiply(numpy.random.rand(2), [1 * numpy.pi, 2 * numpy.pi]) geo1 = automol.geom.euler_rotated(geo1, *angs1) geo2 = automol.geom.euler_rotated(geo2, *angs2) dist_cutoff = 3.0 * phycon.ANG2BOHR geo = automol.geom.join(geo1, geo2, dist_cutoff, *angs12) print("Species: {}".format('+'.join(names))) print('vdw starting geometry') print(automol.geom.xyz_string(geo)) # Set up the filesystem ich = automol.inchi.recalculate(automol.inchi.join(ichs)) chg = sum(chgs) mul = ts_mul spc_info = (ich, chg, mul) spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) orb_restr = fsorb.orbital_restriction(spc_info, thy_info) thy_level = thy_info[0:3] thy_level.append(orb_restr) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(thy_level[1:4]) thy_save_path = thy_save_fs.leaf.path(thy_level[1:4]) run_fs = autofile.fs.run(thy_run_path) # Generate reference geometry # Generate the z-matrix and sampling ranges driver.run_job( job=elstruct.Job.OPTIMIZATION, geom=geo, spc_info=spc_info, thy_level=thy_level, run_fs=run_fs, script_str=opt_script_str, overwrite=overwrite, **opt_kwargs, ) # Save info for the initial geometry (from ichi or fsave dir) ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if ret: print('Saving reference geometry') print(" - Save path: {}".format(thy_save_path)) inf_obj, inp_str, out_str = ret prog = inf_obj.prog method = inf_obj.method geo = elstruct.reader.opt_geometry(prog, out_str) print('vdw ending geometry') print(automol.geom.xyz_string(geo)) thy_save_fs.leaf.file.geometry.write(geo, thy_level[1:4]) ene = elstruct.reader.energy(prog, method, out_str) if ene < min_ene: min_ene = ene print('ene test in vdw') print(ene) thy_save_fs.leaf.file.energy.write(ene, thy_level[1:4]) print('Saving reference geometry') print(" - Save path: {}".format(thy_save_path)) vdw_name = label + ts_name.replace('ts', 'vdw') spc_dct[vdw_name] = spc_dct[ts_name].copy() spc_dct[vdw_name]['ich'] = ich spc_dct[vdw_name]['mul'] = mul spc_dct[vdw_name]['chg'] = chg spc_dct[vdw_name]['dist_info'][1] = dist_cutoff # Make a fake conformer cnf_save_fs = autofile.fs.conformer(thy_save_path) cnf_run_fs = autofile.fs.conformer(thy_run_path) cnf_save_fs.trunk.create() cnf_run_fs.trunk.create() tors_range_dct = {} cinf_obj = autofile.system.info.conformer_trunk( 0, tors_range_dct) cinf_obj.nsamp = 1 cnf_save_fs.trunk.file.info.write(cinf_obj) locs_lst = cnf_save_fs.leaf.existing() if not locs_lst: cid = autofile.system.generate_new_conformer_id() locs = [cid] else: locs = locs_lst[0] cnf_save_fs.leaf.create(locs) cnf_run_fs.leaf.create(locs) cnf_save_fs.leaf.file.geometry_info.write(inf_obj, locs) cnf_save_fs.leaf.file.geometry_input.write(inp_str, locs) cnf_save_fs.leaf.file.energy.write(ene, locs) cnf_save_fs.leaf.file.geometry.write(geo, locs) if min_ene: new_vdws.append(vdw_name) return new_vdws