예제 #1
0
def _scan_sp(ts_info, coord_name, vscnlvl_scn_run_fs, vscnlvl_scn_save_fs,
             mod_var_sp1_thy_info, overwrite, cas_kwargs):
    """ get sps for the scan; cas options and gen lines should be same
    """

    # Set up script and kwargs for the irc run
    script_str, _, sp_kwargs, _ = qchem_params(*mod_var_sp1_thy_info[0:2])
    sp_kwargs.update(cas_kwargs)

    # Compute the single-point energies along the scan
    for locs in vscnlvl_scn_save_fs[-1].existing([[coord_name]]):

        # Set up single point filesys
        vscnlvl_scn_run_fs[-1].create(locs)
        geo_run_path = vscnlvl_scn_run_fs[-1].path(locs)
        geo_save_path = vscnlvl_scn_save_fs[-1].path(locs)
        geo = vscnlvl_scn_save_fs[-1].file.geometry.read(locs)
        zma = vscnlvl_scn_save_fs[-1].file.zmatrix.read(locs)

        # Run the energy
        sp.run_energy(zma,
                      geo,
                      ts_info,
                      mod_var_sp1_thy_info,
                      vscnlvl_scn_save_fs,
                      geo_run_path,
                      geo_save_path,
                      locs,
                      script_str,
                      overwrite,
                      highspin=False,
                      **sp_kwargs)
예제 #2
0
파일: _vtst.py 프로젝트: sjklipp/mechdriver
def _vtst_hess_ene(ts_info, coord_name, mod_thy_info, mod_vsp1_thy_info,
                   scn_save_fs, scn_run_fs, overwrite, **cas_kwargs):
    """ VTST Hessians and Energies
    """

    scn_locs = scn_save_fs[-1].existing([coord_name])

    ioprinter.running('Hessians and Gradients and Energies...', newline=1)
    hess_script_str, _, hess_kwargs, _ = qchem_params(*mod_thy_info[0:2])
    hess_kwargs.update(cas_kwargs)
    script_str, _, ene_kwargs, _ = qchem_params(*mod_vsp1_thy_info[0:2])
    ene_kwargs.update(cas_kwargs)
    for locs in scn_locs:
        geo_run_path = scn_run_fs[-1].path(locs)
        geo_save_path = scn_save_fs[-1].path(locs)
        scn_run_fs[-1].create(locs)
        zma, geo = filesys.inf.cnf_fs_zma_geo(scn_save_fs, locs)
        sp.run_hessian(zma, geo, ts_info, mod_thy_info, scn_save_fs,
                       geo_run_path, geo_save_path, locs, hess_script_str,
                       overwrite, **hess_kwargs)
        sp.run_gradient(zma, geo, ts_info, mod_thy_info, scn_save_fs,
                        geo_run_path, geo_save_path, locs, hess_script_str,
                        overwrite, **hess_kwargs)
        sp.run_energy(zma, geo, ts_info, mod_vsp1_thy_info, scn_save_fs,
                      geo_run_path, geo_save_path, locs, script_str, overwrite,
                      **ene_kwargs)
예제 #3
0
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
예제 #4
0
def _multiref_inf_sep_ene(hs_info,
                          ref_zma,
                          rct_info,
                          rcts_cnf_fs,
                          run_prefix,
                          thy_info,
                          var_scn_thy_info,
                          var_sp1_thy_info,
                          var_sp2_thy_info,
                          hs_var_sp1_thy_info,
                          hs_var_sp2_thy_info,
                          var_sp1_method_dct,
                          var_sp2_method_dct,
                          scn_run_fs,
                          scn_save_fs,
                          inf_locs,
                          overwrite=False,
                          **cas_kwargs):
    """ Obtain the electronic energy for a set of reactants at infinite
        separation for a multi-reference electronic structure method.

        Since multireference methods are not size-consistent, we cannot
        sum the electronic energies of the two reactants from individual
        calculations. One could determine this energy by calculating the
        it where the two reactants are in the same input but the intermolecular
        distance is set arbitrarily large; unfortunately, this leads to
        convergence issues.

        To resulve this, the following approach is used:
        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
        scn = thy for optimizations
        sp1 = low-spin single points
        sp2 = high-spin single points for inf sep

        inf = spc0 + spc1 - hs_sr_e + hs_mr_ene
    """

    # Set groups for loops
    hs_thy_infs = (hs_var_sp2_thy_info, hs_var_sp1_thy_info)
    thy_infs = (var_sp2_thy_info, var_sp1_thy_info)
    method_dcts = (var_sp2_method_dct, var_sp1_method_dct)

    # Calculate the energies for the two cases
    for idx, (meth_dct, thy_inf) in enumerate(zip(method_dcts, hs_thy_infs)):

        if idx == 0:
            ioprinter.info_message(
                " - Running high-spin single reference energy ...")
        else:
            ioprinter.info_message(
                " - Running high-spin multi reference energy ...")

        ioprinter.info_message(' - Method:',
                               tinfo.string(var_scn_thy_info, thy_inf))

        # Calculate the single point energy
        script_str, kwargs = qchem_params(meth_dct)
        cas_kwargs.update(kwargs)

        geo = scn_save_fs[-1].file.geometry.read(inf_locs)
        zma = scn_save_fs[-1].file.zmatrix.read(inf_locs)

        # geo = automol.zmat.geometry(ref_zma)
        sp.run_energy(zma,
                      geo,
                      hs_info,
                      thy_inf,
                      scn_run_fs,
                      scn_save_fs,
                      inf_locs,
                      run_prefix,
                      script_str,
                      overwrite,
                      highspin=True,
                      **cas_kwargs)

        # Read the energty from the filesystem
        geo_save_path = scn_save_fs[-1].path(inf_locs)
        hs_save_fs = autofile.fs.high_spin(geo_save_path)
        if not hs_save_fs[-1].file.energy.exists(thy_inf[1:4]):
            ioprinter.error_message(
                'High-spin energy job failed: ',
                'energy is needed to evaluate infinite separation energy')
            ene = None
        else:
            ene = hs_save_fs[-1].file.energy.read(thy_inf[1:4])

        if idx == 0:
            hs_sr_ene = ene
        else:
            hs_mr_ene = ene

    # Get the single reference energy for each of the reactant configurations
    ioprinter.info_message('')
    ioprinter.info_message(
        'Running single-point calculations for reactants (need DFT)...')
    ioprinter.info_message('Method:', tinfo.string(thy_info, var_sp2_thy_info))
    sp_script_str, kwargs = qchem_params(var_sp2_method_dct)
    reac_ene = _reac_sep_ene(rct_info, var_sp2_thy_info, rcts_cnf_fs,
                             run_prefix, overwrite, sp_script_str, **kwargs)

    # Calculate the infinite seperation energy
    all_enes = (reac_ene, hs_sr_ene, hs_mr_ene)
    if all(ene is not None for ene in all_enes):
        _inf_sep_ene = reac_ene - hs_sr_ene + hs_mr_ene
        ioprinter.info_message('Infinite Separation Energy [au]: '
                               f'{_inf_sep_ene}')
    else:
        _inf_sep_ene = None

    print('inf ene components')
    print('reac', reac_ene)
    print('hs sr', hs_sr_ene)
    print('hs mr', hs_mr_ene)

    return _inf_sep_ene
