www.mooseframework.org
Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes | List of all members
MeshCut3DUserObject Class Reference

MeshCut3DUserObject: (1) reads in a mesh describing the crack surface, (2) uses the mesh to do initial cutting of 3D elements, and (3) grows the mesh based on prescribed growth functions. More...

#include <MeshCut3DUserObject.h>

Inheritance diagram for MeshCut3DUserObject:
[legend]

Public Member Functions

 MeshCut3DUserObject (const InputParameters &parameters)
 
virtual void initialSetup () override
 
virtual void initialize () override
 
virtual const std::vector< Point > getCrackFrontPoints (unsigned int num_crack_front_points) const override
 get a set of points along a crack front from a XFEM GeometricCutUserObject More...
 
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. More...
 
virtual bool cutElementByGeometry (const Elem *elem, std::vector< Xfem::CutFace > &cut_faces, Real time) const override
 Check to see whether a specified 3D element should be cut based on geometric conditions. More...
 
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. More...
 
virtual bool cutFragmentByGeometry (std::vector< std::vector< Point >> &frag_faces, std::vector< Xfem::CutFace > &cut_faces, Real time) const override
 Check to see whether a fragment of a 3D element should be cut based on geometric conditions. More...
 
virtual void execute () override
 
virtual void threadJoin (const UserObject &y) override
 
virtual void finalize () override
 
unsigned int getInterfaceID () const
 Get the interface ID for this cutting object. More...
 
void setInterfaceID (unsigned int interface_id)
 Set the interface ID for this cutting object. More...
 
bool shouldHealMesh () const
 Should the elements cut by this cutting object be healed in the current time step? More...
 

Static Public Member Functions

static InputParameters validParams ()
 

Protected Member Functions

virtual bool intersectWithEdge (const Point &p1, const Point &p2, const std::vector< Point > &_vertices, Point &pint) const
 Check if a line intersects with an element. More...
 
bool findIntersection (const Point &p1, const Point &p2, const std::vector< Point > &vertices, Point &pint) const
 Find directional intersection along the positive extension of the vector from p1 to p2. More...
 
bool isInsideEdge (const Point &p1, const Point &p2, const Point &p) const
 Check if point p is inside the edge p1-p2. More...
 
Real getRelativePosition (const Point &p1, const Point &p2, const Point &p) const
 Get the relative position of p from p1. More...
 
bool isInsideCutPlane (const std::vector< Point > &_vertices, const Point &p) const
 Check if point p is inside a plane. More...
 
void findBoundaryNodes ()
 Find boundary nodes of the cutter mesh This is a simple algorithm simply based on the added angle = 360 degrees Works fine for planar cutting surface for curved cutting surface, need to re-work this subroutine to make it more general. More...
 
void findBoundaryEdges ()
 Find boundary edges of the cutter mesh. More...
 
void sortBoundaryNodes ()
 Sort boundary nodes to be in the right order along the boundary. More...
 
Real findDistance (dof_id_type node1, dof_id_type node2)
 Find distance between two nodes. More...
 
void refineBoundary ()
 If boundary nodes are too sparse, add nodes in between. More...
 
void findActiveBoundaryNodes ()
 Find all active boundary nodes in the cutter mesh Find boundary nodes that will grow; nodes outside of the structural mesh are inactive. More...
 
void findActiveBoundaryDirection ()
 Find growth direction at each active node. More...
 
void growFront ()
 Grow the cutter mesh. More...
 
void sortFrontNodes ()
 Sort the front nodes. More...
 
void findFrontIntersection ()
 Find front-structure intersections. More...
 
void refineFront ()
 Refine the mesh at the front. More...
 
void triangulation ()
 Create tri3 elements between the new front and the old front. More...
 
void joinBoundary ()
 Join active boundaries and inactive boundaries to be the new boundary. More...
 
void serialize (std::string &serialized_buffer)
 Methods to pack/unpack the _marked_elems_2d and _marked_elems_3d data into a structure suitable for parallel communication. More...
 
void deserialize (std::vector< std::string > &serialized_buffers)
 

Protected Attributes

std::unique_ptr< MeshBase > _cut_mesh
 The cutter mesh. More...
 
const unsigned int _cut_elem_nnode = 3
 The cutter mesh has triangluar elements only. More...
 
const unsigned int _cut_elem_dim = 2
 
MooseMesh & _mesh
 The structural mesh. More...
 
const unsigned int _elem_dim = 3
 The structural mesh must be 3D only. More...
 
const Real _const_intersection = 0.01
 Used to define intersection points. More...
 
Real _size_control
 Used for cutter mesh refinement and front advancement. More...
 
unsigned int _n_step_growth
 Number of steps to grow the mesh. More...
 
bool _stop
 variables to help control the work flow More...
 
bool _grow
 
std::vector< dof_id_type > _boundary
 Boundary nodes of the cutter mesh. More...
 
std::set< Xfem::CutEdge_boundary_edges
 Edges at the boundary. More...
 
std::map< dof_id_type, std::vector< dof_id_type > > _boundary_map
 A map of boundary nodes and their neighbors. More...
 
std::vector< std::vector< dof_id_type > > _active_boundary
 Active boundary nodes where growth is allowed. More...
 
std::vector< std::vector< Point > > _active_direction
 Growth direction for active boundaries. More...
 
std::vector< unsigned int > _inactive_boundary_pos
 Inactive boundary. More...
 
std::vector< std::vector< dof_id_type > > _front
 New boundary after growth. More...
 
const Function & _func_x
 Parsed functions of front growth. More...
 
const Function & _func_y
 
const Function & _func_z
 
std::shared_ptr< XFEM_xfem
 Pointer to the XFEM controller object. More...
 
unsigned int _interface_id
 Associated interface id. More...
 
bool _heal_always
 Heal the mesh. More...
 
unsigned int _last_step_initialized
 Time step information needed to advance a 3D crack only at the real beginning of a time step. More...
 
std::map< unsigned int, std::vector< Xfem::GeomMarkedElemInfo2D > > _marked_elems_2d
 Containers with information about all 2D and 3D elements marked for cutting by this object. More...
 
std::map< unsigned int, std::vector< Xfem::GeomMarkedElemInfo3D > > _marked_elems_3d
 

Detailed Description

MeshCut3DUserObject: (1) reads in a mesh describing the crack surface, (2) uses the mesh to do initial cutting of 3D elements, and (3) grows the mesh based on prescribed growth functions.

Definition at line 28 of file MeshCut3DUserObject.h.

Constructor & Destructor Documentation

◆ MeshCut3DUserObject()

MeshCut3DUserObject::MeshCut3DUserObject ( const InputParameters &  parameters)

Definition at line 44 of file MeshCut3DUserObject.C.

45  : GeometricCutUserObject(parameters),
46  _mesh(_subproblem.mesh()),
47  _n_step_growth(getParam<unsigned int>("n_step_growth")),
48  _func_x(getFunction("function_x")),
49  _func_y(getFunction("function_y")),
50  _func_z(getFunction("function_z"))
51 {
52  _grow = (_n_step_growth == 0 ? 0 : 1);
53 
54  if (_grow)
55  {
56  if (!isParamValid("size_control"))
57  mooseError("Crack growth needs size control");
58 
59  _size_control = getParam<Real>("size_control");
60  }
61 
62  // only the xda type is currently supported
63  MeshFileName xfem_cut_mesh_file = getParam<MeshFileName>("mesh_file");
64  _cut_mesh = libmesh_make_unique<ReplicatedMesh>(_communicator);
65  _cut_mesh->read(xfem_cut_mesh_file);
66 
67  // test element type; only tri3 elements are allowed
68  for (const auto & cut_elem : _cut_mesh->element_ptr_range())
69  {
70  if (cut_elem->n_nodes() != _cut_elem_nnode)
71  mooseError("The input cut mesh should include tri elements only!");
72  if (cut_elem->dim() != _cut_elem_dim)
73  mooseError("The input cut mesh should have 2D elements only!");
74  }
75 }

Member Function Documentation

◆ cutElementByGeometry() [1/2]

bool MeshCut3DUserObject::cutElementByGeometry ( const Elem *  elem,
std::vector< Xfem::CutEdge > &  cut_edges,
std::vector< Xfem::CutNode > &  cut_nodes,
Real  time 
) const
overridevirtual

Check to see whether a specified 2D element should be cut based on geometric conditions.

Parameters
elemPointer to the libMesh element to be considered for cutting
cut_edgesData structure filled with information about edges to be cut
cut_nodesData structure filled with information about nodes to be cut
timeCurrent simulation time
Returns
bool true if element is to be cut

Implements GeometricCutUserObject.

Definition at line 124 of file MeshCut3DUserObject.C.

128 {
129  mooseError("invalid method for 3D mesh cutting");
130  return false;
131 }

◆ cutElementByGeometry() [2/2]

bool MeshCut3DUserObject::cutElementByGeometry ( const Elem *  elem,
std::vector< Xfem::CutFace > &  cut_faces,
Real  time 
) const
overridevirtual

Check to see whether a specified 3D element should be cut based on geometric conditions.

Parameters
elemPointer to the libMesh element to be considered for cutting
cut_facesData structure filled with information about edges to be cut
timeCurrent simulation time
Returns
bool true if element is to be cut

Implements GeometricCutUserObject.

Definition at line 134 of file MeshCut3DUserObject.C.

