66 bool Foam::autoSnapDriver::isFeaturePoint
68 const scalar featureCos,
82 if (isFeatureEdge[pEdges[i]])
86 for (
label j = i+1; j < pEdges.
size(); j++)
88 if (isFeatureEdge[pEdges[j]])
90 const edge& eI = edges[pEdges[i]];
91 const edge& eJ = edges[pEdges[j]];
93 const point&
p = points[pointI];
98 scalar vIMag =
mag(vI);
101 scalar vJMag =
mag(vJ);
107 && ((vI/vIMag & vJ/vJMag) < featureCos)
127 void Foam::autoSnapDriver::smoothAndConstrain
138 for (
label avgIter = 0; avgIter < 20; avgIter++)
159 forAll(pointEdges, pointI)
161 const labelList& pEdges = pointEdges[pointI];
163 label nConstraints = constraints[pointI].
first();
165 if (nConstraints <= 1)
169 label edgeI = pEdges[i];
171 if (isPatchMasterEdge[edgeI])
173 label nbrPointI = edges[edgeI].otherVertex(pointI);
174 if (constraints[nbrPointI].first() >= nConstraints)
176 dispSum[pointI] += disp[nbrPointI];
204 forAll(constraints, pointI)
206 if (dispCount[pointI] > 0)
211 *(disp[pointI] + dispSum[pointI]/dispCount[pointI]);
218 void Foam::autoSnapDriver::calcNearestFace
235 faceSurfaceNormal.
setSize(pp.size());
237 faceSurfaceGlobalRegion.
setSize(pp.size());
238 faceSurfaceGlobalRegion = -1;
259 label zoneSurfI = zonedSurfaces[i];
261 const word& faceZoneName = surfZones[zoneSurfI].faceZoneName();
269 "autoSnapDriver::calcNearestFace(..)" 270 ) <<
"Problem. Cannot find zone " << faceZoneName
277 isZonedFace[fZone[i]] = 1;
282 forAll(pp.addressing(), i)
284 if (isZonedFace[pp.addressing()[i]])
286 snapSurf[i] = zoneSurfI;
288 meshFaces.append(pp.addressing()[i]);
322 if (hitInfo[hitI].hit())
324 label faceI = ppFaces[hitI];
325 faceDisp[faceI] = hitInfo[hitI].hitPoint() - fc[hitI];
326 faceSurfaceNormal[faceI] = hitNormal[hitI];
337 "autoSnapDriver::calcNearestFace(..)" 338 ) <<
"Did not find surface near face centre " << fc[hitI]
351 forAll(pp.addressing(), i)
353 if (snapSurf[i] == -1)
356 meshFaces.append(pp.addressing()[i]);
388 if (hitInfo[hitI].hit())
390 label faceI = ppFaces[hitI];
391 faceDisp[faceI] = hitInfo[hitI].hitPoint() - fc[hitI];
392 faceSurfaceNormal[faceI] = hitNormal[hitI];
403 "autoSnapDriver::calcNearestFace(..)" 404 ) <<
"Did not find surface near face centre " << fc[hitI]
414 faceRotation.
setSize(pp.size());
417 forAll(faceRotation, faceI)
420 faceRotation[faceI] =
422 ^ faceSurfaceNormal[faceI];
430 /
"faceDisp_" +
name(iter) +
".obj",
437 /
"faceRotation_" +
name(iter) +
".obj",
450 void Foam::autoSnapDriver::calcNearestFacePointProperties
457 const labelList& faceSurfaceGlobalRegion,
474 pointFaceSurfNormals.setSize(pp.
nPoints());
475 pointFaceDisp.setSize(pp.
nPoints());
476 pointFaceCentres.setSize(pp.
nPoints());
488 label faceI = pFaces[i];
489 if (isMasterFace[faceI] && faceSurfaceGlobalRegion[faceI] != -1)
496 List<point>& pNormals = pointFaceSurfNormals[pointI];
502 labelList& pFid = pointFacePatchID[pointI];
508 label faceI = pFaces[i];
509 label globalRegionI = faceSurfaceGlobalRegion[faceI];
511 if (isMasterFace[faceI] && globalRegionI != -1)
513 pNormals[nFaces] = faceSurfaceNormal[faceI];
514 pDisp[nFaces] = faceDisp[faceI];
516 pFid[nFaces] = globalToMasterPatch_[globalRegionI];
539 if (pp.
coupled() || isA<emptyPolyPatch>(pp))
550 forAll(pp.addressing(), i)
552 label meshFaceI = pp.addressing()[i];
561 label pointI = boundaryPoints[i];
566 List<point>& pNormals = pointFaceSurfNormals[pointI];
569 labelList& pFid = pointFacePatchID[pointI];
573 label meshFaceI = pFaces[i];
595 pointFaceSurfNormals,
631 forAll(pointFaceDisp, pointI)
633 List<point>& pNormals = pointFaceSurfNormals[pointI];
636 labelList& pFid = pointFacePatchID[pointI];
651 void Foam::autoSnapDriver::correctAttraction
663 scalar tang = ((pt-edgePt)&edgeNormal);
668 if (order[0] < order[1])
672 vector attractD = surfacePoints[order[0]]-edgePt;
674 scalar tang2 = (attractD&edgeNormal);
676 attractD -= tang2*edgeNormal;
678 scalar magAttractD =
mag(attractD);
679 scalar fraction = magAttractD/(magAttractD+
mag(edgeOffset));
683 + ((1.0-fraction)*tang2 + fraction*tang)*edgeNormal;
684 edgeOffset = linePt-pt;
699 label patch0 = patchIDs[0];
701 for (
label i = 1; i < patchIDs.
size(); i++)
703 if (patchIDs[i] != patch0)
715 const scalar featureCos,
724 scalar cosAngle = (n&surfaceNormals[j]);
728 (cosAngle >= featureCos)
729 || (cosAngle < (-1+0.001))
754 if (patchIDs.
empty())
760 label patch0 = patchIDs[0];
762 for (
label i = 1; i < patchIDs.
size(); i++)
764 if (patchIDs[i] != patch0)
778 if (surfaceNormals.
size() == 1)
787 forAll(faceToNormalBin, i)
789 if (faceToNormalBin[i] != -1)
791 label& patch = normalToPatch[faceToNormalBin[i]];
797 else if (patch == -2)
801 else if (patch != patchIDs[i])
809 forAll(normalToPatch, normalI)
811 if (normalToPatch[normalI] == -2)
826 void Foam::autoSnapDriver::featureAttractionUsingReconstruction
829 const scalar featureCos,
852 const List<point>& pfSurfNormals = pointFaceSurfNormals[pointI];
854 const List<point>& pfCentres = pointFaceCentres[pointI];
864 surfacePoints.
clear();
865 surfaceNormals.
clear();
869 faceToNormalBin = -1;
873 const point& fc = pfCentres[i];
874 const vector& fSNormal = pfSurfNormals[i];
875 const vector& fDisp = pfDisp[i];
878 if (
magSqr(fDisp) <
sqr(snapDist[pointI]) &&
mag(fSNormal) > VSMALL)
880 const point pt = fc + fDisp;
883 faceToNormalBin[i] = findNormal
890 if (faceToNormalBin[i] != -1)
898 if (surfacePoints.
size() <= 1)
901 faceToNormalBin[i] = surfaceNormals.
size();
902 surfaceNormals.
append(fSNormal);
904 else if (surfacePoints.
size() == 2)
906 plane pl0(surfacePoints[0], surfaceNormals[0]);
907 plane pl1(surfacePoints[1], surfaceNormals[1]);
909 vector featureNormal = r.dir() /
mag(r.dir());
911 if (
mag(fSNormal&featureNormal) >= 0.001)
915 faceToNormalBin[i] = surfaceNormals.
size();
916 surfaceNormals.
append(fSNormal);
919 else if (surfacePoints.
size() == 3)
923 plane pl0(surfacePoints[0], surfaceNormals[0]);
924 plane pl1(surfacePoints[1], surfaceNormals[1]);
925 plane pl2(surfacePoints[2], surfaceNormals[2]);
929 vector featureNormal = r.dir() /
mag(r.dir());
930 if (
mag(fSNormal&featureNormal) >= 0.001)
932 plane pl3(pt, fSNormal);
935 if (
mag(p012-p013) > snapDist[pointI])
939 faceToNormalBin[i] = surfaceNormals.
size();
940 surfaceNormals.
append(fSNormal);
952 if (surfaceNormals.
size() == 1)
956 ((surfacePoints[0]-pt) & surfaceNormals[0])
970 else if (surfaceNormals.
size() == 2)
972 plane pl0(surfacePoints[0], surfaceNormals[0]);
973 plane pl1(surfacePoints[1], surfaceNormals[1]);
978 vector d = r.refPoint()-pt;
993 else if (surfaceNormals.
size() == 3)
996 plane pl0(surfacePoints[0], surfaceNormals[0]);
997 plane pl1(surfacePoints[1], surfaceNormals[1]);
998 plane pl2(surfacePoints[2], surfaceNormals[2]);
1000 vector d = cornerPt - pt;
1008 patchAttraction = d;
1019 void Foam::autoSnapDriver::featureAttractionUsingReconstruction
1022 const bool avoidSnapProblems,
1023 const scalar featureCos,
1046 meshRefiner_.mesh().time().path()
1047 /
"implicitFeatureEdge_" +
name(iter) +
".obj" 1050 Info<<
"Dumping implicit feature-edge direction to " 1051 << feStr().name() <<
endl;
1057 meshRefiner_.mesh().time().path()
1058 /
"implicitFeaturePoint_" +
name(iter) +
".obj" 1061 Info<<
"Dumping implicit feature-point direction to " 1062 << fpStr().name() <<
endl;
1075 featureAttractionUsingReconstruction
1086 pointFaceSurfNormals,
1101 (constraint.
first() > patchConstraints[pointI].
first())
1103 (constraint.
first() == patchConstraints[pointI].
first())
1104 && (
magSqr(attraction) <
magSqr(patchAttraction[pointI]))
1108 patchAttraction[pointI] = attraction;
1109 patchConstraints[pointI] = constraint;
1113 if (patchConstraints[pointI].first() == 2 && feStr.
valid())
1115 feStr().write(
linePointRef(pt, pt+patchAttraction[pointI]));
1117 else if (patchConstraints[pointI].first() == 3 && fpStr.
valid())
1119 fpStr().write(
linePointRef(pt, pt+patchAttraction[pointI]));
1126 void Foam::autoSnapDriver::stringFeatureEdges
1129 const scalar featureCos,
1168 forAll(pointEdges, pointI)
1170 if (patchConstraints[pointI].first() == 2)
1173 const labelList& pEdges = pointEdges[pointI];
1174 const vector& featVec = patchConstraints[pointI].second();
1178 bool hasPos =
false;
1179 bool hasNeg =
false;
1186 if (patchConstraints[nbrPointI].first() > 1)
1189 const point featPt =
1190 nbrPt + patchAttraction[nbrPointI];
1191 const scalar cosAngle = (featVec & (featPt-pt));
1204 if (!hasPos || !hasNeg)
1210 label bestPosPointI = -1;
1211 scalar minPosDistSqr = GREAT;
1212 label bestNegPointI = -1;
1213 scalar minNegDistSqr = GREAT;
1222 patchConstraints[nbrPointI].first() <= 1
1223 && rawPatchConstraints[nbrPointI].first() > 1
1226 const vector& nbrFeatVec =
1227 rawPatchConstraints[pointI].second();
1229 if (
mag(featVec&nbrFeatVec) > featureCos)
1236 rawPatchAttraction[nbrPointI]
1239 const point featPt =
1241 + rawPatchAttraction[nbrPointI];
1242 const scalar cosAngle =
1243 (featVec & (featPt-pt));
1247 if (!hasPos && d2 < minPosDistSqr)
1250 bestPosPointI = nbrPointI;
1255 if (!hasNeg && d2 < minNegDistSqr)
1258 bestNegPointI = nbrPointI;
1265 if (bestPosPointI != -1)
1275 patchAttraction[bestPosPointI] =
1276 0.5*rawPatchAttraction[bestPosPointI];
1277 patchConstraints[bestPosPointI] =
1278 rawPatchConstraints[bestPosPointI];
1282 if (bestNegPointI != -1)
1292 patchAttraction[bestNegPointI] =
1293 0.5*rawPatchAttraction[bestNegPointI];
1294 patchConstraints[bestNegPointI] =
1295 rawPatchConstraints[bestNegPointI];
1305 Info<<
"Stringing feature edges : changed " << nChanged <<
" points" 1315 void Foam::autoSnapDriver::releasePointsNextToMultiPatch
1318 const scalar featureCos,
1340 meshRefiner_.mesh().time().path()
1341 /
"multiPatch_" +
name(iter) +
".obj" 1344 Info<<
"Dumping removed constraints due to same-face" 1345 <<
" multi-patch points to " 1346 << multiPatchStr().name() <<
endl;
1353 forAll(pointFacePatchID, pointI)
1358 pointFacePatchID[pointI],
1359 pointFaceCentres[pointI]
1361 isMultiPatchPoint[pointI] = multiPatchPt.
hit();
1365 forAll(isMultiPatchPoint, pointI)
1367 if (isMultiPatchPoint[pointI])
1371 patchConstraints[pointI].first() <= 1
1372 && rawPatchConstraints[pointI].first() > 1
1375 patchAttraction[pointI] = rawPatchAttraction[pointI];
1376 patchConstraints[pointI] = rawPatchConstraints[pointI];
1399 label nMultiPatchPoints = 0;
1402 label pointI = f[fp];
1405 isMultiPatchPoint[pointI]
1406 && patchConstraints[pointI].first() > 1
1409 nMultiPatchPoints++;
1413 if (nMultiPatchPoints > 0)
1417 label pointI = f[fp];
1420 !isMultiPatchPoint[pointI]
1421 && patchConstraints[pointI].first() > 1
1431 if (multiPatchStr.
valid())
1441 Info<<
"Removing constraints near multi-patch points : changed " 1442 << nChanged <<
" points" <<
endl;
1465 label pointI = f[fp];
1466 if (patchConstraints[pointI].first() >= 2)
1469 if (attractIndices[0] == -1)
1472 attractIndices[0] = fp;
1474 else if (attractIndices[1] == -1)
1478 label fp0 = attractIndices[0];
1487 attractIndices[1] = fp;
1500 if (attractIndices[1] == -1)
1506 return attractIndices;
1510 void Foam::autoSnapDriver::avoidDiagonalAttraction
1513 const scalar featureCos,
1533 if (diag[0] != -1 && diag[1] != -1)
1537 const label i0 = f[diag[0]];
1540 const label i1 = f[diag[1]];
1543 const point mid = 0.5*(pt0+pt1);
1545 const scalar cosAngle =
mag 1547 patchConstraints[i0].second()
1548 & patchConstraints[i1].second()
1557 if (cosAngle > featureCos)
1562 scalar minDistSqr = GREAT;
1565 label pointI = f[fp];
1566 if (patchConstraints[pointI].first() <= 1)
1569 scalar distSqr =
magSqr(mid-pt);
1570 if (distSqr < minDistSqr)
1572 distSqr = minDistSqr;
1579 label minPointI = f[minFp];
1580 patchAttraction[minPointI] =
1582 patchConstraints[minPointI] =
1583 patchConstraints[f[diag[0]]];
1609 Foam::autoSnapDriver::findNearFeatureEdge
1611 const bool isRegionEdge,
1616 const point& estimatedPt,
1654 label featI = nearEdgeFeat[0];
1665 edgeConstraints[featI][nearInfo.
index()].append(c);
1668 patchAttraction[pointI] =
1670 patchConstraints[pointI] =
c;
1677 Foam::autoSnapDriver::findNearFeaturePoint
1679 const bool isRegionPoint,
1684 const point& estimatedPt,
1709 label featI = nearFeat[0];
1715 label featPointI = nearInfo[0].index();
1716 const point& featPt = nearInfo[0].hitPoint();
1717 scalar distSqr =
magSqr(featPt-pt);
1720 label oldPointI = pointAttractor[featI][featPointI];
1722 if (oldPointI != -1)
1734 pointAttractor[featI][featPointI] = pointI;
1739 patchAttraction[pointI] = featPt-pt;
1740 patchConstraints[pointI] =
1766 pointAttractor[featI][featPointI] = pointI;
1771 patchAttraction[pointI] = featPt-pt;
1782 void Foam::autoSnapDriver::determineFeatures
1785 const scalar featureCos,
1786 const bool multiRegionFeatureSnap,
1814 featureEdgeStr.
reset 1818 meshRefiner_.mesh().time().path()
1819 /
"featureEdge_" +
name(iter) +
".obj" 1822 Info<<
"Dumping feature-edge sampling to " 1823 << featureEdgeStr().name() <<
endl;
1829 meshRefiner_.mesh().time().path()
1830 /
"missedFeatureEdge_" +
name(iter) +
".obj" 1833 Info<<
"Dumping feature-edges that are too far away to " 1834 << missedEdgeStr().name() <<
endl;
1836 featurePointStr.
reset 1840 meshRefiner_.mesh().time().path()
1841 /
"featurePoint_" +
name(iter) +
".obj" 1844 Info<<
"Dumping feature-point sampling to " 1845 << featurePointStr().name() <<
endl;
1860 featureAttractionUsingReconstruction
1871 pointFaceSurfNormals,
1887 (constraint.
first() > patchConstraints[pointI].
first())
1889 (constraint.
first() == patchConstraints[pointI].
first())
1890 && (
magSqr(attraction) <
magSqr(patchAttraction[pointI]))
1894 patchAttraction[pointI] = attraction;
1895 patchConstraints[pointI] = constraint;
1898 if (patchConstraints[pointI].first() == 1)
1901 if (multiRegionFeatureSnap)
1903 const point estimatedPt(pt + nearestDisp[pointI]);
1909 pointFacePatchID[pointI],
1915 if (multiPatchPt.
hit())
1940 if (featureEdgeStr.
valid())
1942 featureEdgeStr().write
1950 if (missedEdgeStr.
valid())
1952 missedEdgeStr().write
1961 else if (patchConstraints[pointI].first() == 2)
1966 const point estimatedPt(pt + patchAttraction[pointI]);
1971 bool hasSnapped =
false;
1972 if (multiRegionFeatureSnap)
1979 pointFacePatchID[pointI],
1984 if (multiPatchPt.
hit())
1986 if (multiPatchPt.
index() == 0)
1989 nearInfo = findNearFeatureEdge
2009 nearInfo = findNearFeaturePoint
2038 nearInfo = findNearFeatureEdge
2061 patchConstraints[pointI].first() == 3
2062 && featurePointStr.
valid()
2065 featurePointStr().write
2072 patchConstraints[pointI].first() == 2
2073 && featureEdgeStr.
valid()
2076 featureEdgeStr().write
2084 if (missedEdgeStr.
valid())
2086 missedEdgeStr().write
2093 else if (patchConstraints[pointI].first() == 3)
2096 const point estimatedPt(pt + patchAttraction[pointI]);
2100 if (multiRegionFeatureSnap)
2107 pointFacePatchID[pointI],
2112 if (multiPatchPt.
hit())
2115 nearInfo = findNearFeaturePoint
2136 nearInfo = findNearFeaturePoint
2159 nearInfo = findNearFeaturePoint
2180 if (info.
hit() && featurePointStr.
valid())
2182 featurePointStr().write
2204 void Foam::autoSnapDriver::determineBaffleFeatures
2207 const scalar featureCos,
2237 label faceI = eFaces[i];
2272 meshRefiner_.mesh().time().path()
2273 /
"baffleEdge_" +
name(iter) +
".obj" 2276 Info<<
nl <<
"Dumping baffle-edges to " 2277 << baffleEdgeStr().name() <<
endl;
2283 label nBaffleEdges = 0;
2290 forAll(edgeFaceNormals, edgeI)
2294 if (efn.
size() == 2 && (efn[0]&efn[1]) < baffleFeatureCos)
2296 isBaffleEdge[edgeI] =
true;
2299 pointStatus[e[0]] = 0;
2300 pointStatus[e[1]] = 0;
2302 if (baffleEdgeStr.
valid())
2313 <<
" baffle edges out of " 2315 <<
" edges." <<
endl;
2339 forAll(pointStatus, pointI)
2343 if (pointStatus[pointI] == 0)
2359 if (!nearInfo.
second().hit())
2365 else if (pointStatus[pointI] == 1)
2377 label featI = nearFeat[0];
2381 label featPointI = nearInfo[0].index();
2382 const point& featPt = nearInfo[0].hitPoint();
2383 scalar distSqr =
magSqr(featPt-pt);
2386 label oldPointI = pointAttractor[featI][featPointI];
2397 pointAttractor[featI][featPointI] = pointI;
2403 patchAttraction[pointI] = featPt-pt;
2404 patchConstraints[pointI] =
2407 if (oldPointI != -1)
2462 void Foam::autoSnapDriver::reverseAttractMeshPoints
2499 bb = bb.extend(rndGen, 1
e-4);
2500 bb.min() -=
point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
2501 bb.max() +=
point(ROOTVSMALL, ROOTVSMALL, ROOTVSMALL);
2511 forAll(rawPatchConstraints, pointI)
2513 if (rawPatchConstraints[pointI].first() >= 2)
2515 isFeatureEdgeOrPoint[pointI] =
true;
2522 <<
" for reverse attraction." <<
endl;
2530 isFeatureEdgeOrPoint,
2535 for (
label nGrow = 0; nGrow < 1; nGrow++)
2537 boolList newIsFeatureEdgeOrPoint(isFeatureEdgeOrPoint);
2545 if (isFeatureEdgeOrPoint[f[fp]])
2550 newIsFeatureEdgeOrPoint[f[fp]] =
true;
2557 isFeatureEdgeOrPoint = newIsFeatureEdgeOrPoint;
2563 isFeatureEdgeOrPoint,
2571 forAll(isFeatureEdgeOrPoint, pointI)
2573 if (isFeatureEdgeOrPoint[pointI])
2575 attractPoints.append(pointI);
2582 <<
" for reverse attraction." <<
endl;
2601 forAll(edgeAttractors, featI)
2605 edgeConstraints[featI];
2607 forAll(edgeAttr, featEdgeI)
2613 const point& featPt = attr[i];
2630 patchConstraints[pointI].first() <= 1
2631 ||
magSqr(attraction) <
magSqr(patchAttraction[pointI])
2634 patchAttraction[pointI] = attraction;
2635 patchConstraints[pointI] = edgeConstr[featEdgeI][i];
2642 "autoSnapDriver::featureAttractionUsingFeatureEdges" 2644 ) <<
"Did not find pp point near " << featPt
2661 forAll(pointAttractor, featI)
2663 const labelList& pointAttr = pointAttractor[featI];
2666 forAll(pointAttr, featPointI)
2668 if (pointAttr[featPointI] != -1)
2670 const point& featPt = features[featI].points()
2688 const point attraction = featPt-pt;
2693 if (patchConstraints[pointI].first() <= 1)
2695 patchAttraction[pointI] = attraction;
2696 patchConstraints[pointI] = pointConstr[featPointI];
2698 else if (patchConstraints[pointI].first() == 2)
2700 patchAttraction[pointI] = attraction;
2701 patchConstraints[pointI] = pointConstr[featPointI];
2703 else if (patchConstraints[pointI].first() == 3)
2709 <
magSqr(patchAttraction[pointI])
2712 patchAttraction[pointI] = attraction;
2713 patchConstraints[pointI] =
2714 pointConstr[featPointI];
2724 void Foam::autoSnapDriver::featureAttractionUsingFeatureEdges
2727 const bool avoidSnapProblems,
2728 const scalar featureCos,
2729 const bool multiRegionFeatureSnap,
2758 label nFeatEdges = features[featI].edges().
size();
2759 edgeAttractors[featI].setSize(nFeatEdges);
2760 edgeConstraints[featI].setSize(nFeatEdges);
2770 label nFeatPoints = features[featI].points().
size();
2771 pointAttractor[featI].
setSize(nFeatPoints, -1);
2783 multiRegionFeatureSnap,
2789 pointFaceSurfNormals,
2818 determineBaffleFeatures
2843 reverseAttractMeshPoints
2859 rawPatchConstraints,
2872 meshRefiner_.mesh().time().path()
2873 /
"edgeAttractors_" +
name(iter) +
".obj" 2875 Info<<
"Dumping feature-edge attraction to " 2876 << featureEdgeStr.name() <<
endl;
2880 meshRefiner_.mesh().time().path()
2881 /
"pointAttractors_" +
name(iter) +
".obj" 2883 Info<<
"Dumping feature-point attraction to " 2884 << featurePointStr.name() <<
endl;
2886 forAll(patchConstraints, pointI)
2889 const vector& attr = patchAttraction[pointI];
2891 if (patchConstraints[pointI].first() == 2)
2895 else if (patchConstraints[pointI].first() == 3)
2903 if (avoidSnapProblems)
2908 if (multiRegionFeatureSnap)
2910 releasePointsNextToMultiPatch
2922 rawPatchConstraints,
2944 rawPatchConstraints,
2955 avoidDiagonalAttraction
2965 if (debug&meshRefinement::ATTRACTION)
2969 meshRefiner_.mesh().time().path()
2970 /
"patchAttraction_" +
name(iter) +
".obj",
2979 void Foam::autoSnapDriver::preventFaceSqueeze
2982 const scalar featureCos,
3006 label nConstraints = 0;
3009 label pointI = f[fp];
3012 if (patchConstraints[pointI].first() > 1)
3014 points[fp] = pt + patchAttraction[pointI];
3023 if (nConstraints == f.
size())
3026 scalar newArea = singleF.
mag(points);
3027 if (newArea < 0.1*oldArea)
3034 scalar
s =
magSqr(patchAttraction[f[fp]]);
3043 label pointI = f[maxFp];
3045 patchAttraction[pointI] *= 0.5;
3056 const bool avoidSnapProblems,
3058 const scalar featureCos,
3059 const scalar featureAttract,
3071 Info<<
"Overriding displacement on features :" <<
nl 3072 <<
" implicit features : " << implicitFeatureAttraction <<
nl 3073 <<
" explicit features : " << explicitFeatureAttraction <<
nl 3074 <<
" multi-patch features : " << multiRegionFeatureSnap <<
nl 3102 faceSnapDist[faceI] =
max(faceSnapDist[faceI], snapDist[f[fp]]);
3114 labelList faceSurfaceGlobalRegion(pp.size(), -1);
3124 faceSurfaceGlobalRegion,
3134 calcNearestFacePointProperties
3141 faceSurfaceGlobalRegion,
3143 pointFaceSurfNormals,
3168 if (implicitFeatureAttraction)
3173 featureAttractionUsingReconstruction
3183 pointFaceSurfNormals,
3193 if (explicitFeatureAttraction)
3201 featureAttractionUsingFeatureEdges
3206 multiRegionFeatureSnap,
3212 pointFaceSurfNormals,
3255 Info<<
"Attraction:" << endl
3257 <<
" avg:" << avgPatchDisp << endl
3258 <<
" feature : max:" <<
gMaxMagSqr(patchAttraction)
3259 <<
" avg:" << avgPatchAttr <<
endl;
3273 forAll(patchConstraints, pointI)
3275 if (patchConstraints[pointI].first() > 1)
3278 (1.0-featureAttract)*patchDisp[pointI]
3279 + featureAttract*patchAttraction[pointI];
3287 label nMasterPoints = 0;
3292 forAll(patchConstraints, pointI)
3294 if (isPatchMasterPoint[pointI])
3298 if (patchConstraints[pointI].first() == 1)
3302 else if (patchConstraints[pointI].first() == 2)
3306 else if (patchConstraints[pointI].first() == 3)
3317 Info<<
"Feature analysis : total master points:" 3319 <<
" attraction to :" <<
nl 3320 <<
" feature point : " << nPoint <<
nl 3321 <<
" feature edge : " << nEdge <<
nl 3322 <<
" nearest surface : " << nPlanar <<
nl 3323 <<
" rest : " << nMasterPoints-nPoint-nEdge-nPlanar
3340 if (featureAttract < 1-0.001)
3380 tangPatchDisp -= (pointNormals & patchDisp) * pointNormals;
3391 tangPatchDisp += (pointNormals & patchDisp) * pointNormals;
3398 /
"tangPatchDispConstrained_" +
name(iter) +
".obj",
3405 (1.0-featureAttract)*smoothedPatchDisp
3406 + featureAttract*tangPatchDisp;
3410 const scalar
relax = featureAttract;
3422 vector(GREAT, GREAT, GREAT)
const vectorField & faceAreas() const
void reduce(const List< UPstream::commsStruct > &comms, T &Value, const BinaryOp &bop, const int tag, const label comm)
dimensionedScalar sqrt(const dimensionedScalar &ds)
A List with indirect addressing.
const Type2 & second() const
Return second.
OFstream which keeps track of vertices.
const pointField & points
Simple random number generator.
const faceZoneMesh & faceZones() const
Return face zone mesh.
cachedRandom rndGen(label(0),-1)
A 2-tuple for storing two objects of different types.
Default transformation behaviour for position.
static PackedBoolList getMasterFaces(const polyMesh &)
Get per face whether it is uncoupled or a master of a.
Switch implicitFeatureSnap() const
Mesh data needed to do the Finite Volume discretisation.
Container for data on surfaces used for surface-driven refinement. Contains all the data about the le...
void findNearestPoint(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo) const
Find nearest feature point. Sets.
label size() const
Return the number of elements in the PtrList.
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
virtual bool coupled() const
Return true if this patch is geometrically coupled (i.e. faces and.
vector point
Point is a vector.
An ordered pair of two objects of type <T> with first() and second() elements.
gmvFile<< "tracers "<< particles.size()<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().x()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().position().y()<< " ";}gmvFile<< nl;forAllConstIter(Cloud< passiveParticle >, particles, iter){gmvFile<< iter().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 ))
fileName path() const
Return path.
labelList meshEdges(const edgeList &allEdges, const labelListList &cellEdges, const labelList &faceCells) const
Return labels of patch edges in the global edge list using.
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Tuple2< scalar, label > nearInfo
Private class for finding nearest.
dimensioned< scalar > mag(const dimensioned< Type > &)
const edgeList & edges() const
Return mesh edges. Uses calcEdges.
word name(const complex &)
Return a string representation of a complex.
Default transformation behaviour.
const labelListList & pointEdges() const
const labelListList & edgeFaces() const
Return edge-face addressing.
bool empty() const
Return true if the UList is empty (ie, size() is zero).
dimensioned< scalar > magSqr(const dimensioned< Type > &)
void reset(T *=0)
If object pointer already set, delete object and set to given.
const Type & shapes() const
Reference to shape.
bool valid() const
Return true if the autoPtr valid (ie, the pointer is set).
static T gAverage(const PackedBoolList &isMasterElem, const UList< T > &values)
Helper: calculate average.
void sortedOrder(const UList< T > &, labelList &order)
Generate the (stable) sort order for the list.
const labelListList & pointFaces() const
Return point-face addressing.
A subset of mesh faces organised as a primitive patch.
scalar mag(const pointField &) const
Magnitude of face area.
static labelList getUnnamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of unnamed surfaces (surfaces without faceZoneName)
void clear()
Clear the addressed list, i.e. set the size to zero.
A class for handling words, derived from string.
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Standard boundBox + extra functionality for use in octree.
void size(const label)
Override size to be inconsistent with allocated storage.
DynamicList< T, SizeInc, SizeMult, SizeDiv > & append(const T &)
Append an element at the end of the list.
errorManipArg< error, int > exit(error &err, const int errNo=1)
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
static labelList getNamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of named surfaces (surfaces with faceZoneName)
point planePlaneIntersect(const plane &, const plane &) const
Return the cutting point between this plane and two other planes.
PointIndexHit< point > pointIndexHit
static void syncEdgeList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh edges.
A simple wrapper around bool so that it can be read as a word: true/false, on/off, yes/no, y/n, t/f, or none.
const Type1 & first() const
Return first.
void diag(pointPatchField< vector > &, const pointPatchField< tensor > &)
Accumulates point constraints through successive applications of the applyConstraint function...
bool hit() const
Is there a hit.
Simple container to keep together snap specific information.
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
T & first()
Return the first element of the list.
label index() const
Return index.
label nPoints() const
Return number of points supporting patch faces.
vectorField pointField
pointField is a vectorField.
const Point & hitPoint() const
Return hit point.
A patch is a list of labels that address the faces in the global face list.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const Time & time() const
Return the top-level database.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
A face is a list of labels corresponding to mesh vertices.
const Field< PointType > & localPoints() const
Return pointField of points in patch.
const double e
Elementary charge.
const Field< PointType > & faceCentres() const
Return face centres for patch.
void setSize(const label)
Reset size of List.
Ostream & endl(Ostream &os)
Add newline and flush stream.
#define WarningIn(functionName)
Report a warning using Foam::Warning.
virtual const pointField & points() const
Return raw points.
A List with indirect addressing.
dimensionSet transform(const dimensionSet &)
const labelList & boundaryPoints() const
Return list of boundary points,.
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Switch explicitFeatureSnap() const
const labelList & meshPoints() const
Return labelList of mesh points in patch. They are constructed.
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
static PackedBoolList getMasterEdges(const polyMesh &mesh, const labelList &meshEdges)
Determine master edge for subset of edges. If coupled.
dimensionedScalar cos(const dimensionedScalar &ds)
label otherVertex(const label a) const
Given one vertex, return the other.
static PackedBoolList getMasterPoints(const polyMesh &mesh, const labelList &meshPoints)
Determine master point for subset of points. If coupled.
Unit conversion functions.
const labelListList & pointFaces() const
const Field< PointType > & faceNormals() const
Return face normals for patch.
label globalRegion(const label surfI, const label regionI) const
From surface and region on surface to global region.
static void syncPointList(const polyMesh &, List< T > &, const CombineOp &cop, const T &nullValue, const TransformOp &top)
Synchronize values on all mesh points.
const polyBoundaryMesh & boundaryMesh() const
Return boundary mesh.
const indirectPrimitivePatch & patch() const
Reference to patch.
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
Non-pointer based hierarchical recursive searching.
Encapsulates queries for features.
A list of faces which address into the list of points.
static tmp< pointField > pointNormals(const polyMesh &, const PrimitivePatch< Face, FaceList, PointField, PointType > &)
Return parallel consistent point normals for patches using mesh points.
Geometric class that creates a 2D plane and can return the intersection point between a line and the ...
label start() const
Return start label of this patch in the polyMesh face list.
label nInternalFaces() const
const labelList & patchID() const
Per boundary face label the patch index.
void findNearestRegionEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest region edge. Sets.
const labelListList & pointEdges() const
Return point-edge addressing.
const PtrList< surfaceZonesInfo > & surfZones() const
ray planeIntersect(const plane &) const
Return the cutting line between this plane and another.
Given a displacement moves the mesh by scaling the displacement back until there are no more mesh err...
List< label > labelList
A List of labels.
scalar degToRad(const scalar deg)
Conversion from degrees to radians.
Pair< label > labelPair
Label pair.
label findZoneID(const word &zoneName) const
Find zone index given a name.
const dimensionedScalar c
Speed of light in a vacuum.
Vector< scalar > vector
A scalar version of the templated Vector.
const List< Face > & localFaces() const
Return patch faces addressing into local point list.
void append(const T &)
Append an element at the end of the list.
line< point, const point & > linePointRef
Line using referred points.
virtual const faceList & faces() const
Return raw faces.
Info<< "Finished reading KIVA file"<< endl;cellShapeList cellShapes(nPoints);labelList cellZoning(nPoints,-1);const cellModel &hex=*(cellModeller::lookup("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]=cellShape(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]
void findNearestEdge(const pointField &samples, const scalarField &nearestDistSqr, labelList &nearFeature, List< pointIndexHit > &nearInfo, vectorField &nearNormal) const
Find nearest point on nearest feature edge. Sets.
const labelList & surfaces() const
void applyConstraint(const vector &cd)
Apply and accumulate the effect of the given constraint direction.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
label nEdges() const
Return number of edges in patch.
const Point & missPoint() const
Return miss point.
Switch multiRegionFeatureSnap() const
Application of (multi-)patch point contraints.
An auto-pointer similar to the STL auto_ptr but with automatic casting to a reference to the type and...
Holds (reference to) pointField. Encapsulation of data needed for octree searches. Used for searching for nearest point. No bounding boxes around points. Only overlaps and calcNearest are implemented, rest makes little sense.
void findNearestRegion(const labelList &surfacesToTest, const pointField &samples, const scalarField &nearestDistSqr, labelList &hitSurface, labelList &hitRegion) const
Find nearest point on surfaces. Return surface and region on.
bool isInternalFace(const label faceIndex) const
Return true if given face label is internal to the mesh.
const vectorField & faceCentres() const
static const label labelMax
Type gMaxMagSqr(const UList< Type > &f, const label comm)
A direction and a reference point.
void operator()(List< T > &x, const List< T > &y) const