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(): """ Ensure that DMC obtains the exact result for a hydrogen atom """ from pyscf import lib, gto, scf from pyqmc.slater import PySCFSlater 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 = PySCFSlater(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 branchtime = 5 dfdmc, configs_, weights_ = rundmc( wf, configs, nsteps=4000 + warmup * branchtime, branchtime=branchtime, 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) 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(): """ 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 make_supercell_jastrow(jastrow, S): from pyqmc.jastrowspin import JastrowSpin scale = int(np.round(np.linalg.det(S))) supercell = get_supercell(jastrow._mol, S) newjast = JastrowSpin(supercell, jastrow.a_basis, jastrow.b_basis) newjast.parameters["bcoeff"] = jastrow.parameters["bcoeff"] newjast.parameters["acoeff"] = np.repeat(jastrow.parameters["acoeff"], scale, axis=0) return newjast
def test_wfs(): """ Ensure that the wave function objects are consistent in several situations. """ from pyscf import lib, gto, scf from pyqmc.slater import PySCFSlater from pyqmc.jastrowspin import JastrowSpin from pyqmc.multiplywf import MultiplyWF from pyqmc.manybody_jastrow import J3 import pyqmc mol = gto.M(atom="Li 0. 0. 0.; H 0. 0. 1.5", basis="sto-3g", 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), J3(mol), MultiplyWF(PySCFSlater(mol, mf), JastrowSpin(mol)), MultiplyWF(PySCFSlater(mol, mf), JastrowSpin(mol), J3(mol)), PySCFSlater(mol, mf_uhf), PySCFSlater(mol, mf), PySCFSlater(mol, mf_rohf), ]: for k in wf.parameters: if k != "mo_coeff": wf.parameters[k] = np.random.rand(*wf.parameters[k].shape) for k, item in testwf.test_updateinternals(wf, epos).items(): print(k, item) assert item < epsilon testwf.test_mask(wf, 0, epos) _, epos = pyqmc.vmc(wf, epos, nblocks=1, nsteps=2, tstep=1) # move off node 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(type(wf), fname, min(err)) assert min(err) < epsilon, "epsilon {0}".format(epsilon)
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 default_jastrow(mol, ion_cusp=False, rcut = 7.5): """ Default 2-body jastrow from qwalk, Args: ion_cusp (bool): add an extra term to satisfy electron-ion cusp. Returns: jastrow, to_opt and freeze """ import numpy as np def expand_beta_qwalk(beta0, n): """polypade expansion coefficients for n basis functions with first coeff beta0""" beta = np.zeros(n) beta[0] = beta0 beta1 = np.log(beta0 + 1.00001) for i in range(1, n): beta[i] = np.exp(beta1 + 1.6 * i) - 1 return beta beta_abasis = expand_beta_qwalk(0.2, 4) beta_bbasis = expand_beta_qwalk(0.5, 3) if ion_cusp: abasis = [CutoffCuspFunction(gamma=24, rcut=rcut)] else: abasis = [] abasis += [PolyPadeFunction(beta=beta_abasis[i], rcut=rcut) for i in range(4)] bbasis = [CutoffCuspFunction(gamma=24, rcut=rcut)] bbasis += [PolyPadeFunction(beta=beta_bbasis[i], rcut=rcut) for i in range(3)] jastrow = JastrowSpin(mol, a_basis=abasis, b_basis=bbasis) if ion_cusp: jastrow.parameters["acoeff"][:, 0, :] = mol.atom_charges()[:, None] jastrow.parameters["bcoeff"][0, [0, 1, 2]] = np.array([-0.25, -0.50, -0.25]) freeze = {} freeze["acoeff"] = np.zeros(jastrow.parameters["acoeff"].shape).astype(bool) if ion_cusp: freeze["acoeff"][:, 0, :] = True # Cusp conditions freeze["bcoeff"] = np.zeros(jastrow.parameters["bcoeff"].shape).astype(bool) freeze["bcoeff"][0, [0, 1, 2]] = True # Cusp conditions to_opt = ["acoeff", "bcoeff"] return jastrow, to_opt, freeze
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 default_jastrow(mol): """ Default 2-body jastrow from qwalk, returns jastrow, to_opt and freeze """ import numpy as np def expand_beta_qwalk(beta0, n): """polypade expansion coefficients for n basis functions with first coeff beta0""" beta = np.zeros(n) beta[0] = beta0 beta1 = np.log(beta0 + 1.00001) for i in range(1, n): beta[i] = np.exp(beta1 + 1.6 * i) - 1 return beta beta_abasis = expand_beta_qwalk(0.2, 4) beta_bbasis = expand_beta_qwalk(0.5, 3) abasis = [ PolyPadeFunction(beta=beta_abasis[i], rcut=7.5) for i in range(4) ] bbasis = [CutoffCuspFunction(gamma=24, rcut=7.5)] bbasis += [ PolyPadeFunction(beta=beta_bbasis[i], rcut=7.5) for i in range(3) ] jastrow = JastrowSpin(mol, a_basis=abasis, b_basis=bbasis) jastrow.parameters["bcoeff"][0, [0, 1, 2]] = np.array([-0.25, -0.50, -0.25]) freeze = {} freeze["acoeff"] = np.zeros( jastrow.parameters["acoeff"].shape).astype(bool) freeze["bcoeff"] = np.zeros( jastrow.parameters["bcoeff"].shape).astype(bool) freeze["bcoeff"][0, [0, 1, 2]] = True # Cusp conditions to_opt = ["acoeff", "bcoeff"] return jastrow, to_opt, freeze
def default_jastrow(mol, ion_cusp=None, na=4, nb=3, rcut=None): """ Default 2-body jastrow from qwalk, Args: ion_cusp (bool): add an extra term to satisfy electron-ion cusp. Returns: jastrow, to_opt """ if ion_cusp == False: ion_cusp = [] if not mol.has_ecp(): print("Warning: using neither ECP nor ion_cusp") elif ion_cusp == True: ion_cusp = list(mol._basis.keys()) if mol.has_ecp(): print("Warning: using both ECP and ion_cusp") elif ion_cusp is None: ion_cusp = [l for l in mol._basis.keys() if l not in mol._ecp.keys()] else: assert isinstance(ion_cusp, list) abasis, bbasis = default_jastrow_basis(mol, len(ion_cusp) > 0, na, nb, rcut) jastrow = JastrowSpin(mol, a_basis=abasis, b_basis=bbasis) if len(ion_cusp) > 0: coefs = mol.atom_charges().copy() coefs[[l[0] not in ion_cusp for l in mol._atom]] = 0.0 jastrow.parameters["acoeff"][:, 0, :] = coefs[:, None] jastrow.parameters["bcoeff"][0, [0, 1, 2]] = np.array([-0.25, -0.50, -0.25]) to_opt = {} to_opt["acoeff"] = np.ones(jastrow.parameters["acoeff"].shape).astype(bool) if len(ion_cusp) > 0: to_opt["acoeff"][:, 0, :] = False # Cusp conditions to_opt["bcoeff"] = np.ones(jastrow.parameters["bcoeff"].shape).astype(bool) to_opt["bcoeff"][0, [0, 1, 2]] = False # Cusp conditions return jastrow, to_opt
def test_pbc_wfs(): """ Ensure that the wave function objects are consistent in several situations. """ from pyscf.pbc import lib, gto, scf from pyqmc.slaterpbc import PySCFSlaterPBC, get_supercell from pyqmc.jastrowspin import JastrowSpin from pyqmc.multiplywf import MultiplyWF from pyqmc.coord import OpenConfigs import pyqmc mol = gto.M(atom="H 0. 0. 0.; H 1. 1. 1.", basis="sto-3g", unit="bohr", a=np.eye(3) * 4) mf = scf.KRKS(mol).run() # mf_rohf = scf.KROKS(mol).run() # mf_uhf = scf.KUKS(mol).run() epsilon = 1e-5 nconf = 10 supercell = get_supercell(mol, S=np.eye(3)) epos = pyqmc.initial_guess(supercell, nconf) for wf in [ MultiplyWF(PySCFSlaterPBC(supercell, mf), JastrowSpin(mol)), PySCFSlaterPBC(supercell, mf), # PySCFSlaterPBC(supercell, mf_uhf), # PySCFSlaterPBC(supercell, 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 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_pbc_wfs(): """ Ensure that the wave function objects are consistent in several situations. """ from pyscf.pbc import lib, gto, scf from pyqmc.supercell import get_supercell from pyqmc.slater import PySCFSlater from pyqmc.multislaterpbc import MultiSlaterPBC from pyqmc.jastrowspin import JastrowSpin from pyqmc.multiplywf import MultiplyWF import pyqmc mol = gto.M( atom="H 0. 0. 0.; H 1. 1. 1.", basis="sto-3g", unit="bohr", a=(np.ones((3, 3)) - np.eye(3)) * 4, ) mf = scf.KRKS(mol, mol.make_kpts((2, 2, 2))).run() # mf_rohf = scf.KROKS(mol).run() # mf_uhf = scf.KUKS(mol).run() epsilon = 1e-5 nconf = 10 supercell = get_supercell(mol, S=(np.ones((3, 3)) - 2 * np.eye(3))) epos = pyqmc.initial_guess(supercell, nconf) # For multislaterpbc kinds = 0, 3, 5, 6 # G, X, Y, Z d1 = {kind: [0] for kind in kinds} d2 = d1.copy() d2.update({0: [], 3: [0, 1]}) detwt = [2**0.5, 2**0.5] occup = [[d1, d2], [d1]] map_dets = [[0, 1], [0, 0]] for wf in [ MultiplyWF(PySCFSlater(supercell, mf), JastrowSpin(supercell)), PySCFSlater(supercell, mf), MultiSlaterPBC(supercell, mf, detwt=detwt, occup=occup, map_dets=map_dets), # PySCFSlaterPBC(supercell, mf_uhf), # PySCFSlaterPBC(supercell, mf_rohf), ]: for k in wf.parameters: if "mo_coeff" not in k and k != "det_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 default_jastrow(mol, ion_cusp=None, na=4, nb=3, rcut=None): """ Default 2-body jastrow from qwalk, Args: ion_cusp (bool): add an extra term to satisfy electron-ion cusp. Returns: jastrow, to_opt """ import numpy as np def expand_beta_qwalk(beta0, n): """polypade expansion coefficients for n basis functions with first coeff beta0""" if n == 0: return np.zeros(0) beta = np.zeros(n) beta[0] = beta0 beta1 = np.log(beta0 + 1.00001) for i in range(1, n): beta[i] = np.exp(beta1 + 1.6 * i) - 1 return beta if rcut is None: if hasattr(mol, "a"): rcut = np.amin(np.pi / np.linalg.norm(mol.reciprocal_vectors(), axis=1)) else: rcut = 7.5 beta_abasis = expand_beta_qwalk(0.2, na) beta_bbasis = expand_beta_qwalk(0.5, nb) if ion_cusp == False: ion_cusp = [] if not mol.has_ecp(): print("Warning: using neither ECP nor ion_cusp") elif ion_cusp == True: ion_cusp = list(mol._basis.keys()) if mol.has_ecp(): print("Warning: using both ECP and ion_cusp") elif ion_cusp is None: ion_cusp = [l for l in mol._basis.keys() if l not in mol._ecp.keys()] print("default ion_cusp:", ion_cusp) else: assert isinstance(ion_cusp, list) if len(ion_cusp) > 0: abasis = [CutoffCuspFunction(gamma=24, rcut=rcut)] else: abasis = [] abasis += [PolyPadeFunction(beta=ba, rcut=rcut) for ba in beta_abasis] bbasis = [CutoffCuspFunction(gamma=24, rcut=rcut)] bbasis += [PolyPadeFunction(beta=bb, rcut=rcut) for bb in beta_bbasis] jastrow = JastrowSpin(mol, a_basis=abasis, b_basis=bbasis) if len(ion_cusp) > 0: coefs = mol.atom_charges().copy() coefs[[l[0] not in ion_cusp for l in mol._atom]] = 0.0 jastrow.parameters["acoeff"][:, 0, :] = coefs[:, None] jastrow.parameters["bcoeff"][0, [0, 1, 2]] = np.array([-0.25, -0.50, -0.25]) to_opt = {} to_opt["acoeff"] = np.ones(jastrow.parameters["acoeff"].shape).astype(bool) if len(ion_cusp) > 0: to_opt["acoeff"][:, 0, :] = False # Cusp conditions to_opt["bcoeff"] = np.ones(jastrow.parameters["bcoeff"].shape).astype(bool) to_opt["bcoeff"][0, [0, 1, 2]] = False # Cusp conditions return jastrow, to_opt
import numpy as np from pyscf import lib, gto, scf import pyqmc from pyqmc.slateruhf import PySCFSlaterUHF from pyqmc.jastrowspin import JastrowSpin # from pyqmc.jastrow import Jastrow2B from pyqmc.coord import OpenConfigs import time from pyqmc.manybody_jastrow import J3 import pyqmc.testwf as test from pyqmc.wf import WaveFunction from pyqmc.multiplywf import MultiplyWF # import pandas as pd mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5", basis="sto-3g", unit="bohr") mf = scf.UHF(mol).run() wf1 = PySCFSlaterUHF(mol, mf) wf2 = JastrowSpin(mol) # wf3 = J3(mol) wf = WaveFunction([wf1, wf2]) wfmultiply = MultiplyWF(wf1, wf2) configs = OpenConfigs(np.random.randn(10, np.sum(mol.nelec), 3)) wf.recompute(configs) # res = test.test_wf_gradient(wf, configs) e = 2 epos = configs.electron(e) test.test_mask(wf, 3, epos)