FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
sun_zhao_ma_expansion_data.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8#include <kernel/geometry/raw_refinement_templates.hpp>
9#include <kernel/geometry/refinement_types.hpp>
10#include <kernel/shape.hpp>
11
12#include <unordered_map>
13
14namespace FEAT::Geometry
15{
17 {
18 public:
21
28
30 template<int dim_>
32
34 template<typename Shape__>
36
38 template<int dim_>
39 using TemplateMapByDim = std::unordered_map<RefinementTypeByDim<dim_>, RawTemplate<Shape::Hypercube<dim_>>>;
40
47
54
64 template<typename Shape_>
65 static constexpr bool is_shape_compatible()
66 {
67 return std::is_same_v<Shape_, Shape::Quadrilateral> || std::is_same_v<Shape_, Shape::Hexahedron>;
68 }
69
80 template<int template_dim_, int child_dim_>
81 static constexpr int max_children()
82 {
83 static_assert(template_dim_ <= 3);
84 static_assert(child_dim_ <= 3);
85 const constexpr std::array<std::array<int, 4>, 4> children = {{
86 {0, 0, 0, 0},
87 {2, 3, 0, 0},
88 {8, 18, 11, 0},
89 {62, 197, 216, 82},
90 }};
91 return children[template_dim_][child_dim_];
92 }
93
99 template<int dim_>
101 {
102 if constexpr(dim_ == 1)
103 {
104 return raw_edges();
105 }
106 if constexpr(dim_ == 2)
107 {
108 return raw_faces();
109 }
110 if constexpr(dim_ == 3)
111 {
112 return raw_cells();
113 }
114 XABORTM("SchneidersData supplied no templates of dimension " + stringify(dim_));
115 }
116
119 {
120 static EdgeMap result = {};
121
122 using V = typename RawEdgeTemplate::VertexType;
123
124 if(result.empty())
125 {
126 // No refinement unless either both vertices are marked or one of them is isolated
127 result.insert({RefinementTypeByDim<1>(0b00, false), RawEdgeTemplate()});
128 result.insert({RefinementTypeByDim<1>(0b10, false), RawEdgeTemplate().add_entity(V{0.0}, V{1.0})});
129 result.insert({RefinementTypeByDim<1>(0b01, false), RawEdgeTemplate().add_entity(V{0.0}, V{1.0})});
130
131 // Split edge in half, if adjacent to isolated point
132 result.insert(
133 {RefinementTypeByDim<1>(0b01, true),
134 RawEdgeTemplate().add_entity(V{0.0}, V{1.0 / 2.0}).add_entity(V{1.0 / 2.0}, V{1.0})});
135
136 result.insert(
137 {RefinementTypeByDim<1>(0b10, true),
138 RawEdgeTemplate().add_entity(V{0.0}, V{1.0 / 2.0}).add_entity(V{1.0 / 2.0}, V{1.0})});
139
140 // Split in thirds if adjacent to two marked vertices
141 result.insert(
142 {RefinementTypeByDim<1>(0b11, false),
144 .add_entity(V{0.0}, V{1.0 / 3.0})
145 .add_entity(V{1.0 / 3.0}, V{2.0 / 3.0})
146 .add_entity(V{2.0 / 3.0}, V{1.0})});
147 }
148
149 return result;
150 }
151
154 {
155 static FaceMap result;
156
157 using V = typename RawFaceTemplate::VertexType;
158
159 if(result.empty())
160 {
161 // No refinement if no vertices are marked
162 result.insert({RefinementTypeByDim<2>(0b0000, false), RawFaceTemplate()});
163
164 // Templates for isolated point refinement, with 4 different orientations
165 result.insert(
166 {RefinementTypeByDim<2>(0b0001, true),
168 .add_entity(V{0.0, 0.0}, V{1.0 / 2.0, 0.0}, V{0.0, 1.0 / 2.0}, V{1.0 / 2.0, 1.0 / 2.0})
169 .add_entity(V{1.0 / 2.0, 0.0}, V{1.0, 0.0}, V{1.0 / 2.0, 1.0 / 2.0}, V{1.0, 1.0})
170 .add_entity(V{0.0, 1.0 / 2.0}, V{1.0 / 2.0, 1.0 / 2.0}, V{0.0, 1.0}, V{1.0, 1.0})});
171
172 XASSERT(create_2dtemplate_rotations(result, RefinementTypeByDim<2>(0b0001, true)) == 4);
173
174 // No refinement if corner vertex is not isolated
175 result.insert(
176 {RefinementTypeByDim<2>(0b0001, false), RawFaceTemplate().axis_aligned(V{0.0, 0.0}, V{1.0, 1.0})});
177 result.insert(
178 {RefinementTypeByDim<2>(0b0010, false), RawFaceTemplate().axis_aligned(V{0.0, 0.0}, V{1.0, 1.0})});
179 result.insert(
180 {RefinementTypeByDim<2>(0b0100, false), RawFaceTemplate().axis_aligned(V{0.0, 0.0}, V{1.0, 1.0})});
181 result.insert(
182 {RefinementTypeByDim<2>(0b1000, false), RawFaceTemplate().axis_aligned(V{0.0, 0.0}, V{1.0, 1.0})});
183
184 // Templates for edge refinement, with 4 different orientations
185 result.insert(
186 {RefinementTypeByDim<2>(0b0011, false),
188 .add_entity(V{0.0, 0.0}, V{1.0 / 3.0, 0.0}, V{0.0, 1.0}, V{1.0 / 3.0, 1.0 / 2.0})
189 .add_entity(V{1.0 / 3.0, 0.0}, V{2.0 / 3.0, 0.0}, V{1.0 / 3.0, 1.0 / 2.0}, V{2.0 / 3.0, 1.0 / 2.0})
190 .add_entity(V{2.0 / 3.0, 0.0}, V{1.0, 0.0}, V{2.0 / 3.0, 1.0 / 2.0}, V{1.0, 1.0})
191 .add_entity(V{1.0 / 3.0, 1.0 / 2.0}, V{2.0 / 3.0, 1.0 / 2.0}, V{0.0, 1.0}, V{1.0, 1.0})});
192
193 XASSERT(create_2dtemplate_rotations(result, RefinementTypeByDim<2>(0b0011, false)) == 4);
194
195 // Template for two-edge refinement, with 4 different orientations
196 result.insert(
197 {RefinementTypeByDim<2>(0b0111, false),
199 .add_entity(V{0.4, 0.4}, V{0.6, 0.4}, V{0.4, 0.6}, V{0.6, 0.6})
200 .add_entity(V{0.4, 0.6}, V{0.6, 0.6}, V{0.0, 1.0}, V{1.0, 1.0})
201 .add_entity(V{0.6, 0.6}, V{0.6, 0.4}, V{1.0, 1.0}, V{1.0, 0.0})
202 .add_entity(V{0.6, 0.4}, V{0.4, 0.4}, V{1.0, 0.0}, V{0.0, 0.0})
203 .add_entity(V{0.4, 0.4}, V{0.4, 0.6}, V{0.0, 0.0}, V{0.0, 1.0})
204 .recurse(4, result[RefinementTypeByDim<2>(0b1100, 0b0000)])
205 .recurse(3, result[RefinementTypeByDim<2>(0b1100, 0b0000)])});
206
207 XASSERT(create_2dtemplate_rotations(result, RefinementTypeByDim<2>(0b0111, false)) == 4);
208
209 // Opposite Corner refinements
210 // No refinement, but valid for refinement fields
211 result.insert(
212 {RefinementTypeByDim<2>(0b0110, false), RawFaceTemplate().axis_aligned(V{0.0, 0.0}, V{1.0, 1.0})});
213 result.insert(
214 {RefinementTypeByDim<2>(0b1001, false), RawFaceTemplate().axis_aligned(V{0.0, 0.0}, V{1.0, 1.0})});
215
216 // Template for full refinement
217 result.insert({RefinementTypeByDim<2>(0b1111, false), RawFaceTemplate().grid({3, 3}, V{1.0 / 3.0, 1.0 / 3.0})});
218 }
219
220 return result;
221 }
222
225 {
226 static CellMap result;
227
228 using V = typename RawCellTemplate::VertexType;
229
230 if(result.empty())
231 {
232 // No refinement
233 result.insert({RefinementTypeByDim<3>(0b00000000, false), RawCellTemplate()});
234
235 // Isolated point refinement, in eight orientations
236 RefinementTypeByDim<3> isolated_base_type(0b00000100, true);
237 result.insert(
238 {isolated_base_type,
240 .add_entity(
241 V{0.0, 0.0, 0.0},
242 V{1.0, 0.0, 0.0},
243 V{0.0, 1.0 / 2.0, 0.0},
244 V{1.0 / 2.0, 1.0 / 2.0, 0.0},
245 V{0.0, 0.0, 1.0},
246 V{1.0, 0.0, 1.0},
247 V{0.0, 1.0 / 2.0, 1.0 / 2.0},
248 V{1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0})
249 .add_entity(
250 V{1.0 / 2.0, 1.0 / 2.0, 0.0},
251 V{1.0, 0.0, 0.0},
252 V{1.0 / 2.0, 1.0, 0.0},
253 V{1.0, 1.0, 0.0},
254 V{1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0},
255 V{1.0, 0.0, 1.0},
256 V{1.0 / 2.0, 1.0, 1.0 / 2.0},
257 V{1.0, 1.0, 1.0})
258 .add_entity(
259 V{0.0, 1.0 / 2.0, 1.0 / 2.0},
260 V{1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0},
261 V{0.0, 1.0, 1.0 / 2.0},
262 V{1.0 / 2.0, 1.0, 1.0 / 2.0},
263 V{0.0, 0.0, 1.0},
264 V{1.0, 0.0, 1.0},
265 V{0.0, 1.0, 1.0},
266 V{1.0, 1.0, 1.0})
267 .axis_aligned(V{0.0, 1.0 / 2.0, 0.0}, V{1.0 / 2.0, 1.0, 1.0 / 2.0})});
268
269 XASSERT(create_3dtemplate_rotations(result, isolated_base_type) == 8);
270
271 // Non-Isolated point refinement leads to no refinement
272 RefinementTypeByDim<3> non_isolated_point_base_type(0b00000100, false);
273 result.insert(
274 {non_isolated_point_base_type, RawCellTemplate().axis_aligned(V{0.0, 0.0, 0.0}, V{1.0, 1.0, 1.0})});
275
276 XASSERT(create_3dtemplate_rotations(result, non_isolated_point_base_type) == 8);
277
278 // Edge refinement, in twelve orientations
279 RefinementTypeByDim<3> edge_refinement_base_type(0b00000101, false);
280 result.insert(
281 {edge_refinement_base_type,
283 .add_entity(
284 V{0.0, 0.0, 0.0},
285 V{1.0, 0.0, 0.0},
286 V{0.0, 1.0 / 3.0, 0.0},
287 V{1.0 / 2.0, 1.0 / 3.0, 0.0},
288 V{0.0, 0.0, 1.0},
289 V{1.0, 0.0, 1.0},
290 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
291 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0})
292 .add_entity(
293 V{1.0 / 2.0, 1.0 / 3.0, 0.0},
294 V{1.0, 0.0, 0.0},
295 V{1.0 / 2.0, 2.0 / 3.0, 0.0},
296 V{1.0, 1.0, 0.0},
297 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0},
298 V{1.0, 0.0, 1.0},
299 V{1.0 / 2.0, 2.0 / 3.0, 1.0 / 2.0},
300 V{1.0, 1.0, 1.0})
301 .add_entity(
302 V{0.0, 2.0 / 3.0, 0.0},
303 V{1.0 / 2.0, 2.0 / 3.0, 0.0},
304 V{0.0, 1.0, 0.0},
305 V{1.0, 1.0, 0.0},
306 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
307 V{1.0 / 2.0, 2.0 / 3.0, 1.0 / 2.0},
308 V{0.0, 1.0, 1.0},
309 V{1.0, 1.0, 1.0})
310 .add_entity(
311 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
312 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0},
313 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
314 V{1.0 / 2.0, 2.0 / 3.0, 1.0 / 2.0},
315 V{0.0, 0.0, 1.0},
316 V{1.0, 0.0, 1.0},
317 V{0.0, 1.0, 1.0},
318 V{1.0, 1.0, 1.0})
319 .add_entity(
320 V{0.0, 1.0 / 3.0, 0.0},
321 V{1.0 / 2.0, 1.0 / 3.0, 0.0},
322 V{0.0, 2.0 / 3.0, 0.0},
323 V{1.0 / 2.0, 2.0 / 3.0, 0.0},
324 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
325 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0},
326 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
327 V{1.0 / 2.0, 2.0 / 3.0, 1.0 / 2.0})});
328
329 XASSERT(create_3dtemplate_rotations(result, edge_refinement_base_type) == 12);
330
331 // Face refinement, in six orientations
332 RefinementTypeByDim<3> face_base_refinement(0b00001111, false);
333 result.insert(
334 {face_base_refinement,
336 .add_entity(
337 V{0.0, 0.0, 0.0},
338 V{1.0 / 3.0, 0.0, 0.0},
339 V{0.0, 1.0 / 3.0, 0.0},
340 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
341 V{0.0, 0.0, 1.0},
342 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
343 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
344 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0})
345 .add_entity(
346 V{1.0 / 3.0, 0.0, 0.0},
347 V{2.0 / 3.0, 0.0, 0.0},
348 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
349 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
350 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
351 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
352 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
353 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0})
354 .add_entity(
355 V{2.0 / 3.0, 0.0, 0.0},
356 V{1.0, 0.0, 0.0},
357 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
358 V{1.0, 1.0 / 3.0, 0.0},
359 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
360 V{1.0, 0.0, 1.0},
361 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
362 V{1.0, 1.0 / 3.0, 1.0 / 2.0})
363 .add_entity(
364 V{0.0, 1.0 / 3.0, 0.0},
365 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
366 V{0.0, 2.0 / 3.0, 0.0},
367 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
368 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
369 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
370 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
371 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0})
372 .add_entity(
373 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
374 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
375 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
376 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
377 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
378 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
379 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
380 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0})
381 .add_entity(
382 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
383 V{1.0, 1.0 / 3.0, 0.0},
384 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
385 V{1.0, 2.0 / 3.0, 0.0},
386 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
387 V{1.0, 1.0 / 3.0, 1.0 / 2.0},
388 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
389 V{1.0, 2.0 / 3.0, 1.0 / 2.0})
390 .add_entity(
391 V{0.0, 2.0 / 3.0, 0.0},
392 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
393 V{0.0, 1.0, 0.0},
394 V{1.0 / 3.0, 1.0, 0.0},
395 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
396 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
397 V{0.0, 1.0, 1.0},
398 V{1.0 / 3.0, 1.0, 1.0 / 2.0})
399 .add_entity(
400 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
401 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
402 V{1.0 / 3.0, 1.0, 0.0},
403 V{2.0 / 3.0, 1.0, 0.0},
404 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
405 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
406 V{1.0 / 3.0, 1.0, 1.0 / 2.0},
407 V{2.0 / 3.0, 1.0, 1.0 / 2.0})
408 .add_entity(
409 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
410 V{1.0, 2.0 / 3.0, 0.0},
411 V{2.0 / 3.0, 1.0, 0.0},
412 V{1.0, 1.0, 0.0},
413 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
414 V{1.0, 2.0 / 3.0, 1.0 / 2.0},
415 V{2.0 / 3.0, 1.0, 1.0 / 2.0},
416 V{1.0, 1.0, 1.0})
417 .add_entity(
418 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
419 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
420 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
421 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
422 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
423 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
424 V{1.0 / 3.0, 1.0, 1.0 / 2.0},
425 V{2.0 / 3.0, 1.0, 1.0 / 2.0})
426 .add_entity(
427 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
428 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
429 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
430 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
431 V{0.0, 0.0, 1.0},
432 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
433 V{0.0, 1.0, 1.0},
434 V{1.0 / 3.0, 1.0, 1.0 / 2.0})
435 .add_entity(
436 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
437 V{1.0, 1.0 / 3.0, 1.0 / 2.0},
438 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
439 V{1.0, 2.0 / 3.0, 1.0 / 2.0},
440 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
441 V{1.0, 0.0, 1.0},
442 V{2.0 / 3.0, 1.0, 1.0 / 2.0},
443 V{1.0, 1.0, 1.0})
444 .add_entity(
445 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
446 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
447 V{1.0 / 3.0, 1.0, 1.0 / 2.0},
448 V{2.0 / 3.0, 1.0, 1.0 / 2.0},
449 V{0.0, 0.0, 1.0},
450 V{1.0, 0.0, 1.0},
451 V{0.0, 1.0, 1.0},
452 V{1.0, 1.0, 1.0})});
453
454 XASSERT(create_3dtemplate_rotations(result, face_base_refinement) == 6);
455
456 // Two Edge Refinement, with 24? orientations
457 RefinementTypeByDim<3> two_edge_base_refinement(0b00001101, false);
458 result.insert(
459 {two_edge_base_refinement,
461 .add_entity(
462 V{0.0, 0.0, 0.0},
463 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
464 V{0.0, 1.0, 0.0},
465 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
466 V{0.0, 0.0, 1.0},
467 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
468 V{0.0, 1.0, 1.0},
469 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0})
470 .add_entity(
471 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
472 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
473 V{0.0, 1.0, 0.0},
474 V{1.0, 1.0, 0.0},
475 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
476 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
477 V{0.0, 1.0, 1.0},
478 V{1.0, 1.0, 1.0})
479 .add_entity(
480 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
481 V{1.0, 0.0, 0.0},
482 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
483 V{1.0, 1.0, 0.0},
484 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
485 V{1.0, 0.0, 1.0},
486 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
487 V{1.0, 1.0, 1.0})
488 .add_entity(
489 V{0.0, 0.0, 0.0},
490 V{1.0, 0.0, 0.0},
491 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
492 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
493 V{0.0, 0.0, 1.0},
494 V{1.0, 0.0, 1.0},
495 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
496 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0})
497 .add_entity(
498 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
499 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
500 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
501 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
502 V{0.0, 0.0, 1.0},
503 V{1.0, 0.0, 1.0},
504 V{0.0, 1.0, 1.0},
505 V{1.0, 1.0, 1.0})
506 .add_entity(
507 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
508 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
509 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
510 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
511 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
512 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
513 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
514 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0})
515 .recurse(0, result[RefinementTypeByDim<3>(0b00000101, false)])
516 // Note: Face 0 was replaced in the previous recurse call
517 // We recurse on face 0 again, but mean the face 1 of before the first recursion
518 .recurse(0, result[RefinementTypeByDim<3>(0b00001100, false)])});
519
520 XASSERT(create_3dtemplate_rotations(result, two_edge_base_refinement) == 24);
521
522 // Two face Refinement, with 12? orientations
523 RefinementTypeByDim<3> two_face_base_refinement(0b11011101, false);
524 result.insert(
525 {two_face_base_refinement,
527 .add_entity(
528 V{0.0, 0.0, 0.0},
529 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
530 V{0.0, 1.0, 0.0},
531 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
532 V{0.0, 0.0, 1.0},
533 V{2.0 / 5.0, 2.0 / 5.0, 1.0},
534 V{0.0, 1.0, 1.0},
535 V{2.0 / 5.0, 3.0 / 5.0, 1.0})
536 .add_entity(
537 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
538 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
539 V{0.0, 1.0, 0.0},
540 V{1.0, 1.0, 0.0},
541 V{2.0 / 5.0, 3.0 / 5.0, 1.0},
542 V{3.0 / 5.0, 3.0 / 5.0, 1.0},
543 V{0.0, 1.0, 1.0},
544 V{1.0, 1.0, 1.0})
545 .add_entity(
546 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
547 V{1.0, 0.0, 0.0},
548 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
549 V{1.0, 1.0, 0.0},
550 V{3.0 / 5.0, 2.0 / 5.0, 1.0},
551 V{1.0, 0.0, 1.0},
552 V{3.0 / 5.0, 3.0 / 5.0, 1.0},
553 V{1.0, 1.0, 1.0})
554 .add_entity(
555 V{0.0, 0.0, 0.0},
556 V{1.0, 0.0, 0.0},
557 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
558 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
559 V{0.0, 0.0, 1.0},
560 V{1.0, 0.0, 1.0},
561 V{2.0 / 5.0, 2.0 / 5.0, 1.0},
562 V{3.0 / 5.0, 2.0 / 5.0, 1.0})
563 .axis_aligned(V{2.0 / 5.0, 2.0 / 5.0, 0.0}, V{3.0 / 5.0, 3.0 / 5.0, 1.0})
564 .recurse(0, result[RefinementTypeByDim<3>(0b01010101, false)])
565 .recurse(0, result[RefinementTypeByDim<3>(0b11001100, false)])
566 .recurse(0, result[RefinementTypeByDim<3>(0b10001000, false)])
567 .recurse(0, result[RefinementTypeByDim<3>(0b00010001, false)])});
568
569 XASSERT(create_3dtemplate_rotations(result, two_face_base_refinement) == 12);
570 RefinementTypeByDim<3> three_face_base_refinement(0b11011111, false);
571 result.insert(
572 {three_face_base_refinement,
574 .add_entity( // Left Face
575 V{0.0, 0.0, 0.0},
576 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 5.0},
577 V{0.0, 1.0, 0.0},
578 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 5.0},
579 V{0.0, 0.0, 1.0},
580 V{2.0 / 5.0, 2.0 / 5.0, 3.0 / 5.0},
581 V{0.0, 1.0, 1.0},
582 V{2.0 / 5.0, 3.0 / 5.0, 3.0 / 5.0})
583 .add_entity( // Back Face
584 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 5.0},
585 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 5.0},
586 V{0.0, 1.0, 0.0},
587 V{1.0, 1.0, 0.0},
588 V{2.0 / 5.0, 3.0 / 5.0, 3.0 / 5.0},
589 V{3.0 / 5.0, 3.0 / 5.0, 3.0 / 5.0},
590 V{0.0, 1.0, 1.0},
591 V{1.0, 1.0, 1.0})
592 .add_entity( // Right Face
593 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 5.0},
594 V{1.0, 0.0, 0.0},
595 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 5.0},
596 V{1.0, 1.0, 0.0},
597 V{3.0 / 5.0, 2.0 / 5.0, 3.0 / 5.0},
598 V{1.0, 0.0, 1.0},
599 V{3.0 / 5.0, 3.0 / 5.0, 3.0 / 5.0},
600 V{1.0, 1.0, 1.0})
601 .add_entity( // Front Face
602 V{0.0, 0.0, 0.0},
603 V{1.0, 0.0, 0.0},
604 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 5.0},
605 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 5.0},
606 V{0.0, 0.0, 1.0},
607 V{1.0, 0.0, 1.0},
608 V{2.0 / 5.0, 2.0 / 5.0, 3.0 / 5.0},
609 V{3.0 / 5.0, 2.0 / 5.0, 3.0 / 5.0})
610 .add_entity( // Bottom Face
611 V{0.0, 0.0, 0.0},
612 V{1.0, 0.0, 0.0},
613 V{0.0, 1.0, 0.0},
614 V{1.0, 1.0, 0.0},
615 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 5.0},
616 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 5.0},
617 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 5.0},
618 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 5.0})
619 .add_entity( // Top Face
620 V{2.0 / 5.0, 2.0 / 5.0, 3.0 / 5.0},
621 V{3.0 / 5.0, 2.0 / 5.0, 3.0 / 5.0},
622 V{2.0 / 5.0, 3.0 / 5.0, 3.0 / 5.0},
623 V{3.0 / 5.0, 3.0 / 5.0, 3.0 / 5.0},
624 V{0.0, 0.0, 1.0},
625 V{1.0, 0.0, 1.0},
626 V{0.0, 1.0, 1.0},
627 V{1.0, 1.0, 1.0})
628 .axis_aligned(V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 5.0}, V{3.0 / 5.0, 3.0 / 5.0, 3.0 / 5.0})
629 .recurse(0, result[RefinementTypeByDim<3>(0b01010101, false)])
630 .recurse(0, result[RefinementTypeByDim<3>(0b11001100, false)])
631 .recurse(0, result[RefinementTypeByDim<3>(0b10001010, false)])
632 .recurse(0, result[RefinementTypeByDim<3>(0b00010011, false)])
633 .recurse(0, result[RefinementTypeByDim<3>(0b00001111, false)])
634 .recurse(0, result[RefinementTypeByDim<3>(0b11010000, false)])});
635
636 XASSERT(create_3dtemplate_rotations(result, three_face_base_refinement) == 8);
637 // Full refinement
638 result.insert(
639 {RefinementTypeByDim<3>(0b11111111, false),
640 RawCellTemplate().grid({3, 3, 3}, V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0})});
641 }
642
643 return result;
644 }
645 };
646} // namespace FEAT::Geometry
#define XABORTM(msg)
Abortion macro definition with custom message.
Definition: assertion.hpp:192
#define XASSERT(expr)
Assertion macro definition.
Definition: assertion.hpp:262
static EdgeMap & raw_edges()
Returns the raw templates for edges of this template set.
std::unordered_map< RefinementTypeByDim< dim_ >, RawTemplate< Shape::Hypercube< dim_ > > > TemplateMapByDim
Type of map from refinement type to raw templates.
RawTemplate< Shape::Hypercube< 2 > > RawFaceTemplate
Raw face template type.
TemplateMapByDim< 1 > EdgeMap
Type of map from edge refinement types to raw templates.
static TemplateMapByDim< dim_ > & raw_templates()
Accessor for raw template maps.
static constexpr bool is_shape_compatible()
Shape compatability test.
RawTemplate< Shape::Hypercube< 1 > > RawEdgeTemplate
Raw edge template type.
TemplateMapByDim< 3 > CellMap
Type of map from cell refinement types to raw templates.
static CellMap & raw_cells()
Returns the raw templates for cells of this template set.
static FaceMap & raw_faces()
Returns the raw templates for faces of this template set.
TemplateMapByDim< 2 > FaceMap
Type of map from face refinement types to raw templates.
static constexpr int max_children()
Constexpr function for retrieving maximum number of children for any template of this template set.
RawTemplate< Shape::Hypercube< 3 > > RawCellTemplate
Raw cell template type.
Geometry namespace.
String stringify(const T_ &item)
Converts an item into a String.
Definition: string.hpp:944
Hypercube shape tag struct template.
Definition: shape.hpp:64