140 {
141  bool elem_cut = false;
142 
143  if (elem->dim() != _elem_dim)
144  mooseError("The structural mesh to be cut by a surface mesh must be 3D!");
145 
146  for (unsigned int i = 0; i < elem->n_sides(); ++i)
147  {
148  // This returns the lowest-order type of side.
149  std::unique_ptr<const Elem> curr_side = elem->side_ptr(i);
150  if (curr_side->dim() != 2)
151  mooseError("In cutElementByGeometry dimension of side must be 2, but it is ",
152  curr_side->dim());
153  unsigned int n_edges = curr_side->n_sides();
154 
155  std::vector<unsigned int> cut_edges;
156  std::vector<Real> cut_pos;
157 
158  for (unsigned int j = 0; j < n_edges; j++)
159  {
160  // This returns the lowest-order type of side.
161  std::unique_ptr<const Elem> curr_edge = curr_side->side_ptr(j);
162  if (curr_edge->type() != EDGE2)
163  mooseError("In cutElementByGeometry face edge must be EDGE2, but type is: ",
164  libMesh::Utility::enum_to_string(curr_edge->type()),
165  " base element type is: ",
166  libMesh::Utility::enum_to_string(elem->type()));
167  const Node * node1 = curr_edge->node_ptr(0);
168  const Node * node2 = curr_edge->node_ptr(1);
169 
170  for (const auto & cut_elem : _cut_mesh->element_ptr_range())
171  {
172  std::vector<Point> vertices;
173 
174  for (auto & node : cut_elem->node_ref_range())
175  {
176  Point & this_point = node;
177  vertices.push_back(this_point);
178  }
179 
180  Point intersection;
181  if (intersectWithEdge(*node1, *node2, vertices, intersection))
182  {
183  cut_edges.push_back(j);
184  cut_pos.emplace_back(getRelativePosition(*node1, *node2, intersection));
185  }
186  }
187  }
188 
189  // if two edges of an element are cut, it is considered as an element being cut
190  if (cut_edges.size() == 2)
191  {
192  elem_cut = true;
193  Xfem::CutFace mycut;
194  mycut._face_id = i;
195  mycut._face_edge.push_back(cut_edges[0]);
196  mycut._face_edge.push_back(cut_edges[1]);
197  mycut._position.push_back(cut_pos[0]);
198  mycut._position.push_back(cut_pos[1]);
199  cut_faces.push_back(mycut);
200  }
201  }
202  return elem_cut;
203 }

◆ cutFragmentByGeometry() [1/2]

bool MeshCut3DUserObject::cutFragmentByGeometry ( std::vector< std::vector< Point >> &  frag_edges,
std::vector< Xfem::CutEdge > &  cut_edges,
Real  time 
) const
overridevirtual

Check to see whether a fragment of a 2D element should be cut based on geometric conditions.

Parameters
frag_edgesData structure defining the current fragment to be considered
cut_edgesData structure filled with information about fragment edges to be cut
timeCurrent simulation time
Returns
bool true if fragment is to be cut

Implements GeometricCutUserObject.

Definition at line 206 of file MeshCut3DUserObject.C.

209 {
210  mooseError("invalid method for 3D mesh cutting");
211  return false;
212 }

◆ cutFragmentByGeometry() [2/2]

bool MeshCut3DUserObject::cutFragmentByGeometry ( std::vector< std::vector< Point >> &  frag_faces,
std::vector< Xfem::CutFace > &  cut_faces,
Real  time 
) const
overridevirtual

Check to see whether a fragment of a 3D element should be cut based on geometric conditions.

Parameters
frag_facesData structure defining the current fragment to be considered
cut_facesData structure filled with information about fragment faces to be cut
timeCurrent simulation time
Returns
bool true if fragment is to be cut

Implements GeometricCutUserObject.

Definition at line 215 of file MeshCut3DUserObject.C.

218 {
219  // TODO: Need this for branching in 3D
220  mooseError("cutFragmentByGeometry not yet implemented for 3D mesh cutting");
221  return false;
222 }

◆ deserialize()

void GeometricCutUserObject::deserialize ( std::vector< std::string > &  serialized_buffers)
protectedinherited

Definition at line 222 of file GeometricCutUserObject.C.

223 {
224  mooseAssert(serialized_buffers.size() == _app.n_processors(),
225  "Unexpected size of serialized_buffers: " << serialized_buffers.size());
226 
227  // The input string stream used for deserialization
228  std::istringstream iss;
229 
230  // Loop over all datastructures for all processors to perfrom the gather operation
231  for (unsigned int rank = 0; rank < serialized_buffers.size(); ++rank)
232  {
233  // skip the current processor (its data is already in the structures)
234  if (rank == processor_id())
235  continue;
236 
237  // populate the stream with a new buffer and reset stream state
238  iss.clear();
239  iss.str(serialized_buffers[rank]);
240 
241  // Load the communicated data into temporary structures
242  std::map<unsigned int, std::vector<Xfem::GeomMarkedElemInfo2D>> other_marked_elems_2d;
243  std::map<unsigned int, std::vector<Xfem::GeomMarkedElemInfo3D>> other_marked_elems_3d;
244  dataLoad(iss, other_marked_elems_2d, this);
245  dataLoad(iss, other_marked_elems_3d, this);
246 
247  // merge the data in with the current processor's data
248  _marked_elems_2d.insert(other_marked_elems_2d.begin(), other_marked_elems_2d.end());
249  _marked_elems_3d.insert(other_marked_elems_3d.begin(), other_marked_elems_3d.end());
250  }
251 }

Referenced by GeometricCutUserObject::finalize().

◆ execute()

void GeometricCutUserObject::execute ( )
overridevirtualinherited

Reimplemented in MovingLineSegmentCutSetUserObject.

Definition at line 67 of file GeometricCutUserObject.C.

68 {
69  if (_current_elem->dim() == 2)
70  {
71  std::vector<Xfem::CutEdge> elem_cut_edges;
72  std::vector<Xfem::CutNode> elem_cut_nodes;
73  std::vector<Xfem::CutEdge> frag_cut_edges;
74  std::vector<std::vector<Point>> frag_edges;
75 
76  EFAElement2D * EFAElem = _xfem->getEFAElem2D(_current_elem);
77 
78  // Don't cut again if elem has been already cut twice
79  if (!EFAElem->isFinalCut())
80  {
81  // get fragment edges
82  _xfem->getFragmentEdges(_current_elem, EFAElem, frag_edges);
83 
84  // mark cut edges for the element and its fragment
85  bool cut = cutElementByGeometry(_current_elem, elem_cut_edges, elem_cut_nodes, _t);
86  if (EFAElem->numFragments() > 0)
87  cut |= cutFragmentByGeometry(frag_edges, frag_cut_edges, _t);
88 
89  if (cut)
90  {
92  gmei2d._elem_cut_edges = elem_cut_edges;
93  gmei2d._elem_cut_nodes = elem_cut_nodes;
94  gmei2d._frag_cut_edges = frag_cut_edges;
95  gmei2d._frag_edges = frag_edges;
96  _marked_elems_2d[_current_elem->id()].push_back(gmei2d);
97  }
98  }
99  }
100  else if (_current_elem->dim() == 3)
101  {
102  std::vector<Xfem::CutFace> elem_cut_faces;
103  std::vector<Xfem::CutFace> frag_cut_faces;
104  std::vector<std::vector<Point>> frag_faces;
105 
106  EFAElement3D * EFAElem = _xfem->getEFAElem3D(_current_elem);
107 
108  // Don't cut again if elem has been already cut twice
109  if (!EFAElem->isFinalCut())
110  {
111  // get fragment edges
112  _xfem->getFragmentFaces(_current_elem, EFAElem, frag_faces);
113 
114  // mark cut faces for the element and its fragment
115  bool cut = cutElementByGeometry(_current_elem, elem_cut_faces, _t);
116  // TODO: This would be done for branching, which is not yet supported in 3D
117  // if (EFAElem->numFragments() > 0)
118  // cut |= cutFragmentByGeometry(frag_faces, frag_cut_faces, _t);
119 
120  if (cut)
121  {
123  gmei3d._elem_cut_faces = elem_cut_faces;
124  gmei3d._frag_cut_faces = frag_cut_faces;
125  gmei3d._frag_faces = frag_faces;
126  _marked_elems_3d[_current_elem->id()].push_back(gmei3d);
127  }
128  }
129  }
130 }

Referenced by MovingLineSegmentCutSetUserObject::execute().

◆ finalize()

void GeometricCutUserObject::finalize ( )
overridevirtualinherited

Reimplemented in MovingLineSegmentCutSetUserObject.

Definition at line 254 of file GeometricCutUserObject.C.

255 {
256  // for single processor runs we do not need to do anything here
257  if (_app.n_processors() > 1)
258  {
259  // create send buffer
260  std::string send_buffer;
261 
262  // create byte buffers for the streams received from all processors
263  std::vector<std::string> recv_buffers;
264 
265  // pack the complex datastructures into the string stream
266  serialize(send_buffer);
267 
268  // broadcast serialized data to and receive from all processors
269  _communicator.allgather(send_buffer, recv_buffers);
270 
271  // unpack the received data and merge it into the local data structures
272  deserialize(recv_buffers);
273  }
274 
275  for (const auto & it : _marked_elems_2d)
276  for (const auto & gmei : it.second)
277  _xfem->addGeomMarkedElem2D(it.first, gmei, _interface_id);
278 
279  for (const auto & it : _marked_elems_3d)
280  for (const auto & gmei : it.second)
281  _xfem->addGeomMarkedElem3D(it.first, gmei, _interface_id);
282 
283  _marked_elems_2d.clear();
284  _marked_elems_3d.clear();
285 }

