Dune Core Modules (2.5.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
19namespace 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 {
87 ForEachInteriorSubChild< dim, codim >::apply( functor, *this );
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
constexpr void forEach(Range &&range, F &&f)
Range based for loop.
Definition: hybridutilities.hh:314
Dune namespace.
Definition: alignment.hh:11
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)