libMesh
cell_inf_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 // 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/side.h"
30 #include "libmesh/enum_io_package.h"
31 #include "libmesh/enum_order.h"
32 
33 namespace libMesh
34 {
35 
36 
37 // ------------------------------------------------------------
38 // InfHex8 class static member initializations
39 const int InfHex8::num_nodes;
40 const int InfHex8::num_sides;
41 const int InfHex8::num_edges;
42 const int InfHex8::num_children;
43 const int InfHex8::nodes_per_side;
44 const int InfHex8::nodes_per_edge;
45 
47  {
48  { 0, 1, 2, 3}, // Side 0
49  { 0, 1, 4, 5}, // Side 1
50  { 1, 2, 5, 6}, // Side 2
51  { 2, 3, 6, 7}, // Side 3
52  { 3, 0, 7, 4} // Side 4
53  };
54 
56  {
57  {0, 1}, // Edge 0
58  {1, 2}, // Edge 1
59  {2, 3}, // Edge 2
60  {0, 3}, // Edge 3
61  {0, 4}, // Edge 4
62  {1, 5}, // Edge 5
63  {2, 6}, // Edge 6
64  {3, 7} // Edge 7
65  };
66 
67 // ------------------------------------------------------------
68 // InfHex8 class member functions
69 
70 bool InfHex8::is_node_on_side(const unsigned int n,
71  const unsigned int s) const
72 {
73  libmesh_assert_less (s, n_sides());
74  return std::find(std::begin(side_nodes_map[s]),
75  std::end(side_nodes_map[s]),
76  n) != std::end(side_nodes_map[s]);
77 }
78 
79 std::vector<unsigned>
80 InfHex8::nodes_on_side(const unsigned int s) const
81 {
82  libmesh_assert_less(s, n_sides());
83  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
84 }
85 
86 std::vector<unsigned>
87 InfHex8::nodes_on_edge(const unsigned int e) const
88 {
89  libmesh_assert_less(e, n_edges());
90  return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
91 }
92 
93 bool InfHex8::is_node_on_edge(const unsigned int n,
94  const unsigned int e) const
95 {
96  libmesh_assert_less (e, n_edges());
97  return std::find(std::begin(edge_nodes_map[e]),
98  std::end(edge_nodes_map[e]),
99  n) != std::end(edge_nodes_map[e]);
100 }
101 
102 
103 
105 {
106  return FIRST;
107 }
108 
109 
110 
111 std::unique_ptr<Elem> InfHex8::build_side_ptr (const unsigned int i,
112  bool proxy)
113 {
114  libmesh_assert_less (i, this->n_sides());
115 
116  std::unique_ptr<Elem> face;
117  if (proxy)
118  {
119 #ifdef LIBMESH_ENABLE_DEPRECATED
120  libmesh_deprecated();
121  switch (i)
122  {
123  // base
124  case 0:
125  {
126  face = std::make_unique<Side<Quad4,InfHex8>>(this,i);
127  break;
128  }
129 
130  // ifem sides
131  case 1:
132  case 2:
133  case 3:
134  case 4:
135  {
136  face = std::make_unique<Side<InfQuad4,InfHex8>>(this,i);
137  break;
138  }
139 
140  default:
141  libmesh_error_msg("Invalid side i = " << i);
142  }
143 #else
144  libmesh_error();
145 #endif // LIBMESH_ENABLE_DEPRECATED
146  }
147  else
148  {
149  // Think of a unit cube: (-1,1) x (-1,1) x (1,1)
150  switch (i)
151  {
152  case 0: // the base face
153  {
154  face = std::make_unique<Quad4>();
155  break;
156  }
157 
158  // connecting to another infinite element
159  case 1:
160  case 2:
161  case 3:
162  case 4:
163  {
164  face = std::make_unique<InfQuad4>();
165  break;
166  }
167 
168  default:
169  libmesh_error_msg("Invalid side i = " << i);
170  }
171 
172  // Set the nodes
173  for (auto n : face->node_index_range())
174  face->set_node(n) = this->node_ptr(InfHex8::side_nodes_map[i][n]);
175  }
176 
177 #ifdef LIBMESH_ENABLE_DEPRECATED
178  if (!proxy) // proxy sides used to leave parent() set
179 #endif
180  face->set_parent(nullptr);
181  face->set_interior_parent(this);
182 
183  face->subdomain_id() = this->subdomain_id();
184  face->set_mapping_type(this->mapping_type());
185 #ifdef LIBMESH_ENABLE_AMR
186  face->set_p_level(this->p_level());
187 #endif
188 
189  return face;
190 }
191 
192 
193 void InfHex8::build_side_ptr (std::unique_ptr<Elem> & side,
194  const unsigned int i)
195 {
196  this->side_ptr(side, i);
197 }
198 
199 
200 
201 std::unique_ptr<Elem> InfHex8::build_edge_ptr (const unsigned int i)
202 {
203  if (i < 4) // base edges
204  return this->simple_build_edge_ptr<Edge2,InfHex8>(i);
205 
206  // infinite edges
207  return this->simple_build_edge_ptr<InfEdge2,InfHex8>(i);
208 }
209 
210 
211 
212 void InfHex8::build_edge_ptr (std::unique_ptr<Elem> & edge,
213  const unsigned int i)
214 {
215  libmesh_assert_less (i, this->n_edges());
216 
217  switch (i)
218  {
219  // the base edges
220  case 0:
221  case 1:
222  case 2:
223  case 3:
224  {
225  if (!edge.get() || edge->type() != EDGE2)
226  {
227  edge = this->build_edge_ptr(i);
228  return;
229  }
230  break;
231  }
232 
233  // the infinite edges
234  case 4:
235  case 5:
236  case 6:
237  case 7:
238  {
239  if (!edge.get() || edge->type() != INFEDGE2)
240  {
241  edge = this->build_edge_ptr(i);
242  return;
243  }
244  break;
245  }
246 
247  default:
248  libmesh_error_msg("Invalid edge i = " << i);
249  }
250 
251  edge->subdomain_id() = this->subdomain_id();
252  edge->set_mapping_type(this->mapping_type());
253 #ifdef LIBMESH_ENABLE_AMR
254  edge->set_p_level(this->p_level());
255 #endif
256 
257  // Set the nodes
258  for (auto n : edge->node_index_range())
259  edge->set_node(n) = this->node_ptr(InfHex8::edge_nodes_map[i][n]);
260 }
261 
262 
263 
264 void InfHex8::connectivity(const unsigned int libmesh_dbg_var(sc),
265  const IOPackage iop,
266  std::vector<dof_id_type> & conn) const
267 {
269  libmesh_assert_less (sc, this->n_sub_elem());
270  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
271 
272  switch (iop)
273  {
274  case TECPLOT:
275  {
276  conn.resize(8);
277  conn[0] = this->node_id(0)+1;
278  conn[1] = this->node_id(1)+1;
279  conn[2] = this->node_id(2)+1;
280  conn[3] = this->node_id(3)+1;
281  conn[4] = this->node_id(4)+1;
282  conn[5] = this->node_id(5)+1;
283  conn[6] = this->node_id(6)+1;
284  conn[7] = this->node_id(7)+1;
285  return;
286  }
287 
288  default:
289  libmesh_error_msg("Unsupported IO package " << iop);
290  }
291 }
292 
293 
294 
295 #ifdef LIBMESH_ENABLE_AMR
296 
298  {
299  // embedding matrix for child 0
300  {
301  // 0 1 2 3 4 5 6 7 th parent N.(ode)
302  { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
303  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
304  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 2
305  { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
306  { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 4
307  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 5
308  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 6
309  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5} // 7
310  },
311 
312  // embedding matrix for child 1
313  {
314  // 0 1 2 3 4 5 6 7 th parent N.(ode)
315  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
316  { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
317  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
318  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 3
319  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0}, // 4
320  { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 5
321  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 6
322  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25} // 7
323  },
324 
325  // embedding matrix for child 2
326  {
327  // 0 1 2 3 4 5 6 7 th parent N.(ode)
328  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
329  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0}, // 1
330  { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 2
331  { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 3
332  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 4
333  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 5
334  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 6
335  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5} // 7
336  },
337 
338  // embedding matrix for child 3
339  {
340  // 0 1 2 3 4 5 6 7 th parent N.(ode)
341  { 0.5, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
342  { 0.25, 0.25, 0.25, 0.25, 0.0, 0.0, 0.0, 0.0}, // 1
343  { 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 2
344  { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 3
345  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5}, // 4
346  { 0.0, 0.0, 0.0, 0.0, 0.25, 0.25, 0.25, 0.25}, // 5
347  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 6
348  { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0} // 7
349  }
350  };
351 
352 
353 #endif
354 
355 
356 void
357 InfHex8::permute(unsigned int perm_num)
358 {
359  libmesh_assert_less (perm_num, 4);
360 
361  for (unsigned int i = 0; i != perm_num; ++i)
362  {
363  swap4nodes(0,1,2,3);
364  swap4nodes(4,5,6,7);
365  swap4neighbors(1,2,3,4);
366  }
367 }
368 
369 
370 void
371 InfHex8::flip(BoundaryInfo * boundary_info)
372 {
373  swap2nodes(0,1);
374  swap2nodes(2,3);
375  swap2nodes(4,5);
376  swap2nodes(6,7);
377  swap2neighbors(0,4);
378  swap2boundarysides(0,4,boundary_info);
379  swap2boundaryedges(1,3,boundary_info);
380  swap2boundaryedges(4,5,boundary_info);
381  swap2boundaryedges(6,7,boundary_info);
382 }
383 
384 
385 ElemType
386 InfHex8::side_type (const unsigned int s) const
387 {
388  libmesh_assert_less (s, 5);
389  if (s == 0)
390  return QUAD4;
391  return INFQUAD4;
392 }
393 
394 
395 } // namespace libMesh
396 
397 #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...
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:93
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
ElemType side_type(const unsigned int s) const override final
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 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:3155
unsigned int p_level() const
Definition: elem.h:2945
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:136
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:1984
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
ElemMappingType mapping_type() const
Definition: elem.h:2957
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:1933
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:87
static const int num_children
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:1943
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: cell_inf_hex8.C:80
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
static const int num_sides
subdomain_id_type subdomain_id() const
Definition: elem.h:2391
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2331
void swap4neighbors(unsigned int n1, unsigned int n2, unsigned int n3, unsigned int n4)
Swaps four neighbor_ptrs, "rotating" them.
Definition: elem.h:1994
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:105
static const int num_edges
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=false) override
static const int num_nodes
Geometric constants for InfHex8.
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2299
static const int nodes_per_edge
virtual unsigned int n_sides() const override final
Definition: cell_inf_hex.h:85
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: cell_inf_hex8.C:70