def spin2spatial(tx, orbspin): if tx.ndim == 2: # t1 nocc, nvir = tx.shape else: nocc, nvir = tx.shape[1:3] idxoa = numpy.where(orbspin[:nocc] == 0)[0] idxob = numpy.where(orbspin[:nocc] == 1)[0] idxva = numpy.where(orbspin[nocc:] == 0)[0] idxvb = numpy.where(orbspin[nocc:] == 1)[0] nocc_a = len(idxoa) nocc_b = len(idxob) nvir_a = len(idxva) nvir_b = len(idxvb) if tx.ndim == 2: # t1 t1a = lib.take_2d(tx, idxoa, idxva) t1b = lib.take_2d(tx, idxob, idxvb) return t1a, t1b else: idxoaa = idxoa[:,None] * nocc + idxoa idxoab = idxoa[:,None] * nocc + idxob idxobb = idxob[:,None] * nocc + idxob idxvaa = idxva[:,None] * nvir + idxva idxvab = idxva[:,None] * nvir + idxvb idxvbb = idxvb[:,None] * nvir + idxvb t2 = tx.reshape(nocc**2,nvir**2) t2aa = lib.take_2d(t2, idxoaa.ravel(), idxvaa.ravel()) t2bb = lib.take_2d(t2, idxobb.ravel(), idxvbb.ravel()) t2ab = lib.take_2d(t2, idxoab.ravel(), idxvab.ravel()) t2aa = t2aa.reshape(nocc_a,nocc_a,nvir_a,nvir_a) t2bb = t2bb.reshape(nocc_b,nocc_b,nvir_b,nvir_b) t2ab = t2ab.reshape(nocc_a,nocc_b,nvir_a,nvir_b) return t2aa,t2ab,t2bb
def trans(ci1, aindex, bindex): if aindex is None or bindex is None: return None ma = len(aindex) mb = len(bindex) t1 = numpy.zeros((ma,mb)) for i in range(norb): signa = aindex[:,i,1] signb = bindex[:,i,1] maska = numpy.where(signa!=0)[0] maskb = numpy.where(signb!=0)[0] addra = aindex[maska,i,0] addrb = bindex[maskb,i,0] citmp = lib.take_2d(ci_coeff, addra, addrb) citmp *= signa[maska].reshape(-1,1) citmp *= signb[maskb] #: t1[addra.reshape(-1,1),addrb] += citmp lib.takebak_2d(t1, citmp, maska, maskb) for i in range(norb): signa = aindex[:,i,1] signb = bindex[:,i,1] maska = numpy.where(signa!=0)[0] maskb = numpy.where(signb!=0)[0] addra = aindex[maska,i,0] addrb = bindex[maskb,i,0] citmp = lib.take_2d(t1, maska, maskb) citmp *= signa[maska].reshape(-1,1) citmp *= signb[maskb] #: ci1[maska.reshape(-1,1), maskb] += citmp lib.takebak_2d(ci1, citmp, addra, addrb)
def trans(ci1, aindex, bindex, nea, neb): if aindex is None or bindex is None: return None t1 = numpy.zeros((cistring.num_strings(norb,nea), cistring.num_strings(norb,neb))) for i in range(norb): signa = aindex[:,i,1] signb = bindex[:,i,1] maska = numpy.where(signa!=0)[0] maskb = numpy.where(signb!=0)[0] addra = aindex[maska,i,0] addrb = bindex[maskb,i,0] citmp = lib.take_2d(fcivec, maska, maskb) citmp *= signa[maska].reshape(-1,1) citmp *= signb[maskb] #: t1[addra.reshape(-1,1),addrb] += citmp lib.takebak_2d(t1, citmp, addra, addrb) for i in range(norb): signa = aindex[:,i,1] signb = bindex[:,i,1] maska = numpy.where(signa!=0)[0] maskb = numpy.where(signb!=0)[0] addra = aindex[maska,i,0] addrb = bindex[maskb,i,0] citmp = lib.take_2d(t1, addra, addrb) citmp *= signa[maska].reshape(-1,1) citmp *= signb[maskb] #: ci1[maska.reshape(-1,1), maskb] += citmp lib.takebak_2d(ci1, citmp, maska, maskb)
def test_take_2d(self): a = numpy.arange(49.).reshape(7,7) idx = [3,0,5] idy = [5,4,1] ref = a[idx][:,idy] self.assertTrue(numpy.array_equal(ref, lib.take_2d(a, idx, idy))) a = numpy.arange(49, dtype=numpy.int32).reshape(7,7) ref = a[idx][:,idy] self.assertTrue(numpy.array_equal(ref, lib.take_2d(a, idx, idy))) self.assertTrue(lib.take_2d(a, idx, idy).dtype == numpy.int32)
def _sort_t2_vooo_(mycc, orbsym, t1, t2, eris): assert(t2.flags.c_contiguous) vooo = numpy.asarray(eris.ovoo).transpose(1,0,3,2).conj().copy() nocc, nvir = t1.shape if mycc.mol.symmetry: orbsym = numpy.asarray(orbsym, dtype=numpy.int32) o_sorted = _irrep_argsort(orbsym[:nocc]) v_sorted = _irrep_argsort(orbsym[nocc:]) mo_energy = eris.mo_energy mo_energy = numpy.hstack((mo_energy[:nocc][o_sorted], mo_energy[nocc:][v_sorted])) t1T = numpy.asarray(t1.T[v_sorted][:,o_sorted], order='C') fvo = eris.fock[nocc:,:nocc] fvo = numpy.asarray(fvo[v_sorted][:,o_sorted], order='C') o_sym = orbsym[o_sorted] oo_sym = (o_sym[:,None] ^ o_sym).ravel() oo_sorted = _irrep_argsort(oo_sym) #:vooo = eris.ovoo.transpose(1,0,2,3) #:vooo = vooo[v_sorted][:,o_sorted][:,:,o_sorted][:,:,:,o_sorted] #:vooo = vooo.reshape(nvir,-1,nocc)[:,oo_sorted] oo_idx = numpy.arange(nocc**2).reshape(nocc,nocc)[o_sorted][:,o_sorted] oo_idx = oo_idx.ravel()[oo_sorted] oo_idx = (oo_idx[:,None]*nocc+o_sorted).ravel() vooo = lib.take_2d(vooo.reshape(nvir,-1), v_sorted, oo_idx) vooo = vooo.reshape(nvir,nocc,nocc,nocc) #:t2T = t2.transpose(2,3,1,0) #:t2T = ref_t2T[v_sorted][:,v_sorted][:,:,o_sorted][:,:,:,o_sorted] #:t2T = ref_t2T.reshape(nvir,nvir,-1)[:,:,oo_sorted] t2T = lib.transpose(t2.reshape(nocc**2,-1)) oo_idx = numpy.arange(nocc**2).reshape(nocc,nocc).T[o_sorted][:,o_sorted] oo_idx = oo_idx.ravel()[oo_sorted] vv_idx = (v_sorted[:,None]*nvir+v_sorted).ravel() t2T = lib.take_2d(t2T.reshape(nvir**2,nocc**2), vv_idx, oo_idx, out=t2) t2T = t2T.reshape(nvir,nvir,nocc,nocc) def restore_t2_inplace(t2T): tmp = numpy.zeros((nvir**2,nocc**2), dtype=t2T.dtype) lib.takebak_2d(tmp, t2T.reshape(nvir**2,nocc**2), vv_idx, oo_idx) t2 = lib.transpose(tmp.reshape(nvir**2,nocc**2), out=t2T) return t2.reshape(nocc,nocc,nvir,nvir) else: fvo = eris.fock[nocc:,:nocc].copy() t1T = t1.T.copy() t2T = lib.transpose(t2.reshape(nocc**2,nvir**2)) t2T = lib.transpose(t2T.reshape(nvir**2,nocc,nocc), axes=(0,2,1), out=t2) mo_energy = numpy.asarray(eris.mo_energy, order='C') def restore_t2_inplace(t2T): tmp = lib.transpose(t2T.reshape(nvir**2,nocc,nocc), axes=(0,2,1)) t2 = lib.transpose(tmp.reshape(nvir**2,nocc**2), out=t2T) return t2.reshape(nocc,nocc,nvir,nvir) t2T = t2T.reshape(nvir,nvir,nocc,nocc) return mo_energy, t1T, t2T, vooo, fvo, restore_t2_inplace
def amplitudes_to_cisdvec(c0, c1, c2): nocc, nvir = c1.shape ooidx = numpy.tril_indices(nocc, -1) vvidx = numpy.tril_indices(nvir, -1) c2tril = lib.take_2d(c2.reshape(nocc**2,nvir**2), ooidx[0]*nocc+ooidx[1], vvidx[0]*nvir+vvidx[1]) return numpy.hstack((c0, c1.ravel(), c2tril.ravel()))
def reorder_eri(eri, norb, orbsym): if orbsym is None: return [eri], numpy.arange(norb), numpy.zeros(norb,dtype=numpy.int32) # map irrep IDs of Dooh or Coov to D2h, C2v # see symm.basis.linearmole_symm_descent orbsym = numpy.asarray(orbsym) % 10 # irrep of (ij| pair trilirrep = (orbsym[:,None]^orbsym)[numpy.tril_indices(norb)] # and the number of occurence for each irrep dimirrep = numpy.asarray(numpy.bincount(trilirrep), dtype=numpy.int32) # we sort the irreps of (ij| pair, to group the pairs which have same irreps # "order" is irrep-id-sorted index. The (ij| paired is ordered that the # pair-id given by order[0] comes first in the sorted pair # "rank" is a sorted "order". Given nth (ij| pair, it returns the place(rank) # of the sorted pair old_eri_irrep = numpy.asarray(trilirrep, dtype=numpy.int32) rank_in_irrep = numpy.empty_like(old_eri_irrep) p0 = 0 eri_irs = [numpy.zeros((0,0))] * TOTIRREPS for ir, nnorb in enumerate(dimirrep): idx = numpy.asarray(numpy.where(trilirrep == ir)[0], dtype=numpy.int32) rank_in_irrep[idx] = numpy.arange(nnorb, dtype=numpy.int32) eri_irs[ir] = lib.take_2d(eri, idx, idx) p0 += nnorb return eri_irs, rank_in_irrep, old_eri_irrep
def contract_2e(eri, civec_strs, norb, nelec, link_index=None): ci_coeff, nelec, ci_strs = _unpack(civec_strs, nelec) if link_index is None: link_index = _all_linkstr_index(ci_strs, norb, nelec) cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index na, nlinka = cd_indexa.shape[:2] nb, nlinkb = cd_indexb.shape[:2] eri = ao2mo.restore(1, eri, norb) eri1 = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1) idx,idy = numpy.tril_indices(norb, -1) idx = idx * norb + idy eri1 = lib.take_2d(eri1.reshape(norb**2,-1), idx, idx) * 2 fcivec = ci_coeff.reshape(na,nb) # (bb|bb) if nelec[1] > 1: mb, mlinkb = dd_indexb.shape[:2] fcivecT = lib.transpose(fcivec) ci1T = numpy.zeros((nb,na)) libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivecT.ctypes.data_as(ctypes.c_void_p), ci1T.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(nb), ctypes.c_int(na), ctypes.c_int(mb), ctypes.c_int(mlinkb), dd_indexb.ctypes.data_as(ctypes.c_void_p)) ci1 = lib.transpose(ci1T, out=fcivecT) else: ci1 = numpy.zeros_like(fcivec) # (aa|aa) if nelec[0] > 1: ma, mlinka = dd_indexa.shape[:2] libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(ma), ctypes.c_int(mlinka), dd_indexa.ctypes.data_as(ctypes.c_void_p)) h_ps = numpy.einsum('pqqs->ps', eri) eri1 = eri * 2 for k in range(norb): eri1[:,:,k,k] += h_ps/nelec[0] eri1[k,k,:,:] += h_ps/nelec[1] eri1 = ao2mo.restore(4, eri1, norb) # (bb|aa) libfci.SCIcontract_2e_bbaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(nlinka), ctypes.c_int(nlinkb), cd_indexa.ctypes.data_as(ctypes.c_void_p), cd_indexb.ctypes.data_as(ctypes.c_void_p)) return _as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)
def from_fci(fcivec, ci_strs, norb, nelec): fcivec, nelec, ci_strs = _unpack(fcivec, nelec, ci_strs) addrsa = [cistring.str2addr(norb, nelec[0], x) for x in ci_strs[0]] addrsb = [cistring.str2addr(norb, nelec[1], x) for x in ci_strs[1]] na = cistring.num_strings(norb, nelec[0]) nb = cistring.num_strings(norb, nelec[1]) fcivec = fcivec.reshape(na,nb) civec = lib.take_2d(fcivec, addrsa, addrsb) return _as_SCIvector(civec, ci_strs)
def _make_eris_outcore(mycc, mo_coeff=None): cput0 = (time.clock(), time.time()) log = logger.Logger(mycc.stdout, mycc.verbose) eris = _ChemistsERIs() eris._common_init_(mycc, mo_coeff) mol = mycc.mol mo_coeff = eris.mo_coeff nocc = eris.nocc nao, nmo = mo_coeff.shape nvir = nmo - nocc orbo = mo_coeff[:,:nocc] orbv = mo_coeff[:,nocc:] nvpair = nvir * (nvir+1) // 2 eris.feri1 = lib.H5TmpFile() eris.oooo = eris.feri1.create_dataset('oooo', (nocc,nocc,nocc,nocc), 'f8') eris.ovoo = eris.feri1.create_dataset('ovoo', (nocc,nvir,nocc,nocc), 'f8', chunks=(nocc,1,nocc,nocc)) eris.ovov = eris.feri1.create_dataset('ovov', (nocc,nvir,nocc,nvir), 'f8', chunks=(nocc,1,nocc,nvir)) eris.ovvo = eris.feri1.create_dataset('ovvo', (nocc,nvir,nvir,nocc), 'f8', chunks=(nocc,1,nvir,nocc)) eris.ovvv = eris.feri1.create_dataset('ovvv', (nocc,nvir,nvir,nvir), 'f8') eris.oovv = eris.feri1.create_dataset('oovv', (nocc,nocc,nvir,nvir), 'f8', chunks=(nocc,nocc,1,nvir)) eris.vvvv = eris.feri1.create_dataset('vvvv', (nvir,nvir,nvir,nvir), 'f8') max_memory = max(MEMORYMIN, mycc.max_memory-lib.current_memory()[0]) ftmp = lib.H5TmpFile() ao2mo.full(mol, mo_coeff, ftmp, max_memory=max_memory, verbose=log) eri = ftmp['eri_mo'] nocc_pair = nocc*(nocc+1)//2 tril2sq = lib.square_mat_in_trilu_indices(nmo) oo = eri[:nocc_pair] eris.oooo[:] = ao2mo.restore(1, oo[:,:nocc_pair], nocc) oovv = lib.take_2d(oo, tril2sq[:nocc,:nocc].ravel(), tril2sq[nocc:,nocc:].ravel()) eris.oovv[:] = oovv.reshape(nocc,nocc,nvir,nvir) oo = oovv = None tril2sq = lib.square_mat_in_trilu_indices(nmo) blksize = min(nvir, max(BLKMIN, int(max_memory*1e6/8/nmo**3/2))) for p0, p1 in lib.prange(0, nvir, blksize): q0, q1 = p0+nocc, p1+nocc off0 = q0*(q0+1)//2 off1 = q1*(q1+1)//2 buf = lib.unpack_tril(eri[off0:off1]) tmp = buf[ tril2sq[q0:q1,:nocc] - off0 ] eris.ovoo[:,p0:p1] = tmp[:,:,:nocc,:nocc].transpose(1,0,2,3) eris.ovvo[:,p0:p1] = tmp[:,:,nocc:,:nocc].transpose(1,0,2,3) eris.ovov[:,p0:p1] = tmp[:,:,:nocc,nocc:].transpose(1,0,2,3) eris.ovvv[:,p0:p1] = tmp[:,:,nocc:,nocc:].transpose(1,0,2,3) tmp = buf[ tril2sq[q0:q1,nocc:q1] - off0 ] eris.vvvv[p0:p1,:p1] = tmp[:,:,nocc:,nocc:] if p0 > 0: eris.vvvv[:p0,p0:p1] = tmp[:,:p0,nocc:,nocc:].transpose(1,0,2,3) buf = tmp = None log.timer('CCSD integral transformation', *cput0) return eris
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0): if orbsym is None: return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index) eri = ao2mo.restore(4, eri, norb) neleca, nelecb = direct_spin1._unpack_nelec(nelec) assert(neleca == nelecb) link_indexa = direct_spin0._unpack(norb, nelec, link_index) na, nlinka = link_indexa.shape[:2] eri_irs, rank_eri, irrep_eri = direct_spin1_symm.reorder_eri(eri, norb, orbsym) totirrep = len(eri_irs) strsa = numpy.asarray(cistring.gen_strings4orblist(range(norb), neleca)) aidx, link_indexa = direct_spin1_symm.gen_str_irrep(strsa, orbsym, link_indexa, rank_eri, irrep_eri, totirrep) Tirrep = ctypes.c_void_p*totirrep linka_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa]) eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs]) dimirrep = (ctypes.c_int*totirrep)(*[x.shape[0] for x in eri_irs]) fcivec_shape = fcivec.shape fcivec = fcivec.reshape((na,na), order='C') ci1new = numpy.zeros_like(fcivec) nas = (ctypes.c_int*8)(*[x.size for x in aidx]) ci0 = [] ci1 = [] for ir in range(totirrep): ma, mb = aidx[ir].size, aidx[wfnsym^ir].size ci0.append(numpy.zeros((ma,mb))) ci1.append(numpy.zeros((ma,mb))) if ma > 0 and mb > 0: lib.take_2d(fcivec, aidx[ir], aidx[wfnsym^ir], out=ci0[ir]) ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0]) ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1]) libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs, ctypes.c_int(norb), nas, nas, ctypes.c_int(nlinka), ctypes.c_int(nlinka), linka_ptr, linka_ptr, dimirrep, ctypes.c_int(totirrep), ctypes.c_int(wfnsym)) for ir in range(totirrep): if ci0[ir].size > 0: lib.takebak_2d(ci1new, ci1[ir], aidx[ir], aidx[wfnsym^ir]) return lib.transpose_sum(ci1new, inplace=True).reshape(fcivec_shape)
def spin2spatial(tx, orbspin, kconserv): if tx.ndim == 3: # t1 nocc, nvir = tx.shape[1:] else: nocc, nvir = tx.shape[4:6] nkpts = len(tx) idxoa = [numpy.where(orbspin[k][:nocc] == 0)[0] for k in range(nkpts)] idxob = [numpy.where(orbspin[k][:nocc] == 1)[0] for k in range(nkpts)] idxva = [numpy.where(orbspin[k][nocc:] == 0)[0] for k in range(nkpts)] idxvb = [numpy.where(orbspin[k][nocc:] == 1)[0] for k in range(nkpts)] nocc_a = len(idxoa[0]) nocc_b = len(idxob[0]) nvir_a = len(idxva[0]) nvir_b = len(idxvb[0]) if tx.ndim == 3: # t1 t1a = numpy.zeros((nkpts,nocc_a,nvir_a), dtype=tx.dtype) t1b = numpy.zeros((nkpts,nocc_b,nvir_b), dtype=tx.dtype) for k in range(nkpts): lib.take_2d(tx[k], idxoa[k], idxva[k], out=t1a[k]) lib.take_2d(tx[k], idxob[k], idxvb[k], out=t1b[k]) return t1a, t1b else: t2aa = numpy.zeros((nkpts,nkpts,nkpts,nocc_a,nocc_a,nvir_a,nvir_a), dtype=tx.dtype) t2ab = numpy.zeros((nkpts,nkpts,nkpts,nocc_a,nocc_b,nvir_a,nvir_b), dtype=tx.dtype) t2bb = numpy.zeros((nkpts,nkpts,nkpts,nocc_b,nocc_b,nvir_b,nvir_b), dtype=tx.dtype) t2 = tx.reshape(nkpts,nkpts,nkpts,nocc**2,nvir**2) for ki, kj, ka in kpts_helper.loop_kkk(nkpts): kb = kconserv[ki,ka,kj] idxoaa = idxoa[ki][:,None] * nocc + idxoa[kj] idxoab = idxoa[ki][:,None] * nocc + idxob[kj] idxobb = idxob[ki][:,None] * nocc + idxob[kj] idxvaa = idxva[ka][:,None] * nvir + idxva[kb] idxvab = idxva[ka][:,None] * nvir + idxvb[kb] idxvbb = idxvb[ka][:,None] * nvir + idxvb[kb] lib.take_2d(t2[ki,kj,ka], idxoaa.ravel(), idxvaa.ravel(), out=t2aa[ki,kj,ka]) lib.take_2d(t2[ki,kj,ka], idxobb.ravel(), idxvbb.ravel(), out=t2bb[ki,kj,ka]) lib.take_2d(t2[ki,kj,ka], idxoab.ravel(), idxvab.ravel(), out=t2ab[ki,kj,ka]) return t2aa, t2ab, t2bb
def reorder4irrep_minors(eri, norb, link_index, orbsym): if orbsym is None: return eri, link_index, numpy.array(norb, dtype=numpy.int32) orbsym = numpy.asarray(orbsym) % 10 trilirrep = (orbsym[:,None]^orbsym)[numpy.tril_indices(norb,-1)] dimirrep = numpy.array(numpy.bincount(trilirrep), dtype=numpy.int32) order = numpy.argsort(trilirrep) rank = order.argsort() eri = lib.take_2d(eri, order, order) link_index_irrep = link_index.copy() link_index_irrep[:,:,0] = rank[link_index[:,:,0]] return numpy.asarray(eri, order='C'), link_index_irrep, dimirrep
def contract_2e(eri, civec_strs, norb, nelec, link_index=None, orbsym=None): ci_coeff, nelec, ci_strs = selected_ci._unpack(civec_strs, nelec) if link_index is None: link_index = selected_ci._all_linkstr_index(ci_strs, norb, nelec) cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index na, nlinka = nb, nlinkb = cd_indexa.shape[:2] eri = ao2mo.restore(1, eri, norb) eri1 = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1) idx,idy = numpy.tril_indices(norb, -1) idx = idx * norb + idy eri1 = lib.take_2d(eri1.reshape(norb**2,-1), idx, idx) * 2 lib.transpose_sum(eri1, inplace=True) eri1 *= .5 eri1, dd_indexa, dimirrep = selected_ci_symm.reorder4irrep(eri1, norb, dd_indexa, orbsym, -1) fcivec = ci_coeff.reshape(na,nb) ci1 = numpy.zeros_like(fcivec) # (aa|aa) if nelec[0] > 1: ma, mlinka = mb, mlinkb = dd_indexa.shape[:2] libfci.SCIcontract_2e_aaaa_symm(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(ma), ctypes.c_int(mlinka), dd_indexa.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) h_ps = numpy.einsum('pqqs->ps', eri) * (.5/nelec[0]) eri1 = eri.copy() for k in range(norb): eri1[:,:,k,k] += h_ps eri1[k,k,:,:] += h_ps eri1 = ao2mo.restore(4, eri1, norb) lib.transpose_sum(eri1, inplace=True) eri1 *= .5 eri1, cd_indexa, dimirrep = selected_ci_symm.reorder4irrep(eri1, norb, cd_indexa, orbsym) # (bb|aa) libfci.SCIcontract_2e_bbaa_symm(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(nlinka), ctypes.c_int(nlinkb), cd_indexa.ctypes.data_as(ctypes.c_void_p), cd_indexa.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) lib.transpose_sum(ci1, inplace=True) return selected_ci._as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)
def spin2spatial_ip_doublet(r1, r2, kconserv, kshift, orbspin): '''Convert R1/R2 of spin orbital representation to R1/R2 of spatial orbital representation ''' nkpts, nocc, nvir = np.array(r2.shape)[[1, 3, 4]] idxoa = [np.where(orbspin[k][:nocc] == 0)[0] for k in range(nkpts)] idxob = [np.where(orbspin[k][:nocc] == 1)[0] for k in range(nkpts)] idxva = [np.where(orbspin[k][nocc:] == 0)[0] for k in range(nkpts)] idxvb = [np.where(orbspin[k][nocc:] == 1)[0] for k in range(nkpts)] nocc_a = len(idxoa[0]) # Assume nocc/nvir same for each k-point nocc_b = len(idxob[0]) nvir_a = len(idxva[0]) nvir_b = len(idxvb[0]) r1a = r1[idxoa[kshift]] r1b = r1[idxob[kshift]] r2aaa = np.zeros((nkpts,nkpts,nocc_a,nocc_a,nvir_a), dtype=r2.dtype) r2baa = np.zeros((nkpts,nkpts,nocc_b,nocc_a,nvir_a), dtype=r2.dtype) r2abb = np.zeros((nkpts,nkpts,nocc_a,nocc_b,nvir_b), dtype=r2.dtype) r2bbb = np.zeros((nkpts,nkpts,nocc_b,nocc_b,nvir_b), dtype=r2.dtype) for ki, kj in itertools.product(range(nkpts), repeat=2): ka = kconserv[ki, kshift, kj] idxoaa = idxoa[ki][:,None] * nocc + idxoa[kj] idxoab = idxoa[ki][:,None] * nocc + idxob[kj] idxoba = idxob[ki][:,None] * nocc + idxoa[kj] idxobb = idxob[ki][:,None] * nocc + idxob[kj] r2_tmp = r2[ki, kj].reshape(nocc**2, nvir) r2aaa_tmp = lib.take_2d(r2_tmp, idxoaa.ravel(), idxva[ka]) r2baa_tmp = lib.take_2d(r2_tmp, idxoba.ravel(), idxva[ka]) r2abb_tmp = lib.take_2d(r2_tmp, idxoab.ravel(), idxvb[ka]) r2bbb_tmp = lib.take_2d(r2_tmp, idxobb.ravel(), idxvb[ka]) r2aaa[ki, kj] = r2aaa_tmp.reshape(nocc_a, nocc_a, nvir_a) r2baa[ki, kj] = r2baa_tmp.reshape(nocc_b, nocc_a, nvir_a) r2abb[ki, kj] = r2abb_tmp.reshape(nocc_a, nocc_b, nvir_b) r2bbb[ki, kj] = r2bbb_tmp.reshape(nocc_b, nocc_b, nvir_b) return [r1a, r1b], [r2aaa, r2baa, r2abb, r2bbb]
def spin2spatial_ea_doublet(r1, r2, kconserv, kshift, orbspin): '''Convert R1/R2 of spin orbital representation to R1/R2 of spatial orbital representation''' nkpts, nocc, nvir = np.array(r2.shape)[[1, 2, 3]] idxoa = [np.where(orbspin[k][:nocc] == 0)[0] for k in range(nkpts)] idxob = [np.where(orbspin[k][:nocc] == 1)[0] for k in range(nkpts)] idxva = [np.where(orbspin[k][nocc:] == 0)[0] for k in range(nkpts)] idxvb = [np.where(orbspin[k][nocc:] == 1)[0] for k in range(nkpts)] nocc_a = len(idxoa[0]) nocc_b = len(idxob[0]) nvir_a = len(idxva[0]) nvir_b = len(idxvb[0]) r1a = r1[idxva[kshift]] r1b = r1[idxvb[kshift]] r2aaa = np.zeros((nkpts,nkpts,nocc_a,nvir_a,nvir_a), dtype=r2.dtype) r2aba = np.zeros((nkpts,nkpts,nocc_a,nvir_b,nvir_a), dtype=r2.dtype) r2bab = np.zeros((nkpts,nkpts,nocc_b,nvir_a,nvir_b), dtype=r2.dtype) r2bbb = np.zeros((nkpts,nkpts,nocc_b,nvir_b,nvir_b), dtype=r2.dtype) for kj, ka in itertools.product(range(nkpts), repeat=2): kb = kconserv[kshift, ka, kj] idxvaa = idxva[ka][:,None] * nvir + idxva[kb] idxvab = idxva[ka][:,None] * nvir + idxvb[kb] idxvba = idxvb[ka][:,None] * nvir + idxva[kb] idxvbb = idxvb[ka][:,None] * nvir + idxvb[kb] r2_tmp = r2[kj, ka].reshape(nocc, nvir**2) r2aaa_tmp = lib.take_2d(r2_tmp, idxoa[kj], idxvaa.ravel()) r2aba_tmp = lib.take_2d(r2_tmp, idxoa[kj], idxvba.ravel()) r2bab_tmp = lib.take_2d(r2_tmp, idxob[kj], idxvab.ravel()) r2bbb_tmp = lib.take_2d(r2_tmp, idxob[kj], idxvbb.ravel()) r2aaa[kj, ka] = r2aaa_tmp.reshape(nocc_a, nvir_a, nvir_a) r2aba[kj, ka] = r2aba_tmp.reshape(nocc_a, nvir_b, nvir_a) r2bab[kj, ka] = r2bab_tmp.reshape(nocc_b, nvir_a, nvir_b) r2bbb[kj, ka] = r2bbb_tmp.reshape(nocc_b, nvir_b, nvir_b) return [r1a, r1b], [r2aaa, r2aba, r2bab, r2bbb]
def amplitudes_to_cisdvec(c0, c1, c2): c1a, c1b = c1 c2aa, c2ab, c2bb = c2 nocca, nvira = c1a.shape noccb, nvirb = c1b.shape def trilidx(n): idx = numpy.tril_indices(n, -1) return idx[0] * n + idx[1] ooidxa = trilidx(nocca) vvidxa = trilidx(nvira) ooidxb = trilidx(noccb) vvidxb = trilidx(nvirb) size = (1, nocca*nvira, noccb*nvirb, nocca*noccb*nvira*nvirb, len(ooidxa)*len(vvidxa), len(ooidxb)*len(vvidxb)) loc = numpy.cumsum(size) civec = numpy.empty(loc[-1], dtype=c2ab.dtype) civec[0] = c0 civec[loc[0]:loc[1]] = c1a.ravel() civec[loc[1]:loc[2]] = c1b.ravel() civec[loc[2]:loc[3]] = c2ab.ravel() lib.take_2d(c2aa.reshape(nocca**2,nvira**2), ooidxa, vvidxa, out=civec[loc[3]:loc[4]]) lib.take_2d(c2bb.reshape(noccb**2,nvirb**2), ooidxb, vvidxb, out=civec[loc[4]:loc[5]]) return civec
def rotate_mo(self, mo_coeff, u, log=None): #from pyscf.lo import orth #s = self._scf.get_ovlp() #if self._scf.mol.symmetry: # s = symm.symmetrize_matrix(s, self._scf._scf.mol.symm_orb) #return orth.vec_lowdin(numpy.dot(mo_coeff, u), s) mo = numpy.dot(mo_coeff, u) if log is not None and log.verbose >= logger.DEBUG: idx = numpy.where(self.mo_occ > 0)[0] s = reduce(numpy.dot, (mo[:,idx].T, self._scf.get_ovlp(), self.mo_coeff[:,idx])) log.debug('Overlap to initial guess, SVD = %s', _effective_svd(s, 1e-5)) log.debug('Overlap to last step, SVD = %s', _effective_svd(lib.take_2d(u,idx,idx), 1e-5)) return mo
def enlarge_space(myci, civec_strs, eri, norb, nelec): if isinstance(civec_strs, (tuple, list)): nelec, (strsa, strsb) = _unpack(civec_strs[0], nelec)[1:] ci_coeff = lib.asarray(civec_strs) else: ci_coeff, nelec, (strsa, strsb) = _unpack(civec_strs, nelec) na = len(strsa) nb = len(strsb) ci0 = ci_coeff.reshape(-1,na,nb) civec_a_max = lib.norm(ci0, axis=2).max(axis=0) civec_b_max = lib.norm(ci0, axis=1).max(axis=0) ci_aidx = numpy.where(civec_a_max > myci.ci_coeff_cutoff)[0] ci_bidx = numpy.where(civec_b_max > myci.ci_coeff_cutoff)[0] civec_a_max = civec_a_max[ci_aidx] civec_b_max = civec_b_max[ci_bidx] strsa = strsa[ci_aidx] strsb = strsb[ci_bidx] eri = ao2mo.restore(1, eri, norb) eri_pq_max = abs(eri.reshape(norb**2,-1)).max(axis=1).reshape(norb,norb) strsa_add = select_strs(myci, eri, eri_pq_max, civec_a_max, strsa, norb, nelec[0]) strsb_add = select_strs(myci, eri, eri_pq_max, civec_b_max, strsb, norb, nelec[1]) strsa = numpy.append(strsa, strsa_add) strsb = numpy.append(strsb, strsb_add) aidx = numpy.argsort(strsa) bidx = numpy.argsort(strsb) ci_strs = (strsa[aidx], strsb[bidx]) aidx = numpy.where(aidx < len(ci_aidx))[0] bidx = numpy.where(bidx < len(ci_bidx))[0] ma = len(strsa) mb = len(strsb) cs = [] for i in range(ci0.shape[0]): ci1 = numpy.zeros((ma,mb)) tmp = lib.take_2d(ci0[i], ci_aidx, ci_bidx) lib.takebak_2d(ci1, tmp, aidx, bidx) cs.append(_as_SCIvector(ci1, ci_strs)) if not isinstance(civec_strs, (tuple, list)) and civec_strs.ndim < 3: cs = cs[0] return cs
def overlap(string1, string2, norb, s=None): '''Determinants overlap on non-orthogonal one-particle basis''' if s is None: # orthogonal basis with s_ij = delta_ij return string1 == string2 else: if isinstance(string1, str): nelec = string1.count('1') string1 = int(string1, 2) else: nelec = bin(string1).count('1') if isinstance(string2, str): assert(string2.count('1') == nelec) string2 = int(string2, 2) else: assert(bin(string2).count('1') == nelec) idx1 = [i for i in range(norb) if (1<<i & string1)] idx2 = [i for i in range(norb) if (1<<i & string2)] s1 = lib.take_2d(s, idx1, idx2) return numpy.linalg.det(s1)
def reorder(ci, nelec, orbidxa, orbidxb=None): '''Reorder the CI coefficients, to adapt the reordered orbitals (The relation of the reordered orbitals and original orbitals is new = old[idx]). Eg. The orbital ordering indices ``orbidx = [2,0,1]`` indicates the map old orbital a b c -> new orbital c a b. The strings are reordered as old-strings 0b011, 0b101, 0b110 == (1,2), (1,3), (2,3) <= apply orbidx to get orb-strings orb-strings (3,1), (3,2), (1,2) == 0B101, 0B110, 0B011 <= by gen_strings4orblist then argsort to translate the string representation to the address [2(=0B011), 0(=0B101), 1(=0B110)] ''' neleca, nelecb = _unpack(nelec) if orbidxb is None: orbidxb = orbidxa guide_stringsa = cistring.gen_strings4orblist(orbidxa, neleca) guide_stringsb = cistring.gen_strings4orblist(orbidxb, nelecb) old_det_idxa = numpy.argsort(guide_stringsa) old_det_idxb = numpy.argsort(guide_stringsb) return lib.take_2d(ci, old_det_idxa, old_det_idxb)
def enlarge_space(myci, civec_strs, eri, norb, nelec): if isinstance(civec_strs, (tuple, list)): nelec, (strsa, strsb) = select_ci._unpack(civec_strs[0], nelec)[1:] ci_coeff = lib.asarray(civec_strs) else: ci_coeff, nelec, (strsa, strsb) = select_ci._unpack(civec_strs, nelec) na = nb = len(strsa) ci0 = ci_coeff.reshape(-1,na,nb) abs_ci = abs(ci0).max(axis=0) eri = ao2mo.restore(1, eri, norb) eri_pq_max = abs(eri.reshape(norb**2,-1)).max(axis=1).reshape(norb,norb) civec_a_max = abs_ci.max(axis=1) ci_aidx = numpy.where(civec_a_max > myci.ci_coeff_cutoff)[0] civec_a_max = civec_a_max[ci_aidx] strsa = strsa[ci_aidx] strsa_add = select_ci.select_strs(myci, eri, eri_pq_max, civec_a_max, strsa, norb, nelec[0]) strsa = numpy.append(strsa, strsa_add) aidx = numpy.argsort(strsa) strsa = strsa[aidx] aidx = numpy.where(aidx < len(ci_aidx))[0] ci_bidx = ci_aidx strsb = strsa bidx = aidx ma = mb = len(strsa) cs = [] for i in range(ci0.shape[0]): ci1 = numpy.zeros((ma,mb)) tmp = lib.take_2d(ci0[i], ci_aidx, ci_bidx) lib.takebak_2d(ci1, tmp, aidx, bidx) cs.append(select_ci._as_SCIvector(ci1, (strsa,strsb))) if ci_coeff[0].ndim == 0 or ci_coeff[0].shape[-1] != nb: cs = [c.ravel() for c in cs] if (isinstance(ci_coeff, numpy.ndarray) and ci_coeff.shape[0] == na or ci_coeff.shape[0] == na*nb): cs = cs[0] return cs
def _gamma2_intermediates(mycc, t1, t2, l1, l2, eris=None, compress_vvvv=False): dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = \ ccsd_rdm._gamma2_intermediates(mycc, t1, t2, l1, l2) if eris is None: eris = mycc.ao2mo() nocc, nvir = t1.shape eris_ovvv = numpy.asarray(eris.get_ovvv()) eris_ovoo = numpy.asarray(eris.ovoo) eris_ovov = numpy.asarray(eris.ovov) mo_e = eris.mo_energy eia = lib.direct_sum('i-a->ia', mo_e[:nocc], mo_e[nocc:]) d3 = lib.direct_sum('ia,jb,kc->ijkabc', eia, eia, eia) w =(numpy.einsum('iafb,kjcf->ijkabc', eris_ovvv.conj(), t2) - numpy.einsum('iajm,mkbc->ijkabc', eris_ovoo.conj(), t2)) / d3 v =(numpy.einsum('iajb,kc->ijkabc', eris_ovov.conj(), t1) + numpy.einsum('ck,ijab->ijkabc', eris.fock[nocc:,:nocc], t2)) / d3 w = p6(w) v = p6(v) rw = r6(w) rwv = r6(w * 2 + v * .5) dovov += numpy.einsum('kc,ijkabc->iajb', t1, rw.conj()) * .5 dooov -= numpy.einsum('mkbc,ijkabc->jmia', t2, rwv.conj()) # Note "dovvv +=" also changes the value of dvvov dovvv += numpy.einsum('kjcf,ijkabc->iafb', t2, rwv.conj()) dvvov = dovvv.transpose(2,3,0,1) if compress_vvvv: nvir = mycc.nmo - mycc.nocc idx = numpy.tril_indices(nvir) vidx = idx[0] * nvir + idx[1] dvvvv = dvvvv + dvvvv.transpose(1,0,2,3) dvvvv = dvvvv + dvvvv.transpose(0,1,3,2) dvvvv = lib.take_2d(dvvvv.reshape(nvir**2,nvir**2), vidx, vidx) dvvvv *= .25 return dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov
def reorder4irrep(eri, norb, link_index, orbsym, offdiag=0): if orbsym is None: return eri, link_index, numpy.array(norb, dtype=numpy.int32) orbsym = numpy.asarray(orbsym) # map irrep IDs of Dooh or Coov to D2h, C2v # see symm.basis.linearmole_symm_descent orbsym = orbsym % 10 # irrep of (ij| pair trilirrep = (orbsym[:,None]^orbsym)[numpy.tril_indices(norb, offdiag)] # and the number of occurence for each irrep dimirrep = numpy.array(numpy.bincount(trilirrep), dtype=numpy.int32) # we sort the irreps of (ij| pair, to group the pairs which have same irreps # "order" is irrep-id-sorted index. The (ij| paired is ordered that the # pair-id given by order[0] comes first in the sorted pair # "rank" is a sorted "order". Given nth (ij| pair, it returns the place(rank) # of the sorted pair order = numpy.asarray(trilirrep.argsort(), dtype=numpy.int32) rank = numpy.asarray(order.argsort(), dtype=numpy.int32) eri = lib.take_2d(eri, order, order) link_index_irrep = link_index.copy() link_index_irrep[:,:,0] = rank[link_index[:,:,0]] return numpy.asarray(eri, order='C'), link_index_irrep, dimirrep
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None): cput0 = (time.clock(), time.time()) eris = _ChemistsERIs() eris._common_init_(mycc, mo_coeff) nocca, noccb = mycc.nocc nmoa, nmob = mycc.nmo nvira, nvirb = nmoa - nocca, nmob - noccb moa = eris.mo_coeff[0] mob = eris.mo_coeff[1] nmoa = moa.shape[1] nmob = mob.shape[1] if callable(ao2mofn): eri_aa = ao2mofn(moa).reshape([nmoa] * 4) eri_bb = ao2mofn(mob).reshape([nmob] * 4) eri_ab = ao2mofn((moa, moa, mob, mob)) else: eri_aa = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, moa), nmoa) eri_bb = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, mob), nmob) eri_ab = ao2mo.general(mycc._scf._eri, (moa, moa, mob, mob), compact=False) eri_ba = eri_ab.reshape(nmoa, nmoa, nmob, nmob).transpose(2, 3, 0, 1) eri_aa = eri_aa.reshape(nmoa, nmoa, nmoa, nmoa) eri_ab = eri_ab.reshape(nmoa, nmoa, nmob, nmob) eri_ba = eri_ba.reshape(nmob, nmob, nmoa, nmoa) eri_bb = eri_bb.reshape(nmob, nmob, nmob, nmob) eris.oooo = eri_aa[:nocca, :nocca, :nocca, :nocca].copy() eris.ovoo = eri_aa[:nocca, nocca:, :nocca, :nocca].copy() eris.ovov = eri_aa[:nocca, nocca:, :nocca, nocca:].copy() eris.oovv = eri_aa[:nocca, :nocca, nocca:, nocca:].copy() eris.ovvo = eri_aa[:nocca, nocca:, nocca:, :nocca].copy() eris.ovvv = eri_aa[:nocca, nocca:, nocca:, nocca:].copy() eris.vvvv = eri_aa[nocca:, nocca:, nocca:, nocca:].copy() eris.OOOO = eri_bb[:noccb, :noccb, :noccb, :noccb].copy() eris.OVOO = eri_bb[:noccb, noccb:, :noccb, :noccb].copy() eris.OVOV = eri_bb[:noccb, noccb:, :noccb, noccb:].copy() eris.OOVV = eri_bb[:noccb, :noccb, noccb:, noccb:].copy() eris.OVVO = eri_bb[:noccb, noccb:, noccb:, :noccb].copy() eris.OVVV = eri_bb[:noccb, noccb:, noccb:, noccb:].copy() eris.VVVV = eri_bb[noccb:, noccb:, noccb:, noccb:].copy() eris.ooOO = eri_ab[:nocca, :nocca, :noccb, :noccb].copy() eris.ovOO = eri_ab[:nocca, nocca:, :noccb, :noccb].copy() eris.ovOV = eri_ab[:nocca, nocca:, :noccb, noccb:].copy() eris.ooVV = eri_ab[:nocca, :nocca, noccb:, noccb:].copy() eris.ovVO = eri_ab[:nocca, nocca:, noccb:, :noccb].copy() eris.ovVV = eri_ab[:nocca, nocca:, noccb:, noccb:].copy() eris.vvVV = eri_ab[nocca:, nocca:, noccb:, noccb:].copy() #eris.OOoo = eri_ba[:noccb,:noccb,:nocca,:nocca].copy() eris.OVoo = eri_ba[:noccb, noccb:, :nocca, :nocca].copy() #eris.OVov = eri_ba[:noccb,noccb:,:nocca,nocca:].copy() eris.OOvv = eri_ba[:noccb, :noccb, nocca:, nocca:].copy() eris.OVvo = eri_ba[:noccb, noccb:, nocca:, :nocca].copy() eris.OVvv = eri_ba[:noccb, noccb:, nocca:, nocca:].copy() #eris.VVvv = eri_ba[noccb:,noccb:,nocca:,nocca:].copy() if not callable(ao2mofn): ovvv = eris.ovvv.reshape(nocca * nvira, nvira, nvira) eris.ovvv = lib.pack_tril(ovvv).reshape(nocca, nvira, nvira * (nvira + 1) // 2) eris.vvvv = ao2mo.restore(4, eris.vvvv, nvira) OVVV = eris.OVVV.reshape(noccb * nvirb, nvirb, nvirb) eris.OVVV = lib.pack_tril(OVVV).reshape(noccb, nvirb, nvirb * (nvirb + 1) // 2) eris.VVVV = ao2mo.restore(4, eris.VVVV, nvirb) ovVV = eris.ovVV.reshape(nocca * nvira, nvirb, nvirb) eris.ovVV = lib.pack_tril(ovVV).reshape(nocca, nvira, nvirb * (nvirb + 1) // 2) vvVV = eris.vvVV.reshape(nvira**2, nvirb**2) idxa = np.tril_indices(nvira) idxb = np.tril_indices(nvirb) eris.vvVV = lib.take_2d(vvVV, idxa[0] * nvira + idxa[1], idxb[0] * nvirb + idxb[1]) OVvv = eris.OVvv.reshape(noccb * nvirb, nvira, nvira) eris.OVvv = lib.pack_tril(OVvv).reshape(noccb, nvirb, nvira * (nvira + 1) // 2) return eris
def overlap(cibra, ciket, nmo, nocc, s=None): '''Overlap between two CISD wavefunctions. Args: s : 2D array The overlap matrix of non-orthogonal one-particle basis ''' if s is None: return dot(cibra, ciket, nmo, nocc) DEBUG = True nvir = nmo - nocc nov = nocc * nvir bra0, bra1, bra2 = cisdvec_to_amplitudes(cibra, nmo, nocc) ket0, ket1, ket2 = cisdvec_to_amplitudes(ciket, nmo, nocc) # Sort the ket orbitals to make the orbitals in bra one-one mapt to orbitals # in ket. if ((not DEBUG) and abs(numpy.linalg.det(s[:nocc, :nocc]) - 1) < 1e-2 and abs(numpy.linalg.det(s[nocc:, nocc:]) - 1) < 1e-2): ket_orb_idx = numpy.where(abs(s) > 0.9)[1] s = s[:, ket_orb_idx] oidx = ket_orb_idx[:nocc] vidx = ket_orb_idx[nocc:] - nocc ket1 = ket1[oidx[:, None], vidx] ket2 = ket2[oidx[:, None, None, None], oidx[:, None, None], vidx[:, None], vidx] ooidx = numpy.tril_indices(nocc, -1) vvidx = numpy.tril_indices(nvir, -1) bra2aa = bra2 - bra2.transpose(1, 0, 2, 3) bra2aa = lib.take_2d(bra2aa.reshape(nocc**2, nvir**2), ooidx[0] * nocc + ooidx[1], vvidx[0] * nvir + vvidx[1]) ket2aa = ket2 - ket2.transpose(1, 0, 2, 3) ket2aa = lib.take_2d(ket2aa.reshape(nocc**2, nvir**2), ooidx[0] * nocc + ooidx[1], vvidx[0] * nvir + vvidx[1]) occlist0 = numpy.arange(nocc).reshape(1, nocc) occlists = numpy.repeat(occlist0, 1 + nov + bra2aa.size, axis=0) occlist0 = occlists[:1] occlist1 = occlists[1:1 + nov] occlist2 = occlists[1 + nov:] ia = 0 for i in range(nocc): for a in range(nocc, nmo): occlist1[ia, i] = a ia += 1 ia = 0 for i in range(nocc): for j in range(i): for a in range(nocc, nmo): for b in range(nocc, a): occlist2[ia, i] = a occlist2[ia, j] = b ia += 1 na = len(occlists) if DEBUG: trans = numpy.empty((na, na)) for i, idx in enumerate(occlists): s_sub = s[idx].T.copy() minors = s_sub[occlists] trans[i, :] = numpy.linalg.det(minors) # Mimic the transformation einsum('ab,ap->pb', FCI, trans). # The wavefunction FCI has the [excitation_alpha,excitation_beta] # representation. The zero blocks like FCI[S_alpha,D_beta], # FCI[D_alpha,D_beta], are explicitly excluded. bra_mat = numpy.zeros((na, na)) bra_mat[0, 0] = bra0 bra_mat[0, 1:1 + nov] = bra_mat[1:1 + nov, 0] = bra1.ravel() bra_mat[0, 1 + nov:] = bra_mat[1 + nov:, 0] = bra2aa.ravel() bra_mat[1:1 + nov, 1:1 + nov] = bra2.transpose(0, 2, 1, 3).reshape(nov, nov) ket_mat = numpy.zeros((na, na)) ket_mat[0, 0] = ket0 ket_mat[0, 1:1 + nov] = ket_mat[1:1 + nov, 0] = ket1.ravel() ket_mat[0, 1 + nov:] = ket_mat[1 + nov:, 0] = ket2aa.ravel() ket_mat[1:1 + nov, 1:1 + nov] = ket2.transpose(0, 2, 1, 3).reshape(nov, nov) ovlp = lib.einsum('ab,ap,bq,pq->', bra_mat, trans, trans, ket_mat) else: nov1 = 1 + nov noovv = bra2aa.size bra_SS = numpy.zeros((nov1, nov1)) bra_SS[0, 0] = bra0 bra_SS[0, 1:] = bra_SS[1:, 0] = bra1.ravel() bra_SS[1:, 1:] = bra2.transpose(0, 2, 1, 3).reshape(nov, nov) ket_SS = numpy.zeros((nov1, nov1)) ket_SS[0, 0] = ket0 ket_SS[0, 1:] = ket_SS[1:, 0] = ket1.ravel() ket_SS[1:, 1:] = ket2.transpose(0, 2, 1, 3).reshape(nov, nov) trans_SS = numpy.empty((nov1, nov1)) trans_SD = numpy.empty((nov1, noovv)) trans_DS = numpy.empty((noovv, nov1)) occlist01 = occlists[:nov1] for i, idx in enumerate(occlist01): s_sub = s[idx].T.copy() minors = s_sub[occlist01] trans_SS[i, :] = numpy.linalg.det(minors) minors = s_sub[occlist2] trans_SD[i, :] = numpy.linalg.det(minors) s_sub = s[:, idx].copy() minors = s_sub[occlist2] trans_DS[:, i] = numpy.linalg.det(minors) ovlp = lib.einsum('ab,ap,bq,pq->', bra_SS, trans_SS, trans_SS, ket_SS) ovlp += lib.einsum('ab,a ,bq, q->', bra_SS, trans_SS[:, 0], trans_SD, ket2aa.ravel()) ovlp += lib.einsum('ab,ap,b ,p ->', bra_SS, trans_SD, trans_SS[:, 0], ket2aa.ravel()) ovlp += lib.einsum(' b, p,bq,pq->', bra2aa.ravel(), trans_SS[0, :], trans_DS, ket_SS) ovlp += lib.einsum(' b, p,b ,p ->', bra2aa.ravel(), trans_SD[0, :], trans_DS[:, 0], ket2aa.ravel()) ovlp += lib.einsum('a ,ap, q,pq->', bra2aa.ravel(), trans_DS, trans_SS[0, :], ket_SS) ovlp += lib.einsum('a ,a , q, q->', bra2aa.ravel(), trans_DS[:, 0], trans_SD[0, :], ket2aa.ravel()) # FIXME: whether to approximate the overlap between double excitation coefficients if numpy.linalg.norm(bra2aa) * numpy.linalg.norm(ket2aa) < 1e-4: # Skip the overlap if coefficients of double excitation are small enough pass if (abs(numpy.linalg.det(s[:nocc, :nocc]) - 1) < 1e-2 and abs(numpy.linalg.det(s[nocc:, nocc:]) - 1) < 1e-2): # If the overlap matrix close to identity enough, use the <D|D'> overlap # for orthogonal single-particle basis to approximate the overlap # for non-orthogonal basis. ovlp += numpy.dot(bra2aa.ravel(), ket2aa.ravel()) * trans_SS[0, 0] * 2 else: from multiprocessing import sharedctypes, Process buf_ctypes = sharedctypes.RawArray('d', noovv) trans_ket = numpy.ndarray(noovv, buffer=buf_ctypes) def trans_dot_ket(i0, i1): for i in range(i0, i1): s_sub = s[occlist2[i]].T.copy() minors = s_sub[occlist2] trans_ket[i] = numpy.linalg.det(minors).dot(ket2aa.ravel()) nproc = lib.num_threads() if nproc > 1: seg = (noovv + nproc - 1) // nproc ps = [] for i0, i1 in lib.prange(0, noovv, seg): p = Process(target=trans_dot_ket, args=(i0, i1)) ps.append(p) p.start() [p.join() for p in ps] else: trans_dot_ket(0, noovv) ovlp += numpy.dot(bra2aa.ravel(), trans_ket) * trans_SS[0, 0] * 2 return ovlp
def _gamma2_outcore(cc, t1, t2, l1, l2, h5fobj, compress_vvvv=False): t1a, t1b = t1 t2aa, t2ab, t2bb = t2 l1a, l1b = l1 l2aa, l2ab, l2bb = l2 tauaa = t2aa + numpy.einsum('ia,jb->ijab', 2 * t1a, t1a) tauab = t2ab + numpy.einsum('ia,jb->ijab', t1a, t1b) taubb = t2bb + numpy.einsum('ia,jb->ijab', 2 * t1b, t1b) miajb = einsum('ikac,kjcb->iajb', l2aa, t2aa) miajb += einsum('ikac,jkbc->iajb', l2ab, t2ab) miaJB = einsum('ikac,kjcb->iajb', l2aa, t2ab) miaJB += einsum('ikac,kjcb->iajb', l2ab, t2bb) mIAjb = einsum('kica,jkbc->iajb', l2bb, t2ab) mIAjb += einsum('kica,kjcb->iajb', l2ab, t2aa) mIAJB = einsum('ikac,kjcb->iajb', l2bb, t2bb) mIAJB += einsum('kica,kjcb->iajb', l2ab, t2ab) miAjB = einsum('ikca,jkcb->iajb', l2ab, t2ab) mIaJb = einsum('kiac,kjbc->iajb', l2ab, t2ab) goovv = (l2aa.conj() + tauaa) * .25 goOvV = (l2ab.conj() + tauab) * .5 gOOVV = (l2bb.conj() + taubb) * .25 tmpa = einsum('kc,kica->ia', l1a, t2aa) tmpa += einsum('kc,ikac->ia', l1b, t2ab) tmpb = einsum('kc,kica->ia', l1b, t2bb) tmpb += einsum('kc,kica->ia', l1a, t2ab) goovv += einsum('ia,jb->ijab', tmpa, t1a) goOvV += einsum('ia,jb->ijab', tmpa, t1b) * .5 goOvV += einsum('ia,jb->jiba', tmpb, t1a) * .5 gOOVV += einsum('ia,jb->ijab', tmpb, t1b) tmpa = einsum('kc,kb->cb', l1a, t1a) tmpb = einsum('kc,kb->cb', l1b, t1b) goovv += einsum('cb,ijca->ijab', tmpa, t2aa) * .5 goOvV -= einsum('cb,ijac->ijab', tmpb, t2ab) * .5 goOvV -= einsum('cb,jica->jiba', tmpa, t2ab) * .5 gOOVV += einsum('cb,ijca->ijab', tmpb, t2bb) * .5 tmpa = einsum('kc,jc->kj', l1a, t1a) tmpb = einsum('kc,jc->kj', l1b, t1b) goovv += einsum('kiab,kj->ijab', tauaa, tmpa) * .5 goOvV -= einsum('ikab,kj->ijab', tauab, tmpb) * .5 goOvV -= einsum('kiba,kj->jiba', tauab, tmpa) * .5 gOOVV += einsum('kiab,kj->ijab', taubb, tmpb) * .5 tmpa = numpy.einsum('ldjd->lj', miajb) tmpa += numpy.einsum('ldjd->lj', miAjB) tmpb = numpy.einsum('ldjd->lj', mIAJB) tmpb += numpy.einsum('ldjd->lj', mIaJb) goovv -= einsum('lj,liba->ijab', tmpa, tauaa) * .25 goOvV -= einsum('lj,ilab->ijab', tmpb, tauab) * .25 goOvV -= einsum('lj,liba->jiba', tmpa, tauab) * .25 gOOVV -= einsum('lj,liba->ijab', tmpb, taubb) * .25 tmpa = numpy.einsum('ldlb->db', miajb) tmpa += numpy.einsum('ldlb->db', mIaJb) tmpb = numpy.einsum('ldlb->db', mIAJB) tmpb += numpy.einsum('ldlb->db', miAjB) goovv -= einsum('db,jida->ijab', tmpa, tauaa) * .25 goOvV -= einsum('db,ijad->ijab', tmpb, tauab) * .25 goOvV -= einsum('db,jida->jiba', tmpa, tauab) * .25 gOOVV -= einsum('db,jida->ijab', tmpb, taubb) * .25 goovv -= einsum('ldia,ljbd->ijab', miajb, tauaa) * .5 goovv += einsum('LDia,jLbD->ijab', mIAjb, t2ab) * .5 gOOVV -= einsum('ldia,ljbd->ijab', mIAJB, taubb) * .5 gOOVV += einsum('ldia,ljdb->ijab', miaJB, t2ab) * .5 goOvV -= einsum('LDia,LJBD->iJaB', mIAjb, taubb) * .25 goOvV += einsum('ldia,lJdB->iJaB', miajb, t2ab) * .25 goOvV -= einsum('ldIA,ljbd->jIbA', miaJB, tauaa) * .25 goOvV += einsum('LDIA,jLbD->jIbA', mIAJB, t2ab) * .25 goOvV += einsum('lDiA,lJbD->iJbA', miAjB, tauab) * .5 goOvV += einsum('LdIa,jd,LB->jIaB', mIaJb, t1a, t1b) * .5 tmpaa = einsum('klcd,ijcd->ijkl', l2aa, tauaa) * .25**2 tmpbb = einsum('klcd,ijcd->ijkl', l2bb, taubb) * .25**2 tmpabab = einsum('kLcD,iJcD->iJkL', l2ab, tauab) * .5 goovv += einsum('ijkl,klab->ijab', tmpaa, tauaa) goOvV += einsum('ijkl,klab->ijab', tmpabab, tauab) gOOVV += einsum('ijkl,klab->ijab', tmpbb, taubb) goovv = goovv.conj() goOvV = goOvV.conj() gOOVV = gOOVV.conj() gvvvv = einsum('ijab,ijcd->abcd', tauaa, l2aa) * .125 gvVvV = einsum('ijab,ijcd->abcd', tauab, l2ab) * .25 gVVVV = einsum('ijab,ijcd->abcd', taubb, l2bb) * .125 goooo = einsum('ijab,klab->ijkl', l2aa, tauaa) * .125 goOoO = einsum('ijab,klab->ijkl', l2ab, tauab) * .25 gOOOO = einsum('ijab,klab->ijkl', l2bb, taubb) * .125 gooov = einsum('jkba,ib->jkia', tauaa, -0.25 * l1a) goOoV = einsum('jkba,ib->jkia', tauab, -0.5 * l1a) gOoOv = einsum('kjab,ib->jkia', tauab, -0.5 * l1b) gOOOV = einsum('jkba,ib->jkia', taubb, -0.25 * l1b) gooov += einsum('iljk,la->jkia', goooo, t1a) goOoV += einsum('iljk,la->jkia', goOoO, t1b) * 2 gOoOv += einsum('likj,la->jkia', goOoO, t1a) * 2 gOOOV += einsum('iljk,la->jkia', gOOOO, t1b) tmpa = numpy.einsum('icjc->ij', miajb) * .25 tmpa += numpy.einsum('icjc->ij', miAjB) * .25 tmpb = numpy.einsum('icjc->ij', mIAJB) * .25 tmpb += numpy.einsum('icjc->ij', mIaJb) * .25 gooov -= einsum('ij,ka->jkia', tmpa, t1a) goOoV -= einsum('ij,ka->jkia', tmpa, t1b) gOoOv -= einsum('ij,ka->jkia', tmpb, t1a) gOOOV -= einsum('ij,ka->jkia', tmpb, t1b) gooov += einsum('icja,kc->jkia', miajb, .5 * t1a) goOoV += einsum('icja,kc->jkia', miAjB, .5 * t1b) goOoV -= einsum('icJA,kc->kJiA', miaJB, .5 * t1a) gOoOv += einsum('icja,kc->jkia', mIaJb, .5 * t1a) gOoOv -= einsum('ICja,KC->KjIa', mIAjb, .5 * t1b) gOOOV += einsum('icja,kc->jkia', mIAJB, .5 * t1b) gooov = gooov.conj() goOoV = goOoV.conj() gOoOv = gOoOv.conj() gOOOV = gOOOV.conj() gooov += einsum('jkab,ib->jkia', l2aa, .25 * t1a) goOoV -= einsum('jkba,ib->jkia', l2ab, .5 * t1a) gOoOv -= einsum('kjab,ib->jkia', l2ab, .5 * t1b) gOOOV += einsum('jkab,ib->jkia', l2bb, .25 * t1b) govvv = einsum('ja,ijcb->iacb', .25 * l1a, tauaa) goVvV = einsum('ja,ijcb->iacb', .5 * l1b, tauab) gOvVv = einsum('ja,jibc->iacb', .5 * l1a, tauab) gOVVV = einsum('ja,ijcb->iacb', .25 * l1b, taubb) govvv += einsum('bcad,id->iabc', gvvvv, t1a) goVvV -= einsum('bcda,id->iabc', gvVvV, t1a) * 2 gOvVv -= einsum('cbad,id->iabc', gvVvV, t1b) * 2 gOVVV += einsum('bcad,id->iabc', gVVVV, t1b) tmpa = numpy.einsum('kakb->ab', miajb) * .25 tmpa += numpy.einsum('kakb->ab', mIaJb) * .25 tmpb = numpy.einsum('kakb->ab', mIAJB) * .25 tmpb += numpy.einsum('kakb->ab', miAjB) * .25 govvv += einsum('ab,ic->iacb', tmpa, t1a) goVvV += einsum('ab,ic->iacb', tmpb, t1a) gOvVv += einsum('ab,ic->iacb', tmpa, t1b) gOVVV += einsum('ab,ic->iacb', tmpb, t1b) govvv += einsum('kaib,kc->iabc', miajb, .5 * t1a) goVvV += einsum('KAib,KC->iAbC', mIAjb, .5 * t1b) goVvV -= einsum('kAiB,kc->iAcB', miAjB, .5 * t1a) gOvVv += einsum('kaIB,kc->IaBc', miaJB, .5 * t1a) gOvVv -= einsum('KaIb,KC->IaCb', mIaJb, .5 * t1b) gOVVV += einsum('kaib,kc->iabc', mIAJB, .5 * t1b) govvv = govvv.conj() goVvV = goVvV.conj() gOvVv = gOvVv.conj() gOVVV = gOVVV.conj() govvv += einsum('ijbc,ja->iabc', l2aa, .25 * t1a) goVvV += einsum('iJbC,JA->iAbC', l2ab, .5 * t1b) gOvVv += einsum('jIcB,ja->IaBc', l2ab, .5 * t1a) gOVVV += einsum('ijbc,ja->iabc', l2bb, .25 * t1b) govvo = einsum('ia,jb->ibaj', l1a, t1a) goVvO = einsum('ia,jb->ibaj', l1a, t1b) gOvVo = einsum('ia,jb->ibaj', l1b, t1a) gOVVO = einsum('ia,jb->ibaj', l1b, t1b) govvo += numpy.einsum('iajb->ibaj', miajb) goVvO += numpy.einsum('iajb->ibaj', miaJB) gOvVo += numpy.einsum('iajb->ibaj', mIAjb) gOVVO += numpy.einsum('iajb->ibaj', mIAJB) goVoV = numpy.einsum('iajb->ibja', miAjB) gOvOv = numpy.einsum('iajb->ibja', mIaJb) govvo -= einsum('ikac,jc,kb->ibaj', l2aa, t1a, t1a) goVvO -= einsum('iKaC,JC,KB->iBaJ', l2ab, t1b, t1b) gOvVo -= einsum('kIcA,jc,kb->IbAj', l2ab, t1a, t1a) gOVVO -= einsum('ikac,jc,kb->ibaj', l2bb, t1b, t1b) goVoV += einsum('iKcA,jc,KB->iBjA', l2ab, t1a, t1b) gOvOv += einsum('kIaC,JC,kb->IbJa', l2ab, t1b, t1a) dovov = goovv.transpose(0, 2, 1, 3) - goovv.transpose(0, 3, 1, 2) dvvvv = gvvvv.transpose(0, 2, 1, 3) - gvvvv.transpose(0, 3, 1, 2) doooo = goooo.transpose(0, 2, 1, 3) - goooo.transpose(0, 3, 1, 2) dovvv = govvv.transpose(0, 2, 1, 3) - govvv.transpose(0, 3, 1, 2) dooov = gooov.transpose(0, 2, 1, 3) - gooov.transpose(1, 2, 0, 3) dovvo = govvo.transpose(0, 2, 1, 3) dovov = (dovov + dovov.transpose(2, 3, 0, 1)) * .5 dvvvv = dvvvv + dvvvv.transpose(1, 0, 3, 2).conj() doooo = doooo + doooo.transpose(1, 0, 3, 2).conj() dovvo = (dovvo + dovvo.transpose(3, 2, 1, 0).conj()) * .5 doovv = -dovvo.transpose(0, 3, 2, 1) dvvov = None dOVOV = gOOVV.transpose(0, 2, 1, 3) - gOOVV.transpose(0, 3, 1, 2) dVVVV = gVVVV.transpose(0, 2, 1, 3) - gVVVV.transpose(0, 3, 1, 2) dOOOO = gOOOO.transpose(0, 2, 1, 3) - gOOOO.transpose(0, 3, 1, 2) dOVVV = gOVVV.transpose(0, 2, 1, 3) - gOVVV.transpose(0, 3, 1, 2) dOOOV = gOOOV.transpose(0, 2, 1, 3) - gOOOV.transpose(1, 2, 0, 3) dOVVO = gOVVO.transpose(0, 2, 1, 3) dOVOV = (dOVOV + dOVOV.transpose(2, 3, 0, 1)) * .5 dVVVV = dVVVV + dVVVV.transpose(1, 0, 3, 2).conj() dOOOO = dOOOO + dOOOO.transpose(1, 0, 3, 2).conj() dOVVO = (dOVVO + dOVVO.transpose(3, 2, 1, 0).conj()) * .5 dOOVV = -dOVVO.transpose(0, 3, 2, 1) dVVOV = None dovOV = goOvV.transpose(0, 2, 1, 3) dvvVV = gvVvV.transpose(0, 2, 1, 3) * 2 dooOO = goOoO.transpose(0, 2, 1, 3) * 2 dovVV = goVvV.transpose(0, 2, 1, 3) dooOV = goOoV.transpose(0, 2, 1, 3) dovVO = goVvO.transpose(0, 2, 1, 3) dOVvv = gOvVv.transpose(0, 2, 1, 3) dOOov = gOoOv.transpose(0, 2, 1, 3) dOVvo = gOvVo.transpose(0, 2, 1, 3) dooVV = goVoV.transpose(0, 2, 1, 3) dOOvv = gOvOv.transpose(0, 2, 1, 3) dvvVV = dvvVV + dvvVV.transpose(1, 0, 3, 2).conj() dooOO = dooOO + dooOO.transpose(1, 0, 3, 2).conj() dovVO = (dovVO + dOVvo.transpose(3, 2, 1, 0).conj()) * .5 dooVV = -(dooVV + dooVV.transpose(1, 0, 3, 2).conj()) * .5 dvvOV = None dOVov = None dVVvv = None dOOoo = None dOVvo = dovVO.transpose(3, 2, 1, 0).conj() dOOvv = -(dOOvv + dOOvv.transpose(1, 0, 3, 2).conj()) * .5 dVVov = None if compress_vvvv: nocca, noccb, nvira, nvirb = t2ab.shape idxa = numpy.tril_indices(nvira) idxa = idxa[0] * nvira + idxa[1] idxb = numpy.tril_indices(nvirb) idxb = idxb[0] * nvirb + idxb[1] dvvvv = dvvvv + dvvvv.transpose(1, 0, 2, 3) dvvvv = lib.take_2d(dvvvv.reshape(nvira**2, nvira**2), idxa, idxa) dvvvv *= .5 dvvVV = dvvVV + dvvVV.transpose(1, 0, 2, 3) dvvVV = lib.take_2d(dvvVV.reshape(nvira**2, nvirb**2), idxa, idxb) dvvVV *= .5 dVVVV = dVVVV + dVVVV.transpose(1, 0, 2, 3) dVVVV = lib.take_2d(dVVVV.reshape(nvirb**2, nvirb**2), idxb, idxb) dVVVV *= .5 return ((dovov, dovOV, dOVov, dOVOV), (dvvvv, dvvVV, dVVvv, dVVVV), (doooo, dooOO, dOOoo, dOOOO), (doovv, dooVV, dOOvv, dOOVV), (dovvo, dovVO, dOVvo, dOVVO), (dvvov, dvvOV, dVVov, dVVOV), (dovvv, dovVV, dOVvv, dOVVV), (dooov, dooOV, dOOov, dOOOV))
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0): if orbsym is None: return direct_spin1.contract_2e(eri, fcivec, norb, nelec, link_index) eri = ao2mo.restore(4, eri, norb) neleca, nelecb = _unpack_nelec(nelec) link_indexa, link_indexb = direct_spin1._unpack(norb, nelec, link_index) na, nlinka = link_indexa.shape[:2] nb, nlinkb = link_indexb.shape[:2] eri_irs, rank_eri, irrep_eri = reorder_eri(eri, norb, orbsym) strsa = cistring.gen_strings4orblist(range(norb), neleca) aidx, link_indexa = gen_str_irrep(strsa, orbsym, link_indexa, rank_eri, irrep_eri) if neleca == nelecb: bidx, link_indexb = aidx, link_indexa else: strsb = cistring.gen_strings4orblist(range(norb), nelecb) bidx, link_indexb = gen_str_irrep(strsb, orbsym, link_indexb, rank_eri, irrep_eri) Tirrep = ctypes.c_void_p*TOTIRREPS linka_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa]) linkb_ptr = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexb]) eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs]) dimirrep = (ctypes.c_int*TOTIRREPS)(*[x.shape[0] for x in eri_irs]) fcivec_shape = fcivec.shape fcivec = fcivec.reshape((na,nb), order='C') ci1new = numpy.zeros_like(fcivec) nas = (ctypes.c_int*TOTIRREPS)(*[x.size for x in aidx]) nbs = (ctypes.c_int*TOTIRREPS)(*[x.size for x in bidx]) # aa, ab ci0 = [] ci1 = [] for ir in range(TOTIRREPS): ma, mb = aidx[ir].size, bidx[wfnsym^ir].size ci0.append(numpy.zeros((ma,mb))) ci1.append(numpy.zeros((ma,mb))) if ma > 0 and mb > 0: lib.take_2d(fcivec, aidx[ir], bidx[wfnsym^ir], out=ci0[ir]) ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0]) ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1]) libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs, ctypes.c_int(norb), nas, nbs, ctypes.c_int(nlinka), ctypes.c_int(nlinkb), linka_ptr, linkb_ptr, dimirrep, ctypes.c_int(wfnsym)) for ir in range(TOTIRREPS): if ci0[ir].size > 0: lib.takebak_2d(ci1new, ci1[ir], aidx[ir], bidx[wfnsym^ir]) # bb, ba ci0T = [] for ir in range(TOTIRREPS): mb, ma = bidx[ir].size, aidx[wfnsym^ir].size ci0T.append(numpy.zeros((mb,ma))) if ma > 0 and mb > 0: lib.transpose(ci0[wfnsym^ir], out=ci0T[ir]) ci0, ci0T = ci0T, None ci1 = [numpy.zeros_like(x) for x in ci0] ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0]) ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1]) libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs, ctypes.c_int(norb), nbs, nas, ctypes.c_int(nlinkb), ctypes.c_int(nlinka), linkb_ptr, linka_ptr, dimirrep, ctypes.c_int(wfnsym)) for ir in range(TOTIRREPS): if ci0[ir].size > 0: lib.takebak_2d(ci1new, lib.transpose(ci1[ir]), aidx[wfnsym^ir], bidx[ir]) return ci1new.reshape(fcivec_shape)
def _make_eris_incore(myci, mo_coeff=None): cput0 = (time.clock(), time.time()) eris = _UCISD_ERIs(myci, mo_coeff) nocca = eris.nocca noccb = eris.noccb nmoa = eris.focka.shape[0] nmob = eris.fockb.shape[0] nvira = nmoa - nocca nvirb = nmob - noccb moa, mob = eris.mo_coeff eri_aa = ao2mo.restore(1, ao2mo.full(myci._scf._eri, moa), nmoa) eris.oooo = eri_aa[:nocca, :nocca, :nocca, :nocca].copy() eris.ooov = eri_aa[:nocca, :nocca, :nocca, nocca:].copy() eris.vooo = eri_aa[nocca:, :nocca, :nocca, :nocca].copy() eris.oovo = eri_aa[:nocca, :nocca, nocca:, :nocca].copy() eris.voov = eri_aa[nocca:, :nocca, :nocca, nocca:].copy() eris.vvoo = eri_aa[nocca:, nocca:, :nocca, :nocca].copy() eris.oovv = eri_aa[:nocca, :nocca, nocca:, nocca:].copy() eris.vovo = eri_aa[nocca:, :nocca, nocca:, :nocca].copy() eris.vovv = eri_aa[nocca:, :nocca, nocca:, nocca:].copy() #vovv = eri_aa[nocca:,:nocca,nocca:,nocca:].reshape(-1,nvira,nvira) #eris.vovv = lib.pack_tril(vovv).reshape(nvira,nocca,nvira*(nvira+1)//2) eris.vvvv = ao2mo.restore(4, eri_aa[nocca:, nocca:, nocca:, nocca:].copy(), nvira) vovv = eri_aa = None eri_bb = ao2mo.restore(1, ao2mo.full(myci._scf._eri, mob), nmob) eris.OOOO = eri_bb[:noccb, :noccb, :noccb, :noccb].copy() eris.OOOV = eri_bb[:noccb, :noccb, :noccb, noccb:].copy() eris.VOOO = eri_bb[noccb:, :noccb, :noccb, :noccb].copy() eris.OOVO = eri_bb[:noccb, :noccb, noccb:, :noccb].copy() eris.VOOV = eri_bb[noccb:, :noccb, :noccb, noccb:].copy() eris.VVOO = eri_bb[noccb:, noccb:, :noccb, :noccb].copy() eris.OOVV = eri_bb[:noccb, :noccb, noccb:, noccb:].copy() eris.VOVO = eri_bb[noccb:, :noccb, noccb:, :noccb].copy() eris.VOVV = eri_bb[noccb:, :noccb, noccb:, noccb:].copy() #VOVV = eri_bb[noccb:,:noccb,noccb:,noccb:].reshape(-1,nvirb,nvirb) #eris.VOVV = lib.pack_tril(VOVV).reshape(nvirb,noccb,nvirb*(nvirb+1)//2) eris.VVVV = ao2mo.restore(4, eri_bb[noccb:, noccb:, noccb:, noccb:].copy(), nvirb) VOVV = eri_bb = None eri_ab = ao2mo.general(myci._scf._eri, (moa, moa, mob, mob), compact=False) eri_ab = eri_ab.reshape(nmoa, nmoa, nmob, nmob) eris.ooOO = eri_ab[:nocca, :nocca, :noccb, :noccb].copy() eris.ooOV = eri_ab[:nocca, :nocca, :noccb, noccb:].copy() eris.voOO = eri_ab[nocca:, :nocca, :noccb, :noccb].copy() eris.ooVO = eri_ab[:nocca, :nocca, noccb:, :noccb].copy() eris.voOV = eri_ab[nocca:, :nocca, :noccb, noccb:].copy() eris.ooVV = eri_ab[:nocca, :nocca, noccb:, noccb:].copy() eris.vvOO = eri_ab[nocca:, nocca:, :noccb, :noccb].copy() eris.voVO = eri_ab[nocca:, :nocca, noccb:, :noccb].copy() eris.voVV = eri_ab[nocca:, :nocca, noccb:, noccb:].copy() #voVV = eri_ab[nocca:,:nocca,noccb:,noccb:].reshape(nocca*nvira,nvirb,nvirb) #eris.voVV = lib.pack_tril(voVV).reshape(nvira,nocca,nvirb*(nvirb+1)//2) voVV = None vvVV = eri_ab[nocca:, nocca:, noccb:, noccb:].reshape(nvira**2, nvirb**2) idxa = numpy.tril_indices(nvira) idxb = numpy.tril_indices(nvirb) eris.vvVV = lib.take_2d(vvVV, idxa[0] * nvira + idxa[1], idxb[0] * nvirb + idxb[1]) eri_ba = lib.transpose(eri_ab.reshape(nmoa**2, nmob**2)) eri_ba = eri_ba.reshape(nmob, nmob, nmoa, nmoa) eris.OOoo = eri_ba[:noccb, :noccb, :nocca, :nocca].copy() eris.OOov = eri_ba[:noccb, :noccb, :nocca, nocca:].copy() eris.VOoo = eri_ba[noccb:, :noccb, :nocca, :nocca].copy() eris.OOvo = eri_ba[:noccb, :noccb, nocca:, :nocca].copy() eris.VOov = eri_ba[noccb:, :noccb, :nocca, nocca:].copy() eris.VVoo = eri_ba[noccb:, noccb:, :nocca, :nocca].copy() eris.VOvo = eri_ba[noccb:, :noccb, nocca:, :nocca].copy() eris.VOvv = eri_ba[noccb:, :noccb, nocca:, nocca:].copy() #VOvv = eri_ba[noccb:,:noccb,nocca:,nocca:].reshape(noccb*nvirb,nvira,nvira) #eris.VOvv = lib.pack_tril(VOvv).reshape(nvirb,noccb,nvira*(nvira+1)//2) VOvv = None eris.VVvv = eri_ba[noccb:, noccb:, nocca:, nocca:].copy() return eris
def _ao2mo_ovov(mp, orbo, orbv, feri, max_memory=2000, verbose=None): time0 = (time.clock(), time.time()) log = logger.new_logger(mp, verbose) mol = mp.mol int2e = mol._add_suffix('int2e') ao2mopt = _ao2mo.AO2MOpt(mol, int2e, 'CVHFnr_schwarz_cond', 'CVHFsetnr_direct_scf') nao, nocc = orbo.shape nvir = orbv.shape[1] nbas = mol.nbas assert(nvir <= nao) ao_loc = mol.ao_loc_nr() dmax = max(4, min(nao/3, numpy.sqrt(max_memory*.95e6/8/(nao+nocc)**2))) sh_ranges = ao2mo.outcore.balance_partition(ao_loc, dmax) dmax = max(x[2] for x in sh_ranges) eribuf = numpy.empty((nao,dmax,dmax,nao)) ftmp = lib.H5TmpFile() log.debug('max_memory %s MB (dmax = %s) required disk space %g MB', max_memory, dmax, nocc**2*(nao*(nao+dmax)/2+nvir**2)*8/1e6) buf_i = numpy.empty((nocc*dmax**2*nao)) buf_li = numpy.empty((nocc**2*dmax**2)) buf1 = numpy.empty_like(buf_li) fint = gto.moleintor.getints4c jk_blk_slices = [] count = 0 time1 = time0 with lib.call_in_background(ftmp.__setitem__) as save: for ip, (ish0, ish1, ni) in enumerate(sh_ranges): for jsh0, jsh1, nj in sh_ranges[:ip+1]: i0, i1 = ao_loc[ish0], ao_loc[ish1] j0, j1 = ao_loc[jsh0], ao_loc[jsh1] jk_blk_slices.append((i0,i1,j0,j1)) eri = fint(int2e, mol._atm, mol._bas, mol._env, shls_slice=(0,nbas,ish0,ish1, jsh0,jsh1,0,nbas), aosym='s1', ao_loc=ao_loc, cintopt=ao2mopt._cintopt, out=eribuf) tmp_i = numpy.ndarray((nocc,(i1-i0)*(j1-j0)*nao), buffer=buf_i) tmp_li = numpy.ndarray((nocc,nocc*(i1-i0)*(j1-j0)), buffer=buf_li) lib.ddot(orbo.T, eri.reshape(nao,(i1-i0)*(j1-j0)*nao), c=tmp_i) lib.ddot(orbo.T, tmp_i.reshape(nocc*(i1-i0)*(j1-j0),nao).T, c=tmp_li) tmp_li = tmp_li.reshape(nocc,nocc,(i1-i0),(j1-j0)) save(str(count), tmp_li.transpose(1,0,2,3)) buf_li, buf1 = buf1, buf_li count += 1 time1 = log.timer_debug1('partial ao2mo [%d:%d,%d:%d]' % (ish0,ish1,jsh0,jsh1), *time1) time1 = time0 = log.timer('mp2 ao2mo_ovov pass1', *time0) eri = eribuf = tmp_i = tmp_li = buf_i = buf_li = buf1 = None chunks = (nvir,nvir) h5dat = feri.create_dataset('ovov', (nocc*nvir,nocc*nvir), 'f8', chunks=chunks) # jk_where is the sorting indices for the stacked (oO|pP) integrals in pass 2 jk_where = [] aoao_idx = numpy.arange(nao*nao).reshape(nao,nao) for i0, i1, j0, j1 in jk_blk_slices: # idx of pP in <oO|pP> jk_where.append(aoao_idx[i0:i1,j0:j1].ravel()) if i0 != j0: # idx of pP in (<oO|pP>).transpose(1,0,3,2) jk_where.append(aoao_idx[j0:j1,i0:i1].ravel()) jk_where = numpy.argsort(numpy.hstack(jk_where)).astype(numpy.int32) orbv = numpy.asarray(orbv, order='F') occblk = int(min(nocc, max(4, 250/nocc, max_memory*.9e6/8/(nao**2*nocc)/5))) def load(i0, eri): if i0 >= nocc: return i1 = min(i0+occblk, nocc) eri = eri[:(i1-i0)*nocc] p1 = 0 for k, jk_slice in enumerate(jk_blk_slices): dat = numpy.asarray(ftmp[str(k)][i0:i1]).reshape((i1-i0)*nocc,-1) p0, p1 = p1, p1 + dat.shape[1] eri[:,p0:p1] = dat if jk_slice[0] != jk_slice[2]: dat = numpy.asarray(ftmp[str(k)][:,i0:i1]) dat = dat.transpose(1,0,3,2).reshape((i1-i0)*nocc,-1) p0, p1 = p1, p1 + dat.shape[1] eri[:,p0:p1] = dat def save(i0, i1, dat): for i in range(i0, i1): h5dat[i*nvir:(i+1)*nvir] = dat[i-i0].reshape(nvir,nocc*nvir) buf_prefecth = numpy.empty((occblk*nocc,nao**2)) buf = numpy.empty_like(buf_prefecth) buf1 = numpy.empty_like(buf_prefecth) bufw = numpy.empty((occblk*nocc,nvir**2)) bufw1 = numpy.empty_like(bufw) with lib.call_in_background(load) as prefetch: with lib.call_in_background(save) as bsave: load(0, buf_prefecth) for i0, i1 in lib.prange(0, nocc, occblk): buf, buf_prefecth = buf_prefecth, buf eri = buf[:(i1-i0)*nocc] prefetch(i1, buf_prefecth) idx = numpy.arange(eri.shape[0], dtype=numpy.int32) dat = lib.take_2d(eri, idx, jk_where, out=buf1) dat = _ao2mo.nr_e2(dat, orbv, (0,nvir,0,nvir), 's1', 's1', out=bufw) bsave(i0, i1, dat.reshape(i1-i0,nocc,nvir,nvir).transpose(0,2,1,3)) bufw, bufw1 = bufw1, bufw time1 = log.timer_debug1('pass2 ao2mo [%d:%d]' % (i0,i1), *time1) time0 = log.timer('mp2 ao2mo_ovov pass2', *time0) return h5dat
def restore(symmetry, eri, norb, tao=None): r'''Convert the 2e integrals (in Chemist's notation) between different level of permutation symmetry (8-fold, 4-fold, or no symmetry) Args: symmetry : int or str code to present the target symmetry of 2e integrals | 's8' or '8' or 8 : 8-fold symmetry | 's4' or '4' or 4 : 4-fold symmetry | 's1' or '1' or 1 : no symmetry | 's2ij' or '2ij' : symmetric ij pair for (ij|kl) (TODO) | 's2ij' or '2kl' : symmetric kl pair for (ij|kl) (TODO) Note the 4-fold symmetry requires (ij|kl) == (ij|lk) == (ij|lk) while (ij|kl) != (kl|ij) is not required. eri : ndarray The symmetry of eri is determined by the size of eri and norb norb : int The symmetry of eri is determined by the size of eri and norb Returns: ndarray. The shape depends on the target symmetry. | 8 : (norb*(norb+1)/2)*(norb*(norb+1)/2+1)/2 | 4 : (norb*(norb+1)/2, norb*(norb+1)/2) | 1 : (norb, norb, norb, norb) 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') >>> eri1 = ao2mo.restore(1, eri, mol.nao_nr()) >>> eri4 = ao2mo.restore(4, eri, mol.nao_nr()) >>> eri8 = ao2mo.restore(8, eri, mol.nao_nr()) >>> print(eri1.shape) (7, 7, 7, 7) >>> print(eri1.shape) (28, 28) >>> print(eri1.shape) (406,) ''' targetsym = _stand_sym_code(symmetry) if targetsym not in ('8', '4', '1', '2kl', '2ij'): raise ValueError('symmetry = %s' % symmetry) if eri.dtype != numpy.double: raise RuntimeError('Complex integrals not supported') eri = numpy.asarray(eri, order='C') npair = norb*(norb+1)//2 if eri.size == norb**4: # s1 if targetsym == '1': return eri.reshape(norb,norb,norb,norb) elif targetsym == '2kl': eri = lib.pack_tril(eri.reshape(norb**2,norb,norb)) return eri.reshape(norb,norb,npair) elif targetsym == '2ij': eri = lib.pack_tril(eri.reshape(norb,norb,norb**2), axis=0) return eri.reshape(npair,norb,norb) else: return _convert('1', targetsym, eri, norb) elif eri.size == npair**2: # s4 if targetsym == '4': return eri.reshape(npair,npair) elif targetsym == '8': return lib.pack_tril(eri.reshape(npair,npair)) elif targetsym == '2kl': return lib.unpack_tril(eri, lib.SYMMETRIC, axis=0) elif targetsym == '2ij': return lib.unpack_tril(eri, lib.SYMMETRIC, axis=-1) else: return _convert('4', targetsym, eri, norb) elif eri.size == npair*(npair+1)//2: # 8-fold if targetsym == '8': return eri.ravel() elif targetsym == '4': return lib.unpack_tril(eri.ravel(), lib.SYMMETRIC) elif targetsym == '2kl': return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=0) elif targetsym == '2ij': return lib.unpack_tril(lib.unpack_tril(eri.ravel()), lib.SYMMETRIC, axis=-1) else: return _convert('8', targetsym, eri, norb) elif eri.size == npair*norb**2 and eri.shape[0] == npair: # s2ij if targetsym == '2ij': return eri.reshape(npair,norb,norb) elif targetsym == '8': eri = lib.pack_tril(eri.reshape(npair,norb,norb)) return lib.pack_tril(eri) elif targetsym == '4': return lib.pack_tril(eri.reshape(npair,norb,norb)) elif targetsym == '1': eri = lib.unpack_tril(eri.reshape(npair,norb**2), lib.SYMMETRIC, axis=0) return eri.reshape(norb,norb,norb,norb) elif targetsym == '2kl': tril2sq = lib.square_mat_in_trilu_indices(norb) trilidx = numpy.tril_indices(norb) eri = lib.take_2d(eri.reshape(npair,norb**2), tril2sq.ravel(), trilidx[0]*norb+trilidx[1]) return eri.reshape(norb,norb,npair) elif eri.size == npair*norb**2 and eri.shape[-1] == npair: # s2kl if targetsym == '2kl': return eri.reshape(norb,norb,npair) elif targetsym == '8': eri = lib.pack_tril(eri.reshape(norb,norb,npair), axis=0) return lib.pack_tril(eri) elif targetsym == '4': return lib.pack_tril(eri.reshape(norb,norb,npair), axis=0) elif targetsym == '1': eri = lib.unpack_tril(eri.reshape(norb**2,npair), lib.SYMMETRIC, axis=-1) return eri.reshape(norb,norb,norb,norb) elif targetsym == '2ij': tril2sq = lib.square_mat_in_trilu_indices(norb) trilidx = numpy.tril_indices(norb) eri = lib.take_2d(eri.reshape(norb**2,npair), trilidx[0]*norb+trilidx[1], tril2sq.ravel()) return eri.reshape(npair,norb,norb) else: raise RuntimeError('eri.size = %d, norb = %d' % (eri.size, norb))
def overlap(cibra, ciket, nmo, nocc, s=None): '''Overlap between two CISD wavefunctions. Args: s : a list of 2D arrays The overlap matrix of non-orthogonal one-particle basis ''' if s is None: return dot(cibra, ciket, nmo, nocc) if isinstance(nmo, (int, numpy.integer)): nmoa = nmob = nmo else: nmoa, nmob = nmo nocca, noccb = nocc nvira, nvirb = nmoa - nocca, nmob - noccb bra0, bra1, bra2 = cisdvec_to_amplitudes(cibra, (nmoa, nmob), nocc) ket0, ket1, ket2 = cisdvec_to_amplitudes(ciket, (nmoa, nmob), nocc) ooidx = numpy.tril_indices(nocca, -1) vvidx = numpy.tril_indices(nvira, -1) bra2aa = lib.take_2d(bra2[0].reshape(nocca**2, nvira**2), ooidx[0] * nocca + ooidx[1], vvidx[0] * nvira + vvidx[1]) ket2aa = lib.take_2d(ket2[0].reshape(nocca**2, nvira**2), ooidx[0] * nocca + ooidx[1], vvidx[0] * nvira + vvidx[1]) ooidx = numpy.tril_indices(noccb, -1) vvidx = numpy.tril_indices(nvirb, -1) bra2bb = lib.take_2d(bra2[2].reshape(noccb**2, nvirb**2), ooidx[0] * noccb + ooidx[1], vvidx[0] * nvirb + vvidx[1]) ket2bb = lib.take_2d(ket2[2].reshape(noccb**2, nvirb**2), ooidx[0] * noccb + ooidx[1], vvidx[0] * nvirb + vvidx[1]) nova = nocca * nvira novb = noccb * nvirb occlist0a = numpy.arange(nocca).reshape(1, nocca) occlist0b = numpy.arange(noccb).reshape(1, noccb) occlistsa = numpy.repeat(occlist0a, 1 + nova + bra2aa.size, axis=0) occlistsb = numpy.repeat(occlist0b, 1 + novb + bra2bb.size, axis=0) occlist0a = occlistsa[:1] occlist1a = occlistsa[1:1 + nova] occlist2a = occlistsa[1 + nova:] occlist0b = occlistsb[:1] occlist1b = occlistsb[1:1 + novb] occlist2b = occlistsb[1 + novb:] ia = 0 for i in range(nocca): for a in range(nocca, nmoa): occlist1a[ia, i] = a ia += 1 ia = 0 for i in range(noccb): for a in range(noccb, nmob): occlist1b[ia, i] = a ia += 1 ia = 0 for i in range(nocca): for j in range(i): for a in range(nocca, nmoa): for b in range(nocca, a): occlist2a[ia, i] = a occlist2a[ia, j] = b ia += 1 ia = 0 for i in range(noccb): for j in range(i): for a in range(noccb, nmob): for b in range(noccb, a): occlist2b[ia, i] = a occlist2b[ia, j] = b ia += 1 na = len(occlistsa) trans_a = numpy.empty((na, na)) for i, idx in enumerate(occlistsa): s_sub = s[0][idx].T.copy() minors = s_sub[occlistsa] trans_a[i, :] = numpy.linalg.det(minors) nb = len(occlistsb) trans_b = numpy.empty((nb, nb)) for i, idx in enumerate(occlistsb): s_sub = s[1][idx].T.copy() minors = s_sub[occlistsb] trans_b[i, :] = numpy.linalg.det(minors) # Mimic the transformation einsum('ab,ap->pb', FCI, trans). # The wavefunction FCI has the [excitation_alpha,excitation_beta] # representation. The zero blocks like FCI[S_alpha,D_beta], # FCI[D_alpha,D_beta], are explicitly excluded. bra_mat = numpy.zeros((na, nb)) bra_mat[0, 0] = bra0 bra_mat[1:1 + nova, 0] = bra1[0].ravel() bra_mat[0, 1:1 + novb] = bra1[1].ravel() bra_mat[1 + nova:, 0] = bra2aa.ravel() bra_mat[0, 1 + novb:] = bra2bb.ravel() bra_mat[1:1 + nova, 1:1 + novb] = bra2[1].transpose(0, 2, 1, 3).reshape(nova, novb) c_s = lib.einsum('ab,ap,bq->pq', bra_mat, trans_a, trans_b) ovlp = c_s[0, 0] * ket0 ovlp += numpy.dot(c_s[1:1 + nova, 0], ket1[0].ravel()) ovlp += numpy.dot(c_s[0, 1:1 + novb], ket1[1].ravel()) ovlp += numpy.dot(c_s[1 + nova:, 0], ket2aa.ravel()) ovlp += numpy.dot(c_s[0, 1 + novb:], ket2bb.ravel()) ovlp += numpy.einsum( 'ijab,iajb->', ket2[1], c_s[1:1 + nova, 1:1 + novb].reshape(nocca, nvira, noccb, nvirb)) return ovlp
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None, wfnsym=0): if orbsym is None: return direct_spin1.contract_2e(eri, fcivec, norb, nelec, link_index) eri = ao2mo.restore(4, eri, norb) neleca, nelecb = _unpack_nelec(nelec) link_indexa, link_indexb = direct_spin1._unpack(norb, nelec, link_index) na, nlinka = link_indexa.shape[:2] nb, nlinkb = link_indexb.shape[:2] eri_irs, rank_eri, irrep_eri = reorder_eri(eri, norb, orbsym) strsa = cistring.gen_strings4orblist(range(norb), neleca) aidx, link_indexa = gen_str_irrep(strsa, orbsym, link_indexa, rank_eri, irrep_eri) if neleca == nelecb: bidx, link_indexb = aidx, link_indexa else: strsb = cistring.gen_strings4orblist(range(norb), nelecb) bidx, link_indexb = gen_str_irrep(strsb, orbsym, link_indexb, rank_eri, irrep_eri) Tirrep = ctypes.c_void_p * TOTIRREPS linka_ptr = Tirrep( *[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexa]) linkb_ptr = Tirrep( *[x.ctypes.data_as(ctypes.c_void_p) for x in link_indexb]) eri_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in eri_irs]) dimirrep = (ctypes.c_int * TOTIRREPS)(*[x.shape[0] for x in eri_irs]) fcivec_shape = fcivec.shape fcivec = fcivec.reshape((na, nb), order='C') ci1new = numpy.zeros_like(fcivec) nas = (ctypes.c_int * TOTIRREPS)(*[x.size for x in aidx]) nbs = (ctypes.c_int * TOTIRREPS)(*[x.size for x in bidx]) # aa, ab ci0 = [] ci1 = [] for ir in range(TOTIRREPS): ma, mb = aidx[ir].size, bidx[wfnsym ^ ir].size ci0.append(numpy.zeros((ma, mb))) ci1.append(numpy.zeros((ma, mb))) if ma > 0 and mb > 0: lib.take_2d(fcivec, aidx[ir], bidx[wfnsym ^ ir], out=ci0[ir]) ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0]) ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1]) libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs, ctypes.c_int(norb), nas, nbs, ctypes.c_int(nlinka), ctypes.c_int(nlinkb), linka_ptr, linkb_ptr, dimirrep, ctypes.c_int(wfnsym)) for ir in range(TOTIRREPS): if ci0[ir].size > 0: lib.takebak_2d(ci1new, ci1[ir], aidx[ir], bidx[wfnsym ^ ir]) # bb, ba ci0T = [] for ir in range(TOTIRREPS): mb, ma = bidx[ir].size, aidx[wfnsym ^ ir].size ci0T.append(numpy.zeros((mb, ma))) if ma > 0 and mb > 0: lib.transpose(ci0[wfnsym ^ ir], out=ci0T[ir]) ci0, ci0T = ci0T, None ci1 = [numpy.zeros_like(x) for x in ci0] ci0_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci0]) ci1_ptrs = Tirrep(*[x.ctypes.data_as(ctypes.c_void_p) for x in ci1]) libfci.FCIcontract_2e_symm1(eri_ptrs, ci0_ptrs, ci1_ptrs, ctypes.c_int(norb), nbs, nas, ctypes.c_int(nlinkb), ctypes.c_int(nlinka), linkb_ptr, linka_ptr, dimirrep, ctypes.c_int(wfnsym)) for ir in range(TOTIRREPS): if ci0[ir].size > 0: lib.takebak_2d(ci1new, lib.transpose(ci1[ir]), aidx[wfnsym ^ ir], bidx[ir]) return ci1new.reshape(fcivec_shape)
def overlap(cibra, ciket, nmo, nocc, s=None): '''Overlap between two CISD wavefunctions. Args: s : a list of 2D arrays The overlap matrix of non-orthogonal one-particle basis ''' if s is None: return dot(cibra, ciket, nmo, nocc) if isinstance(nmo, (int, numpy.integer)): nmoa = nmob = nmo else: nmoa, nmob = nmo nocca, noccb = nocc nvira, nvirb = nmoa - nocca, nmob - noccb bra0, bra1, bra2 = cisdvec_to_amplitudes(cibra, (nmoa,nmob), nocc) ket0, ket1, ket2 = cisdvec_to_amplitudes(ciket, (nmoa,nmob), nocc) ooidx = numpy.tril_indices(nocca, -1) vvidx = numpy.tril_indices(nvira, -1) bra2aa = lib.take_2d(bra2[0].reshape(nocca**2,nvira**2), ooidx[0]*nocca+ooidx[1], vvidx[0]*nvira+vvidx[1]) ket2aa = lib.take_2d(ket2[0].reshape(nocca**2,nvira**2), ooidx[0]*nocca+ooidx[1], vvidx[0]*nvira+vvidx[1]) ooidx = numpy.tril_indices(noccb, -1) vvidx = numpy.tril_indices(nvirb, -1) bra2bb = lib.take_2d(bra2[2].reshape(noccb**2,nvirb**2), ooidx[0]*noccb+ooidx[1], vvidx[0]*nvirb+vvidx[1]) ket2bb = lib.take_2d(ket2[2].reshape(noccb**2,nvirb**2), ooidx[0]*noccb+ooidx[1], vvidx[0]*nvirb+vvidx[1]) nova = nocca * nvira novb = noccb * nvirb occlist0a = numpy.arange(nocca).reshape(1,nocca) occlist0b = numpy.arange(noccb).reshape(1,noccb) occlistsa = numpy.repeat(occlist0a, 1+nova+bra2aa.size, axis=0) occlistsb = numpy.repeat(occlist0b, 1+novb+bra2bb.size, axis=0) occlist0a = occlistsa[:1] occlist1a = occlistsa[1:1+nova] occlist2a = occlistsa[1+nova:] occlist0b = occlistsb[:1] occlist1b = occlistsb[1:1+novb] occlist2b = occlistsb[1+novb:] ia = 0 for i in range(nocca): for a in range(nocca, nmoa): occlist1a[ia,i] = a ia += 1 ia = 0 for i in range(noccb): for a in range(noccb, nmob): occlist1b[ia,i] = a ia += 1 ia = 0 for i in range(nocca): for j in range(i): for a in range(nocca, nmoa): for b in range(nocca, a): occlist2a[ia,i] = a occlist2a[ia,j] = b ia += 1 ia = 0 for i in range(noccb): for j in range(i): for a in range(noccb, nmob): for b in range(noccb, a): occlist2b[ia,i] = a occlist2b[ia,j] = b ia += 1 na = len(occlistsa) trans_a = numpy.empty((na,na)) for i, idx in enumerate(occlistsa): s_sub = s[0][idx].T.copy() minors = s_sub[occlistsa] trans_a[i,:] = numpy.linalg.det(minors) nb = len(occlistsb) trans_b = numpy.empty((nb,nb)) for i, idx in enumerate(occlistsb): s_sub = s[1][idx].T.copy() minors = s_sub[occlistsb] trans_b[i,:] = numpy.linalg.det(minors) # Mimic the transformation einsum('ab,ap->pb', FCI, trans). # The wavefunction FCI has the [excitation_alpha,excitation_beta] # representation. The zero blocks like FCI[S_alpha,D_beta], # FCI[D_alpha,D_beta], are explicitly excluded. bra_mat = numpy.zeros((na,nb)) bra_mat[0,0] = bra0 bra_mat[1:1+nova,0] = bra1[0].ravel() bra_mat[0,1:1+novb] = bra1[1].ravel() bra_mat[1+nova:,0] = bra2aa.ravel() bra_mat[0,1+novb:] = bra2bb.ravel() bra_mat[1:1+nova,1:1+novb] = bra2[1].transpose(0,2,1,3).reshape(nova,novb) c_s = lib.einsum('ab,ap,bq->pq', bra_mat, trans_a, trans_b) ovlp = c_s[0,0] * ket0 ovlp += numpy.dot(c_s[1:1+nova,0], ket1[0].ravel()) ovlp += numpy.dot(c_s[0,1:1+novb], ket1[1].ravel()) ovlp += numpy.dot(c_s[1+nova:,0] , ket2aa.ravel()) ovlp += numpy.dot(c_s[0,1+novb:] , ket2bb.ravel()) ovlp += numpy.einsum('ijab,iajb->', ket2[1], c_s[1:1+nova,1:1+novb].reshape(nocca,nvira,noccb,nvirb)) return ovlp
def _gamma2_outcore(cc, t1, t2, l1, l2, h5fobj, compress_vvvv=False): t1a, t1b = t1 t2aa, t2ab, t2bb = t2 l1a, l1b = l1 l2aa, l2ab, l2bb = l2 tauaa = t2aa + numpy.einsum('ia,jb->ijab', 2*t1a, t1a) tauab = t2ab + numpy.einsum('ia,jb->ijab', t1a, t1b) taubb = t2bb + numpy.einsum('ia,jb->ijab', 2*t1b, t1b) miajb = einsum('ikac,kjcb->iajb', l2aa, t2aa) miajb+= einsum('ikac,jkbc->iajb', l2ab, t2ab) miaJB = einsum('ikac,kjcb->iajb', l2aa, t2ab) miaJB+= einsum('ikac,kjcb->iajb', l2ab, t2bb) mIAjb = einsum('kica,jkbc->iajb', l2bb, t2ab) mIAjb+= einsum('kica,kjcb->iajb', l2ab, t2aa) mIAJB = einsum('ikac,kjcb->iajb', l2bb, t2bb) mIAJB+= einsum('kica,kjcb->iajb', l2ab, t2ab) miAjB = einsum('ikca,jkcb->iajb', l2ab, t2ab) mIaJb = einsum('kiac,kjbc->iajb', l2ab, t2ab) goovv = (l2aa.conj() + tauaa) * .25 goOvV = (l2ab.conj() + tauab) * .5 gOOVV = (l2bb.conj() + taubb) * .25 tmpa = einsum('kc,kica->ia', l1a, t2aa) tmpa += einsum('kc,ikac->ia', l1b, t2ab) tmpb = einsum('kc,kica->ia', l1b, t2bb) tmpb += einsum('kc,kica->ia', l1a, t2ab) goovv += einsum('ia,jb->ijab', tmpa, t1a) goOvV += einsum('ia,jb->ijab', tmpa, t1b) * .5 goOvV += einsum('ia,jb->jiba', tmpb, t1a) * .5 gOOVV += einsum('ia,jb->ijab', tmpb, t1b) tmpa = einsum('kc,kb->cb', l1a, t1a) tmpb = einsum('kc,kb->cb', l1b, t1b) goovv += einsum('cb,ijca->ijab', tmpa, t2aa) * .5 goOvV -= einsum('cb,ijac->ijab', tmpb, t2ab) * .5 goOvV -= einsum('cb,jica->jiba', tmpa, t2ab) * .5 gOOVV += einsum('cb,ijca->ijab', tmpb, t2bb) * .5 tmpa = einsum('kc,jc->kj', l1a, t1a) tmpb = einsum('kc,jc->kj', l1b, t1b) goovv += einsum('kiab,kj->ijab', tauaa, tmpa) * .5 goOvV -= einsum('ikab,kj->ijab', tauab , tmpb) * .5 goOvV -= einsum('kiba,kj->jiba', tauab , tmpa) * .5 gOOVV += einsum('kiab,kj->ijab', taubb, tmpb) * .5 tmpa = numpy.einsum('ldjd->lj', miajb) tmpa += numpy.einsum('ldjd->lj', miAjB) tmpb = numpy.einsum('ldjd->lj', mIAJB) tmpb += numpy.einsum('ldjd->lj', mIaJb) goovv -= einsum('lj,liba->ijab', tmpa, tauaa) * .25 goOvV -= einsum('lj,ilab->ijab', tmpb, tauab) * .25 goOvV -= einsum('lj,liba->jiba', tmpa, tauab) * .25 gOOVV -= einsum('lj,liba->ijab', tmpb, taubb) * .25 tmpa = numpy.einsum('ldlb->db', miajb) tmpa += numpy.einsum('ldlb->db', mIaJb) tmpb = numpy.einsum('ldlb->db', mIAJB) tmpb += numpy.einsum('ldlb->db', miAjB) goovv -= einsum('db,jida->ijab', tmpa, tauaa) * .25 goOvV -= einsum('db,ijad->ijab', tmpb, tauab) * .25 goOvV -= einsum('db,jida->jiba', tmpa, tauab) * .25 gOOVV -= einsum('db,jida->ijab', tmpb, taubb) * .25 goovv -= einsum('ldia,ljbd->ijab', miajb, tauaa) * .5 goovv += einsum('LDia,jLbD->ijab', mIAjb, t2ab ) * .5 gOOVV -= einsum('ldia,ljbd->ijab', mIAJB, taubb) * .5 gOOVV += einsum('ldia,ljdb->ijab', miaJB, t2ab ) * .5 goOvV -= einsum('LDia,LJBD->iJaB', mIAjb, taubb) * .25 goOvV += einsum('ldia,lJdB->iJaB', miajb, t2ab ) * .25 goOvV -= einsum('ldIA,ljbd->jIbA', miaJB, tauaa) * .25 goOvV += einsum('LDIA,jLbD->jIbA', mIAJB, t2ab ) * .25 goOvV += einsum('lDiA,lJbD->iJbA', miAjB, tauab) * .5 goOvV += einsum('LdIa,jd,LB->jIaB', mIaJb, t1a, t1b) * .5 tmpaa = einsum('klcd,ijcd->ijkl', l2aa, tauaa) * .25**2 tmpbb = einsum('klcd,ijcd->ijkl', l2bb, taubb) * .25**2 tmpabab = einsum('kLcD,iJcD->iJkL', l2ab, tauab) * .5 goovv += einsum('ijkl,klab->ijab', tmpaa, tauaa) goOvV += einsum('ijkl,klab->ijab', tmpabab, tauab) gOOVV += einsum('ijkl,klab->ijab', tmpbb, taubb) goovv = goovv.conj() goOvV = goOvV.conj() gOOVV = gOOVV.conj() gvvvv = einsum('ijab,ijcd->abcd', tauaa, l2aa) * .125 gvVvV = einsum('ijab,ijcd->abcd', tauab, l2ab) * .25 gVVVV = einsum('ijab,ijcd->abcd', taubb, l2bb) * .125 goooo = einsum('ijab,klab->ijkl', l2aa, tauaa) * .125 goOoO = einsum('ijab,klab->ijkl', l2ab, tauab) * .25 gOOOO = einsum('ijab,klab->ijkl', l2bb, taubb) * .125 gooov = einsum('jkba,ib->jkia', tauaa, -0.25 * l1a) goOoV = einsum('jkba,ib->jkia', tauab, -0.5 * l1a) gOoOv = einsum('kjab,ib->jkia', tauab, -0.5 * l1b) gOOOV = einsum('jkba,ib->jkia', taubb, -0.25 * l1b) gooov += einsum('iljk,la->jkia', goooo, t1a) goOoV += einsum('iljk,la->jkia', goOoO, t1b) * 2 gOoOv += einsum('likj,la->jkia', goOoO, t1a) * 2 gOOOV += einsum('iljk,la->jkia', gOOOO, t1b) tmpa = numpy.einsum('icjc->ij', miajb) * .25 tmpa += numpy.einsum('icjc->ij', miAjB) * .25 tmpb = numpy.einsum('icjc->ij', mIAJB) * .25 tmpb += numpy.einsum('icjc->ij', mIaJb) * .25 gooov -= einsum('ij,ka->jkia', tmpa, t1a) goOoV -= einsum('ij,ka->jkia', tmpa, t1b) gOoOv -= einsum('ij,ka->jkia', tmpb, t1a) gOOOV -= einsum('ij,ka->jkia', tmpb, t1b) gooov += einsum('icja,kc->jkia', miajb, .5 * t1a) goOoV += einsum('icja,kc->jkia', miAjB, .5 * t1b) goOoV -= einsum('icJA,kc->kJiA', miaJB, .5 * t1a) gOoOv += einsum('icja,kc->jkia', mIaJb, .5 * t1a) gOoOv -= einsum('ICja,KC->KjIa', mIAjb, .5 * t1b) gOOOV += einsum('icja,kc->jkia', mIAJB, .5 * t1b) gooov = gooov.conj() goOoV = goOoV.conj() gOoOv = gOoOv.conj() gOOOV = gOOOV.conj() gooov += einsum('jkab,ib->jkia', l2aa, .25*t1a) goOoV -= einsum('jkba,ib->jkia', l2ab, .5 *t1a) gOoOv -= einsum('kjab,ib->jkia', l2ab, .5 *t1b) gOOOV += einsum('jkab,ib->jkia', l2bb, .25*t1b) govvv = einsum('ja,ijcb->iacb', .25 * l1a, tauaa) goVvV = einsum('ja,ijcb->iacb', .5 * l1b, tauab) gOvVv = einsum('ja,jibc->iacb', .5 * l1a, tauab) gOVVV = einsum('ja,ijcb->iacb', .25 * l1b, taubb) govvv += einsum('bcad,id->iabc', gvvvv, t1a) goVvV -= einsum('bcda,id->iabc', gvVvV, t1a) * 2 gOvVv -= einsum('cbad,id->iabc', gvVvV, t1b) * 2 gOVVV += einsum('bcad,id->iabc', gVVVV, t1b) tmpa = numpy.einsum('kakb->ab', miajb) * .25 tmpa += numpy.einsum('kakb->ab', mIaJb) * .25 tmpb = numpy.einsum('kakb->ab', mIAJB) * .25 tmpb += numpy.einsum('kakb->ab', miAjB) * .25 govvv += einsum('ab,ic->iacb', tmpa, t1a) goVvV += einsum('ab,ic->iacb', tmpb, t1a) gOvVv += einsum('ab,ic->iacb', tmpa, t1b) gOVVV += einsum('ab,ic->iacb', tmpb, t1b) govvv += einsum('kaib,kc->iabc', miajb, .5 * t1a) goVvV += einsum('KAib,KC->iAbC', mIAjb, .5 * t1b) goVvV -= einsum('kAiB,kc->iAcB', miAjB, .5 * t1a) gOvVv += einsum('kaIB,kc->IaBc', miaJB, .5 * t1a) gOvVv -= einsum('KaIb,KC->IaCb', mIaJb, .5 * t1b) gOVVV += einsum('kaib,kc->iabc', mIAJB, .5 * t1b) govvv = govvv.conj() goVvV = goVvV.conj() gOvVv = gOvVv.conj() gOVVV = gOVVV.conj() govvv += einsum('ijbc,ja->iabc', l2aa, .25*t1a) goVvV += einsum('iJbC,JA->iAbC', l2ab, .5 *t1b) gOvVv += einsum('jIcB,ja->IaBc', l2ab, .5 *t1a) gOVVV += einsum('ijbc,ja->iabc', l2bb, .25*t1b) govvo = einsum('ia,jb->ibaj', l1a, t1a) goVvO = einsum('ia,jb->ibaj', l1a, t1b) gOvVo = einsum('ia,jb->ibaj', l1b, t1a) gOVVO = einsum('ia,jb->ibaj', l1b, t1b) govvo += numpy.einsum('iajb->ibaj', miajb) goVvO += numpy.einsum('iajb->ibaj', miaJB) gOvVo += numpy.einsum('iajb->ibaj', mIAjb) gOVVO += numpy.einsum('iajb->ibaj', mIAJB) goVoV = numpy.einsum('iajb->ibja', miAjB) gOvOv = numpy.einsum('iajb->ibja', mIaJb) govvo -= einsum('ikac,jc,kb->ibaj', l2aa, t1a, t1a) goVvO -= einsum('iKaC,JC,KB->iBaJ', l2ab, t1b, t1b) gOvVo -= einsum('kIcA,jc,kb->IbAj', l2ab, t1a, t1a) gOVVO -= einsum('ikac,jc,kb->ibaj', l2bb, t1b, t1b) goVoV += einsum('iKcA,jc,KB->iBjA', l2ab, t1a, t1b) gOvOv += einsum('kIaC,JC,kb->IbJa', l2ab, t1b, t1a) dovov = goovv.transpose(0,2,1,3) - goovv.transpose(0,3,1,2) dvvvv = gvvvv.transpose(0,2,1,3) - gvvvv.transpose(0,3,1,2) doooo = goooo.transpose(0,2,1,3) - goooo.transpose(0,3,1,2) dovvv = govvv.transpose(0,2,1,3) - govvv.transpose(0,3,1,2) dooov = gooov.transpose(0,2,1,3) - gooov.transpose(1,2,0,3) dovvo = govvo.transpose(0,2,1,3) dovov =(dovov + dovov.transpose(2,3,0,1)) * .5 dvvvv = dvvvv + dvvvv.transpose(1,0,3,2).conj() doooo = doooo + doooo.transpose(1,0,3,2).conj() dovvo =(dovvo + dovvo.transpose(3,2,1,0).conj()) * .5 doovv =-dovvo.transpose(0,3,2,1) dvvov = None dOVOV = gOOVV.transpose(0,2,1,3) - gOOVV.transpose(0,3,1,2) dVVVV = gVVVV.transpose(0,2,1,3) - gVVVV.transpose(0,3,1,2) dOOOO = gOOOO.transpose(0,2,1,3) - gOOOO.transpose(0,3,1,2) dOVVV = gOVVV.transpose(0,2,1,3) - gOVVV.transpose(0,3,1,2) dOOOV = gOOOV.transpose(0,2,1,3) - gOOOV.transpose(1,2,0,3) dOVVO = gOVVO.transpose(0,2,1,3) dOVOV =(dOVOV + dOVOV.transpose(2,3,0,1)) * .5 dVVVV = dVVVV + dVVVV.transpose(1,0,3,2).conj() dOOOO = dOOOO + dOOOO.transpose(1,0,3,2).conj() dOVVO =(dOVVO + dOVVO.transpose(3,2,1,0).conj()) * .5 dOOVV =-dOVVO.transpose(0,3,2,1) dVVOV = None dovOV = goOvV.transpose(0,2,1,3) dvvVV = gvVvV.transpose(0,2,1,3) * 2 dooOO = goOoO.transpose(0,2,1,3) * 2 dovVV = goVvV.transpose(0,2,1,3) dooOV = goOoV.transpose(0,2,1,3) dovVO = goVvO.transpose(0,2,1,3) dOVvv = gOvVv.transpose(0,2,1,3) dOOov = gOoOv.transpose(0,2,1,3) dOVvo = gOvVo.transpose(0,2,1,3) dooVV = goVoV.transpose(0,2,1,3) dOOvv = gOvOv.transpose(0,2,1,3) dvvVV = dvvVV + dvvVV.transpose(1,0,3,2).conj() dooOO = dooOO + dooOO.transpose(1,0,3,2).conj() dovVO = (dovVO + dOVvo.transpose(3,2,1,0).conj()) * .5 dooVV =-(dooVV + dooVV.transpose(1,0,3,2).conj()) * .5 dvvOV = None dOVov = None dVVvv = None dOOoo = None dOVvo = dovVO.transpose(3,2,1,0).conj() dOOvv =-(dOOvv + dOOvv.transpose(1,0,3,2).conj()) * .5 dVVov = None if compress_vvvv: nocca, noccb, nvira, nvirb = t2ab.shape idxa = numpy.tril_indices(nvira) idxa = idxa[0] * nvira + idxa[1] idxb = numpy.tril_indices(nvirb) idxb = idxb[0] * nvirb + idxb[1] dvvvv = dvvvv + dvvvv.transpose(1,0,2,3) dvvvv = lib.take_2d(dvvvv.reshape(nvira**2,nvira**2), idxa, idxa) dvvvv *= .5 dvvVV = dvvVV + dvvVV.transpose(1,0,2,3) dvvVV = lib.take_2d(dvvVV.reshape(nvira**2,nvirb**2), idxa, idxb) dvvVV *= .5 dVVVV = dVVVV + dVVVV.transpose(1,0,2,3) dVVVV = lib.take_2d(dVVVV.reshape(nvirb**2,nvirb**2), idxb, idxb) dVVVV *= .5 return ((dovov, dovOV, dOVov, dOVOV), (dvvvv, dvvVV, dVVvv, dVVVV), (doooo, dooOO, dOOoo, dOOOO), (doovv, dooVV, dOOvv, dOOVV), (dovvo, dovVO, dOVvo, dOVVO), (dvvov, dvvOV, dVVov, dVVOV), (dovvv, dovVV, dOVvv, dOVVV), (dooov, dooOV, dOOov, dOOOV))
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None): cput0 = (time.clock(), time.time()) eris = _ChemistsERIs() eris._common_init_(mycc, mo_coeff) nocca, noccb = mycc.nocc nmoa, nmob = mycc.nmo nvira, nvirb = nmoa-nocca, nmob-noccb moa = eris.mo_coeff[0] mob = eris.mo_coeff[1] nmoa = moa.shape[1] nmob = mob.shape[1] if callable(ao2mofn): eri_aa = ao2mofn(moa).reshape([nmoa]*4) eri_bb = ao2mofn(mob).reshape([nmob]*4) eri_ab = ao2mofn((moa,moa,mob,mob)) else: eri_aa = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, moa), nmoa) eri_bb = ao2mo.restore(1, ao2mo.full(mycc._scf._eri, mob), nmob) eri_ab = ao2mo.general(mycc._scf._eri, (moa,moa,mob,mob), compact=False) eri_ba = eri_ab.reshape(nmoa,nmoa,nmob,nmob).transpose(2,3,0,1) eri_aa = eri_aa.reshape(nmoa,nmoa,nmoa,nmoa) eri_ab = eri_ab.reshape(nmoa,nmoa,nmob,nmob) eri_ba = eri_ba.reshape(nmob,nmob,nmoa,nmoa) eri_bb = eri_bb.reshape(nmob,nmob,nmob,nmob) eris.oooo = eri_aa[:nocca,:nocca,:nocca,:nocca].copy() eris.ovoo = eri_aa[:nocca,nocca:,:nocca,:nocca].copy() eris.ovov = eri_aa[:nocca,nocca:,:nocca,nocca:].copy() eris.oovv = eri_aa[:nocca,:nocca,nocca:,nocca:].copy() eris.ovvo = eri_aa[:nocca,nocca:,nocca:,:nocca].copy() eris.ovvv = eri_aa[:nocca,nocca:,nocca:,nocca:].copy() eris.vvvv = eri_aa[nocca:,nocca:,nocca:,nocca:].copy() eris.OOOO = eri_bb[:noccb,:noccb,:noccb,:noccb].copy() eris.OVOO = eri_bb[:noccb,noccb:,:noccb,:noccb].copy() eris.OVOV = eri_bb[:noccb,noccb:,:noccb,noccb:].copy() eris.OOVV = eri_bb[:noccb,:noccb,noccb:,noccb:].copy() eris.OVVO = eri_bb[:noccb,noccb:,noccb:,:noccb].copy() eris.OVVV = eri_bb[:noccb,noccb:,noccb:,noccb:].copy() eris.VVVV = eri_bb[noccb:,noccb:,noccb:,noccb:].copy() eris.ooOO = eri_ab[:nocca,:nocca,:noccb,:noccb].copy() eris.ovOO = eri_ab[:nocca,nocca:,:noccb,:noccb].copy() eris.ovOV = eri_ab[:nocca,nocca:,:noccb,noccb:].copy() eris.ooVV = eri_ab[:nocca,:nocca,noccb:,noccb:].copy() eris.ovVO = eri_ab[:nocca,nocca:,noccb:,:noccb].copy() eris.ovVV = eri_ab[:nocca,nocca:,noccb:,noccb:].copy() eris.vvVV = eri_ab[nocca:,nocca:,noccb:,noccb:].copy() #eris.OOoo = eri_ba[:noccb,:noccb,:nocca,:nocca].copy() eris.OVoo = eri_ba[:noccb,noccb:,:nocca,:nocca].copy() #eris.OVov = eri_ba[:noccb,noccb:,:nocca,nocca:].copy() eris.OOvv = eri_ba[:noccb,:noccb,nocca:,nocca:].copy() eris.OVvo = eri_ba[:noccb,noccb:,nocca:,:nocca].copy() eris.OVvv = eri_ba[:noccb,noccb:,nocca:,nocca:].copy() #eris.VVvv = eri_ba[noccb:,noccb:,nocca:,nocca:].copy() if not callable(ao2mofn): ovvv = eris.ovvv.reshape(nocca*nvira,nvira,nvira) eris.ovvv = lib.pack_tril(ovvv).reshape(nocca,nvira,nvira*(nvira+1)//2) eris.vvvv = ao2mo.restore(4, eris.vvvv, nvira) OVVV = eris.OVVV.reshape(noccb*nvirb,nvirb,nvirb) eris.OVVV = lib.pack_tril(OVVV).reshape(noccb,nvirb,nvirb*(nvirb+1)//2) eris.VVVV = ao2mo.restore(4, eris.VVVV, nvirb) ovVV = eris.ovVV.reshape(nocca*nvira,nvirb,nvirb) eris.ovVV = lib.pack_tril(ovVV).reshape(nocca,nvira,nvirb*(nvirb+1)//2) vvVV = eris.vvVV.reshape(nvira**2,nvirb**2) idxa = np.tril_indices(nvira) idxb = np.tril_indices(nvirb) eris.vvVV = lib.take_2d(vvVV, idxa[0]*nvira+idxa[1], idxb[0]*nvirb+idxb[1]) OVvv = eris.OVvv.reshape(noccb*nvirb,nvira,nvira) eris.OVvv = lib.pack_tril(OVvv).reshape(noccb,nvirb,nvira*(nvira+1)//2) return eris
def _make_eris_outcore(mycc, mo_coeff=None): cput0 = (time.clock(), time.time()) log = logger.Logger(mycc.stdout, mycc.verbose) eris = _ChemistsERIs() eris._common_init_(mycc, mo_coeff) mol = mycc.mol mo_coeff = eris.mo_coeff nocc = eris.nocc nao, nmo = mo_coeff.shape nvir = nmo - nocc orbo = mo_coeff[:, :nocc] orbv = mo_coeff[:, nocc:] nvpair = nvir * (nvir + 1) // 2 eris.feri1 = lib.H5TmpFile() eris.oooo = eris.feri1.create_dataset('oooo', (nocc, nocc, nocc, nocc), 'f8') eris.ovoo = eris.feri1.create_dataset('ovoo', (nocc, nvir, nocc, nocc), 'f8', chunks=(nocc, 1, nocc, nocc)) eris.ovov = eris.feri1.create_dataset('ovov', (nocc, nvir, nocc, nvir), 'f8', chunks=(nocc, 1, nocc, nvir)) eris.ovvo = eris.feri1.create_dataset('ovvo', (nocc, nvir, nvir, nocc), 'f8', chunks=(nocc, 1, nvir, nocc)) eris.ovvv = eris.feri1.create_dataset('ovvv', (nocc, nvir, nvir, nvir), 'f8', chunks=(nocc, 1, nvir, nvir)) eris.oovv = eris.feri1.create_dataset('oovv', (nocc, nocc, nvir, nvir), 'f8', chunks=(nocc, nocc, 1, nvir)) eris.vvvv = eris.feri1.create_dataset('vvvv', (nvir, nvir, nvir, nvir), 'f8') max_memory = max(MEMORYMIN, mycc.max_memory - lib.current_memory()[0]) ftmp = lib.H5TmpFile() ao2mo.full(mol, mo_coeff, ftmp, max_memory=max_memory, verbose=log) eri = ftmp['eri_mo'] nocc_pair = nocc * (nocc + 1) // 2 tril2sq = lib.square_mat_in_trilu_indices(nmo) oo = eri[:nocc_pair] eris.oooo[:] = ao2mo.restore(1, oo[:, :nocc_pair], nocc) oovv = lib.take_2d(oo, tril2sq[:nocc, :nocc].ravel(), tril2sq[nocc:, nocc:].ravel()) eris.oovv[:] = oovv.reshape(nocc, nocc, nvir, nvir) oo = oovv = None tril2sq = lib.square_mat_in_trilu_indices(nmo) blksize = min(nvir, max(BLKMIN, int(max_memory * 1e6 / 8 / nmo**3 / 2))) for p0, p1 in lib.prange(0, nvir, blksize): q0, q1 = p0 + nocc, p1 + nocc off0 = q0 * (q0 + 1) // 2 off1 = q1 * (q1 + 1) // 2 buf = lib.unpack_tril(eri[off0:off1]) tmp = buf[tril2sq[q0:q1, :nocc] - off0] eris.ovoo[:, p0:p1] = tmp[:, :, :nocc, :nocc].transpose(1, 0, 2, 3) eris.ovvo[:, p0:p1] = tmp[:, :, nocc:, :nocc].transpose(1, 0, 2, 3) eris.ovov[:, p0:p1] = tmp[:, :, :nocc, nocc:].transpose(1, 0, 2, 3) eris.ovvv[:, p0:p1] = tmp[:, :, nocc:, nocc:].transpose(1, 0, 2, 3) tmp = buf[tril2sq[q0:q1, nocc:q1] - off0] eris.vvvv[p0:p1, :p1] = tmp[:, :, nocc:, nocc:] if p0 > 0: eris.vvvv[:p0, p0:p1] = tmp[:, :p0, nocc:, nocc:].transpose(1, 0, 2, 3) buf = tmp = None log.timer('CCSD integral transformation', *cput0) return eris
def _gamma2_intermediates(mycc, t1, t2, l1, l2, eris=None, compress_vvvv=False): d2 = uccsd_rdm._gamma2_intermediates(mycc, t1, t2, l1, l2) if eris is None: eris = mycc.ao2mo() dovov, dovOV, dOVov, dOVOV = d2[0] dvvvv, dvvVV, dVVvv, dVVVV = d2[1] doooo, dooOO, dOOoo, dOOOO = d2[2] doovv, dooVV, dOOvv, dOOVV = d2[3] dovvo, dovVO, dOVvo, dOVVO = d2[4] dvvov, dvvOV, dVVov, dVVOV = d2[5] dovvv, dovVV, dOVvv, dOVVV = d2[6] dooov, dooOV, dOOov, dOOOV = d2[7] t1a, t1b = t1 t2aa, t2ab, t2bb = t2 nocca, noccb, nvira, nvirb = t2ab.shape nmoa = eris.focka.shape[0] nmob = eris.fockb.shape[0] mo_ea, mo_eb = eris.mo_energy eia = mo_ea[:nocca,None] - mo_ea[nocca:] eIA = mo_eb[:noccb,None] - mo_eb[noccb:] fvo = eris.focka[nocca:,:nocca] fVO = eris.fockb[noccb:,:noccb] # aaa d3 = lib.direct_sum('ia+jb+kc->ijkabc', eia, eia, eia) w = numpy.einsum('ijae,kceb->ijkabc', t2aa, numpy.asarray(eris.get_ovvv()).conj()) w-= numpy.einsum('mkbc,iajm->ijkabc', t2aa, numpy.asarray(eris.ovoo.conj())) v = numpy.einsum('jbkc,ia->ijkabc', numpy.asarray(eris.ovov).conj(), t1a) v+= numpy.einsum('jkbc,ai->ijkabc', t2aa, fvo) * .5 rw = r6(p6(w)) / d3 wvd = r6(p6(w * 2 + v)) / d3 dovov += numpy.einsum('ia,ijkabc->jbkc', t1a, rw.conj()) * 0.25 # *(1/8) instead of (1/4) because ooov appears 4 times in the 2pdm tensor due # to symmetrization, and its contribution is scaled by 1/2 in Tr(H,2pdm) dooov -= numpy.einsum('mkbc,ijkabc->jmia', t2aa, wvd.conj()) * .125 dovvv += numpy.einsum('kjcf,ijkabc->iafb', t2aa, wvd.conj()) * .125 # bbb d3 = lib.direct_sum('ia+jb+kc->ijkabc', eIA, eIA, eIA) w = numpy.einsum('ijae,kceb->ijkabc', t2bb, numpy.asarray(eris.get_OVVV()).conj()) w-= numpy.einsum('imab,kcjm->ijkabc', t2bb, numpy.asarray(eris.OVOO.conj())) v = numpy.einsum('jbkc,ia->ijkabc', numpy.asarray(eris.OVOV).conj(), t1b) v+= numpy.einsum('jkbc,ai->ijkabc', t2bb, fVO) * .5 rw = r6(p6(w)) / d3 wvd = r6(p6(w * 2 + v)) / d3 dOVOV += numpy.einsum('ia,ijkabc->jbkc', t1b, rw.conj()) * .25 dOOOV -= numpy.einsum('mkbc,ijkabc->jmia', t2bb, wvd.conj()) * .125 dOVVV += numpy.einsum('kjcf,ijkabc->iafb', t2bb, wvd.conj()) * .125 # baa d3 = lib.direct_sum('ia+jb+kc->ijkabc', eIA, eia, eia) w = numpy.einsum('jIeA,kceb->IjkAbc', t2ab, numpy.asarray(eris.get_ovvv()).conj()) * 2 w += numpy.einsum('jIbE,kcEA->IjkAbc', t2ab, numpy.asarray(eris.get_ovVV()).conj()) * 2 w += numpy.einsum('jkbe,IAec->IjkAbc', t2aa, numpy.asarray(eris.get_OVvv()).conj()) w -= numpy.einsum('mIbA,kcjm->IjkAbc', t2ab, numpy.asarray(eris.ovoo).conj()) * 2 w -= numpy.einsum('jMbA,kcIM->IjkAbc', t2ab, numpy.asarray(eris.ovOO).conj()) * 2 w -= numpy.einsum('jmbc,IAkm->IjkAbc', t2aa, numpy.asarray(eris.OVoo).conj()) v = numpy.einsum('jbkc,IA->IjkAbc', numpy.asarray(eris.ovov).conj(), t1b) v += numpy.einsum('kcIA,jb->IjkAbc', numpy.asarray(eris.ovOV).conj(), t1a) v += numpy.einsum('kcIA,jb->IjkAbc', numpy.asarray(eris.ovOV).conj(), t1a) v += numpy.einsum('jkbc,AI->IjkAbc', t2aa, fVO) * .5 v += numpy.einsum('kIcA,bj->IjkAbc', t2ab, fvo) * 2 rw = r4(w) / d3 wvd = r4(w * 2 + v) / d3 dovvv += numpy.einsum('jiea,ijkabc->kceb', t2ab, wvd.conj()) * .25 dovVV += numpy.einsum('jibe,ijkabc->kcea', t2ab, wvd.conj()) * .25 dOVvv += numpy.einsum('jkbe,ijkabc->iaec', t2aa, wvd.conj()) * .125 dooov -= numpy.einsum('miba,ijkabc->jmkc', t2ab, wvd.conj()) * .25 dOOov -= numpy.einsum('jmba,ijkabc->imkc', t2ab, wvd.conj()) * .25 dooOV -= numpy.einsum('jmbc,ijkabc->kmia', t2aa, wvd.conj()) * .125 dovov += numpy.einsum('ia,ijkabc->jbkc', t1b, rw.conj()) * .25 #dOVov += numpy.einsum('jb,ijkabc->iakc', t1a, rw.conj()) * .25 dovOV += numpy.einsum('jb,ijkabc->kcia', t1a, rw.conj()) * .25 # bba d3 = lib.direct_sum('ia+jb+kc->ijkabc', eia, eIA, eIA) w = numpy.einsum('ijae,kceb->ijkabc', t2ab, numpy.asarray(eris.get_OVVV()).conj()) * 2 w += numpy.einsum('ijeb,kcea->ijkabc', t2ab, numpy.asarray(eris.get_OVvv()).conj()) * 2 w += numpy.einsum('jkbe,iaec->ijkabc', t2bb, numpy.asarray(eris.get_ovVV()).conj()) w -= numpy.einsum('imab,kcjm->ijkabc', t2ab, numpy.asarray(eris.OVOO).conj()) * 2 w -= numpy.einsum('mjab,kcim->ijkabc', t2ab, numpy.asarray(eris.OVoo).conj()) * 2 w -= numpy.einsum('jmbc,iakm->ijkabc', t2bb, numpy.asarray(eris.ovOO).conj()) v = numpy.einsum('jbkc,ia->ijkabc', numpy.asarray(eris.OVOV).conj(), t1a) v += numpy.einsum('iakc,jb->ijkabc', numpy.asarray(eris.ovOV).conj(), t1b) v += numpy.einsum('iakc,jb->ijkabc', numpy.asarray(eris.ovOV).conj(), t1b) v += numpy.einsum('JKBC,ai->iJKaBC', t2bb, fvo) * .5 v += numpy.einsum('iKaC,BJ->iJKaBC', t2ab, fVO) * 2 rw = r4(w) / d3 wvd = r4(w * 2 + v) / d3 dOVVV += numpy.einsum('ijae,ijkabc->kceb', t2ab, wvd.conj()) * .25 dOVvv += numpy.einsum('ijeb,ijkabc->kcea', t2ab, wvd.conj()) * .25 dovVV += numpy.einsum('jkbe,ijkabc->iaec', t2bb, wvd.conj()) * .125 dOOOV -= numpy.einsum('imab,ijkabc->jmkc', t2ab, wvd.conj()) * .25 dooOV -= numpy.einsum('mjab,ijkabc->imkc', t2ab, wvd.conj()) * .25 dOOov -= numpy.einsum('jmbc,ijkabc->kmia', t2bb, wvd.conj()) * .125 dOVOV += numpy.einsum('ia,ijkabc->jbkc', t1a, rw.conj()) * .25 dovOV += numpy.einsum('jb,ijkabc->iakc', t1b, rw.conj()) * .25 #dOVov += numpy.einsum('jb,ijkabc->kcia', t1b, rw.conj()) * .25 if compress_vvvv: nmoa, nmob = mycc.nmo nocca, noccb, nvira, nvirb = t2ab.shape idxa = numpy.tril_indices(nvira) idxa = idxa[0] * nvira + idxa[1] idxb = numpy.tril_indices(nvirb) idxb = idxb[0] * nvirb + idxb[1] dvvvv = dvvvv + dvvvv.transpose(1,0,2,3) dvvvv = lib.take_2d(dvvvv.reshape(nvira**2,nvira**2), idxa, idxa) dvvvv *= .5 dvvVV = dvvVV + dvvVV.transpose(1,0,2,3) dvvVV = lib.take_2d(dvvVV.reshape(nvira**2,nvirb**2), idxa, idxb) dVVVV = dVVVV + dVVVV.transpose(1,0,2,3) dVVVV = lib.take_2d(dVVVV.reshape(nvirb**2,nvirb**2), idxb, idxb) dVVVV *= .5 d2 = ((dovov, dovOV, dOVov, dOVOV), (dvvvv, dvvVV, dVVvv, dVVVV), (doooo, dooOO, dOOoo, dOOOO), (doovv, dooVV, dOOvv, dOOVV), (dovvo, dovVO, dOVvo, dOVVO), (dvvov, dvvOV, dVVov, dVVOV), (dovvv, dovVV, dOVvv, dOVVV), (dooov, dooOV, dOOov, dOOOV)) return d2
def contract_2e(eri, civec_strs, norb, nelec, link_index=None): ci_coeff, nelec, ci_strs = _unpack(civec_strs, nelec) if link_index is None: link_index = _all_linkstr_index(ci_strs, norb, nelec) cd_indexa, dd_indexa, cd_indexb, dd_indexb = link_index na, nlinka = cd_indexa.shape[:2] nb, nlinkb = cd_indexb.shape[:2] eri = ao2mo.restore(1, eri, norb) eri1 = eri.transpose(0, 2, 1, 3) - eri.transpose(0, 2, 3, 1) idx, idy = numpy.tril_indices(norb, -1) idx = idx * norb + idy eri1 = lib.take_2d(eri1.reshape(norb**2, -1), idx, idx) * 2 fcivec = ci_coeff.reshape(na, nb) # (bb|bb) if nelec[1] > 1: mb, mlinkb = dd_indexb.shape[:2] fcivecT = lib.transpose(fcivec) ci1T = numpy.zeros((nb, na)) libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivecT.ctypes.data_as(ctypes.c_void_p), ci1T.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(nb), ctypes.c_int(na), ctypes.c_int(mb), ctypes.c_int(mlinkb), dd_indexb.ctypes.data_as(ctypes.c_void_p)) ci1 = lib.transpose(ci1T, out=fcivecT) else: ci1 = numpy.zeros_like(fcivec) # (aa|aa) if nelec[0] > 1: ma, mlinka = dd_indexa.shape[:2] libfci.SCIcontract_2e_aaaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(ma), ctypes.c_int(mlinka), dd_indexa.ctypes.data_as(ctypes.c_void_p)) # Adding h_ps below to because contract_2e function computes the # contraction "E_{pq}E_{rs} V_{pqrs} |CI>" (~ p^+ q r^+ s |CI>) while # the actual contraction for (aa|aa) and (bb|bb) part is # "p^+ r^+ s q V_{pqrs} |CI>". To make (aa|aa) and (bb|bb) code reproduce # "p^+ q r^+ s |CI>", we employ the identity # p^+ q r^+ s = p^+ r^+ s q + delta(qr) p^+ s # the second term is the source of h_ps h_ps = numpy.einsum('pqqs->ps', eri) eri1 = eri * 2 for k in range(norb): eri1[:, :, k, k] += h_ps / nelec[0] eri1[k, k, :, :] += h_ps / nelec[1] eri1 = ao2mo.restore(4, eri1, norb) # (bb|aa) libfci.SCIcontract_2e_bbaa(eri1.ctypes.data_as(ctypes.c_void_p), fcivec.ctypes.data_as(ctypes.c_void_p), ci1.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(norb), ctypes.c_int(na), ctypes.c_int(nb), ctypes.c_int(nlinka), ctypes.c_int(nlinkb), cd_indexa.ctypes.data_as(ctypes.c_void_p), cd_indexb.ctypes.data_as(ctypes.c_void_p)) return _as_SCIvector(ci1.reshape(ci_coeff.shape), ci_strs)