indexset.hh

Go to the documentation of this file.
00001 // $Id: indexset.hh 776 2007-05-10 11:12:19Z mblatt $
00002 #ifndef DUNE_INDEXSET_HH
00003 #define DUNE_INDEXSET_HH
00004 
00005 #include<algorithm>
00006 #include<dune/common/arraylist.hh>
00007 #include<dune/common/exceptions.hh>
00008 #include<iostream>
00009 
00010 #include"localindex.hh"
00011 
00012 #include <stdint.h> // for uint32_t
00013 
00014 namespace Dune
00015 {
00025   // forward declarations
00026 
00027   template<class TG, class TL>
00028   class IndexPair;
00029   
00035   template<class TG, class TL>
00036   std::ostream& operator<<(std::ostream& os, const IndexPair<TG,TL>& pair);
00037 
00038   template<class TG, class TL>
00039   bool operator==(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00040 
00041   template<class TG, class TL>
00042   bool operator!=(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00043     
00044   template<class TG, class TL>
00045   bool operator<(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00046 
00047   template<class TG, class TL>
00048   bool operator>(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00049 
00050   template<class TG, class TL>
00051   bool operator<=(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00052 
00053   template<class TG, class TL>
00054   bool operator >=(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00055 
00056   template<class TG, class TL>
00057   bool operator==(const IndexPair<TG,TL>&, const TG&);
00058 
00059   template<class TG, class TL>
00060   bool operator!=(const IndexPair<TG,TL>&, const TG&);
00061     
00062   template<class TG, class TL>
00063   bool operator<(const IndexPair<TG,TL>&, const TG&);
00064 
00065   template<class TG, class TL>
00066   bool operator>(const IndexPair<TG,TL>&, const TG&);
00067 
00068   template<class TG, class TL>
00069   bool operator<=(const IndexPair<TG,TL>&, const TG&);
00070 
00071   template<class TG, class TL>
00072   bool operator >=(const IndexPair<TG,TL>&, const TG&);
00073   
00074   template<typename T>
00075   class MPITraits;
00076   
00080   template<class TG, class TL>
00081   class IndexPair
00082   {
00083     friend std::ostream& operator<<<>(std::ostream&, const IndexPair<TG,TL>&);
00084     friend bool operator==<>(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00085     friend bool operator!=<>(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00086     friend bool operator< <>(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00087     friend bool operator><>(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00088     friend bool operator<=<>(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00089     friend bool operator>=<>(const IndexPair<TG,TL>&, const IndexPair<TG,TL>&);
00090     friend bool operator==<>(const IndexPair<TG,TL>&, const TG&);
00091     friend bool operator!=<>(const IndexPair<TG,TL>&, const TG&);
00092     friend bool operator< <>(const IndexPair<TG,TL>&, const TG&);
00093     friend bool operator> <>(const IndexPair<TG,TL>&, const TG&);
00094     friend bool operator<=<>(const IndexPair<TG,TL>&, const TG&);
00095     friend bool operator>=<>(const IndexPair<TG,TL>&, const TG&);
00096     friend class MPITraits<IndexPair<TG,TL> >;
00097     
00098   public:
00104     typedef TG GlobalIndex;
00105         
00117     typedef TL LocalIndex;
00118 
00125     IndexPair(const GlobalIndex& global, const LocalIndex& local);
00126 
00130     IndexPair();
00137     IndexPair(const GlobalIndex& global);
00138 
00144     inline const GlobalIndex& global() const;
00145         
00151     inline LocalIndex& local();
00152 
00158     inline const LocalIndex& local()const;
00159 
00165     inline void setLocal(int index);
00166   private:
00168     GlobalIndex global_;
00170     LocalIndex local_;
00171   };
00172 
00177   enum ParallelIndexSetState 
00178     {
00183     GROUND, 
00187     RESIZE
00197   };
00198 
00202   class InvalidIndexSetState: public Exception{};
00203   
00204   // Forward declaration
00205   template<class I> class GlobalLookupIndexSet;
00206   
00213   template<typename TG, typename TL, int N=100>
00214   class ParallelIndexSet
00215   {
00216     friend class GlobalLookupIndexSet<ParallelIndexSet<TG,TL,N> >;
00217     
00218   public:    
00223     typedef TG GlobalIndex;
00224         
00236     typedef TL LocalIndex;
00237 
00241     typedef IndexPair<GlobalIndex,LocalIndex> IndexPair;
00242     
00243     enum{
00250       arraySize= (N>0)?N:1
00251         };
00252 
00254     class iterator : 
00255       public ArrayList<IndexPair,N>::iterator
00256     {
00257       typedef typename ArrayList<IndexPair,N>::iterator
00258       Father;
00259       friend class ParallelIndexSet<GlobalIndex,LocalIndex,N>;
00260     public:
00261       iterator(ParallelIndexSet<TG,TL,N>& indexSet, const Father& father)
00262         : Father(father), indexSet_(&indexSet)
00263       {}
00264 
00265       iterator(const iterator& other)
00266         : Father(other), indexSet_(other.indexSet_)
00267       {}
00268 
00269       iterator& operator==(const iterator& other)
00270       {
00271         Father::operator==(other);
00272         indexSet_ = other.indexSet_;
00273       }
00274             
00275     private:      
00283       inline void markAsDeleted() const throw(InvalidIndexSetState)
00284       {
00285 #ifndef NDEBUG
00286         if(indexSet_->state_ != RESIZE)
00287           DUNE_THROW(InvalidIndexSetState, "Indices can only be removed "
00288                      <<"while in RESIZE state!");
00289 #endif
00290         Father::operator*().local().setState(DELETED);
00291       }
00292 
00294       ParallelIndexSet<TG,TL,N>* indexSet_;
00295       
00296     };
00297     
00298     
00299 
00301     typedef typename 
00302     ArrayList<IndexPair,N>::const_iterator 
00303     const_iterator;
00304 
00308     ParallelIndexSet();
00309         
00314     inline const ParallelIndexSetState& state();
00315         
00321     void beginResize() throw(InvalidIndexSetState);
00322 
00331     inline void add(const GlobalIndex& global) throw(InvalidIndexSetState);
00332 
00341     inline void add(const GlobalIndex& global, const LocalIndex& local)
00342       throw(InvalidIndexSetState);
00343 
00351     inline void markAsDeleted(const iterator& position) 
00352       throw(InvalidIndexSetState);
00353 
00365     void endResize() throw(InvalidIndexSetState);
00366 
00376     inline IndexPair& 
00377     operator[](const GlobalIndex& global);
00378 
00379     
00389     inline const IndexPair& 
00390     operator[](const GlobalIndex& global) const;
00391 
00396     inline iterator begin();
00397 
00402     inline iterator end();
00403 
00408     inline const_iterator begin() const;
00409 
00414     inline const_iterator end() const;
00415 
00425     inline void renumberLocal();
00426 
00433     inline int seqNo() const;
00434 
00439     inline size_t size() const;
00440 
00441   private:
00443     ArrayList<IndexPair,N> localIndices_;
00445     ArrayList<IndexPair,N> newIndices_;
00447     ParallelIndexSetState state_;
00449     int seqNo_;
00451     bool deletedEntries_;
00456     inline void merge();
00457   };
00458 
00459   
00465   template<class TG, class TL, int N>
00466   std::ostream& operator<<(std::ostream& os, const ParallelIndexSet<TG,TL,N>& indexSet);
00467   
00473   template<class I>
00474   class GlobalLookupIndexSet
00475   {
00476   public:
00480     typedef I ParallelIndexSet;
00481     
00485     typedef typename ParallelIndexSet::LocalIndex LocalIndex;
00486     
00490     typedef typename ParallelIndexSet::GlobalIndex GlobalIndex;
00491 
00495     typedef typename ParallelIndexSet::const_iterator const_iterator;
00496     
00497     typedef IndexPair<typename I::GlobalIndex, typename I::LocalIndex> IndexPair;
00498     
00505     GlobalLookupIndexSet(const ParallelIndexSet& indexset, std::size_t size);
00506     
00510     ~GlobalLookupIndexSet();
00511     
00521     inline const IndexPair& 
00522     operator[](const GlobalIndex& global) const;
00523 
00527     inline const IndexPair*
00528     pair(const std::size_t& local) const;
00529     
00534     inline const_iterator begin() const;
00535 
00540     inline const_iterator end() const;
00541 
00548     inline int seqNo() const;
00549 
00554     inline size_t size() const;
00555   private:
00559     const ParallelIndexSet& indexSet_;
00560     
00564     std::size_t size_;
00565 
00569     std::vector<const IndexPair*> indices_;
00570     
00571   };
00572   
00573 
00574   template<class TG, class TL>
00575   inline std::ostream& operator<<(std::ostream& os, const IndexPair<TG,TL>& pair)
00576   {
00577     os<<"{global="<<pair.global_<<", local="<<pair.local_<<"}";
00578     return os;
00579   }
00580 
00581   template<class TG, class TL, int N>
00582   inline std::ostream& operator<<(std::ostream& os, const ParallelIndexSet<TG,TL,N>& indexSet)
00583   {
00584     typedef typename ParallelIndexSet<TG,TL,N>::const_iterator Iterator;
00585     Iterator end = indexSet.end();
00586     os<<"{";
00587     for(Iterator index = indexSet.begin(); index != end; ++index)
00588       os<<*index<<" ";
00589     os<<"}";
00590     return os;
00591     
00592   }
00593   
00594   template<class TG, class TL>
00595   inline bool operator==(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00596   {
00597     return a.global_==b.global_;
00598   }
00599 
00600   template<class TG, class TL>
00601   inline bool operator!=(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00602   {
00603     return a.global_!=b.global_;
00604   }
00605     
00606   template<class TG, class TL>
00607   inline bool operator<(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00608   {
00609     return a.global_<b.global_;
00610   }
00611 
00612   template<class TG, class TL>
00613   inline bool operator>(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00614   {
00615     return a.global_>b.global_;
00616   }
00617 
00618   template<class TG, class TL>
00619   inline bool operator<=(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00620   {
00621     return a.global_<=b.global_;
00622   }
00623 
00624   template<class TG, class TL>
00625   inline bool operator >=(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00626   {
00627     return a.global_>=b.global_;
00628   }
00629   
00630   template<class TG, class TL>
00631   inline bool operator==(const IndexPair<TG,TL>& a, const TG& b)
00632   {
00633     return a.global_==b;
00634   }
00635 
00636   template<class TG, class TL>
00637   inline bool operator!=(const IndexPair<TG,TL>& a, const TG& b)
00638   {
00639     return a.global_!=b;
00640   }
00641     
00642   template<class TG, class TL>
00643   inline bool operator<(const IndexPair<TG,TL>& a, const TG& b)
00644   {
00645     return a.global_<b;
00646   }
00647 
00648   template<class TG, class TL>
00649   inline bool operator>(const IndexPair<TG,TL>& a, const TG& b)
00650   {
00651     return a.global_>b;
00652   }
00653 
00654   template<class TG, class TL>
00655   inline bool operator<=(const IndexPair<TG,TL>& a, const TG& b)
00656   {
00657     return a.global_<=b;
00658   }
00659 
00660   template<class TG, class TL>
00661   inline bool operator >=(const IndexPair<TG,TL>& a, const TG& b)
00662   {
00663     return a.global_>=b;
00664   }
00665 
00666   template<class TG, class TL>
00667   IndexPair<TG,TL>::IndexPair(const TG& global, const TL& local)
00668     : global_(global), local_(local){}
00669 
00670   template<class TG, class TL>
00671   IndexPair<TG,TL>::IndexPair(const TG& global)
00672     : global_(global), local_(){}
00673 
00674   template<class TG, class TL>
00675   IndexPair<TG,TL>::IndexPair()
00676     : global_(), local_(){}
00677 
00678   template<class TG, class TL>
00679   inline const TG& IndexPair<TG,TL>::global() const{
00680     return global_;
00681   }
00682 
00683   template<class TG, class TL>
00684   inline TL& IndexPair<TG,TL>::local() {
00685     return local_;
00686   }
00687 
00688   template<class TG, class TL>
00689   inline const TL& IndexPair<TG,TL>::local() const{
00690     return local_;
00691   }
00692 
00693   template<class TG, class TL>
00694   inline void IndexPair<TG,TL>::setLocal(int local){
00695     local_=local;
00696   }
00697 
00698   template<class TG, class TL, int N>
00699   ParallelIndexSet<TG,TL,N>::ParallelIndexSet()
00700     : state_(GROUND), seqNo_(0)
00701   {}
00702 
00703   template<class TG, class TL, int N>
00704   void ParallelIndexSet<TG,TL,N>::beginResize() throw(InvalidIndexSetState)
00705   {
00706 
00707     // Checks in unproductive code
00708 #ifndef NDEBUG
00709     if(state_!=GROUND)
00710       DUNE_THROW(InvalidIndexSetState, 
00711                  "IndexSet has to be in GROUND state, when "
00712                  << "beginResize() is called!");
00713 #endif
00714         
00715     state_ = RESIZE;
00716     deletedEntries_ = false;
00717   }
00718 
00719   template<class TG, class TL, int N>
00720   inline void ParallelIndexSet<TG,TL,N>::add(const GlobalIndex& global) 
00721     throw(InvalidIndexSetState)
00722   {
00723     // Checks in unproductive code
00724 #ifndef NDEBUG
00725     if(state_ != RESIZE)
00726       DUNE_THROW(InvalidIndexSetState, "Indices can only be added "
00727                  <<"while in RESIZE state!");
00728 #endif
00729     newIndices_.push_back(IndexPair(global));
00730   }
00731 
00732   template<class TG, class TL, int N>
00733   inline void ParallelIndexSet<TG,TL,N>::add(const TG& global, const TL& local) 
00734     throw(InvalidIndexSetState)
00735   {
00736     // Checks in unproductive code
00737 #ifndef NDEBUG
00738     if(state_ != RESIZE)
00739       DUNE_THROW(InvalidIndexSetState, "Indices can only be added "
00740                  <<"while in RESIZE state!");
00741 #endif
00742     newIndices_.push_back(IndexPair(global,local));
00743   }
00744 
00745   template<class TG, class TL, int N>
00746   inline void ParallelIndexSet<TG,TL,N>::markAsDeleted(const iterator& global)
00747     throw(InvalidIndexSetState){
00748     // Checks in unproductive code    
00749 #ifndef NDEBUG
00750     if(state_ != RESIZE)
00751       DUNE_THROW(InvalidIndexSetState, "Indices can only be removed "
00752                  <<"while in RESIZE state!");
00753 #endif    
00754     deletedEntries_ = true;
00755 
00756     global.markAsDeleted();
00757   }
00758 
00759   template<class TG, class TL, int N>
00760   void ParallelIndexSet<TG,TL,N>::endResize() throw(InvalidIndexSetState){
00761     // Checks in unproductive code
00762 #ifndef NDEBUG
00763     if(state_ != RESIZE)
00764       DUNE_THROW(InvalidIndexSetState, "endResize called while not "
00765                  <<"in RESIZE state!");
00766 #endif
00767         
00768     std::sort(newIndices_.begin(), newIndices_.end());
00769     merge();
00770     seqNo_++;
00771     state_ = GROUND;
00772   }
00773 
00774   
00775   template<class TG, class TL, int N>
00776   inline void ParallelIndexSet<TG,TL,N>::merge(){
00777     if(localIndices_.size()==0)
00778       {
00779         localIndices_=newIndices_;
00780         newIndices_.clear();
00781       }
00782     else if(newIndices_.size()>0 || deletedEntries_)
00783       {
00784         ArrayList<IndexPair,N> tempPairs;
00785         typedef typename ArrayList<IndexPair,N>::iterator iterator;
00786         typedef typename ArrayList<IndexPair,N>::const_iterator const_iterator;
00787         
00788         iterator old=localIndices_.begin();
00789         iterator added=newIndices_.begin();
00790         const const_iterator endold=localIndices_.end();
00791         const const_iterator endadded=newIndices_.end();
00792                 
00793         while(old != endold && added!= endadded)
00794           {
00795             if(old->local().state()==DELETED){
00796               old.eraseToHere();
00797             }
00798             else if(old->global() < added->global())
00799               {
00800                 tempPairs.push_back(*old);
00801                 old.eraseToHere();
00802               }
00803             else if(old->global() == added->global()){
00804               // Indices have to be the same
00805               assert(old->local()==added->local());
00806               old.eraseToHere();
00807             }
00808             else
00809               {
00810                 tempPairs.push_back(*added);
00811                 added.eraseToHere();
00812               }
00813           }
00814 
00815         while(old != endold)
00816           {
00817             if(old->local().state()!=DELETED){
00818               tempPairs.push_back(*old);
00819             }
00820             old.eraseToHere();
00821           }
00822 
00823         while(added!= endadded)
00824           {
00825             tempPairs.push_back(*added);
00826             added.eraseToHere();
00827           }
00828         localIndices_ = tempPairs;
00829       }
00830   }
00831 
00832 
00833   template<class TG, class TL, int N>
00834   inline const IndexPair<TG,TL>& 
00835   ParallelIndexSet<TG,TL,N>::operator[](const TG& global) const
00836   {
00837     // perform a binary search
00838     int low=0, high=localIndices_.size()-1, probe=-1;
00839 
00840     while(low<high)
00841       {
00842         probe = (high + low) / 2;
00843         if(global <= localIndices_[probe].global())
00844           high = probe;
00845         else
00846           low = probe+1;
00847       }
00848 
00849 #ifdef DUNE_ISTL_WITH_CHECKING
00850     if(probe==-1)
00851       DUNE_THROW(RangeError, "No entries!");
00852 
00853     if( localIndices_[low].global() != global)
00854       DUNE_THROW(RangeError, "Could not find entry of "<<global);
00855     else
00856 #endif
00857       return localIndices_[low];
00858   }
00859 
00860 
00861   template<class TG, class TL, int N>
00862   inline IndexPair<TG,TL>& ParallelIndexSet<TG,TL,N>::operator[](const TG& global)
00863   {
00864     // perform a binary search
00865     int low=0, high=localIndices_.size()-1, probe=-1;
00866 
00867     while(low<high)
00868       {
00869         probe = (high + low) / 2;
00870         if(localIndices_[probe].global() >= global)
00871           high = probe;
00872         else
00873           low = probe+1;
00874       }
00875 
00876 #ifdef DUNE_ISTL_WITH_CHECKING
00877     if(probe==-1)
00878       DUNE_THROW(RangeError, "No entries!");
00879 
00880     if( localIndices_[low].global() != global)
00881       DUNE_THROW(RangeError, "Could not find entry of "<<global);
00882     else
00883 #endif
00884       return localIndices_[low];
00885   }
00886 
00887   template<class TG, class TL, int N>
00888   inline typename ParallelIndexSet<TG,TL,N>::iterator
00889   ParallelIndexSet<TG,TL,N>::begin()
00890   {
00891     return iterator(*this, localIndices_.begin());
00892   }
00893 
00894     
00895   template<class TG, class TL, int N>
00896   inline typename ParallelIndexSet<TG,TL,N>::iterator 
00897   ParallelIndexSet<TG,TL,N>::end()
00898   {
00899     return iterator(*this,localIndices_.end());
00900   }
00901 
00902   template<class TG, class TL, int N>
00903   inline typename ParallelIndexSet<TG,TL,N>::const_iterator 
00904   ParallelIndexSet<TG,TL,N>::begin() const
00905   {
00906     return localIndices_.begin();
00907   }
00908 
00909     
00910   template<class TG, class TL, int N>
00911   inline typename ParallelIndexSet<TG,TL,N>::const_iterator 
00912   ParallelIndexSet<TG,TL,N>::end() const
00913   {
00914     return localIndices_.end();
00915   }
00916 
00917   template<class TG, class TL, int N>
00918   void ParallelIndexSet<TG,TL,N>::renumberLocal(){
00919 #ifndef NDEBUG
00920     if(state_==RESIZE)
00921       DUNE_THROW(InvalidIndexSetState, "IndexSet has to be in "
00922                  <<"GROUND state for renumberLocal()");
00923 #endif
00924 
00925     typedef typename ArrayList<IndexPair,N>::iterator iterator;
00926     const const_iterator end_ = end();
00927     uint32_t index=0;
00928 
00929     for(iterator pair=begin(); pair!=end_; index++, ++pair)
00930       pair->local()=index;
00931   }
00932 
00933   template<class TG, class TL, int N>
00934   inline int ParallelIndexSet<TG,TL,N>::seqNo() const
00935   {
00936     return seqNo_;
00937   }
00938 
00939   template<class TG, class TL, int N>
00940   inline size_t ParallelIndexSet<TG,TL,N>::size() const
00941   {
00942     return localIndices_.size();
00943   }
00944 
00945   template<class I>
00946   GlobalLookupIndexSet<I>::GlobalLookupIndexSet(const I& indexset,
00947                                                 std::size_t size)
00948     : indexSet_(indexset), size_(size), 
00949       indices_(size_, static_cast<const IndexPair*>(0))
00950   {
00951     assert(size>=indexset.size());
00952     const_iterator end_ = indexSet_.end();
00953     size_t i=0;
00954     for(const_iterator pair = indexSet_.begin(); pair!=end_; ++pair, ++i){
00955       assert(pair->local()<size_);
00956       indices_[pair->local()] = &(*pair);
00957     }
00958   }
00959 
00960   template<class I>
00961   GlobalLookupIndexSet<I>::~GlobalLookupIndexSet()
00962   {}
00963   
00964 
00965   template<class I>
00966   inline const IndexPair<typename I::GlobalIndex, typename I::LocalIndex>*
00967   GlobalLookupIndexSet<I>::pair(const std::size_t& local) const
00968   {
00969     return indices_[local];
00970   }
00971   
00972   template<class I>
00973   inline const IndexPair<typename I::GlobalIndex, typename I::LocalIndex>&
00974   GlobalLookupIndexSet<I>::operator[](const GlobalIndex& global) const
00975   {
00976     return indexSet_[global];
00977   }
00978   
00979   template<class I>
00980   typename I::const_iterator GlobalLookupIndexSet<I>::begin() const
00981   {
00982     return indexSet_.begin();
00983   }
00984  
00985   template<class I>
00986   typename I::const_iterator GlobalLookupIndexSet<I>::end() const
00987   {
00988     return indexSet_.end();
00989   }
00990 
00991   template<class I>
00992   inline size_t GlobalLookupIndexSet<I>::size() const
00993   {
00994     return size_;
00995   }
00996   
00997   template<class I>
00998   inline int GlobalLookupIndexSet<I>::seqNo() const
00999   {
01000     return indexSet_.seqNo();
01001   }
01002 }
01003 #endif 

Generated on 12 Dec 2007 with Doxygen (ver 1.5.1)