www.mooseframework.org
EFAFragment2D.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 #include "EFAElement2D.h"
9 
10 #include "EFANode.h"
11 #include "EFAEdge.h"
12 #include "EFAFace.h"
13 #include "EFAFragment2D.h"
14 
15 #include "EFAFaceNode.h"
16 #include "EFAFuncs.h"
17 #include "EFAError.h"
18 
20  bool create_boundary_edges,
21  const EFAElement2D * from_host,
22  unsigned int frag_id)
23  : EFAFragment(), _host_elem(host)
24 {
25  if (create_boundary_edges)
26  {
27  if (!from_host)
28  EFAError("EFAfragment2D constructor must have a from_host to copy from");
29  if (frag_id == std::numeric_limits<unsigned int>::max()) // copy the from_host itself
30  {
31  for (unsigned int i = 0; i < from_host->numEdges(); ++i)
32  _boundary_edges.push_back(new EFAEdge(*from_host->getEdge(i)));
33  }
34  else
35  {
36  if (frag_id > from_host->numFragments() - 1)
37  EFAError("In EFAfragment2D constructor fragment_copy_index out of bounds");
38  for (unsigned int i = 0; i < from_host->getFragment(frag_id)->numEdges(); ++i)
39  _boundary_edges.push_back(new EFAEdge(*from_host->getFragmentEdge(frag_id, i)));
40  }
41  }
42 }
43 
45  : EFAFragment(), _host_elem(host)
46 {
47  for (unsigned int i = 0; i < from_face->numEdges(); ++i)
48  _boundary_edges.push_back(new EFAEdge(*from_face->getEdge(i)));
49 }
50 
52 {
53  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
54  {
55  if (_boundary_edges[i])
56  {
57  delete _boundary_edges[i];
58  _boundary_edges[i] = NULL;
59  }
60  }
61 }
62 
63 void
64 EFAFragment2D::switchNode(EFANode * new_node, EFANode * old_node)
65 {
66  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
67  _boundary_edges[i]->switchNode(new_node, old_node);
68 }
69 
70 bool
72 {
73  bool contains = false;
74  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
75  {
76  if (_boundary_edges[i]->containsNode(node))
77  {
78  contains = true;
79  break;
80  }
81  }
82  return contains;
83 }
84 
85 unsigned int
87 {
88  unsigned int num_cut_edges = 0;
89  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
90  {
91  if (_boundary_edges[i]->hasIntersection())
92  num_cut_edges += _boundary_edges[i]->numEmbeddedNodes();
93  }
94  return num_cut_edges;
95 }
96 
97 unsigned int
99 {
100  unsigned int num_cut_nodes = 0;
101  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
102  if (_boundary_edges[i]->getNode(0)->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
103  num_cut_nodes++;
104  return num_cut_nodes;
105 }
106 
107 std::set<EFANode *>
109 {
110  std::set<EFANode *> nodes;
111  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
112  {
113  nodes.insert(_boundary_edges[i]->getNode(0));
114  nodes.insert(_boundary_edges[i]->getNode(1));
115  }
116  return nodes;
117 }
118 
119 bool
121 {
122  bool is_connected = false;
123  EFAFragment2D * other_frag2d = dynamic_cast<EFAFragment2D *>(other_fragment);
124  if (!other_frag2d)
125  EFAError("in isConnected other_fragment is not of type EFAfragement2D");
126 
127  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
128  {
129  for (unsigned int j = 0; j < other_frag2d->numEdges(); ++j)
130  {
131  if (_boundary_edges[i]->equivalent(*other_frag2d->getEdge(j)))
132  {
133  is_connected = true;
134  break;
135  }
136  }
137  if (is_connected)
138  break;
139  } // i
140  return is_connected;
141 }
142 
143 void
144 EFAFragment2D::removeInvalidEmbeddedNodes(std::map<unsigned int, EFANode *> & EmbeddedNodes)
145 {
146  // if a fragment only has 1 intersection which is in an interior edge
147  // remove this embedded node (MUST DO THIS AFTER combine_tip_edges())
148  if (getNumCuts() == 1)
149  {
150  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
151  {
152  if (isEdgeInterior(i) && _boundary_edges[i]->hasIntersection())
153  {
154  if (_host_elem->numInteriorNodes() != 1)
155  EFAError("host element must have 1 interior node at this point");
156  Efa::deleteFromMap(EmbeddedNodes, _boundary_edges[i]->getEmbeddedNode(0));
157  _boundary_edges[i]->removeEmbeddedNodes();
159  break;
160  }
161  } // i
162  }
163 }
164 
165 void
167 {
168  // combine the tip edges in a crack tip fragment
169  // N.B. the host elem can only have one elem_tip_edge, otherwise it should have already been
170  // completely split
171  if (!_host_elem)
172  EFAError("In combine_tip_edges() the frag must have host_elem");
173 
174  bool has_tip_edges = false;
175  unsigned int elem_tip_edge_id = 99999;
176  std::vector<unsigned int> frag_tip_edge_id;
177  for (unsigned int i = 0; i < _host_elem->numEdges(); ++i)
178  {
179  frag_tip_edge_id.clear();
181  {
182  for (unsigned int j = 0; j < _boundary_edges.size(); ++j)
183  {
185  frag_tip_edge_id.push_back(j);
186  } // j
187  if (frag_tip_edge_id.size() == 2) // combine the two frag edges on this elem edge
188  {
189  has_tip_edges = true;
190  elem_tip_edge_id = i;
191  break;
192  }
193  }
194  } // i
195  if (has_tip_edges)
196  {
197  // frag_tip_edge_id[0] must precede frag_tip_edge_id[1]
198  unsigned int edge0_next(frag_tip_edge_id[0] < (numEdges() - 1) ? frag_tip_edge_id[0] + 1 : 0);
199  if (edge0_next != frag_tip_edge_id[1])
200  EFAError("frag_tip_edge_id[1] must be the next edge of frag_tip_edge_id[0]");
201 
202  // get the two end nodes of the new edge
203  EFANode * node1 = _boundary_edges[frag_tip_edge_id[0]]->getNode(0);
204  EFANode * emb_node = _boundary_edges[frag_tip_edge_id[0]]->getNode(1);
205  EFANode * node2 = _boundary_edges[frag_tip_edge_id[1]]->getNode(1);
206  if (emb_node != _boundary_edges[frag_tip_edge_id[1]]->getNode(0))
207  EFAError("fragment edges are not correctly set up");
208 
209  // get the new edge with one intersection
210  EFAEdge * elem_edge = _host_elem->getEdge(elem_tip_edge_id);
211  double xi_node1 = elem_edge->distanceFromNode1(node1);
212  double xi_node2 = elem_edge->distanceFromNode1(node2);
213  double xi_emb = elem_edge->distanceFromNode1(emb_node);
214  double position = (xi_emb - xi_node1) / (xi_node2 - xi_node1);
215  EFAEdge * full_edge = new EFAEdge(node1, node2);
216  full_edge->addIntersection(position, emb_node, node1);
217 
218  // combine the two original fragment edges
219  delete _boundary_edges[frag_tip_edge_id[0]];
220  delete _boundary_edges[frag_tip_edge_id[1]];
221  _boundary_edges[frag_tip_edge_id[0]] = full_edge;
222  _boundary_edges.erase(_boundary_edges.begin() + frag_tip_edge_id[1]);
223  }
224 }
225 
226 /*
227 std::vector<EFAnode*>
228 EFAfragment::commonNodesWithEdge(EFAEdge & other_edge)
229 {
230  std::vector<EFAnode*> common_nodes;
231  for (unsigned int i = 0; i < 2; ++i)
232  {
233  EFAnode* edge_node = other_edge.get_node(i);
234  if (containsNode(edge_node))
235  common_nodes.push_back(edge_node);
236  }
237  return common_nodes;
238 }
239 */
240 
241 bool
242 EFAFragment2D::isEdgeInterior(unsigned int edge_id) const
243 {
244  if (!_host_elem)
245  EFAError("in isEdgeInterior fragment must have host elem");
246 
247  bool edge_in_elem_edge = false;
248 
249  for (unsigned int i = 0; i < _host_elem->numEdges(); ++i)
250  {
251  if (_host_elem->getEdge(i)->containsEdge(*_boundary_edges[edge_id]))
252  {
253  edge_in_elem_edge = true;
254  break;
255  }
256  }
257  if (!edge_in_elem_edge)
258  return true; // yes, is interior
259  else
260  return false;
261 }
262 
263 std::vector<unsigned int>
265 {
266  std::vector<unsigned int> interior_edge_id;
267  for (unsigned int i = 0; i < _boundary_edges.size(); ++i)
268  {
269  if (isEdgeInterior(i))
270  interior_edge_id.push_back(i);
271  }
272  return interior_edge_id;
273 }
274 
275 bool
276 EFAFragment2D::isSecondaryInteriorEdge(unsigned int edge_id) const
277 {
278  bool is_second_cut = false;
279  if (!_host_elem)
280  EFAError("in isSecondaryInteriorEdge fragment must have host elem");
281 
282  for (unsigned int i = 0; i < _host_elem->numInteriorNodes(); ++i)
283  {
285  {
286  is_second_cut = true;
287  break;
288  }
289  }
290  return is_second_cut;
291 }
292 
293 unsigned int
295 {
296  return _boundary_edges.size();
297 }
298 
299 EFAEdge *
300 EFAFragment2D::getEdge(unsigned int edge_id) const
301 {
302  if (edge_id > _boundary_edges.size() - 1)
303  EFAError("in EFAfragment2D::get_edge, index out of bounds");
304  return _boundary_edges[edge_id];
305 }
306 
307 void
309 {
310  _boundary_edges.push_back(new_edge);
311 }
312 
313 std::set<EFANode *>
314 EFAFragment2D::getEdgeNodes(unsigned int edge_id) const
315 {
316  std::set<EFANode *> edge_nodes;
317  edge_nodes.insert(_boundary_edges[edge_id]->getNode(0));
318  edge_nodes.insert(_boundary_edges[edge_id]->getNode(1));
319  return edge_nodes;
320 }
321 
322 EFAElement2D *
324 {
325  return _host_elem;
326 }
327 
328 std::vector<EFAFragment2D *>
330 {
331  // This method will split one existing fragment into one or two
332  // new fragments and return them.
333  // N.B. each boundary each can only have 1 cut at most
334  std::vector<EFAFragment2D *> new_fragments;
335  std::vector<unsigned int> cut_edges;
336  std::vector<unsigned int> cut_nodes;
337  for (unsigned int iedge = 0; iedge < _boundary_edges.size(); ++iedge)
338  {
339  if (_boundary_edges[iedge]->getNode(0)->category() == EFANode::N_CATEGORY_EMBEDDED_PERMANENT)
340  cut_nodes.push_back(iedge);
341  if (_boundary_edges[iedge]->numEmbeddedNodes() > 1)
342  EFAError("A fragment boundary edge can't have more than 1 cuts");
343  if (_boundary_edges[iedge]->hasIntersection())
344  cut_edges.push_back(iedge);
345  }
346 
347  if (cut_edges.size() > 2)
348  {
349  EFAError("In split() fragment cannot have more than 2 cut edges");
350  }
351  else if (cut_edges.size() == 1 && cut_nodes.size() == 1)
352  {
353  if (cut_edges[0] == 1 && cut_nodes[0] == 0) // case 1
354  {
355  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
356  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
357  EFANode * node1 = _boundary_edges[0]->getNode(0);
358  EFANode * node2 = _boundary_edges[0]->getNode(1);
359  EFANode * node3 = _boundary_edges[1]->getEmbeddedNode(0);
360  EFANode * node4 = _boundary_edges[1]->getNode(1);
361  EFANode * node5 = _boundary_edges[2]->getNode(1);
362 
363  new_frag1->addEdge(new EFAEdge(node1, node2));
364  new_frag1->addEdge(new EFAEdge(node2, node3));
365  new_frag1->addEdge(new EFAEdge(node3, node1));
366 
367  new_frag2->addEdge(new EFAEdge(node1, node3));
368  new_frag2->addEdge(new EFAEdge(node3, node4));
369  new_frag2->addEdge(new EFAEdge(node4, node5));
370  new_frag2->addEdge(new EFAEdge(node5, node1));
371 
372  new_fragments.push_back(new_frag1);
373  new_fragments.push_back(new_frag2);
374  }
375  else if (cut_edges[0] == 2 && cut_nodes[0] == 0) // case 2
376  {
377  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
378  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
379  EFANode * node1 = _boundary_edges[0]->getNode(0);
380  EFANode * node2 = _boundary_edges[0]->getNode(1);
381  EFANode * node3 = _boundary_edges[1]->getNode(1);
382  EFANode * node4 = _boundary_edges[2]->getEmbeddedNode(0);
383  EFANode * node5 = _boundary_edges[2]->getNode(1);
384 
385  new_frag1->addEdge(new EFAEdge(node1, node2));
386  new_frag1->addEdge(new EFAEdge(node2, node3));
387  new_frag1->addEdge(new EFAEdge(node3, node4));
388  new_frag1->addEdge(new EFAEdge(node4, node1));
389 
390  new_frag2->addEdge(new EFAEdge(node1, node4));
391  new_frag2->addEdge(new EFAEdge(node4, node5));
392  new_frag2->addEdge(new EFAEdge(node5, node1));
393 
394  new_fragments.push_back(new_frag1);
395  new_fragments.push_back(new_frag2);
396  }
397  else if (cut_edges[0] == 2 && cut_nodes[0] == 1) // case 3
398  {
399  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
400  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
401  EFANode * node1 = _boundary_edges[0]->getNode(0);
402  EFANode * node2 = _boundary_edges[0]->getNode(1);
403  EFANode * node3 = _boundary_edges[1]->getNode(1);
404  EFANode * node4 = _boundary_edges[2]->getEmbeddedNode(0);
405  EFANode * node5 = _boundary_edges[2]->getNode(1);
406 
407  new_frag1->addEdge(new EFAEdge(node1, node2));
408  new_frag1->addEdge(new EFAEdge(node2, node4));
409  new_frag1->addEdge(new EFAEdge(node4, node5));
410  new_frag1->addEdge(new EFAEdge(node5, node1));
411 
412  new_frag2->addEdge(new EFAEdge(node2, node3));
413  new_frag2->addEdge(new EFAEdge(node3, node4));
414  new_frag2->addEdge(new EFAEdge(node4, node2));
415 
416  new_fragments.push_back(new_frag1);
417  new_fragments.push_back(new_frag2);
418  }
419  else if (cut_edges[0] == 3 && cut_nodes[0] == 1) // case 4
420  {
421  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
422  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
423  EFANode * node1 = _boundary_edges[0]->getNode(0);
424  EFANode * node2 = _boundary_edges[0]->getNode(1);
425  EFANode * node3 = _boundary_edges[1]->getNode(1);
426  EFANode * node4 = _boundary_edges[2]->getNode(1);
427  EFANode * node5 = _boundary_edges[3]->getEmbeddedNode(0);
428 
429  new_frag1->addEdge(new EFAEdge(node2, node3));
430  new_frag1->addEdge(new EFAEdge(node3, node4));
431  new_frag1->addEdge(new EFAEdge(node4, node5));
432  new_frag1->addEdge(new EFAEdge(node5, node2));
433 
434  new_frag2->addEdge(new EFAEdge(node1, node2));
435  new_frag2->addEdge(new EFAEdge(node2, node5));
436  new_frag2->addEdge(new EFAEdge(node5, node1));
437 
438  new_fragments.push_back(new_frag1);
439  new_fragments.push_back(new_frag2);
440  }
441  else if (cut_edges[0] == 3 && cut_nodes[0] == 2) // case 5
442  {
443  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
444  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
445  EFANode * node1 = _boundary_edges[0]->getNode(0);
446  EFANode * node2 = _boundary_edges[0]->getNode(1);
447  EFANode * node3 = _boundary_edges[1]->getNode(1);
448  EFANode * node4 = _boundary_edges[3]->getEmbeddedNode(0);
449  EFANode * node5 = _boundary_edges[2]->getNode(1);
450 
451  new_frag1->addEdge(new EFAEdge(node1, node2));
452  new_frag1->addEdge(new EFAEdge(node2, node3));
453  new_frag1->addEdge(new EFAEdge(node3, node4));
454  new_frag1->addEdge(new EFAEdge(node4, node1));
455 
456  new_frag2->addEdge(new EFAEdge(node3, node5));
457  new_frag2->addEdge(new EFAEdge(node5, node4));
458  new_frag2->addEdge(new EFAEdge(node4, node3));
459 
460  new_fragments.push_back(new_frag1);
461  new_fragments.push_back(new_frag2);
462  }
463  else if (cut_edges[0] == 3 && cut_nodes[0] == 2) // case 5
464  {
465  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
466  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
467  EFANode * node1 = _boundary_edges[0]->getNode(0);
468  EFANode * node2 = _boundary_edges[0]->getNode(1);
469  EFANode * node3 = _boundary_edges[1]->getNode(1);
470  EFANode * node4 = _boundary_edges[3]->getEmbeddedNode(0);
471  EFANode * node5 = _boundary_edges[2]->getNode(1);
472 
473  new_frag1->addEdge(new EFAEdge(node1, node2));
474  new_frag1->addEdge(new EFAEdge(node2, node3));
475  new_frag1->addEdge(new EFAEdge(node3, node4));
476  new_frag1->addEdge(new EFAEdge(node4, node1));
477 
478  new_frag2->addEdge(new EFAEdge(node3, node5));
479  new_frag2->addEdge(new EFAEdge(node5, node4));
480  new_frag2->addEdge(new EFAEdge(node4, node3));
481 
482  new_fragments.push_back(new_frag1);
483  new_fragments.push_back(new_frag2);
484  }
485  else if (cut_edges[0] == 3 && cut_nodes[0] == 2) // case 6
486  {
487  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
488  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
489  EFANode * node1 = _boundary_edges[0]->getNode(0);
490  EFANode * node2 = _boundary_edges[0]->getEmbeddedNode(0);
491  EFANode * node3 = _boundary_edges[0]->getNode(1);
492  EFANode * node4 = _boundary_edges[1]->getNode(1);
493  EFANode * node5 = _boundary_edges[2]->getNode(1);
494 
495  new_frag1->addEdge(new EFAEdge(node1, node2));
496  new_frag1->addEdge(new EFAEdge(node2, node4));
497  new_frag1->addEdge(new EFAEdge(node4, node5));
498  new_frag1->addEdge(new EFAEdge(node5, node1));
499 
500  new_frag2->addEdge(new EFAEdge(node2, node3));
501  new_frag2->addEdge(new EFAEdge(node3, node4));
502  new_frag2->addEdge(new EFAEdge(node4, node2));
503 
504  new_fragments.push_back(new_frag1);
505  new_fragments.push_back(new_frag2);
506  }
507  else if (cut_edges[0] == 1 && cut_nodes[0] == 3) // case 7
508  {
509  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
510  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
511  EFANode * node1 = _boundary_edges[0]->getNode(0);
512  EFANode * node2 = _boundary_edges[0]->getNode(1);
513  EFANode * node3 = _boundary_edges[1]->getEmbeddedNode(0);
514  EFANode * node4 = _boundary_edges[1]->getNode(1);
515  EFANode * node5 = _boundary_edges[2]->getNode(1);
516 
517  new_frag1->addEdge(new EFAEdge(node1, node2));
518  new_frag1->addEdge(new EFAEdge(node2, node3));
519  new_frag1->addEdge(new EFAEdge(node3, node5));
520  new_frag1->addEdge(new EFAEdge(node5, node1));
521 
522  new_frag2->addEdge(new EFAEdge(node3, node4));
523  new_frag2->addEdge(new EFAEdge(node4, node5));
524  new_frag2->addEdge(new EFAEdge(node5, node3));
525 
526  new_fragments.push_back(new_frag1);
527  new_fragments.push_back(new_frag2);
528  }
529  else if (cut_edges[0] == 0 && cut_nodes[0] == 3) // case 8
530  {
531  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
532  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
533  EFANode * node1 = _boundary_edges[0]->getNode(0);
534  EFANode * node2 = _boundary_edges[0]->getEmbeddedNode(0);
535  EFANode * node3 = _boundary_edges[0]->getNode(1);
536  EFANode * node4 = _boundary_edges[1]->getNode(1);
537  EFANode * node5 = _boundary_edges[2]->getNode(1);
538 
539  new_frag1->addEdge(new EFAEdge(node2, node3));
540  new_frag1->addEdge(new EFAEdge(node3, node4));
541  new_frag1->addEdge(new EFAEdge(node4, node5));
542  new_frag1->addEdge(new EFAEdge(node5, node2));
543 
544  new_frag2->addEdge(new EFAEdge(node1, node2));
545  new_frag2->addEdge(new EFAEdge(node2, node5));
546  new_frag2->addEdge(new EFAEdge(node5, node1));
547 
548  new_fragments.push_back(new_frag1);
549  new_fragments.push_back(new_frag2);
550  }
551  }
552  else if (cut_nodes.size() == 2)
553  {
554  if ((cut_nodes[0] == 0 && cut_nodes[1] == 2) || (cut_nodes[0] == 2 && cut_nodes[1] == 0))
555  {
556  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
557  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
558  EFANode * node1 = _boundary_edges[0]->getNode(0);
559  EFANode * node2 = _boundary_edges[1]->getNode(0);
560  EFANode * node3 = _boundary_edges[2]->getNode(0);
561  EFANode * node4 = _boundary_edges[3]->getNode(0);
562 
563  new_frag1->addEdge(new EFAEdge(node1, node2));
564  new_frag1->addEdge(new EFAEdge(node2, node3));
565  new_frag1->addEdge(new EFAEdge(node3, node1));
566 
567  new_frag2->addEdge(new EFAEdge(node3, node4));
568  new_frag2->addEdge(new EFAEdge(node4, node1));
569  new_frag2->addEdge(new EFAEdge(node1, node3));
570 
571  new_fragments.push_back(new_frag1);
572  new_fragments.push_back(new_frag2);
573  }
574  else if ((cut_nodes[0] == 1 && cut_nodes[1] == 3) || (cut_nodes[0] == 3 && cut_nodes[1] == 1))
575  {
576  EFAFragment2D * new_frag1 = new EFAFragment2D(_host_elem, false, NULL);
577  EFAFragment2D * new_frag2 = new EFAFragment2D(_host_elem, false, NULL);
578  EFANode * node1 = _boundary_edges[0]->getNode(0);
579  EFANode * node2 = _boundary_edges[1]->getNode(0);
580  EFANode * node3 = _boundary_edges[2]->getNode(0);
581  EFANode * node4 = _boundary_edges[3]->getNode(0);
582 
583  new_frag1->addEdge(new EFAEdge(node1, node2));
584  new_frag1->addEdge(new EFAEdge(node2, node4));
585  new_frag1->addEdge(new EFAEdge(node4, node1));
586 
587  new_frag2->addEdge(new EFAEdge(node2, node3));
588  new_frag2->addEdge(new EFAEdge(node3, node4));
589  new_frag2->addEdge(new EFAEdge(node4, node2));
590 
591  new_fragments.push_back(new_frag1);
592  new_fragments.push_back(new_frag2);
593  }
594  else if ((cut_nodes[0] == 0 && cut_nodes[1] == 1) || (cut_nodes[0] == 1 && cut_nodes[1] == 2) ||
595  (cut_nodes[0] == 2 && cut_nodes[1] == 3) || (cut_nodes[0] == 3 && cut_nodes[1] == 0) ||
596  (cut_nodes[0] == 1 && cut_nodes[1] == 0) || (cut_nodes[0] == 2 && cut_nodes[1] == 1) ||
597  (cut_nodes[0] == 3 && cut_nodes[1] == 2) || (cut_nodes[0] == 0 && cut_nodes[1] == 3))
598  {
599  EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, NULL);
600  EFANode * node1 = _boundary_edges[0]->getNode(0);
601  EFANode * node2 = _boundary_edges[1]->getNode(0);
602  EFANode * node3 = _boundary_edges[2]->getNode(0);
603  EFANode * node4 = _boundary_edges[3]->getNode(0);
604 
605  new_frag->addEdge(new EFAEdge(node1, node2));
606  new_frag->addEdge(new EFAEdge(node2, node3));
607  new_frag->addEdge(new EFAEdge(node3, node4));
608  new_frag->addEdge(new EFAEdge(node4, node1));
609 
610  new_fragments.push_back(new_frag);
611  }
612  }
613  else if (cut_edges.size() == 2 || (cut_edges.size() == 1 && cut_nodes.size() == 0))
614  {
615  unsigned int iedge = 0;
616  unsigned int icutedge = 0;
617 
618  do // loop over new fragments
619  {
620  EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, NULL);
621 
622  do // loop over edges
623  {
624  if (iedge == cut_edges[icutedge])
625  {
626  EFANode * first_node_on_edge = _boundary_edges[iedge]->getNode(0);
627  unsigned int iprevedge(iedge > 0 ? iedge - 1 : _boundary_edges.size() - 1);
628  if (!_boundary_edges[iprevedge]->containsNode(first_node_on_edge))
629  {
630  first_node_on_edge = _boundary_edges[iedge]->getNode(1);
631  if (!_boundary_edges[iprevedge]->containsNode(first_node_on_edge))
632  EFAError("Previous edge does not contain either of the nodes in this edge");
633  }
634  EFANode * embedded_node1 = _boundary_edges[iedge]->getEmbeddedNode(0);
635  new_frag->addEdge(new EFAEdge(first_node_on_edge, embedded_node1));
636 
637  ++icutedge; // jump to next cut edge or jump back to this edge when only 1 cut edge
638  if (icutedge == cut_edges.size())
639  icutedge = 0;
640  iedge = cut_edges[icutedge];
641  EFANode * embedded_node2 = _boundary_edges[iedge]->getEmbeddedNode(0);
642  if (embedded_node2 != embedded_node1)
643  new_frag->addEdge(new EFAEdge(embedded_node1, embedded_node2));
644 
645  EFANode * second_node_on_edge = _boundary_edges[iedge]->getNode(1);
646  unsigned int inextedge(iedge < (_boundary_edges.size() - 1) ? iedge + 1 : 0);
647  if (!_boundary_edges[inextedge]->containsNode(second_node_on_edge))
648  {
649  second_node_on_edge = _boundary_edges[iedge]->getNode(0);
650  if (!_boundary_edges[inextedge]->containsNode(second_node_on_edge))
651  EFAError("Next edge does not contain either of the nodes in this edge");
652  }
653  new_frag->addEdge(new EFAEdge(embedded_node2, second_node_on_edge));
654  }
655  else // not a cut edge
656  new_frag->addEdge(new EFAEdge(*_boundary_edges[iedge]));
657 
658  ++iedge;
659  if (iedge == _boundary_edges.size())
660  iedge = 0;
661  } while (!_boundary_edges[iedge]->containsEdge(*new_frag->getEdge(0)));
662 
663  if (cut_edges.size() > 1)
664  { // set the starting point for the loop over the other part of the element
665  iedge = cut_edges[0] + 1;
666  if (iedge == _boundary_edges.size())
667  iedge = 0;
668  }
669 
670  new_fragments.push_back(new_frag);
671  } while (new_fragments.size() < cut_edges.size());
672  }
673  else if (cut_nodes.size() == 1)
674  {
675  EFAFragment2D * new_frag = new EFAFragment2D(_host_elem, false, NULL);
676  for (unsigned int iedge = 0; iedge < _boundary_edges.size(); ++iedge)
677  {
678  EFANode * first_node_on_edge = _boundary_edges[iedge]->getNode(0);
679  EFANode * second_node_on_edge = _boundary_edges[iedge]->getNode(1);
680  new_frag->addEdge(new EFAEdge(first_node_on_edge, second_node_on_edge));
681  }
682  new_fragments.push_back(new_frag);
683  }
684 
685  return new_fragments;
686 }
std::vector< unsigned int > getInteriorEdgeID() const
unsigned int numEdges() const
virtual bool isConnected(EFAFragment *other_fragment) const
bool containsEdge(const EFAEdge &other) const
Definition: EFAEdge.C:61
EFAFragment2D * getFragment(unsigned int frag_id) const
virtual void removeInvalidEmbeddedNodes(std::map< unsigned int, EFANode * > &EmbeddedNodes)
void combineTipEdges()
bool deleteFromMap(std::map< unsigned int, T * > &theMap, T *elemToDelete, bool delete_elem=true)
Definition: EFAFuncs.h:21
EFAEdge * getEdge(unsigned int edge_id) const
Definition: EFAFace.C:258
std::set< EFANode * > getEdgeNodes(unsigned int edge_id) const
void addEdge(EFAEdge *new_edge)
virtual unsigned int numInteriorNodes() const
Definition: EFAElement2D.C:351
unsigned int numEdges() const
Definition: EFAFace.C:252
double distanceFromNode1(EFANode *node) const
Definition: EFAEdge.C:246
std::vector< EFAFragment2D * > split()
EFAEdge * getEdge(unsigned int edge_id) const
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
bool isSecondaryInteriorEdge(unsigned int edge_id) const
EFAFaceNode * getInteriorNode(unsigned int interior_node_id) const
virtual unsigned int getNumCutNodes() const
Definition: EFAFragment2D.C:98
virtual std::set< EFANode * > getAllNodes() const
EFAElement2D * getHostElement() const
std::vector< EFAEdge * > _boundary_edges
Definition: EFAFragment2D.h:31
virtual unsigned int getNumCuts() const
Definition: EFAFragment2D.C:86
bool isEdgeInterior(unsigned int edge_id) const
EFANode * getNode()
Definition: EFAFaceNode.C:23
bool hasIntersection() const
Definition: EFAEdge.C:196
virtual unsigned int numFragments() const
Definition: EFAElement2D.C:200
virtual void switchNode(EFANode *new_node, EFANode *old_node)
Definition: EFAFragment2D.C:64
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
Definition: EFAEdge.C:128
unsigned int numEdges() const
void deleteInteriorNodes()
EFAFragment2D(EFAElement2D *host, bool create_boundary_edges, const EFAElement2D *from_host, unsigned int frag_id=std::numeric_limits< unsigned int >::max())
Definition: EFAFragment2D.C:19
EFAElement2D * _host_elem
Definition: EFAFragment2D.h:30
EFAEdge * getEdge(unsigned int edge_id) const
virtual bool containsNode(EFANode *node) const
Definition: EFAFragment2D.C:71