Beispiel #1
0
def test_enforce_pbcs():

    # TEST 1: Check if any electron in new config
    #         is out of the simulation box for set
    #         of non-orthogonal lattice vectors. We
    #         do a controlled comparison between
    #         initial configs and final ones.
    nconf = 7
    lattvecs = np.array([[1.2, 0, 0], [0.6, 1.2 * np.sqrt(3) / 2, 0],
                         [0, 0, 0.8]])  # Triangular lattice
    trans = np.array([[0.1, 0.1, 0.1], [1.3, 0, 0.2],
                      [0.9, 1.8 * np.sqrt(3) / 2, 0], [0, 0, 1.1],
                      [2.34, 1.35099963, 0], [0.48, 1.24707658, 0],
                      [-2.52, 2.28630707, -0.32]])
    check_final = np.array([[0.1, 0.1, 0.1], [0.1, 0, 0.2],
                            [0.3, 0.6 * np.sqrt(3) / 2, 0.], [0, 0, 0.3],
                            [0.54, 0.31176915, 0], [1.08, 0.2078461, 0],
                            [1.08, 0.2078461, 0.48]])
    check_wrap = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1],
                           [1, 1, 0], [-1, 1, 0], [-4, 2, -1]])
    final_trans, final_wrap = enforce_pbc(lattvecs, trans)
    # Checks output configs
    relative_tol = 1e-8
    absolute_tol = 1e-8
    test1a = np.all(
        np.isclose(final_trans,
                   check_final,
                   rtol=relative_tol,
                   atol=absolute_tol))
    # Checks wraparound matrix
    test1b = np.all(
        np.isclose(final_wrap,
                   check_wrap,
                   rtol=relative_tol,
                   atol=absolute_tol))
    test1 = test1a * test1b
    print('Test 1 success:', test1)

    # TEST 2: Check if any electron in new config
    #         is out of the simulation box for set
    #         of non-orthogonal lattice vectors.
    nconf = 50
    lattvecs = np.array([[1.2, 0, 0], [0.6, 1.2 * np.sqrt(3) / 2, 0],
                         [0, 0, 0.8]])  # Triangular lattice
    recpvecs = np.linalg.inv(lattvecs)
    # Old config
    epos = np.random.random((nconf, 3))
    epos = np.einsum('ij,jk->ik', epos, lattvecs)
    # New config
    step = 0.5
    trans = epos + step * (np.random.random((nconf, 3)) - 0.5 * np.ones(
        (nconf, 3)))
    final_trans, wrap = enforce_pbc(lattvecs, trans)
    # Configs in lattice vectors basis
    ff = np.einsum('ij,jk->ik', final_trans, recpvecs)
    test2 = np.all(ff < 1) & np.all(ff >= 0)
    print('Test 2 success:', test2)

    assert (test1 * test2)
Beispiel #2
0
    def aos(self, eval_str, configs, mask=None):
        """
        Returns an ndarray in order [k,..., orbital] of the ao's if value is requested

        if a derivative is requested, will instead return [k,d,...,orbital].

        The ... is the total length of mycoords. You'll need to reshape if you want the original shape
        """
        mycoords = configs.configs if mask is None else configs.configs[mask]
        mycoords = mycoords.reshape((-1, mycoords.shape[-1]))
        primcoords, primwrap = pbc.enforce_pbc(self.Lprim, mycoords)
        # coordinate, dimension
        wrap = configs.wrap if mask is None else configs.wrap[mask]
        wrap = np.dot(wrap, self.S)
        wrap = wrap.reshape((-1, wrap.shape[-1])) + primwrap
        kdotR = np.linalg.multi_dot(
            (self._kpts, self._cell.lattice_vectors().T, wrap.T))
        # k, coordinate
        wrap_phase = get_wrapphase_complex(kdotR)
        # k,coordinate, orbital
        ao = gpu.cp.asarray(
            self._cell.eval_gto(
                "PBC" + eval_str,
                primcoords,
                kpts=self._kpts,
            ))
        ao = gpu.cp.einsum("k...,k...a->k...a", wrap_phase, ao)
        if len(ao.shape) == 4:  # if derivatives are included
            return ao.reshape(
                (ao.shape[0], ao.shape[1], *mycoords.shape[:-1], ao.shape[-1]))
        else:
            return ao.reshape(
                (ao.shape[0], *mycoords.shape[:-1], ao.shape[-1]))
