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_HEX_H 21 : #define LIBMESH_CELL_HEX_H 22 : 23 : // Local includes 24 : #include "libmesh/cell.h" 25 : 26 : namespace libMesh 27 : { 28 : 29 : /** 30 : * The \p Hex is an element in 3D with 6 sides. 31 : * 32 : * \author Benjamin S. Kirk 33 : * \date 2002 34 : * \brief The base class for all hexahedral element types. 35 : */ 36 : class Hex : public Cell 37 : { 38 : public: 39 : 40 : /** 41 : * Default brick element, takes number of nodes and 42 : * parent. Derived classes implement 'true' elements. 43 : */ 44 5025399 : Hex(const unsigned int nn, Elem * p, Node ** nodelinkdata) : 45 5025399 : Cell(nn, num_sides, p, _elemlinks_data, nodelinkdata) 46 : { 47 : // Make sure the interior parent isn't undefined 48 : if (LIBMESH_DIM > 3) 49 : this->set_interior_parent(nullptr); 50 97035 : } 51 : 52 : Hex (Hex &&) = delete; 53 : Hex (const Hex &) = delete; 54 : Hex & operator= (const Hex &) = delete; 55 : Hex & operator= (Hex &&) = delete; 56 97035 : virtual ~Hex() = default; 57 : 58 : /** 59 : * \returns The \p Point associated with local \p Node \p i, 60 : * in master element rather than physical coordinates. 61 : */ 62 2864052 : virtual Point master_point (const unsigned int i) const override final 63 : { 64 89240 : libmesh_assert_less(i, this->n_nodes()); 65 2864052 : return Point(_master_points[i][0], 66 2864052 : _master_points[i][1], 67 2953292 : _master_points[i][2]); 68 : } 69 : 70 : /** 71 : * Geometric constants for all Hexes 72 : */ 73 : static const int num_sides = 6; 74 : static const int num_edges = 12; 75 : static const int num_children = 8; 76 : 77 : /** 78 : * \returns 6. 79 : */ 80 244717173 : virtual unsigned int n_sides() const override final { return 6; } 81 : 82 : /** 83 : * \returns 8. All hexahedra have 8 vertices. 84 : */ 85 404681452 : virtual unsigned int n_vertices() const override final { return 8; } 86 : 87 : /** 88 : * \returns 12. All hexahedra have 12 edges. 89 : */ 90 129605813 : virtual unsigned int n_edges() const override final { return 12; } 91 : 92 : /** 93 : * \returns 6. All hexahedra have 6 faces. 94 : */ 95 46525504 : virtual unsigned int n_faces() const override final { return 6; } 96 : 97 : /** 98 : * \returns 8. 99 : */ 100 111149928 : virtual unsigned int n_children() const override final { return 8; } 101 : 102 : /** 103 : * \returns \p true if the specified child is on the specified side. 104 : */ 105 : virtual bool is_child_on_side(const unsigned int c, 106 : const unsigned int s) const override final; 107 : 108 : /** 109 : * \returns \p true if the specified edge is on the specified side. 110 : */ 111 : virtual bool is_edge_on_side(const unsigned int e, 112 : const unsigned int s) const override final; 113 : 114 : /** 115 : * \returns The side number opposite to \p s 116 : */ 117 : virtual unsigned int opposite_side(const unsigned int s) const override final; 118 : 119 : /** 120 : * \returns The local node number for the node opposite to node n 121 : * on side \p opposite_side(s) (for a tensor product element), or 122 : * throws an error otherwise. 123 : */ 124 : virtual unsigned int opposite_node(const unsigned int n, 125 : const unsigned int s) const override final; 126 : 127 : /** 128 : * Don't hide Elem::key() defined in the base class. 129 : */ 130 : using Elem::key; 131 : 132 : /** 133 : * \returns An id associated with the \p s side of this element. 134 : * The id is not necessarily unique, but should be close. 135 : */ 136 : virtual dof_id_type key (const unsigned int s) const override; 137 : 138 : /** 139 : * \returns An id associated with the \p s side of this element, as 140 : * defined solely by element vertices. The id is not necessarily 141 : * unique, but should be close. This is particularly useful in the 142 : * \p MeshBase::find_neighbors() routine. 143 : */ 144 : virtual dof_id_type low_order_key (const unsigned int s) const override; 145 : 146 : /** 147 : * \returns \p Hex8::side_nodes_map[side][side_node] after doing some range checking. 148 : */ 149 : virtual unsigned int local_side_node(unsigned int side, 150 : unsigned int side_node) const override; 151 : 152 : /** 153 : * \returns \p Hex8::edge_nodes_map[edge][edge_node] after doing some range checking. 154 : */ 155 : virtual unsigned int local_edge_node(unsigned int edge, 156 : unsigned int edge_node) const override; 157 : 158 : /** 159 : * \returns A primitive (4-noded) quad for face i. 160 : */ 161 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final; 162 : 163 : /** 164 : * Rebuilds a primitive (4-noded) quad for face i. 165 : */ 166 : virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) override final; 167 : 168 : /** 169 : * \returns A quantitative assessment of element quality based on 170 : * the quality metric \p q specified by the user. 171 : */ 172 : virtual Real quality (const ElemQuality q) const override; 173 : 174 : /** 175 : * \returns The suggested quality bounds for the hex based on 176 : * quality measure \p q. These are the values suggested by the 177 : * CUBIT User's Manual. 178 : */ 179 : virtual std::pair<Real, Real> qual_bounds (const ElemQuality q) const override; 180 : 181 : virtual std::vector<unsigned int> sides_on_edge(const unsigned int e) const override final; 182 : 183 : /** 184 : * Six sides, four orientations per side. 185 : */ 186 213390 : virtual unsigned int n_permutations() const override final { return 24; } 187 : 188 : virtual bool is_flipped() const override final; 189 : 190 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int n) const override; 191 : 192 : /** 193 : * This maps each edge to the sides that contain said edge. 194 : */ 195 : static const unsigned int edge_sides_map[12][2]; 196 : 197 : virtual bool on_reference_element(const Point & p, 198 : const Real eps = TOLERANCE) const override final; 199 : 200 : protected: 201 : 202 : /** 203 : * Data for links to parent/neighbor/interior_parent elements. 204 : */ 205 : Elem * _elemlinks_data[7+(LIBMESH_DIM>3)]; 206 : 207 : /** 208 : * Matrix that tells which vertices define the location 209 : * of mid-side (or second-order) nodes. This matrix 210 : * is kept here, since the matrix (for the first 12 211 : * higher-order nodes) is identical for \p Hex20 and 212 : * \p Hex27. 213 : */ 214 : static const unsigned short int _second_order_adjacent_vertices[12][2]; 215 : 216 : /** 217 : * Vector that names a child sharing each second order node. 218 : */ 219 : static const unsigned short int _second_order_vertex_child_number[27]; 220 : 221 : /** 222 : * Vector that names the child vertex index for each second order node. 223 : */ 224 : static const unsigned short int _second_order_vertex_child_index[27]; 225 : 226 : /** 227 : * Master element node locations 228 : */ 229 : static const Real _master_points[27][3]; 230 : 231 : /** 232 : * Lookup table from child id, child node id to "possible node 233 : * location" (a simple dictionary-index in a 5x5x5 grid) 234 : */ 235 : static const int _child_node_lookup[8][27]; 236 : 237 : /** 238 : * This maps the \f$ j^{th} \f$ node to the (in this case) 3 edge 239 : * ids adjacent to the node. The edge numbering matches the one used 240 : * in the derived classes' edge_nodes_map. This data structure 241 : * is used in the Hex::edges_adjacent_to_node() override and is 242 : * shared by all the derived Hex types. 243 : */ 244 : static const unsigned int adjacent_edges_map[/*num_vertices*/8][/*n_adjacent_edges*/3]; 245 : }; 246 : 247 : } // namespace libMesh 248 : 249 : #endif // LIBMESH_CELL_HEX_H