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_CELL_HEX27_H 21 : #define LIBMESH_CELL_HEX27_H 22 : 23 : // Local includes 24 : #include "libmesh/cell_hex.h" 25 : 26 : namespace libMesh 27 : { 28 : 29 : /** 30 : * The \p Hex27 is an element in 3D composed of 27 nodes. It is 31 : * numbered like this: 32 : * 33 : * \verbatim 34 : * HEX27: 7 18 6 35 : * o--------------o--------------o 36 : * /: / /| 37 : * / : / / | 38 : * / : / / | 39 : * 19/ : 25/ 17/ | 40 : * o--------------o--------------o | 41 : * / : / /| | 42 : * / 15o / 23o / | 14o 43 : * / : / / | /| zeta 44 : * 4/ : 16/ 5/ | / | ^ eta (into page) 45 : * o--------------o--------------o | / | | / 46 : * | : | 26 | |/ | |/ 47 : * | 24o : | o | 22o | o---> xi 48 : * | : | 10 | /| | 49 : * | 3o....|.........o....|../.|....o 50 : * | . | | / | / 2 51 : * | . 21| 13|/ | / 52 : * 12 o--------------o--------------o | / 53 : * | . | | |/ 54 : * | 11o | 20o | o 55 : * | . | | / 9 56 : * | . | | / 57 : * | . | | / 58 : * |. | |/ 59 : * o--------------o--------------o 60 : * 0 8 1 61 : * \endverbatim 62 : * 63 : * (xi, eta, zeta) in [-1,1]^3 are the reference element coordinates 64 : * associated with the given numbering. 65 : * 66 : * \author Benjamin S. Kirk 67 : * \date 2002 68 : * \brief A 3D hexahedral element with 27 nodes. 69 : */ 70 : class Hex27 final : public Hex 71 : { 72 : public: 73 : 74 : /** 75 : * Constructor. By default this element has no parent. 76 : */ 77 : explicit 78 1788390 : Hex27 (Elem * p=nullptr) : 79 1788390 : Hex(num_nodes, p, _nodelinks_data) 80 1788390 : {} 81 : 82 : Hex27 (Hex27 &&) = delete; 83 : Hex27 (const Hex27 &) = delete; 84 : Hex27 & operator= (const Hex27 &) = delete; 85 : Hex27 & operator= (Hex27 &&) = delete; 86 1871007 : virtual ~Hex27() = default; 87 : 88 : /** 89 : * \returns \p HEX27. 90 : */ 91 13154812747 : virtual ElemType type () const override { return HEX27; } 92 : 93 : /** 94 : * \returns 27. 95 : */ 96 1380805237 : virtual unsigned int n_nodes() const override { return num_nodes; } 97 : 98 : /** 99 : * \returns 8. 100 : */ 101 0 : virtual unsigned int n_sub_elem() const override { return 8; } 102 : 103 : /** 104 : * \returns \p true if the specified (local) node number is a vertex. 105 : */ 106 : virtual bool is_vertex(const unsigned int i) const override; 107 : 108 : /** 109 : * \returns \p true if the specified (local) node number is an edge. 110 : */ 111 : virtual bool is_edge(const unsigned int i) const override; 112 : 113 : /** 114 : * \returns \p true if the specified (local) node number is a face. 115 : */ 116 : virtual bool is_face(const unsigned int i) const override; 117 : 118 : /** 119 : * \returns \p true if the specified (local) node number is on the 120 : * specified side. 121 : */ 122 : virtual bool is_node_on_side(const unsigned int n, 123 : const unsigned int s) const override; 124 : 125 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 126 : 127 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 128 : 129 : /** 130 : * \returns \p true if the specified (local) node number is on the 131 : * specified edge. 132 : */ 133 : virtual bool is_node_on_edge(const unsigned int n, 134 : const unsigned int e) const override; 135 : 136 : /** 137 : * \returns \p true if the element map is definitely affine within 138 : * numerical tolerances. 139 : */ 140 : virtual bool has_affine_map () const override; 141 : 142 : /** 143 : * \returns SECOND. 144 : */ 145 : virtual Order default_order() const override; 146 : 147 : /** 148 : * Don't hide Elem::key() defined in the base class. 149 : */ 150 : using Elem::key; 151 : 152 : /** 153 : * \returns An id associated with the \p s side of this element. 154 : * The id is not necessarily unique, but should be close. 155 : * 156 : * We reimplement this method here for the \p Hex27 since we can 157 : * use the center node of each face to provide a perfect (unique) 158 : * key. 159 : */ 160 : virtual dof_id_type key (const unsigned int s) const override; 161 : 162 : /** 163 : * \returns \p Hex27::side_nodes_map[side][side_node] after doing some range checking. 164 : */ 165 : virtual unsigned int local_side_node(unsigned int side, 166 : unsigned int side_node) const override; 167 : 168 : /** 169 : * \returns \p Hex27::edge_nodes_map[edge][edge_node] after doing some range checking. 170 : */ 171 : virtual unsigned int local_edge_node(unsigned int edge, 172 : unsigned int edge_node) const override; 173 : 174 : /** 175 : * Builds a \p QUAD9 built coincident with face i. 176 : * The \p std::unique_ptr<Elem> handles the memory aspect. 177 : */ 178 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override; 179 : 180 : /** 181 : * Rebuilds a \p QUAD9 built coincident with face i. 182 : */ 183 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem, 184 : const unsigned int i) override; 185 : 186 : // Avoid hiding deprecated version with different signature 187 : using Elem::build_side_ptr; 188 : 189 : /** 190 : * Builds a \p EDGE3 built coincident with edge i. 191 : * The \p std::unique_ptr<Elem> handles the memory aspect. 192 : */ 193 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) override; 194 : 195 : /** 196 : * Rebuilds a \p EDGE3 built coincident with edge i. 197 : */ 198 : virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) override; 199 : 200 : virtual void connectivity(const unsigned int sc, 201 : const IOPackage iop, 202 : std::vector<dof_id_type> & conn) const override; 203 : 204 : /** 205 : * \returns 2 for all edge nodes, 4 for all face nodes, and 206 : * 8 for the bubble node. 207 : */ 208 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override; 209 : 210 : /** 211 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 212 : * that defines the \f$ n^{th} \f$ second-order node. 213 : * 214 : * \note \p n is counted as depicted above, \f$ 8 \le n < 27 \f$. 215 : */ 216 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n, 217 : const unsigned int v) const override; 218 : 219 : /** 220 : * \returns The child number \p c and element-local index \p v of the 221 : * \f$ n^{th} \f$ second-order node on the parent element. See 222 : * elem.h for further details. 223 : */ 224 : virtual std::pair<unsigned short int, unsigned short int> 225 : second_order_child_vertex (const unsigned int n) const override; 226 : 227 : /** 228 : * Geometric constants for Hex27. 229 : */ 230 : static const int num_nodes = 27; 231 : static const int nodes_per_side = 9; 232 : static const int nodes_per_edge = 3; 233 : 234 : /** 235 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ side to 236 : * element node numbers. 237 : */ 238 : static const unsigned int side_nodes_map[num_sides][nodes_per_side]; 239 : 240 : /** 241 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ edge to 242 : * element node numbers. 243 : */ 244 : static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]; 245 : 246 : /** 247 : * A specialization for computing the volume of a Hex27. 248 : */ 249 : virtual Real volume () const override; 250 : 251 : virtual void permute(unsigned int perm_num) override final; 252 : 253 : virtual void flip(BoundaryInfo *) override final; 254 : 255 : unsigned int center_node_on_side(const unsigned short side) const override final; 256 : 257 : ElemType side_type (const unsigned int s) const override final; 258 : 259 : protected: 260 : 261 : 262 : /** 263 : * Data for links to nodes. 264 : */ 265 : Node * _nodelinks_data[num_nodes]; 266 : 267 : 268 : #ifdef LIBMESH_ENABLE_AMR 269 : 270 : /** 271 : * Matrix used to create the elements children. 272 : */ 273 9949202 : virtual Real embedding_matrix (const unsigned int i, 274 : const unsigned int j, 275 : const unsigned int k) const override 276 9949202 : { return _embedding_matrix[i][j][k]; } 277 : 278 : /** 279 : * Matrix that computes new nodal locations/solution values 280 : * from current nodes/solution. 281 : */ 282 : static const Real _embedding_matrix[num_children][num_nodes][num_nodes]; 283 : 284 79665615 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 285 : 286 : #endif // LIBMESH_ENABLE_AMR 287 : 288 : 289 : private: 290 : 291 : /** 292 : * Matrix that tells which vertices define the location 293 : * of mid-side (or second-order) nodes. This matrix only 294 : * covers the nodes that are unique to \p Hex27, while the 295 : * second-order-nodes that are identical with \p Hex20 are covered 296 : * through the \p _second_order_adjacent_vertices matrix in 297 : * \p cell_hex.C. 298 : * 299 : * \note This matrix also does not cover the bubble node. The 300 : * interpolation is trivial and would only blow up the size of this 301 : * matrix. 302 : */ 303 : static const unsigned short int _remaining_second_order_adjacent_vertices[6][4]; 304 : 305 : }; 306 : 307 : } // namespace libMesh 308 : 309 : #endif // LIBMESH_CELL_HEX27_H