dune-grid  2.1.1
dofadmin.hh
Go to the documentation of this file.
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