00001
00002
00003
00004 #ifndef DUNE_PLOCALINDEX_HH
00005 #define DUNE_PLOCALINDEX_HH
00006
00007 #include "localindex.hh"
00008 #include "indexset.hh"
00009 #include "mpitraits.hh"
00010
00011 #include <iostream>
00012
00013 namespace Dune
00014 {
00015
00016
00027 template<class T> class ParallelLocalIndex;
00028
00034 template<class T>
00035 std::ostream& operator<<(std::ostream& os, const ParallelLocalIndex<T>& index)
00036 {
00037 os<<"{local="<<index.localIndex_<<", attr="<<T(index.attribute_)<<", public="
00038 <<(index.public_ ? true : false)<<"}";
00039 return os;
00040 }
00041
00045 template<typename T>
00046 class ParallelLocalIndex
00047 {
00048 #if HAVE_MPI
00049
00050 friend struct MPITraits<ParallelLocalIndex<T> >;
00051 #endif
00052 friend std::ostream& operator<<<>(std::ostream& os, const ParallelLocalIndex<T>& index);
00053
00054 public:
00062 typedef T Attribute;
00071 ParallelLocalIndex(const Attribute& attribute, bool isPublic);
00072
00081 ParallelLocalIndex(size_t localIndex, const Attribute& attribute, bool isPublic=true);
00087 ParallelLocalIndex();
00088
00089 #if 0
00090
00099 ParallelLocalIndex(const Attribute& attribute, size_t local, bool isPublic);
00100 #endif
00101
00106 inline const Attribute attribute() const;
00107
00112 inline void setAttribute(const Attribute& attribute);
00113
00118 inline size_t local() const;
00119
00123 inline operator size_t() const;
00124
00130 inline ParallelLocalIndex<Attribute>& operator=(size_t index);
00131
00136 inline bool isPublic() const;
00137
00142 inline LocalIndexState state() const;
00143
00148 inline void setState(const LocalIndexState& state);
00149
00150 private:
00152 size_t localIndex_;
00153
00155 char attribute_;
00156
00158 char public_;
00159
00166 char state_;
00167
00168 };
00169
00170 template<typename T>
00171 bool operator==(const ParallelLocalIndex<T>& p1,
00172 const ParallelLocalIndex<T>& p2)
00173 {
00174 if(p1.local()!=p2.local())
00175 return false;
00176 if(p1.attribute()!=p2.attribute())
00177 return false;
00178 if(p1.isPublic()!=p2.isPublic())
00179 return false;
00180 return true;
00181 }
00182 template<typename T>
00183 bool operator!=(const ParallelLocalIndex<T>& p1,
00184 const ParallelLocalIndex<T>& p2)
00185 {
00186 return !(p1==p2);
00187 }
00188
00189
00190 template<typename T>
00191 struct LocalIndexComparator<ParallelLocalIndex<T> >
00192 {
00193 static bool compare(const ParallelLocalIndex<T>& t1,
00194 const ParallelLocalIndex<T>& t2){
00195 return t1.attribute()<t2.attribute();
00196 }
00197 };
00198
00199
00200 #if HAVE_MPI
00201
00203 template<typename T>
00204 class MPITraits<ParallelLocalIndex<T> >
00205 {
00206 public:
00207 static MPI_Datatype getType();
00208 private:
00209 static MPI_Datatype type;
00210
00211 };
00212
00213 #endif
00214
00215 template<class T>
00216 ParallelLocalIndex<T>::ParallelLocalIndex(const T& attribute, bool isPublic)
00217 : localIndex_(0), attribute_(static_cast<char>(attribute)),
00218 public_(static_cast<char>(isPublic)), state_(static_cast<char>(VALID))
00219 {}
00220
00221
00222 template<class T>
00223 ParallelLocalIndex<T>::ParallelLocalIndex(size_t local, const T& attribute, bool isPublic)
00224 : localIndex_(local), attribute_(static_cast<char>(attribute)),
00225 public_(static_cast<char>(isPublic)), state_(static_cast<char>(VALID))
00226 {}
00227
00228 template<class T>
00229 ParallelLocalIndex<T>::ParallelLocalIndex()
00230 : localIndex_(0), attribute_(), public_(static_cast<char>(false)),
00231 state_(static_cast<char>(VALID))
00232 {}
00233
00234 template<class T>
00235 inline const T ParallelLocalIndex<T>::attribute() const
00236 {
00237 return T(attribute_);
00238 }
00239
00240 template<class T>
00241 inline void
00242 ParallelLocalIndex<T>::setAttribute(const Attribute& attribute)
00243 {
00244 attribute_ = attribute;
00245 }
00246
00247 template<class T>
00248 inline size_t ParallelLocalIndex<T>::local() const
00249 {
00250 return localIndex_;
00251 }
00252
00253 template<class T>
00254 inline ParallelLocalIndex<T>::operator size_t() const
00255 {
00256 return localIndex_;
00257 }
00258
00259 template<class T>
00260 inline ParallelLocalIndex<T>&
00261 ParallelLocalIndex<T>::operator=(size_t index)
00262 {
00263 localIndex_=index;
00264 return *this;
00265 }
00266
00267 template<class T>
00268 inline bool ParallelLocalIndex<T>::isPublic() const
00269 {
00270 return static_cast<bool>(public_);
00271 }
00272
00273 template<class T>
00274 inline LocalIndexState ParallelLocalIndex<T>::state() const
00275 {
00276 return LocalIndexState(state_);
00277 }
00278
00279 template<class T>
00280 inline void ParallelLocalIndex<T>::setState(const LocalIndexState& state)
00281 {
00282 state_=static_cast<char>(state);
00283 }
00284
00285 #if HAVE_MPI
00286
00287 template<typename T>
00288 MPI_Datatype MPITraits<ParallelLocalIndex<T> >::getType()
00289 {
00290
00291 if(type==MPI_DATATYPE_NULL) {
00292 int length = 1;
00293 MPI_Aint base, disp;
00294 MPI_Datatype types[1] = {MPITraits<char>::getType()};
00295 ParallelLocalIndex<T> rep;
00296 MPI_Get_address(&rep, &base);
00297 MPI_Get_address(&(rep.attribute_), &disp);
00298 disp -= base;
00299
00300 MPI_Datatype tmp;
00301 MPI_Type_create_struct(1, &length, &disp, types, &tmp);
00302
00303 MPI_Type_create_resized(tmp, 0, sizeof(ParallelLocalIndex<T>), &type);
00304 MPI_Type_commit(&type);
00305
00306 MPI_Type_free(&tmp);
00307 }
00308 return type;
00309 }
00310
00311 template<typename T>
00312 MPI_Datatype MPITraits<ParallelLocalIndex<T> >::type = MPI_DATATYPE_NULL;
00313
00314 #endif
00315
00316
00318 }
00319
00320 #endif