https://mooseframework.inl.gov
InterfaceMeshCut2DUserObject.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 
12 
14 
17 {
19  params.addClassDescription("A userobject to cut a 2D mesh using a 1D cutter mesh.");
20  return params;
21 }
22 
24  : InterfaceMeshCutUserObjectBase(parameters)
25 {
26  for (const auto & elem : _cutter_mesh->element_ptr_range())
27  if (elem->type() != EDGE2)
28  mooseError(
29  "InterfaceMeshCut2DUserObject currently only supports EDGE2 element in the cut mesh.");
30 }
31 
32 void
34 {
35  _element_normals.clear();
36 
37  for (const auto & elem : _cutter_mesh->element_ptr_range())
38  {
39  Point a = elem->node_ref(1);
40  Point b = elem->node_ref(0);
41 
42  Point normal_ab = Point(-(b - a)(1), (b - a)(0), 0);
43  normal_ab /= normal_ab.norm();
44 
45  _element_normals.insert(std::make_pair(elem->id(), normal_ab));
46  }
47 }
48 
49 Point
50 InterfaceMeshCut2DUserObject::nodeNormal(const unsigned int & node_id)
51 {
52  Point normal(0.0);
53 
54  for (const auto & node_neigh_elem_id : _node_to_elem_map[node_id])
55  {
56  const auto & elem = _cutter_mesh->elem_ref(node_neigh_elem_id);
57 
58  Point a = elem.node_ref(1);
59  Point b = elem.node_ref(0);
60 
61  Point normal_ab = Point(-(b - a)(1), (b - a)(0), 0);
62  normal_ab /= normal_ab.norm();
63 
64  normal += normal_ab;
65  }
66 
67  unsigned int num = _node_to_elem_map[node_id].size();
68 
69  if (num == 0)
70  mooseError("InterfaceMeshCut2DUserObject, the node is not found in node_to_elem_map in "
71  "calculting its normal.");
72 
73  return normal / num;
74 }
75 
76 bool
78  std::vector<Xfem::CutEdge> & cut_edges,
79  std::vector<Xfem::CutNode> & cut_nodes) const
80 {
81  mooseAssert(elem->dim() == 2, "Dimension of element to be cut must be 2");
82 
83  bool elem_cut = false;
84 
85  for (const auto & cut_elem : _cutter_mesh->element_ptr_range())
86  {
87  unsigned int n_sides = elem->n_sides();
88 
89  for (unsigned int i = 0; i < n_sides; ++i)
90  {
91  std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
92 
93  mooseAssert(curr_side->type() == EDGE2, "Element side type must be EDGE2.");
94 
95  const Node * node1 = curr_side->node_ptr(0);
96  const Node * node2 = curr_side->node_ptr(1);
97  Real seg_int_frac = 0.0;
98 
99  const std::pair<Point, Point> elem_endpoints(cut_elem->node_ref(0), cut_elem->node_ref(1));
100 
101  if (Xfem::intersectSegmentWithCutLine(*node1, *node2, elem_endpoints, 1.0, seg_int_frac))
102  {
103  if (seg_int_frac > Xfem::tol && seg_int_frac < 1.0 - Xfem::tol)
104  {
105  elem_cut = true;
106  Xfem::CutEdge mycut;
107  mycut._id1 = node1->id();
108  mycut._id2 = node2->id();
109  mycut._distance = seg_int_frac;
110  mycut._host_side_id = i;
111  cut_edges.push_back(mycut);
112  }
113  else if (seg_int_frac < Xfem::tol)
114  {
115  elem_cut = true;
116  Xfem::CutNode mycut;
117  mycut._id = node1->id();
118  mycut._host_id = i;
119  cut_nodes.push_back(mycut);
120  }
121  }
122  }
123  }
124  return elem_cut;
125 }
126 
127 bool
129  std::vector<Xfem::CutFace> & /*cut_faces*/) const
130 {
131  mooseError("invalid method for InterfaceMeshCut2DUserObject");
132  return false;
133 }
134 
135 bool
137  std::vector<std::vector<Point>> & /*frag_edges*/,
138  std::vector<Xfem::CutEdge> & /*cut_edges*/) const
139 {
140  mooseError("cutFragmentByGeometry not yet implemented for InterfaceMeshCut2DUserObject");
141  return false;
142 }
143 
144 bool
146  std::vector<std::vector<Point>> & /*frag_faces*/,
147  std::vector<Xfem::CutFace> & /*cut_faces*/) const
148 {
149  mooseError("invalid method for InterfaceMeshCut2DUserObject");
150  return false;
151 }
152 
153 Real
155 {
156  Real min_dist = std::numeric_limits<Real>::max();
157 
158  for (const auto & cut_elem : _cutter_mesh->element_ptr_range())
159  {
160  Point a = cut_elem->node_ref(0);
161  Point b = cut_elem->node_ref(1);
162 
163  Point c = p - a;
164  Point v = (b - a) / (b - a).norm();
165  Real d = (b - a).norm();
166  Real t = v * c;
167 
168  Real dist;
169  Point nearest_point;
170 
171  if (t < 0)
172  {
173  dist = (p - a).norm();
174  nearest_point = a;
175  }
176  else if (t > d)
177  {
178  dist = (p - b).norm();
179  nearest_point = b;
180  }
181  else
182  {
183  v *= t;
184  dist = (p - a - v).norm();
185  nearest_point = (a + v);
186  }
187 
188  Point p_nearest_point = nearest_point - p;
189 
190  Point normal_ab = Point(-(b - a)(1), (b - a)(0), 0);
191 
192  if (normal_ab * p_nearest_point < 0)
193  dist = -dist;
194 
195  if (std::abs(dist) < std::abs(min_dist))
196  min_dist = dist;
197  }
198 
199  return min_dist;
200 }
Data structure defining a cut through a node.
InterfaceMeshCut2DUserObject(const InputParameters &parameters)
virtual void calculateNormals() override
calculate the element normal values for all of the elements.
unsigned int _host_id
Local ID of this node in the host element.
virtual Point nodeNormal(const unsigned int &node_id) override
return the normal at a node in the cutting mesh
virtual bool cutFragmentByGeometry(std::vector< std::vector< Point >> &frag_edges, std::vector< Xfem::CutEdge > &cut_edges) const override
Data structure defining a cut on an element edge.
unsigned int _id1
ID of the first node on the edge.
virtual Real calculateSignedDistance(Point p) const override
Calculate the signed distance for a given point relative to the surface.
auto norm(const T &a) -> decltype(std::abs(a))
virtual bool cutElementByGeometry(const Elem *elem, std::vector< Xfem::CutEdge > &cut_edges, std::vector< Xfem::CutNode > &cut_nodes) const override
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::shared_ptr< MeshBase > _cutter_mesh
The cutter mesh.
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
static const std::string v
Definition: NS.h:84
EDGE2
std::unordered_map< unsigned int, Point > _element_normals
Map of element normal.
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.
void addClassDescription(const std::string &doc_string)
registerMooseObject("XFEMApp", InterfaceMeshCut2DUserObject)
std::unordered_map< dof_id_type, std::vector< dof_id_type > > _node_to_elem_map
node to element map of cut mesh
unsigned int _id
ID of the cut node.