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