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 : 20 : #ifndef LIBMESH_CELL_TET10_H 21 : #define LIBMESH_CELL_TET10_H 22 : 23 : // Local includes 24 : #include "libmesh/cell_tet.h" 25 : #include "libmesh/cell_tet4.h" 26 : #include "libmesh/fe_reference_element_traits.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : /** 32 : * The \p Tet10 is an element in 3D composed of 10 nodes. It is 33 : * numbered like this: 34 : * 35 : * \verbatim 36 : * 3 37 : * TET10: o 38 : * /|\ 39 : * / | \ 40 : * 7 / | \9 41 : * o | o zeta 42 : * / |8 \ ^ 43 : * / o \ | 44 : * / 6 | \ | 45 : * 0 o.....o.|.......o 2 o---> eta 46 : * \ | / \ 47 : * \ | / \ 48 : * \ | / xi (out of page) 49 : * 4 o | o 5 50 : * \ | / 51 : * \ | / 52 : * \|/ 53 : * o 54 : * 1 55 : * \endverbatim 56 : * 57 : * (xi, eta, zeta): { 0 <= xi <= 1 58 : * { 0 <= eta <= 1 59 : * { 0 <= zeta <= 1 60 : * { xi + eta + zeta <= 1 61 : * 62 : * \author Benjamin S. Kirk 63 : * \date 2002 64 : * \brief A 3D tetrahedral element with 10 nodes. 65 : */ 66 : class Tet10 final : public Tet 67 : { 68 : public: 69 : 70 : /** 71 : * Constructor. By default this element has no parent. 72 : */ 73 : explicit 74 1842168 : Tet10 (Elem * p=nullptr) : 75 1842168 : Tet(num_nodes, p, _nodelinks_data) 76 1842168 : {} 77 : 78 : Tet10 (Tet10 &&) = delete; 79 : Tet10 (const Tet10 &) = delete; 80 : Tet10 & operator= (const Tet10 &) = delete; 81 : Tet10 & operator= (Tet10 &&) = delete; 82 1916025 : virtual ~Tet10() = default; 83 : 84 : /** 85 : * \returns \p TET10. 86 : */ 87 1979825536 : virtual ElemType type () const override { return TET10; } 88 : 89 : /** 90 : * \returns 10. 91 : */ 92 166881834 : virtual unsigned int n_nodes() const override { return num_nodes; } 93 : 94 : /** 95 : * \returns 8. 96 : */ 97 0 : virtual unsigned int n_sub_elem() const override { return 8; } 98 : 99 : /** 100 : * \returns \p true if the specified (local) node number is a vertex. 101 : */ 102 : virtual bool is_vertex(const unsigned int i) const override; 103 : 104 : /** 105 : * \returns \p true if the specified (local) node number is an edge. 106 : */ 107 : virtual bool is_edge(const unsigned int i) const override; 108 : 109 : /** 110 : * \returns \p true if the specified (local) node number is a face. 111 : */ 112 : virtual bool is_face(const unsigned int i) const override; 113 : 114 : /** 115 : * \returns \p true if the specified (local) node number is on the 116 : * specified side. 117 : */ 118 : virtual bool is_node_on_side(const unsigned int n, 119 : const unsigned int s) const override; 120 : 121 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 122 : 123 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 124 : 125 : /** 126 : * \returns \p true if the specified (local) node number is on the 127 : * specified edge. 128 : */ 129 : virtual bool is_node_on_edge(const unsigned int n, 130 : const unsigned int e) const override; 131 : 132 : /** 133 : * \returns \p true if the specified child is on the 134 : * specified side. 135 : */ 136 : virtual bool is_child_on_side(const unsigned int c, 137 : const unsigned int s) const override; 138 : 139 : /** 140 : * \returns \p true if the element map is definitely affine within 141 : * numerical tolerances. 142 : */ 143 : virtual bool has_affine_map () const override; 144 : 145 : /** 146 : * \returns SECOND. 147 : */ 148 : virtual Order default_order() const override; 149 : 150 : /** 151 : * \returns \p Tet10::side_nodes_map[side][side_node] after doing some range checking. 152 : */ 153 : virtual unsigned int local_side_node(unsigned int side, 154 : unsigned int side_node) const override; 155 : 156 : /** 157 : * \returns \p Tet10::edge_nodes_map[edge][edge_node] after doing some range checking. 158 : */ 159 : virtual unsigned int local_edge_node(unsigned int edge, 160 : unsigned int edge_node) const override; 161 : 162 : /** 163 : * Builds a \p TRI6 built coincident with face i. 164 : * The \p std::unique_ptr<Elem> handles the memory aspect. 165 : */ 166 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override; 167 : 168 : /** 169 : * Rebuilds a TRI6 built coincident with face i. 170 : */ 171 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem, 172 : const unsigned int i) override; 173 : 174 : // Avoid hiding deprecated version with different signature 175 : using Elem::build_side_ptr; 176 : 177 : /** 178 : * Builds a \p EDGE3 built coincident with edge i. 179 : * The \p std::unique_ptr<Elem> handles the memory aspect. 180 : */ 181 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) override; 182 : 183 : /** 184 : * Rebuilds a \p EDGE3 coincident with edge i. 185 : */ 186 : virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) override; 187 : 188 : virtual void connectivity(const unsigned int sc, 189 : const IOPackage iop, 190 : std::vector<dof_id_type> & conn) const override; 191 : 192 : /** 193 : * \returns 2 for all \p n. 194 : */ 195 5372160 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override 196 5372160 : { return 2; } 197 : 198 : /** 199 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 200 : * that defines the \f$ n^{th} \f$ second-order node. 201 : * 202 : * \note \p n is counted as depicted above, \f$ 4 \le n < 10 \f$. 203 : */ 204 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n, 205 : const unsigned int v) const override; 206 : 207 : /** 208 : * \returns The child number \p c and element-local index \p v of the 209 : * \f$ n^{th} \f$ second-order node on the parent element. See 210 : * elem.h for further details. 211 : */ 212 : virtual std::pair<unsigned short int, unsigned short int> 213 : second_order_child_vertex (const unsigned int n) const override; 214 : 215 : /** 216 : * Geometric constants for Tet10. 217 : */ 218 : static const int num_nodes = 10; 219 : static const int nodes_per_side = 6; 220 : static const int nodes_per_edge = 3; 221 : 222 : /** 223 : * These map the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ edge or 224 : * side to element node numbers. They are derived from the 225 : * first-order Tet4 tables; see fe_reference_element_traits.h. 226 : */ 227 : static constexpr NodeMapTable<num_edges, nodes_per_edge> 228 : _edge_nodes = derived_edge_nodes<Tet4, num_edges>(); 229 : static constexpr const unsigned int (&edge_nodes_map)[num_edges][nodes_per_edge] = _edge_nodes.values; 230 : 231 : static constexpr NodeMapTable<num_sides, nodes_per_side> 232 : _side_nodes = derived_side_nodes<Tet4, num_sides, nodes_per_side> 233 : (_edge_nodes.values, no_face_node); 234 : static constexpr const unsigned int (&side_nodes_map)[num_sides][nodes_per_side] = _side_nodes.values; 235 : 236 : /** 237 : * A specialization for computing the volume of a Tet10. 238 : */ 239 : virtual Real volume () const override; 240 : 241 : virtual void permute(unsigned int perm_num) override final; 242 : 243 : virtual void flip(BoundaryInfo *) override final; 244 : 245 : ElemType side_type (const unsigned int s) const override final; 246 : 247 : protected: 248 : 249 : /** 250 : * Data for links to nodes. 251 : */ 252 : Node * _nodelinks_data[num_nodes]; 253 : 254 : 255 : 256 : #ifdef LIBMESH_ENABLE_AMR 257 : 258 : /** 259 : * Matrix used to create the elements children. 260 : */ 261 : virtual Real embedding_matrix (const unsigned int i, 262 : const unsigned int j, 263 : const unsigned int k) const override; 264 : 265 : /** 266 : * Matrix that computes new nodal locations/solution values 267 : * from current nodes/solution. 268 : */ 269 : static const Real _embedding_matrix[num_children][num_nodes][num_nodes]; 270 : 271 15164726 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 272 : 273 : #endif // LIBMESH_ENABLE_AMR 274 : 275 : private: 276 : 277 : /** 278 : * Matrix that tells which vertices define the location 279 : * of mid-side (or second-order) nodes 280 : */ 281 : static const unsigned short int _second_order_adjacent_vertices[6][2]; 282 : 283 : /** 284 : * Vector that names a child sharing each second order node. 285 : */ 286 : static const unsigned short int _second_order_vertex_child_number[10]; 287 : 288 : /** 289 : * Vector that names the child vertex index for each second order node. 290 : */ 291 : static const unsigned short int _second_order_vertex_child_index[10]; 292 : }; 293 : 294 : } // namespace libMesh 295 : 296 : 297 : #endif // LIBMESH_CELL_TET10_H