www.mooseframework.org
Public Member Functions | Private Member Functions | Private Attributes | List of all members
XFEM Class Reference

This is the XFEM class. More...

#include <XFEM.h>

Inheritance diagram for XFEM:
[legend]

Public Member Functions

 XFEM (const InputParameters &params)
 
 ~XFEM ()
 
void addGeometricCut (GeometricCutUserObject *geometric_cut)
 
void addStateMarkedElem (unsigned int elem_id, RealVectorValue &normal)
 
void addStateMarkedElem (unsigned int elem_id, RealVectorValue &normal, unsigned int marked_side)
 
void addStateMarkedFrag (unsigned int elem_id, RealVectorValue &normal)
 
void clearStateMarkedElems ()
 
void addGeomMarkedElem2D (const unsigned int elem_id, const Xfem::GeomMarkedElemInfo2D geom_info, const unsigned int interface_id)
 Add information about a new cut to be performed on a specific 2d element. More...
 
void addGeomMarkedElem3D (const unsigned int elem_id, const Xfem::GeomMarkedElemInfo3D geom_info, const unsigned int interface_id)
 Add information about a new cut to be performed on a specific 3d element. More...
 
void clearGeomMarkedElems ()
 Clear out the list of elements to be marked for cutting. More...
 
virtual bool update (Real time, NonlinearSystemBase &nl, AuxiliarySystem &aux) override
 
virtual void initSolution (NonlinearSystemBase &nl, AuxiliarySystem &aux) override
 
void buildEFAMesh ()
 
bool markCuts (Real time)
 
bool markCutEdgesByGeometry ()
 
bool markCutEdgesByState (Real time)
 
bool markCutFacesByGeometry ()
 
bool markCutFacesByState ()
 
bool initCutIntersectionEdge (Point cut_origin, RealVectorValue cut_normal, Point &edge_p1, Point &edge_p2, Real &dist)
 
bool cutMeshWithEFA (NonlinearSystemBase &nl, AuxiliarySystem &aux)
 
bool healMesh ()
 Potentially heal the mesh by merging some of the pairs of partial elements cut by XFEM back into single elements if indicated by the cutting objects. More...
 
virtual bool updateHeal () override
 
Point getEFANodeCoords (EFANode *CEMnode, EFAElement *CEMElem, const Elem *elem, MeshBase *displaced_mesh=NULL) const
 
Real getPhysicalVolumeFraction (const Elem *elem) const
 Get the volume fraction of an element that is physical. More...
 
bool isPointInsidePhysicalDomain (const Elem *elem, const Point &point) const
 Return true if the point is inside the element physical domain Note: if this element is not cut, return true too. More...
 
Real getCutPlane (const Elem *elem, const Xfem::XFEM_CUTPLANE_QUANTITY quantity, unsigned int plane_id) const
 Get specified component of normal or origin for cut plane for a given element. More...
 
bool isElemAtCrackTip (const Elem *elem) const
 
bool isElemCut (const Elem *elem, XFEMCutElem *&xfce) const
 
bool isElemCut (const Elem *elem) const
 
void getFragmentFaces (const Elem *elem, std::vector< std::vector< Point >> &frag_faces, bool displaced_mesh=false) const
 
void storeCrackTipOriginAndDirection ()
 
void correctCrackExtensionDirection (const Elem *elem, EFAElement2D *CEMElem, EFAEdge *orig_edge, Point normal, Point crack_tip_origin, Point crack_tip_direction, Real &distance_keep, unsigned int &edge_id_keep, Point &normal_keep)
 
void getCrackTipOrigin (std::map< unsigned int, const Elem * > &elem_id_crack_tip, std::vector< Point > &crack_front_points)
 
Xfem::XFEM_QRULEgetXFEMQRule ()
 
void setXFEMQRule (std::string &xfem_qrule)
 
void setCrackGrowthMethod (bool use_crack_growth_increment, Real crack_growth_increment)
 
void setDebugOutputLevel (unsigned int debug_output_level)
 Controls amount of debugging information output. More...
 
virtual bool getXFEMWeights (MooseArray< Real > &weights, const Elem *elem, QBase *qrule, const MooseArray< Point > &q_points) override
 
virtual bool getXFEMFaceWeights (MooseArray< Real > &weights, const Elem *elem, QBase *qrule, const MooseArray< Point > &q_points, unsigned int side) override
 
virtual const ElementPairLocator::ElementPairList * getXFEMCutElemPairs (unsigned int interface_id)
 Get the list of cut element pairs corresponding to a given interface ID. More...
 
virtual const ElementPairLocator::ElementPairList * getXFEMDisplacedCutElemPairs (unsigned int interface_id)
 Get the list of cut element pairs on the displaced mesh corresponding to a given interface ID. More...
 
virtual unsigned int getGeometricCutID (const GeometricCutUserObject *gcu)
 Get the interface ID corresponding to a given GeometricCutUserObject. More...
 
virtual void getXFEMIntersectionInfo (const Elem *elem, unsigned int plane_id, Point &normal, std::vector< Point > &intersectionPoints, bool displaced_mesh=false) const
 
virtual void getXFEMqRuleOnLine (std::vector< Point > &intersection_points, std::vector< Point > &quad_pts, std::vector< Real > &quad_wts) const
 
virtual void getXFEMqRuleOnSurface (std::vector< Point > &intersection_points, std::vector< Point > &quad_pts, std::vector< Real > &quad_wts) const
 
bool has_secondary_cut ()
 
EFAElement2DgetEFAElem2D (const Elem *elem)
 Get the EFAElement2D object for a specified libMesh element. More...
 
EFAElement3DgetEFAElem3D (const Elem *elem)
 Get the EFAElement3D object for a specified libMesh element. More...
 
void getFragmentEdges (const Elem *elem, EFAElement2D *CEMElem, std::vector< std::vector< Point >> &frag_edges) const
 
void getFragmentFaces (const Elem *elem, EFAElement3D *CEMElem, std::vector< std::vector< Point >> &frag_faces) const
 
const std::map< const Elem *, std::vector< Point > > & getCrackTipOriginMap () const
 

Private Member Functions

void storeSolutionForNode (const Node *node_to_store_to, const Node *node_to_store_from, SystemBase &sys, std::map< unique_id_type, std::vector< Real >> &stored_solution, const NumericVector< Number > &current_solution, const NumericVector< Number > &old_solution, const NumericVector< Number > &older_solution)
 Store the solution in stored_solution for a given node. More...
 
void storeSolutionForElement (const Elem *elem_to_store_to, const Elem *elem_to_store_from, SystemBase &sys, std::map< unique_id_type, std::vector< Real >> &stored_solution, const NumericVector< Number > &current_solution, const NumericVector< Number > &old_solution, const NumericVector< Number > &older_solution)
 Store the solution in stored_solution for a given element. More...
 
void setSolution (SystemBase &sys, const std::map< unique_id_type, std::vector< Real >> &stored_solution, NumericVector< Number > &current_solution, NumericVector< Number > &old_solution, NumericVector< Number > &older_solution)
 Set the solution for all locally-owned nodes/elements that have stored values. More...
 
void setSolutionForDOFs (const std::vector< Real > &stored_solution, const std::vector< dof_id_type > &stored_solution_dofs, NumericVector< Number > &current_solution, NumericVector< Number > &old_solution, NumericVector< Number > &older_solution)
 Set the solution for a set of DOFs. More...
 
std::vector< dof_id_type > getElementSolutionDofs (const Elem *elem, SystemBase &sys) const
 Get a vector of the dof indices for all components of all variables associated with an element. More...
 
std::vector< dof_id_type > getNodeSolutionDofs (const Node *node, SystemBase &sys) const
 Get a vector of the dof indices for all components of all variables associated with a node. More...
 

Private Attributes

bool _has_secondary_cut
 
Xfem::XFEM_QRULE _XFEM_qrule
 
bool _use_crack_growth_increment
 
Real _crack_growth_increment
 
std::vector< const GeometricCutUserObject * > _geometric_cuts
 
std::map< unique_id_type, XFEMCutElem * > _cut_elem_map
 
std::set< const Elem * > _crack_tip_elems
 
std::set< const Elem * > _crack_tip_elems_to_be_healed
 
std::map< unsigned int, ElementPairLocator::ElementPairList > _sibling_elems
 
std::map< unsigned int, ElementPairLocator::ElementPairList > _sibling_displaced_elems
 
std::map< const Elem *, std::vector< Point > > _elem_crack_origin_direction_map
 
std::map< const Elem *, RealVectorValue > _state_marked_elems
 
std::set< const Elem * > _state_marked_frags
 
std::map< const Elem *, unsigned int > _state_marked_elem_sides
 
std::map< const Elem *, std::vector< Xfem::GeomMarkedElemInfo2D > > _geom_marked_elems_2d
 Data structure for storing information about all 2D elements to be cut by geometry. More...
 
std::map< const Elem *, std::vector< Xfem::GeomMarkedElemInfo3D > > _geom_marked_elems_3d
 Data structure for storing information about all 3D elements to be cut by geometry. More...
 
std::map< unsigned int, std::set< unsigned int > > _geom_marker_id_elems
 Data structure for storing the elements cut by specific geometric cutters. More...
 
std::map< const GeometricCutUserObject *, unsigned int > _geom_marker_id_map
 Data structure for storing the GeommetricCutUserObjects and their corresponding id. More...
 
ElementFragmentAlgorithm _efa_mesh
 
unsigned int _debug_output_level
 Controls amount of debugging output information 0: None 1: Summary 2: Details on modifications to mesh 3: Full dump of element fragment algorithm mesh. More...
 
std::map< unique_id_type, std::vector< Real > > _cached_solution
 Data structure to store the nonlinear solution for nodes/elements affected by XFEM For each node/element, this is stored as a vector that contains all components of all applicable variables in an order defined by getElementSolutionDofs() or getNodeSolutionDofs(). More...
 
std::map< unique_id_type, std::vector< Real > > _cached_aux_solution
 Data structure to store the auxiliary solution for nodes/elements affected by XFEM For each node/element, this is stored as a vector that contains all components of all applicable variables in an order defined by getElementSolutionDofs() or getNodeSolutionDofs(). More...
 

Detailed Description

This is the XFEM class.

This class implements algorithms for dynamic mesh modification in support of a phantom node approach for XFEM

Definition at line 61 of file XFEM.h.

Constructor & Destructor Documentation

◆ XFEM()

XFEM::XFEM ( const InputParameters &  params)
explicit

Definition at line 35 of file XFEM.C.

36  : XFEMInterface(params), _efa_mesh(Moose::out), _debug_output_level(1)
37 {
38 #ifndef LIBMESH_ENABLE_UNIQUE_ID
39  mooseError("MOOSE requires unique ids to be enabled in libmesh (configure with "
40  "--enable-unique-id) to use XFEM!");
41 #endif
42  _has_secondary_cut = false;
43 }

◆ ~XFEM()

XFEM::~XFEM ( )

Definition at line 45 of file XFEM.C.

46 {
47  for (std::map<unique_id_type, XFEMCutElem *>::iterator cemit = _cut_elem_map.begin();
48  cemit != _cut_elem_map.end();
49  ++cemit)
50  delete cemit->second;
51 }

Member Function Documentation

◆ addGeometricCut()

void XFEM::addGeometricCut ( GeometricCutUserObject geometric_cut)

Definition at line 54 of file XFEM.C.

55 {
56  _geometric_cuts.push_back(geometric_cut);
57 
58  geometric_cut->setInterfaceID(_geometric_cuts.size() - 1);
59 
60  _geom_marker_id_map[geometric_cut] = _geometric_cuts.size() - 1;
61 }

◆ addGeomMarkedElem2D()

void XFEM::addGeomMarkedElem2D ( const unsigned int  elem_id,
const Xfem::GeomMarkedElemInfo2D  geom_info,
const unsigned int  interface_id 
)

Add information about a new cut to be performed on a specific 2d element.

Parameters
elem_idThe id of the element to be cut
geom_infoThe object containing information about the cut to be performed
interface_idThe ID of the interface

Definition at line 162 of file XFEM.C.

165 {
166  Elem * elem = _mesh->elem_ptr(elem_id);
167  _geom_marked_elems_2d[elem].push_back(geom_info);
168  _geom_marker_id_elems[interface_id].insert(elem_id);
169 }

◆ addGeomMarkedElem3D()

void XFEM::addGeomMarkedElem3D ( const unsigned int  elem_id,
const Xfem::GeomMarkedElemInfo3D  geom_info,
const unsigned int  interface_id 
)

Add information about a new cut to be performed on a specific 3d element.

Parameters
elem_idThe id of the element to be cut
geom_infoThe object containing information about the cut to be performed
interface_idThe ID of the interface

Definition at line 172 of file XFEM.C.

175 {
176  Elem * elem = _mesh->elem_ptr(elem_id);
177  _geom_marked_elems_3d[elem].push_back(geom_info);
178  _geom_marker_id_elems[interface_id].insert(elem_id);
179 }

◆ addStateMarkedElem() [1/2]

void XFEM::addStateMarkedElem ( unsigned int  elem_id,
RealVectorValue &  normal 
)

Definition at line 112 of file XFEM.C.

113 {
114  Elem * elem = _mesh->elem_ptr(elem_id);
115  std::map<const Elem *, RealVectorValue>::iterator mit;
116  mit = _state_marked_elems.find(elem);
117  if (mit != _state_marked_elems.end())
118  mooseError(" ERROR: element ", elem->id(), " already marked for crack growth.");
119  _state_marked_elems[elem] = normal;
120 }

Referenced by addStateMarkedElem(), and addStateMarkedFrag().

◆ addStateMarkedElem() [2/2]

void XFEM::addStateMarkedElem ( unsigned int  elem_id,
RealVectorValue &  normal,
unsigned int  marked_side 
)

Definition at line 123 of file XFEM.C.

124 {
125  addStateMarkedElem(elem_id, normal);
126  Elem * elem = _mesh->elem_ptr(elem_id);
127  std::map<const Elem *, unsigned int>::iterator mit;
128  mit = _state_marked_elem_sides.find(elem);
129  if (mit != _state_marked_elem_sides.end())
130  {
131  mooseError(" ERROR: side of element ", elem->id(), " already marked for crack initiation.");
132  exit(1);
133  }
134  _state_marked_elem_sides[elem] = marked_side;
135 }

◆ addStateMarkedFrag()

void XFEM::addStateMarkedFrag ( unsigned int  elem_id,
RealVectorValue &  normal 
)

Definition at line 138 of file XFEM.C.

139 {
140  addStateMarkedElem(elem_id, normal);
141  Elem * elem = _mesh->elem_ptr(elem_id);
142  std::set<const Elem *>::iterator mit;
143  mit = _state_marked_frags.find(elem);
144  if (mit != _state_marked_frags.end())
145  {
146  mooseError(
147  " ERROR: element ", elem->id(), " already marked for fragment-secondary crack initiation.");
148  exit(1);
149  }
150  _state_marked_frags.insert(elem);
151 }

◆ buildEFAMesh()

void XFEM::buildEFAMesh ( )

Definition at line 340 of file XFEM.C.

341 {
342  _efa_mesh.reset();
343 
344  // Load all existing elements in to EFA mesh
345  for (auto & elem : _mesh->element_ptr_range())
346  {
347  std::vector<unsigned int> quad;
348  for (unsigned int i = 0; i < elem->n_nodes(); ++i)
349  quad.push_back(elem->node_id(i));
350  if (_mesh->mesh_dimension() == 2)
351  _efa_mesh.add2DElement(quad, elem->id());
352  else if (_mesh->mesh_dimension() == 3)
353  _efa_mesh.add3DElement(quad, elem->id());
354  else
355  mooseError("XFEM only works for 2D and 3D");
356  }
357 
358  // Restore fragment information for elements that have been previously cut
359  for (auto & elem : _mesh->element_ptr_range())
360  {
361  std::map<unique_id_type, XFEMCutElem *>::iterator cemit = _cut_elem_map.find(elem->unique_id());
362  if (cemit != _cut_elem_map.end())
363  {
364  XFEMCutElem * xfce = cemit->second;
365  EFAElement * CEMElem = _efa_mesh.getElemByID(elem->id());
366  _efa_mesh.restoreFragmentInfo(CEMElem, xfce->getEFAElement());
367  }
368  }
369 
370  // Must update edge neighbors before restore edge intersections. Otherwise, when we
371  // add edge intersections, we do not have neighbor information to use.
372  // Correction: no need to use neighbor info now
375 }

