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_PYRAMID14_H 21 : #define LIBMESH_CELL_PYRAMID14_H 22 : 23 : // Local includes 24 : #include "libmesh/cell_pyramid.h" 25 : #include "libmesh/cell_pyramid5.h" 26 : #include "libmesh/fe_reference_element_traits.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : /** 32 : * The \p Pyramid14 is an element in 3D composed of 14 nodes, designed 33 : * to interface with a QUAD9 element on the base and a TRI6 element on 34 : * each of the triangular faces. Cubit will generate hybrid meshes 35 : * with linear pyramids, but as of version 14 will not export 36 : * quadratic pyramids. Paraview may support 13-node pyramids, but 37 : * does not render 14-node pyramids correctly. So even if this 38 : * element works in libmesh, we are currently limited in what we can do 39 : * with it outside the library... 40 : * 41 : * The node numbering for the pyramid14 is given below: 42 : * 43 : * \verbatim 44 : * PYRAMID14: 45 : * o 4 46 : * //|\ 47 : * // | \ 48 : * // | \ 49 : * // | \ 50 : * 12 o/ | o 11 51 : * // | \ 52 : * /o 9 o 10 \ 53 : * // | \ zeta 54 : * // | \ ^ eta (into page) 55 : * 3 o/.......o.|........o 2 | / 56 : * ./ 7 | / |/ 57 : * ./ | / o---> xi 58 : * ./ | / 59 : * ./ | / 60 : * 8 o/ o | o 6 61 : * ./ 13 | / 62 : * ./ | / 63 : * ./ |/ 64 : * o--------o---------o 65 : * 0 5 1 66 : * \endverbatim 67 : * 68 : * (xi, eta, zeta): { zeta-1 <= xi <= 1-zeta 69 : * { zeta-1 <= eta <= 1-zeta 70 : * { 0 <= zeta <= 1 71 : * are the reference element coordinates associated with the given 72 : * numbering. 73 : * 74 : * \author John W. Peterson 75 : * \date 2013 76 : * \brief A 3D pyramid element with 14 nodes. 77 : */ 78 : class Pyramid14 final : public Pyramid 79 : { 80 : public: 81 : 82 : /** 83 : * Constructor. By default this element has no parent. 84 : */ 85 : explicit 86 216168 : Pyramid14 (Elem * p=nullptr) : 87 216168 : Pyramid(num_nodes, p, _nodelinks_data) 88 216168 : {} 89 : 90 : Pyramid14 (Pyramid14 &&) = delete; 91 : Pyramid14 (const Pyramid14 &) = delete; 92 : Pyramid14 & operator= (const Pyramid14 &) = delete; 93 : Pyramid14 & operator= (Pyramid14 &&) = delete; 94 222683 : virtual ~Pyramid14() = default; 95 : 96 : /** 97 : * \returns 14. 98 : */ 99 11601010 : virtual unsigned int n_nodes() const override { return num_nodes; } 100 : 101 : /** 102 : * \returns \p PYRAMID14. 103 : */ 104 203410341 : virtual ElemType type () const override { return PYRAMID14; } 105 : 106 : /** 107 : * FIXME: we don't yet have a refinement pattern for pyramids... 108 : * \returns 1. 109 : */ 110 0 : virtual unsigned int n_sub_elem() const override { return 1; } 111 : 112 : /** 113 : * \returns \p true if the specified (local) node number is a vertex. 114 : */ 115 : virtual bool is_vertex(const unsigned int i) const override; 116 : 117 : /** 118 : * \returns \p true if the specified (local) node number is an edge. 119 : */ 120 : virtual bool is_edge(const unsigned int i) const override; 121 : 122 : /** 123 : * \returns \p true if the specified (local) node number is a face. 124 : */ 125 : virtual bool is_face(const unsigned int i) const override; 126 : 127 : /** 128 : * \returns \p true if the specified (local) node number is on the 129 : * specified side. 130 : */ 131 : virtual bool is_node_on_side(const unsigned int n, 132 : const unsigned int s) const override; 133 : 134 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 135 : 136 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 137 : 138 : /** 139 : * \returns \p true if the specified (local) node number is on the 140 : * specified edge. 141 : */ 142 : virtual bool is_node_on_edge(const unsigned int n, 143 : const unsigned int e) const override; 144 : 145 : /** 146 : * \returns \p true if the element map is definitely affine within 147 : * numerical tolerances. 148 : */ 149 : virtual bool has_affine_map () const override; 150 : 151 : /** 152 : * \returns SECOND. 153 : */ 154 : virtual Order default_order() const override; 155 : 156 : /** 157 : * Don't hide Pyramid::key() defined in the base class. 158 : */ 159 : using Pyramid::key; 160 : 161 : /** 162 : * \returns An id associated with the \p s side of this element. 163 : * The id is not necessarily unique, but should be close. 164 : * 165 : * We reimplement this method here for the \p Pyramid14 since we can 166 : * use the center node of the base face to provide a perfect (unique) 167 : * key. 168 : */ 169 : virtual dof_id_type key (const unsigned int s) const override; 170 : 171 : /** 172 : * \returns \p Pyramid14::side_nodes_map[side][side_node] after doing some range checking. 173 : */ 174 : virtual unsigned int local_side_node(unsigned int side, 175 : unsigned int side_node) const override; 176 : 177 : /** 178 : * \returns \p Pyramid14::edge_nodes_map[edge][edge_node] after doing some range checking. 179 : */ 180 : virtual unsigned int local_edge_node(unsigned int edge, 181 : unsigned int edge_node) const override; 182 : 183 : /** 184 : * Builds a \p QUAD9 or \p TRI6 coincident with face i. 185 : * The \p std::unique_ptr<Elem> handles the memory aspect. 186 : */ 187 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override; 188 : 189 : /** 190 : * Rebuilds a \p QUAD9 or \p TRI6 built coincident with face i. 191 : */ 192 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem, 193 : const unsigned int i) override; 194 : 195 : // Avoid hiding deprecated version with different signature 196 : using Elem::build_side_ptr; 197 : 198 : /** 199 : * Builds a \p EDGE3 coincident with edge i. 200 : * The \p std::unique_ptr<Elem> handles the memory aspect. 201 : */ 202 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) override; 203 : 204 : /** 205 : * Rebuilds a \p EDGE3 coincident with edge i. 206 : */ 207 : virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) override; 208 : 209 : virtual void connectivity(const unsigned int sc, 210 : const IOPackage iop, 211 : std::vector<dof_id_type> & conn) const override; 212 : 213 : /** 214 : * \returns 2 for all edge nodes and 4 for face nodes. 215 : */ 216 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int n) const override; 217 : 218 : /** 219 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 220 : * that defines the \f$ n^{th} \f$ second-order node. 221 : */ 222 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n, 223 : const unsigned int v) const override; 224 : 225 : /** 226 : * Geometric constants for Pyramid14. 227 : */ 228 : static const int num_nodes = 14; 229 : static const int nodes_per_side = 9; 230 : static const int nodes_per_edge = 3; 231 : 232 : /** 233 : * These map the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ edge or 234 : * side to element node numbers. They are derived from the 235 : * first-order Pyramid5 tables; see fe_reference_element_traits.h. 236 : */ 237 : static constexpr NodeMapTable<num_edges, nodes_per_edge> 238 : _edge_nodes = derived_edge_nodes<Pyramid5, num_edges>(); 239 : static constexpr const unsigned int (&edge_nodes_map)[num_edges][nodes_per_edge] = _edge_nodes.values; 240 : 241 : static constexpr NodeMapTable<num_sides, nodes_per_side> 242 : _side_nodes = derived_side_nodes<Pyramid5, num_sides, nodes_per_side> 243 : (_edge_nodes.values, [](unsigned int s) { return s == 4 ? 13 : invalid_uint; }); 244 : static constexpr const unsigned int (&side_nodes_map)[num_sides][nodes_per_side] = _side_nodes.values; 245 : 246 : /** 247 : * Specialization for computing the volume of a Pyramid14. 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 : * Data for links to nodes. 263 : */ 264 : Node * _nodelinks_data[num_nodes]; 265 : 266 : 267 : 268 : #ifdef LIBMESH_ENABLE_AMR 269 : 270 : /** 271 : * Matrix used to create the elements children. 272 : */ 273 0 : virtual Real embedding_matrix (const unsigned int, 274 : const unsigned int, 275 : const unsigned int) const override 276 0 : { libmesh_not_implemented(); return 0.; } 277 : 278 0 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 279 : 280 : #endif // LIBMESH_ENABLE_AMR 281 : 282 : }; 283 : 284 : } // namespace libMesh 285 : 286 : 287 : #endif // LIBMESH_CELL_PYRAMID14_H