mapDistributeBase.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2015-2017 OpenFOAM Foundation
9 Copyright (C) 2015-2022 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "mapDistributeBase.H"
30#include "bitSet.H"
31#include "commSchedule.H"
32#include "labelPairHashes.H"
33#include "globalIndex.H"
34#include "ListOps.H"
35
36// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37
38namespace Foam
39{
41}
42
43
44// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
45
47{
48 for (const label val : map)
49 {
50 if (!val)
51 {
52 // Cannot be flipped addressing if it contains zero.
53 return false;
54 }
55 else if (val < 0)
56 {
57 // Must be flipped addressing if it contains negatives.
58 return true;
59 }
60 }
61
62 return false;
63}
64
65
67{
68 for (const labelList& map : maps)
69 {
70 for (const label val : map)
71 {
72 if (!val)
73 {
74 // Cannot be flipped addressing if it contains zero.
75 return false;
76 }
77 else if (val < 0)
78 {
79 // Must be flipped addressing if it contains negatives.
80 return true;
81 }
82 }
83 }
84
85 return false;
86}
87
88
90(
91 const labelListList& maps,
92 const bool hasFlip
93)
94{
95 label maxIndex = -1;
96
97 for (const labelList& map : maps)
98 {
99 for (label index : map)
100 {
101 if (hasFlip)
102 {
103 index = mag(index)-1;
104 }
105
106 maxIndex = max(maxIndex, index);
107 }
108 }
109
110 return (maxIndex+1);
111}
112
113
115(
116 const labelUList& elements,
117 const labelListList& maps,
118 const bool hasFlip
119)
120{
121 if (elements.empty())
122 {
123 return 0;
124 }
125
126 // Moderately efficient markup/search
127
128 bitSet unvisited(elements);
129 label nUnmapped = unvisited.count();
130
131 if (hasFlip)
132 {
133 for (const labelList& map : maps)
134 {
135 for (label index : map)
136 {
137 index = mag(index)-1;
138
139 if (unvisited.unset(index))
140 {
141 --nUnmapped;
142 if (!nUnmapped) break;
143 }
144 }
145 }
146 }
147 else
148 {
149 for (const labelList& map : maps)
150 {
151 for (label index : map)
152 {
153 if (unvisited.unset(index))
154 {
155 --nUnmapped;
156 if (!nUnmapped) break;
157 }
158 }
159 }
160 }
161
162 return nUnmapped;
163}
164
165
167(
168 const label proci,
169 const label expectedSize,
170 const label receivedSize
171)
172{
173 if (receivedSize != expectedSize)
174 {
176 << "Expected from processor " << proci
177 << " " << expectedSize << " but received "
178 << receivedSize << " elements."
179 << abort(FatalError);
180 }
181}
182
183
184// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
185
187(
188 const labelListList& subMap,
189 const labelListList& constructMap,
190 const int tag,
191 const label comm
192)
193{
194 const label myRank = Pstream::myProcNo(comm);
195 const label nProcs = Pstream::nProcs(comm);
196
197 // Communications: send and receive processor
198 List<labelPair> allComms;
199
200 {
201 labelPairHashSet commsSet(nProcs);
202
203 // Find what communication is required
204 forAll(subMap, proci)
205 {
206 if (proci != myRank)
207 {
208 if (subMap[proci].size())
209 {
210 // I need to send to proci
211 commsSet.insert(labelPair(myRank, proci));
212 }
213 if (constructMap[proci].size())
214 {
215 // I need to receive from proci
216 commsSet.insert(labelPair(proci, myRank));
217 }
218 }
219 }
220 allComms = commsSet.toc();
221 }
222
223
224 // Gather/reduce
225 if (Pstream::master(comm))
226 {
227 // Receive and merge
228 for (const int proci : Pstream::subProcs(comm))
229 {
230 IPstream fromProc
231 (
233 proci,
234 0,
235 tag,
236 comm
237 );
238 List<labelPair> nbrData(fromProc);
239
240 for (const labelPair& connection : nbrData)
241 {
242 allComms.appendUniq(connection);
243 }
244 }
245 }
246 else
247 {
248 if (Pstream::parRun())
249 {
250 OPstream toMaster
251 (
254 0,
255 tag,
256 comm
257 );
258 toMaster << allComms;
259 }
260 }
261
262 // Broadcast: send comms information to all
263 Pstream::broadcast(allComms, comm);
264
265 // Determine my schedule.
266 labelList mySchedule
267 (
269 (
270 nProcs,
271 allComms
272 ).procSchedule()[myRank]
273 );
274
275 // Processors involved in my schedule
276 return List<labelPair>(allComms, mySchedule);
277}
278
279
281{
282 if (!schedulePtr_)
283 {
284 schedulePtr_.reset
285 (
287 (
288 schedule(subMap_, constructMap_, UPstream::msgType(), comm_)
289 )
290 );
291 }
292
293 return *schedulePtr_;
294}
295
296
298(
299 const UPstream::commsTypes commsType
300) const
301{
302 if (commsType == UPstream::commsTypes::scheduled)
303 {
304 return schedule();
305 }
306
307 return List<labelPair>::null();
308}
309
310
312{
313 const label myRank = Pstream::myProcNo(comm_);
314 const label nProcs = Pstream::nProcs(comm_);
315
316 // Determine offsets of remote data.
317 labelList minIndex(nProcs, labelMax);
318 labelList maxIndex(nProcs, labelMin);
319 forAll(constructMap_, proci)
320 {
321 const labelList& construct = constructMap_[proci];
322 if (constructHasFlip_)
323 {
324 forAll(construct, i)
325 {
326 label index = mag(construct[i])-1;
327 minIndex[proci] = min(minIndex[proci], index);
328 maxIndex[proci] = max(maxIndex[proci], index);
329 }
330 }
331 else
332 {
333 forAll(construct, i)
334 {
335 label index = construct[i];
336 minIndex[proci] = min(minIndex[proci], index);
337 maxIndex[proci] = max(maxIndex[proci], index);
338 }
339 }
340 }
341
342 label localSize(0);
343
344 if (maxIndex[myRank] != labelMin)
345 {
346 localSize = maxIndex[myRank]+1;
347 }
348
349 os << "Layout: (constructSize:" << constructSize_
350 << " subHasFlip:" << subHasFlip_
351 << " constructHasFlip:" << constructHasFlip_
352 << ")" << nl
353 << "local (processor " << myRank << "):" << nl
354 << " start : 0" << nl
355 << " size : " << localSize << endl;
356
357 label offset = localSize;
358 forAll(minIndex, proci)
359 {
360 if (proci != myRank && !constructMap_[proci].empty())
361 {
362 label size(0);
364 if (maxIndex[proci] != labelMin)
365 {
366 size = maxIndex[proci]-minIndex[proci]+1;
367 if (minIndex[proci] != offset)
368 {
370 << "offset:" << offset
371 << " proci:" << proci
372 << " minIndex:" << minIndex[proci]
373 << abort(FatalError);
374 }
375 }
376
377 os << "processor " << proci << ':' << nl
378 << " start : " << offset << nl
379 << " size : " << size << endl;
380
381 offset += size;
383 }
384}
385
386
388(
389 const globalIndex& globalNumbering,
390 const labelUList& elements,
391 List<Map<label>>& compactMap
392) const
393{
394 const label myRank = Pstream::myProcNo(comm_);
395 const label nProcs = Pstream::nProcs(comm_);
397 // Count all (non-local) elements needed. Just for presizing map.
398 labelList nNonLocal(nProcs, Zero);
399
400 for (const label globalIdx : elements)
401 {
402 if (globalIdx != -1 && !globalNumbering.isLocal(globalIdx))
403 {
404 label proci = globalNumbering.whichProcID(globalIdx);
405 nNonLocal[proci]++;
406 }
407 }
408
409 compactMap.resize_nocopy(nProcs);
410
411 forAll(compactMap, proci)
412 {
413 compactMap[proci].clear();
414 if (proci != myRank)
415 {
416 compactMap[proci].resize(2*nNonLocal[proci]);
417 }
418 }
419
420
421 // Collect all (non-local) elements needed.
422 for (const label globalIdx : elements)
424 if (globalIdx != -1 && !globalNumbering.isLocal(globalIdx))
425 {
426 label proci = globalNumbering.whichProcID(globalIdx);
427 label index = globalNumbering.toLocal(proci, globalIdx);
428 label nCompact = compactMap[proci].size();
429 compactMap[proci].insert(index, nCompact);
430 }
431 }
432}
433
434
436(
437 const globalIndex& globalNumbering,
438 const labelListList& cellCells,
439 List<Map<label>>& compactMap
440) const
441{
442 const label myRank = Pstream::myProcNo(comm_);
443 const label nProcs = Pstream::nProcs(comm_);
444
445 // Count all (non-local) elements needed. Just for presizing map.
446 labelList nNonLocal(nProcs, Zero);
447
448 for (const labelList& cCells : cellCells)
449 {
450 for (const label globalIdx : cCells)
451 {
452 if (globalIdx != -1 && !globalNumbering.isLocal(globalIdx))
453 {
454 label proci = globalNumbering.whichProcID(globalIdx);
455 nNonLocal[proci]++;
456 }
457 }
458 }
459
460 compactMap.resize_nocopy(nProcs);
461
462 forAll(compactMap, proci)
463 {
464 compactMap[proci].clear();
465 if (proci != myRank)
466 {
467 compactMap[proci].resize(2*nNonLocal[proci]);
468 }
469 }
470
471
472 // Collect all (non-local) elements needed.
473 for (const labelList& cCells : cellCells)
474 {
475 for (const label globalIdx : cCells)
476 {
477 if (globalIdx != -1 && !globalNumbering.isLocal(globalIdx))
478 {
479 label proci = globalNumbering.whichProcID(globalIdx);
480 label index = globalNumbering.toLocal(proci, globalIdx);
481 label nCompact = compactMap[proci].size();
482 compactMap[proci].insert(index, nCompact);
483 }
484 }
485 }
486}
487
488
490(
491 const int tag,
492 const globalIndex& globalNumbering,
493 labelList& elements,
494 List<Map<label>>& compactMap,
495 labelList& compactStart
496)
497{
498 const label myRank = Pstream::myProcNo(comm_);
499 const label nProcs = Pstream::nProcs(comm_);
500
501 // The overall compact addressing is
502 // - myProcNo data first (uncompacted)
503 // - all other processors consecutively
504
505 compactStart.setSize(nProcs);
506 compactStart[myRank] = 0;
507 constructSize_ = globalNumbering.localSize();
508 forAll(compactStart, proci)
509 {
510 if (proci != myRank)
511 {
512 compactStart[proci] = constructSize_;
513 constructSize_ += compactMap[proci].size();
514 }
515 }
516
517
518 // Find out what to receive/send in compact addressing.
519
520 // What I want to receive is what others have to send
521 labelListList wantedRemoteElements(nProcs);
522 // Compact addressing for received data
523 constructMap_.setSize(nProcs);
524 forAll(compactMap, proci)
525 {
526 if (proci == myRank)
527 {
528 // All my own elements are used
529 label nLocal = globalNumbering.localSize();
530 wantedRemoteElements[proci] = identity(nLocal);
531 constructMap_[proci] = identity(nLocal);
532 }
533 else
534 {
535 // Remote elements wanted from processor proci
536 labelList& remoteElem = wantedRemoteElements[proci];
537 labelList& localElem = constructMap_[proci];
538 remoteElem.setSize(compactMap[proci].size());
539 localElem.setSize(compactMap[proci].size());
540 label i = 0;
541 forAllIters(compactMap[proci], iter)
542 {
543 const label compactI = compactStart[proci] + iter.val();
544 remoteElem[i] = iter.key();
545 localElem[i] = compactI;
546 iter.val() = compactI;
547 i++;
548 }
549 }
550 }
551
552 subMap_.setSize(nProcs);
553 Pstream::exchange<labelList, label>
554 (
555 wantedRemoteElements,
556 subMap_,
557 tag,
558 comm_
559 );
560
561 // Renumber elements
562 for (label& elem : elements)
563 {
564 elem = renumber(globalNumbering, compactMap, elem);
565 }
566}
567
568
570(
571 const int tag,
572 const globalIndex& globalNumbering,
573 labelListList& cellCells,
574 List<Map<label>>& compactMap,
575 labelList& compactStart
576)
577{
578 const label myRank = Pstream::myProcNo(comm_);
579 const label nProcs = Pstream::nProcs(comm_);
580
581 // The overall compact addressing is
582 // - myProcNo data first (uncompacted)
583 // - all other processors consecutively
584
585 compactStart.setSize(nProcs);
586 compactStart[myRank] = 0;
587 constructSize_ = globalNumbering.localSize();
588 forAll(compactStart, proci)
589 {
590 if (proci != myRank)
591 {
592 compactStart[proci] = constructSize_;
593 constructSize_ += compactMap[proci].size();
594 }
595 }
596
597
598 // Find out what to receive/send in compact addressing.
599
600 // What I want to receive is what others have to send
601 labelListList wantedRemoteElements(nProcs);
602 // Compact addressing for received data
603 constructMap_.setSize(nProcs);
604 forAll(compactMap, proci)
605 {
606 if (proci == myRank)
607 {
608 // All my own elements are used
609 label nLocal = globalNumbering.localSize();
610 wantedRemoteElements[proci] = identity(nLocal);
611 constructMap_[proci] = identity(nLocal);
612 }
613 else
614 {
615 // Remote elements wanted from processor proci
616 labelList& remoteElem = wantedRemoteElements[proci];
617 labelList& localElem = constructMap_[proci];
618 remoteElem.setSize(compactMap[proci].size());
619 localElem.setSize(compactMap[proci].size());
620 label i = 0;
621 forAllIters(compactMap[proci], iter)
622 {
623 const label compactI = compactStart[proci] + iter.val();
624 remoteElem[i] = iter.key();
625 localElem[i] = compactI;
626 iter.val() = compactI;
627 i++;
628 }
629 }
630 }
631
632 subMap_.setSize(nProcs);
633 Pstream::exchange<labelList, label>
634 (
635 wantedRemoteElements,
636 subMap_,
637 tag,
638 comm_
639 );
640
641 // Renumber elements
642 for (labelList& cCells : cellCells)
643 {
644 for (label& celli : cCells)
645 {
646 celli = renumber(globalNumbering, compactMap, celli);
647 }
648 }
649}
650
651
652// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
653
655:
656 mapDistributeBase(UPstream::worldComm)
657{}
658
659
661:
662 constructSize_(0),
663 subMap_(),
664 constructMap_(),
665 subHasFlip_(false),
666 constructHasFlip_(false),
667 comm_(comm),
668 schedulePtr_(nullptr)
669{}
670
671
673:
674 constructSize_(map.constructSize_),
675 subMap_(map.subMap_),
676 constructMap_(map.constructMap_),
677 subHasFlip_(map.subHasFlip_),
678 constructHasFlip_(map.constructHasFlip_),
679 comm_(map.comm_),
680 schedulePtr_(nullptr)
681{}
682
683
685:
686 mapDistributeBase(map.comm())
687{
688 transfer(map);
689}
690
691
693(
694 const label constructSize,
695 labelListList&& subMap,
696 labelListList&& constructMap,
697 const bool subHasFlip,
698 const bool constructHasFlip,
699 const label comm
700)
701:
702 constructSize_(constructSize),
703 subMap_(std::move(subMap)),
704 constructMap_(std::move(constructMap)),
705 subHasFlip_(subHasFlip),
706 constructHasFlip_(constructHasFlip),
707 comm_(comm),
708 schedulePtr_(nullptr)
709{}
710
711
713(
714 const labelUList& sendProcs,
715 const labelUList& recvProcs,
716 const label comm
717)
718:
719 constructSize_(0),
720 subMap_(),
721 constructMap_(),
722 subHasFlip_(false),
723 constructHasFlip_(false),
724 comm_(comm),
725 schedulePtr_(nullptr)
726{
727 const label myRank = Pstream::myProcNo(comm_);
728 const label nProcs = Pstream::nProcs(comm_);
729
730 if (sendProcs.size() != recvProcs.size())
731 {
733 << "The send and receive data is not the same length. sendProcs:"
734 << sendProcs.size() << " recvProcs:" << recvProcs.size()
735 << abort(FatalError);
736 }
737
738 // Per processor the number of samples we have to send/receive.
739 labelList nSend(nProcs, Zero);
740 labelList nRecv(nProcs, Zero);
741
742 forAll(sendProcs, sampleI)
743 {
744 const label sendProc = sendProcs[sampleI];
745 const label recvProc = recvProcs[sampleI];
746
747 // Note that also need to include local communication (both
748 // RecvProc and sendProc on local processor)
749
750 if (myRank == sendProc)
751 {
752 // I am the sender.
753 nSend[recvProc]++;
754 }
755 if (myRank == recvProc)
756 {
757 // I am the receiver.
758 nRecv[sendProc]++;
759 }
760 }
761
762 subMap_.setSize(nProcs);
763 constructMap_.setSize(nProcs);
764 forAll(nSend, proci)
765 {
766 subMap_[proci].setSize(nSend[proci]);
767 constructMap_[proci].setSize(nRecv[proci]);
768 }
769 nSend = 0;
770 nRecv = 0;
771
772 // Largest entry inside constructMap
773 label maxRecvIndex = -1;
774
775 forAll(sendProcs, sampleI)
776 {
777 const label sendProc = sendProcs[sampleI];
778 const label recvProc = recvProcs[sampleI];
779
780 if (myRank == sendProc)
781 {
782 // I am the sender. Store index I need to send.
783 subMap_[recvProc][nSend[recvProc]++] = sampleI;
784 }
785 if (myRank == recvProc)
786 {
787 // I am the receiver.
788 constructMap_[sendProc][nRecv[sendProc]++] = sampleI;
789 maxRecvIndex = sampleI;
790 }
791 }
792
793 constructSize_ = maxRecvIndex+1;
794}
795
796
798(
799 const globalIndex& globalNumbering,
800 labelList& elements,
801 List<Map<label>>& compactMap,
802 const int tag,
803 const label comm
804)
805:
806 constructSize_(0),
807 subMap_(),
808 constructMap_(),
809 subHasFlip_(false),
810 constructHasFlip_(false),
811 comm_(comm),
812 schedulePtr_(nullptr)
813{
814 // Construct per processor compact addressing of the global elements
815 // needed. The ones from the local processor are not included since
816 // these are always all needed.
818 (
819 globalNumbering,
820 elements,
821 compactMap
822 );
823
825 //forAll(compactMap, proci)
826 //{
827 // if (proci != myRank)
828 // {
829 // Map<label>& globalMap = compactMap[proci];
830 //
831 // const List<label> sorted(globalMap.sortedToc());
832 //
833 // forAll(sorted, i)
834 // {
835 // globalMap(sorted[i]) = i;
836 // }
837 // }
838 //}
839
840
841 // Exchange what I need with processor that supplies it. Renumber elements
842 // into compact numbering
843 labelList compactStart;
845 (
846 tag,
847 globalNumbering,
848 elements,
849 compactMap,
850 compactStart
851 );
852
853 if (debug)
854 {
856 }
857}
858
859
861(
862 const globalIndex& globalNumbering,
863 labelListList& cellCells,
864 List<Map<label>>& compactMap,
865 const int tag,
866 const label comm
867)
868:
869 constructSize_(0),
870 subMap_(),
871 constructMap_(),
872 subHasFlip_(false),
873 constructHasFlip_(false),
874 comm_(comm),
875 schedulePtr_(nullptr)
876{
877 // Construct per processor compact addressing of the global elements
878 // needed. The ones from the local processor are not included since
879 // these are always all needed.
881 (
882 globalNumbering,
883 cellCells,
884 compactMap
885 );
886
888 //forAll(compactMap, proci)
889 //{
890 // if (proci != myRank)
891 // {
892 // Map<label>& globalMap = compactMap[proci];
893 //
894 // const List<label> sorted(globalMap.sortedToc());
895 //
896 // forAll(sorted, i)
897 // {
898 // globalMap(sorted[i]) = i;
899 // }
900 // }
901 //}
902
903
904 // Exchange what I need with processor that supplies it. Renumber elements
905 // into compact numbering
906 labelList compactStart;
908 (
909 tag,
910 globalNumbering,
911 cellCells,
912 compactMap,
913 compactStart
914 );
915
916 if (debug)
917 {
919 }
920}
921
922
924(
925 labelListList&& subMap,
926 const bool subHasFlip,
927 const bool constructHasFlip,
928 const label comm
929)
930:
931 constructSize_(0),
932 subMap_(std::move(subMap)),
933 constructMap_(),
934 subHasFlip_(subHasFlip),
935 constructHasFlip_(constructHasFlip),
936 comm_(comm),
937 schedulePtr_(nullptr)
938{
939 const label myRank = Pstream::myProcNo(comm_);
940 const label nProcs = Pstream::nProcs(comm_);
941
942 // Send over how many i need to receive.
943 labelList recvSizes;
944 Pstream::exchangeSizes(subMap_, recvSizes, comm_);
945
946 // Determine order of receiving
947 constructSize_ = 0;
948 constructMap_.resize(nProcs);
949
950
951 // My data first
952 {
953 const label len = recvSizes[myRank];
954
955 constructMap_[myRank] = identity(len, constructSize_);
956 constructSize_ += len;
957 }
958
959 // What the other processors are sending to me
960 forAll(constructMap_, proci)
961 {
962 if (proci != myRank)
963 {
964 const label len = recvSizes[proci];
965
966 constructMap_[proci] = identity(len, constructSize_);
967 constructSize_ += len;
968 }
969 }
970}
971
972
973// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
974
976{
977 labelList sizes(subMap_.size());
978 forAll(subMap_, i)
979 {
980 sizes[i] = subMap_[i].size();
981 }
982
983 return sizes;
984}
985
986
988{
989 labelList sizes(constructMap_.size());
990 forAll(constructMap_, i)
991 {
992 sizes[i] = constructMap_[i].size();
993 }
994
995 return sizes;
996}
997
998
1000{
1001 constructSize_ = 0;
1002 subMap_.clear();
1003 constructMap_.clear();
1004 subHasFlip_ = false;
1005 constructHasFlip_ = false;
1006 // Leave comm_ intact
1007 schedulePtr_.reset(nullptr);
1008}
1009
1010
1012{
1013 if (this == &rhs)
1014 {
1015 // Self-assignment is a no-op
1016 return;
1017 }
1018
1019 constructSize_ = rhs.constructSize_;
1020 subMap_.transfer(rhs.subMap_);
1021 constructMap_.transfer(rhs.constructMap_);
1022 subHasFlip_ = rhs.subHasFlip_;
1023 constructHasFlip_ = rhs.constructHasFlip_;
1024 comm_ = rhs.comm_;
1025 schedulePtr_.reset(nullptr);
1026
1027 rhs.constructSize_ = 0;
1028 rhs.subHasFlip_ = false;
1029 rhs.constructHasFlip_ = false;
1030}
1031
1032
1034(
1035 const globalIndex& globalNumbering,
1036 const List<Map<label>>& compactMap,
1037 const label globalI
1038)
1039{
1040 if (globalI == -1)
1041 {
1042 return globalI;
1043 }
1044 if (globalNumbering.isLocal(globalI))
1045 {
1046 return globalNumbering.toLocal(globalI);
1047 }
1048 else
1049 {
1050 label proci = globalNumbering.whichProcID(globalI);
1051 label index = globalNumbering.toLocal(proci, globalI);
1052 return compactMap[proci][index];
1053 }
1054}
1055
1056
1057// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
1058
1060{
1061 if (this == &rhs)
1062 {
1063 return; // Self-assignment is a no-op
1064 }
1065
1066 constructSize_ = rhs.constructSize_;
1067 subMap_ = rhs.subMap_;
1068 constructMap_ = rhs.constructMap_;
1069 subHasFlip_ = rhs.subHasFlip_;
1070 constructHasFlip_ = rhs.constructHasFlip_;
1071 comm_ = rhs.comm_;
1072 schedulePtr_.reset(nullptr);
1073}
1074
1075
1077{
1078 if (this != &rhs)
1079 {
1080 // Avoid self assignment
1081 transfer(rhs);
1082 }
1083}
1084
1085
1086// ************************************************************************* //
Various functions to operate on Lists.
A HashTable with keys but without contents that is similar to std::unordered_set.
Definition: HashSet.H:96
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
Definition: HashSet.H:191
List< Key > toc() const
The table of contents (the keys) in unsorted order.
Definition: HashTable.C:122
Input inter-processor communications stream.
Definition: IPstream.H:57
void setSize(const label n)
Alias for resize()
Definition: List.H:218
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Definition: ListI.H:146
label appendUniq(const T &val)
Append an element if not already in the list.
Definition: ListI.H:232
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:139
static const List< T > & null()
Return a null List.
Definition: ListI.H:109
A HashTable to objects of type <T> with a label key.
Definition: Map.H:60
Output inter-processor communications stream.
Definition: OPstream.H:57
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:62
label nProcs() const noexcept
Number of ranks associated with PstreamBuffers.
UPstream::rangeType subProcs() const noexcept
Range of sub-processes indices associated with PstreamBuffers.
static void exchangeSizes(const labelUList &sendProcs, const labelUList &recvProcs, const Container &sendData, labelList &sizes, const label tag=UPstream::msgType(), const label comm=UPstream::worldComm)
static void broadcast(Type &value, const label comm=UPstream::worldComm)
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Inter-processor communications stream.
Definition: UPstream.H:59
commsTypes
Types of communications.
Definition: UPstream.H:67
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:556
static constexpr int masterNo() noexcept
Process index of the master (always 0)
Definition: UPstream.H:451
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:433
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition: bitSet.H:66
unsigned int count(const bool on=true) const
Count number of bits set.
Definition: bitSetI.H:500
bitSet & unset(const bitSet &other)
Definition: bitSetI.H:628
Determines the order in which a set of processors should communicate with one another.
Definition: commSchedule.H:68
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
label localSize() const
My local size.
Definition: globalIndexI.H:207
label toLocal(const label i) const
From global to local on current processor.
Definition: globalIndexI.H:325
bool isLocal(const label i) const
Is on local processor.
Definition: globalIndexI.H:244
Class containing processor-to-processor mapping information.
void operator=(const mapDistributeBase &rhs)
Copy assignment.
const List< labelPair > & whichSchedule(const UPstream::commsTypes commsType) const
const List< labelPair > & schedule() const
Return a schedule. Demand driven. See above.
mapDistributeBase()
Default construct (uses worldComm)
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
void transfer(mapDistributeBase &rhs)
Transfer the contents of the argument and annul the argument.
static label renumber(const globalIndex &, const List< Map< label > > &compactMap, const label globalElement)
Helper for construct from globalIndex. Renumbers element.
void calcCompactAddressing(const globalIndex &globalNumbering, const labelUList &elements, List< Map< label > > &compactMap) const
Construct per processor compact addressing of the global elements.
static void checkReceivedSize(const label proci, const label expectedSize, const label receivedSize)
Fatal if expected and received size are not equal.
labelList constructMapSizes() const
The sizes of the constructMap lists.
void exchangeAddressing(const int tag, const globalIndex &globalNumbering, labelList &elements, List< Map< label > > &compactMap, labelList &compactStart)
labelList subMapSizes() const
The sizes of the subMap lists.
static label countUnmapped(const labelUList &elements, const labelListList &maps, const bool hasFlip)
Count the number of unmapped elements.
static label getMappedSize(const labelListList &maps, const bool hasFlip)
Scan the maps for the max addressed index.
void clear()
Reset to zero size, only retaining communicator.
static bool hasFlipAddressing(const labelUList &map)
int myProcNo() const noexcept
Return processor number.
splitCell * master() const
Definition: splitCell.H:113
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
OBJstream os(runTime.globalPath()/outputName)
A HashTable to objects of type <T> with a labelPair key. The hashing is based on labelPair (FixedList...
Namespace for OpenFOAM.
Pair< label > labelPair
A pair of labels.
Definition: Pair.H:57
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
Definition: labelList.C:38
constexpr label labelMin
Definition: label.H:60
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
constexpr label labelMax
Definition: label.H:61
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
#define forAllIters(container, iter)
Iterate across all elements in the container object.
Definition: stdFoam.H:260