60 label procI = toProc[i];
79 sendMap[procI].setSize(nSend[procI]);
87 label procI = toProc[i];
89 sendMap[procI][nSend[procI]++] = i;
105 forAll(constructMap, procI)
111 constructMap[procI].setSize(nRecv);
113 for (
label i = 0; i < nRecv; i++)
115 constructMap[procI][i] = constructSize++;
120 return autoPtr<mapDistribute>
141 mesh_.time().timeName(),
148 zeroGradientFvPatchScalarField::typeName
151 const conformationSurfaces& geometry = geometryToConformTo_;
153 decompositionMethod& decomposer =
172 forAll(volumeStatus, cellI)
178 mesh_.cells()[cellI].points
185 if (geometry.overlaps(cellBb))
189 else if (geometry.inside(cellBb.midpoint()))
201 labelList refCells = selectRefinementCells
210 meshCutter_.consistentRefinement
217 forAll(newCellsToRefine, nCTRI)
219 label cellI = newCellsToRefine[nCTRI];
226 icellWeights[cellI] =
max
229 icellWeights[cellI]/8.0
233 if (
returnReduce(newCellsToRefine.size(), sumOp<label>()) == 0)
239 polyTopoChange meshMod(mesh_);
242 meshCutter_.setRefinement(newCellsToRefine, meshMod);
245 autoPtr<mapPolyMesh> map = meshMod.changeMesh
255 mesh_.updateMesh(map);
258 meshCutter_.updateMesh(map);
263 const labelList& cellMap = map().cellMap();
269 label oldCellI = cellMap[newCellI];
277 newVolumeStatus[newCellI] = volumeStatus[oldCellI];
281 volumeStatus.transfer(newVolumeStatus);
284 Info<<
" Background mesh refined from "
286 <<
" to " << mesh_.globalData().nTotalCells()
287 <<
" cells." <<
endl;
291 forAll(volumeStatus, cellI)
297 mesh_.cells()[cellI].points
304 if (geometry.overlaps(cellBb))
308 else if (geometry.inside(cellBb.midpoint()))
320 bool removeOutsideCells =
false;
322 if (removeOutsideCells)
324 DynamicList<label> cellsToRemove;
326 forAll(volumeStatus, cellI)
330 cellsToRemove.append(cellI);
334 removeCells cellRemover(mesh_);
337 polyTopoChange meshMod(mesh_);
339 labelList exposedFaces = cellRemover.getExposedFaces
345 cellRemover.setRefinement
354 autoPtr<mapPolyMesh> map = meshMod.changeMesh
364 mesh_.updateMesh(map);
367 meshCutter_.updateMesh(map);
368 cellRemover.updateMesh(map);
373 const labelList& cellMap = map().cellMap();
379 label oldCellI = cellMap[newCellI];
387 newVolumeStatus[newCellI] = volumeStatus[oldCellI];
391 volumeStatus.transfer(newVolumeStatus);
396 - mesh_.globalData().nTotalCells()
397 <<
" cells." <<
endl;
409 labelList newDecomp = decomposer.decompose
416 fvMeshDistribute distributor(mesh_, mergeDist_);
418 autoPtr<mapDistributePolyMesh> mapDist = distributor.distribute
423 meshCutter_.distribute(mapDist);
425 mapDist().distributeCellData(volumeStatus);
484 Info<<
"Processor " << procI <<
" "
485 <<
"Number of cells = " << globalCells.localSize(procI)
513 scalar& weightEstimate
523 mesh_.cells()[cellI].points
530 weightEstimate = 1.0;
645 forAll(volumeStatus, cellI)
649 if (meshCutter_.cellLevel()[cellI] < minLevels_)
651 cellsToRefine.insert(cellI);
667 cellsToRefine.insert(cellI);
672 return cellsToRefine.toc();
683 mesh_.nFaces() - mesh_.nInternalFaces(),
684 mesh_.nInternalFaces()
689 boundaryFacesPtr_.reset
693 tmpBoundaryFaces.localFaces(),
694 tmpBoundaryFaces.localPoints()
699 treeBoundBox overallBb(boundaryFacesPtr_().localPoints());
701 Random& rnd = rndGen_;
705 new indexedOctree<treeDataBPatch>
713 overallBb.extend(rnd, 1
e-4),
726 point bbMin(GREAT, GREAT, GREAT);
727 point bbMax(-GREAT, -GREAT, -GREAT);
729 forAll(allBackgroundMeshBounds_, procI)
731 bbMin =
min(bbMin, allBackgroundMeshBounds_[procI].
min());
732 bbMax =
max(bbMax, allBackgroundMeshBounds_[procI].
max());
735 globalBackgroundBounds_ = treeBoundBox(bbMin, bbMax);
742 /
"backgroundMeshDecomposition_proc_"
744 +
"_boundaryFaces.obj"
747 const faceList& faces = boundaryFacesPtr_().localFaces();
750 Map<label> foamToObj(
points.size());
756 const face&
f = faces[i];
760 if (foamToObj.insert(
f[fPI], vertI))
771 fStr<<
' ' << foamToObj[
f[fPI]] + 1;
786 const conformationSurfaces& geometryToConformTo,
787 const dictionary& coeffsDict,
788 const fileName& decompDictFile
792 geometryToConformTo_(geometryToConformTo),
798 "backgroundMeshDecomposition",
802 IOobject::AUTO_WRITE,
814 allBackgroundMeshBounds_(Pstream::nProcs()),
815 globalBackgroundBounds_(),
816 mergeDist_(1
e-6*mesh_.bounds().
mag()),
820 coeffsDict.lookupOrDefault<scalar>(
"minCellSizeLimit", 0.0)
829 <<
"This cannot be used when not running in parallel."
833 const decompositionMethod& decomposer =
836 if (!decomposer.parallelAware())
839 <<
"You have selected decomposition method "
840 << decomposer.typeName
841 <<
" which is not parallel aware." <<
endl
845 Info<<
nl <<
"Building initial background mesh decomposition" <<
endl;
879 label nOccupiedCells = 0;
883 if (icellWeights[cI] > 1 - SMALL)
893 scalar cellWeightLimit =
max
896 *
sum(cellWeights).value()
903 Info<<
" cellWeightLimit " << cellWeightLimit <<
endl;
905 Pout<<
" sum(cellWeights) " <<
sum(cellWeights.internalField())
906 <<
" max(cellWeights) " <<
max(cellWeights.internalField())
914 if (icellWeights[cWI] > cellWeightLimit)
916 cellsToRefine.insert(cWI);
920 if (
returnReduce(cellsToRefine.size(), sumOp<label>()) == 0)
928 meshCutter_.consistentRefinement
935 if (debug && !cellsToRefine.empty())
937 Pout<<
" cellWeights too large in " << cellsToRefine.size()
941 forAll(newCellsToRefine, nCTRI)
943 label cellI = newCellsToRefine[nCTRI];
945 icellWeights[cellI] /= 8.0;
949 polyTopoChange meshMod(mesh_);
952 meshCutter_.setRefinement(newCellsToRefine, meshMod);
955 autoPtr<mapPolyMesh> map = meshMod.changeMesh
965 mesh_.updateMesh(map);
968 meshCutter_.updateMesh(map);
970 Info<<
" Background mesh refined from "
972 <<
" to " << mesh_.globalData().nTotalCells()
973 <<
" cells." <<
endl;
988 Pout<<
" Pre distribute sum(cellWeights) "
990 <<
" max(cellWeights) "
995 decompositionMethod& decomposer =
998 labelList newDecomp = decomposer.decompose
1001 mesh_.cellCentres(),
1005 Info<<
" Redistributing background mesh cells" <<
endl;
1007 fvMeshDistribute distributor(mesh_, mergeDist_);
1009 autoPtr<mapDistributePolyMesh> mapDist = distributor.distribute(newDecomp);
1011 meshCutter_.distribute(mapDist);
1017 Pout<<
" Post distribute sum(cellWeights) "
1018 <<
sum(icellWeights)
1019 <<
" max(cellWeights) "
1020 <<
max(icellWeights)
1026 cellWeights.
write();
1029 buildPatchAndTree();
1055 posProc[pI] = positionOnThisProcessor(pts[pI]);
1064 const treeBoundBox& box
1068 return !bFTreePtr_().findBox(box).empty();
1074 const point& centre,
1075 const scalar radiusSqr
1080 return bFTreePtr_().findNearest(centre, radiusSqr).hit();
1090 return bFTreePtr_().findLine(start, end);
1100 return bFTreePtr_().findLineAny(start, end);
1109 DynamicList<label> toCandidateProc;
1110 DynamicList<point> testPoints;
1114 label nTotalCandidates = 0;
1118 const point& pt = pts[pI];
1120 label nCandidates = 0;
1122 forAll(allBackgroundMeshBounds_, procI)
1126 if (allBackgroundMeshBounds_[procI].overlaps(pt,
sqr(SMALL*100)))
1128 toCandidateProc.append(procI);
1129 testPoints.append(pt);
1135 ptBlockStart[pI] = nTotalCandidates;
1136 ptBlockSize[pI] = nCandidates;
1138 nTotalCandidates += nCandidates;
1142 label preDistributionToCandidateProcSize = toCandidateProc.size();
1144 autoPtr<mapDistribute> map(buildMap(toCandidateProc));
1146 map().distribute(testPoints);
1161 distanceSqrToCandidate[tPI] =
magSqr
1163 testPoints[tPI] - info.hitPoint()
1168 map().reverseDistribute
1170 preDistributionToCandidateProcSize,
1171 distanceSqrToCandidate
1180 SubList<scalar> ptNearestProcResults
1182 distanceSqrToCandidate,
1187 scalar nearestProcDistSqr = GREAT;
1189 forAll(ptNearestProcResults, pPRI)
1191 if (ptNearestProcResults[pPRI] < nearestProcDistSqr)
1193 nearestProcDistSqr = ptNearestProcResults[pPRI];
1195 ptNearestProc[pI] = toCandidateProc[ptBlockStart[pI] + pPRI];
1201 Pout<< pts[pI] <<
" nearestProcDistSqr " << nearestProcDistSqr
1202 <<
" ptNearestProc[pI] " << ptNearestProc[pI] <<
endl;
1205 if (ptNearestProc[pI] < 0)
1208 <<
"The position " << pts[pI]
1209 <<
" did not find a nearest point on the background mesh."
1214 return ptNearestProc;
1224 bool includeOwnProcessor
1227 DynamicList<label> toCandidateProc;
1228 DynamicList<point> testStarts;
1229 DynamicList<point> testEnds;
1233 label nTotalCandidates = 0;
1237 const point&
s = starts[sI];
1238 const point&
e = ends[sI];
1243 label nCandidates = 0;
1245 forAll(allBackgroundMeshBounds_, procI)
1252 && allBackgroundMeshBounds_[procI].intersects(
s,
e,
p)
1255 toCandidateProc.append(procI);
1256 testStarts.append(
s);
1263 segmentBlockStart[sI] = nTotalCandidates;
1264 segmentBlockSize[sI] = nCandidates;
1266 nTotalCandidates += nCandidates;
1270 label preDistributionToCandidateProcSize = toCandidateProc.size();
1272 autoPtr<mapDistribute> map(buildMap(toCandidateProc));
1274 map().distribute(testStarts);
1275 map().distribute(testEnds);
1282 const point&
s = testStarts[sI];
1283 const point&
e = testEnds[sI];
1286 segmentIntersectsCandidate[sI] = bFTreePtr_().findLine(
s,
e);
1289 map().reverseDistribute
1291 preDistributionToCandidateProcSize,
1292 segmentIntersectsCandidate
1298 DynamicList<pointIndexHit> tmpProcHits;
1302 tmpProcHits.clear();
1306 SubList<pointIndexHit> segmentProcResults
1308 segmentIntersectsCandidate,
1309 segmentBlockSize[sI],
1310 segmentBlockStart[sI]
1313 forAll(segmentProcResults, sPRI)
1315 if (segmentProcResults[sPRI].hit())
1317 tmpProcHits.append(segmentProcResults[sPRI]);
1319 tmpProcHits.last().setIndex
1321 toCandidateProc[segmentBlockStart[sI] + sPRI]
1326 segmentHitProcs[sI] = tmpProcHits;
1329 return segmentHitProcs;
1335 const point& centre,
1336 const scalar& radiusSqr
1339 forAll(allBackgroundMeshBounds_, procI)
1341 if (bFTreePtr_().findNearest(centre, radiusSqr).hit())
1353 const point& centre,
1354 const scalar radiusSqr
1359 forAll(allBackgroundMeshBounds_, procI)
1365 && allBackgroundMeshBounds_[procI].overlaps(centre, radiusSqr)
1371 toProc.append(procI);