43 namespace NekMeshUtils
    46 bool FaceMesh::ValidateCurves()
    48     vector<int> curvesInSurface;
    49     for (
int i = 0; i < m_edgeloops.size(); i++)
    51         for (
int j = 0; j < m_edgeloops[i]->edges.size(); j++)
    53             curvesInSurface.push_back(m_edgeloops[i]->edges[j]->GetId());
    59     for (
int i = 0; i < curvesInSurface.size(); i++)
    61         vector<EdgeSharedPtr> es =
    62             m_curvemeshes[curvesInSurface[i]]->GetMeshEdges();
    64         for (
int j = i; j < curvesInSurface.size(); j++)
    71             vector<EdgeSharedPtr> es2 =
    72                 m_curvemeshes[curvesInSurface[j]]->GetMeshEdges();
    74             for (
int l = 0; l < es.size(); l++)
    78                 for (
int k = 0; k < es2.size(); k++)
    80                     if (es[l]->m_n1 == es2[k]->m_n1 ||
    81                         es[l]->m_n1 == es2[k]->m_n2 ||
    82                         es[l]->m_n2 == es2[k]->m_n1 ||
    83                         es[l]->m_n2 == es2[k]->m_n2)
    89                         es2[k]->m_n1->GetCADSurfInfo(m_id);
    91                         es2[k]->m_n2->GetCADSurfInfo(m_id);
    93                     NekDouble den = (P4[0] - P3[0]) * (P2[1] - P1[1]) -
    94                                     (P2[0] - P1[0]) * (P4[1] - P3[1]);
   101                     NekDouble t = ((P1[0] - P3[0]) * (P4[1] - P3[1]) -
   102                                    (P4[0] - P3[0]) * (P1[1] - P3[1])) /
   105                         (P1[0] - P3[0] + t * (P2[0] - P1[0])) / (P4[0] - P3[0]);
   107                     if (t < 1.0 && t > 0.0 && u < 1.0 && u > 0.0)
   110                         uv[0] = P1[0] + t * (P2[0] - P1[0]);
   111                         uv[1] = P1[1] + t * (P2[1] - P1[1]);
   114                              << 
"Curve mesh error at " << loc[0] << 
" "   115                              << loc[1] << 
" " << loc[2] << 
" on face " << m_id
   126 void FaceMesh::ValidateLoops()
   130     for (
int i = 0; i < orderedLoops.size(); i++)
   132         int numPoints = orderedLoops[i].size();
   136             for(
int j = 0; j < m_edgeloops[i]->edges.size(); j++)
   138                 int cid = m_edgeloops[i]->edges[j]->GetId();
   139                 m_curvemeshes[cid]->ReMesh();
   151     for (
int i = 0; i < orderedLoops.size(); i++)
   153         numPoints += orderedLoops[i].size();
   154         for (
int j = 0; j < orderedLoops[i].size(); j++)
   156             m_inBoundary.insert(orderedLoops[i][j]);
   161     ss << 
"3 points required for triangulation, " << numPoints << 
" in loop"   164     for (
int i = 0; i < m_edgeloops.size(); i++)
   166         for (
int j = 0; j < m_edgeloops[i]->edges.size(); j++)
   168             ss << m_edgeloops[i]->edges[j]->GetId() << 
" ";
   172     ASSERTL0(numPoints > 2, 
"number of verts in face is less than 3");
   178     vector<Array<OneD, NekDouble> > centers;
   179     for (
int i = 0; i < m_edgeloops.size(); i++)
   181         centers.push_back(m_edgeloops[i]->center);
   184     pplanemesh->Assign(orderedLoops, centers, m_id, m_str);
   188     pplanemesh->Extract(m_connec);
   203         pplanemesh->AssignStiener(m_stienerpoints);
   205         pplanemesh->Extract(m_connec);
   218     for (
int i = 0; i < m_localElements.size(); i++)
   220         vector<EdgeSharedPtr> e = m_localElements[i]->GetEdgeList();
   221         for (
int j = 0; j < e.size(); j++)
   223             e[j]->m_elLink.clear();
   225         m_mesh->m_element[2].push_back(m_localElements[i]);
   228     if (m_mesh->m_verbose)
   233         cout << scientific << 
