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-2023 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "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  procCellOffsets_.setSize(nCreatedLevels);
73  procFaceMap_.setSize(nCreatedLevels);
74  procBoundaryMap_.setSize(nCreatedLevels);
75  procBoundaryFaceMap_.setSize(nCreatedLevels);
76 
77  procAgglomeratorPtr_().agglomerate();
78  }
79 }
80 
81 
83 {
84  Info<< "GAMGAgglomeration:" << nl
85  << " local agglomerator : " << type() << nl;
86  if (processorAgglomerate())
87  {
88  Info<< " processor agglomerator : "
89  << procAgglomeratorPtr_().type() << nl
90  << nl;
91  }
92 
93  Info<< setw(36) << "nCells"
94  << setw(20) << "nFaces/nCells"
95  << setw(20) << "nInterfaces"
96  << setw(20) << "nIntFaces/nCells"
97  << setw(12) << "profile"
98  << nl
99  << setw(8) << "Level"
100  << setw(8) << "nProcs"
101  << " "
102  << setw(8) << "avg"
103  << setw(8) << "max"
104  << " "
105  << setw(8) << "avg"
106  << setw(8) << "max"
107  << " "
108  << setw(8) << "avg"
109  << setw(8) << "max"
110  << " "
111  << setw(8) << "avg"
112  << setw(8) << "max"
113  //<< " "
114  << setw(12) << "avg"
115  << nl
116  << setw(8) << "-----"
117  << setw(8) << "------"
118  << " "
119  << setw(8) << "---"
120  << setw(8) << "---"
121  << " "
122  << setw(8) << "---"
123  << setw(8) << "---"
124  << " "
125  << setw(8) << "---"
126  << setw(8) << "---"
127  << " "
128  << setw(8) << "---"
129  << setw(8) << "---"
130  //<< " "
131  << setw(12) << "---"
132  //<< " "
133  << nl;
134 
135  const label maxSize = returnReduce(size(), maxOp<label>());
136 
137  for (label levelI = 0; levelI <= maxSize; levelI++)
138  {
139  label nProcs = 0;
140  label nCells = 0;
141  scalar faceCellRatio = 0;
142  label nInterfaces = 0;
143  label nIntFaces = 0;
144  scalar ratio = 0.0;
145  scalar profile = 0.0;
146 
147  if (hasMeshLevel(levelI))
148  {
149  nProcs = 1;
150 
151  const lduMesh& fineMesh = meshLevel(levelI);
152  nCells = fineMesh.lduAddr().size();
153  faceCellRatio =
154  scalar(fineMesh.lduAddr().lowerAddr().size())/nCells;
155 
156  const lduInterfacePtrsList interfaces =
157  fineMesh.interfaces();
158  forAll(interfaces, i)
159  {
160  if (interfaces.set(i))
161  {
162  nInterfaces++;
163  nIntFaces += interfaces[i].faceCells().size();
164  }
165  }
166  ratio = scalar(nIntFaces)/nCells;
167 
168  profile = fineMesh.lduAddr().band().second();
169  }
170 
171  label totNprocs = returnReduce(nProcs, sumOp<label>());
172 
173  label maxNCells = returnReduce(nCells, maxOp<label>());
174  label totNCells = returnReduce(nCells, sumOp<label>());
175 
176  scalar maxFaceCellRatio =
177  returnReduce(faceCellRatio, maxOp<scalar>());
178  scalar totFaceCellRatio =
179  returnReduce(faceCellRatio, sumOp<scalar>());
180 
181  label maxNInt = returnReduce(nInterfaces, maxOp<label>());
182  label totNInt = returnReduce(nInterfaces, sumOp<label>());
183 
184  scalar maxRatio = returnReduce(ratio, maxOp<scalar>());
185  scalar totRatio = returnReduce(ratio, sumOp<scalar>());
186 
187  scalar totProfile = returnReduce(profile, sumOp<scalar>());
188 
189  const int oldPrecision = Info.stream().precision(4);
190 
191  Info<< setw(8) << levelI
192  << setw(8) << totNprocs
193  << " "
194  << setw(8) << totNCells/totNprocs
195  << setw(8) << maxNCells
196  << " "
197  << setw(8) << totFaceCellRatio/totNprocs
198  << setw(8) << maxFaceCellRatio
199  << " "
200  << setw(8) << scalar(totNInt)/totNprocs
201  << setw(8) << maxNInt
202  << " "
203  << setw(8) << totRatio/totNprocs
204  << setw(8) << maxRatio
205  << setw(12) << totProfile/totNprocs
206  << nl;
207 
208  Info.stream().precision(oldPrecision);
209  }
210  Info<< endl;
211 }
212 
213 
215 (
216  const label nCellsInCoarsestLevel,
217  const label nFineCells,
218  const label nCoarseCells,
219  const label comm
220 ) const
221 {
222  const label nTotalCoarseCells =
223  returnReduce(nCoarseCells, sumOp<label>(), UPstream::msgType(), comm);
224  if (nTotalCoarseCells < Pstream::nProcs(comm)*nCellsInCoarsestLevel)
225  {
226  return false;
227  }
228  else
229  {
230  const label nTotalFineCells =
231  returnReduce(nFineCells, sumOp<label>(), UPstream::msgType(), comm);
232  return nTotalCoarseCells < nTotalFineCells;
233  }
234 }
235 
236 
237 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
238 
240 (
241  const lduMesh& mesh,
242  const dictionary& controlDict
243 )
244 :
245  MeshObject<lduMesh, Foam::GeometricMeshObject, GAMGAgglomeration>(mesh),
246 
247  maxLevels_(50),
248 
249  nCellsInCoarsestLevel_
250  (
251  controlDict.getOrDefault<label>("nCellsInCoarsestLevel", 10)
252  ),
253  meshInterfaces_(mesh.interfaces()),
254  procAgglomeratorPtr_
255  (
256  (
257  (UPstream::nProcs(mesh.comm()) > 1)
258  && controlDict.found("processorAgglomerator")
259  )
260  ? GAMGProcAgglomeration::New
261  (
262  controlDict.get<word>("processorAgglomerator"),
263  *this,
265  )
266  : autoPtr<GAMGProcAgglomeration>()
267  ),
268 
269  nCells_(maxLevels_),
270  restrictAddressing_(maxLevels_),
271  nFaces_(maxLevels_),
272  faceRestrictAddressing_(maxLevels_),
273  faceFlipMap_(maxLevels_),
274  nPatchFaces_(maxLevels_),
275  patchFaceRestrictAddressing_(maxLevels_),
276 
277  meshLevels_(maxLevels_)
278 {
279  // Limit the cells in the coarsest level based on the local number of
280  // cells. Note: 2 for pair-wise
283 
284  // Ensure all procs see the same nCellsInCoarsestLevel_
285  reduce(nCellsInCoarsestLevel_, minOp<label>());
286 
288  if (processorAgglomerate())
289  {
290  procAgglomMap_.setSize(maxLevels_);
291  agglomProcIDs_.setSize(maxLevels_);
292  procCellOffsets_.setSize(maxLevels_);
293  procFaceMap_.setSize(maxLevels_);
296  }
297 }
298 
299 
301 (
302  const lduMesh& mesh,
303  const dictionary& controlDict
304 )
305 {
306  const GAMGAgglomeration* agglomPtr =
307  mesh.thisDb().cfindObject<GAMGAgglomeration>
308  (
309  GAMGAgglomeration::typeName
310  );
311 
312  if (agglomPtr)
313  {
314  return *agglomPtr;
315  }
316 
317  {
318  const word agglomeratorType
319  (
320  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
321  );
322 
323  mesh.thisDb().time().libs().open
324  (
325  controlDict,
326  "geometricGAMGAgglomerationLibs",
327  lduMeshConstructorTablePtr_
328  );
329 
330  auto* ctorPtr = lduMeshConstructorTable(agglomeratorType);
331 
332  if (!ctorPtr)
333  {
335  << "Unknown GAMGAgglomeration type "
336  << agglomeratorType << ".\n"
337  << "Valid matrix GAMGAgglomeration types :"
338  << lduMatrixConstructorTablePtr_->sortedToc() << endl
339  << "Valid geometric GAMGAgglomeration types :"
340  << lduMeshConstructorTablePtr_->sortedToc()
341  << exit(FatalError);
342  }
343 
344  auto agglomPtr(ctorPtr(mesh, controlDict));
345  if (debug)
346  {
347  agglomPtr().printLevels();
348  }
349  return store(agglomPtr.ptr());
350  }
351 }
352 
353 
355 (
356  const lduMatrix& matrix,
357  const dictionary& controlDict
358 )
359 {
360  const lduMesh& mesh = matrix.mesh();
361 
362  const GAMGAgglomeration* agglomPtr =
363  mesh.thisDb().cfindObject<GAMGAgglomeration>
364  (
365  GAMGAgglomeration::typeName
366  );
367 
368  if (agglomPtr)
369  {
370  return *agglomPtr;
371  }
372 
373  {
374  const word agglomeratorType
375  (
376  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
377  );
378 
379  mesh.thisDb().time().libs().open
380  (
381  controlDict,
382  "algebraicGAMGAgglomerationLibs",
383  lduMatrixConstructorTablePtr_
384  );
385 
386  auto* ctorPtr = lduMatrixConstructorTable(agglomeratorType);
387 
388  if (!ctorPtr)
389  {
390  return New(mesh, controlDict);
391  }
392  else
393  {
394  auto agglomPtr(ctorPtr(matrix, controlDict));
395  if (debug)
396  {
397  agglomPtr().printLevels();
398  }
399  return store(agglomPtr.ptr());
400  }
401  }
402 }
403 
404 
406 (
407  const lduMesh& mesh,
408  const scalarField& cellVolumes,
409  const vectorField& faceAreas,
410  const dictionary& controlDict
411 )
412 {
413 
414  const GAMGAgglomeration* agglomPtr =
415  mesh.thisDb().cfindObject<GAMGAgglomeration>
416  (
417  GAMGAgglomeration::typeName
418  );
419 
420  if (agglomPtr)
421  {
422  return *agglomPtr;
423  }
424 
425  {
426  const word agglomeratorType
427  (
428  controlDict.lookupOrDefault<word>("agglomerator", "faceAreaPair")
429  );
430 
431  const_cast<Time&>(mesh.thisDb().time()).libs().open
432  (
433  controlDict,
434  "geometricGAMGAgglomerationLibs",
435  geometryConstructorTablePtr_
436  );
437 
438  auto* ctorPtr = geometryConstructorTable(agglomeratorType);
439 
440  if (!ctorPtr)
441  {
443  << "Unknown GAMGAgglomeration type "
444  << agglomeratorType << ".\n"
445  << "Valid geometric GAMGAgglomeration types :"
446  << geometryConstructorTablePtr_->sortedToc()
447  << exit(FatalError);
448  }
449 
450  auto agglomPtr
451  (
452  ctorPtr
453  (
454  mesh,
455  cellVolumes,
456  faceAreas,
458  )
459  );
460  if (debug)
461  {
462  agglomPtr().printLevels();
463  }
464  return store(agglomPtr.ptr());
465  }
466 }
467 
468 
469 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
470 
472 {}
473 
474 
475 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
476 
478 (
479  const label i
480 ) const
481 {
482  if (i == 0)
483  {
484  return mesh_;
485  }
486  else
487  {
488  return meshLevels_[i - 1];
489  }
490 }
491 
492 
493 bool Foam::GAMGAgglomeration::hasMeshLevel(const label i) const
494 {
495  if (i == 0)
496  {
497  return true;
498  }
499  else
500  {
501  return meshLevels_.set(i - 1);
502  }
503 }
504 
505 
507 (
508  const label i
509 ) const
510 {
511  if (i == 0)
512  {
513  return meshInterfaces_;
514  }
515  else
516  {
517  return meshLevels_[i - 1].rawInterfaces();
518  }
519 }
520 
521 
522 void Foam::GAMGAgglomeration::clearLevel(const label i)
523 {
524  if (hasMeshLevel(i))
525  {
526  meshLevels_.set(i - 1, nullptr);
527 
528  if (i < nCells_.size())
529  {
530  nCells_[i] = -555;
531  restrictAddressing_.set(i, nullptr);
532  nFaces_[i] = -666;
533  faceRestrictAddressing_.set(i, nullptr);
534  faceFlipMap_.set(i, nullptr);
535  nPatchFaces_.set(i, nullptr);
536  patchFaceRestrictAddressing_.set(i, nullptr);
537  }
538  }
539 }
540 
541 
543 (
544  const label leveli
545 ) const
546 {
547  return procAgglomMap_[leveli];
548 }
549 
550 
552 (
553  const label leveli
554 ) const
555 {
556  return agglomProcIDs_[leveli];
557 }
558 
560 bool Foam::GAMGAgglomeration::hasProcMesh(const label leveli) const
561 {
562  return procCommunicator_[leveli] != -1;
563 }
564 
565 
566 Foam::label Foam::GAMGAgglomeration::procCommunicator(const label leveli) const
567 {
568  return procCommunicator_[leveli];
569 }
570 
571 
573 (
574  const label leveli
575 ) const
576 {
577  return procCellOffsets_[leveli];
578 }
579 
580 
582 (
583  const label leveli
584 ) const
585 {
586  return procFaceMap_[leveli];
587 }
588 
589 
591 (
592  const label leveli
593 ) const
594 {
595  return procBoundaryMap_[leveli];
596 }
597 
598 
600 (
601  const label leveli
602 ) const
603 {
604  return procBoundaryFaceMap_[leveli];
605 }
606 
607 
609 (
610  labelList& newRestrict,
611  label& nNewCoarse,
612  const lduAddressing& fineAddressing,
613  const labelUList& restriction,
614  const label nCoarse
615 )
616 {
617  if (fineAddressing.size() != restriction.size())
618  {
620  << "nCells:" << fineAddressing.size()
621  << " agglom:" << restriction.size()
622  << abort(FatalError);
623  }
624 
625  // Seed (master) for every region
626  labelList master(identity(fineAddressing.size()));
627 
628  // Now loop and transport master through region
629  const labelUList& lower = fineAddressing.lowerAddr();
630  const labelUList& upper = fineAddressing.upperAddr();
631 
632  while (true)
633  {
634  label nChanged = 0;
635 
636  forAll(lower, facei)
637  {
638  const label own = lower[facei];
639  const label nei = upper[facei];
640 
641  if (restriction[own] == restriction[nei])
642  {
643  // coarse-mesh-internal face
644 
645  if (master[own] < master[nei])
646  {
647  master[nei] = master[own];
648  nChanged++;
649  }
650  else if (master[own] > master[nei])
651  {
652  master[own] = master[nei];
653  nChanged++;
654  }
655  }
656  }
657 
658  reduce(nChanged, sumOp<label>());
659 
660  if (nChanged == 0)
661  {
662  break;
663  }
664  }
665 
666 
667  // Count number of regions/masters per coarse cell
668  labelListList coarseToMasters(nCoarse);
669  nNewCoarse = 0;
670  forAll(restriction, celli)
671  {
672  labelList& masters = coarseToMasters[restriction[celli]];
673 
674  if (!masters.found(master[celli]))
675  {
676  masters.append(master[celli]);
677  nNewCoarse++;
678  }
679  }
680 
681  if (nNewCoarse > nCoarse)
682  {
683  //WarningInFunction
684  // << "Have " << nCoarse
685  // << " agglomerated cells but " << nNewCoarse
686  // << " disconnected regions" << endl;
687 
688  // Keep coarseToMasters[0] the original coarse, allocate new ones
689  // for the others
690  labelListList coarseToNewCoarse(coarseToMasters.size());
691 
692  nNewCoarse = nCoarse;
693 
694  forAll(coarseToMasters, coarseI)
695  {
696  const labelList& masters = coarseToMasters[coarseI];
697 
698  labelList& newCoarse = coarseToNewCoarse[coarseI];
699  newCoarse.setSize(masters.size());
700  newCoarse[0] = coarseI;
701  for (label i=1; i<newCoarse.size(); i++)
702  {
703  newCoarse[i] = nNewCoarse++;
704  }
705  }
706 
707  newRestrict.setSize(fineAddressing.size());
708  forAll(restriction, celli)
709  {
710  const label coarseI = restriction[celli];
711 
712  const label index = coarseToMasters[coarseI].find(master[celli]);
713  newRestrict[celli] = coarseToNewCoarse[coarseI][index];
714  }
715 
716  return false;
717  }
718 
719  return true;
720 }
721 
722 
723 // ************************************************************************* //
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:675
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
virtual int precision() const
Get precision of output field.
Definition: OSstream.C:305
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:578
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:500
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:49
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:487
~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.
string upper(const std::string &s)
Return string copy transformed with std::toupper on each character.
Definition: stringOps.C:1186
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1184
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:378
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:414
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:1020
void setSize(const label n)
Alias for resize()
Definition: List.H:289
dynamicFvMesh & mesh
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)
Definition: labelList.C:31
const lduMesh & mesh() const noexcept
Reference to the mesh.
Definition: MeshObject.H:157
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.
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. Use the alternative stream for serial-only output if it is a v...
Definition: messageStream.C:68
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:1170
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.
void reduce(const List< UPstream::commsStruct > &comms, T &value, const BinaryOp &bop, const int tag, const label comm)
Reduce inplace (cf. MPI Allreduce) using specified communication schedule.
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 the append() metho...
Geometric agglomerated algebraic multigrid agglomeration class.
bool found
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
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.
label size() const
Return number of equations.
const labelListList & faceMap(const label fineLeveli) const
Mapping from processor to procMesh face.