Dune Core Modules (2.9.0)

superentityiterator.hh
1#ifndef DUNE_SPGRID_SUPERENTITYITERATOR_HH
2#define DUNE_SPGRID_SUPERENTITYITERATOR_HH
3
4#include <type_traits>
5
7
8#include <dune/grid/spgrid/direction.hh>
9#include <dune/grid/spgrid/entity.hh>
10#include <dune/grid/spgrid/referencecube.hh>
11
12namespace Dune
13{
14
15 // SPSuperEntityIterator
16 // ---------------------
17
18 template< class Grid >
19 class SPSuperEntityIterator
20 {
21 typedef SPSuperEntityIterator< Grid > This;
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:
33 typedef SPEntity< codimension, dimension, Grid > EntityImpl;
34
35 public:
36 typedef typename EntityImpl::EntityInfo EntityInfo;
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 >
134 struct SPSuperEntityIterator< Grid >::SequenceProvider
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
interface classes for superentity iterators
constexpr auto equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:402
EnableIfInterOperable< T1, T2, bool >::type operator==(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for equality.
Definition: iteratorfacades.hh:237
EnableIfInterOperable< T1, T2, bool >::type operator!=(const ForwardIteratorFacade< T1, V1, R1, D > &lhs, const ForwardIteratorFacade< T2, V2, R2, D > &rhs)
Checks for inequality.
Definition: iteratorfacades.hh:259
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)