def _vtst_hess_ene(ts_info, coord_name, mod_thy_info, mod_vsp1_thy_info, scn_save_fs, scn_run_fs, overwrite, **cas_kwargs): """ VTST Hessians and Energies """ scn_locs = scn_save_fs[-1].existing([coord_name]) ioprinter.running('Hessians and Gradients and Energies...', newline=1) hess_script_str, _, hess_kwargs, _ = qchem_params(*mod_thy_info[0:2]) hess_kwargs.update(cas_kwargs) script_str, _, ene_kwargs, _ = qchem_params(*mod_vsp1_thy_info[0:2]) ene_kwargs.update(cas_kwargs) for locs in scn_locs: geo_run_path = scn_run_fs[-1].path(locs) geo_save_path = scn_save_fs[-1].path(locs) scn_run_fs[-1].create(locs) zma, geo = filesys.inf.cnf_fs_zma_geo(scn_save_fs, locs) sp.run_hessian(zma, geo, ts_info, mod_thy_info, scn_save_fs, geo_run_path, geo_save_path, locs, hess_script_str, overwrite, **hess_kwargs) sp.run_gradient(zma, geo, ts_info, mod_thy_info, scn_save_fs, geo_run_path, geo_save_path, locs, hess_script_str, overwrite, **hess_kwargs) sp.run_energy(zma, geo, ts_info, mod_vsp1_thy_info, scn_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, **ene_kwargs)
def hindered_rotor_scans(zma, spc_info, mod_thy_info, scn_run_fs, scn_save_fs, rotors, tors_model, method_dct, overwrite, saddle=False, increment=0.5235987756, retryfail=True): """ Perform scans over each of the torsional coordinates """ if tors_model != '1dhrfa': script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) scn_typ = 'relaxed' update_guess = True else: script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.ENERGY) scn_typ = 'rigid' update_guess = False run_tors_names = automol.rotor.names(rotors) run_tors_grids = automol.rotor.grids(rotors, increment=increment) # Set constraints const_names = automol.zmat.set_constraint_names(zma, run_tors_names, tors_model) ioprinter.run_rotors(run_tors_names, const_names) for tors_names, tors_grids in zip(run_tors_names, run_tors_grids): ioprinter.info_message('Running Rotor: {}...'.format(tors_names), newline=1) # Setting the constraints constraint_dct = automol.zmat.constraint_dct(zma, const_names, tors_names) scan.execute_scan( zma=zma, spc_info=spc_info, mod_thy_info=mod_thy_info, coord_names=tors_names, coord_grids=tors_grids, scn_run_fs=scn_run_fs, scn_save_fs=scn_save_fs, scn_typ=scn_typ, script_str=script_str, overwrite=overwrite, update_guess=update_guess, reverse_sweep=True, saddle=saddle, constraint_dct=constraint_dct, retryfail=retryfail, **kwargs, )
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 write_elstruct_inp(lj_info, mod_lj_thy_info): """ writes the electronic structure input file """ # Unpack info objects [_, charge, mult] = lj_info [prog, method, basis, orb_lbl] = mod_lj_thy_info assert prog in ('gaussian09', 'gaussian16', 'molpro2015') # Get the job running options script_str, _, kwargs, _ = qchem_params( *mod_lj_thy_info[0:2]) # Write the string elstruct_inp_str = elstruct.writer.energy( geom='GEOMETRY', charge=charge, mult=mult, method=method, basis=basis, prog=prog, mol_options=('nosym', 'noorient'), memory=kwargs['memory'], comment='SAMPLE GEOM', orb_type=orb_lbl ) elstruct_sp_str = '\n'.join(script_str.splitlines()[1:]) return elstruct_inp_str, elstruct_sp_str
def execute_irc(zma, ts_info, mod_ini_thy_info, ini_method_dct, ini_scn_run_fs, ini_scn_save_fs, es_keyword_dct, directions=(elstruct.Job.IRCF, elstruct.Job.IRCR)): """ Run and save the IRC """ coord_name = 'IRC' overwrite = es_keyword_dct['overwrite'] retryfail = es_keyword_dct['retryfail'] # Set up run filesys run_fs = autofile.fs.run(ini_scn_run_fs[1].path([coord_name])) # Run and Read the IRC in the forward and reverse direction for direction in directions: script_str, kwargs = qchem_params(ini_method_dct, job=direction) run_irc(zma, direction, coord_name, run_fs, ini_scn_save_fs, ts_info, mod_ini_thy_info, overwrite, retryfail, script_str, **kwargs) success, _ = es_runner.read_job( job=direction, run_fs=run_fs, ) if success: save_irc(direction, coord_name, run_fs, ini_scn_save_fs, mod_ini_thy_info) return success
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 _singleref_inf_sep_ene(rct_info, sp_thy_info, rcts_cnf_fs, run_prefix, method_dct, overwrite): """ Obtain the electronic energy for a set of reactants at infinite separation for a single-reference electronic structure method. Since single-reference methods are size-consistent, this simply amounts to summing the electronic energies of the reactants calculated independently. Function will attempt to read the energy from the SAVE filesystem and calculate it if it does not currently exist. """ script_str, kwargs = qchem_params(method_dct) return _reac_sep_ene(rct_info, sp_thy_info, rcts_cnf_fs, run_prefix, overwrite, script_str, **kwargs)
def reac_coord_scan(ts_zma, ts_info, zrxn, method_dct, scn_run_fs, scn_save_fs, es_keyword_dct): """ saddle point scan code """ # 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 # 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, thy_save_fs=(), 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, chkstab=False, **kwargs, ) # Find the structure at the maximum on the grid opt scan # if 'elimination' in rxn_typ: # [grid1, grid2] = coord_grids # max_zma = rxngrid.find_max_2d( # grid1, grid2, frm_name, brk_name, scn_save_fs, # mod_thy_info, constraint_dct) # guess_zmas = [max_zma] # else: guess_zmas = rxngrid.find_max_1d(zrxn.class_, coord_grids[0], ts_zma, coord_names[0], scn_save_fs, mod_thy_info, constraint_dct) return guess_zmas
def irc_scan(zma, ts_info, coord_name, mod_ini_thy_info, ini_method_dct, ini_scn_save_fs, geo_run_path, overwrite): """ Run the IRC """ # Set up run filesys run_fs = autofile.fs.run(geo_run_path) # Run and Read the IRC in the forward and reverse direction for irc_job in (elstruct.Job.IRCF, elstruct.Job.IRCR): # Set up the script script_str, kwargs = qchem_params(ini_method_dct, job=irc_job) run_irc(zma, irc_job, coord_name, run_fs, ini_scn_save_fs, ts_info, mod_ini_thy_info, overwrite, script_str, **kwargs) save_irc(irc_job, coord_name, run_fs, ini_scn_save_fs, mod_ini_thy_info)
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 radrad_inf_sep_ene(hs_info, ref_zma, rct_info, rcts_cnf_fs, var_sp1_thy_info, var_sp2_thy_info, hs_var_sp1_thy_info, hs_var_sp2_thy_info, geo, geo_run_path, geo_save_path, scn_save_fs, inf_locs, overwrite=False, **cas_kwargs): """ 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 scn = thy for optimizations sp1 = low-spin single points sp2 = high-spin single points for inf sep inf = spc0 + spc1 - hs_sr_e + hs_mr_ene """ # Initialize infinite sep energy inf_sep_ene = -1.0e12 # Calculate the energies for the two cases hs_inf = (hs_var_sp2_thy_info, hs_var_sp1_thy_info) for idx, thy_info in enumerate(hs_inf): if idx == 0: ioprinter.info_message( " - Running high-spin single reference energy ...") else: ioprinter.info_message( " - Running high-spin multi reference energy ...") # Calculate the single point energy script_str, _, kwargs, _ = qchem_params(*thy_info[0:2]) cas_kwargs.update(kwargs) sp.run_energy(ref_zma, geo, hs_info, thy_info, scn_save_fs, geo_run_path, geo_save_path, inf_locs, script_str, overwrite, highspin=True, **cas_kwargs) # Read the energty from the filesystem hs_save_fs = autofile.fs.high_spin(geo_save_path) if not hs_save_fs[-1].file.energy.exists(thy_info[1:4]): ioprinter.error_message( 'High-spin energy job failed: ', 'energy is needed to evaluate infinite separation energy') ene = None else: ioprinter.info_message( " - Reading high-spin energy from filesystem...") ene = hs_save_fs[-1].file.energy.read(thy_info[1:4]) if idx == 0: hs_sr_ene = ene else: hs_mr_ene = ene # Get the single reference energy for each of the reactant configurations for thy_inf in (var_sp1_thy_info, var_sp2_thy_info): sp_script_str, _, kwargs, _ = qchem_params(*var_sp2_thy_info[0:2]) reac_ene = reac_sep_ene(rct_info, rcts_cnf_fs, thy_inf, overwrite, sp_script_str, **kwargs) # Calculate the infinite seperation energy all_enes = (reac_ene, hs_sr_ene, hs_mr_ene) if all(ene is not None for ene in all_enes): inf_sep_ene = reac_ene - hs_sr_ene + hs_mr_ene else: inf_sep_ene = None return inf_sep_ene
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 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)
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 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 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 molrad_scan(ts_zma, ts_info, rct_info, rcts_cnf_fs, rcts_gra, grid1, grid2, coord_name, frm_bnd_keys, thy_info, vsp1_thy_info, thy_save_fs, ts_save_fs, scn_run_fs, scn_save_fs, overwrite, update_guess, retryfail, zma_locs=(0, )): """ Run the scan for VTST calculations """ # Set the thy info objects appropriately if vsp1_thy_info is not None: inf_thy_info = vsp1_thy_info else: inf_thy_info = thy_info mod_thy_info = filesys.inf.modify_orb_restrict(ts_info, thy_info) mod_vsp1_thy_info = filesys.inf.modify_orb_restrict(ts_info, vsp1_thy_info) # Set script _, opt_script_str, _, opt_kwargs = qchem_params(*mod_thy_info[0:2]) # Setup and run the first part of the scan to shorte scan.run_two_way_scan( ts_zma, ts_info, mod_thy_info, grid1, grid2, coord_name, thy_save_fs, scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess=update_guess, reverse_sweep=False, saddle=False, # opts along scan are min, not sadpt opts constraint_dct=None, retryfail=retryfail, **opt_kwargs) # Infinite seperation energy calculation ioprinter.info_message('Calculating infinite separation energy...', newline=1) ioprinter.debug_message('inf_thy_info', inf_thy_info) _ = scan.molrad_inf_sep_ene(rct_info, rcts_cnf_fs, inf_thy_info, overwrite) # Save the vmatrix for use in reading _save_traj(ts_zma, frm_bnd_keys, rcts_gra, ts_save_fs, zma_locs=zma_locs) ioprinter.running('Hessians and energies...', newline=1) _vtst_hess_ene(ts_info, coord_name, mod_thy_info, mod_vsp1_thy_info, scn_save_fs, scn_run_fs, overwrite, **{})
def hindered_rotor_scans(zma, spc_info, mod_thy_info, thy_save_fs, scn_run_fs, scn_save_fs, rotors, tors_model, method_dct, overwrite, saddle=False, increment=30.0 * phycon.DEG2RAD, retryfail=True, chkstab=None): """ Perform scans over each of the torsional coordinates """ if tors_model != '1dhrfa': script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) scn_typ = 'relaxed' else: script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.ENERGY) scn_typ = 'rigid' run_tors_names = automol.rotor.names(rotors) run_tors_grids = automol.rotor.grids(rotors, increment=increment) # Set constraints const_names = automol.zmat.set_constraint_names(zma, run_tors_names, tors_model) # Set appropriate value for check stability # If not set, don't check if saddle=True if chkstab is None: chkstab = bool(not saddle) ioprinter.run_rotors(run_tors_names, const_names) # for tors_name, tors_grid in zip(tors_names, tors_grids): for tors_names, tors_grids in zip(run_tors_names, run_tors_grids): ioprinter.info_message('Running Rotor: {}...'.format(tors_names), newline=1) # Setting the constraints constraint_dct = automol.zmat.constraint_dct(zma, const_names, tors_names) scan.execute_scan( zma=zma, spc_info=spc_info, mod_thy_info=mod_thy_info, thy_save_fs=thy_save_fs, coord_names=tors_names, coord_grids=tors_grids, scn_run_fs=scn_run_fs, scn_save_fs=scn_save_fs, scn_typ=scn_typ, script_str=script_str, overwrite=overwrite, update_guess=True, reverse_sweep=True, saddle=saddle, constraint_dct=constraint_dct, retryfail=retryfail, chkstab=False, **kwargs, )
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 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 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. Fxn takes two species, performs a (random?) rotation, sticks them together and optimizes the combined geometry. Supposed to use the wells filesystem? """ new_vdws = [] _, opt_script_str, _, opt_kwargs = qchem_params(*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: ioprinter.info_message( 'Cannot find van der Waals well for unimolecular', 'reactant or product') ichs = list(map(lambda name: spc_dct[name]['inchi'], 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 = es_runner.qchem_params(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 = filesys.inf.orbital_restriction(spc_info, ini_thy_info) ini_g = ini_thy_info[0:3] ini_g.append(orb_restr) orb_restr = filesys.inf.orbital_restriction(spc_info, thy_info) thy_info = thy_info[0:3] thy_info.append(orb_restr) spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs[-1].create(spc_info) spc_run_path = spc_run_fs[-1].path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs[-1].create(spc_info) spc_save_path = spc_save_fs[-1].path(spc_info) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs[-1].create(thy_info[1:4]) thy_run_path = thy_run_fs[-1].path(thy_info[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs[-1].create(thy_info[1:4]) thy_save_path = thy_save_fs[-1].path(thy_info[1:4]) run_fs = autofile.fs.run(thy_run_path) ini_thy_save_fs = autofile.fs.theory(spc_save_path) ini_thy_save_fs[-1].create(ini_thy_info[1:4]) cnf_run_fs = autofile.fs.conformer(thy_run_path) cnf_save_fs = autofile.fs.conformer(thy_save_path) geo = geom.reference_geometry(spc_dct[nam], thy_info, ini_thy_info, thy_run_fs, thy_save_fs, ini_thy_save_fs, cnf_run_fs, cnf_save_fs, run_fs, kickoff_size=kickoff_size, kickoff_backward=kickoff_backward, 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)): ioprinter.info_message('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_rotate(geo1, *angs1) geo2 = automol.geom.euler_rotate(geo2, *angs2) dist_cutoff = 3.0 * phycon.ANG2BOHR geo = automol.geom.join(geo1, geo2, dist_cutoff, *angs12) ioprinter.info_message("Species: {}".format('+'.join(names))) ioprinter.geometry(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[-1].create(spc_info) spc_run_path = spc_run_fs[-1].path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs[-1].create(spc_info) spc_save_path = spc_save_fs[-1].path(spc_info) orb_restr = filesys.inf.orbital_restriction(spc_info, thy_info) thy_info = thy_info[0:3] thy_info.append(orb_restr) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs[-1].create(thy_info[1:4]) thy_run_path = thy_run_fs[-1].path(thy_info[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs[-1].create(thy_info[1:4]) thy_save_path = thy_save_fs[-1].path(thy_info[1:4]) run_fs = autofile.fs.run(thy_run_path) # Generate reference geometry # Generate the z-matrix and sampling ranges es_runner.run_job( job=elstruct.Job.OPTIMIZATION, geo=geo, spc_info=spc_info, th_info=thy_info, run_fs=run_fs, script_str=opt_script_str, overwrite=overwrite, **opt_kwargs, ) # Save info for the initial geometry (from ichi or fsave dir) success, ret = es_runner.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if success: ioprinter.save_reference(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) ioprinter.geometry(geo) thy_save_fs[-1].file.geometry.write(geo, thy_info[1:4]) ene = elstruct.reader.energy(prog, method, out_str) if ene < min_ene: min_ene = ene ioprinter.debug_message('ene test in vdw', ene) thy_save_fs[-1].file.energy.write(ene, thy_info[1:4]) ioprinter.save_reference(thy_save_path) vdw_name = label + ts_name.replace('ts', 'vdw') spc_dct[vdw_name] = spc_dct[ts_name].copy() spc_dct[vdw_name]['inchi'] = 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[0].create() cnf_run_fs[0].create() tors_range_dct = {} cinf_obj = autofile.schema.info_objects.conformer[0]( 0, tors_range_dct) cinf_obj.nsamp = 1 cnf_save_fs[0].file.info.write(cinf_obj) locs_lst = cnf_save_fs[-1].existing() if not locs_lst: cid = autofile.schema.generate_new_conformer_id() locs = [cid] else: locs = locs_lst[0] cnf_save_fs[-1].create(locs) cnf_run_fs[-1].create(locs) cnf_save_fs[-1].file.geometry_info.write(inf_obj, locs) cnf_save_fs[-1].file.geometry_input.write(inp_str, locs) cnf_save_fs[-1].file.energy.write(ene, locs) cnf_save_fs[-1].file.geometry.write(geo, locs) if min_ene: new_vdws.append(vdw_name) return new_vdws
def molrad_inf_sep_ene(rct_info, rcts_cnf_fs, mod_thy_info, overwrite): """ Calculate the inf spe ene for a mol-rad ene """ script_str, kwargs = qchem_params(*mod_thy_info[0:2]) return reac_sep_ene(rct_info, rcts_cnf_fs, mod_thy_info, overwrite, script_str, **kwargs)
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 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 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 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')
def _multiref_inf_sep_ene(hs_info, ref_zma, rct_info, rcts_cnf_fs, run_prefix, thy_info, var_scn_thy_info, var_sp1_thy_info, var_sp2_thy_info, hs_var_sp1_thy_info, hs_var_sp2_thy_info, var_sp1_method_dct, var_sp2_method_dct, scn_run_fs, scn_save_fs, inf_locs, overwrite=False, **cas_kwargs): """ Obtain the electronic energy for a set of reactants at infinite separation for a multi-reference electronic structure method. Since multireference methods are not size-consistent, we cannot sum the electronic energies of the two reactants from individual calculations. One could determine this energy by calculating the it where the two reactants are in the same input but the intermolecular distance is set arbitrarily large; unfortunately, this leads to convergence issues. To resulve this, the following approach is used: 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 scn = thy for optimizations sp1 = low-spin single points sp2 = high-spin single points for inf sep inf = spc0 + spc1 - hs_sr_e + hs_mr_ene """ # Set groups for loops hs_thy_infs = (hs_var_sp2_thy_info, hs_var_sp1_thy_info) thy_infs = (var_sp2_thy_info, var_sp1_thy_info) method_dcts = (var_sp2_method_dct, var_sp1_method_dct) # Calculate the energies for the two cases for idx, (meth_dct, thy_inf) in enumerate(zip(method_dcts, hs_thy_infs)): if idx == 0: ioprinter.info_message( " - Running high-spin single reference energy ...") else: ioprinter.info_message( " - Running high-spin multi reference energy ...") ioprinter.info_message(' - Method:', tinfo.string(var_scn_thy_info, thy_inf)) # Calculate the single point energy script_str, kwargs = qchem_params(meth_dct) cas_kwargs.update(kwargs) geo = scn_save_fs[-1].file.geometry.read(inf_locs) zma = scn_save_fs[-1].file.zmatrix.read(inf_locs) # geo = automol.zmat.geometry(ref_zma) sp.run_energy(zma, geo, hs_info, thy_inf, scn_run_fs, scn_save_fs, inf_locs, run_prefix, script_str, overwrite, highspin=True, **cas_kwargs) # Read the energty from the filesystem geo_save_path = scn_save_fs[-1].path(inf_locs) hs_save_fs = autofile.fs.high_spin(geo_save_path) if not hs_save_fs[-1].file.energy.exists(thy_inf[1:4]): ioprinter.error_message( 'High-spin energy job failed: ', 'energy is needed to evaluate infinite separation energy') ene = None else: ene = hs_save_fs[-1].file.energy.read(thy_inf[1:4]) if idx == 0: hs_sr_ene = ene else: hs_mr_ene = ene # Get the single reference energy for each of the reactant configurations ioprinter.info_message('') ioprinter.info_message( 'Running single-point calculations for reactants (need DFT)...') ioprinter.info_message('Method:', tinfo.string(thy_info, var_sp2_thy_info)) sp_script_str, kwargs = qchem_params(var_sp2_method_dct) reac_ene = _reac_sep_ene(rct_info, var_sp2_thy_info, rcts_cnf_fs, run_prefix, overwrite, sp_script_str, **kwargs) # Calculate the infinite seperation energy all_enes = (reac_ene, hs_sr_ene, hs_mr_ene) if all(ene is not None for ene in all_enes): _inf_sep_ene = reac_ene - hs_sr_ene + hs_mr_ene ioprinter.info_message('Infinite Separation Energy [au]: ' f'{_inf_sep_ene}') else: _inf_sep_ene = None print('inf ene components') print('reac', reac_ene) print('hs sr', hs_sr_ene) print('hs mr', hs_mr_ene) return _inf_sep_ene
def conformer_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ Launch tasks associated with conformers. Scan: Generate a set of conformer geometries and energies via random sampling over torsional coordinates following by optimization SP: Calculate ene, grad, .. """ saddle = bool('ts_' in spc_name) spc_dct_i = spc_dct[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']) zrxn = spc_dct_i.get('zrxn', None) overwrite = es_keyword_dct['overwrite'] retryfail = es_keyword_dct['retryfail'] # 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) # New 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) if job == 'samp': # Build the ini zma filesys ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_locs, ini_min_cnf_path = ini_loc_info ini_min_rid, ini_min_cid = ini_locs ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path) # Set up the run scripts script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) # Set variables if it is a saddle two_stage = saddle mc_nsamp = spc_dct_i['mc_nsamp'] resave = es_keyword_dct['resave'] # Read the geometry and zma from the ini file system geo = ini_cnf_save_fs[-1].file.geometry.read(ini_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read([0]) # Read the torsions from the ini file sys if ini_zma_save_fs[-1].file.torsions.exists([0]): tors_dct = ini_zma_save_fs[-1].file.torsions.read([0]) rotors = automol.rotor.from_data(zma, tors_dct) tors_names = automol.rotor.names(rotors, flat=True) else: tors_names = () geo_path = ini_cnf_save_fs[-1].path(ini_locs) ioprinter.initial_geom_path('Sampling started', geo_path) # Check runsystem for equal ring CONF make conf_fs # Else make new ring conf directory rid = conformer.rng_loc_for_geo(geo, cnf_run_fs, cnf_save_fs) if rid is None: conformer.single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=retryfail, zrxn=zrxn, **kwargs) rid = conformer.rng_loc_for_geo(geo, cnf_run_fs, cnf_save_fs) # Run the sampling conformer.conformer_sampling(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, rid, script_str, overwrite, nsamp_par=mc_nsamp, tors_names=tors_names, zrxn=zrxn, two_stage=two_stage, retryfail=retryfail, resave=resave, **kwargs) elif job == 'pucker': # Build the ini zma filesys ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_min_locs, ini_min_cnf_path = ini_loc_info ini_min_rid, ini_min_cid = ini_min_locs ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path) # Set up the run scripts script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) # Set variables if it is a saddle two_stage = saddle mc_nsamp = spc_dct_i['mc_nsamp'] # Read the geometry and zma from the ini file system geo = ini_cnf_save_fs[-1].file.geometry.read(ini_min_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read([0]) # Read the torsions from the ini file sys if ini_zma_save_fs[-1].file.ring_torsions.exists([0]): ring_tors_dct = ini_zma_save_fs[-1].file.ring_torsions.read([0]) else: ring_tors_dct = {} geo_path = ini_cnf_save_fs[-1].path(ini_min_locs) ioprinter.initial_geom_path('Sampling started', geo_path) # Run the sampling conformer.ring_conformer_sampling(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, nsamp_par=mc_nsamp, ring_tors_dct=ring_tors_dct, zrxn=zrxn, two_stage=two_stage, retryfail=retryfail, **kwargs) elif job == 'opt': cnf_range = es_keyword_dct['cnf_range'] ioprinter.debug_message('range', cnf_range) # Set up the run scripts script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_min_locs, ini_min_cnf_path = ini_loc_info ini_min_rid, ini_min_cid = ini_min_locs rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators( cnf_save_fs, mod_thy_info, cnf_range='all') ini_rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators( ini_cnf_save_fs, mod_ini_thy_info, cnf_range=cnf_range) # Truncate the list of the ini confs uni_rng_locs_lst, uni_cnf_locs_lst = conformer.unique_fs_ring_confs( cnf_save_fs, rng_cnf_locs_lst, ini_cnf_save_fs, ini_rng_cnf_locs_lst) ioprinter.debug_message('uni lst that has no similar ring', uni_rng_locs_lst) ioprinter.debug_message('uni lst that has similar ring', uni_cnf_locs_lst) for locs in uni_rng_locs_lst: rid, cid = locs # Obtain the zma from ini loc ini_cnf_save_path = ini_cnf_save_fs[-1].path(locs) ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) # Make the ring filesystem conformer.single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=retryfail, zrxn=zrxn, use_locs=locs, **kwargs) for locs in uni_cnf_locs_lst: ini_locs, rid = locs ini_rid, ini_cid = ini_locs # Obtain the zma from ini loc ini_cnf_save_path = ini_cnf_save_fs[-1].path(ini_locs) ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) # obtain conformer filesystem associated with the ring at the runlevel 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, cid), **kwargs) rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators( cnf_save_fs, mod_thy_info, cnf_range=cnf_range) for locs in rng_cnf_locs_lst: geo = cnf_save_fs[-1].file.geometry.read(locs) ioprinter.geometry(geo) elif job in ('energy', 'grad', 'hess', 'vpt2', 'prop'): cnf_range = es_keyword_dct['cnf_range'] ini_rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators( ini_cnf_save_fs, mod_ini_thy_info, cnf_range=cnf_range) # Check if locs exist, kill if it doesn't if not ini_rng_cnf_locs_lst: ioprinter.error_message('No min-energy conformer found for level:') sys.exit() # Set up the run scripts script_str, kwargs = qchem_params(method_dct) # Run the job over all the conformers requested by the user for ini_locs in ini_rng_cnf_locs_lst: ini_rid, ini_cid = ini_locs ioprinter.running('task for conformer: ', ini_locs, newline=2) ini_cnf_run_fs[-1].create(ini_locs) geo_run_path = ini_cnf_run_fs[-1].path(ini_locs) geo_save_path = ini_cnf_save_fs[-1].path(ini_locs) ini_zma_save_fs = autofile.fs.zmatrix(geo_save_path) ioprinter.debug_message('reading geometry from ', geo_save_path) geo = ini_cnf_save_fs[-1].file.geometry.read(ini_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) ES_TSKS[job](zma, geo, spc_info, mod_thy_info, ini_cnf_save_fs, geo_run_path, geo_save_path, ini_locs, script_str, overwrite, retryfail=retryfail, **kwargs)
def _run_potentials(ts_info, scan_inf_dct, thy_inf_dct, thy_method_dct, mref_params, es_keyword_dct, runfs_dct, savefs_dct): """ Run and save the scan along both grids while (1) optimization: constraining only reaction coordinate, then (2) optimization: constraining all intermolecular coordinates (3) single-point energy on scan (1) """ # Get fs and method objects scn_run_fs = runfs_dct['vscnlvl_scn'] scn_save_fs = savefs_dct['vscnlvl_scn'] cscn_run_fs = runfs_dct['vscnlvl_cscn'] cscn_save_fs = savefs_dct['vscnlvl_cscn'] sp_scn_save_fs = savefs_dct['vscnlvl_scn'] scn_thy_info = thy_inf_dct['mod_var_scnlvl'] sp_thy_info = thy_inf_dct['mod_var_splvl1'] opt_script_str, opt_kwargs = qchem_params( thy_method_dct['var_scnlvl'], elstruct.Job.OPTIMIZATION) cas_kwargs = mref_params['var_scnlvl'] opt_kwargs.update(cas_kwargs) sp_script_str, sp_kwargs = qchem_params( thy_method_dct['var_splvl1']) sp_cas_kwargs = mref_params['var_splvl1'] sp_kwargs.update(sp_cas_kwargs) # Run optimization scans for constraints in (None, scan_inf_dct['constraint_dct']): if constraints is None: _run_fs = scn_run_fs _save_fs = scn_save_fs info_message('Running full scans..', newline=1) else: _run_fs = cscn_run_fs _save_fs = cscn_save_fs info_message('Running constrained scans..', newline=1) thy_inf_str = tinfo.string(scn_thy_info) info_message('Method:', tinfo.string(scn_thy_info)) # Loop over grids (both should start at same point and go in and out) for grid in scan_inf_dct['coord_grids']: info_message(f'Grid: {grid}') scan.execute_scan( zma=scan_inf_dct['inf_sep_zma'], spc_info=ts_info, mod_thy_info=thy_inf_dct['mod_var_scnlvl'], coord_names=scan_inf_dct['coord_names'], coord_grids=(grid,), scn_run_fs=_run_fs, scn_save_fs=_save_fs, scn_typ='relaxed', script_str=opt_script_str, overwrite=es_keyword_dct['overwrite'], update_guess=scan_inf_dct['update_guess'], reverse_sweep=False, saddle=False, constraint_dct=constraints, retryfail=True, **cas_kwargs ) info_message('') # Run the single points on top of the initial, full scan if sp_thy_info is not None: info_message('') info_message('Running single-point calculations on the full scan...') info_message('Method:', tinfo.string(scn_thy_info, sp_thy_info)) for locs in scn_save_fs[-1].existing((scan_inf_dct['coord_names'],)): scn_run_fs[-1].create(locs) geo = scn_save_fs[-1].file.geometry.read(locs) zma = scn_save_fs[-1].file.zmatrix.read(locs) sp.run_energy(zma, geo, ts_info, sp_thy_info, scn_run_fs, scn_save_fs, locs, runfs_dct['prefix'], sp_script_str, es_keyword_dct['overwrite'], highspin=False, **sp_kwargs)
def conformer_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix, print_debug=False): """ Prepares and executes all electronic structure tasks that generate information for species and transition state conformers. This includes sampling and optimization procedures to generate conformer structures, as well as __ calculations using some saved conformer as input. :param job(subtask): calculatiion(s) to perform for conformer :type job: str :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-values 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 """ saddle = bool('ts_' in spc_name) spc_dct_i = spc_dct[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']) zrxn = spc_dct_i.get('zrxn', None) overwrite = es_keyword_dct['overwrite'] retryfail = es_keyword_dct['retryfail'] 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) # New 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) if job == 'samp': # Build the ini zma filesys user_conf_ids = spc_dct_i.get('conf_id') if user_conf_ids is None: ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_locs, ini_min_cnf_path = ini_loc_info else: print(f'Using user specified conformer IDs: {user_conf_ids}') ini_locs = user_conf_ids if any(ini_locs): ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path) # Set up the run scripts script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) # Set variables if it is a saddle two_stage = saddle mc_nsamp = spc_dct_i['mc_nsamp'] resave = es_keyword_dct['resave'] # Read the geometry and zma from the ini file system geo = ini_cnf_save_fs[-1].file.geometry.read(ini_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read([0]) # Read the torsions from the ini file sys if ini_zma_save_fs[-1].file.torsions.exists([0]): tors_dct = ini_zma_save_fs[-1].file.torsions.read([0]) rotors = automol.rotor.from_data(zma, tors_dct) tors_names = automol.rotor.names(rotors, flat=True) else: tors_names = () geo_path = ini_cnf_save_fs[-1].path(ini_locs) ioprinter.initial_geom_path('Sampling started', geo_path) # Check runsystem for equal ring CONF make conf_fs # Else make new ring conf directory rid = conformer.rng_loc_for_geo(geo, cnf_save_fs) if rid is None: conformer.single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=retryfail, zrxn=zrxn, **kwargs) rid = conformer.rng_loc_for_geo(geo, cnf_save_fs) # Run the sampling conformer.conformer_sampling(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, rid, script_str, overwrite, nsamp_par=mc_nsamp, tors_names=tors_names, zrxn=zrxn, two_stage=two_stage, retryfail=retryfail, resave=resave, repulsion_thresh=40.0, print_debug=print_debug, **kwargs) else: ioprinter.info_message('Missing conformers. Skipping task...') elif job == 'pucker': # Build the ini zma filesys ini_loc_info = filesys.mincnf.min_energy_conformer_locators( ini_cnf_save_fs, mod_ini_thy_info) ini_min_locs, ini_min_cnf_path = ini_loc_info ini_zma_save_fs = autofile.fs.zmatrix(ini_min_cnf_path) # Set up the run scripts script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) # Set variables if it is a saddle two_stage = saddle mc_nsamp = spc_dct_i['mc_nsamp'] # Read the geometry and zma from the ini file system geo = ini_cnf_save_fs[-1].file.geometry.read(ini_min_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read([0]) # Read the torsions from the ini file sys if ini_zma_save_fs[-1].file.ring_torsions.exists([0]): ring_tors_dct = ini_zma_save_fs[-1].file.ring_torsions.read([0]) else: ring_tors_dct = {} geo_path = ini_cnf_save_fs[-1].path(ini_min_locs) ioprinter.initial_geom_path('Sampling started', geo_path) # Run the sampling conformer.ring_conformer_sampling(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, nsamp_par=mc_nsamp, ring_tors_dct=ring_tors_dct, zrxn=zrxn, two_stage=two_stage, retryfail=retryfail, **kwargs) elif job == 'opt': cnf_range = es_keyword_dct['cnf_range'] hbond_cutoffs = spc_dct_i['hbond_cutoffs'] cnf_sort_info_lst = _sort_info_lst(es_keyword_dct['sort'], thy_dct, spc_info) # Set up the run scripts script_str, kwargs = qchem_params(method_dct, elstruct.Job.OPTIMIZATION) rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators( cnf_save_fs, mod_thy_info, cnf_range='all', nprocs=nprocs) ini_rng_cnf_locs_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) # Truncate the list of the ini confs uni_rng_locs_lst, uni_cnf_locs_lst = conformer.unique_fs_ring_confs( cnf_save_fs, rng_cnf_locs_lst, ini_cnf_save_fs, ini_rng_cnf_locs_lst) # ioprinter.debug_message( # 'uni lst that has no similar ring', uni_rng_locs_lst) # ioprinter.debug_message( # 'uni lst that has similar ring', uni_cnf_locs_lst) for locs in uni_rng_locs_lst: rid, cid = locs # Obtain the zma from ini loc ini_cnf_save_path = ini_cnf_save_fs[-1].path(locs) ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) # Make the ring filesystem conformer.single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=retryfail, zrxn=zrxn, use_locs=locs, **kwargs) for locs in uni_cnf_locs_lst: ini_locs, rid = locs # Obtain the zma from ini loc ini_cnf_save_path = ini_cnf_save_fs[-1].path(ini_locs) ini_zma_save_fs = autofile.fs.zmatrix(ini_cnf_save_path) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) # obtain conformer filesys associated with ring at the runlevel 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, cid), **kwargs) # print all geometres within cnfrange rng_cnf_locs_lst, _ = filesys.mincnf.conformer_locators( cnf_save_fs, mod_thy_info, cnf_range=cnf_range, sort_info_lst=cnf_sort_info_lst, hbond_cutoffs=hbond_cutoffs, nprocs=nprocs) for locs in rng_cnf_locs_lst: geo = cnf_save_fs[-1].file.geometry.read(locs) ioprinter.geometry(geo) elif job in ('energy', 'grad', 'hess', 'vpt2', 'prop'): cnf_range = es_keyword_dct['cnf_range'] hbond_cutoffs = spc_dct_i['hbond_cutoffs'] cnf_sort_info_lst = _sort_info_lst(es_keyword_dct['sort'], thy_dct, spc_info) user_conf_ids = spc_dct_i.get('conf_id') if user_conf_ids is None: ini_rng_cnf_locs_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: print(f'Using user specified conformer IDs: {user_conf_ids}') ini_rng_cnf_locs_lst = (user_conf_ids, ) # Check if locs exist, kill if it doesn't if not ini_rng_cnf_locs_lst: ioprinter.error_message('No min-energy conformer found for level:') else: # Set up the run scripts script_str, kwargs = qchem_params(method_dct) # Grab frequencies for the reference, print ref freqs if job == 'hess': if ini_cnf_save_fs[-1].file.harmonic_frequencies.exists( ini_rng_cnf_locs_lst[0]): frq = ini_cnf_save_fs[-1].file.harmonic_frequencies.read( ini_rng_cnf_locs_lst[0]) ref_val = frq else: ref_val = None if ref_val is not None and zrxn is not None: ref_path = cnf_save_fs[-1].path(ini_rng_cnf_locs_lst[0]) print('Found reference frequencies for saddle-point ' f'checks for conformer at\n {ref_path}') ioprinter.frequencies(ref_val) else: ref_val = None # Run the job over all the conformers requested by the user print('Going over all requested conformers for task...\n') for ini_locs in ini_rng_cnf_locs_lst: ini_cnf_run_fs[-1].create(ini_locs) geo_save_path = ini_cnf_save_fs[-1].path(ini_locs) ini_zma_save_fs = autofile.fs.zmatrix(geo_save_path) print('Running task for geometry at ', geo_save_path) geo = ini_cnf_save_fs[-1].file.geometry.read(ini_locs) zma = ini_zma_save_fs[-1].file.zmatrix.read((0, )) ES_TSKS[job](zma, geo, spc_info, mod_thy_info, ini_cnf_run_fs, ini_cnf_save_fs, ini_locs, run_prefix, script_str, overwrite, zrxn=zrxn, retryfail=retryfail, method_dct=method_dct, ref_val=ref_val, **kwargs) print('\n === FINISHED CONF ===\n')