def test_aux_e2(self): cell = pgto.Cell() cell.unit = 'B' cell.a = numpy.eye(3) * 3. cell.gs = numpy.array([20,20,20]) cell.atom = 'He 0 1 1; He 1 1 0' cell.basis = { 'He': [[0, (0.8, 1.0)], [0, (1.2, 1.0)]] } cell.verbose = 0 cell.build(0, 0) auxcell = incore.format_aux_basis(cell) cell.nimgs = auxcell.nimgs = [3,3,3] a1 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph') self.assertAlmostEqual(finger(a1), 0.1208944790152819, 9) a2 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', aosym='s2ij') self.assertTrue(numpy.allclose(a1, lib.unpack_tril(a2, axis=0).reshape(a1.shape))) numpy.random.seed(3) kpti_kptj = [numpy.random.random(3)]*2 a1 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', kpti_kptj=kpti_kptj) self.assertAlmostEqual(finger(a1), -0.073719031689332651-0.054002639392614758j, 9) a2 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', aosym='s2ij', kpti_kptj=kpti_kptj) self.assertTrue(numpy.allclose(a1, lib.unpack_tril(a2, 1, axis=0).reshape(a1.shape))) numpy.random.seed(1) kpti_kptj = numpy.random.random((2,3)) a1 = incore.aux_e2(cell, auxcell, 'cint3c1e_sph', kpti_kptj=kpti_kptj) self.assertAlmostEqual(finger(a1), 0.039329191948685879-0.039836453846241987j, 9)
def test_aux_e2(self): tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) numpy.random.seed(1) kptij_lst = numpy.random.random((3,2,3)) kptij_lst[0] = 0 kptij_lst[1,0] = kptij_lst[1,1] outcore.aux_e2(cell, cell, tmpfile.name, aosym='s2ij', comp=1, kptij_lst=kptij_lst, verbose=0) refk0 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[0]) refk1 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[1]) refk2 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[2]) with h5py.File(tmpfile.name, 'r') as f: self.assertTrue(numpy.allclose(refk0, f['eri_mo/0'].value.T)) self.assertTrue(numpy.allclose(refk1, f['eri_mo/1'].value.T)) self.assertTrue(numpy.allclose(refk2, f['eri_mo/2'].value.T))
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph'): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3) buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) nao_pair = nao * (nao + 1) // 2 buf = buf.reshape(nkpts, nao_pair, nchg) mat = numpy.einsum('kxz,z->kx', buf, charge) if cell.dimension == 3: nucbar = sum([ z / nuccell.bas_exp(i)[0] for i, z in enumerate(cell.atom_charges()) ]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) mat[k] += nucbar * s return mat
def test_aux_e2(self): tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) numpy.random.seed(1) kptij_lst = numpy.random.random((3, 2, 3)) kptij_lst[0] = 0 kptij_lst[1, 0] = kptij_lst[1, 1] outcore.aux_e2(cell, cell, tmpfile.name, aosym='s2ij', comp=1, kptij_lst=kptij_lst, verbose=0) refk0 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[0]) refk1 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[1]) refk2 = incore.aux_e2(cell, cell, aosym='s2ij', kpti_kptj=kptij_lst[2]) with h5py.File(tmpfile.name, 'r') as f: self.assertTrue(numpy.allclose(refk0, f['eri_mo/0'].value.T)) self.assertTrue(numpy.allclose(refk1, f['eri_mo/1'].value.T)) self.assertTrue(numpy.allclose(refk2, f['eri_mo/2'].value.T))
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3) buf = incore.aux_e2(cell, fakenuc, intor, aosym=aosym, comp=comp, kptij_lst=kptij_lst) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) if aosym == 's1': nao_pair = nao**2 else: nao_pair = nao * (nao + 1) // 2 if comp == 1: buf = buf.reshape(nkpts, nao_pair, nchg) mat = numpy.einsum('kxz,z->kx', buf, charge) else: buf = buf.reshape(nkpts, comp, nao_pair, nchg) mat = numpy.einsum('kcxz,z->kcx', buf, charge) # vbar is the interaction between the background charge # and the compensating function. 0D, 1D, 2D do not have vbar. if cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph', 'int3c2e_cart'): assert (comp == 1) charge = -cell.atom_charges() nucbar = sum([z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts) for k in range(nkpts): if aosym == 's1': mat[k] -= nucbar * ovlp[k].reshape(nao_pair) else: mat[k] -= nucbar * lib.pack_tril(ovlp[k]) return mat
def test_aux_e2(self): cell = pgto.Cell() cell.unit = 'B' cell.a = numpy.eye(3) * 3. cell.mesh = numpy.array([41] * 3) cell.atom = 'He 0 1 1; He 1 1 0' cell.basis = {'He': [[0, (0.8, 1.0)], [0, (1.2, 1.0)]]} cell.verbose = 0 cell.build(0, 0) auxcell = incore.format_aux_basis(cell) a1 = incore.aux_e2(cell, auxcell, 'int3c1e_sph') self.assertAlmostEqual(lib.fp(a1), 0.1208944790152819, 9) a2 = incore.aux_e2(cell, auxcell, 'int3c1e_sph', aosym='s2ij') self.assertTrue( numpy.allclose(a1, lib.unpack_tril(a2, axis=0).reshape(a1.shape))) numpy.random.seed(3) kpt = numpy.random.random(3) kptij_lst = numpy.array([[kpt, kpt]]) a1 = incore.aux_e2(cell, auxcell, 'int3c1e_sph', kptij_lst=kptij_lst) self.assertAlmostEqual(lib.fp(a1), -0.073719031689332651 - 0.054002639392614758j, 9) a2 = incore.aux_e2(cell, auxcell, 'int3c1e_sph', aosym='s2', kptij_lst=kptij_lst) self.assertTrue( numpy.allclose(a1, lib.unpack_tril(a2, 1, axis=0).reshape(a1.shape))) numpy.random.seed(1) kptij_lst = numpy.random.random((1, 2, 3)) a1 = incore.aux_e2(cell, auxcell, 'int3c1e_sph', kptij_lst=kptij_lst) self.assertAlmostEqual(lib.fp(a1), 0.039329191948685879 - 0.039836453846241987j, 9)
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph'): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = aft._fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3) ishs = mpi.work_balanced_partition(numpy.arange(cell.nbas), costs=numpy.arange(1, cell.nbas + 1)) if len(ishs) > 0: ish0, ish1 = ishs[0], ishs[-1] + 1 buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst, shls_slice=(ish0, ish1, 0, cell.nbas, 0, fakenuc.nbas)) else: buf = numpy.zeros(0) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) nao_pair = nao * (nao + 1) // 2 buf = buf.reshape(nkpts, -1, nchg) # scaled by 1./mpi.pool.size because nuc is mpi.reduced in get_nuc function buf = numpy.einsum('kxz,z->kx', buf, 1. / mpi.pool.size * charge) mat = numpy.empty((nkpts, nao_pair), dtype=numpy.complex128) for k in range(nkpts): mat[k] = mpi.allgather(buf[k]) if rank == 0 and cell.dimension == 3: nucbar = sum([ z / nuccell.bas_exp(i)[0] for i, z in enumerate(cell.atom_charges()) ]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) mat[k] += nucbar * s return mat
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e_sph', aosym='s2', comp=1): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = aft._fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts,kpts)).reshape(-1,2,3) ishs = mpi.work_balanced_partition(numpy.arange(cell.nbas), costs=numpy.arange(1, cell.nbas+1)) if len(ishs) > 0: ish0, ish1 = ishs[0], ishs[-1]+1 buf = incore.aux_e2(cell, fakenuc, intor, aosym='s2', kptij_lst=kptij_lst, shls_slice=(ish0,ish1,0,cell.nbas,0,fakenuc.nbas)) else: buf = numpy.zeros(0) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) nao_pair = nao*(nao+1)//2 buf = buf.reshape(nkpts,-1,nchg) # scaled by 1./mpi.pool.size because nuc is mpi.reduced in get_nuc function buf = numpy.einsum('kxz,z->kx', buf, 1./mpi.pool.size*charge) mat = numpy.empty((nkpts,nao_pair), dtype=numpy.complex128) for k in range(nkpts): mat[k] = mpi.allgather(buf[k]) if (rank == 0 and cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph', 'int3c2e_cart')): assert(comp == 1) charges = cell.atom_charges() nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charges)]) nucbar *= numpy.pi/cell.vol ovlp = cell.pbc_intor('int1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): if aosym == 's1': mat[k] += nucbar * ovlp[k].reshape(nao_pair) else: mat[k] += nucbar * lib.pack_tril(ovlp[k]) return mat
def test_aux_e2(self): tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) numpy.random.seed(1) kptij_lst = numpy.random.random((3,2,3)) kptij_lst[0] = 0 outcore.aux_e2(cell, cell, tmpfile.name, aosym='s2', comp=1, kptij_lst=kptij_lst, verbose=0) refk = incore.aux_e2(cell, cell, aosym='s2', kptij_lst=kptij_lst) with h5py.File(tmpfile.name, 'r') as f: nao = cell.nao_nr() idx = numpy.tril_indices(nao) idx = idx[0] * nao + idx[1] self.assertTrue(numpy.allclose(refk[0,idx], f['eri_mo/0'].value.T)) self.assertTrue(numpy.allclose(refk[1], f['eri_mo/1'].value.T)) self.assertTrue(numpy.allclose(refk[2], f['eri_mo/2'].value.T))
def test_aux_e1(self): tmpfile = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) numpy.random.seed(1) kptij_lst = numpy.random.random((3,2,3)) kptij_lst[0] = 0 outcore.aux_e1(cell, cell, tmpfile.name, aosym='s2', comp=1, kptij_lst=kptij_lst, verbose=0) refk = incore.aux_e2(cell, cell, aosym='s2', kptij_lst=kptij_lst) with h5py.File(tmpfile.name, 'r') as f: nao = cell.nao_nr() idx = numpy.tril_indices(nao) idx = idx[0] * nao + idx[1] self.assertTrue(numpy.allclose(refk[0,idx], f['eri_mo/0'].value.T)) self.assertTrue(numpy.allclose(refk[1], f['eri_mo/1'].value.T)) self.assertTrue(numpy.allclose(refk[2], f['eri_mo/2'].value.T))
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts,kpts)).reshape(-1,2,3) buf = incore.aux_e2(cell, fakenuc, intor, aosym=aosym, comp=comp, kptij_lst=kptij_lst) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) if aosym == 's1': nao_pair = nao**2 else: nao_pair = nao*(nao+1)//2 if comp == 1: buf = buf.reshape(nkpts,nao_pair,nchg) mat = numpy.einsum('kxz,z->kx', buf, charge) else: buf = buf.reshape(nkpts,comp,nao_pair,nchg) mat = numpy.einsum('kcxz,z->kcx', buf, charge) # vbar is the interaction between the background charge # and the compensating function. 0D, 1D, 2D do not have vbar. if cell.dimension == 3 and intor in ('int3c2e', 'int3c2e_sph', 'int3c2e_cart'): assert(comp == 1) charge = -cell.atom_charges() nucbar = sum([z/nuccell.bas_exp(i)[0] for i,z in enumerate(charge)]) nucbar *= numpy.pi/cell.vol ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts) for k in range(nkpts): if aosym == 's1': mat[k] -= nucbar * ovlp[k].reshape(nao_pair) else: mat[k] -= nucbar * lib.pack_tril(ovlp[k]) return mat
def get_pp_loc_part2(cell, kpts=None): '''PRB, 58, 3641 Eq (1), integrals associated to C1, C2, C3, C4 ''' from pyscf.pbc.df import incore if kpts is None: kpts_lst = numpy.zeros((1, 3)) else: kpts_lst = numpy.reshape(kpts, (-1, 3)) nkpts = len(kpts_lst) intors = ('int3c2e', 'int3c1e', 'int3c1e_r2_origk', 'int3c1e_r4_origk', 'int3c1e_r6_origk') kptij_lst = numpy.hstack((kpts_lst, kpts_lst)).reshape(-1, 2, 3) buf = 0 for cn in range(1, 5): fakecell = fake_cell_vloc(cell, cn) if fakecell.nbas > 0: v = incore.aux_e2(cell, fakecell, intors[cn], aosym='s2', comp=1, kptij_lst=kptij_lst) buf += numpy.einsum('...i->...', v) if isinstance(buf, int): if any( cell.atom_symbol(ia) in cell._pseudo for ia in range(cell.natm)): pass else: lib.logger.warn( cell, 'cell.pseudo was specified but its elements %s ' 'were not found in the system.', cell._pseudo.keys()) vpploc = [0] * nkpts else: buf = buf.reshape(nkpts, -1) vpploc = [] for k, kpt in enumerate(kpts_lst): v = lib.unpack_tril(buf[k]) if abs(kpt).sum() < 1e-9: # gamma_point: v = v.real vpploc.append(v) if kpts is None or numpy.shape(kpts) == (3, ): vpploc = vpploc[0] return vpploc
def ecp_int(cell, kpts=None): from pyscf.pbc.df import incore if kpts is None: kpts_lst = numpy.zeros((1, 3)) else: kpts_lst = numpy.reshape(kpts, (-1, 3)) cell, contr_coeff = gto.cell._split_basis(cell) lib.logger.debug1(cell, 'nao %d -> nao %d', *(contr_coeff.shape)) ecpcell = gto.Cell() ecpcell._atm = cell._atm # append a fictitious s function to mimic the auxiliary index in pbc.incore. # ptr2last_env_idx to force PBCnr3c_fill_* function to copy the entire "env" ptr2last_env_idx = len(cell._env) - 1 ecpbas = numpy.vstack([[0, 0, 1, 1, 0, ptr2last_env_idx, 0, 0], cell._ecpbas]).astype(numpy.int32) ecpcell._bas = ecpbas ecpcell._env = cell._env # In pbc.incore _ecpbas is appended to two sets of cell._bas and the # fictitious s function. cell._env[AS_ECPBAS_OFFSET] = cell.nbas * 2 + 1 cell._env[AS_NECPBAS] = len(cell._ecpbas) # shls_slice of auxiliary index (0,1) corresponds to the fictitious s function shls_slice = (0, cell.nbas, 0, cell.nbas, 0, 1) kptij_lst = numpy.hstack((kpts_lst, kpts_lst)).reshape(-1, 2, 3) buf = incore.aux_e2(cell, ecpcell, 'ECPscalar', aosym='s2', kptij_lst=kptij_lst, shls_slice=shls_slice) buf = buf.reshape(len(kpts_lst), -1) mat = [] for k, kpt in enumerate(kpts_lst): v = lib.unpack_tril(buf[k], lib.HERMITIAN) if abs(kpt).sum() < 1e-9: # gamma_point: v = v.real mat.append(reduce(numpy.dot, (contr_coeff.T, v, contr_coeff))) if kpts is None or numpy.shape(kpts) == (3, ): mat = mat[0] return mat
def get_pp_loc_part2(cell, kpts=None): '''PRB, 58, 3641 Eq (1), integrals associated to C1, C2, C3, C4 ''' from pyscf.pbc.df import incore if kpts is None: kpts_lst = numpy.zeros((1,3)) else: kpts_lst = numpy.reshape(kpts, (-1,3)) nkpts = len(kpts_lst) intors = ('int3c2e', 'int3c1e', 'int3c1e_r2_origk', 'int3c1e_r4_origk', 'int3c1e_r6_origk') kptij_lst = numpy.hstack((kpts_lst,kpts_lst)).reshape(-1,2,3) buf = 0 for cn in range(1, 5): fakecell = fake_cell_vloc(cell, cn) if fakecell.nbas > 0: v = incore.aux_e2(cell, fakecell, intors[cn], aosym='s2', comp=1, kptij_lst=kptij_lst) buf += numpy.einsum('...i->...', v) if isinstance(buf, int): if any(cell.atom_symbol(ia) in cell._pseudo for ia in range(cell.natm)): pass else: lib.logger.warn(cell, 'cell.pseudo was specified but its elements %s ' 'were not found in the system.', cell._pseudo.keys()) vpploc = [0] * nkpts else: buf = buf.reshape(nkpts,-1) vpploc = [] for k, kpt in enumerate(kpts_lst): v = lib.unpack_tril(buf[k]) if abs(kpt).sum() < 1e-9: # gamma_point: v = v.real vpploc.append(v) if kpts is None or numpy.shape(kpts) == (3,): vpploc = vpploc[0] return vpploc
def ecp_int(cell, kpts=None): from pyscf.pbc.df import incore if kpts is None: kpts_lst = numpy.zeros((1,3)) else: kpts_lst = numpy.reshape(kpts, (-1,3)) cell, contr_coeff = gto.cell._split_basis(cell) lib.logger.debug1(cell, 'nao %d -> nao %d', *(contr_coeff.shape)) ecpcell = gto.Cell() ecpcell._atm = cell._atm # append a fictitious s function to mimic the auxiliary index in pbc.incore. # ptr2last_env_idx to force PBCnr3c_fill_* function to copy the entire "env" ptr2last_env_idx = len(cell._env) - 1 ecpbas = numpy.vstack([[0, 0, 1, 1, 0, ptr2last_env_idx, 0, 0], cell._ecpbas]).astype(numpy.int32) ecpcell._bas = ecpbas ecpcell._env = cell._env # In pbc.incore _ecpbas is appended to two sets of cell._bas and the # fictitious s function. cell._env[AS_ECPBAS_OFFSET] = cell.nbas * 2 + 1 cell._env[AS_NECPBAS] = len(cell._ecpbas) # shls_slice of auxiliary index (0,1) corresponds to the fictitious s function shls_slice = (0, cell.nbas, 0, cell.nbas, 0, 1) kptij_lst = numpy.hstack((kpts_lst,kpts_lst)).reshape(-1,2,3) buf = incore.aux_e2(cell, ecpcell, 'ECPscalar', aosym='s2', kptij_lst=kptij_lst, shls_slice=shls_slice) buf = buf.reshape(len(kpts_lst),-1) mat = [] for k, kpt in enumerate(kpts_lst): v = lib.unpack_tril(buf[k], lib.HERMITIAN) if abs(kpt).sum() < 1e-9: # gamma_point: v = v.real mat.append(reduce(numpy.dot, (contr_coeff.T, v, contr_coeff))) if kpts is None or numpy.shape(kpts) == (3,): mat = mat[0] return mat
def _int_nuc_vloc(mydf, nuccell, kpts, intor='int3c2e', aosym='s2', comp=1): '''Vnuc - Vloc''' cell = mydf.cell nkpts = len(kpts) # Use the 3c2e code with steep s gaussians to mimic nuclear density fakenuc = _fake_nuc(cell) fakenuc._atm, fakenuc._bas, fakenuc._env = \ gto.conc_env(nuccell._atm, nuccell._bas, nuccell._env, fakenuc._atm, fakenuc._bas, fakenuc._env) kptij_lst = numpy.hstack((kpts, kpts)).reshape(-1, 2, 3) buf = incore.aux_e2(cell, fakenuc, intor, aosym=aosym, comp=comp, kptij_lst=kptij_lst) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) nao = cell.nao_nr() nchg = len(charge) if aosym == 's1': nao_pair = nao**2 else: nao_pair = nao * (nao + 1) // 2 if comp == 1: buf = buf.reshape(nkpts, nao_pair, nchg) mat = numpy.einsum('kxz,z->kx', buf, charge) else: buf = buf.reshape(nkpts, comp, nao_pair, nchg) mat = numpy.einsum('kcxz,z->kcx', buf, charge) if cell.dimension != 0 and intor in ('int3c2e', 'int3c2e_sph', 'int3c2e_cart'): assert (comp == 1) charge = -cell.atom_charges() if cell.dimension == 1 or cell.dimension == 2: Gv, Gvbase, kws = cell.get_Gv_weights(mydf.mesh) G0idx, SI_on_z = pbcgto.cell._SI_for_uniform_model_charge(cell, Gv) ZSI = numpy.einsum("i,ix->x", charge, cell.get_SI(Gv[G0idx])) ZSI -= numpy.einsum('i,xi->x', charge, ft_ao.ft_ao(nuccell, Gv[G0idx])) coulG = 4 * numpy.pi / numpy.linalg.norm(Gv[G0idx], axis=1)**2 nucbar = numpy.einsum('i,i,i,i', ZSI.conj(), coulG, kws[G0idx], SI_on_z) if abs(kpts).sum() < 1e-9: nucbar = nucbar.real else: # cell.dimension == 3 nucbar = sum( [z / nuccell.bas_exp(i)[0] for i, z in enumerate(charge)]) nucbar *= numpy.pi / cell.vol ovlp = cell.pbc_intor('int1e_ovlp', 1, lib.HERMITIAN, kpts) for k in range(nkpts): if aosym == 's1': mat[k] -= nucbar * ovlp[k].reshape(nao_pair) else: mat[k] -= nucbar * lib.pack_tril(ovlp[k]) return mat