def single_conformer(spc_info, thy_level, filesys, overwrite, saddle=False, dist_info=()): """ generate single optimized geometry for randomly sampled initial torsional angles """ mc_nsamp = [False, 0, 0, 0, 0, 1] sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_level[0:2]) thy_save_fs = filesys[3] two_stage = False if saddle: two_stage = True conformer_sampling( spc_info=spc_info, thy_level=thy_level, thy_save_fs=thy_save_fs, cnf_run_fs=filesys[4], cnf_save_fs=filesys[5], script_str=sp_script_str, overwrite=overwrite, nsamp_par=mc_nsamp, saddle=saddle, dist_info=dist_info, two_stage=two_stage, **kwargs, )
def geometry_analysis(tsk, thy_level, ini_filesys, spc, overwrite, saddle=False, selection='min'): """ run the specified electronic structure task for a set of geometries """ params = {} spc_info = finf.get_spc_info(spc) print('Task:', tsk) if 'conf' in tsk: run_dir = ini_filesys[2] save_dir = ini_filesys[3] elif 'tau' in tsk: run_dir = ini_filesys[4] save_dir = ini_filesys[5] elif 'hr' in tsk: run_dir = ini_filesys[6] save_dir = ini_filesys[7] if saddle: params['frm_bnd_key'] = spc['frm_bnd_key'] params['brk_bnd_key'] = spc['brk_bnd_key'] print('key test in ts_geom anal:', params['frm_bnd_key'], params['brk_bnd_key']) else: return if isinstance(selection, str): if selection == 'all': locs_lst = save_dir.leaf.existing() elif selection == 'min': locs_lst = [fsmin.min_energy_conformer_locators(save_dir)] else: locs_lst = selection sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_level[0:2]) params['spc_info'] = spc_info params['thy_level'] = thy_level params['script_str'] = sp_script_str params['overwrite'] = overwrite # cycle over the locations if tsk in ES_TSKS: task_call = eval(ES_TSKS[tsk]) for locs in locs_lst: if locs: params['geo_run_fs'] = run_dir params['geo_save_fs'] = save_dir params['locs'] = locs task_call(params, kwargs) else: print('No initial geometry available for {} on {}'.format( spc_info[0], '/'.join(thy_level[1:3])))
def remove_imag(spc_dct_i, geo, thy_level, thy_run_fs, run_fs, kickoff_size=0.1, kickoff_backward=False, overwrite=False): """ if there is an imaginary frequency displace geometry along the imaginary mode and then reoptimize """ # projrot_script_str = script.PROJROT print('the initial geometries will be checked for imaginary frequencies') spc_info = finf.get_spc_info(spc_dct_i) script_str, opt_script_str, kwargs, opt_kwargs = runpar.run_qchem_par( *thy_level[0:2]) imag, geo, disp_xyzs, hess = run_check_imaginary(spc_info, geo, thy_level, thy_run_fs, script_str, overwrite, **kwargs) chk_idx = 0 while imag and chk_idx < 5: chk_idx += 1 print('imaginary frequency detected, attempting to kick off') geo = run_kickoff_saddle(geo, disp_xyzs, spc_info, thy_level, run_fs, thy_run_fs, opt_script_str, kickoff_size, kickoff_backward, opt_cart=True, **opt_kwargs) print('removing saddlepoint hessian') thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) run_fs = autofile.fs.run(thy_run_path) run_fs.leaf.remove([elstruct.Job.HESSIAN]) imag, geo, disp_xyzs, hess = run_check_imaginary( spc_info, geo, thy_level, thy_run_fs, script_str, overwrite, **kwargs) return geo, hess
def sadpt_reference_geometry(spcdct, thy_level, ini_thy_level, geo_fs, ini_fs, dist_info=(), overwrite=False): """ determine what to use as the reference geometry for all future runs If ini_thy_info refers to geometry dictionary then use that, otherwise values are from a hierarchy of: running level of theory, input level of theory, inchis. From the hierarchy an optimization is performed followed by a check for an imaginary frequency and then a conformer file system is set up. """ thy_save_fs = geo_fs[3] ini_thy_save_fs = ini_fs[1] run_fs = geo_fs[-1] print('initializing geometry') geo = None geo_init = None # Check to see if geometry should be obtained from dictionary spc_info = [spcdct['ich'], spcdct['chg'], spcdct['mul']] if 'input_geom' in ini_thy_level: geom_obj = spcdct['geoobj'] geo_init = geom_obj overwrite = True print('found initial geometry from geometry dictionary') else: # Check to see if geo already exists at running_theory if thy_save_fs.trunk.file.geometry.exists(): thy_path = thy_save_fs.trunk.path() print('getting reference geometry from {}'.format(thy_path)) geo = thy_save_fs.trunk.file.geometry.read() zma = thy_save_fs.trunk.file.zmatrix.read() # print('geo:',automol.geom.string(geo)) if not geo: if ini_thy_save_fs: if ini_thy_save_fs.trunk.file.geometry.exists(): thy_path = ini_thy_save_fs.trunk.path() print( 'getting reference geometry from {}'.format(thy_path)) zma_init = ini_thy_save_fs.trunk.file.zmatrix.read() geo_init = ini_thy_save_fs.trunk.file.geometry.read() if not geo and geo_init: _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par( *thy_level[0:2]) driver.run_job( job='optimization', script_str=opt_script_str, run_fs=run_fs, geom=zma_init, spc_info=spc_info, thy_level=thy_level, saddle=True, overwrite=overwrite, **opt_kwargs, ) opt_ret = driver.read_job( job='optimization', run_fs=run_fs, ) if opt_ret is not None: inf_obj, _, out_str = opt_ret prog = inf_obj.prog method = inf_obj.method ene = elstruct.reader.energy(prog, method, out_str) geo = elstruct.reader.opt_geometry(prog, out_str) zma = elstruct.reader.opt_zmatrix(prog, out_str) if geo: print(" - Saving...") print(" - Save path: {}".format(thy_save_fs.trunk.path())) thy_save_fs.trunk.file.energy.write(ene) thy_save_fs.trunk.file.geometry.write(geo) thy_save_fs.trunk.file.zmatrix.write(zma) conformer.single_conformer(spc_info, thy_level, geo_fs, overwrite, True, dist_info) return geo
def find_ts(spc_dct, ts_dct, ts_zma, ini_thy_info, thy_info, run_prefix, save_prefix, overwrite, rad_rad_ts='vtst'): """ find the ts geometry """ # Set various TS information using the dictionary typ = ts_dct['class'] dist_info = ts_dct['dist_info'] grid = ts_dct['grid'] bkp_ts_class_data = ts_dct['bkp_data'] rad_rad = ('radical radical' in typ) low_spin = ('low spin' in typ) print('prepping ts scan for:', typ) [_, _, rxn_run_path, rxn_save_path] = ts_dct['rxn_fs'] ts_info = (ts_dct['ich'], ts_dct['chg'], ts_dct['mul']) _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(*thy_info[0:2]) orb_restr = fsorb.orbital_restriction(ts_info, thy_info) ref_level = thy_info[0:3] ref_level.append(orb_restr) thy_run_fs = autofile.fs.theory(rxn_run_path) thy_run_fs.leaf.create(ref_level[1:4]) thy_run_path = thy_run_fs.leaf.path(ref_level[1:4]) thy_save_fs = autofile.fs.theory(rxn_save_path) thy_save_fs.leaf.create(ref_level[1:4]) thy_save_path = thy_save_fs.leaf.path(ref_level[1:4]) scn_run_fs = autofile.fs.scan(thy_run_path) scn_save_fs = autofile.fs.scan(thy_save_path) ts_run_fs = autofile.fs.ts(thy_run_path) ts_run_fs.trunk.create() ts_run_path = ts_run_fs.trunk.path() run_fs = autofile.fs.run(ts_run_path) ts_save_fs = autofile.fs.ts(thy_save_path) ts_save_fs.trunk.create() ts_save_path = ts_save_fs.trunk.path() cnf_run_fs = autofile.fs.conformer(ts_run_path) cnf_save_fs = autofile.fs.conformer(ts_save_path) cnf_save_fs.trunk.create() # Unpack the dist info dist_name, _, update_guess, brk_name = dist_info # Get TS from filesys or get it from some procedure min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs) if min_cnf_locs and not overwrite: check_filesys_for_ts(ts_dct, ts_zma, cnf_save_fs, overwrite, typ, dist_info, dist_name, bkp_ts_class_data) else: filesys = [ None, None, ts_run_fs, ts_save_fs, cnf_run_fs, cnf_save_fs, None, None, scn_run_fs, scn_save_fs, run_fs ] print('running ts scan:') if rad_rad and low_spin and 'elimination' not in ts_dct['class']: print('Running Scan for Barrierless TS:') find_barrierless_transition_state( ts_info, ts_zma, ts_dct, spc_dct, grid, dist_name, rxn_run_path, rxn_save_path, rad_rad_ts, ini_thy_info, thy_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess, **opt_kwargs) # Have code analyze the path and switch to a sadpt finder if needed else: print('Running Scan for Fixed TS:') max_zma = run_sadpt_scan(typ, grid, dist_name, brk_name, ts_zma, ts_info, ref_level, scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess, **opt_kwargs) geo, zma, final_dist = find_sadpt_transition_state( opt_script_str, run_fs, max_zma, ts_info, ref_level, overwrite, ts_save_path, ts_save_fs, dist_name, dist_info, filesys, **opt_kwargs) return geo, zma, final_dist
def geometry_generation(tsk, spc, mc_nsamp, ini_thy_level, thy_level, ini_filesys, filesys, overwrite, saddle=False, kickoff=(0.1, False), tors_model=('1dhr', False)): """ run an electronic structure task for generating a list of conformer or tau sampling geometries """ # Separate the kickoff keyword for now [kickoff_size, kickoff_backward] = kickoff spc_info = finf.get_spc_info(spc) # Get a reference geometry if not saddle: geo = geom.reference_geometry(spc, thy_level, ini_thy_level, filesys, ini_filesys, kickoff_size=kickoff_size, kickoff_backward=kickoff_backward, overwrite=overwrite) else: geo = ts.sadpt_reference_geometry(spc, thy_level, ini_thy_level, filesys, ini_filesys, spc['dist_info'], overwrite) if geo: print('Task:', tsk) _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par( *thy_level[0:2]) params = { 'spc_info': spc_info, 'thy_level': thy_level, 'script_str': opt_script_str, 'overwrite': overwrite } if saddle: params['saddle'] = True params['tors_names'] = spc['tors_names'] if tsk in ['conf_samp', 'tau_samp']: params['nsamp_par'] = mc_nsamp if saddle: params['dist_info'] = spc['dist_info'] params['two_stage'] = True params['rxn_class'] = spc['class'] elif tsk in ['hr_scan']: params['tors_model'] = tors_model if 'hind_def' in spc: params['run_tors_names'] = spc['hind_def'] if 'hind_inc' in spc: params['scan_increment'] = spc['hind_inc'] * phycon.DEG2RAD else: params['scan_increment'] = 30. * phycon.DEG2RAD if saddle: params['frm_bnd_key'] = spc['frm_bnd_key'] params['brk_bnd_key'] = spc['brk_bnd_key'] print('key test in ts_geom gen:', params['frm_bnd_key'], params['brk_bnd_key']) if tsk in ES_TSKS: eval(ES_TSKS[tsk])(filesys, params, opt_kwargs)
def reference_geometry(spc_dct_i, thy_level, ini_thy_level, filesys, ini_filesys, kickoff_size=0.1, kickoff_backward=False, overwrite=False): """ determine what to use as the reference geometry for all future runs If ini_thy_info refers to geometry dictionary then use that, otherwise values are from a hierarchy of: running level of theory, input level of theory, inchis. From the hierarchy an optimization is performed followed by a check for an imaginary frequency and then a conformer file system is set up. """ # projrot_script_str = script.PROJROT ret = None thy_run_fs = filesys[2] thy_save_fs = filesys[3] ini_thy_save_fs = ini_filesys[1] cnf_run_fs = filesys[4] cnf_save_fs = filesys[5] run_fs = filesys[-1] if run_fs.trunk.file.info.exists([]): inf_obj = run_fs.trunk.file.info.read([]) if inf_obj.status == autofile.system.RunStatus.RUNNING: print('reference geometry already running') return ret else: prog = thy_level[0] method = thy_level[1] basis = thy_level[2] status = autofile.system.RunStatus.RUNNING inf_obj = autofile.system.info.run(job='', prog=prog, version='version', method=method, basis=basis, status=status) run_fs.trunk.file.info.write(inf_obj, []) print('initializing geometry in reference_geometry') geo = None try: # Check to see if geometry should be obtained from dictionary spc_info = [spc_dct_i['ich'], spc_dct_i['chg'], spc_dct_i['mul']] if 'input_geom' in ini_thy_level: geom_obj = spc_dct_i['geo_obj'] geo_init = geom_obj overwrite = True print('found initial geometry from geometry dictionary') else: # Check to see if geo already exists at running_theory print(thy_save_fs) if thy_save_fs.leaf.file.geometry.exists(thy_level[1:4]): thy_path = thy_save_fs.leaf.path(thy_level[1:4]) print('getting reference geometry from {}'.format(thy_path)) geo = thy_save_fs.leaf.file.geometry.read(thy_level[1:4]) if not geo: if ini_thy_save_fs: geo_exists = ini_thy_save_fs.leaf.file.geometry.exists( ini_thy_level[1:4]) if geo_exists: # If not, Compute geo at running_theory, using geo from # initial_level as the starting point # or from inchi is no initial level geometry thy_path = ini_thy_save_fs.leaf.path( ini_thy_level[1:4]) geo_init = ini_thy_save_fs.leaf.file.geometry.read( ini_thy_level[1:4]) elif 'geo_obj' in spc_dct_i: geo_init = spc_dct_i['geo_obj'] print('getting geometry from geom dictionary') else: print('getting reference geometry from inchi', spc_info[0]) geo_init = automol.inchi.geometry(spc_info[0]) print('got reference geometry from inchi', geo_init) print('getting reference geometry from inchi') elif 'geo_obj' in spc_dct_i: geo_init = spc_dct_i['geo_obj'] print('getting geometry from geom dictionary') else: geo_init = automol.inchi.geometry(spc_info[0]) print('getting reference geometry from inchi') # Optimize from initial geometry to get reference geometry if not geo: _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par( *thy_level[0:2]) params = { 'spc_info': spc_info, 'run_fs': run_fs, 'thy_run_fs': thy_run_fs, 'script_str': opt_script_str, 'overwrite': overwrite, 'thy_level': thy_level, 'ini_geo': geo_init } geo, inf = run_initial_geometry_opt(**params, **opt_kwargs) thy_save_fs.leaf.create(thy_level[1:4]) thy_save_path = thy_save_fs.leaf.path(thy_level[1:4]) ncp = len( automol.graph.connected_components(automol.geom.graph(geo))) if not automol.geom.is_atom(geo) and ncp < 2: geo, hess = remove_imag(spc_dct_i, geo, thy_level, thy_run_fs, run_fs, kickoff_size, kickoff_backward, overwrite=overwrite) tors_names = automol.geom.zmatrix_torsion_coordinate_names(geo) locs_lst = cnf_save_fs.leaf.existing() if locs_lst: saved_geo = cnf_save_fs.leaf.file.geometry.read( locs_lst[0]) saved_tors = automol.geom.zmatrix_torsion_coordinate_names( saved_geo) if tors_names != saved_tors: print("new reference geometry doesn't match original", " reference geometry") print('removing original conformer save data') cnf_run_fs.remove() cnf_save_fs.remove() print('Saving reference geometry') print(" - Save path: {}".format(thy_save_path)) thy_save_fs.leaf.file.hessian.write(hess, thy_level[1:4]) thy_save_fs.leaf.file.geometry.write(geo, thy_level[1:4]) ncp = len( automol.graph.connected_components(automol.geom.graph(geo))) if ncp < 2: zma = automol.geom.zmatrix(geo) thy_save_fs.leaf.file.zmatrix.write(zma, thy_level[1:4]) conformer.single_conformer(spc_info, thy_level, filesys, overwrite) else: print("Cannot create zmatrix for disconnected species") wells.fake_conf(thy_level, filesys, inf) if geo: inf_obj.status = autofile.system.RunStatus.SUCCESS run_fs.trunk.file.info.write(inf_obj, []) else: inf_obj.status = autofile.system.RunStatus.FAILURE run_fs.trunk.file.info.write(inf_obj, []) except IOError: inf_obj.status = autofile.system.RunStatus.FAILURE run_fs.trunk.file.info.write(inf_obj, []) return geo
def run_multiref_rscan(formula, high_mul, zma, spc_info, multi_level, dist_name, grid1, grid2, scn_run_fs, scn_save_fs, overwrite, update_guess=True, gradient=False, hessian=False, num_act_elc=None, num_act_orb=None, alt_constraints=()): """ run constrained optimization scan """ vma = automol.zmatrix.var_(zma) if scn_save_fs.trunk.file.vmatrix.exists(): existing_vma = scn_save_fs.trunk.file.vmatrix.read() assert vma == existing_vma grid = numpy.append(grid1, grid2) grid_dct = {dist_name: grid} if len(grid_dct) > 1: raise NotImplementedError coo_names = [] grid_vals = [] for item in grid_dct.items(): (coo, coo_grid_vals) = item coo_names.append(coo) grid_vals.append(coo_grid_vals) scn_save_fs.branch.create([coo_names]) inf_obj = autofile.system.info.scan_branch(grid_dct) scn_save_fs.branch.file.info.write(inf_obj, [coo_names]) prog = multi_level[0] method = multi_level[1] _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(prog, method) ref_zma = automol.zmatrix.set_values(zma, {coo_names[0]: grid_vals[0][0]}) # Build the elstruct CASSCF options list for multiref calcs cas_opt = [] cas_opt.append( variational.wfn.cas_options(spc_info, formula, num_act_elc, num_act_orb, high_mul, add_two_closed=False)) cas_opt.append( variational.wfn.cas_options(spc_info, formula, num_act_elc, num_act_orb, high_mul, add_two_closed=True)) # Write the lines containing all the calcs for a guess wfn guess_str = variational.wfn.multiref_wavefunction_guess( high_mul, ref_zma, spc_info, multi_level, cas_opt) guess_lines = guess_str.splitlines() # Add the above-built objects to the elstruct opt_kwargs dct opt_kwargs['casscf_options'] = cas_opt[1] opt_kwargs['gen_lines'] = {1: guess_lines} # Add option to opt_kwargs dct to turn off symmetry opt_kwargs['mol_options'] = ['nosym'] # Setup and run the first part of the scan to shorter distances coo_names = [] grid1_vals = [] grid1_dct = {dist_name: grid1} for item in grid1_dct.items(): (coo, coo_grid1_vals) = item coo_names.append(coo) grid1_vals.append(coo_grid1_vals) npoint = 1 for coo_grid1_vals in grid1_vals: npoint *= len(coo_grid1_vals) grid1_idxs = tuple(range(npoint)) if len(grid1_vals) == 1: for grid1_val in grid1_vals[0]: scn_run_fs.leaf.create([coo_names, [grid1_val]]) run_prefixes = tuple( scn_run_fs.leaf.path([coo_names, [grid1_val]]) for grid1_val in grid1_vals[0]) _run_1d_scan( script_str=opt_script_str, run_prefixes=run_prefixes, scn_save_fs=scn_save_fs, guess_zma=zma, coo_name=coo_names[0], grid_idxs=grid1_idxs, grid_vals=grid1_vals[0], spc_info=spc_info, thy_level=multi_level, overwrite=overwrite, update_guess=update_guess, gradient=gradient, hessian=hessian, alt_constraints=alt_constraints, **opt_kwargs, ) # Setup and run the second part of the scan to longer distances coo_names = [] grid2_vals = [] grid2_dct = {dist_name: grid2} for item in grid2_dct.items(): (coo, coo_grid2_vals) = item coo_names.append(coo) grid2_vals.append(coo_grid2_vals) npoint = 1 for coo_grid2_vals in grid2_vals: npoint *= len(coo_grid2_vals) grid2_idxs = tuple(range(npoint)) if len(grid2_vals) == 1: for grid2_val in grid2_vals[0]: scn_run_fs.leaf.create([coo_names, [grid2_val]]) run_prefixes = tuple( scn_run_fs.leaf.path([coo_names, [grid2_val]]) for grid2_val in grid2_vals[0]) _run_1d_scan( script_str=opt_script_str, run_prefixes=run_prefixes, scn_save_fs=scn_save_fs, guess_zma=zma, coo_name=coo_names[0], grid_idxs=grid2_idxs, grid_vals=grid2_vals[0], spc_info=spc_info, thy_level=multi_level, overwrite=overwrite, update_guess=update_guess, gradient=gradient, hessian=hessian, alt_constraints=alt_constraints, **opt_kwargs, )
def infinite_separation_energy(spc_1_info, spc_2_info, ts_info, high_mul, ref_zma, ini_thy_info, thy_info, multi_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs, locs, overwrite=False, num_act_elc=None, num_act_orb=None): """ Obtain the infinite separation energy from the multireference energy at a given reference point, the high-spin low-spin splitting at that reference point, and the high level energy for the high spin state at the reference geometry and for the fragments """ # Initialize infinite sep energy inf_sep_ene = -1.0e12 # set up all the file systems for the TS # start with the geo and reference theory info geo_run_path = scn_run_fs.leaf.path(locs) geo_save_path = scn_save_fs.leaf.path(locs) geo = scn_save_fs.leaf.file.geometry.read(locs) sp_run_fs = autofile.fs.single_point(geo_run_path) sp_save_fs = autofile.fs.single_point(geo_save_path) # get the multi reference ene for low spin state for the ref point on scan # file system for low spin multireference calculation multi_info[0] = 'molpro2015' multi_info[1] = 'caspt2' # ultimately the above should be properly passed prog = multi_info[0] method = multi_info[1] # get the multi reference energy for high spin state for ref point on scan hs_info = (ts_info[0], ts_info[1], high_mul) orb_restr = fsorb.orbital_restriction(hs_info, multi_info) multi_lvl = multi_info[0:3] multi_lvl.append(orb_restr) hs_run_fs = autofile.fs.high_spin(geo_run_path) hs_save_fs = autofile.fs.high_spin(geo_save_path) hs_run_fs.leaf.create(multi_lvl[1:4]) hs_save_fs.leaf.create(multi_lvl[1:4]) hs_mr_run_path = hs_run_fs.leaf.path(multi_lvl[1:4]) hs_mr_save_path = hs_save_fs.leaf.path(multi_lvl[1:4]) run_mr_fs = autofile.fs.run(hs_mr_run_path) mr_script_str, _, mr_kwargs, _ = runpar.run_qchem_par(prog, method) if num_act_elc is None and num_act_orb is None: num_act_elc = high_mul num_act_orb = num_act_elc ts_formula = automol.geom.formula(automol.zmatrix.geometry(ref_zma)) cas_opt, _ = ts.cas_options_2(hs_info, ts_formula, num_act_elc, num_act_orb, high_mul) guess_str = ts.multiref_wavefunction_guess(high_mul, ref_zma, hs_info, multi_lvl, [cas_opt]) guess_lines = guess_str.splitlines() mr_kwargs['casscf_options'] = cas_opt mr_kwargs['mol_options'] = ['nosym'] mr_kwargs['gen_lines'] = {1: guess_lines} ret = driver.read_job( job='energy', run_fs=run_mr_fs, ) if ret: print(" - Reading high spin multi reference energy from output...") inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) hs_save_fs.leaf.file.energy.write(ene, multi_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4]) if not hs_save_fs.leaf.file.energy.exists(multi_lvl[1:4]) or overwrite: print(" - Running high spin multi reference energy ...") driver.run_job( job='energy', script_str=mr_script_str, run_fs=run_mr_fs, geom=geo, spc_info=hs_info, thy_level=multi_lvl, overwrite=overwrite, **mr_kwargs, ) ret = driver.read_job( job='energy', run_fs=run_mr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading high spin multi reference energy from output...") hs_mr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving high spin multi reference energy...") print(" - Save path: {}".format(hs_mr_save_path)) hs_save_fs.leaf.file.energy.write(hs_mr_ene, multi_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4]) else: print('ERROR: high spin multi reference energy job fails: ', 'Energy is needed to evaluate infinite separation energy') return inf_sep_ene else: hs_mr_ene = hs_save_fs.leaf.file.energy.read(multi_lvl[1:4]) # file system for high spin single ireference calculation thy_info = ['molpro2015', 'ccsd(t)-f12', 'cc-pvdz-f12', 'RR'] orb_restr = fsorb.orbital_restriction(hs_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) hs_run_fs.leaf.create(thy_lvl[1:4]) hs_save_fs.leaf.create(thy_lvl[1:4]) hs_sr_run_path = hs_run_fs.leaf.path(thy_lvl[1:4]) hs_sr_save_path = hs_save_fs.leaf.path(thy_lvl[1:4]) run_sr_fs = autofile.fs.run(hs_sr_run_path) sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_lvl[0:2]) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret: print(" - Reading high spin single reference energy from output...") inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) hs_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) if not hs_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite: print(" - Running high spin single reference energy ...") errors, options_mat = runpar.set_molpro_options_mat(hs_info, geo) driver.run_job( job='energy', script_str=sp_script_str, run_fs=run_sr_fs, geom=geo, spc_info=hs_info, thy_level=thy_lvl, errors=errors, options_mat=options_mat, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading high spin single ref energy from output...") hs_sr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving high spin single reference energy...") print(" - Save path: {}".format(hs_sr_save_path)) hs_save_fs.leaf.file.energy.write(hs_sr_ene, thy_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) else: print('ERROR: High spin single reference energy job fails: ', 'Energy is needed to evaluate infinite separation energy') return inf_sep_ene else: hs_sr_ene = hs_save_fs.leaf.file.energy.read(thy_lvl[1:4]) # get the single reference energy for each of the reactant configurations spc_ene = [] spc_infos = [spc_1_info, spc_2_info] for spc_info in spc_infos: # set up the file systems for the reactants one by one spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info) ini_thy_lvl = ini_thy_info[0:3] ini_thy_lvl.append(orb_restr) orb_restr = fsorb.orbital_restriction(spc_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) ini_thy_run_fs = autofile.fs.theory(spc_run_path) ini_thy_run_fs.leaf.create(ini_thy_lvl[1:4]) ini_thy_run_path = ini_thy_run_fs.leaf.path(ini_thy_lvl[1:4]) ini_thy_save_fs = autofile.fs.theory(spc_save_path) ini_thy_save_fs.leaf.create(ini_thy_lvl[1:4]) ini_thy_save_path = ini_thy_save_fs.leaf.path(ini_thy_lvl[1:4]) ini_cnf_run_fs = autofile.fs.conformer(ini_thy_run_path) ini_cnf_save_fs = autofile.fs.conformer(ini_thy_save_path) min_cnf_locs = fsmin.min_energy_conformer_locators(ini_cnf_save_fs) min_cnf_run_path = ini_cnf_run_fs.leaf.path(min_cnf_locs) min_cnf_save_path = ini_cnf_save_fs.leaf.path(min_cnf_locs) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_lvl[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(thy_lvl[1:4]) geo = ini_cnf_save_fs.leaf.file.geometry.read(min_cnf_locs) sp_run_fs = autofile.fs.single_point(min_cnf_run_path) sp_run_fs.leaf.create(thy_lvl[1:4]) sp_save_fs = autofile.fs.single_point(min_cnf_save_path) sp_save_fs.leaf.create(thy_lvl[1:4]) sp_sr_run_path = sp_run_fs.leaf.path(thy_lvl[1:4]) sp_sr_save_path = sp_save_fs.leaf.path(thy_lvl[1:4]) print('sp_sr_run_path') print(sp_sr_run_path) run_sr_fs = autofile.fs.run(sp_sr_run_path) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret: print(" - Reading single reference energy for", "{} from output...".format(spc_info[0])) inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) sp_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4]) sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) if not sp_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite: print(" - Running single reference energy for", "{} from output...".format(spc_info[0])) driver.run_job( job='energy', script_str=sp_script_str, run_fs=run_sr_fs, geom=geo, spc_info=spc_info, thy_level=thy_lvl, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading single reference energy for ", "{} from output...".format(spc_info[0])) sp_sr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving single reference energy for ", "{} from output...".format(spc_info[0])) print(" - Save path: {}".format(sp_sr_save_path)) sp_save_fs.leaf.file.energy.write(sp_sr_ene, thy_lvl[1:4]) sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) else: print('ERROR: Single reference energy job fails', 'for {}: '.format(spc_info[0]), 'Energy needed to evaluate infinite separation energy') return inf_sep_ene else: sp_sr_ene = sp_save_fs.leaf.file.energy.read(thy_lvl[1:4]) spc_ene.append(sp_sr_ene) inf_sep_ene = spc_ene[0] + spc_ene[1] - hs_sr_ene + hs_mr_ene return inf_sep_ene