def _hess(spc_info, mod_thy_info, geo, run_fs, script_str, **kwargs): """ Calculate the Hessian """ # Run Hessian calculation success, ret = es_runner.execute_job( job=elstruct.Job.HESSIAN, spc_info=spc_info, thy_info=mod_thy_info, geo=geo, zrxn=None, run_fs=run_fs, script_str=script_str, overwrite=True, **kwargs, ) # Read the Hessian if success: inf_obj, _, out_str = ret prog = inf_obj.prog ret_hess = elstruct.reader.hessian(prog, out_str) else: ret_hess = None return ret_hess, ret
def _optimize_atom(spc_info, zma_init, method_dct, cnf_save_fs, locs, run_fs, overwrite): """ Deal with an atom separately """ thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) script_str, kwargs = es_runner.qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) # Call the electronic structure optimizer success, ret = es_runner.execute_job(job=elstruct.Job.ENERGY, script_str=script_str, run_fs=run_fs, geo=zma_init, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs) if success: ioprinter.info_message('Succesful reference geometry optimization') filesys.save.atom(ret, cnf_save_fs, mod_thy_info[1:], zma_init, rng_locs=(locs[0], ), tors_locs=(locs[1], )) return success
def _opt(spc_info, mod_thy_info, geo, run_fs, script_str, opt_cart=True, **kwargs): """ Run an optimization """ # Optimize displaced geometry geom = geo if opt_cart else automol.geom.zmatrix(geo) success, ret = es_runner.execute_job( job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=geom, spc_info=spc_info, thy_info=mod_thy_info, zrxn=None, overwrite=True, **kwargs, ) if success: inf_obj, _, out_str = ret prog = inf_obj.prog ret_geo = elstruct.reader.opt_geometry(prog, out_str) else: ret_geo = None return ret_geo, ret
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 """ ioprinter.info_message('\nOptimizing guess Z-Matrix obtained from scan or filesys...') if len(guess_zmas) == 1: ioprinter.info_message( 'There is 1 guess Z-Matrix', 'to attempt to find saddle point.', newline=1) else: ioprinter.info_message( 'There are {} guess Z-Matrices'.format(len(guess_zmas)), 'to attempt to find saddle point.', newline=1) # Loop over all the guess zmas to find a TS opt_ret = None for idx, zma in enumerate(guess_zmas): ioprinter.info_message('\nOptimizing guess Z-Matrix {}...'.format(idx+1)) # Run the transition state optimization opt_success, opt_ret = es_runner.execute_job( job='optimization', script_str=opt_script_str, run_fs=run_fs, geo=zma, spc_info=ts_info, thy_info=mod_thy_info, saddle=True, overwrite=overwrite, **opt_kwargs, ) # If successful, break loop. If not, try constrained opt+full opt seq if opt_success: break # frozen_coords_lst = ((), tors_names) # success, opt_ret = es_runner.multi_stage_optimization( # script_str=opt_script_str, # run_fs=run_fs, # geo=inp_geom, # spc_info=spc_info, # thy_info=thy_info, # frozen_coords_lst=frozen_coords_lst, # overwrite=overwrite, # saddle=saddle, # retryfail=retryfail, # **kwargs # ) return opt_ret
def _check_imaginary(spc_info, geo, mod_thy_info, run_fs, script_str, overwrite=False, **kwargs): """ check if species has an imaginary frequency """ # Initialize info has_imag = False norm_coords = [] hess = ((), ()) # Run Hessian calculation success, ret = es_runner.execute_job( job=elstruct.Job.HESSIAN, spc_info=spc_info, thy_info=mod_thy_info, geo=geo, run_fs=run_fs, script_str=script_str, overwrite=overwrite, **kwargs, ) # Check for imaginary modes if success: inf_obj, _, out_str = ret prog = inf_obj.prog hess = elstruct.reader.hessian(prog, out_str) # Calculate vibrational frequencies if hess: run_path = run_fs[-1].path([elstruct.Job.HESSIAN]) # run_path = run_fs[-1].path(['VIB']) script_str = autorun.SCRIPT_DCT['projrot'] _, _, imag_freq, _ = autorun.projrot.frequencies( script_str, run_path, [geo], [[]], [hess]) # Mode for now set the imaginary frequency check to -100: # Should decrease once freq projector functions properly if imag_freq: ioprinter.warning_message('Imaginary mode found:') norm_coords = elstruct.reader.normal_coordinates(prog, out_str) has_imag = True return has_imag, norm_coords
def _kickoff_saddle(geo, norm_coords, spc_info, mod_thy_info, run_fs, opt_script_str, kickoff_size=0.1, kickoff_backward=False, kickoff_mode=0, opt_cart=True, **kwargs): """ kickoff from saddle to find connected minima """ # Choose the displacement xyzs disp_xyzs = norm_coords[kickoff_mode] # 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) ioprinter.debug_message( 'geo test in kickoff_saddle:', 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) success, ret = es_runner.execute_job( job=elstruct.Job.OPTIMIZATION, script_str=opt_script_str, run_fs=run_fs, geo=geom, spc_info=spc_info, thy_info=mod_thy_info, overwrite=True, **kwargs, ) if success: inf_obj, _, out_str = ret prog = inf_obj.prog geo = elstruct.reader.opt_geometry(prog, out_str) return geo, ret
def saddle_point_hessian(opt_ret, ts_info, method_dct, run_fs, run_prefix, overwrite): """ run things for checking Hessian """ mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) script_str, kwargs = qchem_params(method_dct) # Obtain geometry from optimization opt_inf_obj, _, opt_out_str = opt_ret opt_prog = opt_inf_obj.prog geo = elstruct.reader.opt_geometry(opt_prog, opt_out_str) # Run a Hessian hess_success, hess_ret = es_runner.execute_job( job='hessian', script_str=script_str, run_fs=run_fs, geo=geo, spc_info=ts_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs, ) # If successful, Read the geom and energy from the optimization if hess_success: hess_inf_obj, _, hess_out_str = hess_ret hess = elstruct.reader.hessian(hess_inf_obj.prog, hess_out_str) fml_str = automol.geom.formula_string(geo) vib_path = job_path(run_prefix, 'PROJROT', 'FREQ', fml_str) run_fs[-1].create(['hessian']) script_str = autorun.SCRIPT_DCT['projrot'] freqs, _, imags, _ = autorun.projrot.frequencies( script_str, vib_path, [geo], [[]], [hess]) else: freqs, imags = [], [] return hess_ret, freqs, imags
def optimize_saddle_point(guess_zmas, ts_dct, method_dct, mref_kwargs, runfs_dct, es_keyword_dct, cnf_locs): """ Optimize the transition state structure obtained from the grid search """ # Get info (move later) ts_info = rinfo.ts_info(ts_dct['rxn_info']) mod_thy_info = tinfo.modify_orb_label(tinfo.from_dct(method_dct), ts_info) overwrite = es_keyword_dct['overwrite'] ts_info = rinfo.ts_info(ts_dct['rxn_info']) runlvl_cnf_run_fs = runfs_dct['runlvl_cnf'] runlvl_cnf_run_fs[-1].create(cnf_locs) run_fs = autofile.fs.run(runlvl_cnf_run_fs[-1].path(cnf_locs)) ioprinter.info_message( f'There are {len(guess_zmas)} guess Z-Matrices' 'to attempt to find saddle point.', newline=1) # Loop over all the guess zmas to find a TS opt_ret, hess_ret = None, None for idx, zma in enumerate(guess_zmas): ioprinter.info_message(f'\nOptimizing guess Z-Matrix {idx+1}...') # Run the transition state optimization script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) kwargs.update(mref_kwargs) opt_success, opt_ret = es_runner.execute_job( job='optimization', script_str=script_str, run_fs=run_fs, geo=zma, spc_info=ts_info, thy_info=mod_thy_info, saddle=True, overwrite=overwrite, **kwargs, ) if opt_success: break if opt_success: script_str, kwargs = qchem_params(method_dct) # Obtain geometry from optimization opt_inf_obj, _, opt_out_str = opt_ret opt_prog = opt_inf_obj.prog geo = elstruct.reader.opt_geometry(opt_prog, opt_out_str) # Run a Hessian _, hess_ret = es_runner.execute_job( job='hessian', script_str=script_str, run_fs=run_fs, geo=geo, spc_info=ts_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs, ) return opt_ret, hess_ret
def ring_conformer_sampling(zma, spc_info, thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, nsamp_par=(False, 3, 1, 3, 50, 50), ring_tors_dct=None, zrxn=None, two_stage=False, retryfail=False, **kwargs): """ run sampling algorithm to find conformers """ # Build filesys cnf_save_fs[0].create() inf_obj = autofile.schema.info_objects.conformer_trunk(0) # Set up torsions geo = automol.zmat.geometry(zma) check_dct = { 'dist': 3.5e-1, 'coulomb': 1.5e-2, } _, saved_geos, _ = _saved_cnf_info(cnf_save_fs, thy_info) frag_saved_geos = [] for geoi in saved_geos: frag_saved_geos.append(automol.geom.fragment_ring_geo(geoi)) # Make sample zmas unique_geos, unique_frag_geos, unique_zmas = [], [], [] tors_dcts = ring_tors_dct.items() if ring_tors_dct is not None else {} for ring_atoms, samp_range_dct in tors_dcts: ring_atoms = [int(idx) - 1 for idx in ring_atoms.split('-')] dist_value_dct = automol.zmat.ring_distances(zma, ring_atoms) nsamp = _num_samp_zmas(ring_atoms, nsamp_par) samp_zmas = automol.zmat.samples(zma, nsamp, samp_range_dct) for samp_zma in samp_zmas: if automol.ring_distances_passes(samp_zma, ring_atoms, dist_value_dct): samp_geo = automol.zmat.geometry(samp_zma) frag_samp_geo = automol.geom.fragment_ring_geo(samp_geo) if automol.geom.ring_angles_passes(samp_geo, ring_atoms): if not automol.pot.low_repulsion_struct(geo, samp_geo): frag_samp_unique = automol.geom.is_unique( frag_samp_geo, frag_saved_geos, check_dct) samp_unique = automol.geom.is_unique( samp_geo, unique_frag_geos, check_dct) if frag_samp_unique: if samp_unique: unique_zmas.append(samp_zma) unique_geos.append(samp_geo) unique_frag_geos.append(frag_samp_geo) # Set the samples nsamp = len(unique_zmas) nsamp0 = nsamp nsampd = _calc_nsampd(cnf_save_fs, cnf_run_fs) tot_samp = nsamp - nsampd ioprinter.info_message( ' - Number of samples that have been currently run:', nsampd) ioprinter.info_message(' - Number of samples requested:', nsamp) if nsamp - nsampd > 0: ioprinter.info_message('Running {} samples...'.format(nsamp - nsampd), newline=1) samp_idx = 1 for samp_zma in unique_zmas: nsamp = nsamp0 - nsampd # Break the while loop if enough sampls completed if nsamp <= 0: ioprinter.info_message( 'Requested number of samples have been completed.', 'Conformer search complete.') break # Run the conformer sampling samp_geo = automol.zmat.geometry(samp_zma) rid = autofile.schema.generate_new_ring_id() cid = autofile.schema.generate_new_conformer_id() locs = (rid, cid) cnf_run_fs[-1].create(locs) cnf_run_path = cnf_run_fs[-1].path(locs) run_fs = autofile.fs.run(cnf_run_path) ioprinter.info_message("Run {}/{}".format(samp_idx, tot_samp)) tors_names = tuple( set(names for tors_dct in ring_tors_dct.values() for names in tors_dct.keys())) if two_stage and tors_names: frozen_coords_lst = ((), tors_names) success, ret = es_runner.multi_stage_optimization( script_str=script_str, run_fs=run_fs, geo=samp_zma, spc_info=spc_info, thy_info=thy_info, frozen_coords_lst=frozen_coords_lst, overwrite=overwrite, saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) else: success, ret = es_runner.execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=samp_zma, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) # save function added here if success: _save_conformer(ret, cnf_save_fs, locs, thy_info, zrxn=zrxn, orig_ich=spc_info[0], rid_traj=False, init_zma=samp_zma) nsampd = _calc_nsampd(cnf_save_fs, cnf_run_fs) nsampd += 1 samp_idx += 1 inf_obj.nsamp = nsampd cnf_save_fs[0].file.info.write(inf_obj) cnf_run_fs[0].file.info.write(inf_obj)
def run_vpt2(zma, geo, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, script_str, overwrite, zrxn=None, retryfail=True, method_dct=None, ref_val=None, **kwargs): """ Perform vpt2 analysis for the geometry in the given location """ # Set unneeded vals _, _, _, _ = zrxn, method_dct, ref_val, run_prefix # Set the run filesystem information geo_run_path = geo_run_fs[-1].path(locs) geo_save_path = geo_save_fs[-1].path(locs) 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.zmat.value_dictionary(zma) job_geo = automol.zmat.set_values_by_name( zma, {'R1': vals['R1'] + disp}) is_atom = automol.geom.is_atom(automol.zmat.geometry(job_geo)) else: ioprinter.warning_message( f'Need a zma for high-symmetry of {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.zmat.geometry(job_geo)) else: job_geo = geo is_atom = automol.geom.is_atom(job_geo) if is_atom: ioprinter.info_message('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: ioprinter.info_message( 'No X-Matrix found in save filesys. Running VPT2...') _run = True elif overwrite: ioprinter.info_message( 'User specified to overwrite VPT2 info with new run...') _run = True else: _run = False if _run: success, ret = es_runner.execute_job( job=elstruct.Job.VPT2, script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, zrxn=zrxn, overwrite=overwrite, retryfail=retryfail, **kwargs, ) if success: inf_obj, inp_str, out_str = ret ioprinter.info_message( " - Reading anharmonicities from output...") vpt2_dct = elstruct.reader.vpt2(inf_obj.prog, out_str) ioprinter.save_anharmonicity(geo_save_path) 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) geo_save_fs[-1].file.cubic_force_constants.write( vpt2_dct['cubic_fc'], locs) geo_save_fs[-1].file.quartic_force_constants.write( vpt2_dct['quartic_fc'], locs) else: ioprinter.existing_path('VPT2 information', geo_save_path)
def run_energy(zma, geo, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, script_str, overwrite, zrxn=None, retryfail=True, method_dct=None, highspin=False, ref_val=None, **kwargs): """ Assesses if an electronic energy exists in the CONFS/SP/THY layer of the save filesys for a species at the specified level of theory. If an energy does not exist, or if a user requests overwrite, the appropriate electronic struture calculation is set-up, launched, and then parsed within the run filesys, then that the energy and job input is written into the save filesys. :param zma: Z-Matrix for molecular structure to perform calculation :type zma: automol.zmat object :param geo: goemetry for molecular structure to perform calculation :type geo: automol.geom object :param spc_info: :type spc_info: :param thy_info: :type thy_info: :geo_run_fs: filesystem object for layer where structure is in RUN :geo_run_fs: autofile.fs object :geo_save_fs: filesystem object for layer where structure is in SAVE :geo_save_fs: autofile.fs object :param script_str: shell script for executing electronic structure job :type script_str: str :param overwrite: """ # Set unneeded vals to _, _, _, _ = zrxn, method_dct, ref_val, run_prefix geo_run_path = geo_run_fs[-1].path(locs) geo_save_path = geo_save_fs[-1].path(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_path = sp_run_fs[-1].path(thy_info[1:4]) sp_save_path = sp_save_fs[-1].path(thy_info[1:4]) # 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: ioprinter.info_message( 'No energy found in save filesys. Running energy...') _run = True elif overwrite: ioprinter.info_message( 'User specified to overwrite energy with new run...') _run = True else: _run = False if _run: # Add options matrix for energy runs for molpro _kwargs = copy.deepcopy(kwargs) if thy_info[0] == 'molpro2015': errs, optmat = es_runner.molpro_opts_mat(spc_info, geo) _kwargs.update({'errors': errs, 'options_mat': optmat}) sp_run_fs[-1].create(thy_info[1:4]) run_fs = autofile.fs.run(sp_run_path) success, ret = es_runner.execute_job( job=elstruct.Job.ENERGY, script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, zrxn=zrxn, overwrite=overwrite, retryfail=retryfail, **_kwargs, ) if success: inf_obj, inp_str, out_str = ret ioprinter.info_message(" - Reading energy from output...") ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) ioprinter.energy(ene) sp_save_fs[-1].create(thy_info[1:4]) 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]) ioprinter.save_energy(sp_save_path) else: ioprinter.existing_path('Energy', sp_save_path) ene = sp_save_fs[-1].file.energy.read(thy_info[1:4]) ioprinter.energy(ene) ioprinter.info_message('')
def conformer_sampling(zma, spc_info, thy_info, cnf_run_fs, cnf_save_fs, rid, script_str, overwrite, nsamp_par=(False, 3, 3, 1, 50, 50), tors_names=(), zrxn=None, two_stage=False, retryfail=False, resave=False, repulsion_thresh=40.0, print_debug=True, **kwargs): """ run sampling algorithm to find conformers """ # Check if any saving needs to be done before hand cnf_run_fs[1].create([rid]) if resave: _presamp_save(spc_info, cnf_run_fs, cnf_save_fs, thy_info, zrxn=zrxn, rid=rid) # Build filesys cnf_save_fs[1].create([rid]) inf_obj = autofile.schema.info_objects.conformer_branch(0) # Set the samples nsamp, tors_range_dct = util.calc_nsamp(tors_names, nsamp_par, zma, zrxn=zrxn) nsamp0 = nsamp nsampd = util.calc_nsampd(cnf_save_fs, cnf_run_fs, rid) tot_samp = nsamp - nsampd brk_tot_samp = nsamp * 5 info_message(' - Number of samples that have been currently run:', nsampd) info_message(' - Number of samples requested:', nsamp) if nsamp - nsampd > 0: info_message(f'Running {nsamp-nsampd} samples...', newline=1) # Generate all of the conformers, as needed samp_idx = 1 samp_attempt_idx = 1 while True: nsamp = nsamp0 - nsampd # Break the while loop if enough sampls completed if nsamp <= 0: info_message('Requested number of samples have been completed.', 'Conformer search complete.') break if samp_attempt_idx == brk_tot_samp: info_message(f'Max sample num: 5*{nsamp} attempted, ending search', 'Run again if more samples desired.') break # Run the conformer sampling if nsampd > 0: samp_zma, = automol.zmat.samples(zma, 1, tors_range_dct) else: samp_zma = zma info_message('Generating sample Z-Matrix that does not have', 'high intramolecular repulsion...') bad_geo_cnt = 0 ref_pot = automol.pot.intramol_interaction_potential_sum( automol.zmat.geometry(zma)) samp_pot = automol.pot.intramol_interaction_potential_sum( automol.zmat.geometry(samp_zma)) while samp_pot - ref_pot > repulsion_thresh and bad_geo_cnt < 1000: if print_debug: warning_message('Structure has high repulsion.') warning_message( 'Sums of intramol LJ potential interactions [kcal/mol]:', f'Ref:{ref_pot:.2f}, Test:{samp_pot:.2f}, ' f'Diff:{samp_pot-ref_pot:.2f}') warning_message('Generating new sample Z-Matrix') samp_zma, = automol.zmat.samples(zma, 1, tors_range_dct) samp_pot = automol.pot.intramol_interaction_potential_sum( automol.zmat.geometry(samp_zma)) bad_geo_cnt += 1 cid = autofile.schema.generate_new_conformer_id() locs = [rid, cid] cnf_run_fs[-1].create(locs) cnf_run_path = cnf_run_fs[-1].path(locs) run_fs = autofile.fs.run(cnf_run_path) info_message(f"Run {samp_idx}/{tot_samp}") tors_names = tuple(tors_range_dct.keys()) print('two_stage test:', two_stage, tors_names) if two_stage and tors_names: frozen_coords_lst = (tors_names, ()) success, ret = es_runner.multi_stage_optimization( script_str=script_str, run_fs=run_fs, geo=samp_zma, spc_info=spc_info, thy_info=thy_info, frozen_coords_lst=frozen_coords_lst, zrxn=zrxn, overwrite=overwrite, saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) else: success, ret = es_runner.execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=samp_zma, spc_info=spc_info, thy_info=thy_info, zrxn=zrxn, overwrite=overwrite, saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) # save function added here if success: save_conformer(ret, cnf_run_fs, cnf_save_fs, locs, thy_info, zrxn=zrxn, orig_ich=spc_info[0], rid_traj=True, init_zma=samp_zma) nsampd = util.calc_nsampd(cnf_save_fs, cnf_run_fs, rid) nsampd += 1 samp_idx += 1 inf_obj.nsamp = nsampd cnf_save_fs[1].file.info.write(inf_obj, [rid]) cnf_run_fs[1].file.info.write(inf_obj, [rid]) # Increment attempt counter samp_attempt_idx += 1
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.zmat.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: ioprinter.info_message( 'No Hessian found in save filesys. Running Hessian...') _run = True elif overwrite: ioprinter.info_message( 'User specified to overwrite Hessian with new run...') _run = True else: _run = False if _run: run_fs = autofile.fs.run(geo_run_path) success, ret = es_runner.execute_job( job=elstruct.Job.HESSIAN, script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, retryfail=retryfail, **kwargs, ) if success: inf_obj, inp_str, out_str = ret ioprinter.info_message(" - Reading hessian from output...") hess = elstruct.reader.hessian(inf_obj.prog, out_str) ioprinter.info_message(" - 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) ioprinter.info_message( " - 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: ioprinter.existing_path('Hessian', geo_save_path) _hess_freqs(geo, geo_save_fs, geo_run_path, geo_save_path, locs, overwrite) else: ioprinter.info_message('Species is an atom. Skipping Hessian task.')
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): """ Assesses if an electronic energy exists in the CONFS/SP/THY layer of the save filesys for a species at the specified level of theory. If an energy does not exist, or if a user requests overwrite, the appropriate electronic struture calculation is set-up, launched, and then parsed within the run filesys, then that the energy and job input is written into the save filesys. :param zma: Z-Matrix for species/TS conformer :type zma: automol Z-Matrix data 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]) # _run = need_job((exists, 'energy'), overwrite) if not exists: ioprinter.info_message( 'No energy found in save filesys. Running energy...') _run = True elif overwrite: ioprinter.info_message( '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 = () success, ret = es_runner.execute_job( job=elstruct.Job.ENERGY, script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, errors=errs, options_mat=optmat, overwrite=overwrite, retryfail=retryfail, **kwargs, ) if success: inf_obj, inp_str, out_str = ret ioprinter.info_message(" - Reading energy from output...") ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) ioprinter.energy(ene) 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]) ioprinter.save_energy(sp_save_path) else: ioprinter.existing_path('Energy', sp_save_path) ene = sp_save_fs[-1].file.energy.read(thy_info[1:4]) ioprinter.energy(ene)
def run_gradient(zma, geo, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, script_str, overwrite, zrxn=None, retryfail=True, method_dct=None, ref_val=None, **kwargs): """ Determine the gradient for the geometry in the given location """ # Set unneeded vals _, _, _, _ = zrxn, method_dct, ref_val, run_prefix geo_run_path = geo_run_fs[-1].path(locs) geo_save_path = geo_save_fs[-1].path(locs) # Set input geom if geo is not None: job_geo = geo else: job_geo = automol.zmat.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: ioprinter.info_message( 'No gradient found in save filesys. Running gradient...') _run = True elif overwrite: ioprinter.info_message( 'User specified to overwrite gradient with new run...') _run = True else: _run = False if _run: run_fs = autofile.fs.run(geo_run_path) success, ret = es_runner.execute_job( job=elstruct.Job.GRADIENT, script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, zrxn=zrxn, overwrite=overwrite, retryfail=retryfail, **kwargs, ) if success: inf_obj, inp_str, out_str = ret if is_atom: grad = () else: ioprinter.info_message( " - Reading gradient from output...") grad = elstruct.reader.gradient(inf_obj.prog, out_str) ioprinter.info_message(" - 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) ioprinter.save_geo(geo_save_path) else: ioprinter.existing_path('Gradient', geo_save_path) else: ioprinter.info_message('Species is an atom. Skipping gradient task.')
def _optimize_molecule(spc_info, zma_init, method_dct, cnf_save_fs, locs, run_fs, overwrite, kickoff_size=0.1, kickoff_backward=False): """ Optimize a proper geometry """ thy_info = tinfo.from_dct(method_dct) mod_thy_info = tinfo.modify_orb_label(thy_info, spc_info) script_str, kwargs = es_runner.qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) # Call the electronic structure optimizer success, ret = es_runner.execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=zma_init, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, **kwargs) # read the geometry if success: inf_obj, _, out_str = ret geo = elstruct.reader.opt_geometry(inf_obj.prog, out_str) zma = elstruct.reader.opt_zmatrix(inf_obj.prog, out_str) if zma is None: zma = automol.geom.zmatrix(geo) geo_conn = bool(automol.geom.connected(geo)) # If connected, check for imaginary modes and fix them if possible if geo_conn: # Remove the imaginary mode geo, ret = remove_imag(geo, ret, spc_info, method_dct, run_fs, kickoff_size, kickoff_backward, kickoff_mode=0, overwrite=overwrite) # Recheck connectivity for imag-checked geometry if geo is not None: conf_found = True if automol.geom.connected(geo): ioprinter.info_message( 'Saving structure as the first conformer...', newline=1) filesys.save.conformer(ret, None, cnf_save_fs, mod_thy_info[1:], rng_locs=(locs[0], ), tors_locs=(locs[1], )) else: ioprinter.info_message('Saving disconnected species...') filesys.save.instability(zma_init, zma, cnf_save_fs, rng_locs=(locs[0], ), tors_locs=(locs[1], ), zma_locs=(0, )) else: ioprinter.warning_message('No geom found...', newline=1) conf_found = False else: ioprinter.info_message('Saving disconnected species...') conf_found = False filesys.save.instability(zma_init, zma, cnf_save_fs, rng_locs=(locs[0], ), tors_locs=(locs[1], ), zma_locs=(0, )) return conf_found
def rerun_hessian_and_opt(zma, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, script_str, zrxn=None, retryfail=True, method_dct=None, ref_val=None, attempt=0, hess_script_str=None, **hess_kwargs): """ Perform a tight opt of a geometry and run the hessian. Resave all of its info. """ # Set the run filesystem information if attempt < 2: geo_run_path = geo_run_fs[-1].path(locs) run_fs = autofile.fs.run(geo_run_path) script_str, kwargs = qchem_params(method_dct, job='tightopt') success, ret = es_runner.execute_job( job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=zma, spc_info=spc_info, thy_info=thy_info, zrxn=zrxn, overwrite=True, saddle=zrxn is not None, retryfail=retryfail, **kwargs, ) if success: inf_obj, _, out_str = ret tight_geo = elstruct.reader.opt_geometry(inf_obj.prog, out_str) save_conformer(ret, geo_run_fs, geo_save_fs, locs, thy_info, orig_ich=spc_info[0], init_zma=zma, zrxn=zrxn) if geo_save_fs[-1].exists(locs): ioprinter.info_message( 'TightOpt complete. Rerunning Hessian Job') ioprinter.info_message(automol.geom.string(tight_geo)) run_hessian(zma, tight_geo, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, hess_script_str, True, zrxn=zrxn, retryfail=retryfail, method_dct=method_dct, ref_val=ref_val, correct_vals=True, attempt=attempt + 1, **hess_kwargs) else: ioprinter.error_message( "Could not get rid of negative frequencies after two attempts")
def single_conformer(zma, spc_info, mod_thy_info, cnf_run_fs, cnf_save_fs, script_str, overwrite, retryfail=True, zrxn=None, use_locs=None, **kwargs): """ generate single optimized geometry to be saved into a filesystem """ if not _this_conformer_is_running(zma, cnf_run_fs): # Build the filesystem if use_locs is None: rid = autofile.schema.generate_new_ring_id() cid = autofile.schema.generate_new_conformer_id() locs = (rid, cid) else: locs = use_locs 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 ioprinter.info_message('Optimizing a single conformer', zrxn) success, ret = es_runner.execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=zma, spc_info=spc_info, thy_info=mod_thy_info, overwrite=overwrite, frozen_coordinates=(), saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) 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, zrxn=zrxn): sym_id = _sym_unique(geo, ene, saved_geos, saved_enes) if sym_id is None: if cnf_save_fs[0].file.info.exists(): ioprinter.debug_message('inf_obj path', cnf_save_fs[0].path()) # rinf_obj_s = cnf_save_fs[0].file.info.read() rinf = inf_obj ioprinter.debug_message('inf_obj for r', rinf) # rnsampd = rinf_obj_s.nsamp # rnsampd += 1 # rinf_obj.nsamp = rnsampd else: rinf = autofile.schema.info_objects.conformer_trunk(0) rinf.nsamp = 1 if cnf_save_fs[1].file.info.exists([locs[0]]): cinf_obj_s = cnf_save_fs[1].file.info.read(locs[0]) cinf = inf_obj cnsampd = cinf_obj_s.nsamp cnsampd += 1 cinf.nsamp = cnsampd else: cinf = autofile.schema.info_objects.conformer_branch(0) cinf.nsamp = 1 cnf_save_fs[1].create([locs[0]]) cnf_save_fs[0].file.info.write(rinf) cnf_save_fs[1].file.info.write(cinf, [locs[0]]) filesys.save.conformer(ret, None, cnf_save_fs, mod_thy_info[1:], zrxn=zrxn, rng_locs=(locs[0], ), tors_locs=(locs[1], )) saved_geos.append(geo) saved_enes.append(ene) saved_locs.append(locs) # Update the conformer trajectory file ioprinter.obj('vspace') filesys.mincnf.traj_sort(cnf_save_fs, mod_thy_info) filesys.mincnf.traj_sort(cnf_save_fs, mod_thy_info, locs[0])
def run_hessian(zma, geo, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, script_str, overwrite, zrxn=None, retryfail=True, method_dct=None, ref_val=None, correct_vals=True, attempt=0, **kwargs): """ Determine the hessian for the geometry in the given location """ # Set the run filesystem information geo_run_path = geo_run_fs[-1].path(locs) geo_save_path = geo_save_fs[-1].path(locs) run_fs = autofile.fs.run(geo_run_path) # 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.zmat.geometry(zma) is_atom = automol.geom.is_atom(job_geo) if not is_atom: if _json_database(geo_save_path): print('geo_save_path test:', 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: ioprinter.info_message( 'No Hessian found in save filesys. Running Hessian...') _run = True elif overwrite: ioprinter.info_message( 'User specified to overwrite Hessian with new run...') _run = True else: _run = False if _run: if attempt > 0: script_str, kwargs = qchem_params(method_dct, job='tightfreq') run_fs = autofile.fs.run(geo_run_path) success, ret = es_runner.execute_job( job=elstruct.Job.HESSIAN, script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, zrxn=zrxn, overwrite=overwrite, retryfail=retryfail, **kwargs, ) if success: inf_obj, inp_str, out_str = ret ioprinter.info_message(" - Reading hessian from output...") # If requested, determine if there are too many frequencies if correct_vals: hfrqs = elstruct.reader.harmonic_frequencies( inf_obj.prog, out_str) imags = tuple(x for x in hfrqs if x < 0.0) nimags = len(imags) too_many_imags = ((zrxn is not None and nimags > 1) or (zrxn is None and nimags > 0)) else: too_many_imags = False # If requested, determine if there are frequencies below thrsh correct_low_vals = False if correct_low_vals: hfrqs = elstruct.reader.harmonic_frequencies( inf_obj.prog, out_str) reals = tuple(x for x in hfrqs if x > 0.0) has_low_freqs = any(x for x in reals if x < 30.0) else: has_low_freqs = False if too_many_imags or has_low_freqs: ioprinter.info_message( 'Too many negative freqs or low freqs', hfrqs) rinf_obj = run_fs[-1].file.info.read( [elstruct.Job.HESSIAN]) rinf_obj.status = autofile.schema.RunStatus.FAILURE run_fs[-1].file.info.write(rinf_obj, [elstruct.Job.HESSIAN]) ioprinter.info_message( 'Performing a tightopt, superfine to fix it') rerun_hessian_and_opt(zma, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, script_str, zrxn=zrxn, retryfail=retryfail, method_dct=method_dct, attempt=attempt, hess_script_str=script_str, **kwargs) else: # After determining number of imags is correct, # perform an additional frequency check for TS # assume lowest frequency is the imaginary mode if zrxn is not None: if ref_val is None: print('No reference frequencies available to ' 'perform check') imag_success = True else: imag_success = _assess_imags( hfrqs, ref_val, geo_run_fs, geo_save_fs, locs) else: imag_success = True if imag_success: hess = elstruct.reader.hessian(inf_obj.prog, out_str) ioprinter.info_message(" - 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) ioprinter.info_message( f" - Save path: {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_save_path, locs, run_prefix, overwrite) else: ioprinter.existing_path('Hessian', geo_save_path) _hess_freqs(geo, geo_save_fs, geo_save_path, locs, run_prefix, overwrite) else: ioprinter.info_message('Species is an atom. Skipping Hessian task.')
def conformer_sampling(zma, spc_info, thy_info, cnf_run_fs, cnf_save_fs, rid, script_str, overwrite, nsamp_par=(False, 3, 3, 1, 50, 50), tors_names=(), zrxn=None, two_stage=False, retryfail=False, resave=False, **kwargs): """ run sampling algorithm to find conformers """ # Check if any saving needs to be done before hand if resave: _presamp_save(spc_info, cnf_run_fs, cnf_save_fs, thy_info, zrxn=zrxn, rid=rid) # Build filesys cnf_save_fs[1].create([rid]) inf_obj = autofile.schema.info_objects.conformer_branch(0) # Set the samples nsamp, tors_range_dct = _calc_nsamp(tors_names, nsamp_par, zma, zrxn=zrxn) nsamp0 = nsamp nsampd = _calc_nsampd(cnf_save_fs, cnf_run_fs, rid) tot_samp = nsamp - nsampd brk_tot_samp = nsamp * 5 ioprinter.info_message( ' - Number of samples that have been currently run:', nsampd) ioprinter.info_message(' - Number of samples requested:', nsamp) if nsamp - nsampd > 0: ioprinter.info_message('Running {} samples...'.format(nsamp - nsampd), newline=1) samp_idx = 1 samp_attempt_idx = 1 while True: nsamp = nsamp0 - nsampd # Break the while loop if enough sampls completed if nsamp <= 0: ioprinter.info_message( 'Requested number of samples have been completed.', 'Conformer search complete.') break if samp_attempt_idx == brk_tot_samp: ioprinter.info_message( 'Max sample num: 5*{} attempted, ending search'.format(nsamp), 'Run again if more samples desired.') break # Run the conformer sampling if nsampd > 0: samp_zma, = automol.zmat.samples(zma, 1, tors_range_dct) else: samp_zma = zma bad_geom_count = 0 geo = automol.zmat.geometry(zma) samp_geo = automol.zmat.geometry(samp_zma) while (not automol.pot.low_repulsion_struct(geo, samp_geo) and bad_geom_count < 1000): ioprinter.warning_message('ZMA has high repulsion.', indent=1 / 2.) ioprinter.warning_message('Generating new sample ZMA', indent=1 / 2., newline=1) samp_zma, = automol.zmat.samples(zma, 1, tors_range_dct) samp_geo = automol.zmat.geometry(samp_zma) bad_geom_count += 1 ioprinter.debug_message('ZMA is fine...', indent=1 / 2.) cid = autofile.schema.generate_new_conformer_id() locs = [rid, cid] cnf_run_fs[-1].create(locs) cnf_run_path = cnf_run_fs[-1].path(locs) run_fs = autofile.fs.run(cnf_run_path) ioprinter.info_message("Run {}/{}".format(samp_idx, tot_samp)) tors_names = tuple(tors_range_dct.keys()) if two_stage and tors_names: frozen_coords_lst = ((), tors_names) success, ret = es_runner.multi_stage_optimization( script_str=script_str, run_fs=run_fs, geo=samp_zma, spc_info=spc_info, thy_info=thy_info, frozen_coords_lst=frozen_coords_lst, overwrite=overwrite, saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) else: success, ret = es_runner.execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=samp_zma, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, saddle=bool(zrxn is not None), retryfail=retryfail, **kwargs) # save function added here if success: _save_conformer(ret, cnf_save_fs, locs, thy_info, zrxn=zrxn, orig_ich=spc_info[0], rid_traj=True, init_zma=samp_zma) nsampd = _calc_nsampd(cnf_save_fs, cnf_run_fs, rid) nsampd += 1 samp_idx += 1 inf_obj.nsamp = nsampd cnf_save_fs[1].file.info.write(inf_obj, [rid]) cnf_run_fs[1].file.info.write(inf_obj, [rid]) # Increment attempt counter samp_attempt_idx += 1
def run_prop(zma, geo, spc_info, thy_info, geo_run_fs, geo_save_fs, locs, run_prefix, script_str, overwrite, zrxn=None, retryfail=True, method_dct=None, ref_val=None, **kwargs): """ Determine the properties in the given location """ # Set unneeded vals _, _, _, _ = zrxn, method_dct, ref_val, run_prefix # Set input geom geo_run_path = geo_run_fs[-1].path(locs) geo_save_path = geo_save_fs[-1].path(locs) if geo is not None: job_geo = geo else: job_geo = automol.zmat.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: ioprinter.info_message( 'Either no dipole moment or polarizability found in' 'in save filesys. Running properties...') _run = True elif overwrite: ioprinter.info_message( 'User specified to overwrite property with new run...') _run = True else: _run = False if _run: run_fs = autofile.fs.run(geo_run_path) success, ret = es_runner.execute_job( job=elstruct.Job.MOLPROP, script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, zrxn=zrxn, overwrite=overwrite, retryfail=retryfail, **kwargs, ) if success: inf_obj, _, out_str = ret ioprinter.info_message(" - Reading dipole moment from output...") dmom = elstruct.reader.dipole_moment(inf_obj.prog, out_str) ioprinter.info_message(" - Reading polarizability from output...") polar = elstruct.reader.polarizability(inf_obj.prog, out_str) ioprinter.debug_message('dip mom', dmom) ioprinter.debug_message('polar', polar) ioprinter.info_message( " - 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) ioprinter.save_geo(geo_save_path) else: ioprinter.existing_path('Dipole moment and polarizability', 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]) # _run = need_job((exists, 'energy'), overwrite) if not exists: ioprinter.info_message( 'No energy found in save filesys. Running energy...') _run = True elif overwrite: ioprinter.info_message( '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 = () success, ret = es_runner.execute_job( job='energy', script_str=script_str, run_fs=run_fs, geo=job_geo, spc_info=spc_info, thy_info=thy_info, errors=errs, options_mat=optmat, overwrite=overwrite, retryfail=retryfail, **kwargs, ) if success: inf_obj, inp_str, out_str = ret ioprinter.info_message(" - Reading energy from output...") ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str) ioprinter.energy(ene) 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]) ioprinter.save_energy(sp_save_path) else: ioprinter.existing_path('Energy', sp_save_path) ene = sp_save_fs[-1].file.energy.read(thy_info[1:4]) ioprinter.energy(ene)