Referenced by MovingLineSegmentCutSetUserObject::finalize().

◆ findActiveBoundaryDirection()

void MeshCut3DUserObject::findActiveBoundaryDirection ( )
protected

Find growth direction at each active node.

Definition at line 678 of file MeshCut3DUserObject.C.

682 {
683  _active_direction.clear();
684 
685  for (unsigned int i = 0; i < _active_boundary.size(); ++i)
686  {
687  std::vector<Point> temp;
688  Point dir;
689 
690  if (_inactive_boundary_pos.size() != 0)
691  {
692  for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
693  dir(j) = 0;
694  temp.push_back(dir);
695  }
696 
697  unsigned int i1 = 1;
698  unsigned int i2 = _active_boundary[i].size() - 1;
699  if (_inactive_boundary_pos.size() == 0)
700  {
701  i1 = 0;
702  i2 = _active_boundary[i].size();
703  }
704 
705  for (unsigned int j = i1; j < i2; ++j)
706  {
707  Node * this_node = _cut_mesh->node_ptr(_active_boundary[i][j]);
708  mooseAssert(this_node, "Node is NULL");
709  Point & this_point = *this_node;
710 
711  dir(0) = _func_x.value(0, this_point);
712  dir(1) = _func_y.value(0, this_point);
713  dir(2) = _func_z.value(0, this_point);
714 
715  temp.push_back(dir);
716  }
717 
718  if (_inactive_boundary_pos.size() != 0)
719  {
720  for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
721  dir(j) = 0;
722  temp.push_back(dir);
723  }
724 
725  _active_direction.push_back(temp);
726  }
727 
728  Real maxl = 0;
729 
730  for (unsigned int i = 0; i < _active_direction.size(); ++i)
731  for (unsigned int j = 0; j < _active_direction[i].size(); ++j)
732  {
733  Point pt = _active_direction[i][j];
734  Real length = std::sqrt(pt * pt);
735  if (length > maxl)
736  maxl = length;
737  }
738 
739  for (unsigned int i = 0; i < _active_direction.size(); ++i)
740  for (unsigned int j = 0; j < _active_direction[i].size(); ++j)
741  _active_direction[i][j] /= maxl;
742 }

Referenced by initialize().

◆ findActiveBoundaryNodes()

void MeshCut3DUserObject::findActiveBoundaryNodes ( )
protected

Find all active boundary nodes in the cutter mesh Find boundary nodes that will grow; nodes outside of the structural mesh are inactive.

Definition at line 618 of file MeshCut3DUserObject.C.

619 {
620  _active_boundary.clear();
621  _inactive_boundary_pos.clear();
622 
623  std::unique_ptr<PointLocatorBase> pl = _mesh.getPointLocator();
624  pl->enable_out_of_mesh_mode();
625 
626  unsigned int n_boundary = _boundary.size();
627 
628  // if the node is outside of the structural model, store its position in _boundary to
629  // _inactive_boundary_pos
630  for (unsigned int j = 0; j < n_boundary; ++j)
631  {
632  Node * this_node = _cut_mesh->node_ptr(_boundary[j]);
633  mooseAssert(this_node, "Node is NULL");
634  Point & this_point = *this_node;
635 
636  const Elem * elem = (*pl)(this_point);
637  if (elem == NULL)
638  _inactive_boundary_pos.push_back(j);
639  }
640 
641  unsigned int n_inactive_boundary = _inactive_boundary_pos.size();
642 
643  // all nodes are inactive, stop
644  if (n_inactive_boundary == n_boundary)
645  _stop = 1;
646 
647  // find and store active boundary segments in "_active_boundary"
648  if (n_inactive_boundary == 0)
649  _active_boundary.push_back(_boundary);
650  else
651  {
652  for (unsigned int i = 0; i < n_inactive_boundary - 1; ++i)
653  {
654  if (_inactive_boundary_pos[i + 1] - _inactive_boundary_pos[i] != 1)
655  {
656  std::vector<dof_id_type> temp;
657  for (unsigned int j = _inactive_boundary_pos[i]; j <= _inactive_boundary_pos[i + 1]; ++j)
658  {
659  temp.push_back(_boundary[j]);
660  }
661  _active_boundary.push_back(temp);
662  }
663  }
664  if (_inactive_boundary_pos[n_inactive_boundary - 1] - _inactive_boundary_pos[0] <
665  n_boundary - 1)
666  {
667  std::vector<dof_id_type> temp;
668  for (unsigned int j = _inactive_boundary_pos[n_inactive_boundary - 1]; j < n_boundary; ++j)
669  temp.push_back(_boundary[j]);
670  for (unsigned int j = 0; j <= _inactive_boundary_pos[0]; ++j)
671  temp.push_back(_boundary[j]);
672  _active_boundary.push_back(temp);
673  }
674  }
675 }

Referenced by initialize().

◆ findBoundaryEdges()

void MeshCut3DUserObject::findBoundaryEdges ( )
protected

Find boundary edges of the cutter mesh.

Definition at line 373 of file MeshCut3DUserObject.C.

374 {
375  _boundary_edges.clear();
376 
377  std::vector<dof_id_type> corner_elem_id;
378  unsigned int counter = 0;
379 
380  std::vector<dof_id_type> node_id(_cut_elem_nnode);
381  std::vector<bool> is_node_on_boundary(_cut_elem_nnode);
382 
383  for (const auto & cut_elem : _cut_mesh->element_ptr_range())
384  {
385  for (unsigned int i = 0; i < _cut_elem_nnode; ++i)
386  {
387  node_id[i] = cut_elem->node_ptr(i)->id();
388  is_node_on_boundary[i] = (_boundary_map.find(node_id[i]) != _boundary_map.end());
389  }
390 
391  if (is_node_on_boundary[0] && is_node_on_boundary[1] && is_node_on_boundary[2])
392  {
393  // this is an element at the corner; all nodes are on the boundary but not all edges are on
394  // the boundary
395  corner_elem_id.push_back(counter);
396  }
397  else
398  {
399  // for other elements, find and store boundary edges
400  for (unsigned int i = 0; i < _cut_elem_nnode; ++i)
401  {
402  // if both nodes on an edge are on the boundary, it is a boundary edge.
403  if (is_node_on_boundary[i] && is_node_on_boundary[(i + 1 <= 2) ? i + 1 : 0])
404  {
405  dof_id_type node1 = node_id[i];
406  dof_id_type node2 = node_id[(i + 1 <= 2) ? i + 1 : 0];
407  if (node1 > node2)
408  std::swap(node1, node2);
409 
410  Xfem::CutEdge ce;
411 
412  if (node1 > node2)
413  std::swap(node1, node2);
414  ce._id1 = node1;
415  ce._id2 = node2;
416 
417  _boundary_edges.insert(ce);
418  }
419  }
420  }
421  ++counter;
422  }
423 
424  // loop over edges in corner elements
425  // if an edge is shared by two elements, it is not an boundary edge (is_edge_inside = 1)
426  for (unsigned int i = 0; i < corner_elem_id.size(); ++i)
427  {
428  auto elem_it = _cut_mesh->elements_begin();
429 
430  for (dof_id_type j = 0; j < corner_elem_id[i]; ++j)
431  ++elem_it;
432  Elem * cut_elem = *elem_it;
433 
434  for (unsigned int j = 0; j < _cut_elem_nnode; ++j)
435  {
436  bool is_edge_inside = 0;
437 
438  dof_id_type node1 = cut_elem->node_ptr(j)->id();
439  dof_id_type node2 = cut_elem->node_ptr((j + 1 <= 2) ? j + 1 : 0)->id();
440  if (node1 > node2)
441  std::swap(node1, node2);
442 
443  unsigned int counter = 0;
444  for (const auto & cut_elem2 : _cut_mesh->element_ptr_range())
445  {
446  if (counter != corner_elem_id[i])
447  {
448  for (unsigned int k = 0; k < _cut_elem_nnode; ++k)
449  {
450  dof_id_type node3 = cut_elem2->node_ptr(k)->id();
451  dof_id_type node4 = cut_elem2->node_ptr((k + 1 <= 2) ? k + 1 : 0)->id();
452  if (node3 > node4)
453  std::swap(node3, node4);
454 
455  if (node1 == node3 && node2 == node4)
456  {
457  is_edge_inside = 1;
458  goto endloop;
459  }
460  }
461  }
462  ++counter;
463  }
464  endloop:
465  if (is_edge_inside == 0)
466  {
467  // store boundary edges
468  Xfem::CutEdge ce;
469 
470  if (node1 > node2)
471  std::swap(node1, node2);
472  ce._id1 = node1;
473  ce._id2 = node2;
474 
475  _boundary_edges.insert(ce);
476  }
477  else
478  {
479  // this is not a boundary edge; remove it from existing edge list
480  for (auto it = _boundary_edges.begin(); it != _boundary_edges.end();)
481  {
482  if ((*it)._id1 == node1 && (*it)._id2 == node2)
483  it = _boundary_edges.erase(it);
484  else
485  ++it;
486  }
487  }
488  }
489  }
490 }

Referenced by initialSetup().

◆ findBoundaryNodes()

void MeshCut3DUserObject::findBoundaryNodes ( )
protected

Find boundary nodes of the cutter mesh This is a simple algorithm simply based on the added angle = 360 degrees Works fine for planar cutting surface for curved cutting surface, need to re-work this subroutine to make it more general.

Definition at line 331 of file MeshCut3DUserObject.C.

