libMesh
cell_prism20.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 
19 // Local includes
20 #include "libmesh/cell_prism20.h"
21 #include "libmesh/edge_edge3.h"
22 #include "libmesh/face_quad9.h"
23 #include "libmesh/face_tri7.h"
24 #include "libmesh/enum_io_package.h"
25 #include "libmesh/enum_order.h"
26 #include "libmesh/int_range.h"
27 
28 namespace libMesh
29 {
30 
31 
32 
33 // ------------------------------------------------------------
34 // Prism20 class static member initializations
35 const int Prism20::num_nodes;
36 const int Prism20::nodes_per_side;
37 const int Prism20::nodes_per_edge;
38 
40  {
41  {0, 2, 1, 8, 7, 6, 18, 99, 99}, // Side 0
42  {0, 1, 4, 3, 6, 10, 12, 9, 15}, // Side 1
43  {1, 2, 5, 4, 7, 11, 13, 10, 16}, // Side 2
44  {2, 0, 3, 5, 8, 9, 14, 11, 17}, // Side 3
45  {3, 4, 5, 12, 13, 14, 19, 99, 99} // Side 4
46  };
47 
49  {
50  {0, 1, 6}, // Edge 0
51  {1, 2, 7}, // Edge 1
52  {0, 2, 8}, // Edge 2
53  {0, 3, 9}, // Edge 3
54  {1, 4, 10}, // Edge 4
55  {2, 5, 11}, // Edge 5
56  {3, 4, 12}, // Edge 6
57  {4, 5, 13}, // Edge 7
58  {3, 5, 14} // Edge 8
59  };
60 
61 // ------------------------------------------------------------
62 // Prism20 class member functions
63 
64 bool Prism20::is_vertex(const unsigned int i) const
65 {
66  if (i < 6)
67  return true;
68  return false;
69 }
70 
71 bool Prism20::is_edge(const unsigned int i) const
72 {
73  if (i < 6)
74  return false;
75  if (i > 14)
76  return false;
77  return true;
78 }
79 
80 bool Prism20::is_face(const unsigned int i) const
81 {
82  if (i > 14)
83  return true;
84  return false;
85 }
86 
87 bool Prism20::is_node_on_side(const unsigned int n,
88  const unsigned int s) const
89 {
90  libmesh_assert_less (s, n_sides());
91  return std::find(std::begin(side_nodes_map[s]),
92  std::end(side_nodes_map[s]),
93  n) != std::end(side_nodes_map[s]);
94 }
95 
96 std::vector<unsigned>
97 Prism20::nodes_on_side(const unsigned int s) const
98 {
99  libmesh_assert_less(s, n_sides());
100  auto trim = (s > 0 && s < 4) ? 0 : 2;
101  return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
102 }
103 
104 std::vector<unsigned>
105 Prism20::nodes_on_edge(const unsigned int e) const
106 {
107  libmesh_assert_less(e, n_edges());
108  return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
109 }
110 
111 bool Prism20::is_node_on_edge(const unsigned int n,
112  const unsigned int e) const
113 {
114  libmesh_assert_less (e, n_edges());
115  return std::find(std::begin(edge_nodes_map[e]),
116  std::end(edge_nodes_map[e]),
117  n) != std::end(edge_nodes_map[e]);
118 }
119 
120 
121 
123 {
124  // Make sure z edges are affine
125  Point v = this->point(3) - this->point(0);
126  if (!v.relative_fuzzy_equals(this->point(4) - this->point(1), affine_tol) ||
127  !v.relative_fuzzy_equals(this->point(5) - this->point(2), affine_tol))
128  return false;
129 
130  // Make sure edges are straight
131  v /= 2;
132  if (!v.relative_fuzzy_equals(this->point(9) - this->point(0), affine_tol) ||
133  !v.relative_fuzzy_equals(this->point(10) - this->point(1), affine_tol) ||
134  !v.relative_fuzzy_equals(this->point(11) - this->point(2), affine_tol) ||
135  !v.relative_fuzzy_equals(this->point(15) - this->point(6), affine_tol) ||
136  !v.relative_fuzzy_equals(this->point(16) - this->point(7), affine_tol) ||
137  !v.relative_fuzzy_equals(this->point(17) - this->point(8), affine_tol))
138  return false;
139  v = (this->point(1) - this->point(0))/2;
140  if (!v.relative_fuzzy_equals(this->point(6) - this->point(0), affine_tol) ||
141  !v.relative_fuzzy_equals(this->point(12) - this->point(3), affine_tol))
142  return false;
143  v = (this->point(2) - this->point(0))/2;
144  if (!v.relative_fuzzy_equals(this->point(8) - this->point(0), affine_tol) ||
145  !v.relative_fuzzy_equals(this->point(14) - this->point(3), affine_tol))
146  return false;
147  v = (this->point(2) - this->point(1))/2;
148  if (!v.relative_fuzzy_equals(this->point(7) - this->point(1), affine_tol) ||
149  !v.relative_fuzzy_equals(this->point(13) - this->point(4), affine_tol))
150  return false;
151 
152  // Make sure triangle face midpoints are centered
153  v = this->point(2) + this->point(1) - 2*this->point(0);
154  if (!v.relative_fuzzy_equals((this->point(18)-this->point(0))*3))
155  return false;
156  v = this->point(5) + this->point(4) - 2*this->point(3);
157  if (!v.relative_fuzzy_equals((this->point(19)-this->point(3))*3))
158  return false;
159 
160  return true;
161 }
162 
163 
164 
166 {
167  return THIRD;
168 }
169 
170 dof_id_type Prism20::key (const unsigned int s) const
171 {
172  libmesh_assert_less (s, this->n_sides());
173 
174  switch (s)
175  {
176  case 0: // the triangular face at z=0
177  {
178  return Elem::compute_key (this->node_id(18));
179  }
180  case 1: // the quad face at y=0
181  {
182  return Elem::compute_key (this->node_id(15));
183  }
184  case 2: // the other quad face
185  {
186  return Elem::compute_key (this->node_id(16));
187  }
188  case 3: // the quad face at x=0
189  {
190  return Elem::compute_key (this->node_id(17));
191  }
192  case 4: // the triangular face at z=1
193  {
194  return Elem::compute_key (this->node_id(19));
195  }
196  default:
197  libmesh_error_msg("Invalid side " << s);
198  }
199 }
200 
201 
202 
203 unsigned int Prism20::local_side_node(unsigned int side,
204  unsigned int side_node) const
205 {
206  libmesh_assert_less (side, this->n_sides());
207 
208  // Never more than 9 nodes per side.
209  libmesh_assert_less(side_node, Prism20::nodes_per_side);
210 
211  // Some sides have 7 nodes.
212  libmesh_assert(!(side==0 || side==4) || side_node < 7);
213 
214  return Prism20::side_nodes_map[side][side_node];
215 }
216 
217 
218 
219 unsigned int Prism20::local_edge_node(unsigned int edge,
220  unsigned int edge_node) const
221 {
222  libmesh_assert_less(edge, this->n_edges());
223  libmesh_assert_less(edge_node, Prism20::nodes_per_edge);
224 
225  return Prism20::edge_nodes_map[edge][edge_node];
226 }
227 
228 
229 
230 std::unique_ptr<Elem> Prism20::build_side_ptr (const unsigned int i)
231 {
232  libmesh_assert_less (i, this->n_sides());
233 
234  std::unique_ptr<Elem> face;
235 
236  switch (i)
237  {
238  case 0: // the triangular face at z=-1
239  case 4: // the triangular face at z=1
240  {
241  face = std::make_unique<Tri7>();
242  break;
243  }
244  case 1: // the quad face at y=0
245  case 2: // the other quad face
246  case 3: // the quad face at x=0
247  {
248  face = std::make_unique<Quad9>();
249  break;
250  }
251  default:
252  libmesh_error_msg("Invalid side i = " << i);
253  }
254 
255  // Set the nodes
256  for (auto n : face->node_index_range())
257  face->set_node(n, this->node_ptr(Prism20::side_nodes_map[i][n]));
258 
259  face->set_interior_parent(this);
260  face->inherit_data_from(*this);
261 
262  return face;
263 }
264 
265 
266 
267 void Prism20::build_side_ptr (std::unique_ptr<Elem> & side,
268  const unsigned int i)
269 {
270  libmesh_assert_less (i, this->n_sides());
271 
272  switch (i)
273  {
274  case 0: // the triangular face at z=-1
275  case 4: // the triangular face at z=1
276  {
277  if (!side.get() || side->type() != TRI7)
278  {
279  side = this->build_side_ptr(i);
280  return;
281  }
282  break;
283  }
284 
285  case 1: // the quad face at y=0
286  case 2: // the other quad face
287  case 3: // the quad face at x=0
288  {
289  if (!side.get() || side->type() != QUAD9)
290  {
291  side = this->build_side_ptr(i);
292  return;
293  }
294  break;
295  }
296 
297  default:
298  libmesh_error_msg("Invalid side i = " << i);
299  }
300 
301  side->inherit_data_from(*this);
302 
303  // Set the nodes
304  for (auto n : side->node_index_range())
305  side->set_node(n, this->node_ptr(Prism20::side_nodes_map[i][n]));
306 }
307 
308 
309 
310 std::unique_ptr<Elem> Prism20::build_edge_ptr (const unsigned int i)
311 {
312  return this->simple_build_edge_ptr<Edge3,Prism20>(i);
313 }
314 
315 
316 
317 void Prism20::build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i)
318 {
319  this->simple_build_edge_ptr<Prism20>(edge, i, EDGE3);
320 }
321 
322 
323 
324 void Prism20::connectivity(const unsigned int /*sc*/,
325  const IOPackage /*iop*/,
326  std::vector<dof_id_type> & /*conn*/) const
327 {
328  libmesh_not_implemented(); // FIXME RHS
329 
330 /*
331  libmesh_assert(_nodes);
332  libmesh_assert_less (sc, this->n_sub_elem());
333  libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
334 
335  switch (iop)
336  {
337  case TECPLOT:
338  {
339  conn.resize(8);
340  switch (sc)
341  {
342 
343  case 0:
344  {
345  conn[0] = this->node_id(0)+1;
346  conn[1] = this->node_id(6)+1;
347  conn[2] = this->node_id(8)+1;
348  conn[3] = this->node_id(8)+1;
349  conn[4] = this->node_id(9)+1;
350  conn[5] = this->node_id(15)+1;
351  conn[6] = this->node_id(17)+1;
352  conn[7] = this->node_id(17)+1;
353 
354  return;
355  }
356 
357  case 1:
358  {
359  conn[0] = this->node_id(6)+1;
360  conn[1] = this->node_id(1)+1;
361  conn[2] = this->node_id(7)+1;
362  conn[3] = this->node_id(7)+1;
363  conn[4] = this->node_id(15)+1;
364  conn[5] = this->node_id(10)+1;
365  conn[6] = this->node_id(16)+1;
366  conn[7] = this->node_id(16)+1;
367 
368  return;
369  }
370 
371  case 2:
372  {
373  conn[0] = this->node_id(8)+1;
374  conn[1] = this->node_id(7)+1;
375  conn[2] = this->node_id(2)+1;
376  conn[3] = this->node_id(2)+1;
377  conn[4] = this->node_id(17)+1;
378  conn[5] = this->node_id(16)+1;
379  conn[6] = this->node_id(11)+1;
380  conn[7] = this->node_id(11)+1;
381 
382  return;
383  }
384 
385  case 3:
386  {
387  conn[0] = this->node_id(6)+1;
388  conn[1] = this->node_id(7)+1;
389  conn[2] = this->node_id(8)+1;
390  conn[3] = this->node_id(8)+1;
391  conn[4] = this->node_id(15)+1;
392  conn[5] = this->node_id(16)+1;
393  conn[6] = this->node_id(17)+1;
394  conn[7] = this->node_id(17)+1;
395 
396  return;
397  }
398 
399  case 4:
400  {
401  conn[0] = this->node_id(9)+1;
402  conn[1] = this->node_id(15)+1;
403  conn[2] = this->node_id(17)+1;
404  conn[3] = this->node_id(17)+1;
405  conn[4] = this->node_id(3)+1;
406  conn[5] = this->node_id(12)+1;
407  conn[6] = this->node_id(14)+1;
408  conn[7] = this->node_id(14)+1;
409 
410  return;
411  }
412 
413  case 5:
414  {
415  conn[0] = this->node_id(15)+1;
416  conn[1] = this->node_id(10)+1;
417  conn[2] = this->node_id(16)+1;
418  conn[3] = this->node_id(16)+1;
419  conn[4] = this->node_id(12)+1;
420  conn[5] = this->node_id(4)+1;
421  conn[6] = this->node_id(13)+1;
422  conn[7] = this->node_id(13)+1;
423 
424  return;
425  }
426 
427  case 6:
428  {
429  conn[0] = this->node_id(17)+1;
430  conn[1] = this->node_id(16)+1;
431  conn[2] = this->node_id(11)+1;
432  conn[3] = this->node_id(11)+1;
433  conn[4] = this->node_id(14)+1;
434  conn[5] = this->node_id(13)+1;
435  conn[6] = this->node_id(5)+1;
436  conn[7] = this->node_id(5)+1;
437 
438  return;
439  }
440 
441  case 7:
442  {
443  conn[0] = this->node_id(15)+1;
444  conn[1] = this->node_id(16)+1;
445  conn[2] = this->node_id(17)+1;
446  conn[3] = this->node_id(17)+1;
447  conn[4] = this->node_id(12)+1;
448  conn[5] = this->node_id(13)+1;
449  conn[6] = this->node_id(14)+1;
450  conn[7] = this->node_id(14)+1;
451 
452  return;
453  }
454 
455  default:
456  libmesh_error_msg("Invalid sc = " << sc);
457  }
458 
459  }
460 
461  case VTK:
462  {
463  // VTK now supports VTK_BIQUADRATIC_QUADRATIC_WEDGE directly
464  const unsigned int conn_size = 18;
465  conn.resize(conn_size);
466 
467  // VTK's VTK_BIQUADRATIC_QUADRATIC_WEDGE first 9 (vertex) and
468  // last 3 (mid-face) nodes match. The middle and top layers
469  // of mid-edge nodes are reversed from LibMesh's.
470  for (auto i : index_range(conn))
471  conn[i] = this->node_id(i);
472 
473  // top "ring" of mid-edge nodes
474  conn[9] = this->node_id(12);
475  conn[10] = this->node_id(13);
476  conn[11] = this->node_id(14);
477 
478  // middle "ring" of mid-edge nodes
479  conn[12] = this->node_id(9);
480  conn[13] = this->node_id(10);
481  conn[14] = this->node_id(11);
482 
483  return;
484  }
485 
486  default:
487  libmesh_error_msg("Unsupported IO package " << iop);
488  }
489 */
490 }
491 
492 
493 
494 
495 unsigned int Prism20::n_second_order_adjacent_vertices (const unsigned int n) const
496 {
497  switch (n)
498  {
499  case 6:
500  case 7:
501  case 8:
502  case 9:
503  case 10:
504  case 11:
505  case 12:
506  case 13:
507  case 14:
508  return 2;
509 
510  case 15:
511  case 16:
512  case 17:
513  return 4;
514 
515  case 18:
516  case 19:
517  return 3;
518 
519  default:
520  libmesh_error_msg("Invalid node n = " << n);
521  }
522 }
523 
524 
525 
526 
527 
528 unsigned short int Prism20::second_order_adjacent_vertex (const unsigned int n,
529  const unsigned int v) const
530 {
531  libmesh_assert_greater_equal (n, this->n_vertices());
532  libmesh_assert_less (n, this->n_nodes());
533 
534  switch (n)
535  {
536  /*
537  * These nodes are unique to \p Prism20,
538  * let our _remaining_... matrix handle
539  * this.
540  */
541  case 15:
542  case 16:
543  case 17:
544  case 18:
545  case 19:
546  {
547  libmesh_assert_less (v, 4);
549  }
550 
551  /*
552  * All other second-order nodes (6,...,14) are
553  * identical with Prism15 and are therefore
554  * delegated to the _second_order matrix of
555  * \p Prism
556  */
557  default:
558  {
559  libmesh_assert_less (v, 2);
560  return _second_order_adjacent_vertices[n-this->n_vertices()][v];
561  }
562 
563  }
564 
565  return static_cast<unsigned short int>(-1);
566 }
567 
568 
569 
570 const unsigned short int Prism20::_remaining_second_order_adjacent_vertices[5][4] =
571  {
572  { 0, 1, 3, 4}, // vertices adjacent to node 15
573  { 1, 2, 4, 5}, // vertices adjacent to node 16
574  { 0, 2, 3, 5}, // vertices adjacent to node 17
575  { 0, 1, 2, 99}, // vertices adjacent to node 18
576  { 3, 4, 5, 99} // vertices adjacent to node 19
577  };
578 
579 
580 
581 std::pair<unsigned short int, unsigned short int>
582 Prism20::second_order_child_vertex (const unsigned int n) const
583 {
584  libmesh_assert_greater_equal (n, this->n_vertices());
585  libmesh_assert_less (n, this->n_nodes());
586 
587  return std::pair<unsigned short int, unsigned short int>
590 }
591 
592 
593 
594 void
595 Prism20::permute(unsigned int perm_num)
596 {
597  libmesh_assert_less (perm_num, 6);
598  const unsigned int side = perm_num % 2;
599  const unsigned int rotate = perm_num / 2;
600 
601  for (unsigned int i = 0; i != rotate; ++i)
602  {
603  swap3nodes(0,1,2);
604  swap3nodes(3,4,5);
605  swap3nodes(6,7,8);
606  swap3nodes(9,10,11);
607  swap3nodes(12,13,14);
608  swap3nodes(15,16,17);
609  swap3neighbors(1,2,3);
610  }
611 
612  switch (side) {
613  case 0:
614  break;
615  case 1:
616  swap2nodes(1,3);
617  swap2nodes(0,4);
618  swap2nodes(2,5);
619  swap2nodes(6,12);
620  swap2nodes(9,10);
621  swap2nodes(7,14);
622  swap2nodes(8,13);
623  swap2nodes(16,17);
624  swap2nodes(18,19);
625  swap2neighbors(0,4);
626  swap2neighbors(2,3);
627  break;
628  default:
629  libmesh_error();
630  }
631 }
632 
633 
634 void
635 Prism20::flip(BoundaryInfo * boundary_info)
636 {
637  libmesh_assert(boundary_info);
638 
639  swap2nodes(0,1);
640  swap2nodes(3,4);
641  swap2nodes(7,8);
642  swap2nodes(9,10);
643  swap2nodes(13,14);
644  swap2nodes(16,17);
645  swap2neighbors(2,3);
646  swap2boundarysides(2,3,boundary_info);
647  swap2boundaryedges(0,1,boundary_info);
648  swap2boundaryedges(3,4,boundary_info);
649  swap2boundaryedges(7,8,boundary_info);
650 }
651 
652 
653 unsigned int Prism20::center_node_on_side(const unsigned short side) const
654 {
655  libmesh_assert_less (side, Prism20::num_sides);
656  if (side >= 1 && side <= 3)
657  return side + 14;
658  if (side == 4)
659  return 19;
660  return 18;
661 }
662 
663 
664 ElemType
665 Prism20::side_type (const unsigned int s) const
666 {
667  libmesh_assert_less (s, 5);
668  if (s == 0 || s == 4)
669  return TRI7;
670  return QUAD9;
671 }
672 
673 
674 } // namespace libMesh
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
virtual unsigned int n_second_order_adjacent_vertices(const unsigned int) const override
Definition: cell_prism20.C:495
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
static const int num_edges
Definition: cell_prism.h:74
virtual void flip(BoundaryInfo *) override final
Flips the element (by swapping node and neighbor pointers) to have a mapping Jacobian of opposite sig...
Definition: cell_prism20.C:635
virtual dof_id_type key() const
Definition: elem.C:753
virtual unsigned int n_sides() const override final
Definition: cell_prism.h:86
virtual std::pair< unsigned short int, unsigned short int > second_order_child_vertex(const unsigned int n) const override
Definition: cell_prism20.C:582
static const int num_nodes
Geometric constants for Prism20.
Definition: cell_prism20.h:240
IOPackage
libMesh interfaces with several different software packages for the purposes of creating, reading, and writing mesh files.
virtual void permute(unsigned int perm_num) override final
Permutes the element (by swapping node and neighbor pointers) according to the specified index...
Definition: cell_prism20.C:595
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
Definition: cell_prism20.C:105
virtual bool is_vertex(const unsigned int i) const override
Definition: cell_prism20.C:64
The libMesh namespace provides an interface to certain functionality in the library.
ElemType side_type(const unsigned int s) const override final
Definition: cell_prism20.C:665
virtual unsigned short int second_order_adjacent_vertex(const unsigned int n, const unsigned int v) const override
Definition: cell_prism20.C:528
virtual bool is_node_on_edge(const unsigned int n, const unsigned int e) const override
Definition: cell_prism20.C:111
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:199
void swap3neighbors(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three neighbor_ptrs, "rotating" them.
Definition: elem.h:2133
static const int nodes_per_side
Definition: cell_prism20.h:241
void swap3nodes(unsigned int n1, unsigned int n2, unsigned int n3)
Swaps three node_ptrs, "rotating" them.
Definition: elem.h:2124
virtual Order default_order() const override
Definition: cell_prism20.C:165
virtual unsigned int local_edge_node(unsigned int edge, unsigned int edge_node) const override
Definition: cell_prism20.C:219
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i) override
Builds a QUAD9 or TRI6 built coincident with face i.
Definition: cell_prism20.C:230
void swap2nodes(unsigned int n1, unsigned int n2)
Swaps two node_ptrs.
Definition: elem.h:2092
virtual std::vector< unsigned int > nodes_on_side(const unsigned int s) const override
Definition: cell_prism20.C:97
static const int nodes_per_edge
Definition: cell_prism20.h:242
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:209
virtual unsigned int n_nodes() const override
Definition: cell_prism20.h:105
The BoundaryInfo class contains information relevant to boundary conditions including storing faces...
Definition: boundary_info.h:57
libmesh_assert(ctx)
static constexpr Real affine_tol
Default tolerance to use in has_affine_map().
Definition: elem.h:2061
virtual void connectivity(const unsigned int sc, const IOPackage iop, std::vector< dof_id_type > &conn) const override
Definition: cell_prism20.C:324
virtual unsigned int n_vertices() const override final
Definition: cell_prism.h:91
RealTensorValue rotate(MeshBase &mesh, const Real phi, const Real theta=0., const Real psi=0.)
Rotates the mesh in the xy plane.
virtual bool is_edge(const unsigned int i) const override
Definition: cell_prism20.C:71
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:204
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const override
Definition: cell_prism20.C:87
void swap2neighbors(unsigned int n1, unsigned int n2)
Swaps two neighbor_ptrs.
Definition: elem.h:2102
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i) override
Builds a EDGE3 or INFEDGE2 built coincident with edge i.
Definition: cell_prism20.C:310
virtual bool has_affine_map() const override
Definition: cell_prism20.C:122
virtual unsigned int n_edges() const override final
Definition: cell_prism.h:96
static const int num_sides
Geometric constants for all Prisms.
Definition: cell_prism.h:73
static const unsigned short int _remaining_second_order_adjacent_vertices[5][4]
Matrix that tells which vertices define the location of mid-side (or second-order) nodes...
Definition: cell_prism20.h:314
virtual bool is_face(const unsigned int i) const override
Definition: cell_prism20.C:80
unsigned int center_node_on_side(const unsigned short side) const override final
Definition: cell_prism20.C:653
static dof_id_type compute_key(dof_id_type n0)
Definition: elem.h:3294
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_prism20.h:248
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_prism20.h:254
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
dof_id_type node_id(const unsigned int i) const
Definition: elem.h:2475
const Point & point(const unsigned int i) const
Definition: elem.h:2453
bool relative_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
Definition: type_vector.h:981
uint8_t dof_id_type
Definition: id_types.h:67
virtual unsigned int local_side_node(unsigned int side, unsigned int side_node) const override
Definition: cell_prism20.C:203