dune-grid
2.1.1
|
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 > ¯oData ); 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 > ¯oData, 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 > ¯oData, 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 > ¯oData ) 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 > ¯oData, 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 ¯oElement = 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 ¯oElement = 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 ¯oElement () 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