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