LCOV - code coverage report
Current view: top level - include/geom - cell_tet.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 20 20 100.0 %
Date: 2025-08-19 19:27:09 Functions: 11 12 91.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
       3             : 
       4             : // This library is free software; you can redistribute it and/or
       5             : // modify it under the terms of the GNU Lesser General Public
       6             : // License as published by the Free Software Foundation; either
       7             : // version 2.1 of the License, or (at your option) any later version.
       8             : 
       9             : // This library is distributed in the hope that it will be useful,
      10             : // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12             : // Lesser General Public License for more details.
      13             : 
      14             : // You should have received a copy of the GNU Lesser General Public
      15             : // License along with this library; if not, write to the Free Software
      16             : // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
      17             : 
      18             : 
      19             : 
      20             : #ifndef LIBMESH_CELL_TET_H
      21             : #define LIBMESH_CELL_TET_H
      22             : 
      23             : // Local includes
      24             : #include "libmesh/cell.h"
      25             : 
      26             : namespace libMesh
      27             : {
      28             : 
      29             : /**
      30             :  * The \p Tet is an element in 3D composed of 4 sides.
      31             :  *
      32             :  * \author Benjamin S. Kirk
      33             :  * \date 2002
      34             :  * \brief The base class for all tetrahedral element types.
      35             :  */
      36             : class Tet : public Cell
      37             : {
      38             : public:
      39             : 
      40             :   /**
      41             :    * Default tetrahedral element, takes number of nodes and
      42             :    * parent. Derived classes implement 'true' elements.
      43             :    */
      44    19432678 :   Tet (const unsigned int nn, Elem * p, Node ** nodelinkdata) :
      45    19432678 :     Cell(nn, num_sides, p, _elemlinks_data, nodelinkdata),
      46    19432678 :     _diagonal_selection(INVALID_DIAG)
      47             :   {
      48             :     // Make sure the interior parent isn't undefined
      49             :     if (LIBMESH_DIM > 3)
      50             :       this->set_interior_parent(nullptr);
      51      421842 :   }
      52             : 
      53             :   Tet (Tet &&) = delete;
      54             :   Tet (const Tet &) = delete;
      55             :   Tet & operator= (const Tet &) = delete;
      56             :   Tet & operator= (Tet &&) = delete;
      57      421842 :   virtual ~Tet() = default;
      58             : 
      59             :   /**
      60             :    * \returns The \p Point associated with local \p Node \p i,
      61             :    * in master element rather than physical coordinates.
      62             :    */
      63     2595292 :   virtual Point master_point (const unsigned int i) const override final
      64             :   {
      65       75904 :     libmesh_assert_less(i, this->n_nodes());
      66     2595292 :     return Point(_master_points[i][0],
      67     2595292 :                  _master_points[i][1],
      68     2671196 :                  _master_points[i][2]);
      69             :   }
      70             : 
      71             :   /**
      72             :    * Geometric constants for all Tets
      73             :    */
      74             :   static const int num_sides = 4;
      75             :   static const int num_edges = 6;
      76             :   static const int num_children = 8;
      77             : 
      78             :   /**
      79             :    * \returns 4.
      80             :    */
      81   480372922 :   virtual unsigned int n_sides() const override final { return 4; }
      82             : 
      83             :   /**
      84             :    * \returns 4.  All tetrahedra have 4 vertices.
      85             :    */
      86  2005992573 :   virtual unsigned int n_vertices() const override final { return 4; }
      87             : 
      88             :   /**
      89             :    * \returns 6.  All tetrahedra have 6 edges.
      90             :    */
      91    82730014 :   virtual unsigned int n_edges() const override final { return 6; }
      92             : 
      93             :   /**
      94             :    * \returns 4.  All tetrahedra have 4 faces.
      95             :    */
      96    12031323 :   virtual unsigned int n_faces() const override final { return 4; }
      97             : 
      98             :   /**
      99             :    * \returns 8.
     100             :    */
     101    55206276 :   virtual unsigned int n_children() const override final { return 8; }
     102             : 
     103             :   /**
     104             :    * \returns \p true if the specified edge is on the specified side.
     105             :    */
     106             :   virtual bool is_edge_on_side(const unsigned int e,
     107             :                                const unsigned int s) const override final;
     108             : 
     109             :   /**
     110             :    * Don't hide Elem::key() defined in the base class.
     111             :    */
     112             :   using Elem::key;
     113             : 
     114             :   /**
     115             :    * \returns An id associated with the \p s side of this element.
     116             :    * The id is not necessarily unique, but should be close.
     117             :    */
     118             :   virtual dof_id_type key (const unsigned int s) const override;
     119             : 
     120             :   /**
     121             :    * \returns An id associated with the \p s side of this element, as
     122             :    * defined solely by element vertices.  The id is not necessarily
     123             :    * unique, but should be close.  This is particularly useful in the
     124             :    * \p MeshBase::find_neighbors() routine.
     125             :    */
     126             :   virtual dof_id_type low_order_key (const unsigned int s) const override;
     127             : 
     128             :  /**
     129             :    * \returns \p Tet4::side_nodes_map[side][side_node] after doing some range checking.
     130             :    */
     131             :   virtual unsigned int local_side_node(unsigned int side,
     132             :                                        unsigned int side_node) const override;
     133             : 
     134             :   /**
     135             :    * \returns \p Tet4::edge_nodes_map[edge][edge_node] after doing some range checking.
     136             :    */
     137             :   virtual unsigned int local_edge_node(unsigned int edge,
     138             :                                        unsigned int edge_node) const override;
     139             : 
     140             :   /**
     141             :    * \returns A primitive (3-noded) triangle for face i.
     142             :    */
     143             :   virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final;
     144             : 
     145             :   /**
     146             :    * Rebuilds a primitive (3-noded) triangle for face i.
     147             :    */
     148             :   virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) override final;
     149             : 
     150             :   /**
     151             :    * \returns A quantitative assessment of element quality based on
     152             :    * the quality metric \p q specified by the user.
     153             :    */
     154             :   virtual Real quality (const ElemQuality q) const override;
     155             : 
     156             :   /**
     157             :    * \returns The suggested quality bounds for the hex based on quality
     158             :    * measure \p q.  These are the values suggested by the CUBIT User's
     159             :    * Manual.
     160             :    */
     161             :   virtual std::pair<Real, Real> qual_bounds (const ElemQuality q) const override;
     162             : 
     163             :   /**
     164             :    * This enumeration keeps track of which diagonal is selected during
     165             :    * refinement.  In general there are three possible diagonals to
     166             :    * choose when splitting the octahedron, and by choosing the shortest
     167             :    * one we obtain the best element shape.
     168             :    */
     169             :   enum Diagonal
     170             :     {
     171             :       DIAG_02_13=0,    // diagonal between edges (0,2) and (1,3)
     172             :       DIAG_03_12=1,    // diagonal between edges (0,3) and (1,2)
     173             :       DIAG_01_23=2,    // diagonal between edges (0,1) and (2,3)
     174             :       INVALID_DIAG=99  // diagonal not yet selected
     175             :     };
     176             : 
     177             :   /**
     178             :    * \returns The diagonal that has been selected during refinement.
     179             :    */
     180    33954480 :   Diagonal diagonal_selection () const { return _diagonal_selection; }
     181             : 
     182             :   /**
     183             :    * Allows the user to select the diagonal for the refinement.  This
     184             :    * function may only be called before the element is ever refined.
     185             :    */
     186             :   void select_diagonal (const Diagonal diag) const;
     187             : 
     188             :   virtual std::vector<unsigned int> sides_on_edge(const unsigned int e) const override final;
     189             : 
     190             : 
     191             : #ifdef LIBMESH_ENABLE_AMR
     192             : 
     193             : 
     194             :   /**
     195             :    * Tetrahedral elements permute the embedding matrix depending on which
     196             :    * interior diagonal is used to subdivide into child elements.
     197             :    * But we want to cache topology data based on that matrix.  So we return a
     198             :    * "version number" based on the diagonal selection.
     199             :    */
     200    36098200 :   virtual unsigned int embedding_matrix_version () const override final
     201             :   {
     202    36098200 :     this->choose_diagonal();
     203    36098200 :     return this->diagonal_selection();
     204             :   }
     205             : 
     206             : #endif // LIBMESH_ENABLE_AMR
     207             : 
     208             :   /**
     209             :    * Four sides, three orientations.
     210             :    */
     211     1205053 :   virtual unsigned int n_permutations() const override final { return 12; }
     212             : 
     213             :   virtual bool is_flipped() const override final;
     214             : 
     215             :   virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int n) const override;
     216             : 
     217             :   /**
     218             :    * This maps each edge to the sides that contain said edge.
     219             :    */
     220             :   static const unsigned int edge_sides_map[6][2];
     221             : 
     222             :   virtual bool on_reference_element(const Point & p,
     223             :                                     const Real eps = TOLERANCE) const override final;
     224             : 
     225             : protected:
     226             : 
     227             :   /**
     228             :    * Data for links to parent/neighbor/interior_parent elements.
     229             :    */
     230             :   Elem * _elemlinks_data[5+(LIBMESH_DIM>3)];
     231             : 
     232             :   /**
     233             :    * Master element node locations
     234             :    */
     235             :   static const Real _master_points[14][3];
     236             : 
     237             :   /**
     238             :    * Called by descendant classes with appropriate data to determine
     239             :    * if child c is on side s.  Only works if LIBMESH_ENABLE_AMR.
     240             :    */
     241             :   bool is_child_on_side_helper(const unsigned int c,
     242             :                                const unsigned int s,
     243             :                                const unsigned int checked_nodes[][3] ) const;
     244             : 
     245             :   /**
     246             :    * The currently-selected diagonal used during refinement.
     247             :    * Initialized to INVALID_DIAG.
     248             :    */
     249             :   mutable Diagonal _diagonal_selection;
     250             : 
     251             :   /**
     252             :    * Derived classes use this function to select an initial
     253             :    * diagonal during refinement. The optimal choice is the shortest
     254             :    * of the three.
     255             :    */
     256             :   void choose_diagonal() const;
     257             : 
     258             :   /**
     259             :    * This maps the \f$ j^{th} \f$ node to the (in this case) 3 edge
     260             :    * ids adjacent to the node. The edge numbering matches the ones used
     261             :    * in the derived classes' edge_nodes_map. This data structure
     262             :    * is used in the Tet::edges_adjacent_to_node() override and is
     263             :    * shared by all the derived Tet types.
     264             :    */
     265             :   static const unsigned int adjacent_edges_map[/*num_vertices*/4][/*n_adjacent_edges*/3];
     266             : };
     267             : 
     268             : } // namespace libMesh
     269             : 
     270             : #endif // LIBMESH_CELL_TET_H

Generated by: LCOV version 1.14