libMesh
cell_prism.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2019 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 // C++ includes
20 
21 // Local includes
22 #include "libmesh/cell_prism.h"
23 #include "libmesh/cell_prism6.h"
24 #include "libmesh/face_quad4.h"
25 #include "libmesh/face_tri3.h"
26 
27 namespace libMesh
28 {
29 
30 
31 // ------------------------------------------------------------
32 // Prism class static member initializations
33 
34 
35 // We need to require C++11...
36 const Real Prism::_master_points[18][3] =
37  {
38  {0, 0, -1},
39  {1, 0, -1},
40  {0, 1, -1},
41  {0, 0, 1},
42  {1, 0, 1},
43  {0, 1, 1},
44  {0.5, 0, -1},
45  {0.5, 0.5, -1},
46  {0, 0.5, -1},
47  {0, 0, 0},
48  {1, 0, 0},
49  {0, 1, 0},
50  {0.5, 0, 1},
51  {0.5, 0.5, 1},
52  {0, 0.5, 1},
53  {0.5, 0, 0},
54  {0.5, 0.5, 0},
55  {0, 0.5, 0}
56  };
57 
58 
59 
60 
61 // ------------------------------------------------------------
62 // Prism class member functions
63 dof_id_type Prism::key (const unsigned int s) const
64 {
65  libmesh_assert_less (s, this->n_sides());
66 
67  switch (s)
68  {
69  case 0: // the triangular face at z=0
70  case 4: // the triangular face at z=1
71  return this->compute_key (this->node_id(Prism6::side_nodes_map[s][0]),
72  this->node_id(Prism6::side_nodes_map[s][1]),
73  this->node_id(Prism6::side_nodes_map[s][2]));
74 
75  case 1: // the quad face at y=0
76  case 2: // the other quad face
77  case 3: // the quad face at x=0
78  return this->compute_key (this->node_id(Prism6::side_nodes_map[s][0]),
79  this->node_id(Prism6::side_nodes_map[s][1]),
80  this->node_id(Prism6::side_nodes_map[s][2]),
81  this->node_id(Prism6::side_nodes_map[s][3]));
82 
83  default:
84  libmesh_error_msg("Invalid side " << s);
85  }
86 }
87 
88 
89 
90 unsigned int Prism::which_node_am_i(unsigned int side,
91  unsigned int side_node) const
92 {
93  libmesh_assert_less (side, this->n_sides());
94 
95  // Never more than 4 nodes per side.
96  libmesh_assert_less(side_node, 4);
97 
98  // Some sides have 3 nodes.
99  libmesh_assert(!(side==0 || side==4) || side_node < 3);
100 
101  return Prism6::side_nodes_map[side][side_node];
102 }
103 
104 
105 
106 std::unique_ptr<Elem> Prism::side_ptr (const unsigned int i)
107 {
108  libmesh_assert_less (i, this->n_sides());
109 
110  std::unique_ptr<Elem> face;
111 
112  // Set up the type of element
113  switch (i)
114  {
115  case 0: // the triangular face at z=0
116  case 4: // the triangular face at z=1
117  {
118  face = libmesh_make_unique<Tri3>();
119  break;
120  }
121  case 1: // the quad face at y=0
122  case 2: // the other quad face
123  case 3: // the quad face at x=0
124  {
125  face = libmesh_make_unique<Quad4>();
126  break;
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(Prism6::side_nodes_map[i][n]);
135 
136  return face;
137 }
138 
139 
140 
141 void Prism::side_ptr (std::unique_ptr<Elem> & side,
142  const unsigned int i)
143 {
144  libmesh_assert_less (i, this->n_sides());
145 
146  switch (i)
147  {
148  // the base face
149  case 0: // the triangular face at z=0
150  case 4: // the triangular face at z=1
151  {
152  if (!side.get() || side->type() != TRI3)
153  {
154  side = this->side_ptr(i);
155  return;
156  }
157  break;
158  }
159 
160  case 1: // the quad face at y=0
161  case 2: // the other quad face
162  case 3: // the quad face at x=0
163  {
164  if (!side.get() || side->type() != QUAD4)
165  {
166  side = this->side_ptr(i);
167  return;
168  }
169  break;
170  }
171 
172  default:
173  libmesh_error_msg("Invalid side i = " << i);
174  }
175 
176  side->subdomain_id() = this->subdomain_id();
177 
178  // Set the nodes
179  for (auto n : side->node_index_range())
180  side->set_node(n) = this->node_ptr(Prism6::side_nodes_map[i][n]);
181 }
182 
183 
184 
185 bool Prism::is_child_on_side(const unsigned int c,
186  const unsigned int s) const
187 {
188  libmesh_assert_less (c, this->n_children());
189  libmesh_assert_less (s, this->n_sides());
190 
191  for (unsigned int i = 0; i != 4; ++i)
192  if (Prism6::side_elems_map[s][i] == c)
193  return true;
194  return false;
195 }
196 
197 
198 
199 bool Prism::is_edge_on_side(const unsigned int e,
200  const unsigned int s) const
201 {
202  libmesh_assert_less (e, this->n_edges());
203  libmesh_assert_less (s, this->n_sides());
204 
205  return (is_node_on_side(Prism6::edge_nodes_map[e][0],s) &&
207 }
208 
209 
210 
211 const unsigned short int Prism::_second_order_vertex_child_number[18] =
212  {
213  99,99,99,99,99,99, // Vertices
214  0,1,0,0,1,2,3,4,3, // Edges
215  0,1,0 // Faces
216  };
217 
218 
219 
220 const unsigned short int Prism::_second_order_vertex_child_index[18] =
221  {
222  99,99,99,99,99,99, // Vertices
223  1,2,2,3,4,5,4,5,5, // Edges
224  4,5,5 // Faces
225  };
226 
227 
228 const unsigned short int Prism::_second_order_adjacent_vertices[9][2] =
229  {
230  { 0, 1}, // vertices adjacent to node 6
231  { 1, 2}, // vertices adjacent to node 7
232  { 0, 2}, // vertices adjacent to node 8
233 
234  { 0, 3}, // vertices adjacent to node 9
235  { 1, 4}, // vertices adjacent to node 10
236  { 2, 5}, // vertices adjacent to node 11
237 
238  { 3, 4}, // vertices adjacent to node 12
239  { 4, 5}, // vertices adjacent to node 13
240  { 3, 5} // vertices adjacent to node 14
241  };
242 
243 } // namespace libMesh
libMesh::dof_id_type
uint8_t dof_id_type
Definition: id_types.h:67
libMesh::Elem::is_node_on_side
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
libMesh::Elem::compute_key
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:2683
libMesh::Prism6::side_nodes_map
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
This maps the node of the side to element node numbers.
Definition: cell_prism6.h:159
libMesh::Prism::_second_order_vertex_child_index
static const unsigned short int _second_order_vertex_child_index[18]
Vector that names the child vertex index for each second order node.
Definition: cell_prism.h:164
libMesh
The libMesh namespace provides an interface to certain functionality in the library.
Definition: factoryfunction.C:55
libMesh::Prism::n_edges
virtual unsigned int n_edges() const override final
Definition: cell_prism.h:89
libMesh::Prism::_second_order_vertex_child_number
static const unsigned short int _second_order_vertex_child_number[18]
Vector that names a child sharing each second order node.
Definition: cell_prism.h:159
libMesh::Prism::is_edge_on_side
virtual bool is_edge_on_side(const unsigned int e, const unsigned int s) const override final
Definition: cell_prism.C:199
libMesh::libmesh_assert
libmesh_assert(ctx)
libMesh::QUAD4
Definition: enum_elem_type.h:41
libMesh::Prism6::edge_nodes_map
static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]
This maps the node of the edge to element node numbers.
Definition: cell_prism6.h:170
libMesh::Elem::key
virtual dof_id_type key() const
Definition: elem.C:410
libMesh::TRI3
Definition: enum_elem_type.h:39
libMesh::Prism::which_node_am_i
virtual unsigned int which_node_am_i(unsigned int side, unsigned int side_node) const override
Definition: cell_prism.C:90
libMesh::Prism::n_sides
virtual unsigned int n_sides() const override final
Definition: cell_prism.h:79
libMesh::Prism::_second_order_adjacent_vertices
static const unsigned short int _second_order_adjacent_vertices[9][2]
Matrix that tells which vertices define the location of mid-side (or second-order) nodes.
Definition: cell_prism.h:154
libMesh::Elem::subdomain_id
subdomain_id_type subdomain_id() const
Definition: elem.h:2069
libMesh::Prism::n_children
virtual unsigned int n_children() const override final
Definition: cell_prism.h:99
libMesh::Prism::side_ptr
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override final
Definition: cell_prism.C:106
libMesh::Prism::is_child_on_side
virtual bool is_child_on_side(const unsigned int c, const unsigned int s) const override final
Definition: cell_prism.C:185
libMesh::Elem::node_id
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1977
libMesh::Real
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Definition: libmesh_common.h:121
libMesh::Prism6::side_elems_map
static const unsigned int side_elems_map[num_sides][nodes_per_side]
This maps the child elements with the associated side of the parent element.
Definition: cell_prism6.h:164
libMesh::Elem::node_ptr
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:2009
libMesh::Prism::_master_points
static const Real _master_points[18][3]
Master element node locations.
Definition: cell_prism.h:169