332 {
333  unsigned int n_nodes = _cut_mesh->n_nodes();
334  std::vector<Real> angle(n_nodes, 0); // this assumes that the cutter mesh has compressed node id
335  std::vector<dof_id_type> node_id(_cut_elem_nnode);
336 
337  std::vector<Point> vertices(_cut_elem_nnode);
338 
339  for (const auto & cut_elem : _cut_mesh->element_ptr_range())
340  {
341  for (unsigned int i = 0; i < _cut_elem_nnode; ++i)
342  {
343  Node * this_node = cut_elem->node_ptr(i);
344  Point & this_point = *this_node;
345  vertices[i] = this_point;
346  node_id[i] = this_node->id();
347  }
348 
349  for (unsigned int i = 0; i < _cut_elem_nnode; ++i)
350  mooseAssert(node_id[i] < n_nodes, "Node ID is out of range");
351 
352  angle[node_id[0]] += Xfem::angle_rad_3d(&vertices[2](0), &vertices[0](0), &vertices[1](0));
353  angle[node_id[1]] += Xfem::angle_rad_3d(&vertices[0](0), &vertices[1](0), &vertices[2](0));
354  angle[node_id[2]] += Xfem::angle_rad_3d(&vertices[1](0), &vertices[2](0), &vertices[0](0));
355  }
356 
357  // In each element, angles at three vertices are calculated. Angles associated with all nodes are
358  // evaluated.
359  // Interior nodes will have a total angle = 2*pi; otherwise, it is a boundary node
360  // This assumes the cutter surface is flat.
361  for (const auto & node : _cut_mesh->node_ptr_range())
362  {
363  dof_id_type id = node->id();
364  if (!MooseUtils::relativeFuzzyEqual(angle[id], libMesh::pi * 2))
365  {
366  std::vector<dof_id_type> neighbors;
367  _boundary_map[id] = neighbors;
368  }
369  }
370 }

Referenced by initialSetup().

◆ findDistance()

Real MeshCut3DUserObject::findDistance ( dof_id_type  node1,
dof_id_type  node2 
)
protected

Find distance between two nodes.

Definition at line 553 of file MeshCut3DUserObject.C.

554 {
555  Node * n1 = _cut_mesh->node_ptr(node1);
556  mooseAssert(n1 != nullptr, "Node is NULL");
557  Node * n2 = _cut_mesh->node_ptr(node2);
558  mooseAssert(n2 != nullptr, "Node is NULL");
559  Real distance = (*n1 - *n2).norm();
560  return distance;
561 }

Referenced by refineBoundary(), refineFront(), and triangulation().

◆ findFrontIntersection()

void MeshCut3DUserObject::findFrontIntersection ( )
protected

Find front-structure intersections.

Definition at line 790 of file MeshCut3DUserObject.C.

791 {
792  ConstBndElemRange & range = *_mesh.getBoundaryElementRange();
793 
794  for (unsigned int i = 0; i < _front.size(); ++i)
795  {
796  if (_front[i].size() >= 2)
797  {
798  std::vector<Point> pint1;
799  std::vector<Point> pint2;
800  std::vector<Real> length1;
801  std::vector<Real> length2;
802 
803  Real node_id = _front[i][0];
804  Node * this_node = _cut_mesh->node_ptr(node_id);
805  mooseAssert(this_node, "Node is NULL");
806  Point & p2 = *this_node;
807 
808  node_id = _front[i][1];
809  this_node = _cut_mesh->node_ptr(node_id);
810  mooseAssert(this_node, "Node is NULL");
811  Point & p1 = *this_node;
812 
813  node_id = _front[i].back();
814  this_node = _cut_mesh->node_ptr(node_id);
815  mooseAssert(this_node, "Node is NULL");
816  Point & p4 = *this_node;
817 
818  node_id = _front[i][_front[i].size() - 2];
819  this_node = _cut_mesh->node_ptr(node_id);
820  mooseAssert(this_node, "Node is NULL");
821  Point & p3 = *this_node;
822 
823  bool do_inter1 = 1;
824  bool do_inter2 = 1;
825 
826  std::unique_ptr<PointLocatorBase> pl = _mesh.getPointLocator();
827  pl->enable_out_of_mesh_mode();
828  const Elem * elem = (*pl)(p1);
829  if (elem == NULL)
830  do_inter1 = 0;
831  elem = (*pl)(p4);
832  if (elem == NULL)
833  do_inter2 = 0;
834 
835  for (const auto & belem : range)
836  {
837  Point pt;
838  std::vector<Point> vertices;
839 
840  elem = belem->_elem;
841  std::unique_ptr<const Elem> curr_side = elem->side_ptr(belem->_side);
842  for (unsigned int j = 0; j < curr_side->n_nodes(); ++j)
843  {
844  const Node * node = curr_side->node_ptr(j);
845  const Point & this_point = *node;
846  vertices.push_back(this_point);
847  }
848 
849  if (findIntersection(p1, p2, vertices, pt))
850  {
851  pint1.push_back(pt);
852  length1.push_back((pt - p1) * (pt - p1));
853  }
854  if (findIntersection(p3, p4, vertices, pt))
855  {
856  pint2.push_back(pt);
857  length2.push_back((pt - p3) * (pt - p3));
858  }
859  }
860 
861  if (length1.size() != 0 && do_inter1)
862  {
863  auto it1 = std::min_element(length1.begin(), length1.end());
864  Point inter1 = pint1[std::distance(length1.begin(), it1)];
865  inter1 += (inter1 - p1) * _const_intersection;
866 
867  Node * this_node = Node::build(inter1, _cut_mesh->n_nodes()).release();
868  _cut_mesh->add_node(this_node);
869 
870  mooseAssert(_cut_mesh->n_nodes() - 1 > 0, "The cut mesh should have at least one element.");
871  unsigned int n = _cut_mesh->n_nodes() - 1;
872 
873  auto it = _front[i].begin();
874  _front[i].insert(it, n);
875  }
876 
877  if (length2.size() != 0 && do_inter2)
878  {
879  auto it2 = std::min_element(length2.begin(), length2.end());
880  Point inter2 = pint2[std::distance(length2.begin(), it2)];
881  inter2 += (inter2 - p2) * _const_intersection;
882 
883  Node * this_node = Node::build(inter2, _cut_mesh->n_nodes()).release();
884  _cut_mesh->add_node(this_node);
885 
886  dof_id_type n = _cut_mesh->n_nodes() - 1;
887 
888  auto it = _front[i].begin();
889  unsigned int m = _front[i].size();
890  _front[i].insert(it + m, n);
891  }
892  }
893  }
894 }

Referenced by initialize().

◆ findIntersection()

bool MeshCut3DUserObject::findIntersection ( const Point &  p1,
const Point &  p2,
const std::vector< Point > &  vertices,
Point &  pint 
) const
protected

Find directional intersection along the positive extension of the vector from p1 to p2.

Definition at line 256 of file MeshCut3DUserObject.C.

260 {
261  bool has_intersection = false;
262 
263  Plane elem_plane(vertices[0], vertices[1], vertices[2]);
264  Point point = vertices[0];
265  Point normal = elem_plane.unit_normal(point);
266 
267  std::array<Real, 3> plane_point = {{point(0), point(1), point(2)}};
268  std::array<Real, 3> planenormal = {{normal(0), normal(1), normal(2)}};
269  std::array<Real, 3> p_begin = {{p1(0), p1(1), p1(2)}};
270  std::array<Real, 3> p_end = {{p2(0), p2(1), p2(2)}};
271  std::array<Real, 3> cut_point = {{0.0, 0.0, 0.0}};
272 
274  &plane_point[0], &planenormal[0], &p_begin[0], &p_end[0], &cut_point[0]) == 1)
275  {
276  Point p(cut_point[0], cut_point[1], cut_point[2]);
277  Real dotp = ((p - p1) * (p2 - p1)) / ((p2 - p1) * (p2 - p1));
278  if (isInsideCutPlane(vertices, p) && dotp > 1)
279  {
280  pint = p;
281  has_intersection = true;
282  }
283  }
284  return has_intersection;
285 }

Referenced by findFrontIntersection().

◆ getCrackFrontPoints()

const std::vector< Point > MeshCut3DUserObject::getCrackFrontPoints ( unsigned int  ) const
overridevirtual

get a set of points along a crack front from a XFEM GeometricCutUserObject

Returns
A vector which contains all crack front points

Implements CrackFrontPointsProvider.

Definition at line 1085 of file MeshCut3DUserObject.C.

1086 {
1087  mooseError("getCrackFrontPoints() is not implemented for this object.");
1088 }

◆ getInterfaceID()

unsigned int GeometricCutUserObject::getInterfaceID ( ) const
inlineinherited

Get the interface ID for this cutting object.

Returns
the interface ID

Definition at line 172 of file GeometricCutUserObject.h.

172 { return _interface_id; };

◆ getRelativePosition()

Real MeshCut3DUserObject::getRelativePosition ( const Point &  p1,
const Point &  p2,
const Point &  p 
) const
protected

Get the relative position of p from p1.

Definition at line 296 of file MeshCut3DUserObject.C.

297 {
298  Real full_len = (p2 - p1).norm();
299  Real len_p1_p = (p - p1).norm();
300  return len_p1_p / full_len;
301 }

◆ growFront()

void MeshCut3DUserObject::growFront ( )
protected

Grow the cutter mesh.

Definition at line 745 of file MeshCut3DUserObject.C.

