Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2025 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_QUAD_H 21 : #define LIBMESH_FACE_QUAD_H 22 : 23 : 24 : // Local includes 25 : #include "libmesh/libmesh_common.h" 26 : #include "libmesh/face.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : /** 32 : * The \p QUAD is an element in 2D composed of 4 sides. 33 : * It looks like this: 34 : * \verbatim 35 : * o-----------o 36 : * | | 37 : * | | 38 : * | | 39 : * | | 40 : * | | 41 : * o-----------o 42 : * \endverbatim 43 : * 44 : * \author Benjamin S. Kirk 45 : * \date 2002 46 : * \brief The base class for all quadrilateral element types. 47 : */ 48 : class Quad : public Face 49 : { 50 : public: 51 : 52 : /** 53 : * Default quadrilateral element, takes number of nodes and 54 : * parent. Derived classes implement 'true' elements. 55 : */ 56 1918043767 : Quad (const unsigned int nn, Elem * p, Node ** nodelinkdata) : 57 1918043767 : Face(nn, num_sides, p, _elemlinks_data, nodelinkdata) 58 : { 59 : // Make sure the interior parent isn't undefined 60 : if (LIBMESH_DIM > 2) 61 1918043767 : this->set_interior_parent(nullptr); 62 1918043767 : } 63 : 64 : Quad (Quad &&) = delete; 65 : Quad (const Quad &) = delete; 66 : Quad & operator= (const Quad &) = delete; 67 : Quad & operator= (Quad &&) = delete; 68 14930023 : virtual ~Quad() = default; 69 : 70 : /** 71 : * \returns The \p Point associated with local \p Node \p i, 72 : * in master element rather than physical coordinates. 73 : */ 74 1210580 : virtual Point master_point (const unsigned int i) const override final 75 : { 76 42872 : libmesh_assert_less(i, this->n_nodes()); 77 1210580 : return Point(_master_points[i][0], 78 1210580 : _master_points[i][1], 79 1253452 : _master_points[i][2]); 80 : } 81 : 82 : /** 83 : * Geometric constants for Quad4. 84 : */ 85 : static const int num_sides = 4; 86 : static const int num_children = 4; 87 : 88 : /** 89 : * \returns 4. All quad-derivatives are guaranteed to have at 90 : * least 4 nodes. 91 : */ 92 1231747698 : virtual unsigned int n_nodes() const override { return 4; } 93 : 94 : /** 95 : * \returns 4. 96 : */ 97 3680544470 : virtual unsigned int n_sides() const override final { return 4; } 98 : 99 : /** 100 : * \returns 4. All quadrilaterals have 4 vertices. 101 : */ 102 403190357 : virtual unsigned int n_vertices() const override final { return 4; } 103 : 104 : /** 105 : * \returns 4. All quadrilaterals have 4 edges. 106 : */ 107 76554532 : virtual unsigned int n_edges() const override final { return 4; } 108 : 109 : /** 110 : * \returns 4. 111 : */ 112 202648621 : virtual unsigned int n_children() const override final { return 4; } 113 : 114 : /** 115 : * \returns \p true if the specified child is on the 116 : * specified side. 117 : */ 118 : virtual bool is_child_on_side(const unsigned int c, 119 : const unsigned int s) const override final; 120 : 121 : /** 122 : * \returns The side number opposite to \p s (for a tensor product 123 : * element), or throws an error otherwise. 124 : */ 125 : virtual unsigned int opposite_side(const unsigned int s) const override final; 126 : 127 : /** 128 : * \returns The local node number for the node opposite to node n 129 : * on side \p opposite_side(s) (for a tensor product element), or 130 : * throws an error otherwise. 131 : */ 132 : virtual unsigned int opposite_node(const unsigned int n, 133 : const unsigned int s) const override final; 134 : 135 : /** 136 : * Don't hide Elem::key() defined in the base class. 137 : */ 138 : using Elem::key; 139 : 140 : /** 141 : * \returns An id associated with the global node ids of this 142 : * element. The id is not necessarily unique, but should be 143 : * close. 144 : */ 145 : virtual dof_id_type key () const override; 146 : 147 : /** 148 : * \returns An id associated with the \p s side of this element. 149 : * The id is not necessarily unique, but should be close. 150 : */ 151 : virtual dof_id_type key (const unsigned int s) const override; 152 : 153 : /** 154 : * \returns An id associated with the \p s side of this element, as 155 : * defined solely by element vertices. The id is not necessarily 156 : * unique, but should be close. This is particularly useful in the 157 : * \p MeshBase::find_neighbors() routine. 158 : */ 159 : virtual dof_id_type low_order_key (const unsigned int s) const override; 160 : 161 : /** 162 : * \returns \p Quad4::side_nodes_map[side][side_node] after doing some range checking. 163 : */ 164 : virtual unsigned int local_side_node(unsigned int side, 165 : unsigned int side_node) const override; 166 : 167 : /** 168 : * Calls local_side_node(edge, edge_node). For 2D elements, there is an implied 169 : * equivalence between edges and sides, e.g. n_edges() == n_sides(), so we treat 170 : * these two functions the same. 171 : */ 172 : virtual unsigned int local_edge_node(unsigned int edge, 173 : unsigned int edge_node) const override; 174 : 175 : /** 176 : * \returns A primitive (2-noded) edge for edge i. 177 : */ 178 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final; 179 : 180 : /** 181 : * Rebuilds an EDGE2 coincident with face i. 182 : */ 183 : virtual void side_ptr (std::unique_ptr<Elem> & elem, 184 : const unsigned int i) override final; 185 : 186 : /** 187 : * \returns A quantitative assessment of element quality based on 188 : * the quality metric \p q specified by the user. 189 : */ 190 : virtual Real quality (const ElemQuality q) const override; 191 : 192 : /** 193 : * \returns The suggested quality bounds for 194 : * the hex based on quality measure q. These are 195 : * the values suggested by the CUBIT User's Manual. 196 : */ 197 : virtual std::pair<Real, Real> qual_bounds (const ElemQuality q) const override; 198 : 199 : /** 200 : * Four sides, one orientation each. 201 : */ 202 108536 : virtual unsigned int n_permutations() const override final { return 4; } 203 : 204 : virtual bool is_flipped() const override final; 205 : 206 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int n) const override; 207 : 208 : virtual bool on_reference_element(const Point & p, 209 : const Real eps = TOLERANCE) const override final; 210 : 211 : protected: 212 : 213 : /** 214 : * Data for links to parent/neighbor/interior_parent elements. 215 : */ 216 : Elem * _elemlinks_data[5+(LIBMESH_DIM>2)]; 217 : 218 : /** 219 : * Matrix that tells which vertices define the location 220 : * of mid-side (or second-order) nodes. Since most 221 : * second-order nodes are identical for \p Quad8 and \p Quad9, 222 : * we keep this matrix here in \p Quad 223 : */ 224 : static const unsigned short int _second_order_adjacent_vertices[4][2]; 225 : 226 : /** 227 : * Vector that names a child sharing each second order node. 228 : */ 229 : static const unsigned short int _second_order_vertex_child_number[9]; 230 : 231 : /** 232 : * Vector that names the child vertex index for each second order node. 233 : */ 234 : static const unsigned short int _second_order_vertex_child_index[9]; 235 : 236 : /** 237 : * Master element node locations 238 : */ 239 : static const Real _master_points[9][3]; 240 : 241 : /** 242 : * Lookup table from child id, child node id to "possible node 243 : * location" (a simple dictionary-index in a 5x5 grid) 244 : */ 245 : static const int _child_node_lookup[4][9]; 246 : 247 : /** 248 : * This maps the \f$ j^{th} \f$ node to the (in this case) 2 side 249 : * ids adjacent to the node. The side numbering matches the one used 250 : * in the derived classes' side_nodes_map. This data structure 251 : * is used in the Quad::edges_adjacent_to_node() override and is 252 : * shared by all the derived Quad types. 253 : */ 254 : static const unsigned int adjacent_sides_map[/*num_vertices*/4][/*n_adjacent_sides*/2]; 255 : }; 256 : 257 : } // namespace libMesh 258 : 259 : #endif // LIBMESH_FACE_QUAD_H