Line data Source code
1 : // The libMesh Finite Element Library. 2 : // Copyright (C) 2002-2026 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_FACE_C0POLYHEDRON_H 21 : #define LIBMESH_FACE_C0POLYHEDRON_H 22 : 23 : // Local includes 24 : #include "libmesh/libmesh_common.h" 25 : #include "libmesh/cell_polyhedron.h" 26 : #include "libmesh/enum_order.h" 27 : 28 : namespace libMesh 29 : { 30 : 31 : class Node; 32 : 33 : /** 34 : * The \p C0Polyhedron is an element in 3D with an arbitrary (but fixed) 35 : * number of polygonal first-order (C0Polygon) sides. 36 : * 37 : * In master space ... I give up. We've practically got to have a 38 : * definition distinct for every physical element anyway, and we've 39 : * got to give FE and QBase objects access to the physical element, so 40 : * we'll just do all our FE and Quadrature calculations there. 41 : * 42 : * \author Roy H. Stogner 43 : * \date 2025 44 : * \brief A 3D element with an arbitrary number of polygonal 45 : * first-order sides. 46 : */ 47 696 : class C0Polyhedron : public Polyhedron 48 : { 49 : public: 50 : 51 : /** 52 : * Constructor. Takes the sides as an input, and allocates nodes 53 : * accordingly. 54 : * 55 : * By default this element has no parent. 56 : * 57 : * We'll set up a simple default tetrahedralization here, but if users 58 : * want to adjust node positions later they'll want to retriangulate() 59 : * after. 60 : * @param mid_elem_node a reference to the unique pointer set to the mid-element node, 61 : * only if the default (optimal) tetrahedralization algorithm fails, and the backup 62 : * trivial algorithm is used to tetrahedralize the element. 63 : * It's the caller's job to add this node to the mesh after! 64 : * @param p pointer to the parent element of this one (useful for h-refinement) 65 : */ 66 : explicit 67 : C0Polyhedron (const std::vector<std::shared_ptr<Polygon>> & sides, 68 : std::unique_ptr<Node> & mid_elem_node, 69 : Elem * p=nullptr); 70 : 71 : C0Polyhedron (C0Polyhedron &&) = delete; 72 : C0Polyhedron (const C0Polyhedron &) = delete; 73 : C0Polyhedron & operator= (const C0Polyhedron &) = delete; 74 : C0Polyhedron & operator= (C0Polyhedron &&) = delete; 75 : virtual ~C0Polyhedron(); 76 : 77 : /** 78 : * \returns An Elem of the specified type, which should be the same 79 : * type as \p this, wrapped in a smart pointer. 80 : * 81 : * This is not a complete clone() method (since e.g. it does not set 82 : * node pointers; the standard use case reassigns node pointers from 83 : * a different mesh), but it allows us to more easily copy polyhedra 84 : * objects that depend on side objects and require existing nodes 85 : * and so cannot be constructed with Elem::build(). 86 : */ 87 : std::unique_ptr<Elem> disconnected_clone() const override; 88 : 89 : /** 90 : * \returns \p C0POLYHEDRON. 91 : */ 92 94847727 : virtual ElemType type () const override final { return C0POLYHEDRON; } 93 : 94 : /** 95 : * \returns the number of vertices. For the simple C0Polyhedron 96 : * every node is a vertex. 97 : */ 98 : virtual unsigned int n_vertices() const override final; 99 : 100 : /** 101 : * \returns the number of tetrahedra to break this into for 102 : * visualization. 103 : */ 104 2059 : virtual unsigned int n_sub_elem() const override 105 2059 : { return this->n_subelements(); } 106 : 107 : /** 108 : * \returns \p true if the specified (local) node number is a vertex. 109 : */ 110 : virtual bool is_vertex(const unsigned int i) const override; 111 : 112 : /** 113 : * \returns \p true if the specified (local) node number is an edge. 114 : */ 115 : virtual bool is_edge(const unsigned int i) const override; 116 : 117 : /** 118 : * \returns \p true if the specified (local) node number is a face. 119 : */ 120 : virtual bool is_face(const unsigned int i) const override; 121 : 122 : /** 123 : * \returns \p true if the specified (local) node number is on the 124 : * specified side. 125 : */ 126 : virtual bool is_node_on_side(const unsigned int n, 127 : const unsigned int s) const override; 128 : 129 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 130 : 131 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 132 : 133 : /** 134 : * \returns \p true if the specified (local) node number is on the 135 : * specified edge. 136 : */ 137 : virtual bool is_node_on_edge(const unsigned int n, 138 : const unsigned int e) const override; 139 : 140 : virtual std::vector<unsigned int> edges_adjacent_to_node(const unsigned int n) const override; 141 : 142 : /** 143 : * \returns \p true if the element map is definitely affine within 144 : * numerical tolerances. We don't even share a master element from 145 : * element to element, so we're going to return false here. 146 : */ 147 275902 : virtual bool has_affine_map () const override { return false; } 148 : 149 : /** 150 : * \returns FIRST 151 : */ 152 544254 : virtual Order default_order() const override { return FIRST; } 153 : 154 : /** 155 : * Don't hide Elem::key() defined in the base class. 156 : */ 157 : using Elem::key; 158 : 159 : virtual void connectivity(const unsigned int sf, 160 : const IOPackage iop, 161 : std::vector<dof_id_type> & conn) const override; 162 : 163 : /** 164 : * Element refinement is not implemented for polyhedra. 165 : */ 166 : virtual std::pair<unsigned short int, unsigned short int> 167 : second_order_child_vertex (const unsigned int n) const override; 168 : 169 : /** 170 : * An optimized method for calculating the area of a C0Polyhedron. 171 : */ 172 : virtual Real volume () const override; 173 : 174 : /** 175 : * An optimized method for calculating the centroid of a C0Polyhedron. 176 : */ 177 : virtual Point true_centroid () const override; 178 : 179 : ElemType side_type (const unsigned int s) const override final; 180 : 181 : Point side_vertex_average_normal(const unsigned int s) const override final; 182 : 183 : /** 184 : * \returns the local side-indices of subelement sides of the 185 : * polyhedron 186 : * Each subelement here is a tetrahedron 187 : * @param i the index of the sub-element 188 : * The return array is indexed by sides of the subelement, and contains the 189 : * index of the side of the polyhedron if the sub-element side is on that side, 190 : * or libMesh::invalid_uint if the subelement side is internal to the polyhedron 191 : * NOTE: this routine involves a loop over the sides of the polyhedron 192 : */ 193 : virtual std::array<int, 4> subelement_sides_to_poly_sides(unsigned int i) const; 194 : 195 : /** 196 : * Create a triangulation (tetrahedralization) based on the current 197 : * sides' triangulations. 198 : */ 199 : virtual void retriangulate() override final; 200 : 201 : protected: 202 : 203 : /** 204 : * Add to our triangulation (tetrahedralization). 205 : */ 206 : void add_tet(int n1, int n2, int n3, int n4); 207 : 208 : #ifdef LIBMESH_ENABLE_AMR 209 : 210 : /** 211 : * Matrix used to create the elements children. 212 : */ 213 0 : virtual Real embedding_matrix (const unsigned int /*i*/, 214 : const unsigned int /*j*/, 215 : const unsigned int /*k*/) const override 216 0 : { libmesh_not_implemented(); return 0; } 217 : 218 : #endif // LIBMESH_ENABLE_AMR 219 : 220 : /** 221 : * Whether we have a mid element node 222 : */ 223 : bool _has_mid_elem_node; 224 : }; 225 : 226 : 227 : } // namespace libMesh 228 : 229 : #endif // LIBMESH_FACE_C0POLYHEDRON_H