cell_pyramid5.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2018 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 // Local includes
20 #include "libmesh/side.h"
21 #include "libmesh/cell_pyramid5.h"
22 #include "libmesh/edge_edge2.h"
23 #include "libmesh/face_tri3.h"
24 #include "libmesh/face_quad4.h"
26 #include "libmesh/enum_order.h"
27 
28 namespace libMesh
29 {
30 
31 
32 
33 
34 // ------------------------------------------------------------
35 // Pyramid5 class static member initializations
36 const int Pyramid5::num_nodes;
37 const int Pyramid5::num_sides;
38 const int Pyramid5::num_edges;
39 const int Pyramid5::num_children;
40 const int Pyramid5::nodes_per_side;
41 const int Pyramid5::nodes_per_edge;
42 
44  {
45  {0, 1, 4, 99}, // Side 0
46  {1, 2, 4, 99}, // Side 1
47  {2, 3, 4, 99}, // Side 2
48  {3, 0, 4, 99}, // Side 3
49  {0, 3, 2, 1} // Side 4
50  };
51 
53  {
54  {0, 1}, // Edge 0
55  {1, 2}, // Edge 1
56  {2, 3}, // Edge 2
57  {0, 3}, // Edge 3
58  {0, 4}, // Edge 4
59  {1, 4}, // Edge 5
60  {2, 4}, // Edge 6
61  {3, 4} // Edge 7
62  };
63 
64 
65 
66 // ------------------------------------------------------------
67 // Pyramid5 class member functions
68 
69 bool Pyramid5::is_vertex(const unsigned int) const
70 {
71  return true;
72 }
73 
74 bool Pyramid5::is_edge(const unsigned int) const
75 {
76  return false;
77 }
78 
79 bool Pyramid5::is_face(const unsigned int) const
80 {
81  return false;
82 }
83 
84 bool Pyramid5::is_node_on_side(const unsigned int n,
85  const unsigned int s) const
86 {
87  libmesh_assert_less (s, n_sides());
88  return std::find(std::begin(side_nodes_map[s]),
90  n) != std::end(side_nodes_map[s]);
91 }
92 
93 std::vector<unsigned>
94 Pyramid5::nodes_on_side(const unsigned int s) const
95 {
96  libmesh_assert_less(s, n_sides());
97  auto trim = (s == 4) ? 0 : 1;
98  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
99 }
100 
101 bool Pyramid5::is_node_on_edge(const unsigned int n,
102  const unsigned int e) const
103 {
104  libmesh_assert_less (e, n_edges());
105  return std::find(std::begin(edge_nodes_map[e]),
107  n) != std::end(edge_nodes_map[e]);
108 }
109 
110 
111 
113 {
114  // Point v = this->point(3) - this->point(0);
115  // return (v.relative_fuzzy_equals(this->point(2) - this->point(1)));
116  return false;
117 }
118 
119 
120 
122 {
123  return FIRST;
124 }
125 
126 
127 
128 std::unique_ptr<Elem> Pyramid5::build_side_ptr (const unsigned int i,
129  bool proxy)
130 {
131  libmesh_assert_less (i, this->n_sides());
132 
133  if (proxy)
134  {
135  switch (i)
136  {
137  case 0:
138  case 1:
139  case 2:
140  case 3:
141  return libmesh_make_unique<Side<Tri3,Pyramid5>>(this,i);
142 
143  case 4:
144  return libmesh_make_unique<Side<Quad4,Pyramid5>>(this,i);
145 
146  default:
147  libmesh_error_msg("Invalid side i = " << i);
148  }
149  }
150 
151  else
152  {
153  // Return value
154  std::unique_ptr<Elem> face;
155 
156  switch (i)
157  {
158  case 0: // triangular face 1
159  case 1: // triangular face 2
160  case 2: // triangular face 3
161  case 3: // triangular face 4
162  {
163  face = libmesh_make_unique<Tri3>();
164  break;
165  }
166  case 4: // the quad face at z=0
167  {
168  face = libmesh_make_unique<Quad4>();
169  break;
170  }
171  default:
172  libmesh_error_msg("Invalid side i = " << i);
173  }
174 
175  face->subdomain_id() = this->subdomain_id();
176 
177  // Set the nodes
178  for (unsigned n=0; n<face->n_nodes(); ++n)
179  face->set_node(n) = this->node_ptr(Pyramid5::side_nodes_map[i][n]);
180 
181  return face;
182  }
183 }
184 
185 
186 
187 void Pyramid5::build_side_ptr (std::unique_ptr<Elem> & side,
188  const unsigned int i)
189 {
190  this->side_ptr(side, i);
191 }
192 
193 
194 
195 std::unique_ptr<Elem> Pyramid5::build_edge_ptr (const unsigned int i)
196 {
197  libmesh_assert_less (i, this->n_edges());
198 
199  return libmesh_make_unique<SideEdge<Edge2,Pyramid5>>(this,i);
200 }
201 
202 
203 
204 void Pyramid5::connectivity(const unsigned int libmesh_dbg_var(sc),
205  const IOPackage iop,
206  std::vector<dof_id_type> & conn) const
207 {
208  libmesh_assert(_nodes);
209  libmesh_assert_less (sc, this->n_sub_elem());
210  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
211 
212  switch (iop)
213  {
214  case TECPLOT:
215  {
216  conn.resize(8);
217  conn[0] = this->node_id(0)+1;
218  conn[1] = this->node_id(1)+1;
219  conn[2] = this->node_id(2)+1;
220  conn[3] = this->node_id(3)+1;
221  conn[4] = this->node_id(4)+1;
222  conn[5] = this->node_id(4)+1;
223  conn[6] = this->node_id(4)+1;
224  conn[7] = this->node_id(4)+1;
225  return;
226  }
227 
228  case VTK:
229  {
230  conn.resize(5);
231  conn[0] = this->node_id(3);
232  conn[1] = this->node_id(2);
233  conn[2] = this->node_id(1);
234  conn[3] = this->node_id(0);
235  conn[4] = this->node_id(4);
236  return;
237  }
238 
239  default:
240  libmesh_error_msg("Unsupported IO package " << iop);
241  }
242 }
243 
244 
246 {
247  // The pyramid with a bilinear base has volume given by the
248  // formula in: "Calculation of the Volume of a General Hexahedron
249  // for Flow Predictions", AIAA Journal v.23, no.6, 1984, p.954-
250  Point
251  x0 = point(0), x1 = point(1), x2 = point(2),
252  x3 = point(3), x4 = point(4);
253 
254  // Construct various edge and diagonal vectors.
255  Point v40 = x0 - x4;
256  Point v13 = x3 - x1;
257  Point v02 = x2 - x0;
258  Point v03 = x3 - x0;
259  Point v01 = x1 - x0;
260 
261  // Finally, ready to return the volume!
262  return
263  triple_product(v40, v13, v02) / 6. +
264  triple_product(v02, v01, v03) / 12.;
265 }
266 
269 {
270  return Elem::loose_bounding_box();
271 }
272 
273 } // namespace libMesh
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy) override
Node ** _nodes
Definition: elem.h:1695
virtual bool is_face(const unsigned int i) const override
Definition: cell_pyramid5.C:79
virtual BoundingBox loose_bounding_box() const override
static const int nodes_per_edge
static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]
unsigned short int side
Definition: xdr_io.C:50
virtual BoundingBox loose_bounding_box() const
Definition: elem.C:2857
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: cell_pyramid5.C:84
virtual Real volume() const override
virtual unsigned int n_sides() const override
Definition: cell_pyramid.h:83
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const override
virtual bool has_affine_map() const override
IterBase * end
virtual bool is_edge(const unsigned int i) const override
Definition: cell_pyramid5.C:74
static const int num_children
static const int num_nodes
virtual std::unique_ptr< Elem > side_ptr(const unsigned int i) override
Definition: cell_pyramid.C:100
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: cell_pyramid5.C:94
T triple_product(const TypeVector< T > &a, const TypeVector< T > &b, const TypeVector< T > &c)
Definition: type_vector.h:1054
static const int nodes_per_side
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
subdomain_id_type subdomain_id() const
Definition: elem.h:2034
virtual unsigned int n_edges() const override
Definition: cell_pyramid.h:93
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1957
virtual bool is_vertex(const unsigned int i) const override
Definition: cell_pyramid5.C:69
static const unsigned int side_nodes_map[num_sides][nodes_per_side]
virtual unsigned int n_sub_elem() const override
Definition: cell_pyramid5.h:78
A geometric point in (x,y,z) space.
Definition: point.h:38
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:1914
const Point & point(const unsigned int i) const
Definition: elem.h:1892
virtual Order default_order() const override
static const int num_sides
static const int num_edges