Line data Source code
1 : // The libMesh Finite Element Library.
2 : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 :
4 : // This library is free software; you can redistribute it and/or
5 : // modify it under the terms of the GNU Lesser General Public
6 : // License as published by the Free Software Foundation; either
7 : // version 2.1 of the License, or (at your option) any later version.
8 :
9 : // This library is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 : // Lesser General Public License for more details.
13 :
14 : // You should have received a copy of the GNU Lesser General Public
15 : // License along with this library; if not, write to the Free Software
16 : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 :
18 :
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 :
30 : namespace libMesh
31 : {
32 :
33 :
34 :
35 :
36 : // ------------------------------------------------------------
37 : // Hex8 class static member initializations
38 : const int Hex8::num_nodes;
39 : const int Hex8::nodes_per_side;
40 : const int Hex8::nodes_per_edge;
41 :
42 : const unsigned int Hex8::side_nodes_map[Hex8::num_sides][Hex8::nodes_per_side] =
43 : {
44 : {0, 3, 2, 1}, // Side 0
45 : {0, 1, 5, 4}, // Side 1
46 : {1, 2, 6, 5}, // Side 2
47 : {2, 3, 7, 6}, // Side 3
48 : {3, 0, 4, 7}, // Side 4
49 : {4, 5, 6, 7} // Side 5
50 : };
51 :
52 : const unsigned int Hex8::edge_nodes_map[Hex8::num_edges][Hex8::nodes_per_edge] =
53 : {
54 : {0, 1}, // Edge 0
55 : {1, 2}, // Edge 1
56 : {2, 3}, // Edge 2
57 : {0, 3}, // Edge 3
58 : {0, 4}, // Edge 4
59 : {1, 5}, // Edge 5
60 : {2, 6}, // Edge 6
61 : {3, 7}, // Edge 7
62 : {4, 5}, // Edge 8
63 : {5, 6}, // Edge 9
64 : {6, 7}, // Edge 10
65 : {4, 7} // Edge 11
66 : };
67 :
68 : // ------------------------------------------------------------
69 : // Hex8 class member functions
70 :
71 16207945 : bool Hex8::is_vertex(const unsigned int libmesh_dbg_var(n)) const
72 : {
73 1254360 : libmesh_assert_not_equal_to (n, invalid_uint);
74 16207945 : return true;
75 : }
76 :
77 0 : bool Hex8::is_edge(const unsigned int) const
78 : {
79 0 : return false;
80 : }
81 :
82 0 : bool Hex8::is_face(const unsigned int) const
83 : {
84 0 : return false;
85 : }
86 :
87 1252980 : bool Hex8::is_node_on_side(const unsigned int n,
88 : const unsigned int s) const
89 : {
90 81708 : libmesh_assert_less (s, n_sides());
91 81708 : return std::find(std::begin(side_nodes_map[s]),
92 1252980 : std::end(side_nodes_map[s]),
93 1252980 : n) != std::end(side_nodes_map[s]);
94 : }
95 :
96 : std::vector<unsigned>
97 62799871 : Hex8::nodes_on_side(const unsigned int s) const
98 : {
99 4626470 : libmesh_assert_less(s, n_sides());
100 67426341 : return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
101 : }
102 :
103 : std::vector<unsigned>
104 6612 : Hex8::nodes_on_edge(const unsigned int e) const
105 : {
106 504 : libmesh_assert_less(e, n_edges());
107 12720 : return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
108 : }
109 :
110 951204 : bool Hex8::is_node_on_edge(const unsigned int n,
111 : const unsigned int e) const
112 : {
113 30112 : libmesh_assert_less (e, n_edges());
114 30112 : return std::find(std::begin(edge_nodes_map[e]),
115 951204 : std::end(edge_nodes_map[e]),
116 951204 : n) != std::end(edge_nodes_map[e]);
117 : }
118 :
119 :
120 :
121 5840085 : bool Hex8::has_affine_map() const
122 : {
123 : // Make sure x-edge endpoints are affine
124 974090 : Point v = this->point(1) - this->point(0);
125 5773255 : if (!v.relative_fuzzy_equals(this->point(2) - this->point(3), affine_tol) ||
126 11601726 : !v.relative_fuzzy_equals(this->point(5) - this->point(4), affine_tol) ||
127 6248418 : !v.relative_fuzzy_equals(this->point(6) - this->point(7), affine_tol))
128 78728 : return false;
129 : // Make sure xz-faces are identical parallelograms
130 6244184 : v = this->point(4) - this->point(0);
131 5761357 : if (!v.relative_fuzzy_equals(this->point(7) - this->point(3), affine_tol))
132 0 : return false;
133 : // If all the above checks out, the map is affine
134 482827 : return true;
135 : }
136 :
137 :
138 :
139 136638344 : Order Hex8::default_order() const
140 : {
141 136638344 : return FIRST;
142 : }
143 :
144 :
145 :
146 1289795 : std::unique_ptr<Elem> Hex8::build_side_ptr (const unsigned int i)
147 : {
148 1289795 : return this->simple_build_side_ptr<Quad4, Hex8>(i);
149 : }
150 :
151 :
152 :
153 583013 : void Hex8::build_side_ptr (std::unique_ptr<Elem> & side,
154 : const unsigned int i)
155 : {
156 583013 : this->simple_build_side_ptr<Hex8>(side, i, QUAD4);
157 583013 : }
158 :
159 :
160 :
161 6446054 : std::unique_ptr<Elem> Hex8::build_edge_ptr (const unsigned int i)
162 : {
163 6446054 : return this->simple_build_edge_ptr<Edge2,Hex8>(i);
164 : }
165 :
166 :
167 :
168 135440 : void Hex8::build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i)
169 : {
170 135440 : this->simple_build_edge_ptr<Hex8>(edge, i, EDGE2);
171 135440 : }
172 :
173 :
174 :
175 234943 : void Hex8::connectivity(const unsigned int libmesh_dbg_var(sc),
176 : const IOPackage iop,
177 : std::vector<dof_id_type> & conn) const
178 : {
179 20253 : libmesh_assert(_nodes);
180 20253 : libmesh_assert_less (sc, this->n_sub_elem());
181 20253 : libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
182 :
183 234943 : conn.resize(8);
184 :
185 234943 : switch (iop)
186 : {
187 234943 : case TECPLOT:
188 : {
189 255196 : conn[0] = this->node_id(0)+1;
190 234943 : conn[1] = this->node_id(1)+1;
191 234943 : conn[2] = this->node_id(2)+1;
192 234943 : conn[3] = this->node_id(3)+1;
193 234943 : conn[4] = this->node_id(4)+1;
194 234943 : conn[5] = this->node_id(5)+1;
195 234943 : conn[6] = this->node_id(6)+1;
196 234943 : conn[7] = this->node_id(7)+1;
197 234943 : return;
198 : }
199 :
200 0 : case VTK:
201 : {
202 0 : for (auto i : index_range(conn))
203 0 : conn[i] = this->node_id(i);
204 0 : return;
205 : }
206 :
207 0 : default:
208 0 : libmesh_error_msg("Unsupported IO package " << iop);
209 : }
210 : }
211 :
212 :
213 :
214 : #ifdef LIBMESH_ENABLE_AMR
215 :
216 : const Real Hex8::_embedding_matrix[Hex8::num_children][Hex8::num_nodes][Hex8::num_nodes] =
217 : {
218 : // The 8 children of the Hex-type elements can be thought of as being
219 : // associated with the 8 vertices of the Hex. Some of the children are
220 : // numbered the same as their corresponding vertex, while some are
221 : // not. The children which are numbered differently have been marked
222 : // with ** in the comments below.
223 :
224 : // embedding matrix for child 0 (child 0 is associated with vertex 0)
225 : {
226 : // 0 1 2 3 4 5 6 7
227 : { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0
228 : { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
229 : { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 2
230 : { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
231 : { 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0}, // 4
232 : { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 5
233 : {.125, .125, .125, .125, .125, .125, .125, .125}, // 6
234 : { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25} // 7
235 : },
236 :
237 : // embedding matrix for child 1 (child 1 is associated with vertex 1)
238 : {
239 : // 0 1 2 3 4 5 6 7
240 : { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0
241 : { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
242 : { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
243 : { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 3
244 : { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 4
245 : { 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0}, // 5
246 : { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 6
247 : {.125, .125, .125, .125, .125, .125, .125, .125} // 7
248 : },
249 :
250 : // embedding matrix for child 2 (child 2 is associated with vertex 3**)
251 : {
252 : // 0 1 2 3 4 5 6 7
253 : { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0
254 : { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 1
255 : { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 2
256 : { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 3
257 : { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25}, // 4
258 : {.125, .125, .125, .125, .125, .125, .125, .125}, // 5
259 : { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25}, // 6
260 : { 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5} // 7
261 : },
262 :
263 : // embedding matrix for child 3 (child 3 is associated with vertex 2**)
264 : {
265 : // 0 1 2 3 4 5 6 7
266 : { .25, .25, .25, .25, 0.0, 0.0, 0.0, 0.0}, // 0
267 : { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
268 : { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
269 : { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
270 : {.125, .125, .125, .125, .125, .125, .125, .125}, // 4
271 : { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 5
272 : { 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0}, // 6
273 : { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25} // 7
274 : },
275 :
276 : // embedding matrix for child 4 (child 4 is associated with vertex 4)
277 : {
278 : // 0 1 2 3 4 5 6 7
279 : { 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0}, // 0
280 : { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 1
281 : {.125, .125, .125, .125, .125, .125, .125, .125}, // 2
282 : { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25}, // 3
283 : { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 4
284 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 5
285 : { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25}, // 6
286 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5} // 7
287 : },
288 :
289 : // embedding matrix for child 5 (child 5 is associated with vertex 5)
290 : {
291 : // 0 1 2 3 4 5 6 7
292 : { .25, .25, 0.0, 0.0, .25, .25, 0.0, 0.0}, // 0
293 : { 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0}, // 1
294 : { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 2
295 : {.125, .125, .125, .125, .125, .125, .125, .125}, // 3
296 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 4
297 : { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 5
298 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 6
299 : { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25} // 7
300 : },
301 :
302 : // embedding matrix for child 6 (child 6 is associated with vertex 7**)
303 : {
304 : // 0 1 2 3 4 5 6 7
305 : { .25, 0.0, 0.0, .25, .25, 0.0, 0.0, .25}, // 0
306 : {.125, .125, .125, .125, .125, .125, .125, .125}, // 1
307 : { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25}, // 2
308 : { 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5}, // 3
309 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5}, // 4
310 : { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25}, // 5
311 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 6
312 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0} // 7
313 : },
314 :
315 : // embedding matrix for child 7 (child 7 is associated with vertex 6**)
316 : {
317 : // 0 1 2 3 4 5 6 7
318 : {.125, .125, .125, .125, .125, .125, .125, .125}, // 0
319 : { 0.0, .25, .25, 0.0, 0.0, .25, .25, 0.0}, // 1
320 : { 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.5, 0.0}, // 2
321 : { 0.0, 0.0, .25, .25, 0.0, 0.0, .25, .25}, // 3
322 : { 0.0, 0.0, 0.0, 0.0, .25, .25, .25, .25}, // 4
323 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 5
324 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 6
325 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5} // 7
326 : }
327 : };
328 :
329 :
330 :
331 :
332 : #endif
333 :
334 :
335 :
336 9327 : Point Hex8::centroid_from_points(
337 : const Point & x0, const Point & x1, const Point & x2, const Point & x3,
338 : const Point & x4, const Point & x5, const Point & x6, const Point & x7)
339 : {
340 : // The Jacobian is dx/d(xi) dot (dx/d(eta) cross dx/d(zeta)), where
341 : // dx/d(xi) = a1*eta*zeta + b1*eta + c1*zeta + d1
342 : // dx/d(eta) = a2*xi*zeta + b2*xi + c2*zeta + d2
343 : // dx/d(zeta) = a3*xi*eta + b3*xi + c3*eta + d3
344 :
345 : // Notes:
346 : // 1.) Several of these coefficient vectors are equal, as noted below.
347 : // 2.) These are all off by a factor of 8, but this cancels when we
348 : // divide by the volume, which will also be off by the same
349 : // factor.
350 : Point
351 554 : a1 = -x0 + x1 - x2 + x3 + x4 - x5 + x6 - x7,
352 554 : a2 = a1,
353 554 : a3 = a1;
354 :
355 : Point
356 554 : b1 = x0 - x1 + x2 - x3 + x4 - x5 + x6 - x7,
357 554 : b2 = b1,
358 554 : b3 = x0 - x1 - x2 + x3 - x4 + x5 + x6 - x7;
359 :
360 : Point
361 554 : c1 = b3,
362 554 : c2 = x0 + x1 - x2 - x3 - x4 - x5 + x6 + x7,
363 554 : c3 = c2;
364 :
365 : Point
366 554 : d1 = -x0 + x1 + x2 - x3 - x4 + x5 + x6 - x7,
367 554 : d2 = -x0 - x1 + x2 + x3 - x4 - x5 + x6 + x7,
368 554 : d3 = -x0 - x1 - x2 - x3 + x4 + x5 + x6 + x7;
369 :
370 : // Use 2x2x2 quadrature to compute the integral of each basis
371 : // function (as defined on the [-1,1]^3 reference domain). We use
372 : // a quadrature rule which is exact for tri-cubics. The weights for
373 : // this rule are all equal to 1.
374 : static const Real q[2] = {-std::sqrt(Real(3))/3, std::sqrt(Real(3))/3.};
375 :
376 : // Indices for computing tensor product basis functions. This is
377 : // copied from fe_lagrange_shape_3D.C
378 : static const unsigned int i0[] = {0, 1, 1, 0, 0, 1, 1, 0};
379 : static const unsigned int i1[] = {0, 0, 1, 1, 0, 0, 1, 1};
380 : static const unsigned int i2[] = {0, 0, 0, 0, 1, 1, 1, 1};
381 :
382 : // Compute nodal volumes
383 9327 : std::array<Real, Hex8::num_nodes> V{};
384 :
385 27981 : for (const auto & xi : q)
386 55962 : for (const auto & eta : q)
387 111924 : for (const auto & zeta : q)
388 : {
389 70184 : Real jxw = triple_product(a1*eta*zeta + b1*eta + c1*zeta + d1,
390 74616 : a2*xi*zeta + b2*xi + c2*zeta + d2,
391 79048 : a3*xi*eta + b3*xi + c3*eta + d3);
392 :
393 671544 : for (int i=0; i<Hex8::num_nodes; ++i)
394 1158400 : V[i] += jxw *
395 596928 : fe_lagrange_1D_linear_shape(i0[i], xi) *
396 1158400 : fe_lagrange_1D_linear_shape(i1[i], eta) *
397 596928 : fe_lagrange_1D_linear_shape(i2[i], zeta);
398 : }
399 :
400 : // Compute centroid
401 : return
402 554 : (x0*V[0] + x1*V[1] + x2*V[2] + x3*V[3] + x4*V[4] + x5*V[5] + x6*V[6] + x7*V[7]) /
403 10435 : (V[0] + V[1] + V[2] + V[3] + V[4] + V[5] + V[6] + V[7]);
404 : }
405 :
406 :
407 2968 : Point Hex8::true_centroid () const
408 : {
409 : return Hex8::centroid_from_points
410 2536 : (point(0), point(1), point(2), point(3),
411 3184 : point(4), point(5), point(6), point(7));
412 : }
413 :
414 :
415 237341 : Real Hex8::volume () const
416 : {
417 : // Make copies of our points. It makes the subsequent calculations a bit
418 : // shorter and avoids dereferencing the same pointer multiple times.
419 : Point
420 316313 : x0 = point(0), x1 = point(1), x2 = point(2), x3 = point(3),
421 296570 : x4 = point(4), x5 = point(5), x6 = point(6), x7 = point(7);
422 :
423 : // Construct constant data vectors. The notation is:
424 : // \vec{x}_{\xi} = \vec{a1}*eta*zeta + \vec{b1}*eta + \vec{c1}*zeta + \vec{d1}
425 : // \vec{x}_{\eta} = \vec{a2}*xi*zeta + \vec{b2}*xi + \vec{c2}*zeta + \vec{d2}
426 : // \vec{x}_{\zeta} = \vec{a3}*xi*eta + \vec{b3}*xi + \vec{c3}*eta + \vec{d3}
427 : // but it turns out that a1, a2, and a3 are not needed for the volume calculation.
428 :
429 : // Build up the 6 unique vectors which make up dx/dxi, dx/deta, and dx/dzeta.
430 : Point q[6] =
431 : {
432 19745 : /*b1*/ x0 - x1 + x2 - x3 + x4 - x5 + x6 - x7, /*=b2*/
433 19745 : /*c1*/ x0 - x1 - x2 + x3 - x4 + x5 + x6 - x7, /*=b3*/
434 19745 : /*d1*/ -x0 + x1 + x2 - x3 - x4 + x5 + x6 - x7,
435 19745 : /*c2*/ x0 + x1 - x2 - x3 - x4 - x5 + x6 + x7, /*=c3*/
436 19745 : /*d2*/ -x0 - x1 + x2 + x3 - x4 - x5 + x6 + x7,
437 19745 : /*d3*/ -x0 - x1 - x2 - x3 + x4 + x5 + x6 + x7
438 138215 : };
439 :
440 : // We could check for a linear element, but it's probably faster to
441 : // just compute the result...
442 : return
443 237341 : (triple_product(q[0], q[4], q[3]) +
444 237341 : triple_product(q[2], q[0], q[1]) +
445 237341 : triple_product(q[1], q[3], q[5])) / 192. +
446 237341 : triple_product(q[2], q[4], q[5]) / 64.;
447 : }
448 :
449 : BoundingBox
450 10538260 : Hex8::loose_bounding_box () const
451 : {
452 10538260 : return Elem::loose_bounding_box();
453 : }
454 :
455 :
456 : void
457 3519 : Hex8::permute(unsigned int perm_num)
458 : {
459 354 : libmesh_assert_less (perm_num, 24);
460 3519 : const unsigned int side = perm_num % 6;
461 3519 : const unsigned int rotate = perm_num / 6;
462 :
463 10620 : for (unsigned int i = 0; i != rotate; ++i)
464 : {
465 7101 : swap4nodes(0,1,2,3);
466 7101 : swap4nodes(4,5,6,7);
467 6327 : swap4neighbors(1,2,3,4);
468 : }
469 :
470 3519 : switch (side) {
471 32 : case 0:
472 32 : break;
473 384 : case 1:
474 384 : swap4nodes(3,7,4,0);
475 384 : swap4nodes(2,6,5,1);
476 352 : swap4neighbors(0,3,5,1);
477 352 : break;
478 384 : case 2:
479 384 : swap4nodes(0,4,5,1);
480 384 : swap4nodes(3,7,6,2);
481 352 : swap4neighbors(0,4,5,2);
482 352 : break;
483 384 : case 3:
484 384 : swap4nodes(0,4,7,3);
485 384 : swap4nodes(1,5,6,2);
486 352 : swap4neighbors(0,1,5,3);
487 352 : break;
488 384 : case 4:
489 384 : swap4nodes(1,5,4,0);
490 384 : swap4nodes(2,6,7,3);
491 352 : swap4neighbors(0,2,5,4);
492 352 : break;
493 1599 : case 5:
494 1599 : swap2nodes(0,7);
495 1599 : swap2nodes(1,6);
496 1599 : swap2nodes(2,5);
497 1599 : swap2nodes(3,4);
498 194 : swap2neighbors(0,5);
499 194 : swap2neighbors(1,3);
500 194 : break;
501 0 : default:
502 0 : libmesh_error();
503 : }
504 3519 : }
505 :
506 :
507 : void
508 288 : Hex8::flip(BoundaryInfo * boundary_info)
509 : {
510 24 : libmesh_assert(boundary_info);
511 :
512 288 : swap2nodes(0,1);
513 288 : swap2nodes(2,3);
514 288 : swap2nodes(4,5);
515 288 : swap2nodes(6,7);
516 24 : swap2neighbors(2,4);
517 288 : swap2boundarysides(2,4,boundary_info);
518 288 : swap2boundaryedges(1,3,boundary_info);
519 288 : swap2boundaryedges(4,5,boundary_info);
520 288 : swap2boundaryedges(6,7,boundary_info);
521 288 : swap2boundaryedges(9,11,boundary_info);
522 288 : }
523 :
524 :
525 : ElemType
526 261108 : Hex8::side_type (const unsigned int libmesh_dbg_var(s)) const
527 : {
528 21759 : libmesh_assert_less (s, 6);
529 261108 : return QUAD4;
530 : }
531 :
532 :
533 : } // namespace libMesh
|