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) en = np.mean(df["energytotal"][warmup:]) err = np.std(df["energytotal"][warmup:]) / np.sqrt(nsteps - warmup) assert en - mf.energy_tot() < 10 * err
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 test_wfs(): """ Ensure that the wave function objects are consistent in several situations. """ from pyscf import lib, gto, scf from pyqmc.slateruhf import PySCFSlaterUHF from pyqmc.jastrowspin import JastrowSpin from pyqmc.multiplywf import MultiplyWF mol = gto.M(atom='Li 0. 0. 0.; H 0. 0. 1.5', basis='cc-pvtz', unit='bohr') mf = scf.RHF(mol).run() mf_rohf = scf.ROHF(mol).run() mf_uhf = scf.UHF(mol).run() epsilon = 1e-5 nconf = 10 epos = np.random.randn(nconf, 4, 3) for wf in [ JastrowSpin(mol), MultiplyWF(PySCFSlaterUHF(mol, mf), JastrowSpin(mol)), PySCFSlaterUHF(mol, mf_uhf), PySCFSlaterUHF(mol, mf), PySCFSlaterUHF(mol, mf_rohf) ]: for k in wf.parameters: wf.parameters[k] = np.random.rand(*wf.parameters[k].shape) assert testwf.test_wf_gradient(wf, epos, delta=1e-5)[0] < epsilon assert testwf.test_wf_laplacian(wf, epos, delta=1e-5)[0] < epsilon assert testwf.test_wf_pgradient(wf, epos, delta=1e-5)[0] < epsilon for k, item in testwf.test_updateinternals(wf, epos).items(): assert item < epsilon
def test_accumulator(): """ Tests that the accumulator gets inserted into the data output correctly. """ import pandas as pd from pyqmc.mc import vmc, initial_guess from pyscf import gto, scf from pyqmc.energy import energy from pyqmc.slateruhf import PySCFSlaterUHF from pyqmc.accumulators import EnergyAccumulator mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5", basis="cc-pvtz", unit="bohr", verbose=5) mf = scf.RHF(mol).run() nconf = 5000 wf = PySCFSlaterUHF(mol, mf) coords = initial_guess(mol, nconf) df, coords = vmc(wf, coords, nsteps=30, accumulators={"energy": EnergyAccumulator(mol)}) df = pd.DataFrame(df) eaccum = EnergyAccumulator(mol) eaccum_energy = eaccum(coords, wf) df = pd.DataFrame(df) print(df["energytotal"][29] == np.average(eaccum_energy["total"])) assert df["energytotal"][29] == np.average(eaccum_energy["total"])
def test_wfs(): """ Ensure that the wave function objects are consistent in several situations. """ from pyscf import lib, gto, scf from pyqmc.slateruhf import PySCFSlaterUHF from pyqmc.jastrowspin import JastrowSpin from pyqmc.multiplywf import MultiplyWF from pyqmc.coord import OpenConfigs import pyqmc mol = gto.M(atom="Li 0. 0. 0.; H 0. 0. 1.5", basis="cc-pvtz", unit="bohr") mf = scf.RHF(mol).run() mf_rohf = scf.ROHF(mol).run() mf_uhf = scf.UHF(mol).run() epsilon = 1e-5 nconf = 10 epos = pyqmc.initial_guess(mol, nconf) for wf in [ JastrowSpin(mol), MultiplyWF(PySCFSlaterUHF(mol, mf), JastrowSpin(mol)), PySCFSlaterUHF(mol, mf_uhf), PySCFSlaterUHF(mol, mf), PySCFSlaterUHF(mol, mf_rohf), ]: for k in wf.parameters: if k != "mo_coeff": wf.parameters[k] = np.random.rand(*wf.parameters[k].shape) for fname, func in zip( ["gradient", "laplacian", "pgradient"], [ testwf.test_wf_gradient, testwf.test_wf_laplacian, testwf.test_wf_pgradient, ], ): err = [] for delta in [1e-4, 1e-5, 1e-6, 1e-7, 1e-8]: err.append(func(wf, epos, delta)[0]) print(fname, min(err)) assert min(err) < epsilon for k, item in testwf.test_updateinternals(wf, epos).items(): print(k, item) assert item < epsilon
def genconfigs(n): """ Generate configurations and weights corresponding to the highest determinant in MD expansion """ import os os.system('mkdir -p vmc/') mol, mf, mc, wf, to_opt, freeze = wavefunction(return_mf=True) #Sample from the wave function which we're taking pderiv relative to mf.mo_coeff = mc.mo_coeff mf.mo_occ *= 0 mf.mo_occ[wf.wf1._det_occup[0][-1]] = 2 wfp = PySCFSlaterUHF(mol, mf) #Lots of configurations coords = pyqmc.initial_guess(mol, 100000) eacc = EnergyAccumulator(mol) transform = LinearTransform(wf.parameters, to_opt, freeze) pgrad_bare = PGradTransform(eacc, transform, 0) #Lots of steps warmup = 10 for i in range(n + warmup + 1): df, coords = vmc(wfp, coords, nsteps=1) print(i) if (i > warmup): coords.configs.dump('vmc/coords' + str(i - warmup) + '.pickle') val = wf.recompute(coords) valp = wfp.value() d = pgrad_bare(coords, wf) data = { 'dpH': np.array(d['dpH'])[:, -1], 'dppsi': np.array(d['dppsi'])[:, -1], 'en': np.array(d['total']), "wfval": val[1], "wfpval": valp[1] } pd.DataFrame(data).to_json('vmc/evals' + str(i - warmup) + '.json') return -1
def test(): """ Ensure that DMC obtains the exact result for a hydrogen atom """ from pyscf import lib, gto, scf from pyqmc.slateruhf import PySCFSlaterUHF from pyqmc.jastrowspin import JastrowSpin from pyqmc.dmc import limdrift, dmc from pyqmc.mc import vmc from pyqmc.accumulators import EnergyAccumulator from pyqmc.func3d import ExpCuspFunction from pyqmc.multiplywf import MultiplyWF import pandas as pd mol = gto.M(atom='H 0. 0. 0.', basis='sto-3g', unit='bohr', spin=1) mf = scf.UHF(mol).run() nconf = 1000 configs = np.random.randn(nconf, 1, 3) wf1 = PySCFSlaterUHF(mol, mf) wf = wf1 wf2 = JastrowSpin(mol, a_basis=[ExpCuspFunction(5, .2)], b_basis=[]) wf2.parameters['acoeff'] = np.asarray([[-1.0, 0]]) wf = MultiplyWF(wf1, wf2) dfvmc, configs_ = vmc(wf, configs, nsteps=50, accumulators={'energy': EnergyAccumulator(mol)}) dfvmc = pd.DataFrame(dfvmc) print('vmc energy', np.mean(dfvmc['energytotal']), np.std(dfvmc['energytotal']) / np.sqrt(len(dfvmc))) dfdmc, configs_, weights_ = dmc( wf, configs, nsteps=5000, branchtime=5, accumulators={'energy': EnergyAccumulator(mol)}, ekey=('energy', 'total'), tstep=0.01, drift_limiter=limdrift, verbose=True) dfdmc = pd.DataFrame(dfdmc) dfdmc.sort_values('step', inplace=True) warmup = 200 dfprod = dfdmc[dfdmc.step > warmup] reblock = pyblock.reblock(dfprod[['energytotal', 'energyei']]) print(reblock[1]) dfoptimal = reblock[1][reblock[1][('energytotal', 'optimal block')] != ''] energy = dfoptimal[('energytotal', 'mean')].values[0] err = dfoptimal[('energytotal', 'standard error')].values[0] print("energy", energy, "+/-", err) assert np.abs( energy + 0.5) < 5 * err, "energy not within {0} of -0.5: energy {1}".format( 5 * err, np.mean(energy))
def test(): """ Ensure that DMC obtains the exact result for a hydrogen atom """ from pyscf import lib, gto, scf from pyqmc.slateruhf import PySCFSlaterUHF from pyqmc.jastrowspin import JastrowSpin from pyqmc.dmc import limdrift, rundmc from pyqmc.mc import vmc from pyqmc.accumulators import EnergyAccumulator from pyqmc.func3d import CutoffCuspFunction from pyqmc.multiplywf import MultiplyWF from pyqmc.coord import OpenConfigs import pandas as pd mol = gto.M(atom="H 0. 0. 0.", basis="sto-3g", unit="bohr", spin=1) mf = scf.UHF(mol).run() nconf = 1000 configs = OpenConfigs(np.random.randn(nconf, 1, 3)) wf1 = PySCFSlaterUHF(mol, mf) wf = wf1 wf2 = JastrowSpin(mol, a_basis=[CutoffCuspFunction(5, 0.2)], b_basis=[]) wf2.parameters["acoeff"] = np.asarray([[[1.0, 0]]]) wf = MultiplyWF(wf1, wf2) dfvmc, configs_ = vmc( wf, configs, nsteps=50, accumulators={"energy": EnergyAccumulator(mol)} ) dfvmc = pd.DataFrame(dfvmc) print( "vmc energy", np.mean(dfvmc["energytotal"]), np.std(dfvmc["energytotal"]) / np.sqrt(len(dfvmc)), ) warmup = 200 dfdmc, configs_, weights_ = rundmc( wf, configs, nsteps=4000 + warmup, branchtime=5, accumulators={"energy": EnergyAccumulator(mol)}, ekey=("energy", "total"), tstep=0.005, drift_limiter=limdrift, verbose=False, ) dfdmc = pd.DataFrame(dfdmc) dfdmc.sort_values("step", inplace=True) dfprod = dfdmc[dfdmc.step >= warmup] rb_summary = reblock.reblock_summary(dfprod[["energytotal", "energyei"]], 20) print(rb_summary) energy, err = [rb_summary[v]["energytotal"] for v in ("mean", "standard error")] assert ( np.abs(energy + 0.5) < 5 * err ), "energy not within {0} of -0.5: energy {1}".format(5 * err, np.mean(energy))
def test_ecp(): mol = gto.M( atom="""C 0 0 0 C 1 0 0 """, ecp="bfd", basis="bfd_vtz", ) mf = scf.RHF(mol).run() nconf = 1000 coords = initial_guess(mol, nconf) thresholds = [1e15, 100, 50, 20, 10, 5, 1] label = ["S", "J", "SJ"] ind = 0 for wf in [ PySCFSlaterUHF(mol, mf), JastrowSpin(mol), MultiplyWF(PySCFSlaterUHF(mol, mf), JastrowSpin(mol)), ]: wf.recompute(coords) print(label[ind]) ind += 1 for threshold in thresholds: eacc = EnergyAccumulator(mol, threshold) start = time.time() eacc(coords, wf) end = time.time() print("Threshold=", threshold, np.around(end - start, 2), "s") mc = mcscf.CASCI(mf, ncas=4, nelecas=(2, 2)) mc.kernel() label = ["MS"] ind = 0 for wf in [MultiSlater(mol, mf, mc)]: wf.recompute(coords) print(label[ind]) ind += 1 for threshold in thresholds: eacc = EnergyAccumulator(mol, threshold) start = time.time() eacc(coords, wf) end = time.time() print("Threshold=", threshold, np.around(end - start, 2), "s")
def test_ecp(): mol = gto.M(atom='C 0. 0. 0.', ecp='bfd', basis='bfd_vtz') mf = scf.RHF(mol).run() nconf=5000 wf=PySCFSlaterUHF(mol,mf) coords = initial_guess(mol,nconf) df,coords=vmc(wf,coords,nsteps=100,accumulators={'energy':EnergyAccumulator(mol)} ) df=pd.DataFrame(df) warmup=30 print('mean field',mf.energy_tot(),'vmc estimation', np.mean(df['energytotal'][warmup:]),np.std(df['energytotal'][warmup:])) assert abs(mf.energy_tot()-np.mean(df['energytotal'][warmup:])) <= np.std(df['energytotal'][warmup:])
def default_slater(mol, mf, optimize_orbitals = False): import numpy as np wf = PySCFSlaterUHF(mol, mf) if optimize_orbitals: to_opt = ['mo_coeff_alpha', 'mo_coeff_beta'] freeze = {} for k in ['mo_coeff_alpha', 'mo_coeff_beta']: freeze[k] = np.zeros(wf.parameters[k].shape).astype(bool) maxval = np.argmax(np.abs(wf.parameters[k])) freeze[k][maxval] = True else: to_opt = [] freeze = {} return wf, to_opt, freeze
def slater_jastrow(mol, mf, abasis=None, bbasis=None): if abasis is None: abasis = [GaussianFunction(0.8), GaussianFunction(1.6), GaussianFunction(3.2)] if bbasis is None: bbasis = [ CutoffCuspFunction(2.0, 1.5), GaussianFunction(0.8), GaussianFunction(1.6), GaussianFunction(3.2), ] wf = MultiplyWF( PySCFSlaterUHF(mol, mf), JastrowSpin(mol, a_basis=abasis, b_basis=bbasis) ) return wf
def test_ecp(): mol = gto.M(atom="C 0. 0. 0.", ecp="bfd", basis="bfd_vtz") mf = scf.RHF(mol).run() nconf = 5000 wf = PySCFSlaterUHF(mol, mf) coords = initial_guess(mol, nconf) df, coords = vmc(wf, coords, nsteps=100, accumulators={"energy": EnergyAccumulator(mol)}) df = pd.DataFrame(df) warmup = 30 print( "mean field", mf.energy_tot(), "vmc estimation", np.mean(df["energytotal"][warmup:]), np.std(df["energytotal"][warmup:]), ) assert abs(mf.energy_tot() - np.mean(df["energytotal"][warmup:])) <= np.std( df["energytotal"][warmup:])
return d if __name__ == "__main__": from pyscf import lib, gto, scf import pyqmc from pyqmc.slateruhf import PySCFSlaterUHF # from pyqmc.jastrow import Jastrow2B from pyqmc.coord import OpenConfigs import time import pandas as pd mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5", basis="cc-pvtz", unit="bohr") mf = scf.UHF(mol).run() wf = PySCFSlaterUHF(mol, mf) # wf=Jastrow2B(10,mol) df = [] for i in range(5): configs = OpenConfigs(np.random.randn(18000, np.sum(mol.nelec), 3)) res = test_wf_gradient_laplacian(wf, configs) for d in res: d.update({"step": i}) df.extend(res) print("testing gradient: errors\n", pd.DataFrame(df)) quit() for i in range(5): configs = OpenConfigs(np.random.randn(10, np.sum(mol.nelec), 3)) print("testing gradient: errors", test_wf_gradient(wf, configs, delta=1e-5))