libMesh
Loading...
Searching...
No Matches
Public Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
libMesh::VariationalMeshSmoother Class Reference

This is an implementation of Larisa Branets' smoothing algorithms. More...

#include <mesh_smoother_vsmoother.h>

Inheritance diagram for libMesh::VariationalMeshSmoother:
[legend]

Public Member Functions

 VariationalMeshSmoother (UnstructuredMesh &mesh, Real dilation_weight=0.5, const bool preserve_subdomain_boundaries=true, const Real relative_residual_tolerance=TOLERANCE *TOLERANCE, const Real absolute_residual_tolerance=TOLERANCE *TOLERANCE, const unsigned int verbosity=0)
 Constructor.
 
virtual ~VariationalMeshSmoother ()=default
 Destructor.
 
virtual void setup ()
 Setup method that creates equation systems, system, and constraints, to be called just prior to smoothing.
 
virtual void smooth () override
 Redefinition of the smooth function from the base class.
 
const MeshQualityInfo & get_mesh_info () const
 Getter for the _system's _mesh_info attribute.
 
void set_quadrature_type (QuadratureType qt)
 Set the quadrature rule type used by the underlying VariationalSmootherSystem to integrate the distortion-dilation metric.
 

Protected Attributes

UnstructuredMesh & _mesh
 

Private Member Functions

VariationalSmootherSystem * system () const
 Getter for _system to protect against dangling pointers.
 

Private Attributes

const unsigned int _verbosity
 verbosity setting
 
const Real _dilation_weight
 Smoother control variables.
 
const bool _preserve_subdomain_boundaries
 Whether subdomain boundaries are subject to change via smoothing.
 
std::unique_ptr< DistributedMesh > _mesh_copy
 Mesh copy to avoid multiple EquationSystems.
 
std::unique_ptr< EquationSystems > _equation_systems
 EquationsSystems object associated with the smoother.
 
VariationalSmootherSystem * _system
 
std::unique_ptr< VariationalSmootherConstraint > _constraint
 Constraints imposed on the smoothing process.
 
bool _setup_called
 Attribute the keep track of whether the setup method has been called.
 
Real _relative_residual_tolerance
 Solver relative residual tolerance.
 
Real _absolute_residual_tolerance
 Solver absolute residual tolerance.
 
QuadratureType _quadrature_type = QGAUSS
 Quadrature rule type used to integrate the distortion-dilation metric.
 

Detailed Description

This is an implementation of Larisa Branets' smoothing algorithms.

The initial implementation was done by her, the adaptation to libmesh was completed by Derek Gaston. The code was heavily refactored into something more closely resembling C++ by John Peterson in 2014. The code eventually fell out of use and stopped functioning. Patrick Behne reimplemented the smoother in 2025.

Here are the relevant publications: 1) L. Branets, G. Carey, "Extension of a mesh quality metric for elements with a curved boundary edge or surface", Journal of Computing and Information Science in Engineering, vol. 5(4), pp.302-308, 2005.

2) L. Branets, G. Carey, "A local cell quality metric and variational grid smoothing algorithm", Engineering with Computers, vol. 21, pp.19-28, 2005.

3) L. Branets, "A variational grid optimization algorithm based on a local cell quality metric", Ph.D. thesis, The University of Texas at Austin, 2005.

Notes:

1) The smoother supports tangled meshes. However, not all untangling solves converge. In other words, we are able to untangle SOME tangled meshes, but not ANY tangled mesh.

Author
Derek R. Gaston
Date
2006

Definition at line 75 of file mesh_smoother_vsmoother.h.

Constructor & Destructor Documentation

◆ VariationalMeshSmoother()

libMesh::VariationalMeshSmoother::VariationalMeshSmoother ( UnstructuredMesh &  mesh,
Real  dilation_weight = 0.5,
const bool  preserve_subdomain_boundaries = true,
const Real  relative_residual_tolerance = TOLERANCE * TOLERANCE,
const Real  absolute_residual_tolerance = TOLERANCE * TOLERANCE,
const unsigned int  verbosity = 0 
)

