libMesh
cell_inf_prism6.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_prism6.h"
25 #include "libmesh/edge_edge2.h"
26 #include "libmesh/edge_inf_edge2.h"
27 #include "libmesh/fe_interface.h"
28 #include "libmesh/face_inf_quad4.h"
29 #include "libmesh/face_tri3.h"
30 #include "libmesh/enum_io_package.h"
31 #include "libmesh/enum_order.h"
32 
33 namespace libMesh
34 {
35 
36 
37 // ------------------------------------------------------------
38 // InfPrism6 class static member initializations
39 const int InfPrism6::num_nodes;
42 
44  {
45  { 0, 1, 2, 99}, // Side 0
46  { 0, 1, 3, 4}, // Side 1
47  { 1, 2, 4, 5}, // Side 2
48  { 2, 0, 5, 3} // Side 3
49  };
50 
52  {
53  {0, 1}, // Edge 0
54  {1, 2}, // Edge 1
55  {0, 2}, // Edge 2
56  {0, 3}, // Edge 3
57  {1, 4}, // Edge 4
58  {2, 5} // Edge 5
59  };
60 
61 // ------------------------------------------------------------
62 // InfPrism6 class member functions
63 
64 bool InfPrism6::is_node_on_side(const unsigned int n,
65  const unsigned int s) const
66 {
67  libmesh_assert_less (s, n_sides());
68  return std::find(std::begin(side_nodes_map[s]),
69  std::end(side_nodes_map[s]),
70  n) != std::end(side_nodes_map[s]);
71 }
72 
73 std::vector<unsigned>
74 InfPrism6::nodes_on_side(const unsigned int s) const
75 {
76  libmesh_assert_less(s, n_sides());
77  auto trim = (s > 0) ? 0 : 1;
78  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
79 }
80 
81 std::vector<unsigned>
82 InfPrism6::nodes_on_edge(const unsigned int e) const
83 {
84  libmesh_assert_less(e, n_edges());
85  return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
86 }
87 
88 bool InfPrism6::is_node_on_edge(const unsigned int n,
89  const unsigned int e) const
90 {
91  libmesh_assert_less (e, n_edges());
92  return std::find(std::begin(edge_nodes_map[e]),
93  std::end(edge_nodes_map[e]),
94  n) != std::end(edge_nodes_map[e]);
95 }
96 
97 
98 
100 {
101  return FIRST;
102 }
103 
104 
105 
106 std::unique_ptr<Elem> InfPrism6::build_side_ptr (const unsigned int i)
107 {
108  libmesh_assert_less (i, this->n_sides());
109 
110  std::unique_ptr<Elem> face;
111 
112  switch (i)
113  {
114  case 0: // the triangular face at z=-1, base face
115  {
116  face = std::make_unique<Tri3>();
117  break;
118  }
119 
120  case 1: // the quad face at y=0
121  case 2: // the other quad face
122  case 3: // the quad face at x=0
123  {
124  face = std::make_unique<InfQuad4>();
125  break;
126  }
127 
128  default:
129  libmesh_error_msg("Invalid side i = " << i);
130  }
131 
132  // Set the nodes
133  for (auto n : face->node_index_range())
134  face->set_node(n, this->node_ptr(InfPrism6::side_nodes_map[i][n]));
135 
136  face->set_interior_parent(this);
137  face->inherit_data_from(*this);
138 
139  return face;
140 }
141 
142 
143 void InfPrism6::build_side_ptr (std::unique_ptr<Elem> & side,
144  const unsigned int i)
145 {
146  this->side_ptr(side, i);
147  side->set_interior_parent(this);
148  side->inherit_data_from(*this);
149 }
150 
151 
152 std::unique_ptr<Elem> InfPrism6::build_edge_ptr (const unsigned int i)
153 {
154  if (i < 3)
155  return this->simple_build_edge_ptr<Edge2,InfPrism6>(i);
156 
157  // infinite edges
158  return this->simple_build_edge_ptr<InfEdge2,InfPrism6>(i);
159 }
160 
161 
162 
163 void InfPrism6::build_edge_ptr (std::unique_ptr<Elem> & edge,
164  const unsigned int i)
165 {
166  libmesh_assert_less (i, this->n_edges());
167 
168  switch (i)
169  {
170  // the base edges
171  case 0:
172  case 1:
173  case 2:
174  {
175  if (!edge.get() || edge->type() != EDGE2)
176  {
177  edge = this->build_edge_ptr(i);
178  return;
179  }
180  break;
181  }
182 
183  // the infinite edges
184  case 3:
185  case 4:
186  case 5:
187  {
188  if (!edge.get() || edge->type() != INFEDGE2)
189  {
190  edge = this->build_edge_ptr(i);
191  return;
192  }
193  break;
194  }
195 
196  default:
197  libmesh_error_msg("Invalid edge i = " << i);
198  }
199 
200  edge->inherit_data_from(*this);
201 
202  // Set the nodes
203  for (auto n : edge->node_index_range())
204  edge->set_node(n, this->node_ptr(InfPrism6::edge_nodes_map[i][n]));
205 }
206 
207 
208 
209 void InfPrism6::connectivity(const unsigned int libmesh_dbg_var(sc),
210  const IOPackage iop,
211  std::vector<dof_id_type> & conn) const
212 {
214  libmesh_assert_less (sc, this->n_sub_elem());
215  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
216 
217  switch (iop)
218  {
219  case TECPLOT:
220  {
221  conn.resize(8);
222  conn[0] = this->node_id(0)+1;
223  conn[1] = this->node_id(1)+1;
224  conn[2] = this->node_id(2)+1;
225  conn[3] = this->node_id(2)+1;
226  conn[4] = this->node_id(3)+1;
227  conn[5] = this->node_id(4)+1;
228  conn[6] = this->node_id(5)+1;
229  conn[7] = this->node_id(5)+1;
230  return;
231  }
232 
233  default:
234  libmesh_error_msg("Unsupported IO package " << iop);
235  }
236 }
237 
238 
239 
240 
241 
242 #ifdef LIBMESH_ENABLE_AMR
243 
245  {
246  // embedding matrix for child 0
247  {
248  // 0 1 2 3 4 5 th parent Node
249  { 1.0, 0.0, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
250  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 1
251  { 0.5, 0.0, 0.5, 0.0, 0.0, 0.0}, // 2
252  { 0.0, 0.0, 0.0, 1.0, 0.0, 0.0}, // 3
253  { 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 4
254  { 0.0, 0.0, 0.0, 0.5, 0.0, 0.5} // 5
255  },
256 
257  // embedding matrix for child 1
258  {
259  // 0 1 2 3 4 5 th parent Node
260  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
261  { 0.0, 1.0, 0.0, 0.0, 0.0, 0.0}, // 1
262  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0}, // 2
263  { 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 3
264  { 0.0, 0.0, 0.0, 0.0, 1.0, 0.0}, // 4
265  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5} // 5
266  },
267 
268  // embedding matrix for child 2
269  {
270  // 0 1 2 3 4 5 th parent Node
271  { 0.5, 0.0, 0.5, 0.0, 0.0, 0.0}, // 0th child N.
272  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0}, // 1
273  { 0.0, 0.0, 1.0, 0.0, 0.0, 0.0}, // 2
274  { 0.0, 0.0, 0.0, 0.5, 0.0, 0.5}, // 3
275  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 4
276  { 0.0, 0.0, 0.0, 0.0, 0.0, 1.0} // 5
277  },
278 
279  // embedding matrix for child 3
280  {
281  // 0 1 2 3 4 5 th parent Node
282  { 0.5, 0.5, 0.0, 0.0, 0.0, 0.0}, // 0th child N.
283  { 0.0, 0.5, 0.5, 0.0, 0.0, 0.0}, // 1
284  { 0.5, 0.0, 0.5, 0.0, 0.0, 0.0}, // 2
285  { 0.0, 0.0, 0.0, 0.5, 0.5, 0.0}, // 3
286  { 0.0, 0.0, 0.0, 0.0, 0.5, 0.5}, // 4
287  { 0.0, 0.0, 0.0, 0.5, 0.0, 0.5} // 5
288  }
289  };
290 
291 
292 #endif
293 
294 
295 void
296 InfPrism6::permute(unsigned int perm_num)
297 {
298  libmesh_assert_less (perm_num, 3);
299 
300  for (unsigned int i = 0; i != perm_num; ++i)
301  {
302  swap3nodes(0,1,2);
303  swap3nodes(3,4,5);
304  swap3neighbors(1,2,3);
305  }
306 }
307 
308 
309 void
311 {
312  libmesh_assert(boundary_info);
313 
314  swap2nodes(0,1);
315  swap2nodes(3,4);
316  swap2nodes(7,8);
317  swap2neighbors(2,3);
318  swap2boundarysides(2,3,boundary_info);
319  swap2boundaryedges(3,4,boundary_info);
320 }
321 
322 
323 ElemType
324 InfPrism6::side_type (const unsigned int s) const
325 {
326  libmesh_assert_less (s, 4);
327  if (s == 0)
328  return TRI3;
329  return INFQUAD4;
330 }
331 
332 } // namespace libMesh
333 
334 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
ElemType
Defines an enum for geometric element types.
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
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:2245
static const int num_edges
virtual unsigned int n_edges() const override final
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
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
virtual std::vector< unsigned int > nodes_on_edge(const unsigned int e) const override
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
The libMesh namespace provides an interface to certain functionality in the library.
static const Real _embedding_matrix[num_children][num_nodes][num_nodes]
Matrix that computes new nodal locations/solution values from current nodes/solution.
static const int num_sides
Geometric constants for all InfPrisms.
virtual unsigned int n_sub_elem() const override
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Definition: elem.h:2133
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override
void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three node_ptrs, "rotating" them.
Definition: elem.h:2124
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2092
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
static const int num_nodes
Geometric constants for InfPrism6.
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
virtual Order default_order() const override
ElemType side_type(const unsigned int s) const override final
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:2102
static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]
This maps the node of the edge to element node numbers.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
static const int nodes_per_side
static const int nodes_per_edge
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
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
virtual unsigned int n_sides() const override final
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const override