def VMC(dft_checkfile, output, nconfig=1000, start_from=None, S=None, client=None, npartitions=None, jastrow_kws=None, slater_kws=None, vmc_kws=None, accumulators=None): if vmc_kws is None: vmc_kws = {} mol, mf = pyqmc.recover_pyscf(dft_checkfile) if S is not None: mol = pyqmc.get_supercell(mol, np.asarray(S)) wf, _ = pyqmc.generate_wf(mol, mf, jastrow_kws=jastrow_kws, slater_kws=slater_kws) if start_from is not None: pyqmc.read_wf(wf, start_from) configs = pyqmc.initial_guess(mol, nconfig) pyqmc.vmc(wf, configs, accumulators=generate_accumulators(mol, mf, **accumulators), verbose=True, hdf_file=output, client=client, npartitions=npartitions, **vmc_kws)
def dmc(self, nconfig=1000, **kwargs): configs = pyqmc.initial_guess(self.mol, nconfig) if self.client is None: pyqmc.vmc(self.wf, configs, nsteps=10) pyqmc.rundmc( self.wf, configs, accumulators={"energy": pyqmc.EnergyAccumulator(self.mol)}, **kwargs, ) else: pyqmc.dasktools.distvmc( self.wf, configs, nsteps=10, client=self.client, npartitions=self.npartitions, ) pyqmc.rundmc( self.wf, configs, accumulators={"energy": pyqmc.EnergyAccumulator(self.mol)}, propagate=pyqmc.dasktools.distdmc_propagate, **kwargs, client=self.client, npartitions=self.npartitions, )
def find_basis_evaluate(mfchk, hdf_opt, hdf_vmc, hdf_final): """Given a wave function in hdf_opt, compute the 1-RDM (stored in hdf_vmc) , generate a minimal atomic basis and compute the energy/OBDM/TBDM and store in hdf_final """ from pyqmc.obdm import OBDMAccumulator from pyqmc.tbdm import TBDMAccumulator from pyqmc import EnergyAccumulator sys = pyqmc_from_hdf(mfchk) mol = sys["mol"] a = lo.orth_ao(mol, "lowdin") obdm_up = OBDMAccumulator(mol=mol, orb_coeff=a, spin=0) obdm_down = OBDMAccumulator(mol=mol, orb_coeff=a, spin=1) with h5py.File(hdf_opt, "r") as hdf_in: if f"wf" in hdf_in.keys(): print("reading in wave function") grp = hdf_in[f"wf"] for k in grp.keys(): sys["wf"].parameters[k] = np.array(grp[k]) configs = pyqmc.initial_guess(sys["mol"], 1000) pyqmc.vmc( sys["wf"], configs, nsteps=500, hdf_file=hdf_vmc, accumulators={ "obdm_up": obdm_up, "obdm_down": obdm_down }, ) with h5py.File(hdf_vmc, "r") as vmc_hdf: obdm_up = np.mean(np.array(vmc_hdf["obdm_upvalue"]), axis=0) obdm_down = np.mean(np.array(vmc_hdf["obdm_downvalue"]), axis=0) basis_up = gen_basis(mol, sys["mf"], obdm_up) basis_down = gen_basis(mol, sys["mf"], obdm_down) obdm_up_acc = OBDMAccumulator(mol=mol, orb_coeff=basis_up, spin=0) obdm_down_acc = OBDMAccumulator(mol=mol, orb_coeff=basis_down, spin=1) tbdm = TBDMAccumulator(mol, np.array([basis_up, basis_down]), spin=(0, 1)) acc = { "energy": EnergyAccumulator(mol), "obdm_up": obdm_up_acc, "obdm_down": obdm_down_acc, "tbdm": tbdm, } configs = pyqmc.initial_guess(sys["mol"], 1000) pyqmc.vmc(sys["wf"], configs, nsteps=500, hdf_file=hdf_final, accumulators=acc)
def VMC( dft_checkfile, output, nconfig=1000, ci_checkfile=None, start_from=None, S=None, client=None, npartitions=None, jastrow_kws=None, slater_kws=None, vmc_kws=None, accumulators=None, ): if vmc_kws is None: vmc_kws = {} target_root = 0 if ci_checkfile is None: mol, mf = pyqmc.recover_pyscf(dft_checkfile) mc = None else: mol, mf, mc = pyqmc.recover_pyscf(dft_checkfile, ci_checkfile=ci_checkfile) mc.ci = mc.ci[target_root] if S is not None: print("S", S) mol = pyqmc.get_supercell(mol, np.asarray(S)) if accumulators is None: accumulators = {} wf, _ = pyqmc.generate_wf(mol, mf, mc=mc, jastrow_kws=jastrow_kws, slater_kws=slater_kws) if start_from is not None: pyqmc.read_wf(wf, start_from) configs = pyqmc.initial_guess(mol, nconfig) pyqmc.vmc(wf, configs, accumulators=generate_accumulators(mol, mf, **accumulators), verbose=True, hdf_file=output, client=client, npartitions=npartitions, **vmc_kws)
def evaluate_big1rdm(mc_calc, output, nconfig =1000, **kwargs): mol = mc_calc['mol'] a = pyscf.lo.orth_ao(mol, 'lowdin') obdm_up = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=a, spin=0) obdm_down = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=a, spin=1) configs = pyqmc.initial_guess(mol, 1000) pyqmc.vmc(mc_calc['wf'], configs, hdf_file=output, accumulators = { 'obdm_up':obdm_up, 'obdm_down':obdm_down }, **kwargs )
def evaluate_smallbasis(mc_calc, smallbasis_hdf, nconfig=1000, **kwargs): with h5py.File(smallbasis_hdf,'r') as f: basis_up = f['basis_up'][...] basis_down = f['basis_down'][...] mol = mc_calc['mol'] obdm_up_acc = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=basis_up, spin=0) obdm_down_acc = pyqmc.obdm.OBDMAccumulator(mol=mol, orb_coeff=basis_down, spin=1) tbdm = pyqmc.tbdm.TBDMAccumulator(mol, np.array([basis_up,basis_down]), spin=(0,1)) acc = {'energy': pyqmc.EnergyAccumulator(mol), 'obdm_up':obdm_up_acc, 'obdm_down':obdm_down_acc, 'tbdm': tbdm } configs = pyqmc.initial_guess(mc_calc['mol'], nconfig) pyqmc.vmc(mc_calc['wf'], configs, accumulators = acc, **kwargs)
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 Slater from pyqmc.multiplywf import MultiplyWF from pyqmc import default_jastrow 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(Slater(supercell, mf), default_jastrow(supercell)[0]), Slater(supercell, mf), ]: 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) _, 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)) print(type(wf), fname, min(err)) assert min(err) < epsilon for k, item in testwf.test_updateinternals(wf, epos).items(): print(k, item) assert item < epsilon
def test(): from pyscf.pbc import gto, scf import pyqmc import pandas as pd L = 4 mol = gto.M( atom="""H {0} {0} {0}""".format(0.0), basis="sto-3g", a=np.eye(3) * L, spin=1, unit="bohr", ) mf = scf.UKS(mol) mf.xc = "pbe" mf = mf.density_fit().run() wf = pyqmc.PySCFSlaterUHF(mol, mf) ##################################### ## evaluate KE in PySCF ##################################### ke_mat = mol.pbc_intor("int1e_kin", hermi=1, kpts=np.array([0, 0, 0])) dm = mf.make_rdm1() pyscfke = np.einsum("ij,ji", ke_mat, dm[0]) print("PySCF kinetic energy: {0}".format(pyscfke)) ##################################### ## evaluate KE integral on grid ##################################### X = np.linspace(0, 1, 20, endpoint=False) XYZ = np.meshgrid(X, X, X, indexing="ij") pts = [np.outer(p.ravel(), mol.a[i]) for i, p in enumerate(XYZ)] coords = np.sum(pts, axis=0).reshape((-1, 1, 3)) phase, logdet = wf.recompute(coords) psi = phase * np.exp(logdet) lap = wf.laplacian(0, coords.reshape((-1, 3))) gridke = np.sum(-0.5 * lap * psi ** 2) / np.sum(psi ** 2) print("grid kinetic energy: {0}".format(gridke)) ##################################### ## evaluate KE integral with VMC ##################################### coords = pyqmc.initial_guess(mol, 600, 0.7) coords = PeriodicConfigs(coords, mol.a) warmup = 10 df, coords = pyqmc.vmc( wf, coords, nsteps=128 + warmup, tstep=L * 0.6, accumulators={"energy": pyqmc.accumulators.EnergyAccumulator(mol)}, ) df = pd.DataFrame(df) reblocked = pyqmc.reblock.optimally_reblocked(df["energyke"][warmup:]) print( "VMC kinetic energy: {0} $\pm$ {1}".format( reblocked["mean"], reblocked["standard error"] ) )
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 test_updateinternals(wf, configs): """ Parameters: wf: a wave function object to be tested configs: nconf x nelec x 3 position array Returns: tuple which """ from pyqmc import vmc nconf, ne, ndim = configs.configs.shape delta = 1e-2 iscomplex = 1j if wf.iscomplex else 1 updatevstest = np.zeros((ne, nconf)) * iscomplex recomputevstest = np.zeros((ne, nconf)) * iscomplex recomputevsupdate = np.zeros((ne, nconf)) * iscomplex wfcopy = copy.copy(wf) val1 = wf.recompute(configs) for e in range(ne): # val1 = wf.recompute(configs) epos = configs.make_irreducible(e, configs.configs[:, e, :] + delta) ratio = wf.testvalue(e, epos) wf.updateinternals(e, epos) update = wf.value() configs.move(e, epos, [True] * nconf) recompute = wfcopy.recompute(configs) updatevstest[ e, :] = update[0] / val1[0] * np.exp(update[1] - val1[1]) - ratio recomputevsupdate[e, :] = update[0] / val1[0] * np.exp( update[1] - val1[1]) - recompute[0] / val1[0] * np.exp(recompute[1] - val1[1]) recomputevstest[e, :] = ( recompute[0] / val1[0] * np.exp(recompute[1] - val1[1]) - ratio) val1 = recompute # Test mask and pgrad _, configs = vmc(wf, configs, nblocks=1, nsteps_per_block=1, tstep=2) pgradupdate = wf.pgradient() wf.recompute(configs) pgrad = wf.pgradient() pgdict = { k: np.max(np.abs(pgu - pgrad[k])) for k, pgu in pgradupdate.items() } return { "updatevstest": np.max(np.abs(updatevstest)), "recomputevstest": np.max(np.abs(recomputevstest)), "recomputevsupdate": np.max(np.abs(recomputevsupdate)), **pgdict, }
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 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_shci_wf(): mol = pyscf.gto.M( atom="O 0. 0. 0.; H 0. 0. 2.0", basis="ccecpccpvtz", ecp="ccecp", unit="bohr", charge=-1, ) mf = pyscf.scf.RHF(mol) mf.kernel() e_hf = mf.energy_tot() cisolver = pyscf.hci.SCI(mol) cisolver.select_cutoff = 0.1 nmo = mf.mo_coeff.shape[1] nelec = mol.nelec h1 = mf.mo_coeff.T.dot(mf.get_hcore()).dot(mf.mo_coeff) h2 = pyscf.ao2mo.full(mol, mf.mo_coeff) e, civec = cisolver.kernel(h1, h2, nmo, nelec, verbose=4) cisolver.ci = civec[0] ci_energy = mf.energy_nuc() + e tol = 0.0 configs = pyqmc.initial_guess(mol, 1000) wf = pyqmc.Slater(mol, mf, cisolver, tol=tol) data, configs = pyqmc.vmc( wf, configs, nblocks=40, verbose=True, accumulators={"energy": pyqmc.EnergyAccumulator(mol)}, ) en, err = avg(data["energytotal"][1:]) nsigma = 4 assert len(wf.parameters["det_coeff"]) == len(cisolver.ci) assert en - nsigma * err < e_hf assert en + nsigma * err > ci_energy
# Initialize energy accumulator (and Ewald) pgrad = pyqmc.gradient_generator(supercell, wf, to_opt=to_opt) # Optimize jastrow wf, lm_df = pyqmc.line_minimization(wf, configs, pgrad, hdf_file="pbc_he_linemin.hdf", verbose=True) # Run VMC df, configs = pyqmc.vmc( wf, configs, nblocks=100, accumulators={"energy": pgrad.enacc}, hdf_file="pbc_he_vmc.hdf", verbose=True, ) # Run DMC pyqmc.rundmc( wf, configs, nsteps=1000, accumulators={"energy": pgrad.enacc}, hdf_file="pbc_he_dmc.hdf", verbose=True, )
pgrad_acc = pyqmc.gradient_generator(mol, wf, to_opt) configs = pyqmc.initial_guess(mol, nconfig) line_minimization( wf, configs, pgrad_acc, hdf_file="h2o_opt.hdf", client=client, npartitions=ncore, verbose=True, ) df, configs = vmc( wf, configs, hdf_file="h2o_vmc.hdf", accumulators={"energy": pgrad_acc.enacc}, client=client, npartitions=ncore, verbose=True, ) dfdmc, configs, weights = rundmc( wf, configs, hdf_file="h2o_dmc.hdf", nsteps=1000, accumulators={"energy": pgrad_acc.enacc}, ekey=("energy", "total"), tstep=0.02, verbose=True, client=client, npartitions=ncore,
jastrow.parameters["bcoeff"][0, [0, 1, 2]] = np.array( [-0.25, -0.50, -0.25]) freeze = {} freeze["wf2acoeff"] = np.zeros( jastrow.parameters["acoeff"].shape).astype(bool) freeze["wf2bcoeff"] = np.zeros( jastrow.parameters["bcoeff"].shape).astype(bool) freeze["wf2bcoeff"][0, [0, 1, 2]] = True # Cusp conditions to_opt = ["wf2acoeff", "wf2bcoeff"] # Multiply wf = MultiplyWF(slater, jastrow) configs = pyqmc.initial_guess(supercell, nconfig) # Warm up VMC df, configs = pyqmc.vmc(wf, configs, nsteps=5, verbose=True) # Initialize energy accumulator (and Ewald) pgrad = pyqmc.gradient_generator(supercell, wf, to_opt=to_opt, freeze=freeze) # Optimize jastrow hdf_file = "linemin_nk{0}.hdf".format(nk) wf, lm_df = line_minimization(wf, configs, pgrad, hdf_file=hdf_file, verbose=True) jastrow = wf.wf2
"excited1_final": "excited1_final.hdf5", "excited2_final": "excited2_final.hdf5", } for k, it in savefiles.items(): if os.path.isfile(it): os.remove(it) # Run setuph2(savefiles["mf"], "test") sys = pyqmc_from_hdf(savefiles["mf"]) df, coords = vmc( sys["wf"], pyqmc.initial_guess(sys["mol"], nconfig), client=client, nsteps=10, npartitions=ncore, ) line_minimization( sys["wf"], coords, sys["pgrad"], hdf_file=savefiles["linemin"], client=client, npartitions=ncore, verbose=True, ) # First excited state