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

#include <ElementFragmentAlgorithm.h>

Public Member Functions

 ElementFragmentAlgorithm (std::ostream &os)
 Constructor. More...
 
 ~ElementFragmentAlgorithm ()
 
unsigned int add2DElements (std::vector< std::vector< unsigned int >> &quads)
 
EFAElementadd2DElement (const std::vector< unsigned int > &quad, unsigned int id)
 
EFAElementadd3DElement (const std::vector< unsigned int > &quad, unsigned int id)
 
void updateEdgeNeighbors ()
 
void initCrackTipTopology ()
 
void addElemEdgeIntersection (unsigned int elemid, unsigned int edgeid, double position)
 
void addElemNodeIntersection (unsigned int elemid, unsigned int nodeid)
 
bool addFragEdgeIntersection (unsigned int elemid, unsigned int frag_edge_id, double position)
 
void addElemFaceIntersection (unsigned int elemid, unsigned int faceid, const std::vector< unsigned int > &edgeid, const std::vector< double > &position)
 
void addFragFaceIntersection (unsigned int ElemID, unsigned int FragFaceID, const std::vector< unsigned int > &FragFaceEdgeID, const std::vector< double > &position)
 
void updatePhysicalLinksAndFragments ()
 
void updateTopology (bool mergeUncutVirtualEdges=true)
 
void reset ()
 
void clearAncestry ()
 
void restoreFragmentInfo (EFAElement *const elem, const EFAElement *const from_elem)
 
void createChildElements ()
 
void connectFragments (bool mergeUncutVirtualEdges)
 
void sanityCheck ()
 
void updateCrackTipElements ()
 
void printMesh ()
 
void error (const std::string &error_string)
 
const std::vector< EFAElement * > & getChildElements ()
 
const std::vector< EFAElement * > & getParentElements ()
 
const std::vector< EFANode * > & getNewNodes ()
 
const std::set< EFAElement * > & getCrackTipElements ()
 
const std::map< unsigned int, EFANode * > & getPermanentNodes ()
 
const std::map< unsigned int, EFANode * > & getTempNodes ()
 
const std::map< unsigned int, EFANode * > & getEmbeddedNodes ()
 
EFAElementgetElemByID (unsigned int id)
 
unsigned int getElemIdByNodes (unsigned int *node_id)
 
void clearPotentialIsolatedNodes ()
 

Private Attributes

std::ostream & _ostream
 
std::map< unsigned int, EFANode * > _permanent_nodes
 
std::map< unsigned int, EFANode * > _embedded_nodes
 
std::map< unsigned int, EFANode * > _temp_nodes
 
std::map< unsigned int, EFANode * > _embedded_permanent_nodes
 
std::map< unsigned int, EFAElement * > _elements
 
std::set< EFAElement * > _crack_tip_elements
 
std::vector< EFANode * > _new_nodes
 
std::vector< EFANode * > _deleted_nodes
 
std::vector< EFAElement * > _child_elements
 
std::vector< EFAElement * > _parent_elements
 
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
 

Detailed Description

Definition at line 19 of file ElementFragmentAlgorithm.h.

Constructor & Destructor Documentation

◆ ElementFragmentAlgorithm()

ElementFragmentAlgorithm::ElementFragmentAlgorithm ( std::ostream &  os)

Constructor.

Definition at line 30 of file ElementFragmentAlgorithm.C.

30 : _ostream(os) {}

◆ ~ElementFragmentAlgorithm()

ElementFragmentAlgorithm::~ElementFragmentAlgorithm ( )

Definition at line 32 of file ElementFragmentAlgorithm.C.

33 {
34  std::map<unsigned int, EFANode *>::iterator mit;
35  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
36  {
37  delete mit->second;
38  mit->second = nullptr;
39  }
40  for (mit = _embedded_nodes.begin(); mit != _embedded_nodes.end(); ++mit)
41  {
42  delete mit->second;
43  mit->second = nullptr;
44  }
45  for (mit = _embedded_permanent_nodes.begin(); mit != _embedded_permanent_nodes.end(); ++mit)
46  {
47  delete mit->second;
48  mit->second = nullptr;
49  }
50  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
51  {
52  delete mit->second;
53  mit->second = nullptr;
54  }
55  std::map<unsigned int, EFAElement *>::iterator eit;
56  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
57  {
58  delete eit->second;
59  eit->second = nullptr;
60  }
61 }
std::map< unsigned int, EFAElement * > _elements
std::map< unsigned int, EFANode * > _embedded_permanent_nodes
std::map< unsigned int, EFANode * > _temp_nodes
std::map< unsigned int, EFANode * > _embedded_nodes
std::map< unsigned int, EFANode * > _permanent_nodes

