Beispiel #1
0
    def ibz2bz(self, atoms):
        """Transform wave functions in IBZ to the full BZ."""

        assert self.kd.comm.size == 1

        # New k-point descriptor for full BZ:
        kd = KPointDescriptor(self.kd.bzk_kc, nspins=self.nspins)
        kd.set_symmetry(atoms, self.setups, usesymm=None)
        kd.set_communicator(serial_comm)

        self.pt = LFC(self.gd, [setup.pt_j for setup in self.setups],
                      kd, dtype=self.dtype)
        self.pt.set_positions(atoms.get_scaled_positions())

        self.initialize_wave_functions_from_restart_file()

        weight = 2.0 / kd.nspins / kd.nbzkpts
        
        # Build new list of k-points:
        kpt_u = []
        for s in range(self.nspins):
            for k in range(kd.nbzkpts):
                # Index of symmetry related point in the IBZ
                ik = self.kd.bz2ibz_k[k]
                r, u = self.kd.get_rank_and_index(s, ik)
                assert r == 0
                kpt = self.kpt_u[u]
            
                phase_cd = np.exp(2j * np.pi * self.gd.sdisp_cd *
                                  kd.bzk_kc[k, :, np.newaxis])

                # New k-point:
                kpt2 = KPoint(weight, s, k, k, phase_cd)
                kpt2.f_n = kpt.f_n / kpt.weight / kd.nbzkpts * 2 / self.nspins
                kpt2.eps_n = kpt.eps_n.copy()
                
                # Transform wave functions using symmetry operation:
                Psit_nG = self.gd.collect(kpt.psit_nG)
                if Psit_nG is not None:
                    Psit_nG = Psit_nG.copy()
                    for Psit_G in Psit_nG:
                        Psit_G[:] = self.kd.transform_wave_function(Psit_G, k)
                kpt2.psit_nG = self.gd.empty(self.bd.nbands, dtype=self.dtype)
                self.gd.distribute(Psit_nG, kpt2.psit_nG)

                # Calculate PAW projections:
                kpt2.P_ani = self.pt.dict(len(kpt.psit_nG))
                self.pt.integrate(kpt2.psit_nG, kpt2.P_ani, k)
                
                kpt_u.append(kpt2)

        self.kd = kd
        self.kpt_u = kpt_u
Beispiel #2
0
def dummy_test(lmax=4, rcut=6., lmin=0):  # fix args
    """Run a test using a Gaussian reference function."""
    dtype = complex
    generator = PolarizationOrbitalGenerator(rcut, gaussians=4)
    r = np.arange(0., rcut, .01)
    alpha_ref = 1. / (rcut / 4.)**2.
    import pylab
    for l in range(lmin, lmax + 1):
        g = QuasiGaussian(alpha_ref, rcut)
        norm = get_norm(r, g(r), l)
        g.renormalize(norm)
        gd, psit_k, center, ref = make_dummy_reference(l, g, rcut, dtype=dtype)
        k_kc = ((0., 0., 0.), (.5, .5, .5))
        kpt_u = [
            KPoint([], gd, 1., 0, i, i, k_c, dtype=dtype)
            for i, k_c in enumerate(k_kc)
        ]
        for kpt in kpt_u:
            kpt.allocate(1)
            kpt.f_n = np.array([2.])
            kpt.psit_nG = psit_k

        phi = generator.generate(l, gd, kpt_u, [center], dtype=dtype)

        pylab.figure(l)
        #pylab.plot(r, ref(r)*r**l, 'g', label='ref')
        pylab.plot(r, g(r) * r**l, 'b', label='g')
        pylab.plot(r, phi(r) * r**l, 'r--', label='pol')
        pylab.title('l=%d' % l)
        pylab.legend()
    pylab.show()
Beispiel #3
0
def make_dummy_kpt_reference(l, function, k_c,
                             rcut=6., a=10., n=60, dtype=complex):
    r = np.linspace(0., rcut, 300)
    mcount = 2*l + 1
    fcount = 1
    kcount = 1
    gd = GridDescriptor((n, n, n), (a, a, a), (True, True, True))
    kpt = KPoint([], gd, 1., 0, 0, 0, k_c, dtype)
    spline = Spline(l, r[-1], function(r))
    center = (.5, .5, .5)
    lf = create_localized_functions([spline], gd, center, dtype=dtype)
    lf.set_phase_factors([kpt.k_c])
    psit_nG = gd.zeros(mcount, dtype=dtype)
    coef_xi = np.identity(mcount * fcount, dtype=dtype)
    lf.add(psit_nG, coef_xi, k=0)
    kpt.psit_nG = psit_nG
    print 'Number of boxes', len(lf.box_b)
    print 'Phase kb factors shape', lf.phase_kb.shape
    return gd, kpt, center
