cyclicAMIGAMGInterface.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2019,2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
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 "AMIInterpolation.H"
30 #include "cyclicAMIGAMGInterface.H"
32 #include "Map.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  defineTypeNameAndDebug(cyclicAMIGAMGInterface, 0);
40  (
41  GAMGInterface,
42  cyclicAMIGAMGInterface,
43  lduInterface
44  );
46  (
47  GAMGInterface,
48  cyclicAMIGAMGInterface,
49  Istream
50  );
51 }
52 
53 
54 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
55 
56 Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
57 (
58  const label index,
59  const lduInterfacePtrsList& coarseInterfaces,
60  const lduInterface& fineInterface,
61  const labelField& localRestrictAddressing,
62  const labelField& neighbourRestrictAddressing,
63  const label fineLevelIndex,
64  const label coarseComm
65 )
66 :
68  (
69  index,
70  coarseInterfaces
71  ),
72  neighbPatchID_
73  (
74  refCast<const cyclicAMILduInterface>(fineInterface).neighbPatchID()
75  ),
76  owner_
77  (
78  refCast<const cyclicAMILduInterface>(fineInterface).owner()
79  ),
80  forwardT_
81  (
82  refCast<const cyclicAMILduInterface>(fineInterface).forwardT()
83  ),
84  reverseT_
85  (
86  refCast<const cyclicAMILduInterface>(fineInterface).reverseT()
87  )
88 {
89  const auto& fineCyclicAMIInterface =
90  refCast<const cyclicAMILduInterface>(fineInterface);
91 
92  // Construct face agglomeration from cell agglomeration
93  {
94  // From coarse face to cell
95  DynamicList<label> dynFaceCells(localRestrictAddressing.size());
96 
97  // From face to coarse face
98  DynamicList<label> dynFaceRestrictAddressing
99  (
100  localRestrictAddressing.size()
101  );
102 
103  Map<label> masterToCoarseFace(localRestrictAddressing.size());
104 
105  for (const label curMaster : localRestrictAddressing)
106  {
107  const auto iter = masterToCoarseFace.cfind(curMaster);
108 
109  if (iter.good())
110  {
111  // Already have coarse face
112  dynFaceRestrictAddressing.append(iter.val());
113  }
114  else
115  {
116  // New coarse face
117  const label coarseI = dynFaceCells.size();
118  dynFaceRestrictAddressing.append(coarseI);
119  dynFaceCells.append(curMaster);
120  masterToCoarseFace.insert(curMaster, coarseI);
121  }
122  }
123 
124  faceCells_.transfer(dynFaceCells);
125  faceRestrictAddressing_.transfer(dynFaceRestrictAddressing);
126  }
127 
128 
129  // On the owner side construct the AMI
130 
131  if (fineCyclicAMIInterface.owner())
132  {
133  // Construct the neighbour side agglomeration (as the neighbour would
134  // do it so it the exact loop above using neighbourRestrictAddressing
135  // instead of localRestrictAddressing)
136 
137  labelList nbrFaceRestrictAddressing;
138  {
139  // From face to coarse face
140  DynamicList<label> dynNbrFaceRestrictAddressing
141  (
142  neighbourRestrictAddressing.size()
143  );
144 
145  Map<label> masterToCoarseFace(neighbourRestrictAddressing.size());
146 
147  for (const label curMaster : neighbourRestrictAddressing)
148  {
149  const auto iter = masterToCoarseFace.cfind(curMaster);
150 
151  if (iter.good())
152  {
153  // Already have coarse face
154  dynNbrFaceRestrictAddressing.append(iter.val());
155  }
156  else
157  {
158  // New coarse face
159  const label coarseI = masterToCoarseFace.size();
160  dynNbrFaceRestrictAddressing.append(coarseI);
161  masterToCoarseFace.insert(curMaster, coarseI);
162  }
163  }
164 
165  nbrFaceRestrictAddressing.transfer(dynNbrFaceRestrictAddressing);
166  }
167 
168 
169  amiPtr_.reset
170  (
172  (
173  fineCyclicAMIInterface.AMI(),
175  nbrFaceRestrictAddressing
176  )
177  );
178 
179 
180  const auto& AMI = amiPtr_();
181  if (debug & 2)
182  {
183  const auto oldWarnComm = UPstream::warnComm;
185 
186  const label myRank = UPstream::myProcNo(AMI.comm());
187  Pout<< "At level:" << fineLevelIndex
188  << " agglomerating from ownsize:"
189  << fineInterface.faceCells().size()
190  << " nbrSize:" << neighbourRestrictAddressing.size()
191  << " down to ownsize:" << AMI.srcAddress().size()
192  << " nbrsize:" << AMI.tgtAddress().size()
193  << " Patch:" << index << " comm:" << AMI.comm()
194  << " nProcs:" << UPstream::nProcs(AMI.comm())
195  << " myRank:" << myRank << " agglomerated AMI:"
196  << endl;
197 
198  const label nbrSize = AMI.tgtAddress().size();
199  // From from nbr to owner side
200  {
201  Pout<< "From nbr:" << nbrSize << " to owner:" << this->size()
202  << endl;
203 
204  const auto& addresses = AMI.srcAddress();
205  const auto& weights = AMI.srcWeights();
206 
207  labelList globalIDs(identity(nbrSize));
208  if (AMI.distributed())
209  {
210  const auto& map = AMI.tgtMap();
211  forAll(map.subMap(), proci)
212  {
213  Pout<< " TGTMap: sending to rank:" << proci
214  << " elements:" << flatOutput(map.subMap()[proci])
215  << endl;
216  }
217  forAll(map.constructMap(), proci)
218  {
219  Pout<< " TGTMap: receiving from rank:" << proci
220  << " elements:"
221  << flatOutput(map.constructMap()[proci])
222  << endl;
223  }
224  // Fetch remote global IDs
225  const globalIndex globalFaces(nbrSize, AMI.comm());
226  Pout<< " localNbrSize:" << nbrSize
227  << " globalSize:" << globalFaces.totalSize() << endl;
228 
229  //const label myOffset = globalFaces.offsets()[myRank];
230  for (label& id : globalIDs)
231  {
232  id = globalFaces.toGlobal(myRank, id);
233  }
234  map.distribute(globalIDs);
235  }
236 
237  // Renumber my slots so they are now global face numbers
238  forAll(addresses, facei)
239  {
240  Pout<< " source face:" << facei
241  << " have weights:"
242  << flatOutput(weights[facei])
243  << " from slots:" << flatOutput(addresses[facei])
244  << " from global tgt faces:"
245  << UIndirectList<label>(globalIDs, addresses[facei])
246  << endl;
247  }
248  }
249  // From from owner to nbr side
250  {
251  Pout<< "From owner:" << this->size() << " to nbr:" << nbrSize
252  << endl;
253 
254  const auto& addresses = AMI.tgtAddress();
255  const auto& weights = AMI.tgtWeights();
256 
257  labelList globalIDs(identity(this->size()));
258  if (AMI.distributed())
259  {
260  const auto& map = AMI.srcMap();
261  forAll(map.subMap(), proci)
262  {
263  Pout<< " SRCMap: sending to rank:" << proci
264  << " elements:" << flatOutput(map.subMap()[proci])
265  << endl;
266  }
267  forAll(map.constructMap(), proci)
268  {
269  Pout<< " SRCMap: receiving from rank:" << proci
270  << " elements:"
271  << flatOutput(map.constructMap()[proci])
272  << endl;
273  }
274  // Fetch remote global IDs
275  const globalIndex globalFaces(this->size(), AMI.comm());
276  Pout<< " localSize:" << this->size()
277  << " globalSize:" << globalFaces.totalSize() << endl;
278 
279  for (label& id : globalIDs)
280  {
281  id = globalFaces.toGlobal(myRank, id);
282  }
283  map.distribute(globalIDs);
284  }
285 
286  // Renumber my slots so they are now global face numbers
287  forAll(addresses, facei)
288  {
289  Pout<< " target face:" << facei
290  << " have weights:"
291  << flatOutput(weights[facei])
292  << " from slots:" << flatOutput(addresses[facei])
293  << " from global src faces:"
294  << UIndirectList<label>(globalIDs, addresses[facei])
295  << endl;
296  }
297  }
298  Pout<< "DONE agglomerating at level:" << fineLevelIndex << endl;
299 
300  UPstream::warnComm = oldWarnComm;
301  }
302  }
303 }
304 
305 
306 Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
307 (
308  const label index,
309  const lduInterfacePtrsList& coarseInterfaces,
310  Istream& is
311 )
312 :
313  GAMGInterface(index, coarseInterfaces, is),
314  neighbPatchID_(readLabel(is)),
315  owner_(readBool(is)),
316  forwardT_(is),
317  reverseT_(is)
318 {
319  const bool hasAMI(readBool(is));
320 
321  if (hasAMI)
322  {
323  amiPtr_.reset(new AMIPatchToPatchInterpolation(is));
324  }
325 }
326 
327 
328 Foam::cyclicAMIGAMGInterface::cyclicAMIGAMGInterface
329 (
330  const label index,
331  const lduInterfacePtrsList& coarseInterfaces,
332  const lduInterface& fineInterface,
333  const labelList& interfaceMap,
334  const labelUList& faceCells,
335  const labelUList& faceRestrictAddresssing,
336  const labelUList& faceOffsets,
337  const lduInterfacePtrsList& allInterfaces,
338  const label coarseComm,
339  const label myProcNo,
340  const labelList& procAgglomMap
341 )
342 :
343  GAMGInterface
344  (
345  index,
346  coarseInterfaces,
347  faceCells,
348  faceRestrictAddresssing
349  ),
350  neighbPatchID_
351  (
352  interfaceMap.find
353  (
354  refCast
355  <
356  const cyclicAMILduInterface
357  >(fineInterface).neighbPatchID()
358  )
359  ),
360  owner_
361  (
362  refCast<const cyclicAMILduInterface>(fineInterface).owner()
363  ),
364  forwardT_
365  (
366  refCast<const cyclicAMILduInterface>(fineInterface).forwardT()
367  ),
368  reverseT_
369  (
370  refCast<const cyclicAMILduInterface>(fineInterface).reverseT()
371  )
372 {
373  const auto& fineCyclicAMIInterface =
374  refCast<const cyclicAMIGAMGInterface>(fineInterface);
375 
376  if (fineCyclicAMIInterface.amiPtr_)
377  {
378  const auto& fineAMI = const_cast<AMIPatchToPatchInterpolation&>
379  (
380  fineCyclicAMIInterface.AMI()
381  );
382 
383  label singlePatchProc = fineAMI.singlePatchProc();
384 
385 
386 
387  // Get some sizes
388  label nSrc = 0;
389  label nTgt = 0;
390  bool hasSrcMagSf = false;
391  bool hasSrcCentroids = false;
392  bool hasTgtMagSf = false;
393 
394  forAll(allInterfaces, inti)
395  {
396  if (allInterfaces.set(inti))
397  {
398  const auto& intf =
399  refCast<const cyclicAMIGAMGInterface>(allInterfaces[inti]);
400  const auto& AMI = intf.AMI();
401  nSrc += AMI.srcAddress().size();
402  nTgt += AMI.tgtAddress().size();
403 
404  if (AMI.srcMagSf().size())
405  {
406  hasSrcMagSf = true;
407  if (AMI.srcMagSf().size() != AMI.srcAddress().size())
408  {
410  << "srcMagSf size:" << AMI.srcMagSf().size()
411  << "srcAddress size:" << AMI.srcAddress().size()
412  << exit(FatalError);
413  }
414  }
415  if (AMI.srcCentroids().size())
416  {
417  hasSrcCentroids = true;
418  if (AMI.srcCentroids().size() != AMI.srcAddress().size())
419  {
421  << "srcCentroids size:" << AMI.srcCentroids().size()
422  << "srcAddress size:" << AMI.srcAddress().size()
423  << exit(FatalError);
424  }
425  }
426  if (AMI.tgtMagSf().size())
427  {
428  hasTgtMagSf = true;
429  if (AMI.tgtMagSf().size() != AMI.tgtAddress().size())
430  {
432  << "tgtMagSf size:" << AMI.tgtMagSf().size()
433  << "tgtAddress size:" << AMI.tgtAddress().size()
434  << exit(FatalError);
435  }
436  }
437  }
438  }
439 
440 
441  labelListList srcAddress;
442  scalarListList srcWeights;
443  scalarList srcMagSf;
444  // Needed?
445  pointListList srcCentroids;
446 
447  labelListList tgtAddress;
448  scalarListList tgtWeights;
449  scalarList tgtMagSf;
450 
451 
452  // Map to send src side data to tgt side
453  autoPtr<mapDistribute> srcToTgtMap;
454 
455  // Map to send tgt side data to src side
456  autoPtr<mapDistribute> tgtToSrcMap;
457 
458  if (fineAMI.distributed())
459  {
460  // Create combined maps
461  UPtrList<const mapDistribute> srcMaps(allInterfaces.size());
462  UPtrList<const mapDistribute> tgtMaps(allInterfaces.size());
463  forAll(allInterfaces, inti)
464  {
465  if (allInterfaces.set(inti))
466  {
467  const auto& intf = refCast<const cyclicAMIGAMGInterface>
468  (
469  allInterfaces[inti]
470  );
471  const auto& AMI = intf.AMI();
472  srcMaps.set(inti, &AMI.srcMap());
473  tgtMaps.set(inti, &AMI.tgtMap());
474  }
475  }
476 
477 
478  // Find ranks that agglomerate together
479  const label myAgglom =
480  procAgglomMap[UPstream::myProcNo(fineAMI.comm())];
481 
482  // Invert procAgglomMap
483  const labelListList newToOldRanks
484  (
486  (
487  UPstream::nProcs(coarseComm),
488  procAgglomMap
489  )
490  );
491  const labelList& localRanks = newToOldRanks[myAgglom];
492 
493 
494  // Offsets for slots into results of srcToTgtMap
495  labelList srcStartOfLocal;
496  List<Map<label>> srcCompactMaps;
497 
498  srcToTgtMap.reset
499  (
500  new mapDistribute
501  (
502  srcMaps,
503  localRanks, // per src map which rank it is from
504  coarseComm,
505  newToOldRanks, // destination rank to source ranks
506  srcStartOfLocal,
507  srcCompactMaps
508  )
509  );
510 
511  // Assemble tgtAddress
512  tgtAddress.setSize(nTgt);
513  if (tgtAddress.size())
514  {
515  label alli = 0;
516  forAll(allInterfaces, inti)
517  {
518  if (allInterfaces.set(inti))
519  {
520  const auto& intf = refCast<const cyclicAMIGAMGInterface>
521  (
522  allInterfaces[inti]
523  );
524  const auto& AMI = intf.AMI();
525  const auto& tgtSlots = AMI.tgtAddress();
526  const label localSize =
527  srcStartOfLocal[inti+1]
528  - srcStartOfLocal[inti];
529 
530  forAll(tgtSlots, tgti)
531  {
532  // Append old slots: copy old values and adapt
533  auto& newSlots = tgtAddress[alli++];
534  newSlots = tgtSlots[tgti];
535 
536  // Renumber to new indices
538  (
539  newSlots,
540  localSize,
541  srcStartOfLocal[inti],
542  srcCompactMaps[inti],
543  AMI.srcMap().constructHasFlip() //hasFlip
544  );
545 
546  for (const label slot : newSlots)
547  {
548  if
549  (
550  slot < 0
551  || slot >= srcToTgtMap().constructSize()
552  )
553  {
554  FatalErrorInFunction << " newSlots:"
555  << newSlots << exit(FatalError);
556  }
557  }
558  }
559  }
560  }
561 
562  if (nTgt != alli)
563  {
564  FatalErrorInFunction << "nTgt:" << nTgt
565  << " alli:" << alli << exit(FatalError);
566  }
567  }
568 
569  // Offsets for slots into results of tgtToSrcMap
570  labelList tgtStartOfLocal;
571  List<Map<label>> tgtCompactMaps;
572 
573  tgtToSrcMap.reset
574  (
575  new mapDistribute
576  (
577  tgtMaps,
578  localRanks,
579  coarseComm,
580  newToOldRanks,
581  tgtStartOfLocal,
582  tgtCompactMaps
583  )
584  );
585 
586  // Assemble srcAddress
587  srcAddress.setSize(nSrc);
588  if (srcAddress.size())
589  {
590  label alli = 0;
591  forAll(allInterfaces, inti)
592  {
593  if (allInterfaces.set(inti))
594  {
595  const auto& intf = refCast<const cyclicAMIGAMGInterface>
596  (
597  allInterfaces[inti]
598  );
599  const auto& AMI = intf.AMI();
600  const auto& srcSlots = AMI.srcAddress();
601  const label localSize =
602  tgtStartOfLocal[inti+1]
603  - tgtStartOfLocal[inti];
604 
605  forAll(srcSlots, srci)
606  {
607  // Append old slots: copy old values and adapt
608  auto& newSlots = srcAddress[alli++];
609  newSlots = srcSlots[srci];
610  // Renumber to new indices
612  (
613  newSlots,
614  localSize,
615  tgtStartOfLocal[inti],
616  tgtCompactMaps[inti],
617  AMI.tgtMap().constructHasFlip() //hasFlip
618  );
619 
620  for (const label slot : newSlots)
621  {
622  if
623  (
624  slot < 0
625  || slot >= tgtToSrcMap().constructSize()
626  )
627  {
628  FatalErrorInFunction << " newSlots:"
629  << newSlots << exit(FatalError);
630  }
631  }
632  }
633  }
634  }
635 
636  if (nSrc != alli)
637  {
638  FatalErrorInFunction << "nSrc:" << nSrc
639  << " alli:" << alli << exit(FatalError);
640  }
641  }
642 
643 
644  // Clean up: if no remote elements sent/received mark as
645  // non-distributed. We could do this at the start but this
646  // needs to take all the internal transport into account. Easier
647  // (but less efficient) to do afterwards now all is compacted.
648  {
649  const auto& map = srcToTgtMap().subMap();
650 
651  bool usesRemote = false;
652  forAll(map, proci)
653  {
654  if (proci != myAgglom)
655  {
656  const auto& ss = srcToTgtMap().subMap()[proci];
657  const auto& sc = srcToTgtMap().constructMap()[proci];
658  const auto& ts = tgtToSrcMap().subMap()[proci];
659  const auto& tc = tgtToSrcMap().constructMap()[proci];
660 
661  if (ss.size() || sc.size() || ts.size() || tc.size())
662  {
663  usesRemote = true;
664  break;
665  }
666  }
667  }
668 
669  if (!usesRemote)
670  {
671  //Pout<< "** making fully local on new rank "
672  // << myAgglom << " in comm:" << coarseComm << endl;
673  singlePatchProc = myAgglom;
674  srcToTgtMap.clear();
675  tgtToSrcMap.clear();
676  }
677  }
678  }
679  else
680  {
681  // src/tgt address are straight indices
682 
683  srcAddress.setSize(nSrc);
684  tgtAddress.setSize(nTgt);
685 
686  nSrc = 0;
687  nTgt = 0;
688  forAll(allInterfaces, inti)
689  {
690  if (allInterfaces.set(inti))
691  {
692  const auto& intf = refCast<const cyclicAMIGAMGInterface>
693  (
694  allInterfaces[inti]
695  );
696  const auto& AMI = intf.AMI();
697 
698  const auto& srcA = AMI.srcAddress();
699  if (srcAddress.size())
700  {
701  label srci = nSrc;
702  forAll(srcA, i)
703  {
704  srcAddress[srci++] = srcA[i]+nTgt;
705  }
706  }
707 
708  const auto& tgtA = AMI.tgtAddress();
709  if (tgtAddress.size())
710  {
711  label tgti = nTgt;
712  forAll(tgtA, i)
713  {
714  tgtAddress[tgti++] = tgtA[i]+nSrc;
715  }
716  }
717 
718  nSrc += srcA.size();
719  nTgt += tgtA.size();
720  }
721  }
722  }
723 
724  srcWeights.setSize(nSrc);
725  if (hasSrcMagSf)
726  {
727  srcMagSf.setSize(nSrc);
728  }
729  if (hasSrcCentroids)
730  {
731  srcCentroids.setSize(nSrc);
732  }
733  tgtWeights.setSize(nTgt);
734  if (hasTgtMagSf)
735  {
736  tgtMagSf.setSize(nTgt);
737  }
738 
739 
740  // Append individual data
741  nSrc = 0;
742  nTgt = 0;
743  forAll(allInterfaces, inti)
744  {
745  if (allInterfaces.set(inti))
746  {
747  const auto& intf = refCast<const cyclicAMIGAMGInterface>
748  (
749  allInterfaces[inti]
750  );
751  const auto& AMI = intf.AMI();
752 
753  const auto& srcA = AMI.srcAddress();
754  {
755  // weights
756  SubList<scalarList>(srcWeights, srcA.size(), nSrc) =
757  AMI.srcWeights();
758 
759  // magSf
760  if (hasSrcMagSf)
761  {
762  SubList<scalar>(srcMagSf, srcA.size(), nSrc) =
763  AMI.srcMagSf();
764  }
765 
766  // centroids
767  if (hasSrcCentroids)
768  {
769  SubList<pointList>(srcCentroids, srcA.size(), nSrc) =
770  AMI.srcCentroids();
771  }
772  }
773 
774  const auto& tgtA = AMI.tgtAddress();
775  {
776  // weights
777  SubList<scalarList>(tgtWeights, tgtA.size(), nTgt) =
778  AMI.tgtWeights();
779 
780  if (hasTgtMagSf)
781  {
782  SubList<scalar>(tgtMagSf, tgtA.size(), nTgt) =
783  AMI.tgtMagSf();
784  }
785  }
786 
787  nSrc += srcA.size();
788  nTgt += tgtA.size();
789  }
790  }
791 
792 
793  // Construct with same arguments as original
794  amiPtr_.reset
795  (
797  (
798  fineAMI.requireMatch(),
799  fineAMI.reverseTarget(),
800  fineAMI.lowWeightCorrection()
801  )
802  );
803  amiPtr_().comm(coarseComm),
804  amiPtr_().reset
805  (
806  std::move(srcToTgtMap),
807  std::move(tgtToSrcMap),
808  std::move(srcAddress),
809  std::move(srcWeights),
810  std::move(tgtAddress),
811  std::move(tgtWeights),
812  singlePatchProc
813  );
814  amiPtr_().srcMagSf() = std::move(srcMagSf);
815  amiPtr_().srcCentroids() = std::move(srcCentroids);
816  amiPtr_().tgtMagSf() = std::move(tgtMagSf);
817 
818 
819  if (debug & 2)
820  {
821  const auto& AMI = amiPtr_();
822 
823  const auto oldWarnComm = UPstream::warnComm;
825 
826  const label myRank = UPstream::myProcNo(AMI.comm());
827  Pout<< "PROCAGGLOMERATED :"
828  << " Patch:" << index << " comm:" << AMI.comm()
829  << " nProcs:" << UPstream::nProcs(AMI.comm())
830  << " myRank:" << myRank << " agglomerated AMI:"
831  << endl;
832 
833  const label nbrSize = AMI.tgtAddress().size();
834  // From from nbr to owner side
835  {
836  Pout<< "From nbr:" << nbrSize << " to owner:" << this->size()
837  << endl;
838 
839  const auto& addresses = AMI.srcAddress();
840  const auto& weights = AMI.srcWeights();
841 
842  labelList globalIDs(identity(nbrSize));
843  if (AMI.distributed())
844  {
845  const auto& map = AMI.tgtMap();
846  forAll(map.subMap(), proci)
847  {
848  Pout<< " TGTMap: sending to rank:" << proci
849  << " elements:" << flatOutput(map.subMap()[proci])
850  << endl;
851  }
852  forAll(map.constructMap(), proci)
853  {
854  Pout<< " TGTMap: receiving from rank:" << proci
855  << " elements:"
856  << flatOutput(map.constructMap()[proci])
857  << endl;
858  }
859 
860  // Fetch remote global IDs
861  const globalIndex globalFaces(nbrSize, AMI.comm());
862  Pout<< " localNbrSize:" << nbrSize
863  << " globalSize:" << globalFaces.totalSize() << endl;
864  for (label& id : globalIDs)
865  {
866  id = globalFaces.toGlobal(myRank, id);
867  }
868  map.distribute(globalIDs);
869  }
870 
871  // Renumber my slots so they are now global face numbers
872  forAll(addresses, facei)
873  {
874  Pout<< " source face:" << facei
875  << " have weights:"
876  << flatOutput(weights[facei])
877  << " from slots:" << flatOutput(addresses[facei])
878  << " from global tgt faces:"
879  << UIndirectList<label>(globalIDs, addresses[facei])
880  << endl;
881  }
882  }
883  // From from owner to nbr side
884  {
885  Pout<< "From owner:" << this->size() << " to nbr:" << nbrSize
886  << endl;
887 
888  const auto& addresses = AMI.tgtAddress();
889  const auto& weights = AMI.tgtWeights();
890 
891  labelList globalIDs(identity(this->size()));
892  if (AMI.distributed())
893  {
894  const auto& map = AMI.srcMap();
895  forAll(map.subMap(), proci)
896  {
897  Pout<< " SRCMap: sending to rank:" << proci
898  << " elements:" << flatOutput(map.subMap()[proci])
899  << endl;
900  }
901  forAll(map.constructMap(), proci)
902  {
903  Pout<< " SRCMap: receiving from rank:" << proci
904  << " elements:"
905  << flatOutput(map.constructMap()[proci])
906  << endl;
907  }
908 
909  // Fetch remote global IDs
910  const globalIndex globalFaces(this->size(), AMI.comm());
911  Pout<< " localSize:" << this->size()
912  << " globalSize:" << globalFaces.totalSize() << endl;
913  for (label& id : globalIDs)
914  {
915  id = globalFaces.toGlobal(myRank, id);
916  }
917  map.distribute(globalIDs);
918  }
919 
920  // Renumber my slots so they are now global face numbers
921  forAll(addresses, facei)
922  {
923  Pout<< " target face:" << facei
924  << " have weights:"
925  << flatOutput(weights[facei])
926  << " from slots:" << flatOutput(addresses[facei])
927  << " from global src faces:"
928  << UIndirectList<label>(globalIDs, addresses[facei])
929  << endl;
930  }
931  }
932  Pout<< "DONE PROCAGGLOMERATED" << endl;
933  UPstream::warnComm = oldWarnComm;
934  }
935  }
936 }
937 
938 
939 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
940 
942 (
943  const Pstream::commsTypes commsType,
944  const labelUList& iF
945 ) const
946 {
947  const cyclicAMIGAMGInterface& nbr =
948  dynamic_cast<const cyclicAMIGAMGInterface&>(neighbPatch());
949  const labelUList& nbrFaceCells = nbr.faceCells();
950 
951  auto tpnf = tmp<labelField>::New(nbrFaceCells.size());
952  labelField& pnf = tpnf.ref();
953 
954  forAll(pnf, facei)
955  {
956  pnf[facei] = iF[nbrFaceCells[facei]];
957  }
958 
959  return tpnf;
960 }
961 
962 
963 void Foam::cyclicAMIGAMGInterface::write(Ostream& os) const
964 {
966 
967  const bool hasAMI = amiPtr_.valid();
968 
969  os << token::SPACE << neighbPatchID_
970  << token::SPACE << owner_
971  << token::SPACE << forwardT_
972  << token::SPACE << reverseT_
973  << token::SPACE << hasAMI;
974 
975  if (hasAMI)
976  {
977  os << token::SPACE;
978  AMI().writeData(os);
979  }
980 }
981 
982 
983 // ************************************************************************* //
virtual label size() const
Return size.
List< scalar > scalarList
List of scalar.
Definition: scalarList.H:32
label find(const ListType &input, const UnaryPredicate &pred, const label start=0)
Same as ListOps::find_if.
Definition: ListOps.H:795
Field< label > labelField
Specialisation of Field<T> for label.
Definition: labelField.H:48
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
const pointListList & srcCentroids() const
Return const access to source patch face centroids.
virtual const labelUList & faceCells() const =0
Return faceCell addressing.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
commsTypes
Communications types.
Definition: UPstream.H:72
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition: List.C:326
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
const scalarListList & tgtWeights() const
Return const access to target patch weights.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
virtual tmp< labelField > internalFieldTransfer(const Pstream::commsTypes commsType, const labelUList &iF) const
Transfer and return internal field adjacent to the interface.
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:517
AMIInterpolation AMIPatchToPatchInterpolation
Patch-to-patch interpolation == Foam::AMIInterpolation.
virtual label index() const
const mapDistribute & srcMap() const
Source map - valid only if singlePatchProc = -1 This gets source data into a form to be consumed by t...
Type & refCast(U &obj)
A dynamic_cast (for references). Generates a FatalError on failed casts and uses the virtual type() m...
Definition: typeInfo.H:159
const labelListList & tgtAddress() const
Return const access to target patch addressing.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
label singlePatchProc() const noexcept
The processor holding all faces (both sides), or -1 if distributed.
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:63
labelList faceRestrictAddressing_
Face restrict addressing.
Definition: GAMGInterface.H:76
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
bool distributed() const noexcept
Distributed across processors (singlePatchProc == -1)
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
Macros for easy insertion into run-time selection tables.
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1065
An abstract base class for cyclic AMI coupled interfaces.
void setSize(const label n)
Alias for resize()
Definition: List.H:316
const List< scalar > & tgtMagSf() const
Return const access to target patch face areas.
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
Definition: ListOps.C:107
const_iterator cfind(const Key &key) const
Find and return an const_iterator set at the hashed entry.
Definition: HashTableI.H:113
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Definition: labelLists.C:44
List< scalarList > scalarListList
List of scalarList.
Definition: scalarList.H:35
Space [isspace].
Definition: token.H:131
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition: tmp.H:206
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:414
virtual void write(Ostream &) const
Write to stream.
const scalarListList & srcWeights() const
Return const access to source patch weights.
bool constructHasFlip() const noexcept
Does constructMap include a sign.
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
const List< scalar > & srcMagSf() const
Return const access to source patch face areas.
Abstract base class for GAMG agglomerated interfaces.
Definition: GAMGInterface.H:50
virtual const AMIPatchToPatchInterpolation & AMI() const
virtual void write(Ostream &) const =0
Write to stream.
An abstract base class for implicitly-coupled interfaces e.g. processor and cyclic patches...
Definition: lduInterface.H:53
labelList faceCells_
Face-cell addressing.
Definition: GAMGInterface.H:71
List< label > labelList
A List of labels.
Definition: List.H:62
const mapDistribute & tgtMap() const
Target map - valid only if singlePatchProc=-1. This gets target data into a form to be consumed by sr...
List< pointList > pointListList
List of pointList.
Definition: pointList.H:35
A class for managing temporary objects.
Definition: HashPtrTable.H:50
const labelListList & srcAddress() const
Return const access to source patch addressing.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
bool readBool(Istream &is)
Read bool from stream using Foam::Switch(Istream&)
Definition: bool.C:62
label comm() const
Communicator to use for parallel operations.
Namespace for OpenFOAM.
static label renumberMap(labelListList &mapElements, const labelUList &oldToNew, const bool hasFlip)
Helper for renumbering the (compacted) map elements using the supplied old-to-new mapping...
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225