1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | foam-extend: Open Source CFD
4 \\ / O peration | Version: 3.2
5 \\ / A nd | Web: http://www.foam-extend.org
6 \\/ M anipulation | For copyright notice see file Copyright
7 -------------------------------------------------------------------------------
9 This file is part of foam-extend.
11 foam-extend is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by the
13 Free Software Foundation, either version 3 of the License, or (at your
14 option) any later version.
16 foam-extend is distributed in the hope that it will be useful, but
17 WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "faMeshDecomposition.H"
28 #include "dictionary.H"
29 #include "labelIOList.H"
30 #include "processorFaPatch.H"
32 #include "OSspecific.H"
34 #include "globalMeshData.H"
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 void faMeshDecomposition::distributeFaces()
41 Info<< "\nCalculating distribution of faces" << endl;
43 cpuTime decompositionTime;
45 for (label procI = 0; procI < nProcs(); procI++)
49 Time::controlDictName,
51 time().caseName()/fileName(word("processor") + Foam::name(procI))
58 fvMesh::defaultRegion,
59 processorDb.timeName(),
64 labelHashSet faceProcAddressingHash
80 forAll (faceLabels(), faceI)
82 if (faceProcAddressingHash.found(faceLabels()[faceI] + 1))
84 faceToProc_[faceI] = procI;
89 Info<< "\nFinished decomposition in "
90 << decompositionTime.elapsedCpuTime()
94 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
97 faMeshDecomposition::faMeshDecomposition(const fvMesh& mesh)
111 nProcs_(readInt(decompositionDict_.lookup("numberOfSubdomains"))),
113 faceToProc_(nFaces()),
114 procFaceLabels_(nProcs_),
115 procMeshEdgesMap_(nProcs_),
116 procNInternalEdges_(nProcs_, 0),
117 procPatchEdgeLabels_(nProcs_),
118 procPatchPointAddressing_(nProcs_),
119 procPatchEdgeAddressing_(nProcs_),
120 procEdgeAddressing_(nProcs_),
121 procFaceAddressing_(nProcs_),
122 procBoundaryAddressing_(nProcs_),
123 procPatchSize_(nProcs_),
124 procPatchStartIndex_(nProcs_),
125 procNeighbourProcessors_(nProcs_),
126 procProcessorPatchSize_(nProcs_),
127 procProcessorPatchStartIndex_(nProcs_),
128 globallySharedPoints_(0),
129 cyclicParallel_(false)
131 if (decompositionDict_.found("distributed"))
133 distributed_ = Switch(decompositionDict_.lookup("distributed"));
138 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
140 faMeshDecomposition::~faMeshDecomposition()
144 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
146 void faMeshDecomposition::decomposeMesh(const bool filterEmptyPatches)
148 // Decide which cell goes to which processor
151 Info<< "\nDistributing faces to processors" << endl;
155 List<SLList<label> > procFaceList(nProcs());
157 forAll (faceToProc_, faceI)
159 if (faceToProc_[faceI] >= nProcs())
161 FatalErrorIn("Finite area mesh decomposition")
162 << "Impossible processor label " << faceToProc_[faceI]
163 << "for face " << faceI
164 << abort(FatalError);
168 procFaceList[faceToProc_[faceI]].append(faceI);
172 // Convert linked lists into normal lists
173 forAll (procFaceList, procI)
175 procFaceAddressing_[procI] = procFaceList[procI];
180 // Find processor mesh faceLabels and ...
182 for (label procI = 0; procI < nProcs(); procI++)
186 Time::controlDictName,
188 time().caseName()/fileName(word("processor") + Foam::name(procI))
195 fvMesh::defaultRegion,
196 processorDb.timeName(),
201 labelIOList fvPointProcAddressing
205 "pointProcAddressing",
207 procFvMesh.meshSubDir,
214 HashTable<label, label, Hash<label> > fvFaceProcAddressingHash;
217 labelIOList fvFaceProcAddressing
221 "faceProcAddressing",
223 procFvMesh.meshSubDir,
230 forAll(fvFaceProcAddressing, faceI)
232 fvFaceProcAddressingHash.insert
234 fvFaceProcAddressing[faceI], faceI
239 const labelList& curProcFaceAddressing = procFaceAddressing_[procI];
241 labelList& curFaceLabels = procFaceLabels_[procI];
243 curFaceLabels = labelList(curProcFaceAddressing.size(), -1);
245 forAll(curProcFaceAddressing, faceI)
247 curFaceLabels[faceI] =
248 fvFaceProcAddressingHash.find
250 faceLabels()[curProcFaceAddressing[faceI]] + 1
254 // create processor finite area mesh
258 procFaceLabels_[procI]
261 const indirectPrimitivePatch& patch = this->patch();
262 const Map<label>& map = patch.meshPointMap();
264 HashTable<label, edge, Hash<edge> > edgesHash;
268 label nIntEdges = patch.nInternalEdges();
270 for (label curEdge = 0; curEdge < nIntEdges; curEdge++)
272 edgesHash.insert(patch.edges()[curEdge], ++edgeI);
275 forAll (boundary(), patchI)
277 // Include emptyFaPatch
279 label size = boundary()[patchI].labelList::size();
281 for(int eI=0; eI<size; eI++)
283 edgesHash.insert(patch.edges()[boundary()[patchI][eI]], ++edgeI);
288 const indirectPrimitivePatch& procPatch = procMesh.patch();
289 const vectorField& procPoints = procPatch.localPoints();
290 const labelList& procMeshPoints = procPatch.meshPoints();
291 const edgeList& procEdges = procPatch.edges();
293 labelList& curPatchPointAddressing = procPatchPointAddressing_[procI];
294 curPatchPointAddressing.setSize(procPoints.size(), -1);
296 forAll(procPoints, pointI)
298 curPatchPointAddressing[pointI] =
299 map[fvPointProcAddressing[procMeshPoints[pointI]]];
302 labelList& curPatchEdgeAddressing = procPatchEdgeAddressing_[procI];
303 curPatchEdgeAddressing.setSize(procEdges.size(), -1);
305 forAll(procEdges, edgeI)
307 edge curGlobalEdge = procEdges[edgeI];
308 curGlobalEdge[0] = curPatchPointAddressing[curGlobalEdge[0]];
309 curGlobalEdge[1] = curPatchPointAddressing[curGlobalEdge[1]];
311 curPatchEdgeAddressing[edgeI] = edgesHash.find(curGlobalEdge)();
314 Map<label>& curMap = procMeshEdgesMap_[procI];
316 curMap = Map<label>(2*procEdges.size());
318 forAll(curPatchEdgeAddressing, edgeI)
320 curMap.insert(curPatchEdgeAddressing[edgeI], edgeI);
323 procNInternalEdges_[procI] = procPatch.nInternalEdges();
327 Info << "\nDistributing edges to processors" << endl;
329 // Loop through all internal edges and decide which processor they
330 // belong to. First visit all internal edges.
332 // set references to the original mesh
333 const faBoundaryMesh& patches = boundary();
334 const edgeList& edges = this->edges();
335 const labelList& owner = edgeOwner();
336 const labelList& neighbour = edgeNeighbour();
340 List<SLList<label> > procEdgeList(nProcs());
342 forAll(procEdgeList, procI)
344 for(label i=0; i<procNInternalEdges_[procI]; i++)
346 procEdgeList[procI].append(procPatchEdgeAddressing_[procI][i]);
351 // Detect inter-processor boundaries
353 // Neighbour processor for each subdomain
354 List<SLList<label> > interProcBoundaries(nProcs());
356 // Edge labels belonging to each inter-processor boundary
357 List<SLList<SLList<label> > > interProcBEdges(nProcs());
359 List<SLList<label> > procPatchIndex(nProcs());
361 forAll (neighbour, edgeI)
363 if (faceToProc_[owner[edgeI]] != faceToProc_[neighbour[edgeI]])
365 // inter - processor patch edge found. Go through the list of
366 // inside boundaries for the owner processor and try to find
367 // this inter-processor patch.
369 label ownerProc = faceToProc_[owner[edgeI]];
370 label neighbourProc = faceToProc_[neighbour[edgeI]];
372 SLList<label>::iterator curInterProcBdrsOwnIter =
373 interProcBoundaries[ownerProc].begin();
375 SLList<SLList<label> >::iterator curInterProcBEdgesOwnIter =
376 interProcBEdges[ownerProc].begin();
378 bool interProcBouFound = false;
380 // WARNING: Synchronous SLList iterators
385 curInterProcBdrsOwnIter
386 != interProcBoundaries[ownerProc].end()
387 && curInterProcBEdgesOwnIter
388 != interProcBEdges[ownerProc].end();
389 ++curInterProcBdrsOwnIter, ++curInterProcBEdgesOwnIter
392 if (curInterProcBdrsOwnIter() == neighbourProc)
394 // the inter - processor boundary exists. Add the face
395 interProcBouFound = true;
397 curInterProcBEdgesOwnIter().append(edgeI);
399 SLList<label>::iterator curInterProcBdrsNeiIter =
400 interProcBoundaries[neighbourProc].begin();
402 SLList<SLList<label> >::iterator
403 curInterProcBEdgesNeiIter =
404 interProcBEdges[neighbourProc].begin();
406 bool neighbourFound = false;
408 // WARNING: Synchronous SLList iterators
413 curInterProcBdrsNeiIter !=
414 interProcBoundaries[neighbourProc].end()
415 && curInterProcBEdgesNeiIter !=
416 interProcBEdges[neighbourProc].end();
417 ++curInterProcBdrsNeiIter,
418 ++curInterProcBEdgesNeiIter
421 if (curInterProcBdrsNeiIter() == ownerProc)
423 // boundary found. Add the face
424 neighbourFound = true;
426 curInterProcBEdgesNeiIter().append(edgeI);
429 if (neighbourFound) break;
432 if (interProcBouFound && !neighbourFound)
435 ("faDomainDecomposition::decomposeMesh()")
436 << "Inconsistency in inter - "
437 << "processor boundary lists for processors "
438 << ownerProc << " and " << neighbourProc
439 << abort(FatalError);
443 if (interProcBouFound) break;
446 if (!interProcBouFound)
448 // inter - processor boundaries do not exist and need to
451 // set the new addressing information
454 interProcBoundaries[ownerProc].append(neighbourProc);
455 interProcBEdges[ownerProc].append(SLList<label>(edgeI));
458 interProcBoundaries[neighbourProc].append(ownerProc);
459 interProcBEdges[neighbourProc].append
468 // Loop through patches. For cyclic boundaries detect inter-processor
469 // edges; for all other, add edges to the edge list and remember start
470 // and size of all patches.
472 // for all processors, set the size of start index and patch size
473 // lists to the number of patches in the mesh
474 forAll (procPatchSize_, procI)
476 procPatchSize_[procI].setSize(patches.size());
477 procPatchStartIndex_[procI].setSize(patches.size());
480 forAll (patches, patchI)
482 // Reset size and start index for all processors
483 forAll (procPatchSize_, procI)
485 procPatchSize_[procI][patchI] = 0;
486 procPatchStartIndex_[procI][patchI] =
487 procEdgeList[procI].size();
490 const label patchStart = patches[patchI].start();
492 // if (typeid(patches[patchI]) != typeid(cyclicFaPatch))
495 // Normal patch. Add edges to processor where the face
496 // next to the edge lives
498 const labelListList& eF = patch().edgeFaces();
500 label size = patches[patchI].labelList::size();
502 labelList patchEdgeFaces(size, -1);
504 for(int eI=0; eI<size; eI++)
506 patchEdgeFaces[eI] = eF[patches[patchI][eI]][0];
509 forAll (patchEdgeFaces, edgeI)
511 const label curProc = faceToProc_[patchEdgeFaces[edgeI]];
514 procEdgeList[curProc].append(patchStart + edgeI);
516 // increment the number of edges for this patch
517 procPatchSize_[curProc][patchI]++;
522 // Cyclic patch special treatment
524 const faPatch& cPatch = patches[patchI];
526 const label cycOffset = cPatch.size()/2;
528 // Set reference to faceCells for both patches
529 const labelList::subList firstEdgeFaces
535 const labelList::subList secondEdgeFaces
542 forAll (firstEdgeFaces, edgeI)
546 faceToProc_[firstEdgeFaces[edgeI]]
547 != faceToProc_[secondEdgeFaces[edgeI]]
550 // This edge becomes an inter-processor boundary edge
551 // inter - processor patch edge found. Go through
552 // the list of inside boundaries for the owner
553 // processor and try to find this inter-processor
556 cyclicParallel_ = true;
558 label ownerProc = faceToProc_[firstEdgeFaces[edgeI]];
559 label neighbourProc =
560 faceToProc_[secondEdgeFaces[edgeI]];
562 SLList<label>::iterator curInterProcBdrsOwnIter =
563 interProcBoundaries[ownerProc].begin();
565 SLList<SLList<label> >::iterator
566 curInterProcBEdgesOwnIter =
567 interProcBEdges[ownerProc].begin();
569 bool interProcBouFound = false;
571 // WARNING: Synchronous SLList iterators
576 curInterProcBdrsOwnIter !=
577 interProcBoundaries[ownerProc].end()
578 && curInterProcBEdgesOwnIter !=
579 interProcBEdges[ownerProc].end();
580 ++curInterProcBdrsOwnIter,
581 ++curInterProcBEdgesOwnIter
584 if (curInterProcBdrsOwnIter() == neighbourProc)
586 // the inter - processor boundary exists.
588 interProcBouFound = true;
590 curInterProcBEdgesOwnIter().append
591 (patchStart + edgeI);
593 SLList<label>::iterator curInterProcBdrsNeiIter
594 = interProcBoundaries[neighbourProc].begin();
596 SLList<SLList<label> >::iterator
597 curInterProcBEdgesNeiIter =
598 interProcBEdges[neighbourProc].begin();
600 bool neighbourFound = false;
602 // WARNING: Synchronous SLList iterators
607 curInterProcBdrsNeiIter
608 != interProcBoundaries[neighbourProc].end()
609 && curInterProcBEdgesNeiIter
610 != interProcBEdges[neighbourProc].end();
611 ++curInterProcBdrsNeiIter,
612 ++curInterProcBEdgesNeiIter
615 if (curInterProcBdrsNeiIter() == ownerProc)
617 // boundary found. Add the face
618 neighbourFound = true;
620 curInterProcBEdgesNeiIter()
629 if (neighbourFound) break;
632 if (interProcBouFound && !neighbourFound)
636 "faDomainDecomposition::decomposeMesh()"
637 ) << "Inconsistency in inter-processor "
638 << "boundary lists for processors "
639 << ownerProc << " and " << neighbourProc
640 << " in cyclic boundary matching"
641 << abort(FatalError);
645 if (interProcBouFound) break;
648 if (!interProcBouFound)
650 // inter - processor boundaries do not exist
651 // and need to be created
653 // set the new addressing information
656 interProcBoundaries[ownerProc]
657 .append(neighbourProc);
658 interProcBEdges[ownerProc]
659 .append(SLList<label>(patchStart + edgeI));
662 interProcBoundaries[neighbourProc]
664 interProcBEdges[neighbourProc]
678 // This cyclic edge remains on the processor
679 label ownerProc = faceToProc_[firstEdgeFaces[edgeI]];
682 procEdgeList[ownerProc].append(patchStart + edgeI);
684 // increment the number of edges for this patch
685 procPatchSize_[ownerProc][patchI]++;
687 // Note: I cannot add the other side of the cyclic
688 // boundary here because this would violate the order.
689 // They will be added in a separate loop below
693 // Ordering in cyclic boundaries is important.
694 // Add the other half of cyclic edges for cyclic boundaries
695 // that remain on the processor
696 forAll (secondEdgeFaces, edgeI)
700 faceToProc_[firstEdgeFaces[edgeI]]
701 == faceToProc_[secondEdgeFaces[edgeI]]
704 // This cyclic edge remains on the processor
705 label ownerProc = faceToProc_[firstEdgeFaces[edgeI]];
707 // add the second edge
708 procEdgeList[ownerProc].append
709 (patchStart + cycOffset + edgeI);
711 // increment the number of edges for this patch
712 procPatchSize_[ownerProc][patchI]++;
718 // Convert linked lists into normal lists
719 // Add inter-processor boundaries and remember start indices
720 forAll (procEdgeList, procI)
722 // Get internal and regular boundary processor faces
723 SLList<label>& curProcEdges = procEdgeList[procI];
725 // Get reference to processor edge addressing
726 labelList& curProcEdgeAddressing = procEdgeAddressing_[procI];
728 labelList& curProcNeighbourProcessors =
729 procNeighbourProcessors_[procI];
731 labelList& curProcProcessorPatchSize =
732 procProcessorPatchSize_[procI];
734 labelList& curProcProcessorPatchStartIndex =
735 procProcessorPatchStartIndex_[procI];
737 // calculate the size
738 label nEdgesOnProcessor = curProcEdges.size();
742 SLList<SLList<label> >::iterator curInterProcBEdgesIter =
743 interProcBEdges[procI].begin();
744 curInterProcBEdgesIter != interProcBEdges[procI].end();
745 ++curInterProcBEdgesIter
748 nEdgesOnProcessor += curInterProcBEdgesIter().size();
751 curProcEdgeAddressing.setSize(nEdgesOnProcessor);
753 // Fill in the list. Calculate turning index.
754 // Turning index will be -1 only for some edges on processor
755 // boundaries, i.e. the ones where the current processor ID
756 // is in the face which is a edge neighbour.
757 // Turning index is stored as the sign of the edge addressing list
761 // Add internal and boundary edges
762 // Remember to increment the index by one such that the
763 // turning index works properly.
766 SLList<label>::iterator curProcEdgeIter = curProcEdges.begin();
767 curProcEdgeIter != curProcEdges.end();
771 curProcEdgeAddressing[nEdges] = curProcEdgeIter();
772 // curProcEdgeAddressing[nEdges] = curProcEdgeIter() + 1;
776 // Add inter-processor boundary edges. At the beginning of each
777 // patch, grab the patch start index and size
779 curProcNeighbourProcessors.setSize
781 interProcBoundaries[procI].size()
784 curProcProcessorPatchSize.setSize
786 interProcBoundaries[procI].size()
789 curProcProcessorPatchStartIndex.setSize
791 interProcBoundaries[procI].size()
794 label nProcPatches = 0;
796 SLList<label>::iterator curInterProcBdrsIter =
797 interProcBoundaries[procI].begin();
799 SLList<SLList<label> >::iterator curInterProcBEdgesIter =
800 interProcBEdges[procI].begin();
805 curInterProcBdrsIter != interProcBoundaries[procI].end()
806 && curInterProcBEdgesIter != interProcBEdges[procI].end();
807 ++curInterProcBdrsIter, ++curInterProcBEdgesIter
810 curProcNeighbourProcessors[nProcPatches] =
811 curInterProcBdrsIter();
813 // Get start index for processor patch
814 curProcProcessorPatchStartIndex[nProcPatches] = nEdges;
817 curProcProcessorPatchSize[nProcPatches];
821 // add faces for this processor boundary
825 SLList<label>::iterator curEdgesIter =
826 curInterProcBEdgesIter().begin();
827 curEdgesIter != curInterProcBEdgesIter().end();
833 // Remember to increment the index by one such that the
834 // turning index works properly.
835 if (faceToProc_[owner[curEdgesIter()]] == procI)
837 curProcEdgeAddressing[nEdges] = curEdgesIter();
838 // curProcEdgeAddressing[nEdges] = curEdgesIter() + 1;
843 curProcEdgeAddressing[nEdges] = curEdgesIter();
844 // curProcEdgeAddressing[nEdges] = -(curEdgesIter() + 1);
847 // increment the size
858 Info << "\nCalculating processor boundary addressing" << endl;
859 // For every patch of processor boundary, find the index of the original
860 // patch. Mis-alignment is caused by the fact that patches with zero size
861 // are omitted. For processor patches, set index to -1.
862 // At the same time, filter the procPatchSize_ and procPatchStartIndex_
863 // lists to exclude zero-size patches
864 forAll (procPatchSize_, procI)
866 // Make a local copy of old lists
867 const labelList oldPatchSizes = procPatchSize_[procI];
869 const labelList oldPatchStarts = procPatchStartIndex_[procI];
871 labelList& curPatchSizes = procPatchSize_[procI];
873 labelList& curPatchStarts = procPatchStartIndex_[procI];
875 const labelList& curProcessorPatchSizes =
876 procProcessorPatchSize_[procI];
878 labelList& curBoundaryAddressing = procBoundaryAddressing_[procI];
880 curBoundaryAddressing.setSize
883 + curProcessorPatchSizes.size()
888 forAll (oldPatchSizes, patchI)
890 if (!filterEmptyPatches || oldPatchSizes[patchI] > 0)
892 curBoundaryAddressing[nPatches] = patchI;
894 curPatchSizes[nPatches] = oldPatchSizes[patchI];
896 curPatchStarts[nPatches] = oldPatchStarts[patchI];
902 // reset to the size of live patches
903 curPatchSizes.setSize(nPatches);
904 curPatchStarts.setSize(nPatches);
906 forAll (curProcessorPatchSizes, procPatchI)
908 curBoundaryAddressing[nPatches] = -1;
913 curBoundaryAddressing.setSize(nPatches);
917 // Gather data about globally shared points
919 labelList globallySharedPoints_(0);
923 labelList pointsUsage(nPoints(), 0);
925 // Globally shared points are the ones used by more than 2 processors
926 // Size the list approximately and gather the points
927 labelHashSet gSharedPoints
929 min(100, nPoints()/1000)
932 // Loop through all the processors and mark up points used by
933 // processor boundaries. When a point is used twice, it is a
934 // globally shared point
936 for (label procI = 0; procI < nProcs(); procI++)
938 // Get list of edge labels
939 const labelList& curEdgeLabels = procEdgeAddressing_[procI];
941 // Get start of processor faces
942 const labelList& curProcessorPatchStarts =
943 procProcessorPatchStartIndex_[procI];
945 const labelList& curProcessorPatchSizes =
946 procProcessorPatchSize_[procI];
948 // Reset the lookup list
951 forAll (curProcessorPatchStarts, patchI)
953 const label curStart = curProcessorPatchStarts[patchI];
954 const label curEnd = curStart + curProcessorPatchSizes[patchI];
958 label edgeI = curStart;
963 // Mark the original edge as used
964 // Remember to decrement the index by one (turning index)
965 const label curE = curEdgeLabels[edgeI];
967 const edge& e = edges[curE];
971 if (pointsUsage[e[pointI]] == 0)
973 // Point not previously used
974 pointsUsage[e[pointI]] = patchI + 1;
976 else if (pointsUsage[e[pointI]] != patchI + 1)
978 // Point used by some other patch = global point!
979 gSharedPoints.insert(e[pointI]);
986 // Grab the result from the hash list
987 globallySharedPoints_ = gSharedPoints.toc();
988 sort(globallySharedPoints_);
992 // Edge label for faPatches
994 for (label procI = 0; procI < nProcs(); procI++)
996 fileName processorCasePath
998 time().caseName()/fileName(word("processor")
1002 // create a database
1005 Time::controlDictName,
1011 // read finite volume mesh
1016 fvMesh::defaultRegion,
1017 processorDb.timeName(),
1022 // create finite area mesh
1026 procFaceLabels_[procI]
1030 const labelList& curEdgeAddressing = procEdgeAddressing_[procI];
1032 const labelList& curPatchStartIndex = procPatchStartIndex_[procI];
1033 const labelList& curPatchSize = procPatchSize_[procI];
1035 const labelList& curProcessorPatchStartIndex =
1036 procProcessorPatchStartIndex_[procI];
1038 const labelList& curProcessorPatchSize =
1039 procProcessorPatchSize_[procI];
1041 labelListList& curPatchEdgeLabels = procPatchEdgeLabels_[procI];
1042 curPatchEdgeLabels =
1046 + curProcessorPatchSize.size()
1049 forAll(curPatchSize, patchI)
1051 labelList& curEdgeLabels = curPatchEdgeLabels[patchI];
1052 curEdgeLabels.setSize(curPatchSize[patchI], -1);
1058 int i=curPatchStartIndex[patchI];
1059 i<(curPatchStartIndex[patchI]+curPatchSize[patchI]);
1063 curEdgeLabels[edgeI] =
1064 procMeshEdgesMap_[procI][curEdgeAddressing[i]];
1069 forAll(curProcessorPatchSize, patchI)
1071 labelList& curEdgeLabels =
1072 curPatchEdgeLabels[curPatchSize.size() + patchI];
1073 curEdgeLabels.setSize(curProcessorPatchSize[patchI], -1);
1079 int i=curProcessorPatchStartIndex[patchI];
1080 i<(curProcessorPatchStartIndex[patchI]
1081 +curProcessorPatchSize[patchI]);
1085 curEdgeLabels[edgeI] =
1086 procMeshEdgesMap_[procI][curEdgeAddressing[i]];
1094 bool faMeshDecomposition::writeDecomposition()
1096 Info<< "\nConstructing processor FA meshes" << endl;
1099 // Make a lookup map for globally shared points
1100 Map<label> sharedPointLookup(2*globallySharedPoints_.size());
1102 forAll (globallySharedPoints_, pointi)
1104 sharedPointLookup.insert(globallySharedPoints_[pointi], pointi);
1107 label totProcEdges = 0;
1108 label maxProcPatches = 0;
1109 label maxProcEdges = 0;
1111 // Write out the meshes
1112 for (label procI = 0; procI < nProcs(); procI++)
1114 // Create processor mesh without a boundary
1116 fileName processorCasePath
1118 time().caseName()/fileName(word("processor") + Foam::name(procI))
1121 // create a database
1124 Time::controlDictName,
1129 // read finite volume mesh
1134 fvMesh::defaultRegion,
1135 processorDb.timeName(),
1140 labelIOList fvBoundaryProcAddressing
1144 "boundaryProcAddressing",
1146 procFvMesh.meshSubDir,
1148 IOobject::MUST_READ,
1154 // create finite area mesh
1158 procFaceLabels_[procI]
1161 // Create processor boundary patches
1162 const labelList& curBoundaryAddressing =
1163 procBoundaryAddressing_[procI];
1165 const labelList& curPatchSizes = procPatchSize_[procI];
1167 const labelList& curNeighbourProcessors =
1168 procNeighbourProcessors_[procI];
1170 const labelList& curProcessorPatchSizes =
1171 procProcessorPatchSize_[procI];
1173 const labelListList& curPatchEdgeLabels =
1174 procPatchEdgeLabels_[procI];
1176 const faPatchList& meshPatches = boundary();
1178 List<faPatch*> procPatches
1180 curPatchSizes.size()
1181 + curProcessorPatchSizes.size(),
1182 reinterpret_cast<faPatch*>(NULL)
1187 forAll (curPatchSizes, patchi)
1189 const labelList& curEdgeLabels = curPatchEdgeLabels[nPatches];
1191 label ngbPolyPatchIndex =
1194 fvBoundaryProcAddressing,
1195 meshPatches[curBoundaryAddressing[patchi]]
1196 .ngbPolyPatchIndex()
1199 procPatches[nPatches] =
1200 meshPatches[curBoundaryAddressing[patchi]].clone
1202 procMesh.boundary(),
1211 forAll (curProcessorPatchSizes, procPatchI)
1213 const labelList& curEdgeLabels = curPatchEdgeLabels[nPatches];
1215 procPatches[nPatches] =
1216 new processorFaPatch
1218 word("procBoundary") + Foam::name(procI)
1220 + Foam::name(curNeighbourProcessors[procPatchI]),
1223 procMesh.boundary(),
1226 curNeighbourProcessors[procPatchI]
1232 // Add boundary patches
1233 procMesh.addFaPatches(procPatches);
1235 // Set the precision of the points data to 10
1236 IOstream::defaultPrecision(10);
1241 << "Processor " << procI << nl
1242 << " Number of faces = " << procMesh.nFaces()
1245 label nBoundaryEdges = 0;
1246 label nProcPatches = 0;
1247 label nProcEdges = 0;
1249 forAll (procMesh.boundary(), patchi)
1253 procMesh.boundary()[patchi].type()
1254 == processorFaPatch::typeName
1257 const processorFaPatch& ppp =
1258 refCast<const processorFaPatch>
1260 procMesh.boundary()[patchi]
1263 Info<< " Number of edges shared with processor "
1264 << ppp.neighbProcNo() << " = " << ppp.size() << endl;
1267 nProcEdges += ppp.size();
1271 nBoundaryEdges += procMesh.boundary()[patchi].size();
1275 Info<< " Number of processor patches = " << nProcPatches << nl
1276 << " Number of processor edges = " << nProcEdges << nl
1277 << " Number of boundary edges = " << nBoundaryEdges << endl;
1279 totProcEdges += nProcEdges;
1280 maxProcPatches = max(maxProcPatches, nProcPatches);
1281 maxProcEdges = max(maxProcEdges, nProcEdges);
1283 // create and write the addressing information
1284 labelIOList pointProcAddressing
1288 "pointProcAddressing",
1290 procMesh.meshSubDir,
1295 procPatchPointAddressing_[procI]
1297 pointProcAddressing.write();
1299 labelIOList edgeProcAddressing
1303 "edgeProcAddressing",
1305 procMesh.meshSubDir,
1310 procEdgeAddressing_[procI]
1312 edgeProcAddressing.write();
1314 labelIOList faceProcAddressing
1318 "faceProcAddressing",
1320 procMesh.meshSubDir,
1325 procFaceAddressing_[procI]
1327 faceProcAddressing.write();
1329 labelIOList boundaryProcAddressing
1333 "boundaryProcAddressing",
1335 procMesh.meshSubDir,
1340 procBoundaryAddressing_[procI]
1342 boundaryProcAddressing.write();
1346 << "Number of processor edges = " << totProcEdges/2 << nl
1347 << "Max number of processor patches = " << maxProcPatches << nl
1348 << "Max number of faces between processors = " << maxProcEdges