Example #1
0
    def init_amps(self, eris):
        time0 = time.clock(), time.time()
        nocc = self.nocc()
        nvir = self.nmo() - nocc
        nkpts = self.nkpts
        t1 = numpy.zeros((nkpts,nocc,nvir), dtype=numpy.complex128)
        t2 = numpy.zeros((nkpts,nkpts,nkpts,nocc,nocc,nvir,nvir), dtype=numpy.complex128)
        self.emp2 = 0
        foo = eris.fock[:,:nocc,:nocc].copy()
        fvv = eris.fock[:,nocc:,nocc:].copy()
        eris_oovv = eris.oovv.copy()
        eia = numpy.zeros((nocc,nvir))
        eijab = numpy.zeros((nocc,nocc,nvir,nvir))

        kconserv = tools.get_kconserv(self._scf.cell,self.kpts)
        for ki in range(nkpts):
          for kj in range(nkpts):
            for ka in range(nkpts):
                kb = kconserv[ki,ka,kj]
                for i in range(nocc):
                    for a in range(nvir):
                        eia[i,a] = foo[ki,i,i] - fvv[ka,a,a]
                        for j in range(nocc):
                            for b in range(nvir):
                                eijab[i,j,a,b] = ( foo[ki,i,i] + foo[kj,j,j]
                                                 - fvv[ka,a,a] - fvv[kb,b,b] )
                                t2[ki,kj,ka,i,j,a,b] = eris_oovv[ki,kj,ka,i,j,a,b]/eijab[i,j,a,b]

        t2 = numpy.conj(t2)
        self.emp2 = 0.25*numpy.einsum('pqrijab,pqrijab',t2,eris_oovv).real
        self.emp2 /= nkpts
        logger.info(self, 'Init t2, MP2 energy = %.15g', self.emp2.real)
        logger.timer(self, 'init mp2', *time0)
        print "MP2 energy =", self.emp2
        return self.emp2, t1, t2
Example #2
0
    def __init__(self, mf, frozen=0, mo_coeff=None, mo_occ=None):

        if mo_coeff is None: mo_coeff = mf.mo_coeff
        if mo_occ is None: mo_occ = mf.mo_occ

        self.mol = mf.mol
        self._scf = mf
        self.verbose = self.mol.verbose
        self.stdout = self.mol.stdout
        self.max_memory = mf.max_memory

        self.frozen = frozen

        ##################################################
        # don't modify the following attributes, they are not input options
        self.kpts = mf.kpts
        self.mo_energy = mf.mo_energy
        self.nkpts = len(self.kpts)
        self.kconserv = tools.get_kconserv(mf.cell, mf.kpts)
        self.mo_energy = mf.mo_energy
        self.mo_coeff = mo_coeff
        self.mo_occ = mo_occ
        self._nocc = None
        self._nmo = None
        self.emp2 = None
        self.e_corr = None
        self.t2 = None
        self._keys = set(self.__dict__.keys())
Example #3
0
def cc_Wovvo(cc,t1,t2,eris):
    nkpts, nocc, nvir = t1.shape
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)
    eris_ovvo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nocc,nvir,nvir,nocc),dtype=t2.dtype)
    eris_oovo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nocc,nocc,nvir,nocc),dtype=t2.dtype)
    for km in range(nkpts):
        for kb in range(nkpts):
            for ke in range(nkpts):
                kj = kconserv[km,ke,kb]
                # <mb||je> -> -<mb||ej>
                eris_ovvo[km,kb,ke] = -eris.ovov[km,kb,kj].transpose(0,1,3,2)
                # <mn||je> -> -<mn||ej>
                # let kb = kn as a dummy variable
                eris_oovo[km,kb,ke] = -eris.ooov[km,kb,kj].transpose(0,1,3,2)
    Wmbej = eris_ovvo.copy()
    for km in range(nkpts):
        for kb in range(nkpts):
            for ke in range(nkpts):
                kj = kconserv[km,ke,kb]
                Wmbej[km,kb,ke] += einsum('jf,mbef->mbej',t1[kj,:,:],eris.ovvv[km,kb,ke])
                Wmbej[km,kb,ke] += -einsum('nb,mnej->mbej',t1[kb,:,:],eris_oovo[km,kb,ke])
                for kn in range(nkpts):
                    kf = kconserv[km,ke,kn]
                    Wmbej[km,kb,ke] += -0.5*einsum('jnfb,mnef->mbej',t2[kj,kn,kf],
                                                   eris.oovv[km,kn,ke])
                    if kn == kb and kf == kj:
                        Wmbej[km,kb,ke] += -einsum('jf,nb,mnef->mbej',t1[kj],t1[kn],
                                                   eris.oovv[km,kn,ke])
    return Wmbej
Example #4
0
    def init_amps(self, eris):
        time0 = time.clock(), time.time()
        nocc = self.nocc()
        nvir = self.nmo() - nocc
        nkpts = self.nkpts
        t1 = numpy.zeros((nkpts,nocc,nvir), dtype=numpy.complex128)
        t2 = numpy.zeros((nkpts,nkpts,nkpts,nocc,nocc,nvir,nvir), dtype=numpy.complex128)
        self.emp2 = 0
        foo = eris.fock[:,:nocc,:nocc].copy()
        fvv = eris.fock[:,nocc:,nocc:].copy()
        eris_oovv = eris.oovv.copy()
        eia = numpy.zeros((nocc,nvir))
        eijab = numpy.zeros((nocc,nocc,nvir,nvir))

        kconserv = tools.get_kconserv(self._scf.cell,self.kpts)
        for ki in range(nkpts):
          for kj in range(nkpts):
            for ka in range(nkpts):
                kb = kconserv[ki,ka,kj]
                for i in range(nocc):
                    for a in range(nvir):
                        eia[i,a] = foo[ki,i,i] - fvv[ka,a,a]
                        for j in range(nocc):
                            for b in range(nvir):
                                eijab[i,j,a,b] = ( foo[ki,i,i] + foo[kj,j,j]
                                                 - fvv[ka,a,a] - fvv[kb,b,b] )
                                t2[ki,kj,ka,i,j,a,b] = eris_oovv[ki,kj,ka,i,j,a,b]/eijab[i,j,a,b]

        t2 = numpy.conj(t2)
        self.emp2 = 0.25*numpy.einsum('pqrijab,pqrijab',t2,eris_oovv).real
        self.emp2 /= nkpts
        logger.info(self, 'Init t2, MP2 energy = %.15g', self.emp2.real)
        logger.timer(self, 'init mp2', *time0)
        print "MP2 energy =", self.emp2
        return self.emp2, t1, t2
