Beispiel #1
0
def get_high_level_energy(spc_info,
                          thy_low_level,
                          thy_high_level,
                          save_prefix,
                          saddle=False):
    """ get high level energy at low level optimized geometry
    """
    if saddle:
        spc_save_path = save_prefix
    else:
        spc_save_fs = autofile.fs.species(save_prefix)
        spc_save_fs.leaf.create(spc_info)
        spc_save_path = spc_save_fs.leaf.path(spc_info)

    orb_restr = fsorb.orbital_restriction(spc_info, thy_low_level)
    thy_low_level = thy_low_level[1:3]
    thy_low_level.append(orb_restr)

    ll_save_fs = autofile.fs.theory(spc_save_path)
    ll_save_path = ll_save_fs.leaf.path(thy_low_level)

    if saddle:
        ll_save_fs = autofile.fs.ts(ll_save_path)
        ll_save_fs.trunk.create()
        ll_save_path = ll_save_fs.trunk.path()

    cnf_save_fs = autofile.fs.conformer(ll_save_path)
    min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs)
    if not min_cnf_locs:
        print('ERROR: No minimum conformer geometry for ',
              'this species {}'.format(spc_info[0]))
        return 0.0
    cnf_save_path = cnf_save_fs.leaf.path(min_cnf_locs)

    orb_restr = fsorb.orbital_restriction(spc_info, thy_high_level)
    thy_high_level = thy_high_level[1:3]
    thy_high_level.append(orb_restr)

    sp_save_fs = autofile.fs.single_point(cnf_save_path)
    sp_save_fs.leaf.create(thy_high_level)

    if os.path.exists(sp_save_fs.leaf.path(thy_high_level)):
        min_ene = sp_save_fs.leaf.file.energy.read(thy_high_level)
    else:
        print('No energy at path')
        min_ene = None

    return min_ene
Beispiel #2
0
def get_thermo_paths(spc_save_path, spc_info, har_level):
    """ set up the path for saving the pf input and output
    currently using the harmonic theory directory for this because
    there is no obvious place to save this information for a random
    assortment of har_level, tors_level, vpt2_level
    """
    orb_restr = fsorb.orbital_restriction(spc_info, har_level)
    har_levelp = har_level[1:3]
    har_levelp.append(orb_restr)

    thy_save_fs = autofile.fs.theory(spc_save_path)
    thy_save_fs.leaf.create(har_levelp)
    thy_save_path = thy_save_fs.leaf.path(har_levelp)
    bld_locs = ['PF', 0]
    bld_save_fs = autofile.fs.build(thy_save_path)
    bld_save_fs.leaf.create(bld_locs)
    pf_path = bld_save_fs.leaf.path(bld_locs)

    # prepare NASA polynomials
    bld_locs = ['NASA_POLY', 0]
    bld_save_fs.leaf.create(bld_locs)
    nasa_path = bld_save_fs.leaf.path(bld_locs)

    print('Build Path for Partition Functions')
    print(pf_path)

    return pf_path, nasa_path
Beispiel #3
0
def set_model_filesys(thy_save_fs, spc_info, level, saddle=False):
    """ Gets filesystem objects for torsional calculations
    """
    # Set the level for the model
    levelp = level[0:3]
    levelp.append(fsorb.orbital_restriction(spc_info, level))

    # Get the save fileystem path
    save_path = thy_save_fs.leaf.path(levelp[1:4])
    if saddle:
        save_fs = autofile.fs.ts(save_path)
        save_fs.trunk.create()
        save_path = save_fs.trunk.path()

    # Get the fs object and the locs
    cnf_save_fs = autofile.fs.conformer(save_path)
    min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs)

    # Get the save path for the conformers
    if min_cnf_locs:
        cnf_save_path = cnf_save_fs.leaf.path(min_cnf_locs)
    else:
        cnf_save_path = ''

    return cnf_save_fs, cnf_save_path, min_cnf_locs, save_path
Beispiel #4
0
def run_rates(header_str, energy_trans_str, well_str, bim_str, ts_str, tsdct,
              rxn_save_path, model_dct, thy_dct, run_model):
    """ Generate k(T,P) by first compiling all the MESS strings
        and then running MESS
    """
    pf_levels = lmech.set_es_model_info(model_dct['es'], thy_dct)[0]

    ts_info = (tsdct['ich'], tsdct['chg'], tsdct['mul'])
    orb_restr = fsorb.orbital_restriction(ts_info, thy_info)
    ref_level = thy_info[1:3]
    ref_level.append(orb_restr)
    print('ref level test:', ref_level)
    thy_save_fs = autofile.fs.theory(rxn_save_path)
    thy_save_fs.leaf.create(ref_level)
    thy_save_path = thy_save_fs.leaf.path(ref_level)

    mess_inp_str = '\n'.join(
        [header_str, energy_trans_str, well_str, bim_str, ts_str])

    print('mess input file')
    print(mess_inp_str)

    bld_locs = ['MESS', 0]
    bld_save_fs = autofile.fs.build(thy_save_path)
    bld_save_fs.leaf.create(bld_locs)
    mess_path = bld_save_fs.leaf.path(bld_locs)
    print('Build Path for MESS rate files:')
    print(mess_path)
    with open(os.path.join(mess_path, 'mess.inp'), 'w') as mess_file:
        mess_file.write(mess_inp_str)
    script.run_script(script.MESSRATE, mess_path)
    return mess_path
Beispiel #5
0
def get_thy_save_fs(save_prefix, spc_info, thy_info):
    """ create theory save filesystem
    """
    orb_restr = fsorb.orbital_restriction(
        spc_info, thy_info)
    thy_lvl = thy_info[0:3]
    thy_lvl.append(orb_restr)
    spc_save_path = get_spc_save_path(save_prefix, spc_info)
    thy_save_fs = autofile.fs.theory(spc_save_path)
    return thy_save_fs, thy_lvl