Referenced by update().

◆ clearGeomMarkedElems()

void XFEM::clearGeomMarkedElems ( )

Clear out the list of elements to be marked for cutting.

Called after cutting is done.

Definition at line 182 of file XFEM.C.

183 {
184  _geom_marked_elems_2d.clear();
185  _geom_marked_elems_3d.clear();
186 }

Referenced by update().

◆ clearStateMarkedElems()

void XFEM::clearStateMarkedElems ( )

Definition at line 154 of file XFEM.C.

155 {
156  _state_marked_elems.clear();
157  _state_marked_frags.clear();
158  _state_marked_elem_sides.clear();
159 }

Referenced by update().

◆ correctCrackExtensionDirection()

void XFEM::correctCrackExtensionDirection ( const Elem *  elem,
EFAElement2D CEMElem,
EFAEdge orig_edge,
Point  normal,
Point  crack_tip_origin,
Point  crack_tip_direction,
Real &  distance_keep,
unsigned int &  edge_id_keep,
Point &  normal_keep 
)

Definition at line 447 of file XFEM.C.

456 {
457  std::vector<Point> edge_ends(2, Point(0.0, 0.0, 0.0));
458  Point edge1(0.0, 0.0, 0.0);
459  Point edge2(0.0, 0.0, 0.0);
460  Point left_angle(0.0, 0.0, 0.0);
461  Point right_angle(0.0, 0.0, 0.0);
462  Point left_angle_normal(0.0, 0.0, 0.0);
463  Point right_angle_normal(0.0, 0.0, 0.0);
464  Point crack_direction_normal(0.0, 0.0, 0.0);
465  Point edge1_to_tip(0.0, 0.0, 0.0);
466  Point edge2_to_tip(0.0, 0.0, 0.0);
467  Point edge1_to_tip_normal(0.0, 0.0, 0.0);
468  Point edge2_to_tip_normal(0.0, 0.0, 0.0);
469 
470  Real cos_45 = std::cos(45.0 / 180.0 * 3.14159);
471  Real sin_45 = std::sin(45.0 / 180.0 * 3.14159);
472 
473  left_angle(0) = cos_45 * crack_tip_direction(0) - sin_45 * crack_tip_direction(1);
474  left_angle(1) = sin_45 * crack_tip_direction(0) + cos_45 * crack_tip_direction(1);
475 
476  right_angle(0) = cos_45 * crack_tip_direction(0) + sin_45 * crack_tip_direction(1);
477  right_angle(1) = -sin_45 * crack_tip_direction(0) + cos_45 * crack_tip_direction(1);
478 
479  left_angle_normal(0) = -left_angle(1);
480  left_angle_normal(1) = left_angle(0);
481 
482  right_angle_normal(0) = -right_angle(1);
483  right_angle_normal(1) = right_angle(0);
484 
485  crack_direction_normal(0) = -crack_tip_direction(1);
486  crack_direction_normal(1) = crack_tip_direction(0);
487 
488  Real angle_min = 0.0;
489  Real distance = 0.0;
490  unsigned int nsides = CEMElem->numEdges();
491 
492  for (unsigned int i = 0; i < nsides; ++i)
493  {
494  if (!orig_edge->isPartialOverlap(*CEMElem->getEdge(i)))
495  {
496  edge_ends[0] = getEFANodeCoords(CEMElem->getEdge(i)->getNode(0), CEMElem, elem);
497  edge_ends[1] = getEFANodeCoords(CEMElem->getEdge(i)->getNode(1), CEMElem, elem);
498 
499  edge1_to_tip = (edge_ends[0] * 0.95 + edge_ends[1] * 0.05) - crack_tip_origin;
500  edge2_to_tip = (edge_ends[0] * 0.05 + edge_ends[1] * 0.95) - crack_tip_origin;
501 
502  edge1_to_tip /= pow(edge1_to_tip.norm_sq(), 0.5);
503  edge2_to_tip /= pow(edge2_to_tip.norm_sq(), 0.5);
504 
505  edge1_to_tip_normal(0) = -edge1_to_tip(1);
506  edge1_to_tip_normal(1) = edge1_to_tip(0);
507 
508  edge2_to_tip_normal(0) = -edge2_to_tip(1);
509  edge2_to_tip_normal(1) = edge2_to_tip(0);
510 
511  Real angle_edge1_normal = edge1_to_tip_normal * normal;
512  Real angle_edge2_normal = edge2_to_tip_normal * normal;
513 
514  if (std::abs(angle_edge1_normal) > std::abs(angle_min) &&
515  (edge1_to_tip * crack_tip_direction) > std::cos(45.0 / 180.0 * 3.14159))
516  {
517  edge_id_keep = i;
518  distance_keep = 0.05;
519  normal_keep = edge1_to_tip_normal;
520  angle_min = angle_edge1_normal;
521  }
522  else if (std::abs(angle_edge2_normal) > std::abs(angle_min) &&
523  (edge2_to_tip * crack_tip_direction) > std::cos(45.0 / 180.0 * 3.14159))
524  {
525  edge_id_keep = i;
526  distance_keep = 0.95;
527  normal_keep = edge2_to_tip_normal;
528  angle_min = angle_edge2_normal;
529  }
530 
532  crack_tip_origin, left_angle_normal, edge_ends[0], edge_ends[1], distance) &&
533  (!CEMElem->isEdgePhantom(i)))
534  {
535  if (std::abs(left_angle_normal * normal) > std::abs(angle_min) &&
536  (edge1_to_tip * crack_tip_direction) > std::cos(45.0 / 180.0 * 3.14159))
537  {
538  edge_id_keep = i;
539  distance_keep = distance;
540  normal_keep = left_angle_normal;
541  angle_min = left_angle_normal * normal;
542  }
543  }
544  else if (initCutIntersectionEdge(
545  crack_tip_origin, right_angle_normal, edge_ends[0], edge_ends[1], distance) &&
546  (!CEMElem->isEdgePhantom(i)))
547  {
548  if (std::abs(right_angle_normal * normal) > std::abs(angle_min) &&
549  (edge2_to_tip * crack_tip_direction) > std::cos(45.0 / 180.0 * 3.14159))
550  {
551  edge_id_keep = i;
552  distance_keep = distance;
553  normal_keep = right_angle_normal;
554  angle_min = right_angle_normal * normal;
555  }
556  }
557  else if (initCutIntersectionEdge(crack_tip_origin,
558  crack_direction_normal,
559  edge_ends[0],
560  edge_ends[1],
561  distance) &&
562  (!CEMElem->isEdgePhantom(i)))
563  {
564  if (std::abs(crack_direction_normal * normal) > std::abs(angle_min) &&
565  (crack_tip_direction * crack_tip_direction) > std::cos(45.0 / 180.0 * 3.14159))
566  {
567  edge_id_keep = i;
568  distance_keep = distance;
569  normal_keep = crack_direction_normal;
570  angle_min = crack_direction_normal * normal;
571  }
572  }
573  }
574  }
575 
576  // avoid small volume fraction cut
577  if ((distance_keep - 0.05) < 0.0)
578  {
579  distance_keep = 0.05;
580  }
581  else if ((distance_keep - 0.95) > 0.0)
582  {
583  distance_keep = 0.95;
584  }
585 }

Referenced by markCutEdgesByState().

◆ cutMeshWithEFA()

bool XFEM::cutMeshWithEFA ( NonlinearSystemBase &  nl,
AuxiliarySystem &  aux 
)

Definition at line 1077 of file XFEM.C.

1078 {
1079  std::map<unsigned int, Node *> efa_id_to_new_node;
1080  std::map<unsigned int, Node *> efa_id_to_new_node2;
1081  std::map<unsigned int, Elem *> efa_id_to_new_elem;
1082  _cached_solution.clear();
1083  _cached_aux_solution.clear();
1084 
1086 
1087  if (_debug_output_level > 2)
1088  {
1089  _console << "\nXFEM Element fragment algorithm mesh prior to cutting:\n";
1090  _console << std::flush;
1091  _efa_mesh.printMesh();
1092  }
1093 
1095 
1096  if (_debug_output_level > 2)
1097  {
1098  _console << "\nXFEM Element fragment algorithm mesh after cutting:\n";
1099  _console << std::flush;
1100  _efa_mesh.printMesh();
1101  }
1102 
1103  const std::vector<EFANode *> new_nodes = _efa_mesh.getNewNodes();
1104  const std::vector<EFAElement *> new_elements = _efa_mesh.getChildElements();
1105  const std::vector<EFAElement *> delete_elements = _efa_mesh.getParentElements();
1106 
1107  bool mesh_changed = (new_nodes.size() + new_elements.size() + delete_elements.size() > 0);
1108 
1109  // Prepare to cache solution on DOFs modified by XFEM
1110  if (mesh_changed)
1111  {
1112  nl.serializeSolution();
1113  aux.serializeSolution();
1114  if (_debug_output_level > 1)
1115  _console << "\n";
1116  }
1117  NumericVector<Number> & current_solution = *nl.system().current_local_solution;
1118  NumericVector<Number> & old_solution = nl.solutionOld();
1119  NumericVector<Number> & older_solution = nl.solutionOlder();
1120  NumericVector<Number> & current_aux_solution = *aux.system().current_local_solution;
1121  NumericVector<Number> & old_aux_solution = aux.solutionOld();
1122  NumericVector<Number> & older_aux_solution = aux.solutionOlder();
1123 
1124  std::map<Node *, Node *> new_nodes_to_parents;
1125 
1126  // Add new nodes
1127  for (unsigned int i = 0; i < new_nodes.size(); ++i)
1128  {
1129  unsigned int new_node_id = new_nodes[i]->id();
1130  unsigned int parent_id = new_nodes[i]->parent()->id();
1131 
1132  Node * parent_node = _mesh->node_ptr(parent_id);
1133  Node * new_node = Node::build(*parent_node, _mesh->n_nodes()).release();
1134  _mesh->add_node(new_node);
1135 
1136  new_nodes_to_parents[new_node] = parent_node;
1137 
1138  new_node->set_n_systems(parent_node->n_systems());
1139  efa_id_to_new_node.insert(std::make_pair(new_node_id, new_node));
1140  if (_debug_output_level > 1)
1141  _console << "XFEM added new node: " << new_node->id() << "\n";
1142  if (_displaced_mesh)
1143  {
1144  const Node * parent_node2 = _displaced_mesh->node_ptr(parent_id);
1145  Node * new_node2 = Node::build(*parent_node2, _displaced_mesh->n_nodes()).release();
1146  _displaced_mesh->add_node(new_node2);
1147 
1148  new_node2->set_n_systems(parent_node2->n_systems());
1149  efa_id_to_new_node2.insert(std::make_pair(new_node_id, new_node2));
1150  }
1151  }
1152 
1153  // Add new elements
1154  std::map<unsigned int, std::vector<const Elem *>> temporary_parent_children_map;
1155 
1156  std::vector<boundary_id_type> parent_boundary_ids;
1157 
1158  for (unsigned int i = 0; i < new_elements.size(); ++i)
1159  {
1160  unsigned int parent_id = new_elements[i]->getParent()->id();
1161  unsigned int efa_child_id = new_elements[i]->id();
1162 
1163  Elem * parent_elem = _mesh->elem_ptr(parent_id);
1164  Elem * libmesh_elem = Elem::build(parent_elem->type()).release();
1165 
1166  for (unsigned int m = 0; m < _geometric_cuts.size(); ++m)
1167  {
1168  for (auto & it : _sibling_elems[_geometric_cuts[m]->getInterfaceID()])
1169  {
1170  if (parent_elem == it.first)
1171  it.first = libmesh_elem;
1172  else if (parent_elem == it.second)
1173  it.second = libmesh_elem;
1174  }
1175  }
1176 
1177  // parent has at least two children
1178  if (new_elements[i]->getParent()->numChildren() > 1)
1179  temporary_parent_children_map[parent_elem->id()].push_back(libmesh_elem);
1180 
1181  Elem * parent_elem2 = NULL;
1182  Elem * libmesh_elem2 = NULL;
1183  if (_displaced_mesh)
1184  {
1185  parent_elem2 = _displaced_mesh->elem_ptr(parent_id);
1186  libmesh_elem2 = Elem::build(parent_elem2->type()).release();
1187 
1188  for (unsigned int m = 0; m < _geometric_cuts.size(); ++m)
1189  {
1190  for (auto & it : _sibling_displaced_elems[_geometric_cuts[m]->getInterfaceID()])
1191  {
1192  if (parent_elem2 == it.first)
1193  it.first = libmesh_elem2;
1194  else if (parent_elem2 == it.second)
1195  it.second = libmesh_elem2;
1196  }
1197  }
1198  }
1199 
1200  for (unsigned int j = 0; j < new_elements[i]->numNodes(); ++j)
1201  {
1202  unsigned int node_id = new_elements[i]->getNode(j)->id();
1203  Node * libmesh_node;
1204 
1205  std::map<unsigned int, Node *>::iterator nit = efa_id_to_new_node.find(node_id);
1206  if (nit != efa_id_to_new_node.end())
1207  libmesh_node = nit->second;
1208  else
1209  libmesh_node = _mesh->node_ptr(node_id);
1210 
1211  if (libmesh_node->processor_id() == DofObject::invalid_processor_id)
1212  libmesh_node->processor_id() = parent_elem->processor_id();
1213 
1214  libmesh_elem->set_node(j) = libmesh_node;
1215 
1216  // Store solution for all nodes affected by XFEM (even existing nodes)
1217  if (parent_elem->is_semilocal(_mesh->processor_id()))
1218  {
1219  Node * solution_node = libmesh_node; // Node from which to store solution
1220  if (new_nodes_to_parents.find(libmesh_node) != new_nodes_to_parents.end())
1221  solution_node = new_nodes_to_parents[libmesh_node];
1222 
1223  if ((_moose_mesh->isSemiLocal(solution_node)) ||
1224  (solution_node->processor_id() == _mesh->processor_id()))
1225  {
1226  storeSolutionForNode(libmesh_node,
1227  solution_node,
1228  nl,
1230  current_solution,
1231  old_solution,
1232  older_solution);
1233  storeSolutionForNode(libmesh_node,
1234  solution_node,
1235  aux,
1237  current_aux_solution,
1238  old_aux_solution,
1239  older_aux_solution);
1240  }
1241  }
1242 
1243  Node * parent_node = parent_elem->node_ptr(j);
1244  _mesh->boundary_info->boundary_ids(parent_node, parent_boundary_ids);
1245  _mesh->boundary_info->add_node(libmesh_node, parent_boundary_ids);
1246 
1247  if (_displaced_mesh)
1248  {
1249  std::map<unsigned int, Node *>::iterator nit2 = efa_id_to_new_node2.find(node_id);
1250  if (nit2 != efa_id_to_new_node2.end())
1251  libmesh_node = nit2->second;
1252  else
1253  libmesh_node = _displaced_mesh->node_ptr(node_id);
1254 
1255  if (libmesh_node->processor_id() == DofObject::invalid_processor_id)
1256  libmesh_node->processor_id() = parent_elem2->processor_id();
1257 
1258  libmesh_elem2->set_node(j) = libmesh_node;
1259 
1260  parent_node = parent_elem2->node_ptr(j);
1261  _displaced_mesh->boundary_info->boundary_ids(parent_node, parent_boundary_ids);
1262  _displaced_mesh->boundary_info->add_node(libmesh_node, parent_boundary_ids);
1263  }
1264  }
1265 
1266  libmesh_elem->set_p_level(parent_elem->p_level());
1267  libmesh_elem->set_p_refinement_flag(parent_elem->p_refinement_flag());
1268  _mesh->add_elem(libmesh_elem);
1269  libmesh_elem->set_n_systems(parent_elem->n_systems());
1270  libmesh_elem->subdomain_id() = parent_elem->subdomain_id();
1271  libmesh_elem->processor_id() = parent_elem->processor_id();
1272 
1273  // TODO: The 0 here is the thread ID. Need to sort out how to do this correctly
1274  // TODO: Also need to copy neighbor material data
1275  if (parent_elem->processor_id() == _mesh->processor_id())
1276  {
1277  (*_material_data)[0]->copy(*libmesh_elem, *parent_elem, 0);
1278  for (unsigned int side = 0; side < parent_elem->n_sides(); ++side)
1279  {
1280  _mesh->boundary_info->boundary_ids(parent_elem, side, parent_boundary_ids);
1281  std::vector<boundary_id_type>::iterator it_bd = parent_boundary_ids.begin();
1282  for (; it_bd != parent_boundary_ids.end(); ++it_bd)
1283  {
1284  if (_fe_problem->needBoundaryMaterialOnSide(*it_bd, 0))
1285  (*_bnd_material_data)[0]->copy(*libmesh_elem, *parent_elem, side);
1286  }
1287  }
1288 
1289  // Store solution for all elements affected by XFEM
1290  storeSolutionForElement(libmesh_elem,
1291  parent_elem,
1292  nl,
1294  current_solution,
1295  old_solution,
1296  older_solution);
1297  storeSolutionForElement(libmesh_elem,
1298  parent_elem,
1299  aux,
1301  current_aux_solution,
1302  old_aux_solution,
1303  older_aux_solution);
1304  }
1305 
1306  // The crack tip origin map is stored before cut, thus the elem should be updated with new
1307  // element.
1308  std::map<const Elem *, std::vector<Point>>::iterator mit =
1309  _elem_crack_origin_direction_map.find(parent_elem);
1310  if (mit != _elem_crack_origin_direction_map.end())
1311  {
1312  std::vector<Point> crack_data = _elem_crack_origin_direction_map[parent_elem];
1314  _elem_crack_origin_direction_map[libmesh_elem] = crack_data;
1315  }
1316 
1317  if (_debug_output_level > 1)
1318  _console << "XFEM added new element: " << libmesh_elem->id() << "\n";
1319 
1320  XFEMCutElem * xfce = NULL;
1321  if (_mesh->mesh_dimension() == 2)
1322  {
1323  EFAElement2D * new_efa_elem2d = dynamic_cast<EFAElement2D *>(new_elements[i]);
1324  if (!new_efa_elem2d)
1325  mooseError("EFAelem is not of EFAelement2D type");
1326  xfce = new XFEMCutElem2D(libmesh_elem,
1327  new_efa_elem2d,
1328  _fe_problem->assembly(0).qRule()->n_points(),
1329  libmesh_elem->n_sides());
1330  }
1331  else if (_mesh->mesh_dimension() == 3)
1332  {
1333  EFAElement3D * new_efa_elem3d = dynamic_cast<EFAElement3D *>(new_elements[i]);
1334  if (!new_efa_elem3d)
1335  mooseError("EFAelem is not of EFAelement3D type");
1336  xfce = new XFEMCutElem3D(libmesh_elem,
1337  new_efa_elem3d,
1338  _fe_problem->assembly(0).qRule()->n_points(),
1339  libmesh_elem->n_sides());
1340  }
1341  _cut_elem_map.insert(std::pair<unique_id_type, XFEMCutElem *>(libmesh_elem->unique_id(), xfce));
1342  efa_id_to_new_elem.insert(std::make_pair(efa_child_id, libmesh_elem));
1343 
1344  if (_displaced_mesh)
1345  {
1346  libmesh_elem2->set_p_level(parent_elem2->p_level());
1347  libmesh_elem2->set_p_refinement_flag(parent_elem2->p_refinement_flag());
1348  _displaced_mesh->add_elem(libmesh_elem2);
1349  libmesh_elem2->set_n_systems(parent_elem2->n_systems());
1350  libmesh_elem2->subdomain_id() = parent_elem2->subdomain_id();
1351  libmesh_elem2->processor_id() = parent_elem2->processor_id();
1352  }
1353 
1354  unsigned int n_sides = parent_elem->n_sides();
1355  for (unsigned int side = 0; side < n_sides; ++side)
1356  {
1357  _mesh->boundary_info->boundary_ids(parent_elem, side, parent_boundary_ids);
1358  _mesh->boundary_info->add_side(libmesh_elem, side, parent_boundary_ids);
1359  }
1360  if (_displaced_mesh)
1361  {
1362  n_sides = parent_elem2->n_sides();
1363  for (unsigned int side = 0; side < n_sides; ++side)
1364  {
1365  _displaced_mesh->boundary_info->boundary_ids(parent_elem2, side, parent_boundary_ids);
1366  _displaced_mesh->boundary_info->add_side(libmesh_elem2, side, parent_boundary_ids);
1367  }
1368  }
1369 
1370  unsigned int n_edges = parent_elem->n_edges();
1371  for (unsigned int edge = 0; edge < n_edges; ++edge)
1372  {
1373  _mesh->boundary_info->edge_boundary_ids(parent_elem, edge, parent_boundary_ids);
1374  _mesh->boundary_info->add_edge(libmesh_elem, edge, parent_boundary_ids);
1375  }
1376  if (_displaced_mesh)
1377  {
1378  n_edges = parent_elem2->n_edges();
1379  for (unsigned int edge = 0; edge < n_edges; ++edge)
1380  {
1381  _displaced_mesh->boundary_info->edge_boundary_ids(parent_elem2, edge, parent_boundary_ids);
1382  _displaced_mesh->boundary_info->add_edge(libmesh_elem2, edge, parent_boundary_ids);
1383  }
1384  }
1385  }
1386 
1387  // delete elements
1388  for (std::size_t i = 0; i < delete_elements.size(); ++i)
1389  {
1390  Elem * elem_to_delete = _mesh->elem_ptr(delete_elements[i]->id());
1391 
1392  // delete the XFEMCutElem object for any elements that are to be deleted
1393  std::map<unique_id_type, XFEMCutElem *>::iterator cemit =
1394  _cut_elem_map.find(elem_to_delete->unique_id());
1395  if (cemit != _cut_elem_map.end())
1396  {
1397  delete cemit->second;
1398  _cut_elem_map.erase(cemit);
1399  }
1400 
1401  elem_to_delete->nullify_neighbors();
1402  _mesh->boundary_info->remove(elem_to_delete);
1403  unsigned int deleted_elem_id = elem_to_delete->id();
1404  _mesh->delete_elem(elem_to_delete);
1405  if (_debug_output_level > 1)
1406  _console << "XFEM deleted element: " << deleted_elem_id << "\n";
1407 
1408  if (_displaced_mesh)
1409  {
1410  Elem * elem_to_delete2 = _displaced_mesh->elem_ptr(delete_elements[i]->id());
1411  elem_to_delete2->nullify_neighbors();
1412  _displaced_mesh->boundary_info->remove(elem_to_delete2);
1413  _displaced_mesh->delete_elem(elem_to_delete2);
1414  }
1415  }
1416 
1417  for (std::map<unsigned int, std::vector<const Elem *>>::iterator it =
1418  temporary_parent_children_map.begin();
1419  it != temporary_parent_children_map.end();
1420  ++it)
1421  {
1422  std::vector<const Elem *> & sibling_elem_vec = it->second;
1423  // TODO: for cut-node case, how to find the sibling elements?
1424  // if (sibling_elem_vec.size() != 2)
1425  // mooseError("Must have exactly 2 sibling elements");
1426 
1427  for (unsigned int i = 0; i < _geometric_cuts.size(); ++i)
1428  for (auto const & elem_id : _geom_marker_id_elems[_geometric_cuts[i]->getInterfaceID()])
1429  if (it->first == elem_id)
1430  _sibling_elems[_geometric_cuts[i]->getInterfaceID()].push_back(
1431  std::make_pair(sibling_elem_vec[0], sibling_elem_vec[1]));
1432  }
1433 
1434  // add sibling elems on displaced mesh
1435  if (_displaced_mesh)
1436  {
1437  for (unsigned int i = 0; i < _geometric_cuts.size(); ++i)
1438  {
1439  for (auto & se : _sibling_elems[_geometric_cuts[i]->getInterfaceID()])
1440  {
1441  Elem * elem = _displaced_mesh->elem_ptr(se.first->id());
1442  Elem * elem_pair = _displaced_mesh->elem_ptr(se.second->id());
1443  _sibling_displaced_elems[_geometric_cuts[i]->getInterfaceID()].push_back(
1444  std::make_pair(elem, elem_pair));
1445  }
1446  }
1447  }
1448 
1449  // clear the temporary map
1450  temporary_parent_children_map.clear();
1451 
1452  // Store information about crack tip elements
1453  if (mesh_changed)
1454  {
1455  _crack_tip_elems.clear();
1457  const std::set<EFAElement *> CrackTipElements = _efa_mesh.getCrackTipElements();
1458  std::set<EFAElement *>::const_iterator sit;
1459  for (sit = CrackTipElements.begin(); sit != CrackTipElements.end(); ++sit)
1460  {
1461  unsigned int eid = (*sit)->id();
1462  Elem * crack_tip_elem;
1463  std::map<unsigned int, Elem *>::iterator eit = efa_id_to_new_elem.find(eid);
1464  if (eit != efa_id_to_new_elem.end())
1465  crack_tip_elem = eit->second;
1466  else
1467  crack_tip_elem = _mesh->elem_ptr(eid);
1468  _crack_tip_elems.insert(crack_tip_elem);
1469 
1470  // Store the crack tip elements which are going to be healed
1471  for (unsigned int i = 0; i < _geometric_cuts.size(); ++i)
1472  {
1473  if (_geometric_cuts[i]->shouldHealMesh())
1474  {
1475  for (auto const & mie : _geom_marker_id_elems[_geometric_cuts[i]->getInterfaceID()])
1476  if ((*sit)->getParent() != nullptr)
1477  {
1478  if ((*sit)->getParent()->id() == mie)
1479  _crack_tip_elems_to_be_healed.insert(crack_tip_elem);
1480  }
1481  }
1482  }
1483  }
1484  }
1485  if (_debug_output_level > 0)
1486  {
1487  _console << "\nXFEM mesh cutting with element fragment algorithm complete\n";
1488  _console << "# new nodes: " << new_nodes.size() << "\n";
1489  _console << "# new elements: " << new_elements.size() << "\n";
1490  _console << "# deleted elements: " << delete_elements.size() << "\n";
1491  _console << std::flush;
1492  }
1493 
1494  // store virtual nodes
1495  // store cut edge info
1496  return mesh_changed;
1497 }

Referenced by update().

◆ getCrackTipOrigin()

void XFEM::getCrackTipOrigin ( std::map< unsigned int, const Elem * > &  elem_id_crack_tip,
std::vector< Point > &  crack_front_points 
)

Definition at line 64 of file XFEM.C.

66 {
67  elem_id_crack_tip.clear();
68  crack_front_points.clear();
69  crack_front_points.resize(_elem_crack_origin_direction_map.size());
70 
71  unsigned int crack_tip_index = 0;
72  // This map is used to sort the order in _elem_crack_origin_direction_map such that every process
73  // has same order
74  std::map<unsigned int, const Elem *> elem_id_map;
75 
76  int m = -1;
77  for (std::map<const Elem *, std::vector<Point>>::iterator mit1 =
80  ++mit1)
81  {
82  unsigned int elem_id = mit1->first->id();
83  if (elem_id > 999999)
84  {
85  elem_id_map[m] = mit1->first;
86  m--;
87  }
88  else
89  {
90  elem_id_map[elem_id] = mit1->first;
91  }
92  }
93 
94  for (std::map<unsigned int, const Elem *>::iterator mit1 = elem_id_map.begin();
95  mit1 != elem_id_map.end();
96  mit1++)
97  {
98  const Elem * elem = mit1->second;
99  std::map<const Elem *, std::vector<Point>>::iterator mit2 =
101  if (mit2 != _elem_crack_origin_direction_map.end())
102  {
103  elem_id_crack_tip[crack_tip_index] = mit2->first;
104  crack_front_points[crack_tip_index] =
105  (mit2->second)[0]; // [0] stores origin coordinates and [1] stores direction
106  crack_tip_index++;
107  }
108  }
109 }

◆ getCrackTipOriginMap()

const std::map<const Elem *, std::vector<Point> >& XFEM::getCrackTipOriginMap ( ) const
inline

Definition at line 254 of file XFEM.h.

255  {
257  }

◆ getCutPlane()

Real XFEM::getCutPlane ( const Elem *  elem,
const Xfem::XFEM_CUTPLANE_QUANTITY  quantity,
unsigned int  plane_id 
) const

Get specified component of normal or origin for cut plane for a given element.

Definition at line 1570 of file XFEM.C.

1573 {
1574  Real comp = 0.0;
1575  Point planedata(0.0, 0.0, 0.0);
1576  std::map<unique_id_type, XFEMCutElem *>::const_iterator it;
1577  it = _cut_elem_map.find(elem->unique_id());
1578  if (it != _cut_elem_map.end())
1579  {
1580  const XFEMCutElem * xfce = it->second;
1581  const EFAElement * EFAelem = xfce->getEFAElement();
1582  if (EFAelem->isPartial()) // exclude the full crack tip elements
1583  {
1584  if ((unsigned int)quantity < 3)
1585  {
1586  unsigned int index = (unsigned int)quantity;
1587  planedata = xfce->getCutPlaneOrigin(plane_id, _displaced_mesh);
1588  comp = planedata(index);
1589  }
1590  else if ((unsigned int)quantity < 6)
1591  {
1592  unsigned int index = (unsigned int)quantity - 3;
1593  planedata = xfce->getCutPlaneNormal(plane_id, _displaced_mesh);
1594  comp = planedata(index);
1595  }
1596  else
1597  mooseError("In get_cut_plane index out of range");
1598  }
1599  }
1600  return comp;
1601 }

◆ getEFAElem2D()

EFAElement2D * XFEM::getEFAElem2D ( const Elem *  elem)

Get the EFAElement2D object for a specified libMesh element.

Parameters
elemPointer to the libMesh element for which the object is requested

Definition at line 1651 of file XFEM.C.

1652 {
1653  EFAElement * EFAelem = _efa_mesh.getElemByID(elem->id());
1654  EFAElement2D * EFAelem2D = dynamic_cast<EFAElement2D *>(EFAelem);
1655 
1656  if (!EFAelem2D)
1657  mooseError("EFAelem is not of EFAelement2D type");
1658 
1659  return EFAelem2D;
1660 }

Referenced by markCutEdgesByGeometry(), and markCutEdgesByState().

◆ getEFAElem3D()

EFAElement3D * XFEM::getEFAElem3D ( const Elem *  elem)

Get the EFAElement3D object for a specified libMesh element.

Parameters
elemPointer to the libMesh element for which the object is requested

Definition at line 1663 of file XFEM.C.

1664 {
1665  EFAElement * EFAelem = _efa_mesh.getElemByID(elem->id());
1666  EFAElement3D * EFAelem3D = dynamic_cast<EFAElement3D *>(EFAelem);
1667 
1668  if (!EFAelem3D)
1669  mooseError("EFAelem is not of EFAelement3D type");
1670 
1671  return EFAelem3D;
1672 }

Referenced by markCutFacesByGeometry().

◆ getEFANodeCoords()

Point XFEM::getEFANodeCoords ( EFANode CEMnode,
EFAElement CEMElem,
const Elem *  elem,
MeshBase *  displaced_mesh = NULL 
) const

Definition at line 1500 of file XFEM.C.

