Пример #1
0
    def opt_umat_homo_diff(self, umat, gtol=1e-6):

        ops = self.ops
        Ne_frag = self.Ne_frag
        Ne_env = self.Ne_env
        dim = self.dim

        subTEI = ops["subTEI"]
        subOEI1 = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + umat
        subOEI2 = ops["subKin"] + ops["subVnuc2"] + ops[
            "subVnuc_bound2"] + ops["subCoreJK"] + umat

        coredm = self.core1PDM_ao
        ao2sub = self.ao2sub[:, :dim]

        #frag_coredm_guess = tools.fock2onedm(subOEI1, Ne_frag//2)[0]
        frag_coredm_guess = self.P_imp
        mf_frag = qcwrap.qc_scf(Ne_frag,dim,self.mf_method,mol=self.mol,oei=subOEI1,tei=subTEI,\
                                dm0=frag_coredm_guess,coredm=0.0,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_frag.runscf()

        #env_coredm_guess = tools.fock2onedm(subOEI2, Ne_env//2)[0]
        env_coredm_guess = self.P_bath
        mf_env = qcwrap.qc_scf(Ne_env,dim,self.mf_method,mol=self.mol,oei=subOEI2,tei=subTEI,\
                               dm0=env_coredm_guess,coredm=coredm,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_env.runscf()

        print(np.linalg.norm(mf_frag.rdm1 - self.P_imp))
        print(np.linalg.norm(mf_env.rdm1 - self.P_bath))

        diffP = mf_frag.rdm1 + mf_env.rdm1 - self.P_ref
        print("|P_frag + P_env - P_ref| = ", np.linalg.norm(diffP))
        print("max element of (P_frag + P_env - P_ref) = ",
              np.amax(np.absolute(diffP)))
        self.P_imp = mf_frag.rdm1
        self.P_bath = mf_env.rdm1

        #build null space
        vint = self.build_null_space(mf_frag, mf_env, Ne_frag, Ne_env, dim)
        if vint is None:
            return umat

        #minimize |ehomo_A-ehomo_B|^2
        x0 = tools.mat2vec(umat, dim)
        n = vint.shape[-1]
        c = np.zeros((n))
        res = self.minimize_ehomo_2(c, x0, vint, gtol)
        c = res.x
        #print '|c| = ', np.linalg.norm(c)
        for i in range(n):
            x0 += c[i] * vint[:, i]

        umat = tools.vec2mat(x0, dim)
        #xmat = xmat - np.eye( xmat.shape[ 0 ] ) * np.average( np.diag( xmat ) )

        #tools.MatPrint(umat,'umat')
        #print '|umat| = ', np.linalg.norm(umat)

        return umat
Пример #2
0
    def imp_mf_energy_dfet(self, dim):

        Ne_frag = self.Ne_frag
        ops = self.ops
        Vemb = self.umat

        Vxc = None

        subOEI = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + Vemb
        subTEI = ops["subTEI"]

        ao2sub = self.ao2sub[:, :dim]

        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           self.mf_method,
                           mol=self.mol_frag,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp,
                           coredm=0.0,
                           ao2sub=ao2sub)
        #mf.init_guess =  'minao'
        mf.runscf()
        energy = mf.elec_energy  #- np.trace(np.dot(mf.rdm1,Vemb))

        print('|diffP| = ',
              np.linalg.norm(mf.rdm1 + self.P_bath - self.P_ref_sub))
        print("embeded imp scf (electron) energy = ", energy)

        self.P_imp = mf.rdm1

        return (energy, Vemb, Vxc)
Пример #3
0
    def ks_ccsd_energy(self, dim):

        print("ECW method is CCSD")
        energy = 0.0

        Ne_frag = self.Ne_frag
        ops = self.ops
        umat = self.umat

        subOEI = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + umat
        subTEI = ops["subTEI"]

        ao2sub = self.ao2sub[:, :dim]
        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           self.mf_method,
                           mol=self.mol,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp,
                           coredm=0.0,
                           ao2sub=ao2sub)
        mf.runscf()
        e_ks = mf.elec_energy
        print("e_ks = ", e_ks)

        #HF JK
        veff = self.ints.impJK_sub(mf.make_rdm1(), subTEI)
        mf.get_veff = lambda *args: veff

        print("incore_anyway: ", mf.mol.incore_anyway)

        e_emb = 0.0
        #onedm = mf.make_rdm1()
        #e_emb=np.trace(np.dot(umat,onedm))

        #print "diffP = ",np.linalg.norm(self.P_imp - onedm)

        e_hf = pyscf.scf.hf.energy_elec(mf, mf.make_rdm1(), subOEI, veff)[0]
        print("e_hf = ", e_hf)

        mycc = cc.CCSD(mf).run()
        et = 0.0
        if (self.ecw_method == 'ccsd(t)'):
            print('CCSD(T) correction')
            et = mycc.ccsd_t()

        #ccsd_dm_mo = mycc.make_rdm1()
        #ccsd_dm_sub = tools.dm_loc2ao(ccsd_dm_mo,mf.mo_coeff)
        #e_emb=np.trace(np.dot(umat,ccsd_dm_sub))

        print(mycc.e_corr + et)
        e_ccsd = e_hf + mycc.e_corr + et
        e_ccsd -= e_emb
        print(e_ccsd)

        energy = e_ccsd - e_ks

        print("dmfet correction energy = ", energy)
        return energy
