48 const List<label>& toProc
59 label procI = toProc[i];
78 sendMap[procI].setSize(nSend[procI]);
86 label procI = toProc[i];
88 sendMap[procI][nSend[procI]++] = i;
104 forAll(constructMap, procI)
110 constructMap[procI].setSize(nRecv);
112 for (
label i = 0; i < nRecv; i++)
114 constructMap[procI][i] = constructSize++;
119 return autoPtr<mapDistribute>
133 void Foam::backgroundMeshDecomposition::initialRefinement()
140 mesh_.time().timeName(),
147 zeroGradientFvPatchScalarField::typeName
150 const conformationSurfaces& geometry = geometryToConformTo_;
152 decompositionMethod& decomposer = decomposerPtr_();
159 List<volumeType> volumeStatus
170 forAll(volumeStatus, cellI)
176 mesh_.cells()[cellI].points
183 if (geometry.overlaps(cellBb))
187 else if (geometry.inside(cellBb.midpoint()))
199 labelList refCells = selectRefinementCells
208 meshCutter_.consistentRefinement
215 forAll(newCellsToRefine, nCTRI)
217 label cellI = newCellsToRefine[nCTRI];
224 icellWeights[cellI] =
max 227 icellWeights[cellI]/8.0
231 if (
returnReduce(newCellsToRefine.size(), sumOp<label>()) == 0)
237 polyTopoChange meshMod(mesh_);
240 meshCutter_.setRefinement(newCellsToRefine, meshMod);
243 autoPtr<mapPolyMesh> map = meshMod.changeMesh
253 mesh_.updateMesh(map);
256 meshCutter_.updateMesh(map);
261 const labelList& cellMap = map().cellMap();
263 List<volumeType> newVolumeStatus(cellMap.size());
267 label oldCellI = cellMap[newCellI];
275 newVolumeStatus[newCellI] = volumeStatus[oldCellI];
279 volumeStatus.transfer(newVolumeStatus);
282 Info<<
" Background mesh refined from " 284 <<
" to " << mesh_.globalData().nTotalCells()
285 <<
" cells." <<
endl;
289 forAll(volumeStatus, cellI)
295 mesh_.cells()[cellI].points
302 if (geometry.overlaps(cellBb))
306 else if (geometry.inside(cellBb.midpoint()))
318 bool removeOutsideCells =
false;
320 if (removeOutsideCells)
322 DynamicList<label> cellsToRemove;
324 forAll(volumeStatus, cellI)
328 cellsToRemove.append(cellI);
332 removeCells cellRemover(mesh_);
335 polyTopoChange meshMod(mesh_);
337 labelList exposedFaces = cellRemover.getExposedFaces
343 cellRemover.setRefinement
352 autoPtr<mapPolyMesh> map = meshMod.changeMesh
362 mesh_.updateMesh(map);
365 meshCutter_.updateMesh(map);
366 cellRemover.updateMesh(map);
371 const labelList& cellMap = map().cellMap();
373 List<volumeType> newVolumeStatus(cellMap.size());
377 label oldCellI = cellMap[newCellI];
385 newVolumeStatus[newCellI] = volumeStatus[oldCellI];
389 volumeStatus.transfer(newVolumeStatus);
394 - mesh_.globalData().nTotalCells()
395 <<
" cells." <<
endl;
407 labelList newDecomp = decomposer.decompose
414 fvMeshDistribute distributor(mesh_, mergeDist_);
416 autoPtr<mapDistributePolyMesh> mapDist = distributor.distribute
421 meshCutter_.distribute(mapDist);
423 mapDist().distributeCellData(volumeStatus);
427 printMeshData(mesh_);
450 void Foam::backgroundMeshDecomposition::printMeshData
457 globalIndex globalCells(mesh.nCells());
482 Info<<
"Processor " << procI <<
" " 483 <<
"Number of cells = " << globalCells.localSize(procI)
507 bool Foam::backgroundMeshDecomposition::refineCell
511 scalar& weightEstimate
521 mesh_.cells()[cellI].points
528 weightEstimate = 1.0;
632 Foam::labelList Foam::backgroundMeshDecomposition::selectRefinementCells
634 List<volumeType>& volumeStatus,
643 forAll(volumeStatus, cellI)
647 if (meshCutter_.cellLevel()[cellI] < minLevels_)
649 cellsToRefine.insert(cellI);
665 cellsToRefine.insert(cellI);
670 return cellsToRefine.toc();
674 void Foam::backgroundMeshDecomposition::buildPatchAndTree()
681 mesh_.nFaces() - mesh_.nInternalFaces(),
682 mesh_.nInternalFaces()
687 boundaryFacesPtr_.reset
691 tmpBoundaryFaces.localFaces(),
692 tmpBoundaryFaces.localPoints()
697 treeBoundBox overallBb(boundaryFacesPtr_().localPoints());
699 Random& rnd = rndGen_;
703 new indexedOctree<treeDataBPatch>
711 overallBb.extend(rnd, 1e-4),
724 point bbMin(GREAT, GREAT, GREAT);
725 point bbMax(-GREAT, -GREAT, -GREAT);
727 forAll(allBackgroundMeshBounds_, procI)
729 bbMin =
min(bbMin, allBackgroundMeshBounds_[procI].
min());
730 bbMax =
max(bbMax, allBackgroundMeshBounds_[procI].
max());
733 globalBackgroundBounds_ = treeBoundBox(bbMin, bbMax);
740 /
"backgroundMeshDecomposition_proc_" 742 +
"_boundaryFaces.obj" 745 const faceList& faces = boundaryFacesPtr_().localFaces();
746 const List<point>& points = boundaryFacesPtr_().localPoints();
748 Map<label> foamToObj(points.size());
754 const face&
f = faces[i];
758 if (foamToObj.insert(f[fPI], vertI))
769 fStr<<
' ' << foamToObj[f[fPI]] + 1;
780 Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
784 const conformationSurfaces& geometryToConformTo,
785 const dictionary& coeffsDict
789 geometryToConformTo_(geometryToConformTo),
795 "backgroundMeshDecomposition",
799 IOobject::AUTO_WRITE,
811 allBackgroundMeshBounds_(Pstream::nProcs()),
812 globalBackgroundBounds_(),
820 IOobject::MUST_READ_IF_MODIFIED,
824 decomposerPtr_(decompositionMethod::
New(decomposeDict_)),
825 mergeDist_(1e-6*mesh_.bounds().
mag()),
829 coeffsDict.lookupOrDefault<scalar>(
"minCellSizeLimit", 0.0)
839 "Foam::backgroundMeshDecomposition::backgroundMeshDecomposition" 841 "const dictionary& coeffsDict, " 842 "const conformalVoronoiMesh& foamyHexMesh" 845 <<
"This cannot be used when not running in parallel." 849 if (!decomposerPtr_().parallelAware())
853 "void Foam::backgroundMeshDecomposition::initialRefinement() const" 855 <<
"You have selected decomposition method " 856 << decomposerPtr_().typeName
857 <<
" which is not parallel aware." << endl
861 Info<<
nl <<
"Building initial background mesh decomposition" <<
endl;
895 label nOccupiedCells = 0;
899 if (icellWeights[cI] > 1 - SMALL)
909 scalar cellWeightLimit =
max 912 *
sum(cellWeights).value()
919 Info<<
" cellWeightLimit " << cellWeightLimit <<
endl;
921 Pout<<
" sum(cellWeights) " <<
sum(cellWeights.internalField())
922 <<
" max(cellWeights) " <<
max(cellWeights.internalField())
930 if (icellWeights[cWI] > cellWeightLimit)
932 cellsToRefine.insert(cWI);
936 if (
returnReduce(cellsToRefine.size(), sumOp<label>()) == 0)
944 meshCutter_.consistentRefinement
951 if (debug && !cellsToRefine.empty())
953 Pout<<
" cellWeights too large in " << cellsToRefine.size()
957 forAll(newCellsToRefine, nCTRI)
959 label cellI = newCellsToRefine[nCTRI];
961 icellWeights[cellI] /= 8.0;
965 polyTopoChange meshMod(mesh_);
968 meshCutter_.setRefinement(newCellsToRefine, meshMod);
971 autoPtr<mapPolyMesh> map = meshMod.changeMesh
981 mesh_.updateMesh(map);
984 meshCutter_.updateMesh(map);
986 Info<<
" Background mesh refined from " 988 <<
" to " << mesh_.globalData().nTotalCells()
989 <<
" cells." <<
endl;
1002 printMeshData(mesh_);
1004 Pout<<
" Pre distribute sum(cellWeights) " 1005 <<
sum(icellWeights)
1006 <<
" max(cellWeights) " 1007 <<
max(icellWeights)
1011 labelList newDecomp = decomposerPtr_().decompose
1014 mesh_.cellCentres(),
1018 Info<<
" Redistributing background mesh cells" <<
endl;
1020 fvMeshDistribute distributor(mesh_, mergeDist_);
1022 autoPtr<mapDistributePolyMesh> mapDist = distributor.distribute(newDecomp);
1024 meshCutter_.distribute(mapDist);
1028 printMeshData(mesh_);
1030 Pout<<
" Post distribute sum(cellWeights) " 1031 <<
sum(icellWeights)
1032 <<
" max(cellWeights) " 1033 <<
max(icellWeights)
1039 cellWeights.
write();
1042 buildPatchAndTree();
1061 const List<point>& pts
1064 boolList posProc(pts.size(),
true);
1068 posProc[pI] = positionOnThisProcessor(pts[pI]);
1077 const treeBoundBox& box
1081 return !bFTreePtr_().findBox(box).empty();
1087 const point& centre,
1088 const scalar radiusSqr
1093 return bFTreePtr_().findNearest(centre, radiusSqr).hit();
1103 return bFTreePtr_().findLine(start, end);
1113 return bFTreePtr_().findLineAny(start, end);
1119 const List<point>& pts
1122 DynamicList<label> toCandidateProc;
1123 DynamicList<point> testPoints;
1127 label nTotalCandidates = 0;
1131 const point& pt = pts[pI];
1133 label nCandidates = 0;
1135 forAll(allBackgroundMeshBounds_, procI)
1139 if (allBackgroundMeshBounds_[procI].overlaps(pt,
sqr(SMALL*100)))
1141 toCandidateProc.append(procI);
1142 testPoints.append(pt);
1148 ptBlockStart[pI] = nTotalCandidates;
1149 ptBlockSize[pI] = nCandidates;
1151 nTotalCandidates += nCandidates;
1155 label preDistributionToCandidateProcSize = toCandidateProc.size();
1157 autoPtr<mapDistribute> map(buildMap(toCandidateProc));
1159 map().distribute(testPoints);
1161 List<scalar> distanceSqrToCandidate(testPoints.size(),
sqr(GREAT));
1174 distanceSqrToCandidate[tPI] =
magSqr 1176 testPoints[tPI] - info.hitPoint()
1181 map().reverseDistribute
1183 preDistributionToCandidateProcSize,
1184 distanceSqrToCandidate
1187 labelList ptNearestProc(pts.size(), -1);
1193 SubList<scalar> ptNearestProcResults
1195 distanceSqrToCandidate,
1200 scalar nearestProcDistSqr = GREAT;
1202 forAll(ptNearestProcResults, pPRI)
1204 if (ptNearestProcResults[pPRI] < nearestProcDistSqr)
1206 nearestProcDistSqr = ptNearestProcResults[pPRI];
1208 ptNearestProc[pI] = toCandidateProc[ptBlockStart[pI] + pPRI];
1214 Pout<< pts[pI] <<
" nearestProcDistSqr " << nearestProcDistSqr
1215 <<
" ptNearestProc[pI] " << ptNearestProc[pI] <<
endl;
1218 if (ptNearestProc[pI] < 0)
1223 "Foam::backgroundMeshDecomposition::processorNearestPosition" 1225 "const List<point>& pts" 1228 <<
"The position " << pts[pI]
1229 <<
" did not find a nearest point on the background mesh." 1234 return ptNearestProc;
1242 const List<point>& starts,
1243 const List<point>& ends,
1244 bool includeOwnProcessor
1247 DynamicList<label> toCandidateProc;
1248 DynamicList<point> testStarts;
1249 DynamicList<point> testEnds;
1250 labelList segmentBlockStart(starts.size(), -1);
1251 labelList segmentBlockSize(starts.size(), -1);
1253 label nTotalCandidates = 0;
1257 const point& s = starts[sI];
1258 const point& e = ends[sI];
1263 label nCandidates = 0;
1265 forAll(allBackgroundMeshBounds_, procI)
1272 && allBackgroundMeshBounds_[procI].intersects(s, e,
p)
1275 toCandidateProc.append(procI);
1276 testStarts.append(s);
1283 segmentBlockStart[sI] = nTotalCandidates;
1284 segmentBlockSize[sI] = nCandidates;
1286 nTotalCandidates += nCandidates;
1290 label preDistributionToCandidateProcSize = toCandidateProc.size();
1292 autoPtr<mapDistribute> map(buildMap(toCandidateProc));
1294 map().distribute(testStarts);
1295 map().distribute(testEnds);
1297 List<pointIndexHit> segmentIntersectsCandidate(testStarts.size());
1302 const point& s = testStarts[sI];
1303 const point& e = testEnds[sI];
1306 segmentIntersectsCandidate[sI] = bFTreePtr_().findLine(s, e);
1309 map().reverseDistribute
1311 preDistributionToCandidateProcSize,
1312 segmentIntersectsCandidate
1315 List<List<pointIndexHit> > segmentHitProcs(starts.size());
1318 DynamicList<pointIndexHit> tmpProcHits;
1322 tmpProcHits.clear();
1326 SubList<pointIndexHit> segmentProcResults
1328 segmentIntersectsCandidate,
1329 segmentBlockSize[sI],
1330 segmentBlockStart[sI]
1333 forAll(segmentProcResults, sPRI)
1335 if (segmentProcResults[sPRI].hit())
1337 tmpProcHits.append(segmentProcResults[sPRI]);
1339 tmpProcHits.last().setIndex
1341 toCandidateProc[segmentBlockStart[sI] + sPRI]
1346 segmentHitProcs[sI] = tmpProcHits;
1349 return segmentHitProcs;
1355 const point& centre,
1356 const scalar& radiusSqr
1359 forAll(allBackgroundMeshBounds_, procI)
1361 if (bFTreePtr_().findNearest(centre, radiusSqr).hit())
1373 const point& centre,
1374 const scalar radiusSqr
1379 forAll(allBackgroundMeshBounds_, procI)
1385 && allBackgroundMeshBounds_[procI].overlaps(centre, radiusSqr)
1391 toProc.append(procI);
static bool & parRun()
Is this a parallel run?
autoPtr< mapDistributePolyMesh > distribute(volScalarField &cellWeights)
Redistribute the background mesh based on a supplied weight field,.
static scalar & perturbTol()
Get the perturbation tolerance.
bool overlapsOtherProcessors(const point ¢re, const scalar &radiusSqr) const
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
vector point
Point is a vector.
dimensioned< scalar > mag(const dimensioned< Type > &)
word name(const complex &)
Return a string representation of a complex.
static void gatherList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Gather data but keep individual values separate.
dimensioned< scalar > magSqr(const dimensioned< Type > &)
labelList processorNearestPosition(const List< point > &pts) const
What is the nearest processor to the given position?
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
static autoPtr< mapDistribute > buildMap(const List< label > &toProc)
Build a mapDistribute for the supplied destination processor data.
errorManipArg< error, int > exit(error &err, const int errNo=1)
PointIndexHit< point > pointIndexHit
static void scatterList(const List< commsStruct > &comms, List< T > &Values, const int tag, const label comm)
Scatter data. Reverse of gatherList.
pointIndexHit findLineAny(const point &start, const point &end) const
Find any intersection of line between start and end, (exposing.
autoPtr< BasicCompressibleTurbulenceModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const typename BasicCompressibleTurbulenceModel::transportModel &transport, const word &propertiesName)
labelList overlapProcessors(const point ¢re, const scalar radiusSqr) const
label readLabel(Istream &is)
static label nProcs(const label communicator=0)
Number of processes in parallel run.
bool positionOnThisProcessor(const point &pt) const
Is the given position inside the domain of this decomposition.
Ostream & endl(Ostream &os)
Add newline and flush stream.
stressControl lookup("compactNormalStress") >> compactNormalStress
GeometricField< scalar, fvPatchField, volMesh > volScalarField
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
virtual Ostream & write(const token &)=0
Write next token to stream.
~backgroundMeshDecomposition()
Destructor.
labelList identity(const label len)
Create identity map (map[i] == i) of given length.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &df)
bool overlapsThisProcessor(const treeBoundBox &box) const
Does the given box overlap the faces of the boundary of this.
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
#define FatalErrorIn(functionName)
Report an error message using Foam::FatalError.
HashSet< label, Hash< label > > labelHashSet
A HashSet with label keys.
pointIndexHit findLine(const point &start, const point &end) const
Find nearest intersection of line between start and end, (exposing.
int system(const std::string &command)
Execute the specified command.
List< List< pointIndexHit > > intersectsProcessors(const List< point > &starts, const List< point > &ends, bool includeOwnProcessor=false) const
Which processors are intersected by the line segment, returns all.
List< label > labelList
A List of labels.
const dimensionSet dimless(0, 0, 0, 0, 0, 0, 0)
PrimitivePatch< face, SubList, const pointField & > primitivePatch
Addressing for a faceList slice.
void combineReduce(const List< UPstream::commsStruct > &comms, T &Value, const CombineOp &cop, const int tag, const label comm)
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
List< labelList > labelListList
A List of labelList.
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
PrimitivePatch< face, List, const pointField > bPatch
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
treeDataPrimitivePatch< bPatch > treeDataBPatch
Field< scalar > InternalField
defineTypeNameAndDebug(combustionModel, 0)
prefixOSstream Pout(cout,"Pout")
List< bool > boolList
Bool container classes.