def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=[]): assert(fcivec.flags.c_contiguous) if not list(orbsym): return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index) eri = pyscf.ao2mo.restore(4, eri, norb) if link_index is None: if isinstance(nelec, (int, numpy.integer)): neleca = nelec//2 else: neleca, nelecb = nelec assert(neleca == nelecb) link_index = cistring.gen_linkstr_index_trilidx(range(norb), neleca) na,nlink,_ = link_index.shape ci1 = numpy.empty((na,na)) eri, link_index, dimirrep = \ direct_spin1_symm.reorder4irrep(eri, norb, link_index, orbsym) dimirrep = numpy.array(dimirrep, dtype=numpy.int32) libfci.FCIcontract_2e_spin0_symm(eri.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(nlink), link_index.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) return pyscf.lib.transpose_sum(ci1, inplace=True)
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) 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) Tirrep = ctypes.c_void_p * TOTIRREPS 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 * TOTIRREPS)(*[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 * TOTIRREPS)(*[x.size for x in aidx]) ci0 = [] ci1 = [] for ir in range(TOTIRREPS): 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(wfnsym)) for ir in range(TOTIRREPS): 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 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 contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=None): fcivec = numpy.asarray(fcivec, order='C') if orbsym is None: return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index) eri = pyscf.ao2mo.restore(4, eri, norb) link_index = direct_spin0._unpack(norb, nelec, link_index) na, nlink = link_index.shape[:2] assert (fcivec.size == na**2) ci1 = numpy.empty((na, na)) eri, link_index, dimirrep = \ direct_spin1_symm.reorder4irrep(eri, norb, link_index, orbsym) dimirrep = numpy.array(dimirrep, dtype=numpy.int32) libfci.FCIcontract_2e_spin0_symm( eri.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(nlink), link_index.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) return pyscf.lib.transpose_sum(ci1, inplace=True).reshape(fcivec.shape)
def contract_2e(eri, fcivec, norb, nelec, link_index=None, orbsym=[]): fcivec = numpy.asarray(fcivec, order='C') if not list(orbsym): return direct_spin0.contract_2e(eri, fcivec, norb, nelec, link_index) eri = pyscf.ao2mo.restore(4, eri, norb) link_index = direct_spin0._unpack(norb, nelec, link_index) na, nlink = link_index.shape[:2] assert(fcivec.size == na**2) ci1 = numpy.empty((na,na)) eri, link_index, dimirrep = \ direct_spin1_symm.reorder4irrep(eri, norb, link_index, orbsym) dimirrep = numpy.array(dimirrep, dtype=numpy.int32) libfci.FCIcontract_2e_spin0_symm(eri.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(nlink), link_index.ctypes.data_as(ctypes.c_void_p), dimirrep.ctypes.data_as(ctypes.c_void_p), ctypes.c_int(len(dimirrep))) return pyscf.lib.transpose_sum(ci1, inplace=True).reshape(fcivec.shape)
norb = m.mo_coeff.shape[1] nelec = mol.nelectron h1e = reduce(numpy.dot, (m.mo_coeff.T, scf.hf.get_hcore(mol), m.mo_coeff)) eri = ao2mo.incore.full(m._eri, m.mo_coeff) numpy.random.seed(1) na = cistring.num_strings(norb, nelec//2) fcivec = numpy.random.random((na,na)) fcivec = fcivec + fcivec.T orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, m.mo_coeff) print(numpy.allclose(orbsym, [0, 0, 2, 0, 3, 0, 2])) cis = FCISolver(mol) cis.orbsym = cis.orbsym ci1 = cis.contract_2e(eri, fcivec, norb, nelec) ci1ref = direct_spin0.contract_2e(eri, fcivec, norb, nelec) print(numpy.allclose(ci1ref, ci1)) mol.atom = [['H', (0, 0, i)] for i in range(8)] mol.basis = {'H': 'sto-3g'} mol.symmetry = True mol.build() m = scf.RHF(mol) ehf = m.scf() norb = m.mo_coeff.shape[1] nelec = mol.nelectron eri = ao2mo.incore.full(m._eri, m.mo_coeff) na = cistring.num_strings(norb, nelec//2) fcivec = numpy.random.random((na,na)) fcivec = fcivec + fcivec.T
norb = m.mo_coeff.shape[1] nelec = mol.nelectron h1e = reduce(numpy.dot, (m.mo_coeff.T, scf.hf.get_hcore(mol), m.mo_coeff)) eri = ao2mo.incore.full(m._eri, m.mo_coeff) numpy.random.seed(1) na = cistring.num_strings(norb, nelec // 2) fcivec = numpy.random.random((na, na)) fcivec = fcivec + fcivec.T orbsym = symm.label_orb_symm(mol, mol.irrep_id, mol.symm_orb, m.mo_coeff) print(numpy.allclose(orbsym, [0, 0, 2, 0, 3, 0, 2])) cis = FCISolver(mol) cis.orbsym = orbsym fcivec = addons.symmetrize_wfn(fcivec, norb, nelec, cis.orbsym, wfnsym=0) ci1 = cis.contract_2e(eri, fcivec, norb, nelec) ci1ref = direct_spin0.contract_2e(eri, fcivec, norb, nelec) print(numpy.allclose(ci1ref, ci1)) e = cis.kernel(h1e, eri, norb, nelec, ecore=m.energy_nuc(), davidson_only=True)[0] print(e, e - -75.012647118991595) mol.atom = [['H', (0, 0, i)] for i in range(8)] mol.basis = {'H': 'sto-3g'} mol.symmetry = True mol.build() m = scf.RHF(mol) ehf = m.scf()