Beispiel #1
0
    def full_static_screened_interaction(self):
        """Calcuate W_GG(q)"""
        W_qGG = np.zeros((self.nibzq, self.npw, self.npw), dtype=complex)

        t0 = time()
        for iq in range(self.nibzq):
            q = self.ibzq_qc[iq]
            optical_limit = False
            if np.abs(q).sum() < 1e-8:
                q = self.q_c.copy()
                optical_limit = True
            df = DF(calc=self.calc,
                    q=q,
                    w=(0., ),
                    optical_limit=optical_limit,
                    nbands=self.nbands,
                    hilbert_trans=False,
                    eta=0.0001,
                    ecut=self.ecut * Hartree,
                    xc='RPA',
                    txt='df.out')
            df.initialize()
            df.calculate()

            if optical_limit:
                K_GG = self.V_qGG[iq].copy()
                K0 = calculate_Kc(q,
                                  self.Gvec_Gc,
                                  self.acell_cv,
                                  self.bcell_cv,
                                  self.pbc,
                                  vcut=self.vcut)[0, 0]

                for iG in range(1, self.npw):
                    K_GG[0, iG] = self.V_qGG[iq, iG, iG]**0.5 * K0**0.5
                    K_GG[iG, 0] = self.V_qGG[iq, iG, iG]**0.5 * K0**0.5
                K_GG[0, 0] = K0
                df_GG = np.eye(self.npw, self.npw) - K_GG * df.chi0_wGG[0]
            else:
                df_GG = np.eye(self.npw,
                               self.npw) - self.V_qGG[iq] * df.chi0_wGG[0]
            dfinv_GG = np.linalg.inv(df_GG)

            if optical_limit:
                eps = 1 / dfinv_GG[0, 0]
                self.printtxt(
                    '    RPA macroscopic dielectric constant is: %3.3f' %
                    eps.real)
            W_qGG[iq] = dfinv_GG * self.V_qGG[iq]
            self.timing(iq, t0, self.nibzq, 'iq')

        if rank == 0:
            if self.kernel_file is not None:
                data = {'W_qGG': W_qGG}
                name = self.kernel_file + '.pckl'
                pickle.dump(data, open(name, 'w'), -1)

        return W_qGG
Beispiel #2
0
    def full_static_screened_interaction(self):
        """Calcuate W_GG(q)"""
        W_qGG = np.zeros((self.nibzq, self.npw, self.npw), dtype=complex)

        t0 = time()
        for iq in range(self.nibzq):
            q = self.ibzq_qc[iq]
            optical_limit = False
            if np.abs(q).sum() < 1e-8:
                q = self.q_c.copy()
                optical_limit = True
            df = DF(calc=self.calc,
                    q=q,
                    w=(0.,),
                    optical_limit=optical_limit,
                    nbands=self.nbands,
                    hilbert_trans=False,
                    eta=0.0001,
                    ecut=self.ecut*Hartree,
                    xc='RPA',
                    txt='df.out')
            df.initialize()
            df.calculate()

            if optical_limit:
                K_GG = self.V_qGG[iq].copy()
                q_v = np.dot(q, self.bcell_cv)
                K0 = calculate_Kc(q,
                                  self.Gvec_Gc,
                                  self.acell_cv,
                                  self.bcell_cv,
                                  self.pbc,
                                  vcut=self.vcut)[0,0]

                for iG in range(1,self.npw):
                    K_GG[0, iG] = self.V_qGG[iq, iG, iG]**0.5 * K0**0.5
                    K_GG[iG, 0] = self.V_qGG[iq, iG, iG]**0.5 * K0**0.5
                K_GG[0,0] = K0
                df_GG = np.eye(self.npw, self.npw) - K_GG*df.chi0_wGG[0]
            else:
                df_GG = np.eye(self.npw, self.npw) - self.V_qGG[iq]*df.chi0_wGG[0]
            dfinv_GG = np.linalg.inv(df_GG)
            
            if optical_limit:
                eps = 1/dfinv_GG[0,0]
                self.printtxt('    RPA macroscopic dielectric constant is: %3.3f' %  eps.real)
            W_qGG[iq] = dfinv_GG * self.V_qGG[iq]
            self.timing(iq, t0, self.nibzq, 'iq')
            
        if rank == 0:
            if self.kernel_file is not None:
                data = {'W_qGG': W_qGG}
                name = self.kernel_file+'.pckl'
                pickle.dump(data, open(name, 'w'), -1)
        
        return W_qGG
Beispiel #3
0
    def screened_interaction_kernel(self, iq):
        """Calcuate W_GG(w) for a given q.
        if static: return W_GG(w=0)
        is not static: return W_GG(q,w) - Vc_GG
        """

        q = self.ibzq_qc[iq]
        w = self.w_w.copy() * Hartree

        optical_limit = False
        if np.abs(q).sum() < 1e-8:
            q = np.array([1e-12, 0,
                          0])  # arbitrary q, not really need to be calculated
            optical_limit = True

        hilbert_trans = True
        if self.ppa or self.static:
            hilbert_trans = False

        df = DF(calc=self.calc,
                q=q.copy(),
                w=w,
                nbands=self.nbands,
                eshift=None,
                optical_limit=optical_limit,
                hilbert_trans=hilbert_trans,
                xc='RPA',
                time_ordered=True,
                rpad=self.rpad,
                vcut=self.vcut,
                G_plus_q=True,
                eta=self.eta * Hartree,
                ecut=self.ecut.copy() * Hartree,
                txt='df.out',
                comm=self.dfcomm,
                kcommsize=self.kcommsize)

        df.initialize()
        df.e_skn = self.e_skn.copy()
        df.calculate()

        dfinv_wGG = df.get_inverse_dielectric_matrix(xc='RPA')
        assert df.ecut[0] == self.ecut[0]
        if not self.static and not self.ppa:
            assert df.eta == self.eta
            assert df.Nw == self.Nw
            assert df.dw == self.dw

        # calculate Coulomb kernel and use truncation in 2D
        delta_GG = np.eye(df.npw)
        Vq_G = np.diag(
            calculate_Kc(q,
                         df.Gvec_Gc,
                         self.acell_cv,
                         self.bcell_cv,
                         self.pbc,
                         integrate_gamma=True,
                         N_k=self.kd.N_c,
                         vcut=self.vcut))**0.5
        if (self.vcut == '2D' and df.optical_limit) or self.numint:
            for iG in range(len(df.Gvec_Gc)):
                if df.Gvec_Gc[iG, 0] == 0 and df.Gvec_Gc[iG, 1] == 0:
                    v_q, v0_q = calculate_Kc_q(self.acell_cv,
                                               self.bcell_cv,
                                               self.pbc,
                                               self.kd.N_c,
                                               vcut=self.vcut,
                                               q_qc=np.array([q]),
                                               Gvec_c=df.Gvec_Gc[iG])
                    Vq_G[iG] = v_q[0]**0.5
        self.Kc_GG = np.outer(Vq_G, Vq_G)

        if self.ppa:
            dfinv1_GG = dfinv_wGG[0] - delta_GG
            dfinv2_GG = dfinv_wGG[1] - delta_GG
            self.wt_GG = self.E0 * np.sqrt(dfinv2_GG / (dfinv1_GG - dfinv2_GG))
            self.R_GG = -self.wt_GG / 2 * dfinv1_GG
            del dfinv_wGG
            dfinv_wGG = np.array([1j * pi * self.R_GG + delta_GG])

        if self.static:
            assert len(dfinv_wGG) == 1
            W_GG = dfinv_wGG[0] * self.Kc_GG

            return df, W_GG
        else:
            Nw = np.shape(dfinv_wGG)[0]
            W_wGG = np.zeros_like(dfinv_wGG)
            for iw in range(Nw):
                dfinv_wGG[iw] -= delta_GG
                W_wGG[iw] = dfinv_wGG[iw] * self.Kc_GG

            return df, W_wGG
Beispiel #4
0
    def screened_interaction_kernel(self, iq):
        """Calcuate W_GG(w) for a given q.
        if static: return W_GG(w=0)
        is not static: return W_GG(q,w) - Vc_GG
        """

        q = self.ibzq_qc[iq]
        w = self.w_w.copy()*Hartree

        optical_limit = False
        if np.abs(q).sum() < 1e-8:
            q = np.array([1e-12, 0, 0]) # arbitrary q, not really need to be calculated
            optical_limit = True

        hilbert_trans = True
        if self.ppa or self.static:
            hilbert_trans = False

        df = DF(calc=self.calc, q=q.copy(), w=w, nbands=self.nbands, eshift=None,
                optical_limit=optical_limit, hilbert_trans=hilbert_trans, xc='RPA', time_ordered=True,
                rpad=self.rpad, vcut=self.vcut, G_plus_q=True,
                eta=self.eta*Hartree, ecut=self.ecut.copy()*Hartree,
                txt='df.out', comm=self.dfcomm, kcommsize=self.kcommsize)

        df.initialize()
        df.e_skn = self.e_skn.copy()
        df.calculate()

        dfinv_wGG = df.get_inverse_dielectric_matrix(xc='RPA')
        assert df.ecut[0] == self.ecut[0]
        if not self.static and not self.ppa:
            assert df.eta == self.eta
            assert df.Nw == self.Nw
            assert df.dw == self.dw

        # calculate Coulomb kernel and use truncation in 2D
        delta_GG = np.eye(df.npw)
        Vq_G = np.diag(calculate_Kc(q,
                                    df.Gvec_Gc,
                                    self.acell_cv,
                                    self.bcell_cv,
                                    self.pbc,
                                    integrate_gamma=True,
                                    N_k=self.kd.N_c,
                                    vcut=self.vcut))**0.5
        if (self.vcut == '2D' and df.optical_limit) or self.numint:
            for iG in range(len(df.Gvec_Gc)):
                if df.Gvec_Gc[iG, 0] == 0 and df.Gvec_Gc[iG, 1] == 0:
                    v_q, v0_q = calculate_Kc_q(self.acell_cv,
                                               self.bcell_cv,
                                               self.pbc,
                                               self.kd.N_c,
                                               vcut=self.vcut,
                                               q_qc=np.array([q]),
                                               Gvec_c=df.Gvec_Gc[iG])
                    Vq_G[iG] = v_q[0]**0.5
        self.Kc_GG = np.outer(Vq_G, Vq_G)

        if self.ppa:
            dfinv1_GG = dfinv_wGG[0] - delta_GG
            dfinv2_GG = dfinv_wGG[1] - delta_GG
            self.wt_GG = self.E0 * np.sqrt(dfinv2_GG / (dfinv1_GG - dfinv2_GG))
            self.R_GG = - self.wt_GG / 2 * dfinv1_GG
            del dfinv_wGG
            dfinv_wGG = np.array([1j*pi*self.R_GG + delta_GG])

        if self.static:
            assert len(dfinv_wGG) == 1
            W_GG = dfinv_wGG[0] * self.Kc_GG

            return df, W_GG
        else:
            Nw = np.shape(dfinv_wGG)[0]
            W_wGG = np.zeros_like(dfinv_wGG)
            for iw in range(Nw):
                dfinv_wGG[iw] -= delta_GG
                W_wGG[iw] = dfinv_wGG[iw] * self.Kc_GG

            return df, W_wGG
    def get_C6_coefficient(self,
                           ecut=100.,
                           nbands=None,
                           kcommsize=None,
                           gauss_legendre=None,
                           frequency_cut=None,
                           frequency_scale=None,
                           direction=2):

        self.initialize_calculation(None,
                                    ecut,
                                    nbands,
                                    kcommsize,
                                    gauss_legendre,
                                    frequency_cut,
                                    frequency_scale)

        d = direction
        d_pro = []
        for i in range(3):
            if i != d:
                d_pro.append(i)
        
        dummy = DF(calc=self.calc,
                   eta=0.0,
                   w=self.w * 1j,
                   ecut=self.ecut,
                   hilbert_trans=False)
        dummy.txt = devnull
        dummy.initialize(simple_version=True)
        npw = dummy.npw
        del dummy

        q = [0.,0.,0.]
        q[d] = 1.e-5

        if self.nbands is None:
            nbands = npw
        else:
            nbands = self.nbands

        if self.txt is sys.stdout:
            txt = 'response.txt'
        else:
            txt='response_'+self.txt.name
        df = DF(calc=self.calc,
                xc=None,
                nbands=nbands,
                eta=0.0,
                q=q,
                txt=txt,
                vcut=self.vcut,
                w=self.w * 1j,
                ecut=self.ecut,
                comm=world,
                optical_limit=True,
                G_plus_q=True,
                kcommsize=self.kcommsize,
                hilbert_trans=False)
        
        print('Calculating RPA response function', file=self.txt)
        print('Polarization: %s' % d, file=self.txt)

        chi_wGG = df.get_chi(xc='RPA')
        chi0_wGG = df.chi0_wGG

        Nw_local = len(chi_wGG)
        local_a0_w = np.zeros(Nw_local, dtype=complex)
        a0_w = np.empty(len(self.w), complex)
        local_a_w = np.zeros(Nw_local, dtype=complex)
        a_w = np.empty(len(self.w), complex)

        Gvec_Gv = np.dot(df.Gvec_Gc + np.array(q), df.bcell_cv)
        gd = self.calc.density.gd
        n_d = gd.get_size_of_global_array()[d]
        d_d = gd.get_grid_spacings()[d]
        r_d = np.array([i*d_d for i in range(n_d)])

        print('Calculating real space integrals', file=self.txt)

        int_G = np.zeros(npw, complex)
        for iG in range(npw):
            if df.Gvec_Gc[iG, d_pro[0]] == 0 and df.Gvec_Gc[iG, d_pro[1]] == 0:
                int_G[iG] = np.sum(r_d * np.exp(1j*Gvec_Gv[iG, d] * r_d))*d_d
        int2_GG = np.outer(int_G, int_G.conj())

        print('Calculating dynamic polarizability', file=self.txt)

        for i in range(Nw_local):
            local_a0_w[i] = np.trace(np.dot(chi0_wGG[i], int2_GG))
            local_a_w[i] = np.trace(np.dot(chi_wGG[i], int2_GG))
        df.wcomm.all_gather(local_a0_w, a0_w)
        df.wcomm.all_gather(local_a_w, a_w)

        A = df.vol / gd.cell_cv[d,d]
        a0_w *= A**2 / df.vol
        a_w *= A**2 / df.vol

        del df
        
        C06 = np.sum(a0_w**2 * self.gauss_weights
                     * self.transform) * 3 / (2*np.pi)
        C6 = np.sum(a_w**2 * self.gauss_weights
                    * self.transform) * 3 / (2*np.pi)

        print('C06 = %s Ha*Bohr**6' % (C06.real / Ha), file=self.txt)
        print('C6 = %s Ha*Bohr**6' % (C6.real / Ha), file=self.txt)
        print(file=self.txt)

        return C6.real / Ha, C06.real / Ha
    def initialize_calculation(self,
                               w,
                               ecut,
                               nbands,
                               kcommsize,
                               gauss_legendre,
                               frequency_cut,
                               frequency_scale):
        if kcommsize is None:
            if len(self.calc.wfs.kd.bzk_kc) == 1:
                kcommsize = 1
            else:
                kcommsize = world.size
            
        if w is not None:
            assert (gauss_legendre is None and
                    frequency_cut is None and
                    frequency_scale is None)
        else:
            if gauss_legendre is None:
                gauss_legendre = 16
            self.gauss_points, self.gauss_weights = p_roots(gauss_legendre)
            if frequency_scale is None:
                frequency_scale = 2.0
            if frequency_cut is None:
                frequency_cut = 800.
            ys = 0.5 - 0.5 * self.gauss_points
            ys = ys[::-1]
            w = (-np.log(1-ys))**frequency_scale
            w *= frequency_cut/w[-1]
            alpha = (-np.log(1-ys[-1]))**frequency_scale/frequency_cut
            transform = (-np.log(1-ys))**(frequency_scale-1) \
                        / (1-ys)*frequency_scale/alpha
            self.transform = transform
            
        dummy = DF(calc=self.calc,
                   eta=0.0,
                   w=w * 1j,
                   q=[0.,0.,0.0001],
                   ecut=ecut,
                   optical_limit=True,
                   hilbert_trans=False,
                   kcommsize=kcommsize)
        dummy.txt = devnull
        dummy.initialize(simple_version=True)

        self.npw = dummy.npw
        self.ecut = ecut
        self.w = w
        self.gauss_legendre = gauss_legendre
        self.frequency_cut = frequency_cut
        self.frequency_scale = frequency_scale
        self.kcommsize = kcommsize
        self.nbands = nbands

        print(file=self.txt)
        print('Planewave cutoff              : %s eV' % ecut, file=self.txt)
        print('Number of Planewaves at Gamma : %s' % self.npw, file=self.txt)
        if self.nbands is None:
            print('Response function bands       :'\
                  + ' Equal to number of Planewaves', file=self.txt)
        else:
            print('Response function bands       : %s' \
                  % self.nbands, file=self.txt)
        print('Frequencies', file=self.txt)
        if self.gauss_legendre is not None:
            print('    Gauss-Legendre integration '\
                  + 'with %s frequency points' % len(self.w), file=self.txt)
            print('    Frequency cutoff is '\
                  + '%s eV and scale (B) is %s' % (self.w[-1],
                                                  self.frequency_scale), file=self.txt)
        else:
            print('    %s specified frequency points' \
                  % len(self.w), file=self.txt)
            print('    Frequency cutoff is %s eV' \
                  % self.w[-1], file=self.txt)
        print(file=self.txt)
        print('Parallelization scheme', file=self.txt)
        print('     Total CPUs        : %d' % dummy.comm.size, file=self.txt)
        if dummy.kd.nbzkpts == 1:
            print('     Band parsize      : %d' % dummy.kcomm.size, file=self.txt)
        else:
            print('     Kpoint parsize    : %d' % dummy.kcomm.size, file=self.txt)
        print('     Frequency parsize : %d' % dummy.wScomm.size, file=self.txt)
        print('Memory usage estimate', file=self.txt)
        print('     chi0_wGG(Q)       : %f M / cpu' \
              % (dummy.Nw_local * self.npw**2 * 16. / 1024**2), file=self.txt)
        print(file=self.txt)
        del dummy
    def E_q(self,
            q,
            index=None,
            direction=0,
            integrated=True):

        if abs(np.dot(q, q))**0.5 < 1.e-5:
            q = [0.,0.,0.]
            q[direction] = 1.e-5
            optical_limit = True
        else:
            optical_limit = False

        dummy = DF(calc=self.calc,
                   eta=0.0,
                   w=self.w * 1j,
                   q=q,
                   ecut=self.ecut,
                   G_plus_q=True,
                   optical_limit=optical_limit,
                   hilbert_trans=False)
        dummy.txt = devnull
        dummy.initialize(simple_version=True)
        npw = dummy.npw
        del dummy

        if self.nbands is None:
            nbands = npw
        else:
            nbands = self.nbands

        if self.txt is sys.stdout:
            txt = 'response.txt'
        else:
            txt='response_'+self.txt.name
        df = DF(calc=self.calc,
                xc=None,
                nbands=nbands,
                eta=0.0,
                q=q,
                txt=txt,
                vcut=self.vcut,
                w=self.w * 1j,
                ecut=self.ecut,
                G_plus_q=True,
                kcommsize=self.kcommsize,
                comm=self.dfcomm,
                optical_limit=optical_limit,
                hilbert_trans=False)

        if index is None:
            print('Calculating KS response function at:', file=self.txt)
        else:
            print('#', index, \
                  '- Calculating KS response function at:', file=self.txt)
        if optical_limit:
            print('q = [0 0 0] -', 'Polarization: ', direction, file=self.txt)
        else:
            print('q = [%1.6f %1.6f %1.6f] -' \
                  % (q[0],q[1],q[2]), '%s planewaves' % npw, file=self.txt)

        e_wGG = df.get_dielectric_matrix(xc='RPA', overwritechi0=True)
        df.chi0_wGG = None
        Nw_local = len(e_wGG)
        local_E_q_w = np.zeros(Nw_local, dtype=complex)
        E_q_w = np.empty(len(self.w), complex)
        for i in range(Nw_local):
            local_E_q_w[i] = (np.log(np.linalg.det(e_wGG[i]))
                              + len(e_wGG[0]) - np.trace(e_wGG[i]))
            #local_E_q_w[i] = (np.sum(np.log(np.linalg.eigvals(e_wGG[i])))
            #                  + len(e_wGG[0]) - np.trace(e_wGG[i]))
        df.wcomm.all_gather(local_E_q_w, E_q_w)
        del df
        
        if self.gauss_legendre is not None:
            E_q = np.sum(E_q_w * self.gauss_weights * self.transform) \
                  / (4*np.pi)
        else:   
            dws = self.w[1:] - self.w[:-1]
            E_q = np.dot((E_q_w[:-1] + E_q_w[1:])/2., dws) / (2.*np.pi)


        print('E_c(q) = %s eV' % E_q.real, file=self.txt)
        print(file=self.txt)

        if integrated:
            return E_q.real
        else:
            return E_q_w.real               
