Ejemplo n.º 1
0
    def _make_shared_1e(self):
        cput0 = (time.clock(), time.time())
        log = Logger(self.stdout, self.verbose)
        t1, t2, eris = self.t1, self.t2, self.eris
        self.Loo = imd.Loo(t1, t2, eris)
        self.Lvv = imd.Lvv(t1, t2, eris)
        self.Fov = imd.cc_Fov(t1, t2, eris)

        log.timer('EOM-CCSD shared one-electron intermediates', *cput0)
Ejemplo n.º 2
0
    def _make_shared_2e(self):
        cput0 = (time.clock(), time.time())
        log = Logger(self.stdout, self.verbose)
        t1, t2, eris = self.t1, self.t2, self.eris
        # 2 virtuals
        self.Wovov = imd.Wovov(t1, t2, eris)
        self.Wovvo = imd.Wovvo(t1, t2, eris)
        self.Woovv = eris.ovov.transpose(0, 2, 1, 3)

        log.timer('EOM-CCSD shared two-electron intermediates', *cput0)
Ejemplo n.º 3
0
def energy(cc, t1, t2, eris):
    log = Logger(cc.stdout, cc.verbose)
    nkpts = len(cc.kpts)
    e = 2 * lib.einsum('ia,ia', eris.fov, t1)
    tau = lib.einsum('ia,jb->ijab', t1, t1)
    tau += t2
    e += 2 * lib.einsum('ijab,iajb', tau, eris.ovov)
    e += -lib.einsum('ijab,ibja', tau, eris.ovov)
    if abs(e.imag) > 1e-4:
        log.warn('Non-zero imaginary part found in KRCCSD energy %s', e)
    return e.real / nkpts
Ejemplo n.º 4
0
    def make_ip(self, partition=None):
        self._make_shared_1e()
        if self._made_shared_2e is False and partition != 'mp':
            self._make_shared_2e()
            self._made_shared_2e = True

        cput0 = (time.clock(), time.time())
        log = Logger(self.stdout, self.verbose)
        t1, t2, eris = self.t1, self.t2, self.eris

        # 0 or 1 virtuals
        if partition != 'mp':
            self.Woooo = imd.Woooo(t1, t2, eris)
        self.Wooov = imd.Wooov(t1, t2, eris)
        self.Wovoo = imd.Wovoo(t1, t2, eris)
        self.made_ip_imds = True
        log.timer('EOM-CCSD IP intermediates', *cput0)
Ejemplo n.º 5
0
    def make_ea(self, partition=None):
        self._make_shared_1e()
        if self._made_shared_2e is False and partition != 'mp':
            self._make_shared_2e()
            self._made_shared_2e = True

        cput0 = (time.clock(), time.time())
        log = Logger(self.stdout, self.verbose)
        t1, t2, eris = self.t1, self.t2, self.eris

        # 3 or 4 virtuals
        self.Wvovv = imd.Wvovv(t1, t2, eris)
        if partition == 'mp':
            self.Wvvvo = imd.Wvvvo(t1, t2, eris)
        else:
            self.Wvvvv = imd.Wvvvv(t1, t2, eris)
            self.Wvvvo = imd.Wvvvo(t1, t2, eris, self.Wvvvv)
        self.made_ea_imds = True
        log.timer('EOM-CCSD EA intermediates', *cput0)
Ejemplo n.º 6
0
def kernel(eom,
           nroots=1,
           koopmans=True,
           guess=None,
           left=False,
           eris=None,
           imds=None,
           partition=None,
           kptlist=None,
           dtype=None,
           **kwargs):

    cput0 = (time.clock(), time.time())
    log = Logger(eom.stdout, eom.verbose)
    eom.dump_flags()

    if imds is None:
        imds = eom.make_imds(eris)

    size = eom.vector_size()
    nroots = min(nroots, size)
    from pyscf.pbc.lib.linalg_helper import eigs

    matvec, diag = eom.gen_matvec(imds, left=left, **kwargs)
    user_guess = False
    if guess:
        user_guess = True
        assert len(guess) == nroots
        for g in guess:
            assert g.size == size
    else:
        user_guess = False
        guess = eom.get_init_guess(nroots, koopmans, diag)
    conv, evals, evecs = eigs(matvec,
                              size,
                              nroots,
                              x0=guess,
                              Adiag=diag,
                              verbose=eom.verbose)
    evals = evals.real
    for n, en, vn in zip(range(nroots), evals, evecs.T):
        r1, r2 = eom.vector_to_amplitudes(vn)
        qp_weight = r1.norm()**2
        log.info('EOM-CCSD root %d E = %.16g  qpwt = %0.6g', n, en, qp_weight)
    log.timer('EOM-CCSD', *cput0)
    return conv, evals, evecs