Beispiel #6
0
def find_barrierless_transition_state(ts_info, ts_zma, ts_dct, spc_dct, grid,
                                      dist_name, rxn_run_path, rxn_save_path,
                                      rad_rad_ts, multi_info, ini_thy_info,
                                      thy_info, run_prefix, save_prefix,
                                      scn_run_fs, scn_save_fs, opt_script_str,
                                      overwrite, update_guess, **opt_kwargs):
    """ Run TS finder for barrierless reactions
    """
    # run mep scan
    # multi_info = ['molpro2015', 'caspt2', 'cc-pvtz', 'RR']
    multi_info = ['molpro2015', 'caspt2', 'cc-pvdz', 'RR']

    orb_restr = fsorb.orbital_restriction(ts_info, multi_info)
    multi_level = multi_info[0:3]
    multi_level.append(orb_restr)

    thy_run_fs = autofile.fs.theory(rxn_run_path)
    thy_run_fs.leaf.create(multi_level[1:4])
    thy_run_path = thy_run_fs.leaf.path(multi_level[1:4])

    thy_save_fs = autofile.fs.theory(rxn_save_path)
    thy_save_fs.leaf.create(multi_level[1:4])
    thy_save_path = thy_save_fs.leaf.path(multi_level[1:4])

    scn_run_fs = autofile.fs.scan(thy_run_path)
    scn_save_fs = autofile.fs.scan(thy_save_path)

    ts_formula = automol.geom.formula(automol.zmatrix.geometry(ts_zma))
    grid1 = grid[0]
    grid2 = grid[1]
    grid = numpy.append(grid[0], grid[1])
    high_mul = ts_dct['high_mul']
    print('starting multiref scan:', scn_run_fs.trunk.path())

    # Set the active space
    num_act_orb, num_act_elc = variational.wfn.active_space(
        ts_dct, spc_dct, high_mul)

    # Run PST, VTST, VRC-TST based on RAD_RAD_TS model
    if rad_rad_ts.lower() == 'pst':
        pass
    elif rad_rad_ts.lower() == 'vtst':
        geo, zma, final_dist = variational.vtst.run_vtst_scan(
            ts_zma, ts_formula, ts_info, ts_dct, spc_dct, high_mul, grid1,
            grid2, dist_name, multi_level, num_act_orb, num_act_elc,
            multi_info, ini_thy_info, thy_info, run_prefix, save_prefix,
            scn_run_fs, scn_save_fs, opt_script_str, overwrite, update_guess,
            **opt_kwargs)
    elif rad_rad_ts.lower() == 'vrctst':
        # vrctst.calc_vrctst_rates()
        pass

    return geo, zma, final_dist
Beispiel #7
0
def get_thy_run_path(run_prefix, spc_info, thy_info):
    """ create theory run path
    """
    orb_restr = fsorb.orbital_restriction(
        spc_info, thy_info)
    thy_lvl = thy_info[0:3]
    thy_lvl.append(orb_restr)
    spc_run_path = get_spc_run_path(run_prefix, spc_info)
    thy_run_fs = autofile.fs.theory(spc_run_path)
    thy_run_fs.leaf.create(thy_lvl)
    thy_run_path = thy_run_fs.leaf.path(thy_lvl)
    return thy_run_path
Beispiel #8
0
def reagent_energies(save_prefix, rgt_ichs, rgt_chgs, rgt_muls, thy_level):
    """ reagent energies """
    enes = []
    for rgt_ich, rgt_chg, rgt_mul in zip(rgt_ichs, rgt_chgs, rgt_muls):
        spc_save_fs = autofile.fs.species(save_prefix)
        rgt_info = [rgt_ich, rgt_chg, rgt_mul]
        spc_save_path = spc_save_fs.leaf.path(rgt_info)

        orb_restr = fsorb.orbital_restriction(rgt_info, thy_level)
        thy_lvl = thy_level[0:3]
        thy_lvl.append(orb_restr)
        thy_save_fs = autofile.fs.theory(spc_save_path)
        thy_save_path = thy_save_fs.leaf.path(thy_lvl[1:4])
        cnf_save_fs = autofile.fs.conformer(thy_save_path)
        min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs)
        ene = cnf_save_fs.leaf.file.energy.read(min_cnf_locs)
        enes.append(ene)
    return enes
Beispiel #9
0
def get_geos(
        spcs, spc_dct, ini_thy_info, save_prefix, run_prefix, kickoff_size,
        kickoff_backward, projrot_script_str):
    """get geos for reactants and products using the initial level of theory
    """
    spc_geos = []
    cnf_save_fs_lst = []
    for spc in spcs:
        spc_info = [spc_dct[spc]['ich'],
                    spc_dct[spc]['chg'],
                    spc_dct[spc]['mul']]
        orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info)
        ini_thy_level = ini_thy_info[0:3]
        ini_thy_level.append(orb_restr)
        spc_save_fs = autofile.fs.species(save_prefix)
        spc_save_fs.leaf.create(spc_info)
        spc_save_path = spc_save_fs.leaf.path(spc_info)
        spc_run_fs = autofile.fs.species(run_prefix)
        spc_run_fs.leaf.create(spc_info)
        spc_run_path = spc_run_fs.leaf.path(spc_info)
        ini_thy_save_fs = autofile.fs.theory(spc_save_path)
        ini_thy_save_path = ini_thy_save_fs.leaf.path(ini_thy_level[1:4])
        ini_thy_run_fs = autofile.fs.theory(spc_run_path)
        ini_thy_run_path = ini_thy_run_fs.leaf.path(ini_thy_level[1:4])
        cnf_save_fs = autofile.fs.conformer(ini_thy_save_path)
        cnf_save_fs_lst.append(cnf_save_fs)
        cnf_run_fs = autofile.fs.conformer(ini_thy_run_path)
        min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs)
        if min_cnf_locs:
            geo = cnf_save_fs.leaf.file.geometry.read(min_cnf_locs)
        else:
            run_fs = autofile.fs.run(ini_thy_run_path)
            run_fs.trunk.create()
            tmp_ini_fs = [None, ini_thy_save_fs]
            tmp_fs = [spc_save_fs, spc_run_fs, ini_thy_save_fs, ini_thy_run_fs,
                      cnf_save_fs, cnf_run_fs, run_fs]
            geo = geom.reference_geometry(
                spc_dct[spc], ini_thy_level, ini_thy_level, tmp_fs, tmp_ini_fs,
                kickoff_size, kickoff_backward, projrot_script_str,
                overwrite=False)
        spc_geos.append(geo)
    return spc_geos, cnf_save_fs_lst
