def test_vmc(): """ Test that a VMC calculation of a Slater determinant matches Hartree-Fock within error bars. """ nconf = 5000 mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5", basis="cc-pvtz", unit="bohr", verbose=1) mf_rhf = scf.RHF(mol).run() mf_uhf = scf.UHF(mol).run() nsteps = 100 warmup = 30 for wf, mf in [ (PySCFSlaterUHF(mol, mf_rhf), mf_rhf), (PySCFSlaterUHF(mol, mf_uhf), mf_uhf), ]: coords = initial_guess(mol, nconf) df, coords = vmc(wf, coords, nsteps=nsteps, accumulators={"energy": EnergyAccumulator(mol)}) df = pd.DataFrame(df) df = reblock(df["energytotal"][warmup:], 20) en = df.mean() err = df.sem() assert en - mf.energy_tot( ) < 5 * err, "pyscf {0}, vmc {1}, err {2}".format( en, mf.energy_tot(), err)
def runtest(mol, mf, kind=0, do_mc=False): if do_mc: from pyscf import mcscf mc = mcscf.CASCI(mf, ncas=4, nelecas=(1, 1)) mc.kernel() wf = pyqmc.default_msj(mol, mf, mc)[0] kpt = mf.kpt dm = mc.make_rdm1() if len(dm.shape) == 4: dm = np.sum(dm, axis=0) else: kpt = mf.kpts[kind] wf = pyqmc.Slater(mol, mf) dm = mf.make_rdm1() print("original dm shape", dm.shape) if len(dm.shape) == 4: dm = np.sum(dm, axis=0) dm = dm[kind] ##################################### ## evaluate KE in PySCF ##################################### ke_mat = mol.pbc_intor("int1e_kin", hermi=1, kpts=np.array(kpt)) print("ke_mat", ke_mat.shape) print("dm", dm.shape) pyscfke = np.real(np.einsum("ij,ji->", ke_mat, dm)) print("PySCF kinetic energy: {0}".format(pyscfke)) ##################################### ## evaluate KE integral with VMC ##################################### coords = pyqmc.initial_guess(mol, 1200, 0.7) warmup = 10 start = time.time() df, coords = pyqmc.vmc( wf, coords, nsteps=100 + warmup, tstep=1, accumulators={"energy": pyqmc.accumulators.EnergyAccumulator(mol)}, verbose=False, hdf_file=str(uuid.uuid4()), ) print("VMC time", time.time() - start) df = pd.DataFrame(df) dfke = reblock(df["energyke"][warmup:], 10) dfke /= mol.scale vmcke, err = dfke.mean(), dfke.sem() print("VMC kinetic energy: {0} +- {1}".format(vmcke, err)) assert ( np.abs(vmcke - pyscfke) < 5 * err ), "energy diff not within 5 sigma ({0:.6f}): energies \n{1} \n{2}".format( 5 * err, vmcke, pyscfke)
def runtest(mol, mf, kind): kpt = mf.kpts[kind] wf = pyqmc.PySCFSlaterUHF(mol, mf, twist=np.dot(kpt, mol.a.T / np.pi)) ##################################### ## evaluate KE in PySCF ##################################### ke_mat = mol.pbc_intor('int1e_kin', hermi=1, kpts=np.array(kpt)) dm = mf.make_rdm1() if len(dm.shape) == 4: dm = np.sum(dm, axis=0) pyscfke = np.real(np.einsum('ij,ji->', ke_mat, dm[kind])) print('PySCF kinetic energy: {0}'.format(pyscfke)) ##################################### ## evaluate KE integral with VMC ##################################### coords = pyqmc.initial_guess(mol, 1200, .7) warmup = 10 start = time.time() df, coords = pyqmc.vmc( wf, coords, nsteps=32 + warmup, tstep=1, accumulators={"energy": pyqmc.accumulators.EnergyAccumulator(mol)}, verbose=False, ) print("VMC time", time.time() - start) df = pd.DataFrame(df) dfke = reblock(df["energyke"][warmup:], 8) vmcke, err = dfke.mean(), dfke.sem() print('VMC kinetic energy: {0} +- {1}'.format(vmcke, err)) assert np.abs(vmcke-pyscfke) < 5 * err, \ "energy diff not within 5 sigma ({0:.6f}): energies \n{1} \n{2}".format(5 * err, vmcke, pyscfke)
def test(): """ Tests that the multi-slater wave function value, gradient and parameter gradient evaluations are working correctly. Also checks that VMC energy matches energy calculated in PySCF """ mol = gto.M(atom="Li 0. 0. 0.; H 0. 0. 1.5", basis="cc-pvtz", unit="bohr", spin=0) epsilon = 1e-4 delta = 1e-5 nsteps = 200 warmup = 10 for mf in [scf.RHF(mol).run(), scf.ROHF(mol).run(), scf.UHF(mol).run()]: # Test same number of elecs mc = mcscf.CASCI(mf, ncas=4, nelecas=(1, 1)) mc.kernel() wf = MultiSlater(mol, mf, mc) nconf = 10 nelec = np.sum(mol.nelec) epos = initial_guess(mol, nconf) for k, item in testwf.test_updateinternals(wf, epos).items(): assert item < epsilon assert testwf.test_wf_gradient(wf, epos, delta=delta)[0] < epsilon assert testwf.test_wf_laplacian(wf, epos, delta=delta)[0] < epsilon assert testwf.test_wf_pgradient(wf, epos, delta=delta)[0] < epsilon # Test same number of elecs mc = mcscf.CASCI(mf, ncas=4, nelecas=(1, 1)) mc.kernel() wf = pyqmc.default_msj(mol, mf, mc)[0] nelec = np.sum(mol.nelec) epos = initial_guess(mol, nconf) for k, item in testwf.test_updateinternals(wf, epos).items(): assert item < epsilon assert testwf.test_wf_gradient(wf, epos, delta=delta)[0] < epsilon assert testwf.test_wf_laplacian(wf, epos, delta=delta)[0] < epsilon assert testwf.test_wf_pgradient(wf, epos, delta=delta)[0] < epsilon # Test different number of elecs mc = mcscf.CASCI(mf, ncas=4, nelecas=(2, 0)) mc.kernel() wf = MultiSlater(mol, mf, mc) nelec = np.sum(mol.nelec) epos = initial_guess(mol, nconf) for k, item in testwf.test_updateinternals(wf, epos).items(): assert item < epsilon assert testwf.test_wf_gradient(wf, epos, delta=delta)[0] < epsilon assert testwf.test_wf_laplacian(wf, epos, delta=delta)[0] < epsilon assert testwf.test_wf_pgradient(wf, epos, delta=delta)[0] < epsilon # Quick VMC test nconf = 1000 coords = initial_guess(mol, nconf) df, coords = vmc(wf, coords, nsteps=nsteps, accumulators={"energy": EnergyAccumulator(mol)}) df = pd.DataFrame(df) df = reblock(df["energytotal"][warmup:], 20) en = df.mean() err = df.sem() assert en - mc.e_tot < 5 * err