indexset.hh

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

Generated on Sun Nov 15 22:29:36 2009 for dune-istl by  doxygen 1.5.6