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