示例#1
0
def single_conformer(spc_info,
                     thy_level,
                     filesys,
                     overwrite,
                     saddle=False,
                     dist_info=()):
    """ generate single optimized geometry for
        randomly sampled initial torsional angles
    """
    mc_nsamp = [False, 0, 0, 0, 0, 1]
    sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_level[0:2])
    thy_save_fs = filesys[3]
    two_stage = False
    if saddle:
        two_stage = True
    conformer_sampling(
        spc_info=spc_info,
        thy_level=thy_level,
        thy_save_fs=thy_save_fs,
        cnf_run_fs=filesys[4],
        cnf_save_fs=filesys[5],
        script_str=sp_script_str,
        overwrite=overwrite,
        nsamp_par=mc_nsamp,
        saddle=saddle,
        dist_info=dist_info,
        two_stage=two_stage,
        **kwargs,
    )
示例#2
0
def geometry_analysis(tsk,
                      thy_level,
                      ini_filesys,
                      spc,
                      overwrite,
                      saddle=False,
                      selection='min'):
    """ run the specified electronic structure task
    for a set of geometries
    """
    params = {}
    spc_info = finf.get_spc_info(spc)

    print('Task:', tsk)
    if 'conf' in tsk:
        run_dir = ini_filesys[2]
        save_dir = ini_filesys[3]
    elif 'tau' in tsk:
        run_dir = ini_filesys[4]
        save_dir = ini_filesys[5]
    elif 'hr' in tsk:
        run_dir = ini_filesys[6]
        save_dir = ini_filesys[7]
        if saddle:
            params['frm_bnd_key'] = spc['frm_bnd_key']
            params['brk_bnd_key'] = spc['brk_bnd_key']
            print('key test in ts_geom anal:', params['frm_bnd_key'],
                  params['brk_bnd_key'])
    else:
        return
    if isinstance(selection, str):
        if selection == 'all':
            locs_lst = save_dir.leaf.existing()
        elif selection == 'min':
            locs_lst = [fsmin.min_energy_conformer_locators(save_dir)]
    else:
        locs_lst = selection

    sp_script_str, _, kwargs, _ = runpar.run_qchem_par(*thy_level[0:2])
    params['spc_info'] = spc_info
    params['thy_level'] = thy_level
    params['script_str'] = sp_script_str
    params['overwrite'] = overwrite

    # cycle over the locations
    if tsk in ES_TSKS:
        task_call = eval(ES_TSKS[tsk])
        for locs in locs_lst:
            if locs:
                params['geo_run_fs'] = run_dir
                params['geo_save_fs'] = save_dir
                params['locs'] = locs
                task_call(params, kwargs)
            else:
                print('No initial geometry available for {} on {}'.format(
                    spc_info[0], '/'.join(thy_level[1:3])))
示例#3
0
def remove_imag(spc_dct_i,
                geo,
                thy_level,
                thy_run_fs,
                run_fs,
                kickoff_size=0.1,
                kickoff_backward=False,
                overwrite=False):
    """ if there is an imaginary frequency displace geometry along the imaginary
    mode and then reoptimize
    """

    # projrot_script_str = script.PROJROT

    print('the initial geometries will be checked for imaginary frequencies')
    spc_info = finf.get_spc_info(spc_dct_i)
    script_str, opt_script_str, kwargs, opt_kwargs = runpar.run_qchem_par(
        *thy_level[0:2])

    imag, geo, disp_xyzs, hess = run_check_imaginary(spc_info, geo, thy_level,
                                                     thy_run_fs, script_str,
                                                     overwrite, **kwargs)
    chk_idx = 0
    while imag and chk_idx < 5:
        chk_idx += 1
        print('imaginary frequency detected, attempting to kick off')

        geo = run_kickoff_saddle(geo,
                                 disp_xyzs,
                                 spc_info,
                                 thy_level,
                                 run_fs,
                                 thy_run_fs,
                                 opt_script_str,
                                 kickoff_size,
                                 kickoff_backward,
                                 opt_cart=True,
                                 **opt_kwargs)
        print('removing saddlepoint hessian')

        thy_run_path = thy_run_fs.leaf.path(thy_level[1:4])
        run_fs = autofile.fs.run(thy_run_path)
        run_fs.leaf.remove([elstruct.Job.HESSIAN])
        imag, geo, disp_xyzs, hess = run_check_imaginary(
            spc_info, geo, thy_level, thy_run_fs, script_str, overwrite,
            **kwargs)
    return geo, hess