Beispiel #10
0
def find_ts(spc_dct,
            ts_dct,
            ts_zma,
            ini_thy_info,
            thy_info,
            run_prefix,
            save_prefix,
            overwrite,
            rad_rad_ts='vtst'):
    """ find the ts geometry
    """

    # Set various TS information using the dictionary
    typ = ts_dct['class']
    dist_info = ts_dct['dist_info']
    grid = ts_dct['grid']
    bkp_ts_class_data = ts_dct['bkp_data']
    rad_rad = ('radical radical' in typ)
    low_spin = ('low spin' in typ)
    print('prepping ts scan for:', typ)

    [_, _, rxn_run_path, rxn_save_path] = ts_dct['rxn_fs']
    ts_info = (ts_dct['ich'], ts_dct['chg'], ts_dct['mul'])

    _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(*thy_info[0:2])

    orb_restr = fsorb.orbital_restriction(ts_info, thy_info)
    ref_level = thy_info[0:3]
    ref_level.append(orb_restr)

    thy_run_fs = autofile.fs.theory(rxn_run_path)
    thy_run_fs.leaf.create(ref_level[1:4])
    thy_run_path = thy_run_fs.leaf.path(ref_level[1:4])

    thy_save_fs = autofile.fs.theory(rxn_save_path)
    thy_save_fs.leaf.create(ref_level[1:4])
    thy_save_path = thy_save_fs.leaf.path(ref_level[1:4])

    scn_run_fs = autofile.fs.scan(thy_run_path)
    scn_save_fs = autofile.fs.scan(thy_save_path)

    ts_run_fs = autofile.fs.ts(thy_run_path)
    ts_run_fs.trunk.create()
    ts_run_path = ts_run_fs.trunk.path()
    run_fs = autofile.fs.run(ts_run_path)

    ts_save_fs = autofile.fs.ts(thy_save_path)
    ts_save_fs.trunk.create()
    ts_save_path = ts_save_fs.trunk.path()

    cnf_run_fs = autofile.fs.conformer(ts_run_path)
    cnf_save_fs = autofile.fs.conformer(ts_save_path)
    cnf_save_fs.trunk.create()

    # Unpack the dist info
    dist_name, _, update_guess, brk_name = dist_info

    # Get TS from filesys or get it from some procedure
    min_cnf_locs = fsmin.min_energy_conformer_locators(cnf_save_fs)
    if min_cnf_locs and not overwrite:
        check_filesys_for_ts(ts_dct, ts_zma, cnf_save_fs, overwrite, typ,
                             dist_info, dist_name, bkp_ts_class_data)
    else:
        filesys = [
            None, None, ts_run_fs, ts_save_fs, cnf_run_fs, cnf_save_fs, None,
            None, scn_run_fs, scn_save_fs, run_fs
        ]
        print('running ts scan:')
        if rad_rad and low_spin and 'elimination' not in ts_dct['class']:
            print('Running Scan for Barrierless TS:')
            find_barrierless_transition_state(
                ts_info, ts_zma, ts_dct, spc_dct, grid, dist_name,
                rxn_run_path, rxn_save_path, rad_rad_ts, ini_thy_info,
                thy_info, run_prefix, save_prefix, scn_run_fs, scn_save_fs,
                opt_script_str, overwrite, update_guess, **opt_kwargs)
            # Have code analyze the path and switch to a sadpt finder if needed
        else:
            print('Running Scan for Fixed TS:')
            max_zma = run_sadpt_scan(typ, grid, dist_name, brk_name, ts_zma,
                                     ts_info, ref_level, scn_run_fs,
                                     scn_save_fs, opt_script_str, overwrite,
                                     update_guess, **opt_kwargs)
            geo, zma, final_dist = find_sadpt_transition_state(
                opt_script_str, run_fs, max_zma, ts_info, ref_level, overwrite,
                ts_save_path, ts_save_fs, dist_name, dist_info, filesys,
                **opt_kwargs)

    return geo, zma, final_dist
Beispiel #11
0
def set_fs(spc_dct, spc, thy_info,
           run_prefix, save_prefix,
           setfs_chk=True, ini_fs=False):
    """ set up filesystem """

    # Build the species filesys objs
    [spc_info,
     spc_run_fs, spc_save_fs,
     spc_run_path, spc_save_path] = set_spc_fs(
         spc_dct, spc, run_prefix, save_prefix)

    # Initialize the filesystems
    thy_run_fs = None
    thy_run_path = None
    thy_save_fs = None
    thy_save_path = None
    cnf_run_fs = None
    cnf_save_fs = None
    tau_run_fs = None
    tau_save_fs = None
    thy_level = thy_info
    scn_run_fs = None
    scn_save_fs = None

    # Build the theory filesys obj
    thy_level = thy_info
    orb_restr = fsorb.orbital_restriction(
        spc_info, thy_info)
    thy_level = thy_info[0:3]
    thy_level.append(orb_restr)
    thy_run_fs = autofile.fs.theory(spc_run_path)
    thy_save_fs = autofile.fs.theory(spc_save_path)

    if setfs_chk:
        if 'ts_' in spc:
            thy_run_fs.leaf.create(thy_level[1:4])
            thy_run_path = thy_run_fs.leaf.path(thy_level[1:4])
            thy_save_fs.leaf.create(thy_level[1:4])
            thy_save_path = thy_save_fs.leaf.path(thy_level[1:4])

            thy_run_fs = autofile.fs.ts(thy_run_path)
            thy_run_fs.trunk.create()
            thy_run_path = thy_run_fs.trunk.path()

            thy_save_fs = autofile.fs.ts(thy_save_path)
            thy_save_fs.trunk.create()
            thy_save_path = thy_save_fs.trunk.path()

        else:
            thy_run_fs.leaf.create(thy_level[1:4])
            thy_run_path = thy_run_fs.leaf.path(thy_level[1:4])
            thy_save_fs.leaf.create(thy_level[1:4])
            thy_save_path = thy_save_fs.leaf.path(thy_level[1:4])

        cnf_run_fs = autofile.fs.conformer(thy_run_path)
        cnf_save_fs = autofile.fs.conformer(thy_save_path)
        tau_run_fs = autofile.fs.tau(thy_run_path)
        tau_save_fs = autofile.fs.tau(thy_save_path)
        min_cnf_locs = fsmin.min_energy_conformer_locators(
            cnf_save_fs)
        if min_cnf_locs:
            min_cnf_run_path = cnf_run_fs.leaf.path(min_cnf_locs)
            min_cnf_save_path = cnf_save_fs.leaf.path(min_cnf_locs)
            scn_run_fs = autofile.fs.conformer(min_cnf_run_path)
            scn_save_fs = autofile.fs.conformer(min_cnf_save_path)

    # filesys = [spc_run_fs, spc_save_fs, thy_run_fs, thy_save_fs,
    #            cnf_run_fs, cnf_save_fs, tau_run_fs, tau_save_fs,
    #            scn_run_fs, scn_save_fs]

    # Add run fs if needed
    if not ini_fs:
        filesys = [spc_run_fs, spc_save_fs, 
                   thy_run_fs, thy_save_fs,
                   cnf_run_fs, cnf_save_fs,
                   tau_run_fs, tau_save_fs,
                   scn_run_fs, scn_save_fs]
        run_fs = autofile.fs.run(thy_run_path)
        run_fs.trunk.create()
        filesys.append(run_fs)
    else:
        filesys = [thy_run_fs, thy_save_fs,
                   cnf_run_fs, cnf_save_fs,
                   tau_run_fs, tau_save_fs,
                   scn_run_fs, scn_save_fs]

    return filesys, thy_level
