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 : #ifndef LIBMESH_MESH_TET_INTERFACE_H 20 : #define LIBMESH_MESH_TET_INTERFACE_H 21 : 22 : #include "libmesh/libmesh_config.h" 23 : 24 : // Local includes 25 : #include "libmesh/bounding_box.h" 26 : #include "libmesh/enum_elem_type.h" 27 : #include "libmesh/point.h" // used for specifying holes 28 : 29 : // C++ includes 30 : #include <cstddef> 31 : #include <map> 32 : #include <memory> 33 : #include <string> 34 : #include <vector> 35 : 36 : namespace libMesh 37 : { 38 : // Forward Declarations 39 : class UnstructuredMesh; 40 : class Elem; 41 : 42 : /** 43 : * Class \p MeshTetInterface provides an abstract interface for 44 : * tetrahedralization of meshes by subclasses. 45 : * 46 : * \author Roy H. Stogner 47 : * \date 2024 48 : */ 49 56 : class MeshTetInterface 50 : { 51 : public: 52 : 53 : /** 54 : * Constructor. Takes a reference to the mesh. 55 : */ 56 : explicit 57 : MeshTetInterface (UnstructuredMesh & mesh); 58 : 59 : /** 60 : * Default destructor in base class. 61 : */ 62 : virtual ~MeshTetInterface(); 63 : 64 : /** 65 : * Sets and/or gets the desired tetrahedron volume. Set to zero to 66 : * disable volume constraint. 67 : */ 68 0 : Real & desired_volume() {return _desired_volume;} 69 : 70 : /** 71 : * Sets/gets flag which tells whether to do two steps of Laplace 72 : * mesh smoothing after generating the grid. False by default (for 73 : * compatibility with old TetGenMeshInterface behavior). 74 : */ 75 : bool & smooth_after_generating() {return _smooth_after_generating;} 76 : 77 : /** 78 : * Sets and/or gets the desired element type. This should be a Tet 79 : * type. 80 : */ 81 : ElemType & elem_type() {return _elem_type;} 82 : 83 : /** 84 : * Attaches a vector of Mesh pointers defining holes which will be 85 : * meshed around. We use unique_ptr here because we expect that we 86 : * may need to modify these meshes internally. 87 : */ 88 : void attach_hole_list(std::unique_ptr<std::vector<std::unique_ptr<UnstructuredMesh>>> holes); 89 : 90 : /** 91 : * This is the main public interface for this function. 92 : */ 93 : virtual void triangulate () = 0; 94 : 95 : /** 96 : * Sets a verbosity level, defaulting to 0 (print nothing), to be 97 : * set as high as 100 (print everything). 98 : * 99 : * For verbosity >= 50, print all detected surface mesh integrity 100 : * issues as they're found. Subclasses may add other output at 101 : * other verbosity levels. 102 : */ 103 : void set_verbosity(unsigned int v); 104 : 105 : protected: 106 : 107 : /** 108 : * verbosity setting 109 : */ 110 : unsigned int _verbosity; 111 : 112 : /** 113 : * Remove volume elements from the given mesh, after converting 114 : * their outer boundary faces to surface elements. 115 : * 116 : * Returns the bounding box of the mesh; this is useful for 117 : * detecting misplaced holes later. 118 : */ 119 : static BoundingBox volume_to_surface_mesh (UnstructuredMesh & mesh); 120 : 121 : /** 122 : * Enumeration of possible surface mesh integrity issues. 123 : */ 124 : enum SurfaceIntegrity { 125 : NON_TRI3 = 1, // a non-TRI3 element is found 126 : MISSING_NEIGHBOR = 2, // an element with a nullptr-neighbor is found 127 : EMPTY_MESH = 3, // the mesh is empty 128 : MISSING_BACKLINK = 4, // an element neighbor isn't linked back to it 129 : BAD_NEIGHBOR_NODES = 5, // an element neighbor isn't linked to expected nodes 130 : NON_ORIENTED = 6, // an element neighbor has inconsistent orientation 131 : BAD_NEIGHBOR_LINKS = 7, // an element neighbor has other inconsistent links 132 : DEGENERATE_ELEMENT = 8, // an element has zero area 133 : DEGENERATE_MESH = 9 // the mesh clearly bounds zero volume 134 : }; 135 : 136 : /** 137 : * This function checks the integrity of the current set of 138 : * elements in the Mesh to see if they comprise a topological 139 : * manifold that (if it's also geometrically valid) would define 140 : * valid boundary for a tetrahedralized volume. 141 : * 142 : * Named \p check_hull_integrity() for backward compatibility, but 143 : * now accepts non-convex manifolds. 144 : * 145 : * \returns a set of \p enums describing problems 146 : * found, or an empty set if no problems are found. 147 : */ 148 : [[nodiscard]] std::set<SurfaceIntegrity> check_hull_integrity() const; 149 : 150 : /** 151 : * This function checks the integrity of the current set of 152 : * elements in the Mesh, and corrects what it can. 153 : * 154 : * \returns A set of SurfaceIntegrity codes from \p 155 : * check_hull_integrity() if there are problems it can't fix, or an 156 : * empty set otherwise. 157 : */ 158 : [[nodiscard]] std::set<SurfaceIntegrity> improve_hull_integrity(); 159 : 160 : /** 161 : * This function prints an informative message and throws an 162 : * exception based on the output of the check_hull_integrity() 163 : * function. It is a separate function so that you can check hull 164 : * integrity without exiting or catching an exception if desired. 165 : */ 166 : void process_hull_integrity_result(const std::set<SurfaceIntegrity> & result) const; 167 : 168 : /** 169 : * Delete original convex hull elements from the Mesh 170 : * after performing a Delaunay tetrahedralization. 171 : */ 172 : void delete_2D_hull_elements(); 173 : 174 : /** 175 : * The desired volume for the elements in the resulting mesh. 176 : * Unlimited (indicated by 0) by default 177 : */ 178 : Real _desired_volume; 179 : 180 : /** 181 : * Flag which tells whether we should smooth the mesh after 182 : * it is generated. False by default. 183 : */ 184 : bool _smooth_after_generating; 185 : 186 : /** 187 : * The exact type of tetrahedra we intend to construct 188 : */ 189 : ElemType _elem_type; 190 : 191 : /** 192 : * Local reference to the mesh we are working with. 193 : */ 194 : UnstructuredMesh & _mesh; 195 : 196 : /** 197 : * A pointer to a vector of meshes each defining a hole. If this is 198 : * nullptr, there are no holes! 199 : */ 200 : std::unique_ptr<std::vector<std::unique_ptr<UnstructuredMesh>>> _holes; 201 : }; 202 : 203 : 204 : // ------------------------------------------------------------ 205 : // MeshTetInterface class member functions 206 : inline 207 : void 208 : MeshTetInterface::set_verbosity(unsigned int v) 209 : { 210 : this->_verbosity = v; 211 : } 212 : 213 : 214 : } // namespace libMesh 215 : 216 : #endif // LIBMESH_MESH_TET_INTERFACE_H