dune-foamgrid  2.8-git
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 
16 namespace Dune {
17 
26 template<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
54  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
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
102  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
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 
126 public:
127 
128  typedef Dune::Intersection<const GridImp, typename Dune::FoamGridLeafIntersection<GridImp> > Intersection;
129 
132  return intersection_.impl().equals(other.intersection_.impl());
133  }
134 
136  void increment()
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
158  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
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.
175  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
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.
192  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
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
216  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
217  }
218  }
219 
220 
222  const Intersection & dereference() const {
223  return intersection_;
224  }
225 
226 private:
227  Intersection intersection_;
229  std::shared_ptr<ElementVector> leafNeighbors_;
230  ElementVectorIterator leafNeighborIterator_;
231 };
232 
233 
234 
235 
237 template<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
264  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
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
305  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
306  }
307 
308  }
309 
311  FoamGridLevelIntersectionIterator(const FoamGridEntityImp<dimgrid, dimgrid, dimworld, ctype>* center)
312  : intersection_(FoamGridLevelIntersection<GridImp>(center,center->corners()))
313  {
314  }
315 
316 public:
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
346  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
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
399  intersection_.impl().neighbor_=FoamGridNullIteratorFactory<dimgrid, dimworld, ctype>::null();
400  }
401  }
402 
403 
405  const Intersection & dereference() const
406  {
407  return intersection_;
408  }
409 private:
411  Intersection intersection_;
412 };
413 
414 
415 } // namespace Dune
416 
417 #endif
The FoamGridEntity class.
The FoamGridLeafIntersection and FoamGridLevelIntersection classes.
The null iterator factory for intersections.
Definition: dgffoam.cc:6
Element specialization of FoamGridEntityImp. Element is a grid entity of topological codimension 0 an...
Definition: foamgridelements.hh:18
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< const FoamGridEntityImp< dimgrid, dimgrid, dimworld, ctype > * >::const_iterator null()
Definition: foamgridnulliteratorfactory.hh:18