"\r\t\tFace " << m_id << endl
   234              << 
"\t\t\tNodes: " << m_localNodes.size() << endl
   235              << 
"\t\t\tEdges: " << m_localEdges.size() << endl
   236              << 
"\t\t\tTriangles: " << m_localElements.size() << endl
   237              << 
"\t\t\tLoops: " << m_edgeloops.size() << endl
   238              << 
"\t\t\tSTR: " << m_str << endl
   243 void FaceMesh::OptimiseLocalMesh()
   255 void FaceMesh::Smoothing()
   257     EdgeSet::iterator eit;
   258     NodeSet::iterator nit;
   262     map<int, vector<EdgeSharedPtr> > connectingedges;
   264     map<int, vector<ElementSharedPtr> > connectingelements;
   266     for (eit = m_localEdges.begin(); eit != m_localEdges.end(); eit++)
   268         connectingedges[(*eit)->m_n1->m_id].push_back(*eit);
   269         connectingedges[(*eit)->m_n2->m_id].push_back(*eit);
   272     for (
int i = 0; i < m_localElements.size(); i++)
   274         vector<NodeSharedPtr> v = m_localElements[i]->GetVertexList();
   275         for (
int j = 0; j < 3; j++)
   277             connectingelements[v[j]->m_id].push_back(m_localElements[i]);
   282     for (
int q = 0; q < 4; q++)
   284         for (nit = m_localNodes.begin(); nit != m_localNodes.end(); nit++)
   286             NodeSet::iterator f = m_inBoundary.find((*nit));
   289             if (f != m_inBoundary.end())
   295             vector<NodeSharedPtr> connodes;
   297             vector<EdgeSharedPtr> edges  = connectingedges[(*nit)->m_id];
   298             vector<ElementSharedPtr> els = connectingelements[(*nit)->m_id];
   300             vector<NodeSharedPtr> nodesystem;
   301             vector<NekDouble> lamp;
   303             for (
int i = 0; i < edges.size(); i++)
   305                 vector<NekDouble> lambda;
   308                 if (*nit == edges[i]->m_n1)
   312                 else if (*nit == edges[i]->m_n2)
   318                     ASSERTL0(
false, 
"could not find node");
   324                 for (
int j = 0; j < els.size(); j++)
   326                     vector<NodeSharedPtr> v = els[j]->GetVertexList();
   329                     if (v[0] == J || v[1] == J || v[2] == J)
   337                     vector<EdgeSharedPtr> es = els[j]->GetEdgeList();
   338                     for (
int k = 0; k < es.size(); k++)
   340                         if (!(es[k]->m_n1 == *nit || es[k]->m_n2 == *nit))
   347                     ASSERTL0(found, 
"failed to find edge to test");
   352                     NekDouble lam = ((A[0] - uj[0]) * (B[1] - A[1]) -
   353                                      (A[1] - uj[1]) * (B[0] - A[0])) /
   354                                     ((ui[0] - uj[0]) * (B[1] - A[1]) -
   355                                      (ui[1] - uj[1]) * (B[0] - A[0]));
   357                     if (!(lam < 0) && !(lam > 1))
   358                         lambda.push_back(lam);
   361                 if (lambda.size() > 0)
   363                     sort(lambda.begin(), lambda.end());
   366                     ud[0] = uj[0] + lambda[0] * (ui[0] - uj[0]);
   367                     ud[1] = uj[1] + lambda[0] * (ui[1] - uj[1]);
   370                         new Node(0, locd[0], locd[1], locd[2]));
   371                     dn->SetCADSurf(m_cadsurf, ud);
   373                     nodesystem.push_back(dn);
   374                     lamp.push_back(lambda[0]);
   378                     nodesystem.push_back(J);
   387             for (
int i = 0; i < nodesystem.size(); i++)
   390                 u0[0] += uj[0] / nodesystem.size();
   391                 u0[1] += uj[1] / nodesystem.size();
   452             bool inbounds = 
