def initialize_calculation(self, w, ecut, nbands, kcommsize, extrapolate): dummy = DF(calc=self.calc, eta=0.0, w=w * 1j, q=[0.,0.,0.], ecut=ecut, hilbert_trans=False, kcommsize=kcommsize) dummy.txt = devnull dummy.spin = 0 dummy.initialize() if nbands is None: nbands = dummy.npw self.nbands = nbands print >> self.txt, 'Planewave cut off : %s eV' % ecut print >> self.txt, 'Number of Planewaves : %s' % dummy.npw print >> self.txt, 'Response function bands : %s' % nbands print >> self.txt, 'Frequency range : %s - %s eV' % (w[0], w[-1]) print >> self.txt, 'Number of frequency points : %s' % len(w) if extrapolate: print >> self.txt, 'Extrapolation of frequencies : Squared Lorentzian' print >> self.txt print >> self.txt, 'Parallelization scheme' print >> self.txt, ' Total cpus : %d' % dummy.comm.size if dummy.nkpt == 1: print >> self.txt, ' Band parsize : %d' % dummy.kcomm.size else: print >> self.txt, ' Kpoint parsize : %d' % dummy.kcomm.size print >> self.txt, ' Frequency parsize : %d' % dummy.wScomm.size print >> self.txt, 'Memory usage estimate' print >> self.txt, ' chi0_wGG(Q) : %f M / cpu' % (dummy.Nw_local * dummy.npw**2 * 16. / 1024**2) print >> self.txt del dummy
def initialize_calculation(self, w, ecut, nbands, kcommsize, extrapolate): dummy = DF(calc=self.calc, eta=0.0, w=w * 1j, q=[0., 0., 0.], ecut=ecut, hilbert_trans=False, kcommsize=kcommsize) dummy.txt = devnull dummy.spin = 0 dummy.initialize() if nbands is None: nbands = dummy.npw self.nbands = nbands print >> self.txt, 'Planewave cut off : %s eV' % ecut print >> self.txt, 'Number of Planewaves : %s' % dummy.npw print >> self.txt, 'Response function bands : %s' % nbands print >> self.txt, 'Frequency range : %s - %s eV' % ( w[0], w[-1]) print >> self.txt, 'Number of frequency points : %s' % len(w) if extrapolate: print >> self.txt, 'Extrapolation of frequencies : Squared Lorentzian' print >> self.txt print >> self.txt, 'Parallelization scheme' print >> self.txt, ' Total cpus : %d' % dummy.comm.size if dummy.nkpt == 1: print >> self.txt, ' Band parsize : %d' % dummy.kcomm.size else: print >> self.txt, ' Kpoint parsize : %d' % dummy.kcomm.size print >> self.txt, ' Frequency parsize : %d' % dummy.wScomm.size print >> self.txt, 'Memory usage estimate' print >> self.txt, ' chi0_wGG(Q) : %f M / cpu' % ( dummy.Nw_local * dummy.npw**2 * 16. / 1024**2) print >> self.txt del dummy
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 >> self.txt, 'Calculating RPA response function' print >> self.txt, 'Polarization: %s' % d 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 >> self.txt, 'Calculating real space integrals' 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 >> self.txt, 'Calculating dynamic polarizability' 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 >> self.txt, 'C06 = %s Ha*Bohr**6' % (C06.real / Ha) print >> self.txt, 'C6 = %s Ha*Bohr**6' % (C6.real / Ha) print >> 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.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 >> self.txt print >> self.txt, 'Planewave cutoff : %s eV' % ecut print >> self.txt, 'Number of Planewaves at Gamma : %s' % self.npw if self.nbands is None: print >> self.txt, 'Response function bands :'\ + ' Equal to number of Planewaves' else: print >> self.txt, 'Response function bands : %s' \ % self.nbands print >> self.txt, 'Frequencies' if self.gauss_legendre is not None: print >> self.txt, ' Gauss-Legendre integration '\ + 'with %s frequency points' % len(self.w) print >> self.txt, ' Frequency cutoff is '\ + '%s eV and scale (B) is %s' % (self.w[-1], self.frequency_scale) else: print >> self.txt, ' %s specified frequency points' \ % len(self.w) print >> self.txt, ' Frequency cutoff is %s eV' \ % self.w[-1] print >> self.txt print >> self.txt, 'Parallelization scheme' print >> self.txt, ' Total CPUs : %d' % dummy.comm.size if dummy.kd.nbzkpts == 1: print >> self.txt, ' Band parsize : %d' % dummy.kcomm.size else: print >> self.txt, ' Kpoint parsize : %d' % dummy.kcomm.size print >> self.txt, ' Frequency parsize : %d' % dummy.wScomm.size print >> self.txt, 'Memory usage estimate' print >> self.txt, ' chi0_wGG(Q) : %f M / cpu' \ % (dummy.Nw_local * self.npw**2 * 16. / 1024**2) print >> 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 >> self.txt, 'Calculating KS response function at:' else: print >> self.txt, '#', index, \ '- Calculating KS response function at:' if optical_limit: print >> self.txt, 'q = [0 0 0] -', 'Polarization: ', direction else: print >> self.txt, 'q = [%1.6f %1.6f %1.6f] -' \ % (q[0],q[1],q[2]), '%s planewaves' % npw 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 >> self.txt, 'E_c(q) = %s eV' % E_q.real print >> self.txt if integrated: return E_q.real else: return E_q_w.real
def get_E_q(self, kcommsize=1, index=None, q=[0., 0., 0.], integrated=True, ecut=10, nbands=None, w=np.linspace(0, 200., 32), extrapolate=True): if index is None: self.initialize_calculation(w, ecut, nbands, kcommsize, extrapolate) if abs(q[0]) < 0.001 and abs(q[1]) < 0.001 and abs(q[2]) < 0.001: q = [1.e-5, 0., 0.] optical_limit = True else: optical_limit = False df = DF(calc=self.calc, nbands=self.nbands, eta=0.0, q=q, w=w * 1j, ecut=ecut, kcommsize=kcommsize, optical_limit=optical_limit, hilbert_trans=False) df.txt = devnull if index is None: print >> self.txt, 'Calculating RPA dielectric matrix at:' else: print >> self.txt, '#', index, '- Calculating RPA dielectric matrix at:' if optical_limit: print >> self.txt, 'Q = [0 0 0]' else: print >> self.txt, 'Q = %s' % q e_wGG = df.get_RPA_dielectric_matrix() Nw_local = len(e_wGG) local_E_q_w = np.zeros(Nw_local, dtype=complex) E_q_w = np.empty(len(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]))) # + self.npw - np.trace(e_wGG[i])) df.wcomm.all_gather(local_E_q_w, E_q_w) del df del e_wGG dw = w[1] - w[0] E_q = dw * np.sum((E_q_w[:-1] + E_q_w[1:])/2.) / (2.*np.pi) if extrapolate: print '''Fit tail to: Eq(w) = A**2/((w-B)**2 + C)**2''' e1 = abs(E_q_w[-1])**0.5 e2 = abs(E_q_w[-2])**0.5 e3 = abs(E_q_w[-3])**0.5 w1 = w[-1] w2 = w[-2] w3 = w[-3] B = (((e3*w3**2-e1*w1**2)/(e1-e3) - (e2*w2**2-e1*w1**2)/(e1-e2)) / ((2*w3*e3-2*w1*e1)/(e1-e3) - (2*w2*e2-2*w1*e1)/(e1-e2))) C = ((w2-B)**2*e2 - (w1-B)**2*e1)/(e1-e2) A = e1*((w1-B)**2+C) if C > 0: E_q -= A**2*(np.pi/(4*C**1.5) - (w1-B)/((w1-B)**2+C)/(2*C) - np.arctan((w1-B)/C**0.5)/(2*C**1.5)) / (2*np.pi) else: E_q += A**2*((w1-B)/((w1-B)**2+C)/(2*C) + np.log((w1-B-abs(C)**0.5)/(w1-B+abs(C)**0.5)) /(4*C*abs(C)**0.5)) / (2*np.pi) print >> self.txt, 'E_c(Q) = %s eV' % E_q.real print >> self.txt if index is None: print >> self.txt, 'Calculation completed at: ', ctime() print >> self.txt print >> self.txt, '------------------------------------------------------' if integrated: return E_q else: return E_q_w
def get_E_q(self, kcommsize=1, index=None, q=[0., 0., 0.], integrated=True, ecut=10, nbands=None, w=np.linspace(0, 200., 32), extrapolate=True): if index is None: self.initialize_calculation(w, ecut, nbands, kcommsize, extrapolate) if abs(q[0]) < 0.001 and abs(q[1]) < 0.001 and abs(q[2]) < 0.001: q = [1.e-5, 0., 0.] optical_limit = True else: optical_limit = False df = DF(calc=self.calc, nbands=self.nbands, eta=0.0, q=q, w=w * 1j, ecut=ecut, kcommsize=kcommsize, optical_limit=optical_limit, hilbert_trans=False) df.txt = devnull if index is None: print >> self.txt, 'Calculating RPA dielectric matrix at:' else: print >> self.txt, '#', index, '- Calculating RPA dielectric matrix at:' if optical_limit: print >> self.txt, 'Q = [0 0 0]' else: print >> self.txt, 'Q = %s' % q e_wGG = df.get_RPA_dielectric_matrix() Nw_local = len(e_wGG) local_E_q_w = np.zeros(Nw_local, dtype=complex) E_q_w = np.empty(len(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]))) # + self.npw - np.trace(e_wGG[i])) df.wcomm.all_gather(local_E_q_w, E_q_w) del df del e_wGG dw = w[1] - w[0] E_q = dw * np.sum((E_q_w[:-1] + E_q_w[1:]) / 2.) / (2. * np.pi) if extrapolate: print '''Fit tail to: Eq(w) = A**2/((w-B)**2 + C)**2''' e1 = abs(E_q_w[-1])**0.5 e2 = abs(E_q_w[-2])**0.5 e3 = abs(E_q_w[-3])**0.5 w1 = w[-1] w2 = w[-2] w3 = w[-3] B = (((e3 * w3**2 - e1 * w1**2) / (e1 - e3) - (e2 * w2**2 - e1 * w1**2) / (e1 - e2)) / ((2 * w3 * e3 - 2 * w1 * e1) / (e1 - e3) - (2 * w2 * e2 - 2 * w1 * e1) / (e1 - e2))) C = ((w2 - B)**2 * e2 - (w1 - B)**2 * e1) / (e1 - e2) A = e1 * ((w1 - B)**2 + C) if C > 0: E_q -= A**2 * (np.pi / (4 * C**1.5) - (w1 - B) / ((w1 - B)**2 + C) / (2 * C) - np.arctan( (w1 - B) / C**0.5) / (2 * C**1.5)) / (2 * np.pi) else: E_q += A**2 * ((w1 - B) / ((w1 - B)**2 + C) / (2 * C) + np.log( (w1 - B - abs(C)**0.5) / (w1 - B + abs(C)**0.5)) / (4 * C * abs(C)**0.5)) / (2 * np.pi) print >> self.txt, 'E_c(Q) = %s eV' % E_q.real print >> self.txt if index is None: print >> self.txt, 'Calculation completed at: ', ctime() print >> self.txt print >> self.txt, '------------------------------------------------------' if integrated: return E_q else: return E_q_w