Member Function Documentation

◆ add2DElement()

EFAElement * ElementFragmentAlgorithm::add2DElement ( const std::vector< unsigned int > &  quad,
unsigned int  id 
)

Definition at line 102 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::buildEFAMesh(), and TEST().

103 {
104  unsigned int num_nodes = quad.size();
105 
106  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
107  if (mit != _elements.end())
108  EFAError("In add2DElement element with id: ", id, " already exists");
109 
110  EFAElement2D * newElem = new EFAElement2D(id, num_nodes);
111  _elements.insert(std::make_pair(id, newElem));
112 
113  for (unsigned int j = 0; j < num_nodes; ++j)
114  {
115  EFANode * currNode = nullptr;
116  std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quad[j]);
117  if (mit == _permanent_nodes.end())
118  {
119  currNode = new EFANode(quad[j], EFANode::N_CATEGORY_PERMANENT);
120  _permanent_nodes.insert(std::make_pair(quad[j], currNode));
121  }
122  else
123  currNode = mit->second;
124 
125  newElem->setNode(j, currNode);
126  _inverse_connectivity[currNode].insert(newElem);
127  }
128  newElem->createEdges();
129  return newElem;
130 }
std::map< unsigned int, EFAElement * > _elements
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::map< unsigned int, EFANode * > _permanent_nodes
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:40
void createEdges()

◆ add2DElements()

unsigned int ElementFragmentAlgorithm::add2DElements ( std::vector< std::vector< unsigned int >> &  quads)

Definition at line 64 of file ElementFragmentAlgorithm.C.

Referenced by case1Common(), case2Mesh(), case5Mesh(), and TEST().

65 {
66  unsigned int first_id = 0;
67  unsigned int num_nodes = quads[0].size();
68 
69  if (quads.size() == 0)
70  EFAError("add2DElements called with empty vector of quads");
71 
72  for (unsigned int i = 0; i < quads.size(); ++i)
73  {
74  unsigned int new_elem_id = Efa::getNewID(_elements);
75  EFAElement2D * newElem = new EFAElement2D(new_elem_id, num_nodes);
76  _elements.insert(std::make_pair(new_elem_id, newElem));
77 
78  if (i == 0)
79  first_id = new_elem_id;
80 
81  for (unsigned int j = 0; j < num_nodes; ++j)
82  {
83  EFANode * currNode = nullptr;
84  std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quads[i][j]);
85  if (mit == _permanent_nodes.end())
86  {
87  currNode = new EFANode(quads[i][j], EFANode::N_CATEGORY_PERMANENT);
88  _permanent_nodes.insert(std::make_pair(quads[i][j], currNode));
89  }
90  else
91  currNode = mit->second;
92 
93  newElem->setNode(j, currNode);
94  _inverse_connectivity[currNode].insert(newElem);
95  }
96  newElem->createEdges();
97  }
98  return first_id;
99 }
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
Definition: EFAFuncs.h:38
std::map< unsigned int, EFAElement * > _elements
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::map< unsigned int, EFANode * > _permanent_nodes
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:40
void createEdges()

◆ add3DElement()

EFAElement * ElementFragmentAlgorithm::add3DElement ( const std::vector< unsigned int > &  quad,
unsigned int  id 
)

Definition at line 133 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::buildEFAMesh(), case6Mesh(), and case7Mesh().

134 {
135  unsigned int num_nodes = quad.size();
136  unsigned int num_faces = 0;
137  if (num_nodes == 8 || num_nodes == 20 || num_nodes == 27)
138  num_faces = 6;
139  else if (num_nodes == 4 || num_nodes == 10 || num_nodes == 14)
140  num_faces = 4;
141  else
142  EFAError("In add3DElement element with id: ", id, " has invalid num_nodes");
143 
144  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
145  if (mit != _elements.end())
146  EFAError("In add3DElement element with id: ", id, " already exists");
147 
148  EFAElement3D * newElem = new EFAElement3D(id, num_nodes, num_faces);
149  _elements.insert(std::make_pair(id, newElem));
150 
151  for (unsigned int j = 0; j < num_nodes; ++j)
152  {
153  EFANode * currNode = nullptr;
154  std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quad[j]);
155  if (mit == _permanent_nodes.end())
156  {
157  currNode = new EFANode(quad[j], EFANode::N_CATEGORY_PERMANENT);
158  _permanent_nodes.insert(std::make_pair(quad[j], currNode));
159  }
160  else
161  currNode = mit->second;
162 
163  newElem->setNode(j, currNode);
164  _inverse_connectivity[currNode].insert(newElem);
165  }
166  newElem->createFaces();
167  return newElem;
168 }
void createFaces()
std::map< unsigned int, EFAElement * > _elements
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
std::map< unsigned int, EFANode * > _permanent_nodes
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:40

