https://mooseframework.inl.gov
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
EFAElement3D Class Reference

#include <EFAElement3D.h>

Inheritance diagram for EFAElement3D:
[legend]

Public Member Functions

 EFAElement3D (unsigned int eid, unsigned int n_nodes, unsigned int n_faces)
 
 EFAElement3D (const EFAElement3D *from_elem, bool convert_to_local)
 
 ~EFAElement3D ()
 
virtual unsigned int numFragments () const
 
virtual bool isPartial () const
 
virtual void getNonPhysicalNodes (std::set< EFANode *> &non_physical_nodes) const
 
virtual void switchNode (EFANode *new_node, EFANode *old_node, bool descend_to_parent)
 
virtual void switchEmbeddedNode (EFANode *new_node, EFANode *old_node)
 
virtual void updateFragmentNode ()
 
virtual void getMasterInfo (EFANode *node, std::vector< EFANode *> &master_nodes, std::vector< double > &master_weights) const
 
virtual unsigned int numInteriorNodes () const
 
bool overlaysElement (const EFAElement3D *other_elem) const
 
virtual unsigned int getNeighborIndex (const EFAElement *neighbor_elem) const
 
virtual void getNeighborEdgeIndex (const EFAElement3D *neighbor_elem, unsigned int face_id, unsigned int edge_id, unsigned int &neigh_face_id, unsigned int &neigh_edge_id) const
 
virtual void clearNeighbors ()
 
virtual void setupNeighbors (std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivityMap)
 
virtual void neighborSanityCheck () const
 
virtual void initCrackTip (std::set< EFAElement *> &CrackTipElements)
 
virtual bool shouldDuplicateForCrackTip (const std::set< EFAElement *> &CrackTipElements)
 
virtual bool shouldDuplicateCrackTipSplitElement (const std::set< EFAElement *> &CrackTipElements)
 
virtual bool shouldDuplicateForPhantomCorner ()
 
virtual bool willCrackTipExtend (std::vector< unsigned int > &split_neighbors) const
 
virtual bool isCrackTipElement () const
 
virtual unsigned int getNumCuts () const
 
virtual bool isFinalCut () const
 
virtual void updateFragments (const std::set< EFAElement *> &CrackTipElements, std::map< unsigned int, EFANode *> &EmbeddedNodes)
 
virtual void fragmentSanityCheck (unsigned int n_old_frag_faces, unsigned int n_old_frag_cuts) const
 
virtual void restoreFragment (const EFAElement *const from_elem)
 
virtual void createChild (const std::set< EFAElement *> &CrackTipElements, std::map< unsigned int, EFAElement *> &Elements, std::map< unsigned int, EFAElement *> &newChildElements, std::vector< EFAElement *> &ChildElements, std::vector< EFAElement *> &ParentElements, std::map< unsigned int, EFANode *> &TempNodes)
 
virtual void removePhantomEmbeddedNode ()
 
virtual void connectNeighbors (std::map< unsigned int, EFANode *> &PermanentNodes, std::map< unsigned int, EFANode *> &TempNodes, std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivityMap, bool merge_phantom_faces)
 
virtual void printElement (std::ostream &ostream) const
 
EFAFragment3DgetFragment (unsigned int frag_id) const
 
std::set< EFANode * > getFaceNodes (unsigned int face_id) const
 
bool getFaceNodeParametricCoordinates (EFANode *node, std::vector< double > &xi_3d) const
 
EFAVolumeNodegetInteriorNode (unsigned int interior_node_id) const
 
void removeEmbeddedNode (EFANode *emb_node, bool remove_for_neighbor)
 
unsigned int numFaces () const
 
void setFace (unsigned int face_id, EFAFace *face)
 
void createFaces ()
 
EFAFacegetFace (unsigned int face_id) const
 
unsigned int getFaceID (EFAFace *face) const
 
std::vector< unsigned intgetCommonFaceID (const EFAElement3D *other_elem) const
 
bool getCommonEdgeID (const EFAElement3D *other_elem, std::vector< std::pair< unsigned int, unsigned int >> &common_ids) const
 
unsigned int getNeighborFaceNodeID (unsigned int face_id, unsigned int node_id, EFAElement3D *neighbor_elem) const
 
unsigned int getNeighborFaceInteriorNodeID (unsigned int face_id, unsigned int node_id, EFAElement3D *neighbor_elem) const
 
unsigned int getNeighborFaceEdgeID (unsigned int face_id, unsigned int edg_id, EFAElement3D *neighbor_elem) const
 
void findFacesAdjacentToFaces ()
 
EFAFacegetAdjacentFace (unsigned int face_id, unsigned int edge_id) const
 
EFAFacegetFragmentFace (unsigned int frag_id, unsigned int face_id) const
 
std::set< EFANode * > getPhantomNodeOnFace (unsigned int face_id) const
 
bool getFragmentFaceID (unsigned int elem_face_id, unsigned int &frag_face_id) const
 
bool getFragmentFaceEdgeID (unsigned int ElemFaceID, unsigned int ElemFaceEdgeID, unsigned int &FragFaceID, unsigned int &FragFaceEdgeID) const
 
bool isPhysicalEdgeCut (unsigned int ElemFaceID, unsigned int ElemFaceEdgeID, double position) const
 
bool isFacePhantom (unsigned int face_id) const
 
unsigned int numFaceNeighbors (unsigned int face_id) const
 
unsigned int numEdgeNeighbors (unsigned int face_id, unsigned int edge_id) const
 
EFAElement3DgetFaceNeighbor (unsigned int face_id, unsigned int neighbor_id) const
 
EFAElement3DgetEdgeNeighbor (unsigned int face_id, unsigned int edge_id, unsigned int neighbor_id) const
 
bool fragmentHasTipFaces () const
 
std::vector< unsigned intgetTipFaceIDs () const
 
std::set< EFANode * > getTipEmbeddedNodes () const
 
bool faceContainsTip (unsigned int face_id) const
 
bool fragmentFaceAlreadyCut (unsigned int ElemFaceID) const
 
void addFaceEdgeCut (unsigned int face_id, unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode *> &EmbeddedNodes, bool add_to_neighbor, bool add_to_adjacent)
 
void addFragFaceEdgeCut (unsigned int frag_face_id, unsigned int frag_edge_id, double position, std::map< unsigned int, EFANode *> &EmbeddedNodes, bool add_to_neighbor, bool add_to_adjacent)
 
std::vector< EFANode * > getCommonNodes (const EFAElement3D *other_elem) const
 
unsigned int id () const
 
unsigned int numNodes () const
 
void setNode (unsigned int node_id, EFANode *node)
 
EFANodegetNode (unsigned int node_id) const
 
const std::vector< EFANode * > & getNodes () const
 
bool containsNode (EFANode *node) const
 
void printNodes (std::ostream &ostream) const
 
EFANodecreateLocalNodeFromGlobalNode (const EFANode *global_node) const
 
EFANodegetGlobalNodeFromLocalNode (const EFANode *local_node) const
 
unsigned int getLocalNodeIndex (EFANode *node) const
 
void setCrackTipSplit ()
 
bool isCrackTipSplit () const
 
unsigned int numCrackTipNeighbors () const
 
unsigned int getCrackTipNeighbor (unsigned int index) const
 
void addCrackTipNeighbor (EFAElement *neighbor_elem)
 
EFAElementgetParent () const
 
EFAElementgetChild (unsigned int child_id) const
 
void setParent (EFAElement *parent)
 
unsigned int numChildren () const
 
void addChild (EFAElement *child)
 
void clearParentAndChildren ()
 
void findGeneralNeighbors (const std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivity)
 
EFAElementgetGeneralNeighbor (unsigned int index) const
 
unsigned int numGeneralNeighbors () const
 

Protected Member Functions

void mergeNodes (EFANode *&childNode, EFANode *&childOfNeighborNode, EFAElement *childOfNeighborElem, std::map< unsigned int, EFANode *> &PermanentNodes, std::map< unsigned int, EFANode *> &TempNodes)
 

Protected Attributes

unsigned int _id
 
unsigned int _num_nodes
 
std::vector< EFANode * > _nodes
 
std::vector< EFANode * > _local_nodes
 
EFAElement_parent
 
std::vector< EFAElement * > _children
 
bool _crack_tip_split_element
 
std::vector< unsigned int_crack_tip_neighbors
 
std::vector< EFAElement * > _general_neighbors
 

Private Member Functions

void checkNeighborFaceCut (unsigned int face_id, unsigned int edge_id, double position, EFANode *from_node, EFANode *embedded_node, EFANode *&local_embedded)
 
void mapParametricCoordinateFrom2DTo3D (unsigned int face_id, std::vector< double > &xi_2d, std::vector< double > &xi_3d) const
 
void setLocalCoordinates ()
 

Private Attributes

unsigned int _num_faces
 
std::vector< EFAFace * > _faces
 
std::vector< EFAVolumeNode * > _interior_nodes
 
std::vector< std::vector< EFAElement3D * > > _face_neighbors
 
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
 
std::vector< EFAFragment3D * > _fragments
 
std::vector< std::vector< EFAFace * > > _faces_adjacent_to_faces
 
unsigned int _num_vertices
 
unsigned int _num_interior_face_nodes
 
std::vector< EFAPoint_local_node_coor
 

Detailed Description

Definition at line 20 of file EFAElement3D.h.

Constructor & Destructor Documentation

◆ EFAElement3D() [1/2]

EFAElement3D::EFAElement3D ( unsigned int  eid,
unsigned int  n_nodes,
unsigned int  n_faces 
)

Definition at line 26 of file EFAElement3D.C.

Referenced by createChild().

