Exemplo n.º 1
0
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
Exemplo n.º 2
0
    def from_mean_field(self, cell, mf, twist=None):
        """
        mf is expected to be a KUHF, KRHF, or equivalent DFT objects.
        Selects occupied orbitals from a given twist
        If cell is a supercell, will automatically choose the folded k-points that correspond to that twist.
        """

        cell = (cell if hasattr(cell, "original_cell") else get_supercell(
            cell, np.asarray([[1, 0, 0], [0, 1, 0], [0, 0, 1]])))

        if twist is None:
            twist = np.zeros(3)
        else:
            twist = np.dot(np.linalg.inv(cell.a), np.mod(twist,
                                                         1.0)) * 2 * np.pi
        kinds = list(
            set(get_k_indices(cell, mf,
                              get_supercell_kpts(cell) + twist)))
        if len(kinds) != cell.scale:
            raise ValueError(
                "Did not find the right number of k-points for this supercell")

        detcoeff = np.array([1.0])
        det_map = np.array([[0], [0]])

        if len(mf.mo_coeff[0][0].shape) == 2:
            occup_k = [[[list(np.argwhere(mf.mo_occ[spin][k] > 0.5)[:, 0])]
                        for k in kinds] for spin in [0, 1]]
        elif len(mf.mo_coeff[0][0].shape) == 1:
            occup_k = [[[list(np.argwhere(mf.mo_occ[k] > 1.5 - spin)[:, 0])]
                        for k in kinds] for spin in [0, 1]]

        occup = [[], []]
        for spin in [0, 1]:
            count = 0
            for occ_k in occup_k[spin]:
                occup[spin] += [o + count for o in occ_k[0]]
                count += len(occ_k[0])

        kpts = mf.kpts[kinds]
        if len(mf.mo_coeff[0][0].shape) == 2:
            mo_coeff = [[
                mf.mo_coeff[spin][k][:, occup_k[spin][kinds.index(k)][0]]
                for k in kinds
            ] for spin in [0, 1]]
        elif len(mf.mo_coeff[0][0].shape) == 1:
            mo_coeff = [[
                mf.mo_coeff[k][:, occup_k[spin][kinds.index(k)][0]]
                for k in kinds
            ] for spin in [0, 1]]
        else:
            raise ValueError("Did not expect an scf object of type", type(mf))
        for s in [0, 1]:
            occup[s] = [occup[s]]
        return (
            detcoeff,
            occup,
            det_map,
            PBCOrbitalEvaluatorKpoints(cell, mo_coeff, kpts),
        )
Exemplo n.º 3
0
def get_ewald_energy(cell, S, configs):
    supercell = get_supercell(cell, S)
    ewald = pyqmc.ewald.Ewald(supercell)
    configs = PeriodicConfigs(configs, supercell.lattice_vectors())
    ee, ei, ii = ewald.energy(configs)
    etot = ee + ei + ii
    print(dict(ee=ee, ei=ei, ii=ii))
    print("total energy", etot)
    return etot
Exemplo n.º 4
0
    def __init__(
        self,
        mol,
        orb_coeff,
        spin,
        nsweeps=4,
        tstep=0.50,
        warmup=200,
        naux=None,
        ijkl=None,
        kpts=None,
    ):

        self._mol = mol
        self._tstep = tstep
        self._nsweeps = nsweeps
        self._spin = spin
        self._naux = naux
        self._warmup = warmup

        if kpts is None:
            self.orbitals = pyqmc.orbitals.MoleculeOrbitalEvaluator(mol, orb_coeff)
            norb_up = orb_coeff[0].shape[1]
            norb_down = orb_coeff[1].shape[1]
            if hasattr(mol, "a"):
                warnings.warn(
                    "Using molecular orbital evaluator for a periodic system. This is likely wrong unless you know what you're doing. Make sure to pass kpts into TBDM if you want to use the periodic orbital evaluator."
                )
        else:
            if not hasattr(mol, "original_cell"):
                mol = supercell.get_supercell(mol, np.eye(3))
            self.orbitals = pyqmc.orbitals.PBCOrbitalEvaluatorKpoints(
                mol, orb_coeff, kpts
            )
            norb_up = np.sum([o.shape[1] for o in orb_coeff[0]])
            norb_down = np.sum([o.shape[1] for o in orb_coeff[1]])

        self.dtype = complex if self.orbitals.iscomplex else float
        self._spin_sector = spin
        self._electrons = [
            np.arange(spin[s] * mol.nelec[0], mol.nelec[0] + spin[s] * mol.nelec[1])
            for s in [0, 1]
        ]

        # Default to full 2rdm if ijkl not specified
        if ijkl is None:
            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
        self._warmed_up = False
