def make_remap_matrix(self, debug=False): dst_obj = self.dst_obj src_obj = self.src_obj dsw_dict = dict() # {dst:[(s,w),(s,w),...],...} if debug: ipoly_dict = dict() # {dst:[(src,ipoly,iarea),...],..} for dst, (lat0,lon0) in enumerate(dst_obj.latlons): dst_poly = dst_obj.get_voronoi(dst) dst_area = area_polygon(dst_poly) inout = pt_in_polygon(dst_poly, latlon2xyz(lat0,lon0)) if inout != 'in': print('dst',dst) print('latlon_in_poly?', inout) idx1, idx2, idx3, idx4 = src_obj.get_surround_idxs(lat0, lon0) candidates = set([idx1, idx2, idx3, idx4]) if -1 in candidates: candidates.remove(-1) checked_srcs = set() dsw_dict[dst] = list() while len(candidates) > 0: #print('\t', checked_srcs) src = candidates.pop() src_poly = src_obj.get_voronoi(src) ipoly = intersect_two_polygons(dst_poly, src_poly) checked_srcs.add(src) if ipoly != None: iarea = area_polygon(ipoly) area_ratio = iarea/dst_area if area_ratio > 1e-10: dsw_dict[dst].append( (src, area_ratio) ) nbrs = set(src_obj.get_neighbors(src)) candidates.update(nbrs - checked_srcs) if debug: ipoly_dict[dst].append( (src,ipoly,iarea) ) if debug: self.save_netcdf_ipoly(ipoly_dict) return self.make_remap_matrix_from_dsw_dict(dsw_dict)
def make_remap_matrix_mpi(self, debug=False): from mpi4py import MPI comm = MPI.COMM_WORLD nproc = comm.Get_size() myrank = comm.Get_rank() if nproc == 1: return self.make_remap_matrix() dst_obj = self.dst_obj src_obj = self.src_obj chunk_size = dst_obj.nsize//nproc//10 dsw_dict = dict() # {dst:[(src,wgt),(src,wgt),...],...} if debug: ipoly_dict = dict() # {dst:[(src,ipoly,iarea),...],..} if myrank == 0: start = 0 while start < dst_obj.nsize: rank = comm.recv(source=MPI.ANY_SOURCE, tag=0) comm.send(start, dest=rank, tag=10) start += chunk_size for i in range(nproc-1): rank = comm.recv(source=MPI.ANY_SOURCE, tag=0) comm.send('quit', dest=rank, tag=10) slave_dsw_dict = comm.recv(source=rank, tag=20) dsw_dict.update(slave_dsw_dict) if debug: slave_ipoly_dict = comm.recv(source=rank, tag=30) ipoly_dict.update(slave_src_poly_dict) self.save_netcdf_ipoly(ipoly_dict) return self.make_remap_matrix_from_dsw_dict(dsw_dict) else: while True: comm.send(myrank, dest=0, tag=0) msg = comm.recv(source=0, tag=10) if msg == 'quit': print("Slave rank {} quit.".format(myrank)) comm.send(dsw_dict, dest=0, tag=20) if debug: comm.send(ipoly_dict, dest=0, tag=30) return None, None, None start = msg end = start + chunk_size end = dst_obj.nsize if end > dst_obj.nsize else end print("rank {}: {} ~ {} ({} %%)".format(myrank, start, end, end/dst_obj.nsize*100)) for dst in range(start,end): lat0, lon0 = dst_obj.latlons[dst] dst_poly = dst_obj.get_voronoi(dst) dst_area = area_polygon(dst_poly) idx1, idx2, idx3, idx4 = src_obj.get_surround_idxs(lat0, lon0) candidates = set([idx1, idx2, idx3, idx4]) if -1 in candidates: candidates.remove(-1) checked_srcs = set() dsw_dict[dst] = list() if debug: ipoly_dict[dst] = list() while len(candidates) > 0: src = candidates.pop() src_poly = src_obj.get_voronoi(src) ipoly = intersect_two_polygons(dst_poly, src_poly) checked_srcs.add(src) if ipoly != None: iarea = area_polygon(ipoly) area_ratio = iarea/dst_area if area_ratio > 1e-10: dsw_dict[dst].append( (src, area_ratio) ) nbrs = set(src_obj.get_neighbors(src)) candidates.update(nbrs - checked_srcs) if debug: ipoly_dict[dst].append( (src,ipoly,iarea) )