libMesh
cell_hex8.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 
19 // Local includes
20 #include "libmesh/side.h"
21 #include "libmesh/cell_hex8.h"
22 #include "libmesh/edge_edge2.h"
23 #include "libmesh/face_quad4.h"
24 #include "libmesh/enum_io_package.h"
25 #include "libmesh/enum_order.h"
26 #include "libmesh/fe_lagrange_shape_1D.h"
27 
28 // C++ includes
29 #include <array>
30 
31 namespace libMesh
32 {
33 
34 
35 
36 
37 // ------------------------------------------------------------
38 // Hex8 class static member initializations
39 const int Hex8::num_nodes;
40 const int Hex8::num_sides;
41 const int Hex8::num_edges;
42 const int Hex8::num_children;
43 const int Hex8::nodes_per_side;
44 const int Hex8::nodes_per_edge;
45 
47  {
48  {0, 3, 2, 1}, // Side 0
49  {0, 1, 5, 4}, // Side 1
50  {1, 2, 6, 5}, // Side 2
51  {2, 3, 7, 6}, // Side 3
52  {3, 0, 4, 7}, // Side 4
53  {4, 5, 6, 7} // Side 5
54  };
55 
57  {
58  {0, 1}, // Edge 0
59  {1, 2}, // Edge 1
60  {2, 3}, // Edge 2
61  {0, 3}, // Edge 3
62  {0, 4}, // Edge 4
63  {1, 5}, // Edge 5
64  {2, 6}, // Edge 6
65  {3, 7}, // Edge 7
66  {4, 5}, // Edge 8
67  {5, 6}, // Edge 9
68  {6, 7}, // Edge 10
69  {4, 7} // Edge 11
70  };
71 
72 // ------------------------------------------------------------
73 // Hex8 class member functions
74 
75 bool Hex8::is_vertex(const unsigned int) const
76 {
77  return true;
78 }
79 
80 bool Hex8::is_edge(const unsigned int) const
81 {
82  return false;
83 }
84 
85 bool Hex8::is_face(const unsigned int) const
86 {
87  return false;
88 }
89 
90 bool Hex8::is_node_on_side(const unsigned int n,
91  const unsigned int s) const
92 {
93  libmesh_assert_less (s, n_sides());
94  return std::find(std::begin(side_nodes_map[s]),
95  std::end(side_nodes_map[s]),
96  n) != std::end(side_nodes_map[s]);
97 }
98 
99 std::vector<unsigned>
100 Hex8::nodes_on_side(const unsigned int s) const
101 {
102  libmesh_assert_less(s, n_sides());
103  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
104 }
105 
106 std::vector<unsigned>
107 Hex8::nodes_on_edge(const unsigned int e) const
108 {
109  libmesh_assert_less(e, n_edges());
110  return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
111 }
112 
113 bool Hex8::is_node_on_edge(const unsigned int n,
114  const unsigned int e) const
115 {
116  libmesh_assert_less (e, n_edges());
117  return std::find(std::begin(edge_nodes_map[e]),
118  std::end(edge_nodes_map[e]),
119  n) != std::end(edge_nodes_map[e]);
120 }
121 
122 
123 
125 {
126  // Make sure x-edge endpoints are affine
127  Point v = this->point(1) - this->point(0);
128  if (!v.relative_fuzzy_equals(this->point(2) - this->point(3), affine_tol) ||
129  !v.relative_fuzzy_equals(this->point(5) - this->point(4), affine_tol) ||
130  !v.relative_fuzzy_equals(this->point(6) - this->point(7), affine_tol))
131  return false;
132  // Make sure xz-faces are identical parallelograms
133  v = this->point(4) - this->point(0);
134  if (!v.relative_fuzzy_equals(this->point(7) - this->point(3), affine_tol))
135  return false;
136  // If all the above checks out, the map is affine
137  return true;
138 }
139 
140 
141 
143 {
144  return FIRST;
145 }
146 
147 
148 
149 std::unique_ptr<Elem> Hex8::build_side_ptr (const unsigned int i,
150  bool proxy)
151 {
152  return this->simple_build_side_ptr<Quad4, Hex8>(i, proxy);
153 }
154 
155 
156 
157 void Hex8::build_side_ptr (std::unique_ptr<Elem> & side,
158  const unsigned int i)
159 {
160  this->simple_build_side_ptr<Hex8>(side, i, QUAD4);
161 }
162 
163 
164 
165 std::unique_ptr<Elem> Hex8::build_edge_ptr (const unsigned int i)
166 {
167  return this->simple_build_edge_ptr<Edge2,Hex8>(i);
168 }
169 
170 
171 
172 void Hex8::build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i)
173 {
174  this->simple_build_edge_ptr<Hex8>(edge, i, EDGE2);
175 }
176 
177 
178 
179 void Hex8::connectivity(const unsigned int libmesh_dbg_var(sc),
180  const IOPackage iop,
181  std::vector<dof_id_type> & conn) const
182 {
184  libmesh_assert_less (sc, this->n_sub_elem());
185  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
186 
187  conn.resize(8);
188 
189  switch (iop)
190  {
191  case TECPLOT:
192  {
193  conn[0] = this->node_id(0)+1;
194  conn[1] = this->node_id(1)+1;
195  conn[2] = this->node_id(2)+1;
196  conn[3] = this->node_id(3)+1;
197  conn[4] = this->node_id(4)+1;
198  conn[5] = this->node_id(5)+1;
199  conn[6] = this->node_id(6)+1;
200  conn[7] = this->node_id(7)+1;
201  return;
202  }
203 
204  case VTK:
205  {
206  for (auto i : index_range(conn))
207  conn[i] = this->node_id(i);
208  return;
209  }
210 
211  default:
212  libmesh_error_msg("Unsupported IO package " << iop);
213  }
214 }
215 
216 
217 
218 #ifdef LIBMESH_ENABLE_AMR
219 
221  {
222  // The 8 children of the Hex-type elements can be thought of as being
223  // associated with the 8 vertices of the Hex. Some of the children are
224  // numbered the same as their corresponding vertex, while some are
225  // not. The children which are numbered differently have been marked
226  // with ** in the comments below.
227 
228  // embedding matrix for child 0 (child 0 is associated with vertex 0)
229  {
230  // 0 1 2 3 4 5 6 7
231  { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0
232  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
233  { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 2
234  { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
235  { 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0}, // 4
236  { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 5
237  {.125, .125, .125, .125, .125, .125, .125, .125}, // 6
238  { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25} // 7
239  },
240 
241  // embedding matrix for child 1 (child 1 is associated with vertex 1)
242  {
243  // 0 1 2 3 4 5 6 7
244  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0
245  { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
246  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
247  { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 3
248  { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 4
249  { 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0}, // 5
250  { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 6
251  {.125, .125, .125, .125, .125, .125, .125, .125} // 7
252  },
253 
254  // embedding matrix for child 2 (child 2 is associated with vertex 3**)
255  {
256  // 0 1 2 3 4 5 6 7
257  { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0
258  { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 1
259  { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 2
260  { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 3
261  { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25}, // 4
262  {.125, .125, .125, .125, .125, .125, .125, .125}, // 5
263  { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25}, // 6
264  { 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5} // 7
265  },
266 
267  // embedding matrix for child 3 (child 3 is associated with vertex 2**)
268  {
269  // 0 1 2 3 4 5 6 7
270  { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 0
271  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
272  { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
273  { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
274  {.125, .125, .125, .125, .125, .125, .125, .125}, // 4
275  { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 5
276  { 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0}, // 6
277  { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25} // 7
278  },
279 
280  // embedding matrix for child 4 (child 4 is associated with vertex 4)
281  {
282  // 0 1 2 3 4 5 6 7
283  { 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0}, // 0
284  { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 1
285  {.125, .125, .125, .125, .125, .125, .125, .125}, // 2
286  { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25}, // 3
287  { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 4
288  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 5
289  { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25}, // 6
290  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5} // 7
291  },
292 
293  // embedding matrix for child 5 (child 5 is associated with vertex 5)
294  {
295  // 0 1 2 3 4 5 6 7
296  { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 0
297  { 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0}, // 1
298  { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 2
299  {.125, .125, .125, .125, .125, .125, .125, .125}, // 3
300  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 4
301  { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 5
302  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 6
303  { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25} // 7
304  },
305 
306  // embedding matrix for child 6 (child 6 is associated with vertex 7**)
307  {
308  // 0 1 2 3 4 5 6 7
309  { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25}, // 0
310  {.125, .125, .125, .125, .125, .125, .125, .125}, // 1
311  { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25}, // 2
312  { 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5}, // 3
313  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5}, // 4
314  { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25}, // 5
315  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 6
316  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0} // 7
317  },
318 
319  // embedding matrix for child 7 (child 7 is associated with vertex 6**)
320  {
321  // 0 1 2 3 4 5 6 7
322  {.125, .125, .125, .125, .125, .125, .125, .125}, // 0
323  { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 1
324  { 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0}, // 2
325  { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25}, // 3
326  { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25}, // 4
327  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 5
328  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 6
329  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5} // 7
330  }
331  };
332 
333 
334 
335 
336 #endif
337 
338 
339 
341  const Point & x0, const Point & x1, const Point & x2, const Point & x3,
342  const Point & x4, const Point & x5, const Point & x6, const Point & x7)
343 {
344  // The Jacobian is dx/d(xi) dot (dx/d(eta) cross dx/d(zeta)), where
345  // dx/d(xi) = a1*eta*zeta + b1*eta + c1*zeta + d1
346  // dx/d(eta) = a2*xi*zeta + b2*xi + c2*zeta + d2
347  // dx/d(zeta) = a3*xi*eta + b3*xi + c3*eta + d3
348 
349  // Notes:
350  // 1.) Several of these coefficient vectors are equal, as noted below.
351  // 2.) These are all off by a factor of 8, but this cancels when we
352  // divide by the volume, which will also be off by the same
353  // factor.
354  Point
355  a1 = -x0 + x1 - x2 + x3 + x4 - x5 + x6 - x7,
356  a2 = a1,
357  a3 = a1;
358 
359  Point
360  b1 = x0 - x1 + x2 - x3 + x4 - x5 + x6 - x7,
361  b2 = b1,
362  b3 = x0 - x1 - x2 + x3 - x4 + x5 + x6 - x7;
363 
364  Point
365  c1 = b3,
366  c2 = x0 + x1 - x2 - x3 - x4 - x5 + x6 + x7,
367  c3 = c2;
368 
369  Point
370  d1 = -x0 + x1 + x2 - x3 - x4 + x5 + x6 - x7,
371  d2 = -x0 - x1 + x2 + x3 - x4 - x5 + x6 + x7,
372  d3 = -x0 - x1 - x2 - x3 + x4 + x5 + x6 + x7;
373 
374  // Use 2x2x2 quadrature to compute the integral of each basis
375  // function (as defined on the [-1,1]^3 reference domain). We use
376  // a quadrature rule which is exact for tri-cubics. The weights for
377  // this rule are all equal to 1.
378  static const Real q[2] = {-std::sqrt(3.)/3, std::sqrt(3.)/3.};
379 
380  // Indices for computing tensor product basis functions. This is
381  // copied from fe_lagrange_shape_3D.C
382  static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
383  static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
384  static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
385 
386  // Compute nodal volumes
387  std::array<Real, Hex8::num_nodes> V{};
388 
389  for (const auto & xi : q)
390  for (const auto & eta : q)
391  for (const auto & zeta : q)
392  {
393  Real jxw = triple_product(a1*eta*zeta + b1*eta + c1*zeta + d1,
394  a2*xi*zeta + b2*xi + c2*zeta + d2,
395  a3*xi*eta + b3*xi + c3*eta + d3);
396 
397  for (int i=0; i<Hex8::num_nodes; ++i)
398  V[i] += jxw *
399  fe_lagrange_1D_linear_shape(i0[i], xi) *
400  fe_lagrange_1D_linear_shape(i1[i], eta) *
401  fe_lagrange_1D_linear_shape(i2[i], zeta);
402  }
403 
404  // Compute centroid
405  return
406  (x0*V[0] + x1*V[1] + x2*V[2] + x3*V[3] + x4*V[4] + x5*V[5] + x6*V[6] + x7*V[7]) /
407  (V[0] + V[1] + V[2] + V[3] + V[4] + V[5] + V[6] + V[7]);
408 }
409 
410 
412 {
414  (point(0), point(1), point(2), point(3),
415  point(4), point(5), point(6), point(7));
416 }
417 
418 
420 {
421  // Make copies of our points. It makes the subsequent calculations a bit
422  // shorter and avoids dereferencing the same pointer multiple times.
423  Point
424  x0 = point(0), x1 = point(1), x2 = point(2), x3 = point(3),
425  x4 = point(4), x5 = point(5), x6 = point(6), x7 = point(7);
426 
427  // Construct constant data vectors. The notation is:
428  // \vec{x}_{\xi} = \vec{a1}*eta*zeta + \vec{b1}*eta + \vec{c1}*zeta + \vec{d1}
429  // \vec{x}_{\eta} = \vec{a2}*xi*zeta + \vec{b2}*xi + \vec{c2}*zeta + \vec{d2}
430  // \vec{x}_{\zeta} = \vec{a3}*xi*eta + \vec{b3}*xi + \vec{c3}*eta + \vec{d3}
431  // but it turns out that a1, a2, and a3 are not needed for the volume calculation.
432 
433  // Build up the 6 unique vectors which make up dx/dxi, dx/deta, and dx/dzeta.
434  Point q[6] =
435  {
436  /*b1*/ x0 - x1 + x2 - x3 + x4 - x5 + x6 - x7, /*=b2*/
437  /*c1*/ x0 - x1 - x2 + x3 - x4 + x5 + x6 - x7, /*=b3*/
438  /*d1*/ -x0 + x1 + x2 - x3 - x4 + x5 + x6 - x7,
439  /*c2*/ x0 + x1 - x2 - x3 - x4 - x5 + x6 + x7, /*=c3*/
440  /*d2*/ -x0 - x1 + x2 + x3 - x4 - x5 + x6 + x7,
441  /*d3*/ -x0 - x1 - x2 - x3 + x4 + x5 + x6 + x7
442  };
443 
444  // We could check for a linear element, but it's probably faster to
445  // just compute the result...
446  return
447  (triple_product(q[0], q[4], q[3]) +
448  triple_product(q[2], q[0], q[1]) +
449  triple_product(q[1], q[3], q[5])) / 192. +
450  triple_product(q[2], q[4], q[5]) / 64.;
451 }
452 
455 {
456  return Elem::loose_bounding_box();
457 }
458 
459 
460 void
461 Hex8::permute(unsigned int perm_num)
462 {
463  libmesh_assert_less (perm_num, 24);
464  const unsigned int side = perm_num % 6;
465  const unsigned int rotate = perm_num / 6;
466 
467  for (unsigned int i = 0; i != rotate; ++i)
468  {
469  swap4nodes(0,1,2,3);
470  swap4nodes(4,5,6,7);
471  swap4neighbors(1,2,3,4);
472  }
473 
474  switch (side) {
475  case 0:
476  break;
477  case 1:
478  swap4nodes(3,7,4,0);
479  swap4nodes(2,6,5,1);
480  swap4neighbors(0,3,5,1);
481  break;
482  case 2:
483  swap4nodes(0,4,5,1);
484  swap4nodes(3,7,6,2);
485  swap4neighbors(0,4,5,2);
486  break;
487  case 3:
488  swap4nodes(0,4,7,3);
489  swap4nodes(1,5,6,2);
490  swap4neighbors(0,1,5,3);
491  break;
492  case 4:
493  swap4nodes(1,5,4,0);
494  swap4nodes(2,6,7,3);
495  swap4neighbors(0,2,5,4);
496  break;
497  case 5:
498  swap2nodes(0,7);
499  swap2nodes(1,6);
500  swap2nodes(2,5);
501  swap2nodes(3,4);
502  swap2neighbors(0,5);
503  swap2neighbors(1,3);
504  break;
505  default:
506  libmesh_error();
507  }
508 }
509 
510 
511 void
512 Hex8::flip(BoundaryInfo * boundary_info)
513 {
514  swap2nodes(0,1);
515  swap2nodes(2,3);
516  swap2nodes(4,5);
517  swap2nodes(6,7);
518  swap2neighbors(2,4);
519  swap2boundarysides(2,4,boundary_info);
520  swap2boundaryedges(1,3,boundary_info);
521  swap2boundaryedges(4,5,boundary_info);
522  swap2boundaryedges(6,7,boundary_info);
523  swap2boundaryedges(9,11,boundary_info);
524 }
525 
526 
527 ElemType
528 Hex8::side_type (const unsigned int libmesh_dbg_var(s)) const
529 {
530  libmesh_assert_less (s, 6);
531  return QUAD4;
532 }
533 
534 
535 } // namespace libMesh
static const int num_nodes
Geometric constants for Hex8.
Definition: cell_hex8.h:163
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: cell_hex8.C:100
static const int num_sides
Definition: cell_hex8.h:164
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override
Builds a EDGE2 built coincident with edge i.
Definition: cell_hex8.C:165
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 void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
Definition: cell_hex8.C:179
static const int num_edges
Definition: cell_hex8.h:165
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:3086
virtual Real volume() const override
A specialization for computing the area of a hexahedron with flat sides.
Definition: cell_hex8.C:419
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
Definition: cell_hex8.C:107
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
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
Definition: type_vector.h:53
The libMesh namespace provides an interface to certain functionality in the library.
virtual unsigned int n_sub_elem() const override
Definition: cell_hex8.h:86
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
Definition: cell_hex8.h:174
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
Definition: cell_hex8.h:241
ElemType side_type(const unsigned int s) const override final
Definition: cell_hex8.C:528
virtual Order default_order() const override
Definition: cell_hex8.C:142
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
Definition: type_vector.h:1068
void swap4nodes(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four node_ptrs, "rotating" them.
Definition: elem.h:1984
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:1933
static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]
This maps the node of the edge to element node numbers.
Definition: cell_hex8.h:180
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
static const int nodes_per_edge
Definition: cell_hex8.h:168
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
Definition: cell_hex8.C:461
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
Definition: elem.h:1902
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=false) override
Builds a QUAD4 built coincident with face i.
Definition: cell_hex8.C:149
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: cell_hex8.C:90
virtual bool has_affine_map() const override
Definition: cell_hex8.C:124
RealTensorValue rotate(MeshBase &mesh, const Real phi, const Real theta=0., const Real psi=0.)
Rotates the mesh in the xy plane.
virtual unsigned int n_edges() const override final
Definition: cell_hex.h:83
virtual bool is_face(const unsigned int i) const override
Definition: cell_hex8.C:85
virtual Point true_centroid() const override
We compute the centroid of the Hex using a customized numerical quadrature approach that avoids unnec...
Definition: cell_hex8.C:411
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:1943
static const int nodes_per_side
Definition: cell_hex8.h:167
Defines a Cartesian bounding box by the two corner extremum.
Definition: bounding_box.h:40
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
Definition: cell_hex8.C:512
virtual bool is_edge(const unsigned int i) const override
Definition: cell_hex8.C:80
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const override
Definition: cell_hex8.C:113
virtual unsigned int n_sides() const override final
Definition: cell_hex.h:73
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 BoundingBox loose_bounding_box() const override
Builds a bounding box out of the nodal positions.
Definition: cell_hex8.C:454
static Point centroid_from_points(const Point &x0, const Point &x1, const Point &x2, const Point &x3, const Point &x4, const Point &x5, const Point &x6, const Point &x7)
Class static helper function that computes the centroid of a hexahedral region from a set of input po...
Definition: cell_hex8.C:340
virtual bool is_vertex(const unsigned int i) const override
Definition: cell_hex8.C:75
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2299
const Point & point(const unsigned int i) const
Definition: elem.h:2277
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
Definition: type_vector.h:1004
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition: int_range.h:111
static const int num_children
Definition: cell_hex8.h:166
Real fe_lagrange_1D_linear_shape(const unsigned int i, const Real xi)