dune-grid
2.1.1
|
00001 #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH 00002 #define DUNE_ALBERTAGRIDINDEXSETS_HH 00003 00004 #include <dune/common/stdstreams.hh> 00005 00006 #include <dune/grid/common/grid.hh> 00007 #include <dune/grid/common/indexidset.hh> 00008 #include <dune/grid/common/indexstack.hh> 00009 00010 #include <dune/grid/albertagrid/misc.hh> 00011 #include <dune/grid/albertagrid/dofadmin.hh> 00012 #include <dune/grid/albertagrid/dofvector.hh> 00013 #include <dune/grid/albertagrid/elementinfo.hh> 00014 #include <dune/grid/albertagrid/gridfamily.hh> 00015 00016 #if HAVE_ALBERTA 00017 00018 namespace Dune 00019 { 00020 00021 namespace Alberta 00022 { 00023 typedef Dune::IndexStack< int, 100000 > IndexStack; 00024 00025 extern IndexStack *currentIndexStack; 00026 } 00027 00028 00029 00030 // AlbertaGridHierarchicIndexSet 00031 // ----------------------------- 00032 00033 template< int dim, int dimworld > 00034 class AlbertaGridHierarchicIndexSet 00035 : public IndexSet< AlbertaGridFamily< dim, dimworld >, AlbertaGridHierarchicIndexSet< dim,dimworld >, int > 00036 { 00037 typedef AlbertaGridHierarchicIndexSet< dim, dimworld > This; 00038 typedef IndexSet< AlbertaGridFamily< dim, dimworld >, This, int > Base; 00039 00040 friend class AlbertaGrid< dim, dimworld >; 00041 00042 public: 00043 typedef AlbertaGrid< dim, dimworld > Grid; 00044 typedef AlbertaGridFamily< dim, dimworld > GridFamily; 00045 00046 typedef typename Base::IndexType IndexType; 00047 00048 static const int dimension = GridFamily::dimension; 00049 00050 typedef Alberta::ElementInfo< dimension > ElementInfo; 00051 typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering; 00052 00053 private: 00054 typedef typename GridFamily::Traits Traits; 00055 00056 typedef Alberta::DofVectorPointer< IndexType > IndexVectorPointer; 00057 00058 class InitEntityNumber; 00059 00060 template< int codim > 00061 struct CreateEntityNumbers; 00062 00063 template< int codim > 00064 class RefineNumbering; 00065 00066 template< int codim > 00067 class CoarsenNumbering; 00068 00069 explicit AlbertaGridHierarchicIndexSet ( const DofNumbering &dofNumbering ); 00070 00071 public: 00072 typedef Alberta::IndexStack IndexStack; 00073 00075 template< class Entity > 00076 bool contains ( const Entity & ) const 00077 { 00078 return true; 00079 } 00080 00081 using Base::index; 00082 using Base::subIndex; 00083 00085 template< int cc > 00086 IndexType index ( const typename Traits::template Codim< cc >::Entity &entity ) const 00087 { 00088 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp; 00089 const EntityImp &entityImp = Grid::getRealImplementation( entity ); 00090 return subIndex( entityImp.elementInfo(), entityImp.subEntity(), cc ); 00091 } 00092 00094 template< int cc > 00095 IndexType subIndex ( const typename Traits::template Codim< cc >::Entity &entity, int i, unsigned int codim ) const 00096 { 00097 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp; 00098 const EntityImp &entityImp = Grid::getRealImplementation( entity ); 00099 00100 int k = i; 00101 if( cc > 0 ) 00102 { 00103 const GenericReferenceElement< Alberta::Real, dimension > &refElement 00104 = GenericReferenceElements< Alberta::Real, dimension >::simplex(); 00105 k = refElement.subEntity( entityImp.subEntity(), cc, i, codim ); 00106 } 00107 00108 const int j = entityImp.grid().generic2alberta( codim, k ); 00109 return subIndex( entityImp.elementInfo(), j, codim ); 00110 } 00111 00113 IndexType size ( const GeometryType &type ) const 00114 { 00115 return (type.isSimplex() ? size( dimension - type.dim() ) : 0); 00116 } 00117 00119 IndexType size ( int codim ) const 00120 { 00121 assert( (codim >= 0) && (codim <= dimension) ); 00122 return indexStack_[ codim ].size(); 00123 } 00124 00126 const std::vector< GeometryType > &geomTypes( int codim ) const 00127 { 00128 assert( (codim >= 0) && (codim <= dimension) ); 00129 return geomTypes_[ codim ]; 00130 } 00131 00132 IndexType subIndex ( const ElementInfo &elementInfo, int i, unsigned int codim ) const 00133 { 00134 assert( !elementInfo == false ); 00135 return subIndex( elementInfo.element(), i, codim ); 00136 } 00137 00144 IndexType subIndex ( const Alberta::Element *element, int i, unsigned int codim ) const 00145 { 00146 IndexType *array = (IndexType *)entityNumbers_[ codim ]; 00147 const IndexType subIndex = array[ dofNumbering_( element, codim, i ) ]; 00148 assert( (subIndex >= 0) && (subIndex < size( codim )) ); 00149 return subIndex; 00150 } 00151 00152 void preAdapt () 00153 { 00154 // set global pointer to index stack 00155 if( !IndexVectorPointer::supportsAdaptationData ) 00156 { 00157 assert( Alberta::currentIndexStack == 0 ); 00158 Alberta::currentIndexStack = indexStack_; 00159 } 00160 } 00161 00162 void postAdapt () 00163 { 00164 // remove global pointer to index stack 00165 if( !IndexVectorPointer::supportsAdaptationData ) 00166 Alberta::currentIndexStack = 0; 00167 } 00168 00169 void create (); 00170 void read ( const std::string &filename ); 00171 bool write ( const std::string &filename ) const; 00172 00173 void release () 00174 { 00175 for( int i = 0; i <= dimension; ++i ) 00176 entityNumbers_[ i ].release(); 00177 } 00178 00179 private: 00180 template< int codim > 00181 static IndexStack &getIndexStack ( const IndexVectorPointer &dofVector ) 00182 { 00183 IndexStack *indexStack; 00184 if( IndexVectorPointer::supportsAdaptationData ) 00185 indexStack = dofVector.template getAdaptationData< IndexStack >(); 00186 else 00187 indexStack = &Alberta::currentIndexStack[ codim ]; 00188 assert( indexStack != 0 ); 00189 return *indexStack; 00190 } 00191 00192 // access to the dof vectors 00193 const DofNumbering &dofNumbering_; 00194 00195 // index stacks providing new numbers during adaptation 00196 IndexStack indexStack_[ dimension+1 ]; 00197 00198 // dof vectors storing the (persistent) numbering 00199 IndexVectorPointer entityNumbers_[ dimension+1 ]; 00200 00201 // all geometry types contained in the grid 00202 std::vector< GeometryType > geomTypes_[ dimension+1 ]; 00203 }; 00204 00205 00206 00207 // AlbertaGridHierarchicIndexSet::InitEntityNumber 00208 // ----------------------------------------------- 00209 00210 template< int dim, int dimworld > 00211 class AlbertaGridHierarchicIndexSet< dim, dimworld >::InitEntityNumber 00212 { 00213 IndexStack &indexStack_; 00214 00215 public: 00216 InitEntityNumber ( IndexStack &indexStack ) 00217 : indexStack_( indexStack ) 00218 {} 00219 00220 void operator() ( int &dof ) 00221 { 00222 dof = indexStack_.getIndex(); 00223 } 00224 }; 00225 00226 00227 00228 // AlbertaGridHierarchicIndexSet::CreateEntityNumbers 00229 // -------------------------------------------------- 00230 00231 template< int dim, int dimworld > 00232 template< int codim > 00233 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CreateEntityNumbers 00234 { 00235 static void setup ( AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet ); 00236 00237 static void apply ( const Alberta::HierarchyDofNumbering< dimension > &dofNumbering, 00238 AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet ); 00239 00240 static void apply ( const std::string &filename, 00241 const Alberta::MeshPointer< dimension > &mesh, 00242 AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet ); 00243 }; 00244 00245 00246 00247 // AlbertaGridHierarchicIndexSet::RefineNumbering 00248 // ---------------------------------------------- 00249 00250 template< int dim, int dimworld > 00251 template< int codim > 00252 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::RefineNumbering 00253 { 00254 static const int dimension = dim; 00255 static const int codimension = codim; 00256 00257 private: 00258 typedef Alberta::DofAccess< dimension, codimension > DofAccess; 00259 00260 explicit RefineNumbering ( const IndexVectorPointer &dofVector ) 00261 : indexStack_( getIndexStack< codimension >( dofVector ) ), 00262 dofVector_( dofVector ), 00263 dofAccess_( dofVector.dofSpace() ) 00264 {} 00265 00266 public: 00267 void operator() ( const Alberta::Element *child, int subEntity ); 00268 00269 typedef Alberta::Patch< dimension > Patch; 00270 static void interpolateVector ( const IndexVectorPointer &dofVector, 00271 const Patch &patch ); 00272 00273 private: 00274 IndexStack &indexStack_; 00275 IndexVectorPointer dofVector_; 00276 DofAccess dofAccess_; 00277 }; 00278 00279 00280 00281 // AlbertaGridHierarchicIndexSet::CoarsenNumbering 00282 // ----------------------------------------------- 00283 00284 template< int dim, int dimworld > 00285 template< int codim > 00286 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CoarsenNumbering 00287 { 00288 static const int dimension = dim; 00289 static const int codimension = codim; 00290 00291 private: 00292 typedef Alberta::DofAccess< dimension, codimension > DofAccess; 00293 00294 explicit CoarsenNumbering ( const IndexVectorPointer &dofVector ) 00295 : indexStack_( getIndexStack< codimension >( dofVector ) ), 00296 dofVector_( dofVector ), 00297 dofAccess_( dofVector.dofSpace() ) 00298 {} 00299 00300 public: 00301 void operator() ( const Alberta::Element *child, int subEntity ); 00302 00303 typedef Alberta::Patch< dimension > Patch; 00304 static void restrictVector ( const IndexVectorPointer &dofVector, 00305 const Patch &patch ); 00306 private: 00307 IndexStack &indexStack_; 00308 IndexVectorPointer dofVector_; 00309 DofAccess dofAccess_; 00310 }; 00311 00312 00313 00314 // AlbertaGridIndexSet 00315 // ------------------- 00316 00317 template< int dim, int dimworld > 00318 class AlbertaGridIndexSet 00319 : public IndexSet< AlbertaGrid< dim, dimworld >, AlbertaGridIndexSet< dim, dimworld >, int > 00320 { 00321 typedef AlbertaGridIndexSet< dim, dimworld > This; 00322 typedef IndexSet< AlbertaGrid< dim, dimworld >, This, int > Base; 00323 00324 public: 00325 typedef AlbertaGrid< dim, dimworld > Grid; 00326 00327 typedef typename Base::IndexType IndexType; 00328 00329 static const int dimension = Grid::dimension; 00330 00331 typedef Alberta::ElementInfo< dimension > ElementInfo; 00332 typedef Alberta::HierarchyDofNumbering< dimension > DofNumbering; 00333 00334 private: 00335 typedef typename Grid::Traits Traits; 00336 00337 template< int codim > 00338 struct Insert; 00339 00340 public: 00341 explicit AlbertaGridIndexSet ( const DofNumbering &dofNumbering ) 00342 : dofNumbering_( dofNumbering ) 00343 { 00344 for( int codim = 0; codim <= dimension; ++codim ) 00345 { 00346 indices_[ codim ] = 0; 00347 00348 const GeometryType type( GeometryType::simplex, dimension - codim ); 00349 geomTypes_[ codim ].push_back( type ); 00350 } 00351 } 00352 00353 ~AlbertaGridIndexSet () 00354 { 00355 for( int codim = 0; codim <= dimension; ++codim ) 00356 delete[] indices_[ codim ]; 00357 } 00358 00359 template< class Entity > 00360 bool contains ( const Entity &entity ) const 00361 { 00362 const int codim = Entity::codimension; 00363 00364 const AlbertaGridEntity< codim, dim, const Grid > &entityImp 00365 = Grid::getRealImplementation( entity ); 00366 const Alberta::Element *element = entityImp.elementInfo().el(); 00367 00368 const IndexType *const array = indices_[ codim ]; 00369 const IndexType subIndex = array[ dofNumbering_( element, codim, entityImp.subEntity() ) ]; 00370 00371 return (subIndex >= 0); 00372 } 00373 00374 using Base::index; 00375 using Base::subIndex; 00376 00378 template< int cc > 00379 IndexType index ( const typename Traits::template Codim< cc >::Entity &entity ) const 00380 { 00381 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp; 00382 const EntityImp &entityImp = Grid::getRealImplementation( entity ); 00383 return subIndex( entityImp.elementInfo(), entityImp.subEntity(), cc ); 00384 } 00385 00387 template< int cc > 00388 IndexType subIndex ( const typename Traits::template Codim< cc >::Entity &entity, int i, unsigned int codim ) const 00389 { 00390 typedef AlbertaGridEntity< cc, dim, const Grid > EntityImp; 00391 const EntityImp &entityImp = Grid::getRealImplementation( entity ); 00392 00393 int k = i; 00394 if( cc > 0 ) 00395 { 00396 const GenericReferenceElement< Alberta::Real, dimension > &refElement 00397 = GenericReferenceElements< Alberta::Real, dimension >::simplex(); 00398 k = refElement.subEntity( entityImp.subEntity(), cc, i, codim ); 00399 } 00400 00401 const int j = entityImp.grid().generic2alberta( codim, k ); 00402 return subIndex( entityImp.elementInfo(), j, codim ); 00403 } 00404 00405 IndexType size ( const GeometryType &type ) const 00406 { 00407 return (type.isSimplex() ? size( dimension - type.dim() ) : 0); 00408 } 00409 00410 IndexType size ( int codim ) const 00411 { 00412 assert( (codim >= 0) && (codim <= dimension) ); 00413 return size_[ codim ]; 00414 } 00415 00416 const std::vector< GeometryType > &geomTypes( int codim ) const 00417 { 00418 assert( (codim >= 0) && (codim <= dimension) ); 00419 return geomTypes_[ codim ]; 00420 } 00421 00422 template< class Iterator > 00423 void update ( const Iterator &begin, const Iterator &end ) 00424 { 00425 for( int codim = 0; codim <= dimension; ++codim ) 00426 { 00427 delete[] indices_[ codim ]; 00428 00429 const unsigned int dofSize = dofNumbering_.size( codim ); 00430 indices_[ codim ] = new IndexType[ dofSize ]; 00431 for( unsigned int i = 0; i < dofSize; ++i ) 00432 indices_[ codim ][ i ] = -1; 00433 00434 size_[ codim ] = 0; 00435 } 00436 00437 for( Iterator it = begin; it != end; ++it ) 00438 { 00439 const AlbertaGridEntity< 0, dim, const Grid > &entityImp 00440 = Grid::getRealImplementation( *it ); 00441 const Alberta::Element *element = entityImp.elementInfo().el(); 00442 ForLoop< Insert, 0, dimension >::apply( element, *this ); 00443 } 00444 } 00445 00446 private: 00447 IndexType subIndex ( const ElementInfo &elementInfo, int i, unsigned int codim ) const 00448 { 00449 assert( !elementInfo == false ); 00450 return subIndex( elementInfo.element(), i, codim ); 00451 } 00452 00459 IndexType subIndex ( const Alberta::Element *element, int i, unsigned int codim ) const 00460 { 00461 const IndexType *const array = indices_[ codim ]; 00462 const IndexType subIndex = array[ dofNumbering_( element, codim, i ) ]; 00463 assert( (subIndex >= 0) && (subIndex < size( codim )) ); 00464 return subIndex; 00465 } 00466 00467 // access to the dof vectors 00468 const DofNumbering &dofNumbering_; 00469 00470 // an array of indices for each codimension 00471 IndexType *indices_[ dimension+1 ]; 00472 00473 // the size of each codimension 00474 IndexType size_[ dimension+1 ]; 00475 00476 // all geometry types contained in the grid 00477 std::vector< GeometryType > geomTypes_[ dimension+1 ]; 00478 }; 00479 00480 00481 00482 // AlbertaGridIndexSet::Insert 00483 // --------------------------- 00484 00485 template< int dim, int dimworld > 00486 template< int codim > 00487 struct AlbertaGridIndexSet< dim, dimworld >::Insert 00488 { 00489 static void apply ( const Alberta::Element *const element, 00490 AlbertaGridIndexSet< dim, dimworld > &indexSet ) 00491 { 00492 int *const array = indexSet.indices_[ codim ]; 00493 IndexType &size = indexSet.size_[ codim ]; 00494 00495 for( int i = 0; i < Alberta::NumSubEntities< dim, codim >::value; ++i ) 00496 { 00497 int &index = array[ indexSet.dofNumbering_( element, codim, i ) ]; 00498 if( index < 0 ) 00499 index = size++; 00500 } 00501 } 00502 }; 00503 00504 00505 00506 // AlbertaGridIdSet 00507 // ---------------- 00508 00510 template< int dim, int dimworld > 00511 class AlbertaGridIdSet 00512 : public IdSet< AlbertaGrid< dim, dimworld >, AlbertaGridIdSet< dim, dimworld >, unsigned int > 00513 { 00514 typedef AlbertaGridIdSet< dim, dimworld > This; 00515 typedef IdSet< AlbertaGrid< dim, dimworld >, This, unsigned int > Base; 00516 00517 friend class AlbertaGrid< dim, dimworld >; 00518 00519 public: 00521 typedef typename Base::IdType IdType; 00522 00523 private: 00524 typedef AlbertaGrid< dim, dimworld > Grid; 00525 00526 static const int dimension = Grid::dimension; 00527 00528 typedef typename Grid::HierarchicIndexSet HierarchicIndexSet; 00529 00530 // create id set, only allowed for AlbertaGrid 00531 AlbertaGridIdSet ( const HierarchicIndexSet &hIndexSet ) 00532 : hIndexSet_( hIndexSet ) 00533 {} 00534 00535 public: 00537 template< class Entity > 00538 IdType id ( const Entity &e ) const 00539 { 00540 const int codim = Entity::codimension; 00541 return id< codim >( e ); 00542 } 00543 00545 template< int codim > 00546 IdType id ( const typename Grid::template Codim< codim >::Entity &e ) const 00547 { 00548 assert( (codim >= 0) && (codim <= dimension) ); 00549 const IdType index = hIndexSet_.index( e ); 00550 return (index << 2) | IdType( codim ); 00551 } 00552 00554 IdType subId ( const typename Grid::template Codim< 0 >::Entity &e, int i, unsigned int subcodim ) const 00555 { 00556 assert( int( subcodim ) <= dimension ); 00557 const IdType index = hIndexSet_.subIndex( e, i, subcodim ); 00558 return (index << 2) | IdType( subcodim ); 00559 } 00560 00561 template< int codim > 00562 IdType subId ( const typename Grid::template Codim< codim >::Entity &e, int i, unsigned int subcodim ) const 00563 { 00564 assert( (codim >= 0) && (codim <= dimension) && (int( codim + subcodim ) <= dimension) ); 00565 const IdType index = hIndexSet_.subIndex( e, i, subcodim ); 00566 return (index << 2) | IdType( codim + subcodim ); 00567 } 00568 00569 template< class Entity > 00570 IdType subId ( const Entity &e, int i, unsigned int subcodim ) const 00571 { 00572 return subId< Entity::codimension >( e, i, subcodim ); 00573 } 00574 00575 private: 00576 // prohibit copying 00577 AlbertaGridIdSet ( const This & ); 00578 00579 const HierarchicIndexSet &hIndexSet_; 00580 }; 00581 00582 } // namespace Dune 00583 00584 #endif // #if HAVE_ALBERTA 00585 00586 #endif // #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH