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_PYRAMID_H 21 : #define LIBMESH_CELL_PYRAMID_H 22 : 23 : // Local includes 24 : #include "libmesh/cell.h" 25 : 26 : namespace libMesh 27 : { 28 : 29 : 30 : 31 : 32 : /** 33 : * The \p Pyramid is an element in 3D with 5 sides. 34 : * 35 : * \author Benjamin S. Kirk 36 : * \date 2002 37 : * \brief The base class for all pyramid element types. 38 : */ 39 : class Pyramid : public Cell 40 : { 41 : public: 42 : 43 : /** 44 : * Default pyramid, one quad face, four triangular faces, 45 : * takes number of nodes and parent. 46 : * Derived classes implement 'true' elements. 47 : */ 48 749467 : Pyramid(const unsigned int nn, Elem * p, Node ** nodelinkdata) : 49 749467 : Cell(nn, num_sides, p, _elemlinks_data, nodelinkdata) 50 : { 51 : // Make sure the interior parent isn't undefined 52 : if (LIBMESH_DIM > 3) 53 : this->set_interior_parent(nullptr); 54 2812 : } 55 : 56 : Pyramid (Pyramid &&) = delete; 57 : Pyramid (const Pyramid &) = delete; 58 : Pyramid & operator= (const Pyramid &) = delete; 59 : Pyramid & operator= (Pyramid &&) = delete; 60 2812 : virtual ~Pyramid() = default; 61 : 62 : /** 63 : * \returns The \p Point associated with local \p Node \p i, 64 : * in master element rather than physical coordinates. 65 : */ 66 5136 : virtual Point master_point (const unsigned int i) const override 67 : { 68 240 : libmesh_assert_less(i, this->n_nodes()); 69 5136 : return Point(_master_points[i][0], 70 5136 : _master_points[i][1], 71 5376 : _master_points[i][2]); 72 : } 73 : 74 : /** 75 : * Geometric constants for all Pyramids. 76 : */ 77 : static const int num_sides = 5; 78 : static const int num_edges = 8; 79 : static const int num_children = 0; // not implemented 80 : 81 : /** 82 : * \returns 5. All pyramid-derivatives are guaranteed to have at 83 : * least 5 nodes. 84 : */ 85 2954360 : virtual unsigned int n_nodes() const override { return 5; } 86 : 87 : /** 88 : * \returns 5 89 : */ 90 23661443 : virtual unsigned int n_sides() const override { return 5; } 91 : 92 : /** 93 : * \returns 5. All pyramids have 5 vertices. 94 : */ 95 50228948 : virtual unsigned int n_vertices() const override { return 5; } 96 : 97 : /** 98 : * \returns 8. All pyramids have 8 edges. 99 : */ 100 5928353 : virtual unsigned int n_edges() const override { return 8; } 101 : 102 : /** 103 : * \returns 5. All pyramids have 5 faces. 104 : */ 105 0 : virtual unsigned int n_faces() const override { return 5; } 106 : 107 : /** 108 : * \returns 10. 109 : */ 110 0 : virtual unsigned int n_children() const override { return 10; } 111 : 112 : /** 113 : * \returns \p true if the specified child is on the 114 : * specified side. 115 : */ 116 : virtual bool is_child_on_side(const unsigned int c, 117 : const unsigned int s) const override; 118 : 119 : /** 120 : * \returns \p true if the specified edge is on the specified side. 121 : */ 122 : virtual bool is_edge_on_side(const unsigned int e, 123 : const unsigned int s) const override; 124 : 125 : /** 126 : * Don't hide Elem::key() defined in the base class. 127 : */ 128 : using Elem::key; 129 : 130 : /** 131 : * \returns An id associated with the \p s side of this element. 132 : * The id is not necessarily unique, but should be close. 133 : */ 134 : virtual dof_id_type key (const unsigned int s) const override; 135 : 136 : /** 137 : * \returns An id associated with the \p s side of this element, as 138 : * defined solely by element vertices. The id is not necessarily 139 : * unique, but should be close. This is particularly useful in the 140 : * \p MeshBase::find_neighbors() routine. 141 : */ 142 : virtual dof_id_type low_order_key (const unsigned int s) const override; 143 : 144 : /** 145 : * \returns \p Pyramid5::side_nodes_map[side][side_node] after doing some range checking. 146 : */ 147 : virtual unsigned int local_side_node(unsigned int side, 148 : unsigned int side_node) const override; 149 : 150 : /** 151 : * \returns \p Pyramid5::edge_nodes_map[edge][edge_node] after doing some range checking. 152 : */ 153 : virtual unsigned int local_edge_node(unsigned int edge, 154 : unsigned int edge_node) const override; 155 : 156 : /** 157 : * \returns A primitive triangle or quad for face i. 158 : */ 159 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override; 160 : 161 : /** 162 : * Rebuilds a primitive triangle or quad for face i. 163 : */ 164 : virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) override; 165 : 166 : virtual std::vector<unsigned int> sides_on_edge(const unsigned int e) const override final; 167 : 168 : /** 169 : * \returns Node 4 (the apex) if \p is at the apex within the tolerance 170 : * \p tol. If \p is not at the apex within the tolerance \p tol, will 171 : * return invalid_uint. 172 : * 173 : * The Jacobian at the apex is singular because directional derivatives 174 : * are defined in four directions, independently (four edges meet). 175 : * Therefore, we can check for this in a caught, failed inverse mapping 176 : * and return the correct point without failure if it is the apex. 177 : * This behavior _does_ require exceptions to be enabled. 178 : */ 179 : unsigned int local_singular_node(const Point & p, const Real tol = TOLERANCE*TOLERANCE) const override final; 180 : 181 : /** 182 : * \returns true iff the node at the given index has a singular 183 : * mapping; i.e. is the degree-4 node on a Pyramid. 184 : */ 185 115200 : virtual bool is_singular_node(unsigned int node_idx) const override final { return (node_idx == 4); } 186 : 187 : /** 188 : * One quad side, four orientations. 189 : */ 190 12240 : virtual unsigned int n_permutations() const override final { return 4; } 191 : 192 : virtual bool is_flipped() const override final; 193 : 194 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int n) const override; 195 : 196 : /** 197 : * This maps each edge to the sides that contain said edge. 198 : */ 199 : static const unsigned int edge_sides_map[8][2]; 200 : 201 : virtual bool on_reference_element(const Point & p, 202 : const Real eps = TOLERANCE) const override final; 203 : 204 : protected: 205 : 206 : /** 207 : * Data for links to parent/neighbor/interior_parent elements. 208 : */ 209 : Elem * _elemlinks_data[6+(LIBMESH_DIM>3)]; 210 : 211 : /** 212 : * Master element node locations 213 : */ 214 : static const Real _master_points[14][3]; 215 : 216 : #ifdef LIBMESH_ENABLE_AMR 217 : 218 : /** 219 : * Matrix that allows children to inherit boundary conditions. 220 : */ 221 : unsigned int side_children_matrix (const unsigned int, 222 : const unsigned int) const 223 : { libmesh_not_implemented(); return 0; } 224 : 225 : #endif 226 : 227 : /** 228 : * This maps the \f$ j^{th} \f$ node to the 3 or 4 edge ids adjacent 229 : * to the node. The edge numbering matches the ones used in the 230 : * derived classes' edge_nodes_map. An edge index of 99 is used to 231 : * indicate that there is no adjacent edge. This data structure is 232 : * used in the Pyramid::edges_adjacent_to_node() override and is 233 : * shared by all the derived Hex types. 234 : */ 235 : static const unsigned int adjacent_edges_map[/*num_vertices*/5][/*max_adjacent_edges*/4]; 236 : }; 237 : 238 : } // namespace libMesh 239 : 240 : #endif // LIBMESH_CELL_PYRAMID_H