Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
facehierarchy.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
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#ifndef DUNE_FUFEM_FACE_HIERARCHY_HH
8#define DUNE_FUFEM_FACE_HIERARCHY_HH
9
11
13
14
15
16// forward declarations
17template<class GridType> class Face;
18template<class GridType> struct FaceHierarchy;
19template<class GridType> class HierarchicFaceIterator;
20
21
22
26template<class GridType>
28{
29
30 public:
31 typedef typename GridType::template Codim<0>::Entity Element;
32 typedef typename GridType::LevelGridView::Intersection LevelIntersection;
33 typedef typename GridType::LevelGridView::IntersectionIterator LevelIntersectionIterator;
34
35 enum {dim = Element::dimension};
36
37 static bool isSubFace(const Element& father, const int fatherFace, const Element& son, const int sonFace)
38 {
39 typedef typename Element::LocalGeometry::GlobalCoordinate LocalFatherCoordinate;
40
41 auto fatherRefElement = Dune::ReferenceElements<double, dim>::general(father.type());
42 auto sonRefElement = Dune::ReferenceElements<double, dim>::general(son.type());
43
44 LocalFatherCoordinate centerInFather = son.geometryInFather().global(sonRefElement.position(sonFace, 1));
45
46 const auto& mapping = fatherRefElement.template geometry<1>(fatherFace);
47
48 centerInFather -= mapping.global(mapping.local(centerInFather));
49
50 return centerInFather.two_norm2() < 1e-4;
51 }
52
53 static int findSubFace(const Element& father, const int fatherFace, const Element& child)
54 {
55
56 for(unsigned int i=0; i < child.subEntities(1); ++i)
57 if (isSubFace(father, fatherFace, child, i))
58 return i;
59 return -1;
60 }
61
62 static int findFatherFace(const GridType& grid, const Element& element, const int face)
63 {
64 const Element& father = element.father();
65 for(unsigned int i=0; i < father->subEntities(1); ++i)
66 if (isSubFace(father, i, element, face))
67 return i;
68 return -1;
69 }
70
71 static LevelIntersectionIterator findFatherFaceIntersection(const GridType& grid, const Element& element, const int face)
72 {
73 const Element& father = element.father();
74
75 LevelIntersectionIterator nIt = grid.levelGridView(father.level()).ibegin(father);
76 LevelIntersectionIterator nEnd = grid.levelGridView(father.level()).iend(father);
77 for(; nIt != nEnd; ++nIt)
78 {
79 if (isSubFace(father, nIt->indexInInside(), element, face))
80 return nIt;
81 }
82 DUNE_THROW(Dune::Exception, "No father face found!");
83 }
84
85 static Element finestCoarseNeighbor(const GridType& grid, const Element& element, int face)
86 {
87 LevelIntersectionIterator nIt = grid.levelGridView(element.level()).ibegin(element);
88 LevelIntersectionIterator nEnd = grid.levelGridView(element.level()).iend(element);
89 for(; nIt != nEnd; ++nIt)
90 {
91 if ((nIt->neighbor()) and (nIt->indexInInside()==face))
92 return nIt->outside();
93 }
94
95 Element checkElement(element);
96 while(checkElement.level()>0)
97 {
98 LevelIntersectionIterator fatherIntersection = findFatherFaceIntersection(grid, checkElement, face);
99 if (fatherIntersection->neighbor())
100 return fatherIntersection->outside();
101 checkElement = checkElement.father();
102 face = fatherIntersection->indexInInside();
103 }
104 return element;
105 }
106
107};
108
109
110
118template<class GridType>
119class Face
120{
121 typedef typename GridType::LevelGridView::IntersectionIterator LevelIntersectionIterator;
122 enum {dim = GridType::dimension};
123
124 public:
125 typedef typename GridType::template Codim<0>::Entity Element;
126 typedef typename GridType::LevelGridView::Intersection Intersection;
127 typedef typename GridType::LevelGridView::IntersectionIterator IntersectionIterator;
130
131 Face(const GridType& grid, const Element &e, int index=-1):
132 grid_(&grid),
133 element_(e),
135 {}
136
137 template<class OtherFace>
138 Face(const OtherFace& other):
139 grid_(&other.grid()),
140 element_(other.element()),
141 index_(other.index())
142 {}
143
146 const Element& element() const
147 {
148 return element_;
149 }
150
153 void setElement(const Element& e)
154 {
155 element_ = e;
156 }
157
160 int index() const
161 {
162 return index_;
163 }
164
167 void setIndex(int i)
168 {
169 index_ = i;
170 }
171
174 int level() const
175 {
176 return element().level();
177 }
178
181 const GridType& grid() const
182 {
183 return *grid_;
184 }
185
188 bool isInitialized() const
189 {
190 return index_>=0;
191 }
192
201
210
218 {
219 FaceType fatherFace(*grid_, element().father());
220 for(int i=0; i < fatherFace.element().subEntities(1); ++i)
221 {
222 if (isSubFace(fatherFace.element(), i, element(), index_))
223 {
224 fatherFace.setIndex(i);
225 return fatherFace;
226 }
227 }
228 return fatherFace;
229 }
230
237 template<class OtherFace>
238 bool isFather(const OtherFace& fatherFace) const
239 {
240 if (not(isInitialized()) or not(fatherFace.isInitialized()))
241 return false;
242 if (fatherFace.element() != *element().father())
243 return false;
244 return FaceHierarchy<GridType>::isSubFace(fatherFace.element(), fatherFace.index(), *element_, index_);
245 }
246
253 template<class OtherFace>
254 bool isChild(const OtherFace& childFace) const
255 {
256 return FaceHierarchy<GridType>::isSubFace(element(), index_, childFace.element(), childFace.index());
257 }
258
262 {
263 LevelIntersectionIterator nIt = grid_->levelGridView(level()).ibegin(element());
264 LevelIntersectionIterator nEnd = grid_->levelGridView(level()).iend(element());
265 for(; nIt != nEnd; ++nIt)
266 {
267 if (nIt->indexInInside()==index_)
268 return nIt;
269 }
270 }
271
278
279#if 0
280 Face<GridType> outside() const
281 {
283 if (i.neighbor())
284 return Face<GridType>(*grid_, i.outside(), i.indexInOutside());
285 return Face<GridType>(*grid_);
286 }
287
288 Face<GridType> coarseNeighbor() const
289 {
290 Face<GridType> result = outside();
291
292 if (result.isInitialized())
293 return result;
294
295 auto checkElement = element_;
296 int checkFace = index_;
297 while(checkElement.level()>0)
298 {
299 Intersection fatherInt = fatherIntersection(*grid_, checkElement, checkFace);
300 if (fatherInt.neighbor())
301 return Face<GridType>(*grid_, fatherInt.outside(), fatherInt.indexInOutside());
302 checkElement = checkElement->father();
303 checkFace = fatherInt.indexInInside();
304 }
305 return Face<GridType>(*grid_);
306 }
307#endif
308
309 protected:
310 const GridType* grid_;
313};
314
335template<class GridType>
337 public Dune::ForwardIteratorFacade< HierarchicFaceIterator<GridType>, const Face<GridType> >
338{
339 enum {dim=GridType::dimension};
340
341 typedef typename GridType::HierarchicIterator HierarchicElementIterator;
342 typedef typename GridType::template Codim<0>::Entity Element;
343
344
345 public:
346
348
351
352 HierarchicFaceIterator(const GridType& grid, const FaceType& fatherFace, const int maxLevel, PositionFlag flag) :
353 grid_(grid),
355 fatherFace_(fatherFace),
356 face_(fatherFace)
357 {
358 if (flag==begin)
359 {
360 stack_.reserve(grid.maxLevel()-fatherFace_.element().level());
362 }
363 }
364
368 {
369 incrementFrom(*stack_.back().it_);
370 }
371
376 bool equals(const HierarchicFaceIterator& other) const
377 {
378 return ((stack_.size() == 0) and (other.stack_.size() == 0));
379 }
380
382 const FaceType& dereference() const
383 {
384 return face_;
385 }
386
389 const Element element() const
390 {
391 return *stack_.back().it_;
392 }
393
396 int index() const
397 {
398 return stack_.back().index_;
399 }
400
401
402 protected:
403
404 // The following methods implement a depth first of
405 // sub faces in all descendant elements as depicted
406 // below:
407 //
408 // *-3-*-4-*-6-*-7-*
409 // *---2---*---5---*
410 // *-------1-------*
411 //
412 // All ancestors are stored in the stack in order
413 // to visit their siblings later on.
414 //
415 // To this end we need to store the triple ChildFaceIterator
416 // containing the element iterator, the face index, and the
417 // end element iterator.
418
419 // increment starting from given element
420 // this is needed since the constructor increments
421 // from the entity pointer in father face and increment()
422 // increments from the current back of the stack
423 void incrementFrom(const Element& e)
424 {
425 // If there are children to consider go up in the tree
426 // and put child iterator on the stack.
427 //
428 // Notice that we only consider children of elements
429 // that contain a subface since the current back of
430 // the stack pointed to such an element.
431 int level = e.level();
432 if ((level < maxLevel_) and not(e.isLeaf()))
433 {
434 stack_.push_back(ChildFaceIterator(e.hbegin(level+1), e.hend(level+1)));
435 if (findChildInBack())
436 return;
437 }
438
439 if (stack_.size() == 0)
440 return;
441
442 // Iterate on current level and go down in the tree
443 // until find a child face or reach the end (=stack is empty)
444 do
445 {
446 ++(stack_.back().it_);
447 while (stack_.back().it_ == stack_.back().end_)
448 {
449 stack_.pop_back();
450 if (stack_.size() == 0)
451 return;
452 ++(stack_.back().it_);
453 }
454 } while(not(findChildInBack()));
455 }
456
457 // find child face in back of stack
458 // and set the corresponding face index
459 // return whether a child face was found
461 {
462 bool found = false;
463 if (stack_.size() == 1)
464 found = stack_.back().selectChildFaceOf(fatherFace_.element(), fatherFace_.index());
465 else if (stack_.size() > 1)
466 found = stack_.back().selectChildFaceOf(*stack_[stack_.size()-2].it_, stack_[stack_.size()-2].index_);
467 if (found)
468 face_ = stack_.back().toFace(grid_);
469 return found;
470 }
471
472 // encapsulate hierarchic iterator, end iterator and face index
474 {
476 const HierarchicElementIterator& it,
477 const HierarchicElementIterator& end,
478 int face = -1) :
479 it_(it),
480 end_(end),
481 index_(face)
482 {}
483
484 FaceType toFace(const GridType& grid) const
485 {
486 return FaceType(grid, *it_, index_);
487 }
488
489 bool selectChildFaceOf(const Element& father, int fatherFace)
490 {
491 index_ = FaceHierarchy<GridType>::findSubFace(father, fatherFace, *it_);
492 return (index_ >= 0);
493 }
494
495 HierarchicElementIterator it_;
496 HierarchicElementIterator end_;
498 };
499
500
501 // guess what
502 const GridType& grid_;
503
504 // maximal level to consider
506
507 // the father face we start from
509
510 // the face the iterator points to
512
513 // a stack of hierarchic iterators with face indices
515};
516
517#endif
int maxLevel() const
#define DUNE_THROW(E,...)
auto outside(const Op &op)
Construct outside version of a given operator.
Definition userfunctions.hh:862
int maxLevel() const
LevelGridView levelGridView(int level) const
Class representing a face.
Definition facehierarchy.hh:120
HierarchicIterator hend(int maxLevel) const
Return end of HierarchicIterator to subfaces.
Definition facehierarchy.hh:206
IntersectionIterator fatherIntersection() const
Return a LevelIntersectionIterator associated with the father face.
Definition facehierarchy.hh:274
Face(const OtherFace &other)
Definition facehierarchy.hh:138
GridType::LevelGridView::Intersection Intersection
Definition facehierarchy.hh:126
HierarchicIterator hbegin(int maxLevel) const
Return HierarchicIterator to subfaces.
Definition facehierarchy.hh:197
IntersectionIterator intersection() const
Return a LevelIntersectionIterator associated with this face.
Definition facehierarchy.hh:261
int level() const
Return level of the face/associated element.
Definition facehierarchy.hh:174
bool isChild(const OtherFace &childFace) const
Check for if given face is child face.
Definition facehierarchy.hh:254
int index_
Definition facehierarchy.hh:312
const Element & element() const
Return the element associated with this face.
Definition facehierarchy.hh:146
void setElement(const Element &e)
Set the element associated with this face.
Definition facehierarchy.hh:153
Face< GridType > FaceType
Definition facehierarchy.hh:129
void setIndex(int i)
Set the index of the codim=1 subentity associated with this face.
Definition facehierarchy.hh:167
const GridType * grid_
Definition facehierarchy.hh:310
const GridType & grid() const
Return reference to the grid the face belongs to.
Definition facehierarchy.hh:181
bool isFather(const OtherFace &fatherFace) const
Check if given face is father face.
Definition facehierarchy.hh:238
int index() const
Return the index of the codim=1 subentity associated with this face.
Definition facehierarchy.hh:160
Face(const GridType &grid, const Element &e, int index=-1)
Definition facehierarchy.hh:131
GridType::template Codim< 0 >::Entity Element
Definition facehierarchy.hh:125
GridType::LevelGridView::IntersectionIterator IntersectionIterator
Definition facehierarchy.hh:127
HierarchicFaceIterator< GridType > HierarchicIterator
Definition facehierarchy.hh:128
Element element_
Definition facehierarchy.hh:311
bool isInitialized() const
Check if face is initialized (index>=0)
Definition facehierarchy.hh:188
FaceType father() const
Return father face.
Definition facehierarchy.hh:217
Some static methods providing hierarchical information for faces.
Definition facehierarchy.hh:28
static LevelIntersectionIterator findFatherFaceIntersection(const GridType &grid, const Element &element, const int face)
Definition facehierarchy.hh:71
@ dim
Definition facehierarchy.hh:35
static int findFatherFace(const GridType &grid, const Element &element, const int face)
Definition facehierarchy.hh:62
GridType::LevelGridView::IntersectionIterator LevelIntersectionIterator
Definition facehierarchy.hh:33
GridType::LevelGridView::Intersection LevelIntersection
Definition facehierarchy.hh:32
static Element finestCoarseNeighbor(const GridType &grid, const Element &element, int face)
Definition facehierarchy.hh:85
static bool isSubFace(const Element &father, const int fatherFace, const Element &son, const int sonFace)
Definition facehierarchy.hh:37
GridType::template Codim< 0 >::Entity Element
Definition facehierarchy.hh:31
static int findSubFace(const Element &father, const int fatherFace, const Element &child)
Definition facehierarchy.hh:53
A hierarchical iterator for faces.
Definition facehierarchy.hh:338
FaceType face_
Definition facehierarchy.hh:511
std::vector< ChildFaceIterator > stack_
Definition facehierarchy.hh:514
PositionFlag
Definition facehierarchy.hh:347
@ end
Definition facehierarchy.hh:347
@ begin
Definition facehierarchy.hh:347
int maxLevel_
Definition facehierarchy.hh:505
void increment()
Increment the iterator.
Definition facehierarchy.hh:367
HierarchicFaceIterator(const GridType &grid, const FaceType &fatherFace, const int maxLevel, PositionFlag flag)
Definition facehierarchy.hh:352
const GridType & grid_
Definition facehierarchy.hh:502
const FaceType & dereference() const
Dereference the iterator.
Definition facehierarchy.hh:382
const Element element() const
Get element of current face.
Definition facehierarchy.hh:389
Face< GridType > FaceType
Face type that can be stored independently of the iterator.
Definition facehierarchy.hh:350
bool findChildInBack()
Definition facehierarchy.hh:460
int index() const
Get index of current face within element.
Definition facehierarchy.hh:396
const FaceType & fatherFace_
Definition facehierarchy.hh:508
bool equals(const HierarchicFaceIterator &other) const
Compare to other iterator.
Definition facehierarchy.hh:376
void incrementFrom(const Element &e)
Definition facehierarchy.hh:423
Definition facehierarchy.hh:474
int index_
Definition facehierarchy.hh:497
bool selectChildFaceOf(const Element &father, int fatherFace)
Definition facehierarchy.hh:489
HierarchicElementIterator it_
Definition facehierarchy.hh:495
ChildFaceIterator(const HierarchicElementIterator &it, const HierarchicElementIterator &end, int face=-1)
Definition facehierarchy.hh:475
HierarchicElementIterator end_
Definition facehierarchy.hh:496
FaceType toFace(const GridType &grid) const
Definition facehierarchy.hh:484