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
21namespace 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.111.3 (Jul 15, 22:36, 2024)