Exemple #1
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
Exemple #2
0
    def get_veff(ks, mol=None, dm=None, dm_last=0, vhf_last=0, hermi=1):

        if mol is None: mol = ks.mol
        if dm is None: dm = ks.make_rdm1()

        dm_sub = np.asarray(dm) + coredm
        dm_ao = tools.dm_sub2ao(dm_sub, ao2sub)

        if hasattr(dm, 'mo_coeff'):
            mo_coeff_sub = dm.mo_coeff
            mo_occ_sub = dm.mo_occ

            mo_coeff_ao = tools.mo_sub2ao(mo_coeff_sub, ao2sub)
            mo_occ_ao = mo_occ_sub
            dm_ao = lib.tag_array(dm_ao,
                                  mo_coeff=mo_coeff_ao,
                                  mo_occ=mo_occ_ao)

        n, exc, vxc_ao, hyb = get_vxc(ks, mol, dm_ao)
        vxc = tools.op_ao2sub(vxc_ao, ao2sub)

        vj = None
        vk = None
        if abs(hyb) < 1e-10:
            if (ks._eri is None and ks.direct_scf
                    and getattr(vhf_last, 'vj', None) is not None):
                ddm = numpy.asarray(dm) - numpy.asarray(dm_last)
                vj = ks.get_jk(mol, ddm, hermi)[0]
                vj += vhf_last.vj
            else:
                vj = ks.get_jk(mol, dm, hermi)[0]
            vxc += vj
        else:
            if (ks._eri is None and ks.direct_scf
                    and getattr(vhf_last, 'vk', None) is not None):
                ddm = numpy.asarray(dm) - numpy.asarray(dm_last)
                vj, vk = ks.get_jk(mol, ddm, hermi)
                vj += vhf_last.vj
                vk += vhf_last.vk
            else:
                vj, vk = ks.get_jk(mol, dm, hermi)
            vxc += vj - vk * (hyb * .5)
            exc -= np.einsum('ij,ji', dm, vk) * .5 * hyb * .5

        ecoul = np.einsum('ij,ji', dm, vj) * .5

        vxc = lib.tag_array(vxc, ecoul=ecoul, exc=exc, vj=vj, vk=vk)

        return vxc
Exemple #3
0
    def __init__(self, Ne, Norb, mf_method, mol=None, vext_1e = None, oei=None, vhxc=None, tei=None, ovlp=1, dm0=None,\
                 coredm=0.0, ao2sub=1.0, level_shift=0.0, smear_sigma = 0.0, max_cycle = 50):

        rks_pyscf.__init__(self, Ne, Norb, mf_method, mol, vext_1e, oei, tei,
                           ovlp, dm0, coredm, ao2sub, level_shift, smear_sigma)
        self.max_cycle = max_cycle

        if self.dm_guess is None:
            raise ValueError(
                "dm0 has to be set since it's used as the fixed density")
        if self.tei is None:
            raise ValueError("tei has to be set")

        Kcoeff = self._numint.hybrid_coeff(self.xc)
        self.vhxc = vhxc
        if self.vhxc is None:
            self.vhxc = tools.dm2jk(self.dm_guess, self.tei, Kcoeff)
            if (self.method != 'hf'):
                vxc_ao = get_vxc(
                    self, self.mol,
                    self.coredm + tools.dm_sub2ao(self.dm_guess, ao2sub))[2]
                self.vhxc += tools.op_ao2sub(vxc_ao, ao2sub)