◆ addElemEdgeIntersection()

void ElementFragmentAlgorithm::addElemEdgeIntersection ( unsigned int  elemid,
unsigned int  edgeid,
double  position 
)

Definition at line 202 of file ElementFragmentAlgorithm.C.

Referenced by case1Common(), case2Intersections(), XFEM::markCutEdgesByGeometry(), XFEM::markCutEdgesByState(), and TEST().

205 {
206  // this method is called when we are marking cut edges
207  auto eit = _elements.find(elemid);
208  if (eit == _elements.end())
209  EFAError("Could not find element with id: ", elemid, " in addEdgeIntersection");
210 
211  EFAElement2D * curr_elem = dynamic_cast<EFAElement2D *>(eit->second);
212  if (!curr_elem)
213  EFAError("addElemEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
214  curr_elem->addEdgeCut(edgeid, position, nullptr, _embedded_nodes, true);
215 }
void addEdgeCut(unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode *> &EmbeddedNodes, bool add_to_neighbor)
std::map< unsigned int, EFAElement * > _elements
std::map< unsigned int, EFANode * > _embedded_nodes

◆ addElemFaceIntersection()

void ElementFragmentAlgorithm::addElemFaceIntersection ( unsigned int  elemid,
unsigned int  faceid,
const std::vector< unsigned int > &  edgeid,
const std::vector< double > &  position 
)

Definition at line 251 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::markCutFacesByGeometry(), and TEST().

255 {
256  // this method is called when we are marking cut edges
257  auto eit = _elements.find(elemid);
258  if (eit == _elements.end())
259  EFAError("Could not find element with id: ", elemid, " in addEdgeIntersection");
260 
261  EFAElement3D * curr_elem = dynamic_cast<EFAElement3D *>(eit->second);
262  if (!curr_elem)
263  EFAError("addElemEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
264 
265  // add cuts to two face edges at the same time
266  curr_elem->addFaceEdgeCut(faceid, edgeid[0], position[0], nullptr, _embedded_nodes, true, true);
267  curr_elem->addFaceEdgeCut(faceid, edgeid[1], position[1], nullptr, _embedded_nodes, true, true);
268 }
std::map< unsigned int, EFAElement * > _elements
std::map< unsigned int, EFANode * > _embedded_nodes
void addFaceEdgeCut(unsigned int face_id, unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode *> &EmbeddedNodes, bool add_to_neighbor, bool add_to_adjacent)

◆ addElemNodeIntersection()

void ElementFragmentAlgorithm::addElemNodeIntersection ( unsigned int  elemid,
unsigned int  nodeid 
)

Definition at line 218 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::markCutEdgesByGeometry().

219 {
220  // this method is called when we are marking cut nodes
221  auto eit = _elements.find(elemid);
222  if (eit == _elements.end())
223  EFAError("Could not find element with id: ", elemid, " in addElemNodeIntersection");
224 
225  EFAElement2D * curr_elem = dynamic_cast<EFAElement2D *>(eit->second);
226  if (!curr_elem)
227  EFAError("addElemNodeIntersection: elem ", elemid, " is not of type EFAelement2D");
228 
229  // Only add cut node when the curr_elem does not have any fragment
230  if (curr_elem->numFragments() == 0)
231  curr_elem->addNodeCut(nodeid, nullptr, _permanent_nodes, _embedded_permanent_nodes);
232 }
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:207
std::map< unsigned int, EFAElement * > _elements
std::map< unsigned int, EFANode * > _embedded_permanent_nodes
void addNodeCut(unsigned int node_id, EFANode *embedded_permanent_node, std::map< unsigned int, EFANode *> &PermanentNodes, std::map< unsigned int, EFANode *> &EmbeddedPermanentNodes)
std::map< unsigned int, EFANode * > _permanent_nodes

◆ addFragEdgeIntersection()

bool ElementFragmentAlgorithm::addFragEdgeIntersection ( unsigned int  elemid,
unsigned int  frag_edge_id,
double  position 
)

Definition at line 235 of file ElementFragmentAlgorithm.C.

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

238 {
239  // N.B. this method must be called after addEdgeIntersection
240  auto eit = _elements.find(elemid);
241  if (eit == _elements.end())
242  EFAError("Could not find element with id: ", elemid, " in addFragEdgeIntersection");
243 
244  EFAElement2D * elem = dynamic_cast<EFAElement2D *>(eit->second);
245  if (!elem)
246  EFAError("addFragEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
247  return elem->addFragmentEdgeCut(frag_edge_id, position, _embedded_nodes);
248 }
bool addFragmentEdgeCut(unsigned int frag_edge_id, double position, std::map< unsigned int, EFANode *> &EmbeddedNodes)
std::map< unsigned int, EFAElement * > _elements
std::map< unsigned int, EFANode * > _embedded_nodes

◆ addFragFaceIntersection()

void ElementFragmentAlgorithm::addFragFaceIntersection ( unsigned int  ElemID,
unsigned int  FragFaceID,
const std::vector< unsigned int > &  FragFaceEdgeID,
const std::vector< double > &  position 
)

Definition at line 271 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::markCutFacesByGeometry().

276 {
277  // TODO: need to finish this for 3D problems
278 }

◆ clearAncestry()

void ElementFragmentAlgorithm::clearAncestry ( )

Definition at line 350 of file ElementFragmentAlgorithm.C.

Referenced by TEST().

351 {
352  _inverse_connectivity.clear();
353  for (unsigned int i = 0; i < _parent_elements.size(); ++i)
354  {
356  EFAError("Attempted to delete parent element: ",
357  _parent_elements[i]->id(),
358  " from _elements, but couldn't find it");
359  }
360  _parent_elements.clear();
361 
362  std::map<unsigned int, EFAElement *>::iterator eit;
363  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
364  {
365  EFAElement * curr_elem = eit->second;
366  curr_elem->clearParentAndChildren();
367  for (unsigned int j = 0; j < curr_elem->numNodes(); j++)
368  {
369  EFANode * curr_node = curr_elem->getNode(j);
370  _inverse_connectivity[curr_node].insert(curr_elem);
371  }
372  }
373 
374  std::map<unsigned int, EFANode *>::iterator mit;
375  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
376  mit->second->removeParent();
377 
378  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
379  {
380  delete mit->second;
381  mit->second = nullptr;
382  }
383  _temp_nodes.clear();
384 
385  _new_nodes.clear();
386  _child_elements.clear();
387 
388  // TODO: Sanity check to make sure that there are no nodes that are not connected
389  // to an element -- there shouldn't be any
390 }
void clearParentAndChildren()
Definition: EFAElement.C:201
bool deleteFromMap(std::map< unsigned int, T *> &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:22
std::vector< EFAElement * > _child_elements
std::vector< EFAElement * > _parent_elements
std::map< unsigned int, EFAElement * > _elements
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
std::vector< EFANode * > _new_nodes
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
std::map< unsigned int, EFANode * > _temp_nodes
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
unsigned int numNodes() const
Definition: EFAElement.C:34
std::map< unsigned int, EFANode * > _permanent_nodes

◆ clearPotentialIsolatedNodes()

void ElementFragmentAlgorithm::clearPotentialIsolatedNodes ( )

Definition at line 600 of file ElementFragmentAlgorithm.C.

Referenced by updateTopology().

601 {
602  // compile a set of all child element nodes
603  std::set<EFANode *> child_nodes;
604  for (const auto & child_element : _child_elements)
605  {
606  const auto & nodes = child_element->getNodes();
607  child_nodes.insert(nodes.begin(), nodes.end());
608  }
609 
610  // Collect all parent nodes that will be isolated
611  std::map<EFANode *, EFANode *> isolate_parent_to_child;
612  for (unsigned int i = 0; i < _new_nodes.size(); ++i)
613  {
614  EFANode * parent_node = _new_nodes[i]->parent();
615  if (!parent_node)
616  EFAError("a new permanent node must have a parent node!");
617 
618  auto it = isolate_parent_to_child.lower_bound(parent_node);
619  if (it != isolate_parent_to_child.end() && it->first == parent_node)
620  continue;
621 
622  if (child_nodes.count(parent_node) == 0)
623  isolate_parent_to_child.emplace_hint(it, parent_node, _new_nodes[i]);
624  }
625 
626  // For each isolated parent node, pick one of its child new node
627  // Then, switch that child with its parent for all new elems
628  for (const auto [parent_node, child_node] : isolate_parent_to_child)
629  {
630  for (unsigned int i = 0; i < _child_elements.size(); ++i)
631  if (_child_elements[i]->containsNode(child_node))
632  _child_elements[i]->switchNode(parent_node, child_node, true);
633 
634  _new_nodes.erase(std::remove(_new_nodes.begin(), _new_nodes.end(), child_node),
635  _new_nodes.end());
637  }
638 }
bool deleteFromMap(std::map< unsigned int, T *> &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:22
std::vector< EFAElement * > _child_elements
std::vector< EFANode * > _new_nodes
std::map< unsigned int, EFANode * > _permanent_nodes

◆ connectFragments()

void ElementFragmentAlgorithm::connectFragments ( bool  mergeUncutVirtualEdges)

Definition at line 423 of file ElementFragmentAlgorithm.C.

Referenced by updateTopology().

424 {
425  // now perform the comparison on the children
426  for (unsigned int elem_iter = 0; elem_iter < _child_elements.size(); elem_iter++)
427  {
428  EFAElement * childElem = _child_elements[elem_iter];
429  childElem->connectNeighbors(
430  _permanent_nodes, _temp_nodes, _inverse_connectivity, mergeUncutVirtualEdges);
431  childElem->updateFragmentNode();
432  }
433 
434  // remove all deleted children
435  _child_elements.erase(std::remove(_child_elements.begin(), _child_elements.end(), nullptr),
436  _child_elements.end());
437 }
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)=0
std::vector< EFAElement * > _child_elements
virtual void updateFragmentNode()=0
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
std::map< unsigned int, EFANode * > _temp_nodes
std::map< unsigned int, EFANode * > _permanent_nodes

◆ createChildElements()

void ElementFragmentAlgorithm::createChildElements ( )

Definition at line 400 of file ElementFragmentAlgorithm.C.

Referenced by updateTopology().

401 {
402  // temporary container for new elements -- will be merged with Elements
403  std::map<unsigned int, EFAElement *> newChildElements;
404 
405  // loop over the original elements in the mesh
406  std::map<unsigned int, EFAElement *>::iterator eit;
407  std::map<unsigned int, EFAElement *>::iterator ElementsEnd = _elements.end();
408  for (eit = _elements.begin(); eit != ElementsEnd; ++eit)
409  {
410  EFAElement * curr_elem = eit->second;
411  curr_elem->createChild(_crack_tip_elements,
412  _elements,
413  newChildElements,
416  _temp_nodes);
417  } // loop over elements
418  // Merge newChildElements back in with Elements
419  _elements.insert(newChildElements.begin(), newChildElements.end());
420 }
std::vector< EFAElement * > _child_elements
std::vector< EFAElement * > _parent_elements
std::map< unsigned int, EFAElement * > _elements
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)=0
std::set< EFAElement * > _crack_tip_elements
std::map< unsigned int, EFANode * > _temp_nodes

◆ error()

void ElementFragmentAlgorithm::error ( const std::string &  error_string)

◆ getChildElements()

const std::vector<EFAElement *>& ElementFragmentAlgorithm::getChildElements ( )
inline

Definition at line 78 of file ElementFragmentAlgorithm.h.

Referenced by XFEM::cutMeshWithEFA(), and TEST().

78 { return _child_elements; };
std::vector< EFAElement * > _child_elements

◆ getCrackTipElements()

const std::set<EFAElement *>& ElementFragmentAlgorithm::getCrackTipElements ( )
inline

Definition at line 81 of file ElementFragmentAlgorithm.h.

Referenced by XFEM::cutMeshWithEFA(), XFEM::storeCrackTipOriginAndDirection(), and TEST().

81 { return _crack_tip_elements; };
std::set< EFAElement * > _crack_tip_elements

◆ getElemByID()

EFAElement * ElementFragmentAlgorithm::getElemByID ( unsigned int  id)

Definition at line 568 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::buildEFAMesh(), XFEM::getEFAElem2D(), and XFEM::getEFAElem3D().

569 {
570  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
571  if (mit == _elements.end())
572  EFAError("in getElemByID() could not find element: ", id);
573  return mit->second;
574 }
std::map< unsigned int, EFAElement * > _elements

◆ getElemIdByNodes()

unsigned int ElementFragmentAlgorithm::getElemIdByNodes ( unsigned int node_id)

Definition at line 577 of file ElementFragmentAlgorithm.C.

578 {
579  unsigned int elem_id = std::numeric_limits<unsigned int>::max();
580  std::map<unsigned int, EFAElement *>::iterator eit;
581  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
582  {
583  EFAElement * curr_elem = eit->second;
584  unsigned int counter = 0;
585  for (unsigned int i = 0; i < curr_elem->numNodes(); ++i)
586  {
587  if (curr_elem->getNode(i)->id() == node_id[i])
588  counter += 1;
589  }
590  if (counter == curr_elem->numNodes())
591  {
592  elem_id = curr_elem->id();
593  break;
594  }
595  }
596  return elem_id;
597 }
unsigned int id() const
Definition: EFAElement.C:28
std::map< unsigned int, EFAElement * > _elements
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:46
unsigned int numNodes() const
Definition: EFAElement.C:34
unsigned int id() const
Definition: EFANode.C:36

◆ getEmbeddedNodes()

const std::map<unsigned int, EFANode *>& ElementFragmentAlgorithm::getEmbeddedNodes ( )
inline

Definition at line 84 of file ElementFragmentAlgorithm.h.

Referenced by TEST().

84 { return _embedded_nodes; }
std::map< unsigned int, EFANode * > _embedded_nodes

◆ getNewNodes()

const std::vector<EFANode *>& ElementFragmentAlgorithm::getNewNodes ( )
inline

Definition at line 80 of file ElementFragmentAlgorithm.h.

Referenced by XFEM::cutMeshWithEFA().

80 { return _new_nodes; };
std::vector< EFANode * > _new_nodes

◆ getParentElements()

const std::vector<EFAElement *>& ElementFragmentAlgorithm::getParentElements ( )
inline

Definition at line 79 of file ElementFragmentAlgorithm.h.

Referenced by XFEM::cutMeshWithEFA(), and TEST().

79 { return _parent_elements; };
std::vector< EFAElement * > _parent_elements

◆ getPermanentNodes()

const std::map<unsigned int, EFANode *>& ElementFragmentAlgorithm::getPermanentNodes ( )
inline

Definition at line 82 of file ElementFragmentAlgorithm.h.

Referenced by TEST().

82 { return _permanent_nodes; }
std::map< unsigned int, EFANode * > _permanent_nodes

◆ getTempNodes()

const std::map<unsigned int, EFANode *>& ElementFragmentAlgorithm::getTempNodes ( )
inline

Definition at line 83 of file ElementFragmentAlgorithm.h.

Referenced by TEST().

83 { return _temp_nodes; }
std::map< unsigned int, EFANode * > _temp_nodes

◆ initCrackTipTopology()

void ElementFragmentAlgorithm::initCrackTipTopology ( )

Definition at line 194 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::buildEFAMesh(), and TEST().

195 {
196  _crack_tip_elements.clear(); // re-build CrackTipElements!
197  for (auto pair : _elements)
198  pair.second->initCrackTip(_crack_tip_elements); // CrackTipElements changed here
199 }
std::map< unsigned int, EFAElement * > _elements
std::set< EFAElement * > _crack_tip_elements

◆ printMesh()

void ElementFragmentAlgorithm::printMesh ( )

Definition at line 482 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::cutMeshWithEFA(), sanityCheck(), and TEST().

483 {
484  _ostream << "============================================================"
485  << "==================================================" << std::endl;
486  _ostream << " CutElemMesh Data" << std::endl;
487  _ostream << "============================================================"
488  << "==================================================" << std::endl;
489  _ostream << "Permanent Nodes:" << std::endl;
490  std::map<unsigned int, EFANode *>::iterator mit;
491  unsigned int counter = 0;
492  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
493  {
494  _ostream << " " << mit->second->id();
495  counter += 1;
496  if (counter % 10 == 0)
497  _ostream << std::endl;
498  }
499  _ostream << std::endl;
500  _ostream << "Temp Nodes:" << std::endl;
501  counter = 0;
502  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
503  {
504  _ostream << " " << mit->second->id();
505  counter += 1;
506  if (counter % 10 == 0)
507  _ostream << std::endl;
508  }
509  _ostream << std::endl;
510  _ostream << "Embedded Nodes:" << std::endl;
511  counter = 0;
512  for (mit = _embedded_nodes.begin(); mit != _embedded_nodes.end(); ++mit)
513  {
514  _ostream << " " << mit->second->id();
515  counter += 1;
516  if (counter % 10 == 0)
517  _ostream << std::endl;
518  }
519  _ostream << std::endl;
520  _ostream << "Embedded Permanent Nodes:" << std::endl;
521  counter = 0;
522  for (mit = _embedded_permanent_nodes.begin(); mit != _embedded_permanent_nodes.end(); ++mit)
523  {
524  _ostream << " " << mit->second->id();
525  counter += 1;
526  if (counter % 10 == 0)
527  _ostream << std::endl;
528  }
529  _ostream << std::endl;
530  _ostream << "Parent Elements:" << std::endl;
531  counter = 0;
532  for (unsigned int i = 0; i < _parent_elements.size(); ++i)
533  {
534  _ostream << " " << _parent_elements[i]->id();
535  counter += 1;
536  if (counter % 10 == 0)
537  _ostream << std::endl;
538  }
539  _ostream << std::endl;
540  _ostream << "Child Elements:" << std::endl;
541  counter = 0;
542  for (unsigned int i = 0; i < _child_elements.size(); ++i)
543  {
544  _ostream << " " << _child_elements[i]->id();
545  counter += 1;
546  if (counter % 10 == 0)
547  _ostream << std::endl;
548  }
549  _ostream << std::endl;
550  _ostream << "Elements:" << std::endl;
551  _ostream << " id "
552  << "| nodes "
553  << "| embedded nodes "
554  << "| edge neighbors "
555  << "| frag "
556  << "| frag link ... " << std::endl;
557  _ostream << "------------------------------------------------------------"
558  << "--------------------------------------------------" << std::endl;
559  std::map<unsigned int, EFAElement *>::iterator eit;
560  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
561  {
562  EFAElement * currElem = eit->second;
563  currElem->printElement(_ostream);
564  }
565 }
virtual void printElement(std::ostream &ostream) const =0
std::vector< EFAElement * > _child_elements
std::vector< EFAElement * > _parent_elements
std::map< unsigned int, EFAElement * > _elements
std::map< unsigned int, EFANode * > _embedded_permanent_nodes
std::map< unsigned int, EFANode * > _temp_nodes
std::map< unsigned int, EFANode * > _embedded_nodes
std::map< unsigned int, EFANode * > _permanent_nodes

◆ reset()

void ElementFragmentAlgorithm::reset ( )

Definition at line 318 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::buildEFAMesh().

319 {
320  _new_nodes.clear();
321  _child_elements.clear();
322  _parent_elements.clear();
323  _crack_tip_elements.clear();
324  _inverse_connectivity.clear();
325 
326  std::map<unsigned int, EFANode *>::iterator mit;
327  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
328  {
329  delete mit->second;
330  mit->second = nullptr;
331  }
332  _permanent_nodes.clear();
333 
334  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
335  {
336  delete mit->second;
337  mit->second = nullptr;
338  }
339  _temp_nodes.clear();
340  std::map<unsigned int, EFAElement *>::iterator eit;
341  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
342  {
343  delete eit->second;
344  eit->second = nullptr;
345  }
346  _elements.clear();
347 }
std::vector< EFAElement * > _child_elements
std::vector< EFAElement * > _parent_elements
std::map< unsigned int, EFAElement * > _elements
std::set< EFAElement * > _crack_tip_elements
std::vector< EFANode * > _new_nodes
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
std::map< unsigned int, EFANode * > _temp_nodes
std::map< unsigned int, EFANode * > _permanent_nodes

◆ restoreFragmentInfo()

void ElementFragmentAlgorithm::restoreFragmentInfo ( EFAElement *const  elem,
const EFAElement *const  from_elem 
)

Definition at line 393 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::buildEFAMesh().

395 {
396  elem->restoreFragment(from_elem);
397 }
virtual void restoreFragment(const EFAElement *const from_elem)=0

◆ sanityCheck()

void ElementFragmentAlgorithm::sanityCheck ( )

Definition at line 440 of file ElementFragmentAlgorithm.C.

Referenced by updateTopology().

441 {
442  // Make sure there are no remaining TempNodes
443  if (_temp_nodes.size() > 0)
444  {
445  _ostream << "_temp_nodes size > 0. size=" << _temp_nodes.size() << std::endl;
446  printMesh();
447  throw std::runtime_error("_temp_nodes size > 0");
448  }
449 }
std::map< unsigned int, EFANode * > _temp_nodes

◆ updateCrackTipElements()

void ElementFragmentAlgorithm::updateCrackTipElements ( )

Definition at line 452 of file ElementFragmentAlgorithm.C.

Referenced by updateTopology().

453 {
454  std::set<EFAElement *>::iterator sit;
455  // Delete all elements that were previously flagged as crack tip elements if they have
456  // been split (and hence appear in ParentElements).
457  for (unsigned int i = 0; i < _parent_elements.size(); ++i)
458  {
459  sit = _crack_tip_elements.find(_parent_elements[i]);
460  if (sit != _crack_tip_elements.end())
461  _crack_tip_elements.erase(sit);
462  }
463 
464  // Go through new child elements to find elements that are newly at the crack tip due to
465  // crack growth.
466  for (unsigned int elem_iter = 0; elem_iter < _child_elements.size(); elem_iter++)
467  {
468  EFAElement * childElem = _child_elements[elem_iter];
469  if (childElem->isCrackTipElement())
470  _crack_tip_elements.insert(childElem);
471  } // loop over (new) child elements
472 
473  //_ostream << "Crack tip elements: ";
474  // for (sit=CrackTipElements.begin(); sit!=CrackTipElements.end(); ++sit)
475  //{
476  // _ostream << (*sit)->id<<" ";
477  //}
478  //_ostream << std::endl;
479 }
virtual bool isCrackTipElement() const =0
std::vector< EFAElement * > _child_elements
std::vector< EFAElement * > _parent_elements
std::set< EFAElement * > _crack_tip_elements

◆ updateEdgeNeighbors()

void ElementFragmentAlgorithm::updateEdgeNeighbors ( )

Definition at line 171 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::buildEFAMesh(), case1Common(), case2Mesh(), case5Mesh(), case6Mesh(), case7Mesh(), and TEST().

172 {
173  std::map<unsigned int, EFAElement *>::iterator eit;
174  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
175  {
176  EFAElement * elem = eit->second;
177  elem->clearNeighbors();
178  }
179 
180  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
181  {
182  EFAElement * curr_elem = eit->second;
184  } // loop over all elements
185 
186  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
187  {
188  EFAElement * curr_elem = eit->second;
189  curr_elem->neighborSanityCheck();
190  }
191 }
std::map< unsigned int, EFAElement * > _elements
virtual void neighborSanityCheck() const =0
virtual void setupNeighbors(std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivityMap)=0
virtual void clearNeighbors()=0
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity

◆ updatePhysicalLinksAndFragments()

void ElementFragmentAlgorithm::updatePhysicalLinksAndFragments ( )

Definition at line 281 of file ElementFragmentAlgorithm.C.

Referenced by case1Common(), case2Intersections(), XFEM::cutMeshWithEFA(), and TEST().

282 {
283  // loop over the elements in the mesh
284  std::map<unsigned int, EFAElement *>::iterator eit;
285  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
286  {
287  EFAElement * curr_elem = eit->second;
289  } // loop over all elements
290 }
std::map< unsigned int, EFAElement * > _elements
std::set< EFAElement * > _crack_tip_elements
virtual void updateFragments(const std::set< EFAElement *> &CrackTipElements, std::map< unsigned int, EFANode *> &EmbeddedNodes)=0
std::map< unsigned int, EFANode * > _embedded_nodes

◆ updateTopology()

void ElementFragmentAlgorithm::updateTopology ( bool  mergeUncutVirtualEdges = true)

Definition at line 293 of file ElementFragmentAlgorithm.C.

Referenced by XFEM::cutMeshWithEFA(), and TEST().

294 {
295  // If mergeUncutVirtualEdges=true, this algorithm replicates the
296  // behavior of classical XFEM. If false, it gives the behavior of
297  // the Richardson et. al. (2011) paper
298 
299  _new_nodes.clear();
300  _child_elements.clear();
301  _parent_elements.clear();
302 
303  unsigned int first_new_node_id = Efa::getNewID(_permanent_nodes);
304 
306  connectFragments(mergeUncutVirtualEdges);
307  sanityCheck();
309 
310  for (const auto & [id, node] : _permanent_nodes)
311  if (id >= first_new_node_id)
312  _new_nodes.push_back(node);
313 
314  clearPotentialIsolatedNodes(); // _new_nodes and _permanent_nodes may change here
315 }
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
Definition: EFAFuncs.h:38
void connectFragments(bool mergeUncutVirtualEdges)
std::vector< EFAElement * > _child_elements
std::vector< EFAElement * > _parent_elements
std::vector< EFANode * > _new_nodes
std::map< unsigned int, EFANode * > _permanent_nodes

Member Data Documentation

◆ _child_elements

std::vector<EFAElement *> ElementFragmentAlgorithm::_child_elements
private

◆ _crack_tip_elements

std::set<EFAElement *> ElementFragmentAlgorithm::_crack_tip_elements
private

◆ _deleted_nodes

std::vector<EFANode *> ElementFragmentAlgorithm::_deleted_nodes
private

Definition at line 39 of file ElementFragmentAlgorithm.h.

◆ _elements

std::map<unsigned int, EFAElement *> ElementFragmentAlgorithm::_elements
private

◆ _embedded_nodes

std::map<unsigned int, EFANode *> ElementFragmentAlgorithm::_embedded_nodes
private

◆ _embedded_permanent_nodes

std::map<unsigned int, EFANode *> ElementFragmentAlgorithm::_embedded_permanent_nodes
private

◆ _inverse_connectivity

std::map<EFANode *, std::set<EFAElement *> > ElementFragmentAlgorithm::_inverse_connectivity
private

◆ _new_nodes

std::vector<EFANode *> ElementFragmentAlgorithm::_new_nodes
private

◆ _ostream

std::ostream& ElementFragmentAlgorithm::_ostream
private

Definition at line 30 of file ElementFragmentAlgorithm.h.

Referenced by printMesh(), and sanityCheck().

◆ _parent_elements

std::vector<EFAElement *> ElementFragmentAlgorithm::_parent_elements
private

◆ _permanent_nodes

std::map<unsigned int, EFANode *> ElementFragmentAlgorithm::_permanent_nodes
private

◆ _temp_nodes

std::map<unsigned int, EFANode *> ElementFragmentAlgorithm::_temp_nodes
private

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