def test_h4_rdm(self): mol = gto.Mole() mol.verbose = 0 mol.atom = [ ['H', ( 1.,-1. , 0. )], ['H', ( 0.,-1. ,-1. )], ['H', ( 1.,-0.5 , 0. )], ['H', ( 0.,-1. , 1. )], ] mol.charge = 2 mol.spin = 2 mol.basis = '6-31g' mol.build() mf = scf.UHF(mol).set(init_guess='1e').run(conv_tol=1e-14) ehf0 = mf.e_tot - mol.energy_nuc() mycc = uccsd.UCCSD(mf).run() mycc.solve_lambda() eri_aa = ao2mo.kernel(mf._eri, mf.mo_coeff[0]) eri_bb = ao2mo.kernel(mf._eri, mf.mo_coeff[1]) eri_ab = ao2mo.kernel(mf._eri, [mf.mo_coeff[0], mf.mo_coeff[0], mf.mo_coeff[1], mf.mo_coeff[1]]) h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) efci, fcivec = direct_uhf.kernel((h1a,h1b), (eri_aa,eri_ab,eri_bb), h1a.shape[0], mol.nelec) dm1ref, dm2ref = direct_uhf.make_rdm12s(fcivec, h1a.shape[0], mol.nelec) t1, t2 = mycc.t1, mycc.t2 l1, l2 = mycc.l1, mycc.l2 rdm1 = mycc.make_rdm1(t1, t2, l1, l2) rdm2 = mycc.make_rdm2(t1, t2, l1, l2) self.assertAlmostEqual(abs(dm1ref[0] - rdm1[0]).max(), 0, 6) self.assertAlmostEqual(abs(dm1ref[1] - rdm1[1]).max(), 0, 6) self.assertAlmostEqual(abs(dm2ref[0] - rdm2[0]).max(), 0, 6) self.assertAlmostEqual(abs(dm2ref[1] - rdm2[1]).max(), 0, 6) self.assertAlmostEqual(abs(dm2ref[2] - rdm2[2]).max(), 0, 6)
def test_mp2_contract_eri_dm(self): nocc = mol.nelectron//2 nmo = mf.mo_energy.size nvir = nmo - nocc pt = mp.mp2.MP2(mf) emp2, t2 = pt.kernel() eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo) hcore = mf.get_hcore() rdm1 = pt.make_rdm1() rdm2 = pt.make_rdm2() h1 = reduce(numpy.dot, (mf.mo_coeff.T, hcore, mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, rdm1) e1+= numpy.einsum('ijkl,ijkl', eri, rdm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9) pt.frozen = 2 pt.max_memory = 1 emp2, t2 = pt.kernel(with_t2=False) eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo) hcore = mf.get_hcore() rdm1 = pt.make_rdm1() rdm2 = pt.make_rdm2() h1 = reduce(numpy.dot, (mf.mo_coeff.T, hcore, mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, rdm1) e1+= numpy.einsum('ijkl,ijkl', eri, rdm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9)
def __init__(self, myci, mo_coeff, method='incore'): mol = myci.mol mf = myci._scf nocc = myci.nocc nmo = myci.nmo nvir = nmo - nocc if mo_coeff is None: self.mo_coeff = mo_coeff = myci.mo_coeff if (method == 'incore' and mf._eri is not None): eri = ao2mo.kernel(mf._eri, mo_coeff, verbose=myci.verbose) else: eri = ao2mo.kernel(mol, mo_coeff, verbose=myci.verbose) eri = ao2mo.restore(1, eri, nmo) eri = eri.reshape(nmo,nmo,nmo,nmo) self.oooo = eri[:nocc,:nocc,:nocc,:nocc] self.vvoo = eri[nocc:,nocc:,:nocc,:nocc] self.vooo = eri[nocc:,:nocc,:nocc,:nocc] self.voov = eri[nocc:,:nocc,:nocc,nocc:] self.vovv = lib.pack_tril(eri[nocc:,:nocc,nocc:,nocc:].reshape(-1,nvir,nvir)) self.vvvv = ao2mo.restore(4, eri[nocc:,nocc:,nocc:,nocc:].copy(), nvir) dm = mf.make_rdm1() vhf = mf.get_veff(mol, dm) h1 = mf.get_hcore(mol) self.fock = reduce(numpy.dot, (mo_coeff.T, h1 + vhf, mo_coeff))
def _make_eris_incore(mp, mo_coeff=None, ao2mofn=None, verbose=None): eris = _PhysicistsERIs(mp, mo_coeff) nocc = mp.nocc nao, nmo = eris.mo_coeff.shape nvir = nmo - nocc orbspin = eris.orbspin if callable(ao2mofn): orbo = eris.mo_coeff[:,:nocc] orbv = eris.mo_coeff[:,nocc:] orbo = lib.tag_array(orbo, orbspin=orbspin) eri = ao2mofn((orbo,orbv,orbo,orbv)).reshape(nocc,nvir,nocc,nvir) else: orboa = eris.mo_coeff[:nao//2,:nocc] orbob = eris.mo_coeff[nao//2:,:nocc] orbva = eris.mo_coeff[:nao//2,nocc:] orbvb = eris.mo_coeff[nao//2:,nocc:] if orbspin is None: eri = ao2mo.kernel(mp._scf._eri, (orboa,orbva,orboa,orbva)) eri += ao2mo.kernel(mp._scf._eri, (orbob,orbvb,orbob,orbvb)) eri1 = ao2mo.kernel(mp._scf._eri, (orboa,orbva,orbob,orbvb)) eri += eri1 eri += eri1.T eri = eri.reshape(nocc,nvir,nocc,nvir) else: co = orboa + orbob cv = orbva + orbvb eri = ao2mo.kernel(mp._scf._eri, (co,cv,co,cv)).reshape(nocc,nvir,nocc,nvir) sym_forbid = (orbspin[:nocc,None] != orbspin[nocc:]) eri[sym_forbid,:,:] = 0 eri[:,:,sym_forbid] = 0 eris.oovv = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1) return eris
def test_ao2mo_with_mol_cart(self): pmol = mol.copy() pmol.cart = True nao = pmol.nao_nr() numpy.random.seed(1) mo = numpy.random.random((nao,4)) eri = ao2mo.kernel(pmol, mo) self.assertAlmostEqual(lib.finger(eri), -977.99841341828437, 9) eri = ao2mo.kernel(mol, mo, intor='int2e_cart') self.assertAlmostEqual(lib.finger(eri), -977.99841341828437, 9)
def test_r_outcore_eri(self): n2c = mol.nao_2c() numpy.random.seed(1) mo = numpy.random.random((n2c,n2c)) + numpy.random.random((n2c,n2c))*1j eriref = trans(eri0, [mo]*4) ftmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, mo, ftmp.name, intor='int2e_spinor', max_memory=10, ioblk_size=5) with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(lib.finger(eri1), -550.72966498073129-1149.3561026721848j, 8) self.assertAlmostEqual(abs(eri1-eriref.reshape(n2c**2,n2c**2)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), ftmp.name, intor='int2e_spinor') with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) ftmp = lib.H5TmpFile() ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), ftmp, intor='int2e_spinor', aosym='s1') with ao2mo.load(ftmp) as eri1: self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:4], mo[:,:2]), intor='int2e_spinor', aosym='s2ij') self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:4,:2].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, (mo[:,:2], mo[:,:4], mo[:,:2], mo[:,:4]), intor='int2e_spinor', aosym='s2kl') self.assertAlmostEqual(abs(eri1-eriref[:2,:4,:2,:4].reshape(8,8)).max(), 0, 9) eri1 = ao2mo.kernel(mol, mo[:,:0], intor='int2e_spinor') self.assertTrue(eri1.size == 0)
def test_rdm_h4(self): mol = gto.Mole() mol.verbose = 7 mol.output = '/dev/null' mol.atom = [ ['O', ( 0., 0. , 0. )], ['H', ( 0., -0.757, 0.587)], ['H', ( 0., 0.757 , 0.587)],] mol.spin = 2 mol.basis = 'sto-3g' mol.build() mf = scf.UHF(mol).run(conv_tol=1e-14) myci = ucisd.UCISD(mf) ecisd, civec = myci.kernel() self.assertAlmostEqual(ecisd, -0.033689623198003449, 8) nmoa = nmob = nmo = mf.mo_coeff[1].shape[1] nocc = (6,4) ci0 = myci.to_fcivec(civec, nmo, nocc) ref1, ref2 = fci.direct_uhf.make_rdm12s(ci0, nmo, nocc) rdm1 = myci.make_rdm1(civec) rdm2 = myci.make_rdm2(civec) self.assertAlmostEqual(abs(rdm1[0]-ref1[0]).max(), 0, 6) self.assertAlmostEqual(abs(rdm1[1]-ref1[1]).max(), 0, 6) self.assertAlmostEqual(abs(rdm2[0]-ref2[0]).max(), 0, 6) self.assertAlmostEqual(abs(rdm2[1]-ref2[1]).max(), 0, 6) self.assertAlmostEqual(abs(rdm2[2]-ref2[2]).max(), 0, 6) dm1a = numpy.einsum('ijkk->ji', rdm2[0]) / (mol.nelectron-1) dm1a+= numpy.einsum('ijkk->ji', rdm2[1]) / (mol.nelectron-1) self.assertAlmostEqual(abs(rdm1[0] - dm1a).max(), 0, 9) dm1b = numpy.einsum('kkij->ji', rdm2[2]) / (mol.nelectron-1) dm1b+= numpy.einsum('kkij->ji', rdm2[1]) / (mol.nelectron-1) self.assertAlmostEqual(abs(rdm1[1] - dm1b).max(), 0, 9) eri_aa = ao2mo.kernel(mf._eri, mf.mo_coeff[0], compact=False).reshape([nmoa]*4) eri_bb = ao2mo.kernel(mf._eri, mf.mo_coeff[1], compact=False).reshape([nmob]*4) eri_ab = ao2mo.kernel(mf._eri, [mf.mo_coeff[0], mf.mo_coeff[0], mf.mo_coeff[1], mf.mo_coeff[1]], compact=False) eri_ab = eri_ab.reshape(nmoa,nmoa,nmob,nmob) h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) e2 = (numpy.einsum('ij,ji', h1a, rdm1[0]) + numpy.einsum('ij,ji', h1b, rdm1[1]) + numpy.einsum('ijkl,ijkl', eri_aa, rdm2[0]) * .5 + numpy.einsum('ijkl,ijkl', eri_ab, rdm2[1]) + numpy.einsum('ijkl,ijkl', eri_bb, rdm2[2]) * .5) e2 += mol.energy_nuc() self.assertAlmostEqual(myci.e_tot, e2, 9)
def test_rdm(self): mol = gto.Mole() mol.verbose = 5 mol.output = '/dev/null' mol.atom = [ ['O', ( 0., 0. , 0. )], ['H', ( 0., -0.757, 0.587)], ['H', ( 0., 0.757 , 0.587)],] mol.basis = {'H': 'sto-3g', 'O': 'sto-3g',} mol.build() mf = scf.RHF(mol).run() myci = ci.CISD(mf) ecisd, civec = myci.kernel() self.assertAlmostEqual(ecisd, -0.048878084082066106, 12) nmo = mf.mo_coeff.shape[1] nocc = mol.nelectron//2 rdm1 = myci.make_rdm1(civec) rdm2 = myci.make_rdm2(civec) self.assertAlmostEqual(finger(rdm1), 2.2685199485281689, 9) self.assertAlmostEqual(finger(rdm2), 6.9406226727865876, 9) self.assertAlmostEqual(abs(rdm2-rdm2.transpose(2,3,0,1)).sum(), 0, 9) self.assertAlmostEqual(abs(rdm2-rdm2.transpose(1,0,3,2)).sum(), 0, 9) h1e = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) h2e = ao2mo.kernel(mf._eri, mf.mo_coeff) h2e = ao2mo.restore(1, h2e, nmo) e2 = (numpy.dot(h1e.flatten(),rdm1.flatten()) + numpy.dot(h2e.transpose(0,2,1,3).flatten(),rdm2.flatten()) * .5) self.assertAlmostEqual(ecisd + mf.e_tot - mol.energy_nuc(), e2, 9) dm1 = numpy.einsum('ikjk->ij', rdm2)/(mol.nelectron-1) self.assertAlmostEqual(abs(rdm1 - dm1).sum(), 0, 9)
def test_rdm_h4(self): mol = gto.Mole() mol.verbose = 7 mol.output = '/dev/null' mol.atom = [ ['O', ( 0., 0. , 0. )], ['H', ( 0., -0.757, 0.587)], ['H', ( 0., 0.757 , 0.587)],] mol.spin = 2 mol.basis = 'sto-3g' mol.build() mf = scf.RHF(mol).run(conv_tol=1e-14) myci = ci.GCISD(mf) eris = myci.ao2mo() ecisd, civec = myci.kernel(eris=eris) self.assertAlmostEqual(ecisd, -0.035165114624046617, 8) nmo = eris.mo_coeff.shape[1] rdm1 = myci.make_rdm1(civec, nmo, mol.nelectron) rdm2 = myci.make_rdm2(civec, nmo, mol.nelectron) mo = eris.mo_coeff[:7] + eris.mo_coeff[7:] eri = ao2mo.kernel(mf._eri, mo, compact=False).reshape([nmo]*4) eri[eris.orbspin[:,None]!=eris.orbspin,:,:] = 0 eri[:,:,eris.orbspin[:,None]!=eris.orbspin] = 0 h1e = reduce(numpy.dot, (mo.T, mf.get_hcore(), mo)) h1e[eris.orbspin[:,None]!=eris.orbspin] = 0 e2 = (numpy.einsum('ij,ji', h1e, rdm1) + numpy.einsum('ijkl,ijkl', eri, rdm2) * .5) e2 += mol.energy_nuc() self.assertAlmostEqual(myci.e_tot, e2, 9) dm1 = numpy.einsum('ijkk->ji', rdm2)/(mol.nelectron-1) self.assertAlmostEqual(abs(rdm1 - dm1).max(), 0, 9)
def test_rdm1(self): mol = gto.Mole() mol.verbose = 0 mol.atom = [ ['O', ( 0., 0. , 0. )], ['H', ( 0., -0.757, 0.587)], ['H', ( 0., 0.757 , 0.587)],] mol.basis = '631g' mol.build() mf = scf.RHF(mol).run(conv_tol=1e-14) myci = ci.CISD(mf) myci.frozen = 1 myci.kernel() nmo = myci.nmo nocc = myci.nocc d1 = cisd._gamma1_intermediates(myci, myci.ci, nmo, nocc) myci.max_memory = 0 d2 = cisd._gamma2_intermediates(myci, myci.ci, nmo, nocc, True) dm2 = cisd.ccsd_rdm._make_rdm2(myci, d1, d2, with_dm1=True, with_frozen=True) dm1 = numpy.einsum('ijkk->ij', dm2)/(mol.nelectron-1) h1 = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo+1) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, myci.e_tot, 7)
def test_general(self): nao = mol.nao mo = numpy.random.random((nao,4)) eri = mol.intor('int2e', aosym='s8') eri = ao2mo.kernel(eri, [mo]*4, compact=False) self.assertEqual(eri.shape, (16,16)) h5file = lib.H5TmpFile() ao2mo.kernel(mol, [mo]*4, h5file, intor='int2e', dataname='eri') self.assertEqual(h5file['eri'].shape, (10,10)) ftmp = tempfile.NamedTemporaryFile() ao2mo.kernel(mol, [mo]*4, ftmp, intor='int2e', dataname='eri') with ao2mo.load(ftmp.name, 'eri') as eri: self.assertEqual(eri.shape, (10,10))
def fci(mol, printroots=4, visualize=False, preservedict=True): """Where is my docstring?""" if not preservedict: __hamdict = dict() print("PYCI") print("method: FCI") print("Number of eigenvalues: ", printroots) print("") Na, Nb = mol.nelec E_nuc = mol.energy_nuc() nao = mol.nao_nr() myhf = scf.RHF(mol) E_hf = myhf.kernel() mo_coefficients = myhf.mo_coeff h1e = reduce(np.dot, (mo_coefficients.T, myhf.get_hcore(), mo_coefficients)) print("transforming eris") eri = ao2mo.kernel(mol, mo_coefficients) print("generating all determinants") fulldetlist_sets = gen_dets_sets(nao, Na, Nb) ndets = len(fulldetlist_sets) print("constructing full Hamiltonian") full_hamiltonian = construct_hamiltonian(ndets, fulldetlist_sets, h1e, eri) eig_vals, eig_vecs = sp.sparse.linalg.eigsh(full_hamiltonian, k=2 * printroots) eig_vals_sorted = np.sort(eig_vals)[:printroots] print("") print("first {:} pyci eigvals".format(printroots)) for i in eig_vals_sorted + E_nuc: print(i) # if visualize: # print(len(fulldetlist_sets),len(eig_vecs[:,np.argsort(eig_vals)[0]])) # newdet = [i for i in zip(list(fulldetlist_sets),eig_vecs[:,np.argsort(eig_vals)[0]])] # visualize_sets(newdet,nao,Na,Nb,"FCI") print("Completed FCI!") return eig_vals_sorted + E_nuc
def grad_elec(mc, mf_grad): mf = mf_grad.base mol = mf_grad.mol mo_energy = mc.mo_energy mo_coeff = mc.mo_coeff ncore = mc.ncore ncas = mc.ncas nocc = ncore + ncas nelecas = mc.nelecas nao, nmo = mo_coeff.shape hcore_deriv = mf_grad.hcore_generator(mol) s1 = mf_grad.get_ovlp(mol) casdm1, casdm2 = mc.fcisolver.make_rdm12(mc.ci, ncas, nelecas) dm1 = numpy.zeros((nmo,nmo)) dm1[numpy.diag_indices(ncore)] = 2 dm1[ncore:nocc,ncore:nocc] = casdm1 dm2 = numpy.zeros((nmo,nmo,nmo,nmo)) for i in range(ncore): for j in range(ncore): dm2[i,i,j,j] += 4 dm2[i,j,j,i] -= 2 dm2[i,i,ncore:nocc,ncore:nocc] = casdm1 * 2 dm2[ncore:nocc,ncore:nocc,i,i] = casdm1 * 2 dm2[i,ncore:nocc,ncore:nocc,i] =-casdm1 dm2[ncore:nocc,i,i,ncore:nocc] =-casdm1 dm2[ncore:nocc,ncore:nocc,ncore:nocc,ncore:nocc] = casdm2 h1 = reduce(numpy.dot, (mo_coeff.T, mc._scf.get_hcore(), mo_coeff)) h2 = ao2mo.kernel(mf._eri, mo_coeff, compact=False).reshape([nmo]*4) # Generalized Fock, according to generalized Brillouin theorm # Adv. Chem. Phys., 69, 63 gfock = numpy.dot(h1, dm1) gfock+= numpy.einsum('iqrs,qjsr->ij', h2, dm2) gfock = (gfock + gfock.T) * .5 dme0 = reduce(numpy.dot, (mo_coeff[:,:nocc], gfock[:nocc,:nocc], mo_coeff[:,:nocc].T)) dm1 = reduce(numpy.dot, (mo_coeff, dm1, mo_coeff.T)) dm2 = lib.einsum('ijkl,pi,qj,rk,sl->pqrs', dm2, mo_coeff, mo_coeff, mo_coeff, mo_coeff) eri_deriv1 = mol.intor('int2e_ip1', comp=3).reshape(3,nao,nao,nao,nao) atmlst = range(mol.natm) aoslices = mol.aoslice_by_atom() de = numpy.zeros((len(atmlst),3)) for k, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] h1ao = hcore_deriv(ia) de[k] += numpy.einsum('xij,ij->x', h1ao, dm1) de[k] -= numpy.einsum('xij,ij->x', s1[:,p0:p1], dme0[p0:p1]) * 2 de[k] -= numpy.einsum('xijkl,ijkl->x', eri_deriv1[:,p0:p1], dm2[p0:p1]) * 2 return de
def test_contract(self): mol = gto.M() mol.nelectron = 6 nocc, nvir = mol.nelectron//2, 4 nmo = nocc + nvir nmo_pair = nmo*(nmo+1)//2 mf = scf.RHF(mol) numpy.random.seed(12) mf._eri = numpy.random.random(nmo_pair*(nmo_pair+1)//2) mf.mo_coeff = numpy.random.random((nmo,nmo)) mf.mo_energy = numpy.arange(0., nmo) mf.mo_occ = numpy.zeros(nmo) mf.mo_occ[:nocc] = 2 dm = mf.make_rdm1() vhf = mf.get_veff(mol, dm) h1 = numpy.random.random((nmo,nmo)) * .1 h1 = h1 + h1.T mf.get_hcore = lambda *args: h1 myci = ci.CISD(mf) eris = myci.ao2mo(mf.mo_coeff) eris.ehf = (h1*dm).sum() + (vhf*dm).sum()*.5 c2 = numpy.random.random((nocc,nocc,nvir,nvir)) * .1 c2 = c2 + c2.transpose(1,0,3,2) c1 = numpy.random.random(nocc*nvir+1) * .1 c0, c1 = c1[0], c1[1:].reshape(nocc,nvir) civec = myci.amplitudes_to_cisdvec(c0, c1, c2) hcivec = ci.cisd.contract(myci, civec, eris) self.assertAlmostEqual(lib.finger(hcivec), 2059.5730673341673, 9) e2 = ci.cisd.dot(civec, hcivec+eris.ehf*civec, nmo, nocc) self.assertAlmostEqual(e2, 7226.7494656749295, 9) rdm2 = myci.make_rdm2(civec, nmo, nocc) self.assertAlmostEqual(lib.finger(rdm2), 2.0492023431953221, 9) def fcicontract(h1, h2, norb, nelec, ci0): g2e = fci.direct_spin1.absorb_h1e(h1, h2, norb, nelec, .5) ci1 = fci.direct_spin1.contract_2e(g2e, ci0, norb, nelec) return ci1 ci0 = myci.to_fcivec(civec, nmo, mol.nelec) self.assertAlmostEqual(abs(civec-myci.from_fcivec(ci0, nmo, nocc*2)).max(), 0, 9) h2e = ao2mo.kernel(mf._eri, mf.mo_coeff) h1e = reduce(numpy.dot, (mf.mo_coeff.T, h1, mf.mo_coeff)) ci1 = fcicontract(h1e, h2e, nmo, mol.nelec, ci0) ci2 = myci.to_fcivec(hcivec, nmo, mol.nelec) e1 = numpy.dot(ci1.ravel(), ci0.ravel()) e2 = ci.cisd.dot(civec, hcivec+eris.ehf*civec, nmo, nocc) self.assertAlmostEqual(e1, e2, 9) dovov, dvvvv, doooo, doovv, dovvo, dvvov, dovvv, dooov = \ ci.cisd._gamma2_intermediates(myci, civec, nmo, nocc) self.assertAlmostEqual(lib.finger(numpy.array(dovov)), 0.02868859991188923, 9) self.assertAlmostEqual(lib.finger(numpy.array(dvvvv)),-0.05524957311823144, 9) self.assertAlmostEqual(lib.finger(numpy.array(doooo)), 0.01014399192065793, 9) self.assertAlmostEqual(lib.finger(numpy.array(doovv)), 0.02761239887072825, 9) self.assertAlmostEqual(lib.finger(numpy.array(dovvo)), 0.09971200182238759, 9) self.assertAlmostEqual(lib.finger(numpy.array(dovvv)), 0.12777531252787638, 9) self.assertAlmostEqual(lib.finger(numpy.array(dooov)), 0.18667669732858014, 9)
def cisd(mol, printroots=4, visualize=False, preservedict=True): """Where is my docstring?""" if not preservedict: __hamdict = dict() print("PYCI") print("method: CISD") print("Number of eigenvalues: ", printroots) print("") Na, Nb = mol.nelec E_nuc = mol.energy_nuc() # get number of spatial atomic orbitals which we assume is the # same as the number of spatial molecular orbitals which is true # when using RHF, as long as there are no linear dependencies nao = mol.nao_nr() myhf = scf.RHF(mol) E_hf = myhf.kernel() mo_coefficients = myhf.mo_coeff # create matrix of 1 electron integrals h1e = reduce(np.dot, (mo_coefficients.T, myhf.get_hcore(), mo_coefficients)) print("transforming eris") # get 2 electron integrals eri = ao2mo.kernel(mol, mo_coefficients) # create dictionary of hamiltonian elements hamdict = dict() # create Hartree-Fock determinant bit representation hfdet = (frozenset(range(Na)), frozenset(range(Nb))) # initalize set of target determinants targetdetset = set() # initalize set of core determinants coreset = {hfdet} print("\nHartree-Fock Energy: ", E_hf) # for each determinant in the core set of determinants... for idet in coreset: # ...generate all single and double excitations and add them # to the target set targetdetset |= set(gen_singles_doubles(idet, nao)) # create a set from the union of the target and core determinants targetdetset |= coreset # update the dictionary of hamiltonian elements with those of the # target determinants hamdict.update(populatehamdict(targetdetset, targetdetset, hamdict, h1e, eri)) # construct the hamiltonian in the target space targetham = getsmallham(list(targetdetset), hamdict) # diagonalize the hamiltonian yielding the eigenvalues and # eigenvectors eig_vals, eig_vecs = sp.sparse.linalg.eigsh(targetham, k=2 * printroots) eig_vals_sorted = np.sort(eig_vals)[:printroots] # sort the eigenvalues print("") print("first {:} pyci eigvals".format(printroots)) for i in eig_vals_sorted + E_nuc: print(i) print(np.shape(eig_vecs)) # if visualize: # newdet = [i for i in zip(list(targetdetset),eig_vecs[:,np.argsort(eig_vals)[0]])] # visualize_sets(newdet,nao,Na,Nb,"CISD") print("Completed CISD!") return eig_vals_sorted + E_nuc
def create_PYSCF_fcidump(): myhf = scf.RHF(mol) E = myhf.kernel() c = myhf.mo_coeff h1e = reduce(np.dot, (c.T, myhf.get_hcore(), c)) eri = ao2mo.kernel(mol, c) pt.fcidump.from_integrals('fcidump.txt', h1e, eri, c.shape[1],mol.nelectron, ms=0) cisolver = fci.FCI(mol, myhf.mo_coeff) print('E(HF) = %.12f, E(FCI) = %.12f' % (E,(cisolver.kernel()[0] + mol.energy_nuc())))
def test_h4(self): mol = gto.Mole() mol.verbose = 7 mol.output = '/dev/null' mol.atom = [ ['H', ( 1.,-1. , 0. )], ['H', ( 0.,-1. ,-1. )], ['H', ( 1.,-0.5 , 0. )], ['H', ( 0.,-1. , 1. )], ] mol.charge = 2 mol.spin = 2 mol.basis = '3-21g' mol.build() mf = scf.RHF(mol).run(conv_tol=1e-14) myci = ci.CISD(mf) myci.kernel() self.assertAlmostEqual(myci.e_tot, -0.50569591904536926, 8) mf = scf.UHF(mol).run(conv_tol=1e-14) myci = ci.CISD(mf) ecisd = myci.kernel()[0] self.assertAlmostEqual(ecisd, -0.03598992307519909, 8) self.assertAlmostEqual(myci.e_tot, -0.50569591904536926, 8) eris = myci.ao2mo() ecisd = myci.kernel(eris=eris)[0] eri_aa = ao2mo.kernel(mf._eri, mf.mo_coeff[0]) eri_bb = ao2mo.kernel(mf._eri, mf.mo_coeff[1]) eri_ab = ao2mo.kernel(mf._eri, [mf.mo_coeff[0], mf.mo_coeff[0], mf.mo_coeff[1], mf.mo_coeff[1]]) h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) efci, fcivec = fci.direct_uhf.kernel((h1a,h1b), (eri_aa,eri_ab,eri_bb), h1a.shape[0], mol.nelec) self.assertAlmostEqual(mf.e_tot+ecisd, efci+mol.energy_nuc(), 9) dm1ref, dm2ref = fci.direct_uhf.make_rdm12s(fcivec, h1a.shape[0], mol.nelec) rdm1 = myci.make_rdm1(myci.ci, myci.get_nmo(), myci.get_nocc()) rdm2 = myci.make_rdm2(myci.ci, myci.get_nmo(), myci.get_nocc()) self.assertAlmostEqual(abs(dm1ref[0] - rdm1[0]).max(), 0, 5) self.assertAlmostEqual(abs(dm1ref[1] - rdm1[1]).max(), 0, 5) self.assertAlmostEqual(abs(dm2ref[0] - rdm2[0]).max(), 0, 5) self.assertAlmostEqual(abs(dm2ref[1] - rdm2[1]).max(), 0, 5) self.assertAlmostEqual(abs(dm2ref[2] - rdm2[2]).max(), 0, 5)
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None): cput0 = (time.clock(), time.time()) eris = _PhysicistsERIs() eris._common_init_(mycc, mo_coeff) nocc = eris.nocc nao, nmo = eris.mo_coeff.shape if callable(ao2mofn): eri = ao2mofn(eris.mo_coeff).reshape([nmo]*4) else: assert(eris.mo_coeff.dtype == np.double) mo_a = eris.mo_coeff[:nao//2] mo_b = eris.mo_coeff[nao//2:] orbspin = eris.orbspin if orbspin is None: eri = ao2mo.kernel(mycc._scf._eri, mo_a) eri += ao2mo.kernel(mycc._scf._eri, mo_b) eri1 = ao2mo.kernel(mycc._scf._eri, (mo_a,mo_a,mo_b,mo_b)) eri += eri1 eri += eri1.T else: mo = mo_a + mo_b eri = ao2mo.kernel(mycc._scf._eri, mo) if eri.size == nmo**4: # if mycc._scf._eri is a complex array sym_forbid = (orbspin[:,None] != orbspin).ravel() else: # 4-fold symmetry sym_forbid = (orbspin[:,None] != orbspin)[np.tril_indices(nmo)] eri[sym_forbid,:] = 0 eri[:,sym_forbid] = 0 if eri.dtype == np.double: eri = ao2mo.restore(1, eri, nmo) eri = eri.reshape(nmo,nmo,nmo,nmo) eri = eri.transpose(0,2,1,3) - eri.transpose(0,2,3,1) eris.oooo = eri[:nocc,:nocc,:nocc,:nocc].copy() eris.ooov = eri[:nocc,:nocc,:nocc,nocc:].copy() eris.oovv = eri[:nocc,:nocc,nocc:,nocc:].copy() eris.ovov = eri[:nocc,nocc:,:nocc,nocc:].copy() eris.ovvo = eri[:nocc,nocc:,nocc:,:nocc].copy() eris.ovvv = eri[:nocc,nocc:,nocc:,nocc:].copy() eris.vvvv = eri[nocc:,nocc:,nocc:,nocc:].copy() return eris
def test_ump2_dm(self): pt = mp.MP2(mf) emp2, t2 = pt.kernel() dm1 = pt.make_rdm1() dm2 = pt.make_rdm2() gpt = mp.GMP2(mf).run() dm1ref = gpt.make_rdm1() dm2ref = gpt.make_rdm2() ia = gpt._scf.mo_coeff.orbspin == 0 ib = gpt._scf.mo_coeff.orbspin == 1 mo_a, mo_b = mf.mo_coeff nmoa = mo_a.shape[1] nmob = mo_b.shape[1] nocca, noccb = mol.nelec self.assertTrue(numpy.allclose(dm1[0], dm1ref[ia][:,ia])) self.assertTrue(numpy.allclose(dm1[1], dm1ref[ib][:,ib])) self.assertTrue(numpy.allclose(dm2[0], dm2ref[ia][:,ia][:,:,ia][:,:,:,ia])) self.assertTrue(numpy.allclose(dm2[2], dm2ref[ib][:,ib][:,:,ib][:,:,:,ib])) self.assertTrue(numpy.allclose(dm2[1], dm2ref[ia][:,ia][:,:,ib][:,:,:,ib])) hcore = mf.get_hcore() eriaa = ao2mo.kernel(mf._eri, mo_a, compact=False).reshape([nmoa]*4) eribb = ao2mo.kernel(mf._eri, mo_b, compact=False).reshape([nmob]*4) eriab = ao2mo.kernel(mf._eri, (mo_a,mo_a,mo_b,mo_b), compact=False) eriab = eriab.reshape([nmoa,nmoa,nmob,nmob]) h1a = reduce(numpy.dot, (mo_a.T.conj(), hcore, mo_a)) h1b = reduce(numpy.dot, (mo_b.T.conj(), hcore, mo_b)) e1 = numpy.einsum('ij,ji', h1a, dm1[0]) e1+= numpy.einsum('ij,ji', h1b, dm1[1]) e1+= numpy.einsum('ijkl,ijkl', eriaa, dm2[0]) * .5 e1+= numpy.einsum('ijkl,ijkl', eriab, dm2[1]) e1+= numpy.einsum('ijkl,ijkl', eribb, dm2[2]) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9) vhf = mf.get_veff(mol, mf.make_rdm1()) h1a = reduce(numpy.dot, (mo_a.T, hcore+vhf[0], mo_a)) h1b = reduce(numpy.dot, (mo_b.T, hcore+vhf[1], mo_b)) dm1[0][numpy.diag_indices(nocca)] -= 1 dm1[1][numpy.diag_indices(noccb)] -= 1 e = numpy.einsum('pq,qp', h1a, dm1[0]) e+= numpy.einsum('pq,qp', h1b, dm1[1]) self.assertAlmostEqual(e, -emp2, 9)
def test_rdm_real(self): mol = gto.M() mol.verbose = 0 nocc = 6 nvir = 10 mf = scf.GHF(mol) nmo = nocc + nvir npair = nmo*(nmo//2+1)//4 numpy.random.seed(12) mf._eri = numpy.random.random(npair*(npair+1)//2)*.3 hcore = numpy.random.random((nmo,nmo)) * .5 hcore = hcore + hcore.T + numpy.diag(range(nmo))*2 mf.get_hcore = lambda *args: hcore mf.get_ovlp = lambda *args: numpy.eye(nmo) mf.mo_coeff = numpy.eye(nmo) mf.mo_occ = numpy.zeros(nmo) mf.mo_occ[:nocc] = 1 dm1 = mf.make_rdm1() mf.e_tot = mf.energy_elec()[0] myci = gcisd.GCISD(mf).run() dm1 = myci.make_rdm1() dm2 = myci.make_rdm2() nao = nmo // 2 mo_a = mf.mo_coeff[:nao] mo_b = mf.mo_coeff[nao:] eri = ao2mo.kernel(mf._eri, mo_a) eri += ao2mo.kernel(mf._eri, mo_b) eri1 = ao2mo.kernel(mf._eri, (mo_a,mo_a,mo_b,mo_b)) eri += eri1 eri += eri1.T eri = ao2mo.restore(1, eri, nmo) h1 = reduce(numpy.dot, (mf.mo_coeff.T.conj(), hcore, mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 self.assertAlmostEqual(e1, myci.e_tot, 7) self.assertAlmostEqual(abs(dm2-dm2.transpose(1,0,3,2).conj()).max(), 0, 9) self.assertAlmostEqual(abs(dm2-dm2.transpose(2,3,0,1) ).max(), 0, 9) self.assertAlmostEqual(abs(dm2+dm2.transpose(2,1,0,3) ).max(), 0, 9) self.assertAlmostEqual(abs(dm2+dm2.transpose(0,3,2,1) ).max(), 0, 9)
def test_ccsd(self): mycc = cc.CCSD(mf) ecc = mycc.kernel()[0] h2e = ao2mo.kernel(mf._eri, mf.mo_coeff) h1e = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) eci = fci.direct_spin0.kernel(h1e, h2e, mf.mo_coeff.shape[1], mol.nelectron)[0] eci = eci + mol.energy_nuc() - mf.e_tot self.assertAlmostEqual(eci, ecc, 7) l1, l2 = mycc.solve_lambda() self.assertAlmostEqual(finger(l1), 0.0106196828089, 8) self.assertAlmostEqual(finger(l2), 0.149822823742 , 7)
def test_df_ao2mo(self): mf = scf.density_fit(msym) mf.max_memory = 100 mf.kernel() mc = mcscf.DFCASSCF(mf, 4, 4) eri0 = numpy.dot(mf._cderi.T, mf._cderi) nmo = mc.mo_coeff.shape[1] ncore = mc.ncore nocc = ncore + mc.ncas eri0 = ao2mo.restore(1, ao2mo.kernel(eri0, mc.mo_coeff), nmo) eris = mc.ao2mo(mc.mo_coeff) self.assertTrue(numpy.allclose(eri0[:,:,ncore:nocc,ncore:nocc], eris.ppaa)) self.assertTrue(numpy.allclose(eri0[:,ncore:nocc,:,ncore:nocc], eris.papa))
def test_h2o_rdm(self): mol = mol_s2 mf = mf_s2 mycc = uccsd.UCCSD(mf) mycc.frozen = 2 ecc, t1, t2 = mycc.kernel() l1, l2 = mycc.solve_lambda() dm1a,dm1b = mycc.make_rdm1(t1, t2, l1, l2) dm2aa,dm2ab,dm2bb = mycc.make_rdm2(t1, t2, l1, l2) mo_a = mf.mo_coeff[0] mo_b = mf.mo_coeff[1] nmoa = mo_a.shape[1] nmob = mo_b.shape[1] eriaa = ao2mo.kernel(mf._eri, mo_a, compact=False).reshape([nmoa]*4) eribb = ao2mo.kernel(mf._eri, mo_b, compact=False).reshape([nmob]*4) eriab = ao2mo.kernel(mf._eri, (mo_a,mo_a,mo_b,mo_b), compact=False) eriab = eriab.reshape([nmoa,nmoa,nmob,nmob]) hcore = mf.get_hcore() h1a = reduce(numpy.dot, (mo_a.T.conj(), hcore, mo_a)) h1b = reduce(numpy.dot, (mo_b.T.conj(), hcore, mo_b)) e1 = numpy.einsum('ij,ji', h1a, dm1a) e1+= numpy.einsum('ij,ji', h1b, dm1b) e1+= numpy.einsum('ijkl,ijkl', eriaa, dm2aa) * .5 e1+= numpy.einsum('ijkl,ijkl', eriab, dm2ab) e1+= numpy.einsum('ijkl,ijkl', eribb, dm2bb) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, mycc.e_tot, 7) d1 = uccsd_rdm._gamma1_intermediates(mycc, mycc.t1, mycc.t2, mycc.l1, mycc.l2) mycc.max_memory = 0 d2 = uccsd_rdm._gamma2_intermediates(mycc, mycc.t1, mycc.t2, mycc.l1, mycc.l2, True) dm2 = uccsd_rdm._make_rdm2(mycc, d1, d2, with_dm1=True, with_frozen=True) e1 = numpy.einsum('ij,ji', h1a, dm1a) e1+= numpy.einsum('ij,ji', h1b, dm1b) e1+= numpy.einsum('ijkl,ijkl', eriaa, dm2[0]) * .5 e1+= numpy.einsum('ijkl,ijkl', eriab, dm2[1]) e1+= numpy.einsum('ijkl,ijkl', eribb, dm2[2]) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, mycc.e_tot, 7)
def test_ao2mo(self): dfobj = df.DF(mol) dfobj.build() cderi = dfobj._cderi nao = mol.nao_nr() eri0 = ao2mo.restore(8, numpy.dot(cderi.T, cderi), nao) numpy.random.seed(1) mos = numpy.random.random((nao,nao*10)) mos = (mos[:,:5], mos[:,5:11], mos[:,3:9], mos[:,2:4]) mo_eri0 = ao2mo.kernel(eri0, mos) mo_eri1 = dfobj.ao2mo(mos) self.assertTrue(numpy.allclose(mo_eri0, mo_eri1))
def test_ump2_contract_eri_dm(self): pt = mp.MP2(mf) pt.frozen = [[0,1,2,3],[1]] emp2, t2 = pt.kernel() mo_a, mo_b = mf.mo_coeff nmoa = mo_a.shape[1] nmob = mo_b.shape[1] dm1a,dm1b = pt.make_rdm1() dm2aa,dm2ab,dm2bb = pt.make_rdm2() eriaa = ao2mo.kernel(mf._eri, mo_a, compact=False).reshape([nmoa]*4) eribb = ao2mo.kernel(mf._eri, mo_b, compact=False).reshape([nmob]*4) eriab = ao2mo.kernel(mf._eri, (mo_a,mo_a,mo_b,mo_b), compact=False) eriab = eriab.reshape([nmoa,nmoa,nmob,nmob]) hcore = mf.get_hcore() h1a = reduce(numpy.dot, (mo_a.T.conj(), hcore, mo_a)) h1b = reduce(numpy.dot, (mo_b.T.conj(), hcore, mo_b)) e1 = numpy.einsum('ij,ji', h1a, dm1a) e1+= numpy.einsum('ij,ji', h1b, dm1b) e1+= numpy.einsum('ijkl,ijkl', eriaa, dm2aa) * .5 e1+= numpy.einsum('ijkl,ijkl', eriab, dm2ab) e1+= numpy.einsum('ijkl,ijkl', eribb, dm2bb) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9)
def test_ccsd(self): mycc = cc.CCSD(mf) ecc = mycc.kernel()[0] norb = mf.mo_coeff.shape[1] nelec = mol.nelec h2e = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), norb) h1e = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) eci, civec = fci.direct_spin0.kernel(h1e, h2e, norb, nelec) dm1ref = fci.direct_spin0.make_rdm1(civec, norb, nelec) eci = eci + mol.energy_nuc() - mf.e_tot self.assertAlmostEqual(eci, ecc, 7) l1, l2 = mycc.solve_lambda() self.assertAlmostEqual(finger(l1), 0.0106196828089, 5) dm1 = mycc.make_rdm1() self.assertAlmostEqual(abs(dm1ref-dm1).max(), 0, 5)
def test_h8(self): mol = gto.Mole() mol.verbose = 0 mol.output = None mol.atom = [ ['H', ( 1.,-1. , 0. )], ['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).run() 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) myci = selected_ci.SCI() myci.select_cutoff = 1e-3 myci.ci_coeff_cutoff = 1e-3 myci.dump_flags() e1, c1 = myci.kernel(h1e, eri, norb, nelec) self.assertAlmostEqual(e1, -11.894613845925514, 9) e, c = myci.kernel_fixed_space(h1e, eri, norb, nelec, c1._strs) self.assertAlmostEqual(e, -11.894613845925514, 9) res = myci.large_ci(c1, norb, nelec, .25) self.assertEqual([x[1] for x in res], ['0b1111', '0b1111', '0b10111', '0b10111']) self.assertEqual([x[2] for x in res], ['0b1111', '0b10111', '0b1111', '0b10111']) res = myci.large_ci(c1, norb, nelec, .25, return_strs=False) refa = numpy.array(((0,1,2,3), (0,1,2,3), (0,1,2,4), (0,1,2,4))) refb = numpy.array(((0,1,2,3), (0,1,2,4), (0,1,2,3), (0,1,2,4))) self.assertTrue(numpy.all([x[1] for x in res] == refa)) self.assertTrue(numpy.all([x[2] for x in res] == refb)) self.assertAlmostEqual(myci.spin_square(c1, norb, nelec)[0], 0, 2)
def test_rdm(self): mol = gto.Mole() mol.verbose = 5 mol.output = '/dev/null' mol.atom = [ ['O', ( 0., 0. , 0. )], ['H', ( 0., -0.757, 0.587)], ['H', ( 0., 0.757 , 0.587)],] mol.basis = {'H': 'sto-3g', 'O': 'sto-3g',} mol.build() mf = scf.RHF(mol).run(conv_tol=1e-14) myci = ci.CISD(mf) myci.frozen = 1 eris = myci.ao2mo() ecisd, civec = myci.kernel(eris=eris) self.assertAlmostEqual(ecisd, -0.048800218694077746, 8) nmo = myci.nmo nocc = myci.nocc strs = fci.cistring.gen_strings4orblist(range(nmo+1), nocc+1) mask = (strs & 1) != 0 sub_strs = strs[mask] addrs = fci.cistring.strs2addr(nmo+1, nocc+1, sub_strs) na = len(strs) ci0 = numpy.zeros((na,na)) ci0[addrs[:,None],addrs] = myci.to_fcivec(civec, nmo, nocc*2) ref1, ref2 = fci.direct_spin1.make_rdm12(ci0, (nmo+1), (nocc+1)*2) rdm1 = myci.make_rdm1(civec) rdm2 = myci.make_rdm2(civec) self.assertTrue(numpy.allclose(rdm2, ref2)) self.assertAlmostEqual(abs(rdm2-rdm2.transpose(2,3,0,1)).sum(), 0, 9) self.assertAlmostEqual(abs(rdm2-rdm2.transpose(1,0,3,2)).sum(), 0, 9) dm1 = numpy.einsum('ijkk->ij', rdm2)/(mol.nelectron-1) self.assertAlmostEqual(abs(rdm1 - dm1).sum(), 0, 9) h1 = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo+1) e1 = numpy.einsum('ij,ji', h1, rdm1) e1+= numpy.einsum('ijkl,ijkl', eri, rdm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, myci.e_tot, 7)
def test_gmp2_contract_eri_dm(self): pt = mp.GMP2(mf) pt.frozen = 2 emp2, t2 = pt.kernel() dm1 = pt.make_rdm1() dm2 = pt.make_rdm2() nao = mol.nao_nr() mo_a = pt._scf.mo_coeff[:nao] mo_b = pt._scf.mo_coeff[nao:] nmo = mo_a.shape[1] eri = ao2mo.kernel(mf._eri, mo_a+mo_b, compact=False).reshape([nmo]*4) orbspin = pt._scf.mo_coeff.orbspin sym_forbid = (orbspin[:,None] != orbspin) eri[sym_forbid,:,:] = 0 eri[:,:,sym_forbid] = 0 hcore = mf.get_hcore() h1 = reduce(numpy.dot, (mo_a.T.conj(), hcore, mo_a)) h1+= reduce(numpy.dot, (mo_b.T.conj(), hcore, mo_b)) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9) pt = mp.GMP2(mf) emp2, t2 = pt.kernel() dm1 = pt.make_rdm1() dm2 = pt.make_rdm2() #self.assertAlmostEqual(abs(numpy.einsum('ijkk->ji', dm2)/9 - dm1).max(), 0, 9) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, pt.e_tot, 9) hcore = pt._scf.get_hcore() mo = pt._scf.mo_coeff vhf = pt._scf.get_veff(mol, pt._scf.make_rdm1()) h1 = reduce(numpy.dot, (mo.T, hcore+vhf, mo)) dm1[numpy.diag_indices(mol.nelectron)] -= 1 e = numpy.einsum('pq,qp', h1, dm1) self.assertAlmostEqual(e, -emp2, 9)
def _make_eris_incore(mp, mo_coeff=None, ao2mofn=None, verbose=None): eris = _PhysicistsERIs(mp, mo_coeff) nocc = mp.nocc nao, nmo = eris.mo_coeff.shape nvir = nmo - nocc if callable(ao2mofn): orbo = eris.mo_coeff[:, :nocc] orbv = eris.mo_coeff[:, nocc:] eri = ao2mofn((orbo, orbv, orbo, orbv)).reshape(nocc, nvir, nocc, nvir) else: orbo = eris.mo_coeff[:, :nocc] orbv = eris.mo_coeff[:, nocc:] eri = ao2mo.kernel(mp.mol, (orbo, orbv, orbo, orbv), intor='int2e_spinor').reshape( nocc, nvir, nocc, nvir) eris.oovv = eri.transpose(0, 2, 1, 3) - eri.transpose(0, 2, 3, 1) return eris
def two_body_integrals(self): """A 4-dimension array for electron repulsion integrals in the MO representation. The integrals are computed as h[p,q,r,s]=\int \phi_p(x)* \phi_q(y)* V_{elec-elec} \phi_r(y) \phi_s(x) dxdy """ if self._two_body_integrals is None: mol = self._pyscf_data.get('mol', None) mo = self.canonical_orbitals n_orbitals = mo.shape[1] eri = ao2mo.kernel(mol, mo) eri = ao2mo.restore( 1, # no permutation symmetry eri, n_orbitals) # See PQRS convention in OpenFermion.hamiltonians.molecular_data # h[p,q,r,s] = (ps|qr) = pyscf_eri[p,s,q,r] self._two_body_integrals = numpy.asarray(eri.transpose(0, 2, 3, 1), order='C') return self._two_body_integrals
def get_pi_space(mol,mf,cas_norb,cas_nel,local=True): # {{{ from pyscf import mcscf, mo_mapping, lo, ao2mo # find the 2pz orbitals using mo_mapping ao_labels = ['C 2pz'] pop = mo_mapping.mo_comps(ao_labels, mol, mf.mo_coeff) cas_list = np.sort(pop.argsort()[-cas_norb:]) #take the 2z orbitals and resort in MO order print('Population for pz orbitals', pop[cas_list]) mo_occ = np.where(mf.mo_occ>0)[0] focc_list = list(set(mo_occ)-set(cas_list)) focc = len(focc_list) # localize the active space if local: cl_a = lo.Boys(mol, mf.mo_coeff[:, cas_list]).kernel(verbose=4) C = mf.mo_coeff C[:,cas_list] = cl_a else: C = mf.mo_coeff mo_energy = mf.mo_energy[cas_list] J,K = mf.get_jk() K = K[cas_list,:][:,cas_list] print(K) if mol.symmetry == True: from pyscf import symm mo = symm.symmetrize_orb(mol, C[:,cas_list]) osym = symm.label_orb_symm(mol, mol.irrep_name, mol.symm_orb, mo) #symm.addons.symmetrize_space(mol, mo, s=None, check=True, tol=1e-07) for i in range(len(osym)): print("%4d %8s %16.8f"%(i+1,osym[i],mo_energy[i])) # reorder the orbitals to get docc,active,vir ordering (Note:sort mo takes orbital ordering from 1) mycas = mcscf.CASCI(mf, cas_norb, cas_nel) C = mycas.sort_mo(cas_list+1,mo_coeff=C) # Get the active space integrals and the frozen core energy h, ecore = mycas.get_h1eff(C) g = ao2mo.kernel(mol,C[:,focc:focc+cas_norb], aosym = 's4', compact = False).reshape(4*((cas_norb),)) C = C[:,focc:focc+cas_norb] #only carrying the active sapce orbs return h,ecore,g,C
def test_h4(self): mol = gto.Mole() mol.verbose = 0 mol.atom = [ ['H', ( 1.,-1. , 0. )], ['H', ( 0.,-1. ,-1. )], ['H', ( 1.,-0.5 , 0. )], ['H', ( 0.,-1. , 1. )], ] mol.charge = 2 mol.basis = '3-21g' mol.build() mf = scf.RHF(mol).run(conv_tol=1e-14) ecisd = ci.CISD(mf).kernel()[0] self.assertAlmostEqual(ecisd, -0.024780739973407784, 8) h2e = ao2mo.kernel(mf._eri, mf.mo_coeff) h1e = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) eci = fci.direct_spin0.kernel(h1e, h2e, mf.mo_coeff.shape[1], mol.nelectron)[0] eci = eci + mol.energy_nuc() - mf.e_tot self.assertAlmostEqual(ecisd, eci, 9)
def test_rdm(self): mol = gto.Mole() mol.verbose = 5 mol.output = '/dev/null' mol.atom = [ ['O', (0., 0., 0.)], ['H', (0., -0.757, 0.587)], ['H', (0., 0.757, 0.587)], ] mol.basis = { 'H': 'sto-3g', 'O': 'sto-3g', } mol.build() mf = scf.RHF(mol).run() myci = ci.CISD(mf) ecisd, civec = myci.kernel() self.assertAlmostEqual(ecisd, -0.048878084082066106, 12) nmo = mf.mo_coeff.shape[1] nocc = mol.nelectron // 2 ci0 = myci.to_fci(civec, nmo, nocc * 2) ref1, ref2 = fci.direct_spin1.make_rdm12(ci0, nmo, nocc * 2) rdm1 = myci.make_rdm1(civec) rdm2 = myci.make_rdm2(civec) self.assertTrue(numpy.allclose(rdm2, ref2)) self.assertAlmostEqual(finger(rdm1), 2.2685199485281689, 9) self.assertAlmostEqual(finger(rdm2), -3.7944039102480649, 9) self.assertAlmostEqual( abs(rdm2 - rdm2.transpose(2, 3, 0, 1)).sum(), 0, 9) self.assertAlmostEqual( abs(rdm2 - rdm2.transpose(1, 0, 3, 2)).sum(), 0, 9) h1e = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) h2e = ao2mo.kernel(mf._eri, mf.mo_coeff) h2e = ao2mo.restore(1, h2e, nmo) e2 = (numpy.dot(h1e.flatten(), rdm1.flatten()) + numpy.dot(h2e.flatten(), rdm2.flatten()) * .5) self.assertAlmostEqual(ecisd + mf.e_tot - mol.energy_nuc(), e2, 9) dm1 = numpy.einsum('ijkk->ij', rdm2) / (mol.nelectron - 1) self.assertAlmostEqual(abs(rdm1 - dm1).sum(), 0, 9)
def prepValence(mol, ncore, nact, occ=None, loc="iao", dm=None, writeFcidump=True, writeMolden=False, writeBestDet=True, writeMOs=True): mf = doRHF(mol) mo = mf.mo_coeff lmo = localizeValence(mf, mo[:,ncore:ncore+nact], loc) if writeMolden: tools.molden.from_mo(mol, 'valenceOrbs.molden', lmo) nelec = mol.nelectron - 2 * ncore mc = mcscf.CASSCF(mf, nact, nelec) h1cas, energy_core = mcscf.casci.h1e_for_cas(mc, mf.mo_coeff, nact, ncore) mo_core = mc.mo_coeff[:,:ncore] core_dm = 2 * mo_core.dot(mo_core.T) corevhf = mc.get_veff(mol, core_dm) h1eff = lmo.T.dot(mc.get_hcore() + corevhf).dot(lmo) eri = ao2mo.kernel(mol, lmo) if writeFcidump: tools.fcidump.from_integrals('FCIDUMP', h1eff, eri, nact, nelec, energy_core) if occ is not None: bestDetValence(mol, lmo, occ, eri, writeBestDet) # make fictitious valence only molecule and perform ghf norb = nact molA = gto.M() molA.nelectron = nelec molA.verbose = 4 molA.incore_anyway = True gmf = scf.GHF(molA) gmf.get_hcore = lambda *args: la.block_diag(h1eff, h1eff) gmf.get_ovlp = lambda *args: np.identity(2*norb) gmf.energy_nuc = lambda *args: energy_core gmf._eri = eri if dm is None: dm = gmf.get_init_guess() dm = dm + 2 * np.random.rand(2*norb, 2*norb) gmf.level_shift = 0.1 gmf.max_cycle = 500 print(gmf.kernel(dm0 = dm)) if writeMOs: writeMat(gmf.mo_coeff, "hf.txt", False)
def fci_simple(mol, m, lam=1.0): norb = m.mo_coeff.shape[1] nelec = mol.nelectron f = m.get_fock() hprime = f + lam * (m.get_hcore() - f) h1e = reduce(numpy.dot, (m.mo_coeff.T, hprime, m.mo_coeff)) eri = ao2mo.kernel(m._eri, m.mo_coeff, compact=False) eri = lam * eri.reshape(norb, norb, norb, norb) h2e = fci_slow.absorb_h1e(h1e, eri, norb, nelec, .5) na = cistring.num_strings(norb, nelec // 2) N = na * na assert (N < 2000) H = numpy.zeros((N, N)) I = numpy.identity(N) for i in range(N): hc = fci_slow.contract_2e(h2e, I[:, i], norb, nelec) hc.reshape(-1) H[:, i] = hc e, v = numpy.linalg.eigh(H) #print(e[0] + mol.energy_nuc()) return e[0] + mol.energy_nuc()
def test_h8(self): mol = gto.Mole() mol.verbose = 0 mol.output = None mol.atom = [ ['H', (1., -1., 0.)], ['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).run() 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) myci = select_ci.SCI() myci.select_cutoff = 1e-3 myci.ci_coeff_cutoff = 1e-3 e1, c1 = myci.kernel(h1e, eri, norb, nelec) self.assertAlmostEqual(e1, -11.894613845925514, 9) e, c = myci.kernel_fixed_space(h1e, eri, norb, nelec, c1._strs) self.assertAlmostEqual(e, -11.894613845925514, 9) res = myci.large_ci(c1, norb, nelec, .25) self.assertEqual([x[1] for x in res], ['0b1111', '0b1111', '0b10111', '0b10111']) self.assertEqual([x[2] for x in res], ['0b1111', '0b10111', '0b1111', '0b10111']) self.assertAlmostEqual(myci.spin_square(c1, norb, nelec)[0], 0, 2)
def compute_integrals(problem_description, molecule, RHF): """ Compute one and two-electron integrals and output in Broombridge format """ one_electron_integrals = problem_description.hamiltonian[ 'OneElectronIntegrals']['Values'] two_electron_integrals = problem_description.hamiltonian[ 'TwoElectronIntegrals']['Values'] # Get molecular orbital coefficients h_pq = np.around(RHF.mo_coeff.T @ RHF.get_hcore() @ RHF.mo_coeff, decimals=6) one_electron_integrals = [([j, i], h_pq[i - 1, j - 1]) for (j, i), _ in one_electron_integrals] # Get interaction terms h_pqrs = np.around( ao2mo.restore(1, ao2mo.kernel(molecule, RHF.mo_coeff), 2), 6) two_electron_integrals = [([l, k, j, i], h_pqrs[i - 1, j - 1, k - 1, l - 1]) for (l, k, j, i), _ in two_electron_integrals] return one_electron_integrals, two_electron_integrals
def _make_eris_incore(mycc, mo_coeff=None, ao2mofn=None): cput0 = (time.clock(), time.time()) eris = _PhysicistsERIs() eris._common_init_(mycc, mo_coeff) nocc = eris.nocc nao, nmo = eris.mo_coeff.shape if callable(ao2mofn): eri = ao2mofn(eris.mo_coeff).reshape([nmo] * 4) else: mo = eris.mo_coeff eri = ao2mo.kernel(mycc.mol.intor('int2e_spinor'), mo).reshape(nmo, nmo, nmo, nmo) eri = eri.transpose(0, 2, 1, 3) - eri.transpose(0, 2, 3, 1) eris.oooo = eri[:nocc, :nocc, :nocc, :nocc].copy() eris.ooov = eri[:nocc, :nocc, :nocc, nocc:].copy() eris.oovv = eri[:nocc, :nocc, nocc:, nocc:].copy() eris.ovov = eri[:nocc, nocc:, :nocc, nocc:].copy() eris.ovvo = eri[:nocc, nocc:, nocc:, :nocc].copy() eris.ovvv = eri[:nocc, nocc:, nocc:, nocc:].copy() eris.vvvv = eri[nocc:, nocc:, nocc:, nocc:].copy() return eris
def test_rdm(self): mycc = rccsd.RCCSD(mf) mycc.frozen = 1 mycc.kernel() dm1 = mycc.make_rdm1() dm2 = mycc.make_rdm2() h1 = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) nmo = mf.mo_coeff.shape[1] eri = ao2mo.restore(1, ao2mo.kernel(mf._eri, mf.mo_coeff), nmo) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, mycc.e_tot, 7) d1 = ccsd_rdm._gamma1_intermediates(mycc, mycc.t1, mycc.t2, mycc.l1, mycc.l2) mycc1 = copy.copy(mycc) mycc1.max_memory = 0 d2 = ccsd_rdm._gamma2_intermediates(mycc1, mycc.t1, mycc.t2, mycc.l1, mycc.l2, True) dm2 = ccsd_rdm._make_rdm2(mycc, d1, d2, with_dm1=True, with_frozen=True) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() self.assertAlmostEqual(e1, mycc.e_tot, 7)
def fci(mol, printroots=4, visualize=False, preservedict=True): if not preservedict: __hamdict = {} print("PYCI") print("method: FCI") print("Number of eigenvalues: ", printroots) print("") Na, Nb = mol.nelec #nelec is a tuple with (N_alpha, N_beta) E_nuc = mol.energy_nuc() nao = mol.nao_nr() myhf = scf.RHF(mol) E_hf = myhf.kernel() mo_coefficients = myhf.mo_coeff h1e = reduce(np.dot, (mo_coefficients.T, myhf.get_hcore(), mo_coefficients)) print("transforming eris") eri = ao2mo.kernel(mol, mo_coefficients) print("generating all determinants") fulldetlist_sets = gen_dets_sets(nao, Na, Nb) ndets = len(fulldetlist_sets) print("constructing full Hamiltonian") full_hamiltonian = construct_hamiltonian(ndets, fulldetlist_sets, h1e, eri) eig_vals, eig_vecs = sp.sparse.linalg.eigsh(full_hamiltonian, k=2 * printroots) eig_vals_sorted = np.sort(eig_vals)[:printroots] print("") print("first {:} pyci eigvals".format(printroots)) for i in (eig_vals_sorted + E_nuc): print(i) if visualize: print(len(fulldetlist_sets), len(eig_vecs[:, np.argsort(eig_vals)[0]])) newdet = [ i for i in zip(list(fulldetlist_sets), eig_vecs[:, np.argsort(eig_vals)[0]]) ] visualize_sets(newdet, nao, Na, Nb, "FCI") print("Completed FCI!")
def fcidump(mf, filename='FCIDUMP', tol=1e-8, float_format='%18.12f'): from pyscf.tools.fcidump import from_integrals from pyscf import ao2mo from numpy import dot h1e = reduce(dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) eri = ao2mo.kernel(mf.mol, mf.mo_coeff) nmo = mf.mo_coeff.shape[1] nelec = mf.mol.nelectron ms = 0 orbsym = None fout = open(filename, 'w', 0) write_head(fout, nmo, nelec, ms, orbsym) write_eri(fout, eri, nmo, tol=tol, float_format=float_format) write_hcore(fout, h1e, nmo, tol=tol, float_format=float_format) output_format = float_format + ' 0 0 0 0' fout.write(output_format % mf.energy_nuc()) fout.close()
def test_kernel(self): nao = mol.nao mo = numpy.random.random((nao, 4)) mo1 = numpy.random.random((nao, 2)) eri = ao2mo.kernel(mol, mo, intor='int2e') self.assertEqual(eri.shape, (10, 10)) eri = ao2mo.kernel(mol, [mo, mo1, mo1, mo], intor='int2e') self.assertEqual(eri.shape, (8, 8)) eri = ao2mo.kernel(mol, [mo, mo, mo1, mo1]) self.assertEqual(eri.shape, (10, 3)) eri = ao2mo.kernel(mol, [mo, mo, mo1, mo1]) self.assertEqual(eri.shape, (10, 3)) nao = mol.nao_2c() mo = numpy.random.random((nao, 4)) mo1 = numpy.random.random((nao, 2)) eri = ao2mo.kernel(mol, mo, intor='int2e_spinor') self.assertEqual(eri.shape, (16, 16)) eri = ao2mo.kernel(mol, [mo, mo, mo1, mo1], intor='int2e_spinor') self.assertEqual(eri.shape, (16, 4))
l2 = (l2aa, l2, l2aa) mycc = cc.UCCSD(mf) eris = mycc.ao2mo() dm1 = make_rdm1(mycc, t1, t2, l1, l2, eris) dm2 = make_rdm2(mycc, t1, t2, l1, l2, eris) trdm1 = dm1[0] + dm1[1] trdm2 = dm2[0] + dm2[1] + dm2[1].transpose(2, 3, 0, 1) + dm2[2] print(abs(trdm1 - dm1ref).max()) print(abs(trdm2 - dm2ref).max()) ecc = mycc.kernel(eris=eris)[0] l1, l2 = mycc.solve_lambda(eris=eris) e3ref = mycc.e_tot + mycc.ccsd_t() nmoa, nmob = mycc.nmo eri_aa = ao2mo.kernel(mf._eri, mf.mo_coeff[0], compact=False).reshape([nmoa] * 4) eri_bb = ao2mo.kernel(mf._eri, mf.mo_coeff[1], compact=False).reshape([nmob] * 4) eri_ab = ao2mo.kernel(mf._eri, [mf.mo_coeff[k] for k in (0, 0, 1, 1)], compact=False).reshape(nmoa, nmoa, nmob, nmob) dm1 = make_rdm1(mycc, t1, t2, l1, l2, eris=eris) dm2 = make_rdm2(mycc, t1, t2, l1, l2, eris=eris) h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) e3 = (numpy.einsum('ij,ji->', h1a, dm1[0]) + numpy.einsum('ij,ji->', h1b, dm1[1]) + numpy.einsum('ijkl,ijkl->', eri_aa, dm2[0]) * .5 + numpy.einsum('ijkl,ijkl->', eri_bb, dm2[2]) * .5 + numpy.einsum('ijkl,ijkl->', eri_ab, dm2[1]) + mf.mol.energy_nuc()) print(e3 - e3ref)
c2bb = .1 * numpy.random.random((noccb, noccb, nvirb, nvirb)) c2ab = .1 * numpy.random.random((nocca, noccb, nvira, nvirb)) cisdvec = amplitudes_to_cisdvec(1., (c1a, c1b), (c2aa, c2ab, c2bb)) hcisd0 = contract( myci, amplitudes_to_cisdvec(1., (c1a, c1b), (c2aa, c2ab, c2bb)), eris) # from pyscf.ci import gcisd_slow # res = cisdvec_to_amplitudes(hcisd0, nmoa_nmob, nocca_noccb) # res = (res[0], # uccsd.spatial2spin(res[1], eris.orbspin), # uccsd.spatial2spin(res[2], eris.orbspin)) # print(lib.finger(gcisd_slow.amplitudes_to_cisdvec(*res)) - 187.10206473716548) print(lib.finger(hcisd0) - 466.56620234351681) eris = myci.ao2mo(mf.mo_coeff) hcisd0 = contract(myci, cisdvec, eris) eri_aa = ao2mo.kernel(mf._eri, mf.mo_coeff[0]) eri_bb = ao2mo.kernel(mf._eri, mf.mo_coeff[1]) eri_ab = ao2mo.kernel( mf._eri, [mf.mo_coeff[0], mf.mo_coeff[0], mf.mo_coeff[1], mf.mo_coeff[1]]) h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) h2e = fci.direct_uhf.absorb_h1e((h1a, h1b), (eri_aa, eri_ab, eri_bb), h1a.shape[0], mol.nelec, .5) nmo = (mf.mo_coeff[0].shape[1], mf.mo_coeff[1].shape[1]) fcivec = to_fci(cisdvec, nmo, mol.nelec) hci1 = fci.direct_uhf.contract_2e(h2e, fcivec, h1a.shape[0], mol.nelec) hci1 -= ehf0 * fcivec hcisd1 = from_fci(hci1, nmo, mol.nelec) print(numpy.linalg.norm(hcisd1 - hcisd0) / numpy.linalg.norm(hcisd0))
def kernel(mc, mo_coeff=None, ci=None, atmlst=None, mf_grad=None, verbose=None): if mo_coeff is None: mo_coeff = mc._scf.mo_coeff if ci is None: ci = mc.ci if mf_grad is None: mf_grad = mc._scf.nuc_grad_method() assert (isinstance(ci, numpy.ndarray)) mol = mc.mol ncore = mc.ncore ncas = mc.ncas nocc = ncore + ncas nelecas = mc.nelecas nao, nmo = mo_coeff.shape nao_pair = nao * (nao + 1) // 2 mo_energy = mc._scf.mo_energy mo_occ = mo_coeff[:, :nocc] mo_core = mo_coeff[:, :ncore] mo_cas = mo_coeff[:, ncore:nocc] neleca, nelecb = mol.nelec assert (neleca == nelecb) orbo = mo_coeff[:, :neleca] orbv = mo_coeff[:, neleca:] casdm1, casdm2 = mc.fcisolver.make_rdm12(ci, ncas, nelecas) dm_core = numpy.dot(mo_core, mo_core.T) * 2 dm_cas = reduce(numpy.dot, (mo_cas, casdm1, mo_cas.T)) aapa = ao2mo.kernel(mol, (mo_cas, mo_cas, mo_coeff, mo_cas), compact=False) aapa = aapa.reshape(ncas, ncas, nmo, ncas) vj, vk = mc._scf.get_jk(mol, (dm_core, dm_cas)) h1 = mc.get_hcore() vhf_c = vj[0] - vk[0] * .5 vhf_a = vj[1] - vk[1] * .5 # Imat = h1_{pi} gamma1_{iq} + h2_{pijk} gamma_{iqkj} Imat = numpy.zeros((nmo, nmo)) Imat[:, :nocc] = reduce(numpy.dot, (mo_coeff.T, h1 + vhf_c + vhf_a, mo_occ)) * 2 Imat[:, ncore:nocc] = reduce(numpy.dot, (mo_coeff.T, h1 + vhf_c, mo_cas, casdm1)) Imat[:, ncore:nocc] += lib.einsum('uviw,vuwt->it', aapa, casdm2) aapa = vj = vk = vhf_c = vhf_a = h1 = None ee = mo_energy[:, None] - mo_energy zvec = numpy.zeros_like(Imat) zvec[:ncore, ncore:neleca] = Imat[:ncore, ncore:neleca] / -ee[:ncore, ncore:neleca] zvec[ncore:neleca, :ncore] = Imat[ ncore:neleca, :ncore] / -ee[ncore:neleca, :ncore] zvec[nocc:, neleca:nocc] = Imat[nocc:, neleca:nocc] / -ee[nocc:, neleca:nocc] zvec[neleca:nocc, nocc:] = Imat[neleca:nocc, nocc:] / -ee[neleca:nocc, nocc:] zvec_ao = reduce(numpy.dot, (mo_coeff, zvec + zvec.T, mo_coeff.T)) vhf = mc._scf.get_veff(mol, zvec_ao) * 2 xvo = reduce(numpy.dot, (orbv.T, vhf, orbo)) xvo += Imat[neleca:, :neleca] - Imat[:neleca, neleca:].T def fvind(x): x = x.reshape(xvo.shape) dm = reduce(numpy.dot, (orbv, x, orbo.T)) v = mc._scf.get_veff(mol, dm + dm.T) v = reduce(numpy.dot, (orbv.T, v, orbo)) return v * 2 dm1resp = cphf.solve(fvind, mo_energy, mc._scf.mo_occ, xvo, max_cycle=30)[0] zvec[neleca:, :neleca] = dm1resp zeta = numpy.einsum('ij,j->ij', zvec, mo_energy) zeta = reduce(numpy.dot, (mo_coeff, zeta, mo_coeff.T)) zvec_ao = reduce(numpy.dot, (mo_coeff, zvec + zvec.T, mo_coeff.T)) p1 = numpy.dot(mo_coeff[:, :neleca], mo_coeff[:, :neleca].T) vhf_s1occ = reduce(numpy.dot, (p1, mc._scf.get_veff(mol, zvec_ao), p1)) Imat[:ncore, ncore:neleca] = 0 Imat[ncore:neleca, :ncore] = 0 Imat[nocc:, neleca:nocc] = 0 Imat[neleca:nocc, nocc:] = 0 Imat[neleca:, :neleca] = Imat[:neleca, neleca:].T im1 = reduce(numpy.dot, (mo_coeff, Imat, mo_coeff.T)) casci_dm1 = dm_core + dm_cas hf_dm1 = mc._scf.make_rdm1(mo_coeff, mc._scf.mo_occ) hcore_deriv = mf_grad.hcore_generator(mol) s1 = mf_grad.get_ovlp(mol) diag_idx = numpy.arange(nao) diag_idx = diag_idx * (diag_idx + 1) // 2 + diag_idx casdm2_cc = casdm2 + casdm2.transpose(0, 1, 3, 2) dm2buf = ao2mo._ao2mo.nr_e2(casdm2_cc.reshape(ncas**2, ncas**2), mo_cas.T, (0, nao, 0, nao)).reshape(ncas**2, nao, nao) dm2buf = lib.pack_tril(dm2buf) dm2buf[:, diag_idx] *= .5 dm2buf = dm2buf.reshape(ncas, ncas, nao_pair) casdm2 = casdm2_cc = None if atmlst is None: atmlst = range(mol.natm) aoslices = mol.aoslice_by_atom() de = numpy.zeros((len(atmlst), 3)) max_memory = mc.max_memory - lib.current_memory()[0] blksize = int(max_memory * .9e6 / 8 / ((aoslices[:, 3] - aoslices[:, 2]).max() * nao_pair)) blksize = min(nao, max(2, blksize)) for k, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] h1ao = hcore_deriv(ia) de[k] += numpy.einsum('xij,ij->x', h1ao, casci_dm1) de[k] += numpy.einsum('xij,ij->x', h1ao, zvec_ao) vhf1 = numpy.zeros((3, nao, nao)) q1 = 0 for b0, b1, nf in _shell_prange(mol, 0, mol.nbas, blksize): q0, q1 = q1, q1 + nf dm2_ao = lib.einsum('ijw,pi,qj->pqw', dm2buf, mo_cas[p0:p1], mo_cas[q0:q1]) shls_slice = (shl0, shl1, b0, b1, 0, mol.nbas, 0, mol.nbas) eri1 = mol.intor('int2e_ip1', comp=3, aosym='s2kl', shls_slice=shls_slice).reshape( 3, p1 - p0, nf, nao_pair) de[k] -= numpy.einsum('xijw,ijw->x', eri1, dm2_ao) * 2 for i in range(3): eri1tmp = lib.unpack_tril(eri1[i].reshape((p1 - p0) * nf, -1)) eri1tmp = eri1tmp.reshape(p1 - p0, nf, nao, nao) de[k, i] -= numpy.einsum('ijkl,ij,kl', eri1tmp, hf_dm1[p0:p1, q0:q1], zvec_ao) * 2 de[k, i] -= numpy.einsum('ijkl,kl,ij', eri1tmp, hf_dm1, zvec_ao[p0:p1, q0:q1]) * 2 de[k, i] += numpy.einsum('ijkl,il,kj', eri1tmp, hf_dm1[p0:p1], zvec_ao[q0:q1]) de[k, i] += numpy.einsum('ijkl,jk,il', eri1tmp, hf_dm1[q0:q1], zvec_ao[p0:p1]) #:vhf1c, vhf1a = mf_grad.get_veff(mol, (dm_core, dm_cas)) #:de[k] += numpy.einsum('xij,ij->x', vhf1c[:,p0:p1], casci_dm1[p0:p1]) * 2 #:de[k] += numpy.einsum('xij,ij->x', vhf1a[:,p0:p1], dm_core[p0:p1]) * 2 de[k, i] -= numpy.einsum('ijkl,lk,ij', eri1tmp, dm_core[q0:q1], casci_dm1[p0:p1]) * 2 de[k, i] += numpy.einsum('ijkl,jk,il', eri1tmp, dm_core[q0:q1], casci_dm1[p0:p1]) de[k, i] -= numpy.einsum('ijkl,lk,ij', eri1tmp, dm_cas[q0:q1], dm_core[p0:p1]) * 2 de[k, i] += numpy.einsum('ijkl,jk,il', eri1tmp, dm_cas[q0:q1], dm_core[p0:p1]) eri1 = eri1tmp = None de[k] -= numpy.einsum('xij,ij->x', s1[:, p0:p1], im1[p0:p1]) de[k] -= numpy.einsum('xij,ji->x', s1[:, p0:p1], im1[:, p0:p1]) de[k] -= numpy.einsum('xij,ij->x', s1[:, p0:p1], zeta[p0:p1]) * 2 de[k] -= numpy.einsum('xij,ji->x', s1[:, p0:p1], zeta[:, p0:p1]) * 2 de[k] -= numpy.einsum('xij,ij->x', s1[:, p0:p1], vhf_s1occ[p0:p1]) * 2 de[k] -= numpy.einsum('xij,ji->x', s1[:, p0:p1], vhf_s1occ[:, p0:p1]) * 2 de += rhf_grad.grad_nuc(mol, atmlst) return de
def _make_eris_outcore(mp, mo_coeff=None, verbose=None): cput0 = (time.clock(), time.time()) log = logger.Logger(mp.stdout, mp.verbose) eris = _PhysicistsERIs() eris._common_init_(mp, mo_coeff) nocc = mp.nocc nao, nmo = eris.mo_coeff.shape nvir = nmo - nocc assert (eris.mo_coeff.dtype == numpy.double) orboa = eris.mo_coeff[:nao // 2, :nocc] orbob = eris.mo_coeff[nao // 2:, :nocc] orbva = eris.mo_coeff[:nao // 2, nocc:] orbvb = eris.mo_coeff[nao // 2:, nocc:] orbspin = eris.orbspin feri = eris.feri = lib.H5TmpFile() dtype = numpy.result_type(eris.mo_coeff).char eris.oovv = feri.create_dataset('oovv', (nocc, nocc, nvir, nvir), dtype) if orbspin is None: max_memory = mp.max_memory - lib.current_memory()[0] blksize = min(nocc, max(2, int(max_memory * 1e6 / 8 / (nocc * nvir**2 * 2)))) max_memory = max(2000, max_memory) fswap = lib.H5TmpFile() ao2mo.kernel(mp.mol, (orboa, orbva, orboa, orbva), fswap, 'aaaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mp.mol, (orboa, orbva, orbob, orbvb), fswap, 'aabb', max_memory=max_memory, verbose=log) ao2mo.kernel(mp.mol, (orbob, orbvb, orboa, orbva), fswap, 'bbaa', max_memory=max_memory, verbose=log) ao2mo.kernel(mp.mol, (orbob, orbvb, orbob, orbvb), fswap, 'bbbb', max_memory=max_memory, verbose=log) for p0, p1 in lib.prange(0, nocc, blksize): tmp = numpy.asarray(fswap['aaaa'][p0 * nvir:p1 * nvir]) tmp += numpy.asarray(fswap['aabb'][p0 * nvir:p1 * nvir]) tmp += numpy.asarray(fswap['bbaa'][p0 * nvir:p1 * nvir]) tmp += numpy.asarray(fswap['bbbb'][p0 * nvir:p1 * nvir]) tmp = tmp.reshape(p1 - p0, nvir, nocc, nvir) eris.oovv[p0:p1] = tmp.transpose(0, 2, 1, 3) - tmp.transpose( 0, 2, 3, 1) else: # with orbspin orbo = orboa + orbob orbv = orbva + orbvb max_memory = mp.max_memory - lib.current_memory()[0] blksize = min(nocc, max(2, int(max_memory * 1e6 / 8 / (nocc * nvir**2 * 2)))) max_memory = max(2000, max_memory) fswap = lib.H5TmpFile() ao2mo.kernel(mp.mol, (orbo, orbv, orbo, orbv), fswap, max_memory=max_memory, verbose=log) sym_forbid = orbspin[:nocc, None] != orbspin[nocc:] for p0, p1 in lib.prange(0, nocc, blksize): tmp = numpy.asarray(fswap['eri_mo'][p0 * nvir:p1 * nvir]) tmp = tmp.reshape(p1 - p0, nvir, nocc, nvir) tmp[sym_forbid[p0:p1]] = 0 tmp[:, :, sym_forbid] = 0 eris.oovv[p0:p1] = tmp.transpose(0, 2, 1, 3) - tmp.transpose( 0, 2, 3, 1) cput0 = log.timer_debug1('transforming oovv', *cput0) return eris
from pyscf import ao2mo mol = gto.Mole() mol.verbose = 0 mol.atom = [ ['O', (0., 0., 0.)], ['H', (0., -0.757, 0.587)], ['H', (0., 0.757, 0.587)], ] mol.basis = 'sto3g' mol.build() mf = scf.RHF(mol).run() myci = CISD(mf) eris = ccsd._make_eris_outcore(myci, mf.mo_coeff) ecisd, civec = myci.kernel(eris=eris) print(ecisd - -0.048878084082066106) nmo = myci.nmo nocc = myci.nocc rdm1 = myci.make_rdm1(civec) rdm2 = myci.make_rdm2(civec) h1e = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) h2e = ao2mo.kernel(mf._eri, mf.mo_coeff) h2e = ao2mo.restore(1, h2e, nmo) e2 = (numpy.einsum('ij,ji', h1e, rdm1) + numpy.einsum('ijkl,ijkl', h2e, rdm2) * .5) print(ecisd + mf.e_tot - mol.energy_nuc() - e2) # = 0 print( abs(rdm1 - numpy.einsum('ijkk->ji', rdm2) / (mol.nelectron - 1)).sum())
mol.basis = {'H': 'sto-3g', 'O': 'sto-3g',} mol.build() mf = scf.UHF(mol).run(conv_tol=1e-14) gmf = scf.addons.convert_to_ghf(mf) myci = GCISD(gmf) eris = myci.ao2mo() ecisd, civec = myci.kernel(eris=eris) print(ecisd - -0.048878084082066106) nmo = eris.mo_coeff.shape[1] rdm1 = myci.make_rdm1(civec, nmo, mol.nelectron) rdm2 = myci.make_rdm2(civec, nmo, mol.nelectron) mo = eris.mo_coeff[:7] + eris.mo_coeff[7:] eri = ao2mo.kernel(mf._eri, mo, compact=False).reshape([nmo]*4) eri[eris.orbspin[:,None]!=eris.orbspin,:,:] = 0 eri[:,:,eris.orbspin[:,None]!=eris.orbspin] = 0 h1a = reduce(numpy.dot, (mf.mo_coeff[0].T, mf.get_hcore(), mf.mo_coeff[0])) h1b = reduce(numpy.dot, (mf.mo_coeff[1].T, mf.get_hcore(), mf.mo_coeff[1])) h1e = numpy.zeros((nmo,nmo)) idxa = eris.orbspin == 0 idxb = eris.orbspin == 1 h1e[idxa[:,None]&idxa] = h1a.ravel() h1e[idxb[:,None]&idxb] = h1b.ravel() e2 = (numpy.einsum('ij,ji', h1e, rdm1) + numpy.einsum('ijkl,ijkl', eri, rdm2) * .5) e2 += mol.energy_nuc() print(myci.e_tot - e2) # = 0 print(abs(rdm1 - numpy.einsum('ijkk->ji', rdm2)/(mol.nelectron-1)).sum())
a = scf.UHF(mol) a.scf() ####### This can be removed ###### frozen = [[0], [0]] # 1sa and 1sb pt2 = mp.UMP2(a) pt2.frozen = frozen pt2.kernel() rdm1a, rdm1b = pt2.make_rdm1() rdm2aa, rdm2ab, rdm2bb = pt2.make_rdm2() mo_a = a.mo_coeff[0] mo_b = a.mo_coeff[1] nmoa = mo_a.shape[1] nmob = mo_b.shape[1] eriaa = ao2mo.kernel(a._eri, mo_a, compact=False).reshape([nmoa] * 4) eribb = ao2mo.kernel(a._eri, mo_b, compact=False).reshape([nmob] * 4) eriab = ao2mo.kernel(a._eri, (mo_a, mo_a, mo_b, mo_b), compact=False) eriab = eriab.reshape([nmoa, nmoa, nmob, nmob]) hcore = a.get_hcore() h1a = reduce(numpy.dot, (mo_a.T.conj(), hcore, mo_a)) h1b = reduce(numpy.dot, (mo_b.T.conj(), hcore, mo_b)) e1 = einsum('ij,ji', h1a, rdm1a) e1 += einsum('ij,ji', h1b, rdm1b) e1 += einsum('ijkl,ijkl', eriaa, rdm2aa) * 0.5 e1 += einsum('ijkl,ijkl', eriab, rdm2ab) e1 += einsum('ijkl,ijkl', eribb, rdm2bb) * 0.5 e1 += mol.energy_nuc() lib.logger.info(pt2, "* Ground state Energy with 1/2-RDM : %.8f" % e1) ####### This can be removed ######
if __name__ == '__main__': from functools import reduce from pyscf import gto from pyscf import scf mol = gto.Mole() mol.verbose = 0 mol.output = None mol.atom = [ ['H', (1., -1., 0.)], ['H', (0., -1., -1.)], ['H', (1., -0.5, -1.)], ['H', (0., -0., -1.)], ['H', (1., -0.5, 0.)], ['H', (0., 1., 1.)], ] mol.basis = 'sto-3g' mol.build() m = scf.RHF(mol) m.kernel() norb = m.mo_coeff.shape[1] nelec = mol.nelectron - 2 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 = kernel(h1e, eri, norb, nelec) print(e1, e1 - -7.9766331504361414)
print(numpy.allclose(dm2, dm2.transpose(1,0,3,2))) print(numpy.allclose(dm2, dm2.transpose(2,3,0,1))) d1 = numpy.einsum('kkpq->qp', dm2) / 9 print(numpy.allclose(d1, dm1)) mol = gto.Mole() mol.atom = [ [8 , (0. , 0. , 0.)], [1 , (0. , -0.757 , 0.587)], [1 , (0. , 0.757 , 0.587)]] mol.basis = '631g' mol.build() mf = scf.RHF(mol).run() mycc = ccsd.CCSD(mf) mycc.frozen = 2 ecc, t1, t2 = mycc.kernel() l1, l2 = mycc.solve_lambda() dm1 = make_rdm1(mycc, t1, t2, l1, l2) dm2 = make_rdm2(mycc, t1, t2, l1, l2) nmo = mf.mo_coeff.shape[1] eri = ao2mo.kernel(mf._eri, mf.mo_coeff, compact=False).reshape([nmo]*4) hcore = mf.get_hcore() h1 = reduce(numpy.dot, (mf.mo_coeff.T, hcore, mf.mo_coeff)) e1 = numpy.einsum('ij,ji', h1, dm1) e1+= numpy.einsum('ijkl,ijkl', eri, dm2) * .5 e1+= mol.energy_nuc() print(e1 - mycc.e_tot)
def kernel(mc, mo_coeff=None, ci=None, atmlst=None, mf_grad=None, verbose=None): if mo_coeff is None: mo_coeff = mc.mo_coeff if ci is None: ci = mc.ci if mf_grad is None: mf_grad = mc._scf.nuc_grad_method() if mc.frozen is not None: raise NotImplementedError mol = mc.mol ncore = mc.ncore ncas = mc.ncas nocc = ncore + ncas nelecas = mc.nelecas nao, nmo = mo_coeff.shape nao_pair = nao * (nao + 1) // 2 mo_occ = mo_coeff[:, :nocc] mo_core = mo_coeff[:, :ncore] mo_cas = mo_coeff[:, ncore:nocc] casdm1, casdm2 = mc.fcisolver.make_rdm12(ci, ncas, nelecas) # gfock = Generalized Fock, Adv. Chem. Phys., 69, 63 dm_core = numpy.dot(mo_core, mo_core.T) * 2 dm_cas = reduce(numpy.dot, (mo_cas, casdm1, mo_cas.T)) aapa = ao2mo.kernel(mol, (mo_cas, mo_cas, mo_occ, mo_cas), compact=False) aapa = aapa.reshape(ncas, ncas, nocc, ncas) vj, vk = mc._scf.get_jk(mol, (dm_core, dm_cas)) h1 = mc.get_hcore() vhf_c = vj[0] - vk[0] * .5 vhf_a = vj[1] - vk[1] * .5 gfock = reduce(numpy.dot, (mo_occ.T, h1 + vhf_c + vhf_a, mo_occ)) * 2 gfock[:, ncore:nocc] = reduce(numpy.dot, (mo_occ.T, h1 + vhf_c, mo_cas, casdm1)) gfock[:, ncore:nocc] += numpy.einsum('uviw,vuwt->it', aapa, casdm2) dme0 = reduce(numpy.dot, (mo_occ, (gfock + gfock.T) * .5, mo_occ.T)) aapa = vj = vk = vhf_c = vhf_a = h1 = gfock = None dm1 = dm_core + dm_cas vhf1c, vhf1a = mf_grad.get_veff(mol, (dm_core, dm_cas)) hcore_deriv = mf_grad.hcore_generator(mol) s1 = mf_grad.get_ovlp(mol) diag_idx = numpy.arange(nao) diag_idx = diag_idx * (diag_idx + 1) // 2 + diag_idx casdm2_cc = casdm2 + casdm2.transpose(0, 1, 3, 2) dm2buf = ao2mo._ao2mo.nr_e2(casdm2_cc.reshape(ncas**2, ncas**2), mo_cas.T, (0, nao, 0, nao)).reshape(ncas**2, nao, nao) dm2buf = lib.pack_tril(dm2buf) dm2buf[:, diag_idx] *= .5 dm2buf = dm2buf.reshape(ncas, ncas, nao_pair) casdm2 = casdm2_cc = None if atmlst is None: atmlst = range(mol.natm) aoslices = mol.aoslice_by_atom() de = numpy.zeros((len(atmlst), 3)) max_memory = mc.max_memory - lib.current_memory()[0] blksize = int(max_memory * .9e6 / 8 / ((aoslices[:, 3] - aoslices[:, 2]).max() * nao_pair)) blksize = min(nao, max(2, blksize)) for k, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] h1ao = hcore_deriv(ia) de[k] += numpy.einsum('xij,ij->x', h1ao, dm1) de[k] -= numpy.einsum('xij,ij->x', s1[:, p0:p1], dme0[p0:p1]) * 2 q1 = 0 for b0, b1, nf in _shell_prange(mol, 0, mol.nbas, blksize): q0, q1 = q1, q1 + nf dm2_ao = lib.einsum('ijw,pi,qj->pqw', dm2buf, mo_cas[p0:p1], mo_cas[q0:q1]) shls_slice = (shl0, shl1, b0, b1, 0, mol.nbas, 0, mol.nbas) eri1 = mol.intor('int2e_ip1', comp=3, aosym='s2kl', shls_slice=shls_slice).reshape( 3, p1 - p0, nf, nao_pair) de[k] -= numpy.einsum('xijw,ijw->x', eri1, dm2_ao) * 2 eri1 = None de[k] += numpy.einsum('xij,ij->x', vhf1c[:, p0:p1], dm1[p0:p1]) * 2 de[k] += numpy.einsum('xij,ij->x', vhf1a[:, p0:p1], dm_core[p0:p1]) * 2 de += rhf_grad.grad_nuc(mol, atmlst) return de
def grad_elec(mc, mf_grad): mf = mf_grad.base mol = mf_grad.mol mo_energy = mc.mo_energy mo_coeff = mc.mo_coeff ncore = mc.ncore ncas = mc.ncas nocc = ncore + ncas nelecas = mc.nelecas nao, nmo = mo_coeff.shape hcore_deriv = mf_grad.hcore_generator(mol) s1 = mf_grad.get_ovlp(mol) casdm1, casdm2 = mc.fcisolver.make_rdm12(mc.ci, ncas, nelecas) dm1 = numpy.zeros((nmo, nmo)) dm1[numpy.diag_indices(ncore)] = 2 dm1[ncore:nocc, ncore:nocc] = casdm1 dm2 = numpy.zeros((nmo, nmo, nmo, nmo)) for i in range(ncore): for j in range(ncore): dm2[i, i, j, j] += 4 dm2[i, j, j, i] -= 2 dm2[i, i, ncore:nocc, ncore:nocc] = casdm1 * 2 dm2[ncore:nocc, ncore:nocc, i, i] = casdm1 * 2 dm2[i, ncore:nocc, ncore:nocc, i] = -casdm1 dm2[ncore:nocc, i, i, ncore:nocc] = -casdm1 dm2[ncore:nocc, ncore:nocc, ncore:nocc, ncore:nocc] = casdm2 h1 = reduce(numpy.dot, (mo_coeff.T, mc._scf.get_hcore(), mo_coeff)) h2 = ao2mo.kernel(mf._eri, mo_coeff, compact=False).reshape([nmo] * 4) # Generalized Fock, according to generalized Brillouin theorm # Adv. Chem. Phys., 69, 63 gfock = numpy.dot(h1, dm1) gfock += numpy.einsum('iqrs,qjsr->ij', h2, dm2) gfock = (gfock + gfock.T) * .5 dme0 = reduce( numpy.dot, (mo_coeff[:, :nocc], gfock[:nocc, :nocc], mo_coeff[:, :nocc].T)) dm1 = reduce(numpy.dot, (mo_coeff, dm1, mo_coeff.T)) dm2 = lib.einsum('ijkl,pi,qj,rk,sl->pqrs', dm2, mo_coeff, mo_coeff, mo_coeff, mo_coeff) eri_deriv1 = mol.intor('int2e_ip1', comp=3).reshape(3, nao, nao, nao, nao) atmlst = range(mol.natm) aoslices = mol.aoslice_by_atom() de = numpy.zeros((len(atmlst), 3)) for k, ia in enumerate(atmlst): shl0, shl1, p0, p1 = aoslices[ia] h1ao = hcore_deriv(ia) de[k] += numpy.einsum('xij,ij->x', h1ao, dm1) de[k] -= numpy.einsum('xij,ij->x', s1[:, p0:p1], dme0[p0:p1]) * 2 de[k] -= numpy.einsum('xijkl,ijkl->x', eri_deriv1[:, p0:p1], dm2[p0:p1]) * 2 return de
kappa = v @ np.diag(np.log(ev)) @ np.linalg.inv(v) print(np.linalg.norm(kappa + np.conj(kappa.T))) print('imag = ', np.linalg.norm(np.imag(kappa))) print('diag = ', np.linalg.norm(np.diag(kappa))) assert np.linalg.norm(np.imag(kappa)) < 1E-12 kappa = np.real(kappa) kv, kvv = np.linalg.eig(kappa) ku = kvv @ np.diag(np.exp(kv)) @ np.linalg.inv(kvv) print(np.linalg.norm((ku @ ku.T) - np.identity(len(ku)))) mo_coeff = mo_coeff_lowdin orb_sym = [0] * n_mo na = nb = mol.nelectron // 2 h1e = mo_coeff.T @ mf.get_hcore() @ mo_coeff g2e = ao2mo.restore(1, ao2mo.kernel(mol, mo_coeff), n_mo) ecore = mol.energy_nuc() fd = FCIDUMP(pg='c1', n_sites=n_mo, n_elec=na + nb, twos=na - nb, ipg=0, uhf=False, h1e=h1e, g2e=g2e, orb_sym=orb_sym, const_e=ecore, mu=0) hamil = Hamiltonian(fd, flat=True) fd.write("H10.STO6G.R1.8.FCIDUMP.LOWDIN")
#mol.verbose = 5 #mol.output = 'out_h2o' mol.atom = [[8, (0., 0., 0.)], [1, (0., -.957, .587)], [1, (0.2, .757, .487)]] #mol.basis = 'ccpvdz' mol.basis = '631g' mol.build() mf = scf.RHF(mol) mf.conv_tol = 1e-1 mf.scf() mcc = ccsd.CCSD(mf) mcc.conv_tol = 1e-14 ecc, t1, t2 = mcc.kernel() eris = mcc.ao2mo() e3ref = ccsd_t.kernel(mcc, eris, t1, t2) l1, l2 = ccsd_t_lambda.kernel(mcc, eris, t1, t2)[1:] print(ecc, e3ref) eri_mo = ao2mo.kernel(mf._eri, mf.mo_coeff, compact=False) nmo = mf.mo_coeff.shape[1] eri_mo = eri_mo.reshape(nmo, nmo, nmo, nmo) dm1 = make_rdm1(mcc, t1, t2, l1, l2, eris=eris) dm2 = make_rdm2(mcc, t1, t2, l1, l2, eris=eris) print(lib.finger(dm1) - 1.289951975176953) print(lib.finger(dm2) - 6.6184784979411164) h1 = reduce(numpy.dot, (mf.mo_coeff.T, mf.get_hcore(), mf.mo_coeff)) e3 = (numpy.einsum('ij,ji->', h1, dm1) + numpy.einsum('ijkl,ijkl->', eri_mo, dm2) * .5 + mf.mol.energy_nuc()) print(e3ref, e3 - (mf.e_tot + ecc))
# mo_vir = cv coeff = numpy.hstack([mo_core, mo_occ, mo_vir]) nao, nmo = coeff.shape nocc = mol.nelectron // 2 occ = numpy.zeros(nmo) for i in range(nocc): occ[i] = 2.0 # mycc = cc.CCSD(mf, mo_coeff=coeff, mo_occ=occ) mycc.diis_space = 10 mycc.frozen = ncore mycc.conv_tol = 1e-6 mycc.conv_tol_normt = 1e-6 mycc.max_cycle = 150 ecc, t1, t2 = mycc.kernel() nao, nmo = coeff.shape eris = mycc.ao2mo() e3 = ccsd_t.kernel(mycc, eris, t1, t2) lib.logger.info(mycc, "* CCSD(T) energy : %12.6f" % (ehf + ecc + e3)) l1, l2 = ccsd_t_lambda.kernel(mycc, eris, t1, t2)[1:] rdm1 = ccsd_t_rdm.make_rdm1(mycc, t1, t2, l1, l2, eris=eris) rdm2 = ccsd_t_rdm.make_rdm2(mycc, t1, t2, l1, l2, eris=eris) # eri_mo = ao2mo.kernel(mf._eri, coeff[:, :nmo], compact=False) eri_mo = eri_mo.reshape(nmo, nmo, nmo, nmo) h1 = reduce(numpy.dot, (coeff[:, :nmo].T, mf.get_hcore(), coeff[:, :nmo])) ecc = (numpy.einsum('ij,ji->', h1, rdm1) + numpy.einsum('ijkl,ijkl->', eri_mo, rdm2) * .5 + mf.mol.energy_nuc()) lib.logger.info(mycc, "* Energy with 1/2-RDM : %.8f" % ecc)
def cas_natorb(mc, mo_coeff=None, ci=None, eris=None, sort=False, casdm1=None, verbose=None, with_meta_lowdin=WITH_META_LOWDIN): '''Transform active orbitals to natrual orbitals, and update the CI wfn Args: mc : a CASSCF/CASCI object or RHF object Kwargs: sort : bool Sort natural orbitals wrt the occupancy. Returns: A tuple, the first item is natural orbitals, the second is updated CI coefficients, the third is the natural occupancy associated to the natural orbitals. ''' from pyscf.lo import orth from pyscf.tools import dump_mat from pyscf.tools.mo_mapping import mo_1to1map if mo_coeff is None: mo_coeff = mc.mo_coeff if ci is None: ci = mc.ci log = logger.new_logger(mc, verbose) ncore = mc.ncore ncas = mc.ncas nocc = ncore + ncas nelecas = mc.nelecas if casdm1 is None: casdm1 = mc.fcisolver.make_rdm1(ci, ncas, nelecas) # orbital symmetry is reserved in this _eig call occ, ucas = mc._eig(-casdm1, ncore, nocc) if sort: casorb_idx = numpy.argsort(occ.round(9), kind='mergesort') occ = occ[casorb_idx] ucas = ucas[:, casorb_idx] occ = -occ mo_occ = numpy.zeros(mo_coeff.shape[1]) mo_occ[:ncore] = 2 mo_occ[ncore:nocc] = occ mo_coeff1 = mo_coeff.copy() mo_coeff1[:, ncore:nocc] = numpy.dot(mo_coeff[:, ncore:nocc], ucas) if getattr(mo_coeff, 'orbsym', None) is not None: orbsym = numpy.copy(mo_coeff.orbsym) if sort: orbsym[ncore:nocc] = orbsym[ncore:nocc][casorb_idx] mo_coeff1 = lib.tag_array(mo_coeff1, orbsym=orbsym) if isinstance(ci, numpy.ndarray): fcivec = fci.addons.transform_ci_for_orbital_rotation( ci, ncas, nelecas, ucas) elif isinstance(ci, (tuple, list)) and isinstance(ci[0], numpy.ndarray): # for state-average eigenfunctions fcivec = [ fci.addons.transform_ci_for_orbital_rotation( x, ncas, nelecas, ucas) for x in ci ] else: log.info('FCI vector not available, call CASCI for wavefunction') mocas = mo_coeff1[:, ncore:nocc] hcore = mc.get_hcore() dm_core = numpy.dot(mo_coeff1[:, :ncore] * 2, mo_coeff1[:, :ncore].T) ecore = mc.energy_nuc() ecore += numpy.einsum('ij,ji', hcore, dm_core) h1eff = reduce(numpy.dot, (mocas.T, hcore, mocas)) if getattr(eris, 'ppaa', None) is not None: ecore += eris.vhf_c[:ncore, :ncore].trace() h1eff += reduce(numpy.dot, (ucas.T, eris.vhf_c[ncore:nocc, ncore:nocc], ucas)) aaaa = ao2mo.restore(4, eris.ppaa[ncore:nocc, ncore:nocc, :, :], ncas) aaaa = ao2mo.incore.full(aaaa, ucas) else: if getattr(mc, 'with_df', None): raise NotImplementedError('cas_natorb for DFCASCI/DFCASSCF') corevhf = mc.get_veff(mc.mol, dm_core) ecore += numpy.einsum('ij,ji', dm_core, corevhf) * .5 h1eff += reduce(numpy.dot, (mocas.T, corevhf, mocas)) aaaa = ao2mo.kernel(mc.mol, mocas) # See label_symmetry_ function in casci_symm.py which initialize the # orbital symmetry information in fcisolver. This orbital symmetry # labels should be reordered to match the sorted active space orbitals. if sort and getattr(mo_coeff1, 'orbsym', None) is not None: mc.fcisolver.orbsym = mo_coeff1.orbsym[ncore:nocc] max_memory = max(400, mc.max_memory - lib.current_memory()[0]) e, fcivec = mc.fcisolver.kernel(h1eff, aaaa, ncas, nelecas, ecore=ecore, max_memory=max_memory, verbose=log) log.debug('In Natural orbital, CASCI energy = %s', e) if log.verbose >= logger.INFO: ovlp_ao = mc._scf.get_ovlp() # where_natorb gives the new locations of the natural orbitals where_natorb = mo_1to1map(ucas) log.debug('where_natorb %s', str(where_natorb)) log.info('Natural occ %s', str(occ)) if with_meta_lowdin: log.info( 'Natural orbital (expansion on meta-Lowdin AOs) in CAS space') label = mc.mol.ao_labels() orth_coeff = orth.orth_ao(mc.mol, 'meta_lowdin', s=ovlp_ao) mo_cas = reduce(numpy.dot, (orth_coeff.T, ovlp_ao, mo_coeff1[:, ncore:nocc])) else: log.info('Natural orbital (expansion on AOs) in CAS space') label = mc.mol.ao_labels() mo_cas = mo_coeff1[:, ncore:nocc] dump_mat.dump_rec(log.stdout, mo_cas, label, start=1) if mc._scf.mo_coeff is not None: s = reduce(numpy.dot, (mo_coeff1[:, ncore:nocc].T, mc._scf.get_ovlp(), mc._scf.mo_coeff)) idx = numpy.argwhere(abs(s) > .4) for i, j in idx: log.info('<CAS-nat-orb|mo-hf> %d %d %12.8f', ncore + i + 1, j + 1, s[i, j]) return mo_coeff1, fcivec, mo_occ
def writeFCIDUMP(mol, mf, lmo): h1 = lmo.T.dot(mf.get_hcore()).dot(lmo) eri = ao2mo.kernel(mol, lmo) tools.fcidump.from_integrals('FCIDUMP', h1, eri, mol.nao, mol.nelectron, mf.energy_nuc())