Пример #4
0
    def imp_mf_energy2(self, dim):

        Ne_frag = self.Ne_frag
        ops = self.ops
        umat = self.umat

        proj = 0.5 * self.P_bath
        energy_shift = 1e5
        Vemb = umat + energy_shift * proj
        Vxc = None

        subOEI = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + Vemb
        subTEI = ops["subTEI"]

        ao2sub = self.ao2sub[:, :dim]

        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           self.mf_method,
                           mol=self.mol_frag,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp,
                           coredm=0.0,
                           ao2sub=ao2sub)
        mf.runscf()
        energy = mf.elec_energy

        print('|diffP| = ',
              np.linalg.norm(mf.rdm1 + self.P_bath - self.P_ref_sub))
        print("embeded imp scf (electron) energy = ", energy)

        self.P_imp = mf.rdm1

        return (energy, Vemb, Vxc)
Пример #5
0
    def total_scf_energy(self):

        energy = 0.0

        Norb = self.dim_sub
        Ne = self.Ne_frag + self.Ne_env
        ops = self.ops

        subOEI = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc2"] + ops[
            "subCoreJK"]
        subTEI = ops["subTEI"]

        coredm = self.core1PDM_ao
        ao2sub = self.ao2sub[:, :Norb]

        #dm_guess = tools.fock2onedm(subOEI, Ne//2)[0]
        dm_guess = self.P_ref_sub
        mf = qcwrap.qc_scf(True, mol=self.mol, Ne=Ne, Norb=Norb, method=self.mf_method, \
                           oei=subOEI, tei=subTEI, dm0=dm_guess, coredm=coredm, ao2sub=ao2sub, smear_sigma = self.smear_sigma)
        #mf.init_guess =  'minao'
        mf.kernel()

        print('max(P_tot - P_ref) = ',
              np.amax(np.absolute(mf.rdm1 - self.P_ref_sub)))
        print('|P_tot - P_ref| = ', np.linalg.norm(mf.rdm1 - self.P_ref_sub))

        self.ints.submo_molden(mf.mo_coeff, mf.mo_occ, self.loc2sub,
                               "total_system_mo.molden", self.mol)

        energy = mf.elec_energy + self.core_energy() + self.ints.energy_nuc()

        print('total scf energy = %.15g ' % energy)
        print('%.15g, %.15g, %.15g' %
              (mf.elec_energy, self.core_energy(), self.ints.energy_nuc()))
        return energy
Пример #6
0
    def debug_loc_orb(self):

        #fock = self.fock_loc()
        #eigvals, eigvecs = np.linalg.eigh(fock)
        ##eigvecs = eigvecs[ :, eigvals.argsort() ]
        #print eigvals

        oei = self.hcore_loc()
        tei = self.tei_loc()

        Ne = self.Nelec
        NOrb = self.NOrb
        mf = qcwrap.qc_scf(Ne, NOrb, 'hf', mol=self.mol, oei=oei, tei=tei)
        mf.runscf()

        #print mf.elec_energy
        mycc = cc.CCSD(mf).run()
        et = 0.0
        et = mycc.ccsd_t()
        e_hf = mf.elec_energy + self.energy_nuc()
        print(e_hf)
        print(mycc.e_corr + et)

        e_ccsd = e_hf + mycc.e_corr + et
        print('total ccsd(t) energy = ', e_ccsd)
        exit()
Пример #7
0
    def ccsd_energy_beta(self, dim):

        mol = self.mol_frag
        natm = mol.natm

        mol1 = mol.copy()
        for i in range(natm):
            if (self.deproton[i] == 1):
                mol1._atm[i][0] = 0  #make proton ghost
        print('mol_frag de:')
        print(mol1._atm)
        vnuc_sub = libgen.frag_vnuc_sub(mol1, self.ints, self.loc2sub, dim)

        print("ECW method is CCSD")
        energy = 0.0

        Ne_frag = self.Ne_frag
        ops = self.ops
        umat = self.umat

        subOEI = ops["subKin"] + vnuc_sub + ops["subVnuc_bound1"] + umat
        subTEI = ops["subTEI"]

        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           'hf',
                           mol=None,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp)
        mf.runscf()

        e_emb = 0.0
        #onedm = mf.make_rdm1()
        #e_emb=np.trace(np.dot(umat,onedm))

        #print "diffP = ",np.linalg.norm(self.P_imp - onedm)

        print(mf.elec_energy)
        mycc = cc.CCSD(mf).run()
        et = 0.0
        if (self.ecw_method == 'ccsd(t)'):
            print('CCSD(T) correction')
            et = mycc.ccsd_t()

        e_hf = mf.elec_energy
        print(mycc.e_corr + et)

        e_ccsd = e_hf + mycc.e_corr + et
        e_ccsd -= e_emb
        print(e_ccsd)

        imp_mf_energy = self.imp_mf_energy_beta(dim)

        energy = e_ccsd - imp_mf_energy

        print("dmfet correction energy = ", energy)
        return energy
