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_PRISM_H 21 : #define LIBMESH_CELL_PRISM_H 22 : 23 : // Local includes 24 : #include "libmesh/cell.h" 25 : 26 : namespace libMesh 27 : { 28 : 29 : /** 30 : * The \p Prism is an element in 3D with 5 sides. 31 : * 32 : * \author Benjamin S. Kirk 33 : * \date 2002 34 : * \brief The base class for all prismatic element types. 35 : */ 36 : class Prism : public Cell 37 : { 38 : public: 39 : 40 : /** 41 : * Default prismatic element, takes number of nodes and 42 : * parent. Derived classes implement 'true' elements. 43 : */ 44 1333076 : Prism(const unsigned int nn, Elem * p, Node ** nodelinkdata) : 45 1333076 : 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 27143 : } 51 : 52 : Prism (Prism &&) = delete; 53 : Prism (const Prism &) = delete; 54 : Prism & operator= (const Prism &) = delete; 55 : Prism & operator= (Prism &&) = delete; 56 27143 : virtual ~Prism() = 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 1453725 : virtual Point master_point (const unsigned int i) const override final 63 : { 64 59628 : libmesh_assert_less(i, this->n_nodes()); 65 1453725 : return Point(_master_points[i][0], 66 1453725 : _master_points[i][1], 67 1513353 : _master_points[i][2]); 68 : } 69 : 70 : /** 71 : * Geometric constants for all Prisms. 72 : */ 73 : static const int num_sides = 5; 74 : static const int num_edges = 9; 75 : static const int num_children = 8; 76 : 77 : /** 78 : * \returns 6. All prism-derivatives are guaranteed to have at 79 : * least 6 nodes. 80 : */ 81 132196614 : virtual unsigned int n_nodes() const override { return 6; } 82 : 83 : /** 84 : * \returns 5. 85 : */ 86 86294638 : virtual unsigned int n_sides() const override final { return 5; } 87 : 88 : /** 89 : * \returns 6. All prisms have 6 vertices. 90 : */ 91 174390096 : virtual unsigned int n_vertices() const override final { return 6; } 92 : 93 : /** 94 : * \returns 9. All prisms have 9 edges. 95 : */ 96 38389215 : virtual unsigned int n_edges() const override final { return 9; } 97 : 98 : /** 99 : * \returns 5. All prisms have 5 faces. 100 : */ 101 23469750 : virtual unsigned int n_faces() const override final { return 5; } 102 : 103 : /** 104 : * \returns 8. 105 : */ 106 70909156 : virtual unsigned int n_children() const override final { return 8; } 107 : 108 : /** 109 : * \returns \p true if the specified child is on the specified side. 110 : */ 111 : virtual bool is_child_on_side(const unsigned int c, 112 : const unsigned int s) const override final; 113 : 114 : /** 115 : * \returns \p true if the specified edge is on the specified side. 116 : */ 117 : virtual bool is_edge_on_side(const unsigned int e, 118 : const unsigned int s) const override final; 119 : 120 : /** 121 : * \returns The side number opposite to \p s (for the triangular 122 : * sides) or \p invalid_uint (for the quad sides) 123 : */ 124 : virtual unsigned int opposite_side(const unsigned int s) const override final; 125 : 126 : /** 127 : * Don't hide Elem::key() defined in the base class. 128 : */ 129 : using Elem::key; 130 : 131 : /** 132 : * \returns An id associated with the \p s side of this element. 133 : * The id is not necessarily unique, but should be close. 134 : */ 135 : virtual dof_id_type key (const unsigned int s) const override; 136 : 137 : /** 138 : * \returns An id associated with the \p s side of this element, as 139 : * defined solely by element vertices. The id is not necessarily 140 : * unique, but should be close. This is particularly useful in the 141 : * \p MeshBase::find_neighbors() routine. 142 : */ 143 : virtual dof_id_type low_order_key (const unsigned int s) const override; 144 : 145 : /** 146 : * \returns \p Prism6::side_nodes_map[side][side_node] after doing some range checking. 147 : */ 148 : virtual unsigned int local_side_node(unsigned int side, 149 : unsigned int side_node) const override; 150 : 151 : /** 152 : * \returns \p Prism6::edge_nodes_map[edge][edge_node] after doing some range checking. 153 : */ 154 : virtual unsigned int local_edge_node(unsigned int edge, 155 : unsigned int edge_node) const override; 156 : 157 : /** 158 : * \returns A primitive triangle or quad for face i. 159 : */ 160 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final; 161 : 162 : /** 163 : * Rebuilds a primitive triangle or quad for face i. 164 : */ 165 : virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) override final; 166 : 167 : virtual std::vector<unsigned int> sides_on_edge(const unsigned int e) const override final; 168 : 169 : /** 170 : * Two triangular sides, three orientations. 171 : */ 172 68798 : virtual unsigned int n_permutations() const override final { return 6; } 173 : 174 : virtual bool is_flipped() const override final; 175 : 176 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int n) const override; 177 : 178 : /** 179 : * This maps each edge to the sides that contain said edge. 180 : */ 181 : static const unsigned int edge_sides_map[9][2]; 182 : 183 : virtual bool on_reference_element(const Point & p, 184 : const Real eps = TOLERANCE) const override final; 185 : 186 : protected: 187 : 188 : /** 189 : * Data for links to parent/neighbor/interior_parent elements. 190 : */ 191 : Elem * _elemlinks_data[6+(LIBMESH_DIM>3)]; 192 : 193 : /** 194 : * Matrix that tells which vertices define the location 195 : * of mid-side (or second-order) nodes. for the first 196 : * 9 second-order nodes, this matrix is identical for 197 : * \p Prism15 and \p Prism18, therefore store it here. 198 : */ 199 : static const unsigned short int _second_order_adjacent_vertices[9][2]; 200 : 201 : /** 202 : * Vector that names a child sharing each second order node. 203 : */ 204 : static const unsigned short int _second_order_vertex_child_number[18]; 205 : 206 : /** 207 : * Vector that names the child vertex index for each second order node. 208 : */ 209 : static const unsigned short int _second_order_vertex_child_index[18]; 210 : 211 : /** 212 : * Master element node locations 213 : */ 214 : static const Real _master_points[18][3]; 215 : 216 : /** 217 : * This maps the \f$ j^{th} \f$ Prism vertex to the (in this case) 3 218 : * edge ids adjacent to the node. The edge numbering matches the one 219 : * used in the derived classes' edge_nodes_map. This data structure 220 : * is used in the Prism::edges_adjacent_to_node() override and is 221 : * shared by all the derived Prism types. 222 : */ 223 : static const unsigned int adjacent_edges_map[/*num_vertices*/6][/*n_adjacent_edges*/3]; 224 : }; 225 : 226 : } // namespace libMesh 227 : 228 : #endif // LIBMESH_CELL_PRISM_H