746 {
747  _front.clear();
748 
749  for (unsigned int i = 0; i < _active_boundary.size(); ++i)
750  {
751  std::vector<dof_id_type> temp;
752 
753  unsigned int i1 = 1;
754  unsigned int i2 = _active_boundary[i].size() - 1;
755  if (_inactive_boundary_pos.size() == 0)
756  {
757  i1 = 0;
758  i2 = _active_boundary[i].size();
759  }
760 
761  for (unsigned int j = i1; j < i2; ++j)
762  {
763  Node * this_node = _cut_mesh->node_ptr(_active_boundary[i][j]);
764  mooseAssert(this_node, "Node is NULL");
765  Point & this_point = *this_node;
766  Point dir = _active_direction[i][j];
767 
768  Point x;
769  for (unsigned int k = 0; k < LIBMESH_DIM; ++k)
770  x(k) = this_point(k) + dir(k) * _size_control;
771 
772  this_node = Node::build(x, _cut_mesh->n_nodes()).release();
773  _cut_mesh->add_node(this_node);
774 
775  dof_id_type id = _cut_mesh->n_nodes() - 1;
776  temp.push_back(id);
777  }
778 
779  _front.push_back(temp);
780  }
781 }

Referenced by initialize().

◆ initialize()

void MeshCut3DUserObject::initialize ( )
overridevirtual

Reimplemented from GeometricCutUserObject.

Definition at line 90 of file MeshCut3DUserObject.C.

91 {
92  if (_grow)
93  {
94  unsigned int timestep = _fe_problem.timeStep();
95 
96  if (timestep == 1)
98 
99  _stop = 0;
100 
101  if (timestep > 1 && timestep != _last_step_initialized)
102  {
103  _last_step_initialized = timestep;
104 
105  for (unsigned int i = 0; i < _n_step_growth; ++i)
107 
108  if (_stop != 1)
109  {
111  growFront();
112  sortFrontNodes();
113  if (_inactive_boundary_pos.size() != 0)
115  refineFront();
116  triangulation();
117  joinBoundary();
118  }
119  }
120  }
121 }

◆ initialSetup()

void MeshCut3DUserObject::initialSetup ( )
overridevirtual

Definition at line 78 of file MeshCut3DUserObject.C.

79 {
80  if (_grow)
81  {
86  }
87 }

◆ intersectWithEdge()

bool MeshCut3DUserObject::intersectWithEdge ( const Point &  p1,
const Point &  p2,
const std::vector< Point > &  _vertices,
Point &  pint 
) const
protectedvirtual

Check if a line intersects with an element.

Definition at line 225 of file MeshCut3DUserObject.C.

229 {
230  bool has_intersection = false;
231 
232  Plane elem_plane(vertices[0], vertices[1], vertices[2]);
233  Point point = vertices[0];
234  Point normal = elem_plane.unit_normal(point);
235 
236  std::array<Real, 3> plane_point = {{point(0), point(1), point(2)}};
237  std::array<Real, 3> planenormal = {{normal(0), normal(1), normal(2)}};
238  std::array<Real, 3> edge_point1 = {{p1(0), p1(1), p1(2)}};
239  std::array<Real, 3> edge_point2 = {{p2(0), p2(1), p2(2)}};
240  std::array<Real, 3> cut_point = {{0.0, 0.0, 0.0}};
241 
243  &plane_point[0], &planenormal[0], &edge_point1[0], &edge_point2[0], &cut_point[0]) == 1)
244  {
245  Point temp_p(cut_point[0], cut_point[1], cut_point[2]);
246  if (isInsideCutPlane(vertices, temp_p) && isInsideEdge(p1, p2, temp_p))
247  {
248  pint = temp_p;
249  has_intersection = true;
250  }
251  }
252  return has_intersection;
253 }

◆ isInsideCutPlane()

bool MeshCut3DUserObject::isInsideCutPlane ( const std::vector< Point > &  _vertices,
const Point &  p 
) const
protected

Check if point p is inside a plane.

Definition at line 304 of file MeshCut3DUserObject.C.

305 {
306  unsigned int n_node = vertices.size();
307 
308  Plane elem_plane(vertices[0], vertices[1], vertices[2]);
309  Point normal = elem_plane.unit_normal(vertices[0]);
310 
311  bool inside = false;
312  unsigned int counter = 0;
313 
314  for (unsigned int i = 0; i < n_node; ++i)
315  {
316  unsigned int iplus1 = (i < n_node - 1 ? i + 1 : 0);
317  Point middle2p = p - 0.5 * (vertices[i] + vertices[iplus1]);
318  const Point side_tang = vertices[iplus1] - vertices[i];
319  Point side_norm = side_tang.cross(normal);
320  Xfem::normalizePoint(middle2p);
321  Xfem::normalizePoint(side_norm);
322  if (middle2p * side_norm <= 0.0)
323  counter += 1;
324  }
325  if (counter == n_node)
326  inside = true;
327  return inside;
328 }

Referenced by findIntersection(), and intersectWithEdge().

◆ isInsideEdge()

bool MeshCut3DUserObject::isInsideEdge ( const Point &  p1,
const Point &  p2,
const Point &  p 
) const
protected

Check if point p is inside the edge p1-p2.

Definition at line 288 of file MeshCut3DUserObject.C.

289 {
290  Real dotp1 = (p1 - p) * (p2 - p1);
291  Real dotp2 = (p2 - p) * (p2 - p1);
292  return (dotp1 * dotp2 <= 0.0);
293 }

Referenced by intersectWithEdge().

◆ joinBoundary()

void MeshCut3DUserObject::joinBoundary ( )
protected

Join active boundaries and inactive boundaries to be the new boundary.

Definition at line 1045 of file MeshCut3DUserObject.C.

1046 {
1047  if (_inactive_boundary_pos.size() == 0)
1048  {
1049  _boundary = _front[0];
1050  _boundary.pop_back();
1051  return;
1052  }
1053 
1054  std::vector<dof_id_type> full_front;
1055 
1056  unsigned int size1 = _active_boundary.size();
1057 
1058  for (unsigned int i = 0; i < size1; ++i)
1059  {
1060  unsigned int size2 = _active_boundary[i].size();
1061 
1062  dof_id_type bd1 = _active_boundary[i][size2 - 1];
1063  dof_id_type bd2 = _active_boundary[i + 1 < size1 ? i + 1 : 0][0];
1064 
1065  full_front.insert(full_front.end(), _front[i].begin(), _front[i].end());
1066 
1067  auto it1 = std::find(_boundary.begin(), _boundary.end(), bd1);
1068  unsigned int pos1 = std::distance(_boundary.begin(), it1);
1069  auto it2 = std::find(_boundary.begin(), _boundary.end(), bd2);
1070  unsigned int pos2 = std::distance(_boundary.begin(), it2);
1071 
1072  if (pos1 <= pos2)
1073  full_front.insert(full_front.end(), _boundary.begin() + pos1, _boundary.begin() + pos2 + 1);
1074  else
1075  {
1076  full_front.insert(full_front.end(), _boundary.begin() + pos1, _boundary.end());
1077  full_front.insert(full_front.end(), _boundary.begin(), _boundary.begin() + pos2 + 1);
1078  }
1079  }
1080 
1081  _boundary = full_front;
1082 }

Referenced by initialize().

◆ refineBoundary()

void MeshCut3DUserObject::refineBoundary ( )
protected

If boundary nodes are too sparse, add nodes in between.

Definition at line 564 of file MeshCut3DUserObject.C.

565 {
566  std::vector<dof_id_type> new_boundary_order(_boundary.begin(), _boundary.end());
567 
568  mooseAssert(_boundary.size() >= 2, "Boundary should have at least two nodes");
569 
570  for (unsigned int i = _boundary.size() - 1; i >= 1; --i)
571  {
572  dof_id_type node1 = _boundary[i - 1];
573  dof_id_type node2 = _boundary[i];
574 
575  Real distance = findDistance(node1, node2);
576 
577  if (distance > _size_control)
578  {
579  unsigned int n = static_cast<unsigned int>(distance / _size_control);
580  std::array<Real, LIBMESH_DIM> x1;
581  std::array<Real, LIBMESH_DIM> x2;
582 
583  Node * n1 = _cut_mesh->node_ptr(node1);
584  mooseAssert(n1 != nullptr, "Node is NULL");
585  Point & p1 = *n1;
586  Node * n2 = _cut_mesh->node_ptr(node2);
587  mooseAssert(n2 != nullptr, "Node is NULL");
588  Point & p2 = *n2;
589 
590  for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
591  {
592  x1[j] = p1(j);
593  x2[j] = p2(j);
594  }
595 
596  for (unsigned int j = 0; j < n; ++j)
597  {
598  Point x;
599  for (unsigned int k = 0; k < LIBMESH_DIM; ++k)
600  x(k) = x2[k] - (x2[k] - x1[k]) * (j + 1) / (n + 1);
601 
602  Node * this_node = Node::build(x, _cut_mesh->n_nodes()).release();
603  _cut_mesh->add_node(this_node);
604 
605  dof_id_type id = _cut_mesh->n_nodes() - 1;
606  auto it = new_boundary_order.begin();
607  new_boundary_order.insert(it + i, id);
608  }
609  }
610  }
611 
612  _boundary = new_boundary_order;
613  mooseAssert(_boundary.size() > 0, "Boundary should not have zero size");
614  _boundary.pop_back();
615 }

Referenced by initialSetup().

◆ refineFront()

void MeshCut3DUserObject::refineFront ( )
protected

Refine the mesh at the front.

Definition at line 897 of file MeshCut3DUserObject.C.