Exemple #4
0
    def get_veff(self, mol=None, dm=None, dm_last=0, vhf_last=0, hermi=1):

        #t0 = (time.clock(), time.time())

        if mol is None: mol = self.mol
        if dm is None: dm = self.make_rdm1()

        ao2sub = self.ao2sub
        coredm = self.coredm

        use_mo = False
        n_core_elec = 0.0
        if (isinstance(coredm, np.ndarray) and coredm.ndim == 2):
            s1e_ao = mol.intor_symmetric('int1e_ovlp')
            n_core_elec = np.trace(np.dot(coredm, s1e_ao))
            use_mo = False
        else:
            use_mo = True

        use_mo = False  #debug
        dm_ao = coredm + tools.dm_sub2ao(np.asarray(dm), ao2sub)

        if (hasattr(dm, 'mo_coeff') and use_mo):
            mo_coeff_sub = dm.mo_coeff
            mo_occ_sub = dm.mo_occ

            mo_coeff_ao = tools.mo_sub2ao(mo_coeff_sub, ao2sub)
            mo_occ_ao = mo_occ_sub
            dm_ao = lib.tag_array(dm_ao,
                                  mo_coeff=mo_coeff_ao,
                                  mo_occ=mo_occ_ao)

        n, exc, vxc_ao, hyb = get_vxc(self,
                                      mol,
                                      dm_ao,
                                      n_core_elec=n_core_elec)
        vxc = tools.op_ao2sub(vxc_ao, ao2sub)

        vj = None
        vk = None
        if abs(hyb) < 1e-10:
            if (self._eri is None and self.direct_scf
                    and getattr(vhf_last, 'vj', None) is not None):
                ddm = np.asarray(dm) - np.asarray(dm_last)
                vj = self.get_jk(mol, ddm, hermi)[0]
                vj += vhf_last.vj
            else:
                vj = self.get_jk(mol, dm, hermi)[0]
            vxc += vj
        else:
            if (self._eri is None and self.direct_scf
                    and getattr(vhf_last, 'vk', None) is not None):
                ddm = np.asarray(dm) - np.asarray(dm_last)
                vj, vk = self.get_jk(mol, ddm, hermi)
                vj += vhf_last.vj
                vk += vhf_last.vk
            else:
                vj, vk = self.get_jk(mol, dm, hermi)
            vxc += vj - vk * (hyb * .5)
            exc -= np.einsum('ij,ji', dm, vk) * .5 * hyb * .5

        ecoul = np.einsum('ij,ji', dm, vj) * .5

        vxc = lib.tag_array(vxc, ecoul=ecoul, exc=exc, vj=vj, vk=vk)

        #t1 = tools.timer("get_veff",t0)

        return vxc
Exemple #5
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
Exemple #6
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)
Exemple #7
0
    def embedding_potential(self):

        #if(self.umat is None):
        self.calc_umat()

        #dim_big = self.dim_frag + self.dim_bath
        dim_big = self.dim_big
        '''
        occ_mo_imp = self.frag_mo[:,:self.Ne_frag//2]
        occ_mo_bath = self.env_mo[:,:self.Ne_env//2]
        self.umat = self.pad_umat(occ_mo_imp, occ_mo_bath, self.dim_sub, dim_big, self.core1PDM_loc)
        '''
        #tools.MatPrint(self.P_imp,'self.P_imp')
        #tools.MatPrint(self.P_bath,'self.P_bath')
        #tools.MatPrint(self.P_ref_sub,'P_ref')

        ao2sub = self.ao2sub[:, :dim_big]
        P_imp_ao = tools.dm_sub2ao(self.P_imp, ao2sub)
        P_bath_ao = tools.dm_sub2ao(self.P_bath, ao2sub)

        #tools.MatPrint(P_imp_ao,'P_frag')

        umat_ao = reduce(np.dot, (ao2sub, self.umat, ao2sub.T))

        diffP = P_imp_ao + P_bath_ao + self.core1PDM_ao - self.P_ref_ao
        print('|diffP_ao| = ', np.linalg.norm(diffP), 'max(diffP_ao) = ',
              np.max(diffP))

        if (self.plot_dens):
            cubegen.density(self.mol,
                            "tot_dens.cube",
                            self.P_ref_ao,
                            nx=100,
                            ny=100,
                            nz=100)
            cubegen.density(self.mol,
                            "frag_dens.cube",
                            P_imp_ao,
                            nx=100,
                            ny=100,
                            nz=100)
            cubegen.density(self.mol,
                            "bath_dens.cube",
                            P_bath_ao,
                            nx=100,
                            ny=100,
                            nz=100)
            cubegen.density(self.mol,
                            "core_dens.cube",
                            self.core1PDM_ao,
                            nx=100,
                            ny=100,
                            nz=100)
            cubegen.density(self.mol,
                            "env_dens.cube",
                            P_bath_ao + self.core1PDM_ao,
                            nx=100,
                            ny=100,
                            nz=100)
            cubegen.density(self.mol,
                            "vemb.cube",
                            umat_ao,
                            nx=100,
                            ny=100,
                            nz=100)
            cubegen.density(self.mol,
                            "error_dens.cube",
                            diffP,
                            nx=100,
                            ny=100,
                            nz=100)
