00001 #ifndef ENTITIES_OWNERSHIP_HPP_
00002 #define ENTITIES_OWNERSHIP_HPP_
00003
00004 #include <vector>
00005
00006 #include "uth_log.h"
00007 #include "mmh_intf.h"
00008 #include "un_ord_map_selector.hpp"
00009
00010
00011 namespace mmpt {
00012
00013
00014 typedef int (*fStatPtr)(int,int);
00015 typedef int (*fQueryPtr)(int);
00016
00017 const int N_TYPES = MMC_ALL_N_TYPES+1;
00018
00019 static const fStatPtr status_func[N_TYPES] =
00020 {
00021 mmr_node_status,
00022 mmr_edge_status,
00023 mmr_fa_status,
00024 mmr_el_status,
00025 NULL
00026 };
00027
00028 static const fQueryPtr last_func[N_TYPES] =
00029 {
00030 mmr_get_max_node_id,
00031 mmr_get_max_edge_id,
00032 mmr_get_max_face_id,
00033 mmr_get_max_elem_id,
00034 NULL
00035 };
00036
00037
00038 template<typename TOwnership>
00039 class EntitiesOwnership
00040 {
00041 int local_owner_id;
00042 int mesh_id;
00043
00044 public:
00045
00046 typedef TOwnership EntOwn;
00047
00048
00049 static const EntOwn OWN_NULL ;
00050 static const EntOwn OWN_SELF ;
00051
00052
00053 enum BOUNDARABLE_TYPE{
00054 INNER_BOUNDARABLE=0,
00055 OUTER_BOUNDARABLE,
00056 ANY_BOUNDARABLE,
00057 LAST_BOUNDARABLE
00058 };
00059
00060 static const int UNDEFINED = -1;
00061 static const int SELF = -2;
00062 static const int FOREGIN = -3;
00063
00064 EntitiesOwnership()
00065 : local_owner_id(-1),mesh_id(-1)
00066 {
00067
00068 }
00069
00070 void setMeshId(const int Mesh_id) {
00071 mesh_id = Mesh_id;
00072
00073 boundarables[MMC_NODE].resize(mmr_get_nr_node(Mesh_id));
00074 boundarables[MMC_EDGE].resize(mmr_get_nr_edge(Mesh_id));
00075 boundarables[MMC_FACE].resize(mmr_get_nr_face(Mesh_id));
00076 boundarables[MMC_ELEMENT].resize(mmr_get_nr_elem(Mesh_id));
00077 }
00078
00079 void setLocalOwnerID(int owner_proc_id) {
00080 local_owner_id = owner_proc_id;
00081 }
00082
00083 int getLocalOwnerID() const {
00084 return local_owner_id;
00085 }
00086
00087 void Set(EntOwn & gid, const int owner, const int id_at_owner) const {
00088 gid.owner = owner;
00089 gid.id_at_owner = id_at_owner;
00090 }
00091
00092 void SetOwner(EntOwn & gid, const int owner) const {
00093 gid.owner = owner;
00094 }
00095
00096 void SetId_at_owner(EntOwn & gid, const int id_at_owner) const {
00097 gid.id_at_owner = id_at_owner;
00098 }
00099
00100 int GetOwner(const EntOwn & gid) const {
00101 return gid.owner;
00102 }
00103
00104 int GetId_at_owner(const EntOwn & gid) const {
00105 return gid.id_at_owner;
00106 }
00107
00108 template<int type>
00109 void AddOwnership(const int loc_id,const EntOwn& own) {
00110 mf_check_debug(loc_id > 0, "Wrong local id(%d)!",loc_id);
00111 mf_check(own.owner != local_owner_id, "Adding ownership for self!");
00112 ownerships[type][loc_id] = own;
00113 own2loc[type][own] = loc_id;
00114 mf_log_info("Adding ownership of %d as (%d,%d)",
00115 loc_id,own.owner,own.id_at_owner);
00116 setBoundarable<type>(loc_id);
00117 }
00118
00119 template<int type>
00120 int GetOwner(const int loc_id) const {
00121 int owner = UNDEFINED;
00122 mf_check_debug(loc_id > 0, "Wrong local id(%d)!",loc_id);
00123 typename O_MAP::const_iterator it = ownerships[type].find(loc_id);
00124 if(it != ownerships[type].end()) {
00125 owner = it->second.owner;
00126 }
00127 else {
00128 if(MMC_ACTIVE == status_func[type](mesh_id,loc_id)) {
00129 owner = local_owner_id;
00130 }
00131 }
00132 return owner;
00133 }
00134
00135 template<int type>
00136 int GetId_at_owner(const int loc_id) const {
00137 int id_at_owner = UNDEFINED;
00138 mf_check_debug(loc_id > 0, "Wrong local id(%d)!",loc_id);
00139 typename O_MAP::const_iterator it = ownerships[type].find(loc_id);
00140 if(it != ownerships[type].end()) {
00141 id_at_owner = it->second.id_at_owner;
00142 }
00143 else {
00144 if(MMC_ACTIVE == status_func[type](mesh_id,loc_id)) {
00145 id_at_owner = loc_id;
00146 }
00147 }
00148 return id_at_owner;
00149 }
00150
00151 template<int type>
00152 void GetOwnership(const int loc_id, EntOwn& own) const {
00153 mf_check_debug(loc_id > 0, "Wrong local id(%d)!",loc_id);
00154 typename O_MAP::const_iterator it = ownerships[type].find(loc_id);
00155 if(it == ownerships[type].end() ) {
00156 own.id_at_owner = loc_id;
00157 own.owner = local_owner_id;
00158 }
00159 else {
00160 own = it->second;
00161 }
00162 }
00163
00164 template<int type>
00165 int GetLocIdForOwnership(const EntOwn & own) const {
00166 int loc_id = UNDEFINED;
00167 if(own.owner == local_owner_id) {
00168 if(MMC_ACTIVE == status_func[type](mesh_id,own.id_at_owner)) {
00169 loc_id = own.id_at_owner;
00170 }
00171 }
00172 else {
00173 typename G_MAP::const_iterator it = own2loc[type].find(own);
00174 if(it != own2loc[type].end()) {
00175 loc_id = it->second;
00176 }
00177 }
00178
00179 mf_check(loc_id <= last_func[type](mesh_id), "Loc id (%d) out-of-bounds(%d)!",loc_id, last_func[type](mesh_id));
00180
00181 return loc_id;
00182 }
00183
00184 template<int type>
00185 int RemoveID(const int LocID)
00186 {
00187 typename O_MAP::iterator it = ownerships[type].find(LocID);
00188 if(it != ownerships[type].end()) {
00189 own2loc[type].erase(it->second);
00190 ownerships[type].erase(it);
00191 }
00192 boundarables[type][LocID]=false;
00193 }
00194
00195 template<int type>
00196 int RemoveID(const EntOwn & own)
00197 {
00198 typename G_MAP::iterator it = own2loc[type].find(own);
00199 if(it != own2loc[type].end()) {
00200 ownerships[type].erase(it->second);
00201 own2loc[type].erase(it);
00202 }
00203 }
00204
00205 template<int type>
00206 void setBoundarable(const int Loc_pos)
00207 {
00208 if(boundarables[type].size() <= Loc_pos) {
00209 boundarables[type].resize(Loc_pos+10);
00210 }
00211 boundarables[type][Loc_pos] = true;
00212 }
00213
00214 template<int type>
00215 const std::vector<bool>& getBoundarables() const {
00216 return boundarables[type];
00217 }
00218
00219
00220 template<int Ttype>
00221 void getBoundarablesGlobIDs(std::vector<EntOwn> & Adapt_boundarables,
00222 const BOUNDARABLE_TYPE B_type) const
00223 {
00224 std::vector<bool>::const_iterator it = boundarables[Ttype].begin();
00225 const std::vector<bool>::const_iterator end = boundarables[Ttype].end();
00226
00227 for(int i=0;it != end;++it, ++i) {
00228 if(*it) {
00229 typename O_MAP::const_iterator o_it = ownerships[Ttype].find(i);
00230
00231 bool is_local = ( o_it == ownerships[Ttype].end() ) ;
00232
00233 switch(B_type) {
00234 case INNER_BOUNDARABLE:
00235 if(is_local) {
00236 Adapt_boundarables.push_back(EntOwn(local_owner_id,i));
00237 }
00238 break;
00239 case OUTER_BOUNDARABLE:
00240 if(!is_local) {
00241 Adapt_boundarables.push_back(o_it->second);
00242 }
00243 break;
00244 case ANY_BOUNDARABLE:
00245 default:
00246 mf_fatal_err("Unknown boundrable type");
00247 break;
00248 }
00249 }
00250 }
00251 }
00252
00253 template<int type>
00254 int getBoundaryOwnerships(int * first, const int *last,
00255 std::vector<const EntOwn*>& boundOwns) const
00256 {
00257 assert(first <= last);
00258
00259 int n_boundarables=0;
00260
00261 boundOwns.reserve(last-first);
00262
00263 typename O_MAP::const_iterator it;
00264
00265 for(;first != last; ++first) {
00266 if(boundarables[type][*first]) {
00267 it = ownerships[type].find(*first);
00268 if(it == ownerships[type].end()) {
00269 boundOwns.push_back(& OWN_SELF);
00270 }
00271 else {
00272 boundOwns.push_back( & it->second );
00273 }
00274
00275 ++n_boundarables;
00276 }
00277 else {
00278 boundOwns.push_back(& OWN_NULL);
00279 }
00280 }
00281 return n_boundarables;
00282 }
00283
00284 bool check() const
00285 {
00286 int nel=0;
00287 EntOwn tmp;
00288 while(0!=(nel=mmr_get_next_elem_all(mesh_id,nel))) {
00289 GetOwnership<MMC_ELEMENT>(nel,tmp);
00290 if(tmp.owner == local_owner_id) {
00291 mf_check(tmp.id_at_owner == nel,
00292 "Incorrect ownership(%d,%d) for %d !",
00293 tmp.owner,tmp.id_at_owner,
00294 nel);
00295 }
00296
00297 mf_check(GetLocIdForOwnership<MMC_ELEMENT>(tmp) == nel,
00298 "Incorrect ownership(%d,%d) for %d !",
00299 tmp.owner,tmp.id_at_owner,
00300 nel);
00301
00302 }
00303
00304
00305
00306 return true;
00307 }
00308
00309 private:
00310
00311 #ifdef BOOST_NO_CXX11_HDR_UNORDERED_MAP
00312 typedef boost::unordered_map<int,EntOwn> O_MAP;
00313 typedef boost::unordered_map<EntOwn,int> G_MAP;
00314 #else
00315 typedef std::unordered_map<int,EntOwn> O_MAP;
00316 typedef std::unordered_map<EntOwn,int> G_MAP;
00317 #endif
00318
00319 O_MAP ownerships[N_TYPES];
00320 G_MAP own2loc[N_TYPES];
00321
00322 std::vector<bool> boundarables[N_TYPES];
00323 };
00324
00325 template<typename T>
00326 const typename EntitiesOwnership<T>::EntOwn EntitiesOwnership<T>::OWN_NULL(EntitiesOwnership<T>::UNDEFINED,EntitiesOwnership<T>::UNDEFINED);
00327 template<typename T>
00328 const typename EntitiesOwnership<T>::EntOwn EntitiesOwnership<T>::OWN_SELF(EntitiesOwnership<T>::SELF,EntitiesOwnership<T>::UNDEFINED);
00329
00330
00331 }
00332
00333 #endif // ENTITIES_OWNERSHIP_HPP_