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