示例#4
0
def sadpt_reference_geometry(spcdct,
                             thy_level,
                             ini_thy_level,
                             geo_fs,
                             ini_fs,
                             dist_info=(),
                             overwrite=False):
    """ determine what to use as the reference geometry for all future runs
    If ini_thy_info refers to geometry dictionary then use that,
    otherwise values are from a hierarchy of:
    running level of theory, input level of theory, inchis.
    From the hierarchy an optimization is performed followed by a check for
    an imaginary frequency and then a conformer file system is set up.
    """

    thy_save_fs = geo_fs[3]
    ini_thy_save_fs = ini_fs[1]
    run_fs = geo_fs[-1]
    print('initializing geometry')
    geo = None
    geo_init = None
    # Check to see if geometry should be obtained from dictionary
    spc_info = [spcdct['ich'], spcdct['chg'], spcdct['mul']]
    if 'input_geom' in ini_thy_level:
        geom_obj = spcdct['geoobj']
        geo_init = geom_obj
        overwrite = True
        print('found initial geometry from geometry dictionary')
    else:
        # Check to see if geo already exists at running_theory
        if thy_save_fs.trunk.file.geometry.exists():
            thy_path = thy_save_fs.trunk.path()
            print('getting reference geometry from {}'.format(thy_path))
            geo = thy_save_fs.trunk.file.geometry.read()
            zma = thy_save_fs.trunk.file.zmatrix.read()
            # print('geo:',automol.geom.string(geo))
        if not geo:
            if ini_thy_save_fs:
                if ini_thy_save_fs.trunk.file.geometry.exists():
                    thy_path = ini_thy_save_fs.trunk.path()
                    print(
                        'getting reference geometry from {}'.format(thy_path))
                    zma_init = ini_thy_save_fs.trunk.file.zmatrix.read()
                    geo_init = ini_thy_save_fs.trunk.file.geometry.read()
    if not geo and geo_init:
        _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(
            *thy_level[0:2])
        driver.run_job(
            job='optimization',
            script_str=opt_script_str,
            run_fs=run_fs,
            geom=zma_init,
            spc_info=spc_info,
            thy_level=thy_level,
            saddle=True,
            overwrite=overwrite,
            **opt_kwargs,
        )
        opt_ret = driver.read_job(
            job='optimization',
            run_fs=run_fs,
        )
        if opt_ret is not None:
            inf_obj, _, out_str = opt_ret
            prog = inf_obj.prog
            method = inf_obj.method
            ene = elstruct.reader.energy(prog, method, out_str)
            geo = elstruct.reader.opt_geometry(prog, out_str)
            zma = elstruct.reader.opt_zmatrix(prog, out_str)
        if geo:

            print(" - Saving...")
            print(" - Save path: {}".format(thy_save_fs.trunk.path()))

            thy_save_fs.trunk.file.energy.write(ene)
            thy_save_fs.trunk.file.geometry.write(geo)
            thy_save_fs.trunk.file.zmatrix.write(zma)

            conformer.single_conformer(spc_info, thy_level, geo_fs, overwrite,
                                       True, dist_info)
    return geo