Beispiel #12
0
def fake_species_block(spc_dct_i, spc_dct_j, spc_info_i, spc_info_j, spc_model,
                       pf_levels, save_prefix_i, save_prefix_j):
    """ prepare a fake species block corresponding to the
        van der Waals well between two fragments
    """
    [_, _, harm_level, _, sym_level, tors_level] = pf_levels
    tors_model, vib_model, sym_model = spc_model

    # prepare the four sets of file systems
    orb_restr = fsorb.orbital_restriction(spc_info_i, harm_level)
    har_levelp_i = harm_level[0:3]
    har_levelp_i.append(orb_restr)
    orb_restr = fsorb.orbital_restriction(spc_info_j, harm_level)
    har_levelp_j = harm_level[0:3]
    har_levelp_j.append(orb_restr)

    # Set theory filesystem used throughout
    thy_save_fs_i = autofile.fs.theory(save_prefix_i)
    thy_save_fs_j = autofile.fs.theory(save_prefix_j)

    # Set the filesystem objects for the two species
    harmfs_i = set_model_filesys(thy_save_fs_i,
                                 spc_info_i,
                                 harm_level,
                                 saddle=False)
    harmfs_j = set_model_filesys(thy_save_fs_j,
                                 spc_info_j,
                                 harm_level,
                                 saddle=False)
    [harm_cnf_save_fs_i, _, harm_min_cnf_locs_i, _] = harmfs_i
    [harm_cnf_save_fs_j, _, harm_min_cnf_locs_j, _] = harmfs_j

    if sym_level:
        symfs_i = set_model_filesys(thy_save_fs_i,
                                    spc_info_i,
                                    sym_level,
                                    saddle=False)
        symfs_j = set_model_filesys(thy_save_fs_j,
                                    spc_info_j,
                                    sym_level,
                                    saddle=False)
        [sym_cnf_save_fs_i, _, sym_min_cnf_locs_i, _] = symfs_i
        [sym_cnf_save_fs_j, _, sym_min_cnf_locs_j, _] = symfs_j

    if tors_level:
        torsfs_i = set_model_filesys(thy_save_fs_i,
                                     spc_info_i,
                                     tors_level[0],
                                     saddle=False)
        torsfs_j = set_model_filesys(thy_save_fs_j,
                                     spc_info_j,
                                     tors_level[0],
                                     saddle=False)
        [
            tors_cnf_save_fs_i, tors_cnf_save_path_i, tors_min_cnf_locs_i,
            tors_save_path_i
        ] = torsfs_i
        [
            tors_cnf_save_fs_j, tors_cnf_save_path_j, tors_min_cnf_locs_j,
            tors_save_path_j
        ] = torsfs_j

    spc_str = ''

    # Get the combined electronic energy levels
    elec_levels = messfutil.combine_elec_levels(spc_dct_i, spc_dct_j)

    # Determine the species symmetry factor using the given model
    saddle = False
    dist_names = []
    tors_names = []
    frm_bnd_key = []
    brk_bnd_key = []
    sym_factor_i = sym.symmetry_factor(sym_model, spc_dct_i, spc_info_i,
                                       dist_names, saddle, frm_bnd_key,
                                       brk_bnd_key, tors_names,
                                       tors_cnf_save_fs_i, tors_min_cnf_locs_i,
                                       sym_cnf_save_fs_i, sym_min_cnf_locs_i)
    sym_factor_j = sym.symmetry_factor(sym_model, spc_dct_j, spc_info_j,
                                       dist_names, saddle, frm_bnd_key,
                                       brk_bnd_key, tors_names,
                                       tors_cnf_save_fs_j, tors_min_cnf_locs_j,
                                       sym_cnf_save_fs_j, sym_min_cnf_locs_j)
    sym_factor = sym_factor_i * sym_factor_j

    # Get the freqs
    freqs = pfmodels.set_fake_freqs(harm_min_cnf_locs_i, harm_min_cnf_locs_j,
                                    harm_cnf_save_fs_i, harm_cnf_save_fs_j)
    geo = pfmodels.combine_geos_in_fake_well(harm_min_cnf_locs_i,
                                             harm_min_cnf_locs_j,
                                             harm_cnf_save_fs_i,
                                             harm_cnf_save_fs_j)

    if vib_model == 'harm' and tors_model == 'rigid':
        _, freqs_i, _ = pfmodels.vib_harm_tors_rigid(spc_info_i,
                                                     harm_min_cnf_locs_i,
                                                     harm_cnf_save_fs_i,
                                                     saddle=saddle)
        _, freqs_j, _ = pfmodels.vib_harm_tors_rigid(spc_info_j,
                                                     harm_min_cnf_locs_j,
                                                     harm_cnf_save_fs_j,
                                                     saddle=saddle)
        freqs += freqs_i + freqs_j
        hind_rot_str = ""

    if vib_model == 'harm' and tors_model == '1dhr':
        if messfutil.is_atom(harm_min_cnf_locs_i, harm_cnf_save_fs_i):
            freqs_i = []
            hr_str_i = ''
            symf_i = sym_factor_i
        else:
            _, freqs_i, _, hr_str_i, _ = pfmodels.vib_harm_tors_1dhr(
                harm_min_cnf_locs_i,
                harm_cnf_save_fs_i,
                tors_min_cnf_locs_i,
                tors_cnf_save_fs_i,
                tors_save_path_i,
                tors_cnf_save_path_i,
                spc_dct_i,
                spc_info_i,
                frm_bnd_key,
                brk_bnd_key,
                sym_factor_i,
                elec_levels,
                saddle=False)
        if messfutil.is_atom(harm_min_cnf_locs_j, harm_cnf_save_fs_j):
            freqs_j = []
            hr_str_j = ''
            symf_j = sym_factor_j
        else:
            _, freqs_j, _, hr_str_j, _ = pfmodels.vib_harm_tors_1dhr(
                harm_min_cnf_locs_j,
                harm_cnf_save_fs_j,
                tors_min_cnf_locs_j,
                tors_cnf_save_fs_j,
                tors_save_path_j,
                tors_cnf_save_path_j,
                spc_dct_j,
                spc_info_j,
                frm_bnd_key,
                brk_bnd_key,
                sym_factor_j,
                elec_levels,
                saddle=False)
        freqs += list(freqs_i) + list(freqs_j)
        hind_rot_str = hr_str_i + hr_str_j
        sym_factor = symf_i * symf_j

    core = mess_io.writer.core_rigidrotor(geo, sym_factor)
    spc_str = mess_io.writer.molecule(core,
                                      freqs,
                                      elec_levels,
                                      hind_rot=hind_rot_str)

    return spc_str
