55 void Foam::domainDecomposition::mark
62 for (
const label pointi : zoneElems)
64 if (elementToZone[pointi] == -1)
67 elementToZone[pointi] = zoneI;
69 else if (elementToZone[pointi] >= 0)
72 elementToZone[pointi] = -2;
83 const fileName& decompDictFile
87 facesInstancePointsPtr_
89 pointsInstance() != facesInstance()
100 IOobject::NO_REGISTER
105 decompDictFile_(decompDictFile),
108 decompositionMethod::nDomains
110 decompositionModel::
New 118 cellToProc_(nCells()),
119 procPointAddressing_(nProcs_),
120 procFaceAddressing_(nProcs_),
121 procCellAddressing_(nProcs_),
122 procPatchSize_(nProcs_),
123 procPatchStartIndex_(nProcs_),
124 procNeighbourProcessors_(nProcs_),
125 procProcessorPatchSize_(nProcs_),
126 procProcessorPatchStartIndex_(nProcs_),
127 procProcessorPatchSubPatchIDs_(nProcs_),
128 procProcessorPatchSubPatchStarts_(nProcs_)
130 updateParameters(this->model());
144 const dictionary& params
147 params.readIfPresent(
"distributed", distributed_);
153 Info<<
"\nConstructing processor meshes" <<
endl;
166 forAll(pointZones(), zonei)
168 mark(pointZones()[zonei], zonei, pointToZone);
172 labelList faceToZone(faces().size(), -1);
174 forAll(faceZones(), zonei)
176 mark(faceZones()[zonei], zonei, faceToZone);
182 forAll(cellZones(), zonei)
184 mark(cellZones()[zonei], zonei, cellToZone);
188 PtrDynList<const cellSet> cellSets;
189 PtrDynList<const faceSet> faceSets;
190 PtrDynList<const pointSet> pointSets;
194 IOobjectList objects(*
this, facesInstance(),
"polyMesh/sets");
195 for (
const IOobject&
io : objects.csorted<cellSet>())
197 cellSets.emplace_back(
io);
199 for (
const IOobject&
io : objects.csorted<faceSet>())
201 faceSets.emplace_back(
io);
203 for (
const IOobject&
io : objects.csorted<pointSet>())
205 pointSets.emplace_back(
io);
211 hexRef8Data baseMeshData
226 label maxProcCells = 0;
227 label maxProcFaces = 0;
228 label totProcFaces = 0;
229 label maxProcPatches = 0;
230 label totProcPatches = 0;
233 for (label proci = 0; proci < nProcs_; proci++)
236 const labelList& curPointLabels = procPointAddressing_[proci];
242 forAll(curPointLabels, pointi)
244 pointLookup[curPointLabels[pointi]] = pointi;
248 const labelList& curFaceLabels = procFaceAddressing_[proci];
250 const faceList& meshFaces = faces();
254 faceList procFaces(curFaceLabels.size());
256 forAll(curFaceLabels, facei)
260 label curF =
mag(curFaceLabels[facei]) - 1;
262 faceLookup[curF] = facei;
267 if (curFaceLabels[facei] >= 0)
270 origFaceLabels = meshFaces[curF];
274 origFaceLabels = meshFaces[curF].reverseFace();
278 face& procFaceLabels = procFaces[facei];
280 procFaceLabels.
setSize(origFaceLabels.size());
282 forAll(origFaceLabels, pointi)
284 procFaceLabels[pointi] = pointLookup[origFaceLabels[pointi]];
289 const labelList& curCellLabels = procCellAddressing_[proci];
293 cellList procCells(curCellLabels.size());
295 forAll(curCellLabels, celli)
297 const labelList& origCellLabels = meshCells[curCellLabels[celli]];
299 cell& curCell = procCells[celli];
301 curCell.
setSize(origCellLabels.size());
303 forAll(origCellLabels, cellFacei)
305 curCell[cellFacei] = faceLookup[origCellLabels[cellFacei]];
316 time().caseName()/(
"processor" +
Foam::name(proci)),
320 processorDb.setTime(time());
332 autoPtr<polyMesh> procMeshPtr;
334 if (facesInstancePointsPtr_)
339 facesInstancePointsPtr_(),
353 std::move(facesInstancePoints),
354 std::move(procFaces),
370 std::move(procPoints),
371 std::move(procFaces),
375 polyMesh& procMesh = procMeshPtr();
379 const labelList& curPatchSizes = procPatchSize_[proci];
381 const labelList& curPatchStarts = procPatchStartIndex_[proci];
383 const labelList& curNeighbourProcessors =
384 procNeighbourProcessors_[proci];
386 const labelList& curProcessorPatchSizes =
387 procProcessorPatchSize_[proci];
389 const labelList& curProcessorPatchStarts =
390 procProcessorPatchStartIndex_[proci];
393 procProcessorPatchSubPatchIDs_[proci];
396 procProcessorPatchSubPatchStarts_[proci];
402 label nInterProcPatches = 0;
403 forAll(curSubPatchIDs, procPatchi)
405 nInterProcPatches += curSubPatchIDs[procPatchi].size();
410 curPatchSizes.size() + nInterProcPatches
415 forAll(curPatchSizes, patchi)
419 const polyPatch& meshPatch = meshPatches[patchi];
421 fvFieldDecomposer::patchFieldDecomposer patchMapper
426 curPatchSizes[patchi],
427 curPatchStarts[patchi]
438 procMesh.boundaryMesh(),
440 patchMapper.directAddressing(),
441 curPatchStarts[patchi]
448 forAll(curProcessorPatchSizes, procPatchi)
450 const labelList& subPatchID = curSubPatchIDs[procPatchi];
451 const labelList& subStarts = curSubStarts[procPatchi];
453 label curStart = curProcessorPatchStarts[procPatchi];
459 i < subPatchID.size()-1
460 ? subStarts[i+1] - subStarts[i]
461 : curProcessorPatchSizes[procPatchi] - subStarts[i]
464 if (subPatchID[i] == -1)
470 new processorPolyPatch
475 procMesh.boundaryMesh(),
477 curNeighbourProcessors[procPatchi]
483 const coupledPolyPatch& pcPatch
484 = refCast<const coupledPolyPatch>
486 boundaryMesh()[subPatchID[i]]
492 new processorCyclicPolyPatch
497 procMesh.boundaryMesh(),
499 curNeighbourProcessors[procPatchi],
512 procMesh.addPatches(procPatches);
523 List<DynamicList<label>> zonePoints(pz.size());
528 zonePoints[zonei].setCapacity(pz[zonei].size()/nProcs_);
533 forAll(curPointLabels, pointi)
535 label curPoint = curPointLabels[pointi];
537 label zonei = pointToZone[curPoint];
542 zonePoints[zonei].append(pointi);
544 else if (zonei == -2)
549 label index = pz[zonei].whichPoint(curPoint);
553 zonePoints[zonei].append(pointi);
559 procMesh.pointZones().clearAddressing();
560 procMesh.pointZones().setSize(zonePoints.size());
563 procMesh.pointZones().set
568 procMesh.pointZones(),
570 zonePoints[zonei].shrink()
589 List<DynamicList<label>> zoneFaces(fz.size());
590 List<DynamicList<bool>> zoneFaceFlips(fz.size());
595 label procSize = fz[zonei].size() / nProcs_;
597 zoneFaces[zonei].setCapacity(procSize);
598 zoneFaceFlips[zonei].setCapacity(procSize);
604 forAll(curFaceLabels, facei)
608 label curF =
mag(curFaceLabels[facei]) - 1;
610 label zonei = faceToZone[curF];
615 zoneFaces[zonei].append(facei);
617 label index = fz[zonei].whichFace(curF);
619 bool flip = fz[zonei].flipMap()[index];
621 if (curFaceLabels[facei] < 0)
626 zoneFaceFlips[zonei].append(flip);
628 else if (zonei == -2)
633 label index = fz[zonei].whichFace(curF);
637 zoneFaces[zonei].append(facei);
639 bool flip = fz[zonei].flipMap()[index];
641 if (curFaceLabels[facei] < 0)
646 zoneFaceFlips[zonei].append(flip);
652 procMesh.faceZones().clearAddressing();
653 procMesh.faceZones().setSize(zoneFaces.size());
656 procMesh.faceZones().set
661 zoneFaces[zonei].shrink(),
662 zoneFaceFlips[zonei].shrink(),
683 List<DynamicList<label>> zoneCells(cz.size());
688 zoneCells[zonei].setCapacity(cz[zonei].size()/nProcs_);
691 forAll(curCellLabels, celli)
693 label curCelli = curCellLabels[celli];
695 label zonei = cellToZone[curCelli];
700 zoneCells[zonei].append(celli);
702 else if (zonei == -2)
707 label index = cz[zonei].whichCell(curCelli);
711 zoneCells[zonei].append(celli);
717 procMesh.cellZones().clearAddressing();
718 procMesh.cellZones().setSize(zoneCells.size());
721 procMesh.cellZones().set
726 zoneCells[zonei].shrink(),
746 const auto* pMeshPtr =
747 thisDb().cfindObject<pointMesh>(pointMesh::typeName);
750 const auto& pMesh = *pMeshPtr;
751 const auto& pMeshBoundary = pMesh.boundary();
758 pointBoundaryMesh& procBoundary =
759 const_cast<pointBoundaryMesh&
>(procPointMesh.boundary());
763 bool differsFromPoly =
false;
766 forAll(pMeshBoundary, patchi)
768 const auto* mppPtr = isA<meshPointPatch>(pMeshBoundary[patchi]);
769 if (mppPtr && (procBoundary.findPatchID(mppPtr->name()) == -1))
771 const auto& mpp = *mppPtr;
773 DynamicList<label> procMeshPoints(mpp.size());
774 DynamicField<vector> procNormals(mpp.size());
775 forAll(mpp.meshPoints(), i)
777 const label pointi = mpp.meshPoints()[i];
778 const label procPointi = pointLookup[pointi];
779 if (procPointi != -1)
781 procMeshPoints.append(procPointi);
782 procNormals.append(mpp.pointNormals()[i]);
786 procBoundary.push_back
795 meshPointPatch::typeName
798 differsFromPoly =
true;
805 forAll(procBoundary, patchi)
807 if (!isA<processorPointPatch>(procBoundary[patchi]))
809 oldToNew[patchi] = newPatchi;
811 if (newPatchi != patchi)
813 differsFromPoly =
true;
822 boundaryProcAddressing.setSize(procBoundary.size(), -1);
824 forAll(procBoundary, patchi)
826 if (isA<processorPointPatch>(procBoundary[patchi]))
828 oldToNew[patchi] = newPatchi++;
831 procBoundary.reorder(oldToNew,
true);
837 procBoundary.write();
842 "boundaryProcAddressing",
843 procMesh.facesInstance(),
845 procPointMesh.thisDb()
852 if (facesInstancePointsPtr_)
866 std::move(procPoints)
868 pointsInstancePoints.write();
877 const cellSet& cs = cellSets[i];
878 cellSet
set(procMesh, cs.name(), cs.size()/nProcs_);
881 if (cs.found(curCellLabels[i]))
890 const faceSet& cs = faceSets[i];
891 faceSet
set(procMesh, cs.name(), cs.size()/nProcs_);
894 if (cs.found(
mag(curFaceLabels[i])-1))
903 const pointSet& cs = pointSets[i];
904 pointSet
set(procMesh, cs.name(), cs.size()/nProcs_);
907 if (cs.found(curPointLabels[i]))
931 procCellAddressing_[proci],
932 procPointAddressing_[proci]
937 Info<<
nl <<
"Processor " << proci;
939 if (procMesh.nCells())
948 Info<<
"Number of cells = " << procMesh.nCells() <<
nl;
950 if (procMesh.nCells())
952 Info<<
" Number of points = " << procMesh.nPoints() <<
nl;
955 maxProcCells =
max(maxProcCells, procMesh.nCells());
957 label nBoundaryFaces = 0;
959 label nProcFaces = 0;
961 for (
const polyPatch&
pp : procMesh.boundaryMesh())
963 const auto* cpp = isA<processorPolyPatch>(
pp);
967 const auto& procPatch = *cpp;
969 Info<<
" Number of faces shared with processor " 970 << procPatch.neighbProcNo() <<
" = " 971 << procPatch.size() <<
nl;
973 nProcFaces += procPatch.size();
978 nBoundaryFaces +=
pp.size();
982 if (procMesh.nCells() && (nBoundaryFaces || nProcFaces))
985 <<
" Number of processor faces = " << nProcFaces <<
nl 986 <<
" Number of boundary faces = " << nBoundaryFaces <<
nl;
989 totProcFaces += nProcFaces;
991 maxProcFaces =
max(maxProcFaces, nProcFaces);
999 procMesh.facesInstance(),
1008 ioAddr.rename(
"pointProcAddressing");
1012 ioAddr.rename(
"faceProcAddressing");
1016 ioAddr.rename(
"cellProcAddressing");
1021 label nMeshPatches = curPatchSizes.size();
1023 procBoundaryAddr.resize(nMeshPatches+
nProcPatches, -1);
1026 ioAddr.rename(
"boundaryProcAddressing");
1033 <<
"Number of processor faces = " << (totProcFaces/2) <<
nl 1034 <<
"Max number of cells = " << maxProcCells;
1036 if (maxProcCells != nCells())
1038 scalar avgValue = scalar(nCells())/nProcs_;
1040 Info<<
" (" << 100.0*(maxProcCells-avgValue)/avgValue
1041 <<
"% above average " << avgValue <<
')';
1045 Info<<
"Max number of processor patches = " << maxProcPatches;
1048 scalar avgValue = scalar(totProcPatches)/nProcs_;
1050 Info<<
" (" << 100.0*(maxProcPatches-avgValue)/avgValue
1051 <<
"% above average " << avgValue <<
')';
1055 Info<<
"Max number of faces between processors = " << maxProcFaces;
1058 scalar avgValue = scalar(totProcFaces)/nProcs_;
1060 Info<<
" (" << 100.0*(maxProcFaces-avgValue)/avgValue
1061 <<
"% above average " << avgValue <<
')';
bool writeDecomposition(const bool decomposeSets)
Write decomposition.
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with faceZone content on a polyMesh.
List< cell > cellList
List of cell.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
const word & name() const noexcept
Return the object name.
vectorIOField pointIOField
pointIOField is a vectorIOField.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
static FOAM_NO_DANGLING_REFERENCE const pointMesh & New(const polyMesh &mesh, Args &&... args)
Get existing or create MeshObject registered with typeName.
constexpr char nl
The newline '\n' character (0x0a)
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh")
Ostream & endl(Ostream &os)
Add newline and flush stream.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
Ignore writing from objectRegistry::writeObject()
static void writeContents(const IOobject &io, const UList< T > &content)
Write contents. The IOobject is never registered.
List< labelList > labelListList
List of labelList.
#define forAll(list, i)
Loop across all elements in list.
List< face > faceList
List of faces.
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
PtrList< polyPatch > polyPatchList
Store lists of polyPatch as a PtrList.
vectorField pointField
pointField is a vectorField.
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Reading is optional [identical to LAZY_READ].
ZoneMesh< pointZone, polyMesh > pointZoneMesh
A ZoneMesh with pointZone content on a polyMesh.
MeshObject wrapper of decompositionMethod.
static unsigned int minPrecision(unsigned int prec) noexcept
Set the minimum default precision.
static word controlDictName
The default control dictionary name (normally "controlDict")
void updateParameters(const dictionary ¶ms)
Update flags based on the decomposition model settings.
static const decompositionModel & New(const polyMesh &mesh, const fileName &decompDictFile="", const dictionary *fallback=nullptr)
Read and register on mesh, optionally with alternative decomposeParDict path/name or with fallback co...
static word meshSubDir
Return the mesh sub-directory name (usually "pointMesh")
decomposeUsingBbs false
Use bounding boxes (default) or unique decomposition of triangles (i.e. do not duplicate triangles) ...
Automatically write from objectRegistry::writeObject()
messageStream Info
Information stream (stdout output on master, null elsewhere)
List< label > labelList
A List of labels.
domainDecomposition(const IOobject &io, const fileName &decompDictFile="")
Construct from components.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
const decompositionModel & model() const
Return decomposition model used.
void setSize(label n)
Alias for resize()
Do not request registration (bool: false)
ZoneMesh< cellZone, polyMesh > cellZoneMesh
A ZoneMesh with cellZone content on a polyMesh.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...