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