def get_dielectric_matrix(self, xc='RPA', overwritechi0=False, symmetric=True, chi0_wGG=None, calc=None, vcut=None, dir=None): if self.chi0_wGG is None and chi0_wGG is None: self.initialize() self.calculate() elif self.chi0_wGG is None and chi0_wGG is not None: #Read from file and reinitialize self.xc = xc from gpaw.response.parallel import par_read self.chi0_wGG = par_read(chi0_wGG, 'chi0_wGG') self.nvalbands = self.nbands #self.parallel_init() # parallelization not yet implemented self.Nw_local = self.Nw # parallelization not yet implemented if self.calc is None: from gpaw import GPAW self.calc = GPAW(calc,txt=None) if self.xc == 'ALDA' or self.xc == 'ALDA_X': from gpaw.response.kernel import calculate_Kxc from gpaw.grid_descriptor import GridDescriptor from gpaw.mpi import world, rank, size, serial_comm self.pbc = self.calc.atoms.pbc self.gd = GridDescriptor(self.calc.wfs.gd.N_c*self.rpad, self.acell_cv, pbc_c=True, comm=serial_comm) R_av = self.calc.atoms.positions / Bohr nt_sg = self.calc.density.nt_sG if (self.rpad > 1).any() or (self.pbc - True).any(): nt_sG = self.gd.zeros(self.nspins) #nt_sG = np.zeros([self.nspins, self.nG[0], self.nG[1], self.nG[2]]) for s in range(self.nspins): nt_G = self.pad(nt_sg[s]) nt_sG[s] = nt_G else: nt_sG = nt_sg self.Kxc_sGG = calculate_Kxc(self.gd, nt_sG, self.npw, self.Gvec_Gc, self.gd.N_c, self.vol, self.bcell_cv, R_av, self.calc.wfs.setups, self.calc.density.D_asp, functional=self.xc, density_cut=self.density_cut) if overwritechi0: dm_wGG = self.chi0_wGG else: dm_wGG = np.zeros_like(self.chi0_wGG) if dir is None: q_c = self.q_c else: q_c = np.diag((1,1,1))[dir] * self.qopt self.chi0_wGG[:,0,:] = self.chi00G_wGv[:,:,dir] self.chi0_wGG[:,:,0] = self.chi0G0_wGv[:,:,dir] from gpaw.response.kernel import calculate_Kc, CoulombKernel kernel = CoulombKernel(vcut=self.vcut, pbc=self.calc.atoms.pbc, cell=self.acell_cv) self.Kc_GG = kernel.calculate_Kc(q_c, self.Gvec_Gc, self.bcell_cv, symmetric=symmetric) #self.Kc_GG = calculate_Kc(q_c, # self.Gvec_Gc, # self.acell_cv, # self.bcell_cv, # self.pbc, # self.vcut, # symmetric=symmetric) tmp_GG = np.eye(self.npw, self.npw) if xc == 'RPA': self.printtxt('Use RPA.') for iw in range(self.Nw_local): dm_wGG[iw] = tmp_GG - self.Kc_GG * self.chi0_wGG[iw] elif xc == 'ALDA': self.printtxt('Use ALDA kernel.') # E_LDA = 1 - v_c chi0 (1-fxc chi0)^-1 # http://prb.aps.org/pdf/PRB/v33/i10/p7017_1 eq. 4 A_wGG = self.chi0_wGG.copy() for iw in range(self.Nw_local): A_wGG[iw] = np.dot(self.chi0_wGG[iw], np.linalg.inv(tmp_GG - np.dot(self.Kxc_sGG[0], self.chi0_wGG[iw]))) for iw in range(self.Nw_local): dm_wGG[iw] = tmp_GG - self.Kc_GG * A_wGG[iw] return dm_wGG
def get_dielectric_matrix(self, xc='RPA', overwritechi0=False, symmetric=True, chi0_wGG=None, calc=None, vcut=None, dir=None): if self.chi0_wGG is None and chi0_wGG is None: self.initialize() self.calculate() elif self.chi0_wGG is None and chi0_wGG is not None: #Read from file and reinitialize self.xc = xc from gpaw.response.parallel import par_read self.chi0_wGG = par_read(chi0_wGG, 'chi0_wGG') self.nvalbands = self.nbands #self.parallel_init() # parallelization not yet implemented self.Nw_local = self.Nw # parallelization not yet implemented if self.calc is None: from gpaw import GPAW self.calc = GPAW(calc, txt=None) if self.xc == 'ALDA' or self.xc == 'ALDA_X': from gpaw.response.kernel import calculate_Kxc from gpaw.grid_descriptor import GridDescriptor from gpaw.mpi import world, rank, size, serial_comm self.pbc = self.calc.atoms.pbc self.gd = GridDescriptor(self.calc.wfs.gd.N_c * self.rpad, self.acell_cv, pbc_c=True, comm=serial_comm) R_av = self.calc.atoms.positions / Bohr nt_sg = self.calc.density.nt_sG if (self.rpad > 1).any() or (self.pbc - True).any(): nt_sG = self.gd.zeros(self.nspins) #nt_sG = np.zeros([self.nspins, self.nG[0], self.nG[1], self.nG[2]]) for s in range(self.nspins): nt_G = self.pad(nt_sg[s]) nt_sG[s] = nt_G else: nt_sG = nt_sg self.Kxc_sGG = calculate_Kxc(self.gd, nt_sG, self.npw, self.Gvec_Gc, self.gd.N_c, self.vol, self.bcell_cv, R_av, self.calc.wfs.setups, self.calc.density.D_asp, functional=self.xc, density_cut=self.density_cut) if overwritechi0: dm_wGG = self.chi0_wGG else: dm_wGG = np.zeros_like(self.chi0_wGG) if dir is None: q_c = self.q_c else: q_c = np.diag((1, 1, 1))[dir] * self.qopt self.chi0_wGG[:, 0, :] = self.chi00G_wGv[:, :, dir] self.chi0_wGG[:, :, 0] = self.chi0G0_wGv[:, :, dir] from gpaw.response.kernel import calculate_Kc, CoulombKernel kernel = CoulombKernel(vcut=self.vcut, pbc=self.calc.atoms.pbc, cell=self.acell_cv) self.Kc_GG = kernel.calculate_Kc(q_c, self.Gvec_Gc, self.bcell_cv, symmetric=symmetric) #self.Kc_GG = calculate_Kc(q_c, # self.Gvec_Gc, # self.acell_cv, # self.bcell_cv, # self.pbc, # self.vcut, # symmetric=symmetric) tmp_GG = np.eye(self.npw, self.npw) if xc == 'RPA': self.printtxt('Use RPA.') for iw in range(self.Nw_local): dm_wGG[iw] = tmp_GG - self.Kc_GG * self.chi0_wGG[iw] elif xc == 'ALDA': self.printtxt('Use ALDA kernel.') # E_LDA = 1 - v_c chi0 (1-fxc chi0)^-1 # http://prb.aps.org/pdf/PRB/v33/i10/p7017_1 eq. 4 A_wGG = self.chi0_wGG.copy() for iw in range(self.Nw_local): A_wGG[iw] = np.dot( self.chi0_wGG[iw], np.linalg.inv(tmp_GG - np.dot(self.Kxc_sGG[0], self.chi0_wGG[iw]))) for iw in range(self.Nw_local): dm_wGG[iw] = tmp_GG - self.Kc_GG * A_wGG[iw] return dm_wGG
import numpy as np from gpaw.mpi import size, rank, world from gpaw.response.parallel import par_write, par_read Nw = 400 npw = 10 assert Nw % size == 0 Nw_local = Nw // size chi0_wGG = np.ones((Nw_local, npw, npw), dtype=complex) * rank filename = 'chi0' name = 'chi0_wGG' par_write(filename, name, world, chi0_wGG) chi0_wGG_new = par_read(filename, name) assert (np.abs(chi0_wGG - chi0_wGG_new) < 1e-10).all()
import numpy as np from gpaw.mpi import size, rank, world from gpaw.response.parallel import par_write, par_read Nw = 400 npw = 10 assert Nw % size == 0 Nw_local = Nw // size chi0_wGG = np.ones((Nw_local, npw, npw),dtype=complex) * rank filename = 'chi0' name = 'chi0_wGG' par_write(filename, name, world, chi0_wGG) chi0_wGG_new = par_read(filename, name) assert (np.abs(chi0_wGG - chi0_wGG_new) < 1e-10).all()