1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM 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 2 of the License, or (at your
14 option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM; if not, write to the Free Software Foundation,
23 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 \*---------------------------------------------------------------------------*/
27 #include "globalPoints.H"
28 #include "processorPolyPatch.H"
29 #include "cyclicPolyPatch.H"
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 defineTypeNameAndDebug(Foam::globalPoints, 0);
37 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 // Total number of points on processor patches. Is upper limit for number
41 Foam::label Foam::globalPoints::countPatchPoints
43 const polyBoundaryMesh& patches
48 forAll(patches, patchI)
50 const polyPatch& pp = patches[patchI];
54 (Pstream::parRun() && isA<processorPolyPatch>(pp))
55 || isA<cyclicPolyPatch>(pp)
58 nTotPoints += pp.nPoints();
66 // Collect all topological information about a point on a patch.
67 // (this information is the patch faces using the point and the relative
68 // position of the point in the face)
69 void Foam::globalPoints::addToSend
71 const primitivePatch& pp,
72 const label patchPointI,
73 const procPointList& knownInfo,
75 DynamicList<label>& patchFaces,
76 DynamicList<label>& indexInFace,
77 DynamicList<procPointList>& allInfo
80 label meshPointI = pp.meshPoints()[patchPointI];
82 // Add all faces using the point so we are sure we find it on the
84 const labelList& pFaces = pp.pointFaces()[patchPointI];
88 label patchFaceI = pFaces[i];
90 const face& f = pp[patchFaceI];
92 patchFaces.append(patchFaceI);
93 indexInFace.append(findIndex(f, meshPointI));
94 allInfo.append(knownInfo);
99 // Add nbrInfo to myInfo. Return true if anything changed.
100 // nbrInfo is for a point a list of all the processors using it (and the
101 // meshPoint label on that processor)
102 bool Foam::globalPoints::mergeInfo
104 const procPointList& nbrInfo,
105 procPointList& myInfo
108 // Indices of entries in nbrInfo not yet in myInfo.
109 DynamicList<label> newInfo(nbrInfo.size());
113 const procPoint& info = nbrInfo[i];
115 // Check if info already in myInfo.
120 if (myInfo[j] == info)
122 // Already have information for processor/point combination
123 // in my list so skip.
132 // Mark this information as being not yet in myInfo
139 // Append all nbrInfos referenced in newInfo to myInfo.
141 label index = myInfo.size();
143 myInfo.setSize(index + newInfo.size());
147 myInfo[index++] = nbrInfo[newInfo[i]];
150 // Did anything change?
151 return newInfo.size() > 0;
155 // Updates database of current information on meshpoints with nbrInfo.
156 // Uses mergeInfo above. Returns true if data kept for meshPointI changed.
157 bool Foam::globalPoints::storeInfo
159 const procPointList& nbrInfo,
160 const label meshPointI
163 label infoChanged = false;
165 // Get the index into the procPoints list.
166 Map<label>::iterator iter = meshToProcPoint_.find(meshPointI);
168 if (iter != meshToProcPoint_.end())
170 procPointList& knownInfo = procPoints_[iter()];
172 if (mergeInfo(nbrInfo, knownInfo))
179 procPointList knownInfo(1);
180 knownInfo[0][0] = Pstream::myProcNo();
181 knownInfo[0][1] = meshPointI;
183 if (mergeInfo(nbrInfo, knownInfo))
185 // Update addressing from into procPoints
186 meshToProcPoint_.insert(meshPointI, procPoints_.size());
187 // Insert into list of equivalences.
188 procPoints_.append(knownInfo);
197 // Insert my own points into structure and mark as changed.
198 void Foam::globalPoints::initOwnPoints
200 const bool allPoints,
201 labelHashSet& changedPoints
204 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
206 forAll(patches, patchI)
208 const polyPatch& pp = patches[patchI];
212 (Pstream::parRun() && isA<processorPolyPatch>(pp))
213 || isA<cyclicPolyPatch>(pp)
216 const labelList& meshPoints = pp.meshPoints();
220 // All points on patch
221 forAll(meshPoints, i)
223 label meshPointI = meshPoints[i];
225 procPointList knownInfo(1);
226 knownInfo[0][0] = Pstream::myProcNo();
227 knownInfo[0][1] = meshPointI;
229 // Update addressing from meshpoint to index in procPoints
230 meshToProcPoint_.insert(meshPointI, procPoints_.size());
231 // Insert into list of equivalences.
232 procPoints_.append(knownInfo);
234 // Update changedpoints info.
235 changedPoints.insert(meshPointI);
240 // Boundary points only
241 const labelList& boundaryPoints = pp.boundaryPoints();
243 forAll(boundaryPoints, i)
245 label meshPointI = meshPoints[boundaryPoints[i]];
247 procPointList knownInfo(1);
248 knownInfo[0][0] = Pstream::myProcNo();
249 knownInfo[0][1] = meshPointI;
251 // Update addressing from meshpoint to index in procPoints
252 meshToProcPoint_.insert(meshPointI, procPoints_.size());
253 // Insert into list of equivalences.
254 procPoints_.append(knownInfo);
256 // Update changedpoints info.
257 changedPoints.insert(meshPointI);
265 // Send all my info on changedPoints_ to my neighbours.
266 void Foam::globalPoints::sendPatchPoints(const labelHashSet& changedPoints)
269 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
271 forAll(patches, patchI)
273 const polyPatch& pp = patches[patchI];
275 if (Pstream::parRun() && isA<processorPolyPatch>(pp))
277 // Information to send:
279 DynamicList<label> patchFaces(pp.nPoints());
280 // index in patch face
281 DynamicList<label> indexInFace(pp.nPoints());
282 // all information I currently hold about this patchPoint
283 DynamicList<procPointList> allInfo(pp.nPoints());
286 // Now collect information on all mesh points mentioned in
287 // changedPoints. Note that these points only should occur on
288 // processorPatches (or rather this is a limitation!).
290 const labelList& meshPoints = pp.meshPoints();
292 forAll(meshPoints, patchPointI)
294 label meshPointI = meshPoints[patchPointI];
296 if (changedPoints.found(meshPointI))
298 label index = meshToProcPoint_[meshPointI];
300 const procPointList& knownInfo = procPoints_[index];
302 // Add my information about meshPointI to the send buffers
316 indexInFace.shrink();
321 const processorPolyPatch& procPatch =
322 refCast<const processorPolyPatch>(pp);
326 Pout<< " Sending to "
327 << procPatch.neighbProcNo() << " point information:"
328 << patchFaces.size() << endl;
334 procPatch.neighbProcNo()
337 toNeighbour << patchFaces << indexInFace << allInfo;
344 // Receive all my neighbours' information and merge with mine.
345 // After finishing will have updated
346 // - procPoints_ : all neighbour information merged in.
347 // - meshToProcPoint_
348 // - changedPoints: all meshPoints for which something changed.
349 void Foam::globalPoints::receivePatchPoints(labelHashSet& changedPoints)
351 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
353 // Reset changed points
354 changedPoints.clear();
356 forAll(patches, patchI)
358 const polyPatch& pp = patches[patchI];
360 if (Pstream::parRun() && isA<processorPolyPatch>(pp))
362 const processorPolyPatch& procPatch =
363 refCast<const processorPolyPatch>(pp);
365 labelList patchFaces;
366 labelList indexInFace;
367 List<procPointList> nbrInfo;
370 IPstream fromNeighbour
373 procPatch.neighbProcNo()
375 fromNeighbour >> patchFaces >> indexInFace >> nbrInfo;
380 Pout<< " Received from "
381 << procPatch.neighbProcNo() << " point information:"
382 << patchFaces.size() << endl;
385 forAll(patchFaces, i)
387 const face& f = pp[patchFaces[i]];
389 // Get index in this face from index on face on other side.
390 label index = (f.size() - indexInFace[i]) % f.size();
392 // Get the meshpoint on my side
393 label meshPointI = f[index];
395 //const procPointList& info = nbrInfo[i];
396 //Pout << "Received for my coord "
397 // << mesh_.points()[meshPointI];
401 // Pout<< ' ' <<info[j];
405 if (storeInfo(nbrInfo[i], meshPointI))
407 changedPoints.insert(meshPointI);
411 else if (isA<cyclicPolyPatch>(pp))
413 // Handle cyclics: send lower half to upper half and vice versa.
414 // Or since they both are in memory just do it point by point.
416 const cyclicPolyPatch& cycPatch =
417 refCast<const cyclicPolyPatch>(pp);
419 const labelList& meshPoints = pp.meshPoints();
421 //const edgeList& connections = cycPatch.coupledPoints();
422 const edgeList connections(coupledPoints(cycPatch));
424 forAll(connections, i)
426 const edge& e = connections[i];
428 label meshPointA = meshPoints[e[0]];
429 label meshPointB = meshPoints[e[1]];
431 // Do we have information on meshPointA?
432 Map<label>::iterator procPointA =
433 meshToProcPoint_.find(meshPointA);
435 if (procPointA != meshToProcPoint_.end())
437 // Store A info onto pointB
438 if (storeInfo(procPoints_[procPointA()], meshPointB))
440 changedPoints.insert(meshPointB);
444 // Same for info on pointB
445 Map<label>::iterator procPointB =
446 meshToProcPoint_.find(meshPointB);
448 if (procPointB != meshToProcPoint_.end())
450 // Store B info onto pointA
451 if (storeInfo(procPoints_[procPointB()], meshPointA))
453 changedPoints.insert(meshPointA);
462 // Remove entries which are handled by normal face-face communication. I.e.
463 // those points where the equivalence list is only me and my (face)neighbour
464 void Foam::globalPoints::remove(const Map<label>& directNeighbours)
467 Map<label> oldMeshToProcPoint(meshToProcPoint_);
468 meshToProcPoint_.clear();
470 procPoints_.shrink();
471 List<procPointList> oldProcPoints;
472 oldProcPoints.transfer(procPoints_);
475 // Go through all equivalences
478 Map<label>::const_iterator iter = oldMeshToProcPoint.begin();
479 iter != oldMeshToProcPoint.end();
483 label meshPointI = iter.key();
484 const procPointList& pointInfo = oldProcPoints[iter()];
486 if (pointInfo.size() == 2)
488 // I will be in this equivalence list.
489 // Check whether my direct (=face) neighbour
490 // is in it. This would be an ordinary connection and can be
491 // handled by normal face-face connectivity.
493 const procPoint& a = pointInfo[0];
494 const procPoint& b = pointInfo[1];
498 (a[0] == Pstream::myProcNo() && directNeighbours.found(a[1]))
499 || (b[0] == Pstream::myProcNo() && directNeighbours.found(b[1]))
502 // Normal faceNeighbours
503 if (a[0] == Pstream::myProcNo())
505 //Pout<< "Removing direct neighbour:"
506 // << mesh_.points()[a[1]]
509 else if (b[0] == Pstream::myProcNo())
511 //Pout<< "Removing direct neighbour:"
512 // << mesh_.points()[b[1]]
518 // This condition will be very rare: points are used by
519 // two processors which are not face-face connected.
526 // Processor A and B share a point. Note that this only will
527 // be found if the two domains are face connected at all
528 // (not shown in the picture)
530 meshToProcPoint_.insert(meshPointI, procPoints_.size());
531 procPoints_.append(pointInfo);
534 else if (pointInfo.size() == 1)
536 // This happens for 'wedge' like cyclics where the two halves
537 // come together in the same point so share the same meshPoint.
538 // So this meshPoint will have info of size one only.
541 pointInfo[0][0] != Pstream::myProcNo()
542 || !directNeighbours.found(pointInfo[0][1])
545 meshToProcPoint_.insert(meshPointI, procPoints_.size());
546 procPoints_.append(pointInfo);
551 meshToProcPoint_.insert(meshPointI, procPoints_.size());
552 procPoints_.append(pointInfo);
556 procPoints_.shrink();
560 // Get (indices of) points for which I am master (= lowest numbered point on
561 // lowest numbered processor).
562 // (equivalence lists should be complete by now)
563 Foam::labelList Foam::globalPoints::getMasterPoints() const
565 labelList masterPoints(nPatchPoints_);
568 // Go through all equivalences and determine meshPoints where I am master.
571 Map<label>::const_iterator iter = meshToProcPoint_.begin();
572 iter != meshToProcPoint_.end();
576 label meshPointI = iter.key();
577 const procPointList& pointInfo = procPoints_[iter()];
579 if (pointInfo.size() < 2)
581 // Points should have an equivalence list >= 2 since otherwise
582 // they would be direct neighbours and have been removed in the
584 Pout<< "MeshPoint:" << meshPointI
585 << " coord:" << mesh_.points()[meshPointI]
586 << " has no corresponding point on a neighbouring processor"
588 FatalErrorIn("globalPoints::getMasterPoints()")
589 << '[' << Pstream::myProcNo() << ']'
590 << " MeshPoint:" << meshPointI
591 << " coord:" << mesh_.points()[meshPointI]
592 << " has no corresponding point on a neighbouring processor"
593 << abort(FatalError);
597 // Find lowest processor and lowest mesh point on this processor.
598 label lowestProcI = labelMax;
599 label lowestPointI = labelMax;
603 label proc = pointInfo[i][0];
605 if (proc < lowestProcI)
608 lowestPointI = pointInfo[i][1];
610 else if (proc == lowestProcI)
612 lowestPointI = min(lowestPointI, pointInfo[i][1]);
618 lowestProcI == Pstream::myProcNo()
619 && lowestPointI == meshPointI
622 // I am lowest numbered processor and point. Add to my list.
623 masterPoints[nMaster++] = meshPointI;
628 masterPoints.setSize(nMaster);
634 // Send subset of lists
635 void Foam::globalPoints::sendSharedPoints(const labelList& changedIndices) const
637 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
639 forAll(patches, patchI)
641 const polyPatch& pp = patches[patchI];
643 if (Pstream::parRun() && isA<processorPolyPatch>(pp))
645 const processorPolyPatch& procPatch =
646 refCast<const processorPolyPatch>(pp);
648 OPstream toNeighbour(Pstream::blocking, procPatch.neighbProcNo());
652 Pout<< "Sending to " << procPatch.neighbProcNo()
653 << " changed sharedPoints info:"
654 << changedIndices.size() << endl;
658 << IndirectList<label>(sharedPointAddr_, changedIndices)()
659 << IndirectList<label>(sharedPointLabels_, changedIndices)();
665 // Receive shared point indices for all my shared points. Note that since
666 // there are only a few here we can build a reverse map using the meshpoint
667 // instead of doing all this relative point indexing (patch face + index in
668 // face) as in send/receivePatchPoints
669 void Foam::globalPoints::receiveSharedPoints(labelList& changedIndices)
671 changedIndices.setSize(sharedPointAddr_.size());
674 const polyBoundaryMesh& patches = mesh_.boundaryMesh();
676 // Receive and set shared points
677 forAll(patches, patchI)
679 const polyPatch& pp = patches[patchI];
681 if (Pstream::parRun() && isA<processorPolyPatch>(pp))
683 const processorPolyPatch& procPatch =
684 refCast<const processorPolyPatch>(pp);
686 // Map from neighbouring meshPoint to sharedPoint)
687 Map<label> nbrSharedPoints(sharedPointAddr_.size());
690 // Receive meshPoints on neighbour and sharedPoints and build
691 // map from it. Note that we could have built the map on the
692 // neighbour and sent it over.
693 labelList nbrSharedPointAddr;
694 labelList nbrSharedPointLabels;
697 IPstream fromNeighbour
700 procPatch.neighbProcNo()
702 fromNeighbour >> nbrSharedPointAddr >> nbrSharedPointLabels;
705 // Insert into to map
706 forAll(nbrSharedPointLabels, i)
708 nbrSharedPoints.insert
710 nbrSharedPointLabels[i], // meshpoint on neighbour
711 nbrSharedPointAddr[i] // sharedPoint label
717 // Merge into whatever information I hold.
720 Map<label>::const_iterator iter = meshToProcPoint_.begin();
721 iter != meshToProcPoint_.end();
725 label meshPointI = iter.key();
726 label index = iter();
728 if (sharedPointAddr_[index] == -1)
730 // No shared point known yet for this meshPoint.
731 // See if was received from neighbour.
732 const procPointList& knownInfo = procPoints_[index];
734 // Check through the whole equivalence list for any
735 // point from the neighbour.
738 const procPoint& info = knownInfo[j];
742 (info[0] == procPatch.neighbProcNo())
743 && nbrSharedPoints.found(info[1])
746 // So this knownInfo contains the neighbour point
747 label sharedPointI = nbrSharedPoints[info[1]];
749 sharedPointAddr_[index] = sharedPointI;
750 sharedPointLabels_[index] = meshPointI;
751 changedIndices[nChanged++] = index;
759 else if (isA<cyclicPolyPatch>(pp))
761 const cyclicPolyPatch& cycPatch =
762 refCast<const cyclicPolyPatch>(pp);
764 // Build map from meshPoint to sharedPoint
765 Map<label> meshToSharedPoint(sharedPointAddr_.size());
766 forAll(sharedPointLabels_, i)
768 label meshPointI = sharedPointLabels_[i];
770 meshToSharedPoint.insert(meshPointI, sharedPointAddr_[i]);
774 //const edgeList& connections = cycPatch.coupledPoints();
775 const edgeList connections(coupledPoints(cycPatch));
777 forAll(connections, i)
779 const edge& e = connections[i];
781 label meshPointA = pp.meshPoints()[e[0]];
782 label meshPointB = pp.meshPoints()[e[1]];
784 // Do we already have shared point for meshPointA?
785 Map<label>::iterator fndA = meshToSharedPoint.find(meshPointA);
786 Map<label>::iterator fndB = meshToSharedPoint.find(meshPointB);
788 if (fndA != meshToSharedPoint.end())
790 if (fndB != meshToSharedPoint.end())
792 if (fndA() != fndB())
796 "globalPoints::receiveSharedPoints"
798 ) << "On patch " << pp.name()
799 << " connected points " << meshPointA
800 << ' ' << mesh_.points()[meshPointA]
801 << " and " << meshPointB
802 << ' ' << mesh_.points()[meshPointB]
803 << " are mapped to different shared points: "
804 << fndA() << " and " << fndB()
805 << abort(FatalError);
810 // No shared point yet for B.
811 label sharedPointI = fndA();
813 // Store shared point for meshPointB
814 label index = meshToProcPoint_[meshPointB];
816 sharedPointAddr_[index] = sharedPointI;
817 sharedPointLabels_[index] = meshPointB;
818 changedIndices[nChanged++] = index;
823 // No shared point yet for A.
824 if (fndB != meshToSharedPoint.end())
826 label sharedPointI = fndB();
828 // Store shared point for meshPointA
829 label index = meshToProcPoint_[meshPointA];
831 sharedPointAddr_[index] = sharedPointI;
832 sharedPointLabels_[index] = meshPointA;
833 changedIndices[nChanged++] = index;
840 changedIndices.setSize(nChanged);
844 Foam::edgeList Foam::globalPoints::coupledPoints(const cyclicPolyPatch& pp)
846 // Look at cyclic patch as two halves, A and B.
847 // Now all we know is that relative face index in halfA is same
848 // as coupled face in halfB and also that the 0th vertex
851 // From halfA point to halfB or -1.
852 labelList coupledPoint(pp.nPoints(), -1);
854 for (label patchFaceA = 0; patchFaceA < pp.size()/2; patchFaceA++)
856 const face& fA = pp.localFaces()[patchFaceA];
860 label patchPointA = fA[indexA];
862 if (coupledPoint[patchPointA] == -1)
864 const face& fB = pp.localFaces()[patchFaceA + pp.size()/2];
866 label indexB = (fB.size() - indexA) % fB.size();
868 coupledPoint[patchPointA] = fB[indexB];
873 edgeList connected(pp.nPoints());
875 // Extract coupled points.
876 label connectedI = 0;
878 forAll(coupledPoint, i)
880 if (coupledPoint[i] != -1)
882 connected[connectedI++] = edge(i, coupledPoint[i]);
886 connected.setSize(connectedI);
892 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
894 // Construct from components
895 Foam::globalPoints::globalPoints(const polyMesh& mesh)
898 nPatchPoints_(countPatchPoints(mesh.boundaryMesh())),
899 procPoints_(nPatchPoints_),
900 meshToProcPoint_(nPatchPoints_),
902 sharedPointLabels_(0),
907 Pout<< "globalPoints::globalPoints(const polyMesh&) : "
908 << "doing processor to processor communication to get sharedPoints"
912 labelHashSet changedPoints(nPatchPoints_);
914 // Initialize procPoints with my patch points. Keep track of points
915 // inserted (in changedPoints)
916 // There are two possible forms of this:
917 // - initialize with all patch points (allPoints = true). This causes all
918 // patch points to be exchanged so a lot of information gets stored and
919 // transferred. This all gets filtered out later when removing the
920 // equivalence lists of size 2.
921 // - initialize with boundary points of patches only (allPoints = false).
922 // This should work for all decompositions except extreme ones where a
923 // shared point is not on the boundary of any processor patches using it.
924 // This would happen if a domain was pinched such that two patches share
926 initOwnPoints(true, changedPoints);
928 // Do one exchange iteration to get neighbour points.
929 sendPatchPoints(changedPoints);
930 receivePatchPoints(changedPoints);
933 // Save neighbours reachable through face-face communication.
934 Map<label> neighbourList(meshToProcPoint_);
937 // Exchange until nothing changes on all processors.
938 bool changed = false;
942 sendPatchPoints(changedPoints);
943 receivePatchPoints(changedPoints);
945 changed = changedPoints.size() > 0;
946 reduce(changed, orOp<bool>());
951 // Remove direct neighbours from point equivalences.
952 remove(neighbourList);
955 //Pout<< "After removing locally connected points:" << endl;
958 // Map<label>::const_iterator iter = meshToProcPoint_.begin();
959 // iter != meshToProcPoint_.end();
963 // label meshPointI = iter.key();
964 // const procPointList& pointInfo = procPoints_[iter()];
966 // forAll(pointInfo, i)
968 // Pout<< " pointI:" << meshPointI << ' '
969 // << mesh.points()[meshPointI]
970 // << " connected to proc " << pointInfo[i][0]
971 // << " point:" << pointInfo[i][1]
977 // We now have - in procPoints_ - a list of points which are shared between
978 // multiple processors. These are the ones for which are sharedPoint
979 // needs to be determined. This is done by having the lowest numbered
980 // processor in the equivalence list 'ask' for a sharedPoint number
981 // and then distribute it across processor patches to the non-master
982 // processors. Note: below piece of coding is not very efficient. Uses
983 // a Map where possibly it shouldn't
985 // Initialize sharedPoint addressing. Is for every entry in procPoints_
987 sharedPointAddr_.setSize(meshToProcPoint_.size());
988 sharedPointAddr_ = -1;
989 sharedPointLabels_.setSize(meshToProcPoint_.size());
990 sharedPointLabels_ = -1;
993 // Get points for which I am master (lowest numbered proc)
994 labelList masterPoints(getMasterPoints());
997 // Determine number of master points on all processors.
998 labelList sharedPointSizes(Pstream::nProcs());
999 sharedPointSizes[Pstream::myProcNo()] = masterPoints.size();
1001 Pstream::gatherList(sharedPointSizes);
1002 Pstream::scatterList(sharedPointSizes);
1006 Pout<< "sharedPointSizes:" << sharedPointSizes << endl;
1009 // Get total number of shared points
1011 forAll(sharedPointSizes, procI)
1013 nGlobalPoints_ += sharedPointSizes[procI];
1016 // Assign sharedPoint labels. Every processor gets assigned consecutive
1017 // numbers for its master points.
1018 // These are assigned in processor order so processor0 gets
1019 // 0..masterPoints.size()-1 etc.
1021 // My point labels start after those of lower numbered processors
1022 label sharedPointI = 0;
1023 for (label procI = 0; procI < Pstream::myProcNo(); procI++)
1025 sharedPointI += sharedPointSizes[procI];
1028 forAll(masterPoints, i)
1030 label meshPointI = masterPoints[i];
1032 label index = meshToProcPoint_[meshPointI];
1034 sharedPointLabels_[index] = meshPointI;
1035 sharedPointAddr_[index] = sharedPointI++;
1039 // Now we have a sharedPointLabel for some of the entries in procPoints.
1040 // Send this information to neighbours. Receive their information.
1041 // Loop until nothing changes.
1043 // Initial subset to send is points for which I have sharedPoints
1044 labelList changedIndices(sharedPointAddr_.size());
1047 forAll(sharedPointAddr_, i)
1049 if (sharedPointAddr_[i] != -1)
1051 changedIndices[nChanged++] = i;
1054 changedIndices.setSize(nChanged);
1062 Pout<< "Determined " << changedIndices.size() << " shared points."
1063 << " Exchanging them" << endl;
1065 sendSharedPoints(changedIndices);
1066 receiveSharedPoints(changedIndices);
1068 changed = changedIndices.size() > 0;
1069 reduce(changed, orOp<bool>());
1074 forAll(sharedPointLabels_, i)
1076 if (sharedPointLabels_[i] == -1)
1078 FatalErrorIn("globalPoints::globalPoints(const polyMesh& mesh)")
1079 << "Problem: shared point on processor " << Pstream::myProcNo()
1080 << " not set at index " << sharedPointLabels_[i] << endl
1081 << "This might mean the individual processor domains are not"
1082 << " connected and the overall domain consists of multiple"
1083 << " regions. You can check this with checkMesh"
1084 << abort(FatalError);
1090 Pout<< "globalPoints::globalPoints(const polyMesh&) : "
1091 << "Finished global points" << endl;
1096 // ************************************************************************* //