50 namespace cellCellStencils
65 return (ijk[0]*nDivs[1] + ijk[1])*nDivs[2] + ijk[2];
75 label ij = boxI/nDivs[2];
76 label k = boxI-ij*nDivs[2];
77 label i = ij/nDivs[1];
78 label j = ij-i*nDivs[1];
96 floor(relPt[0]/d[0]*nDivs[0]),
97 floor(relPt[1]/d[1]*nDivs[1]),
98 floor(relPt[2]/d[2]*nDivs[2])
114 const vector sz(d[0]/nDivs[0], d[1]/nDivs[1], d[2]/nDivs[2]);
116 return bb.
min()+0.5*sz+
vector(sz[0]*ids[0], sz[1]*ids[1], sz[2]*ids[2]);
126 const unsigned int val
132 for (
direction cmpt = 0; cmpt < 3; cmpt++)
134 if (maxIds[cmpt] < 0 || minIds[cmpt] > nDivs[cmpt])
141 minIds =
max(labelVector::zero, minIds);
142 maxIds =
min(maxIndex, maxIds);
144 for (
label i = minIds[0]; i <= maxIds[0]; i++)
146 for (
label j = minIds[1]; j <= maxIds[1]; j++)
148 for (
label k = minIds[2];
k <= maxIds[2];
k++)
180 const fvPatch& fvp = pbm[patchI];
183 if (!fvPatch::constraintType(fvp.type()))
195 faceBb.
min() -= smallVec;
196 faceBb.
max() += smallVec;
209 const fvPatch& fvp = pbm[patchI];
212 if (isA<oversetFvPatch>(fvp))
219 patchCellTypes[cellMap[fc[i]]] = patchCellType::OVERSET;
223 faceBb.
min() -= smallVec;
224 faceBb.
max() += smallVec;
228 fill(
patchTypes, bb, nDivs, faceBb, patchCellType::OVERSET);
248 vector(GREAT, GREAT, GREAT),
249 vector(-GREAT, -GREAT, -GREAT)
256 const face&
f = faces[cFaces[cFacei]];
276 const unsigned int val
284 for (
direction cmpt = 0; cmpt < 3; cmpt++)
286 if (maxIds[cmpt] < 0 || minIds[cmpt] > nDivs[cmpt])
293 minIds =
max(labelVector::zero, minIds);
294 maxIds =
min(maxIndex, maxIds);
296 for (
label i = minIds[0]; i <= maxIds[0]; i++)
298 for (
label j = minIds[1]; j <= maxIds[1]; j++)
300 for (
label k = minIds[2];
k <= maxIds[2];
k++)
335 const treeBoundBox& srcPatchBb = srcPatchBbs[Pstream::myProcNo()];
336 const treeBoundBox& tgtPatchBb = tgtPatchBbs[Pstream::myProcNo()];
338 if (srcPatchBb.
overlaps(tgtPatchBb))
341 const labelVector& zoneDivs = patchDivisions[srcI];
343 forAll(tgtCellMap, tgtCelli)
345 label celli = tgtCellMap[tgtCelli];
347 cBb.
min() -= smallVec_;
348 cBb.
max() += smallVec_;
362 allCellTypes[celli] = HOLE;
371 for (
label procI = 0; procI < Pstream::nProcs(); procI++)
373 if (procI != Pstream::myProcNo())
375 const treeBoundBox& srcPatchBb = srcPatchBbs[Pstream::myProcNo()];
378 if (srcPatchBb.
overlaps(tgtPatchBb))
383 os << srcPatchBb << patchDivisions[srcI] << patchParts[srcI];
388 for (
label procI = 0; procI < Pstream::nProcs(); procI++)
390 if (procI != Pstream::myProcNo())
394 const treeBoundBox& tgtPatchBb = tgtPatchBbs[Pstream::myProcNo()];
396 if (srcPatchBb.
overlaps(tgtPatchBb))
401 if (srcPatchBb != receivedBb)
405 <<
" srcPatchBb:" << srcPatchBb
406 <<
" receivedBb:" << receivedBb
413 forAll(tgtCellMap, tgtCelli)
415 label celli = tgtCellMap[tgtCelli];
417 cBb.
min() -= smallVec_;
418 cBb.
max() += smallVec_;
431 allCellTypes[celli] = HOLE;
442 const label destMesh,
443 const label currentDonorMesh,
444 const label newDonorMesh
457 if (currentDonorMesh == -1)
463 const label currentDist =
mag(currentDonorMesh-destMesh);
464 const label newDist =
mag(newDonorMesh-destMesh);
466 if (newDist < currentDist)
470 else if (newDist == currentDist && newDonorMesh > currentDonorMesh)
509 waveMethod::calculate(tgtMesh, srcMesh, tgtToSrcAddr);
510 forAll(tgtCellMap, tgtCelli)
512 label srcCelli = tgtToSrcAddr[tgtCelli];
513 if (srcCelli != -1 && allCellTypes[srcCellMap[srcCelli]] != HOLE)
515 label celli = tgtCellMap[tgtCelli];
519 if (betterDonor(tgtI, allDonor[celli], srcI))
522 globalCells.
toGlobal(srcCellMap[srcCelli]);
524 allStencil[celli][0] = globalDonor;
525 allDonor[celli] = srcI;
540 for (
label procI = 0; procI < Pstream::nProcs(); procI++)
542 if (procI != Pstream::myProcNo())
544 if (tgtBbs[procI].overlaps(srcBbs[Pstream::myProcNo()]))
546 tgtOverlapProcs.
append(procI);
548 if (srcBbs[procI].overlaps(tgtBbs[Pstream::myProcNo()]))
550 srcOverlapProcs.
append(procI);
559 forAll(srcOverlapProcs, i)
561 label procI = srcOverlapProcs[i];
562 tgtSendCells[procI].reserve(tgtMesh.
nCells()/srcOverlapProcs.size());
566 forAll(tgtCellMap, tgtCelli)
568 label celli = tgtCellMap[tgtCelli];
569 if (srcOverlapProcs.size())
572 subBb.
min() -= smallVec_;
573 subBb.
max() += smallVec_;
575 forAll(srcOverlapProcs, i)
577 label procI = srcOverlapProcs[i];
580 tgtSendCells[procI].
append(tgtCelli);
589 forAll(srcOverlapProcs, i)
591 label procI = srcOverlapProcs[i];
592 const labelList& cellIDs = tgtSendCells[procI];
595 os << UIndirectList<point>(tgtCc, cellIDs);
601 forAll(tgtOverlapProcs, i)
603 label procI = tgtOverlapProcs[i];
612 label srcCelli = srcMesh.
findCell(sample, polyMesh::CELL_TETS);
613 if (srcCelli != -1 && allCellTypes[srcCellMap[srcCelli]] != HOLE)
615 donors[sampleI] = globalCells.
toGlobal(srcCellMap[srcCelli]);
625 forAll(srcOverlapProcs, i)
627 label procI = srcOverlapProcs[i];
628 const labelList& cellIDs = tgtSendCells[procI];
633 if (donors.size() != cellIDs.size())
641 label globalDonor = donors[donorI];
643 if (globalDonor != -1)
645 label celli = tgtCellMap[cellIDs[donorI]];
649 if (betterDonor(tgtI, allDonor[celli], srcI))
652 allStencil[celli][0] = globalDonor;
653 allDonor[celli] = srcI;
976 for (
label faceI = 0; faceI <
mesh.nInternalFaces(); faceI++)
982 (ownType == HOLE && neiType != HOLE)
983 || (ownType != HOLE && neiType == HOLE)
986 isBlockedFace[faceI] =
true;
995 syncTools::swapBoundaryCellList(
mesh,
cellTypes, nbrCellTypes);
997 for (
label faceI =
mesh.nInternalFaces(); faceI <
mesh.nFaces(); faceI++)
1000 label neiType = nbrCellTypes[faceI-
mesh.nInternalFaces()];
1004 (ownType == HOLE && neiType != HOLE)
1005 || (ownType != HOLE && neiType == HOLE)
1008 isBlockedFace[faceI] =
true;
1014 << nBlocked <<
endl;
1046 << nRegions <<
endl;
1067 for (
label faceI = 0; faceI <
mesh.nInternalFaces(); faceI++)
1069 if (isBlockedFace[faceI])
1071 label ownRegion = cellRegion[own[faceI]];
1075 if (regionType[ownRegion] == 0)
1077 regionType[ownRegion] = 1;
1081 label neiRegion = cellRegion[nei[faceI]];
1085 if (regionType[neiRegion] == 0)
1087 regionType[neiRegion] = 1;
1095 faceI <
mesh.nFaces();
1099 if (isBlockedFace[faceI])
1101 label ownRegion = cellRegion[own[faceI]];
1103 if (regionType[ownRegion] == 0)
1105 regionType[ownRegion] = 1;
1115 const fvPatch& fvp = pbm[patchI];
1117 if (isA<oversetFvPatch>(fvp))
1119 else if (!fvPatch::constraintType(fvp.type()))
1124 label regionI = cellRegion[fc[i]];
1126 if (
cellTypes[fc[i]] != HOLE && regionType[regionI] != 2)
1128 regionType[regionI] = 2;
1155 Pstream::listCombineScatter(regionType);
1170 const fvPatch& fvp = pbm[patchI];
1172 if (isA<oversetFvPatch>(fvp))
1177 label cellI = fc[i];
1178 label regionI = cellRegion[cellI];
1180 if (regionType[regionI] != 2)
1182 const labelList& slots = compactStencil[cellI];
1185 label otherType = cellRegionType[slots[i]];
1192 regionType[regionI] = 2;
1204 << nChanged <<
endl;
1214 forAll(cellRegion, cellI)
1216 label type = regionType[cellRegion[cellI]];
1229 const scalar wantedFraction,
1234 const cell& cFaces = mesh_.cells()[cellI];
1237 label nbrFacei = cFaces[i];
1238 if (fraction[nbrFacei] < wantedFraction)
1240 fraction[nbrFacei] = wantedFraction;
1241 isFront.
set(nbrFacei);
1249 const scalar layerRelax,
1256 bitSet isFront(mesh_.nFaces());
1265 if (isA<oversetFvPatch>(fvm[patchI]))
1267 const labelList& fc = fvm[patchI].faceCells();
1270 label cellI = fc[i];
1271 if (allCellTypes[cellI] == INTERPOLATED)
1276 isFront.
set(fvm[patchI].
start()+i);
1285 const labelList& own = mesh_.faceOwner();
1286 const labelList& nei = mesh_.faceNeighbour();
1288 for (
label faceI = 0; faceI < mesh_.nInternalFaces(); faceI++)
1290 label ownType = allCellTypes[own[faceI]];
1291 label neiType = allCellTypes[nei[faceI]];
1294 (ownType == HOLE && neiType != HOLE)
1295 || (ownType != HOLE && neiType == HOLE)
1305 syncTools::swapBoundaryCellList(mesh_, allCellTypes, nbrCellTypes);
1309 label faceI = mesh_.nInternalFaces();
1310 faceI < mesh_.nFaces();
1314 label ownType = allCellTypes[own[faceI]];
1315 label neiType = nbrCellTypes[faceI-mesh_.nInternalFaces()];
1319 (ownType == HOLE && neiType != HOLE)
1320 || (ownType != HOLE && neiType == HOLE)
1336 if (isFront.
test(faceI))
1338 fraction[faceI] = 1.0;
1346 bitSet newIsFront(mesh_.nFaces());
1350 if (isFront.
test(faceI))
1352 label own = mesh_.faceOwner()[faceI];
1353 if (allCellTypes[own] != HOLE)
1355 if (allWeight[own] < fraction[faceI])
1359 if (allStencil[own].size())
1361 allWeight[own] = fraction[faceI];
1362 allCellTypes[own] = INTERPOLATED;
1368 fraction[faceI]-layerRelax,
1375 allWeight[own] = 0.0;
1376 allCellTypes[own] = HOLE;
1388 if (mesh_.isInternalFace(faceI))
1390 label nei = mesh_.faceNeighbour()[faceI];
1391 if (allCellTypes[nei] != HOLE)
1393 if (allWeight[nei] < fraction[faceI])
1395 if (allStencil[nei].size())
1397 allWeight[nei] = fraction[faceI];
1398 allCellTypes[nei] = INTERPOLATED;
1402 fraction[faceI]-layerRelax,
1409 allWeight[nei] = 0.0;
1410 allCellTypes[nei] = HOLE;
1429 fraction.transfer(newFraction);
1436 const point& sample,
1443 weights.
setSize(donorCcs.size());
1447 scalar d =
mag(sample-donorCcs[i]);
1489 const vector greatPoint(GREAT, GREAT, GREAT);
1491 boolList isValidDonor(mesh_.nCells(),
true);
1492 forAll(cellTypes_, celli)
1494 if (cellTypes_[celli] == HOLE)
1496 isValidDonor[celli] =
false;
1502 bitSet doneAcceptor(interpolationCells_.size());
1511 forAll(interpolationCells_, i)
1513 if (!doneAcceptor[i])
1515 label cellI = interpolationCells_[i];
1516 const point& cc = mesh_.cellCentres()[cellI];
1517 const labelList& slots = cellStencil_[cellI];
1519 if (slots.size() != 1)
1527 label elemI = slots[slotI];
1545 mapDistributeBase::distribute<point, minMagSqrEqOp<point>,
flipOp>
1547 Pstream::commsTypes::nonBlocking,
1550 cellInterpolationMap().constructMap(),
1552 cellInterpolationMap().subMap(),
1566 if (
samples[cellI] != greatPoint)
1568 donorCells.append(cellI);
1590 label cellI = donorCells[i];
1591 const pointList& donorCentres = donorCellCentres[cellI];
1603 cellInterpolationMap().distribute(donorCellCells);
1604 cellInterpolationMap().distribute(donorWeights);
1605 cellInterpolationMap().distribute(
samples);
1608 forAll(interpolationCells_, i)
1610 if (!doneAcceptor[i])
1612 label cellI = interpolationCells_[i];
1613 const labelList& slots = cellStencil_[cellI];
1615 if (slots.size() != 1)
1621 label slotI = slots[0];
1624 if (
samples[slotI] == mesh_.cellCentres()[cellI])
1626 cellStencil_[cellI].
transfer(donorCellCells[slotI]);
1627 cellInterpolationWeights_[cellI].transfer
1633 doneAcceptor.set(i);
1641 cellInterpolationMap_.reset
1655 Foam::cellCellStencils::inverseDistance::inverseDistance
1666 interpolationCells_(0),
1667 cellInterpolationMap_(),
1669 cellInterpolationWeights_(0),
1670 cellInterpolationWeight_
1674 "cellInterpolationWeight",
1675 mesh_.facesInstance(),
1683 zeroGradientFvPatchScalarField::typeName
1687 nonInterpolatedFields_.insert(
"cellInterpolationWeight");
1688 nonInterpolatedFields_.insert(
"cellTypes");
1689 nonInterpolatedFields_.insert(
"maxMagWeight");
1692 nonInterpolatedFields_.insert(
"cellDisplacement");
1693 nonInterpolatedFields_.insert(
"grad(cellDisplacement)");
1694 const word w(
"snGradCorr(cellDisplacement)");
1695 const word d(
"((viscosity*faceDiffusivity)*magSf)");
1696 nonInterpolatedFields_.insert(
"surfaceIntegrate(("+d+
"*"+w+
"))");
1705 mesh_.time().timeName(),
1707 IOobject::READ_IF_PRESENT,
1715 Pout<<
"Reading cellTypes from time " << mesh_.time().timeName()
1720 forAll(volCellTypes, celli)
1723 cellTypes_[celli] = volCellTypes[celli];
1744 scalar layerRelax(dict_.lookupOrDefault(
"layerRelax", 1.0));
1746 scalar tol = dict_.lookupOrDefault(
"tolerance", 1
e-10);
1747 smallVec_ = mesh_.bounds().span()*tol;
1761 const boundBox& allBb(mesh_.bounds());
1797 allBb.min() - 2*allBb.span(),
1798 allBb.min() - allBb.span()
1814 bbs[procI] = procBb[procI][zoneI];
1826 labelList allPatchTypes(mesh_.nCells(), OTHER);
1830 if (dict_.readIfPresent(
"searchBox", globalPatchBb))
1844 if (dict_.readIfPresent(
"searchBoxDivisions", globalDivs))
1846 patchDivisions = globalDivs;
1852 if (mesh_.nGeometricD() == 1)
1854 nDivs = mesh_.nCells();
1856 else if (mesh_.nGeometricD() == 2)
1877 forAll(patchParts, zoneI)
1884 patchDivisions[zoneI][0]
1885 *patchDivisions[zoneI][1]
1886 *patchDivisions[zoneI][2]
1895 patchDivisions[zoneI],
1907 <<
" mesh regions" <<
endl;
1913 <<
" voxels:" << patchDivisions[zoneI]
1923 labelList allCellTypes(mesh_.nCells(), CALCULATED);
1926 labelList allDonorID(mesh_.nCells(), -1);
2006 createField(mesh_,
"allCellTypes", allCellTypes)
2012 forAll(allPatchTypes, cellI)
2014 if (allCellTypes[cellI] != HOLE)
2016 switch (allPatchTypes[cellI])
2022 if (allStencil[cellI].size())
2024 allCellTypes[cellI] = INTERPOLATED;
2038 allCellTypes[cellI] = HOLE;
2049 createField(mesh_,
"allCellTypes_patch", allCellTypes)
2060 label nCalculated = 0;
2062 forAll(cellTypes_, celli)
2064 if (allCellTypes[celli] == CALCULATED && cellTypes_[celli] == HOLE)
2066 if (allStencil[celli].size() == 0)
2069 allCellTypes[celli] = HOLE;
2070 allStencil[celli].
clear();
2074 allCellTypes[celli] = INTERPOLATED;
2082 Pout<<
"Detected " << nCalculated <<
" cells changing from hole"
2083 <<
" to calculated. Changed to interpolated"
2090 findHoles(globalCells, mesh_,
zoneID, allStencil, allCellTypes);
2096 createField(mesh_,
"allCellTypes_hole", allCellTypes)
2103 forAll(allStencil, celli)
2105 stencilSize[celli] = allStencil[celli].size();
2109 createField(mesh_,
"allStencil_hole", stencilSize)
2117 walkFront(layerRelax, allStencil, allCellTypes, allWeight);
2123 createField(mesh_,
"allCellTypes_front", allCellTypes)
2131 cellTypes_.transfer(allCellTypes);
2132 cellStencil_.setSize(mesh_.nCells());
2133 cellInterpolationWeights_.setSize(mesh_.nCells());
2135 forAll(cellTypes_, cellI)
2137 if (cellTypes_[cellI] == INTERPOLATED)
2139 cellStencil_[cellI].transfer(allStencil[cellI]);
2140 cellInterpolationWeights_[cellI].setSize(1);
2141 cellInterpolationWeights_[cellI][0] = 1.0;
2142 interpolationCells.
append(cellI);
2146 cellStencil_[cellI].clear();
2147 cellInterpolationWeights_[cellI].clear();
2150 interpolationCells_.transfer(interpolationCells);
2153 cellInterpolationMap_.reset
2157 cellInterpolationWeight_.
transfer(allWeight);
2162 >(cellInterpolationWeight_.boundaryFieldRef(),
false);
2168 mesh_.time().
write();
2171 mkDir(mesh_.time().timePath());
2172 OBJstream str(mesh_.time().timePath()/
"injectionStencil.obj");
2173 Pout<<
type() <<
" : dumping injectionStencil to "
2174 << str.name() <<
endl;
2176 cellInterpolationMap().distribute(cc);
2178 forAll(cellStencil_, celli)
2180 const labelList& slots = cellStencil_[celli];
2183 const point& accCc = mesh_.cellCentres()[celli];
2186 const point& donorCc = cc[slots[i]];
2195 createStencil(globalCells);
2201 cellInterpolationWeight_.instance() = mesh_.time().timeName();
2202 cellInterpolationWeight_.write();
2207 forAll(cellStencil_, celli)
2209 const scalarList& wghts = cellInterpolationWeights_[celli];
2212 if (
mag(wghts[i]) >
mag(maxMagWeight[celli]))
2214 maxMagWeight[celli] = wghts[i];
2217 if (
mag(maxMagWeight[celli]) > 1)
2220 Pout<<
"cell:" << celli
2221 <<
" at:" << cc[celli]
2222 <<
" zone:" <<
zoneID[celli]
2223 <<
" donors:" << cellStencil_[celli]
2224 <<
" weights:" << wghts
2234 createField(mesh_,
"maxMagWeight", maxMagWeight)
2248 createField(mesh_,
"cellTypes", cellTypes_)
2261 mkDir(mesh_.time().timePath());
2262 OBJstream str(mesh_.time().timePath()/
"stencil.obj");
2263 Pout<<
type() <<
" : dumping to " << str.name() <<
endl;
2265 cellInterpolationMap().distribute(cc);
2267 forAll(cellStencil_, celli)
2269 const labelList& slots = cellStencil_[celli];
2272 const point& accCc = mesh_.cellCentres()[celli];
2275 const point& donorCc = cc[slots[i]];
2289 forAll(interpolationCells_, i)
2291 label celli = interpolationCells_[i];
2292 const labelList& slots = cellStencil_[celli];
2294 bool hasLocal =
false;
2295 bool hasRemote =
false;
2299 if (slots[sloti] >= mesh_.nCells())
2329 Info<<
"Overset analysis : nCells : "
2332 <<
indent <<
"calculated : " << nCells[CALCULATED] <<
nl
2333 <<
indent <<
"interpolated : " << nCells[INTERPOLATED]
2334 <<
" (interpolated from local:" << nLocal
2335 <<
" mixed local/remote:" << nMixed
2336 <<
" remote:" << nRemote <<
")" <<
nl
2337 <<
indent <<
"hole : " << nCells[HOLE] <<
nl