MFEM v4.8.0
Finite element discretization library
Loading...
Searching...
No Matches
ncmesh_tables.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2025, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_NCMESH_TABLES
13#define MFEM_NCMESH_TABLES
14
15namespace mfem
16{
17
18static constexpr int ref_type_num_children[8] = { 0, 2, 2, 4, 2, 4, 4, 8 };
19
20// derefinement tables
21// The first n numbers in each line are the refined elements that contain
22// the vertices of the parent element. The next m numbers in each line
23// are the refined elements that contain the faces attributes of the parent
24// element.
25
26static constexpr int quad_deref_table[3][4 + 4] =
27{
28 { 0, 1, 1, 0, /**/ 1, 1, 0, 0 }, // 1 - X
29 { 0, 0, 1, 1, /**/ 0, 0, 1, 1 }, // 2 - Y
30 { 0, 1, 2, 3, /**/ 1, 1, 3, 3 } // 3 - iso
31};
32
33static constexpr int hex_deref_table[7][8 + 6] =
34{
35 { 0, 1, 1, 0, 0, 1, 1, 0, /**/ 1, 1, 1, 0, 0, 0 }, // 1 - X
36 { 0, 0, 1, 1, 0, 0, 1, 1, /**/ 0, 0, 0, 1, 1, 1 }, // 2 - Y
37 { 0, 1, 2, 3, 0, 1, 2, 3, /**/ 1, 1, 1, 3, 3, 3 }, // 3 - XY
38 { 0, 0, 0, 0, 1, 1, 1, 1, /**/ 0, 0, 0, 1, 1, 1 }, // 4 - Z
39 { 0, 1, 1, 0, 3, 2, 2, 3, /**/ 1, 1, 1, 3, 3, 3 }, // 5 - XZ
40 { 0, 0, 1, 1, 2, 2, 3, 3, /**/ 0, 0, 0, 3, 3, 3 }, // 6 - YZ
41 { 0, 1, 2, 3, 4, 5, 6, 7, /**/ 1, 1, 1, 7, 7, 7 } // 7 - iso
42};
43
44static constexpr int prism_deref_table[7][6 + 5] =
45{
46 {-1,-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 1
47 {-1,-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 2
48 { 0, 1, 2, 0, 1, 2, /**/ 0, 0, 0, 1, 0 }, // 3 - XY
49 { 0, 0, 0, 1, 1, 1, /**/ 0, 1, 0, 0, 0 }, // 4 - Z
50 {-1,-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 5
51 {-1,-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 6
52 { 0, 1, 2, 4, 5, 6, /**/ 0, 5, 0, 5, 0 } // 7 - iso
53};
54
55static constexpr int pyramid_deref_table[7][5 + 5] =
56{
57 {-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 1
58 {-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 2
59 {-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 3
60 {-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 4
61 {-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 5
62 {-1,-1,-1,-1,-1, /**/ -1,-1,-1,-1,-1 }, // 6
63 { 0, 1, 2, 3, 5, /**/ 0, 5, 5, 5, 5 } // 7 - iso
64};
65
66// child ordering tables
67
68static constexpr char quad_hilbert_child_order[8][4] =
69{
70 {0,1,2,3}, {0,3,2,1}, {1,2,3,0}, {1,0,3,2},
71 {2,3,0,1}, {2,1,0,3}, {3,0,1,2}, {3,2,1,0}
72};
73
74static constexpr char quad_hilbert_child_state[8][4] =
75{
76 {1,0,0,5}, {0,1,1,4}, {3,2,2,7}, {2,3,3,6},
77 {5,4,4,1}, {4,5,5,0}, {7,6,6,3}, {6,7,7,2}
78};
79
80static constexpr char hex_hilbert_child_order[24][8] =
81{
82 {0,1,2,3,7,6,5,4}, {0,3,7,4,5,6,2,1}, {0,4,5,1,2,6,7,3},
83 {1,0,3,2,6,7,4,5}, {1,2,6,5,4,7,3,0}, {1,5,4,0,3,7,6,2},
84 {2,1,5,6,7,4,0,3}, {2,3,0,1,5,4,7,6}, {2,6,7,3,0,4,5,1},
85 {3,0,4,7,6,5,1,2}, {3,2,1,0,4,5,6,7}, {3,7,6,2,1,5,4,0},
86 {4,0,1,5,6,2,3,7}, {4,5,6,7,3,2,1,0}, {4,7,3,0,1,2,6,5},
87 {5,1,0,4,7,3,2,6}, {5,4,7,6,2,3,0,1}, {5,6,2,1,0,3,7,4},
88 {6,2,3,7,4,0,1,5}, {6,5,1,2,3,0,4,7}, {6,7,4,5,1,0,3,2},
89 {7,3,2,6,5,1,0,4}, {7,4,0,3,2,1,5,6}, {7,6,5,4,0,1,2,3}
90};
91
92static constexpr char hex_hilbert_child_state[24][8] =
93{
94 {1,2,2,7,7,21,21,17}, {2,0,0,22,22,16,16,8}, {0,1,1,15,15,6,6,23},
95 {4,5,5,10,10,18,18,14}, {5,3,3,19,19,13,13,11}, {3,4,4,12,12,9,9,20},
96 {8,7,7,17,17,23,23,2}, {6,8,8,0,0,15,15,22}, {7,6,6,21,21,1,1,16},
97 {11,10,10,14,14,20,20,5}, {9,11,11,3,3,12,12,19}, {10,9,9,18,18,4,4,13},
98 {13,14,14,5,5,19,19,10}, {14,12,12,20,20,11,11,4}, {12,13,13,9,9,3,3,18},
99 {16,17,17,2,2,22,22,7}, {17,15,15,23,23,8,8,1}, {15,16,16,6,6,0,0,21},
100 {20,19,19,11,11,14,14,3}, {18,20,20,4,4,10,10,12}, {19,18,18,13,13,5,5,9},
101 {23,22,22,8,8,17,17,0}, {21,23,23,1,1,7,7,15}, {22,21,21,16,16,2,2,6}
102};
103
104
105// child/parent reference domain transforms
107
108// reference domain coordinates as fixed point numbers
109static constexpr RefCoord T_HALF = (1ll << 59);
110static constexpr RefCoord T_ONE = (1ll << 60);
111static constexpr RefCoord T_TWO = (1ll << 61);
112
113// (scaling factors have a different fixed point multiplier)
114static constexpr RefCoord S_HALF = 1;
115static constexpr RefCoord S_ONE = 2;
116static constexpr RefCoord S_TWO = 4;
117
118static constexpr RefCoord tri_corners[3][3] =
119{
120 { 0, 0, 0},
121 {T_ONE, 0, 0},
122 { 0, T_ONE, 0}
123};
124
125static constexpr RefCoord quad_corners[4][3] =
126{
127 { 0, 0, 0},
128 {T_ONE, 0, 0},
129 {T_ONE, T_ONE, 0},
130 { 0, T_ONE, 0}
131};
132
133static constexpr RefCoord hex_corners[8][3] =
134{
135 { 0, 0, 0},
136 {T_ONE, 0, 0},
137 {T_ONE, T_ONE, 0},
138 { 0, T_ONE, 0},
139 { 0, 0, T_ONE},
140 {T_ONE, 0, T_ONE},
141 {T_ONE, T_ONE, T_ONE},
142 { 0, T_ONE, T_ONE}
143};
144
145static constexpr RefCoord prism_corners[6][3] =
146{
147 { 0, 0, 0},
148 {T_ONE, 0, 0},
149 { 0, T_ONE, 0},
150 { 0, 0, T_ONE},
151 {T_ONE, 0, T_ONE},
152 { 0, T_ONE, T_ONE}
153};
154
155static constexpr RefCoord pyramid_corners[5][3] =
156{
157 { 0, 0, 0},
158 {T_ONE, 0, 0},
159 {T_ONE, T_ONE, 0},
160 { 0, T_ONE, 0},
161 { 0, 0, T_ONE}
162};
163
165static const RefPoint* geom_corners[8] =
166{
167 NULL, // point
168 NULL, // segment
169 tri_corners,
170 quad_corners,
171 NULL, // tetrahedron
172 hex_corners,
173 prism_corners,
174 pyramid_corners
175};
176
177// reference domain transform: 3 scales, 3 translations
178struct RefTrf
179{
180 RefCoord s[3], t[3];
181
182 void Apply(const RefCoord src[3], RefCoord dst[3]) const
183 {
184 for (int i = 0; i < 3; i++)
185 {
186 dst[i] = (src[i]*s[i] >> 1) + t[i];
187 }
188 }
189};
190
191static constexpr RefTrf quad_parent_rt1[2] =
192{
193 { {S_HALF, S_ONE, 0}, { 0, 0, 0} },
194 { {S_HALF, S_ONE, 0}, {T_HALF, 0, 0} }
195};
196
197static constexpr RefTrf quad_child_rt1[2] =
198{
199 { {S_TWO, S_ONE, 0}, { 0, 0, 0} },
200 { {S_TWO, S_ONE, 0}, {-T_ONE, 0, 0} }
201};
202
203static constexpr RefTrf quad_parent_rt2[2] =
204{
205 { {S_ONE, S_HALF, 0}, {0, 0, 0} },
206 { {S_ONE, S_HALF, 0}, {0, T_HALF, 0} }
207};
208
209static constexpr RefTrf quad_child_rt2[2] =
210{
211 { {S_ONE, S_TWO, 0}, {0, 0, 0} },
212 { {S_ONE, S_TWO, 0}, {0, -T_ONE, 0} }
213};
214
215static constexpr RefTrf quad_parent_rt3[4] =
216{
217 { {S_HALF, S_HALF, 0}, { 0, 0, 0} },
218 { {S_HALF, S_HALF, 0}, {T_HALF, 0, 0} },
219 { {S_HALF, S_HALF, 0}, {T_HALF, T_HALF, 0} },
220 { {S_HALF, S_HALF, 0}, { 0, T_HALF, 0} }
221};
222
223static constexpr RefTrf quad_child_rt3[4] =
224{
225 { {S_TWO, S_TWO, 0}, { 0, 0, 0} },
226 { {S_TWO, S_TWO, 0}, {-T_ONE, 0, 0} },
227 { {S_TWO, S_TWO, 0}, {-T_ONE, -T_ONE, 0} },
228 { {S_TWO, S_TWO, 0}, { 0, -T_ONE, 0} }
229};
230
231static const RefTrf* quad_parent[4] =
232{
233 NULL,
234 quad_parent_rt1,
235 quad_parent_rt2,
236 quad_parent_rt3
237};
238
239static const RefTrf* quad_child[4] =
240{
241 NULL,
242 quad_child_rt1,
243 quad_child_rt2,
244 quad_child_rt3
245};
246
247static constexpr RefTrf hex_parent_rt1[2] =
248{
249 { {S_HALF, S_ONE, S_ONE}, { 0, 0, 0} },
250 { {S_HALF, S_ONE, S_ONE}, {T_HALF, 0, 0} }
251};
252
253static constexpr RefTrf hex_child_rt1[2] =
254{
255 { {S_TWO, S_ONE, S_ONE}, { 0, 0, 0} },
256 { {S_TWO, S_ONE, S_ONE}, {-T_ONE, 0, 0} }
257};
258
259static constexpr RefTrf hex_parent_rt2[2] =
260{
261 { {S_ONE, S_HALF, S_ONE}, {0, 0, 0} },
262 { {S_ONE, S_HALF, S_ONE}, {0, T_HALF, 0} }
263};
264
265static constexpr RefTrf hex_child_rt2[2] =
266{
267 { {S_ONE, S_TWO, S_ONE}, {0, 0, 0} },
268 { {S_ONE, S_TWO, S_ONE}, {0, -T_ONE, 0} }
269};
270
271static constexpr RefTrf hex_parent_rt3[4] =
272{
273 { {S_HALF, S_HALF, S_ONE}, { 0, 0, 0} },
274 { {S_HALF, S_HALF, S_ONE}, {T_HALF, 0, 0} },
275 { {S_HALF, S_HALF, S_ONE}, {T_HALF, T_HALF, 0} },
276 { {S_HALF, S_HALF, S_ONE}, { 0, T_HALF, 0} }
277};
278
279static constexpr RefTrf hex_child_rt3[4] =
280{
281 { {S_TWO, S_TWO, S_ONE}, { 0, 0, 0} },
282 { {S_TWO, S_TWO, S_ONE}, {-T_ONE, 0, 0} },
283 { {S_TWO, S_TWO, S_ONE}, {-T_ONE, -T_ONE, 0} },
284 { {S_TWO, S_TWO, S_ONE}, { 0, -T_ONE, 0} }
285};
286
287static constexpr RefTrf hex_parent_rt4[2] =
288{
289 { {S_ONE, S_ONE, S_HALF}, {0, 0, 0} },
290 { {S_ONE, S_ONE, S_HALF}, {0, 0, T_HALF} }
291};
292
293static constexpr RefTrf hex_child_rt4[2] =
294{
295 { {S_ONE, S_ONE, S_TWO}, {0, 0, 0} },
296 { {S_ONE, S_ONE, S_TWO}, {0, 0, -T_ONE} }
297};
298
299static constexpr RefTrf hex_parent_rt5[4] =
300{
301 { {S_HALF, S_ONE, S_HALF}, { 0, 0, 0} },
302 { {S_HALF, S_ONE, S_HALF}, {T_HALF, 0, 0} },
303 { {S_HALF, S_ONE, S_HALF}, {T_HALF, 0, T_HALF} },
304 { {S_HALF, S_ONE, S_HALF}, { 0, 0, T_HALF} }
305};
306
307static constexpr RefTrf hex_child_rt5[4] =
308{
309 { {S_TWO, S_ONE, S_TWO}, { 0, 0, 0} },
310 { {S_TWO, S_ONE, S_TWO}, {-T_ONE, 0, 0} },
311 { {S_TWO, S_ONE, S_TWO}, {-T_ONE, 0, -T_ONE} },
312 { {S_TWO, S_ONE, S_TWO}, { 0, 0, -T_ONE} }
313};
314
315static constexpr RefTrf hex_parent_rt6[4] =
316{
317 { {S_ONE, S_HALF, S_HALF}, {0, 0, 0} },
318 { {S_ONE, S_HALF, S_HALF}, {0, T_HALF, 0} },
319 { {S_ONE, S_HALF, S_HALF}, {0, 0, T_HALF} },
320 { {S_ONE, S_HALF, S_HALF}, {0, T_HALF, T_HALF} }
321};
322
323static constexpr RefTrf hex_child_rt6[4] =
324{
325 { {S_ONE, S_TWO, S_TWO}, {0, 0, 0} },
326 { {S_ONE, S_TWO, S_TWO}, {0, -T_ONE, 0} },
327 { {S_ONE, S_TWO, S_TWO}, {0, 0, -T_ONE} },
328 { {S_ONE, S_TWO, S_TWO}, {0, -T_ONE, -T_ONE} }
329};
330
331static constexpr RefTrf hex_parent_rt7[8] =
332{
333 { {S_HALF, S_HALF, S_HALF}, { 0, 0, 0} },
334 { {S_HALF, S_HALF, S_HALF}, {T_HALF, 0, 0} },
335 { {S_HALF, S_HALF, S_HALF}, {T_HALF, T_HALF, 0} },
336 { {S_HALF, S_HALF, S_HALF}, { 0, T_HALF, 0} },
337 { {S_HALF, S_HALF, S_HALF}, { 0, 0, T_HALF} },
338 { {S_HALF, S_HALF, S_HALF}, {T_HALF, 0, T_HALF} },
339 { {S_HALF, S_HALF, S_HALF}, {T_HALF, T_HALF, T_HALF} },
340 { {S_HALF, S_HALF, S_HALF}, { 0, T_HALF, T_HALF} }
341};
342
343static constexpr RefTrf hex_child_rt7[8] =
344{
345 { {S_TWO, S_TWO, S_TWO}, { 0, 0, 0} },
346 { {S_TWO, S_TWO, S_TWO}, {-T_ONE, 0, 0} },
347 { {S_TWO, S_TWO, S_TWO}, {-T_ONE, -T_ONE, 0} },
348 { {S_TWO, S_TWO, S_TWO}, { 0, -T_ONE, 0} },
349 { {S_TWO, S_TWO, S_TWO}, { 0, 0, -T_ONE} },
350 { {S_TWO, S_TWO, S_TWO}, {-T_ONE, 0, -T_ONE} },
351 { {S_TWO, S_TWO, S_TWO}, {-T_ONE, -T_ONE, -T_ONE} },
352 { {S_TWO, S_TWO, S_TWO}, { 0, -T_ONE, -T_ONE} }
353};
354
355static const RefTrf* hex_parent[8] =
356{
357 NULL,
358 hex_parent_rt1,
359 hex_parent_rt2,
360 hex_parent_rt3,
361 hex_parent_rt4,
362 hex_parent_rt5,
363 hex_parent_rt6,
364 hex_parent_rt7
365};
366
367static const RefTrf* hex_child[8] =
368{
369 NULL,
370 hex_child_rt1,
371 hex_child_rt2,
372 hex_child_rt3,
373 hex_child_rt4,
374 hex_child_rt5,
375 hex_child_rt6,
376 hex_child_rt7
377};
378
379static constexpr RefTrf tri_parent_rt3[4] =
380{
381 { { S_HALF, S_HALF, 0}, { 0, 0, 0} },
382 { { S_HALF, S_HALF, 0}, {T_HALF, 0, 0} },
383 { { S_HALF, S_HALF, 0}, { 0, T_HALF, 0} },
384 { {-S_HALF, -S_HALF, 0}, {T_HALF, T_HALF, 0} }
385};
386
387static constexpr RefTrf tri_child_rt3[4] =
388{
389 { { S_TWO, S_TWO, 0}, { 0, 0, 0} },
390 { { S_TWO, S_TWO, 0}, {-T_ONE, 0, 0} },
391 { { S_TWO, S_TWO, 0}, { 0, -T_ONE, 0} },
392 { {-S_TWO, -S_TWO, 0}, { T_ONE, T_ONE, 0} }
393};
394
395static const RefTrf* tri_parent[4] =
396{
397 NULL, NULL, NULL,
398 tri_parent_rt3
399};
400
401static const RefTrf* tri_child[4] =
402{
403 NULL, NULL, NULL,
404 tri_child_rt3
405};
406
407static constexpr RefTrf prism_parent_rt3[4] =
408{
409 { { S_HALF, S_HALF, S_ONE}, { 0, 0, 0} },
410 { { S_HALF, S_HALF, S_ONE}, {T_HALF, 0, 0} },
411 { { S_HALF, S_HALF, S_ONE}, { 0, T_HALF, 0} },
412 { {-S_HALF, -S_HALF, S_ONE}, {T_HALF, T_HALF, 0} }
413};
414
415static constexpr RefTrf prism_child_rt3[4] =
416{
417 { { S_TWO, S_TWO, S_ONE}, { 0, 0, 0} },
418 { { S_TWO, S_TWO, S_ONE}, {-T_ONE, 0, 0} },
419 { { S_TWO, S_TWO, S_ONE}, { 0, -T_ONE, 0} },
420 { {-S_TWO, -S_TWO, S_ONE}, { T_ONE, T_ONE, 0} }
421};
422
423static constexpr RefTrf prism_parent_rt4[2] =
424{
425 { {S_ONE, S_ONE, S_HALF}, {0, 0, 0} },
426 { {S_ONE, S_ONE, S_HALF}, {0, 0, T_HALF} }
427};
428
429static constexpr RefTrf prism_child_rt4[2] =
430{
431 { {S_ONE, S_ONE, S_TWO}, {0, 0, 0} },
432 { {S_ONE, S_ONE, S_TWO}, {0, 0, -T_ONE} }
433};
434
435static constexpr RefTrf prism_parent_rt7[8] =
436{
437 { { S_HALF, S_HALF, S_HALF}, { 0, 0, 0} },
438 { { S_HALF, S_HALF, S_HALF}, {T_HALF, 0, 0} },
439 { { S_HALF, S_HALF, S_HALF}, { 0, T_HALF, 0} },
440 { {-S_HALF, -S_HALF, S_HALF}, {T_HALF, T_HALF, 0} },
441 { { S_HALF, S_HALF, S_HALF}, { 0, 0, T_HALF} },
442 { { S_HALF, S_HALF, S_HALF}, {T_HALF, 0, T_HALF} },
443 { { S_HALF, S_HALF, S_HALF}, { 0, T_HALF, T_HALF} },
444 { {-S_HALF, -S_HALF, S_HALF}, {T_HALF, T_HALF, T_HALF} }
445};
446
447static constexpr RefTrf prism_child_rt7[8] =
448{
449 { { S_TWO, S_TWO, S_TWO}, { 0, 0, 0} },
450 { { S_TWO, S_TWO, S_TWO}, {-T_ONE, 0, 0} },
451 { { S_TWO, S_TWO, S_TWO}, { 0, -T_ONE, 0} },
452 { {-S_TWO, -S_TWO, S_TWO}, { T_ONE, T_ONE, 0} },
453 { { S_TWO, S_TWO, S_TWO}, { 0, 0, -T_ONE} },
454 { { S_TWO, S_TWO, S_TWO}, {-T_ONE, 0, -T_ONE} },
455 { { S_TWO, S_TWO, S_TWO}, { 0, -T_ONE, -T_ONE} },
456 { {-S_TWO, -S_TWO, S_TWO}, { T_ONE, T_ONE, -T_ONE} }
457};
458
459static const RefTrf* prism_parent[8] =
460{
461 NULL, NULL, NULL,
462 prism_parent_rt3,
463 prism_parent_rt4,
464 NULL, NULL,
465 prism_parent_rt7
466};
467
468static const RefTrf* prism_child[8] =
469{
470 NULL, NULL, NULL,
471 prism_child_rt3,
472 prism_child_rt4,
473 NULL, NULL,
474 prism_child_rt7
475};
476
477static const RefTrf** geom_parent[7] =
478{
479 NULL,
480 NULL,
481 tri_parent,
482 quad_parent,
483 NULL,
484 hex_parent,
485 prism_parent
486};
487
488static const RefTrf** geom_child[7] =
489{
490 NULL,
491 NULL,
492 tri_child,
493 quad_child,
494 NULL,
495 hex_child,
496 prism_child
497};
498
499} // namespace mfem
500
501#endif // MFEM_NCMESH_TABLES
std::int64_t RefCoord
Definition ncmesh.hpp:486
RefCoord RefPoint[3]
NCMesh::RefCoord RefCoord
void Apply(const RefCoord src[3], RefCoord dst[3]) const
RefCoord s[3]
RefCoord t[3]