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 solver_quiet Whether to make the solver quiet.
88 : * @param solver_verbose Whether to make the solver verbose.
89 : */
90 : VariationalMeshSmoother(UnstructuredMesh & mesh,
91 : Real dilation_weight = 0.5,
92 : const bool preserve_subdomain_boundaries = true,
93 : const double relative_residual_tolerance = TOLERANCE * TOLERANCE,
94 : const double absolute_residual_tolerance = TOLERANCE * TOLERANCE,
95 : const bool solver_quiet = true,
96 : const bool solver_verbose = false);
97 :
98 : /**
99 : * Destructor.
100 : */
101 0 : virtual ~VariationalMeshSmoother() = default;
102 :
103 : /**
104 : * Setup method that creates equation systems, system, and constraints, to be
105 : * called just prior to smoothing.
106 : */
107 : virtual void setup();
108 :
109 : /**
110 : * Redefinition of the smooth function from the
111 : * base class. All this does is call the smooth
112 : * function in this class which takes an int, using
113 : * a default value of 1.
114 : */
115 50 : virtual void smooth() override {this->smooth(1); }
116 :
117 : /**
118 : * The actual smoothing function, gets called whenever
119 : * the user specifies an actual number of smoothing
120 : * iterations.
121 : */
122 : void smooth(unsigned int n_iterations);
123 :
124 : /**
125 : * Getter for the _system's _mesh_info attribute
126 : */
127 : const MeshQualityInfo & get_mesh_info() const;
128 :
129 : private:
130 :
131 : /**
132 : * Smoother control variables
133 : */
134 : const Real _dilation_weight;
135 :
136 : /**
137 : * Whether subdomain boundaries are subject to change via smoothing
138 : */
139 : const bool _preserve_subdomain_boundaries;
140 :
141 : // These must be declared in reverse dependency order to avoid corrupting the
142 : // heap during destruction
143 :
144 : /**
145 : * Mesh copy to avoid multiple EquationSystems.
146 : */
147 : // independent of _equations_systems and _constraint
148 : std::unique_ptr<DistributedMesh> _mesh_copy;
149 :
150 : /**
151 : * EquationsSystems object associated with the smoother
152 : */
153 : // uses _mesh_copy, owns the system
154 : std::unique_ptr<EquationSystems> _equation_systems;
155 :
156 :
157 : // Now it's safe to store non-owning pointers to the above
158 :
159 : /*
160 : * System used to smooth the mesh.
161 : */
162 : // Owned by _equation_systems
163 : VariationalSmootherSystem * _system;
164 :
165 : /**
166 : * Getter for _system to protect against dangling pointers
167 : */
168 350 : VariationalSmootherSystem * system() const
169 : {
170 350 : libmesh_assert(_system);
171 5375 : return _system;
172 : }
173 :
174 : /**
175 : * Constraints imposed on the smoothing process.
176 : */
177 : // uses system, which is owned by _equations_systems
178 : std::unique_ptr<VariationalSmootherConstraint> _constraint;
179 :
180 : /**
181 : * Attribute the keep track of whether the setup method has been called.
182 : */
183 : bool _setup_called;
184 :
185 : /**
186 : * Solver relative residual tolerance
187 : */
188 : double _relative_residual_tolerance;
189 :
190 : /**
191 : * Solver absolute residual tolerance
192 : */
193 : double _absolute_residual_tolerance;
194 :
195 : /**
196 : * Solver quiet setting
197 : */
198 : bool _solver_quiet;
199 :
200 : /**
201 : * Solver verbose setting
202 : */
203 : bool _solver_verbose;
204 : };
205 :
206 : } // namespace libMesh
207 :
208 : #endif // defined(LIBMESH_ENABLE_VSMOOTHER)
209 :
210 : #endif // LIBMESH_MESH_SMOOTHER_VSMOOTHER_H
|