コード例 #1
0
ファイル: rpa_correlation_energy.py プロジェクト: qsnake/gpaw
    def initialize_calculation(self, w, ecut, nbands, kcommsize, extrapolate):
        
        dummy = DF(calc=self.calc,
                   eta=0.0,
                   w=w * 1j,
                   q=[0.,0.,0.],
                   ecut=ecut,
                   hilbert_trans=False,
                   kcommsize=kcommsize)
        dummy.txt = devnull
        dummy.spin = 0
        dummy.initialize()

        if nbands is None:
            nbands = dummy.npw
        self.nbands = nbands
        
        print >> self.txt, 'Planewave cut off            : %s eV' % ecut
        print >> self.txt, 'Number of Planewaves         : %s' % dummy.npw
        print >> self.txt, 'Response function bands      : %s' % nbands
        print >> self.txt, 'Frequency range              : %s - %s eV' % (w[0], w[-1])
        print >> self.txt, 'Number of frequency points   : %s' % len(w)
        if extrapolate:
            print >> self.txt, 'Extrapolation of frequencies : Squared Lorentzian'
        print >> self.txt
        print >> self.txt, 'Parallelization scheme'
        print >> self.txt, '     Total cpus         : %d' % dummy.comm.size
        if dummy.nkpt == 1:
            print >> self.txt, '     Band parsize       : %d' % dummy.kcomm.size
        else:
            print >> self.txt, '     Kpoint parsize     : %d' % dummy.kcomm.size
        print >> self.txt, '     Frequency parsize  : %d' % dummy.wScomm.size
        print >> self.txt, 'Memory usage estimate'
        print >> self.txt, '     chi0_wGG(Q)        : %f M / cpu' % (dummy.Nw_local *
                                                                     dummy.npw**2 * 16.
                                                                    / 1024**2)
        print >> self.txt
        del dummy
コード例 #2
0
    def initialize_calculation(self, w, ecut, nbands, kcommsize, extrapolate):

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

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

        print >> self.txt, 'Planewave cut off            : %s eV' % ecut
        print >> self.txt, 'Number of Planewaves         : %s' % dummy.npw
        print >> self.txt, 'Response function bands      : %s' % nbands
        print >> self.txt, 'Frequency range              : %s - %s eV' % (
            w[0], w[-1])
        print >> self.txt, 'Number of frequency points   : %s' % len(w)
        if extrapolate:
            print >> self.txt, 'Extrapolation of frequencies : Squared Lorentzian'
        print >> self.txt
        print >> self.txt, 'Parallelization scheme'
        print >> self.txt, '     Total cpus         : %d' % dummy.comm.size
        if dummy.nkpt == 1:
            print >> self.txt, '     Band parsize       : %d' % dummy.kcomm.size
        else:
            print >> self.txt, '     Kpoint parsize     : %d' % dummy.kcomm.size
        print >> self.txt, '     Frequency parsize  : %d' % dummy.wScomm.size
        print >> self.txt, 'Memory usage estimate'
        print >> self.txt, '     chi0_wGG(Q)        : %f M / cpu' % (
            dummy.Nw_local * dummy.npw**2 * 16. / 1024**2)
        print >> self.txt
        del dummy
コード例 #3
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 >> self.txt, 'Calculating RPA response function'
        print >> self.txt, 'Polarization: %s' % d

        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 >> self.txt, 'Calculating real space integrals'

        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 >> self.txt, 'Calculating dynamic polarizability'

        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 >> self.txt, 'C06 = %s Ha*Bohr**6' % (C06.real / Ha)
        print >> self.txt, 'C6 = %s Ha*Bohr**6' % (C6.real / Ha)
        print >> self.txt

        return C6.real / Ha, C06.real / Ha