1504 {
1505  Point node_coor(0.0, 0.0, 0.0);
1506  std::vector<EFANode *> master_nodes;
1507  std::vector<Point> master_points;
1508  std::vector<double> master_weights;
1509 
1510  CEMElem->getMasterInfo(CEMnode, master_nodes, master_weights);
1511  for (std::size_t i = 0; i < master_nodes.size(); ++i)
1512  {
1513  if (master_nodes[i]->category() == EFANode::N_CATEGORY_PERMANENT)
1514  {
1515  unsigned int local_node_id = CEMElem->getLocalNodeIndex(master_nodes[i]);
1516  const Node * node = elem->node_ptr(local_node_id);
1517  if (displaced_mesh)
1518  node = displaced_mesh->node_ptr(node->id());
1519  Point node_p((*node)(0), (*node)(1), (*node)(2));
1520  master_points.push_back(node_p);
1521  }
1522  else
1523  mooseError("master nodes must be permanent");
1524  }
1525  for (std::size_t i = 0; i < master_nodes.size(); ++i)
1526  node_coor += master_weights[i] * master_points[i];
1527 
1528  return node_coor;
1529 }

Referenced by correctCrackExtensionDirection(), getFragmentEdges(), getFragmentFaces(), and markCutEdgesByState().

◆ getElementSolutionDofs()

std::vector< dof_id_type > XFEM::getElementSolutionDofs ( const Elem *  elem,
SystemBase &  sys 
) const
private

Get a vector of the dof indices for all components of all variables associated with an element.

Parameters
elemElement for which dof indices are found
sysSystem for which the dof indices are found

Definition at line 2002 of file XFEM.C.

2003 {
2004  SubdomainID sid = elem->subdomain_id();
2005  const std::vector<MooseVariableFEBase *> & vars = sys.getVariables(0);
2006  std::vector<dof_id_type> solution_dofs;
2007  solution_dofs.reserve(vars.size()); // just an approximation
2008  for (auto var : vars)
2009  {
2010  if (!var->isNodal())
2011  {
2012  const std::set<SubdomainID> & var_subdomains = sys.getSubdomainsForVar(var->number());
2013  if (var_subdomains.empty() || var_subdomains.find(sid) != var_subdomains.end())
2014  {
2015  unsigned int n_comp = elem->n_comp(sys.number(), var->number());
2016  for (unsigned int icomp = 0; icomp < n_comp; ++icomp)
2017  {
2018  dof_id_type elem_dof = elem->dof_number(sys.number(), var->number(), icomp);
2019  solution_dofs.push_back(elem_dof);
2020  }
2021  }
2022  }
2023  }
2024  return solution_dofs;
2025 }

Referenced by setSolution(), and storeSolutionForElement().

◆ getFragmentEdges()

void XFEM::getFragmentEdges ( const Elem *  elem,
EFAElement2D CEMElem,
std::vector< std::vector< Point >> &  frag_edges 
) const

Definition at line 1675 of file XFEM.C.

1678 {
1679  // N.B. CEMElem here has global EFAnode
1680  frag_edges.clear();
1681  if (CEMElem->numFragments() > 0)
1682  {
1683  if (CEMElem->numFragments() > 1)
1684  mooseError("element ", elem->id(), " has more than one fragment at this point");
1685  for (unsigned int i = 0; i < CEMElem->getFragment(0)->numEdges(); ++i)
1686  {
1687  std::vector<Point> p_line(2, Point(0.0, 0.0, 0.0));
1688  p_line[0] = getEFANodeCoords(CEMElem->getFragmentEdge(0, i)->getNode(0), CEMElem, elem);
1689  p_line[1] = getEFANodeCoords(CEMElem->getFragmentEdge(0, i)->getNode(1), CEMElem, elem);
1690  frag_edges.push_back(p_line);
1691  }
1692  }
1693 }

◆ getFragmentFaces() [1/2]

void XFEM::getFragmentFaces ( const Elem *  elem,
EFAElement3D CEMElem,
std::vector< std::vector< Point >> &  frag_faces 
) const

Definition at line 1696 of file XFEM.C.

1699 {
1700  // N.B. CEMElem here has global EFAnode
1701  frag_faces.clear();
1702  if (CEMElem->numFragments() > 0)
1703  {
1704  if (CEMElem->numFragments() > 1)
1705  mooseError("element ", elem->id(), " has more than one fragment at this point");
1706  for (unsigned int i = 0; i < CEMElem->getFragment(0)->numFaces(); ++i)
1707  {
1708  unsigned int num_face_nodes = CEMElem->getFragmentFace(0, i)->numNodes();
1709  std::vector<Point> p_line(num_face_nodes, Point(0.0, 0.0, 0.0));
1710  for (unsigned int j = 0; j < num_face_nodes; ++j)
1711  p_line[j] = getEFANodeCoords(CEMElem->getFragmentFace(0, i)->getNode(j), CEMElem, elem);
1712  frag_faces.push_back(p_line);
1713  }
1714  }
1715 }

◆ getFragmentFaces() [2/2]

void XFEM::getFragmentFaces ( const Elem *  elem,
std::vector< std::vector< Point >> &  frag_faces,
bool  displaced_mesh = false 
) const

Definition at line 1634 of file XFEM.C.

1637 {
1638  std::map<unique_id_type, XFEMCutElem *>::const_iterator it;
1639  it = _cut_elem_map.find(elem->unique_id());
1640  if (it != _cut_elem_map.end())
1641  {
1642  const XFEMCutElem * xfce = it->second;
1643  if (displaced_mesh)
1644  xfce->getFragmentFaces(frag_faces, _displaced_mesh);
1645  else
1646  xfce->getFragmentFaces(frag_faces);
1647  }
1648 }

◆ getGeometricCutID()

virtual unsigned int XFEM::getGeometricCutID ( const GeometricCutUserObject gcu)
inlinevirtual

Get the interface ID corresponding to a given GeometricCutUserObject.

Parameters
gcupointer to the GeometricCutUserObject
Returns
the interface ID

Definition at line 217 of file XFEM.h.

218  {
219  return _geom_marker_id_map[gcu];
220  };

◆ getNodeSolutionDofs()

std::vector< dof_id_type > XFEM::getNodeSolutionDofs ( const Node *  node,
SystemBase &  sys 
) const
private

Get a vector of the dof indices for all components of all variables associated with a node.

Parameters
nodeNode for which dof indices are found
sysSystem for which the dof indices are found

Definition at line 2028 of file XFEM.C.

2029 {
2030  const std::set<SubdomainID> & sids = _moose_mesh->getNodeBlockIds(*node);
2031  const std::vector<MooseVariableFEBase *> & vars = sys.getVariables(0);
2032  std::vector<dof_id_type> solution_dofs;
2033  solution_dofs.reserve(vars.size()); // just an approximation
2034  for (auto var : vars)
2035  {
2036  if (var->isNodal())
2037  {
2038  const std::set<SubdomainID> & var_subdomains = sys.getSubdomainsForVar(var->number());
2039  std::set<SubdomainID> intersect;
2040  set_intersection(var_subdomains.begin(),
2041  var_subdomains.end(),
2042  sids.begin(),
2043  sids.end(),
2044  std::inserter(intersect, intersect.begin()));
2045  if (var_subdomains.empty() || !intersect.empty())
2046  {
2047  unsigned int n_comp = node->n_comp(sys.number(), var->number());
2048  for (unsigned int icomp = 0; icomp < n_comp; ++icomp)
2049  {
2050  dof_id_type node_dof = node->dof_number(sys.number(), var->number(), icomp);
2051  solution_dofs.push_back(node_dof);
2052  }
2053  }
2054  }
2055  }
2056  return solution_dofs;
2057 }

Referenced by setSolution(), and storeSolutionForNode().

◆ getPhysicalVolumeFraction()

Real XFEM::getPhysicalVolumeFraction ( const Elem *  elem) const

Get the volume fraction of an element that is physical.

Definition at line 1532 of file XFEM.C.

1533 {
1534  Real phys_volfrac = 1.0;
1535  std::map<unique_id_type, XFEMCutElem *>::const_iterator it;
1536  it = _cut_elem_map.find(elem->unique_id());
1537  if (it != _cut_elem_map.end())
1538  {
1539  XFEMCutElem * xfce = it->second;
1540  const EFAElement * EFAelem = xfce->getEFAElement();
1541  if (EFAelem->isPartial())
1542  { // exclude the full crack tip elements
1544  phys_volfrac = xfce->getPhysicalVolumeFraction();
1545  }
1546  }
1547 
1548  return phys_volfrac;
1549 }

Referenced by markCutEdgesByState().

◆ getXFEMCutElemPairs()

virtual const ElementPairLocator::ElementPairList* XFEM::getXFEMCutElemPairs ( unsigned int  interface_id)
inlinevirtual

Get the list of cut element pairs corresponding to a given interface ID.

Parameters
interface_idThe ID of the interface
Returns
the list of elements cut by that interface

Definition at line 195 of file XFEM.h.

196  {
197  return &_sibling_elems[interface_id];
198  }

◆ getXFEMDisplacedCutElemPairs()

virtual const ElementPairLocator::ElementPairList* XFEM::getXFEMDisplacedCutElemPairs ( unsigned int  interface_id)
inlinevirtual

Get the list of cut element pairs on the displaced mesh corresponding to a given interface ID.

Parameters
interface_idThe ID of the interface
Returns
the list of elements cut by that interface

Definition at line 207 of file XFEM.h.

208  {
209  return &_sibling_displaced_elems[interface_id];
210  }

◆ getXFEMFaceWeights()

bool XFEM::getXFEMFaceWeights ( MooseArray< Real > &  weights,
const Elem *  elem,
QBase *  qrule,
const MooseArray< Point > &  q_points,
unsigned int  side 
)
overridevirtual

Definition at line 1765 of file XFEM.C.

1770 {
1771  bool have_weights = false;
1772  XFEMCutElem * xfce = NULL;
1773  if (isElemCut(elem, xfce))
1774  {
1775  mooseAssert(xfce != NULL, "Must have valid XFEMCutElem object here");
1776  xfce->getFaceWeightMultipliers(weights, qrule, getXFEMQRule(), q_points, side);
1777  have_weights = true;
1778  }
1779  return have_weights;
1780 }

◆ getXFEMIntersectionInfo()

void XFEM::getXFEMIntersectionInfo ( const Elem *  elem,
unsigned int  plane_id,
Point &  normal,
std::vector< Point > &  intersectionPoints,
bool  displaced_mesh = false 
) const
virtual

Definition at line 1783 of file XFEM.C.

1788 {
1789  std::map<unique_id_type, XFEMCutElem *>::const_iterator it;
1790  it = _cut_elem_map.find(elem->unique_id());
1791  if (it != _cut_elem_map.end())
1792  {
1793  const XFEMCutElem * xfce = it->second;
1794  if (displaced_mesh)
1795  xfce->getIntersectionInfo(plane_id, normal, intersectionPoints, _displaced_mesh);
1796  else
1797  xfce->getIntersectionInfo(plane_id, normal, intersectionPoints);
1798  }
1799 }

◆ getXFEMQRule()

Xfem::XFEM_QRULE & XFEM::getXFEMQRule ( )

Definition at line 1718 of file XFEM.C.

1719 {
1720  return _XFEM_qrule;
1721 }

Referenced by getXFEMFaceWeights(), and getXFEMWeights().

◆ getXFEMqRuleOnLine()

void XFEM::getXFEMqRuleOnLine ( std::vector< Point > &  intersection_points,
std::vector< Point > &  quad_pts,
std::vector< Real > &  quad_wts 
) const
virtual

Definition at line 1802 of file XFEM.C.

1805 {
1806  Point p1 = intersection_points[0];
1807  Point p2 = intersection_points[1];
1808 
1809  // number of quadrature points
1810  std::size_t num_qpoints = 2;
1811 
1812  // quadrature coordinates
1813  Real xi0 = -std::sqrt(1.0 / 3.0);
1814  Real xi1 = std::sqrt(1.0 / 3.0);
1815 
1816  quad_wts.resize(num_qpoints);
1817  quad_pts.resize(num_qpoints);
1818 
1819  Real integ_jacobian = pow((p1 - p2).norm_sq(), 0.5) * 0.5;
1820 
1821  quad_wts[0] = 1.0 * integ_jacobian;
1822  quad_wts[1] = 1.0 * integ_jacobian;
1823 
1824  quad_pts[0] = (1.0 - xi0) / 2.0 * p1 + (1.0 + xi0) / 2.0 * p2;
1825  quad_pts[1] = (1.0 - xi1) / 2.0 * p1 + (1.0 + xi1) / 2.0 * p2;
1826 }

◆ getXFEMqRuleOnSurface()

void XFEM::getXFEMqRuleOnSurface ( std::vector< Point > &  intersection_points,
std::vector< Point > &  quad_pts,
std::vector< Real > &  quad_wts 
) const
virtual

Definition at line 1829 of file XFEM.C.

1832 {
1833  std::size_t nnd_pe = intersection_points.size();
1834  Point xcrd(0.0, 0.0, 0.0);
1835  for (std::size_t i = 0; i < nnd_pe; ++i)
1836  xcrd += intersection_points[i];
1837  xcrd /= nnd_pe;
1838 
1839  quad_pts.resize(nnd_pe);
1840  quad_wts.resize(nnd_pe);
1841 
1842  Real jac = 0.0;
1843 
1844  for (std::size_t j = 0; j < nnd_pe; ++j) // loop all sub-tris
1845  {
1846  std::vector<std::vector<Real>> shape(3, std::vector<Real>(3, 0.0));
1847  std::vector<Point> subtrig_points(3, Point(0.0, 0.0, 0.0)); // sub-trig nodal coords
1848 
1849  int jplus1 = j < nnd_pe - 1 ? j + 1 : 0;
1850  subtrig_points[0] = xcrd;
1851  subtrig_points[1] = intersection_points[j];
1852  subtrig_points[2] = intersection_points[jplus1];
1853 
1854  std::vector<std::vector<Real>> sg2;
1855  Xfem::stdQuadr2D(3, 1, sg2); // get sg2
1856  for (std::size_t l = 0; l < sg2.size(); ++l) // loop all int pts on a sub-trig
1857  {
1858  Xfem::shapeFunc2D(3, sg2[l], subtrig_points, shape, jac, true); // Get shape
1859  std::vector<Real> tsg_line(3, 0.0);
1860  for (std::size_t k = 0; k < 3; ++k) // loop sub-trig nodes
1861  {
1862  tsg_line[0] += shape[k][2] * subtrig_points[k](0);
1863  tsg_line[1] += shape[k][2] * subtrig_points[k](1);
1864  tsg_line[2] += shape[k][2] * subtrig_points[k](2);
1865  }
1866  quad_pts[j + l] = Point(tsg_line[0], tsg_line[1], tsg_line[2]);
1867  quad_wts[j + l] = sg2[l][3] * jac;
1868  }
1869  }
1870 }

◆ getXFEMWeights()

bool XFEM::getXFEMWeights ( MooseArray< Real > &  weights,
const Elem *  elem,
QBase *  qrule,
const MooseArray< Point > &  q_points 
)
overridevirtual

Definition at line 1748 of file XFEM.C.

1752 {
1753  bool have_weights = false;
1754  XFEMCutElem * xfce = NULL;
1755  if (isElemCut(elem, xfce))
1756  {
1757  mooseAssert(xfce != NULL, "Must have valid XFEMCutElem object here");
1758  xfce->getWeightMultipliers(weights, qrule, getXFEMQRule(), q_points);
1759  have_weights = true;
1760  }
1761  return have_weights;
1762 }

◆ has_secondary_cut()

bool XFEM::has_secondary_cut ( )
inline

Definition at line 233 of file XFEM.h.

233 { return _has_secondary_cut; }

◆ healMesh()

bool XFEM::healMesh ( )

Potentially heal the mesh by merging some of the pairs of partial elements cut by XFEM back into single elements if indicated by the cutting objects.

Returns
true if the mesh has been modified due to healing

Definition at line 920 of file XFEM.C.

