예제 #1
0
def wavefunction(return_mf = False):
    """
    Returns Full CI wave function 
    multiplied by a Jastrow with cusp conditions applied 
    """

    from pyqmc import default_msj, default_multislater
    mol = gto.M(atom="Li 0. 0. 0.; H 0. 0. 3.015", basis='cc-pvqz', unit="bohr", spin=0)
    mf = scf.ROHF(mol).run()
    mc = mcscf.CASCI(mf,ncas=6,nelecas=(2,2))
    mc.kernel()
   
    wf, to_opt, freeze = default_msj(mol, mf, mc)

    #Only need to take derivatives wrt determinant coefficients
    to_opt = ['wf1det_coeff'] 
    freeze = {'wf1det_coeff': freeze['wf1det_coeff']}

    #Only need to take derivatives wrt the highest energy det
    #, will have least overlap with nodes!
    freeze = {'wf1det_coeff': np.ones(freeze['wf1det_coeff'].shape).astype(bool)}
    freeze['wf1det_coeff'][10] = False

    wf.parameters['wf1det_coeff'] *= 0
    wf.parameters['wf1det_coeff'][[0,10]] = 1./np.sqrt(2.)

    if(return_mf): return mol, mf, mc, wf, to_opt, freeze
    else: return mol, wf, to_opt, freeze
예제 #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 pyqmc_from_hdf(chkfile):
    """ Loads pyqmc objects from a pyscf checkfile """
    mol = lib.chkfile.load_mol(chkfile)
    mol.output = None
    mol.stdout = None

    mf = scf.RHF(mol)
    mf.__dict__.update(scf.chkfile.load(chkfile, "scf"))
    with h5py.File(chkfile, "r") as f:
        mc = mcscf.CASCI(mf,
                         ncas=int(f["mc/ncas"][...]),
                         nelecas=f["mc/nelecas"][...])
        mc.ci = f["mc/ci"][...]

    wf, to_opt, freeze = pyqmc.default_msj(mol, mf, mc)

    freeze["wf1det_coeff"][...] = False
    pgrad = pyqmc.gradient_generator(mol, wf, to_opt, freeze)

    return {
        "mol": mol,
        "mf": mf,
        "to_opt": to_opt,
        "freeze": freeze,
        "wf": wf,
        "pgrad": pgrad,
    }
예제 #4
0
def gen_wf(chkfile, casfile, root_weights):
    mol = pyscf.lib.chkfile.load_mol(chkfile)
    mol.output = None
    mol.stdout = None

    mf = pyscf.scf.RHF(mol)
    mf.__dict__.update(pyscf.scf.chkfile.load(chkfile, "scf"))

    with h5py.File(casfile, "r") as f:
        mc = pyscf.mcscf.CASCI(mf, ncas=int(f["ncas"][...]), nelecas=f["nelecas"][...])
        mc.ci = f["ci"][0, ...]
        mc.ci=0.0
        for root, weight in root_weights.items():
            mc.ci+=weight*f['ci'][root, ...]

    wf, to_opt, freeze = pyqmc.default_msj(mol, mf, mc, ion_cusp=True)

    return {
        "mol":mol,
        "mf":mf,
        "mc":mc,
        "freeze":freeze,
        "to_opt":to_opt,
        "wf":wf
    }
예제 #5
0
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)
예제 #6
0
def test():
    """ 
    Tests that the multi-slater wave function value, gradient and 
    parameter gradient evaluations are working correctly. Also 
    checks that VMC energy matches energy calculated in PySCF
    """
    mol = gto.M(atom="Li 0. 0. 0.; H 0. 0. 1.5",
                basis="cc-pvtz",
                unit="bohr",
                spin=0)
    epsilon = 1e-4
    delta = 1e-5
    nsteps = 200
    warmup = 10
    for mf in [scf.RHF(mol).run(), scf.ROHF(mol).run(), scf.UHF(mol).run()]:
        # Test same number of elecs
        mc = mcscf.CASCI(mf, ncas=4, nelecas=(1, 1))
        mc.kernel()
        wf = MultiSlater(mol, mf, mc)

        nconf = 10

        nelec = np.sum(mol.nelec)
        epos = initial_guess(mol, nconf)

        for k, item in testwf.test_updateinternals(wf, epos).items():
            assert item < epsilon
        assert testwf.test_wf_gradient(wf, epos, delta=delta)[0] < epsilon
        assert testwf.test_wf_laplacian(wf, epos, delta=delta)[0] < epsilon
        assert testwf.test_wf_pgradient(wf, epos, delta=delta)[0] < epsilon

        # Test same number of elecs
        mc = mcscf.CASCI(mf, ncas=4, nelecas=(1, 1))
        mc.kernel()
        wf = pyqmc.default_msj(mol, mf, mc)[0]

        nelec = np.sum(mol.nelec)
        epos = initial_guess(mol, nconf)

        for k, item in testwf.test_updateinternals(wf, epos).items():
            assert item < epsilon
        assert testwf.test_wf_gradient(wf, epos, delta=delta)[0] < epsilon
        assert testwf.test_wf_laplacian(wf, epos, delta=delta)[0] < epsilon
        assert testwf.test_wf_pgradient(wf, epos, delta=delta)[0] < epsilon

        # Test different number of elecs
        mc = mcscf.CASCI(mf, ncas=4, nelecas=(2, 0))
        mc.kernel()
        wf = MultiSlater(mol, mf, mc)

        nelec = np.sum(mol.nelec)
        epos = initial_guess(mol, nconf)

        for k, item in testwf.test_updateinternals(wf, epos).items():
            assert item < epsilon
        assert testwf.test_wf_gradient(wf, epos, delta=delta)[0] < epsilon
        assert testwf.test_wf_laplacian(wf, epos, delta=delta)[0] < epsilon
        assert testwf.test_wf_pgradient(wf, epos, delta=delta)[0] < epsilon

        # Quick VMC test
        nconf = 1000
        coords = initial_guess(mol, nconf)
        df, coords = vmc(wf,
                         coords,
                         nsteps=nsteps,
                         accumulators={"energy": EnergyAccumulator(mol)})

        df = pd.DataFrame(df)
        df = reblock(df["energytotal"][warmup:], 20)
        en = df.mean()
        err = df.sem()
        assert en - mc.e_tot < 5 * err