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