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_GRID_COMMON_INTERSECTIONITERATOR_HH 4 #define DUNE_GRID_COMMON_INTERSECTIONITERATOR_HH 5 6 #include <dune/common/iteratorfacades.hh> 7 #include <dune/common/proxymemberaccess.hh> 8 9 #include <dune/grid/common/intersection.hh> 10 11 namespace Dune 12 { 13 14 /** \brief Mesh entities of codimension 0 ("elements") allow to visit all 15 intersections with "neighboring" elements and with the domain 16 boundary. 17 18 \tparam GridImp Type that is a model of Dune::Grid 19 \tparam IntersectionIteratorImp Class template that is a model of Dune::IntersectionIterator 20 21 @warning The number of neigbors may be different from the number of 22 faces/edges of an element! 23 24 <h2>Overview</h2> 25 26 Intersections are codimension 1 objects. These 27 intersections are accessed via an IntersectionIterator. This allows 28 the implementation of non-matching grids, as one face can now 29 consist of several intersections. 30 In a conforming mesh such an intersection corresponds to an entity of 31 codimension 1 but in the general non-conforming case there will be no entity 32 in the mesh that directly corresponds to the intersection. Thus, the 33 IntersectionIterator describes these intersections implicitly. 34 35 <H2>Engine Concept</H2> 36 37 The IntersectionIterator class template wraps an object of type IntersectionIteratorImp 38 and forwards all member 39 function calls to corresponding members of this class. In that sense IntersectionIterator 40 defines the interface and IntersectionIteratorImp supplies the implementation. 41 42 <h2>Intersections, leaf grid and level grid</h2> 43 44 On an entity \b e of codimension zero there are two ways to create 45 IntersectionIterators by either using ilevelbegin() / ilevelend() or 46 ileafbegin()/ileafend(). In the first case intersections with 47 neighboring entities having the same level as \b e are traversed; in 48 the second case ileafbegin()==ileafend() if \b e is not a leaf otherwise 49 all intersections with neighboring leaf entities are traversed. 50 51 Consider a situation where two elements \b a and \b b have a common intersection. 52 %Element \b b has been refined into an element \b c and \b d, while \b a has not 53 been refined. 54 In one space dimension this situation is depicted in the figure below. 55 56 \image html islocalref.png "IntersectionIterator in a locally refined mesh." 57 \image latex islocalref.eps "IntersectionIterator in a locally refined mesh." width=\textwidth 58 59 Here the rule is the following: The %LevelIntersectionIterator 60 delivers all intersections 61 with elements on the same level, the %LeafIntersectionIterator delivers 62 the intersections with all leaf elements 63 if it has been started on a leaf element. Both iterators also stop at intersections 64 with the grid boundary. 65 According to this rule the level intersection iterator started at element \b a 66 in the example above delivers an intersection with \b b and the left grid boundary, 67 whereas the leaf intersection iterator returns \b c instead of \b b. 68 Starting on entity \b c the level intersection iterator returns \b d and the 69 intersection with the left boundary of the level 1 grid, 70 but the leaf intersection iterator returns both \b d and \b a. 71 Finally, starting on \b b the level intersection 72 iterator returns \b a and the right boundary, but the leaf intersection iterator is empty since 73 \b b is not a leaf entity of the grid. Starting on \b d both the 74 level and the leaf intersection iterators will return the element \b c 75 together with the right grid boundary. 76 77 @ingroup GIIntersectionIterator 78 */ 79 template< class GridImp, class IntersectionIteratorImp, class IntersectionImp > 80 class IntersectionIterator 81 { 82 public: 83 /** 84 * \brief type of underlying implementation 85 * 86 * \warning Implementation details may change without prior notification. 87 **/ 88 typedef IntersectionIteratorImp Implementation; 89 90 /** 91 * \brief access to the underlying implementation 92 * 93 * \warning Implementation details may change without prior notification. 94 **/ impl()95 Implementation &impl () { return realIterator; } 96 97 /** 98 * \brief access to the underlying implementation 99 * 100 * \warning Implementation details may change without prior notification. 101 **/ impl() const102 const Implementation &impl () const { return realIterator; } 103 104 protected: 105 Implementation realIterator; 106 107 public: 108 /** \brief Type of Intersection this IntersectionIterator points to */ 109 typedef Dune::Intersection< GridImp, IntersectionImp > Intersection; 110 111 //=========================================================== 112 /** @name Dereferencing 113 */ 114 //@{ 115 //=========================================================== 116 117 // The behavior when dereferencing the IntersectionIterator facade depends on 118 // the way the grid implementation handles returning intersections. The implementation 119 // may either return a reference to an intersection stored inside the IntersectionIterator 120 // implementation or a temporary Intersection object. This object has to be forwarded through 121 // the facade to the user, which requires a little trickery, especially for operator->(). 122 // 123 // In order to avoid confusing users reading the Doxygen documentation, we provide "clean" 124 // function signatures to Doxygen and hide the actual implementations. 125 126 #ifdef DOXYGEN 127 128 /** \brief Dereferencing operator. */ 129 Intersection operator*() const; 130 131 /** \brief Pointer operator. */ 132 const Intersection* operator->() const; 133 134 #else // DOXYGEN 135 136 /** \brief Dereferencing operator. */ 137 typename std::conditional< 138 std::is_lvalue_reference< 139 decltype(realIterator.dereference()) 140 >::value, 141 const Intersection&, 142 Intersection 143 >::type operator *() const144 operator*() const 145 { 146 return this->realIterator.dereference(); 147 } 148 149 /** \brief Pointer operator. */ 150 decltype(handle_proxy_member_access(realIterator.dereference())) operator ->() const151 operator->() const 152 { 153 return handle_proxy_member_access(realIterator.dereference()); 154 } 155 156 #endif // DOXYGEN 157 158 //@} 159 160 161 //=========================================================== 162 /** @name Compare methods 163 */ 164 //@{ 165 //=========================================================== 166 167 /** @brief Checks for equality. 168 Only Iterators pointing to the same intersection from the same Entity 169 are equal. Pointing to the same intersection from neighbor is 170 unequal as inside and outside are permuted. 171 */ operator ==(const IntersectionIterator & rhs) const172 bool operator==(const IntersectionIterator& rhs) const 173 { 174 return rhs.equals(*this); 175 } 176 177 /** @brief Checks for inequality. 178 Only Iterators pointing to the same intersection from the same Entity 179 are equal. Pointing to the same intersection from neighbor is 180 unequal as inside and outside are permuted. 181 */ operator !=(const IntersectionIterator & rhs) const182 bool operator!=(const IntersectionIterator& rhs) const 183 { 184 return ! rhs.equals(*this); 185 } 186 //@} 187 188 /** @brief Preincrement operator. Proceed to next intersection.*/ operator ++()189 IntersectionIterator& operator++() 190 { 191 this->realIterator.increment(); 192 return *this; 193 } 194 195 /** @brief Postincrement operator. Proceed to next intersection.*/ operator ++(int)196 IntersectionIterator operator++(int) 197 { 198 IntersectionIterator copy(*this); 199 this->realIterator.increment(); 200 return copy; 201 } 202 203 /** @brief Default constructor. */ IntersectionIterator()204 IntersectionIterator() 205 {} 206 207 //=========================================================== 208 /** @name Implementor interface 209 */ 210 //@{ 211 //=========================================================== 212 213 /** @brief forward equality check to realIterator */ equals(const IntersectionIterator & rhs) const214 bool equals(const IntersectionIterator& rhs) const 215 { 216 return this->realIterator.equals(rhs.realIterator); 217 } 218 219 /** Copy Constructor from IntersectionIteratorImp */ IntersectionIterator(const Implementation & impl)220 IntersectionIterator ( const Implementation &impl ) 221 : realIterator( impl ) 222 {} 223 //@} 224 }; 225 226 } // namespace Dune 227 228 229 namespace std 230 { 231 232 template< class GridImp, class IntersectionIteratorImp, class IntersectionImp > 233 struct iterator_traits< Dune::IntersectionIterator< GridImp, IntersectionIteratorImp, IntersectionImp > > 234 { 235 typedef ptrdiff_t difference_type; 236 typedef const typename Dune::Intersection< GridImp, IntersectionImp > value_type; 237 typedef value_type *pointer; 238 typedef value_type &reference; 239 typedef forward_iterator_tag iterator_category; 240 }; 241 242 } // namespace std 243 244 #include "intersection.hh" 245 246 #endif // DUNE_GRID_COMMON_INTERSECTIONITERATOR_HH 247