921 {
922  bool mesh_changed = false;
923 
924  std::set<Node *> nodes_to_delete;
925  std::set<Node *> nodes_to_delete_displaced;
926  std::set<unsigned int> cutelems_to_delete;
927  unsigned int deleted_elem_count = 0;
928  std::vector<std::string> healed_geometric_cuts;
929 
930  for (unsigned int i = 0; i < _geometric_cuts.size(); ++i)
931  {
932  if (_geometric_cuts[i]->shouldHealMesh())
933  {
934  healed_geometric_cuts.push_back(_geometric_cuts[i]->name());
935  for (auto & it : _sibling_elems[_geometric_cuts[i]->getInterfaceID()])
936  {
937  Elem * elem1 = const_cast<Elem *>(it.first);
938  Elem * elem2 = const_cast<Elem *>(it.second);
939 
940  std::map<unique_id_type, XFEMCutElem *>::iterator cemit =
941  _cut_elem_map.find(elem1->unique_id());
942  if (cemit != _cut_elem_map.end())
943  {
944  const XFEMCutElem * xfce = cemit->second;
945 
946  cutelems_to_delete.insert(elem1->unique_id());
947 
948  for (unsigned int in = 0; in < elem1->n_nodes(); ++in)
949  {
950  Node * e1node = elem1->node_ptr(in);
951  Node * e2node = elem2->node_ptr(in);
952  if (!xfce->isPointPhysical(*e1node) &&
953  e1node != e2node) // This would happen at the crack tip
954  {
955  elem1->set_node(in) = e2node;
956  nodes_to_delete.insert(e1node);
957  }
958  else if (e1node != e2node)
959  nodes_to_delete.insert(e2node);
960  }
961  }
962  else
963  mooseError("Could not find XFEMCutElem for element to be kept in healing");
964 
965  if (_displaced_mesh)
966  {
967  Elem * elem1_displaced = _displaced_mesh->elem_ptr(it.first->id());
968  Elem * elem2_displaced = _displaced_mesh->elem_ptr(it.second->id());
969 
970  std::map<unique_id_type, XFEMCutElem *>::iterator cemit =
971  _cut_elem_map.find(elem1_displaced->unique_id());
972  if (cemit != _cut_elem_map.end())
973  {
974  const XFEMCutElem * xfce = cemit->second;
975 
976  for (unsigned int in = 0; in < elem1_displaced->n_nodes(); ++in)
977  {
978  Node * e1node_displaced = elem1_displaced->node_ptr(in);
979  Node * e2node_displaced = elem2_displaced->node_ptr(in);
980  if (!xfce->isPointPhysical(*e1node_displaced) &&
981  e1node_displaced != e2node_displaced) // This would happen at the crack tip
982  {
983  elem1_displaced->set_node(in) = e2node_displaced;
984  nodes_to_delete_displaced.insert(e1node_displaced);
985  }
986  else if (e1node_displaced != e2node_displaced)
987  nodes_to_delete_displaced.insert(e2node_displaced);
988  }
989  }
990  else
991  mooseError("Could not find XFEMCutElem for element to be kept in healing");
992 
993  elem2_displaced->nullify_neighbors();
994  _displaced_mesh->boundary_info->remove(elem2_displaced);
995  _displaced_mesh->delete_elem(elem2_displaced);
996  }
997 
998  cutelems_to_delete.insert(elem2->unique_id());
999  elem2->nullify_neighbors();
1000  _mesh->boundary_info->remove(elem2);
1001  unsigned int deleted_elem_id = elem2->id();
1002  _mesh->delete_elem(elem2);
1003  if (_debug_output_level > 1)
1004  {
1005  if (deleted_elem_count == 0)
1006  _console << "\n";
1007  _console << "XFEM healing deleted element: " << deleted_elem_id << "\n";
1008  }
1009  ++deleted_elem_count;
1010  mesh_changed = true;
1011  }
1012  }
1013  }
1014 
1015  for (auto & sit : nodes_to_delete)
1016  {
1017  Node * node_to_delete = sit;
1018  dof_id_type deleted_node_id = node_to_delete->id();
1019  _mesh->boundary_info->remove(node_to_delete);
1020  _mesh->delete_node(node_to_delete);
1021  if (_debug_output_level > 1)
1022  _console << "XFEM healing deleted node: " << deleted_node_id << "\n";
1023  }
1024 
1025  if (_displaced_mesh)
1026  {
1027  for (auto & sit : nodes_to_delete_displaced)
1028  {
1029  Node * node_to_delete = sit;
1030  _displaced_mesh->boundary_info->remove(node_to_delete);
1031  _displaced_mesh->delete_node(node_to_delete);
1032  }
1033  }
1034 
1035  for (auto & ced : cutelems_to_delete)
1036  if (_cut_elem_map.find(ced) != _cut_elem_map.end())
1037  {
1038  delete _cut_elem_map.find(ced)->second;
1039  _cut_elem_map.erase(ced);
1040  }
1041 
1042  for (unsigned int i = 0; i < _geometric_cuts.size(); ++i)
1043  if (_geometric_cuts[i]->shouldHealMesh())
1044  _sibling_elems[_geometric_cuts[i]->getInterfaceID()].clear();
1045 
1046  if (_displaced_mesh)
1047  {
1048  for (unsigned int i = 0; i < _geometric_cuts.size(); ++i)
1049  if (_geometric_cuts[i]->shouldHealMesh())
1050  _sibling_displaced_elems[_geometric_cuts[i]->getInterfaceID()].clear();
1051  }
1052 
1053  for (auto & ceh : _crack_tip_elems_to_be_healed)
1054  {
1055  _crack_tip_elems.erase(ceh);
1057  delete _cut_elem_map.find(ceh->unique_id())->second;
1058  _cut_elem_map.erase(ceh->unique_id());
1059  }
1060 
1061  if (!healed_geometric_cuts.empty() && _debug_output_level > 0)
1062  {
1063  _console << "\nXFEM mesh healing complete\n";
1064  _console << "Names of healed geometric cut objects: ";
1065  for (auto geomcut : healed_geometric_cuts)
1066  _console << geomcut << " ";
1067  _console << "\n";
1068  _console << "# deleted nodes: " << nodes_to_delete.size() << "\n";
1069  _console << "# deleted elements: " << deleted_elem_count << "\n";
1070  _console << std::flush;
1071  }
1072 
1073  return mesh_changed;
1074 }

Referenced by updateHeal().

◆ initCutIntersectionEdge()

bool XFEM::initCutIntersectionEdge ( Point  cut_origin,
RealVectorValue  cut_normal,
Point &  edge_p1,
Point &  edge_p2,
Real &  dist 
)

Definition at line 901 of file XFEM.C.

903 {
904  dist = 0.0;
905  bool does_intersect = false;
906  Point origin2p1 = edge_p1 - cut_origin;
907  Real plane2p1 = cut_normal(0) * origin2p1(0) + cut_normal(1) * origin2p1(1);
908  Point origin2p2 = edge_p2 - cut_origin;
909  Real plane2p2 = cut_normal(0) * origin2p2(0) + cut_normal(1) * origin2p2(1);
910 
911  if (plane2p1 * plane2p2 < 0.0)
912  {
913  dist = -plane2p1 / (plane2p2 - plane2p1);
914  does_intersect = true;
915  }
916  return does_intersect;
917 }

Referenced by correctCrackExtensionDirection(), and markCutEdgesByState().

◆ initSolution()

void XFEM::initSolution ( NonlinearSystemBase &  nl,
AuxiliarySystem &  aux 
)
overridevirtual

Definition at line 313 of file XFEM.C.

314 {
315  nl.serializeSolution();
316  aux.serializeSolution();
317  NumericVector<Number> & current_solution = *nl.system().current_local_solution;
318  NumericVector<Number> & old_solution = nl.solutionOld();
319  NumericVector<Number> & older_solution = nl.solutionOlder();
320  NumericVector<Number> & current_aux_solution = *aux.system().current_local_solution;
321  NumericVector<Number> & old_aux_solution = aux.solutionOld();
322  NumericVector<Number> & older_aux_solution = aux.solutionOlder();
323 
324  setSolution(nl, _cached_solution, current_solution, old_solution, older_solution);
325  setSolution(
326  aux, _cached_aux_solution, current_aux_solution, old_aux_solution, older_aux_solution);
327 
328  current_solution.close();
329  old_solution.close();
330  older_solution.close();
331  current_aux_solution.close();
332  old_aux_solution.close();
333  older_aux_solution.close();
334 
335  _cached_solution.clear();
336  _cached_aux_solution.clear();
337 }

◆ isElemAtCrackTip()

bool XFEM::isElemAtCrackTip ( const Elem *  elem) const

Definition at line 1604 of file XFEM.C.

1605 {
1606  return (_crack_tip_elems.find(elem) != _crack_tip_elems.end());
1607 }

Referenced by markCutEdgesByGeometry(), and markCutEdgesByState().

◆ isElemCut() [1/2]

bool XFEM::isElemCut ( const Elem *  elem) const

Definition at line 1627 of file XFEM.C.

1628 {
1629  XFEMCutElem * xfce = NULL;
1630  return isElemCut(elem, xfce);
1631 }

◆ isElemCut() [2/2]

bool XFEM::isElemCut ( const Elem *  elem,
XFEMCutElem *&  xfce 
) const

Definition at line 1610 of file XFEM.C.

1611 {
1612  xfce = NULL;
1613  bool is_cut = false;
1614  std::map<unique_id_type, XFEMCutElem *>::const_iterator it;
1615  it = _cut_elem_map.find(elem->unique_id());
1616  if (it != _cut_elem_map.end())
1617  {
1618  xfce = it->second;
1619  const EFAElement * EFAelem = xfce->getEFAElement();
1620  if (EFAelem->isPartial()) // exclude the full crack tip elements
1621  is_cut = true;
1622  }
1623  return is_cut;
1624 }

Referenced by getXFEMFaceWeights(), getXFEMWeights(), and isElemCut().

◆ isPointInsidePhysicalDomain()

bool XFEM::isPointInsidePhysicalDomain ( const Elem *  elem,
const Point &  point 
) const

Return true if the point is inside the element physical domain Note: if this element is not cut, return true too.

Definition at line 1552 of file XFEM.C.

1553 {
1554  std::map<unique_id_type, XFEMCutElem *>::const_iterator it;
1555  it = _cut_elem_map.find(elem->unique_id());
1556  if (it != _cut_elem_map.end())
1557  {
1558  XFEMCutElem * xfce = it->second;
1559 
1560  if (xfce->isPointPhysical(point))
1561  return true;
1562  }
1563  else
1564  return true;
1565 
1566  return false;
1567 }

◆ markCutEdgesByGeometry()

bool XFEM::markCutEdgesByGeometry ( )

Definition at line 395 of file XFEM.C.

396 {
397  bool marked_edges = false;
398  bool marked_nodes = false;
399 
400  for (const auto & gme : _geom_marked_elems_2d)
401  {
402  for (const auto & gmei : gme.second)
403  {
404  EFAElement2D * EFAElem = getEFAElem2D(gme.first);
405 
406  for (unsigned int i = 0; i < gmei._elem_cut_edges.size(); ++i) // mark element edges
407  {
408  if (!EFAElem->isEdgePhantom(
409  gmei._elem_cut_edges[i]._host_side_id)) // must not be phantom edge
410  {
411  _efa_mesh.addElemEdgeIntersection(gme.first->id(),
412  gmei._elem_cut_edges[i]._host_side_id,
413  gmei._elem_cut_edges[i]._distance);
414  marked_edges = true;
415  }
416  }
417 
418  for (unsigned int i = 0; i < gmei._elem_cut_nodes.size(); ++i) // mark element edges
419  {
420  _efa_mesh.addElemNodeIntersection(gme.first->id(), gmei._elem_cut_nodes[i]._host_id);
421  marked_nodes = true;
422  }
423 
424  for (unsigned int i = 0; i < gmei._frag_cut_edges.size();
425  ++i) // MUST DO THIS AFTER MARKING ELEMENT EDGES
426  {
427  if (!EFAElem->getFragment(0)->isSecondaryInteriorEdge(
428  gmei._frag_cut_edges[i]._host_side_id))
429  {
430  if (_efa_mesh.addFragEdgeIntersection(gme.first->id(),
431  gmei._frag_cut_edges[i]._host_side_id,
432  gmei._frag_cut_edges[i]._distance))
433  {
434  marked_edges = true;
435  if (!isElemAtCrackTip(gme.first))
436  _has_secondary_cut = true;
437  }
438  }
439  }
440  }
441  }
442 
443  return marked_edges || marked_nodes;
444 }

Referenced by markCuts().

◆ markCutEdgesByState()

bool XFEM::markCutEdgesByState ( Real  time)

Definition at line 588 of file XFEM.C.

