102 for (
const auto & node_id : range)
113 std::vector<PenetrationInfo *> p_info;
114 bool info_set(
false);
124 const Point contact_ref =
info->_closest_point_ref;
125 bool contact_point_on_side(
false);
129 std::vector<Point> points(1);
130 points[0] = contact_ref;
131 const std::vector<Point> & secondary_pos = fe_side->get_xyz();
140 contact_point_on_side);
143 info->_closest_point_ref = contact_ref;
146 info->_distance = 0.0;
151 Real old_tangential_distance(
info->_tangential_distance);
152 bool contact_point_on_side(
false);
161 contact_point_on_side);
163 if (contact_point_on_side)
165 if (
info->_tangential_distance <= 0.0)
169 else if (
info->_tangential_distance > 0.0 && old_tangential_distance > 0.0)
171 if (
info->_side->dim() == 2 &&
info->_off_edge_nodes.size() < 2)
189 "Missing entry in node to elem map");
190 const std::vector<dof_id_type> & closest_elems = node_to_elem_pair->second;
192 for (
const auto & elem_id : closest_elems)
196 std::vector<PenetrationInfo *> thisElemInfo;
197 std::vector<const Node *> nodesThatMustBeOnSide;
198 nodesThatMustBeOnSide.push_back(closest_node);
203 if (p_info.size() == 1)
211 else if (p_info.size() > 1)
215 std::vector<RidgeData> ridgeDataVec;
216 for (
unsigned int i = 0; i + 1 < p_info.size(); ++i)
217 for (
unsigned int j = i + 1; j < p_info.size(); ++j)
220 Real tangential_distance(0.0);
221 const Node * closest_node_on_ridge = NULL;
222 unsigned int index = 0;
223 Point closest_coor_ref;
226 closest_node_on_ridge,
232 if (found_ridge_contact_point)
235 rpd._closest_coor = closest_coor;
236 rpd._tangential_distance = tangential_distance;
237 rpd._closest_node = closest_node_on_ridge;
239 rpd._closest_coor_ref = closest_coor_ref;
240 ridgeDataVec.push_back(rpd);
244 if (ridgeDataVec.size() > 0)
248 std::vector<RidgeSetData> ridgeSetDataVec;
249 for (
unsigned int i = 0; i < ridgeDataVec.size(); ++i)
251 bool foundSetWithMatchingNode =
false;
252 for (
unsigned int j = 0; j < ridgeSetDataVec.size(); ++j)
254 if (ridgeDataVec[i]._closest_node != NULL &&
255 ridgeDataVec[i]._closest_node == ridgeSetDataVec[j]._closest_node)
257 foundSetWithMatchingNode =
true;
258 ridgeSetDataVec[j]._ridge_data_vec.push_back(ridgeDataVec[i]);
262 if (!foundSetWithMatchingNode)
266 rsd._ridge_data_vec.push_back(ridgeDataVec[i]);
267 rsd._closest_node = ridgeDataVec[i]._closest_node;
268 ridgeSetDataVec.push_back(rsd);
272 for (
unsigned int i = 0; i < ridgeSetDataVec.size(); ++i)
274 if (ridgeSetDataVec[i]._closest_node !=
277 if (ridgeSetDataVec[i]._ridge_data_vec.size() == 1)
279 if (ridgeSetDataVec[i]._ridge_data_vec[0]._tangential_distance <=
282 ridgeSetDataVec[i]._closest_coor =
283 ridgeSetDataVec[i]._ridge_data_vec[0]._closest_coor;
284 Point contact_point_vec = node - ridgeSetDataVec[i]._closest_coor;
285 ridgeSetDataVec[i]._distance = contact_point_vec.norm();
291 ridgeSetDataVec[i]._closest_coor = *ridgeSetDataVec[i]._closest_node;
292 Point contact_point_vec = node - ridgeSetDataVec[i]._closest_coor;
293 ridgeSetDataVec[i]._distance = contact_point_vec.norm();
298 ridgeSetDataVec[i]._closest_coor =
299 ridgeSetDataVec[i]._ridge_data_vec[0]._closest_coor;
300 Point contact_point_vec = node - ridgeSetDataVec[i]._closest_coor;
301 ridgeSetDataVec[i]._distance = contact_point_vec.norm();
305 unsigned int closest_ridge_set_index(0);
306 Real closest_distance(ridgeSetDataVec[0]._distance);
307 Point closest_point(ridgeSetDataVec[0]._closest_coor);
308 for (
unsigned int i = 1; i < ridgeSetDataVec.size(); ++i)
310 if (ridgeSetDataVec[i]._distance < closest_distance)
312 closest_ridge_set_index = i;
313 closest_distance = ridgeSetDataVec[i]._distance;
314 closest_point = ridgeSetDataVec[i]._closest_coor;
318 if (closest_distance <
324 for (
unsigned int i = 0;
325 i < ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec.size();
328 if (ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[i]._index < face_index)
329 face_index = ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[i]._index;
333 "face_index invalid");
335 p_info[face_index]->_closest_point = closest_point;
336 p_info[face_index]->_distance =
337 (p_info[face_index]->_distance >= 0.0 ? 1.0 : -1.0) * closest_distance;
343 Point normal(closest_point - node);
344 const Real len(normal.norm());
349 const Real dot(normal * p_info[face_index]->_normal);
354 p_info[face_index]->_normal = normal;
356 p_info[face_index]->_tangential_distance = 0.0;
358 Point closest_point_ref;
359 if (ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec.size() ==
362 p_info[face_index]->_tangential_distance =
363 ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[0]._tangential_distance;
364 p_info[face_index]->_closest_point_ref =
365 ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[0]._closest_coor_ref;
369 const Node * closest_node_on_face;
371 closest_node_on_face,
372 p_info[face_index]->_side);
375 if (closest_node_on_face != ridgeSetDataVec[closest_ridge_set_index]._closest_node)
377 mooseError(
"Closest node when restricting point to face != closest node from " 384 std::vector<Point> points(1);
385 points[0] = p_info[face_index]->_closest_point_ref;
386 fe->reinit(p_info[face_index]->_side, &points);
387 p_info[face_index]->_side_phi = fe->get_phi();
388 p_info[face_index]->_side_grad_phi = fe->get_dphi();
389 p_info[face_index]->_dxyzdxi = fe->get_dxyzdxi();
390 p_info[face_index]->_dxyzdeta = fe->get_dxyzdeta();
391 p_info[face_index]->_d2xyzdxideta = fe->get_d2xyzdxideta();
403 unsigned int best(0), i(1);
421 }
while (i < p_info.size() && best < p_info.size());
422 if (best < p_info.size())
450 for (
unsigned int j = 0; j < p_info.size(); ++j)
MooseVariable * _nodal_normal_z
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...
Data structure used to hold penetration information.
NearestNodeLocator & _nearest_node
bool _check_whether_reasonable
bool findRidgeContactPoint(Point &contact_point, Real &tangential_distance, const Node *&closest_node, unsigned int &index, Point &contact_point_ref, std::vector< PenetrationInfo *> &p_info, const unsigned int index1, const unsigned int index2)
void createInfoForElem(std::vector< PenetrationInfo *> &thisElemInfo, std::vector< PenetrationInfo *> &p_info, const Node *secondary_node, const Elem *elem, const std::vector< const Node *> &nodes_that_must_be_on_side, const bool check_whether_reasonable=false)
bool restrictPointToFace(Point &p, const Node *&closest_node, const Elem *side)
Threads::spin_mutex pinfo_mutex
virtual const Node & nodeRef(const dof_id_type i) const
void smoothNormal(PenetrationInfo *info, std::vector< PenetrationInfo *> &p_info, const Node &node)
auto max(const L &left, const R &right)
std::vector< std::vector< FEBase * > > & _fes
void findContactPoint(PenetrationInfo &p_info, FEBase *fe_elem, FEBase *fe_side, FEType &fe_side_type, const Point &secondary_point, bool start_with_centroid, const Real tangential_tolerance, bool &contact_point_on_side)
Finds the closest point (called the contact point) on the primary_elem on side "side" to the secondar...
CompeteInteractionResult competeInteractions(PenetrationInfo *pi1, PenetrationInfo *pi2)
When interactions are identified between a node and two faces, compete between the faces to determine...
std::vector< dof_id_type > _recheck_secondary_nodes
List of secondary nodes for which penetration was not detected in the current patch and for which pat...
virtual MooseVariable & getStandardVariable(const THREAD_ID tid, const std::string &var_name)=0
Returns the variable reference for requested MooseVariable which may be in any system.
FEGenericBase< Real > FEBase
Real _tangential_tolerance
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
std::map< dof_id_type, PenetrationInfo * > & _penetration_info
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...
MooseVariable * _nodal_normal_y
bool _do_normal_smoothing
void computeSlip(FEBase &fe, PenetrationInfo &info)
const std::map< dof_id_type, std::vector< dof_id_type > > & _node_to_elem_map
void switchInfo(PenetrationInfo *&info, PenetrationInfo *&infoNew)
MooseVariable * _nodal_normal_x
PenetrationLocator::NORMAL_SMOOTHING_METHOD _normal_smoothing_method