Beispiel #8
0
    def get_C6_coefficient(self,
                           ecut=100.,
                           nbands=None,
                           kcommsize=None,
                           gauss_legendre=None,
                           frequency_cut=None,
                           frequency_scale=None,
                           direction=2):

        self.initialize_calculation(None, ecut, nbands, kcommsize,
                                    gauss_legendre, frequency_cut,
                                    frequency_scale)

        d = direction
        d_pro = []
        for i in range(3):
            if i != d:
                d_pro.append(i)

        dummy = DF(calc=self.calc,
                   eta=0.0,
                   w=self.w * 1j,
                   ecut=self.ecut,
                   hilbert_trans=False)
        dummy.txt = devnull
        dummy.initialize(simple_version=True)
        npw = dummy.npw
        del dummy

        q = [0., 0., 0.]
        q[d] = 1.e-5

        if self.nbands is None:
            nbands = npw
        else:
            nbands = self.nbands

        if self.txt is sys.stdout:
            txt = 'response.txt'
        else:
            txt = 'response_' + self.txt.name
        df = DF(calc=self.calc,
                xc=None,
                nbands=nbands,
                eta=0.0,
                q=q,
                txt=txt,
                vcut=self.vcut,
                w=self.w * 1j,
                ecut=self.ecut,
                comm=world,
                optical_limit=True,
                G_plus_q=True,
                kcommsize=self.kcommsize,
                hilbert_trans=False)

        print('Calculating RPA response function', file=self.txt)
        print('Polarization: %s' % d, file=self.txt)

        chi_wGG = df.get_chi(xc='RPA')
        chi0_wGG = df.chi0_wGG

        Nw_local = len(chi_wGG)
        local_a0_w = np.zeros(Nw_local, dtype=complex)
        a0_w = np.empty(len(self.w), complex)
        local_a_w = np.zeros(Nw_local, dtype=complex)
        a_w = np.empty(len(self.w), complex)

        Gvec_Gv = np.dot(df.Gvec_Gc + np.array(q), df.bcell_cv)
        gd = self.calc.density.gd
        n_d = gd.get_size_of_global_array()[d]
        d_d = gd.get_grid_spacings()[d]
        r_d = np.array([i * d_d for i in range(n_d)])

        print('Calculating real space integrals', file=self.txt)

        int_G = np.zeros(npw, complex)
        for iG in range(npw):
            if df.Gvec_Gc[iG, d_pro[0]] == 0 and df.Gvec_Gc[iG, d_pro[1]] == 0:
                int_G[iG] = np.sum(
                    r_d * np.exp(1j * Gvec_Gv[iG, d] * r_d)) * d_d
        int2_GG = np.outer(int_G, int_G.conj())

        print('Calculating dynamic polarizability', file=self.txt)

        for i in range(Nw_local):
            local_a0_w[i] = np.trace(np.dot(chi0_wGG[i], int2_GG))
            local_a_w[i] = np.trace(np.dot(chi_wGG[i], int2_GG))
        df.wcomm.all_gather(local_a0_w, a0_w)
        df.wcomm.all_gather(local_a_w, a_w)

        A = df.vol / gd.cell_cv[d, d]
        a0_w *= A**2 / df.vol
        a_w *= A**2 / df.vol

        del df

        C06 = np.sum(
            a0_w**2 * self.gauss_weights * self.transform) * 3 / (2 * np.pi)
        C6 = np.sum(
            a_w**2 * self.gauss_weights * self.transform) * 3 / (2 * np.pi)

        print('C06 = %s Ha*Bohr**6' % (C06.real / Ha), file=self.txt)
        print('C6 = %s Ha*Bohr**6' % (C6.real / Ha), file=self.txt)
        print(file=self.txt)

        return C6.real / Ha, C06.real / Ha
Beispiel #9
0
    def initialize_calculation(self, w, ecut, nbands, kcommsize,
                               gauss_legendre, frequency_cut, frequency_scale):
        if kcommsize is None:
            if len(self.calc.wfs.kd.bzk_kc) == 1:
                kcommsize = 1
            else:
                kcommsize = world.size

        if w is not None:
            assert (gauss_legendre is None and frequency_cut is None
                    and frequency_scale is None)
        else:
            if gauss_legendre is None:
                gauss_legendre = 16
            self.gauss_points, self.gauss_weights = p_roots(gauss_legendre)
            if frequency_scale is None:
                frequency_scale = 2.0
            if frequency_cut is None:
                frequency_cut = 800.
            ys = 0.5 - 0.5 * self.gauss_points
            ys = ys[::-1]
            w = (-np.log(1 - ys))**frequency_scale
            w *= frequency_cut / w[-1]
            alpha = (-np.log(1 - ys[-1]))**frequency_scale / frequency_cut
            transform = (-np.log(1-ys))**(frequency_scale-1) \
                        / (1-ys)*frequency_scale/alpha
            self.transform = transform

        dummy = DF(calc=self.calc,
                   eta=0.0,
                   w=w * 1j,
                   q=[0., 0., 0.0001],
                   ecut=ecut,
                   optical_limit=True,
                   hilbert_trans=False,
                   kcommsize=kcommsize)
        dummy.txt = devnull
        dummy.initialize(simple_version=True)

        self.npw = dummy.npw
        self.ecut = ecut
        self.w = w
        self.gauss_legendre = gauss_legendre
        self.frequency_cut = frequency_cut
        self.frequency_scale = frequency_scale
        self.kcommsize = kcommsize
        self.nbands = nbands

        print(file=self.txt)
        print('Planewave cutoff              : %s eV' % ecut, file=self.txt)
        print('Number of Planewaves at Gamma : %s' % self.npw, file=self.txt)
        if self.nbands is None:
            print('Response function bands       :'\
                  + ' Equal to number of Planewaves', file=self.txt)
        else:
            print('Response function bands       : %s' \
                  % self.nbands, file=self.txt)
        print('Frequencies', file=self.txt)
        if self.gauss_legendre is not None:
            print('    Gauss-Legendre integration '\
                  + 'with %s frequency points' % len(self.w), file=self.txt)
            print('    Frequency cutoff is '\
                  + '%s eV and scale (B) is %s' % (self.w[-1],
                                                  self.frequency_scale), file=self.txt)
        else:
            print('    %s specified frequency points' \
                  % len(self.w), file=self.txt)
            print('    Frequency cutoff is %s eV' \
                  % self.w[-1], file=self.txt)
        print(file=self.txt)
        print('Parallelization scheme', file=self.txt)
        print('     Total CPUs        : %d' % dummy.comm.size, file=self.txt)
        if dummy.kd.nbzkpts == 1:
            print('     Band parsize      : %d' % dummy.kcomm.size,
                  file=self.txt)
        else:
            print('     Kpoint parsize    : %d' % dummy.kcomm.size,
                  file=self.txt)
        print('     Frequency parsize : %d' % dummy.wScomm.size, file=self.txt)
        print('Memory usage estimate', file=self.txt)
        print('     chi0_wGG(Q)       : %f M / cpu' \
              % (dummy.Nw_local * self.npw**2 * 16. / 1024**2), file=self.txt)
        print(file=self.txt)
        del dummy
