예제 #1
0
def build_locops(mol_frag, mol_env, ints, core1PDM_loc, Kcoeff = 1.0, Ne_core=0):

    t0 = tools.time0()

    locKin = ints.frag_kin_loc()

    locVnuc1 = ints.frag_vnuc_loc(mol_frag)
    locVnuc2 = ints.frag_vnuc_loc(mol_env)

#    locVnuc_bound1 = 0.0
#    locVnuc_bound2 = 0.0

    locCoreJK = 0.0
    if(Ne_core>0):
        locCoreJK = ints.coreJK_loc(core1PDM_loc, Kcoeff)

    locTEI = ints.tei_loc()

    ops = {"locKin":locKin}
    ops["locVnuc1"] = locVnuc1
    ops["locVnuc2"] = locVnuc2
#    ops["locVnuc_bound1"] = locVnuc_bound1
#    ops["locVnuc_bound2"] = locVnuc_bound2
    ops["locCoreJK"] = locCoreJK
    ops["locTEI"] = locTEI

    tools.timer("libgen.ops.build_locops",t0)

    return ops
예제 #2
0
def get_vxc(ks, mol, dm, n_core_elec=0.0, hermi=1):

    t0 = tools.time0()

    ground_state = (isinstance(dm, np.ndarray) and dm.ndim == 2)
    if (not ground_state):
        raise Exception("fatal error")

    if ks.grids.coords is None:
        ks.grids.build(with_non0tab=True)
        if ks.small_rho_cutoff > 1e-20 and ground_state:
            # Filter grids the first time setup grids
            #t0 = (time.clock(), time.time())
            ks.grids = prune_small_rho_grids_(ks,
                                              mol,
                                              dm,
                                              ks.grids,
                                              n_core_elec=n_core_elec)
            #t1 = tools.timer("prune grid",t0)

    if hermi == 2:  # because rho = 0
        n, exc, vxc = 0, 0, 0
    else:
        n, exc, vxc = ks._numint.nr_rks(mol, ks.grids, ks.xc, dm, hermi=hermi)

    hyb = ks._numint.hybrid_coeff(ks.xc, spin=mol.spin)

    t1 = tools.timer("vxc construction", t0)

    return n, exc, vxc, hyb
예제 #3
0
def build_subops(impAtom, mol_frag, mol_env, boundary_atoms1, boundary_atoms2, ints, loc2sub, core1PDM_loc, dim, Kcoeff = 1.0, Ne_core=0):

    t0 = tools.time0()

    subKin = frag_kin_sub( ints, loc2sub, dim )
    #subVnuc1 = frag_vnuc_sub( ints, impAtom, loc2sub, dim)
    #subVnuc2 = frag_vnuc_sub( ints, 1-impAtom, loc2sub, dim )

    subVnuc1 = frag_vnuc_sub(mol_frag, ints, loc2sub, dim)
    subVnuc2 = frag_vnuc_sub(mol_env, ints, loc2sub, dim)

    subVnuc_bound1 = 0.0
    subVnuc_bound2 = 0.0
    if(boundary_atoms1 is not None):
        subVnuc_bound1 += ints.bound_vnuc_sub(boundary_atoms1, loc2sub, dim )
    if(boundary_atoms2 is not None):
        subVnuc_bound2 += ints.bound_vnuc_sub(boundary_atoms2, loc2sub, dim )


    #tools.MatPrint(subVnuc_bound1,"subVnuc_bound1")
    #tools.MatPrint(subVnuc_bound2,"subVnuc_bound2")

    subCoreJK = coreJK_sub( ints, loc2sub, dim, core1PDM_loc, Ne_core, Kcoeff )
    subTEI = ints.tei_sub( loc2sub, dim )

    ops = {"subKin":subKin}
    ops["subVnuc1"] = subVnuc1
    ops["subVnuc2"] = subVnuc2
    ops["subVnuc_bound1"] = subVnuc_bound1
    ops["subVnuc_bound2"] = subVnuc_bound2
    ops["subCoreJK"] = subCoreJK
    ops["subTEI"] = subTEI

    tools.timer("libgen.ops.build_subops",t0)
    return ops
