https://mooseframework.inl.gov
Loading...
Searching...
No Matches
GeometricCut3DUserObject.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.addClassDescription("Base class for 3D XFEM Geometric Cut UserObjects");
25 return params;
26}
27
29 : GeometricCutUserObject(parameters), _center(), _normal()
30{
31}
32
33bool
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
42bool
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: ",
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
97bool
98GeometricCut3DUserObject::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
105bool
106GeometricCut3DUserObject::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
114bool
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
137bool
138GeometricCut3DUserObject::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
145Real
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}
const Real p
void mooseError(Args &&... args)
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.
virtual bool intersectWithEdge(const Point &p1, const Point &p2, Point &pint) const
static InputParameters validParams()
GeometricCut3DUserObject(const InputParameters &parameters)
Real getRelativePosition(const Point &p1, const Point &p2, const Point &p) const
virtual bool isInsideCutPlane(Point p) const =0
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.
bool isInsideEdge(const Point &p1, const Point &p2, const Point &p) const
static InputParameters validParams()
Factory constructor, takes parameters so that all derived classes can be built using the same constru...
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
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
std::string enum_to_string(const T e)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
Data structure defining a cut through a face.
unsigned int _face_id
ID of the cut face.
std::vector< Real > _position
Fractional distance along the cut edges where the cut is located.
std::vector< unsigned int > _face_edge
IDs of all cut faces.