dune-common  2.2.0
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   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