AFEPack
MPI_HGeometry.h
浏览该文件的文档。
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