コード例 #4
0
    def initialize_calculation(self,
                               w,
                               ecut,
                               nbands,
                               kcommsize,
                               gauss_legendre,
                               frequency_cut,
                               frequency_scale):
        if kcommsize is None:
            if len(self.calc.wfs.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 >> self.txt
        print >> self.txt, 'Planewave cutoff              : %s eV' % ecut
        print >> self.txt, 'Number of Planewaves at Gamma : %s' % self.npw
        if self.nbands is None:
            print >> self.txt, 'Response function bands       :'\
                  + ' Equal to number of Planewaves'
        else:
            print >> self.txt, 'Response function bands       : %s' \
                  % self.nbands
        print >> self.txt, 'Frequencies'
        if self.gauss_legendre is not None:
            print >> self.txt, '    Gauss-Legendre integration '\
                  + 'with %s frequency points' % len(self.w)
            print >> self.txt, '    Frequency cutoff is '\
                  + '%s eV and scale (B) is %s' % (self.w[-1],
                                                  self.frequency_scale)
        else:
            print >> self.txt, '    %s specified frequency points' \
                  % len(self.w)
            print >> self.txt, '    Frequency cutoff is %s eV' \
                  % self.w[-1]
        print >> self.txt
        print >> self.txt, 'Parallelization scheme'
        print >> self.txt, '     Total CPUs        : %d' % dummy.comm.size
        if dummy.kd.nbzkpts == 1:
            print >> self.txt, '     Band parsize      : %d' % dummy.kcomm.size
        else:
            print >> self.txt, '     Kpoint parsize    : %d' % dummy.kcomm.size
        print >> self.txt, '     Frequency parsize : %d' % dummy.wScomm.size
        print >> self.txt, 'Memory usage estimate'
        print >> self.txt, '     chi0_wGG(Q)       : %f M / cpu' \
              % (dummy.Nw_local * self.npw**2 * 16. / 1024**2)
        print >> self.txt
        del dummy
コード例 #5
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 >> self.txt, 'Calculating KS response function at:'
        else:
            print >> self.txt, '#', index, \
                  '- Calculating KS response function at:'
        if optical_limit:
            print >> self.txt, 'q = [0 0 0] -', 'Polarization: ', direction
        else:
            print >> self.txt, 'q = [%1.6f %1.6f %1.6f] -' \
                  % (q[0],q[1],q[2]), '%s planewaves' % npw

        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 >> self.txt, 'E_c(q) = %s eV' % E_q.real
        print >> self.txt

        if integrated:
            return E_q.real
        else:
            return E_q_w.real               
コード例 #6
0
ファイル: rpa_correlation_energy.py プロジェクト: qsnake/gpaw
    def get_E_q(self,
                kcommsize=1,
                index=None,
                q=[0., 0., 0.],
                integrated=True,
                ecut=10,
                nbands=None,
                w=np.linspace(0, 200., 32),
                extrapolate=True):
        
        if index is None:
            self.initialize_calculation(w, ecut, nbands, kcommsize, extrapolate)

        if abs(q[0]) < 0.001 and abs(q[1]) < 0.001 and abs(q[2]) < 0.001:
            q = [1.e-5, 0., 0.]
            optical_limit = True
        else:
            optical_limit = False
            
        df = DF(calc=self.calc,
                nbands=self.nbands,
                eta=0.0,
                q=q,
                w=w * 1j,
                ecut=ecut,
                kcommsize=kcommsize,
                optical_limit=optical_limit,
                hilbert_trans=False)
        df.txt = devnull

        if index is None:
            print >> self.txt, 'Calculating RPA dielectric matrix at:'
        else:
            print >> self.txt, '#', index, '- Calculating RPA dielectric matrix at:'
        
        if optical_limit:
            print >> self.txt, 'Q = [0 0 0]'
        else:
            print >> self.txt, 'Q = %s' % q 
            
        e_wGG = df.get_RPA_dielectric_matrix()

        Nw_local = len(e_wGG)
        local_E_q_w = np.zeros(Nw_local, dtype=complex)

        E_q_w = np.empty(len(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])))
            #                  + self.npw - np.trace(e_wGG[i]))
        df.wcomm.all_gather(local_E_q_w, E_q_w)
        del df
        del e_wGG
        dw = w[1] - w[0]
        E_q = dw * np.sum((E_q_w[:-1] + E_q_w[1:])/2.) / (2.*np.pi)
        if extrapolate:
            print
            '''Fit tail to: Eq(w) = A**2/((w-B)**2 + C)**2'''
            e1 = abs(E_q_w[-1])**0.5
            e2 = abs(E_q_w[-2])**0.5
            e3 = abs(E_q_w[-3])**0.5
            w1 = w[-1]
            w2 = w[-2]
            w3 = w[-3]
            B = (((e3*w3**2-e1*w1**2)/(e1-e3) - (e2*w2**2-e1*w1**2)/(e1-e2))
                 / ((2*w3*e3-2*w1*e1)/(e1-e3) - (2*w2*e2-2*w1*e1)/(e1-e2)))
            C = ((w2-B)**2*e2 - (w1-B)**2*e1)/(e1-e2)
            A = e1*((w1-B)**2+C)
            if C > 0:
                E_q -= A**2*(np.pi/(4*C**1.5)
                             - (w1-B)/((w1-B)**2+C)/(2*C)
                             - np.arctan((w1-B)/C**0.5)/(2*C**1.5)) / (2*np.pi)
            else:
                E_q += A**2*((w1-B)/((w1-B)**2+C)/(2*C)
                             + np.log((w1-B-abs(C)**0.5)/(w1-B+abs(C)**0.5))
                             /(4*C*abs(C)**0.5)) / (2*np.pi)
                

        print >> self.txt, 'E_c(Q) = %s eV' % E_q.real
        print >> self.txt
        if index is None:
            print >> self.txt, 'Calculation completed at:  ', ctime()
            print >> self.txt
            print >> self.txt, '------------------------------------------------------'
        if integrated:
            return E_q
        else:
            return E_q_w
