def run_irc(zma, irc_job, coord_name, run_fs, ini_scn_save_fs, ts_info, mod_ini_thy_info, overwrite, opt_script_str, **opt_kwargs): """ Run the irc job """ # Maybe check for positive coords if not _irc_ran(ini_scn_save_fs, coord_name, irc_job): print('No IRC calculation in save filesystem') opt_success, _ = es_runner.read_job( job=irc_job, run_fs=run_fs, ) need_irc = bool(not opt_success) else: print('Found IRC directory at {}'.format( ini_scn_save_fs[1].path([coord_name]))) need_irc = False if need_irc: print('Running IRC calculation') es_runner.run_job( job=irc_job, script_str=opt_script_str, run_fs=run_fs, geom=zma, spc_info=ts_info, thy_info=mod_ini_thy_info, overwrite=overwrite, **opt_kwargs, ) else: print('Skipping IRC calculation')
def _init_geom_opt(zma_init, spc_info, mod_thy_info, run_fs, thy_run_fs, opt_script_str, overwrite, **opt_kwargs): """ Generate initial geometry via optimization from either reference geometries or from inchi """ # Set up the filesystem thy_run_fs[-1].create(mod_thy_info[1:4]) thy_run_path = thy_run_fs[-1].path(mod_thy_info[1:4]) # Call the electronic structure optimizer run_fs = autofile.fs.run(thy_run_path) es_runner.run_job( job=elstruct.Job.OPTIMIZATION, script_str=opt_script_str, run_fs=run_fs, geom=zma_init, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, **opt_kwargs, ) success, ret = es_runner.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) geo, zma = None, None if success: print('Succesful reference geometry optimization') inf_obj, _, out_str = ret prog = inf_obj.prog geo = elstruct.reader.opt_geometry(prog, out_str) zma = elstruct.reader.opt_zmatrix(prog, out_str) return geo, zma
def optimize_saddle_point(guess_zmas, ts_info, mod_thy_info, run_fs, opt_script_str, overwrite, **opt_kwargs): """ Optimize the transition state structure obtained from the grid search """ if len(guess_zmas) == 1: print('\nThere is 1 guess Z-Matrix', 'to attempt to find saddle point.') else: print('\nThere are {} guess Z-Matrices'.format(len(guess_zmas)), 'to attempt to find saddle point.') # Loop over all the guess zmas to find a TS opt_ret = None for idx, zma in enumerate(guess_zmas): print('\nAttempting optimization of', 'guess Z-Matrix {}...'.format(idx + 1)) # Run the transition state optimization es_runner.run_job( job='optimization', script_str=opt_script_str, run_fs=run_fs, geom=zma, spc_info=ts_info, thy_info=mod_thy_info, saddle=True, overwrite=overwrite, **opt_kwargs, ) # Read the contents of the optimization opt_success, opt_ret = es_runner.read_job( job='optimization', run_fs=run_fs, ) # If successful, break loop. If not, try constrained opt+full opt seq if opt_success: break else: print() # es_runner.run_job( # job='optimization', # script_str=opt_script_str, # run_fs=run_fs, # geom=zma, # spc_info=ts_info, # thy_info=mod_thy_info, # frozen_coordinates=frozen_coordinates, # saddle=True, # overwrite=overwrite, # **opt_kwargs, # ) return opt_ret
def _kickoff_saddle(geo, disp_xyzs, spc_info, mod_thy_info, 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 """ # Set the filesys thy_run_fs[-1].create(mod_thy_info[1:4]) thy_run_path = thy_run_fs[-1].path(mod_thy_info[1:4]) run_fs = autofile.fs.run(thy_run_path) # Set the displacement vectors and displace geometry disp_len = kickoff_size * phycon.ANG2BOHR if kickoff_backward: disp_len *= -1 disp_xyzs = numpy.multiply(disp_xyzs, disp_len) print('geo test in kickoff_saddle:') print(automol.geom.string(geo), disp_xyzs) geo = automol.geom.displace(geo, disp_xyzs) # Optimize displaced geometry if opt_cart: geom = geo else: geom = automol.geom.zmatrix(geo) es_runner.run_job( job=elstruct.Job.OPTIMIZATION, script_str=opt_script_str, run_fs=run_fs, geom=geom, spc_info=spc_info, thy_info=mod_thy_info, overwrite=True, **kwargs, ) success, ret = es_runner.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if success: inf_obj, _, out_str = ret prog = inf_obj.prog geo = elstruct.reader.opt_geometry(prog, out_str) return geo
def saddle_point_hessian(opt_ret, ts_info, mod_thy_info, run_fs, script_str, overwrite, **opt_kwargs): """ run things for checking Hessian """ # 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 es_runner.run_job( job='hessian', script_str=script_str, run_fs=run_fs, geom=geo, spc_info=ts_info, thy_info=mod_thy_info, overwrite=overwrite, **opt_kwargs, ) # Read the contents of the optimization hess_success, hess_ret = es_runner.read_job( job='hessian', run_fs=run_fs, ) # 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) freq_run_path = run_fs[-1].path(['hessian']) run_fs[-1].create(['hessian']) freqs, _, imags, _ = structure.vib.projrot_freqs([geo], [hess], freq_run_path) else: freqs, imags = [], [] return hess_ret, freqs, imags
def run_tau(zma, spc_info, thy_info, nsamp, tors_range_dct, tau_run_fs, tau_save_fs, script_str, overwrite, saddle, **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[0].create() vma = automol.zmatrix.var_(zma) if tau_save_fs[0].file.vmatrix.exists(): existing_vma = tau_save_fs[0].file.vmatrix.read() assert vma == existing_vma tau_save_fs[0].file.vmatrix.write(vma) idx = 0 nsamp0 = nsamp inf_obj = autofile.schema.info_objects.tau_trunk(0, tors_range_dct) while True: if tau_save_fs[0].file.info.exists(): inf_obj_s = tau_save_fs[0].file.info.read() nsampd = inf_obj_s.nsamp elif tau_run_fs[0].file.info.exists(): inf_obj_r = tau_run_fs[0].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 print(" New nsamp is {:d}.".format(nsamp)) samp_zma, = automol.zmatrix.samples(zma, 1, tors_range_dct) tid = autofile.schema.generate_new_tau_id() locs = [tid] tau_run_fs[-1].create(locs) tau_run_prefix = tau_run_fs[-1].path(locs) run_fs = autofile.fs.run(tau_run_prefix) idx += 1 print("Run {}/{}".format(idx, nsamp0)) print('\nChecking if ZMA has high repulsion...') if automol.intmol.low_repulsion_struct(zma, samp_zma): print('ZMA fine.') es_runner.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_info=thy_info, saddle=saddle, overwrite=overwrite, frozen_coordinates=tors_range_dct.keys(), **kwargs) else: print('repulsive ZMA:') inp_str = elstruct.writer.optimization( geom=samp_zma, charge=spc_info[1], mult=spc_info[2], method=thy_info[1], basis=thy_info[2], prog=thy_info[0], orb_type=thy_info[3], mol_options=['nosym'], frozen_coordinates=tors_range_dct.keys(), ) tau_run_fs[-1].file.geometry_input.write(inp_str, locs) print('geometry for bad ZMA at', tau_run_fs[-1].path(locs)) # nsampd += 1 # inf_obj.nsamp = nsampd # tau_save_fs[0].file.info.write(inf_obj) # tau_run_fs[0].file.info.write(inf_obj) if tau_save_fs[0].file.info.exists(): inf_obj_s = tau_save_fs[0].file.info.read() nsampd = inf_obj_s.nsamp elif tau_run_fs[0].file.info.exists(): inf_obj_r = tau_run_fs[0].file.info.read() nsampd = inf_obj_r.nsamp nsampd += 1 inf_obj.nsamp = nsampd tau_save_fs[0].file.info.write(inf_obj) tau_run_fs[0].file.info.write(inf_obj)
def _check_imaginary(spc_info, geo, mod_thy_info, thy_run_fs, script_str, overwrite=False, **kwargs): """ check if species has an imaginary frequency """ # Handle filesystem thy_run_fs[-1].create(mod_thy_info[1:4]) thy_run_path = thy_run_fs[-1].path(mod_thy_info[1:4]) run_fs = autofile.fs.run(thy_run_path) # Initialize info imag = False disp_xyzs = [] hess = ((), ()) # Run Hessian calculation es_runner.run_job( job=elstruct.Job.HESSIAN, spc_info=spc_info, thy_info=mod_thy_info, geom=geo, run_fs=run_fs, script_str=script_str, overwrite=overwrite, **kwargs, ) # Check for imaginary modes success, ret = es_runner.read_job(job=elstruct.Job.HESSIAN, run_fs=run_fs) if success: inf_obj, _, out_str = ret prog = inf_obj.prog hess = elstruct.reader.hessian(prog, out_str) # Calculate vibrational frequencies if hess: imag = False _, _, imag_freq, _ = structure.vib.projrot_freqs([geo], [hess], thy_run_path) 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)) norm_coos = elstruct.reader.normal_coords(prog, out_str) im_norm_coo = norm_coos[0] disp_xyzs = im_norm_coo return imag, disp_xyzs
def run_vpt2(zma, geo, spc_info, thy_info, geo_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=True, **kwargs): """ Perform vpt2 analysis for the geometry in the given location """ # Set the run filesystem information run_fs = autofile.fs.run(geo_run_path) # Assess if symmetry needs to be broken for the calculation # Add porgram check because might only be issue for gaussian if spc_info[0] in symm.HIGH: if zma is not None: disp = symm.HIGH[spc_info[0]] * phycon.ANG2BOHR vals = automol.zmatrix.values(zma) job_geo = automol.zmatrix.set_values( zma, {'R1': vals['R1'] + disp}) is_atom = automol.geom.is_atom( automol.zmatrix.geometry(job_geo)) else: print('Need a zma for high-symmetry of {}.'.format(spc_info[0]), 'Skipping task') job_geo = None is_atom = False else: if zma is not None: job_geo = zma is_atom = automol.geom.is_atom(automol.zmatrix.geometry(job_geo)) else: job_geo = geo is_atom = automol.geom.is_atom(job_geo) if is_atom: print('Species is an atom, Skipping VPT2 task.') if job_geo is not None and not is_atom: exists = geo_save_fs[-1].file.anharmonicity_matrix.exists(locs) if not exists: print('No X-Matrix found in save filesys. Running VPT2...') _run = True elif overwrite: print('User specified to overwrite VPT2 info with new run...') _run = True else: _run = False if _run: es_runner.run_job( job='vpt2', script_str=script_str, run_fs=run_fs, geom=job_geo, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, retryfail=retryfail, **kwargs, ) success, ret = es_runner.read_job( job='vpt2', run_fs=run_fs, ) if success: inf_obj, inp_str, out_str = ret # if not geo_save_fs[-1].file.hessian.exists(locs): # print(" - No Hessian in filesys.", # "Reading it from output...") # hess = elstruct.reader.hessian(inf_obj.prog, out_str) # print(" - Saving Hessian...") # print(" - Save path: {}".format(geo_save_path)) # geo_save_fs[-1].file.hessian_info.write(inf_obj, locs) # geo_save_fs[-1].file.hessian_input.write(inp_str, locs) # geo_save_fs[-1].file.hessian.write(hess, locs) print(" - Reading anharmonicities from output...") vpt2_dct = elstruct.reader.vpt2(inf_obj.prog, out_str) # hess = elstruct.reader.hessian(inf_obj.prog, out_str) # Write the VPT2 file specifying the Fermi Treatments # fermi_treatment = '{} Defaults'.format(inf_obj.prog) # vpt2_inf_obj = autofile.schema.info.vpt2( # fermi_treatment=fermi_treatment) print(" - Saving anharmonicities...") print(" - Save path: {}".format(geo_save_path)) # geo_save_fs[-1].file.vpt2_info.write(inf_obj, locs) geo_save_fs[-1].file.vpt2_input.write(inp_str, locs) geo_save_fs[-1].file.anharmonic_frequencies.write( vpt2_dct['freqs'], locs) geo_save_fs[-1].file.anharmonic_zpve.write( vpt2_dct['zpve'], locs) geo_save_fs[-1].file.vibro_rot_alpha_matrix.write( vpt2_dct['vibrot_mat'], locs) geo_save_fs[-1].file.quartic_centrifugal_dist_consts.write( vpt2_dct['cent_dist_const'], locs) geo_save_fs[-1].file.anharmonicity_matrix.write( vpt2_dct['x_mat'], locs) else: print('VPT2 information found and saved previously at {}'.format( geo_save_path))
def run_prop(zma, geo, spc_info, thy_info, geo_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=True, **kwargs): """ Determine the properties in the given location """ # Set input geom if geo is not None: job_geo = geo else: job_geo = automol.zmatrix.geometry(zma) if _json_database(geo_save_path): dmom_exists = geo_save_fs[-1].json.dipole_moment.exists(locs) polar_exists = geo_save_fs[-1].json.polarizability.exists(locs) else: dmom_exists = geo_save_fs[-1].file.dipole_moment.exists(locs) polar_exists = geo_save_fs[-1].file.polarizability.exists(locs) if not dmom_exists or not polar_exists: print('Either no dipole moment or polarizability found in' 'in save filesys. Running properties...') _run = True elif overwrite: print('User specified to overwrite property with new run...') _run = True else: _run = False if _run: run_fs = autofile.fs.run(geo_run_path) es_runner.run_job( job='molec_properties', script_str=script_str, run_fs=run_fs, geom=job_geo, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, retryfail=retryfail, **kwargs, ) success, ret = es_runner.read_job( job='molec_properties', run_fs=run_fs, ) if success: inf_obj, inp_str, out_str = ret print(" - Reading dipole moment from output...") dmom = elstruct.reader.dipole_moment(inf_obj.prog, out_str) print(" - Reading polarizability from output...") polar = elstruct.reader.polarizability(inf_obj.prog, out_str) print('dip mom', dmom) print('polar', polar) print(" - Saving dipole moment and polarizability...") if _json_database(geo_save_path): # geo_save_fs[-1].json.property_info.write(inf_obj, locs) # geo_save_fs[-1].json.property_input.write( # inp_str, locs) geo_save_fs[-1].json.dipole_moment.write(dmom, locs) geo_save_fs[-1].json.polarizability.write(polar, locs) else: # geo_save_fs[-1].file.property_info.write(inf_obj, locs) # geo_save_fs[-1].file.property_input.write( # inp_str, locs) geo_save_fs[-1].file.dipole_moment.write(dmom, locs) geo_save_fs[-1].file.polarizability.write(polar, locs) print(" - Save path: {}".format(geo_save_path)) else: print('Dipole moment and polarizability found and', 'saved previously at {}'.format(geo_save_path))
def run_energy(zma, geo, spc_info, thy_info, geo_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=True, highspin=False, **kwargs): """ Find the energy for the given structure """ # geo_save_fs and locs unneeded for this _, _ = geo_save_fs, locs # Prepare unique filesystem since many energies may be under same directory if not highspin: sp_run_fs = autofile.fs.single_point(geo_run_path) sp_save_fs = autofile.fs.single_point(geo_save_path) else: sp_run_fs = autofile.fs.high_spin(geo_run_path) sp_save_fs = autofile.fs.high_spin(geo_save_path) sp_run_fs[-1].create(thy_info[1:4]) sp_run_path = sp_run_fs[-1].path(thy_info[1:4]) sp_save_fs[-1].create(thy_info[1:4]) sp_save_path = sp_save_fs[-1].path(thy_info[1:4]) run_fs = autofile.fs.run(sp_run_path) # Set input geom if geo is not None: job_geo = geo else: job_geo = zma exists = sp_save_fs[-1].file.energy.exists(thy_info[1:4]) if not exists: print('No energy found in save filesys. Running energy...') _run = True elif overwrite: print('User specified to overwrite energy with new run...') _run = True else: _run = False if _run: # Add options matrix for energy runs for molpro if thy_info[0] == 'molpro2015': errs, optmat = es_runner.molpro_opts_mat(spc_info, geo) else: errs = () optmat = () es_runner.run_job( job='energy', script_str=script_str, run_fs=run_fs, geom=job_geo, spc_info=spc_info, thy_info=thy_info, errors=errs, options_mat=optmat, overwrite=overwrite, retryfail=retryfail, **kwargs, ) success, ret = es_runner.read_job( job='energy', run_fs=run_fs, ) if success: 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("Energy: {}".format(ene)) print(" - Saving energy...") sp_save_fs[-1].file.input.write(inp_str, thy_info[1:4]) sp_save_fs[-1].file.info.write(inf_obj, thy_info[1:4]) sp_save_fs[-1].file.energy.write(ene, thy_info[1:4]) print(" - Save path: {}".format(sp_save_path)) else: print('Energy found and saved previously at {}'.format( sp_save_path)) ene = sp_save_fs[-1].file.energy.read(thy_info[1:4]) print("Energy: {}".format(ene))
def run_hessian(zma, geo, spc_info, thy_info, geo_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=True, **kwargs): """ Determine the hessian for the geometry in the given location """ # Set the run filesystem information run_fs = autofile.fs.run(geo_run_path) # if prog == 'molpro2015': # geo = hess_geometry(out_str) # scn_save_fs[-1].file.geometry.write(geo, locs) # Set input geom # Warning using internal coordinates leads to inconsistencies with Gaussian # For this reason we only use Cartesians to generate the Hessian if geo is not None: job_geo = geo else: job_geo = automol.zmatrix.geometry(zma) is_atom = automol.geom.is_atom(job_geo) if not is_atom: if _json_database(geo_save_path): exists = geo_save_fs[-1].json.hessian.exists(locs) else: exists = geo_save_fs[-1].file.hessian.exists(locs) if not exists: print('No Hessian found in save filesys. Running Hessian...') _run = True elif overwrite: print('User specified to overwrite Hessian with new run...') _run = True else: _run = False if _run: run_fs = autofile.fs.run(geo_run_path) es_runner.run_job( job='hessian', script_str=script_str, run_fs=run_fs, geom=job_geo, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, retryfail=retryfail, **kwargs, ) success, ret = es_runner.read_job( job='hessian', run_fs=run_fs, ) if success: inf_obj, inp_str, out_str = ret print(" - Reading hessian from output...") hess = elstruct.reader.hessian(inf_obj.prog, out_str) print(" - Saving Hessian...") if _json_database(geo_save_path): geo_save_fs[-1].json.hessian_info.write(inf_obj, locs) geo_save_fs[-1].json.hessian_input.write(inp_str, locs) geo_save_fs[-1].json.hessian.write(hess, locs) else: geo_save_fs[-1].file.hessian_info.write(inf_obj, locs) geo_save_fs[-1].file.hessian_input.write(inp_str, locs) geo_save_fs[-1].file.hessian.write(hess, locs) print(" - Save path: {}".format(geo_save_path)) if thy_info[0] == 'gaussian09': _hess_grad(inf_obj.prog, out_str, geo_save_fs, geo_save_path, locs, overwrite) _hess_freqs(geo, geo_save_fs, geo_run_path, geo_save_path, locs, overwrite) else: print('Hessian found and saved previously at {}'.format( geo_save_path)) _hess_freqs(geo, geo_save_fs, geo_run_path, geo_save_path, locs, overwrite) else: print('Species is an atom. Skipping Hessian task.')
def run_gradient(zma, geo, spc_info, thy_info, geo_save_fs, geo_run_path, geo_save_path, locs, script_str, overwrite, retryfail=True, **kwargs): """ Determine the gradient for the geometry in the given location """ # Set input geom if geo is not None: job_geo = geo else: job_geo = automol.zmatrix.geometry(zma) is_atom = automol.geom.is_atom(job_geo) if not is_atom: if _json_database(geo_save_path): exists = geo_save_fs[-1].json.gradient.exists(locs) else: exists = geo_save_fs[-1].file.gradient.exists(locs) if not exists: print('No gradient found in save filesys. Running gradient...') _run = True elif overwrite: print('User specified to overwrite gradient with new run...') _run = True else: _run = False if _run: run_fs = autofile.fs.run(geo_run_path) es_runner.run_job( job='gradient', script_str=script_str, run_fs=run_fs, geom=job_geo, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, retryfail=retryfail, **kwargs, ) success, ret = es_runner.read_job( job='gradient', run_fs=run_fs, ) if success: inf_obj, inp_str, out_str = ret if is_atom: grad = () else: print(" - Reading gradient from output...") grad = elstruct.reader.gradient(inf_obj.prog, out_str) print(" - Saving gradient...") if _json_database(geo_save_path): geo_save_fs[-1].json.gradient_info.write(inf_obj, locs) geo_save_fs[-1].json.gradient_input.write( inp_str, locs) geo_save_fs[-1].json.gradient.write(grad, locs) else: geo_save_fs[-1].file.gradient_info.write(inf_obj, locs) geo_save_fs[-1].file.gradient_input.write( inp_str, locs) geo_save_fs[-1].file.gradient.write(grad, locs) print(" - Save path: {}".format(geo_save_path)) else: print('Gradient found and saved previously at {}'.format( geo_save_path)) else: print('Species is an atom. Skipping gradient task.')
def run_conformers(zma, spc_info, thy_info, nsamp, tors_range_dct, cnf_run_fs, cnf_save_fs, script_str, overwrite, saddle, two_stage, retryfail, **kwargs): """ run sampling algorithm to find conformers """ if not tors_range_dct: print(" - No torsional coordinates. Setting nsamp to 1.") nsamp = 1 cnf_save_fs[0].create() # following check breaks; prob add checks to zmas in idv confs # kind of pain # ignoring the idea of storing multiple zmas right now # vma = automol.zmatrix.var_(zma) # if cnf_save_fs[0].file.vmatrix.exists(): # existing_vma = cnf_save_fs[0].file.vmatrix.read() # assert vma == existing_vma # cnf_save_fs[0].file.vmatrix.write(vma) nsamp0 = nsamp inf_obj = autofile.schema.info_objects.conformer_trunk(0) if cnf_save_fs[0].file.info2.exists(): inf_obj_s = cnf_save_fs[0].file.info2.read() nsampd = inf_obj_s.nsamp elif cnf_run_fs[0].file.info2.exists(): inf_obj_r = cnf_run_fs[0].file.info2.read() nsampd = inf_obj_r.nsamp else: nsampd = 0 tot_samp = nsamp - nsampd print(' - Number of samples that have been currently run:', nsampd) print(' - Number of samples requested:', nsamp) if nsamp - nsampd > 0: print('\nRunning {} samples...'.format(nsamp - nsampd)) samp_idx = 1 while True: nsamp = nsamp0 - nsampd # Break the while loop if enough sampls completed if nsamp <= 0: print('Requested number of samples have been completed. ' 'Conformer search complete.') break # Run the conformer sampling if nsampd > 0: samp_zma, = automol.zmatrix.samples(zma, 1, tors_range_dct) else: samp_zma = zma print('\nChecking if ZMA has high repulsion...') # print('zma tests:', # automol.zmatrix.string(zma), automol.zmatrix.string(zma)) bad_geom_count = 0 while (not automol.intmol.low_repulsion_struct(zma, samp_zma) and bad_geom_count < 1000): print(' ZMA has high repulsion.') # print(' Bad geometry:') # print(automol.geom.string(automol.zmatrix.geometry(samp_zma))) print('\n Generating new sample ZMA') samp_zma, = automol.zmatrix.samples(zma, 1, tors_range_dct) bad_geom_count += 1 print(' ZMA is fine...') cid = autofile.schema.generate_new_conformer_id() locs = [cid] cnf_run_fs[-1].create(locs) cnf_run_path = cnf_run_fs[-1].path(locs) run_fs = autofile.fs.run(cnf_run_path) print("Run {}/{}".format(samp_idx, tot_samp)) tors_names = list(tors_range_dct.keys()) if two_stage and tors_names: print('Stage one beginning, holding the coordinates constant', tors_names) es_runner.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, frozen_coordinates=[tors_names], saddle=saddle, retryfail=retryfail, **kwargs) # print('Stage one success, reading for stage 2') success, ret = es_runner.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if success: 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') # print('Stage one success beginning stage two on', samp_zma) es_runner.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, saddle=saddle, retryfail=False, **kwargs) else: es_runner.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=samp_zma, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, saddle=saddle, retryfail=retryfail, **kwargs) if cnf_save_fs[0].file.info2.exists(): inf_obj_s = cnf_save_fs[0].file.info2.read() nsampd = inf_obj_s.nsamp elif cnf_run_fs[0].file.info2.exists(): inf_obj_r = cnf_run_fs[0].file.info2.read() nsampd = inf_obj_r.nsamp nsampd += 1 samp_idx += 1 inf_obj.nsamp = nsampd cnf_save_fs[0].file.info2.write(inf_obj) cnf_run_fs[0].file.info2.write(inf_obj)
def single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=True, saddle=False, **kwargs): """ generate single optimized geometry to be saved into a filesystem """ # Build the filesystem locs = [autofile.schema.generate_new_conformer_id()] cnf_run_fs[-1].create(locs) cnf_run_path = cnf_run_fs[-1].path(locs) run_fs = autofile.fs.run(cnf_run_path) # Run the optimization print('Optimizing a single conformer') es_runner.run_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geom=zma, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, frozen_coordinates=(), saddle=saddle, retryfail=retryfail, **kwargs) # print('Stage one success, reading for stage 2') success, ret = es_runner.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs) if success: inf_obj, _, out_str = 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) saved_locs, saved_geos, saved_enes = _saved_cnf_info( cnf_save_fs, mod_thy_info) if _geo_unique(geo, ene, saved_geos, saved_enes, saddle): sym_id = _sym_unique(geo, ene, saved_geos, saved_enes) if sym_id is None: _save_unique_conformer(ret, mod_thy_info, cnf_save_fs, locs, saddle=saddle, zma_locs=(0, )) saved_geos.append(geo) saved_enes.append(ene) saved_locs.append(locs) # Update the conformer trajectory file print('') filesys.mincnf.traj_sort(cnf_save_fs, mod_thy_info)
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: print('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)): 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_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) 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[-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, geom=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: 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[-1].file.geometry.write(geo, thy_info[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[-1].file.energy.write(ene, thy_info[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]['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 _run_scan(guess_zma, spc_info, mod_thy_info, thy_save_fs, coord_names, grid_vals, scn_run_fs, scn_save_fs, scn_typ, script_str, overwrite, errors=(), options_mat=(), retryfail=True, update_guess=True, saddle=False, constraint_dct=None, chkstab=False, **kwargs): """ new run function """ # Get a connected geometry from the init guess_zma for instability checks # conn_geo = automol.zmatrix.geometry(guess_zma) conn_zma = guess_zma # Set the frozen coordinates (set job at this point?) if constraint_dct is not None: frozen_coordinates = tuple(coord_names) + tuple(constraint_dct) else: frozen_coordinates = coord_names # Read the energies and Hessians from the filesystem for vals in grid_vals: # Set the locs for the scan point locs = [coord_names, vals] if constraint_dct is not None: locs = [constraint_dct] + locs # Create the filesys scn_run_fs[-1].create(locs) run_fs = autofile.fs.run(scn_run_fs[-1].path(locs)) # Build the zma zma = automol.zmatrix.set_values( guess_zma, dict(zip(coord_names, vals))) # Set the job job = _set_job(scn_typ) # Run an optimization or energy job, as needed. geo_exists = scn_save_fs[-1].file.geometry.exists(locs) if not geo_exists or overwrite: if job == elstruct.Job.OPTIMIZATION: es_runner.run_job( job=job, script_str=script_str, run_fs=run_fs, geom=zma, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, frozen_coordinates=frozen_coordinates, errors=errors, options_mat=options_mat, retryfail=retryfail, saddle=saddle, **kwargs ) # Read the output for the zma and geo _, opt_zma, opt_geo = filesys.read_zma_geo(run_fs, job) if opt_zma is not None and opt_geo is not None: # Check connectivity, save instability files if needed if chkstab: connected = automol.geom.connected(opt_geo) else: connected = True # If connected and update requested: update geom # If disconnected: save instab files and break loop if connected: if update_guess: guess_zma = opt_zma else: print('WARNING: Structure seems to be unstable...') # _, opt_ret = es_runner.read_job(job=job, run_fs=run_fs) # instab.write_instab( # conn_zma, opt_zma, # thy_save_fs, mod_thy_info[1:4], # opt_ret, # zma_locs=(0,), # save_cnf=False # ) # break else: print('No output found in file') elif job == elstruct.Job.ENERGY: es_runner.run_job( job=job, script_str=script_str, run_fs=run_fs, geom=zma, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, errors=errors, options_mat=options_mat, retryfail=retryfail, **kwargs ) # Run read_job to print status message _, _ = es_runner.read_job(job=job, run_fs=run_fs) # Write initial geos in run fs as they are needed later run_fs[-1].file.zmatrix.write(zma, [job]) run_fs[-1].file.geometry.write( automol.zmatrix.geometry(zma), [job])