def ts_dct_from_estsks(pes_idx, es_tsk_lst, rxn_lst, thy_dct, spc_dct, run_prefix, save_prefix): """ build a ts queue """ print('\nTasks for transition states requested...') print('Identifying reaction classes for transition states...') # Build the ts_dct ts_dct = {} for tsk_lst in es_tsk_lst: obj, es_keyword_dct = tsk_lst[:-1], tsk_lst[-1] if 'ts' in obj: 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) break ts_dct = {} for rxn in rxn_lst: ts_dct.update( ts_dct_sing_chnl( pes_idx, rxn, spc_dct, run_prefix, save_prefix, thy_info=thy_info, ini_thy_info=ini_thy_info) ) # Build the queue ts_queue = tuple(sadpt for sadpt in ts_dct) if ts_dct else () return ts_dct, ts_queue
def _format_lvl(lvl_val): """ format weird energy calls """ if isinstance(lvl_val, str): val_inf = (1.00, tinfo.from_dct(thy_dct.get(lvl_val))) else: val_inf = (lvl_val[0], tinfo.from_dct(thy_dct.get(lvl_val))) return val_inf
def geom_init(spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ Execute the task for a species used to seed the filesystem with a reliable initial conformer. :param spc_dct: :type spc_dct: :param spc_name: name of species :type spc_name: str :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] spc_info = sinfo.from_dct(spc_dct_i) # Get the theory info 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 _, ini_cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', spc_locs=spc_info, thy_locs=mod_ini_thy_info[1:]) cnf_run_fs, cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', spc_locs=spc_info, thy_locs=mod_thy_info[1:]) # Get a reference geometry if one not found success = conformer.initial_conformer(spc_dct_i, spc_info, ini_method_dct, method_dct, ini_cnf_save_fs, cnf_run_fs, cnf_save_fs, es_keyword_dct) return success
def geom_init(spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ Find the initial geometry """ spc_dct_i = spc_dct[spc_name] spc_info = sinfo.from_dct(spc_dct_i) # Get the theory info 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 _, ini_cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', spc_locs=spc_info, thy_locs=mod_ini_thy_info[1:]) cnf_run_fs, cnf_save_fs = build_fs(run_prefix, save_prefix, 'CONFORMER', spc_locs=spc_info, thy_locs=mod_thy_info[1:]) # _, ini_cnf_save_fs = build_fs( # run_prefix, save_prefix, 'CONFORMER', # spc_locs=spc_info, thy_locs=mod_ini_thy_info[1:]) # cnf_run_fs, cnf_save_fs = build_fs( # run_prefix, save_prefix, 'CONFORMER', # spc_locs=spc_info, thy_locs=mod_thy_info[1:]) _, instab_save_fs = build_fs(run_prefix, save_prefix, 'INSTAB', spc_locs=spc_info, thy_locs=mod_thy_info[1:]) # Get a reference geometry if one not found success = conformer.initial_conformer(spc_dct_i, spc_info, ini_method_dct, method_dct, ini_cnf_save_fs, cnf_run_fs, cnf_save_fs, instab_save_fs, es_keyword_dct) return success
def parse_user_theory(insert_dct): # Get input method explicitly inputted program = insert_dct['program'] method = insert_dct['method'] basis = insert_dct['basis'] orb_res = insert_dct['orb_res'] # Get input method from theory dictionary theory = insert_dct['theory'] if theory is None: if program is None: print('Error: user did not specify program in input') sys.exit() elif method is None: print('Error: user did not specify method in input') sys.exit() elif basis is None: print('Error: user did not specify basis in input') sys.exit() elif orb_res is None: print('Error: user did not specify orb_res in input') sys.exit() else: thy_info = (program, method, basis, orb_res) else: if theory in THEORY_DCT: thy_info = tinfo.from_dct(THEORY_DCT[theory]) else: print( 'Error: user did not specify a theory {}'.format(theory) + ' that is in the THEORY_DCT' + 'please add it to the dct in the script or use program/method/basis/orb_dct' + 'keywords instead of theory') sys.exit() return thy_info
def _set_sort_info_lst(sort_str, thy_dct, spc_info): """ Return the levels to sort conformers by if zpve or sp levels were assigned in input if we ask for zpe(lvl_wbs),sp(lvl_b2t),gibbs(700) out sort_info_lst will be [('gaussian', 'wb97xd', '6-31*', 'RU'), ('gaussian', 'b2plypd3', 'cc-pvtz', 'RU'), None, None, 700.] """ sort_lvls = [None, None, None, None, None] sort_typ_lst = ['freqs', 'sp', 'enthalpy', 'entropy', 'gibbs'] if sort_str is not None: for sort_param in sort_str.split(','): idx = None for typ_idx, typ_str in enumerate(sort_typ_lst): if typ_str in sort_param: lvl_key = sort_str.split(typ_str + '(')[1].split(')')[0] idx = typ_idx if idx is not None: if idx < 2: method_dct = thy_dct.get(lvl_key) if method_dct is None: ioprinter.warning_message( f'no {lvl_key} in theory.dat, ' f'not using {sort_typ_lst[idx]} in sorting') continue thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) sort_lvls[idx] = mod_thy_info else: sort_lvls[idx] = float(lvl_key) return sort_lvls
def rcts_cnf_fs(rct_infos, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ set reactant filesystem stuff """ ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) ini_thy_info = tinfo.from_dct(ini_method_dct) rct_cnf_fs = () for rct_info in rct_infos: mod_ini_thy_info = tinfo.modify_orb_label(ini_thy_info, rct_info) # Build filesys for ini thy info ini_cnf_run_fs, ini_cnf_save_fs = build_fs( run_prefix, save_prefix, 'CONFORMER', spc_locs=rct_info, thy_locs=mod_ini_thy_info[1:]) ini_loc_info = min_energy_conformer_locators(ini_cnf_save_fs, mod_ini_thy_info) ini_min_cnf_locs, ini_min_cnf_path = ini_loc_info # Create run fs if that directory has been deleted to run the jobs ini_cnf_run_fs[-1].create(ini_min_cnf_locs) rct_cnf_fs += ((ini_cnf_run_fs, ini_cnf_save_fs, ini_min_cnf_locs, ini_min_cnf_path), ) return rct_cnf_fs
def _optimize_atom(spc_info, zma_init, method_dct, cnf_save_fs, locs, run_fs, overwrite): """ Deal with an atom separately """ thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) script_str, kwargs = es_runner.qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) # Call the electronic structure optimizer success, ret = es_runner.execute_job(job=elstruct.Job.ENERGY, script_str=script_str, run_fs=run_fs, geo=zma_init, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs) if success: ioprinter.info_message('Succesful reference geometry optimization') filesys.save.atom(ret, cnf_save_fs, mod_thy_info[1:], zma_init, rng_locs=(locs[0], ), tors_locs=(locs[1], )) return success
def conformer_list(spc_name, print_keyword_dct, save_prefix, run_prefix, spc_dct_i, thy_dct): """ Create a list of conformers based on the species name and run.dat geolvl/proplvl """ # conformer range cnf_range = _set_conf_range(print_keyword_dct) hbond_cutoffs = spc_dct_i['hbond_cutoffs'] # thy_info build thy_info = tinfo.from_dct(thy_dct.get(print_keyword_dct.get('geolvl'))) spc_info = sinfo.from_dct(spc_dct_i) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) sort_info_lst = _set_sort_info_lst(print_keyword_dct['sort'], thy_dct, spc_info) zrxn = spc_dct_i.get('zrxn', None) _root = filesys.root_locs(spc_dct_i, saddle=(zrxn is not None), name=spc_name) _, cnf_save_fs = filesys.build_fs(run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_thy_info[1:], **_root) rng_cnf_locs_lst, rng_cnf_locs_path = filesys.mincnf.conformer_locators( cnf_save_fs, mod_thy_info, cnf_range=cnf_range, sort_info_lst=sort_info_lst, hbond_cutoffs=hbond_cutoffs, print_enes=True) return cnf_save_fs, rng_cnf_locs_lst, rng_cnf_locs_path, mod_thy_info
def remove_unstable(spc_queue, spc_dct, thy_dct, spc_mod_dct_i, proc_key_dct, save_prefix): """ For each species in the queue see if there are files in the save filesystem denoting they are unstable. If so, that species is removed from the queue for collection tasks. """ ioprinter.info_message( 'Removing unstable species with instab.yaml file in SAVE filesystem', 'from queue...\n') if spc_mod_dct_i is not None: thy_info = spc_mod_dct_i['vib']['geolvl'][1][1] else: thy_info = tinfo.from_dct(thy_dct.get(proc_key_dct['proplvl'])) stable_queue = () for spc_name in spc_queue: if 'ts_' in spc_name: stable_queue += (spc_name, ) else: instab, path = filesys.read.instability_transformation( spc_dct, spc_name, thy_info, save_prefix) if instab is None: stable_queue += (spc_name, ) else: ioprinter.info_message( f'Found instability file at path {path}', newline=1) ioprinter.info_message(f'Removing {spc_name} from queue') return stable_queue
def generate_spc_model_dct(es_levels, thy_dct): """ Make a specie smodel dct to pass to pf_filesystems function """ spc_model_dct_i = {} for prop in es_levels: spc_model_dct_i[prop] = { 'geolvl': (es_levels['geo'], (1.00, tinfo.from_dct(thy_dct.get(es_levels['geo'])))) } if prop == 'vib': spc_model_dct_i[prop]['mod'] = 'harm' elif prop == 'ene': spc_model_dct_i[prop]['lvl1'] = (es_levels['ene'], (1.00, tinfo.from_dct( thy_dct.get( es_levels['ene'])))) return spc_model_dct_i
def ts_dct_from_estsks(pes_idx, es_tsk_lst, rxn_lst, thy_dct, spc_dct, run_prefix, save_prefix): """ build a ts queue """ print('\nTasks for transition states requested...') print('Identifying reaction classes for transition states...') # Build the ts_dct ts_dct = {} for tsk_lst in es_tsk_lst: obj, es_keyword_dct = tsk_lst[0], tsk_lst[-1] if obj in ('ts', 'all'): # want print for task list 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) break # Discern if TS should be reidentified re_id = False for tsk_lst in es_tsk_lst: obj, es_keyword_dct = tsk_lst[:-1], tsk_lst[-1] if 'find_ts' in obj: re_id = es_keyword_dct.get('re_id', False) ts_dct = {} for rxn in rxn_lst: ts_dct.update( ts_dct_sing_chnl(pes_idx, rxn, spc_dct, run_prefix, save_prefix, thy_info=thy_info, ini_thy_info=ini_thy_info, re_id=re_id)) # Build the queue # ts_queue = tuple(sadpt for sadpt in ts_dct) if ts_dct else () return ts_dct
def skip_task(tsk, spc_dct, spc_name, thy_dct, es_keyword_dct, save_prefix): """ Determine if an electronic structure task should be skipped based on various parameters. :param spc_dct: species dictionary :type spc_dct: dictionary :param spc_name: name of species :type spc_name: string :rtype: bool """ # Initialize skip to be false skip = False # Set theory info needed to find information ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) ini_thy_info = tinfo.from_dct(ini_method_dct) # Perform checks if 'ts' in spc_name: # Skip all tasks except find_ts # if rad-rad TS if tsk not in ('find_ts', 'rpath_scan'): # generalize to other rpath rxn_info = spc_dct[spc_name]['rxn_info'] ts_mul = rinfo.value(rxn_info, 'tsmult') high_ts_mul = rinfo.ts_mult(rxn_info, rxn_mul='high') if rinfo.radrad(rxn_info) and ts_mul != high_ts_mul: skip = True ioprinter.info_message( f'Skipping task because {spc_name}', 'is a low-spin radical radical reaction') else: spc_natoms = len(automol.inchi.geometry(spc_dct[spc_name]['inchi'])) if spc_natoms == 1: # Skip all tasks except init_geom and conf_energy # if species is an atom if tsk not in ('init_geom', 'conf_energy'): skip = True ioprinter.info_message('Skipping task for an atom...', newline=1) else: # Skip all tasks except ini_geom # if (non-TS) species is unstable (zrxn found (i.e. is not None)) if tsk != 'init_geom': instab, path = filesys.read.instability_transformation( spc_dct, spc_name, ini_thy_info, save_prefix) skip = (instab is not None) if skip: ioprinter.info_message( f'Found instability file at path {path}', newline=1) ioprinter.info_message( 'Skipping task for unstable species...', newline=1) return skip
def remove_imag(geo, ini_ret, spc_info, method_dct, run_fs, kickoff_size=0.1, kickoff_backward=False, kickoff_mode=0, overwrite=False): """ if there is an imaginary frequency displace geometry along the imaginary mode and then reoptimize """ thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) opt_script_str, opt_kwargs = qchem_params( method_dct, job=elstruct.Job.OPTIMIZATION) script_str, kwargs = qchem_params( method_dct) ioprinter.info_message( 'The initial geometries will be checked for imaginary frequencies') imag, norm_coords = _check_imaginary( spc_info, geo, mod_thy_info, run_fs, script_str, overwrite, **kwargs) # Make five attempts to remove imag mode if found chk_idx = 0 kick_ret = None while imag and chk_idx < 5: chk_idx += 1 ioprinter.info_message( 'Attempting kick off along mode, attempt {}...'.format(chk_idx)) geo, kick_ret = _kickoff_saddle( geo, norm_coords, spc_info, mod_thy_info, run_fs, opt_script_str, kickoff_size, kickoff_backward, kickoff_mode, opt_cart=True, **opt_kwargs) ioprinter.info_message( 'Removing faulty geometry from filesystem. Rerunning Hessian...') run_fs[-1].remove([elstruct.Job.HESSIAN]) ioprinter.info_message('Rerunning Hessian...') imag, norm_coords = _check_imaginary( spc_info, geo, mod_thy_info, run_fs, script_str, overwrite, **kwargs) # Update kickoff size kickoff_size *= 2.0 if kick_ret is None: ret = ini_ret else: ret = kick_ret return geo, ret
def ts_dct_from_proctsks(pes_idx, proc_tsk_lst, rxn_lst, spc_mod_dct_i, thy_dct, spc_dct, run_prefix, save_prefix): """ build a ts queue """ print('\nTasks for transition states requested...') print('Identifying reaction classes for transition states...') # Build the ts_dct ts_dct = {} for tsk_lst in proc_tsk_lst: obj, proc_keyword_dct = tsk_lst[:-1], tsk_lst[-1] if 'ts' in obj or 'all' in obj: # want print for task list if spc_mod_dct_i is not None: ini_thy_info = spc_mod_dct_i['vib']['geolvl'][1][1] thy_info = spc_mod_dct_i['vib']['geolvl'][1][1] else: ini_thy_info = tinfo.from_dct( thy_dct.get(proc_keyword_dct['geolvl'])) thy_info = tinfo.from_dct( thy_dct.get(proc_keyword_dct['proplvl'])) break ts_dct = {} for rxn in rxn_lst: ts_dct.update( ts_dct_sing_chnl(pes_idx, rxn, spc_dct, run_prefix, save_prefix, thy_info=thy_info, ini_thy_info=ini_thy_info, id_missing=False)) # Build the queue ts_queue = tuple(sadpt for sadpt in ts_dct) if ts_dct else () return ts_dct, ts_queue
def run_tsk(tsk, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ run an electronic structure task for generating a list of conformer or tau sampling geometries """ # Print the head of the task ioprinter.task_header(tsk, spc_name) ioprinter.keyword_list(es_keyword_dct, thy_dct) # If species is unstable, set task to 'none' ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) ini_thy_info = tinfo.from_dct(ini_method_dct) stable = True if 'ts' not in spc_name and tsk != 'init_geom': zrxn, path = filesys.read.instability_transformation( spc_dct, spc_name, ini_thy_info, save_prefix) stable = bool(zrxn is None) if stable: ioprinter.debug_message('- Proceeding with requested task...') # Get stuff from task job = tsk.split('_', 1)[1] # Run the task if an initial geom exists if 'init' in tsk and not skip_task(spc_dct, spc_name): _ = geom_init(spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'conf' in tsk and not skip_task(spc_dct, spc_name): conformer_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'tau' in tsk and not skip_task(spc_dct, spc_name): tau_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'hr' in tsk and not skip_task(spc_dct, spc_name): hr_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'rpath' in tsk and not skip_task(spc_dct, spc_name): pass elif 'irc' in tsk and not skip_task(spc_dct, spc_name): irc_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'find' in tsk: findts(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) else: ioprinter.info_message('Skipping task for unstable species...', newline=1)
def saddle_point_hessian(opt_ret, ts_info, method_dct, run_fs, run_prefix, overwrite): """ run things for checking Hessian """ mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) script_str, kwargs = qchem_params(method_dct) # Obtain geometry from optimization opt_inf_obj, _, opt_out_str = opt_ret opt_prog = opt_inf_obj.prog geo = elstruct.reader.opt_geometry(opt_prog, opt_out_str) # Run a Hessian hess_success, hess_ret = es_runner.execute_job( job='hessian', script_str=script_str, run_fs=run_fs, geo=geo, spc_info=ts_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs, ) # If successful, Read the geom and energy from the optimization if hess_success: hess_inf_obj, _, hess_out_str = hess_ret hess = elstruct.reader.hessian(hess_inf_obj.prog, hess_out_str) fml_str = automol.geom.formula_string(geo) vib_path = job_path(run_prefix, 'PROJROT', 'FREQ', fml_str) run_fs[-1].create(['hessian']) script_str = autorun.SCRIPT_DCT['projrot'] freqs, _, imags, _ = autorun.projrot.frequencies( script_str, vib_path, [geo], [[]], [hess]) else: freqs, imags = [], [] return hess_ret, freqs, imags
def save_saddle_point(opt_ret, hess_ret, ts_dct, method_dct, savefs_dct, cnf_locs): """ Given the saddle point guess structure, obtain a proper saddle point """ # Pull info from the dictionaries to save zrxn = ts_dct['zrxn'] runlvl_cnf_save_fs, _ = savefs_dct['runlvl_cnf_tuple'] ts_info = rinfo.ts_info(ts_dct['rxn_info']) mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) # Save initial saddle point conformer filesys.save.conformer(opt_ret, hess_ret, runlvl_cnf_save_fs, mod_thy_info[1:], zrxn=zrxn, rng_locs=(cnf_locs[0], ), tors_locs=(cnf_locs[1], ), zma_locs=None)
def conformer_list(print_keyword_dct, save_prefix, run_prefix, spc_dct_i, thy_dct): """ Create a list of conformers based on the species name and run.dat geolvl/proplvl """ # conformer range cnf_range = _set_conf_range(print_keyword_dct) # thy_info build thy_info = tinfo.from_dct(thy_dct.get(print_keyword_dct.get('geolvl'))) spc_info = sinfo.from_dct(spc_dct_i) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) _root = filesys.root_locs(spc_dct_i, saddle=False) _, cnf_save_fs = filesys.build_fs(run_prefix, save_prefix, 'CONFORMER', thy_locs=mod_thy_info[1:], **_root) rng_cnf_locs_lst, rng_cnf_locs_path = filesys.mincnf.conformer_locators( cnf_save_fs, mod_thy_info, cnf_range=cnf_range) return cnf_save_fs, rng_cnf_locs_lst, rng_cnf_locs_path
def energy(spc_name, spc_dct_i, spc_mod_dct_i, proc_keyword_dct, thy_dct, locs, locs_path, cnf_fs, run_prefix, save_prefix): """ collect energy """ saddle = 'ts_' in spc_name _ene = None if spc_mod_dct_i: pf_filesystems = filesys.models.pf_filesys(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, name=spc_name, saddle=saddle) _ene = 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) # 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) _ene = sp_save_fs[-1].file.energy.read(mod_thy_info[1:4]) if _ene is not None: miss_data = None else: miss_data = (spc_name + '_'.join(locs), mod_thy_info, 'energy') return [locs_path, _ene], miss_data
def obtain_saddle_point(guess_zmas, ts_dct, method_dct, runfs_dct, savefs_dct, es_keyword_dct): """ Given the saddle point guess structure, obtain a proper saddle point """ # Get info (move later) ts_info = rinfo.ts_info(ts_dct['rxn_info']) mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) overwrite = es_keyword_dct['overwrite'] ts_info = rinfo.ts_info(ts_dct['rxn_info']) zrxn = ts_dct['zrxn'] # runlvl_cnf_run_fs = runfs_dct['runlvl_cnf_fs'] # cid = [autofile.schema.generate_new_conformer_id()] # run_fs = autofile.fs.run(runlvl_cnf_run_fs[-1].path(cid)) run_prefix = runfs_dct['prefix'] runlvl_cnf_run_fs = runfs_dct['runlvl_cnf_fs'] rid = autofile.schema.generate_new_ring_id() cid = autofile.schema.generate_new_conformer_id() locs = (rid, cid) runlvl_cnf_run_fs[-1].create(locs) run_fs = autofile.fs.run(runlvl_cnf_run_fs[-1].path(locs)) # Optimize the saddle point script_str, kwargs = qchem_params(method_dct) opt_ret = optimize_saddle_point(guess_zmas, ts_info, mod_thy_info, run_fs, script_str, overwrite, **kwargs) # Calculate the Hessian for the optimized structure if opt_ret is not None: # Get the Hessian and check the saddle point # (maybe just have remove imag do this?) hess_ret, _, imags = saddle_point_hessian(opt_ret, ts_info, method_dct, run_fs, run_prefix, overwrite) sadpt_status = saddle_point_checker(imags) # ted_status = ted_coordinate_check(opt_ret, hess_ret, ts_dct, run_fs) # remove ted_status check for now since it was crashing # ted_status = True # Assess saddle point, save it if viable # if sadpt_status == 'kickoff': # opt_inf_obj, _, opt_out_str = opt_ret # opt_prog = opt_inf_obj.prog # geo = elstruct.reader.opt_geometry(opt_prog, opt_out_str) # # Need to return an opt_ret # geo, _ = geom.remove_imag( # geo, ts_info, mod_thy_info, ts_run_fs, run_fs, # kickoff_size=0.1, kickoff_backward=False, kickoff_mode=1, # overwrite=False) # sadpt_status = saddle_point_checker(imags) if sadpt_status == 'success': runlvl_cnf_save_fs, _ = savefs_dct['runlvl_cnf_fs'] filesys.save.conformer(opt_ret, hess_ret, runlvl_cnf_save_fs, mod_thy_info[1:], zrxn=zrxn, rng_locs=(rid, ), tors_locs=(cid, ), zma_locs=None) else: ioprinter.warning_message( '\n TS optimization failed. No geom to check and save.')
def initial_conformer(spc_dct_i, spc_info, ini_method_dct, method_dct, ini_cnf_save_fs, cnf_run_fs, cnf_save_fs, es_keyword_dct): """ Assess if a conformer layer with a geometry exists in the save filesys for the given species. If not, attempt to generate some guess structure using InChI strings or input geom from user. and optimize it with input method. Then assess if the optimized structure corresponds to genuine minimum on the PES via a frequency calculation. If a minimum is found, save the conformer geometry, zmatrix, energy, and torsions to the save filesys. Also, the function assessess if the species is unstable and will save the appropriate information. """ ini_thy_info = tinfo.from_dct(ini_method_dct) thy_info = tinfo.from_dct(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) [kickoff_size, kickoff_backward] = spc_dct_i['kickoff'] _, cnf_path = filesys.mincnf.min_energy_conformer_locators( cnf_save_fs, mod_thy_info) overwrite = es_keyword_dct['overwrite'] if not cnf_path: ioprinter.info_message( 'No conformer found in save filesys. Checking for running jobs...') if _init_geom_is_running(cnf_run_fs) and not overwrite: _run = False else: ioprinter.info_message( 'No conformers are running in run filesys.' + 'Proceeding with optimization...') _run = True elif overwrite: ioprinter.info_message( 'User specified to overwrite energy with new run...') _run = True else: _run = False if _run: ioprinter.info_message('Obtaining some initial guess geometry.') geo_init = _obtain_ini_geom(spc_dct_i, ini_cnf_save_fs, mod_ini_thy_info, overwrite) if geo_init is not None: ioprinter.debug_message( 'Assessing if there are any functional groups', 'that cause instability') ioprinter.debug_message('geo str\n', automol.geom.string(geo_init)) zma_init = automol.geom.zmatrix(geo_init) rid = autofile.schema.generate_new_ring_id() cid = autofile.schema.generate_new_conformer_id() # Determine if there is an instability, if so return prods instab_zmas = automol.reac.instability_product_zmas(zma_init) if not instab_zmas: # Build a cid and a run fs cnf_run_fs[-1].create((rid, cid)) run_fs = autofile.fs.run(cnf_run_fs[-1].path((rid, cid))) if not automol.geom.is_atom(geo_init): geo_found = _optimize_molecule( spc_info, zma_init, method_dct, cnf_save_fs, (rid, cid), run_fs, overwrite, kickoff_size=kickoff_size, kickoff_backward=kickoff_backward) else: geo_found = _optimize_atom(spc_info, zma_init, method_dct, cnf_save_fs, (rid, cid), run_fs, overwrite) else: ioprinter.info_message( 'Found functional groups that cause instabilities') filesys.save.instability(zma_init, instab_zmas, cnf_save_fs, rng_locs=(rid, ), tors_locs=(cid, ), zma_locs=(0, )) geo_found = True else: geo_found = False ioprinter.warning_message( 'Unable to obtain an initial guess geometry') else: ioprinter.existing_path('Initial geometry', cnf_path) geo_found = True return geo_found
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 _optimize_molecule(spc_info, zma_init, method_dct, cnf_save_fs, locs, run_fs, overwrite, kickoff_size=0.1, kickoff_backward=False): """ Optimize a proper geometry """ thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) script_str, kwargs = es_runner.qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) # Call the electronic structure optimizer success, ret = es_runner.execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=zma_init, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs) # read the geometry if success: inf_obj, _, out_str = ret geo = elstruct.reader.opt_geometry(inf_obj.prog, out_str) zma = elstruct.reader.opt_zmatrix(inf_obj.prog, out_str) if zma is None: zma = automol.geom.zmatrix(geo) geo_conn = bool(automol.geom.connected(geo)) # If connected, check for imaginary modes and fix them if possible if geo_conn: # Remove the imaginary mode geo, ret = remove_imag(geo, ret, spc_info, method_dct, run_fs, kickoff_size, kickoff_backward, kickoff_mode=0, overwrite=overwrite) # Recheck connectivity for imag-checked geometry if geo is not None: conf_found = True if automol.geom.connected(geo): ioprinter.info_message( 'Saving structure as the first conformer...', newline=1) filesys.save.conformer(ret, None, cnf_save_fs, mod_thy_info[1:], rng_locs=(locs[0], ), tors_locs=(locs[1], )) else: ioprinter.info_message('Saving disconnected species...') filesys.save.instability(zma_init, zma, cnf_save_fs, rng_locs=(locs[0], ), tors_locs=(locs[1], ), zma_locs=(0, )) else: ioprinter.warning_message('No geom found...', newline=1) conf_found = False else: ioprinter.info_message('Saving disconnected species...') conf_found = False filesys.save.instability(zma_init, zma, cnf_save_fs, rng_locs=(locs[0], ), tors_locs=(locs[1], ), zma_locs=(0, )) return conf_found
def frequencies(spc_name, spc_dct_i, spc_mod_dct_i, proc_keyword_dct, thy_dct, cnf_fs, locs, locs_path, run_prefix, save_prefix): """collect frequencies """ # Initialize the data objects to None freqs = None imag = None zpe = None sfactor = None torsfreqs = None all_freqs = None disps = None # Initialize a miss_data object that will be overwritten if data found if spc_mod_dct_i is not None: mod_thy_info = spc_mod_dct_i['vib']['geolvl'][1][1] else: mod_thy_info = tinfo.from_dct(thy_dct.get(proc_keyword_dct['proplvl'])) miss_data = (spc_name, mod_thy_info, 'frequencies') # Get flags to to ID spc as a transiion state zrxn = spc_dct_i.get('zrxn', None) saddle = bool(zrxn) # Get vibrational frequencies if spc_mod_dct_i is not None: pf_filesystems = filesys.models.pf_filesys(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, name=spc_name, saddle=saddle) ret = vib.full_vib_analysis(spc_dct_i, pf_filesystems, spc_mod_dct_i, run_prefix, zrxn=zrxn) if ret is not None: freqs, imag, zpe, sfactor, _, torsfreqs, all_freqs, disps = ret if saddle: print(f'Imaginary Frequencies[cm-1]: {imag}') freqs = (-1 * imag, ) + freqs miss_data = None # Do a TED check if zrxn is not None: vib.ted(spc_dct_i, pf_filesystems, spc_mod_dct_i, run_prefix, zrxn=zrxn) else: es_levels = util.freq_es_levels(proc_keyword_dct) spc_mod_dct_i = util.generate_spc_model_dct(es_levels, thy_dct) ret = vib.read_locs_harmonic_freqs(cnf_fs, locs, run_prefix, zrxn=zrxn) if ret is not None: freqs, imag, zpe, disps = ret if freqs and proc_keyword_dct['scale'] is not None: freqs, zpe = vib.scale_frequencies( freqs, 0.0, spc_mod_dct_i, scale_method=proc_keyword_dct['scale']) if saddle: print(f'Imaginary Frequencies[cm-1]: {imag}') freqs = (-1 * imag, ) + freqs miss_data = None pf_filesystems = filesys.models.pf_filesys(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, name=spc_name, saddle=saddle) # Do a TED check if zrxn is not None: vib.ted(spc_dct_i, pf_filesystems, spc_mod_dct_i, run_prefix, zrxn=zrxn) # Package up the frequencies data if freqs is not None: spc_data = [locs_path, zpe, *freqs] fxn_ret = spc_data, (torsfreqs, all_freqs, sfactor), disps else: fxn_ret = None return fxn_ret, miss_data
def remove_imag(geo, ini_ret, spc_info, method_dct, run_fs, kickoff_size=0.1, kickoff_backward=False, kickoff_mode=0): """ if there is an imaginary frequency displace geometry along the imaginary mode and then reoptimize """ thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) hess_script_str, kwargs = qchem_params(method_dct) ioprinter.info_message( 'Checking the initial geometry for imaginary frequencies...') hess, hess_ret = _hess(spc_info, mod_thy_info, geo, run_fs, hess_script_str, **kwargs) imags, norm_coords = _check_imaginary(geo, hess, hess_ret, run_fs) # Make five attempts to remove imag mode if found count, opt_ret = 1, None while imags and count <= 4: # Either attempt a kickoff-reopt or tight-reopt # Only attempt kickoff-reopt on first two tries if count <= 2: ioprinter.info_message( f'Attempting kick off along mode, attempt {count}...') opt_script_str, opt_kwargs = qchem_params( method_dct, job=elstruct.Job.OPTIMIZATION) disp_geo = _kickoff_saddle( geo, norm_coords, size=kickoff_size, backward=kickoff_backward, mode=kickoff_mode) geo, opt_ret = _opt(spc_info, mod_thy_info, disp_geo, run_fs, opt_script_str, opt_cart=True, **opt_kwargs) hess_script_str, hess_kwargs = qchem_params( method_dct) else: ioprinter.info_message( f'Attempting tight opt, attempt {count-2}...') opt_script_str, opt_kwargs = qchem_params( method_dct, job='tightopt') geo, opt_ret = _opt(spc_info, mod_thy_info, geo, run_fs, opt_script_str, opt_cart=True, **opt_kwargs) hess_script_str, hess_kwargs = qchem_params( method_dct, job='tightfreq') # Assess the imaginary mode after the reoptimization ioprinter.info_message('Rerunning Hessian...') hess, hess_ret = _hess(spc_info, mod_thy_info, geo, run_fs, hess_script_str, **hess_kwargs) imags, norm_coords = _check_imaginary(geo, hess, hess_ret, run_fs) # Update the loop counter and kickoff size count += 1 kickoff_size *= 2.0 if opt_ret is None: ret = ini_ret else: ret = opt_ret return geo, ret
def scan_for_guess(ts_dct, method_dct, runfs_dct, savefs_dct, es_keyword_dct): """ saddle point scan code """ print(' - No Z-Matrix is found in save filesys.') print('\nRunning scan to generate guess Z-Matrix for opt...') # Get es keyword info overwrite = es_keyword_dct['overwrite'] retryfail = es_keyword_dct['retryfail'] # Get info from the dct ts_zma = ts_dct['zma'] zrxn = ts_dct['zrxn'] # convert to zrxn ts_info = rinfo.ts_info(ts_dct['rxn_info']) scn_save_fs = savefs_dct['runlvl_scn_fs'] # Build grid and names appropriate for reaction type scan_inf = automol.reac.build_scan_info(zrxn, ts_zma) coord_names, constraint_dct, coord_grids, update_guess = scan_inf # Get filesystem information if constraint_dct is None: scn_run_fs = runfs_dct['runlvl_scn_fs'] scn_save_fs = savefs_dct['runlvl_scn_fs'] else: scn_run_fs = runfs_dct['runlvl_cscn_fs'] scn_save_fs = savefs_dct['runlvl_cscn_fs'] # Set up script string and kwargs mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) es_runner.scan.execute_scan( zma=ts_zma, spc_info=ts_info, mod_thy_info=mod_thy_info, coord_names=coord_names, coord_grids=coord_grids, scn_run_fs=scn_run_fs, scn_save_fs=scn_save_fs, scn_typ='relaxed', script_str=script_str, overwrite=overwrite, zrxn=zrxn, update_guess=update_guess, reverse_sweep=False, saddle=False, constraint_dct=constraint_dct, retryfail=retryfail, **kwargs, ) guess_zmas = rxngrid.grid_maximum_zmatrices(zrxn.class_, ts_zma, coord_grids, coord_names, scn_save_fs, mod_thy_info, constraint_dct) return guess_zmas
def optimize_saddle_point(guess_zmas, ts_dct, method_dct, mref_kwargs, runfs_dct, es_keyword_dct, cnf_locs): """ Optimize the transition state structure obtained from the grid search """ # Get info (move later) ts_info = rinfo.ts_info(ts_dct['rxn_info']) mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) overwrite = es_keyword_dct['overwrite'] ts_info = rinfo.ts_info(ts_dct['rxn_info']) runlvl_cnf_run_fs = runfs_dct['runlvl_cnf'] runlvl_cnf_run_fs[-1].create(cnf_locs) run_fs = autofile.fs.run(runlvl_cnf_run_fs[-1].path(cnf_locs)) ioprinter.info_message( f'There are {len(guess_zmas)} guess Z-Matrices' 'to attempt to find saddle point.', newline=1) # Loop over all the guess zmas to find a TS opt_ret, hess_ret = None, None for idx, zma in enumerate(guess_zmas): ioprinter.info_message(f'\nOptimizing guess Z-Matrix {idx+1}...') # Run the transition state optimization script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) kwargs.update(mref_kwargs) opt_success, opt_ret = es_runner.execute_job( job='optimization', script_str=script_str, run_fs=run_fs, geo=zma, spc_info=ts_info, thy_info=mod_thy_info, saddle=True, overwrite=overwrite, **kwargs, ) if opt_success: break if opt_success: script_str, kwargs = qchem_params(method_dct) # Obtain geometry from optimization opt_inf_obj, _, opt_out_str = opt_ret opt_prog = opt_inf_obj.prog geo = elstruct.reader.opt_geometry(opt_prog, opt_out_str) # Run a Hessian _, hess_ret = es_runner.execute_job( job='hessian', script_str=script_str, run_fs=run_fs, geo=geo, spc_info=ts_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs, ) return opt_ret, hess_ret
def internal_coordinates_scan(ts_zma, zrxn, ts_info, rxn_class, method_dct, mref_params, scn_run_fs, scn_save_fs, es_keyword_dct, find_max=True): """ Scan along the internal coordinates that correspond to the reaction coordinate. Additional constraints will be used as needed. Both the internal coordinate and constrained coordinates are set according to reaction class. """ # Determine if scan should be for variational reaction class # Build grid and names appropriate for reaction type var = (automol.par.is_radrad(rxn_class) and automol.par.is_low_spin(rxn_class)) scan_inf = automol.reac.build_scan_info(zrxn, ts_zma, var=var) coord_names, constraint_dct, coord_grids, update_guess = scan_inf # Set up script string and kwargs mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) kwargs.update(mref_params) es_runner.scan.execute_scan( zma=ts_zma, spc_info=ts_info, mod_thy_info=mod_thy_info, coord_names=coord_names, coord_grids=coord_grids, scn_run_fs=scn_run_fs, scn_save_fs=scn_save_fs, scn_typ='relaxed', script_str=script_str, overwrite=es_keyword_dct['overwrite'], update_guess=update_guess, reverse_sweep=False, saddle=False, constraint_dct=constraint_dct, retryfail=False, **kwargs, ) if find_max: include_endpts = not mref_params max_zmas = rxngrid.grid_maximum_zmatrices( zrxn.class_, ts_zma, coord_grids, coord_names, scn_save_fs, mod_thy_info, constraint_dct, include_endpts=include_endpts) else: max_zmas = None return max_zmas
def _set_thy_inf_dcts(tsname, ts_dct, thy_dct, es_keyword_dct, run_prefix, save_prefix, zma_locs=(0, )): """ set the theory """ rxn_info = ts_dct['rxn_info'] ts_info = rinfo.ts_info(rxn_info) rct_info = rinfo.rgt_info(rxn_info, 'reacs') rxn_info = rinfo.sort(rxn_info) ts_locs = (int(tsname.split('_')[-1]), ) high_mult = rinfo.ts_mult(rxn_info, rxn_mul='high') # Set the hs info hs_info = (ts_info[0], ts_info[1], high_mult) # Initialize the theory objects ini_thy_info, mod_ini_thy_info = None, None thy_info, mod_thy_info = None, None vscnlvl_thy_info, mod_vscnlvl_thy_info = None, None vsp1lvl_thy_info, mod_vsp1lvl_thy_info = None, None vsp2lvl_thy_info, mod_vsp2lvl_thy_info = None, None hs_vscnlvl_thy_info = None hs_vsp1lvl_thy_info = None hs_vsp2lvl_thy_info = None hs_thy_info = None # Initialize the necessary run filesystem runlvl_ts_run_fs = None runlvl_scn_run_fs = None runlvl_cscn_run_fs = None vscnlvl_ts_run_fs = None vscnlvl_scn_run_fs = None vscnlvl_cscn_run_fs = None vrctst_run_fs = None # Initialize the necessary save filesystem ini_zma_save_fs = None runlvl_ts_save_fs = None runlvl_scn_save_fs = None # above cnf filesys, for search scans runlvl_cscn_save_fs = None # above cnf filesys, for search scans runlvl_cnf_save_fs = None vscnlvl_thy_save_fs = None vscnlvl_ts_save_fs = None vscnlvl_scn_save_fs = None vscnlvl_cscn_save_fs = None vrctst_save_fs = None runlvl_ts_zma_fs = None if es_keyword_dct.get('inplvl', None) is not None: ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) ini_thy_info = tinfo.from_dct(ini_method_dct) mod_ini_thy_info = tinfo.modify_orb_label(ini_thy_info, ts_info) ini_cnf_run_fs, ini_cnf_save_fs = build_fs( run_prefix, save_prefix, 'CONFORMER', rxn_locs=rxn_info, ts_locs=ts_locs, 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_path = ini_loc_info if ini_path: ini_zma_save_fs = autofile.fs.zmatrix( ini_cnf_save_fs[-1].path(ini_min_cnf_locs)) if es_keyword_dct.get('runlvl', None) is not None: method_dct = thy_dct.get(es_keyword_dct['runlvl']) thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, ts_info) hs_thy_info = tinfo.modify_orb_label(thy_info, hs_info) runlvl_cnf_run_fs, runlvl_cnf_save_fs = build_fs( run_prefix, save_prefix, 'CONFORMER', rxn_locs=rxn_info, ts_locs=ts_locs, thy_locs=mod_thy_info[1:]) _, runlvl_ts_zma_save_fs = build_fs(run_prefix, save_prefix, 'ZMATRIX', rxn_locs=rxn_info, ts_locs=ts_locs, thy_locs=mod_thy_info[1:]) runlvl_loc_info = filesys.mincnf.min_energy_conformer_locators( runlvl_cnf_save_fs, mod_thy_info) runlvl_min_cnf_locs, _ = runlvl_loc_info runlvl_cnf_save_fs = (runlvl_cnf_save_fs, runlvl_min_cnf_locs) runlvl_scn_run_fs, runlvl_scn_save_fs = build_fs( run_prefix, save_prefix, 'SCAN', rxn_locs=rxn_info, ts_locs=ts_locs, thy_locs=mod_thy_info[1:], zma_locs=(0, )) runlvl_cscn_run_fs, runlvl_cscn_save_fs = build_fs( run_prefix, save_prefix, 'CSCAN', rxn_locs=rxn_info, ts_locs=ts_locs, thy_locs=mod_thy_info[1:], zma_locs=(0, )) if es_keyword_dct.get('var_scnlvl', None) is not None: method_dct = thy_dct.get(es_keyword_dct['var_scnlvl']) vscnlvl_thy_info = tinfo.from_dct(method_dct) mod_vscnlvl_thy_info = tinfo.modify_orb_label(vscnlvl_thy_info, ts_info) hs_vscnlvl_thy_info = tinfo.modify_orb_label(vscnlvl_thy_info, hs_info) vscnlvl_scn_run_fs, vscnlvl_scn_save_fs = build_fs( run_prefix, save_prefix, 'SCAN', rxn_locs=rxn_info, ts_locs=ts_locs, thy_locs=mod_thy_info[1:], zma_locs=(0, )) vscnlvl_cscn_run_fs, vscnlvl_cscn_save_fs = build_fs( run_prefix, save_prefix, 'CSCAN', rxn_locs=rxn_info, ts_locs=ts_locs, thy_locs=mod_thy_info[1:], zma_locs=(0, )) vrctst_run_fs, vrctst_save_fs = build_fs(run_prefix, save_prefix, 'VRCTST', rxn_locs=rxn_info, ts_locs=ts_locs, thy_locs=mod_thy_info[1:]) if es_keyword_dct.get('var_splvl1', None) is not None: method_dct = thy_dct.get(es_keyword_dct['var_scnlvl1']) vsplvl1_thy_info = tinfo.from_dct(method_dct) mod_vsplvl1_thy_info = tinfo.modify_orb_label( vsplvl1_thy_info, ts_info) hs_vsplvl1_thy_info = tinfo.modify_orb_label( vsplvl1_thy_info, hs_info) if es_keyword_dct.get('var_splvl2', None) is not None: method_dct = thy_dct.get(es_keyword_dct['var_scnlvl2']) vsplvl2_thy_info = tinfo.from_dct(method_dct) mod_vsplvl2_thy_info = tinfo.modify_orb_label( vsplvl2_thy_info, ts_info) hs_vsplvl2_thy_info = tinfo.modify_orb_label( vsplvl2_thy_info, hs_info) # Get the conformer filesys for the reactants _rcts_cnf_fs = rcts_cnf_fs(rct_info, thy_dct, es_keyword_dct, run_prefix, save_prefix) thy_inf_dct = { 'inplvl': ini_thy_info, 'runlvl': thy_info, 'var_scnlvl': vscnlvl_thy_info, 'var_splvl1': vsp1lvl_thy_info, 'var_splvl2': vsp2lvl_thy_info, 'mod_inplvl': mod_ini_thy_info, 'mod_runlvl': mod_thy_info, 'mod_var_scnlvl': mod_vscnlvl_thy_info, 'mod_var_splvl1': mod_vsp1lvl_thy_info, 'mod_var_splvl2': mod_vsp2lvl_thy_info, 'hs_var_scnlvl': hs_vscnlvl_thy_info, 'hs_var_splvl1': hs_vsp1lvl_thy_info, 'hs_var_splvl2': hs_vsp2lvl_thy_info, 'hs_runlvl': hs_thy_info } runfs_dct = { 'runlvl_scn_fs': runlvl_scn_run_fs, 'runlvl_cscn_fs': runlvl_cscn_run_fs, 'runlvl_cnf_fs': runlvl_cnf_run_fs, 'vscnlvl_ts_fs': vscnlvl_ts_run_fs, 'vscnlvl_scn_fs': vscnlvl_scn_run_fs, 'vscnlvl_cscn_fs': vscnlvl_cscn_run_fs, 'vrctst_fs': vrctst_run_fs, } savefs_dct = { 'inilvl_zma_fs': ini_zma_save_fs, 'runlvl_scn_fs': runlvl_scn_save_fs, 'runlvl_cscn_fs': runlvl_cscn_save_fs, 'runlvl_cnf_fs': runlvl_cnf_save_fs, 'vscnlvl_scn_fs': vscnlvl_scn_save_fs, 'vscnlvl_cscn_fs': vscnlvl_cscn_save_fs, 'vrctst_fs': vrctst_save_fs, 'rcts_cnf_fs': _rcts_cnf_fs, 'runlvl_ts_zma_fs': runlvl_ts_zma_save_fs } return thy_inf_dct, runfs_dct, savefs_dct