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_FACE_TRI6_H 21 : #define LIBMESH_FACE_TRI6_H 22 : 23 : // Local includes 24 : #include "libmesh/libmesh_common.h" 25 : #include "libmesh/fe_reference_element_traits.h" 26 : #include "libmesh/face_tri.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : /** 32 : * The \p Tri6 is an element in 2D composed of 6 nodes. It is 33 : * numbered like this: 34 : * 35 : * \verbatim 36 : * TRI6: 37 : * 2 38 : * o 39 : * |\ 40 : * | \ 41 : * | \ eta 42 : * | \ ^ 43 : * | \ | 44 : * 5 o o 4 | 45 : * | \ o---> xi 46 : * | \ 47 : * | \ 48 : * o----o----o 49 : * 0 3 1 50 : * \endverbatim 51 : * 52 : * (xi, eta): { 0 <= xi <= 1 53 : * { 0 <= eta <= 1 54 : * { xi + eta <= 1 55 : * are the reference element coordinates associated with the given 56 : * numbering. 57 : * 58 : * \author Benjamin S. Kirk 59 : * \date 2002 60 : * \brief A 2D triangular element with 6 nodes. 61 : */ 62 : class Tri6 : public Tri 63 : { 64 : public: 65 : 66 : /** 67 : * Constructor. By default this element has no parent. 68 : */ 69 : explicit 70 938705 : Tri6 (Elem * p=nullptr) : 71 938705 : Tri(num_nodes, p, _nodelinks_data) {} 72 : 73 : Tri6 (Tri6 &&) = delete; 74 : Tri6 (const Tri6 &) = delete; 75 : Tri6 & operator= (const Tri6 &) = delete; 76 : Tri6 & operator= (Tri6 &&) = delete; 77 1114610 : virtual ~Tri6() = default; 78 : 79 : /** 80 : * \returns \p TRI6. 81 : */ 82 4562162110 : virtual ElemType type () const override { return TRI6; } 83 : 84 : /** 85 : * \returns 6. 86 : */ 87 2015473390 : virtual unsigned int n_nodes() const override { return num_nodes; } 88 : 89 : /** 90 : * \returns 4. 91 : */ 92 0 : virtual unsigned int n_sub_elem() const override { return 4; } 93 : 94 : /** 95 : * \returns \p true if the specified (local) node number is a vertex. 96 : */ 97 : virtual bool is_vertex(const unsigned int i) const override; 98 : 99 : /** 100 : * \returns \p true if the specified (local) node number is an edge. 101 : */ 102 : virtual bool is_edge(const unsigned int i) const override; 103 : 104 : /** 105 : * \returns \p true if the specified (local) node number is a face. 106 : */ 107 : virtual bool is_face(const unsigned int i) const override; 108 : 109 : /** 110 : * \returns \p true if the specified (local) node number is on the 111 : * specified side. 112 : */ 113 : virtual bool is_node_on_side(const unsigned int n, 114 : const unsigned int s) const override; 115 : 116 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 117 : 118 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 119 : 120 : /** 121 : * \returns \p true if the specified (local) node number is on the 122 : * specified edge (== is_node_on_side in 2D). 123 : */ 124 4371 : virtual bool is_node_on_edge(const unsigned int n, 125 : const unsigned int e) const override 126 4371 : { return this->is_node_on_side(n,e); } 127 : 128 : /** 129 : * \returns \p true if the element map is definitely affine within 130 : * numerical tolerances. 131 : */ 132 : virtual bool has_affine_map () const override; 133 : 134 : /** 135 : * \returns SECOND. 136 : */ 137 : virtual Order default_order() const override; 138 : 139 : /** 140 : * Don't hide Elem::key() defined in the base class. 141 : */ 142 : using Elem::key; 143 : 144 : /** 145 : * \returns An id associated with the \p s side of this element. 146 : * The id is not necessarily unique, but should be close. 147 : * 148 : * We reimplement this method here for the \p Tri6 since we can 149 : * use the center node of each edge to provide a perfect (unique) 150 : * key. 151 : */ 152 : virtual dof_id_type key (const unsigned int s) const override; 153 : 154 : /** 155 : * \returns \p Tri6::side_nodes_map[side][side_node] after doing some range checking. 156 : */ 157 : virtual unsigned int local_side_node(unsigned int side, 158 : unsigned int side_node) const override; 159 : 160 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override; 161 : 162 : /** 163 : * Rebuilds an EDGE2 coincident with face i. 164 : */ 165 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem, 166 : const unsigned int i) override; 167 : 168 : // Avoid hiding deprecated version with different signature 169 : using Elem::build_side_ptr; 170 : 171 : virtual void connectivity(const unsigned int sf, 172 : const IOPackage iop, 173 : std::vector<dof_id_type> & conn) const override; 174 : 175 : /** 176 : * \returns 2 for all \p n. 177 : */ 178 9965 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override 179 9965 : { return 2; } 180 : 181 : /** 182 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 183 : * that defines the \f$ n^{th} \f$ second-order node. 184 : * 185 : * \note \p n is counted as depicted above, \f$ 3 \le n < 6 \f$. 186 : */ 187 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n, 188 : const unsigned int v) const override; 189 : 190 : /** 191 : * \returns The child number \p c and element-local index \p v of the 192 : * \f$ n^{th} \f$ second-order node on the parent element. See 193 : * elem.h for further details. 194 : */ 195 : virtual std::pair<unsigned short int, unsigned short int> 196 : second_order_child_vertex (const unsigned int n) const override; 197 : 198 : /** 199 : * Geometric constants for Tri6. 200 : */ 201 : static const int num_nodes = 6; 202 : static const int nodes_per_side = 3; 203 : 204 : /** 205 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ side to 206 : * element node numbers. 207 : */ 208 : static const ReferenceElementTable<num_sides, nodes_per_side> side_nodes_map; 209 : 210 : /** 211 : * An optimized method for approximating the area of a 212 : * TRI6 using quadrature. 213 : */ 214 : virtual Real volume () const override; 215 : 216 : /** 217 : * \returns A bounding box (not necessarily the minimal bounding box) 218 : * containing the geometric element. 219 : */ 220 : virtual BoundingBox loose_bounding_box () const override; 221 : 222 : virtual void permute(unsigned int perm_num) override final; 223 : 224 : virtual void flip(BoundaryInfo *) override final; 225 : 226 : unsigned int center_node_on_side(const unsigned short side) const override final; 227 : 228 : ElemType side_type (const unsigned int s) const override final; 229 : 230 : protected: 231 : 232 : /** 233 : * Data for links to nodes. 234 : */ 235 : Node * _nodelinks_data[num_nodes]; 236 : 237 : 238 : 239 : #ifdef LIBMESH_ENABLE_AMR 240 : 241 : /** 242 : * Matrix used to create the elements children. 243 : */ 244 632532 : virtual Real embedding_matrix (const unsigned int i, 245 : const unsigned int j, 246 : const unsigned int k) const override 247 632532 : { return _embedding_matrix[i][j][k]; } 248 : 249 : /** 250 : * Matrix that computes new nodal locations/solution values 251 : * from current nodes/solution. 252 : */ 253 : static const Real _embedding_matrix[num_children][num_nodes][num_nodes]; 254 : 255 982332 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 256 : 257 : #endif // LIBMESH_ENABLE_AMR 258 : 259 : private: 260 : 261 : /** 262 : * Matrix that tells which vertices define the location 263 : * of mid-side (or second-order) nodes 264 : */ 265 : static const unsigned short int _second_order_adjacent_vertices[num_sides][2]; 266 : 267 : /** 268 : * Vector that names a child sharing each second order node. 269 : */ 270 : static const unsigned short int _second_order_vertex_child_number[num_nodes]; 271 : 272 : /** 273 : * Vector that names the child vertex index for each second order node. 274 : */ 275 : static const unsigned short int _second_order_vertex_child_index[num_nodes]; 276 : }; 277 : 278 : 279 : } // namespace libMesh 280 : 281 : #endif // LIBMESH_FACE_TRI6_H