FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
sun_zhao_ma_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 <bitset>
13#include <unordered_map>
14
15namespace FEAT::Geometry
16{
18 {
19 public:
22
29
31 template<int dim_>
33
35 template<typename Shape__>
37
39 template<int dim_>
40 using TemplateMapByDim = std::unordered_map<RefinementTypeByDim<dim_>, RawTemplate<Shape::Hypercube<dim_>>>;
41
48
55
65 template<typename Shape_>
66 static constexpr bool is_shape_compatible()
67 {
68 return std::is_same_v<Shape_, Shape::Quadrilateral> || std::is_same_v<Shape_, Shape::Hexahedron>;
69 }
70
81 template<int template_dim_, int child_dim_>
82 static constexpr int max_children()
83 {
84 static_assert(template_dim_ <= 3);
85 static_assert(child_dim_ <= 3);
86 const constexpr std::array<std::array<int, 4>, 4> children = {{
87 {0, 0, 0, 0},
88 {2, 3, 0, 0},
89 {8, 18, 11, 0},
90 {18, 69, 87, 37},
91 }};
92 return children[template_dim_][child_dim_];
93 }
94
100 template<int dim_>
102 {
103 if constexpr(dim_ == 1)
104 {
105 return raw_edges();
106 }
107 if constexpr(dim_ == 2)
108 {
109 return raw_faces();
110 }
111 if constexpr(dim_ == 3)
112 {
113 return raw_cells();
114 }
115 XABORTM("SchneidersData supplied no templates of dimension " + stringify(dim_));
116 }
117
120 {
121 static EdgeMap result = {};
122
123 using V = typename RawEdgeTemplate::VertexType;
124
125 if(result.empty())
126 {
127 // No refinement unless either both vertices are marked or one of them is isolated
128 result.insert({RefinementTypeByDim<1>(0b00, false), RawEdgeTemplate()});
129 result.insert({RefinementTypeByDim<1>(0b10, false), RawEdgeTemplate().add_entity(V{0.0}, V{1.0})});
130 result.insert({RefinementTypeByDim<1>(0b01, false), RawEdgeTemplate().add_entity(V{0.0}, V{1.0})});
131
132 // Split edge in half, if adjacent to isolated point
133 result.insert(
134 {RefinementTypeByDim<1>(0b01, true),
135 RawEdgeTemplate().add_entity(V{0.0}, V{1.0 / 2.0}).add_entity(V{1.0 / 2.0}, V{1.0})});
136
137 result.insert(
138 {RefinementTypeByDim<1>(0b10, true),
139 RawEdgeTemplate().add_entity(V{0.0}, V{1.0 / 2.0}).add_entity(V{1.0 / 2.0}, V{1.0})});
140
141 // Split in thirds if adjacent to two marked vertices
142 result.insert(
143 {RefinementTypeByDim<1>(0b11, false),
145 .add_entity(V{0.0}, V{1.0 / 3.0})
146 .add_entity(V{1.0 / 3.0}, V{2.0 / 3.0})
147 .add_entity(V{2.0 / 3.0}, V{1.0})});
148 }
149
150 return result;
151 }
152
155 {
156 static FaceMap result;
157
158 using V = typename RawFaceTemplate::VertexType;
159
160 if(result.empty())
161 {
162 // No refinement if no vertices are marked
163 result.insert({RefinementTypeByDim<2>(0b0000, false), RawFaceTemplate()});
164
165 // Templates for isolated point refinement, with 4 different orientations
166 result.insert(
167 {RefinementTypeByDim<2>(0b0001, true),
169 .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})
170 .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})
171 .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})});
172
173 XASSERT(create_2dtemplate_rotations(result, RefinementTypeByDim<2>(0b0001, true)) == 4);
174
175 // No refinement if corner vertex is not isolated
176 result.insert(
177 {RefinementTypeByDim<2>(0b0001, false),
178 RawFaceTemplate().add_entity(V{0.0, 0.0}, V{1.0, 0.0}, V{0.0, 1.0}, V{1.0, 1.0})});
179 result.insert(
180 {RefinementTypeByDim<2>(0b0010, false),
181 RawFaceTemplate().add_entity(V{0.0, 0.0}, V{1.0, 0.0}, V{0.0, 1.0}, V{1.0, 1.0})});
182 result.insert(
183 {RefinementTypeByDim<2>(0b0100, false),
184 RawFaceTemplate().add_entity(V{0.0, 0.0}, V{1.0, 0.0}, V{0.0, 1.0}, V{1.0, 1.0})});
185 result.insert(
186 {RefinementTypeByDim<2>(0b1000, false),
187 RawFaceTemplate().add_entity(V{0.0, 0.0}, V{1.0, 0.0}, V{0.0, 1.0}, V{1.0, 1.0})});
188
189 // Templates for edge refinement, with 4 different orientations
190 result.insert(
191 {RefinementTypeByDim<2>(0b0011, false),
193 .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})
194 .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})
195 .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})
196 .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})});
197
198 XASSERT(create_2dtemplate_rotations(result, RefinementTypeByDim<2>(0b0011, false)) == 4);
199
200 // Template for two-edge refinement, with 4 different orientations
201 result.insert(
202 {RefinementTypeByDim<2>(0b0111, false),
204 .add_entity(V{0.4, 0.4}, V{0.6, 0.4}, V{0.4, 0.6}, V{0.6, 0.6})
205 .add_entity(V{0.4, 0.6}, V{0.6, 0.6}, V{0.0, 1.0}, V{1.0, 1.0})
206 .add_entity(V{0.6, 0.6}, V{0.6, 0.4}, V{1.0, 1.0}, V{1.0, 0.0})
207 .add_entity(V{0.6, 0.4}, V{0.4, 0.4}, V{1.0, 0.0}, V{0.0, 0.0})
208 .add_entity(V{0.4, 0.4}, V{0.4, 0.6}, V{0.0, 0.0}, V{0.0, 1.0})
209 .recurse(4, result[RefinementTypeByDim<2>(0b1100, 0b0000)])
210 .recurse(3, result[RefinementTypeByDim<2>(0b1100, 0b0000)])});
211
212 XASSERT(create_2dtemplate_rotations(result, RefinementTypeByDim<2>(0b0111, false)) == 4);
213
214 // Opposite Corner refinements
215 // No refinement, but valid for refinement fields
216 result.insert(
217 {RefinementTypeByDim<2>(0b0110, false),
218 RawFaceTemplate().add_entity(V{0.0, 0.0}, V{1.0, 0.0}, V{0.0, 1.0}, V{1.0, 1.0})});
219 result.insert(
220 {RefinementTypeByDim<2>(0b1001, false),
221 RawFaceTemplate().add_entity(V{0.0, 0.0}, V{1.0, 0.0}, V{0.0, 1.0}, V{1.0, 1.0})});
222
223 // Template for full refinement
224 result.insert({RefinementTypeByDim<2>(0b1111, false), RawFaceTemplate().grid({3, 3}, V{1.0 / 3.0, 1.0 / 3.0})});
225 }
226
227 return result;
228 }
229
232 {
233 static CellMap result;
234
235 using V = typename RawCellTemplate::VertexType;
236
237 if(result.empty())
238 {
239 // No refinement
240 result.insert({RefinementTypeByDim<3>(0b00000000, false), RawCellTemplate()});
241
242 // Isolated point refinement, in eight orientations
243 RefinementTypeByDim<3> isolated_base_type(0b00000100, true);
244 result.insert(
245 {isolated_base_type,
247 .add_entity(
248 V{0.0, 0.0, 0.0},
249 V{1.0, 0.0, 0.0},
250 V{0.0, 1.0 / 2.0, 0.0},
251 V{1.0 / 2.0, 1.0 / 2.0, 0.0},
252 V{0.0, 0.0, 1.0},
253 V{1.0, 0.0, 1.0},
254 V{0.0, 1.0 / 2.0, 1.0 / 2.0},
255 V{1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0})
256 .add_entity(
257 V{1.0 / 2.0, 1.0 / 2.0, 0.0},
258 V{1.0, 0.0, 0.0},
259 V{1.0 / 2.0, 1.0, 0.0},
260 V{1.0, 1.0, 0.0},
261 V{1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0},
262 V{1.0, 0.0, 1.0},
263 V{1.0 / 2.0, 1.0, 1.0 / 2.0},
264 V{1.0, 1.0, 1.0})
265 .add_entity(
266 V{0.0, 1.0 / 2.0, 1.0 / 2.0},
267 V{1.0 / 2.0, 1.0 / 2.0, 1.0 / 2.0},
268 V{0.0, 1.0, 1.0 / 2.0},
269 V{1.0 / 2.0, 1.0, 1.0 / 2.0},
270 V{0.0, 0.0, 1.0},
271 V{1.0, 0.0, 1.0},
272 V{0.0, 1.0, 1.0},
273 V{1.0, 1.0, 1.0})
274 .axis_aligned(V{0.0, 1.0 / 2.0, 0.0}, V{1.0 / 2.0, 1.0, 1.0 / 2.0})});
275
276 XASSERT(create_3dtemplate_rotations(result, isolated_base_type) == 8);
277
278 // Non-Isolated point refinement leads to no refinement
279 RefinementTypeByDim<3> non_isolated_point_base_type(0b00000100, false);
280 result.insert(
281 {non_isolated_point_base_type, RawCellTemplate().axis_aligned(V{0.0, 0.0, 0.0}, V{1.0, 1.0, 1.0})});
282
283 XASSERT(create_3dtemplate_rotations(result, non_isolated_point_base_type) == 8);
284
285 // Edge refinement, in twelve orientations
286 RefinementTypeByDim<3> edge_refinement_base_type(0b00000101, false);
287 result.insert(
288 {edge_refinement_base_type,
290 .add_entity(
291 V{0.0, 0.0, 0.0},
292 V{1.0, 0.0, 0.0},
293 V{0.0, 1.0 / 3.0, 0.0},
294 V{1.0 / 2.0, 1.0 / 3.0, 0.0},
295 V{0.0, 0.0, 1.0},
296 V{1.0, 0.0, 1.0},
297 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
298 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0})
299 .add_entity(
300 V{1.0 / 2.0, 1.0 / 3.0, 0.0},
301 V{1.0, 0.0, 0.0},
302 V{1.0 / 2.0, 2.0 / 3.0, 0.0},
303 V{1.0, 1.0, 0.0},
304 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0},
305 V{1.0, 0.0, 1.0},
306 V{1.0 / 2.0, 2.0 / 3.0, 1.0 / 2.0},
307 V{1.0, 1.0, 1.0})
308 .add_entity(
309 V{0.0, 2.0 / 3.0, 0.0},
310 V{1.0 / 2.0, 2.0 / 3.0, 0.0},
311 V{0.0, 1.0, 0.0},
312 V{1.0, 1.0, 0.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, 1.0, 1.0},
316 V{1.0, 1.0, 1.0})
317 .add_entity(
318 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
319 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0},
320 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
321 V{1.0 / 2.0, 2.0 / 3.0, 1.0 / 2.0},
322 V{0.0, 0.0, 1.0},
323 V{1.0, 0.0, 1.0},
324 V{0.0, 1.0, 1.0},
325 V{1.0, 1.0, 1.0})
326 .add_entity(
327 V{0.0, 1.0 / 3.0, 0.0},
328 V{1.0 / 2.0, 1.0 / 3.0, 0.0},
329 V{0.0, 2.0 / 3.0, 0.0},
330 V{1.0 / 2.0, 2.0 / 3.0, 0.0},
331 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
332 V{1.0 / 2.0, 1.0 / 3.0, 1.0 / 2.0},
333 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
334 V{1.0 / 2.0, 2.0 / 3.0, 1.0 / 2.0})});
335
336 XASSERT(create_3dtemplate_rotations(result, edge_refinement_base_type) == 12);
337
338 // Face refinement, in six orientations
339 RefinementTypeByDim<3> face_base_refinement(0b00001111, false);
340 result.insert(
341 {face_base_refinement,
343 .add_entity(
344 V{0.0, 0.0, 0.0},
345 V{1.0 / 3.0, 0.0, 0.0},
346 V{0.0, 1.0 / 3.0, 0.0},
347 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
348 V{0.0, 0.0, 1.0},
349 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
350 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
351 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0})
352 .add_entity(
353 V{1.0 / 3.0, 0.0, 0.0},
354 V{2.0 / 3.0, 0.0, 0.0},
355 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
356 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
357 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
358 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
359 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
360 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0})
361 .add_entity(
362 V{2.0 / 3.0, 0.0, 0.0},
363 V{1.0, 0.0, 0.0},
364 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
365 V{1.0, 1.0 / 3.0, 0.0},
366 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
367 V{1.0, 0.0, 1.0},
368 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
369 V{1.0, 1.0 / 3.0, 1.0 / 2.0})
370 .add_entity(
371 V{0.0, 1.0 / 3.0, 0.0},
372 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
373 V{0.0, 2.0 / 3.0, 0.0},
374 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
375 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
376 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
377 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
378 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0})
379 .add_entity(
380 V{1.0 / 3.0, 1.0 / 3.0, 0.0},
381 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
382 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
383 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
384 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
385 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
386 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
387 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0})
388 .add_entity(
389 V{2.0 / 3.0, 1.0 / 3.0, 0.0},
390 V{1.0, 1.0 / 3.0, 0.0},
391 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
392 V{1.0, 2.0 / 3.0, 0.0},
393 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
394 V{1.0, 1.0 / 3.0, 1.0 / 2.0},
395 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
396 V{1.0, 2.0 / 3.0, 1.0 / 2.0})
397 .add_entity(
398 V{0.0, 2.0 / 3.0, 0.0},
399 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
400 V{0.0, 1.0, 0.0},
401 V{1.0 / 3.0, 1.0, 0.0},
402 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
403 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
404 V{0.0, 1.0, 1.0},
405 V{1.0 / 3.0, 1.0, 1.0 / 2.0})
406 .add_entity(
407 V{1.0 / 3.0, 2.0 / 3.0, 0.0},
408 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
409 V{1.0 / 3.0, 1.0, 0.0},
410 V{2.0 / 3.0, 1.0, 0.0},
411 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
412 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
413 V{1.0 / 3.0, 1.0, 1.0 / 2.0},
414 V{2.0 / 3.0, 1.0, 1.0 / 2.0})
415 .add_entity(
416 V{2.0 / 3.0, 2.0 / 3.0, 0.0},
417 V{1.0, 2.0 / 3.0, 0.0},
418 V{2.0 / 3.0, 1.0, 0.0},
419 V{1.0, 1.0, 0.0},
420 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
421 V{1.0, 2.0 / 3.0, 1.0 / 2.0},
422 V{2.0 / 3.0, 1.0, 1.0 / 2.0},
423 V{1.0, 1.0, 1.0})
424 .add_entity(
425 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
426 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
427 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
428 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
429 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
430 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
431 V{1.0 / 3.0, 1.0, 1.0 / 2.0},
432 V{2.0 / 3.0, 1.0, 1.0 / 2.0})
433 .add_entity(
434 V{0.0, 1.0 / 3.0, 1.0 / 2.0},
435 V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
436 V{0.0, 2.0 / 3.0, 1.0 / 2.0},
437 V{1.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
438 V{0.0, 0.0, 1.0},
439 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
440 V{0.0, 1.0, 1.0},
441 V{1.0 / 3.0, 1.0, 1.0 / 2.0})
442 .add_entity(
443 V{2.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0},
444 V{1.0, 1.0 / 3.0, 1.0 / 2.0},
445 V{2.0 / 3.0, 2.0 / 3.0, 1.0 / 3.0},
446 V{1.0, 2.0 / 3.0, 1.0 / 2.0},
447 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
448 V{1.0, 0.0, 1.0},
449 V{2.0 / 3.0, 1.0, 1.0 / 2.0},
450 V{1.0, 1.0, 1.0})
451 .add_entity(
452 V{1.0 / 3.0, 0.0, 1.0 / 2.0},
453 V{2.0 / 3.0, 0.0, 1.0 / 2.0},
454 V{1.0 / 3.0, 1.0, 1.0 / 2.0},
455 V{2.0 / 3.0, 1.0, 1.0 / 2.0},
456 V{0.0, 0.0, 1.0},
457 V{1.0, 0.0, 1.0},
458 V{0.0, 1.0, 1.0},
459 V{1.0, 1.0, 1.0})});
460
461 XASSERT(create_3dtemplate_rotations(result, face_base_refinement) == 6);
462
463 // Two Edge Refinement, with 24? orientations
464 RefinementTypeByDim<3> two_edge_base_refinement(0b00001101, false);
465 result.insert(
466 {two_edge_base_refinement,
468 .add_entity(
469 V{0.0, 0.0, 0.0},
470 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
471 V{0.0, 1.0, 0.0},
472 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
473 V{0.0, 0.0, 1.0},
474 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
475 V{0.0, 1.0, 1.0},
476 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0})
477 .add_entity(
478 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
479 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
480 V{0.0, 1.0, 0.0},
481 V{1.0, 1.0, 0.0},
482 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
483 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
484 V{0.0, 1.0, 1.0},
485 V{1.0, 1.0, 1.0})
486 .add_entity(
487 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
488 V{1.0, 0.0, 0.0},
489 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
490 V{1.0, 1.0, 0.0},
491 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
492 V{1.0, 0.0, 1.0},
493 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
494 V{1.0, 1.0, 1.0})
495 .add_entity(
496 V{0.0, 0.0, 0.0},
497 V{1.0, 0.0, 0.0},
498 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
499 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
500 V{0.0, 0.0, 1.0},
501 V{1.0, 0.0, 1.0},
502 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
503 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0})
504 .add_entity(
505 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
506 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
507 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
508 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
509 V{0.0, 0.0, 1.0},
510 V{1.0, 0.0, 1.0},
511 V{0.0, 1.0, 1.0},
512 V{1.0, 1.0, 1.0})
513 .add_entity(
514 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
515 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
516 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
517 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
518 V{2.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
519 V{3.0 / 5.0, 2.0 / 5.0, 2.0 / 3.0},
520 V{2.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0},
521 V{3.0 / 5.0, 3.0 / 5.0, 2.0 / 3.0})
522 .recurse(0, result[RefinementTypeByDim<3>(0b00000101, false)])
523 // Note: Face 0 was replaced in the previous recurse call
524 // We recurse on face 0 again, but mean the face 1 of before the first recursion
525 .recurse(0, result[RefinementTypeByDim<3>(0b00001100, false)])});
526
527 XASSERT(create_3dtemplate_rotations(result, two_edge_base_refinement) == 24);
528
529 // Two face Refinement, with 12? orientations
530 RefinementTypeByDim<3> two_face_base_refinement(0b11011101, false);
531 result.insert(
532 {two_face_base_refinement,
534 .add_entity(
535 V{0.0, 0.0, 0.0},
536 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
537 V{0.0, 1.0, 0.0},
538 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
539 V{0.0, 0.0, 1.0},
540 V{2.0 / 5.0, 2.0 / 5.0, 1.0},
541 V{0.0, 1.0, 1.0},
542 V{2.0 / 5.0, 3.0 / 5.0, 1.0})
543 .add_entity(
544 V{2.0 / 5.0, 3.0 / 5.0, 0.0},
545 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
546 V{0.0, 1.0, 0.0},
547 V{1.0, 1.0, 0.0},
548 V{2.0 / 5.0, 3.0 / 5.0, 1.0},
549 V{3.0 / 5.0, 3.0 / 5.0, 1.0},
550 V{0.0, 1.0, 1.0},
551 V{1.0, 1.0, 1.0})
552 .add_entity(
553 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
554 V{1.0, 0.0, 0.0},
555 V{3.0 / 5.0, 3.0 / 5.0, 0.0},
556 V{1.0, 1.0, 0.0},
557 V{3.0 / 5.0, 2.0 / 5.0, 1.0},
558 V{1.0, 0.0, 1.0},
559 V{3.0 / 5.0, 3.0 / 5.0, 1.0},
560 V{1.0, 1.0, 1.0})
561 .add_entity(
562 V{0.0, 0.0, 0.0},
563 V{1.0, 0.0, 0.0},
564 V{2.0 / 5.0, 2.0 / 5.0, 0.0},
565 V{3.0 / 5.0, 2.0 / 5.0, 0.0},
566 V{0.0, 0.0, 1.0},
567 V{1.0, 0.0, 1.0},
568 V{2.0 / 5.0, 2.0 / 5.0, 1.0},
569 V{3.0 / 5.0, 2.0 / 5.0, 1.0})
570 .axis_aligned(V{2.0 / 5.0, 2.0 / 5.0, 0.0}, V{3.0 / 5.0, 3.0 / 5.0, 1.0})
571 .recurse(0, result[RefinementTypeByDim<3>(0b01010101, false)])
572 .recurse(0, result[RefinementTypeByDim<3>(0b11001100, false)])
573 .recurse(0, result[RefinementTypeByDim<3>(0b10001000, false)])
574 .recurse(0, result[RefinementTypeByDim<3>(0b00010001, false)])});
575
576 XASSERT(create_3dtemplate_rotations(result, two_face_base_refinement) == 12);
577
578 // Full refinement
579 result.insert(
580 {RefinementTypeByDim<3>(0b11111111, false),
581 RawCellTemplate().grid({3, 3, 3}, V{1.0 / 3.0, 1.0 / 3.0, 1.0 / 3.0})});
582 }
583
584 return result;
585 }
586 };
587} // 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 FaceMap & raw_faces()
Returns the raw templates for faces of this template set.
static constexpr bool is_shape_compatible()
Shape compatability test.
static constexpr int max_children()
Constexpr function for retrieving maximum number of children for any template of this template set.
static CellMap & raw_cells()
Returns the raw templates for cells of this template set.
TemplateMapByDim< 1 > EdgeMap
Type of map from edge refinement types to raw templates.
RawTemplate< Shape::Hypercube< 1 > > RawEdgeTemplate
Raw edge template type.
TemplateMapByDim< 3 > CellMap
Type of map from cell refinement types to raw templates.
TemplateMapByDim< 2 > FaceMap
Type of map from face refinement types to raw templates.
static TemplateMapByDim< dim_ > & raw_templates()
Accessor for raw template maps.
RawTemplate< Shape::Hypercube< 2 > > RawFaceTemplate
Raw face template type.
RawTemplate< Shape::Hypercube< 3 > > RawCellTemplate
Raw cell template type.
std::unordered_map< RefinementTypeByDim< dim_ >, RawTemplate< Shape::Hypercube< dim_ > > > TemplateMapByDim
Type of map from refinement type to raw templates.
static EdgeMap & raw_edges()
Returns the raw templates for edges of this template set.
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