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, dm_kpts): '''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) v3c = df.incore.aux_e2(cell, fakenuc, 'int3c2e_ipip1', aosym='s1', comp=9, kptij_lst=kptij_lst) v3c += df.incore.aux_e2(cell, fakenuc, 'int3c2e_ipvip1', aosym='s1', comp=9, kptij_lst=kptij_lst) nao = cell.nao_nr() natm = cell.natm v3c = v3c.reshape(nkpts,3,3,nao,nao,natm*2) efg_loc = 1./nkpts * numpy.einsum('kxypqz,kqp->zxy', v3c, dm_kpts) efg_loc+= 1./nkpts * numpy.einsum('kyxqpz,kqp->zxy', v3c, dm_kpts) v3c = None # Fermi contact fc = df.incore.aux_e2(cell, fakenuc, 'int3c1e', aosym='s1', kptij_lst=kptij_lst) fc = fc.reshape(nkpts,nao,nao,natm*2) vfc = 1./nkpts * numpy.einsum('kpqz,kqp->z', fc, dm_kpts) for i in range(3): efg_loc[:,i,i] += 4./3*numpy.pi * vfc nuc_part = efg_loc[:natm] modchg_part = efg_loc[natm:] efg_loc = nuc_part - modchg_part if cell.dimension == 3: fac = numpy.pi/cell.vol nucbar = numpy.array([fac/nuccell.bas_exp(i)[0] for i in range(natm)]) ipip = cell.pbc_intor('int1e_ipipovlp', 9, lib.HERMITIAN, kpts) ipvip = cell.pbc_intor('int1e_ipovlpip', 9, lib.HERMITIAN, kpts) d2rho_bar = 0 for k in range(nkpts): v = (ipip[k] + ipvip[k]).reshape(3,3,nao,nao) d2rho_bar += numpy.einsum('xypq,qp->xy', v, dm_kpts[k]) d2rho_bar += numpy.einsum('yxqp,qp->xy', v, dm_kpts[k]) d2rho_bar *= 1./nkpts efg_loc -= numpy.einsum('z,xy->zxy', nucbar, d2rho_bar) return efg_loc.real
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