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
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
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
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
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
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
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
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
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
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