104 for (
const auto & node_id : range)
115 std::vector<PenetrationInfo *> p_info;
116 bool info_set(
false);
126 const Point contact_ref =
info->_closest_point_ref;
127 bool contact_point_on_side(
false);
131 std::vector<Point> points(1);
132 points[0] = contact_ref;
133 const std::vector<Point> & secondary_pos = fe_side->
get_xyz();
134 bool search_succeeded =
false;
143 contact_point_on_side,
147 info->_closest_point_ref = contact_ref;
150 info->_distance = 0.0;
155 Real old_tangential_distance(
info->_tangential_distance);
156 bool contact_point_on_side(
false);
157 bool search_succeeded =
false;
166 contact_point_on_side,
169 if (contact_point_on_side)
171 if (
info->_tangential_distance <= 0.0)
175 else if (
info->_tangential_distance > 0.0 && old_tangential_distance > 0.0)
177 if (
info->_side->dim() == 2 &&
info->_off_edge_nodes.size() < 2)
195 "Missing entry in node to elem map");
196 const std::vector<dof_id_type> & closest_elems = node_to_elem_pair->second;
198 for (
const auto & elem_id : closest_elems)
202 std::vector<PenetrationInfo *> thisElemInfo;
203 std::vector<const Node *> nodesThatMustBeOnSide;
204 nodesThatMustBeOnSide.push_back(closest_node);
209 if (p_info.size() == 1)
217 else if (p_info.size() > 1)
221 std::vector<RidgeData> ridgeDataVec;
222 for (
unsigned int i = 0; i + 1 < p_info.size(); ++i)
223 for (
unsigned int j = i + 1; j < p_info.size(); ++j)
226 Real tangential_distance(0.0);
227 const Node * closest_node_on_ridge = NULL;
228 unsigned int index = 0;
229 Point closest_coor_ref;
232 closest_node_on_ridge,
238 if (found_ridge_contact_point)
241 rpd._closest_coor = closest_coor;
242 rpd._tangential_distance = tangential_distance;
243 rpd._closest_node = closest_node_on_ridge;
245 rpd._closest_coor_ref = closest_coor_ref;
246 ridgeDataVec.push_back(rpd);
250 if (ridgeDataVec.size() > 0)
254 std::vector<RidgeSetData> ridgeSetDataVec;
255 for (
unsigned int i = 0; i < ridgeDataVec.size(); ++i)
257 bool foundSetWithMatchingNode =
false;
258 for (
unsigned int j = 0; j < ridgeSetDataVec.size(); ++j)
260 if (ridgeDataVec[i]._closest_node != NULL &&
261 ridgeDataVec[i]._closest_node == ridgeSetDataVec[j]._closest_node)
263 foundSetWithMatchingNode =
true;
264 ridgeSetDataVec[j]._ridge_data_vec.push_back(ridgeDataVec[i]);
268 if (!foundSetWithMatchingNode)
272 rsd._ridge_data_vec.push_back(ridgeDataVec[i]);
273 rsd._closest_node = ridgeDataVec[i]._closest_node;
274 ridgeSetDataVec.push_back(rsd);
278 for (
unsigned int i = 0; i < ridgeSetDataVec.size(); ++i)
280 if (ridgeSetDataVec[i]._closest_node !=
283 if (ridgeSetDataVec[i]._ridge_data_vec.size() == 1)
285 if (ridgeSetDataVec[i]._ridge_data_vec[0]._tangential_distance <=
288 ridgeSetDataVec[i]._closest_coor =
289 ridgeSetDataVec[i]._ridge_data_vec[0]._closest_coor;
290 Point contact_point_vec = node - ridgeSetDataVec[i]._closest_coor;
291 ridgeSetDataVec[i]._distance = contact_point_vec.
norm();
297 ridgeSetDataVec[i]._closest_coor = *ridgeSetDataVec[i]._closest_node;
298 Point contact_point_vec = node - ridgeSetDataVec[i]._closest_coor;
299 ridgeSetDataVec[i]._distance = contact_point_vec.
norm();
304 ridgeSetDataVec[i]._closest_coor =
305 ridgeSetDataVec[i]._ridge_data_vec[0]._closest_coor;
306 Point contact_point_vec = node - ridgeSetDataVec[i]._closest_coor;
307 ridgeSetDataVec[i]._distance = contact_point_vec.
norm();
311 unsigned int closest_ridge_set_index(0);
312 Real closest_distance(ridgeSetDataVec[0]._distance);
313 Point closest_point(ridgeSetDataVec[0]._closest_coor);
314 for (
unsigned int i = 1; i < ridgeSetDataVec.size(); ++i)
316 if (ridgeSetDataVec[i]._distance < closest_distance)
318 closest_ridge_set_index = i;
319 closest_distance = ridgeSetDataVec[i]._distance;
320 closest_point = ridgeSetDataVec[i]._closest_coor;
324 if (closest_distance <
330 for (
unsigned int i = 0;
331 i < ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec.size();
334 if (ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[i]._index < face_index)
335 face_index = ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[i]._index;
339 "face_index invalid");
341 p_info[face_index]->_closest_point = closest_point;
342 p_info[face_index]->_distance =
343 (p_info[face_index]->_distance >= 0.0 ? 1.0 : -1.0) * closest_distance;
349 Point normal(closest_point - node);
350 const Real len(normal.norm());
355 const Real dot(normal * p_info[face_index]->_normal);
360 p_info[face_index]->_normal = normal;
362 p_info[face_index]->_tangential_distance = 0.0;
364 Point closest_point_ref;
365 if (ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec.size() ==
368 p_info[face_index]->_tangential_distance =
369 ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[0]._tangential_distance;
370 p_info[face_index]->_closest_point_ref =
371 ridgeSetDataVec[closest_ridge_set_index]._ridge_data_vec[0]._closest_coor_ref;
375 const Node * closest_node_on_face;
377 closest_node_on_face,
378 p_info[face_index]->_side);
381 if (closest_node_on_face != ridgeSetDataVec[closest_ridge_set_index]._closest_node)
383 mooseError(
"Closest node when restricting point to face != closest node from " 390 std::vector<Point> points(1);
391 points[0] = p_info[face_index]->_closest_point_ref;
392 fe->
reinit(p_info[face_index]->_side, &points);
393 p_info[face_index]->_side_phi = fe->
get_phi();
394 p_info[face_index]->_side_grad_phi = fe->
get_dphi();
409 unsigned int best(0), i(1);
427 }
while (i < p_info.size() && best < p_info.size());
428 if (best < p_info.size())
460 for (
unsigned int j = 0; j < p_info.size(); ++j)
MooseVariable * _nodal_normal_z
auto norm() const -> decltype(std::norm(Real()))
virtual_for_inffe const std::vector< RealGradient > & get_dxyzdeta() const
virtual Elem * elemPtr(const dof_id_type i)
bool findRidgeContactPoint(libMesh::Point &contact_point, Real &tangential_distance, const Node *&closest_node, unsigned int &index, libMesh::Point &contact_point_ref, std::vector< PenetrationInfo *> &p_info, const unsigned int index1, const unsigned int index2)
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
virtual_for_inffe const std::vector< RealGradient > & get_d2xyzdxideta() const
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)
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)
libMesh::FEType & _fe_type
auto max(const L &left, const R &right)
const std::vector< std::vector< OutputGradient > > & get_dphi() const
CompeteInteractionResult competeInteractions(PenetrationInfo *pi1, PenetrationInfo *pi2)
When interactions are identified between a node and two faces, compete between the faces to determine...
void computeSlip(libMesh::FEBase &fe, PenetrationInfo &info)
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)=0
void findContactPoint(PenetrationInfo &p_info, libMesh::FEBase *fe_elem, libMesh::FEBase *fe_side, libMesh::FEType &fe_side_type, const libMesh::Point &secondary_point, bool start_with_centroid, const Real tangential_tolerance, bool &contact_point_on_side, bool &search_succeeded)
Finds the closest point (called the contact point) on the primary_elem on side "side" to the secondar...
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.
virtual_for_inffe const std::vector< Point > & get_xyz() const
Real _tangential_tolerance
bool restrictPointToFace(libMesh::Point &p, const Node *&closest_node, const Elem *side)
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
const std::map< dof_id_type, std::vector< dof_id_type > > & _node_to_elem_map
void switchInfo(PenetrationInfo *&info, PenetrationInfo *&infoNew)
virtual_for_inffe const std::vector< RealGradient > & get_dxyzdxi() const
MooseVariable * _nodal_normal_x
std::vector< std::vector< libMesh::FEBase * > > & _fes
PenetrationLocator::NORMAL_SMOOTHING_METHOD _normal_smoothing_method
const std::vector< std::vector< OutputShape > > & get_phi() const