LCOV - code coverage report
Current view: top level - src/geom - cell_prism15.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4343 (6ea38c) with base 8c3130 Lines: 182 237 76.8 %
Date: 2026-10-13 21:47:33 Functions: 17 23 73.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 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_prism15.h"
      21             : #include "libmesh/edge_edge3.h"
      22             : #include "libmesh/face_quad8.h"
      23             : #include "libmesh/face_tri6.h"
      24             : #include "libmesh/enum_io_package.h"
      25             : #include "libmesh/enum_order.h"
      26             : 
      27             : namespace libMesh
      28             : {
      29             : 
      30             : 
      31             : 
      32             : // ------------------------------------------------------------
      33             : // Prism15 class static member initializations
      34             : const int Prism15::num_nodes;
      35             : const int Prism15::nodes_per_side;
      36             : const int Prism15::nodes_per_edge;
      37             : 
      38             : // ------------------------------------------------------------
      39             : // Prism15 class member functions
      40             : 
      41     1424426 : bool Prism15::is_vertex(const unsigned int i) const
      42             : {
      43     1424426 :   if (i < 6)
      44      567866 :     return true;
      45       68064 :   return false;
      46             : }
      47             : 
      48       34560 : bool Prism15::is_edge(const unsigned int i) const
      49             : {
      50       34560 :   if (i < 6)
      51           0 :     return false;
      52        2880 :   return true;
      53             : }
      54             : 
      55           0 : bool Prism15::is_face(const unsigned int) const
      56             : {
      57           0 :   return false;
      58             : }
      59             : 
      60       44085 : bool Prism15::is_node_on_side(const unsigned int n,
      61             :                               const unsigned int s) const
      62             : {
      63        3380 :   libmesh_assert_less (s, n_sides());
      64        3380 :   return std::find(std::begin(side_nodes_map[s]),
      65       44085 :                    std::end(side_nodes_map[s]),
      66       44085 :                    n) != std::end(side_nodes_map[s]);
      67             : }
      68             : 
      69             : std::vector<unsigned int>
      70     4098817 : Prism15::nodes_on_side(const unsigned int s) const
      71             : {
      72      365336 :   libmesh_assert_less(s, n_sides());
      73     4098817 :   auto trim = (s > 0 && s < 4) ? 0 : 2;
      74     4098817 :   return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
      75             : }
      76             : 
      77             : std::vector<unsigned>
      78       28287 : Prism15::nodes_on_edge(const unsigned int e) const
      79             : {
      80        2322 :   libmesh_assert_less(e, n_edges());
      81       30609 :   return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
      82             : }
      83             : 
      84       98001 : bool Prism15::is_node_on_edge(const unsigned int n,
      85             :                               const unsigned int e) const
      86             : {
      87        7638 :   libmesh_assert_less (e, n_edges());
      88        7638 :   return std::find(std::begin(edge_nodes_map[e]),
      89       98001 :                    std::end(edge_nodes_map[e]),
      90       98001 :                    n) != std::end(edge_nodes_map[e]);
      91             : }
      92             : 
      93             : 
      94             : 
      95      505033 : bool Prism15::has_affine_map() const
      96             : {
      97             :   // Make sure z edges are affine
      98       87952 :   Point v = this->point(3) - this->point(0);
      99      592473 :   if (!v.relative_fuzzy_equals(this->point(4) - this->point(1), affine_tol) ||
     100      589657 :       !v.relative_fuzzy_equals(this->point(5) - this->point(2), affine_tol))
     101        3072 :     return false;
     102             :   // Make sure edges are straight
     103       43720 :   v /= 2;
     104      545241 :   if (!v.relative_fuzzy_equals(this->point(9) - this->point(0), affine_tol) ||
     105     1003346 :       !v.relative_fuzzy_equals(this->point(10) - this->point(1), affine_tol) ||
     106      545025 :       !v.relative_fuzzy_equals(this->point(11) - this->point(2), affine_tol))
     107         672 :     return false;
     108      544953 :   v = (this->point(1) - this->point(0))/2;
     109      588609 :   if (!v.relative_fuzzy_equals(this->point(6) - this->point(0), affine_tol) ||
     110      544905 :       !v.relative_fuzzy_equals(this->point(12) - this->point(3), affine_tol))
     111          48 :     return false;
     112      544901 :   v = (this->point(2) - this->point(0))/2;
     113      588553 :   if (!v.relative_fuzzy_equals(this->point(8) - this->point(0), affine_tol) ||
     114      544853 :       !v.relative_fuzzy_equals(this->point(14) - this->point(3), affine_tol))
     115          48 :     return false;
     116      544849 :   v = (this->point(2) - this->point(1))/2;
     117      588505 :   if (!v.relative_fuzzy_equals(this->point(7) - this->point(1), affine_tol) ||
     118      588505 :       !v.relative_fuzzy_equals(this->point(13) - this->point(4), affine_tol))
     119           0 :     return false;
     120       43656 :   return true;
     121             : }
     122             : 
     123             : 
     124             : 
     125    15188907 : Order Prism15::default_order() const
     126             : {
     127    15188907 :   return SECOND;
     128             : }
     129             : 
     130             : 
     131             : 
     132    24046985 : unsigned int Prism15::local_side_node(unsigned int side,
     133             :                                       unsigned int side_node) const
     134             : {
     135     2146890 :   libmesh_assert_less (side, this->n_sides());
     136             : 
     137             :   // Never more than 8 nodes per side.
     138     2146890 :   libmesh_assert_less(side_node, Prism15::nodes_per_side);
     139             : 
     140             :   // Some sides have 6 nodes.
     141     2146890 :   libmesh_assert(!(side==0 || side==4) || side_node < 6);
     142             : 
     143    24046985 :   return Prism15::side_nodes_map[side][side_node];
     144             : }
     145             : 
     146             : 
     147             : 
     148     8337357 : unsigned int Prism15::local_edge_node(unsigned int edge,
     149             :                                       unsigned int edge_node) const
     150             : {
     151      742482 :   libmesh_assert_less(edge, this->n_edges());
     152      742482 :   libmesh_assert_less(edge_node, Prism15::nodes_per_edge);
     153             : 
     154     8337357 :   return Prism15::edge_nodes_map[edge][edge_node];
     155             : }
     156             : 
     157             : 
     158             : 
     159      512691 : std::unique_ptr<Elem> Prism15::build_side_ptr (const unsigned int i)
     160             : {
     161       20070 :   libmesh_assert_less (i, this->n_sides());
     162             : 
     163      512691 :   std::unique_ptr<Elem> face;
     164             : 
     165      512691 :   switch (i)
     166             :     {
     167      300432 :     case 0: // the triangular face at z=-1
     168             :     case 4: // the triangular face at z=1
     169             :       {
     170      300432 :         face = std::make_unique<Tri6>();
     171      300432 :         break;
     172             :       }
     173      212259 :     case 1: // the quad face at y=0
     174             :     case 2: // the other quad face
     175             :     case 3: // the quad face at x=0
     176             :       {
     177      212259 :         face = std::make_unique<Quad8>();
     178      212259 :         break;
     179             :       }
     180           0 :     default:
     181           0 :       libmesh_error_msg("Invalid side i = " << i);
     182             :     }
     183             : 
     184             :   // Set the nodes
     185     4013355 :   for (auto n : face->node_index_range())
     186     3640812 :     face->set_node(n, this->node_ptr(Prism15::side_nodes_map[i][n]));
     187             : 
     188      512691 :   face->set_interior_parent(this);
     189      492621 :   face->inherit_data_from(*this);
     190             : 
     191      512691 :   return face;
     192           0 : }
     193             : 
     194             : 
     195      479459 : void Prism15::build_side_ptr (std::unique_ptr<Elem> & side,
     196             :                               const unsigned int i)
     197             : {
     198       11066 :   libmesh_assert_less (i, this->n_sides());
     199             : 
     200      479459 :   switch (i)
     201             :     {
     202        2804 :     case 0: // the triangular face at z=-1
     203             :     case 4: // the triangular face at z=1
     204             :       {
     205      120350 :         if (!side.get() || side->type() != TRI6)
     206             :           {
     207      233820 :             side = this->build_side_ptr(i);
     208      119652 :             return;
     209             :           }
     210          62 :         break;
     211             :       }
     212             : 
     213        8262 :     case 1: // the quad face at y=0
     214             :     case 2: // the other quad face
     215             :     case 3: // the quad face at x=0
     216             :       {
     217      359109 :         if (!side.get() || side->type() != QUAD8)
     218             :           {
     219      233330 :             side = this->build_side_ptr(i);
     220      119389 :             return;
     221             :           }
     222        5538 :         break;
     223             :       }
     224             : 
     225           0 :     default:
     226           0 :       libmesh_error_msg("Invalid side i = " << i);
     227             :     }
     228             : 
     229      234818 :   side->inherit_data_from(*this);
     230             : 
     231             :   // Set the nodes
     232     2162366 :   for (auto n : side->node_index_range())
     233     1966624 :     side->set_node(n, this->node_ptr(Prism15::side_nodes_map[i][n]));
     234             : }
     235             : 
     236             : 
     237             : 
     238      755441 : std::unique_ptr<Elem> Prism15::build_edge_ptr (const unsigned int i)
     239             : {
     240      755441 :   return this->simple_build_edge_ptr<Edge3,Prism15>(i);
     241             : }
     242             : 
     243             : 
     244             : 
     245           0 : void Prism15::build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i)
     246             : {
     247           0 :   this->simple_build_edge_ptr<Prism15>(edge, i, EDGE3);
     248           0 : }
     249             : 
     250             : 
     251             : 
     252           0 : void Prism15::connectivity(const unsigned int libmesh_dbg_var(sc),
     253             :                            const IOPackage iop,
     254             :                            std::vector<dof_id_type> & conn) const
     255             : {
     256           0 :   libmesh_assert(_nodes);
     257           0 :   libmesh_assert_less (sc, this->n_sub_elem());
     258           0 :   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
     259             : 
     260           0 :   switch (iop)
     261             :     {
     262           0 :     case TECPLOT:
     263             :       {
     264           0 :         conn.resize(8);
     265           0 :         conn[0] = this->node_id(0)+1;
     266           0 :         conn[1] = this->node_id(1)+1;
     267           0 :         conn[2] = this->node_id(2)+1;
     268           0 :         conn[3] = this->node_id(2)+1;
     269           0 :         conn[4] = this->node_id(3)+1;
     270           0 :         conn[5] = this->node_id(4)+1;
     271           0 :         conn[6] = this->node_id(5)+1;
     272           0 :         conn[7] = this->node_id(5)+1;
     273           0 :         return;
     274             :       }
     275             : 
     276           0 :     case VTK:
     277             :       {
     278             :         // VTK's VTK_QUADRATIC_WEDGE first 9 nodes match, then their
     279             :         // middle and top layers of mid-edge nodes are reversed from
     280             :         // LibMesh's.
     281           0 :         conn.resize(15);
     282           0 :         for (unsigned i=0; i<9; ++i)
     283           0 :           conn[i] = this->node_id(i);
     284             : 
     285             :         // top "ring" of mid-edge nodes
     286           0 :         conn[9]  = this->node_id(12);
     287           0 :         conn[10] = this->node_id(13);
     288           0 :         conn[11] = this->node_id(14);
     289             : 
     290             :         // middle "ring" of mid-edge nodes
     291           0 :         conn[12] = this->node_id(9);
     292           0 :         conn[13] = this->node_id(10);
     293           0 :         conn[14] = this->node_id(11);
     294             : 
     295           0 :         return;
     296             :       }
     297             : 
     298           0 :     default:
     299           0 :       libmesh_error_msg("Unsupported IO package " << iop);
     300             :     }
     301             : }
     302             : 
     303             : 
     304             : 
     305             : 
     306           0 : unsigned short int Prism15::second_order_adjacent_vertex (const unsigned int n,
     307             :                                                           const unsigned int v) const
     308             : {
     309           0 :   libmesh_assert_greater_equal (n, this->n_vertices());
     310           0 :   libmesh_assert_less (n, this->n_nodes());
     311           0 :   libmesh_assert_less (v, 2);
     312           0 :   return _second_order_adjacent_vertices[n-this->n_vertices()][v];
     313             : }
     314             : 
     315             : 
     316             : 
     317             : std::pair<unsigned short int, unsigned short int>
     318           0 : Prism15::second_order_child_vertex (const unsigned int n) const
     319             : {
     320           0 :   libmesh_assert_greater_equal (n, this->n_vertices());
     321           0 :   libmesh_assert_less (n, this->n_nodes());
     322             : 
     323           0 :   return std::pair<unsigned short int, unsigned short int>
     324           0 :     (_second_order_vertex_child_number[n],
     325           0 :      _second_order_vertex_child_index[n]);
     326             : }
     327             : 
     328             : 
     329             : 
     330         264 : Real Prism15::volume () const
     331             : {
     332             :   // This specialization is good for Lagrange mappings only in general
     333         264 :   if (this->mapping_type() != LAGRANGE_MAP)
     334           0 :     return this->Elem::volume();
     335             : 
     336             :   // Make copies of our points.  It makes the subsequent calculations a bit
     337             :   // shorter and avoids dereferencing the same pointer multiple times.
     338             :   Point
     339         354 :     x0 = point(0),   x1 = point(1),   x2 = point(2),   x3 = point(3),   x4 = point(4),
     340         336 :     x5 = point(5),   x6 = point(6),   x7 = point(7),   x8 = point(8),   x9 = point(9),
     341         336 :     x10 = point(10), x11 = point(11), x12 = point(12), x13 = point(13), x14 = point(14);
     342             : 
     343             :   // Terms are copied directly from a Python script.
     344             :   Point dx_dxi[10] =
     345             :     {
     346          20 :       -x0 - x1 + x10 + 2*x12 - x3 - x4 + 2*x6 - x9,
     347          20 :       3*x0/2 + x1/2 + 2*x12 - 3*x3/2 - x4/2 - 2*x6,
     348          20 :       -x0/2 + x1/2 - x10 - x3/2 + x4/2 + x9,
     349          20 :       2*x0 - 2*x12 + 2*x13 - 2*x14 + 2*x3 - 2*x6 + 2*x7 - 2*x8,
     350          20 :       -2*x0 - 2*x12 + 2*x13 - 2*x14 + 2*x3 + 2*x6 - 2*x7 + 2*x8,
     351             :       Point(0,0,0),
     352          20 :       2*x0 + 2*x1 - 4*x12 + 2*x3 + 2*x4 - 4*x6,
     353          20 :       -2*x0 - 2*x1 - 4*x12 + 2*x3 + 2*x4 + 4*x6,
     354             :       Point(0,0,0),
     355             :       Point(0,0,0)
     356         160 :     };
     357             : 
     358             :   Point dx_deta[10] =
     359             :     {
     360          20 :       -x0 + x11 + 2*x14 - x2 - x3 - x5 + 2*x8 - x9,
     361          20 :       3*x0/2 + 2*x14 + x2/2 - 3*x3/2 - x5/2 - 2*x8,
     362          20 :       -x0/2 - x11 + x2/2 - x3/2 + x5/2 + x9,
     363          20 :       2*x0 - 4*x14 + 2*x2 + 2*x3 + 2*x5 - 4*x8,
     364          20 :       -2*x0 - 4*x14 - 2*x2 + 2*x3 + 2*x5 + 4*x8,
     365             :       Point(0,0,0),
     366          20 :       2*x0 - 2*x12 + 2*x13 - 2*x14 + 2*x3 - 2*x6 + 2*x7 - 2*x8,
     367          20 :       -2*x0 - 2*x12 + 2*x13 - 2*x14 + 2*x3 + 2*x6 - 2*x7 + 2*x8,
     368             :       Point(0,0,0),
     369             :       Point(0,0,0)
     370         160 :     };
     371             : 
     372             :   Point dx_dzeta[10] =
     373             :     {
     374          20 :       -x0/2 + x3/2,
     375          20 :       x0 + x3 - 2*x9,
     376             :       Point(0,0,0),
     377          20 :       3*x0/2 + 2*x14 + x2/2 - 3*x3/2 - x5/2 - 2*x8,
     378          20 :       -x0 - 2*x11 + x2 - x3 + x5 + 2*x9,
     379          20 :       -x0 - 2*x14 - x2 + x3 + x5 + 2*x8,
     380          20 :       3*x0/2 + x1/2 + 2*x12 - 3*x3/2 - x4/2 - 2*x6,
     381          20 :       -x0 + x1 - 2*x10 - x3 + x4 + 2*x9,
     382          20 :       -2*x0 - 2*x12 + 2*x13 - 2*x14 + 2*x3 + 2*x6 - 2*x7 + 2*x8,
     383          20 :       -x0 - x1 - 2*x12 + x3 + x4 + 2*x6
     384         200 :     };
     385             : 
     386             :   // The quadrature rule for the Prism15 is a tensor product between a
     387             :   // FOURTH-order TRI3 rule (in xi, eta) and a FIFTH-order EDGE2 rule
     388             :   // in zeta.
     389             : 
     390             :   // Number of points in the 2D quadrature rule.
     391          20 :   const int N2D = 6;
     392             : 
     393             :   // Parameters of the 2D rule
     394             :   static const Real
     395             :     w1 = 1.1169079483900573284750350421656140e-01_R,
     396             :     w2 = 5.4975871827660933819163162450105264e-02_R,
     397             :     a1 = 4.4594849091596488631832925388305199e-01_R,
     398             :     a2 = 9.1576213509770743459571463402201508e-02_R;
     399             : 
     400             :   // Points and weights of the 2D rule
     401             :   static const Real w2D[N2D] = {w1, w1, w1, w2, w2, w2};
     402             : 
     403             :   // Quadrature point locations raised to powers.  xi[0][2] is
     404             :   // quadrature point 0, squared, xi[1][1] is quadrature point 1 to the
     405             :   // first power, etc.  This lets us avoid calling std::pow inside the
     406             :   // loops below.
     407             :   static const Real xi[N2D][3] =
     408             :     {
     409             :       // ^0   ^1      ^2
     410             :       {   1., a1,     a1*a1},
     411             :       {   1., 1-2*a1, (1-2*a1)*(1-2*a1)},
     412             :       {   1., a1,     a1*a1},
     413             :       {   1., a2,     a2*a2},
     414             :       {   1., 1-2*a2, (1-2*a2)*(1-2*a2)},
     415             :       {   1., a2,     a2*a2}
     416             :     };
     417             : 
     418             :   static const Real eta[N2D][3] =
     419             :     {
     420             :       // ^0   ^1      ^2
     421             :       {   1., a1,     a1*a1},
     422             :       {   1., a1,     a1*a1},
     423             :       {   1., 1-2*a1, (1-2*a1)*(1-2*a1)},
     424             :       {   1., a2,     a2*a2},
     425             :       {   1., a2,     a2*a2},
     426             :       {   1., 1-2*a2, (1-2*a2)*(1-2*a2)}
     427             :     };
     428             : 
     429             :   // Number of points in the 1D quadrature rule.
     430          20 :   const int N1D = 3;
     431             : 
     432             :   // Points and weights of the 1D quadrature rule.
     433             :   static const Real w1D[N1D] = {5./9, 8./9, 5./9};
     434             : 
     435         264 :   const Real zeta[N1D][3] =
     436             :     {
     437             :       //^0   ^1                 ^2
     438             :       {  1., -std::sqrt(15)/5., 15./25},
     439             :       {  1., 0.,                0.},
     440             :       {  1., std::sqrt(15)/5.,  15./25}
     441             :     };
     442             : 
     443             :   // The integer exponents for each term.
     444             :   static const int exponents[10][3] =
     445             :     {
     446             :       {0, 0, 0},
     447             :       {0, 0, 1},
     448             :       {0, 0, 2},
     449             :       {0, 1, 0},
     450             :       {0, 1, 1},
     451             :       {0, 2, 0},
     452             :       {1, 0, 0},
     453             :       {1, 0, 1},
     454             :       {1, 1, 0},
     455             :       {2, 0, 0}
     456             :     };
     457             : 
     458          20 :   Real vol = 0.;
     459        1848 :   for (int i=0; i<N2D; ++i)
     460        6336 :     for (int j=0; j<N1D; ++j)
     461             :       {
     462             :         // Compute dx_dxi, dx_deta, dx_dzeta at the current quadrature point.
     463         360 :         Point dx_dxi_q, dx_deta_q, dx_dzeta_q;
     464       52272 :         for (int c=0; c<10; ++c)
     465             :           {
     466        3600 :             Real coeff =
     467       54360 :               xi[i][exponents[c][0]]*
     468       54360 :               eta[i][exponents[c][1]]*
     469       47520 :               zeta[j][exponents[c][2]];
     470             : 
     471        3600 :             dx_dxi_q   += coeff * dx_dxi[c];
     472        3600 :             dx_deta_q  += coeff * dx_deta[c];
     473        3600 :             dx_dzeta_q += coeff * dx_dzeta[c];
     474             :           }
     475             : 
     476             :         // Compute scalar triple product, multiply by weight, and accumulate volume.
     477        5076 :         vol += w2D[i] * w1D[j] * triple_product(dx_dxi_q, dx_deta_q, dx_dzeta_q);
     478             :       }
     479             : 
     480          20 :   return vol;
     481             : }
     482             : 
     483             : 
     484             : 
     485             : #ifdef LIBMESH_ENABLE_AMR
     486             : 
     487             : const Real Prism15::_embedding_matrix[Prism15::num_children][Prism15::num_nodes][Prism15::num_nodes] =
     488             :   {
     489             :     // Embedding matrix for child 0
     490             :     {
     491             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     492             :       {       1,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0 }, //  0
     493             :       {       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0,       0 }, //  1
     494             :       {       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0 }, //  2
     495             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0 }, //  3
     496             :       {   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0 }, //  4
     497             :       {   -0.25,       0,   -0.25,   -0.25,       0,   -0.25,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0,     0.5 }, //  5
     498             :       {   0.375,  -0.125,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0,       0,       0,       0 }, //  6
     499             :       {       0,  -0.125,  -0.125,       0,       0,       0,     0.5,    0.25,     0.5,       0,       0,       0,       0,       0,       0 }, //  7
     500             :       {   0.375,       0,  -0.125,       0,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0,       0 }, //  8
     501             :       {   0.375,       0,       0,  -0.125,       0,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0 }, //  9
     502             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.75,       0,       0,   0.375,   0.375,       0,    0.25,       0,       0 }, // 10
     503             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,    0.75,   0.375,       0,   0.375,       0,       0,    0.25 }, // 11
     504             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.75,    0.25,       0,   0.375,       0,       0 }, // 12
     505             :       {   -0.25, -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125,    0.25 }, // 13
     506             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,   0.375,    0.75,       0,    0.25,       0,       0,   0.375 }  // 14
     507             :     },
     508             : 
     509             :     // Embedding matrix for child 1
     510             :     {
     511             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     512             :       {       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0,       0 }, //  0
     513             :       {       0,       1,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0 }, //  1
     514             :       {       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0 }, //  2
     515             :       {   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0 }, //  3
     516             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0 }, //  4
     517             :       {       0,   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0 }, //  5
     518             :       {  -0.125,   0.375,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0,       0,       0,       0 }, //  6
     519             :       {       0,   0.375,  -0.125,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0,       0,       0 }, //  7
     520             :       {  -0.125,       0,  -0.125,       0,       0,       0,     0.5,     0.5,    0.25,       0,       0,       0,       0,       0,       0 }, //  8
     521             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.75,       0,       0,   0.375,   0.375,       0,    0.25,       0,       0 }, //  9
     522             :       {       0,   0.375,       0,       0,  -0.125,       0,       0,       0,       0,       0,    0.75,       0,       0,       0,       0 }, // 10
     523             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.75,       0,       0,   0.375,   0.375,       0,    0.25,       0 }, // 11
     524             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.25,    0.75,       0,   0.375,       0,       0 }, // 12
     525             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.75,    0.25,       0,   0.375,       0 }, // 13
     526             :       { -0.1875,   -0.25, -0.1875, -0.1875,   -0.25, -0.1875,    0.25,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125 }  // 14
     527             :     },
     528             : 
     529             :     // Embedding matrix for child 2
     530             :     {
     531             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     532             :       {       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0 }, //  0
     533             :       {       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0 }, //  1
     534             :       {       0,       0,       1,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0 }, //  2
     535             :       {   -0.25,       0,   -0.25,   -0.25,       0,   -0.25,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0,     0.5 }, //  3
     536             :       {       0,   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0 }, //  4
     537             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0 }, //  5
     538             :       {  -0.125,  -0.125,       0,       0,       0,       0,    0.25,     0.5,     0.5,       0,       0,       0,       0,       0,       0 }, //  6
     539             :       {       0,  -0.125,   0.375,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0,       0,       0 }, //  7
     540             :       {  -0.125,       0,   0.375,       0,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0,       0 }, //  8
     541             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,    0.75,   0.375,       0,   0.375,       0,       0,    0.25 }, //  9
     542             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.75,       0,       0,   0.375,   0.375,       0,    0.25,       0 }, // 10
     543             :       {       0,       0,   0.375,       0,       0,  -0.125,       0,       0,       0,       0,       0,    0.75,       0,       0,       0 }, // 11
     544             :       { -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,   -0.25,   0.125,    0.25,    0.25,    0.25,    0.25,     0.5,   0.125,    0.25,    0.25 }, // 12
     545             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.25,    0.75,       0,   0.375,       0 }, // 13
     546             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,   0.375,    0.25,       0,    0.75,       0,       0,   0.375 }  // 14
     547             :     },
     548             : 
     549             :     // Embedding matrix for child 3
     550             :     {
     551             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     552             :       {       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0,       0 }, //  0
     553             :       {       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0 }, //  1
     554             :       {       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0 }, //  2
     555             :       {   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0 }, //  3
     556             :       {       0,   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0 }, //  4
     557             :       {   -0.25,       0,   -0.25,   -0.25,       0,   -0.25,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0,     0.5 }, //  5
     558             :       {  -0.125,       0,  -0.125,       0,       0,       0,     0.5,     0.5,    0.25,       0,       0,       0,       0,       0,       0 }, //  6
     559             :       {  -0.125,  -0.125,       0,       0,       0,       0,    0.25,     0.5,     0.5,       0,       0,       0,       0,       0,       0 }, //  7
     560             :       {       0,  -0.125,  -0.125,       0,       0,       0,     0.5,    0.25,     0.5,       0,       0,       0,       0,       0,       0 }, //  8
     561             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.75,       0,       0,   0.375,   0.375,       0,    0.25,       0,       0 }, //  9
     562             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.75,       0,       0,   0.375,   0.375,       0,    0.25,       0 }, // 10
     563             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,    0.75,   0.375,       0,   0.375,       0,       0,    0.25 }, // 11
     564             :       { -0.1875,   -0.25, -0.1875, -0.1875,   -0.25, -0.1875,    0.25,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125 }, // 12
     565             :       { -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,   -0.25,   0.125,    0.25,    0.25,    0.25,    0.25,     0.5,   0.125,    0.25,    0.25 }, // 13
     566             :       {   -0.25, -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125,    0.25 }  // 14
     567             :     },
     568             : 
     569             :     // Embedding matrix for child 4
     570             :     {
     571             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     572             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0 }, //  0
     573             :       {   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0 }, //  1
     574             :       {   -0.25,       0,   -0.25,   -0.25,       0,   -0.25,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0,     0.5 }, //  2
     575             :       {       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0 }, //  3
     576             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0 }, //  4
     577             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1 }, //  5
     578             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.75,    0.25,       0,   0.375,       0,       0 }, //  6
     579             :       {   -0.25, -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125,    0.25 }, //  7
     580             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,   0.375,    0.75,       0,    0.25,       0,       0,   0.375 }, //  8
     581             :       {  -0.125,       0,       0,   0.375,       0,       0,       0,       0,       0,    0.75,       0,       0,       0,       0,       0 }, //  9
     582             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.25,       0,       0,   0.375,   0.375,       0,    0.75,       0,       0 }, // 10
     583             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,    0.25,   0.375,       0,   0.375,       0,       0,    0.75 }, // 11
     584             :       {       0,       0,       0,   0.375,  -0.125,       0,       0,       0,       0,       0,       0,       0,    0.75,       0,       0 }, // 12
     585             :       {       0,       0,       0,       0,  -0.125,  -0.125,       0,       0,       0,       0,       0,       0,     0.5,    0.25,     0.5 }, // 13
     586             :       {       0,       0,       0,   0.375,       0,  -0.125,       0,       0,       0,       0,       0,       0,       0,       0,    0.75 }  // 14
     587             :     },
     588             : 
     589             :     // Embedding matrix for child 5
     590             :     {
     591             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     592             :       {   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0 }, //  0
     593             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0,       0 }, //  1
     594             :       {       0,   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0 }, //  2
     595             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0 }, //  3
     596             :       {       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0 }, //  4
     597             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0 }, //  5
     598             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.25,    0.75,       0,   0.375,       0,       0 }, //  6
     599             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.75,    0.25,       0,   0.375,       0 }, //  7
     600             :       { -0.1875,   -0.25, -0.1875, -0.1875,   -0.25, -0.1875,    0.25,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125 }, //  8
     601             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.25,       0,       0,   0.375,   0.375,       0,    0.75,       0,       0 }, //  9
     602             :       {       0,  -0.125,       0,       0,   0.375,       0,       0,       0,       0,       0,    0.75,       0,       0,       0,       0 }, // 10
     603             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.25,       0,       0,   0.375,   0.375,       0,    0.75,       0 }, // 11
     604             :       {       0,       0,       0,  -0.125,   0.375,       0,       0,       0,       0,       0,       0,       0,    0.75,       0,       0 }, // 12
     605             :       {       0,       0,       0,       0,   0.375,  -0.125,       0,       0,       0,       0,       0,       0,       0,    0.75,       0 }, // 13
     606             :       {       0,       0,       0,  -0.125,       0,  -0.125,       0,       0,       0,       0,       0,       0,     0.5,     0.5,    0.25 }  // 14
     607             :     },
     608             : 
     609             :     // Embedding matrix for child 6
     610             :     {
     611             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     612             :       {   -0.25,       0,   -0.25,   -0.25,       0,   -0.25,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0,     0.5 }, //  0
     613             :       {       0,   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0 }, //  1
     614             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0,       0 }, //  2
     615             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1 }, //  3
     616             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0 }, //  4
     617             :       {       0,       0,       0,       0,       0,       1,       0,       0,       0,       0,       0,       0,       0,       0,       0 }, //  5
     618             :       { -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,   -0.25,   0.125,    0.25,    0.25,    0.25,    0.25,     0.5,   0.125,    0.25,    0.25 }, //  6
     619             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,   0.375,       0,       0,    0.25,    0.75,       0,   0.375,       0 }, //  7
     620             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,   0.375,    0.25,       0,    0.75,       0,       0,   0.375 }, //  8
     621             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,    0.25,   0.375,       0,   0.375,       0,       0,    0.75 }, //  9
     622             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.25,       0,       0,   0.375,   0.375,       0,    0.75,       0 }, // 10
     623             :       {       0,       0,  -0.125,       0,       0,   0.375,       0,       0,       0,       0,       0,    0.75,       0,       0,       0 }, // 11
     624             :       {       0,       0,       0,  -0.125,  -0.125,       0,       0,       0,       0,       0,       0,       0,    0.25,     0.5,     0.5 }, // 12
     625             :       {       0,       0,       0,       0,  -0.125,   0.375,       0,       0,       0,       0,       0,       0,       0,    0.75,       0 }, // 13
     626             :       {       0,       0,       0,  -0.125,       0,   0.375,       0,       0,       0,       0,       0,       0,       0,       0,    0.75 }  // 14
     627             :     },
     628             : 
     629             :     // Embedding matrix for child 7
     630             :     {
     631             :       //       0        1        2        3        4        5        6        7        8        9       10       11       12       13       14
     632             :       {   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0 }, //  0
     633             :       {       0,   -0.25,   -0.25,       0,   -0.25,   -0.25,       0,     0.5,       0,       0,     0.5,     0.5,       0,     0.5,       0 }, //  1
     634             :       {   -0.25,       0,   -0.25,   -0.25,       0,   -0.25,       0,       0,     0.5,     0.5,       0,     0.5,       0,       0,     0.5 }, //  2
     635             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0,       0 }, //  3
     636             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1,       0 }, //  4
     637             :       {       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       0,       1 }, //  5
     638             :       { -0.1875,   -0.25, -0.1875, -0.1875,   -0.25, -0.1875,    0.25,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125 }, //  6
     639             :       { -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,   -0.25,   0.125,    0.25,    0.25,    0.25,    0.25,     0.5,   0.125,    0.25,    0.25 }, //  7
     640             :       {   -0.25, -0.1875, -0.1875,   -0.25, -0.1875, -0.1875,    0.25,   0.125,    0.25,     0.5,    0.25,    0.25,    0.25,   0.125,    0.25 }, //  8
     641             :       { -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.25,       0,       0,   0.375,   0.375,       0,    0.75,       0,       0 }, //  9
     642             :       {       0, -0.1875, -0.1875,       0, -0.1875, -0.1875,       0,    0.25,       0,       0,   0.375,   0.375,       0,    0.75,       0 }, // 10
     643             :       { -0.1875,       0, -0.1875, -0.1875,       0, -0.1875,       0,       0,    0.25,   0.375,       0,   0.375,       0,       0,    0.75 }, // 11
     644             :       {       0,       0,       0,  -0.125,       0,  -0.125,       0,       0,       0,       0,       0,       0,     0.5,     0.5,    0.25 }, // 12
     645             :       {       0,       0,       0,  -0.125,  -0.125,       0,       0,       0,       0,       0,       0,       0,    0.25,     0.5,     0.5 }, // 13
     646             :       {       0,       0,       0,       0,  -0.125,  -0.125,       0,       0,       0,       0,       0,       0,     0.5,    0.25,     0.5 }  // 14
     647             :     }
     648             :   };
     649             : 
     650             : #endif
     651             : 
     652             : 
     653             : void
     654        8736 : Prism15::permute(unsigned int perm_num)
     655             : {
     656         768 :   libmesh_assert_less (perm_num, 6);
     657        8736 :   const unsigned int side = perm_num % 2;
     658        8736 :   const unsigned int rotate = perm_num / 2;
     659             : 
     660       20112 :   for (unsigned int i = 0; i != rotate; ++i)
     661             :     {
     662       11376 :       swap3nodes(0,1,2);
     663       10368 :       swap3nodes(3,4,5);
     664       10368 :       swap3nodes(6,7,8);
     665       10368 :       swap3nodes(9,10,11);
     666       10368 :       swap3nodes(12,13,14);
     667       10368 :       swap3neighbors(1,2,3);
     668             :     }
     669             : 
     670        8736 :   switch (side) {
     671         144 :   case 0:
     672         144 :     break;
     673        7008 :   case 1:
     674        7008 :     swap2nodes(1,3);
     675        7008 :     swap2nodes(0,4);
     676        7008 :     swap2nodes(2,5);
     677        7008 :     swap2nodes(6,12);
     678        7008 :     swap2nodes(9,10);
     679        7008 :     swap2nodes(7,14);
     680        7008 :     swap2nodes(8,13);
     681         624 :     swap2neighbors(0,4);
     682         624 :     swap2neighbors(2,3);
     683         624 :     break;
     684           0 :   default:
     685           0 :     libmesh_error();
     686             :   }
     687             : 
     688        8736 : }
     689             : 
     690             : 
     691             : void
     692         576 : Prism15::flip(BoundaryInfo * boundary_info)
     693             : {
     694          48 :   libmesh_assert(boundary_info);
     695             : 
     696         576 :   swap2nodes(0,1);
     697         576 :   swap2nodes(3,4);
     698         576 :   swap2nodes(7,8);
     699         576 :   swap2nodes(9,10);
     700         576 :   swap2nodes(13,14);
     701          48 :   swap2neighbors(2,3);
     702         576 :   swap2boundarysides(2,3,boundary_info);
     703         576 :   swap2boundaryedges(0,1,boundary_info);
     704         576 :   swap2boundaryedges(3,4,boundary_info);
     705         576 :   swap2boundaryedges(7,8,boundary_info);
     706         576 : }
     707             : 
     708             : 
     709             : ElemType
     710     8036172 : Prism15::side_type (const unsigned int s) const
     711             : {
     712      717416 :   libmesh_assert_less (s, 5);
     713     8036172 :   if (s == 0 || s == 4)
     714       10056 :     return TRI6;
     715      716576 :   return QUAD8;
     716             : }
     717             : 
     718             : } // namespace libMesh

Generated by: LCOV version 1.14