www.mooseframework.org
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)
 
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 int > getCommonFaceID (const EFAElement3D *other_elem) const
 
bool getCommonEdgeID (const EFAElement3D *other_elem, std::vector< unsigned int > &face_id, std::vector< unsigned int > &edge_id) 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 int > getTipFaceIDs () 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
 
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 (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 21 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 24 of file EFAElement3D.C.

Referenced by createChild().

25  : EFAElement(eid, n_nodes),
26  _num_faces(n_faces),
27  _faces(_num_faces, NULL),
30 {
31  if (_num_faces == 4)
32  {
33  _num_vertices = 4;
34  if (_num_nodes == 10)
36  else if (_num_nodes == 4)
38  else
39  EFAError("In EFAelement3D the supported TET element types are TET4 and TET10");
40  }
41  else if (_num_faces == 6)
42  {
43  _num_vertices = 8;
44  if (_num_nodes == 27)
46  else if (_num_nodes == 20)
48  else if (_num_nodes == 8)
50  else
51  EFAError("In EFAelement3D the supported HEX element types are HEX8, HEX20 and HEX27");
52  }
53  else
54  EFAError("In EFAelement3D the supported element types are TET4, TET10, HEX8, HEX20 and HEX27");
56 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:34
unsigned int _num_interior_face_nodes
Definition: EFAElement3D.h:38
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement.C:16
unsigned int _num_nodes
Definition: EFAElement.h:29
unsigned int _num_vertices
Definition: EFAElement3D.h:37
unsigned int _num_faces
Definition: EFAElement3D.h:30
void setLocalCoordinates()
Definition: EFAElement3D.C:153

◆ EFAElement3D() [2/2]

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

Definition at line 58 of file EFAElement3D.C.

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

◆ ~EFAElement3D()

EFAElement3D::~EFAElement3D ( )

Definition at line 116 of file EFAElement3D.C.

117 {
118  for (unsigned int i = 0; i < _fragments.size(); ++i)
119  {
120  if (_fragments[i])
121  {
122  delete _fragments[i];
123  _fragments[i] = NULL;
124  }
125  }
126  for (unsigned int i = 0; i < _faces.size(); ++i)
127  {
128  if (_faces[i])
129  {
130  delete _faces[i];
131  _faces[i] = NULL;
132  }
133  }
134  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
135  {
136  if (_interior_nodes[i])
137  {
138  delete _interior_nodes[i];
139  _interior_nodes[i] = NULL;
140  }
141  }
142  for (unsigned int i = 0; i < _local_nodes.size(); ++i)
143  {
144  if (_local_nodes[i])
145  {
146  delete _local_nodes[i];
147  _local_nodes[i] = NULL;
148  }
149  }
150 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:32
std::vector< EFANode * > _local_nodes
Definition: EFAElement.h:31

Member Function Documentation

◆ addChild()

void EFAElement::addChild ( EFAElement child)
inherited

Definition at line 203 of file EFAElement.C.

204 {
205  _children.push_back(child);
206 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:33

◆ addCrackTipNeighbor()

void EFAElement::addCrackTipNeighbor ( EFAElement neighbor_elem)
inherited

Definition at line 157 of file EFAElement.C.

158 {
159  // Find out what side the specified element is on, and add it as a crack tip neighbor
160  // element for that side.
161  unsigned int neighbor_index = getNeighborIndex(neighbor_elem);
162  bool crack_tip_neighbor_exist = false;
163  for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
164  {
165  if (_crack_tip_neighbors[i] == neighbor_index)
166  {
167  crack_tip_neighbor_exist = true;
168  break;
169  }
170  }
171  if (!crack_tip_neighbor_exist)
172  _crack_tip_neighbors.push_back(neighbor_index);
173 }
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const =0
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:35

◆ 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 1994 of file EFAElement3D.C.

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

2001 {
2002  // Purpose: add intersection on Edge edge_id of Face face_id
2003  EFANode * local_embedded = NULL;
2004  EFAEdge * cut_edge = _faces[face_id]->getEdge(edge_id);
2005  EFANode * edge_node1 = cut_edge->getNode(0);
2006  if (embedded_node) // use the existing embedded node if it was passed in
2007  local_embedded = embedded_node;
2008 
2009  // get adjacent face info
2010  EFAFace * adj_face = getAdjacentFace(face_id, edge_id);
2011  unsigned int adj_face_id = getFaceID(adj_face);
2012  unsigned int adj_edge_id = adj_face->adjacentCommonEdge(_faces[face_id]);
2013 
2014  // check if cut has already been added to this face edge
2015  bool cut_exist = false;
2016 
2017  if (cut_edge->hasIntersectionAtPosition(position, edge_node1))
2018  {
2019  unsigned int emb_id = cut_edge->getEmbeddedNodeIndex(position, edge_node1);
2020  EFANode * old_emb = cut_edge->getEmbeddedNode(emb_id);
2021  if (embedded_node && embedded_node != old_emb)
2022  EFAError("Attempting to add edge intersection when one already exists with different node.",
2023  " elem: ",
2024  _id,
2025  " edge: ",
2026  edge_id,
2027  " position: ",
2028  position);
2029  local_embedded = old_emb;
2030  cut_exist = true;
2031  }
2032 
2033  if (!cut_exist && !fragmentFaceAlreadyCut(face_id) &&
2034  isPhysicalEdgeCut(face_id, edge_id, position))
2035  {
2036  // check if cut has already been added to the neighbor edges
2037  checkNeighborFaceCut(face_id, edge_id, position, edge_node1, embedded_node, local_embedded);
2039  adj_face_id, adj_edge_id, position, edge_node1, embedded_node, local_embedded);
2040 
2041  if (!local_embedded) // need to create new embedded node
2042  {
2043  unsigned int new_node_id = Efa::getNewID(EmbeddedNodes);
2044  local_embedded = new EFANode(new_node_id, EFANode::N_CATEGORY_EMBEDDED);
2045  EmbeddedNodes.insert(std::make_pair(new_node_id, local_embedded));
2046  }
2047 
2048  // add to elem face edge
2049  cut_edge->addIntersection(position, local_embedded, edge_node1);
2050  if (cut_edge->numEmbeddedNodes() > 2)
2051  EFAError("element edge can't have >2 embedded nodes");
2052 
2053  // add to adjacent face edge
2054  if (add_to_adjacent)
2055  {
2056  double adj_pos = 1.0 - position;
2058  adj_face_id, adj_edge_id, adj_pos, local_embedded, EmbeddedNodes, false, false);
2059  }
2060  }
2061 
2062  // add cut to neighbor face edge
2063  if (add_to_neighbor)
2064  {
2065  for (unsigned int en_iter = 0; en_iter < numFaceNeighbors(face_id); ++en_iter)
2066  {
2067  EFAElement3D * face_neighbor = getFaceNeighbor(face_id, en_iter);
2068  unsigned int neigh_face_id = face_neighbor->getNeighborIndex(this);
2069  unsigned neigh_edge_id = getNeighborFaceEdgeID(face_id, edge_id, face_neighbor);
2070  double neigh_pos = 1.0 - position; // get emb node's postion on neighbor edge
2071  face_neighbor->addFaceEdgeCut(
2072  neigh_face_id, neigh_edge_id, neigh_pos, local_embedded, EmbeddedNodes, false, true);
2073  }
2074 
2075  for (unsigned int en_iter = 0; en_iter < numEdgeNeighbors(face_id, edge_id); ++en_iter)
2076  {
2077  EFAElement3D * edge_neighbor = getEdgeNeighbor(face_id, edge_id, en_iter);
2078  unsigned int neigh_face_id, neigh_edge_id;
2079  getNeighborEdgeIndex(edge_neighbor, face_id, edge_id, neigh_face_id, neigh_edge_id);
2080 
2081  // Check the ordering of the node and the assign the position
2082  double neigh_pos;
2083  if (_faces[face_id]->getEdge(edge_id)->getNode(0) ==
2084  edge_neighbor->getFace(neigh_face_id)->getEdge(neigh_edge_id)->getNode(0))
2085  neigh_pos = position;
2086  else if (_faces[face_id]->getEdge(edge_id)->getNode(1) ==
2087  edge_neighbor->getFace(neigh_face_id)->getEdge(neigh_edge_id)->getNode(0))
2088  neigh_pos = 1.0 - position;
2089  else
2090  EFAError("The EFANodes on commaon edge are not matched.");
2091 
2092  edge_neighbor->addFaceEdgeCut(
2093  neigh_face_id, neigh_edge_id, neigh_pos, local_embedded, EmbeddedNodes, false, true);
2094  }
2095  } // If add_to_neighbor required
2096 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
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:330
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
Definition: EFAFuncs.h:39
unsigned int _id
Definition: EFAElement.h:28
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
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
unsigned int getEmbeddedNodeIndex(EFANode *node) const
Definition: EFAEdge.C:281
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:260
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:469
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:211
bool isPhysicalEdgeCut(unsigned int ElemFaceID, unsigned int ElemFaceEdgeID, double position) const
unsigned int numEmbeddedNodes() const
Definition: EFAEdge.C:339
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition: EFAEdge.C:130
unsigned int adjacentCommonEdge(const EFAFace *other_face) const
Definition: EFAFace.C:644
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:179
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 2099 of file EFAElement3D.C.

2105 {
2106  // TODO: mark frag face edges
2107  // also need to check if cut has been added to this frag face edge or neighbor edge of adjacent
2108  // face
2109 }

◆ 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 2112 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

2118 {
2119  // N.B. this is important. We are checking if the corresponding edge of the neighbor face or of
2120  // the adjacent
2121  // face's neighbor face has a cut at the same position. If so, use the existing embedded node as
2122  // local_embedded
2123  for (unsigned int en_iter = 0; en_iter < numFaceNeighbors(face_id); ++en_iter)
2124  {
2125  EFAElement3D * face_neighbor = getFaceNeighbor(face_id, en_iter);
2126  unsigned int neigh_face_id = face_neighbor->getNeighborIndex(this);
2127  unsigned neigh_edge_id = getNeighborFaceEdgeID(face_id, edge_id, face_neighbor);
2128  EFAEdge * neigh_edge = face_neighbor->getFace(neigh_face_id)->getEdge(neigh_edge_id);
2129 
2130  if (neigh_edge->hasIntersectionAtPosition(position, from_node))
2131  {
2132  unsigned int emb_id = neigh_edge->getEmbeddedNodeIndex(position, from_node);
2133  EFANode * old_emb = neigh_edge->getEmbeddedNode(emb_id);
2134 
2135  if (embedded_node && embedded_node != old_emb)
2136  EFAError(
2137  "attempting to add edge intersection when one already exists with different node.");
2138  if (local_embedded && local_embedded != old_emb)
2139  EFAError("attempting to assign contradictory pointer to local_embedded.");
2140 
2141  local_embedded = old_emb;
2142  }
2143  } // en_iter
2144 }
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:330
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:281
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:260
bool hasIntersectionAtPosition(double position, EFANode *from_node) const
Definition: EFAEdge.C:211
unsigned int numFaceNeighbors(unsigned int face_id) const

◆ clearNeighbors()

void EFAElement3D::clearNeighbors ( )
virtual

Implements EFAElement.

Definition at line 496 of file EFAElement3D.C.

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

◆ clearParentAndChildren()

void EFAElement::clearParentAndChildren ( )
inherited

Definition at line 209 of file EFAElement.C.

Referenced by ElementFragmentAlgorithm::clearAncestry().

210 {
211  _parent = NULL;
212  _children.clear();
213 }
EFAElement * _parent
Definition: EFAElement.h:32
std::vector< EFAElement * > _children
Definition: EFAElement.h:33

◆ 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 1141 of file EFAElement3D.C.

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

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

◆ createFaces()

void EFAElement3D::createFaces ( )

Definition at line 1454 of file EFAElement3D.C.

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

1455 {
1456  // create element faces based on existing element nodes
1457  int hex_local_node_indices[6][4] = {
1458  {0, 3, 2, 1}, {0, 1, 5, 4}, {1, 2, 6, 5}, {2, 3, 7, 6}, {3, 0, 4, 7}, {4, 5, 6, 7}};
1459  int tet_local_node_indices[4][3] = {{0, 2, 1}, {0, 1, 3}, {1, 2, 3}, {2, 0, 3}};
1460 
1461  int hex_interior_face_node_indices[6][5] = {{8, 9, 10, 11, 20},
1462  {8, 13, 16, 12, 21},
1463  {9, 14, 17, 13, 22},
1464  {10, 14, 18, 15, 23},
1465  {11, 15, 19, 12, 24},
1466  {16, 17, 18, 19, 25}};
1467  int tet_interior_face_node_indices[4][3] = {{4, 5, 6}, {4, 7, 8}, {5, 8, 9}, {6, 7, 9}};
1468 
1469  _faces = std::vector<EFAFace *>(_num_faces, NULL);
1470  if (_num_nodes == 8 || _num_nodes == 20 || _num_nodes == 27)
1471  {
1472  if (_num_faces != 6)
1473  EFAError("num_faces of hexes must be 6");
1474  for (unsigned int i = 0; i < _num_faces; ++i)
1475  {
1477  for (unsigned int j = 0; j < 4; ++j)
1478  _faces[i]->setNode(j, _nodes[hex_local_node_indices[i][j]]);
1479  _faces[i]->createEdges();
1480  for (unsigned int k = 0; k < _num_interior_face_nodes; ++k)
1481  _faces[i]->setInteriorFaceNode(k, _nodes[hex_interior_face_node_indices[i][k]]);
1482  }
1483  }
1484  else if (_num_nodes == 4 || _num_nodes == 10)
1485  {
1486  if (_num_faces != 4)
1487  EFAError("num_faces of tets must be 4");
1488  for (unsigned int i = 0; i < _num_faces; ++i)
1489  {
1491  for (unsigned int j = 0; j < 3; ++j)
1492  _faces[i]->setNode(j, _nodes[tet_local_node_indices[i][j]]);
1493  _faces[i]->createEdges();
1494  for (unsigned int k = 0; k < _num_interior_face_nodes; ++k)
1495  _faces[i]->setInteriorFaceNode(k, _nodes[tet_interior_face_node_indices[i][k]]);
1496  }
1497  }
1498  else
1499  EFAError("unknown 3D element type in createFaces()");
1500 
1501  for (unsigned int face_iter = 0; face_iter < _num_faces; ++face_iter)
1502  {
1503  _face_edge_neighbors[face_iter].resize(_faces[face_iter]->numEdges());
1504  for (unsigned int edge_iter = 0; edge_iter < _faces[face_iter]->numEdges(); ++edge_iter)
1505  _face_edge_neighbors[face_iter][edge_iter].clear();
1506  }
1507 
1508  // create element face connectivity array
1509  findFacesAdjacentToFaces(); // IMPORTANT
1510 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:34
unsigned int _num_interior_face_nodes
Definition: EFAElement3D.h:38
void findFacesAdjacentToFaces()
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
unsigned int _num_nodes
Definition: EFAElement.h:29
unsigned int _num_faces
Definition: EFAElement3D.h:30
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(), EFAElement2D::EFAElement2D(), 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 = NULL;
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:30
N_CATEGORY category() const
Definition: EFANode.C:42

◆ faceContainsTip()

bool EFAElement3D::faceContainsTip ( unsigned int  face_id) const

Definition at line 1953 of file EFAElement3D.C.

Referenced by fragmentFaceAlreadyCut().

1954 {
1955  bool contain_tip = false;
1956  if (_fragments.size() == 1)
1957  {
1958  unsigned int num_frag_faces = 0; // count how many fragment faces this element face contains
1959  if (_faces[face_id]->hasIntersection())
1960  {
1961  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1962  {
1963  if (_faces[face_id]->containsFace(_fragments[0]->getFace(j)))
1964  num_frag_faces += 1;
1965  } // j
1966  if (num_frag_faces == 2)
1967  contain_tip = true;
1968  }
1969  }
1970  return contain_tip;
1971 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35

◆ findFacesAdjacentToFaces()

void EFAElement3D::findFacesAdjacentToFaces ( )

Definition at line 1681 of file EFAElement3D.C.

Referenced by createFaces(), and EFAElement3D().

1682 {
1683  _faces_adjacent_to_faces.clear();
1684  for (unsigned int i = 0; i < _faces.size(); ++i)
1685  {
1686  std::vector<EFAFace *> face_adjacents(_faces[i]->numEdges(), NULL);
1687  for (unsigned int j = 0; j < _faces.size(); ++j)
1688  {
1689  if (_faces[j] != _faces[i] && _faces[i]->isAdjacent(_faces[j]))
1690  {
1691  unsigned int adj_edge = _faces[i]->adjacentCommonEdge(_faces[j]);
1692  face_adjacents[adj_edge] = _faces[j];
1693  }
1694  }
1695  _faces_adjacent_to_faces.push_back(face_adjacents);
1696  }
1697 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
std::vector< std::vector< EFAFace * > > _faces_adjacent_to_faces
Definition: EFAElement3D.h:36

◆ findGeneralNeighbors()

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

Definition at line 216 of file EFAElement.C.

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

217 {
218  _general_neighbors.clear();
219  std::set<EFAElement *> patch_elements;
220  for (unsigned int inode = 0; inode < _num_nodes; ++inode)
221  {
222  std::set<EFAElement *> this_node_connected_elems = InverseConnectivity[_nodes[inode]];
223  patch_elements.insert(this_node_connected_elems.begin(), this_node_connected_elems.end());
224  }
225 
226  std::set<EFAElement *>::iterator eit2;
227  for (eit2 = patch_elements.begin(); eit2 != patch_elements.end(); ++eit2)
228  {
229  EFAElement * neigh_elem = *eit2;
230  if (neigh_elem != this)
231  _general_neighbors.push_back(neigh_elem);
232  }
233 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
unsigned int _num_nodes
Definition: EFAElement.h:29
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:37

◆ fragmentFaceAlreadyCut()

bool EFAElement3D::fragmentFaceAlreadyCut ( unsigned int  ElemFaceID) const

Definition at line 1974 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1975 {
1976  // when marking cuts, check if the corresponding frag face already has been cut
1977  bool has_cut = false;
1978  if (faceContainsTip(ElemFaceID))
1979  has_cut = true;
1980  else
1981  {
1982  unsigned int FragFaceID = 99999;
1983  if (getFragmentFaceID(ElemFaceID, FragFaceID))
1984  {
1985  EFAFace * frag_face = getFragmentFace(0, FragFaceID);
1986  if (frag_face->hasIntersection())
1987  has_cut = true;
1988  }
1989  }
1990  return has_cut;
1991 }
bool hasIntersection() const
Definition: EFAFace.C:609
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 1872 of file EFAElement3D.C.

Referenced by fragmentSanityCheck(), and isCrackTipElement().

1873 {
1874  bool has_tip_faces = false;
1875  if (_fragments.size() == 1)
1876  {
1877  for (unsigned int i = 0; i < _num_faces; ++i)
1878  {
1879  unsigned int num_frag_faces = 0; // count how many fragment edges this element edge contains
1880  if (_faces[i]->hasIntersection())
1881  {
1882  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1883  {
1884  if (_faces[i]->containsFace(_fragments[0]->getFace(j)))
1885  num_frag_faces += 1;
1886  } // j
1887  if (num_frag_faces == 2)
1888  {
1889  has_tip_faces = true;
1890  break;
1891  }
1892  }
1893  } // i
1894  }
1895  return has_tip_faces;
1896 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int _num_faces
Definition: EFAElement3D.h:30

◆ fragmentSanityCheck()

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

Implements EFAElement.

Definition at line 916 of file EFAElement3D.C.

Referenced by updateFragments().

917 {
918  unsigned int n_interior_nodes = numInteriorNodes();
919  if (n_interior_nodes > 0 && n_interior_nodes != 1)
920  EFAError("After update_fragments this element has ", n_interior_nodes, " interior nodes");
921 
922  if (n_old_frag_cuts == 0)
923  {
924  if (_fragments.size() != 1 || _fragments[0]->numFaces() != n_old_frag_faces)
925  EFAError("Incorrect link size for element with 0 cuts");
926  }
927  else if (fragmentHasTipFaces()) // crack tip case
928  {
929  if (_fragments.size() != 1 || _fragments[0]->numFaces() != n_old_frag_faces + n_old_frag_cuts)
930  EFAError("Incorrect link size for element with crack-tip faces");
931  }
932  else // frag is thoroughly cut
933  {
934  if (_fragments.size() != 2 || (_fragments[0]->numFaces() + _fragments[1]->numFaces()) !=
935  n_old_frag_faces + n_old_frag_cuts + 2)
936  EFAError("Incorrect link size for element that has been completely cut");
937  }
938 }
virtual unsigned int numInteriorNodes() const
Definition: EFAElement3D.C:425
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
bool fragmentHasTipFaces() const

◆ getAdjacentFace()

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

Definition at line 1700 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1701 {
1702  return _faces_adjacent_to_faces[face_id][edge_id];
1703 }
std::vector< std::vector< EFAFace * > > _faces_adjacent_to_faces
Definition: EFAElement3D.h:36

◆ getChild()

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

Definition at line 182 of file EFAElement.C.

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

183 {
184  if (child_id < _children.size())
185  return _children[child_id];
186  else
187  EFAError("child_id out of bounds");
188 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:33

◆ getCommonEdgeID()

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

Definition at line 1556 of file EFAElement3D.C.

Referenced by setupNeighbors().

1559 {
1560  bool has_common_edge = false;
1561  bool move_to_next_edge = false;
1562  face_id.clear();
1563  edge_id.clear();
1564  for (unsigned int i = 0; i < _num_faces; ++i)
1565  for (unsigned int j = 0; j < _faces[i]->numEdges(); ++j)
1566  {
1567  move_to_next_edge = false;
1568  for (unsigned int k = 0; k < other_elem->_num_faces; ++k)
1569  {
1570  for (unsigned int l = 0; l < other_elem->_faces[k]->numEdges(); ++l)
1571  if ((_faces[i]->getEdge(j)->equivalent(*(other_elem->_faces[k]->getEdge(l)))) &&
1572  !(_faces[i]->equivalent(other_elem->_faces[k])))
1573  {
1574  face_id.push_back(i);
1575  edge_id.push_back(j);
1576  move_to_next_edge = true;
1577  has_common_edge = true;
1578  break;
1579  }
1580 
1581  if (move_to_next_edge)
1582  break;
1583  }
1584  }
1585 
1586  return has_common_edge;
1587 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
unsigned int _num_faces
Definition: EFAElement3D.h:30

◆ getCommonFaceID()

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

Definition at line 1538 of file EFAElement3D.C.

Referenced by overlaysElement(), and setupNeighbors().

1539 {
1540  std::vector<unsigned int> face_id;
1541  for (unsigned int i = 0; i < _num_faces; ++i)
1542  {
1543  for (unsigned int j = 0; j < other_elem->_num_faces; ++j)
1544  {
1545  if (_faces[i]->equivalent(other_elem->_faces[j]))
1546  {
1547  face_id.push_back(i);
1548  break;
1549  }
1550  }
1551  }
1552  return face_id;
1553 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
unsigned int _num_faces
Definition: EFAElement3D.h:30

◆ getCommonNodes()

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

Definition at line 2228 of file EFAElement3D.C.

2229 {
2230  std::set<EFANode *> e1nodes(_nodes.begin(),
2231  _nodes.begin() + _num_vertices); // only account for corner nodes
2232  std::set<EFANode *> e2nodes(other_elem->_nodes.begin(),
2233  other_elem->_nodes.begin() + _num_vertices);
2234  std::vector<EFANode *> common_nodes = Efa::getCommonElems(e1nodes, e2nodes);
2235  return common_nodes;
2236 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
unsigned int _num_vertices
Definition: EFAElement3D.h:37
std::vector< T > getCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:70

◆ getCrackTipNeighbor()

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

Definition at line 148 of file EFAElement.C.

149 {
150  if (index < _crack_tip_neighbors.size())
151  return _crack_tip_neighbors[index];
152  else
153  EFAError("in getCrackTipNeighbor index out of bounds");
154 }
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:35

◆ getEdgeNeighbor()

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

Definition at line 1861 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1864 {
1865  if (neighbor_id < _face_edge_neighbors[face_id][edge_id].size())
1866  return _face_edge_neighbors[face_id][edge_id][neighbor_id];
1867  else
1868  EFAError("edge neighbor does not exist");
1869 }
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:34

◆ getFace()

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

◆ getFaceID()

unsigned int EFAElement3D::getFaceID ( EFAFace face) const

Definition at line 1519 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), and overlaysElement().

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

◆ getFaceNeighbor()

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

Definition at line 1852 of file EFAElement3D.C.

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

1853 {
1854  if (_face_neighbors[face_id][0] != NULL && neighbor_id < _face_neighbors[face_id].size())
1855  return _face_neighbors[face_id][neighbor_id];
1856  else
1857  EFAError("edge neighbor does not exist");
1858 }
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33

◆ getFaceNodeParametricCoordinates()

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

Definition at line 1390 of file EFAElement3D.C.

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

◆ getFaceNodes()

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

Definition at line 1381 of file EFAElement3D.C.

Referenced by shouldDuplicateCrackTipSplitElement().

1382 {
1383  std::set<EFANode *> face_nodes;
1384  for (unsigned int i = 0; i < _faces[face_id]->numNodes(); ++i)
1385  face_nodes.insert(_faces[face_id]->getNode(i));
1386  return face_nodes;
1387 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31

◆ 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 1706 of file EFAElement3D.C.

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

1707 {
1708  if (frag_id < _fragments.size())
1709  return _fragments[frag_id]->getFace(face_id);
1710  else
1711  EFAError("frag_id out of bounds in getFragmentFace");
1712 }
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35

◆ getFragmentFaceEdgeID()

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

Definition at line 1762 of file EFAElement3D.C.

Referenced by isPhysicalEdgeCut().

1766 {
1767  // Purpose: given an edge of an elem face, find which frag face's edge it contains
1768  bool frag_edge_found = false;
1769  FragFaceID = 99999;
1770  FragFaceEdgeID = 99999;
1771  if (getFragmentFaceID(ElemFaceID, FragFaceID))
1772  {
1773  EFAEdge * elem_edge = _faces[ElemFaceID]->getEdge(ElemFaceEdgeID);
1774  EFAFace * frag_face = getFragmentFace(0, FragFaceID);
1775  for (unsigned int i = 0; i < frag_face->numEdges(); ++i)
1776  {
1777  if (elem_edge->containsEdge(*frag_face->getEdge(i)))
1778  {
1779  FragFaceEdgeID = i;
1780  frag_edge_found = true;
1781  break;
1782  }
1783  }
1784  }
1785  return frag_edge_found;
1786 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
unsigned int numEdges() const
Definition: EFAFace.C:254
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:260
bool containsEdge(const EFAEdge &other) const
Definition: EFAEdge.C:63
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 1739 of file EFAElement3D.C.

Referenced by fragmentFaceAlreadyCut(), and getFragmentFaceEdgeID().

1740 {
1741  // find the fragment face that is contained by given element edge
1742  // N.B. if the elem edge contains two frag edges, this method will only return
1743  // the first frag edge ID
1744  bool frag_face_found = false;
1745  frag_face_id = 99999;
1746  if (_fragments.size() == 1)
1747  {
1748  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1749  {
1750  if (_faces[elem_face_id]->containsFace(_fragments[0]->getFace(j)))
1751  {
1752  frag_face_id = j;
1753  frag_face_found = true;
1754  break;
1755  }
1756  }
1757  }
1758  return frag_face_found;
1759 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35

◆ getGeneralNeighbor()

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

Definition at line 236 of file EFAElement.C.

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

237 {
238  return _general_neighbors[index];
239 }
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:37

◆ 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:30
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 1416 of file EFAElement3D.C.

Referenced by EFAFragment3D::isThirdInteriorFace().

1417 {
1418  if (interior_node_id < _interior_nodes.size())
1419  return _interior_nodes[interior_node_id];
1420  else
1421  EFAError("interior_node_id out of bounds");
1422 }
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:32

◆ getLocalNodeIndex()

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

Definition at line 111 of file EFAElement.C.

Referenced by XFEM::getEFANodeCoords().

112 {
113  unsigned int local_node_id = 99999;
114  bool found_local_node = false;
115  for (unsigned int i = 0; i < _num_nodes; ++i)
116  {
117  if (_nodes[i] == node)
118  {
119  found_local_node = true;
120  local_node_id = i;
121  break;
122  }
123  }
124  if (!found_local_node)
125  EFAError("In EFAelement::getLocalNodeIndex, cannot find the given node");
126  return local_node_id;
127 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
unsigned int _num_nodes
Definition: EFAElement.h:29

◆ 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::getMaterInfo, cannot find the given EFAnode");
422 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
unsigned int _num_nodes
Definition: EFAElement.h:29
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:30
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:32

◆ 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 469 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

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

◆ getNeighborFaceEdgeID()

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

Definition at line 1651 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), and checkNeighborFaceCut().

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

◆ getNeighborFaceInteriorNodeID()

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

Definition at line 1620 of file EFAElement3D.C.

Referenced by connectNeighbors().

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

◆ getNeighborFaceNodeID()

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

Definition at line 1590 of file EFAElement3D.C.

Referenced by connectNeighbors().

1593 {
1594  // get the corresponding node_id on the corresponding face of neighbor_elem
1595  bool found_id = false;
1596  unsigned int neigh_face_node_id;
1597  unsigned int common_face_id = getNeighborIndex(neighbor_elem);
1598  if (common_face_id == face_id)
1599  {
1600  unsigned int neigh_face_id = neighbor_elem->getNeighborIndex(this);
1601  EFAFace * neigh_face = neighbor_elem->getFace(neigh_face_id);
1602  for (unsigned int i = 0; i < neigh_face->numNodes(); ++i)
1603  {
1604  if (_faces[face_id]->getNode(node_id) == neigh_face->getNode(i))
1605  {
1606  neigh_face_node_id = i;
1607  found_id = true;
1608  break;
1609  }
1610  }
1611  }
1612  else
1613  EFAError("getNeighborFaceNodeID: neighbor_elem is not a neighbor on face_id");
1614  if (!found_id)
1615  EFAError("getNeighborFaceNodeID: could not find neighbor face node id");
1616  return neigh_face_node_id;
1617 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
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  return 99999;
466 }
unsigned int id() const
Definition: EFAElement.C:28
unsigned int _id
Definition: EFAElement.h:28
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33
unsigned int _num_faces
Definition: EFAElement3D.h:30

◆ getNode()

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

◆ 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:30
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35

◆ getNumCuts()

unsigned int EFAElement3D::getNumCuts ( ) const
virtual

Implements EFAElement.

Definition at line 828 of file EFAElement3D.C.

Referenced by restoreFragment().

829 {
830  unsigned int num_cut_faces = 0;
831  for (unsigned int i = 0; i < _num_faces; ++i)
832  if (_faces[i]->hasIntersection())
833  num_cut_faces += 1;
834  return num_cut_faces;
835 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
unsigned int _num_faces
Definition: EFAElement3D.h:30

◆ getParent()

EFAElement * EFAElement::getParent ( ) const
inherited

Definition at line 176 of file EFAElement.C.

177 {
178  return _parent;
179 }
EFAElement * _parent
Definition: EFAElement.h:32

◆ getPhantomNodeOnFace()

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

Definition at line 1715 of file EFAElement3D.C.

Referenced by shouldDuplicateForPhantomCorner().

1716 {
1717  std::set<EFANode *> phantom_nodes;
1718  if (_fragments.size() > 0)
1719  {
1720  for (unsigned int j = 0; j < _faces[face_id]->numNodes(); ++j) // loop ove 2 edge nodes
1721  {
1722  bool node_in_frag = false;
1723  for (unsigned int k = 0; k < _fragments.size(); ++k)
1724  {
1725  if (_fragments[k]->containsNode(_faces[face_id]->getNode(j)))
1726  {
1727  node_in_frag = true;
1728  break;
1729  }
1730  }
1731  if (!node_in_frag)
1732  phantom_nodes.insert(_faces[face_id]->getNode(j));
1733  }
1734  }
1735  return phantom_nodes;
1736 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46

◆ getTipEmbeddedNodes()

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

Definition at line 1924 of file EFAElement3D.C.

1925 {
1926  // if this element is a crack tip element, returns the crack tip edge's ID
1927  std::set<EFANode *> tip_emb;
1928  if (_fragments.size() == 1) // crack tip element with a partial fragment saved
1929  {
1930  for (unsigned int i = 0; i < _num_faces; ++i)
1931  {
1932  std::vector<EFAFace *> frag_faces; // count how many fragment edges this element edge contains
1933  if (_faces[i]->hasIntersection())
1934  {
1935  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1936  {
1937  if (_faces[i]->containsFace(_fragments[0]->getFace(j)))
1938  frag_faces.push_back(_fragments[0]->getFace(j));
1939  } // j
1940  if (frag_faces.size() == 2) // element edge contains two fragment edges
1941  {
1942  unsigned int edge_id = frag_faces[0]->adjacentCommonEdge(frag_faces[1]);
1943  tip_emb.insert(frag_faces[0]->getEdge(edge_id)->getNode(0));
1944  tip_emb.insert(frag_faces[0]->getEdge(edge_id)->getNode(1));
1945  }
1946  }
1947  } // i
1948  }
1949  return tip_emb;
1950 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
unsigned int _num_faces
Definition: EFAElement3D.h:30

◆ getTipFaceIDs()

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

Definition at line 1899 of file EFAElement3D.C.

1900 {
1901  // if this element is a crack tip element, returns the crack tip faces' ID
1902  std::vector<unsigned int> tip_face_id;
1903  if (_fragments.size() == 1) // crack tip element with a partial fragment saved
1904  {
1905  for (unsigned int i = 0; i < _num_faces; ++i)
1906  {
1907  unsigned int num_frag_faces = 0; // count how many fragment faces this element edge contains
1908  if (_faces[i]->hasIntersection())
1909  {
1910  for (unsigned int j = 0; j < _fragments[0]->numFaces(); ++j)
1911  {
1912  if (_faces[i]->containsFace(_fragments[0]->getFace(j)))
1913  num_frag_faces += 1;
1914  } // j
1915  if (num_frag_faces == 2) // element face contains two fragment edges
1916  tip_face_id.push_back(i);
1917  }
1918  } // i
1919  }
1920  return tip_face_id;
1921 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int _num_faces
Definition: EFAElement3D.h:30

◆ id()

unsigned int EFAElement::id ( ) const
inherited

◆ initCrackTip()

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

Implements EFAElement.

Definition at line 619 of file EFAElement3D.C.

620 {
621  if (isCrackTipElement())
622  {
623  CrackTipElements.insert(this);
624  for (unsigned int face_iter = 0; face_iter < _num_faces; ++face_iter)
625  {
626  if ((_face_neighbors[face_iter].size() == 2) && (_faces[face_iter]->hasIntersection()))
627  {
628  // Neither neighbor overlays current element. We are on the uncut element ahead of the tip.
629  // Flag neighbors as crack tip split elements and add this element as their crack tip
630  // neighbor.
631  if (_face_neighbors[face_iter][0]->overlaysElement(this) ||
632  _face_neighbors[face_iter][1]->overlaysElement(this))
633  EFAError("Element has a neighbor that overlays itself");
634 
635  // Make sure the current elment hasn't been flagged as a tip element
637  EFAError("crack_tip_split_element already flagged. In elem: ",
638  _id,
639  " flags: ",
641  " ",
642  _face_neighbors[face_iter][0]->isCrackTipSplit(),
643  " ",
644  _face_neighbors[face_iter][1]->isCrackTipSplit());
645 
646  _face_neighbors[face_iter][0]->setCrackTipSplit();
647  _face_neighbors[face_iter][1]->setCrackTipSplit();
648 
649  _face_neighbors[face_iter][0]->addCrackTipNeighbor(this);
650  _face_neighbors[face_iter][1]->addCrackTipNeighbor(this);
651  }
652  } // face_iter
653  }
654 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
bool isCrackTipSplit() const
Definition: EFAElement.C:136
unsigned int _id
Definition: EFAElement.h:28
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33
unsigned int _num_faces
Definition: EFAElement3D.h:30
bool overlaysElement(const EFAElement3D *other_elem) const
Definition: EFAElement3D.C:431
bool _crack_tip_split_element
Definition: EFAElement.h:34
virtual bool isCrackTipElement() const
Definition: EFAElement3D.C:822

◆ isCrackTipElement()

bool EFAElement3D::isCrackTipElement ( ) const
virtual

Implements EFAElement.

Definition at line 822 of file EFAElement3D.C.

Referenced by initCrackTip(), and shouldDuplicateForCrackTip().

823 {
824  return fragmentHasTipFaces();
825 }
bool fragmentHasTipFaces() const

◆ isCrackTipSplit()

bool EFAElement::isCrackTipSplit ( ) const
inherited

Definition at line 136 of file EFAElement.C.

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

137 {
139 }
bool _crack_tip_split_element
Definition: EFAElement.h:34

◆ isFacePhantom()

bool EFAElement3D::isFacePhantom ( unsigned int  face_id) const

Definition at line 1814 of file EFAElement3D.C.

Referenced by XFEM::markCutFacesByGeometry().

1815 {
1816  bool is_phantom = false;
1817  if (_fragments.size() > 0)
1818  {
1819  bool contains_frag_face = false;
1820  for (unsigned int i = 0; i < _fragments.size(); ++i)
1821  {
1822  for (unsigned int j = 0; j < _fragments[i]->numFaces(); ++j)
1823  {
1824  if (_faces[face_id]->containsFace(_fragments[i]->getFace(j)))
1825  {
1826  contains_frag_face = true;
1827  break;
1828  }
1829  }
1830  if (contains_frag_face)
1831  break;
1832  }
1833  if (!contains_frag_face)
1834  is_phantom = true;
1835  }
1836  return is_phantom;
1837 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAFace * getFace(unsigned int face_id) const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35

◆ isFinalCut()

bool EFAElement3D::isFinalCut ( ) const
virtual

Implements EFAElement.

Definition at line 838 of file EFAElement3D.C.

Referenced by GeometricCutUserObject::execute().

839 {
840  // if an element has been cut third times its fragment must have 3 interior faces
841  // and at this point, we do not want it to be further cut
842  bool cut_third = false;
843  if (_fragments.size() > 0)
844  {
845  unsigned int num_interior_faces = 0;
846  for (unsigned int i = 0; i < _fragments[0]->numFaces(); ++i)
847  {
848  if (_fragments[0]->isFaceInterior(i))
849  num_interior_faces += 1;
850  }
851  if (num_interior_faces == 3)
852  cut_third = true;
853  }
854  return cut_third;
855 }
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35

◆ isPartial()

bool EFAElement3D::isPartial ( ) const
virtual

Implements EFAElement.

Definition at line 275 of file EFAElement3D.C.

Referenced by updateFragments().

276 {
277  bool partial = false;
278  if (_fragments.size() > 0)
279  {
280  for (unsigned int i = 0; i < _num_vertices; ++i)
281  {
282  bool node_in_frag = false;
283  for (unsigned int j = 0; j < _fragments.size(); ++j)
284  {
285  if (_fragments[j]->containsNode(_nodes[i]))
286  {
287  node_in_frag = true;
288  break;
289  }
290  } // j
291  if (!node_in_frag)
292  {
293  partial = true;
294  break;
295  }
296  } // i
297  }
298  return partial;
299 }
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int _num_vertices
Definition: EFAElement3D.h:37

◆ isPhysicalEdgeCut()

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

Definition at line 1789 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1792 {
1793  unsigned int FragFaceID = 99999, FragFaceEdgeID = 99999;
1794  bool is_in_real = false;
1795  if (_fragments.size() == 0)
1796  {
1797  is_in_real = true;
1798  }
1799  else if (getFragmentFaceEdgeID(ElemFaceID, ElemFaceEdgeID, FragFaceID, FragFaceEdgeID))
1800  {
1801  EFAEdge * elem_edge = _faces[ElemFaceID]->getEdge(ElemFaceEdgeID);
1802  EFAEdge * frag_edge = getFragmentFace(0, FragFaceID)->getEdge(FragFaceEdgeID);
1803  double xi[2] = {-1.0, -1.0}; // relative coords of two frag edge nodes
1804  xi[0] = elem_edge->distanceFromNode1(frag_edge->getNode(0));
1805  xi[1] = elem_edge->distanceFromNode1(frag_edge->getNode(1));
1806  if ((position - xi[0]) * (position - xi[1]) <
1807  0.0) // the cut to be added is within the real part of the edge
1808  is_in_real = true;
1809  }
1810  return is_in_real;
1811 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
bool getFragmentFaceEdgeID(unsigned int ElemFaceID, unsigned int ElemFaceEdgeID, unsigned int &FragFaceID, unsigned int &FragFaceEdgeID) const
double distanceFromNode1(EFANode *node) const
Definition: EFAEdge.C:248
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:260
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
EFAFace * getFragmentFace(unsigned int frag_id, unsigned int face_id) const
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:179

◆ mapParametricCoordinateFrom2DTo3D()

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

Definition at line 2147 of file EFAElement3D.C.

Referenced by getFaceNodeParametricCoordinates().

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

◆ 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 248 of file EFAElement.C.

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

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

585 {
586  for (unsigned int face_iter = 0; face_iter < _num_faces; ++face_iter)
587  {
588  for (unsigned int en_iter = 0; en_iter < _face_neighbors[face_iter].size(); ++en_iter)
589  {
590  EFAElement3D * neigh_elem = _face_neighbors[face_iter][en_iter];
591  if (neigh_elem != NULL)
592  {
593  bool found_neighbor = false;
594  for (unsigned int face_iter2 = 0; face_iter2 < neigh_elem->numFaces(); ++face_iter2)
595  {
596  for (unsigned int en_iter2 = 0; en_iter2 < neigh_elem->numFaceNeighbors(face_iter2);
597  ++en_iter2)
598  {
599  if (neigh_elem->getFaceNeighbor(face_iter2, en_iter2) == this)
600  {
601  if ((en_iter2 > 1) && (en_iter > 1))
602  {
603  EFAError(
604  "Element and neighbor element cannot both have >1 neighbors on a common face");
605  }
606  found_neighbor = true;
607  break;
608  }
609  }
610  }
611  if (!found_neighbor)
612  EFAError("Neighbor element doesn't recognize current element as neighbor");
613  }
614  }
615  }
616 }
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33
unsigned int numFaces() const
unsigned int _num_faces
Definition: EFAElement3D.h:30
unsigned int numFaceNeighbors(unsigned int face_id) const

◆ numChildren()

unsigned int EFAElement::numChildren ( ) const
inherited

Definition at line 197 of file EFAElement.C.

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

198 {
199  return _children.size();
200 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:33

◆ numCrackTipNeighbors()

unsigned int EFAElement::numCrackTipNeighbors ( ) const
inherited

Definition at line 142 of file EFAElement.C.

143 {
144  return _crack_tip_neighbors.size();
145 }
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:35

◆ numEdgeNeighbors()

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

Definition at line 1846 of file EFAElement3D.C.

Referenced by addFaceEdgeCut().

1847 {
1848  return _face_edge_neighbors[face_id][edge_id].size();
1849 }
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:34

◆ numFaceNeighbors()

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

Definition at line 1840 of file EFAElement3D.C.

Referenced by addFaceEdgeCut(), checkNeighborFaceCut(), connectNeighbors(), neighborSanityCheck(), printElement(), removeEmbeddedNode(), shouldDuplicateCrackTipSplitElement(), shouldDuplicateForPhantomCorner(), and willCrackTipExtend().

1841 {
1842  return _face_neighbors[face_id].size();
1843 }
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33

◆ numFaces()

unsigned int EFAElement3D::numFaces ( ) const

◆ numFragments()

unsigned int EFAElement3D::numFragments ( ) const
virtual

◆ numGeneralNeighbors()

unsigned int EFAElement::numGeneralNeighbors ( ) const
inherited

Definition at line 242 of file EFAElement.C.

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

243 {
244  return _general_neighbors.size();
245 }
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:37

◆ 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:32

◆ 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  std::vector<unsigned int> 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:31
bool hasSameOrientation(const EFAFace *other_face) const
Definition: EFAFace.C:658
unsigned int getFaceID(EFAFace *face) const
std::vector< unsigned int > getCommonFaceID(const EFAElement3D *other_elem) const

◆ printElement()

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

Implements EFAElement.

Definition at line 1280 of file EFAElement3D.C.

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

◆ removeEmbeddedNode()

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

Definition at line 1425 of file EFAElement3D.C.

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

1426 {
1427  for (unsigned int i = 0; i < _fragments.size(); ++i)
1428  _fragments[i]->removeEmbeddedNode(emb_node);
1429 
1430  for (unsigned int i = 0; i < _faces.size(); ++i)
1431  _faces[i]->removeEmbeddedNode(emb_node);
1432 
1433  if (remove_for_neighbor)
1434  {
1435  for (unsigned int i = 0; i < numFaces(); ++i)
1436  for (unsigned int j = 0; j < numFaceNeighbors(i); ++j)
1437  getFaceNeighbor(i, j)->removeEmbeddedNode(emb_node, false);
1438  }
1439 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAElement3D * getFaceNeighbor(unsigned int face_id, unsigned int neighbor_id) const
unsigned int numFaces() const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
void removeEmbeddedNode(EFANode *emb_node, bool remove_for_neighbor)
unsigned int numFaceNeighbors(unsigned int face_id) const

◆ removePhantomEmbeddedNode()

void EFAElement3D::removePhantomEmbeddedNode ( )
virtual

Implements EFAElement.

Definition at line 1106 of file EFAElement3D.C.

Referenced by createChild().

1107 {
1108  // remove the embedded nodes on faces that are outside the real domain
1109  if (_fragments.size() > 0)
1110  {
1111  for (unsigned int i = 0; i < _num_faces; ++i)
1112  {
1113  // get emb nodes to be removed on edges
1114  std::vector<EFANode *> nodes_to_delete;
1115  for (unsigned int j = 0; j < _faces[i]->numEdges(); ++j)
1116  {
1117  EFAEdge * edge = _faces[i]->getEdge(j);
1118  for (unsigned int k = 0; k < edge->numEmbeddedNodes(); ++k)
1119  {
1120  if (!_fragments[0]->containsNode(edge->getEmbeddedNode(k)))
1121  nodes_to_delete.push_back(edge->getEmbeddedNode(k));
1122  } // k
1123  } // j
1124 
1125  // get emb nodes to be removed in the face interior
1126  for (unsigned int j = 0; j < _faces[i]->numInteriorNodes(); ++j)
1127  {
1128  EFANode * face_node = _faces[i]->getInteriorNode(j)->getNode();
1129  if (!_fragments[0]->containsNode(face_node))
1130  nodes_to_delete.push_back(face_node);
1131  } // j
1132 
1133  // remove all invalid embedded nodes
1134  for (unsigned int j = 0; j < nodes_to_delete.size(); ++j)
1135  _faces[i]->removeEmbeddedNode(nodes_to_delete[j]);
1136  } // i
1137  }
1138 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFANode * getEmbeddedNode(unsigned int index) const
Definition: EFAEdge.C:330
bool containsNode(EFANode *node) const
Definition: EFAElement.C:52
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
void removeEmbeddedNode(EFANode *emb_node, bool remove_for_neighbor)
unsigned int _num_faces
Definition: EFAElement3D.h:30
unsigned int numEmbeddedNodes() const
Definition: EFAEdge.C:339

◆ restoreFragment()

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

Implements EFAElement.

Definition at line 941 of file EFAElement3D.C.

942 {
943  const EFAElement3D * from_elem3d = dynamic_cast<const EFAElement3D *>(from_elem);
944  if (!from_elem3d)
945  EFAError("from_elem is not of EFAelement3D type");
946 
947  // restore fragments
948  if (_fragments.size() != 0)
949  EFAError("in restoreFragmentInfo elements must not have any pre-existing fragments");
950  for (unsigned int i = 0; i < from_elem3d->numFragments(); ++i)
951  _fragments.push_back(new EFAFragment3D(this, true, from_elem3d, i));
952 
953  // restore interior nodes
954  if (_interior_nodes.size() != 0)
955  EFAError("in restoreFragmentInfo elements must not have any pre-exsiting interior nodes");
956  for (unsigned int i = 0; i < from_elem3d->_interior_nodes.size(); ++i)
957  _interior_nodes.push_back(new EFAVolumeNode(*from_elem3d->_interior_nodes[i]));
958 
959  // restore face intersections
960  if (getNumCuts() != 0)
961  EFAError("In restoreEdgeIntersection: edge cuts already exist in element ", _id);
962  for (unsigned int i = 0; i < _num_faces; ++i)
963  _faces[i]->copyIntersection(*from_elem3d->_faces[i]);
964 
965  // replace all local nodes with global nodes
966  for (unsigned int i = 0; i < from_elem3d->numNodes(); ++i)
967  {
968  if (from_elem3d->_nodes[i]->category() == EFANode::N_CATEGORY_LOCAL_INDEX)
969  switchNode(
970  _nodes[i], from_elem3d->_nodes[i], false); // EFAelement is not a child of any parent
971  else
972  EFAError("In restoreFragmentInfo all of from_elem's nodes must be local");
973  }
974 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
unsigned int _id
Definition: EFAElement.h:28
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:269
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int _num_faces
Definition: EFAElement3D.h:30
unsigned int numNodes() const
Definition: EFAElement.C:34
virtual unsigned int getNumCuts() const
Definition: EFAElement3D.C:828
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:32

◆ setCrackTipSplit()

void EFAElement::setCrackTipSplit ( )
inherited

Definition at line 130 of file EFAElement.C.

131 {
133 }
bool _crack_tip_split_element
Definition: EFAElement.h:34

◆ setFace()

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

Definition at line 1448 of file EFAElement3D.C.

1449 {
1450  _faces[face_id] = face;
1451 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31

◆ setLocalCoordinates()

void EFAElement3D::setLocalCoordinates ( )
private

Definition at line 153 of file EFAElement3D.C.

Referenced by EFAElement3D().

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

◆ setNode()

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

◆ setParent()

void EFAElement::setParent ( EFAElement parent)
inherited

Definition at line 191 of file EFAElement.C.

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

192 {
193  _parent = parent;
194 }
EFAElement * _parent
Definition: EFAElement.h:32

◆ setupNeighbors()

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

Implements EFAElement.

Definition at line 508 of file EFAElement3D.C.

509 {
510  findGeneralNeighbors(InverseConnectivityMap);
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  std::vector<unsigned int> common_face_id = getCommonFaceID(neigh_elem);
518  std::vector<unsigned int> face_ids, edge_ids;
519  if (common_face_id.size() == 0 && getCommonEdgeID(neigh_elem, face_ids, edge_ids) &&
520  !overlaysElement(neigh_elem))
521  {
522  bool is_edge_neighbor = false;
523 
524  // Fragments must match up.
525  if ((_fragments.size() > 1) || (neigh_elem->numFragments() > 1))
526  {
527  EFAError("in updateFaceNeighbors: Cannot have more than 1 fragment");
528  }
529  else if ((_fragments.size() == 1) && (neigh_elem->numFragments() == 1))
530  {
531  if (_fragments[0]->isEdgeConnected(neigh_elem->getFragment(0)))
532  is_edge_neighbor = true;
533  }
534  else // If there are no fragments to match up, consider them edge neighbors
535  is_edge_neighbor = true;
536 
537  if (is_edge_neighbor)
538  {
539  for (unsigned int i = 0; i < face_ids.size(); ++i)
540  {
541  unsigned int face_id = face_ids[i];
542  unsigned int edge_id = edge_ids[i];
543  _face_edge_neighbors[face_id][edge_id].push_back(neigh_elem);
544  }
545  }
546  }
547 
548  if (common_face_id.size() == 1 && !overlaysElement(neigh_elem))
549  {
550  unsigned int face_id = common_face_id[0];
551  bool is_face_neighbor = false;
552 
553  // Fragments must match up.
554  if ((_fragments.size() > 1) || (neigh_elem->numFragments() > 1))
555  {
556  EFAError("in updateFaceNeighbors: Cannot have more than 1 fragment");
557  }
558  else if ((_fragments.size() == 1) && (neigh_elem->numFragments() == 1))
559  {
560  if (_fragments[0]->isConnected(neigh_elem->getFragment(0)))
561  is_face_neighbor = true;
562  }
563  else // If there are no fragments to match up, consider them neighbors
564  is_face_neighbor = true;
565 
566  if (is_face_neighbor)
567  {
568  if (_face_neighbors[face_id].size() > 1)
569  {
570  EFAError("Element ",
571  _id,
572  " already has 2 face neighbors: ",
573  _face_neighbors[face_id][0]->id(),
574  " ",
575  _face_neighbors[face_id][1]->id());
576  }
577  _face_neighbors[face_id].push_back(neigh_elem);
578  }
579  }
580  }
581 }
EFAFragment3D * getFragment(unsigned int frag_id) const
std::vector< std::vector< std::vector< EFAElement3D * > > > _face_edge_neighbors
Definition: EFAElement3D.h:34
bool getCommonEdgeID(const EFAElement3D *other_elem, std::vector< unsigned int > &face_id, std::vector< unsigned int > &edge_id) const
unsigned int _id
Definition: EFAElement.h:28
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33
void findGeneralNeighbors(std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivity)
Definition: EFAElement.C:216
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:269
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
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:37

◆ shouldDuplicateCrackTipSplitElement()

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

Implements EFAElement.

Definition at line 681 of file EFAElement3D.C.

Referenced by shouldDuplicateForCrackTip().

682 {
683  // Determine whether element at crack tip should be duplicated. It should be duplicated
684  // if the crack will extend into the next element, or if it has a non-physical node
685  // connected to a face where a crack terminates, but will extend.
686 
687  bool should_duplicate = false;
688  if (_fragments.size() == 1)
689  {
690  std::vector<unsigned int> split_neighbors;
691  if (willCrackTipExtend(split_neighbors))
692  should_duplicate = true;
693  else
694  {
695  // The element may not be at the crack tip, but could have a non-physical node
696  // connected to a crack tip face (on a neighbor element) that will be split. We need to
697  // duplicate in that case as well.
698  std::set<EFANode *> non_physical_nodes;
699  getNonPhysicalNodes(non_physical_nodes);
700 
701  for (unsigned int eit = 0; eit < _general_neighbors.size(); ++eit)
702  {
703  EFAElement3D * neigh_elem = dynamic_cast<EFAElement3D *>(_general_neighbors[eit]);
704  if (!neigh_elem)
705  EFAError("general elem is not of type EFAelement3D");
706 
707  // check if a general neighbor is an old crack tip element and will be split
708  std::set<EFAElement *>::iterator sit;
709  sit = CrackTipElements.find(neigh_elem);
710  if (sit != CrackTipElements.end() && neigh_elem->numFragments() > 1)
711  {
712  for (unsigned int i = 0; i < neigh_elem->numFaces(); ++i)
713  {
714  std::set<EFANode *> neigh_face_nodes = neigh_elem->getFaceNodes(i);
715  if (neigh_elem->numFaceNeighbors(i) == 2 &&
716  Efa::numCommonElems(neigh_face_nodes, non_physical_nodes) > 0)
717  {
718  should_duplicate = true;
719  break;
720  }
721  } // i
722  }
723  if (should_duplicate)
724  break;
725  } // eit
726  }
727  } // IF only one fragment
728  return should_duplicate;
729 }
virtual void getNonPhysicalNodes(std::set< EFANode *> &non_physical_nodes) const
Definition: EFAElement3D.C:302
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:269
unsigned int numFaces() const
virtual bool willCrackTipExtend(std::vector< unsigned int > &split_neighbors) const
Definition: EFAElement3D.C:771
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:50
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:37
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 657 of file EFAElement3D.C.

Referenced by createChild().

658 {
659  // This method is called in createChildElements()
660  // Only duplicate when
661  // 1) currElem will be a NEW crack tip element
662  // 2) currElem is a crack tip split element at last time step and the tip will extend
663  // 3) currElem is the neighbor of a to-be-second-split element which has another neighbor
664  // sharing a phantom node with currElem
665  bool should_duplicate = false;
666  if (_fragments.size() == 1)
667  {
668  std::set<EFAElement *>::iterator sit;
669  sit = CrackTipElements.find(this);
670  if (sit == CrackTipElements.end() && isCrackTipElement())
671  should_duplicate = true;
672  else if (shouldDuplicateCrackTipSplitElement(CrackTipElements))
673  should_duplicate = true;
675  should_duplicate = true;
676  }
677  return should_duplicate;
678 }
virtual bool shouldDuplicateForPhantomCorner()
Definition: EFAElement3D.C:732
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
virtual bool shouldDuplicateCrackTipSplitElement(const std::set< EFAElement *> &CrackTipElements)
Definition: EFAElement3D.C:681
virtual bool isCrackTipElement() const
Definition: EFAElement3D.C:822

◆ shouldDuplicateForPhantomCorner()

bool EFAElement3D::shouldDuplicateForPhantomCorner ( )
virtual

Implements EFAElement.

Definition at line 732 of file EFAElement3D.C.

Referenced by shouldDuplicateForCrackTip().

733 {
734  // if a partial element will be split for a second time and it has two neighbor elements
735  // sharing one phantom node with the aforementioned partial element, then the two neighbor
736  // elements should be duplicated
737  bool should_duplicate = false;
738  if (_fragments.size() == 1 && (!_crack_tip_split_element))
739  {
740  for (unsigned int i = 0; i < _num_faces; ++i)
741  {
742  std::set<EFANode *> phantom_nodes = getPhantomNodeOnFace(i);
743  if (phantom_nodes.size() > 0 && numFaceNeighbors(i) == 1)
744  {
745  EFAElement3D * neighbor_elem = _face_neighbors[i][0];
746  if (neighbor_elem->numFragments() > 1) // neighbor will be split
747  {
748  for (unsigned int j = 0; j < neighbor_elem->numFaces(); ++j)
749  {
750  if (!neighbor_elem->getFace(j)->equivalent(_faces[i]) &&
751  neighbor_elem->numFaceNeighbors(j) > 0)
752  {
753  std::set<EFANode *> neigh_phantom_nodes = neighbor_elem->getPhantomNodeOnFace(j);
754  if (Efa::numCommonElems(phantom_nodes, neigh_phantom_nodes) > 0)
755  {
756  should_duplicate = true;
757  break;
758  }
759  }
760  } // j
761  }
762  }
763  if (should_duplicate)
764  break;
765  } // i
766  }
767  return should_duplicate;
768 }
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
EFAFace * getFace(unsigned int face_id) const
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:269
bool equivalent(const EFAFace *other_face) const
Definition: EFAFace.C:367
unsigned int numFaces() const
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:50
unsigned int _num_faces
Definition: EFAElement3D.h:30
bool _crack_tip_split_element
Definition: EFAElement.h:34
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:31
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int _num_faces
Definition: EFAElement3D.h:30
std::vector< EFAVolumeNode * > _interior_nodes
Definition: EFAElement3D.h:32

◆ 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:31
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement3D.C:329
unsigned int numChildren() const
Definition: EFAElement.C:197
unsigned int numGeneralNeighbors() const
Definition: EFAElement.C:242
EFAElement * getChild(unsigned int child_id) const
Definition: EFAElement.C:182
std::vector< EFANode * > _nodes
Definition: EFAElement.h:30
std::vector< EFAFragment3D * > _fragments
Definition: EFAElement3D.h:35
unsigned int _num_nodes
Definition: EFAElement.h:29
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)=0
EFAElement * _parent
Definition: EFAElement.h:32
EFAElement * getGeneralNeighbor(unsigned int index) const
Definition: EFAElement.C:236

◆ 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 858 of file EFAElement3D.C.

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

◆ willCrackTipExtend()

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

Implements EFAElement.

Definition at line 771 of file EFAElement3D.C.

Referenced by shouldDuplicateCrackTipSplitElement().

772 {
773  // Determine whether the current element is a crack tip element for which the crack will
774  // extend into the next element.
775  // N.B. this is called at the beginning of createChildElements
776  bool will_extend = false;
777  if (_fragments.size() == 1 && _crack_tip_split_element)
778  {
779  for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
780  {
781  unsigned int neigh_idx = _crack_tip_neighbors[i]; // essentially a face_id
782  if (numFaceNeighbors(neigh_idx) != 1)
783  EFAError("in will_crack_tip_extend() element ",
784  _id,
785  " has ",
786  _face_neighbors[neigh_idx].size(),
787  " neighbors on face ",
788  neigh_idx);
789 
790  EFAElement3D * neighbor_elem = _face_neighbors[neigh_idx][0];
791  if (neighbor_elem->numFragments() > 2)
792  {
793  EFAError("in will_crack_tip_extend() element ",
794  neighbor_elem->id(),
795  " has ",
796  neighbor_elem->numFragments(),
797  " fragments");
798  }
799  else if (neighbor_elem->numFragments() == 2)
800  {
801  EFAFragment3D * neigh_frag1 = neighbor_elem->getFragment(0);
802  EFAFragment3D * neigh_frag2 = neighbor_elem->getFragment(1);
803  std::vector<EFANode *> neigh_cut_nodes = neigh_frag1->getCommonNodes(neigh_frag2);
804  unsigned int counter = 0; // counter how many common nodes are contained by current face
805  for (unsigned int j = 0; j < neigh_cut_nodes.size(); ++j)
806  {
807  if (_faces[neigh_idx]->containsNode(neigh_cut_nodes[j]))
808  counter += 1;
809  }
810  if (counter == 2)
811  {
812  split_neighbors.push_back(neigh_idx);
813  will_extend = true;
814  }
815  }
816  } // i
817  }
818  return will_extend;
819 }
EFAFragment3D * getFragment(unsigned int frag_id) const
std::vector< EFAFace * > _faces
Definition: EFAElement3D.h:31
unsigned int id() const
Definition: EFAElement.C:28
unsigned int _id
Definition: EFAElement.h:28
std::vector< std::vector< EFAElement3D * > > _face_neighbors
Definition: EFAElement3D.h:33
virtual unsigned int numFragments() const
Definition: EFAElement3D.C:269
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:35
bool _crack_tip_split_element
Definition: EFAElement.h:34
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:35
unsigned int numFaceNeighbors(unsigned int face_id) const
static unsigned int counter

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 36 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 39 of file EFAElement3D.h.

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

◆ _local_nodes

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

◆ _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 37 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: