def _gamma2_intermediates(cc, t1, t2, l1, l2): d2 = ccsd_rdm._gamma2_intermediates(cc, t1, t2, l1, l2) nocc, nvir = t1.shape if cc.frozen is None or cc.frozen is 0: dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = d2 dvvov = dovvv.transpose(2,3,0,1) dvvvv = ao2mo.restore(1, d2[1], nvir) return dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov nocc0 = numpy.count_nonzero(cc.mo_occ>0) nvir0 = cc.mo_occ.size - nocc0 OA, VA, OF, VF = index_frozen_active(cc) dovov = numpy.zeros((nocc0,nvir0,nocc0,nvir0)) dvvvv = numpy.zeros((nvir0,nvir0,nvir0,nvir0)) doooo = numpy.zeros((nocc0,nocc0,nocc0,nocc0)) doovv = numpy.zeros((nocc0,nocc0,nvir0,nvir0)) dovvo = numpy.zeros((nocc0,nvir0,nvir0,nocc0)) dovvv = numpy.zeros((nocc0,nvir0,nvir0,nvir0)) dooov = numpy.zeros((nocc0,nocc0,nocc0,nvir0)) dovov[OA[:,None,None,None],VA[:,None,None],OA[:,None],VA] = d2[0] dvvvv[VA[:,None,None,None],VA[:,None,None],VA[:,None],VA] = ao2mo.restore(1, d2[1], nvir) doooo[OA[:,None,None,None],OA[:,None,None],OA[:,None],OA] = d2[2] doovv[OA[:,None,None,None],OA[:,None,None],VA[:,None],VA] = d2[3] dovvo[OA[:,None,None,None],VA[:,None,None],VA[:,None],OA] = d2[4] dovvv[OA[:,None,None,None],VA[:,None,None],VA[:,None],VA] = d2[6] dooov[OA[:,None,None,None],OA[:,None,None],OA[:,None],VA] = d2[7] dvvov = dovvv.transpose(2,3,0,1) return dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov
def contract_2e(eri, fcivec, nsite, nelec, nphonon): neleca, nelecb = _unpack_nelec(nelec) link_indexa = cistring.gen_linkstr_index(range(nsite), neleca) link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb) cishape = make_shape(nsite, nelec, nphonon) ci0 = fcivec.reshape(cishape) t1a = numpy.zeros((nsite,nsite)+cishape) t1b = numpy.zeros((nsite,nsite)+cishape) for str0, tab in enumerate(link_indexa): for a, i, str1, sign in tab: t1a[a,i,str1] += sign * ci0[str0] for str0, tab in enumerate(link_indexb): for a, i, str1, sign in tab: t1b[a,i,:,str1] += sign * ci0[:,str0] g2e_aa = ao2mo.restore(1, eri[0], nsite) g2e_ab = ao2mo.restore(1, eri[1], nsite) g2e_bb = ao2mo.restore(1, eri[2], nsite) t2a = numpy.dot(g2e_aa.reshape(nsite**2,-1), t1a.reshape(nsite**2,-1)) t2a+= numpy.dot(g2e_ab.reshape(nsite**2,-1), t1b.reshape(nsite**2,-1)) t2b = numpy.dot(g2e_ab.reshape(nsite**2,-1).T, t1a.reshape(nsite**2,-1)) t2b+= numpy.dot(g2e_bb.reshape(nsite**2,-1), t1b.reshape(nsite**2,-1)) t2a = t2a.reshape((nsite,nsite)+cishape) t2b = t2b.reshape((nsite,nsite)+cishape) fcinew = numpy.zeros(cishape) for str0, tab in enumerate(link_indexa): for a, i, str1, sign in tab: fcinew[str1] += sign * t2a[a,i,str0] for str0, tab in enumerate(link_indexb): for a, i, str1, sign in tab: fcinew[:,str1] += sign * t2b[a,i,:,str0] return fcinew.reshape(fcivec.shape)
def mp2(mol, h1e, eri, mo, nelec, with_1pdm, with_e2frag): eri1 = ao2mo.restore(8, eri, mo.shape[1]) hf_energy, mo_energy, mo_coeff, mo_occ = simple_hf(h1e, eri1, mo, nelec) mf = scf.RHF(mol) mf.get_hcore = lambda mol: h1e mf._eri = eri mymp2 = mp.MP2(mf) mymp2.nocc = nelec // 2 mymp2.nmo = len(mo_energy) emp2, t2 = mymp2.kernel(mo_energy, mo_coeff) if with_1pdm: rdm1 = mymp2.make_rdm1(t2) for i in range(nelec // 2): rdm1[i, i] += 2 rdm1 = reduce(numpy.dot, (mo_coeff, rdm1, mo_coeff.T)) else: rdm1 = None if with_e2frag: norb = mo_coeff.shape[0] eri1 = part_eri_hermi(eri, norb, with_e2frag) eri1 = ao2mo.incore.full(eri1, mo_coeff) eri1 = ao2mo.restore(1, eri1, norb) rdm2 = mymp2.make_rdm2(t2) for i in range(nelec // 2): for j in range(nelec // 2): rdm2[i, i, j, j] += 4 rdm2[i, j, i, j] += -2 e2frag = 0.5 * numpy.dot(rdm2.reshape(-1), eri1.reshape(-1)) else: e2frag = None return hf_energy, emp2 + hf_energy, e2frag, rdm1
def test_nroutcore_eri(self): ftmp = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) erifile = ftmp.name eri_ao = ao2mo.restore(1, mol.intor('int2e', aosym='s2kl'), nao) eriref = numpy.einsum('pjkl,pi->ijkl', eri_ao, mo) eriref = numpy.einsum('ipkl,pj->ijkl', eriref, mo) eriref = numpy.einsum('ijpl,pk->ijkl', eriref, mo) eriref = numpy.einsum('ijkp,pl->ijkl', eriref, mo) mos = (mo[:,:4], mo[:,:3], mo[:,:3], mo[:,:2]) ao2mo.outcore.general(mol, mos, erifile, dataname='eri_mo', intor='int2e', aosym=1) with ao2mo.load(erifile) as eri1: eri1 = numpy.asarray(eri1).reshape(4,3,3,2) self.assertTrue(numpy.allclose(eri1, eriref[:4,:3,:3,:2])) ao2mo.outcore.full(mol, mo, erifile, dataname='eri_mo', intor='int2e_sph', aosym='s2ij', comp=1) with ao2mo.load(erifile, 'eri_mo') as eri: eri1 = ao2mo.restore(1, numpy.array(eri), nao) eri1 = eri1.reshape(nao,nao,nao,nao) self.assertTrue(numpy.allclose(eri1, eriref)) mos = (mo[:,:3], mo[:,:3], mo[:,:3], mo[:,:2]) ao2mo.outcore.general(mol, mos, erifile, dataname='eri_mo', intor='int2e_sph', aosym='s4', comp=1, compact=False) with ao2mo.load(erifile, 'eri_mo') as eri1: eri1 = numpy.asarray(eri1).reshape(3,3,3,2) self.assertTrue(numpy.allclose(eri1, eriref[:3,:3,:3,:2])) ao2mo.outcore.full(mol, mo[:,:0], erifile, intor='int2e', aosym='1', comp=1) with ao2mo.load(erifile, 'eri_mo') as eri: self.assertTrue(eri.size == 0)
def writeIntegralFile(shciobj, h1eff, eri_cas, ncas, nelec, ecore=0): if isinstance(nelec, (int, numpy.integer)): if shciobj.spin is None: nelecb = nelec // 2 else: nelecb = (nelec - shciobj.spin) // 2 neleca = nelec - nelecb else : neleca, nelecb = nelec if shciobj.groupname is not None and shciobj.orbsym is not []: # First removing the symmetry forbidden integrals. This has been done using # the pyscf internal irrep-IDs (stored in shciobj.orbsym) orbsym = numpy.asarray(shciobj.orbsym) % 10 pair_irrep = (orbsym.reshape(-1,1) ^ orbsym)[numpy.tril_indices(ncas)] sym_forbid = pair_irrep.reshape(-1,1) != pair_irrep.ravel() eri_cas = ao2mo.restore(4, eri_cas, ncas) eri_cas[sym_forbid] = 0 eri_cas = ao2mo.restore(8, eri_cas, ncas) # Convert the pyscf internal irrep-ID to molpro irrep-ID orbsym = numpy.asarray(symmetry.convert_orbsym(shciobj.groupname, orbsym)) else: orbsym = [] eri_cas = ao2mo.restore(8, eri_cas, ncas) if not os.path.exists(shciobj.runtimedir): os.makedirs(shciobj.runtimedir) # The name of the FCIDUMP file, default is "FCIDUMP". integralFile = os.path.join(shciobj.runtimedir, shciobj.integralfile) tools.fcidump.from_integrals(integralFile, h1eff, eri_cas, ncas, neleca+nelecb, ecore, ms=abs(neleca-nelecb), orbsym=orbsym) return integralFile
def test_mp2_contract_eri_dm(self): nocc = mol.nelectron//2 nmo = mf.mo_energy.size nvir = nmo - nocc pt = mp.mp2.MP2(mf) emp2, t2 = pt.kernel() eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo) hcore = mf.get_hcore() rdm1 = pt.make_rdm1() rdm2 = pt.make_rdm2() h1 = reduce(numpy.dot, (mf.mo_coeff.T, hcore, mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, rdm1) e1+= numpy.einsum('ijkl,ijkl', eri, rdm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9) pt.frozen = 2 pt.max_memory = 1 emp2, t2 = pt.kernel(with_t2=False) eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo) hcore = mf.get_hcore() rdm1 = pt.make_rdm1() rdm2 = pt.make_rdm2() h1 = reduce(numpy.dot, (mf.mo_coeff.T, hcore, mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, rdm1) e1+= numpy.einsum('ijkl,ijkl', eri, rdm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9)
def __init__(self, myci, mo_coeff, method='incore'): mol = myci.mol mf = myci._scf nocc = myci.nocc nmo = myci.nmo nvir = nmo - nocc if mo_coeff is None: self.mo_coeff = mo_coeff = myci.mo_coeff if (method == 'incore' and mf._eri is not None): eri = ao2mo.kernel(mf._eri, mo_coeff, verbose=myci.verbose) else: eri = ao2mo.kernel(mol, mo_coeff, verbose=myci.verbose) eri = ao2mo.restore(1, eri, nmo) eri = eri.reshape(nmo,nmo,nmo,nmo) self.oooo = eri[:nocc,:nocc,:nocc,:nocc] self.vvoo = eri[nocc:,nocc:,:nocc,:nocc] self.vooo = eri[nocc:,:nocc,:nocc,:nocc] self.voov = eri[nocc:,:nocc,:nocc,nocc:] self.vovv = lib.pack_tril(eri[nocc:,:nocc,nocc:,nocc:].reshape(-1,nvir,nvir)) self.vvvv = ao2mo.restore(4, eri[nocc:,nocc:,nocc:,nocc:].copy(), nvir) dm = mf.make_rdm1() vhf = mf.get_veff(mol, dm) h1 = mf.get_hcore(mol) self.fock = reduce(numpy.dot, (mo_coeff.T, h1 + vhf, mo_coeff))
def writeIntegralFile(DMRGCI, h1eff, eri_cas, ncas, nelec, ecore=0): if isinstance(nelec, (int, numpy.integer)): neleca = nelec//2 + nelec%2 nelecb = nelec - neleca else : neleca, nelecb = nelec # The name of the FCIDUMP file, default is "FCIDUMP". integralFile = os.path.join(DMRGCI.runtimeDir, DMRGCI.integralFile) if DMRGCI.groupname is not None and DMRGCI.orbsym is not []: # First removing the symmetry forbidden integrals. This has been done using # the pyscf internal irrep-IDs (stored in DMRGCI.orbsym) orbsym = numpy.asarray(DMRGCI.orbsym) % 10 pair_irrep = (orbsym.reshape(-1,1) ^ orbsym)[numpy.tril_indices(ncas)] sym_forbid = pair_irrep.reshape(-1,1) != pair_irrep.ravel() eri_cas = ao2mo.restore(4, eri_cas, ncas) eri_cas[sym_forbid] = 0 eri_cas = ao2mo.restore(8, eri_cas, ncas) #orbsym = numpy.asarray(dmrg_sym.convert_orbsym(DMRGCI.groupname, DMRGCI.orbsym)) #eri_cas = pyscf.ao2mo.restore(8, eri_cas, ncas) # Then convert the pyscf internal irrep-ID to molpro irrep-ID orbsym = numpy.asarray(dmrg_sym.convert_orbsym(DMRGCI.groupname, orbsym)) else: orbsym = [] eri_cas = ao2mo.restore(8, eri_cas, ncas) if not os.path.exists(DMRGCI.scratchDirectory): os.makedirs(DMRGCI.scratchDirectory) if not os.path.exists(DMRGCI.runtimeDir): os.makedirs(DMRGCI.runtimeDir) tools.fcidump.from_integrals(integralFile, h1eff, eri_cas, ncas, neleca+nelecb, ecore, ms=abs(neleca-nelecb), orbsym=orbsym) return integralFile
def pspace(h1e, eri, norb, nelec, hdiag, np=400): neleca, nelecb = direct_spin1._unpack_nelec(nelec) h1e_a = numpy.ascontiguousarray(h1e[0]) h1e_b = numpy.ascontiguousarray(h1e[1]) g2e_aa = ao2mo.restore(1, eri[0], norb) g2e_ab = ao2mo.restore(1, eri[1], norb) g2e_bb = ao2mo.restore(1, eri[2], norb) link_indexa = cistring.gen_linkstr_index_trilidx(range(norb), neleca) link_indexb = cistring.gen_linkstr_index_trilidx(range(norb), nelecb) nb = link_indexb.shape[0] addr = numpy.argsort(hdiag)[:np] addra = addr // nb addrb = addr % nb stra = numpy.array([cistring.addr2str(norb,neleca,ia) for ia in addra], dtype=numpy.long) strb = numpy.array([cistring.addr2str(norb,nelecb,ib) for ib in addrb], dtype=numpy.long) np = len(addr) h0 = numpy.zeros((np,np)) libfci.FCIpspace_h0tril_uhf(h0.ctypes.data_as(ctypes.c_void_p), h1e_a.ctypes.data_as(ctypes.c_void_p), h1e_b.ctypes.data_as(ctypes.c_void_p), g2e_aa.ctypes.data_as(ctypes.c_void_p), g2e_ab.ctypes.data_as(ctypes.c_void_p), g2e_bb.ctypes.data_as(ctypes.c_void_p), stra.ctypes.data_as(ctypes.c_void_p), strb.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(np)) for i in range(np): h0[i,i] = hdiag[addr[i]] h0 = lib.hermi_triu(h0) return addr, h0
def test_nr_transe1incore(self): eri_ao = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) eriref = ao2mo.restore(1, eri_ao, nao) eriref = numpy.einsum("ijpl,pk->ijkl", eriref, mo) eriref = numpy.einsum("ijkp,pl->ijkl", eriref, mo) eriref = ao2mo.restore(4, eriref, nao) eri_ao = ao2mo.restore(8, eri_ao, nao) ftrans1 = f1pointer("AO2MOtranse1_incore_s8") fmmm = f1pointer("AO2MOmmm_nr_s2_s2") eri1 = numpy.empty((naopair, naopair)) libao2mo1.AO2MOnr_e1incore_drv( ftrans1, fmmm, eri1.ctypes.data_as(ctypes.c_void_p), eri_ao.ctypes.data_as(ctypes.c_void_p), mo.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(0), ctypes.c_int(naopair), ctypes.c_int(nao), ctypes.c_int(0), ctypes.c_int(nao), ctypes.c_int(0), ctypes.c_int(nao), ) self.assertTrue(numpy.allclose(eri1, eriref))
def make_hdiag(h1e, eri, norb, nelec): neleca, nelecb = direct_spin1._unpack_nelec(nelec) h1e_a = numpy.ascontiguousarray(h1e[0]) h1e_b = numpy.ascontiguousarray(h1e[1]) g2e_aa = ao2mo.restore(1, eri[0], norb) g2e_ab = ao2mo.restore(1, eri[1], norb) g2e_bb = ao2mo.restore(1, eri[2], norb) strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca)) strsb = numpy.asarray(cistring.gen_strings4orblist(range(norb), nelecb)) na = len(strsa) nb = len(strsb) hdiag = numpy.empty(na*nb) jdiag_aa = numpy.asarray(numpy.einsum('iijj->ij',g2e_aa), order='C') jdiag_ab = numpy.asarray(numpy.einsum('iijj->ij',g2e_ab), order='C') jdiag_bb = numpy.asarray(numpy.einsum('iijj->ij',g2e_bb), order='C') kdiag_aa = numpy.asarray(numpy.einsum('ijji->ij',g2e_aa), order='C') kdiag_bb = numpy.asarray(numpy.einsum('ijji->ij',g2e_bb), order='C') libfci.FCImake_hdiag_uhf(hdiag.ctypes.data_as(ctypes.c_void_p), h1e_a.ctypes.data_as(ctypes.c_void_p), h1e_b.ctypes.data_as(ctypes.c_void_p), jdiag_aa.ctypes.data_as(ctypes.c_void_p), jdiag_ab.ctypes.data_as(ctypes.c_void_p), jdiag_bb.ctypes.data_as(ctypes.c_void_p), kdiag_aa.ctypes.data_as(ctypes.c_void_p), kdiag_bb.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(neleca), ctypes.c_int(nelecb), strsa.ctypes.data_as(ctypes.c_void_p), strsb.ctypes.data_as(ctypes.c_void_p)) return numpy.asarray(hdiag)
def part_eri_hermi(eri, norb, nimp): eri1 = ao2mo.restore(4, eri, norb) for i in range(eri1.shape[0]): tmp = lib.unpack_tril(eri1[i]) tmp[nimp:] = 0 eri1[i] = lib.pack_tril(tmp + tmp.T) eri1 = lib.transpose_sum(eri1, inplace=True) return ao2mo.restore(8, eri1, norb) * 0.25
def contract_2e(eri, civec_strs, norb, nelec, link_index=None): ci_coeff, nelec, ci_strs = _unpack(civec_strs, nelec) if link_index is None: link_index = _all_linkstr_index(ci_strs, norb, nelec) cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index na, nlinka = cd_indexa.shape[:2] nb, nlinkb = cd_indexb.shape[:2] eri = ao2mo.restore(1, eri, norb) eri1 = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1) idx,idy = numpy.tril_indices(norb, -1) idx = idx * norb + idy eri1 = lib.take_2d(eri1.reshape(norb**2,-1), idx, idx) * 2 fcivec = ci_coeff.reshape(na,nb) # (bb|bb) if nelec[1] > 1: mb, mlinkb = dd_indexb.shape[:2] fcivecT = lib.transpose(fcivec) ci1T = numpy.zeros((nb,na)) libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivecT.ctypes.data_as(ctypes.c_void_p), ci1T.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(nb), ctypes.c_int(na), ctypes.c_int(mb), ctypes.c_int(mlinkb), dd_indexb.ctypes.data_as(ctypes.c_void_p)) ci1 = lib.transpose(ci1T, out=fcivecT) else: ci1 = numpy.zeros_like(fcivec) # (aa|aa) if nelec[0] > 1: ma, mlinka = dd_indexa.shape[:2] libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(ma), ctypes.c_int(mlinka), dd_indexa.ctypes.data_as(ctypes.c_void_p)) h_ps = numpy.einsum('pqqs->ps', eri) eri1 = eri * 2 for k in range(norb): eri1[:,:,k,k] += h_ps/nelec[0] eri1[k,k,:,:] += h_ps/nelec[1] eri1 = ao2mo.restore(4, eri1, norb) # (bb|aa) libfci.SCIcontract_2e_bbaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(nlinka), ctypes.c_int(nlinkb), cd_indexa.ctypes.data_as(ctypes.c_void_p), cd_indexb.ctypes.data_as(ctypes.c_void_p)) return _as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)
def test_ccsd(self): mol = gto.M() mf = scf.RHF(mol) mcc = cc.CCSD(mf) numpy.random.seed(12) mcc.nocc = nocc = 5 mcc.nmo = nmo = 12 nvir = nmo - nocc eri0 = numpy.random.random((nmo,nmo,nmo,nmo)) eri0 = ao2mo.restore(1, ao2mo.restore(8, eri0, nmo), nmo) fock0 = numpy.random.random((nmo,nmo)) fock0 = fock0 + fock0.T + numpy.diag(range(nmo))*2 t1 = numpy.random.random((nocc,nvir)) t2 = numpy.random.random((nocc,nocc,nvir,nvir)) t2 = t2 + t2.transpose(1,0,3,2) l1 = numpy.random.random((nocc,nvir)) l2 = numpy.random.random((nocc,nocc,nvir,nvir)) l2 = l2 + l2.transpose(1,0,3,2) eris = cc.ccsd._ChemistsERIs() eris.oooo = eri0[:nocc,:nocc,:nocc,:nocc].copy() eris.ovoo = eri0[:nocc,nocc:,:nocc,:nocc].copy() eris.oovv = eri0[:nocc,:nocc,nocc:,nocc:].copy() eris.ovvo = eri0[:nocc,nocc:,nocc:,:nocc].copy() idx = numpy.tril_indices(nvir) eris.ovvv = eri0[:nocc,nocc:,nocc:,nocc:][:,:,idx[0],idx[1]].copy() eris.vvvv = ao2mo.restore(4,eri0[nocc:,nocc:,nocc:,nocc:],nvir) eris.fock = fock0 eris.mo_energy = fock0.diagonal() saved = ccsd_lambda.make_intermediates(mcc, t1, t2, eris) l1new, l2new = ccsd_lambda.update_lambda(mcc, t1, t2, l1, l2, eris, saved) self.assertAlmostEqual(abs(l1new).sum(), 38172.7896467303, 8) self.assertAlmostEqual(numpy.dot(l1new.flatten(), numpy.arange(35)), 739312.005491083, 8) self.assertAlmostEqual(numpy.dot(l1new.flatten(), numpy.sin(numpy.arange(35))), 7019.50937051188, 8) self.assertAlmostEqual(numpy.dot(numpy.sin(l1new.flatten()), numpy.arange(35)), 69.6652346635955, 8) self.assertAlmostEqual(abs(l2new).sum(), 72035.4931071527, 8) self.assertAlmostEqual(abs(l2new-l2new.transpose(1,0,3,2)).sum(), 0, 9) self.assertAlmostEqual(numpy.dot(l2new.flatten(), numpy.arange(35**2)), 48427109.5409886, 7) self.assertAlmostEqual(numpy.dot(l2new.flatten(), numpy.sin(numpy.arange(35**2))), 137.758016736487, 8) self.assertAlmostEqual(numpy.dot(numpy.sin(l2new.flatten()), numpy.arange(35**2)), 507.656936701192, 8) mcc.max_memory = 0 saved = ccsd_lambda.make_intermediates(mcc, t1, t2, eris) l1new, l2new = ccsd_lambda.update_lambda(mcc, t1, t2, l1, l2, eris, saved) self.assertAlmostEqual(abs(l1new).sum(), 38172.7896467303, 8) self.assertAlmostEqual(numpy.dot(l1new.flatten(), numpy.arange(35)), 739312.005491083, 8) self.assertAlmostEqual(numpy.dot(l1new.flatten(), numpy.sin(numpy.arange(35))), 7019.50937051188, 8) self.assertAlmostEqual(numpy.dot(numpy.sin(l1new.flatten()), numpy.arange(35)), 69.6652346635955, 8) self.assertAlmostEqual(abs(l2new).sum(), 72035.4931071527, 8) self.assertAlmostEqual(abs(l2new-l2new.transpose(1,0,3,2)).sum(), 0, 9) self.assertAlmostEqual(numpy.dot(l2new.flatten(), numpy.arange(35**2)), 48427109.5409886, 7) self.assertAlmostEqual(numpy.dot(l2new.flatten(), numpy.sin(numpy.arange(35**2))), 137.758016736487, 8) self.assertAlmostEqual(numpy.dot(numpy.sin(l2new.flatten()), numpy.arange(35**2)), 507.656936701192, 8)
def gen_hop_uhf_external(mf): mol = mf.mol mo_a, mo_b = mf.mo_coeff mo_ea, mo_eb = mf.mo_energy mo_occa, mo_occb = mf.mo_occ nmo = mo_a.shape[1] nocca = numpy.count_nonzero(mo_occa) noccb = numpy.count_nonzero(mo_occb) nvira = nmo - nocca nvirb = nmo - noccb eri_aa = ao2mo.restore(1, ao2mo.full(mol, mo_a), nmo) eri_ab = ao2mo.restore(1, ao2mo.general(mol, [mo_a,mo_a,mo_b,mo_b]), nmo) eri_bb = ao2mo.restore(1, ao2mo.full(mol, mo_b), nmo) # alpha -> alpha haa =-numpy.einsum('abji->iajb', eri_aa[nocca:,nocca:,:nocca,:nocca]) haa+= numpy.einsum('ajbi->iajb', eri_aa[nocca:,:nocca,nocca:,:nocca]) for a in range(nvira): for i in range(nocca): haa[i,a,i,a] += mo_ea[nocca+a] - mo_ea[i] # beta -> beta hbb =-numpy.einsum('abji->iajb', eri_bb[noccb:,noccb:,:noccb,:noccb]) hbb+= numpy.einsum('ajbi->iajb', eri_bb[noccb:,:noccb,noccb:,:noccb]) for a in range(nvirb): for i in range(noccb): hbb[i,a,i,a] += mo_eb[noccb+a] - mo_eb[i] nova = nocca * nvira novb = noccb * nvirb h1 = numpy.zeros((nova+novb,nova+novb)) h1[:nova,:nova] = haa.transpose(1,0,3,2).reshape(nova,nova) h1[nova:,nova:] = hbb.transpose(1,0,3,2).reshape(novb,novb) def hop1(x): return h1.dot(x) h11 =-numpy.einsum('abji->iajb', eri_ab[nocca:,nocca:,:noccb,:noccb]) for a in range(nvira): for i in range(noccb): h11[i,a,i,a] += mo_ea[nocca+a] - mo_eb[i] h22 =-numpy.einsum('jiab->iajb', eri_ab[:nocca,:nocca,noccb:,noccb:]) for a in range(nvirb): for i in range(nocca): h22[i,a,i,a] += mo_eb[noccb+a] - mo_ea[i] h12 =-numpy.einsum('ajbi->iajb', eri_ab[nocca:,:nocca,noccb:,:noccb]) h21 =-numpy.einsum('biaj->iajb', eri_ab[nocca:,:nocca,noccb:,:noccb]) n1 = noccb * nvira n2 = nocca * nvirb h2 = numpy.empty((n1+n2,n1+n2)) h2[:n1,:n1] = h11.transpose(1,0,3,2).reshape(n1,n1) h2[n1:,n1:] = h22.transpose(1,0,3,2).reshape(n2,n2) h2[:n1,n1:] = h12.transpose(1,0,3,2).reshape(n1,n2) h2[n1:,:n1] = h21.transpose(1,0,3,2).reshape(n2,n1) def hop2(x): return h2.dot(x) return hop1, hop2
def _get_VVVV(eris): if eris.VVVV is None and getattr(eris, 'VVL', None) is not None: # DF eris VVL = np.asarray(eris.VVL) nvir = int(np.sqrt(eris.VVL.shape[0]*2)) return ao2mo.restore(1, lib.dot(VVL, VVL.T), nvir) elif len(eris.VVVV.shape) == 2: nvir = int(np.sqrt(eris.VVVV.shape[0]*2)) return ao2mo.restore(1, np.asarray(eris.VVVV), nvir) else: return eris.VVVV
def test_kernel(self): h1 = h1e + h1e.T eri = .5* ao2mo.restore(1, ao2mo.restore(8, h2e, norb), norb) h = fci.direct_spin1.pspace(h1, eri, norb, nelec, np=5000)[1] eref, c0 = numpy.linalg.eigh(h) sol = fci.direct_nosym.FCI() e, c1 = sol.kernel(h1, eri, norb, nelec, max_space=40) self.assertAlmostEqual(eref[0], e, 9) self.assertAlmostEqual(abs(c0[:,0].dot(c1.ravel())), 1, 9)
def absorb_h1e(h1e, eri, norb, nelec, fac=1): '''Modify 2e Hamiltonian to include 1e Hamiltonian contribution. ''' if not isinstance(nelec, (int, numpy.number)): nelec = sum(nelec) h2e = ao2mo.restore(1, eri.copy(), norb) f1e = h1e - numpy.einsum('jiik->jk', h2e) * .5 f1e = f1e * (1./(nelec+1e-100)) for k in range(norb): h2e[k,k,:,:] += f1e h2e[:,:,k,k] += f1e return ao2mo.restore(4, h2e, norb) * fac
def contract_2e(eri, civec_strs, norb, nelec, link_index=None, orbsym=None): ci_coeff, nelec, ci_strs = selected_ci._unpack(civec_strs, nelec) if link_index is None: link_index = selected_ci._all_linkstr_index(ci_strs, norb, nelec) cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index na, nlinka = nb, nlinkb = cd_indexa.shape[:2] eri = ao2mo.restore(1, eri, norb) eri1 = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1) idx,idy = numpy.tril_indices(norb, -1) idx = idx * norb + idy eri1 = lib.take_2d(eri1.reshape(norb**2,-1), idx, idx) * 2 lib.transpose_sum(eri1, inplace=True) eri1 *= .5 eri1, dd_indexa, dimirrep = selected_ci_symm.reorder4irrep(eri1, norb, dd_indexa, orbsym, -1) fcivec = ci_coeff.reshape(na,nb) ci1 = numpy.zeros_like(fcivec) # (aa|aa) if nelec[0] > 1: ma, mlinka = mb, mlinkb = dd_indexa.shape[:2] libfci.SCIcontract_2e_aaaa_symm(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(ma), ctypes.c_int(mlinka), dd_indexa.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) h_ps = numpy.einsum('pqqs->ps', eri) * (.5/nelec[0]) eri1 = eri.copy() for k in range(norb): eri1[:,:,k,k] += h_ps eri1[k,k,:,:] += h_ps eri1 = ao2mo.restore(4, eri1, norb) lib.transpose_sum(eri1, inplace=True) eri1 *= .5 eri1, cd_indexa, dimirrep = selected_ci_symm.reorder4irrep(eri1, norb, cd_indexa, orbsym) # (bb|aa) libfci.SCIcontract_2e_bbaa_symm(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(nlinka), ctypes.c_int(nlinkb), cd_indexa.ctypes.data_as(ctypes.c_void_p), cd_indexa.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) lib.transpose_sum(ci1, inplace=True) return selected_ci._as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)
def test_large_ci(self): norb = 6 nelec = (3,3) numpy.random.seed(10) h1e = numpy.random.random((norb,norb)) h1e = h1e + h1e.T g2e = numpy.random.random((norb,norb,norb,norb)) eri = .5* ao2mo.restore(1, ao2mo.restore(8, g2e, norb), norb) sol = fci.direct_spin1.FCI(mol) e, c1 = sol.kernel(h1e, eri, norb, nelec) self.assertAlmostEqual(e, -4.742664117996546, 9) val = sol.large_ci(c1, norb, nelec) self.assertAlmostEqual(val[0][0], c1[0,0], 9)
def test_restore4(self): self.assertTrue(numpy.allclose(a4, ao2mo.restore(4, a1, n))) self.assertTrue(numpy.allclose(a4, ao2mo.restore('4', a4, n))) self.assertTrue(numpy.allclose(a4, ao2mo.restore('s4', a8, n))) self.assertTrue(numpy.allclose(a4, ao2mo.restore('s4', a2ij, n))) self.assertTrue(numpy.allclose(a4, ao2mo.restore('s4', a2kl, n))) self.assertTrue(numpy.allclose(b4, ao2mo.restore(4, b1, n))) self.assertTrue(numpy.allclose(b4, ao2mo.restore('4', b4, n))) self.assertTrue(numpy.allclose(b4, ao2mo.restore('4', b2ij, n))) self.assertTrue(numpy.allclose(b4, ao2mo.restore('4', b2kl, n)))
def test_uccsd_rdm2_mo2ao(self): mol = gto.Mole() mol.verbose = 0 mol.atom = [ [8 , (0. , 0. , 0.)], [1 , (0. , -0.757 , 0.587)], [1 , (0. , 0.757 , 0.587)]] mol.spin = 2 mol.basis = '631g' mol.build(0, 0) mf = scf.UHF(mol) mf.conv_tol_grad = 1e-8 mf.kernel() mycc = cc.UCCSD(mf) mycc.diis_start_cycle = 1 mycc.conv_tol = 1e-10 eris = mycc.ao2mo() ecc, t1, t2 = mycc.kernel(eris=eris) l1, l2 = mycc.solve_lambda(eris=eris) fdm2 = lib.H5TmpFile() d2 = cc.uccsd_rdm._gamma2_outcore(mycc, t1, t2, l1, l2, fdm2, True) nao = mycc.mo_coeff[0].shape[0] ref = cc.uccsd_rdm._make_rdm2(mycc, None, d2, with_dm1=False) aa = lib.einsum('ijkl,pi,qj,rk,sl->pqrs', ref[0], mycc.mo_coeff[0], mycc.mo_coeff[0], mycc.mo_coeff[0], mycc.mo_coeff[0]) ab = lib.einsum('ijkl,pi,qj,rk,sl->pqrs', ref[1], mycc.mo_coeff[0], mycc.mo_coeff[0], mycc.mo_coeff[1], mycc.mo_coeff[1]) bb = lib.einsum('ijkl,pi,qj,rk,sl->pqrs', ref[2], mycc.mo_coeff[1], mycc.mo_coeff[1], mycc.mo_coeff[1], mycc.mo_coeff[1]) aa = aa + aa.transpose(0,1,3,2) aa = aa + aa.transpose(1,0,2,3) aa = ao2mo.restore(4, aa, nao) * .5 bb = bb + bb.transpose(0,1,3,2) bb = bb + bb.transpose(1,0,2,3) bb = ao2mo.restore(4, bb, nao) * .5 ab = ab + ab.transpose(0,1,3,2) ab = ab + ab.transpose(1,0,2,3) ab = ao2mo.restore(4, ab, nao) * .5 ref = (aa+ab, bb+ab.T) rdm2 = uccsd_grad._rdm2_mo2ao(mycc, d2, mycc.mo_coeff) self.assertAlmostEqual(abs(ref[0]-rdm2[0]).max(), 0, 10) self.assertAlmostEqual(abs(ref[1]-rdm2[1]).max(), 0, 10) uccsd_grad._rdm2_mo2ao(mycc, d2, mycc.mo_coeff, fdm2) self.assertAlmostEqual(abs(ref[0]-fdm2['dm2aa+ab'].value).max(), 0, 10) self.assertAlmostEqual(abs(ref[1]-fdm2['dm2bb+ab'].value).max(), 0, 10) self.assertAlmostEqual(lib.finger(rdm2[0]), -1.6247203743431637, 7) self.assertAlmostEqual(lib.finger(rdm2[1]), -0.44062825991527471, 7)
def pspace(h1e, eri, norb, nelec, hdiag, np=400): '''pspace Hamiltonian to improve Davidson preconditioner. See, CPL, 169, 463 ''' neleca, nelecb = _unpack_nelec(nelec) h1e = numpy.ascontiguousarray(h1e) eri = ao2mo.restore(1, eri, norb) nb = cistring.num_strings(norb, nelecb) if hdiag.size < np: addr = numpy.arange(hdiag.size) else: try: addr = numpy.argpartition(hdiag, np-1)[:np] except AttributeError: addr = numpy.argsort(hdiag)[:np] addra, addrb = divmod(addr, nb) stra = numpy.array([cistring.addr2str(norb,neleca,ia) for ia in addra], dtype=numpy.uint64) strb = numpy.array([cistring.addr2str(norb,nelecb,ib) for ib in addrb], dtype=numpy.uint64) np = len(addr) h0 = numpy.zeros((np,np)) libfci.FCIpspace_h0tril(h0.ctypes.data_as(ctypes.c_void_p), h1e.ctypes.data_as(ctypes.c_void_p), eri.ctypes.data_as(ctypes.c_void_p), stra.ctypes.data_as(ctypes.c_void_p), strb.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(np)) for i in range(np): h0[i,i] = hdiag[addr[i]] h0 = lib.hermi_triu(h0) return addr, h0
def test_eris_contract_vvvv_t2(self): mol = gto.Mole() nocc, nvir = 5, 12 nvir_pair = nvir*(nvir+1)//2 numpy.random.seed(9) t2 = numpy.random.random((nocc,nocc,nvir,nvir)) - .5 t2 = t2 + t2.transpose(1,0,3,2) eris = ccsd._ChemistsERIs() vvvv = numpy.random.random((nvir_pair,nvir_pair)) - .5 eris.vvvv = vvvv + vvvv.T eris.mol = mol mycc.max_memory, bak = 0, mycc.max_memory vt2 = eris._contract_vvvv_t2(mycc, t2, eris.vvvv) mycc.max_memory = bak self.assertAlmostEqual(lib.finger(vt2), -39.572579908080087, 11) vvvv = ao2mo.restore(1, eris.vvvv, nvir) ref = lib.einsum('acbd,ijcd->ijab', vvvv, t2) self.assertAlmostEqual(abs(vt2 - ref).max(), 0, 11) # _contract_s1vvvv_t2, testing complex and real mixed contraction vvvv =(numpy.random.random((nvir,nvir,nvir,nvir)) + numpy.random.random((nvir,nvir,nvir,nvir))*1j - (.5+.5j)) vvvv = vvvv + vvvv.transpose(1,0,3,2).conj() vvvv = vvvv + vvvv.transpose(2,3,0,1) eris.vvvv = vvvv eris.mol = mol mycc.max_memory, bak = 0, mycc.max_memory vt2 = eris._contract_vvvv_t2(mycc, t2, eris.vvvv) mycc.max_memory = bak self.assertAlmostEqual(lib.finger(vt2), 23.502736435296871+113.90422480013488j, 11) ref = lib.einsum('acbd,ijcd->ijab', eris.vvvv, t2) self.assertAlmostEqual(abs(vt2 - ref).max(), 0, 11)
def Srs(mc, dms, eris=None, verbose=None): #Subspace S_rs^{(-2)} mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) dm1 = dms['1'] dm2 = dms['2'] dm3 = dms['3'] ncore = mo_core.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if mo_virt.shape[1] ==0: return 0, 0 if eris is None: h1e = mc.h1e_for_cas()[0] h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0,2,1,3) h2e_v = ao2mo.incore.general(mc._scf._eri,[mo_virt,mo_cas,mo_virt,mo_cas],compact=False) h2e_v = h2e_v.reshape(mo_virt.shape[1],ncas,mo_virt.shape[1],ncas).transpose(0,2,1,3) else: h1e = eris['h1eff'][ncore:nocc,ncore:nocc] h2e = eris['ppaa'][ncore:nocc,ncore:nocc].transpose(0,2,1,3) h2e_v = eris['papa'][nocc:,:,nocc:].transpose(0,2,1,3) # a7 is very sensitive to the accuracy of HF orbital and CI wfn rm2, a7 = make_a7(h1e,h2e,dm1,dm2,dm3) norm = 0.5*numpy.einsum('rsqp,rsba,pqba->rs',h2e_v,h2e_v,rm2) h = 0.5*numpy.einsum('rsqp,rsba,pqab->rs',h2e_v,h2e_v,a7) diff = mc.mo_energy[nocc:,None] + mc.mo_energy[None,nocc:] return _norm_to_energy(norm, h, diff)
def Sijr(mc, dms, eris, verbose=None): #Subspace S_ijr^{(1)} mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) dm1 = dms['1'] dm2 = dms['2'] ncore = mo_core.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if eris is None: h1e = mc.h1e_for_cas()[0] h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0,2,1,3) h2e_v = ao2mo.incore.general(mc._scf._eri,[mo_virt,mo_core,mo_cas,mo_core],compact=False) h2e_v = h2e_v.reshape(mo_virt.shape[1],ncore,ncas,ncore).transpose(0,2,1,3) else: h1e = eris['h1eff'][ncore:nocc,ncore:nocc] h2e = eris['ppaa'][ncore:nocc,ncore:nocc].transpose(0,2,1,3) h2e_v = eris['pacv'][:ncore].transpose(3,1,2,0) if 'h1' in dms: hdm1 = dms['h1'] else: hdm1 = make_hdm1(dm1) a3 = make_a3(h1e,h2e,dm1,dm2,hdm1) norm = 2.0*numpy.einsum('rpji,raji,pa->rji',h2e_v,h2e_v,hdm1)\ - 1.0*numpy.einsum('rpji,raij,pa->rji',h2e_v,h2e_v,hdm1) h = 2.0*numpy.einsum('rpji,raji,pa->rji',h2e_v,h2e_v,a3)\ - 1.0*numpy.einsum('rpji,raij,pa->rji',h2e_v,h2e_v,a3) diff = mc.mo_energy[nocc:,None,None] - mc.mo_energy[None,:ncore,None] - mc.mo_energy[None,None,:ncore] return _norm_to_energy(norm, h, diff)
def Srsi(mc, dms, eris, verbose=None): #Subspace S_ijr^{(1)} mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) dm1 = dms['1'] dm2 = dms['2'] ncore = mo_core.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if eris is None: h1e = mc.h1e_for_cas()[0] h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0,2,1,3) h2e_v = ao2mo.incore.general(mc._scf._eri,[mo_virt,mo_core,mo_virt,mo_cas],compact=False) h2e_v = h2e_v.reshape(mo_virt.shape[1],ncore,mo_virt.shape[1],ncas).transpose(0,2,1,3) else: h1e = eris['h1eff'][ncore:nocc,ncore:nocc] h2e = eris['ppaa'][ncore:nocc,ncore:nocc].transpose(0,2,1,3) h2e_v = eris['pacv'][nocc:].transpose(3,0,2,1) k27 = make_k27(h1e,h2e,dm1,dm2) norm = 2.0*numpy.einsum('rsip,rsia,pa->rsi',h2e_v,h2e_v,dm1)\ - 1.0*numpy.einsum('rsip,sria,pa->rsi',h2e_v,h2e_v,dm1) h = 2.0*numpy.einsum('rsip,rsia,pa->rsi',h2e_v,h2e_v,k27)\ - 1.0*numpy.einsum('rsip,sria,pa->rsi',h2e_v,h2e_v,k27) diff = mc.mo_energy[nocc:,None,None] + mc.mo_energy[None,nocc:,None] - mc.mo_energy[None,None,:ncore] return _norm_to_energy(norm, h, diff)
def make_hdiag(h1e, eri, norb, nelec): '''Diagonal Hamiltonian for Davidson preconditioner ''' neleca, nelecb = _unpack_nelec(nelec) h1e = numpy.asarray(h1e, order='C') eri = ao2mo.restore(1, eri, norb) strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca)) strsb = numpy.asarray(cistring.gen_strings4orblist(range(norb), nelecb)) na = len(strsa) nb = len(strsb) hdiag = numpy.empty(na*nb) jdiag = numpy.asarray(numpy.einsum('iijj->ij',eri), order='C') kdiag = numpy.asarray(numpy.einsum('ijji->ij',eri), order='C') c_h1e = h1e.ctypes.data_as(ctypes.c_void_p) c_jdiag = jdiag.ctypes.data_as(ctypes.c_void_p) c_kdiag = kdiag.ctypes.data_as(ctypes.c_void_p) libfci.FCImake_hdiag_uhf(hdiag.ctypes.data_as(ctypes.c_void_p), c_h1e, c_h1e, c_jdiag, c_jdiag, c_jdiag, c_kdiag, c_kdiag, ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(neleca), ctypes.c_int(nelecb), strsa.ctypes.data_as(ctypes.c_void_p), strsb.ctypes.data_as(ctypes.c_void_p)) return hdiag
def make_hdiag(h1e, g2e, ci_strs, norb, nelec): if isinstance(nelec, (int, numpy.integer)): nelecb = nelec // 2 neleca = nelec - nelecb else: neleca, nelecb = nelec strsa, strsb = ci_strs strsa = numpy.asarray(strsa) strsb = numpy.asarray(strsb) occslista = [[i for i in range(norb) if str0 & (1 << i)] for str0 in strsa] occslistb = [[i for i in range(norb) if str0 & (1 << i)] for str0 in strsb] g2e = ao2mo.restore(1, g2e, norb) diagj = numpy.einsum("iijj->ij", g2e) diagk = numpy.einsum("ijji->ij", g2e) hdiag = [] for aocc in occslista: for bocc in occslistb: e1 = h1e[aocc, aocc].sum() + h1e[bocc, bocc].sum() e2 = ( diagj[aocc][:, aocc].sum() + diagj[aocc][:, bocc].sum() + diagj[bocc][:, aocc].sum() + diagj[bocc][:, bocc].sum() - diagk[aocc][:, aocc].sum() - diagk[bocc][:, bocc].sum() ) hdiag.append(e1 + e2 * 0.5) return numpy.array(hdiag)
def make_diagonal(mol, mo_energy, eris, nocc): nmo = mo_energy.size nvir = nmo - nocc jdiag = numpy.zeros((nmo,nmo)) kdiag = numpy.zeros((nmo,nmo)) eris_vvvv = ao2mo.restore(1, eris.vvvv, nvir) jdiag[:nocc,:nocc] = numpy.einsum('iijj->ij', eris.oooo) kdiag[:nocc,:nocc] = numpy.einsum('jiij->ij', eris.oooo) jdiag[nocc:,nocc:] = numpy.einsum('iijj->ij', eris_vvvv) kdiag[nocc:,nocc:] = numpy.einsum('jiij->ij', eris_vvvv) jdiag[:nocc,nocc:] = numpy.einsum('iijj->ji', eris.vvoo) kdiag[:nocc,nocc:] = numpy.einsum('jiij->ij', eris.voov) jksum = (jdiag[:nocc,:nocc] * 2 - kdiag[:nocc,:nocc]).sum() ehf = mo_energy[:nocc].sum() * 2 - jksum e1diag = numpy.empty((nocc,nvir)) e2diag = numpy.empty((nocc,nocc,nvir,nvir)) for i in range(nocc): for a in range(nocc, nmo): e1diag[i,a-nocc] = ehf - mo_energy[i] + mo_energy[a] \ - jdiag[i,a] + kdiag[i,a] for j in range(nocc): for b in range(nocc, nmo): e2diag[i,j,a-nocc,b-nocc] = ehf \ - mo_energy[i] - mo_energy[j] \ + mo_energy[a] + mo_energy[b] \ + jdiag[i,j] - jdiag[i,a] + kdiag[i,a] \ - jdiag[j,a] - jdiag[i,b] - jdiag[j,b] \ + kdiag[j,b] + jdiag[a,b] return numpy.hstack((ehf, e1diag.reshape(-1), e2diag.reshape(-1)))
def test_get_veff(self): nao = mol.nao_nr()*2 numpy.random.seed(1) d1 = numpy.random.random((nao,nao)) + numpy.random.random((nao,nao)) * 1j d2 = numpy.random.random((nao,nao)) + numpy.random.random((nao,nao)) * 1j d = numpy.array((d1+d1.conj().T, d2+d2.conj().T)) eri = numpy.zeros((nao, nao, nao, nao)) n = nao // 2 eri[:n,:n,:n,:n] = \ eri[n:,n:,n:,n:] = \ eri[:n,:n,n:,n:] = \ eri[n:,n:,:n,:n] = ao2mo.restore(1, mf._eri, n) vj = numpy.einsum('ijkl,xji->xkl', eri, d) vk = numpy.einsum('ijkl,xjk->xil', eri, d) ref = vj - vk v = mf.get_veff(mol, d) self.assertAlmostEqual(abs(ref - v).max(), 0, 12) self.assertAlmostEqual(numpy.linalg.norm(v), 560.3785699368684, 9)
def test_general(self): numpy.random.seed(15) nmo = 12 mo = numpy.random.random((nao,nmo)) eriref = ao2mo.incore.full(eri, mo) tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) io_size = nao**2*4e-5 semi_incore.general(eri, [mo]*4, tmpfile.name, ioblk_size=io_size) with ao2mo.load(tmpfile) as eri_mo: self.assertAlmostEqual(abs(eriref - eri_mo.value).max(), 0, 9) semi_incore.general(eri, [mo]*4, tmpfile.name, ioblk_size=io_size, compact=False) with ao2mo.load(tmpfile) as eri_mo: eriref = ao2mo.restore(1, eriref, nmo).reshape(nmo**2,nmo**2) self.assertAlmostEqual(abs(eriref - eri_mo.value).max(), 0, 9)
def test_select_strs(self): myci = selected_ci.SCI() myci.select_cutoff = 1e-3 norb, nelec = 10, 4 strs = cistring.make_strings(range(norb), nelec) numpy.random.seed(11) mask = numpy.random.random(len(strs)) > .8 strs = strs[mask] nn = norb*(norb+1)//2 eri = (numpy.random.random(nn*(nn+1)//2)-.2)**3 eri[eri<.1] *= 3e-3 eri = ao2mo.restore(1, eri, norb) eri_pq_max = abs(eri.reshape(norb**2,-1)).max(axis=1).reshape(norb,norb) civec_max = numpy.random.random(len(strs)) strs_add0 = select_strs(myci, eri, eri_pq_max, civec_max, strs, norb, nelec) strs_add1 = selected_ci.select_strs(myci, eri, eri_pq_max, civec_max, strs, norb, nelec) self.assertTrue(numpy.all(strs_add0 == strs_add1))
def contract_2e(eri, fcivec, norb, nelec, link_index=None): fcivec = numpy.asarray(fcivec, order='C') eri = ao2mo.restore(4, eri, norb) lib.transpose_sum(eri, inplace=True) eri *= .5 link_index = _unpack(norb, nelec, link_index) na, nlink = link_index.shape[:2] assert(fcivec.size == na**2) ci1 = numpy.empty((na,na)) libfci.FCIcontract_2e_spin0(eri.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nlink), link_index.ctypes.data_as(ctypes.c_void_p)) # no *.5 because FCIcontract_2e_spin0 only compute half of the contraction return lib.transpose_sum(ci1, inplace=True).reshape(fcivec.shape)
def Sijr(mc, dms, eris, verbose=None): #Subspace S_ijr^{(1)} mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) dm1 = dms['1'] dm2 = dms['2'] ncore = mo_core.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if eris is None: h1e = mc.h1e_for_cas()[0] h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0,2,1,3) h2e_v = ao2mo.incore.general(mc._scf._eri,[mo_virt,mo_core,mo_cas,mo_core],compact=False) h2e_v = h2e_v.reshape(mo_virt.shape[1],ncore,ncas,ncore).transpose(0,2,1,3) else: h1e = eris['h1eff'][ncore:nocc,ncore:nocc] h2e = eris['ppaa'][ncore:nocc,ncore:nocc].transpose(0,2,1,3) h2e_v = eris['pacv'][:ncore].transpose(3,1,2,0) if 'h1' in dms: hdm1 = dms['h1'] else: hdm1 = make_hdm1(dm1) a3 = make_a3(h1e,h2e,dm1,dm2,hdm1) # We sum norm and h only over i <= j (or j <= i instead). # See Eq. (13) and (A2) in https://doi.org/10.1063/1.1515317 # This implementation is still somewhat wasteful in terms of memory, # as we only need about half of norm and h in the end. ci_diag = numpy.diag_indices(ncore) ci_triu = numpy.triu_indices(ncore) norm = 2.0*numpy.einsum('rpji,raji,pa->rji',h2e_v,h2e_v,hdm1)\ - 1.0*numpy.einsum('rpji,raij,pa->rji',h2e_v,h2e_v,hdm1) norm += norm.transpose(0, 2, 1) norm[:, ci_diag[0], ci_diag[1]] *= 0.5 h = 2.0*numpy.einsum('rpji,raji,pa->rji',h2e_v,h2e_v,a3)\ - 1.0*numpy.einsum('rpji,raij,pa->rji',h2e_v,h2e_v,a3) h += h.transpose(0, 2, 1) h[:, ci_diag[0], ci_diag[1]] *= 0.5 diff = mc.mo_energy[nocc:,None,None] - mc.mo_energy[None,:ncore,None] - mc.mo_energy[None,None,:ncore] norm_tri = norm[:, ci_triu[0], ci_triu[1]] h_tri = h[:, ci_triu[0], ci_triu[1]] diff_tri = diff[:, ci_triu[0], ci_triu[1]] return _norm_to_energy(norm_tri, h_tri, diff_tri)
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None): cput0 = (time.clock(), time.time()) eris = _PhysicistsERIs() eris._common_init_(mycc, mo_coeff) nocc = eris.nocc nao, nmo = eris.mo_coeff.shape if callable(ao2mofn): eri = ao2mofn(eris.mo_coeff).reshape([nmo]*4) else: assert(eris.mo_coeff.dtype == np.double) mo_a = eris.mo_coeff[:nao//2] mo_b = eris.mo_coeff[nao//2:] orbspin = eris.orbspin if orbspin is None: eri = ao2mo.kernel(mycc._scf._eri, mo_a) eri += ao2mo.kernel(mycc._scf._eri, mo_b) eri1 = ao2mo.kernel(mycc._scf._eri, (mo_a,mo_a,mo_b,mo_b)) eri += eri1 eri += eri1.T else: mo = mo_a + mo_b eri = ao2mo.kernel(mycc._scf._eri, mo) if eri.size == nmo**4: # if mycc._scf._eri is a complex array sym_forbid = (orbspin[:,None] != orbspin).ravel() else: # 4-fold symmetry sym_forbid = (orbspin[:,None] != orbspin)[np.tril_indices(nmo)] eri[sym_forbid,:] = 0 eri[:,sym_forbid] = 0 if eri.dtype == np.double: eri = ao2mo.restore(1, eri, nmo) eri = eri.reshape(nmo,nmo,nmo,nmo) eri = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1) eris.oooo = eri[:nocc,:nocc,:nocc,:nocc].copy() eris.ooov = eri[:nocc,:nocc,:nocc,nocc:].copy() eris.oovv = eri[:nocc,:nocc,nocc:,nocc:].copy() eris.ovov = eri[:nocc,nocc:,:nocc,nocc:].copy() eris.ovvo = eri[:nocc,nocc:,nocc:,:nocc].copy() eris.ovvv = eri[:nocc,nocc:,nocc:,nocc:].copy() eris.vvvv = eri[nocc:,nocc:,nocc:,nocc:].copy() return eris
def enlarge_space(myci, civec_strs, eri, norb, nelec): if isinstance(civec_strs, (tuple, list)): nelec, (strsa, strsb) = selected_ci._unpack(civec_strs[0], nelec)[1:] ci_coeff = lib.asarray(civec_strs) else: ci_coeff, nelec, (strsa, strsb) = selected_ci._unpack(civec_strs, nelec) na = nb = len(strsa) ci0 = ci_coeff.reshape(-1, na, nb) abs_ci = abs(ci0).max(axis=0) eri = ao2mo.restore(1, eri, norb) eri_pq_max = abs(eri.reshape(norb**2, -1)).max(axis=1).reshape(norb, norb) civec_a_max = abs_ci.max(axis=1) ci_aidx = numpy.where(civec_a_max > myci.ci_coeff_cutoff)[0] civec_a_max = civec_a_max[ci_aidx] strsa = strsa[ci_aidx] strsa_add = selected_ci.select_strs(myci, eri, eri_pq_max, civec_a_max, strsa, norb, nelec[0]) strsa = numpy.append(strsa, strsa_add) aidx = numpy.argsort(strsa) strsa = strsa[aidx] aidx = numpy.where(aidx < len(ci_aidx))[0] ci_bidx = ci_aidx strsb = strsa bidx = aidx ma = mb = len(strsa) cs = [] for i in range(ci0.shape[0]): ci1 = numpy.zeros((ma, mb)) tmp = lib.take_2d(ci0[i], ci_aidx, ci_bidx) lib.takebak_2d(ci1, tmp, aidx, bidx) cs.append(selected_ci._as_SCIvector(ci1, (strsa, strsb))) if ci_coeff[0].ndim == 0 or ci_coeff[0].shape[-1] != nb: cs = [c.ravel() for c in cs] if (isinstance(ci_coeff, numpy.ndarray) and ci_coeff.shape[0] == na or ci_coeff.shape[0] == na * nb): cs = cs[0] return cs
def Sr(mc,ci,dms, eris=None, verbose=None): #The subspace S_r^{(-1)} mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) dm1 = dms['1'] dm2 = dms['2'] dm3 = dms['3'] #dm4 = dms['4'] ncore = mo_core.shape[1] nvirt = mo_virt.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if eris is None: h1e = mc.h1e_for_cas()[0] h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0,2,1,3) h2e_v = ao2mo.incore.general(mc._scf._eri,[mo_virt,mo_cas,mo_cas,mo_cas],compact=False) h2e_v = h2e_v.reshape(mo_virt.shape[1],ncas,ncas,ncas).transpose(0,2,1,3) core_dm = numpy.dot(mo_core,mo_core.T) *2 core_vhf = mc.get_veff(mc.mol,core_dm) h1e_v = reduce(numpy.dot, (mo_virt.T, mc.get_hcore()+core_vhf , mo_cas)) h1e_v -= numpy.einsum('mbbn->mn',h2e_v) else: h1e = eris['h1eff'][ncore:nocc,ncore:nocc] h2e = eris['ppaa'][ncore:nocc,ncore:nocc].transpose(0,2,1,3) h2e_v = eris['ppaa'][nocc:,ncore:nocc].transpose(0,2,1,3) h1e_v = eris['h1eff'][nocc:,ncore:nocc] - numpy.einsum('mbbn->mn',h2e_v) if getattr(mc.fcisolver, 'nevpt_intermediate', None): a16 = mc.fcisolver.nevpt_intermediate('A16',ncas,mc.nelecas,ci) else: a16 = make_a16(h1e,h2e, dms, ci, ncas, mc.nelecas) a17 = make_a17(h1e,h2e,dm2,dm3) a19 = make_a19(h1e,h2e,dm1,dm2) ener = numpy.einsum('ipqr,pqrabc,iabc->i',h2e_v,a16,h2e_v)\ + numpy.einsum('ipqr,pqra,ia->i',h2e_v,a17,h1e_v)*2.0\ + numpy.einsum('ip,pa,ia->i',h1e_v,a19,h1e_v) norm = numpy.einsum('ipqr,rpqbac,iabc->i',h2e_v,dm3,h2e_v)\ + numpy.einsum('ipqr,rpqa,ia->i',h2e_v,dm2,h1e_v)*2.0\ + numpy.einsum('ip,pa,ia->i',h1e_v,dm1,h1e_v) return _norm_to_energy(norm, ener, mc.mo_energy[nocc:])
def test_rdm_real(self): nocc = 6 nvir = 10 mf = scf.GHF(mol) nmo = nocc + nvir npair = nmo * (nmo // 2 + 1) // 4 numpy.random.seed(12) mf._eri = numpy.random.random(npair * (npair + 1) // 2) * .3 hcore = numpy.random.random((nmo, nmo)) * .5 hcore = hcore + hcore.T + numpy.diag(range(nmo)) * 2 mf.get_hcore = lambda *args: hcore mf.get_ovlp = lambda *args: numpy.eye(nmo) mf.mo_coeff = numpy.eye(nmo) mf.mo_occ = numpy.zeros(nmo) mf.mo_occ[:nocc] = 1 mycc = gccsd.GCCSD(mf) ecc, t1, t2 = mycc.kernel() l1, l2 = mycc.solve_lambda() dm1 = gccsd_rdm.make_rdm1(mycc, t1, t2, l1, l2) dm2 = gccsd_rdm.make_rdm2(mycc, t1, t2, l1, l2) nao = nmo // 2 mo_a = mf.mo_coeff[:nao] mo_b = mf.mo_coeff[nao:] eri = ao2mo.kernel(mf._eri, mo_a) eri += ao2mo.kernel(mf._eri, mo_b) eri1 = ao2mo.kernel(mf._eri, (mo_a, mo_a, mo_b, mo_b)) eri += eri1 eri += eri1.T eri = ao2mo.restore(1, eri, nmo) h1 = reduce(numpy.dot, (mf.mo_coeff.T.conj(), hcore, mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, dm1) e1 += numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1 += mol.energy_nuc() self.assertAlmostEqual(e1, mycc.e_tot, 7) self.assertAlmostEqual( abs(dm2 - dm2.transpose(1, 0, 3, 2).conj()).max(), 0, 9) self.assertAlmostEqual( abs(dm2 - dm2.transpose(2, 3, 0, 1)).max(), 0, 9) self.assertAlmostEqual( abs(dm2 + dm2.transpose(2, 1, 0, 3)).max(), 0, 9) self.assertAlmostEqual( abs(dm2 + dm2.transpose(0, 3, 2, 1)).max(), 0, 9)
def test_mp2_dm(self): nocc = mol.nelectron//2 nmo = mf.mo_energy.size nvir = nmo - nocc co = mf.mo_coeff[:,:nocc] cv = mf.mo_coeff[:,nocc:] g = ao2mo.incore.general(mf._eri, (co,cv,co,cv)).ravel() eia = mf.mo_energy[:nocc,None] - mf.mo_energy[nocc:] t2ref0 = g/(eia.reshape(-1,1)+eia.reshape(-1)).ravel() t2ref0 = t2ref0.reshape(nocc,nvir,nocc,nvir).transpose(0,2,3,1) pt = mp.mp2.MP2(mf) emp2, t2 = pt.kernel() t2s = numpy.zeros((nocc*2,nocc*2,nvir*2,nvir*2)) t2s[ ::2, ::2, ::2, ::2] = t2ref0 - t2ref0.transpose(0,1,3,2) t2s[1::2,1::2,1::2,1::2] = t2ref0 - t2ref0.transpose(0,1,3,2) t2s[ ::2,1::2,1::2, ::2] = t2ref0 t2s[1::2, ::2, ::2,1::2] = t2ref0 t2s[ ::2,1::2, ::2,1::2] = -t2ref0.transpose(0,1,3,2) t2s[1::2, ::2,1::2, ::2] = -t2ref0.transpose(0,1,3,2) dm1occ =-.5 * numpy.einsum('ikab,jkab->ij', t2s, t2s) dm1vir = .5 * numpy.einsum('ijac,ijbc->ab', t2s, t2s) dm1ref = numpy.zeros((nmo,nmo)) dm1ref[:nocc,:nocc] = dm1occ[ ::2, ::2]+dm1occ[1::2,1::2] dm1ref[nocc:,nocc:] = dm1vir[ ::2, ::2]+dm1vir[1::2,1::2] for i in range(nocc): dm1ref[i,i] += 2 dm1refao = reduce(numpy.dot, (mf.mo_coeff, dm1ref, mf.mo_coeff.T)) rdm1 = mp.mp2.make_rdm1(pt, t2ref0, ao_repr=True) self.assertTrue(numpy.allclose(rdm1, dm1refao)) self.assertTrue(numpy.allclose(pt.make_rdm1(), dm1ref)) rdm1 = mp.mp2.make_rdm1(pt, ao_repr=True) self.assertTrue(numpy.allclose(rdm1, dm1refao)) dm2ref = numpy.zeros((nmo*2,)*4) dm2ref[:nocc*2,nocc*2:,:nocc*2,nocc*2:] = t2s.transpose(0,3,1,2) * .5 dm2ref[nocc*2:,:nocc*2,nocc*2:,:nocc*2] = t2s.transpose(3,0,2,1) * .5 dm2ref = dm2ref[ ::2, ::2, ::2, ::2] + dm2ref[1::2,1::2,1::2,1::2] \ + dm2ref[ ::2, ::2,1::2,1::2] + dm2ref[1::2,1::2, ::2, ::2] eris = ao2mo.restore(1, ao2mo.full(mf._eri, mf.mo_coeff), mf.mo_coeff.shape[1]) self.assertAlmostEqual(numpy.einsum('iajb,iajb', eris, dm2ref)*.5, emp2, 9)
def solve_ERI(OEI, TEI, DMguess, numPairs): mol = gto.Mole() mol.build(verbose=3) mol.atom.append(('C', (0, 0, 0))) mol.nelectron = 2 * numPairs L = OEI.shape[0] mf = scf.RHF(mol) mf.get_hcore = lambda *args: OEI mf.get_ovlp = lambda *args: np.eye(L) mf._eri = ao2mo.restore(8, TEI, L) mf.scf(DMguess) DMloc = np.dot(np.dot(mf.mo_coeff, np.diag(mf.mo_occ)), mf.mo_coeff.T) if (mf.converged == False): mf = rhf_newtonraphson.solve(mf, dm_guess=DMloc) DMloc = np.dot(np.dot(mf.mo_coeff, np.diag(mf.mo_occ)), mf.mo_coeff.T) return DMloc
def Sij(mc, dms, eris, verbose=None): #Subspace S_ij^{(-2)} mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) dm1 = dms['1'] dm2 = dms['2'] dm3 = dms['3'] ncore = mo_core.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if mo_core.size == 0: return 0.0, 0 if eris is None: h1e = mc.h1e_for_cas()[0] h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0, 2, 1, 3) h2e_v = ao2mo.incore.general(mc._scf._eri, [mo_cas, mo_core, mo_cas, mo_core], compact=False) h2e_v = h2e_v.reshape(ncas, ncore, ncas, ncore).transpose(0, 2, 1, 3) else: h1e = eris['h1eff'][ncore:nocc, ncore:nocc] h2e = eris['ppaa'][ncore:nocc, ncore:nocc].transpose(0, 2, 1, 3) h2e_v = eris['papa'][:ncore, :, :ncore].transpose(1, 3, 0, 2) if 'h1' in dms: hdm1 = dms['h1'] else: hdm1 = make_hdm1(dm1) if 'h2' in dms: hdm2 = dms['h2'] else: hdm2 = make_hdm2(dm1, dm2) if 'h3' in dms: hdm3 = dms['h3'] else: hdm3 = make_hdm3(dm1, dm2, dm3, hdm1, hdm2) # a9 is very sensitive to the accuracy of HF orbital and CI wfn a9 = make_a9(h1e, h2e, hdm1, hdm2, hdm3) norm = 0.5 * numpy.einsum('qpij,baij,pqab->ij', h2e_v, h2e_v, hdm2) h = 0.5 * numpy.einsum('qpij,baij,pqab->ij', h2e_v, h2e_v, a9) diff = mc.mo_energy[:ncore, None] + mc.mo_energy[None, :ncore] return _norm_to_energy(norm, h, -diff)
def get_init_guess (fci, norb, nelec, norb_f, h1, h2, nelec_f=None, smult_f=None): if nelec_f is None: nelec_f = _guess_nelec_f (fci, norb, nelec, norb_f, h1, h2) if smult_f is None: smult_f = [abs(n[0]-n[1])+1 for n in nelec_f] h2 = ao2mo.restore (1, h2, norb) i = 0 ci0_f = [] for no, ne, s in zip (norb_f, nelec_f, smult_f): j = i + no h1_i = h1[i:j,i:j] h2_i = h2[i:j,i:j,i:j,i:j] i = j csf = csf_solver (fci.mol, smult=s) hdiag = csf.make_hdiag_csf (h1_i, h2_i, no, ne) ci = csf.get_init_guess (no, ne, 1, hdiag)[0] ci = np.squeeze (fockspace.hilbert2fock (ci, no, ne)) ci0_f.append (ci) return ci0_f
def enlarge_space(myci, civec_strs, eri, norb, nelec): if isinstance(civec_strs, (tuple, list)): nelec, (strsa, strsb) = _unpack(civec_strs[0], nelec)[1:] ci_coeff = lib.asarray(civec_strs) else: ci_coeff, nelec, (strsa, strsb) = _unpack(civec_strs, nelec) na = len(strsa) nb = len(strsb) ci0 = ci_coeff.reshape(-1,na,nb) civec_a_max = lib.norm(ci0, axis=2).max(axis=0) civec_b_max = lib.norm(ci0, axis=1).max(axis=0) ci_aidx = numpy.where(civec_a_max > myci.ci_coeff_cutoff)[0] ci_bidx = numpy.where(civec_b_max > myci.ci_coeff_cutoff)[0] civec_a_max = civec_a_max[ci_aidx] civec_b_max = civec_b_max[ci_bidx] strsa = strsa[ci_aidx] strsb = strsb[ci_bidx] eri = ao2mo.restore(1, eri, norb) eri_pq_max = abs(eri.reshape(norb**2,-1)).max(axis=1).reshape(norb,norb) strsa_add = select_strs(myci, eri, eri_pq_max, civec_a_max, strsa, norb, nelec[0]) strsb_add = select_strs(myci, eri, eri_pq_max, civec_b_max, strsb, norb, nelec[1]) strsa = numpy.append(strsa, strsa_add) strsb = numpy.append(strsb, strsb_add) aidx = numpy.argsort(strsa) bidx = numpy.argsort(strsb) ci_strs = (strsa[aidx], strsb[bidx]) aidx = numpy.where(aidx < len(ci_aidx))[0] bidx = numpy.where(bidx < len(ci_bidx))[0] ma = len(strsa) mb = len(strsb) cs = [] for i in range(ci0.shape[0]): ci1 = numpy.zeros((ma,mb)) tmp = lib.take_2d(ci0[i], ci_aidx, ci_bidx) lib.takebak_2d(ci1, tmp, aidx, bidx) cs.append(_as_SCIvector(ci1, ci_strs)) if not isinstance(civec_strs, (tuple, list)) and civec_strs.ndim < 3: cs = cs[0] return cs
def TestRestore(): for sym in [1, 4, 8]: print("\n symmetry = ", sym) norb = 8 g2e = np.zeros((norb, norb, norb, norb)) #g2e[4,4,5,5] = 2*U; g2e[4, 4, 5, 5] = U g2e[5, 5, 4, 4] = U for i1 in range(norb): for i2 in range(norb): for i3 in range(norb): for i4 in range(norb): if g2e[i1, i2, i3, i4] != 0: print("g2e[", i1, i2, i3, i4, "] = ", g2e[i1, i2, i3, i4]) g2e2 = ao2mo.restore(sym, g2e, norb) del g2e if (sym == 1): print(sym, np.shape(g2e2)) for i1 in range(norb): for i2 in range(norb): for i3 in range(norb): for i4 in range(norb): if g2e2[i1, i2, i3, i4] != 0: print("--> g2e2[", i1, i2, i3, i4, "] = ", g2e2[i1, i2, i3, i4]) elif (sym == 4): print(sym, np.shape(g2e2)) for i1 in range(np.shape(g2e2)[0]): for i2 in range(np.shape(g2e2)[1]): if g2e2[i1, i2] != 0: print("--> g2e2[", i1, i2, "] = ", g2e2[i1, i2]) elif (sym == 8): print(sym, np.shape(g2e2)) for i1 in range(np.shape(g2e2)[0]): if g2e2[i1] != 0: print("--> g2e2[", i1, "] = ", g2e2[i1])
def test_ccsd_rdm(self): mcc = cc.ccsd.CC(mf) mcc.max_memory = 0 mcc.conv_tol = 1e-9 mcc.conv_tol_normt = 1e-7 mcc.kernel() mcc.solve_lambda() dm1 = mcc.make_rdm1() dm2 = mcc.make_rdm2() self.assertAlmostEqual(numpy.linalg.norm(dm1), 4.4227785269355078, 3) self.assertAlmostEqual(numpy.linalg.norm(dm2), 20.074587448789089, 3) nmo = mf.mo_coeff.shape[1] eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo) h1 = reduce(numpy.dot, (mf.mo_coeff.T.conj(), mf.get_hcore(), mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mf.energy_nuc() self.assertAlmostEqual(e1, mcc.e_tot, 7)
def kernel(self, h1, h2, norb, nelec, ci0=None, ecore=0, **kwargs): fakemol = gto.M(verbose=0) nelec = numpy.sum(nelec) fakemol.nelectron = nelec fake_hf = scf.RHF(fakemol) fake_hf._eri = ao2mo.restore(8, h2, norb) fake_hf.get_hcore = lambda *args: h1 fake_hf.get_ovlp = lambda *args: numpy.eye(norb) fake_hf.kernel() self.myci = ci.CISD(fake_hf) self.myci.conv_tol = 1e-7 self.myci.max_cycle = 150 self.myci.max_space = 12 self.myci.lindep = 1e-10 self.myci.nroots = 1 self.myci.level_shift = 0.2 # in precond e_corr, civec = self.myci.kernel() e = fake_hf.e_tot + e_corr return e + ecore, civec
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0): if orbsym is None: return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index) eri = ao2mo.restore(4, eri, norb) neleca, nelecb = direct_spin1._unpack_nelec(nelec) assert(neleca == nelecb) link_indexa = direct_spin0._unpack(norb, nelec, link_index) na, nlinka = link_indexa.shape[:2] eri_irs, rank_eri, irrep_eri = direct_spin1_symm.reorder_eri(eri, norb, orbsym) strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca)) aidx, link_indexa = direct_spin1_symm.gen_str_irrep(strsa, orbsym, link_indexa, rank_eri, irrep_eri) Tirrep = ctypes.c_void_p*TOTIRREPS linka_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa]) eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs]) dimirrep = (ctypes.c_int*TOTIRREPS)(*[x.shape[0] for x in eri_irs]) fcivec_shape = fcivec.shape fcivec = fcivec.reshape((na,na), order='C') ci1new = numpy.zeros_like(fcivec) nas = (ctypes.c_int*TOTIRREPS)(*[x.size for x in aidx]) ci0 = [] ci1 = [] for ir in range(TOTIRREPS): ma, mb = aidx[ir].size, aidx[wfnsym^ir].size ci0.append(numpy.zeros((ma,mb))) ci1.append(numpy.zeros((ma,mb))) if ma > 0 and mb > 0: lib.take_2d(fcivec, aidx[ir], aidx[wfnsym^ir], out=ci0[ir]) ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0]) ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1]) libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs, ctypes.c_int(norb), nas, nas, ctypes.c_int(nlinka), ctypes.c_int(nlinka), linka_ptr, linka_ptr, dimirrep, ctypes.c_int(wfnsym)) for ir in range(TOTIRREPS): if ci0[ir].size > 0: lib.takebak_2d(ci1new, ci1[ir], aidx[ir], aidx[wfnsym^ir]) return lib.transpose_sum(ci1new, inplace=True).reshape(fcivec_shape)
def contract_2e(eri, fcivec, norb, nelec, link_index=None): r'''Contract the 2-electron Hamiltonian with a FCI vector to get a new FCI vector. Note the input arg eri is NOT the 2e hamiltonian matrix, the 2e hamiltonian is .. math:: h2e &= eri_{pq,rs} p^+ q r^+ s \\ &= (pq|rs) p^+ r^+ s q - (pq|rs) \delta_{qr} p^+ s So eri is defined as .. math:: eri_{pq,rs} = (pq|rs) - (1/Nelec) \sum_q (pq|qs) to restore the symmetry between pq and rs, .. math:: eri_{pq,rs} = (pq|rs) - (.5/Nelec) [\sum_q (pq|qs) + \sum_p (pq|rp)] See also :func:`direct_spin1.absorb_h1e` ''' fcivec = numpy.asarray(fcivec, order='C') eri = ao2mo.restore(4, eri, norb) link_indexa, link_indexb = _unpack(norb, nelec, link_index) na, nlinka = link_indexa.shape[:2] nb, nlinkb = link_indexb.shape[:2] assert(fcivec.size == na*nb) ci1 = numpy.empty_like(fcivec) libfci.FCIcontract_2e_spin1(eri.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(nlinka), ctypes.c_int(nlinkb), link_indexa.ctypes.data_as(ctypes.c_void_p), link_indexb.ctypes.data_as(ctypes.c_void_p)) return ci1
def v2rdm_pyscf(): # pyscf reference np.set_printoptions(linewidth=500) basis = 'STO-3G' mol = pyscf.M( atom='B 0 0 0; H 0 0 {}'.format(1.1), basis=basis) mf = mol.RHF() mf.verbose = 3 mf.run() # make h1 and spatial integrals in MO basis eri = ao2mo.kernel(mol, mf.mo_coeff) eri = ao2mo.restore(1, eri, mf.mo_coeff.shape[1]) # this produces spatial MO h1 integrals h1 = reduce(np.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) # these parameters are hard-coded for now nalpha = 3 nbeta = 3 nmo = 6 # hilbert options psi4.set_module_options('hilbert', { #'sdp_solver': 'rrsdp', 'positivity': 'dqg', 'r_convergence': 1e-5, 'e_convergence': 1e-4, 'maxiter': 20000, }) # grab options object options = psi4.core.get_options() options.set_current_module('HILBERT') v2rdm_pyscf = hilbert.v2RDMHelper(nalpha,nbeta,nmo,h1.flatten(),eri.flatten(),options) current_energy = v2rdm_pyscf.compute_energy() return current_energy
def rhf_external(mf, verbose=None): log = logger.new_logger(mf, verbose) mol = mf.mol mo_coeff = mf.mo_coeff mo_energy = mf.mo_energy mo_occ = mf.mo_occ nmo = mo_coeff.shape[1] nocc = numpy.count_nonzero(mo_occ) nvir = nmo - nocc nov = nocc * nvir eri_mo = ao2mo.full(mol, mo_coeff) eri_mo = ao2mo.restore(1, eri_mo, nmo) eai = lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) # A h = numpy.einsum('ckld->kcld', eri_mo[nocc:,:nocc,:nocc,nocc:]) * 2 h-= numpy.einsum('cdlk->kcld', eri_mo[nocc:,nocc:,:nocc,:nocc]) for a in range(nvir): for i in range(nocc): h[i,a,i,a] += eai[a,i] # B h-= numpy.einsum('ckdl->kcld', eri_mo[nocc:,:nocc,nocc:,:nocc]) * 2 h+= numpy.einsum('cldk->kcld', eri_mo[nocc:,:nocc,nocc:,:nocc]) e1 = scipy.linalg.eigh(h.reshape(nov,nov))[0] log.debug('rhf_external: lowest eigs = %s', e1[e1<=max(e1[0],1e-5)]) if e1[0] < -1e-5: log.log('RHF wavefunction has an RHF real -> complex instablity') else: log.log('RHF wavefunction is stable in the RHF real -> complex stablity analysis') h =-numpy.einsum('cdlk->kcld', eri_mo[nocc:,nocc:,:nocc,:nocc]) for a in range(nvir): for i in range(nocc): h[i,a,i,a] += eai[a,i] h-= numpy.einsum('cldk->kcld', eri_mo[nocc:,:nocc,nocc:,:nocc]) e3 = scipy.linalg.eigh(h.reshape(nov,nov))[0] log.debug('rhf_external: lowest eigs of H = %s', e3[e3<=max(e3[0],1e-5)]) if e3[0] < -1e-5: log.log('RHF wavefunction has an RHF -> UHF instablity.') else: log.log('RHF wavefunction is stable in the RHF -> UHF stablity analysis')
def test_rdm(self): mol = gto.Mole() mol.verbose = 5 mol.output = '/dev/null' mol.atom = [ ['O', ( 0., 0. , 0. )], ['H', ( 0., -0.757, 0.587)], ['H', ( 0., 0.757 , 0.587)],] mol.basis = {'H': 'sto-3g', 'O': 'sto-3g',} mol.build() mf = scf.RHF(mol).run(conv_tol=1e-14) myci = ci.CISD(mf) myci.frozen = 1 eris = myci.ao2mo() ecisd, civec = myci.kernel(eris=eris) self.assertAlmostEqual(ecisd, -0.048800218694077746, 8) nmo = myci.nmo nocc = myci.nocc strs = fci.cistring.gen_strings4orblist(range(nmo+1), nocc+1) mask = (strs & 1) != 0 sub_strs = strs[mask] addrs = fci.cistring.strs2addr(nmo+1, nocc+1, sub_strs) na = len(strs) ci0 = numpy.zeros((na,na)) ci0[addrs[:,None],addrs] = myci.to_fcivec(civec, nmo, nocc*2) ref1, ref2 = fci.direct_spin1.make_rdm12(ci0, (nmo+1), (nocc+1)*2) rdm1 = myci.make_rdm1(civec) rdm2 = myci.make_rdm2(civec) self.assertTrue(numpy.allclose(rdm2, ref2)) self.assertAlmostEqual(abs(rdm2-rdm2.transpose(2,3,0,1)).sum(), 0, 9) self.assertAlmostEqual(abs(rdm2-rdm2.transpose(1,0,3,2)).sum(), 0, 9) dm1 = numpy.einsum('ijkk->ij', rdm2)/(mol.nelectron-1) self.assertAlmostEqual(abs(rdm1 - dm1).sum(), 0, 9) h1 = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo+1) e1 = numpy.einsum('ij,ji', h1, rdm1) e1+= numpy.einsum('ijkl,ijkl', eri, rdm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, myci.e_tot, 7)
def Sir(mc, dms, eris, verbose=None): #Subspace S_il^{(0)} mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) dm1 = dms['1'] dm2 = dms['2'] dm3 = dms['3'] ncore = mo_core.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if eris is None: h1e = mc.h1e_for_cas()[0] h2e = ao2mo.restore(1, mc.ao2mo(mo_cas), ncas).transpose(0,2,1,3) h2e_v1 = ao2mo.incore.general(mc._scf._eri,[mo_virt,mo_core,mo_cas,mo_cas],compact=False) h2e_v1 = h2e_v1.reshape(mo_virt.shape[1],ncore,ncas,ncas).transpose(0,2,1,3) h2e_v2 = ao2mo.incore.general(mc._scf._eri,[mo_virt,mo_cas,mo_cas,mo_core],compact=False) h2e_v2 = h2e_v2.reshape(mo_virt.shape[1],ncas,ncas,ncore).transpose(0,2,1,3) else: h1e = eris['h1eff'][ncore:nocc,ncore:nocc] h2e = eris['ppaa'][ncore:nocc,ncore:nocc].transpose(0,2,1,3) h2e_v1 = eris['ppaa'][nocc:,:ncore].transpose(0,2,1,3) h2e_v2 = eris['papa'][nocc:,:,:ncore].transpose(0,3,1,2) h1e_v = eris['h1eff'][nocc:,:ncore] norm = numpy.einsum('rpiq,raib,qpab->ir',h2e_v1,h2e_v1,dm2)*2.0\ - numpy.einsum('rpiq,rabi,qpab->ir',h2e_v1,h2e_v2,dm2)\ - numpy.einsum('rpqi,raib,qpab->ir',h2e_v2,h2e_v1,dm2)\ + numpy.einsum('raqi,rabi,qb->ir',h2e_v2,h2e_v2,dm1)*2.0\ - numpy.einsum('rpqi,rabi,qbap->ir',h2e_v2,h2e_v2,dm2)\ + numpy.einsum('rpqi,raai,qp->ir',h2e_v2,h2e_v2,dm1)\ + numpy.einsum('rpiq,ri,qp->ir',h2e_v1,h1e_v,dm1)*4.0\ - numpy.einsum('rpqi,ri,qp->ir',h2e_v2,h1e_v,dm1)*2.0\ + numpy.einsum('ri,ri->ir',h1e_v,h1e_v)*2.0 a12 = make_a12(h1e,h2e,dm1,dm2,dm3) a13 = make_a13(h1e,h2e,dm1,dm2,dm3) h = numpy.einsum('rpiq,raib,pqab->ir',h2e_v1,h2e_v1,a12)*2.0\ - numpy.einsum('rpiq,rabi,pqab->ir',h2e_v1,h2e_v2,a12)\ - numpy.einsum('rpqi,raib,pqab->ir',h2e_v2,h2e_v1,a12)\ + numpy.einsum('rpqi,rabi,pqab->ir',h2e_v2,h2e_v2,a13) diff = mc.mo_energy[:ncore,None] - mc.mo_energy[None,nocc:] return _norm_to_energy(norm, h, -diff)
def general(mydf, mo_coeffs, kpts=None, compact=False): '''General MO integral transformation''' cell = mydf.cell kptijkl = _format_kpts(kpts) kpti, kptj, kptk, kptl = kptijkl if isinstance(mo_coeffs, numpy.ndarray) and mo_coeffs.ndim == 2: mo_coeffs = (mo_coeffs,) * 4 mo_coeffs = [numpy.asarray(mo, order='F') for mo in mo_coeffs] allreal = not any(numpy.iscomplexobj(mo) for mo in mo_coeffs) q = kptj - kpti coulG = tools.get_coulG(cell, q, gs=mydf.gs) coords = cell.gen_uniform_grids(mydf.gs) max_memory = mydf.max_memory - lib.current_memory()[0] if gamma_point(kptijkl) and allreal: ao = mydf._numint.eval_ao(cell, coords, kpti)[0] if ((iden_coeffs(mo_coeffs[0], mo_coeffs[2]) and iden_coeffs(mo_coeffs[1], mo_coeffs[3]))): moiT = mojT = numpy.asarray(lib.dot(mo_coeffs[0].T,ao.T), order='C') ao = None max_memory = max_memory - moiT.nbytes*1e-6 eri = _contract_compact(mydf, (moiT,mojT), coulG, max_memory=max_memory) if not compact: nmo = moiT.shape[0] eri = ao2mo.restore(1, eri, nmo).reshape(nmo**2,nmo**2) else: mos = [numpy.asarray(lib.dot(c.T, ao.T), order='C') for c in mo_coeffs] ao = None fac = numpy.array(1.) max_memory = max_memory - sum([x.nbytes for x in mos])*1e-6 eri = _contract_plain(mydf, mos, coulG, fac, max_memory=max_memory).real return eri else: aos = mydf._numint.eval_ao(cell, coords, kptijkl) mos = [numpy.asarray(lib.dot(c.T, aos[i].T), order='C') for i,c in enumerate(mo_coeffs)] aos = None fac = numpy.exp(-1j * numpy.dot(coords, q)) max_memory = max_memory - sum([x.nbytes for x in mos])*1e-6 eri = _contract_plain(mydf, mos, coulG, fac, max_memory=max_memory) return eri
def test_eri0000(self): with_df = mdf.MDF(cell) with_df.kpts = numpy.zeros((4,3)) mo =(numpy.random.random((nao,nao)) + numpy.random.random((nao,nao))*1j) eri = ao2mo.restore(1, with_df.get_eri(with_df.kpts), nao) eri0 = numpy.einsum('pjkl,pi->ijkl', eri , mo.conj()) eri0 = numpy.einsum('ipkl,pj->ijkl', eri0, mo ) eri0 = numpy.einsum('ijpl,pk->ijkl', eri0, mo.conj()) eri0 = numpy.einsum('ijkp,pl->ijkl', eri0, mo ) eri1 = with_df.ao2mo(mo, with_df.kpts) self.assertAlmostEqual(abs(eri1.reshape(eri0.shape)-eri0).sum(), 0, 9) mo = mo.real eri0 = numpy.einsum('pjkl,pi->ijkl', eri , mo.conj()) eri0 = numpy.einsum('ipkl,pj->ijkl', eri0, mo ) eri0 = numpy.einsum('ijpl,pk->ijkl', eri0, mo.conj()) eri0 = numpy.einsum('ijkp,pl->ijkl', eri0, mo ) eri1 = with_df.ao2mo(mo, with_df.kpts, compact=False) self.assertAlmostEqual(abs(eri1.reshape(eri0.shape)-eri0).sum(), 0, 9)
def get_ES(n, na, nb, Enuc, h1, h2): mol_FC = gto.M(verbose=0) mol_FC.charge = 0 mol_FC.nelectron = na + nb mol_FC.spin = na - nb mol_FC.incore_anyway = True mol_FC.nao_nr = lambda *args: n mol_FC.energy_nuc = lambda *args: Enuc mf_FC = scf.RHF(mol_FC) mf_FC.get_hcore = lambda *args: h1 mf_FC.get_ovlp = lambda *args: np.eye(n) mf_FC._eri = ao2mo.restore(8, h2, n) rho = np.zeros((n, n)) for i in range(na): rho[i, i] = 2.0 Ehf = mf_FC.kernel(rho) + Enuc Ecc = (cc.CCSD(mf_FC)).kernel()[0] return Ehf, Ecc, mol_FC, mf_FC
def kernel(self, h1e, eri, norb, nelec, ci0=None, ecore=0, **kwargs): if isinstance(nelec, (int, numpy.integer)): nelecb = nelec // 2 neleca = nelec - nelecb else: neleca, nelecb = nelec h2e = self.absorb_h1e(h1e, eri, norb, nelec, .5) h2e = ao2mo.restore(1, h2e, norb) hdiag = self.make_hdiag(h1e, eri, norb, nelec) nroots = 1 if ci0 is None: ci0 = self.get_init_guess(norb, nelec, nroots, hdiag) def hop(c): return self.contract_2e(h2e, c, norb, nelec) precond = lambda x, e, *args: x / (hdiag - e + 1e-4) e, c = lib.davidson(hop, ci0, precond, **kwargs) return e + ecore, c
def make_hdiag(h1e, eri, norb, nelec, opt=None): if isinstance(nelec, (int, numpy.integer)): nelecb = nelec // 2 neleca = nelec - nelecb else: neleca, nelecb = nelec occslista = cistring._gen_occslst(range(norb), neleca) eri = ao2mo.restore(1, eri, norb) diagj = numpy.einsum('iijj->ij', eri) diagk = numpy.einsum('ijji->ij', eri) hdiag = [] for aocc in occslista: bocc = aocc e1 = h1e[aocc, aocc].sum() + h1e[bocc, bocc].sum() e2 = diagj[aocc][:,aocc].sum() + diagj[aocc][:,bocc].sum() \ + diagj[bocc][:,aocc].sum() + diagj[bocc][:,bocc].sum() \ - diagk[aocc][:,aocc].sum() - diagk[bocc][:,bocc].sum() hdiag.append(e1 + e2 * .5) return numpy.array(hdiag)
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None): cput0 = (time.clock(), time.time()) eris = _ChemistsERIs() eris._common_init_(mycc, mo_coeff) nocc = eris.nocc nmo = eris.fock.shape[0] if callable(ao2mofn): eri1 = ao2mofn(eris.mo_coeff).reshape([nmo] * 4) else: eri1 = ao2mo.incore.full(mycc._scf._eri, eris.mo_coeff) eri1 = ao2mo.restore(1, eri1, nmo) eris.oooo = eri1[:nocc, :nocc, :nocc, :nocc].copy() eris.ovoo = eri1[:nocc, nocc:, :nocc, :nocc].copy() eris.ovov = eri1[:nocc, nocc:, :nocc, nocc:].copy() eris.oovv = eri1[:nocc, :nocc, nocc:, nocc:].copy() eris.ovvo = eri1[:nocc, nocc:, nocc:, :nocc].copy() eris.ovvv = eri1[:nocc, nocc:, nocc:, nocc:].copy() logger.timer(mycc, 'GW integral transformation', *cput0) return eris
def two_body_integrals(self): """A 4-dimension array for electron repulsion integrals in the MO representation. The integrals are computed as h[p,q,r,s]=\int \phi_p(x)* \phi_q(y)* V_{elec-elec} \phi_r(y) \phi_s(x) dxdy """ if self._two_body_integrals is None: mol = self._pyscf_data.get('mol', None) mo = self.canonical_orbitals n_orbitals = mo.shape[1] eri = ao2mo.kernel(mol, mo) eri = ao2mo.restore( 1, # no permutation symmetry eri, n_orbitals) # See PQRS convention in OpenFermion.hamiltonians.molecular_data # h[p,q,r,s] = (ps|qr) = pyscf_eri[p,s,q,r] self._two_body_integrals = numpy.asarray(eri.transpose(0, 2, 3, 1), order='C') return self._two_body_integrals