Beispiel #13
0
def vtst_with_no_saddle_block(ts_dct, ts_label, reac_label, prod_label,
                              spc_ene, rct_zpe, projrot_script_str,
                              multi_info):
    """ prepare the mess input string for a variational TS that does not have
    a saddle point. Do it by calling the species block for each grid point
    in the scan file system
    """

    ts_info = ['', ts_dct['chg'], ts_dct['mul']]
    orb_restr = fsorb.orbital_restriction(ts_info, multi_info)
    multi_level = multi_info[0:3]
    multi_level.append(orb_restr)

    rxn_save_path = ts_dct['rxn_fs'][3]
    thy_save_fs = autofile.fs.theory(rxn_save_path)
    thy_save_fs.leaf.create(multi_level[1:4])
    thy_save_path = thy_save_fs.leaf.path(multi_level[1:4])
    scn_save_fs = autofile.fs.scan(thy_save_path)

    # Read the scan save filesystem to get the molecular info
    sym_factor = 1.
    irc_pt_strs = []
    proj_rotors_str = ''
    pot = []

    elec_levels = [[0., ts_dct['mul']]]
    grid = ts_dct['grid']
    grid = numpy.append(grid[0], grid[1])
    dist_name = ts_dct['dist_info'][0]

    # Read the infinite separation energy
    inf_locs = [[dist_name], [1000.]]
    inf_sep_ene = scn_save_fs.leaf.file.energy.read(inf_locs)

    grid[::-1].sort()
    for idx, grid_val in enumerate(grid):
        # Set the filesystem locators for each grid point
        locs = [[dist_name], [grid_val]]

        # Get geometry, energy, and vibrational freqs
        if not scn_save_fs.leaf.file.geometry.exists(locs):
            continue
        else:
            geom = scn_save_fs.leaf.file.geometry.read(locs)
        if not scn_save_fs.leaf.file.energy.exists(locs):
            continue
        else:
            ene = scn_save_fs.leaf.file.energy.read(locs)
        if not scn_save_fs.leaf.file.hessian.exists(locs):
            continue
        else:
            hess = scn_save_fs.leaf.file.hessian.read(locs)
            scn_save_path = scn_save_fs.leaf.path(locs)
            freqs, _, _ = pfmodels.projrot_freqs_1(geom,
                                                   hess,
                                                   pot,
                                                   proj_rotors_str,
                                                   projrot_script_str,
                                                   scn_save_path,
                                                   saddle=True)

        # Calculate standard harmonic ZPVE
        zpe = sum(freqs) * phycon.WAVEN2KCAL / 2.

        # Calcuate infinite separation ZPVE
        # Assumes the ZPVE = ZPVE(1st grid pt) as an approximation
        if idx == 0:
            rct_zpe = zpe

        # Calculate the reference energies
        erel = (ene - inf_sep_ene) * phycon.EH2KCAL
        erel_zpe_corr = erel + zpe - rct_zpe
        eref_abs = erel_zpe_corr + spc_ene

        # Iniialize the header of the string
        irc_pt_str = '!----------------------------------------------- \n'
        irc_pt_str += '! IRC Point {0}\n'.format(str(idx + 1))

        # Write the MESS string for the molecule section for each irc point
        core = mess_io.writer.mol_data.core_rigidrotor(geom,
                                                       sym_factor,
                                                       interp_emax='')
        irc_pt_str += mess_io.writer.species.molecule(core,
                                                      freqs,
                                                      elec_levels,
                                                      hind_rot='',
                                                      xmat=None,
                                                      rovib_coups='',
                                                      rot_dists='')

        # Append the zero energy for the molecule
        irc_pt_str += ('    ZeroEnergy[kcal/mol]      ',
                       '{0:<8.2f}\n'.format(eref_abs))
        if grid_val != grid[-1]:
            irc_pt_str += 'End \n'

        # Append string to list
        irc_pt_strs.append(irc_pt_str)

    # Write the MESS string for the entire variational section
    variational_str = mess_io.writer.rxnchan.ts_variational(
        ts_label, reac_label, prod_label, irc_pt_strs)

    return variational_str
