|
AFEPack
|
00001 00011 #define TEMPLATE template <int DIM, int DOW, class MATCHER> 00012 #define THIS HGeometryForest<DIM,DOW,MATCHER> 00013 00014 TEMPLATE void 00015 THIS::readMesh(const std::string& filename) { 00016 00020 const int& rank = this->_rank; 00021 const int& n_rank = this->_n_rank; 00022 00031 char filename_buf[256]; 00032 if (n_rank > 1) { 00033 sprintf(filename_buf, "%s%d.mesh", filename.c_str(), rank); 00034 } else { 00035 sprintf(filename_buf, "%s.mesh", filename.c_str()); 00036 } 00037 std::cerr << "Reading in mesh data file " 00038 << filename_buf 00039 << " as geometry tree root ..." 00040 << std::endl; 00041 std::ifstream is(filename_buf); 00042 00044 u_int n_point; 00045 is >> n_point; 00046 std::cerr << "\t# points: " << n_point << std::endl; 00047 std::vector<Point<this_t::dow> > point(n_point); 00048 for (u_int i = 0;i < n_point;i ++) is >> point[i]; 00049 is >> n_point; 00050 std::vector<HGeometry<0,this_t::dow> *> geo_0d(n_point, (HGeometry<0,this_t::dow> *)NULL); 00051 for (u_int i = 0;i < n_point;i ++) { 00052 u_int j, k; 00053 is >> j; geo_0d[j] = new HGeometry<0,this_t::dow>(); 00054 is >> k >> k; *dynamic_cast<Point<this_t::dow> *>(geo_0d[j]) = point[k]; 00055 is >> k >> k >> geo_0d[j]->bmark; 00056 } 00057 point.clear(); 00058 00059 #define GDIM 1 00060 u_int n_geo_1d; 00061 std::vector<HGeometry<GDIM,this_t::dow>*> geo_1d; 00062 if (DIM >= 1) { 00063 is >> n_geo_1d; 00064 std::cerr << "\t# 1D-geometry: " << n_geo_1d << std::endl; 00065 geo_1d.resize(n_geo_1d, NULL); 00066 for (u_int i = 0;i < n_geo_1d;i ++) { 00067 u_int j, k, l; 00068 is >> j >> k; geo_1d[j] = new HGeometry<GDIM,this_t::dow>(); 00069 for (k = 0;k < GDIM + 1;k ++) { 00070 is >> l; geo_1d[j]->vertex[k] = geo_0d[l]; 00071 } 00072 is >> k; 00073 for (k = 0;k < GDIM + 1;k ++) { 00074 is >> l; 00075 } 00076 is >> geo_1d[j]->bmark; 00077 } 00078 } 00079 #undef GDIM 00080 00081 #define GDIM 2 00082 u_int n_geo_2d; 00083 std::vector<HGeometry<GDIM,this_t::dow>*> geo_2d; 00084 if (DIM >= 2) { 00085 is >> n_geo_2d; 00086 std::cerr << "\t# 2D-geometry: " << n_geo_2d << std::endl; 00087 geo_2d.resize(n_geo_2d, NULL); 00088 for (u_int i = 0;i < n_geo_2d;i ++) { 00089 u_int j, k, l; 00090 is >> j >> k; geo_2d[j] = new HGeometry<GDIM,this_t::dow>(); 00091 for (k = 0;k < GDIM + 1;k ++) { 00092 is >> l; geo_2d[j]->vertex[k] = geo_0d[l]; 00093 } 00094 is >> k; 00095 for (k = 0;k < GDIM + 1;k ++) { 00096 is >> l; geo_2d[j]->boundary[k] = geo_1d[l]; 00097 } 00098 is >> geo_2d[j]->bmark; 00099 } 00100 } 00101 #undef GDIM 00102 00103 #define GDIM 3 00104 u_int n_geo_3d; 00105 std::vector<HGeometry<GDIM,this_t::dow>*> geo_3d; 00106 if (DIM >= 3) { 00107 is >> n_geo_3d; 00108 std::cerr << "\t# 3D-geometry: " << n_geo_3d << std::endl; 00109 geo_3d.resize(n_geo_3d, NULL); 00110 for (u_int i = 0;i < n_geo_3d;i ++) { 00111 u_int j, k, l; 00112 is >> j >> k; geo_3d[j] = new HGeometry<GDIM,this_t::dow>(); 00113 for (k = 0;k < GDIM + 1;k ++) { 00114 is >> l; geo_3d[j]->vertex[k] = geo_0d[l]; 00115 } 00116 is >> k; 00117 for (k = 0;k < GDIM + 1;k ++) { 00118 is >> l; geo_3d[j]->boundary[k] = geo_2d[l]; 00119 } 00120 is >> geo_3d[j]->bmark; 00121 } 00122 #undef GDIM 00123 } 00124 is.close(); 00125 00126 if (DIM == 1) { 00127 for (u_int i = 0;i < n_geo_1d;++ i) { 00128 this->rootElement().push_back((HGeometry<DIM,this_t::dow> *)geo_1d[i]); 00129 } 00130 } else if (DIM == 2) { 00131 for (u_int i = 0;i < n_geo_2d;++ i) { 00132 this->rootElement().push_back((HGeometry<DIM,this_t::dow> *)geo_2d[i]); 00133 } 00134 } else if (DIM == 3) { 00135 for (u_int i = 0;i < n_geo_3d;++ i) { 00136 this->rootElement().push_back((HGeometry<DIM,this_t::dow> *)geo_3d[i]); 00137 } 00138 } 00139 00145 if (n_rank == 1) return; 00146 00147 sprintf(filename_buf, "%s%d.share", filename.c_str(), rank); 00148 is.open(filename_buf); 00149 std::cerr << "Reading in shared data file " 00150 << filename_buf 00151 << " as shared information ..." 00152 << std::endl; 00153 00155 std::vector<bool> proc_flag(n_rank, false); 00156 std::vector<BinaryBuffer<> > proc_buf_in(n_rank), proc_buf_out(n_rank); 00157 std::vector<AFEPack::ostream<> > proc_os(n_rank); 00158 for (u_int i = 0;i < n_rank;++ i) { 00159 proc_os[i].set_buffer(proc_buf_out[i]); 00160 } 00161 00163 int n_item; 00164 std::vector<std::pair<std::vector<std::pair<int,int> >, int> > 00165 shared_geo_0d, shared_geo_1d, shared_geo_2d, shared_geo_3d; 00166 if (DIM >= 0) { 00167 std::vector<int> n_rank_shared_0d(n_rank, 0); 00168 int n_shared_geo_0d; 00169 is >> n_shared_geo_0d >> n_shared_geo_0d; 00170 std::cerr << "\t# 0d-shared geometry: " << n_shared_geo_0d << std::endl; 00171 shared_geo_0d.resize(n_shared_geo_0d); 00172 for (int i = 0;i < n_shared_geo_0d;++ i) { 00173 is >> n_item; 00174 shared_geo_0d[i].first.resize(n_item); 00175 for (int j = 0;j < n_item;++ j) { 00176 is >> shared_geo_0d[i].first[j].first 00177 >> shared_geo_0d[i].first[j].second; 00178 n_rank_shared_0d[shared_geo_0d[i].first[j].first] += 1; 00179 } 00180 is >> shared_geo_0d[i].second; 00181 } 00182 00183 for (int i = 0;i < n_rank;++ i) { 00184 proc_os[i] << n_rank_shared_0d[i]; 00185 if (n_rank_shared_0d[i] > 0) { 00186 proc_flag[i] = true; 00187 } 00188 } 00189 for (int i = 0;i < n_shared_geo_0d;++ i) { 00190 n_item = shared_geo_0d[i].first.size(); 00191 int local_idx; 00192 for (int j = 0;j < n_item;++ j) { 00193 int rnk = shared_geo_0d[i].first[j].first; 00194 int idx = shared_geo_0d[i].first[j].second; 00195 if (rnk == rank) { 00196 local_idx = idx; 00197 break; 00198 } 00199 } 00200 for (int j = 0;j < n_item;++ j) { 00201 int rnk = shared_geo_0d[i].first[j].first; 00202 int idx = shared_geo_0d[i].first[j].second; 00203 if (rnk != rank) { 00204 proc_os[rnk] << idx << geo_0d[local_idx]; 00205 } 00206 } 00207 } 00208 } 00209 00210 if (DIM >= 1) { 00211 std::vector<int> n_rank_shared_1d(n_rank, 0); 00212 int n_shared_geo_1d; 00213 is >> n_shared_geo_1d >> n_shared_geo_1d; 00214 std::cerr << "\t# 1d-shared geometry: " << n_shared_geo_1d << std::endl; 00215 shared_geo_1d.resize(n_shared_geo_1d); 00216 for (int i = 0;i < n_shared_geo_1d;++ i) { 00217 is >> n_item; 00218 shared_geo_1d[i].first.resize(n_item); 00219 for (int j = 0;j < n_item;++ j) { 00220 is >> shared_geo_1d[i].first[j].first 00221 >> shared_geo_1d[i].first[j].second; 00222 n_rank_shared_1d[shared_geo_1d[i].first[j].first] += 1; 00223 } 00224 is >> shared_geo_1d[i].second; 00225 } 00226 00227 for (int i = 0;i < n_rank;++ i) { 00228 proc_os[i] << n_rank_shared_1d[i]; 00229 if (n_rank_shared_1d[i] > 0) { 00230 proc_flag[i] = true; 00231 } 00232 } 00233 for (int i = 0;i < n_shared_geo_1d;++ i) { 00234 n_item = shared_geo_1d[i].first.size(); 00235 int local_idx; 00236 for (int j = 0;j < n_item;++ j) { 00237 int rnk = shared_geo_1d[i].first[j].first; 00238 int idx = shared_geo_1d[i].first[j].second; 00239 if (rnk == rank) { 00240 local_idx = idx; 00241 break; 00242 } 00243 } 00244 for (int j = 0;j < n_item;++ j) { 00245 int rnk = shared_geo_1d[i].first[j].first; 00246 int idx = shared_geo_1d[i].first[j].second; 00247 if (rnk != rank) { 00248 proc_os[rnk] << idx << geo_1d[local_idx]; 00249 } 00250 } 00251 } 00252 } 00253 00254 if (DIM >= 2) { 00255 std::vector<int> n_rank_shared_2d(n_rank, 0); 00256 int n_shared_geo_2d; 00257 is >> n_shared_geo_2d >> n_shared_geo_2d; 00258 std::cerr << "\t# 2d-shared geometry: " << n_shared_geo_2d << std::endl; 00259 shared_geo_2d.resize(n_shared_geo_2d); 00260 for (int i = 0;i < n_shared_geo_2d;++ i) { 00261 is >> n_item; 00262 shared_geo_2d[i].first.resize(n_item); 00263 for (int j = 0;j < n_item;++ j) { 00264 is >> shared_geo_2d[i].first[j].first 00265 >> shared_geo_2d[i].first[j].second; 00266 n_rank_shared_2d[shared_geo_2d[i].first[j].first] += 1; 00267 } 00268 is >> shared_geo_2d[i].second; 00269 } 00270 00271 for (int i = 0;i < n_rank;++ i) { 00272 proc_os[i] << n_rank_shared_2d[i]; 00273 if (n_rank_shared_2d[i] > 0) { 00274 proc_flag[i] = true; 00275 } 00276 } 00277 for (int i = 0;i < n_shared_geo_2d;++ i) { 00278 n_item = shared_geo_2d[i].first.size(); 00279 int local_idx; 00280 for (int j = 0;j < n_item;++ j) { 00281 int rnk = shared_geo_2d[i].first[j].first; 00282 int idx = shared_geo_2d[i].first[j].second; 00283 if (rnk == rank) { 00284 local_idx = idx; 00285 break; 00286 } 00287 } 00288 for (int j = 0;j < n_item;++ j) { 00289 int rnk = shared_geo_2d[i].first[j].first; 00290 int idx = shared_geo_2d[i].first[j].second; 00291 if (rnk != rank) { 00292 proc_os[rnk] << idx << geo_2d[local_idx]; 00293 } 00294 } 00295 } 00296 } 00297 00298 if (DIM >= 3) { 00299 std::vector<int> n_rank_shared_3d(n_rank, 0); 00300 int n_shared_geo_3d; 00301 is >> n_shared_geo_3d >> n_shared_geo_3d; 00302 std::cerr << "\t# 3d-shared geometry: " << n_shared_geo_3d << std::endl; 00303 shared_geo_3d.resize(n_shared_geo_3d); 00304 for (int i = 0;i < n_shared_geo_3d;++ i) { 00305 is >> n_item; 00306 shared_geo_3d[i].first.resize(n_item); 00307 for (int j = 0;j < n_item;++ j) { 00308 is >> shared_geo_3d[i].first[j].first 00309 >> shared_geo_3d[i].first[j].second; 00310 n_rank_shared_3d[shared_geo_3d[i].first[j].first] += 1; 00311 } 00312 is >> shared_geo_3d[i].second; 00313 } 00314 00315 for (int i = 0;i < n_rank;++ i) { 00316 proc_os[i] << n_rank_shared_3d[i]; 00317 if (n_rank_shared_3d[i] > 0) { 00318 proc_flag[i] = true; 00319 } 00320 } 00321 for (int i = 0;i < n_shared_geo_3d;++ i) { 00322 n_item = shared_geo_3d[i].first.size(); 00323 int local_idx; 00324 for (int j = 0;j < n_item;++ j) { 00325 int rnk = shared_geo_3d[i].first[j].first; 00326 int idx = shared_geo_3d[i].first[j].second; 00327 if (rnk == rank) { 00328 local_idx = idx; 00329 break; 00330 } 00331 } 00332 for (int j = 0;j < n_item;++ j) { 00333 int rnk = shared_geo_3d[i].first[j].first; 00334 int idx = shared_geo_3d[i].first[j].second; 00335 if (rnk != rank) { 00336 proc_os[rnk] << idx << geo_3d[local_idx]; 00337 } 00338 } 00339 } 00340 } 00341 00345 std::cerr << "\ttransfering data ..." << std::endl; 00346 int tag = get_random_tag(_comm), n_req = 0; 00347 proc_flag[rank] = false; 00348 MPI_Request request[2*n_rank]; 00349 MPI_Status status[2*n_rank]; 00350 for (int i = 0;i < n_rank;++ i) { 00351 if (proc_flag[i] == false) continue; 00352 MPI_Isend(proc_buf_out[i].start_address(), proc_buf_out[i].size(), MPI_CHAR, 00353 i, tag, _comm, &request[n_req ++]); 00354 } 00355 for (int i = 0;i < n_rank;++ i) { 00356 MPI_Status mpi_status; 00357 if (proc_flag[i] == false) continue; 00358 MPI_Probe(i, tag, _comm, &mpi_status); 00359 int msg_size; 00360 MPI_Get_count(&mpi_status, MPI_CHAR, &msg_size); 00361 proc_buf_in[i].resize(msg_size); 00362 MPI_Irecv(proc_buf_in[i].start_address(), msg_size, MPI_CHAR, 00363 i, tag, _comm, &request[n_req ++]); 00364 } 00365 MPI_Waitall(n_req, request, status); 00366 00371 std::cerr << "\tdecoding data received ..." << std::endl; 00372 for (int i = 0;i < n_rank;++ i) { 00373 if (proc_flag[i] == false) continue; 00374 AFEPack::istream<> proc_is(proc_buf_in[i]); 00375 int n_shared_item, local_idx; 00376 00377 if (DIM >= 0) { 00378 #define GDIM 0 00379 #define GEO HGeometry<GDIM,this_t::dow> 00380 #define OBJ Shared_object<GEO> 00381 proc_is >> n_shared_item; 00382 for (int j = 0;j < n_shared_item;++ j) { 00383 GEO * remote_obj, * local_obj; 00384 proc_is >> local_idx >> remote_obj; 00385 local_obj = geo_0d[local_idx]; 00386 OBJ * p_info = get_shared_info(*local_obj); 00387 if (p_info == NULL) p_info = new_shared_info(*local_obj); 00388 p_info->add_clone(i, remote_obj); 00389 } 00390 #undef OBJ 00391 #undef GEO 00392 #undef GDIM 00393 } 00394 00395 if (DIM >= 1) { 00396 #define GDIM 1 00397 #define GEO HGeometry<GDIM,this_t::dow> 00398 #define OBJ Shared_object<GEO> 00399 proc_is >> n_shared_item; 00400 for (int j = 0;j < n_shared_item;++ j) { 00401 GEO * remote_obj, * local_obj; 00402 proc_is >> local_idx >> remote_obj; 00403 local_obj = geo_1d[local_idx]; 00404 OBJ * p_info = get_shared_info(*local_obj); 00405 if (p_info == NULL) p_info = new_shared_info(*local_obj); 00406 p_info->add_clone(i, remote_obj); 00407 } 00408 #undef OBJ 00409 #undef GEO 00410 #undef GDIM 00411 } 00412 00413 if (DIM >= 2) { 00414 #define GDIM 2 00415 #define GEO HGeometry<GDIM,this_t::dow> 00416 #define OBJ Shared_object<GEO> 00417 proc_is >> n_shared_item; 00418 for (int j = 0;j < n_shared_item;++ j) { 00419 GEO * remote_obj, * local_obj; 00420 proc_is >> local_idx >> remote_obj; 00421 local_obj = geo_2d[local_idx]; 00422 OBJ * p_info = get_shared_info(*local_obj); 00423 if (p_info == NULL) p_info = new_shared_info(*local_obj); 00424 p_info->add_clone(i, remote_obj); 00425 } 00426 #undef OBJ 00427 #undef GEO 00428 #undef GDIM 00429 } 00430 00431 if (DIM >= 3) { 00432 #define GDIM 3 00433 #define GEO HGeometry<GDIM,this_t::dow> 00434 #define OBJ Shared_object<GEO> 00435 proc_is >> n_shared_item; 00436 for (int j = 0;j < n_shared_item;++ j) { 00437 GEO * remote_obj, * local_obj; 00438 proc_is >> local_idx >> remote_obj; 00439 local_obj = geo_3d[local_idx]; 00440 OBJ * p_info = get_shared_info(*local_obj); 00441 if (p_info == NULL) p_info = new_shared_info(*local_obj); 00442 p_info->add_clone(i, remote_obj); 00443 } 00444 #undef OBJ 00445 #undef GEO 00446 #undef GDIM 00447 } 00448 } 00449 } 00450 00451 TEMPLATE 00452 void THIS::renumerateRootElement(void (*f)(double, double, double, 00453 double&,double&,double&)) 00454 { 00455 std::cerr << "Renumerating element of the mesh using Hibert space curve filling ..." 00456 << std::flush; 00457 int n_ele = this->n_rootElement(); 00458 std::vector<HGeometry<DIM,this_t::dow>*> tmp_ele(n_ele); 00459 std::vector<double> x(n_ele, 0.0), y(n_ele, 0.0), z(n_ele, 0.0); 00460 typename std::list<HGeometry<DIM,this_t::dow>*>::iterator 00461 the_ele = this->rootElement().begin(); 00462 for (int i = 0;i < n_ele;++ i, ++ the_ele) { 00463 tmp_ele[i] = *the_ele; 00464 HGeometry<DIM,this_t::dow>& ele = **the_ele; 00465 const int& n_vtx = ele.n_vertex; 00466 for (int j = 0;j < n_vtx;++ j) { 00467 Point<this_t::dow>& pnt = *ele.vertex[j]; 00468 x[i] += pnt[0]; y[i] += pnt[1]; 00469 if (this_t::dow == 3) z[i] += pnt[2]; 00470 } 00471 x[i] /= n_vtx; y[i] /= n_vtx; 00472 if (this_t::dow == 3) z[i] /= n_vtx; 00473 } 00474 std::vector<int> new_index(n_ele); 00475 hsfc_renumerate(n_ele, &x[0], &y[0], &z[0], &new_index[0], f); 00476 00477 the_ele = this->rootElement().begin(); 00478 for (int i = 0;i < n_ele;++ i, ++ the_ele) { 00479 *the_ele = tmp_ele[new_index[i]]; 00480 } 00481 std::cerr << " OK!" << std::endl; 00482 } 00483 00484 00485 TEMPLATE 00486 void THIS::eraseRootElement(u_int level) { 00487 for (u_int i = 0;i < level;++ i) { 00488 this->eraseRootElementOneLevel(); 00489 } 00490 } 00491 00492 TEMPLATE 00493 void THIS::eraseRootElementOneLevel() { 00495 std::list<HGeometry<DIM,this_t::dow>*> new_root; 00496 typename std::list<HGeometry<DIM,this_t::dow>*>::iterator 00497 the_ele = this->rootElement().begin(), 00498 end_ele = this->rootElement().end(); 00499 for (;the_ele != end_ele;++ the_ele) { 00500 for (u_int i = 0;i < HGeometry<DIM,this_t::dow>::n_child;++ i) { 00501 HGeometry<DIM,this_t::dow> * p_geo = (*the_ele)->child[i]; 00502 if (p_geo == NULL) { 00503 std::cerr << "Macro element is not refined. The root elements are not erased!" 00504 << std::endl; 00505 abort(); 00506 } 00507 new_root.push_back(p_geo); 00508 this->nullParent(*p_geo); 00509 } 00510 } 00511 new_root.swap(this->rootElement()); 00512 00519 property_id_t<bool> pid; 00520 new_property_id(pid); 00521 end_ele = new_root.end(); 00522 the_ele = new_root.begin(); 00523 for (;the_ele != end_ele;++ the_ele) { 00524 this->tryDeleteGeometry(*the_ele, pid); 00525 } 00526 free_property_id(pid); 00527 the_ele = new_root.begin(); 00528 for (;the_ele != end_ele;++ the_ele) { 00529 this->deleteGeometry(*the_ele); 00530 } 00531 } 00532 00533 #undef THIS 00534 #undef TEMPLATE 00535 00537 00538 #define TEMPLATE template <class FOREST> 00539 #define THIS HGeometryMatcher<FOREST> 00540 00541 TEMPLATE 00542 bool THIS::match_geometry() { 00543 typedef THIS this_t; 00544 00545 std::cerr << "Rank " << _forest->rank() 00546 << ": Matching h-geometry among partitions ..." << std::endl; 00547 bool is_operated = false; 00548 do { 00549 _is_operated = false; 00550 00551 if (this_t::dim >= 3) 00552 sync_data(_forest->_comm, _forest->_shared_list_3d, *this, 00553 &this_t::template pack_match_geometry<3>, 00554 &this_t::template unpack_match_geometry<3>, 00555 &this_t::template is_pack_match_geometry<3>); 00556 if (this_t::dim >= 2) 00557 sync_data(_forest->_comm, _forest->_shared_list_2d, *this, 00558 &this_t::template pack_match_geometry<2>, 00559 &this_t::template unpack_match_geometry<2>, 00560 &this_t::template is_pack_match_geometry<2>); 00561 if (this_t::dim >= 1) 00562 sync_data(_forest->_comm, _forest->_shared_list_1d, *this, 00563 &this_t::template pack_match_geometry<1>, 00564 &this_t::template unpack_match_geometry<1>, 00565 &this_t::template is_pack_match_geometry<1>); 00566 00567 int src = _is_operated?1:0, dst = 0; 00568 MPI_Allreduce(&src, &dst, 1, MPI_INT, MPI_SUM, _forest->_comm); 00569 if (_is_operated = (dst > 0)) { 00570 is_operated = true; 00571 } 00572 } while (_is_operated); 00573 return is_operated; 00574 } 00575 00576 TEMPLATE 00577 template <int GDIM> bool 00578 THIS::is_pack_match_geometry(HGeometry<GDIM,dow> * geo) const { 00579 u_int n_unsent_vtx = 0; 00580 u_int n_unsent_bnd = 0; 00581 if (GDIM == 1) { 00585 00586 u_int n_vertex = geo->n_vertex; 00587 for (u_int i = 0;i < n_vertex;++ i) { 00588 if (! is_shared_info_sent(*geo->vertex[i])) { 00589 n_unsent_vtx += 1; 00590 } 00591 } 00592 } else { 00595 00596 u_int n_boundary = geo->n_boundary; 00597 for (u_int i = 0;i < n_boundary;++ i) { 00598 HGeometry<GDIM-1,dow> * bnd = geo->boundary[i]; 00599 if (bnd->parent == NULL && 00600 ! is_shared_info_sent(*bnd)) { 00601 n_unsent_bnd += 1; 00602 } 00603 } 00604 } 00605 00606 u_int n_child = 0; 00607 if (geo->isRefined() && 00608 (! _forest->is_shared_info_sent(*geo->child[0]))) { 00609 n_child = geo->n_child; 00610 } 00611 return ((n_unsent_vtx > 0) || 00612 (n_unsent_bnd > 0) || 00613 (n_child > 0)); 00614 } 00615 00616 TEMPLATE 00617 template <int GDIM> void 00618 THIS::pack_match_geometry(HGeometry<GDIM,dow> * geo, 00619 int remote_rank, 00620 AFEPack::ostream<>& os) { 00622 Shared_object<HGeometry<GDIM,dow> > * so = get_shared_info(*geo); 00623 Point<dow> grp; 00624 00629 bool is_last_entry = (so->rbegin()->first == remote_rank); 00630 00631 if (GDIM == 1) { 00635 00636 u_int n_vertex = geo->n_vertex; 00637 u_int n_unsent_vtx = 0; 00638 for (u_int i = 0;i < n_vertex;++ i) { 00639 if (! is_shared_info_sent(*geo->vertex[i])) { 00640 n_unsent_vtx += 1; 00641 } 00642 } 00643 if (n_unsent_vtx > 0) { 00644 this->_is_operated = true; 00645 } 00646 00647 os << n_unsent_vtx; 00648 for (u_int i = 0;i < n_vertex;++ i) { 00649 HGeometry<0,dow> * vtx = geo->vertex[i]; 00650 if (! is_shared_info_sent(*vtx)) { 00651 os << vtx; 00652 for (u_int n = 0;n < this_t::dow;++ n) { 00653 os << (*vtx)[n]; 00654 } 00655 if (is_last_entry) { 00656 set_shared_info_sent(*vtx); 00657 } 00658 } 00659 } 00660 } else { 00663 00664 u_int n_boundary = geo->n_boundary; 00665 u_int n_unsent_bnd = 0; 00666 for (u_int i = 0;i < n_boundary;++ i) { 00667 HGeometry<GDIM-1,dow> * bnd = geo->boundary[i]; 00668 if (bnd->parent == NULL && 00669 ! is_shared_info_sent(*bnd)) { 00670 n_unsent_bnd += 1; 00671 } 00672 } 00673 00674 if (n_unsent_bnd > 0) { 00675 this->_is_operated = true; 00676 } 00677 00678 os << n_unsent_bnd; 00679 for (u_int i = 0;i < n_boundary;++ i) { 00680 HGeometry<GDIM-1,dow> * bnd = geo->boundary[i]; 00681 if (bnd->parent == NULL && 00682 ! is_shared_info_sent(*bnd)) { 00683 geometry_reference_point(*bnd, grp); 00684 os << bnd << grp; 00685 if (is_last_entry) { 00686 set_shared_info_sent(*bnd); 00687 } 00688 } 00689 } 00690 } 00691 00695 if (geo->isRefined() && 00696 (! _forest->is_shared_info_sent(*geo->child[0]))) { 00703 u_int n_child = geo->n_child; 00704 os << n_child; 00705 for (u_int i = 0;i < n_child;++ i) { 00706 HGeometry<GDIM,dow> * chd = geo->child[i]; 00707 Shared_object<HGeometry<GDIM,dow> > * p_info = get_shared_info(*chd); 00708 if (p_info == NULL) p_info = new_shared_info(*chd); 00709 geometry_reference_point(*chd, grp); 00710 os << chd << grp; 00711 if (is_last_entry) { 00712 set_shared_info_sent(*chd); 00713 } 00714 } 00715 00716 this->_is_operated = true; 00717 } else { 00718 u_int n_child = 0; 00719 os << n_child; 00720 } 00721 } 00722 00723 TEMPLATE 00724 template <int GDIM> void 00725 THIS::unpack_match_geometry(HGeometry<GDIM,dow> * geo, 00726 int remote_rank, 00727 AFEPack::istream<>& is) { 00729 double h = distance(*geo->vertex[0], *geo->vertex[1]); 00730 00731 if (GDIM == 1) { 00735 00736 u_int n_unsent_vtx = 0; 00737 is >> n_unsent_vtx; 00738 std::vector<HGeometry<0,dow>*> remote_vtx(n_unsent_vtx); 00739 std::vector<Point<dow> > pnt(n_unsent_vtx); 00740 for (u_int i = 0;i < n_unsent_vtx;++ i) { 00741 is >> remote_vtx[i] >> pnt[i]; 00742 } 00743 00745 u_int n_vertex = geo->n_vertex; 00746 for (u_int i = 0;i < n_unsent_vtx;++ i) { 00747 for (u_int j = 0;j < n_vertex;++ j) { 00748 HGeometry<0,dow> * vtx = geo->vertex[j]; 00749 int type = matcher().value(pnt[i], *vtx, 1.0e-4*h); 00750 if (type >= 0) { 00751 Shared_object<HGeometry<0,dow> > * 00752 p_info = get_shared_info(*vtx); 00753 if (p_info == NULL) p_info = new_shared_info(*vtx); 00754 p_info->add_clone(remote_rank, type, remote_vtx[i]); 00755 break; 00756 } 00757 } 00758 } 00759 } else { 00763 00764 u_int n_unsent_bnd = 0; 00765 is >> n_unsent_bnd; 00766 std::vector<HGeometry<GDIM-1,dow>*> remote_bnd(n_unsent_bnd); 00767 std::vector<Point<dow> > remote_grp(n_unsent_bnd); 00768 for (u_int i = 0;i < n_unsent_bnd;++ i) { 00769 is >> remote_bnd[i] >> remote_grp[i]; 00770 } 00771 00773 Point<dow> grp; 00774 u_int n_boundary = geo->n_boundary; 00775 for (u_int i = 0;i < n_unsent_bnd;++ i) { 00776 for (u_int j = 0;j < n_boundary;++ j) { 00777 HGeometry<GDIM-1,dow> * bnd = geo->boundary[j]; 00778 if (bnd->parent != NULL) continue; 00779 geometry_reference_point(*bnd, grp); 00780 int type = matcher().value(remote_grp[i], grp, 1.0e-4*h); 00781 if (type >= 0) { 00782 Shared_object<HGeometry<GDIM-1,dow> > * 00783 p_info = get_shared_info(*bnd); 00784 if (p_info == NULL) p_info = new_shared_info(*bnd); 00785 p_info->add_clone(remote_rank, type, remote_bnd[i]); 00786 break; 00787 } 00788 } 00789 } 00790 } 00791 00792 u_int n_child; 00793 is >> n_child; 00794 if (n_child != 0) { 00795 assert (n_child == geo->n_child); 00796 00798 std::vector<HGeometry<GDIM,dow>*> remote_chd(n_child); 00799 std::vector<Point<dow> > remote_grp(n_child); 00800 for (u_int i = 0;i < n_child;++ i) { 00801 is >> remote_chd[i] >> remote_grp[i]; 00802 } 00803 00805 if (_forest->is_dummy(*geo)) return; 00806 00808 if (! geo->isRefined()) geo->refine(); 00809 00811 Point<dow> grp; 00812 u_int n_matched_child = 0; 00813 for (u_int i = 0;i < n_child;++ i) { 00814 HGeometry<GDIM,dow> * chd = geo->child[i]; 00815 geometry_reference_point(*chd, grp); 00816 for (u_int j = 0;j < n_child;++ j) { 00817 if (remote_chd[j] == NULL) continue; 00818 00820 int type = matcher().value(grp, remote_grp[j], 1.0e-4*h); 00821 if (type >= 0) { 00822 Shared_object<HGeometry<GDIM,dow> > * p_info = get_shared_info(*chd); 00823 if (p_info == NULL) p_info = new_shared_info(*chd); 00824 p_info->add_clone(remote_rank, type, remote_chd[j]); 00825 remote_chd[j] = NULL; 00826 n_matched_child += 1; 00827 break; 00828 } 00829 } 00830 } 00831 assert (n_matched_child == n_child); 00832 } 00833 } 00834 00835 TEMPLATE 00836 bool THIS::sync_is_used() { 00837 typedef THIS this_t; 00838 std::cerr << "Rank " << _forest->rank() 00839 << ": Sync is_used flag ..." << std::endl; 00840 _is_operated = false; 00841 if (this_t::dim >= 1) 00842 sync_data(_forest->_comm, _forest->_shared_list_1d, *this, 00843 &this_t::template pack_sync_is_used<1>, 00844 &this_t::template unpack_sync_is_used<1>); 00845 if (this_t::dim >= 2) 00846 sync_data(_forest->_comm, _forest->_shared_list_2d, *this, 00847 &this_t::template pack_sync_is_used<2>, 00848 &this_t::template unpack_sync_is_used<2>); 00849 if (this_t::dim >= 3) 00850 sync_data(_forest->_comm, _forest->_shared_list_3d, *this, 00851 &this_t::template pack_sync_is_used<3>, 00852 &this_t::template unpack_sync_is_used<3>); 00853 00854 int src = _is_operated?1:0, dst = 0; 00855 MPI_Allreduce(&src, &dst, 1, MPI_INT, MPI_SUM, _forest->_comm); 00856 return (dst > 0); 00857 } 00858 00859 TEMPLATE 00860 template <int GDIM> void 00861 THIS::pack_sync_is_used(HGeometry<GDIM,dow> * geo, 00862 int remote_rank, 00863 AFEPack::ostream<>& os) { 00864 bool is_used = _tools.isGeometryUsed(*geo); 00865 os << is_used; 00866 } 00867 00868 TEMPLATE 00869 template <int GDIM> void 00870 THIS::unpack_sync_is_used(HGeometry<GDIM,dow> * geo, 00871 int remote_rank, 00872 AFEPack::istream<>& is) { 00873 bool is_used; 00874 is >> is_used; 00875 00876 if (is_used) { 00877 if (! _tools.isGeometryUsed(*geo)) { 00878 _tools.setGeometryUsed(*geo); 00879 _is_operated = true; 00880 } 00881 } 00882 } 00883 00884 #undef THIS 00885 00887 00888 #define THIS BirdView<FOREST> 00889 00890 TEMPLATE void 00891 THIS::semiregularize() { 00892 forest_t& forest = this->getForest(); 00893 00894 if (! forest.lock()) { // 对几何遗传树进行加锁 00895 std::cerr << "The hierarchy geometry tree is locked, aborting ..."; 00896 abort(); 00897 } 00898 00899 if (forest.rank() == 0) 00900 std::cerr << "Semiregularizing the mesh ... " << std::flush; 00901 const char * timer = "-/|\\"; 00902 int n_element_refined = 0; 00903 this->prepareSemiregularize(); 00904 00905 int round = 0; 00906 bool is_operated; 00907 HGeometryMatcher<forest_t> matcher(forest); 00908 do { 00909 bool flag; 00910 do { 00911 flag = false; 00912 this->semiregularizeHelper(flag, n_element_refined); 00913 } while (flag); 00914 00915 if (forest.rank() == 0) 00916 std::cerr << "\b" << timer[round] << std::flush; 00917 round = (round + 1)%4; 00918 00919 is_operated = false; 00920 if (1) { // forest.n_rank() > 1) { 00921 is_operated |= matcher.match_geometry(); 00922 is_operated |= matcher.sync_is_used(); 00923 } 00924 } while (is_operated); 00925 00926 if (forest.rank() == 0) 00927 std::cerr << "\bOK!\n" 00928 << "\t" << n_element_refined 00929 << " elements refined in semiregularization." 00930 << std::endl; 00931 } 00932 00933 TEMPLATE 00934 void THIS::eraseRootElement(u_int level) { 00935 for (u_int i = 0;i < level;++ i) { 00936 this->eraseRootElementOneLevel(); 00937 } 00938 } 00939 00940 TEMPLATE 00941 void THIS::eraseRootElementOneLevel() { 00943 typedef typename base_t::container_t container_t; 00944 typedef typename base_t::element_t element_t; 00945 container_t new_root; 00946 typename container_t::iterator 00947 the_ele = this->rootElement().begin(), 00948 end_ele = this->rootElement().end(); 00949 for (;the_ele != end_ele;++ the_ele) { 00950 for (u_int i = 0;i < element_t::n_child;++ i) { 00951 element_t * p_geo = (*the_ele)->child[i]; 00952 if (p_geo == NULL) { 00953 std::cerr << "Macro element is not refined. The root elements CAN'T be erased!" 00954 << std::endl; 00955 abort(); 00956 } 00957 new_root.push_back(p_geo); 00958 p_geo->parent = NULL; 00959 } 00960 } 00961 new_root.swap(this->rootElement()); 00962 00963 the_ele = new_root.begin(); 00964 end_ele = new_root.end(); 00965 for (;the_ele != end_ele;++ the_ele) { 00966 delete *the_ele; 00967 } 00968 } 00969 00970 #undef THIS 00971 #undef TEMPLATE 00972
1.7.4