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 :
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 : /**
133 : * Set the quadrature rule type used by the underlying
134 : * VariationalSmootherSystem to integrate the distortion-dilation metric.
135 : * The default (\p QGAUSS) samples the element interior only, which can miss
136 : * degeneracies localized at element corners (e.g. an element collapsing
137 : * toward one of its nodes). A vertex-sampling rule such as \p QTRAP,
138 : * \p QSIMPSON, \p QNODAL, or \p QGAUSS_LOBATTO evaluates the metric at the
139 : * element nodes so a folding corner is penalized (and flagged as tangled) as
140 : * it should be. Must be called before smooth()/setup(). See
141 : * VariationalSmootherSystem::set_quadrature_type() for details and caveats.
142 : */
143 : void set_quadrature_type(QuadratureType qt) { _quadrature_type = qt; }
144 :
145 : private:
146 :
147 : /**
148 : * verbosity setting
149 : */
150 : const unsigned int _verbosity;
151 :
152 : /**
153 : * Smoother control variables
154 : */
155 : const Real _dilation_weight;
156 :
157 : /**
158 : * Whether subdomain boundaries are subject to change via smoothing
159 : */
160 : const bool _preserve_subdomain_boundaries;
161 :
162 : // These must be declared in reverse dependency order to avoid corrupting the
163 : // heap during destruction
164 :
165 : /**
166 : * Mesh copy to avoid multiple EquationSystems.
167 : */
168 : // independent of _equations_systems and _constraint
169 : std::unique_ptr<DistributedMesh> _mesh_copy;
170 :
171 : /**
172 : * EquationsSystems object associated with the smoother
173 : */
174 : // uses _mesh_copy, owns the system
175 : std::unique_ptr<EquationSystems> _equation_systems;
176 :
177 :
178 : // Now it's safe to store non-owning pointers to the above
179 :
180 : /*
181 : * System used to smooth the mesh.
182 : */
183 : // Owned by _equation_systems
184 : VariationalSmootherSystem * _system;
185 :
186 : /**
187 : * Getter for _system to protect against dangling pointers
188 : */
189 580 : VariationalSmootherSystem * system() const
190 : {
191 580 : libmesh_assert(_system);
192 7950 : return _system;
193 : }
194 :
195 : /**
196 : * Constraints imposed on the smoothing process.
197 : */
198 : // uses system, which is owned by _equations_systems
199 : std::unique_ptr<VariationalSmootherConstraint> _constraint;
200 :
201 : /**
202 : * Attribute the keep track of whether the setup method has been called.
203 : */
204 : bool _setup_called;
205 :
206 : /**
207 : * Solver relative residual tolerance
208 : */
209 : Real _relative_residual_tolerance;
210 :
211 : /**
212 : * Solver absolute residual tolerance
213 : */
214 : Real _absolute_residual_tolerance;
215 :
216 : /**
217 : * Quadrature rule type used to integrate the distortion-dilation metric.
218 : * See set_quadrature_type().
219 : */
220 : QuadratureType _quadrature_type = QGAUSS;
221 : };
222 :
223 : } // namespace libMesh
224 :
225 : #endif // defined(LIBMESH_ENABLE_VSMOOTHER)
226 :
227 : #endif // LIBMESH_MESH_SMOOTHER_VSMOOTHER_H
|