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