Example #5
0
 def __init__(self, mf, frozen=[], mo_energy=None, mo_coeff=None, mo_occ=None):
     pyscf.cc.ccsd.CCSD.__init__(self, mf, frozen, mo_energy, mo_coeff, mo_occ)
     self.kpts = mf.kpts
     self.nkpts = len(self.kpts)
     self.kconserv = tools.get_kconserv(mf.cell, mf.kpts)
     self.khelper = kpoint_helper.unique_pqr_list(mf.cell, mf.kpts)
     self.made_ee_imds = False
     self.made_ip_imds = False
     self.made_ea_imds = False
Example #6
0
 def __init__(self, mf, frozen=0, mo_coeff=None, mo_occ=None):
     assert (isinstance(mf, scf.khf.KSCF))
     pyscf.cc.ccsd.CCSD.__init__(self, mf, frozen, mo_coeff, mo_occ)
     self.max_space = 20
     self._keys = self._keys.union(['max_space'])
     self.kpts = mf.kpts
     self.mo_energy = mf.mo_energy
     self.nkpts = len(self.kpts)
     self.kconserv = tools.get_kconserv(mf.cell, mf.kpts)
     self.khelper = kpoint_helper.unique_pqr_list(mf.cell, mf.kpts)
     self.made_ee_imds = False
     self.made_ip_imds = False
     self.made_ea_imds = False
     self.diis = None
Example #7
0
 def __init__(self, kmf, frozen=0, mo_coeff=None, mo_occ=None):
     if frozen != 0:
         raise NotImplementedError
     self._scf = kmf
     self.kpts = kmf.kpts
     self.nkpts = len(kmf.kpts)
     self.kconserv = tools.get_kconserv(kmf.cell, kmf.kpts)
     self.diis = None
     self.khelper = kpts_helper.KptsHelper(kmf.cell, kmf.kpts)
     self.verbose = kmf.verbose
     if mo_coeff is None: mo_coeff = kmf.mo_coeff
     if mo_occ is None: mo_occ = kmf.mo_occ
     self.mo_coeff = mo_coeff
     self.mo_occ = mo_occ
     self.mo_energy = kmf.mo_energy
     self.max_cycle = kmf.max_cycle
     self.conv_tol = kmf.conv_tol
Example #8
0
def check_antisymm_34(cc, kpts, integrals):
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)
    nkpts = len(kpts)
    diff = 0.0
    for kp in range(nkpts):
        for kq in range(nkpts):
            for kr in range(nkpts):
                ks = kconserv[kp, kr, kq]
                for p in range(integrals.shape[3]):
                    for q in range(integrals.shape[4]):
                        for r in range(integrals.shape[5]):
                            for s in range(integrals.shape[6]):
                                pqrs = integrals[kp, kq, kr, p, q, r, s]
                                pqsr = integrals[kp, kq, ks, p, q, s, r]
                                cdiff = numpy.linalg.norm(pqrs + pqsr).real
                                print "AS diff = %.15g" % cdiff, pqrs, pqsr, kp, kq, kr, ks, p, q, r, s
                                diff = max(diff, cdiff)
    print "antisymmetrization : max diff = %.15g" % diff
Example #9
0
def check_antisymm_34( cc, kpts, integrals ):
    kconserv = tools.get_kconserv(cc._scf.cell,cc.kpts)
    nkpts = len(kpts)
    diff = 0.0
    for kp in range(nkpts):
        for kq in range(nkpts):
            for kr in range(nkpts):
                ks = kconserv[kp,kr,kq]
                for p in range(integrals.shape[3]):
                    for q in range(integrals.shape[4]):
                        for r in range(integrals.shape[5]):
                            for s in range(integrals.shape[6]):
                                pqrs = integrals[kp,kq,kr,p,q,r,s]
                                pqsr = integrals[kp,kq,ks,p,q,s,r]
                                cdiff = numpy.linalg.norm(pqrs+pqsr).real
                                print "AS diff = %.15g" % cdiff, pqrs, pqsr, kp, kq, kr, ks, p, q, r, s
                                diff = max(diff,cdiff)
    print "antisymmetrization : max diff = %.15g" % diff
Example #10
0
    def get_TEI(self, ao2eo):
        '''Get embedding TEI without density fitting'''
        kconserv = pbctools.get_kconserv(self.cell, self.kpts)

        Nkpts, nao, neo = ao2eo.shape
        TEI = 0.0
        for i in range(Nkpts):
            for j in range(Nkpts):
                for k in range(Nkpts):
                    l = kconserv[i, j, k]
                    ki, COi = self.kpts[i], ao2eo[i]
                    kj, COj = self.kpts[j], ao2eo[j]
                    kk, C*k = self.kpts[k], ao2eo[k]
                    kl, COl = self.kpts[l], ao2eo[l]
                    TEI += self.kmf.with_df.ao2mo([COi, COj, C*k, COl],
                                                  [ki, kj, kk, kl],
                                                  compact=False)

        return TEI.reshape(neo, neo, neo, neo).real / Nkpts
