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(): from pyscf import lib, gto, scf from pyqmc.accumulators import EnergyAccumulator, PGradTransform, LinearTransform from pyqmc.multiplywf import MultiplyWF from pyqmc.jastrow import Jastrow2B from pyqmc.func3d import GaussianFunction from pyqmc.slater import PySCFSlaterRHF from pyqmc.mc import initial_guess mol = gto.M(atom='H 0. 0. 0.; H 0. 0. 1.5', basis='cc-pvtz', unit='bohr', verbose=5) mf = scf.RHF(mol).run() nconf = 2500 nsteps = 70 warmup = 20 coords = initial_guess(mol, nconf) basis = { 'wf2coeff': [GaussianFunction(0.2), GaussianFunction(0.4), GaussianFunction(0.6)] } wf = MultiplyWF(PySCFSlaterRHF(mol, mf), Jastrow2B(mol, basis['wf2coeff'])) params0 = {'wf2coeff': np.array([-0.8, -0.2, 0.4])} for k, p in wf.parameters.items(): if k in params0: wf.parameters[k] = params0[k] energy_acc = EnergyAccumulator(mol) pgrad_acc = PGradTransform(energy_acc, LinearTransform(wf.parameters)) # Gradient descent wf, data = gradient_descent(wf, coords, pgrad_acc, vmcoptions={'nsteps': nsteps}, warmup=warmup, step=0.5, eps=0.1, maxiters=50, datafile='sropt.json')
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 gradient_generator(mol, wf, to_opt=None, **ewald_kwargs): return PGradTransform(EnergyAccumulator(mol, **ewald_kwargs), LinearTransform(wf.parameters, to_opt))
def gradient_generator(mol, wf, to_opt=None, freeze=None): return PGradTransform(EnergyAccumulator(mol), LinearTransform(wf.parameters, to_opt, freeze))
def integratenode(node_coords, node_grad, vizfile='integratenode.pdf', integ_range=1e-1, poly=1e-2, max_cutoff=0.1): from wavefunction import wavefunction import scipy.integrate as integrate from numpy.polynomial import polynomial mol, wf, to_opt, freeze = wavefunction() eacc = EnergyAccumulator(mol) transform = LinearTransform(wf.parameters, to_opt, freeze) pgrad_bare = PGradTransform(eacc, transform, 1e-15) #Integrate biases and variances biases = [] biases_err = [] variances = [] cutoffs = list(np.logspace(-6, -1, 20)) + [0.05, 0.075] ''' normalization = integrate.quad(lambda x: psi2(x, node_coords, node_grad, wf), -integ_range, integ_range, epsabs = 1e-15, epsrel = 1e-15) for cutoff in cutoffs: print(cutoff) pgrad = PGradTransform_new(eacc, transform, nodal_cutoff = np.array([cutoff])) bias = integrate.quad(lambda x: dpH(x, pgrad, pgrad_bare, node_coords, node_grad, wf)/1e-40, -cutoff, cutoff, epsabs = 1e-15, epsrel = 1e-15, points=[0]) variance = integrate.quad(lambda x: dpH2(x, pgrad, node_coords, node_grad, wf), -cutoff, cutoff, epsabs = 1e-15, epsrel = 1e-15, points=[0]) variance += integrate.quad(lambda x: dpH2(x, pgrad, node_coords, node_grad, wf), -integ_range + cutoff, integ_range - cutoff, epsabs = 1e-15, epsrel = 1e-15) biases.append(bias[0]*1e-40/normalization[0]) variances.append(variance[0]/normalization[0]) df = pd.DataFrame({'cutoff': cutoffs, 'bias': biases, 'variance': variances}) df.to_pickle('integratenode.pickle') ''' df = pd.read_pickle('integratenode.pickle') #Fit theory curves and visualize ind = np.argsort(df['cutoff']) ind = ind[df['cutoff'].iloc[ind] <= max_cutoff] fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(3, 6), sharex=True) x = df['cutoff'].iloc[ind] y = np.abs(df['bias']).iloc[ind] y = y[2:] x = x[2:] p = polynomial.polyfit(x, y, [3]) print("Fit for bias ", p) xfit = np.linspace(min(x), max(x[x < poly]), 1000) fit = p[3] * (xfit)**3 ax[0].plot(np.log10(x), np.log10(y), 'o') ax[0].plot(np.log10(xfit), np.log10(fit), '--') ax[0].set_ylabel(r'log$_{10}$(Bias)') x = df['cutoff'].iloc[ind] y = df['variance'].iloc[ind] y = y[2:] x = x[2:] x = np.log10(x) y = np.log10(y) poly = np.log10(poly) p = polynomial.polyfit(x[x < poly], y[x < poly], [1, 0]) print("Fit for variance ", p) xfit = np.logspace(min(x), max(x[x <= poly]), 1000) fit = p[0] + p[1] * np.log10(xfit) ax[1].plot(x, y, 'o') ax[1].plot(np.log10(xfit), fit, '--') ax[1].set_xlabel(r'$log_{10}(\epsilon/$Bohr$)$') ax[1].set_ylabel(r'log$_{10}$(Variance)') #ax[1].set_xlim((-3.2, 2.3)) #ax[1].set_xticks(np.arange(-3,3)) plt.savefig(vizfile, bbox_inches='tight') plt.close()
def test(): import parsl from pyscf import lib, gto, scf import numpy as np import pandas as pd import logging from parsl.config import Config from parsl.providers import LocalProvider from parsl.channels import LocalChannel from parsl.launchers import SimpleLauncher from parsl.executors import ExtremeScaleExecutor ncore = 4 config = Config( executors=[ ExtremeScaleExecutor(label="Extreme_Local", worker_debug=True, ranks_per_node=ncore, provider=LocalProvider( channel=LocalChannel(), init_blocks=1, max_blocks=1, launcher=SimpleLauncher())) ], strategy=None, ) parsl.load(config) mol = gto.M(atom='H 0. 0. 0.; H 0. 0. 2.0', unit='bohr', ecp='bfd', basis='bfd_vtz') mf = scf.RHF(mol).run() mol.output = None mol.stdout = None mf.output = None mf.stdout = None mf.chkfile = None from pyqmc import ExpCuspFunction, GaussianFunction, MultiplyWF, PySCFSlaterRHF, JastrowSpin, initial_guess, EnergyAccumulator from pyqmc.accumulators import PGradTransform, LinearTransform nconf = 1600 basis = [ ExpCuspFunction(2.0, 1.5), GaussianFunction(0.5), GaussianFunction(2.0), GaussianFunction(.25), GaussianFunction(1.0), GaussianFunction(4.0), GaussianFunction(8.0) ] wf = MultiplyWF(PySCFSlaterRHF(mol, mf), JastrowSpin(mol, basis, basis)) coords = initial_guess(mol, nconf) energy_acc = EnergyAccumulator(mol) pgrad_acc = PGradTransform( energy_acc, LinearTransform(wf.parameters, ['wf2acoeff', 'wf2bcoeff'])) from pyqmc.optsr import gradient_descent gradient_descent(wf, coords, pgrad_acc, vmc=distvmc, vmcoptions={ 'npartitions': ncore, 'nsteps': 100, 'nsteps_per': 100 })