Beispiel #1
0
    def par_save(self, filename, name, A_sS):
        from gpaw.io import open

        nS = self.nS

        if rank == 0:
            w = open(filename, 'w', world)
            w.dimension('nS', nS)

            if name == 'v_SS':
                w.add('w_S', ('nS', ), dtype=self.w_S.dtype)
                w.fill(self.w_S)
            w.add('rhoG0_S', ('nS', ), dtype=complex)
            w.fill(self.rhoG0_S)
            w.add(name, ('nS', 'nS'), dtype=complex)

            tmp = np.zeros_like(A_sS)

        # Assumes that H_SS is written in order from rank 0 - rank N
        for irank in range(size):
            if irank == 0:
                if rank == 0:
                    w.fill(A_sS)
            else:
                if rank == irank:
                    world.send(A_sS, 0, irank + 100)
                if rank == 0:
                    world.receive(tmp, irank, irank + 100)
                    w.fill(tmp)
        if rank == 0:
            w.close()
        world.barrier()
Beispiel #2
0
    def par_save(self,filename, name, A_sS):
        from gpaw.io import open 

        nS_local = self.nS_local
        nS = self.nS
        
        if rank == 0:
            w = open(filename, 'w', world)
            w.dimension('nS', nS)
            
            if name == 'v_SS':
                w.add('w_S', ('nS',), dtype=self.w_S.dtype)
                w.fill(self.w_S)
            w.add('rhoG0_S', ('nS',), dtype=complex)
            w.fill(self.rhoG0_S)
            w.add(name, ('nS', 'nS'), dtype=complex)

            tmp = np.zeros_like(A_sS)

        # Assumes that H_SS is written in order from rank 0 - rank N
        for irank in range(size):
            if irank == 0:
                if rank == 0:
                    w.fill(A_sS)
            else:
                if rank == irank:
                    world.send(A_sS, 0, irank+100)
                if rank == 0:
                    world.receive(tmp, irank, irank+100)
                    w.fill(tmp)
        if rank == 0:
            w.close()
        world.barrier()
Beispiel #3
0
def par_write(filename, name, comm, chi0_wGG):

    ## support only world communicator at the moment
    from gpaw.mpi import rank, size, world
    from gpaw.io import open

    assert comm.size == size
    assert comm.rank == rank

    Nw_local, npw, npw1 = chi0_wGG.shape
    assert npw == npw1
    Nw = Nw_local * size

    if rank == 0:
        w = open(filename, 'w', comm)
        w.dimension('Nw', Nw)
        w.dimension('npw', npw)
        w.add(name, ('Nw', 'npw', 'npw'), dtype=complex)
        tmp = np.zeros_like(chi0_wGG[0])

    for iw in range(Nw):
        irank = iw // Nw_local
        if irank == 0:
            if rank == 0:
                w.fill(chi0_wGG[iw])
        else:
            if rank == irank:
                world.send(chi0_wGG[iw - rank * Nw_local], 0, irank + 100)
            if rank == 0:
                world.receive(tmp, irank, irank + 100)
                w.fill(tmp)
    if rank == 0:
        w.close()
    world.barrier()
Beispiel #4
0
def par_write(filename, name, comm, chi0_wGG):

    ## support only world communicator at the moment
    from gpaw.mpi import rank, size, world
    from gpaw.io import open
    
    assert comm.size == size
    assert comm.rank == rank

    Nw_local, npw, npw1 = chi0_wGG.shape
    assert npw == npw1
    Nw = Nw_local * size
    
    w = open(filename, 'w', comm)
    w.dimension('Nw', Nw)
    w.dimension('npw', npw)
    w.add(name, ('Nw', 'npw', 'npw'), dtype=complex)
    if rank == 0:
        tmp = np.zeros_like(chi0_wGG[0])

    for iw in range(Nw):
        irank = iw // Nw_local
        if irank == 0:
            if rank == 0:
                w.fill(chi0_wGG[iw])
        else:
            if rank == irank:
                world.send(chi0_wGG[iw-rank*Nw_local], 0, irank+100)
            if rank == 0:
                world.receive(tmp, irank, irank+100)
                w.fill(tmp)
    if rank == 0:
        w.close()
    world.barrier()