Example #11
0
def make_tau(cc, t2, t1a, t1b, fac=1., out=None):
    nkpts, nocc, nvir = t1a.shape
    tau1 = t2.copy()
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)
    for ki in range(nkpts):
        for ka in range(nkpts):
            for kj in range(nkpts):
                    kb = kconserv[ki,ka,kj]
                    tmp = numpy.zeros((nocc,nocc,nvir,nvir),dtype=t2.dtype)
                    if ki == ka and kj == kb:
                        tmp += einsum('ia,jb->ijab',t1a[ki],t1b[kj])
                    if ki == kb and kj == ka:
                        tmp -= einsum('ib,ja->ijab',t1a[ki],t1b[kj])
                    if kj == ka and ki == kb:
                        tmp -= einsum('ja,ib->ijab',t1a[kj],t1b[ki])
                    if kj == kb and ki == ka:
                        tmp += einsum('jb,ia->ijab',t1a[kj],t1b[ki])
                    tau1[ki,kj,ka] += fac*0.5*tmp
    return tau1
Example #12
0
def cc_Woooo(cc,t1,t2,eris):
    nkpts, nocc, nvir = t1.shape
    tau = make_tau(cc,t2,t1,t1)
    Wmnij = eris.oooo.copy()
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)
    for km in range(nkpts):
        for kn in range(nkpts):
            # Since it's not enough just to switch i and j and need to create the k_i and k_j
            # so that P(ij) switches both i,j and k_i,k_j
            #   t1[ k_j, j, e ] * v[ k_m, k_n, k_i, m, n, i, e ] -> tmp[ k_i, k_j, m, n, i, j ]
            # Here, x = k_j and y = k_i
            tmp = einsum('xje,ymnie->yxmnij',t1,eris.ooov[km,kn])
            tmp = tmp - tmp.transpose(1,0,2,3,5,4)
            for ki in range(nkpts):
                kj = kconserv[km,ki,kn]
                Wmnij[km,kn,ki] += tmp[ki,kj]
                # Here, x = k_e
                Wmnij[km,kn,ki] += 0.25*einsum('xijef,xmnef->mnij',
                        tau[ki,kj],eris.oovv[km,kn])
    return Wmnij
Example #13
0
def cc_Wvvvv(cc,t1,t2,eris):
    nkpts, nocc, nvir = t1.shape
    eris_vovv = - eris.ovvv.transpose(1,0,2,4,3,5,6)
    tau = make_tau(cc,t2,t1,t1)
    Wabef = eris.vvvv.copy()
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)
    for ka in range(nkpts):
        for kb in range(nkpts):
            for ke in range(nkpts):
                km = kb
                tmp  = einsum('mb,amef->abef',t1[kb],eris_vovv[ka,km,ke])
                km = ka
                tmp -= einsum('ma,bmef->abef',t1[ka],eris_vovv[kb,km,ke])
                Wabef[ka,kb,ke] += -tmp
                # km + kn - ka = kb
                # => kn = ka - km + kb
                for km in range(nkpts):
                    kn = kconserv[ka,km,kb]
                    Wabef[ka,kb,ke] += 0.25*einsum('mnab,mnef->abef',tau[km,kn,ka],
                                                   eris.oovv[km,kn,ke])
    return Wabef
Example #14
0
    def get_loc_TEI(self, ao2lo=None):
        '''Get local TEI in R-space without density fitting'''
        kconserv = pbctools.get_kconserv(self.cell, self.kpts)
        if ao2lo is None: ao2lo = self.ao2lo

        Nkpts, nao, nlo = ao2lo.shape
        size = Nkpts * nlo
        mo_phase = lib.einsum('kui,Rk->kuRi', ao2lo,
                              self.phase.conj()).reshape(Nkpts, nao, size)
        TEI = 0.0
        for i in range(Nkpts):
            for j in range(Nkpts):
                for k in range(Nkpts):
                    l = kconserv[i, j, k]
                    ki, COi = self.kpts[i], mo_phase[i]
                    kj, COj = self.kpts[j], mo_phase[j]
                    kk, C*k = self.kpts[k], mo_phase[k]
                    kl, COl = self.kpts[l], mo_phase[l]
                    TEI += self.kmf.with_df.ao2mo([COi, COj, C*k, COl],
                                                  [ki, kj, kk, kl],
                                                  compact=False)
        self.is_real(TEI)
        return TEI.reshape(size, size, size, size).real / Nkpts
