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