LCOV - code coverage report
Current view: top level - src/geom - cell_pyramid13.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4554 (5a536d) with base 54e0d5 Lines: 185 212 87.3 %
Date: 2026-09-16 12:37:14 Functions: 19 23 82.6 %
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_pyramid13.h"
      21             : #include "libmesh/fe_reference_element_traits.h"
      22             : #include "libmesh/edge_edge3.h"
      23             : #include "libmesh/face_tri6.h"
      24             : #include "libmesh/face_quad8.h"
      25             : #include "libmesh/enum_io_package.h"
      26             : #include "libmesh/enum_order.h"
      27             : 
      28             : namespace libMesh
      29             : {
      30             : 
      31             : 
      32             : 
      33             : 
      34             : // ------------------------------------------------------------
      35             : // Pyramid13 class static member initializations
      36             : const int Pyramid13::num_nodes;
      37             : const int Pyramid13::nodes_per_side;
      38             : const int Pyramid13::nodes_per_edge;
      39             : 
      40             : const ReferenceElementTable<Pyramid13::num_sides, Pyramid13::nodes_per_side>
      41             : Pyramid13::side_nodes_map = build_side_nodes<Pyramid13::num_sides, Pyramid13::nodes_per_side>(PYRAMID13);
      42             : 
      43             : const ReferenceElementTable<Pyramid13::num_edges, Pyramid13::nodes_per_edge>
      44             : Pyramid13::edge_nodes_map = pyramid_edge_nodes();
      45             : 
      46             : // ------------------------------------------------------------
      47             : // Pyramid13 class member functions
      48             : 
      49      269256 : bool Pyramid13::is_vertex(const unsigned int i) const
      50             : {
      51      269256 :   if (i < 5)
      52      146376 :     return true;
      53       33936 :   return false;
      54             : }
      55             : 
      56             : 
      57             : 
      58        9216 : bool Pyramid13::is_edge(const unsigned int i) const
      59             : {
      60        9216 :   if (i < 5)
      61           0 :     return false;
      62        2304 :   return true;
      63             : }
      64             : 
      65             : 
      66             : 
      67           0 : bool Pyramid13::is_face(const unsigned int) const
      68             : {
      69           0 :   return false;
      70             : }
      71             : 
      72             : 
      73             : 
      74       33095 : bool Pyramid13::is_node_on_side(const unsigned int n,
      75             :                                 const unsigned int s) const
      76             : {
      77        8290 :   libmesh_assert_less (s, n_sides());
      78        8290 :   return std::find(std::begin(side_nodes_map[s]),
      79        8290 :                    std::end(side_nodes_map[s]),
      80       33095 :                    n) != std::end(side_nodes_map[s]);
      81             : }
      82             : 
      83             : std::vector<unsigned>
      84       13643 : Pyramid13::nodes_on_side(const unsigned int s) const
      85             : {
      86        3418 :   libmesh_assert_less(s, n_sides());
      87       13643 :   auto trim = (s == 4) ? 0 : 2;
      88       13643 :   return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s]) - trim};
      89             : }
      90             : 
      91             : std::vector<unsigned>
      92       10808 : Pyramid13::nodes_on_edge(const unsigned int e) const
      93             : {
      94        2704 :   libmesh_assert_less(e, n_edges());
      95       10808 :   return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
      96             : }
      97             : 
      98      188792 : bool Pyramid13::is_node_on_edge(const unsigned int n,
      99             :                                 const unsigned int e) const
     100             : {
     101       52216 :   libmesh_assert_less (e, n_edges());
     102       52216 :   return std::find(std::begin(edge_nodes_map[e]),
     103       52216 :                    std::end(edge_nodes_map[e]),
     104      188792 :                    n) != std::end(edge_nodes_map[e]);
     105             : }
     106             : 
     107             : 
     108             : 
     109       18680 : bool Pyramid13::has_affine_map() const
     110             : {
     111             :   // TODO: If the base is a parallelogram and all the triangular faces are planar,
     112             :   // the map should be linear, but I need to test this theory...
     113       18680 :   return false;
     114             : }
     115             : 
     116             : 
     117             : 
     118     1327244 : Order Pyramid13::default_order() const
     119             : {
     120     1327244 :   return SECOND;
     121             : }
     122             : 
     123             : 
     124             : 
     125        6375 : unsigned int Pyramid13::local_side_node(unsigned int side,
     126             :                                         unsigned int side_node) const
     127             : {
     128        1602 :   libmesh_assert_less (side, this->n_sides());
     129             : 
     130             :   // Never more than 8 nodes per side.
     131        1602 :   libmesh_assert_less(side_node, Pyramid13::nodes_per_side);
     132             : 
     133             :   // Some sides have 6 nodes.
     134        1602 :   libmesh_assert(side == 4 || side_node < 6);
     135             : 
     136        6375 :   return Pyramid13::side_nodes_map[side][side_node];
     137             : }
     138             : 
     139             : 
     140             : 
     141       44572 : unsigned int Pyramid13::local_edge_node(unsigned int edge,
     142             :                                         unsigned int edge_node) const
     143             : {
     144       11144 :   libmesh_assert_less(edge, this->n_edges());
     145       11144 :   libmesh_assert_less(edge_node, Pyramid13::nodes_per_edge);
     146             : 
     147       44572 :   return Pyramid13::edge_nodes_map[edge][edge_node];
     148             : }
     149             : 
     150             : 
     151             : 
     152       54094 : std::unique_ptr<Elem> Pyramid13::build_side_ptr (const unsigned int i)
     153             : {
     154       17204 :   libmesh_assert_less (i, this->n_sides());
     155             : 
     156       54094 :   std::unique_ptr<Elem> face;
     157             : 
     158       54094 :   switch (i)
     159             :     {
     160       27974 :     case 0: // triangular face 1
     161             :     case 1: // triangular face 2
     162             :     case 2: // triangular face 3
     163             :     case 3: // triangular face 4
     164             :       {
     165       27974 :         face = std::make_unique<Tri6>();
     166       27974 :         break;
     167             :       }
     168       26120 :     case 4:  // the quad face at z=0
     169             :       {
     170       26120 :         face = std::make_unique<Quad8>();
     171       26120 :         break;
     172             :       }
     173           0 :     default:
     174           0 :       libmesh_error_msg("Invalid side i = " << i);
     175             :     }
     176             : 
     177             :   // Set the nodes
     178      430898 :   for (auto n : face->node_index_range())
     179      496764 :     face->set_node(n, this->node_ptr(Pyramid13::side_nodes_map[i][n]));
     180             : 
     181       54094 :   face->set_interior_parent(this);
     182       36890 :   face->inherit_data_from(*this);
     183             : 
     184       54094 :   return face;
     185           0 : }
     186             : 
     187             : 
     188             : 
     189      104099 : void Pyramid13::build_side_ptr (std::unique_ptr<Elem> & side,
     190             :                                 const unsigned int i)
     191             : {
     192       33370 :   libmesh_assert_less (i, this->n_sides());
     193             : 
     194      104099 :   switch (i)
     195             :     {
     196       25064 :     case 0: // triangular face 1
     197             :     case 1: // triangular face 2
     198             :     case 2: // triangular face 3
     199             :     case 3: // triangular face 4
     200             :       {
     201       78220 :         if (!side.get() || side->type() != TRI6)
     202             :           {
     203         308 :             side = this->build_side_ptr(i);
     204         206 :             return;
     205             :           }
     206       25012 :         break;
     207             :       }
     208        8306 :     case 4:  // the quad face at z=0
     209             :       {
     210       25879 :         if (!side.get() || side->type() != QUAD8)
     211             :           {
     212       34580 :             side = this->build_side_ptr(i);
     213       25502 :             return;
     214             :           }
     215          94 :         break;
     216             :       }
     217           0 :     default:
     218           0 :       libmesh_error_msg("Invalid side i = " << i);
     219             :     }
     220             : 
     221       53285 :   side->inherit_data_from(*this);
     222             : 
     223             :   // Set the nodes
     224      549491 :   for (auto n : side->node_index_range())
     225      621924 :     side->set_node(n, this->node_ptr(Pyramid13::side_nodes_map[i][n]));
     226             : }
     227             : 
     228             : 
     229             : 
     230         168 : std::unique_ptr<Elem> Pyramid13::build_edge_ptr (const unsigned int i)
     231             : {
     232         168 :   return this->simple_build_edge_ptr<Edge3,Pyramid13>(i);
     233             : }
     234             : 
     235             : 
     236             : 
     237           0 : void Pyramid13::build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i)
     238             : {
     239           0 :   this->simple_build_edge_ptr<Pyramid13>(edge, i, EDGE3);
     240           0 : }
     241             : 
     242             : 
     243             : 
     244           0 : void Pyramid13::connectivity(const unsigned int libmesh_dbg_var(sc),
     245             :                              const IOPackage iop,
     246             :                              std::vector<dof_id_type> & /*conn*/) const
     247             : {
     248           0 :   libmesh_assert(_nodes);
     249           0 :   libmesh_assert_less (sc, this->n_sub_elem());
     250           0 :   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
     251             : 
     252           0 :   switch (iop)
     253             :     {
     254           0 :     case TECPLOT:
     255             :       {
     256             :         // TODO
     257           0 :         libmesh_not_implemented();
     258             :       }
     259             : 
     260           0 :     case VTK:
     261             :       {
     262             :         // TODO
     263           0 :         libmesh_not_implemented();
     264             :       }
     265             : 
     266           0 :     default:
     267           0 :       libmesh_error_msg("Unsupported IO package " << iop);
     268             :     }
     269             : }
     270             : 
     271             : 
     272             : 
     273       86688 : unsigned int Pyramid13::n_second_order_adjacent_vertices (const unsigned int n) const
     274             : {
     275       86688 :   switch (n)
     276             :     {
     277       86688 :     case 5:
     278             :     case 6:
     279             :     case 7:
     280             :     case 8:
     281             :     case 9:
     282             :     case 10:
     283             :     case 11:
     284             :     case 12:
     285       86688 :       return 2;
     286             : 
     287           0 :     default:
     288           0 :       libmesh_error_msg("Invalid node n = " << n);
     289             :     }
     290             : }
     291             : 
     292             : 
     293      173376 : unsigned short int Pyramid13::second_order_adjacent_vertex (const unsigned int n,
     294             :                                                             const unsigned int v) const
     295             : {
     296       49536 :   libmesh_assert_greater_equal (n, this->n_vertices());
     297       49536 :   libmesh_assert_less (n, this->n_nodes());
     298             : 
     299      173376 :   switch (n)
     300             :     {
     301      173376 :     case 5:
     302             :     case 6:
     303             :     case 7:
     304             :     case 8:
     305             :     case 9:
     306             :     case 10:
     307             :     case 11:
     308             :     case 12:
     309             :       {
     310       49536 :         libmesh_assert_less (v, 2);
     311             : 
     312             :         // This is the analog of the static, const arrays
     313             :         // {Hex,Prism,Tet10}::_second_order_adjacent_vertices
     314             :         // defined in the respective source files...
     315      173376 :         unsigned short node_list[8][2] =
     316             :           {
     317             :             {0,1},
     318             :             {1,2},
     319             :             {2,3},
     320             :             {0,3},
     321             :             {0,4},
     322             :             {1,4},
     323             :             {2,4},
     324             :             {3,4}
     325             :           };
     326             : 
     327      173376 :         return node_list[n-5][v];
     328             :       }
     329             : 
     330           0 :     default:
     331           0 :       libmesh_error_msg("Invalid n = " << n);
     332             : 
     333             :     }
     334             : }
     335             : 
     336             : 
     337             : 
     338         201 : Real Pyramid13::volume () const
     339             : {
     340             :   // This specialization is good for Lagrange mappings only in general
     341         201 :   if (this->mapping_type() != LAGRANGE_MAP)
     342           0 :     return this->Elem::volume();
     343             : 
     344             :   // Make copies of our points.  It makes the subsequent calculations a bit
     345             :   // shorter and avoids dereferencing the same pointer multiple times.
     346             :   Point
     347         551 :     x0 = point(0), x1 = point(1), x2 = point(2), x3 = point(3),   x4 = point(4),   x5 = point(5),   x6 = point(6),
     348         451 :     x7 = point(7), x8 = point(8), x9 = point(9), x10 = point(10), x11 = point(11), x12 = point(12);
     349             : 
     350             :   // dx/dxi and dx/deta have 14 components while dx/dzeta has 19.
     351             :   // These are copied directly from the output of a Python script.
     352             :   Point dx_dxi[14] =
     353             :     {
     354          52 :       x6/2 - x8/2,
     355          52 :       x0/4 - x1/4 + x10 + x11 - x12 - x2/4 + x3/4 - 3*x6/2 + 3*x8/2 - x9,
     356          52 :       -x0/2 + x1/2 - 2*x10 - 2*x11 + 2*x12 + x2/2 - x3/2 + 3*x6/2 - 3*x8/2 + 2*x9,
     357          52 :       x0/4 - x1/4 + x10 + x11 - x12 - x2/4 + x3/4 - x6/2 + x8/2 - x9,
     358          52 :       x0/4 - x1/4 + x2/4 - x3/4,
     359          52 :       -3*x0/4 + 3*x1/4 - x10 + x11 - x12 - 3*x2/4 + 3*x3/4 + x9,
     360          52 :       x0/2 - x1/2 + x10 - x11 + x12 + x2/2 - x3/2 - x9,
     361          52 :       -x0/4 + x1/4 + x2/4 - x3/4 - x6/2 + x8/2,
     362          52 :       x0/4 - x1/4 - x2/4 + x3/4 + x6/2 - x8/2,
     363          52 :       x0/2 + x1/2 + x2/2 + x3/2 - x5 - x7,
     364          52 :       -x0 - x1 - x2 - x3 + 2*x5 + 2*x7,
     365          52 :       x0/2 + x1/2 + x2/2 + x3/2 - x5 - x7,
     366          52 :       -x0/2 - x1/2 + x2/2 + x3/2 + x5 - x7,
     367          52 :       x0/2 + x1/2 - x2/2 - x3/2 - x5 + x7
     368         780 :     };
     369             : 
     370             :   // dx/dxi and dx/deta have 14 components while dx/dzeta has 19.
     371             :   // These are copied directly from the output of a Python script.
     372             :   Point dx_deta[14] =
     373             :     {
     374          52 :       -x5/2 + x7/2,
     375          52 :       x0/4 + x1/4 - x10 + x11 + x12 - x2/4 - x3/4 + 3*x5/2 - 3*x7/2 - x9,
     376          52 :       -x0/2 - x1/2 + 2*x10 - 2*x11 - 2*x12 + x2/2 + x3/2 - 3*x5/2 + 3*x7/2 + 2*x9,
     377          52 :       x0/4 + x1/4 - x10 + x11 + x12 - x2/4 - x3/4 + x5/2 - x7/2 - x9,
     378          52 :       x0/2 + x1/2 + x2/2 + x3/2 - x6 - x8,
     379          52 :       -x0 - x1 - x2 - x3 + 2*x6 + 2*x8,
     380          52 :       x0/2 + x1/2 + x2/2 + x3/2 - x6 - x8,
     381          52 :       x0/4 - x1/4 + x2/4 - x3/4,
     382          52 :       -3*x0/4 + 3*x1/4 - x10 + x11 - x12 - 3*x2/4 + 3*x3/4 + x9,
     383          52 :       x0/2 - x1/2 + x10 - x11 + x12 + x2/2 - x3/2 - x9,
     384          52 :       -x0/2 + x1/2 + x2/2 - x3/2 - x6 + x8,
     385          52 :       x0/2 - x1/2 - x2/2 + x3/2 + x6 - x8,
     386          52 :       -x0/4 - x1/4 + x2/4 + x3/4 + x5/2 - x7/2,
     387          52 :       x0/4 + x1/4 - x2/4 - x3/4 - x5/2 + x7/2
     388         780 :     };
     389             : 
     390             :   // dx/dxi and dx/deta have 14 components while dx/dzeta has 19.
     391             :   // These are copied directly from the output of a Python script.
     392             :   Point dx_dzeta[19] =
     393             :     {
     394          52 :       x0/4 + x1/4 + x10 + x11 + x12 + x2/4 + x3/4 - x4 - x5 - x6 - x7 - x8 + x9,
     395          52 :       -3*x0/4 - 3*x1/4 - 5*x10 - 5*x11 - 5*x12 - 3*x2/4 - 3*x3/4 + 7*x4 + 4*x5 + 4*x6 + 4*x7 + 4*x8 - 5*x9,
     396          52 :       3*x0/4 + 3*x1/4 + 9*x10 + 9*x11 + 9*x12 + 3*x2/4 + 3*x3/4 - 15*x4 - 6*x5 - 6*x6 - 6*x7 - 6*x8 + 9*x9,
     397          52 :       -x0/4 - x1/4 - 7*x10 - 7*x11 - 7*x12 - x2/4 - x3/4 + 13*x4 + 4*x5 + 4*x6 + 4*x7 + 4*x8 - 7*x9,
     398          52 :       2*x10 + 2*x11 + 2*x12 - 4*x4 - x5 - x6 - x7 - x8 + 2*x9,
     399          52 :       x0/4 + x1/4 - x10 + x11 + x12 - x2/4 - x3/4 + x5/2 - x7/2 - x9,
     400          52 :       -3*x0/4 - 3*x1/4 + 3*x10 - 3*x11 - 3*x12 + 3*x2/4 + 3*x3/4 - 3*x5/2 + 3*x7/2 + 3*x9,
     401          52 :       3*x0/4 + 3*x1/4 - 3*x10 + 3*x11 + 3*x12 - 3*x2/4 - 3*x3/4 + 3*x5/2 - 3*x7/2 - 3*x9,
     402          52 :       -x0/4 - x1/4 + x10 - x11 - x12 + x2/4 + x3/4 - x5/2 + x7/2 + x9,
     403          52 :       x0/4 - x1/4 + x10 + x11 - x12 - x2/4 + x3/4 - x6/2 + x8/2 - x9,
     404          52 :       -3*x0/4 + 3*x1/4 - 3*x10 - 3*x11 + 3*x12 + 3*x2/4 - 3*x3/4 + 3*x6/2 - 3*x8/2 + 3*x9,
     405          52 :       3*x0/4 - 3*x1/4 + 3*x10 + 3*x11 - 3*x12 - 3*x2/4 + 3*x3/4 - 3*x6/2 + 3*x8/2 - 3*x9,
     406          52 :       -x0/4 + x1/4 - x10 - x11 + x12 + x2/4 - x3/4 + x6/2 - x8/2 + x9,
     407          52 :       -x0/4 + x1/4 - x10 + x11 - x12 - x2/4 + x3/4 + x9,
     408          52 :       x0/4 - x1/4 + x10 - x11 + x12 + x2/4 - x3/4 - x9,
     409          52 :       -x0/4 + x1/4 + x2/4 - x3/4 - x6/2 + x8/2,
     410          52 :       x0/4 - x1/4 - x2/4 + x3/4 + x6/2 - x8/2,
     411          52 :       -x0/4 - x1/4 + x2/4 + x3/4 + x5/2 - x7/2,
     412          52 :       x0/4 + x1/4 - x2/4 - x3/4 - x5/2 + x7/2
     413        1040 :     };
     414             : 
     415             :   // The (xi, eta, zeta) exponents for each of the dx_dxi terms
     416             :   static const int dx_dxi_exponents[14][3] =
     417             :     {
     418             :       {0, 0, 0},
     419             :       {0, 0, 1},
     420             :       {0, 0, 2},
     421             :       {0, 0, 3},
     422             :       {0, 1, 0},
     423             :       {0, 1, 1},
     424             :       {0, 1, 2},
     425             :       {0, 2, 0},
     426             :       {0, 2, 1},
     427             :       {1, 0, 0},
     428             :       {1, 0, 1},
     429             :       {1, 0, 2},
     430             :       {1, 1, 0},
     431             :       {1, 1, 1}
     432             :     };
     433             : 
     434             :   // The (xi, eta, zeta) exponents for each of the dx_deta terms
     435             :   static const int dx_deta_exponents[14][3] =
     436             :     {
     437             :       {0, 0, 0},
     438             :       {0, 0, 1},
     439             :       {0, 0, 2},
     440             :       {0, 0, 3},
     441             :       {0, 1, 0},
     442             :       {0, 1, 1},
     443             :       {0, 1, 2},
     444             :       {1, 0, 0},
     445             :       {1, 0, 1},
     446             :       {1, 0, 2},
     447             :       {1, 1, 0},
     448             :       {1, 1, 1},
     449             :       {2, 0, 0},
     450             :       {2, 0, 1}
     451             :     };
     452             : 
     453             :   // The (xi, eta, zeta) exponents for each of the dx_dzeta terms
     454             :   static const int dx_dzeta_exponents[19][3] =
     455             :     {
     456             :       {0, 0, 0},
     457             :       {0, 0, 1},
     458             :       {0, 0, 2},
     459             :       {0, 0, 3},
     460             :       {0, 0, 4},
     461             :       {0, 1, 0},
     462             :       {0, 1, 1},
     463             :       {0, 1, 2},
     464             :       {0, 1, 3},
     465             :       {1, 0, 0},
     466             :       {1, 0, 1},
     467             :       {1, 0, 2},
     468             :       {1, 0, 3},
     469             :       {1, 1, 0},
     470             :       {1, 1, 1},
     471             :       {1, 2, 0},
     472             :       {1, 2, 1},
     473             :       {2, 1, 0},
     474             :       {2, 1, 1},
     475             :     };
     476             : 
     477             :   // Number of points in the quadrature rule
     478          52 :   const int N = 27;
     479             : 
     480             :   // Parameters of the quadrature rule
     481             :   static const Real
     482             :     // Parameters used for (xi, eta) quadrature points.
     483             :     a1 = -7.1805574131988893873307823958101e-01_R,
     484             :     a2 = -5.0580870785392503961340276902425e-01_R,
     485             :     a3 = -2.2850430565396735359574351631314e-01_R,
     486             :     // Parameters used for zeta quadrature points.
     487             :     b1 = 7.2994024073149732155837979012003e-02_R,
     488             :     b2 = 3.4700376603835188472176354340395e-01_R,
     489             :     b3 = 7.0500220988849838312239847758405e-01_R,
     490             :     // There are 9 unique weight values since there are three
     491             :     // for each of the three unique zeta values.
     492             :     w1 = 4.8498876871878584357513834016440e-02_R,
     493             :     w2 = 4.5137737425884574692441981593901e-02_R,
     494             :     w3 = 9.2440441384508327195915094925393e-03_R,
     495             :     w4 = 7.7598202995005734972022134426305e-02_R,
     496             :     w5 = 7.2220379881415319507907170550242e-02_R,
     497             :     w6 = 1.4790470621521332351346415188063e-02_R,
     498             :     w7 = 1.2415712479200917595523541508209e-01_R,
     499             :     w8 = 1.1555260781026451121265147288039e-01_R,
     500             :     w9 = 2.3664752994434131762154264300901e-02_R;
     501             : 
     502             :   // The points and weights of the 3x3x3 quadrature rule
     503             :   static const Real xi[N][3] =
     504             :     {// ^0   ^1  ^2
     505             :       { 1.,  a1, a1*a1},
     506             :       { 1.,  a2, a2*a2},
     507             :       { 1.,  a3, a3*a3},
     508             :       { 1.,  a1, a1*a1},
     509             :       { 1.,  a2, a2*a2},
     510             :       { 1.,  a3, a3*a3},
     511             :       { 1.,  a1, a1*a1},
     512             :       { 1.,  a2, a2*a2},
     513             :       { 1.,  a3, a3*a3},
     514             :       { 1.,  0., 0.   },
     515             :       { 1.,  0., 0.   },
     516             :       { 1.,  0., 0.   },
     517             :       { 1.,  0., 0.   },
     518             :       { 1.,  0., 0.   },
     519             :       { 1.,  0., 0.   },
     520             :       { 1.,  0., 0.   },
     521             :       { 1.,  0., 0.   },
     522             :       { 1.,  0., 0.   },
     523             :       { 1., -a1, a1*a1},
     524             :       { 1., -a2, a2*a2},
     525             :       { 1., -a3, a3*a3},
     526             :       { 1., -a1, a1*a1},
     527             :       { 1., -a2, a2*a2},
     528             :       { 1., -a3, a3*a3},
     529             :       { 1., -a1, a1*a1},
     530             :       { 1., -a2, a2*a2},
     531             :       { 1., -a3, a3*a3}
     532             :     };
     533             : 
     534             :   static const Real eta[N][3] =
     535             :     {// ^0   ^1  ^2
     536             :       { 1.,  a1, a1*a1},
     537             :       { 1.,  a2, a2*a2},
     538             :       { 1.,  a3, a3*a3},
     539             :       { 1.,  0., 0.   },
     540             :       { 1.,  0., 0.   },
     541             :       { 1.,  0., 0.   },
     542             :       { 1., -a1, a1*a1},
     543             :       { 1., -a2, a2*a2},
     544             :       { 1., -a3, a3*a3},
     545             :       { 1.,  a1, a1*a1},
     546             :       { 1.,  a2, a2*a2},
     547             :       { 1.,  a3, a3*a3},
     548             :       { 1.,  0., 0.   },
     549             :       { 1.,  0., 0.   },
     550             :       { 1.,  0., 0.   },
     551             :       { 1., -a1, a1*a1},
     552             :       { 1., -a2, a2*a2},
     553             :       { 1., -a3, a3*a3},
     554             :       { 1.,  a1, a1*a1},
     555             :       { 1.,  a2, a2*a2},
     556             :       { 1.,  a3, a3*a3},
     557             :       { 1.,  0., 0.   },
     558             :       { 1.,  0., 0.   },
     559             :       { 1.,  0., 0.   },
     560             :       { 1., -a1, a1*a1},
     561             :       { 1., -a2, a2*a2},
     562             :       { 1., -a3, a3*a3}
     563             :     };
     564             : 
     565             :   static const Real zeta[N][5] =
     566             :     {// ^0  ^1  ^2     ^3        ^4
     567             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     568             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     569             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     570             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     571             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     572             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     573             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     574             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     575             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     576             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     577             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     578             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     579             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     580             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     581             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     582             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     583             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     584             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     585             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     586             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     587             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     588             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     589             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     590             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3},
     591             :       { 1., b1, b1*b1, b1*b1*b1, b1*b1*b1*b1},
     592             :       { 1., b2, b2*b2, b2*b2*b2, b2*b2*b2*b2},
     593             :       { 1., b3, b3*b3, b3*b3*b3, b3*b3*b3*b3}
     594             :     };
     595             : 
     596             :   static const Real w[N] = {w1, w2, w3, w4, w5, w6, // 0-5
     597             :                             w1, w2, w3, w4, w5, w6, // 6-11
     598             :                             w7, w8, w9, w4, w5, w6, // 12-17
     599             :                             w1, w2, w3, w4, w5, w6, // 18-23
     600             :                             w1, w2, w3};            // 24-26
     601             : 
     602          52 :   Real vol = 0.;
     603        5628 :   for (int q=0; q<N; ++q)
     604             :     {
     605             :       // Compute denominators for the current q.
     606             :       Real
     607        5427 :         den2 = (1. - zeta[q][1])*(1. - zeta[q][1]),
     608        5427 :         den3 = den2*(1. - zeta[q][1]);
     609             : 
     610             :       // Compute dx/dxi and dx/deta at the current q.
     611        1404 :       Point dx_dxi_q, dx_deta_q;
     612       81405 :       for (int c=0; c<14; ++c)
     613             :         {
     614             :           dx_dxi_q +=
     615      114534 :             xi[q][dx_dxi_exponents[c][0]]*
     616       75222 :             eta[q][dx_dxi_exponents[c][1]]*
     617       75978 :             zeta[q][dx_dxi_exponents[c][2]]*dx_dxi[c];
     618             : 
     619             :           dx_deta_q +=
     620      114534 :             xi[q][dx_deta_exponents[c][0]]*
     621       75222 :             eta[q][dx_deta_exponents[c][1]]*
     622       75978 :             zeta[q][dx_deta_exponents[c][2]]*dx_deta[c];
     623             :         }
     624             : 
     625             :       // Compute dx/dzeta at the current q.
     626        1404 :       Point dx_dzeta_q;
     627      108540 :       for (int c=0; c<19; ++c)
     628             :         {
     629             :           dx_dzeta_q +=
     630      155439 :             xi[q][dx_dzeta_exponents[c][0]]*
     631      102087 :             eta[q][dx_dzeta_exponents[c][1]]*
     632      103113 :             zeta[q][dx_dzeta_exponents[c][2]]*dx_dzeta[c];
     633             :         }
     634             : 
     635             :       // Scale everything appropriately
     636        1404 :       dx_dxi_q /= den2;
     637        1404 :       dx_deta_q /= den2;
     638        1404 :       dx_dzeta_q /= den3;
     639             : 
     640             :       // Compute scalar triple product, multiply by weight, and accumulate volume.
     641        6777 :       vol += w[q] * triple_product(dx_dxi_q, dx_deta_q, dx_dzeta_q);
     642             :     }
     643             : 
     644          52 :   return vol;
     645             : }
     646             : 
     647             : 
     648        1188 : void Pyramid13::permute(unsigned int perm_num)
     649             : {
     650         312 :   libmesh_assert_less (perm_num, 4);
     651             : 
     652        2900 :   for (unsigned int i = 0; i != perm_num; ++i)
     653             :     {
     654        1712 :       swap4nodes(0,1,2,3);
     655        1712 :       swap4nodes(5,6,7,8);
     656        1712 :       swap4nodes(9,10,11,12);
     657        1264 :       swap4neighbors(0,1,2,3);
     658             :     }
     659        1188 : }
     660             : 
     661             : 
     662         576 : void Pyramid13::flip(BoundaryInfo * boundary_info)
     663             : {
     664         144 :   libmesh_assert(boundary_info);
     665             : 
     666         576 :   swap2nodes(0,1);
     667         576 :   swap2nodes(2,3);
     668         576 :   swap2nodes(6,8);
     669         576 :   swap2nodes(9,10);
     670         576 :   swap2nodes(11,12);
     671         144 :   swap2neighbors(1,3);
     672         576 :   swap2boundarysides(1,3,boundary_info);
     673         576 :   swap2boundaryedges(1,3,boundary_info);
     674         576 :   swap2boundaryedges(4,5,boundary_info);
     675         576 :   swap2boundaryedges(6,7,boundary_info);
     676         576 : }
     677             : 
     678             : 
     679        2880 : ElemType Pyramid13::side_type (const unsigned int s) const
     680             : {
     681         720 :   libmesh_assert_less (s, 5);
     682        2880 :   if (s < 4)
     683        2304 :     return TRI6;
     684         144 :   return QUAD8;
     685             : }
     686             : 
     687             : 
     688             : } // namespace libMesh

Generated by: LCOV version 1.14