www.mooseframework.org
NearestNodeLocator.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* DO NOT MODIFY THIS HEADER */
3 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
4 /* */
5 /* (c) 2010 Battelle Energy Alliance, LLC */
6 /* ALL RIGHTS RESERVED */
7 /* */
8 /* Prepared by Battelle Energy Alliance, LLC */
9 /* Under Contract No. DE-AC07-05ID14517 */
10 /* With the U. S. Department of Energy */
11 /* */
12 /* See COPYRIGHT for full restrictions */
13 /****************************************************************/
14 
15 #include "NearestNodeLocator.h"
16 #include "MooseMesh.h"
17 #include "SubProblem.h"
19 #include "NearestNodeThread.h"
20 #include "Moose.h"
21 #include "KDTree.h"
22 
23 // libMesh
24 #include "libmesh/boundary_info.h"
25 #include "libmesh/elem.h"
26 #include "libmesh/plane.h"
27 #include "libmesh/mesh_tools.h"
28 
29 std::string
30 _boundaryFuser(BoundaryID boundary1, BoundaryID boundary2)
31 {
32  std::stringstream ss;
33 
34  ss << boundary1 << "to" << boundary2;
35 
36  return ss.str();
37 }
38 
40  MooseMesh & mesh,
41  BoundaryID boundary1,
42  BoundaryID boundary2)
43  : Restartable(_boundaryFuser(boundary1, boundary2), "NearestNodeLocator", subproblem, 0),
44  _subproblem(subproblem),
45  _mesh(mesh),
46  _slave_node_range(NULL),
47  _boundary1(boundary1),
48  _boundary2(boundary2),
49  _first(true)
50 {
51  /*
52  //sanity check on boundary ids
53  const std::set<BoundaryID>& bids=_mesh.getBoundaryIDs();
54  std::set<BoundaryID>::const_iterator sit;
55  sit=bids.find(_boundary1);
56  if (sit == bids.end())
57  mooseError("NearestNodeLocator being created for boundaries ", _boundary1, " and ", _boundary2,
58  ", but boundary ", _boundary1, " does not exist");
59  sit=bids.find(_boundary2);
60  if (sit == bids.end())
61  mooseError("NearestNodeLocator being created for boundaries ", _boundary1, " and ", _boundary2,
62  ", but boundary ", _boundary2, " does not exist");
63  */
64 }
65 
67 
68 void
70 {
71  Moose::perf_log.push("NearestNodeLocator::findNodes()", "Execution");
76  if (_first)
77  {
78  _first = false;
79 
80  // Trial slave nodes are all the nodes on the slave side
81  // We only keep the ones that are either on this processor or are likely
82  // to interact with elements on this processor (ie nodes owned by this processor
83  // are in the "neighborhood" of the slave node
84  std::vector<dof_id_type> trial_slave_nodes;
85  std::vector<dof_id_type> trial_master_nodes;
86 
87  // Build a bounding box. No reason to consider nodes outside of our inflated BB
88  BoundingBox * my_inflated_box = NULL;
89 
90  const std::vector<Real> & inflation = _mesh.getGhostedBoundaryInflation();
91 
92  // This means there was a user specified inflation... so we can build a BB
93  if (inflation.size() > 0)
94  {
95  BoundingBox my_box = MeshTools::create_local_bounding_box(_mesh);
96 
97  Real distance_x = 0;
98  Real distance_y = 0;
99  Real distance_z = 0;
100 
101  distance_x = inflation[0];
102 
103  if (inflation.size() > 1)
104  distance_y = inflation[1];
105 
106  if (inflation.size() > 2)
107  distance_z = inflation[2];
108 
109  my_inflated_box = new BoundingBox(Point(my_box.first(0) - distance_x,
110  my_box.first(1) - distance_y,
111  my_box.first(2) - distance_z),
112  Point(my_box.second(0) + distance_x,
113  my_box.second(1) + distance_y,
114  my_box.second(2) + distance_z));
115  }
116 
117  // Data structures to hold the Nodal Boundary conditions
119  for (const auto & bnode : bnd_nodes)
120  {
121  BoundaryID boundary_id = bnode->_bnd_id;
122  dof_id_type node_id = bnode->_node->id();
123 
124  // If we have a BB only consider saving this node if it's in our inflated BB
125  if (!my_inflated_box || (my_inflated_box->contains_point(*bnode->_node)))
126  {
127  if (boundary_id == _boundary1)
128  trial_master_nodes.push_back(node_id);
129  else if (boundary_id == _boundary2)
130  trial_slave_nodes.push_back(node_id);
131  }
132  }
133 
134  // don't need the BB anymore
135  delete my_inflated_box;
136 
137  const std::map<dof_id_type, std::vector<dof_id_type>> & node_to_elem_map =
139 
140  // Convert trial master nodes to a vector of Points. This would be used to
141  // construct the Kdtree.
142  std::vector<Point> master_points(trial_master_nodes.size());
143  for (unsigned int i = 0; i < trial_master_nodes.size(); ++i)
144  {
145  const Node & node = _mesh.nodeRef(trial_master_nodes[i]);
146  for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
147  master_points[i](j) = node(j);
148  }
149 
150  // Create object kd_tree of class KDTree using the coordinates of trial
151  // master nodes. Maximum number of points in each leaf of the Kd tree is set
152  // using max_leaf_size.
153  unsigned int max_leaf_size = 10;
154  KDTree kd_tree(master_points, max_leaf_size);
155 
156  NodeIdRange trial_slave_node_range(trial_slave_nodes.begin(), trial_slave_nodes.end(), 1);
157 
159  _mesh, trial_master_nodes, node_to_elem_map, _mesh.getPatchSize(), kd_tree);
160 
161  Threads::parallel_reduce(trial_slave_node_range, snt);
162 
163  _slave_nodes = snt._slave_nodes;
164  _neighbor_nodes = snt._neighbor_nodes;
165 
166  for (const auto & dof : snt._ghosted_elems)
168 
169  // Cache the slave_node_range so we don't have to build it each time
170  _slave_node_range = new NodeIdRange(_slave_nodes.begin(), _slave_nodes.end(), 1);
171  }
172 
173  _nearest_node_info.clear();
174 
176 
177  Threads::parallel_reduce(*_slave_node_range, nnt);
178 
180 
182 
183  Moose::perf_log.pop("NearestNodeLocator::findNodes()", "Execution");
184 }
185 
186 void
188 {
189  // Reset all data
190  delete _slave_node_range;
191  _slave_node_range = NULL;
192  _nearest_node_info.clear();
193 
194  _first = true;
195 
196  _slave_nodes.clear();
197  _neighbor_nodes.clear();
198 
199  // Redo the search
200  findNodes();
201 }
202 
203 Real
204 NearestNodeLocator::distance(dof_id_type node_id)
205 {
206  return _nearest_node_info[node_id]._distance;
207 }
208 
209 const Node *
211 {
212  return _nearest_node_info[node_id]._nearest_node;
213 }
214 
215 //===================================================================
217  : _nearest_node(NULL), _distance(std::numeric_limits<Real>::max())
218 {
219 }
std::map< dof_id_type, std::vector< dof_id_type > > _neighbor_nodes
void findNodes()
This is the main method that is going to start the search.
A class for creating restricted objects.
Definition: Restartable.h:31
Definition: KDTree.h:23
StoredRange< std::vector< dof_id_type >::iterator, dof_id_type > NodeIdRange
Definition: MooseTypes.h:81
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...
void reinit()
Completely redo the search from scratch.
NearestNodeLocator(SubProblem &subproblem, MooseMesh &mesh, BoundaryID boundary1, BoundaryID boundary2)
std::map< dof_id_type, NearestNodeInfo > _nearest_node_info
const std::vector< Real > & getGhostedBoundaryInflation() const
Return a writable reference to the _ghosted_boundaries_inflation vector.
Definition: MooseMesh.C:2179
std::vector< dof_id_type > _slave_nodes
std::string _boundaryFuser(BoundaryID boundary1, BoundaryID boundary2)
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:74
PerfLog perf_log
Perflog to be used by applications.
NodeIdRange * _slave_node_range
Generic class for solving transient nonlinear problems.
Definition: SubProblem.h:53
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.
SubProblem & _subproblem
virtual const Node & nodeRef(const dof_id_type i) const
Definition: MooseMesh.C:398
unsigned int getPatchSize() const
Getter for the patch_size parameter.
Definition: MooseMesh.C:2314
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > ConstBndNodeRange
Some useful StoredRange typedefs.
Definition: MooseMesh.h:1184
StoredRange< MooseMesh::const_bnd_node_iterator, const BndNode * > * getBoundaryNodeRange()
Definition: MooseMesh.C:724
boundary_id_type BoundaryID
Definition: MooseTypes.h:75
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...
Definition: MooseMesh.C:642