Beispiel #4
0
def make_dummy_kpt_reference(l,
                             function,
                             k_c,
                             rcut=6.,
                             a=10.,
                             n=60,
                             dtype=complex):
    r = np.linspace(0., rcut, 300)
    mcount = 2 * l + 1
    fcount = 1
    kcount = 1
    gd = GridDescriptor((n, n, n), (a, a, a), (True, True, True))
    kpt = KPoint([], gd, 1., 0, 0, 0, k_c, dtype)
    spline = Spline(l, r[-1], function(r))
    center = (.5, .5, .5)
    lf = create_localized_functions([spline], gd, center, dtype=dtype)
    lf.set_phase_factors([kpt.k_c])
    psit_nG = gd.zeros(mcount, dtype=dtype)
    coef_xi = np.identity(mcount * fcount, dtype=dtype)
    lf.add(psit_nG, coef_xi, k=0)
    kpt.psit_nG = psit_nG
    print 'Number of boxes', len(lf.box_b)
    print 'Phase kb factors shape', lf.phase_kb.shape
    return gd, kpt, center
Beispiel #5
0
    def ibz2bz(self, atoms):
        """Transform wave functions in IBZ to the full BZ."""

        assert self.kd.comm.size == 1

        # New k-point descriptor for full BZ:
        kd = KPointDescriptor(self.kd.bzk_kc, nspins=self.nspins)
        #kd.set_symmetry(atoms, self.setups, enabled=False)
        kd.set_communicator(serial_comm)

        self.pt = LFC(self.gd, [setup.pt_j for setup in self.setups],
                      kd,
                      dtype=self.dtype)
        self.pt.set_positions(atoms.get_scaled_positions())

        self.initialize_wave_functions_from_restart_file()

        weight = 2.0 / kd.nspins / kd.nbzkpts

        # Build new list of k-points:
        kpt_u = []
        for s in range(self.nspins):
            for k in range(kd.nbzkpts):
                # Index of symmetry related point in the IBZ
                ik = self.kd.bz2ibz_k[k]
                r, u = self.kd.get_rank_and_index(s, ik)
                assert r == 0
                kpt = self.kpt_u[u]

                phase_cd = np.exp(2j * np.pi * self.gd.sdisp_cd *
                                  kd.bzk_kc[k, :, np.newaxis])

                # New k-point:
                kpt2 = KPoint(weight, s, k, k, phase_cd)
                kpt2.f_n = kpt.f_n / kpt.weight / kd.nbzkpts * 2 / self.nspins
                kpt2.eps_n = kpt.eps_n.copy()

                # Transform wave functions using symmetry operation:
                Psit_nG = self.gd.collect(kpt.psit_nG)
                if Psit_nG is not None:
                    Psit_nG = Psit_nG.copy()
                    for Psit_G in Psit_nG:
                        Psit_G[:] = self.kd.transform_wave_function(Psit_G, k)
                kpt2.psit_nG = self.gd.empty(self.bd.nbands, dtype=self.dtype)
                self.gd.distribute(Psit_nG, kpt2.psit_nG)

                # Calculate PAW projections:
                kpt2.P_ani = self.pt.dict(len(kpt.psit_nG))
                self.pt.integrate(kpt2.psit_nG, kpt2.P_ani, k)

                kpt_u.append(kpt2)

        self.kd = kd
        self.kpt_u = kpt_u
Beispiel #6
0
    def create_k_points(self, gd):
        """Return a list of KPoints."""

        sdisp_cd = gd.sdisp_cd

        kpt_u = []

        for ks in range(self.ks0, self.ks0 + self.mynks):
            s, k = divmod(ks, self.nibzkpts)
            q = (ks - self.ks0) % self.nibzkpts
            weight = self.weight_k[k] * 2 / self.nspins
            if self.gamma:
                phase_cd = np.ones((3, 2), complex)
            else:
                phase_cd = np.exp(2j * np.pi * sdisp_cd *
                                  self.ibzk_kc[k, :, np.newaxis])
            kpt_u.append(KPoint(weight, s, k, q, phase_cd))

        return kpt_u
