https://mooseframework.inl.gov
GeometricCut2DUserObject.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://mooseframework.inl.gov
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
11 
12 // MOOSE includes
13 #include "MooseError.h"
14 
15 #include "libmesh/string_to_enum.h"
16 
17 // XFEM includes
18 #include "XFEMFuncs.h"
19 
22 {
24  params.addParam<Real>("time_start_cut", 0.0, "Start time of geometric cut propagation");
25  params.addParam<Real>("time_end_cut", 0.0, "End time of geometric cut propagation");
26  params.addClassDescription("Base class for 2D XFEM Geometric Cut UserObjects");
27  return params;
28 }
29 
31  : GeometricCutUserObject(parameters), _cut_line_endpoints(), _cut_time_ranges()
32 {
33  _cut_time_ranges.push_back(
34  std::make_pair(getParam<Real>("time_start_cut"), getParam<Real>("time_end_cut")));
35 }
36 
37 bool
39  std::vector<Xfem::CutEdge> & cut_edges,
40  std::vector<Xfem::CutNode> & cut_nodes) const
41 {
42  bool cut_elem = false;
43 
44  for (unsigned int cut = 0; cut < _cut_line_endpoints.size(); ++cut)
45  {
46  Real fraction = cutFraction(cut);
47 
48  if (fraction > 0.0)
49  {
50  unsigned int n_sides = elem->n_sides();
51 
52  for (unsigned int i = 0; i < n_sides; ++i)
53  {
54  // This returns the lowest-order type of side, which should always
55  // be an EDGE2 here because this class is for 2D only.
56  std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
57  if (curr_side->type() != EDGE2)
58  mooseError("In cutElementByGeometry element side must be EDGE2, but type is: ",
59  libMesh::Utility::enum_to_string(curr_side->type()),
60  " base element type is: ",
61  libMesh::Utility::enum_to_string(elem->type()));
62 
63  const Node * node1 = curr_side->node_ptr(0);
64  const Node * node2 = curr_side->node_ptr(1);
65  Real seg_int_frac = 0.0;
66 
68  *node1, *node2, _cut_line_endpoints[cut], fraction, seg_int_frac))
69  {
70  if (seg_int_frac > Xfem::tol && seg_int_frac < 1.0 - Xfem::tol)
71  {
72  cut_elem = true;
73  Xfem::CutEdge mycut;
74  mycut._id1 = node1->id();
75  mycut._id2 = node2->id();
76  mycut._distance = seg_int_frac;
77  mycut._host_side_id = i;
78  cut_edges.push_back(mycut);
79  }
80  else if (seg_int_frac < Xfem::tol)
81  {
82  cut_elem = true;
83  Xfem::CutNode mycut;
84  mycut._id = node1->id();
85  mycut._host_id = i;
86  cut_nodes.push_back(mycut);
87  }
88  }
89  }
90  }
91  }
92  return cut_elem;
93 }
94 
95 bool
97  std::vector<Xfem::CutFace> & /*cut_faces*/) const
98 {
99  mooseError("Invalid method: must use vector of element edges for 2D mesh cutting");
100  return false;
101 }
102 
103 bool
104 GeometricCut2DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & frag_edges,
105  std::vector<Xfem::CutEdge> & cut_edges) const
106 {
107  bool cut_frag = false;
108 
109  for (unsigned int cut = 0; cut < _cut_line_endpoints.size(); ++cut)
110  {
111  Real fraction = cutFraction(cut);
112 
113  if (fraction > 0.0)
114  {
115  unsigned int n_sides = frag_edges.size();
116 
117  for (unsigned int i = 0; i < n_sides; ++i)
118  {
119  Real seg_int_frac = 0.0;
120 
121  if (Xfem::intersectSegmentWithCutLine(frag_edges[i][0],
122  frag_edges[i][1],
123  _cut_line_endpoints[cut],
124  fraction,
125  seg_int_frac))
126  {
127  cut_frag = true;
128  Xfem::CutEdge mycut;
129  mycut._id1 = i;
130  mycut._id2 = (i < (n_sides - 1) ? (i + 1) : 0);
131  mycut._distance = seg_int_frac;
132  mycut._host_side_id = i;
133  cut_edges.push_back(mycut);
134  }
135  }
136  }
137  }
138  return cut_frag;
139 }
140 
141 bool
142 GeometricCut2DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & /*frag_faces*/,
143  std::vector<Xfem::CutFace> & /*cut_faces*/) const
144 {
145  mooseError("Invalid method: must use vector of element edges for 2D mesh cutting");
146  return false;
147 }
148 
149 Real
150 GeometricCut2DUserObject::cutFraction(unsigned int cut_num) const
151 {
152  mooseAssert(_cut_time_ranges.size() > cut_num,
153  "cut_num is outside the bounds of _cut_time_ranges");
154 
155  Real fraction = 0.0;
156 
157  if (_t >= _cut_time_ranges[cut_num].first)
158  {
159  if (_t >= _cut_time_ranges[cut_num].second)
160  fraction = 1.0;
161  else
162  {
163  Real denominator = _cut_time_ranges[cut_num].second - _cut_time_ranges[cut_num].first;
164  if (MooseUtils::absoluteFuzzyEqual(denominator, 0.0))
165  mooseError("time_start_cut and time_end_cut cannot have the same value");
166  fraction = (_t - _cut_time_ranges[cut_num].first) / denominator;
167  }
168  }
169  return fraction;
170 }
virtual Real cutFraction(unsigned int cut_num) const
Find the fractional distance along a specified cut line for the current time that is currently active...
Data structure defining a cut through a node.
std::vector< std::pair< Point, Point > > _cut_line_endpoints
static InputParameters validParams()
Factory constructor, takes parameters so that all derived classes can be built using the same constru...
bool absoluteFuzzyEqual(const T &var1, const T2 &var2, const T3 &tol=libMesh::TOLERANCE *libMesh::TOLERANCE)
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
static InputParameters validParams()
unsigned int _host_id
Local ID of this node in the host element.
GeometricCut2DUserObject(const InputParameters &parameters)
virtual bool cutElementByGeometry(const Elem *elem, std::vector< Xfem::CutEdge > &cut_edges, std::vector< Xfem::CutNode > &cut_nodes) const override
Data structure defining a cut on an element edge.
unsigned int _id1
ID of the first node on the edge.
static const double tol
Definition: XFEMFuncs.h:21
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)
Determine whether a line segment is intersected by a cutting line, and compute the fraction along tha...
Definition: XFEMFuncs.C:774
std::string enum_to_string(const T e)
Real _distance
Fractional distance along the edge (from node 1 to 2) where the cut is located.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
EDGE2
unsigned int _id2
ID of the second node on the edge.
void mooseError(Args &&... args) const
unsigned int _host_side_id
Local ID of this side in the host element.
std::vector< std::pair< Real, Real > > _cut_time_ranges
Vector of start/end times for each cut segment.
void addClassDescription(const std::string &doc_string)
virtual bool cutFragmentByGeometry(std::vector< std::vector< Point >> &frag_edges, std::vector< Xfem::CutEdge > &cut_edges) const override
unsigned int _id
ID of the cut node.