www.mooseframework.org
GeometricCut3DUserObject.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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.addClassDescription("Base class for 3D XFEM Geometric Cut UserObjects");
25  return params;
26 }
27 
29  : GeometricCutUserObject(parameters), _center(), _normal()
30 {
31 }
32 
33 bool
35  std::vector<Xfem::CutEdge> & /*cut_edges*/,
36  std::vector<Xfem::CutNode> & /*cut_nodes*/) const
37 {
38  mooseError("Invalid method: must use vector of element faces for 3D mesh cutting");
39  return false;
40 }
41 
42 bool
44  std::vector<Xfem::CutFace> & cut_faces) const
45 // TODO: Time evolving cuts not yet supported in 3D (hence the lack of use of the time variable)
46 {
47  bool cut_elem = false;
48 
49  for (unsigned int i = 0; i < elem->n_sides(); ++i)
50  {
51  // This returns the lowest-order type of side.
52  std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
53  if (curr_side->dim() != 2)
54  mooseError("In cutElementByGeometry dimension of side must be 2, but it is ",
55  curr_side->dim());
56  unsigned int n_edges = curr_side->n_sides();
57 
58  std::vector<unsigned int> cut_edges;
59  std::vector<Real> cut_pos;
60 
61  for (unsigned int j = 0; j < n_edges; j++)
62  {
63  // This returns the lowest-order type of side.
64  std::unique_ptr<const Elem> curr_edge = curr_side->side_ptr(j);
65  if (curr_edge->type() != EDGE2)
66  mooseError("In cutElementByGeometry face edge must be EDGE2, but type is: ",
67  libMesh::Utility::enum_to_string(curr_edge->type()),
68  " base element type is: ",
69  libMesh::Utility::enum_to_string(elem->type()));
70  const Node * node1 = curr_edge->node_ptr(0);
71  const Node * node2 = curr_edge->node_ptr(1);
72 
73  Point intersection;
74  if (intersectWithEdge(*node1, *node2, intersection))
75  {
76  cut_edges.push_back(j);
77  cut_pos.push_back(getRelativePosition(*node1, *node2, intersection));
78  }
79  }
80 
81  if (cut_edges.size() == 2)
82  {
83  cut_elem = true;
84  Xfem::CutFace mycut;
85  mycut._face_id = i;
86  mycut._face_edge.push_back(cut_edges[0]);
87  mycut._face_edge.push_back(cut_edges[1]);
88  mycut._position.push_back(cut_pos[0]);
89  mycut._position.push_back(cut_pos[1]);
90  cut_faces.push_back(mycut);
91  }
92  }
93 
94  return cut_elem;
95 }
96 
97 bool
98 GeometricCut3DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & /*frag_edges*/,
99  std::vector<Xfem::CutEdge> & /*cut_edges*/) const
100 {
101  mooseError("Invalid method: must use vector of element faces for 3D mesh cutting");
102  return false;
103 }
104 
105 bool
106 GeometricCut3DUserObject::cutFragmentByGeometry(std::vector<std::vector<Point>> & /*frag_faces*/,
107  std::vector<Xfem::CutFace> & /*cut_faces*/) const
108 {
109  // TODO: Need this for branching in 3D
110  mooseError("cutFragmentByGeometry not yet implemented for 3D mesh cutting");
111  return false;
112 }
113 
114 bool
115 GeometricCut3DUserObject::intersectWithEdge(const Point & p1, const Point & p2, Point & pint) const
116 {
117  bool has_intersection = false;
118  double plane_point[3] = {_center(0), _center(1), _center(2)};
119  double plane_normal[3] = {_normal(0), _normal(1), _normal(2)};
120  double edge_point1[3] = {p1(0), p1(1), p1(2)};
121  double edge_point2[3] = {p2(0), p2(1), p2(2)};
122  double cut_point[3] = {0.0, 0.0, 0.0};
123 
125  plane_point, plane_normal, edge_point1, edge_point2, cut_point) == 1)
126  {
127  Point temp_p(cut_point[0], cut_point[1], cut_point[2]);
128  if (isInsideCutPlane(temp_p) && isInsideEdge(p1, p2, temp_p))
129  {
130  pint = temp_p;
131  has_intersection = true;
132  }
133  }
134  return has_intersection;
135 }
136 
137 bool
138 GeometricCut3DUserObject::isInsideEdge(const Point & p1, const Point & p2, const Point & p) const
139 {
140  Real dotp1 = (p1 - p) * (p2 - p1);
141  Real dotp2 = (p2 - p) * (p2 - p1);
142  return (dotp1 * dotp2 <= 0.0);
143 }
144 
145 Real
147  const Point & p2,
148  const Point & p) const
149 {
150  // get the relative position of p from p1
151  Real full_len = (p2 - p1).norm();
152  Real len_p1_p = (p - p1).norm();
153  return len_p1_p / full_len;
154 }
static InputParameters validParams()
Factory constructor, takes parameters so that all derived classes can be built using the same constru...
virtual bool cutFragmentByGeometry(std::vector< std::vector< Point >> &frag_edges, std::vector< Xfem::CutEdge > &cut_edges) const override
Check to see whether a fragment of a 2D element should be cut based on geometric conditions.
void mooseError(Args &&... args)
GeometricCut3DUserObject(const InputParameters &parameters)
virtual bool isInsideCutPlane(Point p) const =0
std::vector< Real > _position
Fractional distance along the cut edges where the cut is located.
virtual bool intersectWithEdge(const Point &p1, const Point &p2, Point &pint) const
Data structure defining a cut through a face.
int plane_normal_line_exp_int_3d(double pp[3], double normal[3], double p1[3], double p2[3], double pint[3])
Definition: XFEMFuncs.C:403
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.
Definition: XFEMFuncs.C:991
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...
Definition: XFEMFuncs.C:948
auto norm(const T &a) -> decltype(std::abs(a))
Real getRelativePosition(const Point &p1, const Point &p2, const Point &p) const
std::string enum_to_string(const T e)
bool isInsideEdge(const Point &p1, const Point &p2, const Point &p) const
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
EDGE2
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual bool cutElementByGeometry(const Elem *elem, std::vector< Xfem::CutEdge > &cut_edges, std::vector< Xfem::CutNode > &cut_nodes) const override
Check to see whether a specified 2D element should be cut based on geometric conditions.
static InputParameters validParams()
std::vector< unsigned int > _face_edge
IDs of all cut faces.
unsigned int _face_id
ID of the cut face.