ENH: autoLayerDriver: better layering information message
[OpenFOAM-2.0.x.git] / src / OpenFOAM / meshes / polyMesh / mapPolyMesh / mapDistribute / mapDistributeTemplates.C
blobb81168d692d52eedec73b1bd7bccc685fd0e5121
1 /*---------------------------------------------------------------------------*\
2   =========                 |
3   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
4    \\    /   O peration     |
5     \\  /    A nd           | Copyright (C) 2011 OpenFOAM Foundation
6      \\/     M anipulation  |
7 -------------------------------------------------------------------------------
8 License
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
13     the Free Software Foundation, either version 3 of the License, or
14     (at your 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
19     for more details.
21     You should have received a copy of the GNU General Public License
22     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
24 \*---------------------------------------------------------------------------*/
26 #include "Pstream.H"
27 #include "PstreamBuffers.H"
28 #include "PstreamCombineReduceOps.H"
29 #include "globalIndexAndTransform.H"
30 #include "transformField.H"
32 // * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
34 // Distribute list.
35 template<class T>
36 void Foam::mapDistribute::distribute
38     const Pstream::commsTypes commsType,
39     const List<labelPair>& schedule,
40     const label constructSize,
41     const labelListList& subMap,
42     const labelListList& constructMap,
43     List<T>& field
46     if (!Pstream::parRun())
47     {
48         // Do only me to me.
50         const labelList& mySubMap = subMap[Pstream::myProcNo()];
52         List<T> subField(mySubMap.size());
53         forAll(mySubMap, i)
54         {
55             subField[i] = field[mySubMap[i]];
56         }
57         
58         // Receive sub field from myself (subField)
59         const labelList& map = constructMap[Pstream::myProcNo()];
61         field.setSize(constructSize);
63         forAll(map, i)
64         {
65             field[map[i]] = subField[i];
66         }
67         return;
68     }
70     if (commsType == Pstream::blocking)
71     {
72         // Since buffered sending can reuse the field to collect the
73         // received data.
75         // Send sub field to neighbour
76         for (label domain = 0; domain < Pstream::nProcs(); domain++)
77         {
78             const labelList& map = subMap[domain];
80             if (domain != Pstream::myProcNo() && map.size())
81             {
82                 OPstream toNbr(Pstream::blocking, domain);
83                 toNbr << UIndirectList<T>(field, map);
84             }
85         }
87         // Subset myself
88         const labelList& mySubMap = subMap[Pstream::myProcNo()];
90         List<T> subField(mySubMap.size());
91         forAll(mySubMap, i)
92         {
93             subField[i] = field[mySubMap[i]];
94         }
96         // Receive sub field from myself (subField)
97         const labelList& map = constructMap[Pstream::myProcNo()];
99         field.setSize(constructSize);
101         forAll(map, i)
102         {
103             field[map[i]] = subField[i];
104         }
106         // Receive sub field from neighbour
107         for (label domain = 0; domain < Pstream::nProcs(); domain++)
108         {
109             const labelList& map = constructMap[domain];
111             if (domain != Pstream::myProcNo() && map.size())
112             {
113                 IPstream fromNbr(Pstream::blocking, domain);
114                 List<T> subField(fromNbr);
116                 checkReceivedSize(domain, map.size(), subField.size());
118                 forAll(map, i)
119                 {
120                     field[map[i]] = subField[i];
121                 }
122             }
123         }
124     }
125     else if (commsType == Pstream::scheduled)
126     {
127         // Need to make sure I don't overwrite field with received data
128         // since the data might need to be sent to another processor. So
129         // allocate a new field for the results.
130         List<T> newField(constructSize);
132         // Subset myself
133         UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
135         // Receive sub field from myself (subField)
136         const labelList& map = constructMap[Pstream::myProcNo()];
138         forAll(map, i)
139         {
140             newField[map[i]] = subField[i];
141         }
143         // Schedule will already have pruned 0-sized comms
144         forAll(schedule, i)
145         {
146             const labelPair& twoProcs = schedule[i];
147             // twoProcs is a swap pair of processors. The first one is the
148             // one that needs to send first and then receive.
150             label sendProc = twoProcs[0];
151             label recvProc = twoProcs[1];
153             if (Pstream::myProcNo() == sendProc)
154             {
155                 // I am send first, receive next
156                 {
157                     OPstream toNbr(Pstream::scheduled, recvProc);
158                     toNbr << UIndirectList<T>(field, subMap[recvProc]);
159                 }
160                 {
161                     IPstream fromNbr(Pstream::scheduled, recvProc);
162                     List<T> subField(fromNbr);
164                     const labelList& map = constructMap[recvProc];
166                     checkReceivedSize(recvProc, map.size(), subField.size());
168                     forAll(map, i)
169                     {
170                         newField[map[i]] = subField[i];
171                     }
172                 }
173             }
174             else
175             {
176                 // I am receive first, send next
177                 {
178                     IPstream fromNbr(Pstream::scheduled, sendProc);
179                     List<T> subField(fromNbr);
181                     const labelList& map = constructMap[sendProc];
183                     checkReceivedSize(sendProc, map.size(), subField.size());
185                     forAll(map, i)
186                     {
187                         newField[map[i]] = subField[i];
188                     }
189                 }
190                 {
191                     OPstream toNbr(Pstream::scheduled, sendProc);
192                     toNbr << UIndirectList<T>(field, subMap[sendProc]);
193                 }
194             }
195         }
196         field.transfer(newField);
197     }
198     else if (commsType == Pstream::nonBlocking)
199     {
200         if (!contiguous<T>())
201         {
202             PstreamBuffers pBufs(Pstream::nonBlocking);
204             // Stream data into buffer
205             for (label domain = 0; domain < Pstream::nProcs(); domain++)
206             {
207                 const labelList& map = subMap[domain];
209                 if (domain != Pstream::myProcNo() && map.size())
210                 {
211                     // Put data into send buffer
212                     UOPstream toDomain(domain, pBufs);
213                     toDomain << UIndirectList<T>(field, map);
214                 }
215             }
217             // Start receiving
218             pBufs.finishedSends();
220             {
221                 // Set up 'send' to myself
222                 const labelList& mySubMap = subMap[Pstream::myProcNo()];
223                 List<T> mySubField(mySubMap.size());
224                 forAll(mySubMap, i)
225                 {
226                     mySubField[i] = field[mySubMap[i]];
227                 }
228                 // Combine bits. Note that can reuse field storage
229                 field.setSize(constructSize);
230                 // Receive sub field from myself
231                 {
232                     const labelList& map = constructMap[Pstream::myProcNo()];
234                     forAll(map, i)
235                     {
236                         field[map[i]] = mySubField[i];
237                     }
238                 }
239             }
241             // Consume
242             for (label domain = 0; domain < Pstream::nProcs(); domain++)
243             {
244                 const labelList& map = constructMap[domain];
246                 if (domain != Pstream::myProcNo() && map.size())
247                 {
248                     UIPstream str(domain, pBufs);
249                     List<T> recvField(str);
251                     checkReceivedSize(domain, map.size(), recvField.size());
253                     forAll(map, i)
254                     {
255                         field[map[i]] = recvField[i];
256                     }
257                 }
258             }
259         }
260         else
261         {
262             // Set up sends to neighbours
264             List<List<T > > sendFields(Pstream::nProcs());
266             for (label domain = 0; domain < Pstream::nProcs(); domain++)
267             {
268                 const labelList& map = subMap[domain];
270                 if (domain != Pstream::myProcNo() && map.size())
271                 {
272                     List<T>& subField = sendFields[domain];
273                     subField.setSize(map.size());
274                     forAll(map, i)
275                     {
276                         subField[i] = field[map[i]];
277                     }
279                     OPstream::write
280                     (
281                         Pstream::nonBlocking,
282                         domain,
283                         reinterpret_cast<const char*>(subField.begin()),
284                         subField.byteSize()
285                     );
286                 }
287             }
289             // Set up receives from neighbours
291             List<List<T > > recvFields(Pstream::nProcs());
293             for (label domain = 0; domain < Pstream::nProcs(); domain++)
294             {
295                 const labelList& map = constructMap[domain];
297                 if (domain != Pstream::myProcNo() && map.size())
298                 {
299                     recvFields[domain].setSize(map.size());
300                     IPstream::read
301                     (
302                         Pstream::nonBlocking,
303                         domain,
304                         reinterpret_cast<char*>(recvFields[domain].begin()),
305                         recvFields[domain].byteSize()
306                     );
307                 }
308             }
311             // Set up 'send' to myself
313             {
314                 const labelList& map = subMap[Pstream::myProcNo()];
316                 List<T>& subField = sendFields[Pstream::myProcNo()];
317                 subField.setSize(map.size());
318                 forAll(map, i)
319                 {
320                     subField[i] = field[map[i]];
321                 }
322             }
325             // Combine bits. Note that can reuse field storage
327             field.setSize(constructSize);
330             // Receive sub field from myself (sendFields[Pstream::myProcNo()])
331             {
332                 const labelList& map = constructMap[Pstream::myProcNo()];
333                 const List<T>& subField = sendFields[Pstream::myProcNo()];
335                 forAll(map, i)
336                 {
337                     field[map[i]] = subField[i];
338                 }
339             }
342             // Wait for all to finish
344             Pstream::waitRequests();
346             // Collect neighbour fields
348             for (label domain = 0; domain < Pstream::nProcs(); domain++)
349             {
350                 const labelList& map = constructMap[domain];
352                 if (domain != Pstream::myProcNo() && map.size())
353                 {
354                     const List<T>& subField = recvFields[domain];
356                     checkReceivedSize(domain, map.size(), subField.size());
358                     forAll(map, i)
359                     {
360                         field[map[i]] = subField[i];
361                     }
362                 }
363             }
364         }
365     }
366     else
367     {
368         FatalErrorIn("mapDistribute::distribute(..)")
369             << "Unknown communication schedule " << commsType
370             << abort(FatalError);
371     }
375 // Distribute list.
376 template<class T, class CombineOp>
377 void Foam::mapDistribute::distribute
379     const Pstream::commsTypes commsType,
380     const List<labelPair>& schedule,
381     const label constructSize,
382     const labelListList& subMap,
383     const labelListList& constructMap,
384     List<T>& field,
385     const CombineOp& cop,
386     const T& nullValue
389     if (!Pstream::parRun())
390     {
391         // Do only me to me.
393         const labelList& mySubMap = subMap[Pstream::myProcNo()];
395         List<T> subField(mySubMap.size());
396         forAll(mySubMap, i)
397         {
398             subField[i] = field[mySubMap[i]];
399         }
400         
401         // Receive sub field from myself (subField)
402         const labelList& map = constructMap[Pstream::myProcNo()];
404         field.setSize(constructSize);
405         field = nullValue;
407         forAll(map, i)
408         {
409             cop(field[map[i]], subField[i]);
410         }
411         return;
412     }
414     if (commsType == Pstream::blocking)
415     {
416         // Since buffered sending can reuse the field to collect the
417         // received data.
419         // Send sub field to neighbour
420         for (label domain = 0; domain < Pstream::nProcs(); domain++)
421         {
422             const labelList& map = subMap[domain];
424             if (domain != Pstream::myProcNo() && map.size())
425             {
426                 OPstream toNbr(Pstream::blocking, domain);
427                 toNbr << UIndirectList<T>(field, map);
428             }
429         }
431         // Subset myself
432         const labelList& mySubMap = subMap[Pstream::myProcNo()];
434         List<T> subField(mySubMap.size());
435         forAll(mySubMap, i)
436         {
437             subField[i] = field[mySubMap[i]];
438         }
440         // Receive sub field from myself (subField)
441         const labelList& map = constructMap[Pstream::myProcNo()];
443         field.setSize(constructSize);
444         field = nullValue;
446         forAll(map, i)
447         {
448             cop(field[map[i]], subField[i]);
449         }
451         // Receive sub field from neighbour
452         for (label domain = 0; domain < Pstream::nProcs(); domain++)
453         {
454             const labelList& map = constructMap[domain];
456             if (domain != Pstream::myProcNo() && map.size())
457             {
458                 IPstream fromNbr(Pstream::blocking, domain);
459                 List<T> subField(fromNbr);
461                 checkReceivedSize(domain, map.size(), subField.size());
463                 forAll(map, i)
464                 {
465                     cop(field[map[i]], subField[i]);
466                 }
467             }
468         }
469     }
470     else if (commsType == Pstream::scheduled)
471     {
472         // Need to make sure I don't overwrite field with received data
473         // since the data might need to be sent to another processor. So
474         // allocate a new field for the results.
475         List<T> newField(constructSize, nullValue);
477         // Subset myself
478         UIndirectList<T> subField(field, subMap[Pstream::myProcNo()]);
480         // Receive sub field from myself (subField)
481         const labelList& map = constructMap[Pstream::myProcNo()];
483         forAll(map, i)
484         {
485             cop(newField[map[i]], subField[i]);
486         }
488         // Schedule will already have pruned 0-sized comms
489         forAll(schedule, i)
490         {
491             const labelPair& twoProcs = schedule[i];
492             // twoProcs is a swap pair of processors. The first one is the
493             // one that needs to send first and then receive.
495             label sendProc = twoProcs[0];
496             label recvProc = twoProcs[1];
498             if (Pstream::myProcNo() == sendProc)
499             {
500                 // I am send first, receive next
501                 {
502                     OPstream toNbr(Pstream::scheduled, recvProc);
503                     toNbr << UIndirectList<T>(field, subMap[recvProc]);
504                 }
505                 {
506                     IPstream fromNbr(Pstream::scheduled, recvProc);
507                     List<T> subField(fromNbr);
508                     const labelList& map = constructMap[recvProc];
510                     checkReceivedSize(recvProc, map.size(), subField.size());
512                     forAll(map, i)
513                     {
514                         cop(newField[map[i]], subField[i]);
515                     }
516                 }
517             }
518             else
519             {
520                 // I am receive first, send next
521                 {
522                     IPstream fromNbr(Pstream::scheduled, sendProc);
523                     List<T> subField(fromNbr);
524                     const labelList& map = constructMap[sendProc];
526                     checkReceivedSize(sendProc, map.size(), subField.size());
528                     forAll(map, i)
529                     {
530                         cop(newField[map[i]], subField[i]);
531                     }
532                 }
533                 {
534                     OPstream toNbr(Pstream::scheduled, sendProc);
535                     toNbr << UIndirectList<T>(field, subMap[sendProc]);
536                 }
537             }
538         }
539         field.transfer(newField);
540     }
541     else if (commsType == Pstream::nonBlocking)
542     {
543         if (!contiguous<T>())
544         {
545             PstreamBuffers pBufs(Pstream::nonBlocking);
547             // Stream data into buffer
548             for (label domain = 0; domain < Pstream::nProcs(); domain++)
549             {
550                 const labelList& map = subMap[domain];
552                 if (domain != Pstream::myProcNo() && map.size())
553                 {
554                     // Put data into send buffer
555                     UOPstream toDomain(domain, pBufs);
556                     toDomain << UIndirectList<T>(field, map);
557                 }
558             }
560             // Start receiving
561             pBufs.finishedSends();
563             {
564                 // Set up 'send' to myself
565                 List<T> mySubField(field, subMap[Pstream::myProcNo()]);
566                 // Combine bits. Note that can reuse field storage
567                 field.setSize(constructSize);
568                 field = nullValue;
569                 // Receive sub field from myself
570                 {
571                     const labelList& map = constructMap[Pstream::myProcNo()];
573                     forAll(map, i)
574                     {
575                         cop(field[map[i]], mySubField[i]);
576                     }
577                 }
578             }
581             // Wait till all finished
582             UPstream::waitRequests();
584             // Consume
585             for (label domain = 0; domain < Pstream::nProcs(); domain++)
586             {
587                 const labelList& map = constructMap[domain];
589                 if (domain != Pstream::myProcNo() && map.size())
590                 {
591                     UIPstream str(domain, pBufs);
592                     List<T> recvField(str);
594                     checkReceivedSize(domain, map.size(), recvField.size());
596                     forAll(map, i)
597                     {
598                         cop(field[map[i]], recvField[i]);
599                     }
600                 }
601             }
602         }
603         else
604         {
605             // Set up sends to neighbours
607             List<List<T > > sendFields(Pstream::nProcs());
609             for (label domain = 0; domain < Pstream::nProcs(); domain++)
610             {
611                 const labelList& map = subMap[domain];
613                 if (domain != Pstream::myProcNo() && map.size())
614                 {
615                     List<T>& subField = sendFields[domain];
616                     subField.setSize(map.size());
617                     forAll(map, i)
618                     {
619                         subField[i] = field[map[i]];
620                     }
622                     OPstream::write
623                     (
624                         Pstream::nonBlocking,
625                         domain,
626                         reinterpret_cast<const char*>(subField.begin()),
627                         subField.size()*sizeof(T)
628                     );
629                 }
630             }
632             // Set up receives from neighbours
634             List<List<T > > recvFields(Pstream::nProcs());
636             for (label domain = 0; domain < Pstream::nProcs(); domain++)
637             {
638                 const labelList& map = constructMap[domain];
640                 if (domain != Pstream::myProcNo() && map.size())
641                 {
642                     recvFields[domain].setSize(map.size());
643                     UIPstream::read
644                     (
645                         Pstream::nonBlocking,
646                         domain,
647                         reinterpret_cast<char*>(recvFields[domain].begin()),
648                         recvFields[domain].size()*sizeof(T)
649                     );
650                 }
651             }
653             // Set up 'send' to myself
655             {
656                 const labelList& map = subMap[Pstream::myProcNo()];
658                 List<T>& subField = sendFields[Pstream::myProcNo()];
659                 subField.setSize(map.size());
660                 forAll(map, i)
661                 {
662                     subField[i] = field[map[i]];
663                 }
664             }
667             // Combine bits. Note that can reuse field storage
669             field.setSize(constructSize);
670             field = nullValue;
672             // Receive sub field from myself (subField)
673             {
674                 const labelList& map = constructMap[Pstream::myProcNo()];
675                 const List<T>& subField = sendFields[Pstream::myProcNo()];
677                 forAll(map, i)
678                 {
679                     cop(field[map[i]], subField[i]);
680                 }
681             }
684             // Wait for all to finish
686             Pstream::waitRequests();
688             // Collect neighbour fields
690             for (label domain = 0; domain < Pstream::nProcs(); domain++)
691             {
692                 const labelList& map = constructMap[domain];
694                 if (domain != Pstream::myProcNo() && map.size())
695                 {
696                     const List<T>& subField = recvFields[domain];
698                     checkReceivedSize(domain, map.size(), subField.size());
700                     forAll(map, i)
701                     {
702                         cop(field[map[i]], subField[i]);
703                     }
704                 }
705             }
706         }
707     }
708     else
709     {
710         FatalErrorIn("mapDistribute::distribute(..)")
711             << "Unknown communication schedule " << commsType
712             << abort(FatalError);
713     }
717 template<class T>
718 void Foam::mapDistribute::send(PstreamBuffers& pBufs, const List<T>& field)
719 const
721     // Stream data into buffer
722     for (label domain = 0; domain < Pstream::nProcs(); domain++)
723     {
724         const labelList& map = subMap_[domain];
726         if (map.size())
727         {
728             // Put data into send buffer
729             UOPstream toDomain(domain, pBufs);
730             toDomain << UIndirectList<T>(field, map);
731         }
732     }
734     // Start sending and receiving but do not block.
735     pBufs.finishedSends(false);
739 template<class T>
740 void Foam::mapDistribute::receive(PstreamBuffers& pBufs, List<T>& field) const
742     // Consume
743     field.setSize(constructSize_);
745     for (label domain = 0; domain < Pstream::nProcs(); domain++)
746     {
747         const labelList& map = constructMap_[domain];
749         if (map.size())
750         {
751             UIPstream str(domain, pBufs);
752             List<T> recvField(str);
754             if (recvField.size() != map.size())
755             {
756                 FatalErrorIn
757                 (
758                     "template<class T>\n"
759                     "void mapDistribute::receive\n"
760                     "(\n"
761                     "    PstreamBuffers&,\n"
762                     "    List<T>&\n"
763                     ")\n"
764                 )   << "Expected from processor " << domain
765                     << " " << map.size() << " but received "
766                     << recvField.size() << " elements."
767                     << abort(FatalError);
768             }
770             forAll(map, i)
771             {
772                 field[map[i]] = recvField[i];
773             }
774         }
775     }
779 // In case of no transform: copy elements
780 template<class T>
781 void Foam::mapDistribute::applyDummyTransforms(List<T>& field) const
783     forAll(transformElements_, trafoI)
784     {
785         const labelList& elems = transformElements_[trafoI];
787         label n = transformStart_[trafoI];
789         forAll(elems, i)
790         {
791             field[n++] = field[elems[i]];
792         }
793     }
797 // In case of no transform: copy elements
798 template<class T>
799 void Foam::mapDistribute::applyDummyInverseTransforms(List<T>& field) const
801     forAll(transformElements_, trafoI)
802     {
803         const labelList& elems = transformElements_[trafoI];
804         label n = transformStart_[trafoI];
806         forAll(elems, i)
807         {
808             field[elems[i]] = field[n++];
809         }
810     }
814 // Calculate transformed elements.
815 template<class T, class TransformOp>   //, class CombineOp>
816 void Foam::mapDistribute::applyTransforms
818     const globalIndexAndTransform& globalTransforms,
819     List<T>& field,
820     const TransformOp& top
821 ) const
823     const List<vectorTensorTransform>& totalTransform =
824         globalTransforms.transformPermutations();
826     forAll(totalTransform, trafoI)
827     {
828         const vectorTensorTransform& vt = totalTransform[trafoI];
829         const labelList& elems = transformElements_[trafoI];
830         label n = transformStart_[trafoI];
832         // Could be optimised to avoid memory allocations
833         List<T> transformFld(UIndirectList<T>(field, elems));
834         top(vt, true, transformFld);
836         forAll(transformFld, i)
837         {
838             //cop(field[n++], transformFld[i]);
839             field[n++] = transformFld[i];
840         }
841     }
845 // Calculate transformed elements.
846 template<class T, class TransformOp>   //, class CombineOp>
847 void Foam::mapDistribute::applyInverseTransforms
849     const globalIndexAndTransform& globalTransforms,
850     List<T>& field,
851     const TransformOp& top
852 ) const
854     const List<vectorTensorTransform>& totalTransform =
855         globalTransforms.transformPermutations();
857     forAll(totalTransform, trafoI)
858     {
859         const vectorTensorTransform& vt = totalTransform[trafoI];
860         const labelList& elems = transformElements_[trafoI];
861         label n = transformStart_[trafoI];
863         // Could be optimised to avoid memory allocations
864         List<T> transformFld(SubList<T>(field, elems.size(), n));
865         top(vt, false, transformFld);
867         forAll(transformFld, i)
868         {
869             //cop(field[elems[i]], transformFld[i]);
870             field[elems[i]] = transformFld[i];
871         }
872     }
876 //- Distribute data using default commsType.
877 template<class T>
878 void Foam::mapDistribute::distribute
880     List<T>& fld,
881     const bool dummyTransform
882 ) const
884     if (Pstream::defaultCommsType == Pstream::nonBlocking)
885     {
886         distribute
887         (
888             Pstream::nonBlocking,
889             List<labelPair>(),
890             constructSize_,
891             subMap_,
892             constructMap_,
893             fld
894         );
895     }
896     else if (Pstream::defaultCommsType == Pstream::scheduled)
897     {
898         distribute
899         (
900             Pstream::scheduled,
901             schedule(),
902             constructSize_,
903             subMap_,
904             constructMap_,
905             fld
906         );
907     }
908     else
909     {
910         distribute
911         (
912             Pstream::blocking,
913             List<labelPair>(),
914             constructSize_,
915             subMap_,
916             constructMap_,
917             fld
918         );
919     }
921     //- Fill in transformed slots with copies
922     if (dummyTransform)
923     {
924         applyDummyTransforms(fld);
925     }
929 //- Reverse distribute data using default commsType.
930 template<class T>
931 void Foam::mapDistribute::reverseDistribute
933     const label constructSize,
934     List<T>& fld,
935     const bool dummyTransform
936 ) const
938     if (dummyTransform)
939     {
940         applyDummyInverseTransforms(fld);
941     }
943     if (Pstream::defaultCommsType == Pstream::nonBlocking)
944     {
945         distribute
946         (
947             Pstream::nonBlocking,
948             List<labelPair>(),
949             constructSize,
950             constructMap_,
951             subMap_,
952             fld
953         );
954     }
955     else if (Pstream::defaultCommsType == Pstream::scheduled)
956     {
957         distribute
958         (
959             Pstream::scheduled,
960             schedule(),
961             constructSize,
962             constructMap_,
963             subMap_,
964             fld
965         );
966     }
967     else
968     {
969         distribute
970         (
971             Pstream::blocking,
972             List<labelPair>(),
973             constructSize,
974             constructMap_,
975             subMap_,
976             fld
977         );
978     }
982 //- Reverse distribute data using default commsType.
983 //  Since constructSize might be larger than supplied size supply
984 //  a nullValue
985 template<class T>
986 void Foam::mapDistribute::reverseDistribute
988     const label constructSize,
989     const T& nullValue,
990     List<T>& fld,
991     const bool dummyTransform
992 ) const
994     if (dummyTransform)
995     {
996         applyDummyInverseTransforms(fld);
997     }
999     if (Pstream::defaultCommsType == Pstream::nonBlocking)
1000     {
1001         distribute
1002         (
1003             Pstream::nonBlocking,
1004             List<labelPair>(),
1005             constructSize,
1006             constructMap_,
1007             subMap_,
1008             fld,
1009             eqOp<T>(),
1010             nullValue
1011         );
1012     }
1013     else if (Pstream::defaultCommsType == Pstream::scheduled)
1014     {
1015         distribute
1016         (
1017             Pstream::scheduled,
1018             schedule(),
1019             constructSize,
1020             constructMap_,
1021             subMap_,
1022             fld,
1023             eqOp<T>(),
1024             nullValue
1025         );
1026     }
1027     else
1028     {
1029         distribute
1030         (
1031             Pstream::blocking,
1032             List<labelPair>(),
1033             constructSize,
1034             constructMap_,
1035             subMap_,
1036             fld,
1037             eqOp<T>(),
1038             nullValue
1039         );
1040     }
1044 //- Distribute data using default commsType.
1045 template<class T, class TransformOp>
1046 void Foam::mapDistribute::distribute
1048     const globalIndexAndTransform& git,
1049     List<T>& fld,
1050     const TransformOp& top
1051 ) const
1053     // Distribute. Leave out dummy transforms since we're doing them ourselves
1054     distribute(fld, false);
1055     // Do transforms
1056     applyTransforms(git, fld, top);
1060 template<class T, class TransformOp>
1061 void Foam::mapDistribute::reverseDistribute
1063     const globalIndexAndTransform& git,
1064     const label constructSize,
1065     List<T>& fld,
1066     const TransformOp& top
1067 ) const
1069     // Fill slots with reverse-transformed data. Note that it also copies
1070     // back into the non-remote part of fld even though these values are not
1071     // used.
1072     applyInverseTransforms(git, fld, top);
1074     // And send back (the remote slots). Disable dummy transformations.
1075     reverseDistribute(constructSize, fld, false);
1079 template<class T, class TransformOp>
1080 void Foam::mapDistribute::reverseDistribute
1082     const globalIndexAndTransform& git,
1083     const label constructSize,
1084     const T& nullValue,
1085     List<T>& fld,
1086     const TransformOp& top
1087 ) const
1089     // Fill slots with reverse-transformed data Note that it also copies
1090     // back into the non-remote part of fld even though these values are not
1091     // used.
1092     applyInverseTransforms(git, fld, top);   //, eqOp<T>());
1094     // And send back (the remote slots) Disable dummy transformations.
1095     reverseDistribute(constructSize, nullValue, fld, false);
1099 // ************************************************************************* //