dune-spgrid  2.7
spgrid/superentityiterator.hh
Go to the documentation of this file.
1 #ifndef DUNE_SPGRID_SUPERENTITYITERATOR_HH
2 #define DUNE_SPGRID_SUPERENTITYITERATOR_HH
3 
4 #include <type_traits>
5 
7 
11 
12 namespace Dune
13 {
14 
15  // SPSuperEntityIterator
16  // ---------------------
17 
18  template< class Grid >
20  {
22 
23  public:
24  typedef typename std::remove_const< Grid >::type::Traits Traits;
25 
26  static const int dimension = Traits::ReferenceCube::dimension;
27  static const int codimension = 0;
28  static const int mydimension = dimension - codimension;
29 
30  typedef typename Traits::template Codim< codimension >::Entity Entity;
31 
32  private:
34 
35  public:
37  typedef typename EntityImpl::GridLevel GridLevel;
38 
39  struct Begin {};
40  struct End {};
41 
42  private:
43  typedef typename EntityInfo::MultiIndex MultiIndex;
44 
45  struct Sequence
46  {
47  const Sequence *next;
48  MultiIndex idAdd;
49  int index;
50  unsigned int fBoundary;
51  };
52 
53  struct SequenceProvider;
54 
55  public:
56  SPSuperEntityIterator () = default;
57 
58  template< class SubInfo, class BeginEnd >
59  SPSuperEntityIterator ( const SubInfo &subInfo, const BeginEnd &be )
60  : entityInfo_( subInfo.gridLevel() ),
61  fBoundary_( 0 )
62  {
63  sequence_ = SequenceProvider::sequence( subInfo.direction().bits(), be );
64 
65  MultiIndex &id = entityInfo().id();
66 
67  id = subInfo.id();
68  const typename GridLevel::Mesh &globalMesh = entityInfo().gridLevel().globalMesh();
69  for( int i = 0; i < dimension; ++i )
70  {
71  const bool bndLow = (id[ i ] == 2*globalMesh.begin()[ i ]);
72  const bool bndHigh = (id[ i ] == 2*globalMesh.end()[ i ]);
73  fBoundary_ |= (int( bndLow ) | 2*int( bndHigh )) << (2*i);
74  }
75 
76  if( next( id ) )
77  entityInfo().update( subInfo.partitionNumber() );
78  }
79 
80  SPSuperEntityIterator ( const This & ) = default;
81  SPSuperEntityIterator ( This && ) = default;
82 
83  This &operator= ( const This & ) = default;
84  This &operator= ( This && ) = default;
85 
86  Entity operator* () const { return dereference(); }
87 
88  bool operator== ( const This &other ) const { return equals( other ); }
89  bool operator!= ( const This &other ) const { return !equals( other ); }
90 
91  Entity dereference () const { return EntityImpl( entityInfo() ); }
92 
93  bool equals ( const This &other ) const { return entityInfo().equals( other.entityInfo() ); }
94 
95  void increment ()
96  {
97  if( next( entityInfo().id() ) )
98  entityInfo().update();
99  }
100 
101  int index () const { return index_; }
102 
103  const EntityInfo &entityInfo () const { return entityInfo_; }
104  EntityInfo &entityInfo () { return entityInfo_; }
105 
106  const GridLevel &gridLevel () const { return entityInfo().gridLevel(); }
107 
108  private:
109  bool next ( MultiIndex &id )
110  {
111  bool skip;
112  do {
113  assert( sequence_ != 0 );
114  id += sequence_->idAdd;
115  index_ = sequence_->index;
116  skip = ((fBoundary_ & sequence_->fBoundary) != 0);
117  sequence_ = sequence_->next;
118  } while( skip );
119  return (sequence_ != 0);
120  }
121 
122  EntityInfo entityInfo_;
123  const Sequence *sequence_;
124  int index_;
125  unsigned int fBoundary_;
126  };
127 
128 
129 
130  // SPSuperEntityIterator::SequenceProvider
131  // ---------------------------------------
132 
133  template< class Grid >
135  {
136  static const unsigned int numDirections = 1 << dimension;
137 
138  static const Sequence *
139  sequence ( const unsigned int direction, const Begin &b )
140  {
141  assert( direction < numDirections );
142  return instance().begin_[ direction ];
143  }
144 
145  static const Sequence *
146  sequence ( const unsigned int direction, const End &e )
147  {
148  assert( direction < numDirections );
149  return instance().end_[ direction ];
150  }
151 
152  private:
153  SequenceProvider ();
154  ~SequenceProvider ();
155 
156  static const SequenceProvider &instance ()
157  {
158  static SequenceProvider instance;
159  return instance;
160  }
161 
162  const Sequence *begin_[ numDirections ];
163  const Sequence *end_[ numDirections ];
164  };
165 
166 
167 
168  template< class Grid >
169  SPSuperEntityIterator< Grid >::SequenceProvider::SequenceProvider ()
170  {
171  SPReferenceCube< typename Grid::ctype, dimension > refCube;
172 
173  for( unsigned int dir = 0; dir < numDirections; ++dir )
174  {
175  const int codim = SPDirection< dimension >( dir ).codimension();
176 
177  Sequence *head = new Sequence;
178 
179  Sequence *last = head;
180  head->idAdd.clear();
181  for( unsigned int d = 0; d < numDirections; ++d )
182  {
183  if( (d & dir) != 0 )
184  continue;
185 
186  Sequence *next = new Sequence;
187  next->fBoundary = 0;
188  for( int i = 0; i < dimension; ++i )
189  {
190  const int dirbit = int( (dir >> i) & 1);
191  const int dbit = int( (d >> i) & 1 );
192  next->idAdd[ i ] = (1 - dirbit) * (2*dbit - 1);
193  next->fBoundary |= (1 - dirbit) * (1 << (2*i + dbit));
194  }
195  next->index = -1;
196  for( int k = 0; k < refCube.count( codim ); ++k )
197  {
198  const MultiIndex &subId = refCube.subId( codim, k );
199  bool found = true;
200  for( int i = 0; i < dimension; ++i )
201  found &= (next->idAdd[ i ] == -subId[ i ]);
202  if( found )
203  next->index = k;
204  }
205  assert( next->index != -1 );
206  next->idAdd -= head->idAdd;
207  head->idAdd += next->idAdd;
208 
209  last->next = next;
210  last = next;
211  }
212  begin_[ dir ] = head->next;
213 
214  Sequence *end = new Sequence;
215  end->next = 0;
216  end->index = -1;
217  end->fBoundary = 0;
218  for( int i = 0; i < dimension; ++i )
219  end->idAdd[ i ] = 3 * (1 - int( (dir >> i) & 1 ));
220  end_[ dir ] = end;
221 
222  head->next = 0;
223  head->index = end->index;
224  head->fBoundary = end->fBoundary;
225  head->idAdd -= end->idAdd;
226  head->idAdd *= -1;
227  last->next = head;
228  }
229  }
230 
231 
232  template< class Grid >
233  SPSuperEntityIterator< Grid >::SequenceProvider::~SequenceProvider ()
234  {
235  for( unsigned int dir = 0; dir < (1 << dimension); ++dir )
236  {
237  delete end_[ dir ];
238  while( begin_[ dir ] != 0 )
239  {
240  const Sequence *tmp = begin_[ dir ];
241  begin_[ dir ] = begin_[ dir ]->next;
242  delete tmp;
243  }
244  }
245  }
246 
247 } // namespace Dune
248 
249 #endif // #ifndef DUNE_SPGRID_SUPERENTITYITERATOR_HH
Definition: iostream.hh:7
Definition: entity.hh:146
Definition: entityinfo.hh:24
const GridLevel & gridLevel() const
Definition: entityinfo.hh:66
void update()
Definition: entityinfo.hh:122
const MultiIndex & id() const
Definition: entityinfo.hh:68
bool equals(const This &other) const
Definition: entityinfo.hh:77
Definition: gridlevel.hh:35
const Mesh & globalMesh() const
Definition: gridlevel.hh:210
const MultiIndex & end() const
Definition: mesh.hh:37
const MultiIndex & begin() const
Definition: mesh.hh:36
Definition: spgrid/superentityiterator.hh:20
SPSuperEntityIterator(const SubInfo &subInfo, const BeginEnd &be)
Definition: spgrid/superentityiterator.hh:59
bool operator!=(const This &other) const
Definition: spgrid/superentityiterator.hh:89
EntityInfo & entityInfo()
Definition: spgrid/superentityiterator.hh:104
Entity operator*() const
Definition: spgrid/superentityiterator.hh:86
Entity dereference() const
Definition: spgrid/superentityiterator.hh:91
EntityImpl::EntityInfo EntityInfo
Definition: spgrid/superentityiterator.hh:36
SPSuperEntityIterator(This &&)=default
bool operator==(const This &other) const
Definition: spgrid/superentityiterator.hh:88
static const int dimension
Definition: spgrid/superentityiterator.hh:26
SPSuperEntityIterator(const This &)=default
This & operator=(const This &)=default
int index() const
Definition: spgrid/superentityiterator.hh:101
EntityImpl::GridLevel GridLevel
Definition: spgrid/superentityiterator.hh:37
const GridLevel & gridLevel() const
Definition: spgrid/superentityiterator.hh:106
void increment()
Definition: spgrid/superentityiterator.hh:95
Traits::template Codim< codimension >::Entity Entity
Definition: spgrid/superentityiterator.hh:30
const EntityInfo & entityInfo() const
Definition: spgrid/superentityiterator.hh:103
std::remove_const< Grid >::type::Traits Traits
Definition: spgrid/superentityiterator.hh:24
static const int mydimension
Definition: spgrid/superentityiterator.hh:28
bool equals(const This &other) const
Definition: spgrid/superentityiterator.hh:93
static const int codimension
Definition: spgrid/superentityiterator.hh:27
Definition: spgrid/superentityiterator.hh:39
Definition: spgrid/superentityiterator.hh:40
Definition: spgrid/superentityiterator.hh:135
static const Sequence * sequence(const unsigned int direction, const Begin &b)
Definition: spgrid/superentityiterator.hh:139
static const Sequence * sequence(const unsigned int direction, const End &e)
Definition: spgrid/superentityiterator.hh:146
static const unsigned int numDirections
Definition: spgrid/superentityiterator.hh:136
interface classes for superentity iterators