dofadmin.hh

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 #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       // the const cast is needed due to a bug in ALBERTA 2.0
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     // HierarchyDofNumbering::CreateDofSpace
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     // HierarchyDofNumbering::CacheDofSpace
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

Generated on Sun Nov 15 22:28:39 2009 for dune-grid by  doxygen 1.5.6