Ejemplo n.º 7
0
 def init_amps(self, eris):
     time0 = time.clock(), time.time()
     log = Logger(self.stdout, self.verbose)
     nocc = self.nocc
     nvir = self.nmo - nocc
     kpts = self.kpts
     nkpts = self.nkpts
     gvec = self._scf.cell.reciprocal_vectors()
     sym1 = ['+-', [
         kpts,
     ] * 2, None, gvec]
     t1 = lib.zeros([nocc, nvir], eris.dtype, sym1)
     t2 = eris.ovov.transpose(0, 2, 1, 3).conj() / eris.eijab
     self.emp2 = 2 * lib.einsum('ijab,iajb', t2, eris.ovov)
     self.emp2 -= lib.einsum('ijab,ibja', t2, eris.ovov)
     self.emp2 = self.emp2.real / nkpts
     log.info('Init t2, MP2 energy (with fock eigenvalue shift) = %.15g',
              self.emp2)
     log.timer('init mp2', *time0)
     return self.emp2, t1, t2
Ejemplo n.º 8
0
def kernel(eom,
           nroots=1,
           koopmans=True,
           guess=None,
           left=False,
           eris=None,
           imds=None,
           partition=None,
           kptlist=None,
           dtype=None,
           **kwargs):

    cput0 = (time.clock(), time.time())
    eom.dump_flags()

    log = Logger(eom.stdout, eom.verbose)
    if imds is None:
        imds = eom.make_imds(eris)

    size = eom.vector_size()
    nroots = min(nroots, size)
    nkpts = eom.nkpts

    if kptlist is None:
        kptlist = range(nkpts)

    if dtype is None:
        dtype = imds.t1.dtype

    evals = np.zeros((len(kptlist), nroots), np.float)
    evecs = []
    convs = np.zeros((len(kptlist), nroots), dtype)
    from pyscf.pbc.lib.linalg_helper import eigs
    for k, kshift in enumerate(kptlist):
        matvec, diag = eom.gen_matvec(kshift, imds, left=left, **kwargs)
        eom.update_symlib(kshift)
        user_guess = False
        if guess:
            user_guess = True
            assert len(guess) == nroots
            for g in guess:
                assert g.size == size
        else:
            user_guess = False
            guess = eom.get_init_guess(kshift, nroots, koopmans, diag)

        conv_k, evals_k, evecs_k = eigs(matvec,
                                        size,
                                        nroots,
                                        x0=guess,
                                        Adiag=diag,
                                        verbose=eom.verbose)
        evals_k = evals_k.real
        evals[k] = evals_k.real
        evecs.append(evecs_k)
        convs[k] = conv_k
        for n, en, vn in zip(range(nroots), evals_k, evecs_k.T):
            r1, r2 = eom.vector_to_amplitudes(vn, kshift)
            qp_weight = r1.norm()**2
            log.info('EOM-CCSD root %d E = %.16g  qpwt = %0.6g', n, en,
                     qp_weight)
    log.timer('EOM-CCSD', *cput0)
    evecs = np.vstack(tuple(evecs))
    return convs, evals, evecs
