00001
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>
00013
00014 namespace Dune
00015 {
00025
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
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
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
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
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
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
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
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
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
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
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