Beispiel #3
0
def test_compare_enforcements():
    import time
    nconf = 500000
    lattvecs = np.array([[1, -0.75, 0], [0.5, 2 / 3., 0], [0, 0, 2]])
    epos0 = np.random.random((nconf, 3))
    epos0 = np.einsum('ij,jk->ik', epos0, lattvecs)

    # Using enforce_pbc_orth()
    t1 = time.time()
    epos = epos0.copy()
    final_epos_o, wrap_o = enforce_pbc_orth(lattvecs, epos)
    t2 = time.time()
    # Using enforce_pbc()
    epos = epos0.copy()
    final_epos_no, wrap_no = enforce_pbc(lattvecs, epos)
    t3 = time.time()

    relative_tol = 1e-8
    absolute_tol = 1e-8
    test1 = np.all(
        np.isclose(final_epos_o,
                   final_epos_no,
                   rtol=relative_tol,
                   atol=absolute_tol))
    test2 = np.all(
        np.isclose(wrap_o, wrap_no, rtol=relative_tol, atol=absolute_tol))

    print('Same result for enforce_pbc_orth() and enforce_pbc()?',
          test1 * test2)
    print('time[enforce_pbc_orth()] = %f' % (t2 - t1))
    print('time[enforce_pbc()]      = %f' % (t3 - t2))
    assert (test1 * test2)
Beispiel #4
0
 def __init__(self, configs, lattice_vectors, wrap=None):
     configs, wrap_ = enforce_pbc(lattice_vectors, configs)
     self.configs = configs
     self.wrap = wrap_
     if wrap is not None:
         self.wrap += wrap
     self.lvecs = lattice_vectors
     self.dist = MinimalImageDistance(lattice_vectors)
Beispiel #5
0
 def make_irreducible(self, e, vec):
     """ 
      Input: a (nconfig, 3) vector 
      Output: a tuple with the wrapped vector and the number of wraps
     """
     epos, wrap = enforce_pbc(self.lvecs, vec)
     currentwrap = self.wrap if len(self.wrap.shape) == 2 else self.wrap[:, e]
     if len(vec.shape) == 3:
         currentwrap = currentwrap[:, np.newaxis]
     return PeriodicConfigs(epos, self.lvecs, wrap=wrap + currentwrap)
Beispiel #6
0
 def _evaluate_orbitals_pbc(self, configs):
     # wrap supercell positions into primitive cell
     lvecs = self._mol.lattice_vectors()
     prim_coords, prim_wrap = pbc.enforce_pbc(lvecs, configs.configs)
     wrap = prim_wrap + np.dot(configs.wrap, self.supercell.S)
     wrap = wrap.reshape(-1, 3)
     prim_coords = prim_coords.reshape(-1, 3)
     kdotR = np.linalg.multi_dot((self._kpts, lvecs.T, wrap.T))
     wrap_phase = self.get_wrapphase(kdotR)
     # evaluate AOs for all electron positions
     ao = self._mol.eval_gto("PBCGTOval_sph", prim_coords, kpts=self._kpts)
     ao = [aok * wrap_phase[k][:, np.newaxis] for k, aok in enumerate(ao)]
     borb = [aok.dot(ock) for aok, ock in zip(ao, self._orb_coeff)]
     return np.concatenate(borb, axis=1)
