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