1 #ifndef METAGRID_SFCITERATOR_HH
2 #define METAGRID_SFCITERATOR_HH
3 
4 #include <vector>
5 
6 #include <dune/grid/common/capabilities.hh>
7 
8 namespace Dune
9 {
10 
11 // Iterator following the iterator pattern
12 template <class GridView>
13 class SpaceFillingCurveIterator
14 {
15   typedef typename GridView :: template Codim< 0 > :: Iterator      Iterator ;
16   typedef typename GridView :: template Codim< 0 > :: EntityPointer EntityPointer ;
17   typedef typename GridView :: template Codim< 0 > :: Entity        Entity ;
18 
19   typedef typename GridView :: Grid   Grid;
20 
21   static const bool isCartesian = Capabilities :: isCartesian< Grid > :: v;
22 
23   const GridView& gridView_;
24 
25   const Iterator end_;
26   Iterator it_;
27 
28   EntityPointer current_;
29   bool done_;
30 
31   std::vector<int> dir_;
32 
33 public:
34 
SpaceFillingCurveIterator(const GridView & gridView)35   SpaceFillingCurveIterator( const GridView& gridView )
36     : gridView_( gridView ),
37       end_( gridView.template end<0> () ),
38       it_( end_ ),
39       current_( end_ ),
40       done_( true ),
41 	    dir_(GridView::dimension, -1)
42   {}
43 
first()44   void first ()
45   {
46     it_ = gridView_.template begin<0> () ;
47     if( it_ != end_ )
48     {
49       current_ = it_;
50       if( isCartesian )
51       {
52         typedef typename GridView :: IntersectionIterator  IntersectionIterator ;
53         IntersectionIterator endIit = gridView_.iend( *current_ );
54         for( IntersectionIterator iit = gridView_.ibegin( *current_ ); iit != endIit ; ++ iit )
55         {
56           const typename GridView :: Intersection& intersection = *iit ;
57           const int j =intersection.indexInInside();
58           const int i = (j - (j%2) )/2;
59           if ( ! intersection.boundary() )
60           {
61             dir_[ i ] = j;
62           }
63         }
64       }
65       done_ = false;
66     }
67     else
68       done_ = true ;
69   }
70 
next()71   void next()
72   {
73     if( isCartesian )
74     {
75       typedef typename GridView :: IntersectionIterator  IntersectionIterator ;
76       IntersectionIterator endIit = gridView_.iend( *current_ );
77       for( IntersectionIterator iit = gridView_.ibegin( *current_ ); iit != endIit ; ++ iit )
78       {
79         const typename GridView :: Intersection& intersection = *iit ;
80         const int j = intersection.indexInInside();
81         const int i = (j - (j%2) ) /2;
82         if ( dir_[i] == j && intersection.neighbor() && ! intersection.boundary() )
83         {
84           for(int k = 0; k<i; ++k)
85           {
86             dir_[ k ] = (dir_[ k ] == 2*k ) ? 2*k+1 : 2*k ;
87           }
88           current_ = intersection.outside();
89           return;
90         }
91       }
92     }
93     else
94     {
95       ++it_ ;
96       if( it_ != end_ )
97       {
98         current_ = it_;
99         return  ;
100       }
101     }
102 
103     done_ = true;
104   }
105 
item() const106   const Entity& item () const
107   {
108     assert( ! done() );
109     return *current_;
110   }
111 
done() const112   bool done () const { return done_; }
113 };
114 
115 } // end namespace Dune
116 #endif
117 
118 
119