1 // The libMesh Finite Element Library. 2 // Copyright (C) 2002-2020 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_TRI_H 21 #define LIBMESH_FACE_TRI_H 22 23 // Local includes 24 #include "libmesh/libmesh_common.h" 25 #include "libmesh/face.h" 26 27 namespace libMesh 28 { 29 30 /** 31 * The \p Tri is an element in 2D composed of 3 sides. 32 * It looks like this: 33 * \verbatim 34 * ^ 35 * / \ 36 * / \ 37 * / \ 38 * / \ 39 * / \ 40 * ----------- 41 * \endverbatim 42 * 43 * \author Benjamin S. Kirk 44 * \date 2002 45 * \brief The base class for all triangular element types. 46 */ 47 class Tri : public Face 48 { 49 public: 50 51 /** 52 * Default triangular element, takes number of nodes and 53 * parent. Derived classes implement 'true' elements. 54 */ Tri(const unsigned int nn,Elem * p,Node ** nodelinkdata)55 Tri (const unsigned int nn, 56 Elem * p, 57 Node ** nodelinkdata) : 58 Face(nn, Tri::n_sides(), p, _elemlinks_data, nodelinkdata) 59 { 60 // Make sure the interior parent isn't undefined 61 if (LIBMESH_DIM > 2) 62 this->set_interior_parent(nullptr); 63 } 64 65 Tri (Tri &&) = delete; 66 Tri (const Tri &) = delete; 67 Tri & operator= (const Tri &) = delete; 68 Tri & operator= (Tri &&) = delete; 69 virtual ~Tri() = default; 70 71 /** 72 * \returns The \p Point associated with local \p Node \p i, 73 * in master element rather than physical coordinates. 74 */ master_point(const unsigned int i)75 virtual Point master_point (const unsigned int i) const override final 76 { 77 libmesh_assert_less(i, this->n_nodes()); 78 return Point(_master_points[i][0], 79 _master_points[i][1], 80 _master_points[i][2]); 81 } 82 83 /** 84 * \returns 3. All tri-derivatives are guaranteed to have at 85 * least 3 nodes. 86 */ n_nodes()87 virtual unsigned int n_nodes() const override { return 3; } 88 89 /** 90 * \returns 3. 91 */ n_sides()92 virtual unsigned int n_sides() const override final { return 3; } 93 94 /** 95 * \returns 3. All triangles have 3 vertices. 96 */ n_vertices()97 virtual unsigned int n_vertices() const override final { return 3; } 98 99 /** 100 * \returns 3. All triangles have 3 edges. 101 */ n_edges()102 virtual unsigned int n_edges() const override final { return 3; } 103 104 /** 105 * \returns 4. 106 */ n_children()107 virtual unsigned int n_children() const override final { return 4; } 108 109 /** 110 * \returns \p true if the specified child is on the 111 * specified side. 112 */ 113 virtual bool is_child_on_side(const unsigned int c, 114 const unsigned int s) const override final; 115 116 /** 117 * Don't hide Elem::key() defined in the base class. 118 */ 119 using Elem::key; 120 121 /** 122 * \returns An id associated with the \p s side of this element. 123 * The id is not necessarily unique, but should be close. This is 124 * particularly useful in the \p MeshBase::find_neighbors() routine. 125 */ 126 virtual dof_id_type key (const unsigned int s) const override; 127 128 /** 129 * \returns An id associated with the global node ids of this 130 * element. The id is not necessarily unique, but should be 131 * close. 132 */ 133 virtual dof_id_type key () const override final; 134 135 /** 136 * \returns \p Tri3::side_nodes_map[side][side_node] after doing some range checking. 137 */ 138 virtual unsigned int local_side_node(unsigned int side, 139 unsigned int side_node) const override; 140 141 /** 142 * Calls local_side_node(edge, edge_node). For 2D elements, there is an implied 143 * equivalence between edges and sides, e.g. n_edges() == n_sides(), so we treat 144 * these two functions the same. 145 */ 146 virtual unsigned int local_edge_node(unsigned int edge, 147 unsigned int edge_node) const override; 148 149 /** 150 * \returns A primitive (2-noded) edge for edge i. 151 */ 152 virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final; 153 154 /** 155 * Rebuilds an EDGE2 coincident with face i. 156 */ 157 virtual void side_ptr (std::unique_ptr<Elem> & elem, 158 const unsigned int i) override final; 159 160 /** 161 * \returns A quantitative assessment of element quality based on 162 * the quality metric \p q specified by the user. 163 */ 164 virtual Real quality (const ElemQuality q) const override; 165 166 /** 167 * \returns The suggested quality bounds for the hex based on quality 168 * measure \p q. These are the values suggested by the CUBIT User's 169 * Manual. 170 */ 171 virtual std::pair<Real, Real> qual_bounds (const ElemQuality q) const override; 172 173 174 protected: 175 176 /** 177 * Data for links to parent/neighbor/interior_parent elements. 178 */ 179 Elem * _elemlinks_data[4+(LIBMESH_DIM>2)]; 180 181 /** 182 * Master element node locations 183 */ 184 static const Real _master_points[6][3]; 185 }; 186 187 } // namespace libMesh 188 189 #endif // LIBMESH_FACE_TRI_H 190