Beispiel #1
0
    def initiate_wf_and_mm(self):
        SIZE = 60
        self.wf = Wavefunction.from_directory('.')
        vol = self.wf.structure.volume
        self.realspace_wf = self.wf.get_state_realspace(0,
                                                        0,
                                                        0,
                                                        dim=(SIZE, SIZE, SIZE),
                                                        remove_phase=True)
        #self.realspace_chg = np.abs(self.realspace_wf)**2
        self.realspace_chg = self.wf.get_state_realspace_density(0,
                                                                 0,
                                                                 0,
                                                                 dim=(SIZE,
                                                                      SIZE,
                                                                      SIZE))
        self.recipspace_wf = np.fft.fftn(
            self.realspace_wf) / SIZE**3 * np.sqrt(vol)
        self.recipspace_chg = np.fft.fftn(self.realspace_chg) / SIZE**3 * vol
        self.mm_real = MomentumMatrix(self.wf, encut=3000)
        self.mm_direct = MomentumMatrix(self.wf)

        self.ncl_wf = NCLWavefunction.from_directory('noncollinear')
        self.ncl_realspace_wf = self.ncl_wf.get_state_realspace(
            0, 0, 0, dim=(SIZE, SIZE, SIZE), remove_phase=True)
        self.ncl_recipspace_wf = (np.fft.fftn(self.ncl_realspace_wf[0]) / SIZE**3 * np.sqrt(vol),\
             np.fft.fftn(self.ncl_realspace_wf[1]) / SIZE**3 * np.sqrt(vol))
Beispiel #2
0
def get_converged_encut(wavefunction,
                        bs,
                        iband=None,
                        max_encut=500,
                        n_samples=1000,
                        std_tol=0.02):
    from pawpyseed.core.momentum import MomentumMatrix

    nspins = wavefunction.nspin
    nkpoints = wavefunction.kpts.shape[0]
    if iband is None:
        iband = {s: len(bs.bands[s]) for s in bs.spins}

    sample_points = sample_random_kpoints(nspins, nkpoints, iband, n_samples)
    origin = sample_points[0]
    sample_points = sample_points[1:]

    mm = MomentumMatrix(wavefunction, encut=max_encut)
    true_overlaps = get_overlaps(mm, origin, sample_points)

    # filter points to only include these with reasonable overlaps
    mask = true_overlaps > 0.05
    true_overlaps = true_overlaps[mask]
    sample_points = sample_points[mask]

    for encut in np.arange(100, max_encut, 50):
        mm = MomentumMatrix(wavefunction, encut=encut)
        fake_overlaps = get_overlaps(mm, origin, sample_points)
        diff = (true_overlaps / fake_overlaps) - 1
        if diff.std() < std_tol:
            return encut

    return max_encut
Beispiel #3
0
def get_wavefunction_coefficients(wavefunction,
                                  bs,
                                  iband=None,
                                  ikpoints=None,
                                  encut=600,
                                  pbar=True):
    from pawpyseed.core.momentum import MomentumMatrix

    mm = MomentumMatrix(wavefunction, encut=encut)
    if not iband:
        iband = {}

    if not ikpoints:
        ikpoints = np.arange(mm.wf.kpts.shape[0])

    coeffs = {}
    for spin_idx in range(wavefunction.nspin):
        spin = int_to_spin[spin_idx]
        spin_iband = iband.get(spin, None)

        coeffs[spin] = _get_spin_wavefunction_coefficients(mm,
                                                           bs,
                                                           spin,
                                                           iband=spin_iband,
                                                           ikpoints=ikpoints,
                                                           pbar=pbar)

    return coeffs, mm.momentum_grid, wavefunction.kpts[ikpoints]
Beispiel #4
0
def get_wavefunction_coefficients(wavefunction,
                                  bs,
                                  iband=None,
                                  encut=600,
                                  pbar=True):
    from pawpyseed.core.momentum import MomentumMatrix

    mm = MomentumMatrix(wavefunction, encut=encut)
    if not iband:
        iband = {}

    coeffs = {}
    for spin_idx in range(wavefunction.nspin):
        spin = int_to_spin[spin_idx]
        spin_iband = iband.get(spin, None)

        coeffs[spin] = _get_spin_wavefunction_coefficients(mm,
                                                           bs,
                                                           spin,
                                                           iband=spin_iband,
                                                           pbar=pbar)
    return coeffs
