1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_UGINTERSECTIONIT_HH
4 #define DUNE_UGINTERSECTIONIT_HH
5 
6 /** \file
7  * \brief The UGGridIntersectionIterator class
8  */
9 
10 namespace Dune {
11 
12   /** \brief Implementation of the UGGrid LevelIntersectionIterator
13    */
14   template<class GridImp>
15   class UGGridLevelIntersectionIterator
16   {
17 
18     enum {dim=GridImp::dimension};
19 
20     friend class UGGridEntity<0,dim,GridImp>;
21 
22   public:
23     typedef Dune::Intersection< GridImp, Dune::UGGridLevelIntersection< GridImp > > Intersection;
24 
UGGridLevelIntersectionIterator()25     UGGridLevelIntersectionIterator()
26     {}
27 
28     /** The default Constructor makes empty Iterator
29      */
UGGridLevelIntersectionIterator(typename UG_NS<dim>::Element * center,int nb,const GridImp * gridImp)30     UGGridLevelIntersectionIterator(typename UG_NS<dim>::Element* center, int nb, const GridImp* gridImp)
31       : intersection_(UGGridLevelIntersection<GridImp>(center,nb,gridImp))
32     {}
33 
34     //! equality
equals(const UGGridLevelIntersectionIterator<GridImp> & other) const35     bool equals(const UGGridLevelIntersectionIterator<GridImp>& other) const {
36       return intersection_.impl().equals(other.intersection_.impl());
37     }
38 
39     //! prefix increment
increment()40     void increment() {
41       intersection_.impl().neighborCount_++;
42 
43       intersection_.impl().geometry_.reset();
44       intersection_.impl().geometryInInside_.reset();
45       intersection_.impl().geometryInOutside_.reset();
46     }
47 
48     //! \brief dereferencing
dereference() const49     const Intersection & dereference() const {
50       return intersection_;
51     }
52 
53   private:
54 
55     mutable Intersection intersection_;
56 
57   };
58 
59 
60   /** \brief Implementation of the UGGrid LeafIntersectionIterator
61    */
62   template<class GridImp>
63   class UGGridLeafIntersectionIterator
64   {
65 
66     enum {dim=GridImp::dimension};
67 
68     friend class UGGridEntity<0,dim,GridImp>;
69 
70   public:
71 
72     typedef Dune::Intersection< GridImp, Dune::UGGridLeafIntersection< GridImp > > Intersection;
73 
UGGridLeafIntersectionIterator()74     UGGridLeafIntersectionIterator()
75     {}
76 
UGGridLeafIntersectionIterator(typename UG_NS<dim>::Element * center,int nb,const GridImp * gridImp)77     UGGridLeafIntersectionIterator(typename UG_NS<dim>::Element* center, int nb, const GridImp* gridImp)
78       : intersection_(UGGridLeafIntersection<GridImp>(center,nb,gridImp))
79     {}
80 
81     //! equality
equals(const UGGridLeafIntersectionIterator<GridImp> & other) const82     bool equals(const UGGridLeafIntersectionIterator<GridImp>& other) const {
83       return intersection_.impl().equals(other.intersection_.impl());
84     }
85 
86     /** \brief Prefix increment.
87 
88        The UG data structure does not directly contain information about leaf neighbors/intersections.
89        Therefore getting that information is fairly expensive.  In particular, it is too expensive to
90        start looking for the next intersection whenever 'increment()' is called.  Therefore, all
91        intersections of one face of the 'inside' element are precomputed, and incrementing then traverses
92        this precomputed list.  If the list is exhausted the iterator advances to the next faces
93        and precomputes all intersections there.
94      */
increment()95     void increment() {
96 
97       UGGridLeafIntersection<GridImp>& intersectionImp = intersection_.impl();
98 
99       intersectionImp.subNeighborCount_++;
100 
101       // are there no more intersections for the current element face?
102       if (intersectionImp.subNeighborCount_ >= intersectionImp.leafSubFaces_.size() ) {
103 
104         // move to the next face
105         intersectionImp.neighborCount_++;
106         intersectionImp.subNeighborCount_ = 0;
107 
108         // if the next face is not the end iterator construct all intersections for it
109         if (intersectionImp.neighborCount_ < UG_NS<dim>::Sides_Of_Elem(intersectionImp.center_))
110           intersectionImp.constructLeafSubfaces();
111 
112       }
113 
114       // make sure geometries are not taken from the cache the next time
115       // the geometry{|InInside|InOutside} methods are called.
116       intersectionImp.geometry_.reset();
117       intersectionImp.geometryInInside_.reset();
118       intersectionImp.geometryInOutside_.reset();
119     }
120 
121     //! \brief dereferencing
dereference() const122     const Intersection & dereference() const {
123       return intersection_;
124     }
125 
126   private:
127 
128     mutable Intersection intersection_;
129 
130   };
131 
132 }  // namespace Dune
133 
134 #endif
135