21 _nodes(_num_nodes, nullptr),
22 _num_edges(_num_nodes),
23 _edges(_num_edges, nullptr),
24 _face_interior_nodes(num_interior_face_nodes, nullptr)
29 : _num_nodes(other_face._num_nodes),
30 _nodes(_num_nodes, nullptr),
31 _num_edges(_num_nodes),
32 _edges(_num_edges, nullptr)
44 : _num_nodes(frag->numEdges()),
45 _nodes(_num_nodes, nullptr),
46 _num_edges(_num_nodes),
47 _edges(_num_edges, nullptr)
52 unsigned int kprev(
k > 0 ? (
k - 1) : (frag->
numEdges() - 1));
62 for (
unsigned int i = 0; i <
_edges.size(); ++i)
107 bool is_face_node =
true;
110 if (
_nodes[i] == old_node)
113 is_face_node =
false;
124 for (
unsigned int i = 0; i <
_edges.size(); ++i)
133 std::vector<EFANode *> & master_nodes,
134 std::vector<double> & master_weights)
const 138 master_nodes.clear();
139 master_weights.clear();
140 bool masters_found =
false;
145 masters_found =
_edges[i]->getNodeMasters(node, master_nodes, master_weights);
149 EFAError(
"In getMasterInfo: cannot find master nodes in element edges");
159 std::vector<double> emb_xi(2, 0.0);
164 master_nodes.push_back(
_nodes[
j]);
171 EFAError(
"EFAface::getMasterInfo() only works for quad and tri EFAface");
172 master_weights.push_back(
weight);
174 masters_found =
true;
179 return masters_found;
186 bool edge_found =
false;
187 unsigned int edge_id;
189 EFAError(
"EFAface::getEdgeNodeParaCoor can only work for quad or tri faces");
202 double rel_dist =
_edges[edge_id]->distanceFromNode1(node);
203 double xi_1d = 2.0 * rel_dist - 1.0;
212 bool node_in_face =
false;
214 EFAError(
"EFAface::getFaceNodeParaCoor can only work for quad or tri faces");
224 xi_2d.resize(2, 0.0);
244 for (
unsigned int i = 0; i <
_edges.size(); ++i)
249 EFAError(
"in EFAface::createNodes() _edges[i] does not exist");
256 _edges[edge_id] = new_edge;
264 unsigned int i_plus1(i < (
_num_nodes - 1) ? i + 1 : 0);
271 EFAError(
"EFAface::createEdges requires exsiting _nodes");
282 unsigned int edge1_next(edge_id1 < (
_num_edges - 1) ? edge_id1 + 1 : 0);
283 if (edge1_next != edge_id2)
285 unsigned int itmp = edge_id1;
295 EFAError(
"in combine_two_edges face edges are not correctly set up");
302 _edges[edge_id1] = full_edge;
313 EFAError(
"two edges to be combined are not ajacent to each other");
319 std::vector<EFAEdge *> ordered_edges(
_num_edges,
nullptr);
320 ordered_edges[0] =
_edges[0];
323 EFAEdge * last_edge = ordered_edges[i - 1];
340 for (
unsigned int i = 0; i <
_edges.size(); ++i)
341 _edges[i]->reverseNodes();
357 return std::is_permutation(
378 unsigned int counter = 0;
379 for (
unsigned int i = 0; i < other_face->
_num_nodes; ++i)
393 for (
unsigned int i = 0; i <
_edges.size(); ++i)
405 unsigned int index = 0;
406 bool node_found =
false;
423 std::vector<EFAFace *>
426 std::vector<EFAFace *> new_faces;
431 std::vector<EFAFragment2D *> new_frags_tmp = frag_tmp->
split();
434 for (
unsigned int i = 0; i < new_frags_tmp.size(); ++i)
435 new_faces.push_back(
new EFAFace(new_frags_tmp[i]));
439 for (
unsigned int i = 0; i < new_frags_tmp.size(); ++i)
440 delete new_frags_tmp[i];
443 new_faces.push_back(
new EFAFace(*
this));
456 std::vector<EFANode *> common_nodes;
457 common_nodes.push_back(
_edges[this_common_edge_id]->
getNode(0));
458 common_nodes.push_back(
_edges[this_common_edge_id]->
getNode(1));
464 unsigned int this_edge_id0(this_common_edge_id > 0 ? this_common_edge_id - 1
466 unsigned int this_edge_id1(this_common_edge_id < (
_num_edges - 1) ? this_common_edge_id + 1
468 unsigned int other_edge_id0(
469 other_common_edge_id < (other_face->
_num_edges - 1) ? other_common_edge_id + 1 : 0);
470 unsigned int other_edge_id1(other_common_edge_id > 0 ? other_common_edge_id - 1
474 other_face->
_edges[other_edge_id0]->getNode(1));
476 -1.0, common_nodes[0], new_edge0->
getNode(0));
479 unsigned int other_iedge(other_edge_id0 < (other_face->
_num_edges - 1) ? other_edge_id0 + 1
481 while (!other_face->
_edges[other_iedge]->equivalent(*other_face->
_edges[other_edge_id1]))
490 _edges[this_edge_id1]->getNode(1));
492 -1.0, common_nodes[1], new_edge1->
getNode(0));
495 unsigned int this_iedge(this_edge_id1 < (
_num_edges - 1) ? this_edge_id1 + 1 : 0);
504 new_face =
new EFAFace(new_frag);
506 if (new_face->
numNodes() != new_n_nodes)
507 EFAError(
"combine_with() sanity check fails");
522 if (
_edges[
j]->numEmbeddedNodes() > 1)
523 EFAError(
"frag face edge can only have 1 emb node at this point");
528 double inters_x =
_edges[
j]->getIntersection(0, edge_node1);
529 if (
std::abs(inters_x + 1.0) < 1.0e-4)
531 std::vector<double> node1_xi2d(2, 0.0);
532 std::vector<double> node2_xi2d(2, 0.0);
533 std::vector<double> emb_xi2d(2, 0.0);
540 std::sqrt((emb_xi2d[0] - node1_xi2d[0]) * (emb_xi2d[0] - node1_xi2d[0]) +
541 (emb_xi2d[1] - node1_xi2d[1]) * (emb_xi2d[1] - node1_xi2d[1]));
543 std::sqrt((node2_xi2d[0] - node1_xi2d[0]) * (node2_xi2d[0] - node1_xi2d[0]) +
544 (node2_xi2d[1] - node1_xi2d[1]) * (node2_xi2d[1] - node1_xi2d[1]));
545 inters_x = dist2node1 / full_dist;
548 EFAError(
"reference face does not contain the edge with invalid inters");
549 _edges[
j]->resetIntersection(inters_x, emb_node, edge_node1);
558 unsigned int num_cuts = 0;
559 for (
unsigned int i = 0; i <
_edges.size(); ++i)
562 num_cuts +=
_edges[i]->numEmbeddedNodes();
579 for (
unsigned int i = 0; i <
_edges.size(); ++i)
580 if (from_face.
_edges[i]->hasIntersection())
591 unsigned int counter = 0;
611 EFAError(
"this face is not adjacent with other_face");
617 bool same_order =
false;
620 for (
unsigned int i = 0; i < other_face->
numNodes(); ++i)
624 unsigned int iplus1(i < (other_face->
_num_nodes - 1) ? i + 1 : 0);
631 EFAError(
"two faces overlap but can't find correct common nodes");
636 EFAWarning(
"in hasSameOrientation two faces does not overlap");
649 std::vector<double> & xi_2d)
const 652 xi_2d.resize(2, 0.0);
660 else if (edge_id == 1)
665 else if (edge_id == 2)
670 else if (edge_id == 3)
676 EFAError(
"edge_id out of bounds");
682 xi_2d[0] = 0.5 * (1.0 - xi_1d);
683 xi_2d[1] = 0.5 * (1.0 + xi_1d);
685 else if (edge_id == 1)
688 xi_2d[1] = 0.5 * (1.0 - xi_1d);
690 else if (edge_id == 2)
692 xi_2d[0] = 0.5 * (1.0 + xi_1d);
696 EFAError(
"edge_id out of bounds");
699 EFAError(
"the EFAface::mapParametricCoordsFrom1DTo2D only works for quad and tri faces");
void copyIntersection(const EFAFace &from_face)
bool isAdjacent(const EFAFace *other_face) const
bool getMasterInfo(EFANode *node, std::vector< EFANode *> &master_nodes, std::vector< double > &master_weights) const
void setEdge(unsigned int edge_id, EFAEdge *new_edge)
bool hasIntersection() const
EFAFace * combineWithFace(const EFAFace *other_face) const
bool containsNode(const EFANode *node) const
void resetEdgeIntersection(const EFAFace *ref_face)
void setInteriorFaceNode(unsigned int i, EFANode *node)
unsigned int numEdges() const
void addEdge(EFAEdge *new_edge)
bool hasSameOrientation(const EFAFace *other_face) const
void mapParametricCoordsFrom1DTo2D(unsigned int edge_id, double xi_1d, std::vector< double > &xi_2d) const
ADRealEigenVector< T, D, asd > sqrt(const ADRealEigenVector< T, D, asd > &)
std::vector< EFAFragment2D * > split()
void combineTwoEdges(unsigned int edge_id1, unsigned int edge_id2)
bool equivalent(const EFAFace *other_face) const
std::vector< EFAEdge * > _edges
EFANode * getNode(unsigned int node_id) const
unsigned int getNumCuts() const
ADRealEigenVector< T, D, asd > abs(const ADRealEigenVector< T, D, asd > &)
bool getFaceNodeParametricCoords(EFANode *node, std::vector< double > &xi_2d) const
bool getEdgeNodeParametricCoords(EFANode *node, std::vector< double > &xi_2d) const
const dof_id_type n_nodes
bool containsFace(const EFAFace *other_face) const
unsigned int numNodes() const
EFAEdge * getEdge(unsigned int edge_id) const
std::vector< EFAFace * > split() const
bool ownsEdge(const EFAEdge *other_edge) const
double linearQuadShape2D(unsigned int node_id, std::vector< double > &xi_2d)
std::vector< EFANode * > _face_interior_nodes
EFAFaceNode * getInteriorNode(unsigned int index) const
bool containsNode(const EFANode *node) const
std::vector< EFAFaceNode * > _interior_nodes
void switchNode(EFANode *new_node, EFANode *old_node)
void removeEmbeddedNode(EFANode *emb_node)
unsigned int numInteriorNodes() const
std::vector< EFANode * > _nodes
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
double linearTriShape2D(unsigned int node_id, std::vector< double > &xi_2d)
void addIntersection(double position, EFANode *embedded_node_tmp, EFANode *from_node)
EFAEdge * getEdge(unsigned int edge_id) const
unsigned int adjacentCommonEdge(const EFAFace *other_face) const
void setNode(unsigned int node_id, EFANode *node)
EFAFace(unsigned int n_nodes, unsigned int num_interior_face_nodes=0)
EFANode * getNode(unsigned int index) const
static const std::string k