589 {
590  bool marked_edges = false;
591  for (std::map<const Elem *, RealVectorValue>::iterator pmeit = _state_marked_elems.begin();
592  pmeit != _state_marked_elems.end();
593  ++pmeit)
594  {
595  const Elem * elem = pmeit->first;
596  RealVectorValue normal = pmeit->second;
597  EFAElement2D * CEMElem = getEFAElem2D(elem);
598 
599  Real volfrac_elem = getPhysicalVolumeFraction(elem);
600  if (volfrac_elem < 0.25)
601  continue;
602 
603  // continue if elem is already cut twice - IMPORTANT
604  if (CEMElem->isFinalCut())
605  continue;
606 
607  // find the first cut edge
608  unsigned int nsides = CEMElem->numEdges();
609  unsigned int orig_cut_side_id = 999999;
610  Real orig_cut_distance = -1.0;
611  EFANode * orig_node = NULL;
612  EFAEdge * orig_edge = NULL;
613 
614  // crack tip origin coordinates and direction
615  Point crack_tip_origin(0, 0, 0);
616  Point crack_tip_direction(0, 0, 0);
617 
618  if (isElemAtCrackTip(elem)) // crack tip element's crack intiation
619  {
620  orig_cut_side_id = CEMElem->getTipEdgeID();
621  if (orig_cut_side_id < nsides) // valid crack-tip edge found
622  {
623  orig_edge = CEMElem->getEdge(orig_cut_side_id);
624  orig_node = CEMElem->getTipEmbeddedNode();
625  }
626  else
627  mooseError("element ", elem->id(), " has no valid crack-tip edge");
628 
629  // obtain the crack tip origin coordinates and direction.
630  std::map<const Elem *, std::vector<Point>>::iterator ecodm =
632  if (ecodm != _elem_crack_origin_direction_map.end())
633  {
634  crack_tip_origin = (ecodm->second)[0];
635  crack_tip_direction = (ecodm->second)[1];
636  }
637  else
638  mooseError("element ", elem->id(), " cannot find its crack tip origin and direction.");
639  }
640  else
641  {
642  std::map<const Elem *, unsigned int>::iterator mit1;
643  mit1 = _state_marked_elem_sides.find(elem);
644  std::set<const Elem *>::iterator mit2;
645  mit2 = _state_marked_frags.find(elem);
646 
647  if (mit1 != _state_marked_elem_sides.end()) // specified boundary crack initiation
648  {
649  orig_cut_side_id = mit1->second;
650  if (!CEMElem->isEdgePhantom(orig_cut_side_id) &&
651  !CEMElem->getEdge(orig_cut_side_id)->hasIntersection())
652  {
653  orig_cut_distance = 0.5;
654  _efa_mesh.addElemEdgeIntersection(elem->id(), orig_cut_side_id, orig_cut_distance);
655  orig_edge = CEMElem->getEdge(orig_cut_side_id);
656  orig_node = orig_edge->getEmbeddedNode(0);
657  // get a virtual crack tip direction
658  Point elem_center(0.0, 0.0, 0.0);
659  Point edge_center;
660  for (unsigned int i = 0; i < nsides; ++i)
661  {
662  elem_center += getEFANodeCoords(CEMElem->getEdge(i)->getNode(0), CEMElem, elem);
663  elem_center += getEFANodeCoords(CEMElem->getEdge(i)->getNode(1), CEMElem, elem);
664  }
665  elem_center /= nsides * 2.0;
666  edge_center = getEFANodeCoords(orig_edge->getNode(0), CEMElem, elem) +
667  getEFANodeCoords(orig_edge->getNode(1), CEMElem, elem);
668  edge_center /= 2.0;
669  crack_tip_origin = edge_center;
670  crack_tip_direction = elem_center - edge_center;
671  crack_tip_direction /= pow(crack_tip_direction.norm_sq(), 0.5);
672  }
673  else
674  continue; // skip this elem if specified boundary edge is phantom
675  }
676  else if (mit2 != _state_marked_frags.end()) // cut-surface secondary crack initiation
677  {
678  if (CEMElem->numFragments() != 1)
679  mooseError("element ",
680  elem->id(),
681  " flagged for a secondary crack, but has ",
682  CEMElem->numFragments(),
683  " fragments");
684  std::vector<unsigned int> interior_edge_id = CEMElem->getFragment(0)->getInteriorEdgeID();
685  if (interior_edge_id.size() == 1)
686  orig_cut_side_id = interior_edge_id[0];
687  else
688  continue; // skip this elem if more than one interior edges found (i.e. elem's been cut
689  // twice)
690  orig_cut_distance = 0.5;
691  _efa_mesh.addFragEdgeIntersection(elem->id(), orig_cut_side_id, orig_cut_distance);
692  orig_edge = CEMElem->getFragmentEdge(0, orig_cut_side_id);
693  orig_node = orig_edge->getEmbeddedNode(0); // must be an interior embedded node
694  Point elem_center(0.0, 0.0, 0.0);
695  Point edge_center;
696  unsigned int nsides_frag = CEMElem->getFragment(0)->numEdges();
697  for (unsigned int i = 0; i < nsides_frag; ++i)
698  {
699  elem_center +=
700  getEFANodeCoords(CEMElem->getFragmentEdge(0, i)->getNode(0), CEMElem, elem);
701  elem_center +=
702  getEFANodeCoords(CEMElem->getFragmentEdge(0, i)->getNode(1), CEMElem, elem);
703  }
704  elem_center /= nsides_frag * 2.0;
705  edge_center = getEFANodeCoords(orig_edge->getNode(0), CEMElem, elem) +
706  getEFANodeCoords(orig_edge->getNode(1), CEMElem, elem);
707  edge_center /= 2.0;
708  crack_tip_origin = edge_center;
709  crack_tip_direction = elem_center - edge_center;
710  crack_tip_direction /= pow(crack_tip_direction.norm_sq(), 0.5);
711  }
712  else
713  mooseError("element ",
714  elem->id(),
715  " flagged for state-based growth, but has no edge intersections");
716  }
717 
718  Point cut_origin(0.0, 0.0, 0.0);
719  if (orig_node)
720  cut_origin = getEFANodeCoords(orig_node, CEMElem, elem); // cutting plane origin's coords
721  else
722  mooseError("element ", elem->id(), " does not have valid orig_node");
723 
724  // loop through element edges to add possible second cut points
725  std::vector<Point> edge_ends(2, Point(0.0, 0.0, 0.0));
726  Point edge1(0.0, 0.0, 0.0);
727  Point edge2(0.0, 0.0, 0.0);
728  Point cut_edge_point(0.0, 0.0, 0.0);
729  bool find_compatible_direction = false;
730  unsigned int edge_id_keep = 0;
731  Real distance_keep = 0.0;
732  Point normal_keep(0.0, 0.0, 0.0);
733  Real distance = 0.0;
734  bool edge_cut = false;
735 
736  for (unsigned int i = 0; i < nsides; ++i)
737  {
738  if (!orig_edge->isPartialOverlap(*CEMElem->getEdge(i)))
739  {
740  edge_ends[0] = getEFANodeCoords(CEMElem->getEdge(i)->getNode(0), CEMElem, elem);
741  edge_ends[1] = getEFANodeCoords(CEMElem->getEdge(i)->getNode(1), CEMElem, elem);
743  crack_tip_origin, normal, edge_ends[0], edge_ends[1], distance) &&
744  (!CEMElem->isEdgePhantom(i))))
745  {
746  cut_edge_point = distance * edge_ends[1] + (1.0 - distance) * edge_ends[0];
747  distance_keep = distance;
748  edge_id_keep = i;
749  normal_keep = normal;
750  edge_cut = true;
751  break;
752  }
753  }
754  }
755 
756  Point between_two_cuts = (cut_edge_point - crack_tip_origin);
757  between_two_cuts /= pow(between_two_cuts.norm_sq(), 0.5);
758  Real angle_between_two_cuts = between_two_cuts * crack_tip_direction;
759 
760  if (angle_between_two_cuts > std::cos(45.0 / 180.0 * 3.14159)) // original cut direction is good
761  find_compatible_direction = true;
762 
763  if (!find_compatible_direction && edge_cut)
765  CEMElem,
766  orig_edge,
767  normal,
768  crack_tip_origin,
769  crack_tip_direction,
770  distance_keep,
771  edge_id_keep,
772  normal_keep);
773 
774  if (edge_cut)
775  {
777  _efa_mesh.addElemEdgeIntersection(elem->id(), edge_id_keep, distance_keep);
778  else
779  {
780  Point growth_direction(0.0, 0.0, 0.0);
781 
782  growth_direction(0) = -normal_keep(1);
783  growth_direction(1) = normal_keep(0);
784 
785  if (growth_direction * crack_tip_direction < 1.0e-10)
786  growth_direction *= (-1.0);
787 
788  Real x0 = crack_tip_origin(0);
789  Real y0 = crack_tip_origin(1);
790  Real x1 = x0 + _crack_growth_increment * growth_direction(0);
791  Real y1 = y0 + _crack_growth_increment * growth_direction(1);
792 
793  XFEMCrackGrowthIncrement2DCut geometric_cut(x0, y0, x1, y1, time * 0.9, time * 0.9);
794 
795  for (const auto & elem : _mesh->element_ptr_range())
796  {
797  std::vector<CutEdgeForCrackGrowthIncr> elem_cut_edges;
798  EFAElement2D * CEMElem = getEFAElem2D(elem);
799 
800  // continue if elem has been already cut twice - IMPORTANT
801  if (CEMElem->isFinalCut())
802  continue;
803 
804  // mark cut edges for the element and its fragment
805  geometric_cut.cutElementByCrackGrowthIncrement(elem, elem_cut_edges, time);
806 
807  for (unsigned int i = 0; i < elem_cut_edges.size(); ++i) // mark element edges
808  {
809  if (!CEMElem->isEdgePhantom(
810  elem_cut_edges[i]._host_side_id)) // must not be phantom edge
811  {
813  elem->id(), elem_cut_edges[i]._host_side_id, elem_cut_edges[i]._distance);
814  }
815  }
816  }
817  }
818  }
819  // loop though framgent boundary edges to add possible second cut points
820  // N.B. must do this after marking element edges
821  if (CEMElem->numFragments() > 0 && !edge_cut)
822  {
823  for (unsigned int i = 0; i < CEMElem->getFragment(0)->numEdges(); ++i)
824  {
825  if (!orig_edge->isPartialOverlap(*CEMElem->getFragmentEdge(0, i)))
826  {
827  edge_ends[0] =
828  getEFANodeCoords(CEMElem->getFragmentEdge(0, i)->getNode(0), CEMElem, elem);
829  edge_ends[1] =
830  getEFANodeCoords(CEMElem->getFragmentEdge(0, i)->getNode(1), CEMElem, elem);
832  crack_tip_origin, normal, edge_ends[0], edge_ends[1], distance) &&
833  (!CEMElem->getFragment(0)->isSecondaryInteriorEdge(i)))
834  {
835  if (_efa_mesh.addFragEdgeIntersection(elem->id(), edge_id_keep, distance_keep))
836  if (!isElemAtCrackTip(elem))
837  _has_secondary_cut = true;
838  break;
839  }
840  }
841  }
842  }
843 
844  marked_edges = true;
845 
846  } // loop over all state_marked_elems
847 
848  return marked_edges;
849 }

Referenced by markCuts().

◆ markCutFacesByGeometry()

bool XFEM::markCutFacesByGeometry ( )

Definition at line 852 of file XFEM.C.

853 {
854  bool marked_faces = false;
855 
856  for (const auto & gme : _geom_marked_elems_3d)
857  {
858  for (const auto & gmei : gme.second)
859  {
860  EFAElement3D * EFAElem = getEFAElem3D(gme.first);
861 
862  for (unsigned int i = 0; i < gmei._elem_cut_faces.size(); ++i) // mark element faces
863  {
864  if (!EFAElem->isFacePhantom(gmei._elem_cut_faces[i]._face_id)) // must not be phantom face
865  {
866  _efa_mesh.addElemFaceIntersection(gme.first->id(),
867  gmei._elem_cut_faces[i]._face_id,
868  gmei._elem_cut_faces[i]._face_edge,
869  gmei._elem_cut_faces[i]._position);
870  marked_faces = true;
871  }
872  }
873 
874  for (unsigned int i = 0; i < gmei._frag_cut_faces.size();
875  ++i) // MUST DO THIS AFTER MARKING ELEMENT EDGES
876  {
877  if (!EFAElem->getFragment(0)->isThirdInteriorFace(gmei._frag_cut_faces[i]._face_id))
878  {
879  _efa_mesh.addFragFaceIntersection(gme.first->id(),
880  gmei._frag_cut_faces[i]._face_id,
881  gmei._frag_cut_faces[i]._face_edge,
882  gmei._frag_cut_faces[i]._position);
883  marked_faces = true;
884  }
885  }
886  }
887  }
888 
889  return marked_faces;
890 }

Referenced by markCuts().

◆ markCutFacesByState()

bool XFEM::markCutFacesByState ( )

Definition at line 893 of file XFEM.C.

894 {
895  bool marked_faces = false;
896  // TODO: need to finish this for 3D problems
897  return marked_faces;
898 }

Referenced by markCuts().

◆ markCuts()

bool XFEM::markCuts ( Real  time)

Definition at line 378 of file XFEM.C.

379 {
380  bool marked_sides = false;
381  if (_mesh->mesh_dimension() == 2)
382  {
383  marked_sides = markCutEdgesByGeometry();
384  marked_sides |= markCutEdgesByState(time);
385  }
386  else if (_mesh->mesh_dimension() == 3)
387  {
388  marked_sides = markCutFacesByGeometry();
389  marked_sides |= markCutFacesByState();
390  }
391  return marked_sides;
392 }

Referenced by update().

◆ setCrackGrowthMethod()

void XFEM::setCrackGrowthMethod ( bool  use_crack_growth_increment,
Real  crack_growth_increment 
)

Definition at line 1735 of file XFEM.C.

1736 {
1737  _use_crack_growth_increment = use_crack_growth_increment;
1738  _crack_growth_increment = crack_growth_increment;
1739 }

◆ setDebugOutputLevel()

void XFEM::setDebugOutputLevel ( unsigned int  debug_output_level)

Controls amount of debugging information output.

Parameters
debug_output_levelHow much information to output (see description of _debug_output_level)

Definition at line 1742 of file XFEM.C.

1743 {
1744  _debug_output_level = debug_output_level;
1745 }

◆ setSolution()

void XFEM::setSolution ( SystemBase &  sys,
const std::map< unique_id_type, std::vector< Real >> &  stored_solution,
NumericVector< Number > &  current_solution,
NumericVector< Number > &  old_solution,
NumericVector< Number > &  older_solution 
)
private

Set the solution for all locally-owned nodes/elements that have stored values.

Parameters
sysSystem for which the solution is set
stored_solutionData structure that the stored solution is obtained from
current_solutionCurrent solution vector that will be set
old_solutionOld solution vector that will be set
older_solutionOlder solution vector that will be set

Definition at line 1941 of file XFEM.C.

1946 {
1947  for (auto & node : _mesh->local_node_ptr_range())
1948  {
1949  auto mit = stored_solution.find(node->unique_id());
1950  if (mit != stored_solution.end())
1951  {
1952  const std::vector<Real> & stored_node_solution = mit->second;
1953  std::vector<dof_id_type> stored_solution_dofs = getNodeSolutionDofs(node, sys);
1954  setSolutionForDOFs(stored_node_solution,
1955  stored_solution_dofs,
1956  current_solution,
1957  old_solution,
1958  older_solution);
1959  }
1960  }
1961 
1962  for (auto & elem : as_range(_mesh->local_elements_begin(), _mesh->local_elements_end()))
1963  {
1964  auto mit = stored_solution.find(elem->unique_id());
1965  if (mit != stored_solution.end())
1966  {
1967  const std::vector<Real> & stored_elem_solution = mit->second;
1968  std::vector<dof_id_type> stored_solution_dofs = getElementSolutionDofs(elem, sys);
1969  setSolutionForDOFs(stored_elem_solution,
1970  stored_solution_dofs,
1971  current_solution,
1972  old_solution,
1973  older_solution);
1974  }
1975  }
1976 }

Referenced by initSolution().

◆ setSolutionForDOFs()

void XFEM::setSolutionForDOFs ( const std::vector< Real > &  stored_solution,
const std::vector< dof_id_type > &  stored_solution_dofs,
NumericVector< Number > &  current_solution,
NumericVector< Number > &  old_solution,
NumericVector< Number > &  older_solution 
)
private

Set the solution for a set of DOFs.

Parameters
stored_solutionStored solution values to set the solution to
stored_solution_dofsDof indices for the entries in stored_solution
current_solutionCurrent solution vector that will be set
old_solutionOld solution vector that will be set
older_solutionOlder solution vector that will be set

Definition at line 1979 of file XFEM.C.

1984 {
1985  // Solution vector is stored first for current, then old and older solutions.
1986  // These are the offsets to the beginning of the old and older solutions in the vector.
1987  const auto old_solution_offset = stored_solution_dofs.size();
1988  const auto older_solution_offset = old_solution_offset * 2;
1989 
1990  for (std::size_t i = 0; i < stored_solution_dofs.size(); ++i)
1991  {
1992  current_solution.set(stored_solution_dofs[i], stored_solution[i]);
1993  if (_fe_problem->isTransient())
1994  {
1995  old_solution.set(stored_solution_dofs[i], stored_solution[old_solution_offset + i]);
1996  older_solution.set(stored_solution_dofs[i], stored_solution[older_solution_offset + i]);
1997  }
1998  }
1999 }

Referenced by setSolution().

◆ setXFEMQRule()

void XFEM::setXFEMQRule ( std::string &  xfem_qrule)

Definition at line 1724 of file XFEM.C.

1725 {
1726  if (xfem_qrule == "volfrac")
1728  else if (xfem_qrule == "moment_fitting")
1730  else if (xfem_qrule == "direct")
1732 }

◆ storeCrackTipOriginAndDirection()

void XFEM::storeCrackTipOriginAndDirection ( )

Definition at line 189 of file XFEM.C.

190 {
192  std::set<EFAElement *> CrackTipElements = _efa_mesh.getCrackTipElements();
193  std::set<EFAElement *>::iterator sit;
194  for (sit = CrackTipElements.begin(); sit != CrackTipElements.end(); ++sit)
195  {
196  if (_mesh->mesh_dimension() == 2)
197  {
198  EFAElement2D * CEMElem = dynamic_cast<EFAElement2D *>(*sit);
199  EFANode * tip_node = CEMElem->getTipEmbeddedNode();
200  unsigned int cts_id = CEMElem->getCrackTipSplitElementID();
201 
202  Point origin(0, 0, 0);
203  Point direction(0, 0, 0);
204 
205  std::map<unique_id_type, XFEMCutElem *>::const_iterator it;
206  it = _cut_elem_map.find(_mesh->elem_ptr(cts_id)->unique_id());
207  if (it != _cut_elem_map.end())
208  {
209  const XFEMCutElem * xfce = it->second;
210  const EFAElement * EFAelem = xfce->getEFAElement();
211  if (EFAelem->isPartial()) // exclude the full crack tip elements
212  {
213  xfce->getCrackTipOriginAndDirection(tip_node->id(), origin, direction);
214  }
215  }
216 
217  std::vector<Point> tip_data;
218  tip_data.push_back(origin);
219  tip_data.push_back(direction);
220  const Elem * elem = _mesh->elem_ptr((*sit)->id());
222  std::pair<const Elem *, std::vector<Point>>(elem, tip_data));
223  }
224  }
225 }

Referenced by update().

◆ storeSolutionForElement()

