59 x.setSize(sz+
y.size());
132 void Foam::snappySnapDriver::smoothAndConstrain
134 const bitSet& isPatchMasterEdge,
143 for (label avgIter = 0; avgIter < 20; avgIter++)
164 forAll(pointEdges, pointi)
166 const labelList& pEdges = pointEdges[pointi];
168 label nConstraints = constraints[pointi].
first();
170 if (nConstraints <= 1)
174 label edgei = pEdges[i];
176 if (isPatchMasterEdge[edgei])
178 label nbrPointi = edges[edgei].otherVertex(pointi);
179 if (constraints[nbrPointi].first() >= nConstraints)
181 dispSum[pointi] += disp[nbrPointi];
209 forAll(constraints, pointi)
211 if (dispCount[pointi] > 0)
216 *(disp[pointi] + dispSum[pointi]/dispCount[pointi]);
223 void Foam::snappySnapDriver::calcNearestFace
236 const fvMesh&
mesh = meshRefiner_.mesh();
237 const refinementSurfaces& surfaces = meshRefiner_.surfaces();
252 faceSurfaceNormal.setSize(
pp.size());
253 faceSurfaceNormal =
Zero;
254 faceSurfaceGlobalRegion.setSize(
pp.size());
255 faceSurfaceGlobalRegion = -1;
272 const PtrList<surfaceZonesInfo>& surfZones = surfaces.surfZones();
276 label zoneSurfi = zonedSurfaces[i];
278 const wordList& faceZoneNames = surfZones[zoneSurfi].faceZoneNames();
281 DynamicList<label> ppFaces;
282 DynamicList<label> meshFaces;
283 DynamicField<point> fc;
284 forAll(faceZoneNames, fzi)
286 const word& faceZoneName = faceZoneNames[fzi];
291 <<
"Problem. Cannot find zone " << faceZoneName
295 const bitSet isZonedFace(
mesh.
nFaces(), fZone);
297 ppFaces.reserve(ppFaces.capacity()+fZone.size());
298 meshFaces.reserve(meshFaces.capacity()+fZone.size());
299 fc.reserve(meshFaces.capacity()+fZone.size());
303 if (isZonedFace[
pp.addressing()[i]])
305 snapSurf[i] = zoneSurfi;
307 meshFaces.append(
pp.addressing()[i]);
308 fc.append(ppFaceCentres[i]);
317 List<pointIndexHit> hitInfo;
321 surfaces.findNearestRegion
334 if (hitInfo[hiti].hit())
336 label facei = ppFaces[hiti];
337 faceDisp[facei] = hitInfo[hiti].point() - fc[hiti];
338 faceSurfaceNormal[facei] = hitNormal[hiti];
339 faceSurfaceGlobalRegion[facei] = surfaces.globalRegion
347 static label nWarn = 0;
352 <<
"Did not find surface near face centre " << fc[hiti]
358 <<
"Reached warning limit " << nWarn
359 <<
". Suppressing further warnings." <<
endl;
371 DynamicList<label> ppFaces(
pp.size());
372 DynamicList<label> meshFaces(
pp.size());
373 DynamicField<point> fc(
pp.size());
376 if (snapSurf[i] == -1)
379 meshFaces.append(
pp.addressing()[i]);
380 fc.append(ppFaceCentres[i]);
386 List<pointIndexHit> hitInfo;
390 surfaces.findNearestRegion
403 if (hitInfo[hiti].hit())
405 label facei = ppFaces[hiti];
406 faceDisp[facei] = hitInfo[hiti].point() - fc[hiti];
407 faceSurfaceNormal[facei] = hitNormal[hiti];
408 faceSurfaceGlobalRegion[facei] = surfaces.globalRegion
416 static label nWarn = 0;
421 <<
"Did not find surface near face centre " << fc[hiti]
428 <<
"Reached warning limit " << nWarn
429 <<
". Suppressing further warnings." <<
endl;
476 void Foam::snappySnapDriver::calcNearestFacePointProperties
484 const labelList& faceSurfaceGlobalRegion,
486 List<List<point>>& pointFaceSurfNormals,
487 List<List<point>>& pointFaceDisp,
488 List<List<point>>& pointFaceCentres,
489 List<labelList>& pointFacePatchID
492 const fvMesh&
mesh = meshRefiner_.mesh();
501 pointFaceSurfNormals.setSize(
pp.
nPoints());
516 label globalRegioni = faceSurfaceGlobalRegion[facei];
518 if (isMasterFace[
pp.addressing()[facei]] && globalRegioni != -1)
525 List<point>& pNormals = pointFaceSurfNormals[pointi];
526 pNormals.setSize(nFaces);
527 List<point>& pDisp = pointFaceDisp[pointi];
528 pDisp.setSize(nFaces);
529 List<point>& pFc = pointFaceCentres[pointi];
531 labelList& pFid = pointFacePatchID[pointi];
538 label globalRegioni = faceSurfaceGlobalRegion[facei];
540 if (isMasterFace[
pp.addressing()[facei]] && globalRegioni != -1)
542 pNormals[nFaces] = faceSurfaceNormal[facei];
543 pDisp[nFaces] = faceDisp[facei];
544 pFc[nFaces] =
pp.
localFaces()[facei].centre(ppLocalPoints);
545 pFid[nFaces] = globalToMasterPatch_[globalRegioni];
566 const polyPatch&
pp =
pbm[patchi];
568 if (
pp.coupled() || isA<emptyPolyPatch>(
pp))
572 label meshFacei =
pp.start()+i;
581 label meshFacei =
pp.addressing()[i];
605 const edge&
e = edges[edgei];
606 const labelList& eFaces = edgeFaces[edgei];
608 if (eFaces.size() == 1)
611 isBoundaryPoint.
set(
e[0]);
612 isBoundaryPoint.set(
e[1]);
614 else if (eFaces.size() == 2 && bafflePair[eFaces[0]] == eFaces[1])
617 isBoundaryPoint.set(
e[0]);
618 isBoundaryPoint.set(
e[1]);
632 label patchi =
patchID[bFacei];
641 label pointi = meshToPatchPoint[
f[fp]];
643 if (pointi != -1 && isBoundaryPoint.test(pointi))
645 List<point>& pNormals = pointFaceSurfNormals[pointi];
646 List<point>& pDisp = pointFaceDisp[pointi];
647 List<point>& pFc = pointFaceCentres[pointi];
648 labelList& pFid = pointFacePatchID[pointi];
656 const point& pt = ppLocalPoints[pointi];
673 pointFaceSurfNormals,
674 listPlusEqOp<point>(),
683 listPlusEqOp<point>(),
692 forAll(pointFaceCentres, pointi)
695 const point& pt = ppLocalPoints[pointi];
697 List<point>& pFc = pointFaceCentres[pointi];
708 listPlusEqOp<point>(),
712 forAll(pointFaceCentres, pointi)
715 const point& pt = ppLocalPoints[pointi];
717 List<point>& pFc = pointFaceCentres[pointi];
730 listPlusEqOp<label>(),
738 forAll(pointFaceDisp, pointi)
740 List<point>& pNormals = pointFaceSurfNormals[pointi];
741 List<point>& pDisp = pointFaceDisp[pointi];
742 List<point>& pFc = pointFaceCentres[pointi];
743 labelList& pFid = pointFacePatchID[pointi];
747 pNormals = List<point>(pNormals, visitOrder);
748 pDisp = List<point>(pDisp, visitOrder);
749 pFc = List<point>(pFc, visitOrder);
758 void Foam::snappySnapDriver::correctAttraction
760 const DynamicList<point>& surfacePoints,
761 const DynamicList<label>& surfaceCounts,
770 scalar tang = ((pt-edgePt)&edgeNormal);
774 if (order[0] < order[1])
778 vector attractD = surfacePoints[order[0]]-edgePt;
780 scalar tang2 = (attractD&edgeNormal);
782 attractD -= tang2*edgeNormal;
784 scalar magAttractD =
mag(attractD);
785 scalar fraction = magAttractD/(magAttractD+
mag(edgeOffset));
789 + ((1.0-fraction)*tang2 + fraction*tang)*edgeNormal;
790 edgeOffset = linePt-pt;
799 const List<point>& faceCentres
819 Foam::label Foam::snappySnapDriver::findNormal
821 const scalar featureCos,
823 const DynamicList<vector>& surfaceNormals
830 scalar cosAngle = (
n&surfaceNormals[j]);
834 (cosAngle >= featureCos)
835 || (cosAngle < (-1+0.001))
856 const DynamicList<vector>& surfaceNormals,
884 if (surfaceNormals.size() == 1)
892 labelList normalToPatch(surfaceNormals.size(), -1);
893 forAll(faceToNormalBin, i)
895 if (faceToNormalBin[i] != -1)
897 label&
patch = normalToPatch[faceToNormalBin[i]];
903 else if (
patch == -2)
915 forAll(normalToPatch, normali)
917 if (normalToPatch[normali] == -2)
932 void Foam::snappySnapDriver::writeStats
935 const bitSet& isPatchMasterPoint,
936 const List<pointConstraint>& patchConstraints
939 label nMasterPoints = 0;
944 forAll(patchConstraints, pointi)
946 if (isPatchMasterPoint[pointi])
950 if (patchConstraints[pointi].first() == 1)
954 else if (patchConstraints[pointi].first() == 2)
958 else if (patchConstraints[pointi].first() == 3)
965 reduce(nMasterPoints, sumOp<label>());
966 reduce(nPlanar, sumOp<label>());
967 reduce(nEdge, sumOp<label>());
968 reduce(nPoint, sumOp<label>());
969 Info<<
"total master points :" << nMasterPoints
970 <<
" of which attracted to :" <<
nl 971 <<
" feature point : " << nPoint <<
nl 972 <<
" feature edge : " << nEdge <<
nl 973 <<
" nearest surface : " << nPlanar <<
nl 974 <<
" rest : " << nMasterPoints-nPoint-nEdge-nPlanar
980 void Foam::snappySnapDriver::featureAttractionUsingReconstruction
983 const scalar featureCos,
991 const List<List<point>>& pointFaceSurfNormals,
992 const List<List<point>>& pointFaceDisp,
993 const List<List<point>>& pointFaceCentres,
996 DynamicList<point>& surfacePoints,
997 DynamicList<vector>& surfaceNormals,
1001 pointConstraint& patchConstraint
1004 patchAttraction =
Zero;
1005 patchConstraint = pointConstraint();
1007 const List<point>& pfSurfNormals = pointFaceSurfNormals[pointi];
1008 const List<point>& pfDisp = pointFaceDisp[pointi];
1009 const List<point>& pfCentres = pointFaceCentres[pointi];
1019 surfacePoints.clear();
1020 surfaceNormals.clear();
1023 faceToNormalBin.setSize(pfDisp.size());
1024 faceToNormalBin = -1;
1028 const point& fc = pfCentres[i];
1029 const vector& fSNormal = pfSurfNormals[i];
1030 const vector& fDisp = pfDisp[i];
1033 if (
magSqr(fDisp) <
sqr(snapDist[pointi]) &&
mag(fSNormal) > VSMALL)
1035 const point pt = fc + fDisp;
1038 faceToNormalBin[i] = findNormal
1045 if (faceToNormalBin[i] != -1)
1053 if (surfacePoints.size() <= 1)
1055 surfacePoints.append(pt);
1056 faceToNormalBin[i] = surfaceNormals.size();
1057 surfaceNormals.append(fSNormal);
1059 else if (surfacePoints.size() == 2)
1061 plane pl0(surfacePoints[0], surfaceNormals[0]);
1062 plane pl1(surfacePoints[1], surfaceNormals[1]);
1063 plane::ray r(pl0.planeIntersect(pl1));
1064 vector featureNormal = r.dir() /
mag(r.dir());
1066 if (
mag(fSNormal&featureNormal) >= 0.001)
1069 surfacePoints.append(pt);
1070 faceToNormalBin[i] = surfaceNormals.size();
1071 surfaceNormals.append(fSNormal);
1074 else if (surfacePoints.size() == 3)
1078 plane pl0(surfacePoints[0], surfaceNormals[0]);
1079 plane pl1(surfacePoints[1], surfaceNormals[1]);
1080 plane pl2(surfacePoints[2], surfaceNormals[2]);
1081 point p012(pl0.planePlaneIntersect(pl1, pl2));
1083 plane::ray r(pl0.planeIntersect(pl1));
1084 vector featureNormal = r.dir() /
mag(r.dir());
1085 if (
mag(fSNormal&featureNormal) >= 0.001)
1087 plane pl3(pt, fSNormal);
1088 point p013(pl0.planePlaneIntersect(pl1, pl3));
1090 if (
mag(p012-p013) > snapDist[pointi])
1093 surfacePoints.append(pt);
1094 faceToNormalBin[i] = surfaceNormals.size();
1095 surfaceNormals.append(fSNormal);
1105 const point& pt = ppLocalPoints[pointi];
1108 if (surfaceNormals.size() == 1)
1112 ((surfacePoints[0]-pt) & surfaceNormals[0])
1121 patchAttraction = d;
1124 patchConstraint.applyConstraint(surfaceNormals[0]);
1126 else if (surfaceNormals.size() == 2)
1128 plane pl0(surfacePoints[0], surfaceNormals[0]);
1129 plane pl1(surfacePoints[1], surfaceNormals[1]);
1130 plane::ray r(pl0.planeIntersect(pl1));
1134 vector d = r.refPoint()-pt;
1143 patchAttraction = d;
1146 patchConstraint.applyConstraint(surfaceNormals[0]);
1147 patchConstraint.applyConstraint(surfaceNormals[1]);
1149 else if (surfaceNormals.size() == 3)
1152 plane pl0(surfacePoints[0], surfaceNormals[0]);
1153 plane pl1(surfacePoints[1], surfaceNormals[1]);
1154 plane pl2(surfacePoints[2], surfaceNormals[2]);
1155 point cornerPt(pl0.planePlaneIntersect(pl1, pl2));
1156 vector d = cornerPt - pt;
1164 patchAttraction = d;
1167 patchConstraint.applyConstraint(surfaceNormals[0]);
1168 patchConstraint.applyConstraint(surfaceNormals[1]);
1169 patchConstraint.applyConstraint(surfaceNormals[2]);
1175 void Foam::snappySnapDriver::featureAttractionUsingReconstruction
1178 const scalar featureCos,
1185 const List<List<point>>& pointFaceSurfNormals,
1186 const List<List<point>>& pointFaceDisp,
1187 const List<List<point>>& pointFaceCentres,
1191 List<pointConstraint>& patchConstraints
1194 autoPtr<OBJstream> feStr;
1195 autoPtr<OBJstream> fpStr;
1202 meshRefiner_.mesh().time().path()
1203 /
"implicitFeatureEdge_" +
name(iter) +
".obj" 1206 Info<<
"Dumping implicit feature-edge direction to " 1207 << feStr().name() <<
endl;
1213 meshRefiner_.mesh().time().path()
1214 /
"implicitFeaturePoint_" +
name(iter) +
".obj" 1217 Info<<
"Dumping implicit feature-point direction to " 1218 << fpStr().name() <<
endl;
1222 DynamicList<point> surfacePoints(4);
1223 DynamicList<vector> surfaceNormals(4);
1226 forAll(ppLocalPoints, pointi)
1229 pointConstraint constraint;
1231 featureAttractionUsingReconstruction
1243 pointFaceSurfNormals,
1258 (constraint.first() > patchConstraints[pointi].first())
1260 (constraint.first() == patchConstraints[pointi].first())
1261 && (
magSqr(attraction) <
magSqr(patchAttraction[pointi]))
1265 patchAttraction[pointi] = attraction;
1266 patchConstraints[pointi] = constraint;
1269 const point& pt = ppLocalPoints[pointi];
1271 if (feStr && patchConstraints[pointi].first() == 2)
1273 feStr().writeLine(pt, pt+patchAttraction[pointi]);
1275 else if (fpStr && patchConstraints[pointi].first() == 3)
1277 fpStr().writeLine(pt, pt+patchAttraction[pointi]);
1284 void Foam::snappySnapDriver::stringFeatureEdges
1287 const scalar featureCos,
1294 const List<pointConstraint>& rawPatchConstraints,
1297 List<pointConstraint>& patchConstraints
1327 forAll(pointEdges, pointi)
1329 if (patchConstraints[pointi].first() == 2)
1332 const point& pt = ppLocalPoints[pointi];
1333 const labelList& pEdges = pointEdges[pointi];
1334 const vector& featVec = patchConstraints[pointi].second();
1338 bool hasPos =
false;
1339 bool hasNeg =
false;
1343 const edge&
e =
pp.
edges()[pEdges[pEdgei]];
1344 label nbrPointi =
e.otherVertex(pointi);
1346 if (patchConstraints[nbrPointi].first() > 1)
1349 const point& nbrPt = ppLocalPoints[nbrPointi];
1350 const point featPt =
1351 nbrPt + patchAttraction[nbrPointi];
1352 const scalar cosAngle = (featVec & (featPt-pt));
1365 if (!hasPos || !hasNeg)
1371 label bestPosPointi = -1;
1372 scalar minPosDistSqr = GREAT;
1373 label bestNegPointi = -1;
1374 scalar minNegDistSqr = GREAT;
1378 const edge&
e =
pp.
edges()[pEdges[pEdgei]];
1379 label nbrPointi =
e.otherVertex(pointi);
1383 patchConstraints[nbrPointi].first() <= 1
1384 && rawPatchConstraints[nbrPointi].first() > 1
1387 const vector& nbrFeatVec =
1388 rawPatchConstraints[pointi].second();
1390 if (
mag(featVec&nbrFeatVec) > featureCos)
1397 rawPatchAttraction[nbrPointi]
1400 const point featPt =
1402 ppLocalPoints[nbrPointi]
1403 + rawPatchAttraction[nbrPointi];
1404 const scalar cosAngle =
1405 (featVec & (featPt-pt));
1409 if (!hasPos && d2 < minPosDistSqr)
1412 bestPosPointi = nbrPointi;
1417 if (!hasNeg && d2 < minNegDistSqr)
1420 bestNegPointi = nbrPointi;
1427 if (bestPosPointi != -1)
1437 patchAttraction[bestPosPointi] =
1438 0.5*rawPatchAttraction[bestPosPointi];
1439 patchConstraints[bestPosPointi] =
1440 rawPatchConstraints[bestPosPointi];
1444 if (bestNegPointi != -1)
1454 patchAttraction[bestNegPointi] =
1455 0.5*rawPatchAttraction[bestNegPointi];
1456 patchConstraints[bestNegPointi] =
1457 rawPatchConstraints[bestNegPointi];
1466 reduce(nChanged, sumOp<label>());
1467 Info<<
"Stringing feature edges : changed " << nChanged <<
" points" 1477 void Foam::snappySnapDriver::releasePointsNextToMultiPatch
1480 const scalar featureCos,
1486 const List<List<point>>& pointFaceCentres,
1490 const List<pointConstraint>& rawPatchConstraints,
1493 List<pointConstraint>& patchConstraints
1496 autoPtr<OBJstream> multiPatchStr;
1503 meshRefiner_.mesh().time().path()
1504 /
"multiPatch_" +
name(iter) +
".obj" 1507 Info<<
"Dumping removed constraints due to same-face" 1508 <<
" multi-patch points to " 1509 << multiPatchStr().name() <<
endl;
1514 bitSet isMultiPatchPoint(
pp.size());
1516 forAll(pointFacePatchID, pointi)
1520 ppLocalPoints[pointi],
1521 pointFacePatchID[pointi],
1522 pointFaceCentres[pointi]
1524 isMultiPatchPoint.set(pointi, multiPatchPt.hit());
1528 forAll(isMultiPatchPoint, pointi)
1530 if (isMultiPatchPoint.test(pointi))
1534 patchConstraints[pointi].first() <= 1
1535 && rawPatchConstraints[pointi].first() > 1
1538 patchAttraction[pointi] = rawPatchAttraction[pointi];
1539 patchConstraints[pointi] = rawPatchConstraints[pointi];
1562 label nMultiPatchPoints = 0;
1565 label pointi =
f[fp];
1568 isMultiPatchPoint.test(pointi)
1569 && patchConstraints[pointi].first() > 1
1572 ++nMultiPatchPoints;
1576 if (nMultiPatchPoints > 0)
1580 label pointi =
f[fp];
1583 !isMultiPatchPoint.test(pointi)
1584 && patchConstraints[pointi].first() > 1
1590 patchAttraction[pointi] =
Zero;
1591 patchConstraints[pointi] = pointConstraint();
1596 multiPatchStr().write(ppLocalPoints[pointi]);
1603 reduce(nChanged, sumOp<label>());
1604 Info<<
"Removing constraints near multi-patch points : changed " 1605 << nChanged <<
" points" <<
endl;
1613 const List<pointConstraint>& patchConstraints,
1625 for (label startFp = 0; startFp <
f.
size()-2; startFp++)
1632 endFp <
f.
size() && endFp != minFp;
1638 patchConstraints[
f[startFp]].first() >= 2
1639 && patchConstraints[
f[endFp]].first() >= 2
1642 attractIndices =
labelPair(startFp, endFp);
1648 return attractIndices;
1652 bool Foam::snappySnapDriver::isSplitAlignedWithFeature
1654 const scalar featureCos,
1656 const pointConstraint& pc0,
1658 const pointConstraint& pc1
1662 scalar magD =
mag(d);
1675 if (pc0.first() == 2 &&
mag(d & pc0.second()) > featureCos)
1679 else if (pc1.first() == 2 &&
mag(d & pc1.second()) > featureCos)
1692 bool Foam::snappySnapDriver::isConcave
1698 const scalar concaveCos
1702 scalar magN0 =
mag(n0);
1711 scalar d = (
c1-c0)&n0;
1722 scalar magN1 =
mag(n1);
1730 if ((n0&n1) < concaveCos)
1744 const scalar featureCos,
1745 const scalar concaveCos,
1746 const scalar minAreaRatio,
1750 const List<pointConstraint>& patchConstraints,
1756 DynamicField<point>& points1
1763 if (localF.size() >= 4)
1801 for (label startFp = 0; startFp < localF.size()-2; startFp++)
1803 label minFp = localF.rcIndex(startFp);
1807 label endFp = localF.fcIndex(localF.fcIndex(startFp));
1808 endFp < localF.size() && endFp != minFp;
1812 label startPti = localF[startFp];
1813 label endPti = localF[endFp];
1815 const pointConstraint& startPc = patchConstraints[startPti];
1816 const pointConstraint& endPc = patchConstraints[endPti];
1818 if (startPc.first() >= 2 && endPc.first() >= 2)
1820 if (startPc.first() == 2 || endPc.first() == 2)
1826 ppLocalPoints[startPti]+patchAttr[startPti];
1828 ppLocalPoints[endPti]+patchAttr[endPti];
1832 !isSplitAlignedWithFeature
1858 f0.setSize(endFp-startFp+1);
1860 for (label fp = startFp; fp <= endFp; fp++)
1862 f0[i0++] = localF[fp];
1866 const face compact0(
identity(f0.size()));
1869 for (label fp=1; fp < f0.size()-1; fp++)
1876 ppLocalPoints[f0.last()] + patchAttr[f0.last()]
1882 f1.setSize(localF.size()+2-f0.size());
1888 fp = localF.fcIndex(fp)
1891 f1[i1++] = localF[fp];
1893 f1[i1++] = localF[startFp];
1897 const face compact1(
identity(f1.size()));
1899 points1.append(ppLocalPoints[f1[0]] + patchAttr[f1[0]]);
1900 for (label fp=1; fp < f1.size()-1; fp++)
1903 points1.append(ppLocalPoints[
pi] + nearestAttr[
pi]);
1907 ppLocalPoints[f1.last()] + patchAttr[f1.last()]
1921 compact1.centre(points1),
1922 compact1.areaNormal(points1),
1942 const scalar area0 = f0.mag(ppLocalPoints);
1943 const scalar area1 = f1.mag(ppLocalPoints);
1947 area0/area1 >= minAreaRatio
1948 && area1/area0 >= minAreaRatio
1951 attractIndices =
labelPair(startFp, endFp);
1958 return attractIndices;
1962 void Foam::snappySnapDriver::splitDiagonals
1964 const scalar featureCos,
1965 const scalar concaveCos,
1966 const scalar minAreaRatio,
1972 const List<labelList>& pointFacePatchID,
1975 List<pointConstraint>& patchConstraints,
1977 DynamicList<label>& splitFaces,
1978 DynamicList<labelPair>& splits,
1979 DynamicList<labelPair>& splitPatches
1985 splitFaces.setCapacity(bFaces.size());
1987 splits.setCapacity(bFaces.size());
1988 splitPatches.clear();
1989 splitPatches.setCapacity(bFaces.size());
1992 DynamicField<point> facePoints0;
1993 DynamicField<point> facePoints1;
2000 findDiagonalAttraction
2022 splitFaces.append(bFaces[facei]);
2023 splits.append(
split);
2035 && patchConstraints[
f[fp]].first() >= 2
2038 patchConstraints[
f[fp]] = pointConstraint
2040 Tuple2<label, vector>
2043 nearestNormal[
f[fp]]
2046 patchAttraction[
f[fp]] = nearestAttraction[
f[fp]];
2067 for (label fp = 1; fp < f0.size()-1; fp++)
2069 const auto&
patches = pointFacePatchID[f0[fp]];
2075 for (label fp = 1; fp < f1.size()-1; fp++)
2077 const auto&
patches = pointFacePatchID[f1[fp]];
2084 if (twoPatches[0] == -1)
2089 for (label fp = 1; fp < f0.size()-1; fp++)
2091 const auto&
patches = pointFacePatchID[f0[fp]];
2095 for (
const label patchi :
patches)
2097 if (patchi != twoPatches[1])
2099 twoPatches[0] = patchi;
2106 if (twoPatches[1] == -1)
2111 for (label fp = 1; fp < f1.size()-1; fp++)
2113 const auto&
patches = pointFacePatchID[f1[fp]];
2117 for (
const label patchi :
patches)
2119 if (patchi != twoPatches[0])
2121 twoPatches[1] = patchi;
2129 if (twoPatches[0] == -1)
2131 twoPatches[0] = pointFacePatchID[f0[1]][0];
2133 if (twoPatches[1] == -1)
2135 twoPatches[1] = pointFacePatchID[f1[1]][0];
2153 void Foam::snappySnapDriver::avoidDiagonalAttraction
2156 const scalar featureCos,
2162 List<pointConstraint>& patchConstraints
2177 if (
diag[0] != -1 &&
diag[1] != -1)
2181 const label i0 =
f[
diag[0]];
2183 ppLocalPoints[i0]+patchAttraction[i0];
2184 const label i1 =
f[
diag[1]];
2186 ppLocalPoints[i1]+patchAttraction[i1];
2187 const point mid = 0.5*(pt0+pt1);
2189 const scalar cosAngle =
mag 2191 patchConstraints[i0].second()
2192 & patchConstraints[i1].second()
2201 if (cosAngle > featureCos)
2207 scalar minDistSqr = GREAT;
2210 label pointi =
f[fp];
2211 if (patchConstraints[pointi].first() <= 1)
2213 scalar distSqr = mid.distSqr(ppLocalPoints[pointi]);
2214 if (distSqr < minDistSqr)
2222 label minPointi =
f[minFp];
2223 patchAttraction[minPointi] =
2224 mid-ppLocalPoints[minPointi];
2225 patchConstraints[minPointi] = patchConstraints[
f[
diag[0]]];
2251 Foam::snappySnapDriver::findNearFeatureEdge
2253 const bool isRegionEdge,
2259 const point& estimatedPt,
2261 List<List<DynamicList<point>>>& edgeAttractors,
2262 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
2264 List<pointConstraint>& patchConstraints
2267 const refinementFeatures& features = meshRefiner_.features();
2270 List<pointIndexHit> nearEdgeInfo;
2275 features.findNearestRegionEdge
2286 features.findNearestEdge
2297 label feati = nearEdgeFeat[0];
2303 edgeAttractors[feati][nearInfo.index()].append(nearInfo.point());
2304 pointConstraint
c(Tuple2<label, vector>(2, nearNormal[0]));
2305 edgeConstraints[feati][nearInfo.index()].append(
c);
2308 patchAttraction[pointi] = nearInfo.point()-ppLocalPoints[pointi];
2309 patchConstraints[pointi] =
c;
2311 return Tuple2<label, pointIndexHit>(feati, nearInfo);
2316 Foam::snappySnapDriver::findNearFeaturePoint
2318 const bool isRegionPoint,
2324 const point& estimatedPt,
2327 List<labelList>& pointAttractor,
2328 List<List<pointConstraint>>& pointConstraints,
2330 List<List<DynamicList<point>>>& edgeAttractors,
2331 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
2334 List<pointConstraint>& patchConstraints
2337 const refinementFeatures& features = meshRefiner_.features();
2342 List<pointIndexHit> nearInfo;
2343 features.findNearestPoint
2351 label feati = nearFeat[0];
2355 const point& pt = ppLocalPoints[pointi];
2357 label featPointi = nearInfo[0].index();
2358 const point& featPt = nearInfo[0].hitPoint();
2359 scalar distSqr = featPt.distSqr(pt);
2362 label oldPointi = pointAttractor[feati][featPointi];
2364 if (oldPointi != -1)
2367 if (distSqr >= featPt.distSqr(ppLocalPoints[oldPointi]))
2376 pointAttractor[feati][featPointi] = pointi;
2377 pointConstraints[feati][featPointi].first() = 3;
2378 pointConstraints[feati][featPointi].second() =
Zero;
2381 patchAttraction[pointi] = featPt-pt;
2382 patchConstraints[pointi] = pointConstraints[feati][featPointi];
2385 patchAttraction[oldPointi] =
Zero;
2386 patchConstraints[oldPointi] = pointConstraint();
2396 ppLocalPoints[oldPointi],
2408 pointAttractor[feati][featPointi] = pointi;
2409 pointConstraints[feati][featPointi].first() = 3;
2410 pointConstraints[feati][featPointi].second() =
Zero;
2413 patchAttraction[pointi] = featPt-pt;
2414 patchConstraints[pointi] = pointConstraints[feati][featPointi];
2418 return Tuple2<label, pointIndexHit>(feati, nearInfo[0]);
2424 void Foam::snappySnapDriver::determineFeatures
2427 const scalar featureCos,
2428 const bool multiRegionFeatureSnap,
2429 const bool strictRegionFeatureSnap,
2436 const List<List<point>>& pointFaceSurfNormals,
2437 const List<List<point>>& pointFaceDisp,
2438 const List<List<point>>& pointFaceCentres,
2442 List<labelList>& pointAttractor,
2443 List<List<pointConstraint>>& pointConstraints,
2445 List<List<DynamicList<point>>>& edgeAttractors,
2446 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
2449 List<pointConstraint>& patchConstraints
2452 autoPtr<OBJstream> featureEdgeStr;
2453 autoPtr<OBJstream> missedEdgeStr;
2454 autoPtr<OBJstream> featurePointStr;
2455 autoPtr<OBJstream> missedMP0Str;
2456 autoPtr<OBJstream> missedMP1Str;
2460 featureEdgeStr.reset
2464 meshRefiner_.mesh().time().path()
2465 /
"featureEdge_" +
name(iter) +
".obj" 2468 Info<<
"Dumping feature-edge sampling to " 2469 << featureEdgeStr().name() <<
endl;
2475 meshRefiner_.mesh().time().path()
2476 /
"missedFeatureEdge_" +
name(iter) +
".obj" 2479 Info<<
"Dumping feature-edges that are too far away to " 2480 << missedEdgeStr().name() <<
endl;
2482 featurePointStr.reset
2486 meshRefiner_.mesh().time().path()
2487 /
"featurePoint_" +
name(iter) +
".obj" 2490 Info<<
"Dumping feature-point sampling to " 2491 << featurePointStr().name() <<
endl;
2497 meshRefiner_.mesh().time().path()
2498 /
"missedFeatureEdgeFromMPEdge_" +
name(iter) +
".obj" 2501 Info<<
"Dumping region-edges that are too far away to " 2502 << missedMP0Str().name() <<
endl;
2508 meshRefiner_.mesh().time().path()
2509 /
"missedFeatureEdgeFromMPPoint_" +
name(iter) +
".obj" 2512 Info<<
"Dumping region-points that are too far away to " 2513 << missedMP1Str().name() <<
endl;
2517 DynamicList<point> surfacePoints(4);
2518 DynamicList<vector> surfaceNormals(4);
2521 forAll(ppLocalPoints, pointi)
2523 const point& pt = ppLocalPoints[pointi];
2535 pointConstraint constraint;
2537 featureAttractionUsingReconstruction
2549 pointFaceSurfNormals,
2563 if (strictRegionFeatureSnap)
2570 if (constraint.first() == 1)
2572 const auto&
patches = pointFacePatchID[pointi];
2582 else if (
patches[i] != patch1)
2585 constraint.
first() = 2;
2631 (constraint.first() > patchConstraints[pointi].first())
2633 (constraint.first() == patchConstraints[pointi].first())
2634 && (
magSqr(attraction) <
magSqr(patchAttraction[pointi]))
2638 patchAttraction[pointi] = attraction;
2639 patchConstraints[pointi] = constraint;
2642 if (patchConstraints[pointi].first() == 1)
2645 if (multiRegionFeatureSnap)
2647 const point estimatedPt(pt + nearestDisp[pointi]);
2653 pointFacePatchID[pointi],
2659 if (multiPatchPt.hit())
2664 Tuple2<label, pointIndexHit> nearInfo =
2672 multiPatchPt.point(),
2687 featureEdgeStr().writeLine
2698 missedEdgeStr().writeLine
2701 multiPatchPt.point()
2708 else if (patchConstraints[pointi].first() == 2)
2713 const point estimatedPt(pt + patchAttraction[pointi]);
2718 bool hasSnapped =
false;
2719 if (multiRegionFeatureSnap)
2726 pointFacePatchID[pointi],
2731 if (multiPatchPt.hit())
2733 if (multiPatchPt.index() == 0)
2736 nearInfo = findNearFeatureEdge
2754 if (missedMP0Str && !nearInfo.second().hit())
2756 missedMP0Str().writeLine(pt, estimatedPt);
2767 nearInfo = findNearFeaturePoint
2797 if (!nearInfo.second().hit())
2799 nearInfo = findNearFeatureEdge
2818 if (missedMP1Str && !nearInfo.second().hit())
2820 missedMP1Str().writeLine(pt, estimatedPt);
2832 nearInfo = findNearFeatureEdge
2857 && patchConstraints[pointi].first() == 3
2860 featurePointStr().writeLine(pt, info.point());
2865 && patchConstraints[pointi].first() == 2
2868 featureEdgeStr().writeLine(pt, info.point());
2875 missedEdgeStr().writeLine(pt, estimatedPt);
2879 else if (patchConstraints[pointi].first() == 3)
2882 const point estimatedPt(pt + patchAttraction[pointi]);
2886 if (multiRegionFeatureSnap)
2893 pointFacePatchID[pointi],
2898 if (multiPatchPt.hit())
2901 nearInfo = findNearFeaturePoint
2923 nearInfo = findNearFeaturePoint
2947 nearInfo = findNearFeaturePoint
2969 if (featurePointStr && info.hit())
2971 featurePointStr().writeLine(pt, info.point());
2990 void Foam::snappySnapDriver::determineBaffleFeatures
2993 const bool baffleFeaturePoints,
2994 const scalar featureCos,
3001 List<labelList>& pointAttractor,
3002 List<List<pointConstraint>>& pointConstraints,
3004 List<List<DynamicList<point>>>& edgeAttractors,
3005 List<List<DynamicList<pointConstraint>>>& edgeConstraints,
3008 List<pointConstraint>& patchConstraints
3011 const fvMesh&
mesh = meshRefiner_.mesh();
3012 const refinementFeatures& features = meshRefiner_.features();
3015 List<List<point>> edgeFaceNormals(
pp.
nEdges());
3018 forAll(ppFaceNormals, facei)
3020 ppFaceNormals[facei] =
pp.
localFaces()[facei].unitNormal(ppLocalPoints);
3028 List<point>& eFc = edgeFaceNormals[edgei];
3032 label facei = eFaces[i];
3034 eFc[i] = ppFaceNormals[facei];
3050 listPlusEqOp<point>(),
3063 autoPtr<OBJstream> baffleEdgeStr;
3070 meshRefiner_.mesh().time().path()
3071 /
"baffleEdge_" +
name(iter) +
".obj" 3074 Info<<
nl <<
"Dumping baffle-edges to " 3075 << baffleEdgeStr().name() <<
endl;
3081 label nBaffleEdges = 0;
3088 forAll(edgeFaceNormals, edgei)
3090 const List<point>& efn = edgeFaceNormals[edgei];
3092 if (efn.size() == 2 && (efn[0]&efn[1]) < baffleFeatureCos)
3094 isBaffleEdge.set(edgei);
3097 pointStatus[
e[0]] = 0;
3098 pointStatus[
e[1]] = 0;
3102 baffleEdgeStr().write(
e, ppLocalPoints);
3107 reduce(nBaffleEdges, sumOp<label>());
3109 Info<<
"Detected " << nBaffleEdges
3110 <<
" baffle edges out of " 3112 <<
" edges." <<
endl;
3137 label nBafflePoints = 0;
3138 forAll(pointStatus, pointi)
3140 if (pointStatus[pointi] != -1)
3145 reduce(nBafflePoints, sumOp<label>());
3148 label nPointAttract = 0;
3149 label nEdgeAttract = 0;
3151 forAll(pointStatus, pointi)
3153 const point& pt = ppLocalPoints[pointi];
3155 if (pointStatus[pointi] == 0)
3159 Tuple2<label, pointIndexHit> nearInfo = findNearFeatureEdge
3179 if (nearInfo.second().hit())
3183 if (baffleFeaturePoints)
3185 nearInfo = findNearFeaturePoint
3206 if (nearInfo.first() != -1)
3214 else if (pointStatus[pointi] == 1)
3217 List<pointIndexHit> nearInfo;
3218 features.findNearestPoint
3226 label feati = nearFeat[0];
3232 label featPointi = nearInfo[0].index();
3233 const point& featPt = nearInfo[0].hitPoint();
3234 scalar distSqr = featPt.distSqr(pt);
3237 label oldPointi = pointAttractor[feati][featPointi];
3244 < featPt.distSqr(ppLocalPoints[oldPointi])
3248 pointAttractor[feati][featPointi] = pointi;
3249 pointConstraints[feati][featPointi].first() = 3;
3250 pointConstraints[feati][featPointi].second() =
Zero;
3253 patchAttraction[pointi] = featPt-pt;
3254 patchConstraints[pointi] =
3255 pointConstraints[feati][featPointi];
3257 if (oldPointi != -1)
3269 ppLocalPoints[oldPointi],
3294 Tuple2<label, pointIndexHit> nearInfo = findNearFeatureEdge
3309 if (nearInfo.first() != -1)
3317 reduce(nPointAttract, sumOp<label>());
3318 reduce(nEdgeAttract, sumOp<label>());
3320 Info<<
"Baffle points : " << nBafflePoints
3321 <<
" of which attracted to :" <<
nl 3322 <<
" feature point : " << nPointAttract <<
nl 3323 <<
" feature edge : " << nEdgeAttract <<
nl 3324 <<
" rest : " << nBafflePoints-nPointAttract-nEdgeAttract
3330 void Foam::snappySnapDriver::reverseAttractMeshPoints
3339 const List<labelList>& pointAttractor,
3340 const List<List<pointConstraint>>& pointConstraints,
3342 const List<List<DynamicList<point>>>& edgeAttractors,
3343 const List<List<DynamicList<pointConstraint>>>& edgeConstraints,
3346 const List<pointConstraint>& rawPatchConstraints,
3350 List<pointConstraint>& patchConstraints
3353 const refinementFeatures& features = meshRefiner_.features();
3361 treeBoundBox bb(ppLocalPoints);
3368 bb.inflate(
rndGen, 1
e-4, ROOTVSMALL);
3372 DynamicList<label> attractPoints(
pp.
nPoints());
3374 const fvMesh&
mesh = meshRefiner_.mesh();
3378 forAll(rawPatchConstraints, pointi)
3380 if (rawPatchConstraints[pointi].first() >= 2)
3382 isFeatureEdgeOrPoint[pointi] =
true;
3388 <<
" mesh points out of " 3390 <<
" for reverse attraction." <<
endl;
3398 isFeatureEdgeOrPoint,
3403 for (label nGrow = 0; nGrow < 1; nGrow++)
3405 boolList newIsFeatureEdgeOrPoint(isFeatureEdgeOrPoint);
3413 if (isFeatureEdgeOrPoint[
f[fp]])
3418 newIsFeatureEdgeOrPoint[
f[fp]] =
true;
3425 isFeatureEdgeOrPoint = newIsFeatureEdgeOrPoint;
3431 isFeatureEdgeOrPoint,
3439 forAll(isFeatureEdgeOrPoint, pointi)
3441 if (isFeatureEdgeOrPoint[pointi])
3443 attractPoints.append(pointi);
3449 <<
" mesh points out of " 3451 <<
" for reverse attraction." <<
endl;
3455 indexedOctree<treeDataPoint> ppTree
3457 treeDataPoint(ppLocalPoints, attractPoints),
3466 patchAttraction =
Zero;
3468 patchConstraints = pointConstraint();
3470 forAll(edgeAttractors, feati)
3472 const List<DynamicList<point>>& edgeAttr = edgeAttractors[feati];
3473 const List<DynamicList<pointConstraint>>& edgeConstr =
3474 edgeConstraints[feati];
3476 forAll(edgeAttr, featEdgei)
3478 const DynamicList<point>& attr = edgeAttr[featEdgei];
3482 const point& featPt = attr[i];
3492 ppTree.shapes().objectIndex(nearInfo.index());
3494 const point attraction
3497 - ppTree.shapes()[nearInfo.index()]
3504 patchConstraints[pointi].first() <= 1
3505 ||
magSqr(attraction) <
magSqr(patchAttraction[pointi])
3508 patchAttraction[pointi] = attraction;
3509 patchConstraints[pointi] = edgeConstr[featEdgei][i];
3514 static label nWarn = 0;
3519 <<
"Did not find pp point near " << featPt
3525 <<
"Reached warning limit " << nWarn
3526 <<
". Suppressing further warnings." <<
endl;
3545 forAll(pointAttractor, feati)
3547 const labelList& pointAttr = pointAttractor[feati];
3548 const List<pointConstraint>& pointConstr = pointConstraints[feati];
3550 forAll(pointAttr, featPointi)
3552 if (pointAttr[featPointi] != -1)
3554 const point& featPt = features[feati].points()[featPointi];
3566 ppTree.shapes().objectIndex(nearInfo.index());
3568 const point attraction
3571 - ppTree.shapes()[nearInfo.index()]
3577 if (patchConstraints[pointi].first() <= 1)
3579 patchAttraction[pointi] = attraction;
3580 patchConstraints[pointi] = pointConstr[featPointi];
3582 else if (patchConstraints[pointi].first() == 2)
3584 patchAttraction[pointi] = attraction;
3585 patchConstraints[pointi] = pointConstr[featPointi];
3587 else if (patchConstraints[pointi].first() == 3)
3593 <
magSqr(patchAttraction[pointi])
3596 patchAttraction[pointi] = attraction;
3597 patchConstraints[pointi] =
3598 pointConstr[featPointi];
3608 void Foam::snappySnapDriver::featureAttractionUsingFeatureEdges
3611 const bool multiRegionFeatureSnap,
3612 const bool strictRegionFeatureSnap,
3614 const bool detectBaffles,
3615 const bool baffleFeaturePoints,
3617 const bool releasePoints,
3618 const bool stringFeatures,
3619 const bool avoidDiagonal,
3621 const scalar featureCos,
3629 const List<List<point>>& pointFaceSurfNormals,
3630 const List<List<point>>& pointFaceDisp,
3631 const List<List<point>>& pointFaceCentres,
3635 List<pointConstraint>& patchConstraints
3638 const refinementFeatures& features = meshRefiner_.features();
3639 const fvMesh&
mesh = meshRefiner_.mesh();
3641 const bitSet isPatchMasterPoint
3656 List<List<DynamicList<point>>> edgeAttractors(features.size());
3657 List<List<DynamicList<pointConstraint>>> edgeConstraints
3663 label nFeatEdges = features[feati].edges().size();
3664 edgeAttractors[feati].setSize(nFeatEdges);
3665 edgeConstraints[feati].setSize(nFeatEdges);
3671 List<labelList> pointAttractor(features.size());
3672 List<List<pointConstraint>> pointConstraints(features.size());
3675 label nFeatPoints = features[feati].points().size();
3676 pointAttractor[feati].setSize(nFeatPoints, -1);
3677 pointConstraints[feati].setSize(nFeatPoints);
3682 List<pointConstraint> rawPatchConstraints(
pp.
nPoints());
3688 multiRegionFeatureSnap,
3689 strictRegionFeatureSnap,
3696 pointFaceSurfNormals,
3715 Info<<
"Raw geometric feature analysis : ";
3716 writeStats(
pp, isPatchMasterPoint, rawPatchConstraints);
3732 determineBaffleFeatures
3735 baffleFeaturePoints,
3757 Info<<
"After baffle feature analysis : ";
3758 writeStats(
pp, isPatchMasterPoint, rawPatchConstraints);
3766 reverseAttractMeshPoints
3783 rawPatchConstraints,
3793 Info<<
"Reverse attract feature analysis : ";
3800 OBJstream featureEdgeStr
3802 meshRefiner_.mesh().time().path()
3803 /
"edgeAttractors_" +
name(iter) +
".obj" 3805 Info<<
"Dumping feature-edge attraction to " 3806 << featureEdgeStr.name() <<
endl;
3808 OBJstream featurePointStr
3810 meshRefiner_.mesh().time().path()
3811 /
"pointAttractors_" +
name(iter) +
".obj" 3813 Info<<
"Dumping feature-point attraction to " 3814 << featurePointStr.name() <<
endl;
3816 forAll(patchConstraints, pointi)
3818 const point& pt = ppLocalPoints[pointi];
3819 const vector& attr = patchAttraction[pointi];
3821 if (patchConstraints[pointi].first() == 2)
3823 featureEdgeStr.writeLine(pt, pt+attr);
3825 else if (patchConstraints[pointi].first() == 3)
3827 featurePointStr.writeLine(pt, pt+attr);
3839 releasePointsNextToMultiPatch
3852 rawPatchConstraints,
3876 rawPatchConstraints,
3889 avoidDiagonalAttraction
3905 meshRefiner_.mesh().time().path()
3906 /
"patchAttraction_" +
name(iter) +
".obj",
3908 ppLocalPoints + patchAttraction
3915 void Foam::snappySnapDriver::preventFaceSqueeze
3918 const scalar featureCos,
3926 List<pointConstraint>& patchConstraints
3929 autoPtr<OBJstream> strPtr;
3936 meshRefiner_.mesh().time().path()
3937 /
"faceSqueeze_" +
name(iter) +
".obj" 3940 Info<<
"Dumping faceSqueeze corrections to " 3941 << strPtr().name() <<
endl;
3953 singleF.setSize(
f.
size());
3954 for (label i = 0; i <
f.
size(); i++)
3959 label nConstraints = 0;
3962 label pointi =
f[fp];
3963 const point& pt = ppLocalPoints[pointi];
3965 if (patchConstraints[pointi].first() > 1)
3967 points[fp] = pt + patchAttraction[pointi];
3976 if (nConstraints ==
f.
size())
3987 const point& pt = ppLocalPoints[
f[fp]];
3988 const point& nextPt = ppLocalPoints[
f.nextLabel(fp)];
3990 scalar
s = pt.distSqr(nextPt);
3999 label pointi =
f.prevLabel(maxFp);
4003 const point& pt = ppLocalPoints[pointi];
4010 patchAttraction[pointi] = nearestAttraction[pointi];
4014 strPtr().writeLine(pt, pt+patchAttraction[pointi]);
4020 scalar oldArea =
f.mag(ppLocalPoints);
4021 scalar newArea = singleF.mag(
points);
4022 if (newArea < 0.1*oldArea)
4029 scalar
s =
magSqr(patchAttraction[
f[fp]]);
4038 label pointi =
f[maxFp];
4040 patchAttraction[pointi] *= 0.5;
4051 const snapParameters& snapParams,
4052 const bool alignMeshEdges,
4053 const bool strictRegionFeatureSnap,
4055 const scalar featureCos,
4056 const scalar featureAttract,
4063 List<pointConstraint>& patchConstraints,
4065 DynamicList<label>& splitFaces,
4066 DynamicList<labelPair>& splits,
4067 DynamicList<labelPair>& splitPatches
4076 const Switch implicitFeatureAttraction = snapParams.implicitFeatureSnap();
4077 const Switch explicitFeatureAttraction = snapParams.explicitFeatureSnap();
4078 const Switch multiRegionFeatureSnap = snapParams.multiRegionFeatureSnap();
4080 Info<<
"Overriding displacement on features :" <<
nl 4081 <<
" implicit features : " << implicitFeatureAttraction <<
nl 4082 <<
" explicit features : " << explicitFeatureAttraction <<
nl 4083 <<
" multi-patch features : " << multiRegionFeatureSnap <<
nl 4086 const fvMesh&
mesh = meshRefiner_.mesh();
4090 const bitSet isPatchMasterPoint
4103 List<List<point>> pointFaceSurfNormals;
4104 List<List<point>> pointFaceDisp;
4105 List<List<point>> pointFaceCentres;
4106 List<labelList> pointFacePatchID;
4117 faceSnapDist[facei] =
max(faceSnapDist[facei], snapDist[
f[fp]]);
4140 faceSurfaceGlobalRegion
4150 calcNearestFacePointProperties
4157 faceSurfaceGlobalRegion,
4159 pointFaceSurfNormals,
4178 patchAttraction.
setSize(ppLocalPoints.size());
4179 patchAttraction =
Zero;
4181 patchConstraints.setSize(ppLocalPoints.size());
4182 patchConstraints = pointConstraint();
4184 if (implicitFeatureAttraction)
4189 featureAttractionUsingReconstruction
4199 pointFaceSurfNormals,
4209 if (explicitFeatureAttraction)
4212 bool releasePoints =
false;
4213 bool stringFeatures =
false;
4214 bool avoidDiagonal =
false;
4217 releasePoints = snapParams.releasePoints();
4218 stringFeatures = snapParams.stringFeatures();
4219 avoidDiagonal = snapParams.avoidDiagonal();
4229 featureAttractionUsingFeatureEdges
4232 multiRegionFeatureSnap,
4233 strictRegionFeatureSnap,
4235 snapParams.detectBaffles(),
4236 snapParams.baffleFeaturePoints(),
4251 pointFaceSurfNormals,
4261 if (!alignMeshEdges)
4265 degToRad(snapParams.concaveAngle())
4267 const scalar minAreaRatio = snapParams.minAreaRatio();
4269 Info<<
"Introducing face splits to avoid rotating" 4270 <<
" mesh edges. Splitting faces when" <<
nl 4271 <<
indent <<
"- angle not concave by more than " 4272 << snapParams.concaveAngle() <<
" degrees" <<
nl 4273 <<
indent <<
"- resulting triangles of similar area " 4274 <<
" (ratio within " << minAreaRatio <<
")" <<
nl 4299 Info<<
"Diagonal attraction feature correction : ";
4333 <<
" avg:" << avgPatchDisp <<
endl 4334 <<
" feature : max:" <<
gMaxMagSqr(patchAttraction)
4335 <<
" avg:" << avgPatchAttr <<
endl;
4349 forAll(patchConstraints, pointi)
4351 if (patchConstraints[pointi].first() > 1)
4354 (1.0-featureAttract)*patchDisp[pointi]
4355 + featureAttract*patchAttraction[pointi];
4363 Info<<
"Feature analysis : ";
4379 if (featureAttract < 1-0.001)
4386 const bitSet isPatchMasterEdge
4418 tangPatchDisp -= (pointNormals & patchDisp) * pointNormals;
4429 tangPatchDisp += (pointNormals & patchDisp) * pointNormals;
4436 /
"tangPatchDispConstrained_" +
name(iter) +
".obj",
4438 ppLocalPoints + tangPatchDisp
4443 (1.0-featureAttract)*smoothedPatchDisp
4444 + featureAttract*tangPatchDisp;
4448 const scalar
relax = featureAttract;
4459 minMagSqrEqOp<point>(),
4460 vector(GREAT, GREAT, GREAT)
const labelListList & pointEdges() const
Return point-edge addressing.
const labelList patchIDs(pbm.indices(polyPatchNames, true))
const polyBoundaryMesh & pbm
label nPoints() const
Number of points supporting patch faces.
const List< face_type > & localFaces() const
Return patch faces addressing into local point list.
void size(const label n)
Older name for setAddressableSize.
fileName path() const
Return path = rootPath/caseName. Same as TimePaths::path()
Ostream & indent(Ostream &os)
Indent stream.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label nPoints() const noexcept
Number of mesh points.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
void append(const T &val)
Append an element at the end of the list.
List< edge > edgeList
List of edge.
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
const labelListList & pointEdges() const
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
std::enable_if< std::is_same< bool, TypeT >::value, bool >::type set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
Unit conversion functions.
constexpr char nl
The newline '\n' character (0x0a)
bool empty() const noexcept
True if List is empty (ie, size() is zero)
UIndirectList< label > labelUIndList
UIndirectList of labels.
T & first()
Access first element of the list, position [0].
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
const labelList & patchID() const
Per boundary face label the patch index.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
T & first()
Reference to the first element of the list.
This class describes the interaction of an object (often a face) and a point. It carries the info of ...
static bitSet getMasterEdges(const polyMesh &mesh, const labelList &meshEdges)
Determine master edge for subset of edges. If coupled.
const Time & time() const
Return the top-level database.
label nFaces() const noexcept
Number of mesh faces.
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field...
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
List< labelList > labelListList
List of labelList.
const labelList & meshPoints() const
Return labelList of mesh points in patch.
const fvMesh & mesh() const
Reference to mesh.
#define forAll(list, i)
Loop across all elements in list.
label fcIndex(const label i) const noexcept
The forward circular index. The next index in the list which returns to the first at the end of the l...
Type gMaxMagSqr(const UList< Type > &f, const label comm)
A list of faces which address into the list of points.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
void clear()
Clear the list, i.e. set size to zero.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
label size() const noexcept
The number of entries in the list.
constexpr scalar pi(M_PI)
const labelListList & edgeFaces() const
Return edge-face addressing.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
label nInternalFaces() const noexcept
Number of internal faces.
virtual const faceList & faces() const
Return raw faces.
static labelList getUnnamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of unnamed surfaces (surfaces without faceZoneName)
const labelListList & pointFaces() const
Return point-face addressing.
label nEdges() const
Number of edges in patch.
refinementData transform(const tensor &, const refinementData val)
No-op rotational transform for base types.
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
static void splitFace(const face &f, const labelPair &split, face &f0, face &f1)
Helper: split face into:
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field...
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints, -1);const cellModel &hex=cellModel::ref(cellModel::HEX);labelList hexLabels(8);label activeCells=0;labelList pointMap(nPoints);forAll(pointMap, i){ pointMap[i]=i;}for(label i=0;i< nPoints;i++){ if(f[i] > 0.0) { hexLabels[0]=i;hexLabels[1]=i1tab[i];hexLabels[2]=i3tab[i1tab[i]];hexLabels[3]=i3tab[i];hexLabels[4]=i8tab[i];hexLabels[5]=i1tab[i8tab[i]];hexLabels[6]=i3tab[i1tab[i8tab[i]]];hexLabels[7]=i3tab[i8tab[i]];cellShapes[activeCells].reset(hex, hexLabels);edgeList edges=cellShapes[activeCells].edges();forAll(edges, ei) { if(edges[ei].mag(points)< SMALL) { label start=pointMap[edges[ei].start()];while(start !=pointMap[start]) { start=pointMap[start];} label end=pointMap[edges[ei].end()];while(end !=pointMap[end]) { end=pointMap[end];} label minLabel=min(start, end);pointMap[start]=pointMap[end]=minLabel;} } cellZoning[activeCells]=idreg[i];activeCells++;}}cellShapes.setSize(activeCells);cellZoning.setSize(activeCells);forAll(cellShapes, celli){ cellShape &cs=cellShapes[celli];forAll(cs, i) { cs[i]=pointMap[cs[i]];} cs.collapse();}label bcIDs[11]={-1, 0, 2, 4, -1, 5, -1, 6, 7, 8, 9};const label nBCs=12;const word *kivaPatchTypes[nBCs]={ &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &wallPolyPatch::typeName, &symmetryPolyPatch::typeName, &wedgePolyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &polyPatch::typeName, &symmetryPolyPatch::typeName, &oldCyclicPolyPatch::typeName};enum patchTypeNames{ PISTON, VALVE, LINER, CYLINDERHEAD, AXIS, WEDGE, INFLOW, OUTFLOW, PRESIN, PRESOUT, SYMMETRYPLANE, CYCLIC};const char *kivaPatchNames[nBCs]={ "piston", "valve", "liner", "cylinderHead", "axis", "wedge", "inflow", "outflow", "presin", "presout", "symmetryPlane", "cyclic"};List< SLList< face > > pFaces[nBCs]
static bool split(const std::string &line, std::string &key, std::string &val)
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
const vectorField & faceCentres() const
List< word > wordList
List of word.
T & last() noexcept
Access last element of the list, position [N-1] - back()
pointField points0(pointIOField(IOobject("points", mesh.time().constant(), polyMesh::meshSubDir, mesh, IOobject::MUST_READ, IOobject::NO_WRITE, IOobject::NO_REGISTER)))
vector point
Point is a vector.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
#define WarningInFunction
Report a warning using Foam::Warning.
labelList meshEdges(const edgeList &allEdges, const labelListList &cellEdges, const labelList &faceCells) const
Return labels of patch edges in the global edge list using cell addressing.
static bitSet getMasterPoints(const polyMesh &mesh, const labelList &meshPoints)
Determine master point for subset of points. If coupled.
Mesh data needed to do the Finite Volume discretisation.
const vectorField & faceAreas() const
const dimensionedScalar c
Speed of light in a vacuum.
const polyBoundaryMesh & patches
const std::string patch
OpenFOAM patch number as a std::string.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
static labelList findDuplicateFaces(const primitiveMesh &, const labelList &)
Helper routine to find baffles (two boundary faces using the.
static labelList getNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces (surfaces with faceZoneName)
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< label > labelList
A List of labels.
static T gAverage(const bitSet &isMasterElem, const UList< T > &values)
Helper: calculate average.
label rcIndex(const label i) const noexcept
The reverse circular index. The previous index in the list which returns to the last at the beginning...
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
void operator()(List< T > &x, const List< T > &y) const
List< bool > boolList
A List of bools.
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
const volScalarField & p0
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
static constexpr const zero Zero
Global zero (0)