geometrygrid/iterator.hh

Go to the documentation of this file.
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

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].