Beispiel #5
0
    def load(self, filename):

        data = pickle.load(open(filename))
        self.w_S = data['w_S']
        self.v_SS = data['v_SS']

        self.printtxt('Read succesfully !')
Beispiel #6
0
    def load(self, filename):

        data = pickle.load(open(filename))
        self.w_S  = data['w_S']
        self.v_SS = data['v_SS']

        self.printtxt('Read succesfully !')
Beispiel #7
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 #8
0
    def save(self, filename):
        """Dump essential data"""

        data = {'w_S': self.w_S, 'v_SS': self.v_SS}

        if rank == 0:
            pickle.dump(data, open(filename, 'w'), -1)

        world.barrier()
Beispiel #9
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 #10
0
    def save(self, filename):
        """Dump essential data"""

        data = {'w_S'  : self.w_S,
                'v_SS' : self.v_SS}
        
        if rank == 0:
            pickle.dump(data, open(filename, 'w'), -1)

        world.barrier()
Beispiel #11
0
def par_read(filename, name, Nw=None):

    r = open(filename, 'r')
    if Nw is None:
        Nw = r.dimension('Nw')
    else:
        assert Nw <= r.dimension('Nw')
    npw = r.dimension('npw')
    Nw_local = Nw // size
    chi0_wGG = np.zeros((Nw_local, npw, npw), dtype=complex)

    for iw in range(Nw_local):
        chi0_wGG[iw] = r.get(name, iw + rank * Nw_local)

    r.close()

    return chi0_wGG
def par_read(filename, name, Nw=None):

    r = open(filename, 'r')
    if Nw is None:
        Nw = r.dimension('Nw')
    else:
        assert Nw <= r.dimension('Nw')
    npw = r.dimension('npw')
    Nw_local = Nw // size
    chi0_wGG = np.zeros((Nw_local, npw, npw), dtype=complex)

    for iw in range(Nw_local):
        chi0_wGG[iw] = r.get(name, iw+rank*Nw_local)

    r.close()
    
    return chi0_wGG
Beispiel #13
0
    def par_load(self,filename, name):
        from gpaw.io import open 
        r = open(filename, 'r')
        nS = r.dimension('nS')

        if name == 'v_SS':
            self.w_S = r.get('w_S')

        A_SS = np.zeros((self.nS_local, nS), dtype=complex)
        for iS in range(self.nS_start, self.nS_end):   
            A_SS[iS-self.nS_start,:] = r.get(name, iS)

        self.rhoG0_S = r.get('rhoG0_S')

        r.close()
        
        return A_SS
Beispiel #14
0
    def par_load(self, filename, name):
        from gpaw.io import open
        r = open(filename, 'r')
        nS = r.dimension('nS')

        if name == 'v_SS':
            self.w_S = r.get('w_S')

        A_SS = np.zeros((self.nS_local, nS), dtype=complex)
        for iS in range(self.nS_start, self.nS_end):
            A_SS[iS - self.nS_start, :] = r.get(name, iS)

        self.rhoG0_S = r.get('rhoG0_S')

        r.close()

        return A_SS
