meshpointer.hh

Go to the documentation of this file.
00001 #ifndef DUNE_ALBERTA_MESHPOINTER_HH
00002 #define DUNE_ALBERTA_MESHPOINTER_HH
00003 
00009 #include <limits>
00010 #include <string>
00011 
00012 #include <dune/grid/albertagrid/misc.hh>
00013 #include <dune/grid/albertagrid/elementinfo.hh>
00014 #include <dune/grid/albertagrid/macrodata.hh>
00015 #include <dune/grid/albertagrid/projection.hh>
00016 
00017 #if HAVE_ALBERTA
00018 
00019 namespace Dune
00020 {
00021 
00022   namespace Alberta
00023   {
00024 
00025     // External Forward Declarations
00026     // -----------------------------
00027 
00028     template< int dim >
00029     class HierarchyDofNumbering;
00030 
00031 
00032 
00033     // MeshPointer
00034     // -----------
00035 
00036     template< int dim >
00037     class MeshPointer
00038     {
00039       Mesh *mesh_;
00040 
00041       typedef Alberta::ElementInfo< dim > ElementInfo;
00042       typedef typename ElementInfo::MacroElement MacroElement;
00043       typedef typename ElementInfo::FillFlags FillFlags;
00044 
00045       class BoundaryProvider;
00046 
00047       template< int dimWorld >
00048       struct Library;
00049 
00050     public:
00051       class MacroIterator;
00052 
00053       MeshPointer ()
00054       : mesh_( NULL )
00055       {}
00056 
00057       explicit MeshPointer ( Mesh *mesh )
00058       : mesh_( mesh )
00059       {}
00060 
00061       operator Mesh * () const
00062       {
00063         return mesh_;
00064       }
00065 
00066       bool operator! () const
00067       {
00068         return (mesh_ == NULL);
00069       }
00070 
00071       MacroIterator begin () const
00072       {
00073         return MacroIterator( *this, false );
00074       }
00075 
00076       MacroIterator end () const
00077       {
00078         return MacroIterator( *this, true );
00079       }
00080 
00081       int numMacroElements () const;
00082       int size ( int codim ) const;
00083 
00084       // create a mesh from a macrodata structure
00085       // params:  macroData - macro data structure
00086       // returns: number of boundary segments
00087       unsigned int create ( const MacroData< dim > &macroData );
00088 
00089       // create a mesh from a macrodata structure, adding projections
00090       // params:  macroData         - macro data structure
00091       //          projectionFactory - factory for the projections
00092       // returns: number of boundary segments
00093       template< class Proj, class Impl >
00094       unsigned int create ( const MacroData< dim > &macroData,
00095                             const ProjectionFactoryInterface< Proj, Impl > &projectionFactory );
00096 
00097       // create a mesh from a file
00098       // params:  filename - file name of an Alberta macro triangulation
00099       //          binary   - read binary?
00100       // returns: number of boundary segments
00101       unsigned int create ( const std::string &filename, bool binary = false );
00102 
00103       // read back a mesh from a file
00104       // params:  filename - file name of an Alberta save file
00105       //          time     - variable to receive the time stored in the file
00106       // returns: number of boundary segments
00107       //
00108       // notes: - projections are not preserved
00109       //        - we assume that projections are added in the same order they
00110       //          inserted in when the grid was created (otherwise the boundary
00111       //          indices change)
00112       unsigned int read ( const std::string &filename, Real &time );
00113 
00114       bool write ( const std::string &filename, Real time ) const;
00115 
00116       void release ();
00117 
00118       template< class Functor >
00119       void hierarchicTraverse ( Functor &functor,
00120                                 typename FillFlags::Flags fillFlags = FillFlags::standard ) const;
00121 
00122       template< class Functor >
00123       void leafTraverse ( Functor &functor,
00124                           typename FillFlags::Flags fillFlags = FillFlags::standard ) const;
00125 
00126       bool coarsen ( typename FillFlags::Flags fillFlags = FillFlags::nothing );
00127 
00128       bool refine ( typename FillFlags::Flags fillFlags = FillFlags::nothing );
00129 
00130     private:
00131       static ALBERTA NODE_PROJECTION *
00132       initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroElement, int n );
00133       template< class ProjectionProvider >
00134       static ALBERTA NODE_PROJECTION *
00135       initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroElement, int n );
00136     };
00137 
00138 
00139 
00140     // MeshPointer::Library
00141     // --------------------
00142 
00143     template< int dim >
00144     template< int dimWorld >
00145     struct MeshPointer< dim >::Library
00146     {
00147       typedef Alberta::MeshPointer< dim > MeshPointer;
00148 
00149       static unsigned int boundaryCount;
00150       static const void *projectionFactory;
00151 
00152       static void
00153       create ( MeshPointer &ptr, const MacroData< dim > &macroData,
00154                ALBERTA NODE_PROJECTION *(*initNodeProjection)( Mesh *, ALBERTA MACRO_EL *, int ) );
00155       static void release ( MeshPointer &ptr );
00156     };
00157 
00158 
00159 
00160     // Implementation of MeshPointer
00161     // -----------------------------
00162 
00163     template< int dim >
00164     inline int MeshPointer< dim >::numMacroElements () const
00165     {
00166       return (mesh_ != NULL ? mesh_->n_macro_el : 0);
00167     }
00168 
00169 
00170     template<>
00171     inline int MeshPointer< 1 >::size( int codim ) const
00172     {
00173       assert( (codim >= 0) && (codim <= 1) );
00174       return (codim == 0 ? mesh_->n_elements : mesh_->n_vertices);
00175     }
00176 
00177     template<>
00178     inline int MeshPointer< 2 >::size( int codim ) const
00179     {
00180       assert( (codim >= 0) && (codim <= 2) );
00181       if( codim == 0 )
00182         return mesh_->n_elements;
00183       else if( codim == 2 )
00184         return mesh_->n_vertices;
00185       else
00186         return mesh_->n_edges;
00187     }
00188 
00189     template<>
00190     inline int MeshPointer< 3 >::size( int codim ) const
00191     {
00192       assert( (codim >= 0) && (codim <= 3) );
00193       if( codim == 0 )
00194         return mesh_->n_elements;
00195       else if( codim == 3 )
00196         return mesh_->n_vertices;
00197       else if( codim == 1 )
00198         return mesh_->n_faces;
00199       else
00200         return mesh_->n_edges;
00201     }
00202 
00203 
00204     template< int dim >
00205     inline unsigned int MeshPointer< dim >
00206       ::create ( const MacroData< dim > &macroData )
00207     {
00208       release();
00209 
00210       Library< dimWorld >::boundaryCount = 0;
00211       Library< dimWorld >::create( *this, macroData, &initNodeProjection );
00212       return Library< dimWorld >::boundaryCount;
00213     }
00214 
00215 
00216     template< int dim >
00217     template< class Proj, class Impl >
00218     inline unsigned int MeshPointer< dim >
00219       ::create ( const MacroData< dim > &macroData,
00220                  const ProjectionFactoryInterface< Proj, Impl > &projectionFactory )
00221     {
00222       typedef ProjectionFactoryInterface< Proj, Impl > ProjectionFactory;
00223 
00224       release();
00225 
00226       Library< dimWorld >::boundaryCount = 0;
00227       Library< dimWorld >::projectionFactory = &projectionFactory;
00228       Library< dimWorld >::create( *this, macroData, &initNodeProjection< ProjectionFactory > );
00229       Library< dimWorld >::projectionFactory = 0;
00230       return Library< dimWorld >::boundaryCount;
00231     }
00232 
00233 
00234 
00235 
00236     template< int dim >
00237     inline unsigned int MeshPointer< dim >
00238       ::create ( const std::string &filename, bool binary )
00239     {
00240       MacroData< dim > macroData;
00241       macroData.read( filename, binary );
00242       const unsigned int boundaryCount = create( macroData );
00243       macroData.release();
00244       return boundaryCount;
00245     }
00246 
00247 
00248     template< int dim >
00249     inline unsigned int MeshPointer< dim >::read ( const std::string &filename, Real &time )
00250     {
00251       release();
00252 
00253       Library< dimWorld >::boundaryCount = 0;
00254 #if DUNE_ALBERTA_VERSION >= 0x300
00255       mesh_ = ALBERTA read_mesh_xdr( filename.c_str(), &time, NULL, NULL );
00256 #else
00257       mesh_ = ALBERTA read_mesh_xdr( filename.c_str(), &time, NULL );
00258 #endif
00259       return Library< dimWorld >::boundaryCount;
00260     }
00261 
00262 
00263     template< int dim >
00264     inline bool MeshPointer< dim >::write ( const std::string &filename, Real time ) const
00265     {
00266       int success = ALBERTA write_mesh_xdr( mesh_, filename.c_str(), time );
00267       return (success == 0);
00268     }
00269 
00270 
00271     template< int dim >
00272     inline void MeshPointer< dim >::release ()
00273     {
00274       Library< dimWorld >::release( *this );
00275     }
00276 
00277 
00278     template< int dim >
00279     template< class Functor >
00280     inline void MeshPointer< dim >
00281       ::hierarchicTraverse ( Functor &functor,
00282                             typename FillFlags::Flags fillFlags ) const
00283     {
00284       const MacroIterator eit = end();
00285       for( MacroIterator it = begin(); it != eit; ++it )
00286       {
00287         const ElementInfo info = it.elementInfo( fillFlags );
00288         info.hierarchicTraverse( functor );
00289       }
00290     }
00291 
00292 
00293     template< int dim >
00294     template< class Functor >
00295     inline void MeshPointer< dim >
00296       ::leafTraverse ( Functor &functor,
00297                        typename FillFlags::Flags fillFlags ) const
00298     {
00299       const MacroIterator eit = end();
00300       for( MacroIterator it = begin(); it != eit; ++it )
00301       {
00302         const ElementInfo info = it.elementInfo( fillFlags );
00303         info.leafTraverse( functor );
00304       }
00305     }
00306 
00307 
00308 #if DUNE_ALBERTA_VERSION >= 0x300
00309     template< int dim >
00310     inline bool MeshPointer< dim >::coarsen ( typename FillFlags::Flags fillFlags )
00311     {
00312       const bool coarsened = (ALBERTA coarsen( mesh_, fillFlags ) == meshCoarsened);
00313       if( coarsened )
00314         ALBERTA dof_compress( mesh_ );
00315       return coarsened;
00316     }
00317 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
00318 
00319 #if DUNE_ALBERTA_VERSION <= 0x200
00320     template< int dim >
00321     inline bool MeshPointer< dim >::coarsen ( typename FillFlags::Flags fillFlags )
00322     {
00323       assert( fillFlags == FillFlags::nothing );
00324       const bool coarsened = (ALBERTA coarsen( mesh_ ) == meshCoarsened);
00325       if( coarsened )
00326         ALBERTA dof_compress( mesh_ );
00327       return coarsened;
00328     }
00329 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
00330 
00331 
00332 #if DUNE_ALBERTA_VERSION >= 0x300
00333     template< int dim >
00334     inline bool MeshPointer< dim >::refine ( typename FillFlags::Flags fillFlags )
00335     {
00336       return (ALBERTA refine( mesh_, fillFlags ) == meshRefined);
00337     }
00338 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
00339 
00340 #if DUNE_ALBERTA_VERSION <= 0x200
00341     template< int dim >
00342     inline bool MeshPointer< dim >::refine ( typename FillFlags::Flags fillFlags )
00343     {
00344       assert( fillFlags == FillFlags::nothing );
00345       return (ALBERTA refine( mesh_ ) == meshRefined);
00346     }
00347 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
00348 
00349 
00350     template< int dim >
00351     inline ALBERTA NODE_PROJECTION *
00352     MeshPointer< dim >::initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroEl, int n )
00353     {
00354       const MacroElement &macroElement = static_cast< const MacroElement & >( *macroEl );
00355       if( (n > 0) && macroElement.isBoundary( n-1 ) )
00356         return new BasicNodeProjection( Library< dimWorld >::boundaryCount++ );
00357       else
00358         return 0;
00359     }
00360 
00361 
00362     template< int dim >
00363     template< class ProjectionFactory >
00364     inline ALBERTA NODE_PROJECTION *
00365     MeshPointer< dim >::initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroEl, int n )
00366     {
00367       typedef typename ProjectionFactory::Projection Projection;
00368 
00369       const MacroElement &macroElement = static_cast< const MacroElement & >( *macroEl );
00370 
00371       MeshPointer< dim > meshPointer( mesh );
00372       ElementInfo elementInfo( meshPointer, macroElement, FillFlags::standard );
00373       const ProjectionFactory &projectionFactory = *static_cast< const ProjectionFactory * >( Library< dimWorld >::projectionFactory );
00374       if( (n > 0) && macroElement.isBoundary( n-1 ) )
00375       {
00376         const unsigned int boundaryIndex = Library< dimWorld >::boundaryCount++;
00377         if( projectionFactory.hasProjection( elementInfo, n-1 ) )
00378         {
00379           Projection projection = projectionFactory.projection( elementInfo, n-1 );
00380           return new NodeProjection< dim, Projection >( boundaryIndex, projection );
00381         }
00382         else
00383           return new BasicNodeProjection( boundaryIndex );
00384       }
00385       else if( (dim < dimWorld) && (n == 0) )
00386       {
00387         const unsigned int boundaryIndex = std::numeric_limits< unsigned int >::max();
00388         if( projectionFactory.hasProjection( elementInfo ) )
00389         {
00390           Projection projection = projectionFactory.projection( elementInfo );
00391           return new NodeProjection< dim, Projection >( boundaryIndex, projection );
00392         }
00393         else
00394           return 0;
00395       }
00396       else
00397         return 0;
00398     }
00399 
00400 
00401 
00402     // MeshPointer::MacroIterator
00403     // --------------------------
00404 
00405     template< int dim >
00406     class MeshPointer< dim >::MacroIterator
00407     {
00408       typedef MacroIterator This;
00409 
00410       friend class MeshPointer< dim >;
00411 
00412     public:
00413       typedef Alberta::MeshPointer< dim > MeshPointer;
00414       typedef Alberta::ElementInfo< dim > ElementInfo;
00415 
00416     private:
00417       explicit MacroIterator ( const MeshPointer &mesh, bool end = false )
00418       : mesh_( mesh ),
00419         index_( end ? mesh.numMacroElements() : 0 )
00420       {}
00421 
00422     public:
00423       bool done () const
00424       {
00425         return (index_ >= mesh().numMacroElements());
00426       }
00427 
00428       bool equals ( const MacroIterator &other ) const
00429       {
00430         return (index_ == other.index_);
00431       }
00432 
00433       void increment ()
00434       {
00435         assert( !done() );
00436         ++index_;
00437       }
00438 
00439       const MacroElement &macroElement () const
00440       {
00441         assert( !done() );
00442         return static_cast< const MacroElement & >( mesh().mesh_->macro_els[ index_ ] );
00443       }
00444 
00445       const MeshPointer &mesh () const
00446       {
00447         return mesh_;
00448       }
00449 
00450       This &operator++ ()
00451       {
00452         increment();
00453         return *this;
00454       }
00455 
00456       ElementInfo operator* () const
00457       {
00458         return elementInfo();
00459       }
00460 
00461       bool operator== ( const MacroIterator &other ) const
00462       {
00463         return equals( other );
00464       }
00465 
00466       bool operator!= ( const MacroIterator &other ) const
00467       {
00468         return !equals( other );
00469       }
00470 
00471       ElementInfo
00472       elementInfo ( typename FillFlags::Flags fillFlags = FillFlags::standard ) const
00473       {
00474         if( done() )
00475           return ElementInfo();
00476         else
00477           return ElementInfo( mesh(), macroElement(), fillFlags );
00478       }
00479 
00480     private:
00481       MeshPointer mesh_;
00482       int index_;
00483     };
00484 
00485   }
00486 
00487 }
00488 
00489 #endif // #if HAVE_ALBERTA
00490 
00491 #endif // #ifndef DUNE_ALBERTA_MESHPOINTER_HH

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