def this_conformer_is_running(zma, cnf_run_fs): """ Check the RUN filesystem for similar geometry submissions that are currently running """ running = False job = elstruct.Job.OPTIMIZATION for locs in cnf_run_fs[-1].existing(ignore_bad_formats=True): cnf_run_path = cnf_run_fs[-1].path(locs) run_fs = autofile.fs.run(cnf_run_path) run_path = run_fs[-1].path([job]) if run_fs[-1].file.info.exists([job]): inf_obj = run_fs[-1].file.info.read([job]) status = inf_obj.status if status == autofile.schema.RunStatus.RUNNING: start_time = inf_obj.utc_start_time current_time = autofile.schema.utc_time() if (current_time - start_time).total_seconds() < 3000000: subrun_fs = autofile.fs.subrun(run_path) inp_str = subrun_fs[0].file.input.read([0, 0]) inp_str = inp_str.replace('=', '') prog = inf_obj.prog inp_zma = elstruct.reader.inp_zmatrix(prog, inp_str) if automol.zmat.almost_equal(inp_zma, zma, dist_rtol=0.018, ang_atol=.2): _hr = (current_time - start_time).total_seconds() / 3600. info_message( 'This conformer was started in the last ' + f'{_hr:3.4f} hours in {run_path}.') running = True break return running
def assess_pf_convergence(tau_save_fs, ref_ene, temps=(300., 500., 750., 1000., 1500.)): """ Determine how much the partition function has converged """ # Calculate sigma values at various temperatures for the PF for temp in temps: sumq = 0. sum2 = 0. idx = 0 ioprinter.debug_message('integral convergence for T = ', temp) inf_obj_s = tau_save_fs[0].file.info.read() nsamp = inf_obj_s.nsamp saved_locs = tau_save_fs[-1].existing() ratio = float(nsamp) / len(saved_locs) for locs in tau_save_fs[-1].existing(): idx += 1 ene = tau_save_fs[-1].file.energy.read(locs) ene = (ene - ref_ene) * phycon.EH2KCAL tmp = numpy.exp(-ene*349.7/(0.695*temp)) sumq = sumq + tmp sum2 = sum2 + tmp**2 sigma = numpy.sqrt( (abs(sum2/float(idx)-(sumq/float(idx))**2))/float(idx)) ioprinter.debug_message( sumq/float(idx), sigma, 100.*sigma*float(idx)/sumq, idx) inf_obj_s = tau_save_fs[0].file.info.read() nsamp = inf_obj_s.nsamp saved_locs = tau_save_fs[-1].existing() ratio = len(saved_locs) / float(nsamp) ioprinter.info_message('Ratio of good to sampled geometries: ', ratio)
def hindered_rotor_scans(zma, spc_info, mod_thy_info, scn_run_fs, scn_save_fs, rotors, tors_model, method_dct, overwrite, saddle=False, increment=0.5235987756, retryfail=True): """ Perform scans over each of the torsional coordinates """ if tors_model != '1dhrfa': script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.OPTIMIZATION) scn_typ = 'relaxed' update_guess = True else: script_str, kwargs = qchem_params(method_dct, job=elstruct.Job.ENERGY) scn_typ = 'rigid' update_guess = False run_tors_names = automol.rotor.names(rotors) run_tors_grids = automol.rotor.grids(rotors, increment=increment) # Set constraints const_names = automol.zmat.set_constraint_names(zma, run_tors_names, tors_model) ioprinter.run_rotors(run_tors_names, const_names) for tors_names, tors_grids in zip(run_tors_names, run_tors_grids): ioprinter.info_message('Running Rotor: {}...'.format(tors_names), newline=1) # Setting the constraints constraint_dct = automol.zmat.constraint_dct(zma, const_names, tors_names) scan.execute_scan( zma=zma, spc_info=spc_info, mod_thy_info=mod_thy_info, coord_names=tors_names, coord_grids=tors_grids, scn_run_fs=scn_run_fs, scn_save_fs=scn_save_fs, scn_typ=scn_typ, script_str=script_str, overwrite=overwrite, update_guess=update_guess, reverse_sweep=True, saddle=saddle, constraint_dct=constraint_dct, retryfail=retryfail, **kwargs, )
def _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 write_messpf_task(write_messpf_tsk, spc_locs_dct, spc_dct, pes_mod_dct, spc_mod_dct, run_prefix, save_prefix, thm_paths_dct): """ Write messpf input file """ ioprinter.messpf('write_header') spc_mods, pes_mod = parser.models.extract_models(write_messpf_tsk) for spc_name in spc_locs_dct: ioprinter.therm_paths_messpf_write_locations(spc_name, spc_locs_dct[spc_name], spc_mods, thm_paths_dct) for spc_locs in spc_locs_dct[spc_name]: for spc_mod in spc_mods: messpf_inp_str, dat_dct = qt.make_messpf_str( pes_mod_dct[pes_mod]['therm_temps'], spc_dct, spc_name, spc_locs, pes_mod_dct[pes_mod], spc_mod_dct[spc_mod], run_prefix, save_prefix) ioprinter.messpf('input_string') ioprinter.info_message(messpf_inp_str) autorun.write_input( thm_paths_dct[spc_name][tuple(spc_locs)][spc_mod][0], messpf_inp_str, aux_dct=dat_dct, input_name='pf.inp')
def diverged_ts(param, ref_param, cnf_param): """ a """ info_message( "- Transition State conformer has", "diverged from original structure of", "{} {:.3f} with angle {:.3f}".format(param, ref_param, cnf_param))
def zero_point_energy(spc_dct_i, pf_filesystems, spc_model_dct_i, run_prefix, saddle=False, conf=None): """ compute the ZPE including torsional and anharmonic corrections """ ioprinter.info_message('- Calculating zero-point energy') # Calculate ZPVE is_atom = False if not saddle: if typ.is_atom(spc_dct_i): is_atom = True if is_atom: zpe = 0.0 else: _, _, zpe, _ = vib.vib_analysis( spc_dct_i, pf_filesystems, spc_model_dct_i, run_prefix, zrxn=(None if not saddle else 'placeholder')) return zpe
def create_ts_spc(ref, spc_dct, mult, run_prefix, save_prefix, rxnclass): """ add a ts species to the species dictionary """ spec = {} spec['reacs'] = list(ref[0]) spec['prods'] = list(ref[1]) spec['charge'] = 0 spec['inchi'] = '' spec['class'] = rxnclass spec['mult'] = mult rxn_ichs = [[], []] ioprinter.info_message('spec in build spc', spec) for rct_ich in spec['reacs']: if rct_ich: rxn_ichs[0].append(automol.inchi.add_stereo(rct_ich)) for prd_ich in spec['prods']: if prd_ich: rxn_ichs[1].append(automol.inchi.add_stereo(prd_ich)) rct_muls = [] prd_muls = [] rct_chgs = [] prd_chgs = [] for rct in spec['reacs']: found = False for name in spc_dct: if 'inchi' in spc_dct[name]: if spc_dct[name]['inchi'] == rct: rct_muls.append(spc_dct[name]['mult']) rct_chgs.append(spc_dct[name]['charge']) found = True break if not found: new_spc = create_spec(rct) rct_muls.append(new_spc['mult']) rct_chgs.append(new_spc['charge']) for rct in spec['prods']: found = False for name in spc_dct: if 'inchi' in spc_dct[name]: if spc_dct[name]['inchi'] == rct: prd_muls.append(spc_dct[name]['mult']) prd_chgs.append(spc_dct[name]['charge']) found = True break if not found: new_spc = create_spec(rct) prd_muls.append(new_spc['mult']) prd_chgs.append(new_spc['charge']) rxn_muls = [rct_muls, prd_muls] rxn_chgs = [rct_chgs, prd_chgs] rxn_info = rinfo.sort((rxn_ichs, rxn_chgs, rxn_muls, mult)) spec['rxn_info'] = rxn_info spec['ts_locs'] = (0, ) rxn_run_fs, rxn_save_fs = build_fs(run_prefix, save_prefix, 'REACTION') rxn_run_path = rxn_run_fs[-1].path(rxn_info) rxn_save_path = rxn_save_fs[-1].path(rxn_info) spec['rxn_fs'] = [rxn_run_fs, rxn_save_fs, rxn_run_path, rxn_save_path] return spec
def multi_stage_optimization(script_str, run_fs, geo, spc_info, thy_info, frozen_coords_lst, overwrite=False, saddle=False, retryfail=False, **kwargs): """ Run a series of optimizations that utilize varying constraint conditions at each state. :param script_str: BASH submission script for electronic structure job :type script_str: str :param geo: input molecular geometry or Z-Matrix :type geo: :param spc_info: :type spc_info: :param thy_info: :type thy_info: :param frozen_coords_lst: :type frozen_coords_lst: :param overwrite: overwrite existing input file with new one and rerun :type overwrite: bool :param saddle: perform saddle-point optimization :type saddle: bool :param retryfail: re-run the job if failed job found in RUN filesys :type retryfail: bool """ for idx, coords in enumerate(frozen_coords_lst): ioprinter.info_message( 'Stage {} success beginning stage two'.format(idx + 1)) success, ret = execute_job(job=elstruct.Job.OPTIMIZATION, script_str=script_str, run_fs=run_fs, geo=geo, spc_info=spc_info, thy_info=thy_info, overwrite=overwrite, frozen_coordinates=coords, saddle=saddle, retryfail=retryfail, **kwargs) if success: inf_obj, _, out_str = ret geo = elstruct.reader.opt_zmatrix(inf_obj.prog, out_str) print('Success. Moving to next stage...\n') if idx + 1 != len(frozen_coords_lst): print('Success. Moving to next stage...\n') else: print('Succes. Finished sequence') else: print('Failure. Exiting multi stage optimization...\n') break return success, ret
def run_tsk(tsk, spc_queue, spc_dct, thy_dct, etrans_keyword_dct, run_prefix, save_prefix): """ Run the task """ # Print the head of the task ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message('Task:', tsk, newline=1) ioprinter.info_message('Options for transport task:', newline=1) for key, val in etrans_keyword_dct.items(): ioprinter.info_message('{} = {}'.format(key, val)) if tsk == 'onedmin': ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message('Obtaining LJ-Params using OneDMin', newline=1) for spc_name, _ in spc_queue: lj.onedmin(spc_name, spc_dct, thy_dct, etrans_keyword_dct, run_prefix, save_prefix) elif tsk == 'write_transport': ioprinter.obj('vspace') ioprinter.obj('line_dash') ioprinter.info_message('Writing the CHEMKIN transport file', newline=1) build.collate_properties(spc_queue, spc_dct, thy_dct, etrans_keyword_dct, save_prefix)
def read_locs_harmonic_freqs(cnf_fs, cnf_locs, run_prefix, zrxn=None): """ Read the harmonic frequencies for a specific conformer Do the freqs obtain for two species for fake and pst? """ if cnf_locs is not None: geo_exists = cnf_fs[-1].file.geometry.exists(cnf_locs) hess_exists = cnf_fs[-1].file.hessian.exists(cnf_locs) if not geo_exists: ioprinter.error_message( 'No Reference geometry for harmonic frequencies at path', cnf_fs[-1].file.hessian.path(cnf_locs)) if not hess_exists: ioprinter.error_message( 'No Hessian available for harmonic frequencies at path', cnf_fs[-1].file.hessian.path(cnf_locs)) else: geo_exists, hess_exists = False, False if geo_exists and hess_exists: # Obtain geom and freqs from filesys geo = cnf_fs[-1].file.geometry.read(cnf_locs) hess = cnf_fs[-1].file.hessian.read(cnf_locs) ioprinter.reading('Hessian', cnf_fs[-1].path(cnf_locs)) # Build the run filesystem using locs fml_str = automol.geom.formula_string(geo) vib_path = job_path(run_prefix, 'PROJROT', 'FREQ', fml_str) # Obtain the frequencies ioprinter.info_message( 'Calling ProjRot to diagonalize Hessian and get freqs...') script_str = autorun.SCRIPT_DCT['projrot'] freqs, _, imag_freqs, _ = autorun.projrot.frequencies( script_str, vib_path, [geo], [[]], [hess]) # Obtain the displacements norm_coord_str, _ = autorun.projrot.displacements( script_str, vib_path, [geo], [[]], [hess]) # Calculate the zpve ioprinter.frequencies(freqs) zpe = (sum(freqs) / 2.0) * phycon.WAVEN2EH # Check imaginary frequencies and set freqs if zrxn is not None: if len(imag_freqs) > 1: ioprinter.warning_message('Saddle Point has more than', 'one imaginary frequency') imag = imag_freqs[0] else: imag = None ret = (freqs, imag, zpe, norm_coord_str) else: ret = None return ret
def mass_params(well_info, bath_info, etrans_dct): """ Determine the mass parameters used to define the energy transfer model for master equation simulations. Function first assesses if a user has supplied mass parameters by way of ___. If masses have not been provided, then the masses will be simply calculated using the geometries of the well and bath species. :param well_info: spc_info object for well species :type well_info: mechanalyzer.inf.spc object :param bath_info: spc_info object for bath species :type bath_info: mechanalyzer.inf.spc object :param etrans_dct: """ mass = etrans_dct.get('mass', None) if mass is not None: ioprinter.info_message(' - Using the user input values...') [mass1, mass2] = mass else: ioprinter.info_message(' - Obtaining masses from geometries...') geo = automol.inchi.geometry(well_info[0]) mass1 = sum(automol.geom.masses(geo)) geo = automol.inchi.geometry(bath_info[0]) mass2 = sum(automol.geom.masses(geo)) return mass1, mass2
def _split_species(spc_dct, spc_name, thy_info, save_prefix, zma_locs=(0,)): """ split up the unstable species """ # Initialize an empty list prd_names = () # Attempt to read the graph of the instability trans # Get the product graphs and inchis tra, path = filesys.read.instability_transformation( spc_dct, spc_name, thy_info, save_prefix, zma_locs=zma_locs) if tra is not None: ioprinter.info_message('\nFound instability files at path:') ioprinter.info_message(' {}'.format(path)) zrxn, _ = tra prd_gras = automol.reac.product_graphs(zrxn) constituent_ichs = tuple(automol.graph.inchi(gra, stereo=True) for gra in prd_gras) for ich in constituent_ichs: for name, spc_dct_i in spc_dct.items(): if ich == spc_dct_i.get('inchi'): prd_names += (name,) break prd_names = tuple(set(prd_names)) return prd_names
def run(pes_rlst, spc_rlst, trans_tsk_lst, spc_mod_dct, spc_dct, thy_dct, run_prefix, save_prefix): """ main driver for etransfer run """ # Print Header ioprinter.info_message('Calculating Transport:') ioprinter.runlst(('SPC', 0, 0), spc_rlst) # ---------------------------------------------------- # # PREPARE INFORMATION TO PASS TO TRANSPORTDRIVER TASKS # # ---------------------------------------------------- # spc_mods = list(spc_mod_dct.keys()) # hack spc_mod_dct_i = spc_mod_dct[spc_mods[0]] split_rlst = split_unstable_full(pes_rlst, spc_rlst, spc_dct, spc_mod_dct_i, save_prefix) spc_queue = parser.rlst.spc_queue(tuple(split_rlst.values())[0], 'SPC') # --------------------------------------- # # RUN THE REQUESTED TRANSPORTDRIVER TASKS # # --------------------------------------- # for tsk_lst in trans_tsk_lst: [_, tsk, etrans_keyword_dct] = tsk_lst run_tsk(tsk, spc_queue, spc_dct, thy_dct, etrans_keyword_dct, run_prefix, save_prefix)
def _need_run(etrans_save_fs, etrans_locs, etrans_keyword_dct): """ Check if job needs to run """ nsamp = etrans_keyword_dct['nsamp'] overwrite = etrans_keyword_dct['overwrite'] ex1 = etrans_save_fs[-1].file.lennard_jones_epsilon.exists(etrans_locs) ex2 = etrans_save_fs[-1].file.lennard_jones_sigma.exists(etrans_locs) if not ex1 or not ex2: ioprinter.info_message( 'Either no Lennard-Jones epsilon or sigma found in', 'save filesys. Running OneDMin for params...') run = True nsamp_need = nsamp elif overwrite: ioprinter.info_message( 'User specified to overwrite parameters with new run...') run = True nsamp_need = nsamp else: inf_obj = etrans_save_fs[-1].file.info.read(etrans_locs) nsampd = inf_obj.nsamp if nsamp < nsampd: run = True nsamp_need = nsampd - nsamp else: run = False nsamp_need = 0 return run, nsamp_need
def this_conformer_was_run_in_save(zma, cnf_fs): """ Assess if a conformer was run in save """ running = False for locs in cnf_fs[-1].existing(ignore_bad_formats=True): cnf_path = cnf_fs[-1].path(locs) if cnf_fs[-1].file.geometry_input.exists(locs): print('checking input at ', cnf_path) inp_str = cnf_fs[-1].file.geometry_input.read(locs) inp_str = inp_str.replace('=', '') inf_obj = cnf_fs[-1].file.geometry_info.read(locs) prog = inf_obj.prog try: inp_zma = elstruct.reader.inp_zmatrix(prog, inp_str) if automol.zmat.almost_equal(inp_zma, zma, dist_rtol=0.018, ang_atol=.2): info_message( f'This conformer was already run in {cnf_path}.') running = True break except: info_message(f'Program {prog} lacks inp ZMA reader for check') return running
def save_scan(scn_run_fs, scn_save_fs, scn_typ, coord_names, constraint_dct, mod_thy_info, in_zma_fs=False): """ save the scan """ ioprinter.info_message('Saving any newly run HR scans in run filesys...', newline=1) if constraint_dct is None: _save_fxn = _save_scanfs coord_locs = coord_names else: _save_fxn = _save_cscanfs coord_locs = constraint_dct _save_fxn(scn_run_fs=scn_run_fs, scn_save_fs=scn_save_fs, scn_typ=scn_typ, coord_locs=coord_locs, mod_thy_info=mod_thy_info, in_zma_fs=in_zma_fs)
def fs_confs_dict(cnf_save_fs, cnf_save_locs_lst, ini_cnf_save_fs, ini_cnf_save_locs_lst): """ Assess which structures from the cnf_save_fs currently exist within the ini_cnf_save_fs. Generate a dictionary to connect the two """ match_dct = {} for ini_locs in ini_cnf_save_locs_lst: match_dct[ini_locs] = None # Loop over structs in cnf_save, see if they match the current struct inigeo = ini_cnf_save_fs[-1].file.geometry.read(ini_locs) inizma = automol.geom.zmatrix(inigeo) # inizma = ini_cnf_save_fs[-1].file.zmatrix.read(ini_locs) ini_cnf_save_path = ini_cnf_save_fs[-1].path(ini_locs) ioprinter.checking('structures', ini_cnf_save_path) for locs in cnf_save_locs_lst: geo = cnf_save_fs[-1].file.geometry.read(locs) zma = automol.geom.zmatrix(geo) if automol.zmat.almost_equal(inizma, zma, dist_rtol=0.1, ang_atol=.4): cnf_save_path = cnf_save_fs[-1].path(locs) ioprinter.info_message( '- Similar structure found at {}'.format(cnf_save_path)) match_dct[ini_locs] = locs break return match_dct
def save_scan(scn_run_fs, scn_save_fs, scn_typ, coord_names, constraint_dct, mod_thy_info): """ Search for output of electronic structure calculation along the scan coordinate that exist in the SCAN/CSCAN layer of the run filesys. Then parse out the required information and save it into formatted files in the SCAN/CSAN layer of the save filesys. :param scn_run_fs: SCAN/CSCAN object with run filesys prefix :type scn_run_fs: autofile.fs.scan or autofile.fs.cscan object :param scn_save_fs: SCAN/CSCAN object with save filesys prefix :type scn_save_fs: autofile.fs.scan or autofile.fs.cscan object :param coord_names: names of the scan coordinates :type coord_names: tuple(tuple(str)) :param constraint_dct: values of coordinates to constrain during scan :type constraint_dct: dict[str: float] """ ioprinter.info_message('Saving any newly run HR scans in run filesys...', newline=1) # Set job job = _set_job(scn_typ) # Set locs for scan coord_locs, save_locs = scan_locs(scn_run_fs, coord_names, constraint_dct=constraint_dct) if not scn_run_fs[1].exists([coord_locs]): print("No scan to save. Skipping...") else: locs_lst = [] for locs in save_locs: # Set run filesys run_path = scn_run_fs[-1].path(locs) run_fs = autofile.fs.run(run_path) print("Reading from scan run at {}".format(run_path)) # Save the structure success, ret = read_job(job, run_fs) if success: # Need to get the init zma structure in here # could write init zma to run filesys; wont work retro # get init zma readers? if run_fs[-1].file.zmatrix.exists([job]): init_zma = run_fs[-1].file.zmatrix.read([job]) filesys.save.scan_point_structure(ret, scn_save_fs, locs, mod_thy_info[1:], job, init_zma=init_zma, init_geo=None) locs_lst.append(locs) # Build the trajectory file if locs_lst: _write_traj(coord_locs, scn_save_fs, mod_thy_info, locs_lst)
def run_onedmin(spc_name, spc_dct, thy_dct, etrans_keyword_dct, run_prefix, save_prefix): """ Run the task """ bath_name = etrans_keyword_dct['bath'] tgt_dct, bath_dct = spc_dct[spc_name], spc_dct[bath_name] tgt_info = filesys.inf.get_spc_info(tgt_dct) bath_info = filesys.inf.get_spc_info(bath_dct) lj_info = filesys.inf.combine_spc_info(tgt_info, bath_info) # Build the modified thy objs inp_thy_info = filesys.inf.get_es_info(etrans_keyword_dct['inplvl'], thy_dct) run_thy_info = filesys.inf.get_es_info(etrans_keyword_dct['runlvl'], thy_dct) tgt_mod_thy_info = filesys.inf.modify_orb_restrict(tgt_info, inp_thy_info) bath_mod_thy_info = filesys.inf.modify_orb_restrict( bath_info, inp_thy_info) lj_mod_thy_info = filesys.inf.modify_orb_restrict(lj_info, run_thy_info) # Build the target conformer filesystem objects _, tgt_cnf_save_fs = filesys.build_fs(run_prefix, save_prefix, 'CONFORMER', spc_locs=tgt_info, thy_locs=tgt_mod_thy_info[1:]) tgt_loc_info = filesys.mincnf.min_energy_conformer_locators( tgt_cnf_save_fs, tgt_mod_thy_info) _, tgt_cnf_save_path = tgt_loc_info # Build the bath conformer filesystem objects _, bath_cnf_save_fs = filesys.build_fs(run_prefix, save_prefix, 'CONFORMER', spc_locs=bath_info, thy_locs=bath_mod_thy_info[1:]) # Build the target energy transfer filesystem objects etrans_save_fs = autofile.fs.energy_transfer(tgt_cnf_save_path) etrans_locs = bath_info + lj_mod_thy_info[1:4] # Calculate and save the Lennard-Jones parameters, if needed nsamp_needed = _nsamp_needed(etrans_save_fs, etrans_locs, etrans_keyword_dct) if nsamp_needed > 0: _runlj(nsamp_needed, lj_info, tgt_dct, lj_mod_thy_info, tgt_mod_thy_info, bath_mod_thy_info, tgt_cnf_save_fs, bath_cnf_save_fs, etrans_save_fs, etrans_locs, etrans_keyword_dct, run_prefix) else: epath = etrans_save_fs[-1].file.lennard_jones_epsilon.path(etrans_locs) spath = etrans_save_fs[-1].file.lennard_jones_sigma.path(etrans_locs) ioprinter.info_message( '- Lennard-Jones epsilon found at path {}'.format(epath)) ioprinter.info_message( '- Lennard-Jones sigma found at path {}'.format(spath))
def molecular_properties(dmom, polar): """ a """ if dmom is not None and polar is not None: dmom_str = automol.util.vec.string(dmom) polar_str = automol.util.mat.string(polar) info_message('Dipole Moment [Debye]:\n{}'.format(dmom_str), newline=1) info_message('Polarizability []: {}'.format(polar_str))
def run_fits_task(pes_grp_rlst, pes_param_dct, rate_paths_dct, mdriver_path, label_dct, pes_mod_dct, spc_mod_dct, thy_dct, tsk_key_dct): """ Run the fits and potentially assume that the rate_paths_dct will come in with all PESs in group """ # Combine all PESs into a string for writing the CKIN file pes_strs = () for pes_inf in pes_grp_rlst.keys(): _inf = (pes_inf[0], str(pes_inf[1] + 1), str(pes_inf[2] + 1)) pes_strs += ('_'.join(_inf), ) tot_fml = '-'.join(pes_strs) # Get the model and sort info from tsk key dct pes_mod = tsk_key_dct['kin_model'] spc_mod = tsk_key_dct['spc_model'] sort_info_lst = filesys.mincnf.sort_info_lst(tsk_key_dct['sort'], thy_dct) ioprinter.obj('vspace') ioprinter.obj('line_dash') # Obtain the rate constants from the MESS files ioprinter.info_message('Reading Rate Constants from MESS outputs', newline=1) rxn_ktp_dct = obtain_multipes_rxn_ktp_dct(rate_paths_dct, pes_param_dct, label_dct, pes_mod_dct, pes_mod) # Fit the rate constants ioprinter.info_message( 'Fitting Rate Constants for PES to Functional Forms', newline=1) ratefit_dct = pes_mod_dct[pes_mod]['rate_fit'] rxn_param_dct, rxn_err_dct = ratefit.fit.fit_rxn_ktp_dct( rxn_ktp_dct, ratefit_dct['fit_method'], pdep_dct=ratefit_dct['pdep_fit'], arrfit_dct=ratefit_dct['arrfit_fit'], chebfit_dct=ratefit_dct['chebfit_fit'], troefit_dct=ratefit_dct['troefit_fit'], ) # Write the reactions block header, which contains model info rxn_block_cmt = writer.ckin.model_header( (spc_mod, ), spc_mod_dct, sort_info_lst=sort_info_lst, refscheme=pes_mod_dct[pes_mod]['therm_fit']['ref_scheme']) # Get the comments dct and write the Chemkin string rxn_cmts_dct = chemkin_io.writer.comments.get_rxn_cmts_dct( rxn_err_dct=rxn_err_dct, rxn_block_cmt=rxn_block_cmt) ckin_str = chemkin_io.writer.mechanism.write_chemkin_file( rxn_param_dct=rxn_param_dct, rxn_cmts_dct=rxn_cmts_dct) # Write the file ckin_path = output_path('CKIN', prefix=mdriver_path) ckin_filename = f'{tot_fml}.ckin' ioformat.pathtools.write_file(ckin_str, ckin_path, ckin_filename)
def set_reference_ene(rxn_lst, spc_dct, thy_dct, pes_model_dct_i, spc_model_dct_i, run_prefix, save_prefix, ref_idx=0): """ Sets the reference species for the PES for which all energies are scaled relative to. """ # Set the index for the reference species, right now defualt to 1st spc ref_rxn = rxn_lst[ref_idx] _, (ref_rgts, _) = ref_rxn ioprinter.info_message('Determining the reference energy for PES...', newline=1) ioprinter.info_message( ' - Reference species assumed to be the', ' first set of reactants on PES: {}'.format('+'.join(ref_rgts))) # Get the model for the first reference species ref_scheme = pes_model_dct_i['therm_fit']['ref_scheme'] ref_enes = pes_model_dct_i['therm_fit']['ref_enes'] ref_ene_level = spc_model_dct_i['ene']['lvl1'][0] ioprinter.info_message( ' - Energy Level for Reference Species: {}'.format(ref_ene_level)) # Get the elec+zpe energy for the reference species ioprinter.info_message('') hf0k = 0.0 for rgt in ref_rgts: ioprinter.info_message(' - Calculating energy for {}...'.format(rgt)) basis_dct, uniref_dct = thmroutines.basis.prepare_refs( ref_scheme, spc_dct, [[rgt, None]], run_prefix, save_prefix) spc_basis, coeff_basis = basis_dct[rgt] # Build filesystem ene_spc, ene_basis = thmroutines.basis.basis_energy( rgt, spc_basis, uniref_dct, spc_dct, spc_model_dct_i, run_prefix, save_prefix) # Calcualte the total energy hf0k += thmroutines.heatform.calc_hform_0k(ene_spc, ene_basis, spc_basis, coeff_basis, ref_set=ref_enes) hf0k *= phycon.KCAL2EH return hf0k
def frequencies(freqs): """ Print out the Harmonic frequencies and ZPVE """ if freqs is not None: freq_str = automol.util.vec.string(freqs, num_per_row=6, val_format='{0:>12.3f}') harm_zpe = (sum(freqs) / 2.0) * phycon.WAVEN2KCAL info_message('Harmonic frequencies [cm-1]:\n{}'.format(freq_str), newline=1) info_message('Harmonic ZPVE [kcal mol-1]: {}'.format(harm_zpe), newline=1)
def _reac_sep_ene(rct_info, sp_thy_info, rcts_cnf_fs, run_prefix, overwrite, sp_script_str, **kwargs): """ Determine the sum of electronic energies of two reactants specified at the level of theory described in the theory info object. Will calculate the energy if it is not currently in the SAVE filesystem. """ # get the single reference energy for each of the reactant configurations spc_enes = [] for (run_fs, save_fs, mlocs, mpath), inf in zip(rcts_cnf_fs, rct_info): # Set the modified thy info mod_sp_thy_info = tinfo.modify_orb_label(sp_thy_info, inf) # Build filesys zma_fs = autofile.fs.zmatrix(mpath) # Read the geometry and set paths zma = zma_fs[-1].file.zmatrix.read([0]) geo = save_fs[-1].file.geometry.read(mlocs) # Build the single point filesys objects sp_save_fs = autofile.fs.single_point(mpath) # Calculate the save single point energy sp.run_energy(zma, geo, inf, mod_sp_thy_info, run_fs, save_fs, mlocs, run_prefix, sp_script_str, overwrite, **kwargs) exists = sp_save_fs[-1].file.energy.exists(mod_sp_thy_info[1:4]) if not exists: ioprinter.warning_message('No ene found') ene = None else: ene = sp_save_fs[-1].file.energy.read(mod_sp_thy_info[1:4]) # Append ene to list spc_enes.append(ene) # Analyze the energies in the list inf_ene = 0.0 for ene, inf in zip(spc_enes, rct_info): if ene is not None: inf_ene += ene else: ioprinter.error_message( 'Single reference energy job fails', f'for {inf}: ', 'Energy needed to evaluate infinite separation energy') inf_ene = None if inf_ene is not None: ioprinter.info_message(f'Reactant Energy [au]: {inf_ene}') return inf_ene
def _split_species(spc_dct, spc_name, thy_info, save_prefix, zma_locs=(0,)): """ Assess if a given species has an instability transformation file located in the save filesystem within a Z-Matrix layer: SPC/THY/CONFS/Z/ which are specified by the provided info. If file is found, use the contained information to break-up the species into products of the instability transformation. If no file found, return species. :param spc_dct: species information dict[spc_name: spc_information] :param spc_name: mechanism name of species to assess :type spc_name: str :param thy_info: ??? :type thy_info: ??? :param save_prefix: root-path to the save-filesystem :type save_prefix: str :param zma_locs: locs for zma filesys (put in spc dct) :type zma_locs: """ # Initialize an empty list split_names = () # Attempt to read the graph of the instability trans # Get the product graphs and inchis tra, path = filesys.read.instability_transformation( spc_dct, spc_name, thy_info, save_prefix, zma_locs=zma_locs) if tra is not None: ioprinter.info_message('\nFound instability files at path:') ioprinter.info_message(' {}'.format(path)) zrxn, _ = tra prd_gras = automol.reac.product_graphs(zrxn) constituent_ichs = tuple(automol.graph.inchi(gra, stereo=True) for gra in prd_gras) _split_names = () for ich in constituent_ichs: for name, spc_dct_i in spc_dct.items(): if ich == spc_dct_i.get('inchi'): _split_names += (name,) break split_names = tuple(i for n, i in enumerate(_split_names) if i not in _split_names[:n]) print('- Splitting species...') print('- New species: {}'.format(' '.join(split_names))) return split_names
def atm_data(spc_dct, spc_name, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix): """ Pull all neccessary info for the atom """ spc_dct_i = spc_dct[spc_name] # Set up all the filesystem objects using models and levels pf_filesystems = filesys.models.pf_filesys(spc_dct_i, spc_mod_dct_i, run_prefix, save_prefix, False) ioprinter.info_message('Obtaining the geometry...', newline=1) geom = rot.read_geom(pf_filesystems) ioprinter.info_message('Obtaining the electronic energy...', newline=1) ene_chnlvl = ene.read_energy(spc_dct_i, pf_filesystems, spc_mod_dct_i, run_prefix, read_ene=True, read_zpe=False) ene_reflvl = None zpe_chnlvl = None hf0k, hf0k_trs, _, _ = basis.enthalpy_calculation(spc_dct, spc_name, ene_chnlvl, {}, pes_mod_dct_i, spc_mod_dct_i, run_prefix, save_prefix, pforktp='ktp', zrxn=None) ene_chnlvl = hf0k * phycon.KCAL2EH hf0k_trs *= phycon.KCAL2EH # Create info dictionary inf_dct = { 'geom': geom, 'sym_factor': 1.0, 'freqs': tuple(), 'mess_hr_str': '', 'mass': util.atom_mass(spc_dct_i), 'elec_levels': spc_dct_i['elec_levels'], 'ene_chnlvl': ene_chnlvl, 'ene_reflvl': ene_reflvl, 'ene_tsref': hf0k_trs, 'zpe_chnlvl': zpe_chnlvl } return inf_dct
def build_wfn(ref_zma, ts_info, ts_formula, high_mul, rct_ichs, rct_info, aspace, mod_var_scn_thy_info): """ Build wavefunction """ if aspace is not None: num_act_orb, num_act_elc, num_states, guess_str = aspace guess_lines = guess_str.splitlines() casscf_options = cas_options( ts_info, ts_formula, num_act_elc, num_act_orb, num_states, add_two_closed=False) ioprinter.info_message('Using wfn guess from file...', newline=1) else: num_act_orb, num_act_elc, num_states = active_space( rct_ichs, rct_info) # Build the elstruct CASSCF options list used to build the wfn guess # (1) Build wfn with active space # (2) Build wfn with active space + 2 closed orbitals for stability cas_opt = [] cas_opt.append( cas_options( ts_info, ts_formula, num_act_elc, num_act_orb, num_states, add_two_closed=False)) cas_opt.append( cas_options( ts_info, ts_formula, num_act_elc, num_act_orb, num_states, add_two_closed=True)) # Write string that has all the components for building the wfn guess guess_str = multiref_wavefunction_guess( high_mul, ref_zma, ts_info, mod_var_scn_thy_info, cas_opt) guess_lines = guess_str.splitlines() # Set casscf options casscf_options = cas_opt[0] ioprinter.info_message( 'Generating wfn guess from internal options...', newline=1) # Manipulate the opt kwargs to use the wavefunction guess cas_kwargs = { 'casscf_options': casscf_options, 'gen_lines': {1: guess_lines}, 'mol_options': ['nosym'] # Turn off symmetry } return cas_kwargs
def run_tsk(tsk, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix): """ run an electronic structure task for generating a list of conformer or tau sampling geometries """ # Print the head of the task ioprinter.task_header(tsk, spc_name) ioprinter.keyword_list(es_keyword_dct, thy_dct) # If species is unstable, set task to 'none' ini_method_dct = thy_dct.get(es_keyword_dct['inplvl']) ini_thy_info = tinfo.from_dct(ini_method_dct) stable = True if 'ts' not in spc_name and tsk != 'init_geom': zrxn, path = filesys.read.instability_transformation( spc_dct, spc_name, ini_thy_info, save_prefix) stable = bool(zrxn is None) if stable: ioprinter.debug_message('- Proceeding with requested task...') # Get stuff from task job = tsk.split('_', 1)[1] # Run the task if an initial geom exists if 'init' in tsk and not skip_task(spc_dct, spc_name): _ = geom_init(spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'conf' in tsk and not skip_task(spc_dct, spc_name): conformer_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'tau' in tsk and not skip_task(spc_dct, spc_name): tau_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'hr' in tsk and not skip_task(spc_dct, spc_name): hr_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'rpath' in tsk and not skip_task(spc_dct, spc_name): pass elif 'irc' in tsk and not skip_task(spc_dct, spc_name): irc_tsk(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) elif 'find' in tsk: findts(job, spc_dct, spc_name, thy_dct, es_keyword_dct, run_prefix, save_prefix) else: ioprinter.info_message('Skipping task for unstable species...', newline=1)
def build_rundir(etrans_run_path): """ build the run directory """ # for idx in range(100): bld_locs = ['ONEDMIN', 0] bld_save_fs = autofile.fs.build(etrans_run_path) bld_save_fs[-1].create(bld_locs) run_path = bld_save_fs[-1].path(bld_locs) ioprinter.info_message( 'Build Path for OneDMin calculations', run_path) return run_path