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