72 Foam::label Foam::snappySnapDriver::getCollocatedPoints
76 bitSet& isCollocatedPoint
87 bool hasMerged = (nUnique <
points.size());
95 label nCollocated = 0;
100 forAll(pointMap, oldPointi)
112 isCollocatedPoint.set(oldPointi);
118 isCollocatedPoint.set(firstOldPoint[
newPointi]);
121 isCollocatedPoint.set(oldPointi);
134 const meshRefinement& meshRefiner,
135 const motionSmoother& meshMover
139 const polyMesh&
mesh = meshMover.mesh();
142 const hexRef8& cutter = meshRefiner.meshCutter();
143 const labelList& cellLevel = cutter.cellLevel();
187 label nInterface = 0;
194 if (!isFront.test(facei) && ownLevel != neiLevel)
197 isMovingPoint.
set(
f);
211 if (!isFront.test(facei) && ownLevel != neiLevel)
214 isMovingPoint.
set(
f);
224 <<
" inbetween refinement regions." <<
endl;
241 Field<weightedPosition> sumLocation
247 forAll(isMovingPoint, pointi)
249 if (isMovingPoint.test(pointi))
253 sumLocation[pointi].
first() = pCells.size();
254 for (
const label celli : pCells)
265 auto& displacement = tdisplacement.ref();
269 forAll(displacement, pointi)
271 const weightedPosition& wp = sumLocation[pointi];
272 if (
mag(wp.first()) > VSMALL)
274 displacement[pointi] =
275 wp.second()/wp.first()
282 <<
" points inbetween refinement regions." 285 return tdisplacement;
292 const motionSmoother& meshMover,
293 const List<labelPair>& baffles
300 label nNonManifoldPoints = getCollocatedPoints
306 Info<<
"Found " << nNonManifoldPoints <<
" non-manifold point(s)." 326 const polyMesh&
mesh = meshMover.mesh();
334 label f0 = baffles[i].first();
335 label f1 = baffles[i].second();
337 if (isMasterFace.test(f0))
340 isMasterFace.unset(f1);
342 else if (isMasterFace.test(f1))
344 isMasterFace.unset(f0);
349 <<
"Both sides of baffle consisting of faces " << f0
350 <<
" and " << f1 <<
" are already slave faces." 360 Field<weightedPosition> avgBoundary
366 forAll(pointFaces, patchPointi)
372 label facei =
pFaces[pfi];
374 if (isMasterFace.test(
pp.addressing()[facei]))
376 avgBoundary[patchPointi].first() += 1.0;
377 avgBoundary[patchPointi].second() +=
390 if (
mag(avgBoundary[i].first()) > VSMALL)
392 avgBoundary[i].second() /= avgBoundary[i].first();
401 Field<weightedPosition> avgInternal;
403 Field<weightedPosition> globalSum
414 const face&
f = faces[facei];
419 weightedPosition& wp = globalSum[
f[fp]];
433 && refCast<const coupledPolyPatch>(
patches[patchi]).owner()
436 const coupledPolyPatch&
pp =
437 refCast<const coupledPolyPatch>(
patches[patchi]);
443 const face&
f =
pp[i];
444 const point& fc = faceCentres[i];
448 weightedPosition& wp = globalSum[
f[fp]];
459 avgInternal.setSize(meshPoints.size());
461 forAll(avgInternal, patchPointi)
463 label meshPointi = meshPoints[patchPointi];
464 const weightedPosition& wp = globalSum[meshPointi];
466 avgInternal[patchPointi].first() = wp.first();
467 if (
mag(wp.first()) < VSMALL)
470 avgInternal[patchPointi].second() = wp.second();
474 avgInternal[patchPointi].second() = wp.second()/wp.first();
491 anyCell[
f[fp]] = own;
498 auto& patchDisp = tpatchDisp.ref();
502 label meshPointi = meshPoints[i];
511 const weightedPosition&
internal = avgInternal[i];
512 const weightedPosition&
boundary = avgBoundary[i];
516 if (!nonManifoldPoint.test(i))
520 scalar internalBlend = 0.1;
525 internalBlend*
internal.first()*
internal.second()
529 internalBlend*
internal.first()
533 newPos = (1-blend)*avgPos + blend*currentPos;
535 else if (
internal.first() == 0)
543 scalar cellCBlend = 0.8;
546 point avgPos = (1-cellCBlend)*
boundary.second() + cellCBlend*cc;
548 newPos = (1-blend)*avgPos + blend*currentPos;
553 scalar internalBlend = 0.9;
557 internalBlend*
internal.second()
558 + (1-internalBlend)*
boundary.second();
560 newPos = (1-blend)*avgPos + blend*currentPos;
563 patchDisp[i] = newPos - currentPos;
633 const pointMesh& pMesh,
637 const polyMesh&
mesh = pMesh();
640 List<pointEdgePoint> wallInfo(
pp.
nPoints());
651 List<pointEdgePoint> allEdgeInfo(
mesh.
nEdges());
653 PointEdgeWave<pointEdgePoint> wallCalc
666 auto& edgeDist = tedgeDist.ref();
668 forAll(allEdgeInfo, edgei)
670 edgeDist[edgei] =
Foam::sqrt(allEdgeInfo[edgei].distSqr());
677 void Foam::snappySnapDriver::dumpMove
679 const fileName& fName,
685 Info<<
"Dumping move direction to " << fName <<
endl;
687 OFstream nearestStream(fName);
699 nearestStream<<
"l " << verti-1 <<
' ' << verti <<
nl;
706 bool Foam::snappySnapDriver::outwardsDisplacement
715 forAll(pointFaces, pointi)
719 vector disp(patchDisp[pointi]);
721 scalar magDisp =
mag(disp);
731 Warning<<
"Displacement " << patchDisp[pointi]
734 <<
" points through the surrounding patch faces" <<
endl;
747 void Foam::snappySnapDriver::freezeExposedPoints
749 const meshRefinement& meshRefiner,
756 const fvMesh&
mesh = meshRefiner.mesh();
762 const label pointZonei = pointZones.
findZoneID(pzName);
763 if (pointZonei != -1)
765 isFrozenPoint.set(pointZones[pointZonei]);
770 const label faceZonei = faceZones.
findZoneID(fzName);
775 UIndirectList<face>(
mesh.
faces(), faceZones[faceZonei]),
780 const labelList nEdgeFaces(meshRefiner.countEdgeFaces(
pp));
785 if (nEdgeFaces[edgei] != 1)
798 orEqOp<unsigned int>(),
802 for (
const label pointi : isFrozenPoint)
804 const auto iter = outside.meshPointMap().find(pointi);
807 outsideDisp[iter.val()] =
Zero;
815 Foam::snappySnapDriver::snappySnapDriver
823 meshRefiner_(meshRefiner),
824 globalToMasterPatch_(globalToMasterPatch),
825 globalToSlavePatch_(globalToSlavePatch),
845 forAll(pointEdges, pointi)
847 const labelList& pEdges = pointEdges[pointi];
851 const edge&
e = edges[pEdges[pEdgei]];
853 scalar len =
e.mag(localPoints);
855 maxEdgeLen[pointi] =
max(maxEdgeLen[pointi], len);
876 const label nInitErrors,
888 Info<<
"Smoothing patch and internal points ..." <<
endl;
892 Info<<
"Smoothing patch points ..." <<
endl;
899 label smoothIter = 0;
904 Info<<
"Smoothing iteration " << smoothIter <<
endl;
908 checkFaces[facei] = facei;
915 pointDisp = smoothInternalDisplacement(meshRefiner, meshMover);
919 pointField patchDisp(smoothPatchDisplacement(meshMover, baffles));
932 scalar oldErrorReduction = -1;
934 for (label snapIter = 0; snapIter < 2*snapParams.
nSnap(); snapIter++)
936 Info<<
nl <<
"Scaling iteration " << snapIter <<
endl;
938 if (snapIter == snapParams.
nSnap())
940 Info<<
"Displacement scaling for error reduction set to 0." 947 if (meshMover.
scaleMesh(checkFaces, baffles,
true, nInitErrors))
949 Info<<
"Successfully moved mesh" <<
endl;
954 if (oldErrorReduction >= 0)
968 Info<<
"Writing patch smoothed mesh to time " 980 Info<<
"Dumped mesh in = " 984 Info<<
"Patch points smoothed in = " 990 void Foam::snappySnapDriver::getZoneSurfacePoints
994 const word& zoneName,
1004 <<
"Cannot find zone " << zoneName
1020 label meshPointi =
f[fp];
1026 const label pointi = iter.
val();
1027 pointOnZone[pointi] =
true;
1042 Field<weightedPosition> avgBoundary
1048 forAll(pointFaces, pointi)
1052 avgBoundary[pointi].first() =
pFaces.size();
1055 label facei =
pFaces[pfi];
1067 return tavgBoundary;
1121 const scalar planarCos,
1130 Info<<
"Detecting near surfaces ..." <<
endl;
1418 forAll(localPoints, pointi)
1420 const point& pt = localPoints[pointi];
1421 const vector d = 2*(avgCc[pointi]-pt);
1422 start[pointi] = pt - d;
1423 end[pointi] = pt + d;
1435 /
"detectNearSurfaces_" + meshRefiner_.timeName() +
".obj" 1441 const bitSet isPatchMasterPoint
1450 label nOverride = 0;
1458 meshRefiner_.surfaces().surfZones()
1489 forAll(localPoints, pointi)
1492 const point& pt = localPoints[pointi];
1494 bool override =
false;
1533 if (hit1[pointi].hit() && hit2[pointi].hit())
1540 hit1[pointi].point(),
1542 hit2[pointi].point(),
1552 gapStr().writeLine(pt, hit2[pointi].
point());
1556 disp[pointi] = hit2[pointi].point()-pt;
1561 if (
override && isPatchMasterPoint[pointi])
1583 label zoneSurfi = zonedSurfaces[i];
1584 const labelList surfacesToTest(1, zoneSurfi);
1587 surfZones[zoneSurfi].faceZoneNames();
1588 forAll(faceZoneNames, namei)
1590 const word& faceZoneName = faceZoneNames[namei];
1594 getZoneSurfacePoints
1601 const labelList zonePointIndices(pointOnZone.toc());
1633 label pointi = zonePointIndices[i];
1636 const point& pt = localPoints[pointi];
1638 bool override =
false;
1677 if (hit1[i].hit() && hit2[i].hit())
1693 gapStr().writeLine(pt, hit2[i].
point());
1696 disp[pointi] = hit2[i].point()-pt;
1701 if (
override && isPatchMasterPoint[pointi])
1710 Info<<
"Overriding nearest with intersection of close gaps at " 1713 <<
" points." <<
endl;
1717 void Foam::snappySnapDriver::calcNearestSurface
1740 if (nearestNormal.
size() == localPoints.
size())
1760 if (hitInfo[i].hit())
1762 label pointi = zonePointIndices[i];
1763 nearestPoint[pointi] = hitInfo[i].point();
1764 nearestNormal[pointi] = hitNormal[i];
1785 if (hitInfo[i].hit())
1787 label pointi = zonePointIndices[i];
1789 patchDisp[pointi] = hitInfo[i].point() - localPoints[pointi];
1790 minSnapDist[pointi] =
mag(patchDisp[pointi]);
1791 snapSurf[pointi] = hitSurface[i];
1799 const bool strictRegionSnap,
1800 const meshRefinement& meshRefiner,
1810 Info<<
"Calculating patchDisplacement as distance to nearest surface" 1811 <<
" point ..." <<
endl;
1812 if (strictRegionSnap)
1814 Info<<
" non-zone points : attract to local region on surface only" 1816 <<
" zone points : attract to local region on surface only" 1822 Info<<
" non-zone points :" 1823 <<
" attract to nearest of all non-zone surfaces" 1825 <<
" zone points : attract to zone surface only" <<
nl 1830 const refinementSurfaces& surfaces = meshRefiner.
surfaces();
1831 const fvMesh&
mesh = meshRefiner.mesh();
1840 labelList snapSurf(localPoints.size(), -1);
1847 if (strictRegionSnap)
1851 forAll(surfaces.surfaces(), surfi)
1853 label geomi = surfaces.surfaces()[surfi];
1854 label nRegions = surfaces.geometry()[geomi].regions().size();
1856 const labelList surfacesToTest(1, surfi);
1858 for (label regioni = 0; regioni < nRegions; regioni++)
1860 label globali = surfaces.globalRegion(surfi, regioni);
1861 label masterPatchi = globalToMasterPatch[globali];
1892 if (globalToSlavePatch[globali] != masterPatchi)
1894 label slavePatchi = globalToSlavePatch[globali];
1934 meshRefiner.surfaces().surfZones()
1941 List<pointIndexHit> hitInfo;
1944 if (nearestNormal.size() == localPoints.size())
1948 surfaces.findNearestRegion
1961 if (hitInfo[pointi].hit())
1963 nearestPoint[pointi] = hitInfo[pointi].point();
1964 nearestNormal[pointi] = hitNormal[pointi];
1970 surfaces.findNearest
1982 if (hitInfo[pointi].hit())
1985 hitInfo[pointi].point()
1986 - localPoints[pointi];
1988 snapSurf[pointi] = hitSurface[pointi];
1995 meshRefiner.surfaces().surfZones()
2004 const PtrList<surfaceZonesInfo>& surfZones = surfaces.surfZones();
2008 label surfi = zonedSurfaces[i];
2009 const labelList surfacesToTest(1, surfi);
2010 const label geomi = surfaces.surfaces()[surfi];
2011 const label nRegions =
2012 surfaces.geometry()[geomi].regions().size();
2015 surfZones[surfi].faceZoneNames();
2019 forAll(faceZoneNames, locali)
2021 getZoneSurfacePoints
2025 faceZoneNames[locali],
2029 const labelList zonePointIndices(pointOnZone.toc());
2056 if (snapSurf[pointi] == -1)
2058 static label nWarn = 0;
2063 <<
"For point:" << pointi
2064 <<
" coordinate:" << localPoints[pointi]
2065 <<
" did not find any surface within:" 2066 << minSnapDist[pointi] <<
" metre." <<
endl;
2071 <<
"Reached warning limit " << nWarn
2072 <<
". Suppressing further warnings." <<
endl;
2079 const bitSet isPatchMasterPoint
2090 Info<<
"Wanted displacement : average:" 2092 <<
" min:" <<
gMin(magDisp)
2093 <<
" max:" <<
gMax(magDisp) <<
endl;
2097 Info<<
"Calculated surface displacement in = " 2103 forAll(patchDisp, patchPointi)
2105 scalar magDisp =
mag(patchDisp[patchPointi]);
2107 if (magDisp > snapDist[patchPointi])
2109 patchDisp[patchPointi] *= snapDist[patchPointi] / magDisp;
2111 Pout<<
"Limiting displacement for " << patchPointi
2112 <<
" from " << magDisp <<
" to " << snapDist[patchPointi]
2124 minMagSqrEqOp<point>(),
2125 vector(GREAT, GREAT, GREAT)
2143 const fvMesh&
mesh = meshRefiner_.mesh();
2146 Info<<
"Smoothing displacement ..." <<
endl;
2156 for (label iter = 0; iter < snapParams.
nSmoothDispl(); iter++)
2158 if ((iter % 10) == 0)
2160 Info<<
"Iteration " << iter <<
endl;
2163 meshMover.
smooth(oldDisp, edgeGamma, disp);
2165 Info<<
"Displacement smoothed in = " 2171 Info<<
"Writing smoothed mesh to time " << meshRefiner_.timeName()
2188 Info<<
"Writing displacement field ..." <<
endl;
2190 tmp<pointScalarField> magDisp(
mag(disp));
2193 Info<<
"Writing actual patch displacement ..." <<
endl;
2198 /
"actualPatchDisplacement_" + meshRefiner_.timeName() +
".obj",
2208 const snapParameters& snapParams,
2209 const label nInitErrors,
2210 const List<labelPair>& baffles,
2211 motionSmoother& meshMover
2215 const fvMesh&
mesh = meshRefiner_.mesh();
2221 scalar oldErrorReduction = -1;
2223 bool meshOk =
false;
2226 for (label iter = 0; iter < 2*snapParams.nSnap(); iter++)
2230 if (iter == snapParams.nSnap())
2232 Info<<
"Displacement scaling for error reduction set to 0." <<
endl;
2233 oldErrorReduction = meshMover.setErrorReduction(0.0);
2236 meshOk = meshMover.scaleMesh(checkFaces, baffles,
true, nInitErrors);
2240 Info<<
"Successfully moved mesh" <<
endl;
2246 Info<<
"Writing scaled mesh to time " << meshRefiner_.timeName()
2250 Info<<
"Writing displacement field ..." <<
endl;
2251 meshMover.displacement().
write();
2252 tmp<pointScalarField> magDisp(
mag(meshMover.displacement()));
2257 if (oldErrorReduction >= 0)
2259 meshMover.setErrorReduction(oldErrorReduction);
2261 Info<<
"Moved mesh in = " 2283 Info<<
"Repatching faces according to nearest surface ..." <<
endl;
2307 forAll(preserveFaces, facei)
2309 if (preserveFaces[facei] != -1)
2311 isZonedFace.set(facei);
2321 const label zoneSurfi = zonedSurfaces[i];
2322 const wordList& fZoneNames = surfZones[zoneSurfi].faceZoneNames();
2325 const faceZone& fZone = fZones[fZoneNames[i]];
2326 isZonedFace.
set(fZone);
2354 forAll(localFaces, facei)
2356 const face&
f = localFaces[facei];
2360 faceSnapDist[facei] =
max 2362 faceSnapDist[facei],
2386 label facei =
pp.addressing()[i];
2388 if (hitSurface[i] != -1 && !isZonedFace.test(facei))
2390 closestPatch[i] = globalToMasterPatch_
2417 ownPatch[
pp.start()+i] = patchi;
2418 neiPatch[
pp.start()+i] = patchi;
2425 label facei =
pp.addressing()[i];
2427 if (closestPatch[i] != -1 && closestPatch[i] != ownPatch[facei])
2429 ownPatch[facei] = closestPatch[i];
2430 neiPatch[facei] = closestPatch[i];
2439 return meshRefiner_.createBaffles(ownPatch, neiPatch);
2443 void Foam::snappySnapDriver::detectWarpedFaces
2445 const scalar featureCos,
2468 forAll(localFaces, facei)
2470 const face&
f = localFaces[facei];
2478 scalar minCos(GREAT);
2480 for (label startFp = 0; startFp <
f.
size()-2; startFp++)
2487 endFp <
f.
size() && endFp != minFp;
2492 f0.setSize(endFp-startFp+1);
2494 for (label fp = startFp; fp <= endFp; fp++)
2500 for (label fp = endFp; fp != startFp; fp =
f.
fcIndex(fp))
2504 f1[i1++] =
f[startFp];
2509 const vector n0 = f0.areaNormal(localPoints);
2510 const scalar n0Mag =
mag(n0);
2512 const vector n1 = f1.areaNormal(localPoints);
2513 const scalar n1Mag =
mag(n1);
2515 if (n0Mag > ROOTVSMALL && n1Mag > ROOTVSMALL)
2517 scalar cosAngle = (n0/n0Mag) & (n1/n1Mag);
2518 if (cosAngle < minCos)
2528 if (minCos < featureCos)
2530 splitFaces.
append(bFaces[facei]);
2538 Foam::labelList Foam::snappySnapDriver::getInternalOrBaffleDuplicateFace()
const 2540 const fvMesh&
mesh = meshRefiner_.mesh();
2544 List<surfaceZonesInfo::faceZoneType> fzTypes(2);
2547 internalOrBaffleFaceZones = meshRefiner_.getZones(fzTypes);
2550 List<labelPair> baffles
2552 meshRefiner_.subsetBaffles
2555 internalOrBaffleFaceZones,
2564 faceToDuplicate[
p[0]] =
p[1];
2565 faceToDuplicate[
p[1]] =
p[0];
2568 return faceToDuplicate;
2577 const scalar featureCos,
2578 const scalar planarAngle,
2599 fvMesh&
mesh = meshRefiner_.mesh();
2602 <<
"Morphing phase" <<
nl 2603 <<
"--------------" <<
nl 2640 DynamicList<label> bufPatchIDs;
2643 bufPatchIDs.setCapacity(globalToMasterPatch_.size());
2645 const auto& addLayers =
2646 meshRefiner_.surfaces().addBufferLayers();
2649 forAll(globalToMasterPatch_, globalRegioni)
2651 if (addLayers[globalRegioni])
2653 const label masterP =
2654 globalToMasterPatch_[globalRegioni];
2655 const label slaveP =
2656 globalToSlavePatch_[globalRegioni];
2658 bufPatchIDs.append(masterP);
2659 if (slaveP != masterP)
2661 bufPatchIDs.append(slaveP);
2671 if (meshRefiner_.getFaceZoneInfo(fz.name(), mpI, spI,
type))
2673 bufPatchIDs.appendUniq(mpI);
2674 bufPatchIDs.appendUniq(spI);
2684 meshRefiner_.getZones
2686 List<surfaceZonesInfo::faceZoneType>
2696 List<labelPair> baffles;
2699 meshRefiner_.createZoneBaffles
2710 autoPtr<mapPolyMesh> map = meshRefiner_.dupNonManifoldBoundaryPoints();
2713 const labelList& reverseFaceMap = map->reverseFaceMap();
2716 label f0 = reverseFaceMap[baffles[i].first()];
2717 label f1 = reverseFaceMap[baffles[i].second()];
2724 bool doFeatures =
false;
2725 label nFeatIter = 1;
2735 Info<<
"Snapping to features in " << nFeatIter
2736 <<
" iterations ..." <<
endl;
2740 bool meshOk =
false;
2744 const labelList adaptPatchIDs(meshRefiner_.meshedPatches());
2749 autoPtr<indirectPrimitivePatch> ppPtr
2763 Info<<
"Constructing mesh displacer ..." <<
endl;
2764 Info<<
"Using mesh parameters " << motionDict <<
nl <<
endl;
2766 autoPtr<motionSmoother> meshMoverPtr
2785 Info<<
"Checking initial mesh ..." <<
endl;
2794 Info<<
"Detected " << nInitErrors <<
" illegal faces" 2795 <<
" (concave, zero area or negative cell pyramid volume)" 2799 Info<<
"Checked initial mesh in = " 2806 meshRefiner_.subsetBaffles
2954 Info<<
"Adding buffer layers ..." <<
endl;
2957 meshMoverPtr.clear();
2968 UIndirectList<label>(numLayers, bufPatchIDs) = 1;
2970 autoPtr<mapPolyMesh> mapPtr =
3067 addPatchCellLayer addLayer(
mesh,
true,
false);
3070 autoPtr<indirectPrimitivePatch> bufPatchPtr
3077 wantedThickness(bufPatchPtr(), 1
e-1)
3087 tmp<pointVectorField> tdisp
3096 UIndirectList<point>(tdisp.ref(),
mp) = thickness;
3100 for (
auto& ppf : tdisp.ref().boundaryFieldRef())
3102 ppf == ppf.patchInternalField();
3107 pcs.constrainDisplacement(tdisp.ref(),
false);
3109 thickness = UIndirectList<point>(tdisp(),
mp);
3119 for (
const label patchi : bufPatchIDs)
3121 maxLen =
max(maxLen, label(
pbm[patchi].
name().size()));
3127 <<
setf(ios_base::left) <<
setw(maxLen) <<
"patch" 3128 <<
setw(0) <<
" faces layers thickness[m]" <<
nl 3129 <<
setf(ios_base::left) <<
setw(maxLen) <<
"-----" 3130 <<
setw(0) <<
" ----- ------ ------------" <<
endl;
3132 for (
const label patchi : bufPatchIDs)
3138 <<
" " <<
setw(6) << 1
3147 autoPtr<mapPolyMesh> mapPtr = addBufferLayers
3178 autoPtr<mapPolyMesh> mapPtr =
3179 meshRefiner_.mergePoints(pointToMaster);
3203 Info<<
"Writing merged points buffer layer mesh" 3204 <<
" to time " << meshRefiner_.timeName() <<
endl;
3213 meshRefiner_.timeName()
3220 Info<<
"Inflating buffer layers ..." <<
endl;
3225 autoPtr<displacementMotionSolver> motionPtr
3237 tmp<pointField> tnewPoints(motionPtr->newPoints());
3248 Info<<
"Writing smoothed buffer layer mesh to time " 3249 << meshRefiner_.timeName() <<
endl;
3258 meshRefiner_.timeName()
3288 List<pointConstraint> patchConstraints;
3292 DynamicList<label> splitFaces;
3294 DynamicList<labelPair> splits;
3296 DynamicList<labelPair> splitPatches;
3299 for (label iter = 0; iter < nFeatIter; iter++)
3302 <<
"Morph iteration " << iter <<
nl 3303 <<
"-----------------" <<
endl;
3306 bool doSplit =
false;
3312 (iter == nFeatIter-1)
3323 motionSmoother& meshMover = meshMoverPtr();
3342 globalToMasterPatch_,
3343 globalToSlavePatch_,
3373 splitPatches.clear();
3374 disp = calcNearestSurfaceFeature
3381 scalar(iter+1)/nFeatIter,
3399 outwardsDisplacement(
pp, disp);
3414 meshMover.setDisplacement(disp);
3422 /
"patchDisplacement_" +
name(iter) +
".obj",
3429 smoothDisplacement(snapParams, meshMover);
3443 <<
"Did not successfully snap mesh." 3444 <<
" Continuing to snap to resolve easy" <<
nl 3445 <<
" surfaces but the" 3446 <<
" resulting mesh will not satisfy your quality" 3447 <<
" constraints" <<
nl <<
endl;
3453 Info<<
"Writing scaled mesh to time " 3454 << meshRefiner_.timeName() <<
endl;
3465 Info<<
"Writing displacement field ..." <<
endl;
3466 meshMover.displacement().
write();
3467 tmp<pointScalarField> magDisp
3469 mag(meshMover.displacement())
3475 meshMover.correct();
3480 label nTotalSplit =
returnReduce(splitFaces.size(), sumOp<label>());
3481 if (nTotalSplit && doSplit)
3486 labelList duplicateFace(getInternalOrBaffleDuplicateFace());
3489 labelList oldSplitFaces(std::move(splitFaces));
3490 List<labelPair> oldSplits(std::move(splits));
3491 List<labelPair> oldSplitPatches(std::move(splitPatches));
3494 if (duplicateFace[oldSplitFaces[i]] == -1)
3496 splitFaces.append(oldSplitFaces[i]);
3497 splits.append(oldSplits[i]);
3498 splitPatches.append(oldSplitPatches[i]);
3513 meshRefiner_.splitFacesUndo
3525 meshMoverPtr.clear();
3548 snapDist = calcSnapDistance(
mesh, snapParams, ppPtr());
3554 Info<<
"Writing split-faces mesh to time " 3555 << meshRefiner_.timeName() <<
endl;
3572 forAll(internalBaffles, i)
3578 if (
mag(fc0-fc1) > meshRefiner_.mergeDistance())
3581 <<
"Separated baffles : f0:" <<
p[0]
3582 <<
" centre:" << fc0
3583 <<
" f1:" <<
p[1] <<
" centre:" << fc1
3584 <<
" distance:" <<
mag(fc0-fc1)
3599 autoPtr<mapPolyMesh> mapPtr = meshRefiner_.mergeZoneBaffles
3610 Info<<
"Writing baffle-merged mesh to time " 3611 << meshRefiner_.timeName() <<
endl;
3620 meshRefiner_.timeName()
3628 labelList duplicateFace(getInternalOrBaffleDuplicateFace());
3630 repatchToSurface(snapParams, adaptPatchIDs, duplicateFace);
3635 mergeType == meshRefinement::FaceMergeType::GEOMETRIC
3636 || mergeType == meshRefinement::FaceMergeType::IGNOREPATCH
3639 labelList duplicateFace(getInternalOrBaffleDuplicateFace());
3644 label nChanged = meshRefiner_.mergePatchFacesUndo
3648 meshRefiner_.meshedPatches(),
3654 nChanged += meshRefiner_.mergeEdgesUndo(featureCos, motionDict);
3659 Info<<
"Writing patchFace merged mesh to time " 3660 << meshRefiner_.timeName() <<
endl;
3669 meshRefiner_.timeName()
Given a displacement moves the mesh by scaling the displacement back until there are no more mesh err...
const labelListList & pointEdges() const
Return point-edge addressing.
Switch detectNearSurfacesSnap() const
Override attraction to nearest with intersection location.
static bool checkMesh(const bool report, const polyMesh &mesh, const dictionary &dict, labelHashSet &wrongFaces, const bool dryRun=false)
Check mesh with mesh settings in dict. Collects incorrect faces.
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.
reference val() const
Const access to referenced object (value)
void size(const label n)
Older name for setAddressableSize.
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with the type faceZone.
fileName path() const
Return path = rootPath/caseName. Same as TimePaths::path()
label nSmoothDispl() const
Number of mesh displacement smoothing iterations.
const labelList & surfaces() const
static void mapBaffles(const polyMesh &mesh, const labelList &faceMap, List< labelPair > &baffles)
Map baffles after layer addition. Gets new-to-old face map.
bool scaleMesh(const snapParameters &snapParams, const label nInitErrors, const List< labelPair > &baffles, motionSmoother &)
Do the hard work: move the mesh according to displacement,.
errorManipArg< error, int > exit(error &err, const int errNo=1)
A face is a list of labels corresponding to mesh vertices.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const Field< point_type > & localPoints() const
Return pointField of points in patch.
label nPoints() const noexcept
Number of mesh points.
void doSnap(const dictionary &snapDict, const dictionary &motionDict, const meshRefinement::FaceMergeType mergeType, const scalar featureCos, const scalar planarAngle, const snapParameters &snapParams)
Snap onto surface & features.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Type gMin(const FieldField< Field, Type > &f)
virtual const labelList & faceNeighbour() const
Return face neighbour.
static const weightedPosition zero
const word & name() const noexcept
Return the object name.
static const pointMesh & New(const polyMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
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.
bool scaleMesh(labelList &checkFaces, const bool smoothMesh=true, const label nAllow=0)
Move mesh with given scale. Return true if mesh ok or has.
constexpr char nl
The newline '\n' character (0x0a)
const pointMesh & pMesh() const
Reference to pointMesh.
label nSmoothPatch() const
Number of patch smoothing iterations before finding.
T & first()
Access first element of the list, position [0].
dimensionedScalar sqrt(const dimensionedScalar &ds)
Ostream & endl(Ostream &os)
Add newline and flush stream.
virtual void movePoints(const pointField &)
Move points, returns volumes swept by faces in motion.
static writeType writeLevel()
Get/set write level.
#define addProfiling(Name,...)
Define profiling trigger with specified name and description string. The description is generated by ...
GeometricField< vector, pointPatchField, pointMesh > pointVectorField
void setCapacity(const label len)
Alter the size of the underlying storage.
List< labelPair > labelPairList
List of labelPair.
static void getPoints(const UList< weightedPosition > &in, List< point > &out)
Get points.
static List< labelPair > subsetBaffles(const polyMesh &mesh, const labelList &zoneIDs, const List< labelPair > &baffles)
Subset baffles according to zones.
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.
void findNearest(const labelList &surfacesToTest, const pointField &samples, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &) const
Find nearest point on surfaces.
label nFeatureSnap() const
const labelList & meshPoints() const
Return labelList of mesh points in patch.
Pair< int > faceMap(const label facePi, const face &faceP, const label faceNi, const face &faceN)
void smooth(volScalarField &field, const scalar coeff)
const fvMesh & mesh() const
Reference to mesh.
static labelPairList findDuplicateFacePairs(const polyMesh &)
Helper routine to find all baffles (two boundary faces.
label nTotalPoints() const noexcept
Total global number of mesh points. Not compensated for duplicate points!
Container for data on surfaces used for surface-driven refinement. Contains all the data about the le...
virtual const pointField & points() const
Return raw points.
#define forAll(list, i)
Loop across all elements in list.
void correct()
Take over existing mesh position.
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...
label mergePoints(const PointList &points, labelList &pointToUnique, labelList &uniquePoints, const scalar mergeTol=SMALL, const bool verbose=false)
Calculate merge mapping, preserving the original point order. All points closer/equal mergeTol are to...
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
List< face > faceList
List of faces.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
A list of faces which address into the list of points.
Omanip< int > setprecision(const int i)
const Map< label > & meshPointMap() const
Mesh point map.
vectorField pointField
pointField is a vectorField.
const dimensionedScalar e
Elementary charge.
void setSize(const label n)
Alias for resize()
scalar setErrorReduction(const scalar)
Set the errorReduction (by how much to scale the displacement.
FaceMergeType
Enumeration for what to do with co-planar patch faces on a single.
dimensionedScalar cos(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
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.
label nFaceSplitInterval() const
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
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.
virtual int precision() const override
Get precision of output field.
const polyBoundaryMesh & boundaryMesh() const noexcept
Return boundary mesh.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Simple container to keep together snap specific information.
autoPtr< mapPolyMesh > repatchToSurface(const snapParameters &snapParams, const labelList &adaptPatchIDs, const labelList &preserveFaces)
Repatch faces according to surface nearest the face centre.
label size() const noexcept
The number of entries in the list.
const Field< point_type > & faceCentres() const
Return face centres for patch.
virtual const labelList & faceOwner() const
Return face owner.
static void setDisplacement(const labelList &patchIDs, const indirectPrimitivePatch &pp, pointField &patchDisp, pointVectorField &displacement)
Set displacement field from displacement on patch points.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
void smoothDisplacement(const snapParameters &snapParams, motionSmoother &) const
Smooth the displacement field to the internal.
const globalMeshData & globalData() const
Return parallel info (demand-driven)
const edgeList & edges() const
Return list of edges, address into LOCAL point list.
static void preSmoothPatch(const meshRefinement &meshRefiner, const snapParameters &snapParams, const label nInitErrors, const List< labelPair > &baffles, motionSmoother &)
Smooth the mesh (patch and internal) to increase visibility.
label nInternalFaces() const noexcept
Number of internal faces.
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with the type pointZone.
const Field< point_type > & points() const noexcept
Return reference to global points.
void append(const T &val)
Copy append an element to the end of this list.
virtual const faceList & faces() const
Return raw faces.
const PtrList< surfaceZonesInfo > & surfZones() const
const vectorField & cellCentres() const
static labelList getUnnamedSurfaces(const PtrList< surfaceZonesInfo > &surfList)
Get indices of unnamed surfaces (surfaces without faceZoneName)
errorManip< error > abort(error &err)
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie...
label nEdges() const
Number of mesh edges.
const labelListList & pointCells() const
virtual bool write(const bool writeOnProc=true) const
Write mesh using IO settings from time.
void smooth(const GeometricField< Type, pointPatchField, pointMesh > &fld, const scalarField &edgeWeight, GeometricField< Type, pointPatchField, pointMesh > &newFld) const
Fully explicit smoothing of fields (not positions)
word timeName() const
Replacement for Time::timeName() that returns oldInstance (if overwrite_)
static scalarField calcSnapDistance(const fvMesh &mesh, const snapParameters &snapParams, const indirectPrimitivePatch &)
Calculate edge length per patch point.
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO...
OSstream & stream(OSstream *alternative=nullptr)
Return OSstream for output operations.
const labelListList & pointFaces() const
Return point-face addressing.
Istream and Ostream manipulators taking arguments.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
An OFstream that keeps track of vertices and provides convenience output methods for OBJ files...
Smanip< std::ios_base::fmtflags > setf(std::ios_base::fmtflags flags)
int debug
Static debugging option.
static void mapFaceZonePoints(meshRefinement &meshRefiner, const mapPolyMesh &map, labelPairList &baffles, labelList &pointToMaster)
Map numbering after adding cell layers.
Pair< label > labelPair
A pair of labels.
Type gMax(const FieldField< Field, Type > &f)
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
defineTypeNameAndDebug(combustionModel, 0)
const indirectPrimitivePatch & patch() const
Reference to patch.
static tmp< pointField > avgCellCentres(const fvMesh &mesh, const indirectPrimitivePatch &)
Helper: calculate average cell centre per point.
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Geometric merging of points. See below.
static autoPtr< indirectPrimitivePatch > makePatch(const polyMesh &, const labelList &)
Create patch from set of patches.
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]
double cpuTimeIncrement() const
Return CPU time [seconds] since last call to cpuTimeIncrement(), resetCpuTimeIncrement().
messageStream Warning
Warning stream (stdout output on master, null elsewhere), with additional 'FOAM Warning' header text...
Helper class which maintains intersections of (changing) mesh with (static) surfaces.
pointVectorField & pointDisplacement()
Return reference to the point motion displacement field.
bool moving() const noexcept
Is mesh moving.
const vectorField & faceCentres() const
const pointZoneMesh & pointZones() const noexcept
Return point zone mesh.
List< word > wordList
List of word.
label nSnap() const
Maximum number of snapping relaxation iterations. Should stop.
PrimitivePatch< UIndirectList< face >, const pointField & > uindirectPrimitivePatch
A PrimitivePatch with UIndirectList for the faces, const reference for the point field.
Internal::FieldType & primitiveFieldRef(const bool updateAccessTime=true)
Return a reference to the internal field values.
scalar snapTol() const
Relative distance for points to be attracted by surface.
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.
Switch strictRegionSnap() const
Attract point to corresponding surface region only.
Type gAverage(const FieldField< Field, Type > &f)
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
void detectNearSurfaces(const scalar planarCos, const indirectPrimitivePatch &pp, const pointField &ppLocalPoints, const pointField &nearestPoint, const vectorField &nearestNormal, vectorField &disp) const
Per patch point override displacement if in gap situation.
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 polyBoundaryMesh & patches
label globalRegion(const label surfI, const label regionI) const
From surface and region on surface to global region.
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)
label nTotalFaces() const noexcept
Total global number of mesh faces. Not compensated for duplicate faces!
SubField< vector > subField
Declare type of subField.
writeType
Enumeration for what to write. Used as a bit-pattern.
Field< vector > vectorField
Specialisation of Field<T> for vector.
faceZoneType
What to do with faceZone faces.
debugType
Enumeration for what to debug. Used as a bit-pattern.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Omanip< int > setw(const int i)
A subset of mesh faces organised as a primitive patch.
static void syncPoints(const polyMesh &mesh, List< weightedPosition > &)
Synchronisation for mesh point positions.
bool write() const
Write mesh and all data.
List< label > labelList
A List of labels.
static tmp< pointVectorField > makeDisplacementField(const pointMesh &pMesh, const labelList &adaptPatchIDs)
Helper function to make a pointVectorField with correct.
A class for managing temporary objects.
label nSmoothInternal() const
Number of internal point smoothing iterations (combined with.
A patch is a list of labels that address the faces in the global face list.
static T gAverage(const bitSet &isMasterElem, const UList< T > &values)
Helper: calculate average.
void findNearestIntersection(const labelList &surfacesToTest, const pointField &start, const pointField &end, labelList &surface1, List< pointIndexHit > &hit1, labelList ®ion1, labelList &surface2, List< pointIndexHit > &hit2, labelList ®ion2) const
Find intersection nearest to the endpoints. surface1,2 are.
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...
static autoPtr< mapPolyMesh > dupFaceZonePoints(meshRefinement &meshRefiner, const labelList &patchIDs, const labelList &numLayers, List< labelPair > baffles, labelList &pointToMaster)
Duplicate points on faceZones with layers. Re-used when adding buffer layers. Can be made private aga...
bool returnReduceOr(const bool value, const label comm=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
const dimensionedScalar mp
Proton mass.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
pointVectorField & displacement()
Reference to displacement field.
static constexpr const zero Zero
Global zero (0)