void XFEM::storeSolutionForElement ( const Elem *  elem_to_store_to,
const Elem *  elem_to_store_from,
SystemBase &  sys,
std::map< unique_id_type, std::vector< Real >> &  stored_solution,
const NumericVector< Number > &  current_solution,
const NumericVector< Number > &  old_solution,
const NumericVector< Number > &  older_solution 
)
private

Store the solution in stored_solution for a given element.

Parameters
elem_to_store_toElement for which the solution will be stored
elem_to_store_fromElement from which the solution to be stored is obtained
sysSystem from which the solution is stored
stored_solutionData structure that the stored solution is saved to
current_solutionCurrent solution vector that the solution is obtained from
old_solutionOld solution vector that the solution is obtained from
older_solutionOlder solution vector that the solution is obtained from

Definition at line 1907 of file XFEM.C.

1914 {
1915  std::vector<dof_id_type> stored_solution_dofs = getElementSolutionDofs(elem_to_store_from, sys);
1916  std::vector<Real> stored_solution_scratch;
1917  // Size for current solution, as well as for old, and older solution only for transient case
1918  std::size_t stored_solution_size =
1919  (_fe_problem->isTransient() ? stored_solution_dofs.size() * 3 : stored_solution_dofs.size());
1920  stored_solution_scratch.reserve(stored_solution_size);
1921 
1922  // Store in the order defined in stored_solution_dofs first for the current, then for old and
1923  // older if applicable
1924  for (auto dof : stored_solution_dofs)
1925  stored_solution_scratch.push_back(current_solution(dof));
1926 
1927  if (_fe_problem->isTransient())
1928  {
1929  for (auto dof : stored_solution_dofs)
1930  stored_solution_scratch.push_back(old_solution(dof));
1931 
1932  for (auto dof : stored_solution_dofs)
1933  stored_solution_scratch.push_back(older_solution(dof));
1934  }
1935 
1936  if (stored_solution_scratch.size() > 0)
1937  stored_solution[elem_to_store_to->unique_id()] = stored_solution_scratch;
1938 }

Referenced by cutMeshWithEFA().

◆ storeSolutionForNode()

void XFEM::storeSolutionForNode ( const Node *  node_to_store_to,
const Node *  node_to_store_from,
SystemBase &  sys,
std::map< unique_id_type, std::vector< Real >> &  stored_solution,
const NumericVector< Number > &  current_solution,
const NumericVector< Number > &  old_solution,
const NumericVector< Number > &  older_solution 
)
private

Store the solution in stored_solution for a given node.

Parameters
node_to_store_toNode for which the solution will be stored
node_to_store_fromNode from which the solution to be stored is obtained
sysSystem from which the solution is stored
stored_solutionData structure that the stored solution is saved to
current_solutionCurrent solution vector that the solution is obtained from
old_solutionOld solution vector that the solution is obtained from
older_solutionOlder solution vector that the solution is obtained from

Definition at line 1873 of file XFEM.C.

1880 {
1881  std::vector<dof_id_type> stored_solution_dofs = getNodeSolutionDofs(node_to_store_from, sys);
1882  std::vector<Real> stored_solution_scratch;
1883  // Size for current solution, as well as for old, and older solution only for transient case
1884  std::size_t stored_solution_size =
1885  (_fe_problem->isTransient() ? stored_solution_dofs.size() * 3 : stored_solution_dofs.size());
1886  stored_solution_scratch.reserve(stored_solution_size);
1887 
1888  // Store in the order defined in stored_solution_dofs first for the current, then for old and
1889  // older if applicable
1890  for (auto dof : stored_solution_dofs)
1891  stored_solution_scratch.push_back(current_solution(dof));
1892 
1893  if (_fe_problem->isTransient())
1894  {
1895  for (auto dof : stored_solution_dofs)
1896  stored_solution_scratch.push_back(old_solution(dof));
1897 
1898  for (auto dof : stored_solution_dofs)
1899  stored_solution_scratch.push_back(older_solution(dof));
1900  }
1901 
1902  if (stored_solution_scratch.size() > 0)
1903  stored_solution[node_to_store_to->unique_id()] = stored_solution_scratch;
1904 }

Referenced by cutMeshWithEFA().

◆ update()

bool XFEM::update ( Real  time,
NonlinearSystemBase &  nl,
AuxiliarySystem &  aux 
)
overridevirtual

Definition at line 265 of file XFEM.C.

266 {
267  if (_moose_mesh->isDistributedMesh())
268  mooseError("Use of XFEM with distributed mesh is not yet supported");
269 
270  bool mesh_changed = false;
271 
272  buildEFAMesh();
273 
274  _fe_problem->execute(EXEC_XFEM_MARK);
275 
277 
278  if (markCuts(time))
279  mesh_changed = cutMeshWithEFA(nl, aux);
280 
281  if (mesh_changed)
282  {
283  buildEFAMesh();
285  }
286 
287  if (mesh_changed)
288  {
289  // _mesh->find_neighbors();
290  // _mesh->contract();
291  _mesh->allow_renumbering(false);
292  _mesh->skip_partitioning(true);
293  _mesh->prepare_for_use();
294  // _mesh->prepare_for_use(true,true); //doing this preserves the numbering, but generates
295  // warning
296 
297  if (_displaced_mesh)
298  {
299  _displaced_mesh->allow_renumbering(false);
300  _displaced_mesh->skip_partitioning(true);
301  _displaced_mesh->prepare_for_use();
302  // _displaced_mesh->prepare_for_use(true,true);
303  }
304  }
305 
308 
309  return mesh_changed;
310 }

◆ updateHeal()

bool XFEM::updateHeal ( )
overridevirtual

Definition at line 228 of file XFEM.C.

229 {
230  bool mesh_changed = false;
231 
232  mesh_changed = healMesh();
233 
234  if (mesh_changed)
235  {
236  _mesh->update_parallel_id_counts();
237  MeshCommunication().make_elems_parallel_consistent(*_mesh);
238  MeshCommunication().make_nodes_parallel_consistent(*_mesh);
239  // _mesh->find_neighbors();
240  // _mesh->contract();
241  _mesh->allow_renumbering(false);
242  _mesh->skip_partitioning(true);
243  _mesh->prepare_for_use();
244  // _mesh->prepare_for_use(true,true); //doing this preserves the numbering, but generates
245  // warning
246 
247  if (_displaced_mesh)
248  {
249  _displaced_mesh->update_parallel_id_counts();
250  MeshCommunication().make_elems_parallel_consistent(*_displaced_mesh);
251  MeshCommunication().make_nodes_parallel_consistent(*_displaced_mesh);
252  _displaced_mesh->allow_renumbering(false);
253  _displaced_mesh->skip_partitioning(true);
254  _displaced_mesh->prepare_for_use();
255  // _displaced_mesh->prepare_for_use(true,true);
256  }
257  }
258 
259  _geom_marker_id_elems.clear();
260 
261  return mesh_changed;
262 }

Member Data Documentation

◆ _cached_aux_solution

std::map<unique_id_type, std::vector<Real> > XFEM::_cached_aux_solution
private

Data structure to store the auxiliary solution for nodes/elements affected by XFEM For each node/element, this is stored as a vector that contains all components of all applicable variables in an order defined by getElementSolutionDofs() or getNodeSolutionDofs().

This vector first contains the current solution in that order, followed by the old and older solutions, also in that same order.

Definition at line 320 of file XFEM.h.

Referenced by cutMeshWithEFA(), and initSolution().

◆ _cached_solution

std::map<unique_id_type, std::vector<Real> > XFEM::_cached_solution
private

Data structure to store the nonlinear solution for nodes/elements affected by XFEM For each node/element, this is stored as a vector that contains all components of all applicable variables in an order defined by getElementSolutionDofs() or getNodeSolutionDofs().

This vector first contains the current solution in that order, followed by the old and older solutions, also in that same order.

Definition at line 311 of file XFEM.h.

Referenced by cutMeshWithEFA(), and initSolution().

◆ _crack_growth_increment

Real XFEM::_crack_growth_increment
private

Definition at line 265 of file XFEM.h.

Referenced by markCutEdgesByState(), and setCrackGrowthMethod().

◆ _crack_tip_elems

std::set<const Elem *> XFEM::_crack_tip_elems
private

Definition at line 270 of file XFEM.h.

Referenced by cutMeshWithEFA(), healMesh(), and isElemAtCrackTip().

◆ _crack_tip_elems_to_be_healed

std::set<const Elem *> XFEM::_crack_tip_elems_to_be_healed
private

Definition at line 271 of file XFEM.h.

Referenced by cutMeshWithEFA(), and healMesh().

◆ _cut_elem_map

std::map<unique_id_type, XFEMCutElem *> XFEM::_cut_elem_map
private

◆ _debug_output_level

unsigned int XFEM::_debug_output_level
private

Controls amount of debugging output information 0: None 1: Summary 2: Details on modifications to mesh 3: Full dump of element fragment algorithm mesh.

Definition at line 302 of file XFEM.h.

Referenced by cutMeshWithEFA(), healMesh(), and setDebugOutputLevel().

◆ _efa_mesh

ElementFragmentAlgorithm XFEM::_efa_mesh
private

◆ _elem_crack_origin_direction_map

std::map<const Elem *, std::vector<Point> > XFEM::_elem_crack_origin_direction_map
private

◆ _geom_marked_elems_2d

std::map<const Elem *, std::vector<Xfem::GeomMarkedElemInfo2D> > XFEM::_geom_marked_elems_2d
private

Data structure for storing information about all 2D elements to be cut by geometry.

Definition at line 284 of file XFEM.h.

Referenced by addGeomMarkedElem2D(), clearGeomMarkedElems(), and markCutEdgesByGeometry().

◆ _geom_marked_elems_3d

std::map<const Elem *, std::vector<Xfem::GeomMarkedElemInfo3D> > XFEM::_geom_marked_elems_3d
private

Data structure for storing information about all 3D elements to be cut by geometry.

Definition at line 287 of file XFEM.h.

Referenced by addGeomMarkedElem3D(), clearGeomMarkedElems(), and markCutFacesByGeometry().

◆ _geom_marker_id_elems

std::map<unsigned int, std::set<unsigned int> > XFEM::_geom_marker_id_elems
private

Data structure for storing the elements cut by specific geometric cutters.

Definition at line 290 of file XFEM.h.

Referenced by addGeomMarkedElem2D(), addGeomMarkedElem3D(), cutMeshWithEFA(), and updateHeal().

◆ _geom_marker_id_map

std::map<const GeometricCutUserObject *, unsigned int> XFEM::_geom_marker_id_map
private

Data structure for storing the GeommetricCutUserObjects and their corresponding id.

Definition at line 293 of file XFEM.h.

Referenced by addGeometricCut(), and getGeometricCutID().

◆ _geometric_cuts

std::vector<const GeometricCutUserObject *> XFEM::_geometric_cuts
private

Definition at line 267 of file XFEM.h.

Referenced by addGeometricCut(), cutMeshWithEFA(), and healMesh().

◆ _has_secondary_cut

bool XFEM::_has_secondary_cut
private

Definition at line 260 of file XFEM.h.

Referenced by has_secondary_cut(), markCutEdgesByGeometry(), markCutEdgesByState(), and XFEM().

◆ _sibling_displaced_elems

std::map<unsigned int, ElementPairLocator::ElementPairList> XFEM::_sibling_displaced_elems
private

Definition at line 273 of file XFEM.h.

Referenced by cutMeshWithEFA(), getXFEMDisplacedCutElemPairs(), and healMesh().

◆ _sibling_elems

std::map<unsigned int, ElementPairLocator::ElementPairList> XFEM::_sibling_elems
private

Definition at line 272 of file XFEM.h.

Referenced by cutMeshWithEFA(), getXFEMCutElemPairs(), and healMesh().

◆ _state_marked_elem_sides

std::map<const Elem *, unsigned int> XFEM::_state_marked_elem_sides
private

Definition at line 281 of file XFEM.h.

Referenced by addStateMarkedElem(), clearStateMarkedElems(), and markCutEdgesByState().

◆ _state_marked_elems

std::map<const Elem *, RealVectorValue> XFEM::_state_marked_elems
private

Definition at line 279 of file XFEM.h.

Referenced by addStateMarkedElem(), clearStateMarkedElems(), and markCutEdgesByState().

◆ _state_marked_frags

std::set<const Elem *> XFEM::_state_marked_frags
private

Definition at line 280 of file XFEM.h.

Referenced by addStateMarkedFrag(), clearStateMarkedElems(), and markCutEdgesByState().

◆ _use_crack_growth_increment

bool XFEM::_use_crack_growth_increment
private

Definition at line 264 of file XFEM.h.

Referenced by markCutEdgesByState(), and setCrackGrowthMethod().

◆ _XFEM_qrule

Xfem::XFEM_QRULE XFEM::_XFEM_qrule
private

Definition at line 262 of file XFEM.h.

Referenced by getXFEMQRule(), and setXFEMQRule().


