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];
462 (cellI != -1 && cellToCompact[cellI] != -1)
463 ? gapShell[cellToCompact[cellI]]
467 bool selfProx =
true;
470 selfProx = shells_.
gapSelf()[shelli][0];
472 if (surf1[i] != -1 && selfProx)
474 const label globalRegioni = surfaces_.
globalRegion(surf1[i], 0);
475 selfProx = extendedGapSelf[globalRegioni];
482 && (surf2[i] != surf1[i] || selfProx)
489 && (
mag(normal1[i]&normal2[i]) > planarCos)
491 magSqr(hit1[i].hitPoint()-hit2[i].hitPoint())
519 Info<<
"Reached refinement limit." <<
endl;
523 return returnReduce(nRefine-oldNRefine, sumOp<label>());
764 Foam::label Foam::meshRefinement::generateRays
766 const point& nearPoint,
768 const FixedList<label, 3>& gapInfo,
769 const volumeType&
mode,
773 DynamicField<point>& start,
774 DynamicField<point>&
end
777 label nOldRays = start.size();
779 if (cLevel >= gapInfo[1] && cLevel < gapInfo[2] && gapInfo[0] > 0)
781 scalar cellSize = meshCutter_.level0EdgeLength()/
pow(2.0, cLevel);
784 scalar nearGap = gapInfo[0]*cellSize;
793 start.append(nearPoint+1
e-6*
n);
794 end.append(nearPoint+nearGap*
n);
798 start.append(nearPoint-1
e-6*
n);
799 end.append(nearPoint-nearGap*
n);
803 start.append(nearPoint+1
e-6*
n);
804 end.append(nearPoint+nearGap*
n);
806 start.append(nearPoint-1
e-6*
n);
807 end.append(nearPoint-nearGap*
n);
811 return start.size()-nOldRays;
815 Foam::label Foam::meshRefinement::generateRays
817 const bool useSurfaceNormal,
819 const point& nearPoint,
821 const FixedList<label, 3>& gapInfo,
822 const volumeType&
mode,
827 DynamicField<point>& start,
828 DynamicField<point>&
end,
829 DynamicField<scalar>& gapSize,
831 DynamicField<point>& start2,
832 DynamicField<point>& end2,
833 DynamicField<scalar>& gapSize2
893 label nOldRays = start.size();
895 if (cLevel >= gapInfo[1] && cLevel < gapInfo[2] && gapInfo[0] > 0)
897 scalar cellSize = meshCutter_.level0EdgeLength()/
pow(2.0, cLevel);
900 scalar nearGap = gapInfo[0]*cellSize;
904 scalar magV =
mag(v);
906 if (useSurfaceNormal || magV < 0.5*cellSize)
915 start.append(nearPoint+1
e-6*
n);
916 end.append(nearPoint+nearGap*
n);
917 gapSize.append(nearGap);
919 start2.append(nearPoint+1
e-6*
n);
920 end2.append(nearPoint-1
e-6*
n);
921 gapSize2.append(gapSize.last());
925 start.append(nearPoint-1
e-6*
n);
926 end.append(nearPoint-nearGap*
n);
927 gapSize.append(nearGap);
929 start2.append(nearPoint-1
e-6*
n);
930 end2.append(nearPoint+1
e-6*
n);
931 gapSize2.append(gapSize.last());
938 start.append(nearPoint+1
e-6*
n);
939 end.append(nearPoint+nearGap*
n);
940 gapSize.append(nearGap);
942 start2.append(nearPoint+1
e-6*
n);
943 end2.append(nearPoint-1
e-6*
n);
944 gapSize2.append(gapSize.last());
948 start.append(nearPoint-1
e-6*
n);
949 end.append(nearPoint-nearGap*
n);
950 gapSize.append(nearGap);
952 start2.append(nearPoint-1
e-6*
n);
953 end2.append(nearPoint+1
e-6*
n);
954 gapSize2.append(gapSize.last());
966 scalar
s = (v&nearNormal);
1019 vector n(v/(magV+ROOTVSMALL));
1023 scalar
s = (e2 &
n);
1041 end.append(cc+nearGap*
n);
1042 gapSize.append(nearGap);
1045 end2.append(cc-nearGap*
n);
1046 gapSize2.append(nearGap);
1050 end.append(cc+nearGap*e2);
1051 gapSize.append(nearGap);
1054 end2.append(cc-nearGap*e2);
1055 gapSize2.append(nearGap);
1059 end.append(cc+nearGap*e3);
1060 gapSize.append(nearGap);
1063 end2.append(cc-nearGap*e3);
1064 gapSize2.append(nearGap);
1069 return start.size()-nOldRays;
1073 void Foam::meshRefinement::selectGapCandidates
1076 const label nRefine,
1080 List<FixedList<label, 3>>& shellGapInfo,
1081 List<volumeType>& shellGapMode
1084 const labelList& cellLevel = meshCutter_.cellLevel();
1085 const pointField& cellCentres = mesh_.cellCentres();
1088 cellMap.setSize(cellLevel.size()-nRefine);
1093 if (refineCell[cellI] == -1)
1095 cellMap[compactI++] = cellI;
1099 <<
" unmarked cells out of "
1100 << mesh_.globalData().nTotalCells() <<
endl;
1101 cellMap.setSize(compactI);
1105 shells_.findHigherGapLevel
1121 if (shellGapInfo[i][2] > 0)
1123 map[compactI++] = i;
1128 <<
" cells inside gap shells out of "
1129 << mesh_.globalData().nTotalCells() <<
endl;
1131 map.setSize(compactI);
1134 shellGapInfo = UIndirectList<FixedList<label, 3>>(shellGapInfo, map)();
1135 shellGapMode = UIndirectList<volumeType>(shellGapMode, map)();
1139 void Foam::meshRefinement::mergeGapInfo
1141 const FixedList<label, 3>& shellGapInfo,
1142 const volumeType shellGapMode,
1143 const FixedList<label, 3>& surfGapInfo,
1144 const volumeType surfGapMode,
1146 FixedList<label, 3>& gapInfo,
1150 if (surfGapInfo[0] == 0)
1152 gapInfo = shellGapInfo;
1153 gapMode = shellGapMode;
1155 else if (shellGapInfo[0] == 0)
1157 gapInfo = surfGapInfo;
1158 gapMode = surfGapMode;
1168 gapInfo = surfGapInfo;
1169 gapMode = surfGapMode;
1174 Foam::label Foam::meshRefinement::markInternalGapRefinement
1176 const scalar planarCos,
1177 const bool spreadGapSize,
1178 const label nAllowRefine,
1186 detectedGapSize.setSize(mesh_.nCells());
1187 detectedGapSize = GREAT;
1188 numGapCells.setSize(mesh_.nCells());
1191 const labelList& cellLevel = meshCutter_.cellLevel();
1192 const pointField& cellCentres = mesh_.cellCentres();
1193 const scalar edge0Len = meshCutter_.level0EdgeLength();
1195 const List<FixedList<label, 3>>& extendedGapLevel =
1196 surfaces_.extendedGapLevel();
1197 const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode();
1198 const boolList& extendedGapSelf = surfaces_.gapSelf();
1201 const labelList maxLevel(shells_.maxGapLevel());
1203 label oldNRefine = nRefine;
1205 if (
max(maxLevel) > 0)
1210 List<FixedList<label, 3>> shellGapInfo;
1211 List<volumeType> shellGapMode;
1224 List<pointIndexHit> nearInfo;
1234 label cellI = cellMap[i];
1235 scalar cellSize = edge0Len/
pow(2.0, cellLevel[cellI]);
1236 gapSize[i] = shellGapInfo[i][0]*cellSize;
1239 surfaces_.findNearestRegion
1241 identity(surfaces_.surfaces().size()),
1253 DynamicList<label> map(nearInfo.size());
1254 DynamicField<point> rayStart(nearInfo.size());
1255 DynamicField<point> rayEnd(nearInfo.size());
1256 DynamicField<scalar> gapSize(nearInfo.size());
1258 DynamicField<point> rayStart2(nearInfo.size());
1259 DynamicField<point> rayEnd2(nearInfo.size());
1260 DynamicField<scalar> gapSize2(nearInfo.size());
1262 label nTestCells = 0;
1266 if (nearInfo[i].hit())
1268 label globalRegionI = surfaces_.globalRegion
1275 FixedList<label, 3> gapInfo;
1282 extendedGapLevel[globalRegionI],
1283 extendedGapMode[globalRegionI],
1290 label cellI = cellMap[i];
1291 label cLevel = cellLevel[cellI];
1292 if (cLevel >= gapInfo[1] && cLevel < gapInfo[2])
1294 numGapCells[cellI] =
max(numGapCells[cellI], gapInfo[0]);
1298 label nRays = generateRays
1301 nearInfo[i].hitPoint(),
1320 for (label j = 0; j < nRays; j++)
1329 <<
" cells for testing out of "
1330 << mesh_.globalData().nTotalCells() <<
endl;
1341 nearNormal = UIndirectList<vector>(nearNormal, map)();
1342 shellGapInfo.clear();
1343 shellGapMode.clear();
1345 nearSurface.clear();
1351 List<pointIndexHit> hit1;
1353 surfaces_.findNearestIntersection
1363 List<pointIndexHit> hit2;
1365 surfaces_.findNearestIntersection
1379 const label shelli = gapShell[map[i]];
1381 bool selfProx =
true;
1384 selfProx = shells_.gapSelf()[shelli][0];
1386 if (surf1[i] != -1 && selfProx)
1388 const label globalRegioni = surfaces_.globalRegion(surf1[i], 0);
1389 selfProx = extendedGapSelf[globalRegioni];
1396 && (surf2[i] != surf1[i] || selfProx)
1403 const label cellI = cellMap[i];
1405 const scalar d2 =
magSqr(hit1[i].hitPoint()-hit2[i].hitPoint());
1410 && (
mag(normal1[i]&normal2[i]) > planarCos)
1414 detectedGapSize[cellI] =
min
1416 detectedGapSize[cellI],
1427 List<transportData> cellData(mesh_.nCells());
1428 List<transportData> faceData(mesh_.nFaces());
1431 const pointField& faceCentres = mesh_.faceCentres();
1433 DynamicList<label> frontFaces(mesh_.nFaces());
1434 DynamicList<transportData> frontData(mesh_.nFaces());
1435 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
1437 label own = mesh_.faceOwner()[faceI];
1438 label nei = mesh_.faceNeighbour()[faceI];
1440 scalar minSize =
min
1442 detectedGapSize[own],
1443 detectedGapSize[nei]
1446 if (minSize < GREAT)
1448 frontFaces.append(faceI);
1462 label faceI = mesh_.nInternalFaces();
1463 faceI < mesh_.nFaces();
1467 label own = mesh_.faceOwner()[faceI];
1469 if (detectedGapSize[own] < GREAT)
1471 frontFaces.append(faceI);
1477 detectedGapSize[own],
1486 <<
" faces for spreading gap size out of "
1487 << mesh_.globalData().nTotalFaces() <<
endl;
1490 transportData::trackData td(surfaceIndex());
1492 FaceCellWave<transportData, transportData::trackData> deltaCalc
1499 mesh_.globalData().nTotalCells()+1,
1506 label cellI = cellMap[i];
1510 && cellData[cellI].valid(deltaCalc.data())
1511 && numGapCells[cellI] != -1
1515 detectedGapSize[cellI] =
min
1517 detectedGapSize[cellI],
1518 cellData[cellI].data()
1528 label cellI = cellMap[i];
1530 if (cellI != -1 && numGapCells[cellI] != -1)
1533 label cLevel = cellLevel[cellI];
1535 meshCutter_.level0EdgeLength()/
pow(2.0, cLevel);
1536 scalar neededGapSize = numGapCells[cellI]*cellSize;
1538 if (neededGapSize > detectedGapSize[cellI])
1564 Info<<
"Reached refinement limit." <<
endl;
1568 return returnReduce(nRefine-oldNRefine, sumOp<label>());
1572 Foam::label Foam::meshRefinement::markSmallFeatureRefinement
1574 const scalar planarCos,
1575 const label nAllowRefine,
1583 const labelList& cellLevel = meshCutter_.cellLevel();
1584 const labelList& surfaceIndices = surfaces_.surfaces();
1585 const List<FixedList<label, 3>>& extendedGapLevel =
1586 surfaces_.extendedGapLevel();
1587 const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode();
1588 const boolList& extendedGapSelf = surfaces_.gapSelf();
1590 label oldNRefine = nRefine;
1593 labelList shellMaxLevel(shells_.maxGapLevel());
1595 if (
max(shellMaxLevel) == 0)
1601 (void)mesh_.tetBasePtIs();
1602 (void)mesh_.cellTree();
1605 forAll(surfaceIndices, surfI)
1607 label geomI = surfaceIndices[surfI];
1608 const searchableSurface& geom = surfaces_.geometry()[geomI];
1621 geom.boundingSpheres(ctrs, radiusSqr);
1623 List<pointIndexHit> info;
1624 geom.findNearest(ctrs, radiusSqr, info);
1632 <<
" radius:" << radiusSqr[i]
1637 geom.getRegion(info, region);
1638 geom.getNormal(info, normal);
1643 List<FixedList<label, 3>> shellGapInfo;
1644 List<volumeType> shellGapMode;
1646 shells_.findHigherGapLevel
1657 DynamicList<label> map(ctrs.size());
1658 DynamicList<label> cellMap(ctrs.size());
1660 DynamicField<point> rayStart(ctrs.size());
1661 DynamicField<point> rayEnd(ctrs.size());
1662 DynamicField<scalar> gapSize(ctrs.size());
1664 label nTestCells = 0;
1668 if (shellGapInfo[i][2] > 0)
1670 label globalRegionI = surfaces_.globalRegion(surfI, region[i]);
1673 FixedList<label, 3> gapInfo;
1680 extendedGapLevel[globalRegionI],
1681 extendedGapMode[globalRegionI],
1693 const indexedOctree<treeDataCell>& tree = mesh_.cellTree();
1694 if (tree.nodes().size() && tree.bb().contains(ctrs[i]))
1696 cellI = tree.findInside(ctrs[i]);
1699 if (cellI != -1 && refineCell[cellI] == -1)
1705 label nRays = generateRays
1721 for (label j = 0; j < nRays; j++)
1723 cellMap.append(cellI);
1732 <<
" cells containing triangle centres out of "
1733 << mesh_.globalData().nTotalCells() <<
endl;
1741 shellGapInfo.clear();
1742 shellGapMode.clear();
1743 normal = UIndirectList<vector>(normal, map)();
1748 surfaces_.findNearestIntersection
1757 label nOldRefine = 0;
1764 const label shelli = gapShell[map[i]];
1765 bool selfProx =
true;
1768 selfProx = shells_.gapSelf()[shelli][0];
1770 if (surfI != -1 && selfProx)
1772 const label globalRegioni = surfaces_.globalRegion(surfI, 0);
1773 selfProx = extendedGapSelf[globalRegioni];
1779 && (surfaceHit[i] != surfI || selfProx)
1783 label cellI = cellMap[i];
1785 if (
mag(normal[i]&surfaceNormal[i]) > planarCos)
1804 Info<<
"For surface " << geom.name() <<
" found "
1806 <<
" cells in small gaps" <<
endl;
1814 Info<<
"Reached refinement limit." <<
endl;
1818 return returnReduce(nRefine-oldNRefine, sumOp<label>());