Esempio n. 1
0
    def make_ea(self, cc):
        # cc = self.cc
        t1, t2, eris = cc.t1, cc.t2, cc.eris

        self.Lvv = imdk.Lvv(cc, t1, t2, eris)
        self.Loo = imdk.Loo(cc, t1, t2, eris)
        self.Fov = imdk.cc_Fov(cc, t1, t2, eris)
        self.Wvovv = imdk.Wvovv(cc, t1, t2, eris)
        self.Wvvvo = imdk.Wvvvo(cc, t1, t2, eris)
        self.Wovvo = imdk.Wovvo(cc, t1, t2, eris)
        self.Wvvvv = imdk.Wvvvv(cc, t1, t2, eris)
        self.Woovv = eris.oovv
        self.Wovov = imdk.Wovov(cc, t1, t2, eris)
Esempio n. 2
0
def update_amps(cc, t1, t2, eris):
    time0 = time1 = time.clock(), time.time()
    log = logger.Logger(cc.stdout, cc.verbose)
    nkpts, nocc, nvir = t1.shape
    fock = eris.fock
    mo_e_o = [e[:nocc] for e in eris.mo_energy]
    mo_e_v = [e[nocc:] + cc.level_shift for e in eris.mo_energy]

    # Get location of padded elements in occupied and virtual space
    nonzero_opadding, nonzero_vpadding = padding_k_idx(cc, kind="split")

    fov = fock[:, :nocc, nocc:]
    foo = fock[:, :nocc, :nocc]
    fvv = fock[:, nocc:, nocc:]

    kconserv = cc.khelper.kconserv

    Foo = imdk.cc_Foo(t1, t2, eris, kconserv)
    Fvv = imdk.cc_Fvv(t1, t2, eris, kconserv)
    Fov = imdk.cc_Fov(t1, t2, eris, kconserv)
    Loo = imdk.Loo(t1, t2, eris, kconserv)
    Lvv = imdk.Lvv(t1, t2, eris, kconserv)

    # Move energy terms to the other side
    for k in range(nkpts):
        Foo[k][np.diag_indices(nocc)] -= mo_e_o[k]
        Fvv[k][np.diag_indices(nvir)] -= mo_e_v[k]
        Loo[k][np.diag_indices(nocc)] -= mo_e_o[k]
        Lvv[k][np.diag_indices(nvir)] -= mo_e_v[k]
    time1 = log.timer_debug1('intermediates', *time1)

    # T1 equation
    t1new = np.array(fov).astype(t1.dtype).conj()

    for ka in range(nkpts):
        ki = ka
        # kc == ki; kk == ka
        t1new[ka] += -2. * einsum('kc,ka,ic->ia', fov[ki], t1[ka], t1[ki])
        t1new[ka] += einsum('ac,ic->ia', Fvv[ka], t1[ki])
        t1new[ka] += -einsum('ki,ka->ia', Foo[ki], t1[ka])

        tau_term = np.empty((nkpts, nocc, nocc, nvir, nvir), dtype=t1.dtype)
        for kk in range(nkpts):
            tau_term[kk] = 2 * t2[kk, ki, kk] - t2[ki, kk, kk].transpose(1, 0, 2, 3)
        tau_term[ka] += einsum('ic,ka->kica', t1[ki], t1[ka])

        for kk in range(nkpts):
            kc = kk
            t1new[ka] += einsum('kc,kica->ia', Fov[kc], tau_term[kk])

            t1new[ka] += einsum('akic,kc->ia', 2 * eris.voov[ka, kk, ki], t1[kc])
            t1new[ka] += einsum('kaic,kc->ia', -eris.ovov[kk, ka, ki], t1[kc])

            for kc in range(nkpts):
                kd = kconserv[ka, kc, kk]

                Svovv = 2 * eris.vovv[ka, kk, kc] - eris.vovv[ka, kk, kd].transpose(0, 1, 3, 2)
                tau_term_1 = t2[ki, kk, kc].copy()
                if ki == kc and kk == kd:
                    tau_term_1 += einsum('ic,kd->ikcd', t1[ki], t1[kk])
                t1new[ka] += einsum('akcd,ikcd->ia', Svovv, tau_term_1)

                # kk - ki + kl = kc
                #  => kl = ki - kk + kc
                kl = kconserv[ki, kk, kc]
                Sooov = 2 * eris.ooov[kk, kl, ki] - eris.ooov[kl, kk, ki].transpose(1, 0, 2, 3)
                tau_term_1 = t2[kk, kl, ka].copy()
                if kk == ka and kl == kc:
                    tau_term_1 += einsum('ka,lc->klac', t1[ka], t1[kc])
                t1new[ka] += -einsum('klic,klac->ia', Sooov, tau_term_1)
    time1 = log.timer_debug1('t1', *time1)

    # T2 equation
    t2new = np.empty_like(t2)
    for ki, kj, ka in kpts_helper.loop_kkk(nkpts):
        t2new[ki, kj, ka] = eris.oovv[ki, kj, ka].conj()

    mem_now = lib.current_memory()[0]
    if (nocc ** 4 * nkpts ** 3) * 16 / 1e6 + mem_now < cc.max_memory * .9:
        Woooo = imdk.cc_Woooo(t1, t2, eris, kconserv)
    else:
        fimd = lib.H5TmpFile()
        Woooo = fimd.create_dataset('oooo', (nkpts, nkpts, nkpts, nocc, nocc, nocc, nocc), t1.dtype.char)
        Woooo = imdk.cc_Woooo(t1, t2, eris, kconserv, Woooo)

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

        t2new_tmp = np.zeros((nocc, nocc, nvir, nvir), dtype=t2.dtype)
        for kl in range(nkpts):
            kk = kconserv[kj, kl, ki]
            tau_term = t2[kk, kl, ka].copy()
            if kl == kb and kk == ka:
                tau_term += einsum('ic,jd->ijcd', t1[ka], t1[kb])
            t2new_tmp += 0.5 * einsum('klij,klab->ijab', Woooo[kk, kl, ki], tau_term)
        t2new[ki, kj, ka] += t2new_tmp
        t2new[kj, ki, kb] += t2new_tmp.transpose(1, 0, 3, 2)
    Woooo = None
    fimd = None
    time1 = log.timer_debug1('t2 oooo', *time1)

    # einsum('abcd,ijcd->ijab', Wvvvv, tau)
    add_vvvv_(cc, t2new, t1, t2, eris)
    time1 = log.timer_debug1('t2 vvvv', *time1)

    for ki, kj, ka in kpts_helper.loop_kkk(nkpts):
        kb = kconserv[ki, ka, kj]

        t2new_tmp = einsum('ac,ijcb->ijab', Lvv[ka], t2[ki, kj, ka])
        t2new_tmp += einsum('ki,kjab->ijab', -Loo[ki], t2[ki, kj, ka])

        kc = kconserv[ka, ki, kb]
        tmp2 = np.asarray(eris.vovv[kc, ki, kb]).transpose(3, 2, 1, 0).conj() \
               - einsum('kbic,ka->abic', eris.ovov[ka, kb, ki], t1[ka])
        t2new_tmp += einsum('abic,jc->ijab', tmp2, t1[kj])

        kk = kconserv[ki, ka, kj]
        tmp2 = np.asarray(eris.ooov[kj, ki, kk]).transpose(3, 2, 1, 0).conj() \
               + einsum('akic,jc->akij', eris.voov[ka, kk, ki], t1[kj])
        t2new_tmp -= einsum('akij,kb->ijab', tmp2, t1[kb])
        t2new[ki, kj, ka] += t2new_tmp
        t2new[kj, ki, kb] += t2new_tmp.transpose(1, 0, 3, 2)

    mem_now = lib.current_memory()[0]
    if (nocc ** 2 * nvir ** 2 * nkpts ** 3) * 16 / 1e6 * 2 + mem_now < cc.max_memory * .9:
        Wvoov = imdk.cc_Wvoov(t1, t2, eris, kconserv)
        Wvovo = imdk.cc_Wvovo(t1, t2, eris, kconserv)
    else:
        fimd = lib.H5TmpFile()
        Wvoov = fimd.create_dataset('voov', (nkpts, nkpts, nkpts, nvir, nocc, nocc, nvir), t1.dtype.char)
        Wvovo = fimd.create_dataset('vovo', (nkpts, nkpts, nkpts, nvir, nocc, nvir, nocc), t1.dtype.char)
        Wvoov = imdk.cc_Wvoov(t1, t2, eris, kconserv, Wvoov)
        Wvovo = imdk.cc_Wvovo(t1, t2, eris, kconserv, Wvovo)

    for ki, kj, ka in kpts_helper.loop_kkk(nkpts):
        kb = kconserv[ki, ka, kj]
        t2new_tmp = np.zeros((nocc, nocc, nvir, nvir), dtype=t2.dtype)
        for kk in range(nkpts):
            kc = kconserv[ka, ki, kk]
            tmp_voov = 2. * Wvoov[ka, kk, ki] - Wvovo[ka, kk, kc].transpose(0, 1, 3, 2)
            t2new_tmp += einsum('akic,kjcb->ijab', tmp_voov, t2[kk, kj, kc])

            kc = kconserv[ka, ki, kk]
            t2new_tmp -= einsum('akic,kjbc->ijab', Wvoov[ka, kk, ki], t2[kk, kj, kb])

            kc = kconserv[kk, ka, kj]
            t2new_tmp -= einsum('bkci,kjac->ijab', Wvovo[kb, kk, kc], t2[kk, kj, ka])

        t2new[ki, kj, ka] += t2new_tmp
        t2new[kj, ki, kb] += t2new_tmp.transpose(1, 0, 3, 2)
    Wvoov = Wvovo = None
    fimd = None
    time1 = log.timer_debug1('t2 voov', *time1)

    for ki in range(nkpts):
        ka = ki
        # Remove zero/padded elements from denominator
        eia = LARGE_DENOM * np.ones((nocc, nvir), dtype=eris.mo_energy[0].dtype)
        n0_ovp_ia = np.ix_(nonzero_opadding[ki], nonzero_vpadding[ka])
        eia[n0_ovp_ia] = (mo_e_o[ki][:,None] - mo_e_v[ka])[n0_ovp_ia]
        t1new[ki] /= eia

    for ki, kj, ka in kpts_helper.loop_kkk(nkpts):
        kb = kconserv[ki, ka, kj]
        # For LARGE_DENOM, see t1new update above
        eia = LARGE_DENOM * np.ones((nocc, nvir), dtype=eris.mo_energy[0].dtype)
        n0_ovp_ia = np.ix_(nonzero_opadding[ki], nonzero_vpadding[ka])
        eia[n0_ovp_ia] = (mo_e_o[ki][:,None] - mo_e_v[ka])[n0_ovp_ia]

        ejb = LARGE_DENOM * np.ones((nocc, nvir), dtype=eris.mo_energy[0].dtype)
        n0_ovp_jb = np.ix_(nonzero_opadding[kj], nonzero_vpadding[kb])
        ejb[n0_ovp_jb] = (mo_e_o[kj][:,None] - mo_e_v[kb])[n0_ovp_jb]
        eijab = eia[:, None, :, None] + ejb[:, None, :]

        t2new[ki, kj, ka] /= eijab

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

    return t1new, t2new
