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_PRISM18_H 21 : #define LIBMESH_CELL_PRISM18_H 22 : 23 : // Local includes 24 : #include "libmesh/cell_prism.h" 25 : 26 : namespace libMesh 27 : { 28 : 29 : /** 30 : * The \p Prism18 is an element in 3D composed of 18 nodes. 31 : * It is numbered like this: 32 : * 33 : * \verbatim 34 : * PRISM18: 35 : * 5 36 : * o 37 : * /:\ 38 : * / : \ 39 : * / : \ 40 : * / : \ 41 : * 14 o : o 13 42 : * / : \ 43 : * / : \ 44 : * / o 11 \ 45 : * 3 / : \4 46 : * o---------o---------o 47 : * | :12 | 48 : * | : | 49 : * | o : o | zeta 50 : * | 17 o 16 | ^ eta (into page) 51 : * | .2. | | / 52 : * | . . | |/ 53 : * 9 o . o . o 10 o---> xi 54 : * | . 15 . | 55 : * | 8 o o 7 | 56 : * | . . | 57 : * | . . | 58 : * | . . | 59 : * |. .| 60 : * o---------o---------o 61 : * 0 6 1 62 : * \endverbatim 63 : * 64 : * (xi, eta, zeta): { 0 <= xi <= 1 65 : * { 0 <= eta <= 1 66 : * { -1 <= zeta <= 1 67 : * { xi + eta <= 1 68 : * are the reference element coordinates associated with the given 69 : * numbering. 70 : * 71 : * \author Benjamin S. Kirk 72 : * \date 2003 73 : * \brief A 3D prismatic element with 18 nodes. 74 : */ 75 : class Prism18 final : public Prism 76 : { 77 : public: 78 : 79 : /** 80 : * Constructor. By default this element has no parent. 81 : */ 82 : explicit 83 569004 : Prism18 (Elem * p=nullptr) : 84 569004 : Prism(num_nodes, p, _nodelinks_data) 85 569004 : {} 86 : 87 : Prism18 (Prism18 &&) = delete; 88 : Prism18 (const Prism18 &) = delete; 89 : Prism18 & operator= (const Prism18 &) = delete; 90 : Prism18 & operator= (Prism18 &&) = delete; 91 592455 : virtual ~Prism18() = default; 92 : 93 : /** 94 : * \returns \p PRISM18. 95 : */ 96 554616034 : virtual ElemType type () const override { return PRISM18; } 97 : 98 : /** 99 : * \returns 18. 100 : */ 101 151910808 : virtual unsigned int n_nodes() const override { return num_nodes; } 102 : 103 : /** 104 : * \returns 8. 105 : */ 106 0 : virtual unsigned int n_sub_elem() const override { return 8; } 107 : 108 : /** 109 : * \returns \p true if the specified (local) node number is a vertex. 110 : */ 111 : virtual bool is_vertex(const unsigned int i) const override; 112 : 113 : /** 114 : * \returns \p true if the specified (local) node number is an edge. 115 : */ 116 : virtual bool is_edge(const unsigned int i) const override; 117 : 118 : /** 119 : * \returns \p true if the specified (local) node number is a face. 120 : */ 121 : virtual bool is_face(const unsigned int i) const override; 122 : 123 : /** 124 : * \returns \p true if the specified (local) node number is on the 125 : * specified side. 126 : */ 127 : virtual bool is_node_on_side(const unsigned int n, 128 : const unsigned int s) const override; 129 : 130 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 131 : 132 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 133 : 134 : /** 135 : * \returns \p true if the specified (local) node number is on the 136 : * specified edge. 137 : */ 138 : virtual bool is_node_on_edge(const unsigned int n, 139 : const unsigned int e) const override; 140 : 141 : /** 142 : * \returns \p true if the element map is definitely affine within 143 : * numerical tolerances. 144 : */ 145 : virtual bool has_affine_map () const override; 146 : 147 : /** 148 : * \returns SECOND. 149 : */ 150 : virtual Order default_order() const override; 151 : 152 : /** 153 : * Don't hide Elem::key() defined in the base class. 154 : */ 155 : using Elem::key; 156 : 157 : /** 158 : * \returns An id associated with the \p s side of this element. 159 : * The id is not necessarily unique, but should be close. 160 : * 161 : * We reimplement this method here for the \p Prism18 since we can 162 : * use the center node of each quad face to provide a perfect (unique) 163 : * key. 164 : */ 165 : virtual dof_id_type key (const unsigned int s) const override; 166 : 167 : /** 168 : * \returns \p Prism18::side_nodes_map[side][side_node] after doing some range checking. 169 : */ 170 : virtual unsigned int local_side_node(unsigned int side, 171 : unsigned int side_node) const override; 172 : 173 : /** 174 : * \returns \p Prism18::edge_nodes_map[edge][edge_node] after doing some range checking. 175 : */ 176 : virtual unsigned int local_edge_node(unsigned int edge, 177 : unsigned int edge_node) const override; 178 : 179 : /** 180 : * Builds a \p QUAD9 or \p TRI6 built coincident with face i. 181 : * The \p std::unique_ptr<Elem> handles the memory aspect. 182 : */ 183 : virtual std::unique_ptr<Elem> build_side_ptr (const unsigned int i) override; 184 : 185 : /** 186 : * Rebuilds a \p QUAD9 or \p TRI6 built coincident with face i. 187 : */ 188 : virtual void build_side_ptr (std::unique_ptr<Elem> & elem, 189 : const unsigned int i) override; 190 : 191 : // Avoid hiding deprecated version with different signature 192 : using Elem::build_side_ptr; 193 : 194 : /** 195 : * Builds a \p EDGE3 or \p INFEDGE2 built coincident with edge i. 196 : * The \p std::unique_ptr<Elem> handles the memory aspect. 197 : */ 198 : virtual std::unique_ptr<Elem> build_edge_ptr (const unsigned int i) override; 199 : 200 : /** 201 : * Rebuilds a \p EDGE3 built coincident with edges 0 to 2, or \p 202 : * INFEDGE2 built coincident with edges 3 to 5. 203 : */ 204 : virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) override; 205 : 206 : virtual void connectivity(const unsigned int sc, 207 : const IOPackage iop, 208 : std::vector<dof_id_type> & conn) const override; 209 : 210 : /** 211 : * \returns 2 for all edge nodes and 4 for face nodes. 212 : */ 213 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override; 214 : 215 : /** 216 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 217 : * that defines the \f$ n^{th} \f$ second-order node. 218 : * 219 : * \note \p n is counted as depicted above, \f$ 6 \le n < 18 \f$. 220 : */ 221 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n, 222 : const unsigned int v) const override; 223 : 224 : /** 225 : * \returns The child number \p c and element-local index \p v of the 226 : * \f$ n^{th} \f$ second-order node on the parent element. See 227 : * elem.h for further details. 228 : */ 229 : virtual std::pair<unsigned short int, unsigned short int> 230 : second_order_child_vertex (const unsigned int n) const override; 231 : 232 : /** 233 : * Geometric constants for Prism18. 234 : */ 235 : static const int num_nodes = 18; 236 : static const int nodes_per_side = 9; 237 : static const int nodes_per_edge = 3; 238 : 239 : /** 240 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ side to 241 : * element node numbers. 242 : */ 243 : static const unsigned int side_nodes_map[num_sides][nodes_per_side]; 244 : 245 : /** 246 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ edge to 247 : * element node numbers. 248 : */ 249 : static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]; 250 : 251 : /** 252 : * A specialization for computing the volume of a Prism18. 253 : */ 254 : virtual Real volume () const override; 255 : 256 : virtual void permute(unsigned int perm_num) override final; 257 : 258 : virtual void flip(BoundaryInfo *) override final; 259 : 260 : unsigned int center_node_on_side(const unsigned short side) const override final; 261 : 262 : ElemType side_type (const unsigned int s) const override final; 263 : 264 : protected: 265 : 266 : /** 267 : * Data for links to nodes. 268 : */ 269 : Node * _nodelinks_data[num_nodes]; 270 : 271 : 272 : 273 : #ifdef LIBMESH_ENABLE_AMR 274 : 275 : /** 276 : * Matrix used to create the elements children. 277 : */ 278 7171479 : virtual Real embedding_matrix (const unsigned int i, 279 : const unsigned int j, 280 : const unsigned int k) const override 281 7171479 : { return _embedding_matrix[i][j][k]; } 282 : 283 : /** 284 : * Matrix that computes new nodal locations/solution values 285 : * from current nodes/solution. 286 : */ 287 : static const Real _embedding_matrix[num_children][num_nodes][num_nodes]; 288 : 289 58826180 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 290 : 291 : #endif // LIBMESH_ENABLE_AMR 292 : 293 : /** 294 : * Matrix that tells which vertices define the location 295 : * of mid-side (or second-order) nodes. This matrix 296 : * handles only the second-order nodes that are unique 297 : * to \p Prism18. All other second-order nodes are identical 298 : * with \p Prism15, and are therefore handled through a 299 : * matrix contained in \p cell_prism.C 300 : */ 301 : static const unsigned short int _remaining_second_order_adjacent_vertices[3][4]; 302 : }; 303 : 304 : } // namespace libMesh 305 : 306 : #endif // LIBMESH_CELL_PRISM18_H