www.mooseframework.org
GeometricSearchData.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 
10 #include "GeometricSearchData.h"
11 // Moose includes
12 #include "NearestNodeLocator.h"
13 #include "PenetrationLocator.h"
14 #include "ElementPairLocator.h"
15 #include "SubProblem.h"
16 #include "MooseMesh.h"
17 #include "Assembly.h"
18 
19 #include "libmesh/elem.h"
20 #include "libmesh/node.h"
21 
23  : _subproblem(subproblem), _mesh(mesh), _first(true)
24 {
25 }
26 
28 {
29  for (auto & it : _penetration_locators)
30  delete it.second;
31 
32  for (auto & it : _nearest_node_locators)
33  delete it.second;
34 }
35 
36 void
38 {
39  if (type == ALL || type == QUADRATURE || type == NEAREST_NODE)
40  {
41  if (_first) // Only do this once
42  {
43  _first = false;
44 
45  for (const auto & it : _slave_to_qslave)
46  generateQuadratureNodes(it.first, it.second);
47 
48  // reinit on displaced mesh before update
49  for (const auto & epl_it : _element_pair_locators)
50  {
51  ElementPairLocator & epl = *(epl_it.second);
52  epl.reinit();
53  }
54  }
55 
56  // Update the position of quadrature nodes first
57  for (const auto & qbnd : _quadrature_boundaries)
59  }
60 
61  if (type == ALL || type == NEAREST_NODE)
62  {
63  for (const auto & nnl_it : _nearest_node_locators)
64  {
65  NearestNodeLocator * nnl = nnl_it.second;
66  nnl->findNodes();
67  }
68  }
69 
70  if (type == ALL || type == PENETRATION)
71  {
72  for (const auto & pl_it : _penetration_locators)
73  {
74  PenetrationLocator * pl = pl_it.second;
75  pl->detectPenetration();
76  }
77  }
78 
79  if (type == ALL || type == PENETRATION)
80  {
81  for (auto & elem_pair_locator_pair : _element_pair_locators)
82  {
83  ElementPairLocator & epl = (*elem_pair_locator_pair.second);
84  epl.update();
85  }
86  }
87 }
88 
89 void
91 {
93  // Update the position of quadrature nodes first
94  for (const auto & qbnd : _quadrature_boundaries)
96 
97  for (const auto & nnl_it : _nearest_node_locators)
98  {
99  NearestNodeLocator * nnl = nnl_it.second;
100  nnl->reinit();
101  }
102 
103  for (const auto & pl_it : _penetration_locators)
104  {
105  PenetrationLocator * pl = pl_it.second;
106  pl->reinit();
107  }
108 
109  for (const auto & epl_it : _element_pair_locators)
110  {
111  ElementPairLocator & epl = *(epl_it.second);
112  epl.reinit();
113  }
114 }
115 
116 void
118 {
119  for (const auto & nnl_it : _nearest_node_locators)
120  {
121  NearestNodeLocator * nnl = nnl_it.second;
122  nnl->reinit();
123  }
124 }
125 
126 Real
128 {
129  Real max = 0.0;
130 
131  for (const auto & nnl_it : _nearest_node_locators)
132  {
133  NearestNodeLocator * nnl = nnl_it.second;
134 
135  if (nnl->_max_patch_percentage > max)
136  max = nnl->_max_patch_percentage;
137  }
138 
139  return max;
140 }
141 
143 GeometricSearchData::getPenetrationLocator(const BoundaryName & master,
144  const BoundaryName & slave,
145  Order order)
146 {
147  unsigned int master_id = _mesh.getBoundaryID(master);
148  unsigned int slave_id = _mesh.getBoundaryID(slave);
149 
150  _subproblem.addGhostedBoundary(master_id);
152 
153  PenetrationLocator * pl =
154  _penetration_locators[std::pair<unsigned int, unsigned int>(master_id, slave_id)];
155 
156  if (!pl)
157  {
159  *this,
160  _mesh,
161  master_id,
162  slave_id,
163  order,
164  getNearestNodeLocator(master_id, slave_id));
165  _penetration_locators[std::pair<unsigned int, unsigned int>(master_id, slave_id)] = pl;
166  }
167 
168  return *pl;
169 }
170 
173  const BoundaryName & slave,
174  Order order)
175 {
176  unsigned int master_id = _mesh.getBoundaryID(master);
177  unsigned int slave_id = _mesh.getBoundaryID(slave);
178 
179  _subproblem.addGhostedBoundary(master_id);
181 
182  // Generate a new boundary id
183  // TODO: Make this better!
184  unsigned int base_id = 1e6;
185  unsigned int qslave_id = slave_id + base_id;
186 
187  _slave_to_qslave[slave_id] = qslave_id;
188 
189  PenetrationLocator * pl =
190  _penetration_locators[std::pair<unsigned int, unsigned int>(master_id, qslave_id)];
191 
192  if (!pl)
193  {
195  *this,
196  _mesh,
197  master_id,
198  qslave_id,
199  order,
200  getQuadratureNearestNodeLocator(master_id, slave_id));
201  _penetration_locators[std::pair<unsigned int, unsigned int>(master_id, qslave_id)] = pl;
202  }
203 
204  return *pl;
205 }
206 
208 GeometricSearchData::getNearestNodeLocator(const BoundaryName & master, const BoundaryName & slave)
209 {
210  unsigned int master_id = _mesh.getBoundaryID(master);
211  unsigned int slave_id = _mesh.getBoundaryID(slave);
212 
213  _subproblem.addGhostedBoundary(master_id);
215 
216  return getNearestNodeLocator(master_id, slave_id);
217 }
218 
220 GeometricSearchData::getNearestNodeLocator(const unsigned int master_id,
221  const unsigned int slave_id)
222 {
223  NearestNodeLocator * nnl =
224  _nearest_node_locators[std::pair<unsigned int, unsigned int>(master_id, slave_id)];
225 
226  _subproblem.addGhostedBoundary(master_id);
228 
229  if (!nnl)
230  {
231  nnl = new NearestNodeLocator(_subproblem, _mesh, master_id, slave_id);
232  _nearest_node_locators[std::pair<unsigned int, unsigned int>(master_id, slave_id)] = nnl;
233  }
234 
235  return *nnl;
236 }
237 
240  const BoundaryName & slave)
241 {
242  unsigned int master_id = _mesh.getBoundaryID(master);
243  unsigned int slave_id = _mesh.getBoundaryID(slave);
244 
245  _subproblem.addGhostedBoundary(master_id);
247 
248  return getQuadratureNearestNodeLocator(master_id, slave_id);
249 }
250 
253  const unsigned int slave_id)
254 {
255  // TODO: Make this better!
256  unsigned int base_id = 1e6;
257  unsigned int qslave_id = slave_id + base_id;
258 
259  _slave_to_qslave[slave_id] = qslave_id;
260 
261  return getNearestNodeLocator(master_id, qslave_id);
262 }
263 
264 void
265 GeometricSearchData::generateQuadratureNodes(unsigned int slave_id, unsigned int qslave_id)
266 {
267  // Have we already generated quadrature nodes for this boundary id?
268  if (_quadrature_boundaries.find(slave_id) != _quadrature_boundaries.end())
269  return;
270 
271  _quadrature_boundaries.insert(slave_id);
272 
273  const MooseArray<Point> & points_face = _subproblem.assembly(0).qPointsFace();
274 
276  for (const auto & belem : range)
277  {
278  const Elem * elem = belem->_elem;
279  unsigned short int side = belem->_side;
280  BoundaryID boundary_id = belem->_bnd_id;
281 
282  if (elem->processor_id() == _subproblem.processor_id())
283  {
284  if (boundary_id == (BoundaryID)slave_id)
285  {
287  _subproblem.prepare(elem, 0);
288  _subproblem.reinitElemFace(elem, side, boundary_id, 0);
289 
290  for (unsigned int qp = 0; qp < points_face.size(); qp++)
291  _mesh.addQuadratureNode(elem, side, qp, qslave_id, points_face[qp]);
292  }
293  }
294  }
295 }
296 
297 void
298 GeometricSearchData::addElementPairLocator(const unsigned int & interface_id,
299  std::shared_ptr<ElementPairLocator> epl)
300 {
301  _element_pair_locators[interface_id] = epl;
302 }
303 
304 void
306 {
307  const MooseArray<Point> & points_face = _subproblem.assembly(0).qPointsFace();
308 
310  for (const auto & belem : range)
311  {
312  const Elem * elem = belem->_elem;
313  unsigned short int side = belem->_side;
314  BoundaryID boundary_id = belem->_bnd_id;
315 
316  if (elem->processor_id() == _subproblem.processor_id())
317  {
318  if (boundary_id == (BoundaryID)slave_id)
319  {
321  _subproblem.prepare(elem, 0);
322  _subproblem.reinitElemFace(elem, side, boundary_id, 0);
323 
324  for (unsigned int qp = 0; qp < points_face.size(); qp++)
325  (*_mesh.getQuadratureNode(elem, side, qp)) = points_face[qp];
326  }
327  }
328  }
329 }
330 
331 void
333 {
334  // Regenerate the quadrature nodes
335  for (const auto & it : _slave_to_qslave)
336  generateQuadratureNodes(it.first, it.second);
337 }
338 
339 void
341 {
342  for (const auto & nnl_it : _nearest_node_locators)
343  {
344  NearestNodeLocator * nnl = nnl_it.second;
345  nnl->updateGhostedElems();
346  }
347 }
Node * addQuadratureNode(const Elem *elem, const unsigned short int side, const unsigned int qp, BoundaryID bid, const Point &point)
Adds a fictitious "QuadratureNode".
Definition: MooseMesh.C:925
std::set< unsigned int > _quadrature_boundaries
These are real boundaries that have quadrature nodes on them.
void findNodes()
This is the main method that is going to start the search.
virtual void reinit()
virtual void update()
bool _first
Denotes whether this is the first time the geometric search objects have been updated.
PenetrationLocator & getQuadraturePenetrationLocator(const BoundaryName &master, const BoundaryName &slave, Order order=FIRST)
Finds the nearest node to each node in boundary1 to each node in boundary2 and the other way around...
PenetrationLocator & getPenetrationLocator(const BoundaryName &master, const BoundaryName &slave, Order order=FIRST)
void addElementPairLocator(const unsigned int &interface_id, std::shared_ptr< ElementPairLocator > epl)
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > ConstBndElemRange
Definition: MooseMesh.h:1259
virtual Assembly & assembly(THREAD_ID tid)=0
virtual void setCurrentSubdomainID(const Elem *elem, THREAD_ID tid)=0
virtual void reinitElemFace(const Elem *elem, unsigned int side, BoundaryID bnd_id, THREAD_ID tid)=0
void reinit()
Completely redo the search from scratch.
void updateQuadratureNodes(unsigned int slave_id)
Update the positions of the quadrature nodes.
std::map< unsigned int, unsigned int > _slave_to_qslave
A mapping of the real boundary id to the slave boundary ids.
void updateGhostedElems()
Updates the list of ghosted elements at the start of each time step for the nonlinear iteration patch...
NearestNodeLocator & getNearestNodeLocator(const BoundaryName &master, const BoundaryName &slave)
Real maxPatchPercentage()
Maximum percentage through the search patch that any NearestNodeLocator had to look.
NearestNodeLocator & getQuadratureNearestNodeLocator(const BoundaryName &master, const BoundaryName &slave)
unsigned int size() const
The number of elements that can currently be stored in the array.
Definition: MooseArray.h:259
void clearQuadratureNodes()
Clear out any existing quadrature nodes.
Definition: MooseMesh.C:995
boundary_id_type BoundaryID
virtual void prepare(const Elem *elem, THREAD_ID tid)=0
void reinitQuadratureNodes(unsigned int slave_id)
Completely redo quadrature nodes.
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition: MooseMesh.h:74
std::map< unsigned int, std::shared_ptr< ElementPairLocator > > _element_pair_locators
void reinit()
Completely redo all geometric search objects.
void updateGhostedElems()
Updates the ghosted elements at the start of the time step for iterion patch update strategy...
This is the ElementPairLocator class.
GeometricSearchType
Used to select groups of geometric search objects to update.
Node * getQuadratureNode(const Elem *elem, const unsigned short int side, const unsigned int qp)
Get a specified quadrature node.
Definition: MooseMesh.C:977
std::map< std::pair< unsigned int, unsigned int >, PenetrationLocator * > _penetration_locators
MatType type
Generic class for solving transient nonlinear problems.
Definition: SubProblem.h:59
std::map< std::pair< unsigned int, unsigned int >, NearestNodeLocator * > _nearest_node_locators
virtual void addGhostedBoundary(BoundaryID boundary_id)=0
Will make sure that all necessary elements from boundary_id are ghosted to this processor.
const MooseArray< Point > & qPointsFace() const
Returns the reference to the current quadrature being used.
Definition: Assembly.h:247
void update(GeometricSearchType type=ALL)
Update all of the search objects.
StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
Definition: MooseMesh.C:801
void reinit()
Completely redo the search from scratch.
void clearNearestNodeLocators()
Clear out the Penetration Locators so they will redo the search.
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
Definition: MooseMesh.C:1007
void generateQuadratureNodes(unsigned int slave_id, unsigned int qslave_id)
Add Quadrature Nodes to the Mesh in support of Quadrature based penetration location and nearest node...
GeometricSearchData(SubProblem &subproblem, MooseMesh &mesh)