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