示例#5
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
示例#6
0
def geometry_generation(tsk,
                        spc,
                        mc_nsamp,
                        ini_thy_level,
                        thy_level,
                        ini_filesys,
                        filesys,
                        overwrite,
                        saddle=False,
                        kickoff=(0.1, False),
                        tors_model=('1dhr', False)):
    """ run an electronic structure task
    for generating a list of conformer or tau sampling geometries
    """
    # Separate the kickoff keyword for now
    [kickoff_size, kickoff_backward] = kickoff

    spc_info = finf.get_spc_info(spc)

    # Get a reference geometry
    if not saddle:
        geo = geom.reference_geometry(spc,
                                      thy_level,
                                      ini_thy_level,
                                      filesys,
                                      ini_filesys,
                                      kickoff_size=kickoff_size,
                                      kickoff_backward=kickoff_backward,
                                      overwrite=overwrite)
    else:
        geo = ts.sadpt_reference_geometry(spc, thy_level, ini_thy_level,
                                          filesys, ini_filesys,
                                          spc['dist_info'], overwrite)

    if geo:
        print('Task:', tsk)
        _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(
            *thy_level[0:2])
        params = {
            'spc_info': spc_info,
            'thy_level': thy_level,
            'script_str': opt_script_str,
            'overwrite': overwrite
        }
        if saddle:
            params['saddle'] = True
            params['tors_names'] = spc['tors_names']
        if tsk in ['conf_samp', 'tau_samp']:
            params['nsamp_par'] = mc_nsamp
            if saddle:
                params['dist_info'] = spc['dist_info']
                params['two_stage'] = True
                params['rxn_class'] = spc['class']
        elif tsk in ['hr_scan']:
            params['tors_model'] = tors_model
            if 'hind_def' in spc:
                params['run_tors_names'] = spc['hind_def']
            if 'hind_inc' in spc:
                params['scan_increment'] = spc['hind_inc'] * phycon.DEG2RAD
            else:
                params['scan_increment'] = 30. * phycon.DEG2RAD
            if saddle:
                params['frm_bnd_key'] = spc['frm_bnd_key']
                params['brk_bnd_key'] = spc['brk_bnd_key']
                print('key test in ts_geom gen:', params['frm_bnd_key'],
                      params['brk_bnd_key'])

        if tsk in ES_TSKS:
            eval(ES_TSKS[tsk])(filesys, params, opt_kwargs)
示例#7
0
def reference_geometry(spc_dct_i,
                       thy_level,
                       ini_thy_level,
                       filesys,
                       ini_filesys,
                       kickoff_size=0.1,
                       kickoff_backward=False,
                       overwrite=False):
    """ determine what to use as the reference geometry for all future runs
    If ini_thy_info refers to geometry dictionary then use that,
    otherwise values are from a hierarchy of:
    running level of theory, input level of theory, inchis.
    From the hierarchy an optimization is performed followed by a check for
    an imaginary frequency and then a conformer file system is set up.
    """
    # projrot_script_str = script.PROJROT
    ret = None

    thy_run_fs = filesys[2]
    thy_save_fs = filesys[3]
    ini_thy_save_fs = ini_filesys[1]
    cnf_run_fs = filesys[4]
    cnf_save_fs = filesys[5]
    run_fs = filesys[-1]
    if run_fs.trunk.file.info.exists([]):
        inf_obj = run_fs.trunk.file.info.read([])
        if inf_obj.status == autofile.system.RunStatus.RUNNING:
            print('reference geometry already running')
            return ret
    else:
        prog = thy_level[0]
        method = thy_level[1]
        basis = thy_level[2]
        status = autofile.system.RunStatus.RUNNING
        inf_obj = autofile.system.info.run(job='',
                                           prog=prog,
                                           version='version',
                                           method=method,
                                           basis=basis,
                                           status=status)
        run_fs.trunk.file.info.write(inf_obj, [])

    print('initializing geometry in reference_geometry')
    geo = None
    try:
        # Check to see if geometry should be obtained from dictionary
        spc_info = [spc_dct_i['ich'], spc_dct_i['chg'], spc_dct_i['mul']]
        if 'input_geom' in ini_thy_level:
            geom_obj = spc_dct_i['geo_obj']
            geo_init = geom_obj
            overwrite = True
            print('found initial geometry from geometry dictionary')
        else:
            # Check to see if geo already exists at running_theory
            print(thy_save_fs)
            if thy_save_fs.leaf.file.geometry.exists(thy_level[1:4]):
                thy_path = thy_save_fs.leaf.path(thy_level[1:4])
                print('getting reference geometry from {}'.format(thy_path))
                geo = thy_save_fs.leaf.file.geometry.read(thy_level[1:4])
            if not geo:
                if ini_thy_save_fs:
                    geo_exists = ini_thy_save_fs.leaf.file.geometry.exists(
                        ini_thy_level[1:4])
                    if geo_exists:
                        # If not, Compute geo at running_theory, using geo from
                        # initial_level as the starting point
                        # or from inchi is no initial level geometry
                        thy_path = ini_thy_save_fs.leaf.path(
                            ini_thy_level[1:4])
                        geo_init = ini_thy_save_fs.leaf.file.geometry.read(
                            ini_thy_level[1:4])
                    elif 'geo_obj' in spc_dct_i:
                        geo_init = spc_dct_i['geo_obj']
                        print('getting geometry from geom dictionary')
                    else:
                        print('getting reference geometry from inchi',
                              spc_info[0])
                        geo_init = automol.inchi.geometry(spc_info[0])
                        print('got reference geometry from inchi', geo_init)
                        print('getting reference geometry from inchi')
                elif 'geo_obj' in spc_dct_i:
                    geo_init = spc_dct_i['geo_obj']
                    print('getting geometry from geom dictionary')
                else:
                    geo_init = automol.inchi.geometry(spc_info[0])
                    print('getting reference geometry from inchi')
        # Optimize from initial geometry to get reference geometry
        if not geo:
            _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(
                *thy_level[0:2])
            params = {
                'spc_info': spc_info,
                'run_fs': run_fs,
                'thy_run_fs': thy_run_fs,
                'script_str': opt_script_str,
                'overwrite': overwrite,
                'thy_level': thy_level,
                'ini_geo': geo_init
            }
            geo, inf = run_initial_geometry_opt(**params, **opt_kwargs)
            thy_save_fs.leaf.create(thy_level[1:4])
            thy_save_path = thy_save_fs.leaf.path(thy_level[1:4])
            ncp = len(
                automol.graph.connected_components(automol.geom.graph(geo)))
            if not automol.geom.is_atom(geo) and ncp < 2:
                geo, hess = remove_imag(spc_dct_i,
                                        geo,
                                        thy_level,
                                        thy_run_fs,
                                        run_fs,
                                        kickoff_size,
                                        kickoff_backward,
                                        overwrite=overwrite)

                tors_names = automol.geom.zmatrix_torsion_coordinate_names(geo)
                locs_lst = cnf_save_fs.leaf.existing()
                if locs_lst:
                    saved_geo = cnf_save_fs.leaf.file.geometry.read(
                        locs_lst[0])
                    saved_tors = automol.geom.zmatrix_torsion_coordinate_names(
                        saved_geo)
                    if tors_names != saved_tors:
                        print("new reference geometry doesn't match original",
                              " reference geometry")
                        print('removing original conformer save data')
                        cnf_run_fs.remove()
                        cnf_save_fs.remove()

                print('Saving reference geometry')
                print(" - Save path: {}".format(thy_save_path))
                thy_save_fs.leaf.file.hessian.write(hess, thy_level[1:4])

            thy_save_fs.leaf.file.geometry.write(geo, thy_level[1:4])
            ncp = len(
                automol.graph.connected_components(automol.geom.graph(geo)))
            if ncp < 2:
                zma = automol.geom.zmatrix(geo)
                thy_save_fs.leaf.file.zmatrix.write(zma, thy_level[1:4])
                conformer.single_conformer(spc_info, thy_level, filesys,
                                           overwrite)
            else:
                print("Cannot create zmatrix for disconnected species")
                wells.fake_conf(thy_level, filesys, inf)

        if geo:
            inf_obj.status = autofile.system.RunStatus.SUCCESS
            run_fs.trunk.file.info.write(inf_obj, [])
        else:
            inf_obj.status = autofile.system.RunStatus.FAILURE
            run_fs.trunk.file.info.write(inf_obj, [])

    except IOError:
        inf_obj.status = autofile.system.RunStatus.FAILURE
        run_fs.trunk.file.info.write(inf_obj, [])

    return geo
