14#include "libmesh/boundary_info.h"
15#include "libmesh/elem.h"
16#include "libmesh/mesh_base.h"
17#include "libmesh/node.h"
33 "input",
"The input mesh whose boundary nodes are snapped onto the curve.");
35 "boundary",
"The name of the boundary whose nodes are snapped onto the curve.");
37 "parsed_curve_generator",
38 "The ParsedCurveGenerator that defines the curve to snap the nodes onto.");
40 "samples_per_section",
42 "samples_per_section>=2",
43 "Number of uniformly spaced samples of each section of the curve that are used to bracket "
44 "the closest point of the curve.");
47 "Snaps the nodes of a boundary onto the parametric curve of a ParsedCurveGenerator to "
48 "recover the geometry that the straight element edges of the input mesh approximate.");
56 _input(getMesh(
"input")),
60 _curve_mesh(getMesh(
"parsed_curve_generator")),
61 _curve_generator(curveGenerator()),
62 _boundary_name(getParam<BoundaryName>(
"boundary")),
63 _samples_per_section(getParam<unsigned
int>(
"samples_per_section")),
64 _section_bounding_t_values(_curve_generator.sectionBoundingTValues()),
65 _is_closed_loop(_curve_generator.isClosedLoop())
69 "The ParsedCurveGenerator '",
70 getParam<MeshGeneratorName>(
"parsed_curve_generator"),
71 "' must have at least two 'section_bounding_t_values' to define a curve.");
89std::unique_ptr<MeshBase>
96 std::unique_ptr<MeshBase>
mesh = std::move(
_input);
98 if (!
mesh->is_serial())
99 paramError(
"input",
"Input mesh must not be distributed");
106 const BoundaryInfo & boundary_info =
mesh->get_boundary_info();
107 const auto side_list = boundary_info.build_side_list();
108 const auto node_list = boundary_info.build_node_list();
109 std::set<dof_id_type> boundary_node_ids;
110 for (
const auto & [elem_id, side, side_boundary_id] : side_list)
111 if (side_boundary_id == boundary_id)
113 const Elem & elem =
mesh->elem_ref(elem_id);
114 for (
const auto local_node_id : elem.nodes_on_side(side))
115 boundary_node_ids.insert(elem.node_id(local_node_id));
119 boundary_node_ids.insert(node_id);
127 for (
const auto node_id : boundary_node_ids)
129 Node & node =
mesh->node_ref(node_id);
132 node(0) = snapped_point(0);
133 node(1) = snapped_point(1);
136 mesh->unset_has_cached_elem_data();
137 mesh->clear_point_locator();
148 const auto parsed_curve_generator =
dynamic_cast<const ParsedCurveGenerator *
>(&curve_generator);
149 if (!parsed_curve_generator)
151 "The mesh generator '",
152 curve_generator.
name(),
154 curve_generator.
type(),
155 "', but a ParsedCurveGenerator is required to define the curve.");
177 const Point & point)
const
179 const Real dx = curve_point(0) - point(0);
180 const Real dy = curve_point(1) - point(1);
181 return dx * dx + dy * dy;
189 std::size_t closest_sample = 0;
190 Real closest_squared_distance = std::numeric_limits<Real>::max();
194 if (sample_squared_distance < closest_squared_distance)
196 closest_squared_distance = sample_squared_distance;
206 if (closest_sample > 0)
216 return goldenSectionSearch(std::min(t_before, t_after), std::max(t_before, t_after), point);
225 const Real inv_golden_ratio = (std::sqrt(5.0) - 1.0) / 2.0;
228 constexpr unsigned int num_iterations = 60;
230 Real lower = t_lower;
231 Real upper = t_upper;
232 Real t_1 = upper - inv_golden_ratio * (upper - lower);
233 Real t_2 = lower + inv_golden_ratio * (upper - lower);
237 for ([[maybe_unused]]
const auto i : make_range(num_iterations))
239 if (squared_distance_1 < squared_distance_2)
243 squared_distance_2 = squared_distance_1;
244 t_1 = upper - inv_golden_ratio * (upper - lower);
251 squared_distance_1 = squared_distance_2;
252 t_2 = lower + inv_golden_ratio * (upper - lower);
257 return (lower + upper) / 2.0;
267 const Real t_range = t_max - t_min;
269 return t_param - t_range * std::floor((t_param - t_min) / t_range);
registerMooseObject("MooseApp", MoveBoundaryNodesToCurveGenerator)
void ErrorVector unsigned int
MeshGenerators are objects that can modify or add to an existing mesh.
static InputParameters validParams()
const MeshGenerator & getMeshGenerator(const std::string &name) const
const std::string & type() const
Get the type of this class.
const std::string & name() const
Get the name of the class.
void paramError(const std::string ¶m, Args... args) const
Emits an error prefixed with the file and line number of the given param (from the input file) along ...
MooseApp & _app
The MOOSE application this is associated with.
Snaps the nodes of a boundary onto the parametric curve of a ParsedCurveGenerator.
const unsigned int _samples_per_section
Number of uniform samples of each curve section used to bracket the closest curve point.
std::unique_ptr< MeshBase > & _curve_mesh
Reference to the mesh pointer of the curve generator, which is requested for its dependency.
ParsedCurveGenerator & _curve_generator
The ParsedCurveGenerator that defines the curve to snap the nodes onto, and evaluates it.
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
const bool _is_closed_loop
Whether the curve is a closed loop, in which case the parameter wraps at the bounding values.
Point curvePoint(const Real t_param)
Evaluates the curve through the generator that defines it.
Real goldenSectionSearch(const Real t_lower, const Real t_upper, const Point &point)
Refines a bracket of the closest curve point with a golden-section search.
Real squaredDistance(const Real t_param, const Point &point)
Calculates the squared in-plane distance between a given point and a point of the curve.
std::vector< Point > _sample_points
Curve points at the sampled t values, evaluated once in generate() and reused for every node.
std::unique_ptr< MeshBase > & _input
Reference to the input mesh pointer, whose boundary nodes are snapped onto the curve.
ParsedCurveGenerator & curveGenerator() const
Gets the generator that defines the curve, after checking that it is a ParsedCurveGenerator.
Real boundedParameter(const Real t_param) const
Bounds a parameter t into the bounding t values of a closed loop, which is where the formulas of the ...
const BoundaryName _boundary_name
Name of the boundary whose nodes are snapped onto the curve.
Real closestParameter(const Point &point)
Finds the parameter t of the curve point that is the closest to a given point.
std::vector< Real > _t_samples
Sampled t values used to bracket the closest curve point.
static InputParameters validParams()
MoveBoundaryNodesToCurveGenerator(const InputParameters ¶meters)
const std::vector< Real > _section_bounding_t_values
t values that bound the sections of the curve
his ParsedCurveGenerator object is designed to generate a mesh of a curve that consists of EDGE2,...
Point pointCalculator(const Real t_param)
Calculates the point coordinates {x(t), y(t), z(t)} based on parameter t.
const boundary_id_type node_boundary_id
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
bool hasBoundaryNameOrID(const MeshBase &mesh, const BoundaryName &name_or_id)
Whether a particular boundary name or ID exists in the mesh.