GAMGAgglomerateLduAddressing.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 | Copyright (C) 2011-2016 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  label nFlipped = 0;
206  label nDissapear = 0;
207 
208  forAll(faceRestrictAddr, fineFacei)
209  {
210  label coarseFacei = faceRestrictAddr[fineFacei];
211 
212  if (coarseFacei >= 0)
213  {
214  // Maps to coarse face
215  label cOwn = coarseOwner[coarseFacei];
216  label cNei = coarseNeighbour[coarseFacei];
217 
218  label rmUpperAddr = restrictMap[upperAddr[fineFacei]];
219  label rmLowerAddr = restrictMap[lowerAddr[fineFacei]];
220 
221  if (cOwn == rmUpperAddr && cNei == rmLowerAddr)
222  {
223  faceFlipMap[fineFacei] = true;
224  nFlipped++;
225  }
226  else if (cOwn == rmLowerAddr && cNei == rmUpperAddr)
227  {
228  //faceFlipMap[fineFacei] = false;
229  }
230  else
231  {
233  << "problem."
234  << " fineFacei:" << fineFacei
235  << " rmUpperAddr:" << rmUpperAddr
236  << " rmLowerAddr:" << rmLowerAddr
237  << " coarseFacei:" << coarseFacei
238  << " cOwn:" << cOwn
239  << " cNei:" << cNei
240  << exit(FatalError);
241  }
242  }
243  else
244  {
245  nDissapear++;
246  }
247  }
248 
249 
250 
251  // Clear the temporary storage for the coarse cell data
252  cCellnFaces.setSize(0);
253  cCellFaces.setSize(0);
254  initCoarseNeighb.setSize(0);
255  coarseFaceMap.setSize(0);
256 
257 
258  // Create coarse-level interfaces
259 
260  // Get reference to fine-level interfaces
261  const lduInterfacePtrsList& fineInterfaces = interfaceLevel(fineLevelIndex);
262 
263  nPatchFaces_.set(fineLevelIndex, new labelList(fineInterfaces.size(), 0));
264  labelList& nPatchFaces = nPatchFaces_[fineLevelIndex];
265 
266  patchFaceRestrictAddressing_.set
267  (
268  fineLevelIndex,
269  new labelListList(fineInterfaces.size())
270  );
271  labelListList& patchFineToCoarse =
272  patchFaceRestrictAddressing_[fineLevelIndex];
273 
274 
275  // Initialise transfer of restrict addressing on the interface
276  forAll(fineInterfaces, inti)
277  {
278  if (fineInterfaces.set(inti))
279  {
280  fineInterfaces[inti].initInternalFieldTransfer
281  (
282  Pstream::nonBlocking,
283  restrictMap
284  );
285  }
286  }
287 
288  if (Pstream::parRun())
289  {
290  Pstream::waitRequests();
291  }
292 
293 
294  // Add the coarse level
295  meshLevels_.set
296  (
297  fineLevelIndex,
298  new lduPrimitiveMesh
299  (
300  nCoarseCells,
301  coarseOwner,
302  coarseNeighbour,
303  fineMesh.comm(),
304  true
305  )
306  );
307 
308  lduInterfacePtrsList coarseInterfaces(fineInterfaces.size());
309 
310  forAll(fineInterfaces, inti)
311  {
312  if (fineInterfaces.set(inti))
313  {
314  coarseInterfaces.set
315  (
316  inti,
318  (
319  inti,
320  meshLevels_[fineLevelIndex].rawInterfaces(),
321  fineInterfaces[inti],
322  fineInterfaces[inti].interfaceInternalField(restrictMap),
323  fineInterfaces[inti].internalFieldTransfer
324  (
325  Pstream::nonBlocking,
326  restrictMap
327  ),
328  fineLevelIndex,
329  fineMesh.comm()
330  ).ptr()
331  );
332 
333  nPatchFaces[inti] = coarseInterfaces[inti].faceCells().size();
334  patchFineToCoarse[inti] = refCast<const GAMGInterface>
335  (
336  coarseInterfaces[inti]
337  ).faceRestrictAddressing();
338  }
339  }
340 
341  meshLevels_[fineLevelIndex].addInterfaces
342  (
343  coarseInterfaces,
344  lduPrimitiveMesh::nonBlockingSchedule<processorGAMGInterface>
345  (
346  coarseInterfaces
347  )
348  );
349 
350 
351  if (debug & 2)
352  {
353  Pout<< "GAMGAgglomeration :"
354  << " agglomerated level " << fineLevelIndex
355  << " from nCells:" << fineMeshAddr.size()
356  << " nFaces:" << upperAddr.size()
357  << " to nCells:" << nCoarseCells
358  << " nFaces:" << nCoarseFaces
359  << endl;
360  }
361 }
362 
363 
365 (
366  const label meshComm,
367  const labelList& procAgglomMap,
368  const labelList& procIDs,
369  const label allMeshComm,
370 
371  const label levelIndex
372 )
373 {
374  const lduMesh& myMesh = meshLevels_[levelIndex-1];
375 
376 
377  label oldWarn = UPstream::warnComm;
378  UPstream::warnComm = meshComm;
379 
380 
381  procAgglomMap_.set(levelIndex, new labelList(procAgglomMap));
382  agglomProcIDs_.set(levelIndex, new labelList(procIDs));
383  procCommunicator_[levelIndex] = allMeshComm;
384 
385  // These could only be set on the master procs but it is
386  // quite convenient to also have them on the slaves
387  procCellOffsets_.set(levelIndex, new labelList(0));
388  procFaceMap_.set(levelIndex, new labelListList(0));
389  procBoundaryMap_.set(levelIndex, new labelListList(0));
390  procBoundaryFaceMap_.set(levelIndex, new labelListListList(0));
391 
392 
393  // Collect meshes
394  PtrList<lduPrimitiveMesh> otherMeshes;
395  lduPrimitiveMesh::gather(meshComm, myMesh, procIDs, otherMeshes);
396 
397  if (Pstream::myProcNo(meshComm) == procIDs[0])
398  {
399  // Combine all addressing
400 
401  labelList procFaceOffsets;
402  meshLevels_.set
403  (
404  levelIndex-1,
405  new lduPrimitiveMesh
406  (
407  allMeshComm,
408  procAgglomMap,
409 
410  procIDs,
411  myMesh,
412  otherMeshes,
413 
414  procCellOffsets_[levelIndex],
415  procFaceOffsets,
416  procFaceMap_[levelIndex],
417  procBoundaryMap_[levelIndex],
418  procBoundaryFaceMap_[levelIndex]
419  )
420  );
421  }
422 
423 
424  // Combine restrict addressing
425  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
426 
427  procAgglomerateRestrictAddressing
428  (
429  meshComm,
430  procIDs,
431  levelIndex
432  );
433 
434  if (Pstream::myProcNo(meshComm) != procIDs[0])
435  {
436  clearLevel(levelIndex);
437  }
438 
439  UPstream::warnComm = oldWarn;
440 }
441 
442 
444 (
445  const label comm,
446  const labelList& procIDs,
447  const label levelIndex
448 )
449 {
450  // Collect number of cells
451  labelList nFineCells;
452  gatherList
453  (
454  comm,
455  procIDs,
456  restrictAddressing_[levelIndex].size(),
457  nFineCells
458  );
459 
460  labelList offsets(nFineCells.size()+1);
461  {
462  offsets[0] = 0;
463  forAll(nFineCells, i)
464  {
465  offsets[i+1] = offsets[i] + nFineCells[i];
466  }
467  }
468 
469  // Combine and renumber nCoarseCells
470  labelList nCoarseCells;
471  gatherList
472  (
473  comm,
474  procIDs,
475  nCells_[levelIndex],
476  nCoarseCells
477  );
478 
479  // (cell)restrictAddressing
480  const globalIndex cellOffsetter(offsets);
481 
482  labelList procRestrictAddressing;
483  cellOffsetter.gather
484  (
485  comm,
486  procIDs,
487  restrictAddressing_[levelIndex],
488  procRestrictAddressing,
489 
490  UPstream::msgType(),
491  Pstream::nonBlocking //Pstream::scheduled
492  );
493 
494 
495  if (Pstream::myProcNo(comm) == procIDs[0])
496  {
497  labelList coarseCellOffsets(procIDs.size()+1);
498  {
499  coarseCellOffsets[0] = 0;
500  forAll(procIDs, i)
501  {
502  coarseCellOffsets[i+1] = coarseCellOffsets[i]+nCoarseCells[i];
503  }
504  }
505 
506  nCells_[levelIndex] = coarseCellOffsets.last();
507 
508  // Renumber consecutively
509  for (label proci = 1; proci < procIDs.size(); proci++)
510  {
511  SubList<label> procSlot
512  (
513  procRestrictAddressing,
514  offsets[proci+1]-offsets[proci],
515  offsets[proci]
516  );
517  forAll(procSlot, i)
518  {
519  procSlot[i] += coarseCellOffsets[proci];
520  }
521  }
522 
523  restrictAddressing_[levelIndex].transfer(procRestrictAddressing);
524  }
525 }
526 
527 
529 {
530  label prevLevel = curLevel - 1;
531 
532  // Set the previous level nCells to the current
533  nCells_[prevLevel] = nCells_[curLevel];
534  nFaces_[prevLevel] = nFaces_[curLevel];
535 
536  // Map the restrictAddressing from the coarser level into the previous
537  // finer level
538 
539  const labelList& curResAddr = restrictAddressing_[curLevel];
540  labelList& prevResAddr = restrictAddressing_[prevLevel];
541 
542  const labelList& curFaceResAddr = faceRestrictAddressing_[curLevel];
543  labelList& prevFaceResAddr = faceRestrictAddressing_[prevLevel];
544  const boolList& curFaceFlipMap = faceFlipMap_[curLevel];
545  boolList& prevFaceFlipMap = faceFlipMap_[prevLevel];
546 
547  forAll(prevFaceResAddr, i)
548  {
549  if (prevFaceResAddr[i] >= 0)
550  {
551  label fineFacei = prevFaceResAddr[i];
552  prevFaceResAddr[i] = curFaceResAddr[fineFacei];
553  prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
554  }
555  else
556  {
557  label fineFacei = -prevFaceResAddr[i] - 1;
558  prevFaceResAddr[i] = -curResAddr[fineFacei] - 1;
559  prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
560  }
561  }
562 
563  // Delete the restrictAddressing for the coarser level
564  faceRestrictAddressing_.set(curLevel, NULL);
565  faceFlipMap_.set(curLevel, NULL);
566 
567  forAll(prevResAddr, i)
568  {
569  prevResAddr[i] = curResAddr[prevResAddr[i]];
570  }
571 
572  const labelListList& curPatchFaceResAddr =
574  labelListList& prevPatchFaceResAddr =
575  patchFaceRestrictAddressing_[prevLevel];
576 
577  forAll(prevPatchFaceResAddr, inti)
578  {
579  const labelList& curResAddr = curPatchFaceResAddr[inti];
580  labelList& prevResAddr = prevPatchFaceResAddr[inti];
581  forAll(prevResAddr, i)
582  {
583  label fineFacei = prevResAddr[i];
584  prevResAddr[i] = curResAddr[fineFacei];
585  }
586  }
587 
588  // Delete the restrictAddressing for the coarser level
589  restrictAddressing_.set(curLevel, NULL);
590 
591  // Patch faces
592  nPatchFaces_[prevLevel] = nPatchFaces_[curLevel];
593 
594 
595 
596  // Adapt the restrict addressing for the patches
597  const lduInterfacePtrsList& curInterLevel =
598  meshLevels_[curLevel].rawInterfaces();
599  const lduInterfacePtrsList& prevInterLevel =
600  meshLevels_[prevLevel].rawInterfaces();
601 
602  forAll(prevInterLevel, inti)
603  {
604  if (prevInterLevel.set(inti))
605  {
606  GAMGInterface& prevInt = refCast<GAMGInterface>
607  (
608  const_cast<lduInterface&>
609  (
610  prevInterLevel[inti]
611  )
612  );
613  const GAMGInterface& curInt = refCast<const GAMGInterface>
614  (
615  curInterLevel[inti]
616  );
617  prevInt.combine(curInt);
618  }
619  }
620 
621  // Delete the matrix addressing and coefficients from the previous level
622  // and replace with the corresponding entry from the coarser level
623  meshLevels_.set(prevLevel, meshLevels_.set(curLevel, NULL));
624 }
625 
626 
627 //void Foam::GAMGAgglomeration::gatherList
628 //(
629 // const label comm,
630 // const labelList& procIDs,
631 //
632 // const label myVal,
633 // labelList& vals,
634 // const int tag
635 //)
636 //{
637 // vals.setSize(procIDs.size());
638 //
639 // if (Pstream::myProcNo(comm) == procIDs[0])
640 // {
641 // vals[0] = myVal;
642 //
643 // for (label i=1; i<procIDs.size(); i++)
644 // {
645 // label& slaveVal = vals[i];
646 // IPstream::read
647 // (
648 // Pstream::scheduled,
649 // procIDs[i],
650 // reinterpret_cast<char*>(&slaveVal),
651 // sizeof(slaveVal),
652 // tag,
653 // comm
654 // );
655 // }
656 // }
657 // else
658 // {
659 // OPstream::write
660 // (
661 // Pstream::scheduled,
662 // procIDs[0],
663 // reinterpret_cast<const char*>(&myVal),
664 // sizeof(myVal),
665 // tag,
666 // comm
667 // );
668 // }
669 //}
670 
671 
673 (
674  const label comm,
675  const labelList& procAgglomMap,
676  labelList& masterProcs,
677  List<label>& agglomProcIDs
678 )
679 {
680  // Determine the master processors
681  Map<label> agglomToMaster(procAgglomMap.size());
682 
683  forAll(procAgglomMap, proci)
684  {
685  label coarseI = procAgglomMap[proci];
686 
687  Map<label>::iterator fnd = agglomToMaster.find(coarseI);
688  if (fnd == agglomToMaster.end())
689  {
690  agglomToMaster.insert(coarseI, proci);
691  }
692  else
693  {
694  fnd() = min(fnd(), proci);
695  }
696  }
697 
698  masterProcs.setSize(agglomToMaster.size());
699  forAllConstIter(Map<label>, agglomToMaster, iter)
700  {
701  masterProcs[iter.key()] = iter();
702  }
703 
704 
705  // Collect all the processors in my agglomeration
706  label myProcID = Pstream::myProcNo(comm);
707  label myAgglom = procAgglomMap[myProcID];
708 
709  // Get all processors agglomerating to the same coarse
710  // processor
711  agglomProcIDs = findIndices(procAgglomMap, myAgglom);
712  // Make sure the master is the first element.
713  label index = findIndex
714  (
715  agglomProcIDs,
716  agglomToMaster[myAgglom]
717  );
718  Swap(agglomProcIDs[0], agglomProcIDs[index]);
719 }
720 
721 
722 // ************************************************************************* //
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:106
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
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::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:76
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:417
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition: lduMesh.H:59
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:440
virtual label comm() const =0
Return communicator used for parallel communication.
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 findIndices(const ListType &, typename ListType::const_reference, const label start=0)
Find all occurences of given element. Linear search.
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tdf1, const word &name, const dimensionSet &dimensions)
List< bool > boolList
Bool container classes.
Definition: boolList.H:50
iterator find(const Key &)
Find and return an iterator set at the hashedEntry.
Definition: HashTable.C:138
bool set(const label) const
Is element set.
Definition: UPtrListI.H:78
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
A List obtained as a section of another List.
Definition: SubList.H:53
void Swap(T &a, T &b)
Definition: Swap.H:43
label size() const
Return number of equations.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
Simplest contrete lduMesh which stores the addressing needed by lduMatrix.
virtual const lduAddressing & lduAddr() const =0
Return ldu addressing.
List< label > labelList
A List of labels.
Definition: labelList.H:56
labelList nCells_
The number of cells in each level.
forAllConstIter(PtrDictionary< phaseModel >, mixture.phases(), phase)
Definition: pEqn.H:29
errorManip< error > abort(error &err)
Definition: errorManip.H:131
labelList nFaces_
The number of (coarse) faces in each level.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: HashTable.H:60
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
void agglomerateLduAddressing(const label fineLevelIndex)
Assemble coarse mesh addressing.
prefixOSstream Pout(cout,"Pout")
Definition: IOstreams.H:53
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurence of given element and return index,.
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Abstract base class for GAMG agglomerated interfaces.
Definition: GAMGInterface.H:51
void combine(const GAMGInterface &)
Merge the next level with this level.
Definition: GAMGInterface.C:56
label size() const
Return the number of elements in the UList.
Definition: UListI.H:299
void setSize(const label)
Reset size of List.
Definition: List.C:295
void procAgglomerateRestrictAddressing(const label comm, const labelList &procIDs, const label levelIndex)
Collect and combine basic restriction addressing:
A templated 1D list of pointers to objects of type <T>, where the size of the array is known and used...
Definition: List.H:62
List< labelListList > labelListListList
A List of labelListList.
Definition: labelList.H:58
An abstract base class for implicitly-coupled interfaces e.g. processor and cyclic patches...
Definition: lduInterface.H:53
The class contains the addressing required by the lduMatrix: upper, lower and losort.
PtrList< boolList > faceFlipMap_
Face flip: for faces mapped to internal faces stores whether.
T & last()
Return the last element of the list.
Definition: UListI.H:128
static void calculateRegionMaster(const label comm, const labelList &procAgglomMap, labelList &masterProcs, List< label > &agglomProcIDs)
Given fine to coarse processor map determine:
void combineLevels(const label curLevel)
Combine a level with the previous one.
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29