コード例 #7
0
    def get_E_q(self,
                kcommsize=1,
                index=None,
                q=[0., 0., 0.],
                integrated=True,
                ecut=10,
                nbands=None,
                w=np.linspace(0, 200., 32),
                extrapolate=True):

        if index is None:
            self.initialize_calculation(w, ecut, nbands, kcommsize,
                                        extrapolate)

        if abs(q[0]) < 0.001 and abs(q[1]) < 0.001 and abs(q[2]) < 0.001:
            q = [1.e-5, 0., 0.]
            optical_limit = True
        else:
            optical_limit = False

        df = DF(calc=self.calc,
                nbands=self.nbands,
                eta=0.0,
                q=q,
                w=w * 1j,
                ecut=ecut,
                kcommsize=kcommsize,
                optical_limit=optical_limit,
                hilbert_trans=False)
        df.txt = devnull

        if index is None:
            print >> self.txt, 'Calculating RPA dielectric matrix at:'
        else:
            print >> self.txt, '#', index, '- Calculating RPA dielectric matrix at:'

        if optical_limit:
            print >> self.txt, 'Q = [0 0 0]'
        else:
            print >> self.txt, 'Q = %s' % q

        e_wGG = df.get_RPA_dielectric_matrix()

        Nw_local = len(e_wGG)
        local_E_q_w = np.zeros(Nw_local, dtype=complex)

        E_q_w = np.empty(len(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])))
            #                  + self.npw - np.trace(e_wGG[i]))
        df.wcomm.all_gather(local_E_q_w, E_q_w)
        del df
        del e_wGG
        dw = w[1] - w[0]
        E_q = dw * np.sum((E_q_w[:-1] + E_q_w[1:]) / 2.) / (2. * np.pi)
        if extrapolate:
            print
            '''Fit tail to: Eq(w) = A**2/((w-B)**2 + C)**2'''
            e1 = abs(E_q_w[-1])**0.5
            e2 = abs(E_q_w[-2])**0.5
            e3 = abs(E_q_w[-3])**0.5
            w1 = w[-1]
            w2 = w[-2]
            w3 = w[-3]
            B = (((e3 * w3**2 - e1 * w1**2) / (e1 - e3) -
                  (e2 * w2**2 - e1 * w1**2) / (e1 - e2)) /
                 ((2 * w3 * e3 - 2 * w1 * e1) / (e1 - e3) -
                  (2 * w2 * e2 - 2 * w1 * e1) / (e1 - e2)))
            C = ((w2 - B)**2 * e2 - (w1 - B)**2 * e1) / (e1 - e2)
            A = e1 * ((w1 - B)**2 + C)
            if C > 0:
                E_q -= A**2 * (np.pi / (4 * C**1.5) - (w1 - B) /
                               ((w1 - B)**2 + C) / (2 * C) - np.arctan(
                                   (w1 - B) / C**0.5) /
                               (2 * C**1.5)) / (2 * np.pi)
            else:
                E_q += A**2 * ((w1 - B) / ((w1 - B)**2 + C) / (2 * C) + np.log(
                    (w1 - B - abs(C)**0.5) / (w1 - B + abs(C)**0.5)) /
                               (4 * C * abs(C)**0.5)) / (2 * np.pi)

        print >> self.txt, 'E_c(Q) = %s eV' % E_q.real
        print >> self.txt
        if index is None:
            print >> self.txt, 'Calculation completed at:  ', ctime()
            print >> self.txt
            print >> self.txt, '------------------------------------------------------'
        if integrated:
            return E_q
        else:
            return E_q_w