- Home
- About DUNE
- Download
- Documentation
- Community
- Development
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 // External Forward Declarations 00016 // ----------------------------- 00017 00018 template< int dim > 00019 class MeshPointer; 00020 00021 00022 00023 // DofAccess 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 // HierarchyDofNumbering 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 static const int nNodeTypes = N_NODE_TYPES; 00104 00105 template< int codim > 00106 struct CreateDofSpace; 00107 00108 template< int codim > 00109 struct CacheDofSpace; 00110 00111 typedef std::pair< int, int > Cache; 00112 00113 MeshPointer mesh_; 00114 const DofSpace *emptySpace_; 00115 const DofSpace *dofSpace_[ dimension+1 ]; 00116 Cache cache_[ dimension+1 ]; 00117 00118 public: 00119 HierarchyDofNumbering () 00120 {} 00121 00122 private: 00123 HierarchyDofNumbering ( const This & ); 00124 This &operator= ( const This & ); 00125 00126 public: 00127 ~HierarchyDofNumbering () 00128 { 00129 release(); 00130 } 00131 00132 int operator() ( const Element *element, int codim, unsigned int subEntity ) const 00133 { 00134 assert( !(*this) == false ); 00135 assert( (codim >= 0) && (codim <= dimension) ); 00136 const Cache &cache = cache_[ codim ]; 00137 return element->dof[ cache.first + subEntity ][ cache.second ]; 00138 } 00139 00140 int operator() ( const ElementInfo &element, int codim, unsigned int subEntity ) const 00141 { 00142 return (*this)( element.el(), codim, subEntity ); 00143 } 00144 00145 bool operator! () const 00146 { 00147 return !mesh_; 00148 } 00149 00150 const DofSpace *dofSpace ( int codim ) const 00151 { 00152 assert( !(*this) == false ); 00153 assert( (codim >= 0) && (codim <= dimension) ); 00154 return dofSpace_[ codim ]; 00155 } 00156 00157 const DofSpace *emptyDofSpace () const 00158 { 00159 assert( !(*this) == false ); 00160 return emptySpace_; 00161 } 00162 00163 const MeshPointer &mesh () const 00164 { 00165 return mesh_; 00166 } 00167 00168 int size ( int codim ) const 00169 { 00170 return dofSpace( codim )->admin->size; 00171 } 00172 00173 void create ( const MeshPointer &mesh ); 00174 00175 void release () 00176 { 00177 if( !(*this) ) 00178 return; 00179 00180 for( int codim = 0; codim <= dimension; ++codim ) 00181 freeDofSpace( dofSpace_[ codim ] ); 00182 freeDofSpace( emptySpace_ ); 00183 mesh_ = MeshPointer(); 00184 } 00185 00186 private: 00187 static const DofSpace *createEmptyDofSpace ( const MeshPointer &mesh ); 00188 static const DofSpace *createDofSpace ( const MeshPointer &mesh, 00189 const std::string &name, 00190 const int (&ndof)[ nNodeTypes ], 00191 const bool periodic = false ); 00192 static void freeDofSpace ( const DofSpace *dofSpace ); 00193 }; 00194 00195 00196 00197 template< int dim > 00198 inline void 00199 HierarchyDofNumbering< dim >::create ( const MeshPointer &mesh ) 00200 { 00201 release(); 00202 00203 if( !mesh ) 00204 return; 00205 00206 mesh_ = mesh; 00207 ForLoop< CreateDofSpace, 0, dimension >::apply( mesh_, dofSpace_ ); 00208 ForLoop< CacheDofSpace, 0, dimension >::apply( dofSpace_, cache_ ); 00209 00210 emptySpace_ = createEmptyDofSpace( mesh_ ); 00211 for( int i = 0; i < nNodeTypes; ++i ) 00212 assert( emptySpace_->admin->n_dof[ i ] == 0 ); 00213 } 00214 00215 00216 00217 template< int dim > 00218 inline const DofSpace * 00219 HierarchyDofNumbering< dim >::createEmptyDofSpace ( const MeshPointer &mesh ) 00220 { 00221 int ndof[ nNodeTypes ]; 00222 for( int i = 0; i < nNodeTypes; ++i ) 00223 ndof[ i ] = 0; 00224 std::string name = "Empty"; 00225 return createDofSpace( mesh, name, ndof ); 00226 } 00227 00228 00229 #if DUNE_ALBERTA_VERSION >= 0x300 00230 template< int dim > 00231 inline const DofSpace * 00232 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh, 00233 const std::string &name, 00234 const int (&ndof)[ nNodeTypes ], 00235 const bool periodic ) 00236 { 00237 const ALBERTA FLAGS flags 00238 = ADM_PRESERVE_COARSE_DOFS | (periodic ? ADM_PERIODIC : 0); 00239 return ALBERTA get_dof_space ( mesh, name.c_str(), ndof, flags ); 00240 } 00241 #endif // #if DUNE_ALBERTA_VERSION >= 0x300 00242 00243 #if DUNE_ALBERTA_VERSION == 0x200 00244 template< int dim > 00245 inline const DofSpace * 00246 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh, 00247 const std::string &name, 00248 const int (&ndof)[ nNodeTypes ], 00249 const bool periodic ) 00250 { 00251 return ALBERTA get_fe_space ( mesh, name.c_str(), ndof, NULL, 1 ); 00252 } 00253 #endif // #if DUNE_ALBERTA_VERSION == 0x200 00254 00255 00256 #if DUNE_ALBERTA_VERSION >= 0x300 00257 template< int dim > 00258 inline void 00259 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace ) 00260 { 00261 ALBERTA free_fe_space( dofSpace ); 00262 } 00263 #endif // #if DUNE_ALBERTA_VERSION >= 0x300 00264 00265 #if DUNE_ALBERTA_VERSION == 0x200 00266 template< int dim > 00267 inline void 00268 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace ) 00269 { 00270 // the const cast is needed due to a bug in ALBERTA 2.0 00271 ALBERTA free_fe_space( const_cast< DofSpace * >( dofSpace ) ); 00272 } 00273 #endif // #if DUNE_ALBERTA_VERSION == 0x200 00274 00275 00276 00277 // HierarchyDofNumbering::CreateDofSpace 00278 // ------------------------------------- 00279 00280 template< int dim > 00281 template< int codim > 00282 struct HierarchyDofNumbering< dim >::CreateDofSpace 00283 { 00284 static void apply ( const MeshPointer &mesh, const DofSpace *(&dofSpace)[ dim+1 ] ) 00285 { 00286 int ndof[ nNodeTypes ]; 00287 for( int i = 0; i < nNodeTypes; ++i ) 00288 ndof[ i ] = 0; 00289 ndof[ CodimType< dim, codim >::value ] = 1; 00290 00291 std::string name = "Codimension "; 00292 name += (char)(codim + '0'); 00293 00294 dofSpace[ codim ] = createDofSpace( mesh, name, ndof ); 00295 assert( dofSpace[ codim ] != NULL ); 00296 } 00297 }; 00298 00299 00300 00301 // HierarchyDofNumbering::CacheDofSpace 00302 // ------------------------------------- 00303 00304 template< int dim > 00305 template< int codim > 00306 struct HierarchyDofNumbering< dim >::CacheDofSpace 00307 { 00308 static void apply ( const DofSpace *(&dofSpace)[ dim+1 ], Cache (&cache)[ dim+1 ] ) 00309 { 00310 const int codimtype = CodimType< dim, codim >::value; 00311 cache[ codim ].first = dofSpace[ codim ]->mesh->node[ codimtype ]; 00312 cache[ codim ].second = dofSpace[ codim ]->admin->n0_dof[ codimtype ]; 00313 } 00314 }; 00315 } 00316 00317 } 00318 00319 #endif // #if HAVE_ALBERTA 00320 00321 #endif
Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].