Example #15
0
def update_amps(cc, t1, t2, eris, max_memory=2000):
    time0 = time.clock(), time.time()
    log = logger.Logger(cc.stdout, cc.verbose)
    nkpts, nocc, nvir = t1.shape
    fock = eris.fock

    fov = fock[:, :nocc, nocc:].copy()
    foo = fock[:, :nocc, :nocc].copy()
    fvv = fock[:, nocc:, nocc:].copy()

    #mo_e = eris.fock.diagonal()
    #eia = mo_e[:nocc,None] - mo_e[None,nocc:]
    #eijab = lib.direct_sum('ia,jb->ijab',eia,eia)

    tau = imdk.make_tau(cc, t2, t1, t1)

    Fvv = imdk.cc_Fvv(cc, t1, t2, eris)
    Foo = imdk.cc_Foo(cc, t1, t2, eris)
    Fov = imdk.cc_Fov(cc, t1, t2, eris)
    Woooo = imdk.cc_Woooo(cc, t1, t2, eris)
    Wvvvv = imdk.cc_Wvvvv(cc, t1, t2, eris)
    Wovvo = imdk.cc_Wovvo(cc, t1, t2, eris)

    # Move energy terms to the other side
    for k in range(nkpts):
        Fvv[k] -= numpy.diag(numpy.diag(fvv[k]))
        Foo[k] -= numpy.diag(numpy.diag(foo[k]))

    # Get the momentum conservation array
    # Note: chemist's notation for momentum conserving t2(ki,kj,ka,kb), even though
    # integrals are in physics notation
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)

    eris_ovvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nvir, nvir,
                                   nocc),
                            dtype=t2.dtype)
    eris_oovo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nocc, nocc, nvir,
                                   nocc),
                            dtype=t2.dtype)
    eris_vvvo = numpy.zeros(shape=(nkpts, nkpts, nkpts, nvir, nvir, nvir,
                                   nocc),
                            dtype=t2.dtype)
    for km in range(nkpts):
        for kb in range(nkpts):
            for ke in range(nkpts):
                kj = kconserv[km, ke, kb]
                # <mb||je> -> -<mb||ej>
                eris_ovvo[km, kb,
                          ke] = -eris.ovov[km, kb, kj].transpose(0, 1, 3, 2)
                # <mn||je> -> -<mn||ej>
                # let kb = kn as a dummy variable
                eris_oovo[km, kb,
                          ke] = -eris.ooov[km, kb, kj].transpose(0, 1, 3, 2)
                # <ma||be> -> - <be||am>*
                # let kj = ka as a dummy variable
                kj = kconserv[km, ke, kb]
                eris_vvvo[ke, kj, kb] = -eris.ovvv[km, kb, ke].transpose(
                    2, 3, 1, 0).conj()

    # T1 equation
    t1new = numpy.zeros(shape=t1.shape, dtype=t1.dtype)
    for ka in range(nkpts):
        ki = ka
        t1new[ka] += numpy.array(fov[ka, :, :]).conj()
        t1new[ka] += einsum('ie,ae->ia', t1[ka], Fvv[ka])
        t1new[ka] += -einsum('ma,mi->ia', t1[ka], Foo[ka])
        for km in range(nkpts):
            t1new[ka] += einsum('imae,me->ia', t2[ka, km, ka], Fov[km])
            t1new[ka] += -einsum('nf,naif->ia', t1[km], eris.ovov[km, ka, ki])
            for kn in range(nkpts):
                ke = kconserv[km, ki, kn]
                t1new[ka] += -0.5 * einsum('imef,maef->ia', t2[ki, km, ke],
                                           eris.ovvv[km, ka, ke])
                t1new[ka] += -0.5 * einsum('mnae,nmei->ia', t2[km, kn, ka],
                                           eris_oovo[kn, km, ke])

    # T2 equation
    t2new = numpy.array(eris.oovv).conj()
    for ki in range(nkpts):
        for kj in range(nkpts):
            for ka in range(nkpts):
                # Chemist's notation for momentum conserving t2(ki,kj,ka,kb)
                kb = kconserv[ki, ka, kj]

                Ftmp = Fvv[kb] - 0.5 * einsum('mb,me->be', t1[kb], Fov[kb])
                tmp = einsum('ijae,be->ijab', t2[ki, kj, ka], Ftmp)
                t2new[ki, kj, ka] += tmp

                #t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2)
                Ftmp = Fvv[ka] - 0.5 * einsum('ma,me->ae', t1[ka], Fov[ka])
                tmp = einsum('ijbe,ae->ijab', t2[ki, kj, kb], Ftmp)
                t2new[ki, kj, ka] -= tmp

                Ftmp = Foo[kj] + 0.5 * einsum('je,me->mj', t1[kj], Fov[kj])
                tmp = einsum('imab,mj->ijab', t2[ki, kj, ka], Ftmp)
                t2new[ki, kj, ka] -= tmp

                #t2new[kj,ki,ka] += tmp.transpose(1,0,2,3)
                Ftmp = Foo[ki] + 0.5 * einsum('ie,me->mi', t1[ki], Fov[ki])
                tmp = einsum('jmab,mi->ijab', t2[kj, ki, ka], Ftmp)
                t2new[ki, kj, ka] += tmp

                for km in range(nkpts):
                    # Wminj
                    #   - km - kn + ka + kb = 0
                    # =>  kn = ka - km + kb
                    kn = kconserv[ka, km, kb]
                    t2new[ki, kj, ka] += 0.5 * einsum(
                        'mnab,mnij->ijab', tau[km, kn, ka], Woooo[km, kn, ki])
                    ke = km
                    t2new[ki, kj, ka] += 0.5 * einsum(
                        'ijef,abef->ijab', tau[ki, kj, ke], Wvvvv[ka, kb, ke])

                    # Wmbej
                    #     - km - kb + ke + kj = 0
                    #  => ke = km - kj + kb
                    ke = kconserv[km, kj, kb]
                    tmp = einsum('imae,mbej->ijab', t2[ki, km, ka],
                                 Wovvo[km, kb, ke])
                    #     - km - kb + ke + kj = 0
                    # =>  ke = km - kj + kb
                    #
                    # t[i,e] => ki = ke
                    # t[m,a] => km = ka
                    if km == ka and ke == ki:
                        tmp -= einsum('ie,ma,mbej->ijab', t1[ki], t1[km],
                                      eris_ovvo[km, kb, ke])
                    t2new[ki, kj, ka] += tmp
                    t2new[ki, kj, kb] -= tmp.transpose(0, 1, 3, 2)
                    t2new[kj, ki, ka] -= tmp.transpose(1, 0, 2, 3)
                    t2new[kj, ki, kb] += tmp.transpose(1, 0, 3, 2)

                ke = ki
                tmp = einsum('ie,abej->ijab', t1[ki], eris_vvvo[ka, kb, ke])
                t2new[ki, kj, ka] += tmp
                # P(ij) term
                ke = kj
                tmp = einsum('je,abei->ijab', t1[kj], eris_vvvo[ka, kb, ke])
                t2new[ki, kj, ka] -= tmp

                km = ka
                tmp = einsum('ma,mbij->ijab', t1[ka], eris.ovoo[km, kb, ki])
                t2new[ki, kj, ka] -= tmp
                # P(ab) term
                km = kb
                tmp = einsum('mb,maij->ijab', t1[kb], eris.ovoo[km, ka, ki])
                t2new[ki, kj, ka] += tmp

    eia = numpy.zeros(shape=t1new.shape, dtype=t1new.dtype)
    for ki in range(nkpts):
        for i in range(nocc):
            for a in range(nvir):
                eia[ki, i, a] = foo[ki, i, i] - fvv[ki, a, a]
        t1new[ki] /= eia[ki]

    eijab = numpy.zeros(shape=t2new.shape, dtype=t2new.dtype)
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)
    for ki in range(nkpts):
        for kj in range(nkpts):
            for ka in range(nkpts):
                kb = kconserv[ki, ka, kj]
                for i in range(nocc):
                    for a in range(nvir):
                        for j in range(nocc):
                            for b in range(nvir):
                                eijab[ki, kj, ka, i, j, a,
                                      b] = (foo[ki, i, i] + foo[kj, j, j] -
                                            fvv[ka, a, a] - fvv[kb, b, b])
                t2new[ki, kj, ka] /= eijab[ki, kj, ka]

    time0 = log.timer_debug1('update t1 t2', *time0)

    return t1new, t2new