Beispiel #7
0
    def create_k_points(self, gd, collinear):
        """Return a list of KPoints."""

        sdisp_cd = gd.sdisp_cd  # Maybe pass gd.sdisp_cd instead of gd??
        # We do not in fact use any other property of gd.

        kpt_u = []

        for ks in range(self.ks0, self.ks0 + self.mynks):
            s, k = divmod(ks, self.nibzkpts)
            q = (ks - self.ks0) % self.nibzkpts
            weight = self.weight_k[k] * 2 / self.nspins
            if self.gamma:
                phase_cd = np.ones((3, 2), complex)
            else:
                phase_cd = np.exp(2j * np.pi *
                                  sdisp_cd * self.ibzk_kc[k, :, np.newaxis])
            if not collinear:
                s = None
                weight *= 0.5
            kpt_u.append(KPoint(weight, s, k, q, phase_cd))

        return kpt_u
Beispiel #8
0
def dummy_kpt_test():
    l = 0
    rcut = 6.
    a = 5.
    k_kc = [(.5, .5, .5)]  #[(0., 0., 0.), (0.5, 0.5, 0.5)]
    kcount = len(k_kc)
    dtype = complex
    r = np.arange(0., rcut, .01)

    spos_ac_ref = [(0., 0., 0.)]  #, (.2, .2, .2)]
    spos_ac = [(0., 0., 0.), (.2, .2, .2)]

    ngaussians = 4
    realgaussindex = (ngaussians - 1) / 2

    rchars = np.linspace(1., rcut, ngaussians)
    splines = []
    gaussians = [QuasiGaussian(1. / rch**2., rcut) for rch in rchars]
    for g in gaussians:
        norm = get_norm(r, g(r), l)
        g.renormalize(norm)
        spline = Spline(l, r[-1], g(r))
        splines.append(spline)

    refgauss = gaussians[realgaussindex]
    refspline = splines[realgaussindex]

    gd = GridDescriptor((60, 60, 60), (a, a, a), (1, 1, 1))

    reflf_a = [
        create_localized_functions([refspline], gd, spos_c, dtype=dtype)
        for spos_c in spos_ac_ref
    ]
    for reflf in reflf_a:
        reflf.set_phase_factors(k_kc)

    kpt_u = [
        KPoint([], gd, 1., 0, k, k, k_c, dtype) for k, k_c in enumerate(k_kc)
    ]

    for kpt in kpt_u:
        kpt.allocate(1)
        kpt.f_n[0] = 1.
        psit_nG = gd.zeros(1, dtype=dtype)
        coef_xi = np.identity(1, dtype=dtype)
        integral = np.zeros((1, 1), dtype=dtype)
        for reflf in reflf_a:
            reflf.add(psit_nG, coef_xi, k=kpt.k)
            reflf.integrate(psit_nG, integral, k=kpt.k)
        kpt.psit_nG = psit_nG
        print 'ref norm', integral

    print 'calculating overlaps'
    os_kmii, oS_kmii = overlaps(l, gd, splines, kpt_u, spos_ac=spos_ac_ref)
    print 'done'

    lf_a = [
        create_localized_functions(splines, gd, spos_c, dtype=dtype)
        for spos_c in spos_ac
    ]
    for lf in lf_a:
        lf.set_phase_factors(k_kc)

    s_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype)
    S_kii = np.zeros((kcount, ngaussians, ngaussians), dtype=dtype)

    for kpt in kpt_u:
        k = kpt.k
        all_integrals = np.zeros((1, ngaussians), dtype=dtype)
        tempgrids = gd.zeros(ngaussians, dtype=dtype)
        tempcoef_xi = np.identity(ngaussians, dtype=dtype)
        for lf in lf_a:
            lf.integrate(kpt.psit_nG, all_integrals, k=k)
            lf.add(tempgrids, tempcoef_xi, k=k)
            lf.integrate(tempgrids, s_kii[k], k=k)

        print 'all <phi|psi>'
        print all_integrals

        conj_integrals = np.conj(all_integrals)
        for i in range(ngaussians):
            for j in range(ngaussians):
                S_kii[k, i, j] = conj_integrals[0, i] * all_integrals[0, j]

    print 'handmade s_kmii'
    print s_kii

    print 'handmade S_ii'
    print S_kii

    s_kmii = s_kii.reshape(kcount, 1, ngaussians, ngaussians)
    S_kmii = S_kii.reshape(kcount, 1, ngaussians, ngaussians)

    print 'matrices from overlap function'
    print 's_kmii'
    print os_kmii
    print 'S_kmii'
    print oS_kmii

    optimizer = CoefficientOptimizer(s_kmii, S_kmii, ngaussians)
    coefficients = optimizer.find_coefficients()

    optimizer2 = CoefficientOptimizer(os_kmii, oS_kmii, ngaussians)
    coefficients2 = optimizer2.find_coefficients()

    print 'coefs'
    print coefficients
    print 'overlaps() coefs'
    print coefficients2
    print 'badness'
    print optimizer.evaluate(coefficients)
    exactsolution = [0.] * ngaussians
    exactsolution[realgaussindex] = 1.
    print 'badness of exact solution'
    print optimizer.evaluate(exactsolution)

    orbital = LinearCombination(coefficients, gaussians)
    orbital2 = LinearCombination(coefficients2, gaussians)
    norm = get_norm(r, orbital(r), l)
    norm2 = get_norm(r, orbital2(r), l)
    orbital.renormalize(norm)
    orbital2.renormalize(norm2)

    import pylab
    pylab.plot(r, refgauss(r), label='ref')
    pylab.plot(r, orbital(r), label='opt')
    pylab.plot(r, orbital2(r), '--', label='auto')
    pylab.legend()
    pylab.show()