Beispiel #14
0
def infinite_separation_energy(spc_1_info,
                               spc_2_info,
                               ts_info,
                               high_mul,
                               ref_zma,
                               ini_thy_info,
                               thy_info,
                               multi_info,
                               run_prefix,
                               save_prefix,
                               scn_run_fs,
                               scn_save_fs,
                               locs,
                               overwrite=False,
                               num_act_elc=None,
                               num_act_orb=None):
    """ Obtain the infinite separation energy from the multireference energy
        at a given reference point, the high-spin low-spin splitting at that
        reference point, and the high level energy for the high spin state
        at the reference geometry and for the fragments
    """

    # Initialize infinite sep energy
    inf_sep_ene = -1.0e12

    # set up all the file systems for the TS
    # start with the geo and reference theory info
    geo_run_path = scn_run_fs.leaf.path(locs)
    geo_save_path = scn_save_fs.leaf.path(locs)
    geo = scn_save_fs.leaf.file.geometry.read(locs)
    sp_run_fs = autofile.fs.single_point(geo_run_path)
    sp_save_fs = autofile.fs.single_point(geo_save_path)

    # get the multi reference ene for low spin state for the ref point on scan

    # file system for low spin multireference calculation

    multi_info[0] = 'molpro2015'
    multi_info[1] = 'caspt2'
    # ultimately the above should be properly passed
    prog = multi_info[0]
    method = multi_info[1]

    # get the multi reference energy for high spin state for ref point on scan
    hs_info = (ts_info[0], ts_info[1], high_mul)
    orb_restr = fsorb.orbital_restriction(hs_info, multi_info)
    multi_lvl = multi_info[0:3]
    multi_lvl.append(orb_restr)

    hs_run_fs = autofile.fs.high_spin(geo_run_path)
    hs_save_fs = autofile.fs.high_spin(geo_save_path)
    hs_run_fs.leaf.create(multi_lvl[1:4])
    hs_save_fs.leaf.create(multi_lvl[1:4])

    hs_mr_run_path = hs_run_fs.leaf.path(multi_lvl[1:4])
    hs_mr_save_path = hs_save_fs.leaf.path(multi_lvl[1:4])
    run_mr_fs = autofile.fs.run(hs_mr_run_path)

    mr_script_str, _, mr_kwargs, _ = runpar.run_qchem_par(prog, method)

    if num_act_elc is None and num_act_orb is None:
        num_act_elc = high_mul
        num_act_orb = num_act_elc
    ts_formula = automol.geom.formula(automol.zmatrix.geometry(ref_zma))

    cas_opt, _ = ts.cas_options_2(hs_info, ts_formula, num_act_elc,
                                  num_act_orb, high_mul)
    guess_str = ts.multiref_wavefunction_guess(high_mul, ref_zma, hs_info,
                                               multi_lvl, [cas_opt])
    guess_lines = guess_str.splitlines()

    mr_kwargs['casscf_options'] = cas_opt
    mr_kwargs['mol_options'] = ['nosym']
    mr_kwargs['gen_lines'] = {1: guess_lines}

    ret = driver.read_job(
        job='energy',
        run_fs=run_mr_fs,
    )
    if ret:
        print(" - Reading high spin multi reference energy from output...")
        inf_obj, inp_str, out_str = ret
        ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str)
        hs_save_fs.leaf.file.energy.write(ene, multi_lvl[1:4])
        hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4])
        hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4])

    if not hs_save_fs.leaf.file.energy.exists(multi_lvl[1:4]) or overwrite:
        print(" - Running high spin multi reference energy ...")
        driver.run_job(
            job='energy',
            script_str=mr_script_str,
            run_fs=run_mr_fs,
            geom=geo,
            spc_info=hs_info,
            thy_level=multi_lvl,
            overwrite=overwrite,
            **mr_kwargs,
        )

        ret = driver.read_job(
            job='energy',
            run_fs=run_mr_fs,
        )

        if ret is not None:
            inf_obj, inp_str, out_str = ret

            print(" - Reading high spin multi reference energy from output...")
            hs_mr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method,
                                               out_str)

            print(" - Saving high spin multi reference energy...")
            print(" - Save path: {}".format(hs_mr_save_path))
            hs_save_fs.leaf.file.energy.write(hs_mr_ene, multi_lvl[1:4])
            hs_save_fs.leaf.file.input.write(inp_str, multi_lvl[1:4])
            hs_save_fs.leaf.file.info.write(inf_obj, multi_lvl[1:4])
        else:
            print('ERROR: high spin multi reference energy job fails: ',
                  'Energy is needed to evaluate infinite separation energy')
            return inf_sep_ene

    else:
        hs_mr_ene = hs_save_fs.leaf.file.energy.read(multi_lvl[1:4])

    # file system for high spin single ireference calculation
    thy_info = ['molpro2015', 'ccsd(t)-f12', 'cc-pvdz-f12', 'RR']
    orb_restr = fsorb.orbital_restriction(hs_info, thy_info)
    thy_lvl = thy_info[0:3]
    thy_lvl.append(orb_restr)

    hs_run_fs.leaf.create(thy_lvl[1:4])
    hs_save_fs.leaf.create(thy_lvl[1:4])

    hs_sr_run_path = hs_run_fs.leaf.path(thy_lvl[1:4])
    hs_sr_save_path = hs_save_fs.leaf.path(thy_lvl[1:4])
    run_sr_fs = autofile.fs.run(hs_sr_run_path)

    sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_lvl[0:2])
    ret = driver.read_job(
        job='energy',
        run_fs=run_sr_fs,
    )
    if ret:
        print(" - Reading high spin single reference energy from output...")
        inf_obj, inp_str, out_str = ret
        ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str)
        hs_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4])
        hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4])
        hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4])

    if not hs_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite:
        print(" - Running high spin single reference energy ...")

        errors, options_mat = runpar.set_molpro_options_mat(hs_info, geo)

        driver.run_job(
            job='energy',
            script_str=sp_script_str,
            run_fs=run_sr_fs,
            geom=geo,
            spc_info=hs_info,
            thy_level=thy_lvl,
            errors=errors,
            options_mat=options_mat,
            overwrite=overwrite,
            **kwargs,
        )

        ret = driver.read_job(
            job='energy',
            run_fs=run_sr_fs,
        )

        if ret is not None:
            inf_obj, inp_str, out_str = ret

            print(" - Reading high spin single ref energy from output...")
            hs_sr_ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method,
                                               out_str)

            print(" - Saving high spin single reference energy...")
            print(" - Save path: {}".format(hs_sr_save_path))
            hs_save_fs.leaf.file.energy.write(hs_sr_ene, thy_lvl[1:4])
            hs_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4])
            hs_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4])
        else:
            print('ERROR: High spin single reference energy job fails: ',
                  'Energy is needed to evaluate infinite separation energy')
            return inf_sep_ene

    else:
        hs_sr_ene = hs_save_fs.leaf.file.energy.read(thy_lvl[1:4])

    # get the single reference energy for each of the reactant configurations
    spc_ene = []
    spc_infos = [spc_1_info, spc_2_info]
    for spc_info in spc_infos:
        # set up the file systems for the reactants one by one
        spc_run_fs = autofile.fs.species(run_prefix)
        spc_run_fs.leaf.create(spc_info)
        spc_run_path = spc_run_fs.leaf.path(spc_info)
        spc_save_fs = autofile.fs.species(save_prefix)
        spc_save_fs.leaf.create(spc_info)
        spc_save_path = spc_save_fs.leaf.path(spc_info)

        orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info)
        ini_thy_lvl = ini_thy_info[0:3]
        ini_thy_lvl.append(orb_restr)

        orb_restr = fsorb.orbital_restriction(spc_info, thy_info)
        thy_lvl = thy_info[0:3]
        thy_lvl.append(orb_restr)

        ini_thy_run_fs = autofile.fs.theory(spc_run_path)
        ini_thy_run_fs.leaf.create(ini_thy_lvl[1:4])
        ini_thy_run_path = ini_thy_run_fs.leaf.path(ini_thy_lvl[1:4])
        ini_thy_save_fs = autofile.fs.theory(spc_save_path)
        ini_thy_save_fs.leaf.create(ini_thy_lvl[1:4])
        ini_thy_save_path = ini_thy_save_fs.leaf.path(ini_thy_lvl[1:4])
        ini_cnf_run_fs = autofile.fs.conformer(ini_thy_run_path)
        ini_cnf_save_fs = autofile.fs.conformer(ini_thy_save_path)
        min_cnf_locs = fsmin.min_energy_conformer_locators(ini_cnf_save_fs)
        min_cnf_run_path = ini_cnf_run_fs.leaf.path(min_cnf_locs)
        min_cnf_save_path = ini_cnf_save_fs.leaf.path(min_cnf_locs)

        thy_run_fs = autofile.fs.theory(spc_run_path)
        thy_run_fs.leaf.create(thy_lvl[1:4])
        thy_save_fs = autofile.fs.theory(spc_save_path)
        thy_save_fs.leaf.create(thy_lvl[1:4])

        geo = ini_cnf_save_fs.leaf.file.geometry.read(min_cnf_locs)

        sp_run_fs = autofile.fs.single_point(min_cnf_run_path)
        sp_run_fs.leaf.create(thy_lvl[1:4])
        sp_save_fs = autofile.fs.single_point(min_cnf_save_path)
        sp_save_fs.leaf.create(thy_lvl[1:4])

        sp_sr_run_path = sp_run_fs.leaf.path(thy_lvl[1:4])
        sp_sr_save_path = sp_save_fs.leaf.path(thy_lvl[1:4])
        print('sp_sr_run_path')
        print(sp_sr_run_path)
        run_sr_fs = autofile.fs.run(sp_sr_run_path)

        ret = driver.read_job(
            job='energy',
            run_fs=run_sr_fs,
        )
        if ret:
            print(" - Reading single reference energy for",
                  "{} from output...".format(spc_info[0]))
            inf_obj, inp_str, out_str = ret
            ene = elstruct.reader.energy(inf_obj.prog, inf_obj.method, out_str)
            sp_save_fs.leaf.file.energy.write(ene, thy_lvl[1:4])
            sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4])
            sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4])

        if not sp_save_fs.leaf.file.energy.exists(thy_lvl[1:4]) or overwrite:
            print(" - Running single reference energy for",
                  "{} from output...".format(spc_info[0]))
            driver.run_job(
                job='energy',
                script_str=sp_script_str,
                run_fs=run_sr_fs,
                geom=geo,
                spc_info=spc_info,
                thy_level=thy_lvl,
                overwrite=overwrite,
                **kwargs,
            )

            ret = driver.read_job(
                job='energy',
                run_fs=run_sr_fs,
            )

            if ret is not None:
                inf_obj, inp_str, out_str = ret

                print(" - Reading single reference energy for ",
                      "{} from output...".format(spc_info[0]))
                sp_sr_ene = elstruct.reader.energy(inf_obj.prog,
                                                   inf_obj.method, out_str)

                print(" - Saving single reference energy for ",
                      "{} from output...".format(spc_info[0]))
                print(" - Save path: {}".format(sp_sr_save_path))
                sp_save_fs.leaf.file.energy.write(sp_sr_ene, thy_lvl[1:4])
                sp_save_fs.leaf.file.input.write(inp_str, thy_lvl[1:4])
                sp_save_fs.leaf.file.info.write(inf_obj, thy_lvl[1:4])

            else:
                print('ERROR: Single reference energy job fails',
                      'for {}: '.format(spc_info[0]),
                      'Energy needed to evaluate infinite separation energy')
                return inf_sep_ene

        else:
            sp_sr_ene = sp_save_fs.leaf.file.energy.read(thy_lvl[1:4])

        spc_ene.append(sp_sr_ene)

    inf_sep_ene = spc_ene[0] + spc_ene[1] - hs_sr_ene + hs_mr_ene

    return inf_sep_ene
