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
2092 Info<<
"Wanted displacement : average:" 2094 <<
" min:" <<
limits.min()
2099 Info<<
"Calculated surface displacement in = " 2105 forAll(patchDisp, patchPointi)
2107 scalar magDisp =
mag(patchDisp[patchPointi]);
2109 if (magDisp > snapDist[patchPointi])
2111 patchDisp[patchPointi] *= snapDist[patchPointi] / magDisp;
2113 Pout<<
"Limiting displacement for " << patchPointi
2114 <<
" from " << magDisp <<
" to " << snapDist[patchPointi]
2126 minMagSqrEqOp<point>(),
2127 vector(GREAT, GREAT, GREAT)
2145 const fvMesh&
mesh = meshRefiner_.mesh();
2148 Info<<
"Smoothing displacement ..." <<
endl;
2158 for (label iter = 0; iter < snapParams.
nSmoothDispl(); iter++)
2160 if ((iter % 10) == 0)
2162 Info<<
"Iteration " << iter <<
endl;
2165 meshMover.
smooth(oldDisp, edgeGamma, disp);
2167 Info<<
"Displacement smoothed in = " 2173 Info<<
"Writing smoothed mesh to time " << meshRefiner_.timeName()
2190 Info<<
"Writing displacement field ..." <<
endl;
2192 tmp<pointScalarField> magDisp(
mag(disp));
2195 Info<<
"Writing actual patch displacement ..." <<
endl;
2200 /
"actualPatchDisplacement_" + meshRefiner_.timeName() +
".obj",
2210 const snapParameters& snapParams,
2211 const label nInitErrors,
2212 const List<labelPair>& baffles,
2213 motionSmoother& meshMover
2217 const fvMesh&
mesh = meshRefiner_.mesh();
2223 scalar oldErrorReduction = -1;
2225 bool meshOk =
false;
2228 for (label iter = 0; iter < 2*snapParams.nSnap(); iter++)
2232 if (iter == snapParams.nSnap())
2234 Info<<
"Displacement scaling for error reduction set to 0." <<
endl;
2235 oldErrorReduction = meshMover.setErrorReduction(0.0);
2238 meshOk = meshMover.scaleMesh(checkFaces, baffles,
true, nInitErrors);
2242 Info<<
"Successfully moved mesh" <<
endl;
2248 Info<<
"Writing scaled mesh to time " << meshRefiner_.timeName()
2252 Info<<
"Writing displacement field ..." <<
endl;
2253 meshMover.displacement().
write();
2254 tmp<pointScalarField> magDisp(
mag(meshMover.displacement()));
2259 if (oldErrorReduction >= 0)
2261 meshMover.setErrorReduction(oldErrorReduction);
2263 Info<<
"Moved mesh in = " 2285 Info<<
"Repatching faces according to nearest surface ..." <<
endl;
2309 forAll(preserveFaces, facei)
2311 if (preserveFaces[facei] != -1)
2313 isZonedFace.set(facei);
2323 const label zoneSurfi = zonedSurfaces[i];
2324 const wordList& fZoneNames = surfZones[zoneSurfi].faceZoneNames();
2327 const faceZone& fZone = fZones[fZoneNames[i]];
2328 isZonedFace.
set(fZone);
2356 forAll(localFaces, facei)
2358 const face&
f = localFaces[facei];
2362 faceSnapDist[facei] =
max 2364 faceSnapDist[facei],
2388 label facei =
pp.addressing()[i];
2390 if (hitSurface[i] != -1 && !isZonedFace.test(facei))
2392 closestPatch[i] = globalToMasterPatch_
2419 ownPatch[
pp.start()+i] = patchi;
2420 neiPatch[
pp.start()+i] = patchi;
2427 label facei =
pp.addressing()[i];
2429 if (closestPatch[i] != -1 && closestPatch[i] != ownPatch[facei])
2431 ownPatch[facei] = closestPatch[i];
2432 neiPatch[facei] = closestPatch[i];
2441 return meshRefiner_.createBaffles(ownPatch, neiPatch);
2445 void Foam::snappySnapDriver::detectWarpedFaces
2447 const scalar featureCos,
2470 forAll(localFaces, facei)
2472 const face&
f = localFaces[facei];
2480 scalar minCos(GREAT);
2482 for (label startFp = 0; startFp <
f.
size()-2; startFp++)
2489 endFp <
f.
size() && endFp != minFp;
2494 f0.setSize(endFp-startFp+1);
2496 for (label fp = startFp; fp <= endFp; fp++)
2502 for (label fp = endFp; fp != startFp; fp =
f.
fcIndex(fp))
2506 f1[i1++] =
f[startFp];
2511 const vector n0 = f0.areaNormal(localPoints);
2512 const scalar n0Mag =
mag(n0);
2514 const vector n1 = f1.areaNormal(localPoints);
2515 const scalar n1Mag =
mag(n1);
2517 if (n0Mag > ROOTVSMALL && n1Mag > ROOTVSMALL)
2519 scalar cosAngle = (n0/n0Mag) & (n1/n1Mag);
2520 if (cosAngle < minCos)
2530 if (minCos < featureCos)
2532 splitFaces.
append(bFaces[facei]);
2540 Foam::labelList Foam::snappySnapDriver::getInternalOrBaffleDuplicateFace()
const 2542 const fvMesh&
mesh = meshRefiner_.mesh();
2546 List<surfaceZonesInfo::faceZoneType> fzTypes(2);
2549 internalOrBaffleFaceZones = meshRefiner_.getZones(fzTypes);
2552 List<labelPair> baffles
2554 meshRefiner_.subsetBaffles
2557 internalOrBaffleFaceZones,
2566 faceToDuplicate[
p[0]] =
p[1];
2567 faceToDuplicate[
p[1]] =
p[0];
2570 return faceToDuplicate;
2579 const scalar featureCos,
2580 const scalar planarAngle,
2601 fvMesh&
mesh = meshRefiner_.mesh();
2604 <<
"Morphing phase" <<
nl 2605 <<
"--------------" <<
nl 2642 DynamicList<label> bufPatchIDs;
2645 bufPatchIDs.setCapacity(globalToMasterPatch_.size());
2647 const auto& addLayers =
2648 meshRefiner_.surfaces().addBufferLayers();
2651 forAll(globalToMasterPatch_, globalRegioni)
2653 if (addLayers[globalRegioni])
2655 const label masterP =
2656 globalToMasterPatch_[globalRegioni];
2657 const label slaveP =
2658 globalToSlavePatch_[globalRegioni];
2660 bufPatchIDs.append(masterP);
2661 if (slaveP != masterP)
2663 bufPatchIDs.append(slaveP);
2673 if (meshRefiner_.getFaceZoneInfo(fz.name(), mpI, spI,
type))
2675 bufPatchIDs.push_uniq(mpI);
2676 bufPatchIDs.push_uniq(spI);
2686 meshRefiner_.getZones
2688 List<surfaceZonesInfo::faceZoneType>
2698 List<labelPair> baffles;
2701 meshRefiner_.createZoneBaffles
2712 autoPtr<mapPolyMesh> map = meshRefiner_.dupNonManifoldBoundaryPoints();
2715 const labelList& reverseFaceMap = map->reverseFaceMap();
2718 label f0 = reverseFaceMap[baffles[i].first()];
2719 label f1 = reverseFaceMap[baffles[i].second()];
2726 bool doFeatures =
false;
2727 label nFeatIter = 1;
2737 Info<<
"Snapping to features in " << nFeatIter
2738 <<
" iterations ..." <<
endl;
2742 bool meshOk =
false;
2746 const labelList adaptPatchIDs(meshRefiner_.meshedPatches());
2751 autoPtr<indirectPrimitivePatch> ppPtr
2765 Info<<
"Constructing mesh displacer ..." <<
endl;
2766 Info<<
"Using mesh parameters " << motionDict <<
nl <<
endl;
2768 autoPtr<motionSmoother> meshMoverPtr
2787 Info<<
"Checking initial mesh ..." <<
endl;
2796 Info<<
"Detected " << nInitErrors <<
" illegal faces" 2797 <<
" (concave, zero area or negative cell pyramid volume)" 2801 Info<<
"Checked initial mesh in = " 2808 meshRefiner_.subsetBaffles
2956 Info<<
"Adding buffer layers ..." <<
endl;
2959 meshMoverPtr.clear();
2970 UIndirectList<label>(numLayers, bufPatchIDs) = 1;
2972 autoPtr<mapPolyMesh> mapPtr =
3069 addPatchCellLayer addLayer(
mesh,
true,
false);
3072 autoPtr<indirectPrimitivePatch> bufPatchPtr
3079 wantedThickness(bufPatchPtr(), 1
e-1)
3089 tmp<pointVectorField> tdisp
3098 UIndirectList<point>(tdisp.ref(),
mp) = thickness;
3102 for (
auto& ppf : tdisp.ref().boundaryFieldRef())
3104 ppf == ppf.patchInternalField();
3109 pcs.constrainDisplacement(tdisp.ref(),
false);
3111 thickness = UIndirectList<point>(tdisp(),
mp);
3121 for (
const label patchi : bufPatchIDs)
3123 maxLen =
max(maxLen, label(
pbm[patchi].
name().size()));
3129 <<
setf(ios_base::left) <<
setw(maxLen) <<
"patch" 3130 <<
setw(0) <<
" faces layers thickness[m]" <<
nl 3131 <<
setf(ios_base::left) <<
setw(maxLen) <<
"-----" 3132 <<
setw(0) <<
" ----- ------ ------------" <<
endl;
3134 for (
const label patchi : bufPatchIDs)
3140 <<
" " <<
setw(6) << 1
3149 autoPtr<mapPolyMesh> mapPtr = addBufferLayers
3180 autoPtr<mapPolyMesh> mapPtr =
3181 meshRefiner_.mergePoints(pointToMaster);
3205 Info<<
"Writing merged points buffer layer mesh" 3206 <<
" to time " << meshRefiner_.timeName() <<
endl;
3215 meshRefiner_.timeName()
3222 Info<<
"Inflating buffer layers ..." <<
endl;
3227 autoPtr<displacementMotionSolver> motionPtr
3239 tmp<pointField> tnewPoints(motionPtr->newPoints());
3250 Info<<
"Writing smoothed buffer layer mesh to time " 3251 << meshRefiner_.timeName() <<
endl;
3260 meshRefiner_.timeName()
3269 snapDist = calcSnapDistance(
mesh, snapParams, ppPtr());
3294 List<pointConstraint> patchConstraints;
3298 DynamicList<label> splitFaces;
3300 DynamicList<labelPair> splits;
3302 DynamicList<labelPair> splitPatches;
3305 for (label iter = 0; iter < nFeatIter; iter++)
3308 <<
"Morph iteration " << iter <<
nl 3309 <<
"-----------------" <<
endl;
3312 bool doSplit =
false;
3318 (iter == nFeatIter-1)
3329 motionSmoother& meshMover = meshMoverPtr();
3348 globalToMasterPatch_,
3349 globalToSlavePatch_,
3379 splitPatches.clear();
3380 disp = calcNearestSurfaceFeature
3387 scalar(iter+1)/nFeatIter,
3405 outwardsDisplacement(
pp, disp);
3420 meshMover.setDisplacement(disp);
3428 /
"patchDisplacement_" +
name(iter) +
".obj",
3435 smoothDisplacement(snapParams, meshMover);
3449 <<
"Did not successfully snap mesh." 3450 <<
" Continuing to snap to resolve easy" <<
nl 3451 <<
" surfaces but the" 3452 <<
" resulting mesh will not satisfy your quality" 3453 <<
" constraints" <<
nl <<
endl;
3459 Info<<
"Writing scaled mesh to time " 3460 << meshRefiner_.timeName() <<
endl;
3471 Info<<
"Writing displacement field ..." <<
endl;
3472 meshMover.displacement().
write();
3473 tmp<pointScalarField> magDisp
3475 mag(meshMover.displacement())
3481 meshMover.correct();
3486 label nTotalSplit =
returnReduce(splitFaces.size(), sumOp<label>());
3487 if (nTotalSplit && doSplit)
3492 labelList duplicateFace(getInternalOrBaffleDuplicateFace());
3495 labelList oldSplitFaces(std::move(splitFaces));
3496 List<labelPair> oldSplits(std::move(splits));
3497 List<labelPair> oldSplitPatches(std::move(splitPatches));
3500 if (duplicateFace[oldSplitFaces[i]] == -1)
3502 splitFaces.append(oldSplitFaces[i]);
3503 splits.append(oldSplits[i]);
3504 splitPatches.append(oldSplitPatches[i]);
3519 meshRefiner_.splitFacesUndo
3531 meshMoverPtr.clear();
3554 snapDist = calcSnapDistance(
mesh, snapParams, ppPtr());
3560 Info<<
"Writing split-faces mesh to time " 3561 << meshRefiner_.timeName() <<
endl;
3578 forAll(internalBaffles, i)
3584 if (
mag(fc0-fc1) > meshRefiner_.mergeDistance())
3587 <<
"Separated baffles : f0:" <<
p[0]
3588 <<
" centre:" << fc0
3589 <<
" f1:" <<
p[1] <<
" centre:" << fc1
3590 <<
" distance:" <<
mag(fc0-fc1)
3605 autoPtr<mapPolyMesh> mapPtr = meshRefiner_.mergeZoneBaffles
3616 Info<<
"Writing baffle-merged mesh to time " 3617 << meshRefiner_.timeName() <<
endl;
3626 meshRefiner_.timeName()
3634 labelList duplicateFace(getInternalOrBaffleDuplicateFace());
3636 repatchToSurface(snapParams, adaptPatchIDs, duplicateFace);
3641 mergeType == meshRefinement::FaceMergeType::GEOMETRIC
3642 || mergeType == meshRefinement::FaceMergeType::IGNOREPATCH
3645 labelList duplicateFace(getInternalOrBaffleDuplicateFace());
3650 label nChanged = meshRefiner_.mergePatchFacesUndo
3654 meshRefiner_.meshedPatches(),
3660 nChanged += meshRefiner_.mergeEdgesUndo(featureCos, motionDict);
3665 Info<<
"Writing patchFace merged mesh to time " 3666 << meshRefiner_.timeName() <<
endl;
3675 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.
virtual const labelList & faceNeighbour() const
Return face neighbour.
static const weightedPosition zero
const word & name() const noexcept
Return the object name.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
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.
static FOAM_NO_DANGLING_REFERENCE const pointMesh & New(const polyMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
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...
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.
MinMax< Type > gMinMax(const FieldField< Field, Type > &f)
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.
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];} pointMap[start]=pointMap[end]=Foam::min(start, end);} } 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};constexpr 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< DynamicList< face > > pFaces[nBCs]
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
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.
OSstream & stream(OSstream *alternative=nullptr, int communicator=-1)
Return OSstream for output operations.
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)
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
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 registered IO, a reference to the associated polyMesh...
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.
Type gAverage(const FieldField< Field, Type > &f, const label comm)
The global arithmetic average of a FieldField.
Pair< label > labelPair
A pair of labels.
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.
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.
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...
std::enable_if_t< std::is_same_v< bool, TypeT >, bool > set(const label i, bool val=true)
A bitSet::set() method for a list of bool.
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...
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)