meshpointer.hh

Go to the documentation of this file.
00001 #ifndef DUNE_ALBERTA_MESHPOINTER_HH
00002 #define DUNE_ALBERTA_MESHPOINTER_HH
00003 
00009 #include <cassert>
00010 #include <string>
00011 
00012 #include <dune/grid/albertagrid/misc.hh>
00013 #include <dune/grid/albertagrid/elementinfo.hh>
00014 #include <dune/grid/albertagrid/albertaextra.hh>
00015 #include <dune/grid/albertagrid/macrodata.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::FillFlags FillFlags;
00043 
00044       class BoundaryProvider;
00045       class MacroIteratorBase;
00046 
00047     public:
00048       class MacroIterator;
00049 
00050       MeshPointer ()
00051       : mesh_( NULL )
00052       {}
00053 
00054       explicit MeshPointer ( Mesh *mesh )
00055       : mesh_( mesh )
00056       {}
00057 
00058       operator Mesh * () const
00059       {
00060         return mesh_;
00061       }
00062 
00063       bool operator! () const
00064       {
00065         return (mesh_ == NULL);
00066       }
00067 
00068       MacroIterator begin () const
00069       {
00070         return MacroIterator( *this, false );
00071       }
00072 
00073       MacroIterator end () const
00074       {
00075         return MacroIterator( *this, true );
00076       }
00077 
00078       std::string name () const
00079       {
00080         if( mesh_ != NULL )
00081           return mesh_->name;
00082         else
00083           return std::string();
00084       }
00085 
00086       int size ( int codim ) const;
00087 
00088       void create ( const MacroData< dim > &macroData, const std::string &name );
00089       void create ( const std::string &filename, const std::string &name, bool binary = false );
00090 
00091       void read ( const std::string &filename, Real &time );
00092 
00093       bool write ( const std::string &filename, Real time ) const;
00094 
00095       void release ()
00096       {
00097         if( mesh_ != NULL )
00098         {
00099 #if (DUNE_ALBERTA_VERSION < 0x200) && (DIM == 3)
00100           // circumvent memory bug in ALBERTA 1.2
00101           ALBERTA RC_LIST_EL *list = ALBERTA get_rc_list( mesh_ );
00102           list = 0;
00103 #endif
00104           ALBERTA free_mesh( mesh_ );
00105           mesh_ = NULL;
00106         }
00107       }
00108 
00109       template< class Functor >
00110       void hierarchicTraverse ( Functor &functor,
00111                                 typename FillFlags::Flags fillFlags = FillFlags::standard ) const;
00112 
00113       template< class Functor >
00114       void leafTraverse ( Functor &functor,
00115                           typename FillFlags::Flags fillFlags = FillFlags::standard ) const;
00116 
00117       bool coarsen ( typename FillFlags::Flags fillFlags = FillFlags::nothing );
00118 
00119       bool refine ( typename FillFlags::Flags fillFlags = FillFlags::nothing );
00120 
00121 #if DUNE_ALBERTA_VERSION < 0x200
00122     private:
00123       static void initDofAdmins ( Mesh *mesh )
00124       {
00125         mesh->preserve_coarse_dofs = 1;
00126         HierarchyDofNumbering< dim > dofNumbering;
00127         dofNumbering.create( MeshPointer< dim >( mesh ) );
00128       }
00129 #endif
00130     };
00131 
00132 
00133 
00134     template<>
00135     inline int MeshPointer< 1 >::size( int codim ) const
00136     {
00137       assert( (codim >= 0) && (codim <= 1) );
00138       return (codim == 0 ? mesh_->n_elements : mesh_->n_vertices);
00139     }
00140 
00141 #if (DUNE_ALBERTA_VERSION >= 0x200) || (DIM >= 2)
00142     template<>
00143     inline int MeshPointer< 2 >::size( int codim ) const
00144     {
00145       assert( (codim >= 0) && (codim <= 2) );
00146       if( codim == 0 )
00147         return mesh_->n_elements;
00148       else if( codim == 2 )
00149         return mesh_->n_vertices;
00150       else
00151         return mesh_->n_edges;
00152     }
00153 #endif // #if (DUNE_ALBERTA_VERSION >= 0x200) || (ALBERTA_DIM >= 2)
00154 
00155 #if (DUNE_ALBERTA_VERSION >= 0x200) || (DIM == 3)
00156     template<>
00157     inline int MeshPointer< 3 >::size( int codim ) const
00158     {
00159       assert( (codim >= 0) && (codim <= 3) );
00160       if( codim == 0 )
00161         return mesh_->n_elements;
00162       else if( codim == 3 )
00163         return mesh_->n_vertices;
00164       else if( codim == 1 )
00165         return mesh_->n_faces;
00166       else
00167         return mesh_->n_edges;
00168     }
00169 #endif // #if (DUNE_ALBERTA_VERSION >= 0x200) || (ALBERTA_DIM == 3)
00170 
00171 
00172 #if DUNE_ALBERTA_VERSION >= 0x200
00173     template< int dim >
00174     inline void MeshPointer< dim >
00175       ::create ( const MacroData< dim > &macroData, const std::string &name )
00176     {
00177       release();
00178 
00179 #if DUNE_ALBERTA_VERSION >= 0x201
00180       mesh_ = GET_MESH( dim, name.c_str(), macroData, NULL, NULL );
00181 #else
00182       mesh_ = GET_MESH( dim, name.c_str(), macroData, NULL );
00183 #endif
00184 
00185       if( mesh_ != NULL )
00186       {
00187         typedef AlbertHelp::AlbertLeafData< dim, dim+1 > LeafData;
00188         ALBERTA init_leaf_data( mesh_, sizeof( typename LeafData::Data ),
00189                                 LeafData::AlbertLeafRefine,
00190                                 LeafData::AlbertLeafCoarsen );
00191       }
00192     }
00193 #endif // #if DUNE_ALBERTA_VERSION >= 0x200
00194 
00195 #if DUNE_ALBERTA_VERSION < 0x200
00196     template< int dim >
00197     inline void MeshPointer< dim >
00198       ::create ( const MacroData< dim > &macroData, const std::string &name )
00199     {
00200       release();
00201 
00202       typedef AlbertHelp::AlbertLeafData< dim, dim+1 > LeafData;
00203       mesh_ = ALBERTA get_mesh( name.c_str(), initDofAdmins, LeafData::initLeafData );
00204       if( mesh_ != NULL )
00205         ALBERTA macro_data2mesh( mesh_, macroData, BoundaryProvider::initBoundary );
00206     }
00207 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00208 
00209 
00210 #if DUNE_ALBERTA_VERSION >= 0x200
00211     template< int dim >
00212     inline void MeshPointer< dim >
00213       ::create ( const std::string &filename, const std::string &name, bool binary )
00214     {
00215       MacroData< dim > macroData;
00216       macroData.read( filename, binary );
00217       create( macroData, name );
00218       macroData.release();
00219     }
00220 #endif // #if DUNE_ALBERTA_VERSION >= 0x200
00221 
00222 #if DUNE_ALBERTA_VERSION < 0x200
00223     template< int dim >
00224     inline void MeshPointer< dim >
00225       ::create ( const std::string &filename, const std::string &name, bool binary )
00226     {
00227       release();
00228 
00229       typedef AlbertHelp::AlbertLeafData< dim, dim+1 > LeafData;
00230       mesh_ = ALBERTA get_mesh( name.c_str(), initDofAdmins, LeafData::initLeafData );
00231       if( mesh_ != NULL )
00232       {
00233         if( binary )
00234           ALBERTA read_macro_xdr( mesh_, filename.c_str(), BoundaryProvider::initBoundary );
00235         else
00236           ALBERTA read_macro( mesh_, filename.c_str(), BoundaryProvider::initBoundary );
00237       }
00238     }
00239 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00240 
00241 
00242 
00243 #if DUNE_ALBERTA_VERSION < 0x200
00244     template< int dim >
00245     inline void MeshPointer< dim >::read ( const std::string &filename, Real &time )
00246     {
00247       release();
00248 
00249       typedef AlbertHelp::AlbertLeafData< dim, dim+1 > LeafData;
00250       mesh_ = ALBERTA read_mesh_xdr( filename.c_str(), &time, LeafData::initLeafData, BoundaryProvider::initBoundary );
00251     }
00252 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00253 
00254 #if DUNE_ALBERTA_VERSION >= 0x200
00255     template< int dim >
00256     inline void MeshPointer< dim >::read ( const std::string &filename, Real &time )
00257     {
00258       release();
00259 #if DUNE_ALBERTA_VERSION >= 0x201
00260       mesh_ = ALBERTA read_mesh_xdr( filename.c_str(), &time, NULL, NULL );
00261 #else
00262       mesh_ = ALBERTA read_mesh_xdr( filename.c_str(), &time, NULL );
00263 #endif
00264 
00265       if( mesh_ != NULL )
00266       {
00267         typedef AlbertHelp::AlbertLeafData< dim, dim+1 > LeafData;
00268         ALBERTA init_leaf_data( mesh_, sizeof( typename LeafData::Data ),
00269                                 LeafData::AlbertLeafRefine,
00270                                 LeafData::AlbertLeafCoarsen );
00271       }
00272     }
00273 #endif // #if DUNE_ALBERTA_VERSION >= 0x200
00274 
00275 
00276     template< int dim >
00277     inline bool MeshPointer< dim >::write ( const std::string &filename, Real time ) const
00278     {
00279       int success = ALBERTA write_mesh_xdr( mesh_, filename.c_str(), time );
00280       return (success == 0);
00281     }
00282 
00283 
00284     template< int dim >
00285     template< class Functor >
00286     inline void MeshPointer< dim >
00287       ::hierarchicTraverse ( Functor &functor,
00288                             typename FillFlags::Flags fillFlags ) const
00289     {
00290       const MacroIterator eit = end();
00291       for( MacroIterator it = begin(); it != eit; ++it )
00292       {
00293         const ElementInfo info = it.elementInfo( fillFlags );
00294         info.hierarchicTraverse( functor );
00295       }
00296     }
00297 
00298 
00299     template< int dim >
00300     template< class Functor >
00301     inline void MeshPointer< dim >
00302       ::leafTraverse ( Functor &functor,
00303                        typename FillFlags::Flags fillFlags ) const
00304     {
00305       const MacroIterator eit = end();
00306       for( MacroIterator it = begin(); it != eit; ++it )
00307       {
00308         const ElementInfo info = it.elementInfo( fillFlags );
00309         info.leafTraverse( functor );
00310       }
00311     }
00312 
00313 
00314 #if DUNE_ALBERTA_VERSION >= 0x201
00315     template< int dim >
00316     inline bool MeshPointer< dim >::coarsen ( typename FillFlags::Flags fillFlags )
00317     {
00318       const bool coarsened = (ALBERTA coarsen( mesh_, fillFlags ) == meshCoarsened);
00319       if( coarsened )
00320         ALBERTA dof_compress( mesh_ );
00321       return coarsened;
00322     }
00323 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00324 
00325 #if DUNE_ALBERTA_VERSION <= 0x200
00326     template< int dim >
00327     inline bool MeshPointer< dim >::coarsen ( typename FillFlags::Flags fillFlags )
00328     {
00329       assert( fillFlags == FillFlags::nothing );
00330       const bool coarsened = (ALBERTA coarsen( mesh_ ) == meshCoarsened);
00331       if( coarsened )
00332         ALBERTA dof_compress( mesh_ );
00333       return coarsened;
00334     }
00335 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
00336 
00337 
00338 #if DUNE_ALBERTA_VERSION >= 0x201
00339     template< int dim >
00340     inline bool MeshPointer< dim >::refine ( typename FillFlags::Flags fillFlags )
00341     {
00342       return (ALBERTA refine( mesh_, fillFlags ) == meshRefined);
00343     }
00344 #endif // #if DUNE_ALBERTA_VERSION >= 0x201
00345 
00346 #if DUNE_ALBERTA_VERSION <= 0x200
00347     template< int dim >
00348     inline bool MeshPointer< dim >::refine ( typename FillFlags::Flags fillFlags )
00349     {
00350       assert( fillFlags == FillFlags::nothing );
00351       return (ALBERTA refine( mesh_ ) == meshRefined);
00352     }
00353 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
00354 
00355 
00356 
00357     // MeshPointer::BoundaryProvider
00358     // -----------------------------
00359 
00360 #if DUNE_ALBERTA_VERSION < 0x200
00361     template< int dim >
00362     class MeshPointer< dim >::BoundaryProvider
00363     {
00364       static const int interior = INTERIOR;
00365 
00366 #if DIM > 1
00367       static const int numTypes = 256;
00368       static const int firstType = -127;
00369 
00370       Boundary boundaries[ numTypes ];
00371 #endif
00372 
00373       BoundaryProvider ();
00374 
00375       // prohibit copying and assignment
00376       BoundaryProvider ( const BoundaryProvider & );
00377       BoundaryProvider &operator= ( const BoundaryProvider & );
00378 
00379     public:
00380       const Boundary *operator[] ( int type ) const;
00381       
00382       static const BoundaryProvider &instance ()
00383       {
00384         static BoundaryProvider provider;
00385         return provider;
00386       }
00387 
00388       static const Boundary *initBoundary ( Mesh *mesh, int type )
00389       {
00390         return instance()[ type ];
00391       }
00392     };
00393 
00394 
00395     template< int dim >
00396     inline MeshPointer< dim >::BoundaryProvider::BoundaryProvider ()
00397     {
00398 #if DIM > 1
00399       for( int i = 0; i < numTypes; ++i )
00400       {
00401         boundaries[ i ].param_bound = NULL;
00402         boundaries[ i ].bound = i+firstType;
00403       }
00404 #endif
00405     }
00406 
00407 
00408     template< int dim >
00409     inline const Boundary *
00410     MeshPointer< dim >::BoundaryProvider::operator[] ( int type ) const
00411     {
00412       int index = type-firstType;
00413       if( (type == interior) || (index < 0) || (index >= numTypes) )
00414         DUNE_THROW( AlbertaError, "Invalid boundary type: " << type << "." );
00415 #if DIM > 1
00416       return &(boundaries[ index ]);
00417 #else
00418       return NULL;
00419 #endif
00420     }
00421 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00422 
00423 
00424 
00425     // MeshPointer::MacroIteratorBase
00426     // ------------------------------
00427 
00428 #if DUNE_ALBERTA_VERSION >= 0x200
00429     template< int dim >
00430     class MeshPointer< dim >::MacroIteratorBase
00431     {
00432       friend class MacroIterator;
00433 
00434     public:
00435       typedef Alberta::MeshPointer< dim > MeshPointer;
00436       typedef Alberta::ElementInfo< dim > ElementInfo;
00437 
00438     private:
00439       MeshPointer mesh_;
00440       int index_;
00441 
00442       explicit MacroIteratorBase ( const MeshPointer &mesh, bool end = false )
00443       : mesh_( mesh ),
00444         index_( end ? numMacroElements() : 0 )
00445       {}
00446 
00447     public:
00448       bool done () const
00449       {
00450         return (index_ >= numMacroElements());
00451       }
00452 
00453       bool equals ( const MacroIterator &other ) const
00454       {
00455         return (index_ == other.index_);
00456       }
00457 
00458       void increment ()
00459       {
00460         assert( !done() );
00461         ++index_;
00462       }
00463 
00464       MacroElement &macroElement () const
00465       {
00466         assert( !done() );
00467         return mesh().mesh_->macro_els[ index_ ];
00468       }
00469 
00470       const MeshPointer &mesh () const
00471       {
00472         return mesh_;
00473       }
00474 
00475     private:
00476       int numMacroElements () const
00477       {
00478         return mesh().mesh_->n_macro_el;
00479       }
00480     };
00481 #endif // #if DUNE_ALBERTA_VERSION >= 0x200
00482 
00483 #if DUNE_ALBERTA_VERSION < 0x200
00484     template< int dim >
00485     class MeshPointer< dim >::MacroIteratorBase
00486     { 
00487       friend class MacroIterator;
00488 
00489     public:
00490       typedef Alberta::MeshPointer< dim > MeshPointer;
00491       typedef Alberta::ElementInfo< dim > ElementInfo;
00492 
00493       typedef typename ElementInfo::FillFlags FillFlags;
00494 
00495     private:
00496       MeshPointer mesh_;
00497       MacroElement *element_;
00498 
00499       explicit MacroIteratorBase ( const MeshPointer &mesh, bool end = false )
00500       : mesh_( mesh ),
00501         element_( end ? NULL : mesh.mesh_->first_macro_el )
00502       {}
00503 
00504     public:
00505       bool done () const
00506       {
00507         return (element_ == NULL);
00508       }
00509 
00510       bool equals ( const MacroIterator &other ) const
00511       {
00512         return (element_ == other.element_);
00513       }
00514 
00515       void increment ()
00516       {
00517         assert( !done() );
00518         element_ = element_->next;
00519       }
00520 
00521       MacroElement &macroElement () const
00522       {
00523         assert( !done() );
00524         return *element_;
00525       }
00526 
00527       const MeshPointer &mesh () const
00528       {
00529         return mesh_;
00530       }
00531     };
00532 #endif // #if DUNE_ALBERTA_VERSION < 0x200
00533 
00534 
00535 
00536     // MeshPointer::MacroIterator
00537     // --------------------------
00538 
00539     template< int dim >
00540     class MeshPointer< dim >::MacroIterator
00541     : public MeshPointer< dim >::MacroIteratorBase
00542     {
00543       typedef MacroIterator This;
00544       typedef MacroIteratorBase Base;
00545 
00546       friend class MeshPointer< dim >;
00547 
00548     public:
00549       typedef Alberta::MeshPointer< dim > MeshPointer;
00550       typedef Alberta::ElementInfo< dim > ElementInfo;
00551 
00552     private:
00553       explicit MacroIterator ( const MeshPointer &mesh, bool end = false )
00554       : Base( mesh, end )
00555       {}
00556 
00557     public:
00558       using Base::done;
00559       using Base::equals;
00560       using Base::increment;
00561       using Base::macroElement;
00562       using Base::mesh;
00563 
00564       This &operator++ ()
00565       {
00566         increment();
00567         return *this;
00568       }
00569 
00570       ElementInfo operator* () const
00571       {
00572         return elementInfo();
00573       }
00574 
00575       bool operator== ( const MacroIterator &other ) const
00576       {
00577         return equals( other );
00578       }
00579 
00580       bool operator!= ( const MacroIterator &other ) const
00581       {
00582         return !equals( other );
00583       }
00584 
00585       ElementInfo
00586       elementInfo ( typename FillFlags::Flags fillFlags = FillFlags::standard ) const
00587       {
00588         if( done() )
00589           return ElementInfo();
00590         else
00591           return ElementInfo( mesh(), macroElement(), fillFlags );
00592       }
00593     };
00594 
00595   }
00596 
00597 }
00598 
00599 #endif // #if HAVE_ALBERTA
00600 
00601 #endif

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