Beispiel #7
0
def test_enforce_pbcs():

    # TEST 1: Check if any electron in new config
    #         is out of the simulation box for set
    #         of non-orthogonal lattice vectors. We
    #         do a controlled comparison between
    #         initial configs and final ones.
    nconf = 7
    lattvecs = np.array([[1.2, 0, 0], [0.6, 1.2 * np.sqrt(3) / 2, 0],
                         [0, 0, 0.8]])  # Triangular lattice
    trans = (np.array([
        [0.1, 0.1, 0.1],
        [1.3, 0, 0.2],
        [0.9, 1.8 * np.sqrt(3) / 2, 0],
        [0, 0, 1.1],
        [2.34, 1.35099963, 0],
        [0.48, 1.24707658, 0],
        [-2.52, 2.28630707, -0.32],
    ]) + 1e-14)
    check_final = (np.array([
        [0.1, 0.1, 0.1],
        [0.1, 0, 0.2],
        [0.3, 0.6 * np.sqrt(3) / 2, 0.0],
        [0, 0, 0.3],
        [0.54, 0.31176915, 0],
        [1.08, 0.2078461, 0],
        [1.08, 0.2078461, 0.48],
    ]) + 1e-14)
    check_wrap = np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1],
                           [1, 1, 0], [-1, 1, 0], [-4, 2, -1]])
    final_trans, final_wrap = enforce_pbc(lattvecs, trans)
    # Checks output configs
    relative_tol = 1e-8
    absolute_tol = 1e-8
    test1a = np.all(
        np.isclose(final_trans,
                   check_final,
                   rtol=relative_tol,
                   atol=absolute_tol))
    # Checks wraparound matrix
    test1b = np.all(
        np.isclose(final_wrap,
                   check_wrap,
                   rtol=relative_tol,
                   atol=absolute_tol))
    test1 = test1a * test1b
    assert test1
Beispiel #8
0
 def make_irreducible(self, e, vec, mask=None):
     """
     Input: a (nconfig, 3) vector or a (nconfig, N, 3) vector
     Output: A Periodic Electron
     """
     if mask is None:
         mask = np.ones(vec.shape[0:-1], dtype=bool)
     epos_, wrap_ = pbc.enforce_pbc(self.lvecs, vec[mask])
     epos = vec.copy()
     epos[mask] = epos_
     wrap = self.wrap[:, e, :].copy()
     if len(vec.shape) == 3:
         wrap = np.repeat(self.wrap[:, e][:, np.newaxis],
                          vec.shape[1],
                          axis=1)
     wrap[mask] += wrap_
     return PeriodicElectron(epos, self.lvecs, wrap=wrap, dist=self.dist)
Beispiel #9
0
 def evaluate_orbitals(self, configs, mask=None, eval_str="PBCGTOval_sph"):
     mycoords = configs.configs
     if mask is not None:
         mycoords = mycoords[mask]
     mycoords = mycoords.reshape((-1, mycoords.shape[-1]))
     # wrap supercell positions into primitive cell
     prim_coords, prim_wrap = pbc.enforce_pbc(self._cell.lattice_vectors(),
                                              mycoords)
     configswrap = configs.wrap.reshape(prim_wrap.shape)
     wrap = prim_wrap + np.dot(configswrap, self.supercell.S)
     kdotR = np.linalg.multi_dot(
         (self._kpts, self._cell.lattice_vectors().T, wrap.T))
     wrap_phase = np.exp(1j * kdotR)
     # evaluate AOs for all electron positions
     ao = self._cell.eval_gto(eval_str, prim_coords, kpts=self._kpts)
     ao = [ao[k] * wrap_phase[k][:, np.newaxis] for k in range(self.nk)]
     return ao
Beispiel #10
0
def test_non_orthogonal():
    # TEST 2: Check if any electron in new config
    #         is out of the simulation box for set
    #         of non-orthogonal lattice vectors.
    nconf = 50
    lattvecs = np.array([[1.2, 0, 0], [0.6, 1.2 * np.sqrt(3) / 2, 0],
                         [0, 0, 0.8]])  # Triangular lattice
    recpvecs = np.linalg.inv(lattvecs)
    # Old config
    epos = np.random.random((nconf, 3))
    epos = np.einsum("ij,jk->ik", epos, lattvecs)
    # New config
    step = 0.5
    trans = epos + step * (np.random.random((nconf, 3)) - 0.5 * np.ones(
        (nconf, 3)))
    final_trans, wrap = enforce_pbc(lattvecs, trans)
    # Configs in lattice vectors basis
    ff = np.einsum("ij,jk->ik", final_trans, recpvecs)
    test2 = np.all(ff < 1) & np.all(ff >= 0)

    assert test2
