www.mooseframework.org
ElementFragmentAlgorithm.C
Go to the documentation of this file.
1 /****************************************************************/
2 /* MOOSE - Multiphysics Object Oriented Simulation Environment */
3 /* */
4 /* All contents are licensed under LGPL V2.1 */
5 /* See LICENSE for full restrictions */
6 /****************************************************************/
7 
8 // TODO:
9 // Clean up error checking in (!found_edge)
10 // Save fragment for uncut element ahead of crack tip to avoid renumbering if only embedded node
11 // Add common code to compare neighbors & fragments (replace multiple set_intersection calls)
12 
13 // Handle cases other than 0 or 2 cut edges/elem (include data structure to link cut edges with
14 // cracks?)
15 // Allow for more than one cut on an edge
16 // Support 2d higher order elements
17 // 3D propagation
18 // 3D branching
19 
21 
22 #include "EFANode.h"
23 #include "EFAElement3D.h"
24 #include "EFAElement2D.h"
25 #include "EFAFuncs.h"
26 #include "EFAError.h"
27 
28 ElementFragmentAlgorithm::ElementFragmentAlgorithm(std::ostream & os) : _ostream(os) {}
29 
31 {
32  std::map<unsigned int, EFANode *>::iterator mit;
33  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
34  {
35  delete mit->second;
36  mit->second = NULL;
37  }
38  for (mit = _embedded_nodes.begin(); mit != _embedded_nodes.end(); ++mit)
39  {
40  delete mit->second;
41  mit->second = NULL;
42  }
43  for (mit = _embedded_permanent_nodes.begin(); mit != _embedded_permanent_nodes.end(); ++mit)
44  {
45  delete mit->second;
46  mit->second = NULL;
47  }
48  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
49  {
50  delete mit->second;
51  mit->second = NULL;
52  }
53  std::map<unsigned int, EFAElement *>::iterator eit;
54  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
55  {
56  delete eit->second;
57  eit->second = NULL;
58  }
59 }
60 
61 unsigned int
62 ElementFragmentAlgorithm::add2DElements(std::vector<std::vector<unsigned int>> & quads)
63 {
64  unsigned int first_id = 0;
65  unsigned int num_nodes = quads[0].size();
66 
67  if (quads.size() == 0)
68  EFAError("add2DElements called with empty vector of quads");
69 
70  for (unsigned int i = 0; i < quads.size(); ++i)
71  {
72  unsigned int new_elem_id = Efa::getNewID(_elements);
73  EFAElement2D * newElem = new EFAElement2D(new_elem_id, num_nodes);
74  _elements.insert(std::make_pair(new_elem_id, newElem));
75 
76  if (i == 0)
77  first_id = new_elem_id;
78 
79  for (unsigned int j = 0; j < num_nodes; ++j)
80  {
81  EFANode * currNode = NULL;
82  std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quads[i][j]);
83  if (mit == _permanent_nodes.end())
84  {
85  currNode = new EFANode(quads[i][j], EFANode::N_CATEGORY_PERMANENT);
86  _permanent_nodes.insert(std::make_pair(quads[i][j], currNode));
87  }
88  else
89  currNode = mit->second;
90 
91  newElem->setNode(j, currNode);
92  _inverse_connectivity[currNode].insert(newElem);
93  }
94  newElem->createEdges();
95  }
96  return first_id;
97 }
98 
99 EFAElement *
100 ElementFragmentAlgorithm::add2DElement(std::vector<unsigned int> quad, unsigned int id)
101 {
102  unsigned int num_nodes = quad.size();
103 
104  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
105  if (mit != _elements.end())
106  EFAError("In add2DElement element with id: ", id, " already exists");
107 
108  EFAElement2D * newElem = new EFAElement2D(id, num_nodes);
109  _elements.insert(std::make_pair(id, newElem));
110 
111  for (unsigned int j = 0; j < num_nodes; ++j)
112  {
113  EFANode * currNode = NULL;
114  std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quad[j]);
115  if (mit == _permanent_nodes.end())
116  {
117  currNode = new EFANode(quad[j], EFANode::N_CATEGORY_PERMANENT);
118  _permanent_nodes.insert(std::make_pair(quad[j], currNode));
119  }
120  else
121  currNode = mit->second;
122 
123  newElem->setNode(j, currNode);
124  _inverse_connectivity[currNode].insert(newElem);
125  }
126  newElem->createEdges();
127  return newElem;
128 }
129 
130 EFAElement *
131 ElementFragmentAlgorithm::add3DElement(std::vector<unsigned int> quad, unsigned int id)
132 {
133  unsigned int num_nodes = quad.size();
134  unsigned int num_faces = 0;
135  if (num_nodes == 27)
136  num_faces = 6;
137  else if (num_nodes == 20)
138  num_faces = 6;
139  else if (num_nodes == 8)
140  num_faces = 6;
141  else if (num_nodes == 4)
142  num_faces = 4;
143  else if (num_nodes == 10)
144  num_faces = 4;
145  else
146  EFAError("In add3DElement element with id: ", id, " has invalid num_nodes");
147 
148  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
149  if (mit != _elements.end())
150  EFAError("In add3DElement element with id: ", id, " already exists");
151 
152  EFAElement3D * newElem = new EFAElement3D(id, num_nodes, num_faces);
153  _elements.insert(std::make_pair(id, newElem));
154 
155  for (unsigned int j = 0; j < num_nodes; ++j)
156  {
157  EFANode * currNode = NULL;
158  std::map<unsigned int, EFANode *>::iterator mit = _permanent_nodes.find(quad[j]);
159  if (mit == _permanent_nodes.end())
160  {
161  currNode = new EFANode(quad[j], EFANode::N_CATEGORY_PERMANENT);
162  _permanent_nodes.insert(std::make_pair(quad[j], currNode));
163  }
164  else
165  currNode = mit->second;
166 
167  newElem->setNode(j, currNode);
168  _inverse_connectivity[currNode].insert(newElem);
169  }
170  newElem->createFaces();
171  return newElem;
172 }
173 
174 void
176 {
177  std::map<unsigned int, EFAElement *>::iterator eit;
178  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
179  {
180  EFAElement * elem = eit->second;
181  elem->clearNeighbors();
182  }
183 
184  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
185  {
186  EFAElement * curr_elem = eit->second;
188  } // loop over all elements
189 
190  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
191  {
192  EFAElement * curr_elem = eit->second;
193  curr_elem->neighborSanityCheck();
194  }
195 }
196 
197 void
199 {
200  _crack_tip_elements.clear(); // re-build CrackTipElements!
201  std::map<unsigned int, EFAElement *>::iterator eit;
202  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
203  {
204  EFAElement * curr_elem = eit->second;
205  curr_elem->initCrackTip(_crack_tip_elements); // CrackTipElements changed here
206  }
207 }
208 
209 void
211  unsigned int edgeid,
212  double position)
213 {
214  // this method is called when we are marking cut edges
215  std::map<unsigned int, EFAElement *>::iterator eit = _elements.find(elemid);
216  if (eit == _elements.end())
217  EFAError("Could not find element with id: ", elemid, " in addEdgeIntersection");
218 
219  EFAElement2D * curr_elem = dynamic_cast<EFAElement2D *>(eit->second);
220  if (!curr_elem)
221  EFAError("addElemEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
222  curr_elem->addEdgeCut(edgeid, position, NULL, _embedded_nodes, true);
223 }
224 
225 void
226 ElementFragmentAlgorithm::addElemNodeIntersection(unsigned int elemid, unsigned int nodeid)
227 {
228  // this method is called when we are marking cut nodes
229  std::map<unsigned int, EFAElement *>::iterator eit = _elements.find(elemid);
230  if (eit == _elements.end())
231  EFAError("Could not find element with id: ", elemid, " in addElemNodeIntersection");
232 
233  EFAElement2D * curr_elem = dynamic_cast<EFAElement2D *>(eit->second);
234  if (!curr_elem)
235  EFAError("addElemNodeIntersection: elem ", elemid, " is not of type EFAelement2D");
236 
237  // Only add cut node when the curr_elem does not have any fragment
238  if (curr_elem->numFragments() == 0)
239  curr_elem->addNodeCut(nodeid, NULL, _permanent_nodes, _embedded_permanent_nodes);
240 }
241 
242 bool
244  unsigned int frag_edge_id,
245  double position)
246 {
247  // N.B. this method must be called after addEdgeIntersection
248  std::map<unsigned int, EFAElement *>::iterator eit = _elements.find(elemid);
249  if (eit == _elements.end())
250  EFAError("Could not find element with id: ", elemid, " in addFragEdgeIntersection");
251 
252  EFAElement2D * elem = dynamic_cast<EFAElement2D *>(eit->second);
253  if (!elem)
254  EFAError("addFragEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
255  return elem->addFragmentEdgeCut(frag_edge_id, position, _embedded_nodes);
256 }
257 
258 void
260  unsigned int faceid,
261  std::vector<unsigned int> edgeid,
262  std::vector<double> position)
263 {
264  // this method is called when we are marking cut edges
265  std::map<unsigned int, EFAElement *>::iterator eit = _elements.find(elemid);
266  if (eit == _elements.end())
267  EFAError("Could not find element with id: ", elemid, " in addEdgeIntersection");
268 
269  EFAElement3D * curr_elem = dynamic_cast<EFAElement3D *>(eit->second);
270  if (!curr_elem)
271  EFAError("addElemEdgeIntersection: elem ", elemid, " is not of type EFAelement2D");
272 
273  // add cuts to two face edges at the same time
274  curr_elem->addFaceEdgeCut(faceid, edgeid[0], position[0], NULL, _embedded_nodes, true, true);
275  curr_elem->addFaceEdgeCut(faceid, edgeid[1], position[1], NULL, _embedded_nodes, true, true);
276 }
277 
278 void
280  unsigned int /*FragFaceID*/,
281  std::vector<unsigned int> /*FragFaceEdgeID*/,
282  std::vector<double> /*position*/)
283 {
284  // TODO: need to finish this for 3D problems
285 }
286 
287 void
289 {
290  // loop over the elements in the mesh
291  std::map<unsigned int, EFAElement *>::iterator eit;
292  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
293  {
294  EFAElement * curr_elem = eit->second;
296  } // loop over all elements
297 }
298 
299 void
300 ElementFragmentAlgorithm::updateTopology(bool mergeUncutVirtualEdges)
301 {
302  // If mergeUncutVirtualEdges=true, this algorithm replicates the
303  // behavior of classical XFEM. If false, it gives the behavior of
304  // the Richardson et. al. (2011) paper
305 
306  _new_nodes.clear();
307  _child_elements.clear();
308  _parent_elements.clear();
309  // _merged_edge_map.clear();
310 
311  unsigned int first_new_node_id = Efa::getNewID(_permanent_nodes);
312 
314  connectFragments(mergeUncutVirtualEdges);
315  sanityCheck();
317 
318  std::map<unsigned int, EFANode *>::iterator mit;
319  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
320  {
321  if (mit->first >= first_new_node_id)
322  _new_nodes.push_back(mit->second);
323  }
324  clearPotentialIsolatedNodes(); // _new_nodes and _permanent_nodes may change here
325 }
326 
327 void
329 {
330  _new_nodes.clear();
331  _child_elements.clear();
332  _parent_elements.clear();
333  // _merged_edge_map.clear();
334  _crack_tip_elements.clear();
335  _inverse_connectivity.clear();
336 
337  std::map<unsigned int, EFANode *>::iterator mit;
338  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
339  {
340  delete mit->second;
341  mit->second = NULL;
342  }
343  _permanent_nodes.clear();
344  // for (mit = EmbeddedNodes.begin(); mit != EmbeddedNodes.end(); ++mit )
345  // {
346  // delete mit->second;
347  // mit->second = NULL;
348  // }
349  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
350  {
351  delete mit->second;
352  mit->second = NULL;
353  }
354  _temp_nodes.clear();
355  std::map<unsigned int, EFAElement *>::iterator eit;
356  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
357  {
358  delete eit->second;
359  eit->second = NULL;
360  }
361  _elements.clear();
362 }
363 
364 void
366 {
367  _inverse_connectivity.clear();
368  for (unsigned int i = 0; i < _parent_elements.size(); ++i)
369  {
371  EFAError("Attempted to delete parent element: ",
372  _parent_elements[i]->id(),
373  " from _elements, but couldn't find it");
374  }
375  _parent_elements.clear();
376 
377  std::map<unsigned int, EFAElement *>::iterator eit;
378  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
379  {
380  EFAElement * curr_elem = eit->second;
381  curr_elem->clearParentAndChildren();
382  for (unsigned int j = 0; j < curr_elem->numNodes(); j++)
383  {
384  EFANode * curr_node = curr_elem->getNode(j);
385  _inverse_connectivity[curr_node].insert(curr_elem);
386  }
387  }
388 
389  std::map<unsigned int, EFANode *>::iterator mit;
390  for (mit = _permanent_nodes.begin(); mit != _permanent_nodes.end(); ++mit)
391  mit->second->removeParent();
392 
393  for (mit = _temp_nodes.begin(); mit != _temp_nodes.end(); ++mit)
394  {
395  delete mit->second;
396  mit->second = NULL;
397  }
398  _temp_nodes.clear();
399 
400  _new_nodes.clear();
401  _child_elements.clear();
402 
403  // TODO: Sanity check to make sure that there are no nodes that are not connected
404  // to an element -- there shouldn't be any
405 }
406 
407 void
409  const EFAElement * const from_elem)
410 {
411  elem->restoreFragment(from_elem);
412 }
413 
414 void
416 {
417  // temporary container for new elements -- will be merged with Elements
418  std::map<unsigned int, EFAElement *> newChildElements;
419 
420  // loop over the original elements in the mesh
421  std::map<unsigned int, EFAElement *>::iterator eit;
422  std::map<unsigned int, EFAElement *>::iterator ElementsEnd = _elements.end();
423  for (eit = _elements.begin(); eit != ElementsEnd; ++eit)
424  {
425  EFAElement * curr_elem = eit->second;
426  curr_elem->createChild(_crack_tip_elements,
427  _elements,
428  newChildElements,
431  _temp_nodes);
432  } // loop over elements
433  // Merge newChildElements back in with Elements
434  _elements.insert(newChildElements.begin(), newChildElements.end());
435 }
436 
437 void
438 ElementFragmentAlgorithm::connectFragments(bool mergeUncutVirtualEdges)
439 {
440  // now perform the comparison on the children
441  for (unsigned int elem_iter = 0; elem_iter < _child_elements.size(); elem_iter++)
442  {
443  EFAElement * childElem = _child_elements[elem_iter];
444  childElem->connectNeighbors(
445  _permanent_nodes, _temp_nodes, _inverse_connectivity, mergeUncutVirtualEdges);
446  childElem->updateFragmentNode();
447  } // loop over child elements
448 
449  std::vector<EFAElement *>::iterator vit;
450  for (vit = _child_elements.begin(); vit != _child_elements.end();)
451  {
452  if (*vit == NULL)
453  vit = _child_elements.erase(vit);
454  else
455  ++vit;
456  }
457 }
458 
459 void
461 {
462  // Make sure there are no remaining TempNodes
463  if (_temp_nodes.size() > 0)
464  {
465  _ostream << "_temp_nodes size > 0. size=" << _temp_nodes.size() << std::endl;
466  printMesh();
467  exit(1);
468  }
469 }
470 
471 void
473 {
474  std::set<EFAElement *>::iterator sit;
475  // Delete all elements that were previously flagged as crack tip elements if they have
476  // been split (and hence appear in ParentElements).
477  for (unsigned int i = 0; i < _parent_elements.size(); ++i)
478  {
479  sit = _crack_tip_elements.find(_parent_elements[i]);
480  if (sit != _crack_tip_elements.end())
481  _crack_tip_elements.erase(sit);
482  }
483 
484  // Go through new child elements to find elements that are newly at the crack tip due to
485  // crack growth.
486  for (unsigned int elem_iter = 0; elem_iter < _child_elements.size(); elem_iter++)
487  {
488  EFAElement * childElem = _child_elements[elem_iter];
489  if (childElem->isCrackTipElement())
490  _crack_tip_elements.insert(childElem);
491  } // loop over (new) child elements
492 
493  //_ostream << "Crack tip elements: ";
494  // for (sit=CrackTipElements.begin(); sit!=CrackTipElements.end(); ++sit)
495  //{
496  // _ostream << (*sit)->id<<" ";
497  //}
498  //_ostream << std::endl;
499 }
500 
501 void
503 {
504  _ostream << "============================================================"
505  << "==================================================" << std::endl;
506  _ostream << " CutElemMesh Data" << std::endl;
507  _ostream << "============================================================"
508  << "==================================================" << std::endl;
509  _ostream << "Permanent Nodes:" << std::endl;
510  std::map<unsigned int, EFANode *>::iterator mit;
511  unsigned int counter = 0;
512  for (mit = _permanent_nodes.begin(); mit != _permanent_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 << "Temp Nodes:" << std::endl;
521  counter = 0;
522  for (mit = _temp_nodes.begin(); mit != _temp_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 << "Embedded Nodes:" << std::endl;
531  counter = 0;
532  for (mit = _embedded_nodes.begin(); mit != _embedded_nodes.end(); ++mit)
533  {
534  _ostream << " " << mit->second->id();
535  counter += 1;
536  if (counter % 10 == 0)
537  _ostream << std::endl;
538  }
539  _ostream << std::endl;
540  _ostream << "Embedded Permanent Nodes:" << std::endl;
541  counter = 0;
542  for (mit = _embedded_permanent_nodes.begin(); mit != _embedded_permanent_nodes.end(); ++mit)
543  {
544  _ostream << " " << mit->second->id();
545  counter += 1;
546  if (counter % 10 == 0)
547  _ostream << std::endl;
548  }
549  _ostream << std::endl;
550  _ostream << "Parent Elements:" << std::endl;
551  counter = 0;
552  for (unsigned int i = 0; i < _parent_elements.size(); ++i)
553  {
554  _ostream << " " << _parent_elements[i]->id();
555  counter += 1;
556  if (counter % 10 == 0)
557  _ostream << std::endl;
558  }
559  _ostream << std::endl;
560  _ostream << "Child Elements:" << std::endl;
561  counter = 0;
562  for (unsigned int i = 0; i < _child_elements.size(); ++i)
563  {
564  _ostream << " " << _child_elements[i]->id();
565  counter += 1;
566  if (counter % 10 == 0)
567  _ostream << std::endl;
568  }
569  _ostream << std::endl;
570  _ostream << "Elements:" << std::endl;
571  _ostream << " id "
572  << "| nodes "
573  << "| embedded nodes "
574  << "| edge neighbors "
575  << "| frag "
576  << "| frag link ... " << std::endl;
577  _ostream << "------------------------------------------------------------"
578  << "--------------------------------------------------" << std::endl;
579  std::map<unsigned int, EFAElement *>::iterator eit;
580  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
581  {
582  EFAElement * currElem = eit->second;
583  currElem->printElement(_ostream);
584  }
585 }
586 
587 EFAElement *
589 {
590  std::map<unsigned int, EFAElement *>::iterator mit = _elements.find(id);
591  if (mit == _elements.end())
592  EFAError("in getElemByID() could not find element: ", id);
593  return mit->second;
594 }
595 
596 unsigned int
598 {
599  unsigned int elem_id = 99999;
600  std::map<unsigned int, EFAElement *>::iterator eit;
601  for (eit = _elements.begin(); eit != _elements.end(); ++eit)
602  {
603  EFAElement * curr_elem = eit->second;
604  unsigned int counter = 0;
605  for (unsigned int i = 0; i < curr_elem->numNodes(); ++i)
606  {
607  if (curr_elem->getNode(i)->id() == node_id[i])
608  counter += 1;
609  }
610  if (counter == curr_elem->numNodes())
611  {
612  elem_id = curr_elem->id();
613  break;
614  }
615  }
616  return elem_id;
617 }
618 
619 void
621 {
622  // Collect all parent nodes that will be isolated
623  std::map<EFANode *, std::vector<EFANode *>> isolate_parent_to_child;
624  for (unsigned int i = 0; i < _new_nodes.size(); ++i)
625  {
626  EFANode * parent_node = _new_nodes[i]->parent();
627  if (!parent_node)
628  EFAError("a new permanent node must have a parent node!");
629  bool isParentNodeInNewElem = false;
630  for (unsigned int j = 0; j < _child_elements.size(); ++j)
631  {
632  if (_child_elements[j]->containsNode(parent_node))
633  {
634  isParentNodeInNewElem = true;
635  break;
636  }
637  }
638  if (!isParentNodeInNewElem)
639  isolate_parent_to_child[parent_node].push_back(_new_nodes[i]);
640  }
641 
642  // For each isolated parent node, pick one of its child new node
643  // Then, switch that child with its parent for all new elems
644  std::map<EFANode *, std::vector<EFANode *>>::iterator mit;
645  for (mit = isolate_parent_to_child.begin(); mit != isolate_parent_to_child.end(); ++mit)
646  {
647  EFANode * parent_node = mit->first;
648  EFANode * child_node = (mit->second)[0]; // need to discard it and swap it back to its parent
649  for (unsigned int i = 0; i < _child_elements.size(); ++i)
650  {
651  if (_child_elements[i]->containsNode(child_node))
652  _child_elements[i]->switchNode(parent_node, child_node, true);
653  }
654  _new_nodes.erase(std::remove(_new_nodes.begin(), _new_nodes.end(), child_node),
655  _new_nodes.end());
657  }
658 }
void clearParentAndChildren()
Definition: EFAElement.C:207
void addElemNodeIntersection(unsigned int elemid, unsigned int nodeid)
virtual void updateFragments(const std::set< EFAElement * > &CrackTipElements, std::map< unsigned int, EFANode * > &EmbeddedNodes)=0
void addElemEdgeIntersection(unsigned int elemid, unsigned int edgeid, double position)
EFANode * getNode(unsigned int node_id) const
Definition: EFAElement.C:44
ElementFragmentAlgorithm(std::ostream &os)
Constructor.
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:21
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
void createFaces()
unsigned int id() const
Definition: EFAElement.C:26
void connectFragments(bool mergeUncutVirtualEdges)
virtual void setupNeighbors(std::map< EFANode *, std::set< EFAElement * >> &InverseConnectivityMap)=0
std::vector< EFAElement * > _child_elements
std::vector< EFAElement * > _parent_elements
void addFragFaceIntersection(unsigned int ElemID, unsigned int FragFaceID, std::vector< unsigned int > FragFaceEdgeID, std::vector< double > position)
void updateTopology(bool mergeUncutVirtualEdges=true)
std::map< unsigned int, EFAElement * > _elements
unsigned int add2DElements(std::vector< std::vector< unsigned int >> &quads)
unsigned int numNodes() const
Definition: EFAElement.C:32
virtual void updateFragmentNode()=0
void addElemFaceIntersection(unsigned int elemid, unsigned int faceid, std::vector< unsigned int > edgeid, std::vector< double > position)
virtual bool isCrackTipElement() const =0
bool addFragEdgeIntersection(unsigned int elemid, unsigned int frag_edge_id, double position)
virtual void neighborSanityCheck() const =0
std::map< unsigned int, EFANode * > _embedded_permanent_nodes
virtual void initCrackTip(std::set< EFAElement * > &CrackTipElements)=0
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
virtual void restoreFragment(const EFAElement *const from_elem)=0
std::set< EFAElement * > _crack_tip_elements
virtual void clearNeighbors()=0
std::vector< EFANode * > _new_nodes
virtual void printElement(std::ostream &ostream)=0
void restoreFragmentInfo(EFAElement *const elem, const EFAElement *const from_elem)
unsigned int getElemIdByNodes(unsigned int *node_id)
std::map< EFANode *, std::set< EFAElement * > > _inverse_connectivity
void addEdgeCut(unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode * > &EmbeddedNodes, bool add_to_neighbor)
unsigned int id() const
Definition: EFANode.C:34
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
EFAElement * add2DElement(std::vector< unsigned int > quad, unsigned int id)
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 * > _temp_nodes
EFAElement * getElemByID(unsigned int id)
unsigned int getNewID(std::map< unsigned int, T * > &theMap)
Definition: EFAFuncs.h:37
std::map< unsigned int, EFANode * > _embedded_nodes
std::map< unsigned int, EFANode * > _permanent_nodes
bool addFragmentEdgeCut(unsigned int frag_edge_id, double position, std::map< unsigned int, EFANode * > &EmbeddedNodes)
EFAElement * add3DElement(std::vector< unsigned int > quad, unsigned int id)
static unsigned int counter
void setNode(unsigned int node_id, EFANode *node)
Definition: EFAElement.C:38
void createEdges()
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)