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_MESH_SMOOTHER_VSMOOTHER_H 21 : #define LIBMESH_MESH_SMOOTHER_VSMOOTHER_H 22 : 23 : #include "libmesh/libmesh_config.h" 24 : #if defined(LIBMESH_ENABLE_VSMOOTHER) 25 : 26 : // Local Includes 27 : #include "libmesh/libmesh_common.h" 28 : #include "libmesh/mesh_smoother.h" 29 : #include "libmesh/variational_smoother_system.h" 30 : #include "libmesh/variational_smoother_constraint.h" 31 : #include "petsc_diff_solver.h" 32 : #include "libmesh/distributed_mesh.h" 33 : #include "libmesh/equation_systems.h" 34 : 35 : // C++ Includes 36 : #include <cstddef> 37 : #include <vector> 38 : #include <map> 39 : #include <fstream> 40 : 41 : namespace libMesh 42 : { 43 : 44 : // Forward declarations 45 : class UnstructuredMesh; 46 : 47 : /** 48 : * This is an implementation of Larisa Branets' smoothing algorithms. 49 : * The initial implementation was done by her, the adaptation to 50 : * libmesh was completed by Derek Gaston. The code was heavily 51 : * refactored into something more closely resembling C++ by John 52 : * Peterson in 2014. The code eventually fell out of use and stopped 53 : * functioning. Patrick Behne reimplemented the smoother in 2025. 54 : * 55 : * Here are the relevant publications: 56 : * 1) L. Branets, G. Carey, "Extension of a mesh quality metric for 57 : * elements with a curved boundary edge or surface", 58 : * Journal of Computing and Information Science in Engineering, vol. 5(4), pp.302-308, 2005. 59 : * 60 : * 2) L. Branets, G. Carey, "A local cell quality metric and variational grid 61 : * smoothing algorithm", Engineering with Computers, vol. 21, pp.19-28, 2005. 62 : * 63 : * 3) L. Branets, "A variational grid optimization algorithm based on a local 64 : * cell quality metric", Ph.D. thesis, The University of Texas at Austin, 2005. 65 : * 66 : * Notes: 67 : * 68 : * 1) The smoother supports tangled meshes. However, not all untangling solves 69 : * converge. In other words, we are able to untangle SOME tangled meshes, but 70 : * not ANY tangled mesh. 71 : * 72 : * \author Derek R. Gaston 73 : * \date 2006 74 : */ 75 : class VariationalMeshSmoother : public MeshSmoother 76 : { 77 : public: 78 : /** 79 : * Constructor. 80 : * @param mesh Mesh to smooth by minimizing the distortion-dilation metric. 81 : * @param dilation_wiehgt Weight to give the dilation metric. The distortion 82 : * metric is given 1 - dilation_weight. 83 : * @param preserve_subdomain_boundaries Whether the smoother is to preserve or 84 : * modify sobdomain boundaries. 85 : * @param relative_residual_tolerance Solver setting for the relative residual tolerance. 86 : * @param absolute_residual_tolerance Solver setting for the absolute residual tolerance. 87 : * @param verbosity Smoother verbosity option specifying how much information 88 : * is output. The verbosity levels and the corresponding information output 89 : * are as follows: 90 : * 91 : * verbosity = 0 : No information 92 : * 93 : * verbosity > 15: Prints: 94 : * - Solver nonlinear and linear iteration information 95 : * 96 : * The VariationalSmootherSystem and VariationalSmootherConstraint classes use 97 : * the same verbosity value as this VariationalMeshSmoother class. For details 98 : * on what those systems print, refer to the documentation for the _verbosity 99 : * attribute in each class. 100 : */ 101 : VariationalMeshSmoother(UnstructuredMesh & mesh, 102 : Real dilation_weight = 0.5, 103 : const bool preserve_subdomain_boundaries = true, 104 : const Real relative_residual_tolerance = TOLERANCE * TOLERANCE, 105 : const Real absolute_residual_tolerance = TOLERANCE * TOLERANCE, 106 : const unsigned int verbosity = 0); 107 : 108 : /** 109 : * Destructor. 110 : */ 111 0 : virtual ~VariationalMeshSmoother() = default; 112 : 113 : /** 114 : * Setup method that creates equation systems, system, and constraints, to be 115 : * called just prior to smoothing. 116 : */ 117 : virtual void setup(); 118 : 119 : /** 120 : * Redefinition of the smooth function from the 121 : * base class. All this does is call the smooth 122 : * function in this class which takes an int, using 123 : * a default value of 1. 124 : */ 125 : virtual void smooth() override; 126 : 127 : /** 128 : * Getter for the _system's _mesh_info attribute 129 : */ 130 : const MeshQualityInfo & get_mesh_info() const; 131 : 132 : private: 133 : 134 : /** 135 : * verbosity setting 136 : */ 137 : const unsigned int _verbosity; 138 : 139 : /** 140 : * Smoother control variables 141 : */ 142 : const Real _dilation_weight; 143 : 144 : /** 145 : * Whether subdomain boundaries are subject to change via smoothing 146 : */ 147 : const bool _preserve_subdomain_boundaries; 148 : 149 : // These must be declared in reverse dependency order to avoid corrupting the 150 : // heap during destruction 151 : 152 : /** 153 : * Mesh copy to avoid multiple EquationSystems. 154 : */ 155 : // independent of _equations_systems and _constraint 156 : std::unique_ptr<DistributedMesh> _mesh_copy; 157 : 158 : /** 159 : * EquationsSystems object associated with the smoother 160 : */ 161 : // uses _mesh_copy, owns the system 162 : std::unique_ptr<EquationSystems> _equation_systems; 163 : 164 : 165 : // Now it's safe to store non-owning pointers to the above 166 : 167 : /* 168 : * System used to smooth the mesh. 169 : */ 170 : // Owned by _equation_systems 171 : VariationalSmootherSystem * _system; 172 : 173 : /** 174 : * Getter for _system to protect against dangling pointers 175 : */ 176 480 : VariationalSmootherSystem * system() const 177 : { 178 480 : libmesh_assert(_system); 179 7448 : return _system; 180 : } 181 : 182 : /** 183 : * Constraints imposed on the smoothing process. 184 : */ 185 : // uses system, which is owned by _equations_systems 186 : std::unique_ptr<VariationalSmootherConstraint> _constraint; 187 : 188 : /** 189 : * Attribute the keep track of whether the setup method has been called. 190 : */ 191 : bool _setup_called; 192 : 193 : /** 194 : * Solver relative residual tolerance 195 : */ 196 : Real _relative_residual_tolerance; 197 : 198 : /** 199 : * Solver absolute residual tolerance 200 : */ 201 : Real _absolute_residual_tolerance; 202 : }; 203 : 204 : } // namespace libMesh 205 : 206 : #endif // defined(LIBMESH_ENABLE_VSMOOTHER) 207 : 208 : #endif // LIBMESH_MESH_SMOOTHER_VSMOOTHER_H