dune-grid  2.2.0
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/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