예제 #4
0
def coreJK_sub(ints, loc2sub, numActive, coreDMloc, Ne_core, Kcoeff = 1.0):

    t0 = tools.time0()
    sub_coreJK = None
    if(Ne_core == 0):
        sub_coreJK = 0.0        
    else:
        loc_coreJK = ints.coreJK_loc(coreDMloc, Kcoeff)
        sub_coreJK = tools.op_loc2sub(loc_coreJK, loc2sub[:,:numActive])

    t1 = tools.timer("coreJK_sub",t0)
    return sub_coreJK
예제 #5
0
    def oep_calc_diffP_derivative(self, x, dim, Ne_frag, Ne_env, P_ref, ops):

        t0 = tools.time0()
        size = dim * (dim + 1) // 2

        hess_frag = oep_calc_dPdV(self.frag_mo[:, :-1], self.frag_mo[:, -1],
                                  size, self.Ne_frag // 2, dim)
        hess_env = oep_calc_dPdV(self.env_mo[:, :-1], self.env_mo[:, -1], size,
                                 self.Ne_env // 2, dim)

        t1 = tools.timer("hessian", t0)
        return hess_frag + hess_env
예제 #6
0
def oep_hess(jCa,
             orb_Ea,
             size,
             NOrb,
             NAlpha=None,
             mo_occ=None,
             smear=0.0,
             sym_tab=None):

    mo_coeff = np.reshape(jCa, (NOrb * NOrb), 'F')
    hess = np.ndarray((size, size), dtype=float, order='F')
    nthread = lib.num_threads()
    e_tol = 1e-4
    occ_tol = 1e-8  #this should be small enough?

    t0 = tools.time0()

    if smear < 1e-8:
        if NAlpha is None:
            raise ValueError("NAlpha has to be set")

        libhess.calc_hess_dm_fast(hess.ctypes.data_as(ctypes.c_void_p), \
                              mo_coeff.ctypes.data_as(ctypes.c_void_p), orb_Ea.ctypes.data_as(ctypes.c_void_p), \
                              ctypes.c_int(size), ctypes.c_int(NOrb), ctypes.c_int(NAlpha), ctypes.c_int(nthread))
    else:
        if mo_occ is None:
            raise ValueError("mo_occ has to be set")

        libhess.calc_hess_dm_fast_frac(hess.ctypes.data_as(ctypes.c_void_p), \
                              mo_coeff.ctypes.data_as(ctypes.c_void_p), orb_Ea.ctypes.data_as(ctypes.c_void_p), \
                              mo_occ.ctypes.data_as(ctypes.c_void_p),\
                              ctypes.c_int(size), ctypes.c_int(NOrb), ctypes.c_int(nthread),\
                              ctypes.c_double(smear), ctypes.c_double(e_tol), ctypes.c_double(occ_tol))

    #tools.MatPrint(hess,"hess")
    t1 = tools.timer("hessian construction", t0)

    #if sym_tab is not None:
    #    return symmtrize_hess(hess,sym_tab,size)

    return hess
예제 #7
0
    def oep_loop(self, umat0, do_leastsq=False):
        '''
        oep with split loops
        '''

        t0 = tools.time0()

        params = self.params
        gtol0 = copy.copy(params.options["gtol"])
        gtol_min = 1e6
        dim = self.dim

        threshold = params.diffP_tol
        maxit = params.outer_maxit
        it = 0
        umat = copy.copy(umat0)
        while it < maxit:
            it += 1
            print(" OEP iteration ", it)

            P_imp_old = copy.copy(self.P_imp)
            P_bath_old = copy.copy(self.P_bath)

            diffP = (self.P_imp + self.P_bath - self.P_ref)
            gtol = np.amax(np.absolute(diffP))
            gtol_min = min(gtol, gtol_min)
            self.params.options["gtol"] = max(gtol_min / 5.0,
                                              gtol0)  #gradually reduce gtol
            '''
            if self.use_suborb and it ==1:
                gtol_min = 0.25 #hack
                self.params.options["gtol"] = max(gtol_min/5.0, gtol0)
            '''

            if do_leastsq:
                umat = self.oep_leastsq(umat,
                                        nonscf=True,
                                        dm0_frag=P_imp_old,
                                        dm0_env=P_bath_old)
            else:
                umat = self.oep_old(umat,
                                    nonscf=True,
                                    dm0_frag=P_imp_old,
                                    dm0_env=P_bath_old)

            if self.use_suborb:
                #sdmfet
                ao2sub = self.ao2sub[:, :dim]
                scf_args_frag = {'mol':self.mol_frag, 'Ne':self.Ne_frag, 'Norb':dim, 'method':self.mf_method,\
                                 'vext_1e':umat, 'oei':self.oei_frag, 'vhxc':self.vhxc_frag, 'tei':self.tei, 'dm0':P_imp_old, 'coredm':0.0, \
                                 'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle}
                mf_frag = qcwrap.qc_scf(True, nonscf=True, **scf_args_frag)
                mf_frag.kernel()
                self.P_imp = mf_frag.rdm1

                scf_args_env  = {'mol':self.mol_env, 'Ne':self.Ne_env, 'Norb':dim, 'method':self.mf_method,\
                                 'vext_1e':umat, 'oei':self.oei_env, 'vhxc':self.vhxc_env, 'tei':self.tei, 'dm0':P_bath_old, 'coredm':self.core1PDM_ao, \
                                 'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle}
                mf_env = qcwrap.qc_scf(True, nonscf=True, **scf_args_env)
                mf_env.kernel()
                self.P_bath = mf_env.rdm1
            else:
                #dmfet
                scf_args_frag = {'mol':self.mol_frag, 'xc_func':self.mf_method, 'dm0':P_imp_old, \
                                 'vext_1e':umat, 'extra_oei':self.vnuc_bound_frag_ao, 'smear_sigma':self.smear_sigma,\
                                 'max_cycle':self.scf_max_cycle}
                mf_frag = qcwrap.qc_scf(False, nonscf=True, **scf_args_frag)
                mf_frag.kernel()
                self.P_imp = mf_frag.rdm1

                scf_args_env  = {'mol':self.mol_env, 'xc_func':self.mf_method, 'dm0':P_bath_old, \
                                 'vext_1e':umat, 'extra_oei':self.vnuc_bound_env_ao, 'smear_sigma':self.smear_sigma,\
                                 'max_cycle':self.scf_max_cycle}
                mf_env = qcwrap.qc_scf(False, nonscf=True, **scf_args_env)
                mf_env.kernel()
                self.P_bath = mf_env.rdm1

            gmax_imp = tools.mat_diff_max(self.P_imp, P_imp_old)
            gmax_bath = tools.mat_diff_max(self.P_bath, P_bath_old)
            print("diffP_max_imp, diffP_max_bath ")
            print(gmax_imp, gmax_bath)

            del (P_imp_old)
            del (P_bath_old)

            #convergence check
            if gmax_imp < threshold and gmax_bath < threshold:
                print("embedding potential optimization converged")
                break
            if it == maxit:
                print(
                    "STOP: embedding potential optimization exceeds max No. of iterations"
                )

        t1 = tools.timer("embedding potential optimization (split loops)", t0)

        self.params.options["gtol"] = gtol0

        return umat
예제 #8
0
    def oep_old(self, umat0, nonscf=False, dm0_frag=None, dm0_env=None):
        '''
        Extended Wu-Yang method
        JCP, 134, 154110 (2011)
        '''

        t0 = tools.time0()

        params = self.params
        print("gtol = ", params.options["gtol"])
        dim = self.dim
        sym_tab = self.sym_tab

        x0 = self.v2m(umat0, dim, False, sym_tab)
        func = ObjFunc_WuYang
        scf_solver = qcwrap.qc_scf

        if self.use_suborb:
            #sdmfet
            ao2sub = self.ao2sub[:, :dim]

            scf_args_frag = {'mol':self.mol_frag, 'Ne':self.Ne_frag, 'Norb':dim, 'method':self.mf_method,\
                             'oei':self.oei_frag, 'tei':self.tei, 'dm0':dm0_frag, 'coredm':0.0, \
                             'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle}

            scf_args_env  = {'mol':self.mol_env, 'Ne':self.Ne_env, 'Norb':dim, 'method':self.mf_method,\
                             'oei':self.oei_env, 'tei':self.tei, 'dm0':dm0_env, 'coredm':self.core1PDM_ao, \
                             'ao2sub':ao2sub, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle}

            if nonscf:  #hack to compute vhxc here
                from pydmfet.qcwrap.pyscf_rks_nonscf import rks_nonscf
                mf_frag = rks_nonscf(self.Ne_frag, dim, self.mf_method.lower(), mol=self.mol_frag,\
                                     oei=self.oei_frag,tei=self.tei,dm0=dm0_frag,coredm=0.0,\
                                     ao2sub=ao2sub,smear_sigma=self.smear_sigma,max_cycle=self.scf_max_cycle)
                self.vhxc_frag = copy.copy(mf_frag.vhxc)
                scf_args_frag.update({'vhxc': self.vhxc_frag})

                mf_env = rks_nonscf(self.Ne_env, dim, self.mf_method.lower(), mol=self.mol_env,\
                                     oei=self.oei_env,tei=self.tei,dm0=dm0_env,coredm=self.core1PDM_ao,\
                                     ao2sub=ao2sub,smear_sigma=self.smear_sigma,max_cycle=self.scf_max_cycle)
                self.vhxc_env = copy.copy(mf_env.vhxc)
                scf_args_env.update({'vhxc': self.vhxc_env})

        else:
            #dmfet (no frozen density)
            scf_args_frag = {'mol':self.mol_frag, 'xc_func':self.mf_method, 'dm0':dm0_frag, \
                             'extra_oei':self.vnuc_bound_frag_ao, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle}
            scf_args_env  = {'mol':self.mol_env, 'xc_func':self.mf_method, 'dm0':dm0_env, \
                             'extra_oei':self.vnuc_bound_env_ao, 'smear_sigma':self.smear_sigma, 'max_cycle':self.scf_max_cycle}

        use_hess = False
        jac = True
        hess = None
        if params.opt_method.lower().startswith(
                "trust") or params.opt_method.lower() == "newton":
            use_hess = True
            func = Memoize_Jac_Hess(ObjFunc_WuYang)
            jac = func.derivative
            hess = func.hessian

        func_args = (
            self.v2m,
            sym_tab,
            scf_solver,
            self.P_ref,
            dim,
            self.use_suborb,
            nonscf,
            scf_args_frag,
            scf_args_env,
            use_hess,
        )

        ovlp = np.eye(dim)
        if not self.use_suborb:
            ovlp = self.mol_full.intor_symmetric('int1e_ovlp')
        shift = self.v2m(ovlp, dim, False, sym_tab)
        shift = shift / np.linalg.norm(shift)

        optimizer = OEP_Optimize(params.opt_method, params.options, x0, func,
                                 func_args, jac, hess)
        x = optimizer.kernel(const_shift=shift)

        umat = self.v2m(x, dim, True, sym_tab)

        t1 = tools.timer("embedding potential optimization (extended Wu-Yang)",
                         t0)

        return umat
예제 #9
0
from pydmfet import locints, sdmfet, oep, tools
from pydmfet.qcwrap.pyscf_rks_ao import rks_ao
from pyscf import gto, scf, ao2mo
import numpy as np
from pyscf.tools import molden

t0 = tools.time0()

bas = '6-31G*'
temp = 0.005

mol = gto.Mole()
mol.atom = open('O2-C24.xyz').read()
mol.basis = bas
mol.charge = 0
mol.build(max_memory=24000, verbose=4)

dm_guess = None
_, _, mo_coeff, mo_occ, _, _ = molden.load("MO_pbe.molden")
dm_guess = np.dot(mo_coeff * mo_occ, mo_coeff.T)

mf = rks_ao(mol, smear_sigma=temp)
mf.xc = "pbe,pbe"
mf.max_cycle = 50
mf.scf(dm0=dm_guess)

myInts = locints.LocalIntegrals(mf, range(mol.nao_nr()), 'meta_lowdin')

natoms = mol.natm
impAtom = np.zeros([natoms], dtype=int)
for i in range(8):