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 : // 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_hex8.h"
25 : #include "libmesh/edge_edge2.h"
26 : #include "libmesh/edge_inf_edge2.h"
27 : #include "libmesh/face_quad4.h"
28 : #include "libmesh/face_inf_quad4.h"
29 : #include "libmesh/enum_io_package.h"
30 : #include "libmesh/enum_order.h"
31 :
32 : namespace libMesh
33 : {
34 :
35 :
36 : // ------------------------------------------------------------
37 : // InfHex8 class static member initializations
38 : const int InfHex8::num_nodes;
39 : const int InfHex8::nodes_per_side;
40 : const int InfHex8::nodes_per_edge;
41 :
42 : const unsigned int InfHex8::side_nodes_map[InfHex8::num_sides][InfHex8::nodes_per_side] =
43 : {
44 : { 0, 1, 2, 3}, // Side 0
45 : { 0, 1, 4, 5}, // Side 1
46 : { 1, 2, 5, 6}, // Side 2
47 : { 2, 3, 6, 7}, // Side 3
48 : { 3, 0, 7, 4} // Side 4
49 : };
50 :
51 : const unsigned int InfHex8::edge_nodes_map[InfHex8::num_edges][InfHex8::nodes_per_edge] =
52 : {
53 : {0, 1}, // Edge 0
54 : {1, 2}, // Edge 1
55 : {2, 3}, // Edge 2
56 : {0, 3}, // Edge 3
57 : {0, 4}, // Edge 4
58 : {1, 5}, // Edge 5
59 : {2, 6}, // Edge 6
60 : {3, 7} // Edge 7
61 : };
62 :
63 : // ------------------------------------------------------------
64 : // InfHex8 class member functions
65 :
66 356 : bool InfHex8::is_node_on_side(const unsigned int n,
67 : const unsigned int s) const
68 : {
69 132 : libmesh_assert_less (s, n_sides());
70 132 : return std::find(std::begin(side_nodes_map[s]),
71 356 : std::end(side_nodes_map[s]),
72 356 : n) != std::end(side_nodes_map[s]);
73 : }
74 :
75 : std::vector<unsigned>
76 136 : InfHex8::nodes_on_side(const unsigned int s) const
77 : {
78 47 : libmesh_assert_less(s, n_sides());
79 183 : return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
80 : }
81 :
82 : std::vector<unsigned>
83 160 : InfHex8::nodes_on_edge(const unsigned int e) const
84 : {
85 56 : libmesh_assert_less(e, n_edges());
86 216 : return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
87 : }
88 :
89 368 : bool InfHex8::is_node_on_edge(const unsigned int n,
90 : const unsigned int e) const
91 : {
92 144 : libmesh_assert_less (e, n_edges());
93 144 : return std::find(std::begin(edge_nodes_map[e]),
94 368 : std::end(edge_nodes_map[e]),
95 368 : n) != std::end(edge_nodes_map[e]);
96 : }
97 :
98 :
99 :
100 7304 : Order InfHex8::default_order() const
101 : {
102 7304 : return FIRST;
103 : }
104 :
105 :
106 :
107 201776 : std::unique_ptr<Elem> InfHex8::build_side_ptr (const unsigned int i)
108 : {
109 75543 : libmesh_assert_less (i, this->n_sides());
110 :
111 201776 : std::unique_ptr<Elem> face;
112 :
113 : // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
114 201776 : switch (i)
115 : {
116 201248 : case 0: // the base face
117 : {
118 201248 : face = std::make_unique<Quad4>();
119 201248 : break;
120 : }
121 :
122 : // connecting to another infinite element
123 528 : case 1:
124 : case 2:
125 : case 3:
126 : case 4:
127 : {
128 528 : face = std::make_unique<InfQuad4>();
129 528 : break;
130 : }
131 :
132 0 : default:
133 0 : libmesh_error_msg("Invalid side i = " << i);
134 : }
135 :
136 : // Set the nodes
137 1008880 : for (auto n : face->node_index_range())
138 1098892 : face->set_node(n, this->node_ptr(InfHex8::side_nodes_map[i][n]));
139 :
140 201776 : face->set_interior_parent(this);
141 128829 : face->inherit_data_from(*this);
142 :
143 201776 : return face;
144 0 : }
145 :
146 :
147 70 : void InfHex8::build_side_ptr (std::unique_ptr<Elem> & side,
148 : const unsigned int i)
149 : {
150 70 : this->side_ptr(side, i);
151 70 : side->set_interior_parent(this);
152 45 : side->inherit_data_from(*this);
153 70 : }
154 :
155 :
156 :
157 39568 : std::unique_ptr<Elem> InfHex8::build_edge_ptr (const unsigned int i)
158 : {
159 39568 : if (i < 4) // base edges
160 19692 : return this->simple_build_edge_ptr<Edge2,InfHex8>(i);
161 :
162 : // infinite edges
163 19876 : return this->simple_build_edge_ptr<InfEdge2,InfHex8>(i);
164 : }
165 :
166 :
167 :
168 0 : void InfHex8::build_edge_ptr (std::unique_ptr<Elem> & edge,
169 : const unsigned int i)
170 : {
171 0 : libmesh_assert_less (i, this->n_edges());
172 :
173 0 : switch (i)
174 : {
175 : // the base edges
176 0 : case 0:
177 : case 1:
178 : case 2:
179 : case 3:
180 : {
181 0 : if (!edge.get() || edge->type() != EDGE2)
182 : {
183 0 : edge = this->build_edge_ptr(i);
184 0 : return;
185 : }
186 0 : break;
187 : }
188 :
189 : // the infinite edges
190 0 : case 4:
191 : case 5:
192 : case 6:
193 : case 7:
194 : {
195 0 : if (!edge.get() || edge->type() != INFEDGE2)
196 : {
197 0 : edge = this->build_edge_ptr(i);
198 0 : return;
199 : }
200 0 : break;
201 : }
202 :
203 0 : default:
204 0 : libmesh_error_msg("Invalid edge i = " << i);
205 : }
206 :
207 0 : edge->inherit_data_from(*this);
208 :
209 : // Set the nodes
210 0 : for (auto n : edge->node_index_range())
211 0 : edge->set_node(n, this->node_ptr(InfHex8::edge_nodes_map[i][n]));
212 : }
213 :
214 :
215 :
216 0 : void InfHex8::connectivity(const unsigned int libmesh_dbg_var(sc),
217 : const IOPackage iop,
218 : std::vector<dof_id_type> & conn) const
219 : {
220 0 : libmesh_assert(_nodes);
221 0 : libmesh_assert_less (sc, this->n_sub_elem());
222 0 : libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
223 :
224 0 : switch (iop)
225 : {
226 0 : case TECPLOT:
227 : {
228 0 : conn.resize(8);
229 0 : conn[0] = this->node_id(0)+1;
230 0 : conn[1] = this->node_id(1)+1;
231 0 : conn[2] = this->node_id(2)+1;
232 0 : conn[3] = this->node_id(3)+1;
233 0 : conn[4] = this->node_id(4)+1;
234 0 : conn[5] = this->node_id(5)+1;
235 0 : conn[6] = this->node_id(6)+1;
236 0 : conn[7] = this->node_id(7)+1;
237 0 : return;
238 : }
239 :
240 0 : default:
241 0 : libmesh_error_msg("Unsupported IO package " << iop);
242 : }
243 : }
244 :
245 :
246 :
247 : #ifdef LIBMESH_ENABLE_AMR
248 :
249 : const Real InfHex8::_embedding_matrix[InfHex8::num_children][InfHex8::num_nodes][InfHex8::num_nodes] =
250 : {
251 : // embedding matrix for child 0
252 : {
253 : // 0 1 2 3 4 5 6 7 th parent N.(ode)
254 : { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
255 : { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
256 : { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 2
257 : { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
258 : { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 4
259 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 5
260 : { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 6
261 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5} // 7
262 : },
263 :
264 : // embedding matrix for child 1
265 : {
266 : // 0 1 2 3 4 5 6 7 th parent N.(ode)
267 : { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
268 : { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
269 : { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
270 : { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 3
271 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 4
272 : { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 5
273 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 6
274 : { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25} // 7
275 : },
276 :
277 : // embedding matrix for child 2
278 : {
279 : // 0 1 2 3 4 5 6 7 th parent N.(ode)
280 : { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
281 : { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
282 : { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
283 : { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
284 : { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 4
285 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 5
286 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 6
287 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5} // 7
288 : },
289 :
290 : // embedding matrix for child 3
291 : {
292 : // 0 1 2 3 4 5 6 7 th parent N.(ode)
293 : { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
294 : { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 1
295 : { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 2
296 : { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 3
297 : { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5}, // 4
298 : { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 5
299 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 6
300 : { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0} // 7
301 : }
302 : };
303 :
304 :
305 : #endif
306 :
307 :
308 : void
309 0 : InfHex8::permute(unsigned int perm_num)
310 : {
311 0 : libmesh_assert_less (perm_num, 4);
312 :
313 0 : for (unsigned int i = 0; i != perm_num; ++i)
314 : {
315 0 : swap4nodes(0,1,2,3);
316 0 : swap4nodes(4,5,6,7);
317 0 : swap4neighbors(1,2,3,4);
318 : }
319 0 : }
320 :
321 :
322 : void
323 0 : InfHex8::flip(BoundaryInfo * boundary_info)
324 : {
325 0 : libmesh_assert(boundary_info);
326 :
327 0 : swap2nodes(0,1);
328 0 : swap2nodes(2,3);
329 0 : swap2nodes(4,5);
330 0 : swap2nodes(6,7);
331 0 : swap2neighbors(0,4);
332 0 : swap2boundarysides(0,4,boundary_info);
333 0 : swap2boundaryedges(1,3,boundary_info);
334 0 : swap2boundaryedges(4,5,boundary_info);
335 0 : swap2boundaryedges(6,7,boundary_info);
336 0 : }
337 :
338 :
339 : ElemType
340 45 : InfHex8::side_type (const unsigned int s) const
341 : {
342 15 : libmesh_assert_less (s, 5);
343 45 : if (s == 0)
344 9 : return QUAD4;
345 12 : return INFQUAD4;
346 : }
347 :
348 :
349 : } // namespace libMesh
350 :
351 : #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
|