예제 #1
0
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
예제 #2
0
def test():
    # Default multi-Slater wave function
    mol = gto.M(atom="Li 0. 0. 0.; H 0. 0. 1.5",
                basis="cc-pvtz",
                unit="bohr",
                spin=0)
    mf = scf.RHF(mol).run()
    mc = mcscf.CASCI(mf, ncas=2, nelecas=(1, 1))
    mc.kernel()

    wf, to_opt = default_msj(mol, mf, mc)
    old_parms = wf.parameters
    lt = LinearTransform(wf.parameters, to_opt)

    # Test serialize parameters
    x0 = lt.serialize_parameters(wf.parameters)
    x0 += np.random.normal(size=x0.shape)
    wf.parameters = lt.deserialize(x0)
    assert wf.parameters["wf1det_coeff"][0] == old_parms["wf1det_coeff"][0]
    assert np.sum(wf.parameters["wf2bcoeff"][0] -
                  old_parms["wf2bcoeff"][0]) == 0

    # Test serialize gradients
    configs = OpenConfigs(np.random.randn(10, 4, 3))
    wf.recompute(configs)
    pgrad = wf.pgradient()
    pgrad_serial = lt.serialize_gradients(pgrad)
    assert np.sum(pgrad_serial[:, :3] - pgrad["wf1det_coeff"][:, 1:4]) == 0
예제 #3
0
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
예제 #4
0
def test_constraints(H2_ccecp_casci_s0):
    mol, mf, mc = H2_ccecp_casci_s0

    wf, to_opt = pyq.generate_wf(mol, mf, mc=mc)

    old_parms = copy.deepcopy(wf.parameters)
    lt = LinearTransform(wf.parameters, to_opt)

    # Test serialize parameters
    x0 = lt.serialize_parameters(wf.parameters)
    x0 += np.random.normal(size=x0.shape)
    for k, it in lt.deserialize(wf, x0).items():
        assert wf.parameters[k].shape == it.shape
        wf.parameters[k] = it

    # to_opt is supposed to be false for both of these.
    assert wf.parameters["wf1det_coeff"][0] == old_parms["wf1det_coeff"][0]
    assert np.sum(wf.parameters["wf2bcoeff"][0] -
                  old_parms["wf2bcoeff"][0]) == 0
    # While this one is supposed to change.
    assert np.sum(wf.parameters["wf2bcoeff"][1] -
                  old_parms["wf2bcoeff"][1]) != 0

    # Test serialize gradients
    configs = pyq.initial_guess(mol, 10)
    wf.recompute(configs)
    pgrad = wf.pgradient()
    pgrad_serial = lt.serialize_gradients(pgrad)

    # Pgrad should be walkers, configs
    assert pgrad_serial.shape[1] == x0.shape[0]
예제 #5
0
def test_transform(LiH_sto3g_rhf):
    """Tests that the shapes are ok"""
    mol, mf = LiH_sto3g_rhf
    wf, to_opt = pyq.generate_wf(mol, mf)
    transform = LinearTransform(wf.parameters)
    x = transform.serialize_parameters(wf.parameters)
    nconfig = 10
    configs = pyq.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
예제 #6
0
def eval_configs(data, cutoffs):
    """
  Evaluate values using the 
  regularization we have constructed
  """

    mol, wf, to_opt, freeze = wavefunction()
    eacc = EnergyAccumulator(mol)
    transform = LinearTransform(wf.parameters, to_opt, freeze)

    print("data loaded")
    r2 = data['distance_squared']
    weight = data['weight_total']

    d = {}
    for cutoff in list(cutoffs):
        node_cut = r2 < cutoff**2
        print(cutoff, node_cut.sum())

        c = 7. / (cutoff**6)
        b = -15. / (cutoff**4)
        a = 9. / (cutoff**2)

        l2 = r2[node_cut]
        dpH = np.copy(data['dpH'])
        dpH[node_cut] *= a * l2 + b * l2**2 + c * l2**3

        hist, bin_edges = np.histogram(np.log10(np.abs(dpH)[np.abs(dpH) > 0]),
                                       bins=200,
                                       density=True,
                                       weights=weight[np.abs(dpH) > 0])
        d['hist' + str(cutoff)] = list(np.log10(hist)) + [None]
        d['bins' + str(cutoff)] = bin_edges
    df = pd.DataFrame(d)
    df.to_pickle('histogram.pickle')