Beispiel #15
0
    def get_dielectric_function(self, filename='df.dat', readfile=None):

        if self.epsilon_w is None:
            self.initialize()

            if readfile is None:
                H_sS = self.calculate()
                self.printtxt('Diagonalizing %s matrix.' % self.mode)
                self.diagonalize(H_sS)
                self.printtxt('Calculating dielectric function.')
            elif readfile == 'H_SS':
                H_sS = self.par_load('H_SS', 'H_SS')
                self.printtxt('Finished reading H_SS.gpw')
                self.diagonalize(H_sS)
                self.printtxt('Finished diagonalizing BSE matrix')
            elif readfile == 'v_SS':
                self.v_SS = self.par_load('v_SS', 'v_SS')
                self.printtxt('Finished reading v_SS.gpw')
            else:
                XX

            w_S = self.w_S
            if not self.coupling:
                v_SS = self.v_SS.T # v_SS[:,lamda]
            else:
                v_SS = self.v_SS
            rhoG0_S = self.rhoG0_S
            focc_S = self.focc_S

            # get overlap matrix
            if self.coupling:
                tmp = np.dot(v_SS.conj().T, v_SS )
                overlap_SS = np.linalg.inv(tmp)
    
            # get chi
            epsilon_w = np.zeros(self.Nw, dtype=complex)
            t0 = time()

            A_S = np.dot(rhoG0_S, v_SS)
            B_S = np.dot(rhoG0_S*focc_S, v_SS)
            if self.coupling:
                C_S = np.dot(B_S.conj(), overlap_SS.T) * A_S
            else:
                if world.size == 1:
                    C_S = B_S.conj() * A_S
                else:
                    tmp = B_S.conj() * A_S
                    C_S = gatherv(tmp, self.nS)

            for iw in range(self.Nw):
                tmp_S = 1. / (iw*self.dw - w_S + 1j*self.eta)
                epsilon_w[iw] += np.dot(tmp_S, C_S)
    
            epsilon_w *=  - 4 * pi / np.inner(self.qq_v, self.qq_v) / self.vol
            epsilon_w += 1        

            self.epsilon_w = epsilon_w
    
        if rank == 0:
            f = open(filename,'w')
            #g = open('excitons.dat', 'w')
            for iw in range(self.Nw):
                energy = iw * self.dw * Hartree
                print >> f, energy, np.real(epsilon_w[iw]), np.imag(epsilon_w[iw])
                #print >> g, energy, np.real(C_S[iw])/max(abs(C_S))
            f.close()
            #g.close()
        # Wait for I/O to finish
        world.barrier()

        """Check f-sum rule."""
        N1 = 0
        for iw in range(self.Nw):
            w = iw * self.dw
            N1 += np.imag(epsilon_w[iw]) * w
        N1 *= self.dw * self.vol / (2 * pi**2)

        self.printtxt('')
        self.printtxt('Sum rule:')
        nv = self.nvalence
        self.printtxt('N1 = %f, %f  %% error' %(N1, (N1 - nv) / nv * 100) )

        return epsilon_w
