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_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 : /** 32 : * The \p C0Polyhedron is an element in 3D with an arbitrary (but fixed) 33 : * number of polygonal first-order (C0Polygon) sides. 34 : * 35 : * In master space ... I give up. We've practically got to have a 36 : * definition distinct for every physical element anyway, and we've 37 : * got to give FE and QBase objects access to the physical element, so 38 : * we'll just do all our FE and Quadrature calculations there. 39 : * 40 : * \author Roy H. Stogner 41 : * \date 2025 42 : * \brief A 3D element with an arbitrary number of polygonal 43 : * first-order sides. 44 : */ 45 440 : class C0Polyhedron : public Polyhedron 46 : { 47 : public: 48 : 49 : /** 50 : * Constructor. Takes the sides as an input, and allocates nodes 51 : * accordingly. 52 : * 53 : * By default this element has no parent. 54 : * 55 : * We'll set up a simple default tetrahedralization here, but if users 56 : * want to adjust node positions later they'll want to retriangulate() 57 : * after. 58 : */ 59 : explicit 60 : C0Polyhedron (const std::vector<std::shared_ptr<Polygon>> & sides, 61 : Elem * p=nullptr); 62 : 63 : C0Polyhedron (C0Polyhedron &&) = delete; 64 : C0Polyhedron (const C0Polyhedron &) = delete; 65 : C0Polyhedron & operator= (const C0Polyhedron &) = delete; 66 : C0Polyhedron & operator= (C0Polyhedron &&) = delete; 67 : virtual ~C0Polyhedron(); 68 : 69 : /** 70 : * \returns An Elem of the specified type, which should be the same 71 : * type as \p this, wrapped in a smart pointer. 72 : * 73 : * This is not a complete clone() method (since e.g. it does not set 74 : * node pointers; the standard use case reassigns node pointers from 75 : * a different mesh), but it allows us to more easily copy polyhedra 76 : * objects that depend on side objects and require existing nodes 77 : * and so cannot be constructed with Elem::build(). 78 : */ 79 : std::unique_ptr<Elem> disconnected_clone() const override; 80 : 81 : /** 82 : * \returns \p C0POLYHEDRON. 83 : */ 84 52124741 : virtual ElemType type () const override final { return C0POLYHEDRON; } 85 : 86 : /** 87 : * \returns the number of vertices. For the simple C0Polyhedron 88 : * every node is a vertex. 89 : */ 90 6629110 : virtual unsigned int n_vertices() const override final { return this->_nodelinks_data.size(); } 91 : 92 : /** 93 : * \returns the number of tetrahedra to break this into for 94 : * visualization. 95 : */ 96 0 : virtual unsigned int n_sub_elem() const override 97 0 : { return this->n_subelements(); } 98 : 99 : /** 100 : * \returns \p true if the specified (local) node number is a vertex. 101 : */ 102 : virtual bool is_vertex(const unsigned int i) const override; 103 : 104 : /** 105 : * \returns \p true if the specified (local) node number is an edge. 106 : */ 107 : virtual bool is_edge(const unsigned int i) const override; 108 : 109 : /** 110 : * \returns \p true if the specified (local) node number is a face. 111 : */ 112 : virtual bool is_face(const unsigned int i) const override; 113 : 114 : /** 115 : * \returns \p true if the specified (local) node number is on the 116 : * specified side. 117 : */ 118 : virtual bool is_node_on_side(const unsigned int n, 119 : const unsigned int s) const override; 120 : 121 : virtual std::vector<unsigned int> nodes_on_side(const unsigned int s) const override; 122 : 123 : virtual std::vector<unsigned int> nodes_on_edge(const unsigned int e) const override; 124 : 125 : /** 126 : * \returns \p true if the specified (local) node number is on the 127 : * specified edge. 128 : */ 129 : virtual bool is_node_on_edge(const unsigned int n, 130 : const unsigned int e) const override; 131 : 132 : /** 133 : * \returns \p true if the element map is definitely affine within 134 : * numerical tolerances. We don't even share a master element from 135 : * element to element, so we're going to return false here. 136 : */ 137 157643 : virtual bool has_affine_map () const override { return false; } 138 : 139 : /** 140 : * \returns FIRST 141 : */ 142 311084 : virtual Order default_order() const override { return FIRST; } 143 : 144 : /** 145 : * Don't hide Elem::key() defined in the base class. 146 : */ 147 : using Elem::key; 148 : 149 : virtual void connectivity(const unsigned int sf, 150 : const IOPackage iop, 151 : std::vector<dof_id_type> & conn) const override; 152 : 153 : /** 154 : * Element refinement is not implemented for polyhedra. 155 : */ 156 : virtual std::pair<unsigned short int, unsigned short int> 157 : second_order_child_vertex (const unsigned int n) const override; 158 : 159 : /** 160 : * An optimized method for calculating the area of a C0Polyhedron. 161 : */ 162 : virtual Real volume () const override; 163 : 164 : /** 165 : * An optimized method for calculating the centroid of a C0Polyhedron. 166 : */ 167 : virtual Point true_centroid () const override; 168 : 169 : ElemType side_type (const unsigned int s) const override final; 170 : 171 : /** 172 : * Create a triangulation (tetrahedralization) based on the current 173 : * sides' triangulations. 174 : */ 175 : virtual void retriangulate() override final; 176 : 177 : protected: 178 : 179 : /** 180 : * Add to our triangulation (tetrahedralization). 181 : */ 182 : void add_tet(int n1, int n2, int n3, int n4); 183 : 184 : #ifdef LIBMESH_ENABLE_AMR 185 : 186 : /** 187 : * Matrix used to create the elements children. 188 : */ 189 0 : virtual Real embedding_matrix (const unsigned int /*i*/, 190 : const unsigned int /*j*/, 191 : const unsigned int /*k*/) const override 192 0 : { libmesh_not_implemented(); return 0; } 193 : 194 : #endif // LIBMESH_ENABLE_AMR 195 : 196 : }; 197 : 198 : 199 : } // namespace libMesh 200 : 201 : #endif // LIBMESH_FACE_C0POLYHEDRON_H