LCOV - code coverage report
Current view: top level - src/efa - EFAFace.C (source / functions) Hit Total Coverage
Test: idaholab/moose xfem: #31405 (292dce) with base fef103 Lines: 279 337 82.8 %
Date: 2025-09-04 07:58:55 Functions: 34 36 94.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       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 "EFAFace.h"
      11             : 
      12             : #include "EFAFaceNode.h"
      13             : #include "EFANode.h"
      14             : #include "EFAEdge.h"
      15             : #include "EFAFragment2D.h"
      16             : #include "EFAFuncs.h"
      17             : #include "EFAError.h"
      18             : 
      19      220532 : EFAFace::EFAFace(unsigned int n_nodes, unsigned int num_interior_face_nodes)
      20      220532 :   : _num_nodes(n_nodes),
      21      220532 :     _nodes(_num_nodes, nullptr),
      22      220532 :     _num_edges(_num_nodes),
      23      220532 :     _edges(_num_edges, nullptr),
      24      220532 :     _face_interior_nodes(num_interior_face_nodes, nullptr)
      25             : {
      26      220532 : }
      27             : 
      28      191894 : EFAFace::EFAFace(const EFAFace & other_face)
      29      191894 :   : _num_nodes(other_face._num_nodes),
      30      191894 :     _nodes(_num_nodes, nullptr),
      31      191894 :     _num_edges(_num_nodes),
      32      191894 :     _edges(_num_edges, nullptr)
      33             : {
      34      891580 :   for (unsigned int k = 0; k < other_face._num_nodes; ++k)
      35             :   {
      36      699686 :     _nodes[k] = other_face._nodes[k];
      37      699686 :     _edges[k] = new EFAEdge(*other_face._edges[k]);
      38             :   }
      39      191894 :   for (unsigned int k = 0; k < other_face._interior_nodes.size(); ++k)
      40           0 :     _interior_nodes.push_back(new EFAFaceNode(*other_face._interior_nodes[k]));
      41      191894 : }
      42             : 
      43       10840 : EFAFace::EFAFace(const EFAFragment2D * frag)
      44       10840 :   : _num_nodes(frag->numEdges()),
      45       10840 :     _nodes(_num_nodes, nullptr),
      46       10840 :     _num_edges(_num_nodes),
      47       10840 :     _edges(_num_edges, nullptr)
      48             : {
      49       52610 :   for (unsigned int k = 0; k < frag->numEdges(); ++k)
      50             :   {
      51       41770 :     EFANode * node = frag->getEdge(k)->getNode(0);
      52       41770 :     unsigned int kprev(k > 0 ? (k - 1) : (frag->numEdges() - 1));
      53       41770 :     if (!frag->getEdge(kprev)->containsNode(node))
      54           0 :       node = getEdge(k)->getNode(1);
      55       41770 :     _nodes[k] = node;
      56       41770 :     _edges[k] = new EFAEdge(*frag->getEdge(k));
      57             :   }
      58       10840 : }
      59             : 
      60      423266 : EFAFace::~EFAFace()
      61             : {
      62     1959926 :   for (unsigned int i = 0; i < _edges.size(); ++i)
      63             :   {
      64     1536660 :     if (_edges[i])
      65             :     {
      66     1536660 :       delete _edges[i];
      67     1536660 :       _edges[i] = nullptr;
      68             :     }
      69             :   }
      70      423266 :   for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
      71             :   {
      72           0 :     if (_interior_nodes[i])
      73             :     {
      74           0 :       delete _interior_nodes[i];
      75           0 :       _interior_nodes[i] = nullptr;
      76             :     }
      77             :   }
      78      423266 : }
      79             : 
      80             : void
      81      320104 : EFAFace::setInteriorFaceNode(unsigned int i, EFANode * node)
      82             : {
      83      320104 :   _face_interior_nodes[i] = node;
      84      320104 : }
      85             : 
      86             : unsigned int
      87     7568787 : EFAFace::numNodes() const
      88             : {
      89     7568787 :   return _nodes.size();
      90             : }
      91             : 
      92             : void
      93      786960 : EFAFace::setNode(unsigned int node_id, EFANode * node)
      94             : {
      95      786960 :   _nodes[node_id] = node;
      96      786960 : }
      97             : 
      98             : EFANode *
      99     5501172 : EFAFace::getNode(unsigned int node_id) const
     100             : {
     101     5501172 :   return _nodes[node_id];
     102             : }
     103             : 
     104             : void
     105     6412455 : EFAFace::switchNode(EFANode * new_node, EFANode * old_node)
     106             : {
     107             :   bool is_face_node = true;
     108    27881741 :   for (unsigned int i = 0; i < _num_nodes; ++i)
     109             :   {
     110    21469286 :     if (_nodes[i] == old_node)
     111             :     {
     112      153543 :       _nodes[i] = new_node;
     113             :       is_face_node = false;
     114             :     }
     115             :   }
     116     6412455 :   if (is_face_node)
     117             :   {
     118    16994216 :     for (unsigned int i = 0; i < _face_interior_nodes.size(); ++i)
     119    10735304 :       if (_face_interior_nodes[i] == old_node)
     120        9664 :         _face_interior_nodes[i] = new_node;
     121             :   }
     122             :   else
     123             :   {
     124      737171 :     for (unsigned int i = 0; i < _edges.size(); ++i)
     125      583628 :       _edges[i]->switchNode(new_node, old_node);
     126      153543 :     for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
     127           0 :       _interior_nodes[i]->switchNode(new_node, old_node);
     128             :   }
     129     6412455 : }
     130             : 
     131             : bool
     132     2611614 : EFAFace::getMasterInfo(EFANode * node,
     133             :                        std::vector<EFANode *> & master_nodes,
     134             :                        std::vector<double> & master_weights) const
     135             : {
     136             :   // Given a EFAnode, find the element edge or fragment edge that contains it
     137             :   // Return its master nodes and weights
     138     2611614 :   master_nodes.clear();
     139     2611614 :   master_weights.clear();
     140             :   bool masters_found = false;
     141     6329864 :   for (unsigned int i = 0; i < _num_edges; ++i) // check element exterior edges
     142             :   {
     143     6329864 :     if (_edges[i]->containsNode(node))
     144             :     {
     145     2611614 :       masters_found = _edges[i]->getNodeMasters(node, master_nodes, master_weights);
     146     2611614 :       if (masters_found)
     147             :         break;
     148             :       else
     149           0 :         EFAError("In getMasterInfo: cannot find master nodes in element edges");
     150             :     }
     151             :   }
     152             : 
     153             :   if (!masters_found) // check element interior embedded nodes
     154             :   {
     155           0 :     for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
     156             :     {
     157           0 :       if (_interior_nodes[i]->getNode() == node)
     158             :       {
     159           0 :         std::vector<double> emb_xi(2, 0.0);
     160           0 :         emb_xi[0] = _interior_nodes[i]->getParametricCoordinates(0);
     161           0 :         emb_xi[1] = _interior_nodes[i]->getParametricCoordinates(1);
     162           0 :         for (unsigned int j = 0; j < _num_nodes; ++j)
     163             :         {
     164           0 :           master_nodes.push_back(_nodes[j]);
     165           0 :           double weight = 0.0;
     166           0 :           if (_num_nodes == 4)
     167           0 :             weight = Efa::linearQuadShape2D(j, emb_xi);
     168           0 :           else if (_num_nodes == 3)
     169           0 :             weight = Efa::linearTriShape2D(j, emb_xi);
     170             :           else
     171           0 :             EFAError("EFAface::getMasterInfo() only works for quad and tri EFAface");
     172           0 :           master_weights.push_back(weight);
     173             :         }
     174             :         masters_found = true;
     175             :         break;
     176           0 :       }
     177             :     }
     178             :   }
     179     2611614 :   return masters_found;
     180             : }
     181             : 
     182             : bool
     183        3108 : EFAFace::getEdgeNodeParametricCoords(EFANode * node, std::vector<double> & xi_2d) const
     184             : {
     185             :   // get the parametric coords of a node in an edge
     186             :   bool edge_found = false;
     187             :   unsigned int edge_id;
     188        3108 :   if (!isTriOrQuad())
     189           0 :     EFAError("EFAface::getEdgeNodeParaCoor can only work for quad or tri faces");
     190             : 
     191        5586 :   for (unsigned int i = 0; i < _num_edges; ++i)
     192             :   {
     193        5586 :     if (_edges[i]->containsNode(node))
     194             :     {
     195             :       edge_id = i;
     196             :       edge_found = true;
     197             :       break;
     198             :     }
     199             :   }
     200        3108 :   if (edge_found)
     201             :   {
     202        3108 :     double rel_dist = _edges[edge_id]->distanceFromNode1(node);
     203        3108 :     double xi_1d = 2.0 * rel_dist - 1.0; // translate to [-1,1] parent coord syst
     204        3108 :     mapParametricCoordsFrom1DTo2D(edge_id, xi_1d, xi_2d);
     205             :   }
     206        3108 :   return edge_found;
     207             : }
     208             : 
     209             : bool
     210        3108 : EFAFace::getFaceNodeParametricCoords(EFANode * node, std::vector<double> & xi_2d) const
     211             : {
     212             :   bool node_in_face = false;
     213        3108 :   if (!isTriOrQuad())
     214           0 :     EFAError("EFAface::getFaceNodeParaCoor can only work for quad or tri faces");
     215             : 
     216        3108 :   if (getEdgeNodeParametricCoords(node, xi_2d))
     217             :     node_in_face = true;
     218             :   else
     219             :   {
     220           0 :     for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
     221             :     {
     222           0 :       if (_interior_nodes[i]->getNode() == node)
     223             :       {
     224           0 :         xi_2d.resize(2, 0.0);
     225           0 :         xi_2d[0] = _interior_nodes[i]->getParametricCoordinates(0);
     226           0 :         xi_2d[1] = _interior_nodes[i]->getParametricCoordinates(1);
     227             :         node_in_face = true;
     228           0 :         break;
     229             :       }
     230             :     } // i
     231             :   }
     232        3108 :   return node_in_face;
     233             : }
     234             : 
     235             : unsigned int
     236       57532 : EFAFace::numInteriorNodes() const
     237             : {
     238       57532 :   return _interior_nodes.size();
     239             : }
     240             : 
     241             : void
     242        2424 : EFAFace::createNodes()
     243             : {
     244       11176 :   for (unsigned int i = 0; i < _edges.size(); ++i)
     245             :   {
     246        8752 :     if (_edges[i] != nullptr)
     247        8752 :       _nodes[i] = _edges[i]->getNode(0);
     248             :     else
     249           0 :       EFAError("in EFAface::createNodes() _edges[i] does not exist");
     250             :   }
     251        2424 : }
     252             : 
     253             : void
     254        8752 : EFAFace::setEdge(unsigned int edge_id, EFAEdge * new_edge)
     255             : {
     256        8752 :   _edges[edge_id] = new_edge;
     257        8752 : }
     258             : 
     259             : void
     260      218108 : EFAFace::createEdges()
     261             : {
     262     1005068 :   for (unsigned int i = 0; i < _num_nodes; ++i)
     263             :   {
     264      786960 :     unsigned int i_plus1(i < (_num_nodes - 1) ? i + 1 : 0);
     265      786960 :     if (_nodes[i] != nullptr && _nodes[i_plus1] != nullptr)
     266             :     {
     267      786960 :       EFAEdge * new_edge = new EFAEdge(_nodes[i], _nodes[i_plus1]);
     268      786960 :       _edges[i] = new_edge;
     269             :     }
     270             :     else
     271           0 :       EFAError("EFAface::createEdges requires exsiting _nodes");
     272             :   }
     273      218108 : }
     274             : 
     275             : void
     276         508 : EFAFace::combineTwoEdges(unsigned int edge_id1, unsigned int edge_id2)
     277             : {
     278         762 :   if (_edges[edge_id1]->containsNode(_edges[edge_id2]->getNode(0)) ||
     279         254 :       _edges[edge_id1]->containsNode(_edges[edge_id2]->getNode(1)))
     280             :   {
     281             :     // edge_id1 must precede edge_id2
     282         508 :     unsigned int edge1_next(edge_id1 < (_num_edges - 1) ? edge_id1 + 1 : 0);
     283         508 :     if (edge1_next != edge_id2) // if not, swap
     284             :     {
     285             :       unsigned int itmp = edge_id1;
     286             :       edge_id1 = edge_id2;
     287             :       edge_id2 = itmp;
     288             :     }
     289             : 
     290             :     // build new edge and delete old ones
     291         508 :     EFANode * new_node1 = _edges[edge_id1]->getNode(0);
     292         508 :     EFANode * emb_node = _edges[edge_id1]->getNode(1);
     293         508 :     EFANode * new_node2 = _edges[edge_id2]->getNode(1);
     294         508 :     if (emb_node != _edges[edge_id2]->getNode(0))
     295           0 :       EFAError("in combine_two_edges face edges are not correctly set up");
     296             : 
     297         508 :     EFAEdge * full_edge = new EFAEdge(new_node1, new_node2);
     298         508 :     full_edge->addIntersection(-1.0, emb_node, new_node1); // dummy intersection_x
     299             : 
     300         508 :     delete _edges[edge_id1];
     301         508 :     delete _edges[edge_id2];
     302         508 :     _edges[edge_id1] = full_edge;
     303         508 :     _edges.erase(_edges.begin() + edge_id2);
     304             : 
     305             :     // update face memeber variables
     306         508 :     _num_edges -= 1;
     307         508 :     _num_nodes -= 1;
     308         508 :     _nodes.resize(_num_nodes, nullptr);
     309        2380 :     for (unsigned int k = 0; k < _num_edges; ++k)
     310        1872 :       _nodes[k] = _edges[k]->getNode(0);
     311             :   }
     312             :   else
     313           0 :     EFAError("two edges to be combined are not ajacent to each other");
     314         508 : }
     315             : 
     316             : void
     317        2424 : EFAFace::sortEdges()
     318             : {
     319        2424 :   std::vector<EFAEdge *> ordered_edges(_num_edges, nullptr);
     320        2424 :   ordered_edges[0] = _edges[0];
     321        8752 :   for (unsigned int i = 1; i < _num_edges; ++i)
     322             :   {
     323        6328 :     EFAEdge * last_edge = ordered_edges[i - 1];
     324       18082 :     for (unsigned int j = 0; j < _num_edges; ++j)
     325             :     {
     326       18082 :       if (!_edges[j]->equivalent(*last_edge) && _edges[j]->containsNode(last_edge->getNode(1)))
     327             :       {
     328        6328 :         ordered_edges[i] = _edges[j];
     329        6328 :         break;
     330             :       }
     331             :     } // j
     332             :   }   // i
     333        2424 :   _edges = ordered_edges;
     334        2424 : }
     335             : 
     336             : void
     337        2424 : EFAFace::reverseEdges()
     338             : {
     339             :   // reverse the orientation of the face
     340       11176 :   for (unsigned int i = 0; i < _edges.size(); ++i)
     341        8752 :     _edges[i]->reverseNodes();
     342        2424 :   std::reverse(_edges.begin(), _edges.end());
     343        2424 : }
     344             : 
     345             : bool
     346        6216 : EFAFace::isTriOrQuad() const
     347             : {
     348        6216 :   if (_num_edges == 3 || _num_edges == 4)
     349             :     return true;
     350             :   else
     351           0 :     return false;
     352             : }
     353             : 
     354             : bool
     355    41757617 : EFAFace::equivalent(const EFAFace * other_face) const
     356             : {
     357    41757617 :   return std::is_permutation(
     358    41757617 :       _nodes.begin(), _nodes.end(), other_face->_nodes.begin(), other_face->_nodes.end());
     359             : }
     360             : 
     361             : bool
     362    76265468 : EFAFace::containsNode(const EFANode * node) const
     363             : {
     364   259608770 :   for (unsigned int i = 0; i < _num_edges; ++i)
     365   220520462 :     if (_edges[i]->containsNode(node))
     366             :       return true;
     367             : 
     368    39088308 :   for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
     369           0 :     if (_interior_nodes[i]->getNode() == node)
     370             :       return true;
     371             : 
     372             :   return false;
     373             : }
     374             : 
     375             : bool
     376    17051396 : EFAFace::containsFace(const EFAFace * other_face) const
     377             : {
     378             :   unsigned int counter = 0;
     379    81695276 :   for (unsigned int i = 0; i < other_face->_num_nodes; ++i)
     380             :   {
     381    64643880 :     if (containsNode(other_face->_nodes[i]))
     382    33306232 :       counter += 1;
     383             :   }
     384    17051396 :   if (counter == other_face->_num_nodes)
     385             :     return true;
     386             :   else
     387    13094775 :     return false;
     388             : }
     389             : 
     390             : bool
     391    17089834 : EFAFace::ownsEdge(const EFAEdge * other_edge) const
     392             : {
     393    69756453 :   for (unsigned int i = 0; i < _edges.size(); ++i)
     394    57593161 :     if (_edges[i]->equivalent(*other_edge))
     395             :       return true;
     396             :   return false;
     397             : }
     398             : 
     399             : void
     400           0 : EFAFace::removeEmbeddedNode(EFANode * emb_node)
     401             : {
     402           0 :   for (unsigned int i = 0; i < _num_edges; ++i)
     403           0 :     _edges[i]->removeEmbeddedNode(emb_node);
     404             : 
     405             :   unsigned int index = 0;
     406             :   bool node_found = false;
     407           0 :   for (unsigned int i = 0; i < _interior_nodes.size(); ++i)
     408             :   {
     409           0 :     if (_interior_nodes[i]->getNode() == emb_node)
     410             :     {
     411             :       node_found = true;
     412             :       index = i;
     413             :       break;
     414             :     }
     415             :   }
     416           0 :   if (node_found)
     417             :   {
     418           0 :     delete _interior_nodes[index];
     419           0 :     _interior_nodes.erase(_interior_nodes.begin() + index);
     420             :   }
     421           0 : }
     422             : 
     423             : std::vector<EFAFace *>
     424        8438 : EFAFace::split() const
     425             : {
     426             :   std::vector<EFAFace *> new_faces;
     427        8438 :   if (getNumCuts() > 0)
     428             :   {
     429             :     // construct a fragment from this face
     430        5733 :     EFAFragment2D * frag_tmp = new EFAFragment2D(nullptr, this);
     431        5733 :     std::vector<EFAFragment2D *> new_frags_tmp = frag_tmp->split();
     432             : 
     433             :     // copy new_frags to new_faces
     434       16309 :     for (unsigned int i = 0; i < new_frags_tmp.size(); ++i)
     435       10576 :       new_faces.push_back(new EFAFace(new_frags_tmp[i]));
     436             : 
     437             :     // delete frag_tmp and new_frags
     438        5733 :     delete frag_tmp;
     439       16309 :     for (unsigned int i = 0; i < new_frags_tmp.size(); ++i)
     440       10576 :       delete new_frags_tmp[i];
     441        5733 :   }
     442             :   else
     443        2705 :     new_faces.push_back(new EFAFace(*this));
     444             : 
     445        8438 :   return new_faces;
     446           0 : }
     447             : 
     448             : EFAFace *
     449         264 : EFAFace::combineWithFace(const EFAFace * other_face) const
     450             : {
     451             :   // combine this face with another adjacent face
     452             :   EFAFace * new_face = nullptr;
     453         264 :   if (isAdjacent(other_face))
     454             :   {
     455         264 :     unsigned int this_common_edge_id = adjacentCommonEdge(other_face);
     456             :     std::vector<EFANode *> common_nodes;
     457         264 :     common_nodes.push_back(_edges[this_common_edge_id]->getNode(0));
     458         264 :     common_nodes.push_back(_edges[this_common_edge_id]->getNode(1));
     459             : 
     460         264 :     unsigned int other_common_edge_id = other_face->adjacentCommonEdge(this);
     461         264 :     unsigned int new_n_nodes = _num_edges + other_face->_num_edges - 4;
     462         264 :     EFAFragment2D * new_frag = new EFAFragment2D(nullptr, false, nullptr); // temp fragment
     463             : 
     464         264 :     unsigned int this_edge_id0(this_common_edge_id > 0 ? this_common_edge_id - 1
     465           0 :                                                        : _num_edges - 1); // common_nodes[0]
     466         264 :     unsigned int this_edge_id1(this_common_edge_id < (_num_edges - 1) ? this_common_edge_id + 1
     467             :                                                                       : 0); // common_nodes[1]
     468             :     unsigned int other_edge_id0(
     469         264 :         other_common_edge_id < (other_face->_num_edges - 1) ? other_common_edge_id + 1 : 0);
     470         264 :     unsigned int other_edge_id1(other_common_edge_id > 0 ? other_common_edge_id - 1
     471             :                                                          : other_face->_num_edges - 1);
     472             : 
     473         264 :     EFAEdge * new_edge0 = new EFAEdge(_edges[this_edge_id0]->getNode(0),
     474         264 :                                       other_face->_edges[other_edge_id0]->getNode(1));
     475         264 :     new_edge0->addIntersection(
     476             :         -1.0, common_nodes[0], new_edge0->getNode(0)); // dummy intersection_x
     477         264 :     new_frag->addEdge(new_edge0);                      // common_nodes[0]'s edge
     478             : 
     479         264 :     unsigned int other_iedge(other_edge_id0 < (other_face->_num_edges - 1) ? other_edge_id0 + 1
     480             :                                                                            : 0);
     481         468 :     while (!other_face->_edges[other_iedge]->equivalent(*other_face->_edges[other_edge_id1]))
     482             :     {
     483         204 :       new_frag->addEdge(new EFAEdge(*other_face->_edges[other_iedge]));
     484         204 :       other_iedge += 1;
     485         204 :       if (other_iedge == other_face->_num_edges)
     486             :         other_iedge = 0;
     487             :     } // loop over other_face's edges
     488             : 
     489             :     EFAEdge * new_edge1 = new EFAEdge(other_face->_edges[other_edge_id1]->getNode(0),
     490         264 :                                       _edges[this_edge_id1]->getNode(1));
     491         264 :     new_edge1->addIntersection(
     492             :         -1.0, common_nodes[1], new_edge1->getNode(0)); // dummy intersection_x
     493         264 :     new_frag->addEdge(new_edge1);
     494             : 
     495         264 :     unsigned int this_iedge(this_edge_id1 < (_num_edges - 1) ? this_edge_id1 + 1 : 0);
     496         508 :     while (!_edges[this_iedge]->equivalent(*_edges[this_edge_id0])) // common_nodes[1]'s edge
     497             :     {
     498         244 :       new_frag->addEdge(new EFAEdge(*_edges[this_iedge]));
     499         244 :       this_iedge += 1;
     500         244 :       if (this_iedge == _num_edges)
     501             :         this_iedge = 0;
     502             :     } // loop over this_face's edges
     503             : 
     504         264 :     new_face = new EFAFace(new_frag);
     505         264 :     delete new_frag;
     506         264 :     if (new_face->numNodes() != new_n_nodes)
     507           0 :       EFAError("combine_with() sanity check fails");
     508         264 :   }
     509         264 :   return new_face;
     510             : }
     511             : 
     512             : void
     513         772 : EFAFace::resetEdgeIntersection(const EFAFace * ref_face)
     514             : {
     515             :   // set up correct edge intersections based on the reference face
     516             :   // the reference face must contain the edge of this face that is to be set up
     517             :   // the reference face must be an element face
     518        3620 :   for (unsigned int j = 0; j < _num_edges; ++j)
     519             :   {
     520        2848 :     if (_edges[j]->hasIntersection())
     521             :     {
     522        1100 :       if (_edges[j]->numEmbeddedNodes() > 1)
     523           0 :         EFAError("frag face edge can only have 1 emb node at this point");
     524             : 
     525        1100 :       EFANode * edge_node1 = _edges[j]->getNode(0);
     526        1100 :       EFANode * edge_node2 = _edges[j]->getNode(1);
     527        1100 :       EFANode * emb_node = _edges[j]->getEmbeddedNode(0);
     528        1100 :       double inters_x = _edges[j]->getIntersection(0, edge_node1);
     529        1100 :       if (std::abs(inters_x + 1.0) < 1.0e-4) // invalid intersection found
     530             :       {
     531        1036 :         std::vector<double> node1_xi2d(2, 0.0);
     532        1036 :         std::vector<double> node2_xi2d(2, 0.0);
     533        1036 :         std::vector<double> emb_xi2d(2, 0.0);
     534        2072 :         if (ref_face->getFaceNodeParametricCoords(edge_node1, node1_xi2d) &&
     535        2072 :             ref_face->getFaceNodeParametricCoords(edge_node2, node2_xi2d) &&
     536        1036 :             ref_face->getFaceNodeParametricCoords(emb_node, emb_xi2d))
     537             :         {
     538             :           // TODO: this is not correct for unstructured elements. Need a fix
     539             :           double dist2node1 =
     540        1036 :               std::sqrt((emb_xi2d[0] - node1_xi2d[0]) * (emb_xi2d[0] - node1_xi2d[0]) +
     541        1036 :                         (emb_xi2d[1] - node1_xi2d[1]) * (emb_xi2d[1] - node1_xi2d[1]));
     542             :           double full_dist =
     543        1036 :               std::sqrt((node2_xi2d[0] - node1_xi2d[0]) * (node2_xi2d[0] - node1_xi2d[0]) +
     544        1036 :                         (node2_xi2d[1] - node1_xi2d[1]) * (node2_xi2d[1] - node1_xi2d[1]));
     545        1036 :           inters_x = dist2node1 / full_dist;
     546             :         }
     547             :         else
     548           0 :           EFAError("reference face does not contain the edge with invalid inters");
     549        1036 :         _edges[j]->resetIntersection(inters_x, emb_node, edge_node1);
     550        1036 :       }
     551             :     }
     552             :   }
     553         772 : }
     554             : 
     555             : unsigned int
     556      283721 : EFAFace::getNumCuts() const
     557             : {
     558             :   unsigned int num_cuts = 0;
     559     1312917 :   for (unsigned int i = 0; i < _edges.size(); ++i)
     560             :   {
     561     1029196 :     if (_edges[i]->hasIntersection())
     562      144157 :       num_cuts += _edges[i]->numEmbeddedNodes();
     563             :   }
     564      283721 :   return num_cuts;
     565             : }
     566             : 
     567             : bool
     568      251467 : EFAFace::hasIntersection() const
     569             : {
     570      251467 :   if (getNumCuts() > 1)
     571             :     return true;
     572             :   else
     573      192185 :     return false;
     574             : }
     575             : 
     576             : void
     577       43826 : EFAFace::copyIntersection(const EFAFace & from_face)
     578             : {
     579      202490 :   for (unsigned int i = 0; i < _edges.size(); ++i)
     580      158664 :     if (from_face._edges[i]->hasIntersection())
     581       60840 :       _edges[i]->copyIntersection(*from_face._edges[i], 0);
     582             : 
     583       43826 :   if (from_face.numInteriorNodes() > 0)
     584           0 :     _interior_nodes = from_face._interior_nodes;
     585       43826 : }
     586             : 
     587             : bool
     588     3546708 : EFAFace::isAdjacent(const EFAFace * other_face) const
     589             : {
     590             :   // two faces are adjacent if they only share one common edge
     591             :   unsigned int counter = 0;
     592    16729274 :   for (unsigned int i = 0; i < _num_edges; ++i)
     593    13182566 :     if (other_face->ownsEdge(_edges[i]))
     594     3253473 :       counter += 1;
     595             : 
     596     3546708 :   if (counter == 1)
     597             :     return true;
     598             :   else
     599      293235 :     return false;
     600             : }
     601             : 
     602             : unsigned int
     603     1673069 : EFAFace::adjacentCommonEdge(const EFAFace * other_face) const
     604             : {
     605     1673069 :   if (isAdjacent(other_face))
     606             :   {
     607     3907268 :     for (unsigned int i = 0; i < _num_edges; ++i)
     608     3907268 :       if (other_face->ownsEdge(_edges[i]))
     609     1673069 :         return i;
     610             :   }
     611           0 :   EFAError("this face is not adjacent with other_face");
     612             : }
     613             : 
     614             : bool
     615      158940 : EFAFace::hasSameOrientation(const EFAFace * other_face) const
     616             : {
     617             :   bool same_order = false;
     618      158940 :   if (equivalent(other_face))
     619             :   {
     620      718480 :     for (unsigned int i = 0; i < other_face->numNodes(); ++i)
     621             :     {
     622      560308 :       if (other_face->_nodes[i] == _nodes[0])
     623             :       {
     624      158940 :         unsigned int iplus1(i < (other_face->_num_nodes - 1) ? i + 1 : 0);
     625      158940 :         if (other_face->_nodes[iplus1] == _nodes[1])
     626             :         {
     627             :           same_order = true;
     628             :           break;
     629             :         }
     630      158172 :         else if (other_face->_nodes[iplus1] != _nodes[_num_nodes - 1])
     631           0 :           EFAError("two faces overlap but can't find correct common nodes");
     632             :       }
     633             :     }
     634             :   }
     635             :   else
     636             :     EFAWarning("in hasSameOrientation two faces does not overlap");
     637      158940 :   return same_order;
     638             : }
     639             : 
     640             : EFAFaceNode *
     641           0 : EFAFace::getInteriorNode(unsigned int index) const
     642             : {
     643           0 :   return _interior_nodes[index];
     644             : }
     645             : 
     646             : void
     647        3108 : EFAFace::mapParametricCoordsFrom1DTo2D(unsigned int edge_id,
     648             :                                        double xi_1d,
     649             :                                        std::vector<double> & xi_2d) const
     650             : {
     651             :   // given the 1D parent coord of a point in an 2D element edge, translate it to 2D para coords
     652        3108 :   xi_2d.resize(2, 0.0);
     653        3108 :   if (_num_edges == 4)
     654             :   {
     655        2148 :     if (edge_id == 0)
     656             :     {
     657        1020 :       xi_2d[0] = xi_1d;
     658        1020 :       xi_2d[1] = -1.0;
     659             :     }
     660        1128 :     else if (edge_id == 1)
     661             :     {
     662         412 :       xi_2d[0] = 1.0;
     663         412 :       xi_2d[1] = xi_1d;
     664             :     }
     665         716 :     else if (edge_id == 2)
     666             :     {
     667         682 :       xi_2d[0] = -xi_1d;
     668         682 :       xi_2d[1] = 1.0;
     669             :     }
     670          34 :     else if (edge_id == 3)
     671             :     {
     672          34 :       xi_2d[0] = -1.0;
     673          34 :       xi_2d[1] = -xi_1d;
     674             :     }
     675             :     else
     676           0 :       EFAError("edge_id out of bounds");
     677             :   }
     678         960 :   else if (_num_edges == 3)
     679             :   {
     680         960 :     if (edge_id == 0)
     681             :     {
     682         480 :       xi_2d[0] = 0.5 * (1.0 - xi_1d);
     683         480 :       xi_2d[1] = 0.5 * (1.0 + xi_1d);
     684             :     }
     685         480 :     else if (edge_id == 1)
     686             :     {
     687         360 :       xi_2d[0] = 0.0;
     688         360 :       xi_2d[1] = 0.5 * (1.0 - xi_1d);
     689             :     }
     690         120 :     else if (edge_id == 2)
     691             :     {
     692         120 :       xi_2d[0] = 0.5 * (1.0 + xi_1d);
     693         120 :       xi_2d[1] = 0.0;
     694             :     }
     695             :     else
     696           0 :       EFAError("edge_id out of bounds");
     697             :   }
     698             :   else
     699           0 :     EFAError("the EFAface::mapParametricCoordsFrom1DTo2D only works for quad and tri faces");
     700        3108 : }

Generated by: LCOV version 1.14