def _int_nuc_vloc(mydf, nuccell, kpts, intor='cint3c2e_sph'): '''Vnuc - Vloc''' cell = mydf.cell rcut = max(cell.rcut, nuccell.rcut) Ls = cell.get_lattice_Ls(rcut=rcut) expLk = numpy.asarray(numpy.exp(1j * numpy.dot(Ls, kpts.T)), order='C') 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) nao = cell.nao_nr() buf = [ numpy.zeros((nao, nao, fakenuc.natm), order='F', dtype=numpy.complex128) for k in range(nkpts) ] ints = incore._wrap_int3c(cell, fakenuc, intor, 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int * 6)(0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2, cell.nbas * 2 + fakenuc.natm) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm, gto.PTR_COORD] ptr_coordL = numpy.vstack( (ptr_coordL, ptr_coordL + 1, ptr_coordL + 2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l + 1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) for k in range(nkpts): v = numpy.einsum('ijz,z->ij', buf[k], charge) buf[k] = lib.pack_tril(v + v.T.conj()) 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('cint1e_ovlp_sph', 1, lib.HERMITIAN, kpts) for k in range(nkpts): s = lib.pack_tril(ovlp[k]) buf[k] += nucbar * s return buf
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)) nkpts = len(kpts_lst) Ls = cell.get_lattice_Ls() expLk = numpy.asarray(numpy.exp(1j * numpy.dot(Ls, kpts_lst.T)), order='C') ecpcell = gto.Mole() ecpcell._atm = cell._atm # append a single s function for auxiliary index. # So the pbc fill_3c driver can handle the 2D integrals in (1,n,n) array ecpbas = numpy.vstack([[0, 0, 1, 1, 0, 0, 0, 0], cell._ecpbas]).astype(numpy.int32) ecpcell._bas = ecpbas ecpcell._env = cell._env nao = cell.nao_nr() buf = [ numpy.zeros((nao, nao), order='F', dtype=numpy.complex128) for k in range(nkpts) ] ints = incore._wrap_int3c(cell, ecpcell, 'ECPscalar_sph', 1, Ls, buf) atm, bas, env = ints._envs[:3] env[PTR_ECPBAS_OFFSET] = cell.nbas * 2 + 1 env[PTR_NECPBAS] = len(cell._ecpbas) c_shls_slice = (ctypes.c_int * 6)(0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2, cell.nbas * 2 + 1) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm, PTR_COORD] ptr_coordL = numpy.vstack( (ptr_coordL, ptr_coordL + 1, ptr_coordL + 2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l + 1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) for k, kpt in enumerate(kpts_lst): if abs(kpt).sum() < 1e-6: buf[k] = buf[k].real + buf[k].real.T else: buf[k] = buf[k] + buf[k].T.conj() if kpts is None or numpy.shape(kpts) == (3, ): buf = buf[0] return buf
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)) nkpts = len(kpts_lst) Ls = cell.get_lattice_Ls() expLk = numpy.asarray(numpy.exp(1j*numpy.dot(Ls, kpts_lst.T)), order='C') ecpcell = gto.Mole() ecpcell._atm = cell._atm # append a single s function for auxiliary index. # So the pbc fill_3c driver can handle the 2D integrals in (1,n,n) array ecpbas = numpy.vstack([[0, 0, 1, 1, 0, 0, 0, 0], cell._ecpbas]).astype(numpy.int32) ecpcell._bas = ecpbas ecpcell._env = cell._env nao = cell.nao_nr() buf = [numpy.zeros((nao,nao), order='F', dtype=numpy.complex128) for k in range(nkpts)] ints = incore._wrap_int3c(cell, ecpcell, 'ECPscalar_sph', 1, Ls, buf) atm, bas, env = ints._envs[:3] env[PTR_ECPBAS_OFFSET] = cell.nbas * 2 + 1 env[PTR_NECPBAS] = len(cell._ecpbas) c_shls_slice = (ctypes.c_int*6)(0, cell.nbas, cell.nbas, cell.nbas*2, cell.nbas*2, cell.nbas*2+1) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm,PTR_COORD] ptr_coordL = numpy.vstack((ptr_coordL,ptr_coordL+1,ptr_coordL+2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l+1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) for k, kpt in enumerate(kpts_lst): if abs(kpt).sum() < 1e-6: buf[k] = buf[k].real + buf[k].real.T else: buf[k] = buf[k] + buf[k].T.conj() if kpts is None or numpy.shape(kpts) == (3,): buf = buf[0] return buf
def _int_nuc_vloc(cell, nuccell, kpts): '''Vnuc - Vloc''' nimgs = numpy.max((cell.nimgs, nuccell.nimgs), axis=0) Ls = numpy.asarray(cell.get_lattice_Ls(nimgs), order='C') expLk = numpy.asarray(numpy.exp(1j * numpy.dot(Ls, kpts.T)), order='C') 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) nao = cell.nao_nr() buf = [ numpy.zeros((nao, nao, fakenuc.natm), order='F', dtype=numpy.complex128) for k in range(nkpts) ] ints = incore._wrap_int3c(cell, fakenuc, 'cint3c2e_sph', 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int * 6)(0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2, cell.nbas * 2 + fakenuc.natm) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm, gto.PTR_COORD] ptr_coordL = numpy.vstack( (ptr_coordL, ptr_coordL + 1, ptr_coordL + 2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l + 1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) for k, kpt in enumerate(kpts): v = numpy.einsum('ijz,z->ij', buf[k], charge) if gamma_point(kpt): buf[k] = v.real + v.real.T else: buf[k] = v + v.T.conj() return buf
def _int_nuc_vloc(cell, nuccell, kpts): '''Vnuc - Vloc''' nimgs = numpy.max((cell.nimgs, nuccell.nimgs), axis=0) Ls = numpy.asarray(cell.get_lattice_Ls(nimgs), order='C') expLk = numpy.asarray(numpy.exp(1j*numpy.dot(Ls, kpts.T)), order='C') 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) nao = cell.nao_nr() buf = [numpy.zeros((nao,nao,fakenuc.natm), order='F', dtype=numpy.complex128) for k in range(nkpts)] ints = incore._wrap_int3c(cell, fakenuc, 'cint3c2e_sph', 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int*6)(0, cell.nbas, cell.nbas, cell.nbas*2, cell.nbas*2, cell.nbas*2+fakenuc.natm) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm,gto.PTR_COORD] ptr_coordL = numpy.vstack((ptr_coordL,ptr_coordL+1,ptr_coordL+2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l+1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) charge = cell.atom_charges() charge = numpy.append(charge, -charge) # (charge-of-nuccell, charge-of-fakenuc) for k, kpt in enumerate(kpts): v = numpy.einsum('ijz,z->ij', buf[k], charge) if gamma_point(kpt): buf[k] = v.real + v.real.T else: buf[k] = v + v.T.conj() return buf
def _int_vloc_part2(cell, fakecell, kpts, intor='cint3c1e_sph'): '''Vnuc - Vloc''' from pyscf.pbc.df import incore # sum over largest number of images in either cell or auxcell nimgs = numpy.max((cell.nimgs, fakecell.nimgs), axis=0) Ls = numpy.asarray(cell.get_lattice_Ls(nimgs), order='C') expLk = numpy.asarray(numpy.exp(1j * numpy.dot(Ls, kpts.T)), order='C') nkpts = len(kpts) nao = cell.nao_nr() naux = fakecell.nao_nr() buf = [ numpy.zeros((nao, nao, naux), order='F', dtype=numpy.complex128) for k in range(nkpts) ] ints = incore._wrap_int3c(cell, fakecell, intor, 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int * 6)(0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2, len(bas)) xyz = cell.atom_coords().copy('C') ptr_coordL = atm[:cell.natm, gto.PTR_COORD] ptr_coordL = numpy.vstack( (ptr_coordL, ptr_coordL + 1, ptr_coordL + 2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l + 1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) for k, kpt in enumerate(kpts): v = numpy.einsum('ijk->ij', buf[k]) if abs(kpt).sum() < 1e-9: # gamma_point: v = v.real + v.real.T else: v = v + v.T.conj() buf[k] = v return buf
def _int_vloc_part2(cell, fakecell, kpts, intor='cint3c1e_sph'): '''Vnuc - Vloc''' from pyscf.pbc.df import incore # sum over largest number of images in either cell or auxcell rcut = max(cell.rcut, fakecell.rcut) Ls = cell.get_lattice_Ls(rcut=rcut) expLk = numpy.asarray(numpy.exp(1j*numpy.dot(Ls, kpts.T)), order='C') nkpts = len(kpts) nao = cell.nao_nr() naux = fakecell.nao_nr() buf = [numpy.zeros((nao,nao,naux), order='F', dtype=numpy.complex128) for k in range(nkpts)] ints = incore._wrap_int3c(cell, fakecell, intor, 1, Ls, buf) atm, bas, env = ints._envs[:3] c_shls_slice = (ctypes.c_int*6)(0, cell.nbas, cell.nbas, cell.nbas*2, cell.nbas*2, len(bas)) xyz = cell.atom_coords().copy('C') ptr_coordL = atm[:cell.natm,gto.PTR_COORD] ptr_coordL = numpy.vstack((ptr_coordL,ptr_coordL+1,ptr_coordL+2)).T.copy('C') for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 exp_Lk = numpy.einsum('k,ik->ik', expLk[l].conj(), expLk[:l+1]) exp_Lk = numpy.asarray(exp_Lk, order='C') exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) for k, kpt in enumerate(kpts): v = numpy.einsum('ijk->ij', buf[k]) if abs(kpt).sum() < 1e-9: # gamma_point: v = v.real + v.real.T else: v = v + v.T.conj() buf[k] = v return buf
def aux_e2(cell, auxcell, erifile, intor='cint3c2e_sph', aosym='s1', comp=1, kptij_lst=None, dataname='eri_mo', max_memory=2000, verbose=0): '''3-center AO integrals (ij|L) with double lattice sum: \sum_{lm} (i[l]j[m]|L[0]), where L is the auxiliary basis. On diks, the integrals are stored as (kptij_idx, naux, nao_pair) Args: kptij_lst : (*,2,3) array A list of (kpti, kptj) ''' if comp > 1: raise NotImplementedError('comp = %d' % comp) if h5py.is_hdf5(erifile): feri = h5py.File(erifile) if dataname in feri: del (feri[dataname]) if dataname + '-kptij' in feri: del (feri[dataname + '-kptij']) else: feri = h5py.File(erifile, 'w') if kptij_lst is None: kptij_lst = numpy.zeros((1, 2, 3)) feri[dataname + '-kptij'] = kptij_lst nkptij = len(kptij_lst) # sum over largest number of images in either cell or auxcell nimgs = numpy.max((cell.nimgs, auxcell.nimgs), axis=0) Ls = cell.get_lattice_Ls(nimgs) logger.debug1(cell, "pbc.df.outcore.Images %s", nimgs) logger.debug3(cell, "Ls = %s", Ls) nao = cell.nao_nr() #naux = auxcell.nao_nr('ssc' in intor) naux = auxcell.nao_nr() aosym_s2 = numpy.zeros(nkptij, dtype=bool) for k, kptij in enumerate(kptij_lst): key = '%s/%d' % (dataname, k) if abs(kptij).sum() < 1e-9: # gamma_point: dtype = 'f8' else: dtype = 'c16' aosym_s2[k] = abs(kptij[0] - kptij[1]).sum() < 1e-9 if aosym_s2[k]: nao_pair = nao * (nao + 1) // 2 else: nao_pair = nao * nao if comp == 1: shape = (naux, nao_pair) else: shape = (comp, naux, nao_pair) chunks = (min(256, naux), min(256, nao_pair)) # 512 KB feri.create_dataset(key, shape, dtype, chunks=chunks) if naux == 0: feri.close() return erifile aux_loc = auxcell.ao_loc_nr('ssc' in intor) buflen = max(8, int(max_memory * 1e6 / 16 / (nkptij * nao**2 * comp))) auxranges = balance_segs(aux_loc[1:] - aux_loc[:-1], buflen) buflen = max([x[2] for x in auxranges]) buf = [ numpy.zeros(nao * nao * buflen * comp, dtype=numpy.complex128) for k in range(nkptij) ] ints = incore._wrap_int3c(cell, auxcell, intor, comp, Ls, buf) atm, bas, env = ints._envs[:3] xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm, PTR_COORD] ptr_coordL = numpy.vstack( (ptr_coordL, ptr_coordL + 1, ptr_coordL + 2)).T.copy('C') kpti = kptij_lst[:, 0] kptj = kptij_lst[:, 1] if numpy.all(aosym_s2): def ccsum_or_reorder(Lpq): tmp = numpy.asarray(Lpq.transpose(0, 2, 1).conj(), order='C') tmp += Lpq return tmp else: def ccsum_or_reorder(Lpq): return numpy.asarray(Lpq, order='C') naux0 = 0 for istep, auxrange in enumerate(auxranges): sh0, sh1, nrow = auxrange c_shls_slice = (ctypes.c_int * 6)(0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2 + sh0, cell.nbas * 2 + sh1) if numpy.all(aosym_s2): for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 e = numpy.dot( Ls[:l + 1] - L1, kptj.T) # Lattice sum over half of the images {1..l} exp_Lk = numpy.exp(1j * numpy.asarray(e, order='C')) exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) else: for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 e = numpy.dot(Ls, kptj.T) - numpy.dot(L1, kpti.T) exp_Lk = numpy.exp(1j * numpy.asarray(e, order='C')) ints(exp_Lk, c_shls_slice) for k, kptij in enumerate(kptij_lst): h5dat = feri['%s/%d' % (dataname, k)] # transpose 3201 as (comp,L,i,j) mat = numpy.ndarray((nao, nao, nrow, comp), order='F', dtype=numpy.complex128, buffer=buf[k]) for icomp, vi in enumerate(mat.transpose(3, 2, 0, 1)): v = ccsum_or_reorder(vi) if abs(kptij).sum() < 1e-9: # gamma_point: v = v.real if aosym_s2[k]: v = lib.pack_tril(v) else: v = v.reshape(nrow, -1) if comp == 1: h5dat[naux0:naux0 + nrow] = v else: h5dat[icomp, naux0:naux0 + nrow] = v mat[:] = 0 naux0 += nrow feri.close() return erifile
def aux_e2(cell, auxcell, erifile, intor='cint3c2e_sph', aosym='s1', comp=1, kptij_lst=None, dataname='eri_mo', max_memory=2000, verbose=0): '''3-center AO integrals (ij|L) with double lattice sum: \sum_{lm} (i[l]j[m]|L[0]), where L is the auxiliary basis. On diks, the integrals are stored as (kptij_idx, naux, nao_pair) Args: kptij_lst : (*,2,3) array A list of (kpti, kptj) ''' if comp > 1: raise NotImplementedError('comp = %d' % comp) if h5py.is_hdf5(erifile): feri = h5py.File(erifile) if dataname in feri: del(feri[dataname]) if dataname+'-kptij' in feri: del(feri[dataname+'-kptij']) else: feri = h5py.File(erifile, 'w') if kptij_lst is None: kptij_lst = numpy.zeros((1,2,3)) feri[dataname+'-kptij'] = kptij_lst nkptij = len(kptij_lst) # sum over largest number of images in either cell or auxcell nimgs = numpy.max((cell.nimgs, auxcell.nimgs), axis=0) Ls = cell.get_lattice_Ls(nimgs) logger.debug1(cell, "pbc.df.outcore.Images %s", nimgs) logger.debug3(cell, "Ls = %s", Ls) nao = cell.nao_nr() #naux = auxcell.nao_nr('ssc' in intor) naux = auxcell.nao_nr() aosym_s2 = numpy.zeros(nkptij, dtype=bool) for k, kptij in enumerate(kptij_lst): key = '%s/%d' % (dataname, k) if abs(kptij).sum() < 1e-9: # gamma_point: dtype = 'f8' else: dtype = 'c16' aosym_s2[k] = abs(kptij[0]-kptij[1]).sum() < 1e-9 if aosym_s2[k]: nao_pair = nao * (nao+1) // 2 else: nao_pair = nao * nao if comp == 1: shape = (naux,nao_pair) else: shape = (comp,naux,nao_pair) chunks = (min(256,naux), min(256,nao_pair)) # 512 KB feri.create_dataset(key, shape, dtype, chunks=chunks) if naux == 0: feri.close() return erifile aux_loc = auxcell.ao_loc_nr('ssc' in intor) buflen = max(8, int(max_memory*1e6/16/(nkptij*nao**2*comp))) auxranges = balance_segs(aux_loc[1:]-aux_loc[:-1], buflen) buflen = max([x[2] for x in auxranges]) buf = [numpy.zeros(nao*nao*buflen*comp, dtype=numpy.complex128) for k in range(nkptij)] ints = incore._wrap_int3c(cell, auxcell, intor, comp, Ls, buf) atm, bas, env = ints._envs[:3] xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coordL = atm[:cell.natm,PTR_COORD] ptr_coordL = numpy.vstack((ptr_coordL,ptr_coordL+1,ptr_coordL+2)).T.copy('C') kpti = kptij_lst[:,0] kptj = kptij_lst[:,1] if numpy.all(aosym_s2): def ccsum_or_reorder(Lpq): tmp = numpy.asarray(Lpq.transpose(0,2,1).conj(), order='C') tmp += Lpq return tmp else: def ccsum_or_reorder(Lpq): return numpy.asarray(Lpq, order='C') naux0 = 0 for istep, auxrange in enumerate(auxranges): sh0, sh1, nrow = auxrange c_shls_slice = (ctypes.c_int*6)(0, cell.nbas, cell.nbas, cell.nbas*2, cell.nbas*2+sh0, cell.nbas*2+sh1) if numpy.all(aosym_s2): for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 e = numpy.dot(Ls[:l+1]-L1, kptj.T) # Lattice sum over half of the images {1..l} exp_Lk = numpy.exp(1j * numpy.asarray(e, order='C')) exp_Lk[l] = .5 ints(exp_Lk, c_shls_slice) else: for l, L1 in enumerate(Ls): env[ptr_coordL] = xyz + L1 e = numpy.dot(Ls, kptj.T) - numpy.dot(L1, kpti.T) exp_Lk = numpy.exp(1j * numpy.asarray(e, order='C')) ints(exp_Lk, c_shls_slice) for k, kptij in enumerate(kptij_lst): h5dat = feri['%s/%d'%(dataname,k)] # transpose 3201 as (comp,L,i,j) mat = numpy.ndarray((nao,nao,nrow,comp), order='F', dtype=numpy.complex128, buffer=buf[k]) for icomp, vi in enumerate(mat.transpose(3,2,0,1)): v = ccsum_or_reorder(vi) if abs(kptij).sum() < 1e-9: # gamma_point: v = v.real if aosym_s2[k]: v = lib.pack_tril(v) else: v = v.reshape(nrow,-1) if comp == 1: h5dat[naux0:naux0+nrow] = v else: h5dat[icomp,naux0:naux0+nrow] = v mat[:] = 0 naux0 += nrow feri.close() return erifile