Exemplo n.º 5
0
    def from_mean_field(self,
                        cell,
                        mf,
                        twist=None,
                        determinants=None,
                        tol=None):
        """
        mf is expected to be a KUHF, KRHF, or equivalent DFT objects.
        Selects occupied orbitals from a given twist
        If cell is a supercell, will automatically choose the folded k-points that correspond to that twist.

        """

        cell = (cell
                if hasattr(cell, "original_cell") else supercell.get_supercell(
                    cell, np.asarray([[1, 0, 0], [0, 1, 0], [0, 0, 1]])))
        if twist is None:
            twist = np.zeros(3)
        else:
            twist = np.dot(np.linalg.inv(cell.a), np.mod(twist,
                                                         1.0)) * 2 * np.pi
        kinds = list(
            set(
                get_k_indices(cell, mf,
                              supercell.get_supercell_kpts(cell) + twist)))
        if len(kinds) != cell.scale:
            raise ValueError(
                f"Found {len(kinds)} k-points but should have found {cell.scale}."
            )
        kpts = mf.kpts[kinds]

        if determinants is None:
            determinants = [
                (1.0,
                 pyqmc.determinant_tools.create_pbc_determinant(cell, mf, []))
            ]

        mo_coeff, determinants_flat = select_orbitals_kpoints(
            determinants, mf, kinds)
        detcoeff, occup, det_map = pyqmc.determinant_tools.create_packed_objects(
            determinants_flat, format="list", tol=tol)
        # Check
        for s, (occ_s, nelec_s) in enumerate(zip(occup, cell.nelec)):
            for determinant in occ_s:
                if len(determinant) != nelec_s:
                    raise RuntimeError(
                        f"The number of electrons of spin {s} should be {nelec_s}, but found {len(determinant)} orbital[s]. You may have used a large smearing value.. Please pass your own determinants list. "
                    )

        return (
            detcoeff,
            occup,
            det_map,
            PBCOrbitalEvaluatorKpoints(cell, mo_coeff, kpts),
        )
Exemplo n.º 6
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 kpts is None:
            self.orbitals = MoleculeOrbitalEvaluator(mol,
                                                     [orb_coeff, orb_coeff])
        else:
            if not hasattr(mol, "original_cell"):
                mol = supercell.get_supercell(mol, np.eye(3))
            self.orbitals = PBCOrbitalEvaluatorKpoints(mol,
                                                       [orb_coeff, orb_coeff],
                                                       kpts)

        self._tstep = tstep
        self.nelec = len(self._electrons)
        self._nsweeps = nsweeps
        self._nstep = nsweeps * self.nelec
        self.norb = self.orbitals.parameters["mo_coeff_alpha"].shape[-1]

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

        accept, extra_configs, _ = sample_onebody(
            self._extra_config,
            self.orbitals,
            spin=0,
            nsamples=warmup,
            tstep=self._tstep,
        )
        self._extra_config = extra_configs[-1]
Exemplo n.º 7
0
    def __init__(
        self,
        mol,
        orb_coeff,
        spin,
        nsweeps=4,
        tstep=0.50,
        warmup=200,
        naux=500,
        ijkl=None,
        kpts=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._tstep = tstep
        self._nsweeps = nsweeps
        self._spin = spin

        if kpts is None:
            self.orbitals = MoleculeOrbitalEvaluator(mol, orb_coeff)
        else:
            if not hasattr(mol, "original_cell"):
                mol = supercell.get_supercell(mol, np.eye(3))
            self.orbitals = PBCOrbitalEvaluatorKpoints(mol, orb_coeff, kpts)

        self._spin_sector = spin
        self._electrons = [
            np.arange(spin[s] * mol.nelec[0],
                      mol.nelec[0] + spin[s] * mol.nelec[1]) for s in [0, 1]
        ]

        # Initialization and warmup of configurations
        nwalkers = int(naux / sum(self._mol.nelec))
        self._aux_configs = []
        for spin in [0, 1]:
            self._aux_configs.append(initial_guess(mol, nwalkers))
            self._aux_configs[spin].reshape((-1, 1, 3))
            _, self._aux_configs[spin], _ = sample_onebody(
                self._aux_configs[spin], self.orbitals, 0, nsamples=warmup)
            self._aux_configs[spin] = self._aux_configs[spin][-1]

        # 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
Exemplo n.º 8
0
def test_pbc(li_cubic_ccecp):
    from pyqmc import supercell
    import scipy

    mol, mf = li_cubic_ccecp

    # 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}"
Exemplo n.º 9
0
    def __init__(
        self,
        mol,
        orb_coeff,
        nsweeps=5,
        tstep=0.50,
        warmup=100,
        naux=None,
        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))

        if kpts is None:
            self.orbitals = pyqmc.orbitals.MoleculeOrbitalEvaluator(
                mol, [orb_coeff, orb_coeff]
            )
            if hasattr(mol, "a"):
                raise ValueError("kpts is required if the system is periodic")
        else:
            if not hasattr(mol, "original_cell"):
                mol = supercell.get_supercell(mol, np.eye(3))
            self.orbitals = pyqmc.orbitals.PBCOrbitalEvaluatorKpoints(
                mol, [orb_coeff, orb_coeff], kpts
            )

        self.iscomplex = self.orbitals.iscomplex

        self._tstep = tstep
        self.nelec = len(self._electrons)
        self._nsweeps = nsweeps
        self._nstep = nsweeps * self.nelec
        self._warmup = warmup
        self._naux = naux
        self._warmed_up = False
        self._mol = mol
        self.norb = self.orbitals.parameters["mo_coeff_alpha"].shape[-1]