Constructor.

Parameters
meshMesh to smooth by minimizing the distortion-dilation metric.
dilation_wiehgtWeight to give the dilation metric. The distortion metric is given 1 - dilation_weight.
preserve_subdomain_boundariesWhether the smoother is to preserve or modify sobdomain boundaries.
relative_residual_toleranceSolver setting for the relative residual tolerance.
absolute_residual_toleranceSolver setting for the absolute residual tolerance.
verbositySmoother verbosity option specifying how much information is output. The verbosity levels and the corresponding information output are as follows:

verbosity = 0 : No information

verbosity > 15: Prints:

  • Solver nonlinear and linear iteration information

The VariationalSmootherSystem and VariationalSmootherConstraint classes use the same verbosity value as this VariationalMeshSmoother class. For details on what those systems print, refer to the documentation for the _verbosity attribute in each class.

Definition at line 52 of file mesh_smoother_vsmoother.C.

57 : MeshSmoother(mesh), _verbosity(verbosity),
58 _dilation_weight(dilation_weight),
59 _preserve_subdomain_boundaries(preserve_subdomain_boundaries),
60 _setup_called(false),
61 _relative_residual_tolerance(relative_residual_tolerance),
62 _absolute_residual_tolerance(absolute_residual_tolerance) {}
MeshSmoother(UnstructuredMesh &mesh)
Constructor.
const Real _dilation_weight
Smoother control variables.
const unsigned int _verbosity
verbosity setting
Real _relative_residual_tolerance
Solver relative residual tolerance.
Real _absolute_residual_tolerance
Solver absolute residual tolerance.
bool _setup_called
Attribute the keep track of whether the setup method has been called.
const bool _preserve_subdomain_boundaries
Whether subdomain boundaries are subject to change via smoothing.
MeshBase & mesh

◆ ~VariationalMeshSmoother()

virtual libMesh::VariationalMeshSmoother::~VariationalMeshSmoother ( )
virtualdefault

Destructor.

Member Function Documentation

◆ get_mesh_info()

const MeshQualityInfo & libMesh::VariationalMeshSmoother::get_mesh_info ( ) const

Getter for the _system's _mesh_info attribute.

Definition at line 197 of file mesh_smoother_vsmoother.C.

198{
199 libmesh_error_msg_if(!_setup_called, "Need to first call the setup() method of "
200 << "this VariationalMeshSmoother object, then call get_mesh_info() prior "
201 << "to calling smooth().");
202 return _system->get_mesh_info();
203}
const MeshQualityInfo & get_mesh_info()
Getter for the _mesh_info attribute.

References _setup_called, _system, and libMesh::VariationalSmootherSystem::get_mesh_info().

Referenced by MeshSmootherTest::testVariationalSmoother().

◆ set_quadrature_type()

void libMesh::VariationalMeshSmoother::set_quadrature_type ( QuadratureType  qt)
inline

Set the quadrature rule type used by the underlying VariationalSmootherSystem to integrate the distortion-dilation metric.

The default (QGAUSS) samples the element interior only, which can miss degeneracies localized at element corners (e.g. an element collapsing toward one of its nodes). A vertex-sampling rule such as QTRAP, QSIMPSON, QNODAL, or QGAUSS_LOBATTO evaluates the metric at the element nodes so a folding corner is penalized (and flagged as tangled) as it should be. Must be called before smooth()/setup(). See VariationalSmootherSystem::set_quadrature_type() for details and caveats.

Definition at line 143 of file mesh_smoother_vsmoother.h.

143{ _quadrature_type = qt; }
QuadratureType _quadrature_type
Quadrature rule type used to integrate the distortion-dilation metric.

References _quadrature_type.

Referenced by MeshSmootherTest::testVariationalQuadratureHourglass().

◆ setup()

void libMesh::VariationalMeshSmoother::setup ( )
virtual

Setup method that creates equation systems, system, and constraints, to be called just prior to smoothing.

Definition at line 64 of file mesh_smoother_vsmoother.C.

