def test_incore_s4(self): eri4 = ao2mo.restore(4, mf._eri, nmo) dm = mf.make_rdm1() vj0, vk0 = _vhf.incore(eri4, dm, hermi=1) vj1, vk1 = scf.hf.get_jk(mol, dm, hermi=1) self.assertTrue(numpy.allclose(vj0, vj1)) self.assertTrue(numpy.allclose(vk0, vk1))
def test_incore_s4(self): eri4 = ao2mo.restore(4, mf._eri, nmo) dm = mf.make_rdm1() vj0, vk0 = _vhf.incore(eri4, dm, hermi=1) vj1, vk1 = scf.hf.get_jk(mol, dm, hermi=1) self.assertTrue(numpy.allclose(vj0,vj1)) self.assertTrue(numpy.allclose(vk0,vk1))
def dot_eri_dm(eri, dm, hermi=0): '''Compute J, K matrices in terms of the given 2-electron integrals and density matrix: J ~ numpy.einsum('pqrs,qp->rs', eri, dm) K ~ numpy.einsum('pqrs,qr->ps', eri, dm) Args: eri : ndarray 8-fold or 4-fold ERIs dm : ndarray or list of ndarrays A density matrix or a list of density matrices Kwargs: hermi : int Whether J, K matrix is hermitian | 0 : no hermitian or symmetric | 1 : hermitian | 2 : anti-hermitian Returns: Depending on the given dm, the function returns one J and one K matrix, or a list of J matrices and a list of K matrices, corresponding to the input density matrices. Examples: >>> from pyscf import gto, scf >>> from pyscf.scf import _vhf >>> mol = gto.M(atom='H 0 0 0; H 0 0 1.1') >>> eri = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) >>> dms = numpy.random.random((3,mol.nao_nr(),mol.nao_nr())) >>> j, k = scf.hf.dot_eri_dm(eri, dms, hermi=0) >>> print(j.shape) (3, 2, 2) ''' if isinstance(dm, numpy.ndarray) and dm.ndim == 2: vj, vk = _vhf.incore(eri, dm, hermi=hermi) else: dm = numpy.asarray(dm, order='C') nao = dm.shape[-1] dms = dm.reshape(-1, nao, nao) vjk = [_vhf.incore(eri, dmi, hermi=hermi) for dmi in dms] vj = numpy.array([v[0] for v in vjk]).reshape(dm.shape) vk = numpy.array([v[1] for v in vjk]).reshape(dm.shape) return vj, vk
def get_jk(agf2, eri, rdm1, with_j=True, with_k=True): ''' Get the J/K matrices. Args: eri : ndarray or H5 dataset Electronic repulsion integrals (NOT as _ChemistsERIs) rdm1 : 2D array Reduced density matrix Kwargs: with_j : bool Whether to compute J. Default value is True with_k : bool Whether to compute K. Default value is True Returns: tuple of ndarrays corresponding to J and K, if either are not requested then they are set to None. ''' if isinstance(eri, np.ndarray): vj, vk = _vhf.incore(eri, rdm1, with_j=with_j, with_k=with_k) else: nmo = rdm1.shape[0] npair = nmo * (nmo + 1) // 2 vj = vk = None if with_j: rdm1_tril = lib.pack_tril(rdm1 + np.tril(rdm1, k=-1)) vj = np.zeros_like(rdm1_tril) if with_k: vk = np.zeros_like(rdm1) blksize = _agf2.get_blksize(agf2.max_memory, (nmo * npair, nmo**3)) blksize = min(1, max(BLKMIN, blksize)) logger.debug1(agf2, 'blksize (ragf2.get_jk) = %d' % blksize) tril2sq = lib.square_mat_in_trilu_indices(nmo) for p0, p1 in lib.prange(0, nmo, blksize): idx = list(np.concatenate(tril2sq[p0:p1])) eri0 = eri[idx] # vj built in tril layout with scaled rdm1_tril if with_j: vj[idx] = np.dot(eri0, rdm1_tril) if with_k: eri0 = lib.unpack_tril(eri0, axis=-1) eri0 = eri0.reshape(p1 - p0, nmo, nmo, nmo) vk[p0:p1] = lib.einsum('ijkl,jk->il', eri0, rdm1) if with_j: vj = lib.unpack_tril(vj) return vj, vk
def dot_eri_dm(eri, dm, hermi=0): '''Compute J, K matrices in terms of the given 2-electron integrals and density matrix: J ~ numpy.einsum('pqrs,qp->rs', eri, dm) K ~ numpy.einsum('pqrs,qr->ps', eri, dm) Args: eri : ndarray 8-fold or 4-fold ERIs dm : ndarray or list of ndarrays A density matrix or a list of density matrices Kwargs: hermi : int Whether J, K matrix is hermitian | 0 : no hermitian or symmetric | 1 : hermitian | 2 : anti-hermitian Returns: Depending on the given dm, the function returns one J and one K matrix, or a list of J matrices and a list of K matrices, corresponding to the input density matrices. Examples: >>> from pyscf import gto, scf >>> from pyscf.scf import _vhf >>> mol = gto.M(atom='H 0 0 0; H 0 0 1.1') >>> eri = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) >>> dms = numpy.random.random((3,mol.nao_nr(),mol.nao_nr())) >>> j, k = scf.hf.dot_eri_dm(eri, dms, hermi=0) >>> print(j.shape) (3, 2, 2) ''' if isinstance(dm, numpy.ndarray) and dm.ndim == 2: vj, vk = _vhf.incore(eri, dm, hermi=hermi) else: vjk = [_vhf.incore(eri, dmi, hermi=hermi) for dmi in dm] vj = numpy.array([v[0] for v in vjk]) vk = numpy.array([v[1] for v in vjk]) return vj, vk