dune-common
2.2.0
|
00001 // $Id$ 00002 00003 #ifndef DUNE_PLOCALINDEX_HH 00004 #define DUNE_PLOCALINDEX_HH 00005 00006 #include "localindex.hh" 00007 #include "indexset.hh" 00008 #include <iostream> 00009 00010 #include <dune/common/mpitraits.hh> 00011 00012 namespace Dune 00013 { 00014 00015 00026 template<class T> class ParallelLocalIndex; 00027 00033 template<class T> 00034 std::ostream& operator<<(std::ostream& os, const ParallelLocalIndex<T>& index) 00035 { 00036 os<<"{local="<<index.localIndex_<<", attr="<<T(index.attribute_)<<", public=" 00037 <<(index.public_?true:false)<<"}"; 00038 return os; 00039 } 00040 00044 template<typename T> 00045 class ParallelLocalIndex 00046 { 00047 #if HAVE_MPI 00048 // friend declaration needed for MPITraits 00049 friend class MPITraits<ParallelLocalIndex<T> >; 00050 #endif 00051 friend std::ostream& operator<<<>(std::ostream& os, const ParallelLocalIndex<T>& index); 00052 00053 public: 00061 typedef T Attribute; 00070 ParallelLocalIndex(const Attribute& attribute, bool isPublic); 00071 00080 ParallelLocalIndex(size_t localIndex, const Attribute& attribute, bool isPublic=true); 00086 ParallelLocalIndex(); 00087 00088 #if 0 00089 00098 ParallelLocalIndex(const Attribute& attribute, size_t local, bool isPublic); 00099 #endif 00100 00105 inline const Attribute attribute() const; 00106 00111 inline void setAttribute(const Attribute& attribute); 00112 00117 inline size_t local() const; 00118 00122 inline operator size_t() const; 00123 00129 inline ParallelLocalIndex<Attribute>& operator=(size_t index); 00130 00135 inline bool isPublic() const; 00136 00141 inline LocalIndexState state() const; 00142 00147 inline void setState(const LocalIndexState& state); 00148 00149 private: 00151 size_t localIndex_; 00152 00154 char attribute_; 00155 00157 char public_; 00158 00165 char state_; 00166 00167 }; 00168 00169 template<typename T> 00170 bool operator==(const ParallelLocalIndex<T>& p1, 00171 const ParallelLocalIndex<T>& p2) 00172 { 00173 if(p1.local()!=p2.local()) 00174 return false; 00175 if(p1.attribute()!=p2.attribute()) 00176 return false; 00177 if(p1.isPublic()!=p2.isPublic()) 00178 return false; 00179 return true; 00180 } 00181 template<typename T> 00182 bool operator!=(const ParallelLocalIndex<T>& p1, 00183 const ParallelLocalIndex<T>& p2) 00184 { 00185 return !(p1==p2); 00186 } 00187 00188 00189 template<typename T> 00190 struct LocalIndexComparator<ParallelLocalIndex<T> > 00191 { 00192 static bool compare(const ParallelLocalIndex<T>& t1, 00193 const ParallelLocalIndex<T>& t2){ 00194 return t1.attribute()<t2.attribute(); 00195 } 00196 }; 00197 00198 00199 #if HAVE_MPI 00200 00202 template<typename T> 00203 class MPITraits<ParallelLocalIndex<T> > 00204 { 00205 public: 00206 static MPI_Datatype getType(); 00207 private: 00208 static MPI_Datatype type; 00209 00210 }; 00211 00212 #endif 00213 00214 template<class T> 00215 ParallelLocalIndex<T>::ParallelLocalIndex(const T& attribute, bool isPublic) 00216 : localIndex_(0), attribute_(static_cast<char>(attribute)), 00217 public_(static_cast<char>(isPublic)), state_(static_cast<char>(VALID)) 00218 {} 00219 00220 00221 template<class T> 00222 ParallelLocalIndex<T>::ParallelLocalIndex(size_t local, const T& attribute, bool isPublic) 00223 : localIndex_(local), attribute_(static_cast<char>(attribute)), 00224 public_(static_cast<char>(isPublic)), state_(static_cast<char>(VALID)) 00225 {} 00226 00227 template<class T> 00228 ParallelLocalIndex<T>::ParallelLocalIndex() 00229 : localIndex_(0), attribute_(), public_(static_cast<char>(false)), 00230 state_(static_cast<char>(VALID)) 00231 {} 00232 00233 template<class T> 00234 inline const T ParallelLocalIndex<T>::attribute() const 00235 { 00236 return T(attribute_); 00237 } 00238 00239 template<class T> 00240 inline void 00241 ParallelLocalIndex<T>::setAttribute(const Attribute& attribute) 00242 { 00243 attribute_ = attribute; 00244 } 00245 00246 template<class T> 00247 inline size_t ParallelLocalIndex<T>::local() const 00248 { 00249 return localIndex_; 00250 } 00251 00252 template<class T> 00253 inline ParallelLocalIndex<T>::operator size_t() const 00254 { 00255 return localIndex_; 00256 } 00257 00258 template<class T> 00259 inline ParallelLocalIndex<T>& 00260 ParallelLocalIndex<T>::operator=(size_t index) 00261 { 00262 localIndex_=index; 00263 return *this; 00264 } 00265 00266 template<class T> 00267 inline bool ParallelLocalIndex<T>::isPublic() const 00268 { 00269 return static_cast<bool>(public_); 00270 } 00271 00272 template<class T> 00273 inline LocalIndexState ParallelLocalIndex<T>::state() const 00274 { 00275 return LocalIndexState(state_); 00276 } 00277 00278 template<class T> 00279 inline void ParallelLocalIndex<T>::setState(const LocalIndexState& state) 00280 { 00281 state_=static_cast<char>(state); 00282 } 00283 00284 #if HAVE_MPI 00285 00286 template<typename T> 00287 MPI_Datatype MPITraits<ParallelLocalIndex<T> >::getType() 00288 { 00289 00290 if(type==MPI_DATATYPE_NULL){ 00291 int length[3]; 00292 MPI_Aint disp[3]; 00293 MPI_Datatype types[3] = {MPI_LB, MPITraits<char>::getType(), MPI_UB}; 00294 ParallelLocalIndex<T> rep[2]; 00295 length[0]=length[1]=length[2]=1; 00296 MPI_Address(rep, disp); // lower bound of the datatype 00297 MPI_Address(&(rep[0].attribute_), disp+1); 00298 MPI_Address(rep+1, disp+2); // upper bound of the datatype 00299 for(int i=2; i >= 0; --i) 00300 disp[i] -= disp[0]; 00301 MPI_Type_struct(3, length, disp, types, &type); 00302 MPI_Type_commit(&type); 00303 } 00304 return type; 00305 } 00306 00307 template<typename T> 00308 MPI_Datatype MPITraits<ParallelLocalIndex<T> >::type = MPI_DATATYPE_NULL; 00309 00310 #endif 00311 00312 00314 } // namespace Dune 00315 00316 #endif