00001 #ifndef DUNE_ALBERTAGRIDINDEXSETS_HH
00002 #define DUNE_ALBERTAGRIDINDEXSETS_HH
00003
00004 #if HAVE_ALBERTA
00005
00006 #include <dune/common/stdstreams.hh>
00007
00008 #include <dune/grid/common/grid.hh>
00009 #include <dune/grid/common/indexidset.hh>
00010 #include <dune/grid/common/indexstack.hh>
00011
00012 #include <dune/grid/albertagrid/albertaheader.hh>
00013 #include <dune/grid/albertagrid/misc.hh>
00014 #include <dune/grid/albertagrid/referencetopo.hh>
00015 #include <dune/grid/albertagrid/dofadmin.hh>
00016 #include <dune/grid/albertagrid/dofvector.hh>
00017 #include <dune/grid/albertagrid/elementinfo.hh>
00018
00019 namespace Dune
00020 {
00021
00022
00023
00024
00025 template< int dim, int dimworld >
00026 class AlbertaGrid;
00027
00028 template< int codim, int dim, class GridImp >
00029 class AlbertaGridEntity;
00030
00031
00032
00033 namespace Alberta
00034 {
00035 typedef Dune::IndexStack< int, 100000 > IndexStack;
00036
00037 static IndexStack *currentIndexStack = 0;
00038 }
00039
00040
00041
00043 template <class GridImp>
00044 struct AlbertaGridHierarchicIteratorTypes
00045 {
00047 template<int cd>
00048 struct Codim
00049 {
00050 template<PartitionIteratorType pitype>
00051 struct Partition
00052 {
00053
00054
00055
00056
00057 typedef typename remove_const<GridImp>::type::Traits::template Codim<cd>::template Partition<pitype>::LeafIterator Iterator;
00058 };
00059 };
00060 };
00061
00062
00063
00064
00065
00066
00067 template< int dim, int dimworld >
00068 class AlbertaGridHierarchicIndexSet
00069 : public IndexSetDefaultImplementation
00070 < AlbertaGrid< dim, dimworld >,
00071 AlbertaGridHierarchicIndexSet< dim,dimworld >,
00072 AlbertaGridHierarchicIteratorTypes< AlbertaGrid< dim, dimworld > > >
00073 {
00074 typedef AlbertaGridHierarchicIndexSet< dim, dimworld > This;
00075
00076 friend class AlbertaGrid< dim, dimworld >;
00077
00078 typedef AlbertaGrid< dim, dimworld > Grid;
00079
00080 typedef typename Grid::Traits Traits;
00081
00082 static const int dimension = Grid::dimension;
00083
00084 typedef Alberta::DofVectorPointer< int > IndexVectorPointer;
00085
00086 template< int codim >
00087 class DofAccess;
00088
00089 class InitEntityNumber;
00090
00091 template< int codim >
00092 struct CreateEntityNumbers;
00093
00094 template< int codim >
00095 class RefineNumbering;
00096
00097 template< int codim >
00098 class CoarsenNumbering;
00099
00100 explicit AlbertaGridHierarchicIndexSet ( const Grid &grid );
00101
00102 public:
00103 typedef Alberta::IndexStack IndexStack;
00104
00106 template< class Entity >
00107 bool contains ( const Entity & ) const
00108 {
00109 return true;
00110 }
00111
00113 template< class Entity >
00114 int index ( const Entity &entity ) const
00115 {
00116 const int codim = Entity::codimension;
00117 return index< codim >( entity );
00118 }
00119
00121 template< int codim >
00122 int index ( const typename Grid::Traits::template Codim< codim >::Entity &entity ) const
00123 {
00124 const AlbertaGridEntity< codim, dim, const Grid > &entityImp
00125 = Grid::getRealImplementation( entity );
00126 return subIndex< codim >( entityImp.elementInfo().el(), entityImp.subEntity() );
00127 }
00128
00130 template< int codim >
00131 int subIndex ( const typename Traits::template Codim< 0 >::Entity &entity, int i ) const
00132 {
00133 const AlbertaGridEntity< 0, dim, const Grid > &entityImp
00134 = Grid::getRealImplementation( entity );
00135 const int j = entityImp.grid().dune2alberta( codim, i );
00136 return subIndex< codim >( entityImp.elementInfo().el(), j );
00137 }
00138
00140 int size ( GeometryType type ) const
00141 {
00142 return (type.isSimplex() ? size( dimension - type.dim() ) : 0);
00143 }
00144
00146 int size ( int codim ) const
00147 {
00148 assert( (codim >= 0) && (codim <= dimension) );
00149 return indexStack_[ codim ].size();
00150 }
00151
00153 const std::vector< GeometryType > &geomTypes( int codim ) const
00154 {
00155 assert( (codim >= 0) && (codim <= dimension) );
00156 return geomTypes_[ codim ];
00157 }
00158
00159 #ifdef INDEXSET_HAS_ITERATORS
00160
00162 template<int cd, PartitionIteratorType pitype>
00163 typename AlbertaGridHierarchicIteratorTypes<Grid>::template Codim<cd>::
00164 template Partition<pitype>::Iterator end () const
00165 {
00166 return grid_.template leafend<cd,pitype> ();
00167 }
00168
00171 template<int cd, PartitionIteratorType pitype>
00172 typename AlbertaGridHierarchicIteratorTypes<Grid>::template Codim<cd>::
00173 template Partition<pitype>::Iterator begin () const
00174 {
00175 return grid_.template leafbegin<cd,pitype> ();
00176 }
00177 #endif
00178
00179 template< int codim >
00180 int subIndex ( const Alberta::ElementInfo< dimension > &elementInfo, int i ) const
00181 {
00182 assert( !elementInfo == false );
00183 return subIndex< codim >( elementInfo.el(), i );
00184 }
00185
00191 template< int codim >
00192 int subIndex ( const Alberta::Element *element, int i ) const
00193 {
00194 Int2Type< codim > codimVariable;
00195
00196 int *array = (int *)entityNumbers_[ codim ];
00197 const int subIndex = array[ dofAccess_[ codimVariable ]( element, i ) ];
00198 assert( (subIndex >= 0) && (subIndex < size( codim )) );
00199 return subIndex;
00200 }
00201
00202 void preAdapt ()
00203 {
00204
00205 if( !IndexVectorPointer::supportsAdaptationData )
00206 {
00207 assert( Alberta::currentIndexStack == 0 );
00208 Alberta::currentIndexStack = indexStack_;
00209 }
00210 }
00211
00212 void postAdapt ()
00213 {
00214
00215 if( !IndexVectorPointer::supportsAdaptationData )
00216 Alberta::currentIndexStack = 0;
00217 }
00218
00219 void create ( const Alberta::HierarchyDofNumbering< dimension > &dofNumbering )
00220 {
00221 Alberta::ForLoop< CreateEntityNumbers, 0, dimension >::apply( dofNumbering, *this );
00222 }
00223
00224 void read ( const std::string &filename,
00225 const Alberta::MeshPointer< dimension > &mesh )
00226 {
00227 Alberta::ForLoop< CreateEntityNumbers, 0, dimension >::apply( filename, mesh, *this );
00228 }
00229
00230 bool write ( const std::string &filename ) const
00231 {
00232 bool success = true;
00233 for( int i = 0; i <= dimension; ++i )
00234 {
00235 std::ostringstream s;
00236 s << filename << ".cd" << i;
00237 success &= entityNumbers_[ i ].write( s.str() );
00238 }
00239 return success;
00240 }
00241
00242 void release ()
00243 {
00244 for( int i = 0; i <= dimension; ++i )
00245 entityNumbers_[ i ].release();
00246 }
00247
00248 private:
00249 template< int codim >
00250 static IndexStack &getIndexStack ( const IndexVectorPointer &dofVector )
00251 {
00252 IndexStack *indexStack;
00253 if( IndexVectorPointer::supportsAdaptationData )
00254 indexStack = dofVector.template getAdaptationData< IndexStack >();
00255 else
00256 indexStack = &Alberta::currentIndexStack[ codim ];
00257 assert( indexStack != 0 );
00258 return *indexStack;
00259 }
00260
00261 private:
00262 #ifdef INDEXSET_HAS_ITERATORS
00263
00264 const Grid &grid_;
00265 #endif
00266
00267
00268 IndexStack indexStack_[ dimension+1 ];
00269
00270
00271 IndexVectorPointer entityNumbers_[ dimension+1 ];
00272
00273
00274 Alberta::CodimTable< DofAccess, dimension > dofAccess_;
00275
00276
00277 std::vector< GeometryType > geomTypes_[ dimension+1 ];
00278 };
00279
00280
00281
00282 template< int dim, int dimworld >
00283 inline AlbertaGridHierarchicIndexSet< dim, dimworld >
00284 ::AlbertaGridHierarchicIndexSet ( const Grid &grid )
00285 #ifdef INDEXSET_HAS_ITERATORS
00286 : grid_( grid )
00287 #endif
00288 {
00289 for( int codim = 0; codim <= dimension; ++codim )
00290 {
00291 const GeometryType type( GeometryType::simplex, dimension - codim );
00292 geomTypes_[ codim ].push_back( type );
00293 }
00294 }
00295
00296
00297
00298
00299
00300
00301 template< int dim, int dimworld >
00302 template< int codim >
00303 class AlbertaGridHierarchicIndexSet< dim, dimworld >::DofAccess
00304 : public Alberta::DofAccess< dim, codim >
00305 {
00306 typedef Alberta::DofAccess< dim, codim > Base;
00307
00308 public:
00309 DofAccess ()
00310 {}
00311
00312 explicit DofAccess ( const Alberta::DofSpace *dofSpace )
00313 : Base( dofSpace )
00314 {}
00315 };
00316
00317
00318
00319
00320
00321
00322 template< int dim, int dimworld >
00323 class AlbertaGridHierarchicIndexSet< dim, dimworld >::InitEntityNumber
00324 {
00325 IndexStack &indexStack_;
00326
00327 public:
00328 InitEntityNumber ( IndexStack &indexStack )
00329 : indexStack_( indexStack )
00330 {}
00331
00332 void operator() ( int &dof )
00333 {
00334 dof = indexStack_.getIndex();
00335 }
00336 };
00337
00338
00339
00340
00341
00342
00343 template< int dim, int dimworld >
00344 template< int codim >
00345 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CreateEntityNumbers
00346 {
00347 static void setup ( AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet )
00348 {
00349 IndexVectorPointer &entityNumbers = indexSet.entityNumbers_[ codim ];
00350
00351 Int2Type< codim > codimVariable;
00352 indexSet.dofAccess_[ codimVariable ] = DofAccess< codim >( entityNumbers.dofSpace() );
00353
00354 entityNumbers.template setupInterpolation< RefineNumbering< codim > >();
00355 entityNumbers.template setupRestriction< CoarsenNumbering< codim > >();
00356 entityNumbers.setAdaptationData( &(indexSet.indexStack_[ codim ]) );
00357 }
00358
00359 static void apply ( const Alberta::HierarchyDofNumbering< dimension > &dofNumbering,
00360 AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet )
00361 {
00362 const Alberta::DofSpace *dofSpace = dofNumbering.dofSpace( codim );
00363
00364 std::ostringstream s;
00365 s << "Numbering for codimension " << codim;
00366 indexSet.entityNumbers_[ codim ].create( dofSpace, s.str() );
00367
00368 InitEntityNumber init( indexSet.indexStack_[ codim ] );
00369 indexSet.entityNumbers_[ codim ].forEach( init );
00370
00371 setup( indexSet );
00372 }
00373
00374 static void apply ( const std::string &filename,
00375 const Alberta::MeshPointer< dimension > &mesh,
00376 AlbertaGridHierarchicIndexSet< dim, dimworld > &indexSet )
00377 {
00378 std::ostringstream s;
00379 s << filename << ".cd" << codim;
00380 indexSet.entityNumbers_[ codim ].read( s.str(), mesh );
00381
00382 const int maxIndex = max( indexSet.entityNumbers_[ codim ] );
00383 indexSet.indexStack_[ codim ].setMaxIndex( maxIndex + 1 );
00384
00385 setup( indexSet );
00386 }
00387 };
00388
00389
00390
00391
00392
00393
00394 template< int dim, int dimworld >
00395 template< int codim >
00396 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::RefineNumbering
00397 {
00398 static const int dimension = dim;
00399 static const int codimension = codim;
00400
00401 private:
00402 typedef Alberta::Patch< dimension > Patch;
00403 typedef Alberta::DofAccess< dimension, codimension > DofAccess;
00404
00405 IndexStack &indexStack_;
00406 IndexVectorPointer dofVector_;
00407 DofAccess dofAccess_;
00408
00409 explicit RefineNumbering ( const IndexVectorPointer &dofVector )
00410 : indexStack_( getIndexStack< codimension >( dofVector ) ),
00411 dofVector_( dofVector ),
00412 dofAccess_( dofVector.dofSpace() )
00413 {}
00414
00415 public:
00416 void operator() ( const Alberta::Element *child, int subEntity )
00417 {
00418 int *const array = (int *)dofVector_;
00419 const int dof = dofAccess_( child, subEntity );
00420 array[ dof ] = indexStack_.getIndex();
00421 }
00422
00423 static void interpolateVector ( const IndexVectorPointer &dofVector,
00424 const Patch &patch )
00425 {
00426 RefineNumbering refineNumbering( dofVector );
00427 patch.forEachInteriorSubChild( refineNumbering );
00428 }
00429 };
00430
00431
00432
00433
00434
00435
00436 template< int dim, int dimworld >
00437 template< int codim >
00438 struct AlbertaGridHierarchicIndexSet< dim, dimworld >::CoarsenNumbering
00439 {
00440 static const int dimension = dim;
00441 static const int codimension = codim;
00442
00443 private:
00444 typedef Alberta::Patch< dimension > Patch;
00445 typedef Alberta::DofAccess< dimension, codimension > DofAccess;
00446
00447 IndexStack &indexStack_;
00448 IndexVectorPointer dofVector_;
00449 DofAccess dofAccess_;
00450
00451 explicit CoarsenNumbering ( const IndexVectorPointer &dofVector )
00452 : indexStack_( getIndexStack< codimension >( dofVector ) ),
00453 dofVector_( dofVector ),
00454 dofAccess_( dofVector.dofSpace() )
00455 {}
00456
00457 public:
00458 void operator() ( const Alberta::Element *child, int subEntity )
00459 {
00460 int *const array = (int *)dofVector_;
00461 const int dof = dofAccess_( child, subEntity );
00462 indexStack_.freeIndex( array[ dof ] );
00463 }
00464
00465 static void restrictVector ( const IndexVectorPointer &dofVector,
00466 const Patch &patch )
00467 {
00468 CoarsenNumbering coarsenNumbering( dofVector );
00469 patch.forEachInteriorSubChild( coarsenNumbering );
00470 }
00471 };
00472
00473
00474
00475
00476
00477
00479 template< int dim, int dimworld >
00480 class AlbertaGridIdSet
00481 : public IdSetDefaultImplementation
00482 < AlbertaGrid< dim, dimworld >, AlbertaGridIdSet< dim, dimworld >, unsigned int >
00483 {
00484 typedef AlbertaGridIdSet< dim, dimworld > This;
00485 typedef AlbertaGrid< dim, dimworld > Grid;
00486 typedef IdSetDefaultImplementation< Grid, This, unsigned int > Base;
00487
00488 friend class AlbertaGrid< dim, dimworld >;
00489
00490 static const int codimShift = 30;
00491 static const int maxCodimSize = (1 << codimShift);
00492
00493 typedef typename Grid::HierarchicIndexSet HierarchicIndexSet;
00494
00495 const HierarchicIndexSet &hIndexSet_;
00496
00498 AlbertaGridIdSet ( const HierarchicIndexSet &hIndexSet )
00499 : hIndexSet_( hIndexSet )
00500 {}
00501
00502 public:
00504 typedef typename Base::IdType IdType;
00505
00507 template< class Entity >
00508 IdType id ( const Entity &e ) const
00509 {
00510 const int codim = Entity::codimension;
00511 return id< codim >( e );
00512 }
00513
00515 template< int codim >
00516 IdType id ( const typename Grid::template Codim< codim >::Entity &e ) const
00517 {
00518 assert( hIndexSet_.size( codim ) < maxCodimSize );
00519 const IdType index = hIndexSet_.index( e );
00520 return ((IdType)codim << codimShift) + index;
00521 }
00522
00524 template< int codim >
00525 IdType subId ( const typename Grid::template Codim< 0 >::Entity &e, int i ) const
00526 {
00527 assert( hIndexSet_.size( codim ) < maxCodimSize );
00528 const IdType index = hIndexSet_.template subIndex< codim >( e, i );
00529 return ((IdType)codim << codimShift) + index;
00530 }
00531 };
00532
00533 }
00534
00535 #endif // HAVE_ALBERTA
00536
00537 #endif