Example #1
0
    def __init__(
        self,
        mol,
        orb_coeff,
        nstep=10,
        tstep=0.50,
        warmup=100,
        naux=500,
        spin=None,
        electrons=None,
    ):
        assert (
            len(orb_coeff.shape) == 2
        ), "orb_coeff should be a list of orbital coefficients."

        if not (spin is None):
            if spin == 0:
                self._electrons = np.arange(0, mol.nelec[0])
            elif spin == 1:
                self._electrons = np.arange(mol.nelec[0], np.sum(mol.nelec))
            else:
                raise ValueError("Spin not equal to 0 or 1")
        elif not (electrons is None):
            self._electrons = electrons
        else:
            self._electrons = np.arange(0, np.sum(mol.nelec))

        self._orb_coeff = orb_coeff
        self._tstep = tstep
        self._mol = mol
        # self._extra_config = np.random.normal(scale=tstep,size=3) # not zero to avoid sitting on top of atom.
        nelec = sum(self._mol.nelec)
        self._extra_config = initial_guess(mol, int(naux / nelec) + 1).configs.reshape(
            -1, 3
        )

        self._nstep = nstep

        for i in range(warmup):
            accept, self._extra_config = sample_onebody(
                mol, orb_coeff, self._extra_config, tstep
            )
Example #2
0
def test_ecp():
    mol = gto.M(atom='''C 0 0 0 
       C 1 0 0 
    ''',
                ecp="bfd",
                basis="bfd_vtz")
    mf = scf.RHF(mol).run()
    nconf = 1000
    coords = initial_guess(mol, nconf)
    thresholds = [1e15, 100, 50, 20, 10, 5, 1]
    label = ['S', 'J', 'SJ']
    ind = 0
    for wf in [
            PySCFSlaterUHF(mol, mf),
            JastrowSpin(mol),
            MultiplyWF(PySCFSlaterUHF(mol, mf), JastrowSpin(mol))
    ]:
        wf.recompute(coords)
        print(label[ind])
        ind += 1
        for threshold in thresholds:
            eacc = EnergyAccumulator(mol, threshold)
            start = time.time()
            eacc(coords, wf)
            end = time.time()
            print('Threshold=', threshold, np.around(end - start, 2), 's')
    mc = mcscf.CASCI(mf, ncas=4, nelecas=(2, 2))
    mc.kernel()

    label = ['MS']
    ind = 0
    for wf in [MultiSlater(mol, mf, mc)]:
        wf.recompute(coords)
        print(label[ind])
        ind += 1
        for threshold in thresholds:
            eacc = EnergyAccumulator(mol, threshold)
            start = time.time()
            eacc(coords, wf)
            end = time.time()
            print('Threshold=', threshold, np.around(end - start, 2), 's')
Example #3
0
    def __init__(
        self,
        mol,
        orb_coeff,
        nsweeps=5,
        tstep=0.50,
        warmup=100,
        naux=500,
        spin=None,
        electrons=None,
    ):
        assert (len(orb_coeff.shape) == 2
                ), "orb_coeff should be a list of orbital coefficients."

        if not (spin is None):
            if spin == 0:
                self._electrons = np.arange(0, mol.nelec[0])
            elif spin == 1:
                self._electrons = np.arange(mol.nelec[0], np.sum(mol.nelec))
            else:
                raise ValueError("Spin not equal to 0 or 1")
        elif not (electrons is None):
            self._electrons = electrons
        else:
            self._electrons = np.arange(0, np.sum(mol.nelec))

        self._orb_coeff = orb_coeff
        self._tstep = tstep
        self._mol = mol

        nelec = len(self._electrons)
        self._extra_config = initial_guess(mol,
                                           int(naux / nelec) +
                                           1).configs.reshape(-1, 3)

        self._nsweeps = nsweeps
        self._nstep = nsweeps * nelec

        for i in range(warmup):
            accept, self._extra_config = sample_onebody(
                mol, orb_coeff, self._extra_config, tstep)
Example #4
0
def test():

    mol = gto.M(
        atom="Li 0. 0. 0.; Li 0. 0. 1.5", basis="sto-3g", unit="bohr", verbose=0
    )
    mf = scf.RHF(mol).run()

    # Lowdin orthogonalized AO basis.
    lowdin = lo.orth_ao(mol, "lowdin")

    # MOs in the Lowdin basis.
    mo = solve(lowdin, mf.mo_coeff)

    # make AO to localized orbital coefficients.
    mfobdm = mf.make_rdm1(mo, mf.mo_occ)

    ### Test OBDM calculation.
    nconf = 500
    nsteps = 400
    warmup = 15
    wf = Slater(mol, mf)
    configs = initial_guess(mol, nconf)
    obdm_dict = dict(mol=mol, orb_coeff=lowdin, nsweeps=5, warmup=15)
    obdm = OBDMAccumulator(**obdm_dict)
    obdm_up = OBDMAccumulator(**obdm_dict, spin=0)
    obdm_down = OBDMAccumulator(**obdm_dict, spin=1)

    df, coords = vmc(
        wf,
        configs,
        nsteps=nsteps,
        accumulators={"obdm": obdm, "obdm_up": obdm_up, "obdm_down": obdm_down},
    )
    obdm_est = {}
    for k in ["obdm", "obdm_up", "obdm_down"]:
        avg_norm = np.mean(df[k + "norm"][warmup:], axis=0)
        avg_obdm = np.mean(df[k + "value"][warmup:], axis=0)
        obdm_est[k] = normalize_obdm(avg_obdm, avg_norm)

    assert np.mean(np.abs(obdm_est["obdm_up"] + obdm_est["obdm_down"] - mfobdm)) < 0.05
Example #5
0
def test_accumulator():
    """Tests that the accumulator gets inserted into the data output correctly."""
    mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5",
                basis="cc-pvtz",
                unit="bohr",
                verbose=5)
    mf = scf.RHF(mol).run()
    nconf = 5000
    wf = Slater(mol, mf)
    coords = initial_guess(mol, nconf)

    df, coords = vmc(wf,
                     coords,
                     nsteps=30,
                     accumulators={"energy": EnergyAccumulator(mol)})
    df = pd.DataFrame(df)
    eaccum = EnergyAccumulator(mol)
    eaccum_energy = eaccum(coords, wf)
    df = pd.DataFrame(df)
    print(df["energytotal"][29] == np.average(eaccum_energy["total"]))

    assert df["energytotal"][29] == np.average(eaccum_energy["total"])
Example #6
0
def test_ecp_sj(C2_ccecp_rhf, nconf=10000):
    """test whether the cutoff saves us time without changing the energy too much.
    Because it's a stochastic evaluation, random choices can make a big difference, so we only require 10% agreement between these two."""
    mol, mf = C2_ccecp_rhf
    THRESHOLDS = [1e15, 10]

    np.random.seed(1234)
    coords = initial_guess(mol, nconf)
    wf = MultiplyWF(Slater(mol, mf), generate_jastrow(mol)[0])
    wf.recompute(coords)
    times = []
    energies = []
    for threshold in THRESHOLDS:
        np.random.seed(1234)
        eacc = EnergyAccumulator(mol, threshold)
        start = time.time()
        energy = eacc(coords, wf)
        end = time.time()
        times.append(end - start)
        energies.append(np.mean(energy["total"]))
    # print(times, energies)
    assert times[1] < times[0]
    assert (energies[1] - energies[0]) / energies[0] < 0.1
