50 #define TOL_BLEND 1.0e-8
59 ProcessSpherigon::create);
93 "Number of points to add to face edges.");
95 "Tag identifying surface to process.");
97 "Curve both triangular faces of prism on boundary.");
99 "Use alternative file for Spherigon definition");
101 "Apply scaling factor to coordinates in file ");
103 "Add randowm noise to normals of amplitude AMP in specified region. input string is Amp,xmin,xmax,ymin,ymax,zmin,zmax");
142 return sqrt(tmp1*tmp1 + tmp2*tmp2 + tmp3*tmp3);
170 vector<double> &r, vector<Node> &Q,
Node &P, vector<double> &blend)
172 vector<double> tmp(r.size());
173 double totBlend = 0.0;
177 for (i = 0; i < nV; ++i)
180 tmp [i] = (Q[i]-P).abs2();
183 for (i = 0; i < nV; ++i)
185 int ip = (i+1) % nV, im = (i-1+nV) % nV;
189 blend[i] = r[i]*r[i]*(
190 r[im]*r[im]*tmp[im]/(tmp[im] + tmp[i]) +
191 r[ip]*r[ip]*tmp[ip]/(tmp[ip] + tmp[i]));
192 totBlend += blend[i];
196 for (i = 0; i < nV; ++i)
198 blend[i] /= totBlend;
230 for (
int i = 0; i < el.size(); ++i)
238 "Spherigon expansions must be lines, triangles or "
242 int nV = e->GetVertexCount();
243 vector<NodeSharedPtr> node(nV);
245 for (
int j = 0; j < nV; ++j)
247 node[j] = e->GetVertex(j);
252 if (mesh->m_spaceDim == 3)
255 Node v1 = *(node[1]) - *(node[0]);
256 Node v2 = *(node[2]) - *(node[0]);
262 Node dx = *(node[1]) - *(node[0]);
263 dx /= sqrt(dx.
abs2());
271 for (
int j = 0; j < nV; ++j)
273 nIt = mesh->m_vertexNormals.find(e->GetVertex(j)->m_id);
274 if (nIt == mesh->m_vertexNormals.end())
276 mesh->m_vertexNormals[e->GetVertex(j)->m_id] = n;
286 for (nIt = mesh->m_vertexNormals.begin();
287 nIt != mesh->m_vertexNormals.end (); ++nIt)
289 Node &n = mesh->m_vertexNormals[nIt->first];
300 "Spherigon implementation only valid in 2D/3D.");
303 boost::unordered_set<int> visitedEdges;
306 vector<ElementSharedPtr> el;
310 cout <<
"ProcessSpherigon: Smoothing mesh..." << endl;
328 string surfTag =
m_config[
"surf"].as<
string>();
329 bool prismTag =
m_config[
"BothTriFacesOnPrism"].beenSet;
333 vector<unsigned int> surfs;
335 sort(surfs.begin(), surfs.end());
337 m_mesh->m_spherigonSurfs.clear();
338 for (
int i = 0; i <
m_mesh->m_element[
m_mesh->m_expDim].size(); ++i)
341 int nSurf =
m_mesh->m_expDim == 3 ? el->GetFaceCount() :
344 for (
int j = 0; j < nSurf; ++j)
346 int bl = el->GetBoundaryLink(j);
353 vector<int> tags = bEl->GetTagList();
356 sort(tags.begin(), tags.end());
357 set_intersection(surfs.begin(), surfs.end(),
358 tags .begin(), tags .end(),
359 back_inserter(inter));
361 if (inter.size() == 1)
363 m_mesh->m_spherigonSurfs.insert(make_pair(i, j));
367 if(nSurf == 5 && prismTag)
371 int triFace = j == 1 ? 3 : 1;
372 m_mesh->m_spherigonSurfs.insert(
373 make_pair(i, triFace));
380 if (
m_mesh->m_spherigonSurfs.size() == 0)
382 cerr <<
"WARNING: Spherigon surfaces have not been defined "
383 <<
"-- ignoring smoothing." << endl;
387 if (
m_mesh->m_expDim == 3)
389 for (it =
m_mesh->m_spherigonSurfs.begin();
390 it !=
m_mesh->m_spherigonSurfs.end (); ++it)
394 vector<NodeSharedPtr> nodes = f->m_vertexList;
400 CreateInstance(eType,conf,nodes,t);
403 for (
int i = 0; i < f->m_vertexList.size(); ++i)
405 elmt->SetVertex(i, f->m_vertexList[i]);
407 for (
int i = 0; i < f->m_edgeList.size(); ++i)
409 elmt->SetEdge(i, f->m_edgeList[i]);
417 for (it =
m_mesh->m_spherigonSurfs.begin();
418 it !=
m_mesh->m_spherigonSurfs.end (); ++it)
422 vector<NodeSharedPtr> nodes;
426 nodes.push_back(edge->m_n1);
427 nodes.push_back(edge->m_n2);
431 CreateInstance(eType,conf,nodes,t);
434 elmt->SetVertex(0, nodes[0]);
435 elmt->SetVertex(1, nodes[1]);
436 elmt->SetEdge(0,
m_mesh->m_element[
m_mesh->m_expDim][it->first]->
444 ASSERTL0(
false,
"Spherigon expansions must be 2/3 dimensional");
450 bool normalsGenerated =
false;
453 std::string normalfile =
m_config[
"usenormalfile"].as<
string>();
454 if(normalfile.compare(
"NoFile") != 0)
460 cout <<
"Inputing normal file: " << normalfile <<
" with scaling of " << scale << endl;
466 inply.open(normalfile.c_str());
470 plyfile = boost::shared_ptr<InputPly>(
new InputPly(m));
471 plyfile->ReadPly(inply,scale);
472 plyfile->ProcessVertices();
479 Array<OneD, NekDouble> len2(plymesh->m_vertexSet.size());
480 Node minx(0,0.0,0.0,0.0), tmp,tmpsav;
483 map<int,NodeSharedPtr> surfverts;
486 for (
int i = 0; i < el.size(); ++i)
489 int nV = e->GetVertexCount();
490 for (
int j = 0; j < nV; ++j)
492 int id = e->GetVertex(j)->m_id;
493 surfverts[id] = e->GetVertex(j);
506 cout <<
"\t Processing surface normals " << endl;
509 map<int,int> locnorm;
510 for(vIt = surfverts.begin(); vIt != surfverts.end(); ++vIt,++cnt)
514 for(j = 0, it = plymesh->m_vertexSet.begin(); it != plymesh->m_vertexSet.end(); ++it, ++j)
516 tmp = *(vIt->second)- *(*it);
522 cntmin = (*it)->m_id;
526 locnorm[cntmin] = vIt->first;
528 ASSERTL1(cntmin < plymesh->m_vertexNormals.size(),
"cntmin is out of range");
529 m_mesh->m_vertexNormals[vIt->first] = plymesh->m_vertexNormals[cntmin];
534 cout <<
"\t end of processing surface normals " << endl;
536 normalsGenerated =
true;
538 else if (
m_mesh->m_vertexNormals.size() == 0)
541 normalsGenerated =
true;
546 std::string normalnoise =
m_config[
"normalnoise"].as<
string>();
547 if(normalnoise.compare(
"NotSpecified") != 0)
549 vector<NekDouble> values;
552 int nvalues = values.size()/2;
558 cout <<
"\t adding noise to normals of amplitude "<< amp <<
" in range: ";
559 for(
int i = 0; i < nvalues; ++i)
561 cout << values[2*i+1] <<
"," << values[2*i+2] <<
" ";
567 map<int,NodeSharedPtr> surfverts;
570 for (
int i = 0; i < el.size(); ++i)
573 int nV = e->GetVertexCount();
574 for (
int j = 0; j < nV; ++j)
576 int id = e->GetVertex(j)->m_id;
577 surfverts[id] = e->GetVertex(j);
581 for(vIt = surfverts.begin(); vIt != surfverts.end(); ++vIt)
583 bool AddNoise =
false;
585 for(
int i = 0; i < nvalues; ++i)
592 if(((vIt->second)->m_x > values[2*i+1])&&((vIt->second)->m_x < values[2*i+2]))
600 if(((vIt->second)->m_x > values[2*i+1])&&
601 ((vIt->second)->m_x < values[2*i+2])&&
602 ((vIt->second)->m_y > values[2*i+3])&&
603 ((vIt->second)->m_y < values[2*i+4]))
611 if(((vIt->second)->m_x > values[2*i+1])&&
612 ((vIt->second)->m_x < values[2*i+2])&&
613 ((vIt->second)->m_y > values[2*i+3])&&
614 ((vIt->second)->m_y < values[2*i+4])&&
615 ((vIt->second)->m_z > values[2*i+5])&&
616 ((vIt->second)->m_z < values[2*i+6]))
628 Node rvec(0,rand(),rand(),rand());
629 rvec *= values[0]/sqrt(rvec.
abs2());
631 Node normal =
m_mesh->m_vertexNormals[vIt->first];
634 normal /= sqrt(normal.abs2());
636 m_mesh->m_vertexNormals[vIt->first] = normal;
645 int nquad =
m_mesh->m_spaceDim == 3 ? nq*nq : nq;
646 Array<OneD, NekDouble> x(nq*nq);
647 Array<OneD, NekDouble> y(nq*nq);
648 Array<OneD, NekDouble> z(nq*nq);
650 Array<OneD, NekDouble> xc(nq*nq);
651 Array<OneD, NekDouble> yc(nq*nq);
652 Array<OneD, NekDouble> zc(nq*nq);
654 ASSERTL0(nq > 2,
"Number of points must be greater than 2.");
668 Array<OneD, NekDouble> xnodal(nq*(nq+1)/2), ynodal(nq*(nq+1)/2);
669 stdtri->GetNodalPoints(xnodal, ynodal);
671 int edgeMap[3][4][2] = {
672 {{0, 1}, {-1, -1}, {-1, -1 }, {-1, -1}},
673 {{0, 1}, {nq-1, nq}, {nq*(nq-1), -nq}, {-1, -1}},
674 {{0, 1}, {nq-1, nq}, {nq*nq-1, -1 }, {nq*(nq-1), -nq}}
677 int vertMap[3][4][2] = {
678 {{0, 1}, {0, 0}, {0, 0}, {0, 0}},
679 {{0, 1}, {1, 2}, {2, 3}, {0, 0}},
680 {{0, 1}, {1, 2}, {2, 3}, {3, 0}},
683 for (
int i = 0; i < el.size(); ++i)
699 e->GetGeom(
m_mesh->m_spaceDim));
703 seg->GetCoords(x,y,z);
716 Array<OneD, NekDouble> coord(2);
717 tri->GetCoords(xc,yc,zc);
720 for (
int j = 0; j < nquad; ++j)
722 coord[0] = xnodal[j];
723 coord[1] = ynodal[j];
724 x[j] = stdtri->PhysEvaluate(coord, xc);
727 for (
int j = 0; j < nquad; ++j)
729 coord[0] = xnodal[j];
730 coord[1] = ynodal[j];
731 y[j] = stdtri->PhysEvaluate(coord, yc);
734 for (
int j = 0; j < nquad; ++j)
736 coord[0] = xnodal[j];
737 coord[1] = ynodal[j];
738 z[j] = stdtri->PhysEvaluate(coord, zc);
749 quad->GetCoords(x,y,z);
754 ASSERTL0(
false,
"Unknown expansion type.");
758 if (
m_mesh->m_spaceDim == 2)
764 int nV = e->GetVertexCount();
766 for (
int j = 0; j < nV; ++j)
768 v.push_back(*(e->GetVertex(j)));
769 ASSERTL1(
m_mesh->m_vertexNormals.count(v[j].m_id) != 0,
"Normal has not been defined");
770 vN.push_back(
m_mesh->m_vertexNormals[v[j].m_id]);
773 vector<Node> tmp (nV);
774 vector<double> r (nV);
777 vector<Node> Qp (nV);
778 vector<double> blend(nV);
779 vector<Node> out (nquad);
782 double segLength = sqrt((v[0] - v[1]).abs2());
785 for (
int j = 0; j < nquad; ++j)
787 Node P(0, x[j], y[j], z[j]);
792 if (
m_mesh->m_spaceDim == 2)
797 r[0] = sqrt((P - v[0]).abs2()) / segLength;
798 r[0] = max(min(1.0, r[0]), 0.0);
802 N = vN[0]*r[0] + vN[1]*r[1];
804 else if (
m_mesh->m_spaceDim == 3)
806 for (
int k = 0; k < nV; ++k)
814 for (
int k = 0; k < nV; ++k)
817 for (
int l = 0; l < nV-2; ++l)
826 for (
int k = 0; k < nV; ++k)
836 for (
int k = 0; k < nV; ++k)
841 K [k] = P+N*((v[k]-P).dot(N));
842 tmp1 = (v[k]-K[k]).dot(vN[k]) / (1.0 + N.
dot(vN[k]));
843 Q [k] = K[k] + N*tmp1;
844 Qp[k] = v[k] - N*((v[k]-P).dot(N));
853 for (
int k = 0; k < nV; ++k)
863 int offset = (int)e->GetConf().m_e-2;
865 for (
int edge = 0; edge < e->GetEdgeCount(); ++edge)
867 eIt = visitedEdges.find(e->GetEdge(edge)->m_id);
868 if (eIt == visitedEdges.end())
870 bool reverseEdge = !(v[vertMap[offset][edge][0]] ==
871 *(e->GetEdge(edge)->m_n1));
874 e->GetEdge(edge)->m_edgeNodes.clear();
878 for (
int j = 1; j < nq-1; ++j)
880 int v = edgeMap[offset][edge][0] +
881 j*edgeMap[offset][edge][1];
882 e->GetEdge(edge)->m_edgeNodes.push_back(
888 for (
int j = 0; j < nq-2; ++j)
890 int v = 3 + edge*(nq-2) + j;
891 e->GetEdge(edge)->m_edgeNodes.push_back(
898 reverse(e->GetEdge(edge)->m_edgeNodes.begin(),
899 e->GetEdge(edge)->m_edgeNodes.end());
902 e->GetEdge(edge)->m_curveType =
905 visitedEdges.insert(e->GetEdge(edge)->m_id);
910 if (
m_mesh->m_spaceDim == 3)
912 vector<NodeSharedPtr> volNodes;
916 volNodes.resize((nq-2)*(nq-2));
917 for (
int j = 1; j < nq-1; ++j)
919 for (
int k = 1; k < nq-1; ++k)
922 volNodes[(j-1)*(nq-2)+(k-1)] =
929 for (
int j = 3+3*(nq-2); j < nquad; ++j)
935 e->SetVolumeNodes(volNodes);
940 if (
m_mesh->m_expDim == 3)
944 for (it =
m_mesh->m_spherigonSurfs.begin();
945 it !=
m_mesh->m_spherigonSurfs.end (); ++it, ++elmt)
950 f->m_faceNodes = el[elmt]->GetVolumeNodes();
951 f->m_curveType = f->m_vertexList.size() == 3 ?
957 if (normalsGenerated)
959 m_mesh->m_vertexNormals.clear();