69 _edge_extension_factor(getParam<Real>(
"edge_extension_factor")),
70 _nucleate_across_full_element(getParam<bool>(
"nucleate_across_full_element")),
71 _is_nucleation_length_provided(isParamValid(
"nucleation_length")),
72 _nucleation_length(_is_nucleation_length_provided ? getParam<Real>(
"nucleation_length") : 0),
73 _tensor(getMaterialProperty<
RankTwoTensor>(getParam<
std::string>(
"tensor"))),
74 _nucleation_threshold(coupledValue(
"nucleation_threshold")),
75 _scalar_type(getParam<
MooseEnum>(
"scalar_type")),
76 _point1(parameters.get<Point>(
"point1")),
77 _point2(parameters.get<Point>(
"point2")),
78 _JxW(_assembly.JxW()),
79 _coord(_assembly.coordTransformation())
85 std::pair<RealVectorValue, RealVectorValue> & cutterElemNodes)
87 bool does_it_crack =
false;
88 unsigned int numqp =
_qrule->n_points();
91 Real average_threshold = 0.0;
94 for (
unsigned int qp = 0; qp < numqp; ++qp)
97 mooseError(
"Threshold must be strictly positive in MeshCut2DRankTwoTensorNucleation");
105 if (point_dir.absolute_fuzzy_equals(zero))
106 mooseError(
"Cutter element has zero length in MeshCut2DRankTwoTensorNucleation");
108 if (tensor_quantity > average_threshold)
110 does_it_crack =
true;
113 Point crack_dir = point_dir.cross(Point(0, 0, 1));
116 std::unique_ptr<const Elem> edge;
117 Real circumference = 0;
121 circumference += edge->length(0, 1);
125 Real intersection_distance;
129 bool is_point_0_on_external_boundary =
false;
130 bool is_point_1_on_external_boundary =
false;
134 const auto & edge0 = edge->point(0);
135 const auto & edge1 = edge->point(1);
137 elem_center, -crack_dir, circumference, edge0, edge1, point_0, intersection_distance))
138 is_point_0_on_external_boundary = (
_current_elem->neighbor_ptr(e) ==
nullptr);
145 intersection_distance))
146 is_point_1_on_external_boundary = (
_current_elem->neighbor_ptr(e) ==
nullptr);
154 Real traverse_length = (point_0 - point_1).norm();
160 "Trying to nucleate crack smaller than element length, increase nucleation_length.\n "
161 "Location of crack being nucleated: ",
163 "\n nucleation_length: ",
165 "\n Length to traverse element: ",
167 "\n This error can be suppressed by setting nucleate_across_full_element=True which "
168 "will nucleate a crack the size of the element.");
175 point_0 = point_0 - extend_length * crack_dir.unit();
176 point_1 = point_1 + extend_length * crack_dir.unit();
180 if (is_point_0_on_external_boundary)
183 point_0 = point_0 + extend_length * crack_dir.unit();
187 point_1 = point_1 + extend_length * crack_dir.unit();
189 else if (is_point_1_on_external_boundary)
191 point_1 = point_1 - extend_length * crack_dir.unit();
193 point_0 = point_0 - extend_length * crack_dir.unit();
195 cutterElemNodes = {point_0, point_1};
198 return does_it_crack;
203 const Point & direction,
207 Point & intersection_point,
208 Real & intersection_distance)
211 const Real TRACE_TOLERANCE = 1e-5;
213 const auto r = direction * length;
214 const auto s = v1 - v0;
215 const auto rxs = r(0) * s(1) - r(1) * s(0);
218 if (std::abs(rxs) < TRACE_TOLERANCE)
221 const auto v0mu0 = v0 - start;
222 const auto t = (v0mu0(0) * s(1) - v0mu0(1) * s(0)) / rxs;
223 if (0 >= t + TRACE_TOLERANCE || t - TRACE_TOLERANCE > 1.0)
228 const auto u = (v0mu0(0) * r(1) - v0mu0(1) * r(0)) / rxs;
229 if (0 < u + TRACE_TOLERANCE && u - TRACE_TOLERANCE <= 1.0)
231 intersection_point = start + r * t;
232 intersection_distance = t * length;