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