Example #7
0
def test_ecp():

    mol = gto.M(atom="C 0. 0. 0.", ecp="bfd", basis="bfd_vtz")
    mf = scf.RHF(mol).run()
    nconf = 5000
    wf = Slater(mol, mf)
    coords = initial_guess(mol, nconf)
    df, coords = vmc(wf,
                     coords,
                     nsteps=100,
                     accumulators={"energy": EnergyAccumulator(mol)})
    df = pd.DataFrame(df)
    warmup = 30
    print(
        "mean field",
        mf.energy_tot(),
        "vmc estimation",
        np.mean(df["energytotal"][warmup:]),
        np.std(df["energytotal"][warmup:]),
    )

    assert abs(mf.energy_tot() -
               np.mean(df["energytotal"][warmup:])) <= np.std(
                   df["energytotal"][warmup:])
Example #8
0
def test_vmc(C2_ccecp_rhf):
    """
    Test that a VMC calculation of a Slater determinant matches Hartree-Fock within error bars.
    """
    mol, mf = C2_ccecp_rhf
    nconf = 500
    nsteps = 300
    warmup = 30

    wf = Slater(mol, mf)
    coords = initial_guess(mol, nconf)
    df, coords = vmc(
        wf,
        coords,
        nblocks=int(nsteps / 30),
        nsteps_per_block=30,
        accumulators={"energy": EnergyAccumulator(mol)},
    )

    df = pd.DataFrame(df)["energytotal"][int(warmup / 30):]
    en = df.mean()
    err = df.sem()
    assert en - mf.energy_tot(
    ) < 5 * err, "pyscf {0}, vmc {1}, err {2}".format(mf.energy_tot(), en, err)
