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
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
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('Calculating RPA response function', file=self.txt) print('Polarization: %s' % d, file=self.txt) 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('Calculating real space integrals', file=self.txt) 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('Calculating dynamic polarizability', file=self.txt) 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('C06 = %s Ha*Bohr**6' % (C06.real / Ha), file=self.txt) print('C6 = %s Ha*Bohr**6' % (C6.real / Ha), file=self.txt) print(file=self.txt) return C6.real / Ha, C06.real / Ha
def initialize_calculation(self, w, ecut, nbands, kcommsize, gauss_legendre, frequency_cut, frequency_scale): if kcommsize is None: if len(self.calc.wfs.kd.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(file=self.txt) print('Planewave cutoff : %s eV' % ecut, file=self.txt) print('Number of Planewaves at Gamma : %s' % self.npw, file=self.txt) if self.nbands is None: print('Response function bands :'\ + ' Equal to number of Planewaves', file=self.txt) else: print('Response function bands : %s' \ % self.nbands, file=self.txt) print('Frequencies', file=self.txt) if self.gauss_legendre is not None: print(' Gauss-Legendre integration '\ + 'with %s frequency points' % len(self.w), file=self.txt) print(' Frequency cutoff is '\ + '%s eV and scale (B) is %s' % (self.w[-1], self.frequency_scale), file=self.txt) else: print(' %s specified frequency points' \ % len(self.w), file=self.txt) print(' Frequency cutoff is %s eV' \ % self.w[-1], file=self.txt) print(file=self.txt) print('Parallelization scheme', file=self.txt) print(' Total CPUs : %d' % dummy.comm.size, file=self.txt) if dummy.kd.nbzkpts == 1: print(' Band parsize : %d' % dummy.kcomm.size, file=self.txt) else: print(' Kpoint parsize : %d' % dummy.kcomm.size, file=self.txt) print(' Frequency parsize : %d' % dummy.wScomm.size, file=self.txt) print('Memory usage estimate', file=self.txt) print(' chi0_wGG(Q) : %f M / cpu' \ % (dummy.Nw_local * self.npw**2 * 16. / 1024**2), file=self.txt) print(file=self.txt) del dummy
# view(atoms) atoms.get_potential_energy() calc.write('graphite.gpw', 'all') if EELS: f = paropen('graphite_q_list', 'w') for i in range(1, 8): w = np.linspace(0, 40, 401) q = np.array([i / 20., 0., 0.]) # Gamma-M excitation #q = np.array([i/20., -i/20., 0.]) # Gamma-K excitation ecut = 40 + (i - 1) * 10 df = DF(calc='graphite.gpw', nbands=nband, q=q, w=w, eta=0.2, ecut=ecut) df.get_EELS_spectrum(filename='graphite_EELS_' + str(i)) df.check_sum_rule() print(sqrt(np.inner(df.qq_v / Bohr, df.qq_v / Bohr)), ecut, file=f) if rank == 0: os.remove('graphite.gpw')
nc=[0,4], coupling=True, mode='RPA', q=np.array([0.25, 0, 0]), ecut=50., eta=0.2) bse.get_dielectric_function('Al_bse.dat') if df: # Excited state calculation q = np.array([1/4.,0.,0.]) w = np.linspace(0, 24, 241) df = DF(calc='Al.gpw', q=q, w=w, eta=0.2, ecut=50, hilbert_trans=False) df.get_EELS_spectrum(filename='Al_df.dat') df.write('Al.pckl') df.check_sum_rule() if check_spectrum: d = np.loadtxt('Al_bse.dat')[:,2] wpeak = 16.4 Nw = 164 if d[Nw] > d[Nw-1] and d[Nw] > d[Nw+1]: pass else: raise ValueError('Plasmon peak not correct ! ')
def screened_interaction_kernel(self, iq): """Calcuate W_GG(w) for a given q. if static: return W_GG(w=0) is not static: return W_GG(q,w) - Vc_GG """ q = self.ibzq_qc[iq] w = self.w_w.copy() * Hartree optical_limit = False if np.abs(q).sum() < 1e-8: q = np.array([1e-12, 0, 0]) # arbitrary q, not really need to be calculated optical_limit = True hilbert_trans = True if self.ppa or self.static: hilbert_trans = False df = DF(calc=self.calc, q=q.copy(), w=w, nbands=self.nbands, eshift=None, optical_limit=optical_limit, hilbert_trans=hilbert_trans, xc='RPA', time_ordered=True, rpad=self.rpad, vcut=self.vcut, G_plus_q=True, eta=self.eta * Hartree, ecut=self.ecut.copy() * Hartree, txt='df.out', comm=self.dfcomm, kcommsize=self.kcommsize) df.initialize() df.e_skn = self.e_skn.copy() df.calculate() dfinv_wGG = df.get_inverse_dielectric_matrix(xc='RPA') assert df.ecut[0] == self.ecut[0] if not self.static and not self.ppa: assert df.eta == self.eta assert df.Nw == self.Nw assert df.dw == self.dw # calculate Coulomb kernel and use truncation in 2D delta_GG = np.eye(df.npw) Vq_G = np.diag( calculate_Kc(q, df.Gvec_Gc, self.acell_cv, self.bcell_cv, self.pbc, integrate_gamma=True, N_k=self.kd.N_c, vcut=self.vcut))**0.5 if (self.vcut == '2D' and df.optical_limit) or self.numint: for iG in range(len(df.Gvec_Gc)): if df.Gvec_Gc[iG, 0] == 0 and df.Gvec_Gc[iG, 1] == 0: v_q, v0_q = calculate_Kc_q(self.acell_cv, self.bcell_cv, self.pbc, self.kd.N_c, vcut=self.vcut, q_qc=np.array([q]), Gvec_c=df.Gvec_Gc[iG]) Vq_G[iG] = v_q[0]**0.5 self.Kc_GG = np.outer(Vq_G, Vq_G) if self.ppa: dfinv1_GG = dfinv_wGG[0] - delta_GG dfinv2_GG = dfinv_wGG[1] - delta_GG self.wt_GG = self.E0 * np.sqrt(dfinv2_GG / (dfinv1_GG - dfinv2_GG)) self.R_GG = -self.wt_GG / 2 * dfinv1_GG del dfinv_wGG dfinv_wGG = np.array([1j * pi * self.R_GG + delta_GG]) if self.static: assert len(dfinv_wGG) == 1 W_GG = dfinv_wGG[0] * self.Kc_GG return df, W_GG else: Nw = np.shape(dfinv_wGG)[0] W_wGG = np.zeros_like(dfinv_wGG) for iw in range(Nw): dfinv_wGG[iw] -= delta_GG W_wGG[iw] = dfinv_wGG[iw] * self.Kc_GG return df, W_wGG
def screened_interaction_kernel(self, iq): """Calcuate W_GG(w) for a given q. if static: return W_GG(w=0) is not static: return W_GG(q,w) - Vc_GG """ q = self.ibzq_qc[iq] w = self.w_w.copy()*Hartree optical_limit = False if np.abs(q).sum() < 1e-8: q = np.array([1e-12, 0, 0]) # arbitrary q, not really need to be calculated optical_limit = True hilbert_trans = True if self.ppa or self.static: hilbert_trans = False df = DF(calc=self.calc, q=q.copy(), w=w, nbands=self.nbands, eshift=None, optical_limit=optical_limit, hilbert_trans=hilbert_trans, xc='RPA', time_ordered=True, rpad=self.rpad, vcut=self.vcut, G_plus_q=True, eta=self.eta*Hartree, ecut=self.ecut.copy()*Hartree, txt='df.out', comm=self.dfcomm, kcommsize=self.kcommsize) df.initialize() df.e_skn = self.e_skn.copy() df.calculate() dfinv_wGG = df.get_inverse_dielectric_matrix(xc='RPA') assert df.ecut[0] == self.ecut[0] if not self.static and not self.ppa: assert df.eta == self.eta assert df.Nw == self.Nw assert df.dw == self.dw # calculate Coulomb kernel and use truncation in 2D delta_GG = np.eye(df.npw) Vq_G = np.diag(calculate_Kc(q, df.Gvec_Gc, self.acell_cv, self.bcell_cv, self.pbc, integrate_gamma=True, N_k=self.kd.N_c, vcut=self.vcut))**0.5 if (self.vcut == '2D' and df.optical_limit) or self.numint: for iG in range(len(df.Gvec_Gc)): if df.Gvec_Gc[iG, 0] == 0 and df.Gvec_Gc[iG, 1] == 0: v_q, v0_q = calculate_Kc_q(self.acell_cv, self.bcell_cv, self.pbc, self.kd.N_c, vcut=self.vcut, q_qc=np.array([q]), Gvec_c=df.Gvec_Gc[iG]) Vq_G[iG] = v_q[0]**0.5 self.Kc_GG = np.outer(Vq_G, Vq_G) if self.ppa: dfinv1_GG = dfinv_wGG[0] - delta_GG dfinv2_GG = dfinv_wGG[1] - delta_GG self.wt_GG = self.E0 * np.sqrt(dfinv2_GG / (dfinv1_GG - dfinv2_GG)) self.R_GG = - self.wt_GG / 2 * dfinv1_GG del dfinv_wGG dfinv_wGG = np.array([1j*pi*self.R_GG + delta_GG]) if self.static: assert len(dfinv_wGG) == 1 W_GG = dfinv_wGG[0] * self.Kc_GG return df, W_GG else: Nw = np.shape(dfinv_wGG)[0] W_wGG = np.zeros_like(dfinv_wGG) for iw in range(Nw): dfinv_wGG[iw] -= delta_GG W_wGG[iw] = dfinv_wGG[iw] * self.Kc_GG return df, W_wGG
occupations=FermiDirac(0.001), convergence={'bands': 70}) atoms.set_calculator(calc) atoms.get_potential_energy() calc.write('si.gpw', 'all') if ABS: w = np.linspace(0, 24, 481) q = np.array([0.0, 0.00001, 0.]) # getting macroscopic constant df = DF(calc='si.gpw', q=q, w=(0., ), eta=0.001, hilbert_trans=False, ecut=150, optical_limit=True, txt='df_1.out') eM1, eM2 = df.get_macroscopic_dielectric_constant() df.write('df_1.pckl') if np.abs(eM1 - 13.991793) > 1e-3 or np.abs(eM2 - 12.589129) > 1e-3: print(eM1, eM2) raise ValueError('Please check dielectric constant !') #getting absorption spectrum df = DF(calc='si.gpw', q=q,
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('Calculating RPA response function', file=self.txt) print('Polarization: %s' % d, file=self.txt) 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('Calculating real space integrals', file=self.txt) 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('Calculating dynamic polarizability', file=self.txt) 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('C06 = %s Ha*Bohr**6' % (C06.real / Ha), file=self.txt) print('C6 = %s Ha*Bohr**6' % (C6.real / Ha), file=self.txt) print(file=self.txt) return C6.real / Ha, C06.real / Ha
def initialize_calculation(self, w, ecut, nbands, kcommsize, gauss_legendre, frequency_cut, frequency_scale): if kcommsize is None: if len(self.calc.wfs.kd.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(file=self.txt) print('Planewave cutoff : %s eV' % ecut, file=self.txt) print('Number of Planewaves at Gamma : %s' % self.npw, file=self.txt) if self.nbands is None: print('Response function bands :'\ + ' Equal to number of Planewaves', file=self.txt) else: print('Response function bands : %s' \ % self.nbands, file=self.txt) print('Frequencies', file=self.txt) if self.gauss_legendre is not None: print(' Gauss-Legendre integration '\ + 'with %s frequency points' % len(self.w), file=self.txt) print(' Frequency cutoff is '\ + '%s eV and scale (B) is %s' % (self.w[-1], self.frequency_scale), file=self.txt) else: print(' %s specified frequency points' \ % len(self.w), file=self.txt) print(' Frequency cutoff is %s eV' \ % self.w[-1], file=self.txt) print(file=self.txt) print('Parallelization scheme', file=self.txt) print(' Total CPUs : %d' % dummy.comm.size, file=self.txt) if dummy.kd.nbzkpts == 1: print(' Band parsize : %d' % dummy.kcomm.size, file=self.txt) else: print(' Kpoint parsize : %d' % dummy.kcomm.size, file=self.txt) print(' Frequency parsize : %d' % dummy.wScomm.size, file=self.txt) print('Memory usage estimate', file=self.txt) print(' chi0_wGG(Q) : %f M / cpu' \ % (dummy.Nw_local * self.npw**2 * 16. / 1024**2), file=self.txt) print(file=self.txt) del dummy
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('Calculating KS response function at:', file=self.txt) else: print('#', index, \ '- Calculating KS response function at:', file=self.txt) if optical_limit: print('q = [0 0 0] -', 'Polarization: ', direction, file=self.txt) else: print('q = [%1.6f %1.6f %1.6f] -' \ % (q[0],q[1],q[2]), '%s planewaves' % npw, file=self.txt) 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('E_c(q) = %s eV' % E_q.real, file=self.txt) print(file=self.txt) if integrated: return E_q.real else: return E_q_w.real
atoms.center() calc = GPAW(gpts=(12,12,12), eigensolver=RMM_DIIS(), mixer=Mixer(0.1,3), kpts=(4,4,4), xc='LDA') atoms.set_calculator(calc) atoms.get_potential_energy() calc.write('Al1.gpw','all') # Excited state calculation q = np.array([1./4.,0.,0.]) w = np.linspace(0, 24, 241) df = DF(calc='Al1.gpw', q=q, w=w, eta=0.2, ecut=50) #df.write('Al.pckl') df.get_EELS_spectrum(filename='EELS_Al_1') atoms = Atoms('Al8',scaled_positions=[(0,0,0), (0.5,0,0), (0,0.5,0), (0,0,0.5), (0.5,0.5,0), (0.5,0,0.5), (0.,0.5,0.5), (0.5,0.5,0.5)], cell=[(0,a,a),(a,0,a),(a,a,0)], pbc=True) calc = GPAW(gpts=(24,24,24),
def get_chiM_2D_from_old_DF(filenames_eps, read, qpoints, d=None, write_chi0 = False, name = None): #rec_cell = reciprocal_cell*Bohr #q_points = np.loadtxt(filename_qpoints) #q_points = np.dot(q_points,rec_cell) #Gvec = pickle.load(open(filename_Gvec %0)) #Gvec = np.dot(Gvec,rec_cell) # the cell has to be in bohr from gpaw.response.df0 import DF df = DF() df.read(read + str(qpoints[0])) cell = df.acell_cv Gvec = np.dot(df.Gvec_Gc,df.bcell_cv) nq = len(filenames_eps)#len(q_points[:,0]) L = cell[2,2] # Length of cell in Bohr d /= Bohr # d in Bohr z0 = L/2. # position of layer npw = Gvec.shape[0] nw = df.Nw omega_w = df.w_w#[0.] q_points_abs = [] Glist = [] for iG in range(npw): # List of G with Gx,Gy = 0 if Gvec[iG, 0] == 0 and Gvec[iG, 1] == 0: Glist.append(iG) epsM_2D_qw = np.zeros([nq, nw], dtype=complex) epsD_2D_qw = np.zeros([nq, nw], dtype=complex) chiM_2D_qw = np.zeros([nq, nw], dtype=complex) chiD_2D_qw = np.zeros([nq, nw], dtype=complex) VM_eff_qw = np.zeros([nq, nw], dtype=complex) for iq in range(nq): df.read(read + str(qpoints[iq])) la,la,la,eps_wGG, chi_wGG = pickle.load(open(filenames_eps[iq])) #chi_wGG = pickle.load(open(filenames_chi %iq)) #chi_wGG = np.array(chi_wGG) eps_inv_wGG = np.zeros_like(eps_wGG, dtype = complex) for iw in range(nw): eps_inv_wGG[iw] = np.linalg.inv(eps_wGG[iw]) eps_inv_wGG[iw] = np.identity(npw) del eps_wGG q = df.q_c#q_points[iq] q_abs = np.linalg.norm(q) q_points_abs.append(q_abs) # return q in Ang epsM_2D_inv = eps_inv_wGG[:, 0, 0] epsD_2D_inv = np.zeros_like(eps_inv_wGG[:, 0, 0], dtype = complex) chiM_2D = np.zeros_like(eps_inv_wGG[:, 0, 0], dtype = complex) #chi_wGG[:, 0, 0]# chiD_2D = np.zeros_like(eps_inv_wGG[:, 0, 0], dtype = complex) for iG in Glist[1:]: G_z = Gvec[iG, 2] epsM_2D_inv += 2./d * np.exp(1j*G_z*z0) * np.sin(G_z*d/2.) / G_z * eps_inv_wGG[:, iG, 0] for iG1 in Glist[1:]: G_z1 = Gvec[iG1, 2] # intregrate over entire cell for z and z' factor1 = z_factor(z0, L, G_z) factor2 = z_factor(z0, L, G_z1, sign=-1) chiD_2D += 1./L * factor1 * factor2 * chi_wGG[:, iG, iG1] # intregrate z over d for epsilon^-1 #factor1 = z_factor2(z0, d, G_z) #epsD_2D_inv += 2j / d / L * factor1 * factor2 * eps_inv_wGG[:, iG, iG1] #average #epsD_2D_inv += 1j * G_z * np.exp(1j*G_z*z0) * factor2 * eps_inv_wGG[:, iG, iG1] #atz0 factor1 = z_factor(z0, d, G_z) epsD_2D_inv += 12. / d**3 / L * factor1 * factor2 * eps_inv_wGG[:, iG, iG1] #kristian epsM_2D_qw[iq, :] = 1. / epsM_2D_inv epsD_2D_qw[iq, :] = 1. / epsD_2D_inv chiM_2D_qw[iq, :] = L * chi_wGG[:, 0, 0] #chiM_2D# chiD_2D_qw[iq, :] = chiD_2D del chi_wGG, eps_inv_wGG # Effective Coulomb interaction in 2D from eps_{2D}^{-1} = 1 + V_{eff} \chi_{2D} VM_eff_qw = (1. /epsM_2D_qw - 1) / chiM_2D_qw VD_eff_qw = (1. /epsD_2D_qw - 1) / chiD_2D_qw chi0M_2D_qw = (1 - epsM_2D_qw) * 1. / VM_eff_qw # Chi0 from effective Coulomb chi0D_2D_qw = (1 - epsD_2D_qw) * 1. / VD_eff_qw pickle.dump((np.array(q_points_abs), omega_w, VM_eff_qw, VD_eff_qw, chiM_2D_qw, chiD_2D_qw), open(name + '-chi.pckl', 'w')) pickle.dump((np.array(q_points_abs), omega_w, VM_eff_qw, VD_eff_qw, chi0M_2D_qw, chi0D_2D_qw, chiM_2D_qw, chiD_2D_qw, epsM_2D_qw, epsD_2D_qw), open(name + '-2D.pckl', 'w')) return np.array(q_points_abs), omega_w, chiM_2D_qw, chiD_2D_qw, VM_eff_qw, VD_eff_qw, epsM_2D_qw, epsD_2D_qw
w=np.linspace(0,20,201), mode='RPA', nc=[0,8], nv=[0,8], coupling=True, q=np.array([0.0001,0,0.]), optical_limit=True, ecut=50., nbands=8) bse.get_dielectric_function('C_bse.dat') if df: from gpaw.response.df0 import DF df = DF('C_kpt8.gpw', w=np.linspace(0,20,201), q=np.array([0.0001,0,0.]), optical_limit=True, ecut=50., hilbert_trans=False) df.get_absorption_spectrum(filename='C.dat') if check_spectrum: d = np.loadtxt('C_bse.dat')[:,2] Nw1 = 96 Nw2 = 109 if d[Nw1] > d[Nw1-1] and d[Nw1] > d[Nw1+1] and \ d[Nw2] > d[Nw2-1] and d[Nw2] > d[Nw2+1] : pass else: print(d[Nw1], d[Nw2]) raise ValueError('Absorption peak not correct ! ')
w=np.linspace(0, 20, 201), mode='RPA', nc=[0, 8], nv=[0, 8], coupling=True, q=np.array([0.0001, 0, 0.]), optical_limit=True, ecut=50., nbands=8) bse.get_dielectric_function('C_bse.dat') if df: from gpaw.response.df0 import DF df = DF('C_kpt8.gpw', w=np.linspace(0, 20, 201), q=np.array([0.0001, 0, 0.]), optical_limit=True, ecut=50., hilbert_trans=False) df.get_absorption_spectrum(filename='C.dat') if check_spectrum: d = np.loadtxt('C_bse.dat')[:, 2] Nw1 = 96 Nw2 = 109 if d[Nw1] > d[Nw1-1] and d[Nw1] > d[Nw1+1] and \ d[Nw2] > d[Nw2-1] and d[Nw2] > d[Nw2+1] : pass else: print(d[Nw1], d[Nw2]) raise ValueError('Absorption peak not correct ! ')
eigensolver='cg', occupations=FermiDirac(0.001), convergence={'bands': nbands}) atoms.set_calculator(calc) atoms.get_potential_energy() calc.write('C2.gpw', 'all') # Macroscopic dielectric constant calculation q = np.array([0.0, 0.00001, 0.]) w = np.linspace(0, 15, 150) df = DF(calc='C2.gpw', q=q, w=(0., ), eta=0.001, nbands=nbands, ecut=50, hilbert_trans=False, optical_limit=True) eM1, eM2 = df.get_macroscopic_dielectric_constant(xc='ALDA') if np.abs(eM2 - 7.914302) > 1e-3: raise ValueError( "Incorrect value for Diamond dielectric constant with ALDA Kernel %.4f" % (eM2)) # Dielectric function df = DF(calc='C2.gpw', q=q, w=w, eta=0.40,
# view(atoms) atoms.get_potential_energy() calc.write('graphite.gpw','all') if EELS: f = paropen('graphite_q_list', 'w') for i in range(1,8): w = np.linspace(0, 40, 401) q = np.array([i/20., 0., 0.]) # Gamma-M excitation #q = np.array([i/20., -i/20., 0.]) # Gamma-K excitation ecut = 40 + (i-1)*10 df = DF(calc='graphite.gpw', nbands=nband, q=q, w=w, eta=0.2,ecut=ecut) df.get_EELS_spectrum(filename='graphite_EELS_' + str(i)) df.check_sum_rule() print >> f, sqrt(np.inner(df.qq_v / Bohr, df.qq_v / Bohr)), ecut if rank == 0: os.remove('graphite.gpw')
eigensolver='cg', occupations=FermiDirac(0.001), convergence={'bands':nbands}) atoms.set_calculator(calc) atoms.get_potential_energy() calc.write('C2.gpw','all') # Macroscopic dielectric constant calculation q = np.array([0.0, 0.00001, 0.]) w = np.linspace(0,15,150) df = DF(calc='C2.gpw', q=q, w=(0.,), eta=0.001, nbands=nbands, ecut=50, hilbert_trans=False, optical_limit=True) eM1, eM2 = df.get_macroscopic_dielectric_constant(xc='ALDA') if np.abs(eM2 - 7.914302) > 1e-3: raise ValueError("Incorrect value for Diamond dielectric constant with ALDA Kernel %.4f" % (eM2)) # Dielectric function df = DF(calc='C2.gpw', q=q, w=w, eta=0.40, nbands=nbands, xc='Bootstrap',
nbands=nband+5, parallel={'domain':1, 'band':1}, convergence={'bands':nband}, eigensolver = 'cg', width=0.1) atoms.set_calculator(calc) atoms.get_potential_energy() if EELS: for i in range(1, 2): w = np.linspace(0, 15, 301) q = np.array([-i/64., i/64., 0.]) # Gamma - K ecut = 40 + i*10 df = DF(calc=calc, q=q, w=w, eta=0.05, ecut = ecut, txt='df_' + str(i) + '.out') df.get_surface_response_function(z0=21.2/2, filename='be_EELS') df.get_EELS_spectrum() df.check_sum_rule() df.write('df_' + str(i) + '.pckl') if check: d = np.loadtxt('be_EELS') wpeak1 = 2.50 # eV wpeak2 = 9.95 Nw1 = 50 Nw2 = 199 if (d[Nw1, 1] > d[Nw1-1, 1] and d[Nw1, 1] > d[Nw1+1, 1] and d[Nw2, 1] > d[Nw2-1, 1] and d[Nw2, 1] > d[Nw2+1, 1]):
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('Calculating KS response function at:', file=self.txt) else: print('#', index, \ '- Calculating KS response function at:', file=self.txt) if optical_limit: print('q = [0 0 0] -', 'Polarization: ', direction, file=self.txt) else: print('q = [%1.6f %1.6f %1.6f] -' \ % (q[0],q[1],q[2]), '%s planewaves' % npw, file=self.txt) 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('E_c(q) = %s eV' % E_q.real, file=self.txt) print(file=self.txt) if integrated: return E_q.real else: return E_q_w.real
}, convergence={'bands': nband}, eigensolver='cg', width=0.1) atoms.set_calculator(calc) atoms.get_potential_energy() if EELS: for i in range(1, 2): w = np.linspace(0, 15, 301) q = np.array([-i / 64., i / 64., 0.]) # Gamma - K ecut = 40 + i * 10 df = DF(calc=calc, q=q, w=w, eta=0.05, ecut=ecut, txt='df_' + str(i) + '.out') df.get_surface_response_function(z0=21.2 / 2, filename='be_EELS') df.get_EELS_spectrum() df.check_sum_rule() df.write('df_' + str(i) + '.pckl') if check: d = np.loadtxt('be_EELS') wpeak1 = 2.50 # eV wpeak2 = 9.95 Nw1 = 50 Nw2 = 199
def get_chiM_2D_from_old_DF(filenames_eps, read, qpoints, d=None, write_chi0=False, name=None): #rec_cell = reciprocal_cell*Bohr #q_points = np.loadtxt(filename_qpoints) #q_points = np.dot(q_points,rec_cell) #Gvec = pickle.load(open(filename_Gvec %0)) #Gvec = np.dot(Gvec,rec_cell) # the cell has to be in bohr from gpaw.response.df0 import DF df = DF() df.read(read + str(qpoints[0])) cell = df.acell_cv Gvec = np.dot(df.Gvec_Gc, df.bcell_cv) nq = len(filenames_eps) #len(q_points[:,0]) L = cell[2, 2] # Length of cell in Bohr d /= Bohr # d in Bohr z0 = L / 2. # position of layer npw = Gvec.shape[0] nw = df.Nw omega_w = df.w_w #[0.] q_points_abs = [] Glist = [] for iG in range(npw): # List of G with Gx,Gy = 0 if Gvec[iG, 0] == 0 and Gvec[iG, 1] == 0: Glist.append(iG) epsM_2D_qw = np.zeros([nq, nw], dtype=complex) epsD_2D_qw = np.zeros([nq, nw], dtype=complex) chiM_2D_qw = np.zeros([nq, nw], dtype=complex) chiD_2D_qw = np.zeros([nq, nw], dtype=complex) VM_eff_qw = np.zeros([nq, nw], dtype=complex) for iq in range(nq): df.read(read + str(qpoints[iq])) la, la, la, eps_wGG, chi_wGG = pickle.load(open(filenames_eps[iq])) #chi_wGG = pickle.load(open(filenames_chi %iq)) #chi_wGG = np.array(chi_wGG) eps_inv_wGG = np.zeros_like(eps_wGG, dtype=complex) for iw in range(nw): eps_inv_wGG[iw] = np.linalg.inv(eps_wGG[iw]) eps_inv_wGG[iw] = np.identity(npw) del eps_wGG q = df.q_c #q_points[iq] q_abs = np.linalg.norm(q) q_points_abs.append(q_abs) # return q in Ang epsM_2D_inv = eps_inv_wGG[:, 0, 0] epsD_2D_inv = np.zeros_like(eps_inv_wGG[:, 0, 0], dtype=complex) chiM_2D = np.zeros_like(eps_inv_wGG[:, 0, 0], dtype=complex) #chi_wGG[:, 0, 0]# chiD_2D = np.zeros_like(eps_inv_wGG[:, 0, 0], dtype=complex) for iG in Glist[1:]: G_z = Gvec[iG, 2] epsM_2D_inv += 2. / d * np.exp(1j * G_z * z0) * np.sin( G_z * d / 2.) / G_z * eps_inv_wGG[:, iG, 0] for iG1 in Glist[1:]: G_z1 = Gvec[iG1, 2] # intregrate over entire cell for z and z' factor1 = z_factor(z0, L, G_z) factor2 = z_factor(z0, L, G_z1, sign=-1) chiD_2D += 1. / L * factor1 * factor2 * chi_wGG[:, iG, iG1] # intregrate z over d for epsilon^-1 #factor1 = z_factor2(z0, d, G_z) #epsD_2D_inv += 2j / d / L * factor1 * factor2 * eps_inv_wGG[:, iG, iG1] #average #epsD_2D_inv += 1j * G_z * np.exp(1j*G_z*z0) * factor2 * eps_inv_wGG[:, iG, iG1] #atz0 factor1 = z_factor(z0, d, G_z) epsD_2D_inv += 12. / d**3 / L * factor1 * factor2 * eps_inv_wGG[:, iG, iG1] #kristian epsM_2D_qw[iq, :] = 1. / epsM_2D_inv epsD_2D_qw[iq, :] = 1. / epsD_2D_inv chiM_2D_qw[iq, :] = L * chi_wGG[:, 0, 0] #chiM_2D# chiD_2D_qw[iq, :] = chiD_2D del chi_wGG, eps_inv_wGG # Effective Coulomb interaction in 2D from eps_{2D}^{-1} = 1 + V_{eff} \chi_{2D} VM_eff_qw = (1. / epsM_2D_qw - 1) / chiM_2D_qw VD_eff_qw = (1. / epsD_2D_qw - 1) / chiD_2D_qw chi0M_2D_qw = (1 - epsM_2D_qw) * 1. / VM_eff_qw # Chi0 from effective Coulomb chi0D_2D_qw = (1 - epsD_2D_qw) * 1. / VD_eff_qw pickle.dump((np.array(q_points_abs), omega_w, VM_eff_qw, VD_eff_qw, chiM_2D_qw, chiD_2D_qw), open(name + '-chi.pckl', 'w')) pickle.dump( (np.array(q_points_abs), omega_w, VM_eff_qw, VD_eff_qw, chi0M_2D_qw, chi0D_2D_qw, chiM_2D_qw, chiD_2D_qw, epsM_2D_qw, epsD_2D_qw), open(name + '-2D.pckl', 'w')) return np.array( q_points_abs ), omega_w, chiM_2D_qw, chiD_2D_qw, VM_eff_qw, VD_eff_qw, epsM_2D_qw, epsD_2D_qw