www.mooseframework.org
XFEMCrackGrowthIncrement2DCut.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
3 /* */
4 /* All contents are licensed under LGPL V2.1 */
5 /* See LICENSE for full restrictions */
6 /****************************************************************/
7 
9 #include "XFEMFuncs.h"
10 #include "GeometricCutUserObject.h"
11 #include "MooseError.h"
12 #include "libmesh/string_to_enum.h"
13 
15  Real x0, Real y0, Real x1, Real y1, Real t0, Real t1)
16  : _time_range(std::make_pair(t0, t1)),
17  _cut_line_endpoints(std::make_pair(Point(x0, y0, 0.0), Point(x1, y1, 0.0)))
18 {
19 }
20 
21 Real
23 {
24  Real fraction = 0.0;
25  if (time >= _time_range.first)
26  {
27  if (time >= _time_range.second)
28  fraction = 1.0;
29  else
30  fraction = (time - _time_range.first) / (_time_range.second - _time_range.first);
31  }
32  return fraction;
33 }
34 
35 bool
37  const Elem * elem, std::vector<CutEdgeForCrackGrowthIncr> & cut_edges, Real time)
38 {
39  bool cut_elem = false;
40 
41  Real fraction = cutCompletionFraction(time);
42 
43  if (fraction > 0.0)
44  {
45  unsigned int n_sides = elem->n_sides();
46 
47  for (unsigned int i = 0; i < n_sides; ++i)
48  {
49  // This returns the lowest-order type of side, which should always
50  // be an EDGE2 here because this class is for 2D only.
51  std::unique_ptr<Elem> curr_side = elem->side(i);
52  if (curr_side->type() != EDGE2)
53  mooseError("In cutElementByGeometry element side must be EDGE2, but type is: ",
54  libMesh::Utility::enum_to_string(curr_side->type()),
55  " base element type is: ",
56  libMesh::Utility::enum_to_string(elem->type()));
57 
58  const Node * node1 = curr_side->get_node(0);
59  const Node * node2 = curr_side->get_node(1);
60  Real seg_int_frac = 0.0;
61 
62  if (IntersectSegmentWithCutLine(*node1, *node2, _cut_line_endpoints, fraction, seg_int_frac))
63  {
64  cut_elem = true;
66  mycut.id1 = node1->id();
67  mycut.id2 = node2->id();
68  mycut.distance = seg_int_frac;
69  mycut.host_side_id = i;
70  cut_edges.push_back(mycut);
71  }
72  }
73  }
74  return cut_elem;
75 }
76 
77 bool
79  const Point & segment_point1,
80  const Point & segment_point2,
81  const std::pair<Point, Point> & cutting_line_points,
82  const Real & cutting_line_fraction,
83  Real & segment_intersection_fraction)
84 {
85  // Use the algorithm described here to determine whether a line segment is intersected
86  // by a cutting line, and to compute the fraction along that line where the intersection
87  // occurs:
88  // http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
89 
90  bool cut_segment = false;
91  Point seg_dir = segment_point2 - segment_point1;
92  Point cut_dir = cutting_line_points.second - cutting_line_points.first;
93  Point cut_start_to_seg_start = segment_point1 - cutting_line_points.first;
94 
95  Real cut_dir_cross_seg_dir = crossProduct2D(cut_dir, seg_dir);
96 
97  if (std::abs(cut_dir_cross_seg_dir) > Xfem::tol)
98  {
99  // Fraction of the distance along the cutting segment where it intersects the edge segment
100  Real cut_int_frac = crossProduct2D(cut_start_to_seg_start, seg_dir) / cut_dir_cross_seg_dir;
101 
102  if (cut_int_frac >= 0.0 && cut_int_frac <= cutting_line_fraction)
103  { // Cutting segment intersects the line of the edge segment, but the intersection point may be
104  // outside the segment
105  Real int_frac = crossProduct2D(cut_start_to_seg_start, cut_dir) / cut_dir_cross_seg_dir;
106  if (int_frac >= 0.0 &&
107  int_frac <= 1.0) // TODO: revisit end cases for intersections with corners
108  {
109  cut_segment = true;
110  segment_intersection_fraction = int_frac;
111  }
112  }
113  }
114  return cut_segment;
115 }
116 
117 Real
118 XFEMCrackGrowthIncrement2DCut::crossProduct2D(const Point & point_a, const Point & point_b)
119 {
120  return (point_a(0) * point_b(1) - point_b(0) * point_a(1));
121 }
const std::pair< Point, Point > _cut_line_endpoints
bool IntersectSegmentWithCutLine(const Point &segment_point1, const Point &segment_point2, const std::pair< Point, Point > &cutting_line_points, const Real &cutting_line_fraction, Real &segment_intersection_fraction)
const std::pair< Real, Real > _time_range
Real crossProduct2D(const Point &point_a, const Point &point_b)
XFEMCrackGrowthIncrement2DCut(Real x0, Real y0, Real x1, Real y1, Real t0, Real t1)
static const double tol
Definition: XFEMFuncs.h:26
virtual bool cutElementByCrackGrowthIncrement(const Elem *elem, std::vector< CutEdgeForCrackGrowthIncr > &cut_edges, Real time)