Beispiel #9
0
    def ibz2bz(self, atoms):
        """Transform wave functions in IBZ to the full BZ."""

        assert self.kd.comm.size == 1

        # New k-point descriptor for full BZ:
        kd = KPointDescriptor(self.kd.bzk_kc, nspins=self.nspins)
        kd.set_communicator(serial_comm)

        self.pt = LFC(self.gd, [setup.pt_j for setup in self.setups],
                      kd,
                      dtype=self.dtype)
        self.pt.set_positions(atoms.get_scaled_positions())

        self.initialize_wave_functions_from_restart_file()

        weight = 2.0 / kd.nspins / kd.nbzkpts

        # Build new list of k-points:
        kpt_u = []
        for s in range(self.nspins):
            for k in range(kd.nbzkpts):
                # Index of symmetry related point in the IBZ
                ik = self.kd.bz2ibz_k[k]
                r, u = self.kd.get_rank_and_index(s, ik)
                assert r == 0
                kpt = self.mykpts[u]

                phase_cd = np.exp(2j * np.pi * self.gd.sdisp_cd *
                                  kd.bzk_kc[k, :, np.newaxis])

                # New k-point:
                kpt2 = KPoint(weight, s, k, k, phase_cd)
                kpt2.f_n = kpt.f_n / kpt.weight / kd.nbzkpts * 2 / self.nspins
                kpt2.eps_n = kpt.eps_n.copy()

                # Transform wave functions using symmetry operation:
                Psit_nG = self.gd.collect(kpt.psit_nG)
                if Psit_nG is not None:
                    Psit_nG = Psit_nG.copy()
                    for Psit_G in Psit_nG:
                        Psit_G[:] = self.kd.transform_wave_function(Psit_G, k)
                kpt2.psit = UniformGridWaveFunctions(self.bd.nbands,
                                                     self.gd,
                                                     self.dtype,
                                                     kpt=k,
                                                     dist=(self.bd.comm,
                                                           self.bd.comm.size),
                                                     spin=kpt.s,
                                                     collinear=True)
                self.gd.distribute(Psit_nG, kpt2.psit_nG)
                # Calculate PAW projections:
                nproj_a = [setup.ni for setup in self.setups]
                kpt2.projections = Projections(self.bd.nbands,
                                               nproj_a,
                                               kpt.projections.atom_partition,
                                               self.bd.comm,
                                               collinear=True,
                                               spin=s,
                                               dtype=self.dtype)

                kpt2.psit.matrix_elements(self.pt, out=kpt2.projections)
                kpt_u.append(kpt2)

        self.kd = kd
        self.mykpts = kpt_u