45Foam::label Foam::meshRefinement::markSurfaceGapRefinement
47 const scalar planarCos,
49 const label nAllowRefine,
50 const labelList& neiLevel,
51 const pointField& neiCc,
53 labelList& refineCell,
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>());
764Foam::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;
815Foam::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;
1073void 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)();
1139void 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;
1174Foam::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],
1435 List<transportData> cellData(mesh_.nCells());
1436 List<transportData> faceData(mesh_.nFaces());
1439 const pointField& faceCentres = mesh_.faceCentres();
1441 DynamicList<label> frontFaces(mesh_.nFaces());
1442 DynamicList<transportData> frontData(mesh_.nFaces());
1443 for (label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
1445 label own = mesh_.faceOwner()[faceI];
1446 label nei = mesh_.faceNeighbour()[faceI];
1448 scalar minSize =
min
1450 detectedGapSize[own],
1451 detectedGapSize[nei]
1454 if (minSize < GREAT)
1456 frontFaces.append(faceI);
1470 label faceI = mesh_.nInternalFaces();
1471 faceI < mesh_.nFaces();
1475 label own = mesh_.faceOwner()[faceI];
1477 scalar minSize =
min
1479 detectedGapSize[own],
1480 boundaryGapSize[faceI-mesh_.nInternalFaces()]
1483 if (minSize < GREAT)
1485 frontFaces.append(faceI);
1500 <<
" faces for spreading gap size out of "
1501 << mesh_.globalData().nTotalFaces() <<
endl;
1504 transportData::trackData td(surfaceIndex());
1506 FaceCellWave<transportData, transportData::trackData> deltaCalc
1513 mesh_.globalData().nTotalCells()+1,
1520 label cellI = cellMap[i];
1524 && cellData[cellI].valid(deltaCalc.data())
1525 && numGapCells[cellI] != -1
1529 detectedGapSize[cellI] =
min
1531 detectedGapSize[cellI],
1532 cellData[cellI].data()
1542 label cellI = cellMap[i];
1544 if (cellI != -1 && numGapCells[cellI] != -1)
1547 label cLevel = cellLevel[cellI];
1549 meshCutter_.level0EdgeLength()/
pow(2.0, cLevel);
1550 scalar neededGapSize = numGapCells[cellI]*cellSize;
1552 if (neededGapSize > detectedGapSize[cellI])
1578 Info<<
"Reached refinement limit." <<
endl;
1582 return returnReduce(nRefine-oldNRefine, sumOp<label>());
1586Foam::label Foam::meshRefinement::markSmallFeatureRefinement
1588 const scalar planarCos,
1589 const label nAllowRefine,
1597 const labelList& cellLevel = meshCutter_.cellLevel();
1598 const labelList& surfaceIndices = surfaces_.surfaces();
1599 const List<FixedList<label, 3>>& extendedGapLevel =
1600 surfaces_.extendedGapLevel();
1601 const List<volumeType>& extendedGapMode = surfaces_.extendedGapMode();
1602 const boolList& extendedGapSelf = surfaces_.gapSelf();
1604 label oldNRefine = nRefine;
1607 labelList shellMaxLevel(shells_.maxGapLevel());
1609 if (
max(shellMaxLevel) == 0)
1615 (void)mesh_.tetBasePtIs();
1616 (void)mesh_.cellTree();
1619 forAll(surfaceIndices, surfI)
1621 label geomI = surfaceIndices[surfI];
1622 const searchableSurface& geom = surfaces_.geometry()[geomI];
1635 geom.boundingSpheres(ctrs, radiusSqr);
1637 List<pointIndexHit> info;
1638 geom.findNearest(ctrs, radiusSqr, info);
1646 <<
" radius:" << radiusSqr[i]
1651 geom.getRegion(info, region);
1652 geom.getNormal(info, normal);
1657 List<FixedList<label, 3>> shellGapInfo;
1658 List<volumeType> shellGapMode;
1660 shells_.findHigherGapLevel
1671 DynamicList<label> map(ctrs.size());
1672 DynamicList<label> cellMap(ctrs.size());
1674 DynamicField<point> rayStart(ctrs.size());
1675 DynamicField<point> rayEnd(ctrs.size());
1676 DynamicField<scalar> gapSize(ctrs.size());
1678 label nTestCells = 0;
1682 if (shellGapInfo[i][2] > 0)
1684 label globalRegionI = surfaces_.globalRegion(surfI, region[i]);
1687 FixedList<label, 3> gapInfo;
1694 extendedGapLevel[globalRegionI],
1695 extendedGapMode[globalRegionI],
1707 const indexedOctree<treeDataCell>& tree = mesh_.cellTree();
1708 if (tree.nodes().size() && tree.bb().contains(ctrs[i]))
1710 cellI = tree.findInside(ctrs[i]);
1713 if (cellI != -1 && refineCell[cellI] == -1)
1719 label nRays = generateRays
1735 for (label j = 0; j < nRays; j++)
1737 cellMap.append(cellI);
1746 <<
" cells containing triangle centres out of "
1747 << mesh_.globalData().nTotalCells() <<
endl;
1755 shellGapInfo.clear();
1756 shellGapMode.clear();
1757 normal = UIndirectList<vector>(normal, map)();
1762 surfaces_.findNearestIntersection
1771 label nOldRefine = 0;
1778 const label shelli = gapShell[map[i]];
1779 bool selfProx =
true;
1782 selfProx = shells_.gapSelf()[shelli][0];
1784 if (surfI != -1 && selfProx)
1786 const label globalRegioni = surfaces_.globalRegion(surfI, 0);
1787 selfProx = extendedGapSelf[globalRegioni];
1793 && (surfaceHit[i] != surfI || selfProx)
1797 label cellI = cellMap[i];
1799 if (
mag(normal[i]&surfaceNormal[i]) > planarCos)
1818 Info<<
"For surface " << geom.name() <<
" found "
1820 <<
" cells in small gaps" <<
endl;
1828 Info<<
"Reached refinement limit." <<
endl;
1832 return returnReduce(nRefine-oldNRefine, sumOp<label>());
void setSize(const label n)
Alias for resize()
void size(const label n)
Older name for setAddressableSize.
const labelIOList & cellLevel() const
virtual const labelList & faceOwner() const
Return face owner.
virtual const labelList & faceNeighbour() const
Return face neighbour.
bool isInternalFace(const label faceIndex) const noexcept
Return true if given face label is internal to the mesh.
label nBoundaryFaces() const noexcept
Number of boundary faces (== nFaces - nInternalFaces)
label nInternalFaces() const noexcept
Number of internal faces.
const vectorField & cellCentres() const
label nCells() const noexcept
Number of mesh cells.
const List< volumeType > & extendedGapMode() const
From global region number to side of surface to detect.
label globalRegion(const label surfI, const label regionI) const
From surface and region on surface to global region.
const boolList & gapSelf() const
From global region number to whether to detect gaps to same.
const labelList & surfaces() const
const List< FixedList< label, 3 > > & extendedGapLevel() const
From global region number to specification of gap and its.
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.
labelList maxGapLevel() const
Highest shell gap level.
const boolListList & gapSelf() const
Per shell, per region whether to test for gap with same surface.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
@ OUTSIDE
A location outside the volume.
@ MIXED
A location that is partly inside and outside.
@ INSIDE
A location inside the volume.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
messageStream Info
Information stream (stdout output on master, null elsewhere)
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
vectorField pointField
pointField is a vectorField.
vector point
Point is a vector.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< bool > boolList
A List of bools.
static constexpr const zero Zero
Global zero (0)
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
errorManipArg< error, int > exit(error &err, const int errNo=1)
UIndirectList< label > labelUIndList
UIndirectList of labels.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
#define forAll(list, i)
Loop across all elements in list.