Dune Core Modules (unstable)

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