void CrackFrontDefinition::calculateRThetaToCrackFront(const Point qp, const unsigned int node_index, Real & r, Real & theta) const { unsigned int num_nodes(_ordered_crack_front_nodes.size()); Point p = qp; // Loop over nodes to find the two crack front nodes closest to the point qp Real mindist1(1.0e30); Real mindist2(1.0e30); Point closest_node1(0.0); Point closest_node2(0.0); for (unsigned int nit = 0; nit != num_nodes; ++nit) { Node & crack_front_node = _mesh.node(_ordered_crack_front_nodes[nit]); RealVectorValue crack_node_to_current_node = p - crack_front_node; Real dist = crack_node_to_current_node.size(); if (dist < mindist1) { mindist2 = mindist1; closest_node2 = closest_node1; mindist1 = dist; closest_node1 = crack_front_node; } else if (dist < mindist2 && dist != mindist1) { mindist2 = dist; closest_node2 = crack_front_node; } } //Rotate coordinates to crack front coordinate system closest_node1 = rotateToCrackFrontCoords(closest_node1,node_index); closest_node2 = rotateToCrackFrontCoords(closest_node2,node_index); if (closest_node1(2) > closest_node2(2)) { RealVectorValue tmp = closest_node2; closest_node2 = closest_node1; closest_node1 = tmp; } p = rotateToCrackFrontCoords(p,node_index); //Find r, the distance between the qp and the crack front RealVectorValue crack_front_edge = closest_node2 - closest_node1; Real edge_length_sq = crack_front_edge.size_sq(); RealVectorValue closest_node1_to_p = p - closest_node1; Real perp = crack_front_edge * closest_node1_to_p; Real dist_along_edge = perp / edge_length_sq; RealVectorValue point_on_edge = closest_node1 + crack_front_edge * dist_along_edge; RealVectorValue r_vec = p - point_on_edge; r = r_vec.size(); //Find theta, the angle between r and the crack front plane RealVectorValue crack_plane_normal = rotateToCrackFrontCoords(_crack_plane_normal,node_index); Real p_to_plane_dist = std::abs(closest_node1_to_p*crack_plane_normal); //Determine if p is above or below the crack plane Real y_local = p(1) - closest_node1(1); //Determine if p is in front of or behind the crack front RealVectorValue p2(p); p2(1) = 0; RealVectorValue p2_vec = p2 - closest_node1; Real ahead = crack_front_edge(2) * p2_vec(0) - crack_front_edge(0) * p2_vec(2); Real x_local(0); if (ahead >= 0) x_local = 1; else x_local = -1; //Calculate theta based on in which quadrant in the crack front coordinate //system the qp is located if (x_local >= 0 && y_local >= 0) theta = std::asin(p_to_plane_dist/r); else if (x_local < 0 && y_local >= 0) theta = libMesh::pi - std::asin(p_to_plane_dist/r); else if (x_local < 0 && y_local < 0) theta = -(libMesh::pi - std::asin(p_to_plane_dist/r)); else if (x_local >= 0 && y_local < 0) theta = -std::asin(p_to_plane_dist/r); }
void CrackFrontDefinition::calculateRThetaToCrackFront(const Point qp, const unsigned int node_index, Real & r, Real & theta) const { unsigned int num_nodes(_ordered_crack_front_nodes.size()); Point p = qp; Point closest_node(0.0); RealVectorValue closest_node_to_p; Node & crack_tip_node = _mesh.node(_ordered_crack_front_nodes[node_index]); RealVectorValue crack_tip_node_rot = rotateToCrackFrontCoords(crack_tip_node,node_index); RealVectorValue crack_front_edge = rotateToCrackFrontCoords(_tangent_directions[node_index],node_index); Point p_rot = rotateToCrackFrontCoords(p,node_index); p_rot = p_rot - crack_tip_node_rot; if (_treat_as_2d) { closest_node = crack_tip_node_rot; closest_node_to_p = p_rot; //Find r, the distance between the qp and the crack front RealVectorValue r_vec = p_rot; r = r_vec.size(); } else { // Loop over crack front nodes to find the one closest to the point qp Real min_dist = std::numeric_limits<Real>::max(); for (unsigned int nit = 0; nit != num_nodes; ++nit) { Node & crack_front_node = _mesh.node(_ordered_crack_front_nodes[nit]); RealVectorValue crack_node_to_current_node = p - crack_front_node; Real dist = crack_node_to_current_node.size(); if (dist < min_dist) { min_dist = dist; closest_node = crack_front_node; } } //Rotate coordinates to crack front coordinate system closest_node = rotateToCrackFrontCoords(closest_node,node_index); closest_node = closest_node - crack_tip_node_rot; //Find r, the distance between the qp and the crack front Real edge_length_sq = crack_front_edge.size_sq(); closest_node_to_p = p_rot - closest_node; Real perp = crack_front_edge * closest_node_to_p; Real dist_along_edge = perp / edge_length_sq; RealVectorValue point_on_edge = closest_node + crack_front_edge * dist_along_edge; RealVectorValue r_vec = p_rot - point_on_edge; r = r_vec.size(); } //Find theta, the angle between r and the crack front plane RealVectorValue crack_plane_normal = rotateToCrackFrontCoords(_crack_plane_normal,node_index); Real p_to_plane_dist = std::abs(closest_node_to_p*crack_plane_normal); //Determine if p is above or below the crack plane Real y_local = p_rot(1) - closest_node(1); //Determine if p is in front of or behind the crack front RealVectorValue p2(p_rot); p2(1) = 0; RealVectorValue p2_vec = p2 - closest_node; Real ahead = crack_front_edge(2) * p2_vec(0) - crack_front_edge(0) * p2_vec(2); Real x_local(0); if (ahead >= 0) x_local = 1; else x_local = -1; //Calculate theta based on in which quadrant in the crack front coordinate //system the qp is located if (x_local >= 0 && y_local >= 0) theta = std::asin(p_to_plane_dist/r); else if (x_local < 0 && y_local >= 0) theta = libMesh::pi - std::asin(p_to_plane_dist/r); else if (x_local < 0 && y_local < 0) theta = -(libMesh::pi - std::asin(p_to_plane_dist/r)); else if (x_local >= 0 && y_local < 0) theta = -std::asin(p_to_plane_dist/r); }