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