Beispiel #16
0
    def calculate(self):
        calc = self.calc
        focc_S = self.focc_S
        e_S = self.e_S
        op_scc = calc.wfs.kd.symmetry.op_scc

        # Get phi_qaGp
        if self.mode == 'RPA':
            self.phi_aGp = self.get_phi_aGp()
        else:
            fd = opencew('phi_qaGp')
            if fd is None:
                self.reader = Reader('phi_qaGp')
                tmp = self.load_phi_aGp(self.reader, 0)[0]
                assert len(tmp) == self.npw
                self.printtxt('Finished reading phi_aGp')
            else:
                self.printtxt('Calculating phi_qaGp')
                self.get_phi_qaGp()
                world.barrier()
                self.reader = Reader('phi_qaGp')
            self.printtxt('Memory used %f M' % (maxrss() / 1024.**2))
            self.printtxt('')

        if self.optical_limit:
            iq = np.where(np.sum(abs(self.ibzq_qc), axis=1) < 1e-5)[0][0]
        else:
            iq = np.where(
                np.sum(abs(self.ibzq_qc - self.q_c), axis=1) < 1e-5)[0][0]
        kc_G = np.array([self.V_qGG[iq, iG, iG] for iG in range(self.npw)])
        if self.optical_limit:
            kc_G[0] = 0.

        # Get screened Coulomb kernel
        if self.mode == 'BSE':
            try:
                # Read
                data = pickle.load(open(self.kernel_file + '.pckl'))
                W_qGG = data['W_qGG']
                assert np.shape(W_qGG) == np.shape(self.V_qGG)
                self.printtxt('Finished reading screening interaction kernel')
            except:
                # Calculate from scratch
                self.printtxt('Calculating screening interaction kernel.')
                W_qGG = self.full_static_screened_interaction()
            self.printtxt('')
        else:
            W_qGG = self.V_qGG

        t0 = time()
        self.printtxt('Calculating %s matrix elements' % self.mode)

        # Calculate full kernel
        K_SS = np.zeros((self.nS_local, self.nS), dtype=complex)
        self.rhoG0_S = np.zeros(self.nS, dtype=complex)

        #noGmap = 0
        for iS in range(self.nS_start, self.nS_end):
            k1, n1, m1 = self.Sindex_S3[iS]
            rho1_G = self.density_matrix(n1, m1, k1)
            self.rhoG0_S[iS] = rho1_G[0]
            for jS in range(self.nS):
                k2, n2, m2 = self.Sindex_S3[jS]
                rho2_G = self.density_matrix(n2, m2, k2)
                K_SS[iS - self.nS_start,
                     jS] = np.sum(rho1_G.conj() * rho2_G * kc_G)

                if not self.mode == 'RPA':
                    rho3_G = self.density_matrix(n1, n2, k1, k2)
                    rho4_G = self.density_matrix(m1, m2, self.kq_k[k1],
                                                 self.kq_k[k2])

                    q_c = self.kd.bzk_kc[k2] - self.kd.bzk_kc[k1]
                    q_c[np.where(q_c > 0.501)] -= 1.
                    q_c[np.where(q_c < -0.499)] += 1.
                    iq = self.kd.where_is_q(q_c, self.bzq_qc)

                    if not self.qsymm:
                        W_GG = W_qGG[iq]
                    else:
                        ibzq = self.ibzq_q[iq]
                        W_GG_tmp = W_qGG[ibzq]

                        iop = self.iop_q[iq]
                        timerev = self.timerev_q[iq]
                        diff_c = self.diff_qc[iq]
                        invop = np.linalg.inv(op_scc[iop])
                        Gindex = np.zeros(self.npw, dtype=int)
                        for iG in range(self.npw):
                            G_c = self.Gvec_Gc[iG]
                            if timerev:
                                RotG_c = -np.int8(
                                    np.dot(invop, G_c + diff_c).round())
                            else:
                                RotG_c = np.int8(
                                    np.dot(invop, G_c + diff_c).round())
                            tmp_G = np.abs(self.Gvec_Gc - RotG_c).sum(axis=1)
                            try:
                                Gindex[iG] = np.where(tmp_G < 1e-5)[0][0]
                            except:
                                #noGmap += 1
                                Gindex[iG] = -1

                        W_GG = np.zeros_like(W_GG_tmp)
                        for iG in range(self.npw):
                            for jG in range(self.npw):
                                if Gindex[iG] == -1 or Gindex[jG] == -1:
                                    W_GG[iG, jG] = 0
                                else:
                                    W_GG[iG, jG] = W_GG_tmp[Gindex[iG],
                                                            Gindex[jG]]

                    if self.mode == 'BSE':
                        tmp_GG = np.outer(rho3_G.conj(), rho4_G) * W_GG
                        K_SS[iS - self.nS_start, jS] -= 0.5 * np.sum(tmp_GG)
                    else:
                        tmp_G = rho3_G.conj() * rho4_G * np.diag(W_GG)
                        K_SS[iS - self.nS_start, jS] -= 0.5 * np.sum(tmp_G)
            self.timing(iS, t0, self.nS_local, 'pair orbital')

        K_SS /= self.vol

        world.sum(self.rhoG0_S)
        #self.printtxt('Number of G indices outside the Gvec_Gc: %d' % noGmap)

        # Get and solve Hamiltonian
        H_sS = np.zeros_like(K_SS)
        for iS in range(self.nS_start, self.nS_end):
            H_sS[iS - self.nS_start, iS] = e_S[iS]
            for jS in range(self.nS):
                H_sS[iS - self.nS_start,
                     jS] += focc_S[iS] * K_SS[iS - self.nS_start, jS]

        # Force matrix to be Hermitian
        if not self.coupling:
            if world.size > 1:
                H_Ss = self.redistribute_H(H_sS)
            else:
                H_Ss = H_sS
            H_sS = (np.real(H_sS) + np.real(H_Ss.T)) / 2. + 1j * (
                np.imag(H_sS) - np.imag(H_Ss.T)) / 2.

        # Save H_sS matrix
        self.par_save('H_SS', 'H_SS', H_sS)

        return H_sS
Beispiel #17
0
    def calculate(self):
        calc = self.calc
        f_skn = self.f_skn
        e_skn = self.e_skn
        kq_k = self.kq_k
        focc_S = self.focc_S
        e_S = self.e_S
        op_scc = calc.wfs.symmetry.op_scc

        # Get phi_qaGp
        if self.mode == 'RPA':
            self.phi_aGp = self.get_phi_aGp()
        else:
            try:
                self.reader = Reader('phi_qaGp')
                tmp = self.load_phi_aGp(self.reader, 0)[0]
                assert len(tmp) == self.npw
                self.printtxt('Finished reading phi_aGp')
            except:
                self.printtxt('Calculating phi_qaGp')
                self.get_phi_qaGp()
                world.barrier()
                self.reader = Reader('phi_qaGp')                
            self.printtxt('Memory used %f M' % (maxrss() / 1024.**2))
            self.printtxt('')

        if self.optical_limit:
            iq = np.where(np.sum(abs(self.ibzq_qc), axis=1) < 1e-5)[0][0]
        else:
            iq = np.where(np.sum(abs(self.ibzq_qc - self.q_c), axis=1) < 1e-5)[0][0]
        kc_G = np.array([self.V_qGG[iq, iG, iG] for iG in range(self.npw)])
        if self.optical_limit:
            kc_G[0] = 0.

        # Get screened Coulomb kernel
        if self.mode == 'BSE':
            try:
                # Read
                data = pickle.load(open(self.kernel_file+'.pckl'))
                W_qGG = data['W_qGG']
                assert np.shape(W_qGG) == np.shape(self.V_qGG)
                self.printtxt('Finished reading screening interaction kernel')
            except:
                # Calculate from scratch
                self.printtxt('Calculating screening interaction kernel.')
                W_qGG = self.full_static_screened_interaction()
            self.printtxt('')
        else:
            W_qGG = self.V_qGG
 
        t0 = time()
        self.printtxt('Calculating %s matrix elements' % self.mode)

        # Calculate full kernel
        K_SS = np.zeros((self.nS_local, self.nS), dtype=complex)
        self.rhoG0_S = np.zeros(self.nS, dtype=complex)

        #noGmap = 0
        for iS in range(self.nS_start, self.nS_end):
            k1, n1, m1 = self.Sindex_S3[iS]
            rho1_G = self.density_matrix(n1,m1,k1)
            self.rhoG0_S[iS] = rho1_G[0]
            for jS in range(self.nS):
                k2, n2, m2 = self.Sindex_S3[jS]
                rho2_G = self.density_matrix(n2,m2,k2)
                K_SS[iS-self.nS_start, jS] = np.sum(rho1_G.conj() * rho2_G * kc_G)

                if not self.mode == 'RPA':
                    rho3_G = self.density_matrix(n1,n2,k1,k2)
                    rho4_G = self.density_matrix(m1,m2,self.kq_k[k1],
                                                 self.kq_k[k2])

                    q_c = self.kd.bzk_kc[k2] - self.kd.bzk_kc[k1]
                    q_c[np.where(q_c > 0.501)] -= 1.
                    q_c[np.where(q_c < -0.499)] += 1.
                    iq = self.kd.where_is_q(q_c, self.bzq_qc)
                    
                    if not self.qsymm:    
                        W_GG = W_qGG[iq]
                    else:
                        ibzq = self.ibzq_q[iq]
                        W_GG_tmp = W_qGG[ibzq]

                        iop = self.iop_q[iq]
                        timerev = self.timerev_q[iq]
                        diff_c = self.diff_qc[iq]
                        invop = np.linalg.inv(op_scc[iop])
                        Gindex = np.zeros(self.npw, dtype=int)
                        for iG in range(self.npw):
                            G_c = self.Gvec_Gc[iG]
                            if timerev:
                                RotG_c = -np.int8(np.dot(invop, G_c+diff_c).round())
                            else:
                                RotG_c = np.int8(np.dot(invop, G_c+diff_c).round())
                            tmp_G = np.abs(self.Gvec_Gc - RotG_c).sum(axis=1)
                            try:
                                Gindex[iG] = np.where(tmp_G < 1e-5)[0][0]
                            except:
                                #noGmap += 1
                                Gindex[iG] = -1
    
                        W_GG = np.zeros_like(W_GG_tmp)
                        for iG in range(self.npw):
                            for jG in range(self.npw):
                                if Gindex[iG] == -1 or Gindex[jG] == -1:
                                    W_GG[iG, jG] = 0
                                else:
                                    W_GG[iG, jG] = W_GG_tmp[Gindex[iG], Gindex[jG]]
                                    
                    if self.mode == 'BSE':
                        tmp_GG = np.outer(rho3_G.conj(), rho4_G) * W_GG
                        K_SS[iS-self.nS_start, jS] -= 0.5 * np.sum(tmp_GG)
                    else:
                        tmp_G = rho3_G.conj() * rho4_G * np.diag(W_GG)
                        K_SS[iS-self.nS_start, jS] -= 0.5 * np.sum(tmp_G)
            self.timing(iS, t0, self.nS_local, 'pair orbital') 
 
        K_SS /= self.vol

        world.sum(self.rhoG0_S)
        #self.printtxt('Number of G indices outside the Gvec_Gc: %d' % noGmap)

        # Get and solve Hamiltonian
        H_sS = np.zeros_like(K_SS)
        for iS in range(self.nS_start, self.nS_end):
            H_sS[iS-self.nS_start,iS] = e_S[iS]
            for jS in range(self.nS):
                H_sS[iS-self.nS_start,jS] += focc_S[iS] * K_SS[iS-self.nS_start,jS]
  
        # Force matrix to be Hermitian
        if not self.coupling:
            if world.size > 1:
                H_Ss = self.redistribute_H(H_sS)
            else:
                H_Ss = H_sS
            H_sS = (np.real(H_sS) + np.real(H_Ss.T)) / 2. + 1j * (np.imag(H_sS) - np.imag(H_Ss.T)) /2.

        # Save H_sS matrix
        self.par_save('H_SS','H_SS', H_sS)

        return H_sS
