https://mooseframework.inl.gov
Loading...
Searching...
No Matches
GeometricSearchData.C
Go to the documentation of this file.
1//* This file is part of the MOOSE framework
2//* https://mooseframework.inl.gov
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#include "libmesh/int_range.h"
22
24 : _subproblem(subproblem), _mesh(mesh), _first(true), _search_using_point_locator(false)
25{
26 // do a check on the boundary IDs to see if any conflict will rise from computing QP node set IDs
27 const auto & nodeset_ids = _mesh.meshNodesetIds();
28 for (const auto id : nodeset_ids)
29 if (nodeset_ids.find(-id - 1) != nodeset_ids.end())
30 mooseError("Your mesh contains nodesets with negative IDs that interfere with QP nodeset IDs "
31 "potentially generated by the GeometricSearch system.");
32}
33
35{
36 for (auto & it : _penetration_locators)
37 delete it.second;
38
39 for (auto & it : _nearest_node_locators)
40 delete it.second;
41}
42
43void
45{
46 if (type == ALL || type == QUADRATURE || type == NEAREST_NODE)
47 {
48 if (_first) // Only do this once
49 {
50 _first = false;
51
52 for (const auto & it : _secondary_to_qsecondary)
53 generateQuadratureNodes(it.first, it.second);
54
55 // reinit on displaced mesh before update
56 for (const auto & epl_it : _element_pair_locators)
57 {
58 ElementPairLocator & epl = *(epl_it.second);
59 epl.reinit();
60 }
61 }
62
63 // Update the position of quadrature nodes first
64 for (const auto & qbnd : _quadrature_boundaries)
66 }
67
68 if (type == ALL || type == NEAREST_NODE)
69 {
70 for (const auto & nnl_it : _nearest_node_locators)
71 {
72 NearestNodeLocator * nnl = nnl_it.second;
73 nnl->findNodes();
74 }
75 }
76
77 if (type == ALL || type == PENETRATION)
78 {
79 for (const auto & pl_it : _penetration_locators)
80 {
81 PenetrationLocator * pl = pl_it.second;
83 }
84 }
85
86 if (type == ALL || type == PENETRATION)
87 {
88 for (auto & elem_pair_locator_pair : _element_pair_locators)
89 {
90 ElementPairLocator & epl = (*elem_pair_locator_pair.second);
91 epl.update();
92 }
93 }
94}
95
96void
98{
100 // Update the position of quadrature nodes first
101 for (const auto & qbnd : _quadrature_boundaries)
103
104 for (const auto & nnl_it : _nearest_node_locators)
105 {
106 NearestNodeLocator * nnl = nnl_it.second;
107 nnl->reinit();
108 }
109
110 for (const auto & pl_it : _penetration_locators)
111 {
112 PenetrationLocator * pl = pl_it.second;
113 pl->reinit();
114 }
115
116 for (const auto & epl_it : _element_pair_locators)
117 {
118 ElementPairLocator & epl = *(epl_it.second);
119 epl.reinit();
120 }
121}
122
123void
125{
126 for (const auto & nnl_it : _nearest_node_locators)
127 {
128 NearestNodeLocator * nnl = nnl_it.second;
129 nnl->reinit();
130 }
131}
132
133Real
135{
136 Real max = 0.0;
137
138 for (const auto & nnl_it : _nearest_node_locators)
139 {
140 NearestNodeLocator * nnl = nnl_it.second;
141
142 if (nnl->_max_patch_percentage > max)
143 max = nnl->_max_patch_percentage;
144 }
145
146 return max;
147}
148
151 const BoundaryName & secondary,
152 Order order)
153{
154 auto primary_id = _mesh.getBoundaryID(primary);
155 auto secondary_id = _mesh.getBoundaryID(secondary);
156
158 _subproblem.addGhostedBoundary(secondary_id);
159
160 PenetrationLocator * pl =
161 _penetration_locators[std::pair<BoundaryID, BoundaryID>(primary_id, secondary_id)];
162
163 if (!pl)
164 {
166 *this,
167 _mesh,
168 primary_id,
169 secondary_id,
170 order,
171 getNearestNodeLocator(primary_id, secondary_id));
172
174 pl->setUsePointLocator(true);
175
176 _penetration_locators[std::pair<BoundaryID, BoundaryID>(primary_id, secondary_id)] = pl;
177 }
178
179 return *pl;
180}
181
184 const BoundaryName & secondary,
185 Order order)
186{
187 const auto primary_id = _mesh.getBoundaryID(primary);
188 const auto secondary_id = _mesh.getBoundaryID(secondary);
189
191 _subproblem.addGhostedBoundary(secondary_id);
192
193 // Generate a new boundary id (we use the negative numbers and subtract 1 to disambiguate id=0)
194 const auto qsecondary_id = -secondary_id - 1;
195
196 _secondary_to_qsecondary[secondary_id] = qsecondary_id;
197
198 PenetrationLocator * pl =
199 _penetration_locators[std::pair<BoundaryID, BoundaryID>(primary_id, qsecondary_id)];
200
201 if (!pl)
202 {
204 *this,
205 _mesh,
206 primary_id,
207 qsecondary_id,
208 order,
209 getQuadratureNearestNodeLocator(primary_id, secondary_id));
210
212 pl->setUsePointLocator(true);
213
214 _penetration_locators[std::pair<BoundaryID, BoundaryID>(primary_id, qsecondary_id)] = pl;
215 }
216
217 return *pl;
218}
219
222 const BoundaryName & secondary)
223{
224 const auto primary_id = _mesh.getBoundaryID(primary);
225 const auto secondary_id = _mesh.getBoundaryID(secondary);
226
228 _subproblem.addGhostedBoundary(secondary_id);
229
230 return getNearestNodeLocator(primary_id, secondary_id);
231}
232
235 const BoundaryID secondary_id)
236{
237 NearestNodeLocator * nnl =
238 _nearest_node_locators[std::pair<BoundaryID, BoundaryID>(primary_id, secondary_id)];
239
241 _subproblem.addGhostedBoundary(secondary_id);
242
243 if (!nnl)
244 {
245 nnl = new NearestNodeLocator(_subproblem, _mesh, primary_id, secondary_id);
246 _nearest_node_locators[std::pair<BoundaryID, BoundaryID>(primary_id, secondary_id)] = nnl;
247 }
248
249 return *nnl;
250}
251
254 const BoundaryName & secondary)
255{
256 const auto primary_id = _mesh.getBoundaryID(primary);
257 const auto secondary_id = _mesh.getBoundaryID(secondary);
258
260 _subproblem.addGhostedBoundary(secondary_id);
261
262 return getQuadratureNearestNodeLocator(primary_id, secondary_id);
263}
264
267 const BoundaryID secondary_id)
268{
269 // Generate a new boundary id (we use the negative numbers and subtract 1 to disambiguate id=0)
270 const auto qsecondary_id = -secondary_id - 1;
271
272 _secondary_to_qsecondary[secondary_id] = qsecondary_id;
273 return getNearestNodeLocator(primary_id, qsecondary_id);
274}
275
276void
278 const BoundaryID qsecondary_id,
279 bool reiniting)
280{
281 // Have we already generated quadrature nodes for this boundary id?
282 if (_quadrature_boundaries.find(secondary_id) != _quadrature_boundaries.end())
283 {
284 if (!reiniting)
285 return;
286 }
287 else
288 _quadrature_boundaries.insert(secondary_id);
289
290 const MooseArray<Point> & points_face = _subproblem.assembly(0, 0).qPointsFace();
291
293 for (const auto & belem : range)
294 {
295 const Elem * elem = belem->_elem;
296 const auto side = belem->_side;
297 const auto boundary_id = belem->_bnd_id;
298
299 if (elem->processor_id() == _subproblem.processor_id())
300 {
301 if (boundary_id == (BoundaryID)secondary_id)
302 {
303 // All we should need to do here is reinit the underlying libMesh::FE object because that
304 // will get us the correct points for the current element and side
306 _subproblem.assembly(0, 0).reinit(elem, side);
307
308 for (const auto qp : index_range(points_face))
309 _mesh.addQuadratureNode(elem, side, qp, qsecondary_id, points_face[qp]);
310 }
311 }
312 }
313}
314
315void
317 std::shared_ptr<ElementPairLocator> epl)
318{
319 _element_pair_locators[interface_id] = epl;
320}
321
322void
324{
325 if (state != _search_using_point_locator)
326 {
327 for (auto & [key, val] : _penetration_locators)
328 {
329 libmesh_ignore(key);
330 if (val)
331 val->setUsePointLocator(state);
332 }
333 }
334
336}
337
338void
340{
341 const MooseArray<Point> & points_face = _subproblem.assembly(0, 0).qPointsFace();
342
344 for (const auto & belem : range)
345 {
346 const Elem * elem = belem->_elem;
347 const auto side = belem->_side;
348 const auto boundary_id = belem->_bnd_id;
349
350 if (elem->processor_id() == _subproblem.processor_id())
351 {
352 if (boundary_id == (BoundaryID)secondary_id)
353 {
354 // All we should need to do here is reinit the underlying libMesh::FE object because that
355 // will get us the correct points for the current element and side
357 _subproblem.assembly(0, 0).reinit(elem, side);
358
359 for (const auto qp : index_range(points_face))
360 (*_mesh.getQuadratureNode(elem, side, qp)) = points_face[qp];
361 }
362 }
363 }
364}
365
366void
368{
369 // Regenerate the quadrature nodes
370 for (const auto & it : _secondary_to_qsecondary)
371 generateQuadratureNodes(it.first, it.second, /*reiniting=*/true);
372}
373
374void
376{
377 for (const auto & nnl_it : _nearest_node_locators)
378 {
379 NearestNodeLocator * nnl = nnl_it.second;
380 nnl->updateGhostedElems();
381 }
382}
boundary_id_type BoundaryID
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
void reinit(const Elem *elem)
Reinitialize objects (JxW, q_points, ...) for an elements.
Definition Assembly.C:1821
const MooseArray< Point > & qPointsFace() const
Returns the reference to the current quadrature being used.
Definition Assembly.h:345
This is the ElementPairLocator class.
void reinit()
Completely redo all geometric search objects.
NearestNodeLocator & getNearestNodeLocator(const BoundaryName &primary, const BoundaryName &secondary)
GeometricSearchType
Used to select groups of geometric search objects to update.
void addElementPairLocator(BoundaryID interface_id, std::shared_ptr< ElementPairLocator > epl)
bool _first
Denotes whether this is the first time the geometric search objects have been updated.
void reinitQuadratureNodes(const BoundaryID secondary_id)
Completely redo quadrature nodes.
std::map< std::pair< BoundaryID, BoundaryID >, NearestNodeLocator * > _nearest_node_locators
void clearNearestNodeLocators()
Clear out the Penetration Locators so they will redo the search.
std::map< BoundaryID, std::shared_ptr< ElementPairLocator > > _element_pair_locators
std::set< BoundaryID > _quadrature_boundaries
These are real boundaries that have quadrature nodes on them.
void updateGhostedElems()
Updates the list of ghosted elements at the start of each time step for the nonlinear iteration patch...
std::map< std::pair< BoundaryID, BoundaryID >, PenetrationLocator * > _penetration_locators
bool _search_using_point_locator
Denotes whether the PenetrationLocator objects should use a point locator rather than cheaper node-to...
NearestNodeLocator & getQuadratureNearestNodeLocator(const BoundaryName &primary, const BoundaryName &secondary)
void updateQuadratureNodes(const BoundaryID secondary_id)
Update the positions of the quadrature nodes.
GeometricSearchData(SubProblem &subproblem, MooseMesh &mesh)
void update(GeometricSearchType type=ALL)
Update all of the search objects.
PenetrationLocator & getPenetrationLocator(const BoundaryName &primary, const BoundaryName &secondary, libMesh::Order order=libMesh::FIRST)
std::map< BoundaryID, BoundaryID > _secondary_to_qsecondary
A mapping of the real boundary id to the secondary boundary ids.
Real maxPatchPercentage()
Maximum percentage through the search patch that any NearestNodeLocator had to look.
void generateQuadratureNodes(const BoundaryID secondary_id, const BoundaryID qsecondary_id, bool reiniting=false)
Add Quadrature Nodes to the Mesh in support of Quadrature based penetration location and nearest node...
void setSearchUsingPointLocator(bool state)
PenetrationLocator & getQuadraturePenetrationLocator(const BoundaryName &primary, const BoundaryName &secondary, libMesh::Order order=libMesh::FIRST)
forward declarations
Definition MooseArray.h:18
MooseMesh wraps a libMesh::Mesh object and enhances its capabilities by caching additional data and s...
Definition MooseMesh.h:95
Node * getQuadratureNode(const Elem *elem, const unsigned short int side, const unsigned int qp)
Get a specified quadrature node.
Definition MooseMesh.C:1649
void clearQuadratureNodes()
Clear out any existing quadrature nodes.
Definition MooseMesh.C:1667
const std::set< BoundaryID > & meshNodesetIds() const
Returns a read-only reference to the set of nodesets currently present in the Mesh.
Definition MooseMesh.C:3290
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
Get the associated BoundaryID for the boundary name.
Definition MooseMesh.C:1681
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:1600
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement * > * getBoundaryElementRange()
Definition MooseMesh.C:1298
Finds the nearest node to each node in boundary1 to each node in boundary2 and the other way around.
void reinit()
Completely redo the search from scratch.
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.
void setUsePointLocator(bool state)
void reinit()
Completely redo the search from scratch.
Generic class for solving transient nonlinear problems.
Definition SubProblem.h:79
virtual void setCurrentSubdomainID(const Elem *elem, const THREAD_ID tid)=0
virtual void addGhostedBoundary(BoundaryID boundary_id)=0
Will make sure that all necessary elements from boundary_id are ghosted to this processor.
virtual Assembly & assembly(const THREAD_ID tid, const unsigned int sys_num)=0
processor_id_type processor_id() const
MeshBase & mesh