true;
   453             if (u0[0] < bounds[0])
   457             else if (u0[0] > bounds[1])
   461             else if (u0[1] < bounds[2])
   465             else if (u0[1] > bounds[3])
   501             (*nit)->Move(l2, m_id, u0);
   506 void FaceMesh::DiagonalSwap()
   508     map<int, int> idealConnec;
   509     map<int, int> actualConnec;
   510     map<int, vector<EdgeSharedPtr> > nodetoedge;
   512     EdgeSet::iterator eit;
   513     for (eit = m_localEdges.begin(); eit != m_localEdges.end(); eit++)
   515         nodetoedge[(*eit)->m_n1->m_id].push_back(*eit);
   516         nodetoedge[(*eit)->m_n2->m_id].push_back(*eit);
   518     NodeSet::iterator nit;
   519     for (nit = m_localNodes.begin(); nit != m_localNodes.end(); nit++)
   522         NodeSet::iterator f = m_inBoundary.find((*nit));
   523         if (f == m_inBoundary.end()) 
   526             idealConnec[(*nit)->m_id] = 6;
   550             idealConnec[(*nit)->m_id] = 4;
   553     for (nit = m_localNodes.begin(); nit != m_localNodes.end(); nit++)
   555         actualConnec[(*nit)->m_id] = nodetoedge[(*nit)->m_id].size();
   560     for (
int q = 0; q < 4; q++)
   562         int edgesStart = m_localEdges.size();
   564         m_localEdges.clear();
   566         int swappedEdges = 0;
   568         EdgeSet::iterator it;
   570         for (it = edges.begin(); it != edges.end(); it++)
   574             NodeSet::iterator f1 = m_inBoundary.find((*it)->m_n1);
   575             NodeSet::iterator f2 = m_inBoundary.find((*it)->m_n2);
   576             if (f1 != m_inBoundary.end() && f2 != m_inBoundary.end())
   578                 m_localEdges.insert(e);
   588             vector<NodeSharedPtr> nt = tri1->GetVertexList();
   592             if (nt[0] != n1 && nt[0] != n2)
   598             else if (nt[1] != n1 && nt[1] != n2)
   604             else if (nt[2] != n1 && nt[2] != n2)
   612                 ASSERTL0(
false, 
"failed to identify verticies in tri1");
   615             nt = tri2->GetVertexList();
   617             if (nt[0] != n1 && nt[0] != n2)
   621             else if (nt[1] != n1 && nt[1] != n2)
   625             else if (nt[2] != n1 && nt[2] != n2)
   631                 ASSERTL0(
false, 
"failed to identify verticies in tri2");
   646             ai = A->GetCADSurfInfo(m_id);
   647             bi = B->GetCADSurfInfo(m_id);
   648             ci = C->GetCADSurfInfo(m_id);
   649             di = D->GetCADSurfInfo(m_id);
   653             CDA = 0.5 * (-di[0] * ci[1] + ai[0] * ci[1] + ci[0] * di[1] -
   654                          ai[0] * di[1] - ci[0] * ai[1] + di[0] * ai[1]);
   656             CBD = 0.5 * (-bi[0] * ci[1] + di[0] * ci[1] + ci[0] * bi[1] -
   657                          di[0] * bi[1] - ci[0] * di[1] + bi[0] * di[1]);
   661             if (!(CDA > 0.001 && CBD > 0.001))
   663                 m_localEdges.insert(e);
   671                 int nodedefectbefore = 0;
   673                     abs(actualConnec[A->m_id] - idealConnec[A->m_id]);
   675                     abs(actualConnec[B->m_id] - idealConnec[B->m_id]);
   677                     abs(actualConnec[C->m_id] - idealConnec[C->m_id]);
   679                     abs(actualConnec[D->m_id] - idealConnec[D->m_id]);
   681                 int nodedefectafter = 0;
   683                     abs(actualConnec[A->m_id] - 1 - idealConnec[A->m_id]);
   685                     abs(actualConnec[B->m_id] - 1 - idealConnec[B->m_id]);
   687                     abs(actualConnec[C->m_id] + 1 - idealConnec[C->m_id]);
   689                     abs(actualConnec[D->m_id] + 1 - idealConnec[D->m_id]);
   691                 if (nodedefectafter < nodedefectbefore)
   698                 NekDouble minanglebefore = C->Angle(A, B);
   699                 minanglebefore           = min(minanglebefore, A->Angle(B, C));
   700                 minanglebefore           = min(minanglebefore, B->Angle(A, C));
   701                 minanglebefore           = min(minanglebefore, B->Angle(A, D));
   702                 minanglebefore           = min(minanglebefore, A->Angle(B, D));
   703                 minanglebefore           = min(minanglebefore, D->Angle(A, B));
   705                 NekDouble minangleafter = C->Angle(B, D);
   706                 minangleafter           = min(minangleafter, D->Angle(B, C));
   707                 minangleafter           = min(minangleafter, B->Angle(C, D));
   708                 minangleafter           = min(minangleafter, C->Angle(A, D));
   709                 minangleafter           = min(minangleafter, A->Angle(C, D));
   710                 minangleafter           = min(minangleafter, D->Angle(A, C));
   712                 if (minangleafter > minanglebefore)
   720                 actualConnec[A->m_id]--;
   721                 actualConnec[B->m_id]--;
   722                 actualConnec[C->m_id]++;
   723                 actualConnec[D->m_id]++;
   727                 CAt = std::shared_ptr<Edge>(
new Edge(C, A));
   728                 ADt = std::shared_ptr<Edge>(
new Edge(A, D));
   729                 DBt = std::shared_ptr<Edge>(
new Edge(D, B));
   730                 BCt = std::shared_ptr<Edge>(
new Edge(B, C));
   732                 vector<EdgeSharedPtr> es = tri1->GetEdgeList();
   733                 for (
int i = 0; i < 3; i++)
   744                 es = tri2->GetEdgeList();
   745                 for (
int i = 0; i < 3; i++)
   758                 vector<pair<ElementSharedPtr, int> > links;
   760                 links = CA->m_elLink;
   761                 CA->m_elLink.clear();
   762                 for (
int i = 0; i < links.size(); i++)
   764                     if (links[i].first->GetId() == tri1->GetId())
   768                     CA->m_elLink.push_back(links[i]);
   771                 links = BC->m_elLink;
   772                 BC->m_elLink.clear();
   773                 for (
int i = 0; i < links.size(); i++)
   775                     if (links[i].first->GetId() == tri1->GetId())
   779                     BC->m_elLink.push_back(links[i]);
   782                 links = AD->m_elLink;
   783                 AD->m_elLink.clear();
   784                 for (
int i = 0; i < links.size(); i++)
   786                     if (links[i].first->GetId() == tri2->GetId())
   790                     AD->m_elLink.push_back(links[i]);
   793                 links = DB->m_elLink;
   794                 DB->m_elLink.clear();
   795                 for (
int i = 0; i < links.size(); i++)
   797                     if (links[i].first->GetId() == tri2->GetId())
   801                     DB->m_elLink.push_back(links[i]);
   806                 vector<NodeSharedPtr> t1, t2;
   815                                 m_mesh->m_spaceDim != 3);
   816                 vector<int> tags = tri1->GetTagList();
   818                 int id1 = tri1->GetId();
   819                 int id2 = tri2->GetId();
   823                 tags                   = tri2->GetTagList();
   829                 ntri1->m_parentCAD = m_cadsurf;
   830                 ntri2->m_parentCAD = m_cadsurf;
   832                 vector<EdgeSharedPtr> t1es = ntri1->GetEdgeList();
   833                 for (
int i = 0; i < 3; i++)
   837                         ntri1->SetEdge(i, DB);
   838                         DB->m_elLink.push_back(
   839                             pair<ElementSharedPtr, int>(ntri1, i));
   841                     else if (t1es[i] == BC)
   843                         ntri1->SetEdge(i, BC);
   844                         BC->m_elLink.push_back(
   845                             pair<ElementSharedPtr, int>(ntri1, i));
   847                     else if (t1es[i] == newe)
   849                         ntri1->SetEdge(i, newe);
   850                         newe->m_elLink.push_back(
   851                             pair<ElementSharedPtr, int>(ntri1, i));
   855                         ASSERTL0(
false, 
"weird edge in new tri 1");
   858                 vector<EdgeSharedPtr> t2es = ntri2->GetEdgeList();
   859                 for (
int i = 0; i < 3; i++)
   863                         ntri2->SetEdge(i, CA);
   864                         CA->m_elLink.push_back(
   865                             pair<ElementSharedPtr, int>(ntri2, i));
   867                     else if (t2es[i] == AD)
   869                         ntri2->SetEdge(i, AD);
   870                         AD->m_elLink.push_back(
   871                             pair<ElementSharedPtr, int>(ntri2, i));
   873                     else if (t2es[i] == newe)
   875                         ntri2->SetEdge(i, newe);
   876                         newe->m_elLink.push_back(
   877                             pair<ElementSharedPtr, int>(ntri2, i));
   881                         ASSERTL0(
false, 
"weird edge in new tri 2");
   885                 m_localEdges.insert(newe);
   887                 m_localElements[id1] = ntri1;
   888                 m_localElements[id2] = ntri2;
   894                 m_localEdges.insert(e);
   898         ASSERTL0(m_localEdges.size() == edgesStart, 
"mismatch edge count");
   902 void FaceMesh::BuildLocalMesh()
   909     for (
int i = 0; i < m_connec.size(); i++)
   912                         m_mesh->m_spaceDim != 3);
   915         tags.push_back(m_compId);
   918         E->m_parentCAD = m_cadsurf;
   920         vector<NodeSharedPtr> nods = E->GetVertexList();
   921         for (
int j = 0; j < nods.size(); j++)
   924             m_localNodes.insert(nods[j]);
   927         E->SetId(m_localElements.size());
   928         m_localElements.push_back(E);
   931     for (
int i = 0; i < m_localElements.size(); ++i)
   933         for (
int j = 0; j < m_localElements[i]->GetEdgeCount(); ++j)
   935             pair<EdgeSet::iterator, bool> testIns;
   938             EdgeSet::iterator s = m_mesh->m_edgeSet.find(ed);
   939             if (!(s == m_mesh->m_edgeSet.end()))
   942                 m_localElements[i]->SetEdge(j, *s);
   945             testIns = m_localEdges.insert(ed);
   950                 ed2->m_elLink.push_back(
   951                     pair<ElementSharedPtr, int>(m_localElements[i], j));
   956                 m_localElements[i]->SetEdge(j, e2);
   957                 e2->m_elLink.push_back(
   958                     pair<ElementSharedPtr, int>(m_localElements[i], j));
   964 void FaceMesh::Stretching()
   970     NekDouble dxu = int(bnds[1] - bnds[0] < bnds[3] - bnds[2]
   972                             : (bnds[1] - bnds[0]) / (bnds[3] - bnds[2]) * 40);
   973     NekDouble dxv = int(bnds[3] - bnds[2] < bnds[1] - bnds[0]
   975                             : (bnds[3] - bnds[2]) / (bnds[1] - bnds[0]) * 40);
   977     NekDouble du = (bnds[1] - bnds[0]) / dxu;
   978     NekDouble dv = (bnds[3] - bnds[2]) / dxv;
   982     for (
int i = 0; i < dxu; i++)
   984         for (
int j = 0; j < dxv; j++)
   987             uv[0] = bnds[0] + i * du;
   988             uv[1] = bnds[2] + j * dv;
   999             NekDouble ru = sqrt(r[3] * r[3] + r[4] * r[4] + r[5] * r[5]);
  1000             NekDouble rv = sqrt(r[6] * r[6] + r[7] * r[7] + r[8] * r[8]);
  1018 bool FaceMesh::Validate()
  1023     int pointBefore = m_stienerpoints.size();
  1024     for (
int i = 0; i < m_connec.size(); i++)
  1028         vector<Array<OneD, NekDouble> > info;
  1030         for (
int j = 0; j < 3; j++)
  1032             info.push_back(m_connec[i][j]->GetCADSurfInfo(m_id));
  1035         r[0] = m_connec[i][0]->Distance(m_connec[i][1]);
  1036         r[1] = m_connec[i][1]->Distance(m_connec[i][2]);
  1037         r[2] = m_connec[i][2]->Distance(m_connec[i][0]);
  1039         a[0] = m_connec[i][0]->Angle(m_connec[i][1]->GetLoc(),
  1040                                      m_connec[i][2]->GetLoc(),
  1041                                      m_cadsurf->N(info[0]));
  1042         a[1] = m_connec[i][1]->Angle(m_connec[i][2]->GetLoc(),
  1043                                      m_connec[i][0]->GetLoc(),
  1044                                      m_cadsurf->N(info[1]));
  1045         a[2] = m_connec[i][2]->Angle(m_connec[i][0]->GetLoc(),
  1046                                      m_connec[i][1]->GetLoc(),
  1047                                      m_cadsurf->N(info[2]));
  1049         NekDouble d1 = m_mesh->m_octree->Query(m_connec[i][0]->GetLoc());
  1050         NekDouble d2 = m_mesh->m_octree->Query(m_connec[i][1]->GetLoc());
  1051         NekDouble d3 = m_mesh->m_octree->Query(m_connec[i][2]->GetLoc());
  1054         uvc[0] = (info[0][0] + info[1][0] + info[2][0]) / 3.0;
  1055         uvc[1] = (info[0][1] + info[1][1] + info[2][1]) / 3.0;
  1058         NekDouble d4 = m_mesh->m_octree->Query(locc);
  1060         NekDouble d = (d1 + d2 + d3 + d4) / 4.0;
  1062         vector<bool> valid(3);
  1063         valid[0] = r[0] < d * 1.5;
  1064         valid[1] = r[1] < d * 1.5;
  1065         valid[2] = r[2] < d * 1.5;
  1067         vector<bool> angValid(3);
  1068         angValid[0] = a[0] / M_PI * 180.0 > 20.0 && a[0] / M_PI * 180.0 < 120.0;
  1069         angValid[1] = a[1] / M_PI * 180.0 > 20.0 && a[1] / M_PI * 180.0 < 120.0;
  1070         angValid[2] = a[2] / M_PI * 180.0 > 20.0 && a[2] / M_PI * 180.0 < 120.0;
  1073         int numAngValid = 0;
  1074         for (
int j = 0; j < 3; j++)
  1092         if (numValid != 3 || numAngValid != 3)
  1119     if (m_stienerpoints.size() == pointBefore)
  1133     NekDouble npDelta = m_mesh->m_octree->Query(np);
  1136         new Node(m_mesh->m_numNodes++, np[0], np[1], np[2]));
  1140     for (
int i = 0; i < orderedLoops.size(); i++)
  1142         for (
int j = 0; j < orderedLoops[i].size(); j++)
  1144             NekDouble r = orderedLoops[i][j]->Distance(n);
  1146             if (r < npDelta / 2.0)
  1156         for (
int i = 0; i < m_stienerpoints.size(); i++)
  1158             NekDouble r = m_stienerpoints[i]->Distance(n);
  1160             if (r < npDelta / 2.0)
  1170         n->SetCADSurf(m_cadsurf, uv);
  1171         m_stienerpoints.push_back(n);
  1175 void FaceMesh::OrientateCurves()
  1178     orderedLoops.clear();
  1181     for (
int i = 0; i < m_edgeloops.size(); i++)
  1183         vector<NodeSharedPtr> cE;
  1184         for (
int j = 0; j < m_edgeloops[i]->edges.size(); j++)
  1186             int cid = m_edgeloops[i]->edges[j]->GetId();
  1187             vector<NodeSharedPtr> edgePoints =
  1188                 m_curvemeshes[cid]->GetMeshPoints();
  1190             int numPoints = m_curvemeshes[cid]->GetNumPoints();
  1194                 for (
int k = 0; k < numPoints - 1; k++)
  1196                     cE.push_back(edgePoints[k]);
  1201                 for (
int k = numPoints - 1; k > 0; k--)
  1203                     cE.push_back(edgePoints[k]);
  1207         orderedLoops.push_back(cE);
 
#define ASSERTL0(condition, msg)
Basic information about an element. 
Represents an edge which joins two points. 
std::unordered_set< EdgeSharedPtr, EdgeHash > EdgeSet
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
std::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge. 
ElementFactory & GetElementFactory()
std::shared_ptr< Node > NodeSharedPtr
tBaseSharedPtr CreateInstance(tKey idKey, tParam... args)
Create an instance of the class referred to by idKey. 
std::shared_ptr< Element > ElementSharedPtr
std::shared_ptr< TriangleInterface > TriangleInterfaceSharedPtr