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

#include <EFAElement2D.h>

Inheritance diagram for EFAElement2D:
[legend]

Public Member Functions

 EFAElement2D (unsigned int eid, unsigned int n_nodes)
 
 EFAElement2D (const EFAElement2D *from_elem, bool convert_to_local)
 
 EFAElement2D (const EFAFace *from_face)
 
 ~EFAElement2D ()
 
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 EFAElement2D *other_elem) const
 
virtual unsigned int getNeighborIndex (const EFAElement *neighbor_elem) 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_edges, 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_edges)
 
virtual void printElement (std::ostream &ostream)
 
EFAFragment2DgetFragment (unsigned int frag_id) const
 
std::set< EFANode * > getEdgeNodes (unsigned int edge_id) const
 
bool getEdgeNodeParametricCoordinate (EFANode *node, std::vector< double > &para_coor) const
 
EFAFaceNodegetInteriorNode (unsigned int interior_node_id) const
 
void deleteInteriorNodes ()
 
unsigned int numEdges () const
 
void setEdge (unsigned int edge_id, EFAEdge *edge)
 
void createEdges ()
 
EFAEdgegetEdge (unsigned int edge_id) const
 
EFAEdgegetFragmentEdge (unsigned int frag_id, unsigned int edge_id) const
 
std::set< EFANode * > getPhantomNodeOnEdge (unsigned int edge_id) const
 
bool getFragmentEdgeID (unsigned int elem_edge_id, unsigned int &frag_edge_id) const
 
bool isEdgePhantom (unsigned int edge_id) const
 
unsigned int numEdgeNeighbors (unsigned int edge_id) const
 
EFAElement2DgetEdgeNeighbor (unsigned int edge_id, unsigned int neighbor_id) const
 
unsigned int getCrackTipSplitElementID () const
 
bool fragmentHasTipEdges () const
 
unsigned int getTipEdgeID () const
 
EFANodegetTipEmbeddedNode () const
 
bool edgeContainsTip (unsigned int edge_id) const
 
bool fragmentEdgeAlreadyCut (unsigned int ElemEdgeID) const
 
void addEdgeCut (unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode * > &EmbeddedNodes, bool add_to_neighbor)
 
void addNodeCut (unsigned int node_id, EFANode *embedded_permanent_node, std::map< unsigned int, EFANode * > &PermanentNodes, std::map< unsigned int, EFANode * > &EmbeddedPermanentNodes)
 
bool addFragmentEdgeCut (unsigned int frag_edge_id, double position, std::map< unsigned int, EFANode * > &EmbeddedNodes)
 
std::vector< EFAFragment2D * > branchingSplit (std::map< unsigned int, EFANode * > &EmbeddedNodes)
 
