dune-alugrid 3.0.0
iterator_imp.cc
Go to the documentation of this file.
1#ifndef DUNE_ALUGRID_ITERATOR_IMP_CC
2#define DUNE_ALUGRID_ITERATOR_IMP_CC
3
4#include <dune/geometry/genericgeometry/topologytypes.hh>
5
6#include "alu3dinclude.hh"
7
8#include "geometry.hh"
9#include "entity.hh"
10#include "grid.hh"
11#include "faceutility.hh"
12
13namespace Dune {
14
15/************************************************************************************
16 ###
17 # # # ##### ###### ##### #### ###### #### # #####
18 # ## # # # # # # # # # # #
19 # # # # # ##### # # #### ##### # # #
20 # # # # # # ##### # # # # #
21 # # ## # # # # # # # # # # #
22 ### # # # ###### # # #### ###### #### # #
23************************************************************************************/
24
25// --IntersectionIterator
26template<class GridImp>
28ALU3dGridIntersectionIterator(const bool levelIntersectionIterator) :
29 connector_( levelIntersectionIterator ),
30 geoProvider_(connector_),
31 item_(0),
32 ghost_(0),
33 index_(-1)
34{
35}
36
37template<class GridImp>
38inline void
40{
41 item_ = 0;
42 ghost_ = 0;
43 // index < 0 indicates end iterator
44 index_ = -1;
45}
46
47template<class GridImp>
49setFirstItem (const HElementType & elem, int wLevel)
50{
51 ghost_ = 0;
52 item_ = static_cast<const IMPLElementType *> (&elem);
53
54 // Get first face
55 const GEOFaceType* firstFace = getFace(*item_, index_);
56
57 const GEOFaceType* childFace = firstFace->down();
58 if( childFace ) firstFace = childFace;
59
60 // Store the face in the connector
61 setNewFace(*firstFace);
62}
63
64template<class GridImp>
66setInteriorItem (const HElementType & elem, const BNDFaceType& ghost, int wLevel)
67{
68 // get correct face number
69 index_ = ElementTopo::alu2duneFace( ghost.getGhost().second );
70
71 // store ghost for method inside
72 ghost_ = &ghost;
73
74 // Get first face
75 const GEOFaceType* firstFace = getFace( ghost, index_ );
76 item_ = static_cast<const IMPLElementType *> (&elem);
77
78 const GEOFaceType* childFace = firstFace->down();
79 if( childFace ) firstFace = childFace;
80
81 // Store the face in the connector
82 setGhostFace(*firstFace);
83}
84
85template<class GridImp>
86template <class EntityType>
88first (const EntityType & en, int wLevel,
89 const bool conformingRefinement,
90 const bool ghostCellsEnabled )
91{
92 if( ! en.isLeaf() && en.level()>0)
93 {
94 done();
95 return ;
96 }
97
98 // adjust connector flags
99 connector_.setFlags( conformingRefinement, ghostCellsEnabled );
100
101 innerLevel_ = en.level();
102 index_ = 0;
103
104 if( en.isGhost() )
105 {
106 setInteriorItem(en.getItem(), en.getGhost(), wLevel);
107 }
108 else
109 {
110 // for the 2d version numFaces is smaller then the actual
111 // stored nFaces of the element
112 alugrid_assert ( dim == 3 ?
113 (numFaces == en.getItem().nFaces()) :
114 (numFaces < en.getItem().nFaces()) );
115 setFirstItem(en.getItem(), wLevel);
116 }
117}
118
119// copy constructor
120template<class GridImp>
123 connector_(org.connector_),
124 geoProvider_(connector_),
125 item_(org.item_),
126 ghost_(org.ghost_)
127{
128 if(org.item_)
129 { // else it's a end iterator
130 item_ = org.item_;
132 index_ = org.index_;
133 }
134 else
135 {
136 done();
137 }
138}
139
140// copy constructor
141template<class GridImp>
142inline void
145{
146 if(org.item_)
147 {
148 // adjust connector flags
149 connector_.setFlags( org.connector_.conformingRefinement(), org.connector_.ghostCellsEnabled() );
150
151 // else it's a end iterator
152 item_ = org.item_;
153 ghost_ = org.ghost_;
154 innerLevel_ = org.innerLevel_;
155 index_ = org.index_;
156 connector_.updateFaceInfo(org.connector_.face(),innerLevel_,
157 item_->twist(ElementTopo::dune2aluFace(index_)));
158 geoProvider_.resetFaceGeom();
159 }
160 else {
161 done();
162 }
163 alugrid_assert ( equals(org) );
164}
165
166// check whether entities are the same or whether iterator is done
167template<class GridImp>
170{
171 // this method is only to check equality of real iterators and end
172 // iterators
173 return ((item_ == i.item_) &&
174 (index_ == i.index_ )
175 );
176}
177
178template<class GridImp>
180{
181 // leaf increment
182 alugrid_assert (item_);
183
184 const GEOFaceType * nextFace = 0;
185
186 // When neighbour element is refined, try to get the next child on the face
187 if (connector_.conformanceState() == FaceInfoType::REFINED_OUTER)
188 {
189 nextFace = connector_.face().next();
190
191 // There was a next child face...
192 if (nextFace)
193 {
194 if( ImplTraits :: isGhost( ghost_ ) )
195 {
196 setGhostFace( *nextFace );
197 }
198 else
199 {
200 setNewFace(*nextFace);
201 }
202 return; // we found what we were looking for...
203 }
204 } // end if
205
206 // Next face number of starting element
207 ++index_;
208
209 // When the face number is larger than the number of faces an element
210 // can have, we've reached the end...
211 // for ghost elements here is finito
212 if (index_ >= numFaces || ghost_ )
213 {
214 done();
215 return;
216 }
217
218 // ... else we can take the next face
219 nextFace = getFace(connector_.innerEntity(), index_);
220 alugrid_assert (nextFace);
221
222 // Check whether we need to go down first
223 //if (nextFace has children which need to be visited)
224 const GEOFaceType * childFace = nextFace->down();
225 if( childFace ) nextFace = childFace;
226
227 alugrid_assert (nextFace);
228 setNewFace(*nextFace);
229 return;
230}
231
232
233template<class GridImp>
236{
237 alugrid_assert ( neighbor() );
238 // make sure that outside is not called for an end iterator
239
240 if( connector_.ghostBoundary() )
241 {
242 // create entity pointer with ghost boundary face
243 return EntityPointerImpl( connector_.boundaryFace() );
244 }
245
246 alugrid_assert ( &connector_.outerEntity() );
247 return EntityPointerImpl( connector_.outerEntity() );
248}
249
250template<class GridImp>
253{
254 if( ImplTraits :: isGhost( ghost_ ) )
255 {
256 return EntityPointerImpl( *ghost_ );
257 }
258 else
259 {
260 // make sure that inside is not called for an end iterator
261 return EntityPointerImpl( connector_.innerEntity() );
262 }
263}
264
265template<class GridImp>
267{
268 return connector_.boundary();
269}
270
271template<class GridImp>
273{
274 return connector_.neighbor();
275}
276
277template<class GridImp>
278inline int
280{
281 alugrid_assert (ElementTopo::dune2aluFace(index_) == connector_.innerALUFaceIndex());
282 return index_;
283}
284
285template< class GridImp >
288{
289 buildLocalGeometries();
290 return LocalGeometry( intersectionSelfLocal_ );
291}
292
293
294template< class GridImp >
295inline int
297{
298 return ElementTopo::alu2duneFace( connector_.outerALUFaceIndex() );
299}
300
301template< class GridImp >
304{
305 return Twist( connector_.duneTwist( indexInInside(), connector_.innerTwist() ) );
306}
307
308template< class GridImp >
311{
312 return Twist( connector_.duneTwist( indexInOutside(), connector_.outerTwist() ) );
313}
314
315template< class GridImp >
318{
319 alugrid_assert (neighbor());
320 buildLocalGeometries();
321 return LocalGeometry( intersectionNeighborLocal_ );
322}
323
324template<class GridImp>
327integrationOuterNormal(const FieldVector<alu3d_ctype, dim-1>& local) const
328{
329 return this->outerNormal(local);
330}
331
332template<class GridImp>
335outerNormal(const FieldVector<alu3d_ctype, dim-1>& local) const
336{
337 alugrid_assert (item_ != 0);
338
339 if(GridImp::dimension == 2 && GridImp::dimensionworld == 3 && GridImp::elementType == hexa)
340 {
341 typedef typename LocalGeometry::GlobalCoordinate Coordinate;
342 typedef typename GridImp::template Codim<0>::Geometry ElementGeometry;
343
344 NormalType outerNormal;
345 const ReferenceElement< alu3d_ctype, dim > &refElement =
346 ReferenceElements< alu3d_ctype, dim >::cube();
347
348 Coordinate xInside = geometryInInside().global( local );
349 Coordinate refNormal = refElement.integrationOuterNormal( indexInInside() );
350
351#if DUNE_VERSION_NEWER(DUNE_GRID,2,4)
352 const ElementGeometry insideGeom = inside().geometry();
353#else
354 const ElementGeometry insideGeom = inside().dereference().geometry();
355#endif
356 insideGeom.jacobianInverseTransposed( xInside ).mv( refNormal, outerNormal );
357 outerNormal *= insideGeom.integrationElement( xInside );
358 if(connector_.conformanceState() == FaceInfoType::REFINED_OUTER) outerNormal *=0.5;
359 return outerNormal;
360 }
361
362 return geoProvider_.outerNormal(local);
363}
364
365template<class GridImp>
368unitOuterNormal(const FieldVector<alu3d_ctype, dim-1>& local) const
369{
370 unitOuterNormal_ = this->outerNormal(local);
371 unitOuterNormal_ *= (1.0/unitOuterNormal_.two_norm());
372 return unitOuterNormal_;
373}
374
375template< class GridImp >
378{
379 geoProvider_.buildGlobalGeom( intersectionGlobal_ );
380 return Geometry( intersectionGlobal_ );
381}
382
383template<class GridImp>
384inline GeometryType
386type () const
387{
388 return GeometryType(
389 GridImp::elementType == tetra ?
390 GenericGeometry :: SimplexTopology< dim-1 > :: type :: id :
391 GenericGeometry :: CubeTopology < dim-1 > :: type :: id,
392 dim-1 );
393}
394
395template<class GridImp>
396inline int
398{
399 alugrid_assert ( item_ );
400 return ( boundary() ) ? connector_.boundaryId() : 0;
401}
402
403template<class GridImp>
404inline size_t
406{
407 alugrid_assert ( item_ );
408 alugrid_assert ( boundary() );
409 return connector_.segmentIndex();
410}
411
412template< class GridImp >
414{
415 intersectionSelfLocal_.buildGeom( geoProvider_.intersectionSelfLocal() );
416 if ( !connector_.outerBoundary() )
417 intersectionNeighborLocal_.buildGeom( geoProvider_.intersectionNeighborLocal() );
418}
419
420template <class GridImp>
423getFace(const GEOTriangleBndType& bnd, int index) const
424{
425 return bnd.myhface3(0);
426}
427
428template <class GridImp>
431getFace(const GEOQuadBndType& bnd, int index) const
432{
433 return bnd.myhface4(0);
434}
435
436template <class GridImp>
439getFace(const GEOTetraElementType& elem, int index) const
440{
441 alugrid_assert (index >= 0 && index < numFaces);
442 return elem.myhface(ElementTopo::dune2aluFace(index));
443}
444
445template <class GridImp>
448getFace(const GEOHexaElementType& elem, int index) const
449{
450 alugrid_assert (index >= 0 && index < numFaces);
451 return elem.myhface(ElementTopo::dune2aluFace(index));
452}
453
454template <class GridImp>
456setNewFace(const GEOFaceType& newFace)
457{
458 alugrid_assert ( ! ghost_ );
459 alugrid_assert ( innerLevel_ == item_->level() );
460 connector_.updateFaceInfo(newFace,innerLevel_,
461 item_->twist(ElementTopo::dune2aluFace(index_)) );
462 geoProvider_.resetFaceGeom();
463}
464
465template <class GridImp>
467setGhostFace(const GEOFaceType& newFace)
468{
469 alugrid_assert ( ghost_ );
470 alugrid_assert ( innerLevel_ == ghost_->level() );
471 connector_.updateFaceInfo(newFace,innerLevel_, ghost_->twist(0) );
472 geoProvider_.resetFaceGeom();
473}
474
475template <class GridImp>
476inline int
478level() const {
479 alugrid_assert ( item_ && (innerLevel_ == item_->level()) );
480 return innerLevel_;
481}
482
483/************************************************************************************
484 ###
485 # # # ##### ###### ##### #### ###### #### # #####
486 # ## # # # # # # # # # # #
487 # # # # # ##### # # #### ##### # # #
488 # # # # # # ##### # # # # #
489 # # ## # # # # # # # # # # #
490 ### # # # ###### # # #### ###### #### # #
491************************************************************************************/
492
493// --IntersectionIterator
494template<class GridImp>
497 : ALU3dGridIntersectionIterator<GridImp>( true )
498 , levelNeighbor_(false)
499 , isLeafItem_(false)
500{
501}
502
503template<class GridImp>
504template <class EntityType>
506first (const EntityType & en, int wLevel,
507 const bool conformingRefinement, const bool ghostCellsEnabled )
508{
509 connector_.setFlags( conformingRefinement, ghostCellsEnabled );
510
511 // if given Entity is not leaf, we create an end iterator
512 index_ = 0;
513 isLeafItem_ = en.isLeaf();
514
515 if( en.isGhost() )
516 {
517 setInteriorItem(en.getItem(), en.getGhost(), wLevel);
518 }
519 else
520 {
521 // for the 2d version numFaces is smaller then the actual
522 // stored nFaces of the element
523 alugrid_assert ( dim == 3 ?
524 (numFaces == en.getItem().nFaces()) :
525 (numFaces < en.getItem().nFaces()) );
526 setFirstItem(en.getItem(), wLevel);
527 }
528}
529
530template<class GridImp>
532setFirstItem (const HElementType & elem, int wLevel)
533{
534 ghost_ = 0;
535 item_ = static_cast<const IMPLElementType *> (&elem);
536 this->innerLevel_ = wLevel;
537 // Get first face
538 const GEOFaceType* firstFace = getFace(*item_, index_);
539 // Store the face in the connector
540 setNewFace(*firstFace);
541}
542
543template<class GridImp>
544inline void ALU3dGridLevelIntersectionIterator<GridImp> ::
545setInteriorItem (const HElementType & elem, const BNDFaceType& ghost, int wLevel)
546{
547 // store ghost for method inside
548 ghost_ = &ghost;
549 item_ = static_cast<const IMPLElementType *> (&elem);
550 // get correct face number
551 index_ = ElementTopo::alu2duneFace( ghost.getGhost().second );
552
553 innerLevel_ = wLevel;
554
555 // Get first face
556 const GEOFaceType* firstFace = getFace( ghost, index_ );
557
558 // Store the face in the connector
559 setNewFace(*firstFace);
560}
561
562// copy constructor
563template<class GridImp>
566 : ALU3dGridIntersectionIterator<GridImp>(org)
567 , levelNeighbor_(org.levelNeighbor_)
568 , isLeafItem_(org.isLeafItem_)
569{
570}
571
572// copy constructor
573template<class GridImp>
574inline void
577{
579 levelNeighbor_ = org.levelNeighbor_;
580 isLeafItem_ = org.isLeafItem_;
581}
582
583template<class GridImp>
585{
586 // level increment
587 alugrid_assert ( item_ );
588
589 // Next face number of starting element
590 ++index_;
591
592 // When the face number is larger than the number of faces an element
593 // can have, we've reached the end...
594 if ( index_ >= numFaces || ImplTraits::isGhost( ghost_ ) )
595 {
596 done();
597 return;
598 }
599
600 // ... else we can take the next face
601 const GEOFaceType * nextFace = getFace(connector_.innerEntity(), index_);
602 alugrid_assert (nextFace);
603
604 setNewFace(*nextFace);
605 return;
606}
607
608template<class GridImp>
610{
611 return levelNeighbor_ && (BaseType :: neighbor());
612}
613
614template <class GridImp>
616setNewFace(const GEOFaceType& newFace)
617{
618 alugrid_assert ( item_->level() == innerLevel_ );
619 levelNeighbor_ = (newFace.level() == innerLevel_);
620 connector_.updateFaceInfo(newFace, innerLevel_,
621 ( ImplTraits::isGhost( ghost_ ) ) ?
622 ghost_->twist(0) :
623 item_->twist(ElementTopo::dune2aluFace( index_ ))
624 );
625 geoProvider_.resetFaceGeom();
626
627 // check again level neighbor because outer element might be coarser then
628 // this element
629 if( isLeafItem_ )
630 {
631 if( connector_.ghostBoundary() )
632 {
633 const BNDFaceType & ghost = connector_.boundaryFace();
634 // if nonconformity occurs then no level neighbor
635 levelNeighbor_ = (innerLevel_ == ghost.ghostLevel() );
636 }
637 else if ( ! connector_.outerBoundary() )
638 {
639 levelNeighbor_ = (connector_.outerEntity().level() == innerLevel_);
640 }
641 }
642}
643
644} // end namespace Dune
645
646#if COMPILE_ALUGRID_INLINE
647 #include "iterator.cc"
648#endif
649
650#endif // DUNE_ALUGRID_ITERATOR_IMP_CC
#define alugrid_assert(EX)
Definition alugrid_assert.hh:20
Definition alu3dinclude.hh:80
@ hexa
Definition topology.hh:12
@ tetra
Definition topology.hh:12
Definition alu3dinclude.hh:259
Definition iterator.hh:56
LocalGeometry geometryInInside() const
Definition iterator_imp.cc:287
NormalType outerNormal(const FieldVector< alu3d_ctype, dim-1 > &local) const
Definition iterator_imp.cc:335
int boundaryId() const
return information about the Boundary
Definition iterator_imp.cc:397
int indexInInside() const
Definition iterator_imp.cc:279
void done()
Definition iterator_imp.cc:39
const BNDFaceType * ghost_
current pointer to ghost face if iterator was started from ghost element
Definition iterator.hh:270
GridImp::template Codim< 1 >::Geometry Geometry
Definition iterator.hh:108
Geometry geometry() const
Definition iterator_imp.cc:377
int index_
Definition iterator.hh:273
EntityPointerImpl inside() const
access entity where iteration started
Definition iterator_imp.cc:252
NormalType integrationOuterNormal(const FieldVector< alu3d_ctype, dim-1 > &local) const
Definition iterator_imp.cc:327
int level() const
return level of iterator (level of item)
Definition iterator_imp.cc:478
GridImp::template Codim< 1 >::LocalGeometry LocalGeometry
Definition iterator.hh:109
bool boundary() const
return true if intersection is with boundary.
Definition iterator_imp.cc:266
Twist twistInInside() const
returns twist of face compared to inner element
Definition iterator_imp.cc:303
Twist twistInOutside() const
returns twist of face compared to outer element
Definition iterator_imp.cc:310
NormalType unitOuterNormal(const FieldVector< alu3d_ctype, dim-1 > &local) const
Definition iterator_imp.cc:368
LocalGeometry geometryInOutside() const
Definition iterator_imp.cc:317
int innerLevel_
Definition iterator.hh:272
FaceInfoType connector_
Definition iterator.hh:263
EntityPointerImpl outside() const
access neighbor
Definition iterator_imp.cc:235
void buildLocalGeometries() const
Definition iterator_imp.cc:413
GridImp::template Codim< 0 >::EntityPointerImpl EntityPointerImpl
Definition iterator.hh:110
void setNewFace(const GEOFaceType &newFace)
Definition iterator_imp.cc:456
FieldVector< alu3d_ctype, dimworld > NormalType
Definition iterator.hh:116
const ALU3dImplTraits< tetra, Comm >::GEOFaceType * getFace(const GEOTriangleBndType &bnd, int index) const
Definition iterator_imp.cc:423
Twists::Twist Twist
Definition iterator.hh:105
void assign(const ALU3dGridIntersectionIterator< GridImp > &org)
assignment of iterators
Definition iterator_imp.cc:144
bool neighbor() const
return true if across the face an neighbor on leaf exists
Definition iterator_imp.cc:272
const IMPLElementType * item_
current element from which we started the intersection iterator
Definition iterator.hh:267
GeometryType type() const
obtain the type of reference element for this intersection
Definition iterator_imp.cc:386
size_t boundarySegmentIndex() const
return the boundary segment index
Definition iterator_imp.cc:405
int indexInOutside() const
Definition iterator_imp.cc:296
bool conformingRefinement() const
return true if conforming refinement is enabled
Definition faceutility.hh:138
bool ghostCellsEnabled() const
return true if ghost cells are enabled
Definition faceutility.hh:141
const GEOFaceType & face() const
Returns the ALU3dGrid face.
Definition faceutility_imp.cc:320
bool neighbor() const
return true if across the edge an neighbor on this level exists
Definition iterator_imp.cc:609