indexset.hh

Go to the documentation of this file.
00001 // $Id: indexset.hh 956 2008-11-05 10:01:47Z 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 Dune::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 Dune::IndexPair<typename I::GlobalIndex, typename I::LocalIndex> IndexPair;
00498     
00505     GlobalLookupIndexSet(const ParallelIndexSet& indexset, std::size_t size);
00506     
00512     GlobalLookupIndexSet(const ParallelIndexSet& indexset);
00513 
00517     ~GlobalLookupIndexSet();
00518     
00528     inline const IndexPair& 
00529     operator[](const GlobalIndex& global) const;
00530 
00534     inline const IndexPair*
00535     pair(const std::size_t& local) const;
00536     
00541     inline const_iterator begin() const;
00542 
00547     inline const_iterator end() const;
00548 
00555     inline int seqNo() const;
00556 
00561     inline size_t size() const;
00562   private:
00566     const ParallelIndexSet& indexSet_;
00567     
00571     std::size_t size_;
00572 
00576     std::vector<const IndexPair*> indices_;
00577     
00578   };
00579   
00580 
00581   template<class TG, class TL>
00582   inline std::ostream& operator<<(std::ostream& os, const IndexPair<TG,TL>& pair)
00583   {
00584     os<<"{global="<<pair.global_<<", local="<<pair.local_<<"}";
00585     return os;
00586   }
00587 
00588   template<class TG, class TL, int N>
00589   inline std::ostream& operator<<(std::ostream& os, const ParallelIndexSet<TG,TL,N>& indexSet)
00590   {
00591     typedef typename ParallelIndexSet<TG,TL,N>::const_iterator Iterator;
00592     Iterator end = indexSet.end();
00593     os<<"{";
00594     for(Iterator index = indexSet.begin(); index != end; ++index)
00595       os<<*index<<" ";
00596     os<<"}";
00597     return os;
00598     
00599   }
00600   
00601   template<class TG, class TL>
00602   inline bool operator==(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00603   {
00604     return a.global_==b.global_;
00605   }
00606 
00607   template<class TG, class TL>
00608   inline bool operator!=(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00609   {
00610     return a.global_!=b.global_;
00611   }
00612     
00613   template<class TG, class TL>
00614   inline bool operator<(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00615   {
00616     return a.global_<b.global_;
00617   }
00618 
00619   template<class TG, class TL>
00620   inline bool operator>(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00621   {
00622     return a.global_>b.global_;
00623   }
00624 
00625   template<class TG, class TL>
00626   inline bool operator<=(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00627   {
00628     return a.global_<=b.global_;
00629   }
00630 
00631   template<class TG, class TL>
00632   inline bool operator >=(const IndexPair<TG,TL>& a, const IndexPair<TG,TL>& b)
00633   {
00634     return a.global_>=b.global_;
00635   }
00636   
00637   template<class TG, class TL>
00638   inline bool operator==(const IndexPair<TG,TL>& a, const TG& b)
00639   {
00640     return a.global_==b;
00641   }
00642 
00643   template<class TG, class TL>
00644   inline bool operator!=(const IndexPair<TG,TL>& a, const TG& b)
00645   {
00646     return a.global_!=b;
00647   }
00648     
00649   template<class TG, class TL>
00650   inline bool operator<(const IndexPair<TG,TL>& a, const TG& b)
00651   {
00652     return a.global_<b;
00653   }
00654 
00655   template<class TG, class TL>
00656   inline bool operator>(const IndexPair<TG,TL>& a, const TG& b)
00657   {
00658     return a.global_>b;
00659   }
00660 
00661   template<class TG, class TL>
00662   inline bool operator<=(const IndexPair<TG,TL>& a, const TG& b)
00663   {
00664     return a.global_<=b;
00665   }
00666 
00667   template<class TG, class TL>
00668   inline bool operator >=(const IndexPair<TG,TL>& a, const TG& b)
00669   {
00670     return a.global_>=b;
00671   }
00672 
00673   template<class TG, class TL>
00674   IndexPair<TG,TL>::IndexPair(const TG& global, const TL& local)
00675     : global_(global), local_(local){}
00676 
00677   template<class TG, class TL>
00678   IndexPair<TG,TL>::IndexPair(const TG& global)
00679     : global_(global), local_(){}
00680 
00681   template<class TG, class TL>
00682   IndexPair<TG,TL>::IndexPair()
00683     : global_(), local_(){}
00684 
00685   template<class TG, class TL>
00686   inline const TG& IndexPair<TG,TL>::global() const{
00687     return global_;
00688   }
00689 
00690   template<class TG, class TL>
00691   inline TL& IndexPair<TG,TL>::local() {
00692     return local_;
00693   }
00694 
00695   template<class TG, class TL>
00696   inline const TL& IndexPair<TG,TL>::local() const{
00697     return local_;
00698   }
00699 
00700   template<class TG, class TL>
00701   inline void IndexPair<TG,TL>::setLocal(int local){
00702     local_=local;
00703   }
00704 
00705   template<class TG, class TL, int N>
00706   ParallelIndexSet<TG,TL,N>::ParallelIndexSet()
00707     : state_(GROUND), seqNo_(0)
00708   {}
00709 
00710   template<class TG, class TL, int N>
00711   void ParallelIndexSet<TG,TL,N>::beginResize() throw(InvalidIndexSetState)
00712   {
00713 
00714     // Checks in unproductive code
00715 #ifndef NDEBUG
00716     if(state_!=GROUND)
00717       DUNE_THROW(InvalidIndexSetState, 
00718                  "IndexSet has to be in GROUND state, when "
00719                  << "beginResize() is called!");
00720 #endif
00721         
00722     state_ = RESIZE;
00723     deletedEntries_ = false;
00724   }
00725 
00726   template<class TG, class TL, int N>
00727   inline void ParallelIndexSet<TG,TL,N>::add(const GlobalIndex& global) 
00728     throw(InvalidIndexSetState)
00729   {
00730     // Checks in unproductive code
00731 #ifndef NDEBUG
00732     if(state_ != RESIZE)
00733       DUNE_THROW(InvalidIndexSetState, "Indices can only be added "
00734                  <<"while in RESIZE state!");
00735 #endif
00736     newIndices_.push_back(IndexPair(global));
00737   }
00738 
00739   template<class TG, class TL, int N>
00740   inline void ParallelIndexSet<TG,TL,N>::add(const TG& global, const TL& local) 
00741     throw(InvalidIndexSetState)
00742   {
00743     // Checks in unproductive code
00744 #ifndef NDEBUG
00745     if(state_ != RESIZE)
00746       DUNE_THROW(InvalidIndexSetState, "Indices can only be added "
00747                  <<"while in RESIZE state!");
00748 #endif
00749     newIndices_.push_back(IndexPair(global,local));
00750   }
00751 
00752   template<class TG, class TL, int N>
00753   inline void ParallelIndexSet<TG,TL,N>::markAsDeleted(const iterator& global)
00754     throw(InvalidIndexSetState){
00755     // Checks in unproductive code    
00756 #ifndef NDEBUG
00757     if(state_ != RESIZE)
00758       DUNE_THROW(InvalidIndexSetState, "Indices can only be removed "
00759                  <<"while in RESIZE state!");
00760 #endif    
00761     deletedEntries_ = true;
00762 
00763     global.markAsDeleted();
00764   }
00765 
00766   template<class TG, class TL, int N>
00767   void ParallelIndexSet<TG,TL,N>::endResize() throw(InvalidIndexSetState){
00768     // Checks in unproductive code
00769 #ifndef NDEBUG
00770     if(state_ != RESIZE)
00771       DUNE_THROW(InvalidIndexSetState, "endResize called while not "
00772                  <<"in RESIZE state!");
00773 #endif
00774         
00775     std::sort(newIndices_.begin(), newIndices_.end());
00776     merge();
00777     seqNo_++;
00778     state_ = GROUND;
00779   }
00780 
00781   
00782   template<class TG, class TL, int N>
00783   inline void ParallelIndexSet<TG,TL,N>::merge(){
00784     if(localIndices_.size()==0)
00785       {
00786         localIndices_=newIndices_;
00787         newIndices_.clear();
00788       }
00789     else if(newIndices_.size()>0 || deletedEntries_)
00790       {
00791         ArrayList<IndexPair,N> tempPairs;
00792         typedef typename ArrayList<IndexPair,N>::iterator iterator;
00793         typedef typename ArrayList<IndexPair,N>::const_iterator const_iterator;
00794         
00795         iterator old=localIndices_.begin();
00796         iterator added=newIndices_.begin();
00797         const const_iterator endold=localIndices_.end();
00798         const const_iterator endadded=newIndices_.end();
00799                 
00800         while(old != endold && added!= endadded)
00801           {
00802             if(old->local().state()==DELETED){
00803               old.eraseToHere();
00804             }
00805             else if(old->global() < added->global())
00806               {
00807                 tempPairs.push_back(*old);
00808                 old.eraseToHere();
00809               }
00810             else if(old->global() == added->global()){
00811               // Indices have to be the same
00812               assert(old->local()==added->local());
00813               old.eraseToHere();
00814             }
00815             else
00816               {
00817                 tempPairs.push_back(*added);
00818                 added.eraseToHere();
00819               }
00820           }
00821 
00822         while(old != endold)
00823           {
00824             if(old->local().state()!=DELETED){
00825               tempPairs.push_back(*old);
00826             }
00827             old.eraseToHere();
00828           }
00829 
00830         while(added!= endadded)
00831           {
00832             tempPairs.push_back(*added);
00833             added.eraseToHere();
00834           }
00835         localIndices_ = tempPairs;
00836       }
00837   }
00838 
00839 
00840   template<class TG, class TL, int N>
00841   inline const IndexPair<TG,TL>& 
00842   ParallelIndexSet<TG,TL,N>::operator[](const TG& global) const
00843   {
00844     // perform a binary search
00845     int low=0, high=localIndices_.size()-1, probe=-1;
00846 
00847     while(low<high)
00848       {
00849         probe = (high + low) / 2;
00850         if(global <= localIndices_[probe].global())
00851           high = probe;
00852         else
00853           low = probe+1;
00854       }
00855 
00856 #ifdef DUNE_ISTL_WITH_CHECKING
00857     if(probe==-1)
00858       DUNE_THROW(RangeError, "No entries!");
00859 
00860     if( localIndices_[low].global() != global)
00861       DUNE_THROW(RangeError, "Could not find entry of "<<global);
00862     else
00863 #endif
00864       return localIndices_[low];
00865   }
00866 
00867 
00868   template<class TG, class TL, int N>
00869   inline IndexPair<TG,TL>& ParallelIndexSet<TG,TL,N>::operator[](const TG& global)
00870   {
00871     // perform a binary search
00872     int low=0, high=localIndices_.size()-1, probe=-1;
00873 
00874     while(low<high)
00875       {
00876         probe = (high + low) / 2;
00877         if(localIndices_[probe].global() >= global)
00878           high = probe;
00879         else
00880           low = probe+1;
00881       }
00882 
00883 #ifdef DUNE_ISTL_WITH_CHECKING
00884     if(probe==-1)
00885       DUNE_THROW(RangeError, "No entries!");
00886 
00887     if( localIndices_[low].global() != global)
00888       DUNE_THROW(RangeError, "Could not find entry of "<<global);
00889     else
00890 #endif
00891       return localIndices_[low];
00892   }
00893 
00894   template<class TG, class TL, int N>
00895   inline typename ParallelIndexSet<TG,TL,N>::iterator
00896   ParallelIndexSet<TG,TL,N>::begin()
00897   {
00898     return iterator(*this, localIndices_.begin());
00899   }
00900 
00901     
00902   template<class TG, class TL, int N>
00903   inline typename ParallelIndexSet<TG,TL,N>::iterator 
00904   ParallelIndexSet<TG,TL,N>::end()
00905   {
00906     return iterator(*this,localIndices_.end());
00907   }
00908 
00909   template<class TG, class TL, int N>
00910   inline typename ParallelIndexSet<TG,TL,N>::const_iterator 
00911   ParallelIndexSet<TG,TL,N>::begin() const
00912   {
00913     return localIndices_.begin();
00914   }
00915 
00916     
00917   template<class TG, class TL, int N>
00918   inline typename ParallelIndexSet<TG,TL,N>::const_iterator 
00919   ParallelIndexSet<TG,TL,N>::end() const
00920   {
00921     return localIndices_.end();
00922   }
00923 
00924   template<class TG, class TL, int N>
00925   void ParallelIndexSet<TG,TL,N>::renumberLocal(){
00926 #ifndef NDEBUG
00927     if(state_==RESIZE)
00928       DUNE_THROW(InvalidIndexSetState, "IndexSet has to be in "
00929                  <<"GROUND state for renumberLocal()");
00930 #endif
00931 
00932     typedef typename ArrayList<IndexPair,N>::iterator iterator;
00933     const const_iterator end_ = end();
00934     uint32_t index=0;
00935 
00936     for(iterator pair=begin(); pair!=end_; index++, ++pair)
00937       pair->local()=index;
00938   }
00939 
00940   template<class TG, class TL, int N>
00941   inline int ParallelIndexSet<TG,TL,N>::seqNo() const
00942   {
00943     return seqNo_;
00944   }
00945 
00946   template<class TG, class TL, int N>
00947   inline size_t ParallelIndexSet<TG,TL,N>::size() const
00948   {
00949     return localIndices_.size();
00950   }
00951 
00952   template<class I>
00953   GlobalLookupIndexSet<I>::GlobalLookupIndexSet(const I& indexset,
00954                                                 std::size_t size)
00955     : indexSet_(indexset), size_(size), 
00956       indices_(size_, static_cast<const IndexPair*>(0))
00957   {
00958     assert(size>=indexset.size());
00959     const_iterator end_ = indexSet_.end();
00960 
00961     for(const_iterator pair = indexSet_.begin(); pair!=end_; ++pair){
00962       assert(pair->local()<size_);
00963       indices_[pair->local()] = &(*pair);
00964     }
00965   }
00966 
00967    template<class I>
00968   GlobalLookupIndexSet<I>::GlobalLookupIndexSet(const I& indexset)
00969     : indexSet_(indexset)
00970   {
00971     const_iterator end_ = indexSet_.end();
00972     size_t size=0;
00973     for(const_iterator pair = indexSet_.begin(); pair!=end_; ++pair)
00974       size_=std::max(size_,static_cast<std::size_t>(pair->local()));
00975     
00976     indices_.resize(++size_);
00977     
00978     for(const_iterator pair = indexSet_.begin(); pair!=end_; ++pair)
00979       indices_[pair->local()] = &(*pair);
00980   }
00981 
00982   template<class I>
00983   GlobalLookupIndexSet<I>::~GlobalLookupIndexSet()
00984   {}
00985   
00986 
00987   template<class I>
00988   inline const IndexPair<typename I::GlobalIndex, typename I::LocalIndex>*
00989   GlobalLookupIndexSet<I>::pair(const std::size_t& local) const
00990   {
00991     return indices_[local];
00992   }
00993   
00994   template<class I>
00995   inline const IndexPair<typename I::GlobalIndex, typename I::LocalIndex>&
00996   GlobalLookupIndexSet<I>::operator[](const GlobalIndex& global) const
00997   {
00998     return indexSet_[global];
00999   }
01000   
01001   template<class I>
01002   typename I::const_iterator GlobalLookupIndexSet<I>::begin() const
01003   {
01004     return indexSet_.begin();
01005   }
01006  
01007   template<class I>
01008   typename I::const_iterator GlobalLookupIndexSet<I>::end() const
01009   {
01010     return indexSet_.end();
01011   }
01012 
01013   template<class I>
01014   inline size_t GlobalLookupIndexSet<I>::size() const
01015   {
01016     return size_;
01017   }
01018   
01019   template<class I>
01020   inline int GlobalLookupIndexSet<I>::seqNo() const
01021   {
01022     return indexSet_.seqNo();
01023   }
01024 }
01025 #endif 

Generated on Tue Jul 28 22:29:13 2009 for dune-istl by  doxygen 1.5.6