898 {
899  std::vector<std::vector<dof_id_type>> new_front(_front.begin(), _front.end());
900 
901  for (unsigned int ifront = 0; ifront < _front.size(); ++ifront)
902  {
903  unsigned int i1 = _front[ifront].size() - 1;
904  if (_inactive_boundary_pos.size() == 0)
905  i1 = _front[ifront].size();
906 
907  for (unsigned int i = i1; i >= 1; --i)
908  {
909  unsigned int i2 = i;
910  if (_inactive_boundary_pos.size() == 0)
911  i2 = (i <= _front[ifront].size() - 1 ? i : 0);
912 
913  dof_id_type node1 = _front[ifront][i - 1];
914  dof_id_type node2 = _front[ifront][i2];
915  Real distance = findDistance(node1, node2);
916 
917  if (distance > _size_control)
918  {
919  unsigned int n = static_cast<int>(distance / _size_control);
920  std::array<Real, LIBMESH_DIM> x1;
921  std::array<Real, LIBMESH_DIM> x2;
922 
923  Node * this_node = _cut_mesh->node_ptr(node1);
924  mooseAssert(this_node, "Node is NULL");
925  Point & p1 = *this_node;
926  this_node = _cut_mesh->node_ptr(node2);
927  mooseAssert(this_node, "Node is NULL");
928  Point & p2 = *this_node;
929 
930  for (unsigned int j = 0; j < LIBMESH_DIM; ++j)
931  {
932  x1[j] = p1(j);
933  x2[j] = p2(j);
934  }
935 
936  for (unsigned int j = 0; j < n; ++j)
937  {
938  Point x;
939  for (unsigned int k = 0; k < LIBMESH_DIM; ++k)
940  x(k) = x2[k] - (x2[k] - x1[k]) * (j + 1) / (n + 1);
941 
942  Node * this_node = Node::build(x, _cut_mesh->n_nodes()).release();
943  _cut_mesh->add_node(this_node);
944 
945  dof_id_type id = _cut_mesh->n_nodes() - 1;
946 
947  auto it = new_front[ifront].begin();
948  new_front[ifront].insert(it + i, id);
949  }
950  }
951  }
952  }
953 
954  _front = new_front;
955 }

Referenced by initialize().

◆ serialize()

void GeometricCutUserObject::serialize ( std::string &  serialized_buffer)
protectedinherited

Methods to pack/unpack the _marked_elems_2d and _marked_elems_3d data into a structure suitable for parallel communication.

Definition at line 209 of file GeometricCutUserObject.C.

210 {
211  // stream for serializing the _marked_elems_2d and _marked_elems_3d data structures to a byte
212  // stream
213  std::ostringstream oss;
214  dataStore(oss, _marked_elems_2d, this);
215  dataStore(oss, _marked_elems_3d, this);
216 
217  // Populate the passed in string pointer with the string stream's buffer contents
218  serialized_buffer.assign(oss.str());
219 }

Referenced by GeometricCutUserObject::finalize().

◆ setInterfaceID()

void GeometricCutUserObject::setInterfaceID ( unsigned int  interface_id)
inlineinherited

Set the interface ID for this cutting object.

Parameters
theinterface ID

Definition at line 178 of file GeometricCutUserObject.h.

178 { _interface_id = interface_id; };

Referenced by XFEM::addGeometricCut().

◆ shouldHealMesh()

bool GeometricCutUserObject::shouldHealMesh ( ) const
inlineinherited

Should the elements cut by this cutting object be healed in the current time step?

Returns
true if the cut element should be healed

Definition at line 185 of file GeometricCutUserObject.h.

185 { return _heal_always; };

◆ sortBoundaryNodes()

void MeshCut3DUserObject::sortBoundaryNodes ( )
protected

Sort boundary nodes to be in the right order along the boundary.

Definition at line 493 of file MeshCut3DUserObject.C.

494 {
495  _boundary.clear();
496 
497  for (auto it = _boundary_edges.begin(); it != _boundary_edges.end(); ++it)
498  {
499  dof_id_type node1 = (*it)._id1;
500  dof_id_type node2 = (*it)._id2;
501 
502  mooseAssert(_boundary_map.find(node1) != _boundary_map.end(),
503  "_boundary_map does not have this key");
504  mooseAssert(_boundary_map.find(node2) != _boundary_map.end(),
505  "_boundary_map does not have this key");
506 
507  _boundary_map.find(node1)->second.push_back(node2);
508  _boundary_map.find(node2)->second.push_back(node1);
509  }
510 
511  auto it = _boundary_map.begin();
512  while (it != _boundary_map.end())
513  {
514  if (it->second.size() != 2)
515  mooseError(
516  "Boundary nodes in the cutter mesh must have exactly two neighbors; this one has: ",
517  it->second.size());
518  ++it;
519  }
520 
521  auto it2 = _boundary_edges.begin();
522  dof_id_type node1 = (*it2)._id1;
523  dof_id_type node2 = (*it2)._id2;
524  _boundary.push_back(node1);
525  _boundary.push_back(node2);
526 
527  for (unsigned int i = 0; i < _boundary_edges.size() - 1; ++i)
528  {
529  mooseAssert(_boundary_map.find(node2) != _boundary_map.end(),
530  "_boundary_map does not have this key");
531 
532  dof_id_type node3 = _boundary_map.find(node2)->second[0];
533  dof_id_type node4 = _boundary_map.find(node2)->second[1];
534 
535  if (node3 == node1)
536  {
537  _boundary.push_back(node4);
538  node1 = node2;
539  node2 = node4;
540  }
541  else if (node4 == node1)
542  {
543  _boundary.push_back(node3);
544  node1 = node2;
545  node2 = node3;
546  }
547  else
548  mooseError("Discontinuity in cutter boundary");
549  }
550 }

Referenced by initialSetup().

◆ sortFrontNodes()

void MeshCut3DUserObject::sortFrontNodes ( )
protected

Sort the front nodes.

Definition at line 784 of file MeshCut3DUserObject.C.

786 {
787 }

Referenced by initialize().

◆ threadJoin()

void GeometricCutUserObject::threadJoin ( const UserObject &  y)
overridevirtualinherited

Definition at line 133 of file GeometricCutUserObject.C.

134 {
135  const GeometricCutUserObject & gcuo = dynamic_cast<const GeometricCutUserObject &>(y);
136 
137  for (const auto & it : gcuo._marked_elems_2d)
138  {
139  mooseAssert(_marked_elems_2d.find(it.first) == _marked_elems_2d.end(),
140  "Element already inserted in map from a different thread");
141  _marked_elems_2d[it.first] = it.second;
142  }
143  for (const auto & it : gcuo._marked_elems_3d)
144  {
145  mooseAssert(_marked_elems_3d.find(it.first) == _marked_elems_3d.end(),
146  "Element already inserted in map from a different thread");
147  _marked_elems_3d[it.first] = it.second;
148  }
149 }

◆ triangulation()

void MeshCut3DUserObject::triangulation ( )
protected

Create tri3 elements between the new front and the old front.

Definition at line 958 of file MeshCut3DUserObject.C.

959 {
960 
961  mooseAssert(_active_boundary.size() == _front.size(),
962  "_active_boundary and _front should have the same size!");
963 
964  if (_inactive_boundary_pos.size() == 0)
965  {
966  _active_boundary[0].push_back(_active_boundary[0][0]);
967  _front[0].push_back(_front[0][0]);
968  }
969 
970  // loop over active segments
971  for (unsigned int k = 0; k < _front.size(); ++k)
972  {
973  unsigned int n1 = _active_boundary[k].size();
974  unsigned int n2 = _front[k].size();
975 
976  unsigned int i1 = 0;
977  unsigned int i2 = 0;
978 
979  // stop when all nodes are associated with an element
980  while (!(i1 == n1 - 1 && i2 == n2 - 1))
981  {
982  std::vector<dof_id_type> elem;
983 
984  dof_id_type p1 = _active_boundary[k][i1]; // node in the old front
985  dof_id_type p2 = _front[k][i2]; // node in the new front
986 
987  if (i1 != n1 - 1 && i2 != n2 - 1)
988  {
989  dof_id_type p3 = _active_boundary[k][i1 + 1]; // next node in the old front
990  dof_id_type p4 = _front[k][i2 + 1]; // next node in the new front
991 
992  elem.push_back(p1);
993  elem.push_back(p2);
994 
995  Real d1 = findDistance(p1, p4);
996  Real d2 = findDistance(p3, p2);
997 
998  if (d1 < d2)
999  {
1000  elem.push_back(p4);
1001  i2++;
1002  }
1003 
1004  else
1005  {
1006  elem.push_back(p3);
1007  i1++;
1008  }
1009  }
1010 
1011  else if (i1 == n1 - 1)
1012  {
1013  dof_id_type p4 = _front[k][i2 + 1]; // next node in the new front
1014 
1015  elem.push_back(p1);
1016  elem.push_back(p2);
1017  elem.push_back(p4);
1018  i2++;
1019  }
1020 
1021  else if (i2 == n2 - 1)
1022  {
1023  dof_id_type p3 = _active_boundary[k][i1 + 1]; // next node in the old front
1024 
1025  elem.push_back(p1);
1026  elem.push_back(p2);
1027  elem.push_back(p3);
1028  i1++;
1029  }
1030 
1031  Elem * new_elem = Elem::build(TRI3).release();
1032 
1033  for (unsigned int i = 0; i < _cut_elem_nnode; ++i)
1034  {
1035  mooseAssert(_cut_mesh->node_ptr(elem[i]) != nullptr, "Node is NULL");
1036  new_elem->set_node(i) = _cut_mesh->node_ptr(elem[i]);
1037  }
1038 
1039  _cut_mesh->add_elem(new_elem);
1040  }
1041  }
1042 }