Esempio n. 3
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:]
    foo = fock[:, :nocc, :nocc]
    fvv = fock[:, nocc:, nocc:]

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

    Foo = imdk.cc_Foo(cc, t1, t2, eris)
    Fvv = imdk.cc_Fvv(cc, t1, t2, eris)
    Fov = imdk.cc_Fov(cc, t1, t2, eris)
    Loo = imdk.Loo(cc, t1, t2, eris)
    Lvv = imdk.Lvv(cc, t1, t2, eris)
    Woooo = imdk.cc_Woooo(cc, t1, t2, eris)
    Wvvvv = imdk.cc_Wvvvv(cc, t1, t2, eris)
    Wvoov = imdk.cc_Wvoov(cc, t1, t2, eris)
    Wvovo = imdk.cc_Wvovo(cc, t1, t2, eris)

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

    kconserv = cc.kconserv

    # T1 equation
    # TODO: Check this conj(). Hirata and Bartlett has
    # f_{vo}(a,i), which should be equal to f_{ov}^*(i,a)
    t1new = np.empty((nkpts, nocc, nvir), dtype=t1.dtype)
    t1new[:] = fov[:].conj().copy()
    for ka in range(nkpts):
        ki = ka
        # kc == ki; kk == ka
        t1new[ka] += -2.0 * einsum("kc,ka,ic->ia", fov[ki], t1[ka], t1[ki])
        t1new[ka] += einsum("ac,ic->ia", Fvv[ka], t1[ki])
        t1new[ka] += -einsum("ki,ka->ia", Foo[ki], t1[ka])

        tau_term = np.empty((nkpts, nocc, nocc, nvir, nvir), dtype=t1.dtype)
        for kk in range(nkpts):
            tau_term[kk] = 2 * t2[kk, ki, kk] - t2[ki, kk, kk].transpose(1, 0, 2, 3)
        tau_term[ka] += einsum("ic,ka->kica", t1[ki], t1[ka])

        for kk in range(nkpts):
            kc = kk
            t1new[ka] += einsum("kc,kica->ia", Fov[kc], tau_term[kk])

            t1new[ka] += einsum("akic,kc->ia", 2 * eris.voov[ka, kk, ki], t1[kc])
            t1new[ka] += einsum("akci,kc->ia", -eris.vovo[ka, kk, kc], t1[kc])

            for kc in range(nkpts):
                kd = kconserv[ka, kc, kk]

                Svovv = 2 * eris.vovv[ka, kk, kc] - eris.vovv[ka, kk, kd].transpose(0, 1, 3, 2)
                tau_term_1 = t2[ki, kk, kc].copy()
                if ki == kc and kk == kd:
                    tau_term_1 += einsum("ic,kd->ikcd", t1[ki], t1[kk])
                t1new[ka] += einsum("akcd,ikcd->ia", Svovv, tau_term_1)

                # kk - ki + kl = kc
                #  => kl = ki - kk + kc
                kl = kconserv[ki, kk, kc]
                Sooov = 2 * eris.ooov[kk, kl, ki] - eris.ooov[kl, kk, ki].transpose(1, 0, 2, 3)
                tau_term_1 = t2[kk, kl, ka].copy()
                if kk == ka and kl == kc:
                    tau_term_1 += einsum("ka,lc->klac", t1[ka], t1[kc])
                t1new[ka] += -einsum("klic,klac->ia", Sooov, tau_term_1)

    # T2 equation
    # For conj(), see Hirata and Bartlett, Eq. (36)
    t2new = np.array(eris.oovv, copy=True).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]

                for kl in range(nkpts):
                    # kk - ki + kl = kj
                    # => kk = kj - kl + ki
                    kk = kconserv[kj, kl, ki]
                    t2new[ki, kj, ka] += einsum("klij,klab->ijab", Woooo[kk, kl, ki], t2[kk, kl, ka])
                    if kl == kb and kk == ka:
                        t2new[ki, kj, ka] += einsum("klij,ka,lb->ijab", Woooo[ka, kb, ki], t1[ka], t1[kb])

                for kc in range(nkpts):
                    kd = kconserv[ka, kc, kb]
                    tau_term = t2[ki, kj, kc].copy()
                    if ki == kc and kj == kd:
                        tau_term += einsum("ic,jd->ijcd", t1[ki], t1[kj])
                    t2new[ki, kj, ka] += einsum("abcd,ijcd->ijab", Wvvvv[ka, kb, kc], tau_term)

                t2new[ki, kj, ka] += einsum("ac,ijcb->ijab", Lvv[ka], t2[ki, kj, ka])
                # P(ij)P(ab)
                t2new[ki, kj, ka] += einsum("bc,jica->ijab", Lvv[kb], t2[kj, ki, kb])

                t2new[ki, kj, ka] += einsum("ki,kjab->ijab", -Loo[ki], t2[ki, kj, ka])
                # P(ij)P(ab)
                t2new[ki, kj, ka] += einsum("kj,kiba->ijab", -Loo[kj], t2[kj, ki, kb])

                tmp2 = eris.vvov[ka, kb, ki] - einsum("kbic,ka->abic", eris.ovov[ka, kb, ki], t1[ka])
                tmp = einsum("abic,jc->ijab", tmp2, t1[kj])
                t2new[ki, kj, ka] += tmp
                # P(ij)P(ab)
                tmp2 = eris.vvov[kb, ka, kj] - einsum("kajc,kb->bajc", eris.ovov[kb, ka, kj], t1[kb])
                tmp = einsum("bajc,ic->ijab", tmp2, t1[ki])
                t2new[ki, kj, ka] += tmp

                # ka - ki + kk = kj
                # => kk = ki - ka + kj
                kk = kconserv[ki, ka, kj]
                tmp2 = eris.vooo[ka, kk, ki] + einsum("akic,jc->akij", eris.voov[ka, kk, ki], t1[kj])
                tmp = einsum("akij,kb->ijab", tmp2, t1[kb])
                t2new[ki, kj, ka] -= tmp
                # P(ij)P(ab)
                kk = kconserv[kj, kb, ki]
                tmp2 = eris.vooo[kb, kk, kj] + einsum("bkjc,ic->bkji", eris.voov[kb, kk, kj], t1[ki])
                tmp = einsum("bkji,ka->ijab", tmp2, t1[ka])
                t2new[ki, kj, ka] -= tmp

                for kk in range(nkpts):
                    kc = kconserv[ka, ki, kk]
                    tmp_voov = 2.0 * Wvoov[ka, kk, ki] - Wvovo[ka, kk, kc].transpose(0, 1, 3, 2)
                    tmp = einsum("akic,kjcb->ijab", tmp_voov, t2[kk, kj, kc])
                    # tmp = 2*einsum('akic,kjcb->ijab',Wvoov[ka,kk,ki],t2[kk,kj,kc]) - \
                    #        einsum('akci,kjcb->ijab',Wvovo[ka,kk,kc],t2[kk,kj,kc])
                    t2new[ki, kj, ka] += tmp
                    # P(ij)P(ab)
                    kc = kconserv[kb, kj, kk]
                    tmp_voov = 2.0 * Wvoov[kb, kk, kj] - Wvovo[kb, kk, kc].transpose(0, 1, 3, 2)
                    tmp = einsum("bkjc,kica->ijab", tmp_voov, t2[kk, ki, kc])
                    # tmp = 2*einsum('bkjc,kica->ijab',Wvoov[kb,kk,kj],t2[kk,ki,kc]) - \
                    #        einsum('bkcj,kica->ijab',Wvovo[kb,kk,kc],t2[kk,ki,kc])
                    t2new[ki, kj, ka] += tmp

                    kc = kconserv[ka, ki, kk]
                    tmp = einsum("akic,kjbc->ijab", Wvoov[ka, kk, ki], t2[kk, kj, kb])
                    t2new[ki, kj, ka] -= tmp
                    # P(ij)P(ab)
                    kc = kconserv[kb, kj, kk]
                    tmp = einsum("bkjc,kiac->ijab", Wvoov[kb, kk, kj], t2[kk, ki, ka])
                    t2new[ki, kj, ka] -= tmp

                    kc = kconserv[kk, ka, kj]
                    tmp = einsum("bkci,kjac->ijab", Wvovo[kb, kk, kc], t2[kk, kj, ka])
                    t2new[ki, kj, ka] -= tmp
                    # P(ij)P(ab)
                    kc = kconserv[kk, kb, ki]
                    tmp = einsum("akcj,kibc->ijab", Wvovo[ka, kk, kc], t2[kk, ki, kb])
                    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]

    for ki in range(nkpts):
        for kj in range(nkpts):
            for ka in range(nkpts):
                kb = kconserv[ki, ka, kj]
                eia = np.diagonal(foo[ki]).reshape(-1, 1) - np.diagonal(fvv[ka])
                ejb = np.diagonal(foo[kj]).reshape(-1, 1) - np.diagonal(fvv[kb])
                eijab = lib.direct_sum("ia,jb->ijab", eia, ejb)
                t2new[ki, kj, ka] /= eijab

    time0 = log.timer_debug1("update t1 t2", *time0)
    #    sys.exit("exiting for testing...")

    return t1new, t2new