Beispiel #5
0
class TestMomentumMatrix:
    def setup(self):
        self.currdir = os.getcwd()
        os.chdir(os.path.join(MODULE_DIR, "../../../test_files"))
        self.initialize_wf_and_mm()

    def initialize_wf_and_mm(self):
        SIZE = 60
        self.wf = Wavefunction.from_directory(".")
        vol = self.wf.structure.volume
        self.realspace_wf = self.wf.get_state_realspace(0,
                                                        0,
                                                        0,
                                                        dim=(SIZE, SIZE, SIZE),
                                                        remove_phase=True)
        # self.realspace_chg = np.abs(self.realspace_wf)**2
        self.realspace_chg = self.wf.get_state_realspace_density(0,
                                                                 0,
                                                                 0,
                                                                 dim=(SIZE,
                                                                      SIZE,
                                                                      SIZE))
        self.recipspace_wf = np.fft.fftn(
            self.realspace_wf) / SIZE**3 * np.sqrt(vol)
        self.recipspace_chg = np.fft.fftn(self.realspace_chg) / SIZE**3 * vol
        self.mm_real = MomentumMatrix(self.wf, encut=3000)
        self.mm_direct = MomentumMatrix(self.wf)
        self.mm_direct2 = MomentumMatrix(self.wf, encut=self.wf.encut)

        self.ncl_wf = NCLWavefunction.from_directory("noncollinear")
        self.ncl_realspace_wf = self.ncl_wf.get_state_realspace(
            0, 0, 0, dim=(SIZE, SIZE, SIZE), remove_phase=True)
        self.ncl_recipspace_wf = (
            np.fft.fftn(self.ncl_realspace_wf[0]) / SIZE**3 * np.sqrt(vol),
            np.fft.fftn(self.ncl_realspace_wf[1]) / SIZE**3 * np.sqrt(vol),
        )

    def teardown(self):
        os.chdir(self.currdir)

    def test_ncl_transform(self):
        chg = np.sum(np.abs(self.ncl_recipspace_wf[0])**2) + np.sum(
            np.abs(self.ncl_recipspace_wf[1])**2)
        assert_array_almost_equal(chg, 1, 3)

    def test_encut_insensitivity(self):
        res = self.mm_direct.get_momentum_matrix_elems(0, 0, 0, 0, 0, 0)
        res2 = self.mm_direct2.get_momentum_matrix_elems(0, 0, 0, 0, 0, 0)
        assert_almost_equal(res[0], 1, 4)
        assert_almost_equal(res2[0], 1, 4)
        assert_almost_equal(res[:6], res2[:6], 7)

    def test_get_momentum_matrix_elems(self):
        res = self.mm_direct.get_momentum_matrix_elems(0, 0, 0, 0, 0, 0)
        grid = self.mm_direct.momentum_grid
        for i in range(grid.shape[0]):
            if (np.abs(grid[i]) < 3).all():
                # print(grid[i], res[i], self.recipspace_chg[grid[i][0],grid[i][1],grid[i][2]])
                assert_almost_equal(
                    res[i], self.recipspace_chg[grid[i][0], grid[i][1],
                                                grid[i][2]], 3)
        with assert_raises(ValueError):
            self.mm_direct.get_momentum_matrix_elems(0, 0, 0, 0, -1, 0)

    def test_get_reciprocal_fullfw(self):
        res = self.mm_real.get_reciprocal_fullfw(0, 0, 0)
        print("check size", np.sum(np.abs(res)**2))
        grid = self.mm_real.momentum_grid
        for i in range(grid.shape[0]):
            if (np.abs(grid[i]) < 2).all():
                # print(grid[i], res[i], self.recipspace_wf[grid[i][0],grid[i][1],grid[i][2]])
                assert_almost_equal(
                    res[i], self.recipspace_wf[grid[i][0], grid[i][1],
                                               grid[i][2]], 3)
        with assert_raises(ValueError):
            self.mm_real.get_reciprocal_fullfw(50, 0, 0)

    def test_g_from_wf(self):
        grid = self.mm_real.momentum_grid
        for i in range(grid.shape[0]):
            if (np.abs(grid[i]) < 2).all():
                # print(grid[i], self.mm_real.g_from_wf(0,0,0,0,0,0,grid[i]), self.recipspace_chg[grid[i][0],grid[i][1],grid[i][2]])
                assert_almost_equal(
                    self.mm_real.g_from_wf(0, 0, 0, 0, 0, 0, grid[i]),
                    self.recipspace_chg[grid[i][0], grid[i][1], grid[i][2]],
                    3,
                )
        with assert_raises(ValueError):
            self.mm_real.g_from_wf(100, 0, 0, 0, 0, 0, [0, 0, 0])