Referenced by initialize().

◆ validParams()

InputParameters CrackFrontPointsProvider::validParams ( )
staticinherited

Definition at line 15 of file CrackFrontPointsProvider.C.

16 {
17  InputParameters params = ElementUserObject::validParams();
18  params.addClassDescription("Base class for a class that can provide a set of points along a "
19  "crack front. The virtual functions must be overridden by a derived "
20  "class to provide this functionality.");
21  return params;
22 }

Member Data Documentation

◆ _active_boundary

std::vector<std::vector<dof_id_type> > MeshCut3DUserObject::_active_boundary
protected

Active boundary nodes where growth is allowed.

Definition at line 89 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryDirection(), findActiveBoundaryNodes(), growFront(), joinBoundary(), and triangulation().

◆ _active_direction

std::vector<std::vector<Point> > MeshCut3DUserObject::_active_direction
protected

Growth direction for active boundaries.

Definition at line 92 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryDirection(), and growFront().

◆ _boundary

std::vector<dof_id_type> MeshCut3DUserObject::_boundary
protected

Boundary nodes of the cutter mesh.

Definition at line 80 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryNodes(), joinBoundary(), refineBoundary(), and sortBoundaryNodes().

◆ _boundary_edges

std::set<Xfem::CutEdge> MeshCut3DUserObject::_boundary_edges
protected

Edges at the boundary.

Definition at line 83 of file MeshCut3DUserObject.h.

Referenced by findBoundaryEdges(), and sortBoundaryNodes().

◆ _boundary_map

std::map<dof_id_type, std::vector<dof_id_type> > MeshCut3DUserObject::_boundary_map
protected

A map of boundary nodes and their neighbors.

Definition at line 86 of file MeshCut3DUserObject.h.

Referenced by findBoundaryEdges(), findBoundaryNodes(), and sortBoundaryNodes().

◆ _const_intersection

const Real MeshCut3DUserObject::_const_intersection = 0.01
protected

Used to define intersection points.

Definition at line 67 of file MeshCut3DUserObject.h.

Referenced by findFrontIntersection().

◆ _cut_elem_dim

const unsigned int MeshCut3DUserObject::_cut_elem_dim = 2
protected

Definition at line 58 of file MeshCut3DUserObject.h.

Referenced by MeshCut3DUserObject().

◆ _cut_elem_nnode

const unsigned int MeshCut3DUserObject::_cut_elem_nnode = 3
protected

The cutter mesh has triangluar elements only.

Definition at line 57 of file MeshCut3DUserObject.h.

Referenced by findBoundaryEdges(), findBoundaryNodes(), MeshCut3DUserObject(), and triangulation().

◆ _cut_mesh

std::unique_ptr<MeshBase> MeshCut3DUserObject::_cut_mesh
protected

◆ _elem_dim

const unsigned int MeshCut3DUserObject::_elem_dim = 3
protected

The structural mesh must be 3D only.

Definition at line 64 of file MeshCut3DUserObject.h.

◆ _front

std::vector<std::vector<dof_id_type> > MeshCut3DUserObject::_front
protected

New boundary after growth.

Definition at line 98 of file MeshCut3DUserObject.h.

Referenced by findFrontIntersection(), growFront(), joinBoundary(), refineFront(), and triangulation().

◆ _func_x

const Function& MeshCut3DUserObject::_func_x
protected

Parsed functions of front growth.

Definition at line 203 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryDirection().

◆ _func_y

const Function& MeshCut3DUserObject::_func_y
protected

Definition at line 204 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryDirection().

◆ _func_z

const Function& MeshCut3DUserObject::_func_z
protected

Definition at line 205 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryDirection().

◆ _grow

bool MeshCut3DUserObject::_grow
protected

Definition at line 77 of file MeshCut3DUserObject.h.

Referenced by initialize(), initialSetup(), and MeshCut3DUserObject().

◆ _heal_always

bool GeometricCutUserObject::_heal_always
protectedinherited

Heal the mesh.

Definition at line 195 of file GeometricCutUserObject.h.

◆ _inactive_boundary_pos

std::vector<unsigned int> MeshCut3DUserObject::_inactive_boundary_pos
protected

◆ _interface_id

unsigned int GeometricCutUserObject::_interface_id
protectedinherited

Associated interface id.

Definition at line 192 of file GeometricCutUserObject.h.

Referenced by GeometricCutUserObject::finalize(), and GeometricCutUserObject::GeometricCutUserObject().

◆ _last_step_initialized

unsigned int GeometricCutUserObject::_last_step_initialized
protectedinherited

Time step information needed to advance a 3D crack only at the real beginning of a time step.

Definition at line 198 of file GeometricCutUserObject.h.

Referenced by initialize().

◆ _marked_elems_2d

std::map<unsigned int, std::vector<Xfem::GeomMarkedElemInfo2D> > GeometricCutUserObject::_marked_elems_2d
protectedinherited

◆ _marked_elems_3d

std::map<unsigned int, std::vector<Xfem::GeomMarkedElemInfo3D> > GeometricCutUserObject::_marked_elems_3d
protectedinherited

◆ _mesh

MooseMesh& MeshCut3DUserObject::_mesh
protected

The structural mesh.

Definition at line 61 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryNodes(), and findFrontIntersection().

◆ _n_step_growth

unsigned int MeshCut3DUserObject::_n_step_growth
protected

Number of steps to grow the mesh.

Definition at line 73 of file MeshCut3DUserObject.h.

Referenced by initialize(), and MeshCut3DUserObject().

◆ _size_control

Real MeshCut3DUserObject::_size_control
protected

Used for cutter mesh refinement and front advancement.

Definition at line 70 of file MeshCut3DUserObject.h.

Referenced by growFront(), MeshCut3DUserObject(), refineBoundary(), and refineFront().

◆ _stop

bool MeshCut3DUserObject::_stop
protected

variables to help control the work flow

Definition at line 76 of file MeshCut3DUserObject.h.

Referenced by findActiveBoundaryNodes(), and initialize().

◆ _xfem

std::shared_ptr<XFEM> GeometricCutUserObject::_xfem
protectedinherited

