Dune Core Modules (2.6.0)

refinement.hh
Go to the documentation of this file.
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_ALBERTA_REFINEMENT_HH
4 #define DUNE_ALBERTA_REFINEMENT_HH
5 
12 #include <cassert>
13 
14 #include <dune/grid/albertagrid/misc.hh>
16 
17 #if HAVE_ALBERTA
18 
19 namespace Dune
20 {
21 
22  namespace Alberta
23  {
24 
25  // Internal Forward Declarations
26  // -----------------------------
27 
28  template< int dim, int codim >
29  struct ForEachInteriorSubChild;
30 
31 
32 
33  // Patch
34  // -----
35 
36  template< int dim >
37  class Patch
38  {
39  typedef Patch< dim > This;
40 
41  static_assert(((dim >= 1) && (dim <= 3)),
42  "Alberta supports only dimensions 1, 2, 3");
43 
44  public:
45  static const int dimension = dim;
46 
47  typedef Alberta::ElementInfo< dimension > ElementInfo;
48 
49  typedef ALBERTA RC_LIST_EL ElementList;
50 
51  private:
52  ElementList *list_;
53  int count_;
54 
55  public:
56  Patch ( ElementList *list, int count )
57  : list_( list ),
58  count_( count )
59  {
60  assert( count > 0 );
61  }
62 
63  Element *operator[] ( int i ) const;
64 
65  int count () const
66  {
67  return count_;
68  }
69 
70  template< class LevelProvider >
71  ElementInfo elementInfo ( int i, const LevelProvider &levelProvider ) const;
72 
73  int elementType ( int i ) const;
74  bool hasNeighbor ( int i, int neighbor ) const;
75  int neighborIndex ( int i, int neighbor ) const;
76 
77  template< class Functor >
78  void forEach ( Functor &functor ) const
79  {
80  for( int i = 0; i < count(); ++i )
81  functor( (*this)[ i ] );
82  }
83 
84  template< int codim, class Functor >
85  void forEachInteriorSubChild ( Functor &functor ) const
86  {
88  }
89  };
90 
91 
92  template< int dim >
93  inline Element *Patch< dim >::operator[] ( int i ) const
94  {
95  assert( (i >= 0) && (i < count()) );
96  return list_[ i ].el_info.el;
97  }
98 
99 
100  template< int dim >
101  template< class LevelProvider >
102  inline typename Patch< dim >::ElementInfo
103  Patch< dim >::elementInfo ( int i, const LevelProvider &levelProvider ) const
104  {
105  assert( (i >= 0) && (i < count()) );
106  return ElementInfo::createFake( list_[ i ].el_info );
107  }
108 
109  template<>
110  template< class LevelProvider >
111  inline typename Patch< 2 >::ElementInfo
112  Patch< 2 >::elementInfo ( int i, const LevelProvider &levelProvider ) const
113  {
114  assert( (i >= 0) && (i < count()) );
115  const MeshPointer< 2 > &mesh = levelProvider.mesh();
116  const Element *element = (*this)[ i ];
117  const int level = levelProvider( element );
118  return ElementInfo::createFake( mesh, element, level );
119  }
120 
121 
122  template< int dim >
123  inline int Patch< dim >::elementType ( int i ) const
124  {
125  assert( (i >= 0) && (i < count()) );
126  return list_[ i ].el_info.el_type;
127  }
128 
129 
130  template< int dim >
131  inline bool Patch< dim >::hasNeighbor ( int i, int neighbor ) const
132  {
133  return (list_[ i ].neigh[ neighbor ] != NULL);
134  }
135 
136  template< int dim >
137  inline int Patch< dim >::neighborIndex ( int i, int neighbor ) const
138  {
139  assert( hasNeighbor( i, neighbor ) );
140  return (list_[ i ].neigh[ neighbor ]->no);
141  }
142 
143 
144 
145  // ForEachInteriorSubChild
146  // -----------------------
147 
148  template< int dim >
149  struct ForEachInteriorSubChild< dim, 0 >
150  {
151  template< class Functor >
152  static void apply ( Functor &functor, const Patch< dim > &patch )
153  {
154  for( int i = 0; i < patch.count(); ++i )
155  {
156  Element *const father = patch[ i ];
157  functor( father->child[ 0 ], 0 );
158  functor( father->child[ 1 ], 0 );
159  }
160  }
161  };
162 
163  template< int dim >
164  struct ForEachInteriorSubChild< dim, dim >
165  {
166  template< class Functor >
167  static void apply ( Functor &functor, const Patch< dim > &patch )
168  {
169  functor( patch[ 0 ]->child[ 0 ], dim );
170  }
171  };
172 
173  template<>
174  struct ForEachInteriorSubChild< 2, 1 >
175  {
176  template< class Functor >
177  static void apply ( Functor &functor, const Patch< 2 > &patch )
178  {
179  // see alberta/src/2d/lagrange_2_2d.c for details
180  Element *const firstFather = patch[ 0 ];
181 
182  Element *const firstChild = firstFather->child[ 0 ];
183  functor( firstChild, 0 );
184  functor( firstChild, 1 );
185 
186  functor( firstFather->child[ 1 ], 1 );
187 
188  if( patch.count() > 1 )
189  {
190  Element *const father = patch[ 1 ];
191  functor( father->child[ 0 ], 1 );
192  }
193  }
194  };
195 
196  template<>
197  struct ForEachInteriorSubChild< 3, 1 >
198  {
199  template< class Functor >
200  static void apply ( Functor &functor, const Patch< 3 > &patch )
201  {
202  // see alberta/src/3d/lagrange_3_3d.c for details
203  Element *const firstFather = patch[ 0 ];
204 
205  Element *const firstChild = firstFather->child[ 0 ];
206  functor( firstChild, 0 );
207  functor( firstChild, 1 );
208  functor( firstChild, 2 );
209 
210  Element *const secondChild = firstFather->child[ 1 ];
211  functor( secondChild, 1 );
212  functor( secondChild, 2 );
213 
214  for( int i = 1; i < patch.count(); ++i )
215  {
216  Element *const father = patch[ i ];
217  const int type = patch.elementType( i );
218 
219  int lr_set = 0;
220  if( patch.hasNeighbor( i, 0 ) && (patch.neighborIndex( i, 0 ) < i) )
221  lr_set |= 1;
222  if( patch.hasNeighbor( i, 1 ) && (patch.neighborIndex( i, 1 ) < i) )
223  lr_set |= 2;
224  assert( lr_set != 0 );
225 
226  functor( father->child[ 0 ], 0 );
227  switch( lr_set )
228  {
229  case 1 :
230  functor( father->child[ 0 ], 2 );
231  functor( father->child[ 1 ], (type == 0 ? 1 : 2) );
232  break;
233 
234  case 2 :
235  functor( father->child[ 0 ], 1 );
236  functor( father->child[ 1 ], (type == 0 ? 2 : 1) );
237  break;
238  }
239  }
240  }
241  };
242 
243  template<>
244  struct ForEachInteriorSubChild< 3, 2 >
245  {
246  template< class Functor >
247  static void apply ( Functor &functor, const Patch< 3 > &patch )
248  {
249  // see alberta/src/3d/lagrange_2_3d.c for details
250  Element *const firstFather = patch[ 0 ];
251 
252  Element *const firstChild = firstFather->child[ 0 ];
253  functor( firstChild, 2 );
254  functor( firstChild, 4 );
255  functor( firstChild, 5 );
256 
257  functor( firstFather->child[ 1 ], 2 );
258 
259  for( int i = 1; i < patch.count(); ++i )
260  {
261  Element *const father = patch[ i ];
262 
263  int lr_set = 0;
264  if( patch.hasNeighbor( i, 0 ) && (patch.neighborIndex( i, 0 ) < i) )
265  lr_set = 1;
266  if( patch.hasNeighbor( i, 1 ) && (patch.neighborIndex( i, 1 ) < i) )
267  lr_set += 2;
268  assert( lr_set != 0 );
269 
270  switch( lr_set )
271  {
272  case 1 :
273  functor( father->child[ 0 ], 4 );
274  break;
275 
276  case 2 :
277  functor( father->child[ 0 ], 5 );
278  break;
279  }
280  }
281  }
282  };
283 
284 
285 
286  // GeometryInFather
287  // ----------------
288 
289  template< int dim >
290  struct GeometryInFather;
291 
292  template<>
293  struct GeometryInFather< 1 >
294  {
295  static const int dim = 1;
296 
297  typedef Real LocalVector[ dim ];
298 
299  static const LocalVector &
300  coordinate ( int child, int orientation, int i )
301  {
302  static const Real coords[ 2 ][ dim+1 ][ dim ]
303  = { { {0.0}, {0.5} }, { {0.5}, {1.0} } };
304  assert( (i >= 0) && (i <= dim) );
305  return coords[ child ][ i ];
306  }
307  };
308 
309  template<>
310  struct GeometryInFather< 2 >
311  {
312  static const int dim = 2;
313 
314  typedef Real LocalVector[ dim ];
315 
316  static const LocalVector &
317  coordinate ( int child, int orientation, int i )
318  {
319  static const Real coords[ 2 ][ dim+1 ][ dim ]
320  = { { {0.0, 1.0}, {0.0, 0.0}, {0.5, 0.0} },
321  { {1.0, 0.0}, {0.0, 1.0}, {0.5, 0.0} } };
322  assert( (i >= 0) && (i <= dim) );
323  return coords[ child ][ i ];
324  }
325  };
326 
327  template<>
328  struct GeometryInFather< 3 >
329  {
330  static const int dim = 3;
331 
332  typedef Real LocalVector[ dim ];
333 
334  static const LocalVector &
335  coordinate ( int child, int orientation, int i )
336  {
337  static const Real coords[ 2 ][ dim+1 ][ dim ]
338  = { { {0.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {0.5, 0.0, 0.0} },
339  { {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {0.5, 0.0, 0.0} } };
340  static const int flip[ 2 ][ 2 ][ dim+1 ]
341  = { { {0, 1, 2, 3}, {0, 1, 2, 3} }, { {0, 2, 1, 3}, {0, 1, 2, 3} } };
342  assert( (i >= 0) && (i <= dim) );
343  i = flip[ child ][ orientation ][ i ];
344  return coords[ child ][ i ];
345  }
346  };
347 
348  }
349 
350 }
351 
352 #endif // #if HAVE_ALBERTA
353 
354 #endif
provides a wrapper for ALBERTA's el_info structure
decltype(auto) apply(F &&f, ArgTuple &&args)
Apply function with arguments given as tuple.
Definition: apply.hh:58
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:308
Dune namespace.
Definition: alignedallocator.hh:10
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)