def general(mydf, mo_coeffs, kpts=None, compact=True): if isinstance(mo_coeffs, numpy.ndarray) and mo_coeffs.ndim == 2: mo_coeffs = (mo_coeffs,) * 4 eri = mydf.get_eri(kpts) #################### # gamma point, the integral is real and with s4 symmetry if eri.dtype == numpy.float64: return ao2mo.general(eri, mo_coeffs, compact=compact) else: mokl, klslice = ao2mo.incore._conc_mos(mo_coeffs[2], mo_coeffs[3], False)[2:] if mokl.dtype == numpy.float64: mokl = mokl + 0j nao = mo_coeffs[0].shape[0] nmoi = mo_coeffs[0].shape[1] nmoj = mo_coeffs[1].shape[1] nmok = mo_coeffs[2].shape[1] nmol = mo_coeffs[3].shape[1] moi = numpy.asarray(mo_coeffs[0], order='F') moj = numpy.asarray(mo_coeffs[1], order='F') tao = [0] ao_loc = None pqkl = _ao2mo.r_e2(eri.reshape(-1,nao**2), mokl, klslice, tao, ao_loc, aosym='s1') pqkl = pqkl.reshape(nao,nao,nmok*nmol) pjkl = numpy.empty((nao,nmoj,nmok*nmol), dtype=numpy.complex128) for i in range(nao): lib.dot(moj.T, pqkl[i], 1, pjkl[i], 0) pqkl = None eri_mo = lib.dot(moi.T.conj(), pjkl.reshape(nao,-1)) return eri_mo.reshape(nmoi*nmoj,-1)
def get_eri(self): nao = self.mol.nao_nr() nao_pair = nao * (nao+1) // 2 ao_eri = numpy.zeros((nao_pair,nao_pair)) for eri1 in self.loop(): lib.dot(eri1.T, eri1, 1, ao_eri, 1) return ao2mo.restore(8, ao_eri, nao)
def get_j_kpts(mf, cell, dm_kpts, kpts, kpt_band=None): coords = gen_grid.gen_uniform_grids(cell) nkpts = len(kpts) ngs = len(coords) dm_kpts = np.asarray(dm_kpts) nao = dm_kpts.shape[-1] ni = numint._KNumInt(kpts) aoR_kpts = ni.eval_ao(cell, coords, kpts) if kpt_band is not None: aoR_kband = numint.eval_ao(cell, coords, kpt_band) dms = dm_kpts.reshape(-1,nkpts,nao,nao) nset = dms.shape[0] vjR = [get_vjR(cell, dms[i], aoR_kpts) for i in range(nset)] if kpt_band is not None: vj_kpts = [cell.vol/ngs * lib.dot(aoR_kband.T.conj()*vjR[i], aoR_kband) for i in range(nset)] if dm_kpts.ndim == 3: # One set of dm_kpts for KRHF vj_kpts = vj_kpts[0] return lib.asarray(vj_kpts) else: vj_kpts = [] for i in range(nset): vj = [cell.vol/ngs * lib.dot(aoR_k.T.conj()*vjR[i], aoR_k) for aoR_k in aoR_kpts] vj_kpts.append(lib.asarray(vj)) return lib.asarray(vj_kpts).reshape(dm_kpts.shape)
def h_op(x): x = self.unpack_uniq_var(x) norb = x.shape[0] #:hx = numpy.einsum('qp,xjj,xjq->pj', x, dip, dip) #:hx+= numpy.einsum('qp,xqq,xjq->pj', x, dip, dip) #:hx+= numpy.einsum('jk,xkk,xkp->pj', x, dip, dip) #:hx+= numpy.einsum('jk,xpp,xkp->pj', x, dip, dip) #:hx+= numpy.einsum('qj,xjq,xjp->pj', x, dip, dip) #:hx+= numpy.einsum('pk,xjp,xkp->pj', x, dip, dip) #:hx-= numpy.einsum('qp,xpp,xjq->pj', x, dip, dip) * 2 #:hx-= numpy.einsum('qp,xjp,xpq->pj', x, dip, dip) * 2 #:hx+= numpy.einsum('qj,xjp,xjq->pj', x, dip, dip) #:hx+= numpy.einsum('pk,xkp,xjp->pj', x, dip, dip) #:hx-= numpy.einsum('jk,xjj,xkp->pj', x, dip, dip) * 2 #:hx-= numpy.einsum('jk,xkj,xjp->pj', x, dip, dip) * 2 #:return -self.pack_uniq_var(hx) #:hx = numpy.einsum('iq,qp->pi', g0, x) hx = lib.dot(x.T, g0.T).conj() #:hx+= numpy.einsum('qi,xiq,xip->pi', x, dip, dip) * 2 hx+= numpy.einsum('xip,xi->pi', dip, numpy.einsum('qi,xiq->xi', x, dip)) * 2 #:hx-= numpy.einsum('qp,xpp,xiq->pi', x, dip, dip) * 2 hx-= numpy.einsum('xpp,xip->pi', dip, lib.dot(dip.reshape(-1,norb), x).reshape(3,norb,norb)) * 2 #:hx-= numpy.einsum('qp,xip,xpq->pi', x, dip, dip) * 2 hx-= numpy.einsum('xip,xp->pi', dip, numpy.einsum('qp,xpq->xp', x, dip)) * 2 return -self.pack_uniq_var(hx-hx.conj().T)
def gamma1_intermediates(mycc, t1, t2, l1, l2): nocc, nvir = t1.shape doo =-numpy.einsum('ja,ia->ij', l1, t1) dvv = numpy.einsum('ia,ib->ab', l1, t1) dvo = l1.T xtv = numpy.einsum('ie,me->im', t1, l1) dov = t1 - numpy.einsum('im,ma->ia', xtv, t1) #:doo -= numpy.einsum('jkab,ikab->ij', l2, theta) #:dvv += numpy.einsum('jica,jicb->ab', l2, theta) #:xt1 = numpy.einsum('mnef,inef->mi', l2, make_theta(t2)) #:xt2 = numpy.einsum('mnaf,mnef->ea', l2, make_theta(t2)) #:dov += numpy.einsum('imae,me->ia', make_theta(t2), l1) #:dov -= numpy.einsum('ma,ie,me->ia', t1, t1, l1) #:dov -= numpy.einsum('mi,ma->ia', xt1, t1) #:dov -= numpy.einsum('ie,ae->ia', t1, xt2) max_memory = mycc.max_memory - lib.current_memory()[0] unit = nocc*nvir**2 blksize = max(ccsd.BLKMIN, int(max_memory*.95e6/8/unit)) for p0, p1 in prange(0, nocc, blksize): theta = make_theta(t2[p0:p1]) doo[p0:p1] -= lib.dot(theta.reshape(p1-p0,-1), l2.reshape(nocc,-1).T) dov[p0:p1] += numpy.einsum('imae,me->ia', theta, l1) xt1 = lib.dot(l2.reshape(nocc,-1), theta.reshape(p1-p0,-1).T) dov[p0:p1] -= numpy.einsum('mi,ma->ia', xt1, t1) xt2 = lib.dot(theta.reshape(-1,nvir).T, l2[p0:p1].reshape(-1,nvir)) dov -= numpy.einsum('ie,ae->ia', t1, xt2) dvv += lib.dot(l2[p0:p1].reshape(-1,nvir).T, theta.reshape(-1,nvir)) return doo, dov, dvo, dvv
def _nao_sub(mol, pre_occ, pre_nao, s=None): if s is None: s = mol.intor_symmetric("cint1e_ovlp_sph") core_lst, val_lst, rydbg_lst = _core_val_ryd_list(mol) nbf = mol.nao_nr() cnao = numpy.empty((nbf, nbf)) if core_lst: c = pre_nao[:, core_lst].copy() s1 = reduce(lib.dot, (c.T, s, c)) cnao[:, core_lst] = c1 = lib.dot(c, orth.lowdin(s1)) c = pre_nao[:, val_lst].copy() c -= reduce(lib.dot, (c1, c1.T, s, c)) else: c = pre_nao[:, val_lst] if val_lst: s1 = reduce(lib.dot, (c.T, s, c)) wt = pre_occ[val_lst] cnao[:, val_lst] = lib.dot(c, orth.weight_orth(s1, wt)) if rydbg_lst: cvlst = core_lst + val_lst c1 = cnao[:, cvlst].copy() c = pre_nao[:, rydbg_lst].copy() c -= reduce(lib.dot, (c1, c1.T, s, c)) s1 = reduce(lib.dot, (c.T, s, c)) cnao[:, rydbg_lst] = lib.dot(c, orth.lowdin(s1)) snorm = numpy.linalg.norm(reduce(lib.dot, (cnao.T, s, cnao)) - numpy.eye(nbf)) if snorm > 1e-9: logger.warn(mol, "Weak orthogonality for localized orbitals %s", snorm) return cnao
def cost_function(self, u=None): if u is None: u = numpy.eye(self.mo_coeff.shape[1]) mo_coeff = lib.dot(self.mo_coeff, u) dip = dipole_integral(self.mol, mo_coeff) r2 = self.mol.intor_symmetric('int1e_r2') r2 = numpy.einsum('pi,pi->', mo_coeff, lib.dot(r2, mo_coeff)) val = r2 - numpy.einsum('xii,xii->', dip, dip) * 2 return val
def add_k_(vk, dm, pqk, coulG, buf=None): nG = pqk.shape[-1] pqk *= numpy.sqrt(coulG) ipk = lib.dot(dm, pqk.reshape(nao,-1)).reshape(nao,nao,-1) pik = numpy.ndarray((nao,nao,nG), buffer=buf) pik[:] = ipk.transpose(1,0,2) vk += lib.dot(pqk.reshape(nao,-1), pik.reshape(nao,-1).T) return vk
def transform_ci_for_orbital_rotation(ci, norb, nelec, u): '''Transform CI coefficients to the representation in new one-particle basis. Solving CI problem for Hamiltonian h1, h2 defined in old basis, CI_old = fci.kernel(h1, h2, ...) Given orbital rotation u, the CI problem can be either solved by transforming the Hamiltonian, or transforming the coefficients. CI_new = fci.kernel(u^T*h1*u, ...) = transform_ci_for_orbital_rotation(CI_old, u) Args: u : 2D array or a list of 2D array the orbital rotation to transform the old one-particle basis to new one-particle basis ''' neleca, nelecb = _unpack(nelec) strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca)) strsb = numpy.asarray(cistring.gen_strings4orblist(range(norb), nelecb)) one_particle_strs = numpy.asarray([1<<i for i in range(norb)]) na = len(strsa) nb = len(strsb) if isinstance(u, numpy.ndarray) and u.ndim == 2: ua = ub = u else: ua, ub = u # Unitary transformation array trans_ci is the overlap between two sets of CI basis. occ_masks = (strsa[:,None] & one_particle_strs) != 0 trans_ci_a = numpy.zeros((na,na)) #for i in range(na): # for old basis # for j in range(na): # uij = u[occ_masks[i]][:,occ_masks[j]] # trans_ci_a[i,j] = numpy.linalg.det(uij) occ_idx_all_strs = numpy.where(occ_masks)[1] for i in range(na): ui = ua[occ_masks[i]].T.copy() minors = numpy.take(ui, occ_idx_all_strs, axis=0).reshape(na,neleca,neleca) trans_ci_a[i,:] = numpy.linalg.det(minors) if neleca == nelecb and numpy.allclose(ua, ub): trans_ci_b = trans_ci_a else: occ_masks = (strsb[:,None] & one_particle_strs) != 0 trans_ci_b = numpy.zeros((nb,nb)) #for i in range(nb): # for j in range(nb): # uij = u[occ_masks[i]][:,occ_masks[j]] # trans_ci_b[i,j] = numpy.linalg.det(uij) occ_idx_all_strs = numpy.where(occ_masks)[1] for i in range(nb): ui = ub[occ_masks[i]].T.copy() minors = numpy.take(ui, occ_idx_all_strs, axis=0).reshape(nb,nelecb,nelecb) trans_ci_b[i,:] = numpy.linalg.det(minors) # Transform old basis to new basis for all alpha-electron excitations ci = lib.dot(trans_ci_a.T, ci.reshape(na,nb)) # Transform old basis to new basis for all beta-electron excitations ci = lib.dot(ci.reshape(na,nb), trans_ci_b) return ci
def h_op(x): x = self.unpack_uniq_var(x) norb = x.shape[0] hx = lib.dot(x.T, g0.T) hx+= numpy.einsum('xip,xi->pi', pop, numpy.einsum('qi,xiq->xi', x, pop)) * 2 hx-= numpy.einsum('xpp,xip->pi', pop, lib.dot(pop.reshape(-1,norb), x).reshape(-1,norb,norb)) * 2 hx-= numpy.einsum('xip,xp->pi', pop, numpy.einsum('qp,xpq->xp', x, pop)) * 2 return -self.pack_uniq_var(hx-hx.T)
def gamma1_intermediates(mycc, t1, t2, l1, l2): nocc, nvir = t1.shape goo = -numpy.einsum('ja,ia->ij', l1, t1) gvv = numpy.einsum('ia,ib->ab', l1, t1) #:goo -= numpy.einsum('jkab,ikab->ij', l2, theta) #:gvv += numpy.einsum('jica,jicb->ab', l2, theta) theta = make_theta(t2) goo -= lib.dot(theta.reshape(nocc,-1), l2.reshape(nocc,-1).T) gvv += lib.dot(l2.reshape(-1,nvir).T, theta.reshape(-1,nvir)) return goo, gvv
def short_range_k(dm, Lpq, j3c): Lpq = Lpq.reshape(-1,nao) j3c = j3c.reshape(-1,nao) iLp = lib.dot(dm, Lpq.T).reshape(-1,nao) vk = lib.dot(j3c.T, iLp) if hermi: vk = vk + vk.T else: iLp = lib.dot(dm.T, Lpq.T).reshape(-1,nao) vk += lib.dot(iLp.T, j3c) return vk
def trans(aoi, aoj, fac=1): if id(aoi) == id(aoj) and iden_coeffs(mo_coeffs[0], mo_coeffs[1]): moi = moj = numpy.asarray(lib.dot(mo_coeffs[0].T,aoi.T), order='C') else: moi = numpy.asarray(lib.dot(mo_coeffs[0].T, aoi.T), order='C') moj = numpy.asarray(lib.dot(mo_coeffs[1].T, aoj.T), order='C') mo_pairs_G = numpy.empty((nmoi,nmoj,ngrids), dtype=numpy.complex128) for i in range(nmoi): mo_pairs_G[i] = tools.fft(fac * moi[i].conj() * moj, mydf.mesh) mo_pairs_G = mo_pairs_G.reshape(-1,ngrids).T return mo_pairs_G
def shift_grids(r): r_frac = lib.dot(r - origin, b.T) # Grids on the boundary (r_frac == +/-0.5) of the new cell may lead to # unbalanced contributions to the dipole moment. Exclude them from the # dipole and quadrupole r_frac[r_frac== 0.5] = 0 r_frac[r_frac==-0.5] = 0 r_frac[r_frac > 0.5] -= 1 r_frac[r_frac <-0.5] += 1 r = lib.dot(r_frac, a) return r
def trans(aoiR, aojR, fac=1): if id(aoiR) == id(aojR) and ao2mo.incore.iden_coeffs(mo_coeffs[0], mo_coeffs[1]): moiR = mojR = numpy.asarray(lib.dot(mo_coeffs[0].T,aoiR.T), order='C') else: moiR = numpy.asarray(lib.dot(mo_coeffs[0].T, aoiR.T), order='C') mojR = numpy.asarray(lib.dot(mo_coeffs[1].T, aojR.T), order='C') mo_pairs_G = numpy.empty((nmoi,nmoj,ngs), dtype=numpy.complex128) for i in range(nmoi): mo_pairs_G[i] = tools.fft(fac * moiR[i].conj() * mojR, mydf.gs) mo_pairs_G = mo_pairs_G.reshape(-1,ngs).T return mo_pairs_G
def get_j_kpts(mydf, dm_kpts, hermi=1, kpts=np.zeros((1, 3)), kpt_band=None): """Get the Coulomb (J) AO matrix at sampled k-points. Args: dm_kpts : (nkpts, nao, nao) ndarray or a list of (nkpts,nao,nao) ndarray Density matrix at each k-point. If a list of k-point DMs, eg, UHF alpha and beta DM, the alpha and beta DMs are contracted separately. kpts : (nkpts, 3) ndarray Kwargs: kpt_band : (3,) ndarray An arbitrary "band" k-point at which to evalute the matrix. Returns: vj : (nkpts, nao, nao) ndarray or list of vj if the input dm_kpts is a list of DMs """ cell = mydf.cell gs = mydf.gs dm_kpts = lib.asarray(dm_kpts, order="C") dms = _format_dms(dm_kpts, kpts) nset, nkpts, nao = dms.shape[:3] coulG = tools.get_coulG(cell, gs=gs) ngs = len(coulG) vR = rhoR = np.zeros((nset, ngs)) for k, aoR in mydf.aoR_loop(gs, kpts): for i in range(nset): rhoR[i] += numint.eval_rho(cell, aoR, dms[i, k]) for i in range(nset): rhoR[i] *= 1.0 / nkpts rhoG = tools.fft(rhoR[i], gs) vG = coulG * rhoG vR[i] = tools.ifft(vG, gs).real if kpt_band is not None: for k, aoR_kband in mydf.aoR_loop(gs, kpts, kpt_band): pass vj_kpts = [cell.vol / ngs * lib.dot(aoR_kband.T.conj() * vR[i], aoR_kband) for i in range(nset)] if dm_kpts.ndim == 3: # One set of dm_kpts for KRHF vj_kpts = vj_kpts[0] return lib.asarray(vj_kpts) else: vj_kpts = [] weight = cell.vol / ngs for k, aoR in mydf.aoR_loop(gs, kpts): for i in range(nset): vj_kpts.append(weight * lib.dot(aoR.T.conj() * vR[i], aoR)) vj_kpts = lib.asarray(vj_kpts).reshape(nkpts, nset, nao, nao) return vj_kpts.transpose(1, 0, 2, 3).reshape(dm_kpts.shape)
def general(mydf, mo_coeffs, kpts=None, compact=getattr(__config__, 'pbc_df_ao2mo_general_compact', True)): '''General MO integral transformation''' from pyscf.pbc.df.df_ao2mo import warn_pbc2d_eri warn_pbc2d_eri(mydf) cell = mydf.cell kptijkl = _format_kpts(kpts) kpti, kptj, kptk, kptl = kptijkl if isinstance(mo_coeffs, numpy.ndarray) and mo_coeffs.ndim == 2: mo_coeffs = (mo_coeffs,) * 4 mo_coeffs = [numpy.asarray(mo, order='F') for mo in mo_coeffs] if not _iskconserv(cell, kptijkl): lib.logger.warn(cell, 'fft_ao2mo: momentum conservation not found in ' 'the given k-points %s', kptijkl) return numpy.zeros([mo.shape[1] for mo in mo_coeffs]) allreal = not any(numpy.iscomplexobj(mo) for mo in mo_coeffs) q = kptj - kpti coulG = tools.get_coulG(cell, q, mesh=mydf.mesh) coords = cell.gen_uniform_grids(mydf.mesh) max_memory = mydf.max_memory - lib.current_memory()[0] if gamma_point(kptijkl) and allreal: ao = mydf._numint.eval_ao(cell, coords, kpti)[0] if ((iden_coeffs(mo_coeffs[0], mo_coeffs[1]) and iden_coeffs(mo_coeffs[0], mo_coeffs[2]) and iden_coeffs(mo_coeffs[0], mo_coeffs[3]))): moiT = mojT = numpy.asarray(lib.dot(mo_coeffs[0].T,ao.T), order='C') ao = None max_memory = max_memory - moiT.nbytes*1e-6 eri = _contract_compact(mydf, (moiT,mojT), coulG, max_memory=max_memory) if not compact: nmo = moiT.shape[0] eri = ao2mo.restore(1, eri, nmo).reshape(nmo**2,nmo**2) else: mos = [numpy.asarray(lib.dot(c.T, ao.T), order='C') for c in mo_coeffs] ao = None fac = numpy.array(1.) max_memory = max_memory - sum([x.nbytes for x in mos])*1e-6 eri = _contract_plain(mydf, mos, coulG, fac, max_memory=max_memory).real return eri else: aos = mydf._numint.eval_ao(cell, coords, kptijkl) mos = [numpy.asarray(lib.dot(c.T, aos[i].T), order='C') for i,c in enumerate(mo_coeffs)] aos = None fac = numpy.exp(-1j * numpy.dot(coords, q)) max_memory = max_memory - sum([x.nbytes for x in mos])*1e-6 eri = _contract_plain(mydf, mos, coulG, fac, max_memory=max_memory) return eri
def gamma1_intermediates(mycc, t1, t2, l1, l2, max_memory=2000): nocc, nvir = t1.shape goo = -numpy.einsum('ja,ia->ij', l1, t1) gvv = numpy.einsum('ia,ib->ab', l1, t1) #:goo -= numpy.einsum('jkab,ikab->ij', l2, theta) #:gvv += numpy.einsum('jica,jicb->ab', l2, theta) max_memory = max_memory - lib.current_memory()[0] unit = nocc*nvir**2 blksize = max(ccsd.BLKMIN, int(max_memory*.95e6/8/unit)) for p0, p1 in prange(0, nocc, blksize): theta = make_theta(t2[p0:p1]) goo[p0:p1] -= lib.dot(theta.reshape(p1-p0,-1), l2.reshape(nocc,-1).T) gvv += lib.dot(l2[p0:p1].reshape(-1,nvir).T, theta.reshape(-1,nvir)) return goo, gvv
def make_kpt(kpt): # kpt = kptj - kpti # search for all possible ki and kj that has ki-kj+kpt=0 kk_match = numpy.einsum('ijx->ij', abs(kk_table + kpt)) < 1e-9 kpti_idx, kptj_idx = numpy.where(kk_todo & kk_match) nkptj = len(kptj_idx) log.debug1('kpt = %s', kpt) log.debug1('kpti_idx = %s', kpti_idx) log.debug1('kptj_idx = %s', kptj_idx) kk_todo[kpti_idx,kptj_idx] = False if swap_2e and abs(kpt).sum() > 1e-9: kk_todo[kptj_idx,kpti_idx] = False mydf.exxdiv = exxdiv vkcoulG = tools.get_coulG(cell, kpt, True, mydf, mydf.gs) / cell.vol # <r|-G+k_rs|s> = conj(<s|G-k_rs|r>) = conj(<s|G+k_sr|r>) for k, pqkR, pqkI, p0, p1 \ in mydf.ft_loop(cell, mydf.gs, kpt, kpts[kptj_idx], max_memory=max_memory): ki = kpti_idx[k] kj = kptj_idx[k] coulG = numpy.sqrt(vkcoulG[p0:p1]) # case 1: k_pq = (pi|iq) pqkR *= coulG pqkI *= coulG rsk =(pqkR.reshape(nao,nao,-1).transpose(1,0,2) - pqkI.reshape(nao,nao,-1).transpose(1,0,2)*1j) qpk = rsk.conj() for i in range(nset): qsk = lib.dot(dms[i,kj], rsk.reshape(nao,-1)).reshape(nao,nao,-1) #:vk_kpts[i,ki] += numpy.einsum('qpk,qsk->ps', qpk, qsk) vk_kpts[i,ki] += lib.dot(qpk.transpose(1,0,2).reshape(nao,-1), qsk.transpose(1,0,2).reshape(nao,-1).T) qsk = None rsk = qpk = None # case 2: k_pq = (iq|pi) if swap_2e and abs(kpt).sum() > 1e-9: srk = pqkR - pqkI*1j pqk = srk.reshape(nao,nao,-1).conj() for i in range(nset): prk = lib.dot(dms[i,ki].T, srk.reshape(nao,-1)).reshape(nao,nao,-1) #:vk_kpts[i,kj] += numpy.einsum('prk,pqk->rq', prk, pqk) vk_kpts[i,kj] += lib.dot(prk.transpose(1,0,2).reshape(nao,-1), pqk.transpose(1,0,2).reshape(nao,-1).T) prk = None srk = pqk = None pqkR = pqkI = coulG = None return None
def _fftn_blas(f, mesh): Gx = np.fft.fftfreq(mesh[0]) Gy = np.fft.fftfreq(mesh[1]) Gz = np.fft.fftfreq(mesh[2]) expRGx = np.exp(np.einsum('x,k->xk', -2j * np.pi * np.arange(mesh[0]), Gx)) expRGy = np.exp(np.einsum('x,k->xk', -2j * np.pi * np.arange(mesh[1]), Gy)) expRGz = np.exp(np.einsum('x,k->xk', -2j * np.pi * np.arange(mesh[2]), Gz)) g0 = g = lib.transpose(f.reshape(-1, mesh[1] * mesh[2])).astype(np.complex128) g1 = np.empty_like(g0) g = lib.dot(g.reshape(-1, mesh[0]), expRGx, c=g1.reshape(-1, mesh[0])) g = lib.dot(g.reshape(mesh[1], -1).T, expRGy, c=g0.reshape(-1, mesh[1])) g = lib.dot(g.reshape(mesh[2], -1).T, expRGz, c=g1.reshape(-1, mesh[2])) return g.reshape(-1, *mesh)
def pw_contract(istep, sh_range, j3cR, j3cI): bstart, bend, ncol = sh_range if aosym == 's2': shls_slice = (bstart, bend, 0, bend) else: shls_slice = (bstart, bend, 0, cell.nbas) for p0, p1 in lib.prange(0, ngrids, Gblksize): dat = ft_ao._ft_aopair_kpts(cell, Gv[p0:p1], shls_slice, aosym, b, gxyz[p0:p1], Gvbase, kpt, adapted_kptjs, out=buf) nG = p1 - p0 for k, ji in enumerate(adapted_ji_idx): aoao = dat[k].reshape(nG, ncol) pqkR = numpy.ndarray((ncol, nG), buffer=pqkRbuf) pqkI = numpy.ndarray((ncol, nG), buffer=pqkIbuf) pqkR[:] = aoao.real.T pqkI[:] = aoao.imag.T lib.dot(kLR[p0:p1].T, pqkR.T, -1, j3cR[k][naux:], 1) lib.dot(kLI[p0:p1].T, pqkI.T, -1, j3cR[k][naux:], 1) if not (is_zero(kpt) and gamma_point(adapted_kptjs[k])): lib.dot(kLR[p0:p1].T, pqkI.T, -1, j3cI[k][naux:], 1) lib.dot(kLI[p0:p1].T, pqkR.T, 1, j3cI[k][naux:], 1) for k, ji in enumerate(adapted_ji_idx): if is_zero(kpt) and gamma_point(adapted_kptjs[k]): v = fuse(j3cR[k]) else: v = fuse(j3cR[k] + j3cI[k] * 1j) if j2ctag == 'CD': v = scipy.linalg.solve_triangular(j2c, v, lower=True, overwrite_b=True) feri['j3c/%d/%d' % (ji, istep)] = v else: feri['j3c/%d/%d' % (ji, istep)] = lib.dot(j2c, v) # low-dimension systems if j2c_negative is not None: feri['j3c-/%d/%d' % (ji, istep)] = lib.dot(j2c_negative, v)
def _ifftn_blas(g, mesh): Gx = np.fft.fftfreq(mesh[0]) Gy = np.fft.fftfreq(mesh[1]) Gz = np.fft.fftfreq(mesh[2]) expRGx = np.exp(np.einsum('x,k->xk', 2j*np.pi*np.arange(mesh[0]), Gx)) expRGy = np.exp(np.einsum('x,k->xk', 2j*np.pi*np.arange(mesh[1]), Gy)) expRGz = np.exp(np.einsum('x,k->xk', 2j*np.pi*np.arange(mesh[2]), Gz)) out = np.empty(g.shape, dtype=np.complex128) buf = np.empty(mesh, dtype=np.complex128) for i, gi in enumerate(g): buf[:] = gi.reshape(mesh) f = lib.dot(buf.reshape(mesh[0],-1).T, expRGx, 1./mesh[0], c=out[i].reshape(-1,mesh[0])) f = lib.dot(f.reshape(mesh[1],-1).T, expRGy, 1./mesh[1], c=buf.reshape(-1,mesh[1])) f = lib.dot(f.reshape(mesh[2],-1).T, expRGz, 1./mesh[2], c=out[i].reshape(-1,mesh[2])) return out.reshape(-1, *mesh)
def _fftn_blas(f, mesh): Gx = np.fft.fftfreq(mesh[0]) Gy = np.fft.fftfreq(mesh[1]) Gz = np.fft.fftfreq(mesh[2]) expRGx = np.exp(np.einsum('x,k->xk', -2j*np.pi*np.arange(mesh[0]), Gx)) expRGy = np.exp(np.einsum('x,k->xk', -2j*np.pi*np.arange(mesh[1]), Gy)) expRGz = np.exp(np.einsum('x,k->xk', -2j*np.pi*np.arange(mesh[2]), Gz)) out = np.empty(f.shape, dtype=np.complex128) buf = np.empty(mesh, dtype=np.complex128) for i, fi in enumerate(f): buf[:] = fi.reshape(mesh) g = lib.dot(buf.reshape(mesh[0],-1).T, expRGx, c=out[i].reshape(-1,mesh[0])) g = lib.dot(g.reshape(mesh[1],-1).T, expRGy, c=buf.reshape(-1,mesh[1])) g = lib.dot(g.reshape(mesh[2],-1).T, expRGz, c=out[i].reshape(-1,mesh[2])) return out.reshape(-1, *mesh)
def h_op(x): x = self.unpack_uniq_var(x) norb = x.shape[0] hx = lib.dot(x.T, g0.T).conj() * 2 pop2 = numpy.einsum('xii->xi', pop)**2 pop3 = numpy.einsum('xii->xi', pop)**3 tmp = numpy.einsum('qi,xiq->xi', x, pop) * pop2 hx += numpy.einsum('xip,xi->pi', pop, tmp) * 12 hx -= numpy.einsum( 'xp,xip->pi', pop3, lib.dot(pop.reshape(-1, norb), x).reshape(-1, norb, norb)) * 4 tmp = numpy.einsum('qp,xpq->xp', x, pop) * pop2 hx -= numpy.einsum('xip,xp->pi', pop, tmp) * 12 return -self.pack_uniq_var(hx - hx.conj().T)
def ao2mo(self, mo_coeffs): from pyscf.ao2mo import _ao2mo nmoi, nmoj, nmok, nmol = [x.shape[1] for x in mo_coeffs] mo_eri = numpy.zeros((nmoi * nmoj, nmok * nmol)) moij = numpy.asarray(numpy.hstack((mo_coeffs[0], mo_coeffs[1])), order='F') ijshape = (0, nmoi, nmoi, nmoi + nmoj) mokl = numpy.asarray(numpy.hstack((mo_coeffs[2], mo_coeffs[3])), order='F') klshape = (0, nmok, nmok, nmok + nmol) for eri1 in self.loop(): buf1 = _ao2mo.nr_e2(eri1, moij, ijshape, 's2', 's1') buf2 = _ao2mo.nr_e2(eri1, mokl, klshape, 's2', 's1') lib.dot(buf1.T, buf2, 1, mo_eri, 1) return mo_eri
def get_eri(mydf, kpts=None, compact=False): cell = mydf.cell if kpts is None: kptijkl = numpy.zeros((4,3)) elif numpy.shape(kpts) == (3,): kptijkl = numpy.vstack([kpts]*4) else: kptijkl = numpy.reshape(kpts, (4,3)) kpti, kptj, kptk, kptl = kptijkl nao = cell.nao_nr() nao_pair = nao * (nao+1) // 2 coulG = tools.get_coulG(cell, kptj-kpti, gs=mydf.gs) ngs = len(coulG) #################### # gamma point, the integral is real and with s4 symmetry if abs(kptijkl).sum() < 1e-9: ao_pairs_G = get_ao_pairs_G(mydf, kptijkl[:2], compact) ao_pairs_G *= numpy.sqrt(coulG).reshape(-1,1) aoijR = ao_pairs_G.real.copy() aoijI = ao_pairs_G.imag.copy() ao_pairs_G = None eri = lib.dot(aoijR.T, aoijR, cell.vol/ngs**2) eri = lib.dot(aoijI.T, aoijI, cell.vol/ngs**2, eri, 1) return eri #################### # (kpt) i == j == k == l != 0 # (kpt) i == l && j == k && i != j && j != k => # # complex integrals, N^4 elements elif (abs(kpti-kptl).sum() < 1e-9) and (abs(kptj-kptk).sum() < 1e-9): ao_pairs_G = get_ao_pairs_G(mydf, kptijkl[:2], False) ao_pairs_G *= numpy.sqrt(coulG).reshape(-1,1) ao_pairs_invG = ao_pairs_G.T.reshape(nao,nao,-1).transpose(1,0,2).conj() ao_pairs_invG = ao_pairs_invG.reshape(-1,ngs) return lib.dot(ao_pairs_G.T, ao_pairs_invG.T, cell.vol/ngs**2) #################### # aosym = s1, complex integrals # else: ao_pairs_G = get_ao_pairs_G(mydf, kptijkl[:2], False) # ao_pairs_invG = rho_rs(-G+k_rs) = conj(rho_sr(G+k_sr)).swap(r,s) ao_pairs_invG = get_ao_pairs_G(mydf, -kptijkl[2:], False).conj() ao_pairs_G *= coulG.reshape(-1,1) return lib.dot(ao_pairs_G.T, ao_pairs_invG, cell.vol/ngs**2)
def test_dot_ao_ao(self): non0tab = dft.numint.make_mask(mol, mf.grids.coords) ao = dft.numint.eval_ao(mol, mf.grids.coords, deriv=1) res0 = lib.dot(ao[0].T, ao[1]) res1 = dft.numint._dot_ao_ao(mol, ao[0], ao[1], nao, mf.grids.weights.size, non0tab) self.assertTrue(numpy.allclose(res0, res1))
def test_dot_ao_ao(self): non0tab = dft.numint.make_mask(mol, mf.grids.coords) ao = dft.numint.eval_ao(mol, mf.grids.coords, deriv=1) res0 = lib.dot(ao[0].T, ao[1]) res1 = dft.numint._dot_ao_ao(mol, ao[0], ao[1], non0tab, shls_slice=(0,mol.nbas), ao_loc=ao_loc) self.assertTrue(numpy.allclose(res0, res1))
def make_natorbs(self, rdm1_mo=None, relaxed=False): ''' Calculate natural orbitals. Note: the most occupied orbitals come first (left) and the least occupied orbitals last (right). Args: rdm1_mo : 1-RDM in MO basis the function calculates a density matrix if none is provided relaxed : calculated relaxed or unrelaxed density matrix Returns: natural occupation numbers, natural orbitals ''' if rdm1_mo is None: dm = self.make_rdm1(relaxed=relaxed, ao_repr=False) elif isinstance(rdm1_mo, np.ndarray): dm = rdm1_mo else: raise TypeError('rdm1_mo must be a 2-D array') eigval, eigvec = np.linalg.eigh(dm) natocc = np.flip(eigval) natorb = lib.dot(self.mo_coeff, np.fliplr(eigvec)) return natocc, natorb
def get_nuc(mydf, kpts): mydf = _sync_mydf(mydf) cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1, 3)) else: kpts_lst = numpy.reshape(kpts, (-1, 3)) if abs(kpts_lst).sum() < 1e-9: # gamma_point dtype = numpy.float64 else: dtype = numpy.complex128 mesh = mydf.mesh charge = -cell.atom_charges() Gv = cell.get_Gv(mesh) SI = cell.get_SI(Gv) rhoG = numpy.dot(charge, SI) coulG = tools.get_coulG(cell, mesh=mesh, Gv=Gv) vneG = rhoG * coulG vneR = tools.ifft(vneG, mydf.mesh).real vne = [0] * len(kpts_lst) for ao_ks_etc, p0, p1 in mydf.mpi_aoR_loop(mydf.grids, kpts_lst): ao_ks = ao_ks_etc[0] for k, ao in enumerate(ao_ks): vne[k] += lib.dot(ao.T.conj() * vneR[p0:p1], ao) ao = ao_ks = None vne = mpi.reduce(lib.asarray(vne)) if rank == 0: if kpts is None or numpy.shape(kpts) == (3, ): vne = vne[0] return vne
def get_grad(self, u=None): if u is None: u = numpy.eye(self.mo_coeff.shape[1]) mo_coeff = lib.dot(self.mo_coeff, u) pop = atomic_pops(self.mol, mo_coeff, self.pop_method) g0 = numpy.einsum('xii,xip->pi', pop, pop) g = -self.pack_uniq_var(g0 - g0.T) * 2 return g
def get_grad(self, u=None): if u is None: u = numpy.eye(self.mo_coeff.shape[1]) mo_coeff = lib.dot(self.mo_coeff, u) dip = dipole_integral(self.mol, mo_coeff) g0 = numpy.einsum('xii,xip->pi', dip, dip) g = -self.pack_uniq_var(g0 - g0.T) * 2 return g
def gen_g_hop(self, u): mo_coeff = lib.dot(self.mo_coeff, u) pop = atomic_pops(self.mol, mo_coeff, self.pop_method) g0 = numpy.einsum('xii,xip->pi', pop, pop) g = -self.pack_uniq_var(g0 - g0.T) * 2 h_diag = numpy.einsum('xii,xpp->pi', pop, pop) * 2 g_diag = g0.diagonal() h_diag -= g_diag + g_diag.reshape(-1, 1) h_diag += numpy.einsum('xip,xip->pi', pop, pop) * 2 h_diag += numpy.einsum('xip,xpi->pi', pop, pop) * 2 h_diag = -self.pack_uniq_var(h_diag) * 2 g0 = g0 + g0.T def h_op(x): x = self.unpack_uniq_var(x) norb = x.shape[0] hx = lib.dot(x.T, g0.T) hx += numpy.einsum('xip,xi->pi', pop, numpy.einsum('qi,xiq->xi', x, pop)) * 2 hx -= numpy.einsum( 'xpp,xip->pi', pop, lib.dot(pop.reshape(-1, norb), x).reshape(-1, norb, norb)) * 2 hx -= numpy.einsum('xip,xp->pi', pop, numpy.einsum('qp,xpq->xp', x, pop)) * 2 return -self.pack_uniq_var(hx - hx.T) return g, h_op, h_diag
def gen_g_hop(self, u): mo_coeff = lib.dot(self.mo_coeff, u) pop = atomic_pops(self.mol, mo_coeff, self.pop_method) g0 = numpy.einsum('xii,xip->pi', pop, pop) g = -self.pack_uniq_var(g0-g0.T) * 2 h_diag = numpy.einsum('xii,xpp->pi', pop, pop) * 2 g_diag = g0.diagonal() h_diag-= g_diag + g_diag.reshape(-1,1) h_diag+= numpy.einsum('xip,xip->pi', pop, pop) * 2 h_diag+= numpy.einsum('xip,xpi->pi', pop, pop) * 2 h_diag = -self.pack_uniq_var(h_diag) * 2 g0 = g0 + g0.T def h_op(x): x = self.unpack_uniq_var(x) norb = x.shape[0] hx = lib.dot(x.T, g0.T) hx+= numpy.einsum('xip,xi->pi', pop, numpy.einsum('qi,xiq->xi', x, pop)) * 2 hx-= numpy.einsum('xpp,xip->pi', pop, lib.dot(pop.reshape(-1,norb), x).reshape(-1,norb,norb)) * 2 hx-= numpy.einsum('xip,xp->pi', pop, numpy.einsum('qp,xpq->xp', x, pop)) * 2 return -self.pack_uniq_var(hx-hx.T) return g, h_op, h_diag
def get_nuc(mydf, kpts=None): cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1, 3)) else: kpts_lst = numpy.reshape(kpts, (-1, 3)) gs = mydf.gs charge = -cell.atom_charges() Gv = cell.get_Gv(gs) SI = cell.get_SI(Gv) rhoG = numpy.dot(charge, SI) coulG = tools.get_coulG(cell, gs=gs, Gv=Gv) vneG = rhoG * coulG vneR = tools.ifft(vneG, mydf.gs).real vne = [ lib.dot(aoR.T.conj() * vneR, aoR) for k, aoR in mydf.aoR_loop(gs, kpts_lst) ] if kpts is None or numpy.shape(kpts) == (3, ): vne = vne[0] return numpy.asarray(vne)
def make_rdm12e(fcivec, nsite, nelec): '''1-electron and 2-electron density matrices dm_pq = <|p^+ q|> dm_{pqrs} = <|p^+ r^+ q s|> (note 2pdm is ordered in chemist notation) ''' neleca, nelecb = _unpack_nelec(nelec) link_indexa = cistring.gen_linkstr_index(range(nsite), neleca) link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb) na = cistring.num_strings(nsite, neleca) nb = cistring.num_strings(nsite, nelecb) ci0 = fcivec.reshape(na,nb,-1) rdm1 = numpy.zeros((nsite,nsite)) rdm2 = numpy.zeros((nsite,nsite,nsite,nsite)) for str0 in range(na): t1 = numpy.zeros((nsite,nsite,nb)+ci0.shape[2:]) for a, i, str1, sign in link_indexa[str0]: t1[i,a,:] += sign * ci0[str1,:] for k, tab in enumerate(link_indexb): for a, i, str1, sign in tab: t1[i,a,k] += sign * ci0[str0,str1] rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1) # i^+ j|0> => <0|j^+ i, so swap i and j #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1) tmp = lib.dot(t1.reshape(nsite**2,-1), t1.reshape(nsite**2,-1).T) rdm2 += tmp.reshape((nsite,)*4).transpose(1,0,2,3) rdm1, rdm2 = rdm.reorder_rdm(rdm1, rdm2, True) return rdm1, rdm2
def make_rdm12e(fcivec, nsite, nelec): '''1-electron and 2-electron density matrices dm_pq = <|p^+ q|> dm_{pqrs} = <|p^+ r^+ q s|> (note 2pdm is ordered in chemist notation) ''' neleca, nelecb = _unpack_nelec(nelec) link_indexa = cistring.gen_linkstr_index(range(nsite), neleca) link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb) na = cistring.num_strings(nsite, neleca) nb = cistring.num_strings(nsite, nelecb) ci0 = fcivec.reshape(na, nb, -1) rdm1 = numpy.zeros((nsite, nsite)) rdm2 = numpy.zeros((nsite, nsite, nsite, nsite)) for str0 in range(na): t1 = numpy.zeros((nsite, nsite, nb) + ci0.shape[2:]) for a, i, str1, sign in link_indexa[str0]: t1[i, a, :] += sign * ci0[str1, :] for k, tab in enumerate(link_indexb): for a, i, str1, sign in tab: t1[i, a, k] += sign * ci0[str0, str1] rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1) # i^+ j|0> => <0|j^+ i, so swap i and j #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1) tmp = lib.dot(t1.reshape(nsite**2, -1), t1.reshape(nsite**2, -1).T) rdm2 += tmp.reshape((nsite, ) * 4).transpose(1, 0, 2, 3) rdm1, rdm2 = rdm.reorder_rdm(rdm1, rdm2, True) return rdm1, rdm2
def make_rdm12e(fcivec, nsite, nelec): if isinstance(nelec, (int, numpy.number)): nelecb = nelec//2 neleca = nelec - nelecb else: neleca, nelecb = nelec link_indexa = cistring.gen_linkstr_index(range(nsite), neleca) link_indexb = cistring.gen_linkstr_index(range(nsite), nelecb) na = cistring.num_strings(nsite, neleca) nb = cistring.num_strings(nsite, nelecb) ci0 = fcivec.reshape(na,nb,-1) rdm1 = numpy.zeros((nsite,nsite)) rdm2 = numpy.zeros((nsite,nsite,nsite,nsite)) for str0 in range(na): t1 = numpy.zeros((nsite,nsite,nb)+ci0.shape[2:]) for a, i, str1, sign in link_indexa[str0]: t1[i,a,:] += sign * ci0[str1,:] for k, tab in enumerate(link_indexb): for a, i, str1, sign in tab: t1[i,a,k] += sign * ci0[str0,str1] rdm1 += numpy.einsum('mp,ijmp->ij', ci0[str0], t1) # i^+ j|0> => <0|j^+ i, so swap i and j #:rdm2 += numpy.einsum('ijmp,klmp->jikl', t1, t1) tmp = lib.dot(t1.reshape(nsite**2,-1), t1.reshape(nsite**2,-1).T) rdm2 += tmp.reshape((nsite,)*4).transpose(1,0,2,3) rdm1, rdm2 = pyscf.fci.rdm.reorder_rdm(rdm1, rdm2, True) return rdm1, rdm2
def madd_admn_mnbc(a, b, c, fac=1): m0, m1, m2, m3 = a.shape n0, n1, n2, n3 = b.shape assert(c.shape == (m0,n2,n3,m1) and m2 == n0 and m3 == n1) tmp = lib.dot(a.reshape(m0*m1,m2*m3), b.reshape(n0*n1,n2*n3), fac) c += tmp.reshape(m0,m1,n2,n3).transpose(0,2,3,1) return c
def get_grad(self, u=None): if u is None: u = numpy.eye(self.mo_coeff.shape[1]) mo_coeff = lib.dot(self.mo_coeff, u) dip = dipole_integral(self.mol, mo_coeff) g0 = numpy.einsum('xii,xip->pi', dip, dip) g = -self.pack_uniq_var(g0-g0.conj().T) * 2 return g
def _contract_plain(mydf, mos, coulG, phase, max_memory): cell = mydf.cell moiT, mojT, mokT, molT = mos nmoi, nmoj, nmok, nmol = [x.shape[0] for x in mos] ngrids = moiT.shape[1] wcoulG = coulG * (cell.vol/ngrids) dtype = numpy.result_type(phase, *mos) eri = numpy.empty((nmoi*nmoj,nmok*nmol), dtype=dtype) blksize = int(min(max(nmoi,nmok), (max_memory*1e6/16 - eri.size)/2/ngrids/max(nmoj,nmol)+1)) assert blksize > 0 buf0 = numpy.empty((blksize,max(nmoj,nmol),ngrids), dtype=dtype) buf1 = numpy.ndarray((blksize,nmoj,ngrids), dtype=dtype, buffer=buf0) buf2 = numpy.ndarray((blksize,nmol,ngrids), dtype=dtype, buffer=buf0) for p0, p1 in lib.prange(0, nmoi, blksize): mo_pairs = numpy.einsum('ig,jg->ijg', moiT[p0:p1].conj()*phase, mojT, out=buf1[:p1-p0]) mo_pairs_G = tools.fft(mo_pairs.reshape(-1,ngrids), mydf.mesh) mo_pairs = None mo_pairs_G*= wcoulG v = tools.ifft(mo_pairs_G, mydf.mesh) mo_pairs_G = None v *= phase.conj() if dtype == numpy.double: v = numpy.asarray(v.real, order='C') for q0, q1 in lib.prange(0, nmok, blksize): mo_pairs = numpy.einsum('ig,jg->ijg', mokT[q0:q1].conj(), molT, out=buf2[:q1-q0]) eri[p0*nmoj:p1*nmoj,q0*nmol:q1*nmol] = lib.dot(v, mo_pairs.reshape(-1,ngrids).T) v = None return eri
def make_natorbs(self, rdm1_mo=None, relaxed=False): ''' Calculate natural orbitals. Note: the most occupied orbitals come first (left) and the least occupied orbitals last (right). Args: rdm1_mo : 1-RDM in MO basis the function calculates a density matrix if none is provided relaxed : calculated relaxed or unrelaxed density matrix Returns: natural occupation numbers, natural orbitals ''' if rdm1_mo is None: dm = self.make_rdm1(ao_repr=False, relaxed=relaxed) elif isinstance(rdm1_mo, np.ndarray): dm = rdm1_mo else: raise TypeError('rdm1_mo must be a 3-D array') # Transform the beta component to the alpha basis and sum both together. SAO = self.mol.intor_symmetric('int1e_ovlp') Sab = lib.einsum('xp,xy,yq->pq', self.mo_coeff[0, :, :], SAO, self.mo_coeff[1, :, :]) rdm1_abas = dm[0, :, :] + lib.einsum('pr,rs,qs->pq', Sab, dm[1, :, :], Sab) # Diagonalize the spin-traced 1-RDM in alpha basis to get the natural orbitals. eigval, eigvec = np.linalg.eigh(rdm1_abas) natocc = np.flip(eigval) natorb = lib.dot(self.mo_coeff[0, :, :], np.fliplr(eigvec)) return natocc, natorb
def get_mo_pairs_G(mydf, mo_coeffs, kpts=numpy.zeros((2, 3)), compact=False): '''Calculate forward (G|ij) FFT of all MO pairs. Args: mo_coeff: length-2 list of (nao,nmo) ndarrays The two sets of MO coefficients to use in calculating the product |ij). Returns: mo_pairs_G : (ngs, nmoi*nmoj) ndarray The FFT of the real-space MO pairs. ''' if kpts is None: kpts = mydf.kpts cell = mydf.cell kpts = numpy.asarray(kpts) coords = pdft.gen_grid.gen_uniform_grids(cell, mydf.gs) nmoi = mo_coeffs[0].shape[1] nmoj = mo_coeffs[1].shape[1] ngs = len(coords) def trans(aoiR, aojR, fac=1): if id(aoiR) == id(aojR) and ao2mo.incore.iden_coeffs( mo_coeffs[0], mo_coeffs[1]): moiR = mojR = numpy.asarray(lib.dot(mo_coeffs[0].T, aoiR.T), order='C') else: moiR = numpy.asarray(lib.dot(mo_coeffs[0].T, aoiR.T), order='C') mojR = numpy.asarray(lib.dot(mo_coeffs[1].T, aojR.T), order='C') mo_pairs_G = numpy.empty((nmoi, nmoj, ngs), dtype=numpy.complex128) for i in range(nmoi): mo_pairs_G[i] = tools.fft(fac * moiR[i].conj() * mojR, mydf.gs) mo_pairs_G = mo_pairs_G.reshape(-1, ngs).T return mo_pairs_G if abs(kpts).sum() < 1e-9: # gamma point, real aoR = mydf._numint.eval_ao(cell, coords, kpts[:1])[0] if compact and ao2mo.incore.iden_coeffs(mo_coeffs[0], mo_coeffs[1]): moR = numpy.asarray(lib.dot(mo_coeffs[0].T, aoR.T), order='C') npair = nmoi * (nmoi + 1) // 2 mo_pairs_G = numpy.empty((npair, ngs), dtype=numpy.complex128) ij = 0 for i in range(nmoi): mo_pairs_G[ij:ij + i + 1] = tools.fft( moR[i].conj() * moR[:i + 1], mydf.gs) ij += i + 1 mo_pairs_G = mo_pairs_G.T else: mo_pairs_G = trans(aoR, aoR) elif abs(kpts[0] - kpts[1]).sum() < 1e-9: aoR = mydf._numint.eval_ao(cell, coords, kpts[:1])[0] mo_pairs_G = trans(aoR, aoR) else: aoiR, aojR = mydf._numint.eval_ao(cell, coords, kpts) q = kpts[1] - kpts[0] fac = numpy.exp(-1j * numpy.dot(coords, q)) mo_pairs_G = trans(aoiR, aojR, fac) return mo_pairs_G
def gen_g_hop(self, u): mo_coeff = lib.dot(self.mo_coeff, u) dip = dipole_integral(self.mol, mo_coeff) g0 = numpy.einsum('xii,xip->pi', dip, dip) g = -self.pack_uniq_var(g0 - g0.T) * 2 h_diag = numpy.einsum('xii,xpp->pi', dip, dip) * 2 h_diag -= g0.diagonal() + g0.diagonal().reshape(-1, 1) h_diag += numpy.einsum('xip,xip->pi', dip, dip) * 2 h_diag += numpy.einsum('xip,xpi->pi', dip, dip) * 2 h_diag = -self.pack_uniq_var(h_diag) * 2 #:nmo = mo_coeff.shape[1] #:h = numpy.einsum('xjj,xjq,pk->pjqk', dip, dip, numpy.eye(nmo)) #:h+= numpy.einsum('xqq,xjq,pk->pjqk', dip, dip, numpy.eye(nmo)) #:h+= numpy.einsum('xjq,xjp,jk->pjqk', dip, dip, numpy.eye(nmo)) #:h+= numpy.einsum('xjp,xkp,pq->pjqk', dip, dip, numpy.eye(nmo)) #:h-= numpy.einsum('xjj,xkp,jq->pjqk', dip, dip, numpy.eye(nmo)) #:h-= numpy.einsum('xpp,xjq,pk->pjqk', dip, dip, numpy.eye(nmo)) #:h-= numpy.einsum('xjp,xpq,pk->pjqk', dip, dip, numpy.eye(nmo))*2 #:h = h - h.transpose(0,1,3,2) #:h = h - h.transpose(1,0,2,3) #:h = h + h.transpose(2,3,0,1) #:h *= -.5 #:idx = numpy.tril_indices(nmo, -1) #:h = h[idx][:,idx[0],idx[1]] g0 = g0 + g0.T def h_op(x): x = self.unpack_uniq_var(x) norb = x.shape[0] #:hx = numpy.einsum('qp,xjj,xjq->pj', x, dip, dip) #:hx+= numpy.einsum('qp,xqq,xjq->pj', x, dip, dip) #:hx+= numpy.einsum('jk,xkk,xkp->pj', x, dip, dip) #:hx+= numpy.einsum('jk,xpp,xkp->pj', x, dip, dip) #:hx+= numpy.einsum('qj,xjq,xjp->pj', x, dip, dip) #:hx+= numpy.einsum('pk,xjp,xkp->pj', x, dip, dip) #:hx-= numpy.einsum('qp,xpp,xjq->pj', x, dip, dip) * 2 #:hx-= numpy.einsum('qp,xjp,xpq->pj', x, dip, dip) * 2 #:hx+= numpy.einsum('qj,xjp,xjq->pj', x, dip, dip) #:hx+= numpy.einsum('pk,xkp,xjp->pj', x, dip, dip) #:hx-= numpy.einsum('jk,xjj,xkp->pj', x, dip, dip) * 2 #:hx-= numpy.einsum('jk,xkj,xjp->pj', x, dip, dip) * 2 #:return -self.pack_uniq_var(hx) #:hx = numpy.einsum('iq,qp->pi', g0, x) hx = lib.dot(x.T, g0.T) #:hx+= numpy.einsum('qi,xiq,xip->pi', x, dip, dip) * 2 hx += numpy.einsum('xip,xi->pi', dip, numpy.einsum('qi,xiq->xi', x, dip)) * 2 #:hx-= numpy.einsum('qp,xpp,xiq->pi', x, dip, dip) * 2 hx -= numpy.einsum( 'xpp,xip->pi', dip, lib.dot(dip.reshape(-1, norb), x).reshape(3, norb, norb)) * 2 #:hx-= numpy.einsum('qp,xip,xpq->pi', x, dip, dip) * 2 hx -= numpy.einsum('xip,xp->pi', dip, numpy.einsum('qp,xpq->xp', x, dip)) * 2 return -self.pack_uniq_var(hx - hx.T) return g, h_op, h_diag
def get_nuc(mydf, kpts): mydf = _sync_mydf(mydf) cell = mydf.cell if kpts is None: kpts_lst = numpy.zeros((1,3)) else: kpts_lst = numpy.reshape(kpts, (-1,3)) if abs(kpts_lst).sum() < 1e-9: # gamma_point dtype = numpy.float64 else: dtype = numpy.complex128 gs = mydf.gs charge = -cell.atom_charges() Gv = cell.get_Gv(gs) SI = cell.get_SI(Gv) rhoG = numpy.dot(charge, SI) coulG = tools.get_coulG(cell, gs=gs, Gv=Gv) vneG = rhoG * coulG vneR = tools.ifft(vneG, mydf.gs).real vne = [lib.dot(aoR.T.conj()*vneR, aoR) for k, aoR in mydf.mpi_aoR_loop(gs, kpts_lst)] vne = mpi.gather(lib.asarray(vne, dtype=dtype)) if rank == 0: if kpts is None or numpy.shape(kpts) == (3,): vne = vne[0] return vne
def get_nuc(mydf, kpts=None): if kpts is None: kpts_lst = numpy.zeros((1, 3)) else: kpts_lst = numpy.reshape(kpts, (-1, 3)) cell = mydf.cell mesh = mydf.mesh charge = -cell.atom_charges() Gv = cell.get_Gv(mesh) SI = cell.get_SI(Gv) rhoG = numpy.dot(charge, SI) coulG = tools.get_coulG(cell, mesh=mesh, Gv=Gv) vneG = rhoG * coulG vneR = tools.ifft(vneG, mesh).real vne = [0] * len(kpts_lst) for ao_ks_etc, p0, p1 in mydf.aoR_loop(mydf.grids, kpts_lst): ao_ks = ao_ks_etc[0] for k, ao in enumerate(ao_ks): vne[k] += lib.dot(ao.T.conj() * vneR[p0:p1], ao) ao = ao_ks = None if kpts is None or numpy.shape(kpts) == (3, ): vne = vne[0] return numpy.asarray(vne)
def pw_contract(istep, sh_range, j3cR, j3cI): bstart, bend, ncol = sh_range if aosym == 's2': shls_slice = (bstart, bend, 0, bend) else: shls_slice = (bstart, bend, 0, cell.nbas) for p0, p1 in lib.prange(0, ngrids, Gblksize): dat = ft_ao._ft_aopair_kpts(cell, Gv[p0:p1], shls_slice, aosym, b, gxyz[p0:p1], Gvbase, kpt, adapted_kptjs, out=buf) if (cell.dimension == 1 or cell.dimension == 2) and is_zero(kpt): G0idx, SI_on_z = pbcgto.cell._SI_for_uniform_model_charge(cell, Gv[p0:p1]) if SI_on_z.size > 0: for k, aoao in enumerate(dat): aoao[G0idx] -= numpy.einsum('g,i->gi', SI_on_z, ovlp[k]) aux = fuse(ft_ao.ft_ao(fused_cell, Gv[p0:p1][G0idx]).T) vG_mod = numpy.einsum('ig,g,g->i', aux.conj(), wcoulG[p0:p1][G0idx], SI_on_z) if gamma_point(adapted_kptjs[k]): j3cR[k][:naux] -= vG_mod[:,None].real * ovlp[k] else: tmp = vG_mod[:,None] * ovlp[k] j3cR[k][:naux] -= tmp.real j3cI[k][:naux] -= tmp.imag tmp = aux = vG_mod nG = p1 - p0 for k, ji in enumerate(adapted_ji_idx): aoao = dat[k].reshape(nG,ncol) pqkR = numpy.ndarray((ncol,nG), buffer=pqkRbuf) pqkI = numpy.ndarray((ncol,nG), buffer=pqkIbuf) pqkR[:] = aoao.real.T pqkI[:] = aoao.imag.T lib.dot(kLR[p0:p1].T, pqkR.T, -1, j3cR[k][naux:], 1) lib.dot(kLI[p0:p1].T, pqkI.T, -1, j3cR[k][naux:], 1) if not (is_zero(kpt) and gamma_point(adapted_kptjs[k])): lib.dot(kLR[p0:p1].T, pqkI.T, -1, j3cI[k][naux:], 1) lib.dot(kLI[p0:p1].T, pqkR.T, 1, j3cI[k][naux:], 1) for k, ji in enumerate(adapted_ji_idx): if is_zero(kpt) and gamma_point(adapted_kptjs[k]): v = fuse(j3cR[k]) else: v = fuse(j3cR[k] + j3cI[k] * 1j) if j2ctag == 'CD': v = scipy.linalg.solve_triangular(j2c, v, lower=True, overwrite_b=True) else: v = lib.dot(j2c, v) feri['j3c/%d/%d'%(ji,istep)] = v
def get_mo_pairs_G(mydf, mo_coeffs, kpts=numpy.zeros((2,3)), q=None, compact=getattr(__config__, 'pbc_df_mo_pairs_compact', False)): '''Calculate forward (G|ij) FFT of all MO pairs. Args: mo_coeff: length-2 list of (nao,nmo) ndarrays The two sets of MO coefficients to use in calculating the product |ij). Returns: mo_pairs_G : (ngrids, nmoi*nmoj) ndarray The FFT of the real-space MO pairs. ''' if kpts is None: kpts = numpy.zeros((2,3)) cell = mydf.cell kpts = numpy.asarray(kpts) coords = cell.gen_uniform_grids(mydf.mesh) nmoi = mo_coeffs[0].shape[1] nmoj = mo_coeffs[1].shape[1] ngrids = len(coords) def trans(aoi, aoj, fac=1): if id(aoi) == id(aoj) and iden_coeffs(mo_coeffs[0], mo_coeffs[1]): moi = moj = numpy.asarray(lib.dot(mo_coeffs[0].T,aoi.T), order='C') else: moi = numpy.asarray(lib.dot(mo_coeffs[0].T, aoi.T), order='C') moj = numpy.asarray(lib.dot(mo_coeffs[1].T, aoj.T), order='C') mo_pairs_G = numpy.empty((nmoi,nmoj,ngrids), dtype=numpy.complex128) for i in range(nmoi): mo_pairs_G[i] = tools.fft(fac * moi[i].conj() * moj, mydf.mesh) mo_pairs_G = mo_pairs_G.reshape(-1,ngrids).T return mo_pairs_G if gamma_point(kpts): # gamma point, real ao = mydf._numint.eval_ao(cell, coords, kpts[:1])[0] if compact and iden_coeffs(mo_coeffs[0], mo_coeffs[1]): mo = numpy.asarray(lib.dot(mo_coeffs[0].T, ao.T), order='C') npair = nmoi*(nmoi+1)//2 mo_pairs_G = numpy.empty((npair,ngrids), dtype=numpy.complex128) ij = 0 for i in range(nmoi): mo_pairs_G[ij:ij+i+1] = tools.fft(mo[i].conj() * mo[:i+1], mydf.mesh) ij += i + 1 mo_pairs_G = mo_pairs_G.T else: mo_pairs_G = trans(ao, ao) elif is_zero(kpts[0]-kpts[1]): ao = mydf._numint.eval_ao(cell, coords, kpts[:1])[0] mo_pairs_G = trans(ao, ao) else: if q is None: q = kpts[1] - kpts[0] aoi, aoj = mydf._numint.eval_ao(cell, coords, kpts) fac = numpy.exp(-1j * numpy.dot(coords, q)) mo_pairs_G = trans(aoi, aoj, fac) return mo_pairs_G
def get_eri(mydf, kpts=None, compact=False): cell = mydf.cell kptijkl = _format_kpts(kpts) kpti, kptj, kptk, kptl = kptijkl nao = cell.nao_nr() nao_pair = nao * (nao + 1) // 2 q = kptj - kpti coulG = tools.get_coulG(cell, q, gs=mydf.gs) ngs = len(coulG) #################### # gamma point, the integral is real and with s4 symmetry if abs(kptijkl).sum() < 1e-9: ao_pairs_G = get_ao_pairs_G(mydf, kptijkl[:2], q, compact=compact) ao_pairs_G *= numpy.sqrt(coulG).reshape(-1, 1) aoijR = ao_pairs_G.real.copy() aoijI = ao_pairs_G.imag.copy() ao_pairs_G = None eri = lib.dot(aoijR.T, aoijR, cell.vol / ngs**2) eri = lib.dot(aoijI.T, aoijI, cell.vol / ngs**2, eri, 1) return eri #################### # (kpt) i == j == k == l != 0 # (kpt) i == l && j == k && i != j && j != k => # # complex integrals, N^4 elements elif (abs(kpti - kptl).sum() < 1e-9) and (abs(kptj - kptk).sum() < 1e-9): ao_pairs_G = get_ao_pairs_G(mydf, kptijkl[:2], q, compact=False) ao_pairs_G *= numpy.sqrt(coulG).reshape(-1, 1) ao_pairs_invG = ao_pairs_G.T.reshape(nao, nao, -1).transpose(1, 0, 2).conj() ao_pairs_invG = ao_pairs_invG.reshape(-1, ngs) return lib.dot(ao_pairs_G.T, ao_pairs_invG.T, cell.vol / ngs**2) #################### # aosym = s1, complex integrals # else: ao_pairs_G = get_ao_pairs_G(mydf, kptijkl[:2], q, compact=False) # ao_pairs_invG = rho_rs(-G+k_rs) = conj(rho_sr(G+k_sr)).swap(r,s) ao_pairs_invG = get_ao_pairs_G(mydf, -kptijkl[2:], q, compact=False).conj() ao_pairs_G *= coulG.reshape(-1, 1) return lib.dot(ao_pairs_G.T, ao_pairs_invG, cell.vol / ngs**2)
def _Lij_to_Lmn(Lij, basis, ki, kj): if len(basis.shape) == 3: basis = basis[np.newaxis, ...] if len(Lij.shape) == 3: Lij = Lij[np.newaxis, ...] spin, ncells, nlo, nemb = basis.shape nL = Lij.shape[-3] Lmn = np.zeros((spin, nL, nemb, nemb), dtype=np.complex128) Li_n = np.empty((nL * nlo, nemb), dtype=np.complex128) Ln_m = np.empty((nL * nemb, nemb), dtype=np.complex128) for s in range(spin): lib.dot(Lij[s].reshape((nL * nlo, nlo)), basis[s, kj], c=Li_n) lib.dot(np.ascontiguousarray(np.swapaxes(Li_n.reshape((nL, nlo, nemb)), 1, 2).reshape((nL*nemb, nlo))), \ basis[s, ki].conj(), c=Ln_m) Lmn[s] = np.swapaxes(Ln_m.reshape((nL, nemb, nemb)), 1, 2) return Lmn
def get_j_kpts(mydf, dm_kpts, hermi=1, kpts=np.zeros((1, 3)), kpts_band=None): '''Get the Coulomb (J) AO matrix at sampled k-points. Args: dm_kpts : (nkpts, nao, nao) ndarray or a list of (nkpts,nao,nao) ndarray Density matrix at each k-point. If a list of k-point DMs, eg, UHF alpha and beta DM, the alpha and beta DMs are contracted separately. kpts : (nkpts, 3) ndarray Kwargs: kpts_band : (3,) ndarray or (*,3) ndarray A list of arbitrary "band" k-points at which to evalute the matrix. Returns: vj : (nkpts, nao, nao) ndarray or list of vj if the input dm_kpts is a list of DMs ''' cell = mydf.cell mesh = mydf.mesh low_dim_ft_type = mydf.low_dim_ft_type dm_kpts = lib.asarray(dm_kpts, order='C') dms = _format_dms(dm_kpts, kpts) nset, nkpts, nao = dms.shape[:3] coulG = tools.get_coulG(cell, mesh=mesh, low_dim_ft_type=low_dim_ft_type) ngrids = len(coulG) vR = rhoR = np.zeros((nset, ngrids)) for ao_ks_etc, p0, p1 in mydf.aoR_loop(mydf.grids, kpts): ao_ks = ao_ks_etc[0] for k, ao in enumerate(ao_ks): for i in range(nset): rhoR[i, p0:p1] += numint.eval_rho(cell, ao, dms[i, k]) ao = ao_ks = None for i in range(nset): rhoR[i] *= 1. / nkpts rhoG = tools.fft(rhoR[i], mesh) vG = coulG * rhoG vR[i] = tools.ifft(vG, mesh).real kpts_band, input_band = _format_kpts_band(kpts_band, kpts), kpts_band nband = len(kpts_band) weight = cell.vol / ngrids vR *= weight if gamma_point(kpts_band): vj_kpts = np.zeros((nset, nband, nao, nao)) else: vj_kpts = np.zeros((nset, nband, nao, nao), dtype=np.complex128) for ao_ks_etc, p0, p1 in mydf.aoR_loop(mydf.grids, kpts_band): ao_ks = ao_ks_etc[0] for k, ao in enumerate(ao_ks): for i in range(nset): vj_kpts[i, k] += lib.dot(ao.T.conj() * vR[i, p0:p1], ao) return _format_jks(vj_kpts, dm_kpts, input_band, kpts)
def cost_function(self, u=None): if u is None: u = numpy.eye(self.mo_coeff.shape[1]) mo_coeff = lib.dot(self.mo_coeff, u) pop = self.atomic_pops(self.mol, mo_coeff, self.pop_method) if self.exponent == 2: return numpy.einsum('xii,xii->', pop, pop) else: pop2 = numpy.einsum('xii->xi', pop)**2 return numpy.einsum('xi,xi', pop2, pop2)
def ao2mo(self, mo_coeffs, compact=getattr(__config__, 'df_df_DF_ao2mo_compact', True)): if isinstance(mo_coeffs, numpy.ndarray) and mo_coeffs.ndim == 2: mo_coeffs = (mo_coeffs,) * 4 ijmosym, nij_pair, moij, ijslice = _conc_mos(mo_coeffs[0], mo_coeffs[1], compact) klmosym, nkl_pair, mokl, klslice = _conc_mos(mo_coeffs[2], mo_coeffs[3], compact) mo_eri = numpy.zeros((nij_pair,nkl_pair)) sym = (iden_coeffs(mo_coeffs[0], mo_coeffs[2]) and iden_coeffs(mo_coeffs[1], mo_coeffs[3])) Lij = Lkl = None for eri1 in self.loop(): Lij = _ao2mo.nr_e2(eri1, moij, ijslice, aosym='s2', mosym=ijmosym, out=Lij) if sym: Lkl = Lij else: Lkl = _ao2mo.nr_e2(eri1, mokl, klslice, aosym='s2', mosym=klmosym, out=Lkl) lib.dot(Lij.T, Lkl, 1, mo_eri, 1) return mo_eri
def get_eri_2c2e(mydf): from pyscf.gto.ft_ao import ft_ao eriR = 0 kptijkl = numpy.zeros((4, 3)) q = numpy.zeros(3) coulG = mydf.weighted_coulG(q, False, mydf.mesh) Gv, Gvbase, kws = cell.get_Gv_weights(mydf.mesh) ao = ft_ao(cell, Gv) return lib.dot(ao.T * coulG, ao.conj())