Example #16
0
    def __init__(self, cell, kpts):
        kconserv = tools.get_kconserv(cell, kpts)
        nkpts = len(kpts)
        temp = range(0, nkpts)
        klist = pyscf.lib.cartesian_prod((temp, temp, temp))
        completed = numpy.zeros((nkpts, nkpts, nkpts), dtype=int)

        self.operations = numpy.zeros((nkpts, nkpts, nkpts), dtype=int)
        self.equivalentList = numpy.zeros((nkpts, nkpts, nkpts, 3), dtype=int)
        self.nUnique = 0
        self.uniqueList = numpy.array([])

        ivec = 0
        not_done = True
        while (not_done):
            current_kvec = klist[ivec]
            # check to see if it's been done...
            kp = current_kvec[0]
            kq = current_kvec[1]
            kr = current_kvec[2]
            #print "computing ",kp,kq,kr
            if completed[kp, kq, kr] == 0:
                self.nUnique += 1
                self.uniqueList = numpy.append(self.uniqueList, current_kvec)
                ks = kconserv[kp, kq, kr]

                # Now find all equivalent kvectors by permuting it all possible ways...
                # and then storing how its related by symmetry
                completed[kp, kq, kr] = 1
                self.operations[kp, kq, kr] = 0
                self.equivalentList[kp, kq, kr] = current_kvec.copy()

                completed[kr, ks, kp] = 1
                self.operations[kr, ks, kp] = 1  #.transpose(2,3,0,1)
                self.equivalentList[kr, ks, kp] = current_kvec.copy()

                completed[kq, kp, ks] = 1
                self.operations[kq, kp,
                                ks] = 2  #numpy.conj(.transpose(1,0,3,2))
                self.equivalentList[kq, kp, ks] = current_kvec.copy()

                completed[ks, kr, kq] = 1
                self.operations[ks, kr,
                                kq] = 3  #numpy.conj(.transpose(3,2,1,0))
                self.equivalentList[ks, kr, kq] = current_kvec.copy()

            ivec += 1
            if ivec == len(klist):
                not_done = False

        self.uniqueList = self.uniqueList.reshape(self.nUnique, -1)
        if DEBUG == 1:
            print "::: kpoint helper :::"
            print "kvector list (in)"
            print "   shape = ", klist.shape
            print "kvector list (out)"
            print "   shape  = ", self.uniqueList.shape
            print "   unique list ="
            print self.uniqueList
            print "transformation ="
            for i in range(klist.shape[0]):
                pqr = klist[i]
                irr_pqr = self.equivalentList[pqr[0], pqr[1], pqr[2]]
                print "%3d %3d %3d   ->  %3d %3d %3d" % (
                    pqr[0], pqr[1], pqr[2], irr_pqr[0], irr_pqr[1], irr_pqr[2])
Example #17
0
def update_amps(cc, t1, t2, eris, max_memory=2000):
    time0 = time.clock(), time.time()
    log = logger.Logger(cc.stdout, cc.verbose)
    nkpts, nocc, nvir = t1.shape
    #nov = nocc*nvir
    fock = eris.fock
    #t1new = numpy.zeros_like(t1)
    #t2new = numpy.zeros_like(t2)

    fov = fock[:,:nocc,nocc:].copy()
    foo = fock[:,:nocc,:nocc].copy()
    fvv = fock[:,nocc:,nocc:].copy()

    #mo_e = eris.fock.diagonal()
    #eia = mo_e[:nocc,None] - mo_e[None,nocc:]
    #eijab = lib.direct_sum('ia,jb->ijab',eia,eia)

    tau = imdk.make_tau(cc,t2,t1,t1)

    ### From eom-cc hackathon code ###
    Fvv = imdk.cc_Fvv(cc,t1,t2,eris)
    Foo = imdk.cc_Foo(cc,t1,t2,eris)
    Fov = imdk.cc_Fov(cc,t1,t2,eris)
    Woooo = imdk.cc_Woooo(cc,t1,t2,eris)
    Wvvvv = imdk.cc_Wvvvv(cc,t1,t2,eris)
    Wovvo = imdk.cc_Wovvo(cc,t1,t2,eris)

    # Move energy terms to the other side
    Fvv -= fvv
    Foo -= foo

    # Get the momentum conservation array
    # Note: chemist's notation for momentum conserving t2(ki,kj,ka,kb), even though
    # integrals are in physics notation
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)

    eris_ovvo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nocc,nvir,nvir,nocc), dtype=t2.dtype)
    eris_oovo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nocc,nocc,nvir,nocc), dtype=t2.dtype)
    eris_vvvo = numpy.zeros(shape=(nkpts,nkpts,nkpts,nvir,nvir,nvir,nocc), dtype=t2.dtype)
    for km in range(nkpts):
        for kb in range(nkpts):
            for ke in range(nkpts):
                kj = kconserv[km,ke,kb]
                # <mb||je> -> -<mb||ej>
                eris_ovvo[km,kb,ke] = -eris.ovov[km,kb,kj].transpose(0,1,3,2)
                # <mn||je> -> -<mn||ej>
                # let kb = kn as a dummy variable
                eris_oovo[km,kb,ke] = -eris.ooov[km,kb,kj].transpose(0,1,3,2)
                # <ma||be> -> - <be||am>*
                # let kj = ka as a dummy variable
                kj = kconserv[km,ke,kb]
                eris_vvvo[ke,kj,kb] = -eris.ovvv[km,kb,ke].transpose(2,3,1,0).conj()

    # T1 equation
    t1new = numpy.zeros(shape=t1.shape, dtype=t1.dtype)
    for ka in range(nkpts):
        ki = ka
        # TODO: Does this fov need a conj()? Usually zero w/ canonical HF.
        t1new[ka] += fov[ka,:,:]
        t1new[ka] +=  einsum('ie,ae->ia',t1[ka],Fvv[ka])
        t1new[ka] += -einsum('ma,mi->ia',t1[ka],Foo[ka])
        for km in range(nkpts):
            t1new[ka] +=  einsum('imae,me->ia',t2[ka,km,ka],Fov[km])
            t1new[ka] += -einsum('nf,naif->ia',t1[km],eris.ovov[km,ka,ki])
            for kn in range(nkpts):
                ke = kconserv[km,ki,kn]
                t1new[ka] += -0.5*einsum('imef,maef->ia',t2[ki,km,ke],eris.ovvv[km,ka,ke])
                t1new[ka] += -0.5*einsum('mnae,nmei->ia',t2[km,kn,ka],eris_oovo[kn,km,ke])

    # T2 equation
    # For conj(), see Hirata and Bartlett, Eq. (36)
    t2new = eris.oovv.copy().conj()

    for ki in range(nkpts):
      for kj in range(nkpts):
        for ka in range(nkpts):
            # Chemist's notation for momentum conserving t2(ki,kj,ka,kb)
            kb = kconserv[ki,ka,kj]

            Ftmp = Fvv[kb] - 0.5*einsum('mb,me->be',t1[kb],Fov[kb])
            tmp = einsum('ijae,be->ijab',t2[ki,kj,ka],Ftmp)
            t2new[ki,kj,ka] += tmp

            Ftmp = Fvv[ka] - 0.5*einsum('ma,me->ae',t1[ka],Fov[ka])
            tmp = einsum('ijbe,ae->ijab',t2[ki,kj,kb],Ftmp)
            t2new[ki,kj,ka] -= tmp

            #t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2)

            Ftmp = Foo[kj] + 0.5*einsum('je,me->mj',t1[kj],Fov[kj])
            tmp = einsum('imab,mj->ijab',t2[ki,kj,ka],Ftmp)
            t2new[ki,kj,ka] -= tmp

            Ftmp = Foo[ki] + 0.5*einsum('ie,me->mi',t1[ki],Fov[ki])
            tmp = einsum('jmab,mi->ijab',t2[kj,ki,ka],Ftmp)
            t2new[ki,kj,ka] += tmp

            #t2new[kj,ki,ka] += tmp.transpose(1,0,2,3)

            for km in range(nkpts):
                # Wminj
                #     - km - kn + ka + kb = 0
                # =>  kn = ka - km + kb
                kn = kconserv[ka,km,kb]
                t2new[ki,kj,ka] += 0.5*einsum('mnab,mnij->ijab',tau[km,kn,ka],Woooo[km,kn,ki])
                ke = km
                t2new[ki,kj,ka] += 0.5*einsum('ijef,abef->ijab',tau[ki,kj,ke],Wvvvv[ka,kb,ke])

                # Wmbej
                #     - km - kb + ke + kj = 0
                #  => ke = km - kj + kb
                ke = kconserv[km,kj,kb]
                tmp = einsum('imae,mbej->ijab',t2[ki,km,ka],Wovvo[km,kb,ke])
                #     - km - kb + ke + kj = 0
                # =>  ke = km - kj + kb
                #
                # t[i,e] => ki = ke
                # t[m,a] => km = ka
                if km == ka and ke == ki:
                    tmp -= einsum('ie,ma,mbej->ijab',t1[ki],t1[km],eris_ovvo[km,kb,ke])
                t2new[ki,kj,ka] += tmp
                t2new[ki,kj,kb] -= tmp.transpose(0,1,3,2)
                t2new[kj,ki,ka] -= tmp.transpose(1,0,2,3)
                t2new[kj,ki,kb] += tmp.transpose(1,0,3,2)

            ke = ki
            tmp = einsum('ie,abej->ijab',t1[ki],eris_vvvo[ka,kb,ke])
            t2new[ki,kj,ka] += tmp
            # P(ij) term
            ke = kj
            tmp = einsum('je,abei->ijab',t1[kj],eris_vvvo[ka,kb,ke])
            t2new[ki,kj,ka] -= tmp

            km = ka
            tmp = einsum('ma,mbij->ijab',t1[ka],eris.ovoo[km,kb,ki])
            t2new[ki,kj,ka] -= tmp
            # P(ab) term
            km = kb
            tmp = einsum('mb,maij->ijab',t1[kb],eris.ovoo[km,ka,ki])
            t2new[ki,kj,ka] += tmp

    eia = numpy.zeros(shape=t1new.shape, dtype=t1new.dtype)
    for ki in range(nkpts):
        for i in range(nocc):
            for a in range(nvir):
                eia[ki,i,a] = foo[ki,i,i] - fvv[ki,a,a]
        t1new[ki] /= eia[ki]

    eijab = numpy.zeros(shape=t2new.shape, dtype=t2new.dtype)
    kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)
    for ki in range(nkpts):
        for kj in range(nkpts):
            for ka in range(nkpts):
                kb = kconserv[ki,ka,kj]
                for i in range(nocc):
                    for a in range(nvir):
                        for j in range(nocc):
                            for b in range(nvir):
                                eijab[ki,kj,ka,i,j,a,b] = ( foo[ki,i,i] + foo[kj,j,j]
                                                          - fvv[ka,a,a] - fvv[kb,b,b] )
                t2new[ki,kj,ka] /= eijab[ki,kj,ka]

    time0 = log.timer_debug1('update t1 t2', *time0)

    return t1new, t2new