示例#8
0
def run_multiref_rscan(formula,
                       high_mul,
                       zma,
                       spc_info,
                       multi_level,
                       dist_name,
                       grid1,
                       grid2,
                       scn_run_fs,
                       scn_save_fs,
                       overwrite,
                       update_guess=True,
                       gradient=False,
                       hessian=False,
                       num_act_elc=None,
                       num_act_orb=None,
                       alt_constraints=()):
    """ run constrained optimization scan
    """

    vma = automol.zmatrix.var_(zma)
    if scn_save_fs.trunk.file.vmatrix.exists():
        existing_vma = scn_save_fs.trunk.file.vmatrix.read()
        assert vma == existing_vma

    grid = numpy.append(grid1, grid2)
    grid_dct = {dist_name: grid}
    if len(grid_dct) > 1:
        raise NotImplementedError

    coo_names = []
    grid_vals = []
    for item in grid_dct.items():
        (coo, coo_grid_vals) = item
        coo_names.append(coo)
        grid_vals.append(coo_grid_vals)

    scn_save_fs.branch.create([coo_names])
    inf_obj = autofile.system.info.scan_branch(grid_dct)
    scn_save_fs.branch.file.info.write(inf_obj, [coo_names])

    prog = multi_level[0]
    method = multi_level[1]

    _, opt_script_str, _, opt_kwargs = runpar.run_qchem_par(prog, method)

    ref_zma = automol.zmatrix.set_values(zma, {coo_names[0]: grid_vals[0][0]})

    # Build the elstruct CASSCF options list for multiref calcs
    cas_opt = []
    cas_opt.append(
        variational.wfn.cas_options(spc_info,
                                    formula,
                                    num_act_elc,
                                    num_act_orb,
                                    high_mul,
                                    add_two_closed=False))
    cas_opt.append(
        variational.wfn.cas_options(spc_info,
                                    formula,
                                    num_act_elc,
                                    num_act_orb,
                                    high_mul,
                                    add_two_closed=True))

    # Write the lines containing all the calcs for a guess wfn
    guess_str = variational.wfn.multiref_wavefunction_guess(
        high_mul, ref_zma, spc_info, multi_level, cas_opt)
    guess_lines = guess_str.splitlines()

    # Add the above-built objects to the elstruct opt_kwargs dct
    opt_kwargs['casscf_options'] = cas_opt[1]
    opt_kwargs['gen_lines'] = {1: guess_lines}

    # Add option to opt_kwargs dct to turn off symmetry
    opt_kwargs['mol_options'] = ['nosym']

    # Setup and run the first part of the scan to shorter distances
    coo_names = []
    grid1_vals = []
    grid1_dct = {dist_name: grid1}
    for item in grid1_dct.items():
        (coo, coo_grid1_vals) = item
        coo_names.append(coo)
        grid1_vals.append(coo_grid1_vals)

    npoint = 1
    for coo_grid1_vals in grid1_vals:
        npoint *= len(coo_grid1_vals)
    grid1_idxs = tuple(range(npoint))
    if len(grid1_vals) == 1:
        for grid1_val in grid1_vals[0]:
            scn_run_fs.leaf.create([coo_names, [grid1_val]])
        run_prefixes = tuple(
            scn_run_fs.leaf.path([coo_names, [grid1_val]])
            for grid1_val in grid1_vals[0])

    _run_1d_scan(
        script_str=opt_script_str,
        run_prefixes=run_prefixes,
        scn_save_fs=scn_save_fs,
        guess_zma=zma,
        coo_name=coo_names[0],
        grid_idxs=grid1_idxs,
        grid_vals=grid1_vals[0],
        spc_info=spc_info,
        thy_level=multi_level,
        overwrite=overwrite,
        update_guess=update_guess,
        gradient=gradient,
        hessian=hessian,
        alt_constraints=alt_constraints,
        **opt_kwargs,
    )

    # Setup and run the second part of the scan to longer distances
    coo_names = []
    grid2_vals = []
    grid2_dct = {dist_name: grid2}
    for item in grid2_dct.items():
        (coo, coo_grid2_vals) = item
        coo_names.append(coo)
        grid2_vals.append(coo_grid2_vals)

    npoint = 1
    for coo_grid2_vals in grid2_vals:
        npoint *= len(coo_grid2_vals)
    grid2_idxs = tuple(range(npoint))
    if len(grid2_vals) == 1:
        for grid2_val in grid2_vals[0]:
            scn_run_fs.leaf.create([coo_names, [grid2_val]])
        run_prefixes = tuple(
            scn_run_fs.leaf.path([coo_names, [grid2_val]])
            for grid2_val in grid2_vals[0])
    _run_1d_scan(
        script_str=opt_script_str,
        run_prefixes=run_prefixes,
        scn_save_fs=scn_save_fs,
        guess_zma=zma,
        coo_name=coo_names[0],
        grid_idxs=grid2_idxs,
        grid_vals=grid2_vals[0],
        spc_info=spc_info,
        thy_level=multi_level,
        overwrite=overwrite,
        update_guess=update_guess,
        gradient=gradient,
        hessian=hessian,
        alt_constraints=alt_constraints,
        **opt_kwargs,
    )
示例#9
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