Beispiel #15
0
def find_vdw(ts_name, spc_dct, thy_info, ini_thy_info, vdw_params, nsamp_par,
             run_prefix, save_prefix, kickoff_size, kickoff_backward,
             overwrite):
    """ Find van der Waals structures for all the pairs of
        species in a reaction list
    """
    projrot_script_str = script.PROJROT
    new_vdws = []
    _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(*thy_info[:2])
    mul = spc_dct[ts_name]['low_mul']
    vdw_names_lst = []
    if vdw_params[0]:
        vdw_names_lst.append([sorted(spc_dct[ts_name]['reacs']), mul, 'r'])
    if vdw_params[1]:
        vdw_names_lst.append([sorted(spc_dct[ts_name]['prods']), mul, 'p'])

    for names, ts_mul, label in vdw_names_lst:
        if len(names) < 2:
            print('Cannot find van der Waals well for unimolecular',
                  'reactant or product')
        ichs = list(map(lambda name: spc_dct[name]['ich'], names))
        chgs = list(map(lambda name: spc_dct[name]['chg'], names))
        muls = list(map(lambda name: spc_dct[name]['mul'], names))

        # theory
        prog = thy_info[0]
        method = thy_info[1]
        _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(prog, method)

        geos = [(), ()]
        ntaudof = 0.
        for i, (nam, ich, chg, mul) in enumerate(zip(names, ichs, chgs, muls)):
            spc_info = [ich, chg, mul]
            orb_restr = fsorb.orbital_restriction(spc_info, ini_thy_info)
            ini_thy_level = ini_thy_info[0:3]
            ini_thy_level.append(orb_restr)
            orb_restr = fsorb.orbital_restriction(spc_info, thy_info)
            thy_level = thy_info[0:3]
            thy_level.append(orb_restr)
            spc_run_fs = autofile.fs.species(run_prefix)
            spc_run_fs.leaf.create(spc_info)
            spc_run_path = spc_run_fs.leaf.path(spc_info)
            spc_save_fs = autofile.fs.species(save_prefix)
            spc_save_fs.leaf.create(spc_info)
            spc_save_path = spc_save_fs.leaf.path(spc_info)

            thy_run_fs = autofile.fs.theory(spc_run_path)
            thy_run_fs.leaf.create(thy_level[1:4])
            thy_run_path = thy_run_fs.leaf.path(thy_level[1:4])
            thy_save_fs = autofile.fs.theory(spc_save_path)
            thy_save_fs.leaf.create(thy_level[1:4])
            thy_save_path = thy_save_fs.leaf.path(thy_level[1:4])
            run_fs = autofile.fs.run(thy_run_path)

            ini_thy_save_fs = autofile.fs.theory(spc_save_path)
            ini_thy_save_fs.leaf.create(ini_thy_level[1:4])

            cnf_run_fs = autofile.fs.conformer(thy_run_path)
            cnf_save_fs = autofile.fs.conformer(thy_save_path)

            ini_filesys = [None, ini_thy_save_fs]
            filesys = [
                spc_run_fs, spc_save_fs, thy_run_fs, thy_save_fs, cnf_run_fs,
                cnf_save_fs, None, None, None, None, run_fs
            ]
            geo = geom.reference_geometry(
                spc_dct[nam],
                thy_level,
                ini_thy_level,
                filesys,
                ini_filesys,
                kickoff_size=kickoff_size,
                kickoff_backward=kickoff_backward,
                projrot_script_str=projrot_script_str,
                overwrite=overwrite)
            geos[i] = geo
            gra = automol.geom.graph(geo)
            ntaudof += len(
                automol.graph.rotational_bond_keys(gra, with_h_rotors=False))
        nsamp = util.nsamp_init(nsamp_par, ntaudof)
        geo1, geo2 = geos
        geo1 = automol.geom.mass_centered(geo1)
        geo2 = automol.geom.mass_centered(geo2)
        min_ene = 0.
        for idx in range(int(nsamp)):
            print('Optimizing vdw geometry {}/{}'.format(idx + 1, nsamp))
            angs1 = numpy.multiply(numpy.random.rand(3),
                                   [1 * numpy.pi, 2 * numpy.pi, 2 * numpy.pi])
            angs2 = numpy.multiply(numpy.random.rand(3),
                                   [1 * numpy.pi, 2 * numpy.pi, 2 * numpy.pi])
            angs12 = numpy.multiply(numpy.random.rand(2),
                                    [1 * numpy.pi, 2 * numpy.pi])
            geo1 = automol.geom.euler_rotated(geo1, *angs1)
            geo2 = automol.geom.euler_rotated(geo2, *angs2)
            dist_cutoff = 3.0 * phycon.ANG2BOHR

            geo = automol.geom.join(geo1, geo2, dist_cutoff, *angs12)
            print("Species: {}".format('+'.join(names)))
            print('vdw starting geometry')
            print(automol.geom.xyz_string(geo))

            # Set up the filesystem
            ich = automol.inchi.recalculate(automol.inchi.join(ichs))
            chg = sum(chgs)
            mul = ts_mul
            spc_info = (ich, chg, mul)
            spc_run_fs = autofile.fs.species(run_prefix)
            spc_run_fs.leaf.create(spc_info)
            spc_run_path = spc_run_fs.leaf.path(spc_info)
            spc_save_fs = autofile.fs.species(save_prefix)
            spc_save_fs.leaf.create(spc_info)
            spc_save_path = spc_save_fs.leaf.path(spc_info)
            orb_restr = fsorb.orbital_restriction(spc_info, thy_info)
            thy_level = thy_info[0:3]
            thy_level.append(orb_restr)
            thy_run_fs = autofile.fs.theory(spc_run_path)
            thy_run_fs.leaf.create(thy_level[1:4])
            thy_run_path = thy_run_fs.leaf.path(thy_level[1:4])
            thy_save_fs = autofile.fs.theory(spc_save_path)
            thy_save_fs.leaf.create(thy_level[1:4])
            thy_save_path = thy_save_fs.leaf.path(thy_level[1:4])
            run_fs = autofile.fs.run(thy_run_path)

            # Generate reference geometry
            # Generate the z-matrix and sampling ranges
            driver.run_job(
                job=elstruct.Job.OPTIMIZATION,
                geom=geo,
                spc_info=spc_info,
                thy_level=thy_level,
                run_fs=run_fs,
                script_str=opt_script_str,
                overwrite=overwrite,
                **opt_kwargs,
            )

            # Save info for the initial geometry (from ichi or fsave dir)
            ret = driver.read_job(job=elstruct.Job.OPTIMIZATION, run_fs=run_fs)
            if ret:
                print('Saving reference geometry')
                print(" - Save path: {}".format(thy_save_path))

                inf_obj, inp_str, out_str = ret
                prog = inf_obj.prog
                method = inf_obj.method
                geo = elstruct.reader.opt_geometry(prog, out_str)
                print('vdw ending geometry')
                print(automol.geom.xyz_string(geo))
                thy_save_fs.leaf.file.geometry.write(geo, thy_level[1:4])
                ene = elstruct.reader.energy(prog, method, out_str)
                if ene < min_ene:
                    min_ene = ene
                    print('ene test in vdw')
                    print(ene)
                    thy_save_fs.leaf.file.energy.write(ene, thy_level[1:4])
                    print('Saving reference geometry')
                    print(" - Save path: {}".format(thy_save_path))
                    vdw_name = label + ts_name.replace('ts', 'vdw')
                    spc_dct[vdw_name] = spc_dct[ts_name].copy()
                    spc_dct[vdw_name]['ich'] = ich
                    spc_dct[vdw_name]['mul'] = mul
                    spc_dct[vdw_name]['chg'] = chg
                    spc_dct[vdw_name]['dist_info'][1] = dist_cutoff

                    # Make a fake conformer
                    cnf_save_fs = autofile.fs.conformer(thy_save_path)
                    cnf_run_fs = autofile.fs.conformer(thy_run_path)
                    cnf_save_fs.trunk.create()
                    cnf_run_fs.trunk.create()
                    tors_range_dct = {}
                    cinf_obj = autofile.system.info.conformer_trunk(
                        0, tors_range_dct)
                    cinf_obj.nsamp = 1
                    cnf_save_fs.trunk.file.info.write(cinf_obj)
                    locs_lst = cnf_save_fs.leaf.existing()
                    if not locs_lst:
                        cid = autofile.system.generate_new_conformer_id()
                        locs = [cid]
                    else:
                        locs = locs_lst[0]
                    cnf_save_fs.leaf.create(locs)
                    cnf_run_fs.leaf.create(locs)
                    cnf_save_fs.leaf.file.geometry_info.write(inf_obj, locs)
                    cnf_save_fs.leaf.file.geometry_input.write(inp_str, locs)
                    cnf_save_fs.leaf.file.energy.write(ene, locs)
                    cnf_save_fs.leaf.file.geometry.write(geo, locs)
        if min_ene:
            new_vdws.append(vdw_name)

    return new_vdws