def initialize(self): self.ini = True BASECHI.initialize(self) self.txtname = self.gwtxtname self.output_init() self.printtxt('GPAW version %s' % (version)) self.printtxt('-----------------------------------------------') self.printtxt('GW calculation started at:') self.printtxt(ctime()) self.printtxt('-----------------------------------------------') self.starttime = time() calc = self.calc kd = self.kd # band init if self.gwnbands is None: if self.npw > calc.wfs.bd.nbands: self.nbands = calc.wfs.bd.nbands else: self.nbands = self.npw # eigenvalue init if self.user_skn is not None: self.printtxt('Use eigenvalues from user.') assert np.shape( self.user_skn )[0] == self.nspins, 'Eigenvalues not compatible with .gpw file!' assert np.shape( self.user_skn )[1] == self.kd.nibzkpts, 'Eigenvalues not compatible with .gpw file!' assert np.shape( self.user_skn)[2] >= self.nbands, 'Too few eigenvalues!' self.e_skn = self.user_skn else: self.printtxt('Use eigenvalues from the calculator.') # q point init self.bzq_kc = kd.get_bz_q_points() self.ibzq_qc = self.bzq_kc # q point symmetry is not used at the moment. self.nqpt = np.shape(self.bzq_kc)[0] # frequency points init self.static = False if self.ppa: # Plasmon Pole Approximation if self.E0 is None: self.E0 = Hartree self.E0 /= Hartree self.w_w = np.array([0., 1j * self.E0]) self.hilbert_trans = False self.wpar = 1 elif self.w_w is None: # static COHSEX self.w_w = np.array([0.]) self.static = True self.hilbert_trans = False self.wpar = 1 self.eta = 0.0001 / Hartree else: # create nonlinear frequency grid # grid is linear from 0 to wcut with spacing dw # spacing is linearily increasing between wcut and wmax # Hilbert transforms are still carried out on linear grid wcut = self.w_w[0] wmax = self.w_w[1] dw = self.w_w[2] w_w = np.linspace(0., wcut, wcut / dw + 1) i = 1 wi = wcut while wi < wmax: wi += i * dw w_w = np.append(w_w, wi) i += 1 while len(w_w) % self.wpar != 0: wi += i * dw w_w = np.append(w_w, wi) i += 1 dw_w = np.zeros(len(w_w)) dw_w[0] = dw dw_w[1:] = w_w[1:] - w_w[:-1] self.w_w = w_w / Hartree self.dw_w = dw_w / Hartree self.eta_w = dw_w * 4 / Hartree self.wcut = wcut self.wmax = self.w_w[-1] self.wmin = self.w_w[0] self.dw = self.w_w[1] - self.w_w[0] self.Nw = len(self.w_w) # self.wpar = int(self.Nw * self.npw**2 * 16. / 1024**2) // 1500 + 1 # estimate memory and parallelize over frequencies for s in range(self.nspins): emaxdiff = self.e_skn[s][:, self.nbands - 1].max() - self.e_skn[s][:, 0].min() assert (self.wmax > emaxdiff ), 'Maximum frequency must be larger than %f' % ( emaxdiff * Hartree) # GW kpoints init if self.kpoints is None: self.gwnkpt = self.kd.nibzkpts self.gwkpt_k = kd.ibz2bz_k else: self.gwnkpt = np.shape(self.kpoints)[0] self.gwkpt_k = self.kpoints # GW bands init if self.bands is None: self.gwnband = self.nbands self.bands = self.gwbands_n = np.arange(self.nbands) else: self.gwnband = np.shape(self.bands)[0] self.gwbands_n = self.bands self.alpha = 1j / (2 * pi * self.vol * self.kd.nbzkpts) # parallel init assert len(self.w_w) % self.wpar == 0 self.wcommsize = self.wpar self.qcommsize = size // self.wpar assert self.qcommsize * self.wcommsize == size, 'wpar must be integer divisor of number of requested cores' if self.nqpt != 1: # parallelize over q-points self.wcomm, self.qcomm, self.worldcomm = set_communicator( world, rank, size, self.wpar) self.ncomm = serial_comm self.dfcomm = self.wcomm self.kcommsize = 1 else: # parallelize over bands self.wcomm, self.ncomm, self.worldcomm = set_communicator( world, rank, size, self.wpar) self.qcomm = serial_comm if self.wpar > 1: self.dfcomm = self.wcomm self.kcommsize = 1 else: self.dfcomm = self.ncomm self.kcommsize = self.ncomm.size nq, self.nq_local, self.q_start, self.q_end = parallel_partition( self.nqpt, self.qcomm.rank, self.qcomm.size, reshape=False) nb, self.nbands_local, self.m_start, self.m_end = parallel_partition( self.nbands, self.ncomm.rank, self.ncomm.size, reshape=False)
def parallel_init(self): """Parallel initialization. By default, only use kcomm and wcomm. Parameters: kcomm: kpoint communicator wScomm: spectral function communicator wcomm: frequency communicator """ if extra_parameters.get("df_dry_run"): from gpaw.mpi import DryRunCommunicator size = extra_parameters["df_dry_run"] world = DryRunCommunicator(size) rank = world.rank self.comm = world else: world = self.comm rank = self.comm.rank size = self.comm.size wcommsize = int(self.NwS * self.npw ** 2 * 16.0 / 1024 ** 2) // 1500 # megabyte wcommsize += 1 if size < wcommsize: raise ValueError("Number of cpus are not enough ! ") if self.kcommsize is None: self.kcommsize = world.size if wcommsize > size // self.kcommsize: # if matrix too large, overwrite kcommsize and distribute matrix self.printtxt("kcommsize is over written ! ") while size % wcommsize != 0: wcommsize += 1 self.kcommsize = size // wcommsize assert self.kcommsize * wcommsize == size if self.kcommsize < 1: raise ValueError("Number of cpus are not enough ! ") self.kcomm, self.wScomm, self.wcomm = set_communicator(world, rank, size, self.kcommsize) if self.kd.nbzkpts >= world.size: self.nkpt_reshape = self.kd.nbzkpts self.nkpt_reshape, self.nkpt_local, self.kstart, self.kend = parallel_partition( self.nkpt_reshape, self.kcomm.rank, self.kcomm.size, reshape=True, positive=True ) self.mband_local = self.nvalbands self.mlist = np.arange(self.nbands) else: # if number of kpoints == 1, use band parallelization self.nkpt_local = self.kd.nbzkpts self.kstart = 0 self.kend = self.kd.nbzkpts self.nkpt_reshape = self.kd.nbzkpts self.nbands, self.mband_local, self.mlist = parallel_partition_list( self.nbands, self.kcomm.rank, self.kcomm.size ) if self.NwS % size != 0: self.NwS -= self.NwS % size self.NwS, self.NwS_local, self.wS1, self.wS2 = parallel_partition( self.NwS, self.wScomm.rank, self.wScomm.size, reshape=False ) if self.hilbert_trans: self.Nw, self.Nw_local, self.wstart, self.wend = parallel_partition( self.Nw, self.wcomm.rank, self.wcomm.size, reshape=True ) else: if self.Nw > 1: # assert self.Nw % (self.comm.size / self.kcomm.size) == 0 self.wcomm = self.wScomm self.Nw, self.Nw_local, self.wstart, self.wend = parallel_partition( self.Nw, self.wcomm.rank, self.wcomm.size, reshape=False ) else: # if frequency point is too few, then dont parallelize self.wcomm = serial_comm self.wstart = 0 self.wend = self.Nw self.Nw_local = self.Nw return
def initialize(self): self.ini = True BASECHI.initialize(self) self.txtname = self.gwtxtname self.output_init() self.printtxt('GPAW version %s' %(version)) self.printtxt('-----------------------------------------------') self.printtxt('GW calculation started at:') self.printtxt(ctime()) self.printtxt('-----------------------------------------------') self.starttime = time() calc = self.calc kd = self.kd # band init if self.gwnbands is None: if self.npw > calc.wfs.bd.nbands: self.nbands = calc.wfs.bd.nbands else: self.nbands = self.npw # eigenvalue init if self.user_skn is not None: self.printtxt('Use eigenvalues from user.') assert np.shape(self.user_skn)[0] == self.nspins, 'Eigenvalues not compatible with .gpw file!' assert np.shape(self.user_skn)[1] == self.kd.nibzkpts, 'Eigenvalues not compatible with .gpw file!' assert np.shape(self.user_skn)[2] >= self.nbands, 'Too few eigenvalues!' self.e_skn = self.user_skn else: self.printtxt('Use eigenvalues from the calculator.') # q point init self.bzq_kc = kd.get_bz_q_points() self.ibzq_qc = self.bzq_kc # q point symmetry is not used at the moment. self.nqpt = np.shape(self.bzq_kc)[0] # frequency points init self.static=False if self.ppa: # Plasmon Pole Approximation if self.E0 is None: self.E0 = Hartree self.E0 /= Hartree self.w_w = np.array([0., 1j*self.E0]) self.hilbert_trans=False self.wpar=1 elif self.w_w is None: # static COHSEX self.w_w = np.array([0.]) self.static=True self.hilbert_trans=False self.wpar=1 self.eta = 0.0001 / Hartree else: # create nonlinear frequency grid # grid is linear from 0 to wcut with spacing dw # spacing is linearily increasing between wcut and wmax # Hilbert transforms are still carried out on linear grid wcut = self.w_w[0] wmax = self.w_w[1] dw = self.w_w[2] w_w = np.linspace(0., wcut, wcut/dw+1) i=1 wi=wcut while wi < wmax: wi += i*dw w_w = np.append(w_w, wi) i+=1 while len(w_w) % self.wpar != 0: wi += i*dw w_w = np.append(w_w, wi) i+=1 dw_w = np.zeros(len(w_w)) dw_w[0] = dw dw_w[1:] = w_w[1:] - w_w[:-1] self.w_w = w_w / Hartree self.dw_w = dw_w / Hartree self.eta_w = dw_w * 4 / Hartree self.wcut = wcut self.wmax = self.w_w[-1] self.wmin = self.w_w[0] self.dw = self.w_w[1] - self.w_w[0] self.Nw = len(self.w_w) # self.wpar = int(self.Nw * self.npw**2 * 16. / 1024**2) // 1500 + 1 # estimate memory and parallelize over frequencies for s in range(self.nspins): emaxdiff = self.e_skn[s][:,self.nbands-1].max() - self.e_skn[s][:,0].min() assert (self.wmax > emaxdiff), 'Maximum frequency must be larger than %f' %(emaxdiff*Hartree) # GW kpoints init if self.kpoints is None: self.gwnkpt = self.kd.nibzkpts self.gwkpt_k = kd.ibz2bz_k else: self.gwnkpt = np.shape(self.kpoints)[0] self.gwkpt_k = self.kpoints # GW bands init if self.bands is None: self.gwnband = self.nbands self.bands = self.gwbands_n = np.arange(self.nbands) else: self.gwnband = np.shape(self.bands)[0] self.gwbands_n = self.bands self.alpha = 1j/(2*pi * self.vol * self.kd.nbzkpts) # parallel init assert len(self.w_w) % self.wpar == 0 self.wcommsize = self.wpar self.qcommsize = size // self.wpar assert self.qcommsize * self.wcommsize == size, 'wpar must be integer divisor of number of requested cores' if self.nqpt != 1: # parallelize over q-points self.wcomm, self.qcomm, self.worldcomm = set_communicator(world, rank, size, self.wpar) self.ncomm = serial_comm self.dfcomm = self.wcomm self.kcommsize = 1 else: # parallelize over bands self.wcomm, self.ncomm, self.worldcomm = set_communicator(world, rank, size, self.wpar) self.qcomm = serial_comm if self.wpar > 1: self.dfcomm = self.wcomm self.kcommsize = 1 else: self.dfcomm = self.ncomm self.kcommsize = self.ncomm.size nq, self.nq_local, self.q_start, self.q_end = parallel_partition( self.nqpt, self.qcomm.rank, self.qcomm.size, reshape=False) nb, self.nbands_local, self.m_start, self.m_end = parallel_partition( self.nbands, self.ncomm.rank, self.ncomm.size, reshape=False)
def parallel_init(self): """Parallel initialization. By default, only use kcomm and wcomm. Parameters: kcomm: kpoint communicator wScomm: spectral function communicator wcomm: frequency communicator """ if extra_parameters.get('df_dry_run'): from gpaw.mpi import DryRunCommunicator size = extra_parameters['df_dry_run'] world = DryRunCommunicator(size) rank = world.rank self.comm = world else: world = self.comm rank = self.comm.rank size = self.comm.size wcommsize = int(self.NwS * self.npw**2 * 16. / 1024**2) // 1500 # megabyte wcommsize += 1 if size < wcommsize: raise ValueError('Number of cpus are not enough ! ') if self.kcommsize is None: self.kcommsize = world.size if wcommsize > size // self.kcommsize: # if matrix too large, overwrite kcommsize and distribute matrix self.printtxt('kcommsize is over written ! ') while size % wcommsize != 0: wcommsize += 1 self.kcommsize = size // wcommsize assert self.kcommsize * wcommsize == size if self.kcommsize < 1: raise ValueError('Number of cpus are not enough ! ') self.kcomm, self.wScomm, self.wcomm = set_communicator(world, rank, size, self.kcommsize) if self.kd.nbzkpts >= world.size: self.nkpt_reshape = self.kd.nbzkpts self.nkpt_reshape, self.nkpt_local, self.kstart, self.kend = parallel_partition( self.nkpt_reshape, self.kcomm.rank, self.kcomm.size, reshape=True, positive=True) self.mband_local = self.nvalbands self.mlist = np.arange(self.nbands) else: # if number of kpoints == 1, use band parallelization self.nkpt_local = self.kd.nbzkpts self.kstart = 0 self.kend = self.kd.nbzkpts self.nkpt_reshape = self.kd.nbzkpts self.nbands, self.mband_local, self.mlist = parallel_partition_list( self.nbands, self.kcomm.rank, self.kcomm.size) if self.NwS % size != 0: self.NwS -= self.NwS % size self.NwS, self.NwS_local, self.wS1, self.wS2 = parallel_partition( self.NwS, self.wScomm.rank, self.wScomm.size, reshape=False) if self.hilbert_trans: self.Nw, self.Nw_local, self.wstart, self.wend = parallel_partition( self.Nw, self.wcomm.rank, self.wcomm.size, reshape=True) else: if self.Nw > 1: # assert self.Nw % (self.comm.size / self.kcomm.size) == 0 self.wcomm = self.wScomm self.Nw, self.Nw_local, self.wstart, self.wend = parallel_partition( self.Nw, self.wcomm.rank, self.wcomm.size, reshape=False) else: # if frequency point is too few, then dont parallelize self.wcomm = serial_comm self.wstart = 0 self.wend = self.Nw self.Nw_local = self.Nw return
def get_rpa_correlation_energy(self, kcommsize=None, dfcommsize=world.size, directions=None, skip_gamma=False, ecut=10, nbands=None, gauss_legendre=None, frequency_cut=None, frequency_scale=None, w=None, restart=None): self.initialize_calculation(w, ecut, nbands, kcommsize, gauss_legendre, frequency_cut, frequency_scale) if dfcommsize == world.size: self.dfcomm = world E_q = [] if restart is not None: assert type(restart) is str try: f = paropen(restart, 'r') lines = f.readlines() for line in lines: E_q.append(eval(line)) f.close() print >> self.txt, 'Correlation energy obtained ' \ +'from %s q-points obtained from restart file: ' \ % len(E_q), restart print >> self.txt except: IOError for index, q in zip(range(len(E_q), len(self.ibz_q_points)), self.ibz_q_points[len(E_q):]): if abs(np.dot(q, q))**0.5 < 1.e-5: E_q0 = 0. if skip_gamma: print >> self.txt, \ 'Not calculating q at the Gamma point' print >> self.txt else: if directions is None: directions = [[0, 1/3.], [1, 1/3.], [2, 1/3.]] for d in directions: E_q0 += self.E_q(q, index=index, direction=d[0]) * d[1] E_q.append(E_q0) else: E_q.append(self.E_q(q, index=index)) if restart is not None: f = paropen(restart, 'a') print >> f, E_q[-1] f.close() E = np.dot(np.array(self.q_weights), np.array(E_q).real) else: # parallelzation over q points print >> self.txt, 'parallelization over q point ! ' # creates q list qlist = [] qweight = [] id = 0 for iq, q in enumerate(self.ibz_q_points): if abs(np.dot(q, q))**0.5 < 1.e-5: if skip_gamma: continue else: if directions is None: directions = [[0, 1/3.], [1, 1/3.], [2, 1/3.]] for d in directions: qlist.append((id, q, d[0], d[1])) qweight.append(self.q_weights[iq]) id += 1 continue qlist.append((id, q, 0, 1)) qweight.append(self.q_weights[iq]) id += 1 nq = len(qlist) # distribute q list self.dfcomm, qcomm = set_communicator(world, world.rank, world.size, kcommsize=dfcommsize)[:2] nq, nq_local, qlist_local = parallel_partition_list(nq, qcomm.rank, qcomm.size) E_q = np.zeros(nq) for iq in qlist_local: try: ff = open('E_q_%s_%s.dat' %(self.tag,iq), 'r') E_q[iq] = ff.readline().split()[-2] print >> self.txt, 'Reading E_q[%s] '%(iq), E_q[iq] except: E_q[iq] = self.E_q(qlist[iq][1], index=iq, direction=qlist[iq][2]) * qlist[iq][3] if self.tag is not None and self.dfcomm.rank == 0: ff = open('E_q_%s_%s.dat' %(self.tag,iq), 'a') print >> ff, qlist[iq][1:4], E_q[iq], qweight[iq] ff.close() qcomm.sum(E_q) print >> self.txt, '(q, direction, weight), E_q, qweight' for iq in range(nq): print >> self.txt, qlist[iq][1:4], E_q[iq], qweight[iq] E = np.dot(np.array(qweight), np.array(E_q)) print >> self.txt, 'RPA correlation energy:' print >> self.txt, 'E_c = %s eV' % E print >> self.txt print >> self.txt, 'Calculation completed at: ', ctime() print >> self.txt print >> self.txt, \ '------------------------------------------------------' print >> self.txt return E
def get_rpa_correlation_energy(self, kcommsize=None, dfcommsize=world.size, directions=None, skip_gamma=False, ecut=10, nbands=None, gauss_legendre=None, frequency_cut=None, frequency_scale=None, w=None, restart=None): self.initialize_calculation(w, ecut, nbands, kcommsize, gauss_legendre, frequency_cut, frequency_scale) if dfcommsize == world.size: self.dfcomm = world E_q = [] if restart is not None: assert type(restart) is str try: f = paropen(restart, 'r') lines = f.readlines() for line in lines: E_q.append(eval(line)) f.close() print('Correlation energy obtained ' \ +'from %s q-points obtained from restart file: ' \ % len(E_q), restart, file=self.txt) print(file=self.txt) except: IOError for index, q in zip(range(len(E_q), len(self.ibz_q_points)), self.ibz_q_points[len(E_q):]): if abs(np.dot(q, q))**0.5 < 1.e-5: E_q0 = 0. if skip_gamma: print('Not calculating q at the Gamma point', file=self.txt) print(file=self.txt) else: if directions is None: directions = [[0, 1 / 3.], [1, 1 / 3.], [2, 1 / 3.]] for d in directions: E_q0 += self.E_q(q, index=index, direction=d[0]) * d[1] E_q.append(E_q0) else: E_q.append(self.E_q(q, index=index)) if restart is not None: f = paropen(restart, 'a') print(E_q[-1], file=f) f.close() E = np.dot(np.array(self.q_weights), np.array(E_q).real) else: # parallelzation over q points print('parallelization over q point ! ', file=self.txt) # creates q list qlist = [] qweight = [] id = 0 for iq, q in enumerate(self.ibz_q_points): if abs(np.dot(q, q))**0.5 < 1.e-5: if skip_gamma: continue else: if directions is None: directions = [[0, 1 / 3.], [1, 1 / 3.], [2, 1 / 3.]] for d in directions: qlist.append((id, q, d[0], d[1])) qweight.append(self.q_weights[iq]) id += 1 continue qlist.append((id, q, 0, 1)) qweight.append(self.q_weights[iq]) id += 1 nq = len(qlist) # distribute q list self.dfcomm, qcomm = set_communicator(world, world.rank, world.size, kcommsize=dfcommsize)[:2] nq, nq_local, qlist_local = parallel_partition_list( nq, qcomm.rank, qcomm.size) E_q = np.zeros(nq) for iq in qlist_local: try: ff = open('E_q_%s_%s.dat' % (self.tag, iq), 'r') E_q[iq] = ff.readline().split()[-2] print('Reading E_q[%s] ' % (iq), E_q[iq], file=self.txt) except: E_q[iq] = self.E_q(qlist[iq][1], index=iq, direction=qlist[iq][2]) * qlist[iq][3] if self.tag is not None and self.dfcomm.rank == 0: ff = open('E_q_%s_%s.dat' % (self.tag, iq), 'a') print(qlist[iq][1:4], E_q[iq], qweight[iq], file=ff) ff.close() qcomm.sum(E_q) print('(q, direction, weight), E_q, qweight', file=self.txt) for iq in range(nq): print(qlist[iq][1:4], E_q[iq], qweight[iq], file=self.txt) E = np.dot(np.array(qweight), np.array(E_q)) print('RPA correlation energy:', file=self.txt) print('E_c = %s eV' % E, file=self.txt) print(file=self.txt) print('Calculation completed at: ', ctime(), file=self.txt) print(file=self.txt) print('------------------------------------------------------', file=self.txt) print(file=self.txt) return E