Beispiel #18
0
    def get_dielectric_function(self, filename='df.dat', readfile=None):

        if self.epsilon_w is None:
            self.initialize()

            if readfile is None:
                H_sS = self.calculate()
                self.printtxt('Diagonalizing %s matrix.' % self.mode)
                self.diagonalize(H_sS)
                self.printtxt('Calculating dielectric function.')
            elif readfile == 'H_SS':
                H_sS = self.par_load('H_SS', 'H_SS')
                self.printtxt('Finished reading H_SS.gpw')
                self.diagonalize(H_sS)
                self.printtxt('Finished diagonalizing BSE matrix')
            elif readfile == 'v_SS':
                self.v_SS = self.par_load('v_SS', 'v_SS')
                self.printtxt('Finished reading v_SS.gpw')
            else:
                1 / 0

            w_S = self.w_S
            if not self.coupling:
                v_SS = self.v_SS.T  # v_SS[:,lamda]
            else:
                v_SS = self.v_SS
            rhoG0_S = self.rhoG0_S
            focc_S = self.focc_S

            # get overlap matrix
            if self.coupling:
                tmp = np.dot(v_SS.conj().T, v_SS)
                overlap_SS = np.linalg.inv(tmp)

            # get chi
            epsilon_w = np.zeros(self.Nw, dtype=complex)

            A_S = np.dot(rhoG0_S, v_SS)
            B_S = np.dot(rhoG0_S * focc_S, v_SS)
            if self.coupling:
                C_S = np.dot(B_S.conj(), overlap_SS.T) * A_S
            else:
                if world.size == 1:
                    C_S = B_S.conj() * A_S
                else:
                    tmp = B_S.conj() * A_S
                    C_S = gatherv(tmp, self.nS)

            for iw in range(self.Nw):
                tmp_S = 1. / (iw * self.dw - w_S + 1j * self.eta)
                epsilon_w[iw] += np.dot(tmp_S, C_S)

            epsilon_w *= -4 * pi / np.inner(self.qq_v, self.qq_v) / self.vol
            epsilon_w += 1

            self.epsilon_w = epsilon_w

        if rank == 0:
            f = open(filename, 'w')
            for iw in range(self.Nw):
                energy = iw * self.dw * Hartree
                print(energy,
                      np.real(epsilon_w[iw]),
                      np.imag(epsilon_w[iw]),
                      file=f)
            f.close()
            #g.close()
        # Wait for I/O to finish
        world.barrier()
        """Check f-sum rule."""
        N1 = 0
        for iw in range(self.Nw):
            w = iw * self.dw
            N1 += np.imag(epsilon_w[iw]) * w
        N1 *= self.dw * self.vol / (2 * pi**2)

        self.printtxt('')
        self.printtxt('Sum rule:')
        nv = self.nvalence
        self.printtxt('N1 = %f, %f  %% error' % (N1, (N1 - nv) / nv * 100))

        return epsilon_w