std::vector< EFANode * > getCommonNodes (const EFAElement2D *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 mapParametricCoordFrom1Dto2D (unsigned int edge_id, double xi_1d, std::vector< double > &para_coor) const
 
void setLocalCoordinates ()
 

Private Attributes

unsigned int _num_edges
 
std::vector< EFAEdge * > _edges
 
std::vector< EFAFaceNode * > _interior_nodes
 
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
 
std::vector< EFAFragment2D * > _fragments
 
std::vector< EFAPoint_local_node_coor
 

Detailed Description

Definition at line 19 of file EFAElement2D.h.

Constructor & Destructor Documentation

EFAElement2D::EFAElement2D ( unsigned int  eid,
unsigned int  n_nodes 
)

Definition at line 21 of file EFAElement2D.C.

Referenced by createChild().

21  : EFAElement(eid, n_nodes)
22 {
23  if (n_nodes == 4 || n_nodes == 8 || n_nodes == 9)
24  _num_edges = 4;
25  else if (n_nodes == 3 || n_nodes == 6)
26  _num_edges = 3;
27  else
28  EFAError("In EFAelement2D the supported element types are QUAD4, QUAD8, QUAD9, TRI3 and TRI6");
30  _edges = std::vector<EFAEdge *>(_num_edges, NULL);
32  std::vector<std::vector<EFAElement2D *>>(_num_edges, std::vector<EFAElement2D *>(1, NULL));
33 }
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement.C:14
void setLocalCoordinates()
Definition: EFAElement2D.C:139
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFAElement2D::EFAElement2D ( const EFAElement2D from_elem,
bool  convert_to_local 
)

Definition at line 35 of file EFAElement2D.C.

36  : EFAElement(from_elem->_id, from_elem->_num_nodes),
37  _num_edges(from_elem->_num_edges),
38  _edges(_num_edges, NULL),
39  _edge_neighbors(_num_edges, std::vector<EFAElement2D *>(1, NULL))
40 {
41  if (convert_to_local)
42  {
43  // build local nodes from global nodes
44  for (unsigned int i = 0; i < _num_nodes; ++i)
45  {
46  if (from_elem->_nodes[i]->category() == EFANode::N_CATEGORY_PERMANENT ||
47  from_elem->_nodes[i]->category() == EFANode::N_CATEGORY_TEMP ||
48  from_elem->_nodes[i]->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
49  {
50  _nodes[i] = from_elem->createLocalNodeFromGlobalNode(from_elem->_nodes[i]);
51  _local_nodes.push_back(_nodes[i]); // convenient to delete local nodes
52  }
53  else
54  EFAError("In EFAelement2D ",
55  from_elem->id(),
56  " the copy constructor must have from_elem w/ global nodes. node: ",
57  i,
58  " category: ",
59  from_elem->_nodes[i]->category());
60  }
61 
62  // copy edges, fragments and interior nodes from from_elem
63  for (unsigned int i = 0; i < _num_edges; ++i)
64  _edges[i] = new EFAEdge(*from_elem->_edges[i]);
65  for (unsigned int i = 0; i < from_elem->_fragments.size(); ++i)
66  _fragments.push_back(new EFAFragment2D(this, true, from_elem, i));
67  for (unsigned int i = 0; i < from_elem->_interior_nodes.size(); ++i)
68  _interior_nodes.push_back(new EFAFaceNode(*from_elem->_interior_nodes[i]));
69 
70  // replace all global nodes with local nodes
71  for (unsigned int i = 0; i < _num_nodes; ++i)
72  {
73  if (_nodes[i]->category() == EFANode::N_CATEGORY_LOCAL_INDEX)
74  switchNode(
75  _nodes[i],
76  from_elem->_nodes[i],
77  false); // when save to _cut_elem_map, the EFAelement is not a child of any parent
78  else
79  EFAError("In EFAelement2D copy constructor this elem's nodes must be local");
80  }
81 
83  }
84  else
85  EFAError("this EFAelement2D constructor only converts global nodes to local nodes");
86 }
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
unsigned int _id
Definition: EFAElement.h:26
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
unsigned int id() const
Definition: EFAElement.C:26
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement.C:14
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement2D.C:260
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
std::vector< EFAPoint > _local_node_coor
Definition: EFAElement2D.h:34
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFANode * createLocalNodeFromGlobalNode(const EFANode *global_node) const
Definition: EFAElement.C:68
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
std::vector< EFANode * > _local_nodes
Definition: EFAElement.h:29
EFAElement2D::EFAElement2D ( const EFAFace from_face)

Definition at line 88 of file EFAElement2D.C.

89  : EFAElement(0, from_face->numNodes()),
90  _num_edges(from_face->numEdges()),
91  _edges(_num_edges, NULL),
92  _edge_neighbors(_num_edges, std::vector<EFAElement2D *>(1, NULL))
93 {
94  for (unsigned int i = 0; i < _num_nodes; ++i)
95  _nodes[i] = from_face->getNode(i);
96  for (unsigned int i = 0; i < _num_edges; ++i)
97  _edges[i] = new EFAEdge(*from_face->getEdge(i));
98  for (unsigned int i = 0; i < from_face->numInteriorNodes(); ++i)
99  _interior_nodes.push_back(new EFAFaceNode(*from_face->getInteriorNode(i)));
100 }
unsigned int numNodes() const
Definition: EFAFace.C:85
unsigned int numInteriorNodes() const
Definition: EFAFace.C:234
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:258
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
unsigned int numEdges() const
Definition: EFAFace.C:252
EFAElement(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement.C:14
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
EFAFaceNode * getInteriorNode(unsigned int index) const
Definition: EFAFace.C:682
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFANode * getNode(unsigned int node_id) const
Definition: EFAFace.C:97
EFAElement2D::~EFAElement2D ( )

Definition at line 102 of file EFAElement2D.C.

103 {
104  for (unsigned int i = 0; i < _fragments.size(); ++i)
105  {
106  if (_fragments[i])
107  {
108  delete _fragments[i];
109  _fragments[i] = NULL;
110  }
111  }
112  for (unsigned int i = 0; i < _edges.size(); ++i)
113  {
114  if (_edges[i])
115  {
116  delete _edges[i];
117  _edges[i] = NULL;
118  }
119  }
120  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
121  {
122  if (_interior_nodes[i])
123  {
124  delete _interior_nodes[i];
125  _interior_nodes[i] = NULL;
126  }
127  }
128  for (unsigned int i = 0; i < _local_nodes.size(); ++i)
129  {
130  if (_local_nodes[i])
131  {
132  delete _local_nodes[i];
133  _local_nodes[i] = NULL;
134  }
135  }
136 }
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
std::vector< EFANode * > _local_nodes
Definition: EFAElement.h:29

Member Function Documentation

void EFAElement::addChild ( EFAElement child)
inherited

Definition at line 201 of file EFAElement.C.

202 {
203  _children.push_back(child);
204 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:31
void EFAElement::addCrackTipNeighbor ( EFAElement neighbor_elem)
inherited

Definition at line 155 of file EFAElement.C.

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

Definition at line 1709 of file EFAElement2D.C.

Referenced by addEdgeCut(), and ElementFragmentAlgorithm::addElemEdgeIntersection().

1714 {
1715  EFANode * local_embedded = NULL;
1716  EFANode * edge_node1 = _edges[edge_id]->getNode(0);
1717  if (embedded_node) // use the existing embedded node if it was passed in
1718  local_embedded = embedded_node;
1719 
1720  if (_edges[edge_id]->hasIntersectionAtPosition(position, edge_node1) &&
1721  position > Xfem::tol & position < 1.0 - Xfem::tol)
1722  {
1723  unsigned int emb_id = _edges[edge_id]->getEmbeddedNodeIndex(position, edge_node1);
1724  EFANode * old_emb = _edges[edge_id]->getEmbeddedNode(emb_id);
1725  if (embedded_node && embedded_node != old_emb)
1726  {
1727  EFAError("Attempting to add edge intersection when one already exists with different node.",
1728  " elem: ",
1729  _id,
1730  " edge: ",
1731  edge_id,
1732  " position: ",
1733  position);
1734  }
1735  local_embedded = old_emb;
1736  }
1737  else // if no cut exists at the input position
1738  {
1739  bool add2elem = true;
1740 
1741  // check if it is necessary to add cuts to fragment
1742  unsigned int frag_edge_id = 99999; // the id of the partially overlapping fragment edge
1743  EFAEdge * frag_edge = NULL;
1744  EFANode * frag_edge_node1 = NULL;
1745  double frag_pos = -1.0;
1746  bool add2frag = false;
1747 
1748  if (getFragmentEdgeID(edge_id, frag_edge_id)) // elem edge contains a frag edge
1749  {
1750  frag_edge = getFragmentEdge(0, frag_edge_id);
1751  if (!fragmentEdgeAlreadyCut(edge_id))
1752  {
1753  double xi[2] = {-1.0, -1.0}; // relative coords of two frag edge nodes
1754  xi[0] = _edges[edge_id]->distanceFromNode1(frag_edge->getNode(0));
1755  xi[1] = _edges[edge_id]->distanceFromNode1(frag_edge->getNode(1));
1756  if ((position - xi[0]) * (position - xi[1]) <
1757  0.0) // the cut to be added is within the real part of the edge
1758  {
1759  frag_edge_node1 = frag_edge->getNode(0);
1760  frag_pos = (position - xi[0]) / (xi[1] - xi[0]);
1761  add2frag = true;
1762  }
1763  else // the emb node to be added is in the phantom part of the elem edge
1764  add2elem = false; // DO NOT ADD INTERSECT IN THIS CASE
1765  }
1766  else
1767  {
1768  EFAWarning("attempting to add new cut to a cut fragment edge");
1769  add2elem = false; // DO NOT ADD INTERSECT IN THIS CASE
1770  }
1771  }
1772 
1773  // If elem edge has 2 cuts but they have not been restored yet, it's OK because
1774  // getFragmentEdgeID = false so we won't add anything to the restored fragment.
1775  // add to elem edge (IMPORTANT to do it AFTER the above fragment check)
1776  if (add2elem)
1777  {
1778  if (!local_embedded) // need to create new embedded node
1779  {
1780  unsigned int new_node_id = Efa::getNewID(EmbeddedNodes);
1781  local_embedded = new EFANode(new_node_id, EFANode::N_CATEGORY_EMBEDDED);
1782  EmbeddedNodes.insert(std::make_pair(new_node_id, local_embedded));
1783  }
1784  _edges[edge_id]->addIntersection(position, local_embedded, edge_node1);
1785  if (_edges[edge_id]->numEmbeddedNodes() > 2)
1786  EFAError("element edge can't have >2 embedded nodes");
1787  }
1788 
1789  // add to frag edge
1790  if (add2frag)
1791  {
1792  frag_edge->addIntersection(frag_pos, local_embedded, frag_edge_node1);
1793  if (frag_edge->numEmbeddedNodes() > 1)
1794  EFAError("fragment edge can't have >1 embedded nodes");
1795  }
1796  } // IF the input embedded node already exists on this elem edge
1797 
1798  if (add_to_neighbor)
1799  {
1800  for (unsigned int en_iter = 0; en_iter < numEdgeNeighbors(edge_id); ++en_iter)
1801  {
1802  EFAElement2D * edge_neighbor = getEdgeNeighbor(edge_id, en_iter);
1803  unsigned int neighbor_edge_id = edge_neighbor->getNeighborIndex(this);
1804  if (edge_neighbor->getEdge(neighbor_edge_id)->getNode(0) == edge_node1) // same direction
1805  EFAError("neighbor edge has the same direction as this edge");
1806  double neigh_pos = 1.0 - position; // get emb node's postion on neighbor edge
1807  edge_neighbor->addEdgeCut(neighbor_edge_id, neigh_pos, local_embedded, EmbeddedNodes, false);
1808  }
1809  } // If add_to_neighbor required
1810 }
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement2D.C:445
unsigned int _id
Definition: EFAElement.h:26
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
unsigned int numEmbeddedNodes() const
Definition: EFAEdge.C:337
EFAEdge * getEdge(unsigned int edge_id) const
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
EFAElement2D * getEdgeNeighbor(unsigned int edge_id, unsigned int neighbor_id) const
bool fragmentEdgeAlreadyCut(unsigned int ElemEdgeID) const
static const double tol
Definition: XFEMFuncs.h:26
bool getFragmentEdgeID(unsigned int elem_edge_id, unsigned int &frag_edge_id) const
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:177
void addEdgeCut(unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode * > &EmbeddedNodes, bool add_to_neighbor)
unsigned int numEdgeNeighbors(unsigned int edge_id) const
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition: EFAFuncs.h:37
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition: EFAEdge.C:128
bool EFAElement2D::addFragmentEdgeCut ( unsigned int  frag_edge_id,
double  position,
std::map< unsigned int, EFANode * > &  EmbeddedNodes 
)

Definition at line 1836 of file EFAElement2D.C.

Referenced by ElementFragmentAlgorithm::addFragEdgeIntersection().

1839 {
1840  if (_fragments.size() != 1)
1841  EFAError("Element: ", _id, " should have only 1 fragment in addFragEdgeIntersection");
1842  EFANode * local_embedded = NULL;
1843 
1844  // check if this intersection coincide with any embedded node on this edge
1845  bool isValidIntersection = true;
1846  EFAEdge * frag_edge = getFragmentEdge(0, frag_edge_id); // we're considering this edge
1847  EFANode * edge_node1 = frag_edge->getNode(0);
1848  EFANode * edge_node2 = frag_edge->getNode(1);
1849  if ((std::abs(position) < Xfem::tol && edge_node1->category() == EFANode::N_CATEGORY_EMBEDDED) ||
1850  (std::abs(1.0 - position) < Xfem::tol &&
1851  edge_node2->category() == EFANode::N_CATEGORY_EMBEDDED))
1852  isValidIntersection = false;
1853 
1854  // TODO: do not allow to cut fragment's node
1855  if (std::abs(position) < Xfem::tol || std::abs(1.0 - position) < Xfem::tol)
1856  isValidIntersection = false;
1857 
1858  // add valid intersection point to an edge
1859  if (isValidIntersection)
1860  {
1861  if (frag_edge->hasIntersection())
1862  {
1863  if (!frag_edge->hasIntersectionAtPosition(position, edge_node1))
1864  EFAError("Attempting to add fragment edge intersection when one already exists with "
1865  "different position.",
1866  " elem: ",
1867  _id,
1868  " edge: ",
1869  frag_edge_id,
1870  " position: ",
1871  position,
1872  " old position: ",
1873  frag_edge->getIntersection(0, edge_node1));
1874  }
1875  else // blank edge - in fact, it can only be a blank element interior edge
1876  {
1877  if (!_fragments[0]->isEdgeInterior(frag_edge_id) ||
1878  _fragments[0]->isSecondaryInteriorEdge(frag_edge_id))
1879  EFAError("Attemping to add intersection to an invalid fragment edge. Element: ",
1880  _id,
1881  " fragment_edge: ",
1882  frag_edge_id);
1883 
1884  // create the embedded node and add it to the fragment's boundary edge
1885  unsigned int new_node_id = Efa::getNewID(EmbeddedNodes);
1886  local_embedded = new EFANode(new_node_id, EFANode::N_CATEGORY_EMBEDDED);
1887  EmbeddedNodes.insert(std::make_pair(new_node_id, local_embedded));
1888  frag_edge->addIntersection(position, local_embedded, edge_node1);
1889 
1890  // save this interior embedded node to FaceNodes
1891  // TODO: for unstructured elements, the following calution gives you inaccurate position of
1892  // face nodes
1893  // must solve this issue for 3D!
1894  std::vector<double> node1_para_coor(2, 0.0);
1895  std::vector<double> node2_para_coor(2, 0.0);
1896  if (getEdgeNodeParametricCoordinate(edge_node1, node1_para_coor) &&
1897  getEdgeNodeParametricCoordinate(edge_node2, node2_para_coor))
1898  {
1899  double xi = (1.0 - position) * node1_para_coor[0] + position * node2_para_coor[0];
1900  double eta = (1.0 - position) * node1_para_coor[1] + position * node2_para_coor[1];
1901  _interior_nodes.push_back(new EFAFaceNode(local_embedded, xi, eta));
1902  }
1903  else
1904  EFAError("elem: ", _id, " cannot get the parametric coords of two end embedded nodes");
1905  }
1906  // no need to add intersection for neighbor fragment - if this fragment has a
1907  // neighbor fragment, the neighbor has already been treated in addEdgeIntersection;
1908  // for an interior edge, there is no neighbor fragment
1909  }
1910 
1911  return isValidIntersection;
1912 }
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
unsigned int _id
Definition: EFAElement.h:26
bool getEdgeNodeParametricCoordinate(EFANode *node, std::vector< double > &para_coor) const
bool hasIntersectionAtPosition(double position, EFANode *from_node) const
Definition: EFAEdge.C:209
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
N_CATEGORY category() const
Definition: EFANode.C:40
static const double tol
Definition: XFEMFuncs.h:26
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:177
bool hasIntersection() const
Definition: EFAEdge.C:196
double getIntersection(unsigned int emb_id, EFANode *from_node) const
Definition: EFAEdge.C:235
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition: EFAFuncs.h:37
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition: EFAEdge.C:128
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement2D::addNodeCut ( unsigned int  node_id,
EFANode embedded_permanent_node,
std::map< unsigned int, EFANode * > &  PermanentNodes,
std::map< unsigned int, EFANode * > &  EmbeddedPermanentNodes 
)

Definition at line 1813 of file EFAElement2D.C.

Referenced by ElementFragmentAlgorithm::addElemNodeIntersection().

1817 {
1818  EFANode * local_embedded_permanent = NULL;
1819  EFANode * node = _nodes[node_id];
1820  if (embedded_permanent_node) // use the existing embedded node if it was passed in
1821  local_embedded_permanent = embedded_permanent_node;
1822 
1823  if (node->category() == EFANode::N_CATEGORY_PERMANENT)
1824  {
1826  local_embedded_permanent = node;
1827  EmbeddedPermanentNodes.insert(std::make_pair(node->id(), local_embedded_permanent));
1828  if (!Efa::deleteFromMap(PermanentNodes, local_embedded_permanent, false))
1829  EFAError("Attempted to delete node: ",
1830  local_embedded_permanent->id(),
1831  " from PermanentNodes, but couldn't find it");
1832  }
1833 }
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:21
N_CATEGORY category() const
Definition: EFANode.C:40
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
void setCategory(EFANode::N_CATEGORY category)
Definition: EFANode.C:58
unsigned int id() const
Definition: EFANode.C:34
std::vector< EFAFragment2D * > EFAElement2D::branchingSplit ( std::map< unsigned int, EFANode * > &  EmbeddedNodes)

Definition at line 1915 of file EFAElement2D.C.

Referenced by updateFragments().

1916 {
1917  if (isPartial())
1918  EFAError("branching is only allowed for an uncut element");
1919 
1920  // collect all emb nodes counterclockwise
1921  std::vector<EFANode *> three_nodes;
1922  for (unsigned int i = 0; i < _edges.size(); ++i)
1923  {
1924  EFANode * node1 = _edges[i]->getNode(0);
1925  if (_edges[i]->numEmbeddedNodes() == 1)
1926  three_nodes.push_back(_edges[i]->getEmbeddedNode(0));
1927  else if (_edges[i]->numEmbeddedNodes() == 2)
1928  {
1929  unsigned int id0(
1930  _edges[i]->getIntersection(0, node1) < _edges[i]->getIntersection(1, node1) ? 0 : 1);
1931  unsigned int id1 = 1 - id0;
1932  three_nodes.push_back(_edges[i]->getEmbeddedNode(id0));
1933  three_nodes.push_back(_edges[i]->getEmbeddedNode(id1));
1934  }
1935  }
1936  if (three_nodes.size() != 3)
1937  EFAError("three_nodes.size() != 3");
1938 
1939  // get the parent coords of the braycenter of the three nodes
1940  // TODO: may need a better way to compute this "branching point"
1941  std::vector<double> center_xi(2, 0.0);
1942  for (unsigned int i = 0; i < 3; ++i)
1943  {
1944  std::vector<double> xi_2d(2, 0.0);
1945  getEdgeNodeParametricCoordinate(three_nodes[i], xi_2d);
1946  center_xi[0] += xi_2d[0];
1947  center_xi[1] += xi_2d[1];
1948  }
1949  center_xi[0] /= 3.0;
1950  center_xi[1] /= 3.0;
1951 
1952  // create a new interior node for current element
1953  unsigned int new_node_id = Efa::getNewID(EmbeddedNodes);
1954  EFANode * new_emb = new EFANode(new_node_id, EFANode::N_CATEGORY_EMBEDDED);
1955  EmbeddedNodes.insert(std::make_pair(new_node_id, new_emb));
1956  _interior_nodes.push_back(new EFAFaceNode(new_emb, center_xi[0], center_xi[1]));
1957 
1958  // generate the three fragments
1959  std::vector<EFAFragment2D *> new_fragments;
1960  for (unsigned int i = 0; i < 3; ++i) // loop over 3 sectors
1961  {
1962  EFAFragment2D * new_frag = new EFAFragment2D(this, false, NULL);
1963  unsigned int iplus1(i < 2 ? i + 1 : 0);
1964  new_frag->addEdge(new EFAEdge(three_nodes[iplus1], new_emb));
1965  new_frag->addEdge(new EFAEdge(new_emb, three_nodes[i]));
1966 
1967  unsigned int iedge = 0;
1968  bool add_more_edges = true;
1969  for (unsigned int j = 0; j < _edges.size(); ++j)
1970  {
1971  if (_edges[j]->containsNode(three_nodes[i]))
1972  {
1973  if (_edges[j]->containsNode(three_nodes[iplus1]))
1974  {
1975  new_frag->addEdge(new EFAEdge(three_nodes[i], three_nodes[iplus1]));
1976  add_more_edges = false;
1977  }
1978  else
1979  {
1980  new_frag->addEdge(new EFAEdge(three_nodes[i], _edges[j]->getNode(1)));
1981  }
1982  iedge = j;
1983  break;
1984  }
1985  } // j
1986  while (add_more_edges)
1987  {
1988  iedge += 1;
1989  if (iedge == _edges.size())
1990  iedge = 0;
1991  if (_edges[iedge]->containsNode(three_nodes[iplus1]))
1992  {
1993  new_frag->addEdge(new EFAEdge(_edges[iedge]->getNode(0), three_nodes[iplus1]));
1994  add_more_edges = false;
1995  }
1996  else
1997  new_frag->addEdge(new EFAEdge(_edges[iedge]->getNode(0), _edges[iedge]->getNode(1)));
1998  }
1999  new_fragments.push_back(new_frag);
2000  } // i
2001  return new_fragments;
2002 }
virtual bool isPartial() const
Definition: EFAElement2D.C:206
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
void addEdge(EFAEdge *new_edge)
bool getEdgeNodeParametricCoordinate(EFANode *node, std::vector< double > &para_coor) const
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition: EFAFuncs.h:37
void EFAElement2D::clearNeighbors ( )
virtual

Implements EFAElement.

Definition at line 457 of file EFAElement2D.C.

458 {
459  _general_neighbors.clear();
460  for (unsigned int edge_iter = 0; edge_iter < _num_edges; ++edge_iter)
461  _edge_neighbors[edge_iter] = std::vector<EFAElement2D *>(1, NULL);
462 }
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:35
void EFAElement::clearParentAndChildren ( )
inherited

Definition at line 207 of file EFAElement.C.

Referenced by ElementFragmentAlgorithm::clearAncestry().

208 {
209  _parent = NULL;
210  _children.clear();
211 }
EFAElement * _parent
Definition: EFAElement.h:30
std::vector< EFAElement * > _children
Definition: EFAElement.h:31
void EFAElement2D::connectNeighbors ( std::map< unsigned int, EFANode * > &  PermanentNodes,
std::map< unsigned int, EFANode * > &  TempNodes,
std::map< EFANode *, std::set< EFAElement * >> &  InverseConnectivityMap,
bool  merge_phantom_edges 
)
virtual

Implements EFAElement.

Definition at line 1170 of file EFAElement2D.C.

1174 {
1175  // N.B. "this" must point to a child element that was just created
1176  if (!_parent)
1177  EFAError("no parent element for child element ", _id, " in connect_neighbors");
1178  EFAElement2D * parent2d = dynamic_cast<EFAElement2D *>(_parent);
1179  if (!parent2d)
1180  EFAError("cannot dynamic cast to parent2d in connect_neighbors");
1181 
1182  // First loop through edges and merge nodes with neighbors as appropriate
1183  for (unsigned int j = 0; j < _num_edges; ++j)
1184  {
1185  for (unsigned int k = 0; k < parent2d->numEdgeNeighbors(j); ++k)
1186  {
1187  EFAElement2D * NeighborElem = parent2d->getEdgeNeighbor(j, k);
1188  unsigned int neighbor_edge_id = NeighborElem->getNeighborIndex(parent2d);
1189 
1190  if (_edges[j]->hasIntersection())
1191  {
1192  for (unsigned int l = 0; l < NeighborElem->numChildren(); ++l)
1193  {
1194  EFAElement2D * childOfNeighborElem =
1195  dynamic_cast<EFAElement2D *>(NeighborElem->getChild(l));
1196  if (!childOfNeighborElem)
1197  EFAError("dynamic cast childOfNeighborElem fails");
1198 
1199  // Check to see if the nodes are already merged. There's nothing else to do in that case.
1200  EFAEdge * neighborChildEdge = childOfNeighborElem->getEdge(neighbor_edge_id);
1201  if (_edges[j]->equivalent(*neighborChildEdge))
1202  continue;
1203 
1204  if (_fragments[0]->isConnected(childOfNeighborElem->getFragment(0)))
1205  {
1206  unsigned int num_edge_nodes = 2;
1207  for (unsigned int i = 0; i < num_edge_nodes; ++i)
1208  {
1209  unsigned int childNodeIndex = i;
1210  unsigned int neighborChildNodeIndex = num_edge_nodes - 1 - childNodeIndex;
1211 
1212  EFANode * childNode = _edges[j]->getNode(childNodeIndex);
1213  EFANode * childOfNeighborNode = neighborChildEdge->getNode(neighborChildNodeIndex);
1214 
1215  mergeNodes(
1216  childNode, childOfNeighborNode, childOfNeighborElem, PermanentNodes, TempNodes);
1217  }
1218 
1219  EFANode * childNode = _edges[j]->getInteriorNode();
1220  EFANode * childOfNeighborNode = neighborChildEdge->getInteriorNode();
1221 
1222  mergeNodes(
1223  childNode, childOfNeighborNode, childOfNeighborElem, PermanentNodes, TempNodes);
1224  }
1225  } // l, loop over NeighborElem's children
1226  }
1227  else // No edge intersection -- optionally merge non-material nodes if they share a common
1228  // parent
1229  {
1230  if (merge_phantom_edges)
1231  {
1232  for (unsigned int l = 0; l < NeighborElem->numChildren(); ++l)
1233  {
1234  EFAElement2D * childOfNeighborElem =
1235  dynamic_cast<EFAElement2D *>(NeighborElem->getChild(l));
1236  if (!childOfNeighborElem)
1237  EFAError("dynamic cast childOfNeighborElem fails");
1238 
1239  EFAEdge * neighborChildEdge = childOfNeighborElem->getEdge(neighbor_edge_id);
1240  if (!neighborChildEdge->hasIntersection()) // neighbor edge must NOT have
1241  // intersection either
1242  {
1243  // Check to see if the nodes are already merged. There's nothing else to do in that
1244  // case.
1245  unsigned int num_edge_nodes = 2;
1246  for (unsigned int i = 0; i < num_edge_nodes; ++i)
1247  {
1248  unsigned int childNodeIndex = i;
1249  unsigned int neighborChildNodeIndex = num_edge_nodes - 1 - childNodeIndex;
1250 
1251  EFANode * childNode = _edges[j]->getNode(childNodeIndex);
1252  EFANode * childOfNeighborNode = neighborChildEdge->getNode(neighborChildNodeIndex);
1253 
1254  if (childNode->parent() != NULL &&
1255  childNode->parent() ==
1256  childOfNeighborNode
1257  ->parent()) // non-material node and both come from same parent
1258  mergeNodes(childNode,
1259  childOfNeighborNode,
1260  childOfNeighborElem,
1261  PermanentNodes,
1262  TempNodes);
1263  } // i
1264  }
1265  } // loop over NeighborElem's children
1266  } // if (merge_phantom_edges)
1267  } // IF edge-j has_intersection()
1268  } // k, loop over neighbors on edge j
1269  } // j, loop over all edges
1270 
1271  // Now do a second loop through edges and convert remaining nodes to permanent nodes.
1272  // Important: temp nodes are not shared by any neighbor, so no need to switch nodes on neighbors
1273  for (unsigned int j = 0; j < _num_nodes; ++j)
1274  {
1275  EFANode * childNode = _nodes[j];
1276  if (childNode->category() == EFANode::N_CATEGORY_TEMP)
1277  {
1278  // if current child element does not have siblings, and if current temp node is a lone one
1279  // this temp node should be merged back to its parent permanent node. Otherwise we would have
1280  // permanent nodes that are not connected to any element
1281  std::set<EFAElement *> patch_elems = InverseConnectivityMap[childNode->parent()];
1282  if (parent2d->numFragments() == 1 && patch_elems.size() == 1)
1283  switchNode(childNode->parent(), childNode, false);
1284  else
1285  {
1286  unsigned int new_node_id = Efa::getNewID(PermanentNodes);
1287  EFANode * newNode =
1288  new EFANode(new_node_id, EFANode::N_CATEGORY_PERMANENT, childNode->parent());
1289  PermanentNodes.insert(std::make_pair(new_node_id, newNode));
1290  switchNode(newNode, childNode, false);
1291  }
1292  if (!Efa::deleteFromMap(TempNodes, childNode))
1293  EFAError(
1294  "Attempted to delete node: ", childNode->id(), " from TempNodes, but couldn't find it");
1295  }
1296  }
1297 }
EFAFragment2D * getFragment(unsigned int frag_id) const
EFANode * parent() const
Definition: EFANode.C:46
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
Definition: EFAElement2D.C:445
unsigned int _id
Definition: EFAElement.h:26
unsigned int numChildren() const
Definition: EFAElement.C:195
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:21
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
EFAElement2D * getEdgeNeighbor(unsigned int edge_id, unsigned int neighbor_id) const
EFANode * getInteriorNode() const
Definition: EFAEdge.h:43
N_CATEGORY category() const
Definition: EFANode.C:40
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement2D.C:260
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
EFAElement * _parent
Definition: EFAElement.h:30
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:177
bool hasIntersection() const
Definition: EFAEdge.C:196
unsigned int id() const
Definition: EFANode.C:34
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
unsigned int numEdgeNeighbors(unsigned int edge_id) const
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition: EFAFuncs.h:37
void mergeNodes(EFANode *&childNode, EFANode *&childOfNeighborNode, EFAElement *childOfNeighborElem, std::map< unsigned int, EFANode * > &PermanentNodes, std::map< unsigned int, EFANode * > &TempNodes)
Definition: EFAElement.C:246
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFAElement * getChild(unsigned int child_id) const
Definition: EFAElement.C:180
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
bool EFAElement::containsNode ( EFANode node) const
inherited
void EFAElement2D::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 984 of file EFAElement2D.C.

990 {
991  if (_children.size() != 0)
992  EFAError("Element cannot have existing children in createChildElements");
993 
994  bool shouldDuplicateForCutNodeElement = false;
995  for (unsigned int j = 0; j < _num_nodes; ++j)
996  {
997  if (_nodes[j]->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
998  shouldDuplicateForCutNodeElement = true;
999  }
1000 
1001  if (_fragments.size() > 1 || shouldDuplicateForCrackTip(CrackTipElements) ||
1002  shouldDuplicateForCutNodeElement)
1003  {
1004  if (_fragments.size() > 3)
1005  EFAError("More than 3 fragments not yet supported");
1006 
1007  // set up the children
1008  ParentElements.push_back(this);
1009  for (unsigned int ichild = 0; ichild < _fragments.size(); ++ichild)
1010  {
1011  unsigned int new_elem_id;
1012  if (newChildElements.size() == 0)
1013  new_elem_id = Efa::getNewID(Elements);
1014  else
1015  new_elem_id = Efa::getNewID(newChildElements);
1016 
1017  EFAElement2D * childElem = new EFAElement2D(new_elem_id, this->numNodes());
1018  newChildElements.insert(std::make_pair(new_elem_id, childElem));
1019 
1020  ChildElements.push_back(childElem);
1021  childElem->setParent(this);
1022  _children.push_back(childElem);
1023 
1024  std::vector<EFAPoint> local_embedded_node_coor;
1025 
1026  for (unsigned int i = 0; i < this->getFragment(ichild)->numEdges(); ++i)
1027  {
1028  if (this->getFragment(ichild)->isEdgeInterior(i))
1029  {
1030  std::vector<EFANode *> master_nodes;
1031  std::vector<double> master_weights;
1032 
1033  for (unsigned int j = 0; j < 2; ++j)
1034  {
1035  this->getMasterInfo(
1036  this->getFragmentEdge(ichild, i)->getNode(j), master_nodes, master_weights);
1037  EFAPoint coor(0.0, 0.0, 0.0);
1038  for (unsigned int k = 0; k < master_nodes.size(); ++k)
1039  {
1040  EFANode * local = this->createLocalNodeFromGlobalNode(master_nodes[k]);
1041  coor += _local_node_coor[local->id()] * master_weights[k];
1042  delete local;
1043  }
1044  local_embedded_node_coor.push_back(coor);
1045  }
1046  }
1047  }
1048 
1049  EFAPoint normal(0.0, 0.0, 0.0);
1050  EFAPoint origin(0.0, 0.0, 0.0);
1051  EFAPoint normal2(0.0, 0.0, 0.0);
1052  EFAPoint origin2(0.0, 0.0, 0.0);
1053 
1054  if (local_embedded_node_coor.size())
1055  {
1056  EFAPoint cut_line = local_embedded_node_coor[1] - local_embedded_node_coor[0];
1057  normal = EFAPoint(cut_line(1), -cut_line(0), 0.0);
1058  Xfem::normalizePoint(normal);
1059  origin = (local_embedded_node_coor[0] + local_embedded_node_coor[1]) * 0.5;
1060  }
1061 
1062  if (local_embedded_node_coor.size() == 4)
1063  {
1064  EFAPoint cut_line = local_embedded_node_coor[3] - local_embedded_node_coor[2];
1065  normal2 = EFAPoint(cut_line(1), -cut_line(0), 0.0);
1066  Xfem::normalizePoint(normal2);
1067  origin2 = (local_embedded_node_coor[2] + local_embedded_node_coor[3]) * 0.5;
1068  }
1069 
1070  // get child element's nodes
1071  for (unsigned int j = 0; j < _num_nodes; ++j)
1072  {
1073  EFAPoint p(0.0, 0.0, 0.0);
1074  p = _local_node_coor[j];
1075 
1076  EFAPoint origin_to_point = p - origin;
1077  EFAPoint origin2_to_point = p - origin2;
1078 
1079  if (_fragments.size() == 1 &&
1080  _nodes[j]->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT) // create temp node for
1081  // embedded permanent
1082  // node
1083  {
1084  unsigned int new_node_id = Efa::getNewID(TempNodes);
1085  EFANode * newNode = new EFANode(new_node_id, EFANode::N_CATEGORY_TEMP, _nodes[j]);
1086  TempNodes.insert(std::make_pair(new_node_id, newNode));
1087  childElem->setNode(j, newNode); // be a temp node
1088  }
1089  else if (_fragments.size() == 1 && !shouldDuplicateForCrackTip(CrackTipElements))
1090  {
1091  childElem->setNode(j, _nodes[j]); // inherit parent's node
1092  }
1093  else if (std::abs(origin_to_point * normal) < Xfem::tol &&
1094  _fragments.size() > 1) // cut through node case
1095  {
1096  unsigned int new_node_id = Efa::getNewID(TempNodes);
1097  EFANode * newNode = new EFANode(new_node_id, EFANode::N_CATEGORY_TEMP, _nodes[j]);
1098  TempNodes.insert(std::make_pair(new_node_id, newNode));
1099  childElem->setNode(j, newNode); // be a temp node
1100  }
1101  else if (origin_to_point * normal < Xfem::tol && origin2_to_point * normal2 < Xfem::tol &&
1102  (_fragments.size() > 1 || shouldDuplicateForCrackTip(CrackTipElements)))
1103  {
1104  childElem->setNode(j, _nodes[j]); // inherit parent's node
1105  }
1106  else if (normal.norm() < Xfem::tol && normal2.norm() < Xfem::tol &&
1107  _fragments.size() == 1) // cut along edge case
1108  {
1109  childElem->setNode(j, _nodes[j]); // inherit parent's node
1110  }
1111  else if ((_fragments.size() > 1 ||
1113  CrackTipElements))) // parent element's node is not in fragment
1114  {
1115  unsigned int new_node_id = Efa::getNewID(TempNodes);
1116  EFANode * newNode = new EFANode(new_node_id, EFANode::N_CATEGORY_TEMP, _nodes[j]);
1117  TempNodes.insert(std::make_pair(new_node_id, newNode));
1118  childElem->setNode(j, newNode); // be a temp node
1119  }
1120  }
1121 
1122  // get child element's fragments
1123  EFAFragment2D * new_frag = new EFAFragment2D(childElem, true, this, ichild);
1124  childElem->_fragments.push_back(new_frag);
1125 
1126  // get child element's edges
1127  for (unsigned int j = 0; j < _num_edges; ++j)
1128  {
1129  unsigned int jplus1(j < (_num_edges - 1) ? j + 1 : 0);
1130  EFAEdge * new_edge = new EFAEdge(childElem->getNode(j), childElem->getNode(jplus1));
1131  if (_edges[j]->hasIntersection())
1132  new_edge->copyIntersection(*_edges[j], 0);
1133  if ((_num_edges == 4 && _num_nodes > 4) || (_num_edges == 3 && _num_nodes > 3))
1134  new_edge->setInteriorNode(childElem->getNode(_num_edges + j));
1135  childElem->setEdge(j, new_edge);
1136  }
1137  childElem->removePhantomEmbeddedNode(); // IMPORTANT
1138 
1139  // inherit old interior nodes
1140  for (unsigned int j = 0; j < _interior_nodes.size(); ++j)
1141  childElem->_interior_nodes.push_back(new EFAFaceNode(*_interior_nodes[j]));
1142  }
1143  }
1144  else // num_links == 1 || num_links == 0
1145  // child is itself - but don't insert into the list of ChildElements!!!
1146  _children.push_back(this);
1147 }
unsigned int numEdges() const
EFAFragment2D * getFragment(unsigned int frag_id) const
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
virtual void getMasterInfo(EFANode *node, std::vector< EFANode * > &master_nodes, std::vector< double > &master_weights) const
Definition: EFAElement2D.C:298
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
void setEdge(unsigned int edge_id, EFAEdge *edge)
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
unsigned int numNodes() const
Definition: EFAElement.C:32
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
void setParent(EFAElement *parent)
Definition: EFAElement.C:189
unsigned int _num_nodes
Definition: EFAElement.h:27
bool isEdgeInterior(unsigned int edge_id) const
virtual void removePhantomEmbeddedNode()
void setInteriorNode(EFANode *node)
Definition: EFAEdge.h:44
static const double tol
Definition: XFEMFuncs.h:26
void copyIntersection(const EFAEdge &other, unsigned int from_node_id)
Definition: EFAEdge.C:158
std::vector< EFAPoint > _local_node_coor
Definition: EFAElement2D.h:34
unsigned int id() const
Definition: EFANode.C:34
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition: EFAFuncs.h:37
void normalizePoint(Point &p)
Definition: XFEMFuncs.C:628
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAElement * > _children
Definition: EFAElement.h:31
EFAElement2D(unsigned int eid, unsigned int n_nodes)
Definition: EFAElement2D.C:21
virtual bool shouldDuplicateForCrackTip(const std::set< EFAElement * > &CrackTipElements)
Definition: EFAElement2D.C:613
EFANode * createLocalNodeFromGlobalNode(const EFANode *global_node) const
Definition: EFAElement.C:68
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:38
void EFAElement2D::createEdges ( )

Definition at line 1458 of file EFAElement2D.C.

Referenced by ElementFragmentAlgorithm::add2DElement(), and ElementFragmentAlgorithm::add2DElements().

1459 {
1460  for (unsigned int i = 0; i < _num_edges; ++i)
1461  {
1462  unsigned int i_plus1(i < (_num_edges - 1) ? i + 1 : 0);
1463  EFAEdge * new_edge = new EFAEdge(_nodes[i], _nodes[i_plus1]);
1464 
1465  if ((_num_edges == 4 && _num_nodes > 4) || (_num_edges == 3 && _num_nodes > 3))
1466  new_edge->setInteriorNode(
1467  _nodes[i + _num_edges]); // '_num_edges' is the offset of interior edge node numbering
1468 
1469  _edges[i] = new_edge;
1470  }
1471 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
void setInteriorNode(EFANode *node)
Definition: EFAEdge.h:44
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFANode * EFAElement::createLocalNodeFromGlobalNode ( const EFANode global_node) const
inherited

Definition at line 68 of file EFAElement.C.

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

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

Definition at line 1438 of file EFAElement2D.C.

Referenced by EFAFragment2D::removeInvalidEmbeddedNodes().

1439 {
1440  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
1441  delete _interior_nodes[i];
1442  _interior_nodes.clear();
1443 }
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
bool EFAElement2D::edgeContainsTip ( unsigned int  edge_id) const

Definition at line 1668 of file EFAElement2D.C.

Referenced by fragmentEdgeAlreadyCut().

1669 {
1670  bool contains_tip = false;
1671  if (_fragments.size() == 1)
1672  {
1673  unsigned int num_frag_edges = 0; // count how many fragment edges this element edge contains
1674  if (_edges[edge_id]->hasIntersection())
1675  {
1676  for (unsigned int j = 0; j < _fragments[0]->numEdges(); ++j)
1677  {
1678  if (_edges[edge_id]->containsEdge(*_fragments[0]->getEdge(j)))
1679  num_frag_edges += 1;
1680  } // j
1681  if (num_frag_edges == 2)
1682  contains_tip = true;
1683  }
1684  }
1685  return contains_tip;
1686 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement::findGeneralNeighbors ( std::map< EFANode *, std::set< EFAElement * >> &  InverseConnectivity)
inherited

Definition at line 214 of file EFAElement.C.

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

215 {
216  _general_neighbors.clear();
217  std::set<EFAElement *> patch_elements;
218  for (unsigned int inode = 0; inode < _num_nodes; ++inode)
219  {
220  std::set<EFAElement *> this_node_connected_elems = InverseConnectivity[_nodes[inode]];
221  patch_elements.insert(this_node_connected_elems.begin(), this_node_connected_elems.end());
222  }
223 
224  std::set<EFAElement *>::iterator eit2;
225  for (eit2 = patch_elements.begin(); eit2 != patch_elements.end(); ++eit2)
226  {
227  EFAElement * neigh_elem = *eit2;
228  if (neigh_elem != this)
229  _general_neighbors.push_back(neigh_elem);
230  }
231 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:35
bool EFAElement2D::fragmentEdgeAlreadyCut ( unsigned int  ElemEdgeID) const

Definition at line 1689 of file EFAElement2D.C.

Referenced by addEdgeCut().

1690 {
1691  // when marking cuts, check if the corresponding frag edge already has been cut
1692  bool has_cut = false;
1693  if (edgeContainsTip(ElemEdgeID))
1694  has_cut = true;
1695  else
1696  {
1697  unsigned int FragEdgeID = 99999;
1698  if (getFragmentEdgeID(ElemEdgeID, FragEdgeID))
1699  {
1700  EFAEdge * frag_edge = getFragmentEdge(0, FragEdgeID);
1701  if (frag_edge->hasIntersection())
1702  has_cut = true;
1703  }
1704  }
1705  return has_cut;
1706 }
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
bool edgeContainsTip(unsigned int edge_id) const
bool getFragmentEdgeID(unsigned int elem_edge_id, unsigned int &frag_edge_id) const
bool hasIntersection() const
Definition: EFAEdge.C:196
bool EFAElement2D::fragmentHasTipEdges ( ) const

Definition at line 1580 of file EFAElement2D.C.

Referenced by isCrackTipElement().

1581 {
1582  bool has_tip_edges = false;
1583  if (_fragments.size() == 1)
1584  {
1585  for (unsigned int i = 0; i < _num_edges; ++i)
1586  {
1587  unsigned int num_frag_edges = 0; // count how many fragment edges this element edge contains
1588  if (_edges[i]->hasIntersection())
1589  {
1590  for (unsigned int j = 0; j < _fragments[0]->numEdges(); ++j)
1591  {
1592  if (_edges[i]->containsEdge(*_fragments[0]->getEdge(j)))
1593  num_frag_edges += 1;
1594  } // j
1595  if (num_frag_edges == 2)
1596  {
1597  has_tip_edges = true;
1598  break;
1599  }
1600  }
1601  } // i
1602  }
1603  return has_tip_edges;
1604 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement2D::fragmentSanityCheck ( unsigned int  n_old_frag_edges,
unsigned int  n_old_frag_cuts 
) const
virtual

Implements EFAElement.

Definition at line 869 of file EFAElement2D.C.

Referenced by updateFragments().

870 {
871  if (n_old_frag_cuts > 3)
872  EFAError("Sanity check: in element ", _id, " frag has more than 3 cut edges");
873 
874  // count permanent and embedded nodes for new fragments
875  std::vector<unsigned int> num_emb;
876  std::vector<unsigned int> num_perm;
877  std::vector<unsigned int> num_emb_perm;
878  for (unsigned int i = 0; i < _fragments.size(); ++i)
879  {
880  num_emb.push_back(0);
881  num_perm.push_back(0);
882  num_emb_perm.push_back(0);
883  std::set<EFANode *> perm_nodes;
884  std::set<EFANode *> emb_nodes;
885  std::set<EFANode *> emb_perm_nodes;
886  for (unsigned int j = 0; j < _fragments[i]->numEdges(); ++j)
887  {
888  for (unsigned int k = 0; k < 2; ++k)
889  {
890  EFANode * temp_node = _fragments[i]->getEdge(j)->getNode(k);
891  if (temp_node->category() == EFANode::N_CATEGORY_PERMANENT)
892  perm_nodes.insert(temp_node);
893  else if (temp_node->category() == EFANode::N_CATEGORY_EMBEDDED)
894  emb_nodes.insert(temp_node);
895  else if (temp_node->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
896  emb_perm_nodes.insert(temp_node);
897  else
898  EFAError("Invalid node category");
899  }
900  }
901  num_perm[i] = perm_nodes.size();
902  num_emb[i] = emb_nodes.size();
903  num_emb_perm[i] = emb_perm_nodes.size();
904  }
905 
906  // TODO: For cut-node case, how to check fragment sanity
907  for (unsigned int i = 0; i < _fragments.size(); ++i)
908  if (num_emb_perm[i] != 0)
909  return;
910 
911  unsigned int n_interior_nodes = numInteriorNodes();
912  if (n_interior_nodes > 0 && n_interior_nodes != 1)
913  EFAError("After update_fragments this element has ", n_interior_nodes, " interior nodes");
914 
915  if (n_old_frag_cuts == 0)
916  {
917  if (_fragments.size() != 1 || _fragments[0]->numEdges() != n_old_frag_edges)
918  EFAError("Incorrect link size for element with 0 cuts");
919  }
920  else if (n_old_frag_cuts == 1) // crack tip case
921  {
922  if (_fragments.size() != 1 || _fragments[0]->numEdges() != n_old_frag_edges + 1)
923  EFAError("Incorrect link size for element with 1 cut");
924  }
925  else if (n_old_frag_cuts == 2)
926  {
927  if (_fragments.size() != 2 ||
928  (_fragments[0]->numEdges() + _fragments[1]->numEdges()) != n_old_frag_edges + 4)
929  EFAError("Incorrect link size for element with 2 cuts");
930  }
931  else if (n_old_frag_cuts == 3)
932  {
933  if (_fragments.size() != 3 ||
934  (_fragments[0]->numEdges() + _fragments[1]->numEdges() + _fragments[2]->numEdges()) !=
935  n_old_frag_edges + 9)
936  EFAError("Incorrect link size for element with 3 cuts");
937  }
938  else
939  EFAError("Unexpected number of old fragment cuts");
940 }
unsigned int _id
Definition: EFAElement.h:26
virtual unsigned int numInteriorNodes() const
Definition: EFAElement2D.C:351
N_CATEGORY category() const
Definition: EFANode.C:40
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
EFAElement * EFAElement::getChild ( unsigned int  child_id) const
inherited

Definition at line 180 of file EFAElement.C.

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

181 {
182  if (child_id < _children.size())
183  return _children[child_id];
184  else
185  EFAError("child_id out of bounds");
186 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:31
std::vector< EFANode * > EFAElement2D::getCommonNodes ( const EFAElement2D other_elem) const

Definition at line 2060 of file EFAElement2D.C.

Referenced by overlaysElement(), and setupNeighbors().

2061 {
2062  std::set<EFANode *> e1nodes(_nodes.begin(),
2063  _nodes.begin() + _num_edges); // only account for corner nodes
2064  std::set<EFANode *> e2nodes(other_elem->_nodes.begin(), other_elem->_nodes.begin() + _num_edges);
2065  std::vector<EFANode *> common_nodes = Efa::getCommonElems(e1nodes, e2nodes);
2066  return common_nodes;
2067 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
std::vector< T > getCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:68
unsigned int _num_edges
Definition: EFAElement2D.h:29
unsigned int EFAElement::getCrackTipNeighbor ( unsigned int  index) const
inherited

Definition at line 146 of file EFAElement.C.

147 {
148  if (index < _crack_tip_neighbors.size())
149  return _crack_tip_neighbors[index];
150  else
151  EFAError("in getCrackTipNeighbor index out of bounds");
152 }
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:33
unsigned int EFAElement2D::getCrackTipSplitElementID ( ) const

Definition at line 592 of file EFAElement2D.C.

Referenced by XFEM::storeCrackTipOriginAndDirection().

593 {
594  if (isCrackTipElement())
595  {
596  for (unsigned int edge_iter = 0; edge_iter < _num_edges; ++edge_iter)
597  {
598  if ((_edge_neighbors[edge_iter].size() == 2) && (_edges[edge_iter]->hasIntersection()))
599  {
600  if (_edge_neighbors[edge_iter][0] != NULL &&
601  _edge_neighbors[edge_iter][0]->isCrackTipSplit())
602  {
603  return _edge_neighbors[edge_iter][0]->id();
604  }
605  }
606  }
607  }
608  EFAError("In getCrackTipSplitElementID could not find element id");
609  return 0;
610 }
bool isCrackTipSplit() const
Definition: EFAElement.C:134
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
virtual bool isCrackTipElement() const
Definition: EFAElement2D.C:773
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFAEdge * EFAElement2D::getEdge ( unsigned int  edge_id) const
EFAElement2D * EFAElement2D::getEdgeNeighbor ( unsigned int  edge_id,
unsigned int  neighbor_id 
) const

Definition at line 1571 of file EFAElement2D.C.

Referenced by addEdgeCut(), connectNeighbors(), neighborSanityCheck(), and printElement().

1572 {
1573  if (_edge_neighbors[edge_id][0] != NULL && neighbor_id < _edge_neighbors[edge_id].size())
1574  return _edge_neighbors[edge_id][neighbor_id];
1575  else
1576  EFAError("edge neighbor does not exist");
1577 }
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
bool EFAElement2D::getEdgeNodeParametricCoordinate ( EFANode node,
std::vector< double > &  para_coor 
) const

Definition at line 1405 of file EFAElement2D.C.

Referenced by addFragmentEdgeCut(), and branchingSplit().

1406 {
1407  // get the parametric coords of a node in an element edge
1408  unsigned int edge_id = 99999;
1409  bool edge_found = false;
1410  for (unsigned int i = 0; i < _num_edges; ++i)
1411  {
1412  if (_edges[i]->containsNode(node))
1413  {
1414  edge_id = i;
1415  edge_found = true;
1416  break;
1417  }
1418  }
1419  if (edge_found)
1420  {
1421  double rel_dist = _edges[edge_id]->distanceFromNode1(node);
1422  double xi_1d = 2.0 * rel_dist - 1.0; // translate to [-1,1] parent coord syst
1423  mapParametricCoordFrom1Dto2D(edge_id, xi_1d, para_coor);
1424  }
1425  return edge_found;
1426 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
unsigned int _num_edges
Definition: EFAElement2D.h:29
void mapParametricCoordFrom1Dto2D(unsigned int edge_id, double xi_1d, std::vector< double > &para_coor) const
std::set< EFANode * > EFAElement2D::getEdgeNodes ( unsigned int  edge_id) const

Definition at line 1396 of file EFAElement2D.C.

Referenced by setupNeighbors(), and shouldDuplicateCrackTipSplitElement().

1397 {
1398  std::set<EFANode *> edge_nodes;
1399  edge_nodes.insert(_edges[edge_id]->getNode(0));
1400  edge_nodes.insert(_edges[edge_id]->getNode(1));
1401  return edge_nodes;
1402 }
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAFragment2D * EFAElement2D::getFragment ( unsigned int  frag_id) const
EFAEdge * EFAElement2D::getFragmentEdge ( unsigned int  frag_id,
unsigned int  edge_id 
) const
bool EFAElement2D::getFragmentEdgeID ( unsigned int  elem_edge_id,
unsigned int &  frag_edge_id 
) const

Definition at line 1513 of file EFAElement2D.C.

Referenced by addEdgeCut(), and fragmentEdgeAlreadyCut().

1514 {
1515  // find the fragment edge that is contained by given element edge
1516  // N.B. if the elem edge contains two frag edges, this method will only return
1517  // the first frag edge ID
1518  bool frag_edge_found = false;
1519  frag_edge_id = 99999;
1520  if (_fragments.size() == 1)
1521  {
1522  for (unsigned int j = 0; j < _fragments[0]->numEdges(); ++j)
1523  {
1524  if (_edges[elem_edge_id]->containsEdge(*_fragments[0]->getEdge(j)))
1525  {
1526  frag_edge_id = j;
1527  frag_edge_found = true;
1528  break;
1529  }
1530  }
1531  }
1532  return frag_edge_found;
1533 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
EFAElement * EFAElement::getGeneralNeighbor ( unsigned int  index) const
inherited

Definition at line 234 of file EFAElement.C.

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

235 {
236  return _general_neighbors[index];
237 }
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:35
EFANode * EFAElement::getGlobalNodeFromLocalNode ( const EFANode local_node) const
inherited

Definition at line 93 of file EFAElement.C.

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

Definition at line 1429 of file EFAElement2D.C.

Referenced by EFAFragment2D::isSecondaryInteriorEdge().

1430 {
1431  if (interior_node_id < _interior_nodes.size())
1432  return _interior_nodes[interior_node_id];
1433  else
1434  EFAError("interior_node_id out of bounds");
1435 }
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
unsigned int EFAElement::getLocalNodeIndex ( EFANode node) const
inherited

Definition at line 109 of file EFAElement.C.

Referenced by XFEM::getEFANodeCoords().

110 {
111  unsigned int local_node_id = 99999;
112  bool found_local_node = false;
113  for (unsigned int i = 0; i < _num_nodes; ++i)
114  {
115  if (_nodes[i] == node)
116  {
117  found_local_node = true;
118  local_node_id = i;
119  break;
120  }
121  }
122  if (!found_local_node)
123  EFAError("In EFAelement::getLocalNodeIndex, cannot find the given node");
124  return local_node_id;
125 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
void EFAElement2D::getMasterInfo ( EFANode node,
std::vector< EFANode * > &  master_nodes,
std::vector< double > &  master_weights 
) const
virtual

Implements EFAElement.

Definition at line 298 of file EFAElement2D.C.

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

301 {
302  // Given a EFANode, find the element edge or fragment edge that contains it
303  // Return its master nodes and weights
304  master_nodes.clear();
305  master_weights.clear();
306  bool masters_found = false;
307  for (unsigned int i = 0; i < _num_edges; ++i) // check element exterior edges
308  {
309  if (_edges[i]->containsNode(node))
310  {
311  masters_found = _edges[i]->getNodeMasters(node, master_nodes, master_weights);
312  if (masters_found)
313  break;
314  else
315  EFAError("In getMasterInfo: cannot find master nodes in element edges");
316  }
317  }
318 
319  if (!masters_found) // check element interior embedded nodes
320  {
321  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
322  {
323  if (_interior_nodes[i]->getNode() == node)
324  {
325  std::vector<double> emb_xi(2, 0.0);
326  emb_xi[0] = _interior_nodes[i]->getParametricCoordinates(0);
327  emb_xi[1] = _interior_nodes[i]->getParametricCoordinates(1);
328  for (unsigned int j = 0; j < _num_edges; ++j)
329  {
330  master_nodes.push_back(_nodes[j]);
331  double weight = 0.0;
332  if (_num_edges == 4)
333  weight = Efa::linearQuadShape2D(j, emb_xi);
334  else if (_num_edges == 3)
335  weight = Efa::linearTriShape2D(j, emb_xi);
336  else
337  EFAError("unknown 2D element");
338  master_weights.push_back(weight);
339  }
340  masters_found = true;
341  break;
342  }
343  }
344  }
345 
346  if (!masters_found)
347  EFAError("In EFAelement2D::getMaterInfo, cannot find the given EFAnode");
348 }
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
double linearQuadShape2D(unsigned int node_id, std::vector< double > &xi_2d)
Definition: EFAFuncs.C:14
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
unsigned int _num_edges
Definition: EFAElement2D.h:29
double linearTriShape2D(unsigned int node_id, std::vector< double > &xi_2d)
Definition: EFAFuncs.C:21
unsigned int EFAElement2D::getNeighborIndex ( const EFAElement neighbor_elem) const
virtual

Implements EFAElement.

Definition at line 445 of file EFAElement2D.C.

Referenced by addEdgeCut(), and connectNeighbors().

446 {
447  for (unsigned int i = 0; i < _num_edges; ++i)
448  for (unsigned int j = 0; j < _edge_neighbors[i].size(); ++j)
449  if (_edge_neighbors[i][j] == neighbor_elem)
450  return i;
451 
452  EFAError(
453  "in get_neighbor_index() element: ", _id, " does not have neighbor: ", neighbor_elem->id());
454 }
unsigned int _id
Definition: EFAElement.h:26
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
unsigned int id() const
Definition: EFAElement.C:26
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFANode * EFAElement::getNode ( unsigned int  node_id) const
inherited
void EFAElement2D::getNonPhysicalNodes ( std::set< EFANode * > &  non_physical_nodes) const
virtual

Implements EFAElement.

Definition at line 233 of file EFAElement2D.C.

Referenced by shouldDuplicateCrackTipSplitElement().

234 {
235  // Any nodes that don't belong to any fragment are non-physical
236  // First add all nodes in the element to the set
237  for (unsigned int i = 0; i < _nodes.size(); ++i)
238  non_physical_nodes.insert(_nodes[i]);
239 
240  // Now delete any nodes that are contained in fragments
241  std::set<EFANode *>::iterator sit;
242  for (sit = non_physical_nodes.begin(); sit != non_physical_nodes.end();)
243  {
244  bool erased = false;
245  for (unsigned int i = 0; i < _fragments.size(); ++i)
246  {
247  if (_fragments[i]->containsNode(*sit))
248  {
249  non_physical_nodes.erase(sit++);
250  erased = true;
251  break;
252  }
253  }
254  if (!erased)
255  ++sit;
256  }
257 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
unsigned int EFAElement2D::getNumCuts ( ) const
virtual

Implements EFAElement.

Definition at line 779 of file EFAElement2D.C.

Referenced by restoreFragment().

780 {
781  unsigned int num_cuts = 0;
782  for (unsigned int i = 0; i < _num_edges; ++i)
783  if (_edges[i]->hasIntersection())
784  num_cuts += _edges[i]->numEmbeddedNodes();
785  return num_cuts;
786 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
unsigned int _num_edges
Definition: EFAElement2D.h:29
EFAElement * EFAElement::getParent ( ) const
inherited

Definition at line 174 of file EFAElement.C.

175 {
176  return _parent;
177 }
EFAElement * _parent
Definition: EFAElement.h:30
std::set< EFANode * > EFAElement2D::getPhantomNodeOnEdge ( unsigned int  edge_id) const

Definition at line 1489 of file EFAElement2D.C.

Referenced by shouldDuplicateForPhantomCorner().

1490 {
1491  std::set<EFANode *> phantom_nodes;
1492  if (_fragments.size() > 0)
1493  {
1494  for (unsigned int j = 0; j < 2; ++j) // loop ove 2 edge nodes
1495  {
1496  bool node_in_frag = false;
1497  for (unsigned int k = 0; k < _fragments.size(); ++k)
1498  {
1499  if (_fragments[k]->containsNode(_edges[edge_id]->getNode(j)))
1500  {
1501  node_in_frag = true;
1502  break;
1503  }
1504  }
1505  if (!node_in_frag)
1506  phantom_nodes.insert(_edges[edge_id]->getNode(j));
1507  }
1508  }
1509  return phantom_nodes;
1510 }
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
unsigned int EFAElement2D::getTipEdgeID ( ) const

Definition at line 1607 of file EFAElement2D.C.

Referenced by XFEM::markCutEdgesByState().

1608 {
1609  // if this element is a crack tip element, returns the crack tip edge's ID
1610  unsigned int tip_edge_id = 99999;
1611  if (_fragments.size() == 1) // crack tip element with a partial fragment saved
1612  {
1613  for (unsigned int i = 0; i < _num_edges; ++i)
1614  {
1615  unsigned int num_frag_edges = 0; // count how many fragment edges this element edge contains
1616  if (_edges[i]->hasIntersection())
1617  {
1618  for (unsigned int j = 0; j < _fragments[0]->numEdges(); ++j)
1619  {
1620  if (_edges[i]->containsEdge(*_fragments[0]->getEdge(j)))
1621  num_frag_edges += 1;
1622  }
1623  if (num_frag_edges == 2) // element edge contains two fragment edges
1624  {
1625  tip_edge_id = i;
1626  break;
1627  }
1628  }
1629  }
1630  }
1631  return tip_edge_id;
1632 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
EFANode * EFAElement2D::getTipEmbeddedNode ( ) const

Definition at line 1635 of file EFAElement2D.C.

Referenced by XFEM::markCutEdgesByState(), and XFEM::storeCrackTipOriginAndDirection().

1636 {
1637  // if this element is a crack tip element, returns the crack tip edge's ID
1638  EFANode * tip_emb = NULL;
1639  if (_fragments.size() == 1) // crack tip element with a partial fragment saved
1640  {
1641  for (unsigned int i = 0; i < _num_edges; ++i)
1642  {
1643  std::vector<EFAEdge *> frag_edges; // count how many fragment edges this element edge contains
1644  if (_edges[i]->hasIntersection())
1645  {
1646  for (unsigned int j = 0; j < _fragments[0]->numEdges(); ++j)
1647  {
1648  if (_edges[i]->containsEdge(*_fragments[0]->getEdge(j)))
1649  frag_edges.push_back(_fragments[0]->getEdge(j));
1650  } // j
1651  if (frag_edges.size() == 2) // element edge contains two fragment edges
1652  {
1653  if (frag_edges[1]->containsNode(frag_edges[0]->getNode(1)))
1654  tip_emb = frag_edges[0]->getNode(1);
1655  else if (frag_edges[1]->containsNode(frag_edges[0]->getNode(0)))
1656  tip_emb = frag_edges[0]->getNode(0);
1657  else
1658  EFAError("Common node can't be found between 2 tip frag edges");
1659  break;
1660  }
1661  }
1662  }
1663  }
1664  return tip_emb;
1665 }
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
unsigned int EFAElement::id ( ) const
inherited
void EFAElement2D::initCrackTip ( std::set< EFAElement * > &  CrackTipElements)
virtual

Implements EFAElement.

Definition at line 554 of file EFAElement2D.C.

555 {
556  if (isCrackTipElement())
557  {
558  CrackTipElements.insert(this);
559  for (unsigned int edge_iter = 0; edge_iter < _num_edges; ++edge_iter)
560  {
561  if ((_edge_neighbors[edge_iter].size() == 2) && (_edges[edge_iter]->hasIntersection()))
562  {
563  // Neither neighbor overlays current element. We are on the uncut element ahead of the tip.
564  // Flag neighbors as crack tip split elements and add this element as their crack tip
565  // neighbor.
566  if (_edge_neighbors[edge_iter][0]->overlaysElement(this) ||
567  _edge_neighbors[edge_iter][1]->overlaysElement(this))
568  EFAError("Element has a neighbor that overlays itself");
569 
570  // Make sure the current elment hasn't been flagged as a tip element
572  EFAError("crack_tip_split_element already flagged. In elem: ",
573  _id,
574  " flags: ",
576  " ",
577  _edge_neighbors[edge_iter][0]->isCrackTipSplit(),
578  " ",
579  _edge_neighbors[edge_iter][1]->isCrackTipSplit());
580 
581  _edge_neighbors[edge_iter][0]->setCrackTipSplit();
582  _edge_neighbors[edge_iter][1]->setCrackTipSplit();
583 
584  _edge_neighbors[edge_iter][0]->addCrackTipNeighbor(this);
585  _edge_neighbors[edge_iter][1]->addCrackTipNeighbor(this);
586  }
587  } // edge_iter
588  }
589 }
bool overlaysElement(const EFAElement2D *other_elem) const
Definition: EFAElement2D.C:357
unsigned int _id
Definition: EFAElement.h:26
bool isCrackTipSplit() const
Definition: EFAElement.C:134
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
virtual bool isCrackTipElement() const
Definition: EFAElement2D.C:773
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
unsigned int _num_edges
Definition: EFAElement2D.h:29
bool _crack_tip_split_element
Definition: EFAElement.h:32
bool EFAElement2D::isCrackTipElement ( ) const
virtual

Implements EFAElement.

Definition at line 773 of file EFAElement2D.C.

Referenced by getCrackTipSplitElementID(), initCrackTip(), and shouldDuplicateForCrackTip().

774 {
775  return fragmentHasTipEdges();
776 }
bool fragmentHasTipEdges() const
bool EFAElement::isCrackTipSplit ( ) const
inherited

Definition at line 134 of file EFAElement.C.

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

135 {
137 }
bool _crack_tip_split_element
Definition: EFAElement.h:32
bool EFAElement2D::isEdgePhantom ( unsigned int  edge_id) const

Definition at line 1536 of file EFAElement2D.C.

Referenced by XFEM::correctCrackExtensionDirection(), XFEM::markCutEdgesByGeometry(), and XFEM::markCutEdgesByState().

1537 {
1538  bool is_phantom = false;
1539  if (_fragments.size() > 0)
1540  {
1541  bool contain_frag_edge = false;
1542  for (unsigned int i = 0; i < _fragments.size(); ++i)
1543  {
1544  for (unsigned int j = 0; j < _fragments[i]->numEdges(); ++j)
1545  {
1546  if (_edges[edge_id]->containsEdge(*_fragments[i]->getEdge(j)))
1547  {
1548  contain_frag_edge = true;
1549  break;
1550  }
1551  } // j
1552  if (contain_frag_edge)
1553  break;
1554  } // i
1555  if (!contain_frag_edge)
1556  is_phantom = true;
1557  }
1558  return is_phantom;
1559 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
bool EFAElement2D::isFinalCut ( ) const
virtual

Implements EFAElement.

Definition at line 789 of file EFAElement2D.C.

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

790 {
791  // if an element has been cut twice its fragment must have two interior edges
792  bool cut_twice = false;
793  if (_fragments.size() > 0)
794  {
795  unsigned int num_interior_edges = 0;
796  for (unsigned int i = 0; i < _fragments[0]->numEdges(); ++i)
797  {
798  if (_fragments[0]->isEdgeInterior(i))
799  num_interior_edges += 1;
800  }
801  if (num_interior_edges == 2)
802  cut_twice = true;
803  }
804  return cut_twice;
805 }
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
bool EFAElement2D::isPartial ( ) const
virtual

Implements EFAElement.

Definition at line 206 of file EFAElement2D.C.

Referenced by branchingSplit(), XFEMCutElem2D::computeMomentFittingWeights(), and updateFragments().

207 {
208  bool partial = false;
209  if (_fragments.size() > 0)
210  {
211  for (unsigned int i = 0; i < _num_edges; ++i)
212  {
213  bool node_in_frag = false;
214  for (unsigned int j = 0; j < _fragments.size(); ++j)
215  {
216  if (_fragments[j]->containsNode(_nodes[i]))
217  {
218  node_in_frag = true;
219  break;
220  }
221  } // j
222  if (!node_in_frag)
223  {
224  partial = true;
225  break;
226  }
227  } // i
228  }
229  return partial;
230 }
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement2D::mapParametricCoordFrom1Dto2D ( unsigned int  edge_id,
double  xi_1d,
std::vector< double > &  para_coor 
) const
private

Definition at line 2005 of file EFAElement2D.C.

Referenced by getEdgeNodeParametricCoordinate().

2008 {
2009  para_coor.resize(2, 0.0);
2010  if (_num_edges == 4)
2011  {
2012  if (edge_id == 0)
2013  {
2014  para_coor[0] = xi_1d;
2015  para_coor[1] = -1.0;
2016  }
2017  else if (edge_id == 1)
2018  {
2019  para_coor[0] = 1.0;
2020  para_coor[1] = xi_1d;
2021  }
2022  else if (edge_id == 2)
2023  {
2024  para_coor[0] = -xi_1d;
2025  para_coor[1] = 1.0;
2026  }
2027  else if (edge_id == 3)
2028  {
2029  para_coor[0] = -1.0;
2030  para_coor[1] = -xi_1d;
2031  }
2032  else
2033  EFAError("edge_id out of bounds");
2034  }
2035  else if (_num_edges == 3)
2036  {
2037  if (edge_id == 0)
2038  {
2039  para_coor[0] = 0.5 * (1.0 - xi_1d);
2040  para_coor[1] = 0.5 * (1.0 + xi_1d);
2041  }
2042  else if (edge_id == 1)
2043  {
2044  para_coor[0] = 0.0;
2045  para_coor[1] = 0.5 * (1.0 - xi_1d);
2046  }
2047  else if (edge_id == 2)
2048  {
2049  para_coor[0] = 0.5 * (1.0 + xi_1d);
2050  para_coor[1] = 0.0;
2051  }
2052  else
2053  EFAError("edge_id out of bounds");
2054  }
2055  else
2056  EFAError("unknown element for 2D");
2057 }
unsigned int _num_edges
Definition: EFAElement2D.h:29
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 246 of file EFAElement.C.

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

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

Implements EFAElement.

Definition at line 521 of file EFAElement2D.C.

522 {
523  for (unsigned int edge_iter = 0; edge_iter < _num_edges; ++edge_iter)
524  {
525  for (unsigned int en_iter = 0; en_iter < _edge_neighbors[edge_iter].size(); ++en_iter)
526  {
527  EFAElement2D * neigh_elem = _edge_neighbors[edge_iter][en_iter];
528  if (neigh_elem != NULL)
529  {
530  bool found_neighbor = false;
531  for (unsigned int edge_iter2 = 0; edge_iter2 < neigh_elem->numEdges(); ++edge_iter2)
532  {
533  for (unsigned int en_iter2 = 0; en_iter2 < neigh_elem->numEdgeNeighbors(edge_iter2);
534  ++en_iter2)
535  {
536  if (neigh_elem->getEdgeNeighbor(edge_iter2, en_iter2) == this)
537  {
538  if ((en_iter2 > 1) && (en_iter > 1))
539  EFAError(
540  "Element and neighbor element cannot both have >1 neighbors on a common edge");
541  found_neighbor = true;
542  break;
543  }
544  }
545  }
546  if (!found_neighbor)
547  EFAError("Neighbor element doesn't recognize current element as neighbor");
548  }
549  }
550  }
551 }
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
EFAElement2D * getEdgeNeighbor(unsigned int edge_id, unsigned int neighbor_id) const
unsigned int numEdgeNeighbors(unsigned int edge_id) const
unsigned int _num_edges
Definition: EFAElement2D.h:29
unsigned int numEdges() const
unsigned int EFAElement::numChildren ( ) const
inherited

Definition at line 195 of file EFAElement.C.

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

196 {
197  return _children.size();
198 }
std::vector< EFAElement * > _children
Definition: EFAElement.h:31
unsigned int EFAElement::numCrackTipNeighbors ( ) const
inherited

Definition at line 140 of file EFAElement.C.

141 {
142  return _crack_tip_neighbors.size();
143 }
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:33
unsigned int EFAElement2D::numEdgeNeighbors ( unsigned int  edge_id) const

Definition at line 1562 of file EFAElement2D.C.

Referenced by addEdgeCut(), connectNeighbors(), neighborSanityCheck(), printElement(), shouldDuplicateCrackTipSplitElement(), shouldDuplicateForPhantomCorner(), and willCrackTipExtend().

1563 {
1564  unsigned int num_neighbors = 0;
1565  if (_edge_neighbors[edge_id][0])
1566  num_neighbors = _edge_neighbors[edge_id].size();
1567  return num_neighbors;
1568 }
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
unsigned int EFAElement2D::numEdges ( ) const
unsigned int EFAElement2D::numFragments ( ) const
virtual
unsigned int EFAElement::numGeneralNeighbors ( ) const
inherited

Definition at line 240 of file EFAElement.C.

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

241 {
242  return _general_neighbors.size();
243 }
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:35
unsigned int EFAElement2D::numInteriorNodes ( ) const
virtual

Implements EFAElement.

Definition at line 351 of file EFAElement2D.C.

Referenced by fragmentSanityCheck(), EFAFragment2D::isSecondaryInteriorEdge(), and EFAFragment2D::removeInvalidEmbeddedNodes().

352 {
353  return _interior_nodes.size();
354 }
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
unsigned int EFAElement::numNodes ( ) const
inherited
bool EFAElement2D::overlaysElement ( const EFAElement2D other_elem) const

Definition at line 357 of file EFAElement2D.C.

Referenced by initCrackTip(), and setupNeighbors().

358 {
359  bool overlays = false;
360 
361  if (other_elem->numEdges() != _num_edges)
362  return overlays;
363 
364  std::vector<EFANode *> common_nodes = getCommonNodes(other_elem);
365 
366  // Find indices of common nodes
367  if (common_nodes.size() == 2)
368  {
369  std::vector<EFANode *> common_nodes_vec(common_nodes.begin(), common_nodes.end());
370 
371  unsigned int e1n1idx = _num_edges + 1;
372  unsigned int e1n2idx = _num_edges + 1;
373  for (unsigned int i = 0; i < _num_edges; ++i)
374  {
375  if (_nodes[i] == common_nodes_vec[0])
376  {
377  e1n1idx = i;
378  }
379  else if (_nodes[i] == common_nodes_vec[1])
380  {
381  e1n2idx = i;
382  }
383  }
384 
385  if (e1n1idx > _num_edges || e1n2idx > _num_edges)
386  EFAError("in overlays_elem() couldn't find common node");
387 
388  bool e1ascend = false;
389  unsigned int e1n1idx_plus1(e1n1idx < (_num_edges - 1) ? e1n1idx + 1 : 0);
390  unsigned int e1n1idx_minus1(e1n1idx > 0 ? e1n1idx - 1 : _num_edges - 1);
391  if (e1n2idx == e1n1idx_plus1)
392  {
393  e1ascend = true;
394  }
395  else
396  {
397  if (e1n2idx != e1n1idx_minus1)
398  EFAError("in overlays_elem() common nodes must be adjacent to each other");
399  }
400 
401  unsigned int e2n1idx = _num_edges + 1;
402  unsigned int e2n2idx = _num_edges + 1;
403  for (unsigned int i = 0; i < _num_edges; ++i)
404  {
405  if (other_elem->getNode(i) == common_nodes_vec[0])
406  {
407  e2n1idx = i;
408  }
409  else if (other_elem->getNode(i) == common_nodes_vec[1])
410  {
411  e2n2idx = i;
412  }
413  }
414  if (e2n1idx > other_elem->numNodes() || e2n2idx > other_elem->numNodes())
415  EFAError("in overlays_elem() couldn't find common node");
416 
417  bool e2ascend = false;
418  unsigned int e2n1idx_plus1(e2n1idx < (_num_edges - 1) ? e2n1idx + 1 : 0);
419  unsigned int e2n1idx_minus1(e2n1idx > 0 ? e2n1idx - 1 : _num_edges - 1);
420  if (e2n2idx == e2n1idx_plus1)
421  {
422  e2ascend = true;
423  }
424  else
425  {
426  if (e2n2idx != e2n1idx_minus1)
427  EFAError("in overlays_elem() common nodes must be adjacent to each other");
428  }
429 
430  // if indices both ascend or descend, they overlay
431  if ((e1ascend && e2ascend) || (!e1ascend && !e2ascend))
432  {
433  overlays = true;
434  }
435  }
436  else if (common_nodes.size() > 2)
437  {
438  // TODO: We probably need more error checking here.
439  overlays = true;
440  }
441  return overlays;
442 }
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
unsigned int numNodes() const
Definition: EFAElement.C:32
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
std::vector< EFANode * > getCommonNodes(const EFAElement2D *other_elem) const
unsigned int _num_edges
Definition: EFAElement2D.h:29
unsigned int numEdges() const
void EFAElement2D::printElement ( std::ostream &  ostream)
virtual

Implements EFAElement.

Definition at line 1311 of file EFAElement2D.C.

1312 {
1313  ostream << std::setw(4);
1314  ostream << _id << " | ";
1315  for (unsigned int j = 0; j < _num_nodes; ++j)
1316  {
1317  ostream << std::setw(5) << _nodes[j]->idCatString();
1318  }
1319 
1320  ostream << " | ";
1321  for (unsigned int j = 0; j < _num_edges; ++j)
1322  {
1323  ostream << std::setw(4);
1324  if (_edges[j]->hasIntersection())
1325  {
1326  if (_edges[j]->numEmbeddedNodes() > 1)
1327  {
1328  ostream << "[";
1329  for (unsigned int k = 0; k < _edges[j]->numEmbeddedNodes(); ++k)
1330  {
1331  ostream << _edges[j]->getEmbeddedNode(k)->id();
1332  if (k == _edges[j]->numEmbeddedNodes() - 1)
1333  ostream << "]";
1334  else
1335  ostream << " ";
1336  }
1337  }
1338  else
1339  ostream << _edges[j]->getEmbeddedNode(0)->id() << " ";
1340  }
1341  else
1342  ostream << " -- ";
1343  }
1344  ostream << " | ";
1345  for (unsigned int j = 0; j < _num_edges; ++j)
1346  {
1347  if (numEdgeNeighbors(j) > 1)
1348  {
1349  ostream << "[";
1350  for (unsigned int k = 0; k < numEdgeNeighbors(j); ++k)
1351  {
1352  ostream << getEdgeNeighbor(j, k)->id();
1353  if (k == numEdgeNeighbors(j) - 1)
1354  ostream << "]";
1355  else
1356  ostream << " ";
1357  }
1358  ostream << " ";
1359  }
1360  else
1361  {
1362  ostream << std::setw(4);
1363  if (numEdgeNeighbors(j) == 1)
1364  ostream << getEdgeNeighbor(j, 0)->id() << " ";
1365  else
1366  ostream << " -- ";
1367  }
1368  }
1369  ostream << " | ";
1370  for (unsigned int j = 0; j < _fragments.size(); ++j)
1371  {
1372  ostream << std::setw(4);
1373  ostream << " " << j << " | ";
1374  for (unsigned int k = 0; k < _fragments[j]->numEdges(); ++k)
1375  {
1376  EFANode * prt_node = getFragmentEdge(j, k)->getNode(0);
1377  unsigned int kprev(k > 0 ? k - 1 : _fragments[j]->numEdges() - 1);
1378  if (!getFragmentEdge(j, kprev)->containsNode(prt_node))
1379  prt_node = getFragmentEdge(j, k)->getNode(1);
1380  ostream << std::setw(5) << prt_node->idCatString();
1381  }
1382  }
1383  ostream << std::endl;
1384 }
unsigned int _id
Definition: EFAElement.h:26
std::string idCatString()
Definition: EFANode.C:18
unsigned int id() const
Definition: EFAElement.C:26
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
EFAElement2D * getEdgeNeighbor(unsigned int edge_id, unsigned int neighbor_id) const
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
EFANode * getNode(unsigned int index) const
Definition: EFAEdge.C:177
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
unsigned int numEdgeNeighbors(unsigned int edge_id) const
unsigned int _num_edges
Definition: EFAElement2D.h:29
unsigned int numEdges() const
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement::printNodes ( std::ostream &  ostream) const
inherited

Definition at line 59 of file EFAElement.C.

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

Implements EFAElement.

Definition at line 1150 of file EFAElement2D.C.

Referenced by createChild().

1151 {
1152  // remove the embedded nodes on edge that are not inside the real part
1153  if (_fragments.size() > 0)
1154  {
1155  for (unsigned int i = 0; i < _num_edges; ++i)
1156  {
1157  std::vector<EFANode *> nodes_to_delete;
1158  for (unsigned int j = 0; j < _edges[i]->numEmbeddedNodes(); ++j)
1159  {
1160  if (!_fragments[0]->containsNode(_edges[i]->getEmbeddedNode(j)))
1161  nodes_to_delete.push_back(_edges[i]->getEmbeddedNode(j));
1162  }
1163  for (unsigned int j = 0; j < nodes_to_delete.size(); ++j)
1164  _edges[i]->removeEmbeddedNode(nodes_to_delete[j]);
1165  } // i
1166  }
1167 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
bool containsNode(EFANode *node) const
Definition: EFAElement.C:50
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement2D::restoreFragment ( const EFAElement *const  from_elem)
virtual

Implements EFAElement.

Definition at line 943 of file EFAElement2D.C.

944 {
945  const EFAElement2D * from_elem2d = dynamic_cast<const EFAElement2D *>(from_elem);
946  if (!from_elem2d)
947  EFAError("from_elem is not of EFAelement2D type");
948 
949  // restore fragments
950  if (_fragments.size() != 0)
951  EFAError("in restoreFragmentInfo elements must not have any pre-existing fragments");
952  for (unsigned int i = 0; i < from_elem2d->numFragments(); ++i)
953  _fragments.push_back(new EFAFragment2D(this, true, from_elem2d, i));
954 
955  // restore interior nodes
956  if (_interior_nodes.size() != 0)
957  EFAError("in restoreFragmentInfo elements must not have any pre-exsiting interior nodes");
958  for (unsigned int i = 0; i < from_elem2d->_interior_nodes.size(); ++i)
959  _interior_nodes.push_back(new EFAFaceNode(*from_elem2d->_interior_nodes[i]));
960 
961  // restore edge intersections
962  if (getNumCuts() != 0)
963  EFAError("In restoreEdgeIntersection: edge cuts already exist in element ", _id);
964  for (unsigned int i = 0; i < _num_edges; ++i)
965  {
966  if (from_elem2d->_edges[i]->hasIntersection())
967  _edges[i]->copyIntersection(*from_elem2d->_edges[i], 0);
968  if (_edges[i]->numEmbeddedNodes() > 2)
969  EFAError("elem ", _id, " has an edge with >2 cuts");
970  }
971 
972  // replace all local nodes with global nodes
973  for (unsigned int i = 0; i < from_elem2d->numNodes(); ++i)
974  {
975  if (from_elem2d->_nodes[i]->category() == EFANode::N_CATEGORY_LOCAL_INDEX)
976  switchNode(
977  _nodes[i], from_elem2d->_nodes[i], false); // EFAelement is not a child of any parent
978  else
979  EFAError("In restoreFragmentInfo all of from_elem's nodes must be local");
980  }
981 }
virtual unsigned int getNumCuts() const
Definition: EFAElement2D.C:779
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
unsigned int _id
Definition: EFAElement.h:26
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
unsigned int numNodes() const
Definition: EFAElement.C:32
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement2D.C:260
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement::setCrackTipSplit ( )
inherited

Definition at line 128 of file EFAElement.C.

129 {
131 }
bool _crack_tip_split_element
Definition: EFAElement.h:32
void EFAElement2D::setEdge ( unsigned int  edge_id,
EFAEdge edge 
)

Definition at line 1452 of file EFAElement2D.C.

Referenced by createChild().

1453 {
1454  _edges[edge_id] = edge;
1455 }
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
void EFAElement2D::setLocalCoordinates ( )
private

Definition at line 139 of file EFAElement2D.C.

Referenced by EFAElement2D().

140 {
141  if (_num_edges == 4)
142  {
143  /*
144  3 6 2
145  QUAD9(QUAD8): o-----o-----o
146  | |
147  | 8 |
148  7 o o o 5
149  | |
150  | |
151  o-----o-----o
152  0 4 1
153 
154  */
156  _local_node_coor[0] = EFAPoint(0.0, 0.0, 0.0);
157  _local_node_coor[1] = EFAPoint(1.0, 0.0, 0.0);
158  _local_node_coor[2] = EFAPoint(1.0, 1.0, 0.0);
159  _local_node_coor[3] = EFAPoint(0.0, 1.0, 0.0);
160 
161  if (_num_nodes > 4)
162  {
163  _local_node_coor[4] = EFAPoint(0.5, 0.0, 0.0);
164  _local_node_coor[5] = EFAPoint(1.0, 0.5, 0.0);
165  _local_node_coor[6] = EFAPoint(0.5, 1.0, 0.0);
166  _local_node_coor[7] = EFAPoint(0.0, 0.5, 0.0);
167  }
168 
169  if (_num_nodes > 8)
170  _local_node_coor[8] = EFAPoint(0.5, 0.5, 0.0);
171  }
172  else
173  {
174  /*
175  TRI6: 2
176  o
177  | \
178  | \
179  5 o o 4
180  | \
181  | \
182  o-----o-----o
183  0 3 1
184  */
186  _local_node_coor[0] = EFAPoint(0.0, 0.0, 0.0);
187  _local_node_coor[1] = EFAPoint(1.0, 0.0, 0.0);
188  _local_node_coor[2] = EFAPoint(0.0, 1.0, 0.0);
189 
190  if (_num_nodes > 3)
191  {
192  _local_node_coor[3] = EFAPoint(0.5, 0.0, 0.0);
193  _local_node_coor[4] = EFAPoint(0.5, 0.5, 0.0);
194  _local_node_coor[5] = EFAPoint(0.0, 0.5, 0.0);
195  }
196  }
197 }
unsigned int _num_nodes
Definition: EFAElement.h:27
std::vector< EFAPoint > _local_node_coor
Definition: EFAElement2D.h:34
unsigned int _num_edges
Definition: EFAElement2D.h:29
void EFAElement::setNode ( unsigned int  node_id,
EFANode node 
)
inherited
void EFAElement::setParent ( EFAElement parent)
inherited

Definition at line 189 of file EFAElement.C.

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

190 {
191  _parent = parent;
192 }
EFAElement * _parent
Definition: EFAElement.h:30
void EFAElement2D::setupNeighbors ( std::map< EFANode *, std::set< EFAElement * >> &  InverseConnectivityMap)
virtual

Implements EFAElement.

Definition at line 465 of file EFAElement2D.C.

466 {
467  findGeneralNeighbors(InverseConnectivityMap);
468  for (unsigned int eit2 = 0; eit2 < _general_neighbors.size(); ++eit2)
469  {
470  EFAElement2D * neigh_elem = dynamic_cast<EFAElement2D *>(_general_neighbors[eit2]);
471  if (!neigh_elem)
472  EFAError("neighbor_elem is not of EFAelement2D type");
473 
474  std::vector<EFANode *> common_nodes = getCommonNodes(neigh_elem);
475  if (common_nodes.size() >= 2)
476  {
477  for (unsigned int edge_iter = 0; edge_iter < _num_edges; ++edge_iter)
478  {
479  std::set<EFANode *> edge_nodes = getEdgeNodes(edge_iter);
480  bool is_edge_neighbor = false;
481 
482  // Must share nodes on this edge
483  if (Efa::numCommonElems(edge_nodes, common_nodes) == 2 && (!overlaysElement(neigh_elem)))
484  {
485  // Fragments must match up.
486  if ((_fragments.size() > 1) || (neigh_elem->numFragments() > 1))
487  EFAError("in updateEdgeNeighbors: Cannot have more than 1 fragment");
488  else if ((_fragments.size() == 1) && (neigh_elem->numFragments() == 1))
489  {
490  if (_fragments[0]->isConnected(neigh_elem->getFragment(0)))
491  is_edge_neighbor = true;
492  }
493  else // If there are no fragments to match up, consider them neighbors
494  is_edge_neighbor = true;
495  }
496 
497  if (is_edge_neighbor)
498  {
499  if (_edge_neighbors[edge_iter][0])
500  {
501  if (_edge_neighbors[edge_iter].size() > 1)
502  {
503  EFAError("Element ",
504  _id,
505  " already has 2 edge neighbors: ",
506  _edge_neighbors[edge_iter][0]->id(),
507  " ",
508  _edge_neighbors[edge_iter][1]->id());
509  }
510  _edge_neighbors[edge_iter].push_back(neigh_elem);
511  }
512  else
513  _edge_neighbors[edge_iter][0] = neigh_elem;
514  }
515  }
516  }
517  }
518 }
EFAFragment2D * getFragment(unsigned int frag_id) const
bool overlaysElement(const EFAElement2D *other_elem) const
Definition: EFAElement2D.C:357
unsigned int _id
Definition: EFAElement.h:26
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
std::vector< EFANode * > getCommonNodes(const EFAElement2D *other_elem) const
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:48
void findGeneralNeighbors(std::map< EFANode *, std::set< EFAElement * >> &InverseConnectivity)
Definition: EFAElement.C:214
std::set< EFANode * > getEdgeNodes(unsigned int edge_id) const
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:35
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
bool EFAElement2D::shouldDuplicateCrackTipSplitElement ( const std::set< EFAElement * > &  CrackTipElements)
virtual

Implements EFAElement.

Definition at line 637 of file EFAElement2D.C.

Referenced by shouldDuplicateForCrackTip().

638 {
639  // Determine whether element at crack tip should be duplicated. It should be duplicated
640  // if the crack will extend into the next element, or if it has a non-physical node
641  // connected to a face where a crack terminates, but will extend.
642 
643  bool should_duplicate = false;
644  if (_fragments.size() == 1)
645  {
646  std::vector<unsigned int> split_neighbors;
647  if (willCrackTipExtend(split_neighbors))
648  should_duplicate = true;
649  else
650  {
651  // The element may not be at the crack tip, but could have a non-physical node
652  // connected to a crack tip face (on a neighbor element) that will be split. We need to
653  // duplicate in that case as well.
654  std::set<EFANode *> non_physical_nodes;
655  getNonPhysicalNodes(non_physical_nodes);
656 
657  for (unsigned int eit = 0; eit < _general_neighbors.size(); ++eit)
658  {
659  EFAElement2D * neigh_elem = dynamic_cast<EFAElement2D *>(_general_neighbors[eit]);
660  if (!neigh_elem)
661  EFAError("general elem is not of type EFAelement2D");
662 
663  // check if a general neighbor is an old crack tip element and will be split
664  std::set<EFAElement *>::iterator sit;
665  sit = CrackTipElements.find(neigh_elem);
666  if (sit != CrackTipElements.end() && neigh_elem->numFragments() > 1)
667  {
668  for (unsigned int i = 0; i < neigh_elem->numEdges(); ++i)
669  {
670  std::set<EFANode *> neigh_edge_nodes = neigh_elem->getEdgeNodes(i);
671  if (neigh_elem->numEdgeNeighbors(i) == 2 &&
672  Efa::numCommonElems(neigh_edge_nodes, non_physical_nodes) > 0)
673  {
674  should_duplicate = true;
675  break;
676  }
677  } // i
678  }
679  if (should_duplicate)
680  break;
681  } // eit
682  }
683  } // IF one fragment
684  return should_duplicate;
685 }
virtual bool willCrackTipExtend(std::vector< unsigned int > &split_neighbors) const
Definition: EFAElement2D.C:727
virtual void getNonPhysicalNodes(std::set< EFANode * > &non_physical_nodes) const
Definition: EFAElement2D.C:233
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:48
std::set< EFANode * > getEdgeNodes(unsigned int edge_id) const
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
unsigned int numEdgeNeighbors(unsigned int edge_id) const
unsigned int numEdges() const
std::vector< EFAElement * > _general_neighbors
Definition: EFAElement.h:35
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
bool EFAElement2D::shouldDuplicateForCrackTip ( const std::set< EFAElement * > &  CrackTipElements)
virtual

Implements EFAElement.

Definition at line 613 of file EFAElement2D.C.

Referenced by createChild().

614 {
615  // This method is called in createChildElements()
616  // Only duplicate when
617  // 1) currElem will be a NEW crack tip element
618  // 2) currElem is a crack tip split element at last time step and the tip will extend
619  // 3) currElem is the neighbor of a to-be-second-split element which has another neighbor
620  // sharing a phantom node with currElem
621  bool should_duplicate = false;
622  if (_fragments.size() == 1)
623  {
624  std::set<EFAElement *>::iterator sit;
625  sit = CrackTipElements.find(this);
626  if (sit == CrackTipElements.end() && isCrackTipElement())
627  should_duplicate = true;
628  else if (shouldDuplicateCrackTipSplitElement(CrackTipElements))
629  should_duplicate = true;
631  should_duplicate = true;
632  }
633  return should_duplicate;
634 }
virtual bool shouldDuplicateForPhantomCorner()
Definition: EFAElement2D.C:688
virtual bool isCrackTipElement() const
Definition: EFAElement2D.C:773
virtual bool shouldDuplicateCrackTipSplitElement(const std::set< EFAElement * > &CrackTipElements)
Definition: EFAElement2D.C:637
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
bool EFAElement2D::shouldDuplicateForPhantomCorner ( )
virtual

Implements EFAElement.

Definition at line 688 of file EFAElement2D.C.

Referenced by shouldDuplicateForCrackTip().

689 {
690  // if a partial element will be split for a second time and it has two neighbor elements
691  // sharing one phantom node with the aforementioned partial element, then the two neighbor
692  // elements should be duplicated
693  bool should_duplicate = false;
694  if (_fragments.size() == 1 && (!_crack_tip_split_element))
695  {
696  for (unsigned int i = 0; i < _num_edges; ++i)
697  {
698  std::set<EFANode *> phantom_nodes = getPhantomNodeOnEdge(i);
699  if (phantom_nodes.size() > 0 && numEdgeNeighbors(i) == 1)
700  {
701  EFAElement2D * neighbor_elem = _edge_neighbors[i][0];
702  if (neighbor_elem->numFragments() > 1) // neighbor will be split
703  {
704  for (unsigned int j = 0; j < neighbor_elem->numEdges(); ++j)
705  {
706  if (!neighbor_elem->getEdge(j)->equivalent(*_edges[i]) &&
707  neighbor_elem->numEdgeNeighbors(j) > 0)
708  {
709  std::set<EFANode *> neigh_phantom_nodes = neighbor_elem->getPhantomNodeOnEdge(j);
710  if (Efa::numCommonElems(phantom_nodes, neigh_phantom_nodes) > 0)
711  {
712  should_duplicate = true;
713  break;
714  }
715  }
716  } // j
717  }
718  }
719  if (should_duplicate)
720  break;
721  } // i
722  }
723  return should_duplicate;
724 }
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
std::set< EFANode * > getPhantomNodeOnEdge(unsigned int edge_id) const
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:48
bool equivalent(const EFAEdge &other) const
Definition: EFAEdge.C:36
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
unsigned int numEdgeNeighbors(unsigned int edge_id) const
unsigned int _num_edges
Definition: EFAElement2D.h:29
unsigned int numEdges() const
bool _crack_tip_split_element
Definition: EFAElement.h:32
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement2D::switchEmbeddedNode ( EFANode new_node,
EFANode old_node 
)
virtual

Implements EFAElement.

Definition at line 287 of file EFAElement2D.C.

288 {
289  for (unsigned int i = 0; i < _num_edges; ++i)
290  _edges[i]->switchNode(new_emb_node, old_emb_node);
291  for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
292  _interior_nodes[i]->switchNode(new_emb_node, old_emb_node);
293  for (unsigned int i = 0; i < _fragments.size(); ++i)
294  _fragments[i]->switchNode(new_emb_node, old_emb_node);
295 }
std::vector< EFAFaceNode * > _interior_nodes
Definition: EFAElement2D.h:31
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement2D.C:260
unsigned int _num_edges
Definition: EFAElement2D.h:29
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement2D::switchNode ( EFANode new_node,
EFANode old_node,
bool  descend_to_parent 
)
virtual

Implements EFAElement.

Definition at line 260 of file EFAElement2D.C.

Referenced by connectNeighbors(), EFAElement2D(), restoreFragment(), switchEmbeddedNode(), and updateFragmentNode().

261 {
262  // We are not switching any embedded nodes here
263  for (unsigned int i = 0; i < _num_nodes; ++i)
264  {
265  if (_nodes[i] == old_node)
266  _nodes[i] = new_node;
267  }
268  for (unsigned int i = 0; i < _fragments.size(); ++i)
269  _fragments[i]->switchNode(new_node, old_node);
270 
271  for (unsigned int i = 0; i < _edges.size(); ++i)
272  _edges[i]->switchNode(new_node, old_node);
273 
274  if (_parent && descend_to_parent)
275  {
276  _parent->switchNode(new_node, old_node, false);
277  for (unsigned int i = 0; i < _parent->numGeneralNeighbors(); ++i)
278  {
279  EFAElement * neigh_elem = _parent->getGeneralNeighbor(i); // generalized neighbor element
280  for (unsigned int k = 0; k < neigh_elem->numChildren(); ++k)
281  neigh_elem->getChild(k)->switchNode(new_node, old_node, false);
282  }
283  }
284 }
unsigned int numChildren() const
Definition: EFAElement.C:195
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement2D.C:260
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)=0
EFAElement * _parent
Definition: EFAElement.h:30
EFAElement * getGeneralNeighbor(unsigned int index) const
Definition: EFAElement.C:234
unsigned int numGeneralNeighbors() const
Definition: EFAElement.C:240
EFAElement * getChild(unsigned int child_id) const
Definition: EFAElement.C:180
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
void EFAElement2D::updateFragmentNode ( )
virtual

Implements EFAElement.

Definition at line 1300 of file EFAElement2D.C.

1301 {
1302  for (unsigned int j = 0; j < _num_nodes; ++j)
1303  {
1304  if (_nodes[j]->parent() != NULL &&
1305  _nodes[j]->parent()->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
1306  switchNode(_nodes[j], _nodes[j]->parent(), false);
1307  }
1308 }
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
Definition: EFAElement2D.C:260
std::vector< EFANode * > _nodes
Definition: EFAElement.h:28
unsigned int _num_nodes
Definition: EFAElement.h:27
void EFAElement2D::updateFragments ( const std::set< EFAElement * > &  CrackTipElements,
std::map< unsigned int, EFANode * > &  EmbeddedNodes 
)
virtual

Implements EFAElement.

Definition at line 808 of file EFAElement2D.C.

810 {
811  // combine the crack-tip edges in a fragment to a single intersected edge
812  std::set<EFAElement *>::iterator sit;
813  sit = CrackTipElements.find(this);
814  if (sit != CrackTipElements.end()) // curr_elem is a crack tip element
815  {
816  if (_fragments.size() == 1)
817  _fragments[0]->combineTipEdges();
818  else
819  EFAError("crack tip elem ", _id, " must have 1 fragment");
820  }
821 
822  // if a fragment only has 1 intersection which is in an interior edge
823  // remove this embedded node (MUST DO THIS AFTER combine_tip_edges())
824  if (_fragments.size() == 1)
825  _fragments[0]->removeInvalidEmbeddedNodes(EmbeddedNodes);
826 
827  // for an element with no fragment, create one fragment identical to the element
828  if (_fragments.size() == 0)
829  _fragments.push_back(new EFAFragment2D(this, true, this));
830  if (_fragments.size() != 1)
831  EFAError("Element ", _id, " must have 1 fragment at this point");
832 
833  // count fragment's cut edges
834  unsigned int num_cut_frag_edges = _fragments[0]->getNumCuts();
835  unsigned int num_cut_nodes = _fragments[0]->getNumCutNodes();
836  unsigned int num_frag_edges = _fragments[0]->numEdges();
837  if (num_cut_frag_edges > 3)
838  EFAError("In element ", _id, " there are more than 2 cut fragment edges");
839 
840  if (num_cut_frag_edges == 0 && num_cut_nodes == 0)
841  {
842  if (!isPartial()) // delete the temp frag for an uncut elem
843  {
844  delete _fragments[0];
845  _fragments.clear();
846  }
847  // Element has already been cut. Don't recreate fragments because we
848  // would create multiple fragments to cover the entire element and
849  // lose the information about what part of this element is physical.
850  return;
851  }
852 
853  // split one fragment into one, two or three new fragments
854  std::vector<EFAFragment2D *> new_frags;
855  if (num_cut_frag_edges == 3)
856  new_frags = branchingSplit(EmbeddedNodes);
857  else
858  new_frags = _fragments[0]->split();
859 
860  delete _fragments[0]; // delete the old fragment
861  _fragments.clear();
862  for (unsigned int i = 0; i < new_frags.size(); ++i)
863  _fragments.push_back(new_frags[i]);
864 
865  fragmentSanityCheck(num_frag_edges, num_cut_frag_edges);
866 }
virtual bool isPartial() const
Definition: EFAElement2D.C:206
virtual void fragmentSanityCheck(unsigned int n_old_frag_edges, unsigned int n_old_frag_cuts) const
Definition: EFAElement2D.C:869
unsigned int _id
Definition: EFAElement.h:26
std::vector< EFAFragment2D * > branchingSplit(std::map< unsigned int, EFANode * > &EmbeddedNodes)
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33
bool EFAElement2D::willCrackTipExtend ( std::vector< unsigned int > &  split_neighbors) const
virtual

Implements EFAElement.

Definition at line 727 of file EFAElement2D.C.

Referenced by shouldDuplicateCrackTipSplitElement().

728 {
729  // Determine whether the current element is a crack tip element for which the crack will
730  // extend into the next element.
731  // N.B. this is called at the beginning of createChildElements
732  bool will_extend = false;
733  if (_fragments.size() == 1 && _crack_tip_split_element)
734  {
735  for (unsigned int i = 0; i < _crack_tip_neighbors.size(); ++i)
736  {
737  unsigned int neigh_idx = _crack_tip_neighbors[i];
738  if (numEdgeNeighbors(neigh_idx) != 1)
739  EFAError("in will_crack_tip_extend() element: ",
740  _id,
741  " has: ",
742  _edge_neighbors[neigh_idx].size(),
743  " on edge: ",
744  neigh_idx);
745 
746  EFAElement2D * neighbor_elem = _edge_neighbors[neigh_idx][0];
747  if (neighbor_elem->numFragments() > 2)
748  EFAError("in will_crack_tip_extend() element: ",
749  neighbor_elem->id(),
750  " has: ",
751  neighbor_elem->numFragments(),
752  " fragments");
753  else if (neighbor_elem->numFragments() == 2)
754  {
755  EFAFragment2D * frag1 = neighbor_elem->getFragment(0);
756  EFAFragment2D * frag2 = neighbor_elem->getFragment(1);
757  std::vector<EFANode *> neigh_cut_nodes = frag1->getCommonNodes(frag2);
758  if (neigh_cut_nodes.size() != 2)
759  EFAError("2 frags in a elem does not share 2 common nodes");
760  if (_edges[neigh_idx]->isEmbeddedNode(neigh_cut_nodes[0]) ||
761  _edges[neigh_idx]->isEmbeddedNode(neigh_cut_nodes[1]))
762  {
763  split_neighbors.push_back(neigh_idx);
764  will_extend = true;
765  }
766  }
767  } // i
768  }
769  return will_extend;
770 }
EFAFragment2D * getFragment(unsigned int frag_id) const
unsigned int _id
Definition: EFAElement.h:26
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
Definition: EFAElement2D.h:32
unsigned int id() const
Definition: EFAElement.C:26
std::vector< EFAEdge * > _edges
Definition: EFAElement2D.h:30
std::vector< EFANode * > getCommonNodes(EFAFragment *other) const
Definition: EFAFragment.C:18
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
unsigned int numEdgeNeighbors(unsigned int edge_id) const
bool _crack_tip_split_element
Definition: EFAElement.h:32
std::vector< unsigned int > _crack_tip_neighbors
Definition: EFAElement.h:33
std::vector< EFAFragment2D * > _fragments
Definition: EFAElement2D.h:33

Member Data Documentation

std::vector<EFAElement *> EFAElement::_children
protectedinherited
std::vector<unsigned int> EFAElement::_crack_tip_neighbors
protectedinherited
bool EFAElement::_crack_tip_split_element
protectedinherited
std::vector<std::vector<EFAElement2D *> > EFAElement2D::_edge_neighbors
private
std::vector<EFAEdge *> EFAElement2D::_edges
private
std::vector<EFAFragment2D *> EFAElement2D::_fragments
private
std::vector<EFAElement *> EFAElement::_general_neighbors
protectedinherited
unsigned int EFAElement::_id
protectedinherited
std::vector<EFAFaceNode *> EFAElement2D::_interior_nodes
private
std::vector<EFAPoint> EFAElement2D::_local_node_coor
private

Definition at line 34 of file EFAElement2D.h.

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

std::vector<EFANode *> EFAElement::_local_nodes
protectedinherited
std::vector<EFANode *> EFAElement::_nodes
protectedinherited
unsigned int EFAElement2D::_num_edges
private
unsigned int EFAElement::_num_nodes
protectedinherited
EFAElement* EFAElement::_parent
protectedinherited

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