Blockstructured Adaptive Mesh Refinement in object-oriented C++
00001 #ifndef _included_GridFunctionComm1_h 00002 #define _included_GridFunctionComm1_h 00003 00009 /*****************************************************************************/ 00010 /**** Data Communications: Reads ****/ 00011 /*****************************************************************************/ 00012 template <class DAGH_GFType> 00013 void GridFunction(1)<DAGH_GFType>::GF_ReadData(const int time) { 00014 00015 List<GridDataBucketVoid*>& lgdbkt = gt->data(time); 00016 GridDataBucketVoid** gdbkt = 0; 00017 DAGHListLoop(lgdbkt, gdbkt, GridDataBucketVoid*) { 00018 00019 GridDataBucket<DAGH_GFType>* rcvbkt = (GridDataBucket<DAGH_GFType> *) *gdbkt; 00020 const int num = rcvbkt->num(); 00021 for (register int i=0;i<num;i++) { 00022 struct gdhdr *gdh == rcvbkt->head(i); 00023 if (gdh->time_value != dagh_timevalue(time_sten_rad,gdh->level)) continue; 00024 00025 #ifdef DEBUG_PRINT_GF_COMM 00026 ( comm_service::log() << "[GF_ReadData: Extracting" << *gdh 00027 << "]" << endl).flush(); 00028 #endif 00029 00030 #ifdef DEBUG_PRINT 00031 assert(gdh->time == time); 00032 #endif 00033 00034 const int t = gdh->time; 00035 const int l = gdh->level; 00036 const int idx = gdh->index; 00037 00038 #ifdef DEBUG_PRINT 00039 assert (gdb[t]); 00040 #endif 00041 BBox& bbox = gdh->bbox; 00042 if (!bbox.empty() && gdb[t][l][idx]->boundingbox().intersects(bbox)) { 00043 int currank = gdb[t][l][idx]->griddata().bbox().rank; 00044 bbox.rank = currank; 00045 bbox.lower().rank = currank; 00046 bbox.upper().rank = currank; 00047 bbox.stepsize().rank = currank; 00048 (gdb[t][l][idx]->griddata()).copy(*rcvbkt,i); 00049 } 00050 } 00051 delete rcvbkt; rcvbkt = 0; 00052 } DAGHEndLoop 00053 lgdbkt.empty(); 00054 } 00055 00056 template <class DAGH_GFType> 00057 void GridFunction(1)<DAGH_GFType>::GF_ReadData(const int time, 00058 const int level) { 00059 00060 List<GridDataBucketVoid*>& lgdbkt = gt->data(time); 00061 GridDataBucketVoid** gdbkt = 0; 00062 DAGHListLoop(lgdbkt, gdbkt, GridDataBucketVoid*) { 00063 00064 GridDataBucket<DAGH_GFType>* rcvbkt = (GridDataBucket<DAGH_GFType> *) *gdbkt; 00065 const int num = rcvbkt->num(); 00066 for (register int i=0;i<num;i++) { 00067 struct gdhdr *gdh == rcvbkt->head(i); 00068 if (level != gdh->level) continue; 00069 if (gdh->time_value != dagh_timevalue(time_sten_rad,gdh->level)) continue; 00070 00071 #ifdef DEBUG_PRINT_GF_COMM 00072 ( comm_service::log() << "[GF_ReadData: Extracting" 00073 << *gdh 00074 << "]" << endl).flush(); 00075 #endif 00076 00077 00078 #ifdef DEBUG_PRINT 00079 assert(gdh->time == time); 00080 #endif 00081 00082 const int t = gdh->time; 00083 const int l = gdh->level; 00084 const int idx = gdh->index; 00085 #ifdef DEBUG_PRINT 00086 assert (gdb[t]); 00087 #endif 00088 BBox& bbox = gdh->bbox; 00089 if (!bbox.empty() && gdb[t][l][idx]->boundingbox().intersects(bbox)) { 00090 int currank = gdb[t][l][idx]->griddata().bbox().rank; 00091 bbox.rank = currank; 00092 bbox.lower().rank = currank; 00093 bbox.upper().rank = currank; 00094 bbox.stepsize().rank = currank; 00095 (gdb[t][l][idx]->griddata()).copy(*rcvbkt,i); 00096 } 00097 } 00098 } DAGHEndLoop 00099 /* lgdbkt.empty() can't be called here, because Buckets can contain more than one level. */ 00100 /* Take care to empty list after ALL levels got their data. */ 00101 } 00102 00103 template <class DAGH_GFType> 00104 void GridFunction(1)<DAGH_GFType>::GF_ReadData(const int time, 00105 GridData(1)<DAGH_GFType>& into) { 00106 00107 List<GridDataBucketVoid*>& lgdbkt = gt->data(time); 00108 GridDataBucketVoid** gdbkt = 0; 00109 DAGHListLoop(lgdbkt, gdbkt, GridDataBucketVoid*) { 00110 GridDataBucket<DAGH_GFType>* rcvbkt = 00111 (GridDataBucket<DAGH_GFType> *) *gdbkt; 00112 const int num = rcvbkt->num(); 00113 for (register int i=0;i<num;i++) { 00114 struct gdhdr *gdh == rcvbkt->head(i); 00115 if (gdh->time_value != dagh_timevalue(time_sten_rad,gdh->level)) continue; 00116 00117 #ifdef DEBUG_PRINT_GF_COMM 00118 ( comm_service::log() << "[GF_ReadData: Extracting" 00119 << *rcvbkt->head(i) 00120 << "]" << endl).flush(); 00121 #endif 00122 00123 into.copy(*rcvbkt,i); 00124 } 00125 delete rcvbkt; rcvbkt = 0; 00126 } DAGHEndLoop 00127 lgdbkt.empty(); 00128 } 00129 00130 /*****************************************************************************/ 00131 /**** Ghost Communications: Write ****/ 00132 /*****************************************************************************/ 00133 template <class DAGH_GFType> 00134 void GridFunction(1)<DAGH_GFType>::GF_WriteGhosts(const int time, 00135 const int level, 00136 const int axis, 00137 const int dir) { 00138 const int pnum = comm_service::proc_num(); 00139 const int me = comm_service::proc_me(); 00140 if (pnum == 1) return; 00141 00142 register int const t = dagh_timeindex(time,level); 00143 register int const l = level; 00144 if (!comm(t,l) || t > 2*time_sten_rad || !gdb[t]) return; 00145 const int idx = (l * DAGHMaxAxis * DAGHMaxDirs) + (axis * DAGHMaxDirs) + dir; 00146 const int time_value = dagh_timevalue(time_sten_rad,level); 00147 00148 #ifdef DEBUG_PRINT_GF_COMM 00149 ( comm_service::log() << "[GF_WriteGhost t: "<< t << " ]" << endl).flush(); 00150 #endif 00151 register int p; 00152 for (p=0;p<pnum;p++) 00153 if (p!=me && ghost_recv_server[p] && ghost_recv_server[p][idx]) 00154 ghost_recv_server[p][idx]->postrcv(); 00155 00156 for (p=0;p<pnum;p++) { 00157 if (p == me) continue; 00158 if (ghost_send_info[p] && ghost_send_info[p][idx]) { 00159 GridDataBucket<DAGH_GFType> *gdbkt = 00160 new GridDataBucket<DAGH_GFType>(ghost_send_info[p][idx]->cnt, 00161 ghost_send_info[p][idx]->size, 00162 DAGHPacked); 00163 int s = 0; 00164 for (register int i=0; i<length[l]; i++) if (gdb[t][l][i]) { 00165 #ifdef DEBUG_PRINT_GF_COMM 00166 ( comm_service::log() << "[GF_WriteGhost i: "<< i << " ]" << endl).flush(); 00167 #endif 00168 s += gdb[t][l][i]->gdbWriteGhosts(p, time_value, axis, dir, *gdbkt, s); 00169 } 00170 #ifdef DEBUG_PRINT_GF_COMM 00171 for (register int j=0;j<gdbkt->num();j++) { 00172 struct gdhdr *gdh == gdbkt->head(j); 00173 ( comm_service::log() << "[GF_WriteGhost: Sending" << *gdh 00174 << "]" << endl).flush(); 00175 } 00176 #endif 00177 for (register int ii=0;ii<gdbkt->num();ii++) 00178 (gdbkt->head(ii))->level = l; 00179 gt->send((DAGHGhostTag|idx),gdbkt,p); 00180 } 00181 } 00182 } 00183 00184 /*****************************************************************************/ 00185 /**** Ghost Communications: Read ****/ 00186 /*****************************************************************************/ 00187 template <class DAGH_GFType> 00188 void GridFunction(1)<DAGH_GFType>::GF_PeriodicBBoxMove(BBox& from, int& idx, 00189 const int& length) { 00190 BBox wholebb = growupper(dagh.wholebbox(),1); 00191 Coords wholebblength = wholebb.upper()-wholebb.lower(); 00192 00193 for (int d=gfrank-1; d>=0; d--) 00194 if (dagh.periodicboundary(d)) { 00195 int idxtest = ipow(3, dagh.periodicindex(d)); 00196 00197 if (idx >= 2*idxtest*length) { 00198 from.lower(d) += wholebblength(d); from.upper(d) += wholebblength(d); 00199 idx -= 2*idxtest*length; 00200 } 00201 else if (idx >= idxtest*length) { 00202 from.lower(d) -= wholebblength(d); from.upper(d) -= wholebblength(d); 00203 idx -= idxtest*length; 00204 } 00205 } 00206 } 00207 00208 00209 template <class DAGH_GFType> 00210 void GridFunction(1)<DAGH_GFType>::GF_ReadGhosts(const int time, 00211 const int level, 00212 const int axis, 00213 const int dir) { 00214 register int const t = dagh_timeindex(time,level); 00215 register int const l = level; 00216 if (!comm(t,l) || t > 2*time_sten_rad || !gdb[t]) return; 00217 00218 const int pnum = comm_service::proc_num(); 00219 const int me = comm_service::proc_me(); 00220 const int idx = (l * DAGHMaxAxis * DAGHMaxDirs) + (axis * DAGHMaxDirs) + dir; 00221 const int time_value = dagh_timevalue(time_sten_rad,level); 00222 00223 GDB_Interaction* gdbi; 00224 int ngdbi; 00225 00226 /* Local copies */ 00227 const int c = DAGHMaxDirs*axis + dir; 00228 if (ghost_recv_info[me] && ghost_recv_info[me][idx] 00229 && ghost_recv_info[me][idx]->cnt > 0) { 00230 for (register int i=0; i<length[l]; i++) if (gdb[t][l][i]) 00231 if (gdb[t][l][i]->gdb_read_info[me] && gdb[t][l][i]->gdb_read_index[me]) { 00232 if ((ngdbi=gdb[t][l][i]->gdb_read_index[me][c])>0 && 00233 (gdbi=gdb[t][l][i]->gdb_read_info[me][c])) 00234 for (register int m=0; m<ngdbi; m++) { 00235 if (gdbi[m].idx<length[l]) if (gdbi[m].idx!=i && gdb[t][l][gdbi[m].idx]) { 00236 #ifdef DEBUG_PRINT_GF_COMM 00237 ( comm_service::log() << "[GF_ReadGhosts::LocalCopy " 00238 << "[" << i << "<-" << gdbi[m].idx << "]" 00239 << gdbi[m].bbox << endl).flush(); 00240 #endif 00241 gdb[t][l][i]->griddata().copy(gdb[t][l][gdbi[m].idx]->griddata(), 00242 gdbi[m].bbox); 00243 } 00244 00245 /* Periodic boundaries */ 00246 if (gdbi[m].idx>=length[l]) { 00247 BBox from = gdbi[m].bbox; 00248 int idxl = gdbi[m].idx; 00249 GF_PeriodicBBoxMove(from, idxl, length[l]); 00250 00251 if (gdb[t][l][idxl]) { 00252 #ifdef DEBUG_PRINT_GF_COMM 00253 ( comm_service::log() << "[GF_ReadGhosts::Periodic LocalCopy " 00254 << "[" << i << "<-" << idxl << "]" 00255 << gdbi[m].bbox << from << endl).flush(); 00256 #endif 00257 gdb[t][l][i]->griddata().copy(gdb[t][l][idxl]->griddata(), 00258 gdbi[m].bbox,from); 00259 } 00260 } 00261 } 00262 } 00263 } 00264 00265 if (pnum > 1) { /* Receives */ 00266 register int p; 00267 for (p=0;p<pnum;p++) { 00268 if (p == me) continue; 00269 if (ghost_recv_server[p] && ghost_recv_server[p][idx] 00270 && !ghost_recv_server[p][idx]->received()) 00271 comm_service::serve(*ghost_recv_server[p][idx]->req()); 00272 } 00273 00274 register int rcvcnt = 0; 00275 List<GridDataBucketVoid*>& lgdbkt = gt->ghosts(t,l); 00276 GridDataBucketVoid** gdbkt = 0; 00277 DAGHListLoop(lgdbkt, gdbkt, GridDataBucketVoid*) { 00278 GridDataBucket<DAGH_GFType>* rcvbkt = 00279 (GridDataBucket<DAGH_GFType> *) *gdbkt; 00280 const int num = rcvbkt->num(); 00281 for (register int i=0;i<num;i++) { 00282 struct gdhdr *gdh == rcvbkt->head(i); 00283 if (gdh->time_value != time_value) continue; 00284 00285 #ifdef DEBUG_PRINT 00286 assert(gdh->time == t); 00287 #endif 00288 00289 const int t = gdh->time; 00290 const int l = gdh->level; 00291 #ifdef DEBUG_PRINT 00292 assert (l == level); 00293 assert (gdb[t]); 00294 #endif 00295 if (l != level) continue; 00296 00297 BBox& from = gdh->bbox; 00298 int idxl = gdh->index; 00299 00300 if (!from.empty()) { 00301 00302 /* Periodic Boundaries */ 00303 if (idxl>=length[l]) { 00304 BBox to = from; 00305 GF_PeriodicBBoxMove(to, idxl, length[l]); 00306 00307 if (gdb[t][l][idxl]) 00308 if (!to.empty() && gdb[t][l][idxl]->boundingbox().intersects(to)) { 00309 int currank = gdb[t][l][idxl]->griddata().bbox().rank; 00310 from.rank = currank; 00311 from.lower().rank = currank; 00312 from.upper().rank = currank; 00313 from.stepsize().rank = currank; 00314 to.rank = currank; 00315 to.lower().rank = currank; 00316 to.upper().rank = currank; 00317 to.stepsize().rank = currank; 00318 #ifdef DEBUG_PRINT_GF_COMM 00319 ( comm_service::log() << "[GF_ReadGhost: Periodic Extracted" 00320 << *gdh << to << "]" << endl).flush(); 00321 #endif 00322 (gdb[t][l][idxl]->griddata()).copy(*rcvbkt,i,to,from); 00323 } 00324 } 00325 else 00326 if (gdb[t][l][idxl]) if (gdb[t][l][idxl]->boundingbox().intersects(from)) { 00327 int currank = gdb[t][l][idxl]->griddata().bbox().rank; 00328 from.rank = currank; 00329 from.lower().rank = currank; 00330 from.upper().rank = currank; 00331 from.stepsize().rank = currank; 00332 #ifdef DEBUG_PRINT_GF_COMM 00333 ( comm_service::log() << "[GF_ReadGhost: Extracted" << *gdh 00334 << "]" << endl).flush(); 00335 #endif 00336 (gdb[t][l][idxl]->griddata()).copy(*rcvbkt,i); 00337 } 00338 } 00339 rcvcnt++; 00340 } 00341 delete rcvbkt; rcvbkt = 0; 00342 } DAGHEndLoop 00343 #ifdef DEBUG_PRINT 00344 assert (rcvcnt == ghost_recv_cnt[idx]); 00345 #endif 00346 lgdbkt.empty(); 00347 } 00348 } 00349 00350 #endif
Quickstart Users Guide Programmers Reference Installation Examples Download
AMROC Main Home Contactlast update: 06/01/04