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/fe_reference_element_traits.h" 26 : #include "libmesh/face_tri.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : /** 32 : * The \p Tri7 is an element in 2D composed of 7 nodes. It is 33 : * numbered like this: 34 : * 35 : * \verbatim 36 : * TRI7: 37 : * 2 38 : * o 39 : * |\ 40 : * | \ 41 : * | \ eta 42 : * | \ ^ 43 : * | \ | 44 : * 5 o o 4 | 45 : * | o \ o---> xi 46 : * | 6 \ 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 Roy H Stogner 59 : * \date 2021 60 : * \brief A 2D triangular element with 7 nodes. 61 : */ 62 : class Tri7 : public Tri 63 : { 64 : public: 65 : 66 : /** 67 : * Constructor. By default this element has no parent. 68 : */ 69 : explicit 70 5158752 : Tri7 (Elem * p=nullptr) : 71 5158752 : Tri(num_nodes, p, _nodelinks_data) {} 72 : 73 : Tri7 (Tri7 &&) = delete; 74 : Tri7 (const Tri7 &) = delete; 75 : Tri7 & operator= (const Tri7 &) = delete; 76 : Tri7 & operator= (Tri7 &&) = delete; 77 6318593 : virtual ~Tri7() = default; 78 : 79 : /** 80 : * \returns \p TRI7. 81 : */ 82 619992239 : virtual ElemType type () const override { return TRI7; } 83 : 84 : /** 85 : * \returns 7. 86 : */ 87 117451165 : 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 1056 : virtual bool is_node_on_edge(const unsigned int n, 125 : const unsigned int e) const override 126 1056 : { 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 THIRD. 136 : */ 137 : virtual Order default_order() const override; 138 : 139 : /** 140 : * \returns SECOND - the sides are EDGE3 141 : */ 142 : virtual Order default_side_order() const override; 143 : 144 : /** 145 : * Don't hide Elem::key() defined in the base class. 146 : */ 147 : using Elem::key; 148 : 149 : /** 150 : * \returns An id associated with the \p s side of this element. 151 : * The id is not necessarily unique, but should be close. 152 : * 153 : * We reimplement this method here for the \p Tri7 since we can 154 : * use the center node of each edge to provide a perfect (unique) 155 : * key. 156 : */ 157 : virtual dof_id_type key (const unsigned int s) const override; 158 : 159 : /** 160 : * \returns \p Tri7::side_nodes_map[side][side_node] after doing some range checking. 161 : */ 162 : virtual unsigned int local_side_node(unsigned int side, 163 : unsigned int side_node) const override; 164 : 165 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override; 166 : 167 : /** 168 : * Rebuilds an EDGE2 coincident with face i. 169 : */ 170 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem, 171 : const unsigned int i) override; 172 : 173 : // Avoid hiding deprecated version with different signature 174 : using Elem::build_side_ptr; 175 : 176 : virtual void connectivity(const unsigned int sf, 177 : const IOPackage iop, 178 : std::vector<dof_id_type> & conn) const override; 179 : 180 : /** 181 : * \returns 2 for edge nodes and 3 for the interior node. 182 : */ 183 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override; 184 : 185 : /** 186 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 187 : * that defines the \f$ n^{th} \f$ second-order node. 188 : * 189 : * \note \p n is counted as depicted above, \f$ 3 \le n < 7 \f$. 190 : */ 191 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n, 192 : const unsigned int v) const override; 193 : 194 : /** 195 : * \returns The child number \p c and element-local index \p v of the 196 : * \f$ n^{th} \f$ second-order node on the parent element. See 197 : * elem.h for further details. 198 : */ 199 : virtual std::pair<unsigned short int, unsigned short int> 200 : second_order_child_vertex (const unsigned int n) const override; 201 : 202 : /** 203 : * Geometric constants for Tri7. 204 : */ 205 : static const int num_nodes = 7; 206 : static const int nodes_per_side = 3; 207 : 208 : /** 209 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ side to 210 : * element node numbers. 211 : */ 212 : static const ReferenceElementTable<num_sides, nodes_per_side> side_nodes_map; 213 : 214 : /** 215 : * \returns A bounding box (not necessarily the minimal bounding box) 216 : * containing the geometric element. 217 : */ 218 : virtual BoundingBox loose_bounding_box () const override; 219 : 220 : virtual void permute(unsigned int perm_num) override final; 221 : 222 : virtual void flip(BoundaryInfo *) override final; 223 : 224 : #ifdef LIBMESH_ENABLE_AMR 225 : virtual 226 : const std::vector<std::pair<unsigned char, unsigned char>> & 227 12236 : parent_bracketing_nodes(unsigned int c, 228 : unsigned int n) const override 229 12236 : { return _parent_bracketing_nodes[c][n]; } 230 : #endif 231 : 232 : unsigned int center_node_on_side(const unsigned short side) const override final; 233 : 234 : ElemType side_type (const unsigned int s) const override final; 235 : 236 : protected: 237 : 238 : /** 239 : * Data for links to nodes. 240 : */ 241 : Node * _nodelinks_data[num_nodes]; 242 : 243 : 244 : 245 : #ifdef LIBMESH_ENABLE_AMR 246 : 247 : /** 248 : * Matrix used to create the elements children. 249 : */ 250 34272 : virtual Real embedding_matrix (const unsigned int i, 251 : const unsigned int j, 252 : const unsigned int k) const override 253 34272 : { return _embedding_matrix[i][j][k]; } 254 : 255 : /** 256 : * Matrix that computes new nodal locations/solution values 257 : * from current nodes/solution. 258 : */ 259 : static const Real _embedding_matrix[num_children][num_nodes][num_nodes]; 260 : 261 : /** 262 : * Pairs of nodes that bracket child nodes when doing mesh 263 : * refinement. 264 : */ 265 : static const std::vector<std::pair<unsigned char, unsigned char>> 266 : _parent_bracketing_nodes[num_children][num_nodes]; 267 : 268 21168 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 269 : 270 : #endif // LIBMESH_ENABLE_AMR 271 : 272 : private: 273 : 274 : /** 275 : * Matrix that tells which vertices define the location 276 : * of mid-side (or second-order) nodes 277 : */ 278 : static const unsigned short int _second_order_adjacent_vertices[num_sides][2]; 279 : 280 : /** 281 : * Vector that names a child sharing each second order node. 282 : */ 283 : static const unsigned short int _second_order_vertex_child_number[num_nodes]; 284 : 285 : /** 286 : * Vector that names the child vertex index for each second order node. 287 : */ 288 : static const unsigned short int _second_order_vertex_child_index[num_nodes]; 289 : }; 290 : 291 : 292 : } // namespace libMesh 293 : 294 : #endif // LIBMESH_FACE_TRI6_H