def test_2d_uu(self): m = np.random.random((2, 5, 5)) c1 = np.random.random((2, 5, 10)) c2 = np.random.random((2, 5, 10)) t1 = util.ao2mo(m, c1, c2) t2 = util.einsum('spq,spi,sqj->sij', m, c1, c2) self.assertAlmostEqual(np.max(np.absolute(t1 - t2)), 0, 8)
def test_2d_rr(self): m = np.random.random((5, 5)) c1 = np.random.random((5, 10)) c2 = np.random.random((5, 10)) t1 = util.ao2mo(m, c1, c2) t2 = util.einsum('pq,pi,qj->ij', m, c1, c2) self.assertAlmostEqual(np.max(np.absolute(t1 - t2)), 0, 8)
def test_4d_uu(self): m = np.random.random((2, 2, 5, 5, 5, 5)) c1 = np.random.random((2, 5, 10)) c2 = np.random.random((2, 5, 10)) c3 = np.random.random((2, 5, 10)) c4 = np.random.random((2, 5, 10)) t1 = util.ao2mo(m, c1, c2, c3, c4) t2 = util.einsum('abpqrs,api,aqj,brk,bsl->abijkl', m, c1, c2, c3, c4) self.assertAlmostEqual(np.max(np.absolute(t1 - t2)), 0, 8)
def test_4d_rr(self): m = np.random.random((5, 5, 5, 5)) c1 = np.random.random((5, 10)) c2 = np.random.random((5, 10)) c3 = np.random.random((5, 10)) c4 = np.random.random((5, 10)) t1 = util.ao2mo(m, c1, c2, c3, c4) t2 = util.einsum('pqrs,pi,qj,rk,sl->ijkl', m, c1, c2, c3, c4) self.assertAlmostEqual(np.max(np.absolute(t1 - t2)), 0, 8)
def setup(self): self.eri_ao = util.spin_block(self.hf.eri_ao, self.hf.eri_ao) self.h1e_ao = util.spin_block(self.hf.h1e_ao, self.hf.h1e_ao) if isinstance(self.hf, hf.RHF): self.e = util.spin_block(self.hf.e, self.hf.e) self.c = util.spin_block(self.hf.c, self.hf.c) elif isinstance(self.hf, hf.UHF): self.e = util.spin_block(*list(self.hf.e)) self.c = util.spin_block(*list(self.hf.c)) mask = np.argsort(self.e) self.e = self.e[mask] self.c = self.c[:,mask] self.eri_ao = self.eri_ao.transpose(0,2,1,3) - \ self.eri_ao.transpose(0,2,3,1) self.h1e_mo = util.ao2mo(self.h1e_ao, self.c, self.c) self.eri_mo = util.ao2mo(self.eri_ao, self.c, self.c, self.c, self.c)
def solve_casida(self): #TODO: this step is n^6 and inefficient in memory, rethink e_ia = util.outer_sum([-self.gf.e_occ, self.gf.e_vir]) co = self.gf.v[:self.nphys, self.gf.e < self.chempot] cv = self.gf.v[:self.nphys, self.gf.e >= self.chempot] iajb = util.ao2mo(self.eri, co, cv, co, cv).reshape((e_ia.size, ) * 2) apb = np.diag(e_ia.flatten()) + 4.0 * iajb amb = np.diag(np.sqrt(e_ia.flatten())) h_rpa = util.dots((amb, apb, amb)) e_rpa, v_rpa = util.eigh(h_rpa) e_rpa = np.sqrt(e_rpa) xpy = util.einsum('ij,jk,k->ik', amb, v_rpa, 1.0 / np.sqrt(e_rpa)) xpy *= np.sqrt(2.0) self.rpa = (e_rpa, v_rpa, xpy) return self.rpa
def run(self): t_amp = np.zeros((self.nvir, self.nvir, self.nocc, self.nocc), dtype=types.float64) o = slice(None, self.nocc) v = slice(self.nocc, None) opdm_corr = np.zeros((self.nso,)*2, dtype=types.float64) opdm_ref = opdm_corr.copy() opdm_ref[o,o] = np.eye(self.nocc) tpdm_corr = np.zeros((self.nso,)*4, dtype=types.float64) x = opdm_corr.copy() eija = util.outer_sum([-self.e[v], -self.e[v], self.e[o], self.e[o]]) eija = 1.0 / eija if self.diis: diis = util.DIIS(self.diis_space) for niter in range(1, self.maxiter+1): f = self.h1e_mo + util.einsum('piqi->pq', self.eri_mo[:,o,:,o]) fp = f.copy() np.fill_diagonal(fp, 0.0) e = f.diagonal() t1 = self.eri_mo[v,v,o,o] t2 = util.einsum('ac,cbij->abij', fp[v,v], t_amp) t3 = util.einsum('ki,abkj->abij', fp[o,o], t_amp) t_amp = t1.copy() t_amp += t2 - t2.transpose(1,0,2,3) t_amp -= t3 - t3.transpose(0,1,3,2) t_amp *= eija if niter > 1: if self.diis: t_amp = diis.update(t_amp) if self.damping > 0.0: damping = self.damping t_amp = (1.0 - damping) * t_amp + damping * self._t_prev if self.damping > 0.0: self._t_prev = t_amp.copy() opdm_corr[v,v] = util.einsum('ijac,bcij->ba', t_amp.T, t_amp) * 0.5 opdm_corr[o,o] = util.einsum('jkab,abik->ji', t_amp.T, t_amp) * -0.5 opdm = opdm_corr + opdm_ref tpdm_corr[v,v,o,o] = t_amp tpdm_corr[o,o,v,v] = t_amp.T tpdm2 = util.einsum('rp,sq->rspq', opdm_corr, opdm_ref) tpdm3 = util.einsum('rp,sq->rspq', opdm_ref, opdm_ref) tpdm = tpdm_corr.copy() tpdm += tpdm2 - tpdm2.transpose(1,0,2,3) tpdm -= tpdm2.transpose(0,1,3,2) - tpdm2.transpose(1,0,3,2) tpdm += tpdm3 - tpdm3.transpose(1,0,2,3) fnr = util.einsum('pr,rq->pq', self.h1e_mo, opdm) fnr += util.einsum('prst,stqr->pq', self.eri_mo, tpdm) * 0.5 x[v,o] = ((fnr - fnr.T)[v,o]) / util.outer_sum([-self.e[v], self.e[o]]) u = expm(x - x.T) c = np.dot(self.c, u) self.c = c self.h1e_mo = util.ao2mo(self.h1e_ao, c, c) self.eri_mo = util.ao2mo(self.eri_ao, c, c, c, c) e_prev = self.e_tot self.e_1body = util.einsum('pq,qp->', self.h1e_mo, opdm) self.e_1body += self.hf.e_nuc self.e_2body = 0.25 * util.einsum('pqrs,rspq->', self.eri_mo, tpdm) if abs(self.e_tot - e_prev) < self.etol: break return self
def get_eri(self, coeffs): return util.ao2mo(self.eri_ao, *coeffs)
def eri_mo(self): if not self.with_df: return util.ao2mo(self.eri_ao, self.c, self.c, self.c, self.c) else: return util.ao2mo(self.eri_ao, self.c, self.c)
def rdm1_mo(self): sds = util.ao2mo(self.rdm1_ao, self.ovlp_ao, self.ovlp_ao) return util.ao2mo(sds, self.c, self.c)
def fock_mo(self): return util.ao2mo(self.fock_ao, self.c, self.c)
def h1e_mo(self): return util.ao2mo(self.h1e_ao, self.c, self.c)