Beispiel #11
0
def runtest(mol, mf, kind=0):
    for k, occ in enumerate(mf.mo_occ):
        print(k, occ)
    kpt = mf.kpts[kind]
    twist = np.dot(kpt, mol.lattice_vectors().T / (2 * np.pi))
    print("kpt", kpt)
    print("twist", twist)
    wf0 = pyqmc.PySCFSlaterPBC(mol, mf)
    wft = pyqmc.PySCFSlaterPBC(mol, mf, twist=twist)

    #####################################
    ## compare values across boundary
    ## psi, KE, ecp,
    #####################################
    nconfig = 100
    coords = pyqmc.initial_guess(mol, nconfig, 1)
    nelec = coords.configs.shape[1]
    epos, wrap = enforce_pbc(coords.lvecs, coords.configs)
    coords = PeriodicConfigs(epos, coords.lvecs)

    shift_ = np.random.randint(10, size=coords.configs.shape) - 5
    phase = np.exp(2j * np.pi * np.einsum("ijk,k->ij", shift_, twist))

    shift = np.dot(shift_, mol.lattice_vectors())
    epos, wrap = enforce_pbc(coords.lvecs, epos + shift)
    newcoords = PeriodicConfigs(epos, coords.lvecs, wrap=wrap)

    assert np.linalg.norm(newcoords.configs - coords.configs) < 1e-12

    ph0, val0 = wf0.recompute(coords)
    pht, valt = wft.recompute(coords)
    enacc = pyqmc.accumulators.EnergyAccumulator(mol, threshold=np.inf)
    np.random.seed(0)
    en0 = enacc(coords, wf0)
    np.random.seed(0)
    ent = enacc(coords, wft)

    e = 0
    rat0 = wf0.testvalue(e, newcoords.electron(e))
    assert np.linalg.norm(rat0 - 1) < 1e-10, rat0 - 1
    ratt = wft.testvalue(e, newcoords.electron(e))
    rattdiff = ratt - phase[:, e]
    assert np.linalg.norm(rattdiff) < 1e-9, [
        np.round(rattdiff, 10),
        np.amax(np.abs(rattdiff)),
    ]

    ph0new, val0new = wf0.recompute(newcoords)
    phtnew, valtnew = wft.recompute(newcoords)
    np.random.seed(0)
    en0new = enacc(newcoords, wf0)
    np.random.seed(0)
    entnew = enacc(newcoords, wft)

    assert np.linalg.norm(ph0 - ph0new) < 1e-11
    assert np.linalg.norm(pht * phase.prod(axis=1) - phtnew) < 1e-11, (
        pht * phase.prod(axis=1) - phtnew)
    assert np.linalg.norm(val0 - val0new) < 1e-11, np.linalg.norm(val0 -
                                                                  val0new)
    assert np.linalg.norm(valt - valtnew) < 1e-11, np.linalg.norm(valt -
                                                                  valtnew)

    for k in en0.keys():
        print(k)
        diff0 = en0[k] - en0new[k]
        difft = ent[k] - entnew[k]
        if k == "ecp":
            for l, diff in [("0", diff0), ("t", difft)]:
                mad = np.mean(np.abs(diff))
                if True:  # mad > 1e-12:
                    print("ecp%s diff" % l, mad, np.linalg.norm(diff))
                    assert mad < 1e-3, diff
        else:
            assert np.linalg.norm(diff0) < 1e-10, diff0
            assert np.linalg.norm(difft) < 1e-10, difft