Пример #8
0
    def mp2_energy(self, dim):

        print("ECW method is MP2")

        energy = 0.0

        Ne_frag = self.Ne_frag
        ops = self.ops
        umat = self.umat

        Ne_env = self.Ne_env
        P_bath_JK = libgen.coreJK_sub(
            self.ints, self.loc2sub, dim,
            tools.dm_sub2ao(self.P_bath, self.loc2sub[:, :dim]), Ne_env, 1.0)

        subOEI = ops["subKin"] + ops["subVnuc1"] + ops[
            "subVnuc2"] + P_bath_JK + 0.5 * 1e4 * self.P_bath
        #subOEI = ops["subKin"]+ops["subVnuc1"]+ops["subVnuc_bound1"]+umat
        subTEI = ops["subTEI"]

        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           'hf',
                           mol=self.mol,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp)
        mf.runscf()

        #self.ints.submo_molden( mf.mo_coeff, mf.mo_occ, self.loc2sub, 'mo_imp.molden' )
        print('|diffP| = ',
              np.linalg.norm(mf.rdm1 + self.P_bath - self.P_ref_sub))

        print("mo_energy")
        print(mf.mo_energy)

        e_emb = 0.0
        #onedm = mf.make_rdm1()
        #e_emb=np.trace(np.dot(umat,onedm))
        #print "diffP = ",np.linalg.norm(self.P_imp - onedm)

        mp2 = mp.MP2(mf)
        mp2.kernel()

        e_mp2 = mf.elec_energy + mp2.e_corr
        e_mp2 -= e_emb

        imp_mf_energy = self.imp_mf_energy(dim)

        energy = e_mp2 - imp_mf_energy

        print("dmfet correction energy = ", energy)
        return energy
Пример #9
0
    def imp_mf_energy_beta(self, dim):

        mol = self.mol_frag
        natm = mol.natm

        mol1 = mol.copy()
        for i in range(natm):
            if (self.deproton[i] == 1):
                mol1._atm[i][0] = 0  #make proton ghost

        vnuc_sub = libgen.frag_vnuc_sub(mol1, self.ints, self.loc2sub, dim)

        Ne_frag = self.Ne_frag
        ops = self.ops
        umat = self.umat

        subOEI = ops["subKin"] + vnuc_sub + ops["subVnuc_bound1"] + umat
        subTEI = ops["subTEI"]

        ao2sub = self.ao2sub[:, :dim]
        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           self.mf_method,
                           mol=self.mol,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp,
                           coredm=0.0,
                           ao2sub=ao2sub)
        mf.runscf()
        energy = mf.elec_energy

        e_emb = 0.0
        #onedm = mf.make_rdm1()
        #e_emb = np.trace(np.dot(umat,onedm))

        energy -= e_emb

        print("embeded imp scf (electron) energy = ", energy)
        return energy