Beispiel #10
0
    def E_q(self, q, index=None, direction=0, integrated=True):

        if abs(np.dot(q, q))**0.5 < 1.e-5:
            q = [0., 0., 0.]
            q[direction] = 1.e-5
            optical_limit = True
        else:
            optical_limit = False

        dummy = DF(calc=self.calc,
                   eta=0.0,
                   w=self.w * 1j,
                   q=q,
                   ecut=self.ecut,
                   G_plus_q=True,
                   optical_limit=optical_limit,
                   hilbert_trans=False)
        dummy.txt = devnull
        dummy.initialize(simple_version=True)
        npw = dummy.npw
        del dummy

        if self.nbands is None:
            nbands = npw
        else:
            nbands = self.nbands

        if self.txt is sys.stdout:
            txt = 'response.txt'
        else:
            txt = 'response_' + self.txt.name
        df = DF(calc=self.calc,
                xc=None,
                nbands=nbands,
                eta=0.0,
                q=q,
                txt=txt,
                vcut=self.vcut,
                w=self.w * 1j,
                ecut=self.ecut,
                G_plus_q=True,
                kcommsize=self.kcommsize,
                comm=self.dfcomm,
                optical_limit=optical_limit,
                hilbert_trans=False)

        if index is None:
            print('Calculating KS response function at:', file=self.txt)
        else:
            print('#', index, \
                  '- Calculating KS response function at:', file=self.txt)
        if optical_limit:
            print('q = [0 0 0] -', 'Polarization: ', direction, file=self.txt)
        else:
            print('q = [%1.6f %1.6f %1.6f] -' \
                  % (q[0],q[1],q[2]), '%s planewaves' % npw, file=self.txt)

        e_wGG = df.get_dielectric_matrix(xc='RPA', overwritechi0=True)
        df.chi0_wGG = None
        Nw_local = len(e_wGG)
        local_E_q_w = np.zeros(Nw_local, dtype=complex)
        E_q_w = np.empty(len(self.w), complex)
        for i in range(Nw_local):
            local_E_q_w[i] = (np.log(np.linalg.det(e_wGG[i])) + len(e_wGG[0]) -
                              np.trace(e_wGG[i]))
            #local_E_q_w[i] = (np.sum(np.log(np.linalg.eigvals(e_wGG[i])))
            #                  + len(e_wGG[0]) - np.trace(e_wGG[i]))
        df.wcomm.all_gather(local_E_q_w, E_q_w)
        del df

        if self.gauss_legendre is not None:
            E_q = np.sum(E_q_w * self.gauss_weights * self.transform) \
                  / (4*np.pi)
        else:
            dws = self.w[1:] - self.w[:-1]
            E_q = np.dot((E_q_w[:-1] + E_q_w[1:]) / 2., dws) / (2. * np.pi)

        print('E_c(q) = %s eV' % E_q.real, file=self.txt)
        print(file=self.txt)

        if integrated:
            return E_q.real
        else:
            return E_q_w.real