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 0 : virtual void smooth() override {this->smooth(1); } 126 : 127 : /** 128 : * The actual smoothing function, gets called whenever 129 : * the user specifies an actual number of smoothing 130 : * iterations. 131 : */ 132 : void smooth(unsigned int n_iterations); 133 : 134 : /** 135 : * Getter for the _system's _mesh_info attribute 136 : */ 137 : const MeshQualityInfo & get_mesh_info() const; 138 : 139 : private: 140 : 141 : /** 142 : * verbosity setting 143 : */ 144 : const unsigned int _verbosity; 145 : 146 : /** 147 : * Smoother control variables 148 : */ 149 : const Real _dilation_weight; 150 : 151 : /** 152 : * Whether subdomain boundaries are subject to change via smoothing 153 : */ 154 : const bool _preserve_subdomain_boundaries; 155 : 156 : // These must be declared in reverse dependency order to avoid corrupting the 157 : // heap during destruction 158 : 159 : /** 160 : * Mesh copy to avoid multiple EquationSystems. 161 : */ 162 : // independent of _equations_systems and _constraint 163 : std::unique_ptr<DistributedMesh> _mesh_copy; 164 : 165 : /** 166 : * EquationsSystems object associated with the smoother 167 : */ 168 : // uses _mesh_copy, owns the system 169 : std::unique_ptr<EquationSystems> _equation_systems; 170 : 171 : 172 : // Now it's safe to store non-owning pointers to the above 173 : 174 : /* 175 : * System used to smooth the mesh. 176 : */ 177 : // Owned by _equation_systems 178 : VariationalSmootherSystem * _system; 179 : 180 : /** 181 : * Getter for _system to protect against dangling pointers 182 : */ 183 476 : VariationalSmootherSystem * system() const 184 : { 185 476 : libmesh_assert(_system); 186 7310 : return _system; 187 : } 188 : 189 : /** 190 : * Constraints imposed on the smoothing process. 191 : */ 192 : // uses system, which is owned by _equations_systems 193 : std::unique_ptr<VariationalSmootherConstraint> _constraint; 194 : 195 : /** 196 : * Attribute the keep track of whether the setup method has been called. 197 : */ 198 : bool _setup_called; 199 : 200 : /** 201 : * Solver relative residual tolerance 202 : */ 203 : Real _relative_residual_tolerance; 204 : 205 : /** 206 : * Solver absolute residual tolerance 207 : */ 208 : Real _absolute_residual_tolerance; 209 : }; 210 : 211 : } // namespace libMesh 212 : 213 : #endif // defined(LIBMESH_ENABLE_VSMOOTHER) 214 : 215 : #endif // LIBMESH_MESH_SMOOTHER_VSMOOTHER_H