libMesh
cell_inf_hex8.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_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 
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 
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 bool InfHex8::is_node_on_side(const unsigned int n,
67  const unsigned int s) const
68 {
69  libmesh_assert_less (s, n_sides());
70  return std::find(std::begin(side_nodes_map[s]),
71  std::end(side_nodes_map[s]),
72  n) != std::end(side_nodes_map[s]);
73 }
74 
75 std::vector<unsigned>
76 InfHex8::nodes_on_side(const unsigned int s) const
77 {
78  libmesh_assert_less(s, n_sides());
79  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
80 }
81 
82 std::vector<unsigned>
83 InfHex8::nodes_on_edge(const unsigned int e) const
84 {
85  libmesh_assert_less(e, n_edges());
86  return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
87 }
88 
89 bool InfHex8::is_node_on_edge(const unsigned int n,
90  const unsigned int e) const
91 {
92  libmesh_assert_less (e, n_edges());
93  return std::find(std::begin(edge_nodes_map[e]),
94  std::end(edge_nodes_map[e]),
95  n) != std::end(edge_nodes_map[e]);
96 }
97 
98 
99 
101 {
102  return FIRST;
103 }
104 
105 
106 
107 std::unique_ptr<Elem> InfHex8::build_side_ptr (const unsigned int i)
108 {
109  libmesh_assert_less (i, this->n_sides());
110 
111  std::unique_ptr<Elem> face;
112 
113  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
114  switch (i)
115  {
116  case 0: // the base face
117  {
118  face = std::make_unique<Quad4>();
119  break;
120  }
121 
122  // connecting to another infinite element
123  case 1:
124  case 2:
125  case 3:
126  case 4:
127  {
128  face = std::make_unique<InfQuad4>();
129  break;
130  }
131 
132  default:
133  libmesh_error_msg("Invalid side i = " << i);
134  }
135 
136  // Set the nodes
137  for (auto n : face->node_index_range())
138  face->set_node(n, this->node_ptr(InfHex8::side_nodes_map[i][n]));
139 
140  face->set_interior_parent(this);
141  face->inherit_data_from(*this);
142 
143  return face;
144 }
145 
146 
147 void InfHex8::build_side_ptr (std::unique_ptr<Elem> & side,
148  const unsigned int i)
149 {
150  this->side_ptr(side, i);
151  side->set_interior_parent(this);
152  side->inherit_data_from(*this);
153 }
154 
155 
156 
157 std::unique_ptr<Elem> InfHex8::build_edge_ptr (const unsigned int i)
158 {
159  if (i < 4) // base edges
160  return this->simple_build_edge_ptr<Edge2,InfHex8>(i);
161 
162  // infinite edges
163  return this->simple_build_edge_ptr<InfEdge2,InfHex8>(i);
164 }
165 
166 
167 
168 void InfHex8::build_edge_ptr (std::unique_ptr<Elem> & edge,
169  const unsigned int i)
170 {
171  libmesh_assert_less (i, this->n_edges());
172 
173  switch (i)
174  {
175  // the base edges
176  case 0:
177  case 1:
178  case 2:
179  case 3:
180  {
181  if (!edge.get() || edge->type() != EDGE2)
182  {
183  edge = this->build_edge_ptr(i);
184  return;
185  }
186  break;
187  }
188 
189  // the infinite edges
190  case 4:
191  case 5:
192  case 6:
193  case 7:
194  {
195  if (!edge.get() || edge->type() != INFEDGE2)
196  {
197  edge = this->build_edge_ptr(i);
198  return;
199  }
200  break;
201  }
202 
203  default:
204  libmesh_error_msg("Invalid edge i = " << i);
205  }
206 
207  edge->inherit_data_from(*this);
208 
209  // Set the nodes
210  for (auto n : edge->node_index_range())
211  edge->set_node(n, this->node_ptr(InfHex8::edge_nodes_map[i][n]));
212 }
213 
214 
215 
216 void InfHex8::connectivity(const unsigned int libmesh_dbg_var(sc),
217  const IOPackage iop,
218  std::vector<dof_id_type> & conn) const
219 {
221  libmesh_assert_less (sc, this->n_sub_elem());
222  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
223 
224  switch (iop)
225  {
226  case TECPLOT:
227  {
228  conn.resize(8);
229  conn[0] = this->node_id(0)+1;
230  conn[1] = this->node_id(1)+1;
231  conn[2] = this->node_id(2)+1;
232  conn[3] = this->node_id(3)+1;
233  conn[4] = this->node_id(4)+1;
234  conn[5] = this->node_id(5)+1;
235  conn[6] = this->node_id(6)+1;
236  conn[7] = this->node_id(7)+1;
237  return;
238  }
239 
240  default:
241  libmesh_error_msg("Unsupported IO package " << iop);
242  }
243 }
244 
245 
246 
247 #ifdef LIBMESH_ENABLE_AMR
248 
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 InfHex8::permute(unsigned int perm_num)
310 {
311  libmesh_assert_less (perm_num, 4);
312 
313  for (unsigned int i = 0; i != perm_num; ++i)
314  {
315  swap4nodes(0,1,2,3);
316  swap4nodes(4,5,6,7);
317  swap4neighbors(1,2,3,4);
318  }
319 }
320 
321 
322 void
323 InfHex8::flip(BoundaryInfo * boundary_info)
324 {
325  libmesh_assert(boundary_info);
326 
327  swap2nodes(0,1);
328  swap2nodes(2,3);
329  swap2nodes(4,5);
330  swap2nodes(6,7);
331  swap2neighbors(0,4);
332  swap2boundarysides(0,4,boundary_info);
333  swap2boundaryedges(1,3,boundary_info);
334  swap2boundaryedges(4,5,boundary_info);
335  swap2boundaryedges(6,7,boundary_info);
336 }
337 
338 
339 ElemType
340 InfHex8::side_type (const unsigned int s) const
341 {
342  libmesh_assert_less (s, 5);
343  if (s == 0)
344  return QUAD4;
345  return INFQUAD4;
346 }
347 
348 
349 } // namespace libMesh
350 
351 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
static const int num_children
Definition: cell_inf_hex.h:85
ElemType
Defines an enum for geometric element types.
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const override
Definition: cell_inf_hex8.C:89
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
ElemType side_type(const unsigned int s) const override final
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 int n_sub_elem() const override
Definition: cell_inf_hex8.h:86
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
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
static const int nodes_per_side
The libMesh namespace provides an interface to certain functionality in the library.
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
Definition: cell_inf_hex.C:146
static const int num_edges
Definition: cell_inf_hex.h:84
virtual Order default_order() const 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
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2092
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
Definition: cell_inf_hex8.C:83
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:2102
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: cell_inf_hex8.C:76
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:2153
static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]
This maps the node of the side to element node numbers.
virtual unsigned int n_edges() const override final
Definition: cell_inf_hex.h:112
static const int num_nodes
Geometric constants for InfHex8.
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
static const int nodes_per_edge
virtual unsigned int n_sides() const override final
Definition: cell_inf_hex.h:92
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: cell_inf_hex8.C:66