16 #include "libmesh/elem.h" 17 #include "libmesh/int_range.h" 18 #include "libmesh/unstructured_mesh.h" 28 params.
addRequiredParam<Point>(
"starting_point",
"Starting point for the polyline");
30 "Starting value for the direction of the line");
31 params.
addRequiredParam<MeshGeneratorName>(
"input",
"The mesh we get the sideset from");
32 params.
addRequiredParam<BoundaryName>(
"nodeset",
"Nodeset to follow to form the polyline");
34 "Radius of the sphere used to find points in the nodeset");
36 "ignore_nodes_behind",
38 "Ignore nodes in the nodeset that are behind the current point in the polyline");
39 params.
addParam<
bool>(
"loop",
false,
"Whether edges should form a closed loop");
46 "Approximate size of the edge elements (before any refinement with num_edges_between_points) " 47 "and approximate step to advance by to search for the next point in the polyline");
49 "max_edges", 1000,
"Maximum number of edges. Serves as a stopping criterion");
51 "num_edges_between_points", 1,
"How many Edge elements to build between each point pair");
54 params.
addParam<SubdomainName>(
"line_subdomain",
"line",
"Subdomain name for the line");
56 "start_boundary",
"start",
"Boundary to assign to (non-looped) polyline start");
58 "end_boundary",
"end",
"Boundary to assign to (non-looped) polyline end");
63 "whether to output additional information to console during the line generation");
66 "Generates a polyline (open ended or looped) of Edge elements by marching along a nodeeset " 67 "and trying to be as close as possible to the nodes of the nodeset");
75 _input(getMesh(
"input")),
76 _starting_point(getParam<Point>(
"starting_point")),
77 _starting_direction(getParam<Point>(
"starting_direction")),
78 _ignore_nodes_behind(getParam<bool>(
"ignore_nodes_behind")),
79 _loop(getParam<bool>(
"loop")),
80 _line_subdomain(getParam<SubdomainName>(
"line_subdomain")),
81 _start_boundary(getParam<BoundaryName>(
"start_boundary")),
82 _end_boundary(getParam<BoundaryName>(
"end_boundary")),
83 _dx(getParam<
Real>(
"dx")),
84 _num_edges_between_points(getParam<unsigned
int>(
"num_edges_between_points")),
85 _verbose(getParam<bool>(
"verbose"))
89 "Loop does not have a start or end boundary. These parameters must not be passed.");
92 std::unique_ptr<MeshBase>
96 MeshBase &
mesh = *uptr_mesh;
97 std::unique_ptr<MeshBase> base_mesh = std::move(
_input);
98 if (!base_mesh->is_serial())
99 paramError(
"input",
"Input mesh must not be distributed");
102 if (!base_mesh->preparation().has_boundary_id_sets)
103 base_mesh->get_boundary_info().regenerate_id_sets();
106 const auto nodeset_id =
110 const auto n_points = getParam<unsigned int>(
"max_edges");
117 const auto all_nodeset_tuples = base_mesh->get_boundary_info().build_node_list(
119 std::vector<dof_id_type> nodeset_nodes;
120 nodeset_nodes.reserve(all_nodeset_tuples.size() /
121 base_mesh->get_boundary_info().n_boundary_ids());
122 for (
const auto & tup : all_nodeset_tuples)
123 if (
BoundaryID(std::get<1>(tup)) == nodeset_id)
124 nodeset_nodes.push_back(std::get<0>(tup));
126 _console <<
"Total number of nodes in nodeset " << getParam<BoundaryName>(
"nodeset") <<
": " 127 << nodeset_nodes.size() << std::endl;
129 unsigned int n_segments = 0;
133 const auto previous_point = current_point;
134 current_point += previous_direction *
_dx;
141 unsigned int n_sum = 0;
142 for (
const auto n_id : nodeset_nodes)
143 if ((current_point - base_mesh->node_ref(n_id)).
norm_sq() < search_radius_sq)
146 ((base_mesh->node_ref(n_id) - current_point) * previous_direction >= 0))
148 barycenter += base_mesh->node_ref(n_id);
155 mooseError(
"Did not find any nodes in the nodeset near the current point at: ",
158 barycenter = previous_point;
160 if (MooseUtils::absoluteFuzzyEqual((barycenter - previous_point).
norm_sq(), 0))
162 mooseInfo(
"Barycenter did not move from ", barycenter,
". Returning!");
167 const auto new_direction = (barycenter - previous_point).unit();
168 previous_direction = new_direction;
173 current_point = previous_point +
_dx * new_direction;
176 _console << i <<
": new point: " << current_point <<
" new direction " << previous_direction
182 auto p = previous_point;
198 const auto ip1 =
_loop ? (i + 1) % max_nodes : (i + 1);
199 auto elem = Elem::build(
EDGE2);
200 elem->set_node(0,
mesh.node_ptr(i));
201 elem->set_node(1,
mesh.node_ptr(ip1));
203 mesh.add_elem(std::move(elem));
209 BoundaryInfo & bi =
mesh.get_boundary_info();
212 bi.add_side(
mesh.elem_ptr(0), 0, ids[0]);
213 bi.add_side(
mesh.elem_ptr(
n_elem - 1), 1, ids[1]);
216 mesh.prepare_for_use();
void mooseInfo(Args &&... args) const
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 ...
const Point _starting_direction
Starting direction for the polyline.
PolyLineMeshFollowingNodeSetGenerator(const InputParameters ¶meters)
const bool _verbose
Whether to output to console the mesh generation process.
const Real _dx
Approximate spacing between nodes.
const bool _ignore_nodes_behind
Whether to only look in front of the polyline for nodes in the nodeset.
const bool _loop
Whether edges should form a closed loop. Will error if the nodeset does not loop back on itself...
std::unique_ptr< MeshBase > & _input
BoundaryID getBoundaryID(const BoundaryName &boundary_name, const MeshBase &mesh)
Gets the boundary ID associated with the given BoundaryName.
const BoundaryName & _end_boundary
const BoundaryName & _start_boundary
Boundary names to assign to (non-looped) polyline start and end.
boundary_id_type BoundaryID
Generates a polyline (open ended or looped) of Edge elements by marching along a nodeeset and trying ...
const unsigned int _num_edges_between_points
How many Edge elements to build between each point pair.
std::vector< BoundaryID > getBoundaryIDs(const libMesh::MeshBase &mesh, const std::vector< BoundaryName > &boundary_name, bool generate_unknown, const std::set< BoundaryID > &mesh_boundary_ids)
Gets the boundary IDs with their names.
static InputParameters validParams()
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point _starting_point
Starting point of the polyline.
static InputParameters validParams()
IntRange< T > make_range(T beg, T end)
void mooseError(Args &&... args) const
Emits an error prefixed with object name and type and optionally a file path to the top-level block p...
const ConsoleStream _console
An instance of helper class to write streams to the Console objects.
std::unique_ptr< MeshBase > buildMeshBaseObject(unsigned int dim=libMesh::invalid_uint)
Build a MeshBase object whose underlying type will be determined by the Mesh input file block...
bool isParamSetByUser(const std::string &name) const
Test if the supplied parameter is set by a user, as opposed to not set or set to default.
MeshGenerators are objects that can modify or add to an existing mesh.
void ErrorVector unsigned int
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template pow< 2 >(tan(_arg))+1.0) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(sqrt
std::unique_ptr< MeshBase > generate() override
Generate / modify the mesh.
registerMooseObject("MooseApp", PolyLineMeshFollowingNodeSetGenerator)