예제 #7
0
def viznode(node_coords, node_grad, cutoffs, vizfile='viznode.pdf'):
    from wavefunction import wavefunction
    mol, wf, to_opt, freeze = wavefunction()
    eacc = EnergyAccumulator(mol)
    transform = LinearTransform(wf.parameters, to_opt, freeze)

    #Generate the distances we want
    x = np.arange(np.sqrt(1 / 0.01), 1001)
    x = 1. / x**2
    x = np.append(x, np.linspace(0.01, 0.12, 100))
    x = np.append(x, np.array([0, 1e-15, 1e-12, 1e-8] + [-y for y in x]))
    x = np.sort(x)

    coord_path = np.einsum('ij,l->lij', node_grad[0], x) + node_coords[0]
    coord_path = OpenConfigs(coord_path)

    #Move across the node in this path
    val = wf.recompute(coord_path)
    fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(3, 6), sharex=True)
    for k, cutoff in enumerate([1e-8] + cutoffs):
        pgrad = PGradTransform_new(eacc,
                                   transform,
                                   nodal_cutoff=np.array([cutoff]))
        d = pgrad(coord_path, wf)

        total = d['total']
        dpH = np.array(d['dpH'])[:, 0, 0]

        if (cutoff == 1e-8):
            ax[0].plot(x,
                       dpH * (val[0] * np.exp(val[1]))**2,
                       'k-',
                       label=r'$10^{' + str(int(np.log10(cutoff))) + '}$')
            ax[1].plot(x, np.log10(dpH**2 * (val[0] * np.exp(val[1]))**2),
                       'k-')
        else:
            ax[0].plot(x,
                       dpH * (val[0] * np.exp(val[1]))**2,
                       '-',
                       label=r'$10^{' + str(int(np.log10(cutoff))) + '}$')
            ax[1].plot(x, np.log10(dpH**2 * (val[0] * np.exp(val[1]))**2), '-')

    ax[0].set_ylabel(r'$E_L\frac{\partial_p \Psi}{\Psi} f_\epsilon |\Psi|^2$')
    ax[1].set_ylabel(
        r'log$_{10}((E_L\frac{\partial_p \Psi}{\Psi})^2 f_\epsilon^2|\Psi|^2)$'
    )
    ax[1].set_xlabel(r'$l$ (Bohr)')
    ax[0].set_xlim((-max(x) - 0.02, max(x) + 0.02))
    ax[1].set_xlim((-max(x) - 0.02, max(x) + 0.02))
    ax[0].legend(loc='best', title=r'$\epsilon$ (Bohr)')
    plt.savefig(vizfile, bbox_inches='tight')
    plt.close()
예제 #8
0
def collectconfigs(n, dump_file):
    """
  Collect all the configurations from genconfig
  into a single place
  """
    dpH_total = []
    weight_total = []
    logweight_total = []
    distance_squared = []

    mol, wf, to_opt, freeze = wavefunction()

    eacc = EnergyAccumulator(mol)
    transform = LinearTransform(wf.parameters, to_opt, freeze)
    pgrad_bare = PGradTransform_new(eacc, transform, 1e-20)

    for i in range(1, n + 1):
        print(i)
        coords = OpenConfigs(pd.read_pickle('vmc/coords' + str(i) + '.pickle'))
        df = pd.read_json('vmc/evals' + str(i) + '.json')

        wf.recompute(coords)
        print("Recomputed")
        node_cut, r2 = pgrad_bare._node_cut(coords, wf)
        print("nodes cut")

        dpH = df['dpH'].values
        wfval = df['wfval'].values
        wfpval = df['wfpval'].values

        logweight = 2 * (wfval - wfpval)
        weight = np.exp(logweight)
        print(i, weight[weight == 0])

        dpH_total += list(dpH)
        weight_total += list(weight)
        logweight_total += list(logweight)
        distance_squared += list(r2)
        print(i, np.array(weight_total)[np.array(weight_total) == 0])

        df = pd.DataFrame({
            'dpH': dpH_total,
            'weight_total': weight_total,
            'logweight_total': logweight_total,
            'distance_squared': distance_squared
        })
        df.to_pickle(dump_file)
    return df
예제 #9
0
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
예제 #10
0
파일: optsr.py 프로젝트: krongch2/pyqmc
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')
예제 #11
0
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()
예제 #12
0
파일: __init__.py 프로젝트: jtkrogel/pyqmc
def gradient_generator(mol, wf, to_opt=None, **ewald_kwargs):
    return PGradTransform(EnergyAccumulator(mol, **ewald_kwargs),
                          LinearTransform(wf.parameters, to_opt))
