31 "In EFAelement2D the supported element types are QUAD4, QUAD8, QUAD9, TRI3, TRI6 and TRI7");
38 :
EFAElement(from_elem->_id, from_elem->_num_nodes),
39 _num_edges(from_elem->_num_edges),
40 _edges(_num_edges, nullptr),
41 _edge_neighbors(_num_edges, {
nullptr})
46 for (
unsigned int i = 0; i < _num_nodes; ++i)
53 _local_nodes.push_back(_nodes[i]);
56 EFAError(
"In EFAelement2D ",
58 " the copy constructor must have from_elem w/ global nodes. node: ",
61 from_elem->_nodes[i]->category());
65 for (
unsigned int i = 0; i < _num_edges; ++i)
66 _edges[i] =
new EFAEdge(*from_elem->_edges[i]);
67 for (
unsigned int i = 0; i < from_elem->_fragments.size(); ++i)
68 _fragments.push_back(
new EFAFragment2D(
this,
true, from_elem, i));
69 for (
unsigned int i = 0; i < from_elem->_interior_nodes.size(); ++i)
70 _interior_nodes.push_back(
new EFAFaceNode(*from_elem->_interior_nodes[i]));
73 for (
unsigned int i = 0; i < _num_nodes; ++i)
81 EFAError(
"In EFAelement2D copy constructor this elem's nodes must be local");
84 _local_node_coor = from_elem->_local_node_coor;
87 EFAError(
"this EFAelement2D constructor only converts global nodes to local nodes");
92 _num_edges(from_face->numEdges()),
93 _edges(_num_edges, nullptr),
94 _edge_neighbors(_num_edges, {
nullptr})
96 for (
unsigned int i = 0; i < _num_nodes; ++i)
97 _nodes[i] = from_face->
getNode(i);
98 for (
unsigned int i = 0; i < _num_edges; ++i)
99 _edges[i] =
new EFAEdge(*from_face->getEdge(i));
100 for (
unsigned int i = 0; i < from_face->numInteriorNodes(); ++i)
101 _interior_nodes.push_back(
new EFAFaceNode(*from_face->getInteriorNode(i)));
106 for (
unsigned int i = 0; i <
_fragments.size(); ++i)
114 for (
unsigned int i = 0; i <
_edges.size(); ++i)
215 bool partial =
false;
220 bool node_in_frag =
false;
244 for (
unsigned int i = 0; i <
_nodes.size(); ++i)
245 non_physical_nodes.insert(
_nodes[i]);
248 std::set<EFANode *>::iterator sit;
249 for (sit = non_physical_nodes.begin(); sit != non_physical_nodes.end();)
252 for (
unsigned int i = 0; i <
_fragments.size(); ++i)
256 non_physical_nodes.erase(sit++);
272 if (
_nodes[i] == old_node)
275 for (
unsigned int i = 0; i <
_fragments.size(); ++i)
278 for (
unsigned int i = 0; i <
_edges.size(); ++i)
281 if (
_parent && descend_to_parent)
300 for (
unsigned int i = 0; i <
_fragments.size(); ++i)
306 std::vector<EFANode *> & master_nodes,
307 std::vector<double> & master_weights)
const 311 master_nodes.clear();
312 master_weights.clear();
313 bool masters_found =
false;
318 masters_found =
_edges[i]->getNodeMasters(node, master_nodes, master_weights);
322 EFAError(
"In getMasterInfo: cannot find master nodes in element edges");
332 std::vector<double> emb_xi(2, 0.0);
337 master_nodes.push_back(
_nodes[
j]);
344 EFAError(
"unknown 2D element");
345 master_weights.push_back(
weight);
347 masters_found =
true;
354 EFAError(
"In EFAelement2D::getMaterInfo, cannot find the given EFAnode");
366 bool overlays =
false;
374 if (common_nodes.size() == 2)
376 std::vector<EFANode *> common_nodes_vec(common_nodes.begin(), common_nodes.end());
382 if (
_nodes[i] == common_nodes_vec[0])
386 else if (
_nodes[i] == common_nodes_vec[1])
393 EFAError(
"in overlays_elem() couldn't find common node");
395 bool e1ascend =
false;
396 unsigned int e1n1idx_plus1(e1n1idx < (
_num_edges - 1) ? e1n1idx + 1 : 0);
397 unsigned int e1n1idx_minus1(e1n1idx > 0 ? e1n1idx - 1 :
_num_edges - 1);
398 if (e1n2idx == e1n1idx_plus1)
404 if (e1n2idx != e1n1idx_minus1)
405 EFAError(
"in overlays_elem() common nodes must be adjacent to each other");
412 if (other_elem->
getNode(i) == common_nodes_vec[0])
416 else if (other_elem->
getNode(i) == common_nodes_vec[1])
422 EFAError(
"in overlays_elem() couldn't find common node");
424 bool e2ascend =
false;
425 unsigned int e2n1idx_plus1(e2n1idx < (
_num_edges - 1) ? e2n1idx + 1 : 0);
426 unsigned int e2n1idx_minus1(e2n1idx > 0 ? e2n1idx - 1 :
_num_edges - 1);
427 if (e2n2idx == e2n1idx_plus1)
433 if (e2n2idx != e2n1idx_minus1)
434 EFAError(
"in overlays_elem() common nodes must be adjacent to each other");
438 if ((e1ascend && e2ascend) || (!e1ascend && !e2ascend))
443 else if (common_nodes.size() > 2)
460 "in get_neighbor_index() element: ",
_id,
" does not have neighbor: ", neighbor_elem->
id());
467 for (
unsigned int edge_iter = 0; edge_iter <
_num_edges; ++edge_iter)
479 EFAError(
"neighbor_elem is not of EFAelement2D type");
482 if (common_nodes.size() >= 2)
484 for (
unsigned int edge_iter = 0; edge_iter <
_num_edges; ++edge_iter)
486 std::set<EFANode *> edge_nodes =
getEdgeNodes(edge_iter);
487 bool is_edge_neighbor =
false;
494 EFAError(
"in updateEdgeNeighbors: Cannot have more than 1 fragment");
498 is_edge_neighbor =
true;
501 is_edge_neighbor =
true;
504 if (is_edge_neighbor)
512 " already has 2 edge neighbors: ",
530 for (
unsigned int edge_iter = 0; edge_iter <
_num_edges; ++edge_iter)
532 for (
unsigned int en_iter = 0; en_iter <
_edge_neighbors[edge_iter].size(); ++en_iter)
535 if (neigh_elem !=
nullptr)
537 bool found_neighbor =
false;
538 for (
unsigned int edge_iter2 = 0; edge_iter2 < neigh_elem->
numEdges(); ++edge_iter2)
540 for (
unsigned int en_iter2 = 0; en_iter2 < neigh_elem->
numEdgeNeighbors(edge_iter2);
545 if ((en_iter2 > 1) && (en_iter > 1))
547 "Element and neighbor element cannot both have >1 neighbors on a common edge");
548 found_neighbor =
true;
554 EFAError(
"Neighbor element doesn't recognize current element as neighbor");
565 CrackTipElements.insert(
this);
566 for (
unsigned int edge_iter = 0; edge_iter <
_num_edges; ++edge_iter)
575 EFAError(
"Element has a neighbor that overlays itself");
579 EFAError(
"crack_tip_split_element already flagged. In elem: ",
603 for (
unsigned int edge_iter = 0; edge_iter <
_num_edges; ++edge_iter)
615 EFAError(
"In getCrackTipSplitElementID could not find element id");
628 bool should_duplicate =
false;
631 std::set<EFAElement *>::iterator sit;
632 sit = CrackTipElements.find(
this);
634 should_duplicate =
true;
636 should_duplicate =
true;
638 should_duplicate =
true;
640 return should_duplicate;
650 bool should_duplicate =
false;
653 std::vector<unsigned int> split_neighbors;
655 should_duplicate =
true;
661 std::set<EFANode *> non_physical_nodes;
668 EFAError(
"general elem is not of type EFAelement2D");
671 std::set<EFAElement *>::iterator sit;
672 sit = CrackTipElements.find(neigh_elem);
673 if (sit != CrackTipElements.end() && neigh_elem->
numFragments() > 1)
675 for (
unsigned int i = 0; i < neigh_elem->
numEdges(); ++i)
677 std::set<EFANode *> neigh_edge_nodes = neigh_elem->
getEdgeNodes(i);
681 should_duplicate =
true;
686 if (should_duplicate)
691 return should_duplicate;
700 bool should_duplicate =
false;
711 for (
unsigned int j = 0;
j < neighbor_elem->
numEdges(); ++
j)
719 should_duplicate =
true;
726 if (should_duplicate)
730 return should_duplicate;
739 bool will_extend =
false;
746 EFAError(
"in will_crack_tip_extend() element: ",
755 EFAError(
"in will_crack_tip_extend() element: ",
764 std::vector<EFANode *> neigh_cut_nodes = frag1->
getCommonNodes(frag2);
765 if (neigh_cut_nodes.size() != 2)
766 EFAError(
"2 frags in a elem does not share 2 common nodes");
767 if (
_edges[neigh_idx]->isEmbeddedNode(neigh_cut_nodes[0]) ||
768 _edges[neigh_idx]->isEmbeddedNode(neigh_cut_nodes[1]))
770 split_neighbors.push_back(neigh_idx);
788 unsigned int num_cuts = 0;
790 if (
_edges[i]->hasIntersection())
791 num_cuts +=
_edges[i]->numEmbeddedNodes();
799 bool cut_twice =
false;
802 unsigned int num_interior_edges = 0;
803 for (
unsigned int i = 0; i <
_fragments[0]->numEdges(); ++i)
806 num_interior_edges += 1;
808 if (num_interior_edges == 2)
816 std::map<unsigned int, EFANode *> & EmbeddedNodes)
819 std::set<EFAElement *>::iterator sit;
820 sit = CrackTipElements.find(
this);
821 if (sit != CrackTipElements.end())
826 EFAError(
"crack tip elem ",
_id,
" must have 1 fragment");
832 _fragments[0]->removeInvalidEmbeddedNodes(EmbeddedNodes);
838 EFAError(
"Element ",
_id,
" must have 1 fragment at this point");
841 unsigned int num_cut_frag_edges =
_fragments[0]->getNumCuts();
842 unsigned int num_cut_nodes =
_fragments[0]->getNumCutNodes();
843 unsigned int num_frag_edges =
_fragments[0]->numEdges();
844 if (num_cut_frag_edges > 3)
845 EFAError(
"In element ",
_id,
" there are more than 2 cut fragment edges");
847 if (num_cut_frag_edges == 0 && num_cut_nodes == 0)
861 std::vector<EFAFragment2D *> new_frags;
862 if (num_cut_frag_edges == 3)
869 for (
unsigned int i = 0; i < new_frags.size(); ++i)
878 if (n_old_frag_cuts > 3)
879 EFAError(
"Sanity check: in element ",
_id,
" frag has more than 3 cut edges");
882 std::vector<unsigned int> num_emb;
883 std::vector<unsigned int> num_perm;
884 std::vector<unsigned int> num_emb_perm;
885 for (
unsigned int i = 0; i <
_fragments.size(); ++i)
887 num_emb.push_back(0);
888 num_perm.push_back(0);
889 num_emb_perm.push_back(0);
890 std::set<EFANode *> perm_nodes;
891 std::set<EFANode *> emb_nodes;
892 std::set<EFANode *> emb_perm_nodes;
895 for (
unsigned int k = 0;
k < 2; ++
k)
899 perm_nodes.insert(temp_node);
901 emb_nodes.insert(temp_node);
903 emb_perm_nodes.insert(temp_node);
905 EFAError(
"Invalid node category");
908 num_perm[i] = perm_nodes.size();
909 num_emb[i] = emb_nodes.size();
910 num_emb_perm[i] = emb_perm_nodes.size();
914 for (
unsigned int i = 0; i <
_fragments.size(); ++i)
915 if (num_emb_perm[i] != 0)
919 if (n_interior_nodes > 0 && n_interior_nodes != 1)
920 EFAError(
"After update_fragments this element has ", n_interior_nodes,
" interior nodes");
922 if (n_old_frag_cuts == 0)
925 EFAError(
"Incorrect link size for element with 0 cuts");
927 else if (n_old_frag_cuts == 1)
930 EFAError(
"Incorrect link size for element with 1 cut");
932 else if (n_old_frag_cuts == 2)
936 EFAError(
"Incorrect link size for element with 2 cuts");
938 else if (n_old_frag_cuts == 3)
941 _fragments[2]->numEdges()) != n_old_frag_edges + 9)
942 EFAError(
"Incorrect link size for element with 3 cuts");
945 EFAError(
"Unexpected number of old fragment cuts");
953 EFAError(
"from_elem is not of EFAelement2D type");
957 EFAError(
"in restoreFragmentInfo elements must not have any pre-existing fragments");
958 for (
unsigned int i = 0; i < from_elem2d->
numFragments(); ++i)
963 EFAError(
"in restoreFragmentInfo elements must not have any pre-exsiting interior nodes");
969 EFAError(
"In restoreEdgeIntersection: edge cuts already exist in element ",
_id);
972 if (from_elem2d->
_edges[i]->hasIntersection())
973 _edges[i]->copyIntersection(*from_elem2d->
_edges[i], 0);
974 if (
_edges[i]->numEmbeddedNodes() > 2)
975 EFAError(
"elem ",
_id,
" has an edge with >2 cuts");
979 for (
unsigned int i = 0; i < from_elem2d->
numNodes(); ++i)
985 EFAError(
"In restoreFragmentInfo all of from_elem's nodes must be local");
991 std::map<unsigned int, EFAElement *> & Elements,
992 std::map<unsigned int, EFAElement *> & newChildElements,
993 std::vector<EFAElement *> & ChildElements,
994 std::vector<EFAElement *> & ParentElements,
995 std::map<unsigned int, EFANode *> & TempNodes)
998 EFAError(
"Element cannot have existing children in createChildElements");
1000 bool shouldDuplicateForCutNodeElement =
false;
1004 shouldDuplicateForCutNodeElement =
true;
1008 shouldDuplicateForCutNodeElement)
1011 EFAError(
"More than 3 fragments not yet supported");
1014 ParentElements.push_back(
this);
1015 for (
unsigned int ichild = 0; ichild <
_fragments.size(); ++ichild)
1017 unsigned int new_elem_id;
1018 if (newChildElements.size() == 0)
1024 newChildElements.insert(std::make_pair(new_elem_id, childElem));
1026 ChildElements.push_back(childElem);
1030 std::vector<EFAPoint> local_embedded_node_coor;
1036 std::vector<EFANode *> master_nodes;
1037 std::vector<double> master_weights;
1039 for (
unsigned int j = 0;
j < 2; ++
j)
1044 for (
unsigned int k = 0;
k < master_nodes.size(); ++
k)
1050 local_embedded_node_coor.push_back(coor);
1060 if (local_embedded_node_coor.size())
1062 EFAPoint cut_line = local_embedded_node_coor[1] - local_embedded_node_coor[0];
1063 normal =
EFAPoint(cut_line(1), -cut_line(0), 0.0);
1065 origin = (local_embedded_node_coor[0] + local_embedded_node_coor[1]) * 0.5;
1068 if (local_embedded_node_coor.size() == 4)
1070 EFAPoint cut_line = local_embedded_node_coor[3] - local_embedded_node_coor[2];
1071 normal2 =
EFAPoint(cut_line(1), -cut_line(0), 0.0);
1073 origin2 = (local_embedded_node_coor[2] + local_embedded_node_coor[3]) * 0.5;
1082 EFAPoint origin_to_point = p - origin;
1083 EFAPoint origin2_to_point = p - origin2;
1092 TempNodes.insert(std::make_pair(new_node_id, newNode));
1104 TempNodes.insert(std::make_pair(new_node_id, newNode));
1107 else if (origin_to_point * normal <
Xfem::tol && origin2_to_point * normal2 <
Xfem::tol &&
1123 TempNodes.insert(std::make_pair(new_node_id, newNode));
1137 if (
_edges[
j]->hasIntersection())
1161 for (
unsigned int i = 0; i <
_num_edges; ++i)
1163 std::vector<EFANode *> nodes_to_delete;
1164 for (
unsigned int j = 0;
j <
_edges[i]->numEmbeddedNodes(); ++
j)
1167 nodes_to_delete.push_back(
_edges[i]->getEmbeddedNode(
j));
1169 for (
unsigned int j = 0;
j < nodes_to_delete.size(); ++
j)
1170 _edges[i]->removeEmbeddedNode(nodes_to_delete[
j]);
1177 std::map<unsigned int, EFANode *> & TempNodes,
1178 std::map<
EFANode *, std::set<EFAElement *>> & InverseConnectivityMap,
1179 bool merge_phantom_edges)
1183 EFAError(
"no parent element for child element ",
_id,
" in connect_neighbors");
1186 EFAError(
"cannot dynamic cast to parent2d in connect_neighbors");
1196 if (
_edges[
j]->hasIntersection())
1198 for (
unsigned int l = 0; l < NeighborElem->
numChildren(); ++l)
1202 if (!childOfNeighborElem)
1203 EFAError(
"dynamic cast childOfNeighborElem fails");
1206 EFAEdge * neighborChildEdge = childOfNeighborElem->
getEdge(neighbor_edge_id);
1207 if (
_edges[
j]->equivalent(*neighborChildEdge))
1212 unsigned int num_edge_nodes = 2;
1213 for (
unsigned int i = 0; i < num_edge_nodes; ++i)
1215 unsigned int childNodeIndex = i;
1216 unsigned int neighborChildNodeIndex = num_edge_nodes - 1 - childNodeIndex;
1219 EFANode * childOfNeighborNode = neighborChildEdge->
getNode(neighborChildNodeIndex);
1222 childNode, childOfNeighborNode, childOfNeighborElem, PermanentNodes, TempNodes);
1229 childNode, childOfNeighborNode, childOfNeighborElem, PermanentNodes, TempNodes);
1236 if (merge_phantom_edges)
1238 for (
unsigned int l = 0; l < NeighborElem->
numChildren(); ++l)
1242 if (!childOfNeighborElem)
1243 EFAError(
"dynamic cast childOfNeighborElem fails");
1245 EFAEdge * neighborChildEdge = childOfNeighborElem->
getEdge(neighbor_edge_id);
1251 unsigned int num_edge_nodes = 2;
1252 for (
unsigned int i = 0; i < num_edge_nodes; ++i)
1254 unsigned int childNodeIndex = i;
1255 unsigned int neighborChildNodeIndex = num_edge_nodes - 1 - childNodeIndex;
1258 EFANode * childOfNeighborNode = neighborChildEdge->
getNode(neighborChildNodeIndex);
1260 if (childNode->
parent() !=
nullptr &&
1265 childOfNeighborNode,
1266 childOfNeighborElem,
1287 std::set<EFAElement *> patch_elems = InverseConnectivityMap[childNode->
parent()];
1288 if (parent2d->
numFragments() == 1 && patch_elems.size() == 1)
1295 PermanentNodes.insert(std::make_pair(new_node_id, newNode));
1300 "Attempted to delete node: ", childNode->
id(),
" from TempNodes, but couldn't find it");
1310 if (
_nodes[
j]->parent() !=
nullptr &&
1319 ostream << std::setw(4);
1320 ostream <<
_id <<
" | ";
1323 ostream << std::setw(5) <<
_nodes[
j]->idCatString();
1329 ostream << std::setw(4);
1330 if (
_edges[
j]->hasIntersection())
1332 if (
_edges[
j]->numEmbeddedNodes() > 1)
1335 for (
unsigned int k = 0;
k <
_edges[
j]->numEmbeddedNodes(); ++
k)
1337 ostream <<
_edges[
j]->getEmbeddedNode(
k)->id();
1338 if (
k ==
_edges[
j]->numEmbeddedNodes() - 1)
1345 ostream <<
_edges[
j]->getEmbeddedNode(0)->id() <<
" ";
1368 ostream << std::setw(4);
1378 ostream << std::setw(4);
1379 ostream <<
" " <<
j <<
" | ";
1386 ostream << std::setw(5) << prt_node->
idCatString();
1389 ostream << std::endl;
1398 EFAError(
"frag_id out of bounds");
1404 std::set<EFANode *> edge_nodes;
1414 unsigned int edge_id = std::numeric_limits<unsigned int>::max();
1415 bool edge_found =
false;
1416 for (
unsigned int i = 0; i <
_num_edges; ++i)
1427 double rel_dist =
_edges[edge_id]->distanceFromNode1(node);
1428 double xi_1d = 2.0 * rel_dist - 1.0;
1440 EFAError(
"interior_node_id out of bounds");
1466 for (
unsigned int i = 0; i <
_num_edges; ++i)
1468 unsigned int i_plus1(i < (
_num_edges - 1) ? i + 1 : 0);
1491 EFAError(
"frag_id out of bounds in get_frag_edge()");
1497 std::set<EFANode *> phantom_nodes;
1500 for (
unsigned int j = 0;
j < 2; ++
j)
1502 bool node_in_frag =
false;
1507 node_in_frag =
true;
1515 return phantom_nodes;
1524 bool frag_edge_found =
false;
1525 frag_edge_id = std::numeric_limits<unsigned int>::max();
1528 for (
unsigned int j = 0;
j <
_fragments[0]->numEdges(); ++
j)
1533 frag_edge_found =
true;
1538 return frag_edge_found;
1544 bool is_phantom =
false;
1547 bool contain_frag_edge =
false;
1548 for (
unsigned int i = 0; i <
_fragments.size(); ++i)
1550 for (
unsigned int j = 0;
j <
_fragments[i]->numEdges(); ++
j)
1554 contain_frag_edge =
true;
1558 if (contain_frag_edge)
1561 if (!contain_frag_edge)
1570 unsigned int num_neighbors = 0;
1573 return num_neighbors;
1582 EFAError(
"edge neighbor does not exist");
1588 bool has_tip_edges =
false;
1591 for (
unsigned int i = 0; i <
_num_edges; ++i)
1593 unsigned int num_frag_edges = 0;
1594 if (
_edges[i]->hasIntersection())
1596 for (
unsigned int j = 0;
j <
_fragments[0]->numEdges(); ++
j)
1599 num_frag_edges += 1;
1601 if (num_frag_edges == 2)
1603 has_tip_edges =
true;
1609 return has_tip_edges;
1616 unsigned int tip_edge_id = std::numeric_limits<unsigned int>::max();
1619 for (
unsigned int i = 0; i <
_num_edges; ++i)
1621 unsigned int num_frag_edges = 0;
1622 if (
_edges[i]->hasIntersection())
1624 for (
unsigned int j = 0;
j <
_fragments[0]->numEdges(); ++
j)
1627 num_frag_edges += 1;
1629 if (num_frag_edges == 2)
1647 for (
unsigned int i = 0; i <
_num_edges; ++i)
1649 std::vector<EFAEdge *> frag_edges;
1650 if (
_edges[i]->hasIntersection())
1652 for (
unsigned int j = 0;
j <
_fragments[0]->numEdges(); ++
j)
1657 if (frag_edges.size() == 2)
1660 tip_emb = frag_edges[0]->
getNode(1);
1662 tip_emb = frag_edges[0]->
getNode(0);
1664 EFAError(
"Common node can't be found between 2 tip frag edges");
1676 bool contains_tip =
false;
1679 unsigned int num_frag_edges = 0;
1680 if (
_edges[edge_id]->hasIntersection())
1682 for (
unsigned int j = 0;
j <
_fragments[0]->numEdges(); ++
j)
1685 num_frag_edges += 1;
1687 if (num_frag_edges == 2)
1688 contains_tip =
true;
1691 return contains_tip;
1698 bool has_cut =
false;
1703 unsigned int FragEdgeID = std::numeric_limits<unsigned int>::max();
1718 std::map<unsigned int, EFANode *> & EmbeddedNodes,
1719 bool add_to_neighbor)
1721 EFANode * local_embedded =
nullptr;
1724 local_embedded = embedded_node;
1726 if (
_edges[edge_id]->hasIntersectionAtPosition(position, edge_node1) && position >
Xfem::tol &&
1729 unsigned int emb_id =
_edges[edge_id]->getEmbeddedNodeIndex(position, edge_node1);
1730 EFANode * old_emb =
_edges[edge_id]->getEmbeddedNode(emb_id);
1731 if (embedded_node && embedded_node != old_emb)
1733 EFAError(
"Attempting to add edge intersection when one already exists with different node.",
1741 local_embedded = old_emb;
1745 bool add2elem =
true;
1749 unsigned int frag_edge_id = std::numeric_limits<unsigned int>::max();
1750 EFAEdge * frag_edge =
nullptr;
1751 EFANode * frag_edge_node1 =
nullptr;
1752 double frag_pos = -1.0;
1753 bool add2frag =
false;
1760 double xi[2] = {-1.0, -1.0};
1761 xi[0] =
_edges[edge_id]->distanceFromNode1(frag_edge->
getNode(0));
1762 xi[1] =
_edges[edge_id]->distanceFromNode1(frag_edge->
getNode(1));
1763 if ((position - xi[0]) * (position - xi[1]) <
1766 frag_edge_node1 = frag_edge->
getNode(0);
1767 frag_pos = (position - xi[0]) / (xi[1] - xi[0]);
1775 EFAWarning(
"attempting to add new cut to a cut fragment edge");
1785 if (!local_embedded)
1789 EmbeddedNodes.insert(std::make_pair(new_node_id, local_embedded));
1791 _edges[edge_id]->addIntersection(position, local_embedded, edge_node1);
1792 if (
_edges[edge_id]->numEmbeddedNodes() > 2)
1793 EFAError(
"element edge can't have >2 embedded nodes");
1799 frag_edge->
addIntersection(frag_pos, local_embedded, frag_edge_node1);
1801 EFAError(
"fragment edge can't have >1 embedded nodes");
1805 if (add_to_neighbor)
1807 for (
unsigned int en_iter = 0; en_iter <
numEdgeNeighbors(edge_id); ++en_iter)
1811 if (edge_neighbor->
getEdge(neighbor_edge_id)->
getNode(0) == edge_node1)
1812 EFAError(
"neighbor edge has the same direction as this edge");
1813 double neigh_pos = 1.0 - position;
1814 edge_neighbor->
addEdgeCut(neighbor_edge_id, neigh_pos, local_embedded, EmbeddedNodes,
false);
1821 EFANode * embedded_permanent_node,
1822 std::map<unsigned int, EFANode *> & PermanentNodes,
1823 std::map<unsigned int, EFANode *> & EmbeddedPermanentNodes)
1825 EFANode * local_embedded_permanent =
nullptr;
1827 if (embedded_permanent_node)
1828 local_embedded_permanent = embedded_permanent_node;
1833 local_embedded_permanent = node;
1834 EmbeddedPermanentNodes.insert(std::make_pair(node->
id(), local_embedded_permanent));
1836 EFAError(
"Attempted to delete node: ",
1837 local_embedded_permanent->
id(),
1838 " from PermanentNodes, but couldn't find it");
1845 std::map<unsigned int, EFANode *> & EmbeddedNodes)
1848 EFAError(
"Element: ",
_id,
" should have only 1 fragment in addFragEdgeIntersection");
1849 EFANode * local_embedded =
nullptr;
1852 bool isValidIntersection =
true;
1859 isValidIntersection =
false;
1863 isValidIntersection =
false;
1866 if (isValidIntersection)
1871 EFAError(
"Attempting to add fragment edge intersection when one already exists with " 1872 "different position.",
1884 if (!
_fragments[0]->isEdgeInterior(frag_edge_id) ||
1885 _fragments[0]->isSecondaryInteriorEdge(frag_edge_id))
1886 EFAError(
"Attemping to add intersection to an invalid fragment edge. Element: ",
1894 EmbeddedNodes.insert(std::make_pair(new_node_id, local_embedded));
1901 std::vector<double> node1_para_coor(2, 0.0);
1902 std::vector<double> node2_para_coor(2, 0.0);
1906 double xi = (1.0 - position) * node1_para_coor[0] + position * node2_para_coor[0];
1907 double eta = (1.0 - position) * node1_para_coor[1] + position * node2_para_coor[1];
1911 EFAError(
"elem: ",
_id,
" cannot get the parametric coords of two end embedded nodes");
1918 return isValidIntersection;
1921 std::vector<EFAFragment2D *>
1925 EFAError(
"branching is only allowed for an uncut element");
1928 std::vector<EFANode *> three_nodes;
1929 for (
unsigned int i = 0; i <
_edges.size(); ++i)
1932 if (
_edges[i]->numEmbeddedNodes() == 1)
1933 three_nodes.push_back(
_edges[i]->getEmbeddedNode(0));
1934 else if (
_edges[i]->numEmbeddedNodes() == 2)
1937 _edges[i]->getIntersection(0, node1) <
_edges[i]->getIntersection(1, node1) ? 0 : 1);
1938 unsigned int id1 = 1 - id0;
1939 three_nodes.push_back(
_edges[i]->getEmbeddedNode(id0));
1940 three_nodes.push_back(
_edges[i]->getEmbeddedNode(id1));
1943 if (three_nodes.size() != 3)
1944 EFAError(
"three_nodes.size() != 3");
1948 std::vector<double> center_xi(2, 0.0);
1949 for (
unsigned int i = 0; i < 3; ++i)
1951 std::vector<double> xi_2d(2, 0.0);
1953 center_xi[0] += xi_2d[0];
1954 center_xi[1] += xi_2d[1];
1956 center_xi[0] /= 3.0;
1957 center_xi[1] /= 3.0;
1962 EmbeddedNodes.insert(std::make_pair(new_node_id, new_emb));
1966 std::vector<EFAFragment2D *> new_fragments;
1967 for (
unsigned int i = 0; i < 3; ++i)
1970 unsigned int iplus1(i < 2 ? i + 1 : 0);
1974 unsigned int iedge = 0;
1975 bool add_more_edges =
true;
1976 for (
unsigned int j = 0;
j <
_edges.size(); ++
j)
1982 new_frag->
addEdge(
new EFAEdge(three_nodes[i], three_nodes[iplus1]));
1983 add_more_edges =
false;
1993 while (add_more_edges)
1996 if (iedge ==
_edges.size())
2001 add_more_edges =
false;
2006 new_fragments.push_back(new_frag);
2008 return new_fragments;
2014 std::vector<double> & para_coor)
const 2016 para_coor.resize(2, 0.0);
2021 para_coor[0] = xi_1d;
2022 para_coor[1] = -1.0;
2024 else if (edge_id == 1)
2027 para_coor[1] = xi_1d;
2029 else if (edge_id == 2)
2031 para_coor[0] = -xi_1d;
2034 else if (edge_id == 3)
2036 para_coor[0] = -1.0;
2037 para_coor[1] = -xi_1d;
2040 EFAError(
"edge_id out of bounds");
2046 para_coor[0] = 0.5 * (1.0 - xi_1d);
2047 para_coor[1] = 0.5 * (1.0 + xi_1d);
2049 else if (edge_id == 1)
2052 para_coor[1] = 0.5 * (1.0 - xi_1d);
2054 else if (edge_id == 2)
2056 para_coor[0] = 0.5 * (1.0 + xi_1d);
2060 EFAError(
"edge_id out of bounds");
2063 EFAError(
"unknown element for 2D");
2066 std::vector<EFANode *>
2069 std::set<EFANode *> e1nodes(
_nodes.begin(),
2073 return common_nodes;
virtual void printElement(std::ostream &ostream) const
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)
bool isCrackTipSplit() const
unsigned int numEdgeNeighbors(unsigned int edge_id) const
void addEdgeCut(unsigned int edge_id, double position, EFANode *embedded_node, std::map< unsigned int, EFANode *> &EmbeddedNodes, bool add_to_neighbor)
void mapParametricCoordFrom1Dto2D(unsigned int edge_id, double xi_1d, std::vector< double > ¶_coor) const
virtual void fragmentSanityCheck(unsigned int n_old_frag_edges, unsigned int n_old_frag_cuts) const
std::vector< EFANode * > getCommonNodes(const EFAElement2D *other_elem) const
bool addFragmentEdgeCut(unsigned int frag_edge_id, double position, std::map< unsigned int, EFANode *> &EmbeddedNodes)
bool edgeContainsTip(unsigned int edge_id) const
unsigned int numChildren() const
unsigned int getNewID(std::map< unsigned int, T *> &theMap)
unsigned int getCrackTipSplitElementID() const
virtual void switchEmbeddedNode(EFANode *new_node, EFANode *old_node)
bool getEdgeNodeParametricCoordinate(EFANode *node, std::vector< double > ¶_coor) const
double getIntersection(unsigned int emb_id, EFANode *from_node) const
virtual void restoreFragment(const EFAElement *const from_elem)
std::vector< EFAFragment2D * > branchingSplit(std::map< unsigned int, EFANode *> &EmbeddedNodes)
std::vector< EFAFaceNode * > _interior_nodes
virtual bool shouldDuplicateForPhantomCorner()
std::string idCatString()
virtual unsigned int numInteriorNodes() const
unsigned int getTipEdgeID() const
virtual unsigned int getNeighborIndex(const EFAElement *neighbor_elem) const
virtual void getNonPhysicalNodes(std::set< EFANode *> &non_physical_nodes) const
std::vector< std::vector< EFAElement2D * > > _edge_neighbors
unsigned int numEdges() const
EFAEdge * getEdge(unsigned int edge_id) const
EFAFaceNode * getInteriorNode(unsigned int interior_node_id) const
virtual bool isCrackTipElement() const
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)
void addEdge(EFAEdge *new_edge)
virtual bool shouldDuplicateForCrackTip(const std::set< EFAElement *> &CrackTipElements)
void setEdge(unsigned int edge_id, EFAEdge *edge)
bool fragmentEdgeAlreadyCut(unsigned int ElemEdgeID) const
std::vector< EFAEdge * > _edges
bool hasIntersection() const
bool deleteFromMap(std::map< unsigned int, T *> &theMap, T *elemToDelete, bool delete_elem=true)
bool isEdgeInterior(unsigned int edge_id) const
unsigned int numEdges() const
bool isEdgePhantom(unsigned int edge_id) const
virtual unsigned int numFragments() const
virtual void neighborSanityCheck() const
unsigned int numGeneralNeighbors() const
bool containsNode(EFANode *node) const
virtual void initCrackTip(std::set< EFAElement *> &CrackTipElements)
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
EFAElement * getChild(unsigned int child_id) const
virtual void updateFragmentNode()
std::vector< EFANode * > getCommonNodes(EFAFragment *other) const
const dof_id_type n_nodes
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)
std::vector< EFANode * > _nodes
bool getFragmentEdgeID(unsigned int elem_edge_id, unsigned int &frag_edge_id) const
virtual void updateFragments(const std::set< EFAElement *> &CrackTipElements, std::map< unsigned int, EFANode *> &EmbeddedNodes)
EFAFragment2D * getFragment(unsigned int frag_id) const
virtual bool shouldDuplicateCrackTipSplitElement(const std::set< EFAElement *> &CrackTipElements)
void setParent(EFAElement *parent)
virtual unsigned int getNumCuts() const
void findGeneralNeighbors(const std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivity)
virtual void switchNode(EFANode *new_node, EFANode *old_node, bool descend_to_parent)=0
virtual bool isFinalCut() const
bool fragmentHasTipEdges() const
virtual void removePhantomEmbeddedNode()
EFANode * getNode(unsigned int node_id) const
std::set< EFANode * > getEdgeNodes(unsigned int edge_id) const
unsigned int numCommonElems(std::set< T > &v1, std::set< T > &v2)
bool equivalent(const EFAEdge &other) const
void setInteriorNode(EFANode *node)
virtual void clearNeighbors()
EFANode * getInteriorNode() const
void setLocalCoordinates()
EFAElement * getGeneralNeighbor(unsigned int index) const
void copyIntersection(const EFAEdge &other, unsigned int from_node_id)
void setCategory(EFANode::N_CATEGORY category)
double linearQuadShape2D(unsigned int node_id, std::vector< double > &xi_2d)
void mergeNodes(EFANode *&childNode, EFANode *&childOfNeighborNode, EFAElement *childOfNeighborElem, std::map< unsigned int, EFANode *> &PermanentNodes, std::map< unsigned int, EFANode *> &TempNodes)
EFANode * getTipEmbeddedNode() const
std::vector< EFAPoint > _local_node_coor
bool hasIntersectionAtPosition(double position, EFANode *from_node) const
EFAElement2D * getEdgeNeighbor(unsigned int edge_id, unsigned int neighbor_id) const
bool overlaysElement(const EFAElement2D *other_elem) const
std::vector< T > getCommonElems(std::set< T > &v1, std::set< T > &v2)
void addNodeCut(unsigned int node_id, EFANode *embedded_permanent_node, std::map< unsigned int, EFANode *> &PermanentNodes, std::map< unsigned int, EFANode *> &EmbeddedPermanentNodes)
virtual bool willCrackTipExtend(std::vector< unsigned int > &split_neighbors) const
std::set< EFANode * > getPhantomNodeOnEdge(unsigned int edge_id) const
virtual bool isPartial() const
EFANode * createLocalNodeFromGlobalNode(const EFANode *global_node) const
virtual void getMasterInfo(EFANode *node, std::vector< EFANode *> &master_nodes, std::vector< double > &master_weights) const
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
void normalizePoint(Point &p)
unsigned int numNodes() const
unsigned int numEmbeddedNodes() const
double linearTriShape2D(unsigned int node_id, std::vector< double > &xi_2d)
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
void deleteInteriorNodes()
std::vector< EFAElement * > _general_neighbors
std::vector< EFAElement * > _children
EFAElement2D(unsigned int eid, unsigned int n_nodes)
bool _crack_tip_split_element
EFANode * getNode(unsigned int index) const
std::vector< unsigned int > _crack_tip_neighbors
static const std::string k
EFAEdge * getFragmentEdge(unsigned int frag_id, unsigned int edge_id) const
std::vector< EFAFragment2D * > _fragments
void setNode(unsigned int node_id, EFANode *node)
virtual void setupNeighbors(std::map< EFANode *, std::set< EFAElement *>> &InverseConnectivityMap)
std::vector< EFANode * > _local_nodes
N_CATEGORY category() const