65{
66 // Check for multiple dimensions
69
70 if (_mesh.elem_dimensions().size() > 1)
71 libmesh_not_implemented_msg("Meshes containing elements of differing dimension are not yet supported.");
72
73 /*
74 Ideally we'd want to update _mesh directly even if it already has an
75 EquationSystems attached and doing work on it ... and that's thwarted by the
76 problems:
77
78 1. We can't easily tell if there's already an EquationSystems attached.
79 2. We can't attach a second EquationSystems safely (if it already has a system 0)
80 because the DoF indexing will need to be overwritten by our system.
81 3. The destructor of es won't even clean up after itself (we generally expect
82 a mesh to go unused after its EquationSystems is destroyed), much less know
83 how to restore anything from a previous EquationSystems.
84
85 To avoid these issues, we'll just construct a new DistributedMesh _mesh_copy
86 from _mesh, then do the solve on _mesh_copy, then copy its node locations back
87 to _mesh after the solve is done. That'll be slightly less memory-efficient
88 and somewhat more CPU-efficient in the case where _mesh is serial, though
89 it'll be significantly less memory-efficient when _mesh is already distributed,
90 but either way the robustness is probably worth it.
91 */
92
93 // Create a new mesh, EquationSystems, and System
94 _mesh_copy = std::make_unique<DistributedMesh>(_mesh);
95
96 // If the _mesh wasn't prepared, that's fine (we'll just be moving
97 // its nodes), but we do need the copy to be prepared before our
98 // solve does things like looking at neighbors. We'll disable
99 // repartitioning and renumbering first to make sure that we can
100 // transfer our geometry changes back to the original mesh.
101 _mesh_copy->allow_renumbering(false);
102 _mesh_copy->skip_partitioning(true);
103 _mesh_copy->complete_preparation();
104
105 _equation_systems = std::make_unique<EquationSystems>(*_mesh_copy);
106 _system =
107 &(_equation_systems->add_system<VariationalSmootherSystem>("variational_smoother_system"));
108
109 // Set this to something > 0 to add more quadrature points than the default
110 // rule that integrates order 2 * fe_order + 1 polynomials exactly.
111 // Using higher quadrature orders has not had a significant effect on observed solutions.
112 //system()->extra_quadrature_order = 0;
113
114 // The default Gauss rule samples the element interior only, so it can miss
115 // degeneracies localized at element corners (e.g. an element collapsing
116 // toward one of its nodes). Selecting a vertex-sampling rule (QTRAP,
117 // QSIMPSON, QNODAL, QGAUSS_LOBATTO) evaluates the metric at the element
118 // nodes instead. Defaults to QGAUSS.
120
121 // Uncomment these to debug
122 //system()->print_element_solutions=true;
123 //system()->print_element_residuals=true;
124 //system()->print_element_jacobians=true;
125
126 // Add boundary node and hanging node constraints
127 _constraint = std::make_unique<VariationalSmootherConstraint>(
130
131 // Set system parameters
134
135 // Set up solver
136 system()->time_solver = std::make_unique<SteadySolver>(*_system);
137
138 // Uncomment this line and use -snes_test_jacobian and -snes_test_jacobian_view
139 // flags to compare the hand-coded jacobian in VariationalSmootherSystem
140 // to finite difference jacobians.
141 //system()->time_solver->diff_solver() = std::make_unique<PetscDiffSolver>(*_system);
142
143 _equation_systems->init();
144
145 // Solver verbosity
146 if (_verbosity > 15) {
147 DiffSolver &solver = *(system()->time_solver->diff_solver().get());
148 solver.quiet = false;
149 solver.verbose = true;
150 }
151
152 // Solver convergence tolerances
153 system()->time_solver->diff_solver()->relative_residual_tolerance = _relative_residual_tolerance;
154 system()->time_solver->diff_solver()->absolute_residual_tolerance = _absolute_residual_tolerance;
155
156 _setup_called = true;
157}
std::unique_ptr< TimeSolver > time_solver
A pointer to the solver object we're going to use.
Preparation preparation() const
Definition mesh_base.h:213
const std::set< unsigned char > & elem_dimensions() const
Definition mesh_base.h:2650
UnstructuredMesh & _mesh
void attach_constraint_object(Constraint &constrain)
Register a user object for imposing constraints.
Definition system.C:2007
std::unique_ptr< VariationalSmootherConstraint > _constraint
Constraints imposed on the smoothing process.
std::unique_ptr< EquationSystems > _equation_systems
EquationsSystems object associated with the smoother.
VariationalSmootherSystem * system() const
Getter for _system to protect against dangling pointers.
std::unique_ptr< DistributedMesh > _mesh_copy
Mesh copy to avoid multiple EquationSystems.
void set_quadrature_type(QuadratureType qt)
Set the quadrature rule type used to integrate the distortion-dilation metric over each element.
void set_verbosity(const unsigned int verbosity)

References _absolute_residual_tolerance, _constraint, _dilation_weight, _equation_systems, libMesh::MeshSmoother::_mesh, _mesh_copy, _preserve_subdomain_boundaries, _quadrature_type, _relative_residual_tolerance, _setup_called, _system, _verbosity, libMesh::System::attach_constraint_object(), libMesh::MeshBase::cache_elem_data(), libMesh::MeshBase::elem_dimensions(), libMesh::VariationalSmootherSystem::get_dilation_weight(), libMesh::MeshBase::Preparation::has_cached_elem_data, libMesh::MeshBase::preparation(), libMesh::DiffSolver::quiet, libMesh::VariationalSmootherSystem::set_quadrature_type(), libMesh::VariationalSmootherSystem::set_verbosity(), system(), libMesh::DifferentiableSystem::time_solver, and libMesh::DiffSolver::verbose.

Referenced by smooth(), and MeshSmootherTest::testVariationalSmoother().

◆ smooth()

void libMesh::VariationalMeshSmoother::smooth ( )
overridevirtual

Redefinition of the smooth function from the base class.

All this does is call the smooth function in this class which takes an int, using a default value of 1.

Implements libMesh::MeshSmoother.

Definition at line 159 of file mesh_smoother_vsmoother.C.

160{
161 LOG_SCOPE("smooth()", "VariationalMeshSmoother");
162
163 if (!_setup_called)
164 setup();
165
166 libmesh_try
167 {
168 system()->solve();
169 }
170
171 libmesh_catch (ConvergenceFailure& e)
172 {
173#ifdef LIBMESH_ENABLE_EXCEPTIONS
174 throw ConvergenceFailure("The VariationalMeshSmoother solve failed to converge.");
175#endif
176 }
177
178 // Update _mesh from _mesh_copy
179 for (auto * node_copy : _mesh_copy->local_node_ptr_range())
180 {
181 auto & node = _mesh.node_ref(node_copy->id());
182 for (const auto d : make_range(_mesh_copy->mesh_dimension()))
183 node(d) = (*node_copy)(d);
184 }
185
186 SyncNodalPositions sync_object(_mesh);
187 Parallel::sync_dofobject_data_by_id (_mesh.comm(), _mesh.nodes_begin(), _mesh.nodes_end(), sync_object);
188
189 // Release memory occupied by _mesh_copy
190 // Destruct this before _mesh_copy because it references _mesh_copy
191 _equation_systems.reset();
192 _mesh_copy.reset();
193 // We'll need to call setup again since we'll have to reconstruct _mesh_copy
194 _setup_called = false;
195}
virtual const Node & node_ref(const dof_id_type i) const
Definition mesh_base.h:742
const Parallel::Communicator & comm() const
virtual void setup()
Setup method that creates equation systems, system, and constraints, to be called just prior to smoot...
virtual void solve() override
Solves the system to smooth the mesh.
void sync_dofobject_data_by_id(const Communicator &comm, const Iterator &range_begin, const Iterator &range_end, SyncFunctor &sync)
Request data about a range of ghost dofobjects uniquely identified by their id.
IntRange< T > make_range(T beg, T end)
The 2-parameter make_range() helper function returns an IntRange<T> when both input parameters are of...
Definition int_range.h:176

References _equation_systems, libMesh::MeshSmoother::_mesh, _mesh_copy, _setup_called, libMesh::ParallelObject::comm(), libMesh::make_range(), libMesh::MeshBase::node_ref(), setup(), libMesh::VariationalSmootherSystem::solve(), libMesh::Parallel::sync_dofobject_data_by_id(), and system().

Referenced by main(), MeshSmootherTest::testVariationalQuadratureHourglass(), MeshSmootherTest::testVariationalSmoother(), and MeshSmootherTest::testVariationalSmootherRegression().

◆ system()

VariationalSmootherSystem * libMesh::VariationalMeshSmoother::system ( ) const
inlineprivate

Getter for _system to protect against dangling pointers.

Definition at line 189 of file mesh_smoother_vsmoother.h.

190 {
192 return _system;
193 }
libmesh_assert(ctx)

References _system, and libMesh::libmesh_assert().

Referenced by setup(), and smooth().

Member Data Documentation

◆ _absolute_residual_tolerance

Real libMesh::VariationalMeshSmoother::_absolute_residual_tolerance
private

Solver absolute residual tolerance.

Definition at line 214 of file mesh_smoother_vsmoother.h.

Referenced by setup().

◆ _constraint

std::unique_ptr<VariationalSmootherConstraint> libMesh::VariationalMeshSmoother::_constraint
private

Constraints imposed on the smoothing process.

Definition at line 199 of file mesh_smoother_vsmoother.h.

Referenced by setup().

◆ _dilation_weight

const Real libMesh::VariationalMeshSmoother::_dilation_weight
private

Smoother control variables.

Definition at line 155 of file mesh_smoother_vsmoother.h.

Referenced by setup().

◆ _equation_systems

std::unique_ptr<EquationSystems> libMesh::VariationalMeshSmoother::_equation_systems
private

EquationsSystems object associated with the smoother.

Definition at line 175 of file mesh_smoother_vsmoother.h.

Referenced by setup(), and smooth().

◆ _mesh

UnstructuredMesh& libMesh::MeshSmoother::_mesh
protectedinherited

◆ _mesh_copy

std::unique_ptr<DistributedMesh> libMesh::VariationalMeshSmoother::_mesh_copy
private

Mesh copy to avoid multiple EquationSystems.

Definition at line 169 of file mesh_smoother_vsmoother.h.

Referenced by setup(), and smooth().

◆ _preserve_subdomain_boundaries

const bool libMesh::VariationalMeshSmoother::_preserve_subdomain_boundaries
private

Whether subdomain boundaries are subject to change via smoothing.

Definition at line 160 of file mesh_smoother_vsmoother.h.

Referenced by setup().

◆ _quadrature_type

QuadratureType libMesh::VariationalMeshSmoother::_quadrature_type = QGAUSS
private

Quadrature rule type used to integrate the distortion-dilation metric.

See set_quadrature_type().

Definition at line 220 of file mesh_smoother_vsmoother.h.

Referenced by set_quadrature_type(), and setup().

◆ _relative_residual_tolerance

Real libMesh::VariationalMeshSmoother::_relative_residual_tolerance
private

Solver relative residual tolerance.

Definition at line 209 of file mesh_smoother_vsmoother.h.

Referenced by setup().

◆ _setup_called

bool libMesh::VariationalMeshSmoother::_setup_called
private

Attribute the keep track of whether the setup method has been called.

Definition at line 204 of file mesh_smoother_vsmoother.h.

Referenced by get_mesh_info(), setup(), and smooth().

◆ _system

VariationalSmootherSystem* libMesh::VariationalMeshSmoother::_system
private

Definition at line 184 of file mesh_smoother_vsmoother.h.

Referenced by get_mesh_info(), setup(), and system().

◆ _verbosity

const unsigned int libMesh::VariationalMeshSmoother::_verbosity
private

verbosity setting

Definition at line 150 of file mesh_smoother_vsmoother.h.

Referenced by setup().


The documentation for this class was generated from the following files: