|
AFEPack
|
00001 00011 #ifndef __MPI_HGeometry_h__ 00012 #define __MPI_HGeometry_h__ 00013 00014 #include <set> 00015 #include <AFEPack/HGeometry.h> 00016 #include "MPI.h" 00017 00018 namespace MPI { 00019 00020 template <int DIM, int DOW, class MATCHER> class HGeometryForest; 00021 template <class FOREST> class BirdView; 00022 template <class FOREST> class BirdViewSet; 00023 template <class FOREST> class HGeometryMatcher; 00024 template <class FOREST> class HLoadBalance; 00025 00026 template <int DOW> 00027 struct PointDistance { 00028 int value(const Point<DOW>& p0, 00029 const Point<DOW>& p1, 00030 double tol) const { 00031 return (distance(p0, p1) < tol)?0:-1; 00032 } 00033 }; 00034 00042 template <int DIM, int DOW=DIM, class MATCHER=PointDistance<DOW> > 00043 class HGeometryForest : public HGeometryTree<DIM,DOW> { 00044 private: 00045 typedef HGeometryForest<DIM,DOW,MATCHER> this_t; 00046 public: 00047 typedef HGeometryTree<DIM,DOW> tree_t; 00048 typedef MATCHER matcher_t; 00049 00050 template <int D> 00051 const Shared_ptr_list<HGeometry<D,DOW> >& 00052 get_shared_list() const { 00053 const void * p_list; 00054 switch (D) { 00055 case 0: p_list = &_shared_list_0d; break; 00056 case 1: p_list = &_shared_list_1d; break; 00057 case 2: p_list = &_shared_list_2d; break; 00058 case 3: p_list = &_shared_list_3d; break; 00059 } 00060 return *((const Shared_ptr_list<HGeometry<D,DOW> > *)p_list); 00061 } 00062 00068 template <int GDIM> 00069 bool is_on_primary_rank(const HGeometry<GDIM,DOW>& geo) const { 00070 typedef HGeometry<GDIM,DOW> geo_t; 00071 typedef Shared_object<geo_t> obj_t; 00072 obj_t * p_obj = this->get_shared_info(geo); 00073 if (p_obj == NULL) { 00074 return true; 00075 } else { 00076 return p_obj->is_on_primary_rank(_rank); 00077 } 00078 } 00079 00083 template <int GDIM> 00084 int primary_rank(const HGeometry<GDIM,DOW>& geo) const { 00085 typedef HGeometry<GDIM,DOW> geo_t; 00086 typedef Shared_object<geo_t> obj_t; 00087 obj_t * p_obj = this->get_shared_info(geo); 00088 if (p_obj == NULL) { 00089 return _rank; 00090 } else { 00091 return p_obj->primary_rank(_rank); 00092 } 00093 } 00094 00098 template <int GDIM> 00099 bool is_primary_geometry(const HGeometry<GDIM,DOW>& geo) const { 00100 typedef HGeometry<GDIM,DOW> geo_t; 00101 typedef Shared_object<geo_t> obj_t; 00102 obj_t * p_obj = this->get_shared_info(geo); 00103 if (p_obj == NULL) { 00104 return true; 00105 } else { 00106 return p_obj->is_primary_object(_rank); 00107 } 00108 } 00109 00114 bool is_geometry_shared(const RegularMesh<DIM,DOW>& mesh, 00115 int dim, int idx) const { 00116 switch(dim) { 00117 case 0: return (get_shared_info(*mesh.template h_geometry<0>(idx)) != NULL); 00118 case 1: return (get_shared_info(*mesh.template h_geometry<1>(idx)) != NULL); 00119 case 2: return (get_shared_info(*mesh.template h_geometry<2>(idx)) != NULL); 00120 case 3: return (get_shared_info(*mesh.template h_geometry<3>(idx)) != NULL); 00121 } 00122 } 00123 00124 const matcher_t& matcher() const { return _matcher; } 00125 matcher_t& matcher() { return _matcher; } 00126 00127 private: 00128 MPI_Comm _comm; 00129 int _rank; 00130 int _n_rank; 00131 matcher_t _matcher; 00132 00139 property_id_t<> _pid_shared_info_sent; 00140 template <class GEO> bool 00141 is_shared_info_sent(GEO& geo) const { 00142 return (geo.get_property(_pid_shared_info_sent) != NULL); 00143 } 00144 template <class GEO> void 00145 set_shared_info_sent(GEO& geo) const { 00146 geo.new_property(_pid_shared_info_sent); 00147 } 00148 template <class GEO> void 00149 clear_shared_info_sent(GEO& geo) const { 00150 geo.free_property(_pid_shared_info_sent); 00151 } 00152 00159 property_id_t<> _pid_dummy; 00160 template <class GEO> bool 00161 is_dummy(GEO& geo) const { 00162 return (geo.get_property(_pid_dummy) != NULL); 00163 } 00164 template <class GEO> void 00165 dummy(GEO& geo) const { 00166 geo.new_property(_pid_dummy); 00167 } 00168 template <class GEO> void 00169 undummy(GEO& geo) const { 00170 geo.free_property(_pid_dummy); 00171 } 00172 00181 #define GDIM 0 00182 #define GEO HGeometry<GDIM,DOW> 00183 #define OBJ Shared_object<GEO> 00184 private: 00185 property_id_t<OBJ> _pid_so_0d; 00186 Shared_ptr_list<GEO> _shared_list_0d; 00187 00188 public: 00189 OBJ * get_shared_info(const GEO& geo) const { 00190 return geo.get_property(_pid_so_0d); 00191 } 00192 OBJ * new_shared_info(GEO& geo) { 00193 OBJ * p_obj = geo.new_property(_pid_so_0d); 00194 p_obj->local_pointer() = &geo; 00195 _shared_list_0d.push_back(p_obj); 00196 return p_obj; 00197 } 00198 void erase_shared_info(GEO& geo) { 00199 OBJ * p_obj = geo.get_property(_pid_so_0d); 00200 if (p_obj == NULL) return; 00201 _shared_list_0d.erase(std::find(_shared_list_0d.begin_ptr(), 00202 _shared_list_0d.end_ptr(), 00203 p_obj)); 00204 } 00205 #undef OBJ 00206 #undef GEO 00207 #undef GDIM 00208 00209 #define GDIM 1 00210 #define GEO HGeometry<GDIM,DOW> 00211 #define OBJ Shared_object<GEO> 00212 private: 00213 property_id_t<OBJ> _pid_so_1d; 00214 Shared_ptr_list<GEO> _shared_list_1d; 00215 00216 public: 00217 OBJ * get_shared_info(const GEO& geo) const { 00218 return geo.get_property(_pid_so_1d); 00219 } 00220 OBJ * new_shared_info(GEO& geo) { 00221 OBJ * p_obj = geo.new_property(_pid_so_1d); 00222 p_obj->local_pointer() = &geo; 00223 _shared_list_1d.push_back(p_obj); 00224 return p_obj; 00225 } 00226 void erase_shared_info(GEO& geo) { 00227 OBJ * p_obj = geo.get_property(_pid_so_1d); 00228 if (p_obj == NULL) return; 00229 _shared_list_1d.erase(std::find(_shared_list_1d.begin_ptr(), 00230 _shared_list_1d.end_ptr(), 00231 p_obj)); 00232 } 00233 #undef OBJ 00234 #undef GEO 00235 #undef GDIM 00236 00237 #define GDIM 2 00238 #define GEO HGeometry<GDIM,DOW> 00239 #define OBJ Shared_object<GEO> 00240 private: 00241 property_id_t<OBJ> _pid_so_2d; 00242 Shared_ptr_list<GEO> _shared_list_2d; 00243 00244 public: 00245 OBJ * get_shared_info(const GEO& geo) const { 00246 return geo.get_property(_pid_so_2d); 00247 } 00248 OBJ * new_shared_info(GEO& geo) { 00249 OBJ * p_obj = geo.new_property(_pid_so_2d); 00250 p_obj->local_pointer() = &geo; 00251 _shared_list_2d.push_back(p_obj); 00252 return p_obj; 00253 } 00254 void erase_shared_info(GEO& geo) { 00255 OBJ * p_obj = geo.get_property(_pid_so_2d); 00256 if (p_obj == NULL) return; 00257 _shared_list_2d.erase(std::find(_shared_list_2d.begin_ptr(), 00258 _shared_list_2d.end_ptr(), 00259 p_obj)); 00260 } 00261 #undef OBJ 00262 #undef GEO 00263 #undef GDIM 00264 00265 #define GDIM 3 00266 #define GEO HGeometry<GDIM,DOW> 00267 #define OBJ Shared_object<GEO> 00268 private: 00269 property_id_t<OBJ> _pid_so_3d; 00270 Shared_ptr_list<GEO> _shared_list_3d; 00271 00272 public: 00273 OBJ * get_shared_info(const GEO& geo) const { 00274 return geo.get_property(_pid_so_3d); 00275 } 00276 OBJ * new_shared_info(GEO& geo) { 00277 OBJ * p_obj = geo.new_property(_pid_so_3d); 00278 p_obj->local_pointer() = &geo; 00279 _shared_list_3d.push_back(p_obj); 00280 return p_obj; 00281 } 00282 void erase_shared_info(GEO& geo) { 00283 OBJ * p_obj = geo.get_property(_pid_so_3d); 00284 if (p_obj == NULL) return; 00285 _shared_list_3d.erase(std::find(_shared_list_3d.begin_ptr(), 00286 _shared_list_3d.end_ptr(), 00287 p_obj)); 00288 } 00289 #undef OBJ 00290 #undef GEO 00291 #undef GDIM 00292 00293 bool lock() { return HGeometryTree<DIM,DOW>::lock(); } 00294 void unlock() { HGeometryTree<DIM,DOW>::unlock(); } 00295 00296 public: 00297 HGeometryForest() { new_property(); } 00298 HGeometryForest(MPI_Comm comm) { 00299 set_communicator(comm); 00300 new_property(); 00301 } 00302 virtual ~HGeometryForest() { this->clear(); } 00303 00304 void clear() { 00305 _shared_list_0d.clear(); 00306 _shared_list_1d.clear(); 00307 _shared_list_2d.clear(); 00308 _shared_list_3d.clear(); 00309 00310 free_property(); 00311 HGeometryTree<DIM,DOW>::clear(); 00312 new_property(); 00313 } 00314 00315 void new_property() { 00316 new_property_id(_pid_shared_info_sent); 00317 new_property_id(_pid_dummy); 00318 if (DIM >= 0) new_property_id(_pid_so_0d); 00319 if (DIM >= 1) new_property_id(_pid_so_1d); 00320 if (DIM >= 2) new_property_id(_pid_so_2d); 00321 if (DIM >= 3) new_property_id(_pid_so_3d); 00322 } 00323 00324 void free_property() { 00325 free_property_id(_pid_shared_info_sent); 00326 free_property_id(_pid_dummy); 00327 if (DIM >= 0) free_property_id(_pid_so_0d); 00328 if (DIM >= 1) free_property_id(_pid_so_1d); 00329 if (DIM >= 2) free_property_id(_pid_so_2d); 00330 if (DIM >= 3) free_property_id(_pid_so_3d); 00331 } 00332 00333 void set_communicator(MPI_Comm comm) { 00334 _comm = comm; 00335 MPI_Comm_rank(_comm, &_rank); 00336 MPI_Comm_size(_comm, &_n_rank); 00337 } 00338 MPI_Comm communicator() const { return _comm; } 00339 int rank() const { return _rank; } 00340 int n_rank() const { return _n_rank; } 00341 void readMesh(const std::string&); 00342 00343 void eraseRootElement(u_int level = 1); 00344 void renumerateRootElement(void (*f)(double, double, double, 00345 double&,double&,double&) = NULL); 00346 00347 private: 00348 void eraseRootElementOneLevel(); 00349 template <class GEO> 00350 void nullParent(GEO& geo) { 00351 geo.parent = NULL; 00352 for (u_int i = 0;i < GEO::n_boundary;++ i) { 00353 this->nullParent(*geo.boundary[i]); 00354 } 00355 } 00356 template <class GEO> 00357 void tryDeleteGeometry(GEO * p_geo, 00358 const property_id_t<bool>& pid) { 00359 for (u_int i = 0;i < GEO::n_boundary;++ i) { 00360 if (p_geo->boundary[i]->get_property(pid) != NULL) { 00361 p_geo->boundary[i] = NULL; 00362 } else { 00363 this->tryDeleteGeometry(p_geo->boundary[i], pid); 00364 } 00365 } 00366 bool * p_prp = p_geo->get_property(pid); 00367 assert (p_prp == NULL); 00368 p_geo->new_property(pid); 00369 this->erase_shared_info(*p_geo); 00370 } 00371 template <class GEO> 00372 void deleteGeometry(GEO * p_geo) { 00373 for (u_int i = 0;i < GEO::n_boundary;++ i) { 00374 if (p_geo->boundary[i] != NULL) { 00375 this->deleteGeometry(p_geo->boundary[i]); 00376 } 00377 } 00378 delete p_geo; 00379 } 00380 00381 friend class BirdView<this_t>; 00382 friend class HGeometryMatcher<this_t>; 00383 friend class HLoadBalance<this_t>; 00384 00385 public: 00386 typedef BirdView<this_t> birdview_t; 00387 typedef BirdViewSet<this_t> birdview_set_t; 00388 typedef HLoadBalance<this_t> load_balancer_t; 00389 00390 }; // HGeometryForest 00391 00396 template <class FOREST> 00397 class BirdView : public IrregularMesh<FOREST::dim,FOREST::dow> { 00398 public: 00399 enum {dim = FOREST::dim, dow = FOREST::dow}; 00400 typedef IrregularMesh<dim, dow> base_t; 00401 typedef FOREST forest_t; 00402 public: 00403 BirdView() : base_t() {} 00404 explicit BirdView(forest_t& forest) : base_t(forest) {} 00405 virtual ~BirdView() {} 00406 00407 forest_t& getForest() const { 00408 return dynamic_cast<forest_t&>(this->geometryTree()); 00409 } 00410 virtual void semiregularize(); 00411 void eraseRootElement(u_int level = 1); 00412 private: 00413 void eraseRootElementOneLevel(); 00414 }; 00415 00420 template <class FOREST> 00421 class BirdViewSet : public std::set<BirdView<FOREST>*> { 00422 private: 00423 typedef BirdView<FOREST> birdview_t; 00424 typedef std::set<birdview_t*> base_t; 00425 public: 00426 typedef _Deref_iterator<typename base_t::iterator, birdview_t> iterator; 00427 typedef _Deref_iterator<typename base_t::const_iterator, const birdview_t> const_iterator; 00428 public: 00429 void add(birdview_t& bv) { base_t::insert(&bv); } 00430 void erase(birdview_t& bv) { base_t::erase(&bv); } 00431 00432 iterator begin() { return base_t::begin(); } 00433 iterator end() { return base_t::end(); } 00434 00435 const_iterator begin() const { return base_t::begin(); } 00436 const_iterator end() const { return base_t::end(); } 00437 00438 typename base_t::iterator begin_ptr() { return base_t::begin(); } 00439 typename base_t::iterator end_ptr() { return base_t::end(); } 00440 00441 typename base_t::const_iterator begin_ptr() const { return base_t::begin(); } 00442 typename base_t::const_iterator end_ptr() const { return base_t::end(); } 00443 }; 00444 00445 template <class FOREST> 00446 BirdViewSet<FOREST> 00447 make_set(BirdView<FOREST>& mesh0, 00448 BirdView<FOREST>& mesh1) { 00449 BirdViewSet<FOREST> bvs; 00450 bvs.add(mesh0); 00451 bvs.add(mesh1); 00452 return bvs; 00453 } 00454 template <class FOREST> 00455 BirdViewSet<FOREST> 00456 make_set(BirdView<FOREST>& mesh0, 00457 BirdView<FOREST>& mesh1, 00458 BirdView<FOREST>& mesh2) { 00459 BirdViewSet<FOREST> bvs; 00460 bvs.add(mesh0); 00461 bvs.add(mesh1); 00462 bvs.add(mesh2); 00463 return bvs; 00464 } 00465 template <class FOREST> 00466 BirdViewSet<FOREST> 00467 make_set(BirdView<FOREST>& mesh0, 00468 BirdView<FOREST>& mesh1, 00469 BirdView<FOREST>& mesh2, 00470 BirdView<FOREST>& mesh3) { 00471 BirdViewSet<FOREST> bvs; 00472 bvs.add(mesh0); 00473 bvs.add(mesh1); 00474 bvs.add(mesh2); 00475 bvs.add(mesh3); 00476 return bvs; 00477 } 00478 00502 template <class FOREST> 00503 class HGeometryMatcher { 00504 public: 00505 enum {dim = FOREST::dim, dow = FOREST::dow}; 00506 typedef FOREST forest_t; 00507 private: 00508 typedef HGeometryMatcher<forest_t> this_t; 00509 typedef typename forest_t::matcher_t matcher_t; 00510 00511 HTools _tools; 00512 forest_t * _forest; 00513 bool _is_operated; 00514 00515 const matcher_t& matcher() const { return _forest->matcher(); } 00516 00517 template <class GEO> bool 00518 is_shared_info_sent(GEO& geo) const { 00519 return _forest->is_shared_info_sent(geo); 00520 } 00521 template <class GEO> void 00522 set_shared_info_sent(GEO& geo) const { 00523 _forest->set_shared_info_sent(geo); 00524 } 00525 template <class GEO> Shared_object<GEO> * 00526 new_shared_info(GEO& geo) const { 00527 return _forest->new_shared_info(geo); 00528 } 00529 template <class GEO> Shared_object<GEO> * 00530 get_shared_info(GEO& geo) const { 00531 return _forest->get_shared_info(geo); 00532 } 00533 00534 public: 00535 HGeometryMatcher(forest_t& forest) : _forest(&forest) {} 00536 00543 bool match_geometry(); 00544 template <int GDIM> bool 00545 is_pack_match_geometry(HGeometry<GDIM,dow> * geo) const; 00546 template <int GDIM> void 00547 pack_match_geometry(HGeometry<GDIM,dow> * geo, 00548 int remote_rank, 00549 AFEPack::ostream<>& os); 00550 template <int GDIM> void 00551 unpack_match_geometry(HGeometry<GDIM,dow> * geo, 00552 int remote_rank, 00553 AFEPack::istream<>& is); 00554 00555 public: 00559 void set_matcher(const matcher_t& _matcher) { matcher = _matcher; } 00560 00567 bool sync_is_used(); 00568 template <int GDIM> void 00569 pack_sync_is_used(HGeometry<GDIM,dow> * geo, 00570 int remote_rank, 00571 AFEPack::ostream<>& os); 00572 template <int GDIM> void 00573 unpack_sync_is_used(HGeometry<GDIM,dow> * geo, 00574 int remote_rank, 00575 AFEPack::istream<>& is); 00576 00577 private: 00581 template <class GEO> 00582 void geometry_reference_point(GEO& geo, 00583 Point<dow>& pnt) const { 00584 int n_vtx = geo.n_vertex; 00585 for (int n = 0;n < dow;++ n) { 00586 pnt[n] = 0.0; 00587 for (int i = 0;i < n_vtx;++ i) { 00588 pnt[n] += (*geo.vertex[i])[n]; 00589 } 00590 pnt[n] /= n_vtx; 00591 } 00592 } 00593 00594 }; 00595 00596 00597 #include "MPI_HGeometry.templates.h" 00598 00599 } // namespace MPI 00600 00601 #endif // __MPI_HGeometry_h__ 00602
1.7.4