Пример #10
0
    def cost_ehomo_2(self, c, x0, vint):

        x = x0.copy()

        n = len(c)
        for i in range(n):
            x += c[i] * vint[:, i]

        ops = self.ops
        Ne_frag = self.Ne_frag
        Ne_env = self.Ne_env
        dim = self.dim

        umat = tools.vec2mat(x, dim)
        subTEI = ops["subTEI"]
        subOEI1 = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"] + umat
        subOEI2 = ops["subKin"] + ops["subVnuc2"] + ops[
            "subVnuc_bound2"] + ops["subCoreJK"] + umat

        coredm = self.core1PDM_ao
        ao2sub = self.ao2sub[:, :dim]

        frag_coredm_guess = self.P_imp
        mf_frag = qcwrap.qc_scf(Ne_frag,dim,self.mf_method,mol=self.mol,oei=subOEI1,tei=subTEI,\
                                dm0=frag_coredm_guess,coredm=0.0,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_frag.runscf()

        env_coredm_guess = self.P_bath
        mf_env = qcwrap.qc_scf(Ne_env,dim,self.mf_method,mol=self.mol,oei=subOEI2,tei=subTEI,\
                               dm0=env_coredm_guess,coredm=coredm,ao2sub=ao2sub, smear_sigma = 0.0)
        mf_env.runscf()

        diffP = mf_frag.rdm1 + mf_env.rdm1 - self.P_ref
        #print "|P_frag + P_env - P_ref| = ", np.linalg.norm(diffP)
        #print "max element of (P_frag + P_env - P_ref) = ", np.amax(np.absolute(diffP) )

        ehomo_A = mf_frag.mo_energy[Ne_frag // 2 - 1]
        ehomo_B = mf_env.mo_energy[Ne_env // 2 - 1]
        delta_ehomo = ehomo_A - ehomo_B
        #print 'ehomo_A=',ehomo_A,'  ehomo_B=',ehomo_B, '  delta_ehomo=', delta_ehomo

        elumo_A = mf_frag.mo_energy[Ne_frag // 2]
        elumo_B = mf_env.mo_energy[Ne_env // 2]
        delta_elumo = elumo_A - elumo_B
        #print 'elumo_A=',elumo_A,'  elumo_B=',elumo_B, '  delta_elumo=', delta_elumo

        #objective function
        f = delta_ehomo * delta_ehomo + delta_elumo * delta_elumo  #+ (elumo_A-ehomo_A-0.3)**2

        homo_A = mf_frag.mo_coeff[:, Ne_frag // 2 - 1]
        homo_B = mf_env.mo_coeff[:, Ne_env // 2 - 1]
        lumo_A = mf_frag.mo_coeff[:, Ne_frag // 2]
        lumo_B = mf_env.mo_coeff[:, Ne_env // 2]
        #gradient
        g = np.zeros((n))
        for i in range(n):
            tmp = tools.vec2mat(vint[:, i], dim)
            EA = np.dot(homo_A, np.dot(tmp, homo_A))
            EB = np.dot(homo_B, np.dot(tmp, homo_B))
            g[i] = 2.0 * delta_ehomo * (EA - EB)

            EA = np.dot(lumo_A, np.dot(tmp, lumo_A))
            EB = np.dot(lumo_B, np.dot(tmp, lumo_B))
            g[i] += 2.0 * delta_elumo * (EA - EB)

            #EB=np.dot(homo_A,np.dot(tmp,homo_A))
            #g[i] += 2.0*(elumo_A-ehomo_A-0.3)*(EA-EB)

        return (f, g)
Пример #11
0
    def verify_scf(self, umat):
        '''
        Extra SCF calculations with final umat
        '''
        print('========================================')
        print(' SCF with converged embedding potential ')
        print('========================================')

        Ne_frag = self.Ne_frag
        Ne_env = self.Ne_env
        dim = self.dim

        dm0_frag = self.P_imp
        if self.use_suborb:
            coredm = self.core1PDM_ao
            ao2sub = self.ao2sub[:, :dim]
            mf_frag = qcwrap.qc_scf(True, mol=self.mol_frag, Ne=Ne_frag, Norb=dim, method=self.mf_method,\
                                    vext_1e=umat, 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)
        else:
            mf_frag = qcwrap.qc_scf(False, mol=self.mol_frag, xc_func=self.mf_method,\
                                    vext_1e=umat, extra_oei=self.vnuc_bound_frag_ao, \
                                    dm0=dm0_frag, smear_sigma = self.smear_sigma, max_cycle=self.scf_max_cycle)

        #mf_frag.init_guess =  'minao'
        #mf_frag.conv_check = False
        mf_frag.kernel()
        FRAG_energy = mf_frag.elec_energy
        FRAG_1RDM = mf_frag.rdm1
        frag_mo = mf_frag.mo_coeff
        frag_occ = mf_frag.mo_occ

        #mf_frag.stability(internal=True, external=False, verbose=5)

        dm0_env = self.P_bath
        if self.use_suborb:
            mf_env = qcwrap.qc_scf(True, mol=self.mol_env, Ne=Ne_env, Norb=dim, method=self.mf_method, \
                                   vext_1e=umat, oei=self.oei_env, tei=self.tei,\
                                   dm0=dm0_env, coredm=coredm, ao2sub=ao2sub, smear_sigma = self.smear_sigma,\
                                   max_cycle=self.scf_max_cycle)
        else:
            mf_env = qcwrap.qc_scf(False, mol=self.mol_env, xc_func=self.mf_method, \
                                   vext_1e=umat, extra_oei=self.vnuc_bound_env_ao, \
                                   dm0=dm0_env, smear_sigma = self.smear_sigma, max_cycle=self.scf_max_cycle)

        #mf_env.init_guess =  'minao'
        #mf_env.conv_check = False
        mf_env.kernel()
        ENV_energy = mf_env.elec_energy
        ENV_1RDM = mf_env.rdm1
        env_mo = mf_env.mo_coeff
        env_occ = mf_env.mo_occ

        print("scf energies:")
        print("EA (no vemb contrib.) = ",
              FRAG_energy - np.trace(np.dot(FRAG_1RDM, umat)))
        print("EB (no vemb contrib.) = ",
              ENV_energy - np.trace(np.dot(ENV_1RDM, umat)))
        #print np.trace(np.dot(FRAG_1RDM,umat)), np.trace(np.dot(ENV_1RDM,umat)),np.trace(np.dot(FRAG_1RDM+ENV_1RDM,umat))
        W = FRAG_energy + ENV_energy - np.trace(np.dot(self.P_ref, umat))
        print("W = ", W)
        '''
        deltaN = 0.001
        mf_frag.mo_occ[Ne_frag//2] = deltaN
        mu_A = (mf_frag.energy_tot() - FRAG_energy)/deltaN
        mf_env.mo_occ[Ne_env//2] = deltaN
        mu_B = (mf_env.energy_tot() - ENV_energy)/deltaN
        print ('mu_A = ',mu_A)
        print ('mu_B = ',mu_B)

        mf_frag.mo_occ[Ne_frag//2-1] = mf_frag.mo_occ[Ne_frag//2-1] - deltaN
        mu_A = (-mf_frag.energy_tot() + FRAG_energy)/deltaN
        mf_env.mo_occ[Ne_env//2-1] = mf_env.mo_occ[Ne_env//2-1] - deltaN
        mu_B = (-mf_env.energy_tot() + ENV_energy)/deltaN
        print ('mu_A = ',mu_A)
        print ('mu_B = ',mu_B)
        '''

        if (self.P_imp is not None):
            print("P_imp change (scf - non-scf): ",
                  tools.mat_diff_norm(FRAG_1RDM, self.P_imp))
            print("P_bath change (scf - non-scf): ",
                  tools.mat_diff_norm(ENV_1RDM, self.P_bath))
        diffP = FRAG_1RDM + ENV_1RDM - self.P_ref
        diffP_norm = np.linalg.norm(diffP)
        diffP_max = np.amax(np.absolute(diffP))
        print("|P_frag + P_env - P_ref| = ", diffP_norm)
        print("max element of (P_frag + P_env - P_ref) = ", diffP_max)

        self.frag_mo = mf_frag.mo_coeff
        self.env_mo = mf_env.mo_coeff

        print('mo orthogonality:')
        if self.use_suborb:
            ortho = np.dot(mf_frag.mo_coeff[:, :Ne_frag // 2].T,
                           mf_env.mo_coeff[:, :Ne_env // 2])
            print(ortho)
        else:
            s = self.mol_full.intor_symmetric('int1e_ovlp')
            ortho = reduce(np.dot,
                           (mf_frag.mo_coeff[:, mf_frag.mo_occ > 1e-8].T, s,
                            mf_env.mo_coeff[:, mf_env.mo_occ > 1e-8]))
            print(ortho)

        return (FRAG_1RDM, ENV_1RDM)
Пример #12
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
Пример #13
0
    def ccsd_energy(self, dim):

        print("ECW method is CCSD")
        energy = 0.0

        Ne_frag = self.Ne_frag
        ops = self.ops
        umat = self.umat

        Ne_env = self.Ne_env
        P_bath_JK = libgen.coreJK_sub(
            self.ints, self.loc2sub, dim,
            tools.dm_sub2ao(self.P_bath, self.loc2sub[:, :dim]), Ne_env, 1.0)

        subOEI = ops["subKin"] + ops["subVnuc1"] + ops[
            "subVnuc2"] + P_bath_JK + ops["subCoreJK"] + 0.5 * 1e4 * self.P_bath
        #subOEI = ops["subKin"]+ops["subVnuc1"]+ops["subVnuc_bound1"]+umat + 0.5*1e4*self.P_bath
        subTEI = ops["subTEI"]

        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           'hf',
                           mol=self.mol,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp)
        mf.runscf()

        e_emb = 0.0
        #onedm = mf.make_rdm1()
        #e_emb=np.trace(np.dot(umat,onedm))

        #print "diffP = ",np.linalg.norm(self.P_imp - onedm)

        print(mf.elec_energy)
        mycc = cc.CCSD(mf)
        mycc.max_cycle = 200
        #mycc.conv_tol = 1e-6
        #mycc.conv_tol_normt = 1e-4
        mycc.kernel()

        et = 0.0
        if (self.ecw_method == 'ccsd(t)'):
            print('CCSD(T) correction')
            et = mycc.ccsd_t()

        #ccsd_dm_mo = mycc.make_rdm1()
        #ccsd_dm_sub = tools.dm_loc2ao(ccsd_dm_mo,mf.mo_coeff)
        #e_emb=np.trace(np.dot(umat,ccsd_dm_sub))

        e_hf = mf.elec_energy
        print(mycc.e_corr + et)

        e_ccsd = e_hf + mycc.e_corr + et
        e_ccsd -= e_emb
        print(e_ccsd)

        imp_mf_energy = self.imp_mf_energy(dim)

        energy = e_ccsd - imp_mf_energy

        print("dmfet correction energy = ", energy)
        return energy
Пример #14
0
    def imp_mf_energy(self, dim):

        Ne_frag = self.Ne_frag
        ops = self.ops
        umat = self.umat

        Ne_env = self.Ne_env
        P_bath_loc = tools.dm_sub2ao(self.P_bath, self.loc2sub[:, :dim])
        P_bath_JK = libgen.coreJK_sub(self.ints, self.loc2sub, dim, P_bath_loc,
                                      Ne_env, self.Kcoeff)

        proj = 0.5 * self.P_bath
        energy_shift = 1e5

        ao2sub = self.ao2sub[:, :dim]
        coredm = self.core1PDM_ao + tools.dm_sub2ao(self.P_bath, ao2sub)

        Vemb = ops["subVnuc2"] + P_bath_JK + ops[
            "subCoreJK"] + energy_shift * proj
        Vxc = None
        if (self.mf_method != 'hf'):
            P_imp_ao = tools.dm_sub2ao(self.P_imp, ao2sub)
            mf_frag = qcwrap.qc_scf(Ne_frag,
                                    dim,
                                    self.mf_method,
                                    mol=self.mol_frag,
                                    oei=None,
                                    tei=None,
                                    dm0=self.P_imp,
                                    coredm=0.0,
                                    ao2sub=ao2sub)
            vxc_imp_ao = qcwrap.pyscf_rks.get_vxc(mf_frag, self.mol_frag,
                                                  P_imp_ao)[2]
            vxc_full_ao = qcwrap.pyscf_rks.get_vxc(self.mf_full, self.mol,
                                                   coredm + P_imp_ao)[2]

            Vxc = tools.op_ao2sub(vxc_full_ao, ao2sub) - tools.op_ao2sub(
                vxc_imp_ao, ao2sub)
            Vemb += Vxc

        subOEI = ops["subKin"] + ops["subVnuc1"] + Vemb
        #subOEI = ops["subKin"]+ops["subVnuc1"]+ops["subVnuc2"]+P_bath_JK+ops["subCoreJK"]+ energy_shift*proj
        #subOEI = ops["subKin"]+ops["subVnuc1"]+ops["subVnuc_bound1"]+umat +0.5*1e4*self.P_bath
        subTEI = ops["subTEI"]

        mf = qcwrap.qc_scf(Ne_frag, dim, self.mf_method, mol=self.mol_frag, oei=subOEI, tei=subTEI, dm0=self.P_imp, coredm=0.0, ao2sub=ao2sub,\
                           smear_sigma = self.smear_sigma)
        mf.runscf()
        energy = mf.elec_energy

        #self.ints.submo_molden(mf.mo_coeff, mf.mo_occ, self.loc2sub, "mo_frag.molden" )

        print('|diffP| = ',
              np.linalg.norm(mf.rdm1 + self.P_bath - self.P_ref_sub))
        print("embeded imp scf (electron) energy = ", energy)

        self.P_imp = mf.rdm1

        print('level shift energy contribution: ',
              np.trace(np.dot(energy_shift * proj, self.P_imp)))

        return (energy, Vemb, Vxc)
Пример #15
0
    def ecw_energy(self, method, dim):

        mf_energy, Vemb, Vxc = self.imp_mf_energy(dim)

        Ne_frag = self.Ne_frag
        ops = self.ops

        subOEI = ops["subKin"] + ops["subVnuc1"] + Vemb
        subTEI = ops["subTEI"]

        mf = qcwrap.qc_scf(Ne_frag,
                           dim,
                           'hf',
                           mol=self.mol_frag,
                           oei=subOEI,
                           tei=subTEI,
                           dm0=self.P_imp)
        mf.runscf()
        e_hf = mf.elec_energy  # - np.trace(np.dot(mf.rdm1,Vemb))
        if (self.plot_mo):
            self.ints.submo_molden(mf.mo_coeff, mf.mo_occ, self.loc2sub,
                                   "mo_frag.molden", self.mol_frag)

        exc = 0.0
        if (Vxc is not None):
            #           exc = np.einsum('ij,ji', Vxc, mf.rdm1-self.P_imp)
            exc = np.einsum('ij,ji', Vxc, self.P_imp)
        print('exc = ', exc)

        if (method == 'hf'):
            energy = e_hf
        elif (method == 'mp2'):
            mp2 = mp.MP2(mf)
            mp2.kernel()
            energy = e_hf + mp2.e_corr
        elif (method == 'ccsd' or method == 'ccsd(t)'):
            mycc = cc.CCSD(mf)
            mycc.max_cycle = 200
            #mycc.conv_tol = 1e-6
            #mycc.conv_tol_normt = 1e-4
            mycc.kernel()

            et = 0.0
            if (method == 'ccsd(t)'):
                print('CCSD(T) correction')
                et = mycc.ccsd_t()

            energy = e_hf + mycc.e_corr + et
        elif (method == 'eomccsd'):
            mf.verbose = 5
            mycc = cc.RCCSD(mf)
            mycc.kernel()
            es, vs = mycc.eomee_ccsd_singlet(nroots=self.ex_nroots)

            if (self.ex_nroots == 1):
                r1, r2 = mycc.vector_to_amplitudes(vs)
                print('debug: ', r1.shape)
            else:
                for vn in vs:
                    r1, r2 = mycc.vector_to_amplitudes(vn)

            energy = e_hf + mycc.e_corr
        elif (method == 'eomsfccsd'):
            self.mol_frag.spin = 2
            mf = qcwrap.pyscf_rks.rohf_pyscf(Ne_frag,
                                             dim,
                                             mol=self.mol_frag,
                                             oei=subOEI,
                                             tei=subTEI,
                                             dm0=np.array((.5 * self.P_imp,
                                                           .5 * self.P_imp)))
            mf.kernel(dm0=mf.dm_guess)

            mf1 = qcwrap.pyscf_rks.uhf_pyscf(Ne_frag,
                                             dim,
                                             mol=self.mol_frag,
                                             oei=subOEI,
                                             tei=subTEI,
                                             dm0=None)
            mf1.convert_from_rhf(mf)

            mycc = cc.UCCSD(mf1)
            mycc.verbose = 5
            mycc.kernel()
            es, vs = mycc.eomsf_ccsd(nroots=self.ex_nroots)

            if (self.ex_nroots == 1):
                r1, r2 = cc.eom_uccsd.vector_to_amplitudes_eomsf(
                    vs, mycc.nmo, mycc.nocc)
                tools.print_eomcc_t1(r1[0])
                tools.print_eomcc_t1(r1[1])
            else:
                for vn in vs:
                    r1, r2 = cc.eom_uccsd.vector_to_amplitudes_eomsf(
                        vn, mycc.nmo, mycc.nocc)
                    tools.print_eomcc_t1(r1[0])
                    tools.print_eomcc_t1(r1[1])

            energy = mf1.e_tot + mycc.e_corr
        else:
            raise Exception("ecw_method not supported!")

        energy -= mf_energy
        energy -= exc

        return energy
Пример #16
0
    def pad_umat(self, occ_mo_imp, occ_mo_bath, dim_small, dim_big,
                 core1dm_loc):

        if (dim_small == dim_big):
            return self.umat

        ops = libgen.build_subops(self.impAtom, self.mol_frag,self.mol_env, \
                                  self.boundary_atoms,self.boundary_atoms2, self.ints, self.loc2sub, core1dm_loc, dim_big,self.Kcoeff, self.Nelec_core)
        self.ops = ops

        P_imp_small = 2.0 * np.dot(occ_mo_imp, occ_mo_imp.T)
        P_bath_small = 2.0 * np.dot(occ_mo_bath, occ_mo_bath.T)

        dim_ext = dim_big - dim_small

        P_imp_big = np.pad(P_imp_small, ((0, dim_ext), (0, dim_ext)),
                           'constant',
                           constant_values=0)
        P_bath_big = np.pad(P_bath_small, ((0, dim_ext), (0, dim_ext)),
                            'constant',
                            constant_values=0)

        self.P_imp = P_imp_big
        self.P_bath = P_bath_big
        self.P_ref_sub = tools.dm_loc2sub(self.OneDM_loc - self.core1PDM_loc,
                                          self.loc2sub[:, :dim_big])

        JK_imp = self.ints.impJK_sub(P_imp_big, ops["subTEI"], self.Kcoeff)
        JK_bath = self.ints.impJK_sub(P_bath_big, ops["subTEI"], self.Kcoeff)

        ao2sub = self.ao2sub[:, :dim_big]
        coredm = self.core1PDM_ao
        if (self.mf_method != 'hf'):
            mf1 = qcwrap.qc_scf(True, mol=self.mol_frag, Ne=self.Ne_frag, Norb=dim_big, method=self.mf_method, \
                                oei=None,tei=None,dm0=P_imp_big,coredm=0.0,ao2sub=ao2sub)
            vxc_imp_ao = qcwrap.pyscf_rks.get_vxc(
                mf1, self.mol_frag, tools.dm_sub2ao(P_imp_big, ao2sub))[2]
            JK_imp += tools.op_ao2sub(vxc_imp_ao, ao2sub)

            env_dm = coredm + tools.dm_sub2ao(P_bath_big, ao2sub)
            mf2 = qcwrap.qc_scf(True, mol=self.mol_env, Ne=self.Ne_env, Norb=dim_big, method=self.mf_method, \
                                oei=None,tei=None,dm0=P_bath_big,coredm=coredm, ao2sub=ao2sub)
            vxc_bath_ao = qcwrap.pyscf_rks.get_vxc(
                mf2, self.mol_env, env_dm, n_core_elec=self.Nelec_core)[2]
            JK_bath += tools.op_ao2sub(vxc_bath_ao, ao2sub)

        oei_imp = ops["subKin"] + ops["subVnuc1"] + ops[
            "subVnuc_bound1"] + JK_imp
        ext_oei_imp = oei_imp[dim_small:, :dim_small]

        oei_bath = ops["subKin"] + ops["subVnuc2"] + ops[
            "subVnuc_bound2"] + ops["subCoreJK"] + JK_bath
        ext_oei_bath = oei_bath[dim_small:, :dim_small]

        b_imp = -np.dot(ext_oei_imp, occ_mo_imp)
        b_bath = -np.dot(ext_oei_bath, occ_mo_bath)

        #solve uv = b for u
        v = np.concatenate((occ_mo_imp, occ_mo_bath), axis=1)
        b = np.concatenate((b_imp, b_bath), axis=1)

        AAT = np.dot(v.T, v)
        #tools.MatPrint(AAT,'AAT')
        #tmp = np.dot(np.linalg.inv(AAT), b.T)
        tmp = b.T
        uT = np.dot(v, tmp)
        u = uT.T

        #u = scipy.linalg.lstsq(v.T, b.T, cond=None, overwrite_a=False, overwrite_b=False, check_finite=True, lapack_driver=None)[0]
        #u = np.linalg.lstsq(v.T, b.T, rcond=1e-9)[0]
        #tools.MatPrint(u.T,"u")
        #zero = np.dot(u.T,v)-b
        #tools.MatPrint(zero,"zero")

        #tools.MatPrint(self.umat,"umat")

        umat = np.pad(self.umat, ((0, dim_ext), (0, dim_ext)),
                      'constant',
                      constant_values=0)
        umat[dim_small:, :dim_small] = u
        umat[:dim_small, dim_small:] = u.T

        #umat1=umat.copy()
        #umat1[dim_small:, :dim_small] = -ext_oei_bath
        #umat1[:dim_small, dim_small:] = -ext_oei_bath.T

        #print "u-u1=",np.linalg.norm(umat-umat1)

        #debug
        subOEI = ops["subKin"] + ops["subVnuc1"] + ops["subVnuc_bound1"]
        #energy, onedm, mo = qcwrap.pyscf_rhf.scf( subOEI, ops["subTEI"], dim_big, self.Ne_frag, P_imp_big, self.mf_method)
        mf1 = qcwrap.qc_scf(True, mol=self.mol_frag, Ne=self.Ne_frag, Norb=dim_big, method=self.mf_method,\
                            vext_1e = umat, oei=subOEI,tei=ops["subTEI"],dm0=P_imp_big,coredm=0.0,ao2sub=ao2sub)
        mf1.runscf()

        subOEI = ops["subKin"] + ops["subVnuc2"] + ops["subVnuc_bound2"] + ops[
            "subCoreJK"]
        #energy2, onedm2, mo2 = qcwrap.pyscf_rhf.scf( subOEI, ops["subTEI"], dim_big, self.Ne_env, P_bath_big, self.mf_method)
        mf2 = qcwrap.qc_scf(True, mol=self.mol_env, Ne=self.Ne_env, Norb=dim_big, method=self.mf_method,\
                            vext_1e = umat, oei=subOEI,tei=ops["subTEI"],dm0=P_bath_big,coredm=coredm,ao2sub=ao2sub)
        #mf2.conv_check = False #temp

        #subOEI = ops["subKin"]+ops["subVnuc2"]+ops["subVnuc_bound2"]+umat1
        #s = self.mf_full.get_ovlp(self.mol)
        #coredm_sub = tools.dm_ao2sub(coredm,s,ao2sub)
        #mf2 = qcwrap.qc_scf(self.Ne_env+self.Nelec_core,dim_big,self.mf_method,mol=self.mol_env,oei=subOEI,tei=ops["subTEI"],dm0=P_bath_big+coredm_sub,coredm=0.0,ao2sub=ao2sub)
        mf2.runscf()

        diffP = mf1.rdm1 + mf2.rdm1 - self.P_ref_sub
        #diffP = mf1.rdm1 + mf2.rdm1 - tools.dm_loc2sub(self.OneDM_loc, self.loc2sub[:,:dim_big])

        print(np.linalg.norm(P_imp_big - mf1.rdm1),
              np.linalg.norm(P_bath_big - mf2.rdm1))
        print('|diffP| = ', np.linalg.norm(diffP), 'max(diffP) = ',
              np.amax(np.absolute(diffP)))
        #tools.MatPrint(diffP,"diffP")
        #tools.MatPrint(mf1.rdm1,"P1")
        #tools.MatPrint(mf2.rdm1,"P2")
        #tools.MatPrint(P_imp_small,"P_imp_small")
        #tools.MatPrint(P_bath_small,"P_bath_small")
        return umat