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