Example #18
0
    def __init__(self, cc, mo_coeff=None, method='incore'):
        cput0 = (time.clock(), time.time())
        moidx = numpy.ones(shape=cc.mo_energy.shape, dtype=numpy.bool)
        nkpts = cc.nkpts
        nmo = cc.nmo()
        # TODO change this for k-points ... seems like it should work
        if isinstance(cc.frozen, (int, numpy.integer)):
            for k in range(nkpts):
                moidx[k, :cc.frozen] = False
        elif len(cc.frozen) > 0:
            for k in range(nkpts):
                moidx[k, numpy.asarray(cc.frozen)] = False
        assert (numpy.count_nonzero(moidx) % 2 == 0
                )  # works for restricted CCSD only
        if mo_coeff is None:
            # TODO make this work for frozen maybe... seems like it should work
            nao = cc._scf.cell.nao_nr()
            self.mo_coeff = numpy.zeros((nkpts, nao * 2, nmo),
                                        dtype=numpy.complex128)
            for k in range(nkpts):
                self.mo_coeff[k] = cc.mo_coeff[k][:, moidx[k]]
            mo_coeff = self.mo_coeff
            self.fock = numpy.zeros((nkpts, nmo, nmo))
            for k in range(nkpts):
                self.fock[k] = numpy.diag(cc.mo_energy[k][moidx[k]])
        else:  # If mo_coeff is not canonical orbital
            # TODO does this work for k-points? changed to conjugate.
            self.mo_coeff = mo_coeff = mo_coeff[:, moidx]
            dm = cc._scf.make_rdm1(cc.mo_coeff, cc.mo_occ)
            fockao = cc._scf.get_hcore() + cc._scf.get_veff(cc.mol, dm)
            self.fock = reduce(numpy.dot,
                               (numpy.conj(mo_coeff.T), fockao, mo_coeff))

        nocc = cc.nocc()
        nmo = cc.nmo()
        nvir = nmo - nocc
        mem_incore, mem_outcore, mem_basic = pyscf.cc.ccsd._mem_usage(
            nocc, nvir)
        mem_now = lib.current_memory()[0]

        # Convert to spin-orbitals and anti-symmetrize
        nao = cc._scf.cell.nao_nr()
        so_coeff = numpy.zeros((nkpts, nao, nmo), dtype=numpy.complex128)
        so_coeff[:, :, ::2] = so_coeff[:, :, 1::2] = mo_coeff[:, :nao, ::2]

        log = logger.Logger(cc.stdout, cc.verbose)
        if (method == 'incore' and cc._scf._eri is None and
            (mem_incore + mem_now < cc.max_memory) or cc.mol.incore_anyway):

            kconserv = tools.get_kconserv(cc._scf.cell, cc.kpts)

            eri = numpy.zeros((nkpts, nkpts, nkpts, nmo, nmo, nmo, nmo),
                              dtype=numpy.complex128)
            fao2mo = cc._scf.with_df.ao2mo
            for kp in range(nkpts):
                for kq in range(nkpts):
                    for kr in range(nkpts):
                        ks = kconserv[kp, kq, kr]
                        eri_kpt = fao2mo((so_coeff[kp], so_coeff[kq],
                                          so_coeff[kr], so_coeff[ks]),
                                         (cc.kpts[kp], cc.kpts[kq],
                                          cc.kpts[kr], cc.kpts[ks]),
                                         compact=False)
                        eri_kpt = eri_kpt.reshape(nmo, nmo, nmo, nmo)
                        eri[kp, kq, kr] = eri_kpt.copy()

            eri[:, :, :, ::2,
                1::2] = eri[:, :, :,
                            1::2, ::2] = eri[:, :, :, :, :, ::2,
                                             1::2] = eri[:, :, :, :, :,
                                                         1::2, ::2] = 0.

            # Checking some things...
            maxdiff = 0.0
            for kp in range(nkpts):
                for kq in range(nkpts):
                    for kr in range(nkpts):
                        ks = kconserv[kp, kq, kr]
                        for p in range(nmo):
                            for q in range(nmo):
                                for r in range(nmo):
                                    for s in range(nmo):
                                        pqrs = eri[kp, kq, kr, p, q, r, s]
                                        rspq = eri[kr, ks, kp, r, s, p, q]
                                        diff = numpy.linalg.norm(pqrs -
                                                                 rspq).real
                                        if diff > 1e-5:
                                            print "** Warning: ERI diff at ",
                                            print "kp,kq,kr,ks,p,q,r,s =", kp, kq, kr, ks, p, q, r, s
                                        maxdiff = max(maxdiff, diff)
            print "Max difference in (pq|rs) - (rs|pq) = %.15g" % maxdiff
            #print "ERI ="
            #print eri

            # Antisymmetrizing (pq|rs)-(ps|rq), where the latter integral is equal to
            # (rq|ps); done since we aren't tracking the kpoint of orbital 's'
            eri1 = eri - eri.transpose(2, 1, 0, 5, 4, 3, 6)
            # Chemist -> physics notation
            eri1 = eri1.transpose(0, 2, 1, 3, 5, 4, 6)

            self.dtype = eri1.dtype
            self.oooo = eri1[:, :, :, :nocc, :nocc, :nocc, :nocc].copy(
            ) / nkpts
            self.ooov = eri1[:, :, :, :nocc, :nocc, :nocc,
                             nocc:].copy() / nkpts
            self.ovoo = eri1[:, :, :, :nocc,
                             nocc:, :nocc, :nocc].copy() / nkpts
            self.oovv = eri1[:, :, :, :nocc, :nocc, nocc:,
                             nocc:].copy() / nkpts
            self.ovov = eri1[:, :, :, :nocc, nocc:, :nocc,
                             nocc:].copy() / nkpts
            self.ovvv = eri1[:, :, :, :nocc, nocc:, nocc:,
                             nocc:].copy() / nkpts
            self.vvvv = eri1[:, :, :, nocc:, nocc:, nocc:,
                             nocc:].copy() / nkpts
            #ovvv = eri1[:nocc,nocc:,nocc:,nocc:].copy()
            #self.ovvv = numpy.empty((nocc,nvir,nvir*(nvir+1)//2))
            #for i in range(nocc):
            #    for j in range(nvir):
            #        self.ovvv[i,j] = lib.pack_tril(ovvv[i,j])
            #self.vvvv = pyscf.ao2mo.restore(4, eri1[nocc:,nocc:,nocc:,nocc:], nvir)

        log.timer('CCSD integral transformation', *cput0)
