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_PRISM20_H 21 : #define LIBMESH_CELL_PRISM20_H 22 : 23 : // Local includes 24 : #include "libmesh/cell_prism.h" 25 : 26 : namespace libMesh 27 : { 28 : 29 : /** 30 : * The \p Prism20 is an element in 3D composed of 20 nodes. 31 : * It is numbered like this: 32 : * 33 : * \verbatim 34 : * PRISM20: 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 : * And it also includes two face nodes: 65 : * Node 18, centroid on side 0, arithmetic mean of 0/1/2 or 6/7/8 66 : * Node 19, centroid on side 4, arithmetic mean of 3/4/5 or 12/13/14 67 : * 68 : * (xi, eta, zeta): { 0 <= xi <= 1 69 : * { 0 <= eta <= 1 70 : * { -1 <= zeta <= 1 71 : * { xi + eta <= 1 72 : * are the reference element coordinates associated with the given 73 : * numbering. 74 : * 75 : * \author Roy H. Stogner 76 : * \date 2022 77 : * \brief A 3D prismatic element with 20 nodes. 78 : */ 79 : class Prism20 final : public Prism 80 : { 81 : public: 82 : 83 : /** 84 : * Constructor. By default this element has no parent. 85 : */ 86 : explicit 87 105382 : Prism20 (Elem * p=nullptr) : 88 105382 : Prism(num_nodes, p, _nodelinks_data) 89 105382 : {} 90 : 91 : Prism20 (Prism20 &&) = delete; 92 : Prism20 (const Prism20 &) = delete; 93 : Prism20 & operator= (const Prism20 &) = delete; 94 : Prism20 & operator= (Prism20 &&) = delete; 95 109275 : virtual ~Prism20() = default; 96 : 97 : /** 98 : * \returns \p PRISM20. 99 : */ 100 1743389285 : virtual ElemType type () const override { return PRISM20; } 101 : 102 : /** 103 : * \returns 20. 104 : */ 105 416487214 : virtual unsigned int n_nodes() const override { return num_nodes; } 106 : 107 : /** 108 : * \returns 8. 109 : */ 110 0 : virtual unsigned int n_sub_elem() const override { return 8; } 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 Elem::key() defined in the base class. 158 : */ 159 : using Elem::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 Prism20 since we can 166 : * use the center node of each quad 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 Prism20::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 Prism20::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 built 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 or \p INFEDGE2 built 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 built coincident with edges 0 to 2, or \p 206 : * INFEDGE2 built coincident with edges 3 to 5. 207 : */ 208 : virtual void build_edge_ptr (std::unique_ptr<Elem> & edge, const unsigned int i) override; 209 : 210 : virtual void connectivity(const unsigned int sc, 211 : const IOPackage iop, 212 : std::vector<dof_id_type> & conn) const override; 213 : 214 : /** 215 : * \returns 2 for all edge nodes, 4 for quad face nodes, 6 for tri 216 : * face nodes. 217 : */ 218 : virtual unsigned int n_second_order_adjacent_vertices (const unsigned int) const override; 219 : 220 : /** 221 : * \returns The element-local number of the \f$ v^{th} \f$ vertex 222 : * that defines the \f$ n^{th} \f$ second-order node. 223 : * 224 : * \note \p n is counted as depicted above, \f$ 6 \le n < 20 \f$. 225 : */ 226 : virtual unsigned short int second_order_adjacent_vertex (const unsigned int n, 227 : const unsigned int v) const override; 228 : 229 : /** 230 : * \returns The child number \p c and element-local index \p v of the 231 : * \f$ n^{th} \f$ second-order node on the parent element. See 232 : * elem.h for further details. 233 : */ 234 : virtual std::pair<unsigned short int, unsigned short int> 235 : second_order_child_vertex (const unsigned int n) const override; 236 : 237 : /** 238 : * Geometric constants for Prism20. 239 : */ 240 : static const int num_nodes = 20; 241 : static const int nodes_per_side = 9; 242 : static const int nodes_per_edge = 3; 243 : 244 : /** 245 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ side to 246 : * element node numbers. 247 : */ 248 : static const unsigned int side_nodes_map[num_sides][nodes_per_side]; 249 : 250 : /** 251 : * This maps the \f$ j^{th} \f$ node of the \f$ i^{th} \f$ edge to 252 : * element node numbers. 253 : */ 254 : static const unsigned int edge_nodes_map[num_edges][nodes_per_edge]; 255 : 256 : virtual void permute(unsigned int perm_num) override final; 257 : 258 : virtual void flip(BoundaryInfo *) override final; 259 : 260 : #ifdef LIBMESH_ENABLE_AMR 261 : virtual 262 : const std::vector<std::pair<unsigned char, unsigned char>> & 263 0 : parent_bracketing_nodes(unsigned int, 264 : unsigned int) const override 265 : { 266 : // We can't get any good bracketing nodes for child tri-center 267 : // nodes on the parent prism midplane. No refining Prism20 for 268 : // us. 269 0 : libmesh_not_implemented_msg("Prism20 cannot be refined; use Prism21 instead."); 270 : } 271 : #endif 272 : 273 : unsigned int center_node_on_side(const unsigned short side) const override final; 274 : 275 : ElemType side_type (const unsigned int s) const override final; 276 : 277 : protected: 278 : 279 : /** 280 : * Data for links to nodes. 281 : */ 282 : Node * _nodelinks_data[num_nodes]; 283 : 284 : 285 : 286 : #ifdef LIBMESH_ENABLE_AMR 287 : 288 : /** 289 : * Matrix used to create the elements children. 290 : */ 291 0 : virtual Real embedding_matrix (const unsigned int, 292 : const unsigned int, 293 : const unsigned int) const override 294 : { 295 : // We can't get any good bracketing nodes for child tri-center 296 : // nodes on the parent prism midplane, so we can't auto-calculate 297 : // embedding matrices and couldn't use them if we did. 298 0 : libmesh_not_implemented_msg("Prism20 cannot be refined; use Prism21 instead."); 299 : return 0; 300 : } 301 : 302 0 : LIBMESH_ENABLE_TOPOLOGY_CACHES; 303 : 304 : #endif // LIBMESH_ENABLE_AMR 305 : 306 : /** 307 : * Matrix that tells which vertices define the location 308 : * of mid-side (or second-order) nodes. This matrix 309 : * handles only the second-order nodes that are unique 310 : * to \p Prism20. All other second-order nodes are identical 311 : * with \p Prism15, and are therefore handled through a 312 : * matrix contained in \p cell_prism.C 313 : */ 314 : static const unsigned short int _remaining_second_order_adjacent_vertices[5][4]; 315 : }; 316 : 317 : } // namespace libMesh 318 : 319 : #endif // LIBMESH_CELL_PRISM20_H