Ejemplo n.º 9
0
    def __init__(self, cc, mo_coeff=None):
        from pyscf.pbc.cc.ccsd import _adjust_occ
        import pyscf.pbc.tools.pbc as tools
        if mo_coeff is None:
            mo_coeff = cc.mo_coeff
        cput0 = (time.clock(), time.time())
        log = Logger(cc.stdout, cc.verbose)
        self.lib = lib
        nocc, nmo, nkpts = cc.nocc, cc.nmo, cc.nkpts
        nvir = nmo - nocc
        cell, kpts = cc._scf.cell, cc.kpts
        gvec = cell.reciprocal_vectors()
        sym1 = ['+-', [
            kpts,
        ] * 2, None, gvec]
        sym2 = ['+-+-', [
            kpts,
        ] * 4, None, gvec]
        mo_coeff = self.mo_coeff = padded_mo_coeff(cc, mo_coeff)
        nonzero_opadding, nonzero_vpadding = padding_k_idx(cc, kind="split")
        madelung = tools.madelung(cell, kpts)

        dm = cc._scf.make_rdm1(cc.mo_coeff, cc.mo_occ)
        with pyscflib.temporary_env(cc._scf, exxdiv=None):
            fockao = cc._scf.get_hcore() + cc._scf.get_veff(cell, dm)
        fock = np.asarray([
            reduce(np.dot, (mo.T.conj(), fockao[k], mo))
            for k, mo in enumerate(mo_coeff)
        ])

        self.dtype = dtype = np.result_type(*fock).char
        self.foo = tensor(fock[:, :nocc, :nocc], sym1)
        self.fov = tensor(fock[:, :nocc, nocc:], sym1)
        self.fvv = tensor(fock[:, nocc:, nocc:], sym1)

        mo_energy = [fock[k].diagonal().real for k in range(nkpts)]
        mo_energy = [
            _adjust_occ(mo_e, nocc, -madelung)
            for k, mo_e in enumerate(mo_energy)
        ]

        mo_e_o = [e[:nocc] for e in mo_energy]
        mo_e_v = [e[nocc:] + cc.level_shift for e in mo_energy]
        foo_ = np.asarray([np.diag(e) for e in mo_e_o])
        fvv_ = np.asarray([np.diag(e) for e in mo_e_v])
        self._foo = tensor(foo_, sym1)
        self._fvv = tensor(fvv_, sym1)

        eia = np.zeros([nkpts, nocc, nvir])
        for ki in range(nkpts):
            eia[ki] = _get_epq([0, nocc, ki, mo_e_o, nonzero_opadding],
                               [0, nvir, ki, mo_e_v, nonzero_vpadding],
                               fac=[1.0, -1.0])

        self.eia = tensor(eia, sym1)
        self.oooo = zeros([nocc, nocc, nocc, nocc], dtype, sym2)
        self.ooov = zeros([nocc, nocc, nocc, nvir], dtype, sym2)
        self.ovov = zeros([nocc, nvir, nocc, nvir], dtype, sym2)
        self.oovv = zeros([nocc, nocc, nvir, nvir], dtype, sym2)
        self.ovvo = zeros([nocc, nvir, nvir, nocc], dtype, sym2)
        self.ovvv = zeros([nocc, nvir, nvir, nvir], dtype, sym2)
        self.vvvv = zeros([nvir, nvir, nvir, nvir], dtype, sym2)
        self.eijab = zeros([nocc, nocc, nvir, nvir], np.float64, sym2)

        with_df = cc._scf.with_df
        fao2mo = cc._scf.with_df.ao2mo
        kconserv = cc.khelper.kconserv
        khelper = cc.khelper

        jobs = list(khelper.symm_map.keys())
        for itask in jobs:
            ikp, ikq, ikr = itask
            iks = kconserv[ikp, ikq, ikr]
            eri_kpt = fao2mo(
                (mo_coeff[ikp], mo_coeff[ikq], mo_coeff[ikr], mo_coeff[iks]),
                (kpts[ikp], kpts[ikq], kpts[ikr], kpts[iks]),
                compact=False)
            if dtype == np.float: eri_kpt = eri_kpt.real
            eri_kpt = eri_kpt.reshape(nmo, nmo, nmo, nmo) / nkpts
            done = np.zeros([nkpts, nkpts, nkpts])
            for (kp, kq, kr) in khelper.symm_map[(ikp, ikq, ikr)]:
                if done[kp, kq, kr]: continue
                eri_kpt_symm = khelper.transform_symm(eri_kpt, kp, kq, kr)
                oooo = eri_kpt_symm[:nocc, :nocc, :nocc, :nocc]
                ooov = eri_kpt_symm[:nocc, :nocc, :nocc, nocc:]
                ovov = eri_kpt_symm[:nocc, nocc:, :nocc, nocc:]
                oovv = eri_kpt_symm[:nocc, :nocc, nocc:, nocc:]
                ovvo = eri_kpt_symm[:nocc, nocc:, nocc:, :nocc]
                ovvv = eri_kpt_symm[:nocc, nocc:, nocc:, nocc:]
                vvvv = eri_kpt_symm[nocc:, nocc:, nocc:, nocc:]
                ks = kconserv[kp, kq, kr]
                eia = _get_epq([0, nocc, kp, mo_e_o, nonzero_opadding],
                               [0, nvir, kq, mo_e_v, nonzero_vpadding],
                               fac=[1.0, -1.0])
                ejb = _get_epq([0, nocc, kr, mo_e_o, nonzero_opadding],
                               [0, nvir, ks, mo_e_v, nonzero_vpadding],
                               fac=[1.0, -1.0])
                eijab = eia[:, None, :, None] + ejb[None, :, None, :]

                self.oooo.array[kp, kq, kr] = oooo
                self.ooov.array[kp, kq, kr] = ooov
                self.ovov.array[kp, kq, kr] = ovov
                self.oovv.array[kp, kq, kr] = oovv
                self.ovvo.array[kp, kq, kr] = ovvo
                self.ovvv.array[kp, kq, kr] = ovvv
                self.vvvv.array[kp, kq, kr] = vvvv
                self.eijab.array[kp, kr, kq] = eijab
                done[kp, kq, kr] = 1

        log.timer("ao2mo transformation", *cput0)