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