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

Generated on Thu Apr 2 10:40:38 2009 for dune-grid by  doxygen 1.5.6