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 const bool periodic = false );
00196 static void freeDofSpace ( const DofSpace *dofSpace );
00197 };
00198
00199
00200
00201 template< int dim >
00202 inline void
00203 HierarchyDofNumbering< dim >::create ( const MeshPointer &mesh )
00204 {
00205 release();
00206
00207 if( !mesh )
00208 return;
00209
00210 mesh_ = mesh;
00211 ForLoop< CreateDofSpace, 0, dimension >::apply( mesh_, dofSpace_ );
00212 ForLoop< CacheDofSpace, 0, dimension >::apply( dofSpace_, cache_ );
00213
00214 emptySpace_ = createEmptyDofSpace( mesh_ );
00215 for( int i = 0; i < nNodeTypes; ++i )
00216 assert( emptySpace_->admin->n_dof[ i ] == 0 );
00217 }
00218
00219
00220
00221 template< int dim >
00222 inline const DofSpace *
00223 HierarchyDofNumbering< dim >::createEmptyDofSpace ( const MeshPointer &mesh )
00224 {
00225 int ndof[ nNodeTypes ];
00226 for( int i = 0; i < nNodeTypes; ++i )
00227 ndof[ i ] = 0;
00228 std::string name = "Empty";
00229 return createDofSpace( mesh, name, ndof );
00230 }
00231
00232
00233 #if DUNE_ALBERTA_VERSION >= 0x201
00234 template< int dim >
00235 inline const DofSpace *
00236 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
00237 const std::string &name,
00238 const int (&ndof)[ nNodeTypes ],
00239 const bool periodic )
00240 {
00241 const ALBERTA FLAGS flags
00242 = ADM_PRESERVE_COARSE_DOFS | (periodic ? ADM_PERIODIC : 0);
00243 return ALBERTA get_dof_space ( mesh, name.c_str(), ndof, flags );
00244 }
00245 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00246
00247 #if DUNE_ALBERTA_VERSION == 0x200
00248 template< int dim >
00249 inline const DofSpace *
00250 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
00251 const std::string &name,
00252 const int (&ndof)[ nNodeTypes ],
00253 const bool periodic )
00254 {
00255 return ALBERTA get_fe_space ( mesh, name.c_str(), ndof, NULL, 1 );
00256 }
00257 #endif // #if DUNE_ALBERTA_VERSION == 0x200
00258
00259 #if DUNE_ALBERTA_VERSION < 0x200
00260 template< int dim >
00261 inline const DofSpace *
00262 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh,
00263 const std::string &name,
00264 const int (&ndof)[ nNodeTypes ],
00265 const bool periodic )
00266 {
00267 return ALBERTA get_fe_space ( mesh, name.c_str(), ndof, NULL );
00268 }
00269 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00270
00271
00272 #if DUNE_ALBERTA_VERSION >= 0x201
00273 template< int dim >
00274 inline void
00275 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
00276 {
00277 ALBERTA free_fe_space( dofSpace );
00278 }
00279 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00280
00281 #if DUNE_ALBERTA_VERSION == 0x200
00282 template< int dim >
00283 inline void
00284 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
00285 {
00286
00287 ALBERTA free_fe_space( const_cast< DofSpace * >( dofSpace ) );
00288 }
00289 #endif // #if DUNE_ALBERTA_VERSION == 0x200
00290
00291 #if DUNE_ALBERTA_VERSION < 0x200
00292 template< int dim >
00293 inline void
00294 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace )
00295 {
00296 if( dofSpace->name != NULL )
00297 free( (char *)(dofSpace->name) );
00298 memFree< const DofSpace >( dofSpace, 1 );
00299 }
00300 #endif
00301
00302
00303
00304
00305
00306
00307 template< int dim >
00308 template< int codim >
00309 struct HierarchyDofNumbering< dim >::CreateDofSpace
00310 {
00311 static void apply ( const MeshPointer &mesh, const DofSpace *(&dofSpace)[ dim+1 ] )
00312 {
00313 int ndof[ nNodeTypes ];
00314 for( int i = 0; i < nNodeTypes; ++i )
00315 ndof[ i ] = 0;
00316 ndof[ CodimType< dim, codim >::value ] = 1;
00317
00318 std::string name = "Codimension ";
00319 name += (char)(codim + '0');
00320
00321 dofSpace[ codim ] = createDofSpace( mesh, name, ndof );
00322 assert( dofSpace[ codim ] != NULL );
00323 }
00324 };
00325
00326
00327
00328
00329
00330
00331 template< int dim >
00332 template< int codim >
00333 struct HierarchyDofNumbering< dim >::CacheDofSpace
00334 {
00335 static void apply ( const DofSpace *(&dofSpace)[ dim+1 ], Cache (&cache)[ dim+1 ] )
00336 {
00337 const int codimtype = CodimType< dim, codim >::value;
00338 cache[ codim ].first = dofSpace[ codim ]->mesh->node[ codimtype ];
00339 cache[ codim ].second = dofSpace[ codim ]->admin->n0_dof[ codimtype ];
00340 }
00341 };
00342 }
00343
00344 }
00345
00346 #endif // #if HAVE_ALBERTA
00347
00348 #endif