Exemplo n.º 10
0
def test_RKS(kind=0, nk=(1, 1, 1)):
    L = 2
    mol = gto.M(
        atom="""He     {0}      {0}      {0}""".format(0.0),
        basis="sto-3g",
        a=np.eye(3) * L,
        unit="bohr",
    )
    kpts = mol.make_kpts(nk)
    mf = scf.KRKS(mol, kpts)
    mf.xc = "pbe"
    # mf = mf.density_fit()
    mf = mf.run()

    supercell = get_supercell(mol, np.diag(nk))
    runtest(supercell, mf, kind=kind)
Exemplo n.º 11
0
def noncubic(kind=0, nk=(1, 1, 1)):
    L = 3
    mol = gto.M(
        atom="""H     {0}      {0}      {0}                
                  H     {1}      {1}      {1}""".format(0.0, L / 4),
        basis="sto-3g",
        a=(np.ones((3, 3)) - np.eye(3)) * L / 2,
        spin=0,
        unit="bohr",
    )
    kpts = mol.make_kpts(nk)
    mf = scf.KUKS(mol, kpts)
    mf.xc = "pbe"
    # mf = mf.density_fit()
    mf = mf.run()
    supercell = get_supercell(mol, np.diag(nk))
    runtest(supercell, mf, kind=kind)
Exemplo n.º 12
0
    def from_mean_field(self, cell, mf, twist=None, determinants=None):
        """
        mf is expected to be a KUHF, KRHF, or equivalent DFT objects.
        Selects occupied orbitals from a given twist
        If cell is a supercell, will automatically choose the folded k-points that correspond to that twist.

        """

        cell = (
            cell
            if hasattr(cell, "original_cell")
            else supercell.get_supercell(
                cell, np.asarray([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
            )
        )
        if twist is None:
            twist = np.zeros(3)
        else:
            twist = np.dot(np.linalg.inv(cell.a), np.mod(twist, 1.0)) * 2 * np.pi
        kinds = list(
            set(get_k_indices(cell, mf, supercell.get_supercell_kpts(cell) + twist))
        )
        if len(kinds) != cell.scale:
            raise ValueError(
                f"Found {len(kinds)} k-points but should have found {cell.scale}."
            )
        kpts = mf.kpts[kinds]

        if determinants is None:
            determinants = [
                (1.0, pyqmc.determinant_tools.create_pbc_determinant(cell, mf, []))
            ]

        mo_coeff, determinants_flat = select_orbitals_kpoints(determinants, mf, kinds)
        detcoeff, occup, det_map = pyqmc.determinant_tools.create_packed_objects(
            determinants_flat, format="list"
        )

        return (
            detcoeff,
            occup,
            det_map,
            PBCOrbitalEvaluatorKpoints(cell, mo_coeff, kpts),
        )
Exemplo n.º 13
0
def initialize_qmc_objects(
    dft_checkfile,
    nconfig=1000,
    load_parameters=None,
    ci_checkfile=None,
    S=None,
    jastrow_kws=None,
    slater_kws=None,
    accumulators=None,
    opt_wf=False,
    target_root=0,
    nodal_cutoff=1e-3,
):
    if ci_checkfile is None:
        mol, mf = pyscftools.recover_pyscf(dft_checkfile)
        mc = None
    else:
        mol, mf, mc = pyscftools.recover_pyscf(dft_checkfile,
                                               ci_checkfile=ci_checkfile)
        mc.ci = mc.ci[target_root]

    if S is not None:
        mol = supercell.get_supercell(mol, np.asarray(S))

    wf, to_opt = wftools.generate_wf(mol,
                                     mf,
                                     mc=mc,
                                     jastrow_kws=jastrow_kws,
                                     slater_kws=slater_kws)
    if load_parameters is not None:
        wftools.read_wf(wf, load_parameters)

    configs = pyqmc.mc.initial_guess(mol, nconfig)
    if opt_wf:
        acc = pyqmc.accumulators.gradient_generator(mol,
                                                    wf,
                                                    to_opt,
                                                    nodal_cutoff=nodal_cutoff)
    else:
        if accumulators == None:
            accumulators = {}
        acc = generate_accumulators(mol, mf, **accumulators)

    return wf, configs, acc
Exemplo n.º 14
0
def multislater(kind=0, nk=(1, 1, 1)):
    L = 3
    mol = gto.Cell(
        atom="""H     {0}      {0}      {0}                
                  H     {1}      {1}      {1}""".format(0.0, L / 2),
        basis="cc-pvtz",
        spin=0,
        unit="bohr",
    )
    mol.exp_to_discard = 0.1
    mol.build(a=np.eye(3) * L)
    kpts = mol.make_kpts(nk)
    mf = scf.UKS(mol, (0, 0, 0))
    mf.xc = "pbe"
    mf = multigrid(mf)
    mf = remove_linear_dep_(mf)
    mf.chkfile = "h_bcc.chkfile"
    mf = mf.run()

    supercell = get_supercell(mol, np.diag(nk))
    runtest(supercell, mf, kind=kind, do_mc=True)
Exemplo n.º 15
0
def test_info_functions_pbc():
    from pyscf.pbc import gto, scf
    from pyqmc.supercell import get_supercell

    mol = gto.Cell(atom="He 0.00 0.00 0.00", basis="ccpvdz", unit="B")
    mol.a = 5.61 * np.eye(3)
    mol.build()

    mf = scf.KRHF(mol, kpts=mol.make_kpts([2, 2, 2])).density_fit()
    ehf = mf.kernel()

    supercell = get_supercell(mol, 2 * np.eye(3))
    kinds = [0, 1]
    dm_orbs = [mf.mo_coeff[i][:, :2] for i in kinds]
    wf, to_opt = pyqmc.default_sj(mol, mf)
    accumulators = {
        "pgrad": pyqmc.gradient_generator(mol, wf, to_opt, ewald_gmax=10),
        "obdm": OBDMAccumulator(mol, dm_orbs, kpts=mf.kpts[kinds]),
        "Sq": pyqmc.accumulators.SqAccumulator(mol.lattice_vectors()),
    }
    info_functions(mol, wf, accumulators)
Exemplo n.º 16
0
def cubic_with_ecp(kind=0, nk=(1, 1, 1)):
    from pyscf.pbc.dft.multigrid import multigrid

    start = time.time()
    L = 6.63
    mol = gto.Cell(
        atom="""Li     {0}      {0}      {0}                
                  Li     {1}      {1}      {1}""".format(0.0, L / 2),
        basis="bfd-vdz",
        ecp="bfd",
        spin=0,
        unit="bohr",
    )
    mol.exp_to_discard = 0.1
    mol.build(a=np.eye(3) * L)
    kpts = mol.make_kpts(nk)
    mf = scf.KUKS(mol, kpts)
    mf.xc = "pbe"
    # mf = mf.density_fit()
    mf = multigrid(mf)
    mf = mf.run()
    supercell = get_supercell(mol, np.diag(nk))
    runtest(supercell, mf, kind=kind)
Exemplo n.º 17
0
    kmf = scf.KRHF(cell, exxdiv=None).density_fit()
    kmf.kpts = cell.make_kpts([nk, nk, nk])
    ehf = kmf.kernel()
    print("EHF", ehf)
    return cell, kmf


if __name__ == "__main__":
    # Run SCF
    cell, kmf = run_scf(nk=2)

    # Set up wf and configs
    nconfig = 100
    S = np.eye(3) * 2  # 2x2x2 supercell
    supercell = get_supercell(cell, S)
    wf, to_opt = pyqmc.default_sj(supercell, kmf)
    configs = pyqmc.initial_guess(supercell, nconfig)

    # Initialize energy accumulator (and Ewald)
    pgrad = pyqmc.gradient_generator(supercell, wf, to_opt=to_opt)

    # Optimize jastrow
    wf, lm_df = pyqmc.line_minimization(wf,
                                        configs,
                                        pgrad,
                                        hdf_file="pbc_he_linemin.hdf",
                                        verbose=True)

    # Run VMC
    df, configs = pyqmc.vmc(
Exemplo n.º 18
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]
Exemplo n.º 19
0
def test_pbc():
    from pyscf.pbc import gto, scf
    from pyqmc import supercell
    import scipy

    lvecs = (np.ones((3, 3)) - 2 * 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)) - np.eye(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 = 800
    nsteps = 50
    warmup = 6
    wf = PySCFSlater(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,
    )

    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)

    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)