00001 #ifndef DUNE_ALBERTA_DOFADMIN_HH
00002 #define DUNE_ALBERTA_DOFADMIN_HH
00003
00004 #include <dune/grid/albertagrid/misc.hh>
00005 #include <dune/grid/albertagrid/elementinfo.hh>
00006
00007 #if HAVE_ALBERTA
00008
00009 namespace Dune
00010 {
00011
00012 namespace Alberta
00013 {
00014
00015
00016
00017
00018 template< int dim >
00019 class MeshPointer;
00020
00021
00022
00023
00024
00025
00026 template< int dim, int codim >
00027 class DofAccess
00028 {
00029 static const int codimtype = CodimType< dim, codim >::value;
00030
00031 public:
00032 static const int numSubEntities = NumSubEntities< dim, codim >::value;
00033
00034 static const int dimension = dim;
00035 static const int codimension = codim;
00036
00037 typedef Alberta::ElementInfo< dimension > ElementInfo;
00038
00039 private:
00040 int node_;
00041 int index_;
00042 #ifndef NDEBUG
00043 int count_;
00044 #endif
00045
00046 public:
00047 DofAccess ()
00048 : node_( -1 )
00049 {}
00050
00051 explicit DofAccess ( const DofSpace *dofSpace )
00052 {
00053 node_ = dofSpace->admin->mesh->node[ codimtype ];
00054 index_ = dofSpace->admin->n0_dof[ codimtype ];
00055 #ifndef NDEBUG
00056 count_ = dofSpace->admin->n_dof[ codimtype ];
00057 #endif
00058 }
00059
00060 int operator() ( const Element *element, int subEntity, int i ) const
00061 {
00062 #ifndef NDEBUG
00063 assert( node_ != -1 );
00064 assert( subEntity < numSubEntities );
00065 assert( i < count_ );
00066 #endif
00067 return element->dof[ node_ + subEntity ][ index_ + i ];
00068 }
00069
00070 int operator() ( const Element *element, int subEntity ) const
00071 {
00072 return (*this)( element, subEntity, 0 );
00073 }
00074
00075 int operator() ( const ElementInfo &elementInfo, int subEntity, int i ) const
00076 {
00077 return (*this)( elementInfo.el(), subEntity, i );
00078 }
00079
00080 int operator() ( const ElementInfo &elementInfo, int subEntity ) const
00081 {
00082 return (*this)( elementInfo.el(), subEntity );
00083 }
00084 };
00085
00086
00087
00088
00089
00090
00091 template< int dim >
00092 class HierarchyDofNumbering
00093 {
00094 typedef HierarchyDofNumbering< dim > This;
00095
00096 public:
00097 static const int dimension = dim;
00098
00099 typedef Alberta::MeshPointer< dimension > MeshPointer;
00100 typedef Alberta::ElementInfo< dimension > ElementInfo;
00101
00102 private:
00103 #if DUNE_ALBERTA_VERSION >= 0x200
00104 static const int nNodeTypes = N_NODE_TYPES;
00105 #else
00106 static const int nNodeTypes = DIM+1;
00107 #endif
00108
00109 template< int codim >
00110 struct CreateDofSpace;
00111
00112 template< int codim >
00113 struct CacheDofSpace;
00114
00115 typedef std::pair< int, int > Cache;
00116
00117 MeshPointer mesh_;
00118 const DofSpace *emptySpace_;
00119 const DofSpace *dofSpace_[ dimension+1 ];
00120 Cache cache_[ dimension+1 ];
00121
00122 public:
00123 HierarchyDofNumbering ()
00124 {}
00125
00126 private:
00127 HierarchyDofNumbering ( const This & );
00128 This &operator= ( const This & );
00129
00130 public:
00131 ~HierarchyDofNumbering ()
00132 {
00133 release();
00134 }
00135
00136 int operator() ( const Element *element, int codim, unsigned int subEntity ) const
00137 {
00138 assert( !(*this) == false );
00139 assert( (codim >= 0) && (codim <= dimension) );
00140 const Cache &cache = cache_[ codim ];
00141 return element->dof[ cache.first + subEntity ][ cache.second ];
00142 }
00143
00144 int operator() ( const ElementInfo &element, int codim, unsigned int subEntity ) const
00145 {
00146 return (*this)( element.el(), codim, subEntity );
00147 }
00148
00149 bool operator! () const
00150 {
00151 return !mesh_;
00152 }
00153
00154 const DofSpace *dofSpace ( int codim ) const
00155 {
00156 assert( !(*this) == false );
00157 assert( (codim >= 0) && (codim <= dimension) );
00158 return dofSpace_[ codim ];
00159 }
00160
00161 const DofSpace *emptyDofSpace () const
00162 {
00163 assert( !(*this) == false );
00164 return emptySpace_;
00165 }
00166
00167 const MeshPointer &mesh () const
00168 {
00169 return mesh_;
00170 }
00171
00172 int size ( int codim ) const
00173 {
00174 return dofSpace( codim )->admin->size;
00175 }
00176
00177 void create ( const MeshPointer &mesh );
00178
00179 void release ()
00180 {
00181 if( !(*this) )
00182 return;
00183
00184 for( int codim = 0; codim <= dimension; ++codim )
00185 freeDofSpace( dofSpace_[ codim ] );
00186 freeDofSpace( emptySpace_ );
00187 mesh_ = MeshPointer();
00188 }
00189
00190 private:
00191 static const DofSpace *createEmptyDofSpace ( const MeshPointer &mesh );
00192 static const DofSpace *createDofSpace ( const MeshPointer &mesh,
00193 const std::string &name,
00194 const int (&ndof)[ nNodeTypes ] );
00195 static void freeDofSpace ( const DofSpace *dofSpace );
00196 };
00197
00198
00199
00200 template< int dim >
00201 inline void
00202 HierarchyDofNumbering< dim >::create ( const MeshPointer &mesh )
00203 {
00204 release();
00205
00206 if( !mesh )
00207 return;
00208
00209 mesh_ = mesh;
00210 ForLoop< CreateDofSpace, 0, dimension >::apply( mesh_, dofSpace_ );
00211 ForLoop< CacheDofSpace, 0, dimension >::apply( dofSpace_, cache_ );
00212
00213 emptySpace_ = createEmptyDofSpace( mesh_ );
00214 for( int i = 0; i < nNodeTypes; ++i )
00215 assert( emptySpace_->admin->n_dof[ i ] == 0 );
00216 }
00217
00218
00219
00220 template< int dim >
00221 inline const DofSpace *
00222 HierarchyDofNumbering< dim >::createEmptyDofSpace ( const MeshPointer &mesh )
00223 {
00224 int ndof[ nNodeTypes ];
00225 for( int i = 0; i < nNodeTypes; ++i )
00226 ndof[ i ] = 0;
00227 std::string name = "Empty";
00228 return createDofSpace( mesh, name, ndof );
00229 }
00230
00231
00232 #if DUNE_ALBERTA_VERSION >= 0x201
00233 template< int dim >
00234 inline const DofSpace *
00235 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
00236 const std::string &name,
00237 const int (&ndof)[ nNodeTypes ] )
00238 {
00239 const ALBERTA FLAGS flags = ADM_PRESERVE_COARSE_DOFS;
00240 return ALBERTA get_dof_space ( mesh, name.c_str(), ndof, flags );
00241 }
00242 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00243
00244 #if DUNE_ALBERTA_VERSION == 0x200
00245 template< int dim >
00246 inline const DofSpace *
00247 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
00248 const std::string &name,
00249 const int (&ndof)[ nNodeTypes ] )
00250 {
00251 return ALBERTA get_fe_space ( mesh, name.c_str(), ndof, NULL, 1 );
00252 }
00253 #endif // #if DUNE_ALBERTA_VERSION == 0x200
00254
00255 #if DUNE_ALBERTA_VERSION < 0x200
00256 template< int dim >
00257 inline const DofSpace *
00258 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
00259 const std::string &name,
00260 const int (&ndof)[ nNodeTypes ] )
00261 {
00262 return ALBERTA get_fe_space ( mesh, name.c_str(), ndof, NULL );
00263 }
00264 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00265
00266
00267 #if DUNE_ALBERTA_VERSION >= 0x201
00268 template< int dim >
00269 inline void
00270 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
00271 {
00272 ALBERTA free_fe_space( dofSpace );
00273 }
00274 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00275
00276 #if DUNE_ALBERTA_VERSION == 0x200
00277 template< int dim >
00278 inline void
00279 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
00280 {
00281
00282 ALBERTA free_fe_space( const_cast< DofSpace * >( dofSpace ) );
00283 }
00284 #endif // #if DUNE_ALBERTA_VERSION == 0x200
00285
00286 #if DUNE_ALBERTA_VERSION < 0x200
00287 template< int dim >
00288 inline void
00289 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
00290 {
00291 if( dofSpace->name != NULL )
00292 free( (char *)(dofSpace->name) );
00293 memFree< const DofSpace >( dofSpace, 1 );
00294 }
00295 #endif
00296
00297
00298
00299
00300
00301
00302 template< int dim >
00303 template< int codim >
00304 struct HierarchyDofNumbering< dim >::CreateDofSpace
00305 {
00306 static void apply ( const MeshPointer &mesh, const DofSpace *(&dofSpace)[ dim+1 ] )
00307 {
00308 int ndof[ nNodeTypes ];
00309 for( int i = 0; i < nNodeTypes; ++i )
00310 ndof[ i ] = 0;
00311 ndof[ CodimType< dim, codim >::value ] = 1;
00312
00313 std::string name = "Codimension ";
00314 name += (char)(codim + '0');
00315
00316 dofSpace[ codim ] = createDofSpace( mesh, name, ndof );
00317 assert( dofSpace[ codim ] != NULL );
00318 }
00319 };
00320
00321
00322
00323
00324
00325
00326 template< int dim >
00327 template< int codim >
00328 struct HierarchyDofNumbering< dim >::CacheDofSpace
00329 {
00330 static void apply ( const DofSpace *(&dofSpace)[ dim+1 ], Cache (&cache)[ dim+1 ] )
00331 {
00332 const int codimtype = CodimType< dim, codim >::value;
00333 cache[ codim ].first = dofSpace[ codim ]->mesh->node[ codimtype ];
00334 cache[ codim ].second = dofSpace[ codim ]->admin->n0_dof[ codimtype ];
00335 }
00336 };
00337 }
00338
00339 }
00340
00341 #endif // #if HAVE_ALBERTA
00342
00343 #endif