GAMGAgglomerateLduAddressing.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
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.
15 
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.
20 
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/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "GAMGAgglomeration.H"
27 #include "GAMGInterface.H"
28 #include "processorGAMGInterface.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
33 (
34  const label fineLevelIndex
35 )
36 {
37  const lduMesh& fineMesh = meshLevel(fineLevelIndex);
38  const lduAddressing& fineMeshAddr = fineMesh.lduAddr();
39 
40  const labelUList& upperAddr = fineMeshAddr.upperAddr();
41  const labelUList& lowerAddr = fineMeshAddr.lowerAddr();
42 
43  label nFineFaces = upperAddr.size();
44 
45  // Get restriction map for current level
46  const labelField& restrictMap = restrictAddressing(fineLevelIndex);
47 
48  if (min(restrictMap) == -1)
49  {
51  << "min(restrictMap) == -1" << exit(FatalError);
52  }
53 
54  if (restrictMap.size() != fineMeshAddr.size())
55  {
57  << "restrict map does not correspond to fine level. " << endl
58  << " Sizes: restrictMap: " << restrictMap.size()
59  << " nEqns: " << fineMeshAddr.size()
60  << abort(FatalError);
61  }
62 
63 
64  // Get the number of coarse cells
65  const label nCoarseCells = nCells_[fineLevelIndex];
66 
67  // Storage for coarse cell neighbours and coefficients
68 
69  // Guess initial maximum number of neighbours in coarse cell
70  label maxNnbrs = 10;
71 
72  // Number of faces for each coarse-cell
73  labelList cCellnFaces(nCoarseCells, 0);
74 
75  // Setup initial packed storage for coarse-cell faces
76  labelList cCellFaces(maxNnbrs*nCoarseCells);
77 
78  // Create face-restriction addressing
79  faceRestrictAddressing_.set(fineLevelIndex, new labelList(nFineFaces));
80  labelList& faceRestrictAddr = faceRestrictAddressing_[fineLevelIndex];
81 
82  // Initial neighbour array (not in upper-triangle order)
83  labelList initCoarseNeighb(nFineFaces);
84 
85  // Counter for coarse faces
86  label& nCoarseFaces = nFaces_[fineLevelIndex];
87  nCoarseFaces = 0;
88 
89  // Loop through all fine faces
90  forAll(upperAddr, fineFacei)
91  {
92  label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
93  label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
94 
95  if (rmUpperAddr == rmLowerAddr)
96  {
97  // For each fine face inside of a coarse cell keep the address
98  // of the cell corresponding to the face in the faceRestrictAddr
99  // as a negative index
100  faceRestrictAddr[fineFacei] = -(rmUpperAddr + 1);
101  }
102  else
103  {
104  // this face is a part of a coarse face
105 
106  label cOwn = rmUpperAddr;
107  label cNei = rmLowerAddr;
108 
109  // get coarse owner and neighbour
110  if (rmUpperAddr > rmLowerAddr)
111  {
112  cOwn = rmLowerAddr;
113  cNei = rmUpperAddr;
114  }
115 
116  // check the neighbour to see if this face has already been found
117  label* ccFaces = &cCellFaces[maxNnbrs*cOwn];
118 
119  bool nbrFound = false;
120  label& ccnFaces = cCellnFaces[cOwn];
121 
122  for (int i=0; i<ccnFaces; i++)
123  {
124  if (initCoarseNeighb[ccFaces[i]] == cNei)
125  {
126  nbrFound = true;
127  faceRestrictAddr[fineFacei] = ccFaces[i];
128  break;
129  }
130  }
131 
132  if (!nbrFound)
133  {
134  if (ccnFaces >= maxNnbrs)
135  {
136  label oldMaxNnbrs = maxNnbrs;
137  maxNnbrs *= 2;
138 
139  cCellFaces.setSize(maxNnbrs*nCoarseCells);
140 
141  forAllReverse(cCellnFaces, i)
142  {
143  label* oldCcNbrs = &cCellFaces[oldMaxNnbrs*i];
144  label* newCcNbrs = &cCellFaces[maxNnbrs*i];
145 
146  for (int j=0; j<cCellnFaces[i]; j++)
147  {
148  newCcNbrs[j] = oldCcNbrs[j];
149  }
150  }
151 
152  ccFaces = &cCellFaces[maxNnbrs*cOwn];
153  }
154 
155  ccFaces[ccnFaces] = nCoarseFaces;
156  initCoarseNeighb[nCoarseFaces] = cNei;
157  faceRestrictAddr[fineFacei] = nCoarseFaces;
158  ccnFaces++;
159 
160  // new coarse face created
161  nCoarseFaces++;
162  }
163  }
164  } // end for all fine faces
165 
166 
167  // Renumber into upper-triangular order
168 
169  // All coarse owner-neighbour storage
170  labelList coarseOwner(nCoarseFaces);
171  labelList coarseNeighbour(nCoarseFaces);
172  labelList coarseFaceMap(nCoarseFaces);
173 
174  label coarseFacei = 0;
175 
176  forAll(cCellnFaces, cci)
177  {
178  label* cFaces = &cCellFaces[maxNnbrs*cci];
179  label ccnFaces = cCellnFaces[cci];
180 
181  for (int i=0; i<ccnFaces; i++)
182  {
183  coarseOwner[coarseFacei] = cci;
184  coarseNeighbour[coarseFacei] = initCoarseNeighb[cFaces[i]];
185  coarseFaceMap[cFaces[i]] = coarseFacei;
186  coarseFacei++;
187  }
188  }
189 
190  forAll(faceRestrictAddr, fineFacei)
191  {
192  if (faceRestrictAddr[fineFacei] >= 0)
193  {
194  faceRestrictAddr[fineFacei] =
195  coarseFaceMap[faceRestrictAddr[fineFacei]];
196  }
197  }
198 
199 
200  // Create face-flip status
201  faceFlipMap_.set(fineLevelIndex, new boolList(nFineFaces, false));
202  boolList& faceFlipMap = faceFlipMap_[fineLevelIndex];
203 
204 
205  forAll(faceRestrictAddr, fineFacei)
206  {
207  label coarseFacei = faceRestrictAddr[fineFacei];
208 
209  if (coarseFacei >= 0)
210  {
211  // Maps to coarse face
212  label cOwn = coarseOwner[coarseFacei];
213  label cNei = coarseNeighbour[coarseFacei];
214 
215  label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
216  label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
217 
218  if (cOwn == rmUpperAddr && cNei == rmLowerAddr)
219  {
220  faceFlipMap[fineFacei] = true;
221  }
222  else if (cOwn == rmLowerAddr && cNei == rmUpperAddr)
223  {
224  // faceFlipMap[fineFacei] = false;
225  }
226  else
227  {
229  << "problem."
230  << " fineFacei:" << fineFacei
231  << " rmUpperAddr:" << rmUpperAddr
232  << " rmLowerAddr:" << rmLowerAddr
233  << " coarseFacei:" << coarseFacei
234  << " cOwn:" << cOwn
235  << " cNei:" << cNei
236  << exit(FatalError);
237  }
238  }
239  }
240 
241 
242 
243  // Clear the temporary storage for the coarse cell data
244  cCellnFaces.setSize(0);
245  cCellFaces.setSize(0);
246  initCoarseNeighb.setSize(0);
247  coarseFaceMap.setSize(0);
248 
249 
250  // Create coarse-level interfaces
251 
252  // Get reference to fine-level interfaces
253  const lduInterfacePtrsList& fineInterfaces = interfaceLevel(fineLevelIndex);
254 
255  nPatchFaces_.set(fineLevelIndex, new labelList(fineInterfaces.size(), 0));
256  labelList& nPatchFaces = nPatchFaces_[fineLevelIndex];
257 
259  (
260  fineLevelIndex,
261  new labelListList(fineInterfaces.size())
262  );
263  labelListList& patchFineToCoarse =
264  patchFaceRestrictAddressing_[fineLevelIndex];
265 
266 
267  // Initialise transfer of restrict addressing on the interface
268  forAll(fineInterfaces, inti)
269  {
270  if (fineInterfaces.set(inti))
271  {
272  fineInterfaces[inti].initInternalFieldTransfer
273  (
275  restrictMap
276  );
277  }
278  }
279 
280  if (Pstream::parRun())
281  {
283  }
284 
285 
286  // Add the coarse level
287  meshLevels_.set
288  (
289  fineLevelIndex,
290  new lduPrimitiveMesh
291  (
292  nCoarseCells,
293  coarseOwner,
294  coarseNeighbour,
295  fineMesh.comm(),
296  true
297  )
298  );
299 
300  lduInterfacePtrsList coarseInterfaces(fineInterfaces.size());
301 
302  forAll(fineInterfaces, inti)
303  {
304  if (fineInterfaces.set(inti))
305  {
306  coarseInterfaces.set
307  (
308  inti,
310  (
311  inti,
312  meshLevels_[fineLevelIndex].rawInterfaces(),
313  fineInterfaces[inti],
314  fineInterfaces[inti].interfaceInternalField(restrictMap),
315  fineInterfaces[inti].internalFieldTransfer
316  (
318  restrictMap
319  ),
320  fineLevelIndex,
321  fineMesh.comm()
322  ).ptr()
323  );
324 
325  nPatchFaces[inti] = coarseInterfaces[inti].faceCells().size();
326  patchFineToCoarse[inti] = refCast<const GAMGInterface>
327  (
328  coarseInterfaces[inti]
329  ).faceRestrictAddressing();
330  }
331  }
332 
333  meshLevels_[fineLevelIndex].addInterfaces
334  (
335  coarseInterfaces,
336  lduPrimitiveMesh::nonBlockingSchedule<processorGAMGInterface>
337  (
338  coarseInterfaces
339  )
340  );
341 
342 
343  if (debug & 2)
344  {
345  Pout<< "GAMGAgglomeration :"
346  << " agglomerated level " << fineLevelIndex
347  << " from nCells:" << fineMeshAddr.size()
348  << " nFaces:" << upperAddr.size()
349  << " to nCells:" << nCoarseCells
350  << " nFaces:" << nCoarseFaces
351  << endl;
352  }
353 }
354 
355 
357 (
358  const label meshComm,
359  const labelList& procAgglomMap,
360  const labelList& procIDs,
361  const label allMeshComm,
362 
363  const label levelIndex
364 )
365 {
366  const lduMesh& myMesh = meshLevels_[levelIndex-1];
367 
368 
369  procAgglomMap_.set(levelIndex, new labelList(procAgglomMap));
370  agglomProcIDs_.set(levelIndex, new labelList(procIDs));
371  procCommunicator_[levelIndex] = allMeshComm;
372 
373  // These could only be set on the master procs but it is
374  // quite convenient to also have them on the slaves
375  procCellOffsets_.set(levelIndex, new labelList(0));
376  procFaceMap_.set(levelIndex, new labelListList(0));
377  procBoundaryMap_.set(levelIndex, new labelListList(0));
378  procBoundaryFaceMap_.set(levelIndex, new labelListListList(0));
379 
380 
381  // Collect meshes
382  PtrList<lduPrimitiveMesh> otherMeshes;
383  lduPrimitiveMesh::gather(meshComm, myMesh, procIDs, otherMeshes);
384 
385  if (Pstream::myProcNo(meshComm) == procIDs[0])
386  {
387  // Combine all addressing
388 
389  labelList procFaceOffsets;
390  meshLevels_.set
391  (
392  levelIndex-1,
393  new lduPrimitiveMesh
394  (
395  allMeshComm,
396  procAgglomMap,
397 
398  procIDs,
399  myMesh,
400  otherMeshes,
401 
402  procCellOffsets_[levelIndex],
403  procFaceOffsets,
404  procFaceMap_[levelIndex],
405  procBoundaryMap_[levelIndex],
406  procBoundaryFaceMap_[levelIndex]
407  )
408  );
409  }
410 
411 
412  // Combine restrict addressing
413  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
414 
415  procAgglomerateRestrictAddressing
416  (
417  meshComm,
418  procIDs,
419  levelIndex
420  );
421 
422  if (Pstream::myProcNo(meshComm) != procIDs[0])
423  {
424  clearLevel(levelIndex);
425  }
426 }
427 
428 
430 (
431  const label comm,
432  const labelList& procIDs,
433  const label levelIndex
434 )
435 {
436  // Collect number of cells
437  labelList nFineCells;
438  gatherList
439  (
440  comm,
441  procIDs,
442  restrictAddressing_[levelIndex].size(),
443  nFineCells
444  );
445 
446  labelList offsets(nFineCells.size()+1);
447  {
448  offsets[0] = 0;
449  forAll(nFineCells, i)
450  {
451  offsets[i+1] = offsets[i] + nFineCells[i];
452  }
453  }
454 
455  // Combine and renumber nCoarseCells
456  labelList nCoarseCells;
457  gatherList
458  (
459  comm,
460  procIDs,
461  nCells_[levelIndex],
462  nCoarseCells
463  );
464 
465  // (cell)restrictAddressing
466  const globalIndex cellOffsetter(offsets);
467 
468  labelList procRestrictAddressing;
469  cellOffsetter.gather
470  (
471  comm,
472  procIDs,
473  restrictAddressing_[levelIndex],
474  procRestrictAddressing,
475 
477  Pstream::commsTypes::nonBlocking // Pstream::commsTypes::scheduled
478  );
479 
480 
481  if (Pstream::myProcNo(comm) == procIDs[0])
482  {
483  labelList coarseCellOffsets(procIDs.size()+1);
484  {
485  coarseCellOffsets[0] = 0;
486  forAll(procIDs, i)
487  {
488  coarseCellOffsets[i+1] = coarseCellOffsets[i]+nCoarseCells[i];
489  }
490  }
491 
492  nCells_[levelIndex] = coarseCellOffsets.last();
493 
494  // Renumber consecutively
495  for (label proci = 1; proci < procIDs.size(); proci++)
496  {
497  SubList<label> procSlot
498  (
499  procRestrictAddressing,
500  offsets[proci+1]-offsets[proci],
501  offsets[proci]
502  );
503  forAll(procSlot, i)
504  {
505  procSlot[i] += coarseCellOffsets[proci];
506  }
507  }
508 
509  restrictAddressing_[levelIndex].transfer(procRestrictAddressing);
510  }
511 }
512 
513 
515 {
516  label prevLevel = curLevel - 1;
517 
518  // Set the previous level nCells to the current
519  nCells_[prevLevel] = nCells_[curLevel];
520  nFaces_[prevLevel] = nFaces_[curLevel];
521 
522  // Map the restrictAddressing from the coarser level into the previous
523  // finer level
524 
525  const labelList& curResAddr = restrictAddressing_[curLevel];
526  labelList& prevResAddr = restrictAddressing_[prevLevel];
527 
528  const labelList& curFaceResAddr = faceRestrictAddressing_[curLevel];
529  labelList& prevFaceResAddr = faceRestrictAddressing_[prevLevel];
530  const boolList& curFaceFlipMap = faceFlipMap_[curLevel];
531  boolList& prevFaceFlipMap = faceFlipMap_[prevLevel];
532 
533  forAll(prevFaceResAddr, i)
534  {
535  if (prevFaceResAddr[i] >= 0)
536  {
537  label fineFacei = prevFaceResAddr[i];
538  prevFaceResAddr[i] = curFaceResAddr[fineFacei];
539  prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
540  }
541  else
542  {
543  label fineFacei = -prevFaceResAddr[i] - 1;
544  prevFaceResAddr[i] = -curResAddr[fineFacei] - 1;
545  prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
546  }
547  }
548 
549  // Delete the restrictAddressing for the coarser level
550  faceRestrictAddressing_.set(curLevel, nullptr);
551  faceFlipMap_.set(curLevel, nullptr);
552 
553  forAll(prevResAddr, i)
554  {
555  prevResAddr[i] = curResAddr[prevResAddr[i]];
556  }
557 
558  const labelListList& curPatchFaceResAddr =
559  patchFaceRestrictAddressing_[curLevel];
560  labelListList& prevPatchFaceResAddr =
561  patchFaceRestrictAddressing_[prevLevel];
562 
563  forAll(prevPatchFaceResAddr, inti)
564  {
565  const labelList& curResAddr = curPatchFaceResAddr[inti];
566  labelList& prevResAddr = prevPatchFaceResAddr[inti];
567  forAll(prevResAddr, i)
568  {
569  label fineFacei = prevResAddr[i];
570  prevResAddr[i] = curResAddr[fineFacei];
571  }
572  }
573 
574  // Delete the restrictAddressing for the coarser level
575  restrictAddressing_.set(curLevel, nullptr);
576 
577  // Patch faces
578  nPatchFaces_[prevLevel] = nPatchFaces_[curLevel];
579 
580 
581 
582  // Adapt the restrict addressing for the patches
583  const lduInterfacePtrsList& curInterLevel =
584  meshLevels_[curLevel].rawInterfaces();
585  const lduInterfacePtrsList& prevInterLevel =
586  meshLevels_[prevLevel].rawInterfaces();
587 
588  forAll(prevInterLevel, inti)
589  {
590  if (prevInterLevel.set(inti))
591  {
592  GAMGInterface& prevInt = refCast<GAMGInterface>
593  (
594  const_cast<lduInterface&>
595  (
596  prevInterLevel[inti]
597  )
598  );
599  const GAMGInterface& curInt = refCast<const GAMGInterface>
600  (
601  curInterLevel[inti]
602  );
603  prevInt.combine(curInt);
604  }
605  }
606 
607  // Delete the matrix addressing and coefficients from the previous level
608  // and replace with the corresponding entry from the coarser level
609  meshLevels_.set(prevLevel, meshLevels_.set(curLevel, nullptr));
610 }
611 
612 
613 //void Foam::GAMGAgglomeration::gatherList
614 //(
615 // const label comm,
616 // const labelList& procIDs,
617 //
618 // const label myVal,
619 // labelList& vals,
620 // const int tag
621 //)
622 //{
623 // vals.setSize(procIDs.size());
624 //
625 // if (Pstream::myProcNo(comm) == procIDs[0])
626 // {
627 // vals[0] = myVal;
628 //
629 // for (label i=1; i<procIDs.size(); i++)
630 // {
631 // label& slaveVal = vals[i];
632 // IPstream::read
633 // (
634 // Pstream::commsTypes::scheduled,
635 // procIDs[i],
636 // reinterpret_cast<char*>(&slaveVal),
637 // sizeof(slaveVal),
638 // tag,
639 // comm
640 // );
641 // }
642 // }
643 // else
644 // {
645 // OPstream::write
646 // (
647 // Pstream::commsTypes::scheduled,
648 // procIDs[0],
649 // reinterpret_cast<const char*>(&myVal),
650 // sizeof(myVal),
651 // tag,
652 // comm
653 // );
654 // }
655 //}
656 
657 
659 (
660  const label comm,
661  const labelList& procAgglomMap,
662  labelList& masterProcs,
663  List<label>& agglomProcIDs
664 )
665 {
666  // Determine the master processors
667  Map<label> agglomToMaster(procAgglomMap.size());
668 
669  forAll(procAgglomMap, proci)
670  {
671  label coarseI = procAgglomMap[proci];
672 
673  Map<label>::iterator fnd = agglomToMaster.find(coarseI);
674  if (fnd == agglomToMaster.end())
675  {
676  agglomToMaster.insert(coarseI, proci);
677  }
678  else
679  {
680  fnd() = min(fnd(), proci);
681  }
682  }
683 
684  masterProcs.setSize(agglomToMaster.size());
685  forAllConstIter(Map<label>, agglomToMaster, iter)
686  {
687  masterProcs[iter.key()] = iter();
688  }
689 
690 
691  // Collect all the processors in my agglomeration
692  label myProcID = Pstream::myProcNo(comm);
693  label myAgglom = procAgglomMap[myProcID];
694 
695  // Get all processors agglomerating to the same coarse
696  // processor
697  agglomProcIDs = findIndices(procAgglomMap, myAgglom);
698  // Make sure the master is the first element.
699  label index = findIndex
700  (
701  agglomProcIDs,
702  agglomToMaster[myAgglom]
703  );
704  Swap(agglomProcIDs[0], agglomProcIDs[index]);
705 }
706 
707 
708 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:446
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
void procAgglomerateRestrictAddressing(const label comm, const labelList &procIDs, const label levelIndex)
Collect and combine basic restriction addressing:
void agglomerateLduAddressing(const label fineLevelIndex)
Assemble coarse mesh addressing.
static void calculateRegionMaster(const label comm, const labelList &procAgglomMap, labelList &masterProcs, List< label > &agglomProcIDs)
Given fine to coarse processor map determine:
const boolList & faceFlipMap(const label leveli) const
Return face flip map of given level.
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
PtrList< boolList > faceFlipMap_
Face flip: for faces mapped to internal faces stores whether.
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
void procAgglomerateLduAddressing(const label comm, const labelList &procAgglomMap, const labelList &procIDs, const label allMeshComm, const label levelIndex)
Collect and combine processor meshes into allMesh:
labelList nFaces_
The number of (coarse) faces in each level.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
labelList nCells_
The number of cells in each level.
const labelList & nPatchFaces(const label leveli) const
Return number of coarse patch faces (before processor.
void combineLevels(const label curLevel)
Combine a level with the previous one.
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
const lduInterfacePtrsList & interfaceLevel(const label leveli) const
Return LDU interface addressing of given level.
const labelField & restrictAddressing(const label leveli) const
Return cell restrict addressing of given level.
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
Abstract base class for GAMG agglomerated interfaces.
Definition: GAMGInterface.H:54
void combine(const GAMGInterface &)
Merge the next level with this level.
Definition: GAMGInterface.C:56
static autoPtr< GAMGInterface > New(const label index, const lduInterfacePtrsList &coarseInterfaces, const lduInterface &fineInterface, const labelField &localRestrictAddressing, const labelField &neighbourRestrictAddressing, const label fineLevelIndex, const label coarseComm)
Return a pointer to a new interface created on freestore given.
label size() const
Return number of elements in table.
Definition: HashTableI.H:65
bool insert(const Key &, const T &newElmt)
Insert a new hashedEntry.
Definition: HashTableI.H:80
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:142
void transfer(List< T > &)
Transfer the contents of the argument List into this list.
Definition: List.C:342
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
void setSize(const label)
Reset size of List.
Definition: List.C:281
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: PtrList.H:75
A List obtained as a section of another List.
Definition: SubList.H:56
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
T & last()
Return the last element of the list.
Definition: UListI.H:128
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
Definition: UPstream.C:147
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:399
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:476
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
bool set(const label) const
Is element set.
Definition: UPtrListI.H:78
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:64
static void gather(const labelUList &offsets, const label comm, const labelList &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const Pstream::commsTypes commsType=Pstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
The class contains the addressing required by the lduMatrix: upper, lower and losort.
label size() const
Return number of equations.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
An abstract base class for implicitly-coupled interfaces e.g. processor and cyclic patches.
Definition: lduInterface.H:54
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition: lduMesh.H:60
virtual label comm() const =0
Return communicator used for parallel communication.
virtual const lduAddressing & lduAddr() const =0
Return ldu addressing.
Simplest concrete lduMesh which stores the addressing needed by lduMatrix.
static void gather(const label comm, const lduMesh &mesh, const labelList &procIDs, PtrList< lduPrimitiveMesh > &otherMeshes)
Gather meshes from other processors onto procIDs[0].
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
List< label > labelList
A List of labels.
Definition: labelList.H:56
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
labelList findIndices(const ListType &, typename ListType::const_reference, const label start=0)
Find all occurrences of given element. Linear search.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
List< labelListList > labelListListList
A List of labelListList.
Definition: labelList.H:58
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
error FatalError
void Swap(T &a, T &b)
Definition: Swap.H:43
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112