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)
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)
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
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)
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)
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
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
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
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)