dune-grid  2.2.0
common/defaultindexsets.hh
Go to the documentation of this file.
00001 #ifndef DUNE_DEFAULTINDEXSETS_HH
00002 #define DUNE_DEFAULTINDEXSETS_HH
00003 
00004 //- system includes 
00005 #include <vector>
00006 #include <rpc/rpc.h>
00007 
00008 //- Dune includes 
00009 #include <dune/common/misc.hh>
00010 // #include <dune/common/interfaces.hh>
00011 #include <dune/grid/common/grid.hh>
00012 #include <dune/grid/common/adaptcallback.hh> // for compatibility only
00013 #include <dune/grid/utility/persistentcontainer.hh>
00014 
00021 namespace Dune {
00022 
00024 template <class GridImp>
00025 struct DefaultLevelIteratorTypes
00026 {
00028   template<int cd>
00029   struct Codim
00030   {
00031     template<PartitionIteratorType pitype>
00032     struct Partition
00033     {
00034       typedef typename GridImp::Traits::template Codim<cd>::template Partition<pitype>::LevelIterator Iterator;
00035     };
00036   };
00037 };
00038 
00040 template <class GridImp>
00041 struct DefaultLeafIteratorTypes
00042 {
00044   template<int cd>
00045   struct Codim
00046   {
00047     template<PartitionIteratorType pitype>
00048     struct Partition
00049     {
00050       typedef typename GridImp::Traits::template Codim<cd>::
00051         template Partition<pitype>::LeafIterator  Iterator;
00052     };
00053   };
00054 };
00055 
00056 
00057 namespace DefaultIndexSetHelper
00058 {
00059 
00060   template< class Grid, class Index >
00061   struct ContainsIndex
00062   {
00063     static bool
00064     contains ( const PersistentContainer< Grid, Index > &container,
00065                const size_t index )
00066     {
00067       DUNE_THROW( NotImplemented, "DefaultIndexSetHelper::ContainsIndex not implemented for this grid." );
00068       return true;
00069     }
00070   };
00071 
00072 } // namespace DefaultIndexSetHelper
00073 
00074 
00079 template < class GridImp, class IteratorImp >
00080 class DefaultIndexSet :
00081   public IndexSet< GridImp, DefaultIndexSet <GridImp, IteratorImp>, unsigned int >
00082 {
00083   typedef GridImp GridType;
00084   enum { dim = GridType :: dimension };
00085 
00086 public:
00087   enum { ncodim = GridType::dimension + 1 };
00088 
00090   typedef unsigned int IndexType;
00091 
00093   typedef IteratorImp IteratorType ;
00094   
00095   struct Index 
00096   {
00097     int index_;
00098     Index() : index_( -1 ) {}
00099     int index() const { return index_; }
00100     void set( const int index ) { index_ = index; }
00101   };
00102 
00103   typedef PersistentContainer< GridType, Index > PersistentContainerType ;
00104   typedef std::vector< PersistentContainerType* > PersistentContainerVectorType;
00105 
00106 private:
00107   typedef DefaultIndexSet<GridType, IteratorType > ThisType;
00108 
00109   template <class EntityType, int codim> 
00110   struct InsertEntity
00111   {
00112     template <class SizeVector>
00113     static void insert(const EntityType & en, 
00114                        PersistentContainerVectorType &indexContainer, 
00115                        SizeVector& sizes)
00116     {
00117       PersistentContainerType& codimContainer = *(indexContainer[ codim ]);
00118       for( int i = 0; i < en.template count< codim >(); ++i )
00119       {
00120         Index& idx = codimContainer( en , i );
00121         if( idx.index() < 0 )
00122         {
00123           idx.set( sizes[codim] );
00124           ++ sizes[ codim ];
00125         }
00126       }
00127       InsertEntity<EntityType,codim-1>::insert(en, indexContainer, sizes);
00128     }
00129   };
00130   
00131   template <class EntityType> 
00132   struct InsertEntity<EntityType,0>
00133   {
00134     template <class SizeVector>
00135     static void insert(const EntityType & en, 
00136                        PersistentContainerVectorType &indexContainer, 
00137                        SizeVector& sizes)
00138     {
00139       enum { codim = 0 };
00140       PersistentContainerType& codimContainer = *(indexContainer[ codim ]);
00141       Index& idx = codimContainer[ en ];
00142       if( idx.index() < 0 )
00143       {
00144         idx.set( sizes[codim] );
00145         ++ sizes[ codim ];
00146       }
00147     }
00148   };
00149   
00150 public:
00153   using IndexSet<GridType, DefaultIndexSet>::subIndex;
00154     
00157   DefaultIndexSet( const GridType & grid , 
00158                    const IteratorType& begin,
00159                    const IteratorType& end,
00160                    const int level = -1 )
00161   : grid_(grid), 
00162     indexContainers_( ncodim, (PersistentContainerType *) 0),
00163     size_( ncodim, -1 ),
00164     level_(level)
00165   {
00166     for( int codim=0; codim < ncodim; ++codim ) 
00167       indexContainers_[ codim ] = new PersistentContainerType( grid, codim );
00168 
00169     calcNewIndex (begin, end);
00170   }
00171 
00173   ~DefaultIndexSet () 
00174   {
00175     for( int codim=0; codim < ncodim; ++codim )
00176       delete indexContainers_[ codim ];
00177   }
00178 
00179   const PersistentContainerType& indexContainer( const size_t codim ) const 
00180   {
00181     assert( codim < indexContainers_.size() );
00182     assert( indexContainers_[ codim ] );
00183     return *( indexContainers_[ codim ] );
00184   }
00185 
00186   PersistentContainerType& indexContainer( const size_t codim ) 
00187   {
00188     assert( codim < indexContainers_.size() );
00189     assert( indexContainers_[ codim ] );
00190     return *( indexContainers_[ codim ] );
00191   }
00192 
00194   template<class EntityType>
00195   IndexType index (const EntityType & en) const 
00196   {
00197     enum { cd = EntityType :: codimension };
00198     // this must not be true for vertices 
00199     // therefore only check other codims 
00200 #ifndef NDEBUG 
00201     const int codim = cd;
00202     assert( (codim == dim) ? (1) : ( level_ < 0 ) || (level_ == en.level() )); 
00203     assert( indexContainer( codim )[ en ].index() >= 0 );
00204 #endif
00205     return indexContainer( cd )[ en ].index();
00206   }
00207  
00209   template<int cd>
00210   IndexType index (const typename GridImp::template Codim<cd>::Entity& en) const 
00211   {
00212     // this must not be true for vertices 
00213     // therefore only check other codims 
00214 #ifndef NDEBUG 
00215     const int codim = cd;
00216     //const bool isLeaf = (codim == 0) ? en.isLeaf() : true ;
00217     assert( (codim == dim) ? (1) : ( level_ < 0 ) || (level_ == en.level() )); 
00218     assert( indexContainer( cd )[ en ].index() >= 0 );
00219 #endif
00220     return indexContainer( cd )[ en ].index();
00221   }
00222  
00225   template< int cc >
00226   IndexType subIndex ( const typename remove_const< GridImp >::type::Traits::template Codim< cc >::Entity &e,
00227                        int i, unsigned int codim ) const
00228   {
00229     assert( (codim != 0) || (level_ < 0) || ( level_ == e.level() ) );
00230     assert( indexContainer( codim )( e, i ).index() >= 0 );
00231     return indexContainer( codim )( e, i ).index();
00232   }
00233 
00235   template<class EntityType>
00236   bool contains (const EntityType& en) const
00237   {
00238     enum { cd = EntityType :: codimension };
00239     return (indexContainer( cd )[ en ].index() >= 0 );
00240   }
00241 
00243   IndexType size ( int codim ) const
00244   {
00245     assert( codim >= 0 && codim <= GridType::dimension );
00246     return size_[ codim ];
00247   }
00248 
00251   IndexType size ( GeometryType type ) const
00252   {
00253     if( typeNotValid(type) ) return 0;
00254     return size_[GridType::dimension-type.dim()];
00255   }
00256 
00259   void calcNewIndex (const IteratorType& begin, const IteratorType& end )
00260   {
00261     // resize arrays to new size 
00262     // and set size to zero 
00263     for(int cd=0; cd<ncodim; ++cd) 
00264     {
00265       indexContainer( cd ).clear();
00266       size_[cd] = 0;
00267     }
00268 
00269     // grid walk to setup index set 
00270     for(IteratorType it = begin; it != end; ++it)
00271     {
00272       assert( ( level_ < 0 ) ? it->isLeaf() : (it->level() == level_) );
00273       insertEntity( *it, size_ );
00274     }
00275 
00276     // remember the number of entity on level and cd = 0
00277     for(int cd=0; cd<ncodim; ++cd) 
00278     {
00279 #ifndef NDEBUG
00280       const int gridSize = ( level_ < 0 ) ? grid_.size( cd ) : grid_.size( level_, cd); 
00281       const int mySize = size_[cd];
00282       if( mySize > gridSize ) 
00283       {
00284         std::cout << mySize << " s | g " << gridSize << std::endl;
00285       }
00286       assert( mySize <= gridSize );
00287 #endif
00288     }
00289   }
00290 
00292   const std::vector<GeometryType>& geomTypes (int codim) const
00293   {
00294     return grid_.geomTypes( codim );
00295   }
00296 
00298   bool containsIndex ( const int cd , const int idx) const
00299   {
00300     typedef DefaultIndexSetHelper::ContainsIndex< GridType, Index > ContainsIndex;
00301     return ContainsIndex::contains( indexContainer( cd ), idx ); 
00302   }
00303 
00304 private:
00305   // return whether set has this type stored or not 
00306   bool typeNotValid (const GeometryType & type) const 
00307   {
00308     int codim = GridType :: dimension - type.dim();
00309     const std::vector<GeometryType> & geomT = geomTypes(codim); 
00310     for(size_t i=0; i<geomT.size(); ++i) if(geomT[i] == type) return false;
00311     return true;  
00312   }
00313 
00314   // calculate index for the codim 
00315   template <class EntityType, class SizeVector>
00316   void insertEntity(EntityType & en, SizeVector& sizes)
00317   {
00318     InsertEntity<EntityType,dim>::insert( en, indexContainers_, sizes);
00319   }
00320 
00321   // grid this index set belongs to 
00322   const GridType& grid_;
00323 
00325   PersistentContainerVectorType indexContainers_;
00326 
00327   // number of entitys of each level an codim 
00328   std::vector< int > size_;
00329 
00330   // the level for which this index set is created 
00331   const int level_;
00332   
00333 };
00334 
00335 
00336 } // end namespace Dune 
00337 #endif