Esempio n. 1
0
    def diagonalize(self, H_sS):
        if self.coupling: # Non-Hermitian matrix can only use linalg.eig
            self.printtxt('Use numpy.linalg.eig')
            H_SS = np.zeros((self.nS, self.nS), dtype=complex)
            if self.nS % world.size == 0:
                world.all_gather(H_sS, H_SS)
            else:
                H_SS = gatherv(H_sS)

            self.w_S, self.v_SS = np.linalg.eig(H_SS)
            self.par_save('v_SS', 'v_SS', self.v_SS[self.nS_start:self.nS_end, :].copy())
        else:
            if world.size == 1:
                self.printtxt('Use lapack.')
                from gpaw.utilities.lapack import diagonalize
                self.w_S = np.zeros(self.nS)
                H_SS = H_sS
                diagonalize(H_SS, self.w_S)
                self.v_SS = H_SS.conj() # eigenvectors in the rows, transposed later
            else:
                self.printtxt('Use scalapack')
                self.w_S, self.v_sS = self.scalapack_diagonalize(H_sS)
                self.v_SS = self.v_sS # just use the same name
            self.par_save('v_SS', 'v_SS', self.v_SS)
        
        return 
Esempio n. 2
0
    def diagonalize(self, H_sS):
        if self.coupling:  # Non-Hermitian matrix can only use linalg.eig
            self.printtxt('Use numpy.linalg.eig')
            H_SS = np.zeros((self.nS, self.nS), dtype=complex)
            if self.nS % world.size == 0:
                world.all_gather(H_sS, H_SS)
            else:
                H_SS = gatherv(H_sS)

            self.w_S, self.v_SS = np.linalg.eig(H_SS)
            self.par_save('v_SS', 'v_SS',
                          self.v_SS[self.nS_start:self.nS_end, :].copy())
        else:
            if world.size == 1:
                self.printtxt('Use lapack.')
                from gpaw.utilities.lapack import diagonalize
                self.w_S = np.zeros(self.nS)
                H_SS = H_sS
                diagonalize(H_SS, self.w_S)
                self.v_SS = H_SS.conj(
                )  # eigenvectors in the rows, transposed later
            else:
                self.printtxt('Use scalapack')
                self.w_S, self.v_sS = self.scalapack_diagonalize(H_sS)
                self.v_SS = self.v_sS  # just use the same name
            self.par_save('v_SS', 'v_SS', self.v_SS)

        return
Esempio n. 3
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
Esempio n. 4
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