dune-foamgrid 2.8.0
Loading...
Searching...
No Matches
foamgridintersectioniterators.hh
Go to the documentation of this file.
1// -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set ts=8 sw=4 et sts=4:
3#ifndef DUNE_FOAMGRID_INTERSECTIONITERATORS_HH
4#define DUNE_FOAMGRID_INTERSECTIONITERATORS_HH
5
6#include <memory>
11
16namespace Dune {
17
26template<class GridImp>
28{
29
30 enum {dimworld = GridImp::dimensionworld};
31 enum {dimgrid = GridImp::dimension};
32
33 typedef typename GridImp::ctype ctype;
34
35 typedef std::vector<typename std::vector<const FoamGridEntityImp<dimgrid, dimgrid, dimworld, ctype>*>::const_iterator> ElementVector;
36 typedef typename ElementVector::const_iterator ElementVectorIterator;
37
38 // Only the codim-0 entity is allowed to call the constructors
39 friend class FoamGridEntity<0,dimgrid,GridImp>;
40
41 template<typename, typename, typename>
42 friend class Dune::IntersectionIterator;
43
45 {}
46
49 : intersection_(FoamGridLeafIntersection<GridImp>(center,facet)), leafNeighbors_(std::make_shared<ElementVector>())
50 {
51 if(facet==center->corners())
52 {
53 // This is the end iterator
55 return;
56 }
57
58 pushBackLeafNeighbours_(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_], leafNeighbors_);
59 if(leafNeighbors_->size()==1)
60 {
61 // This is a boundary facet.
62 intersection_.impl().neighbor_ = FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
63 return;
64 }
65
66 // Search for the first intersection
67 while(intersection_.impl().facetIndex_ != center->corners()) // not an end iterator
68 {
69 leafNeighborIterator_ = leafNeighbors_->begin();
70 intersection_.impl().neighbor_=*leafNeighborIterator_;
71 while(leafNeighborIterator_!=leafNeighbors_->end() &&
72 intersection_.impl().center_==**leafNeighborIterator_)
73 {
74 ++leafNeighborIterator_;
75 if(leafNeighborIterator_ != leafNeighbors_->end())
76 intersection_.impl().neighbor_=*leafNeighborIterator_;
77 }
78 if(leafNeighborIterator_==leafNeighbors_->end())
79 {
80 if(leafNeighbors_->size()==1)
81 {
82 // This is a boundary intersection.
83 return;
84 }else
85 {
86 // No valid intersection found on this facet, move to next one.
87 ++intersection_.impl().facetIndex_;
88 if(intersection_.impl().facetIndex_ != center->corners())
89 {
90 leafNeighbors_->clear();
91 pushBackLeafNeighbours_(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_], leafNeighbors_);
92 }
93 }
94 }else
95 // intersection with another element found!
96 break;
97 }
98
99 if(intersection_.impl().facetIndex_ == center->corners())
100 {
101 // This is an end iterator
103 }
104 }
105
107 FoamGridLeafIntersectionIterator(const FoamGridEntityImp<dimgrid, dimgrid, dimworld, ctype>* center)
108 : intersection_(FoamGridLeafIntersection<GridImp>(center,center->corners()))
109 {
110 }
111
113 void pushBackLeafNeighbours_(const FoamGridEntityImp<dimgrid-1, dimgrid, dimworld, ctype>* facet, std::shared_ptr<ElementVector> leafNeighbours)
114 {
115 if (facet->isLeaf())
116 for(auto it = facet->elements_.begin(); it != facet->elements_.end(); ++it)
117 leafNeighbours->push_back(it);
118 else
119 {
120 // do it recursively until the leaf level
121 for(auto&& son : facet->sons_)
122 pushBackLeafNeighbours_(son, leafNeighbours);
123 }
124 }
125
126public:
127
128 typedef Dune::Intersection<const GridImp, typename Dune::FoamGridLeafIntersection<GridImp> > Intersection;
129
132 return intersection_.impl().equals(other.intersection_.impl());
133 }
134
137 {
138 if(intersection_.impl().facetIndex_ == intersection_.impl().center_->corners())
139 {
140 // This is already the end iterator
141 DUNE_THROW(InvalidStateException, "Cannot increment a one past the end iterator");
142 return;
143 }
144 if(leafNeighbors_->size()==1)
145 {
146 // This was a boundary intersection go to the next facet
147 ++intersection_.impl().facetIndex_;
148 if(intersection_.impl().facetIndex_ < intersection_.impl().center_->corners()){
149 // There is another facet, initialize neighbor_ iterator.
150 leafNeighbors_->clear();
151 pushBackLeafNeighbours_(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_], leafNeighbors_);
152 leafNeighborIterator_ = leafNeighbors_->begin();
153 intersection_.impl().neighbor_=*leafNeighborIterator_;
154 }
155 else
156 {
157 // This is the end iterator
159 return;
160 }
161 }else
162 {
163 // Move to the next intersection of this facet
164 ++leafNeighborIterator_;
165 if(leafNeighborIterator_ != leafNeighbors_->end())
166 intersection_.impl().neighbor_=*leafNeighborIterator_;
167 }
168
169 // Search for the first intersection with a neighbor
170 while(intersection_.impl().facetIndex_ != intersection_.impl().center_->corners()) // still a valid facet
171 {
172 if(leafNeighbors_->size()==1)
173 {
174 // This is a boundary intersection.
176 return;
177 }
178
179 while(leafNeighborIterator_ != leafNeighbors_->end() &&
180 intersection_.impl().center_==**leafNeighborIterator_)
181 {
182 // Wrong level or neighbor points to center. In both cases this intersection is invalid.
183 ++leafNeighborIterator_;
184 if(leafNeighborIterator_ != leafNeighbors_->end())
185 intersection_.impl().neighbor_=*leafNeighborIterator_;
186 }
187 if(leafNeighborIterator_==leafNeighbors_->end())
188 {
189 if(leafNeighbors_->size()==1)
190 {
191 // This is a boundary intersection.
193 return;
194 }
195 else
196 {
197 // No valid intersection found on this facet, move to next facet.
198 ++intersection_.impl().facetIndex_;
199 if(intersection_.impl().facetIndex_ < intersection_.impl().center_->corners())
200 {
201 leafNeighbors_->clear();
202 pushBackLeafNeighbours_(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_], leafNeighbors_);
203 // There is another facet, initialize neighbor_ iterator.
204 leafNeighborIterator_ = leafNeighbors_->begin();
205 intersection_.impl().neighbor_=*leafNeighborIterator_;
206 }
207 }
208 }else
209 // intersection with another element found!
210 break;
211 }
212
213 if(intersection_.impl().facetIndex_ == intersection_.impl().center_->corners())
214 {
215 // This is an end iterator
217 }
218 }
219
220
222 const Intersection & dereference() const {
223 return intersection_;
224 }
225
226private:
227 Intersection intersection_;
229 std::shared_ptr<ElementVector> leafNeighbors_;
230 ElementVectorIterator leafNeighborIterator_;
231};
232
233
234
235
237template<class GridImp>
239{
240
241 enum { dimgrid = GridImp::dimension };
242 enum { dimworld = GridImp::dimensionworld };
243
244 typedef typename GridImp::ctype ctype;
245
246 // Only the codim-0 entity is allowed to call the constructors
247 friend class FoamGridEntity<0, dimgrid, GridImp>;
248
249 template<typename, typename, typename>
250 friend class Dune::IntersectionIterator;
251
253 {}
254
259 : intersection_(FoamGridLevelIntersection<GridImp>(center,facet))
260 {
261 if(facet==center->corners())
262 {
263 // This is the end iterator
265 return;
266 }
267
268 if(center->facet_[intersection_.impl().facetIndex_]->elements_.size()==1)
269 {
270 // This is a boundary facet.
271 intersection_.impl().neighbor_ =
272 intersection_.impl().neighborEnd_=
273 intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.end();
274 return;
275 }
276
277 // Search for the first intersection with a same level neighbor
278 while(intersection_.impl().facetIndex_ != center->corners()) // not an end iterator
279 {
280 intersection_.impl().neighbor_=intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.begin();
281 intersection_.impl().neighborEnd_=intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.end();
282 while(intersection_.impl().neighbor_!=intersection_.impl().neighborEnd_ &&
283 (intersection_.impl().center_==*intersection_.impl().neighbor_
284 ||intersection_.impl().center_->level()!=(*intersection_.impl().neighbor_)->level()))
285 {
286 ++intersection_.impl().neighbor_;
287 }
288 if(intersection_.impl().neighbor_==intersection_.impl().neighborEnd_)
289 {
290 if(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.size()==1)
291 {
292 // This is a boundary intersection.
293 return;
294 }else
295 // No valid intersection found on this facet, move to next one.
296 ++intersection_.impl().facetIndex_;
297 }else
298 // intersection with another element found!
299 break;
300 }
301
302 if(intersection_.impl().facetIndex_ == center->corners())
303 {
304 // This is an end iterator
306 }
307
308 }
309
311 FoamGridLevelIntersectionIterator(const FoamGridEntityImp<dimgrid, dimgrid, dimworld, ctype>* center)
312 : intersection_(FoamGridLevelIntersection<GridImp>(center,center->corners()))
313 {
314 }
315
316public:
317
318 typedef Dune::Intersection<const GridImp, typename Dune::FoamGridLevelIntersection<GridImp> > Intersection;
319
322 return intersection_.impl().equals(other.intersection_.impl());
323 }
324
326 void increment() {
327 if(intersection_.impl().facetIndex_==
328 intersection_.impl().center_->corners())
329 {
330 // This is already the end iterator
331 DUNE_THROW(InvalidStateException, "Cannot increment a one past the end iterator");
332 return;
333 }
334 if(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.size()==1)
335 {
336 // This was a boundary intersection.
337 ++intersection_.impl().facetIndex_;
338 if(intersection_.impl().facetIndex_ < intersection_.impl().center_->corners()){
339 // There is another facet, initialize neighbor_ iterator.
340 intersection_.impl().neighbor_=intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.begin();
341 intersection_.impl().neighborEnd_=intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.end();;
342 }
343 else
344 {
345 // This is the end iterator
347 return;
348 }
349 }else
350 {
351 // Move to the next intersection of this facet
352 ++intersection_.impl().neighbor_;
353 }
354
355 // Search for the first intersection with a same level neighbor
356 while(intersection_.impl().facetIndex_ != intersection_.impl().center_->corners()) // still a valid facet
357 {
358 if(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.size()==1)
359 {
360 // This is a boundary intersection.
361 intersection_.impl().neighbor_=intersection_.impl().neighborEnd_;
362 return;
363 }
364
365 while(intersection_.impl().neighbor_!=intersection_.impl().neighborEnd_ &&
366 (intersection_.impl().center_==*intersection_.impl().neighbor_
367 ||intersection_.impl().center_->level()!=(*intersection_.impl().neighbor_)->level()))
368 {
369 // Wrong level or neighbor points to center. In both cases this intersection is invalid.
370 ++intersection_.impl().neighbor_;
371 }
372 if(intersection_.impl().neighbor_==
373 intersection_.impl().neighborEnd_)
374 {
375 if(intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.size()==1)
376 {
377 // This is a boundary intersection.
378 return;
379 }
380 else
381 {
382 // No valid intersection found on this facet, move to next facet.
383 ++intersection_.impl().facetIndex_;
384 if(intersection_.impl().facetIndex_ < intersection_.impl().center_->corners())
385 {
386 // There is another facet, initialize neighbor_ iterator.
387 intersection_.impl().neighbor_=intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.begin();
388 intersection_.impl().neighborEnd_=intersection_.impl().center_->facet_[intersection_.impl().facetIndex_]->elements_.end();
389 }
390 }
391 }else
392 // intersection with another element found!
393 break;
394 }
395
396 if(intersection_.impl().facetIndex_ == intersection_.impl().center_->corners())
397 {
398 // This is an end iterator
400 }
401 }
402
403
405 const Intersection & dereference() const
406 {
407 return intersection_;
408 }
409private:
411 Intersection intersection_;
412};
413
414
415} // namespace Dune
416
417#endif
The null iterator factory for intersections.
The FoamGridEntity class.
The FoamGridLeafIntersection and FoamGridLevelIntersection classes.
Definition: dgffoam.cc:6
The implementation of entities in a FoamGrid.
Definition: foamgridentity.hh:54
Definition: foamgridintersectioniterators.hh:239
bool equals(const FoamGridLevelIntersectionIterator< GridImp > &other) const
equality
Definition: foamgridintersectioniterators.hh:321
Dune::Intersection< const GridImp, typename Dune::FoamGridLevelIntersection< GridImp > > Intersection
Definition: foamgridintersectioniterators.hh:318
void increment()
prefix increment
Definition: foamgridintersectioniterators.hh:326
const Intersection & dereference() const
dereferencing
Definition: foamgridintersectioniterators.hh:405
Iterator over all element neighborsMesh entities of codimension 0 ("elements") allow to visit all nei...
Definition: foamgridintersectioniterators.hh:28
Dune::Intersection< const GridImp, typename Dune::FoamGridLeafIntersection< GridImp > > Intersection
Definition: foamgridintersectioniterators.hh:128
void increment()
prefix increment
Definition: foamgridintersectioniterators.hh:136
bool equals(const FoamGridLeafIntersectionIterator< GridImp > &other) const
equality
Definition: foamgridintersectioniterators.hh:131
const Intersection & dereference() const
dereferencing
Definition: foamgridintersectioniterators.hh:222
Definition: foamgridintersections.hh:252
Iterator over all element neighborsMesh entities of codimension 0 ("elements") allow to visit all nei...
Definition: foamgridintersections.hh:386
static std::vector< constFoamGridEntityImp< dimgrid, dimgrid, dimworld, ctype > * >::const_iterator null()
Definition: foamgridnulliteratorfactory.hh:18
The actual entity implementation.
Definition: foamgridvertex.hh:47