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
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
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
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