Exemple #8
0
    def __init__(self, mf_full,mol_frag,mol_env, ints, cluster, impAtom, Ne_frag, boundary_atoms=None, boundary_atoms2=None, \
                 umat = None, P_frag_ao = None, P_env_ao = None, \
                 dim_imp =None, dim_bath = None, dim_big = None, smear_sigma = 0.0, \
                 sub_threshold = 1e-13, oep_params = oep.OEPparams(), ecw_method = 'HF', mf_method = 'HF', ex_nroots = 1, \
                 plot_dens=True, plot_mo = True, deproton=None, use_bath_virt = False, use_umat_ao = False, scf_max_cycle=50, frac_occ_tol=1e-6):

        self.use_suborb = True
        self.ints = ints
        self.mf_full = mf_full
        self.mol = self.mf_full.mol
        self.cluster = cluster
        self.ao_bas_tab_frag = self.cluster
        self.impAtom = impAtom
        self.Ne_frag = Ne_frag
        self.Ne_frag_orig = copy.copy(self.Ne_frag)
        self.boundary_atoms = boundary_atoms
        self.boundary_atoms2 = boundary_atoms2
        self.deproton = deproton
        self.plot_dens = plot_dens
        self.plot_mo = plot_mo
        self.scf_max_cycle = scf_max_cycle

        self.P_ref_ao = mf_full.make_rdm1()
        self.P_frag_ao = P_frag_ao
        self.P_env_ao = P_env_ao

        self.mol_frag = mol_frag
        self.mol_env = mol_env

        self.smear_sigma = smear_sigma

        self.use_umat_ao = use_umat_ao

        self.dim_frag = np.sum(self.cluster)
        #self.dim_env = self.cluster.size - self.dim_frag

        self.ecw_method = ecw_method.lower()
        self.mf_method = mf_method.lower()
        self.ex_nroots = ex_nroots
        self.sub_threshold = sub_threshold

        self.Kcoeff = 1.0
        if (self.mf_method != 'hf'):
            ks = self.mf_full
            self.Kcoeff = ks._numint.hybrid_coeff(ks.xc, spin=self.mol.spin)

        #construct subspace
        self.OneDM_loc, mo_coeff = self.ints.build_1pdm_loc()
        #tools.MatPrint(self.OneDM_loc,"self.OneDM_loc")
        '''
        ##########################
        # SCF with local orbitals
        ##########################
        ops_loc = libgen.build_locops(self.mol_frag, self.mol_env, self.ints, 0.0, self.Kcoeff, 0)
        oei_loc = ops_loc["locKin"]+ops_loc["locVnuc1"]+ops_loc["locVnuc2"]
        tei_loc = ops_loc["locTEI"]

        mf = qcwrap.qc_scf(True, mol=self.mol, Ne=self.ints.Nelec, Norb=self.ints.NOrb, method=self.mf_method, \
                           oei=oei_loc, tei=tei_loc, dm0=self.OneDM_loc, coredm=0.0,\
                           ao2sub=self.ints.ao2loc, smear_sigma = self.smear_sigma)
        #mf.init_guess = 'minao'
        mf.kernel()
        energy = mf.elec_energy + self.ints.energy_nuc()
        print('total scf energy = %.15g ' % energy)
        ##########################
        '''

        mo_coeff_loc, mo_occ_loc, _ = self.ints.get_loc_mo(self.smear_sigma)

        self.dim_imp, self.dim_bath, self.Occupations, self.loc2sub, occ_imp, occ_bath = \
        subspac.construct_subspace2(mo_coeff_loc,mo_occ_loc, self.mol_frag, self.ints, self.cluster,dim_imp,dim_bath,self.sub_threshold,\
                                    occ_tol = frac_occ_tol)

        self.P_frag_loc = None
        self.P_env_loc = None
        if (self.P_frag_ao is not None):
            s = self.mf_full.get_ovlp(self.mol)
            self.P_frag_loc = tools.dm_ao2loc(self.P_frag_ao, s,
                                              self.ints.ao2loc)
            self.P_env_loc = tools.dm_ao2loc(self.P_env_ao, s,
                                             self.ints.ao2loc)
        else:
            #self.P_frag_loc, self.P_env_loc, mo_frag_loc, mo_occ_loc  = subspac.loc_fullP_to_fragP(self.cluster,mo_coeff,self.ints.Nelec//2, self.ints.NOrb)
            self.P_frag_loc, self.P_env_loc = subspac.mulliken_partition_loc(
                self.cluster, self.OneDM_loc)

        #self.dim_imp, self.dim_bath, self.Occupations, self.loc2sub, occ_imp, occ_bath = \
        #    subspac.construct_subspace(self.ints,self.mol_frag,self.mol_env,self.OneDM_loc, self.cluster, self.sub_threshold, dim_bath, dim_imp)

        #test boys
        #self.loc2sub = np.eye(10)
        #self.dim_imp=1
        #self.dim_bath=2
        #self.Occupations=np.array([0.,0.,0.,2.,2.,0.,0.,0.,0.,0.])
        #self.Occupations[:]=0.0

        #tools.MatPrint(self.loc2sub,'self.loc2sub')
        #self.ints.sub_molden( self.loc2sub, 'loc2sub.molden', mo_occ=None )
        #exit()

        self.dim_sub = self.dim_imp + self.dim_bath
        print('dimension of subspace: imp, bath', )
        print(self.dim_imp, self.dim_bath)

        self.dim_big = dim_big
        if dim_big is None: self.dim_big = self.dim_frag + self.dim_bath
        #construct core determinant
        idx = self.dim_frag + self.dim_bath
        self.core1PDM_loc, self.Nelec_core, Norb_imp_throw, self.frag_core1PDM_loc = subspac.build_core(
            self.Occupations, self.loc2sub, idx)
        self.core1PDM_ao = tools.dm_loc2ao(self.core1PDM_loc, self.ints.ao2loc)

        if (use_bath_virt):
            #determine boundary orbitals
            ##################
            nbas = self.mol.nao_nr()
            natoms = self.mol.natm
            aoslice = self.mol.aoslice_by_atom()
            impurities = np.zeros([nbas], dtype=int)
            for i in range(natoms):
                if (abs(boundary_atoms[i]) >= 0.01):
                    impurities[aoslice[i, 2]:aoslice[i, 3]] = 1

            isbound = impurities == 1
            self.is_bound_orb = np.zeros([nbas], dtype=int)
            dim_active = self.dim_frag + self.dim_bath
            n_bound_orb = 0
            for i in range(dim_active + self.Nelec_core // 2, nbas):
                weight = np.linalg.norm(self.loc2sub[isbound, i])
                if (weight > 0.5):
                    self.is_bound_orb[i] = 1
                    n_bound_orb += 1

            self.is_bound_orb[:dim_active] = -1
            self.is_bound_orb[dim_active:dim_active + self.Nelec_core // 2] = 2
            _loc2sub = self.loc2sub.copy()
            self.loc2sub[:, dim_active:dim_active +
                         n_bound_orb] = _loc2sub[:, self.is_bound_orb == 1]
            self.loc2sub[:, dim_active + n_bound_orb:dim_active + n_bound_orb +
                         self.Nelec_core //
                         2] = _loc2sub[:, self.is_bound_orb == 2]
            self.loc2sub[:, dim_active + n_bound_orb + self.Nelec_core //
                         2:] = _loc2sub[:, self.is_bound_orb == 0]

            self.dim_big += n_bound_orb
            print("dim_big = ", self.dim_big)
            #################

        #debug
        self.dim_big = self.dim_sub

        self.ao2sub = np.dot(self.ints.ao2loc, self.loc2sub)
        #tools.MatPrint(self.ao2sub,'ao2sub')

        self.P_env_loc -= self.core1PDM_loc  #assume core does not have imp contribution

        self.Ne_frag = self.Ne_frag - Norb_imp_throw * 2
        self.Ne_env = self.ints.Nelec - self.Ne_frag - self.Nelec_core

        print('Ne_frag, Ne_env, Ne_core')
        print(self.Ne_frag, self.Ne_env, self.Nelec_core)

        self.umat = umat
        self.P_imp = None
        self.P_bath = None

        dim = self.dim_sub
        loc2sub = self.loc2sub
        self.P_ref_sub = tools.dm_loc2sub(self.OneDM_loc - self.core1PDM_loc,
                                          loc2sub[:, :dim])
        #tools.MatPrint(self.P_ref_sub, "P_ref")

        self.P_imp = np.dot(np.dot(self.loc2sub[:, :dim].T, self.P_frag_loc),
                            self.loc2sub[:, :dim])
        self.P_bath = np.dot(np.dot(self.loc2sub[:, :dim].T, self.P_env_loc),
                             self.loc2sub[:, :dim])
        #print ('|diffP| = ',  np.linalg.norm(self.P_imp + self.P_bath - self.P_ref_sub))
        #print ('P_imp idem:', np.linalg.norm(np.dot(self.P_imp,self.P_imp) - 2.0*self.P_imp))
        #print ('P_bath idem:',np.linalg.norm(np.dot(self.P_bath,self.P_bath) - 2.0*self.P_bath))

        #if(self.umat is not None):
        #    self.umat = tools.op_ao2sub(self.umat, self.ao2sub[:,:dim])
        if self.umat is None:
            #self.umat = np.random.rand(dim,dim)
            #self.umat = 0.5*(self.umat+self.umat.T)
            #self.umat = self.umat - np.eye( self.umat.shape[ 0 ] ) * np.average( np.diag( self.umat ) )
            self.umat = np.zeros((dim, dim))
        print('|umat| = ', np.linalg.norm(self.umat))
        '''
        #density partition
        self.P_imp,P2 = subspac.subocc_to_dens_part(self.P_ref_sub,occ_imp, occ_bath, self.dim_imp, self.dim_bath)

        self.P_bath = self.P_ref_sub - self.P_imp
        print 'check idempotency for P_imp, P_bath'
        print np.linalg.norm(np.dot(self.P_imp,self.P_imp)-2.0*self.P_imp)
        print np.linalg.norm(np.dot(self.P_bath,self.P_bath)-2.0*self.P_bath)
        '''
        '''
        frag_occ = np.zeros([dim],dtype = float)
        for i in range(dim):
            frag_occ[i] = self.P_imp[i,i]
        self.ints.sub_molden( self.loc2sub[:,:dim], 'frag_dens_guess.molden', frag_occ )

        env_occ = np.zeros([dim],dtype = float)
        for i in range(dim):
            env_occ[i] = self.P_bath[i,i]
        self.ints.sub_molden( self.loc2sub[:,:dim], 'env_dens_guess.molden', env_occ )
        '''

        self.ints.sub_molden(self.loc2sub, "ao2sub.molden")

        self.oep_params = oep_params

        self.ops = None

        #test use
        self.P_ref = None
        self.vnuc_bound_frag = None
        self.vnuc_bound_env = None
        if (self.use_umat_ao):
            self.P_ref = self.P_ref_ao
            self.vnuc_bound_frag = 0.0
            self.vnuc_bound_env = 0.0
            if (self.umat is None):
                self.umat = np.zeros((dim, dim))
            s = self.mf_full.get_ovlp(self.mol)
            ao2sub = self.ao2sub[:, :self.dim_sub]
            self.P_imp = tools.dm_sub2ao(self.P_imp, ao2sub)
            self.P_bath = tools.dm_sub2ao(self.P_bath, ao2sub)
            return None
        #end test

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

        self.total_scf_energy()
        self.P_ref = self.P_ref_sub
        self.P_imp, self.P_bath = oep.init_dens_par(self, self.dim_sub, True)
Exemple #9
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