libMesh
cell_inf_hex18.C
Go to the documentation of this file.
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 
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 
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 
67 {
68  return SECOND;
69 }
70 
71 bool InfHex18::is_node_on_side(const unsigned int n,
72  const unsigned int s) const
73 {
74  libmesh_assert_less (s, n_sides());
75  return std::find(std::begin(side_nodes_map[s]),
76  std::end(side_nodes_map[s]),
77  n) != std::end(side_nodes_map[s]);
78 }
79 
80 std::vector<unsigned>
81 InfHex18::nodes_on_side(const unsigned int s) const
82 {
83  libmesh_assert_less(s, n_sides());
84  auto trim = (s == 0) ? 0 : 3;
85  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
86 }
87 
88 std::vector<unsigned>
89 InfHex18::nodes_on_edge(const unsigned int e) const
90 {
91  libmesh_assert_less(e, n_edges());
92  auto trim = (e < 4) ? 0 : 1;
93  return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e]) - trim};
94 }
95 
96 bool InfHex18::is_node_on_edge(const unsigned int n,
97  const unsigned int e) const
98 {
99  libmesh_assert_less (e, n_edges());
100  return std::find(std::begin(edge_nodes_map[e]),
101  std::end(edge_nodes_map[e]),
102  n) != std::end(edge_nodes_map[e]);
103 }
104 
105 
106 
107 dof_id_type InfHex18::key (const unsigned int s) const
108 {
109  libmesh_assert_less (s, this->n_sides());
110 
111  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
112  switch (s)
113  {
114  case 0: // the base face
115  return this->compute_key (this->node_id(16));
116 
117  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  return InfHex::key(s);
122 
123  default:
124  libmesh_error_msg("Invalid side s = " << s);
125  }
126 }
127 
128 
129 
130 unsigned int InfHex18::local_side_node(unsigned int side,
131  unsigned int side_node) const
132 {
133  libmesh_assert_less (side, this->n_sides());
134 
135  // Never more than 9 nodes per side.
136  libmesh_assert_less (side_node, InfHex18::nodes_per_side);
137 
138  // Some sides have 6 nodes.
139  libmesh_assert(side == 0 || side_node < 6);
140 
141  return InfHex18::side_nodes_map[side][side_node];
142 }
143 
144 
145 
146 unsigned int InfHex18::local_edge_node(unsigned int edge,
147  unsigned int edge_node) const
148 {
149  libmesh_assert_less (edge, this->n_edges());
150 
151  // Never more than 3 nodes per edge.
152  libmesh_assert_less (edge_node, InfHex18::nodes_per_edge);
153 
154  // Some edges only have 2 nodes.
155  libmesh_assert(edge < 4 || edge_node < 2);
156 
157  return InfHex18::edge_nodes_map[edge][edge_node];
158 }
159 
160 
161 
162 std::unique_ptr<Elem> InfHex18::build_side_ptr (const unsigned int i)
163 {
164  libmesh_assert_less (i, this->n_sides());
165 
166  std::unique_ptr<Elem> face;
167 
168  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
169  switch (i)
170  {
171  // the base face
172  case 0:
173  {
174  face = std::make_unique<Quad9>();
175  break;
176  }
177 
178  // connecting to another infinite element
179  case 1:
180  case 2:
181  case 3:
182  case 4:
183  {
184  face = std::make_unique<InfQuad6>();
185  break;
186  }
187 
188  default:
189  libmesh_error_msg("Invalid side i = " << i);
190  }
191 
192  for (auto n : face->node_index_range())
193  face->set_node(n, this->node_ptr(InfHex18::side_nodes_map[i][n]));
194 
195  face->set_interior_parent(this);
196  face->inherit_data_from(*this);
197 
198  return face;
199 }
200 
201 
202 
203 void InfHex18::build_side_ptr (std::unique_ptr<Elem> & side,
204  const unsigned int i)
205 {
206  libmesh_assert_less (i, this->n_sides());
207 
208  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
209  switch (i)
210  {
211  // the base face
212  case 0:
213  {
214  if (!side.get() || side->type() != QUAD9)
215  {
216  side = this->build_side_ptr(i);
217  return;
218  }
219  break;
220  }
221 
222  // connecting to another infinite element
223  case 1:
224  case 2:
225  case 3:
226  case 4:
227  {
228  if (!side.get() || side->type() != INFQUAD6)
229  {
230  side = this->build_side_ptr(i);
231  return;
232  }
233  break;
234  }
235 
236  default:
237  libmesh_error_msg("Invalid side i = " << i);
238  }
239 
240  side->inherit_data_from(*this);
241 
242  // Set the nodes
243  for (auto n : side->node_index_range())
244  side->set_node(n, this->node_ptr(InfHex18::side_nodes_map[i][n]));
245 }
246 
247 
248 
249 std::unique_ptr<Elem> InfHex18::build_edge_ptr (const unsigned int i)
250 {
251  if (i < 4) // base edges
252  return this->simple_build_edge_ptr<Edge3,InfHex18>(i);
253 
254  // infinite edges
255  return this->simple_build_edge_ptr<InfEdge2,InfHex18>(i);
256 }
257 
258 
259 
260 void InfHex18::build_edge_ptr (std::unique_ptr<Elem> & edge,
261  const unsigned int i)
262 {
263  libmesh_assert_less (i, this->n_edges());
264 
265  switch (i)
266  {
267  // the base edges
268  case 0:
269  case 1:
270  case 2:
271  case 3:
272  {
273  if (!edge.get() || edge->type() != EDGE3)
274  {
275  edge = this->build_edge_ptr(i);
276  return;
277  }
278  break;
279  }
280 
281  // the infinite edges
282  case 4:
283  case 5:
284  case 6:
285  case 7:
286  {
287  if (!edge.get() || edge->type() != INFEDGE2)
288  {
289  edge = this->build_edge_ptr(i);
290  return;
291  }
292  break;
293  }
294 
295  default:
296  libmesh_error_msg("Invalid edge i = " << i);
297  }
298 
299  edge->inherit_data_from(*this);
300 
301  // Set the nodes
302  for (auto n : edge->node_index_range())
303  edge->set_node(n, this->node_ptr(InfHex18::edge_nodes_map[i][n]));
304 }
305 
306 
307 
308 void InfHex18::connectivity(const unsigned int sc,
309  const IOPackage iop,
310  std::vector<dof_id_type> & conn) const
311 {
313  libmesh_assert_less (sc, this->n_sub_elem());
314  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
315 
316  switch (iop)
317  {
318  case TECPLOT:
319  {
320  switch (sc)
321  {
322  case 0:
323 
324  conn[0] = this->node_id(0)+1;
325  conn[1] = this->node_id(8)+1;
326  conn[2] = this->node_id(16)+1;
327  conn[3] = this->node_id(11)+1;
328  conn[4] = this->node_id(4)+1;
329  conn[5] = this->node_id(12)+1;
330  conn[6] = this->node_id(17)+1;
331  conn[7] = this->node_id(15)+1;
332 
333  return;
334 
335  case 1:
336 
337  conn[0] = this->node_id(8)+1;
338  conn[1] = this->node_id(1)+1;
339  conn[2] = this->node_id(9)+1;
340  conn[3] = this->node_id(16)+1;
341  conn[4] = this->node_id(12)+1;
342  conn[5] = this->node_id(5)+1;
343  conn[6] = this->node_id(13)+1;
344  conn[7] = this->node_id(17)+1;
345 
346  return;
347 
348  case 2:
349 
350  conn[0] = this->node_id(11)+1;
351  conn[1] = this->node_id(16)+1;
352  conn[2] = this->node_id(10)+1;
353  conn[3] = this->node_id(3)+1;
354  conn[4] = this->node_id(15)+1;
355  conn[5] = this->node_id(17)+1;
356  conn[6] = this->node_id(14)+1;
357  conn[7] = this->node_id(7)+1;
358 
359  return;
360 
361  case 3:
362 
363  conn[0] = this->node_id(16)+1;
364  conn[1] = this->node_id(9)+1;
365  conn[2] = this->node_id(2)+1;
366  conn[3] = this->node_id(10)+1;
367  conn[4] = this->node_id(17)+1;
368  conn[5] = this->node_id(13)+1;
369  conn[6] = this->node_id(6)+1;
370  conn[7] = this->node_id(14)+1;
371 
372  return;
373 
374  default:
375  libmesh_error_msg("Invalid sc = " << sc);
376  }
377  }
378 
379  default:
380  libmesh_error_msg("Unsupported IO package " << iop);
381  }
382 }
383 
384 
385 
386 
387 unsigned int InfHex18::n_second_order_adjacent_vertices (const unsigned int n) const
388 {
389  switch (n)
390  {
391  case 8:
392  case 9:
393  case 10:
394  case 11:
395  case 12:
396  case 13:
397  case 14:
398  case 15:
399  return 2;
400 
401  case 16:
402  case 17:
403  return 4;
404 
405  default:
406  libmesh_error_msg("Invalid node n = " << n);
407  }
408 }
409 
410 
411 
412 unsigned short int InfHex18::second_order_adjacent_vertex (const unsigned int n,
413  const unsigned int v) const
414 {
415  libmesh_assert_greater_equal (n, this->n_vertices());
416  libmesh_assert_less (n, this->n_nodes());
417  libmesh_assert_less (v, this->n_second_order_adjacent_vertices(n));
418 
419  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  return static_cast<unsigned short int>(v);
428  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  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  return _second_order_adjacent_vertices[n-this->n_vertices()][v];
443 }
444 
445 
446 
447 std::pair<unsigned short int, unsigned short int>
448 InfHex18::second_order_child_vertex (const unsigned int n) const
449 {
450  libmesh_assert_greater_equal (n, this->n_vertices());
451  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  return std::pair<unsigned short int, unsigned short int>
460 }
461 
462 
463 
464 
465 
466 
467 
468 #ifdef LIBMESH_ENABLE_AMR
469 
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 InfHex18::permute(unsigned int perm_num)
571 {
572  libmesh_assert_less (perm_num, 4);
573 
574  for (unsigned int i = 0; i != perm_num; ++i)
575  {
576  swap4nodes(0,1,2,3);
577  swap4nodes(4,5,6,7);
578  swap4nodes(8,9,10,11);
579  swap4nodes(12,13,14,15);
580  swap4neighbors(1,2,3,4);
581  }
582 }
583 
584 
585 void
586 InfHex18::flip(BoundaryInfo * boundary_info)
587 {
588  libmesh_assert(boundary_info);
589 
590  swap2nodes(0,1);
591  swap2nodes(2,3);
592  swap2nodes(4,5);
593  swap2nodes(6,7);
594  swap2nodes(9,11);
595  swap2nodes(13,15);
596  swap2neighbors(0,4);
597  swap2boundarysides(0,4,boundary_info);
598  swap2boundaryedges(1,3,boundary_info);
599  swap2boundaryedges(4,5,boundary_info);
600  swap2boundaryedges(6,7,boundary_info);
601 }
602 
603 
604 ElemType
605 InfHex18::side_type (const unsigned int s) const
606 {
607  libmesh_assert_less (s, 5);
608  if (s == 0)
609  return QUAD9;
610  return INFQUAD6;
611 }
612 
613 
614 } // namespace libMesh
615 
616 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
static const int num_nodes
Geometric constants for InfHex18.
static const int nodes_per_edge
static const int num_children
Definition: cell_inf_hex.h:85
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:3550
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
static const int num_sides
Geometric constants for all InfHexes.
Definition: cell_inf_hex.h:83
Node ** _nodes
Pointers to the nodes we are connected to.
Definition: elem.h:2245
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const override
virtual dof_id_type key() const
Definition: elem.C:753
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
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:3534
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:250
static const int num_edges
Definition: cell_inf_hex.h:84
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:2143
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2092
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:99
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:2102
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const override
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:260
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:2153
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:112
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:3294
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
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:255
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:92
virtual unsigned int n_nodes() const override