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

#include <EFAFragment2D.h>

Inheritance diagram for EFAFragment2D:
[legend]

Public Member Functions

 EFAFragment2D (EFAElement2D *host, bool create_boundary_edges, const EFAElement2D *from_host, unsigned int frag_id=std::numeric_limits< unsigned int >::max())
 
 EFAFragment2D (EFAElement2D *host, const EFAFace *from_face)
 
 ~EFAFragment2D ()
 
virtual void switchNode (EFANode *new_node, EFANode *old_node)
 
virtual bool containsNode (EFANode *node) const
 
virtual unsigned int getNumCuts () const
 
virtual unsigned int getNumCutNodes () const
 
virtual std::set< EFANode * > getAllNodes () const
 
virtual bool isConnected (EFAFragment *other_fragment) const
 
virtual void removeInvalidEmbeddedNodes (std::map< unsigned int, EFANode *> &EmbeddedNodes)
 
void combineTipEdges ()
 
bool isEdgeInterior (unsigned int edge_id) const
 
std::vector< unsigned int > getInteriorEdgeID () const
 
bool isSecondaryInteriorEdge (unsigned int edge_id) const
 
unsigned int numEdges () const
 
EFAEdgegetEdge (unsigned int edge_id) const
 
void addEdge (EFAEdge *new_edge)
 
std::set< EFANode * > getEdgeNodes (unsigned int edge_id) const
 
EFAElement2DgetHostElement () const
 
std::vector< EFAFragment2D * > split ()
 
std::vector< EFANode * > getCommonNodes (EFAFragment *other) const
 

Private Attributes

EFAElement2D_host_elem
 
std::vector< EFAEdge * > _boundary_edges
 

Detailed Description

Definition at line 21 of file EFAFragment2D.h.

Constructor & Destructor Documentation

◆ EFAFragment2D() [1/2]

EFAFragment2D::EFAFragment2D ( EFAElement2D host,
bool  create_boundary_edges,
const EFAElement2D from_host,
unsigned int  frag_id = std::numeric_limits<unsigned int>::max() 
)

Definition at line 21 of file EFAFragment2D.C.

Referenced by split().

25  : EFAFragment(), _host_elem(host)
26 {
27  if (create_boundary_edges)
28  {
29  if (!from_host)
30  EFAError("EFAfragment2D constructor must have a from_host to copy from");
31  if (frag_id == std::numeric_limits<unsigned int>::max()) // copy the from_host itself
32  {
33  for (unsigned int i = 0; i < from_host->numEdges(); ++i)
34  _boundary_edges.push_back(new EFAEdge(*from_host->getEdge(i)));
35  }
36  else
37  {
38  if (frag_id > from_host->numFragments() - 1)
39  EFAError("In EFAfragment2D constructor fragment_copy_index out of bounds");
40  for (unsigned int i = 0; i < from_host->getFragment(frag_id)->numEdges(); ++i)
41  _boundary_edges.push_back(new EFAEdge(*from_host->getFragmentEdge(frag_id, i)));
42  }
43  }
44 }
unsigned int numEdges() const
EFAEdge * getEdge(unsigned int edge_id) const
unsigned int numEdges() const
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:202
EFAFragment2D * getFragment(unsigned int frag_id) const
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const

◆ EFAFragment2D() [2/2]

EFAFragment2D::EFAFragment2D ( EFAElement2D host,
const EFAFace from_face 
)

Definition at line 46 of file EFAFragment2D.C.

47  : EFAFragment(), _host_elem(host)
48 {
49  for (unsigned int i = 0; i < from_face->numEdges(); ++i)
50  _boundary_edges.push_back(new EFAEdge(*from_face->getEdge(i)));
51 }
unsigned int numEdges() const
Definition: EFAFace.C:254
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:260
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32

◆ ~EFAFragment2D()

EFAFragment2D::~EFAFragment2D ( )

Definition at line 53 of file EFAFragment2D.C.

54 {
55  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
56  {
57  if (_boundary_edges[i])
58  {
59  delete _boundary_edges[i];
60  _boundary_edges[i] = NULL;
61  }
62  }
63 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

Member Function Documentation

◆ addEdge()

void EFAFragment2D::addEdge ( EFAEdge new_edge)

Definition at line 310 of file EFAFragment2D.C.

Referenced by EFAElement2D::branchingSplit(), EFAFace::combineWithFace(), and split().

311 {
312  _boundary_edges.push_back(new_edge);
313 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

◆ combineTipEdges()

void EFAFragment2D::combineTipEdges ( )

Definition at line 168 of file EFAFragment2D.C.

169 {
170  // combine the tip edges in a crack tip fragment
171  // N.B. the host elem can only have one elem_tip_edge, otherwise it should have already been
172  // completely split
173  if (!_host_elem)
174  EFAError("In combine_tip_edges() the frag must have host_elem");
175 
176  bool has_tip_edges = false;
177  unsigned int elem_tip_edge_id = 99999;
178  std::vector<unsigned int> frag_tip_edge_id;
179  for (unsigned int i = 0; i < _host_elem->numEdges(); ++i)
180  {
181  frag_tip_edge_id.clear();
183  {
184  for (unsigned int j = 0; j < _boundary_edges.size(); ++j)
185  {
187  frag_tip_edge_id.push_back(j);
188  } // j
189  if (frag_tip_edge_id.size() == 2) // combine the two frag edges on this elem edge
190  {
191  has_tip_edges = true;
192  elem_tip_edge_id = i;
193  break;
194  }
195  }
196  } // i
197  if (has_tip_edges)
198  {
199  // frag_tip_edge_id[0] must precede frag_tip_edge_id[1]
200  unsigned int edge0_next(frag_tip_edge_id[0] < (numEdges() - 1) ? frag_tip_edge_id[0] + 1 : 0);
201  if (edge0_next != frag_tip_edge_id[1])
202  EFAError("frag_tip_edge_id[1] must be the next edge of frag_tip_edge_id[0]");
203 
204  // get the two end nodes of the new edge
205  EFANode * node1 = _boundary_edges[frag_tip_edge_id[0]]->getNode(0);
206  EFANode * emb_node = _boundary_edges[frag_tip_edge_id[0]]->getNode(1);
207  EFANode * node2 = _boundary_edges[frag_tip_edge_id[1]]->getNode(1);
208  if (emb_node != _boundary_edges[frag_tip_edge_id[1]]->getNode(0))
209  EFAError("fragment edges are not correctly set up");
210 
211  // get the new edge with one intersection
212  EFAEdge * elem_edge = _host_elem->getEdge(elem_tip_edge_id);
213  double xi_node1 = elem_edge->distanceFromNode1(node1);
214  double xi_node2 = elem_edge->distanceFromNode1(node2);
215  double xi_emb = elem_edge->distanceFromNode1(emb_node);
216  double position = (xi_emb - xi_node1) / (xi_node2 - xi_node1);
217  EFAEdge * full_edge = new EFAEdge(node1, node2);
218  full_edge->addIntersection(position, emb_node, node1);
219 
220  // combine the two original fragment edges
221  delete _boundary_edges[frag_tip_edge_id[0]];
222  delete _boundary_edges[frag_tip_edge_id[1]];
223  _boundary_edges[frag_tip_edge_id[0]] = full_edge;
224  _boundary_edges.erase(_boundary_edges.begin() + frag_tip_edge_id[1]);
225  }
226 }
unsigned int numEdges() const
EFAEdge * getEdge(unsigned int edge_id) const
bool hasIntersection() const
Definition: EFAEdge.C:198
unsigned int numEdges() const
double distanceFromNode1(EFANode *node) const
Definition: EFAEdge.C:248
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
bool containsEdge(const EFAEdge &other) const
Definition: EFAEdge.C:63
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition: EFAEdge.C:130
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32

◆ containsNode()

bool EFAFragment2D::containsNode ( EFANode node) const
virtual

Implements EFAFragment.

Definition at line 73 of file EFAFragment2D.C.

Referenced by isSecondaryInteriorEdge(), and split().

74 {
75  bool contains = false;
76  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
77  {
78  if (_boundary_edges[i]->containsNode(node))
79  {
80  contains = true;
81  break;
82  }
83  }
84  return contains;
85 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
virtual bool containsNode(EFANode *node) const
Definition: EFAFragment2D.C:73

◆ getAllNodes()

std::set< EFANode * > EFAFragment2D::getAllNodes ( ) const
virtual

Implements EFAFragment.

Definition at line 110 of file EFAFragment2D.C.

111 {
112  std::set<EFANode *> nodes;
113  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
114  {
115  nodes.insert(_boundary_edges[i]->getNode(0));
116  nodes.insert(_boundary_edges[i]->getNode(1));
117  }
118  return nodes;
119 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

◆ getCommonNodes()

std::vector< EFANode * > EFAFragment::getCommonNodes ( EFAFragment other) const
inherited

Definition at line 20 of file EFAFragment.C.

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

21 {
22  std::set<EFANode *> frag1_nodes = getAllNodes();
23  std::set<EFANode *> frag2_nodes = other->getAllNodes();
24  std::vector<EFANode *> common_nodes = Efa::getCommonElems(frag1_nodes, frag2_nodes);
25  return common_nodes;
26 }
virtual std::set< EFANode * > getAllNodes() const =0
std::vector< T > getCommonElems(std::set< T > &v1, std::set< T > &v2)
Definition: EFAFuncs.h:70

◆ getEdge()

EFAEdge * EFAFragment2D::getEdge ( unsigned int  edge_id) const

Definition at line 302 of file EFAFragment2D.C.

Referenced by EFAFace::EFAFace(), XFEMCutElem2D::getPhysicalQuadraturePoints(), isConnected(), and split().

303 {
304  if (edge_id > _boundary_edges.size() - 1)
305  EFAError("in EFAfragment2D::get_edge, index out of bounds");
306  return _boundary_edges[edge_id];
307 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

◆ getEdgeNodes()

std::set< EFANode * > EFAFragment2D::getEdgeNodes ( unsigned int  edge_id) const

Definition at line 316 of file EFAFragment2D.C.

317 {
318  std::set<EFANode *> edge_nodes;
319  edge_nodes.insert(_boundary_edges[edge_id]->getNode(0));
320  edge_nodes.insert(_boundary_edges[edge_id]->getNode(1));
321  return edge_nodes;
322 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

◆ getHostElement()

EFAElement2D * EFAFragment2D::getHostElement ( ) const

Definition at line 325 of file EFAFragment2D.C.

326 {
327  return _host_elem;
328 }
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32

◆ getInteriorEdgeID()

std::vector< unsigned int > EFAFragment2D::getInteriorEdgeID ( ) const

Definition at line 266 of file EFAFragment2D.C.

Referenced by XFEM::markCutEdgesByState().

267 {
268  std::vector<unsigned int> interior_edge_id;
269  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
270  {
271  if (isEdgeInterior(i))
272  interior_edge_id.push_back(i);
273  }
274  return interior_edge_id;
275 }
bool isEdgeInterior(unsigned int edge_id) const
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

◆ getNumCutNodes()

unsigned int EFAFragment2D::getNumCutNodes ( ) const
virtual

Implements EFAFragment.

Definition at line 100 of file EFAFragment2D.C.

101 {
102  unsigned int num_cut_nodes = 0;
103  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
104  if (_boundary_edges[i]->getNode(0)->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
105  num_cut_nodes++;
106  return num_cut_nodes;
107 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

◆ getNumCuts()

unsigned int EFAFragment2D::getNumCuts ( ) const
virtual

Implements EFAFragment.

Definition at line 88 of file EFAFragment2D.C.

Referenced by removeInvalidEmbeddedNodes().

89 {
90  unsigned int num_cut_edges = 0;
91  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
92  {
93  if (_boundary_edges[i]->hasIntersection())
94  num_cut_edges += _boundary_edges[i]->numEmbeddedNodes();
95  }
96  return num_cut_edges;
97 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33

◆ isConnected()

bool EFAFragment2D::isConnected ( EFAFragment other_fragment) const
virtual

Implements EFAFragment.

Definition at line 122 of file EFAFragment2D.C.

123 {
124  bool is_connected = false;
125  EFAFragment2D * other_frag2d = dynamic_cast<EFAFragment2D *>(other_fragment);
126  if (!other_frag2d)
127  EFAError("in isConnected other_fragment is not of type EFAfragement2D");
128 
129  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
130  {
131  for (unsigned int j = 0; j < other_frag2d->numEdges(); ++j)
132  {
133  if (_boundary_edges[i]->equivalent(*other_frag2d->getEdge(j)))
134  {
135  is_connected = true;
136  break;
137  }
138  }
139  if (is_connected)
140  break;
141  } // i
142  return is_connected;
143 }
unsigned int numEdges() const
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
EFAEdge * getEdge(unsigned int edge_id) const

◆ isEdgeInterior()

bool EFAFragment2D::isEdgeInterior ( unsigned int  edge_id) const

Definition at line 244 of file EFAFragment2D.C.

Referenced by EFAElement2D::createChild(), XFEMCutElem2D::getCrackTipOriginAndDirection(), XFEMCutElem2D::getCutPlaneNormal(), XFEMCutElem2D::getCutPlaneOrigin(), getInteriorEdgeID(), XFEMCutElem2D::getIntersectionInfo(), XFEMCutElem2D::numCutPlanes(), and removeInvalidEmbeddedNodes().

245 {
246  if (!_host_elem)
247  EFAError("in isEdgeInterior fragment must have host elem");
248 
249  bool edge_in_elem_edge = false;
250 
251  for (unsigned int i = 0; i < _host_elem->numEdges(); ++i)
252  {
253  if (_host_elem->getEdge(i)->containsEdge(*_boundary_edges[edge_id]))
254  {
255  edge_in_elem_edge = true;
256  break;
257  }
258  }
259  if (!edge_in_elem_edge)
260  return true; // yes, is interior
261  else
262  return false;
263 }
EFAEdge * getEdge(unsigned int edge_id) const
unsigned int numEdges() const
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
bool containsEdge(const EFAEdge &other) const
Definition: EFAEdge.C:63
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32

◆ isSecondaryInteriorEdge()

bool EFAFragment2D::isSecondaryInteriorEdge ( unsigned int  edge_id) const

Definition at line 278 of file EFAFragment2D.C.

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

279 {
280  bool is_second_cut = false;
281  if (!_host_elem)
282  EFAError("in isSecondaryInteriorEdge fragment must have host elem");
283 
284  for (unsigned int i = 0; i < _host_elem->numInteriorNodes(); ++i)
285  {
287  {
288  is_second_cut = true;
289  break;
290  }
291  }
292  return is_second_cut;
293 }
virtual unsigned int numInteriorNodes() const
Definition: EFAElement2D.C:353
EFAFaceNode * getInteriorNode(unsigned int interior_node_id) const
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
EFANode * getNode()
Definition: EFAFaceNode.C:25
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32
virtual bool containsNode(EFANode *node) const
Definition: EFAFragment2D.C:73

◆ numEdges()

unsigned int EFAFragment2D::numEdges ( ) const

◆ removeInvalidEmbeddedNodes()

void EFAFragment2D::removeInvalidEmbeddedNodes ( std::map< unsigned int, EFANode *> &  EmbeddedNodes)
virtual

Implements EFAFragment.

Definition at line 146 of file EFAFragment2D.C.

147 {
148  // if a fragment only has 1 intersection which is in an interior edge
149  // remove this embedded node (MUST DO THIS AFTER combine_tip_edges())
150  if (getNumCuts() == 1)
151  {
152  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
153  {
154  if (isEdgeInterior(i) && _boundary_edges[i]->hasIntersection())
155  {
156  if (_host_elem->numInteriorNodes() != 1)
157  EFAError("host element must have 1 interior node at this point");
158  Efa::deleteFromMap(EmbeddedNodes, _boundary_edges[i]->getEmbeddedNode(0));
159  _boundary_edges[i]->removeEmbeddedNodes();
161  break;
162  }
163  } // i
164  }
165 }
virtual unsigned int getNumCuts() const
Definition: EFAFragment2D.C:88
virtual unsigned int numInteriorNodes() const
Definition: EFAElement2D.C:353
bool deleteFromMap(std::map< unsigned int, T *> &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:23
bool isEdgeInterior(unsigned int edge_id) const
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
void deleteInteriorNodes()
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32

◆ split()

std::vector< EFAFragment2D * > EFAFragment2D::split ( )

Definition at line 331 of file EFAFragment2D.C.

Referenced by EFAFace::split().

332 {
333  // This method will split one existing fragment into one or two
334  // new fragments and return them.
335  // N.B. each boundary each can only have 1 cut at most
336  std::vector<EFAFragment2D *> new_fragments;
337  std::vector<unsigned int> cut_edges;
338  std::vector<unsigned int> cut_nodes;
339  for (unsigned int iedge = 0; iedge < _boundary_edges.size(); ++iedge)
340  {
341  if (_boundary_edges[iedge]->getNode(0)->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
342  cut_nodes.push_back(iedge);
343  if (_boundary_edges[iedge]->numEmbeddedNodes() > 1)
344  EFAError("A fragment boundary edge can't have more than 1 cuts");
345  if (_boundary_edges[iedge]->hasIntersection())
346  cut_edges.push_back(iedge);
347  }
348 
349  if (cut_edges.size() > 2)
350  {
351  EFAError("In split() fragment cannot have more than 2 cut edges");
352  }
353  else if (cut_edges.size() == 1 && cut_nodes.size() == 1)
354  {
355  if (cut_edges[0] == 1 && cut_nodes[0] == 0) // case 1
356  {
357  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
358  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
359  EFANode * node1 = _boundary_edges[0]->getNode(0);
360  EFANode * node2 = _boundary_edges[0]->getNode(1);
361  EFANode * node3 = _boundary_edges[1]->getEmbeddedNode(0);
362  EFANode * node4 = _boundary_edges[1]->getNode(1);
363  EFANode * node5 = _boundary_edges[2]->getNode(1);
364 
365  new_frag1->addEdge(new EFAEdge(node1, node2));
366  new_frag1->addEdge(new EFAEdge(node2, node3));
367  new_frag1->addEdge(new EFAEdge(node3, node1));
368 
369  new_frag2->addEdge(new EFAEdge(node1, node3));
370  new_frag2->addEdge(new EFAEdge(node3, node4));
371  new_frag2->addEdge(new EFAEdge(node4, node5));
372  new_frag2->addEdge(new EFAEdge(node5, node1));
373 
374  new_fragments.push_back(new_frag1);
375  new_fragments.push_back(new_frag2);
376  }
377  else if (cut_edges[0] == 2 && cut_nodes[0] == 0) // case 2
378  {
379  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
380  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
381  EFANode * node1 = _boundary_edges[0]->getNode(0);
382  EFANode * node2 = _boundary_edges[0]->getNode(1);
383  EFANode * node3 = _boundary_edges[1]->getNode(1);
384  EFANode * node4 = _boundary_edges[2]->getEmbeddedNode(0);
385  EFANode * node5 = _boundary_edges[2]->getNode(1);
386 
387  new_frag1->addEdge(new EFAEdge(node1, node2));
388  new_frag1->addEdge(new EFAEdge(node2, node3));
389  new_frag1->addEdge(new EFAEdge(node3, node4));
390  new_frag1->addEdge(new EFAEdge(node4, node1));
391 
392  new_frag2->addEdge(new EFAEdge(node1, node4));
393  new_frag2->addEdge(new EFAEdge(node4, node5));
394  new_frag2->addEdge(new EFAEdge(node5, node1));
395 
396  new_fragments.push_back(new_frag1);
397  new_fragments.push_back(new_frag2);
398  }
399  else if (cut_edges[0] == 2 && cut_nodes[0] == 1) // case 3
400  {
401  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
402  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
403  EFANode * node1 = _boundary_edges[0]->getNode(0);
404  EFANode * node2 = _boundary_edges[0]->getNode(1);
405  EFANode * node3 = _boundary_edges[1]->getNode(1);
406  EFANode * node4 = _boundary_edges[2]->getEmbeddedNode(0);
407  EFANode * node5 = _boundary_edges[2]->getNode(1);
408 
409  new_frag1->addEdge(new EFAEdge(node1, node2));
410  new_frag1->addEdge(new EFAEdge(node2, node4));
411  new_frag1->addEdge(new EFAEdge(node4, node5));
412  new_frag1->addEdge(new EFAEdge(node5, node1));
413 
414  new_frag2->addEdge(new EFAEdge(node2, node3));
415  new_frag2->addEdge(new EFAEdge(node3, node4));
416  new_frag2->addEdge(new EFAEdge(node4, node2));
417 
418  new_fragments.push_back(new_frag1);
419  new_fragments.push_back(new_frag2);
420  }
421  else if (cut_edges[0] == 3 && cut_nodes[0] == 1) // case 4
422  {
423  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
424  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
425  EFANode * node1 = _boundary_edges[0]->getNode(0);
426  EFANode * node2 = _boundary_edges[0]->getNode(1);
427  EFANode * node3 = _boundary_edges[1]->getNode(1);
428  EFANode * node4 = _boundary_edges[2]->getNode(1);
429  EFANode * node5 = _boundary_edges[3]->getEmbeddedNode(0);
430 
431  new_frag1->addEdge(new EFAEdge(node2, node3));
432  new_frag1->addEdge(new EFAEdge(node3, node4));
433  new_frag1->addEdge(new EFAEdge(node4, node5));
434  new_frag1->addEdge(new EFAEdge(node5, node2));
435 
436  new_frag2->addEdge(new EFAEdge(node1, node2));
437  new_frag2->addEdge(new EFAEdge(node2, node5));
438  new_frag2->addEdge(new EFAEdge(node5, node1));
439 
440  new_fragments.push_back(new_frag1);
441  new_fragments.push_back(new_frag2);
442  }
443  else if (cut_edges[0] == 3 && cut_nodes[0] == 2) // case 5
444  {
445  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
446  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
447  EFANode * node1 = _boundary_edges[0]->getNode(0);
448  EFANode * node2 = _boundary_edges[0]->getNode(1);
449  EFANode * node3 = _boundary_edges[1]->getNode(1);
450  EFANode * node4 = _boundary_edges[3]->getEmbeddedNode(0);
451  EFANode * node5 = _boundary_edges[2]->getNode(1);
452 
453  new_frag1->addEdge(new EFAEdge(node1, node2));
454  new_frag1->addEdge(new EFAEdge(node2, node3));
455  new_frag1->addEdge(new EFAEdge(node3, node4));
456  new_frag1->addEdge(new EFAEdge(node4, node1));
457 
458  new_frag2->addEdge(new EFAEdge(node3, node5));
459  new_frag2->addEdge(new EFAEdge(node5, node4));
460  new_frag2->addEdge(new EFAEdge(node4, node3));
461 
462  new_fragments.push_back(new_frag1);
463  new_fragments.push_back(new_frag2);
464  }
465  else if (cut_edges[0] == 3 && cut_nodes[0] == 2) // case 5
466  {
467  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
468  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
469  EFANode * node1 = _boundary_edges[0]->getNode(0);
470  EFANode * node2 = _boundary_edges[0]->getNode(1);
471  EFANode * node3 = _boundary_edges[1]->getNode(1);
472  EFANode * node4 = _boundary_edges[3]->getEmbeddedNode(0);
473  EFANode * node5 = _boundary_edges[2]->getNode(1);
474 
475  new_frag1->addEdge(new EFAEdge(node1, node2));
476  new_frag1->addEdge(new EFAEdge(node2, node3));
477  new_frag1->addEdge(new EFAEdge(node3, node4));
478  new_frag1->addEdge(new EFAEdge(node4, node1));
479 
480  new_frag2->addEdge(new EFAEdge(node3, node5));
481  new_frag2->addEdge(new EFAEdge(node5, node4));
482  new_frag2->addEdge(new EFAEdge(node4, node3));
483 
484  new_fragments.push_back(new_frag1);
485  new_fragments.push_back(new_frag2);
486  }
487  else if (cut_edges[0] == 3 && cut_nodes[0] == 2) // case 6
488  {
489  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
490  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
491  EFANode * node1 = _boundary_edges[0]->getNode(0);
492  EFANode * node2 = _boundary_edges[0]->getEmbeddedNode(0);
493  EFANode * node3 = _boundary_edges[0]->getNode(1);
494  EFANode * node4 = _boundary_edges[1]->getNode(1);
495  EFANode * node5 = _boundary_edges[2]->getNode(1);
496 
497  new_frag1->addEdge(new EFAEdge(node1, node2));
498  new_frag1->addEdge(new EFAEdge(node2, node4));
499  new_frag1->addEdge(new EFAEdge(node4, node5));
500  new_frag1->addEdge(new EFAEdge(node5, node1));
501 
502  new_frag2->addEdge(new EFAEdge(node2, node3));
503  new_frag2->addEdge(new EFAEdge(node3, node4));
504  new_frag2->addEdge(new EFAEdge(node4, node2));
505 
506  new_fragments.push_back(new_frag1);
507  new_fragments.push_back(new_frag2);
508  }
509  else if (cut_edges[0] == 1 && cut_nodes[0] == 3) // case 7
510  {
511  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
512  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
513  EFANode * node1 = _boundary_edges[0]->getNode(0);
514  EFANode * node2 = _boundary_edges[0]->getNode(1);
515  EFANode * node3 = _boundary_edges[1]->getEmbeddedNode(0);
516  EFANode * node4 = _boundary_edges[1]->getNode(1);
517  EFANode * node5 = _boundary_edges[2]->getNode(1);
518 
519  new_frag1->addEdge(new EFAEdge(node1, node2));
520  new_frag1->addEdge(new EFAEdge(node2, node3));
521  new_frag1->addEdge(new EFAEdge(node3, node5));
522  new_frag1->addEdge(new EFAEdge(node5, node1));
523 
524  new_frag2->addEdge(new EFAEdge(node3, node4));
525  new_frag2->addEdge(new EFAEdge(node4, node5));
526  new_frag2->addEdge(new EFAEdge(node5, node3));
527 
528  new_fragments.push_back(new_frag1);
529  new_fragments.push_back(new_frag2);
530  }
531  else if (cut_edges[0] == 0 && cut_nodes[0] == 3) // case 8
532  {
533  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
534  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
535  EFANode * node1 = _boundary_edges[0]->getNode(0);
536  EFANode * node2 = _boundary_edges[0]->getEmbeddedNode(0);
537  EFANode * node3 = _boundary_edges[0]->getNode(1);
538  EFANode * node4 = _boundary_edges[1]->getNode(1);
539  EFANode * node5 = _boundary_edges[2]->getNode(1);
540 
541  new_frag1->addEdge(new EFAEdge(node2, node3));
542  new_frag1->addEdge(new EFAEdge(node3, node4));
543  new_frag1->addEdge(new EFAEdge(node4, node5));
544  new_frag1->addEdge(new EFAEdge(node5, node2));
545 
546  new_frag2->addEdge(new EFAEdge(node1, node2));
547  new_frag2->addEdge(new EFAEdge(node2, node5));
548  new_frag2->addEdge(new EFAEdge(node5, node1));
549 
550  new_fragments.push_back(new_frag1);
551  new_fragments.push_back(new_frag2);
552  }
553  }
554  else if (cut_nodes.size() == 2)
555  {
556  if ((cut_nodes[0] == 0 && cut_nodes[1] == 2) || (cut_nodes[0] == 2 && cut_nodes[1] == 0))
557  {
558  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
559  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
560  EFANode * node1 = _boundary_edges[0]->getNode(0);
561  EFANode * node2 = _boundary_edges[1]->getNode(0);
562  EFANode * node3 = _boundary_edges[2]->getNode(0);
563  EFANode * node4 = _boundary_edges[3]->getNode(0);
564 
565  new_frag1->addEdge(new EFAEdge(node1, node2));
566  new_frag1->addEdge(new EFAEdge(node2, node3));
567  new_frag1->addEdge(new EFAEdge(node3, node1));
568 
569  new_frag2->addEdge(new EFAEdge(node3, node4));
570  new_frag2->addEdge(new EFAEdge(node4, node1));
571  new_frag2->addEdge(new EFAEdge(node1, node3));
572 
573  new_fragments.push_back(new_frag1);
574  new_fragments.push_back(new_frag2);
575  }
576  else if ((cut_nodes[0] == 1 && cut_nodes[1] == 3) || (cut_nodes[0] == 3 && cut_nodes[1] == 1))
577  {
578  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
579  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
580  EFANode * node1 = _boundary_edges[0]->getNode(0);
581  EFANode * node2 = _boundary_edges[1]->getNode(0);
582  EFANode * node3 = _boundary_edges[2]->getNode(0);
583  EFANode * node4 = _boundary_edges[3]->getNode(0);
584 
585  new_frag1->addEdge(new EFAEdge(node1, node2));
586  new_frag1->addEdge(new EFAEdge(node2, node4));
587  new_frag1->addEdge(new EFAEdge(node4, node1));
588 
589  new_frag2->addEdge(new EFAEdge(node2, node3));
590  new_frag2->addEdge(new EFAEdge(node3, node4));
591  new_frag2->addEdge(new EFAEdge(node4, node2));
592 
593  new_fragments.push_back(new_frag1);
594  new_fragments.push_back(new_frag2);
595  }
596  else if ((cut_nodes[0] == 0 && cut_nodes[1] == 1) || (cut_nodes[0] == 1 && cut_nodes[1] == 2) ||
597  (cut_nodes[0] == 2 && cut_nodes[1] == 3) || (cut_nodes[0] == 3 && cut_nodes[1] == 0) ||
598  (cut_nodes[0] == 1 && cut_nodes[1] == 0) || (cut_nodes[0] == 2 && cut_nodes[1] == 1) ||
599  (cut_nodes[0] == 3 && cut_nodes[1] == 2) || (cut_nodes[0] == 0 && cut_nodes[1] == 3))
600  {
601  EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, NULL);
602  EFANode * node1 = _boundary_edges[0]->getNode(0);
603  EFANode * node2 = _boundary_edges[1]->getNode(0);
604  EFANode * node3 = _boundary_edges[2]->getNode(0);
605  EFANode * node4 = _boundary_edges[3]->getNode(0);
606 
607  new_frag->addEdge(new EFAEdge(node1, node2));
608  new_frag->addEdge(new EFAEdge(node2, node3));
609  new_frag->addEdge(new EFAEdge(node3, node4));
610  new_frag->addEdge(new EFAEdge(node4, node1));
611 
612  new_fragments.push_back(new_frag);
613  }
614  }
615  else if (cut_edges.size() == 2 || (cut_edges.size() == 1 && cut_nodes.size() == 0))
616  {
617  unsigned int iedge = 0;
618  unsigned int icutedge = 0;
619 
620  do // loop over new fragments
621  {
622  EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, NULL);
623 
624  do // loop over edges
625  {
626  if (iedge == cut_edges[icutedge])
627  {
628  EFANode * first_node_on_edge = _boundary_edges[iedge]->getNode(0);
629  unsigned int iprevedge(iedge > 0 ? iedge - 1 : _boundary_edges.size() - 1);
630  if (!_boundary_edges[iprevedge]->containsNode(first_node_on_edge))
631  {
632  first_node_on_edge = _boundary_edges[iedge]->getNode(1);
633  if (!_boundary_edges[iprevedge]->containsNode(first_node_on_edge))
634  EFAError("Previous edge does not contain either of the nodes in this edge");
635  }
636  EFANode * embedded_node1 = _boundary_edges[iedge]->getEmbeddedNode(0);
637  new_frag->addEdge(new EFAEdge(first_node_on_edge, embedded_node1));
638 
639  ++icutedge; // jump to next cut edge or jump back to this edge when only 1 cut edge
640  if (icutedge == cut_edges.size())
641  icutedge = 0;
642  iedge = cut_edges[icutedge];
643  EFANode * embedded_node2 = _boundary_edges[iedge]->getEmbeddedNode(0);
644  if (embedded_node2 != embedded_node1)
645  new_frag->addEdge(new EFAEdge(embedded_node1, embedded_node2));
646 
647  EFANode * second_node_on_edge = _boundary_edges[iedge]->getNode(1);
648  unsigned int inextedge(iedge < (_boundary_edges.size() - 1) ? iedge + 1 : 0);
649  if (!_boundary_edges[inextedge]->containsNode(second_node_on_edge))
650  {
651  second_node_on_edge = _boundary_edges[iedge]->getNode(0);
652  if (!_boundary_edges[inextedge]->containsNode(second_node_on_edge))
653  EFAError("Next edge does not contain either of the nodes in this edge");
654  }
655  new_frag->addEdge(new EFAEdge(embedded_node2, second_node_on_edge));
656  }
657  else // not a cut edge
658  new_frag->addEdge(new EFAEdge(*_boundary_edges[iedge]));
659 
660  ++iedge;
661  if (iedge == _boundary_edges.size())
662  iedge = 0;
663  } while (!_boundary_edges[iedge]->containsEdge(*new_frag->getEdge(0)));
664 
665  if (cut_edges.size() > 1)
666  { // set the starting point for the loop over the other part of the element
667  iedge = cut_edges[0] + 1;
668  if (iedge == _boundary_edges.size())
669  iedge = 0;
670  }
671 
672  new_fragments.push_back(new_frag);
673  } while (new_fragments.size() < cut_edges.size());
674  }
675  else if (cut_nodes.size() == 1)
676  {
677  EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, NULL);
678  for (unsigned int iedge = 0; iedge < _boundary_edges.size(); ++iedge)
679  {
680  EFANode * first_node_on_edge = _boundary_edges[iedge]->getNode(0);
681  EFANode * second_node_on_edge = _boundary_edges[iedge]->getNode(1);
682  new_frag->addEdge(new EFAEdge(first_node_on_edge, second_node_on_edge));
683  }
684  new_fragments.push_back(new_frag);
685  }
686 
687  return new_fragments;
688 }
void addEdge(EFAEdge *new_edge)
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
EFAEdge * getEdge(unsigned int edge_id) const
EFAFragment2D(EFAElement2D *host, bool create_boundary_edges, const EFAElement2D *from_host, unsigned int frag_id=std::numeric_limits< unsigned int >::max())
Definition: EFAFragment2D.C:21
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:32
virtual bool containsNode(EFANode *node) const
Definition: EFAFragment2D.C:73

◆ switchNode()

void EFAFragment2D::switchNode ( EFANode new_node,
EFANode old_node 
)
virtual

Implements EFAFragment.

Definition at line 66 of file EFAFragment2D.C.

67 {
68  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
69  _boundary_edges[i]->switchNode(new_node, old_node);
70 }
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:33
virtual void switchNode(EFANode *new_node, EFANode *old_node)
Definition: EFAFragment2D.C:66

Member Data Documentation

◆ _boundary_edges

std::vector<EFAEdge *> EFAFragment2D::_boundary_edges
private

◆ _host_elem

EFAElement2D* EFAFragment2D::_host_elem
private

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