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 : /** 80 : * Simple constructor to use for smoothing purposes 81 : */ 82 : VariationalMeshSmoother(UnstructuredMesh & mesh, 83 : Real dilation_weight=0.5, 84 : const bool preserve_subdomain_boundaries=true); 85 : 86 : /** 87 : * Destructor. 88 : */ 89 0 : virtual ~VariationalMeshSmoother() = default; 90 : 91 : /** 92 : * Setup method that creates equation systems, system, and constraints, to be 93 : * called just prior to smoothing. 94 : */ 95 : virtual void setup(); 96 : 97 : /** 98 : * Redefinition of the smooth function from the 99 : * base class. All this does is call the smooth 100 : * function in this class which takes an int, using 101 : * a default value of 1. 102 : */ 103 38 : virtual void smooth() override {this->smooth(1); } 104 : 105 : /** 106 : * The actual smoothing function, gets called whenever 107 : * the user specifies an actual number of smoothing 108 : * iterations. 109 : */ 110 : void smooth(unsigned int n_iterations); 111 : 112 : /** 113 : * Getter for the _system's _mesh_info attribute 114 : */ 115 : const MeshQualityInfo & get_mesh_info() const; 116 : 117 : private: 118 : 119 : /** 120 : * Smoother control variables 121 : */ 122 : const Real _dilation_weight; 123 : 124 : /** 125 : * Whether subdomain boundaries are subject to change via smoothing 126 : */ 127 : const bool _preserve_subdomain_boundaries; 128 : 129 : // These must be declared in reverse dependency order to avoid corrupting the 130 : // heap during destruction 131 : 132 : /** 133 : * Mesh copy to avoid multiple EquationSystems. 134 : */ 135 : // independent of _equations_systems and _constraint 136 : std::unique_ptr<DistributedMesh> _mesh_copy; 137 : 138 : /** 139 : * EquationsSystems object associated with the smoother 140 : */ 141 : // uses _mesh_copy, owns the system 142 : std::unique_ptr<EquationSystems> _equation_systems; 143 : 144 : 145 : // Now it's safe to store non-owning pointers to the above 146 : 147 : /* 148 : * System used to smooth the mesh. 149 : */ 150 : // Owned by _equation_systems 151 : VariationalSmootherSystem * _system; 152 : 153 : /** 154 : * Getter for _system to protect against dangling pointers 155 : */ 156 228 : VariationalSmootherSystem * system() const 157 : { 158 228 : libmesh_assert(_system); 159 4047 : return _system; 160 : } 161 : 162 : /** 163 : * Constraints imposed on the smoothing process. 164 : */ 165 : // uses system, which is owned by _equations_systems 166 : std::unique_ptr<VariationalSmootherConstraint> _constraint; 167 : 168 : /** 169 : * Attribute the keep track of whether the setup method has been called. 170 : */ 171 : bool _setup_called; 172 : }; 173 : 174 : } // namespace libMesh 175 : 176 : #endif // defined(LIBMESH_ENABLE_VSMOOTHER) 177 : 178 : #endif // LIBMESH_MESH_SMOOTHER_VSMOOTHER_H