|
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 return (geo->get_property(_pid_out) != NULL); 00180 } 00181 00182 void pack_data(geometry_t * geo, 00183 int remote_rank, 00184 AFEPack::ostream<>& os) { 00185 data_t * p_data = geo->get_property(_pid_out); 00186 assert (p_data != NULL); 00187 os << *p_data; 00188 } 00189 void unpack_data(geometry_t * geo, 00190 int remote_rank, 00191 AFEPack::istream<>& is) { 00192 assert (_forest->get_shared_info(*geo) != NULL); 00193 assert (geo->get_property(_pid_in) == NULL); 00194 data_t * p_data = geo->new_property(_pid_in); 00195 is >> *p_data; 00196 } 00197 }; 00198 00226 template <class FOREST, class PACKER> 00227 class SyncerPtr { 00228 public: 00229 enum { dim = FOREST::dim, dow = FOREST::dow }; 00230 typedef FOREST forest_t; 00231 typedef PACKER packer_t; 00232 typedef typename packer_t::data_t data_t; 00233 typedef HGeometry<dim-1,dow> geometry_t; 00234 00235 private: 00236 typedef SyncerPtr<forest_t,packer_t> this_t; 00237 00238 packer_t _packer; 00239 const forest_t * _forest; 00240 00241 property_id_t<data_t> _pid_out; 00242 property_id_t<data_t> _pid_in; 00243 00244 Transmit_map<geometry_t> _transmit_map; 00245 00246 public: 00247 SyncerPtr() { new_property(); } 00248 SyncerPtr(const forest_t& forest) : _forest(&forest) { 00249 new_property(); 00250 } 00251 SyncerPtr(const forest_t& forest, const packer_t& packer) : 00252 _forest(&forest), _packer(packer) { 00253 new_property(); 00254 } 00255 SyncerPtr(const this_t& syncer) : 00256 _forest(syncer._forest), _packer(syncer._packer) { 00257 new_property(); 00258 } 00259 00260 private: 00261 void new_property() { 00262 new_property_id(_pid_in); 00263 new_property_id(_pid_out); 00264 } 00265 void free_property() { 00266 free_property_id(_pid_in); 00267 free_property_id(_pid_out); 00268 } 00269 00270 public: 00271 void set_forest(const forest_t& forest) { _forest = &forest; } 00272 const forest_t& forest() const { return *_forest; } 00273 00274 void set_packer(const packer_t& packer) { 00275 free_data_buffer(); 00276 _packer = packer; 00277 } 00278 const typename packer_t::packer_t * packer() const { 00279 return _packer.packer(); 00280 } 00281 00286 template <class OBJ> void 00287 attach_send_buffer(const OBJ& obj, const data_t data) const { 00288 data_t * p_data = _packer.get_property(obj, _pid_out); 00289 if (p_data == NULL) p_data = _packer.new_property(obj, _pid_out); 00290 (*p_data) = data; 00291 } 00296 template <class OBJ> void 00297 attach_recv_buffer(const OBJ& obj, const data_t data) const { 00298 data_t * p_data = _packer.get_property(obj, _pid_in); 00299 if (p_data == NULL) p_data = _packer.new_property(obj, _pid_in); 00300 (*p_data) = data; 00301 } 00302 00306 void free_data_buffer() { 00307 free_property(); 00308 new_property(); 00309 } 00310 00311 void update_transmit_map() { 00312 _transmit_map.build(_forest->template get_shared_list<dim-1>(), 00313 *this, &this_t::is_pack_data); 00314 } 00315 00322 void sync(bool is_update_transmit_map = true) { 00323 if (is_update_transmit_map) { 00324 update_transmit_map(); 00325 } 00326 00327 sync_data(_forest->communicator(), 00328 _transmit_map, 00329 *this, 00330 &this_t::pack_data, 00331 &this_t::unpack_data); 00332 } 00333 00338 bool is_pack_data(geometry_t * geo) const { 00339 return (geo->get_property(_pid_out) != NULL); 00340 } 00341 00342 void pack_data(geometry_t * geo, 00343 int remote_rank, 00344 AFEPack::ostream<>& os) { 00345 const data_t * p_data = geo->get_property(_pid_out); 00346 assert (p_data != NULL); 00347 assert (geo->get_property(_pid_in) != NULL); 00348 os << **p_data; 00349 } 00350 void unpack_data(geometry_t * geo, 00351 int remote_rank, 00352 AFEPack::istream<>& is) { 00353 const data_t * p_data = geo->get_property(_pid_in); 00354 assert (p_data != NULL); 00355 assert (geo->get_property(_pid_out) != NULL); 00356 is >> **p_data; 00357 } 00358 }; 00359 00360 namespace details { 00361 template <class OBJ, class DATA> 00362 struct _dummy_packer { 00363 DATA * _dummy_func(const OBJ&, const property_id_t<DATA>&) { return NULL; } 00364 }; 00365 00369 template <class OBJ, class DATA, 00370 class PACKER = _dummy_packer<OBJ,DATA> > 00371 class Packer { 00372 public: 00373 typedef OBJ object_t; 00374 typedef DATA data_t; 00375 typedef PACKER packer_t; 00376 typedef property_id_t<data_t> pid_t; 00377 typedef data_t * (packer_t::*fun_ptr_t)(const object_t&, const pid_t&) const; 00378 00379 private: 00380 typedef Packer<object_t,data_t,packer_t> this_t; 00381 const packer_t * _packer; 00382 fun_ptr_t _new_property; 00383 fun_ptr_t _get_property; 00384 00385 public: 00386 Packer() {} 00387 Packer(const packer_t& pac, fun_ptr_t _np, fun_ptr_t _gp) : 00388 _packer(&pac), _new_property(_np), _get_property(_gp) {} 00389 Packer(const this_t& fdp) : _packer(fdp._packer), 00390 _new_property(fdp._new_property), _get_property(fdp._get_property) {} 00391 this_t& operator=(const this_t& fdp) { 00392 _packer = fdp._packer; 00393 _new_property = fdp._new_property; 00394 _get_property = fdp._get_property; 00395 return *this; 00396 } 00397 00398 public: 00399 const packer_t * packer() const { return _packer; } 00400 data_t * get_property(const object_t& obj, const pid_t& pid) const { 00401 return (_packer->*_get_property)(obj, pid); 00402 }; 00403 data_t * new_property(const object_t& obj, const pid_t& pid) const { 00404 return (_packer->*_new_property)(obj, pid); 00405 }; 00406 }; 00407 00411 template <class OBJ, class DATA> 00412 class Packer<OBJ,DATA,_dummy_packer<OBJ,DATA> > { 00413 public: 00414 typedef OBJ object_t; 00415 typedef DATA data_t; 00416 typedef _dummy_packer<object_t,DATA> packer_t; 00417 typedef property_id_t<data_t> pid_t; 00418 typedef data_t * (*fun_ptr_t)(const object_t&, const pid_t&); 00419 private: 00420 typedef Packer<object_t,data_t,packer_t> this_t; 00421 fun_ptr_t _new_property; 00422 fun_ptr_t _get_property; 00423 public: 00424 Packer() {} 00425 Packer(fun_ptr_t _np, fun_ptr_t _gp) : 00426 _new_property(_np), _get_property(_gp) {} 00427 Packer(const this_t& fdp) : 00428 _new_property(fdp._new_property), _get_property(fdp._get_property) {} 00429 this_t& operator=(const this_t& fdp) { 00430 _new_property = fdp._new_property; 00431 _get_property = fdp._get_property; 00432 return *this; 00433 } 00434 public: 00435 const packer_t * packer() const { return NULL; } 00436 data_t * get_property(const object_t& obj, const pid_t& pid) const { 00437 return (*_get_property)(obj, pid); 00438 }; 00439 data_t * new_property(const object_t& obj, const pid_t& pid) const { 00440 return (*_new_property)(obj, pid); 00441 }; 00442 }; 00443 00444 } // namespace details 00445 00450 template <class DATA, class MESH> 00451 struct Mesh { 00452 typedef MESH mesh_t; 00453 typedef typename mesh_t::ir_mesh_t ir_mesh_t; 00454 typedef details::Packer<GeometryBM, DATA, mesh_t> packer_t; 00455 typedef HGeometry<mesh_t::dim-1,mesh_t::dow> h_geometry_t; 00456 static packer_t get_packer(const mesh_t& mesh) { 00457 return packer_t(mesh, 00458 &mesh_t::template new_property<DATA,mesh_t::dim-1>, 00459 &mesh_t::template get_property<DATA,mesh_t::dim-1>); 00460 } 00461 static packer_t get_packer(const ir_mesh_t& mesh) { 00462 return packer_t(mesh.regularMesh(), 00463 &mesh_t::template new_property<DATA,mesh_t::dim-1>, 00464 &mesh_t::template get_property<DATA,mesh_t::dim-1>); 00465 } 00466 }; 00467 00472 template <class DATA, class SPACE> 00473 struct FESpace { 00474 typedef SPACE fe_space_t; 00475 typedef typename fe_space_t::dg_element_t dg_element_t; 00476 typedef details::Packer<dg_element_t, DATA, fe_space_t> packer_t; 00477 typedef HGeometry<fe_space_t::tdim1, fe_space_t::dow> h_geometry_t; 00478 static packer_t get_packer(const fe_space_t& sp) { 00479 return packer_t(sp, 00480 &fe_space_t::template new_property<DATA>, 00481 &fe_space_t::template get_property<DATA>); 00482 } 00483 }; 00484 00485 } // namespace FaceData 00486 } // namespace MPI 00487 00488 #endif // __MPI_FaceData_h__ 00489
1.7.4