21#include "libmesh/boundary_info.h"
22#include "libmesh/elem.h"
23#include "libmesh/plane.h"
24#include "libmesh/mesh_tools.h"
31 Moose::stringify(boundary1) +
Moose::stringify(boundary2),
35 "NearestNodeLocator_" +
Moose::stringify(boundary1) +
"_" +
36 Moose::stringify(boundary2)),
37 _subproblem(subproblem),
39 _boundary1(boundary1),
40 _boundary2(boundary2),
42 _reinit_iteration(true),
43 _patch_update_strategy(_mesh.getPatchUpdateStrategy())
65 TIME_SECTION(
"findNodes", 3,
"Finding Nearest Nodes");
81 std::vector<dof_id_type> trial_secondary_nodes;
82 std::vector<dof_id_type> trial_primary_nodes;
85 std::unique_ptr<BoundingBox> my_inflated_box =
nullptr;
90 if (inflation.size() > 0)
95 for (
unsigned int i = 0; i < inflation.size(); ++i)
99 std::make_unique<BoundingBox>(my_box.first -
distance, my_box.second +
distance);
104 for (
const auto & bnode : bnd_nodes)
107 dof_id_type node_id = bnode->_node->id();
110 if (!my_inflated_box || (my_inflated_box->contains_point(*bnode->_node)))
113 trial_primary_nodes.push_back(node_id);
115 trial_secondary_nodes.push_back(node_id);
121 std::vector<Point> primary_points(trial_primary_nodes.size());
122 for (
unsigned int i = 0; i < trial_primary_nodes.size(); ++i)
124 const Node & node =
_mesh.
nodeRef(trial_primary_nodes[i]);
125 primary_points[i] = node;
133 trial_secondary_nodes.begin(), trial_secondary_nodes.end(), 1);
190 auto node_to_elem_pair = node_to_elem_map.find(nearest_node->id());
192 if (node_to_elem_pair != node_to_elem_map.end())
194 const std::vector<dof_id_type> & elems_connected_to_node = node_to_elem_pair->second;
195 for (
const auto & dof : elems_connected_to_node)
196 if (std::find(ghost.begin(), ghost.end(), dof) == ghost.end() &&
198 mooseError(
"Error in NearestNodeLocator: The nearest neighbor lies outside the "
199 "ghosted set of elements. Increase the ghosting_patch_size parameter in the "
200 "mesh block and try again.");
209 TIME_SECTION(
"reinit", 3,
"Reinitializing Nearest Node Search");
249 TIME_SECTION(
"updatePatch", 3,
"Updating Nearest Node Search Patch");
251 std::vector<dof_id_type> trial_primary_nodes;
254 std::unique_ptr<BoundingBox> my_inflated_box =
nullptr;
259 if (inflation.size() > 0)
264 for (
unsigned int i = 0; i < inflation.size(); ++i)
268 std::make_unique<BoundingBox>(my_box.first -
distance, my_box.second +
distance);
273 for (
const auto & bnode : bnd_nodes)
276 dof_id_type node_id = bnode->_node->id();
279 if (!my_inflated_box || (my_inflated_box->contains_point(*bnode->_node)))
282 trial_primary_nodes.push_back(node_id);
287 std::vector<Point> primary_points(trial_primary_nodes.size());
288 for (
unsigned int i = 0; i < trial_primary_nodes.size(); ++i)
290 const Node & node =
_mesh.
nodeRef(trial_primary_nodes[i]);
291 primary_points[i] = node;
300 NodeIdRange secondary_node_range(secondary_nodes.begin(), secondary_nodes.end(), 1);
320 for (
const auto & node_id : tracked_secondary_nodes)
324 tracked_secondary_nodes.begin(), tracked_secondary_nodes.end(), 1);
336 for (
const auto & node_id : tracked_secondary_node_range)
344 auto node_to_elem_pair = node_to_elem_map.find(nearest_node->id());
346 if (node_to_elem_pair != node_to_elem_map.end())
348 const std::vector<dof_id_type> & elems_connected_to_node = node_to_elem_pair->second;
349 for (
const auto & dof : elems_connected_to_node)
350 if (std::find(ghost.begin(), ghost.end(), dof) == ghost.end() &&
352 mooseError(
"Error in NearestNodeLocator: The nearest neighbor lies outside the ghosted "
353 "set of elements. Increase the ghosting_patch_size parameter in the mesh "
354 "block and try again.");
362 TIME_SECTION(
"updateGhostedElems", 5,
"Updating Nearest Node Search Because of Ghosting");
377 : _nearest_node(nullptr), _distance(
std::numeric_limits<Real>::max())
boundary_id_type BoundaryID
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
virtual const Node & nodeRef(const dof_id_type i) const
unsigned int getMaxLeafSize() const
Getter for the maximum leaf size parameter.
virtual Elem * elemPtr(const dof_id_type i)
MeshBase & getMesh()
Accessor for the underlying libMesh Mesh object.
const std::vector< Real > & getGhostedBoundaryInflation() const
Return a writable reference to the _ghosted_boundaries_inflation vector.
const std::unordered_map< dof_id_type, std::vector< dof_id_type > > & nodeToElemMap()
If not already created, creates a map from every node to all elements to which they are connected.
unsigned int getGhostingPatchSize() const
Getter for the ghosting_patch_size parameter.
unsigned int getPatchSize() const
Getter for the patch_size parameter.
libMesh::StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
const Moose::PatchUpdateType _patch_update_strategy
const Node * nearestNode(dof_id_type node_id)
Valid to call this after findNodes() has been called to get a pointer to the nearest node.
std::map< dof_id_type, std::vector< dof_id_type > > _neighbor_nodes
Real _max_patch_percentage
std::unique_ptr< NodeIdRange > _secondary_node_range
std::vector< dof_id_type > _new_ghosted_elems
void updatePatch(std::vector< dof_id_type > &secondary_nodes)
Reconstructs the KDtree, updates the patch for the nodes in secondary_nodes, and updates the closest ...
NearestNodeLocator(SubProblem &subproblem, MooseMesh &mesh, BoundaryID boundary1, BoundaryID boundary2)
Real distance(dof_id_type node_id)
Valid to call this after findNodes() has been called to get the distance to the nearest node.
std::vector< dof_id_type > _secondary_nodes
void reinit()
Completely redo the search from scratch.
std::map< dof_id_type, NearestNodeInfo > _nearest_node_info
void findNodes()
This is the main method that is going to start the search.
void updateGhostedElems()
Updates the ghosted elements at the start of the time step for iteration patch update strategy.
Real _max_patch_percentage
std::map< dof_id_type, NearestNodeLocator::NearestNodeInfo > _nearest_node_info
Interface for objects interacting with the PerfGraph.
A class for creating restricted objects.
std::set< dof_id_type > _ghosted_elems
Elements that we need to ghost.
std::map< dof_id_type, std::vector< dof_id_type > > _neighbor_nodes
The neighborhood nodes associated with each node.
std::vector< dof_id_type > _secondary_nodes
List of the secondary nodes we're actually going to keep track of.
Generic class for solving transient nonlinear problems.
virtual std::set< dof_id_type > & ghostedElems()
Return the list of elements that should have their DoFs ghosted to this processor.
virtual void addGhostedElem(dof_id_type elem_id)=0
Will make sure that all dofs connected to elem_id are ghosted to this processor.
processor_id_type processor_id() const
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
void parallel_reduce(const Range &range, Body &body, unsigned int n_threads=libMesh::n_threads())