GAMGAgglomeration.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-2024 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 "GAMGAgglomeration.H"
30 #include "lduMesh.H"
31 #include "lduMatrix.H"
32 #include "Time.H"
33 #include "GAMGInterface.H"
34 #include "GAMGProcAgglomeration.H"
35 #include "pairGAMGAgglomeration.H"
36 #include "IOmanip.H"
37 
38 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42  defineTypeNameAndDebug(GAMGAgglomeration, 0);
43  defineRunTimeSelectionTable(GAMGAgglomeration, lduMesh);
44  defineRunTimeSelectionTable(GAMGAgglomeration, lduMatrix);
46 }
47 
48 
49 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
50 
52 (
53  const label nCreatedLevels,
54  const bool doProcessorAgglomerate
55 )
56 {
57  nCells_.setSize(nCreatedLevels, 0);
58  restrictAddressing_.setSize(nCreatedLevels);
59  nFaces_.setSize(nCreatedLevels, 0);
60  faceRestrictAddressing_.setSize(nCreatedLevels);
61  faceFlipMap_.setSize(nCreatedLevels);
62  nPatchFaces_.setSize(nCreatedLevels);
63  patchFaceRestrictAddressing_.setSize(nCreatedLevels);
64  meshLevels_.setSize(nCreatedLevels);
65 
66  // Have procCommunicator_ always, even if not procAgglomerating
67  procCommunicator_.setSize(nCreatedLevels + 1, -1);
68  if (doProcessorAgglomerate && processorAgglomerate())
69  {
70  procAgglomMap_.setSize(nCreatedLevels);
71  agglomProcIDs_.setSize(nCreatedLevels);
72  procAgglomCommunicator_.setSize(nCreatedLevels);
73  procCellOffsets_.setSize(nCreatedLevels);
74  procFaceMap_.setSize(nCreatedLevels);
75  procBoundaryMap_.setSize(nCreatedLevels);
76  procBoundaryFaceMap_.setSize(nCreatedLevels);
77 
78  procAgglomeratorPtr_().agglomerate();
79  }
80 }
81 
82 
84 {
85  Info<< "GAMGAgglomeration:" << nl
86  << " local agglomerator : " << type() << nl;
87  if (processorAgglomerate())
88  {
89  Info<< " processor agglomerator : "
90  << procAgglomeratorPtr_().type() << nl
91  << nl;
92  }
93 
94  Info<< setw(36) << "nCells"
95  << setw(20) << "nFaces/nCells"
96  << setw(20) << "nInterfaces"
97  << setw(20) << "nIntFaces/nCells"
98  << setw(12) << "profile"
99  << nl
100  << setw(8) << "Level"
101  << setw(8) << "nProcs"
102  << " "
103  << setw(8) << "avg"
104  << setw(8) << "max"
105  << " "
106  << setw(8) << "avg"
107  << setw(8) << "max"
108  << " "
109  << setw(8) << "avg"
110  << setw(8) << "max"
111  << " "
112  << setw(8) << "avg"
113  << setw(8) << "max"
114  //<< " "
115  << setw(12) << "avg"
116  << nl
117  << setw(8) << "-----"
118  << setw(8) << "------"
119  << " "
120  << setw(8) << "---"
121  << setw(8) << "---"
122  << " "
123  << setw(8) << "---"
124  << setw(8) << "---"
125  << " "
126  << setw(8) << "---"
127  << setw(8) << "---"
128  << " "
129  << setw(8) << "---"
130  << setw(8) << "---"
131  //<< " "
132  << setw(12) << "---"
133  //<< " "
134  << nl;
135 
136  const label maxSize = returnReduce(size(), maxOp<label>());
137 
138  for (label levelI = 0; levelI <= maxSize; levelI++)
139  {
140  label nProcs = 0;
141  label nCells = 0;
142  scalar faceCellRatio = 0;
143  label nInterfaces = 0;
144  label nIntFaces = 0;
145  scalar ratio = 0.0;
146  scalar profile = 0.0;
147 
148  if (hasMeshLevel(levelI))
149  {
150  nProcs = 1;
151 
152  const lduMesh& fineMesh = meshLevel(levelI);
153  nCells = fineMesh.lduAddr().size();
154  faceCellRatio =
155  scalar(fineMesh.lduAddr().lowerAddr().size())/nCells;
156 
157  const lduInterfacePtrsList interfaces =
158  fineMesh.interfaces();
159  forAll(interfaces, i)
160  {
161  if (interfaces.set(i))
162  {
163  nInterfaces++;
164  nIntFaces += interfaces[i].faceCells().size();
165  }
166  }
167  ratio = scalar(nIntFaces)/nCells;
168 
169  profile = fineMesh.lduAddr().band().second();
170  }
171 
172  label totNprocs = returnReduce(nProcs, sumOp<label>());
173 
174  label maxNCells = returnReduce(nCells, maxOp<label>());
175  label totNCells = returnReduce(nCells, sumOp<label>());
176 
177  scalar maxFaceCellRatio =
178  returnReduce(faceCellRatio, maxOp<scalar>());
179  scalar totFaceCellRatio =
180  returnReduce(faceCellRatio, sumOp<scalar>());
181 
182  label maxNInt = returnReduce(nInterfaces, maxOp<label>());
183  label totNInt = returnReduce(nInterfaces, sumOp<label>());
184 
185  scalar maxRatio = returnReduce(ratio, maxOp<scalar>());
186  scalar totRatio = returnReduce(ratio, sumOp<scalar>());
187 
188  scalar totProfile = returnReduce(profile, sumOp<scalar>());
189 
190  const int oldPrecision = Info.stream().precision(4);
191 
192  Info<< setw(8) << levelI
193  << setw(8) << totNprocs
194  << " "
195  << setw(8) << totNCells/totNprocs
196  << setw(8) << maxNCells
197  << " "
198  << setw(8) << totFaceCellRatio/totNprocs
199  << setw(8) << maxFaceCellRatio
200  << " "
201  << setw(8) << scalar(totNInt)/totNprocs
202  << setw(8) << maxNInt
203  << " "
204  << setw(8) << totRatio/totNprocs
205  << setw(8) << maxRatio
206  << setw(12) << totProfile/totNprocs
207  << nl;
208 
209  Info.stream().precision(oldPrecision);
210  }
211  Info<< endl;
212 }
213 
214 
216 (
217  const label nCellsInCoarsestLevel,
218  const label nFineCells,
219  const label nCoarseCells,
220  const label comm
221 ) const
222 {
223  const label nTotalCoarseCells =
224  returnReduce(nCoarseCells, sumOp<label>(), UPstream::msgType(), comm);
225  if (nTotalCoarseCells < Pstream::nProcs(comm)*nCellsInCoarsestLevel)
226  {
227  return false;
228  }
229  else
230  {
231  const label nTotalFineCells =
232  returnReduce(nFineCells, sumOp<label>(), UPstream::msgType(), comm);
233  return nTotalCoarseCells < nTotalFineCells;
234  }
235 }
236 
237 
238 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
239 
241 (
242  const lduMesh& mesh,
243  const dictionary& controlDict
244 )
245 :
246  MeshObject_type(mesh),
247 
248  maxLevels_(50),
249 
250  nCellsInCoarsestLevel_
251  (
252  controlDict.getOrDefault<label>("nCellsInCoarsestLevel", 10)
253  ),
254  meshInterfaces_(mesh.interfaces()),
255  procAgglomeratorPtr_
256  (
257  (
258  (UPstream::nProcs(mesh.comm()) > 1)
259  && controlDict.found("processorAgglomerator")
260  )
261  ? GAMGProcAgglomeration::New
262  (
263  controlDict.get<word>("processorAgglomerator"),
264  *this,
266  )
267  : autoPtr<GAMGProcAgglomeration>()
268  ),
269 
270  nCells_(maxLevels_),
271  restrictAddressing_(maxLevels_),
272  nFaces_(maxLevels_),
273  faceRestrictAddressing_(maxLevels_),
274  faceFlipMap_(maxLevels_),
275  nPatchFaces_(maxLevels_),
276  patchFaceRestrictAddressing_(maxLevels_),
277 
278  meshLevels_(maxLevels_)
279 {
280  // Limit the cells in the coarsest level based on the local number of
281  // cells. Note: 2 for pair-wise
284 
285  // Ensure all procs see the same nCellsInCoarsestLevel_
286  reduce(nCellsInCoarsestLevel_, minOp<label>());
287 
289  if (processorAgglomerate())
290  {
291  procAgglomMap_.setSize(maxLevels_);
292  agglomProcIDs_.setSize(maxLevels_);
294  procCellOffsets_.setSize(maxLevels_);
295  procFaceMap_.setSize(maxLevels_);
298  }
299 }
300 
301 
303 (
304  const lduMesh& mesh,
305  const dictionary& controlDict
306 )
307 {
308  const GAMGAgglomeration* agglomPtr =
309  mesh.thisDb().cfindObject<GAMGAgglomeration>
310  (
311  GAMGAgglomeration::typeName
312  );
313 
314  if (agglomPtr)
315  {
316  return *agglomPtr;
317  }
318 
319  {
320  const word agglomeratorType
321  (
322  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
323  );
324 
325  mesh.thisDb().time().libs().open
326  (
327  controlDict,
328  "geometricGAMGAgglomerationLibs",
329  lduMeshConstructorTablePtr_
330  );
331 
332  auto* ctorPtr = lduMeshConstructorTable(agglomeratorType);
333 
334  if (!ctorPtr)
335  {
337  << "Unknown GAMGAgglomeration type "
338  << agglomeratorType << ".\n"
339  << "Valid matrix GAMGAgglomeration types :"
340  << lduMatrixConstructorTablePtr_->sortedToc() << endl
341  << "Valid geometric GAMGAgglomeration types :"
342  << lduMeshConstructorTablePtr_->sortedToc()
343  << exit(FatalError);
344  }
345 
346  auto agglomPtr(ctorPtr(mesh, controlDict));
347  if (debug)
348  {
349  agglomPtr().printLevels();
350  }
351  return regIOobject::store(agglomPtr);
352  }
353 }
354 
355 
357 (
358  const lduMatrix& matrix,
359  const dictionary& controlDict
360 )
361 {
362  const lduMesh& mesh = matrix.mesh();
363 
364  const GAMGAgglomeration* agglomPtr =
365  mesh.thisDb().cfindObject<GAMGAgglomeration>
366  (
367  GAMGAgglomeration::typeName
368  );
369 
370  if (agglomPtr)
371  {
372  return *agglomPtr;
373  }
374 
375  {
376  const word agglomeratorType
377  (
378  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
379  );
380 
381  mesh.thisDb().time().libs().open
382  (
383  controlDict,
384  "algebraicGAMGAgglomerationLibs",
385  lduMatrixConstructorTablePtr_
386  );
387 
388  auto* ctorPtr = lduMatrixConstructorTable(agglomeratorType);
389 
390  if (!ctorPtr)
391  {
392  return New(mesh, controlDict);
393  }
394  else
395  {
396  auto agglomPtr(ctorPtr(matrix, controlDict));
397  if (debug)
398  {
399  agglomPtr().printLevels();
400  }
401  return regIOobject::store(agglomPtr);
402  }
403  }
404 }
405 
406 
408 (
409  const lduMesh& mesh,
410  const scalarField& cellVolumes,
411  const vectorField& faceAreas,
412  const dictionary& controlDict
413 )
414 {
415 
416  const GAMGAgglomeration* agglomPtr =
417  mesh.thisDb().cfindObject<GAMGAgglomeration>
418  (
419  GAMGAgglomeration::typeName
420  );
421 
422  if (agglomPtr)
423  {
424  return *agglomPtr;
425  }
426 
427  {
428  const word agglomeratorType
429  (
430  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
431  );
432 
433  const_cast<Time&>(mesh.thisDb().time()).libs().open
434  (
435  controlDict,
436  "geometricGAMGAgglomerationLibs",
437  geometryConstructorTablePtr_
438  );
439 
440  auto* ctorPtr = geometryConstructorTable(agglomeratorType);
441 
442  if (!ctorPtr)
443  {
445  << "Unknown GAMGAgglomeration type "
446  << agglomeratorType << ".\n"
447  << "Valid geometric GAMGAgglomeration types :"
448  << geometryConstructorTablePtr_->sortedToc()
449  << exit(FatalError);
450  }
451 
452  auto agglomPtr
453  (
454  ctorPtr
455  (
456  mesh,
457  cellVolumes,
458  faceAreas,
460  )
461  );
462  if (debug)
463  {
464  agglomPtr().printLevels();
465  }
466  return regIOobject::store(agglomPtr);
467  }
468 }
469 
470 
471 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
472 
474 {}
475 
476 
477 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
478 
480 (
481  const label i
482 ) const
483 {
484  if (i == 0)
485  {
486  return mesh_;
487  }
488  else
489  {
490  return meshLevels_[i - 1];
491  }
492 }
493 
494 
495 bool Foam::GAMGAgglomeration::hasMeshLevel(const label i) const
496 {
497  if (i == 0)
498  {
499  return true;
500  }
501  else
502  {
503  return meshLevels_.set(i - 1);
504  }
505 }
506 
507 
509 (
510  const label i
511 ) const
512 {
513  if (i == 0)
514  {
515  return meshInterfaces_;
516  }
517  else
518  {
519  return meshLevels_[i - 1].rawInterfaces();
520  }
521 }
522 
523 
524 void Foam::GAMGAgglomeration::clearLevel(const label i)
525 {
526  if (hasMeshLevel(i))
527  {
528  meshLevels_.set(i - 1, nullptr);
529 
530  if (i < nCells_.size())
531  {
532  nCells_[i] = -555;
533  restrictAddressing_.set(i, nullptr);
534  nFaces_[i] = -666;
535  faceRestrictAddressing_.set(i, nullptr);
536  faceFlipMap_.set(i, nullptr);
537  nPatchFaces_.set(i, nullptr);
538  patchFaceRestrictAddressing_.set(i, nullptr);
539  }
540  }
541 }
542 
543 
545 (
546  const label leveli
547 ) const
548 {
549  return procAgglomMap_[leveli];
550 }
551 
552 
554 (
555  const label leveli
556 ) const
557 {
558  return agglomProcIDs_[leveli];
559 }
560 
562 bool Foam::GAMGAgglomeration::hasProcMesh(const label leveli) const
563 {
564  return procCommunicator_[leveli] != -1;
565 }
566 
568 Foam::label Foam::GAMGAgglomeration::procCommunicator(const label leveli) const
569 {
570  return procCommunicator_[leveli];
571 }
572 
573 
574 Foam::label Foam::GAMGAgglomeration::agglomCommunicator(const label leveli) const
575 {
576  return procAgglomCommunicator_[leveli];
577 }
578 
579 
581 (
582  const label leveli
583 ) const
584 {
585  return procCellOffsets_[leveli];
586 }
587 
588 
590 (
591  const label leveli
592 ) const
593 {
594  return procFaceMap_[leveli];
595 }
596 
597 
599 (
600  const label leveli
601 ) const
602 {
603  return procBoundaryMap_[leveli];
604 }
605 
606 
608 (
609  const label leveli
610 ) const
611 {
612  return procBoundaryFaceMap_[leveli];
613 }
614 
615 
617 (
618  labelList& newRestrict,
619  label& nNewCoarse,
620  const lduAddressing& fineAddressing,
621  const labelUList& restriction,
622  const label nCoarse
623 )
624 {
625  if (fineAddressing.size() != restriction.size())
626  {
628  << "nCells:" << fineAddressing.size()
629  << " agglom:" << restriction.size()
630  << abort(FatalError);
631  }
632 
633  // Seed (master) for every region
634  labelList master(identity(fineAddressing.size()));
635 
636  // Now loop and transport master through region
637  const labelUList& lower = fineAddressing.lowerAddr();
638  const labelUList& upper = fineAddressing.upperAddr();
639 
640  while (true)
641  {
642  label nChanged = 0;
643 
644  forAll(lower, facei)
645  {
646  const label own = lower[facei];
647  const label nei = upper[facei];
648 
649  if (restriction[own] == restriction[nei])
650  {
651  // coarse-mesh-internal face
652 
653  if (master[own] < master[nei])
654  {
655  master[nei] = master[own];
656  nChanged++;
657  }
658  else if (master[own] > master[nei])
659  {
660  master[own] = master[nei];
661  nChanged++;
662  }
663  }
664  }
665 
666  reduce(nChanged, sumOp<label>());
667 
668  if (nChanged == 0)
669  {
670  break;
671  }
672  }
673 
674 
675  // Count number of regions/masters per coarse cell
676  labelListList coarseToMasters(nCoarse);
677  nNewCoarse = 0;
678  forAll(restriction, celli)
679  {
680  labelList& masters = coarseToMasters[restriction[celli]];
681 
682  if (!masters.found(master[celli]))
683  {
684  masters.append(master[celli]);
685  nNewCoarse++;
686  }
687  }
688 
689  if (nNewCoarse > nCoarse)
690  {
691  //WarningInFunction
692  // << "Have " << nCoarse
693  // << " agglomerated cells but " << nNewCoarse
694  // << " disconnected regions" << endl;
695 
696  // Keep coarseToMasters[0] the original coarse, allocate new ones
697  // for the others
698  labelListList coarseToNewCoarse(coarseToMasters.size());
699 
700  nNewCoarse = nCoarse;
701 
702  forAll(coarseToMasters, coarseI)
703  {
704  const labelList& masters = coarseToMasters[coarseI];
705 
706  labelList& newCoarse = coarseToNewCoarse[coarseI];
707  newCoarse.setSize(masters.size());
708  newCoarse[0] = coarseI;
709  for (label i=1; i<newCoarse.size(); i++)
710  {
711  newCoarse[i] = nNewCoarse++;
712  }
713  }
714 
715  newRestrict.setSize(fineAddressing.size());
716  forAll(restriction, celli)
717  {
718  const label coarseI = restriction[celli];
719 
720  const label index = coarseToMasters[coarseI].find(master[celli]);
721  newRestrict[celli] = coarseToNewCoarse[coarseI][index];
722  }
723 
724  return false;
725  }
726 
727  return true;
728 }
729 
730 
731 // ************************************************************************* //
autoPtr< GAMGProcAgglomeration > procAgglomeratorPtr_
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
PtrList< labelListList > procBoundaryMap_
Mapping from processor to procMeshLevel boundary.
bool hasProcMesh(const label fineLeveli) const
Check that level has combined mesh.
static bool checkRestriction(labelList &newRestrict, label &nNewCoarse, const lduAddressing &fineAddressing, const labelUList &restriction, const label nCoarse)
Given restriction determines if coarse cells are connected.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
bool continueAgglomerating(const label nCellsInCoarsestLevel, const label nCells, const label nCoarseCells, const label comm) const
Check the need for further agglomeration.
PtrList< labelListList > procFaceMap_
Mapping from processor to procMeshLevel face.
dlLibraryTable & libs() const noexcept
Mutable access to the loaded dynamic libraries.
Definition: Time.H:722
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
PtrList< labelListListList > procBoundaryFaceMap_
Mapping from processor to procMeshLevel boundary face.
GAMGAgglomeration(const GAMGAgglomeration &)=delete
No copy construct.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:608
label agglomCommunicator(const label fineLeveli) const
Communicator for collecting contributions.
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:521
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
PtrList< labelList > procCellOffsets_
Mapping from processor to procMeshLevel cells.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
const labelListList & boundaryMap(const label fineLeveli) const
Mapping from processor to procMesh boundary.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
~GAMGAgglomeration()
Destructor.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition: lduMesh.H:53
tmp< DimensionedField< TypeR, GeoMesh > > New(const tmp< DimensionedField< TypeR, GeoMesh >> &tf1, const word &name, const dimensionSet &dimensions, const bool initCopy=false)
Global function forwards to reuseTmpDimensionedField::New.
static const GAMGAgglomeration & New(const lduMesh &mesh, const dictionary &controlDict)
Return the selected geometric agglomerator.
bool store()
Register object with its registry and transfer ownership to the registry.
Definition: regIOobjectI.H:36
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1187
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1252
const Type * cfindObject(const word &name, const bool recursive=false) const
Return const pointer to the object of the given Type.
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
void clearLevel(const label leveli)
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
virtual const objectRegistry & thisDb() const
Return the object registry - resolve conflict polyMesh/lduMesh.
Definition: fvMesh.H:376
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
label procCommunicator(const label fineLeveli) const
Communicator for current level or -1.
labelList procCommunicator_
Communicator for given level.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
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:1077
void setSize(const label n)
Alias for resize()
Definition: List.H:320
dynamicFvMesh & mesh
label size() const noexcept
Return number of equations.
bool processorAgglomerate() const
Whether to agglomerate across processors.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
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
const lduMesh & mesh() const noexcept
Reference to the mesh.
Definition: MeshObject.H:255
virtual int precision() const override
Get precision of output field.
Definition: OSstream.C:334
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
const Time & time() const noexcept
Return time registry.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
PtrList< UPstream::communicator > procAgglomCommunicator_
Communicator for collecting contributions. Note self-contained.
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
const labelList & agglomProcIDs(const label fineLeveli) const
Set of processors to agglomerate. Element 0 is the master processor. (local, same only on those proce...
void printLevels() const
Print level overview.
virtual const lduAddressing & lduAddr() const =0
Return ldu addressing.
labelList nCells_
The number of cells in each level.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
runTime controlDict().readEntry("adjustTimeStep"
The central control dictionary, the contents of which are either taken directly from the FOAM_CONTROL...
Definition: debug.C:142
errorManip< error > abort(error &err)
Definition: errorManip.H:139
labelList nFaces_
The number of (coarse) faces in each level.
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
OSstream & stream(OSstream *alternative=nullptr)
Return OSstream for output operations.
Definition: messageStream.C:79
Istream and Ostream manipulators taking arguments.
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
const label maxLevels_
Max number of levels.
const labelList & cellOffsets(const label fineLeveli) const
Mapping from processor to procMesh cells.
string lower(const std::string &s)
Return string copy transformed with std::tolower on each character.
Definition: stringOps.C:1171
const labelListListList & boundaryFaceMap(const label fineLeveli) const
Mapping from processor to procMesh boundary face.
const labelList & procAgglomMap(const label fineLeveli) const
Mapping from processor to agglomerated processor (global, all processors have the same information)...
PtrList< labelList > procAgglomMap_
Per level, per processor the processor it agglomerates into.
const lduInterfacePtrsList & interfaceLevel(const label leveli) const
Return LDU interface addressing of given level.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Field< vector > vectorField
Specialisation of Field<T> for vector.
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.
Omanip< int > setw(const int i)
Definition: IOmanip.H:199
List< label > labelList
A List of labels.
Definition: List.H:62
bool open(bool verbose=true)
Open named, but unopened libraries. These names will normally have been added with push_back()...
Geometric agglomerated algebraic multigrid agglomeration class.
bool found
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
label nCellsInCoarsestLevel_
Number of cells in coarsest level.
void compactLevels(const label nCreatedLevels, const bool doProcessorAgglomerate)
Shrink the number of levels to that specified. Optionally do.
Namespace for OpenFOAM.
const labelListList & faceMap(const label fineLeveli) const
Mapping from processor to procMesh face.