12 #include "libmesh/enum_point_locator_type.h" 27 for (
const auto & elem :
_cutter_mesh->element_ptr_range())
28 if (elem->type() !=
TRI3)
29 mooseError(
"InterfaceMeshCut3DUserObject currently only supports TRI3 elements in the " 38 for (
const auto & elem :
_cutter_mesh->element_ptr_range())
40 std::vector<Point> vertices{elem->node_ref(0), elem->node_ref(1), elem->node_ref(2)};
41 std::array<Point, 7> normal;
42 Plane elem_plane(vertices[0], vertices[1], vertices[2]);
43 normal[0] = 2.0 *
libMesh::pi * elem_plane.unit_normal(vertices[0]);
45 for (
unsigned int i = 0; i < elem->n_nodes(); i++)
47 Point normal_at_node(0.0);
48 const Node & node = elem->node_ref(i);
52 const Elem & node_neigh_elem =
_cutter_mesh->elem_ref(node_neigh_elem_id);
53 std::vector<Point> vertices{
54 node_neigh_elem.node_ref(0), node_neigh_elem.node_ref(1), node_neigh_elem.node_ref(2)};
55 Plane elem_plane(vertices[0], vertices[1], vertices[2]);
56 unsigned int j = node_neigh_elem.local_node(node.id());
57 Point normal_at_node_j = elem_plane.unit_normal(vertices[0]);
58 unsigned int m =
j + 1 < 3 ?
j + 1 :
j + 1 - 3;
59 unsigned int n =
j + 2 < 3 ?
j + 2 :
j + 2 - 3;
60 Point line_1 = node_neigh_elem.node_ref(
j) - node_neigh_elem.node_ref(m);
61 Point line_2 = node_neigh_elem.node_ref(
j) - node_neigh_elem.node_ref(n);
62 Real dot = line_1 * line_2;
63 Real lenSq1 = line_1 * line_1;
64 Real lenSq2 = line_2 * line_2;
65 Real angle = std::acos(dot / std::sqrt(lenSq1 * lenSq2));
66 normal_at_node += normal_at_node_j * angle;
68 normal[1 + i] = normal_at_node;
71 for (
unsigned int i = 0; i < elem->n_sides(); i++)
73 std::vector<Point> vertices{elem->node_ref(0), elem->node_ref(1), elem->node_ref(2)};
75 Plane elem_plane(vertices[0], vertices[1], vertices[2]);
76 Point normal_at_edge =
libMesh::pi * elem_plane.unit_normal(vertices[0]);
78 const Elem * neighbor = elem->neighbor_ptr(i);
80 if (neighbor !=
nullptr)
82 std::vector<Point> vertices{
83 neighbor->node_ref(0), neighbor->node_ref(1), neighbor->node_ref(2)};
85 Plane elem_plane(vertices[0], vertices[1], vertices[2]);
86 normal_at_edge +=
libMesh::pi * elem_plane.unit_normal(vertices[0]);
88 normal[4 + i] = normal_at_edge;
101 const auto & elem =
_cutter_mesh->elem_ref(node_neigh_elem_id);
102 Plane elem_plane(elem.node_ref(0), elem.node_ref(1), elem.node_ref(2));
103 normal += elem_plane.unit_normal(elem.node_ref(0));
112 std::vector<Xfem::CutEdge> & ,
113 std::vector<Xfem::CutNode> & )
const 115 mooseError(
"invalid method for 3D mesh cutting");
121 std::vector<Xfem::CutFace> & cut_faces)
const 123 mooseAssert(elem->dim() == 3,
"Dimension of element to be cut must be 3");
125 bool elem_cut =
false;
127 for (
unsigned int i = 0; i < elem->n_sides(); ++i)
130 std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
132 mooseAssert(curr_side->dim() == 2,
"Side dimension must be 2");
134 unsigned int n_edges = curr_side->n_sides();
136 std::vector<unsigned int> cut_edges;
137 std::vector<Real> cut_pos;
139 for (
unsigned int j = 0;
j < n_edges;
j++)
142 std::unique_ptr<const Elem> curr_edge = curr_side->side_ptr(
j);
143 if (curr_edge->type() !=
EDGE2)
144 mooseError(
"In cutElementByGeometry face edge must be EDGE2, but type is: ",
146 " base element type is: ",
148 const Node * node1 = curr_edge->node_ptr(0);
149 const Node * node2 = curr_edge->node_ptr(1);
151 for (
const auto & cut_elem :
_cutter_mesh->element_ptr_range())
153 std::vector<Point> vertices;
155 for (
auto & node : cut_elem->node_ref_range())
157 Point & this_point = node;
158 vertices.push_back(this_point);
163 std::find(cut_edges.begin(), cut_edges.end(),
j) == cut_edges.end())
165 cut_edges.push_back(
j);
172 if (cut_edges.size() == 2)
181 cut_faces.push_back(mycut);
190 std::vector<std::vector<Point>> & ,
191 std::vector<Xfem::CutEdge> & )
const 193 mooseError(
"invalid method for 3D mesh cutting");
199 std::vector<std::vector<Point>> & ,
200 std::vector<Xfem::CutFace> & )
const 202 mooseError(
"cutFragmentByGeometry not yet implemented for 3D mesh cutting");
210 Real min_dist = std::numeric_limits<Real>::max();
211 for (
const auto & cut_elem :
_cutter_mesh->element_ptr_range())
213 std::vector<Point> vertices{
214 cut_elem->node_ref(0), cut_elem->node_ref(1), cut_elem->node_ref(2)};
218 p, cut_elem->node_ref(0), cut_elem->node_ref(1), cut_elem->node_ref(2), xp, region);
222 if (dist < std::abs(min_dist))
225 Point normal = (
_pseudo_normal.find(cut_elem->id())->second)[region];
226 if (normal * (p - xp) < 0.0)
232 for (std::vector<Real>::iterator it =
distance.begin(); it !=
distance.begin() + 1; ++it)
236 return -sum_dist / 1.0;
238 return sum_dist / 1.0;
std::unordered_map< unsigned int, std::array< Point, 7 > > _pseudo_normal
Map of information defining cutting elements, stored in this order for each element: pseudo normal...
virtual Real calculateSignedDistance(Point p) const override
Calculate the signed distance for a given point relative to the surface.
virtual Point nodeNormal(const unsigned int &node_id) override
return the normal at a node in the cutting mesh
static InputParameters validParams()
std::vector< Real > _position
Fractional distance along the cut edges where the cut is located.
Real distance(const Point &p)
Data structure defining a cut through a face.
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.
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...
InterfaceMeshCut3DUserObject(const InputParameters ¶meters)
static InputParameters validParams()
std::shared_ptr< MeshBase > _cutter_mesh
The cutter mesh.
virtual bool cutFragmentByGeometry(std::vector< std::vector< Point >> &frag_edges, std::vector< Xfem::CutEdge > &cut_edges) const override
std::string enum_to_string(const T e)
virtual void calculateNormals() override
calculate the element normal values for all of the elements.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
void mooseError(Args &&... args) const
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
registerMooseObject("XFEMApp", InterfaceMeshCut3DUserObject)
std::unordered_map< dof_id_type, std::vector< dof_id_type > > _node_to_elem_map
node to element map of cut mesh
Real pointTriangleDistance(const Point &x0, const Point &x1, const Point &x2, const Point &x3, Point &xp, unsigned int ®ion)
Calculate the signed distance from a point to a triangle.
std::vector< unsigned int > _face_edge
IDs of all cut faces.
unsigned int _face_id
ID of the cut face.