Example #9
0
def test(atom="He", total_spin=0, total_charge=0, scf_basis="sto-3g"):
    mol = gto.M(
        atom="%s 0. 0. 0.; %s 0. 0. 1.5" % (atom, atom),
        basis=scf_basis,
        unit="bohr",
        verbose=4,
        spin=total_spin,
        charge=total_charge,
    )
    mf = scf.UHF(mol).run()
    # Intrinsic Atomic Orbitals
    iaos = make_separate_spin_iaos(
        mol, mf, np.array([i for i in range(mol.natm)]), iao_basis="minao"
    )
    # iaos=make_combined_spin_iaos(mol,mf,np.array([i for i in range(mol.natm)]),iao_basis='minao')
    # MOs in the IAO basis
    mo = reps_combined_spin_iaos(
        iaos,
        mf,
        np.einsum("i,j->ji", np.arange(mf.mo_coeff[0].shape[1]), np.array([1, 1])),
    )
    # Mean-field obdm in IAO basis
    mfobdm = mf.make_rdm1(mo, mf.mo_occ)
    # Mean-field tbdm in IAO basis
    mftbdm = singledet_tbdm(mf, mfobdm)

    ### Test TBDM calculation.
    # VMC params
    nconf = 500
    n_vmc_steps = 400
    vmc_tstep = 0.3
    vmc_warmup = 30
    # TBDM params
    tbdm_sweeps = 4
    tbdm_tstep = 0.5

    wf = PySCFSlater(mol, mf)  # Single-Slater (no jastrow) wf
    configs = initial_guess(mol, nconf)
    energy = EnergyAccumulator(mol)
    obdm_up = OBDMAccumulator(mol=mol, orb_coeff=iaos[0], nsweeps=tbdm_sweeps, spin=0)
    obdm_down = OBDMAccumulator(mol=mol, orb_coeff=iaos[1], nsweeps=tbdm_sweeps, spin=1)
    tbdm_upup = TBDMAccumulator(
        mol=mol, orb_coeff=iaos, nsweeps=tbdm_sweeps, tstep=tbdm_tstep, spin=(0, 0)
    )
    tbdm_updown = TBDMAccumulator(
        mol=mol, orb_coeff=iaos, nsweeps=tbdm_sweeps, tstep=tbdm_tstep, spin=(0, 1)
    )
    tbdm_downup = TBDMAccumulator(
        mol=mol, orb_coeff=iaos, nsweeps=tbdm_sweeps, tstep=tbdm_tstep, spin=(1, 0)
    )
    tbdm_downdown = TBDMAccumulator(
        mol=mol, orb_coeff=iaos, nsweeps=tbdm_sweeps, tstep=tbdm_tstep, spin=(1, 1)
    )

    print("VMC...")
    df, coords = vmc(
        wf,
        configs,
        nsteps=n_vmc_steps,
        tstep=vmc_tstep,
        accumulators={
            "energy": energy,
            "obdm_up": obdm_up,
            "obdm_down": obdm_down,
            "tbdm_upup": tbdm_upup,
            "tbdm_updown": tbdm_updown,
            "tbdm_downup": tbdm_downup,
            "tbdm_downdown": tbdm_downdown,
        },
        verbose=True,
    )

    # Compares obdm from QMC and MF
    obdm_est = {}
    for k in ["obdm_up", "obdm_down"]:
        avg_norm = np.mean(df[k + "norm"][vmc_warmup:], axis=0)
        avg_obdm = np.mean(df[k + "value"][vmc_warmup:], axis=0)
        obdm_est[k] = normalize_obdm(avg_obdm, avg_norm)
    qmcobdm = np.array([obdm_est["obdm_up"], obdm_est["obdm_down"]])
    print("\nComparing QMC and MF obdm:")
    for s in [0, 1]:
        # print('QMC obdm[%d]:\n'%s,qmcobdm[s])
        # print('MF obdm[%d]:\n'%s,mfobdm[s])
        print("diff[%d]:\n" % s, qmcobdm[s] - mfobdm[s])

    # Compares tbdm from QMC and MF
    avg_norm = {}
    avg_tbdm = {}
    tbdm_est = {}
    for t in ["tbdm_upup", "tbdm_updown", "tbdm_downup", "tbdm_downdown"]:
        for k in df.keys():
            if k.startswith(t + "norm_"):
                avg_norm[k.split("_")[-1]] = np.mean(df[k][vmc_warmup:], axis=0)
            if k.startswith(t + "value"):
                avg_tbdm[k.split("_")[-1]] = np.mean(df[k][vmc_warmup:], axis=0)
    for k in avg_tbdm:
        tbdm_est[k] = normalize_tbdm(
            avg_tbdm[k].reshape(2, 2, 2, 2), avg_norm["a"], avg_norm["b"]
        )
    qmctbdm = np.array(
        [
            [tbdm_est["upupvalue"], tbdm_est["updownvalue"]],
            [tbdm_est["downupvalue"], tbdm_est["downdownvalue"]],
        ]
    )
    print("\nComparing QMC and MF tbdm:")
    for sa, sb in [[0, 0], [0, 1], [1, 0], [1, 1]]:
        # print('QMC tbdm[%d,%d]:\n'%(sa,sb),qmctbdm[sa,sb])
        # print('MF tbdm[%d,%d]:\n'%(sa,sb),mftbdm[sa,sb])
        diff = qmctbdm[sa, sb] - mftbdm[sa, sb]
        print("diff[%d,%d]:\n" % (sa, sb), diff)
        assert np.max(np.abs(diff)) < 0.05
