AFEPack
|
00001 00011 #ifndef __MPI_FaceData_h__ 00012 #define __MPI_FaceData_h__ 00013 00014 #include "MPI_HGeometry.h" 00015 #include <AFEPack/DGFEMSpace.h> 00016 00017 namespace MPI { 00018 namespace FaceData { 00019 00064 template <class FOREST, class PACKER> 00065 class Syncer { 00066 public: 00067 enum { dim = FOREST::dim, dow = FOREST::dow }; 00068 typedef FOREST forest_t; 00069 typedef PACKER packer_t; 00070 typedef typename packer_t::data_t data_t; 00071 typedef HGeometry<dim-1,dow> geometry_t; 00072 00073 private: 00074 typedef Syncer<forest_t,packer_t> this_t; 00075 00076 const forest_t * _forest; 00077 packer_t _packer; 00078 00079 property_id_t<data_t> _pid_out; 00080 property_id_t<data_t> _pid_in; 00081 00082 Transmit_map<geometry_t> _transmit_map; 00083 00084 public: 00085 Syncer() { new_property(); } 00086 Syncer(const forest_t& forest) : _forest(&forest) { 00087 new_property(); 00088 } 00089 Syncer(const forest_t& forest, const packer_t& packer) : 00090 _forest(&forest), _packer(packer) { 00091 new_property(); 00092 } 00093 Syncer(const this_t& syncer) : 00094 _forest(syncer._forest), _packer(syncer._packer) { 00095 new_property(); 00096 } 00097 00098 private: 00099 void new_property() { 00100 new_property_id(_pid_in); 00101 new_property_id(_pid_out); 00102 } 00103 void free_property() { 00104 free_property_id(_pid_in); 00105 free_property_id(_pid_out); 00106 } 00107 00108 public: 00109 void set_forest(const forest_t& forest) { _forest = &forest; } 00110 const forest_t& forest() const { return *_forest; } 00111 00112 void set_packer(const packer_t& packer) { 00113 _packer = packer; 00114 free_data_buffer(); 00115 } 00116 const typename packer_t::packer_t * packer() const { 00117 return _packer.packer(); 00118 } 00119 00124 template <class OBJ> data_t * 00125 get_send_buffer(const OBJ& obj) const { 00126 data_t * p_data = _packer.get_property(obj, _pid_out); 00127 if (p_data == NULL) p_data = _packer.new_property(obj, _pid_out); 00128 return p_data; 00129 } 00134 template <class OBJ> data_t * 00135 get_recv_buffer(const OBJ& obj) const { 00136 data_t * p_data = _packer.get_property(obj, _pid_in); 00137 return p_data; 00138 } 00139 00143 void free_data_buffer() { 00144 free_property(); 00145 new_property(); 00146 } 00147 00151 void update_transmit_map() { 00152 _transmit_map.build(_forest->template get_shared_list<dim-1>(), 00153 *this, &this_t::is_pack_data); 00154 } 00155 00162 void sync(bool is_update_transmit_map = true) { 00163 if (is_update_transmit_map) { 00164 update_transmit_map(); 00165 } 00166 00167 sync_data(_forest->communicator(), 00168 _transmit_map, 00169 *this, 00170 &this_t::pack_data, 00171 &this_t::unpack_data); 00172 } 00173 00178 bool is_pack_data(geometry_t * geo) const { 00179 assert (_forest->get_shared_info(*geo) != NULL); 00180 return (geo->get_property(_pid_out) != NULL); 00181 } 00182 00183 void pack_data(geometry_t * geo, 00184 int remote_rank, 00185 AFEPack::ostream<>& os) { 00186 assert (_forest->get_shared_info(*geo) != NULL); 00187 data_t * p_data = geo->get_property(_pid_out); 00188 assert (p_data != NULL); 00189 os << *p_data; 00190 } 00191 void unpack_data(geometry_t * geo, 00192 int remote_rank, 00193 AFEPack::istream<>& is) { 00194 assert (_forest->get_shared_info(*geo) != NULL); 00195 data_t * p_data = geo->get_property(_pid_in); 00196 if (p_data == NULL) p_data = geo->new_property(_pid_in); 00197 is >> *p_data; 00198 } 00199 }; 00200 00228 template <class FOREST, class PACKER> 00229 class SyncerPtr { 00230 public: 00231 enum { dim = FOREST::dim, dow = FOREST::dow }; 00232 typedef FOREST forest_t; 00233 typedef PACKER packer_t; 00234 typedef typename packer_t::data_t data_t; 00235 typedef HGeometry<dim-1,dow> geometry_t; 00236 00237 private: 00238 typedef SyncerPtr<forest_t,packer_t> this_t; 00239 00240 packer_t _packer; 00241 const forest_t * _forest; 00242 00243 property_id_t<data_t> _pid_out; 00244 property_id_t<data_t> _pid_in; 00245 00246 Transmit_map<geometry_t> _transmit_map; 00247 00248 public: 00249 SyncerPtr() { new_property(); } 00250 SyncerPtr(const forest_t& forest) : _forest(&forest) { 00251 new_property(); 00252 } 00253 SyncerPtr(const forest_t& forest, const packer_t& packer) : 00254 _forest(&forest), _packer(packer) { 00255 new_property(); 00256 } 00257 SyncerPtr(const this_t& syncer) : 00258 _forest(syncer._forest), _packer(syncer._packer) { 00259 new_property(); 00260 } 00261 00262 private: 00263 void new_property() { 00264 new_property_id(_pid_in); 00265 new_property_id(_pid_out); 00266 } 00267 void free_property() { 00268 free_property_id(_pid_in); 00269 free_property_id(_pid_out); 00270 } 00271 00272 public: 00273 void set_forest(const forest_t& forest) { _forest = &forest; } 00274 const forest_t& forest() const { return *_forest; } 00275 00276 void set_packer(const packer_t& packer) { 00277 free_data_buffer(); 00278 _packer = packer; 00279 } 00280 const typename packer_t::packer_t * packer() const { 00281 return _packer.packer(); 00282 } 00283 00288 template <class OBJ> void 00289 attach_send_buffer(const OBJ& obj, const data_t data) const { 00290 data_t * p_data = _packer.get_property(obj, _pid_out); 00291 if (p_data == NULL) p_data = _packer.new_property(obj, _pid_out); 00292 (*p_data) = data; 00293 } 00298 template <class OBJ> void 00299 attach_recv_buffer(const OBJ& obj, const data_t data) const { 00300 data_t * p_data = _packer.get_property(obj, _pid_in); 00301 if (p_data == NULL) p_data = _packer.new_property(obj, _pid_in); 00302 (*p_data) = data; 00303 } 00304 00308 void free_data_buffer() { 00309 free_property(); 00310 new_property(); 00311 } 00312 00313 void update_transmit_map() { 00314 _transmit_map.build(_forest->template get_shared_list<dim-1>(), 00315 *this, &this_t::is_pack_data); 00316 } 00317 00324 void sync(bool is_update_transmit_map = true) { 00325 if (is_update_transmit_map) { 00326 update_transmit_map(); 00327 } 00328 00329 sync_data(_forest->communicator(), 00330 _transmit_map, 00331 *this, 00332 &this_t::pack_data, 00333 &this_t::unpack_data); 00334 } 00335 00340 bool is_pack_data(geometry_t * geo) const { 00341 return (geo->get_property(_pid_out) != NULL); 00342 } 00343 00344 void pack_data(geometry_t * geo, 00345 int remote_rank, 00346 AFEPack::ostream<>& os) { 00347 const data_t * p_data = geo->get_property(_pid_out); 00348 assert (p_data != NULL); 00349 assert (geo->get_property(_pid_in) != NULL); 00350 os << **p_data; 00351 } 00352 void unpack_data(geometry_t * geo, 00353 int remote_rank, 00354 AFEPack::istream<>& is) { 00355 const data_t * p_data = geo->get_property(_pid_in); 00356 assert (p_data != NULL); 00357 assert (geo->get_property(_pid_out) != NULL); 00358 is >> **p_data; 00359 } 00360 }; 00361 00362 namespace details { 00363 template <class OBJ, class DATA> 00364 struct _dummy_packer { 00365 DATA * _dummy_func(const OBJ&, const property_id_t<DATA>&) { return NULL; } 00366 }; 00367 00371 template <class OBJ, class DATA, 00372 class PACKER = _dummy_packer<OBJ,DATA> > 00373 class Packer { 00374 public: 00375 typedef OBJ object_t; 00376 typedef DATA data_t; 00377 typedef PACKER packer_t; 00378 typedef property_id_t<data_t> pid_t; 00379 typedef data_t * (packer_t::*fun_ptr_t)(const object_t&, const pid_t&) const; 00380 00381 private: 00382 typedef Packer<object_t,data_t,packer_t> this_t; 00383 const packer_t * _packer; 00384 fun_ptr_t _new_property; 00385 fun_ptr_t _get_property; 00386 00387 public: 00388 Packer() {} 00389 Packer(const packer_t& pac, fun_ptr_t _np, fun_ptr_t _gp) : 00390 _packer(&pac), _new_property(_np), _get_property(_gp) {} 00391 Packer(const this_t& fdp) : _packer(fdp._packer), 00392 _new_property(fdp._new_property), _get_property(fdp._get_property) {} 00393 this_t& operator=(const this_t& fdp) { 00394 _packer = fdp._packer; 00395 _new_property = fdp._new_property; 00396 _get_property = fdp._get_property; 00397 return *this; 00398 } 00399 00400 public: 00401 const packer_t * packer() const { return _packer; } 00402 data_t * get_property(const object_t& obj, const pid_t& pid) const { 00403 return (_packer->*_get_property)(obj, pid); 00404 }; 00405 data_t * new_property(const object_t& obj, const pid_t& pid) const { 00406 return (_packer->*_new_property)(obj, pid); 00407 }; 00408 }; 00409 00413 template <class OBJ, class DATA> 00414 class Packer<OBJ,DATA,_dummy_packer<OBJ,DATA> > { 00415 public: 00416 typedef OBJ object_t; 00417 typedef DATA data_t; 00418 typedef _dummy_packer<object_t,DATA> packer_t; 00419 typedef property_id_t<data_t> pid_t; 00420 typedef data_t * (*fun_ptr_t)(const object_t&, const pid_t&); 00421 private: 00422 typedef Packer<object_t,data_t,packer_t> this_t; 00423 fun_ptr_t _new_property; 00424 fun_ptr_t _get_property; 00425 public: 00426 Packer() {} 00427 Packer(fun_ptr_t _np, fun_ptr_t _gp) : 00428 _new_property(_np), _get_property(_gp) {} 00429 Packer(const this_t& fdp) : 00430 _new_property(fdp._new_property), _get_property(fdp._get_property) {} 00431 this_t& operator=(const this_t& fdp) { 00432 _new_property = fdp._new_property; 00433 _get_property = fdp._get_property; 00434 return *this; 00435 } 00436 public: 00437 const packer_t * packer() const { return NULL; } 00438 data_t * get_property(const object_t& obj, const pid_t& pid) const { 00439 return (*_get_property)(obj, pid); 00440 }; 00441 data_t * new_property(const object_t& obj, const pid_t& pid) const { 00442 return (*_new_property)(obj, pid); 00443 }; 00444 }; 00445 00446 } // namespace details 00447 00452 template <class DATA, class MESH> 00453 struct Mesh { 00454 typedef MESH mesh_t; 00455 typedef typename mesh_t::ir_mesh_t ir_mesh_t; 00456 typedef details::Packer<GeometryBM, DATA, mesh_t> packer_t; 00457 typedef HGeometry<mesh_t::dim-1,mesh_t::dow> h_geometry_t; 00458 static packer_t get_packer(const mesh_t& mesh) { 00459 return packer_t(mesh, 00460 &mesh_t::template new_property<DATA,mesh_t::dim-1>, 00461 &mesh_t::template get_property<DATA,mesh_t::dim-1>); 00462 } 00463 static packer_t get_packer(const ir_mesh_t& mesh) { 00464 return packer_t(mesh.regularMesh(), 00465 &mesh_t::template new_property<DATA,mesh_t::dim-1>, 00466 &mesh_t::template get_property<DATA,mesh_t::dim-1>); 00467 } 00468 }; 00469 00474 template <class DATA, class SPACE> 00475 struct FESpace { 00476 typedef SPACE fe_space_t; 00477 typedef typename fe_space_t::dg_element_t dg_element_t; 00478 typedef details::Packer<dg_element_t, DATA, fe_space_t> packer_t; 00479 typedef HGeometry<fe_space_t::tdim1, fe_space_t::dow> h_geometry_t; 00480 static packer_t get_packer(const fe_space_t& sp) { 00481 return packer_t(sp, 00482 &fe_space_t::template new_property<DATA>, 00483 &fe_space_t::template get_property<DATA>); 00484 } 00485 }; 00486 00487 } // namespace FaceData 00488 } // namespace MPI 00489 00490 #endif // __MPI_FaceData_h__ 00491