def kernel_ft_smpl(h1e, g2e, norb, nelec, T, m=50,\ nsmpl=20000, Tmin=1e-3, symm='SOC', **kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if T < Tmin: return fcisolver.kernel(h1e, g2e, norb, nelec)[0] h2e = fcisolver.absorb_h1e(h1e, g2e, norb, nelec, .5) if symm is 'SOC': na = cistring.num_strings(norb, nelec) ci0 = numpy.random.randn(na) else: na = cistring.num_strings(norb, nelec // 2) ci0 = numpy.random.randn(na * na) ci0 = ci0 / numpy.linalg.norm(ci0) hdiag = fcisolver.make_hdiag(h1e, g2e, norb, nelec) hdiag = hdiag - hdiag[0] def hop(c): hc = fcisolver.contract_2e(h2e, c, norb, nelec) return hc.reshape(-1) E = ftsmpl.ft_smpl_E(hop, ci0, T, nsamp=nsmpl) return E
def ftsolver(h1e,g2e,norb,nelec,T,mu=0,symm='UHF', Tmin=1.e-3,\ dcompl=False,**kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver h1e = h1e[0] g2e = g2e[1] elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver dcompl = True elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if isinstance(nelec, (int, np.integer)): nelecb = nelec // 2 neleca = nelec - nelecb else: neleca, nelecb = nelec na = cistring.num_strings(norb, neleca) nb = cistring.num_strings(norb, nelecb) nelec = (neleca, nelecb) ne = neleca + nelecb ndim = na * nb if T < Tmin: e, v = fcisolver.kernel(h1e, g2e, norb, nelec) RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec) z = np.exp(-(e - mu * ne) / T) return np.asarray(RDM1) * ndim, np.asarray(RDM2) * ndim, e * ndim ew, ev = diagH(h1e, g2e, norb, nelec, fcisolver) rdm1, rdm2 = [], [] RDM1 = np.zeros((2, norb, norb)) RDM2 = np.zeros((3, norb, norb, norb, norb)) Z = np.sum(np.exp(-(ew - mu * ne) / T)) E = np.sum(np.exp(-(ew - mu * ne) / T) * ew) # not normalized #print Z, E for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, nelec) RDM1 += np.asarray(dm1) * np.exp(-(ew[i] - mu * ne) / T) RDM2 += np.asarray(dm2) * np.exp(-(ew[i] - mu * ne) / T) if symm is not 'UHF' and len(RDM1.shape) == 3: RDM1 = np.sum(RDM1, axis=0) RDM2 = np.sum(RDM2, axis=0) RDM1 /= Z RDM2 /= Z E /= Z return RDM1, RDM2, E
def energy(h1e,g2e,norb,nelec,beta,mu=0.0,bmax=1e3, \ dcompl=False,**kwargs): if beta > bmax: e, v = fcisolver.kernel(h1e, g2e, norb, nelec) return e # check for overflow e0, _ = fcisolver.kernel(h1e, g2e, norb, norb) exp_max = (-e0 + mu * norb) * beta if (exp_max > 700): exp_shift = exp_max - 500 else: exp_shift = 0 # Calculating E, Z # na =/= nb Z = 0. E = 0. for na in range(0, norb + 1): for nb in range(na + 1, norb + 1): ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) * 2 E += np.sum(np.exp(exp_) * ew) * 2 for na in range(0, norb + 1): nb = na ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) E += np.sum(np.exp(exp_) * ew) E /= Z return E
def rdm12s_ft_smpl(h1e, g2e, norb, nelec, T, \ m=50, nsmpl=20000, Tmin=1e-3, symm='RHF', **kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if T < Tmin: e, c = fcisolver.kernel(h1e, g2e, norb, nelec) dm1, dm2 = fcisolver.make_rdm12s(c, norb, nelec) dm1 = numpy.asarray(dm1) dm2 = numpy.asarray(dm2) else: h2e = fcisolver.absorb_h1e(h1e, g2e, norb, nelec, .5) if symm is 'SOC': na = cistring.num_strings(norb, nelec) ci0 = numpy.random.randn(na) else: na = cistring.num_strings(norb, nelec // 2) ci0 = numpy.random.randn(na * na) hdiag = fcisolver.make_hdiag(h1e, g2e, norb, nelec) hdiag = hdiag - hdiag[0] disp = numpy.exp(T) * 0.5 ci0 = ci0 / numpy.linalg.norm(ci0) def hop(c): hc = fcisolver.contract_2e(h2e, c, norb, nelec) return hc.reshape(-1) def qud(v1): dm1, dm2 = fcisolver.make_rdm12s(v1, norb, nelec) return dm1, dm2 dm1, dm2, e = ftsmpl.ft_smpl_rdm12s(qud, hop, ci0, T, norb, nsamp=nsmpl, M=m) if symm is 'UHF': return dm1, dm2, e elif len(dm1.shape) == 3: return numpy.sum(dm1, axis=0), numpy.sum(dm2, axis=0), e else: return dm1, dm2, e
def test_kernel_small_system(self): e1, c1 = selected_ci.kernel(h1[:2, :2], eri[:6], 2, (1, 1), nroots=2) e2, c2 = direct_spin1.kernel(h1[:2, :2], eri[:6], 2, (1, 1), nroots=2) self.assertAlmostEqual(abs(numpy.array(e1) - e2).max(), 0, 9) self.assertRaises(RuntimeError, selected_ci.kernel, h1[:2, :2], eri[:6], 2, (1, 1), nroots=6)
def test_kernel(self): myci = select_ci.SCI() e1, c1 = select_ci.kernel(h1, eri, norb, nelec) e2, c2 = direct_spin1.kernel(h1, eri, norb, nelec) self.assertAlmostEqual(e1, e2, 9) self.assertAlmostEqual(abs(numpy.dot(c1.ravel(), c2.ravel())), 1, 9) dm1_1 = myci.make_rdm1(c1, norb, nelec) dm1_2 = direct_spin1.make_rdm1(c2, norb, nelec) self.assertAlmostEqual(abs(dm1_1 - dm1_2).sum(), 0, 4) dm2_1 = myci.make_rdm2(c1, norb, nelec) dm2_2 = direct_spin1.make_rdm12(c2, norb, nelec)[1] self.assertAlmostEqual(abs(dm2_1 - dm2_2).sum(), 0, 2)
def test_kernel(self): myci = select_ci.SelectCI() e1, c1 = select_ci.kernel(h1, eri, norb, nelec) e2, c2 = direct_spin1.kernel(h1, eri, norb, nelec) self.assertAlmostEqual(e1, e2, 9) self.assertAlmostEqual(abs(numpy.dot(c1.ravel(), c2.ravel())), 1, 9) dm1_1 = myci.make_rdm1(c1, norb, nelec) dm1_2 = direct_spin1.make_rdm1(c2, norb, nelec) self.assertAlmostEqual(abs(dm1_1 - dm1_2).sum(), 0, 4) dm2_1 = myci.make_rdm2(c1, norb, nelec) dm2_2 = direct_spin1.make_rdm12(c2, norb, nelec)[1] self.assertAlmostEqual(abs(dm2_1 - dm2_2).sum(), 0, 2)
def elec_number(mu,h1e,g2e,norb,beta,bmax=1e3, \ dcompl=False,**kwargs): ''' return: electron number in form of Na ( = Nb) gradient wrt mu dNa/dmu ( = dNb/dmu) ''' Z = 0. Na = 0 Ncorr_a = 0 # check for overflow e0, _ = fcisolver.kernel(h1e, g2e, norb, norb) exp_max = (-e0 + mu * norb) * beta if (exp_max > 700): exp_shift = exp_max - 500 else: exp_shift = 0 for na in range(0, norb + 1): for nb in range(na + 1, norb + 1): ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) * 2 Na += ne * np.sum(np.exp(exp_)) Ncorr_a += (ne * ne) * np.sum(np.exp(exp_)) for na in range(0, norb + 1): nb = na ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) Na += na * np.sum(np.exp(exp_)) Ncorr_a += (na * ne) * np.sum(np.exp(exp_)) Na /= Z Ncorr_a /= Z N = Na * 2 grad_a = beta * (Ncorr_a - Na * N) return Na, grad_a
def rdm1s_ft_smpl(h1e, g2e, norb, nelec, T, \ m=50, nsmpl=20000, Tmin=1e-3, symm='RHF', **kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if T < Tmin: e, c = fcisolver.kernel(h1e, g2e, norb, nelec) rdm1 = fcisolver.make_rdm1s(c, norb, nelec) return numpy.asarray(rdm1), e h2e = fcisolver.absorb_h1e(h1e, g2e, norb, nelec, .5) if symm is 'SOC': na = cistring.num_strings(norb, nelec) ci0 = numpy.random.randn(na) else: na = cistring.num_strings(norb, nelec // 2) ci0 = numpy.random.randn(na * na) ci0 = ci0 / numpy.linalg.norm(ci0) def hop(c): hc = fcisolver.contract_2e(h2e, c, norb, nelec) return hc.reshape(-1) def qud(v1): dm1 = fcisolver.make_rdm1s(v1, norb, nelec) return dm1 dm1, e = ftsmpl.ft_smpl_rdm1s(qud,\ hop, ci0, T, norb, nsamp=nsmpl,M=m) return dm1, e
jk = jk.ravel() jk_sorted = abs(jk).argsort()[::-1] ci1 = [as_SCIvector(numpy.ones(1), hf_str)] myci = SelectedCI() myci.select_cutoff = .001 myci.ci_coeff_cutoff = .001 ci2 = enlarge_space(myci, ci1, h1, eri, jk, eri_sorted, jk_sorted, norb, nelec) print(len(ci2[0])) ci2 = enlarge_space(myci, ci1, h1, eri, jk, eri_sorted, jk_sorted, norb, nelec) numpy.random.seed(1) ci3 = numpy.random.random(ci2[0].size) ci3 *= 1./numpy.linalg.norm(ci3) ci3 = [ci3] ci3 = enlarge_space(myci, ci2, h1, eri, jk, eri_sorted, jk_sorted, norb, nelec) efci = direct_spin1.kernel(h1, eri, norb, nelec, verbose=5)[0] ci4 = contract_2e_ctypes((h1, eri), ci3[0], norb, nelec) fci3 = to_fci(ci3, norb, nelec) h2e = direct_spin1.absorb_h1e(h1, eri, norb, nelec, .5) fci4 = direct_spin1.contract_2e(h2e, fci3, norb, nelec) fci4 = from_fci(fci4, ci3[0]._strs, norb, nelec) print(abs(ci4-fci4).sum()) e = myci.kernel(h1, eri, norb, nelec, verbose=5)[0] print(e, efci)
def rdm12s_fted(h1e,g2e,norb,nelec,beta,mu=0.0,bmax=1e3, \ dcompl=False,**kwargs): ''' Return the expectation values of energy, RDM1 and RDM2 at temperature T. ''' # make sure the Hamiltonians have the correct shape # if (type(h1e) is tuple) or (type(h1e) is list): # h1e = h1e[0] # g2e = g2e[0] Z = 0. E = 0. RDM1 = np.zeros((norb, norb)) RDM2_0 = np.zeros((norb, norb, norb, norb)) RDM2_1 = np.zeros((norb, norb, norb, norb)) if beta > bmax: e, v = fcisolver.kernel(h1e, g2e, norb, nelec) RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec) return np.asarray(RDM1), np.asarray(RDM2), e # check for overflow e0, _ = fcisolver.kernel(h1e, g2e, norb, norb) exp_max = (-e0 + mu * norb) * beta if (exp_max > 700): exp_shift = exp_max - 500 else: exp_shift = 0 # Calculating E, RDM1, Z N = 0 # na =/= nb for na in range(0, norb + 1): for nb in range(na + 1, norb + 1): ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) * 2 E += np.sum(np.exp(exp_) * ew) * 2 N += ne * np.sum(np.exp(exp_)) * 2 for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, (na, nb)) RDM1 += (dm1[0] + dm1[1]) * np.exp(exp_[i]) RDM2_0 += (dm2[0] + dm2[2]) * np.exp(exp_[i]) RDM2_1 += (dm2[1] + np.transpose(dm2[1], (2, 3, 0, 1))) * np.exp( exp_[i]) for na in range(0, norb + 1): nb = na ne = na + nb ew, ev = diagH(h1e, g2e, norb, (na, nb), fcisolver) exp_ = (-ew + mu * (na + nb)) * beta exp_ -= exp_shift ndim = len(ew) Z += np.sum(np.exp(exp_)) E += np.sum(np.exp(exp_) * ew) N += ne * np.sum(np.exp(exp_)) for i in range(ndim): dm1, dm2 = fcisolver.make_rdm12s(ev[:, i].copy(), norb, (na, nb)) RDM1 += dm1[0] * np.exp(exp_[i]) RDM2_0 += dm2[0] * np.exp(exp_[i]) RDM2_1 += dm2[1] * np.exp(exp_[i]) E /= Z N /= Z RDM1 /= Z RDM2_0 /= Z RDM2_1 /= Z log.result("The expectation of electron number:") log.result("N(total) = %10.10f" % N) RDM1 = np.asarray([RDM1, RDM1]) RDM2 = np.asarray([RDM2_0, RDM2_1, RDM2_0]) log.result("FTED energy: %10.12f" % E) # RDM2 order: aaaa, aabb, bbbb return RDM1, RDM2, E
["H", (0.0, -1.0, -1.0)], ["H", (1.0, -0.5, -1.0)], ["H", (0.0, -0.0, -1.0)], ["H", (1.0, -0.5, 0.0)], ["H", (0.0, 1.0, 1.0)], ["H", (1.0, 2.0, 3.0)], ["H", (1.0, 2.0, 4.0)], ] mol.basis = "sto-3g" mol.build() m = scf.RHF(mol) m.kernel() norb = m.mo_coeff.shape[1] nelec = mol.nelectron h1e = reduce(numpy.dot, (m.mo_coeff.T, m.get_hcore(), m.mo_coeff)) eri = ao2mo.kernel(m._eri, m.mo_coeff, compact=False) eri = eri.reshape(norb, norb, norb, norb) e1, c1 = kernel(h1e, eri, norb, nelec) e2, c2 = direct_spin1.kernel(h1e, eri, norb, nelec) print(e1, e1 - -11.894559902235565, "diff to FCI", e1 - e2) print(c1[0].shape, c2.shape) dm1_1 = make_rdm1(c1, norb, nelec) dm1_2 = direct_spin1.make_rdm1(c2, norb, nelec) print(abs(dm1_1 - dm1_2).sum()) dm2_1 = make_rdm2(c1, norb, nelec) dm2_2 = direct_spin1.make_rdm12(c2, norb, nelec)[1] print(abs(dm2_1 - dm2_2).sum())
def test_kernel_small_system(self): e1, c1 = selected_ci.kernel(h1[:2,:2], eri[:6], 2, (1,1), nroots=2) e2, c2 = direct_spin1.kernel(h1[:2,:2], eri[:6], 2, (1,1), nroots=2) self.assertAlmostEqual(abs(numpy.array(e1) - e2).max(), 0, 9) self.assertRaises(RuntimeError, selected_ci.kernel, h1[:2,:2], eri[:6], 2, (1,1), nroots=6)
if __name__ == '__main__': from pyscf.fci import direct_uhf as fcisolver norb = 12 nelec = (norb / 2, norb / 2) u = 4.0 T = 0.05 mu = 2 h1e = numpy.zeros((norb, norb)) for i in range(norb): h1e[i, (i + 1) % norb] = -1.0 h1e[i, (i - 1) % norb] = -1.0 #h1e[0,-1] = 0. #h1e[-1,0] = 0. g2e_ = numpy.zeros((norb, ) * 4) for i in range(norb): g2e_[i, i, i, i] = u h1e = (h1e, h1e) g2e = (numpy.zeros((norb, ) * 4), g2e_, numpy.zeros((norb, ) * 4)) rdm1, rdm2, e = rdm12s_ftfci(h1e,g2e,norb,nelec,T,mu,m=200,Tmin=1e-3,\ dcompl=False,symm='UHF') e0, v = fcisolver.kernel(h1e, g2e, norb, nelec, nroots=1) rdm10, rdm20 = fcisolver.make_rdm12s(v, norb, nelec) print e / norb - e0 / norb print numpy.linalg.norm(rdm1 - rdm10) print numpy.linalg.norm(rdm2 - rdm20) print rdm1[0][:4, :4] print rdm10[0][:4, :4]
['H', (0., -1., -1.)], ['H', (1., -0.5, -1.)], ['H', (0., -0., -1.)], ['H', (1., -0.5, 0.)], ['H', (0., 1., 1.)], ['H', (1., 2., 3.)], ['H', (1., 2., 4.)], ] mol.basis = 'sto-3g' mol.build() m = scf.RHF(mol) m.kernel() norb = m.mo_coeff.shape[1] nelec = mol.nelectron h1e = reduce(numpy.dot, (m.mo_coeff.T, m.get_hcore(), m.mo_coeff)) eri = ao2mo.kernel(m._eri, m.mo_coeff, compact=False) eri = eri.reshape(norb, norb, norb, norb) e1, c1 = kernel(h1e, eri, norb, nelec) e2, c2 = direct_spin1.kernel(h1e, eri, norb, nelec) print(e1, e1 - -11.894559902235565, 'diff to FCI', e1 - e2) print(c1[0].shape, c2.shape) dm1_1 = make_rdm1(c1, norb, nelec) dm1_2 = direct_spin1.make_rdm1(c2, norb, nelec) print(abs(dm1_1 - dm1_2).sum()) dm2_1 = make_rdm2(c1, norb, nelec) dm2_2 = direct_spin1.make_rdm12(c2, norb, nelec)[1] print(abs(dm2_1 - dm2_2).sum())
def rdm12s_ftfci(h1e,g2e,norb,nelec,T,mu,m=50,Tmin=1e-3,\ dcompl=False,symm='RHF',**kwargs): if symm is 'RHF': from pyscf.fci import direct_spin1 as fcisolver elif symm is 'SOC': from pyscf.fci import fci_slow_spinless as fcisolver dcompl = True elif symm is 'UHF': from pyscf.fci import direct_uhf as fcisolver else: from pyscf.fci import direct_spin1 as fcisolver if symm != 'UHF' and isinstance(h1e, tuple): h1e = h1e[0] g2e = g2e[1] if T < Tmin: # only for half-filling e, v = fcisolver.kernel(h1e, g2e, norb, nelec) RDM1, RDM2 = fcisolver.make_rdm12s(v, norb, nelec) return numpy.asarray(RDM1), numpy.asarray(RDM2), e # loop over na and nb Z = 0. E = 0. RDM1 = numpy.zeros((2, norb, norb), dtype=numpy.complex128) RDM2 = numpy.zeros((3, norb, norb, norb, norb), dtype=numpy.complex128) #for ns in range(1): # rdm1,rdm2,e,z = lanczos_grand.ft_solver(h1e,g2e,fcisolver,norb,nelec,T,mu=0,m=m) # RDM1 += rdm1 # RDM2 += rdm2 # E += e # Z += z # calculate the number of states nstate = 0. dN = 0 for na in range(norb / 2 - dN, norb / 2 + dN + 1): for nb in range(norb / 2 - dN, norb / 2 + dN + 1): nstate += cistring.num_strings(norb, na) * cistring.num_strings( norb, nb) for na in range(norb / 2 - dN, norb / 2 + dN + 1): for nb in range(na, norb / 2 + dN + 1): ne = (na, nb) ntot = na + nb nci = cistring.num_strings(norb, na) * cistring.num_strings( norb, nb) factor = numpy.exp(0 * (ntot - norb) / T) if nci < 1e2: rdm1, rdm2, e, z = ed_canonical.ftsolver(h1e, g2e, fcisolver, norb, ne, T, mu, symm='UHF') Z += z / nstate * factor E += e / nstate * factor RDM1 += rdm1 / nstate * factor RDM2 += rdm2 / nstate * factor else: rdm1, rdm2, e, z = lanczos_grand.ft_solver( h1e, g2e, fcisolver, norb, ne, T, mu) Z += z * (nci / nstate) * factor E += e * (nci / nstate) * factor RDM1 += rdm1 * (nci / nstate) * factor RDM2 += rdm2 * (nci / nstate) * factor #if nb > na: # Z += 2*(nci/nstate)*z*factor # E += 2*(nci/nstate)*e*factor # RDM1 += (nci/nstate)*rdm1*factor # RDM1 += (nci/nstate)*permute_rdm1(rdm1)*factor # RDM2 += 2*(nci/nstate)*rdm2*factor #else: # Z += (nci/nstate)*z*factor # E += (nci/nstate)*e*factor # RDM1 += (nci/nstate)*rdm1*factor # #RDM1 += (nci/nstate)*permute_rdm1(rdm1)*factor/2. # RDM2 += (nci/nstate)*rdm2*factor # E /= Z RDM1 /= Z RDM2 /= Z if not dcompl: E = E.real RDM1 = RDM1.real RDM2 = RDM2.real return RDM1, RDM2, E