Example #19
0
    def __init__(self, cc, mo_coeff=None, method='incore'):
        cput0 = (time.clock(), time.time())
        moidx = numpy.ones(shape=cc.mo_energy.shape, dtype=numpy.bool)
        nkpts = cc.nkpts
        nmo = cc.nmo()
        # TODO change this for k-points ... seems like it should work
        if isinstance(cc.frozen, (int, numpy.integer)):
            for k in range(nkpts):
                moidx[k,:cc.frozen] = False
        elif len(cc.frozen) > 0:
            for k in range(nkpts):
                moidx[k,numpy.asarray(cc.frozen)] = False
        if mo_coeff is None:
            # TODO make this work for frozen maybe... seems like it should work
            self.mo_coeff = numpy.zeros((nkpts,nmo,nmo),dtype=numpy.complex128)
            for k in range(nkpts):
                self.mo_coeff[k] = cc.mo_coeff[k][:,moidx[k]]
            mo_coeff = self.mo_coeff
            self.fock = numpy.zeros((nkpts,nmo,nmo))
            for k in range(nkpts):
                self.fock[k] = numpy.diag(cc.mo_energy[k][moidx[k]])
        else:  # If mo_coeff is not canonical orbital
            # TODO does this work for k-points? changed to conjugate.
            self.mo_coeff = mo_coeff = mo_coeff[:,moidx]
            dm = cc._scf.make_rdm1(cc.mo_coeff, cc.mo_occ)
            fockao = cc._scf.get_hcore() + cc._scf.get_veff(cc.mol, dm)
            self.fock = reduce(numpy.dot, (numpy.conj(mo_coeff.T), fockao, mo_coeff))

        nocc = cc.nocc()
        nmo = cc.nmo()
        nvir = nmo - nocc
        mem_incore, mem_outcore, mem_basic = pyscf.cc.ccsd._mem_usage(nocc, nvir)
        mem_now = lib.current_memory()[0]

        # Convert to spin-orbitals and anti-symmetrize
        so_coeff = numpy.zeros((nkpts,nmo/2,nmo),dtype=numpy.complex128)
        so_coeff[:,:,::2] = so_coeff[:,:,1::2] = mo_coeff[:,:nmo/2,::2]

        log = logger.Logger(cc.stdout, cc.verbose)
        if (method == 'incore' and cc._scf._eri is None and
            (mem_incore+mem_now < cc.max_memory) or cc.mol.incore_anyway):

            kconserv = tools.get_kconserv(cc._scf.cell,cc.kpts)

            eri = numpy.zeros((nkpts,nkpts,nkpts,nmo,nmo,nmo,nmo), dtype=numpy.complex128)
            for kp in range(nkpts):
                for kq in range(nkpts):
                    for kr in range(nkpts):
                        ks = kconserv[kp,kq,kr]
                        eri_kpt = pyscf.pbc.ao2mo.general(cc._scf.cell,
                                    (so_coeff[kp,:,:],so_coeff[kq,:,:],so_coeff[kr,:,:],so_coeff[ks,:,:]),
                                    (cc.kpts[kp],cc.kpts[kq],cc.kpts[kr],cc.kpts[ks]))
                        eri_kpt = eri_kpt.reshape(nmo,nmo,nmo,nmo)
                        eri[kp,kq,kr] = eri_kpt.copy()

            eri[:,:,:,::2,1::2] = eri[:,:,:,1::2,::2] = eri[:,:,:,:,:,::2,1::2] = eri[:,:,:,:,:,1::2,::2] = 0.

            # Checking some things...
            maxdiff = 0.0
            for kp in range(nkpts):
                for kq in range(nkpts):
                    for kr in range(nkpts):
                        ks = kconserv[kp,kq,kr]
                        for p in range(nmo):
                            for q in range(nmo):
                                for r in range(nmo):
                                    for s in range(nmo):
                                        pqrs = eri[kp,kq,kr,p,q,r,s]
                                        rspq = eri[kr,ks,kp,r,s,p,q]
                                        diff = numpy.linalg.norm(pqrs - rspq).real
                                        if diff > 1e-5:
                                            print "** Warning: ERI diff at ",
                                            print "kp,kq,kr,ks,p,q,r,s =", kp, kq, kr, ks, p, q, r, s
                                        maxdiff = max(maxdiff,diff)
            print "Max difference in (pq|rs) - (rs|pq) = %.15g" % maxdiff
            #print "ERI ="
            #print eri

            # Antisymmetrizing (pq|rs)-(ps|rq), where the latter integral is equal to
            # (rq|ps); done since we aren't tracking the kpoint of orbital 's'
            eri1 = eri - eri.transpose(2,1,0,5,4,3,6)
            # Chemist -> physics notation
            eri1 = eri1.transpose(0,2,1,3,5,4,6)

            self.dtype = eri1.dtype
            self.oooo = eri1[:,:,:,:nocc,:nocc,:nocc,:nocc].copy() / nkpts
            self.ooov = eri1[:,:,:,:nocc,:nocc,:nocc,nocc:].copy() / nkpts
            self.ovoo = eri1[:,:,:,:nocc,nocc:,:nocc,:nocc].copy() / nkpts
            self.oovv = eri1[:,:,:,:nocc,:nocc,nocc:,nocc:].copy() / nkpts
            self.ovov = eri1[:,:,:,:nocc,nocc:,:nocc,nocc:].copy() / nkpts
            self.ovvv = eri1[:,:,:,:nocc,nocc:,nocc:,nocc:].copy() / nkpts
            self.vvvv = eri1[:,:,:,nocc:,nocc:,nocc:,nocc:].copy() / nkpts
            #ovvv = eri1[:nocc,nocc:,nocc:,nocc:].copy()
            #self.ovvv = numpy.empty((nocc,nvir,nvir*(nvir+1)//2))
            #for i in range(nocc):
            #    for j in range(nvir):
            #        self.ovvv[i,j] = lib.pack_tril(ovvv[i,j])
            #self.vvvv = pyscf.ao2mo.restore(4, eri1[nocc:,nocc:,nocc:,nocc:], nvir)


        log.timer('CCSD integral transformation', *cput0)