LCOV - code coverage report
Current view: top level - src/geom - cell_tet10.C (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4343 (6ea38c) with base 8c3130 Lines: 156 267 58.4 %
Date: 2026-10-13 21:47:33 Functions: 21 25 84.0 %
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_tet10.h"
      21             : #include "libmesh/edge_edge3.h"
      22             : #include "libmesh/face_tri6.h"
      23             : #include "libmesh/enum_io_package.h"
      24             : #include "libmesh/enum_order.h"
      25             : 
      26             : namespace libMesh
      27             : {
      28             : 
      29             : 
      30             : 
      31             : // ------------------------------------------------------------
      32             : // Tet10 class static member initializations
      33             : const int Tet10::num_nodes;
      34             : const int Tet10::nodes_per_side;
      35             : const int Tet10::nodes_per_edge;
      36             : 
      37             : // ------------------------------------------------------------
      38             : // Tet10 class member functions
      39             : 
      40    20169103 : bool Tet10::is_vertex(const unsigned int i) const
      41             : {
      42    20169103 :   if (i < 4)
      43     8267948 :     return true;
      44      764732 :   return false;
      45             : }
      46             : 
      47     1202688 : bool Tet10::is_edge(const unsigned int i) const
      48             : {
      49     1202688 :   if (i < 4)
      50           0 :     return false;
      51      100224 :   return true;
      52             : }
      53             : 
      54           0 : bool Tet10::is_face(const unsigned int) const
      55             : {
      56           0 :   return false;
      57             : }
      58             : 
      59      183704 : bool Tet10::is_node_on_side(const unsigned int n,
      60             :                             const unsigned int s) const
      61             : {
      62       15152 :   libmesh_assert_less (s, n_sides());
      63       15152 :   return std::find(std::begin(side_nodes_map[s]),
      64      183704 :                    std::end(side_nodes_map[s]),
      65      183704 :                    n) != std::end(side_nodes_map[s]);
      66             : }
      67             : 
      68             : std::vector<unsigned>
      69    16269463 : Tet10::nodes_on_side(const unsigned int s) const
      70             : {
      71      761036 :   libmesh_assert_less(s, n_sides());
      72    17030499 :   return {std::begin(side_nodes_map[s]), std::end(side_nodes_map[s])};
      73             : }
      74             : 
      75             : std::vector<unsigned>
      76      180138 : Tet10::nodes_on_edge(const unsigned int e) const
      77             : {
      78       14988 :   libmesh_assert_less(e, n_edges());
      79      195126 :   return {std::begin(edge_nodes_map[e]), std::end(edge_nodes_map[e])};
      80             : }
      81             : 
      82     4622916 : bool Tet10::is_node_on_edge(const unsigned int n,
      83             :                             const unsigned int e) const
      84             : {
      85      168408 :   libmesh_assert_less (e, n_edges());
      86      168408 :   return std::find(std::begin(edge_nodes_map[e]),
      87     4622916 :                    std::end(edge_nodes_map[e]),
      88     4622916 :                    n) != std::end(edge_nodes_map[e]);
      89             : }
      90             : 
      91             : 
      92             : #ifdef LIBMESH_ENABLE_AMR
      93             : 
      94             : // This function only works if LIBMESH_ENABLE_AMR...
      95    11473615 : bool Tet10::is_child_on_side(const unsigned int c,
      96             :                              const unsigned int s) const
      97             : {
      98             :   // Table of local IDs for the midege nodes on the side opposite a given node.
      99             :   // See the ASCII art in the header file for this class to confirm this.
     100    11473615 :   const unsigned int midedge_nodes_opposite[4][3] =
     101             :     {
     102             :       {5,8,9}, // midedge nodes opposite node 0
     103             :       {6,7,9}, // midedge nodes opposite node 1
     104             :       {4,7,8}, // midedge nodes opposite node 2
     105             :       {4,5,6}  // midedge nodes opposite node 3
     106             :     };
     107             : 
     108             :   // Call the base class helper function
     109    11926159 :   return Tet::is_child_on_side_helper(c, s, midedge_nodes_opposite);
     110             : }
     111             : 
     112             : #else
     113             : 
     114             : bool Tet10::is_child_on_side(const unsigned int /*c*/,
     115             :                              const unsigned int /*s*/) const
     116             : {
     117             :   libmesh_not_implemented();
     118             :   return false;
     119             : }
     120             : 
     121             : #endif //LIBMESH_ENABLE_AMR
     122             : 
     123             : 
     124             : 
     125     1387764 : bool Tet10::has_affine_map() const
     126             : {
     127             :   // Make sure edges are straight
     128      221968 :   Point v = this->point(1) - this->point(0);
     129     1498748 :   if (!v.relative_fuzzy_equals
     130     1387764 :       ((this->point(4) - this->point(0))*2, affine_tol))
     131        4752 :     return false;
     132     1436972 :   v = this->point(2) - this->point(1);
     133     1436972 :   if (!v.relative_fuzzy_equals
     134     1330740 :       ((this->point(5) - this->point(1))*2, affine_tol))
     135          96 :     return false;
     136     1435724 :   v = this->point(2) - this->point(0);
     137     1435724 :   if (!v.relative_fuzzy_equals
     138     1329588 :       ((this->point(6) - this->point(0))*2, affine_tol))
     139           0 :     return false;
     140     1435724 :   v = this->point(3) - this->point(0);
     141     1435724 :   if (!v.relative_fuzzy_equals
     142     1329588 :       ((this->point(7) - this->point(0))*2, affine_tol))
     143         144 :     return false;
     144     1433852 :   v = this->point(3) - this->point(1);
     145     1433852 :   if (!v.relative_fuzzy_equals
     146     1327860 :       ((this->point(8) - this->point(1))*2, affine_tol))
     147           0 :     return false;
     148     1433852 :   v = this->point(3) - this->point(2);
     149     1433852 :   if (!v.relative_fuzzy_equals
     150     1327860 :       ((this->point(9) - this->point(2))*2, affine_tol))
     151           0 :     return false;
     152      105992 :   return true;
     153             : }
     154             : 
     155             : 
     156             : 
     157   179304460 : Order Tet10::default_order() const
     158             : {
     159   179304460 :   return SECOND;
     160             : }
     161             : 
     162             : 
     163             : 
     164    44020487 : unsigned int Tet10::local_side_node(unsigned int side,
     165             :                                     unsigned int side_node) const
     166             : {
     167     1883678 :   libmesh_assert_less (side, this->n_sides());
     168     1883678 :   libmesh_assert_less (side_node, Tet10::nodes_per_side);
     169             : 
     170    44020487 :   return Tet10::side_nodes_map[side][side_node];
     171             : }
     172             : 
     173             : 
     174             : 
     175    88194489 : unsigned int Tet10::local_edge_node(unsigned int edge,
     176             :                                     unsigned int edge_node) const
     177             : {
     178     6930906 :   libmesh_assert_less (edge, this->n_edges());
     179     6930906 :   libmesh_assert_less (edge_node, Tet10::nodes_per_edge);
     180             : 
     181    88194489 :   return Tet10::edge_nodes_map[edge][edge_node];
     182             : }
     183             : 
     184             : 
     185             : 
     186     3124496 : std::unique_ptr<Elem> Tet10::build_side_ptr (const unsigned int i)
     187             : {
     188     3124496 :   return this->simple_build_side_ptr<Tri6, Tet10>(i);
     189             : }
     190             : 
     191             : 
     192             : 
     193     5716976 : void Tet10::build_side_ptr (std::unique_ptr<Elem> & side,
     194             :                             const unsigned int i)
     195             : {
     196     5716976 :   this->simple_build_side_ptr<Tet10>(side, i, TRI6);
     197     5716976 : }
     198             : 
     199             : 
     200             : 
     201     5246393 : std::unique_ptr<Elem> Tet10::build_edge_ptr (const unsigned int i)
     202             : {
     203     5246393 :   return this->simple_build_edge_ptr<Edge3,Tet10>(i);
     204             : }
     205             : 
     206             : 
     207             : 
     208       15918 : void Tet10::build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i)
     209             : {
     210       15918 :   this->simple_build_edge_ptr<Tet10>(edge, i, EDGE3);
     211       15918 : }
     212             : 
     213             : 
     214             : 
     215           0 : void Tet10::connectivity(const unsigned int sc,
     216             :                          const IOPackage iop,
     217             :                          std::vector<dof_id_type> & conn) const
     218             : {
     219           0 :   libmesh_assert(_nodes);
     220           0 :   libmesh_assert_less (sc, this->n_sub_elem());
     221           0 :   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
     222             : 
     223           0 :   switch (iop)
     224             :     {
     225           0 :     case TECPLOT:
     226             :       {
     227           0 :         conn.resize(8);
     228           0 :         switch (sc)
     229             :           {
     230             : 
     231             : 
     232             :             // Linear sub-tet 0
     233           0 :           case 0:
     234             : 
     235           0 :             conn[0] = this->node_id(0)+1;
     236           0 :             conn[1] = this->node_id(4)+1;
     237           0 :             conn[2] = this->node_id(6)+1;
     238           0 :             conn[3] = this->node_id(6)+1;
     239           0 :             conn[4] = this->node_id(7)+1;
     240           0 :             conn[5] = this->node_id(7)+1;
     241           0 :             conn[6] = this->node_id(7)+1;
     242           0 :             conn[7] = this->node_id(7)+1;
     243             : 
     244           0 :             return;
     245             : 
     246             :             // Linear sub-tet 1
     247           0 :           case 1:
     248             : 
     249           0 :             conn[0] = this->node_id(4)+1;
     250           0 :             conn[1] = this->node_id(1)+1;
     251           0 :             conn[2] = this->node_id(5)+1;
     252           0 :             conn[3] = this->node_id(5)+1;
     253           0 :             conn[4] = this->node_id(8)+1;
     254           0 :             conn[5] = this->node_id(8)+1;
     255           0 :             conn[6] = this->node_id(8)+1;
     256           0 :             conn[7] = this->node_id(8)+1;
     257             : 
     258           0 :             return;
     259             : 
     260             :             // Linear sub-tet 2
     261           0 :           case 2:
     262             : 
     263           0 :             conn[0] = this->node_id(5)+1;
     264           0 :             conn[1] = this->node_id(2)+1;
     265           0 :             conn[2] = this->node_id(6)+1;
     266           0 :             conn[3] = this->node_id(6)+1;
     267           0 :             conn[4] = this->node_id(9)+1;
     268           0 :             conn[5] = this->node_id(9)+1;
     269           0 :             conn[6] = this->node_id(9)+1;
     270           0 :             conn[7] = this->node_id(9)+1;
     271             : 
     272           0 :             return;
     273             : 
     274             :             // Linear sub-tet 3
     275           0 :           case 3:
     276             : 
     277           0 :             conn[0] = this->node_id(7)+1;
     278           0 :             conn[1] = this->node_id(8)+1;
     279           0 :             conn[2] = this->node_id(9)+1;
     280           0 :             conn[3] = this->node_id(9)+1;
     281           0 :             conn[4] = this->node_id(3)+1;
     282           0 :             conn[5] = this->node_id(3)+1;
     283           0 :             conn[6] = this->node_id(3)+1;
     284           0 :             conn[7] = this->node_id(3)+1;
     285             : 
     286           0 :             return;
     287             : 
     288             :             // Linear sub-tet 4
     289           0 :           case 4:
     290             : 
     291           0 :             conn[0] = this->node_id(4)+1;
     292           0 :             conn[1] = this->node_id(8)+1;
     293           0 :             conn[2] = this->node_id(6)+1;
     294           0 :             conn[3] = this->node_id(6)+1;
     295           0 :             conn[4] = this->node_id(7)+1;
     296           0 :             conn[5] = this->node_id(7)+1;
     297           0 :             conn[6] = this->node_id(7)+1;
     298           0 :             conn[7] = this->node_id(7)+1;
     299             : 
     300           0 :             return;
     301             : 
     302             :             // Linear sub-tet 5
     303           0 :           case 5:
     304             : 
     305           0 :             conn[0] = this->node_id(4)+1;
     306           0 :             conn[1] = this->node_id(5)+1;
     307           0 :             conn[2] = this->node_id(6)+1;
     308           0 :             conn[3] = this->node_id(6)+1;
     309           0 :             conn[4] = this->node_id(8)+1;
     310           0 :             conn[5] = this->node_id(8)+1;
     311           0 :             conn[6] = this->node_id(8)+1;
     312           0 :             conn[7] = this->node_id(8)+1;
     313             : 
     314           0 :             return;
     315             : 
     316             :             // Linear sub-tet 6
     317           0 :           case 6:
     318             : 
     319           0 :             conn[0] = this->node_id(5)+1;
     320           0 :             conn[1] = this->node_id(9)+1;
     321           0 :             conn[2] = this->node_id(6)+1;
     322           0 :             conn[3] = this->node_id(6)+1;
     323           0 :             conn[4] = this->node_id(8)+1;
     324           0 :             conn[5] = this->node_id(8)+1;
     325           0 :             conn[6] = this->node_id(8)+1;
     326           0 :             conn[7] = this->node_id(8)+1;
     327             : 
     328           0 :             return;
     329             : 
     330             :             // Linear sub-tet 7
     331           0 :           case 7:
     332             : 
     333           0 :             conn[0] = this->node_id(7)+1;
     334           0 :             conn[1] = this->node_id(6)+1;
     335           0 :             conn[2] = this->node_id(9)+1;
     336           0 :             conn[3] = this->node_id(9)+1;
     337           0 :             conn[4] = this->node_id(8)+1;
     338           0 :             conn[5] = this->node_id(8)+1;
     339           0 :             conn[6] = this->node_id(8)+1;
     340           0 :             conn[7] = this->node_id(8)+1;
     341             : 
     342           0 :             return;
     343             : 
     344             : 
     345           0 :           default:
     346           0 :             libmesh_error_msg("Invalid sc = " << sc);
     347             :           }
     348             :       }
     349             : 
     350           0 :     case VTK:
     351             :       {
     352             :         // VTK connectivity for VTK_QUADRATIC_TETRA matches libMesh's own.
     353           0 :         conn.resize(Tet10::num_nodes);
     354           0 :         for (auto i : index_range(conn))
     355           0 :           conn[i] = this->node_id(i);
     356           0 :         return;
     357             :       }
     358             : 
     359           0 :     default:
     360           0 :       libmesh_error_msg("Unsupported IO package " << iop);
     361             :     }
     362             : }
     363             : 
     364             : 
     365             : 
     366             : const unsigned short int Tet10::_second_order_vertex_child_number[10] =
     367             :   {
     368             :     99,99,99,99, // Vertices
     369             :     0,1,0,0,1,2  // Edges
     370             :   };
     371             : 
     372             : 
     373             : 
     374             : const unsigned short int Tet10::_second_order_vertex_child_index[10] =
     375             :   {
     376             :     99,99,99,99, // Vertices
     377             :     1,2,2,3,3,3  // Edges
     378             :   };
     379             : 
     380             : 
     381             : 
     382             : std::pair<unsigned short int, unsigned short int>
     383           0 : Tet10::second_order_child_vertex (const unsigned int n) const
     384             : {
     385           0 :   libmesh_assert_greater_equal (n, this->n_vertices());
     386           0 :   libmesh_assert_less (n, this->n_nodes());
     387           0 :   return std::pair<unsigned short int, unsigned short int>
     388           0 :     (_second_order_vertex_child_number[n],
     389           0 :      _second_order_vertex_child_index[n]);
     390             : }
     391             : 
     392             : 
     393             : 
     394    10744320 : unsigned short int Tet10::second_order_adjacent_vertex (const unsigned int n,
     395             :                                                         const unsigned int v) const
     396             : {
     397      318720 :   libmesh_assert_greater_equal (n, this->n_vertices());
     398      318720 :   libmesh_assert_less (n, this->n_nodes());
     399      318720 :   libmesh_assert_less (v, 2);
     400    10744320 :   return _second_order_adjacent_vertices[n-this->n_vertices()][v];
     401             : }
     402             : 
     403             : 
     404             : 
     405             : const unsigned short int Tet10::_second_order_adjacent_vertices[6][2] =
     406             :   {
     407             :     {0, 1}, // vertices adjacent to node 4
     408             :     {1, 2}, // vertices adjacent to node 5
     409             :     {0, 2}, // vertices adjacent to node 6
     410             :     {0, 3}, // vertices adjacent to node 7
     411             :     {1, 3}, // vertices adjacent to node 8
     412             :     {2, 3}  // vertices adjacent to node 9
     413             :   };
     414             : 
     415             : 
     416             : 
     417             : 
     418             : 
     419             : #ifdef LIBMESH_ENABLE_AMR
     420             : 
     421             : const Real Tet10::_embedding_matrix[Tet10::num_children][Tet10::num_nodes][Tet10::num_nodes] =
     422             :   {
     423             :     // embedding matrix for child 0
     424             :     {
     425             :       //    0      1      2      3      4      5      6      7      8      9
     426             :       {    1.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.}, // 0
     427             :       {    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.,    0.}, // 1
     428             :       {    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.}, // 2
     429             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.}, // 3
     430             :       { 0.375,-0.125,    0.,    0.,  0.75,    0.,    0.,    0.,    0.,    0.}, // 4
     431             :       {    0.,-0.125,-0.125,    0.,   0.5,  0.25,   0.5,    0.,    0.,    0.}, // 5
     432             :       { 0.375,    0.,-0.125,    0.,    0.,    0.,  0.75,    0.,    0.,    0.}, // 6
     433             :       { 0.375,    0.,    0.,-0.125,    0.,    0.,    0.,  0.75,    0.,    0.}, // 7
     434             :       {    0.,-0.125,    0.,-0.125,   0.5,    0.,    0.,   0.5,  0.25,    0.}, // 8
     435             :       {    0.,    0.,-0.125,-0.125,    0.,    0.,   0.5,   0.5,    0.,  0.25}  // 9
     436             :     },
     437             : 
     438             :     // embedding matrix for child 1
     439             :     {
     440             :       //    0      1      2      3      4      5      6      7      8      9
     441             :       {    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.,    0.}, // 0
     442             :       {    0.,    1.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.}, // 1
     443             :       {    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.}, // 2
     444             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.}, // 3
     445             :       {-0.125, 0.375,    0.,    0.,  0.75,    0.,    0.,    0.,    0.,    0.}, // 4
     446             :       {    0., 0.375,-0.125,    0.,    0.,  0.75,    0.,    0.,    0.,    0.}, // 5
     447             :       {-0.125,    0.,-0.125,    0.,   0.5,   0.5,  0.25,    0.,    0.,    0.}, // 6
     448             :       {-0.125,    0.,    0.,-0.125,   0.5,    0.,    0.,  0.25,   0.5,    0.}, // 7
     449             :       {    0., 0.375,    0.,-0.125,    0.,    0.,    0.,    0.,  0.75,    0.}, // 8
     450             :       {    0.,    0.,-0.125,-0.125,    0.,   0.5,    0.,    0.,   0.5,  0.25}  // 9
     451             :     },
     452             : 
     453             :     // embedding matrix for child 2
     454             :     {
     455             :       //    0      1      2      3      4      5      6      7      8      9
     456             :       {    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.}, // 0
     457             :       {    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.}, // 1
     458             :       {    0.,    0.,    1.,    0.,    0.,    0.,    0.,    0.,    0.,    0.}, // 2
     459             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.}, // 3
     460             :       {-0.125,-0.125,    0.,    0.,  0.25,   0.5,   0.5,    0.,    0.,    0.}, // 4
     461             :       {    0.,-0.125, 0.375,    0.,    0.,  0.75,    0.,    0.,    0.,    0.}, // 5
     462             :       {-0.125,    0., 0.375,    0.,    0.,    0.,  0.75,    0.,    0.,    0.}, // 6
     463             :       {-0.125,    0.,    0.,-0.125,    0.,    0.,   0.5,  0.25,    0.,   0.5}, // 7
     464             :       {    0.,-0.125,    0.,-0.125,    0.,   0.5,    0.,    0.,  0.25,   0.5}, // 8
     465             :       {    0.,    0., 0.375,-0.125,    0.,    0.,    0.,    0.,    0.,  0.75}  // 9
     466             :     },
     467             : 
     468             :     // embedding matrix for child 3
     469             :     {
     470             :       //    0      1      2      3      4      5      6      7      8      9
     471             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.}, // 0
     472             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.}, // 1
     473             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.}, // 2
     474             :       {    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.,    0.,    0.}, // 3
     475             :       {-0.125,-0.125,    0.,    0.,  0.25,    0.,    0.,   0.5,   0.5,    0.}, // 4
     476             :       {    0.,-0.125,-0.125,    0.,    0.,  0.25,    0.,    0.,   0.5,   0.5}, // 5
     477             :       {-0.125,    0.,-0.125,    0.,    0.,    0.,  0.25,   0.5,    0.,   0.5}, // 6
     478             :       {-0.125,    0.,    0., 0.375,    0.,    0.,    0.,  0.75,    0.,    0.}, // 7
     479             :       {    0.,-0.125,    0., 0.375,    0.,    0.,    0.,    0.,  0.75,    0.}, // 8
     480             :       {    0.,    0.,-0.125, 0.375,    0.,    0.,    0.,    0.,    0.,  0.75}  // 9
     481             :     },
     482             : 
     483             :     // embedding matrix for child 4
     484             :     {
     485             :       //    0      1      2      3      4      5      6      7      8      9
     486             :       {    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.,    0.}, // 0
     487             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.}, // 1
     488             :       {    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.}, // 2
     489             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.}, // 3
     490             :       {-0.125,    0.,    0.,-0.125,   0.5,    0.,    0.,  0.25,   0.5,    0.}, // 4
     491             :       {-0.125,-0.125,-0.125,-0.125,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25}, // 5
     492             :       {    0.,-0.125,-0.125,    0.,   0.5,  0.25,   0.5,    0.,    0.,    0.}, // 6
     493             :       {    0.,-0.125,    0.,-0.125,   0.5,    0.,    0.,   0.5,  0.25,    0.}, // 7
     494             :       {-0.125,-0.125,    0.,    0.,  0.25,    0.,    0.,   0.5,   0.5,    0.}, // 8
     495             :       {    0.,    0.,-0.125,-0.125,    0.,    0.,   0.5,   0.5,    0.,  0.25}  // 9
     496             :     },
     497             : 
     498             :     // embedding matrix for child 5
     499             :     {
     500             :       //    0      1      2      3      4      5      6      7      8      9
     501             :       {    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.,    0.}, // 0
     502             :       {    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.}, // 1
     503             :       {    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.}, // 2
     504             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.}, // 3
     505             :       {-0.125,    0.,-0.125,    0.,   0.5,   0.5,  0.25,    0.,    0.,    0.}, // 4
     506             :       {-0.125,-0.125,    0.,    0.,  0.25,   0.5,   0.5,    0.,    0.,    0.}, // 5
     507             :       {    0.,-0.125,-0.125,    0.,   0.5,  0.25,   0.5,    0.,    0.,    0.}, // 6
     508             :       {-0.125,    0.,    0.,-0.125,   0.5,    0.,    0.,  0.25,   0.5,    0.}, // 7
     509             :       {    0.,    0.,-0.125,-0.125,    0.,   0.5,    0.,    0.,   0.5,  0.25}, // 8
     510             :       {-0.125,-0.125,-0.125,-0.125,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25}  // 9
     511             :     },
     512             : 
     513             :     // embedding matrix for child 6
     514             :     {
     515             :       //    0      1      2      3      4      5      6      7      8      9
     516             :       {    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.}, // 0
     517             :       {    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.,    0.}, // 1
     518             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.}, // 2
     519             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.}, // 3
     520             :       {-0.125,-0.125,    0.,    0.,  0.25,   0.5,   0.5,    0.,    0.,    0.}, // 4
     521             :       {    0.,-0.125,    0.,-0.125,    0.,   0.5,    0.,    0.,  0.25,   0.5}, // 5
     522             :       {-0.125,    0.,    0.,-0.125,    0.,    0.,   0.5,  0.25,    0.,   0.5}, // 6
     523             :       {-0.125,-0.125,-0.125,-0.125,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25}, // 7
     524             :       {    0.,    0.,-0.125,-0.125,    0.,   0.5,    0.,    0.,   0.5,  0.25}, // 8
     525             :       {    0.,-0.125,-0.125,    0.,    0.,  0.25,    0.,    0.,   0.5,   0.5}  // 9
     526             :     },
     527             : 
     528             :     // embedding matrix for child 7
     529             :     {
     530             :       //    0      1      2      3      4      5      6      7      8      9
     531             :       {    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.,    0.}, // 0
     532             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.}, // 1
     533             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.}, // 2
     534             :       {    0.,    0.,    0.,    0.,    0.,    0.,    0.,    1.,    0.,    0.}, // 3
     535             :       {-0.125,-0.125,-0.125,-0.125,  0.25,  0.25,  0.25,  0.25,  0.25,  0.25}, // 4
     536             :       {    0.,-0.125,-0.125,    0.,    0.,  0.25,    0.,    0.,   0.5,   0.5}, // 5
     537             :       {-0.125,    0.,    0.,-0.125,    0.,    0.,   0.5,  0.25,    0.,   0.5}, // 6
     538             :       {    0.,    0.,-0.125,-0.125,    0.,    0.,   0.5,   0.5,    0.,  0.25}, // 7
     539             :       {-0.125,-0.125,    0.,    0.,  0.25,    0.,    0.,   0.5,   0.5,    0.}, // 8
     540             :       {-0.125,    0.,-0.125,    0.,    0.,    0.,  0.25,   0.5,    0.,   0.5}  // 9
     541             :     }
     542             :   };
     543             : 
     544             : 
     545             : 
     546    26690145 : Real Tet10::embedding_matrix (const unsigned int i,
     547             :                               const unsigned int j,
     548             :                               const unsigned int k) const
     549             : {
     550             :   // Choose an optimal diagonal, if one has not already been selected
     551    26690145 :   this->choose_diagonal();
     552             : 
     553             :   // Permuted j and k indices
     554             :   unsigned int
     555     1094408 :     jp=j,
     556     1094408 :     kp=k;
     557             : 
     558    26690145 :   if ((i>3) && (this->_diagonal_selection!=DIAG_02_13))
     559             :     {
     560             :       // Just the enum value cast to an unsigned int...
     561      177840 :       const unsigned ds = static_cast<unsigned int>(this->_diagonal_selection); // == 1 or 2
     562             : 
     563             :       // Instead of doing a lot of arithmetic, use these
     564             :       // straightforward arrays for the permutations.  Note that 3 ->
     565             :       // 3, and the first array consists of "forward" permutations of
     566             :       // the sets {0,1,2}, {4,5,6}, and {7,8,9} while the second array
     567             :       // consists of "reverse" permutations of the same sets.
     568     4427598 :       const unsigned int perms[2][10] =
     569             :         {
     570             :           {1, 2, 0, 3, 5, 6, 4, 8, 9, 7},
     571             :           {2, 0, 1, 3, 6, 4, 5, 9, 7, 8}
     572             :         };
     573             : 
     574             :       // Permute j
     575     4427598 :       jp = perms[ds-1][j];
     576             :       //      if (jp<3)
     577             :       //        jp = (jp+ds)%3;
     578             :       //      else if (jp>3)
     579             :       //        jp = (jp-1+ds)%3 + 1 + 3*((jp-1)/3);
     580             : 
     581             :       // Permute k
     582     4427598 :       kp = perms[ds-1][k];
     583             :       //      if (kp<3)
     584             :       //        kp = (kp+ds)%3;
     585             :       //      else if (kp>3)
     586             :       //        kp = (kp-1+ds)%3 + 1 + 3*((kp-1)/3);
     587             :     }
     588             : 
     589             :   // Debugging:
     590             :   // libMesh::err << "Selected diagonal " << _diagonal_selection << std::endl;
     591             :   // libMesh::err << "j=" << j << std::endl;
     592             :   // libMesh::err << "k=" << k << std::endl;
     593             :   // libMesh::err << "jp=" << jp << std::endl;
     594             :   // libMesh::err << "kp=" << kp << std::endl;
     595             : 
     596             :   // Call embedding matrix with permuted indices
     597    26690145 :   return this->_embedding_matrix[i][jp][kp];
     598             : }
     599             : 
     600             : #endif // #ifdef LIBMESH_ENABLE_AMR
     601             : 
     602             : 
     603             : 
     604      140448 : Real Tet10::volume () const
     605             : {
     606             :   // This specialization is good for Lagrange mappings only in general
     607      140448 :   if (this->mapping_type() != LAGRANGE_MAP)
     608        2653 :     return this->Elem::volume();
     609             : 
     610             :   // Make copies of our points.  It makes the subsequent calculations a bit
     611             :   // shorter and avoids dereferencing the same pointer multiple times.
     612             :   Point
     613      192945 :     x0 = point(0), x1 = point(1), x2 = point(2), x3 = point(3), x4 = point(4),
     614      181915 :     x5 = point(5), x6 = point(6), x7 = point(7), x8 = point(8), x9 = point(9);
     615             : 
     616             :   // The constant components of the dx/dxi vector, linear in xi, eta, zeta.
     617             :   // These were copied directly from the output of a Python script.
     618             :   Point dx_dxi[4] =
     619             :     {
     620       16408 :       -3*x0 - x1 + 4*x4,         // constant
     621       16408 :       4*x0 - 4*x4 - 4*x7 + 4*x8, // zeta
     622       16408 :       4*x0 - 4*x4 + 4*x5 - 4*x6, // eta
     623       16408 :       4*x0 + 4*x1 - 8*x4         // xi
     624       82040 :     };
     625             : 
     626             :   // The constant components of the dx/deta vector, linear in xi, eta, zeta.
     627             :   // These were copied directly from the output of a Python script.
     628             :   Point dx_deta[4] =
     629             :     {
     630       16408 :       -3*x0 - x2 + 4*x6,         // constant
     631       16408 :       4*x0 - 4*x6 - 4*x7 + 4*x9, // zeta
     632       16408 :       4*x0 + 4*x2 - 8*x6,        // eta
     633       16408 :       4*x0 - 4*x4 + 4*x5 - 4*x6  // xi
     634       82040 :     };
     635             : 
     636             :   // The constant components of the dx/dzeta vector, linear in xi, eta, zeta.
     637             :   // These were copied directly from the output of a Python script.
     638             :   Point dx_dzeta[4] =
     639             :     {
     640       16408 :       -3*x0 - x3 + 4*x7,         // constant
     641       16408 :       4*x0 + 4*x3 - 8*x7,        // zeta
     642       16408 :       4*x0 - 4*x6 - 4*x7 + 4*x9, // eta
     643       16408 :       4*x0 - 4*x4 - 4*x7 + 4*x8  // xi
     644       82040 :     };
     645             : 
     646             :   // 2x2x2 conical quadrature rule.  Note: there is also a five point
     647             :   // rule for tets with a negative weight which would be cheaper, but
     648             :   // we'll use this one to preclude any possible issues with
     649             :   // cancellation error.
     650       16408 :   const int N = 8;
     651             :   static const Real w[N] =
     652             :     {
     653             :       3.6979856358852914509238091810505e-02_R,
     654             :       1.6027040598476613723156741868689e-02_R,
     655             :       2.1157006454524061178256145400082e-02_R,
     656             :       9.1694299214797439226823542540576e-03_R,
     657             :       3.6979856358852914509238091810505e-02_R,
     658             :       1.6027040598476613723156741868689e-02_R,
     659             :       2.1157006454524061178256145400082e-02_R,
     660             :       9.1694299214797439226823542540576e-03_R
     661             :     };
     662             : 
     663             :   static const Real xi[N] =
     664             :     {
     665             :       1.2251482265544137786674043037115e-01_R,
     666             :       5.4415184401122528879992623629551e-01_R,
     667             :       1.2251482265544137786674043037115e-01_R,
     668             :       5.4415184401122528879992623629551e-01_R,
     669             :       1.2251482265544137786674043037115e-01_R,
     670             :       5.4415184401122528879992623629551e-01_R,
     671             :       1.2251482265544137786674043037115e-01_R,
     672             :       5.4415184401122528879992623629551e-01_R
     673             :     };
     674             : 
     675             :   static const Real eta[N] =
     676             :     {
     677             :       1.3605497680284601717109468420738e-01_R,
     678             :       7.0679724159396903069267439165167e-02_R,
     679             :       5.6593316507280088053551297149570e-01_R,
     680             :       2.9399880063162286589079157179842e-01_R,
     681             :       1.3605497680284601717109468420738e-01_R,
     682             :       7.0679724159396903069267439165167e-02_R,
     683             :       5.6593316507280088053551297149570e-01_R,
     684             :       2.9399880063162286589079157179842e-01_R
     685             :     };
     686             : 
     687             :   static const Real zeta[N] =
     688             :     {
     689             :       1.5668263733681830907933725249176e-01_R,
     690             :       8.1395667014670255076709592007207e-02_R,
     691             :       6.5838687060044409936029672711329e-02_R,
     692             :       3.4202793236766414300604458388142e-02_R,
     693             :       5.8474756320489429588282763292971e-01_R,
     694             :       3.0377276481470755305409673253211e-01_R,
     695             :       2.4571332521171333166171692542182e-01_R,
     696             :       1.2764656212038543100867773351792e-01_R
     697             :     };
     698             : 
     699       16408 :   Real vol = 0.;
     700     1240155 :   for (int q=0; q<N; ++q)
     701             :     {
     702             :       // Compute dx_dxi, dx_deta, dx_dzeta at the current quadrature point.
     703             :       Point
     704      395984 :         dx_dxi_q   = dx_dxi[0]   + zeta[q]*dx_dxi[1]   + eta[q]*dx_dxi[2]   + xi[q]*dx_dxi[3],
     705      131264 :         dx_deta_q  = dx_deta[0]  + zeta[q]*dx_deta[1]  + eta[q]*dx_deta[2]  + xi[q]*dx_deta[3],
     706      131264 :         dx_dzeta_q = dx_dzeta[0] + zeta[q]*dx_dzeta[1] + eta[q]*dx_dzeta[2] + xi[q]*dx_dzeta[3];
     707             : 
     708             :       // Compute scalar triple product, multiply by weight, and accumulate volume.
     709     1190600 :       vol += w[q] * triple_product(dx_dxi_q, dx_deta_q, dx_dzeta_q);
     710             :     }
     711             : 
     712       16408 :   return vol;
     713             : }
     714             : 
     715             : 
     716      278784 : void Tet10::permute(unsigned int perm_num)
     717             : {
     718       12672 :   libmesh_assert_less (perm_num, 12);
     719             : 
     720      278784 :   const unsigned int side = perm_num % 4;
     721      278784 :   const unsigned int rotate = perm_num / 4;
     722             : 
     723      573888 :   for (unsigned int i = 0; i != rotate; ++i)
     724             :     {
     725      295104 :       swap3nodes(0,1,2);
     726      281952 :       swap3nodes(4,5,6);
     727      281952 :       swap3nodes(7,8,9);
     728      281952 :       swap3neighbors(1,2,3);
     729             :     }
     730             : 
     731      278784 :   switch (side) {
     732        3648 :   case 0:
     733        3648 :     break;
     734       61536 :   case 1:
     735       61536 :     swap3nodes(0,2,3);
     736       58608 :     swap3nodes(4,5,8);
     737       58608 :     swap3nodes(6,9,7);
     738       58608 :     swap3neighbors(0,2,1);
     739       58608 :     break;
     740       53376 :   case 2:
     741       53376 :     swap3nodes(2,0,3);
     742       50688 :     swap3nodes(5,4,8);
     743       50688 :     swap3nodes(6,7,9);
     744       50688 :     swap3neighbors(0,1,2);
     745       50688 :     break;
     746       77856 :   case 3:
     747       77856 :     swap3nodes(2,1,3);
     748       74448 :     swap3nodes(5,8,9);
     749       74448 :     swap3nodes(6,4,7);
     750       74448 :     swap3neighbors(0,1,3);
     751       74448 :     break;
     752           0 :   default:
     753           0 :     libmesh_error();
     754             :   }
     755      278784 : }
     756             : 
     757             : 
     758        6912 : void Tet10::flip(BoundaryInfo * boundary_info)
     759             : {
     760         576 :   libmesh_assert(boundary_info);
     761             : 
     762        6912 :   swap2nodes(0,2);
     763        6912 :   swap2nodes(4,5);
     764        6912 :   swap2nodes(7,9);
     765         576 :   swap2neighbors(1,2);
     766        6912 :   swap2boundarysides(1,2,boundary_info);
     767        6912 :   swap2boundaryedges(0,1,boundary_info);
     768        6912 :   swap2boundaryedges(3,5,boundary_info);
     769        6912 : }
     770             : 
     771             : 
     772    30078532 : ElemType Tet10::side_type (const unsigned int libmesh_dbg_var(s)) const
     773             : {
     774     1316904 :   libmesh_assert_less (s, 4);
     775    30078532 :   return TRI6;
     776             : }
     777             : 
     778             : 
     779             : } // namespace libMesh

Generated by: LCOV version 1.14