27  : EFAElement(eid, n_nodes),
28  _num_faces(n_faces),
29  _faces(_num_faces, nullptr),
32 {
33  if (_num_faces == 4)
34  {
35  _num_vertices = 4;
36  if (_num_nodes == 14)
38  else if (_num_nodes == 10)
40  else if (_num_nodes == 4)
42  else
43  EFAError("In EFAelement3D the supported TET element types are TET4, TET10 and TET14");
44  }
45  else if (_num_faces == 6)
46  {
47  _num_vertices = 8;
48  if (_num_nodes == 27)
50  else if (_num_nodes == 20)
52  else if (_num_nodes == 8)
54  else
55  EFAError("In EFAelement3D the supported HEX element types are HEX8, HEX20 and HEX27");
56  }
57  else
58  EFAError("In EFAelement3D the supported element types are TET4, TET10, TET14, HEX8, HEX20 and "
59  "HEX27");
61 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:33
unsigned int _num_interior_face_nodes
Definition: EFAElement3D.h:37
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement.C:16
unsigned int _num_nodes
Definition: EFAElement.h:28
unsigned int _num_vertices
Definition: EFAElement3D.h:36
unsigned int _num_faces
Definition: EFAElement3D.h:29
void setLocalCoordinates()
Definition: EFAElement3D.C:141

◆ EFAElement3D() [2/2]

EFAElement3D::EFAElement3D ( const EFAElement3D from_elem,
bool  convert_to_local 
)

Definition at line 63 of file EFAElement3D.C.

64  : EFAElement(from_elem->_id, from_elem->_num_nodes),
65  _num_faces(from_elem->_num_faces),
66  _faces(_num_faces, nullptr),
69 {
70  if (convert_to_local)
71  {
72  // build local nodes from global nodes
73  for (unsigned int i = 0; i < _num_nodes; ++i)
74  {
75  if (from_elem->_nodes[i]->category() == EFANode::N_CATEGORY_PERMANENT ||
76  from_elem->_nodes[i]->category() == EFANode::N_CATEGORY_TEMP)
77  {
78  _nodes[i] = from_elem->createLocalNodeFromGlobalNode(from_elem->_nodes[i]);
79  _local_nodes.push_back(_nodes[i]); // convenient to delete local nodes
80  }
81  else
82  EFAError("In EFAelement3D ",
83  from_elem->id(),
84  " the copy constructor must have from_elem w/ global nodes. node: ",
85  i,
86  " category: ",
87  from_elem->_nodes[i]->category());
88  }
89 
90  // copy faces, fragments and interior nodes from from_elem
91  for (unsigned int i = 0; i < _num_faces; ++i)
92  _faces[i] = new EFAFace(*from_elem->_faces[i]);
93  for (unsigned int i = 0; i < from_elem->_fragments.size(); ++i)
94  _fragments.push_back(new EFAFragment3D(this, true, from_elem, i));
95  for (unsigned int i = 0; i < from_elem->_interior_nodes.size(); ++i)
96  _interior_nodes.push_back(new EFAVolumeNode(*from_elem->_interior_nodes[i]));
97 
98  // replace all global nodes with local nodes
99  for (unsigned int i = 0; i < _num_nodes; ++i)
100  {
101  if (_nodes[i]->category() == EFANode::N_CATEGORY_LOCAL_INDEX)
102  switchNode(
103  _nodes[i],
104  from_elem->_nodes[i],
105  false); // when save to _cut_elem_map, the EFAelement is not a child of any parent
106  else
107  EFAError("In EFAelement3D copy constructor this elem's nodes must be local");
108  }
109 
110  // create element face connectivity array (IMPORTANT)
112 
113  _local_node_coor = from_elem->_local_node_coor;
115  _num_vertices = from_elem->_num_vertices;
116  }
117  else
118  EFAError("this EFAelement3D constructor only converts global nodes to local nodes");
119 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:33
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
unsigned int id() const
Definition: EFAElement.C:28
unsigned int _id
Definition: EFAElement.h:27
unsigned int _num_interior_face_nodes
Definition: EFAElement3D.h:37
void findFacesAdjacentToFaces()
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement.C:16
std::vector< EFAPoint > _local_node_coor
Definition: EFAElement3D.h:38
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_nodes
Definition: EFAElement.h:28
unsigned int _num_vertices
Definition: EFAElement3D.h:36
unsigned int _num_faces
Definition: EFAElement3D.h:29
EFANode * createLocalNodeFromGlobalNode(const EFANode *global_node) const
Definition: EFAElement.C:70
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31
std::vector< EFANode * > _local_nodes
Definition: EFAElement.h:30

◆ ~EFAElement3D()

EFAElement3D::~EFAElement3D ( )

Definition at line 121 of file EFAElement3D.C.

122 {
123  for (unsigned int i = 0; i < _fragments.size(); ++i)
124  if (_fragments[i])
125  delete _fragments[i];
126 
127  for (unsigned int i = 0; i < _faces.size(); ++i)
128  if (_faces[i])
129  delete _faces[i];
130 
131  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
132  if (_interior_nodes[i])
133  delete _interior_nodes[i];
134 
135  for (unsigned int i = 0; i < _local_nodes.size(); ++i)
136  if (_local_nodes[i])
137  delete _local_nodes[i];
138 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31
std::vector< EFANode * > _local_nodes
Definition: EFAElement.h:30

Member Function Documentation

◆ addChild()

void EFAElement::addChild ( EFAElement child)
inherited

Definition at line 195 of file EFAElement.C.

196 {
197  _children.push_back(child);
198 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:32

◆ addCrackTipNeighbor()

void EFAElement::addCrackTipNeighbor ( EFAElement neighbor_elem)
inherited

Definition at line 149 of file EFAElement.C.

150 {
151  // Find out what side the specified element is on, and add it as a crack tip neighbor
152  // element for that side.
153  unsigned int neighbor_index = getNeighborIndex(neighbor_elem);
154  bool crack_tip_neighbor_exist = false;
155  for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
156  {
157  if (_crack_tip_neighbors[i] == neighbor_index)
158  {
159  crack_tip_neighbor_exist = true;
160  break;
161  }
162  }
163  if (!crack_tip_neighbor_exist)
164  _crack_tip_neighbors.push_back(neighbor_index);
165 }
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const =0
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:34

◆ addFaceEdgeCut()

void EFAElement3D::addFaceEdgeCut ( unsigned int  face_id,
unsigned int  edge_id,
double  position,
EFANode embedded_node,
std::map< unsigned int, EFANode *> &  EmbeddedNodes,
bool  add_to_neighbor,
bool  add_to_adjacent 
)

Definition at line 1986 of file EFAElement3D.C.

Referenced by ElementFragmentAlgorithm::addElemFaceIntersection(), and addFaceEdgeCut().

1993 {
1994  // Purpose: add intersection on Edge edge_id of Face face_id
1995  EFANode * local_embedded = nullptr;
1996  EFAEdge * cut_edge = _faces[face_id]->getEdge(edge_id);
1997  EFANode * edge_node1 = cut_edge->getNode(0);
1998  if (embedded_node) // use the existing embedded node if it was passed in
1999  local_embedded = embedded_node;
2000 
2001  // get adjacent face info
2002  EFAFace * adj_face = getAdjacentFace(face_id, edge_id);
2003  unsigned int adj_face_id = getFaceID(adj_face);
2004  unsigned int adj_edge_id = adj_face->adjacentCommonEdge(_faces[face_id]);
2005 
2006  // check if cut has already been added to this face edge
2007  bool cut_exist = false;
2008 
2009  if (cut_edge->hasIntersectionAtPosition(position, edge_node1))
2010  {
2011  unsigned int emb_id = cut_edge->getEmbeddedNodeIndex(position, edge_node1);
2012  EFANode * old_emb = cut_edge->getEmbeddedNode(emb_id);
2013  if (embedded_node && embedded_node != old_emb)
2014  EFAError("Attempting to add edge intersection when one already exists with different node.",
2015  " elem: ",
2016  _id,
2017  " edge: ",
2018  edge_id,
2019  " position: ",
2020  position);
2021  local_embedded = old_emb;
2022  cut_exist = true;
2023  }
2024 
2025  if (!cut_exist && !fragmentFaceAlreadyCut(face_id) &&
2026  isPhysicalEdgeCut(face_id, edge_id, position))
2027  {
2028  // check if cut has already been added to the neighbor edges
2029  checkNeighborFaceCut(face_id, edge_id, position, edge_node1, embedded_node, local_embedded);
2031  adj_face_id, adj_edge_id, position, edge_node1, embedded_node, local_embedded);
2032 
2033  if (!local_embedded) // need to create new embedded node
2034  {
2035  unsigned int new_node_id = Efa::getNewID(EmbeddedNodes);
2036  local_embedded = new EFANode(new_node_id, EFANode::N_CATEGORY_EMBEDDED);
2037  EmbeddedNodes.insert(std::make_pair(new_node_id, local_embedded));
2038  }
2039 
2040  // add to elem face edge
2041  cut_edge->addIntersection(position, local_embedded, edge_node1);
2042  if (cut_edge->numEmbeddedNodes() > 2)
2043  EFAError("element edge can't have >2 embedded nodes");
2044 
2045  // cut fragment faces, which is an essential addition to other code in this method that cuts
2046  // element faces
2047  unsigned int FragFaceID;
2048  unsigned int FragFaceEdgeID;
2049  if (getFragmentFaceEdgeID(face_id, edge_id, FragFaceID, FragFaceEdgeID))
2050  {
2051  EFAEdge * elem_edge = _faces[face_id]->getEdge(edge_id);
2052  EFAEdge * frag_edge = getFragmentFace(0, FragFaceID)->getEdge(FragFaceEdgeID);
2053  double xi[2] = {-1.0, -1.0}; // relative coords of two frag edge nodes
2054  xi[0] = elem_edge->distanceFromNode1(frag_edge->getNode(0));
2055  xi[1] = elem_edge->distanceFromNode1(frag_edge->getNode(1));
2056  double frag_pos = (position - xi[0]) / (xi[1] - xi[0]);
2057  EFANode * frag_edge_node1 = frag_edge->getNode(0);
2058 
2059  if (!frag_edge->hasIntersection())
2060  frag_edge->addIntersection(frag_pos, local_embedded, frag_edge_node1);
2061  }
2062 
2063  // add to adjacent face edge
2064  if (add_to_adjacent)
2065  {
2066  double adj_pos = 1.0 - position;
2068  adj_face_id, adj_edge_id, adj_pos, local_embedded, EmbeddedNodes, false, false);
2069  }
2070  }
2071 
2072  // add cut to neighbor face edge
2073  if (add_to_neighbor)
2074  {
2075  for (unsigned int en_iter = 0; en_iter < numFaceNeighbors(face_id); ++en_iter)
2076  {
2077  EFAElement3D * face_neighbor = getFaceNeighbor(face_id, en_iter);
2078  unsigned int neigh_face_id = face_neighbor->getNeighborIndex(this);
2079  unsigned neigh_edge_id = getNeighborFaceEdgeID(face_id, edge_id, face_neighbor);
2080  double neigh_pos = 1.0 - position; // get emb node's postion on neighbor edge
2081  face_neighbor->addFaceEdgeCut(
2082  neigh_face_id, neigh_edge_id, neigh_pos, local_embedded, EmbeddedNodes, false, true);
2083  }
2084 
2085  for (unsigned int en_iter = 0; en_iter < numEdgeNeighbors(face_id, edge_id); ++en_iter)
2086  {
2087  EFAElement3D * edge_neighbor = getEdgeNeighbor(face_id, edge_id, en_iter);
2088  unsigned int neigh_face_id, neigh_edge_id;
2089  getNeighborEdgeIndex(edge_neighbor, face_id, edge_id, neigh_face_id, neigh_edge_id);
2090 
2091  // Check the ordering of the node and the assign the position
2092  double neigh_pos;
2093  if (_faces[face_id]->getEdge(edge_id)->getNode(0) ==
2094  edge_neighbor->getFace(neigh_face_id)->getEdge(neigh_edge_id)->getNode(0))
2095  neigh_pos = position;
2096  else if (_faces[face_id]->getEdge(edge_id)->getNode(1) ==
2097  edge_neighbor->getFace(neigh_face_id)->getEdge(neigh_edge_id)->getNode(0))
2098  neigh_pos = 1.0 - position;
2099  else
2100  EFAError("The EFANodes on commaon edge are not matched.");
2101 
2102  edge_neighbor->addFaceEdgeCut(
2103  neigh_face_id, neigh_edge_id, neigh_pos, local_embedded, EmbeddedNodes, false, true);
2104  }
2105  } // If add_to_neighbor required
2106 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
EFANode * getEmbeddedNode(unsigned int index) const
Definition: EFAEdge.C:332
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
Definition: EFAFuncs.h:38
unsigned int _id
Definition: EFAElement.h:27
bool getFragmentFaceEdgeID(unsigned int ElemFaceID, unsigned int ElemFaceEdgeID, unsigned int &FragFaceID, unsigned int &FragFaceEdgeID) const
void checkNeighborFaceCut(unsigned int face_id, unsigned int edge_id, double position, EFANode *from_node, EFANode *embedded_node, EFANode *&local_embedded)
unsigned int getFaceID(EFAFace *face) const
EFAFace * getAdjacentFace(unsigned int face_id, unsigned int edge_id) const
bool hasIntersection() const
Definition: EFAEdge.C:200
EFAElement3D * getEdgeNeighbor(unsigned int face_id, unsigned int edge_id, unsigned int neighbor_id) const
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement3D.C:458
unsigned int getNeighborFaceEdgeID(unsigned int face_id, unsigned int edg_id, EFAElement3D *neighbor_elem) const
unsigned int numEdgeNeighbors(unsigned int face_id, unsigned int edge_id) const
double distanceFromNode1(EFANode *node) const
Definition: EFAEdge.C:250
unsigned int getEmbeddedNodeIndex(EFANode *node) const
Definition: EFAEdge.C:283
virtual void getNeighborEdgeIndex(const EFAElement3D *neighbor_elem, unsigned int face_id, unsigned int edge_id, unsigned int &neigh_face_id, unsigned int &neigh_edge_id) const
Definition: EFAElement3D.C:468
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.h:50
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
bool fragmentFaceAlreadyCut(unsigned int ElemFaceID) const
bool hasIntersectionAtPosition(double position, EFANode *from_node) const
Definition: EFAEdge.C:213
bool isPhysicalEdgeCut(unsigned int ElemFaceID, unsigned int ElemFaceEdgeID, double position) const
unsigned int numEmbeddedNodes() const
Definition: EFAEdge.C:341
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition: EFAEdge.C:132
unsigned int adjacentCommonEdge(const EFAFace *other_face) const
Definition: EFAFace.C:603
EFAFace * getFragmentFace(unsigned int frag_id, unsigned int face_id) const
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:181
unsigned int numFaceNeighbors(unsigned int face_id) const
void addFaceEdgeCut(unsigned int face_id, unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode *> &EmbeddedNodes, bool add_to_neighbor, bool add_to_adjacent)

◆ addFragFaceEdgeCut()

void EFAElement3D::addFragFaceEdgeCut ( unsigned int  frag_face_id,
unsigned int  frag_edge_id,
double  position,
std::map< unsigned int, EFANode *> &  EmbeddedNodes,
bool  add_to_neighbor,
bool  add_to_adjacent 
)

Definition at line 2109 of file EFAElement3D.C.

2115 {
2116  // TODO: mark frag face edges
2117  // also need to check if cut has been added to this frag face edge or neighbor edge of adjacent
2118  // face
2119 }

◆ checkNeighborFaceCut()

void EFAElement3D::checkNeighborFaceCut ( unsigned int  face_id,
unsigned int  edge_id,
double  position,
EFANode from_node,
EFANode embedded_node,
EFANode *&  local_embedded 
)
private

Definition at line 2122 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

2128 {
2129  // N.B. this is important. We are checking if the corresponding edge of the neighbor face or of
2130  // the adjacent
2131  // face's neighbor face has a cut at the same position. If so, use the existing embedded node as
2132  // local_embedded
2133  for (unsigned int en_iter = 0; en_iter < numFaceNeighbors(face_id); ++en_iter)
2134  {
2135  EFAElement3D * face_neighbor = getFaceNeighbor(face_id, en_iter);
2136  unsigned int neigh_face_id = face_neighbor->getNeighborIndex(this);
2137  unsigned neigh_edge_id = getNeighborFaceEdgeID(face_id, edge_id, face_neighbor);
2138  EFAEdge * neigh_edge = face_neighbor->getFace(neigh_face_id)->getEdge(neigh_edge_id);
2139 
2140  if (neigh_edge->hasIntersectionAtPosition(position, from_node))
2141  {
2142  unsigned int emb_id = neigh_edge->getEmbeddedNodeIndex(position, from_node);
2143  EFANode * old_emb = neigh_edge->getEmbeddedNode(emb_id);
2144 
2145  if (embedded_node && embedded_node != old_emb)
2146  EFAError(
2147  "attempting to add edge intersection when one already exists with different node.");
2148  if (local_embedded && local_embedded != old_emb)
2149  EFAError("attempting to assign contradictory pointer to local_embedded.");
2150 
2151  local_embedded = old_emb;
2152  }
2153  } // en_iter
2154 }
EFAFace * getFace(unsigned int face_id) const
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
EFANode * getEmbeddedNode(unsigned int index) const
Definition: EFAEdge.C:332
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement3D.C:458
unsigned int getNeighborFaceEdgeID(unsigned int face_id, unsigned int edg_id, EFAElement3D *neighbor_elem) const
unsigned int getEmbeddedNodeIndex(EFANode *node) const
Definition: EFAEdge.C:283
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.h:50
bool hasIntersectionAtPosition(double position, EFANode *from_node) const
Definition: EFAEdge.C:213
unsigned int numFaceNeighbors(unsigned int face_id) const

◆ clearNeighbors()

void EFAElement3D::clearNeighbors ( )
virtual

Implements EFAElement.

Definition at line 495 of file EFAElement3D.C.

496 {
497  _general_neighbors.clear();
498  for (unsigned int face_iter = 0; face_iter < _num_faces; ++face_iter)
499  {
500  _face_neighbors[face_iter].clear();
501  for (unsigned int edge_iter = 0; edge_iter < _faces[face_iter]->numEdges(); ++edge_iter)
502  _face_edge_neighbors[face_iter][edge_iter].clear();
503  }
504 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:33
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
sideset clear()
unsigned int _num_faces
Definition: EFAElement3D.h:29
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:36

◆ clearParentAndChildren()

void EFAElement::clearParentAndChildren ( )
inherited

Definition at line 201 of file EFAElement.C.

Referenced by ElementFragmentAlgorithm::clearAncestry().

202 {
203  _parent = nullptr;
204  _children.clear();
205 }
EFAElement * _parent
Definition: EFAElement.h:31
std::vector< EFAElement * > _children
Definition: EFAElement.h:32

◆ connectNeighbors()

void EFAElement3D::connectNeighbors ( std::map< unsigned int, EFANode *> &  PermanentNodes,
std::map< unsigned int, EFANode *> &  TempNodes,
std::map< EFANode *, std::set< EFAElement *>> &  InverseConnectivityMap,
bool  merge_phantom_faces 
)
virtual

Implements EFAElement.

Definition at line 1136 of file EFAElement3D.C.

1140 {
1141  // N.B. "this" must point to a child element that was just created
1142  if (!_parent)
1143  EFAError("no parent element for child element ", _id, " in connect_neighbors");
1144  EFAElement3D * parent3d = dynamic_cast<EFAElement3D *>(_parent);
1145  if (!parent3d)
1146  EFAError("cannot dynamic cast to parent3d in connect_neighbors");
1147 
1148  // First loop through edges and merge nodes with neighbors as appropriate
1149  for (unsigned int j = 0; j < _num_faces; ++j)
1150  {
1151  for (unsigned int k = 0; k < parent3d->numFaceNeighbors(j); ++k)
1152  {
1153  EFAElement3D * NeighborElem = parent3d->getFaceNeighbor(j, k);
1154  unsigned int neighbor_face_id = NeighborElem->getNeighborIndex(parent3d);
1155 
1156  if (_faces[j]->hasIntersection())
1157  {
1158  for (unsigned int l = 0; l < NeighborElem->numChildren(); ++l)
1159  {
1160  EFAElement3D * childOfNeighborElem =
1161  dynamic_cast<EFAElement3D *>(NeighborElem->getChild(l));
1162  if (!childOfNeighborElem)
1163  EFAError("dynamic cast childOfNeighborElem fails");
1164 
1165  // Check to see if the nodes are already merged. There's nothing else to do in that case.
1166  EFAFace * neighborChildFace = childOfNeighborElem->getFace(neighbor_face_id);
1167  if (_faces[j]->equivalent(neighborChildFace))
1168  continue;
1169 
1170  if (_fragments[0]->isConnected(childOfNeighborElem->getFragment(0)))
1171  {
1172  for (unsigned int i = 0; i < _faces[j]->numNodes(); ++i)
1173  {
1174  unsigned int childNodeIndex = i;
1175  unsigned int neighborChildNodeIndex =
1176  parent3d->getNeighborFaceNodeID(j, childNodeIndex, NeighborElem);
1177 
1178  EFANode * childNode = _faces[j]->getNode(childNodeIndex);
1179  EFANode * childOfNeighborNode = neighborChildFace->getNode(neighborChildNodeIndex);
1180  mergeNodes(
1181  childNode, childOfNeighborNode, childOfNeighborElem, PermanentNodes, TempNodes);
1182  } // i
1183 
1184  for (unsigned int m = 0; m < _num_interior_face_nodes; ++m)
1185  {
1186  unsigned int childNodeIndex = m;
1187  unsigned int neighborChildNodeIndex =
1188  parent3d->getNeighborFaceInteriorNodeID(j, childNodeIndex, NeighborElem);
1189 
1190  EFANode * childNode = _faces[j]->getInteriorFaceNode(childNodeIndex);
1191  EFANode * childOfNeighborNode =
1192  neighborChildFace->getInteriorFaceNode(neighborChildNodeIndex);
1193  mergeNodes(
1194  childNode, childOfNeighborNode, childOfNeighborElem, PermanentNodes, TempNodes);
1195  } // m
1196  }
1197  } // l, loop over NeighborElem's children
1198  }
1199  else // No edge intersection -- optionally merge non-material nodes if they share a common
1200  // parent
1201  {
1202  if (merge_phantom_faces)
1203  {
1204  for (unsigned int l = 0; l < NeighborElem->numChildren(); ++l)
1205  {
1206  EFAElement3D * childOfNeighborElem =
1207  dynamic_cast<EFAElement3D *>(NeighborElem->getChild(l));
1208  if (!childOfNeighborElem)
1209  EFAError("dynamic cast childOfNeighborElem fails");
1210 
1211  EFAFace * neighborChildFace = childOfNeighborElem->getFace(neighbor_face_id);
1212  if (!neighborChildFace
1213  ->hasIntersection()) // neighbor face must NOT have intersection either
1214  {
1215  // Check to see if the nodes are already merged. There's nothing else to do in that
1216  // case.
1217  if (_faces[j]->equivalent(neighborChildFace))
1218  continue;
1219 
1220  for (unsigned int i = 0; i < _faces[j]->numNodes(); ++i)
1221  {
1222  unsigned int childNodeIndex = i;
1223  unsigned int neighborChildNodeIndex =
1224  parent3d->getNeighborFaceNodeID(j, childNodeIndex, NeighborElem);
1225 
1226  EFANode * childNode = _faces[j]->getNode(childNodeIndex);
1227  EFANode * childOfNeighborNode = neighborChildFace->getNode(neighborChildNodeIndex);
1228 
1229  if (childNode->parent() != nullptr &&
1230  childNode->parent() ==
1231  childOfNeighborNode
1232  ->parent()) // non-material node and both come from same parent
1233  mergeNodes(childNode,
1234  childOfNeighborNode,
1235  childOfNeighborElem,
1236  PermanentNodes,
1237  TempNodes);
1238  } // i
1239  }
1240  } // loop over NeighborElem's children
1241  } // if (merge_phantom_edges)
1242  } // IF edge-j has_intersection()
1243  } // k, loop over neighbors on edge j
1244  } // j, loop over all faces
1245 
1246  // Now do a second loop through faces and convert remaining nodes to permanent nodes.
1247  // If there is no neighbor on that face, also duplicate the embedded node if it exists
1248  for (unsigned int j = 0; j < _num_nodes; ++j)
1249  {
1250  EFANode * childNode = _nodes[j];
1251  if (childNode->category() == EFANode::N_CATEGORY_TEMP)
1252  {
1253  // if current child element does not have siblings, and if current temp node is a lone one
1254  // this temp node should be merged back to its parent permanent node. Otherwise we would have
1255  // permanent nodes that are not connected to any element
1256  std::set<EFAElement *> patch_elems = InverseConnectivityMap[childNode->parent()];
1257  if (parent3d->numFragments() == 1 && patch_elems.size() == 1)
1258  switchNode(childNode->parent(), childNode, false);
1259  else
1260  {
1261  unsigned int new_node_id = Efa::getNewID(PermanentNodes);
1262  EFANode * newNode =
1263  new EFANode(new_node_id, EFANode::N_CATEGORY_PERMANENT, childNode->parent());
1264  PermanentNodes.insert(std::make_pair(new_node_id, newNode));
1265  switchNode(newNode, childNode, false);
1266  }
1267  if (!Efa::deleteFromMap(TempNodes, childNode))
1268  EFAError(
1269  "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
1270  }
1271  }
1272 }
EFAFragment3D * getFragment(unsigned int frag_id) const
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
unsigned int numChildren() const
Definition: EFAElement.C:189
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
Definition: EFAFuncs.h:38
unsigned int _id
Definition: EFAElement.h:27
unsigned int _num_interior_face_nodes
Definition: EFAElement3D.h:37
bool deleteFromMap(std::map< unsigned int, T *> &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:22
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:272
unsigned int getNeighborFaceNodeID(unsigned int face_id, unsigned int node_id, EFAElement3D *neighbor_elem) const
EFANode * getNode(unsigned int node_id) const
Definition: EFAFace.C:99
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement3D.C:458
EFAElement * getChild(unsigned int child_id) const
Definition: EFAElement.C:174
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_nodes
Definition: EFAElement.h:28
EFAElement * _parent
Definition: EFAElement.h:31
EFANode * getInteriorFaceNode(unsigned int i) const
Definition: EFAFace.h:58
void mergeNodes(EFANode *&childNode, EFANode *&childOfNeighborNode, EFAElement *childOfNeighborElem, std::map< unsigned int, EFANode *> &PermanentNodes, std::map< unsigned int, EFANode *> &TempNodes)
Definition: EFAElement.C:242
unsigned int _num_faces
Definition: EFAElement3D.h:29
unsigned int getNeighborFaceInteriorNodeID(unsigned int face_id, unsigned int node_id, EFAElement3D *neighbor_elem) const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
EFANode * parent() const
Definition: EFANode.C:48
static const std::string k
Definition: NS.h:130
unsigned int numFaceNeighbors(unsigned int face_id) const
unsigned int id() const
Definition: EFANode.C:36
N_CATEGORY category() const
Definition: EFANode.C:42

◆ containsNode()

bool EFAElement::containsNode ( EFANode node) const
inherited

◆ createChild()

void EFAElement3D::createChild ( const std::set< EFAElement *> &  CrackTipElements,
std::map< unsigned int, EFAElement *> &  Elements,
std::map< unsigned int, EFAElement *> &  newChildElements,
std::vector< EFAElement *> &  ChildElements,
std::vector< EFAElement *> &  ParentElements,
std::map< unsigned int, EFANode *> &  TempNodes 
)
virtual

Implements EFAElement.

Definition at line 964 of file EFAElement3D.C.

970 {
971  if (_children.size() != 0)
972  EFAError("Element cannot have existing children in createChildElements");
973 
974  if (_fragments.size() > 1 || shouldDuplicateForCrackTip(CrackTipElements))
975  {
976  if (_fragments.size() > 2)
977  EFAError("More than 2 fragments not yet supported");
978 
979  // set up the children
980  ParentElements.push_back(this);
981  for (unsigned int ichild = 0; ichild < _fragments.size(); ++ichild)
982  {
983  unsigned int new_elem_id;
984  if (newChildElements.size() == 0)
985  new_elem_id = Efa::getNewID(Elements);
986  else
987  new_elem_id = Efa::getNewID(newChildElements);
988 
989  EFAElement3D * childElem = new EFAElement3D(new_elem_id, this->numNodes(), this->numFaces());
990  newChildElements.insert(std::make_pair(new_elem_id, childElem));
991 
992  ChildElements.push_back(childElem);
993  childElem->setParent(this);
994  _children.push_back(childElem);
995 
996  std::vector<std::vector<EFANode *>> cut_plane_nodes;
997  for (unsigned int i = 0; i < this->getFragment(ichild)->numFaces(); ++i)
998  {
999  if (this->getFragment(ichild)->isFaceInterior(i))
1000  {
1001  EFAFace * face = this->getFragment(ichild)->getFace(i);
1002  std::vector<EFANode *> node_line;
1003  for (unsigned int j = 0; j < face->numNodes(); ++j)
1004  node_line.push_back(face->getNode(j));
1005  cut_plane_nodes.push_back(node_line);
1006  }
1007  }
1008 
1009  std::vector<EFAPoint> cut_plane_points;
1010 
1011  EFAPoint orig(0.0, 0.0, 0.0);
1012 
1013  std::vector<EFAPoint> normal_v;
1014 
1015  if (cut_plane_nodes.size())
1016  {
1017  for (unsigned int i = 0; i < cut_plane_nodes[0].size(); ++i)
1018  {
1019  std::vector<EFANode *> master_nodes;
1020  std::vector<double> master_weights;
1021 
1022  this->getMasterInfo(cut_plane_nodes[0][i], master_nodes, master_weights);
1023  EFAPoint coor(0.0, 0.0, 0.0);
1024  for (unsigned int i = 0; i < master_nodes.size(); ++i)
1025  {
1026  EFANode * local = this->createLocalNodeFromGlobalNode(master_nodes[i]);
1027  coor += _local_node_coor[local->id()] * master_weights[i];
1028  delete local;
1029  }
1030  cut_plane_points.push_back(coor);
1031  }
1032 
1033  for (unsigned int i = 0; i < cut_plane_points.size(); ++i)
1034  orig += cut_plane_points[i];
1035  orig /= cut_plane_points.size();
1036 
1037  for (unsigned int i = 0; i < cut_plane_points.size(); ++i)
1038  {
1039  unsigned int iplus1 = i < cut_plane_points.size() - 1 ? i + 1 : 0;
1040  unsigned int iminus1 = i == 0 ? cut_plane_points.size() - 1 : i - 1;
1041  EFAPoint ray1 = cut_plane_points[iminus1] - cut_plane_points[i];
1042  EFAPoint ray2 = cut_plane_points[i] - cut_plane_points[iplus1];
1043  normal_v.push_back(ray1.cross(ray2));
1044  }
1045 
1046  for (unsigned int i = 0; i < normal_v.size(); ++i)
1047  Xfem::normalizePoint(normal_v[i]);
1048  }
1049 
1050  // get child element's nodes
1051  for (unsigned int j = 0; j < _num_nodes; ++j)
1052  {
1053  EFAPoint p(0.0, 0.0, 0.0);
1054  p = _local_node_coor[j];
1055  EFAPoint origin_to_point = p - orig;
1056 
1057  bool node_outside_fragment = false;
1058  for (unsigned int k = 0; k < normal_v.size(); ++k)
1059  if (origin_to_point * normal_v[k] > Xfem::tol)
1060  {
1061  node_outside_fragment = true;
1062  break;
1063  }
1064 
1065  if (_fragments.size() == 1 && !shouldDuplicateForCrackTip(CrackTipElements))
1066  childElem->setNode(j, _nodes[j]); // inherit parent's node
1067  else if (!node_outside_fragment)
1068  childElem->setNode(j, _nodes[j]); // inherit parent's node
1069  else // parent element's node is not in fragment
1070  {
1071  unsigned int new_node_id = Efa::getNewID(TempNodes);
1072  EFANode * newNode = new EFANode(new_node_id, EFANode::N_CATEGORY_TEMP, _nodes[j]);
1073  TempNodes.insert(std::make_pair(new_node_id, newNode));
1074  childElem->setNode(j, newNode); // be a temp node
1075  }
1076  }
1077 
1078  // get child element's fragments
1079  EFAFragment3D * new_frag = new EFAFragment3D(childElem, true, this, ichild);
1080  childElem->_fragments.push_back(new_frag);
1081 
1082  // get child element's faces and set up adjacent faces
1083  childElem->createFaces();
1084  for (unsigned int j = 0; j < _num_faces; ++j)
1085  childElem->_faces[j]->copyIntersection(*_faces[j]);
1086  childElem->removePhantomEmbeddedNode(); // IMPORTANT
1087 
1088  // inherit old interior nodes
1089  for (unsigned int j = 0; j < _interior_nodes.size(); ++j)
1090  childElem->_interior_nodes.push_back(new EFAVolumeNode(*_interior_nodes[j]));
1091  }
1092  }
1093  else // num_links == 1 || num_links == 0
1094  {
1095  // child is itself - but don't insert into the list of ChildElements!!!
1096  _children.push_back(this);
1097  }
1098 }
EFAFragment3D * getFragment(unsigned int frag_id) const
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
virtual bool shouldDuplicateForCrackTip(const std::set< EFAElement *> &CrackTipElements)
Definition: EFAElement3D.C:644
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
Definition: EFAFuncs.h:38
void createFaces()
EFAPoint cross(const EFAPoint &point)
Definition: EFAPoint.C:98
unsigned int numFaces() const
EFANode * getNode(unsigned int node_id) const
Definition: EFAFace.C:99
std::vector< EFAPoint > _local_node_coor
Definition: EFAElement3D.h:38
bool isFaceInterior(unsigned int face_id) const
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
EFAFace * getFace(unsigned int face_id) const
unsigned int numNodes() const
Definition: EFAFace.C:87
void setParent(EFAElement *parent)
Definition: EFAElement.C:183
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
virtual void removePhantomEmbeddedNode()
unsigned int _num_nodes
Definition: EFAElement.h:28
static const double tol
Definition: XFEMFuncs.h:21
virtual void getMasterInfo(EFANode *node, std::vector< EFANode *> &master_nodes, std::vector< double > &master_weights) const
Definition: EFAElement3D.C:373
unsigned int _num_faces
Definition: EFAElement3D.h:29
EFANode * createLocalNodeFromGlobalNode(const EFANode *global_node) const
Definition: EFAElement.C:70
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void normalizePoint(Point &p)
Definition: XFEMFuncs.C:621
unsigned int numNodes() const
Definition: EFAElement.C:34
EFAElement3D(unsigned int eid, unsigned int n_nodes, unsigned int n_faces)
Definition: EFAElement3D.C:26
std::vector< EFAElement * > _children
Definition: EFAElement.h:32
static const std::string k
Definition: NS.h:130
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:40
unsigned int numFaces() const

◆ createFaces()

void EFAElement3D::createFaces ( )

Definition at line 1449 of file EFAElement3D.C.

Referenced by ElementFragmentAlgorithm::add3DElement(), and createChild().

1450 {
1451  // create element faces based on existing element nodes
1452  int hex_local_node_indices[6][4] = {
1453  {0, 3, 2, 1}, {0, 1, 5, 4}, {1, 2, 6, 5}, {2, 3, 7, 6}, {3, 0, 4, 7}, {4, 5, 6, 7}};
1454  int tet_local_node_indices[4][3] = {{0, 2, 1}, {0, 1, 3}, {1, 2, 3}, {2, 0, 3}};
1455 
1456  int hex_interior_face_node_indices[6][5] = {{8, 9, 10, 11, 20},
1457  {8, 13, 16, 12, 21},
1458  {9, 14, 17, 13, 22},
1459  {10, 14, 18, 15, 23},
1460  {11, 15, 19, 12, 24},
1461  {16, 17, 18, 19, 25}};
1462  int tet_interior_face_node_indices[4][4] = {
1463  {4, 5, 6, 10}, {4, 7, 8, 11}, {5, 8, 9, 12}, {6, 7, 9, 13}};
1464 
1465  _faces = std::vector<EFAFace *>(_num_faces, nullptr);
1466  if (_num_nodes == 8 || _num_nodes == 20 || _num_nodes == 27)
1467  {
1468  if (_num_faces != 6)
1469  EFAError("num_faces of hexes must be 6");
1470  for (unsigned int i = 0; i < _num_faces; ++i)
1471  {
1473  for (unsigned int j = 0; j < 4; ++j)
1474  _faces[i]->setNode(j, _nodes[hex_local_node_indices[i][j]]);
1475  _faces[i]->createEdges();
1476  for (unsigned int k = 0; k < _num_interior_face_nodes; ++k)
1477  _faces[i]->setInteriorFaceNode(k, _nodes[hex_interior_face_node_indices[i][k]]);
1478  }
1479  }
1480  else if (_num_nodes == 4 || _num_nodes == 10 || _num_nodes == 14)
1481  {
1482  if (_num_faces != 4)
1483  EFAError("num_faces of tets must be 4");
1484  for (unsigned int i = 0; i < _num_faces; ++i)
1485  {
1487  for (unsigned int j = 0; j < 3; ++j)
1488  _faces[i]->setNode(j, _nodes[tet_local_node_indices[i][j]]);
1489  _faces[i]->createEdges();
1490  for (unsigned int k = 0; k < _num_interior_face_nodes; ++k)
1491  _faces[i]->setInteriorFaceNode(k, _nodes[tet_interior_face_node_indices[i][k]]);
1492  }
1493  }
1494  else
1495  EFAError("unknown 3D element type in createFaces()");
1496 
1497  for (unsigned int face_iter = 0; face_iter < _num_faces; ++face_iter)
1498  {
1499  _face_edge_neighbors[face_iter].resize(_faces[face_iter]->numEdges());
1500  for (unsigned int edge_iter = 0; edge_iter < _faces[face_iter]->numEdges(); ++edge_iter)
1501  _face_edge_neighbors[face_iter][edge_iter].clear();
1502  }
1503 
1504  // create element face connectivity array
1505  findFacesAdjacentToFaces(); // IMPORTANT
1506 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:33
unsigned int _num_interior_face_nodes
Definition: EFAElement3D.h:37
void findFacesAdjacentToFaces()
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
sideset clear()
unsigned int _num_nodes
Definition: EFAElement.h:28
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:40

◆ createLocalNodeFromGlobalNode()

EFANode * EFAElement::createLocalNodeFromGlobalNode ( const EFANode global_node) const
inherited

Definition at line 70 of file EFAElement.C.

Referenced by EFAElement2D::createChild(), createChild(), and EFAElement3D().

71 {
72  // Given a global node, create a new local node
73  if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
74  global_node->category() != EFANode::N_CATEGORY_TEMP &&
76  EFAError("In createLocalNodeFromGlobalNode node is not global");
77 
78  EFANode * new_local_node = nullptr;
79  unsigned int inode = 0;
80  for (; inode < _nodes.size(); ++inode)
81  {
82  if (_nodes[inode] == global_node)
83  {
84  new_local_node = new EFANode(inode, EFANode::N_CATEGORY_LOCAL_INDEX);
85  break;
86  }
87  }
88  if (!new_local_node)
89  EFAError("In createLocalNodeFromGlobalNode could not find global node");
90 
91  return new_local_node;
92 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
N_CATEGORY category() const
Definition: EFANode.C:42

◆ faceContainsTip()

bool EFAElement3D::faceContainsTip ( unsigned int  face_id) const

Definition at line 1945 of file EFAElement3D.C.

Referenced by fragmentFaceAlreadyCut().

1946 {
1947  bool contain_tip = false;
1948  if (_fragments.size() == 1)
1949  {
1950  unsigned int num_frag_faces = 0; // count how many fragment faces this element face contains
1951  if (_faces[face_id]->hasIntersection())
1952  {
1953  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1954  {
1955  if (_faces[face_id]->containsFace(_fragments[0]->getFace(j)))
1956  num_frag_faces += 1;
1957  } // j
1958  if (num_frag_faces == 2)
1959  contain_tip = true;
1960  }
1961  }
1962  return contain_tip;
1963 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ findFacesAdjacentToFaces()

void EFAElement3D::findFacesAdjacentToFaces ( )

Definition at line 1674 of file EFAElement3D.C.

Referenced by createFaces(), and EFAElement3D().

1675 {
1676  _faces_adjacent_to_faces.clear();
1677  for (unsigned int i = 0; i < _faces.size(); ++i)
1678  {
1679  std::vector<EFAFace *> face_adjacents(_faces[i]->numEdges(), nullptr);
1680  for (unsigned int j = 0; j < _faces.size(); ++j)
1681  {
1682  if (_faces[j] != _faces[i] && _faces[i]->isAdjacent(_faces[j]))
1683  {
1684  unsigned int adj_edge = _faces[i]->adjacentCommonEdge(_faces[j]);
1685  face_adjacents[adj_edge] = _faces[j];
1686  }
1687  }
1688  _faces_adjacent_to_faces.push_back(face_adjacents);
1689  }
1690 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
std::vector< std::vector< EFAFace * > > _faces_adjacent_to_faces
Definition: EFAElement3D.h:35
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ findGeneralNeighbors()

void EFAElement::findGeneralNeighbors ( const std::map< EFANode *, std::set< EFAElement *>> &  InverseConnectivity)
inherited

Definition at line 208 of file EFAElement.C.

Referenced by EFAElement2D::setupNeighbors(), and setupNeighbors().

210 {
211  _general_neighbors.clear();
212  std::set<EFAElement *> patch_elements;
213  for (unsigned int inode = 0; inode < _num_nodes; ++inode)
214  {
215  auto it = inverse_connectivity.find(_nodes[inode]);
216  if (it != inverse_connectivity.end())
217  patch_elements.insert(it->second.begin(), it->second.end());
218  }
219 
220  std::set<EFAElement *>::iterator eit2;
221  for (eit2 = patch_elements.begin(); eit2 != patch_elements.end(); ++eit2)
222  {
223  EFAElement * neigh_elem = *eit2;
224  if (neigh_elem != this)
225  _general_neighbors.push_back(neigh_elem);
226  }
227 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
unsigned int _num_nodes
Definition: EFAElement.h:28
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:36

◆ fragmentFaceAlreadyCut()

bool EFAElement3D::fragmentFaceAlreadyCut ( unsigned int  ElemFaceID) const

Definition at line 1966 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1967 {
1968  // when marking cuts, check if the corresponding frag face already has been cut
1969  bool has_cut = false;
1970  if (faceContainsTip(ElemFaceID))
1971  has_cut = true;
1972  else
1973  {
1974  unsigned int FragFaceID = std::numeric_limits<unsigned int>::max();
1975  if (getFragmentFaceID(ElemFaceID, FragFaceID))
1976  {
1977  EFAFace * frag_face = getFragmentFace(0, FragFaceID);
1978  if (frag_face->hasIntersection())
1979  has_cut = true;
1980  }
1981  }
1982  return has_cut;
1983 }
bool hasIntersection() const
Definition: EFAFace.C:568
bool getFragmentFaceID(unsigned int elem_face_id, unsigned int &frag_face_id) const
EFAFace * getFragmentFace(unsigned int frag_id, unsigned int face_id) const
bool faceContainsTip(unsigned int face_id) const

◆ fragmentHasTipFaces()

bool EFAElement3D::fragmentHasTipFaces ( ) const

Definition at line 1864 of file EFAElement3D.C.

Referenced by fragmentSanityCheck(), and isCrackTipElement().

1865 {
1866  bool has_tip_faces = false;
1867  if (_fragments.size() == 1)
1868  {
1869  for (unsigned int i = 0; i < _num_faces; ++i)
1870  {
1871  unsigned int num_frag_faces = 0; // count how many fragment edges this element edge contains
1872  if (_faces[i]->hasIntersection())
1873  {
1874  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1875  {
1876  if (_faces[i]->containsFace(_fragments[0]->getFace(j)))
1877  num_frag_faces += 1;
1878  } // j
1879  if (num_frag_faces == 2)
1880  {
1881  has_tip_faces = true;
1882  break;
1883  }
1884  }
1885  } // i
1886  }
1887  return has_tip_faces;
1888 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ fragmentSanityCheck()

void EFAElement3D::fragmentSanityCheck ( unsigned int  n_old_frag_faces,
unsigned int  n_old_frag_cuts 
) const
virtual

Implements EFAElement.

Definition at line 903 of file EFAElement3D.C.

Referenced by updateFragments().

904 {
905  unsigned int n_interior_nodes = numInteriorNodes();
906  if (n_interior_nodes > 0 && n_interior_nodes != 1)
907  EFAError("After update_fragments this element has ", n_interior_nodes, " interior nodes");
908 
909  if (n_old_frag_cuts == 0)
910  {
911  if (_fragments.size() != 1 || _fragments[0]->numFaces() != n_old_frag_faces)
912  EFAError("Incorrect link size for element with 0 cuts");
913  }
914  else if (fragmentHasTipFaces()) // crack tip case
915  {
916  if (_fragments.size() != 1 || _fragments[0]->numFaces() != n_old_frag_faces + n_old_frag_cuts)
917  EFAError("Incorrect link size for element with crack-tip faces");
918  }
919  else // frag is thoroughly cut
920  {
921  if (_fragments.size() != 2 || (_fragments[0]->numFaces() + _fragments[1]->numFaces()) !=
922  n_old_frag_faces + n_old_frag_cuts + 2)
923  EFAError("Incorrect link size for element that has been completely cut");
924  }
925 }
virtual unsigned int numInteriorNodes() const
Definition: EFAElement3D.C:425
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
bool fragmentHasTipFaces() const

◆ getAdjacentFace()

EFAFace * EFAElement3D::getAdjacentFace ( unsigned int  face_id,
unsigned int  edge_id 
) const

Definition at line 1693 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1694 {
1695  return _faces_adjacent_to_faces[face_id][edge_id];
1696 }
std::vector< std::vector< EFAFace * > > _faces_adjacent_to_faces
Definition: EFAElement3D.h:35

◆ getChild()

EFAElement * EFAElement::getChild ( unsigned int  child_id) const
inherited

Definition at line 174 of file EFAElement.C.

Referenced by EFAElement2D::connectNeighbors(), connectNeighbors(), EFAElement2D::switchNode(), and switchNode().

175 {
176  if (child_id < _children.size())
177  return _children[child_id];
178  else
179  EFAError("child_id out of bounds");
180 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:32

◆ getCommonEdgeID()

bool EFAElement3D::getCommonEdgeID ( const EFAElement3D other_elem,
std::vector< std::pair< unsigned int, unsigned int >> &  common_ids 
) const

Definition at line 1549 of file EFAElement3D.C.

Referenced by setupNeighbors().

1551 {
1552  // all edges of the other element
1553  std::set<std::pair<EFANode *, EFANode *>> other_edges;
1554  for (const auto k : index_range(other_elem->_faces))
1555  {
1556  const auto & face = *other_elem->_faces[k];
1557  for (const auto l : make_range(other_elem->_faces[k]->numEdges()))
1558  {
1559  const auto & edge = *face.getEdge(l);
1560  other_edges.insert(edge.getSortedNodes());
1561  }
1562  }
1563 
1564  // loop over all edges of this element
1565  common_ids.clear();
1566  for (const auto i : index_range(_faces))
1567  for (const auto j : make_range(_faces[i]->numEdges()))
1568  {
1569  const auto & edge = *_faces[i]->getEdge(j);
1570  const auto edge_nodes = edge.getSortedNodes();
1571 
1572  // is this edge contained in the other element?
1573  if (edge.isEmbeddedPermanent() || other_edges.count(edge_nodes) == 0)
1574  continue;
1575 
1576  common_ids.emplace_back(i, j);
1577  }
1578 
1579  return common_ids.size() > 0;
1580 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
IntRange< T > make_range(T beg, T end)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130
auto index_range(const T &sizable)

◆ getCommonFaceID()

std::vector< unsigned int > EFAElement3D::getCommonFaceID ( const EFAElement3D other_elem) const

Definition at line 1534 of file EFAElement3D.C.

Referenced by overlaysElement(), and setupNeighbors().

1535 {
1536  std::vector<unsigned int> face_id;
1537  for (unsigned int i = 0; i < _num_faces; ++i)
1538  for (unsigned int j = 0; j < other_elem->_num_faces; ++j)
1539  if (_faces[i]->equivalent(other_elem->_faces[j]))
1540  {
1541  face_id.push_back(i);
1542  break;
1543  }
1544 
1545  return face_id;
1546 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ getCommonNodes()

std::vector< EFANode * > EFAElement3D::getCommonNodes ( const EFAElement3D other_elem) const

Definition at line 2238 of file EFAElement3D.C.

2239 {
2240  std::set<EFANode *> e1nodes(_nodes.begin(),
2241  _nodes.begin() + _num_vertices); // only account for corner nodes
2242  std::set<EFANode *> e2nodes(other_elem->_nodes.begin(),
2243  other_elem->_nodes.begin() + _num_vertices);
2244  std::vector<EFANode *> common_nodes = Efa::getCommonElems(e1nodes, e2nodes);
2245  return common_nodes;
2246 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
unsigned int _num_vertices
Definition: EFAElement3D.h:36
std::vector< T > getCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:69

◆ getCrackTipNeighbor()

unsigned int EFAElement::getCrackTipNeighbor ( unsigned int  index) const
inherited

Definition at line 140 of file EFAElement.C.

141 {
142  if (index < _crack_tip_neighbors.size())
143  return _crack_tip_neighbors[index];
144  else
145  EFAError("in getCrackTipNeighbor index out of bounds");
146 }
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:34

◆ getEdgeNeighbor()

EFAElement3D * EFAElement3D::getEdgeNeighbor ( unsigned int  face_id,
unsigned int  edge_id,
unsigned int  neighbor_id 
) const

Definition at line 1853 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1856 {
1857  if (neighbor_id < _face_edge_neighbors[face_id][edge_id].size())
1858  return _face_edge_neighbors[face_id][edge_id][neighbor_id];
1859  else
1860  EFAError("edge neighbor does not exist");
1861 }
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:33

◆ getFace()

EFAFace * EFAElement3D::getFace ( unsigned int  face_id) const

◆ getFaceID()

unsigned int EFAElement3D::getFaceID ( EFAFace face) const

Definition at line 1515 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), and overlaysElement().

1516 {
1517  bool found_face_id = false;
1518  unsigned int face_id;
1519  for (unsigned int iface = 0; iface < _num_faces; ++iface)
1520  {
1521  if (_faces[iface]->equivalent(face))
1522  {
1523  face_id = iface;
1524  found_face_id = true;
1525  break;
1526  }
1527  }
1528  if (!found_face_id)
1529  EFAError("input face not found in get_face_id()");
1530  return face_id;
1531 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
unsigned int _num_faces
Definition: EFAElement3D.h:29

◆ getFaceNeighbor()

EFAElement3D * EFAElement3D::getFaceNeighbor ( unsigned int  face_id,
unsigned int  neighbor_id 
) const

Definition at line 1844 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), checkNeighborFaceCut(), connectNeighbors(), XFEM::cutMeshWithEFA(), neighborSanityCheck(), printElement(), and removeEmbeddedNode().

1845 {
1846  if (_face_neighbors[face_id][0] != nullptr && neighbor_id < _face_neighbors[face_id].size())
1847  return _face_neighbors[face_id][neighbor_id];
1848  else
1849  EFAError("edge neighbor does not exist");
1850 }
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32

◆ getFaceNodeParametricCoordinates()

bool EFAElement3D::getFaceNodeParametricCoordinates ( EFANode node,
std::vector< double > &  xi_3d 
) const

Definition at line 1385 of file EFAElement3D.C.

1386 {
1387  // get the parametric coords of a node in an element face
1388  unsigned int face_id = std::numeric_limits<unsigned int>::max();
1389  bool face_found = false;
1390  for (unsigned int i = 0; i < _num_faces; ++i)
1391  {
1392  if (_faces[i]->containsNode(node))
1393  {
1394  face_id = i;
1395  face_found = true;
1396  break;
1397  }
1398  }
1399  if (face_found)
1400  {
1401  std::vector<double> xi_2d(2, 0.0);
1402  if (_faces[face_id]->getFaceNodeParametricCoords(node, xi_2d))
1403  mapParametricCoordinateFrom2DTo3D(face_id, xi_2d, xi_3d);
1404  else
1405  EFAError("failed to get the 2D para coords on the face");
1406  }
1407  return face_found;
1408 }
void mapParametricCoordinateFrom2DTo3D(unsigned int face_id, std::vector< double > &xi_2d, std::vector< double > &xi_3d) const
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
unsigned int _num_faces
Definition: EFAElement3D.h:29

◆ getFaceNodes()

std::set< EFANode * > EFAElement3D::getFaceNodes ( unsigned int  face_id) const

Definition at line 1376 of file EFAElement3D.C.

Referenced by shouldDuplicateCrackTipSplitElement().

1377 {
1378  std::set<EFANode *> face_nodes;
1379  for (unsigned int i = 0; i < _faces[face_id]->numNodes(); ++i)
1380  face_nodes.insert(_faces[face_id]->getNode(i));
1381  return face_nodes;
1382 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30

◆ getFragment()

EFAFragment3D * EFAElement3D::getFragment ( unsigned int  frag_id) const

◆ getFragmentFace()

EFAFace * EFAElement3D::getFragmentFace ( unsigned int  frag_id,
unsigned int  face_id 
) const

Definition at line 1699 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), EFAFragment3D::EFAFragment3D(), fragmentFaceAlreadyCut(), getFragmentFaceEdgeID(), XFEM::getFragmentFaces(), and isPhysicalEdgeCut().

1700 {
1701  if (frag_id < _fragments.size())
1702  return _fragments[frag_id]->getFace(face_id);
1703  else
1704  EFAError("frag_id out of bounds in getFragmentFace");
1705 }
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34

◆ getFragmentFaceEdgeID()

bool EFAElement3D::getFragmentFaceEdgeID ( unsigned int  ElemFaceID,
unsigned int  ElemFaceEdgeID,
unsigned int FragFaceID,
unsigned int FragFaceEdgeID 
) const

Definition at line 1755 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), and isPhysicalEdgeCut().

1759 {
1760  // Purpose: given an edge of an elem face, find which frag face's edge it contains
1761  bool frag_edge_found = false;
1762  FragFaceID = FragFaceEdgeID = std::numeric_limits<unsigned int>::max();
1763  if (getFragmentFaceID(ElemFaceID, FragFaceID))
1764  {
1765  EFAEdge * elem_edge = _faces[ElemFaceID]->getEdge(ElemFaceEdgeID);
1766  EFAFace * frag_face = getFragmentFace(0, FragFaceID);
1767  for (unsigned int i = 0; i < frag_face->numEdges(); ++i)
1768  {
1769  if (elem_edge->containsEdge(*frag_face->getEdge(i)))
1770  {
1771  FragFaceEdgeID = i;
1772  frag_edge_found = true;
1773  break;
1774  }
1775  }
1776  }
1777  return frag_edge_found;
1778 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
unsigned int numEdges() const
Definition: EFAFace.h:49
bool containsEdge(const EFAEdge &other) const
Definition: EFAEdge.C:65
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.h:50
bool getFragmentFaceID(unsigned int elem_face_id, unsigned int &frag_face_id) const
EFAFace * getFragmentFace(unsigned int frag_id, unsigned int face_id) const

◆ getFragmentFaceID()

bool EFAElement3D::getFragmentFaceID ( unsigned int  elem_face_id,
unsigned int frag_face_id 
) const

Definition at line 1732 of file EFAElement3D.C.

Referenced by fragmentFaceAlreadyCut(), and getFragmentFaceEdgeID().

1733 {
1734  // find the fragment face that is contained by given element edge
1735  // N.B. if the elem edge contains two frag edges, this method will only return
1736  // the first frag edge ID
1737  bool frag_face_found = false;
1738  frag_face_id = std::numeric_limits<unsigned int>::max();
1739  if (_fragments.size() == 1)
1740  {
1741  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1742  {
1743  if (_faces[elem_face_id]->containsFace(_fragments[0]->getFace(j)))
1744  {
1745  frag_face_id = j;
1746  frag_face_found = true;
1747  break;
1748  }
1749  }
1750  }
1751  return frag_face_found;
1752 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ getGeneralNeighbor()

EFAElement * EFAElement::getGeneralNeighbor ( unsigned int  index) const
inherited

Definition at line 230 of file EFAElement.C.

Referenced by EFAElement2D::switchNode(), and switchNode().

231 {
232  return _general_neighbors[index];
233 }
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:36

◆ getGlobalNodeFromLocalNode()

EFANode * EFAElement::getGlobalNodeFromLocalNode ( const EFANode local_node) const
inherited

Definition at line 95 of file EFAElement.C.

96 {
97  // Given a local node, find the global node corresponding to that node
98  if (local_node->category() != EFANode::N_CATEGORY_LOCAL_INDEX)
99  EFAError("In getGlobalNodeFromLocalNode node passed in is not local");
100 
101  EFANode * global_node = _nodes[local_node->id()];
102 
103  if (global_node->category() != EFANode::N_CATEGORY_PERMANENT &&
104  global_node->category() != EFANode::N_CATEGORY_TEMP)
105  EFAError("In getGlobalNodeFromLocalNode, the node stored by the element is not global");
106 
107  return global_node;
108 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
unsigned int id() const
Definition: EFANode.C:36
N_CATEGORY category() const
Definition: EFANode.C:42

◆ getInteriorNode()

EFAVolumeNode * EFAElement3D::getInteriorNode ( unsigned int  interior_node_id) const

Definition at line 1411 of file EFAElement3D.C.

Referenced by EFAFragment3D::isThirdInteriorFace().

1412 {
1413  if (interior_node_id < _interior_nodes.size())
1414  return _interior_nodes[interior_node_id];
1415  else
1416  EFAError("interior_node_id out of bounds");
1417 }
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31

◆ getLocalNodeIndex()

unsigned int EFAElement::getLocalNodeIndex ( EFANode node) const
inherited

Definition at line 111 of file EFAElement.C.

Referenced by XFEM::getEFANodeCoords().

112 {
113  for (unsigned int i = 0; i < _num_nodes; ++i)
114  {
115  if (_nodes[i] == node)
116  return i;
117  }
118  EFAError("In EFAelement::getLocalNodeIndex, cannot find the given node");
119 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
unsigned int _num_nodes
Definition: EFAElement.h:28

◆ getMasterInfo()

void EFAElement3D::getMasterInfo ( EFANode node,
std::vector< EFANode *> &  master_nodes,
std::vector< double > &  master_weights 
) const
virtual

Implements EFAElement.

Definition at line 373 of file EFAElement3D.C.

Referenced by createChild(), and XFEMCutElem3D::getNodeCoordinates().

376 {
377  // Given a EFAnode, return its master nodes and weights
378  master_nodes.clear();
379  master_weights.clear();
380  bool masters_found = false;
381  for (unsigned int i = 0; i < _num_faces; ++i) // check element exterior faces
382  {
383  if (_faces[i]->containsNode(node))
384  {
385  masters_found = _faces[i]->getMasterInfo(node, master_nodes, master_weights);
386  if (masters_found)
387  break;
388  else
389  EFAError("In getMasterInfo: cannot find master nodes in element faces");
390  }
391  }
392 
393  if (!masters_found) // check element interior embedded nodes
394  {
395  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
396  {
397  if (_interior_nodes[i]->getNode() == node)
398  {
399  std::vector<double> xi_3d(3, -100.0);
400  for (unsigned int j = 0; j < 3; ++j)
401  xi_3d[j] = _interior_nodes[i]->getParametricCoordinates(j);
402  for (unsigned int j = 0; j < _num_nodes; ++j)
403  {
404  master_nodes.push_back(_nodes[j]);
405  double weight = 0.0;
406  if (_num_nodes == 8)
407  weight = Efa::linearHexShape3D(j, xi_3d);
408  else if (_num_nodes == 4)
409  weight = Efa::linearTetShape3D(j, xi_3d);
410  else
411  EFAError("unknown 3D element");
412  master_weights.push_back(weight);
413  }
414  masters_found = true;
415  break;
416  }
417  }
418  }
419 
420  if (!masters_found)
421  EFAError("In EFAelement3D::getMasterInfo, cannot find the given EFANode");
422 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
dof_id_type weight(const MeshBase &mesh, const processor_id_type pid)
unsigned int _num_nodes
Definition: EFAElement.h:28
double linearTetShape3D(unsigned int node_id, std::vector< double > &xi_3d)
Definition: EFAFuncs.C:48
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
double linearHexShape3D(unsigned int node_id, std::vector< double > &xi_3d)
Definition: EFAFuncs.C:33
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31

◆ getNeighborEdgeIndex()

void EFAElement3D::getNeighborEdgeIndex ( const EFAElement3D neighbor_elem,
unsigned int  face_id,
unsigned int  edge_id,
unsigned int neigh_face_id,
unsigned int neigh_edge_id 
) const
virtual

Definition at line 468 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

473 {
474  EFAEdge * edge = this->getFace(face_id)->getEdge(edge_id);
475  for (unsigned int i = 0; i < neighbor_elem->numFaces(); ++i)
476  {
477  for (unsigned int j = 0; j < neighbor_elem->getFace(i)->numEdges(); ++j)
478  {
479  EFAEdge * neigh_edge = neighbor_elem->getFace(i)->getEdge(j);
480  if (neigh_edge->equivalent(*edge))
481  {
482  neigh_face_id = i;
483  neigh_edge_id = j;
484  return;
485  }
486  }
487  }
488  EFAError("in getNeighborEdgeIndex() element ",
489  _id,
490  " does not share a common edge with element",
491  neighbor_elem->id());
492 }
EFAFace * getFace(unsigned int face_id) const
unsigned int numEdges() const
Definition: EFAFace.h:49
unsigned int id() const
Definition: EFAElement.C:28
unsigned int _id
Definition: EFAElement.h:27
unsigned int numFaces() const
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.h:50
bool equivalent(const EFAEdge &other) const
Definition: EFAEdge.C:38
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ getNeighborFaceEdgeID()

unsigned int EFAElement3D::getNeighborFaceEdgeID ( unsigned int  face_id,
unsigned int  edg_id,
EFAElement3D neighbor_elem 
) const

Definition at line 1644 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), and checkNeighborFaceCut().

1647 {
1648  // get the corresponding edge_id on the corresponding face of neighbor_elem
1649  bool found_id = false;
1650  unsigned int neigh_face_edge_id;
1651  unsigned int common_face_id = getNeighborIndex(neighbor_elem);
1652  if (common_face_id == face_id)
1653  {
1654  unsigned int neigh_face_id = neighbor_elem->getNeighborIndex(this);
1655  EFAFace * neigh_face = neighbor_elem->getFace(neigh_face_id);
1656  for (unsigned int i = 0; i < neigh_face->numEdges(); ++i)
1657  {
1658  if (_faces[face_id]->getEdge(edge_id)->equivalent(*neigh_face->getEdge(i)))
1659  {
1660  neigh_face_edge_id = i;
1661  found_id = true;
1662  break;
1663  }
1664  }
1665  }
1666  else
1667  EFAError("getNeighborFaceEdgeID: neighbor_elem is not a neighbor on face_id");
1668  if (!found_id)
1669  EFAError("getNeighborFaceEdgeID: could not find neighbor face edge id");
1670  return neigh_face_edge_id;
1671 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
unsigned int numEdges() const
Definition: EFAFace.h:49
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement3D.C:458
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.h:50

◆ getNeighborFaceInteriorNodeID()

unsigned int EFAElement3D::getNeighborFaceInteriorNodeID ( unsigned int  face_id,
unsigned int  node_id,
EFAElement3D neighbor_elem 
) const

Definition at line 1613 of file EFAElement3D.C.

Referenced by connectNeighbors().

1616 {
1617  // get the corresponding node_id on the corresponding face of neighbor_elem
1618  bool found_id = false;
1619  unsigned int neigh_face_node_id;
1620  unsigned int common_face_id = getNeighborIndex(neighbor_elem);
1621  if (common_face_id == face_id)
1622  {
1623  unsigned int neigh_face_id = neighbor_elem->getNeighborIndex(this);
1624  EFAFace * neigh_face = neighbor_elem->getFace(neigh_face_id);
1625 
1626  for (unsigned int i = 0; i < _num_interior_face_nodes; ++i)
1627  {
1628  if (_faces[face_id]->getInteriorFaceNode(node_id) == neigh_face->getInteriorFaceNode(i))
1629  {
1630  neigh_face_node_id = i;
1631  found_id = true;
1632  break;
1633  }
1634  }
1635  }
1636  else
1637  EFAError("getNeighborFaceNodeID: neighbor_elem is not a neighbor on face_id");
1638  if (!found_id)
1639  EFAError("getNeighborFaceNodeID: could not find neighbor face node id");
1640  return neigh_face_node_id;
1641 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
unsigned int _num_interior_face_nodes
Definition: EFAElement3D.h:37
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement3D.C:458
EFANode * getInteriorFaceNode(unsigned int i) const
Definition: EFAFace.h:58

◆ getNeighborFaceNodeID()

unsigned int EFAElement3D::getNeighborFaceNodeID ( unsigned int  face_id,
unsigned int  node_id,
EFAElement3D neighbor_elem 
) const

Definition at line 1583 of file EFAElement3D.C.

Referenced by connectNeighbors().

1586 {
1587  // get the corresponding node_id on the corresponding face of neighbor_elem
1588  bool found_id = false;
1589  unsigned int neigh_face_node_id;
1590  unsigned int common_face_id = getNeighborIndex(neighbor_elem);
1591  if (common_face_id == face_id)
1592  {
1593  unsigned int neigh_face_id = neighbor_elem->getNeighborIndex(this);
1594  EFAFace * neigh_face = neighbor_elem->getFace(neigh_face_id);
1595  for (unsigned int i = 0; i < neigh_face->numNodes(); ++i)
1596  {
1597  if (_faces[face_id]->getNode(node_id) == neigh_face->getNode(i))
1598  {
1599  neigh_face_node_id = i;
1600  found_id = true;
1601  break;
1602  }
1603  }
1604  }
1605  else
1606  EFAError("getNeighborFaceNodeID: neighbor_elem is not a neighbor on face_id");
1607  if (!found_id)
1608  EFAError("getNeighborFaceNodeID: could not find neighbor face node id");
1609  return neigh_face_node_id;
1610 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
EFANode * getNode(unsigned int node_id) const
Definition: EFAFace.C:99
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement3D.C:458
unsigned int numNodes() const
Definition: EFAFace.C:87
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46

◆ getNeighborIndex()

unsigned int EFAElement3D::getNeighborIndex ( const EFAElement neighbor_elem) const
virtual

Implements EFAElement.

Definition at line 458 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), checkNeighborFaceCut(), connectNeighbors(), getNeighborFaceEdgeID(), getNeighborFaceInteriorNodeID(), and getNeighborFaceNodeID().

459 {
460  for (unsigned int i = 0; i < _num_faces; ++i)
461  for (unsigned int j = 0; j < _face_neighbors[i].size(); ++j)
462  if (_face_neighbors[i][j] == neighbor_elem)
463  return i;
464  EFAError("in getNeighborIndex() element ", _id, " does not have neighbor ", neighbor_elem->id());
465 }
unsigned int id() const
Definition: EFAElement.C:28
unsigned int _id
Definition: EFAElement.h:27
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ getNode()

EFANode * EFAElement::getNode ( unsigned int  node_id) const
inherited

◆ getNodes()

const std::vector<EFANode *>& EFAElement::getNodes ( ) const
inlineinherited

Definition at line 44 of file EFAElement.h.

44 { return _nodes; }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29

◆ getNonPhysicalNodes()

void EFAElement3D::getNonPhysicalNodes ( std::set< EFANode *> &  non_physical_nodes) const
virtual

Implements EFAElement.

Definition at line 302 of file EFAElement3D.C.

Referenced by shouldDuplicateCrackTipSplitElement().

303 {
304  // Any nodes that don't belong to any fragment are non-physical
305  // First add all nodes in the element to the set
306  for (unsigned int i = 0; i < _nodes.size(); ++i)
307  non_physical_nodes.insert(_nodes[i]);
308 
309  // Now delete any nodes that are contained in fragments
310  std::set<EFANode *>::iterator sit;
311  for (sit = non_physical_nodes.begin(); sit != non_physical_nodes.end();)
312  {
313  bool erased = false;
314  for (unsigned int i = 0; i < _fragments.size(); ++i)
315  {
316  if (_fragments[i]->containsNode(*sit))
317  {
318  non_physical_nodes.erase(sit++);
319  erased = true;
320  break;
321  }
322  }
323  if (!erased)
324  ++sit;
325  }
326 }
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34

◆ getNumCuts()

unsigned int EFAElement3D::getNumCuts ( ) const
virtual

Implements EFAElement.

Definition at line 815 of file EFAElement3D.C.

Referenced by restoreFragment().

816 {
817  unsigned int num_cut_faces = 0;
818  for (unsigned int i = 0; i < _num_faces; ++i)
819  if (_faces[i]->hasIntersection())
820  num_cut_faces += 1;
821  return num_cut_faces;
822 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
unsigned int _num_faces
Definition: EFAElement3D.h:29

◆ getParent()

EFAElement * EFAElement::getParent ( ) const
inherited

Definition at line 168 of file EFAElement.C.

169 {
170  return _parent;
171 }
EFAElement * _parent
Definition: EFAElement.h:31

◆ getPhantomNodeOnFace()

std::set< EFANode * > EFAElement3D::getPhantomNodeOnFace ( unsigned int  face_id) const

Definition at line 1708 of file EFAElement3D.C.

Referenced by shouldDuplicateForPhantomCorner().

1709 {
1710  std::set<EFANode *> phantom_nodes;
1711  if (_fragments.size() > 0)
1712  {
1713  for (unsigned int j = 0; j < _faces[face_id]->numNodes(); ++j) // loop ove 2 edge nodes
1714  {
1715  bool node_in_frag = false;
1716  for (unsigned int k = 0; k < _fragments.size(); ++k)
1717  {
1718  if (_fragments[k]->containsNode(_faces[face_id]->getNode(j)))
1719  {
1720  node_in_frag = true;
1721  break;
1722  }
1723  }
1724  if (!node_in_frag)
1725  phantom_nodes.insert(_faces[face_id]->getNode(j));
1726  }
1727  }
1728  return phantom_nodes;
1729 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130

◆ getTipEmbeddedNodes()

std::set< EFANode * > EFAElement3D::getTipEmbeddedNodes ( ) const

Definition at line 1916 of file EFAElement3D.C.

1917 {
1918  // if this element is a crack tip element, returns the crack tip edge's ID
1919  std::set<EFANode *> tip_emb;
1920  if (_fragments.size() == 1) // crack tip element with a partial fragment saved
1921  {
1922  for (unsigned int i = 0; i < _num_faces; ++i)
1923  {
1924  std::vector<EFAFace *> frag_faces; // count how many fragment edges this element edge contains
1925  if (_faces[i]->hasIntersection())
1926  {
1927  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1928  {
1929  if (_faces[i]->containsFace(_fragments[0]->getFace(j)))
1930  frag_faces.push_back(_fragments[0]->getFace(j));
1931  } // j
1932  if (frag_faces.size() == 2) // element edge contains two fragment edges
1933  {
1934  unsigned int edge_id = frag_faces[0]->adjacentCommonEdge(frag_faces[1]);
1935  tip_emb.insert(frag_faces[0]->getEdge(edge_id)->getNode(0));
1936  tip_emb.insert(frag_faces[0]->getEdge(edge_id)->getNode(1));
1937  }
1938  }
1939  } // i
1940  }
1941  return tip_emb;
1942 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ getTipFaceIDs()

std::vector< unsigned int > EFAElement3D::getTipFaceIDs ( ) const

Definition at line 1891 of file EFAElement3D.C.

1892 {
1893  // if this element is a crack tip element, returns the crack tip faces' ID
1894  std::vector<unsigned int> tip_face_id;
1895  if (_fragments.size() == 1) // crack tip element with a partial fragment saved
1896  {
1897  for (unsigned int i = 0; i < _num_faces; ++i)
1898  {
1899  unsigned int num_frag_faces = 0; // count how many fragment faces this element edge contains
1900  if (_faces[i]->hasIntersection())
1901  {
1902  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1903  {
1904  if (_faces[i]->containsFace(_fragments[0]->getFace(j)))
1905  num_frag_faces += 1;
1906  } // j
1907  if (num_frag_faces == 2) // element face contains two fragment edges
1908  tip_face_id.push_back(i);
1909  }
1910  } // i
1911  }
1912  return tip_face_id;
1913 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ id()

unsigned int EFAElement::id ( ) const
inherited

◆ initCrackTip()

void EFAElement3D::initCrackTip ( std::set< EFAElement *> &  CrackTipElements)
virtual

Implements EFAElement.

Definition at line 606 of file EFAElement3D.C.

607 {
608  if (isCrackTipElement())
609  {
610  CrackTipElements.insert(this);
611  for (unsigned int face_iter = 0; face_iter < _num_faces; ++face_iter)
612  {
613  if ((_face_neighbors[face_iter].size() == 2) && (_faces[face_iter]->hasIntersection()))
614  {
615  // Neither neighbor overlays current element. We are on the uncut element ahead of the tip.
616  // Flag neighbors as crack tip split elements and add this element as their crack tip
617  // neighbor.
618  if (_face_neighbors[face_iter][0]->overlaysElement(this) ||
619  _face_neighbors[face_iter][1]->overlaysElement(this))
620  EFAError("Element has a neighbor that overlays itself");
621 
622  // Make sure the current elment hasn't been flagged as a tip element
624  EFAError("crack_tip_split_element already flagged. In elem: ",
625  _id,
626  " flags: ",
628  " ",
629  _face_neighbors[face_iter][0]->isCrackTipSplit(),
630  " ",
631  _face_neighbors[face_iter][1]->isCrackTipSplit());
632 
633  _face_neighbors[face_iter][0]->setCrackTipSplit();
634  _face_neighbors[face_iter][1]->setCrackTipSplit();
635 
636  _face_neighbors[face_iter][0]->addCrackTipNeighbor(this);
637  _face_neighbors[face_iter][1]->addCrackTipNeighbor(this);
638  }
639  } // face_iter
640  }
641 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
bool isCrackTipSplit() const
Definition: EFAElement.C:128
unsigned int _id
Definition: EFAElement.h:27
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
unsigned int _num_faces
Definition: EFAElement3D.h:29
bool overlaysElement(const EFAElement3D *other_elem) const
Definition: EFAElement3D.C:431
bool _crack_tip_split_element
Definition: EFAElement.h:33
virtual bool isCrackTipElement() const
Definition: EFAElement3D.C:809

◆ isCrackTipElement()

bool EFAElement3D::isCrackTipElement ( ) const
virtual

Implements EFAElement.

Definition at line 809 of file EFAElement3D.C.

Referenced by initCrackTip(), and shouldDuplicateForCrackTip().

810 {
811  return fragmentHasTipFaces();
812 }
bool fragmentHasTipFaces() const

◆ isCrackTipSplit()

bool EFAElement::isCrackTipSplit ( ) const
inherited

Definition at line 128 of file EFAElement.C.

Referenced by EFAElement2D::getCrackTipSplitElementID(), EFAElement2D::initCrackTip(), and initCrackTip().

129 {
131 }
bool _crack_tip_split_element
Definition: EFAElement.h:33

◆ isFacePhantom()

bool EFAElement3D::isFacePhantom ( unsigned int  face_id) const

Definition at line 1806 of file EFAElement3D.C.

Referenced by XFEM::markCutFacesByGeometry().

1807 {
1808  bool is_phantom = false;
1809  if (_fragments.size() > 0)
1810  {
1811  bool contains_frag_face = false;
1812  for (unsigned int i = 0; i < _fragments.size(); ++i)
1813  {
1814  for (unsigned int j = 0; j < _fragments[i]->numFaces(); ++j)
1815  {
1816  if (_faces[face_id]->containsFace(_fragments[i]->getFace(j)))
1817  {
1818  contains_frag_face = true;
1819  break;
1820  }
1821  }
1822  if (contains_frag_face)
1823  break;
1824  }
1825  if (!contains_frag_face)
1826  is_phantom = true;
1827  }
1828  return is_phantom;
1829 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ isFinalCut()

bool EFAElement3D::isFinalCut ( ) const
virtual

Implements EFAElement.

Definition at line 825 of file EFAElement3D.C.

Referenced by GeometricCutUserObject::execute().

826 {
827  // if an element has been cut third times its fragment must have 3 interior faces
828  // and at this point, we do not want it to be further cut
829  bool cut_third = false;
830  if (_fragments.size() > 0)
831  {
832  unsigned int num_interior_faces = 0;
833  for (unsigned int i = 0; i < _fragments[0]->numFaces(); ++i)
834  {
835  if (_fragments[0]->isFaceInterior(i))
836  num_interior_faces += 1;
837  }
838  if (num_interior_faces == 3)
839  cut_third = true;
840  }
841  return cut_third;
842 }
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34

◆ isPartial()

bool EFAElement3D::isPartial ( ) const
virtual

Implements EFAElement.

Definition at line 278 of file EFAElement3D.C.

Referenced by updateFragments().

279 {
280  if (_fragments.size() > 0)
281  {
282  for (unsigned int i = 0; i < _num_vertices; ++i)
283  {
284  bool node_in_frag = false;
285  for (unsigned int j = 0; j < _fragments.size(); ++j)
286  {
287  if (_fragments[j]->containsNode(_nodes[i]))
288  {
289  node_in_frag = true;
290  break;
291  }
292  } // j
293 
294  if (!node_in_frag)
295  return true;
296  } // i
297  }
298  return false;
299 }
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_vertices
Definition: EFAElement3D.h:36
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")

◆ isPhysicalEdgeCut()

bool EFAElement3D::isPhysicalEdgeCut ( unsigned int  ElemFaceID,
unsigned int  ElemFaceEdgeID,
double  position 
) const

Definition at line 1781 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1784 {
1785  unsigned int FragFaceID, FragFaceEdgeID = std::numeric_limits<unsigned int>::max();
1786  bool is_in_real = false;
1787  if (_fragments.size() == 0)
1788  {
1789  is_in_real = true;
1790  }
1791  else if (getFragmentFaceEdgeID(ElemFaceID, ElemFaceEdgeID, FragFaceID, FragFaceEdgeID))
1792  {
1793  EFAEdge * elem_edge = _faces[ElemFaceID]->getEdge(ElemFaceEdgeID);
1794  EFAEdge * frag_edge = getFragmentFace(0, FragFaceID)->getEdge(FragFaceEdgeID);
1795  double xi[2] = {-1.0, -1.0}; // relative coords of two frag edge nodes
1796  xi[0] = elem_edge->distanceFromNode1(frag_edge->getNode(0));
1797  xi[1] = elem_edge->distanceFromNode1(frag_edge->getNode(1));
1798  if ((position - xi[0]) * (position - xi[1]) <
1799  0.0) // the cut to be added is within the real part of the edge
1800  is_in_real = true;
1801  }
1802  return is_in_real;
1803 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
bool getFragmentFaceEdgeID(unsigned int ElemFaceID, unsigned int ElemFaceEdgeID, unsigned int &FragFaceID, unsigned int &FragFaceEdgeID) const
double distanceFromNode1(EFANode *node) const
Definition: EFAEdge.C:250
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.h:50
EFAFace * getFragmentFace(unsigned int frag_id, unsigned int face_id) const
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:181

◆ mapParametricCoordinateFrom2DTo3D()

void EFAElement3D::mapParametricCoordinateFrom2DTo3D ( unsigned int  face_id,
std::vector< double > &  xi_2d,
std::vector< double > &  xi_3d 
) const
private

Definition at line 2157 of file EFAElement3D.C.

Referenced by getFaceNodeParametricCoordinates().

2160 {
2161  // given the coords of a point in a 2D face, translate it to 3D parametric coords
2162  xi_3d.resize(3, 0.0);
2163  if (_num_faces == 6)
2164  {
2165  if (face_id == 0)
2166  {
2167  xi_3d[0] = xi_2d[1];
2168  xi_3d[1] = xi_2d[0];
2169  xi_3d[2] = -1.0;
2170  }
2171  else if (face_id == 1)
2172  {
2173  xi_3d[0] = xi_2d[0];
2174  xi_3d[1] = -1.0;
2175  xi_3d[2] = xi_2d[1];
2176  }
2177  else if (face_id == 2)
2178  {
2179  xi_3d[0] = 1.0;
2180  xi_3d[1] = xi_2d[0];
2181  xi_3d[2] = xi_2d[1];
2182  }
2183  else if (face_id == 3)
2184  {
2185  xi_3d[0] = -xi_2d[0];
2186  xi_3d[1] = 1.0;
2187  xi_3d[2] = xi_2d[1];
2188  }
2189  else if (face_id == 4)
2190  {
2191  xi_3d[0] = -1.0;
2192  xi_3d[1] = -xi_2d[0];
2193  xi_3d[2] = xi_2d[1];
2194  }
2195  else if (face_id == 5)
2196  {
2197  xi_3d[0] = xi_2d[0];
2198  xi_3d[1] = xi_2d[1];
2199  xi_3d[2] = 1.0;
2200  }
2201  else
2202  EFAError("face_id out of bounds");
2203  }
2204  else if (_num_faces == 4)
2205  {
2206  if (face_id == 0)
2207  {
2208  xi_3d[0] = xi_2d[0];
2209  xi_3d[1] = xi_2d[1];
2210  xi_3d[2] = 0.0;
2211  }
2212  else if (face_id == 1)
2213  {
2214  xi_3d[0] = 0.0;
2215  xi_3d[1] = xi_2d[0];
2216  xi_3d[2] = xi_2d[1];
2217  }
2218  else if (face_id == 2)
2219  {
2220  xi_3d[0] = xi_2d[1];
2221  xi_3d[1] = 0.0;
2222  xi_3d[2] = xi_2d[0];
2223  }
2224  else if (face_id == 3)
2225  {
2226  xi_3d[0] = xi_2d[0];
2227  xi_3d[1] = xi_2d[2];
2228  xi_3d[2] = xi_2d[1];
2229  }
2230  else
2231  EFAError("face_id out of bounds");
2232  }
2233  else
2234  EFAError("unknown element for 3D");
2235 }
unsigned int _num_faces
Definition: EFAElement3D.h:29

◆ mergeNodes()

void EFAElement::mergeNodes ( EFANode *&  childNode,
EFANode *&  childOfNeighborNode,
EFAElement childOfNeighborElem,
std::map< unsigned int, EFANode *> &  PermanentNodes,
std::map< unsigned int, EFANode *> &  TempNodes 
)
protectedinherited

Definition at line 242 of file EFAElement.C.

Referenced by EFAElement2D::connectNeighbors(), and connectNeighbors().

247 {
248  // Important: this must be run only on child elements that were just created
249  if (!_parent)
250  EFAError("no getParent element for child element ", _id, " in mergeNodes");
251 
252  EFAElement * childElem = this;
253  if (childNode != childOfNeighborNode)
254  {
255  if (childNode->category() == EFANode::N_CATEGORY_PERMANENT)
256  {
257  if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
258  {
259  if (childOfNeighborNode->parent() == childNode) // merge into childNode
260  {
261  childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
262  if (!Efa::deleteFromMap(PermanentNodes, childOfNeighborNode))
263  {
264  EFAError("Attempted to delete node: ",
265  childOfNeighborNode->id(),
266  " from PermanentNodes, but couldn't find it");
267  }
268  childOfNeighborNode = childNode;
269  }
270  else if (childNode->parent() == childOfNeighborNode) // merge into childOfNeighborNode
271  {
272  childElem->switchNode(childOfNeighborNode, childNode, true);
273  if (!Efa::deleteFromMap(PermanentNodes, childNode))
274  {
275  EFAError("Attempted to delete node: ",
276  childNode->id(),
277  " from PermanentNodes, but couldn't find it");
278  }
279  childNode = childOfNeighborNode;
280  }
281  else if (childNode->parent() != nullptr &&
282  childNode->parent() == childOfNeighborNode->parent())
283  {
284  // merge into childNode if both nodes are child permanent
285  childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
286  if (!Efa::deleteFromMap(PermanentNodes,
287  childOfNeighborNode)) // delete childOfNeighborNode
288  {
289  EFAError("Attempted to delete node: ",
290  childOfNeighborNode->id(),
291  " from PermanentNodes, but couldn't find it");
292  }
293  childOfNeighborNode = childNode;
294  }
295  else
296  {
297  EFAError("Attempting to merge nodes: ",
298  childNode->id(),
299  " and ",
300  childOfNeighborNode->id(),
301  " but both are permanent themselves");
302  }
303  }
304  else
305  {
306  if (childOfNeighborNode->parent() != childNode &&
307  childOfNeighborNode->parent() != childNode->parent())
308  {
309  EFAError("Attempting to merge nodes ",
310  childOfNeighborNode->idCatString(),
311  " and ",
312  childNode->idCatString(),
313  " but neither the 2nd node nor its parent is parent of the 1st");
314  }
315  childOfNeighborElem->switchNode(childNode, childOfNeighborNode, true);
316  if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
317  EFAError("Attempted to delete node: ",
318  childOfNeighborNode->id(),
319  " from TempNodes, but couldn't find it");
320  childOfNeighborNode = childNode;
321  }
322  }
323  else if (childOfNeighborNode->category() == EFANode::N_CATEGORY_PERMANENT)
324  {
325  if (childNode->parent() != childOfNeighborNode &&
326  childNode->parent() != childOfNeighborNode->parent())
327  {
328  EFAError("Attempting to merge nodes ",
329  childNode->id(),
330  " and ",
331  childOfNeighborNode->id(),
332  " but neither the 2nd node nor its parent is parent of the 1st");
333  }
334  childElem->switchNode(childOfNeighborNode, childNode, true);
335  if (!Efa::deleteFromMap(TempNodes, childNode))
336  EFAError(
337  "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
338  childNode = childOfNeighborNode;
339  }
340  else // both nodes are temporary -- create new permanent node and delete temporary nodes
341  {
342  unsigned int new_node_id = Efa::getNewID(PermanentNodes);
343  EFANode * newNode =
344  new EFANode(new_node_id, EFANode::N_CATEGORY_PERMANENT, childNode->parent());
345  PermanentNodes.insert(std::make_pair(new_node_id, newNode));
346 
347  childOfNeighborElem->switchNode(newNode, childOfNeighborNode, true);
348  childElem->switchNode(newNode, childNode, true);
349 
350  if (childNode->parent() != childOfNeighborNode->parent())
351  {
352  EFAError("Attempting to merge nodes ",
353  childNode->id(),
354  " and ",
355  childOfNeighborNode->id(),
356  " but they don't share a common parent");
357  }
358 
359  if (!Efa::deleteFromMap(TempNodes, childOfNeighborNode))
360  EFAError("Attempted to delete node: ",
361  childOfNeighborNode->id(),
362  " from TempNodes, but couldn't find it");
363  if (!Efa::deleteFromMap(TempNodes, childNode))
364  EFAError(
365  "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
366  childOfNeighborNode = newNode;
367  childNode = newNode;
368  }
369  }
370 }
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
Definition: EFAFuncs.h:38
unsigned int _id
Definition: EFAElement.h:27
std::string idCatString()
Definition: EFANode.C:20
bool deleteFromMap(std::map< unsigned int, T *> &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:22
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)=0
EFAElement * _parent
Definition: EFAElement.h:31
EFANode * parent() const
Definition: EFANode.C:48
unsigned int id() const
Definition: EFANode.C:36
N_CATEGORY category() const
Definition: EFANode.C:42

◆ neighborSanityCheck()

void EFAElement3D::neighborSanityCheck ( ) const
virtual

Implements EFAElement.

Definition at line 573 of file EFAElement3D.C.

574 {
575  for (unsigned int face_iter = 0; face_iter < _num_faces; ++face_iter)
576  {
577  for (unsigned int en_iter = 0; en_iter < _face_neighbors[face_iter].size(); ++en_iter)
578  {
579  EFAElement3D * neigh_elem = _face_neighbors[face_iter][en_iter];
580  if (neigh_elem != nullptr)
581  {
582  bool found_neighbor = false;
583  for (unsigned int face_iter2 = 0; face_iter2 < neigh_elem->numFaces(); ++face_iter2)
584  {
585  for (unsigned int en_iter2 = 0; en_iter2 < neigh_elem->numFaceNeighbors(face_iter2);
586  ++en_iter2)
587  {
588  if (neigh_elem->getFaceNeighbor(face_iter2, en_iter2) == this)
589  {
590  if ((en_iter2 > 1) && (en_iter > 1))
591  EFAError(
592  "Element and neighbor element cannot both have >1 neighbors on a common face");
593  found_neighbor = true;
594  break;
595  }
596  }
597  }
598  if (!found_neighbor)
599  EFAError("Neighbor element doesn't recognize current element as neighbor");
600  }
601  }
602  }
603 }
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
unsigned int numFaces() const
unsigned int _num_faces
Definition: EFAElement3D.h:29
unsigned int numFaceNeighbors(unsigned int face_id) const

◆ numChildren()

unsigned int EFAElement::numChildren ( ) const
inherited

Definition at line 189 of file EFAElement.C.

Referenced by EFAElement2D::connectNeighbors(), connectNeighbors(), EFAElement2D::switchNode(), and switchNode().

190 {
191  return _children.size();
192 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:32

◆ numCrackTipNeighbors()

unsigned int EFAElement::numCrackTipNeighbors ( ) const
inherited

Definition at line 134 of file EFAElement.C.

135 {
136  return _crack_tip_neighbors.size();
137 }
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:34

◆ numEdgeNeighbors()

unsigned int EFAElement3D::numEdgeNeighbors ( unsigned int  face_id,
unsigned int  edge_id 
) const

Definition at line 1838 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1839 {
1840  return _face_edge_neighbors[face_id][edge_id].size();
1841 }
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:33

◆ numFaceNeighbors()

unsigned int EFAElement3D::numFaceNeighbors ( unsigned int  face_id) const

◆ numFaces()

unsigned int EFAElement3D::numFaces ( ) const

◆ numFragments()

unsigned int EFAElement3D::numFragments ( ) const
virtual

◆ numGeneralNeighbors()

unsigned int EFAElement::numGeneralNeighbors ( ) const
inherited

Definition at line 236 of file EFAElement.C.

Referenced by EFAElement2D::switchNode(), and switchNode().

237 {
238  return _general_neighbors.size();
239 }
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:36

◆ numInteriorNodes()

unsigned int EFAElement3D::numInteriorNodes ( ) const
virtual

Implements EFAElement.

Definition at line 425 of file EFAElement3D.C.

Referenced by fragmentSanityCheck(), and EFAFragment3D::isThirdInteriorFace().

426 {
427  return _interior_nodes.size();
428 }
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31

◆ numNodes()

unsigned int EFAElement::numNodes ( ) const
inherited

◆ overlaysElement()

bool EFAElement3D::overlaysElement ( const EFAElement3D other_elem) const

Definition at line 431 of file EFAElement3D.C.

Referenced by initCrackTip(), and setupNeighbors().

432 {
433  bool overlays = false;
434  const EFAElement3D * other3d = dynamic_cast<const EFAElement3D *>(other_elem);
435  if (!other3d)
436  EFAError("failed to dynamic cast to other3d");
437 
438  // Find indices of common nodes
439  const auto & common_face_curr = getCommonFaceID(other3d);
440  if (common_face_curr.size() == 1)
441  {
442  unsigned int curr_face_id = common_face_curr[0];
443  EFAFace * curr_face = _faces[curr_face_id];
444  unsigned int other_face_id = other3d->getFaceID(curr_face);
445  EFAFace * other_face = other3d->_faces[other_face_id];
446  if (curr_face->hasSameOrientation(other_face))
447  overlays = true;
448  }
449  else if (common_face_curr.size() > 1)
450  {
451  // TODO: We probably need more error checking here.
452  overlays = true;
453  }
454  return overlays;
455 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
bool hasSameOrientation(const EFAFace *other_face) const
Definition: EFAFace.C:615
unsigned int getFaceID(EFAFace *face) const
std::vector< unsigned int > getCommonFaceID(const EFAElement3D *other_elem) const

◆ printElement()

void EFAElement3D::printElement ( std::ostream &  ostream) const
virtual

Implements EFAElement.

Definition at line 1275 of file EFAElement3D.C.

1276 {
1277  // first line: all elem faces
1278  ostream << std::setw(5);
1279  ostream << _id << "| ";
1280  for (unsigned int j = 0; j < _num_faces; ++j)
1281  {
1282  for (unsigned int k = 0; k < _faces[j]->numNodes(); ++k)
1283  ostream << std::setw(5) << _faces[j]->getNode(k)->idCatString();
1284  ostream << " | ";
1285  }
1286  ostream << std::endl;
1287 
1288  // second line: emb nodes in all faces + neighbor of each face
1289  ostream << std::setw(5);
1290  ostream << "embed"
1291  << "| ";
1292  for (unsigned int j = 0; j < _num_faces; ++j)
1293  {
1294  for (unsigned int k = 0; k < _faces[j]->numEdges(); ++k)
1295  {
1296  ostream << std::setw(4);
1297  if (_faces[j]->getEdge(k)->hasIntersection())
1298  {
1299  if (_faces[j]->getEdge(k)->numEmbeddedNodes() > 1)
1300  {
1301  ostream << "[";
1302  for (unsigned int l = 0; l < _faces[j]->getEdge(k)->numEmbeddedNodes(); ++l)
1303  {
1304  ostream << _faces[j]->getEdge(k)->getEmbeddedNode(l)->id() << " ";
1305  if (l == _faces[j]->getEdge(k)->numEmbeddedNodes() - 1)
1306  ostream << "]";
1307  else
1308  ostream << " ";
1309  } // l
1310  }
1311  else
1312  ostream << _faces[j]->getEdge(k)->getEmbeddedNode(0)->id() << " ";
1313  }
1314  else
1315  ostream << " -- ";
1316  } // k
1317  ostream << " | ";
1318  } // j
1319  ostream << std::endl;
1320 
1321  // third line: neighbors
1322  ostream << std::setw(5);
1323  ostream << "neigh"
1324  << "| ";
1325  for (unsigned int j = 0; j < _num_faces; ++j)
1326  {
1327  ostream << std::setw(4);
1328  if (numFaceNeighbors(j) > 1)
1329  {
1330  ostream << "[";
1331  for (unsigned int k = 0; k < numFaceNeighbors(j); ++k)
1332  {
1333  ostream << getFaceNeighbor(j, k)->id();
1334  if (k == numFaceNeighbors(j) - 1)
1335  ostream << "]";
1336  else
1337  ostream << " ";
1338  }
1339  }
1340  else
1341  {
1342  if (numFaceNeighbors(j) == 1)
1343  ostream << getFaceNeighbor(j, 0)->id() << " ";
1344  else
1345  ostream << " -- ";
1346  }
1347  }
1348  ostream << std::endl;
1349 
1350  // fourth line: fragments
1351  for (unsigned int j = 0; j < _fragments.size(); ++j)
1352  {
1353  ostream << std::setw(4);
1354  ostream << "frag" << j << "| ";
1355  for (unsigned int k = 0; k < _fragments[j]->numFaces(); ++k)
1356  {
1357  for (unsigned int l = 0; l < _fragments[j]->getFace(k)->numNodes(); ++l)
1358  ostream << std::setw(5) << _fragments[j]->getFace(k)->getNode(l)->idCatString();
1359  ostream << " | ";
1360  }
1361  ostream << std::endl;
1362  }
1363  ostream << std::endl;
1364 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
unsigned int id() const
Definition: EFAElement.C:28
unsigned int _id
Definition: EFAElement.h:27
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130
unsigned int numFaceNeighbors(unsigned int face_id) const

◆ printNodes()

void EFAElement::printNodes ( std::ostream &  ostream) const
inherited

Definition at line 61 of file EFAElement.C.

62 {
63  ostream << "***** nodes for element " << _id << " *****" << std::endl;
64  for (unsigned int i = 0; i < _num_nodes; ++i)
65  ostream << "addr " << _nodes[i] << ", ID " << _nodes[i]->idCatString() << ", category "
66  << _nodes[i]->category() << std::endl;
67 }
unsigned int _id
Definition: EFAElement.h:27
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
unsigned int _num_nodes
Definition: EFAElement.h:28

◆ removeEmbeddedNode()

void EFAElement3D::removeEmbeddedNode ( EFANode emb_node,
bool  remove_for_neighbor 
)

Definition at line 1420 of file EFAElement3D.C.

Referenced by removeEmbeddedNode(), EFAFragment3D::removeInvalidEmbeddedNodes(), and removePhantomEmbeddedNode().

1421 {
1422  for (unsigned int i = 0; i < _fragments.size(); ++i)
1423  _fragments[i]->removeEmbeddedNode(emb_node);
1424 
1425  for (unsigned int i = 0; i < _faces.size(); ++i)
1426  _faces[i]->removeEmbeddedNode(emb_node);
1427 
1428  if (remove_for_neighbor)
1429  {
1430  for (unsigned int i = 0; i < numFaces(); ++i)
1431  for (unsigned int j = 0; j < numFaceNeighbors(i); ++j)
1432  getFaceNeighbor(i, j)->removeEmbeddedNode(emb_node, false);
1433  }
1434 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
unsigned int numFaces() const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
void removeEmbeddedNode(EFANode *emb_node, bool remove_for_neighbor)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
unsigned int numFaceNeighbors(unsigned int face_id) const

◆ removePhantomEmbeddedNode()

void EFAElement3D::removePhantomEmbeddedNode ( )
virtual

Implements EFAElement.

Definition at line 1101 of file EFAElement3D.C.

Referenced by createChild().

1102 {
1103  // remove the embedded nodes on faces that are outside the real domain
1104  if (_fragments.size() > 0)
1105  {
1106  for (unsigned int i = 0; i < _num_faces; ++i)
1107  {
1108  // get emb nodes to be removed on edges
1109  std::vector<EFANode *> nodes_to_delete;
1110  for (unsigned int j = 0; j < _faces[i]->numEdges(); ++j)
1111  {
1112  EFAEdge * edge = _faces[i]->getEdge(j);
1113  for (unsigned int k = 0; k < edge->numEmbeddedNodes(); ++k)
1114  {
1115  if (!_fragments[0]->containsNode(edge->getEmbeddedNode(k)))
1116  nodes_to_delete.push_back(edge->getEmbeddedNode(k));
1117  } // k
1118  } // j
1119 
1120  // get emb nodes to be removed in the face interior
1121  for (unsigned int j = 0; j < _faces[i]->numInteriorNodes(); ++j)
1122  {
1123  EFANode * face_node = _faces[i]->getInteriorNode(j)->getNode();
1124  if (!_fragments[0]->containsNode(face_node))
1125  nodes_to_delete.push_back(face_node);
1126  } // j
1127 
1128  // remove all invalid embedded nodes
1129  for (unsigned int j = 0; j < nodes_to_delete.size(); ++j)
1130  _faces[i]->removeEmbeddedNode(nodes_to_delete[j]);
1131  } // i
1132  }
1133 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
void removeEmbeddedNode(EFANode *emb_node, bool remove_for_neighbor)
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
static const std::string k
Definition: NS.h:130

◆ restoreFragment()

void EFAElement3D::restoreFragment ( const EFAElement *const  from_elem)
virtual

Implements EFAElement.

Definition at line 928 of file EFAElement3D.C.

929 {
930  const EFAElement3D * from_elem3d = dynamic_cast<const EFAElement3D *>(from_elem);
931  if (!from_elem3d)
932  EFAError("from_elem is not of EFAelement3D type");
933 
934  // restore fragments
935  if (_fragments.size() != 0)
936  EFAError("in restoreFragmentInfo elements must not have any pre-existing fragments");
937  for (unsigned int i = 0; i < from_elem3d->numFragments(); ++i)
938  _fragments.push_back(new EFAFragment3D(this, true, from_elem3d, i));
939 
940  // restore interior nodes
941  if (_interior_nodes.size() != 0)
942  EFAError("in restoreFragmentInfo elements must not have any pre-exsiting interior nodes");
943  for (unsigned int i = 0; i < from_elem3d->_interior_nodes.size(); ++i)
944  _interior_nodes.push_back(new EFAVolumeNode(*from_elem3d->_interior_nodes[i]));
945 
946  // restore face intersections
947  if (getNumCuts() != 0)
948  EFAError("In restoreEdgeIntersection: edge cuts already exist in element ", _id);
949  for (unsigned int i = 0; i < _num_faces; ++i)
950  _faces[i]->copyIntersection(*from_elem3d->_faces[i]);
951 
952  // replace all local nodes with global nodes
953  for (unsigned int i = 0; i < from_elem3d->numNodes(); ++i)
954  {
955  if (from_elem3d->_nodes[i]->category() == EFANode::N_CATEGORY_LOCAL_INDEX)
956  switchNode(
957  _nodes[i], from_elem3d->_nodes[i], false); // EFAelement is not a child of any parent
958  else
959  EFAError("In restoreFragmentInfo all of from_elem's nodes must be local");
960  }
961 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
unsigned int _id
Definition: EFAElement.h:27
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:272
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_faces
Definition: EFAElement3D.h:29
unsigned int numNodes() const
Definition: EFAElement.C:34
virtual unsigned int getNumCuts() const
Definition: EFAElement3D.C:815
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31

◆ setCrackTipSplit()

void EFAElement::setCrackTipSplit ( )
inherited

Definition at line 122 of file EFAElement.C.

123 {
125 }
bool _crack_tip_split_element
Definition: EFAElement.h:33

◆ setFace()

void EFAElement3D::setFace ( unsigned int  face_id,
EFAFace face 
)

Definition at line 1443 of file EFAElement3D.C.

1444 {
1445  _faces[face_id] = face;
1446 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30

◆ setLocalCoordinates()

void EFAElement3D::setLocalCoordinates ( )
private

Definition at line 141 of file EFAElement3D.C.

Referenced by EFAElement3D().

142 {
143  if (_num_faces == 6)
144  {
145  /*
146  HEX27(HEX20): 7 18 6
147  o--------------o--------------o
148  /: / /|
149  / : / / |
150  / : / / |
151  19/ : 25/ 17/ |
152  o--------------o--------------o |
153  / : / /| |
154  / 15o / 23o / | 14o
155  / : / / | /|
156  4/ : 16/ 5/ | / |
157  o--------------o--------------o | / |
158  | : | 26 | |/ |
159  | 24o : | o | 22o |
160  | : | 10 | /| |
161  | 3o....|.........o....|../.|....o
162  | . | | / | / 2
163  | . 21| 13|/ | /
164  12 o--------------o--------------o | /
165  | . | | |/
166  | 11o | 20o | o
167  | . | | / 9
168  | . | | /
169  | . | | /
170  |. | |/
171  o--------------o--------------o
172  0 8 1
173 
174  */
176  _local_node_coor[0] = EFAPoint(0.0, 0.0, 0.0);
177  _local_node_coor[1] = EFAPoint(1.0, 0.0, 0.0);
178  _local_node_coor[2] = EFAPoint(1.0, 1.0, 0.0);
179  _local_node_coor[3] = EFAPoint(0.0, 1.0, 0.0);
180  _local_node_coor[4] = EFAPoint(0.0, 0.0, 1.0);
181  _local_node_coor[5] = EFAPoint(1.0, 0.0, 1.0);
182  _local_node_coor[6] = EFAPoint(1.0, 1.0, 1.0);
183  _local_node_coor[7] = EFAPoint(0.0, 1.0, 1.0);
184 
185  if (_num_nodes > 8)
186  {
187  _local_node_coor[8] = EFAPoint(0.5, 0.0, 0.0);
188  _local_node_coor[9] = EFAPoint(1.0, 0.5, 0.0);
189  _local_node_coor[10] = EFAPoint(0.5, 1.0, 0.0);
190  _local_node_coor[11] = EFAPoint(0.0, 0.5, 0.0);
191  _local_node_coor[12] = EFAPoint(0.0, 0.0, 0.5);
192  _local_node_coor[13] = EFAPoint(1.0, 0.0, 0.5);
193  _local_node_coor[14] = EFAPoint(1.0, 1.0, 0.5);
194  _local_node_coor[15] = EFAPoint(0.0, 1.0, 0.5);
195  _local_node_coor[16] = EFAPoint(0.5, 0.0, 1.0);
196  _local_node_coor[17] = EFAPoint(1.0, 0.5, 1.0);
197  _local_node_coor[18] = EFAPoint(0.5, 1.0, 1.0);
198  _local_node_coor[19] = EFAPoint(0.0, 0.5, 1.0);
199  }
200 
201  if (_num_nodes > 20)
202  {
203  _local_node_coor[20] = EFAPoint(0.5, 0.5, 0.0);
204  _local_node_coor[21] = EFAPoint(0.5, 0.0, 0.5);
205  _local_node_coor[22] = EFAPoint(1.0, 0.5, 0.5);
206  _local_node_coor[23] = EFAPoint(0.5, 1.0, 0.5);
207  _local_node_coor[24] = EFAPoint(0.0, 0.5, 0.5);
208  _local_node_coor[25] = EFAPoint(0.5, 0.5, 1.0);
209  _local_node_coor[26] = EFAPoint(0.5, 0.5, 0.5);
210  }
211  }
212  else if (_num_faces == 4)
213  {
214  /*
215  3
216  TET10: o
217  /|\
218  / | \
219  7 / | \9
220  o | o
221  / |8 \
222  / o \
223  / 6 | \
224  0 o.....o.|.......o 2
225  \ | /
226  \ | /
227  \ | /
228  4 o | o 5
229  \ | /
230  \ | /
231  \|/
232  o
233  1
234 
235  */
236  /*
237  TET14 elements also include four face nodes:
238  Node 10, centroid on side 0, arithmetic mean of 0/1/2 or 4/5/6
239  Node 11, centroid on side 1, arithmetic mean of 0/1/3 or 4/7/8
240  Node 12, centroid on side 2, arithmetic mean of 1/2/3 or 5/8/9
241  Node 13, centroid on side 3, arithmetic mean of 0/2/3 or 6/7/9
242  */
244  _local_node_coor[0] = EFAPoint(0.0, 0.0, 0.0);
245  _local_node_coor[1] = EFAPoint(1.0, 0.0, 0.0);
246  _local_node_coor[2] = EFAPoint(0.0, 1.0, 0.0);
247  _local_node_coor[3] = EFAPoint(0.0, 0.0, 1.0);
248 
249  if (_num_nodes > 4)
250  {
251  _local_node_coor[4] = EFAPoint(0.5, 0.0, 0.0);
252  _local_node_coor[5] = EFAPoint(0.5, 0.5, 0.0);
253  _local_node_coor[6] = EFAPoint(0.0, 0.5, 0.0);
254  _local_node_coor[7] = EFAPoint(0.0, 0.0, 0.5);
255  _local_node_coor[8] = EFAPoint(0.5, 0.0, 0.5);
256  _local_node_coor[9] = EFAPoint(0.0, 0.5, 0.5);
257  }
258 
259  if (_num_nodes > 10)
260  {
261  _local_node_coor[10] = EFAPoint(1 / 3., 1 / 3., 0.0);
262  _local_node_coor[11] = EFAPoint(1 / 3., 0.0, 1 / 3.);
263  _local_node_coor[12] = EFAPoint(1 / 3., 1 / 3., 1 / 3.);
264  _local_node_coor[13] = EFAPoint(0.0, 1 / 3., 1 / 3.);
265  }
266  }
267  else
268  EFAError("EFAElement3D: number of faces should be either 4(TET) or 6(HEX).");
269 }
std::vector< EFAPoint > _local_node_coor
Definition: EFAElement3D.h:38
unsigned int _num_nodes
Definition: EFAElement.h:28
unsigned int _num_faces
Definition: EFAElement3D.h:29

◆ setNode()

void EFAElement::setNode ( unsigned int  node_id,
EFANode node 
)
inherited

◆ setParent()

void EFAElement::setParent ( EFAElement parent)
inherited

Definition at line 183 of file EFAElement.C.

Referenced by EFAElement2D::createChild(), and createChild().

184 {
185  _parent = parent;
186 }
EFAElement * _parent
Definition: EFAElement.h:31

◆ setupNeighbors()

void EFAElement3D::setupNeighbors ( std::map< EFANode *, std::set< EFAElement *>> &  InverseConnectivityMap)
virtual

Implements EFAElement.

Definition at line 507 of file EFAElement3D.C.

508 {
509  findGeneralNeighbors(inverse_connectivity_map);
510  std::vector<std::pair<unsigned int, unsigned int>> common_ids;
511  for (unsigned int eit2 = 0; eit2 < _general_neighbors.size(); ++eit2)
512  {
513  EFAElement3D * neigh_elem = dynamic_cast<EFAElement3D *>(_general_neighbors[eit2]);
514  if (!neigh_elem)
515  EFAError("neighbor_elem is not of EFAelement3D type");
516 
517  const auto & common_face_id = getCommonFaceID(neigh_elem);
518  if (common_face_id.empty() && getCommonEdgeID(neigh_elem, common_ids) &&
519  !overlaysElement(neigh_elem))
520  {
521  bool is_edge_neighbor = false;
522 
523  // Fragments must match up.
524  if ((_fragments.size() > 1) || (neigh_elem->numFragments() > 1))
525  EFAError("in updateFaceNeighbors: Cannot have more than 1 fragment");
526 
527  if ((_fragments.size() == 1) && (neigh_elem->numFragments() == 1))
528  {
529  if (_fragments[0]->isEdgeConnected(neigh_elem->getFragment(0)))
530  is_edge_neighbor = true;
531  }
532  else // If there are no fragments to match up, consider them edge neighbors
533  is_edge_neighbor = true;
534 
535  if (is_edge_neighbor)
536  for (const auto & [face_id, edge_id] : common_ids)
537  _face_edge_neighbors[face_id][edge_id].push_back(neigh_elem);
538  }
539 
540  if (common_face_id.size() == 1 && !overlaysElement(neigh_elem))
541  {
542  unsigned int face_id = common_face_id[0];
543  bool is_face_neighbor = false;
544 
545  // Fragments must match up.
546  if ((_fragments.size() > 1) || (neigh_elem->numFragments() > 1))
547  EFAError("in updateFaceNeighbors: Cannot have more than 1 fragment");
548 
549  if ((_fragments.size() == 1) && (neigh_elem->numFragments() == 1))
550  {
551  if (_fragments[0]->isConnected(neigh_elem->getFragment(0)))
552  is_face_neighbor = true;
553  }
554  else // If there are no fragments to match up, consider them neighbors
555  is_face_neighbor = true;
556 
557  if (is_face_neighbor)
558  {
559  if (_face_neighbors[face_id].size() > 1)
560  EFAError("Element ",
561  _id,
562  " already has 2 face neighbors: ",
563  _face_neighbors[face_id][0]->id(),
564  " ",
565  _face_neighbors[face_id][1]->id());
566  _face_neighbors[face_id].push_back(neigh_elem);
567  }
568  }
569  }
570 }
EFAFragment3D * getFragment(unsigned int frag_id) const
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:33
unsigned int _id
Definition: EFAElement.h:27
bool getCommonEdgeID(const EFAElement3D *other_elem, std::vector< std::pair< unsigned int, unsigned int >> &common_ids) const
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:272
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
void findGeneralNeighbors(const std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivity)
Definition: EFAElement.C:208
std::vector< unsigned int > getCommonFaceID(const EFAElement3D *other_elem) const
bool overlaysElement(const EFAElement3D *other_elem) const
Definition: EFAElement3D.C:431
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:36

◆ shouldDuplicateCrackTipSplitElement()

bool EFAElement3D::shouldDuplicateCrackTipSplitElement ( const std::set< EFAElement *> &  CrackTipElements)
virtual

Implements EFAElement.

Definition at line 668 of file EFAElement3D.C.

Referenced by shouldDuplicateForCrackTip().

669 {
670  // Determine whether element at crack tip should be duplicated. It should be duplicated
671  // if the crack will extend into the next element, or if it has a non-physical node
672  // connected to a face where a crack terminates, but will extend.
673 
674  bool should_duplicate = false;
675  if (_fragments.size() == 1)
676  {
677  std::vector<unsigned int> split_neighbors;
678  if (willCrackTipExtend(split_neighbors))
679  should_duplicate = true;
680  else
681  {
682  // The element may not be at the crack tip, but could have a non-physical node
683  // connected to a crack tip face (on a neighbor element) that will be split. We need to
684  // duplicate in that case as well.
685  std::set<EFANode *> non_physical_nodes;
686  getNonPhysicalNodes(non_physical_nodes);
687 
688  for (unsigned int eit = 0; eit < _general_neighbors.size(); ++eit)
689  {
690  EFAElement3D * neigh_elem = dynamic_cast<EFAElement3D *>(_general_neighbors[eit]);
691  if (!neigh_elem)
692  EFAError("general elem is not of type EFAelement3D");
693 
694  // check if a general neighbor is an old crack tip element and will be split
695  std::set<EFAElement *>::iterator sit;
696  sit = CrackTipElements.find(neigh_elem);
697  if (sit != CrackTipElements.end() && neigh_elem->numFragments() > 1)
698  {
699  for (unsigned int i = 0; i < neigh_elem->numFaces(); ++i)
700  {
701  std::set<EFANode *> neigh_face_nodes = neigh_elem->getFaceNodes(i);
702  if (neigh_elem->numFaceNeighbors(i) == 2 &&
703  Efa::numCommonElems(neigh_face_nodes, non_physical_nodes) > 0)
704  {
705  should_duplicate = true;
706  break;
707  }
708  } // i
709  }
710  if (should_duplicate)
711  break;
712  } // eit
713  }
714  } // IF only one fragment
715  return should_duplicate;
716 }
virtual void getNonPhysicalNodes(std::set< EFANode *> &non_physical_nodes) const
Definition: EFAElement3D.C:302
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:272
unsigned int numFaces() const
virtual bool willCrackTipExtend(std::vector< unsigned int > &split_neighbors) const
Definition: EFAElement3D.C:758
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:49
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:36
unsigned int numFaceNeighbors(unsigned int face_id) const
std::set< EFANode * > getFaceNodes(unsigned int face_id) const

◆ shouldDuplicateForCrackTip()

bool EFAElement3D::shouldDuplicateForCrackTip ( const std::set< EFAElement *> &  CrackTipElements)
virtual

Implements EFAElement.

Definition at line 644 of file EFAElement3D.C.

Referenced by createChild().

645 {
646  // This method is called in createChildElements()
647  // Only duplicate when
648  // 1) currElem will be a NEW crack tip element
649  // 2) currElem is a crack tip split element at last time step and the tip will extend
650  // 3) currElem is the neighbor of a to-be-second-split element which has another neighbor
651  // sharing a phantom node with currElem
652  bool should_duplicate = false;
653  if (_fragments.size() == 1)
654  {
655  std::set<EFAElement *>::iterator sit;
656  sit = CrackTipElements.find(this);
657  if (sit == CrackTipElements.end() && isCrackTipElement())
658  should_duplicate = true;
659  else if (shouldDuplicateCrackTipSplitElement(CrackTipElements))
660  should_duplicate = true;
662  should_duplicate = true;
663  }
664  return should_duplicate;
665 }
virtual bool shouldDuplicateForPhantomCorner()
Definition: EFAElement3D.C:719
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
virtual bool shouldDuplicateCrackTipSplitElement(const std::set< EFAElement *> &CrackTipElements)
Definition: EFAElement3D.C:668
virtual bool isCrackTipElement() const
Definition: EFAElement3D.C:809

◆ shouldDuplicateForPhantomCorner()

bool EFAElement3D::shouldDuplicateForPhantomCorner ( )
virtual

Implements EFAElement.

Definition at line 719 of file EFAElement3D.C.

Referenced by shouldDuplicateForCrackTip().

720 {
721  // if a partial element will be split for a second time and it has two neighbor elements
722  // sharing one phantom node with the aforementioned partial element, then the two neighbor
723  // elements should be duplicated
724  bool should_duplicate = false;
725  if (_fragments.size() == 1 && (!_crack_tip_split_element))
726  {
727  for (unsigned int i = 0; i < _num_faces; ++i)
728  {
729  std::set<EFANode *> phantom_nodes = getPhantomNodeOnFace(i);
730  if (phantom_nodes.size() > 0 && numFaceNeighbors(i) == 1)
731  {
732  EFAElement3D * neighbor_elem = _face_neighbors[i][0];
733  if (neighbor_elem->numFragments() > 1) // neighbor will be split
734  {
735  for (unsigned int j = 0; j < neighbor_elem->numFaces(); ++j)
736  {
737  if (!neighbor_elem->getFace(j)->equivalent(_faces[i]) &&
738  neighbor_elem->numFaceNeighbors(j) > 0)
739  {
740  std::set<EFANode *> neigh_phantom_nodes = neighbor_elem->getPhantomNodeOnFace(j);
741  if (Efa::numCommonElems(phantom_nodes, neigh_phantom_nodes) > 0)
742  {
743  should_duplicate = true;
744  break;
745  }
746  }
747  } // j
748  }
749  }
750  if (should_duplicate)
751  break;
752  } // i
753  }
754  return should_duplicate;
755 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
EFAFace * getFace(unsigned int face_id) const
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:272
bool equivalent(const EFAFace *other_face) const
Definition: EFAFace.C:355
unsigned int numFaces() const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:49
unsigned int _num_faces
Definition: EFAElement3D.h:29
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
bool _crack_tip_split_element
Definition: EFAElement.h:33
unsigned int numFaceNeighbors(unsigned int face_id) const
std::set< EFANode * > getPhantomNodeOnFace(unsigned int face_id) const

◆ switchEmbeddedNode()

void EFAElement3D::switchEmbeddedNode ( EFANode new_node,
EFANode old_node 
)
virtual

Implements EFAElement.

Definition at line 356 of file EFAElement3D.C.

357 {
358  for (unsigned int i = 0; i < _num_faces; ++i)
359  _faces[i]->switchNode(new_emb_node, old_emb_node);
360  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
361  _interior_nodes[i]->switchNode(new_emb_node, old_emb_node);
362  for (unsigned int i = 0; i < _fragments.size(); ++i)
363  _fragments[i]->switchNode(new_emb_node, old_emb_node);
364 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_faces
Definition: EFAElement3D.h:29
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:31

◆ switchNode()

void EFAElement3D::switchNode ( EFANode new_node,
EFANode old_node,
bool  descend_to_parent 
)
virtual

Implements EFAElement.

Definition at line 329 of file EFAElement3D.C.

Referenced by connectNeighbors(), EFAElement3D(), restoreFragment(), and switchEmbeddedNode().

330 {
331  // We are not switching any embedded nodes here; This is an enhanced version
332  for (unsigned int i = 0; i < _num_nodes; ++i)
333  {
334  if (_nodes[i] == old_node)
335  _nodes[i] = new_node;
336  }
337  for (unsigned int i = 0; i < _fragments.size(); ++i)
338  _fragments[i]->switchNode(new_node, old_node);
339 
340  for (unsigned int i = 0; i < _faces.size(); ++i)
341  _faces[i]->switchNode(new_node, old_node);
342 
343  if (_parent && descend_to_parent)
344  {
345  _parent->switchNode(new_node, old_node, false);
346  for (unsigned int i = 0; i < _parent->numGeneralNeighbors(); ++i)
347  {
348  EFAElement * neigh_elem = _parent->getGeneralNeighbor(i); // generalized neighbor element
349  for (unsigned int k = 0; k < neigh_elem->numChildren(); ++k)
350  neigh_elem->getChild(k)->switchNode(new_node, old_node, false);
351  }
352  }
353 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
unsigned int numChildren() const
Definition: EFAElement.C:189
unsigned int numGeneralNeighbors() const
Definition: EFAElement.C:236
EFAElement * getChild(unsigned int child_id) const
Definition: EFAElement.C:174
std::vector< EFANode * > _nodes
Definition: EFAElement.h:29
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
unsigned int _num_nodes
Definition: EFAElement.h:28
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)=0
EFAElement * _parent
Definition: EFAElement.h:31
EFAElement * getGeneralNeighbor(unsigned int index) const
Definition: EFAElement.C:230
static const std::string k
Definition: NS.h:130

◆ updateFragmentNode()

void EFAElement3D::updateFragmentNode ( )
virtual

Implements EFAElement.

Definition at line 367 of file EFAElement3D.C.

368 {
369  // In EFAElement3D, updateFragmentNode needs to be implemented
370 }

◆ updateFragments()

void EFAElement3D::updateFragments ( const std::set< EFAElement *> &  CrackTipElements,
std::map< unsigned int, EFANode *> &  EmbeddedNodes 
)
virtual

Implements EFAElement.

Definition at line 845 of file EFAElement3D.C.

847 {
848  // combine the crack-tip faces in a fragment to a single intersected face
849  std::set<EFAElement *>::iterator sit;
850  sit = CrackTipElements.find(this);
851  if (sit != CrackTipElements.end()) // curr_elem is a crack tip element
852  {
853  if (_fragments.size() == 1)
854  _fragments[0]->combine_tip_faces();
855  else
856  EFAError("crack tip elem ", _id, " must have 1 fragment");
857  }
858 
859  // remove the inappropriate embedded nodes on interior faces
860  // (MUST DO THIS AFTER combine_tip_faces())
861  if (_fragments.size() == 1)
862  _fragments[0]->removeInvalidEmbeddedNodes(EmbeddedNodes);
863 
864  // for an element with no fragment, create one fragment identical to the element
865  if (_fragments.size() == 0)
866  _fragments.push_back(new EFAFragment3D(this, true, this));
867  if (_fragments.size() != 1)
868  EFAError("Element ", _id, " must have 1 fragment at this point");
869 
870  // count fragment's cut faces
871  unsigned int num_cut_frag_faces = _fragments[0]->getNumCuts();
872  unsigned int num_frag_faces = _fragments[0]->numFaces();
873  if (num_cut_frag_faces > _fragments[0]->numFaces())
874  EFAError("In element ", _id, " there are too many cut fragment faces");
875 
876  // leave the uncut frag as it is
877  if (num_cut_frag_faces == 0)
878  {
879  if (!isPartial()) // delete the temp frag for an uncut elem
880  {
881  delete _fragments[0];
882  _fragments.clear();
883  }
884  return;
885  }
886 
887  // split one fragment into one or two new fragments
888  std::vector<EFAFragment3D *> new_frags = _fragments[0]->split();
889  if (new_frags.size() == 1 || new_frags.size() == 2)
890  {
891  delete _fragments[0]; // delete the old fragment
892  _fragments.clear();
893  for (unsigned int i = 0; i < new_frags.size(); ++i)
894  _fragments.push_back(new_frags[i]);
895  }
896  else
897  EFAError("Number of fragments must be 1 or 2 at this point");
898 
899  fragmentSanityCheck(num_frag_faces, num_cut_frag_faces);
900 }
unsigned int _id
Definition: EFAElement.h:27
unsigned int numFaces() const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
virtual bool isPartial() const
Definition: EFAElement3D.C:278
virtual void fragmentSanityCheck(unsigned int n_old_frag_faces, unsigned int n_old_frag_cuts) const
Definition: EFAElement3D.C:903

◆ willCrackTipExtend()

bool EFAElement3D::willCrackTipExtend ( std::vector< unsigned int > &  split_neighbors) const
virtual

Implements EFAElement.

Definition at line 758 of file EFAElement3D.C.

Referenced by shouldDuplicateCrackTipSplitElement().

759 {
760  // Determine whether the current element is a crack tip element for which the crack will
761  // extend into the next element.
762  // N.B. this is called at the beginning of createChildElements
763  bool will_extend = false;
764  if (_fragments.size() == 1 && _crack_tip_split_element)
765  {
766  for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
767  {
768  unsigned int neigh_idx = _crack_tip_neighbors[i]; // essentially a face_id
769  if (numFaceNeighbors(neigh_idx) != 1)
770  EFAError("in will_crack_tip_extend() element ",
771  _id,
772  " has ",
773  _face_neighbors[neigh_idx].size(),
774  " neighbors on face ",
775  neigh_idx);
776 
777  EFAElement3D * neighbor_elem = _face_neighbors[neigh_idx][0];
778  if (neighbor_elem->numFragments() > 2)
779  {
780  EFAError("in will_crack_tip_extend() element ",
781  neighbor_elem->id(),
782  " has ",
783  neighbor_elem->numFragments(),
784  " fragments");
785  }
786  else if (neighbor_elem->numFragments() == 2)
787  {
788  EFAFragment3D * neigh_frag1 = neighbor_elem->getFragment(0);
789  EFAFragment3D * neigh_frag2 = neighbor_elem->getFragment(1);
790  std::vector<EFANode *> neigh_cut_nodes = neigh_frag1->getCommonNodes(neigh_frag2);
791  unsigned int counter = 0; // counter how many common nodes are contained by current face
792  for (unsigned int j = 0; j < neigh_cut_nodes.size(); ++j)
793  {
794  if (_faces[neigh_idx]->containsNode(neigh_cut_nodes[j]))
795  counter += 1;
796  }
797  if (counter == 2)
798  {
799  split_neighbors.push_back(neigh_idx);
800  will_extend = true;
801  }
802  }
803  } // i
804  }
805  return will_extend;
806 }
EFAFragment3D * getFragment(unsigned int frag_id) const
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:30
unsigned int id() const
Definition: EFAElement.C:28
unsigned int _id
Definition: EFAElement.h:27
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:32
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:272
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFANode * > getCommonNodes(EFAFragment *other) const
Definition: EFAFragment.C:20
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:34
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
bool _crack_tip_split_element
Definition: EFAElement.h:33
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:34
unsigned int numFaceNeighbors(unsigned int face_id) const

Member Data Documentation

◆ _children

std::vector<EFAElement *> EFAElement::_children
protectedinherited

◆ _crack_tip_neighbors

std::vector<unsigned int> EFAElement::_crack_tip_neighbors
protectedinherited

◆ _crack_tip_split_element

bool EFAElement::_crack_tip_split_element
protectedinherited

◆ _face_edge_neighbors

std::vector<std::vector<std::vector<EFAElement3D *> > > EFAElement3D::_face_edge_neighbors
private

◆ _face_neighbors

std::vector<std::vector<EFAElement3D *> > EFAElement3D::_face_neighbors
private

◆ _faces

std::vector<EFAFace *> EFAElement3D::_faces
private

◆ _faces_adjacent_to_faces

std::vector<std::vector<EFAFace *> > EFAElement3D::_faces_adjacent_to_faces
private

Definition at line 35 of file EFAElement3D.h.

Referenced by findFacesAdjacentToFaces(), and getAdjacentFace().

◆ _fragments

std::vector<EFAFragment3D *> EFAElement3D::_fragments
private

◆ _general_neighbors

std::vector<EFAElement *> EFAElement::_general_neighbors
protectedinherited

◆ _id

unsigned int EFAElement::_id
protectedinherited

◆ _interior_nodes

std::vector<EFAVolumeNode *> EFAElement3D::_interior_nodes
private

◆ _local_node_coor

std::vector<EFAPoint> EFAElement3D::_local_node_coor
private

Definition at line 38 of file EFAElement3D.h.

Referenced by createChild(), EFAElement3D(), and setLocalCoordinates().

◆ _local_nodes

std::vector<EFANode *> EFAElement::_local_nodes
protectedinherited

Definition at line 30 of file EFAElement.h.

Referenced by EFAElement3D(), EFAElement2D::~EFAElement2D(), and ~EFAElement3D().

◆ _nodes

std::vector<EFANode *> EFAElement::_nodes
protectedinherited

◆ _num_faces

unsigned int EFAElement3D::_num_faces
private

◆ _num_interior_face_nodes

unsigned int EFAElement3D::_num_interior_face_nodes
private

◆ _num_nodes

unsigned int EFAElement::_num_nodes
protectedinherited

◆ _num_vertices

unsigned int EFAElement3D::_num_vertices
private

Definition at line 36 of file EFAElement3D.h.

Referenced by EFAElement3D(), getCommonNodes(), and isPartial().

◆ _parent

EFAElement* EFAElement::_parent
protectedinherited

The documentation for this class was generated from the following files: