www.mooseframework.org
EFAFragment2D.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
3 //*
4 //* All rights reserved, see COPYRIGHT for full restrictions
5 //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
6 //*
7 //* Licensed under LGPL 2.1, please see LICENSE for details
8 //* https://www.gnu.org/licenses/lgpl-2.1.html
9 
10 #include "EFAElement2D.h"
11 
12 #include "EFANode.h"
13 #include "EFAEdge.h"
14 #include "EFAFace.h"
15 #include "EFAFragment2D.h"
16 
17 #include "EFAFaceNode.h"
18 #include "EFAFuncs.h"
19 #include "EFAError.h"
20 
22  bool create_boundary_edges,
23  const EFAElement2D * from_host,
24  unsigned int frag_id)
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 }
45 
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 }
52 
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 }
64 
65 void
66 EFAFragment2D::switchNode(EFANode * new_node, EFANode * old_node)
67 {
68  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
69  _boundary_edges[i]->switchNode(new_node, old_node);
70 }
71 
72 bool
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 }
86 
87 unsigned int
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 }
98 
99 unsigned int
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 }
108 
109 std::set<EFANode *>
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 }
120 
121 bool
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 }
144 
145 void
146 EFAFragment2D::removeInvalidEmbeddedNodes(std::map<unsigned int, EFANode *> & EmbeddedNodes)
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 }
166 
167 void
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 }
227 
228 /*
229 std::vector<EFAnode*>
230 EFAfragment::commonNodesWithEdge(EFAEdge & other_edge)
231 {
232  std::vector<EFAnode*> common_nodes;
233  for (unsigned int i = 0; i < 2; ++i)
234  {
235  EFAnode* edge_node = other_edge.node_ptr(i);
236  if (containsNode(edge_node))
237  common_nodes.push_back(edge_node);
238  }
239  return common_nodes;
240 }
241 */
242 
243 bool
244 EFAFragment2D::isEdgeInterior(unsigned int edge_id) const
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 }
264 
265 std::vector<unsigned int>
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 }
276 
277 bool
278 EFAFragment2D::isSecondaryInteriorEdge(unsigned int edge_id) const
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 }
294 
295 unsigned int
297 {
298  return _boundary_edges.size();
299 }
300 
301 EFAEdge *
302 EFAFragment2D::getEdge(unsigned int edge_id) const
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 }
308 
309 void
311 {
312  _boundary_edges.push_back(new_edge);
313 }
314 
315 std::set<EFANode *>
316 EFAFragment2D::getEdgeNodes(unsigned int edge_id) const
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 }
323 
324 EFAElement2D *
326 {
327  return _host_elem;
328 }
329 
330 std::vector<EFAFragment2D *>
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 }
EFAFace::getEdge
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:260
EFAFragment2D::getInteriorEdgeID
std::vector< unsigned int > getInteriorEdgeID() const
Definition: EFAFragment2D.C:266
EFAElement2D::getEdge
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAElement2D.C:1475
EFANode.h
EFAFuncs.h
EFAFaceNode.h
EFAFragment2D::EFAFragment2D
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
EFAFragment2D::switchNode
virtual void switchNode(EFANode *new_node, EFANode *old_node)
Definition: EFAFragment2D.C:66
EFAFragment2D::getEdge
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFragment2D.C:302
EFAEdge::addIntersection
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition: EFAEdge.C:130
EFAFragment2D::split
std::vector< EFAFragment2D * > split()
Definition: EFAFragment2D.C:331
EFAElement2D::getFragmentEdge
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
Definition: EFAElement2D.C:1481
EFAFragment2D
Definition: EFAFragment2D.h:20
EFAElement2D::deleteInteriorNodes
void deleteInteriorNodes()
Definition: EFAElement2D.C:1439
EFAFace.h
EFAFaceNode::getNode
EFANode * getNode()
Definition: EFAFaceNode.C:25
EFAFragment2D::_boundary_edges
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:32
EFAFragment2D.h
EFAFragment2D::combineTipEdges
void combineTipEdges()
Definition: EFAFragment2D.C:168
EFAElement2D::getFragment
EFAFragment2D * getFragment(unsigned int frag_id) const
Definition: EFAElement2D.C:1388
EFAError.h
EFAFragment2D::containsNode
virtual bool containsNode(EFANode *node) const
Definition: EFAFragment2D.C:73
EFAElement2D::getInteriorNode
EFAFaceNode * getInteriorNode(unsigned int interior_node_id) const
Definition: EFAElement2D.C:1430
EFAFragment2D::getEdgeNodes
std::set< EFANode * > getEdgeNodes(unsigned int edge_id) const
Definition: EFAFragment2D.C:316
EFAFragment2D::isSecondaryInteriorEdge
bool isSecondaryInteriorEdge(unsigned int edge_id) const
Definition: EFAFragment2D.C:278
EFAFragment2D::getHostElement
EFAElement2D * getHostElement() const
Definition: EFAFragment2D.C:325
EFAFragment2D::getNumCutNodes
virtual unsigned int getNumCutNodes() const
Definition: EFAFragment2D.C:100
EFAFragment2D::getNumCuts
virtual unsigned int getNumCuts() const
Definition: EFAFragment2D.C:88
EFAEdge.h
EFAFragment2D::removeInvalidEmbeddedNodes
virtual void removeInvalidEmbeddedNodes(std::map< unsigned int, EFANode * > &EmbeddedNodes)
Definition: EFAFragment2D.C:146
EFAFace
Definition: EFAFace.h:19
EFAFragment2D::isConnected
virtual bool isConnected(EFAFragment *other_fragment) const
Definition: EFAFragment2D.C:122
EFAEdge::distanceFromNode1
double distanceFromNode1(EFANode *node) const
Definition: EFAEdge.C:248
EFAFragment2D::~EFAFragment2D
~EFAFragment2D()
Definition: EFAFragment2D.C:53
EFAEdge
Definition: EFAEdge.h:16
EFANode::N_CATEGORY_EMBEDDED_PERMANENT
Definition: EFANode.h:22
EFANode
Definition: EFANode.h:14
EFAEdge::hasIntersection
bool hasIntersection() const
Definition: EFAEdge.C:198
EFAEdge::containsEdge
bool containsEdge(const EFAEdge &other) const
Definition: EFAEdge.C:63
EFAFragment
Definition: EFAFragment.h:18
EFAElement2D::numFragments
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:202
EFAFragment2D::getAllNodes
virtual std::set< EFANode * > getAllNodes() const
Definition: EFAFragment2D.C:110
EFAElement2D
Definition: EFAElement2D.h:20
EFAElement2D::numEdges
unsigned int numEdges() const
Definition: EFAElement2D.C:1447
Efa::deleteFromMap
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:22
EFAFragment2D::addEdge
void addEdge(EFAEdge *new_edge)
Definition: EFAFragment2D.C:310
EFAFragment2D::numEdges
unsigned int numEdges() const
Definition: EFAFragment2D.C:296
EFAElement2D.h
EFAFace::numEdges
unsigned int numEdges() const
Definition: EFAFace.C:254
EFAFragment2D::isEdgeInterior
bool isEdgeInterior(unsigned int edge_id) const
Definition: EFAFragment2D.C:244
EFAFragment2D::_host_elem
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:31
EFAElement2D::numInteriorNodes
virtual unsigned int numInteriorNodes() const
Definition: EFAElement2D.C:353