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_INF_PRISM_H 21 : #define LIBMESH_CELL_INF_PRISM_H 22 : 23 : #include "libmesh/libmesh_config.h" 24 : 25 : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 26 : 27 : // Local includes 28 : #include "libmesh/cell_inf.h" 29 : 30 : namespace libMesh 31 : { 32 : 33 : /** 34 : * The \p InfPrism is an element in 3D with 4 sides. 35 : * The \f$ 5^{th} \f$ side is theoretically located at infinity, 36 : * and therefore not accounted for. 37 : * However, one could say that the \f$ 5^{th} \f$ side actually 38 : * does exist in the mesh, since the outer nodes are located 39 : * at a specific distance from the mesh origin (and therefore 40 : * define a side). Still, this face is not to be used! 41 : * 42 : * \author Daniel Dreyer 43 : * \date 2003 44 : * \brief The base class for all 3D infinite prismatic element types. 45 : */ 46 : class InfPrism : public InfCell 47 : { 48 : public: 49 : 50 : /** 51 : * Default infinite prism element, takes number of nodes and 52 : * parent. Derived classes implement 'true' elements. 53 : */ 54 652 : InfPrism(const unsigned int nn, Elem * p, Node ** nodelinkdata) : 55 652 : InfCell(nn, num_sides, p, _elemlinks_data, nodelinkdata) 56 200 : {} 57 : 58 : InfPrism (InfPrism &&) = delete; 59 : InfPrism (const InfPrism &) = delete; 60 : InfPrism & operator= (const InfPrism &) = delete; 61 : InfPrism & operator= (InfPrism &&) = delete; 62 200 : virtual ~InfPrism() = default; 63 : 64 : /** 65 : * \returns The \p Point associated with local \p Node \p i, 66 : * in master element rather than physical coordinates. 67 : */ 68 12590 : virtual Point master_point (const unsigned int i) const override final 69 : { 70 5036 : libmesh_assert_less(i, this->n_nodes()); 71 12590 : return Point(_master_points[i][0], 72 12590 : _master_points[i][1], 73 17626 : _master_points[i][2]); 74 : } 75 : 76 : /** 77 : * Geometric constants for all InfPrisms. 78 : */ 79 : static const int num_sides = 4; 80 : static const int num_edges = 6; 81 : static const int num_children = 4; 82 : 83 : /** 84 : * \returns 4. Infinite elements have one side less 85 : * than their conventional counterparts, since one 86 : * side is supposed to be located at infinity. 87 : */ 88 329712 : virtual unsigned int n_sides() const override final { return 4; } 89 : 90 : /** 91 : * \returns 6. All infinite prisms (in our 92 : * setting) have 6 vertices. 93 : */ 94 210355 : virtual unsigned int n_vertices() const override final { return 6; } 95 : 96 : /** 97 : * \returns 6. All infinite prisms have 6 edges, 98 : * 3 lying in the base, and 3 perpendicular to the base. 99 : */ 100 48652 : virtual unsigned int n_edges() const override final { return 6; } 101 : 102 : /** 103 : * \returns 4. All prisms have 4 faces. 104 : */ 105 0 : virtual unsigned int n_faces() const override final { return 4; } 106 : 107 : /** 108 : * \returns 4. 109 : */ 110 15616 : virtual unsigned int n_children() const override final { return 4; } 111 : 112 : /** 113 : * We number vertices first. 114 : */ 115 40854 : virtual bool is_vertex(const unsigned int i) const override final { return (i < 6); } 116 : 117 : /** 118 : * We number edges next. 119 : */ 120 96 : virtual bool is_edge(const unsigned int i) const override final { return (i >= 6 && i < 9); } 121 : 122 : /** 123 : * We number faces last. 124 : */ 125 24 : virtual bool is_face(const unsigned int i) const override final { return (i >= 9 && i < 12); } 126 : 127 : /** 128 : * \returns \p true if the specified (local) node number is a 129 : * "mid-edge" node on an infinite element edge. 130 : */ 131 120 : virtual bool is_mid_infinite_edge_node(const unsigned int i) const 132 120 : override final { return (i > 2 && i < 6); } 133 : 134 : /** 135 : * \returns \p true if the specified child is on the specified side. 136 : */ 137 : virtual bool is_child_on_side(const unsigned int c, 138 : const unsigned int s) const override final; 139 : 140 : /** 141 : * \returns \p true if the specified edge is on the specified side. 142 : */ 143 : virtual bool is_edge_on_side(const unsigned int e, 144 : const unsigned int s) const override final; 145 : 146 : /** 147 : * Don't hide Elem::key() defined in the base class. 148 : */ 149 : using Elem::key; 150 : 151 : /** 152 : * \returns An id associated with the \p s side of this element. 153 : * The id is not necessarily unique, but should be close. 154 : */ 155 : virtual dof_id_type key (const unsigned int s) const override; 156 : 157 : /** 158 : * \returns An id associated with the \p s side of this element, as 159 : * defined solely by element vertices. The id is not necessarily 160 : * unique, but should be close. This is particularly useful in the 161 : * \p MeshBase::find_neighbors() routine. 162 : */ 163 : virtual dof_id_type low_order_key (const unsigned int s) const override; 164 : 165 : /** 166 : * \returns InfPrism6::side_nodes_map[side][side_node] after doing some range checking. 167 : */ 168 : virtual unsigned int local_side_node(unsigned int side, 169 : unsigned int side_node) const override; 170 : 171 : /** 172 : * \returns InfPrism6::edge_nodes_map[edge][edge_node] after doing some range checking. 173 : */ 174 : virtual unsigned int local_edge_node(unsigned int edge, 175 : unsigned int edge_node) const override; 176 : 177 : /** 178 : * \returns A primitive (3-noded) tri or (4-noded) infquad for 179 : * face i. 180 : */ 181 : virtual std::unique_ptr<Elem> side_ptr (const unsigned int i) override final; 182 : 183 : /** 184 : * Rebuilds a primitive (3-noded) tri or (4-noded) infquad for face 185 : * i. 186 : */ 187 : virtual void side_ptr (std::unique_ptr<Elem> & side, const unsigned int i) override final; 188 : 189 : /** 190 : * @returns \p true when this element contains the point 191 : * \p p. Customized for infinite elements, since knowledge 192 : * about the envelope can be helpful. 193 : */ 194 : virtual bool contains_point (const Point & p, Real tol=TOLERANCE) const override; 195 : 196 : /** 197 : * One non-infinite side, three orientations. 198 : */ 199 0 : virtual unsigned int n_permutations() const override final { return 3; } 200 : 201 : std::vector<unsigned int> sides_on_edge(const unsigned int e) const override final; 202 : 203 : virtual bool is_flipped() const override final; 204 : 205 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int n) const override; 206 : 207 : /** 208 : * This maps each edge to the sides that contain said edge. 209 : */ 210 : static const unsigned int edge_sides_map[6][2]; 211 : 212 : virtual bool on_reference_element(const Point & p, 213 : const Real eps = TOLERANCE) const override final; 214 : 215 : protected: 216 : 217 : /** 218 : * Data for links to parent/neighbor/interior_parent elements. 219 : */ 220 : Elem * _elemlinks_data[5+(LIBMESH_DIM>3)]; 221 : 222 : /** 223 : * Master element node locations 224 : */ 225 : static const Real _master_points[12][3]; 226 : 227 : /** 228 : * This maps the \f$ j^{th} \f$ node to the 3 (or fewer) edge ids 229 : * adjacent to the node. The edge numbering matches the ones used in 230 : * the derived classes' edge_nodes_map. An edge index of 99 is used 231 : * to indicate that there is no adjacent edge. This data structure 232 : * is used in the InfPrism::edges_adjacent_to_node() override and is 233 : * shared by all the derived InfPrism types. 234 : */ 235 : static const unsigned int adjacent_edges_map[/*num_vertices*/6][/*max_adjacent_edges*/3]; 236 : }; 237 : 238 : } // namespace libMesh 239 : 240 : #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 241 : 242 : #endif // LIBMESH_CELL_INF_PRISM_H