The documentation for this class was generated from the following files:
XFEM::_geom_marker_id_elems
std::map< unsigned int, std::set< unsigned int > > _geom_marker_id_elems
Data structure for storing the elements cut by specific geometric cutters.
Definition: XFEM.h:290
ElementFragmentAlgorithm::updatePhysicalLinksAndFragments
void updatePhysicalLinksAndFragments()
Definition: ElementFragmentAlgorithm.C:290
EFAFragment2D::getInteriorEdgeID
std::vector< unsigned int > getInteriorEdgeID() const
Definition: EFAFragment2D.C:266
ElementFragmentAlgorithm::initCrackTipTopology
void initCrackTipTopology()
Definition: ElementFragmentAlgorithm.C:200
EFANode::id
unsigned int id() const
Definition: EFANode.C:36
EFAElement2D::getEdge
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAElement2D.C:1475
XFEM::isElemAtCrackTip
bool isElemAtCrackTip(const Elem *elem) const
Definition: XFEM.C:1604
XFEM::storeSolutionForElement
void storeSolutionForElement(const Elem *elem_to_store_to, const Elem *elem_to_store_from, SystemBase &sys, std::map< unique_id_type, std::vector< Real >> &stored_solution, const NumericVector< Number > &current_solution, const NumericVector< Number > &old_solution, const NumericVector< Number > &older_solution)
Store the solution in stored_solution for a given element.
Definition: XFEM.C:1907
EFAElement2D::isFinalCut
virtual bool isFinalCut() const
Definition: EFAElement2D.C:791
EFAElement
Definition: EFAElement.h:19
ElementFragmentAlgorithm::getNewNodes
const std::vector< EFANode * > & getNewNodes()
Definition: ElementFragmentAlgorithm.h:81
Xfem::shapeFunc2D
void shapeFunc2D(unsigned int nen, std::vector< Real > &ss, std::vector< Point > &xl, std::vector< std::vector< Real >> &shp, Real &xsj, bool natl_flg)
Definition: XFEMFuncs.C:269
EFAElement3D::getFragmentFace
EFAFace * getFragmentFace(unsigned int frag_id, unsigned int face_id) const
Definition: EFAElement3D.C:1706
XFEM::_XFEM_qrule
Xfem::XFEM_QRULE _XFEM_qrule
Definition: XFEM.h:262
EFAFragment3D::numFaces
unsigned int numFaces() const
Definition: EFAFragment3D.C:271
XFEMCutElem::getIntersectionInfo
virtual void getIntersectionInfo(unsigned int plane_id, Point &normal, std::vector< Point > &intersectionPoints, MeshBase *displaced_mesh=NULL) const =0
XFEM::storeSolutionForNode
void storeSolutionForNode(const Node *node_to_store_to, const Node *node_to_store_from, SystemBase &sys, std::map< unique_id_type, std::vector< Real >> &stored_solution, const NumericVector< Number > &current_solution, const NumericVector< Number > &old_solution, const NumericVector< Number > &older_solution)
Store the solution in stored_solution for a given node.
Definition: XFEM.C:1873
XFEM::_state_marked_frags
std::set< const Elem * > _state_marked_frags
Definition: XFEM.h:280
XFEM::addStateMarkedElem
void addStateMarkedElem(unsigned int elem_id, RealVectorValue &normal)
Definition: XFEM.C:112
EXEC_XFEM_MARK
const ExecFlagType EXEC_XFEM_MARK
Exec flag used to execute MooseObjects while elements are being marked for cutting by XFEM.
XFEM::getEFAElem3D
EFAElement3D * getEFAElem3D(const Elem *elem)
Get the EFAElement3D object for a specified libMesh element.
Definition: XFEM.C:1663
pow
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
Definition: ExpressionBuilder.h:673
EFAElement3D::getFragment
EFAFragment3D * getFragment(unsigned int frag_id) const
Definition: EFAElement3D.C:1372
EFAFace::getNode
EFANode * getNode(unsigned int node_id) const
Definition: EFAFace.C:99
XFEMCutElem::getPhysicalVolumeFraction
Real getPhysicalVolumeFraction() const
Returns the volume fraction of the element fragment.
Definition: XFEMCutElem.C:49
ElementFragmentAlgorithm::add3DElement
EFAElement * add3DElement(std::vector< unsigned int > quad, unsigned int id)
Definition: ElementFragmentAlgorithm.C:133
XFEM::_geom_marked_elems_2d
std::map< const Elem *, std::vector< Xfem::GeomMarkedElemInfo2D > > _geom_marked_elems_2d
Data structure for storing information about all 2D elements to be cut by geometry.
Definition: XFEM.h:284
XFEMCutElem::getFragmentFaces
virtual void getFragmentFaces(std::vector< std::vector< Point >> &frag_faces, MeshBase *displaced_mesh=NULL) const =0
EFAFragment3D::isThirdInteriorFace
bool isThirdInteriorFace(unsigned int face_id) const
Definition: EFAFragment3D.C:253
XFEM::cutMeshWithEFA
bool cutMeshWithEFA(NonlinearSystemBase &nl, AuxiliarySystem &aux)
Definition: XFEM.C:1077
XFEM::getElementSolutionDofs
std::vector< dof_id_type > getElementSolutionDofs(const Elem *elem, SystemBase &sys) const
Get a vector of the dof indices for all components of all variables associated with an element.
Definition: XFEM.C:2002
ElementFragmentAlgorithm::addFragFaceIntersection
void addFragFaceIntersection(unsigned int ElemID, unsigned int FragFaceID, std::vector< unsigned int > FragFaceEdgeID, std::vector< double > position)
Definition: ElementFragmentAlgorithm.C:281
XFEM::clearStateMarkedElems
void clearStateMarkedElems()
Definition: XFEM.C:154
XFEM::_state_marked_elems
std::map< const Elem *, RealVectorValue > _state_marked_elems
Definition: XFEM.h:279
XFEM::isElemCut
bool isElemCut(const Elem *elem, XFEMCutElem *&xfce) const
Definition: XFEM.C:1610
ElementFragmentAlgorithm::updateTopology
void updateTopology(bool mergeUncutVirtualEdges=true)
Definition: ElementFragmentAlgorithm.C:302
Xfem::DIRECT
Definition: XFEM.h:41
XFEM::markCutFacesByGeometry
bool markCutFacesByGeometry()
Definition: XFEM.C:852
EFAElement::getLocalNodeIndex
unsigned int getLocalNodeIndex(EFANode *node) const
Definition: EFAElement.C:111
XFEM::buildEFAMesh
void buildEFAMesh()
Definition: XFEM.C:340
XFEM::setSolutionForDOFs
void setSolutionForDOFs(const std::vector< Real > &stored_solution, const std::vector< dof_id_type > &stored_solution_dofs, NumericVector< Number > &current_solution, NumericVector< Number > &old_solution, NumericVector< Number > &older_solution)
Set the solution for a set of DOFs.
Definition: XFEM.C:1979
XFEM::correctCrackExtensionDirection
void correctCrackExtensionDirection(const Elem *elem, EFAElement2D *CEMElem, EFAEdge *orig_edge, Point normal, Point crack_tip_origin, Point crack_tip_direction, Real &distance_keep, unsigned int &edge_id_keep, Point &normal_keep)
Definition: XFEM.C:447
XFEMCutElem::getFaceWeightMultipliers
void getFaceWeightMultipliers(MooseArray< Real > &face_weights, QBase *qrule, Xfem::XFEM_QRULE xfem_qrule, const MooseArray< Point > &q_points, unsigned int side)
Definition: XFEMCutElem.C:75
EFAElement2D::getFragmentEdge
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
Definition: EFAElement2D.C:1481
XFEM::_geom_marked_elems_3d
std::map< const Elem *, std::vector< Xfem::GeomMarkedElemInfo3D > > _geom_marked_elems_3d
Data structure for storing information about all 3D elements to be cut by geometry.
Definition: XFEM.h:287
XFEM::markCutFacesByState
bool markCutFacesByState()
Definition: XFEM.C:893
XFEM::getPhysicalVolumeFraction
Real getPhysicalVolumeFraction(const Elem *elem) const
Get the volume fraction of an element that is physical.
Definition: XFEM.C:1532
XFEM::getXFEMQRule
Xfem::XFEM_QRULE & getXFEMQRule()
Definition: XFEM.C:1718
ElementFragmentAlgorithm::addElemFaceIntersection
void addElemFaceIntersection(unsigned int elemid, unsigned int faceid, std::vector< unsigned int > edgeid, std::vector< double > position)
Definition: ElementFragmentAlgorithm.C:261
EFAElement3D
Definition: EFAElement3D.h:20
XFEMCutElem2D
Definition: XFEMCutElem2D.h:24
XFEM::_state_marked_elem_sides
std::map< const Elem *, unsigned int > _state_marked_elem_sides
Definition: XFEM.h:281
ElementFragmentAlgorithm::printMesh
void printMesh()
Definition: ElementFragmentAlgorithm.C:504
ElementFragmentAlgorithm::addFragEdgeIntersection
bool addFragEdgeIntersection(unsigned int elemid, unsigned int frag_edge_id, double position)
Definition: ElementFragmentAlgorithm.C:245
XFEM::_cached_solution
std::map< unique_id_type, std::vector< Real > > _cached_solution
Data structure to store the nonlinear solution for nodes/elements affected by XFEM For each node/elem...
Definition: XFEM.h:311
XFEM::markCutEdgesByState
bool markCutEdgesByState(Real time)
Definition: XFEM.C:588
EFAElement3D::isFacePhantom
bool isFacePhantom(unsigned int face_id) const
Definition: EFAElement3D.C:1814
EFAElement2D::isEdgePhantom
bool isEdgePhantom(unsigned int edge_id) const
Definition: EFAElement2D.C:1537
XFEM::_geometric_cuts
std::vector< const GeometricCutUserObject * > _geometric_cuts
Definition: XFEM.h:267
XFEM::setSolution
void setSolution(SystemBase &sys, const std::map< unique_id_type, std::vector< Real >> &stored_solution, NumericVector< Number > &current_solution, NumericVector< Number > &old_solution, NumericVector< Number > &older_solution)
Set the solution for all locally-owned nodes/elements that have stored values.
Definition: XFEM.C:1941
ElementFragmentAlgorithm::getParentElements
const std::vector< EFAElement * > & getParentElements()
Definition: ElementFragmentAlgorithm.h:80
XFEMCutElem::getEFAElement
virtual const EFAElement * getEFAElement() const =0
XFEM::_use_crack_growth_increment
bool _use_crack_growth_increment
Definition: XFEM.h:264
ElementFragmentAlgorithm::updateEdgeNeighbors
void updateEdgeNeighbors()
Definition: ElementFragmentAlgorithm.C:177
XFEM::getEFAElem2D
EFAElement2D * getEFAElem2D(const Elem *elem)
Get the EFAElement2D object for a specified libMesh element.
Definition: XFEM.C:1651
EFAElement2D::getCrackTipSplitElementID
unsigned int getCrackTipSplitElementID() const
Definition: EFAElement2D.C:594
EFAElement::getMasterInfo
virtual void getMasterInfo(EFANode *node, std::vector< EFANode * > &master_nodes, std::vector< double > &master_weights) const =0
EFAEdge::getNode
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:179
GeometricCutUserObject::setInterfaceID
void setInterfaceID(unsigned int interface_id)
Set the interface ID for this cutting object.
Definition: GeometricCutUserObject.h:178
XFEM::getNodeSolutionDofs
std::vector< dof_id_type > getNodeSolutionDofs(const Node *node, SystemBase &sys) const
Get a vector of the dof indices for all components of all variables associated with a node.
Definition: XFEM.C:2028
EFAElement2D::getFragment
EFAFragment2D * getFragment(unsigned int frag_id) const
Definition: EFAElement2D.C:1388
name
const std::string name
Definition: Setup.h:21
ElementFragmentAlgorithm::getChildElements
const std::vector< EFAElement * > & getChildElements()
Definition: ElementFragmentAlgorithm.h:79
ElementFragmentAlgorithm::reset
void reset()
Definition: ElementFragmentAlgorithm.C:330
XFEM::_debug_output_level
unsigned int _debug_output_level
Controls amount of debugging output information 0: None 1: Summary 2: Details on modifications to mes...
Definition: XFEM.h:302
ElementFragmentAlgorithm::add2DElement
EFAElement * add2DElement(std::vector< unsigned int > quad, unsigned int id)
Definition: ElementFragmentAlgorithm.C:102
XFEM::clearGeomMarkedElems
void clearGeomMarkedElems()
Clear out the list of elements to be marked for cutting.
Definition: XFEM.C:182
EFAFragment2D::isSecondaryInteriorEdge
bool isSecondaryInteriorEdge(unsigned int edge_id) const
Definition: EFAFragment2D.C:278
XFEM::_sibling_elems
std::map< unsigned int, ElementPairLocator::ElementPairList > _sibling_elems
Definition: XFEM.h:272
XFEM::_crack_growth_increment
Real _crack_growth_increment
Definition: XFEM.h:265
XFEM::_crack_tip_elems_to_be_healed
std::set< const Elem * > _crack_tip_elems_to_be_healed
Definition: XFEM.h:271
XFEM::_cut_elem_map
std::map< unique_id_type, XFEMCutElem * > _cut_elem_map
Definition: XFEM.h:269
XFEMCutElem::getWeightMultipliers
void getWeightMultipliers(MooseArray< Real > &weights, QBase *qrule, Xfem::XFEM_QRULE xfem_qrule, const MooseArray< Point > &q_points)
Definition: XFEMCutElem.C:61
XFEM::_crack_tip_elems
std::set< const Elem * > _crack_tip_elems
Definition: XFEM.h:270
XFEMCrackGrowthIncrement2DCut
Definition: XFEMCrackGrowthIncrement2DCut.h:26
EFAEdge::getEmbeddedNode
EFANode * getEmbeddedNode(unsigned int index) const
Definition: EFAEdge.C:330
EFANode::N_CATEGORY_PERMANENT
Definition: EFANode.h:19
XFEM::healMesh
bool healMesh()
Potentially heal the mesh by merging some of the pairs of partial elements cut by XFEM back into sing...
Definition: XFEM.C:920
Xfem::MOMENT_FITTING
Definition: XFEM.h:40
XFEMCutElem::computePhysicalVolumeFraction
virtual void computePhysicalVolumeFraction()=0
Computes the volume fraction of the element fragment.
XFEM::_sibling_displaced_elems
std::map< unsigned int, ElementPairLocator::ElementPairList > _sibling_displaced_elems
Definition: XFEM.h:273
EFAElement3D::numFragments
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:269
EFAEdge
Definition: EFAEdge.h:16
XFEM::initCutIntersectionEdge
bool initCutIntersectionEdge(Point cut_origin, RealVectorValue cut_normal, Point &edge_p1, Point &edge_p2, Real &dist)
Definition: XFEM.C:901
EFANode
Definition: EFANode.h:14
EFAEdge::hasIntersection
bool hasIntersection() const
Definition: EFAEdge.C:198
XFEM::_cached_aux_solution
std::map< unique_id_type, std::vector< Real > > _cached_aux_solution
Data structure to store the auxiliary solution for nodes/elements affected by XFEM For each node/elem...
Definition: XFEM.h:320
EFAEdge::isPartialOverlap
bool isPartialOverlap(const EFAEdge &other) const
Definition: EFAEdge.C:57
XFEM::getEFANodeCoords
Point getEFANodeCoords(EFANode *CEMnode, EFAElement *CEMElem, const Elem *elem, MeshBase *displaced_mesh=NULL) const
Definition: XFEM.C:1500
XFEMCutElem::isPointPhysical
bool isPointPhysical(const Point &p) const
Definition: XFEMCutElem.C:191
ElementFragmentAlgorithm::restoreFragmentInfo
void restoreFragmentInfo(EFAElement *const elem, const EFAElement *const from_elem)
Definition: ElementFragmentAlgorithm.C:410
EFAElement::isPartial
virtual bool isPartial() const =0
EFAElement2D::numFragments
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:202
Xfem::stdQuadr2D
void stdQuadr2D(unsigned int nen, unsigned int iord, std::vector< std::vector< Real >> &sg2)
Definition: XFEMFuncs.C:96
EFAElement2D
Definition: EFAElement2D.h:20
EFAElement2D::getTipEmbeddedNode
EFANode * getTipEmbeddedNode() const
Definition: EFAElement2D.C:1636
EFAElement2D::numEdges
unsigned int numEdges() const
Definition: EFAElement2D.C:1447
EFAFace::numNodes
unsigned int numNodes() const
Definition: EFAFace.C:87
XFEM::markCuts
bool markCuts(Real time)
Definition: XFEM.C:378
XFEM::markCutEdgesByGeometry
bool markCutEdgesByGeometry()
Definition: XFEM.C:395
XFEMCutElem::getCutPlaneOrigin
virtual Point getCutPlaneOrigin(unsigned int plane_id, MeshBase *displaced_mesh=NULL) const =0
XFEMCutElem::getCutPlaneNormal
virtual Point getCutPlaneNormal(unsigned int plane_id, MeshBase *displaced_mesh=NULL) const =0
XFEMCutElem::getCrackTipOriginAndDirection
virtual void getCrackTipOriginAndDirection(unsigned tip_id, Point &origin, Point &direction) const =0
EFAFragment2D::numEdges
unsigned int numEdges() const
Definition: EFAFragment2D.C:296
XFEM::_efa_mesh
ElementFragmentAlgorithm _efa_mesh
Definition: XFEM.h:295
ElementFragmentAlgorithm::getElemByID
EFAElement * getElemByID(unsigned int id)
Definition: ElementFragmentAlgorithm.C:590
ElementFragmentAlgorithm::getCrackTipElements
const std::set< EFAElement * > & getCrackTipElements()
Definition: ElementFragmentAlgorithm.h:82
XFEMCutElem
Definition: XFEMCutElem.h:29
XFEM::_geom_marker_id_map
std::map< const GeometricCutUserObject *, unsigned int > _geom_marker_id_map
Data structure for storing the GeommetricCutUserObjects and their corresponding id.
Definition: XFEM.h:293
XFEM::storeCrackTipOriginAndDirection
void storeCrackTipOriginAndDirection()
Definition: XFEM.C:189
XFEMCutElem3D
Definition: XFEMCutElem3D.h:24
ElementFragmentAlgorithm::addElemEdgeIntersection
void addElemEdgeIntersection(unsigned int elemid, unsigned int edgeid, double position)
Definition: ElementFragmentAlgorithm.C:212
Xfem::VOLFRAC
Definition: XFEM.h:39
EFAElement2D::getTipEdgeID
unsigned int getTipEdgeID() const
Definition: EFAElement2D.C:1608
ElementFragmentAlgorithm::addElemNodeIntersection
void addElemNodeIntersection(unsigned int elemid, unsigned int nodeid)
Definition: ElementFragmentAlgorithm.C:228
XFEM::_has_secondary_cut
bool _has_secondary_cut
Definition: XFEM.h:260
XFEM::_elem_crack_origin_direction_map
std::map< const Elem *, std::vector< Point > > _elem_crack_origin_direction_map
Definition: XFEM.h:275