예제 #5
0
def _run_potentials(ts_info, scan_inf_dct,
                    thy_inf_dct, thy_method_dct, mref_params,
                    es_keyword_dct, runfs_dct, savefs_dct):
    """ Run and save the scan along both grids while
          (1) optimization: constraining only reaction coordinate, then
          (2) optimization: constraining all intermolecular coordinates
          (3) single-point energy on scan (1)
    """

    # Get fs and method objects
    scn_run_fs = runfs_dct['vscnlvl_scn']
    scn_save_fs = savefs_dct['vscnlvl_scn']
    cscn_run_fs = runfs_dct['vscnlvl_cscn']
    cscn_save_fs = savefs_dct['vscnlvl_cscn']
    sp_scn_save_fs = savefs_dct['vscnlvl_scn']
    scn_thy_info = thy_inf_dct['mod_var_scnlvl']
    sp_thy_info = thy_inf_dct['mod_var_splvl1']

    opt_script_str, opt_kwargs = qchem_params(
        thy_method_dct['var_scnlvl'], elstruct.Job.OPTIMIZATION)
    cas_kwargs = mref_params['var_scnlvl']
    opt_kwargs.update(cas_kwargs)

    sp_script_str, sp_kwargs = qchem_params(
        thy_method_dct['var_splvl1'])
    sp_cas_kwargs = mref_params['var_splvl1']
    sp_kwargs.update(sp_cas_kwargs)

    # Run optimization scans
    for constraints in (None, scan_inf_dct['constraint_dct']):
        if constraints is None:
            _run_fs = scn_run_fs
            _save_fs = scn_save_fs
            info_message('Running full scans..', newline=1)
        else:
            _run_fs = cscn_run_fs
            _save_fs = cscn_save_fs
            info_message('Running constrained scans..', newline=1)

        thy_inf_str = tinfo.string(scn_thy_info)
        info_message('Method:', tinfo.string(scn_thy_info))

        # Loop over grids (both should start at same point and go in and out)
        for grid in scan_inf_dct['coord_grids']:
            info_message(f'Grid: {grid}')
            scan.execute_scan(
                zma=scan_inf_dct['inf_sep_zma'],
                spc_info=ts_info,
                mod_thy_info=thy_inf_dct['mod_var_scnlvl'],
                coord_names=scan_inf_dct['coord_names'],
                coord_grids=(grid,),
                scn_run_fs=_run_fs,
                scn_save_fs=_save_fs,
                scn_typ='relaxed',
                script_str=opt_script_str,
                overwrite=es_keyword_dct['overwrite'],
                update_guess=scan_inf_dct['update_guess'],
                reverse_sweep=False,
                saddle=False,
                constraint_dct=constraints,
                retryfail=True,
                **cas_kwargs
            )
            info_message('')

    # Run the single points on top of the initial, full scan
    if sp_thy_info is not None:
        info_message('')
        info_message('Running single-point calculations on the full scan...')
        info_message('Method:', tinfo.string(scn_thy_info, sp_thy_info))
        for locs in scn_save_fs[-1].existing((scan_inf_dct['coord_names'],)):
            scn_run_fs[-1].create(locs)
            geo = scn_save_fs[-1].file.geometry.read(locs)
            zma = scn_save_fs[-1].file.zmatrix.read(locs)
            sp.run_energy(zma, geo, ts_info, sp_thy_info,
                          scn_run_fs, scn_save_fs, locs, runfs_dct['prefix'],
                          sp_script_str, es_keyword_dct['overwrite'],
                          highspin=False, **sp_kwargs)