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 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 optimize_excited(mc_anchors, mc_calc, nconfig = 1000, **kwargs): acc = pyqmc.gradient_generator(mc_calc['mol'], mc_calc['wf'], to_opt=mc_calc['to_opt']) wfs = [x['wf'] for x in mc_anchors] wfs.append(mc_calc['wf']) configs = pyqmc.initial_guess(mc_calc['mol'], nconfig) pyqmc.optimize_orthogonal.optimize_orthogonal(wfs,configs, acc, **kwargs)
def test_transform(): """ Just prints things out; TODO: figure out a thing to test. """ from pyscf import gto, scf import pyqmc r = 1.54 / .529177 mol = gto.M(atom='H 0. 0. 0.; H 0. 0. %g' % r, ecp='bfd', basis='bfd_vtz', unit='bohr', verbose=1) mf = scf.RHF(mol).run() wf = pyqmc.slater_jastrow(mol, mf) enacc = pyqmc.EnergyAccumulator(mol) print(list(wf.parameters.keys())) transform = LinearTransform(wf.parameters) x = transform.serialize_parameters(wf.parameters) nconfig = 10 configs = pyqmc.initial_guess(mol, nconfig) wf.recompute(configs) pgrad = wf.pgradient() gradtrans = transform.serialize_gradients(pgrad) assert gradtrans.shape[1] == len(x) assert gradtrans.shape[0] == nconfig
def test_transform(): """ Just prints things out; TODO: figure out a thing to test. """ from pyscf import gto, scf r = 1.54 / 0.529177 mol = gto.M( atom="H 0. 0. 0.; H 0. 0. %g" % r, ecp="bfd", basis="bfd_vtz", unit="bohr", verbose=1, ) mf = scf.RHF(mol).run() wf, to_opt = pyqmc.default_sj(mol, mf) enacc = pyqmc.EnergyAccumulator(mol) print(list(wf.parameters.keys())) transform = LinearTransform(wf.parameters) x = transform.serialize_parameters(wf.parameters) nconfig = 10 configs = pyqmc.initial_guess(mol, nconfig) wf.recompute(configs) pgrad = wf.pgradient() gradtrans = transform.serialize_gradients(pgrad) assert gradtrans.shape[1] == len(x) assert gradtrans.shape[0] == nconfig
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 OPTIMIZE( dft_checkfile, output, nconfig=1000, start_from=None, S=None, client=None, npartitions=None, jastrow_kws=None, slater_kws=None, linemin_kws=None, ): if linemin_kws is None: linemin_kws = {} mol, mf = pyqmc.recover_pyscf(dft_checkfile) if S is not None: mol = pyqmc.get_supercell(mol, np.asarray(S)) wf, to_opt = 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) acc = pyqmc.gradient_generator(mol, wf, to_opt) pyqmc.line_minimization(wf, configs, acc, verbose=True, hdf_file=output, client=client, npartitions=npartitions, **linemin_kws)
def DMC(dft_checkfile, output, nconfig=1000, start_from=None, S=None, client=None, npartitions=None, jastrow_kws=None, slater_kws=None, dmc_kws=None, accumulators=None): if dmc_kws is None: dmc_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.rundmc(wf, configs, accumulators=generate_accumulators(mol, mf, **accumulators), verbose=True, hdf_file=output, client=client, npartitions=npartitions, **dmc_kws)
def OPTIMIZE( dft_checkfile, output, anchors=None, nconfig=1000, ci_checkfile=None, start_from=None, S=None, client=None, npartitions=None, jastrow_kws=None, slater_kws=None, linemin_kws=None, ): if linemin_kws is None: linemin_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: mol = pyqmc.get_supercell(mol, np.asarray(S)) wf, to_opt = 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) acc = pyqmc.gradient_generator(mol, wf, to_opt) if anchors is None: pyqmc.line_minimization(wf, configs, acc, verbose=True, hdf_file=output, client=client, npartitions=npartitions, **linemin_kws) else: wfs = [pyqmc.read_wf(copy.deepcopy(wf), a) for a in anchors] wfs.append(wf) pyqmc.optimize_orthogonal( wfs, configs, acc, # verbose=True, hdf_file=output, client=client, npartitions=npartitions, **linemin_kws)
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 setup(self): self.mol = pyscf.gto.M(atom="O 0 0 0; H 0 -2.757 2.587; H 0 2.757 2.587", basis=f'ccecpccpvdz', ecp='ccecp') self.mf = pyscf.scf.RHF(self.mol).run() self.configs = pyqmc.initial_guess(self.mol, 500) self.slater, self.slater_to_opt = pyqmc.default_slater(self.mol, self.mf, optimize_orbitals=True) self.jastrow, self.jastrow_to_opt = pyqmc.default_jastrow(self.mol) self.pgrad_acc = pyqmc.gradient_generator(self.mol, self.slater, self.slater_to_opt) self.slater.recompute(self.configs) self.jastrow.recompute(self.configs)
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 generate_test_inputs(): import pyqmc from pyqmc.coord import PeriodicConfigs from pyscf.pbc import gto, scf from pyscf.pbc.dft.multigrid import multigrid from pyscf.pbc import tools from pyscf import lib from_chkfile = True if from_chkfile: def loadchkfile(chkfile): cell = gto.cell.loads(lib.chkfile.load(chkfile, "mol")) kpts = cell.make_kpts([1, 1, 1]) mf = scf.KRKS(cell, kpts) mf.__dict__.update(lib.chkfile.load(chkfile, "scf")) return cell, mf cell1, mf1 = loadchkfile("mf1.chkfile") cell2, mf2 = loadchkfile("mf2.chkfile") else: L = 4 cell2 = gto.M( atom="""H {0} {0} {0} H {1} {1} {1}""".format(0.0, L * 0.25), basis="sto-3g", a=np.eye(3) * L, spin=0, unit="bohr", ) print("Primitive cell") kpts = cell2.make_kpts((2, 2, 2)) mf2 = scf.KRKS(cell2, kpts) mf2.xc = "pbe" mf2.chkfile = "mf2.chkfile" mf2 = mf2.run() print("Supercell") cell1 = tools.super_cell(cell2, [2, 2, 2]) kpts = [[0, 0, 0]] mf1 = scf.KRKS(cell1, kpts) mf1.xc = "pbe" mf1.chkfile = "mf1.chkfile" mf1 = mf1.run() # wf1 = pyqmc.PySCFSlaterUHF(cell1, mf1) wf1 = PySCFSlaterPBC(cell1, mf1, supercell=1 * np.eye(3)) wf2 = PySCFSlaterPBC(cell2, mf2, supercell=2 * np.eye(3)) configs = pyqmc.initial_guess(cell1, 10, 0.1) return wf1, wf2, configs
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 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 info_functions(mol, wf, accumulators): accumulators["energy"] = accumulators["pgrad"].enacc configs = pyqmc.initial_guess(mol, 100) wf.recompute(configs) for k, acc in accumulators.items(): shapes = acc.shapes() keys = acc.keys() assert shapes.keys() == keys, "keys: {0}\nshapes: {1}".format( keys, shapes) avg = acc.avg(configs, wf) assert avg.keys() == keys, (k, avg.keys(), keys) for ka in keys: assert shapes[ka] == avg[ka].shape, "{0} {1}".format( ka, avg[ka].shape)
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 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 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(): """ Optimize a Helium atom's wave function and check that it's better than Hartree-Fock""" mol = gto.M(atom="He 0. 0. 0.", basis="bfd_vdz", ecp="bfd", unit="bohr") mf = scf.RHF(mol).run() wf = slater_jastrow(mol, mf) nconf = 500 wf, dfgrad, dfline = line_minimization(wf, initial_guess(mol, nconf), gradient_generator(mol, wf)) dfgrad = pd.DataFrame(dfgrad) mfen = mf.energy_tot() enfinal = dfgrad["en"].values[-1] enfinal_err = dfgrad["en_err"].values[-1] assert mfen > enfinal
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_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 test(): print("running scf", flush=True) mol = gto.M(atom="H 0. 0. 0.; H 0. 0. 1.6", basis="ccpvdz", unit="bohr") mf = scf.UHF(mol).run() mf.stdout = None print("setting up wfs", flush=True) wf0 = pyqmc.Slater(mol, mf) mf.mo_coeff[0][:, 0] = np.mean(mf.mo_coeff[0][:, :2], axis=1) wf1, to_opt = pyqmc.default_slater(mol, mf, optimize_orbitals=True) pgrad = pyqmc.gradient_generator(mol, wf1, to_opt) configs = pyqmc.initial_guess(mol, 2000) wf0.recompute(configs) wf1.recompute(configs) wfs = [wf0, wf1] print("warming up", flush=True) block_avg, configs = oo.sample_overlap_worker(wfs, configs, pgrad, 20, tstep=1.5) print("computing gradients and normalization", flush=True) data = get_data(wfs, configs, pgrad) parameters = pgrad.transform.serialize_parameters(wfs[-1].parameters) N = compute_normalization(wfs, [parameters], pgrad.transform, configs) print(np.stack([data["N"], N])) print("computing numerical gradients", flush=True) error = {"N": [], "S": []} deltas = [1e-4, 1e-5, 1e-6] numgrad = numerical_gradient(wfs, configs, pgrad, deltas) for k, ng in numgrad.items(): pgerr = data[k + "_derivative"].T[:, np.newaxis] - ng error[k] = pgerr print("computing errors", flush=True) for k, er in error.items(): error[k] = np.amin(er, axis=1) print(k) print(error[k])
def optimize(self, nconfig=1000, **kwargs): configs = pyqmc.initial_guess(self.mol, nconfig) acc = pyqmc.gradient_generator(self.mol, self.wf, to_opt=self.to_opt) if self.client is None: pyqmc.line_minimization(self.wf, configs, acc, **kwargs) else: pyqmc.dasktools.line_minimization( self.wf, configs, acc, **kwargs, client=self.client, lmoptions={"npartitions": self.npartitions}, vmcoptions={ "npartitions": self.npartitions, 'nblocks': 5, 'nsteps_per_block': 20 }, )
def setup(self): self.cell = pyscf.pbc.gto.Cell() self.cell.atom = '''C 0. 0. 0. C 0.8917 0.8917 0.8917 C 1.7834 1.7834 0. C 2.6751 2.6751 0.8917 C 1.7834 0. 1.7834 C 2.6751 0.8917 2.6751 C 0. 1.7834 1.7834 C 0.8917 2.6751 2.6751''' self.cell.basis = f'ccecpccpvdz' self.cell.pseudo = 'ccecp' self.cell.a = np.eye(3)*3.5668 self.cell.exp_to_discard=0.2 self.cell.build() self.configs = pyqmc.initial_guess(self.cell, 500) self.jastrow, self.jastrow_to_opt = pyqmc.default_jastrow(self.cell) self.jastrow.recompute(self.configs)
def sweepelectron(): """ Sweep an electron across the molecule to find a guess for the nodal position """ import copy from pyqmc.accumulators import EnergyAccumulator, LinearTransform, PGradTransform #Generate wave function and bare parameter gradient objects mol, wf, to_opt, freeze = wavefunction() eacc = EnergyAccumulator(mol) transform = LinearTransform(wf.parameters, to_opt, freeze) pgrad = PGradTransform(eacc, transform, 1e-20) #Initial coords configs = pyqmc.initial_guess(mol, 1).configs[:,:,:] #Sweep electron 0 full_df = None e = 3 #electron dim = 1 #Coordinate to vary for i in np.linspace(0, 20, 200): new_configs = copy.deepcopy(configs) new_configs[:,e,dim] += i shifted_configs = OpenConfigs(new_configs) wfval = wf.recompute(shifted_configs) d = pgrad(shifted_configs, wf) small_df = pd.DataFrame({ 'ke':[d['ke'][0]], 'total':[d['total'][0]], 'dppsi':[d['dppsi'][0][0]], 'dpH' :[d['dpH'][0][0]], 'wfval':[wfval[0][0]*np.exp(wfval[1][0])], 'ycoord': i, 'configs':[copy.deepcopy(new_configs)], }) if(full_df is None): full_df = small_df else: full_df = pd.concat((full_df, small_df), axis=0) return full_df.reset_index()
def test(): chkfile = "h2.hdf5" optfile = "linemin.hdf5" run_scf(chkfile) mol, mf = pyqmc.recover_pyscf(chkfile) noise = (np.random.random(mf.mo_coeff.shape) - 0.5) * 0.2 mf.mo_coeff = mf.mo_coeff * 1j + noise slater_kws = {"optimize_orbitals": True} wf, to_opt = pyqmc.generate_wf(mol, mf, slater_kws=slater_kws) configs = pyqmc.initial_guess(mol, 100) acc = pyqmc.gradient_generator(mol, wf, to_opt) pyqmc.line_minimization(wf, configs, acc, verbose=True, hdf_file=optfile, max_iterations=5) assert os.path.isfile(optfile) os.remove(chkfile) os.remove(optfile)
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
import pyqmc import pyqmc.dasktools from pyqmc.dasktools import distvmc as vmc from pyqmc.dasktools import line_minimization from pyqmc.cvmc import optimize from dask.distributed import Client, LocalCluster r = 1.1 ncore = 2 sys = setuph2(r) cluster = LocalCluster(n_workers=ncore, threads_per_worker=1) client = Client(cluster) # Set up calculation nconf = 800 configs = pyqmc.initial_guess(sys["mol"], nconf) wf, dfgrad, dfline = line_minimization( sys["wf"], configs, pyqmc.gradient_generator(sys["mol"], sys["wf"]), client=client, maxiters=5, ) forcing = {} obj = {} for k in sys["descriptors"]: forcing[k] = 0.0 obj[k] = 0.0