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-2018 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::commsTypes::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::commsTypes::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  procAgglomMap_.set(levelIndex, new labelList(procAgglomMap));
378  agglomProcIDs_.set(levelIndex, new labelList(procIDs));
379  procCommunicator_[levelIndex] = allMeshComm;
380 
381  // These could only be set on the master procs but it is
382  // quite convenient to also have them on the slaves
383  procCellOffsets_.set(levelIndex, new labelList(0));
384  procFaceMap_.set(levelIndex, new labelListList(0));
385  procBoundaryMap_.set(levelIndex, new labelListList(0));
386  procBoundaryFaceMap_.set(levelIndex, new labelListListList(0));
387 
388 
389  // Collect meshes
390  PtrList<lduPrimitiveMesh> otherMeshes;
391  lduPrimitiveMesh::gather(meshComm, myMesh, procIDs, otherMeshes);
392 
393  if (Pstream::myProcNo(meshComm) == procIDs[0])
394  {
395  // Combine all addressing
396 
397  labelList procFaceOffsets;
398  meshLevels_.set
399  (
400  levelIndex-1,
401  new lduPrimitiveMesh
402  (
403  allMeshComm,
404  procAgglomMap,
405 
406  procIDs,
407  myMesh,
408  otherMeshes,
409 
410  procCellOffsets_[levelIndex],
411  procFaceOffsets,
412  procFaceMap_[levelIndex],
413  procBoundaryMap_[levelIndex],
414  procBoundaryFaceMap_[levelIndex]
415  )
416  );
417  }
418 
419 
420  // Combine restrict addressing
421  // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
422 
423  procAgglomerateRestrictAddressing
424  (
425  meshComm,
426  procIDs,
427  levelIndex
428  );
429 
430  if (Pstream::myProcNo(meshComm) != procIDs[0])
431  {
432  clearLevel(levelIndex);
433  }
434 }
435 
436 
438 (
439  const label comm,
440  const labelList& procIDs,
441  const label levelIndex
442 )
443 {
444  // Collect number of cells
445  labelList nFineCells;
446  gatherList
447  (
448  comm,
449  procIDs,
450  restrictAddressing_[levelIndex].size(),
451  nFineCells
452  );
453 
454  labelList offsets(nFineCells.size()+1);
455  {
456  offsets[0] = 0;
457  forAll(nFineCells, i)
458  {
459  offsets[i+1] = offsets[i] + nFineCells[i];
460  }
461  }
462 
463  // Combine and renumber nCoarseCells
464  labelList nCoarseCells;
465  gatherList
466  (
467  comm,
468  procIDs,
469  nCells_[levelIndex],
470  nCoarseCells
471  );
472 
473  // (cell)restrictAddressing
474  const globalIndex cellOffsetter(offsets);
475 
476  labelList procRestrictAddressing;
477  cellOffsetter.gather
478  (
479  comm,
480  procIDs,
481  restrictAddressing_[levelIndex],
482  procRestrictAddressing,
483 
484  UPstream::msgType(),
485  Pstream::commsTypes::nonBlocking // Pstream::commsTypes::scheduled
486  );
487 
488 
489  if (Pstream::myProcNo(comm) == procIDs[0])
490  {
491  labelList coarseCellOffsets(procIDs.size()+1);
492  {
493  coarseCellOffsets[0] = 0;
494  forAll(procIDs, i)
495  {
496  coarseCellOffsets[i+1] = coarseCellOffsets[i]+nCoarseCells[i];
497  }
498  }
499 
500  nCells_[levelIndex] = coarseCellOffsets.last();
501 
502  // Renumber consecutively
503  for (label proci = 1; proci < procIDs.size(); proci++)
504  {
505  SubList<label> procSlot
506  (
507  procRestrictAddressing,
508  offsets[proci+1]-offsets[proci],
509  offsets[proci]
510  );
511  forAll(procSlot, i)
512  {
513  procSlot[i] += coarseCellOffsets[proci];
514  }
515  }
516 
517  restrictAddressing_[levelIndex].transfer(procRestrictAddressing);
518  }
519 }
520 
521 
523 {
524  label prevLevel = curLevel - 1;
525 
526  // Set the previous level nCells to the current
527  nCells_[prevLevel] = nCells_[curLevel];
528  nFaces_[prevLevel] = nFaces_[curLevel];
529 
530  // Map the restrictAddressing from the coarser level into the previous
531  // finer level
532 
533  const labelList& curResAddr = restrictAddressing_[curLevel];
534  labelList& prevResAddr = restrictAddressing_[prevLevel];
535 
536  const labelList& curFaceResAddr = faceRestrictAddressing_[curLevel];
537  labelList& prevFaceResAddr = faceRestrictAddressing_[prevLevel];
538  const boolList& curFaceFlipMap = faceFlipMap_[curLevel];
539  boolList& prevFaceFlipMap = faceFlipMap_[prevLevel];
540 
541  forAll(prevFaceResAddr, i)
542  {
543  if (prevFaceResAddr[i] >= 0)
544  {
545  label fineFacei = prevFaceResAddr[i];
546  prevFaceResAddr[i] = curFaceResAddr[fineFacei];
547  prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
548  }
549  else
550  {
551  label fineFacei = -prevFaceResAddr[i] - 1;
552  prevFaceResAddr[i] = -curResAddr[fineFacei] - 1;
553  prevFaceFlipMap[i] = curFaceFlipMap[fineFacei];
554  }
555  }
556 
557  // Delete the restrictAddressing for the coarser level
558  faceRestrictAddressing_.set(curLevel, nullptr);
559  faceFlipMap_.set(curLevel, nullptr);
560 
561  forAll(prevResAddr, i)
562  {
563  prevResAddr[i] = curResAddr[prevResAddr[i]];
564  }
565 
566  const labelListList& curPatchFaceResAddr =
568  labelListList& prevPatchFaceResAddr =
569  patchFaceRestrictAddressing_[prevLevel];
570 
571  forAll(prevPatchFaceResAddr, inti)
572  {
573  const labelList& curResAddr = curPatchFaceResAddr[inti];
574  labelList& prevResAddr = prevPatchFaceResAddr[inti];
575  forAll(prevResAddr, i)
576  {
577  label fineFacei = prevResAddr[i];
578  prevResAddr[i] = curResAddr[fineFacei];
579  }
580  }
581 
582  // Delete the restrictAddressing for the coarser level
583  restrictAddressing_.set(curLevel, nullptr);
584 
585  // Patch faces
586  nPatchFaces_[prevLevel] = nPatchFaces_[curLevel];
587 
588 
589 
590  // Adapt the restrict addressing for the patches
591  const lduInterfacePtrsList& curInterLevel =
592  meshLevels_[curLevel].rawInterfaces();
593  const lduInterfacePtrsList& prevInterLevel =
594  meshLevels_[prevLevel].rawInterfaces();
595 
596  forAll(prevInterLevel, inti)
597  {
598  if (prevInterLevel.set(inti))
599  {
600  GAMGInterface& prevInt = refCast<GAMGInterface>
601  (
602  const_cast<lduInterface&>
603  (
604  prevInterLevel[inti]
605  )
606  );
607  const GAMGInterface& curInt = refCast<const GAMGInterface>
608  (
609  curInterLevel[inti]
610  );
611  prevInt.combine(curInt);
612  }
613  }
614 
615  // Delete the matrix addressing and coefficients from the previous level
616  // and replace with the corresponding entry from the coarser level
617  meshLevels_.set(prevLevel, meshLevels_.set(curLevel, nullptr));
618 }
619 
620 
621 //void Foam::GAMGAgglomeration::gatherList
622 //(
623 // const label comm,
624 // const labelList& procIDs,
625 //
626 // const label myVal,
627 // labelList& vals,
628 // const int tag
629 //)
630 //{
631 // vals.setSize(procIDs.size());
632 //
633 // if (Pstream::myProcNo(comm) == procIDs[0])
634 // {
635 // vals[0] = myVal;
636 //
637 // for (label i=1; i<procIDs.size(); i++)
638 // {
639 // label& slaveVal = vals[i];
640 // IPstream::read
641 // (
642 // Pstream::commsTypes::scheduled,
643 // procIDs[i],
644 // reinterpret_cast<char*>(&slaveVal),
645 // sizeof(slaveVal),
646 // tag,
647 // comm
648 // );
649 // }
650 // }
651 // else
652 // {
653 // OPstream::write
654 // (
655 // Pstream::commsTypes::scheduled,
656 // procIDs[0],
657 // reinterpret_cast<const char*>(&myVal),
658 // sizeof(myVal),
659 // tag,
660 // comm
661 // );
662 // }
663 //}
664 
665 
667 (
668  const label comm,
669  const labelList& procAgglomMap,
670  labelList& masterProcs,
671  List<label>& agglomProcIDs
672 )
673 {
674  // Determine the master processors
675  Map<label> agglomToMaster(procAgglomMap.size());
676 
677  forAll(procAgglomMap, proci)
678  {
679  label coarseI = procAgglomMap[proci];
680 
681  Map<label>::iterator fnd = agglomToMaster.find(coarseI);
682  if (fnd == agglomToMaster.end())
683  {
684  agglomToMaster.insert(coarseI, proci);
685  }
686  else
687  {
688  fnd() = min(fnd(), proci);
689  }
690  }
691 
692  masterProcs.setSize(agglomToMaster.size());
693  forAllConstIter(Map<label>, agglomToMaster, iter)
694  {
695  masterProcs[iter.key()] = iter();
696  }
697 
698 
699  // Collect all the processors in my agglomeration
700  label myProcID = Pstream::myProcNo(comm);
701  label myAgglom = procAgglomMap[myProcID];
702 
703  // Get all processors agglomerating to the same coarse
704  // processor
705  agglomProcIDs = findIndices(procAgglomMap, myAgglom);
706  // Make sure the master is the first element.
707  label index = findIndex
708  (
709  agglomProcIDs,
710  agglomToMaster[myAgglom]
711  );
712  Swap(agglomProcIDs[0], agglomProcIDs[index]);
713 }
714 
715 
716 // ************************************************************************* //
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:57
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
autoPtr< CompressibleMomentumTransportModel > New(const volScalarField &rho, const volVectorField &U, const surfaceScalarField &phi, const viscosity &viscosity)
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:112
error FatalError
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]).
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
#define forAllConstIter(Container, container, iter)
Iterate across all elements in the container object of type.
Definition: UList.H:477
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:429
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
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:446
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 occurrences 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.
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:142
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
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.
layerAndWeight min(const layerAndWeight &a, const layerAndWeight &b)
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.
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.
bool set(const label) const
Is element set.
Definition: UPtrListI.H:78
label findIndex(const ListType &, typename ListType::const_reference, const label start=0)
Find first occurrence of given element and return index,.
Abstract base class for GAMG agglomerated interfaces.
Definition: GAMGInterface.H:51
label size() const
Return the number of elements in the UPtrList.
Definition: UPtrListI.H:29
void combine(const GAMGInterface &)
Merge the next level with this level.
Definition: GAMGInterface.C:56
void setSize(const label)
Reset size of List.
Definition: List.C:281
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:70
List< labelListList > labelListListList
A List of labelListList.
Definition: labelList.H:58
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
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
label size() const
Return the number of elements in the UList.
Definition: UListI.H:311
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 number of equations.