def test_r_outcore_eri(self): n2c = mol.nao_2c() numpy.random.seed(1) mo = numpy.random.random((n2c,n2c)) + numpy.random.random((n2c,n2c))*1j eriref = trans(eri0, [mo]*4) ftmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, mo, erifile=ftmp.name, intor='int2e_spinor', max_memory=10, ioblk_size=5) with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(lib.finger(eri1), -550.72966498073129-1149.3561026721848j, 8) self.assertAlmostEqual(abs(eri1-eriref.reshape(n2c**2,n2c**2)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), erifile=ftmp.name, intor='int2e_spinor') with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) ftmp = lib.H5TmpFile() ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), erifile=ftmp, intor='int2e_spinor', aosym='s1') with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:4], mo[:,:2]), intor='int2e_spinor', aosym='s2ij') self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:4,:2].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), intor='int2e_spinor', aosym='s2kl') self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, mo[:,:0], intor='int2e_spinor') self.assertTrue(eri1.size == 0)
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 test_r_outcore_eri(self): n2c = mol.nao_2c() numpy.random.seed(1) mo = numpy.random.random((n2c,n2c)) + numpy.random.random((n2c,n2c))*1j eriref = trans(eri0, [mo]*4) ftmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, mo, ftmp.name, intor='int2e_spinor', max_memory=10, ioblk_size=5) with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(lib.finger(eri1), -550.72966498073129-1149.3561026721848j, 8) self.assertAlmostEqual(abs(eri1-eriref.reshape(n2c**2,n2c**2)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), ftmp.name, intor='int2e_spinor') with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) ftmp = lib.H5TmpFile() ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), ftmp, intor='int2e_spinor', aosym='s1') with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:4], mo[:,:2]), intor='int2e_spinor', aosym='s2ij') self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:4,:2].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), intor='int2e_spinor', aosym='s2kl') self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, mo[:,:0], intor='int2e_spinor') self.assertTrue(eri1.size == 0)
def kernel(self): ''' This is a simplified version of pyscf.mp.mp2. ''' # init nmo = len(self._vhf.mo_energy) no = self.mol.nelectron // 2 nv = nmo - no emp2 = 0 co = self._vhf.mo_coeff[:, :no] cv = self._vhf.mo_coeff[:, no:] # g from pyscf.scf import _vhf eri = _vhf.int2e_sph(self.mol._atm, self.mol._bas, self.mol._env) eri = ao2mo.incore.general(eri, (co, cv, co, cv)) # mp2 eia = pyscf.lib.direct_sum('i-a->ia', self._vhf.mo_energy[:no], self._vhf.mo_energy[no:]) with ao2mo.load(eri) as g: for i in xrange(no): gi = np.asarray(g[i * nv: (i + 1) * nv]) gi = gi.reshape(nv, no, nv).transpose(1,0,2) #t2[i] = gi / pyscf.lib.direct_sum('jb+a->jba', eia, eia[i]) t2i = gi / pyscf.lib.direct_sum('jb+a->jba', eia, eia[i]) theta = gi * 2 - gi.transpose(0,2,1) emp2 += (t2i * theta).sum() self.eMP2 = emp2
def ao2mo(self, mo_coeff): log = logger.Logger(self.stdout, self.verbose) time0 = (time.clock(), time.time()) log.debug('transform (ia|jb)') nmo = self.nmo nocc = self.nocc nvir = nmo - nocc co = mo_coeff[:, :nocc] cv = mo_coeff[:, nocc:] mem_incore, mem_outcore, mem_basic = _mem_usage(nocc, nvir) mem_now = pyscf.lib.current_memory()[0] if mem_now < mem_basic: warnings.warn( '%s: Not enough memory. Available mem %s MB, required mem %s MB\n' % (self.ao2mo, mem_now, mem_basic)) if (self._scf._eri is not None and mem_incore + mem_now < self.max_memory or self.mol.incore_anyway): if self._scf._eri is None: eri = self.intor('cint2e_sph', aosym='s8') else: eri = self._scf._eri eri = ao2mo.incore.general(eri, (co, cv, co, cv)) else: max_memory = max(2000, self.max_memory * .9 - mem_now) erifile = tempfile.NamedTemporaryFile() ao2mo.outcore.general(self.mol, (co, cv, co, cv), erifile.name, max_memory=max_memory, verbose=self.verbose) eri = erifile time1 = log.timer('Integral transformation', *time0) return ao2mo.load(eri)
def Sijrs(mc, eris, verbose=None): mo_core, mo_cas, mo_virt = _extract_orbs(mc, mc.mo_coeff) ncore = mo_core.shape[1] nvirt = mo_virt.shape[1] ncas = mo_cas.shape[1] nocc = ncore + ncas if eris is None: erifile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) feri = ao2mo.outcore.general(mc.mol, (mo_core,mo_virt,mo_core,mo_virt), erifile.name, verbose=mc.verbose) else: feri = eris['cvcv'] eia = mc.mo_energy[:ncore,None] -mc.mo_energy[None,nocc:] norm = 0 e = 0 with ao2mo.load(feri) as cvcv: for i in range(ncore): djba = (eia.reshape(-1,1) + eia[i].reshape(1,-1)).ravel() gi = numpy.asarray(cvcv[i*nvirt:(i+1)*nvirt]) gi = gi.reshape(nvirt,ncore,nvirt).transpose(1,2,0) t2i = (gi.ravel()/djba).reshape(ncore,nvirt,nvirt) # 2*ijab-ijba theta = gi*2 - gi.transpose(0,2,1) norm += numpy.einsum('jab,jab', gi, theta) e += numpy.einsum('jab,jab', t2i, theta) return norm, e
def ao2mo(self, mo_coeff): log = logger.Logger(self.stdout, self.verbose) time0 = (time.clock(), time.time()) log.debug('transform (ia|jb)') nmo = self.nmo nocc = self.nocc nvir = nmo - nocc co = mo_coeff[:,:nocc] cv = mo_coeff[:,nocc:] mem_incore, mem_outcore, mem_basic = _mem_usage(nocc, nvir) mem_now = pyscf.lib.current_memory()[0] if mem_now < mem_basic: warnings.warn('%s: Not enough memory. Available mem %s MB, required mem %s MB\n' % (self.ao2mo, mem_now, mem_basic)) if (self._scf._eri is not None and mem_incore+mem_now < self.max_memory or self.mol.incore_anyway): if self._scf._eri is None: eri = self.intor('cint2e_sph', aosym='s8') else: eri = self._scf._eri eri = ao2mo.incore.general(eri, (co,cv,co,cv)) else: max_memory = max(2000, self.max_memory*.9-mem_now) erifile = tempfile.NamedTemporaryFile() ao2mo.outcore.general(self.mol, (co,cv,co,cv), erifile.name, max_memory=max_memory, verbose=self.verbose) eri = erifile time1 = log.timer('Integral transformation', *time0) return ao2mo.load(eri)
def ao2mo(self, mo_coeff): log = logger.Logger(self.stdout, self.verbose) time0 = (time.clock(), time.time()) log.debug('transform (ia|jb)') nmo = self.nmo nocc = self.nocc nvir = nmo - nocc co = mo_coeff[:,:nocc] cv = mo_coeff[:,nocc:] mem_incore, mem_outcore, mem_basic = _mem_usage(nocc, nvir) mem_now = pyscf.lib.current_memory()[0] if (self._scf._eri is not None and mem_incore+mem_now < self.max_memory or self.mol.incore_anyway): if self._scf._eri is None: from pyscf.scf import _vhf eri = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) else: eri = self._scf._eri eri = ao2mo.incore.general(eri, (co,cv,co,cv)) else: max_memory = max(2000, self.max_memory*.9-mem_now) erifile = tempfile.NamedTemporaryFile() ao2mo.outcore.general(self.mol, (co,cv,co,cv), erifile.name, max_memory=max_memory-mem_basic, verbose=self.verbose) eri = erifile time1 = log.timer('Integral transformation', *time0) return ao2mo.load(eri)
def test_full(self): nao = mol.nao mo = numpy.random.random((nao,4)) eri = mol.intor('int2e', aosym='s4') eri = ao2mo.kernel(eri, mo, compact=False) self.assertEqual(eri.shape, (16,16)) h5file = lib.H5TmpFile() ao2mo.kernel(mol, mo, h5file, intor='int2e', dataname='eri') with ao2mo.load(h5file, 'eri') as eri: self.assertEqual(eri.shape, (10,10)) ftmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, mo, ftmp, intor='int2e', dataname='eri') with ao2mo.load(ftmp, 'eri') as eri: self.assertEqual(eri.shape, (10,10))
def test_full(self): nao = mol.nao mo = numpy.random.random((nao, 4)) eri = mol.intor('int2e', aosym='s4') eri = ao2mo.kernel(eri, mo, compact=False) self.assertEqual(eri.shape, (16, 16)) h5file = lib.H5TmpFile() ao2mo.kernel(mol, mo, erifile=h5file, intor='int2e', dataname='eri') with ao2mo.load(h5file, 'eri') as eri: self.assertEqual(eri.shape, (10, 10)) ftmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, mo, ftmp, intor='int2e', dataname='eri') with ao2mo.load(ftmp, 'eri') as eri: self.assertEqual(eri.shape, (10, 10))
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_general_complex(self): numpy.random.seed(15) nmo = 12 mo = numpy.random.random((nao,nmo)) + numpy.random.random((nao,nmo))*1j eriref = lib.einsum('pqrs,pi,qj,rk,sl->ijkl', ao2mo.restore(1, eri, nao), mo.conj(), mo, mo.conj(), mo) eriref = eriref.reshape(12**2,12**2) 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)
def get_t2(mo_coeff, nocc): nmo = mo_coeff.shape[1] nvir = nmo - nocc co = mo_coeff[:, :nocc] cv = mo_coeff[:, nocc:] eri = mol.intor('cint2e_sph', aosym='s8') eri = ao2mo.incore.general(eri, (co, cv, co, cv)) eri = ao2mo.load(eri) t2 = np.empty((nocc, nocc, nvir, nvir)) eia = mo_energy[:nocc, None] - mo_energy[None, nocc:] with eri as ovov: for i in range(nocc): gi = np.asarray(ovov[i * nvir:(i + 1) * nvir]) gi = gi.reshape(nvir, nocc, nvir).transpose(1, 0, 2) t2[i] = gi / lib.direct_sum('jb+a->jba', eia, eia[i]) return t2
def contract_Sijrs(self): feri = self.eris['cvcv'] eia = self.mo_energy[:self.ncore, None] - self.mo_energy[None, self.nocc:] norm = 0 ener = 0 with ao2mo.load(feri) as cvcv: for i in range(self.ncore): djba = (eia.reshape(-1, 1) + eia[i].reshape(1, -1)).ravel() gi = np.asarray(cvcv[i * self.nvirt:(i + 1) * self.nvirt]) gi = gi.reshape(self.nvirt, self.ncore, self.nvirt).transpose(1, 2, 0) t2i = (gi.ravel() / djba).reshape(self.ncore, self.nvirt, self.nvirt) # 2*ijab-ijba theta = gi * 2 - gi.transpose(0, 2, 1) norm += einsum('jab,jab', gi, theta) ener += einsum('jab,jab', t2i, theta) return norm, ener, None
def ao2mo(self, mo_coeff): log = logger.Logger(self.stdout, self.verbose) time0 = (time.clock(), time.time()) log.debug('transform (ia|jb)') nmo = self.nmo nocc = self.nocc nvir = nmo - nocc co = mo_coeff[:, :nocc] cv = mo_coeff[:, nocc:] mem_incore, mem_outcore, mem_basic = _mem_usage(nocc, nvir) mem_now = lib.current_memory()[0] if mem_now < mem_basic: warnings.warn( '%s: Not enough memory. Available mem %s MB, required mem %s MB\n' % (self.ao2mo, mem_now, mem_basic)) if hasattr(self._scf, 'with_df') and self._scf.with_df: # To handle the PBC or custom 2-electron with 3-index tensor. # Call dfmp2.MP2 for efficient DF-MP2 implementation. log.warn( 'MP2 detected DF being bound to the HF object. ' '(ia|jb) is computed based on the DF 3-tensor integrals.\n' 'You can switch to dfmp2.MP2 for the DF-MP2 implementation') eri = self._scf.with_df.ao2mo((co, cv, co, cv)) elif (self._scf._eri is not None and mem_incore + mem_now < self.max_memory or self.mol.incore_anyway): if self._scf._eri is None: eri = self.intor('int2e', aosym='s8') else: eri = self._scf._eri eri = ao2mo.incore.general(eri, (co, cv, co, cv)) else: max_memory = max(2000, self.max_memory * .9 - mem_now) erifile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) ao2mo.outcore.general(self.mol, (co, cv, co, cv), erifile.name, max_memory=max_memory, verbose=self.verbose) eri = erifile time1 = log.timer('Integral transformation', *time0) return ao2mo.load(eri)
def ao2mo(self, mo_coeff): log = logger.Logger(self.stdout, self.verbose) time0 = (time.clock(), time.time()) log.debug("transform (ia|jb)") nmo = self.nmo nocc = self.nocc nvir = nmo - nocc co = mo_coeff[:, :nocc] cv = mo_coeff[:, nocc:] mem_incore, mem_outcore, mem_basic = _mem_usage(nocc, nvir) mem_now = lib.current_memory()[0] if mem_now < mem_basic: warnings.warn( "%s: Not enough memory. Available mem %s MB, required mem %s MB\n" % (self.ao2mo, mem_now, mem_basic) ) if hasattr(self._scf, "with_df") and self._scf.with_df: # To handle the PBC or custom 2-electron with 3-index tensor. # Call dfmp2.MP2 for efficient DF-MP2 implementation. log.warn( "MP2 detected DF being bound to the HF object. " "(ia|jb) is computed based on the DF 3-tensor integrals.\n" "You can switch to dfmp2.MP2 for the DF-MP2 implementation" ) eri = self._scf.with_df.ao2mo((co, cv, co, cv)) elif self._scf._eri is not None and mem_incore + mem_now < self.max_memory or self.mol.incore_anyway: if self._scf._eri is None: eri = self.intor("cint2e_sph", aosym="s8") else: eri = self._scf._eri eri = ao2mo.incore.general(eri, (co, cv, co, cv)) else: max_memory = max(2000, self.max_memory * 0.9 - mem_now) erifile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) ao2mo.outcore.general(self.mol, (co, cv, co, cv), erifile.name, max_memory=max_memory, verbose=self.verbose) eri = erifile time1 = log.timer("Integral transformation", *time0) return ao2mo.load(eri)
feri = h5py.File(gradtmp.name, 'r') grad = numpy.array(feri['eri_mo']).reshape(-1,nocc,nvir,nocc,nvir) print('shape of gradient integrals %s' % str(grad.shape)) import tempfile import numpy import h5py from pyscf import ao2mo nocc = mol.nelectron // 2 nvir = len(mf.mo_energy) - nocc co = mf.mo_coeff[:,:nocc] cv = mf.mo_coeff[:,nocc:] hess1tmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, (co,cv,co,cv), hess1tmp.name, intor='cint2e_ipvip1_sph', dataname='hessints1', aosym='s4', comp=9, verbose=0) with ao2mo.load(hess1tmp, 'hessints1') as eri: hess1 = numpy.array(eri).reshape(-1,nocc,nvir,nocc,nvir) hess2tmp = tempfile.NamedTemporaryFile() ao2mo.general(mol, (co,cv,co,cv), hess2tmp.name, intor='cint2e_ipip1_sph', dataname='hessints2', aosym='s2kl', comp=9, verbose=0) feri = h5py.File(hess2tmp.name, 'r') hess2 = numpy.array(feri['hessints2']).reshape(-1,nocc,nvir,nocc,nvir) hess3tmp = tempfile.NamedTemporaryFile() with ao2mo.load(ao2mo.general(mol, (co,cv,co,cv), hess3tmp.name, intor='cint2e_ip1ip2_sph', aosym='s1', comp=9, verbose=0)) as eri: hess3 = numpy.array(eri).reshape(-1,nocc,nvir,nocc,nvir) print('shape of hessian integrals: hess1 %s, hess2 %s, hess3 %s' % (str(hess1.shape), str(hess2.shape), str(hess3.shape)))
def test_load(self): a = numpy.zeros(3) with ao2mo.load(a) as eri: self.assertTrue(a is eri)
) mf = scf.RHF(mol) mf.kernel() orb = mf.mo_coeff # get the two-electron integrals as a numpy array eri = ao2mo.kernel(mol, orb) ftmp = tempfile.NamedTemporaryFile() # saves the two-electron integrals in the file ftmp.name ao2mo.kernel(mol, orb, ftmp.name) ftmp = tempfile.NamedTmpFile() ao2mo.kernel(mol, orb, ftmp) with ao2mo.load(ftmp) as eri: print(eri.shape) import numpy with ao2mo.load(ftmp) as eri: eri1 = ao2mo.restore(1, numpy.asarray(eri), orb.shape[1]) eri4 = ao2mo.restore('4', numpy.asarray(eri), orb.shape[1) eri8 = ao2mo.restore('s8', numpy.asarray(eri), orb.shape[1]) print(eri1.shape) print(eri4.shape) print(eri8.shape) eri = ao2mo.kernel(mol, orb) print(type(eri)) with ao2mo.load(erifile) as eri: print(eri.shape)
def solve (mol, nel, cf_core, cf_gs, ImpOrbs, chempot=0., n_orth=0, FrozenPot=None, mf_tot=None): # cf_core : core orbitals (in AO basis, assumed orthonormal) # cf_gs : guess orbitals (in AO basis) # ImpOrbs : cf_gs -> impurity orbitals transformation # n_orth : number of orthonormal orbitals in cf_gs [1..n_orth] mol_ = gto.Mole() mol_.build (verbose=0) mol_.nelectron = nel mol_.incore_anyway = True cfx = cf_gs print("cfx shape", cfx.shape) Sf = mol.intor_symmetric('cint1e_ovlp_sph') Hc = mol.intor_symmetric('cint1e_kin_sph') \ + mol.intor_symmetric('cint1e_nuc_sph') \ + FrozenPot occ = np.zeros((cfx.shape[1],)) occ[:nel//2] = 2. # core contributions dm_core = np.dot(cf_core, cf_core.T)*2 jk_core = scf.hf.get_veff (mol, dm_core) e_core = np.trace(np.dot(Hc, dm_core)) \ + 0.5*np.trace(np.dot(jk_core, dm_core)) # transform integrals Sp = np.dot(cfx.T, np.dot(Sf, cfx)) Hp = np.dot(cfx.T, np.dot(Hc, cfx)) jkp = np.dot(cfx.T, np.dot(jk_core, cfx)) # density fitting ============================================================ # mf = scf.RHF(mol).density_fit() # this should be moved out of to the parent directory, to avoid repetition # mf.with_df._cderi_to_save = 'saved_cderi.h5' # rank-3 decomposition # mf.kernel() ### moved these three lines to orbital_selection_fc auxmol = df.incore.format_aux_basis(mol, auxbasis='weigend') j3c = df.incore.aux_e2(mol, auxmol, intor='cint3c2e_sph', aosym='s1') nao = mol.nao_nr() naoaux = auxmol.nao_nr() j3c = j3c.reshape(nao,nao,naoaux) # (ij|L) print("j3c shape", j3c.shape) j2c = df.incore.fill_2c2e(mol, auxmol) #(L|M) overlap matrix between auxiliary basis functions #the eri is (ij|kl) = \sum_LM (ij|L) (L|M) (M|kl) omega = sla.inv(j2c) eps,U = sla.eigh(omega) #after this transformation the eri is (ij|kl) = \sum_L (ij|L) (L|kl) j3c = np.dot(np.dot(j3c,U),np.diag(np.sqrt(eps))) #this part is slow, as we again store the whole eri_df # conv = np.einsum('prl,pi,rj->ijl', j3c, cfx, cfx) conv = np.einsum('prl,pi->irl',j3c,cfx) conv = np.einsum('irl,rj->ijl',conv,cfx) df_eri = np.einsum('ijm,klm->ijkl',conv,conv) intsp_df = ao2mo.restore(4, df_eri, cfx.shape[1]) print("DF instp", intsp_df.shape) # ============================================================================= # intsp = ao2mo.outcore.full_iofree (mol, cfx) #TODO: this we need to calculate on the fly using generator f'n # print("intsp shape", intsp.shape) # orthogonalize cf [virtuals] cf = np.zeros((cfx.shape[1],)*2,) if n_orth > 0: assert (n_orth <= cfx.shape[1]) assert (np.allclose(np.eye(n_orth), Sp[:n_orth,:n_orth])) else: n_orth = 0 cf[:n_orth,:n_orth] = np.eye(n_orth) if n_orth < cfx.shape[1]: val, vec = sla.eigh(-Sp[n_orth:,n_orth:]) idx = -val > 1.e-12 U = np.dot(vec[:,idx]*1./(np.sqrt(-val[idx])), \ vec[:,idx].T) cf[n_orth:,n_orth:] = U # define ImpOrbs projection Xp = np.dot(ImpOrbs, ImpOrbs.T) # Si = np.dot(ImpOrbs.T, np.dot(Sp, ImpOrbs)) # Mp = np.dot(ImpOrbs, np.dot(sla.inv(Si), ImpOrbs.T)) Np = np.dot(Sp, Xp) # print np.allclose(Np, np.dot(Np, np.dot(Mp, Np))) # HF calculation mol_.energy_nuc = lambda *args: mol.energy_nuc() + e_core mf1 = scf.RHF(mol_) #.density_fit() #mf.verbose = 4 mf1.mo_coeff = cf mf1.mo_occ = occ mf1.get_ovlp = lambda *args: Sp mf1.get_hcore = lambda *args: Hp + jkp - 0.5*chempot*(Np + Np.T) mf1._eri = ao2mo.restore (8, intsp_df, cfx.shape[1]) #trying something nt = scf.newton(mf1) #nt.verbose = 4 nt.max_cycle_inner = 1 nt.max_stepsize = 0.25 nt.ah_max_cycle = 32 nt.ah_start_tol = 1.0e-12 nt.ah_grad_trust_region = 1.0e8 nt.conv_tol_grad = 1.0e-6 nt.kernel() cf = nt.mo_coeff if not nt.converged: raise RuntimeError ('hf failed to converge') mo_coeff = nt.mo_coeff mo_energy = nt.mo_energy mo_occ = nt.mo_occ # dfMP2 solution nocc = nel//2 # mp2solver = dfmp2_testing.MP2(mf_tot) #(work) #we just pass the mf for the full molecule to dfmp2 mp2solver = dfmp2.DFMP2(mf_tot) #(work) #we just pass the mf for the full molecule to dfmp2 # mp2solver = dfmp2.MP2(mf) #(home) mp2solver.verbose = 5 mp2solver.kernel(mo_energy=mo_energy, mo_coeff=mo_coeff, nocc=nocc) # exit() ''' Try generating j3c for the whole molecule, on the fly, then use that for rdms ''' def make_rdm1(mp2solver, t2, mo_coeff, mo_energy, nocc): '''1-particle density matrix in MO basis. The off-diagonal blocks due to the orbital response contribution are not included. ''' mo = np.asarray(mo_coeff, order='F') nmo = mo.shape[1] nvir = nmo - nocc dm1occ = np.zeros((nocc,nocc)) dm1vir = np.zeros((nvir,nvir)) for i in range(nocc): dm1vir += np.einsum('jca,jcb->ab', t2[i], t2[i]) * 2 \ - np.einsum('jca,jbc->ab', t2[i], t2[i]) dm1occ += np.einsum('iab,jab->ij', t2[i], t2[i]) * 2 \ - np.einsum('iab,jba->ij', t2[i], t2[i]) rdm1 = np.zeros((nmo,nmo)) # *2 for beta electron rdm1[:nocc,:nocc] =-dm1occ * 2 rdm1[nocc:,nocc:] = dm1vir * 2 for i in range(nocc): rdm1[i,i] += 2 return rdm1 def make_rdm2(mp2solver, t2, mo_coeff, mo_energy, nocc): '''2-RDM in MO basis''' mo = np.asarray(mo_coeff, order='F') nmo = mo.shape[1] nvir = nmo - nocc dm2 = np.zeros((nmo,nmo,nmo,nmo)) # Chemist notation #dm2[:nocc,nocc:,:nocc,nocc:] = t2.transpose(0,3,1,2)*2 - t2.transpose(0,2,1,3) #dm2[nocc:,:nocc,nocc:,:nocc] = t2.transpose(3,0,2,1)*2 - t2.transpose(2,0,3,1) for i in range(nocc): t2i = t2[i] dm2[i,nocc:,:nocc,nocc:] = t2i.transpose(1,0,2)*2 - t2i.transpose(2,0,1) dm2[nocc:,i,nocc:,:nocc] = dm2[i,nocc:,:nocc,nocc:].transpose(0,2,1) for i in range(nocc): for j in range(nocc): dm2[i,i,j,j] += 4 dm2[i,j,j,i] -= 2 return dm2 mo = np.asarray(mo_coeff, order='F') nmo = mo.shape[1] nvir = nmo - nocc co = mo_coeff[:,:nocc] cv = mo_coeff[:,nocc:] # eri = mol_.intor('cint2e_sph', aosym='s8') _scf = mf1 eri = _scf._eri eri = ao2mo.incore.general(eri, (co,cv,co,cv)) print("eri shape", eri.shape) eri = ao2mo.load(eri) t2 = np.empty((nocc,nocc,nvir,nvir)) eia = mo_energy[:nocc,None] - mo_energy[None,nocc:] with eri as ovov: print("ovov", ovov) for i in range(nocc): gi = np.asarray(ovov[i*nvir:(i+1)*nvir]) gi = gi.reshape(nvir, nocc, nvir).transpose(1,0,2) t2[i] = gi/lib.direct_sum('jb+a->jba', eia, eia[i]) rdm1 = make_rdm1(mp2solver, t2, mo_coeff, mo_energy, nocc) from scipy.linalg import eigh print("hermitian?", np.allclose(rdm1,rdm1.T)) w,v = eigh(rdm1) print(w) print(np.trace(rdm1)) print("rm1 shape", rdm1.shape) rdm2 = make_rdm2(mp2solver, t2, mo_coeff, mo_energy, nocc) print("rmd2 shape", rdm2.shape) print("cfx shape", cfx.shape) # # # ------------------------------------- # # TEST: compare rdm dmet with dfmp2 rdms # # atoms_test=\ # # [['C',( 0.0000, 0.0000, 0.7680)],\ # # ['C',( 0.0000, 0.0000,-0.7680)],\ # # ['H',(-1.0192, 0.0000, 1.1573)],\ # # ['H',( 0.5096, 0.8826, 1.1573)],\ # # ['H',( 0.5096,-0.8826, 1.1573)],\ # # ['H',( 1.0192, 0.0000,-1.1573)],\ # # ['H',(-0.5096,-0.8826,-1.1573)],\ # # ['H',(-0.5096, 0.8826,-1.1573)]] # # atoms_test = [ # ['O' , (0. , 0. , 0.)],\ # ['H' , (0. , -0.757 , 0.587)],\ # ['H' , (0. , 0.757 , 0.587)]] # # mol_test = gto.M(atom=atoms_test,basis='cc-pvdz') # m_test = scf.RHF(mol_test).density_fit() # m_test.kernel() # # mm_test = dfmp2.DFMP2(m_test) # mm_test.kernel() # from pyscf.mp import mp2 # rdm1_test = mp2.make_rdm1(mm_test) # rdm2_test = mp2.make_rdm2(mm_test) # # # --------------plots ------------------------ # # Plot sorted rdm1 values # x1 = rdm1 # y1 = x1.flatten() # y1 = np.sort(y1) # import matplotlib.pyplot as plt # plt.plot(y1, 'r', label='rdm1 from dmet') # plt.ylabel('rdm1') # x2 = rdm1_test # y2 = x2.flatten() # y2 = np.sort(y2) # plt.plot(y2, 'b', label='rdm1 for dfmp2') # plt.ylabel('rdm1 sorted values') # # Place a legend above this subplot, expanding itself to # # fully use the given bounding box. # plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, # ncol=2, mode="expand", borderaxespad=0.) # # plt.show() # # print("deviations between sorted 1rdm in MO basis ") # print(np.abs(y1-y2).max()) # # # Plot sorted rdm2 values # x1 = rdm2 # y1 = x1.flatten() # y1 = np.sort(y1) # import matplotlib.pyplot as plt # plt.plot(y1, 'r', label='rdm2 from dmet') # plt.ylabel('rdm2') # x2 = rdm2_test # y2 = x2.flatten() # y2 = np.sort(y2) # plt.plot(y2, 'b', label='rdm2 for dfmp2') # plt.ylabel('rdm1 sorted values') # # Place a legend above this subplot, expanding itself to # # fully use the given bounding box. # plt.legend(bbox_to_anchor=(0., 1.02, 1., .102), loc=3, # ncol=2, mode="expand", borderaxespad=0.) # # plt.show() # print("deviations between sorted 1rdm in MO basis ") # print(np.abs(y1-y2).max()) # # # print("deviations between 1rdm,2rdm in MO basis ") # print(np.abs(rdm1-rdm1_test).max()) # print(np.abs(rdm2-rdm2_test).max()) # # ------------------------------------------------------------ # transform rdm's to original basis tei = ao2mo.restore(1, intsp_df, cfx.shape[1]) rdm1 = np.dot(cf, np.dot(rdm1, cf.T)) rdm2 = np.einsum('ai,ijkl->ajkl', cf, rdm2) rdm2 = np.einsum('bj,ajkl->abkl', cf, rdm2) rdm2 = np.einsum('ck,abkl->abcl', cf, rdm2) rdm2 = np.einsum('dl,abcl->abcd', cf, rdm2) ImpEnergy = +0.25 *np.einsum('ij,jk,ki->', 2*Hp+jkp, rdm1, Xp) \ +0.25 *np.einsum('ij,jk,ki->', 2*Hp+jkp, Xp, rdm1) \ +0.125*np.einsum('ijkl,ijkm,ml->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,ijml,mk->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,imkl,mj->', tei, rdm2, Xp) \ +0.125*np.einsum('ijkl,mjkl,mi->', tei, rdm2, Xp) Nel = np.trace(np.dot(np.dot(rdm1, Sp), Xp)) return Nel, ImpEnergy
# 5 d/dY d/dY # 6 d/dY d/dZ # 7 d/dZ d/dX # 8 d/dZ d/dY # 9 d/dZ d/dZ # orb = mf.mo_coeff hesstmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, orb, hesstmp.name, intor='cint2e_ipvip1_sph', dataname='hessints1', aosym='s4', comp=9) with ao2mo.load(hesstmp, 'hessints1') as eri: print('(d/dR i d/dR j| kl) have shape %s due to the 4-fold permutation ' 'symmetry i >= j, k >= l' % str(eri.shape)) ao2mo.kernel(mol, orb, hesstmp.name, intor='cint2e_ipip1_sph', dataname='hessints2', aosym='s2kl', comp=9) feri = h5py.File(hesstmp.name, 'r') print('(d/dR d/dR i j| kl) have shape %s due to the 2-fold permutation ' 'symmetry k >= l' % str(feri['hessints2'].shape)) feri.close()
# Hessian integrals have 9 components # 1 d/dX d/dX # 2 d/dX d/dY # 3 d/dX d/dZ # 4 d/dY d/dX # 5 d/dY d/dY # 6 d/dY d/dZ # 7 d/dZ d/dX # 8 d/dZ d/dY # 9 d/dZ d/dZ # orb = mf.mo_coeff hesstmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, orb, hesstmp.name, intor='cint2e_ipvip1_sph', dataname='hessints1', aosym='s4', comp=9) with ao2mo.load(hesstmp, 'hessints1') as eri: print('(d/dR i d/dR j| kl) have shape %s due to the 4-fold permutation ' 'symmetry i >= j, k >= l' % str(eri.shape)) ao2mo.kernel(mol, orb, hesstmp.name, intor='cint2e_ipip1_sph', dataname='hessints2', aosym='s2kl', comp=9) feri = h5py.File(hesstmp.name, 'r') print('(d/dR d/dR i j| kl) have shape %s due to the 2-fold permutation ' 'symmetry k >= l' % str(feri['hessints2'].shape)) feri.close() with ao2mo.load(ao2mo.kernel(mol, orb, hesstmp.name, intor='cint2e_ip1ip2_sph', aosym='s1', comp=9)) as eri: print('(d/dR i j|d/dR k l) have shape %s because there is no permutation ' 'symmetry' % str(eri.shape))