dune-grid
2.2.0
|
00001 #ifndef DUNE_GEOGRID_ITERATOR_HH 00002 #define DUNE_GEOGRID_ITERATOR_HH 00003 00004 #include <dune/geometry/referenceelements.hh> 00005 00006 #include <dune/grid/geometrygrid/declaration.hh> 00007 #include <dune/grid/geometrygrid/entitypointer.hh> 00008 00009 namespace Dune 00010 { 00011 00012 namespace GeoGrid 00013 { 00014 00015 // Internal Forward Declarations 00016 // ----------------------------- 00017 00018 template< class Traits, bool fake = Traits::fake > 00019 class Iterator; 00020 00021 template< class Grid > 00022 class HierarchicIterator; 00023 00024 00025 00026 // PartitionIteratorFilter 00027 // ----------------------- 00028 00029 template< int codim, PartitionIteratorType pitype, class Grid > 00030 struct PartitionIteratorFilter; 00031 00032 template< int codim, class Grid > 00033 struct PartitionIteratorFilter< codim, Interior_Partition, Grid > 00034 { 00035 static const int dimension = remove_const< Grid >::type::dimension; 00036 static const int codimension = codim; 00037 00038 static const PartitionIteratorType Element_Partition = Interior_Partition; 00039 00040 typedef typename remove_const< Grid >::type::ctype ctype; 00041 typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element; 00042 typedef GenericReferenceElement< ctype, dimension > ReferenceElement; 00043 00044 static bool apply ( const ReferenceElement &refElement, 00045 const Element &element, int subEntity ) 00046 { 00047 const int size = refElement.size( subEntity, codim, dimension ); 00048 for( int i = 0; i < size; ++i ) 00049 { 00050 const int j = refElement.subEntity( subEntity, codim, i, dimension ); 00051 PartitionType type = element.template subEntity< dimension >( j )->partitionType(); 00052 if( type == InteriorEntity ) 00053 return true; 00054 } 00055 return false; 00056 } 00057 }; 00058 00059 template< int codim, class Grid > 00060 struct PartitionIteratorFilter< codim, InteriorBorder_Partition, Grid > 00061 { 00062 static const int dimension = remove_const< Grid >::type::dimension; 00063 static const int codimension = codim; 00064 00065 static const PartitionIteratorType Element_Partition = Interior_Partition; 00066 00067 typedef typename remove_const< Grid >::type::ctype ctype; 00068 typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element; 00069 typedef GenericReferenceElement< ctype, dimension > ReferenceElement; 00070 00071 static bool apply ( const ReferenceElement &refElement, 00072 const Element &element, int subEntity ) 00073 { 00074 return true; 00075 } 00076 }; 00077 00078 template< int codim, class Grid > 00079 struct PartitionIteratorFilter< codim, Overlap_Partition, Grid > 00080 { 00081 static const int dimension = remove_const< Grid >::type::dimension; 00082 static const int codimension = codim; 00083 00084 static const PartitionIteratorType Element_Partition = Overlap_Partition; 00085 00086 typedef typename remove_const< Grid >::type::ctype ctype; 00087 typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element; 00088 typedef GenericReferenceElement< ctype, dimension > ReferenceElement; 00089 00090 static bool apply ( const ReferenceElement &refElement, 00091 const Element &element, int subEntity ) 00092 { 00093 if( element.partitionType() == InteriorEntity ) 00094 return true; 00095 00096 const int size = refElement.size( subEntity, codim, dimension ); 00097 for( int i = 0; i < size; ++i ) 00098 { 00099 const int j = refElement.subEntity( subEntity, codim, i, dimension ); 00100 PartitionType type = element.template subEntity< dimension >( j )->partitionType(); 00101 if( (type == OverlapEntity) || (type == BorderEntity) ) 00102 return true; 00103 } 00104 return false; 00105 } 00106 }; 00107 00108 template< int codim, class Grid > 00109 struct PartitionIteratorFilter< codim, OverlapFront_Partition, Grid > 00110 { 00111 static const int dimension = remove_const< Grid >::type::dimension; 00112 static const int codimension = codim; 00113 00114 static const PartitionIteratorType Element_Partition = Overlap_Partition; 00115 00116 typedef typename remove_const< Grid >::type::ctype ctype; 00117 typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element; 00118 typedef GenericReferenceElement< ctype, dimension > ReferenceElement; 00119 00120 static bool apply ( const ReferenceElement &refElement, 00121 const Element &element, int subEntity ) 00122 { 00123 return true; 00124 } 00125 }; 00126 00127 template< int codim, class Grid > 00128 struct PartitionIteratorFilter< codim, All_Partition, Grid > 00129 { 00130 static const int dimension = remove_const< Grid >::type::dimension; 00131 static const int codimension = codim; 00132 00133 static const PartitionIteratorType Element_Partition = All_Partition; 00134 00135 typedef typename remove_const< Grid >::type::ctype ctype; 00136 typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element; 00137 typedef GenericReferenceElement< ctype, dimension > ReferenceElement; 00138 00139 static bool apply ( const ReferenceElement &refElement, 00140 const Element &element, int subEntity ) 00141 { 00142 return true; 00143 } 00144 }; 00145 00146 template< int codim, class Grid > 00147 struct PartitionIteratorFilter< codim, Ghost_Partition, Grid > 00148 { 00149 static const int dimension = remove_const< Grid >::type::dimension; 00150 static const int codimension = codim; 00151 00152 static const PartitionIteratorType Element_Partition = Ghost_Partition; 00153 00154 typedef typename remove_const< Grid >::type::ctype ctype; 00155 typedef typename remove_const< Grid >::type::Traits::template Codim< 0 >::Entity Element; 00156 typedef GenericReferenceElement< ctype, dimension > ReferenceElement; 00157 00158 static bool apply ( const ReferenceElement &refElement, 00159 const Element &element, int subEntity ) 00160 { 00161 const int size = refElement.size( subEntity, codim, dimension ); 00162 for( int i = 0; i < size; ++i ) 00163 { 00164 const int j = refElement.subEntity( subEntity, codim, i, dimension ); 00165 PartitionType type = element.template subEntity< dimension >( j )->partitionType(); 00166 if( type == GhostEntity ) 00167 return true; 00168 } 00169 return false; 00170 } 00171 }; 00172 00173 00174 00175 // Iterator (real) 00176 // --------------- 00177 00178 template< class Traits > 00179 class Iterator< Traits, false > 00180 : public EntityPointer< Traits, false > 00181 { 00182 typedef EntityPointer< Traits, false > Base; 00183 00184 typedef typename Traits::Grid Grid; 00185 00186 public: 00187 typedef typename Traits::IteratorType IteratorType; 00188 00189 protected: 00190 typedef typename Base::EntityImpl EntityImpl; 00191 00192 using Base::hostEntityIterator_; 00193 using Base::entityImpl; 00194 using Base::grid; 00195 00196 public: 00197 Iterator ( const Grid &grid, int level, IteratorType type ) 00198 : Base( grid, Traits::getHostEntityIterator( grid.hostGrid(), level, type ) ) 00199 {} 00200 00201 void increment () 00202 { 00203 ++hostEntityIterator_; 00204 entityImpl() = EntityImpl( grid() ); 00205 } 00206 }; 00207 00208 00209 00210 // Iterator (fake) 00211 // --------------- 00212 00213 template< class Traits > 00214 class Iterator< Traits, true > 00215 : public EntityPointer< Traits, true > 00216 { 00217 typedef EntityPointer< Traits, true > Base; 00218 00219 typedef typename Traits::Grid Grid; 00220 00221 public: 00222 static const int dimension = Traits::dimension; 00223 static const int codimension = Traits::codimension; 00224 00225 typedef typename Traits::IteratorType IteratorType; 00226 00227 private: 00228 typedef typename Traits::Filter Filter; 00229 00230 typedef typename Traits::HostElement HostElement; 00231 typedef typename Traits::HostElementIterator HostElementIterator; 00232 typedef typename Traits::HostIndexSet HostIndexSet; 00233 00234 protected: 00235 typedef typename Base::EntityImpl EntityImpl; 00236 00237 using Base::hostElementIterator_; 00238 using Base::entityImpl; 00239 using Base::grid; 00240 00241 public: 00242 Iterator ( const Grid &grid, int level, IteratorType type ) 00243 : Base( grid, Traits::getHostElementIterator( grid.hostGrid(), level, type ), -1 ), 00244 hostEnd_( Traits::getHostElementIterator( grid.hostGrid(), level, Traits::end ) ), 00245 hostIndexSet_( &Traits::getHostIndexSet( grid.hostGrid(), level ) ) 00246 { 00247 if( hostElementIterator_ != hostEnd_ ) 00248 { 00249 visited_.resize( hostIndexSet_->size( codimension ), false ); 00250 increment(); 00251 } 00252 } 00253 00254 void increment () 00255 { 00256 typedef typename Traits::ctype ctype; 00257 00258 int subEntity = this->subEntity(); 00259 while( hostElementIterator_ != hostEnd_ ) 00260 { 00261 const HostElement &hostElement = *hostElementIterator_; 00262 00263 const GenericReferenceElement< ctype, dimension > &refElement 00264 = GenericReferenceElements< ctype, dimension >::general( hostElement.type() ); 00265 00266 ++subEntity; 00267 const int count = refElement.size( codimension ); 00268 for( ; subEntity < count; ++subEntity ) 00269 { 00270 if( !Filter::apply( refElement, hostElement, subEntity ) ) 00271 continue; 00272 00273 const size_t index = hostIndexSet_->subIndex( hostElement, subEntity, codimension ); 00274 if( !visited_[ index ] ) 00275 { 00276 visited_[ index ] = true; 00277 entityImpl() = EntityImpl( grid(), subEntity ); 00278 return; 00279 } 00280 } 00281 ++hostElementIterator_; 00282 subEntity = -1; 00283 } 00284 entityImpl() = EntityImpl( grid(), subEntity ); 00285 } 00286 00287 private: 00288 HostElementIterator hostEnd_; 00289 const HostIndexSet *hostIndexSet_; 00290 std::vector< bool > visited_; 00291 }; 00292 00293 00294 00295 // LeafIteratorTraits 00296 // ------------------ 00297 00298 template< int codim, PartitionIteratorType pitype, class Grid > 00299 struct LeafIteratorTraits 00300 : public EntityPointerTraits< codim, Grid > 00301 { 00302 typedef typename EntityPointerTraits< codim, Grid >::HostGrid HostGrid; 00303 00304 typedef PartitionIteratorFilter< codim, pitype, HostGrid > Filter; 00305 00306 static const PartitionIteratorType Entity_Partition = pitype; 00307 static const PartitionIteratorType Element_Partition = Filter::Element_Partition; 00308 00309 typedef typename HostGrid::template Codim< codim > 00310 ::template Partition< Entity_Partition >::LeafIterator 00311 HostEntityIterator; 00312 typedef typename HostGrid::template Codim< 0 > 00313 ::template Partition< Element_Partition >::LeafIterator 00314 HostElementIterator; 00315 00316 typedef typename HostGrid::LeafIndexSet HostIndexSet; 00317 00318 enum IteratorType { begin, end }; 00319 00320 static HostEntityIterator 00321 getHostEntityIterator ( const HostGrid &hostGrid, int level, IteratorType type ) 00322 { 00323 if( type == begin ) 00324 return hostGrid.template leafbegin< codim, Entity_Partition >(); 00325 else 00326 return hostGrid.template leafend< codim, Entity_Partition >(); 00327 } 00328 00329 static HostElementIterator 00330 getHostElementIterator ( const HostGrid &hostGrid, int level, IteratorType type ) 00331 { 00332 if( type == begin ) 00333 return hostGrid.template leafbegin< 0, Element_Partition >(); 00334 else 00335 return hostGrid.template leafend< 0, Element_Partition >(); 00336 } 00337 00338 static const HostIndexSet &getHostIndexSet ( const HostGrid &hostGrid, int level ) 00339 { 00340 return hostGrid.leafIndexSet(); 00341 } 00342 }; 00343 00344 00345 00346 // LevelIteratorTraits 00347 // ------------------- 00348 00349 template< int codim, PartitionIteratorType pitype, class Grid > 00350 struct LevelIteratorTraits 00351 : public EntityPointerTraits< codim, Grid > 00352 { 00353 typedef typename EntityPointerTraits< codim, Grid >::HostGrid HostGrid; 00354 00355 typedef PartitionIteratorFilter< codim, pitype, HostGrid > Filter; 00356 00357 static const PartitionIteratorType Entity_Partition = pitype; 00358 static const PartitionIteratorType Element_Partition = Filter::Element_Partition; 00359 00360 typedef typename HostGrid::template Codim< codim > 00361 ::template Partition< Entity_Partition >::LevelIterator 00362 HostEntityIterator; 00363 typedef typename HostGrid::template Codim< 0 > 00364 ::template Partition< Element_Partition >::LevelIterator 00365 HostElementIterator; 00366 00367 typedef typename HostGrid::LevelIndexSet HostIndexSet; 00368 00369 enum IteratorType { begin, end }; 00370 00371 static HostEntityIterator 00372 getHostEntityIterator ( const HostGrid &hostGrid, int level, IteratorType type ) 00373 { 00374 if( type == begin ) 00375 return hostGrid.template lbegin< codim, Entity_Partition >( level ); 00376 else 00377 return hostGrid.template lend< codim, Entity_Partition >( level ); 00378 } 00379 00380 static HostElementIterator 00381 getHostElementIterator ( const HostGrid &hostGrid, int level, IteratorType type ) 00382 { 00383 if( type == begin ) 00384 return hostGrid.template lbegin< 0, Element_Partition >( level ); 00385 else 00386 return hostGrid.template lend< 0, Element_Partition >( level ); 00387 } 00388 00389 static const HostIndexSet &getHostIndexSet ( const HostGrid &hostGrid, int level ) 00390 { 00391 return hostGrid.levelIndexSet( level ); 00392 } 00393 }; 00394 00395 00396 00397 // HierarchicIteratorTraits 00398 // ------------------------ 00399 00400 template< class Grid > 00401 struct HierarchicIteratorTraits 00402 : public EntityPointerTraits< 0, Grid > 00403 { 00404 typedef typename remove_const< Grid >::type::Traits Traits; 00405 00406 typedef typename Traits::HostGrid::Traits::HierarchicIterator HostEntityIterator; 00407 typedef typename Traits::HostGrid::Traits::HierarchicIterator HostElementIterator; 00408 }; 00409 00410 00411 00412 // HierarchicIterator 00413 // ------------------ 00414 00415 template< class Grid > 00416 class HierarchicIterator 00417 : public EntityPointer< HierarchicIteratorTraits< Grid > > 00418 { 00419 typedef HierarchicIteratorTraits< Grid > Traits; 00420 00421 typedef EntityPointer< Traits > Base; 00422 00423 protected: 00424 typedef typename Base::EntityImpl EntityImpl; 00425 typedef typename Traits::HostEntityIterator HostEntityIterator; 00426 00427 using Base::hostEntityIterator_; 00428 using Base::entityImpl; 00429 using Base::grid; 00430 00431 public: 00432 HierarchicIterator ( const Grid &grid, 00433 const HostEntityIterator &hostEntityIterator ) 00434 : Base( grid, hostEntityIterator ) 00435 {} 00436 00437 void increment () 00438 { 00439 ++hostEntityIterator_; 00440 entityImpl() = EntityImpl( grid() ); 00441 } 00442 }; 00443 00444 } // namespace GeoGrid 00445 00446 } // namespace Dune 00447 00448 #endif // #ifndef DUNE_GEOGRID_ITERATOR_HH