예제 #13
0
파일: cvmc_h2.py 프로젝트: fieldplay/pyqmc
def setuph2(r, obdm_steps=5):
    from pyscf import gto, scf, lo
    from pyqmc.accumulators import LinearTransform, EnergyAccumulator
    from pyqmc.obdm import OBDMAccumulator
    from pyqmc.cvmc import DescriptorFromOBDM, PGradDescriptor

    import itertools

    # ccECP from A. Annaberdiyev et al. Journal of Chemical Physics 149, 134108 (2018)
    basis = {
        "H":
        gto.basis.parse("""
    H S
23.843185 0.00411490
10.212443 0.01046440
4.374164 0.02801110
1.873529 0.07588620
0.802465 0.18210620
0.343709 0.34852140
0.147217 0.37823130
0.063055 0.11642410
""")
    }
    """
H S
0.040680 1.00000000
H S
0.139013 1.00000000
H P
0.166430 1.00000000
H P
0.740212 1.00000000
"""
    ecp = {
        "H":
        gto.basis.parse_ecp("""
    H nelec 0
H ul
1 21.24359508259891 1.00000000000000
3 21.24359508259891 21.24359508259891
2 21.77696655044365 -10.85192405303825
""")
    }

    mol = gto.M(atom=f"H 0. 0. 0.; H 0. 0. {r}",
                unit="bohr",
                basis=basis,
                ecp=ecp,
                verbose=5)
    mf = scf.RHF(mol).run()
    mo_occ = mf.mo_coeff[:, mf.mo_occ > 0]
    a = lo.iao.iao(mol, mo_occ)
    a = lo.vec_lowdin(a, mf.get_ovlp())

    obdm_up = OBDMAccumulator(mol=mol, orb_coeff=a, nstep=obdm_steps, spin=0)
    obdm_down = OBDMAccumulator(mol=mol, orb_coeff=a, nstep=obdm_steps, spin=1)

    wf = pyqmc.slater_jastrow(mol, mf)

    freeze = {}
    for k in wf.parameters:
        freeze[k] = np.zeros(wf.parameters[k].shape, dtype='bool')
    print(freeze.keys())
    print(wf.parameters['wf1mo_coeff_alpha'])
    #this freezing allows us to easily go between bonding and
    # AFM configurations.
    freeze['wf1mo_coeff_alpha'][0, 0] = True
    freeze['wf1mo_coeff_beta'][1, 0] = True

    descriptors = {
        "t": [[(1.0, (0, 1)), (1.0, (1, 0))], [(1.0, (0, 1)), (1.0, (1, 0))]],
        "trace": [[(1.0, (0, 0)), (1.0, (1, 1))], [(1.0, (0, 0)),
                                                   (1.0, (1, 1))]],
    }
    for i in [0, 1]:
        descriptors[f"nup{i}"] = [[(1.0, (i, i))], []]
        descriptors[f"ndown{i}"] = [[], [(1.0, (i, i))]]

    acc = PGradDescriptor(
        EnergyAccumulator(mol),
        LinearTransform(wf.parameters, freeze=freeze),
        [obdm_up, obdm_down],
        DescriptorFromOBDM(descriptors, norm=2.0),
    )

    return {
        "wf": wf,
        "acc": acc,
        "mol": mol,
        "mf": mf,
        "descriptors": descriptors
    }
예제 #14
0
파일: dedp_vmc.py 프로젝트: sapatha2/cutoff
from wavefunction import wavefunction

if __name__ == '__main__':
    nconfig_per_core = 100
    ncore = 20
    nsteps = 2000000

    cutoffs = list(np.logspace(-8, -1, 20)) + list([
        0.05, 0.075, 0.11, 0.12, 0.13, 0.14, 0.15, 0.16, 0.17, 0.18, 0.19, 0.20
    ])
    cutoffs = np.sort(cutoffs)
    mol, mf, mc, wf, to_opt, freeze = wavefunction(return_mf=True)
    wf.parameters['wf1det_coeff'] *= 0
    wf.parameters['wf1det_coeff'][[0, 10]] = 1. / np.sqrt(2.)

    eacc = EnergyAccumulator(mol)
    transform = LinearTransform(wf.parameters, to_opt, freeze)
    pgrad = PGradTransform_new(eacc, transform, np.array(cutoffs))

    #Client
    cluster = LocalCluster(n_workers=ncore, threads_per_worker=1)
    client = Client(cluster)

    distvmc(wf,
            pyqmc.initial_guess(mol, nconfig_per_core * ncore),
            client=client,
            accumulators={"pgrad": pgrad},
            nsteps_per=100,
            nsteps=nsteps,
            hdf_file='dedp_vmc_local.hdf5')
예제 #15
0
파일: __init__.py 프로젝트: fieldplay/pyqmc
def gradient_generator(mol, wf, to_opt=None, freeze=None):
    return PGradTransform(EnergyAccumulator(mol),
                          LinearTransform(wf.parameters, to_opt, freeze))
예제 #16
0
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()
예제 #17
0
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
                     })