dune-grid  2.2.1
meshpointer.hh
Go to the documentation of this file.
1 #ifndef DUNE_ALBERTA_MESHPOINTER_HH
2 #define DUNE_ALBERTA_MESHPOINTER_HH
3 
9 #include <limits>
10 #include <string>
11 
16 
17 #if HAVE_ALBERTA
18 
19 namespace Dune
20 {
21 
22  namespace Alberta
23  {
24 
25  // External Forward Declarations
26  // -----------------------------
27 
28  template< int dim >
29  class HierarchyDofNumbering;
30 
31 
32 
33  // MeshPointer
34  // -----------
35 
36  template< int dim >
38  {
40  typedef typename ElementInfo::MacroElement MacroElement;
41  typedef typename ElementInfo::FillFlags FillFlags;
42 
43  class BoundaryProvider;
44 
45  template< int dimWorld >
46  struct Library;
47 
48  public:
49  class MacroIterator;
50 
52  : mesh_( 0 )
53  {}
54 
55  explicit MeshPointer ( Mesh *mesh )
56  : mesh_( mesh )
57  {}
58 
59  operator Mesh * () const
60  {
61  return mesh_;
62  }
63 
64  operator bool () const
65  {
66  return (bool)mesh_;
67  }
68 
69  MacroIterator begin () const
70  {
71  return MacroIterator( *this, false );
72  }
73 
74  MacroIterator end () const
75  {
76  return MacroIterator( *this, true );
77  }
78 
79  int numMacroElements () const;
80  int size ( int codim ) const;
81 
82  // create a mesh from a macrodata structure
83  // params: macroData - macro data structure
84  // returns: number of boundary segments
85  unsigned int create ( const MacroData< dim > &macroData );
86 
87  // create a mesh from a macrodata structure, adding projections
88  // params: macroData - macro data structure
89  // projectionFactory - factory for the projections
90  // returns: number of boundary segments
91  template< class Proj, class Impl >
92  unsigned int create ( const MacroData< dim > &macroData,
93  const ProjectionFactoryInterface< Proj, Impl > &projectionFactory );
94 
95  // create a mesh from a file
96  // params: filename - file name of an Alberta macro triangulation
97  // binary - read binary?
98  // returns: number of boundary segments
99  unsigned int create ( const std::string &filename, bool binary = false );
100 
101  // read back a mesh from a file
102  // params: filename - file name of an Alberta save file
103  // time - variable to receive the time stored in the file
104  // returns: number of boundary segments
105  //
106  // notes: - projections are not preserved
107  // - we assume that projections are added in the same order they
108  // inserted in when the grid was created (otherwise the boundary
109  // indices change)
110  unsigned int read ( const std::string &filename, Real &time );
111 
112  bool write ( const std::string &filename, Real time ) const;
113 
114  void release ();
115 
116  template< class Functor >
117  void hierarchicTraverse ( Functor &functor,
118  typename FillFlags::Flags fillFlags = FillFlags::standard ) const;
119 
120  template< class Functor >
121  void leafTraverse ( Functor &functor,
122  typename FillFlags::Flags fillFlags = FillFlags::standard ) const;
123 
124  bool coarsen ( typename FillFlags::Flags fillFlags = FillFlags::nothing );
125 
126  bool refine ( typename FillFlags::Flags fillFlags = FillFlags::nothing );
127 
128  private:
129  static ALBERTA NODE_PROJECTION *
130  initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroElement, int n );
131  template< class ProjectionProvider >
132  static ALBERTA NODE_PROJECTION *
133  initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroElement, int n );
134 
135  Mesh *mesh_;
136  };
137 
138 
139 
140  // MeshPointer::Library
141  // --------------------
142 
143  template< int dim >
144  template< int dimWorld >
145  struct MeshPointer< dim >::Library
146  {
148 
149  static unsigned int boundaryCount;
150  static const void *projectionFactory;
151 
152  static void
153  create ( MeshPointer &ptr, const MacroData< dim > &macroData,
154  ALBERTA NODE_PROJECTION *(*initNodeProjection)( Mesh *, ALBERTA MACRO_EL *, int ) );
155  static void release ( MeshPointer &ptr );
156  };
157 
158 
159 
160  // MeshPointer::MacroIterator
161  // --------------------------
162 
163  template< int dim >
165  {
166  typedef MacroIterator This;
167 
168  friend class MeshPointer< dim >;
169 
170  public:
173 
174  private:
175  explicit MacroIterator ( const MeshPointer &mesh, bool end = false )
176  : mesh_( mesh ),
177  index_( end ? mesh.numMacroElements() : 0 )
178  {}
179 
180  public:
181  bool done () const
182  {
183  return (index_ >= mesh().numMacroElements());
184  }
185 
186  bool equals ( const MacroIterator &other ) const
187  {
188  return (index_ == other.index_);
189  }
190 
191  void increment ()
192  {
193  assert( !done() );
194  ++index_;
195  }
196 
197  const MacroElement &macroElement () const
198  {
199  assert( !done() );
200  return static_cast< const MacroElement & >( mesh().mesh_->macro_els[ index_ ] );
201  }
202 
203  const MeshPointer &mesh () const
204  {
205  return mesh_;
206  }
207 
208  This &operator++ ()
209  {
210  increment();
211  return *this;
212  }
213 
214  ElementInfo operator* () const
215  {
216  return elementInfo();
217  }
218 
219  bool operator== ( const MacroIterator &other ) const
220  {
221  return equals( other );
222  }
223 
224  bool operator!= ( const MacroIterator &other ) const
225  {
226  return !equals( other );
227  }
228 
230  elementInfo ( typename FillFlags::Flags fillFlags = FillFlags::standard ) const
231  {
232  if( done() )
233  return ElementInfo();
234  else
235  return ElementInfo( mesh(), macroElement(), fillFlags );
236  }
237 
238  private:
239  MeshPointer mesh_;
240  int index_;
241  };
242 
243 
244 
245  // Implementation of MeshPointer
246  // -----------------------------
247 
248  template< int dim >
250  {
251  return (mesh_ ? mesh_->n_macro_el : 0);
252  }
253 
254 
255  template<>
256  inline int MeshPointer< 1 >::size( int codim ) const
257  {
258  assert( (codim >= 0) && (codim <= 1) );
259  return (codim == 0 ? mesh_->n_elements : mesh_->n_vertices);
260  }
261 
262  template<>
263  inline int MeshPointer< 2 >::size( int codim ) const
264  {
265  assert( (codim >= 0) && (codim <= 2) );
266  if( codim == 0 )
267  return mesh_->n_elements;
268  else if( codim == 2 )
269  return mesh_->n_vertices;
270  else
271  return mesh_->n_edges;
272  }
273 
274  template<>
275  inline int MeshPointer< 3 >::size( int codim ) const
276  {
277  assert( (codim >= 0) && (codim <= 3) );
278  if( codim == 0 )
279  return mesh_->n_elements;
280  else if( codim == 3 )
281  return mesh_->n_vertices;
282  else if( codim == 1 )
283  return mesh_->n_faces;
284  else
285  return mesh_->n_edges;
286  }
287 
288 
289  template< int dim >
290  inline unsigned int MeshPointer< dim >
291  ::create ( const MacroData< dim > &macroData )
292  {
293  release();
294 
296  Library< dimWorld >::create( *this, macroData, &initNodeProjection );
298  }
299 
300 
301  template< int dim >
302  template< class Proj, class Impl >
303  inline unsigned int MeshPointer< dim >
304  ::create ( const MacroData< dim > &macroData,
305  const ProjectionFactoryInterface< Proj, Impl > &projectionFactory )
306  {
308 
309  release();
310 
312  Library< dimWorld >::projectionFactory = &projectionFactory;
313  Library< dimWorld >::create( *this, macroData, &initNodeProjection< ProjectionFactory > );
316  }
317 
318 
319 
320 
321  template< int dim >
322  inline unsigned int MeshPointer< dim >
323  ::create ( const std::string &filename, bool binary )
324  {
325  MacroData< dim > macroData;
326  macroData.read( filename, binary );
327  const unsigned int boundaryCount = create( macroData );
328  macroData.release();
329  return boundaryCount;
330  }
331 
332 
333  template< int dim >
334  inline unsigned int MeshPointer< dim >::read ( const std::string &filename, Real &time )
335  {
336  release();
337 
339 #if DUNE_ALBERTA_VERSION >= 0x300
340  mesh_ = ALBERTA read_mesh_xdr( filename.c_str(), &time, NULL, NULL );
341 #else
342  mesh_ = ALBERTA read_mesh_xdr( filename.c_str(), &time, NULL );
343 #endif
345  }
346 
347 
348  template< int dim >
349  inline bool MeshPointer< dim >::write ( const std::string &filename, Real time ) const
350  {
351  int success = ALBERTA write_mesh_xdr( mesh_, filename.c_str(), time );
352  return (success == 0);
353  }
354 
355 
356  template< int dim >
358  {
360  }
361 
362 
363  template< int dim >
364  template< class Functor >
365  inline void MeshPointer< dim >
366  ::hierarchicTraverse ( Functor &functor,
367  typename FillFlags::Flags fillFlags ) const
368  {
369  const MacroIterator eit = end();
370  for( MacroIterator it = begin(); it != eit; ++it )
371  {
372  const ElementInfo info = it.elementInfo( fillFlags );
373  info.hierarchicTraverse( functor );
374  }
375  }
376 
377 
378  template< int dim >
379  template< class Functor >
380  inline void MeshPointer< dim >
381  ::leafTraverse ( Functor &functor,
382  typename FillFlags::Flags fillFlags ) const
383  {
384  const MacroIterator eit = end();
385  for( MacroIterator it = begin(); it != eit; ++it )
386  {
387  const ElementInfo info = it.elementInfo( fillFlags );
388  info.leafTraverse( functor );
389  }
390  }
391 
392 
393 #if DUNE_ALBERTA_VERSION >= 0x300
394  template< int dim >
395  inline bool MeshPointer< dim >::coarsen ( typename FillFlags::Flags fillFlags )
396  {
397  const bool coarsened = (ALBERTA coarsen( mesh_, fillFlags ) == meshCoarsened);
398  if( coarsened )
399  ALBERTA dof_compress( mesh_ );
400  return coarsened;
401  }
402 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
403 
404 #if DUNE_ALBERTA_VERSION <= 0x200
405  template< int dim >
406  inline bool MeshPointer< dim >::coarsen ( typename FillFlags::Flags fillFlags )
407  {
408  assert( fillFlags == FillFlags::nothing );
409  const bool coarsened = (ALBERTA coarsen( mesh_ ) == meshCoarsened);
410  if( coarsened )
411  ALBERTA dof_compress( mesh_ );
412  return coarsened;
413  }
414 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
415 
416 
417 #if DUNE_ALBERTA_VERSION >= 0x300
418  template< int dim >
419  inline bool MeshPointer< dim >::refine ( typename FillFlags::Flags fillFlags )
420  {
421  return (ALBERTA refine( mesh_, fillFlags ) == meshRefined);
422  }
423 #endif // #if DUNE_ALBERTA_VERSION >= 0x300
424 
425 #if DUNE_ALBERTA_VERSION <= 0x200
426  template< int dim >
427  inline bool MeshPointer< dim >::refine ( typename FillFlags::Flags fillFlags )
428  {
429  assert( fillFlags == FillFlags::nothing );
430  return (ALBERTA refine( mesh_ ) == meshRefined);
431  }
432 #endif // #if DUNE_ALBERTA_VERSION <= 0x200
433 
434 
435  template< int dim >
436  inline ALBERTA NODE_PROJECTION *
437  MeshPointer< dim >::initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroEl, int n )
438  {
439  const MacroElement &macroElement = static_cast< const MacroElement & >( *macroEl );
440  if( (n > 0) && macroElement.isBoundary( n-1 ) )
441  return new BasicNodeProjection( Library< dimWorld >::boundaryCount++ );
442  else
443  return 0;
444  }
445 
446 
447  template< int dim >
448  template< class ProjectionFactory >
449  inline ALBERTA NODE_PROJECTION *
450  MeshPointer< dim >::initNodeProjection ( Mesh *mesh, ALBERTA MACRO_EL *macroEl, int n )
451  {
452  typedef typename ProjectionFactory::Projection Projection;
453 
454  const MacroElement &macroElement = static_cast< const MacroElement & >( *macroEl );
455 
456  MeshPointer< dim > meshPointer( mesh );
457  ElementInfo elementInfo( meshPointer, macroElement, FillFlags::standard );
458  const ProjectionFactory &projectionFactory = *static_cast< const ProjectionFactory * >( Library< dimWorld >::projectionFactory );
459  if( (n > 0) && macroElement.isBoundary( n-1 ) )
460  {
461  const unsigned int boundaryIndex = Library< dimWorld >::boundaryCount++;
462  if( projectionFactory.hasProjection( elementInfo, n-1 ) )
463  {
464  Projection projection = projectionFactory.projection( elementInfo, n-1 );
465  return new NodeProjection< dim, Projection >( boundaryIndex, projection );
466  }
467  else
468  return new BasicNodeProjection( boundaryIndex );
469  }
470  else if( (dim < dimWorld) && (n == 0) )
471  {
472  const unsigned int boundaryIndex = std::numeric_limits< unsigned int >::max();
473  if( projectionFactory.hasProjection( elementInfo ) )
474  {
475  Projection projection = projectionFactory.projection( elementInfo );
476  return new NodeProjection< dim, Projection >( boundaryIndex, projection );
477  }
478  else
479  return 0;
480  }
481  else
482  return 0;
483  }
484 
485  } // namespace Alberta
486 
487 } // namespace Dune
488 
489 #endif // #if HAVE_ALBERTA
490 
491 #endif // #ifndef DUNE_ALBERTA_MESHPOINTER_HH