dune-common 2.1.1
plocalindex.hh
Go to the documentation of this file.
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     
00170   template<typename T>
00171   struct LocalIndexComparator<ParallelLocalIndex<T> >
00172   {
00173     static bool compare(const ParallelLocalIndex<T>& t1, 
00174                         const ParallelLocalIndex<T>& t2){
00175       return t1.attribute()<t2.attribute();
00176     }
00177   };
00178 
00179 
00180 #if HAVE_MPI
00181 
00183   template<typename T>
00184   class MPITraits<ParallelLocalIndex<T> >
00185   {
00186   public:
00187     static MPI_Datatype getType();
00188   private:
00189     static MPI_Datatype type;
00190     
00191   };
00192   
00193 #endif
00194 
00195   template<class T>
00196   ParallelLocalIndex<T>::ParallelLocalIndex(const T& attribute, bool isPublic) 
00197     : localIndex_(0), attribute_(static_cast<char>(attribute)), 
00198       public_(static_cast<char>(isPublic)), state_(static_cast<char>(VALID))
00199   {}
00200 
00201 
00202   template<class T>
00203   ParallelLocalIndex<T>::ParallelLocalIndex(size_t local, const T& attribute, bool isPublic) 
00204     : localIndex_(local), attribute_(static_cast<char>(attribute)), 
00205       public_(static_cast<char>(isPublic)), state_(static_cast<char>(VALID))
00206   {}
00207 
00208   template<class T>
00209   ParallelLocalIndex<T>::ParallelLocalIndex() 
00210     : localIndex_(0), attribute_(), public_(static_cast<char>(false)), 
00211       state_(static_cast<char>(VALID))
00212   {}
00213 
00214   template<class T>
00215   inline const T ParallelLocalIndex<T>::attribute() const
00216   {
00217     return T(attribute_);
00218   }
00219 
00220   template<class T>
00221   inline void 
00222   ParallelLocalIndex<T>::setAttribute(const Attribute& attribute)
00223   {
00224     attribute_ = attribute;
00225   }
00226 
00227   template<class T>
00228   inline size_t ParallelLocalIndex<T>::local() const
00229   {
00230     return localIndex_;
00231   }
00232 
00233   template<class T>
00234   inline ParallelLocalIndex<T>::operator size_t() const
00235   {
00236     return localIndex_;
00237   }
00238     
00239   template<class T>
00240   inline ParallelLocalIndex<T>& 
00241   ParallelLocalIndex<T>::operator=(size_t index)
00242   {
00243     localIndex_=index;
00244     return *this;
00245   }
00246 
00247   template<class T>
00248   inline bool ParallelLocalIndex<T>::isPublic() const
00249   {
00250     return static_cast<bool>(public_);
00251   }
00252 
00253   template<class T>
00254   inline LocalIndexState ParallelLocalIndex<T>::state() const
00255   {
00256     return LocalIndexState(state_);
00257   }
00258 
00259   template<class T>
00260   inline void ParallelLocalIndex<T>::setState(const LocalIndexState& state)
00261   {
00262     state_=static_cast<char>(state);
00263   }
00264 
00265 #if HAVE_MPI
00266 
00267   template<typename T>
00268   MPI_Datatype MPITraits<ParallelLocalIndex<T> >::getType()
00269   {
00270     
00271     if(type==MPI_DATATYPE_NULL){
00272       int length[3];
00273       MPI_Aint disp[3];
00274       MPI_Datatype types[3] = {MPI_LB, MPITraits<char>::getType(), MPI_UB};
00275       ParallelLocalIndex<T> rep[2];
00276       length[0]=length[1]=length[2]=1;
00277       MPI_Address(rep, disp); // lower bound of the datatype
00278       MPI_Address(&(rep[0].attribute_), disp+1);
00279       MPI_Address(rep+1, disp+2); // upper bound of the datatype
00280       for(int i=2; i >= 0; --i)
00281         disp[i] -= disp[0];
00282       MPI_Type_struct(3, length, disp, types, &type);
00283       MPI_Type_commit(&type);
00284     }
00285     return type;
00286   }
00287   
00288   template<typename T>
00289   MPI_Datatype MPITraits<ParallelLocalIndex<T> >::type = MPI_DATATYPE_NULL;
00290 
00291 #endif
00292 
00293 
00295 } // namespace Dune
00296 
00297 #endif