14 #include "libmesh/string_to_enum.h" 17 #include "libmesh/face_tri3.h" 18 #include "libmesh/edge_edge2.h" 19 #include "libmesh/serial_mesh.h" 20 #include "libmesh/plane.h" 21 #include "libmesh/mesh_tools.h" 30 MooseEnum growthDirection(
"MAX_HOOP_STRESS FUNCTION",
"FUNCTION");
32 "growth_dir_method", growthDirection,
"choose from FUNCTION, MAX_HOOP_STRESS");
33 MooseEnum growthRate(
"REPORTER FUNCTION",
"FUNCTION");
35 "growth_increment_method", growthRate,
"choose from FUNCTION, REPORTER");
36 params.
addParam<FunctionName>(
"growth_direction_x",
37 "Function defining x-component of crack growth direction");
38 params.
addParam<FunctionName>(
"growth_direction_y",
39 "Function defining y-component of crack growth direction");
40 params.
addParam<FunctionName>(
"growth_direction_z",
41 "Function defining z-component of crack growth direction");
43 params.
addParam<VectorPostprocessorName>(
44 "ki_vectorpostprocessor",
"II_KI_1",
"Name of the VectorPostprocessor that computes K_I");
45 params.
addParam<VectorPostprocessorName>(
"kii_vectorpostprocessor",
47 "The name of the vectorpostprocessor that contains KII");
49 "The name of the Reporter that computes the growth increment");
50 params.
addParam<FunctionName>(
"growth_rate",
"Function defining crack growth rate");
52 "size_control", 0,
"Criterion for refining elements while growing the crack");
53 params.
addParam<
unsigned int>(
"n_step_growth", 0,
"Number of steps for crack growth");
54 params.
addParam<std::vector<dof_id_type>>(
"crack_front_nodes",
55 "Set of nodes to define crack front");
64 _mesh(_subproblem.
mesh()),
66 _growth_increment_method(
68 _n_step_growth(getParam<unsigned
int>(
"n_step_growth")),
69 _is_mesh_modified(false),
70 _func_x(parameters.isParamValid(
"growth_direction_x") ? &getFunction(
"growth_direction_x")
72 _func_y(parameters.isParamValid(
"growth_direction_y") ? &getFunction(
"growth_direction_y")
74 _func_z(parameters.isParamValid(
"growth_direction_z") ? &getFunction(
"growth_direction_z")
76 _func_v(parameters.isParamValid(
"growth_rate") ? &getFunction(
"growth_rate") : nullptr),
78 ? &getVectorPostprocessorValue(
79 "ki_vectorpostprocessor",
80 getParam<VectorPostprocessorName>(
"ki_vectorpostprocessor"))
83 ? &getVectorPostprocessorValue(
84 "kii_vectorpostprocessor",
85 getParam<VectorPostprocessorName>(
"kii_vectorpostprocessor"))
87 _growth_inc_reporter((_growth_increment_method ==
GrowthRateEnum::REPORTER)
88 ? &getReporterValueByName<
std::vector<
Real>>(
97 paramError(
"size_control",
"Crack growth needs size control.");
103 mooseError(
"function is not specified for the function method that defines growth direction");
120 "Required for any crack growth rate or direction criterion that requires fracture " 124 for (
const auto & cut_elem :
_cutter_mesh->element_ptr_range())
127 mooseError(
"The input cut mesh should include tri elements only!");
129 mooseError(
"The input cut mesh must be 2D elements only!");
188 std::vector<Xfem::CutEdge> & ,
189 std::vector<Xfem::CutNode> & )
const 191 mooseError(
"invalid method for 3D mesh cutting");
197 std::vector<Xfem::CutFace> & cut_faces)
const 202 bool elem_cut =
false;
204 if (elem->dim() != _elem_dim)
205 mooseError(
"The structural mesh to be cut by a surface mesh must be 3D!");
207 for (
unsigned int i = 0; i < elem->n_sides(); ++i)
210 std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
211 if (curr_side->dim() != 2)
212 mooseError(
"In cutElementByGeometry dimension of side must be 2, but it is ",
214 unsigned int n_edges = curr_side->n_sides();
216 std::vector<unsigned int> cut_edges;
217 std::vector<Real> cut_pos;
219 for (
unsigned int j = 0;
j < n_edges;
j++)
222 std::unique_ptr<const Elem> curr_edge = curr_side->side_ptr(
j);
223 if (curr_edge->type() !=
EDGE2)
224 mooseError(
"In cutElementByGeometry face edge must be EDGE2, but type is: ",
226 " base element type is: ",
228 const Node * node1 = curr_edge->node_ptr(0);
229 const Node * node2 = curr_edge->node_ptr(1);
231 for (
const auto & cut_elem : _cutter_mesh->element_ptr_range())
233 std::vector<Point> vertices;
235 for (
auto & node : cut_elem->node_ref_range())
237 Point & this_point = node;
238 vertices.push_back(this_point);
244 cut_edges.push_back(
j);
251 if (cut_edges.size() == 2)
260 cut_faces.push_back(mycut);
268 std::vector<Xfem::CutEdge> & )
const 270 mooseError(
"invalid method for 3D mesh cutting");
276 std::vector<Xfem::CutFace> & )
const 279 mooseError(
"cutFragmentByGeometry not yet implemented for 3D mesh cutting");
286 const std::vector<Point> & vertices,
289 bool has_intersection =
false;
291 Plane elem_plane(vertices[0], vertices[1], vertices[2]);
292 Point point = vertices[0];
293 Point normal = elem_plane.unit_normal(point);
295 std::array<Real, 3> plane_point = {{point(0), point(1), point(2)}};
296 std::array<Real, 3> planenormal = {{normal(0), normal(1), normal(2)}};
297 std::array<Real, 3> edge_point1 = {{p1(0), p1(1), p1(2)}};
298 std::array<Real, 3> edge_point2 = {{p2(0), p2(1), p2(2)}};
299 std::array<Real, 3> cut_point = {{0.0, 0.0, 0.0}};
302 &plane_point[0], &planenormal[0], &edge_point1[0], &edge_point2[0], &cut_point[0]) == 1)
304 Point temp_p(cut_point[0], cut_point[1], cut_point[2]);
308 has_intersection =
true;
311 return has_intersection;
317 const std::vector<Point> & vertices,
320 bool has_intersection =
false;
322 Plane elem_plane(vertices[0], vertices[1], vertices[2]);
323 Point point = vertices[0];
324 Point normal = elem_plane.unit_normal(point);
326 std::array<Real, 3> plane_point = {{point(0), point(1), point(2)}};
327 std::array<Real, 3> planenormal = {{normal(0), normal(1), normal(2)}};
328 std::array<Real, 3> p_begin = {{p1(0), p1(1), p1(2)}};
329 std::array<Real, 3> p_end = {{p2(0), p2(1), p2(2)}};
330 std::array<Real, 3> cut_point = {{0.0, 0.0, 0.0}};
333 &plane_point[0], &planenormal[0], &p_begin[0], &p_end[0], &cut_point[0]) == 1)
335 Point p(cut_point[0], cut_point[1], cut_point[2]);
336 Real dotp = ((p - p1) * (p2 - p1)) / ((p2 - p1) * (p2 - p1));
340 has_intersection =
true;
343 return has_intersection;
349 Real dotp1 = (p1 - p) * (p2 - p1);
350 Real dotp2 = (p2 - p) * (p2 - p1);
351 return (dotp1 * dotp2 <= 0.0);
357 const Point & p)
const 361 return len_p1_p / full_len;
366 const Point & p)
const 368 unsigned int n_node = vertices.size();
370 Plane elem_plane(vertices[0], vertices[1], vertices[2]);
371 Point normal = elem_plane.unit_normal(vertices[0]);
374 unsigned int counter = 0;
376 for (
unsigned int i = 0; i < n_node; ++i)
378 unsigned int iplus1 = (i < n_node - 1 ? i + 1 : 0);
379 Point middle2p = p - 0.5 * (vertices[i] + vertices[iplus1]);
380 const Point side_tang = vertices[iplus1] - vertices[i];
381 Point side_norm = side_tang.cross(normal);
384 if (middle2p * side_norm <= 0.0)
387 if (counter == n_node)
395 auto boundary_node_ids = MeshTools::find_boundary_nodes(*
_cutter_mesh);
396 for (
auto it = boundary_node_ids.cbegin(); it != boundary_node_ids.cend(); it++)
399 std::vector<dof_id_type> neighbors;
409 std::vector<dof_id_type> corner_elem_id;
410 unsigned int counter = 0;
415 for (
const auto & cut_elem :
_cutter_mesh->element_ptr_range())
419 node_id[i] = cut_elem->node_ptr(i)->id();
423 if (is_node_on_boundary[0] && is_node_on_boundary[1] && is_node_on_boundary[2])
427 corner_elem_id.push_back(counter);
435 if (is_node_on_boundary[i] && is_node_on_boundary[(i + 1 <= 2) ? i + 1 : 0])
438 dof_id_type node2 = node_id[(i + 1 <= 2) ? i + 1 : 0];
440 std::swap(node1, node2);
445 std::swap(node1, node2);
458 for (
unsigned int i = 0; i < corner_elem_id.size(); ++i)
464 Elem * cut_elem = *elem_it;
468 bool is_edge_inside = 0;
471 dof_id_type node2 = cut_elem->node_ptr((
j + 1 <= 2) ?
j + 1 : 0)->id();
473 std::swap(node1, node2);
475 unsigned int counter = 0;
476 for (
const auto & cut_elem2 :
_cutter_mesh->element_ptr_range())
478 if (counter != corner_elem_id[i])
483 dof_id_type node4 = cut_elem2->node_ptr((
k + 1 <= 2) ?
k + 1 : 0)->id();
485 std::swap(node3, node4);
487 if (node1 == node3 && node2 == node4)
497 if (is_edge_inside == 0)
503 std::swap(node1, node2);
514 if ((*it)._id1 == node1 && (*it)._id2 == node2)
535 "_boundary_map does not have this key");
537 "_boundary_map does not have this key");
546 if (it->second.size() != 2)
548 "Boundary nodes in the cutter mesh must have exactly two neighbors; this one has: ",
562 "_boundary_map does not have this key");
573 else if (node4 == node1)
580 mooseError(
"Discontinuity in cutter boundary");
588 mooseAssert(n1 !=
nullptr,
"Node is NULL");
590 mooseAssert(n2 !=
nullptr,
"Node is NULL");
600 mooseAssert(
_boundary.size() >= 2,
"Boundary must be at least two nodes");
602 for (
unsigned int i =
_boundary.size() - 1; i >= 1; --i)
612 std::array<Real, 3> x1;
613 std::array<Real, 3> x2;
616 mooseAssert(n1 !=
nullptr,
"Node is NULL");
619 mooseAssert(n2 !=
nullptr,
"Node is NULL");
622 for (
unsigned int j = 0;
j < 3; ++
j)
628 for (
unsigned int j = 0;
j < n; ++
j)
631 for (
unsigned int k = 0;
k < 3; ++
k)
632 x(
k) = x2[
k] - (x2[
k] - x1[
k]) * (
j + 1) / (n + 1);
634 Node * this_node = Node::build(
x,
_cutter_mesh->n_nodes()).release();
638 auto it = new_boundary_order.begin();
639 new_boundary_order.insert(it + i,
id);
645 mooseAssert(
_boundary.size() > 0,
"Boundary should not have zero size");
656 pl->enable_out_of_mesh_mode();
658 unsigned int n_boundary =
_boundary.size();
662 for (
unsigned int j = 0;
j < n_boundary; ++
j)
665 mooseAssert(this_node,
"Node is NULL");
666 Point & this_point = *this_node;
668 const Elem * elem = (*pl)(this_point);
676 if (n_inactive_boundary == n_boundary)
680 if (n_inactive_boundary == 0)
684 for (
unsigned int i = 0; i < n_inactive_boundary - 1; ++i)
688 std::vector<dof_id_type> temp;
699 std::vector<dof_id_type> temp;
713 "crack-front-definition using the cutter mesh only supports one active crack front " 720 std::vector<Point> temp;
725 for (
unsigned int j = 0;
j < 3; ++
j)
740 for (
unsigned int j = i1;
j < i2; ++
j)
743 mooseAssert(this_node,
"Node is NULL");
744 Point & this_point = *this_node;
754 mooseAssert(
_ki_vpp->size() ==
_kii_vpp->size(),
"KI and KII VPPs must be the same size");
756 "the number of crack front nodes in the self-similar method should equal to the " 757 "size of VPP defined at the crack front");
759 "the number of crack front nodes should be the same in _crack_front_points and " 760 "_active_boundary[0]");
766 for (
unsigned int j = i1;
j < i2; ++
j)
771 Real theta = 2 * std::atan((ki - std::sqrt(ki * ki + kii * kii)) / (4 * kii));
779 dir_cfc(0) = std::cos(theta);
780 dir_cfc(1) = std::sin(theta);
788 mooseError(
"This growth_dir_method is not pre-defined!");
792 for (
unsigned int j = 0;
j < 3; ++
j)
807 Real length = std::sqrt(pt * pt);
824 std::vector<dof_id_type> temp;
835 for (
unsigned int j = i1;
j < i2; ++
j)
838 mooseAssert(this_node,
"Node is NULL");
839 Point & this_point = *this_node;
843 Real growth_increment = 0;
855 growth_increment = 0;
862 mooseError(
"This growth_increment_method is not pre-defined!");
866 for (
unsigned int k = 0;
k < 3; ++
k)
867 x(
k) = this_point(
k) + dir(
k) * growth_increment;
869 this_node = Node::build(
x,
_cutter_mesh->n_nodes()).release();
903 for (
unsigned int i = 0; i <
_front.size(); ++i)
905 if (
_front[i].size() >= 2)
907 std::vector<Point> pint1;
908 std::vector<Point> pint2;
909 std::vector<Real> length1;
910 std::vector<Real> length2;
914 mooseAssert(this_node,
"Node is NULL");
915 Point & p2 = *this_node;
917 if (
_front[i].size() >= 4)
923 mooseAssert(this_node,
"Node is NULL");
924 Point & p1 = *this_node;
926 node_id =
_front[i].back();
928 mooseAssert(this_node,
"Node is NULL");
929 Point & p4 = *this_node;
931 if (
_front[i].size() >= 4)
937 mooseAssert(this_node,
"Node is NULL");
938 Point & p3 = *this_node;
944 pl->enable_out_of_mesh_mode();
945 const Elem * elem = (*pl)(p1);
952 for (
const auto & belem : range)
955 std::vector<Point> vertices;
958 std::unique_ptr<const Elem> curr_side = elem->side_ptr(belem->_side);
959 for (
unsigned int j = 0;
j < curr_side->n_nodes(); ++
j)
961 const Node * node = curr_side->node_ptr(
j);
962 const Point & this_point = *node;
963 vertices.push_back(this_point);
969 length1.push_back((pt - p1) * (pt - p1));
974 length2.push_back((pt - p3) * (pt - p3));
978 if (length1.size() != 0 && do_inter1)
980 auto it1 = std::min_element(length1.begin(), length1.end());
981 Point inter1 = pint1[std::distance(length1.begin(), it1)];
984 Node * this_node = Node::build(inter1,
_cutter_mesh->n_nodes()).release();
987 mooseAssert(
_cutter_mesh->n_nodes() - 1 > 0,
"The cut mesh must be at least one element.");
990 auto it =
_front[i].begin();
997 if (length2.size() != 0 && do_inter2)
999 auto it2 = std::min_element(length2.begin(), length2.end());
1000 Point inter2 = pint2[std::distance(length2.begin(), it2)];
1003 Node * this_node = Node::build(inter2,
_cutter_mesh->n_nodes()).release();
1008 auto it =
_front[i].begin();
1009 unsigned int m =
_front[i].size();
1010 _front[i].insert(it + m, n);
1022 std::vector<std::vector<dof_id_type>> new_front(
_front.begin(),
_front.end());
1024 for (
unsigned int ifront = 0; ifront <
_front.size(); ++ifront)
1026 unsigned int i1 =
_front[ifront].size() - 1;
1028 i1 =
_front[ifront].size();
1030 for (
unsigned int i = i1; i >= 1; --i)
1032 unsigned int i2 = i;
1034 i2 = (i <=
_front[ifront].size() - 1 ? i : 0);
1043 std::array<Real, 3> x1;
1044 std::array<Real, 3> x2;
1047 mooseAssert(this_node,
"Node is NULL");
1048 Point & p1 = *this_node;
1050 mooseAssert(this_node,
"Node is NULL");
1051 Point & p2 = *this_node;
1053 for (
unsigned int j = 0;
j < 3; ++
j)
1059 for (
unsigned int j = 0;
j < n; ++
j)
1062 for (
unsigned int k = 0;
k < 3; ++
k)
1063 x(
k) = x2[
k] - (x2[
k] - x1[
k]) * (
j + 1) / (n + 1);
1065 Node * this_node = Node::build(
x,
_cutter_mesh->n_nodes()).release();
1070 auto it = new_front[ifront].begin();
1071 new_front[ifront].insert(it + i,
id);
1091 mooseError(
"the crack front and the tracked crack front definition must match in terms of " 1092 "their end nodes\n _front[0][0]= " +
1095 "\n _tracked_crack_front_points.back()=" +
1108 "_active_boundary and _front must be the same size!");
1117 for (
unsigned int k = 0;
k <
_front.size(); ++
k)
1120 unsigned int n2 =
_front[
k].size();
1122 unsigned int i1 = 0;
1123 unsigned int i2 = 0;
1126 while (!(i1 == n1 - 1 && i2 == n2 - 1))
1128 std::vector<dof_id_type> elem;
1133 if (i1 != n1 - 1 && i2 != n2 - 1)
1157 else if (i1 == n1 - 1)
1167 else if (i2 == n2 - 1)
1177 Elem * new_elem = Elem::build(
TRI3).release();
1181 mooseAssert(
_cutter_mesh->node_ptr(elem[i]) !=
nullptr,
"Node is NULL");
1182 new_elem->set_node(i,
_cutter_mesh->node_ptr(elem[i]));
1200 std::vector<dof_id_type> full_front;
1204 for (
unsigned int i = 0; i < size1; ++i)
1211 full_front.insert(full_front.end(),
_front[i].begin(),
_front[i].end());
1214 unsigned int pos1 = std::distance(
_boundary.begin(), it1);
1216 unsigned int pos2 = std::distance(
_boundary.begin(), it2);
1219 full_front.insert(full_front.end(),
_boundary.begin() + pos1,
_boundary.begin() + pos2 + 1);
1223 full_front.insert(full_front.end(),
_boundary.begin(),
_boundary.begin() + pos2 + 1);
1230 const std::vector<Point>
1233 std::vector<Point> crack_front_points(number_crack_front_points);
1237 mooseError(
"Number of nodes in CrackFrontDefinition does not match the number of nodes in the " 1238 "cutter_mesh.\nCrackFrontDefinition nodes = " +
1242 for (
unsigned int i = 0; i < number_crack_front_points; ++i)
1246 mooseAssert(this_node,
"Node is NULL");
1247 Point & this_point = *this_node;
1248 crack_front_points[i] = this_point;
1250 return crack_front_points;
1253 const std::vector<RealVectorValue>
1256 std::vector<RealVectorValue> crack_plane_normals(number_crack_front_points);
1259 std::unordered_map<dof_id_type, std::vector<dof_id_type>> node_to_elems_map;
1260 node_to_elems_map.clear();
1261 for (
const auto & elem :
_cutter_mesh->element_ptr_range())
1262 for (
auto & node : elem->node_ref_range())
1263 node_to_elems_map[node.id()].push_back(elem->id());
1266 std::unordered_map<dof_id_type, RealVectorValue> elem_to_normal_map;
1267 elem_to_normal_map.clear();
1268 for (
const auto & elem :
_cutter_mesh->element_ptr_range())
1270 Point & p1 = *elem->node_ptr(0);
1271 Point & p2 = *elem->node_ptr(1);
1272 Point & p3 = *elem->node_ptr(2);
1273 Plane elem_plane(p3, p2, p1);
1275 elem_to_normal_map[elem->id()] = normal;
1281 for (
unsigned int i = 0; i < number_crack_front_points; ++i)
1284 std::vector<dof_id_type> elems = node_to_elems_map[id];
1285 unsigned int n_elem = elems.size();
1288 for (
unsigned int j = 0;
j <
n_elem; ++
j)
1289 normal_avr += elem_to_normal_map[elems[
j]];
1290 normal_avr = normal_avr /
n_elem;
1291 crack_plane_normals[i] = normal_avr;
1293 return crack_plane_normals;
1301 unsigned int ibnd = 0;
1305 std::vector<int> index(size_this_segment, -1);
1307 unsigned int i1 = n_inactive_nodes == 0 ? 0 : 1;
1308 unsigned int i2 = n_inactive_nodes == 0 ? size_this_segment : size_this_segment - 1;
1311 for (
unsigned int j = i1;
j < i2; ++
j)
void isCutterModified(const bool is_cutter_modified)
Set the value of _is_cutter_modified.
int _last_step_initialized
Time step information needed to advance a 3D crack only at the real beginning of a time step...
GrowthDirectionEnum
Enum to for crack growth direction.
CrackMeshCut3DUserObject: (1) reads in a mesh describing the crack surface, (2) uses the mesh to do i...
Real _size_control
Used for cutter mesh refinement and front advancement.
T & getUserObject(const std::string &name, unsigned int tid=0) const
void paramError(const std::string ¶m, Args... args) const
void findBoundaryNodes()
Find boundary nodes of the cutter mesh This is a simple algorithm simply based on the added angle = 3...
void mooseError(Args &&... args)
const unsigned int _cut_elem_nnode
The cutter mesh has triangluar elements only.
const ReporterMode REPORTER_MODE_ROOT
void findActiveBoundaryNodes()
Find all active boundary nodes in the cutter mesh Find boundary nodes that will grow; nodes outside o...
std::vector< int > getFrontPointsIndex() const
Get crack front points in the active segment -1 means inactive; positive is the point's index in the ...
unsigned int _n_step_growth
Number of steps to grow the mesh.
static InputParameters validParams()
bool findIntersection(const Point &p1, const Point &p2, const std::vector< Point > &vertices, Point &point) const
Find directional intersection along the positive extension of the vector from p1 to p2...
const GrowthDirectionEnum _growth_dir_method
The direction method for growing mesh at the front.
const GrowthRateEnum _growth_increment_method
The growth increment method for growing mesh at the front.
virtual bool cutFragmentByGeometry(std::vector< std::vector< Point >> &frag_edges, std::vector< Xfem::CutEdge > &cut_edges) const override
Real getRelativePosition(const Point &p1, const Point &p2, const Point &p) const
Get the relative position of p from p1.
std::vector< Real > _position
Fractional distance along the cut edges where the cut is located.
Real findDistance(dof_id_type node1, dof_id_type node2)
Find distance between two nodes.
std::map< dof_id_type, std::vector< dof_id_type > > _boundary_map
A map of boundary nodes and their neighbors.
const std::vector< Real > *const _ki_vpp
Pointer to fracture integral ki if available.
Real distance(const Point &p)
void growFront()
Grow the cutter mesh.
void updateNumberOfCrackFrontPoints(const std::size_t num_points)
Change the number of crack front nodes.
Data structure defining a cut through a face.
const Real _const_intersection
Used to define intersection points.
void findBoundaryEdges()
Find boundary edges of the cutter mesh.
void triangulation()
Create tri3 elements between the new front and the old front.
void refineFront()
Refine the mesh at the front.
Data structure defining a cut on an element edge.
std::vector< dof_id_type > _tracked_crack_front_points
Front nodes that are grown from the crack front definition defined in the input therefore, they are (1) in the same order as defined in the input and (2) the number of nodes does not change.
RealVectorValue rotateFromCrackFrontCoordsToGlobal(const RealVectorValue vector, const std::size_t point_index) const
Rotate a vector from crack front cartesian coordinate to global cartesian coordinate.
int plane_normal_line_exp_int_3d(double pp[3], double normal[3], double p1[3], double p2[3], double pint[3])
void sortFrontNodes()
Sort the front nodes.
Class used in fracture integrals to define geometric characteristics of the crack front...
std::vector< dof_id_type > _crack_front_points
updated crack front definition they are in the same order as defined in the input but the number of n...
Real getRelativePosition(const Point &p1, const Point &p2, const Point &p)
Get the relative position of p from p1 respect to the total length of the line segment.
void findFrontIntersection()
Find front-structure intersections.
const Function * _func_x
Parsed functions of front growth.
std::vector< std::vector< dof_id_type > > _front
New boundary after growth.
virtual void initialSetup() override
unsigned int _id1
ID of the first node on the edge.
const std::vector< double > x
registerMooseObject("XFEMApp", CrackMeshCut3DUserObject)
virtual const std::vector< Point > getCrackFrontPoints(unsigned int num_crack_front_points) const override
get a set of points along a crack front from a XFEM GeometricCutUserObject
bool intersectWithEdge(const Point &p1, const Point &p2, const std::vector< Point > &vertices, Point &pint)
check if a line intersects with an element defined by vertices calculate the distance from a point to...
unsigned int _num_crack_front_points
Total number of crack front points in the mesh cutter.
virtual bool cutElementByGeometry(const Elem *elem, std::vector< Xfem::CutEdge > &cut_edges, std::vector< Xfem::CutNode > &cut_nodes) const override
bool _is_mesh_modified
Indicator that shows if the cutting mesh is modified or not in this calculation step.
CrackMeshCut3DUserObject(const InputParameters ¶meters)
bool _stop
Variables to help control the work flow.
std::string stringify(const T &t)
const std::vector< Real > *const _kii_vpp
Pointer to fracture integral kii if available.
const unsigned int _cut_elem_dim
std::vector< unsigned int > _inactive_boundary_pos
Inactive boundary.
std::string enum_to_string(const T e)
void joinBoundary()
Join active boundaries and inactive boundaries to be the new boundary.
virtual const std::vector< RealVectorValue > getCrackPlaneNormals(unsigned int num_crack_front_points) const override
get a set of normal vectors along a crack front from a XFEM GeometricCutUserObject ...
virtual bool intersectWithEdge(const Point &p1, const Point &p2, const std::vector< Point > &_vertices, Point &point) const
Check if a line intersects with an element.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void sortBoundaryNodes()
Sort boundary nodes to be in the right order along the boundary.
unsigned int _id2
ID of the second node on the edge.
FEProblemBase & _fe_problem
Simple base class for XFEM cutting objects that use a mesh to cut.
std::vector< std::vector< dof_id_type > > _active_boundary
Active boundary nodes where growth is allowed.
void mooseError(Args &&... args) const
unsigned int getNumberOfCrackFrontPoints() const
Return the total number of crack front points.
MooseMesh & _mesh
The structural mesh.
CrackFrontDefinition * _crack_front_definition
The crack front definition.
static InputParameters validParams()
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void normalizePoint(Point &p)
virtual std::unique_ptr< libMesh::PointLocatorBase > getPointLocator() const
libMesh::StoredRange< MooseMesh::const_bnd_elem_iterator, const BndElement *> * getBoundaryElementRange()
bool isParamValid(const std::string &name) const
virtual void initialize() override
GrowthRateEnum
Enum to for crack growth rate.
virtual Real value(Real t, const Point &p) const
bool isInsideEdge(const Point &p1, const Point &p2, const Point &p) const
Check if point p is inside the edge p1-p2.
std::unique_ptr< MeshBase > _cutter_mesh
The xfem cutter mesh.
std::set< Xfem::CutEdge > _boundary_edges
Edges at the boundary.
void refineBoundary()
If boundary nodes are too sparse, add nodes in between.
std::vector< std::vector< Point > > _active_direction
Growth direction for active boundaries.
const std::vector< Real > *const _growth_inc_reporter
Pointer to reporter with growth increment if available.
static const std::string k
void ErrorVector unsigned int
void findActiveBoundaryDirection()
Find growth direction at each active node.
std::vector< unsigned int > _face_edge
IDs of all cut faces.
unsigned int _face_id
ID of the cut face.
bool isInsideCutPlane(const std::vector< Point > &_vertices, const Point &p) const
Check if point p is inside a plane.
std::vector< dof_id_type > _boundary
Boundary nodes of the cutter mesh.