21 #include "libmesh/boundary_info.h" 22 #include "libmesh/elem.h" 23 #include "libmesh/plane.h" 24 #include "libmesh/mesh_tools.h" 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");
71 const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map =
_mesh.
nodeToElemMap();
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)
92 BoundingBox my_box = MeshTools::create_local_bounding_box(
_mesh);
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)
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);
138 Threads::parallel_reduce(trial_secondary_node_range, snt);
153 Threads::parallel_reduce(trial_secondary_node_range, snt_ghosting);
155 for (
const auto & dof : snt_ghosting._ghosted_elems)
160 for (
const auto & dof : snt._ghosted_elems)
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");
247 TIME_SECTION(
"updatePatch", 3,
"Updating Nearest Node Search Patch");
249 std::vector<dof_id_type> trial_primary_nodes;
252 std::unique_ptr<BoundingBox> my_inflated_box =
nullptr;
257 if (inflation.size() > 0)
259 BoundingBox my_box = MeshTools::create_local_bounding_box(
_mesh);
262 for (
unsigned int i = 0; i < inflation.size(); ++i)
266 std::make_unique<BoundingBox>(my_box.first -
distance, my_box.second +
distance);
271 for (
const auto & bnode : bnd_nodes)
277 if (!my_inflated_box || (my_inflated_box->contains_point(*bnode->_node)))
280 trial_primary_nodes.push_back(node_id);
285 std::vector<Point> primary_points(trial_primary_nodes.size());
286 for (
unsigned int i = 0; i < trial_primary_nodes.size(); ++i)
288 const Node & node =
_mesh.
nodeRef(trial_primary_nodes[i]);
289 primary_points[i] = node;
292 const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map =
_mesh.
nodeToElemMap();
298 NodeIdRange secondary_node_range(secondary_nodes.begin(), secondary_nodes.end(), 1);
303 Threads::parallel_reduce(secondary_node_range, snt);
309 Threads::parallel_reduce(secondary_node_range, snt_ghosting);
312 for (
const auto & dof : snt_ghosting._ghosted_elems)
315 std::vector<dof_id_type> tracked_secondary_nodes = snt._secondary_nodes;
318 for (
const auto & node_id : tracked_secondary_nodes)
322 tracked_secondary_nodes.begin(), tracked_secondary_nodes.end(), 1);
326 Threads::parallel_reduce(tracked_secondary_node_range, nnt);
334 for (
const auto & node_id : tracked_secondary_node_range)
340 const Node * nearest_node = nnt._nearest_node_info[node_id]._nearest_node;
342 auto node_to_elem_pair = node_to_elem_map.find(nearest_node->id());
344 if (node_to_elem_pair != node_to_elem_map.end())
346 const std::vector<dof_id_type> & elems_connected_to_node = node_to_elem_pair->second;
347 for (
const auto & dof : elems_connected_to_node)
348 if (std::find(ghost.begin(), ghost.end(), dof) == ghost.end() &&
350 mooseError(
"Error in NearestNodeLocator: The nearest neighbor lies outside the ghosted " 351 "set of elements. Increase the ghosting_patch_size parameter in the mesh " 352 "block and try again.");
360 TIME_SECTION(
"updateGhostedElems", 5,
"Updating Nearest Node Search Because of Ghosting");
375 : _nearest_node(nullptr), _distance(
std::numeric_limits<
Real>::
max())
std::map< dof_id_type, std::vector< dof_id_type > > _neighbor_nodes
Real _max_patch_percentage
void findNodes()
This is the main method that is going to start the search.
A class for creating restricted objects.
virtual Elem * elemPtr(const dof_id_type i)
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application...
StoredRange< std::vector< dof_id_type >::iterator, dof_id_type > NodeIdRange
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 ...
unsigned int getGhostingPatchSize() const
Getter for the ghosting_patch_size parameter.
std::map< dof_id_type, NearestNodeLocator::NearestNodeInfo > _nearest_node_info
Real distance(dof_id_type node_id)
Valid to call this after findNodes() has been called to get the distance to the nearest node...
const std::vector< Real > & getGhostedBoundaryInflation() const
Return a writable reference to the _ghosted_boundaries_inflation vector.
void reinit()
Completely redo the search from scratch.
virtual const Node & nodeRef(const dof_id_type i) const
NearestNodeLocator(SubProblem &subproblem, MooseMesh &mesh, BoundaryID boundary1, BoundaryID boundary2)
auto max(const L &left, const R &right)
std::map< dof_id_type, NearestNodeInfo > _nearest_node_info
std::unique_ptr< NodeIdRange > _secondary_node_range
std::vector< dof_id_type > _secondary_nodes
Real _max_patch_percentage
boundary_id_type BoundaryID
unsigned int getMaxLeafSize() const
Getter for the maximum leaf size parameter.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
const Moose::PatchUpdateType _patch_update_strategy
void updateGhostedElems()
Updates the ghosted elements at the start of the time step for iterion patch update strategy...
virtual std::set< dof_id_type > & ghostedElems()
Return the list of elements that should have their DoFs ghosted to this processor.
std::string stringify(const T &t)
conversion to string
unsigned int getPatchSize() const
Getter for the patch_size parameter.
Interface for objects interacting with the PerfGraph.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Generic class for solving transient nonlinear problems.
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...
virtual void addGhostedElem(dof_id_type elem_id)=0
Will make sure that all dofs connected to elem_id are ghosted to this processor.
std::vector< dof_id_type > _new_ghosted_elems
MOOSE now contains C++17 code, so give a reasonable error message stating what the user can do to add...
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > ConstBndNodeRange
Some useful StoredRange typedefs.
processor_id_type processor_id() const
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
const std::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...