Example #10
0
    def __init__(
        self,
        mol,
        orb_coeff,
        spin,
        nsweeps=4,
        tstep=0.50,
        warmup=200,
        naux=500,
        ijkl=None,
    ):
        assert (
            len(orb_coeff.shape) == 3
        ), "orb_coeff should be a list of orbital coefficients with size (2,num_mobasis,num_orb)."

        self._mol = mol
        self._orb_coeff = orb_coeff
        self._tstep = tstep
        self._nsweeps = nsweeps
        self._spin = spin

        self._spin_sector = spin
        self._electrons_a = np.arange(
            spin[0] * mol.nelec[0], mol.nelec[0] + spin[0] * mol.nelec[1]
        )
        self._electrons_b = np.arange(
            spin[1] * mol.nelec[0], mol.nelec[0] + spin[1] * mol.nelec[1]
        )
        self._pairs = np.array(
            np.meshgrid(self._electrons_a, self._electrons_b)
        ).T.reshape(-1, 2)
        self._pairs = self._pairs[
            self._pairs[:, 0] != self._pairs[:, 1]
        ]  # Removes repeated electron pairs

        # Initialization and warmup of aux_configs_a
        self._aux_configs_a = initial_guess(
            mol, int(naux / sum(self._mol.nelec))
        ).configs.reshape(-1, 3)
        for i in range(warmup):
            accept_a, self._aux_configs_a = sample_onebody(
                mol, orb_coeff[self._spin_sector[0]], self._aux_configs_a, tstep
            )
        # Initialization and warmup of aux_configs_b
        self._aux_configs_b = initial_guess(
            mol, int(naux / sum(self._mol.nelec))
        ).configs.reshape(-1, 3)
        for i in range(warmup):
            accept_b, self._aux_configs_b = sample_onebody(
                mol, orb_coeff[self._spin_sector[1]], self._aux_configs_b, tstep
            )
        # Default to full 2rdm if ijkl not specified
        if ijkl is None:
            norb_up = orb_coeff[0].shape[1]
            norb_down = orb_coeff[1].shape[1]
            ijkl = [
                [i, j, k, l]
                for i in range(norb_up)
                for j in range(norb_up)
                for k in range(norb_down)
                for l in range(norb_down)
            ]
        self._ijkl = np.array(ijkl).T
Example #11
0
def test_pbc():
    from pyscf.pbc import gto, scf
    from pyqmc import PySCFSlaterUHF, PySCFSlaterPBC
    from pyqmc import slaterpbc
    import scipy

    lvecs = (np.ones((3, 3)) - np.eye(3)) * 2.0
    mol = gto.M(
        atom="H 0. 0. -{0}; H 0. 0. {0}".format(0.7),
        basis="sto-3g",
        unit="bohr",
        verbose=0,
        a=lvecs,
    )
    mf = scf.KRHF(mol, kpts=mol.make_kpts((2, 2, 2)))
    mf = mf.run()

    S = np.ones((3, 3)) - 2 * np.eye(3)
    mol = slaterpbc.get_supercell(mol, S)
    kpts = slaterpbc.get_supercell_kpts(mol)[:2]
    kdiffs = mf.kpts[np.newaxis] - kpts[:, np.newaxis]
    kinds = np.nonzero(np.linalg.norm(kdiffs, axis=-1) < 1e-12)[1]

    # Lowdin orthogonalized AO basis.
    # lowdin = lo.orth_ao(mol, "lowdin")
    loiao = lo.iao.iao(mol.original_cell, mf.mo_coeff, kpts=kpts)
    occs = [mf.mo_occ[k] for k in kinds]
    coefs = [mf.mo_coeff[k] for k in kinds]
    ovlp = mf.get_ovlp()[kinds]
    lowdin = [lo.vec_lowdin(l, o) for l, o in zip(loiao, ovlp)]
    lreps = [np.linalg.multi_dot([l.T, o, c]) for l, o, c in zip(lowdin, ovlp, coefs)]

    # make AO to localized orbital coefficients.
    mfobdm = [np.einsum("ij,j,kj->ik", l.conj(), o, l) for l, o in zip(lreps, occs)]

    ### Test OBDM calculation.
    nconf = 800
    nsteps = 50
    warmup = 6
    wf = PySCFSlaterPBC(mol, mf)
    configs = initial_guess(mol, nconf)
    obdm_dict = dict(mol=mol, orb_coeff=lowdin, kpts=kpts, nsweeps=4, warmup=10)
    obdm = OBDMAccumulator(**obdm_dict)
    obdm_up = OBDMAccumulator(**obdm_dict, spin=0)
    obdm_down = OBDMAccumulator(**obdm_dict, spin=1)

    df, coords = vmc(
        wf,
        configs,
        nsteps=nsteps,
        accumulators={"obdm": obdm, "obdm_up": obdm_up, "obdm_down": obdm_down},
        verbose=True,
    )
    df = DataFrame(df)

    obdm_est = {}
    for k in ["obdm", "obdm_up", "obdm_down"]:
        avg_norm = np.array(df.loc[warmup:, k + "norm"].values.tolist()).mean(axis=0)
        avg_obdm = np.array(df.loc[warmup:, k + "value"].values.tolist()).mean(axis=0)
        obdm_est[k] = normalize_obdm(avg_obdm, avg_norm)

    print("Average OBDM(orb,orb)", obdm_est["obdm"].round(3))
    mfobdm = scipy.linalg.block_diag(*mfobdm)
    print("mf obdm", mfobdm.round(3))
    max_abs_err = np.max(np.abs(obdm_est["obdm"] - mfobdm))
    assert max_abs_err < 0.05, "max abs err {0}".format(max_abs_err)
    print(obdm_est["obdm_up"].diagonal().round(3))
    print(obdm_est["obdm_down"].diagonal().round(3))
    mae = np.mean(np.abs(obdm_est["obdm_up"] + obdm_est["obdm_down"] - mfobdm))
    maup = np.mean(np.abs(obdm_est["obdm_up"]))
    madn = np.mean(np.abs(obdm_est["obdm_down"]))
    mamf = np.mean(np.abs(mfobdm))
    assert mae < 0.05, "mae {0}\n maup {1}\n madn {2}\n mamf {3}".format(
        mae, maup, madn, mamf
    )
