def _run_2d_scan(script_str, run_prefixes, scn_save_fs, guess_zma, coo_names, grid_idxs, grid_vals, spc_info, thy_level, overwrite, errors=(), options_mat=(), retry_failed=True, update_guess=True, saddle=False, alt_constraints=(), **kwargs): """ run 2-dimensional scan with constrained optimization """ npoints = len(grid_idxs) assert len(grid_vals[0]) * len( grid_vals[1]) == len(run_prefixes) == npoints idx = 0 for grid_val_i in grid_vals[0]: for grid_val_j in grid_vals[1]: grid_idx = grid_idxs[idx] run_prefix = run_prefixes[idx] print("Point {}/{}".format(grid_idx + 1, npoints)) zma = automol.zmatrix.set_values(guess_zma, { coo_names[0]: grid_val_i, coo_names[1]: grid_val_j }) run_fs = autofile.fs.run(run_prefix) idx += 1 frozen_coordinates = coo_names + list(alt_constraints) if not scn_save_fs.leaf.file.geometry.exists( [coo_names, [grid_val_i, grid_val_j]]) or overwrite: driver.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, frozen_coordinates=frozen_coordinates, errors=errors, options_mat=options_mat, retry_failed=retry_failed, saddle=saddle, **kwargs) ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if update_guess and ret is not None: inf_obj, _, out_str = ret prog = inf_obj.prog guess_zma = elstruct.reader.opt_zmatrix(prog, out_str)
def run_check_imaginary(spc_info, geo, thy_level, thy_run_fs, script_str, overwrite=False, **kwargs): """ check if species has an imaginary frequency """ # projrot_script_str = script.PROJROT thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) run_fs = autofile.fs.run(thy_run_path) imag = False disp_xyzs = [] hess = ((), ()) if automol.geom.is_atom(geo): hess = ((), ()) else: driver.run_job( job=elstruct.Job.HESSIAN, spc_info=spc_info, thy_level=thy_level, geom=geo, run_fs=run_fs, script_str=script_str, overwrite=overwrite, **kwargs, ) ret = driver.read_job(job=elstruct.Job.HESSIAN, run_fs=run_fs) if ret: inf_obj, _, out_str = ret prog = inf_obj.prog hess = elstruct.reader.hessian(prog, out_str) if hess: imag = False _, imag_freq = projrot_frequencies(geo, hess, thy_level, thy_run_fs) if imag_freq: imag = True # Mode for now set the imaginary frequency check to -100: # Should decrease once freq projector functions properly if imag: imag = True print('Imaginary mode found:') norm_coos = elstruct.util.normal_coordinates(geo, hess, project=True) im_norm_coo = numpy.array(norm_coos)[:, 0] disp_xyzs = numpy.reshape(im_norm_coo, (-1, 3)) return imag, geo, disp_xyzs, hess
def run_energy( spc_info, thy_level, geo_run_fs, geo_save_fs, locs, script_str, overwrite, **kwargs): """ Find the energy for the given structure """ # Prepare unique filesystem since many energies may be under same directory geo_run_path = geo_run_fs.leaf.path(locs) geo_save_path = geo_save_fs.leaf.path(locs) geo = geo_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) sp_run_fs.leaf.create(thy_level[1:4]) sp_run_path = sp_run_fs.leaf.path(thy_level[1:4]) sp_save_fs.leaf.create(thy_level[1:4]) run_fs = autofile.fs.run(sp_run_path) if not sp_save_fs.leaf.file.energy.exists(thy_level[1:4]) or overwrite: # Add options matrix for energy runs for molpro if thy_level[0] == 'molpro2015': errors, options_mat = runpar.set_molpro_options_mat(spc_info, geo) else: errors = () options_mat = () driver.run_job( job='energy', script_str=script_str, run_fs=run_fs, geom=geo, spc_info=spc_info, thy_level=thy_level, errors=errors, options_mat=options_mat, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='energy', run_fs=run_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading energy from output...") ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving energy...") sp_save_fs.leaf.file.input.write(inp_str, thy_level[1:4]) sp_save_fs.leaf.file.info.write(inf_obj, thy_level[1:4]) sp_save_fs.leaf.file.energy.write(ene, thy_level[1:4])
def run_vpt2( spc_info, thy_level, geo_run_fs, geo_save_fs, locs, script_str, overwrite, **kwargs): """ Perform vpt2 analysis for the geometry in the given location """ geo_run_path = geo_run_fs.leaf.path(locs) geo_save_path = geo_save_fs.leaf.path(locs) geo = geo_save_fs.leaf.file.geometry.read(locs) run_fs = autofile.fs.run(geo_run_path) if not geo_save_fs.leaf.file.anharmnicity_matrix.exists(locs) or overwrite: print('Running vpt2') driver.run_job( job='vpt2', script_str=script_str, run_fs=run_fs, geom=geo, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='vpt2', run_fs=run_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret if automol.geom.is_atom(geo): pass else: print(" - Reading anharmonicities from output...") vpt2_dct = elstruct.reader.vpt2(inf_obj.prog, out_str) print(" - Saving anharmonicities...") print(" - Save path: {}".format(geo_save_path)) # geo_save_fs.leaf.file.vpt2_info.write(inf_obj, locs) geo_save_fs.leaf.file.vpt2_input.write(inp_str, locs) geo_save_fs.leaf.file.anharmonic_frequencies.write( vpt2_dct['freqs'], locs) geo_save_fs.leaf.file.anharmonic_zpve.write( vpt2_dct['zpve'], locs) geo_save_fs.leaf.file.anharmonicity_matrix.write( vpt2_dct['x_mat'], locs) geo_save_fs.leaf.file.vibro_rot_alpha_matrix.write( vpt2_dct['vibrot_mat'], locs) geo_save_fs.leaf.file.quartic_centrifugal_dist_consts.write( vpt2_dct['cent_dist_const'], locs)
def run_hessian( spc_info, thy_level, geo_run_fs, geo_save_fs, locs, script_str, overwrite, **kwargs): """ Determine the hessian for the geometry in the given location """ geo_run_path = geo_run_fs.leaf.path(locs) geo_save_path = geo_save_fs.leaf.path(locs) geo = geo_save_fs.leaf.file.geometry.read(locs) run_fs = autofile.fs.run(geo_run_path) if not geo_save_fs.leaf.file.hessian.exists(locs) or overwrite: print('Running hessian') driver.run_job( job='hessian', script_str=script_str, run_fs=run_fs, geom=geo, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='hessian', run_fs=run_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret if automol.geom.is_atom(geo): freqs = () else: print(" - Reading hessian from output...") hess = elstruct.reader.hessian(inf_obj.prog, out_str) freqs = elstruct.util.harmonic_frequencies( geo, hess, project=False) print(" - Saving hessian...") print(" - Save path: {}".format(geo_save_path)) geo_save_fs.leaf.file.hessian_info.write(inf_obj, locs) geo_save_fs.leaf.file.hessian_input.write(inp_str, locs) geo_save_fs.leaf.file.hessian.write(hess, locs) geo_save_fs.leaf.file.harmonic_frequencies.write(freqs, locs)
def run_gradient( spc_info, thy_level, geo_run_fs, geo_save_fs, locs, script_str, overwrite, **kwargs): """ Determine the gradient for the geometry in the given location """ geo_run_path = geo_run_fs.leaf.path(locs) geo_save_path = geo_save_fs.leaf.path(locs) geo = geo_save_fs.leaf.file.geometry.read(locs) run_fs = autofile.fs.run(geo_run_path) if not geo_save_fs.leaf.file.gradient.exists(locs) or overwrite: print('Running gradient') driver.run_job( job='gradient', script_str=script_str, run_fs=run_fs, geom=geo, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='gradient', run_fs=run_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret if automol.geom.is_atom(geo): grad = () else: print(" - Reading gradient from output...") grad = elstruct.reader.gradient(inf_obj.prog, out_str) print(" - Saving gradient...") print(" - Save path: {}".format(geo_save_path)) geo_save_fs.leaf.file.gradient_info.write(inf_obj, locs) geo_save_fs.leaf.file.gradient_input.write(inp_str, locs) geo_save_fs.leaf.file.gradient.write(grad, locs)
def run_kickoff_saddle(geo, disp_xyzs, spc_info, thy_level, run_fs, thy_run_fs, opt_script_str, kickoff_size=0.1, kickoff_backward=False, opt_cart=True, **kwargs): """ kickoff from saddle to find connected minima """ print('kickoff from saddle') thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) run_fs = autofile.fs.run(thy_run_path) disp_len = kickoff_size * phycon.ANG2BOHR if kickoff_backward: disp_len *= -1 disp_xyzs = numpy.multiply(disp_xyzs, disp_len) geo = automol.geom.displaced(geo, disp_xyzs) if opt_cart: geom = geo else: geom = automol.geom.zmatrix(geo) driver.run_job( job=elstruct.Job.OPTIMIZATION, script_str=opt_script_str, run_fs=run_fs, geom=geom, spc_info=spc_info, thy_level=thy_level, overwrite=True, **kwargs, ) ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if ret: inf_obj, _, out_str = ret prog = inf_obj.prog geo = elstruct.reader.opt_geometry(prog, out_str) return geo
def run_initial_geometry_opt(spc_info, thy_level, run_fs, thy_run_fs, script_str, overwrite, ini_geo, **kwargs): """ generate initial geometry via optimization from either reference geometries or from inchi """ # set up the filesystem thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) # check if geometry has already been saved # if not call the electronic structure optimizer ncp1 = len(automol.graph.connected_components(automol.geom.graph(ini_geo))) if ncp1 < 2: geom = automol.geom.zmatrix(ini_geo) else: geom = ini_geo run_fs = autofile.fs.run(thy_run_path) print('thy_run_path') driver.run_job( job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=geom, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, **kwargs, ) ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) geo = None inf = None if ret: print('Succesful reference geometry optimization') inf_obj, _, out_str = ret prog = inf_obj.prog geo = elstruct.reader.opt_geometry(prog, out_str) ncp2 = len(automol.graph.connected_components(automol.geom.graph(geo))) if ncp2 >= 2: method = inf_obj.method ene = elstruct.reader.energy(prog, method, out_str) inf = [inf_obj, ene] return geo, inf
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_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): """ Optimize the transition state structure obtained from the grid search """ # Run the transition state optimization driver.run_job( job='optimization', script_str=opt_script_str, run_fs=run_fs, geom=max_zma, spc_info=ts_info, thy_level=ref_level, saddle=True, overwrite=overwrite, **opt_kwargs, ) # Read the contents of the optimization opt_ret = driver.read_job( job='optimization', run_fs=run_fs, ) if opt_ret is not None: # If successful, Read the geom and energy from the optimization 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) # Save the information into the filesystem print(" - Saving...") print(" - Save path: {}".format(ts_save_path)) ts_save_fs.trunk.file.energy.write(ene) ts_save_fs.trunk.file.geometry.write(geo) ts_save_fs.trunk.file.zmatrix.write(zma) # Run single conformer to get intitial conformer in filesystem vals = automol.zmatrix.values(zma) final_dist = vals[dist_name] dist_info[1] = final_dist conformer.conformer_sampling(spc_info=ts_info, thy_level=ref_level, thy_save_fs=filesys[3], cnf_run_fs=filesys[4], cnf_save_fs=filesys[5], script_str=opt_script_str, overwrite=overwrite, nsamp_par=[False, 0, 0, 0, 0, 1], saddle=True, dist_info=dist_info, two_stage=True, **opt_kwargs) else: # Give up and return failed information geo = 'failed' zma = 'failed' final_dist = 0. return geo, zma, final_dist
def run_tau( zma, spc_info, thy_level, nsamp, tors_range_dct, tau_run_fs, tau_save_fs, script_str, overwrite, **kwargs): """ run sampling algorithm to find tau dependent geometries """ if not tors_range_dct: print("No torsional coordinates. Setting nsamp to 1.") nsamp = 1 tau_save_fs.trunk.create() vma = automol.zmatrix.var_(zma) if tau_save_fs.trunk.file.vmatrix.exists(): existing_vma = tau_save_fs.trunk.file.vmatrix.read() assert vma == existing_vma tau_save_fs.trunk.file.vmatrix.write(vma) idx = 0 nsamp0 = nsamp inf_obj = autofile.system.info.tau_trunk(0, tors_range_dct) while True: if tau_save_fs.trunk.file.info.exists(): inf_obj_s = tau_save_fs.trunk.file.info.read() nsampd = inf_obj_s.nsamp elif tau_save_fs.trunk.file.info.exists(): inf_obj_r = tau_save_fs.trunk.file.info.read() nsampd = inf_obj_r.nsamp else: nsampd = 0 nsamp = nsamp0 - nsampd if nsamp <= 0: print('Reached requested number of samples. ' 'Tau sampling complete.') break else: print(" New nsamp is {:d}.".format(nsamp)) samp_zma, = automol.zmatrix.samples(zma, 1, tors_range_dct) tid = autofile.system.generate_new_tau_id() locs = [tid] tau_run_fs.leaf.create(locs) tau_run_prefix = tau_run_fs.leaf.path(locs) run_fs = autofile.fs.run(tau_run_prefix) idx += 1 print("Run {}/{}".format(idx, nsamp0)) driver.run_job( job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, frozen_coordinates=tors_range_dct.keys(), **kwargs ) nsampd += 1 inf_obj.nsamp = nsampd tau_save_fs.trunk.file.info.write(inf_obj) tau_run_fs.trunk.file.info.write(inf_obj)
def run_conformers(zma, spc_info, thy_level, nsamp, tors_range_dct, cnf_run_fs, cnf_save_fs, script_str, overwrite, saddle, two_stage, **kwargs): """ run sampling algorithm to find conformers """ if not tors_range_dct: print("No torsional coordinates. Setting nsamp to 1.") nsamp = 1 print('Number of samples requested:', nsamp) cnf_save_fs.trunk.create() vma = automol.zmatrix.var_(zma) if cnf_save_fs.trunk.file.vmatrix.exists(): existing_vma = cnf_save_fs.trunk.file.vmatrix.read() print(existing_vma) print(vma) assert vma == existing_vma cnf_save_fs.trunk.file.vmatrix.write(vma) idx = 0 nsamp0 = nsamp inf_obj = autofile.system.info.conformer_trunk(0, tors_range_dct) if cnf_save_fs.trunk.file.info.exists(): inf_obj_s = cnf_save_fs.trunk.file.info.read() nsampd = inf_obj_s.nsamp elif cnf_run_fs.trunk.file.info.exists(): inf_obj_r = cnf_run_fs.trunk.file.info.read() nsampd = inf_obj_r.nsamp else: nsampd = 0 while True: nsamp = nsamp0 - nsampd if nsamp <= 0: print('Reached requested number of samples. ' 'Conformer search complete.') break else: print(" New nsamp requested is {:d}.".format(nsamp)) if nsampd > 0: samp_zma, = automol.zmatrix.samples(zma, 1, tors_range_dct) else: samp_zma = zma cid = autofile.system.generate_new_conformer_id() locs = [cid] cnf_run_fs.leaf.create(locs) cnf_run_path = cnf_run_fs.leaf.path(locs) run_fs = autofile.fs.run(cnf_run_path) idx += 1 print("Run {}/{}".format(nsampd + 1, nsamp0)) tors_names = list(tors_range_dct.keys()) if two_stage and tors_names: print('Stage one beginning, holding the coordinates constant', tors_names) driver.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, frozen_coordinates=[tors_names], saddle=saddle, **kwargs) print('Stage one success, reading for stage 2') ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if ret: sinf_obj, _, out_str = ret prog = sinf_obj.prog samp_zma = elstruct.reader.opt_zmatrix(prog, out_str) print('Stage one success beginning stage two on', samp_zma) driver.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, saddle=saddle, **kwargs) else: driver.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, saddle=saddle, **kwargs) if cnf_save_fs.trunk.file.info.exists(): inf_obj_s = cnf_save_fs.trunk.file.info.read() nsampd = inf_obj_s.nsamp elif cnf_run_fs.trunk.file.info.exists(): inf_obj_r = cnf_run_fs.trunk.file.info.read() nsampd = inf_obj_r.nsamp nsampd += 1 inf_obj.nsamp = nsampd cnf_save_fs.trunk.file.info.write(inf_obj) cnf_run_fs.trunk.file.info.write(inf_obj)
def _run_1d_scan(script_str, run_prefixes, scn_save_fs, guess_zma, coo_name, grid_idxs, grid_vals, spc_info, thy_level, overwrite, errors=(), options_mat=(), retry_failed=True, update_guess=True, saddle=False, gradient=False, hessian=False, alt_constraints=(), **kwargs): """ run 1 dimensional scan with constrained optimization """ npoints = len(grid_idxs) assert len(grid_vals) == len(run_prefixes) == npoints grid_info = zip(grid_idxs, grid_vals, run_prefixes) for grid_idx, grid_val, run_prefix in grid_info: print("Point {}/{}".format(grid_idx + 1, npoints)) zma = automol.zmatrix.set_values(guess_zma, {coo_name: grid_val}) run_fs = autofile.fs.run(run_prefix) frozen_coordinates = [coo_name] + list(alt_constraints) geo_exists = scn_save_fs.leaf.file.geometry.exists([[coo_name], [grid_val]]) if not geo_exists or overwrite: driver.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, frozen_coordinates=frozen_coordinates, errors=errors, options_mat=options_mat, retry_failed=retry_failed, saddle=saddle, **kwargs) ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if ret is not None: inf_obj, _, out_str = ret prog = inf_obj.prog opt_zma = elstruct.reader.opt_zmatrix(prog, out_str) if update_guess: guess_zma = opt_zma if gradient: driver.run_job(job=elstruct.Job.GRADIENT, script_str=script_str, run_fs=run_fs, geom=opt_zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, frozen_coordinates=[coo_name], errors=errors, options_mat=options_mat, retry_failed=retry_failed, **kwargs) ret = driver.read_job(job=elstruct.Job.GRADIENT, run_fs=run_fs) if hessian: driver.run_job(job=elstruct.Job.HESSIAN, script_str=script_str, run_fs=run_fs, geom=opt_zma, spc_info=spc_info, thy_level=thy_level, overwrite=overwrite, frozen_coordinates=[coo_name], errors=errors, options_mat=options_mat, retry_failed=retry_failed, **kwargs) ret = driver.read_job(job=elstruct.Job.HESSIAN, run_fs=run_fs)
def infinite_separation_energy(spc_1_info, spc_2_info, ts_info, high_mul, ref_zma, ini_thy_info, thy_info, multi_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs, locs, overwrite=False, num_act_elc=None, num_act_orb=None): """ Obtain the infinite separation energy from the multireference energy at a given reference point, the high-spin low-spin splitting at that reference point, and the high level energy for the high spin state at the reference geometry and for the fragments """ # Initialize infinite sep energy inf_sep_ene = -1.0e12 # set up all the file systems for the TS # start with the geo and reference theory info geo_run_path = scn_run_fs.leaf.path(locs) geo_save_path = scn_save_fs.leaf.path(locs) geo = scn_save_fs.leaf.file.geometry.read(locs) sp_run_fs = autofile.fs.single_point(geo_run_path) sp_save_fs = autofile.fs.single_point(geo_save_path) # get the multi reference ene for low spin state for the ref point on scan # file system for low spin multireference calculation multi_info[0] = 'molpro2015' multi_info[1] = 'caspt2' # ultimately the above should be properly passed prog = multi_info[0] method = multi_info[1] # get the multi reference energy for high spin state for ref point on scan hs_info = (ts_info[0], ts_info[1], high_mul) orb_restr = fsorb.orbital_restriction(hs_info, multi_info) multi_lvl = multi_info[0:3] multi_lvl.append(orb_restr) hs_run_fs = autofile.fs.high_spin(geo_run_path) hs_save_fs = autofile.fs.high_spin(geo_save_path) hs_run_fs.leaf.create(multi_lvl[1:4]) hs_save_fs.leaf.create(multi_lvl[1:4]) hs_mr_run_path = hs_run_fs.leaf.path(multi_lvl[1:4]) hs_mr_save_path = hs_save_fs.leaf.path(multi_lvl[1:4]) run_mr_fs = autofile.fs.run(hs_mr_run_path) mr_script_str, _, mr_kwargs, _ = runpar.run_qchem_par(prog, method) if num_act_elc is None and num_act_orb is None: num_act_elc = high_mul num_act_orb = num_act_elc ts_formula = automol.geom.formula(automol.zmatrix.geometry(ref_zma)) cas_opt, _ = ts.cas_options_2(hs_info, ts_formula, num_act_elc, num_act_orb, high_mul) guess_str = ts.multiref_wavefunction_guess(high_mul, ref_zma, hs_info, multi_lvl, [cas_opt]) guess_lines = guess_str.splitlines() mr_kwargs['casscf_options'] = cas_opt mr_kwargs['mol_options'] = ['nosym'] mr_kwargs['gen_lines'] = {1: guess_lines} ret = driver.read_job( job='energy', run_fs=run_mr_fs, ) if ret: print(" - Reading high spin multi reference energy from output...") inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) hs_save_fs.leaf.file.energy.write(ene, multi_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4]) if not hs_save_fs.leaf.file.energy.exists(multi_lvl[1:4]) or overwrite: print(" - Running high spin multi reference energy ...") driver.run_job( job='energy', script_str=mr_script_str, run_fs=run_mr_fs, geom=geo, spc_info=hs_info, thy_level=multi_lvl, overwrite=overwrite, **mr_kwargs, ) ret = driver.read_job( job='energy', run_fs=run_mr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading high spin multi reference energy from output...") hs_mr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving high spin multi reference energy...") print(" - Save path: {}".format(hs_mr_save_path)) hs_save_fs.leaf.file.energy.write(hs_mr_ene, multi_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4]) else: print('ERROR: high spin multi reference energy job fails: ', 'Energy is needed to evaluate infinite separation energy') return inf_sep_ene else: hs_mr_ene = hs_save_fs.leaf.file.energy.read(multi_lvl[1:4]) # file system for high spin single ireference calculation thy_info = ['molpro2015', 'ccsd(t)-f12', 'cc-pvdz-f12', 'RR'] orb_restr = fsorb.orbital_restriction(hs_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) hs_run_fs.leaf.create(thy_lvl[1:4]) hs_save_fs.leaf.create(thy_lvl[1:4]) hs_sr_run_path = hs_run_fs.leaf.path(thy_lvl[1:4]) hs_sr_save_path = hs_save_fs.leaf.path(thy_lvl[1:4]) run_sr_fs = autofile.fs.run(hs_sr_run_path) sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_lvl[0:2]) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret: print(" - Reading high spin single reference energy from output...") inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) hs_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) if not hs_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite: print(" - Running high spin single reference energy ...") errors, options_mat = runpar.set_molpro_options_mat(hs_info, geo) driver.run_job( job='energy', script_str=sp_script_str, run_fs=run_sr_fs, geom=geo, spc_info=hs_info, thy_level=thy_lvl, errors=errors, options_mat=options_mat, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading high spin single ref energy from output...") hs_sr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving high spin single reference energy...") print(" - Save path: {}".format(hs_sr_save_path)) hs_save_fs.leaf.file.energy.write(hs_sr_ene, thy_lvl[1:4]) hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) else: print('ERROR: High spin single reference energy job fails: ', 'Energy is needed to evaluate infinite separation energy') return inf_sep_ene else: hs_sr_ene = hs_save_fs.leaf.file.energy.read(thy_lvl[1:4]) # get the single reference energy for each of the reactant configurations spc_ene = [] spc_infos = [spc_1_info, spc_2_info] for spc_info in spc_infos: # set up the file systems for the reactants one by one spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info) ini_thy_lvl = ini_thy_info[0:3] ini_thy_lvl.append(orb_restr) orb_restr = fsorb.orbital_restriction(spc_info, thy_info) thy_lvl = thy_info[0:3] thy_lvl.append(orb_restr) ini_thy_run_fs = autofile.fs.theory(spc_run_path) ini_thy_run_fs.leaf.create(ini_thy_lvl[1:4]) ini_thy_run_path = ini_thy_run_fs.leaf.path(ini_thy_lvl[1:4]) ini_thy_save_fs = autofile.fs.theory(spc_save_path) ini_thy_save_fs.leaf.create(ini_thy_lvl[1:4]) ini_thy_save_path = ini_thy_save_fs.leaf.path(ini_thy_lvl[1:4]) ini_cnf_run_fs = autofile.fs.conformer(ini_thy_run_path) ini_cnf_save_fs = autofile.fs.conformer(ini_thy_save_path) min_cnf_locs = fsmin.min_energy_conformer_locators(ini_cnf_save_fs) min_cnf_run_path = ini_cnf_run_fs.leaf.path(min_cnf_locs) min_cnf_save_path = ini_cnf_save_fs.leaf.path(min_cnf_locs) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_lvl[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(thy_lvl[1:4]) geo = ini_cnf_save_fs.leaf.file.geometry.read(min_cnf_locs) sp_run_fs = autofile.fs.single_point(min_cnf_run_path) sp_run_fs.leaf.create(thy_lvl[1:4]) sp_save_fs = autofile.fs.single_point(min_cnf_save_path) sp_save_fs.leaf.create(thy_lvl[1:4]) sp_sr_run_path = sp_run_fs.leaf.path(thy_lvl[1:4]) sp_sr_save_path = sp_save_fs.leaf.path(thy_lvl[1:4]) print('sp_sr_run_path') print(sp_sr_run_path) run_sr_fs = autofile.fs.run(sp_sr_run_path) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret: print(" - Reading single reference energy for", "{} from output...".format(spc_info[0])) inf_obj, inp_str, out_str = ret ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) sp_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4]) sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) if not sp_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite: print(" - Running single reference energy for", "{} from output...".format(spc_info[0])) driver.run_job( job='energy', script_str=sp_script_str, run_fs=run_sr_fs, geom=geo, spc_info=spc_info, thy_level=thy_lvl, overwrite=overwrite, **kwargs, ) ret = driver.read_job( job='energy', run_fs=run_sr_fs, ) if ret is not None: inf_obj, inp_str, out_str = ret print(" - Reading single reference energy for ", "{} from output...".format(spc_info[0])) sp_sr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) print(" - Saving single reference energy for ", "{} from output...".format(spc_info[0])) print(" - Save path: {}".format(sp_sr_save_path)) sp_save_fs.leaf.file.energy.write(sp_sr_ene, thy_lvl[1:4]) sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4]) sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4]) else: print('ERROR: Single reference energy job fails', 'for {}: '.format(spc_info[0]), 'Energy needed to evaluate infinite separation energy') return inf_sep_ene else: sp_sr_ene = sp_save_fs.leaf.file.energy.read(thy_lvl[1:4]) spc_ene.append(sp_sr_ene) inf_sep_ene = spc_ene[0] + spc_ene[1] - hs_sr_ene + hs_mr_ene return inf_sep_ene
def find_vdw(ts_name, spc_dct, thy_info, ini_thy_info, vdw_params, nsamp_par, run_prefix, save_prefix, kickoff_size, kickoff_backward, overwrite): """ Find van der Waals structures for all the pairs of species in a reaction list """ projrot_script_str = script.PROJROT new_vdws = [] _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(*thy_info[:2]) mul = spc_dct[ts_name]['low_mul'] vdw_names_lst = [] if vdw_params[0]: vdw_names_lst.append([sorted(spc_dct[ts_name]['reacs']), mul, 'r']) if vdw_params[1]: vdw_names_lst.append([sorted(spc_dct[ts_name]['prods']), mul, 'p']) for names, ts_mul, label in vdw_names_lst: if len(names) < 2: print('Cannot find van der Waals well for unimolecular', 'reactant or product') ichs = list(map(lambda name: spc_dct[name]['ich'], names)) chgs = list(map(lambda name: spc_dct[name]['chg'], names)) muls = list(map(lambda name: spc_dct[name]['mul'], names)) # theory prog = thy_info[0] method = thy_info[1] _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(prog, method) geos = [(), ()] ntaudof = 0. for i, (nam, ich, chg, mul) in enumerate(zip(names, ichs, chgs, muls)): spc_info = [ich, chg, mul] orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info) ini_thy_level = ini_thy_info[0:3] ini_thy_level.append(orb_restr) orb_restr = fsorb.orbital_restriction(spc_info, thy_info) thy_level = thy_info[0:3] thy_level.append(orb_restr) spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(thy_level[1:4]) thy_save_path = thy_save_fs.leaf.path(thy_level[1:4]) run_fs = autofile.fs.run(thy_run_path) ini_thy_save_fs = autofile.fs.theory(spc_save_path) ini_thy_save_fs.leaf.create(ini_thy_level[1:4]) cnf_run_fs = autofile.fs.conformer(thy_run_path) cnf_save_fs = autofile.fs.conformer(thy_save_path) ini_filesys = [None, ini_thy_save_fs] filesys = [ spc_run_fs, spc_save_fs, thy_run_fs, thy_save_fs, cnf_run_fs, cnf_save_fs, None, None, None, None, run_fs ] geo = geom.reference_geometry( spc_dct[nam], thy_level, ini_thy_level, filesys, ini_filesys, kickoff_size=kickoff_size, kickoff_backward=kickoff_backward, projrot_script_str=projrot_script_str, overwrite=overwrite) geos[i] = geo gra = automol.geom.graph(geo) ntaudof += len( automol.graph.rotational_bond_keys(gra, with_h_rotors=False)) nsamp = util.nsamp_init(nsamp_par, ntaudof) geo1, geo2 = geos geo1 = automol.geom.mass_centered(geo1) geo2 = automol.geom.mass_centered(geo2) min_ene = 0. for idx in range(int(nsamp)): print('Optimizing vdw geometry {}/{}'.format(idx + 1, nsamp)) angs1 = numpy.multiply(numpy.random.rand(3), [1 * numpy.pi, 2 * numpy.pi, 2 * numpy.pi]) angs2 = numpy.multiply(numpy.random.rand(3), [1 * numpy.pi, 2 * numpy.pi, 2 * numpy.pi]) angs12 = numpy.multiply(numpy.random.rand(2), [1 * numpy.pi, 2 * numpy.pi]) geo1 = automol.geom.euler_rotated(geo1, *angs1) geo2 = automol.geom.euler_rotated(geo2, *angs2) dist_cutoff = 3.0 * phycon.ANG2BOHR geo = automol.geom.join(geo1, geo2, dist_cutoff, *angs12) print("Species: {}".format('+'.join(names))) print('vdw starting geometry') print(automol.geom.xyz_string(geo)) # Set up the filesystem ich = automol.inchi.recalculate(automol.inchi.join(ichs)) chg = sum(chgs) mul = ts_mul spc_info = (ich, chg, mul) spc_run_fs = autofile.fs.species(run_prefix) spc_run_fs.leaf.create(spc_info) spc_run_path = spc_run_fs.leaf.path(spc_info) spc_save_fs = autofile.fs.species(save_prefix) spc_save_fs.leaf.create(spc_info) spc_save_path = spc_save_fs.leaf.path(spc_info) orb_restr = fsorb.orbital_restriction(spc_info, thy_info) thy_level = thy_info[0:3] thy_level.append(orb_restr) thy_run_fs = autofile.fs.theory(spc_run_path) thy_run_fs.leaf.create(thy_level[1:4]) thy_run_path = thy_run_fs.leaf.path(thy_level[1:4]) thy_save_fs = autofile.fs.theory(spc_save_path) thy_save_fs.leaf.create(thy_level[1:4]) thy_save_path = thy_save_fs.leaf.path(thy_level[1:4]) run_fs = autofile.fs.run(thy_run_path) # Generate reference geometry # Generate the z-matrix and sampling ranges driver.run_job( job=elstruct.Job.OPTIMIZATION, geom=geo, spc_info=spc_info, thy_level=thy_level, run_fs=run_fs, script_str=opt_script_str, overwrite=overwrite, **opt_kwargs, ) # Save info for the initial geometry (from ichi or fsave dir) ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if ret: print('Saving reference geometry') print(" - Save path: {}".format(thy_save_path)) inf_obj, inp_str, out_str = ret prog = inf_obj.prog method = inf_obj.method geo = elstruct.reader.opt_geometry(prog, out_str) print('vdw ending geometry') print(automol.geom.xyz_string(geo)) thy_save_fs.leaf.file.geometry.write(geo, thy_level[1:4]) ene = elstruct.reader.energy(prog, method, out_str) if ene < min_ene: min_ene = ene print('ene test in vdw') print(ene) thy_save_fs.leaf.file.energy.write(ene, thy_level[1:4]) print('Saving reference geometry') print(" - Save path: {}".format(thy_save_path)) vdw_name = label + ts_name.replace('ts', 'vdw') spc_dct[vdw_name] = spc_dct[ts_name].copy() spc_dct[vdw_name]['ich'] = ich spc_dct[vdw_name]['mul'] = mul spc_dct[vdw_name]['chg'] = chg spc_dct[vdw_name]['dist_info'][1] = dist_cutoff # Make a fake conformer cnf_save_fs = autofile.fs.conformer(thy_save_path) cnf_run_fs = autofile.fs.conformer(thy_run_path) cnf_save_fs.trunk.create() cnf_run_fs.trunk.create() tors_range_dct = {} cinf_obj = autofile.system.info.conformer_trunk( 0, tors_range_dct) cinf_obj.nsamp = 1 cnf_save_fs.trunk.file.info.write(cinf_obj) locs_lst = cnf_save_fs.leaf.existing() if not locs_lst: cid = autofile.system.generate_new_conformer_id() locs = [cid] else: locs = locs_lst[0] cnf_save_fs.leaf.create(locs) cnf_run_fs.leaf.create(locs) cnf_save_fs.leaf.file.geometry_info.write(inf_obj, locs) cnf_save_fs.leaf.file.geometry_input.write(inp_str, locs) cnf_save_fs.leaf.file.energy.write(ene, locs) cnf_save_fs.leaf.file.geometry.write(geo, locs) if min_ene: new_vdws.append(vdw_name) return new_vdws