Dune Core Modules (unstable)

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