def ao2mo(self, mo_coeff=None): nmoa, nmob = self.nmo nao = self.mo_coeff[0].shape[0] naux = self.with_df.get_naoaux() mem_incore = (nmoa**2 * naux + nmob**2 * naux + nao**2 * naux) * 8 / 1e6 mem_now = lib.current_memory()[0] moa = numpy.asarray(mo_coeff[0], order='F') mob = numpy.asarray(mo_coeff[1], order='F') ijslicea = (0, nmoa, 0, nmoa) ijsliceb = (0, nmob, 0, nmob) Lpqa = None Lpqb = None if (mem_incore + mem_now < 0.99 * self.max_memory) or self.mol.incore_anyway: Lpqa = _ao2mo.nr_e2(self.with_df._cderi, moa, ijslicea, aosym='s2', out=Lpqa) Lpqb = _ao2mo.nr_e2(self.with_df._cderi, mob, ijsliceb, aosym='s2', out=Lpqb) return np.asarray( (Lpqa.reshape(naux, nmoa, nmoa), Lpqb.reshape(naux, nmob, nmob))) else: logger.warn(self, 'Memory may not be enough!') raise NotImplementedError
def vind(zs): nz = len(zs) if wfnsym is not None and mol.symmetry: zs = numpy.copy(zs) zs[:,sym_forbid] = 0 dmvo = numpy.empty((2,nz,nao,nao)) for i in range(nz): z = dai * zs[i] za = z[:nocca*nvira].reshape(nvira,nocca) zb = z[nocca*nvira:].reshape(nvirb,noccb) dm = reduce(numpy.dot, (orbva, za, orboa.T)) dmvo[0,i] = dm + dm.T dm = reduce(numpy.dot, (orbvb, zb, orbob.T)) dmvo[1,i] = dm + dm.T v1ao = ni.nr_uks_fxc(mol, mf.grids, mf.xc, dm0, dmvo, 0, 1, rho0, vxc, fxc, max_memory) if self.singlet: vj = mf.get_j(mf.mol, dmvo, hermi=1) v1ao += vj[0] + vj[1] v1a = _ao2mo.nr_e2(v1ao[0], mo_coeff[0], (nocca,nmo,0,nocca)) v1b = _ao2mo.nr_e2(v1ao[1], mo_coeff[1], (noccb,nmo,0,noccb)) hx = numpy.hstack((v1a.reshape(nz,-1), v1b.reshape(nz,-1))) for i, z in enumerate(zs): hx[i] += edai * z hx[i] *= dai return hx
def vind(zs): nz = len(zs) if wfnsym is not None and mol.symmetry: zs = numpy.copy(zs) zs[:, sym_forbid] = 0 dmvo = numpy.empty((2, nz, nao, nao)) for i, z in enumerate(zs): za = z[:nocca * nvira].reshape(nvira, nocca) zb = z[nocca * nvira:].reshape(nvirb, noccb) dmvo[0, i] = reduce(numpy.dot, (orbva, za, orboa.T)) dmvo[1, i] = reduce(numpy.dot, (orbvb, zb, orbob.T)) v1ao = vresp(dmvo) v1a = _ao2mo.nr_e2(v1ao[0], mo_coeff[0], (nocca, nmo, 0, nocca)).reshape(-1, nvira, nocca) v1b = _ao2mo.nr_e2(v1ao[1], mo_coeff[1], (noccb, nmo, 0, noccb)).reshape(-1, nvirb, noccb) for i, z in enumerate(zs): za = z[:nocca * nvira].reshape(nvira, nocca) zb = z[nocca * nvira:].reshape(nvirb, noccb) v1a[i] += numpy.einsum('ai,ai->ai', e_ai_a, za) v1b[i] += numpy.einsum('ai,ai->ai', e_ai_b, zb) hx = numpy.hstack((v1a.reshape(nz, -1), v1b.reshape(nz, -1))) if wfnsym is not None and mol.symmetry: hx[:, sym_forbid] = 0 return hx
def _trans_aapp_(mo, ncore, ncas, fload, ao_loc=None): nmo = mo[0].shape[1] nocc = (ncore[0] + ncas, ncore[1] + ncas) c_nmo = ctypes.c_int(nmo) klshape = (0, nmo, 0, nmo) japcv = numpy.empty((ncas,nmo,ncore[0],nmo-ncore[0])) aapp = numpy.empty((ncas,ncas,nmo,nmo)) aaPP = numpy.empty((ncas,ncas,nmo,nmo)) appa = numpy.empty((ncas,nmo,nmo,ncas)) apPA = numpy.empty((ncas,nmo,nmo,ncas)) apCV = numpy.empty((ncas,nmo,ncore[1],nmo-ncore[1])) ppp = numpy.empty((nmo,nmo,nmo)) for i in range(ncas): buf = _ao2mo.nr_e2(fload(ncore[0]+i), mo[0], klshape, aosym='s4', mosym='s2', ao_loc=ao_loc) lib.unpack_tril(buf, out=ppp) aapp[i] = ppp[ncore[0]:nocc[0]] appa[i] = ppp[:,:,ncore[0]:nocc[0]] #japcp = avcp * 2 - acpv.transpose(0,2,1,3) - avcp.transpose(0,3,2,1) japcv[i] = ppp[:,:ncore[0],ncore[0]:] * 2 \ - ppp[:ncore[0],:,ncore[0]:].transpose(1,0,2) \ - ppp[ncore[0]:,:ncore[0],:].transpose(2,1,0) buf = _ao2mo.nr_e2(fload(ncore[0]+i), mo[1], klshape, aosym='s4', mosym='s2', ao_loc=ao_loc) lib.unpack_tril(buf, out=ppp) aaPP[i] = ppp[ncore[0]:nocc[0]] apPA[i] = ppp[:,:,ncore[1]:nocc[1]] apCV[i] = ppp[:,:ncore[1],ncore[1]:] return aapp, aaPP, appa, apPA, japcv, apCV
def vind(zs): nz = len(zs) if wfnsym is not None and mol.symmetry: zs = numpy.copy(zs) zs[:, sym_forbid] = 0 dmov = numpy.empty((2, nz, nao, nao)) for i, z in enumerate(zs): za = z[:nocca * nvira].reshape(nocca, nvira) zb = z[nocca * nvira:].reshape(noccb, nvirb) dmov[0, i] = reduce(numpy.dot, (orboa, za, orbva.conj().T)) dmov[1, i] = reduce(numpy.dot, (orbob, zb, orbvb.conj().T)) v1ao = vresp(dmov) v1a = _ao2mo.nr_e2(v1ao[0], mo_a, (0, nocca, nocca, nmo)).reshape(-1, nocca, nvira) v1b = _ao2mo.nr_e2(v1ao[1], mo_b, (0, noccb, noccb, nmo)).reshape(-1, noccb, nvirb) for i, z in enumerate(zs): za = z[:nocca * nvira].reshape(nocca, nvira) zb = z[nocca * nvira:].reshape(noccb, nvirb) v1a[i] += numpy.einsum('ia,ia->ia', e_ia_a, za) v1b[i] += numpy.einsum('ia,ia->ia', e_ia_b, zb) hx = numpy.hstack((v1a.reshape(nz, -1), v1b.reshape(nz, -1))) if wfnsym is not None and mol.symmetry: hx[:, sym_forbid] = 0 return hx
def ao2mo(self, mo_coeffs, 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 vind(xys): nz = len(xys) if wfnsym is not None and mol.symmetry: # shape(nz,2,nocc,nvir): 2 ~ X,Y xys = numpy.copy(xys).reshape(nz,2,nocc,nvir) xys[:,:,sym_forbid] = 0 dms = numpy.empty((nz,nao,nao)) for i in range(nz): x, y = xys[i].reshape(2,nocc,nvir) # *2 for double occupancy dmx = reduce(numpy.dot, (orbo, x*2, orbv.T)) dmy = reduce(numpy.dot, (orbv, y.T*2, orbo.T)) dms[i] = dmx + dmy # AX + BY v1ao = vresp(dms) v1ov = _ao2mo.nr_e2(v1ao, mo_coeff, (0,nocc,nocc,nmo)).reshape(-1,nocc,nvir) v1vo = _ao2mo.nr_e2(v1ao, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir,nocc) hx = numpy.empty((nz,2,nocc,nvir), dtype=v1ov.dtype) for i in range(nz): x, y = xys[i].reshape(2,nocc,nvir) hx[i,0] = v1ov[i] hx[i,0]+= numpy.einsum('sp,qs->qp', fvv, x) # AX hx[i,0]-= numpy.einsum('sp,pr->sr', foo, x) # AX hx[i,1] =-v1vo[i].T hx[i,1]-= numpy.einsum('sp,qs->qp', fvv, y) #-AY hx[i,1]+= numpy.einsum('sp,pr->sr', foo, y) #-AY if wfnsym is not None and mol.symmetry: hx[:,:,sym_forbid] = 0 return hx.reshape(nz,-1)
def vind(mo1): mo1aa, mo1ab, mo1ba, mo1bb = _split_mo1(mo1) dm1aa = _dm1_mo2ao(mo1aa, orbva, orboa) dm1ab = _dm1_mo2ao(mo1ab, orbva, orbob) dm1ba = _dm1_mo2ao(mo1ba, orbvb, orboa) dm1bb = _dm1_mo2ao(mo1bb, orbvb, orbob) # imaginary Hermitian dm1 = numpy.vstack([ dm1aa - dm1aa.transpose(0, 2, 1), dm1ab - dm1ba.transpose(0, 2, 1), dm1ba - dm1ab.transpose(0, 2, 1), dm1bb - dm1bb.transpose(0, 2, 1) ]) v1 = vresp(dm1) v1aa = _ao2mo.nr_e2(v1[:nset], mo_va_oa, (0, nvira, nvira, nvira + nocca)) v1ab = _ao2mo.nr_e2(v1[nset * 1:nset * 2], mo_va_ob, (0, nvira, nvira, nvira + noccb)) v1ba = _ao2mo.nr_e2(v1[nset * 2:nset * 3], mo_vb_oa, (0, nvirb, nvirb, nvirb + nocca)) v1bb = _ao2mo.nr_e2(v1[nset * 3:], mo_vb_ob, (0, nvirb, nvirb, nvirb + noccb)) v1aa = v1aa.reshape(nset, nvira, nocca) v1ab = v1ab.reshape(nset, nvira, noccb) v1ba = v1ba.reshape(nset, nvirb, nocca) v1bb = v1bb.reshape(nset, nvirb, noccb) v1aa *= eai_aa v1ab *= eai_ab v1ba *= eai_ba v1bb *= eai_bb v1mo = numpy.hstack((v1aa.reshape(nset, -1), v1ab.reshape(nset, -1), v1ba.reshape(nset, -1), v1bb.reshape(nset, -1))) return v1mo.ravel()
def vind(mo1): mo1aa, mo1ab, mo1ba, mo1bb = _split_mo1(mo1) dm1aa = _dm1_mo2ao(mo1aa, orbva, orboa) dm1ab = _dm1_mo2ao(mo1ab, orbva, orbob) dm1ba = _dm1_mo2ao(mo1ba, orbvb, orboa) dm1bb = _dm1_mo2ao(mo1bb, orbvb, orbob) dm1 = lib.asarray([dm1aa+dm1aa.transpose(0,2,1), dm1ab+dm1ba.transpose(0,2,1), dm1ba+dm1ab.transpose(0,2,1), dm1bb+dm1bb.transpose(0,2,1)]) v1 = vresp(dm1) v1aa = _ao2mo.nr_e2(v1[0], mo_va_oa, (0,nvira,nvira,nvira+nocca)) v1ab = _ao2mo.nr_e2(v1[1], mo_va_ob, (0,nvira,nvira,nvira+noccb)) v1ba = _ao2mo.nr_e2(v1[2], mo_vb_oa, (0,nvirb,nvirb,nvirb+nocca)) v1bb = _ao2mo.nr_e2(v1[3], mo_vb_ob, (0,nvirb,nvirb,nvirb+noccb)) v1aa = v1aa.reshape(nset,nvira,nocca) v1ab = v1ab.reshape(nset,nvira,noccb) v1ba = v1ba.reshape(nset,nvirb,nocca) v1bb = v1bb.reshape(nset,nvirb,noccb) v1aa *= eai_aa v1ab *= eai_ab v1ba *= eai_ba v1bb *= eai_bb v1mo = numpy.hstack((v1aa.reshape(nset,-1), v1ab.reshape(nset,-1), v1ba.reshape(nset,-1), v1bb.reshape(nset,-1))) return v1mo.ravel()
def vind(mo1): mo1aa, mo1ab, mo1ba, mo1bb = _split_mo1(mo1) dm1aa = _dm1_mo2ao(mo1aa, orbva, orboa) dm1ab = _dm1_mo2ao(mo1ab, orbva, orbob) dm1ba = _dm1_mo2ao(mo1ba, orbvb, orboa) dm1bb = _dm1_mo2ao(mo1bb, orbvb, orbob) dm1 = lib.asarray([ dm1aa + dm1aa.transpose(0, 2, 1), dm1ab + dm1ba.transpose(0, 2, 1), dm1ba + dm1ab.transpose(0, 2, 1), dm1bb + dm1bb.transpose(0, 2, 1) ]) v1 = vresp(dm1) v1aa = _ao2mo.nr_e2(v1[0], mo_va_oa, (0, nvira, nvira, nvira + nocca)) v1ab = _ao2mo.nr_e2(v1[1], mo_va_ob, (0, nvira, nvira, nvira + noccb)) v1ba = _ao2mo.nr_e2(v1[2], mo_vb_oa, (0, nvirb, nvirb, nvirb + nocca)) v1bb = _ao2mo.nr_e2(v1[3], mo_vb_ob, (0, nvirb, nvirb, nvirb + noccb)) v1aa = v1aa.reshape(nset, nvira, nocca) v1ab = v1ab.reshape(nset, nvira, noccb) v1ba = v1ba.reshape(nset, nvirb, nocca) v1bb = v1bb.reshape(nset, nvirb, noccb) v1aa *= eai_aa v1ab *= eai_ab v1ba *= eai_ba v1bb *= eai_bb v1mo = numpy.hstack( (v1aa.reshape(nset, -1), v1ab.reshape(nset, -1), v1ba.reshape(nset, -1), v1bb.reshape(nset, -1))) return v1mo.ravel()
def _dtrans(Lpq, Lij, ijmosym, moij, ijslice, Lrs, Lkl, klmosym, mokl, klslice, sym): Lij = _ao2mo.nr_e2(Lpq, moij, ijslice, aosym="s2", mosym=ijmosym, out=Lij) if sym: Lkl = Lij else: Lkl = _ao2mo.nr_e2(Lrs, mokl, klslice, aosym="s2", mosym=klmosym, out=Lkl) return Lij, Lkl
def _dtrans(Lpq, Lij, ijmosym, moij, ijslice, Lrs, Lkl, klmosym, mokl, klslice, sym): Lij = _ao2mo.nr_e2(Lpq, moij, ijslice, aosym='s2', mosym=ijmosym, out=Lij) if sym: Lkl = Lij else: Lkl = _ao2mo.nr_e2(Lrs, mokl, klslice, aosym='s2', mosym=klmosym, out=Lkl) return Lij, Lkl
def vind(mo1): mo1a = mo1.reshape(-1,nova+novb)[:,:nova].reshape(-1,nvira,nocca) mo1b = mo1.reshape(-1,nova+novb)[:,nova:].reshape(-1,nvirb,noccb) nset = mo1a.shape[0] dm1a = _dm1_mo2ao(mo1a, orbva, orboa) dm1b = _dm1_mo2ao(mo1b, orbvb, orbob) dm1 = numpy.vstack([dm1a-dm1a.transpose(0,2,1), dm1b-dm1b.transpose(0,2,1)]) v1 = vresp(dm1) v1a = _ao2mo.nr_e2(v1[ :nset], mo_va_oa, (0,nvira,nvira,nvira+nocca)) v1b = _ao2mo.nr_e2(v1[nset: ], mo_vb_ob, (0,nvirb,nvirb,nvirb+noccb)) v1mo = numpy.hstack((v1a.reshape(nset,-1), v1b.reshape(nset,-1))) return v1mo.ravel()
def vind(mo1): mo1a = mo1.reshape(-1, nova + novb)[:, :nova].reshape(-1, nvira, nocca) mo1b = mo1.reshape(-1, nova + novb)[:, nova:].reshape(-1, nvirb, noccb) nset = mo1a.shape[0] dm1a = _dm1_mo2ao(mo1a, orbva, orboa) dm1b = _dm1_mo2ao(mo1b, orbvb, orbob) dm1 = numpy.asarray( [dm1a - dm1a.transpose(0, 2, 1), dm1b - dm1b.transpose(0, 2, 1)]) v1 = vresp(dm1) v1a = _ao2mo.nr_e2(v1[0], mo_va_oa, (0, nvira, nvira, nvira + nocca)) v1b = _ao2mo.nr_e2(v1[1], mo_vb_ob, (0, nvirb, nvirb, nvirb + noccb)) v1mo = numpy.hstack((v1a.reshape(nset, -1), v1b.reshape(nset, -1))) return v1mo.ravel()
def trans_e1_incore(eri_ao, mo, ncore, ncas): nmo = mo.shape[1] nocc = ncore + ncas eri1 = pyscf.ao2mo.incore.half_e1(eri_ao, (mo,mo[:,:nocc]), compact=False) eri1 = eri1.reshape(nmo,nocc,-1) klppshape = (0, nmo, 0, nmo) klpashape = (0, nmo, ncore, nocc) aapp = numpy.empty((ncas,ncas,nmo,nmo)) for i in range(ncas): _ao2mo.nr_e2(eri1[ncore+i,ncore:nocc], mo, klppshape, aosym='s4', mosym='s1', out=aapp[i]) ppaa = pyscf.lib.transpose(aapp.reshape(ncas*ncas,-1)).reshape(nmo,nmo,ncas,ncas) aapp = None papa = numpy.empty((nmo,ncas,nmo,ncas)) for i in range(nmo): _ao2mo.nr_e2(eri1[i,ncore:nocc], mo, klpashape, aosym='s4', mosym='s1', out=papa[i]) pp = numpy.empty((nmo,nmo)) j_cp = numpy.zeros((ncore,nmo)) k_pc = numpy.zeros((nmo,ncore)) for i in range(ncore): _ao2mo.nr_e2(eri1[i,i:i+1], mo, klppshape, aosym='s4', mosym='s1', out=pp) j_cp[i] = pp.diagonal() j_pc = j_cp.T.copy() pp = numpy.empty((ncore,ncore)) for i in range(nmo): klshape = (i, i+1, 0, ncore) _ao2mo.nr_e2(eri1[i,:ncore], mo, klshape, aosym='s4', mosym='s1', out=pp) k_pc[i] = pp.diagonal() return j_pc, k_pc, ppaa, papa
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_vind(self, zs): '''Compute Ax''' mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ>0).sum() nvir = nmo - nocc orbv = mo_coeff[:,nocc:] orbo = mo_coeff[:,:nocc] nz = len(zs) dmvo = numpy.empty((nz,nao,nao)) for i, z in enumerate(zs): dmvo[i] = reduce(numpy.dot, (orbv, z.reshape(nvir,nocc), orbo.T)) vj, vk = self._scf.get_jk(self.mol, dmvo, hermi=0) if self.singlet: vhf = vj*2 - vk else: vhf = -vk #v1vo = numpy.asarray([reduce(numpy.dot, (orbv.T, v, orbo)) for v in vhf]) v1vo = _ao2mo.nr_e2(vhf, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir*nocc) eai = lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) eai = eai.ravel() for i, z in enumerate(zs): v1vo[i] += eai * z return v1vo.reshape(nz,-1)
def get_vind(self, zs): '''Compute Ax''' mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ > 0).sum() nvir = nmo - nocc orbv = mo_coeff[:, nocc:] orbo = mo_coeff[:, :nocc] nz = len(zs) dmvo = numpy.empty((nz, nao, nao)) for i, z in enumerate(zs): dmvo[i] = reduce(numpy.dot, (orbv, z.reshape(nvir, nocc), orbo.T)) vj, vk = self._scf.get_jk(self.mol, dmvo, hermi=0) if self.singlet: vhf = vj * 2 - vk else: vhf = -vk #v1vo = numpy.asarray([reduce(numpy.dot, (orbv.T, v, orbo)) for v in vhf]) v1vo = _ao2mo.nr_e2(vhf, mo_coeff, (nocc, nmo, 0, nocc)).reshape(-1, nvir * nocc) eai = lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) eai = eai.ravel() for i, z in enumerate(zs): v1vo[i] += eai * z return v1vo.reshape(nz, -1)
def get_vind(self, zs): mol = self.mol mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ>0).sum() nvir = nmo - nocc orbv = mo_coeff[:,nocc:] orbo = mo_coeff[:,:nocc] eai = pyscf.lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) dai = numpy.sqrt(eai).ravel() nz = len(zs) dmvo = numpy.empty((nz,nao,nao)) for i, z in enumerate(zs): dm = reduce(numpy.dot, (orbv, (dai*z).reshape(nvir,nocc), orbo.T)) dmvo[i] = dm + dm.T # +cc for A+B and K_{ai,jb} in A == K_{ai,bj} in B mem_now = pyscf.lib.current_memory()[0] max_memory = max(2000, self.max_memory*.9-mem_now) v1ao = _contract_xc_kernel(self, self._scf.xc, dmvo, singlet=self.singlet, max_memory=max_memory) if self.singlet: vj = self._scf.get_j(mol, dmvo, hermi=1) v1ao += vj * 2 v1vo = _ao2mo.nr_e2(v1ao, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir*nocc) edai = eai.ravel() * dai for i, z in enumerate(zs): # numpy.sqrt(eai) * (eai*dai*z + v1vo) v1vo[i] += edai*z v1vo[i] *= dai return v1vo.reshape(nz,-1)
def vind(mo1): dm1 = _dm1_mo2ao(mo1.reshape(nset,nvir,nocc), orbv, orbo*2) # *2 for double occupancy dm1 = dm1 + dm1.transpose(0,2,1) v1 = vresp(dm1) v1 = _ao2mo.nr_e2(v1, mo_v_o, (0,nvir,nvir,nmo)).reshape(nset,nvir,nocc) v1 *= eai return v1.ravel()
def get_vind(self, zs): mol = self.mol mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ>0).sum() nvir = nmo - nocc orbv = mo_coeff[:,nocc:] orbo = mo_coeff[:,:nocc] eai = lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) dai = numpy.sqrt(eai).ravel() nz = len(zs) dmvo = numpy.empty((nz,nao,nao)) for i, z in enumerate(zs): dm = reduce(numpy.dot, (orbv, (dai*z).reshape(nvir,nocc), orbo.T)) dmvo[i] = dm + dm.T # +cc for A+B and K_{ai,jb} in A == K_{ai,bj} in B mem_now = lib.current_memory()[0] max_memory = max(2000, self.max_memory*.9-mem_now) v1ao = _contract_xc_kernel(self, self._scf.xc, dmvo, singlet=self.singlet, max_memory=max_memory) if self.singlet: vj = self._scf.get_j(mol, dmvo, hermi=1) v1ao += vj * 2 v1vo = _ao2mo.nr_e2(v1ao, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir*nocc) edai = eai.ravel() * dai for i, z in enumerate(zs): # numpy.sqrt(eai) * (eai*dai*z + v1vo) v1vo[i] += edai*z v1vo[i] *= dai return v1vo.reshape(nz,-1)
def _trans(mo, ncore, ncas, fload, cvcv=None, ao_loc=None): nao, nmo = mo.shape nocc = ncore + ncas nvir = nmo - nocc nav = nmo - ncore if cvcv is None: cvcv = numpy.zeros((ncore*nvir,ncore*nvir)) pacv = numpy.empty((nmo,ncas,ncore*nvir)) aapp = numpy.empty((ncas,ncas,nmo*nmo)) papa = numpy.empty((nmo,ncas,nmo*ncas)) vcv = numpy.empty((nav,ncore*nvir)) apa = numpy.empty((ncas,nmo*ncas)) vpa = numpy.empty((nav,nmo*ncas)) app = numpy.empty((ncas,nmo*nmo)) for i in range(ncore): buf = fload(i, i+1) klshape = (0, ncore, nocc, nmo) _ao2mo.nr_e2(buf, mo, klshape, aosym='s4', mosym='s1', out=vcv, ao_loc=ao_loc) cvcv[i*nvir:(i+1)*nvir] = vcv[ncas:] pacv[i] = vcv[:ncas] klshape = (0, nmo, ncore, nocc) _ao2mo.nr_e2(buf[:ncas], mo, klshape, aosym='s4', mosym='s1', out=apa, ao_loc=ao_loc) papa[i] = apa for i in range(ncas): buf = fload(ncore+i, ncore+i+1) klshape = (0, ncore, nocc, nmo) _ao2mo.nr_e2(buf, mo, klshape, aosym='s4', mosym='s1', out=vcv, ao_loc=ao_loc) pacv[ncore:,i] = vcv klshape = (0, nmo, ncore, nocc) _ao2mo.nr_e2(buf, mo, klshape, aosym='s4', mosym='s1', out=vpa, ao_loc=ao_loc) papa[ncore:,i] = vpa klshape = (0, nmo, 0, nmo) _ao2mo.nr_e2(buf[:ncas], mo, klshape, aosym='s4', mosym='s1', out=app, ao_loc=ao_loc) aapp[i] = app #pyscf.lib.transpose(aapp.reshape(ncas**2, -1), inplace=True) ppaa = pyscf.lib.transpose(aapp.reshape(ncas**2,-1)) return (ppaa.reshape(nmo,nmo,ncas,ncas), papa.reshape(nmo,ncas,nmo,ncas), pacv.reshape(nmo,ncas,ncore,nvir), cvcv)
def get_vind(self, xys): ''' [ A B][X] [-B -A][Y] ''' mol = self.mol mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ > 0).sum() nvir = nmo - nocc orbv = mo_coeff[:, nocc:] orbo = mo_coeff[:, :nocc] nz = len(xys) dms = numpy.empty((nz * 2, nao, nao)) for i in range(nz): x, y = xys[i].reshape(2, nvir, nocc) dmx = reduce(numpy.dot, (orbv, x, orbo.T)) dmy = reduce(numpy.dot, (orbv, y, orbo.T)) dms[i] = dmx + dmy.T # AX + BY dms[i + nz] = dms[i].T # = dmy + dmx.T # AY + BX hyb = self._scf._numint.hybrid_coeff(self._scf.xc, spin=(mol.spin > 0) + 1) if abs(hyb) > 1e-10: vj, vk = self._scf.get_jk(self.mol, dms, hermi=0) if self.singlet: veff = vj * 2 - hyb * vk else: veff = -hyb * vk else: if self.singlet: vj = self._scf.get_j(self.mol, dms, hermi=1) veff = vj * 2 else: veff = numpy.zeros((nz * 2, nao, nao)) mem_now = pyscf.lib.current_memory()[0] max_memory = max(2000, self.max_memory * .9 - mem_now) v1xc = _contract_xc_kernel(self, self._scf.xc, dms[:nz], singlet=self.singlet, max_memory=max_memory) veff[:nz] += v1xc veff[nz:] += v1xc veff = _ao2mo.nr_e2(veff, mo_coeff, (nocc, nmo, 0, nocc)).reshape(-1, nvir * nocc) eai = pyscf.lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) eai = eai.ravel() for i, z in enumerate(xys): x, y = z.reshape(2, -1) veff[i] += eai * x # AX veff[i + nz] += eai * y # AY hx = numpy.hstack((veff[:nz], -veff[nz:])) return hx.reshape(nz, -1)
def loop_ao2mo(self, mo_coeff, nocc): mo = numpy.asarray(mo_coeff, order='F') nmo = mo.shape[1] ijslice = (0, nocc, nocc, nmo) Lov = None for eri1 in self._scf.with_df.loop(): Lov = _ao2mo.nr_e2(eri1, mo, ijslice, aosym='s2', out=Lov) yield Lov
def _trans_aapp_(mo, ncore, ncas, fload, ao_loc=None): nmo = mo[0].shape[1] nocc = (ncore[0] + ncas, ncore[1] + ncas) c_nmo = ctypes.c_int(nmo) funpack = pyscf.lib.numpy_helper._np_helper.NPdunpack_tril klshape = (0, nmo, 0, nmo) japcv = numpy.empty((ncas, nmo, ncore[0], nmo - ncore[0])) aapp = numpy.empty((ncas, ncas, nmo, nmo)) aaPP = numpy.empty((ncas, ncas, nmo, nmo)) appa = numpy.empty((ncas, nmo, nmo, ncas)) apPA = numpy.empty((ncas, nmo, nmo, ncas)) apCV = numpy.empty((ncas, nmo, ncore[1], nmo - ncore[1])) ppp = numpy.empty((nmo, nmo, nmo)) for i in range(ncas): buf = _ao2mo.nr_e2(fload(ncore[0] + i), mo[0], klshape, aosym='s4', mosym='s2', ao_loc=ao_loc) for j in range(nmo): funpack(c_nmo, buf[j].ctypes.data_as(ctypes.c_void_p), ppp[j].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(1)) aapp[i] = ppp[ncore[0]:nocc[0]] appa[i] = ppp[:, :, ncore[0]:nocc[0]] #japcp = avcp * 2 - acpv.transpose(0,2,1,3) - avcp.transpose(0,3,2,1) japcv[i] = ppp[:,:ncore[0],ncore[0]:] * 2 \ - ppp[:ncore[0],:,ncore[0]:].transpose(1,0,2) \ - ppp[ncore[0]:,:ncore[0],:].transpose(2,1,0) buf = _ao2mo.nr_e2(fload(ncore[0] + i), mo[1], klshape, aosym='s4', mosym='s2', ao_loc=ao_loc) for j in range(nmo): funpack(c_nmo, buf[j].ctypes.data_as(ctypes.c_void_p), ppp[j].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(1)) aaPP[i] = ppp[ncore[0]:nocc[0]] apPA[i] = ppp[:, :, ncore[1]:nocc[1]] apCV[i] = ppp[:, :ncore[1], ncore[1]:] return aapp, aaPP, appa, apPA, japcv, apCV
def ao2mo(self, mo_coeffs, 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 _trans(mo, ncore, ncas, fload, cvcv=None, ao_loc=None): nao, nmo = mo.shape nocc = ncore + ncas nvir = nmo - nocc nav = nmo - ncore if cvcv is None: cvcv = numpy.zeros((ncore*nvir,ncore*nvir)) pacv = numpy.empty((nmo,ncas,ncore*nvir)) aapp = numpy.empty((ncas,ncas,nmo*nmo)) papa = numpy.empty((nmo,ncas,nmo*ncas)) vcv = numpy.empty((nav,ncore*nvir)) apa = numpy.empty((ncas,nmo*ncas)) vpa = numpy.empty((nav,nmo*ncas)) app = numpy.empty((ncas,nmo*nmo)) for i in range(ncore): buf = fload(i, i+1) klshape = (0, ncore, nocc, nmo) _ao2mo.nr_e2(buf, mo, klshape, aosym='s4', mosym='s1', out=vcv, ao_loc=ao_loc) cvcv[i*nvir:(i+1)*nvir] = vcv[ncas:] pacv[i] = vcv[:ncas] klshape = (0, nmo, ncore, nocc) _ao2mo.nr_e2(buf[:ncas], mo, klshape, aosym='s4', mosym='s1', out=apa, ao_loc=ao_loc) papa[i] = apa for i in range(ncas): buf = fload(ncore+i, ncore+i+1) klshape = (0, ncore, nocc, nmo) _ao2mo.nr_e2(buf, mo, klshape, aosym='s4', mosym='s1', out=vcv, ao_loc=ao_loc) pacv[ncore:,i] = vcv klshape = (0, nmo, ncore, nocc) _ao2mo.nr_e2(buf, mo, klshape, aosym='s4', mosym='s1', out=vpa, ao_loc=ao_loc) papa[ncore:,i] = vpa klshape = (0, nmo, 0, nmo) _ao2mo.nr_e2(buf[:ncas], mo, klshape, aosym='s4', mosym='s1', out=app, ao_loc=ao_loc) aapp[i] = app ppaa = lib.transpose(aapp.reshape(ncas**2,-1)) return (ppaa.reshape(nmo,nmo,ncas,ncas), papa.reshape(nmo,ncas,nmo,ncas), pacv.reshape(nmo,ncas,ncore,nvir), cvcv)
def get_int3c_mo(mol, auxmol, mo_coeff, compact=getattr(__config__, 'df_df_DF_ao2mo_compact', True), max_memory=None): ''' Evaluate (P|uv) c_ui c_vj -> (P|ij) Args: mol: gto.Mole auxmol: gto.Mole, contains auxbasis mo_coeff: ndarray, list, or tuple containing MO coefficients if two ndarrays mo_coeff = (mo0, mo1) are provided, mo0 and mo1 are used for the two AO dimensions Kwargs: compact: bool If true, will return only unique ERIs along the two MO dimensions. Does nothing if mo_coeff contains two different sets of orbitals. max_memory: int Maximum memory consumption in MB Returns: int3c: ndarray of shape (naux, nmo0, nmo1) or (naux, nmo*(nmo+1)//2) ''' nao, naux, nbas, nauxbas = mol.nao, auxmol.nao, mol.nbas, auxmol.nbas npair = nao * (nao + 1) // 2 if max_memory is None: max_memory = mol.max_memory # Separate mo_coeff if isinstance(mo_coeff, np.ndarray) and mo_coeff.ndim == 2: mo0 = mo1 = mo_coeff else: mo0, mo1 = mo_coeff[0], mo_coeff[1] nmo0, nmo1 = mo0.shape[-1], mo1.shape[-1] mosym, nmo_pair, mo_conc, mo_slice = _conc_mos(mo0, mo1, compact=compact) # (P|uv) -> (P|ij) get_int3c = _int3c_wrapper(mol, auxmol, 'int3c2e', 's2ij') int3c = np.zeros((naux, nmo_pair), dtype=mo0.dtype) max_memory -= lib.current_memory()[0] blksize = int(min(max(max_memory * 1e6 / 8 / (npair * 2), 20), 240)) aux_loc = auxmol.ao_loc aux_ranges = balance_partition(aux_loc, blksize) for shl0, shl1, nL in aux_ranges: int3c_ao = get_int3c((0, nbas, 0, nbas, shl0, shl1)) # (uv|P) p0, p1 = aux_loc[shl0], aux_loc[shl1] int3c_ao = int3c_ao.T # is apparently stored f-contiguous but in the actual memory order I need, so just transpose int3c[p0:p1] = _ao2mo.nr_e2(int3c_ao, mo_conc, mo_slice, aosym='s2', mosym=mosym, out=int3c[p0:p1]) int3c_ao = None # Shape and return if 's1' in mosym: int3c = int3c.reshape(naux, nmo0, nmo1) return int3c
def _trans_cvcv_(mo, ncore, ncas, fload, ao_loc=None): nmo = mo[0].shape[1] c_nmo = ctypes.c_int(nmo) jc_pp = numpy.empty((ncore[0], nmo, nmo)) jc_PP = numpy.zeros((nmo, nmo)) kc_pp = numpy.empty((ncore[0], nmo, nmo)) jcvcv = numpy.zeros((ncore[0], nmo - ncore[0], ncore[0], nmo - ncore[0])) cvCV = numpy.empty((ncore[0], nmo - ncore[0], ncore[1], nmo - ncore[1])) vcp = numpy.empty((nmo - ncore[0], ncore[0], nmo)) cpp = numpy.empty((ncore[0], nmo, nmo)) for i in range(ncore[0]): buf = fload(i) klshape = (0, ncore[1], ncore[1], nmo) _ao2mo.nr_e2(buf[ncore[0]:nmo], mo[1], klshape, aosym='s4', mosym='s1', out=cvCV[i], ao_loc=ao_loc) klshape = (0, nmo, 0, nmo) tmp = _ao2mo.nr_e2(buf[i:i + 1], mo[1], klshape, aosym='s4', mosym='s1', ao_loc=ao_loc) jc_PP += tmp.reshape(nmo, nmo) klshape = (0, ncore[0], 0, nmo) _ao2mo.nr_e2(buf[ncore[0]:nmo], mo[0], klshape, aosym='s4', mosym='s1', out=vcp, ao_loc=ao_loc) kc_pp[i, ncore[0]:] = vcp[:, i] klshape = (0, nmo, 0, nmo) _ao2mo.nr_e2(buf[:ncore[0]], mo[0], klshape, aosym='s4', mosym='s2', out=buf[:ncore[0]], ao_loc=ao_loc) lib.unpack_tril(buf[:ncore[0]], out=cpp) jc_pp[i] = cpp[i] kc_pp[i, :ncore[0]] = cpp[:, i] #jcvcv = cvcv * 2 - cvcv.transpose(2,1,0,3) - ccvv.transpose(0,2,1,3) jcvcv[i] = vcp[:,:,ncore[0]:] * 2 \ - vcp[:,:,ncore[0]:].transpose(2,1,0) \ - cpp[:,ncore[0]:,ncore[0]:].transpose(1,0,2) return jc_pp, jc_PP, kc_pp, jcvcv, cvCV
def vind(xys): nz = len(xys) if wfnsym is not None and mol.symmetry: # shape(nz,2,-1): 2 ~ X,Y xys = numpy.copy(xys).reshape(nz, 2, -1) xys[:, :, sym_forbid] = 0 dms = numpy.empty((2, nz, nao, nao)) # 2 ~ alpha,beta for i in range(nz): x, y = xys[i].reshape(2, -1) xa = x[:nocca * nvira].reshape(nocca, nvira) xb = x[nocca * nvira:].reshape(noccb, nvirb) ya = y[:nocca * nvira].reshape(nocca, nvira) yb = y[nocca * nvira:].reshape(noccb, nvirb) dmx = reduce(numpy.dot, (orboa, xa, orbva.T)) dmy = reduce(numpy.dot, (orbva, ya.T, orboa.T)) dms[0, i] = dmx + dmy # AX + BY dmx = reduce(numpy.dot, (orbob, xb, orbvb.T)) dmy = reduce(numpy.dot, (orbvb, yb.T, orbob.T)) dms[1, i] = dmx + dmy # AX + BY v1ao = vresp(dms) v1avo = _ao2mo.nr_e2(v1ao[0], mo_a, (nocca, nmo, 0, nocca)) v1bvo = _ao2mo.nr_e2(v1ao[1], mo_b, (noccb, nmo, 0, noccb)) v1aov = _ao2mo.nr_e2(v1ao[0], mo_a, (0, nocca, nocca, nmo)) v1bov = _ao2mo.nr_e2(v1ao[1], mo_b, (0, noccb, noccb, nmo)) hx = numpy.empty((nz, 2, nvira * nocca + nvirb * noccb), dtype=v1avo.dtype) for i in range(nz): x, y = xys[i].reshape(2, -1) hx[i, 0, :nvira * nocca] = v1aov[i].ravel() hx[i, 0, nvira * nocca:] = v1bov[i].ravel() hx[i, 0] += e_ia * x # AX hx[i, 1, :nvira * nocca] = -v1avo[i].reshape(nvira, nocca).T.ravel() hx[i, 1, nvira * nocca:] = -v1bvo[i].reshape(nvirb, noccb).T.ravel() hx[i, 1] -= e_ia * y #-AY if wfnsym is not None and mol.symmetry: hx[:, :, sym_forbid] = 0 return hx.reshape(nz, -1)
def get_vind(self, xys): ''' [ A B][X] [-B -A][Y] ''' mol = self.mol mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ>0).sum() nvir = nmo - nocc orbv = mo_coeff[:,nocc:] orbo = mo_coeff[:,:nocc] nz = len(xys) dms = numpy.empty((nz*2,nao,nao)) for i in range(nz): x, y = xys[i].reshape(2,nvir,nocc) dmx = reduce(numpy.dot, (orbv, x, orbo.T)) dmy = reduce(numpy.dot, (orbv, y, orbo.T)) dms[i ] = dmx + dmy.T # AX + BY dms[i+nz] = dms[i].T # = dmy + dmx.T # AY + BX hyb = self._scf._numint.hybrid_coeff(self._scf.xc, spin=(mol.spin>0)+1) if abs(hyb) > 1e-10: vj, vk = self._scf.get_jk(self.mol, dms, hermi=0) if self.singlet: veff = vj * 2 - hyb * vk else: veff = -hyb * vk else: if self.singlet: vj = self._scf.get_j(self.mol, dms, hermi=1) veff = vj * 2 else: veff = numpy.zeros((nz*2,nao,nao)) mem_now = pyscf.lib.current_memory()[0] max_memory = max(2000, self.max_memory*.9-mem_now) v1xc = _contract_xc_kernel(self, self._scf.xc, dms[:nz], singlet=self.singlet, max_memory=max_memory) veff[:nz] += v1xc veff[nz:] += v1xc veff = _ao2mo.nr_e2(veff, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir*nocc) eai = pyscf.lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) eai = eai.ravel() for i, z in enumerate(xys): x, y = z.reshape(2,-1) veff[i ] += eai * x # AX veff[i+nz] += eai * y # AY hx = numpy.hstack((veff[:nz], -veff[nz:])) return hx.reshape(nz,-1)
def _init_df_eris(cc, eris): from pyscf.pbc.df import df from pyscf.ao2mo import _ao2mo if cc._scf.with_df._cderi is None: cc._scf.with_df.build() cell = cc._scf.cell if cell.dimension == 2: # 2D ERIs are not positive definite. The 3-index tensors are stored in # two part. One corresponds to the positive part and one corresponds # to the negative part. The negative part is not considered in the # DF-driven CCSD implementation. raise NotImplementedError nocc = cc.nocc nmo = cc.nmo nvir = nmo - nocc nao = cell.nao_nr() kpts = cc.kpts nkpts = len(kpts) naux = cc._scf.with_df.get_naoaux() if gamma_point(kpts): dtype = np.double else: dtype = np.complex128 dtype = np.result_type(dtype, *eris.mo_coeff) eris.Lpv = Lpv = np.empty((nkpts, nkpts), dtype=object) with h5py.File(cc._scf.with_df._cderi, 'r') as f: kptij_lst = f['j3c-kptij'].value tao = [] ao_loc = None for ki, kpti in enumerate(kpts): for kj, kptj in enumerate(kpts): kpti_kptj = np.array((kpti, kptj)) Lpq = np.asarray(df._getitem(f, 'j3c', kpti_kptj, kptij_lst)) mo = np.hstack((eris.mo_coeff[ki], eris.mo_coeff[kj][:, nocc:])) mo = np.asarray(mo, dtype=dtype, order='F') if dtype == np.double: out = _ao2mo.nr_e2(Lpq, mo, (0, nmo, nmo, nmo + nvir), aosym='s2') else: #Note: Lpq.shape[0] != naux if linear dependency is found in auxbasis if Lpq[0].size != nao**2: # aosym = 's2' Lpq = lib.unpack_tril(Lpq).astype(np.complex128) out = _ao2mo.r_e2(Lpq, mo, (0, nmo, nmo, nmo + nvir), tao, ao_loc) Lpv[ki, kj] = out.reshape(-1, nmo, nvir) return eris
def _trans_aapp_(mo, ncore, ncas, fload, ao_loc=None): nmo = mo[0].shape[1] nocc = (ncore[0] + ncas, ncore[1] + ncas) c_nmo = ctypes.c_int(nmo) funpack = pyscf.lib.numpy_helper._np_helper.NPdunpack_tril klshape = (0, nmo, 0, nmo) japcv = numpy.empty((ncas,nmo,ncore[0],nmo-ncore[0])) aapp = numpy.empty((ncas,ncas,nmo,nmo)) aaPP = numpy.empty((ncas,ncas,nmo,nmo)) appa = numpy.empty((ncas,nmo,nmo,ncas)) apPA = numpy.empty((ncas,nmo,nmo,ncas)) apCV = numpy.empty((ncas,nmo,ncore[1],nmo-ncore[1])) ppp = numpy.empty((nmo,nmo,nmo)) for i in range(ncas): buf = _ao2mo.nr_e2(fload(ncore[0]+i), mo[0], klshape, aosym='s4', mosym='s2', ao_loc=ao_loc) for j in range(nmo): funpack(c_nmo, buf[j].ctypes.data_as(ctypes.c_void_p), ppp[j].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(1)) aapp[i] = ppp[ncore[0]:nocc[0]] appa[i] = ppp[:,:,ncore[0]:nocc[0]] #japcp = avcp * 2 - acpv.transpose(0,2,1,3) - avcp.transpose(0,3,2,1) japcv[i] = ppp[:,:ncore[0],ncore[0]:] * 2 \ - ppp[:ncore[0],:,ncore[0]:].transpose(1,0,2) \ - ppp[ncore[0]:,:ncore[0],:].transpose(2,1,0) buf = _ao2mo.nr_e2(fload(ncore[0]+i), mo[1], klshape, aosym='s4', mosym='s2', ao_loc=ao_loc) for j in range(nmo): funpack(c_nmo, buf[j].ctypes.data_as(ctypes.c_void_p), ppp[j].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(1)) aaPP[i] = ppp[ncore[0]:nocc[0]] apPA[i] = ppp[:,:,ncore[1]:nocc[1]] apCV[i] = ppp[:,:ncore[1],ncore[1]:] return aapp, aaPP, appa, apPA, japcv, apCV
def vind(zs): nz = len(zs) if wfnsym is not None and mol.symmetry: zs = numpy.copy(zs) zs[:,sym_forbid] = 0 dmov = numpy.empty((2,nz,nao,nao)) for i in range(nz): z = d_ia * zs[i] za = z[:nocca*nvira].reshape(nocca,nvira) zb = z[nocca*nvira:].reshape(noccb,nvirb) dm = reduce(numpy.dot, (orboa, za, orbva.T)) dmov[0,i] = dm + dm.T dm = reduce(numpy.dot, (orbob, zb, orbvb.T)) dmov[1,i] = dm + dm.T v1ao = vresp(dmov) v1a = _ao2mo.nr_e2(v1ao[0], mo_coeff[0], (0,nocca,nocca,nmo)) v1b = _ao2mo.nr_e2(v1ao[1], mo_coeff[1], (0,noccb,noccb,nmo)) hx = numpy.hstack((v1a.reshape(nz,-1), v1b.reshape(nz,-1))) for i, z in enumerate(zs): hx[i] += ed_ia * z hx[i] *= d_ia return hx
def vind(zs): nz = len(zs) dmov = numpy.empty((nz,nao,nao)) for i, z in enumerate(zs): # *2 for double occupancy dm = reduce(numpy.dot, (orbo, (d_ia*z).reshape(nocc,nvir)*2, orbv.T)) dmov[i] = dm + dm.T # +cc for A+B and K_{ai,jb} in A == K_{ai,bj} in B v1ao = vresp(dmov) v1ov = _ao2mo.nr_e2(v1ao, mo_coeff, (0,nocc,nocc,nmo)).reshape(-1,nocc*nvir) for i, z in enumerate(zs): # numpy.sqrt(e_ia) * (e_ia*d_ia*z + v1ov) v1ov[i] += ed_ia*z v1ov[i] *= d_ia return v1ov.reshape(nz,-1)
def vind(zs): nz = len(zs) if wfnsym is not None and mol.symmetry: zs = numpy.copy(zs) zs[:, sym_forbid] = 0 dmov = numpy.empty((2, nz, nao, nao)) for i in range(nz): z = d_ia * zs[i] za = z[:nocca * nvira].reshape(nocca, nvira) zb = z[nocca * nvira:].reshape(noccb, nvirb) dm = reduce(numpy.dot, (orboa, za, orbva.T)) dmov[0, i] = dm + dm.T dm = reduce(numpy.dot, (orbob, zb, orbvb.T)) dmov[1, i] = dm + dm.T v1ao = vresp(dmov) v1a = _ao2mo.nr_e2(v1ao[0], mo_coeff[0], (0, nocca, nocca, nmo)) v1b = _ao2mo.nr_e2(v1ao[1], mo_coeff[1], (0, noccb, noccb, nmo)) hx = numpy.hstack((v1a.reshape(nz, -1), v1b.reshape(nz, -1))) for i, z in enumerate(zs): hx[i] += ed_ia * z hx[i] *= d_ia return hx
def vind(zs): nz = len(zs) dmvo = numpy.empty((nz,nao,nao)) for i, z in enumerate(zs): # *2 for double occupancy dm = reduce(numpy.dot, (orbv, (dai*z).reshape(nvir,nocc)*2, orbo.T)) dmvo[i] = dm + dm.T # +cc for A+B and K_{ai,jb} in A == K_{ai,bj} in B v1ao = vresp(dmvo) v1vo = _ao2mo.nr_e2(v1ao, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir*nocc) for i, z in enumerate(zs): # numpy.sqrt(eai) * (eai*dai*z + v1vo) v1vo[i] += edai*z v1vo[i] *= dai return v1vo.reshape(nz,-1)
def loop_ao2mo(self, mo_coeff, nocc): mo = numpy.asarray(mo_coeff, order='F') nmo = mo.shape[1] ijslice = (0, nocc, nocc, nmo) Lov = None with_df = self.with_df nvir = nmo - nocc naux = with_df.get_naoaux() mem_now = lib.current_memory()[0] max_memory = max(2000, self.max_memory*.9-mem_now) blksize = int(min(naux, max(with_df.blockdim, (max_memory*1e6/8-nocc*nvir**2*2)/(nocc*nvir)))) for eri1 in with_df.loop(blksize=blksize): Lov = _ao2mo.nr_e2(eri1, mo, ijslice, aosym='s2', out=Lov) yield Lov
def ao2mo(self, mo_coeff=None): if mo_coeff is None: mo_coeff = self.mo_coeff nmo = self.nmo nao = self.mo_coeff.shape[0] naux = self.with_df.get_naoaux() mem_incore = (2*nmo**2*naux) * 8/1e6 mem_now = lib.current_memory()[0] mo = numpy.asarray(mo_coeff, order='F') ijslice = (0, nmo, 0, nmo) Lpq = None if (mem_incore + mem_now < 0.99*self.max_memory) or self.mol.incore_anyway: Lpq = _ao2mo.nr_e2(self.with_df._cderi, mo, ijslice, aosym='s2', out=Lpq) return Lpq.reshape(naux,nmo,nmo) else: logger.warn(self, 'Memory may not be enough!') raise NotImplementedError
def vind(zs): nz = len(zs) if wfnsym is not None and mol.symmetry: zs = numpy.copy(zs).reshape(-1,nocc,nvir) zs[:,sym_forbid] = 0 dmov = numpy.empty((nz,nao,nao)) for i, z in enumerate(zs): # *2 for double occupancy dmov[i] = reduce(numpy.dot, (orbo, z.reshape(nocc,nvir)*2, orbv.conj().T)) v1ao = vresp(dmov) #v1ov = numpy.asarray([reduce(numpy.dot, (orbo.T, v, orbv)) for v in v1ao]) v1ov = _ao2mo.nr_e2(v1ao, mo_coeff, (0,nocc,nocc,nmo)).reshape(-1,nocc,nvir) for i, z in enumerate(zs): v1ov[i]+= numpy.einsum('sp,qs->qp', fvv, z.reshape(nocc,nvir)) v1ov[i]-= numpy.einsum('sp,pr->sr', foo, z.reshape(nocc,nvir)) if wfnsym is not None and mol.symmetry: v1ov[:,sym_forbid] = 0 return v1ov.reshape(nz,-1)
def _exact_paaa(self, mo, u, out=None): if self.with_df: nmo = mo.shape[1] ncore = self.ncore ncas = self.ncas nocc = ncore + ncas mo1 = numpy.dot(mo, u) mo1_cas = mo1[:,ncore:nocc] paaa = numpy.zeros((nmo*ncas,ncas*ncas)) moij = numpy.asarray(numpy.hstack((mo1, mo1_cas)), order='F') ijshape = (0, nmo, nmo, nmo+ncas) for eri1 in self.with_df.loop(): bufpa = _ao2mo.nr_e2(eri1, moij, ijshape, 's2', 's1') bufaa = numpy.asarray(buf1[ncore:nocc,:], order='C') pyscf.lib.dot(bufpa.T, bufaa, 1, paaa, 1) return paaa.reshape(nmo,ncas,ncas,ncas) else: return casscf_class._exact_paaa(self, mol, u, out)
def _trans_cvcv_(mo, ncore, ncas, fload, ao_loc=None): nmo = mo[0].shape[1] c_nmo = ctypes.c_int(nmo) funpack = pyscf.lib.numpy_helper._np_helper.NPdunpack_tril jc_pp = numpy.empty((ncore[0],nmo,nmo)) jc_PP = numpy.zeros((nmo,nmo)) kc_pp = numpy.empty((ncore[0],nmo,nmo)) jcvcv = numpy.zeros((ncore[0],nmo-ncore[0],ncore[0],nmo-ncore[0])) cvCV = numpy.empty((ncore[0],nmo-ncore[0],ncore[1],nmo-ncore[1])) vcp = numpy.empty((nmo-ncore[0],ncore[0],nmo)) cpp = numpy.empty((ncore[0],nmo,nmo)) for i in range(ncore[0]): buf = fload(i) klshape = (0, ncore[1], ncore[1], nmo) _ao2mo.nr_e2(buf[ncore[0]:nmo], mo[1], klshape, aosym='s4', mosym='s1', out=cvCV[i], ao_loc=ao_loc) klshape = (0, nmo, 0, nmo) tmp = _ao2mo.nr_e2(buf[i:i+1], mo[1], klshape, aosym='s4', mosym='s1', ao_loc=ao_loc) jc_PP += tmp.reshape(nmo,nmo) klshape = (0, ncore[0], 0, nmo) _ao2mo.nr_e2(buf[ncore[0]:nmo], mo[0], klshape, aosym='s4', mosym='s1', out=vcp, ao_loc=ao_loc) kc_pp[i,ncore[0]:] = vcp[:,i] klshape = (0, nmo, 0, nmo) _ao2mo.nr_e2(buf[:ncore[0]], mo[0], klshape, aosym='s4', mosym='s2', out=buf[:ncore[0]], ao_loc=ao_loc) for j in range(ncore[0]): funpack(c_nmo, buf[j].ctypes.data_as(ctypes.c_void_p), cpp[j].ctypes.data_as(ctypes.c_void_p), ctypes.c_int(1)) jc_pp[i] = cpp[i] kc_pp[i,:ncore[0]] = cpp[:,i] #jcvcv = cvcv * 2 - cvcv.transpose(2,1,0,3) - ccvv.transpose(0,2,1,3) jcvcv[i] = vcp[:,:,ncore[0]:] * 2 \ - vcp[:,:,ncore[0]:].transpose(2,1,0) \ - cpp[:,ncore[0]:,ncore[0]:].transpose(1,0,2) return jc_pp, jc_PP, kc_pp, jcvcv, cvCV
def get_vind(self, zs): '''Compute Ax''' mol = self.mol mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ>0).sum() nvir = nmo - nocc orbv = mo_coeff[:,nocc:] orbo = mo_coeff[:,:nocc] nz = len(zs) dmvo = numpy.empty((nz,nao,nao)) for i, z in enumerate(zs): dmvo[i] = reduce(numpy.dot, (orbv, z.reshape(nvir,nocc), orbo.T)) mem_now = pyscf.lib.current_memory()[0] max_memory = max(2000, self.max_memory*.9-mem_now) v1ao = _contract_xc_kernel(self, self._scf.xc, dmvo, singlet=self.singlet, max_memory=max_memory) hyb = self._scf._numint.hybrid_coeff(self._scf.xc, spin=(mol.spin>0)+1) if abs(hyb) > 1e-10: vj, vk = self._scf.get_jk(self.mol, dmvo, hermi=0) if self.singlet: v1ao += vj * 2 - hyb * vk else: v1ao += -hyb * vk else: if self.singlet: vj = self._scf.get_j(self.mol, dmvo, hermi=1) v1ao += vj * 2 v1vo = _ao2mo.nr_e2(v1ao, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir*nocc) eai = pyscf.lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) eai = eai.ravel() for i, z in enumerate(zs): v1vo[i] += eai * z return v1vo.reshape(nz,-1)
def _add_vvVV(mycc, t1, t2ab, eris, out=None): '''Ht2 = np.einsum('iJcD,acBD->iJaB', t2ab, vvVV) without using symmetry in t2ab or Ht2 ''' time0 = time.clock(), time.time() if t2ab.size == 0: return np.zeros_like(t2ab) if t1 is not None: t2ab = make_tau_ab(t2ab, t1, t1) log = logger.Logger(mycc.stdout, mycc.verbose) nocca, noccb, nvira, nvirb = t2ab.shape if mycc.direct: # AO direct CCSD if getattr(eris, 'mo_coeff', None) is not None: mo_a, mo_b = eris.mo_coeff else: moidxa, moidxb = mycc.get_frozen_mask() mo_a = mycc.mo_coeff[0][:,moidxa] mo_b = mycc.mo_coeff[1][:,moidxb] # Note tensor t2ab may be t2bbab from eom_uccsd code. In that # particular case, nocca, noccb do not equal to the actual number of # alpha/beta occupied orbitals. orbva and orbvb cannot be indexed as # mo_a[:,nocca:] and mo_b[:,noccb:] orbva = mo_a[:,-nvira:] orbvb = mo_b[:,-nvirb:] tau = lib.einsum('ijab,pa->ijpb', t2ab, orbva) tau = lib.einsum('ijab,pb->ijap', tau, orbvb) time0 = logger.timer_debug1(mycc, 'vvvv-tau mo2ao', *time0) buf = eris._contract_vvVV_t2(mycc, tau, mycc.direct, out, log) mo = np.asarray(np.hstack((orbva, orbvb)), order='F') Ht2 = _ao2mo.nr_e2(buf.reshape(nocca*noccb,-1), mo.conj(), (0,nvira,nvira,nvira+nvirb), 's1', 's1') return Ht2.reshape(t2ab.shape) else: return eris._contract_vvVV_t2(mycc, t2ab, mycc.direct, out, log)
def get_vind(self, xys): ''' [ A B][X] [-B -A][Y] ''' mo_coeff = self._scf.mo_coeff mo_energy = self._scf.mo_energy nao, nmo = mo_coeff.shape nocc = (self._scf.mo_occ>0).sum() nvir = nmo - nocc orbv = mo_coeff[:,nocc:] orbo = mo_coeff[:,:nocc] nz = len(xys) dms = numpy.empty((nz*2,nao,nao)) for i in range(nz): x, y = xys[i].reshape(2,nvir,nocc) dmx = reduce(numpy.dot, (orbv, x, orbo.T)) dmy = reduce(numpy.dot, (orbv, y, orbo.T)) dms[i ] = dmx + dmy.T # AX + BY dms[i+nz] = dms[i].T # = dmy + dmx.T # AY + BX vj, vk = self._scf.get_jk(self.mol, dms, hermi=0) if self.singlet: vhf = vj*2 - vk else: vhf = -vk #vhf = numpy.asarray([reduce(numpy.dot, (orbv.T, v, orbo)) for v in vhf]) vhf = _ao2mo.nr_e2(vhf, mo_coeff, (nocc,nmo,0,nocc)).reshape(-1,nvir*nocc) eai = lib.direct_sum('a-i->ai', mo_energy[nocc:], mo_energy[:nocc]) eai = eai.ravel() for i, z in enumerate(xys): x, y = z.reshape(2,-1) vhf[i ] += eai * x # AX vhf[i+nz] += eai * y # AY hx = numpy.hstack((vhf[:nz], -vhf[nz:])) return hx.reshape(nz,-1)
def trans_e1_outcore(mol, mo, ncore, ncas, erifile, max_memory=None, level=1, verbose=logger.WARN): time0 = (time.clock(), time.time()) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(mol.stdout, verbose) log.debug1('trans_e1_outcore level %d max_memory %d', level, max_memory) nao, nmo = mo.shape nao_pair = nao*(nao+1)//2 nocc = ncore + ncas _tmpfile1 = tempfile.NamedTemporaryFile() faapp_buf = h5py.File(_tmpfile1.name) feri = h5py.File(erifile, 'w') mo_c = numpy.asarray(mo, order='C') mo = numpy.asarray(mo, order='F') pashape = (0, nmo, ncore, nocc) papa_buf = numpy.zeros((nao,ncas,nmo*ncas)) j_pc = numpy.zeros((nmo,ncore)) k_pc = numpy.zeros((nmo,ncore)) mem_words = int(max(2000,max_memory-papa_buf.nbytes/1e6)*1e6/8) aobuflen = mem_words//(nao_pair+nocc*nmo) + 1 ao_loc = numpy.array(mol.ao_loc_nr(), dtype=numpy.int32) shranges = outcore.guess_shell_ranges(mol, True, aobuflen, None, ao_loc) ao2mopt = _ao2mo.AO2MOpt(mol, 'cint2e_sph', 'CVHFnr_schwarz_cond', 'CVHFsetnr_direct_scf') nstep = len(shranges) paapp = 0 maxbuflen = max([x[2] for x in shranges]) log.debug('mem_words %.8g MB, maxbuflen = %d', mem_words*8/1e6, maxbuflen) bufs1 = numpy.empty((maxbuflen, nao_pair)) bufs2 = numpy.empty((maxbuflen, nmo*ncas)) if level == 1: bufs3 = numpy.empty((maxbuflen, nao*ncore)) log.debug('mem cache %.8g MB', (bufs1.nbytes+bufs2.nbytes+bufs3.nbytes)/1e6) else: log.debug('mem cache %.8g MB', (bufs1.nbytes+bufs2.nbytes)/1e6) ti0 = log.timer('Initializing trans_e1_outcore', *time0) # fmmm, ftrans, fdrv for level 1 fmmm = _fpointer('MCSCFhalfmmm_nr_s2_ket') ftrans = _fpointer('AO2MOtranse1_nr_s4') fdrv = getattr(libmcscf, 'AO2MOnr_e2_drv') for istep,sh_range in enumerate(shranges): log.debug('[%d/%d], AO [%d:%d], len(buf) = %d', istep+1, nstep, *sh_range) buf = bufs1[:sh_range[2]] _ao2mo.nr_e1fill('cint2e_sph', sh_range, mol._atm, mol._bas, mol._env, 's4', 1, ao2mopt, buf) if log.verbose >= logger.DEBUG1: ti1 = log.timer('AO integrals buffer', *ti0) bufpa = bufs2[:sh_range[2]] _ao2mo.nr_e1(buf, mo, pashape, 's4', 's1', out=bufpa) # jc_pp, kc_pp if level == 1: # ppaa, papa and vhf, jcp, kcp if log.verbose >= logger.DEBUG1: ti1 = log.timer('buffer-pa', *ti1) buf1 = bufs3[:sh_range[2]] fdrv(ftrans, fmmm, buf1.ctypes.data_as(ctypes.c_void_p), buf.ctypes.data_as(ctypes.c_void_p), mo.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(sh_range[2]), ctypes.c_int(nao), ctypes.c_int(0), ctypes.c_int(nao), ctypes.c_int(0), ctypes.c_int(ncore), ctypes.POINTER(ctypes.c_void_p)(), ctypes.c_int(0)) p0 = 0 for ij in range(sh_range[0], sh_range[1]): i,j = _ao2mo._extract_pair(ij) i0 = ao_loc[i] j0 = ao_loc[j] i1 = ao_loc[i+1] j1 = ao_loc[j+1] di = i1 - i0 dj = j1 - j0 if i == j: dij = di * (di+1) // 2 buf = numpy.empty((di,di,nao*ncore)) idx = numpy.tril_indices(di) buf[idx] = buf1[p0:p0+dij] buf[idx[1],idx[0]] = buf1[p0:p0+dij] buf = buf.reshape(di,di,nao,ncore) mo1 = mo_c[i0:i1] tmp = numpy.einsum('uvpc,pc->uvc', buf, mo[:,:ncore]) tmp = pyscf.lib.dot(mo1.T, tmp.reshape(di,-1)) j_pc += numpy.einsum('vp,pvc->pc', mo1, tmp.reshape(nmo,di,ncore)) tmp = numpy.einsum('uvpc,uc->vcp', buf, mo1[:,:ncore]) tmp = pyscf.lib.dot(tmp.reshape(-1,nmo), mo).reshape(di,ncore,nmo) k_pc += numpy.einsum('vp,vcp->pc', mo1, tmp) else: dij = di * dj buf = buf1[p0:p0+dij].reshape(di,dj,nao,ncore) mo1 = mo_c[i0:i1] mo2 = mo_c[j0:j1] tmp = numpy.einsum('uvpc,pc->uvc', buf, mo[:,:ncore]) tmp = pyscf.lib.dot(mo1.T, tmp.reshape(di,-1)) j_pc += numpy.einsum('vp,pvc->pc', mo2, tmp.reshape(nmo,dj,ncore)) * 2 tmp = numpy.einsum('uvpc,uc->vcp', buf, mo1[:,:ncore]) tmp = pyscf.lib.dot(tmp.reshape(-1,nmo), mo).reshape(dj,ncore,nmo) k_pc += numpy.einsum('vp,vcp->pc', mo2, tmp) tmp = numpy.einsum('uvpc,vc->ucp', buf, mo2[:,:ncore]) tmp = pyscf.lib.dot(tmp.reshape(-1,nmo), mo).reshape(di,ncore,nmo) k_pc += numpy.einsum('up,ucp->pc', mo1, tmp) p0 += dij if log.verbose >= logger.DEBUG1: ti1 = log.timer('j_cp and k_cp', *ti1) if log.verbose >= logger.DEBUG1: ti1 = log.timer('half transformation of the buffer', *ti1) # ppaa, papa faapp_buf[str(istep)] = \ bufpa.reshape(sh_range[2],nmo,ncas)[:,ncore:nocc].reshape(-1,ncas**2).T p0 = 0 for ij in range(sh_range[0], sh_range[1]): i,j = _ao2mo._extract_pair(ij) i0 = ao_loc[i] j0 = ao_loc[j] i1 = ao_loc[i+1] j1 = ao_loc[j+1] di = i1 - i0 dj = j1 - j0 if i == j: dij = di * (di+1) // 2 buf1 = numpy.empty((di,di,nmo*ncas)) idx = numpy.tril_indices(di) buf1[idx] = bufpa[p0:p0+dij] buf1[idx[1],idx[0]] = bufpa[p0:p0+dij] else: dij = di * dj buf1 = bufpa[p0:p0+dij].reshape(di,dj,-1) mo1 = mo[j0:j1,ncore:nocc].copy() for i in range(di): pyscf.lib.dot(mo1.T, buf1[i], 1, papa_buf[i0+i], 1) mo1 = mo[i0:i1,ncore:nocc].copy() buf1 = pyscf.lib.dot(mo1.T, buf1.reshape(di,-1)) papa_buf[j0:j1] += buf1.reshape(ncas,dj,-1).transpose(1,0,2) p0 += dij if log.verbose >= logger.DEBUG1: ti1 = log.timer('ppaa and papa buffer', *ti1) ti0 = log.timer('gen AO/transform MO [%d/%d]'%(istep+1,nstep), *ti0) buf = buf1 = bufpa = None bufs1 = bufs2 = bufs3 = None time1 = log.timer('mc_ao2mo pass 1', *time0) log.debug1('Half transformation done. Current memory %d', pyscf.lib.current_memory()[0]) nblk = int(max(8, min(nmo, (max_memory*1e6/8-papa_buf.size)/(ncas**2*nmo)))) log.debug1('nblk for papa = %d', nblk) dset = feri.create_dataset('papa', (nmo,ncas,nmo,ncas), 'f8') for i0, i1 in prange(0, nmo, nblk): tmp = pyscf.lib.dot(mo[:,i0:i1].T, papa_buf.reshape(nao,-1)) dset[i0:i1] = tmp.reshape(i1-i0,ncas,nmo,ncas) papa_buf = tmp = None time1 = log.timer('papa pass 2', *time1) tmp = numpy.empty((ncas**2,nao_pair)) p0 = 0 for istep, sh_range in enumerate(shranges): tmp[:,p0:p0+sh_range[2]] = faapp_buf[str(istep)] p0 += sh_range[2] nblk = int(max(8, min(nmo, (max_memory*1e6/8-tmp.size)/(ncas**2*nmo)-1))) log.debug1('nblk for ppaa = %d', nblk) dset = feri.create_dataset('ppaa', (nmo,nmo,ncas,ncas), 'f8') for i0, i1 in prange(0, nmo, nblk): tmp1 = _ao2mo.nr_e2(tmp, mo, (i0,i1,0,nmo), 's4', 's1', ao_loc=ao_loc) tmp1 = tmp1.reshape(ncas,ncas,i1-i0,nmo) for j in range(i1-i0): dset[i0+j] = tmp1[:,:,j].transpose(2,0,1) tmp = tmp1 = None time1 = log.timer('ppaa pass 2', *time1) faapp_buf.close() feri.close() _tmpfile1 = None time0 = log.timer('mc_ao2mo', *time0) return j_pc, k_pc
def general(eri_ao, mo_coeffs, verbose=0, compact=True, **kwargs): r'''For the given four sets of orbitals, transfer the 8-fold or 4-fold 2e AO integrals to MO integrals. Args: eri_ao : ndarray AO integrals, can be either 8-fold or 4-fold symmetry. mo_coeffs : 4-item list of ndarray Four sets of orbital coefficients, corresponding to the four indices of (ij|kl) Kwargs: verbose : int Print level compact : bool When compact is True, depending on the four oribital sets, the returned MO integrals has (up to 4-fold) permutation symmetry. If it's False, the function will abandon any permutation symmetry, and return the "plain" MO integrals Returns: 2D array of transformed MO integrals. The MO integrals may or may not have the permutation symmetry, depending on the given orbitals, and the kwargs compact. If the four sets of orbitals are identical, the MO integrals will at most have 4-fold symmetry. Examples: >>> from pyscf import gto >>> from pyscf.scf import _vhf >>> from pyscf import ao2mo >>> mol = gto.M(atom='O 0 0 0; H 0 1 0; H 0 0 1', basis='sto3g') >>> eri = mol.intor('int2e_sph', aosym='s8') >>> mo1 = numpy.random.random((mol.nao_nr(), 10)) >>> mo2 = numpy.random.random((mol.nao_nr(), 8)) >>> mo3 = numpy.random.random((mol.nao_nr(), 6)) >>> mo4 = numpy.random.random((mol.nao_nr(), 4)) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo3,mo4)) >>> print(eri1.shape) (80, 24) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo3,mo3)) >>> print(eri1.shape) (80, 21) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo3,mo3), compact=False) >>> print(eri1.shape) (80, 36) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo1,mo2,mo2)) >>> print(eri1.shape) (55, 36) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo1,mo2)) >>> print(eri1.shape) (80, 80) ''' log = logger.new_logger(sys, verbose) nao = mo_coeffs[0].shape[0] nao_pair = nao*(nao+1)//2 if eri_ao.size == nao**4: return lib.einsum('pqrs,pi,qj,rk,sl->ijkl', eri_ao.reshape([nao]*4), mo_coeffs[0].conj(), mo_coeffs[1], mo_coeffs[2].conj(), mo_coeffs[3]) # transform e1 eri1 = half_e1(eri_ao, mo_coeffs, compact) klmosym, nkl_pair, mokl, klshape = _conc_mos(mo_coeffs[2], mo_coeffs[3], compact) if eri1.shape[0] == 0 or nkl_pair == 0: # 0 dimension causes error in certain BLAS implementations return numpy.zeros((eri1.shape[0],nkl_pair)) # if nij_pair > nkl_pair: # log.warn('low efficiency for AO to MO trans!') # transform e2 eri1 = _ao2mo.nr_e2(eri1, mokl, klshape, aosym='s4', mosym=klmosym) return eri1
def general(mol, mo_coeffs, erifile, auxbasis='weigend+etb', dataname='eri_mo', tmpdir=None, int3c='cint3c2e_sph', aosym='s2ij', int2c='cint2c2e_sph', comp=1, max_memory=2000, ioblk_size=256, verbose=0, compact=True): ''' Transform ij of (ij|L) to MOs. ''' assert(aosym in ('s1', 's2ij')) time0 = (time.clock(), time.time()) if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(mol.stdout, verbose) swapfile = tempfile.NamedTemporaryFile(dir=tmpdir) cholesky_eri_b(mol, swapfile.name, auxbasis, dataname, int3c, aosym, int2c, comp, ioblk_size, verbose=log) fswap = h5py.File(swapfile.name, 'r') time1 = log.timer('AO->MO eri transformation 1 pass', *time0) nmoi = mo_coeffs[0].shape[1] nmoj = mo_coeffs[1].shape[1] nao = mo_coeffs[0].shape[0] auxmol = incore.format_aux_basis(mol, auxbasis) naoaux = auxmol.nao_nr() aosym = _stand_sym_code(aosym) if aosym == 's1': nao_pair = nao * nao aosym_as_nr_e2 = 's1' else: nao_pair = nao * (nao+1) // 2 aosym_as_nr_e2 = 's2kl' ijmosym, nij_pair, moij, ijshape = \ ao2mo.incore._conc_mos(mo_coeffs[0], mo_coeffs[1], compact and aosym != 's1') if h5py.is_hdf5(erifile): feri = h5py.File(erifile) if dataname in feri: del(feri[dataname]) else: feri = h5py.File(erifile, 'w') if comp == 1: chunks = (min(int(64e3/nmoj),naoaux), nmoj) # 512K h5d_eri = feri.create_dataset(dataname, (naoaux,nij_pair), 'f8', chunks=chunks) else: chunks = (1, min(int(64e3/nmoj),naoaux), nmoj) # 512K h5d_eri = feri.create_dataset(dataname, (comp,naoaux,nij_pair), 'f8', chunks=chunks) aopairblks = len(fswap[dataname+'/0']) iolen = min(int(ioblk_size*1e6/8/(nao_pair+nij_pair)), naoaux) totstep = (naoaux+iolen-1)//iolen * comp buf = numpy.empty((iolen, nao_pair)) ti0 = time1 for icomp in range(comp): istep = 0 for row0, row1 in prange(0, naoaux, iolen): nrow = row1 - row0 istep += 1 log.debug('step 2 [%d/%d], [%d,%d:%d], row = %d', istep, totstep, icomp, row0, row1, nrow) col0 = 0 for ic in range(aopairblks): dat = fswap['%s/%d/%d'%(dataname,icomp,ic)] col1 = col0 + dat.shape[1] buf[:nrow,col0:col1] = dat[row0:row1] col0 = col1 buf1 = _ao2mo.nr_e2(buf[:nrow], moij, ijshape, aosym_as_nr_e2, ijmosym) if comp == 1: h5d_eri[row0:row1] = buf1 else: h5d_eri[icomp,row0:row1] = buf1 ti0 = log.timer('step 2 [%d/%d], [%d,%d:%d], row = %d'% (istep, totstep, icomp, row0, row1, nrow), *ti0) fswap.close() feri.close() log.timer('AO->MO CD eri transformation 2 pass', *time1) log.timer('AO->MO CD eri transformation', *time0) return erifile
def general(eri_ao, mo_coeffs, verbose=0, compact=True): r'''For the given four sets of orbitals, transfer the 8-fold or 4-fold 2e AO integrals to MO integrals. Args: eri_ao : ndarray AO integrals, can be either 8-fold or 4-fold symmetry. mo_coeffs : 4-item list of ndarray Four sets of orbital coefficients, corresponding to the four indices of (ij|kl) Kwargs: verbose : int Print level compact : bool When compact is True, depending on the four oribital sets, the returned MO integrals has (up to 4-fold) permutation symmetry. If it's False, the function will abandon any permutation symmetry, and return the "plain" MO integrals Returns: 2D array of transformed MO integrals. The MO integrals may or may not have the permutation symmetry, depending on the given orbitals, and the kwargs compact. If the four sets of orbitals are identical, the MO integrals will at most have 4-fold symmetry. Examples: >>> from pyscf import gto >>> from pyscf.scf import _vhf >>> from pyscf import ao2mo >>> mol = gto.M(atom='O 0 0 0; H 0 1 0; H 0 0 1', basis='sto3g') >>> eri = _vhf.int2e_sph(mol._atm, mol._bas, mol._env) >>> mo1 = numpy.random.random((mol.nao_nr(), 10)) >>> mo2 = numpy.random.random((mol.nao_nr(), 8)) >>> mo3 = numpy.random.random((mol.nao_nr(), 6)) >>> mo4 = numpy.random.random((mol.nao_nr(), 4)) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo3,mo4)) >>> print(eri1.shape) (80, 24) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo3,mo3)) >>> print(eri1.shape) (80, 21) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo3,mo3), compact=False) >>> print(eri1.shape) (80, 36) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo1,mo2,mo2)) >>> print(eri1.shape) (55, 36) >>> eri1 = ao2mo.incore.general(eri, (mo1,mo2,mo1,mo2)) >>> print(eri1.shape) (80, 80) ''' if isinstance(verbose, logger.Logger): log = verbose else: log = logger.Logger(sys.stdout, verbose) nao = mo_coeffs[0].shape[0] nao_pair = nao*(nao+1)//2 assert(eri_ao.size in (nao_pair**2, nao_pair*(nao_pair+1)//2)) # transform e1 eri1 = half_e1(eri_ao, mo_coeffs, compact) klmosym, nkl_pair, mokl, klshape = _conc_mos(mo_coeffs[2], mo_coeffs[3], compact) if eri1.shape[0] == 0 or nkl_pair == 0: # 0 dimension sometimes causes blas problem return numpy.zeros((nij_pair,nkl_pair)) # if nij_pair > nkl_pair: # log.warn('low efficiency for AO to MO trans!') # transform e2 eri1 = _ao2mo.nr_e2(eri1, mokl, klshape, aosym='s4', mosym=klmosym) return eri1
def __init__(self, cc, mo_coeff=None, method='incore'): cput0 = (time.clock(), time.time()) moidx = numpy.ones(cc.mo_occ.size, dtype=numpy.bool) if isinstance(cc.frozen, (int, numpy.integer)): moidx[:cc.frozen] = False elif len(cc.frozen) > 0: moidx[numpy.asarray(cc.frozen)] = False if mo_coeff is None: self.mo_coeff = mo_coeff = cc.mo_coeff[:,moidx] else: self.mo_coeff = mo_coeff = mo_coeff[:,moidx] dm = cc._scf.make_rdm1(cc.mo_coeff, cc.mo_occ) fockao = cc._scf.get_hcore() + cc._scf.get_veff(cc.mol, dm) self.fock = reduce(numpy.dot, (mo_coeff.T, fockao, mo_coeff)) nocc = cc.nocc nmo = cc.nmo nvir = nmo - nocc mem_incore, mem_outcore, mem_basic = _mem_usage(nocc, nvir) mem_now = lib.current_memory()[0] log = logger.Logger(cc.stdout, cc.verbose) if hasattr(cc._scf, 'with_df') and cc._scf.with_df: #log.warn('CCSD detected DF being bound to the HF object. ' # 'MO integrals are computed based on the DF 3-tensor integrals.\n' # 'You can switch to dfccsd.CCSD for the DF-CCSD implementation') nvir_pair = nvir * (nvir+1) // 2 oooo = numpy.zeros((nocc*nocc,nocc*nocc)) ooov = numpy.zeros((nocc*nocc,nocc*nvir)) ovoo = numpy.zeros((nocc*nvir,nocc*nocc)) oovv = numpy.zeros((nocc*nocc,nvir*nvir)) ovov = numpy.zeros((nocc*nvir,nocc*nvir)) ovvv = numpy.zeros((nocc*nvir,nvir_pair)) vvvv = numpy.zeros((nvir_pair,nvir_pair)) mo = numpy.asarray(mo_coeff, order='F') nmo = mo.shape[1] ijslice = (0, nmo, 0, nmo) Lpq = None for eri1 in cc._scf.with_df.loop(): Lpq = _ao2mo.nr_e2(eri1, mo, ijslice, aosym='s2', out=Lpq).reshape(-1,nmo,nmo) Loo = Lpq[:,:nocc,:nocc].reshape(-1,nocc**2) Lov = Lpq[:,:nocc,nocc:].reshape(-1,nocc*nvir) Lvv = Lpq[:,nocc:,nocc:].reshape(-1,nvir**2) lib.ddot(Loo.T, Loo, 1, oooo, 1) lib.ddot(Loo.T, Lov, 1, ooov, 1) lib.ddot(Lov.T, Loo, 1, ovoo, 1) lib.ddot(Loo.T, Lvv, 1, oovv, 1) lib.ddot(Lov.T, Lov, 1, ovov, 1) Lvv = lib.pack_tril(Lvv.reshape(-1,nvir,nvir)) lib.ddot(Lov.T, Lvv, 1, ovvv, 1) lib.ddot(Lvv.T, Lvv, 1, vvvv, 1) _tmpfile1 = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) self.feri1 = feri1 = h5py.File(_tmpfile1.name) def __del__feri1(self): feri1.close() self.feri1.__del__ = __del__feri1 self.feri1['oooo'] = oooo.reshape(nocc,nocc,nocc,nocc) self.feri1['ooov'] = ooov.reshape(nocc,nocc,nocc,nvir) self.feri1['ovoo'] = ovoo.reshape(nocc,nvir,nocc,nocc) self.feri1['oovv'] = oovv.reshape(nocc,nocc,nvir,nvir) self.feri1['ovov'] = ovov.reshape(nocc,nvir,nocc,nvir) self.feri1['ovvv'] = ovvv.reshape(nocc,nvir,nvir_pair) self.feri1['vvvv'] = vvvv.reshape(nvir_pair,nvir_pair) self.oooo = self.feri1['oooo'] self.ooov = self.feri1['ooov'] self.ovoo = self.feri1['ovoo'] self.oovv = self.feri1['oovv'] self.ovov = self.feri1['ovov'] self.ovvv = self.feri1['ovvv'] self.vvvv = self.feri1['vvvv'] elif (method == 'incore' and cc._scf._eri is not None and (mem_incore+mem_now < cc.max_memory) or cc.mol.incore_anyway): eri1 = ao2mo.incore.full(cc._scf._eri, mo_coeff) #:eri1 = ao2mo.restore(1, eri1, nmo) #:self.oooo = eri1[:nocc,:nocc,:nocc,:nocc].copy() #:self.ooov = eri1[:nocc,:nocc,:nocc,nocc:].copy() #:self.ovoo = eri1[:nocc,nocc:,:nocc,:nocc].copy() #:self.oovv = eri1[:nocc,:nocc,nocc:,nocc:].copy() #:self.ovov = eri1[:nocc,nocc:,:nocc,nocc:].copy() #:ovvv = eri1[:nocc,nocc:,nocc:,nocc:].copy() #:self.ovvv = numpy.empty((nocc,nvir,nvir*(nvir+1)//2)) #:for i in range(nocc): #: for j in range(nvir): #: self.ovvv[i,j] = lib.pack_tril(ovvv[i,j]) #:self.vvvv = ao2mo.restore(4, eri1[nocc:,nocc:,nocc:,nocc:], nvir) nvir_pair = nvir * (nvir+1) // 2 self.oooo = numpy.empty((nocc,nocc,nocc,nocc)) self.ooov = numpy.empty((nocc,nocc,nocc,nvir)) self.ovoo = numpy.empty((nocc,nvir,nocc,nocc)) self.oovv = numpy.empty((nocc,nocc,nvir,nvir)) self.ovov = numpy.empty((nocc,nvir,nocc,nvir)) self.ovvv = numpy.empty((nocc,nvir,nvir_pair)) self.vvvv = numpy.empty((nvir_pair,nvir_pair)) ij = 0 outbuf = numpy.empty((nmo,nmo,nmo)) for i in range(nocc): buf = lib.unpack_tril(eri1[ij:ij+i+1], out=outbuf[:i+1]) for j in range(i+1): self.oooo[i,j] = self.oooo[j,i] = buf[j,:nocc,:nocc] self.ooov[i,j] = self.ooov[j,i] = buf[j,:nocc,nocc:] self.oovv[i,j] = self.oovv[j,i] = buf[j,nocc:,nocc:] ij += i + 1 ij1 = 0 for i in range(nocc,nmo): buf = lib.unpack_tril(eri1[ij:ij+i+1], out=outbuf[:i+1]) self.ovoo[:,i-nocc] = buf[:nocc,:nocc,:nocc] self.ovov[:,i-nocc] = buf[:nocc,:nocc,nocc:] for j in range(nocc): self.ovvv[j,i-nocc] = lib.pack_tril(_cp(buf[j,nocc:,nocc:])) for j in range(nocc, i+1): self.vvvv[ij1] = lib.pack_tril(_cp(buf[j,nocc:,nocc:])) ij1 += 1 ij += i + 1 else: cput1 = time.clock(), time.time() _tmpfile1 = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) _tmpfile2 = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) self.feri1 = feri1 = h5py.File(_tmpfile1.name) def __del__feri1(self): feri1.close() self.feri1.__del__ = __del__feri1 orbo = mo_coeff[:,:nocc] orbv = mo_coeff[:,nocc:] nvpair = nvir * (nvir+1) // 2 self.oooo = self.feri1.create_dataset('oooo', (nocc,nocc,nocc,nocc), 'f8') self.ooov = self.feri1.create_dataset('ooov', (nocc,nocc,nocc,nvir), 'f8') self.ovoo = self.feri1.create_dataset('ovoo', (nocc,nvir,nocc,nocc), 'f8') self.oovv = self.feri1.create_dataset('oovv', (nocc,nocc,nvir,nvir), 'f8') self.ovov = self.feri1.create_dataset('ovov', (nocc,nvir,nocc,nvir), 'f8') self.ovvv = self.feri1.create_dataset('ovvv', (nocc,nvir,nvpair), 'f8') fsort = _ccsd.libcc.CCsd_sort_inplace nocc_pair = nocc*(nocc+1)//2 nvir_pair = nvir*(nvir+1)//2 def sort_inplace(eri): fsort(eri.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(nocc), ctypes.c_int(nvir), ctypes.c_int(eri.shape[0])) vv = eri[:,:nvir_pair] oo = eri[:,nvir_pair:nvir_pair+nocc_pair] ov = eri[:,nvir_pair+nocc_pair:].reshape(-1,nocc,nvir) return oo, ov, vv buf = numpy.empty((nmo,nmo,nmo)) def save_occ_frac(i, p0, p1, eri): oo, ov, vv = sort_inplace(eri) self.oooo[i,p0:p1] = lib.unpack_tril(oo, out=buf) self.ooov[i,p0:p1] = ov self.oovv[i,p0:p1] = lib.unpack_tril(vv, out=buf) def save_vir_frac(i, p0, p1, eri): oo, ov, vv = sort_inplace(eri) self.ovoo[i,p0:p1] = lib.unpack_tril(oo, out=buf) self.ovov[i,p0:p1] = ov self.ovvv[i,p0:p1] = vv if not cc.direct: max_memory = max(2000,cc.max_memory-lib.current_memory()[0]) self.feri2 = feri2 = h5py.File(_tmpfile2.name) def __del__feri2(self): feri2.close() self.feri2.__del__ = __del__feri2 ao2mo.full(cc.mol, orbv, self.feri2, max_memory=max_memory, verbose=log) self.vvvv = self.feri2['eri_mo'] cput1 = log.timer_debug1('transforming vvvv', *cput1) tmpfile3 = tempfile.NamedTemporaryFile(dir=lib.param.TMPDIR) with h5py.File(tmpfile3.name, 'w') as feri: max_memory = max(2000, cc.max_memory-lib.current_memory()[0]) mo = numpy.hstack((orbv, orbo)) ao2mo.general(cc.mol, (orbo,mo,mo,mo), feri, max_memory=max_memory, verbose=log) cput1 = log.timer_debug1('transforming oppp', *cput1) blksize = max(1, int(min(8e9,max_memory*.5e6)/8/nmo**2)) handler = None for i in range(nocc): for p0, p1 in lib.prange(0, nvir, blksize): eri = _cp(feri['eri_mo'][i*nmo+p0:i*nmo+p1]) handler = async_do(handler, save_vir_frac, i, p0, p1, eri) for p0, p1 in lib.prange(0, nocc, blksize): eri = _cp(feri['eri_mo'][i*nmo+nvir+p0:i*nmo+nvir+p1]) handler = async_do(handler, save_occ_frac, i, p0, p1, eri) cput1 = log.timer_debug1('sorting %d'%i, *cput1) if handler is not None: handler.join() for key in feri.keys(): del(feri[key]) log.timer('CCSD integral transformation', *cput0)
def add_wvvVV_(self, t1, t2, eris, t2new_tril): time0 = time.clock(), time.time() nocc, nvir = t1.shape #: tau = t2 + numpy.einsum('ia,jb->ijab', t1, t1) #: t2new += numpy.einsum('ijcd,acdb->ijab', tau, vvvv) def contract_rec_(t2new_tril, tau, eri, i0, i1, j0, j1): nao = tau.shape[-1] ic = i1 - i0 jc = j1 - j0 #: t2tril[:,j0:j1] += numpy.einsum('xcd,cdab->xab', tau[:,i0:i1], eri) _dgemm('N', 'N', nocc*(nocc+1)//2, jc*nao, ic*nao, tau.reshape(-1,nao*nao), eri.reshape(-1,jc*nao), t2new_tril.reshape(-1,nao*nao), 1, 1, i0*nao, 0, j0*nao) #: t2tril[:,i0:i1] += numpy.einsum('xcd,abcd->xab', tau[:,j0:j1], eri) _dgemm('N', 'T', nocc*(nocc+1)//2, ic*nao, jc*nao, tau.reshape(-1,nao*nao), eri.reshape(-1,jc*nao), t2new_tril.reshape(-1,nao*nao), 1, 1, j0*nao, 0, i0*nao) def contract_tril_(t2new_tril, tau, eri, a0, a): nvir = tau.shape[-1] #: t2new[i,:i+1, a] += numpy.einsum('xcd,cdb->xb', tau[:,a0:a+1], eri) _dgemm('N', 'N', nocc*(nocc+1)//2, nvir, (a+1-a0)*nvir, tau.reshape(-1,nvir*nvir), eri.reshape(-1,nvir), t2new_tril.reshape(-1,nvir*nvir), 1, 1, a0*nvir, 0, a*nvir) #: t2new[i,:i+1,a0:a] += numpy.einsum('xd,abd->xab', tau[:,a], eri[:a]) if a > a0: _dgemm('N', 'T', nocc*(nocc+1)//2, (a-a0)*nvir, nvir, tau.reshape(-1,nvir*nvir), eri.reshape(-1,nvir), t2new_tril.reshape(-1,nvir*nvir), 1, 1, a*nvir, 0, a0*nvir) if self.direct: # AO-direct CCSD mol = self.mol nao, nmo = self.mo_coeff.shape nao_pair = nao * (nao+1) // 2 aos = numpy.asarray(self.mo_coeff[:,nocc:].T, order='F') outbuf = numpy.empty((nocc*(nocc+1)//2,nao,nao)) tau = numpy.ndarray((nocc*(nocc+1)//2,nvir,nvir), buffer=outbuf) p0 = 0 for i in range(nocc): tau[p0:p0+i+1] = numpy.einsum('a,jb->jab', t1[i], t1[:i+1]) tau[p0:p0+i+1] += t2[i,:i+1] p0 += i + 1 tau = _ao2mo.nr_e2(tau.reshape(-1,nvir**2), aos, (0,nao,0,nao), 's1', 's1') tau = tau.reshape(-1,nao,nao) time0 = logger.timer_debug1(self, 'vvvv-tau', *time0) ao2mopt = _ao2mo.AO2MOpt(mol, 'cint2e_sph', 'CVHFnr_schwarz_cond', 'CVHFsetnr_direct_scf') outbuf[:] = 0 ao_loc = mol.ao_loc_nr() max_memory = max(0, self.max_memory - lib.current_memory()[0]) dmax = max(4, int(numpy.sqrt(max_memory*.95e6/8/nao**2/2))) sh_ranges = ao2mo.outcore.balance_partition(ao_loc, dmax) dmax = max(x[2] for x in sh_ranges) eribuf = numpy.empty((dmax,dmax,nao,nao)) loadbuf = numpy.empty((dmax,dmax,nao,nao)) fint = gto.moleintor.getints2e for ip, (ish0, ish1, ni) in enumerate(sh_ranges): for jsh0, jsh1, nj in sh_ranges[:ip]: eri = fint('cint2e_sph', mol._atm, mol._bas, mol._env, shls_slice=(ish0,ish1,jsh0,jsh1), aosym='s2kl', ao_loc=ao_loc, cintopt=ao2mopt._cintopt, out=eribuf) i0, i1 = ao_loc[ish0], ao_loc[ish1] j0, j1 = ao_loc[jsh0], ao_loc[jsh1] tmp = numpy.ndarray((i1-i0,nao,j1-j0,nao), buffer=loadbuf) _ccsd.libcc.CCload_eri(tmp.ctypes.data_as(ctypes.c_void_p), eri.ctypes.data_as(ctypes.c_void_p), (ctypes.c_int*4)(i0, i1, j0, j1), ctypes.c_int(nao)) contract_rec_(outbuf, tau, tmp, i0, i1, j0, j1) time0 = logger.timer_debug1(self, 'AO-vvvv [%d:%d,%d:%d]' % (ish0,ish1,jsh0,jsh1), *time0) eri = fint('cint2e_sph', mol._atm, mol._bas, mol._env, shls_slice=(ish0,ish1,ish0,ish1), aosym='s4', ao_loc=ao_loc, cintopt=ao2mopt._cintopt, out=eribuf) i0, i1 = ao_loc[ish0], ao_loc[ish1] for i in range(i1-i0): p0, p1 = i*(i+1)//2, (i+1)*(i+2)//2 tmp = lib.unpack_tril(eri[p0:p1], out=loadbuf) contract_tril_(outbuf, tau, tmp, i0, i0+i) time0 = logger.timer_debug1(self, 'AO-vvvv [%d:%d,%d:%d]' % (ish0,ish1,ish0,ish1), *time0) eribuf = loadbuf = eri = tmp = None mo = numpy.asarray(self.mo_coeff, order='F') tmp = _ao2mo.nr_e2(outbuf, mo, (nocc,nmo,nocc,nmo), 's1', 's1', out=tau) t2new_tril += tmp.reshape(-1,nvir,nvir) #: tmp = numpy.einsum('ijcd,ka,kdcb->ijba', tau, t1, eris.ovvv) #: t2new -= tmp + tmp.transpose(1,0,3,2) tmp = _ao2mo.nr_e2(outbuf, mo, (nocc,nmo,0,nocc), 's1', 's1', out=tau) t2new_tril -= lib.ddot(tmp.reshape(-1,nocc), t1).reshape(-1,nvir,nvir) tmp = _ao2mo.nr_e2(outbuf, mo, (0,nocc,nocc,nmo), 's1', 's1', out=tau) #: t2new_tril -= numpy.einsum('xkb,ka->xab', tmp.reshape(-1,nocc,nvir), t1) tmp = lib.transpose(tmp.reshape(-1,nocc,nvir), axes=(0,2,1), out=outbuf) tmp = lib.ddot(tmp.reshape(-1,nocc), t1, 1, numpy.ndarray(t2new_tril.shape, buffer=tau), 0) tmp = lib.transpose(tmp.reshape(-1,nvir,nvir), axes=(0,2,1), out=outbuf) t2new_tril -= tmp.reshape(-1,nvir,nvir) else: #: tau = t2 + numpy.einsum('ia,jb->ijab', t1, t1) #: t2new += numpy.einsum('ijcd,acdb->ijab', tau, vvvv) tau = numpy.empty((nocc*(nocc+1)//2,nvir,nvir)) p0 = 0 for i in range(nocc): tau[p0:p0+i+1] = numpy.einsum('a,jb->jab', t1[i], t1[:i+1]) tau[p0:p0+i+1] += t2[i,:i+1] p0 += i + 1 time0 = logger.timer_debug1(self, 'vvvv-tau', *time0) p0 = 0 outbuf = numpy.empty((nvir,nvir,nvir)) outbuf1 = numpy.empty((nvir,nvir,nvir)) handler = None for a in range(nvir): buf = lib.unpack_tril(eris.vvvv[p0:p0+a+1], out=outbuf) outbuf, outbuf1 = outbuf1, outbuf handler = async_do(handler, contract_tril_, t2new_tril, tau, buf, 0, a) p0 += a+1 time0 = logger.timer_debug1(self, 'vvvv %d'%a, *time0) handler.join() return t2new_tril
def kernel(mp, t2, atmlst=None, mf_grad=None, verbose=logger.INFO): if mf_grad is None: mf_grad = mp._scf.nuc_grad_method() log = logger.new_logger(mp, verbose) time0 = time.clock(), time.time() log.debug('Build mp2 rdm1 intermediates') d1 = mp2._gamma1_intermediates(mp, t2) doo, dvv = d1 time1 = log.timer_debug1('rdm1 intermediates', *time0) # Set nocc, nvir for half-transformation of 2pdm. Frozen orbitals are exculded. # nocc, nvir should be updated to include the frozen orbitals when proceeding # the 1-particle quantities later. mol = mp.mol with_frozen = not (mp.frozen is None or mp.frozen is 0) OA, VA, OF, VF = _index_frozen_active(mp.get_frozen_mask(), mp.mo_occ) orbo = mp.mo_coeff[:,OA] orbv = mp.mo_coeff[:,VA] nao, nocc = orbo.shape nvir = orbv.shape[1] # Partially transform MP2 density matrix and hold it in memory # The rest transformation are applied during the contraction to ERI integrals part_dm2 = _ao2mo.nr_e2(t2.reshape(nocc**2,nvir**2), numpy.asarray(orbv.T, order='F'), (0,nao,0,nao), 's1', 's1').reshape(nocc,nocc,nao,nao) part_dm2 = (part_dm2.transpose(0,2,3,1) * 4 - part_dm2.transpose(0,3,2,1) * 2) hf_dm1 = mp._scf.make_rdm1(mp.mo_coeff, mp.mo_occ) if atmlst is None: atmlst = range(mol.natm) offsetdic = mol.offset_nr_by_atom() diagidx = numpy.arange(nao) diagidx = diagidx*(diagidx+1)//2 + diagidx de = numpy.zeros((len(atmlst),3)) Imat = numpy.zeros((nao,nao)) fdm2 = lib.H5TmpFile() vhf1 = fdm2.create_dataset('vhf1', (len(atmlst),3,nao,nao), 'f8') # 2e AO integrals dot 2pdm max_memory = max(0, mp.max_memory - lib.current_memory()[0]) blksize = max(1, int(max_memory*.9e6/8/(nao**3*2.5))) Imat1 = 0 Imat2 = 0 for k, ia in enumerate(atmlst): shl0, shl1, p0, p1 = offsetdic[ia] ip1 = p0 vhf = numpy.zeros((3,nao,nao)) for b0, b1, nf in _shell_prange(mol, shl0, shl1, blksize): ip0, ip1 = ip1, ip1 + nf dm2buf = lib.einsum('pi,iqrj->pqrj', orbo[ip0:ip1], part_dm2) dm2buf+= lib.einsum('qi,iprj->pqrj', orbo, part_dm2[:,ip0:ip1]) dm2buf = lib.einsum('pqrj,sj->pqrs', dm2buf, orbo) dm2buf = dm2buf + dm2buf.transpose(0,1,3,2) dm2buf = lib.pack_tril(dm2buf.reshape(-1,nao,nao)).reshape(nf,nao,-1) dm2buf[:,:,diagidx] *= .5 shls_slice = (b0,b1,0,mol.nbas,0,mol.nbas,0,mol.nbas) eri0 = mol.intor('int2e', aosym='s2kl', shls_slice=shls_slice) Imat += lib.einsum('ipx,iqx->pq', eri0.reshape(nf,nao,-1), dm2buf) eri0 = None eri1 = mol.intor('int2e_ip1', comp=3, aosym='s2kl', shls_slice=shls_slice).reshape(3,nf,nao,-1) de[k] -= numpy.einsum('xijk,ijk->x', eri1, dm2buf) * 2 dm2buf = None # HF part for i in range(3): eri1tmp = lib.unpack_tril(eri1[i]).reshape(nf*nao,-1) eri1tmp = eri1tmp.reshape(nf,nao,nao,nao) vhf[i] += numpy.einsum('ijkl,ij->kl', eri1tmp, hf_dm1[ip0:ip1]) vhf[i] -= numpy.einsum('ijkl,il->kj', eri1tmp, hf_dm1[ip0:ip1]) * .5 vhf[i,ip0:ip1] += numpy.einsum('ijkl,kl->ij', eri1tmp, hf_dm1) vhf[i,ip0:ip1] -= numpy.einsum('ijkl,jk->il', eri1tmp, hf_dm1) * .5 eri1 = eri1tmp = None vhf1[k] = vhf log.debug('2e-part grad of atom %d %s = %s', ia, mol.atom_symbol(ia), de[k]) time1 = log.timer_debug1('2e-part grad of atom %d'%ia, *time1) # Recompute nocc, nvir to include the frozen orbitals and make contraction for # the 1-particle quantities, see also the kernel function in ccsd_grad module. mo_coeff = mp.mo_coeff mo_energy = mp._scf.mo_energy nao, nmo = mo_coeff.shape nocc = numpy.count_nonzero(mp.mo_occ > 0) Imat = reduce(numpy.dot, (mo_coeff.T, Imat, mp._scf.get_ovlp(), mo_coeff)) * -1 dm1mo = numpy.zeros((nmo,nmo)) if with_frozen: dco = Imat[OF[:,None],OA] / (mo_energy[OF,None] - mo_energy[OA]) dfv = Imat[VF[:,None],VA] / (mo_energy[VF,None] - mo_energy[VA]) dm1mo[OA[:,None],OA] = doo + doo.T dm1mo[OF[:,None],OA] = dco dm1mo[OA[:,None],OF] = dco.T dm1mo[VA[:,None],VA] = dvv + dvv.T dm1mo[VF[:,None],VA] = dfv dm1mo[VA[:,None],VF] = dfv.T else: dm1mo[:nocc,:nocc] = doo + doo.T dm1mo[nocc:,nocc:] = dvv + dvv.T dm1 = reduce(numpy.dot, (mo_coeff, dm1mo, mo_coeff.T)) vhf = mp._scf.get_veff(mp.mol, dm1) * 2 Xvo = reduce(numpy.dot, (mo_coeff[:,nocc:].T, vhf, mo_coeff[:,:nocc])) Xvo+= Imat[:nocc,nocc:].T - Imat[nocc:,:nocc] dm1mo += _response_dm1(mp, Xvo) time1 = log.timer_debug1('response_rdm1 intermediates', *time1) Imat[nocc:,:nocc] = Imat[:nocc,nocc:].T im1 = reduce(numpy.dot, (mo_coeff, Imat, mo_coeff.T)) time1 = log.timer_debug1('response_rdm1', *time1) log.debug('h1 and JK1') hcore_deriv = mf_grad.hcore_generator(mol) s1 = mf_grad.get_ovlp(mol) zeta = lib.direct_sum('i+j->ij', mo_energy, mo_energy) * .5 zeta[nocc:,:nocc] = mo_energy[:nocc] zeta[:nocc,nocc:] = mo_energy[:nocc].reshape(-1,1) zeta = reduce(numpy.dot, (mo_coeff, zeta*dm1mo, mo_coeff.T)) dm1 = reduce(numpy.dot, (mo_coeff, dm1mo, mo_coeff.T)) p1 = numpy.dot(mo_coeff[:,:nocc], mo_coeff[:,:nocc].T) vhf_s1occ = reduce(numpy.dot, (p1, mp._scf.get_veff(mol, dm1+dm1.T), p1)) time1 = log.timer_debug1('h1 and JK1', *time1) # Hartree-Fock part contribution dm1p = hf_dm1 + dm1*2 dm1 += hf_dm1 zeta += mf_grad.make_rdm1e(mo_energy, mo_coeff, mp.mo_occ) for k, ia in enumerate(atmlst): shl0, shl1, p0, p1 = offsetdic[ia] # s[1] dot I, note matrix im1 is not hermitian de[k] += numpy.einsum('xij,ij->x', s1[:,p0:p1], im1[p0:p1]) de[k] += numpy.einsum('xji,ij->x', s1[:,p0:p1], im1[:,p0:p1]) # h[1] \dot DM, contribute to f1 h1ao = hcore_deriv(ia) de[k] += numpy.einsum('xij,ji->x', h1ao, dm1) # -s[1]*e \dot DM, contribute to f1 de[k] -= numpy.einsum('xij,ij->x', s1[:,p0:p1], zeta[p0:p1] ) de[k] -= numpy.einsum('xji,ij->x', s1[:,p0:p1], zeta[:,p0:p1]) # -vhf[s_ij[1]], contribute to f1, *2 for s1+s1.T de[k] -= numpy.einsum('xij,ij->x', s1[:,p0:p1], vhf_s1occ[p0:p1]) * 2 de[k] -= numpy.einsum('xij,ij->x', vhf1[k], dm1p) de += mf_grad.grad_nuc(mol) log.timer('%s gradients' % mp.__class__.__name__, *time0) return de