7 #include <unordered_map>
23 using json = rsvsjson::json;
25 void tetgen::internal::MeshData2Tetgenio(
const mesh &meshgeom,
tetgen::io_safe &tetin,
int facetOffset,
int pointOffset,
26 int pointMarker,
const std::vector<double> &pointMtrList,
27 const std::vector<double> &facetConstr,
int facetConstrOffset)
32 vector<int> orderVert;
33 int countI, countJ, countK, nFacetConstr;
36 countI = meshgeom.verts.size();
37 countJ = min(
int(pointMtrList.size()), tetin.numberofpointmtrs);
38 for (
int i = 0; i < countI; ++i)
41 for (
int j = 0; j < 3; ++j)
43 tetin.pointlist[(i + pointOffset) * 3 + j] = meshgeom.verts(i)->coord[j];
46 for (
int j = 0; j < countJ; ++j)
48 tetin.pointmtrlist[(i + pointOffset) * countJ + j] = pointMtrList[j];
51 tetin.pointmarkerlist[i + pointOffset] = pointMarker;
55 nFacetConstr = facetConstr.size();
57 for (
int i = 0; i < nFacetConstr; ++i)
60 tetin.facetconstraintlist[(facetConstrOffset + i) * 2] =
double(facetConstrOffset + i + 1);
61 tetin.facetconstraintlist[(facetConstrOffset + i) * 2 + 1] = facetConstr[i];
65 countI = meshgeom.surfs.size();
66 if (nFacetConstr != 1 && nFacetConstr != countI && nFacetConstr != 0)
68 std::cerr <<
"Warning: Number of constraints is not 1 or the "
69 "number of surfaces, the code will work but the behaviour "
73 nFacetConstr = max(nFacetConstr, 1);
74 for (
int i = 0; i < countI; ++i)
76 tetin.allocatefacet(i + facetOffset, 1);
78 meshgeom.surfs(i)->OrderedVerts(&meshgeom, orderVert);
79 tetin.allocatefacetpolygon(i + facetOffset, 0, orderVert.size());
80 countK = orderVert.size();
81 for (
int k = 0; k < countK; ++k)
83 tetin.facetlist[i + facetOffset].polygonlist[0].vertexlist[k] =
84 meshgeom.verts.find(orderVert[k]) + pointOffset;
87 tetin.facetmarkerlist[i + facetOffset] = facetConstrOffset + (i % nFacetConstr) + 1;
92 void tetgen::internal::Mesh2Tetgenio(
const mesh &meshgeom,
const mesh &meshdomain,
tetgen::io_safe &tetin,
int numHoles)
103 tetin.firstnumber = 0;
105 tetin.numberoffacets = meshgeom.surfs.size() + meshdomain.surfs.size();
106 tetin.numberofholes = numHoles;
107 tetin.numberofpoints += meshgeom.verts.size() + meshdomain.verts.size();
109 tetin.numberofpointmtrs = 1;
110 tetin.numberoffacetconstraints = 2;
114 tetgen::internal::MeshData2Tetgenio(meshgeom, tetin, 0, 0, 1, {0.0}, {0.0}, 0);
115 tetgen::internal::MeshData2Tetgenio(meshdomain, tetin, meshgeom.surfs.size(), meshgeom.verts.size(), -1, {-1.0},
119 void tetgen::internal::Mesh2TetgenioPoints(
const mesh &meshgeom,
const mesh &meshdomain,
tetgen::io_safe &tetin)
131 tetin.firstnumber = 0;
133 tetin.numberoffacets = 0;
134 tetin.numberofholes = 0;
135 tetin.numberofpoints += meshgeom.verts.size() + meshdomain.verts.size();
137 tetin.numberofpointmtrs = 0;
138 tetin.numberoffacetconstraints = 0;
141 int nPtsGeom = meshgeom.verts.size();
142 for (
int i = 0; i < nPtsGeom; ++i)
144 for (
int j = 0; j < 3; ++j)
146 tetin.pointlist[i * 3 + j] = meshgeom.verts(i)->coord[j];
149 int nPtsDom = meshdomain.verts.size();
150 for (
int i = 0; i < nPtsDom; ++i)
152 for (
int j = 0; j < 3; ++j)
154 tetin.pointlist[(i + nPtsGeom) * 3 + j] = meshdomain.verts(i)->coord[j];
159 void tetgen::internal::PointCurvature2Metric(std::vector<double> &vertCurvature,
const tetgen::apiparam &inparam)
161 double maxCurv = *max_element(vertCurvature.begin(), vertCurvature.end());
162 double minCurv = 0.0;
163 double deltaCurv = maxCurv - minCurv;
164 auto lininterp = [&](
double curv) ->
double {
169 int count = vertCurvature.size();
170 for (
int i = 0; i < count; ++i)
172 vertCurvature[i] = lininterp(vertCurvature[i]);
186 mesh meshdomain, meshgeom;
191 std::vector<int> holeIndices;
192 std::array<double, 3> upperB, lowerB;
193 std::vector<int> vertPerSubDomain;
194 std::vector<double> holeCoords;
198 meshgeom.ReturnBoundingBox(lowerB, upperB);
200 for (
int i = 0; i < 3; ++i)
202 lowerB[i] -= distBound;
203 upperB[i] += distBound;
207 nHoles = holeCoords.size() / 3;
208 tetgen::internal::Mesh2Tetgenio(meshgeom, meshdomain, tetin, nHoles);
214 int count = holeCoords.size();
215 for (
int i = 0; i < count; ++i)
217 tetin.holelist[i] = holeCoords[i];
221 int startPnt = meshgeom.verts.size();
224 tetin.SpecifyTetPointMetric(0, startPnt, {tetgenParam.
surfedgelengths[0]});
229 DisplayVectorStatistics(vertCurvature);
230 tetgen::internal::PointCurvature2Metric(vertCurvature, tetgenParam);
231 tetin.SpecifyTetPointMetric(0, startPnt, vertCurvature);
232 DisplayVectorStatistics(vertCurvature);
234 for (
int i = 0; i < int(tetgenParam.
edgelengths.size()); ++i)
236 tetin.SpecifyTetPointMetric(startPnt, vertPerSubDomain[i], {tetgenParam.
edgelengths[i]});
237 startPnt = startPnt + vertPerSubDomain[i];
240 startPnt = meshgeom.surfs.size();
241 int nSurfPerSubDomain = meshdomain.surfs.size() / vertPerSubDomain.size();
242 for (
int i = 0; i < int(vertPerSubDomain.size()) - 1; ++i)
244 tetin.SpecifyTetFacetMetric(startPnt, nSurfPerSubDomain, 0);
245 startPnt = startPnt + nSurfPerSubDomain;
264 std::vector<int> holeIndices;
265 std::vector<int> vertPerSubDomain;
267 vertPerSubDomain.push_back(meshdomain.verts.size());
269 tetgen::internal::Mesh2Tetgenio(meshboundary, meshdomain, tetin, nHoles);
271 int startPnt = meshboundary.verts.size();
274 int count = vertEdgeLength.size();
275 for (
int i = 0; i < count; ++i)
277 vertEdgeLength[i] = vertEdgeLength[i] * tetgenParam.
edgelengths[0];
279 tetin.SpecifyTetPointMetric(0, startPnt, vertEdgeLength);
282 count = vertEdgeLength.size();
283 for (
int i = 0; i < count; ++i)
285 vertEdgeLength[i] = vertEdgeLength[i] * tetgenParam.
edgelengths[0];
287 tetin.SpecifyTetPointMetric(startPnt, startPnt + vertEdgeLength.size(), vertEdgeLength);
293 meshboundary.Init(0, 0, 0, 0);
294 meshboundary.HashArray();
296 tetgen::input::RSVSGRIDS(meshdomain, meshboundary, tetin, tetgenParam);
300 bool generateVoroBound)
313 if (generateVoroBound)
323 std::vector<double> vertsToAdd;
324 std::array<double, 3> vertModif = {0, 0, 0}, edgeModif = {0, 0, 0};
325 #ifdef RSVS_DIAGNOSTIC_RESOLVED
327 tecout.OpenFile(
"../TESTOUT/rsvs_voro.plt",
"a");
329 vertsToAdd.reserve(100);
331 for (
int l = 0; l < 4; ++l)
333 vertModif = {0, 0, 0};
338 for (
int i = 0; i < 8; ++i)
340 for (
int j = 0; j < 3; ++j)
343 double delta = (tetgenParam.
upperB[j] - tetgenParam.
lowerB[j]) * vertModif[j];
344 vertsToAdd.push_back(
345 (((i / k) % 2) ? tetgenParam.
upperB[j] + delta : tetgenParam.
lowerB[j] - delta));
352 int nEdgeSteps = ceil(1.0 / (tetgenParam.
distanceTol * 2));
353 for (
int ll = 1; ll < nEdgeSteps; ++ll)
355 for (
int l = 0; l < 3; ++l)
357 edgeModif = {0, 0, 0};
358 edgeModif[l] = 1.0 / double(nEdgeSteps) * ll;
359 for (
int j = 0; j < 2; ++j)
361 vertModif = {0, 0, 0};
362 vertModif[(l + j + 1) % 3] = tetgenParam.
distanceTol;
363 for (
int i = 0; i < 4; ++i)
366 for (
int m = 0; m < 3; ++m)
370 vertsToAdd.push_back(edgeModif[l]);
374 double delta = (tetgenParam.
upperB[m] - tetgenParam.
lowerB[m]) * vertModif[m];
375 int k = pow(2, (m + 3 - (l + 1)) % 3);
376 vertsToAdd.push_back(
377 (((i / k) % 2) ? tetgenParam.
upperB[m] + delta : tetgenParam.
lowerB[m] - delta));
389 #ifdef RSVS_DIAGNOSTIC_RESOLVED
390 tecout.PrintMesh(meshgeom, 0, 0, rsvs3d::constants::tecplot::point);
395 meshgeom.Init(0, 0, 0, 0);
397 meshgeom.PrepareForUse();
399 tetgen::internal::Mesh2TetgenioPoints(meshgeom, meshdomain, tetin);
415 std::ofstream meshFile;
416 std::vector<int> diffBounds, numBounds;
419 meshFile.open(fileName);
422 DEINCR = tetout.firstnumber ? -1 : 0;
427 std::cerr << std::endl <<
"Error: " << fileName << std::endl <<
" in could not be opened" << std::endl;
431 meshFile.precision(16);
433 meshFile <<
"NDIME= 3" << std::endl;
435 meshFile <<
"NPOIN= " << tetout.numberofpoints << std::endl;
436 for (
int i = 0; i < tetout.numberofpoints; ++i)
438 for (
int j = 0; j < 3; ++j)
440 meshFile << tetout.pointlist[i * 3 + j] <<
" ";
442 meshFile << std::endl;
445 int nElms = tetout.numberoftetrahedra;
446 meshFile <<
"NELEM= " << nElms << std::endl;
448 for (
int i = 0; i < tetout.numberoftetrahedra; ++i)
451 for (
int j = 0; j < 4; ++j)
453 meshFile << tetout.tetrahedronlist[i * tetout.numberofcorners + j] + DEINCR <<
" ";
455 meshFile << std::endl;
459 diffBounds.reserve(10);
460 numBounds.reserve(10);
461 diffBounds.push_back(0);
462 numBounds.push_back(0);
463 int nBounds = diffBounds.size();
466 for (
int i = 0; i < tetout.numberoftrifaces; ++i)
468 bool flagSame =
false;
470 while ((j < nBounds) && !flagSame)
472 flagSame = flagSame || (diffBounds[j] == tetout.trifacemarkerlist[i]);
477 diffBounds.push_back(tetout.trifacemarkerlist[i]);
478 numBounds.push_back(0);
487 meshFile <<
"NMARK= " << nBounds - 1 << std::endl;
488 for (
int k = 1; k < nBounds; ++k)
490 meshFile <<
"MARKER_TAG= " << diffBounds[k] << std::endl;
491 meshFile <<
"MARKER_ELEMS= " << numBounds[k] << std::endl;
492 for (
int i = 0; i < tetout.numberoftrifaces; ++i)
494 if (tetout.trifacemarkerlist[i] == diffBounds[k])
497 for (
int j = 0; j < 3; ++j)
499 meshFile << tetout.trifacelist[i * 3 + j] + DEINCR <<
" ";
501 meshFile << std::endl;
514 void tetgen::internal::CloseVoronoiMesh(
mesh &meshout,
tetgen::io_safe &tetout, std::vector<int> &rayEdges,
int DEINCR,
534 int nVerts, nEdges, nSurfs;
536 double lStep, lStepMin = -0.00;
541 std::vector<int> rayCells;
542 std::vector<int> &rayFaces = rayFacesSearch.vec;
543 std::vector<int> pair;
545 nVerts = meshout.verts.size();
546 nEdges = meshout.edges.size();
547 nSurfs = meshout.surfs.size();
553 count = rayEdges.size();
554 vertNew.edgeind.reserve(6);
555 vertNew.edgeind.assign(1, 0);
556 for (
int i = 0; i < count; ++i)
558 vertNew.index = nVerts + 1;
559 vertNew.edgeind[0] = rayEdges[i];
560 meshout.edges[rayEdges[i] - 1].vertind[1] = nVerts + 1;
562 tetgen::internal::ProjectRay(3, boundBox, tetout.vedgelist[rayEdges[i] - 1].vnormal,
563 meshout.verts[tetout.vedgelist[rayEdges[i] - 1].v1 + DEINCR].coord, lStepMin);
565 for (
int j = 0; j < 3; ++j)
567 vertNew.coord[j] = lStep * tetout.vedgelist[rayEdges[i] - 1].vnormal[j] +
568 meshout.verts[tetout.vedgelist[rayEdges[i] - 1].v1 + DEINCR].coord[j];
570 meshout.verts.push_back(vertNew);
571 newVerts.vec.push_back(nVerts + 1);
575 newVerts.GenerateHash();
580 meshout.edges.HashArray();
581 rayFaces = ConcatenateVectorField(meshout.edges, &edge::surfind, meshout.edges.find_list(rays.vec));
584 count = rayFaces.size();
585 edgeNew.surfind.reserve(6);
586 edgeNew.surfind.assign(1, 0);
587 for (
int i = 0; i < count; ++i)
591 for (
int a : rays.find_list(meshout.surfs[rayFaces[i] - 1].edgeind))
598 if (pair.size() != 2)
603 edgeNew.index = nEdges + 1;
604 for (
int j = 0; j < 2; ++j)
606 edgeNew.vertind[j] = meshout.edges[rays.vec[pair[j]] - 1].vertind[1];
607 meshout.verts[edgeNew.vertind[j] - 1].edgeind.push_back(edgeNew.index);
609 edgeNew.surfind[0] = rayFaces[i];
611 meshout.edges.push_back(edgeNew);
612 meshout.surfs[rayFaces[i] - 1].edgeind.push_back(edgeNew.index);
613 newEdges.vec.push_back(edgeNew.index);
617 newEdges.GenerateHash();
618 rayFacesSearch.GenerateHash();
623 meshout.surfs.HashArray();
624 rayCells = ConcatenateVectorField(meshout.surfs, &surf::voluind, meshout.surfs.find_list(rayFaces));
627 count = rayCells.size();
629 for (
int i = 0; i < count; ++i)
633 surfNew.edgeind.clear();
634 for (
auto a : rayFacesSearch.find_list(meshout.volus[rayCells[i] - 1].surfind))
647 surfNew.index = nSurfs + 1;
648 for (
auto ind : pair)
650 auto &edgeind = meshout.surfs[rayFacesSearch.vec[ind] - 1].edgeind;
653 for (j = 0; j < n; ++j)
655 if (newEdges.find(edgeind[j]) != -1)
657 surfNew.edgeind.push_back(edgeind[j]);
658 meshout.edges[edgeind[j] - 1].surfind.push_back(surfNew.index);
667 " were recognised as new. This should not happen.");
671 std::cerr <<
"Unexpected behaviour with number of edges" << std::endl;
674 surfNew.voluind[0] = rayCells[i];
675 surfNew.voluind[1] = 0;
677 meshout.volus[rayCells[i] - 1].surfind.push_back(surfNew.index);
678 meshout.surfs.push_back(surfNew);
686 domBounds[0] = {INFINITY, INFINITY, INFINITY};
687 domBounds[1] = {-INFINITY, -INFINITY, -INFINITY};
688 int nVerts = tetout.numberofpoints;
691 for (
int i = 0; i < count; ++i)
693 for (
int j = 0; j < n; ++j)
696 domBounds[0][j] <= tetout.pointlist[i * n + j] ? domBounds[0][j] : tetout.pointlist[i * n + j];
698 domBounds[1][j] >= tetout.pointlist[i * n + j] ? domBounds[1][j] : tetout.pointlist[i * n + j];
712 int nVerts, nEdges, nSurfs, nVolus;
713 int count, INCR, DEINCR, n;
714 vector<int> rayInd, rayInd2;
717 nVerts = tetout.numberofvpoints;
718 nEdges = tetout.numberofvedges;
719 nSurfs = tetout.numberofvfacets;
720 nVolus = tetout.numberofvcells;
724 INCR = tetout.firstnumber ? 0 : 1;
725 DEINCR = tetout.firstnumber ? -1 : 0;
729 if (tetout.vpointlist == NULL)
734 meshout.Init(nVerts, nEdges, nSurfs, nVolus);
735 meshout.PopulateIndices();
738 for (
int i = 0; i < nEdges; ++i)
740 meshout.edges[i].vertind.clear();
742 rayInd.reserve(nEdges);
747 for (
int i = 0; i < count; ++i)
749 meshout.verts[i].index = i + 1;
750 for (
int j = 0; j < n; ++j)
752 meshout.verts[i].coord[j] = tetout.vpointlist[i * n + j];
759 for (
int i = 0; i < count; ++i)
761 meshout.edges[i].vertind = {tetout.vedgelist[i].v1 + INCR, tetout.vedgelist[i].v2 + INCR};
763 meshout.verts[tetout.vedgelist[i].v1 + DEINCR].edgeind.push_back(i + 1);
765 if (tetout.vedgelist[i].v2 > -1)
768 meshout.verts[tetout.vedgelist[i].v2 + DEINCR].edgeind.push_back(i + 1);
773 rayInd.push_back(i + 1);
779 for (
int i = 0; i < count; ++i)
782 n = tetout.vfacetlist[i].elist[0];
783 for (
int j = 0; j < n; ++j)
785 if (tetout.vfacetlist[i].elist[j + 1] > -1)
787 meshout.surfs[i].edgeind.push_back(tetout.vfacetlist[i].elist[j + 1] + INCR);
788 meshout.edges[tetout.vfacetlist[i].elist[j + 1] + DEINCR].surfind.push_back(i + 1);
796 meshout.surfs[i].voluind[0] = tetout.vfacetlist[i].c1 + INCR;
797 meshout.surfs[i].voluind[1] = tetout.vfacetlist[i].c2 + INCR;
799 if (tetout.vfacetlist[i].c1 == tetout.vfacetlist[i].c2)
802 "the same two cells");
806 for (
int j = 0; j < n; ++j)
808 meshout.volus[meshout.surfs[i].voluind[j] - 1].surfind.push_back(i + 1);
813 tetgen::internal::CloseVoronoiMesh(meshout, tetout, rayInd, DEINCR, boundBox);
816 for (
int i = 0; i < nVolus; ++i)
818 meshout.volus[i].target = (double(rand() % 1000001) / 1000000);
819 meshout.volus[i].fill = meshout.volus[i].target;
820 meshout.volus[i].error = meshout.volus[i].target;
823 meshout.TestConnectivityBiDir(__PRETTY_FUNCTION__);
824 meshout.TightenConnectivity();
825 meshout.PrepareForUse();
828 auto groupedVertices = GroupCloseVertices(meshout, 1e-7);
829 auto out = meshout.MergeGroupedVertices(groupedVertices,
false);
832 meshout.RemoveSingularConnectors(out);
834 meshout.PrepareForUse();
835 meshout.TightenConnectivity();
836 meshout.OrderEdges();
837 meshout.SetBorders();
840 if (meshout.TestConnectivityBiDir(__PRETTY_FUNCTION__))
846 FlattenBoundaryFaces(meshout);
847 meshout.PrepareForUse();
848 meshout.TightenConnectivity();
849 meshout.OrderEdges();
850 meshout.SetBorders();
853 if (meshout.TestConnectivityBiDir(__PRETTY_FUNCTION__))
910 std::vector<int> vertsVoro;
911 std::vector<int> vertBlock, elmMapping;
914 std::cout <<
"tetrahedralisation: ";
915 auto boundFaces = tetgen::voronoi::Points2VoroAndTetmesh(vecPts, voroMesh, snakMesh, inparam);
916 std::cout <<
"done. ";
918 std::cout <<
"connection(vols): ";
919 int nBlocks = snakMesh.ConnectedVolumes(elmMapping, boundFaces);
920 std::cout <<
"done. ";
923 if (nBlocks != voroMesh.volus.size())
925 std::cerr <<
"Error : nBlocks (" << nBlocks <<
")!=nVolus Voromesh (" << voroMesh.volus.size() <<
")"
930 auto elmMappingCopy = elmMapping;
931 for (
int i = 0; i < nBlocks; ++i)
938 if (elmMappingCopy[jStart] == i + 1)
940 indRep = snakMesh.volus(jStart)->index;
942 }
while (indRep == -1);
943 for (
int j = jStart; j < int(elmMapping.size()); ++j)
945 if (elmMappingCopy[j] == i + 1)
947 elmMapping[j] = indRep;
951 std::cout <<
"parenting: ";
953 snakMesh.AddParent(&vosMesh, elmMapping);
954 snakMesh.PrepareForUse();
956 vosMesh.PrepareForUse();
957 std::cout <<
"done. ";
959 if (vosMesh.volus.size() != voroMesh.volus.size())
961 std::cerr <<
"Error : vosMesh (" << vosMesh.volus.size() <<
")!=nVolus Voromesh (" << voroMesh.volus.size()
965 if (vosMesh.TestConnectivityBiDir(__PRETTY_FUNCTION__))
971 std::vector<int> vecPtsMapping = snakMesh.
VertexInVolume(vecPts, 4);
972 #ifdef RSVS_DIAGNOSTIC_RESOLVED
973 DisplayVector(vecPtsMapping);
976 int count = vosMesh.volus.size();
977 for (
int i = 0; i < count; ++i)
979 vosMesh.volus[i].fill = 0.0;
981 int nVecMap = vecPtsMapping.size();
982 for (
int i = 0; i < nVecMap; ++i)
985 .volus[vosMesh.volus.find(elmMapping[snakMesh.volus.find(vecPtsMapping[i])],
988 .fill = vecPts[i * 4 + 3];
990 for (
int i = 0; i < count; ++i)
992 vosMesh.volus[i].target = vosMesh.volus[i].fill;
993 vosMesh.volus[i].error = 0.0;
995 std::cout <<
"Finishing: ";
996 vosMesh.PrepareForUse();
998 vosMesh.SetBorders();
999 snakMesh.SetBorders();
1000 std::cout <<
"finished. ";
1001 std::cout << std::endl;
1003 return vecPtsMapping;
1021 tetgen::input::RSVS2CFD(snakein, tetin, inparam);
1026 inparam.command =
"pkqm";
1027 rsvstetrahedralize(inparam.command.c_str(), &tetin, &tetout);
1029 tetgen::output::SU2(fileName.c_str(), tetout);
1050 int nVerts, nEdges, nSurfs, nVolus;
1051 int count, INCR, DEINCR, n;
1053 nVerts = tetout.numberofpoints;
1054 nEdges = tetout.numberofedges;
1055 nSurfs = tetout.numberoftrifaces;
1056 nVolus = tetout.numberoftetrahedra;
1060 INCR = tetout.firstnumber ? 0 : 1;
1061 DEINCR = tetout.firstnumber ? -1 : 0;
1065 if (tetout.tet2facelist == NULL)
1070 meshout.Init(nVerts, nEdges, nSurfs, nVolus);
1071 meshout.PopulateIndices();
1073 std::cout << __FUNCTION__ <<
" converting tetrahedralisation of size ";
1074 std::cout << std::endl;
1075 meshout.displight();
1076 std::cout << std::endl;
1079 for (
int i = 0; i < nSurfs; ++i)
1081 meshout.surfs[i].voluind.clear();
1083 for (
int i = 0; i < nEdges; ++i)
1085 meshout.edges[i].vertind.clear();
1089 std::cout <<
"verts: ";
1092 for (
int i = 0; i < count; ++i)
1094 for (
int j = 0; j < n; ++j)
1096 meshout.verts[i].coord[j] = tetout.pointlist[i * n + j];
1099 std::cout <<
"done. ";
1103 std::cout <<
"edges: ";
1105 for (
int i = 0; i < count; ++i)
1107 meshout.edges[i].vertind = {tetout.edgelist[i * 2] + INCR, tetout.edgelist[i * 2 + 1] + INCR};
1108 for (
int j = 0; j < 2; ++j)
1110 meshout.verts[tetout.edgelist[i * 2 + j] + DEINCR].edgeind.push_back(i + 1);
1113 std::cout <<
"done. ";
1116 std::cout <<
"volus: ";
1119 for (
int i = 0; i < count; ++i)
1121 for (
int j = 0; j < n; ++j)
1123 meshout.volus[i].surfind.push_back(tetout.tet2facelist[i * n + j] + INCR);
1124 meshout.surfs[tetout.tet2facelist[i * n + j] + DEINCR].voluind.push_back(i + 1);
1127 for (
int i = 0; i < nSurfs; ++i)
1129 if (meshout.surfs[i].voluind.size() == 1)
1131 meshout.surfs[i].voluind.push_back(0);
1134 std::cout <<
"done. ";
1137 std::cout <<
"surfs: ";
1140 for (
int i = 0; i < count; ++i)
1142 for (
int j = 0; j < n; ++j)
1144 meshout.surfs[i].edgeind.push_back(tetout.face2edgelist[i * n + j] + INCR);
1145 meshout.edges[tetout.face2edgelist[i * n + j] + DEINCR].surfind.push_back(i + 1);
1148 std::cout <<
"done. ";
1151 std::cout <<
"finishing: ";
1152 for (
int i = 0; i < nVolus; ++i)
1154 meshout.volus[i].target = (double(rand() % 1000001) / 1000000);
1155 meshout.volus[i].fill = meshout.volus[i].target;
1156 meshout.volus[i].error = meshout.volus[i].target;
1158 meshout.TightenConnectivity();
1159 meshout.PrepareForUse();
1161 meshout.TestConnectivityBiDir(__PRETTY_FUNCTION__);
1163 std::cout <<
"finished conversion. ";
1164 std::cout << std::endl;
1184 meshdomain.Init(0, 0, 0, 0);
1185 meshdomain.PrepareForUse();
1186 meshgeom.PrepareForUse();
1188 tetgen::internal::Mesh2TetgenioPoints(meshgeom, meshdomain, tetinPts);
1194 std::cout << std::endl <<
"__________________________________________________" << std::endl;
1195 std::cout << std::endl
1196 <<
" TetGen start (cmd: " << switches <<
")" << std::endl
1197 <<
"__________________________________________________" << std::endl;
1198 std::cout <<
"____ in ";
1203 std::cout <<
"____ addin ";
1204 addin->displaystats();
1208 std::cout <<
"____ bgmin ";
1209 bgmin->displaystats();
1211 std::cout <<
"___________________________________" << std::endl;
1213 auto meshout = tetrahedralize(switches, in, out, addin, bgmin);
1214 std::cout <<
"___________________________________" << std::endl;
1215 std::cout <<
"____ out ";
1216 out->displaystats();
1217 std::cout << std::endl <<
"__________________________________________________" << std::endl;
1218 std::cout << std::endl
1219 <<
" TetGen end" << std::endl
1220 <<
"__________________________________________________" << std::endl;
1224 std::vector<bool> tetgen::voronoi::Points2VoroAndTetmesh(
const std::vector<double> &vecPts,
mesh &voroMesh,
1234 std::vector<int> voroPts;
1235 std::vector<bool> tetSurfInVoro;
1236 std::vector<double> lowerB, upperB;
1238 tetgen::input::POINTGRIDS(ptsMesh, tetinV, inparam,
true);
1240 rsvstetrahedralize(cmd.c_str(), &tetinV, &tetoutV);
1241 voroMesh = tetgen::output::VORO2MESH(tetoutV);
1243 lowerB.assign(3, 0.0);
1244 upperB.assign(3, 0.0);
1245 for (
int i = 0; i < 3; ++i)
1252 voroMesh.TestConnectivityBiDir(__PRETTY_FUNCTION__);
1253 voroMesh.CropAtBoundary(lowerB, upperB);
1254 voroMesh.TightenConnectivity();
1255 voroMesh.OrderEdges();
1256 voroMesh.SetBorders();
1258 TriangulateAllFaces(voroMesh);
1259 voroMesh.PrepareForUse();
1260 voroMesh.TightenConnectivity();
1261 voroMesh.OrderEdges();
1262 voroMesh.SetBorders();
1265 std::vector<int> vertPerSubDomain;
1268 tetgen::input::RSVSGRIDS(voroMesh, tetinT, inparam);
1270 int nInternalLayers = 0;
1278 cmd =
"QpqminnefO9/7";
1281 rsvstetrahedralize(cmd.c_str(), &tetinT, &tetoutT, &tetinSupport);
1283 catch (exception
const &ex)
1285 std::cerr << std::endl <<
"Input points: ";
1286 DisplayVector(vecPts);
1287 std::cerr << std::endl;
1289 tetinT.save_poly(
"dbg/tetgen_error");
1290 tetinT.save_nodes(
"dbg/tetgen_error");
1291 voroMesh.displight();
1296 INCR = tetoutT.firstnumber ? 0 : 1;
1298 for (
int i = 0; i < tetoutT.numberoftrifaces; ++i)
1300 if (tetoutT.trifacemarkerlist[i] != 0)
1302 for (
int j = 0; j < 3; ++j)
1304 voroPts.push_back(tetoutT.trifacelist[i * 3 + j] + INCR);
1310 tetSurfInVoro.reserve(tetoutT.numberoftrifaces);
1312 for (
int i = 0; i < tetoutT.numberoftrifaces; ++i)
1314 tetSurfInVoro.push_back(tetoutT.trifacemarkerlist[i] != 0);
1317 return (tetSurfInVoro);
1320 std::vector<bool> tetgen::voronoi::BoundaryFacesFromPoints(
const mesh &meshin,
const std::vector<int> &boundaryPts)
1327 std::vector<bool> boundaryFaces, boundaryVertsLog;
1328 std::vector<int> tempVerts;
1330 nVerts = meshin.verts.size();
1331 nSurfs = meshin.surfs.size();
1333 boundaryVertsLog.assign(nVerts,
false);
1334 boundaryFaces.assign(nSurfs,
false);
1335 int count = boundaryPts.size();
1336 for (
int i = 0; i < count; ++i)
1338 boundaryVertsLog[meshin.verts.find(boundaryPts[i])] =
true;
1340 for (
int i = 0; i < nSurfs; ++i)
1343 meshin.surfs(i)->OrderedVerts(&meshin, tempVerts);
1344 bool isBound =
true;
1345 for (
auto j : tempVerts)
1347 isBound = isBound && boundaryVertsLog[meshin.verts.find(j)];
1353 boundaryFaces[i] = isBound;
1355 return boundaryFaces;
1358 void tetgen::io_safe::allocate()
1361 if (this->numberofpoints > 0)
1363 this->pointlist =
new REAL[this->numberofpoints * 3];
1364 this->pointattributelist =
new REAL[this->numberofpoints * this->numberofpointattributes];
1365 this->pointmtrlist =
new REAL[this->numberofpoints * this->numberofpointmtrs];
1366 this->pointmarkerlist =
new int[this->numberofpoints];
1369 if (this->numberoftetrahedra > 0)
1371 this->tetrahedronlist =
new int[this->numberoftetrahedra * this->numberofcorners];
1372 this->tetrahedronattributelist =
new REAL[this->numberoftetrahedra];
1373 this->tetrahedronvolumelist =
new REAL[this->numberoftetrahedra * this->numberoftetrahedronattributes];
1377 if (this->numberoffacets > 0)
1379 this->facetlist =
new tetgenio::facet[this->numberoffacets];
1380 this->facetmarkerlist =
new int[this->numberoffacets];
1381 for (
int i = 0; i < this->numberoffacets; ++i)
1383 this->facetlist[i].numberofpolygons = 0;
1384 this->facetlist[i].numberofholes = 0;
1388 if (this->numberoffacetconstraints > 0)
1391 this->facetconstraintlist =
new REAL[this->numberoffacetconstraints * 2];
1394 if (this->numberofholes > 0)
1396 this->holelist =
new REAL[this->numberofholes * 3];
1400 if (this->numberofregions > 0)
1402 this->regionlist =
new REAL[this->numberofregions * 5];
1406 if (this->numberofsegmentconstraints > 0)
1408 this->segmentconstraintlist =
new REAL[this->numberofsegmentconstraints * 3];
1411 if (this->numberoftrifaces > 0)
1413 this->trifacelist =
new int[this->numberoftrifaces * 3];
1414 this->trifacemarkerlist =
new int[this->numberoftrifaces];
1415 this->o2facelist =
new int[this->numberoftrifaces * 3];
1416 this->face2tetlist =
new int[this->numberoftrifaces * 2];
1420 if (this->numberofedges > 0)
1422 this->edgelist =
new int[this->numberofedges * 2];
1423 this->edgemarkerlist =
new int[this->numberofedges];
1424 this->o2edgelist =
new int[this->numberofedges];
1425 this->edge2tetlist =
new int[this->numberofedges];
1426 this->face2edgelist =
new int[this->numberofedges * 3];
1430 if (this->numberofvedges || this->numberofvpoints || this->numberofvcells || this->numberofvfacets)
1432 std::cerr <<
"Warning : tetgen::io_safe::allocate() does not support "
1438 void tetgen::io_safe::allocatefacet(
int fIndex)
1440 if (fIndex < this->numberoffacets)
1442 if (this->facetlist[fIndex].numberofpolygons > 0)
1444 this->facetlist[fIndex].polygonlist =
new tetgenio::polygon[this->facetlist[fIndex].numberofpolygons];
1448 this->facetlist[fIndex].polygonlist = (tetgenio::polygon *)NULL;
1450 if (this->facetlist[fIndex].numberofholes > 0)
1452 this->facetlist[fIndex].holelist =
new REAL[this->facetlist[fIndex].numberofholes];
1456 this->facetlist[fIndex].holelist = (REAL *)NULL;
1461 std::cerr <<
"Error: Index passed to facet allocation out "
1466 void tetgen::io_safe::allocatefacetpolygon(
int fIndex,
int pIndex)
1468 if (fIndex < this->numberoffacets)
1470 if (pIndex < this->facetlist[fIndex].numberofpolygons)
1472 if (this->facetlist[fIndex].polygonlist[pIndex].numberofvertices > 0)
1474 this->facetlist[fIndex].polygonlist[pIndex].vertexlist =
1475 new int[this->facetlist[fIndex].polygonlist[pIndex].numberofvertices];
1479 this->facetlist[fIndex].polygonlist[pIndex].vertexlist = (
int *)NULL;
1484 std::cerr <<
"Error: Index passed to polygon allocation out "
1491 std::cerr <<
"Error: Index passed to polygon allocation "
1492 "for facet out of range"
1496 void tetgen::io_safe::allocatefacet(
int fIndex,
int numPoly)
1501 if (fIndex < this->numberoffacets)
1503 this->facetlist[fIndex].numberofpolygons = numPoly;
1504 this->allocatefacet(fIndex);
1508 std::cerr <<
"Error: Index passed to facet allocation out "
1513 void tetgen::io_safe::allocatefacetpolygon(
int fIndex,
int pIndex,
int numVerts)
1515 if (fIndex < this->numberoffacets)
1517 if (pIndex < this->facetlist[fIndex].numberofpolygons)
1519 this->facetlist[fIndex].polygonlist[pIndex].numberofvertices = numVerts;
1520 this->allocatefacetpolygon(fIndex, pIndex);
1524 std::cerr <<
"Error: Index passed to polygon allocation out "
1531 std::cerr <<
"Error: Index passed to polygon allocation "
1532 "for facet out of range"
1536 void tetgen::io_safe::SpecifyTetPointMetric(
int startPnt,
int numPnt,
const std::vector<double> &mtrs)
1542 int count = int(mtrs.size()) < this->numberofpointmtrs ? mtrs.size() : this->numberofpointmtrs;
1544 if ((startPnt + numPnt) > this->numberofpoints)
1548 else if (startPnt < 0)
1553 for (
int i = startPnt; i < startPnt + numPnt; ++i)
1555 for (
int j = 0; j < count; ++j)
1557 this->pointmtrlist[(i * this->numberofpointmtrs) + j] = mtrs[j];
1562 void tetgen::io_safe::SpecifyIndividualTetPointMetric(
int startPnt,
int numPnt,
const std::vector<double> &mtrs)
1568 if ((startPnt + numPnt) > this->numberofpoints)
1572 else if (startPnt < 0)
1576 else if (numPnt * this->numberofpointmtrs !=
int(mtrs.size()))
1579 "the number of point metrics");
1581 int count = mtrs.size();
1582 for (
int i = 0; i < count; ++i)
1584 this->pointmtrlist[(startPnt * this->numberofpointmtrs) + i] = mtrs[i];
1587 void tetgen::io_safe::SpecifyTetFacetMetric(
int startPnt,
int numPnt,
int marker)
1593 if ((startPnt + numPnt) > this->numberoffacets)
1597 else if (startPnt < 0)
1602 for (
int i = startPnt; i < startPnt + numPnt; ++i)
1604 this->facetmarkerlist[i] = marker;
1608 void tetgen::io_safe::displaystats()
1610 std::cout <<
"tetrahedralisation stats: " << std::endl;
1611 std::cout <<
"points " << this->numberofpoints <<
", ";
1612 std::cout <<
"numberofpointmtrs " << this->numberofpointmtrs <<
", ";
1613 std::cout <<
"tetrahedra " << this->numberoftetrahedra <<
", ";
1614 std::cout <<
"facets " << this->numberoffacets <<
", ";
1615 std::cout <<
"facetconstraints " << this->numberoffacetconstraints <<
", ";
1616 std::cout << std::endl;
1617 std::cout <<
"holes " << this->numberofholes <<
", ";
1618 std::cout <<
"regions " << this->numberofregions <<
", ";
1619 std::cout <<
"segmentconstraints " << this->numberofsegmentconstraints <<
", ";
1620 std::cout <<
"trifaces " << this->numberoftrifaces <<
", ";
1621 std::cout << std::endl;
1622 std::cout <<
"edges " << this->numberofedges <<
", ";
1623 std::cout <<
"vedges " << this->numberofvedges <<
", ";
1624 std::cout <<
"vpoints " << this->numberofvpoints <<
", ";
1625 std::cout <<
"vcells " << this->numberofvcells <<
", ";
1626 std::cout <<
"vfacets " << this->numberofvfacets <<
", ";
1627 std::cout << std::endl;
1629 void tetgen::io_safe::displaypoints()
1631 for (
int j = 0; j < this->numberofpointmtrs; ++j)
1633 std::cout <<
"metric " << j <<
" :";
1634 for (
int i = 0; i < this->numberofpoints * this->numberofpointmtrs; i = i + this->numberofpointmtrs)
1636 std::cout << this->pointmtrlist[i + j] <<
" ";
1638 std::cout << std::endl;
1640 for (
int i = 0; i < this->numberoffacetconstraints * 2; ++i)
1642 std::cout << this->facetconstraintlist[i] <<
" ";
1652 j = json{{
"lowerB", p.
lowerB},
1655 {
"curvatureSmoothing", p.curvatureSmoothing},
1658 {
"generateMeshInside", p.generateMeshInside},
1659 {
"command", p.command}};
1663 j.at(
"lowerB").get_to(p.
lowerB);
1664 j.at(
"upperB").get_to(p.
upperB);
1665 p.
surfedgelengths = j.at(
"surfedgelengths").get<std::array<double, 2>>();
1666 j.at(
"curvatureSmoothing").get_to(p.curvatureSmoothing);
1667 p.
edgelengths = j.at(
"edgelengths").get<std::vector<double>>();
1669 j.at(
"generateMeshInside").get_to(p.generateMeshInside);
1670 p.command = j.at(
"command").get<std::string>();
1673 void tetgen::apiparam::ReadJsonString(
const std::string &jsonStr)
1677 json j = json::parse(jsonStr);
1678 json jparam = *
this;
1684 catch (std::exception
const &ex)
1689 rsvsjson::flatupdate(jparam, j,
false,
false);
1693 catch (std::exception
const &ex)
1696 " string into tetgen parameters: \n") +
1704 void tetgen::test::LoadData(
mesh &snakeMesh,
mesh &voluMesh,
snake &snakein,
mesh &triMesh)
1712 loadErrors += snakeMesh.read(
"../TESTOUT/testtetgen/SnakeMesh_181205T193158_sphere2.msh");
1713 loadErrors += voluMesh.read(
"../TESTOUT/testtetgen/VoluMesh_181205T193158_sphere2.msh");
1714 loadErrors += snakein.read(
"../TESTOUT/testtetgen/Snake_181205T193158_sphere2.3snk");
1719 snakein.SetSnakeMesh(&snakeMesh);
1721 snakeMesh.PrepareForUse();
1724 voluMesh.PrepareForUse();
1727 snakein.PrepareForUse();
1729 snakein.AssignInternalVerts();
1731 snakeMesh.AddParent(&voluMesh);
1733 triRSVS.stattri.clear();
1734 triRSVS.trivert.clear();
1735 triRSVS.PrepareForUse();
1736 TriangulateMesh(snakeMesh, triRSVS);
1737 TriangulateSnake(snakein, triRSVS);
1738 triRSVS.PrepareForUse();
1739 triRSVS.CalcTriVertPos();
1740 MaintainTriangulateSnake(triRSVS);
1742 MeshTriangulation(triMesh, snakein.snakeconn, triRSVS.dynatri, triRSVS.trivert);
1744 triMesh.PrepareForUse();
1745 triMesh.OrderEdges();
1746 triMesh.TestConnectivityBiDir(__PRETTY_FUNCTION__);
1752 int tetgen::test::api()
1772 std::cout <<
"Assignement passed " << std::endl;
1780 "/edgelengths/2":2.0
1794 std::cout <<
"Constructor passed " << std::endl;
1799 "working for vector beyond bounds");
1800 std::cerr <<
"edgelengths.size " << p1.
edgelengths.size() << std::endl;
1805 std::cout <<
"Constructor passed " << std::endl;
1812 int tetgen::test::CFD()
1818 mesh snakeMesh, voluMesh, triMesh;
1823 inparam.
lowerB = {-15.0, -15.0, -15.0};
1824 inparam.
upperB = {15.0, 15.0, 15.0};
1827 tetgen::test::LoadData(snakeMesh, voluMesh, snakein, triMesh);
1828 tetgen::input::RSVS2CFD(snakein, tetin, inparam);
1830 tetin.save_nodes(
"../TESTOUT/testtetgen/rsvs_3cell_2body");
1831 tetin.save_poly(
"../TESTOUT/testtetgen/rsvs_3cell_2body");
1836 inparam.command =
"Qpkqm";
1837 rsvstetrahedralize(inparam.command.c_str(), &tetin, &tetout);
1843 std::cout <<
"Finished the tettgen process " << std::endl;
1845 catch (exception
const &ex)
1847 cerr <<
"Exception: " << ex.what() << endl;
1853 int tetgen::test::call()
1858 mesh meshdomain, meshtet, meshvoro, meshtet2;
1860 std::array<std::array<double, 2>, 3> dimDomain;
1865 tecout.OpenFile(
"../TESTOUT/trianglemeshconv.plt");
1866 inparam.
lowerB = {-0.0, -0.0, -0.0};
1867 inparam.
upperB = {1.0, 1.0, 1.0};
1872 BuildBlockGrid({3, 1, 1}, meshdomain);
1873 dimDomain[0] = {0, 3.0};
1875 dimDomain[1] = {0, 1.0};
1876 dimDomain[2] = {0, 1.0};
1877 meshdomain.Scale(dimDomain);
1878 meshdomain.PrepareForUse();
1879 tecout.PrintMesh(meshdomain);
1881 tetgen::input::RSVSGRIDS(meshdomain, tetin, inparam);
1883 tetin.save_nodes(
"../TESTOUT/testtetgen/rsvs_3cell_grid");
1884 tetin.save_poly(
"../TESTOUT/testtetgen/rsvs_3cell_grid");
1889 inparam.command =
"Qpkqnnvefm";
1890 rsvstetrahedralize(inparam.command.c_str(), &tetin, &tetout);
1895 std::cout <<
"Finished the tettgen process " << std::endl;
1897 tecout.PrintMesh(meshtet);
1899 std::cout <<
" Meshed the tetrahedralization" << std::endl;
1900 tetgen::input::POINTGRIDS(meshtet, tetin3, inparam);
1901 inparam.command =
"Qv";
1902 rsvstetrahedralize(inparam.command.c_str(), &tetin3, &tetout3);
1903 meshvoro = tetgen::output::VORO2MESH(tetout3);
1905 tecout.PrintMesh(meshvoro);
1906 tecout.PrintMesh(meshvoro, 0, 0, rsvs3d::constants::tecplot::line);
1907 tecout.PrintMesh(meshvoro, 0, 0, rsvs3d::constants::tecplot::point);
1908 std::cout <<
" Meshed the voronization" << std::endl;
1911 meshvoro.PrepareForUse();
1913 std::vector<int> subs;
1914 subs = ConcatenateVectorField(meshvoro.volus, &volu::surfind, 0, meshvoro.volus.size());
1915 std::cout <<
"Number of surfs " << subs.size() << std::endl;
1918 std::cout <<
"Number of surfs " << subs.size() << std::endl;
1919 inparam.command =
"Qpkqnnefm";
1920 tetgen::input::RSVSGRIDS(meshvoro, tetin2, inparam);
1922 tetin2.save_nodes(
"../TESTOUT/testtetgen/rsvs_voro_grid");
1923 tetin2.save_poly(
"../TESTOUT/testtetgen/rsvs_voro_grid");
1925 rsvstetrahedralize(inparam.command.c_str(), &tetin2, &tetout2);
1926 std::cout <<
"Finished the tettgen process " << std::endl;
1928 tecout.PrintMesh(meshtet2);
1930 catch (exception
const &ex)
1932 cerr <<
"Exception: " << ex.what() << endl;
1937 int tetgen::test::RSVSVORO()
1939 std::vector<double> vecPts, vecPts2;
1940 mesh vosMesh, snakMesh;
1944 const char *tecoutStr =
"../TESTOUT/rsvs_voro.plt";
1945 vector<int> numCells = {0, 1, 2, 3, 4, 5, 10, 20, 100, 1000};
1946 vector<double> numEdge = {0.05, 0.1, 0.3};
1948 tecout.OpenFile(tecoutStr);
1950 for (
auto i : numCells)
1952 for (
int k = i2 * 4; k < i * 4; ++k)
1954 vecPts2.push_back(
double(abs(rand()) % 32767) / 32767.0);
1958 for (
int k = 0; k < 8; ++k)
1960 vecPts.push_back((k % 2));
1961 vecPts.push_back(((k / 2) % 2));
1962 vecPts.push_back(((k / 4) % 2));
1963 vecPts.push_back(0);
1965 for (
auto j : numEdge)
1967 nErrors += tetgen::test::RSVSVOROFunc(vecPts, j, tecoutStr);
1975 int tetgen::test::RSVSVOROFunc_contain(
int nPts,
double distanceTol,
const char *tecoutStr)
1977 std::vector<double> vecPts;
1978 mesh vosMesh, snakMesh, meshPts;
1983 cout <<
"__________________________________________________" << endl;
1984 cout <<
"Start Voronoi mesh generation for " << nPts <<
" points" << endl;
1985 cout <<
"__________________________________________________" << endl;
1986 for (
int i = 0; i < nPts * 4; ++i)
1988 vecPts.push_back(
double(abs(rand()) % 32767) / 32767.0);
1990 for (
int i = 0; i < 8; ++i)
1992 vecPts.push_back((i % 2));
1993 vecPts.push_back(((i / 2) % 2));
1994 vecPts.push_back(((i / 4) % 2));
1995 vecPts.push_back(0);
1998 tecout.OpenFile(tecoutStr,
"a");
2000 inparam.
lowerB = {-0.0, -0.0, -0.0};
2001 inparam.
upperB = {1.0, 1.0, 1.0};
2009 meshPts.Init(nPts + 8, 0, 0, 0);
2010 meshPts.PopulateIndices();
2011 for (
int i = 0; i < nPts + 8; ++i)
2013 meshPts.verts[i].coord.assign(vecPts.begin() + i * 4, vecPts.begin() + i * 4 + 3);
2015 meshPts.PrepareForUse();
2017 int nVecMap = vecMap.size();
2018 for (
int i = 0; i < nVecMap; ++i)
2020 std::cout << snakMesh.ParentElementIndex(vecMap[i]) <<
" ";
2021 tecout.PrintMesh(vosMesh, nPts * 3 + 1, i, 5, {snakMesh.ParentElementIndex(vecMap[i])});
2022 tecout.PrintMesh(snakMesh, nPts * 3 + 2, i, 5, {vecMap[i]});
2023 tecout.PrintMesh(meshPts, nPts * 3 + 3, i, rsvs3d::constants::tecplot::point, {i + 1});
2025 cout <<
"__________________________________________________" << endl;
2027 catch (exception
const &ex)
2029 cerr <<
"Exception: " << ex.what() << endl;
2030 cerr <<
"for " << __PRETTY_FUNCTION__ <<
"with nPoints = " << nPts << endl;
2036 int tetgen::test::RSVSVOROFunc(
const std::vector<double> &vecPts,
double distanceTol,
const char *tecoutStr)
2039 int nPts = vecPts.size() / 4 - 8;
2040 mesh vosMesh, snakMesh, meshPts;
2045 cout <<
"__________________________________________________" << endl;
2046 cout <<
"Start Voronoi mesh generation for " << nPts <<
" points" << endl;
2047 cout <<
"__________________________________________________" << endl;
2049 tecout.OpenFile(tecoutStr,
"a");
2051 inparam.
lowerB = {-0.0, -0.0, -0.0};
2052 inparam.
upperB = {1.0, 1.0, 1.0};
2057 tecout.PrintMesh(snakMesh, 1, nPts + distanceTol);
2058 tecout.PrintMesh(vosMesh, 2, nPts + distanceTol);
2059 meshPts.Init(nPts + 8, 0, 0, 0);
2060 meshPts.PopulateIndices();
2061 for (
int i = 0; i < nPts + 8; ++i)
2063 meshPts.verts[i].coord.assign(vecPts.begin() + i * 4, vecPts.begin() + i * 4 + 3);
2065 meshPts.PrepareForUse();
2066 tecout.PrintMesh(meshPts, 3, nPts + distanceTol, rsvs3d::constants::tecplot::point);
2067 cout <<
"__________________________________________________" << endl;
2069 catch (exception
const &ex)
2071 cerr <<
"Exception: " << ex.what() << endl;
2072 cerr <<
"for " << __PRETTY_FUNCTION__ <<
"with nPoints = " << nPts << endl;
2078 int tetgen::test::RSVSVORO_Contain()
2080 std::vector<double> vecPts;
2081 mesh vosMesh, snakMesh;
2085 const char *tecoutStr =
"../TESTOUT/rsvs_voro_contain.plt";
2086 vector<int> numCells = {
2090 vector<double> numEdge = {
2096 tecout.OpenFile(tecoutStr);
2098 for (
auto i : numCells)
2100 for (
auto j : numEdge)
2102 nErrors += tetgen::test::RSVSVOROFunc_contain(i, j, tecoutStr);
Provide std::vector container with hashed index mapping.
Class for an edge object in a mesh.
std::vector< int > VertexInVolume(const std::vector< double > testVertices, int sizeVert=3) const
Finds for each vertex, the volume object containing it.
void OrientFaces()
Orients either surfaces or edges depending on the dimensionality of the object.
Class for surface object in a mesh.
double distanceTol
Distance tolerance.
std::vector< double > edgelengths
Controls the edgelengths at regular intervals.
std::array< double, 2 > surfedgelengths
Controls the surface edgelengths in CFD in the order: {point of lowest curvature, point of highest cu...
std::array< double, 3 > lowerB
Lower domain bound.
std::array< double, 3 > upperB
Upper domain bound.
Class for memory safe interface with tetgen.h.
Class for a vertex in a mesh.
Provides all the mesh tools used for the generation of 3D grids and geometries.
mesh Points2Mesh(const std::vector< double > &vecPts, int nProp=3)
Takes in a set of points and returns a mesh of points ready for voronisation.
Tools for the mathematical processing of meshes.
std::vector< double > CalculateVertexCurvature(const mesh &meshin, int smoothingSteps)
Calculates the vertex curvature.
mesh BuildCutCellDomain(const std::array< double, 3 > &outerLowerB, const std::array< double, 3 > &outerUpperB, const std::array< double, 3 > &innerLowerB, const std::array< double, 3 > &innerUpperB, int nSteps, std::vector< int > &vertPerSubDomain)
Builds a series of domains with different edge properties controlling the interpolation of the metric...
std::vector< double > VolumeInternalLayers(const mesh &meshin, int nLayers)
Returns points on edges between volume pseudo centroid and vertices.
std::vector< double > CalculateVertexMaxEdgeLength(const mesh &meshin)
Calculates the vertex maximum edge length.
void PrepareSnakeForCFD(const snake &snakein, double distanceTol, mesh &meshgeom, std::vector< double > &holeCoords)
Prepares the snake to be used for CFD, removes duplicate points and triangulates it.
Tools for the refinement and coarsening of meshes.
void CoarsenMesh(const mesh &meshchild, mesh &newparent, const std::vector< int > &elmMapping)
Provide tecplot file formating for mesh and snake outputs.
Interface between the RSVS project and the JSON for Modern C++ library.
Provides the core restricted surface snake container.
Interface between the RSVS project and tetgen.
mesh TET2MESH(tetgen::io_safe &tetout)
Translates a tetgen output to the RSVS native mesh format.
std::array< std::array< double, 3 >, 2 > dombounds
Type defining domain boundaries.
void SU2(const char *fileName, const tetgenio &tetout)
std::vector< int > RSVSVoronoiMesh(const std::vector< double > &vecPts, mesh &vosMesh, mesh &snakMesh, tetgen::apiparam &inparam)
Genrates Snaking and VOS RSVS meshes from the voronoi diagram of a set of points.
void SnakeToSU2(const snake &snakein, const std::string &fileName, tetgen::apiparam &inparam)
Genrates an SU2 mesh file from a snake.
void GenerateInternalPoints(const mesh &meshin, int nLevels, tetgen::io_safe &tetinPts)
Generate points inside volume cells of a mesh.
Provides a triangulation for snake and meshes.
Generation of cartesian grids.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_LOGIC(M)
Throw a logic_error.
#define RSVS3D_ERROR_NOTHROW(M)
Generic rsvs warning.
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.