Example #12
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
Example #13
0
    def __init__(
        self,
        mol,
        orb_coeff,
        nsweeps=5,
        tstep=0.50,
        warmup=100,
        naux=500,
        spin=None,
        electrons=None,
        kpts=None,
    ):

        if spin is not None:
            if spin == 0:
                self._electrons = np.arange(0, mol.nelec[0])
            elif spin == 1:
                self._electrons = np.arange(mol.nelec[0], np.sum(mol.nelec))
            else:
                raise ValueError("Spin not equal to 0 or 1")
        elif electrons is not None:
            self._electrons = electrons
        else:
            self._electrons = np.arange(0, np.sum(mol.nelec))

        self.iscomplex = bool(sum(map(np.iscomplexobj, orb_coeff)))
        if hasattr(mol, "lattice_vectors"):
            assert kpts is not None
            assert len(orb_coeff) == len(kpts)
            self.iscomplex = self.iscomplex or np.linalg.norm(kpts) > 1e-12
            self._kpts = kpts
            self.evaluate_orbitals = self._evaluate_orbitals_pbc
            if self.iscomplex:
                self.get_wrapphase = slater.get_wrapphase_complex
            else:
                self.get_wrapphase = slater.get_wrapphase_real
            for attribute in ["original_cell", "S"]:
                if not hasattr(mol, attribute):
                    from pyqmc.supercell import get_supercell

                    mol = get_supercell(mol, np.eye(3))
            self.supercell = mol
            self._mol = mol.original_cell
        else:
            self._mol = mol
            self.evaluate_orbitals = self._evaluate_orbitals
            assert (len(orb_coeff.shape) == 2
                    ), "orb_coeff should be a list of orbital coefficients."

        self._orb_coeff = orb_coeff
        if hasattr(self._orb_coeff, "shape"):
            self.norb = self._orb_coeff.shape[1]
        else:
            self.norb = sum(c.shape[1] for c in self._orb_coeff)
        self._tstep = tstep
        self.nelec = len(self._electrons)
        self._nsweeps = nsweeps
        self._nstep = nsweeps * self.nelec

        self._extra_config = initial_guess(mol, int(naux / self.nelec) + 1)
        self._extra_config.reshape((-1, 3))

        accept, extra_configs = self.sample_onebody(self._extra_config, warmup)
        self._extra_config = extra_configs[-1]
Example #14
0
def test():

    mol = gto.M(atom="Li 0. 0. 0.; Li 0. 0. 1.5",
                basis="sto-3g",
                unit="bohr",
                verbose=0)
    mf = scf.RHF(mol).run()

    # Lowdin orthogonalized AO basis.
    lowdin = lo.orth_ao(mol, "lowdin")

    # MOs in the Lowdin basis.
    mo = solve(lowdin, mf.mo_coeff)

    # make AO to localized orbital coefficients.
    mfobdm = mf.make_rdm1(mo, mf.mo_occ)

    ### Test OBDM calculation.
    nconf = 500
    nsteps = 400
    obdm_steps = 4
    warmup = 15
    wf = PySCFSlaterUHF(mol, mf)
    configs = initial_guess(mol, nconf)
    energy = EnergyAccumulator(mol)
    obdm = OBDMAccumulator(mol=mol, orb_coeff=lowdin, nstep=obdm_steps)
    obdm_up = OBDMAccumulator(mol=mol,
                              orb_coeff=lowdin,
                              nstep=obdm_steps,
                              spin=0)
    obdm_down = OBDMAccumulator(mol=mol,
                                orb_coeff=lowdin,
                                nstep=obdm_steps,
                                spin=1)

    df, coords = vmc(
        wf,
        configs,
        nsteps=nsteps,
        accumulators={
            "energy": energy,
            "obdm": obdm,
            "obdm_up": obdm_up,
            "obdm_down": obdm_down,
        },
    )
    df = DataFrame(df)

    obdm_est = {}
    for k in ["obdm", "obdm_up", "obdm_down"]:
        avg_norm = np.array(df.loc[warmup:,
                                   k + "norm"].values.tolist()).mean(axis=0)
        avg_obdm = np.array(df.loc[warmup:,
                                   k + "value"].values.tolist()).mean(axis=0)
        obdm_est[k] = normalize_obdm(avg_obdm, avg_norm)

    print("Average OBDM(orb,orb)", obdm_est["obdm"].diagonal().round(3))
    print("mf obdm", mfobdm.diagonal().round(3))
    assert np.max(np.abs(obdm_est["obdm"] - mfobdm)) < 0.05
    print(obdm_est["obdm_up"].diagonal().round(3))
    print(obdm_est["obdm_down"].diagonal().round(3))
    assert np.max(
        np.abs(obdm_est["obdm_up"] + obdm_est["obdm_down"] - mfobdm)) < 0.05
Example #15
0
def test():
    from pyscf import gto, scf, lo
    from numpy.linalg import solve
    from pyqmc.slater import PySCFSlaterRHF
    from pyqmc.mc import initial_guess, vmc
    from pyqmc.accumulators import EnergyAccumulator
    from pandas import DataFrame

    ### Generate some basic objects.
    # Simple Li2 run.
    mol = gto.M(atom='Li 0. 0. 0.; Li 0. 0. 1.5',
                basis='sto-3g',
                unit='bohr',
                verbose=0)
    mf = scf.RHF(mol).run()

    # Lowdin orthogonalized AO basis.
    lowdin = lo.orth_ao(mol, 'lowdin')

    # MOs in the Lowdin basis.
    mo = solve(lowdin, mf.mo_coeff)

    # make AO to localized orbital coefficients.
    mfobdm = mf.make_rdm1(mo, mf.mo_occ)

    #print(mfobdm.diagonal().round(2))

    ### Test one-body sampler.
    #test_sample_onebody(mol,lowdin,mf,nsample=int(1e4))
    #test_sample_onebody(mol,lowdin,mf,nsample=int(4e4))
    #test_sample_onebody(mol,lowdin,mf,nsample=int(1e5))

    ### Test OBDM calculation.
    nconf = 500
    nsteps = 400
    obdm_steps = 2
    warmup = 15
    wf = PySCFSlaterRHF(mol, mf)
    configs = initial_guess(mol, nconf)
    energy = EnergyAccumulator(mol)
    obdm = OBDMAccumulator(mol=mol, orb_coeff=mf.mo_coeff, nstep=obdm_steps)
    df, coords = vmc(wf,
                     configs,
                     nsteps=nsteps,
                     accumulators={
                         'energy': energy,
                         'obdm': obdm
                     })
    df = DataFrame(df)
    df['obdm'] = df[['obdmvalue','obdmnorm']]\
        .apply(lambda x:normalize_obdm(x['obdmvalue'],x['obdmnorm']),axis=1)
    print(df[['obdmvalue', 'obdmnorm',
              'obdm']].applymap(lambda x: x.ravel()[0]))
    avg_norm = np.array(df.loc[warmup:,
                               'obdmnorm'].values.tolist()).mean(axis=0)
    avg_obdm = np.array(df.loc[warmup:, 'obdm'].values.tolist()).mean(axis=0)
    std_obdm = np.array(
        df.loc[warmup:, 'obdm'].values.tolist()).std(axis=0) / nsteps**0.5
    print("Average norm(orb)", avg_norm)
    print("Average OBDM(orb,orb)", avg_obdm.diagonal().round(3))
    print("OBDM error (orb,orb)",
          std_obdm.diagonal().round(
              3))  # Note this needs reblocking to be accurate.
    print("AO occupation", mfobdm[0, 0])
    print('mean field', mf.energy_tot(), 'vmc estimation',
          np.mean(df['energytotal'][warmup:]),
          np.std(df['energytotal'][warmup:]))
