www.mooseframework.org
SlaveNeighborhoodThread.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
11 
12 #include "AuxiliarySystem.h"
13 #include "Problem.h"
14 #include "FEProblem.h"
15 #include "MooseMesh.h"
16 
17 #include "libmesh/threads.h"
18 
20  const MooseMesh & mesh,
21  const std::vector<dof_id_type> & trial_master_nodes,
22  const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map,
23  const unsigned int patch_size,
24  KDTree & kd_tree)
25  : _kd_tree(kd_tree),
26  _mesh(mesh),
27  _trial_master_nodes(trial_master_nodes),
28  _node_to_elem_map(node_to_elem_map),
29  _patch_size(patch_size)
30 {
31 }
32 
33 // Splitting Constructor
35  Threads::split /*split*/)
36  : _kd_tree(x._kd_tree),
37  _mesh(x._mesh),
38  _trial_master_nodes(x._trial_master_nodes),
39  _node_to_elem_map(x._node_to_elem_map),
40  _patch_size(x._patch_size)
41 {
42 }
43 
50 void
52 {
53  unsigned int patch_size =
54  std::min(_patch_size, static_cast<unsigned int>(_trial_master_nodes.size()));
55 
56  std::vector<std::size_t> return_index(patch_size);
57 
58  for (const auto & node_id : range)
59  {
60  const Node & node = _mesh.nodeRef(node_id);
61  Point query_pt;
62  for (unsigned int i = 0; i < LIBMESH_DIM; ++i)
63  query_pt(i) = node(i);
64 
75  _kd_tree.neighborSearch(query_pt, patch_size, return_index);
76 
77  std::vector<dof_id_type> neighbor_nodes(return_index.size());
78  for (unsigned int i = 0; i < return_index.size(); ++i)
79  neighbor_nodes[i] = _trial_master_nodes[return_index[i]];
80 
81  processor_id_type processor_id = _mesh.processor_id();
82 
91  bool need_to_track = false;
92 
93  if (_mesh.nodeRef(node_id).processor_id() == processor_id)
94  need_to_track = true;
95  else
96  {
97  {
98  auto node_to_elem_pair = _node_to_elem_map.find(node_id);
99  if (node_to_elem_pair != _node_to_elem_map.end())
100  {
101  const std::vector<dof_id_type> & elems_connected_to_node = node_to_elem_pair->second;
102 
103  // See if we own any of the elements connected to the slave node
104  for (const auto & dof : elems_connected_to_node)
105  if (_mesh.elemPtr(dof)->processor_id() == processor_id)
106  {
107  need_to_track = true;
108  break; // Break out of element loop
109  }
110  }
111  }
112 
113  if (!need_to_track)
114  { // Now check the neighbor nodes to see if we own any of them
115  for (const auto & neighbor_node_id : neighbor_nodes)
116  {
117  if (_mesh.nodeRef(neighbor_node_id).processor_id() == processor_id)
118  need_to_track = true;
119  else // Now see if we own any of the elements connected to the neighbor nodes
120  {
121  auto node_to_elem_pair = _node_to_elem_map.find(neighbor_node_id);
122  mooseAssert(node_to_elem_pair != _node_to_elem_map.end(),
123  "Missing entry in node to elem map");
124  const std::vector<dof_id_type> & elems_connected_to_node = node_to_elem_pair->second;
125 
126  for (const auto & dof : elems_connected_to_node)
127  if (_mesh.elemPtr(dof)->processor_id() == processor_id)
128  {
129  need_to_track = true;
130  break; // Break out of element loop
131  }
132  }
133 
134  if (need_to_track)
135  break; // Breaking out of neighbor loop
136  }
137  }
138  }
139 
140  if (need_to_track)
141  {
142  // Add this node as a slave node to search in the future
143  _slave_nodes.push_back(node_id);
144 
145  // Set it's neighbors
146  _neighbor_nodes[node_id] = neighbor_nodes;
147 
148  { // Add the elements connected to the slave node to the ghosted list
149  auto node_to_elem_pair = _node_to_elem_map.find(node_id);
150 
151  if (node_to_elem_pair != _node_to_elem_map.end())
152  {
153  const std::vector<dof_id_type> & elems_connected_to_node = node_to_elem_pair->second;
154 
155  for (const auto & dof : elems_connected_to_node)
156  _ghosted_elems.insert(dof);
157  }
158  }
159  // Now add elements connected to the neighbor nodes to the ghosted list
160  for (unsigned int neighbor_it = 0; neighbor_it < neighbor_nodes.size(); neighbor_it++)
161  {
162  auto node_to_elem_pair = _node_to_elem_map.find(neighbor_nodes[neighbor_it]);
163  mooseAssert(node_to_elem_pair != _node_to_elem_map.end(),
164  "Missing entry in node to elem map");
165  const std::vector<dof_id_type> & elems_connected_to_node = node_to_elem_pair->second;
166 
167  for (const auto & dof : elems_connected_to_node)
168  _ghosted_elems.insert(dof);
169  }
170  }
171  }
172 }
173 
174 void
176 {
177  _slave_nodes.insert(_slave_nodes.end(), other._slave_nodes.begin(), other._slave_nodes.end());
178  _ghosted_elems.insert(other._ghosted_elems.begin(), other._ghosted_elems.end());
179  _neighbor_nodes.insert(other._neighbor_nodes.begin(), other._neighbor_nodes.end());
180 }
virtual Elem * elemPtr(const dof_id_type i)
Definition: MooseMesh.C:2267
Definition: KDTree.h:19
StoredRange< std::vector< dof_id_type >::iterator, dof_id_type > NodeIdRange
Definition: MooseTypes.h:165
const std::map< dof_id_type, std::vector< dof_id_type > > & _node_to_elem_map
Node to elem map.
void operator()(const NodeIdRange &range)
Save a patch of nodes that are close to each of the slave nodes to speed the search algorithm TODO: T...
void neighborSearch(Point &query_point, unsigned int patch_size, std::vector< std::size_t > &return_index)
Definition: KDTree.C:27
static PetscErrorCode Vec x
std::set< dof_id_type > _ghosted_elems
Elements that we need to ghost.
virtual const Node & nodeRef(const dof_id_type i) const
Definition: MooseMesh.C:436
std::vector< std::string > split(const std::string &str, const std::string &delimiter)
Python like split function for strings.
Definition: MooseUtils.C:736
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:74
std::map< dof_id_type, std::vector< dof_id_type > > _neighbor_nodes
The neighborhood nodes associated with each node.
SlaveNeighborhoodThread(const MooseMesh &mesh, const std::vector< dof_id_type > &trial_master_nodes, const std::map< dof_id_type, std::vector< dof_id_type >> &node_to_elem_map, const unsigned int patch_size, KDTree &_kd_tree)
void join(const SlaveNeighborhoodThread &other)
std::vector< dof_id_type > _slave_nodes
List of the slave nodes we&#39;re actually going to keep track of.
const std::vector< dof_id_type > & _trial_master_nodes
Nodes to search against.
unsigned int _patch_size
The number of nodes to keep.
const MooseMesh & _mesh
The Mesh.