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