def CISD(mf, frozen=0, mo_coeff=None, mo_occ=None): from pyscf import lib from pyscf import scf if isinstance(mf, scf.uhf.UHF): return ucisd.UCISD(mf, frozen, mo_coeff, mo_occ) elif isinstance(mf, scf.rohf.ROHF): lib.logger.warn( mf, 'RCISD method does not support ROHF method. ROHF object ' 'is converted to UHF object and UCISD method is called.') mf = scf.addons.convert_to_uhf(mf) return ucisd.UCISD(mf, frozen, mo_coeff, mo_occ) else: return cisd.CISD(mf, frozen, mo_coeff, mo_occ)
def test_frozen(self): myci = ucisd.UCISD(mf) myci.frozen = [0, 1, 10, 11, 12] myci.max_memory = 1 myci.kernel() g1 = ucisd_grad.kernel(myci, myci.ci, mf_grad=grad.UHF(mf)) self.assertAlmostEqual(lib.finger(g1), -0.23578589551312196, 6)
def test_cisd_grad(self): myci = ucisd.UCISD(mf) myci.max_memory = 1 myci.conv_tol = 1e-10 myci.kernel() g1 = ucisd_grad.kernel(myci, myci.ci, mf_grad=grad.UHF(mf)) self.assertAlmostEqual(lib.finger(g1), -0.22651925227633429, 6)
def test_frozen(self): myci = ucisd.UCISD(mf) myci.frozen = [0, 1, 10, 11, 12] myci.max_memory = 1 myci.kernel() g1 = myci.Gradients().kernel(myci.ci) self.assertAlmostEqual(lib.finger(g1), -0.23578589551312196, 6)
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 UCISD(mf, frozen=None, mo_coeff=None, mo_occ=None): from pyscf.soscf import newton_ah if isinstance(mf, newton_ah._CIAH_SOSCF) or not isinstance(mf, scf.uhf.UHF): mf = scf.addons.convert_to_uhf(mf) if getattr(mf, 'with_df', None): raise NotImplementedError('DF-UCISD') else: return ucisd.UCISD(mf, frozen, mo_coeff, mo_occ)
ucisd.UCISD.Gradients = lib.class_as_method(Gradients) if __name__ == '__main__': from pyscf import gto from pyscf import scf from pyscf import ao2mo mol = gto.M( atom=[["O", (0., 0., 0.)], [1, (0., -0.757, 0.587)], [1, (0., 0.757, 0.587)]], basis='631g', spin=2, ) mf = scf.UHF(mol).run() myci = ucisd.UCISD(mf).run() g1 = myci.Gradients().kernel() # O 0.0000000000 -0.0000000000 0.1456473095 # H -0.0000000000 0.1107223084 -0.0728236548 # H 0.0000000000 -0.1107223084 -0.0728236548 print(lib.finger(g1) - -0.22651886837710072) print('-----------------------------------') mol = gto.M( atom=[["O", (0., 0., 0.)], [1, (0., -0.757, 0.587)], [1, (0., 0.757, 0.587)]], basis='631g', spin=2, ) mf = scf.UHF(mol).run() myci = ucisd.UCISD(mf)
def test_rdm_vs_ucisd(self): mol = gto.Mole() mol.atom = [ [8 , (0. , 0. , 0.)], [1 , (0. , -0.757 , 0.587)], [1 , (0. , 0.757 , 0.587)]] mol.verbose = 5 mol.output = '/dev/null' mol.basis = '631g' mol.spin = 2 mol.build() mf = scf.UHF(mol).run() myuci = ucisd.UCISD(mf) myuci.frozen = 1 myuci.kernel() udm1 = myuci.make_rdm1() udm2 = myuci.make_rdm2() mf = scf.addons.convert_to_ghf(mf) mygci = gcisd.GCISD(mf) mygci.frozen = 2 mygci.kernel() dm1 = mygci.make_rdm1() dm2 = mygci.make_rdm2() nao = mol.nao_nr() mo_a = mf.mo_coeff[:nao] mo_b = mf.mo_coeff[nao:] nmo = mo_a.shape[1] eri = ao2mo.kernel(mf._eri, mo_a+mo_b, compact=False).reshape([nmo]*4) orbspin = mf.mo_coeff.orbspin sym_forbid = (orbspin[:,None] != orbspin) eri[sym_forbid,:,:] = 0 eri[:,:,sym_forbid] = 0 hcore = scf.RHF(mol).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, mygci.e_tot, 7) idxa = numpy.where(orbspin == 0)[0] idxb = numpy.where(orbspin == 1)[0] self.assertAlmostEqual(abs(dm1[idxa[:,None],idxa] - udm1[0]).max(), 0, 5) self.assertAlmostEqual(abs(dm1[idxb[:,None],idxb] - udm1[1]).max(), 0, 5) self.assertAlmostEqual(abs(dm2[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] - udm2[0]).max(), 0, 5) self.assertAlmostEqual(abs(dm2[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] - udm2[1]).max(), 0, 5) self.assertAlmostEqual(abs(dm2[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] - udm2[2]).max(), 0, 5) c0, c1, c2 = myuci.cisdvec_to_amplitudes(myuci.ci) ut1 = [0] * 2 ut2 = [0] * 3 ut0 = c0 + .2j ut1[0] = c1[0] + numpy.cos(c1[0]) * .2j ut1[1] = c1[1] + numpy.cos(c1[1]) * .2j ut2[0] = c2[0] + numpy.sin(c2[0]) * .8j ut2[1] = c2[1] + numpy.sin(c2[1]) * .8j ut2[2] = c2[2] + numpy.sin(c2[2]) * .8j civec = myuci.amplitudes_to_cisdvec(ut0, ut1, ut2) udm1 = myuci.make_rdm1(civec) udm2 = myuci.make_rdm2(civec) gt1 = mygci.spatial2spin(ut1) gt2 = mygci.spatial2spin(ut2) civec = mygci.amplitudes_to_cisdvec(ut0, gt1, gt2) gdm1 = mygci.make_rdm1(civec) gdm2 = mygci.make_rdm2(civec) self.assertAlmostEqual(abs(gdm1[idxa[:,None],idxa] - udm1[0]).max(), 0, 9) self.assertAlmostEqual(abs(gdm1[idxb[:,None],idxb] - udm1[1]).max(), 0, 9) self.assertAlmostEqual(abs(gdm2[idxa[:,None,None,None],idxa[:,None,None],idxa[:,None],idxa] - udm2[0]).max(), 0, 9) self.assertAlmostEqual(abs(gdm2[idxa[:,None,None,None],idxa[:,None,None],idxb[:,None],idxb] - udm2[1]).max(), 0, 9) self.assertAlmostEqual(abs(gdm2[idxb[:,None,None,None],idxb[:,None,None],idxb[:,None],idxb] - udm2[2]).max(), 0, 9)