Example #16
0
def test_pbc(h_noncubic_sto3g):
    # from pyscf.pbc import gto, scf
    from pyqmc import supercell
    import scipy

    mol, mf = h_noncubic_sto3g

    # S = np.ones((3, 3)) - np.eye(3)
    S = np.identity(3)
    mol = supercell.get_supercell(mol, S)
    kpts = supercell.get_supercell_kpts(mol)[:2]
    kdiffs = mf.kpts[np.newaxis] - kpts[:, np.newaxis]
    kinds = np.nonzero(np.linalg.norm(kdiffs, axis=-1) < 1e-12)[1]

    # Lowdin orthogonalized AO basis.
    # lowdin = lo.orth_ao(mol, "lowdin")
    loiao = lo.iao.iao(mol.original_cell, mf.mo_coeff, kpts=kpts)
    occs = [mf.mo_occ[k] for k in kinds]
    coefs = [mf.mo_coeff[k] for k in kinds]
    ovlp = mf.get_ovlp()[kinds]
    lowdin = [lo.vec_lowdin(l, o) for l, o in zip(loiao, ovlp)]
    lreps = [
        np.linalg.multi_dot([l.T, o, c])
        for l, o, c in zip(lowdin, ovlp, coefs)
    ]

    # make AO to localized orbital coefficients.
    mfobdm = [
        np.einsum("ij,j,kj->ik", l.conj(), o, l) for l, o in zip(lreps, occs)
    ]

    ### Test OBDM calculation.
    nconf = 500
    nsteps = 100
    warmup = 6
    wf = Slater(mol, mf)
    configs = initial_guess(mol, nconf)
    obdm_dict = dict(mol=mol,
                     orb_coeff=lowdin,
                     kpts=kpts,
                     nsweeps=4,
                     warmup=10)
    obdm = OBDMAccumulator(**obdm_dict)

    df, coords = vmc(
        wf,
        configs,
        nsteps=nsteps,
        accumulators={"obdm":
                      obdm},  # , "obdm_up": obdm_up, "obdm_down": obdm_down},
        verbose=True,
    )

    obdm_est = {}
    for k in ["obdm"]:  # , "obdm_up", "obdm_down"]:
        avg_norm = np.mean(df[k + "norm"][warmup:], axis=0)
        avg_obdm = np.mean(df[k + "value"][warmup:], axis=0)
        obdm_est[k] = normalize_obdm(avg_obdm, avg_norm)

    mfobdm = scipy.linalg.block_diag(*mfobdm)

    mae = np.mean(np.abs(obdm_est["obdm"] - mfobdm))
    assert mae < 0.05, f"mae {mae}"