def run3c(fill, kpts, shls_slice=None): intor = 'int3c2e_sph' nao = cell.nao_nr() nkpts = len(kpts) if fill == 'PBCnr3c_fill_gs2': out = numpy.empty((nao * (nao + 1) // 2, nao)) kptij_idx = numpy.arange(nkpts).astype(numpy.int32) elif fill == 'PBCnr3c_fill_gs1': out = numpy.empty((nao, nao, nao)) kptij_idx = numpy.arange(nkpts).astype(numpy.int32) elif fill in ('PBCnr3c_fill_kks1', 'PBCnr3c_fill_kks2'): kptij_idx = numpy.asarray( [i * nkpts + j for i in range(nkpts) for j in range(i + 1)], dtype=numpy.int32) out = numpy.empty((len(kptij_idx), nao, nao, nao), dtype=numpy.complex128) elif fill == 'PBCnr3c_fill_ks1': kptij_idx = numpy.arange(nkpts).astype(numpy.int32) out = numpy.empty((nkpts, nao, nao, nao), dtype=numpy.complex128) elif fill == 'PBCnr3c_fill_ks2': out = numpy.empty((nkpts, nao * (nao + 1) // 2, nao), dtype=numpy.complex128) kptij_idx = numpy.arange(nkpts).astype(numpy.int32) else: raise RuntimeError nkpts_ij = len(kptij_idx) nimgs = len(Ls) expkL = numpy.exp(1j * numpy.dot(kpts, Ls.T)) comp = 1 if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas * 2, cell.nbas * 2, cell.nbas * 3) pcell = copy.copy(cell) pcell._atm, pcell._bas, pcell._env = \ atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) atm, bas, env = gto.conc_env(atm, bas, env, cell._atm, cell._bas, cell._env) ao_loc = gto.moleintor.make_loc(bas, 'int3c2e_sph') cintopt = lib.c_null_ptr() pbcopt = _pbcintor.PBCOpt(pcell).init_rcut_cond(pcell, 1e-9) libpbc.PBCnr3c_drv(getattr(libpbc, intor), getattr(libpbc, fill), out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts_ij), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(len(Ls)), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), kptij_idx.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 6)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, lib.c_null_ptr(), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas), env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out
def __init__(self, mol, intor=None, prescreen='CVHFnoscreen', qcondname=None, dmcondname=None): '''If function "qcondname" is presented, the qcond (sqrt(integrals)) and will be initialized in __init__. prescreen, qcondname, dmcondname can be either function pointers or names of C functions defined in libcvhf module ''' self._this = ctypes.POINTER(_CVHFOpt)() #print self._this.contents, expect ValueError: NULL pointer access if intor is None: self._intor = intor self._cintopt = lib.c_null_ptr() else: self._intor = mol._add_suffix(intor) self._cintopt = make_cintopt(mol._atm, mol._bas, mol._env, intor) self._dmcondname = dmcondname natm = ctypes.c_int(mol.natm) nbas = ctypes.c_int(mol.nbas) libcvhf.CVHFinit_optimizer(ctypes.byref(self._this), mol._atm.ctypes.data_as(ctypes.c_void_p), natm, mol._bas.ctypes.data_as(ctypes.c_void_p), nbas, mol._env.ctypes.data_as(ctypes.c_void_p)) self.prescreen = prescreen if qcondname is not None and intor is not None: self.init_cvhf_direct(mol, intor, qcondname)
def jk_part(mol, grid_coords, dms, fg): # transfer bvv to SGXsetnr_direct_scf_blk. from _vhf.VHFOpt # need add mol._bvv in scf.mole.py c_bvv = numpy.asarray(mol._bvv, dtype=numpy.int32, order='C') nbvv = ctypes.c_int(c_bvv.shape[0]) ao_loc = make_loc(c_bas, intor) fsetqcond = getattr(libcvhf, 'SGXsetnr_direct_scf_blk') fsetqcond(vhfopt._this, getattr(libcvhf, intor), lib.c_null_ptr(), ao_loc.ctypes.data_as(ctypes.c_void_p), c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p), c_bvv.ctypes.data_as(ctypes.c_void_p), nbvv) fakemol = gto.fakemol_for_charges(grid_coords) atm, bas, env = gto.mole.conc_env(mol._atm, mol._bas, mol._env, fakemol._atm, fakemol._bas, fakemol._env) ao_loc = moleintor.make_loc(bas, intor) shls_slice = (0, mol.nbas, 0, mol.nbas, mol.nbas, len(bas)) ngrids = grid_coords.shape[0] vj = vk = None fjk = [] dmsptr = [] vjkptr = [] if with_j: if dms[0].ndim == 1: # the value of density at each grid vj = numpy.zeros((len(dms), ncomp, nao, nao))[:, 0] for i, dm in enumerate(dms): dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p)) vjkptr.append(vj[i].ctypes.data_as(ctypes.c_void_p)) fjk.append(_vhf._fpointer('SGXnr' + aosym + '_ijg_g_ij')) else: vj = numpy.zeros((len(dms), ncomp, ngrids))[:, 0] for i, dm in enumerate(dms): dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p)) vjkptr.append(vj[i].ctypes.data_as(ctypes.c_void_p)) fjk.append(_vhf._fpointer('SGXnr' + aosym + '_ijg_ji_g')) if with_k: vk = numpy.zeros((len(fg), ncomp, ngrids, nao))[:, 0] for i, dm in enumerate(fg): dmsptr.append(dm.ctypes.data_as(ctypes.c_void_p)) vjkptr.append(vk[i].ctypes.data_as(ctypes.c_void_p)) fjk.append(_vhf._fpointer('SGXnr' + aosym + '_ijg_gj_gi')) n_dm = len(fjk) fjk = (ctypes.c_void_p * (n_dm))(*fjk) dmsptr = (ctypes.c_void_p * (n_dm))(*dmsptr) vjkptr = (ctypes.c_void_p * (n_dm))(*vjkptr) drv(cintor, fdot, fjk, dmsptr, vjkptr, n_dm, ncomp, (ctypes.c_int * 6)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, vhfopt._this, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), env.ctypes.data_as(ctypes.c_void_p)) return vj, vk
def run(intor, comp=1, suffix='_sph', thr=1e-7): if suffix == '_spinor': intor = intor = 'c%s'%intor else: intor = intor = 'c%s%s'%(intor,suffix) print intor fn1 = getattr(_cint3, intor) fn2 = getattr(_cint2, intor) cintopt = make_cintopt(mol._atm, mol._bas, mol._env, intor) args = (mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), cintopt) for i in range(mol.nbas): for j in range(mol.nbas): for k in range(mol.nbas): for l in range(mol.nbas): ref = mol.intor_by_shell(intor, [i,j,k,l], comp=comp) #fn2(ref.ctypes.data_as(ctypes.c_void_p), # (ctypes.c_int*4)(i,j,k,l), # mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), # mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), # mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr()) buf = numpy.empty_like(ref) fn1(buf.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(i,j,k,l), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr()) if numpy.linalg.norm(ref-buf) > thr: print intor, '| nopt', i, j, k, l, numpy.linalg.norm(ref-buf)#, ref, buf #exit() fn1(buf.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(i,j,k,l), *args) if numpy.linalg.norm(ref-buf) > thr: print intor, '|', i, j, k, l, numpy.linalg.norm(ref-buf)
def get_ovlp(mf, cell=None, kpts=None): '''Get the overlap AO matrices at sampled k-points. Args: kpts : (nkpts, 3) ndarray Returns: ovlp_kpts : (nkpts, nao, nao) ndarray ''' if cell is None: cell = mf.cell if kpts is None: kpts = mf.kpts # Avoid pbcopt's prescreening in the lattice sum, for better accuracy s = cell.pbc_intor('int1e_ovlp', hermi=1, kpts=kpts, pbcopt=lib.c_null_ptr()) cond = np.max(lib.cond(s)) if cond * cell.precision > 1e2: prec = 1e2 / cond rmin = max([cell.bas_rcut(ib, prec) for ib in range(cell.nbas)]) if cell.rcut < rmin: logger.warn( cell, 'Singularity detected in overlap matrix. ' 'Integral accuracy may be not enough.\n ' 'You can adjust cell.precision or cell.rcut to ' 'improve accuracy. Recommended values are\n ' 'cell.precision = %.2g or smaller.\n ' 'cell.rcut = %.4g or larger.', prec, rmin) return lib.asarray(s)
def type2_by_shell(mol, shls, cart=False): li = mol.bas_angular(shls[0]) lj = mol.bas_angular(shls[1]) if cart: fn = libecp.ECPtype2_cart di = (li + 1) * (li + 2) // 2 * mol.bas_nctr(shls[0]) dj = (lj + 1) * (lj + 2) // 2 * mol.bas_nctr(shls[1]) else: fn = libecp.ECPtype2_sph di = (li * 2 + 1) * mol.bas_nctr(shls[0]) dj = (lj * 2 + 1) * mol.bas_nctr(shls[1]) cache_size = libecp.ECPscalar_cache_size( ctypes.c_int(1), (ctypes.c_int * 2)(*shls), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) cache = numpy.empty(cache_size) buf = numpy.empty((di, dj), order='F') fn(buf.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 2)(*shls), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(mol._ecpbas)), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr(), cache.ctypes.data_as(ctypes.c_void_p)) return buf
def get_ovlp(cell, kpt=np.zeros(3)): '''Get the overlap AO matrix. ''' # Avoid pbcopt's prescreening in the lattice sum, for better accuracy s = cell.pbc_intor('int1e_ovlp', hermi=0, kpts=kpt, pbcopt=lib.c_null_ptr()) s = lib.asarray(s) hermi_error = abs(s - np.rollaxis(s.conj(), -1, -2)).max() if hermi_error > cell.precision and hermi_error > 1e-12: logger.warn( cell, '%.4g error found in overlap integrals. ' 'cell.precision or cell.rcut can be adjusted to ' 'improve accuracy.') cond = np.max(lib.cond(s)) if cond * cell.precision > 1e2: prec = 1e2 / cond rmin = max([cell.bas_rcut(ib, prec) for ib in range(cell.nbas)]) if cell.rcut < rmin: logger.warn( cell, 'Singularity detected in overlap matrix. ' 'Integral accuracy may be not enough.\n ' 'You can adjust cell.precision or cell.rcut to ' 'improve accuracy. Recommended values are\n ' 'cell.precision = %.2g or smaller.\n ' 'cell.rcut = %.4g or larger.', prec, rmin) return s
def _get_jk(_rdm1, _eri): j = np.zeros((nphys * (nphys + 1) // 2), dtype=types.float64) k = np.zeros((nphys, nphys), dtype=types.float64) _rdm1_tril = lib.pack_tril(_rdm1 + np.tril(_rdm1, k=-1)) c_int = ctypes.c_int args = (c_int(nphys), (c_int * 4)(0, nphys, 0, nphys), lib.c_null_ptr(), c_int(0)) buf = np.empty((2, maxblk, nphys, nphys)) for p0 in range(0, naux, maxblk): s = slice(p0, min(p0 + maxblk, naux)) eri1 = _eri[s] naux_block = eri1.shape[0] rho = np.dot(eri1, _rdm1_tril) j += np.dot(rho, eri1) buf1 = buf[0, :naux_block] _fdrv(to_ptr(buf1), to_ptr(eri1), to_ptr(_rdm1), c_int(naux_block), *args) buf2 = lib.unpack_tril(eri1, out=buf[1]) k = util.dgemm(buf1.reshape((-1, nphys)).T, buf2.reshape((-1, nphys)), c=k, beta=1) j = lib.unpack_tril(j).reshape(_rdm1.shape) k = k.reshape(_rdm1.shape) return j, k
def get_A_mat(self): ''' Construct the projection matrix: A_{m,n}^{\mathbf{k}} Equation (62) in MV, Phys. Rev. B 56, 12847 or equation (22) in SMV, Phys. Rev. B 65, 035109 ''' A_matrix_loc = np.empty( [self.num_kpts_loc, self.num_wann_loc, self.num_bands_loc], dtype=np.complex128) if self.use_bloch_phases == True: Amn = np.zeros([self.num_wann_loc, self.num_bands_loc]) np.fill_diagonal(Amn, 1) A_matrix_loc[:, :, :] = Amn else: from pyscf.dft import numint, gen_grid grids = gen_grid.Grids(self.cell).build() coords = grids.coords weights = grids.weights for ith_wann in range(self.num_wann_loc): frac_site = self.proj_site[ith_wann] abs_site = frac_site.dot(self.real_lattice_loc) / param.BOHR l = self.proj_l[ith_wann] mr = self.proj_m[ith_wann] r = self.proj_radial[ith_wann] zona = self.proj_zona[ith_wann] x_axis = self.proj_x[ith_wann] z_axis = self.proj_z[ith_wann] gr = g_r(coords, abs_site, l, mr, r, zona, x_axis, z_axis, unit='B') ao_L0 = numint.eval_ao(self.cell, coords) s_aoL0_g = np.einsum('i,i,iv->v', weights, gr, ao_L0, optimize=True) for k_id in range(self.num_kpts_loc): kpt = self.cell.get_abs_kpts(self.kpt_latt_loc[k_id]) mo_included = self.mo_coeff_kpts[k_id][:, self. band_included_list] s_kpt = self.cell.pbc_intor('int1e_ovlp', hermi=1, kpts=kpt, pbcopt=lib.c_null_ptr()) s_ao = np.einsum('uv,v->u', s_kpt, s_aoL0_g, optimize=True) A_matrix_loc[k_id, ith_wann, :] = np.einsum( 'v,vu,um->m', s_aoL0_g, s_kpt, mo_included, optimize=True).conj() return A_matrix_loc
def run2c(intor, fill, kpts, shls_slice=None): nkpts = len(kpts) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas * 2) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] comp = 1 out = numpy.empty((nkpts, comp, ni, nj), dtype=numpy.complex128) fintor = getattr(gto.moleintor.libcgto, intor) fill = getattr(libpbc, fill) intopt = lib.c_null_ptr() Ls = cell.get_lattice_Ls() expkL = numpy.asarray(numpy.exp(1j * numpy.dot(kpts, Ls.T)), order='C') drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(len(Ls)), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas), env.ctypes.data_as(ctypes.c_void_p)) return out
def run2c(intor, fill, kpts, shls_slice=None): nkpts = len(kpts) pcell = copy.copy(cell) pcell._atm, pcell._bas, pcell._env = \ atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] comp = 1 out = numpy.empty((nkpts,comp,ni,nj), dtype=numpy.complex128) fintor = getattr(gto.moleintor.libcgto, intor) fill = getattr(libpbc, fill) intopt = lib.c_null_ptr() pbcopt = _pbcintor.PBCOpt(pcell).init_rcut_cond(pcell, 1e-9) expkL = numpy.asarray(numpy.exp(1j*numpy.dot(kpts, Ls.T)), order='C') drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(len(Ls)), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, pbcopt._this, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas), env.ctypes.data_as(ctypes.c_void_p)) return out
def ft_ao(mol, Gv, shls_slice=None, b=numpy.eye(3), gxyz=None, Gvbase=None, verbose=None): ''' FT transform AO ''' if shls_slice is None: shls_slice = (0, mol.nbas) nGv = Gv.shape[0] if (gxyz is None or b is None or Gvbase is None # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int * 3)(0, 0, 0) p_b = (ctypes.c_double * 1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b - numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), numpy.zeros(3)) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int * 3)(*[len(x) for x in Gvbase]) fn = libcgto.GTO_ft_ovlp_mat intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) fill = getattr(libcgto, 'GTO_ft_fill_s1') ghost_atm = numpy.array([[0, 0, 0, 0, 0, 0]], dtype=numpy.int32) ghost_bas = numpy.array([[0, 0, 1, 1, 0, 0, 3, 0]], dtype=numpy.int32) ghost_env = numpy.zeros(4) ghost_env[3] = numpy.sqrt(4 * numpy.pi) # s function spherical norm atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, ghost_atm, ghost_bas, ghost_env) ao_loc = mol.ao_loc_nr() nao = ao_loc[mol.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc, [nao + 1])), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] mat = numpy.zeros((nGv, ni), order='F', dtype=numpy.complex) shls_slice = shls_slice + (mol.nbas, mol.nbas + 1) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(atm)), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(bas)), env.ctypes.data_as(ctypes.c_void_p)) return mat
def int_ket(_bas, intor): if len(_bas) == 0: return [] intor = cell._add_suffix(intor) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = numpy.empty((nkpts, ni, nj), dtype=numpy.complex128) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, lib.c_null_ptr(), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out
def int_ket(_bas, intor): if len(_bas) == 0: return [] intor = cell._add_suffix(intor) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = numpy.empty((nkpts,ni,nj), dtype=numpy.complex128) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, lib.c_null_ptr(), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out
def run(intor, comp=1, suffix='_sph', thr=1e-9): if suffix == '_spinor': intor = intor = 'c%s' % intor else: intor = intor = 'c%s%s' % (intor, suffix) print intor fn1 = getattr(_cint3, intor) #fn2 = getattr(_cint2, intor) #cintopt = make_cintopt(mol._atm, mol._bas, mol._env, intor) cintopt = lib.c_null_ptr() args = (mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), cintopt) for i in range(mol.nbas): for j in range(mol.nbas): ref = mol.intor_by_shell(intor, [i, j], comp=comp) #fn2(ref.ctypes.data_as(ctypes.c_void_p), # (ctypes.c_int*2)(i,j), # mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), # mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), # mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr()) buf = numpy.empty_like(ref) fn1(buf.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 2)(i, j), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) if numpy.linalg.norm(ref - buf) > thr: print intor, '| nopt', i, j, numpy.linalg.norm( ref - buf) #, ref, buf exit()
def gen_type1(shls): di = (mol.bas_angular(shls[0]) * 2 + 1) * mol.bas_nctr(shls[0]) dj = (mol.bas_angular(shls[1]) * 2 + 1) * mol.bas_nctr(shls[1]) mat0 = numpy.zeros((di, dj)) for ia in range(mol.natm): ecpbas = mol._ecpbas[mol._ecpbas[:, ATOM_OF] == ia] if len(ecpbas) == 0: continue ecpbas0 = ecpbas[ecpbas[:, ANG_OF] < 0] if len(ecpbas0) == 0: continue mat0 += type1_by_shell(mol, shls, ia, ecpbas0) mat1 = numpy.empty(mat0.shape, order='F') cache = numpy.empty(100000) libecp.ECPtype1_sph(mat1.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 2)(*shls), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(mol._ecpbas)), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr(), cache.ctypes.data_as(ctypes.c_void_p)) if not numpy.allclose(mat0, mat1, atol=1e-8): print(i, j, numpy.linalg.norm(mat0 - mat1)) self.assertTrue(numpy.allclose(mat0, mat1, atol=1e-6)) mat2 = gto.ecp.type1_by_shell(mol, shls) self.assertTrue(numpy.allclose(mat0, mat2, atol=1e-6))
def gen_type1(shls): di = (mol.bas_angular(shls[0])*2+1) * mol.bas_nctr(shls[0]) dj = (mol.bas_angular(shls[1])*2+1) * mol.bas_nctr(shls[1]) mat0 = numpy.zeros((di,dj)) for ia in range(mol.natm): ecpbas = mol._ecpbas[mol._ecpbas[:,ATOM_OF] == ia] if len(ecpbas) == 0: continue ecpbas0 = ecpbas[ecpbas[:,ANG_OF] < 0] if len(ecpbas0) == 0: continue mat0 += type1_by_shell(mol, shls, ia, ecpbas0) mat1 = numpy.empty(mat0.shape, order='F') cache = numpy.empty(100000) libecp.ECPtype1_sph(mat1.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*2)(*shls), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(mol._ecpbas)), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr(), cache.ctypes.data_as(ctypes.c_void_p)) if not numpy.allclose(mat0, mat1, atol=1e-8): print(i, j, numpy.linalg.norm(mat0-mat1)) self.assertTrue(numpy.allclose(mat0, mat1, atol=1e-6)) mat2 = gto.ecp.type1_by_shell(mol, shls) self.assertTrue(numpy.allclose(mat0, mat2, atol=1e-6))
def ft_aopair(mol, Gv, shls_slice=None, aosym='s1', b=numpy.eye(3), gxyz=None, Gvbase=None, buf=None, verbose=None): r''' FT transform AO pair \int i(r) j(r) exp(-ikr) dr^3 ''' if shls_slice is None: shls_slice = (0, mol.nbas, 0, mol.nbas) nGv = Gv.shape[0] if (gxyz is None or b is None or Gvbase is None # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b-numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), numpy.zeros(3)) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) fn = libcgto.GTO_ft_ovlp_mat intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) ao_loc = numpy.asarray(mol.ao_loc_nr(), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] if aosym == 's1': if shls_slice[:2] == shls_slice[2:4]: fill = getattr(libcgto, 'GTO_ft_fill_s1hermi') else: fill = getattr(libcgto, 'GTO_ft_fill_s1') shape = (nGv,ni,nj) else: fill = getattr(libcgto, 'GTO_ft_fill_s2') i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nGv,nij) mat = numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=buf) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) return mat
def fill_2c2e(cell, auxcell, intor='int2c2e', hermi=0, kpt=numpy.zeros(3)): '''2-center 2-electron AO integrals (L|ij), where L is the auxiliary basis. ''' if hermi != 0: hermi = pyscf.lib.HERMITIAN # pbcopt use the value of AO-pair to prescreening PBC integrals in the lattice # summation. Pass NULL pointer to pbcopt to prevent the prescreening return auxcell.pbc_intor(intor, 1, hermi, kpt, pbcopt=lib.c_null_ptr())
def r_e1(intor, mo_coeff, orbs_slice, sh_range, atm, bas, env, tao, aosym='s1', comp=1, ao2mopt=None, out=None): assert(aosym in ('s4', 's2ij', 's2kl', 's1', 'a2ij', 'a2kl', 'a4ij', 'a4kl', 'a4')) intor = ascint3(intor) mo_coeff = numpy.asfortranarray(mo_coeff) i0, i1, j0, j1 = orbs_slice icount = i1 - i0 jcount = j1 - j0 ij_count = icount * jcount c_atm = numpy.asarray(atm, dtype=numpy.int32) c_bas = numpy.asarray(bas, dtype=numpy.int32) c_env = numpy.asarray(env) natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) klsh0, klsh1, nkl = sh_range if icount <= jcount: fmmm = _fpointer('AO2MOmmm_r_iltj') else: fmmm = _fpointer('AO2MOmmm_r_igtj') if out is None: out = numpy.empty((comp,nkl,ij_count), dtype=numpy.complex) else: out = numpy.ndarray((comp,nkl,nao_pair), dtype=numpy.complex, buffer=out) if out.size == 0: return out if ao2mopt is not None: cao2mopt = ao2mopt._this cintopt = ao2mopt._cintopt cintor = ao2mopt._intor else: cao2mopt = lib.c_null_ptr() cintor = _fpointer(intor) cintopt = make_cintopt(c_atm, c_bas, c_env, intor) tao = numpy.asarray(tao, dtype=numpy.int32) ao_loc = make_loc(bas, 'spinor') fdrv = getattr(libao2mo, 'AO2MOr_e1_drv') fill = _fpointer('AO2MOfill_r_' + aosym) ftrans = _fpointer('AO2MOtranse1_r_' + aosym) fdrv(cintor, fill, ftrans, fmmm, out.ctypes.data_as(ctypes.c_void_p), mo_coeff.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(klsh0), ctypes.c_int(klsh1-klsh0), ctypes.c_int(nkl), ctypes.c_int(comp), (ctypes.c_int*4)(*orbs_slice), tao.ctypes.data_as(ctypes.c_void_p), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cao2mopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) return out
def ft_ao(mol, Gv, shls_slice=None, b=numpy.eye(3), gxyz=None, Gvbase=None, verbose=None): ''' FT transform AO ''' if shls_slice is None: shls_slice = (0, mol.nbas) nGv = Gv.shape[0] if (gxyz is None or b is None or Gvbase is None # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b-numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), numpy.zeros(3)) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) fn = libcgto.GTO_ft_fill_drv if mol.cart: intor = getattr(libcgto, 'GTO_ft_ovlp_cart') else: intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) fill = getattr(libcgto, 'GTO_ft_fill_s1') ghost_atm = numpy.array([[0,0,0,0,0,0]], dtype=numpy.int32) ghost_bas = numpy.array([[0,0,1,1,0,0,3,0]], dtype=numpy.int32) ghost_env = numpy.zeros(4) ghost_env[3] = numpy.sqrt(4*numpy.pi) # s function spherical norm atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, ghost_atm, ghost_bas, ghost_env) ao_loc = mol.ao_loc_nr() nao = ao_loc[mol.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc, [nao+1])), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] mat = numpy.zeros((nGv,ni), order='F', dtype=numpy.complex) shls_slice = shls_slice + (mol.nbas, mol.nbas+1) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(1), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(atm)), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(bas)), env.ctypes.data_as(ctypes.c_void_p)) return mat
def ft_ao(mol, Gv, shls_slice=None, invh=None, gxyz=None, gs=None, verbose=None): ''' FT transform AO ''' if shls_slice is None: shls_slice = (0, mol.nbas) nGv = Gv.shape[0] if gxyz is None or invh is None or gs is None: GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_invh = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*gs) # Guess what type of eval_gz to use if isinstance(invh, numpy.ndarray) and invh.shape == (3,3): p_invh = invh.ctypes.data_as(ctypes.c_void_p) if numpy.allclose(invh-numpy.diag(invh.diagonal()), 0): eval_gz = 'GTO_Gv_uniform_orth' else: eval_gz = 'GTO_Gv_uniform_nonorth' else: invh = numpy.hstack(invh) p_invh = invh.ctypes.data_as(ctypes.c_void_p) eval_gz = 'GTO_Gv_nonuniform_orth' fn = libcgto.GTO_ft_ovlp_mat intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) fill = getattr(libcgto, 'GTO_ft_fill_s1') ghost_atm = numpy.array([[0,0,0,0,0,0]], dtype=numpy.int32) ghost_bas = numpy.array([[0,0,1,1,0,0,3,0]], dtype=numpy.int32) ghost_env = numpy.zeros(4) ghost_env[3] = numpy.sqrt(4*numpy.pi) # s function spheric norm atm, bas, env = gto.conc_env(mol._atm, mol._bas, mol._env, ghost_atm, ghost_bas, ghost_env) ao_loc = mol.ao_loc_nr() nao = ao_loc[mol.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc, [nao+1])), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] mat = numpy.zeros((nGv,ni), order='F', dtype=numpy.complex) shls_slice = shls_slice + (mol.nbas, mol.nbas+1) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_invh, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(atm)), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(bas)), env.ctypes.data_as(ctypes.c_void_p)) return mat
def r_e1(intor, mo_coeff, orbs_slice, sh_range, atm, bas, env, tao, aosym='s1', comp=1, ao2mopt=None, out=None): assert(aosym in ('s4', 's2ij', 's2kl', 's1', 'a2ij', 'a2kl', 'a4ij', 'a4kl', 'a4')) mo_coeff = numpy.asfortranarray(mo_coeff) i0, i1, j0, j1 = orbs_slice icount = i1 - i0 jcount = j1 - j0 ij_count = icount * jcount c_atm = numpy.asarray(atm, dtype=numpy.int32) c_bas = numpy.asarray(bas, dtype=numpy.int32) c_env = numpy.asarray(env) natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) klsh0, klsh1, nkl = sh_range if icount <= jcount: fmmm = _fpointer('AO2MOmmm_r_iltj') else: fmmm = _fpointer('AO2MOmmm_r_igtj') if out is None: out = numpy.empty((comp,nkl,ij_count), dtype=numpy.complex) else: out = numpy.ndarray((comp,nkl,nao_pair), dtype=numpy.complex, buffer=out) if out.size == 0: return out if ao2mopt is not None: cao2mopt = ao2mopt._this cintopt = ao2mopt._cintopt cintor = ao2mopt._intor else: cao2mopt = lib.c_null_ptr() cintor = _fpointer(intor) cintopt = _vhf.make_cintopt(c_atm, c_bas, c_env, intor) tao = numpy.asarray(tao, dtype=numpy.int32) ao_loc = moleintor.make_loc(bas, 'spinor') fdrv = getattr(libao2mo, 'AO2MOr_e1_drv') fill = _fpointer('AO2MOfill_r_' + aosym) ftrans = _fpointer('AO2MOtranse1_r_' + aosym) fdrv(cintor, fill, ftrans, fmmm, out.ctypes.data_as(ctypes.c_void_p), mo_coeff.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(klsh0), ctypes.c_int(klsh1-klsh0), ctypes.c_int(nkl), ctypes.c_int(comp), (ctypes.c_int*4)(*orbs_slice), tao.ctypes.data_as(ctypes.c_void_p), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cao2mopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) return out
def __init__(self, mol, intor, prescreen='CVHFnoscreen', qcondname=None, dmcondname=None): intor = mol._add_suffix(intor) self._this = ctypes.POINTER(_CVHFOpt)() #print self._this.contents, expect ValueError: NULL pointer access self._intor = intor self._cintopt = lib.c_null_ptr() self._dmcondname = dmcondname self.init_cvhf_direct(mol, intor, prescreen, qcondname)
def _int_vnl(cell, fakecell, hl_blocks, kpts): '''Vnuc - Vloc''' 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) xyz = numpy.asarray(cell.atom_coords(), order='C') fill = getattr(libpbc, 'PBCnr2c_fill_s1') intopt = lib.c_null_ptr() def int_ket(_bas, intor): if len(_bas) == 0: return [] atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = [ numpy.zeros((ni, nj), order='F', dtype=numpy.complex128) for k in range(nkpts) ] out_ptrs = (ctypes.c_void_p * nkpts)(*[x.ctypes.data_as(ctypes.c_void_p) for x in out]) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) ptr_coords = numpy.asarray(atm[:cell.natm, gto.PTR_COORD], dtype=numpy.int32, order='C') drv = libpbc.PBCnr2c_drv drv(fintor, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coords.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), expLk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), (ctypes.c_int * 4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p)) return out hl_dims = numpy.asarray([len(hl) for hl in hl_blocks]) out = (int_ket(fakecell._bas[hl_dims > 0], 'cint1e_ovlp_sph'), int_ket(fakecell._bas[hl_dims > 1], 'cint1e_pbc_r2_origi_sph'), int_ket(fakecell._bas[hl_dims > 2], 'cint1e_pbc_r4_origi_sph')) return out
def ft_aopair(mol, Gv, shls_slice=None, aosym='s1', b=numpy.eye(3), gxyz=None, Gvbase=None, buf=None, verbose=None): ''' FT transform AO pair \int i(r) j(r) exp(-ikr) dr^3 ''' if shls_slice is None: shls_slice = (0, mol.nbas, 0, mol.nbas) nGv = Gv.shape[0] if (gxyz is None or b is None or Gvbase is None # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), numpy.zeros(3)) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) eval_gz = 'GTO_Gv_cubic' fn = libcgto.GTO_ft_ovlp_mat intor = getattr(libcgto, 'GTO_ft_ovlp_sph') eval_gz = getattr(libcgto, eval_gz) ao_loc = numpy.asarray(mol.ao_loc_nr(), dtype=numpy.int32) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] if aosym == 's1': if shls_slice[:2] == shls_slice[2:4]: fill = getattr(libcgto, 'GTO_ft_fill_s1hermi') else: fill = getattr(libcgto, 'GTO_ft_fill_s1') shape = (nGv,ni,nj) else: fill = getattr(libcgto, 'GTO_ft_fill_s2') i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nGv,nij) mat = numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=buf) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) return mat
def make_cintopt(atm, bas, env, intor): c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = c_atm.shape[0] nbas = c_bas.shape[0] cintopt = lib.c_null_ptr() foptinit = getattr(_cint3, intor + '_optimizer') foptinit(ctypes.byref(cintopt), c_atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), c_bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), c_env.ctypes.data_as(ctypes.c_void_p)) return cintopt
def run3c(fill, kpts, shls_slice=None): intor = 'int3c2e_sph' nao = cell.nao_nr() nkpts = len(kpts) if fill == 'PBCnr3c_fill_gs2': out = numpy.empty((nao*(nao+1)//2,nao)) kptij_idx = numpy.arange(nkpts).astype(numpy.int32) elif fill == 'PBCnr3c_fill_gs1': out = numpy.empty((nao,nao,nao)) kptij_idx = numpy.arange(nkpts).astype(numpy.int32) elif fill in ('PBCnr3c_fill_kks1', 'PBCnr3c_fill_kks2'): kptij_idx = numpy.asarray([i*nkpts+j for i in range(nkpts) for j in range(i+1)], dtype=numpy.int32) out = numpy.empty((len(kptij_idx),nao,nao,nao), dtype=numpy.complex128) elif fill == 'PBCnr3c_fill_ks1': kptij_idx = numpy.arange(nkpts).astype(numpy.int32) out = numpy.empty((nkpts,nao,nao,nao), dtype=numpy.complex128) elif fill == 'PBCnr3c_fill_ks2': out = numpy.empty((nkpts,nao*(nao+1)//2,nao), dtype=numpy.complex128) kptij_idx = numpy.arange(nkpts).astype(numpy.int32) else: raise RuntimeError nkpts_ij = len(kptij_idx) nimgs = len(Ls) expkL = numpy.exp(1j*numpy.dot(kpts, Ls.T)) comp = 1 if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2, cell.nbas*2, cell.nbas*3) pcell = copy.copy(cell) pcell._atm, pcell._bas, pcell._env = \ atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) atm, bas, env = gto.conc_env(atm, bas, env, cell._atm, cell._bas, cell._env) ao_loc = gto.moleintor.make_loc(bas, 'int3c2e_sph') cintopt = lib.c_null_ptr() pbcopt = _pbcintor.PBCOpt(pcell).init_rcut_cond(pcell, 1e-9) libpbc.PBCnr3c_drv(getattr(libpbc, intor), getattr(libpbc, fill), out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts_ij), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(len(Ls)), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), kptij_idx.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*6)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, pbcopt._this, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas), env.ctypes.data_as(ctypes.c_void_p)) return out
def _int_vnl(cell, fakecell, hl_blocks, kpts): '''Vnuc - Vloc''' 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) xyz = numpy.asarray(cell.atom_coords(), order='C') fill = getattr(libpbc, 'PBCnr2c_fill_s1') intopt = lib.c_null_ptr() def int_ket(_bas, intor): if len(_bas) == 0: return [] atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = [numpy.zeros((ni,nj), order='F', dtype=numpy.complex128) for k in range(nkpts)] out_ptrs = (ctypes.c_void_p*nkpts)( *[x.ctypes.data_as(ctypes.c_void_p) for x in out]) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) ptr_coords = numpy.asarray(atm[:cell.natm,gto.PTR_COORD], dtype=numpy.int32, order='C') drv = libpbc.PBCnr2c_drv drv(fintor, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coords.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), expLk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), (ctypes.c_int*4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p)) return out hl_dims = numpy.asarray([len(hl) for hl in hl_blocks]) out = (int_ket(fakecell._bas[hl_dims>0], 'cint1e_ovlp_sph'), int_ket(fakecell._bas[hl_dims>1], 'cint1e_pbc_r2_origi_sph'), int_ket(fakecell._bas[hl_dims>2], 'cint1e_pbc_r4_origi_sph')) return out
def make_cintopt(atm, bas, env, intor): c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = c_atm.shape[0] nbas = c_bas.shape[0] cintopt = lib.c_null_ptr() foptinit = getattr(_cint3, intor+'_optimizer') foptinit(ctypes.byref(cintopt), c_atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), c_bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), c_env.ctypes.data_as(ctypes.c_void_p)) return cintopt
def nr_e1fill(intor, sh_range, atm, bas, env, aosym='s1', comp=1, ao2mopt=None, out=None): assert (aosym in ('s4', 's2ij', 's2kl', 's1')) c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, order='C') natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) ao_loc = moleintor.make_loc(bas, intor) nao = ao_loc[-1] klsh0, klsh1, nkl = sh_range if aosym in ('s4', 's2ij'): nao_pair = nao * (nao + 1) // 2 else: nao_pair = nao * nao if out is None: out = numpy.empty((comp, nkl, nao_pair)) else: out = numpy.ndarray((comp, nkl, nao_pair), buffer=out) if out.size == 0: return out if ao2mopt is not None: cao2mopt = ao2mopt._this cintopt = ao2mopt._cintopt cintor = ao2mopt._intor else: cao2mopt = lib.c_null_ptr() cintor = _fpointer(intor) cintopt = _vhf.make_cintopt(c_atm, c_bas, c_env, intor) fdrv = getattr(libao2mo, 'AO2MOnr_e1fill_drv') fill = _fpointer('AO2MOfill_nr_' + aosym) fdrv(cintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(klsh0), ctypes.c_int(klsh1 - klsh0), ctypes.c_int(nkl), ctypes.c_int(comp), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cao2mopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) return out
def test_rad_part(self): rs, ws = radi.gauss_chebyshev(99) ur0 = rad_part(mol, mol._ecpbas, rs) ur1 = numpy.empty_like(ur0) libecp.ECPrad_part(ur1.ctypes.data_as(ctypes.c_void_p), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(0), ctypes.c_int(len(rs)), ctypes.c_int(1), (ctypes.c_int*2)(0, len(mol._ecpbas)), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr()) self.assertTrue(numpy.allclose(ur0, ur1))
def make_cintopt(atm, bas, env, intor): intor = intor.replace('_sph', '').replace('_cart', '').replace('_spinor', '') c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = c_atm.shape[0] nbas = c_bas.shape[0] cintopt = lib.c_null_ptr() foptinit = getattr(libcgto, intor + '_optimizer') foptinit(ctypes.byref(cintopt), c_atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), c_bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), c_env.ctypes.data_as(ctypes.c_void_p)) return ctypes.cast(cintopt, _cintoptHandler)
def init_cvhf_direct(self, mol, intor, qcondname): intor = mol._add_suffix(intor) if intor == self._intor: cintopt = self._cintopt else: cintopt = lib.c_null_ptr() ao_loc = make_loc(mol._bas, intor) fsetqcond = getattr(libcvhf, qcondname) natm = ctypes.c_int(mol.natm) nbas = ctypes.c_int(mol.nbas) fsetqcond(self._this, getattr(libcvhf, intor), cintopt, ao_loc.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), natm, mol._bas.ctypes.data_as(ctypes.c_void_p), nbas, mol._env.ctypes.data_as(ctypes.c_void_p))
def _int_vnl(cell, fakecell, hl_blocks, kpts): '''Vnuc - Vloc''' rcut = max(cell.rcut, fakecell.rcut) Ls = cell.get_lattice_Ls(rcut=rcut) nimgs = len(Ls) expkL = numpy.asarray(numpy.exp(1j * numpy.dot(kpts, Ls.T)), order='C') nkpts = len(kpts) fill = getattr(libpbc, 'PBCnr2c_fill_ks1') intopt = lib.c_null_ptr() def int_ket(_bas, intor): if len(_bas) == 0: return [] intor = cell._add_suffix(intor) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = numpy.empty((nkpts, ni, nj), dtype=numpy.complex128) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, lib.c_null_ptr(), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out hl_dims = numpy.asarray([len(hl) for hl in hl_blocks]) out = (int_ket(fakecell._bas[hl_dims > 0], 'int1e_ovlp'), int_ket(fakecell._bas[hl_dims > 1], 'int1e_r2_origi'), int_ket(fakecell._bas[hl_dims > 2], 'int1e_r4_origi')) return out
def _int_vnl(cell, fakecell, hl_blocks, kpts): '''Vnuc - Vloc''' rcut = max(cell.rcut, fakecell.rcut) Ls = cell.get_lattice_Ls(rcut=rcut) nimgs = len(Ls) expkL = numpy.asarray(numpy.exp(1j*numpy.dot(kpts, Ls.T)), order='C') nkpts = len(kpts) fill = getattr(libpbc, 'PBCnr2c_fill_ks1') intopt = lib.c_null_ptr() def int_ket(_bas, intor): if len(_bas) == 0: return [] intor = cell._add_suffix(intor) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, fakecell._atm, _bas, fakecell._env) atm = numpy.asarray(atm, dtype=numpy.int32) bas = numpy.asarray(bas, dtype=numpy.int32) env = numpy.asarray(env, dtype=numpy.double) natm = len(atm) nbas = len(bas) shls_slice = (cell.nbas, nbas, 0, cell.nbas) ao_loc = gto.moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = numpy.empty((nkpts,ni,nj), dtype=numpy.complex128) comp = 1 fintor = getattr(gto.moleintor.libcgto, intor) drv = libpbc.PBCnr2c_drv drv(fintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, lib.c_null_ptr(), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(env.size)) return out hl_dims = numpy.asarray([len(hl) for hl in hl_blocks]) out = (int_ket(fakecell._bas[hl_dims>0], 'int1e_ovlp'), int_ket(fakecell._bas[hl_dims>1], 'int1e_r2_origi'), int_ket(fakecell._bas[hl_dims>2], 'int1e_r4_origi')) return out
def test_rad_part(self): rs, ws = radi.gauss_chebyshev(99) ur0 = rad_part(mol, mol._ecpbas, rs) ur1 = numpy.empty_like(ur0) libecp.ECPrad_part(ur1.ctypes.data_as(ctypes.c_void_p), rs.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(0), ctypes.c_int(len(rs)), ctypes.c_int(1), (ctypes.c_int * 2)(0, len(mol._ecpbas)), mol._ecpbas.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr()) self.assertTrue(numpy.allclose(ur0, ur1))
def _dot_ao_mo(mol, ao, mo, non0tab=None, shls_slice=None, ao_loc=None, hermi=0): if hermi: #print ("_dot_ao_mo punting to numint._dot_ao_ao") return numint._dot_ao_ao(mol, ao, mo, non0tab=non0tab, shls_slice=shls_slice, ao_loc=ao_loc, hermi=hermi) ngrids, nao = ao.shape nmo = mo.shape[-1] if nao < SWITCH_SIZE: #print ("_dot_ao_mo punting to lib.dot") return lib.dot(ao.T.conj(), mo) #print ("_dot_ao_mo doing my own thing") if not ao.flags.f_contiguous: ao = lib.transpose(ao) if not mo.flags.f_contiguous: mo = lib.transpose(mo) if ao.dtype == mo.dtype == np.double: fn = libpdft.VOTdot_ao_mo else: raise NotImplementedError("Complex-orbital PDFT") if non0tab is None or shls_slice is None or ao_loc is None: pnon0tab = pshls_slice = pao_loc = lib.c_null_ptr() else: pnon0tab = non0tab.ctypes.data_as(ctypes.c_void_p) pshls_slice = (ctypes.c_int * 2)(*shls_slice) pao_loc = ao_loc.ctypes.data_as(ctypes.c_void_p) vv = np.empty((nao, nmo), dtype=ao.dtype) fn(vv.ctypes.data_as(ctypes.c_void_p), ao.ctypes.data_as(ctypes.c_void_p), mo.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nao), ctypes.c_int(nmo), ctypes.c_int(ngrids), ctypes.c_int(mol.nbas), pnon0tab, pshls_slice, pao_loc) return vv
def get_fock(self, rdm1=None): ''' Returns the Fock matrix resulting from the current, or provided, density. ''' if rdm1 is None: rdm1 = self.rdm1 nphys = self.nphys naux = self.eri.shape[0] maxblk = self.options['maxblk'] j = np.zeros((nphys * (nphys + 1) // 2), dtype=types.float64) k = np.zeros((nphys, nphys), dtype=types.float64) rdm1_tril = lib.pack_tril(rdm1 + np.tril(rdm1, k=-1)) c_int = ctypes.c_int args = (c_int(nphys), (c_int * 4)(0, nphys, 0, nphys), lib.c_null_ptr(), c_int(0)) buf = np.empty((2, maxblk, nphys, nphys)) for p0 in range(0, naux, maxblk): s = slice(p0, min(p0 + maxblk, naux)) eri1 = self.eri[s] naux_block = eri1.shape[0] rho = np.dot(eri1, rdm1_tril) j += np.dot(rho, eri1) buf1 = buf[0, :naux_block] _fdrv(to_ptr(buf1), to_ptr(eri1), to_ptr(rdm1), c_int(naux_block), *args) buf2 = lib.unpack_tril(eri1, out=buf[1]) k = util.dgemm(buf1.reshape((-1, nphys)).T, buf2.reshape((-1, nphys)), c=k, beta=1) j = lib.unpack_tril(j).reshape(rdm1.shape) k = k.reshape(rdm1.shape) f = self.h1e + j - 0.5 * k return f
def get_ovlp(cell, kpt=np.zeros(3)): '''Get the overlap AO matrix. ''' # Avoid pbcopt's prescreening in the lattice sum, for better accuracy s = cell.pbc_intor('int1e_ovlp', hermi=1, kpts=kpt, pbcopt=lib.c_null_ptr()) cond = np.max(lib.cond(s)) if cond * cell.precision > 1e2: prec = 1e2 / cond rmin = max([cell.bas_rcut(ib, prec) for ib in range(cell.nbas)]) if cell.rcut < rmin: logger.warn(cell, 'Singularity detected in overlap matrix. ' 'Integral accuracy may be not enough.\n ' 'You can adjust cell.precision or cell.rcut to ' 'improve accuracy. Recommended values are\n ' 'cell.precision = %.2g or smaller.\n ' 'cell.rcut = %.4g or larger.', prec, rmin) return s
def nr_e1fill(intor, sh_range, atm, bas, env, aosym='s1', comp=1, ao2mopt=None, out=None): assert(aosym in ('s4', 's2ij', 's2kl', 's1')) c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, order='C') natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) ao_loc = moleintor.make_loc(bas, intor) nao = ao_loc[-1] klsh0, klsh1, nkl = sh_range if aosym in ('s4', 's2ij'): nao_pair = nao * (nao+1) // 2 else: nao_pair = nao * nao if out is None: out = numpy.empty((comp,nkl,nao_pair)) else: out = numpy.ndarray((comp,nkl,nao_pair), buffer=out) if out.size == 0: return out if ao2mopt is not None: cao2mopt = ao2mopt._this cintopt = ao2mopt._cintopt cintor = ao2mopt._intor else: cao2mopt = lib.c_null_ptr() cintor = _fpointer(intor) cintopt = _vhf.make_cintopt(c_atm, c_bas, c_env, intor) fdrv = getattr(libao2mo, 'AO2MOnr_e1fill_drv') fill = _fpointer('AO2MOfill_nr_' + aosym) fdrv(cintor, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(klsh0), ctypes.c_int(klsh1-klsh0), ctypes.c_int(nkl), ctypes.c_int(comp), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cao2mopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) return out
def so_by_shell(mol, shls): '''Spin-orbit coupling ECP in spinor basis i/2 <Pauli_matrix dot l U(r)> ''' li = mol.bas_angular(shls[0]) lj = mol.bas_angular(shls[1]) di = (li * 4 + 2) * mol.bas_nctr(shls[0]) dj = (lj * 4 + 2) * mol.bas_nctr(shls[1]) bas = numpy.vstack((mol._bas, mol._ecpbas)) mol._env[AS_ECPBAS_OFFSET] = len(mol._bas) mol._env[AS_NECPBAS] = len(mol._ecpbas) buf = numpy.empty((di, dj), order='F', dtype=numpy.complex128) cache = numpy.empty(buf.size * 48 + 100000) fn = libecp.ECPso_spinor fn(buf.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int * 2)(di, dj), (ctypes.c_int * 2)(*shls), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p), lib.c_null_ptr(), cache.ctypes.data_as(ctypes.c_void_p)) return buf
def get_fock(rdm1, h1e, eri, maxblk=DF_MAXBLK): # Gets the Fock matrix (MO basis) # Transforms to AO basis and then back to appease pyscf nphys = rdm1.shape[-1] naux = eri.shape[0] j = np.zeros((nphys * (nphys + 1) // 2)) k = np.zeros((nphys, nphys)) rdm1tril = lib.pack_tril(rdm1 + np.tril(rdm1, k=-1)) rargs = (ctypes.c_int(nphys), (ctypes.c_int * 4)(0, nphys, 0, nphys), lib.c_null_ptr(), ctypes.c_int(0)) buf = np.empty((2, maxblk, nphys, nphys)) for s in _get_df_blocks(eri, maxblk): eri1 = eri[s] naux_block = eri1.shape[0] rho = dot(eri1, rdm1tril) j += dot(rho, eri1) buf1 = buf[0, :naux_block] _fdrv(_ftrans, _fmmm, to_ptr(buf1), to_ptr(eri1), to_ptr(rdm1), ctypes.c_int(naux_block), *rargs) buf2 = lib.unpack_tril(eri1, out=buf[1]) k = dgemm(buf1.reshape(-1, nphys).T, buf2.reshape(-1, nphys), c=k, beta=1) j = mpi_reduce(j) k = mpi_reduce(k) j = lib.unpack_tril(j).reshape(rdm1.shape) k = k.reshape(rdm1.shape) f = h1e + j - 0.5 * k return f
def init_cvhf_direct(self, mol, intor, qcondname): '''qcondname can be the function pointer or the name of a C function defined in libcvhf module ''' intor = mol._add_suffix(intor) if intor == self._intor: cintopt = self._cintopt else: cintopt = lib.c_null_ptr() ao_loc = make_loc(mol._bas, intor) if isinstance(qcondname, ctypes._CFuncPtr): fsetqcond = qcondname else: fsetqcond = getattr(libcvhf, qcondname) natm = ctypes.c_int(mol.natm) nbas = ctypes.c_int(mol.nbas) fsetqcond(self._this, getattr(libcvhf, intor), cintopt, ao_loc.ctypes.data_as(ctypes.c_void_p), mol._atm.ctypes.data_as(ctypes.c_void_p), natm, mol._bas.ctypes.data_as(ctypes.c_void_p), nbas, mol._env.ctypes.data_as(ctypes.c_void_p))
def make_cintopt(atm, bas, env, intor): intor = intor.replace('_sph', '').replace('_cart', '').replace('_spinor', '') c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = c_atm.shape[0] nbas = c_bas.shape[0] cintopt = lib.c_null_ptr() # TODO: call specific ECP optimizers for each intor. if intor[:3] == 'ECP': foptinit = libcgto.ECPscalar_optimizer foptinit(ctypes.byref(cintopt), c_atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), c_bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), c_env.ctypes.data_as(ctypes.c_void_p)) return ctypes.cast(cintopt, _ecpoptHandler) else: foptinit = getattr(libcgto, intor + '_optimizer') foptinit(ctypes.byref(cintopt), c_atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), c_bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), c_env.ctypes.data_as(ctypes.c_void_p)) return ctypes.cast(cintopt, _cintoptHandler)
def make_cintopt(atm, bas, env, intor): intor = intor.replace('_sph','').replace('_cart','').replace('_spinor','') c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = c_atm.shape[0] nbas = c_bas.shape[0] cintopt = lib.c_null_ptr() # TODO: call specific ECP optimizers for each intor. if intor[:3] == 'ECP': foptinit = libcgto.ECPscalar_optimizer foptinit(ctypes.byref(cintopt), c_atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), c_bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), c_env.ctypes.data_as(ctypes.c_void_p)) return ctypes.cast(cintopt, _ecpoptHandler) else: foptinit = getattr(libcgto, intor+'_optimizer') foptinit(ctypes.byref(cintopt), c_atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), c_bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), c_env.ctypes.data_as(ctypes.c_void_p)) return ctypes.cast(cintopt, _cintoptHandler)
def ft_aopair(mol, Gv, shls_slice=None, aosym='s1', b=numpy.eye(3), gxyz=None, Gvbase=None, buf=None, intor='GTO_ft_ovlp', comp=1, verbose=None): r''' FT transform AO pair \int i(r) j(r) exp(-ikr) dr^3 ''' intor = mol._add_suffix(intor) if shls_slice is None: shls_slice = (0, mol.nbas, 0, mol.nbas) nGv = Gv.shape[0] if (gxyz is None or b is None or Gvbase is None # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b-numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), numpy.zeros(3)) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) ao_loc = gto.moleintor.make_loc(mol._bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] if aosym == 's1': if (shls_slice[:2] == shls_slice[2:4] and intor.startswith('GTO_ft_ovlp')): fill = getattr(libcgto, 'GTO_ft_fill_s1hermi') else: fill = getattr(libcgto, 'GTO_ft_fill_s1') shape = (nGv,ni,nj,comp) else: fill = getattr(libcgto, 'GTO_ft_fill_s2') i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nGv,nij,comp) mat = numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=buf) fn = libcgto.GTO_ft_fill_drv intor = getattr(libcgto, intor) eval_gz = getattr(libcgto, eval_gz) fn(intor, eval_gz, fill, mat.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(comp), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), ctypes.c_double(0), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), mol._atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.natm), mol._bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(mol.nbas), mol._env.ctypes.data_as(ctypes.c_void_p)) mat = numpy.rollaxis(mat, -1, 0) if comp == 1: mat = mat[0] return mat
def direct_bindm(intor, aosym, jkdescript, dms, ncomp, atm, bas, env, vhfopt=None, cintopt=None, shls_slice=None): assert(aosym in ('s8', 's4', 's2ij', 's2kl', 's1', 'aa4', 'a4ij', 'a4kl', 'a2ij', 'a2kl')) intor = ascint3(intor) c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) if isinstance(dms, numpy.ndarray) and dms.ndim == 2: dms = dms[numpy.newaxis,:,:] n_dm = len(dms) nao = dms[0].shape[0] dms = [numpy.asarray(dm, order='C') for dm in dms] if isinstance(jkdescript, str): jkdescripts = (jkdescript,) else: jkdescripts = jkdescript njk = len(jkdescripts) assert(njk == n_dm) if vhfopt is None: cintor = _fpointer(intor) cvhfopt = lib.c_null_ptr() else: vhfopt.set_dm(dms, atm, bas, env) cvhfopt = vhfopt._this cintopt = vhfopt._cintopt cintor = getattr(libcvhf, vhfopt._intor) if cintopt is None: cintopt = make_cintopt(c_atm, c_bas, c_env, intor) fdrv = getattr(libcvhf, 'CVHFnr_direct_drv') dotsym = _INTSYMAP[aosym] fdot = _fpointer('CVHFdot_nr'+dotsym) if shls_slice is None: shls_slice = (0, c_bas.shape[0])*4 ao_loc = make_loc(bas, intor) vjk = [] descr_sym = [x.split('->') for x in jkdescripts] fjk = (ctypes.c_void_p*(n_dm))() dmsptr = (ctypes.c_void_p*(n_dm))() vjkptr = (ctypes.c_void_p*(n_dm))() for i, (dmsym, vsym) in enumerate(descr_sym): f1 = _fpointer('CVHFnr%s_%s_%s'%(aosym, dmsym, vsym)) assert(dms[i].shape == get_dims(dmsym, shls_slice, ao_loc)) vshape = (ncomp,) + get_dims(vsym[-2:], shls_slice, ao_loc) vjk.append(numpy.empty(vshape)) dmsptr[i] = dms[i].ctypes.data_as(ctypes.c_void_p) vjkptr[i] = vjk[i].ctypes.data_as(ctypes.c_void_p) fjk[i] = f1 shls_slice = (ctypes.c_int*8)(*shls_slice) fdrv(cintor, fdot, fjk, dmsptr, vjkptr, ctypes.c_int(n_dm), ctypes.c_int(ncomp), shls_slice, ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cvhfopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) if ncomp == 1: vjk = [v.reshape(v.shape[1:]) for v in vjk] if isinstance(jkdescript, str): vjk = vjk[0] return vjk
def gen_partition(mol, atom_grids_tab, radii_adjust=None, atomic_radii=radi.BRAGG_RADII, becke_scheme=original_becke): '''Generate the mesh grid coordinates and weights for DFT numerical integration. We can change radii_adjust, becke_scheme functions to generate different meshgrid. Returns: grid_coord and grid_weight arrays. grid_coord array has shape (N,3); weight 1D array has N elements. ''' if callable(radii_adjust) and atomic_radii is not None: f_radii_adjust = radii_adjust(mol, atomic_radii) else: f_radii_adjust = None atm_coords = numpy.asarray(mol.atom_coords() , order='C') atm_dist = gto.inter_distance(mol) if (becke_scheme is original_becke and (radii_adjust is radi.treutler_atomic_radii_adjust or radii_adjust is radi.becke_atomic_radii_adjust or f_radii_adjust is None)): if f_radii_adjust is None: p_radii_table = lib.c_null_ptr() else: f_radii_table = numpy.asarray([f_radii_adjust(i, j, 0) for i in range(mol.natm) for j in range(mol.natm)]) p_radii_table = f_radii_table.ctypes.data_as(ctypes.c_void_p) def gen_grid_partition(coords): coords = numpy.asarray(coords, order='F') ngrids = coords.shape[0] pbecke = numpy.empty((mol.natm,ngrids)) libdft.VXCgen_grid(pbecke.ctypes.data_as(ctypes.c_void_p), coords.ctypes.data_as(ctypes.c_void_p), atm_coords.ctypes.data_as(ctypes.c_void_p), p_radii_table, ctypes.c_int(mol.natm), ctypes.c_int(ngrids)) return pbecke else: def gen_grid_partition(coords): ngrids = coords.shape[0] grid_dist = numpy.empty((mol.natm,ngrids)) for ia in range(mol.natm): dc = coords - atm_coords[ia] grid_dist[ia] = numpy.sqrt(numpy.einsum('ij,ij->i',dc,dc)) pbecke = numpy.ones((mol.natm,ngrids)) for i in range(mol.natm): for j in range(i): g = 1/atm_dist[i,j] * (grid_dist[i]-grid_dist[j]) if f_radii_adjust is not None: g = f_radii_adjust(i, j, g) g = becke_scheme(g) pbecke[i] *= .5 * (1-g) pbecke[j] *= .5 * (1+g) return pbecke coords_all = [] weights_all = [] for ia in range(mol.natm): coords, vol = atom_grids_tab[mol.atom_symbol(ia)] coords = coords + atm_coords[ia] pbecke = gen_grid_partition(coords) weights = vol * pbecke[ia] * (1./pbecke.sum(axis=0)) coords_all.append(coords) weights_all.append(weights) return numpy.vstack(coords_all), numpy.hstack(weights_all)
def intor_cross(intor, cell1, cell2, comp=1, hermi=0, kpts=None, kpt=None): r'''1-electron integrals from two cells like .. math:: \langle \mu | intor | \nu \rangle, \mu \in cell1, \nu \in cell2 ''' if kpts is None: if kpt is not None: kpts_lst = np.reshape(kpt, (1,3)) else: kpts_lst = np.zeros((1,3)) else: kpts_lst = np.reshape(kpts, (-1,3)) nkpts = len(kpts_lst) atm, bas, env = conc_env(cell1._atm, cell1._bas, cell1._env, cell2._atm, cell2._bas, cell2._env) atm = np.asarray(atm, dtype=np.int32) bas = np.asarray(bas, dtype=np.int32) env = np.asarray(env, dtype=np.double) natm = len(atm) nbas = len(bas) shls_slice = (0, cell1.nbas, cell1.nbas, nbas) ao_loc = moleintor.make_loc(bas, intor) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] out = [np.zeros((ni,nj,comp), order='F', dtype=np.complex128) for k in range(nkpts)] out_ptrs = (ctypes.c_void_p*nkpts)( *[x.ctypes.data_as(ctypes.c_void_p) for x in out]) if hermi == 0: aosym = 's1' else: aosym = 's2' if '2c2e' in intor: fill = getattr(libpbc, 'PBCnr2c2e_fill_'+aosym) else: assert('2e' not in intor) fill = getattr(libpbc, 'PBCnr2c_fill_'+aosym) fintor = moleintor._fpointer(intor) intopt = lib.c_null_ptr() nimgs = np.max((cell1.nimgs, cell2.nimgs), axis=0) Ls = np.asarray(cell1.get_lattice_Ls(nimgs), order='C') expLk = np.asarray(np.exp(1j*np.dot(Ls, kpts_lst.T)), order='C') xyz = np.asarray(cell2.atom_coords(), order='C') ptr_coords = np.asarray(atm[cell1.natm:,mole.PTR_COORD], dtype=np.int32, order='C') drv = libpbc.PBCnr2c_drv drv(fintor, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coords.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell2.natm), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), expLk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), (ctypes.c_int*4)(*(shls_slice[:4])), ao_loc.ctypes.data_as(ctypes.c_void_p), intopt, atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nbas), env.ctypes.data_as(ctypes.c_void_p)) def trans(out): out = out.transpose(2,0,1) if hermi == lib.HERMITIAN: # GTOint2c fills the upper triangular of the F-order array. idx = np.triu_indices(ni) for i in range(comp): out[i,idx[1],idx[0]] = out[i,idx[0],idx[1]].conj() elif hermi == lib.ANTIHERMI: idx = np.triu_indices(ni) for i in range(comp): out[i,idx[1],idx[0]] = -out[i,idx[0],idx[1]].conj() elif hermi == lib.SYMMETRIC: idx = np.triu_indices(ni) for i in range(comp): out[i,idx[1],idx[0]] = out[i,idx[0],idx[1]] if comp == 1: out = out.reshape(ni,nj) return out for k, kpt in enumerate(kpts_lst): if abs(kpt).sum() < 1e-9: # gamma_point out[k] = np.asarray(trans(out[k].real), order='C') else: out[k] = np.asarray(trans(out[k]), order='C') if kpts is None or np.shape(kpts) == (3,): # A single k-point out = out[0] return out
def _ft_aopair_kpts(cell, Gv, shls_slice=None, aosym='s1', b=None, gxyz=None, Gvbase=None, q=numpy.zeros(3), kptjs=numpy.zeros((1,3)), intor='GTO_ft_ovlp', comp=1, out=None): r''' FT transform AO pair \sum_T exp(-i k_j * T) \int exp(-i(G+q)r) i(r) j(r-T) dr^3 The return array holds the AO pair corresponding to the kpoints given by kptjs ''' intor = cell._add_suffix(intor) q = numpy.reshape(q, 3) kptjs = numpy.asarray(kptjs, order='C').reshape(-1,3) Gv = numpy.asarray(Gv, order='C').reshape(-1,3) nGv = Gv.shape[0] GvT = numpy.asarray(Gv.T, order='C') GvT += q.reshape(-1,1) if (gxyz is None or b is None or Gvbase is None or (abs(q).sum() > 1e-9) # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): p_gxyzT = lib.c_null_ptr() p_mesh = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: if abs(b-numpy.diag(b.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_orth' else: eval_gz = 'GTO_Gv_nonorth' gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), q) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_mesh = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) Ls = cell.get_lattice_Ls() expkL = numpy.exp(1j * numpy.dot(kptjs, Ls.T)) atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = gto.moleintor.make_loc(bas, intor) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2) else: shls_slice = (shls_slice[0], shls_slice[1], cell.nbas+shls_slice[2], cell.nbas+shls_slice[3]) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] nkpts = len(kptjs) nimgs = len(Ls) shape = (nkpts, comp, ni, nj, nGv) # Theoretically, hermitian symmetry can be also found for kpti == kptj: # f_ji(G) = \int f_ji exp(-iGr) = \int f_ij^* exp(-iGr) = [f_ij(-G)]^* # hermi operation needs reordering the axis-0. It is inefficient. if aosym == 's1hermi': # Symmetry for Gamma point assert(is_zero(q) and is_zero(kptjs) and ni == nj) elif aosym == 's2': i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nkpts, comp, nij, nGv) drv = libpbc.PBC_ft_latsum_drv cintor = getattr(libpbc, intor) eval_gz = getattr(libpbc, eval_gz) if nkpts == 1: fill = getattr(libpbc, 'PBC_ft_fill_nk1'+aosym) else: fill = getattr(libpbc, 'PBC_ft_fill_k'+aosym) out = numpy.ndarray(shape, dtype=numpy.complex128, buffer=out) drv(cintor, eval_gz, fill, out.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nkpts), ctypes.c_int(comp), ctypes.c_int(nimgs), Ls.ctypes.data_as(ctypes.c_void_p), expkL.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_mesh, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas), env.ctypes.data_as(ctypes.c_void_p)) if aosym == 's1hermi': for i in range(1,ni): out[:,:,:i,i] = out[:,:,i,:i] out = numpy.rollaxis(out, -1, 2) if comp == 1: out = out[:,0] return out
def _ft_aopair_kpts(cell, Gv, shls_slice=None, aosym='s1', invh=None, gxyz=None, gs=None, kpt=numpy.zeros(3), kptjs=numpy.zeros((2,3)), out=None): ''' FT transform AO pair \int i(r) j(r) exp(-ikr) dr^3 for all kpt = kptj - kpti. The return list holds the AO pair array corresponding to the kpoints given by kptjs ''' kpt = numpy.reshape(kpt, 3) kptjs = numpy.asarray(kptjs, order='C').reshape(-1,3) nGv = Gv.shape[0] Gv = Gv + kpt # kptis = kptjs - kpt if (gxyz is None or invh is None or gs is None or (abs(kpt).sum() > 1e-9)): GvT = numpy.asarray(Gv.T, order='C') p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_invh = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: GvT = numpy.asarray(Gv.T, order='C') gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*gs) # Guess what type of eval_gz to use if isinstance(invh, numpy.ndarray) and invh.shape == (3,3): p_invh = invh.ctypes.data_as(ctypes.c_void_p) if abs(invh-numpy.diag(invh.diagonal())).sum() < 1e-8: eval_gz = 'GTO_Gv_uniform_orth' else: eval_gz = 'GTO_Gv_uniform_nonorth' else: invh = numpy.hstack(invh) p_invh = invh.ctypes.data_as(ctypes.c_void_p) eval_gz = 'GTO_Gv_nonuniform_orth' drv = libpbc.PBC_ft_latsum_kpts intor = getattr(libpbc, 'GTO_ft_ovlp_sph') eval_gz = getattr(libpbc, eval_gz) # make copy of atm,bas,env because they are modified in the lattice sum atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = cell.ao_loc_nr() nao = ao_loc[cell.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc[:-1], ao_loc+nao)), dtype=numpy.int32) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2) else: shls_slice = (shls_slice[0], shls_slice[1], cell.nbas+shls_slice[2], cell.nbas+shls_slice[3]) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] shape = (nGv, ni, nj) fill = getattr(libpbc, 'PBC_ft_fill_'+aosym) if aosym == 's1hermi': # Symmetry for Gamma point assert(abs(kpt).sum() < 1e-9 and abs(kptjs).sum() < 1e-9) elif aosym == 's2': i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nGv, nij) if out is None: out = [numpy.zeros(shape, order='F', dtype=numpy.complex128) for k in range(len(kptjs))] else: out = [numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=out[k]) for k in range(len(kptjs))] out_ptrs = (ctypes.c_void_p*len(out))( *[x.ctypes.data_as(ctypes.c_void_p) for x in out]) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coord = numpy.asarray(atm[cell.natm:,gto.PTR_COORD], dtype=numpy.int32, order='C') Ls = numpy.asarray(cell.get_lattice_Ls(cell.nimgs), order='C') exp_Lk = numpy.einsum('ik,jk->ij', Ls, kptjs) exp_Lk = numpy.exp(1j * numpy.asarray(exp_Lk, order='C')) drv(intor, eval_gz, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coord.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(xyz)), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), exp_Lk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(kptjs)), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), GvT.ctypes.data_as(ctypes.c_void_p), p_invh, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm*2), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas*2), env.ctypes.data_as(ctypes.c_void_p)) if aosym == 's1hermi': for mat in out: for i in range(1,ni): mat[:,:i,i] = mat[:,i,:i] return out
mol.basis = "cc-pvdz" mol.build() rhf = scf.RHF(mol) rhf.scf() nao = mol.nao_nr() npair = nao * (nao + 1) // 2 c_atm = numpy.array(mol._atm, dtype=numpy.int32) c_bas = numpy.array(mol._bas, dtype=numpy.int32) c_env = numpy.array(mol._env) natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) cvhfopt = lib.c_null_ptr() cintopt = lib.c_null_ptr() ao_loc = numpy.asarray(mol.ao_loc_nr(), dtype=numpy.int32) # for each dm1, call namejk def runjk(dm1, ncomp, intorname, filldot, *namejk): fdrv = getattr(libcvhf2, "CVHFnr_direct_drv") intor = getattr(libcvhf2, intorname) fdot = getattr(libcvhf2._handle, filldot) njk = len(namejk) if dm1.ndim == 2: n_dm = 1 dm1 = (dm1,) else: n_dm = dm1.shape[0]
def get_jk(dfobj, dm, hermi=1, vhfopt=None, with_j=True, with_k=True): t0 = t1 = (time.clock(), time.time()) log = logger.Logger(dfobj.stdout, dfobj.verbose) assert(with_j or with_k) fmmm = _ao2mo.libao2mo.AO2MOmmm_bra_nr_s2 fdrv = _ao2mo.libao2mo.AO2MOnr_e2_drv ftrans = _ao2mo.libao2mo.AO2MOtranse2_nr_s2 null = lib.c_null_ptr() dms = numpy.asarray(dm) dm_shape = dms.shape nao = dm_shape[-1] dms = dms.reshape(-1,nao,nao) nset = dms.shape[0] vj = [0] * nset vk = [0] * nset if not with_k: dmtril = [] idx = numpy.arange(nao) for k in range(nset): dm = lib.pack_tril(dms[k]+dms[k].T) dm[idx*(idx+1)//2+idx] *= .5 dmtril.append(dm) for eri1 in dfobj.loop(): naux, nao_pair = eri1.shape for k in range(nset): rho = numpy.einsum('px,x->p', eri1, dmtril[k]) vj[k] += numpy.einsum('p,px->x', rho, eri1) elif getattr(dm, 'mo_coeff', None) is not None: #TODO: test whether dm.mo_coeff matching dm mo_coeff = numpy.asarray(dm.mo_coeff, order='F') mo_occ = numpy.asarray(dm.mo_occ) nmo = mo_occ.shape[-1] mo_coeff = mo_coeff.reshape(-1,nao,nmo) mo_occ = mo_occ.reshape(-1,nmo) if mo_occ.shape[0] * 2 == nset: # handle ROHF DM mo_coeff = numpy.vstack((mo_coeff, mo_coeff)) mo_occa = numpy.array(mo_occ> 0, dtype=numpy.double) mo_occb = numpy.array(mo_occ==2, dtype=numpy.double) assert(mo_occa.sum() + mo_occb.sum() == mo_occ.sum()) mo_occ = numpy.vstack((mo_occa, mo_occb)) dmtril = [] orbo = [] for k in range(nset): if with_j: dmtril.append(lib.pack_tril(dms[k]+dms[k].T)) i = numpy.arange(nao) dmtril[k][i*(i+1)//2+i] *= .5 c = numpy.einsum('pi,i->pi', mo_coeff[k][:,mo_occ[k]>0], numpy.sqrt(mo_occ[k][mo_occ[k]>0])) orbo.append(numpy.asarray(c, order='F')) buf = numpy.empty((dfobj.blockdim*nao,nao)) for eri1 in dfobj.loop(): naux, nao_pair = eri1.shape assert(nao_pair == nao*(nao+1)//2) for k in range(nset): if with_j: rho = numpy.einsum('px,x->p', eri1, dmtril[k]) vj[k] += numpy.einsum('p,px->x', rho, eri1) nocc = orbo[k].shape[1] if nocc > 0: buf1 = buf[:naux*nocc] fdrv(ftrans, fmmm, buf1.ctypes.data_as(ctypes.c_void_p), eri1.ctypes.data_as(ctypes.c_void_p), orbo[k].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(naux), ctypes.c_int(nao), (ctypes.c_int*4)(0, nocc, 0, nao), null, ctypes.c_int(0)) vk[k] += lib.dot(buf1.T, buf1) t1 = log.timer_debug1('jk', *t1) else: #:vk = numpy.einsum('pij,jk->pki', cderi, dm) #:vk = numpy.einsum('pki,pkj->ij', cderi, vk) rargs = (ctypes.c_int(nao), (ctypes.c_int*4)(0, nao, 0, nao), null, ctypes.c_int(0)) dms = [numpy.asarray(x, order='F') for x in dms] buf = numpy.empty((2,dfobj.blockdim,nao,nao)) for eri1 in dfobj.loop(): naux, nao_pair = eri1.shape for k in range(nset): buf1 = buf[0,:naux] fdrv(ftrans, fmmm, buf1.ctypes.data_as(ctypes.c_void_p), eri1.ctypes.data_as(ctypes.c_void_p), dms[k].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(naux), *rargs) if with_j: rho = numpy.einsum('kii->k', buf1) vj[k] += numpy.einsum('p,px->x', rho, eri1) buf2 = lib.unpack_tril(eri1, out=buf[1]) vk[k] += lib.dot(buf1.reshape(-1,nao).T, buf2.reshape(-1,nao)) t1 = log.timer_debug1('jk', *t1) if with_j: vj = lib.unpack_tril(vj, 1).reshape(dm_shape) if with_k: vk = numpy.asarray(vk).reshape(dm_shape) logger.timer(dfobj, 'vj and vk', *t0) return vj, vk
def _ft_aopair_kpts(cell, Gv, shls_slice=None, aosym='s1', b=None, gxyz=None, Gvbase=None, kpt=numpy.zeros(3), kptjs=numpy.zeros((2,3)), out=None): ''' FT transform AO pair \int i(r) j(r) exp(-ikr) dr^3 for all kpt = kptj - kpti. The return list holds the AO pair array corresponding to the kpoints given by kptjs ''' kpt = numpy.reshape(kpt, 3) # kptis = kptjs - kpt kptjs = numpy.asarray(kptjs, order='C').reshape(-1,3) nGv = Gv.shape[0] GvT = numpy.asarray(Gv.T, order='C') GvT += kpt.reshape(-1,1) if (gxyz is None or b is None or Gvbase is None or (abs(kpt).sum() > 1e-9) # backward compatibility for pyscf-1.2, in which the argument Gvbase is gs or (Gvbase is not None and isinstance(Gvbase[0], (int, numpy.integer)))): p_gxyzT = lib.c_null_ptr() p_gs = (ctypes.c_int*3)(0,0,0) p_b = (ctypes.c_double*1)(0) eval_gz = 'GTO_Gv_general' else: gxyzT = numpy.asarray(gxyz.T, order='C', dtype=numpy.int32) p_gxyzT = gxyzT.ctypes.data_as(ctypes.c_void_p) b = numpy.hstack((b.ravel(), kpt) + Gvbase) p_b = b.ctypes.data_as(ctypes.c_void_p) p_gs = (ctypes.c_int*3)(*[len(x) for x in Gvbase]) eval_gz = 'GTO_Gv_cubic' drv = libpbc.PBC_ft_latsum_kpts intor = getattr(libpbc, 'GTO_ft_ovlp_sph') eval_gz = getattr(libpbc, eval_gz) # make copy of atm,bas,env because they are modified in the lattice sum atm, bas, env = gto.conc_env(cell._atm, cell._bas, cell._env, cell._atm, cell._bas, cell._env) ao_loc = cell.ao_loc_nr() nao = ao_loc[cell.nbas] ao_loc = numpy.asarray(numpy.hstack((ao_loc[:-1], ao_loc+nao)), dtype=numpy.int32) if shls_slice is None: shls_slice = (0, cell.nbas, cell.nbas, cell.nbas*2) else: shls_slice = (shls_slice[0], shls_slice[1], cell.nbas+shls_slice[2], cell.nbas+shls_slice[3]) ni = ao_loc[shls_slice[1]] - ao_loc[shls_slice[0]] nj = ao_loc[shls_slice[3]] - ao_loc[shls_slice[2]] shape = (nGv, ni, nj) fill = getattr(libpbc, 'PBC_ft_fill_'+aosym) # Theoretically, hermitian symmetry can be also found for kpti == kptj: # f_ji(G) = \int f_ji exp(-iGr) = \int f_ij^* exp(-iGr) = [f_ij(-G)]^* # The hermi operation needs reordering the axis-0. It is inefficient. if aosym == 's1hermi': # Symmetry for Gamma point assert(abs(kpt).sum() < 1e-9 and abs(kptjs).sum() < 1e-9) elif aosym == 's2': i0 = ao_loc[shls_slice[0]] i1 = ao_loc[shls_slice[1]] nij = i1*(i1+1)//2 - i0*(i0+1)//2 shape = (nGv, nij) if out is None: out = [numpy.zeros(shape, order='F', dtype=numpy.complex128) for k in range(len(kptjs))] else: out = [numpy.ndarray(shape, order='F', dtype=numpy.complex128, buffer=out[k]) for k in range(len(kptjs))] out_ptrs = (ctypes.c_void_p*len(out))( *[x.ctypes.data_as(ctypes.c_void_p) for x in out]) xyz = numpy.asarray(cell.atom_coords(), order='C') ptr_coord = numpy.asarray(atm[cell.natm:,gto.PTR_COORD], dtype=numpy.int32, order='C') Ls = cell.get_lattice_Ls() exp_Lk = numpy.einsum('ik,jk->ij', Ls, kptjs) exp_Lk = numpy.exp(1j * numpy.asarray(exp_Lk, order='C')) drv(intor, eval_gz, fill, out_ptrs, xyz.ctypes.data_as(ctypes.c_void_p), ptr_coord.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(xyz)), Ls.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(Ls)), exp_Lk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(kptjs)), (ctypes.c_int*4)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), GvT.ctypes.data_as(ctypes.c_void_p), p_b, p_gxyzT, p_gs, ctypes.c_int(nGv), atm.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.natm*2), bas.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(cell.nbas*2), env.ctypes.data_as(ctypes.c_void_p)) if aosym == 's1hermi': for mat in out: for i in range(1,ni): mat[:,:i,i] = mat[:,i,:i] return out
def direct(dms, atm, bas, env, vhfopt=None, hermi=0, cart=False): c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) if isinstance(dms, numpy.ndarray) and dms.ndim == 2: dms = dms[numpy.newaxis,:,:] n_dm = len(dms) nao = dms[0].shape[0] dms = numpy.asarray(dms, order='C') if vhfopt is None: if cart: intor = 'int2e_cart' else: intor = 'int2e_sph' cintopt = make_cintopt(c_atm, c_bas, c_env, intor) cvhfopt = lib.c_null_ptr() else: vhfopt.set_dm(dms, atm, bas, env) cvhfopt = vhfopt._this cintopt = vhfopt._cintopt intor = vhfopt._intor cintor = _fpointer(intor) fdrv = getattr(libcvhf, 'CVHFnr_direct_drv') fdot = _fpointer('CVHFdot_nrs8') fvj = _fpointer('CVHFnrs8_ji_s2kl') if hermi == 1: fvk = _fpointer('CVHFnrs8_li_s2kj') else: fvk = _fpointer('CVHFnrs8_li_s1kj') vjk = numpy.empty((2,n_dm,nao,nao)) fjk = (ctypes.c_void_p*(2*n_dm))() dmsptr = (ctypes.c_void_p*(2*n_dm))() vjkptr = (ctypes.c_void_p*(2*n_dm))() for i in range(n_dm): dmsptr[i] = dms[i].ctypes.data_as(ctypes.c_void_p) vjkptr[i] = vjk[0,i].ctypes.data_as(ctypes.c_void_p) fjk[i] = fvj for i in range(n_dm): dmsptr[n_dm+i] = dms[i].ctypes.data_as(ctypes.c_void_p) vjkptr[n_dm+i] = vjk[1,i].ctypes.data_as(ctypes.c_void_p) fjk[n_dm+i] = fvk shls_slice = (ctypes.c_int*8)(*([0, c_bas.shape[0]]*4)) ao_loc = make_loc(bas, intor) fdrv(cintor, fdot, fjk, dmsptr, vjkptr, ctypes.c_int(n_dm*2), ctypes.c_int(1), shls_slice, ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cvhfopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) # vj must be symmetric for idm in range(n_dm): vjk[0,idm] = lib.hermi_triu(vjk[0,idm], 1) if hermi != 0: # vk depends for idm in range(n_dm): vjk[1,idm] = lib.hermi_triu(vjk[1,idm], hermi) if n_dm == 1: vjk = vjk.reshape(2,nao,nao) return vjk
def rdirect_bindm(intor, aosym, jkdescript, dms, ncomp, atm, bas, env, vhfopt=None, cintopt=None, shls_slice=None): assert(aosym in ('s8', 's4', 's2ij', 's2kl', 's1', 'a4ij', 'a4kl', 'a2ij', 'a2kl')) intor = ascint3(intor) c_atm = numpy.asarray(atm, dtype=numpy.int32, order='C') c_bas = numpy.asarray(bas, dtype=numpy.int32, order='C') c_env = numpy.asarray(env, dtype=numpy.double, order='C') natm = ctypes.c_int(c_atm.shape[0]) nbas = ctypes.c_int(c_bas.shape[0]) if isinstance(dms, numpy.ndarray) and dms.ndim == 2: dms = dms[numpy.newaxis,:,:] n_dm = len(dms) nao = dms[0].shape[0] dms = numpy.asarray(dms, order='C', dtype=numpy.complex128) if isinstance(jkdescript, str): jkdescript = (jkdescript,) njk = len(jkdescript) assert(njk == n_dm) if vhfopt is None: cintor = _fpointer(intor) cvhfopt = lib.c_null_ptr() else: vhfopt.set_dm(dms, atm, bas, env) cvhfopt = vhfopt._this cintopt = vhfopt._cintopt cintor = getattr(libcvhf, vhfopt._intor) if cintopt is None: cintopt = make_cintopt(c_atm, c_bas, c_env, intor) fdrv = getattr(libcvhf, 'CVHFr_direct_drv') dotsym = _INTSYMAP[aosym] fdot = _fpointer('CVHFdot_r'+dotsym) if shls_slice is None: shls_slice = (0, c_bas.shape[0])*4 else: raise NotImplementedError ao_loc = make_loc(bas, intor) unpackas = _INTUNPACKMAP_R[aosym] descr_sym = [x.split('->') for x in jkdescript] fjk = (ctypes.c_void_p*(n_dm))() dm1 = (ctypes.c_void_p*(n_dm))() for i, (dmsym, vsym) in enumerate(descr_sym): f1 = _fpointer('CVHFr%s_%s_%s'%(unpackas, dmsym, vsym)) dm1[i] = dms[i].ctypes.data_as(ctypes.c_void_p) fjk[i] = f1 vjk = numpy.empty((njk,ncomp,nao,nao), dtype=numpy.complex) fdrv(cintor, fdot, fjk, dm1, vjk.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(n_dm), ctypes.c_int(ncomp), (ctypes.c_int*8)(*shls_slice), ao_loc.ctypes.data_as(ctypes.c_void_p), cintopt, cvhfopt, c_atm.ctypes.data_as(ctypes.c_void_p), natm, c_bas.ctypes.data_as(ctypes.c_void_p), nbas, c_env.ctypes.data_as(ctypes.c_void_p)) if ncomp == 1: vjk = vjk.reshape(njk,nao,nao) if njk == 1: vjk = vjk.reshape(vjk.shape[1:]) return vjk
def get_becke_grids(cell, atom_grid={}, radi_method=dft.radi.gauss_chebyshev, level=3, prune=nwchem_prune): '''real-space grids using Becke scheme Args: cell : instance of :class:`Cell` Returns: coords : (N, 3) ndarray The real-space grid point coordinates. weights : (N) ndarray ''' # When low_dim_ft_type is set, pbc_eval_gto treats the 2D system as a 3D system. # To get the correct particle number in numint module, the atomic grids needs to # be consistent with the treatment in pbc_eval_gto (see issue 164). if cell.dimension < 2 or cell.low_dim_ft_type == 'inf_vacuum': dimension = cell.dimension else: dimension = 3 Ls = cell.get_lattice_Ls(dimension=dimension) atm_coords = Ls.reshape(-1,1,3) + cell.atom_coords() atom_grids_tab = gen_atomic_grids(cell, atom_grid, radi_method, level, prune) coords_all = [] weights_all = [] b = cell.reciprocal_vectors(norm_to=1) supatm_idx = [] k = 0 for iL, L in enumerate(Ls): for ia in range(cell.natm): coords, vol = atom_grids_tab[cell.atom_symbol(ia)] coords = coords + atm_coords[iL,ia] # search for grids in unit cell c = b.dot(coords.T).round(8) mask = np.ones(c.shape[1], dtype=bool) if dimension >= 1: mask &= (c[0]>=0) & (c[0]<=1) if dimension >= 2: mask &= (c[1]>=0) & (c[1]<=1) if dimension == 3: mask &= (c[2]>=0) & (c[2]<=1) vol = vol[mask] if vol.size > 8: c = c[:,mask] if dimension >= 1: vol[c[0]==0] *= .5 vol[c[0]==1] *= .5 if dimension >= 2: vol[c[1]==0] *= .5 vol[c[1]==1] *= .5 if dimension == 3: vol[c[2]==0] *= .5 vol[c[2]==1] *= .5 coords = coords[mask] coords_all.append(coords) weights_all.append(vol) supatm_idx.append(k) k += 1 offs = np.append(0, np.cumsum([w.size for w in weights_all])) coords_all = np.vstack(coords_all) weights_all = np.hstack(weights_all) atm_coords = np.asarray(atm_coords.reshape(-1,3)[supatm_idx], order='C') sup_natm = len(atm_coords) p_radii_table = lib.c_null_ptr() fn = dft.gen_grid.libdft.VXCgen_grid ngrids = weights_all.size max_memory = cell.max_memory - lib.current_memory()[0] blocksize = min(ngrids, max(2000, int(max_memory*1e6/8 / sup_natm))) displs = lib.misc._blocksize_partition(offs, blocksize) for n0, n1 in zip(displs[:-1], displs[1:]): p0, p1 = offs[n0], offs[n1] pbecke = np.empty((sup_natm,p1-p0)) coords = np.asarray(coords_all[p0:p1], order='F') fn(pbecke.ctypes.data_as(ctypes.c_void_p), coords.ctypes.data_as(ctypes.c_void_p), atm_coords.ctypes.data_as(ctypes.c_void_p), p_radii_table, ctypes.c_int(sup_natm), ctypes.c_int(p1-p0)) weights_all[p0:p1] /= pbecke.sum(axis=0) for ia in range(n0, n1): i0, i1 = offs[ia], offs[ia+1] weights_all[i0:i1] *= pbecke[ia,i0-p0:i1-p0] return coords_all, weights_all
def get_jk(dfobj, dms, hermi=1, vhfopt=None, with_j=True, with_k=True): t0 = t1 = (time.clock(), time.time()) log = logger.Logger(dfobj.stdout, dfobj.verbose) if len(dms) == 0: return [], [] elif isinstance(dms, numpy.ndarray) and dms.ndim == 2: nset = 1 dms = [dms] is_single_dm = True else: nset = len(dms) is_single_dm = False nao = dms[0].shape[0] fmmm = _ao2mo.libao2mo.AO2MOmmm_bra_nr_s2 fdrv = _ao2mo.libao2mo.AO2MOnr_e2_drv ftrans = _ao2mo.libao2mo.AO2MOtranse2_nr_s2 vj = numpy.zeros((nset,nao,nao)) vk = numpy.zeros((nset,nao,nao)) null = lib.c_null_ptr() #:vj = reduce(numpy.dot, (cderi.reshape(-1,nao*nao), dm.reshape(-1), #: cderi.reshape(-1,nao*nao))).reshape(nao,nao) if hermi == 1: # and numpy.einsum('ij,ij->', dm, ovlp) > 0.1 # I cannot assume dm is positive definite because it might be the density # matrix difference when the mf.direct_scf flag is set. dmtril = [] cpos = [] cneg = [] for k, dm in enumerate(dms): if with_j: dmtril.append(lib.pack_tril(dm+dm.T)) i = numpy.arange(nao) dmtril[k][i*(i+1)//2+i] *= .5 if with_k: e, c = scipy.linalg.eigh(dm) pos = e > OCCDROP neg = e < -OCCDROP #:vk = numpy.einsum('pij,jk->kpi', cderi, c[:,abs(e)>OCCDROP]) #:vk = numpy.einsum('kpi,kpj->ij', vk, vk) tmp = numpy.einsum('ij,j->ij', c[:,pos], numpy.sqrt(e[pos])) cpos.append(numpy.asarray(tmp, order='F')) tmp = numpy.einsum('ij,j->ij', c[:,neg], numpy.sqrt(-e[neg])) cneg.append(numpy.asarray(tmp, order='F')) buf = numpy.empty((dfobj.blockdim*nao,nao)) for eri1 in dfobj.loop(): naux, nao_pair = eri1.shape assert(nao_pair == nao*(nao+1)//2) for k in range(nset): if with_j: buf1 = reduce(numpy.dot, (eri1, dmtril[k], eri1)) vj[k] += lib.unpack_tril(buf1, hermi) if with_k and cpos[k].shape[1] > 0: buf1 = buf[:naux*cpos[k].shape[1]] fdrv(ftrans, fmmm, buf1.ctypes.data_as(ctypes.c_void_p), eri1.ctypes.data_as(ctypes.c_void_p), cpos[k].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(naux), ctypes.c_int(nao), (ctypes.c_int*4)(0, cpos[k].shape[1], 0, 0), null, ctypes.c_int(0)) vk[k] += lib.dot(buf1.T, buf1) if with_k and cneg[k].shape[1] > 0: buf1 = buf[:naux*cneg[k].shape[1]] fdrv(ftrans, fmmm, buf1.ctypes.data_as(ctypes.c_void_p), eri1.ctypes.data_as(ctypes.c_void_p), cneg[k].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(naux), ctypes.c_int(nao), (ctypes.c_int*4)(0, cneg[k].shape[1], 0, 0), null, ctypes.c_int(0)) vk[k] -= lib.dot(buf1.T, buf1) t1 = log.timer_debug1('jk', *t1) else: #:vk = numpy.einsum('pij,jk->pki', cderi, dm) #:vk = numpy.einsum('pki,pkj->ij', cderi, vk) rargs = (ctypes.c_int(nao), (ctypes.c_int*4)(0, nao, 0, 0), null, ctypes.c_int(0)) dms = [numpy.asarray(dm, order='F') for dm in dms] buf = numpy.empty((2,dfobj.blockdim,nao,nao)) for eri1 in dfobj.loop(): naux, nao_pair = eri1.shape for k in range(nset): buf1 = buf[0,:naux] fdrv(ftrans, fmmm, buf1.ctypes.data_as(ctypes.c_void_p), eri1.ctypes.data_as(ctypes.c_void_p), dms[k].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(naux), *rargs) rho = numpy.einsum('kii->k', buf1) vj[k] += lib.unpack_tril(numpy.dot(rho, eri1), 1) if with_k: buf2 = lib.unpack_tril(eri1, out=buf[1]) vk[k] += lib.dot(buf1.reshape(-1,nao).T, buf2.reshape(-1,nao)) t1 = log.timer_debug1('jk', *t1) if is_single_dm: vj = vj[0] vk = vk[0] logger.timer(dfobj, 'vj and vk', *t0) return vj, vk