DUNE-FEM (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
23namespace 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 equals(T1 &&t1, T2 &&t2)
Equality comparison.
Definition: hybridutilities.hh:587
constexpr auto max
Function object that returns the greater of the given values.
Definition: hybridutilities.hh:484
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:238
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:260
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.111.3 (Nov 21, 23:30, 2024)