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  updateInterval_(controlDict.getOrDefault<label>("updateInterval", 1)),
251  requireUpdate_(false),
252 
253  nCellsInCoarsestLevel_
254  (
255  controlDict.getOrDefault<label>("nCellsInCoarsestLevel", 10)
256  ),
257  meshInterfaces_(mesh.interfaces()),
258  procAgglomeratorPtr_
259  (
260  (
261  (UPstream::nProcs(mesh.comm()) > 1)
262  && controlDict.found("processorAgglomerator")
263  )
264  ? GAMGProcAgglomeration::New
265  (
266  controlDict.get<word>("processorAgglomerator"),
267  *this,
269  )
270  : autoPtr<GAMGProcAgglomeration>()
271  ),
272 
273  nCells_(maxLevels_),
274  restrictAddressing_(maxLevels_),
275  nFaces_(maxLevels_),
276  faceRestrictAddressing_(maxLevels_),
277  faceFlipMap_(maxLevels_),
278  nPatchFaces_(maxLevels_),
279  patchFaceRestrictAddressing_(maxLevels_),
280 
281  meshLevels_(maxLevels_)
282 {
283  // Limit the cells in the coarsest level based on the local number of
284  // cells. Note: 2 for pair-wise
287 
288  // Ensure all procs see the same nCellsInCoarsestLevel_
289  reduce(nCellsInCoarsestLevel_, minOp<label>());
290 
292  if (processorAgglomerate())
293  {
294  procAgglomMap_.setSize(maxLevels_);
295  agglomProcIDs_.setSize(maxLevels_);
297  procCellOffsets_.setSize(maxLevels_);
298  procFaceMap_.setSize(maxLevels_);
301  }
302 }
303 
304 
306 (
307  const lduMesh& mesh,
308  const dictionary& controlDict
309 )
310 {
311  const GAMGAgglomeration* agglomPtr =
312  mesh.thisDb().cfindObject<GAMGAgglomeration>
313  (
314  GAMGAgglomeration::typeName
315  );
316 
317  if (agglomPtr)
318  {
319  if (agglomPtr->requireUpdate_)
320  {
321  mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
323  }
324 
325  return *agglomPtr;
326  }
327 
328  {
329  const word agglomeratorType
330  (
331  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
332  );
333 
334  mesh.thisDb().time().libs().open
335  (
336  controlDict,
337  "geometricGAMGAgglomerationLibs",
338  lduMeshConstructorTablePtr_
339  );
340 
341  auto* ctorPtr = lduMeshConstructorTable(agglomeratorType);
342 
343  if (!ctorPtr)
344  {
346  << "Unknown GAMGAgglomeration type "
347  << agglomeratorType << ".\n"
348  << "Valid matrix GAMGAgglomeration types :"
349  << lduMatrixConstructorTablePtr_->sortedToc() << endl
350  << "Valid geometric GAMGAgglomeration types :"
351  << lduMeshConstructorTablePtr_->sortedToc()
352  << exit(FatalError);
353  }
354 
355  auto agglomPtr(ctorPtr(mesh, controlDict));
356  if (debug)
357  {
358  agglomPtr().printLevels();
359  }
360  return regIOobject::store(agglomPtr);
361  }
362 }
363 
364 
366 (
367  const lduMatrix& matrix,
368  const dictionary& controlDict
369 )
370 {
371  const lduMesh& mesh = matrix.mesh();
372 
373  const GAMGAgglomeration* agglomPtr =
374  mesh.thisDb().cfindObject<GAMGAgglomeration>
375  (
376  GAMGAgglomeration::typeName
377  );
378 
379  if (agglomPtr)
380  {
381  if (agglomPtr->requireUpdate_)
382  {
383  mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
384  return GAMGAgglomeration::New(matrix, controlDict);
385  }
386 
387  return *agglomPtr;
388  }
389 
390  {
391  const word agglomeratorType
392  (
393  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
394  );
395 
396  mesh.thisDb().time().libs().open
397  (
398  controlDict,
399  "algebraicGAMGAgglomerationLibs",
400  lduMatrixConstructorTablePtr_
401  );
402 
403  auto* ctorPtr = lduMatrixConstructorTable(agglomeratorType);
404 
405  if (!ctorPtr)
406  {
407  return New(mesh, controlDict);
408  }
409  else
410  {
411  auto agglomPtr(ctorPtr(matrix, controlDict));
412  if (debug)
413  {
414  agglomPtr().printLevels();
415  }
416  return regIOobject::store(agglomPtr);
417  }
418  }
419 }
420 
421 
423 (
424  const lduMesh& mesh,
425  const scalarField& cellVolumes,
426  const vectorField& faceAreas,
427  const dictionary& controlDict
428 )
429 {
430 
431  const GAMGAgglomeration* agglomPtr =
432  mesh.thisDb().cfindObject<GAMGAgglomeration>
433  (
434  GAMGAgglomeration::typeName
435  );
436 
437  if (agglomPtr)
438  {
439  if (agglomPtr->requireUpdate_)
440  {
441  mesh.thisDb().checkOut(const_cast<GAMGAgglomeration*>(agglomPtr));
443  }
444 
445  return *agglomPtr;
446  }
447 
448  {
449  const word agglomeratorType
450  (
451  controlDict.getOrDefault<word>("agglomerator", "faceAreaPair")
452  );
453 
454  const_cast<Time&>(mesh.thisDb().time()).libs().open
455  (
456  controlDict,
457  "geometricGAMGAgglomerationLibs",
458  geometryConstructorTablePtr_
459  );
460 
461  auto* ctorPtr = geometryConstructorTable(agglomeratorType);
462 
463  if (!ctorPtr)
464  {
466  << "Unknown GAMGAgglomeration type "
467  << agglomeratorType << ".\n"
468  << "Valid geometric GAMGAgglomeration types :"
469  << geometryConstructorTablePtr_->sortedToc()
470  << exit(FatalError);
471  }
472 
473  auto agglomPtr
474  (
475  ctorPtr
476  (
477  mesh,
478  cellVolumes,
479  faceAreas,
481  )
482  );
483  if (debug)
484  {
485  agglomPtr().printLevels();
486  }
487  return regIOobject::store(agglomPtr);
488  }
489 }
490 
491 
492 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
495 {}
496 
497 
498 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
499 
501 {
502  return
503  (updateInterval_ > 0)
504  && ((mesh_.thisDb().time().timeIndex() % updateInterval_) == 0);
505 }
506 
507 
509 {
510  if (requiresUpdate())
511  {
512  requireUpdate_ = true;
513  }
514  // What to return?
515  return requireUpdate_;
516 }
517 
518 
520 (
521  const label i
522 ) const
523 {
524  if (i == 0)
525  {
526  return mesh_;
527  }
528  else
529  {
530  return meshLevels_[i - 1];
531  }
532 }
533 
534 
535 bool Foam::GAMGAgglomeration::hasMeshLevel(const label i) const
536 {
537  if (i == 0)
538  {
539  return true;
540  }
541  else
542  {
543  return meshLevels_.set(i - 1);
544  }
545 }
546 
547 
549 (
550  const label i
551 ) const
552 {
553  if (i == 0)
554  {
555  return meshInterfaces_;
556  }
557  else
558  {
559  return meshLevels_[i - 1].rawInterfaces();
560  }
561 }
562 
563 
564 void Foam::GAMGAgglomeration::clearLevel(const label i)
565 {
566  if (hasMeshLevel(i))
567  {
568  meshLevels_.set(i - 1, nullptr);
569 
570  if (i < nCells_.size())
571  {
572  nCells_[i] = -555;
573  restrictAddressing_.set(i, nullptr);
574  nFaces_[i] = -666;
575  faceRestrictAddressing_.set(i, nullptr);
576  faceFlipMap_.set(i, nullptr);
577  nPatchFaces_.set(i, nullptr);
578  patchFaceRestrictAddressing_.set(i, nullptr);
579  }
580  }
581 }
582 
583 
585 (
586  const label leveli
587 ) const
588 {
589  return procAgglomMap_[leveli];
590 }
591 
592 
594 (
595  const label leveli
596 ) const
597 {
598  return agglomProcIDs_[leveli];
599 }
600 
602 bool Foam::GAMGAgglomeration::hasProcMesh(const label leveli) const
603 {
604  return procCommunicator_[leveli] != -1;
605 }
606 
608 Foam::label Foam::GAMGAgglomeration::procCommunicator(const label leveli) const
609 {
610  return procCommunicator_[leveli];
611 }
612 
613 
614 Foam::label Foam::GAMGAgglomeration::agglomCommunicator(const label leveli) const
615 {
616  return procAgglomCommunicator_[leveli];
617 }
618 
619 
621 (
622  const label leveli
623 ) const
624 {
625  return procCellOffsets_[leveli];
626 }
627 
628 
630 (
631  const label leveli
632 ) const
633 {
634  return procFaceMap_[leveli];
635 }
636 
637 
639 (
640  const label leveli
641 ) const
642 {
643  return procBoundaryMap_[leveli];
644 }
645 
646 
648 (
649  const label leveli
650 ) const
651 {
652  return procBoundaryFaceMap_[leveli];
653 }
654 
655 
657 (
658  labelList& newRestrict,
659  label& nNewCoarse,
660  const lduAddressing& fineAddressing,
661  const labelUList& restriction,
662  const label nCoarse
663 )
664 {
665  if (fineAddressing.size() != restriction.size())
666  {
668  << "nCells:" << fineAddressing.size()
669  << " agglom:" << restriction.size()
670  << abort(FatalError);
671  }
672 
673  // Seed (master) for every region
674  labelList master(identity(fineAddressing.size()));
675 
676  // Now loop and transport master through region
677  const labelUList& lower = fineAddressing.lowerAddr();
678  const labelUList& upper = fineAddressing.upperAddr();
679 
680  while (true)
681  {
682  label nChanged = 0;
683 
684  forAll(lower, facei)
685  {
686  const label own = lower[facei];
687  const label nei = upper[facei];
688 
689  if (restriction[own] == restriction[nei])
690  {
691  // coarse-mesh-internal face
692 
693  if (master[own] < master[nei])
694  {
695  master[nei] = master[own];
696  nChanged++;
697  }
698  else if (master[own] > master[nei])
699  {
700  master[own] = master[nei];
701  nChanged++;
702  }
703  }
704  }
705 
706  reduce(nChanged, sumOp<label>());
707 
708  if (nChanged == 0)
709  {
710  break;
711  }
712  }
713 
714 
715  // Count number of regions/masters per coarse cell
716  labelListList coarseToMasters(nCoarse);
717  nNewCoarse = 0;
718  forAll(restriction, celli)
719  {
720  labelList& masters = coarseToMasters[restriction[celli]];
721 
722  if (!masters.found(master[celli]))
723  {
724  masters.append(master[celli]);
725  nNewCoarse++;
726  }
727  }
728 
729  if (nNewCoarse > nCoarse)
730  {
731  //WarningInFunction
732  // << "Have " << nCoarse
733  // << " agglomerated cells but " << nNewCoarse
734  // << " disconnected regions" << endl;
735 
736  // Keep coarseToMasters[0] the original coarse, allocate new ones
737  // for the others
738  labelListList coarseToNewCoarse(coarseToMasters.size());
739 
740  nNewCoarse = nCoarse;
741 
742  forAll(coarseToMasters, coarseI)
743  {
744  const labelList& masters = coarseToMasters[coarseI];
745 
746  labelList& newCoarse = coarseToNewCoarse[coarseI];
747  newCoarse.setSize(masters.size());
748  newCoarse[0] = coarseI;
749  for (label i=1; i<newCoarse.size(); i++)
750  {
751  newCoarse[i] = nNewCoarse++;
752  }
753  }
754 
755  newRestrict.setSize(fineAddressing.size());
756  forAll(restriction, celli)
757  {
758  const label coarseI = restriction[celli];
759 
760  const label index = coarseToMasters[coarseI].find(master[celli]);
761  newRestrict[celli] = coarseToNewCoarse[coarseI][index];
762  }
763 
764  return false;
765  }
766 
767  return true;
768 }
769 
770 
771 // ************************************************************************* //
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
bool checkOut(regIOobject *io) const
Remove a regIOobject from registry and free memory if the object is ownedByRegistry. A nullptr is ignored.
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
bool requiresUpdate() const
Does the agglomeration need to be fully updated?
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
virtual bool movePoints()
Update when the mesh moves.
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.