45 Foam::label Foam::meshRefinement::markSurfaceGapRefinement
47 const scalar planarCos,
49 const label nAllowRefine,
63 label oldNRefine = nRefine;
65 if (
max(maxLevel) > 0)
73 labelList testFaces(getRefineCandidateFaces(refineCell));
98 List<FixedList<label, 3>> shellGapInfo;
99 List<volumeType> shellGapMode;
101 DynamicField<point> compactToCc(mesh_.
nCells()/10);
102 DynamicList<label> compactToLevel(compactToCc.capacity());
105 label faceI = testFaces[i];
107 if (cellToCompact[own] == -1)
109 cellToCompact[own] = compactToCc.size();
110 compactToCc.
append(cellCentres[own]);
111 compactToLevel.append(cellLevel[own]);
116 if (cellToCompact[nei] == -1)
118 cellToCompact[nei] = compactToCc.size();
119 compactToCc.
append(cellCentres[nei]);
120 compactToLevel.append(cellLevel[nei]);
126 if (bFaceToCompact[bFaceI] == -1)
128 bFaceToCompact[bFaceI] = compactToCc.size();
129 compactToCc.append(neiCc[bFaceI]);
130 compactToLevel.append(neiLevel[bFaceI]);
135 shells_.findHigherGapLevel
192 const List<FixedList<label, 3>>& extendedGapLevel =
194 const List<volumeType>& extendedGapMode =
199 List<pointIndexHit> ccHit1;
204 List<pointIndexHit> ccHit2;
229 DynamicField<point> rayStart(2*ccSurface1.size());
230 DynamicField<point> rayEnd(2*ccSurface1.size());
231 DynamicField<scalar> gapSize(2*ccSurface1.size());
233 DynamicField<point> rayStart2(2*ccSurface1.size());
234 DynamicField<point> rayEnd2(2*ccSurface1.size());
235 DynamicField<scalar> gapSize2(2*ccSurface1.size());
237 DynamicList<label> cellMap(2*ccSurface1.size());
238 DynamicList<label> compactMap(2*ccSurface1.size());
242 label surfI = ccSurface1[i];
246 label globalRegionI =
249 label faceI = testFaces[i];
250 const point& surfPt = ccHit1[i].hitPoint();
255 cellToCompact[own] != -1
256 && shellGapInfo[cellToCompact[own]][2] > 0
260 label compactI = cellToCompact[own];
261 FixedList<label, 3> gapInfo;
265 shellGapInfo[compactI],
266 shellGapMode[compactI],
267 extendedGapLevel[globalRegionI],
268 extendedGapMode[globalRegionI],
274 const point& cc = cellCentres[own];
275 label nRays = generateRays
282 surfPt+((cc-surfPt)&ccNormal1[i])*ccNormal1[i],
293 for (label j = 0; j < nRays; j++)
296 compactMap.append(i);
304 cellToCompact[nei] != -1
305 && shellGapInfo[cellToCompact[nei]][2] > 0
309 label compactI = cellToCompact[nei];
310 FixedList<label, 3> gapInfo;
314 shellGapInfo[compactI],
315 shellGapMode[compactI],
316 extendedGapLevel[globalRegionI],
317 extendedGapMode[globalRegionI],
323 const point& cc = cellCentres[nei];
324 label nRays = generateRays
331 surfPt+((cc-surfPt)&ccNormal1[i])*ccNormal1[i],
342 for (label j = 0; j < nRays; j++)
345 compactMap.append(i);
359 bFaceToCompact[bFaceI] != -1
360 && shellGapInfo[bFaceToCompact[bFaceI]][2] > 0
364 label compactI = bFaceToCompact[bFaceI];
365 FixedList<label, 3> gapInfo;
369 shellGapInfo[compactI],
370 shellGapMode[compactI],
371 extendedGapLevel[globalRegionI],
372 extendedGapMode[globalRegionI],
378 const point& cc = neiCc[bFaceI];
379 label nRays = generateRays
386 surfPt+((cc-surfPt)&ccNormal1[i])*ccNormal1[i],
397 for (label j = 0; j < nRays; j++)
400 compactMap.append(i);
408 <<
" rays from " <<
returnReduce(testFaces.size(), sumOp<label>())
409 <<
" intersected faces" <<
endl;
426 ccNormal1 = UIndirectList<vector>(ccNormal1, compactMap)();
431 List<pointIndexHit> hit1;
443 List<pointIndexHit> hit2;
458 const label cellI = cellMap[i];
461 cellToCompact[cellI] != -1
462 ? gapShell[cellToCompact[cellI]]
466 bool selfProx =
true;
469 selfProx = shells_.
gapSelf()[shelli][0];
471 if (surf1[i] != -1 && selfProx)
473 const label globalRegioni = surfaces_.
globalRegion(surf1[i], 0);
474 selfProx = extendedGapSelf[globalRegioni];
481 && (surf2[i] != surf1[i] || selfProx)
485 label cellI = cellMap[i];
490 && (
mag(normal1[i]&normal2[i]) > planarCos)
492 magSqr(hit1[i].hitPoint()-hit2[i].hitPoint())
520 Info<<
"Reached refinement limit." <<
endl;
524 return returnReduce(nRefine-oldNRefine, sumOp<label>());
765 Foam::label Foam::meshRefinement::generateRays
767 const point& nearPoint,
769 const FixedList<label, 3>& gapInfo,
770 const volumeType&
mode,
774 DynamicField<point>& start,
775 DynamicField<point>&
end
778 label nOldRays = start.size();
780 if (cLevel >= gapInfo[1] && cLevel < gapInfo[2] && gapInfo[0] > 0)
782 scalar cellSize = meshCutter_.level0EdgeLength()/
pow(2.0, cLevel);
785 scalar nearGap = gapInfo[0]*cellSize;
794 start.append(nearPoint+1
e-6*
n);
795 end.append(nearPoint+nearGap*
n);
799 start.append(nearPoint-1
e-6*
n);
800 end.append(nearPoint-nearGap*
n);
804 start.append(nearPoint+1
e-6*
n);
805 end.append(nearPoint+nearGap*
n);
807 start.append(nearPoint-1
e-6*
n);
808 end.append(nearPoint-nearGap*
n);
812 return start.size()-nOldRays;
816 Foam::label Foam::meshRefinement::generateRays
818 const bool useSurfaceNormal,
820 const point& nearPoint,
822 const FixedList<label, 3>& gapInfo,
823 const volumeType&
mode,
828 DynamicField<point>& start,
829 DynamicField<point>&
end,
830 DynamicField<scalar>& gapSize,
832 DynamicField<point>& start2,
833 DynamicField<point>& end2,
834 DynamicField<scalar>& gapSize2
894 label nOldRays = start.size();
896 if (cLevel >= gapInfo[1] && cLevel < gapInfo[2] && gapInfo[0] > 0)
898 scalar cellSize = meshCutter_.level0EdgeLength()/
pow(2.0, cLevel);
901 scalar nearGap = gapInfo[0]*cellSize;
905 scalar magV =
mag(v);
907 if (useSurfaceNormal || magV < 0.5*cellSize)
916 start.append(nearPoint+1
e-6*
n);
917 end.append(nearPoint+nearGap*
n);
918 gapSize.append(nearGap);
920 start2.append(nearPoint+1
e-6*
n);
921 end2.append(nearPoint-1
e-6*
n);
922 gapSize2.append(gapSize.last());
926 start.append(nearPoint-1
e-6*
n);
927 end.append(nearPoint-nearGap*
n);
928 gapSize.append(nearGap);
930 start2.append(nearPoint-1
e-6*
n);
931 end2.append(nearPoint+1
e-6*
n);
932 gapSize2.append(gapSize.last());
939 start.append(nearPoint+1
e-6*
n);
940 end.append(nearPoint+nearGap*
n);
941 gapSize.append(nearGap);
943 start2.append(nearPoint+1
e-6*
n);
944 end2.append(nearPoint-1
e-6*
n);
945 gapSize2.append(gapSize.last());
949 start.append(nearPoint-1
e-6*
n);
950 end.append(nearPoint-nearGap*
n);
951 gapSize.append(nearGap);
953 start2.append(nearPoint-1
e-6*
n);
954 end2.append(nearPoint+1
e-6*
n);
955 gapSize2.append(gapSize.last());
967 scalar
s = (v&nearNormal);
1020 vector n(v/(magV+ROOTVSMALL));
1024 scalar
s = (e2 &
n);
1042 end.append(cc+nearGap*
n);
1043 gapSize.append(nearGap);
1046 end2.append(cc-nearGap*
n);
1047 gapSize2.append(nearGap);
1051 end.append(cc+nearGap*e2);
1052 gapSize.append(nearGap);
1055 end2.append(cc-nearGap*e2);
1056 gapSize2.append(nearGap);
1060 end.append(cc+nearGap*e3);
1061 gapSize.append(nearGap);
1064 end2.append(cc-nearGap*e3);
1065 gapSize2.append(nearGap);
1070 return start.size()-nOldRays;
1074 void Foam::meshRefinement::selectGapCandidates
1077 const label nRefine,
1081 List<FixedList<label, 3>>& shellGapInfo,
1082 List<volumeType>& shellGapMode
1085 const labelList& cellLevel = meshCutter_.cellLevel();
1086 const pointField& cellCentres = mesh_.cellCentres();
1089 cellMap.setSize(cellLevel.size()-nRefine);
1094 if (refineCell[cellI] == -1)
1096 cellMap[compactI++] = cellI;
1100 <<
" unmarked cells out of "
1101 << mesh_.globalData().nTotalCells() <<
endl;
1102 cellMap.setSize(compactI);
1106 shells_.findHigherGapLevel
1122 if (shellGapInfo[i][2] > 0)
1124 map[compactI++] = i;
1129 <<
" cells inside gap shells out of "
1130 << mesh_.globalData().nTotalCells() <<
endl;
1132 map.setSize(compactI);
1135 shellGapInfo = UIndirectList<FixedList<label, 3>>(shellGapInfo, map)();
1136 shellGapMode = UIndirectList<volumeType>(shellGapMode, map)();
1140 void Foam::meshRefinement::mergeGapInfo
1142 const FixedList<label, 3>& shellGapInfo,
1143 const volumeType shellGapMode,
1144 const FixedList<label, 3>& surfGapInfo,
1145 const volumeType surfGapMode,
1147 FixedList<label, 3>& gapInfo,
1151 if (surfGapInfo[0] == 0)
1153 gapInfo = shellGapInfo;
1154 gapMode = shellGapMode;
1156 else if (shellGapInfo[0] == 0)
1158 gapInfo = surfGapInfo;
1159 gapMode = surfGapMode;
1169 gapInfo = surfGapInfo;
1170 gapMode = surfGapMode;
1175 Foam::label Foam::meshRefinement::markInternalGapRefinement
1177 const scalar planarCos,
1178 const bool spreadGapSize,
1179 const label nAllowRefine,
1187 detectedGapSize.setSize(mesh_.nCells());
1188 detectedGapSize = GREAT;
1189 numGapCells.setSize(mesh_.nCells());
1192 const labelList& cellLevel = meshCutter_.cellLevel();
1193 const pointField& cellCentres = mesh_.cellCentres();
1194 const scalar edge0Len = meshCutter_.level0EdgeLength();
1196 const List<FixedList<label, 3>>& extendedGapLevel =
1197 surfaces_.extendedGapLevel();
1198 const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode();
1199 const boolList& extendedGapSelf = surfaces_.gapSelf();
1202 const labelList maxLevel(shells_.maxGapLevel());
1204 label oldNRefine = nRefine;
1206 if (
max(maxLevel) > 0)
1211 List<FixedList<label, 3>> shellGapInfo;
1212 List<volumeType> shellGapMode;
1235 label cellI = cellMap[i];
1236 scalar cellSize = edge0Len/
pow(2.0, cellLevel[cellI]);
1237 gapSize[i] = shellGapInfo[i][0]*cellSize;
1240 surfaces_.findNearestRegion
1242 identity(surfaces_.surfaces().size()),
1254 DynamicList<label> map(
nearInfo.size());
1255 DynamicField<point> rayStart(
nearInfo.size());
1256 DynamicField<point> rayEnd(
nearInfo.size());
1257 DynamicField<scalar> gapSize(
nearInfo.size());
1259 DynamicField<point> rayStart2(
nearInfo.size());
1260 DynamicField<point> rayEnd2(
nearInfo.size());
1261 DynamicField<scalar> gapSize2(
nearInfo.size());
1263 label nTestCells = 0;
1269 label globalRegionI = surfaces_.globalRegion
1276 FixedList<label, 3> gapInfo;
1283 extendedGapLevel[globalRegionI],
1284 extendedGapMode[globalRegionI],
1291 label cellI = cellMap[i];
1292 label cLevel = cellLevel[cellI];
1293 if (cLevel >= gapInfo[1] && cLevel < gapInfo[2])
1295 numGapCells[cellI] =
max(numGapCells[cellI], gapInfo[0]);
1299 label nRays = generateRays
1321 for (label j = 0; j < nRays; j++)
1330 <<
" cells for testing out of "
1331 << mesh_.globalData().nTotalCells() <<
endl;
1342 nearNormal = UIndirectList<vector>(nearNormal, map)();
1343 shellGapInfo.clear();
1344 shellGapMode.clear();
1346 nearSurface.clear();
1352 List<pointIndexHit> hit1;
1354 surfaces_.findNearestIntersection
1364 List<pointIndexHit> hit2;
1366 surfaces_.findNearestIntersection
1380 const label shelli = gapShell[map[i]];
1382 bool selfProx =
true;
1385 selfProx = shells_.gapSelf()[shelli][0];
1387 if (surf1[i] != -1 && selfProx)
1389 const label globalRegioni = surfaces_.globalRegion(surf1[i], 0);
1390 selfProx = extendedGapSelf[globalRegioni];
1397 && (surf2[i] != surf1[i] || selfProx)
1404 const label cellI = cellMap[i];
1406 const scalar d2 =
magSqr(hit1[i].hitPoint()-hit2[i].hitPoint());
1411 && (
mag(normal1[i]&normal2[i]) > planarCos)
1415 detectedGapSize[cellI] =
min
1417 detectedGapSize[cellI],
1428 List<transportData> cellData(mesh_.nCells());
1429 List<transportData> faceData(mesh_.nFaces());
1432 const pointField& faceCentres = mesh_.faceCentres();
1434 DynamicList<label> frontFaces(mesh_.nFaces());
1435 DynamicList<transportData> frontData(mesh_.nFaces());
1436 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
1438 label own = mesh_.faceOwner()[faceI];
1439 label nei = mesh_.faceNeighbour()[faceI];
1441 scalar minSize =
min
1443 detectedGapSize[own],
1444 detectedGapSize[nei]
1447 if (minSize < GREAT)
1449 frontFaces.append(faceI);
1463 label faceI = mesh_.nInternalFaces();
1464 faceI < mesh_.nFaces();
1468 label own = mesh_.faceOwner()[faceI];
1470 if (detectedGapSize[own] < GREAT)
1472 frontFaces.append(faceI);
1478 detectedGapSize[own],
1487 <<
" faces for spreading gap size out of "
1488 << mesh_.globalData().nTotalFaces() <<
endl;
1491 transportData::trackData td(surfaceIndex());
1493 FaceCellWave<transportData, transportData::trackData> deltaCalc
1500 mesh_.globalData().nTotalCells()+1,
1507 label cellI = cellMap[i];
1511 && cellData[cellI].valid(deltaCalc.data())
1512 && numGapCells[cellI] != -1
1516 detectedGapSize[cellI] =
min
1518 detectedGapSize[cellI],
1519 cellData[cellI].data()
1529 label cellI = cellMap[i];
1531 if (cellI != -1 && numGapCells[cellI] != -1)
1534 label cLevel = cellLevel[cellI];
1536 meshCutter_.level0EdgeLength()/
pow(2.0, cLevel);
1537 scalar neededGapSize = numGapCells[cellI]*cellSize;
1539 if (neededGapSize > detectedGapSize[cellI])
1565 Info<<
"Reached refinement limit." <<
endl;
1569 return returnReduce(nRefine-oldNRefine, sumOp<label>());
1573 Foam::label Foam::meshRefinement::markSmallFeatureRefinement
1575 const scalar planarCos,
1576 const label nAllowRefine,
1584 const labelList& cellLevel = meshCutter_.cellLevel();
1585 const labelList& surfaceIndices = surfaces_.surfaces();
1586 const List<FixedList<label, 3>>& extendedGapLevel =
1587 surfaces_.extendedGapLevel();
1588 const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode();
1589 const boolList& extendedGapSelf = surfaces_.gapSelf();
1591 label oldNRefine = nRefine;
1594 labelList shellMaxLevel(shells_.maxGapLevel());
1596 if (
max(shellMaxLevel) == 0)
1602 (void)mesh_.tetBasePtIs();
1603 (void)mesh_.cellTree();
1606 forAll(surfaceIndices, surfI)
1608 label geomI = surfaceIndices[surfI];
1609 const searchableSurface& geom = surfaces_.geometry()[geomI];
1622 geom.boundingSpheres(ctrs, radiusSqr);
1624 List<pointIndexHit> info;
1625 geom.findNearest(ctrs, radiusSqr, info);
1633 <<
" radius:" << radiusSqr[i]
1638 geom.getRegion(info, region);
1639 geom.getNormal(info, normal);
1644 List<FixedList<label, 3>> shellGapInfo;
1645 List<volumeType> shellGapMode;
1647 shells_.findHigherGapLevel
1658 DynamicList<label> map(ctrs.size());
1659 DynamicList<label> cellMap(ctrs.size());
1661 DynamicField<point> rayStart(ctrs.size());
1662 DynamicField<point> rayEnd(ctrs.size());
1663 DynamicField<scalar> gapSize(ctrs.size());
1665 label nTestCells = 0;
1669 if (shellGapInfo[i][2] > 0)
1671 label globalRegionI = surfaces_.globalRegion(surfI, region[i]);
1674 FixedList<label, 3> gapInfo;
1681 extendedGapLevel[globalRegionI],
1682 extendedGapMode[globalRegionI],
1694 const indexedOctree<treeDataCell>& tree = mesh_.cellTree();
1695 if (tree.nodes().size() && tree.bb().contains(ctrs[i]))
1697 cellI = tree.findInside(ctrs[i]);
1700 if (cellI != -1 && refineCell[cellI] == -1)
1706 label nRays = generateRays
1722 for (label j = 0; j < nRays; j++)
1724 cellMap.append(cellI);
1733 <<
" cells containing triangle centres out of "
1734 << mesh_.globalData().nTotalCells() <<
endl;
1742 shellGapInfo.clear();
1743 shellGapMode.clear();
1744 normal = UIndirectList<vector>(normal, map)();
1749 surfaces_.findNearestIntersection
1758 label nOldRefine = 0;
1765 const label shelli = gapShell[map[i]];
1766 bool selfProx =
true;
1769 selfProx = shells_.gapSelf()[shelli][0];
1771 if (surfI != -1 && selfProx)
1773 const label globalRegioni = surfaces_.globalRegion(surfI, 0);
1774 selfProx = extendedGapSelf[globalRegioni];
1780 && (surfaceHit[i] != surfI || selfProx)
1784 label cellI = cellMap[i];
1786 if (
mag(normal[i]&surfaceNormal[i]) > planarCos)
1805 Info<<
"For surface " << geom.name() <<
" found "
1807 <<
" cells in small gaps" <<
endl;
1815 Info<<
"Reached refinement limit." <<
endl;
1819 return returnReduce(nRefine-oldNRefine, sumOp<label>());