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

Generated on Fri Apr 29 2011 with Doxygen (ver 1.7.1) [doxygen-log,error-log].