Line data Source code
1 : //* This file is part of the MOOSE framework
2 : //* https://mooseframework.inl.gov
3 : //*
4 : //* All rights reserved, see COPYRIGHT for full restrictions
5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 : //*
7 : //* Licensed under LGPL 2.1, please see LICENSE for details
8 : //* https://www.gnu.org/licenses/lgpl-2.1.html
9 :
10 : #include "SmoothMeshGenerator.h"
11 :
12 : // libMesh includes
13 : #include "libmesh/mesh_smoother_laplace.h"
14 : #include "libmesh/mesh_smoother_vsmoother.h"
15 : #include "libmesh/unstructured_mesh.h"
16 : #include "libmesh/replicated_mesh.h"
17 :
18 : #include "CastUniquePointer.h"
19 :
20 : registerMooseObject("MooseApp", SmoothMeshGenerator);
21 :
22 : InputParameters
23 3103 : SmoothMeshGenerator::validParams()
24 : {
25 3103 : InputParameters params = MeshGenerator::validParams();
26 :
27 12412 : params.addRequiredParam<MeshGeneratorName>("input", "The mesh we want to smooth.");
28 6206 : params.addClassDescription("Utilizes the specified smoothing algorithm to attempt to improve "
29 : "mesh quality.");
30 :
31 12412 : MooseEnum SmootherAlgorithm("variational laplace", "variational");
32 12412 : params.addParam<MooseEnum>("algorithm", SmootherAlgorithm, "The smoothing algorithm to use.");
33 9309 : params.addParam<unsigned int>(
34 6206 : "iterations", 1, "Laplace algorithm only: the number of smoothing iterations to do.");
35 15515 : params.addRangeCheckedParam<Real>(
36 : "dilation_weight",
37 6206 : 0.5,
38 : "dilation_weight >= 0.0 & dilation_weight <= 1.0",
39 : "Variational algorithm only: the weight of the dilation metric. The distortion metric is "
40 : "given weight 1 - dilation_weight.");
41 9309 : params.addParam<bool>("preserve_subdomain_boundaries",
42 6206 : true,
43 : "Variational algorithm only: whether the input mesh's subdomain boundaries "
44 : "should be preserved during the smoothing process.");
45 9309 : params.addParam<Real>("relative_residual_tolerance",
46 6206 : TOLERANCE * TOLERANCE,
47 : "Variational algorithm only: solver relative residual tolerance.");
48 9309 : params.addParam<Real>("absolute_residual_tolerance",
49 6206 : TOLERANCE * TOLERANCE,
50 : "Variational algorithm only: solver absolute residual tolerance.");
51 12412 : params.addRangeCheckedParam<unsigned int>(
52 : "verbosity",
53 6206 : 1,
54 : "0 <= verbosity <= 100",
55 : "Variational algorithm only: verbosity level between 0 and 100.");
56 :
57 6206 : return params;
58 3103 : }
59 :
60 24 : SmoothMeshGenerator::SmoothMeshGenerator(const InputParameters & parameters)
61 : : MeshGenerator(parameters),
62 24 : _input(getMesh("input")),
63 48 : _algorithm(getParam<MooseEnum>("algorithm")),
64 48 : _iterations(getParam<unsigned int>("iterations")),
65 48 : _dilation_weight(getParam<Real>("dilation_weight")),
66 48 : _preserve_subdomain_boundaries(getParam<bool>("preserve_subdomain_boundaries")),
67 48 : _relative_residual_tolerance(getParam<Real>("relative_residual_tolerance")),
68 48 : _absolute_residual_tolerance(getParam<Real>("absolute_residual_tolerance")),
69 72 : _verbosity(getParam<unsigned int>("verbosity"))
70 : {
71 72 : if (isParamSetByUser("algorithm"))
72 : {
73 : // Error if user tries to mix laplace smoother params with variational
74 : // smoother params
75 :
76 24 : std::vector<std::string> check_params;
77 24 : std::string other_algorithm;
78 24 : if (_algorithm == "laplace")
79 : {
80 11 : other_algorithm = "variational";
81 66 : check_params = {"dilation_weight",
82 : "preserve_subdomain_boundaries",
83 : "relative_residual_tolerance",
84 : "absolute_residual_tolerance",
85 66 : "verbosity"};
86 : }
87 :
88 : else // _algorithm == "variational"
89 : {
90 13 : other_algorithm = "laplace";
91 26 : check_params = {"iterations"};
92 : }
93 :
94 77 : for (const auto & param_name : check_params)
95 59 : if (isParamSetByUser(param_name))
96 6 : mooseError(" param '",
97 : param_name,
98 : "' applies to algorithm='",
99 : other_algorithm,
100 : "' only and has no effect on the ",
101 : "currently selected algorithm='",
102 6 : _algorithm,
103 : "'.");
104 18 : }
105 90 : }
106 :
107 : std::unique_ptr<MeshBase>
108 18 : SmoothMeshGenerator::generate()
109 : {
110 : // This cast transfers ownership from _input to mesh
111 18 : std::unique_ptr<UnstructuredMesh> mesh = dynamic_pointer_cast<UnstructuredMesh>(_input);
112 18 : std::unique_ptr<libMesh::MeshSmoother> smoother = nullptr;
113 :
114 18 : if (_algorithm == "laplace")
115 : {
116 8 : if (!mesh->is_serial())
117 0 : mooseError(
118 : "SmoothMeshGenerator with algorithm='laplace' is not implemented for distributed meshes");
119 :
120 8 : smoother = std::make_unique<libMesh::LaplaceMeshSmoother>(*mesh, _iterations);
121 : }
122 :
123 10 : else if (_algorithm == "variational")
124 : {
125 20 : smoother = std::make_unique<libMesh::VariationalMeshSmoother>(*mesh,
126 10 : _dilation_weight,
127 10 : _preserve_subdomain_boundaries,
128 10 : _relative_residual_tolerance,
129 10 : _absolute_residual_tolerance,
130 20 : _verbosity);
131 : }
132 :
133 18 : smoother->smooth();
134 :
135 36 : return dynamic_pointer_cast<MeshBase>(mesh);
136 18 : }
|