dune-grid
2.1.1
|
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 00043 public: 00044 DofAccess () 00045 : node_( -1 ) 00046 {} 00047 00048 explicit DofAccess ( const DofSpace *dofSpace ) 00049 { 00050 node_ = dofSpace->admin->mesh->node[ codimtype ]; 00051 index_ = dofSpace->admin->n0_dof[ codimtype ]; 00052 } 00053 00054 int operator() ( const Element *element, int subEntity, int i ) const 00055 { 00056 assert( node_ != -1 ); 00057 assert( subEntity < numSubEntities ); 00058 return element->dof[ node_ + subEntity ][ index_ + i ]; 00059 } 00060 00061 int operator() ( const Element *element, int subEntity ) const 00062 { 00063 return (*this)( element, subEntity, 0 ); 00064 } 00065 00066 int operator() ( const ElementInfo &elementInfo, int subEntity, int i ) const 00067 { 00068 return (*this)( elementInfo.el(), subEntity, i ); 00069 } 00070 00071 int operator() ( const ElementInfo &elementInfo, int subEntity ) const 00072 { 00073 return (*this)( elementInfo.el(), subEntity ); 00074 } 00075 }; 00076 00077 00078 00079 // HierarchyDofNumbering 00080 // --------------------- 00081 00082 template< int dim > 00083 class HierarchyDofNumbering 00084 { 00085 typedef HierarchyDofNumbering< dim > This; 00086 00087 public: 00088 static const int dimension = dim; 00089 00090 typedef Alberta::MeshPointer< dimension > MeshPointer; 00091 typedef Alberta::ElementInfo< dimension > ElementInfo; 00092 00093 private: 00094 static const int nNodeTypes = N_NODE_TYPES; 00095 00096 template< int codim > 00097 struct CreateDofSpace; 00098 00099 template< int codim > 00100 struct CacheDofSpace; 00101 00102 typedef std::pair< int, int > Cache; 00103 00104 MeshPointer mesh_; 00105 const DofSpace *emptySpace_; 00106 const DofSpace *dofSpace_[ dimension+1 ]; 00107 Cache cache_[ dimension+1 ]; 00108 00109 public: 00110 HierarchyDofNumbering () 00111 {} 00112 00113 private: 00114 HierarchyDofNumbering ( const This & ); 00115 This &operator= ( const This & ); 00116 00117 public: 00118 ~HierarchyDofNumbering () 00119 { 00120 release(); 00121 } 00122 00123 int operator() ( const Element *element, int codim, unsigned int subEntity ) const 00124 { 00125 assert( !(*this) == false ); 00126 assert( (codim >= 0) && (codim <= dimension) ); 00127 const Cache &cache = cache_[ codim ]; 00128 return element->dof[ cache.first + subEntity ][ cache.second ]; 00129 } 00130 00131 int operator() ( const ElementInfo &element, int codim, unsigned int subEntity ) const 00132 { 00133 return (*this)( element.el(), codim, subEntity ); 00134 } 00135 00136 bool operator! () const 00137 { 00138 return !mesh_; 00139 } 00140 00141 const DofSpace *dofSpace ( int codim ) const 00142 { 00143 assert( !(*this) == false ); 00144 assert( (codim >= 0) && (codim <= dimension) ); 00145 return dofSpace_[ codim ]; 00146 } 00147 00148 const DofSpace *emptyDofSpace () const 00149 { 00150 assert( !(*this) == false ); 00151 return emptySpace_; 00152 } 00153 00154 const MeshPointer &mesh () const 00155 { 00156 return mesh_; 00157 } 00158 00159 int size ( int codim ) const 00160 { 00161 return dofSpace( codim )->admin->size; 00162 } 00163 00164 void create ( const MeshPointer &mesh ); 00165 00166 void release () 00167 { 00168 if( !(*this) ) 00169 return; 00170 00171 for( int codim = 0; codim <= dimension; ++codim ) 00172 freeDofSpace( dofSpace_[ codim ] ); 00173 freeDofSpace( emptySpace_ ); 00174 mesh_ = MeshPointer(); 00175 } 00176 00177 private: 00178 static const DofSpace *createEmptyDofSpace ( const MeshPointer &mesh ); 00179 static const DofSpace *createDofSpace ( const MeshPointer &mesh, 00180 const std::string &name, 00181 const int (&ndof)[ nNodeTypes ], 00182 const bool periodic = false ); 00183 static void freeDofSpace ( const DofSpace *dofSpace ); 00184 }; 00185 00186 00187 00188 template< int dim > 00189 inline void 00190 HierarchyDofNumbering< dim >::create ( const MeshPointer &mesh ) 00191 { 00192 release(); 00193 00194 if( !mesh ) 00195 return; 00196 00197 mesh_ = mesh; 00198 ForLoop< CreateDofSpace, 0, dimension >::apply( mesh_, dofSpace_ ); 00199 ForLoop< CacheDofSpace, 0, dimension >::apply( dofSpace_, cache_ ); 00200 00201 emptySpace_ = createEmptyDofSpace( mesh_ ); 00202 for( int i = 0; i < nNodeTypes; ++i ) 00203 assert( emptySpace_->admin->n_dof[ i ] == 0 ); 00204 } 00205 00206 00207 00208 template< int dim > 00209 inline const DofSpace * 00210 HierarchyDofNumbering< dim >::createEmptyDofSpace ( const MeshPointer &mesh ) 00211 { 00212 int ndof[ nNodeTypes ]; 00213 for( int i = 0; i < nNodeTypes; ++i ) 00214 ndof[ i ] = 0; 00215 std::string name = "Empty"; 00216 return createDofSpace( mesh, name, ndof ); 00217 } 00218 00219 00220 #if DUNE_ALBERTA_VERSION >= 0x300 00221 template< int dim > 00222 inline const DofSpace * 00223 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh, 00224 const std::string &name, 00225 const int (&ndof)[ nNodeTypes ], 00226 const bool periodic ) 00227 { 00228 const ALBERTA FLAGS flags 00229 = ADM_PRESERVE_COARSE_DOFS | (periodic ? ADM_PERIODIC : 0); 00230 return ALBERTA get_dof_space ( mesh, name.c_str(), ndof, flags ); 00231 } 00232 #endif // #if DUNE_ALBERTA_VERSION >= 0x300 00233 00234 #if DUNE_ALBERTA_VERSION == 0x200 00235 template< int dim > 00236 inline const DofSpace * 00237 HierarchyDofNumbering< dim >::createDofSpace ( const MeshPointer &mesh, 00238 const std::string &name, 00239 const int (&ndof)[ nNodeTypes ], 00240 const bool periodic ) 00241 { 00242 return ALBERTA get_fe_space ( mesh, name.c_str(), ndof, NULL, 1 ); 00243 } 00244 #endif // #if DUNE_ALBERTA_VERSION == 0x200 00245 00246 00247 #if DUNE_ALBERTA_VERSION >= 0x300 00248 template< int dim > 00249 inline void 00250 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace ) 00251 { 00252 ALBERTA free_fe_space( dofSpace ); 00253 } 00254 #endif // #if DUNE_ALBERTA_VERSION >= 0x300 00255 00256 #if DUNE_ALBERTA_VERSION == 0x200 00257 template< int dim > 00258 inline void 00259 HierarchyDofNumbering< dim >::freeDofSpace ( const DofSpace *dofSpace ) 00260 { 00261 // the const cast is needed due to a bug in ALBERTA 2.0 00262 ALBERTA free_fe_space( const_cast< DofSpace * >( dofSpace ) ); 00263 } 00264 #endif // #if DUNE_ALBERTA_VERSION == 0x200 00265 00266 00267 00268 // HierarchyDofNumbering::CreateDofSpace 00269 // ------------------------------------- 00270 00271 template< int dim > 00272 template< int codim > 00273 struct HierarchyDofNumbering< dim >::CreateDofSpace 00274 { 00275 static void apply ( const MeshPointer &mesh, const DofSpace *(&dofSpace)[ dim+1 ] ) 00276 { 00277 int ndof[ nNodeTypes ]; 00278 for( int i = 0; i < nNodeTypes; ++i ) 00279 ndof[ i ] = 0; 00280 ndof[ CodimType< dim, codim >::value ] = 1; 00281 00282 std::string name = "Codimension "; 00283 name += (char)(codim + '0'); 00284 00285 dofSpace[ codim ] = createDofSpace( mesh, name, ndof ); 00286 assert( dofSpace[ codim ] != NULL ); 00287 } 00288 }; 00289 00290 00291 00292 // HierarchyDofNumbering::CacheDofSpace 00293 // ------------------------------------- 00294 00295 template< int dim > 00296 template< int codim > 00297 struct HierarchyDofNumbering< dim >::CacheDofSpace 00298 { 00299 static void apply ( const DofSpace *(&dofSpace)[ dim+1 ], Cache (&cache)[ dim+1 ] ) 00300 { 00301 const int codimtype = CodimType< dim, codim >::value; 00302 cache[ codim ].first = dofSpace[ codim ]->mesh->node[ codimtype ]; 00303 cache[ codim ].second = dofSpace[ codim ]->admin->n0_dof[ codimtype ]; 00304 } 00305 }; 00306 } 00307 00308 } 00309 00310 #endif // #if HAVE_ALBERTA 00311 00312 #endif