Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 : // Local includes
19 : #include "libmesh/libmesh_config.h"
20 :
21 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
22 :
23 : // Local includes cont'd
24 : #include "libmesh/cell_inf_hex18.h"
25 : #include "libmesh/edge_edge3.h"
26 : #include "libmesh/edge_inf_edge2.h"
27 : #include "libmesh/face_quad9.h"
28 : #include "libmesh/face_inf_quad6.h"
29 : #include "libmesh/enum_io_package.h"
30 : #include "libmesh/enum_order.h"
31 :
32 : namespace libMesh
33 : {
34 :
35 :
36 : // ------------------------------------------------------------
37 : // InfHex18 class static member initializations
38 : const int InfHex18::num_nodes;
39 : const int InfHex18::nodes_per_side;
40 : const int InfHex18::nodes_per_edge;
41 :
42 : const unsigned int InfHex18::side_nodes_map[InfHex18::num_sides][InfHex18::nodes_per_side] =
43 : {
44 : { 0, 1, 2, 3, 8, 9, 10, 11, 16}, // Side 0
45 : { 0, 1, 4, 5, 8, 12, 99, 99, 99}, // Side 1
46 : { 1, 2, 5, 6, 9, 13, 99, 99, 99}, // Side 2
47 : { 2, 3, 6, 7, 10, 14, 99, 99, 99}, // Side 3
48 : { 3, 0, 7, 4, 11, 15, 99, 99, 99} // Side 4
49 : };
50 :
51 : const unsigned int InfHex18::edge_nodes_map[InfHex18::num_edges][InfHex18::nodes_per_edge] =
52 : {
53 : {0, 1, 8}, // Edge 0
54 : {1, 2, 9}, // Edge 1
55 : {2, 3, 10}, // Edge 2
56 : {0, 3, 11}, // Edge 3
57 : {0, 4, 99}, // Edge 4
58 : {1, 5, 99}, // Edge 5
59 : {2, 6, 99}, // Edge 6
60 : {3, 7, 99} // Edge 7
61 : };
62 :
63 : // ------------------------------------------------------------
64 : // InfHex18 class member functions
65 :
66 4914 : Order InfHex18::default_order() const
67 : {
68 4914 : return SECOND;
69 : }
70 :
71 6339 : bool InfHex18::is_node_on_side(const unsigned int n,
72 : const unsigned int s) const
73 : {
74 2053 : libmesh_assert_less (s, n_sides());
75 2053 : return std::find(std::begin(side_nodes_map[s]),
76 6339 : std::end(side_nodes_map[s]),
77 6339 : n) != std::end(side_nodes_map[s]);
78 : }
79 :
80 : std::vector<unsigned>
81 136 : InfHex18::nodes_on_side(const unsigned int s) const
82 : {
83 47 : libmesh_assert_less(s, n_sides());
84 136 : auto trim = (s == 0) ? 0 : 3;
85 136 : return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
86 : }
87 :
88 : std::vector<unsigned>
89 172 : InfHex18::nodes_on_edge(const unsigned int e) const
90 : {
91 60 : libmesh_assert_less(e, n_edges());
92 112 : auto trim = (e < 4) ? 0 : 1;
93 172 : return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e]) - trim};
94 : }
95 :
96 780 : bool InfHex18::is_node_on_edge(const unsigned int n,
97 : const unsigned int e) const
98 : {
99 308 : libmesh_assert_less (e, n_edges());
100 308 : return std::find(std::begin(edge_nodes_map[e]),
101 780 : std::end(edge_nodes_map[e]),
102 780 : n) != std::end(edge_nodes_map[e]);
103 : }
104 :
105 :
106 :
107 0 : dof_id_type InfHex18::key (const unsigned int s) const
108 : {
109 0 : libmesh_assert_less (s, this->n_sides());
110 :
111 : // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
112 0 : switch (s)
113 : {
114 0 : case 0: // the base face
115 0 : return this->compute_key (this->node_id(16));
116 :
117 0 : case 1: // the face at y = -1
118 : case 2: // the face at x = 1
119 : case 3: // the face at y = 1
120 : case 4: // the face at x = -1
121 0 : return InfHex::key(s);
122 :
123 0 : default:
124 0 : libmesh_error_msg("Invalid side s = " << s);
125 : }
126 : }
127 :
128 :
129 :
130 0 : unsigned int InfHex18::local_side_node(unsigned int side,
131 : unsigned int side_node) const
132 : {
133 0 : libmesh_assert_less (side, this->n_sides());
134 :
135 : // Never more than 9 nodes per side.
136 0 : libmesh_assert_less (side_node, InfHex18::nodes_per_side);
137 :
138 : // Some sides have 6 nodes.
139 0 : libmesh_assert(side == 0 || side_node < 6);
140 :
141 0 : return InfHex18::side_nodes_map[side][side_node];
142 : }
143 :
144 :
145 :
146 480 : unsigned int InfHex18::local_edge_node(unsigned int edge,
147 : unsigned int edge_node) const
148 : {
149 160 : libmesh_assert_less (edge, this->n_edges());
150 :
151 : // Never more than 3 nodes per edge.
152 160 : libmesh_assert_less (edge_node, InfHex18::nodes_per_edge);
153 :
154 : // Some edges only have 2 nodes.
155 160 : libmesh_assert(edge < 4 || edge_node < 2);
156 :
157 480 : return InfHex18::edge_nodes_map[edge][edge_node];
158 : }
159 :
160 :
161 :
162 304200 : std::unique_ptr<Elem> InfHex18::build_side_ptr (const unsigned int i)
163 : {
164 96738 : libmesh_assert_less (i, this->n_sides());
165 :
166 304200 : std::unique_ptr<Elem> face;
167 :
168 : // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
169 304200 : switch (i)
170 : {
171 : // the base face
172 303661 : case 0:
173 : {
174 303661 : face = std::make_unique<Quad9>();
175 303661 : break;
176 : }
177 :
178 : // connecting to another infinite element
179 539 : case 1:
180 : case 2:
181 : case 3:
182 : case 4:
183 : {
184 539 : face = std::make_unique<InfQuad6>();
185 539 : break;
186 : }
187 :
188 0 : default:
189 0 : libmesh_error_msg("Invalid side i = " << i);
190 : }
191 :
192 3040383 : for (auto n : face->node_index_range())
193 3599682 : face->set_node(n, this->node_ptr(InfHex18::side_nodes_map[i][n]));
194 :
195 304200 : face->set_interior_parent(this);
196 208185 : face->inherit_data_from(*this);
197 :
198 304200 : return face;
199 0 : }
200 :
201 :
202 :
203 166 : void InfHex18::build_side_ptr (std::unique_ptr<Elem> & side,
204 : const unsigned int i)
205 : {
206 25 : libmesh_assert_less (i, this->n_sides());
207 :
208 : // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
209 166 : switch (i)
210 : {
211 : // the base face
212 5 : case 0:
213 : {
214 110 : if (!side.get() || side->type() != QUAD9)
215 : {
216 206 : side = this->build_side_ptr(i);
217 107 : return;
218 : }
219 1 : break;
220 : }
221 :
222 : // connecting to another infinite element
223 20 : case 1:
224 : case 2:
225 : case 3:
226 : case 4:
227 : {
228 56 : if (!side.get() || side->type() != INFQUAD6)
229 : {
230 14 : side = this->build_side_ptr(i);
231 11 : return;
232 : }
233 16 : break;
234 : }
235 :
236 0 : default:
237 0 : libmesh_error_msg("Invalid side i = " << i);
238 : }
239 :
240 31 : side->inherit_data_from(*this);
241 :
242 : // Set the nodes
243 345 : for (auto n : side->node_index_range())
244 402 : side->set_node(n, this->node_ptr(InfHex18::side_nodes_map[i][n]));
245 : }
246 :
247 :
248 :
249 2704 : std::unique_ptr<Elem> InfHex18::build_edge_ptr (const unsigned int i)
250 : {
251 2704 : if (i < 4) // base edges
252 1260 : return this->simple_build_edge_ptr<Edge3,InfHex18>(i);
253 :
254 : // infinite edges
255 1444 : return this->simple_build_edge_ptr<InfEdge2,InfHex18>(i);
256 : }
257 :
258 :
259 :
260 0 : void InfHex18::build_edge_ptr (std::unique_ptr<Elem> & edge,
261 : const unsigned int i)
262 : {
263 0 : libmesh_assert_less (i, this->n_edges());
264 :
265 0 : switch (i)
266 : {
267 : // the base edges
268 0 : case 0:
269 : case 1:
270 : case 2:
271 : case 3:
272 : {
273 0 : if (!edge.get() || edge->type() != EDGE3)
274 : {
275 0 : edge = this->build_edge_ptr(i);
276 0 : return;
277 : }
278 0 : break;
279 : }
280 :
281 : // the infinite edges
282 0 : case 4:
283 : case 5:
284 : case 6:
285 : case 7:
286 : {
287 0 : if (!edge.get() || edge->type() != INFEDGE2)
288 : {
289 0 : edge = this->build_edge_ptr(i);
290 0 : return;
291 : }
292 0 : break;
293 : }
294 :
295 0 : default:
296 0 : libmesh_error_msg("Invalid edge i = " << i);
297 : }
298 :
299 0 : edge->inherit_data_from(*this);
300 :
301 : // Set the nodes
302 0 : for (auto n : edge->node_index_range())
303 0 : edge->set_node(n, this->node_ptr(InfHex18::edge_nodes_map[i][n]));
304 : }
305 :
306 :
307 :
308 0 : void InfHex18::connectivity(const unsigned int sc,
309 : const IOPackage iop,
310 : std::vector<dof_id_type> & conn) const
311 : {
312 0 : libmesh_assert(_nodes);
313 0 : libmesh_assert_less (sc, this->n_sub_elem());
314 0 : libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
315 :
316 0 : switch (iop)
317 : {
318 0 : case TECPLOT:
319 : {
320 0 : switch (sc)
321 : {
322 0 : case 0:
323 :
324 0 : conn[0] = this->node_id(0)+1;
325 0 : conn[1] = this->node_id(8)+1;
326 0 : conn[2] = this->node_id(16)+1;
327 0 : conn[3] = this->node_id(11)+1;
328 0 : conn[4] = this->node_id(4)+1;
329 0 : conn[5] = this->node_id(12)+1;
330 0 : conn[6] = this->node_id(17)+1;
331 0 : conn[7] = this->node_id(15)+1;
332 :
333 0 : return;
334 :
335 0 : case 1:
336 :
337 0 : conn[0] = this->node_id(8)+1;
338 0 : conn[1] = this->node_id(1)+1;
339 0 : conn[2] = this->node_id(9)+1;
340 0 : conn[3] = this->node_id(16)+1;
341 0 : conn[4] = this->node_id(12)+1;
342 0 : conn[5] = this->node_id(5)+1;
343 0 : conn[6] = this->node_id(13)+1;
344 0 : conn[7] = this->node_id(17)+1;
345 :
346 0 : return;
347 :
348 0 : case 2:
349 :
350 0 : conn[0] = this->node_id(11)+1;
351 0 : conn[1] = this->node_id(16)+1;
352 0 : conn[2] = this->node_id(10)+1;
353 0 : conn[3] = this->node_id(3)+1;
354 0 : conn[4] = this->node_id(15)+1;
355 0 : conn[5] = this->node_id(17)+1;
356 0 : conn[6] = this->node_id(14)+1;
357 0 : conn[7] = this->node_id(7)+1;
358 :
359 0 : return;
360 :
361 0 : case 3:
362 :
363 0 : conn[0] = this->node_id(16)+1;
364 0 : conn[1] = this->node_id(9)+1;
365 0 : conn[2] = this->node_id(2)+1;
366 0 : conn[3] = this->node_id(10)+1;
367 0 : conn[4] = this->node_id(17)+1;
368 0 : conn[5] = this->node_id(13)+1;
369 0 : conn[6] = this->node_id(6)+1;
370 0 : conn[7] = this->node_id(14)+1;
371 :
372 0 : return;
373 :
374 0 : default:
375 0 : libmesh_error_msg("Invalid sc = " << sc);
376 : }
377 : }
378 :
379 0 : default:
380 0 : libmesh_error_msg("Unsupported IO package " << iop);
381 : }
382 : }
383 :
384 :
385 :
386 :
387 60 : unsigned int InfHex18::n_second_order_adjacent_vertices (const unsigned int n) const
388 : {
389 60 : switch (n)
390 : {
391 0 : case 8:
392 : case 9:
393 : case 10:
394 : case 11:
395 : case 12:
396 : case 13:
397 : case 14:
398 : case 15:
399 0 : return 2;
400 :
401 12 : case 16:
402 : case 17:
403 12 : return 4;
404 :
405 0 : default:
406 0 : libmesh_error_msg("Invalid node n = " << n);
407 : }
408 : }
409 :
410 :
411 :
412 144 : unsigned short int InfHex18::second_order_adjacent_vertex (const unsigned int n,
413 : const unsigned int v) const
414 : {
415 0 : libmesh_assert_greater_equal (n, this->n_vertices());
416 0 : libmesh_assert_less (n, this->n_nodes());
417 0 : libmesh_assert_less (v, this->n_second_order_adjacent_vertices(n));
418 :
419 144 : if (n == 16)
420 : /*
421 : * for the bubble node in the base the return value is
422 : * simply v. Why? -- the user asks for the v-th
423 : * adjacent vertex, from \p n_second_order_adjacent_vertices()
424 : * there are 4 adjacent vertices, and these happen to be
425 : * 0..3
426 : */
427 24 : return static_cast<unsigned short int>(v);
428 120 : else if (n == 17)
429 : /*
430 : * for the bubble node further out similar reasoning works,
431 : * but v must be shifted to the further-out nodes:
432 : * simply add 4
433 : */
434 24 : return static_cast<unsigned short int>(v+4);
435 :
436 : else
437 : /*
438 : * all others are stored in the vertices matrix -- note
439 : * that this matrix is kept in \p InfHex to foster
440 : * code-reuse
441 : */
442 96 : return _second_order_adjacent_vertices[n-this->n_vertices()][v];
443 : }
444 :
445 :
446 :
447 : std::pair<unsigned short int, unsigned short int>
448 0 : InfHex18::second_order_child_vertex (const unsigned int n) const
449 : {
450 0 : libmesh_assert_greater_equal (n, this->n_vertices());
451 0 : libmesh_assert_less (n, this->n_nodes());
452 : /*
453 : * the _second_order_vertex_child_* vectors are
454 : * stored in cell_inf_hex.C, since they are identical
455 : * for InfHex16 and InfHex18
456 : */
457 0 : return std::pair<unsigned short int, unsigned short int>
458 0 : (_second_order_vertex_child_number[n],
459 0 : _second_order_vertex_child_index[n]);
460 : }
461 :
462 :
463 :
464 :
465 :
466 :
467 :
468 : #ifdef LIBMESH_ENABLE_AMR
469 :
470 : const Real InfHex18::_embedding_matrix[InfHex18::num_children][InfHex18::num_nodes][InfHex18::num_nodes] =
471 : {
472 : // embedding matrix for child 0
473 : {
474 : // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
475 : { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
476 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
477 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 2
478 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 3
479 : { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 4
480 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 5
481 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, // 6
482 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 7
483 : { 0.375, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 8
484 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 9
485 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 10
486 : { 0.375, 0.0, 0.0, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 11
487 : { 0.0, 0.0, 0.0, 0.0, 0.375, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0}, // 12
488 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.0, 0.75}, // 13
489 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.75}, // 14
490 : { 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, 0.0, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0}, // 15
491 : { 0.140625, -0.046875, 0.015625, -0.046875, 0.0, 0.0, 0.0, 0.0, 0.28125, -0.09375, -0.09375, 0.28125, 0.0, 0.0, 0.0, 0.0, 0.5625, 0.0}, // 16
492 : { 0.0, 0.0, 0.0, 0.0, 0.140625, -0.046875, 0.015625, -0.046875, 0.0, 0.0, 0.0, 0.0, 0.28125, -0.09375, -0.09375, 0.28125, 0.0, 0.5625} // 17
493 : },
494 :
495 : // embedding matrix for child 1
496 : {
497 : // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
498 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
499 : { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
500 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
501 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 3
502 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 4
503 : { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 5
504 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 6
505 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, // 7
506 : { -0.125, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 8
507 : { 0.0, 0.375, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 9
508 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 10
509 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 11
510 : { 0.0, 0.0, 0.0, 0.0, -0.125, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0}, // 12
511 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0}, // 13
512 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.75}, // 14
513 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.0, 0.75}, // 15
514 : { -0.046875, 0.140625, -0.046875, 0.015625, 0.0, 0.0, 0.0, 0.0, 0.28125, 0.28125, -0.09375, -0.09375, 0.0, 0.0, 0.0, 0.0, 0.5625, 0.0}, // 16
515 : { 0.0, 0.0, 0.0, 0.0, -0.046875, 0.140625, -0.046875, 0.015625, 0.0, 0.0, 0.0, 0.0, 0.28125, 0.28125, -0.09375, -0.09375, 0.0, 0.5625} // 17
516 : },
517 :
518 : // embedding matrix for child 2
519 : {
520 : // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
521 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 0th child N.
522 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
523 : { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
524 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 3
525 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, // 4
526 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 5
527 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 6
528 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 7
529 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 8
530 : { 0.0, -0.125, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 9
531 : { 0.0, 0.0, 0.375, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 10
532 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 11
533 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, 0.0, -0.125, 0.0, 0.75}, // 12
534 : { 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0}, // 13
535 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.375, -0.125, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0}, // 14
536 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.0, 0.75}, // 15
537 : { 0.015625, -0.046875, 0.140625, -0.046875, 0.0, 0.0, 0.0, 0.0, -0.09375, 0.28125, 0.28125, -0.09375, 0.0, 0.0, 0.0, 0.0, 0.5625, 0.0}, // 16
538 : { 0.0, 0.0, 0.0, 0.0, 0.015625, -0.046875, 0.140625, -0.046875, 0.0, 0.0, 0.0, 0.0, -0.09375, 0.28125, 0.28125, -0.09375, 0.0, 0.5625} // 17
539 : },
540 :
541 : // embedding matrix for child 3
542 : {
543 : // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
544 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
545 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 1
546 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
547 : { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 3
548 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 4
549 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0}, // 5
550 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 6
551 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 7
552 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 8
553 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0}, // 9
554 : { 0.0, 0.0, -0.125, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 10
555 : { -0.125, 0.0, 0.0, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 11
556 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.75}, // 12
557 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.375, 0.0, 0.0, 0.75}, // 13
558 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.125, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0, 0.0}, // 14
559 : { 0.0, 0.0, 0.0, 0.0, -0.125, 0.0, 0.0, 0.375, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.75, 0.0, 0.0}, // 15
560 : { -0.046875, 0.015625, -0.046875, 0.140625, 0.0, 0.0, 0.0, 0.0, -0.09375, -0.09375, 0.28125, 0.28125, 0.0, 0.0, 0.0, 0.0, 0.5625, 0.0}, // 16
561 : { 0.0, 0.0, 0.0, 0.0, -0.046875, 0.015625, -0.046875, 0.140625, 0.0, 0.0, 0.0, 0.0, -0.09375, -0.09375, 0.28125, 0.28125, 0.0, 0.5625} // 17
562 : }
563 : };
564 :
565 :
566 : #endif
567 :
568 :
569 : void
570 0 : InfHex18::permute(unsigned int perm_num)
571 : {
572 0 : libmesh_assert_less (perm_num, 4);
573 :
574 0 : for (unsigned int i = 0; i != perm_num; ++i)
575 : {
576 0 : swap4nodes(0,1,2,3);
577 0 : swap4nodes(4,5,6,7);
578 0 : swap4nodes(8,9,10,11);
579 0 : swap4nodes(12,13,14,15);
580 0 : swap4neighbors(1,2,3,4);
581 : }
582 0 : }
583 :
584 :
585 : void
586 0 : InfHex18::flip(BoundaryInfo * boundary_info)
587 : {
588 0 : libmesh_assert(boundary_info);
589 :
590 0 : swap2nodes(0,1);
591 0 : swap2nodes(2,3);
592 0 : swap2nodes(4,5);
593 0 : swap2nodes(6,7);
594 0 : swap2nodes(9,11);
595 0 : swap2nodes(13,15);
596 0 : swap2neighbors(0,4);
597 0 : swap2boundarysides(0,4,boundary_info);
598 0 : swap2boundaryedges(1,3,boundary_info);
599 0 : swap2boundaryedges(4,5,boundary_info);
600 0 : swap2boundaryedges(6,7,boundary_info);
601 0 : }
602 :
603 :
604 : ElemType
605 45 : InfHex18::side_type (const unsigned int s) const
606 : {
607 15 : libmesh_assert_less (s, 5);
608 45 : if (s == 0)
609 9 : return QUAD9;
610 12 : return INFQUAD6;
611 : }
612 :
613 :
614 : } // namespace libMesh
615 :
616 : #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
|