The documentation for this class was generated from the following files:
MeshCut3DUserObject::findBoundaryNodes
void findBoundaryNodes()
Find boundary nodes of the cutter mesh This is a simple algorithm simply based on the added angle = 3...
Definition: MeshCut3DUserObject.C:331
GeometricCutUserObject::serialize
void serialize(std::string &serialized_buffer)
Methods to pack/unpack the _marked_elems_2d and _marked_elems_3d data into a structure suitable for p...
Definition: GeometricCutUserObject.C:209
MeshCut3DUserObject::findActiveBoundaryDirection
void findActiveBoundaryDirection()
Find growth direction at each active node.
Definition: MeshCut3DUserObject.C:678
Xfem::CutEdge::_id1
unsigned int _id1
ID of the first node on the edge.
Definition: GeometricCutUserObject.h:29
MeshCut3DUserObject::getRelativePosition
Real getRelativePosition(const Point &p1, const Point &p2, const Point &p) const
Get the relative position of p from p1.
Definition: MeshCut3DUserObject.C:296
EFAElement2D::isFinalCut
virtual bool isFinalCut() const
Definition: EFAElement2D.C:791
MeshCut3DUserObject::refineFront
void refineFront()
Refine the mesh at the front.
Definition: MeshCut3DUserObject.C:897
Xfem::GeomMarkedElemInfo2D
Data structure describing geometrically described cut through 2D element.
Definition: GeometricCutUserObject.h:75
EFAElement3D::isFinalCut
virtual bool isFinalCut() const
Definition: EFAElement3D.C:838
GeometricCutUserObject::_xfem
std::shared_ptr< XFEM > _xfem
Pointer to the XFEM controller object.
Definition: GeometricCutUserObject.h:185
MeshCut3DUserObject::_func_y
const Function & _func_y
Definition: MeshCut3DUserObject.h:204
MeshCut3DUserObject::isInsideEdge
bool isInsideEdge(const Point &p1, const Point &p2, const Point &p) const
Check if point p is inside the edge p1-p2.
Definition: MeshCut3DUserObject.C:288
MeshCut3DUserObject::_func_z
const Function & _func_z
Definition: MeshCut3DUserObject.h:205
MeshCut3DUserObject::refineBoundary
void refineBoundary()
If boundary nodes are too sparse, add nodes in between.
Definition: MeshCut3DUserObject.C:564
MeshCut3DUserObject::_grow
bool _grow
Definition: MeshCut3DUserObject.h:77
MeshCut3DUserObject::findBoundaryEdges
void findBoundaryEdges()
Find boundary edges of the cutter mesh.
Definition: MeshCut3DUserObject.C:373
GeometricCutUserObject::deserialize
void deserialize(std::vector< std::string > &serialized_buffers)
Definition: GeometricCutUserObject.C:222
counter
static unsigned int counter
Definition: ContactPenetrationAuxAction.C:17
MeshCut3DUserObject::_size_control
Real _size_control
Used for cutter mesh refinement and front advancement.
Definition: MeshCut3DUserObject.h:70
Xfem::CutFace::_position
std::vector< Real > _position
Fractional distance along the cut edges where the cut is located.
Definition: GeometricCutUserObject.h:71
Xfem::CutEdge::_id2
unsigned int _id2
ID of the second node on the edge.
Definition: GeometricCutUserObject.h:31
Xfem::GeomMarkedElemInfo2D::_elem_cut_edges
std::vector< CutEdge > _elem_cut_edges
Container for data about all cut edges in this element.
Definition: GeometricCutUserObject.h:78
Xfem::GeomMarkedElemInfo2D::_elem_cut_nodes
std::vector< CutNode > _elem_cut_nodes
Container for data about all cut nodes in this element.
Definition: GeometricCutUserObject.h:80
MeshCut3DUserObject::findActiveBoundaryNodes
void findActiveBoundaryNodes()
Find all active boundary nodes in the cutter mesh Find boundary nodes that will grow; nodes outside o...
Definition: MeshCut3DUserObject.C:618
Xfem::GeomMarkedElemInfo2D::_frag_edges
std::vector< std::vector< Point > > _frag_edges
Container for data about all cut edges in cut fragments in this element.
Definition: GeometricCutUserObject.h:84
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
MeshCut3DUserObject::_front
std::vector< std::vector< dof_id_type > > _front
New boundary after growth.
Definition: MeshCut3DUserObject.h:98
Xfem::CutFace::_face_id
unsigned int _face_id
ID of the cut face.
Definition: GeometricCutUserObject.h:67
MeshCut3DUserObject::_active_boundary
std::vector< std::vector< dof_id_type > > _active_boundary
Active boundary nodes where growth is allowed.
Definition: MeshCut3DUserObject.h:89
EFAElement3D
Definition: EFAElement3D.h:20
MeshCut3DUserObject::_mesh
MooseMesh & _mesh
The structural mesh.
Definition: MeshCut3DUserObject.h:61
MeshCut3DUserObject::_boundary_edges
std::set< Xfem::CutEdge > _boundary_edges
Edges at the boundary.
Definition: MeshCut3DUserObject.h:83
MeshCut3DUserObject::_boundary
std::vector< dof_id_type > _boundary
Boundary nodes of the cutter mesh.
Definition: MeshCut3DUserObject.h:80
MeshCut3DUserObject::sortBoundaryNodes
void sortBoundaryNodes()
Sort boundary nodes to be in the right order along the boundary.
Definition: MeshCut3DUserObject.C:493
MeshCut3DUserObject::findDistance
Real findDistance(dof_id_type node1, dof_id_type node2)
Find distance between two nodes.
Definition: MeshCut3DUserObject.C:553
MeshCut3DUserObject::findIntersection
bool findIntersection(const Point &p1, const Point &p2, const std::vector< Point > &vertices, Point &pint) const
Find directional intersection along the positive extension of the vector from p1 to p2.
Definition: MeshCut3DUserObject.C:256
MeshCut3DUserObject::isInsideCutPlane
bool isInsideCutPlane(const std::vector< Point > &_vertices, const Point &p) const
Check if point p is inside a plane.
Definition: MeshCut3DUserObject.C:304
Xfem::CutFace::_face_edge
std::vector< unsigned int > _face_edge
IDs of all cut faces.
Definition: GeometricCutUserObject.h:69
GeometricCutUserObject::_marked_elems_3d
std::map< unsigned int, std::vector< Xfem::GeomMarkedElemInfo3D > > _marked_elems_3d
Definition: GeometricCutUserObject.h:202
MeshCut3DUserObject::_const_intersection
const Real _const_intersection
Used to define intersection points.
Definition: MeshCut3DUserObject.h:67
GeometricCutUserObject::cutFragmentByGeometry
virtual bool cutFragmentByGeometry(std::vector< std::vector< Point >> &frag_edges, std::vector< Xfem::CutEdge > &cut_edges, Real time) const =0
Check to see whether a fragment of a 2D element should be cut based on geometric conditions.
dataLoad
void dataLoad(std::istream &stream, Xfem::CutFace &cf, void *context)
Definition: GeometricCutUserObject.C:163
dataStore
void dataStore(std::ostream &stream, Xfem::CutFace &cf, void *context)
Definition: GeometricCutUserObject.C:154
GeometricCutUserObject::_last_step_initialized
unsigned int _last_step_initialized
Time step information needed to advance a 3D crack only at the real beginning of a time step.
Definition: GeometricCutUserObject.h:198
Xfem::GeomMarkedElemInfo3D
Data structure describing geometrically described cut through 3D element.
Definition: GeometricCutUserObject.h:88
Xfem::GeomMarkedElemInfo2D::_frag_cut_edges
std::vector< CutEdge > _frag_cut_edges
Container for data about all cut fragments in this element.
Definition: GeometricCutUserObject.h:82
MeshCut3DUserObject::_cut_elem_dim
const unsigned int _cut_elem_dim
Definition: MeshCut3DUserObject.h:58
validParams
InputParameters validParams()
GeometricCutUserObject::_interface_id
unsigned int _interface_id
Associated interface id.
Definition: GeometricCutUserObject.h:192
MeshCut3DUserObject::_boundary_map
std::map< dof_id_type, std::vector< dof_id_type > > _boundary_map
A map of boundary nodes and their neighbors.
Definition: MeshCut3DUserObject.h:86
GeometricCutUserObject::_marked_elems_2d
std::map< unsigned int, std::vector< Xfem::GeomMarkedElemInfo2D > > _marked_elems_2d
Containers with information about all 2D and 3D elements marked for cutting by this object.
Definition: GeometricCutUserObject.h:201
MeshCut3DUserObject::_func_x
const Function & _func_x
Parsed functions of front growth.
Definition: MeshCut3DUserObject.h:203
MeshCut3DUserObject::_active_direction
std::vector< std::vector< Point > > _active_direction
Growth direction for active boundaries.
Definition: MeshCut3DUserObject.h:92
MeshCut3DUserObject::_n_step_growth
unsigned int _n_step_growth
Number of steps to grow the mesh.
Definition: MeshCut3DUserObject.h:73
MeshCut3DUserObject::sortFrontNodes
void sortFrontNodes()
Sort the front nodes.
Definition: MeshCut3DUserObject.C:784
MeshCut3DUserObject::_cut_mesh
std::unique_ptr< MeshBase > _cut_mesh
The cutter mesh.
Definition: MeshCut3DUserObject.h:54
Xfem::normalizePoint
void normalizePoint(Point &p)
Definition: XFEMFuncs.C:621
MeshCut3DUserObject::joinBoundary
void joinBoundary()
Join active boundaries and inactive boundaries to be the new boundary.
Definition: MeshCut3DUserObject.C:1045
GeometricCutUserObject::_heal_always
bool _heal_always
Heal the mesh.
Definition: GeometricCutUserObject.h:195
MeshCut3DUserObject::findFrontIntersection
void findFrontIntersection()
Find front-structure intersections.
Definition: MeshCut3DUserObject.C:790
GeometricCutUserObject::cutElementByGeometry
virtual bool cutElementByGeometry(const Elem *elem, std::vector< Xfem::CutEdge > &cut_edges, std::vector< Xfem::CutNode > &cut_nodes, Real time) const =0
Check to see whether a specified 2D element should be cut based on geometric conditions.
GeometricCutUserObject::GeometricCutUserObject
GeometricCutUserObject(const InputParameters &parameters)
Factory constructor, takes parameters so that all derived classes can be built using the same constru...
Definition: GeometricCutUserObject.C:39
MeshCut3DUserObject::_cut_elem_nnode
const unsigned int _cut_elem_nnode
The cutter mesh has triangluar elements only.
Definition: MeshCut3DUserObject.h:57
Xfem::GeomMarkedElemInfo3D::_frag_faces
std::vector< std::vector< Point > > _frag_faces
Container for data about all cut faces in cut fragments in this element.
Definition: GeometricCutUserObject.h:95
MeshCut3DUserObject::_stop
bool _stop
variables to help control the work flow
Definition: MeshCut3DUserObject.h:76
MeshCut3DUserObject::intersectWithEdge
virtual bool intersectWithEdge(const Point &p1, const Point &p2, const std::vector< Point > &_vertices, Point &pint) const
Check if a line intersects with an element.
Definition: MeshCut3DUserObject.C:225
Xfem::GeomMarkedElemInfo3D::_frag_cut_faces
std::vector< CutFace > _frag_cut_faces
Container for data about all faces this element's fragment.
Definition: GeometricCutUserObject.h:93
EFAElement2D::numFragments
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:202
EFAElement2D
Definition: EFAElement2D.h:20
MeshCut3DUserObject::triangulation
void triangulation()
Create tri3 elements between the new front and the old front.
Definition: MeshCut3DUserObject.C:958
Xfem::CutFace
Data structure defining a cut through a face.
Definition: GeometricCutUserObject.h:64
Xfem::angle_rad_3d
double angle_rad_3d(double p1[3], double p2[3], double p3[3])
Definition: XFEMFuncs.C:691
MeshCut3DUserObject::_elem_dim
const unsigned int _elem_dim
The structural mesh must be 3D only.
Definition: MeshCut3DUserObject.h:64
Xfem::GeomMarkedElemInfo3D::_elem_cut_faces
std::vector< CutFace > _elem_cut_faces
Container for data about all cut faces in this element.
Definition: GeometricCutUserObject.h:91
Xfem::CutEdge
Data structure defining a cut on an element edge.
Definition: GeometricCutUserObject.h:26
MeshCut3DUserObject::growFront
void growFront()
Grow the cutter mesh.
Definition: MeshCut3DUserObject.C:745
MeshCut3DUserObject::_inactive_boundary_pos
std::vector< unsigned int > _inactive_boundary_pos
Inactive boundary.
Definition: MeshCut3DUserObject.h:95