libMesh
cell_inf_hex18.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 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/side.h"
30 #include "libmesh/enum_io_package.h"
31 #include "libmesh/enum_order.h"
32 
33 namespace libMesh
34 {
35 
36 
37 // ------------------------------------------------------------
38 // InfHex18 class static member initializations
39 const int InfHex18::num_nodes;
40 const int InfHex18::num_sides;
41 const int InfHex18::num_edges;
42 const int InfHex18::num_children;
43 const int InfHex18::nodes_per_side;
44 const int InfHex18::nodes_per_edge;
45 
47  {
48  { 0, 1, 2, 3, 8, 9, 10, 11, 16}, // Side 0
49  { 0, 1, 4, 5, 8, 12, 99, 99, 99}, // Side 1
50  { 1, 2, 5, 6, 9, 13, 99, 99, 99}, // Side 2
51  { 2, 3, 6, 7, 10, 14, 99, 99, 99}, // Side 3
52  { 3, 0, 7, 4, 11, 15, 99, 99, 99} // Side 4
53  };
54 
56  {
57  {0, 1, 8}, // Edge 0
58  {1, 2, 9}, // Edge 1
59  {2, 3, 10}, // Edge 2
60  {0, 3, 11}, // Edge 3
61  {0, 4, 99}, // Edge 4
62  {1, 5, 99}, // Edge 5
63  {2, 6, 99}, // Edge 6
64  {3, 7, 99} // Edge 7
65  };
66 
67 // ------------------------------------------------------------
68 // InfHex18 class member functions
69 
71 {
72  return SECOND;
73 }
74 
75 bool InfHex18::is_node_on_side(const unsigned int n,
76  const unsigned int s) const
77 {
78  libmesh_assert_less (s, n_sides());
79  return std::find(std::begin(side_nodes_map[s]),
80  std::end(side_nodes_map[s]),
81  n) != std::end(side_nodes_map[s]);
82 }
83 
84 std::vector<unsigned>
85 InfHex18::nodes_on_side(const unsigned int s) const
86 {
87  libmesh_assert_less(s, n_sides());
88  auto trim = (s == 0) ? 0 : 3;
89  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
90 }
91 
92 std::vector<unsigned>
93 InfHex18::nodes_on_edge(const unsigned int e) const
94 {
95  libmesh_assert_less(e, n_edges());
96  auto trim = (e < 4) ? 0 : 1;
97  return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e]) - trim};
98 }
99 
100 bool InfHex18::is_node_on_edge(const unsigned int n,
101  const unsigned int e) const
102 {
103  libmesh_assert_less (e, n_edges());
104  return std::find(std::begin(edge_nodes_map[e]),
105  std::end(edge_nodes_map[e]),
106  n) != std::end(edge_nodes_map[e]);
107 }
108 
109 
110 
111 dof_id_type InfHex18::key (const unsigned int s) const
112 {
113  libmesh_assert_less (s, this->n_sides());
114 
115  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
116  switch (s)
117  {
118  case 0: // the base face
119  return this->compute_key (this->node_id(16));
120 
121  case 1: // the face at y = -1
122  case 2: // the face at x = 1
123  case 3: // the face at y = 1
124  case 4: // the face at x = -1
125  return InfHex::key(s);
126 
127  default:
128  libmesh_error_msg("Invalid side s = " << s);
129  }
130 }
131 
132 
133 
134 unsigned int InfHex18::local_side_node(unsigned int side,
135  unsigned int side_node) const
136 {
137  libmesh_assert_less (side, this->n_sides());
138 
139  // Never more than 9 nodes per side.
140  libmesh_assert_less (side_node, InfHex18::nodes_per_side);
141 
142  // Some sides have 6 nodes.
143  libmesh_assert(side == 0 || side_node < 6);
144 
145  return InfHex18::side_nodes_map[side][side_node];
146 }
147 
148 
149 
150 unsigned int InfHex18::local_edge_node(unsigned int edge,
151  unsigned int edge_node) const
152 {
153  libmesh_assert_less (edge, this->n_edges());
154 
155  // Never more than 3 nodes per edge.
156  libmesh_assert_less (edge_node, InfHex18::nodes_per_edge);
157 
158  // Some edges only have 2 nodes.
159  libmesh_assert(edge < 4 || edge_node < 2);
160 
161  return InfHex18::edge_nodes_map[edge][edge_node];
162 }
163 
164 
165 
166 std::unique_ptr<Elem> InfHex18::build_side_ptr (const unsigned int i,
167  bool proxy)
168 {
169  libmesh_assert_less (i, this->n_sides());
170 
171  std::unique_ptr<Elem> face;
172  if (proxy)
173  {
174 #ifdef LIBMESH_ENABLE_DEPRECATED
175  libmesh_deprecated();
176  switch (i)
177  {
178  // base
179  case 0:
180  {
181  face = std::make_unique<Side<Quad9,InfHex18>>(this,i);
182  break;
183  }
184 
185  // ifem sides
186  case 1:
187  case 2:
188  case 3:
189  case 4:
190  {
191  face = std::make_unique<Side<InfQuad6,InfHex18>>(this,i);
192  break;
193  }
194 
195  default:
196  libmesh_error_msg("Invalid side i = " << i);
197  }
198 #else
199  libmesh_error();
200 #endif // LIBMESH_ENABLE_DEPRECATED
201  }
202  else
203  {
204  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
205  switch (i)
206  {
207  // the base face
208  case 0:
209  {
210  face = std::make_unique<Quad9>(this);
211  break;
212  }
213 
214  // connecting to another infinite element
215  case 1:
216  case 2:
217  case 3:
218  case 4:
219  {
220  face = std::make_unique<InfQuad6>(this);
221  break;
222  }
223 
224  default:
225  libmesh_error_msg("Invalid side i = " << i);
226  }
227 
228  for (auto n : face->node_index_range())
229  face->set_node(n) = this->node_ptr(InfHex18::side_nodes_map[i][n]);
230  }
231 
232 #ifdef LIBMESH_ENABLE_DEPRECATED
233  if (!proxy) // proxy sides used to leave parent() set
234 #endif
235  face->set_parent(nullptr);
236  face->set_interior_parent(this);
237 
238  face->subdomain_id() = this->subdomain_id();
239  face->set_mapping_type(this->mapping_type());
240 #ifdef LIBMESH_ENABLE_AMR
241  face->set_p_level(this->p_level());
242 #endif
243 
244  return face;
245 }
246 
247 
248 
249 void InfHex18::build_side_ptr (std::unique_ptr<Elem> & side,
250  const unsigned int i)
251 {
252  libmesh_assert_less (i, this->n_sides());
253 
254  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
255  switch (i)
256  {
257  // the base face
258  case 0:
259  {
260  if (!side.get() || side->type() != QUAD9)
261  {
262  side = this->build_side_ptr(i, false);
263  return;
264  }
265  break;
266  }
267 
268  // connecting to another infinite element
269  case 1:
270  case 2:
271  case 3:
272  case 4:
273  {
274  if (!side.get() || side->type() != INFQUAD6)
275  {
276  side = this->build_side_ptr(i, false);
277  return;
278  }
279  break;
280  }
281 
282  default:
283  libmesh_error_msg("Invalid side i = " << i);
284  }
285 
286  side->subdomain_id() = this->subdomain_id();
287  side->set_mapping_type(this->mapping_type());
288 
289  // Set the nodes
290  for (auto n : side->node_index_range())
291  side->set_node(n) = this->node_ptr(InfHex18::side_nodes_map[i][n]);
292 }
293 
294 
295 
296 std::unique_ptr<Elem> InfHex18::build_edge_ptr (const unsigned int i)
297 {
298  if (i < 4) // base edges
299  return this->simple_build_edge_ptr<Edge3,InfHex18>(i);
300 
301  // infinite edges
302  return this->simple_build_edge_ptr<InfEdge2,InfHex18>(i);
303 }
304 
305 
306 
307 void InfHex18::build_edge_ptr (std::unique_ptr<Elem> & edge,
308  const unsigned int i)
309 {
310  libmesh_assert_less (i, this->n_edges());
311 
312  switch (i)
313  {
314  // the base edges
315  case 0:
316  case 1:
317  case 2:
318  case 3:
319  {
320  if (!edge.get() || edge->type() != EDGE3)
321  {
322  edge = this->build_edge_ptr(i);
323  return;
324  }
325  break;
326  }
327 
328  // the infinite edges
329  case 4:
330  case 5:
331  case 6:
332  case 7:
333  {
334  if (!edge.get() || edge->type() != INFEDGE2)
335  {
336  edge = this->build_edge_ptr(i);
337  return;
338  }
339  break;
340  }
341 
342  default:
343  libmesh_error_msg("Invalid edge i = " << i);
344  }
345 
346  edge->subdomain_id() = this->subdomain_id();
347  edge->set_mapping_type(this->mapping_type());
348 #ifdef LIBMESH_ENABLE_AMR
349  edge->set_p_level(this->p_level());
350 #endif
351 
352  // Set the nodes
353  for (auto n : edge->node_index_range())
354  edge->set_node(n) = this->node_ptr(InfHex18::edge_nodes_map[i][n]);
355 }
356 
357 
358 
359 void InfHex18::connectivity(const unsigned int sc,
360  const IOPackage iop,
361  std::vector<dof_id_type> & conn) const
362 {
364  libmesh_assert_less (sc, this->n_sub_elem());
365  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
366 
367  switch (iop)
368  {
369  case TECPLOT:
370  {
371  switch (sc)
372  {
373  case 0:
374 
375  conn[0] = this->node_id(0)+1;
376  conn[1] = this->node_id(8)+1;
377  conn[2] = this->node_id(16)+1;
378  conn[3] = this->node_id(11)+1;
379  conn[4] = this->node_id(4)+1;
380  conn[5] = this->node_id(12)+1;
381  conn[6] = this->node_id(17)+1;
382  conn[7] = this->node_id(15)+1;
383 
384  return;
385 
386  case 1:
387 
388  conn[0] = this->node_id(8)+1;
389  conn[1] = this->node_id(1)+1;
390  conn[2] = this->node_id(9)+1;
391  conn[3] = this->node_id(16)+1;
392  conn[4] = this->node_id(12)+1;
393  conn[5] = this->node_id(5)+1;
394  conn[6] = this->node_id(13)+1;
395  conn[7] = this->node_id(17)+1;
396 
397  return;
398 
399  case 2:
400 
401  conn[0] = this->node_id(11)+1;
402  conn[1] = this->node_id(16)+1;
403  conn[2] = this->node_id(10)+1;
404  conn[3] = this->node_id(3)+1;
405  conn[4] = this->node_id(15)+1;
406  conn[5] = this->node_id(17)+1;
407  conn[6] = this->node_id(14)+1;
408  conn[7] = this->node_id(7)+1;
409 
410  return;
411 
412  case 3:
413 
414  conn[0] = this->node_id(16)+1;
415  conn[1] = this->node_id(9)+1;
416  conn[2] = this->node_id(2)+1;
417  conn[3] = this->node_id(10)+1;
418  conn[4] = this->node_id(17)+1;
419  conn[5] = this->node_id(13)+1;
420  conn[6] = this->node_id(6)+1;
421  conn[7] = this->node_id(14)+1;
422 
423  return;
424 
425  default:
426  libmesh_error_msg("Invalid sc = " << sc);
427  }
428  }
429 
430  default:
431  libmesh_error_msg("Unsupported IO package " << iop);
432  }
433 }
434 
435 
436 
437 
438 unsigned int InfHex18::n_second_order_adjacent_vertices (const unsigned int n) const
439 {
440  switch (n)
441  {
442  case 8:
443  case 9:
444  case 10:
445  case 11:
446  case 12:
447  case 13:
448  case 14:
449  case 15:
450  return 2;
451 
452  case 16:
453  case 17:
454  return 4;
455 
456  default:
457  libmesh_error_msg("Invalid node n = " << n);
458  }
459 }
460 
461 
462 
463 unsigned short int InfHex18::second_order_adjacent_vertex (const unsigned int n,
464  const unsigned int v) const
465 {
466  libmesh_assert_greater_equal (n, this->n_vertices());
467  libmesh_assert_less (n, this->n_nodes());
468  libmesh_assert_less (v, this->n_second_order_adjacent_vertices(n));
469 
470  if (n == 16)
471  /*
472  * for the bubble node in the base the return value is
473  * simply v. Why? -- the user asks for the v-th
474  * adjacent vertex, from \p n_second_order_adjacent_vertices()
475  * there are 4 adjacent vertices, and these happen to be
476  * 0..3
477  */
478  return static_cast<unsigned short int>(v);
479  else if (n == 17)
480  /*
481  * for the bubble node further out similar reasoning works,
482  * but v must be shifted to the further-out nodes:
483  * simply add 4
484  */
485  return static_cast<unsigned short int>(v+4);
486 
487  else
488  /*
489  * all others are stored in the vertices matrix -- note
490  * that this matrix is kept in \p InfHex to foster
491  * code-reuse
492  */
493  return _second_order_adjacent_vertices[n-this->n_vertices()][v];
494 }
495 
496 
497 
498 std::pair<unsigned short int, unsigned short int>
499 InfHex18::second_order_child_vertex (const unsigned int n) const
500 {
501  libmesh_assert_greater_equal (n, this->n_vertices());
502  libmesh_assert_less (n, this->n_nodes());
503  /*
504  * the _second_order_vertex_child_* vectors are
505  * stored in cell_inf_hex.C, since they are identical
506  * for InfHex16 and InfHex18
507  */
508  return std::pair<unsigned short int, unsigned short int>
511 }
512 
513 
514 
515 
516 
517 
518 
519 #ifdef LIBMESH_ENABLE_AMR
520 
522  {
523  // embedding matrix for child 0
524  {
525  // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
526  { 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.
527  { 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
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, 0.0, 0.0, 1.0, 0.0}, // 2
529  { 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
530  { 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
531  { 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
532  { 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
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.0, 0.0, 1.0, 0.0, 0.0}, // 7
534  { 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
535  { 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
536  { 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
537  { 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
538  { 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
539  { 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
540  { 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
541  { 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
542  { 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
543  { 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
544  },
545 
546  // embedding matrix for child 1
547  {
548  // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
549  { 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.
550  { 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
551  { 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
552  { 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
553  { 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
554  { 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
555  { 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
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.0, 0.0, 0.0, 0.0, 1.0}, // 7
557  { -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
558  { 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
559  { 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
560  { 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
561  { 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
562  { 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
563  { 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
564  { 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
565  { -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
566  { 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
567  },
568 
569  // embedding matrix for child 2
570  {
571  // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
572  { 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.
573  { 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
574  { 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
575  { 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
576  { 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
577  { 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
578  { 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
579  { 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
580  { 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
581  { 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
582  { 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
583  { 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
584  { 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
585  { 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
586  { 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
587  { 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
588  { 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
589  { 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
590  },
591 
592  // embedding matrix for child 3
593  {
594  // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 th parent Node
595  { 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.
596  { 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
597  { 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
598  { 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
599  { 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
600  { 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
601  { 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
602  { 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
603  { 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
604  { 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
605  { 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
606  { -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
607  { 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
608  { 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
609  { 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
610  { 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
611  { -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
612  { 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
613  }
614  };
615 
616 
617 #endif
618 
619 
620 void
621 InfHex18::permute(unsigned int perm_num)
622 {
623  libmesh_assert_less (perm_num, 4);
624 
625  for (unsigned int i = 0; i != perm_num; ++i)
626  {
627  swap4nodes(0,1,2,3);
628  swap4nodes(4,5,6,7);
629  swap4nodes(8,9,10,11);
630  swap4nodes(12,13,14,15);
631  swap4neighbors(1,2,3,4);
632  }
633 }
634 
635 
636 void
637 InfHex18::flip(BoundaryInfo * boundary_info)
638 {
639  swap2nodes(0,1);
640  swap2nodes(2,3);
641  swap2nodes(4,5);
642  swap2nodes(6,7);
643  swap2nodes(9,11);
644  swap2nodes(13,15);
645  swap2neighbors(0,4);
646  swap2boundarysides(0,4,boundary_info);
647  swap2boundaryedges(1,3,boundary_info);
648  swap2boundaryedges(4,5,boundary_info);
649  swap2boundaryedges(6,7,boundary_info);
650 }
651 
652 
653 ElemType
654 InfHex18::side_type (const unsigned int s) const
655 {
656  libmesh_assert_less (s, 5);
657  if (s == 0)
658  return QUAD9;
659  return INFQUAD6;
660 }
661 
662 
663 } // namespace libMesh
664 
665 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
static const int num_nodes
Geometric constants for InfHex18.
static const int num_sides
static const int nodes_per_edge
ElemType
Defines an enum for geometric element types.
void swap2boundaryedges(unsigned short e1, unsigned short e2, BoundaryInfo *boundary_info) const
Swaps two edges in boundary_info, if it is non-null.
Definition: elem.C:3171
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:2087
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const override
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=false) override
virtual dof_id_type key() const
Definition: elem.C:563
virtual unsigned int n_sub_elem() const override
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
static const int num_children
virtual Order default_order() const override
void swap2boundarysides(unsigned short s1, unsigned short s2, BoundaryInfo *boundary_info) const
Swaps two sides in boundary_info, if it is non-null.
Definition: elem.C:3155
unsigned int p_level() const
Definition: elem.h:2945
The libMesh namespace provides an interface to certain functionality in the library.
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
static const unsigned short int _second_order_adjacent_vertices[8][2]
For higher-order elements, namely InfHex16 and InfHex18, the matrices for adjacent vertices of second...
Definition: cell_inf_hex.h:238
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override
void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four node_ptrs, "rotating" them.
Definition: elem.h:1984
ElemMappingType mapping_type() const
Definition: elem.h:2957
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:1933
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
virtual unsigned int n_vertices() const override final
Definition: cell_inf_hex.h:92
virtual unsigned int local_edge_node(unsigned int edge, unsigned int edge_node) const override
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const override
static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]
This maps the node of the edge to element node numbers.
static const int nodes_per_side
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:1943
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const override
static const int num_edges
static const unsigned short int _second_order_vertex_child_index[18]
Vector that names the child vertex index for each second order node.
Definition: cell_inf_hex.h:248
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
Definition: elem.h:2391
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2331
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:1994
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const override
ElemType side_type(const unsigned int s) const override final
virtual unsigned int n_edges() const override final
Definition: cell_inf_hex.h:105
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int) const override
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:3131
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2299
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
static const unsigned short int _second_order_vertex_child_number[18]
Vector that names a child sharing each second order node.
Definition: cell_inf_hex.h:243
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
uint8_t dof_id_type
Definition: id_types.h:67
virtual unsigned int n_sides() const override final
Definition: cell_inf_hex.h:85
virtual unsigned int n_nodes() const override