GAMGAgglomeration.H
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 Class
28  Foam::GAMGAgglomeration
29 
30 Description
31  Geometric agglomerated algebraic multigrid agglomeration class.
32 
33  Example of the specification in fvSolution:
34  \verbatim
35  {
36  solver GAMG;
37  smoother symGaussSeidel;
38 
39  // Whether to cache the agglomeration
40  cacheAgglomeration yes;
41  // Optionally update every updateInterval mesh motion. Default is 1.
42  updateInterval 10;
43 
44  // Optionally agglomerate coarsest-level across processors
45  processorAgglomerator masterCoarsest;
46  nMasters 2;
47 
48  tolerance 1e-2;
49  relTol 0;
50  }
51  \endverbatim
52 
53 SourceFiles
54  GAMGAgglomeration.C
55  GAMGAgglomerationTemplates.C
56  GAMGAgglomerateLduAddressing.C
57 
58 \*---------------------------------------------------------------------------*/
59 
60 #ifndef Foam_GAMGAgglomeration_H
61 #define Foam_GAMGAgglomeration_H
62 
63 #include "MeshObject.H"
64 #include "lduPrimitiveMesh.H"
65 #include "lduInterfacePtrsList.H"
66 #include "primitiveFields.H"
67 #include "runTimeSelectionTables.H"
68 
69 #include "boolList.H"
70 
71 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
72 
73 namespace Foam
74 {
75 
76 // Forward Declarations
77 class lduMesh;
78 class lduMatrix;
79 class mapDistribute;
80 class GAMGProcAgglomeration;
81 
82 /*---------------------------------------------------------------------------*\
83  Class GAMGAgglomeration Declaration
84 \*---------------------------------------------------------------------------*/
85 
87 :
88  public MeshObject<lduMesh, MoveableMeshObject, GAMGAgglomeration>
89 {
90  // Private Typedefs
91 
92  typedef MeshObject
93  <
94  lduMesh,
98 
99 
100 protected:
101 
102  // Protected Data
103 
104  //- Max number of levels
105  const label maxLevels_;
106 
107  //- Update agglomeration every updateInterval_ steps
108  const label updateInterval_;
109 
110  //- Does agglomeration require update
111  mutable bool requireUpdate_;
113  //- Number of cells in coarsest level
115 
116  //- Cached mesh interfaces
118 
120 
121  //- The number of cells in each level
123 
124  //- Cell restriction addressing array.
125  // Maps from the finer to the coarser level.
127 
128  //- The number of (coarse) faces in each level.
129  // max(faceRestrictAddressing)+1.
131 
132  //- Face restriction addressing array.
133  // Maps from the finer to the coarser level.
134  // Positive indices map the finer faces which form part of the boundary
135  // of the coarser cells to the corresponding coarser cell face.
136  // Negative indices map the finer faces which are internal to the
137  // coarser cells to minus the corresponding coarser cell index minus 1.
139 
140  //- Face flip: for faces mapped to internal faces stores whether
141  // the face is reversed or not. This is used to avoid having
142  // to access the coarse mesh at all when mapping
144 
145  //- The number of (coarse) patch faces in each level.
146  // max(patchFaceRestrictAddressing_)+1.
148 
149  //- Patch-local face restriction addressing array.
150  // Maps from the finer to the coarser level. Always positive.
151  // Extracted from GAMGInterfaces after agglomeration.
153 
154  //- Hierarchy of mesh addressing
156 
157 
158  // Processor agglomeration
159 
160  //- Per level, per processor the processor it agglomerates into
163  //- Per level the set of processors to agglomerate. Element 0 is
164  // the 'master' of the cluster.
166 
167  //- Communicator for given level
170  //- Communicator for collecting contributions. Note self-contained
171  // communicator for ease of cleanup - this one gets allocated
172  // internally, not by the GAMGProcAgglomerations
174 
175  //- Mapping from processor to procMeshLevel cells
178  //- Mapping from processor to procMeshLevel face
180 
181  //- Mapping from processor to procMeshLevel boundary
183 
184  //- Mapping from processor to procMeshLevel boundary face
186 
187 
188  // Protected Member Functions
189 
190  //- Does the agglomeration need to be fully updated?
191  bool requiresUpdate() const;
192 
193  //- Assemble coarse mesh addressing
194  void agglomerateLduAddressing(const label fineLevelIndex);
195 
196  //- Combine a level with the previous one
197  void combineLevels(const label curLevel);
198 
199  //- Shrink the number of levels to that specified. Optionally do
200  // processor agglomeration
201  void compactLevels
202  (
203  const label nCreatedLevels,
204  const bool doProcessorAgglomerate
205  );
206 
207  //- Check the need for further agglomeration
209  (
210  const label nCellsInCoarsestLevel,
211  const label nCells,
212  const label nCoarseCells,
213  const label comm
214  ) const;
216  void clearLevel(const label leveli);
217 
218  //- Print level overview
219  void printLevels() const;
221 
222  // Processor agglomeration
223 
224  //- Collect and combine processor meshes into allMesh:
225  //
226  // - allMeshComm : communicator for combined mesh.
227  // - procAgglomMap : per processor the new agglomerated
228  // processor (rank in allMeshComm!). Global information.
229  // - procIDs : local information: same for all in
230  // agglomerated processor.
232  (
233  const label comm,
234  const labelList& procAgglomMap,
235  const labelList& procIDs,
236  const label allMeshComm,
237  const label levelIndex
238  );
239 
240  //- Collect and combine basic restriction addressing:
241  //
242  // - nCells_
243  // - restrictAddressing_
245  (
246  const label comm,
247  const labelList& procIDs,
248  const label levelIndex
249  );
250 
251 
252  //- No copy construct
253  GAMGAgglomeration(const GAMGAgglomeration&) = delete;
254 
255  //- No copy assignment
256  void operator=(const GAMGAgglomeration&) = delete;
257 
258 
259 public:
260 
261  //- Declare friendship with GAMGProcAgglomeration
262  friend class GAMGProcAgglomeration;
263 
264  //- Runtime type information
265  TypeName("GAMGAgglomeration");
266 
267 
268  // Declare run-time constructor selection tables
269 
270  //- Runtime selection table for pure geometric agglomerators
272  (
273  autoPtr,
275  lduMesh,
276  (
277  const lduMesh& mesh,
278  const dictionary& controlDict
279  ),
280  (
281  mesh,
283  )
284  );
285 
286  //- Runtime selection table for matrix or mixed geometric/matrix
287  //- agglomerators
289  (
290  autoPtr,
292  lduMatrix,
293  (
294  const lduMatrix& matrix,
295  const dictionary& controlDict
296  ),
297  (
298  matrix,
300  )
301  );
302 
303  //- Runtime selection table for matrix or mixed geometric/matrix
304  //- agglomerators
306  (
307  autoPtr,
309  geometry,
310  (
311  const lduMesh& mesh,
312  const scalarField& cellVolumes,
313  const vectorField& faceAreas,
314  const dictionary& controlDict
315  ),
316  (
317  mesh,
318  cellVolumes,
319  faceAreas,
321  )
322  );
323 
324 
325  // Constructors
326 
327  //- Construct given mesh and controls
329  (
330  const lduMesh& mesh,
331  const dictionary& controlDict
332  );
333 
334 
335  // Selectors
336 
337  //- Return the selected geometric agglomerator
338  static const GAMGAgglomeration& New
339  (
340  const lduMesh& mesh,
341  const dictionary& controlDict
342  );
343 
344  //- Return the selected matrix agglomerator
345  static const GAMGAgglomeration& New
346  (
347  const lduMatrix& matrix,
348  const dictionary& controlDict
349  );
350 
351  //- Return the selected geometric agglomerator
352  static const GAMGAgglomeration& New
353  (
354  const lduMesh& mesh,
355  const scalarField& cellVolumes,
356  const vectorField& faceAreas,
357  const dictionary& controlDict
358  );
359 
360 
361  //- Destructor
363 
364 
365  // Member Functions
366 
367  //- Update when the mesh moves
368  virtual bool movePoints();
369 
370 
371  // Access
372 
373  label size() const
374  {
375  return meshLevels_.size();
376  }
377 
378  //- Return LDU mesh of given level
379  const lduMesh& meshLevel(const label leveli) const;
380 
381  //- Do we have mesh for given level?
382  bool hasMeshLevel(const label leveli) const;
383 
384  //- Return LDU interface addressing of given level
386  (
387  const label leveli
388  ) const;
389 
390  //- Return cell restrict addressing of given level
391  const labelField& restrictAddressing(const label leveli) const
392  {
393  return restrictAddressing_[leveli];
394  }
395 
396  //- Return face restrict addressing of given level
397  const labelList& faceRestrictAddressing(const label leveli) const
398  {
399  return faceRestrictAddressing_[leveli];
400  }
401 
402  const labelListList& patchFaceRestrictAddressing(const label leveli)
403  const
404  {
405  return patchFaceRestrictAddressing_[leveli];
406  }
407 
408  //- Return face flip map of given level
409  const boolList& faceFlipMap(const label leveli) const
410  {
411  return faceFlipMap_[leveli];
412  }
413 
414  //- Return number of coarse cells (before processor agglomeration)
415  label nCells(const label leveli) const
416  {
417  return nCells_[leveli];
418  }
419 
420  //- Return number of coarse faces (before processor agglomeration)
421  label nFaces(const label leveli) const
422  {
423  return nFaces_[leveli];
424  }
425 
426  //- Return number of coarse patch faces (before processor
427  //- agglomeration)
428  const labelList& nPatchFaces(const label leveli) const
429  {
430  return nPatchFaces_[leveli];
431  }
432 
433 
434  // Restriction and prolongation
435 
436  //- Restrict (integrate by summation) cell field
437  template<class Type>
438  void restrictField
439  (
440  Field<Type>& cf,
441  const Field<Type>& ff,
442  const label fineLevelIndex,
443  const bool procAgglom
444  ) const;
445 
446  //- Restrict (integrate by summation) face field
447  template<class Type>
448  void restrictFaceField
449  (
450  Field<Type>& cf,
451  const Field<Type>& ff,
452  const label fineLevelIndex
453  ) const;
454 
455  //- Restrict (integrate by summation) cell field
456  template<class Type>
457  void restrictField
458  (
459  Field<Type>& cf,
460  const Field<Type>& ff,
461  const labelList& fineToCoarse
462  ) const;
464  //- Prolong (interpolate by injection) cell field
465  template<class Type>
466  void prolongField
467  (
468  Field<Type>& ff,
469  const Field<Type>& cf,
470  const label coarseLevelIndex,
471  const bool procAgglom
472  ) const;
473 
474  //- Prolong (interpolate by injection) cell field. Return reference
475  // to (potentially scattered) coarse field
476  template<class Type>
478  (
479  Field<Type>& ff, // fine-level field
480  Field<Type>& work, // work storage
481  const Field<Type>& cf, // coarse-level field
482  const label coarseLevelIndex
483  ) const;
484 
485 
486  // Processor agglomeration. Note that the mesh and agglomeration is
487  // stored per fineLevel (even though it is the coarse level mesh that
488  // has been agglomerated). This is just for convenience and consistency
489  // with GAMGSolver notation.
490 
491  //- Given fine to coarse processor map determine:
492  //
493  // - for each coarse processor a master (minimum of the fine
494  // processors)
495  // - for each coarse processor the set of fine processors
496  // (element 0 is the master processor)
498  (
499  const label comm,
500  const labelList& procAgglomMap,
501  labelList& masterProcs,
503  );
504 
505  //- Whether to agglomerate across processors
506  bool processorAgglomerate() const
507  {
508  return bool(procAgglomeratorPtr_);
509  }
510 
511  //- Mapping from processor to agglomerated processor (global, all
512  //- processors have the same information). Note that level is
513  //- the fine, not the coarse, level index. This is to be
514  //- consistent with the way the restriction is stored
515  const labelList& procAgglomMap(const label fineLeveli) const;
516 
517  //- Set of processors to agglomerate. Element 0 is the
518  //- master processor. (local, same only on those processors that
519  //- agglomerate)
520  const labelList& agglomProcIDs(const label fineLeveli) const;
521 
522  //- Check that level has combined mesh
523  bool hasProcMesh(const label fineLeveli) const;
524 
525  //- Communicator for current level or -1
526  label procCommunicator(const label fineLeveli) const;
528  //- Communicator for collecting contributions
529  label agglomCommunicator(const label fineLeveli) const;
530 
531  //- Mapping from processor to procMesh cells
532  const labelList& cellOffsets(const label fineLeveli) const;
533 
534  //- Mapping from processor to procMesh face
535  const labelListList& faceMap(const label fineLeveli) const;
537  //- Mapping from processor to procMesh boundary
538  const labelListList& boundaryMap(const label fineLeveli) const;
539 
540  //- Mapping from processor to procMesh boundary face
541  const labelListListList& boundaryFaceMap(const label fineLeveli)
542  const;
543 
544 
545  // Helpers
546 
547  //- Agglomerate from a starting level. Starting level is usually 0
548  //- (initial mesh) but sometimes >0 (restarting after processor
549  //- agglomeration)
550  virtual void agglomerate
551  (
552  const label nCellsInCoarsestLevel,
553  const label startLevel,
554  const scalarField& startFaceWeights,
555  const bool doProcessorAgglomerate = true
556  ) = 0;
557 
558  //- Given restriction determines if coarse cells are connected.
559  // Return ok is so, otherwise creates new restriction that is
560  static bool checkRestriction
561  (
562  labelList& newRestrict,
563  label& nNewCoarse,
564  const lduAddressing& fineAddressing,
565  const labelUList& restriction,
566  const label nCoarse
567  );
568 };
569 
570 
571 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
572 
573 } // End namespace Foam
574 
575 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
576 
577 #ifdef NoRepository
579 #endif
580 
581 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
582 
583 #endif
584 
585 // ************************************************************************* //
autoPtr< GAMGProcAgglomeration > procAgglomeratorPtr_
PtrList< labelListList > procBoundaryMap_
Mapping from processor to procMeshLevel boundary.
const labelList & faceRestrictAddressing(const label leveli) const
Return face restrict addressing of given level.
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.
const labelList & nPatchFaces(const label leveli) const
Return number of coarse patch faces (before processor agglomeration)
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.
void restrictField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex, const bool procAgglom) const
Restrict (integrate by summation) cell field.
bool requireUpdate_
Does agglomeration require update.
const boolList & faceFlipMap(const label leveli) const
Return face flip map of given level.
PtrList< labelListList > patchFaceRestrictAddressing_
Patch-local face restriction addressing array.
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
PtrList< labelListListList > procBoundaryFaceMap_
Mapping from processor to procMeshLevel boundary face.
GAMGAgglomeration(const GAMGAgglomeration &)=delete
No copy construct.
label agglomCommunicator(const label fineLeveli) const
Communicator for collecting contributions.
MoveableMeshObject(const word &objName, const objectRegistry &obr)
Construct from name and instance on registry.
Definition: MeshObject.H:326
TypeName("GAMGAgglomeration")
Runtime type information.
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
PtrList< labelList > procCellOffsets_
Mapping from processor to procMeshLevel cells.
void restrictFaceField(Field< Type > &cf, const Field< Type > &ff, const label fineLevelIndex) const
Restrict (integrate by summation) face field.
const labelListList & boundaryMap(const label fineLeveli) const
Mapping from processor to procMesh boundary.
~GAMGAgglomeration()
Destructor.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition: lduMesh.H:53
static const GAMGAgglomeration & New(const lduMesh &mesh, const dictionary &controlDict)
Return the selected geometric agglomerator.
void procAgglomerateLduAddressing(const label comm, const labelList &procAgglomMap, const labelList &procIDs, const label allMeshComm, const label levelIndex)
Collect and combine processor meshes into allMesh:
PtrList< labelList > faceRestrictAddressing_
Face restriction addressing array.
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
PtrList< labelList > nPatchFaces_
The number of (coarse) patch faces in each level.
void clearLevel(const label leveli)
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
label procCommunicator(const label fineLeveli) const
Communicator for current level or -1.
labelList procCommunicator_
Communicator for given level.
Templated abstract base-class for optional mesh objects used to automate their allocation to the mesh...
Definition: MeshObject.H:152
bool requiresUpdate() const
Does the agglomeration need to be fully updated?
const lduInterfacePtrsList meshInterfaces_
Cached mesh interfaces.
virtual bool movePoints()
Update when the mesh moves.
bool processorAgglomerate() const
Whether to agglomerate across processors.
PtrList< lduPrimitiveMesh > meshLevels_
Hierarchy of mesh addressing.
const lduMesh & mesh() const noexcept
Reference to the mesh.
Definition: MeshObject.H:255
PtrList< UPstream::communicator > procAgglomCommunicator_
Communicator for collecting contributions. Note self-contained.
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.
labelList nCells_
The number of cells in each level.
void prolongField(Field< Type > &ff, const Field< Type > &cf, const label coarseLevelIndex, const bool procAgglom) const
Prolong (interpolate by injection) cell field.
runTime controlDict().readEntry("adjustTimeStep"
The central control dictionary, the contents of which are either taken directly from the FOAM_CONTROL...
Definition: debug.C:142
labelList nFaces_
The number of (coarse) faces in each level.
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
void agglomerateLduAddressing(const label fineLevelIndex)
Assemble coarse mesh addressing.
label nFaces(const label leveli) const
Return number of coarse faces (before processor agglomeration)
const label maxLevels_
Max number of levels.
Specialisations of Field<T> for scalar, vector and tensor.
lduMatrix is a general matrix class in which the coefficients are stored as three arrays...
Definition: lduMatrix.H:80
const labelList & cellOffsets(const label fineLeveli) const
Mapping from processor to procMesh cells.
void procAgglomerateRestrictAddressing(const label comm, const labelList &procIDs, const label levelIndex)
Collect and combine basic restriction addressing:
const labelListListList & boundaryFaceMap(const label fineLeveli) const
Mapping from processor to procMesh boundary face.
const label updateInterval_
Update agglomeration every updateInterval_ steps.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
Definition: List.H:55
const labelList & procAgglomMap(const label fineLeveli) const
Mapping from processor to agglomerated processor (global, all processors have the same information)...
Processor agglomeration of GAMGAgglomerations.
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.
const labelField & restrictAddressing(const label leveli) const
Return cell restrict addressing of given level.
declareRunTimeSelectionTable(autoPtr, GAMGAgglomeration, lduMesh,(const lduMesh &mesh, const dictionary &controlDict),(mesh, controlDict))
Runtime selection table for pure geometric agglomerators.
Pointer management similar to std::unique_ptr, with some additional methods and type checking...
Definition: HashPtrTable.H:48
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.
Macros to ease declaration of run-time selection tables.
virtual void agglomerate(const label nCellsInCoarsestLevel, const label startLevel, const scalarField &startFaceWeights, const bool doProcessorAgglomerate=true)=0
Agglomerate from a starting level. Starting level is usually 0 (initial mesh) but sometimes >0 (resta...
List< label > labelList
A List of labels.
Definition: List.H:62
const labelListList & patchFaceRestrictAddressing(const label leveli) const
Geometric agglomerated algebraic multigrid agglomeration class.
List< bool > boolList
A List of bools.
Definition: List.H:60
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
static void calculateRegionMaster(const label comm, const labelList &procAgglomMap, labelList &masterProcs, List< label > &agglomProcIDs)
Given fine to coarse processor map determine:
label nCells(const label leveli) const
Return number of coarse cells (before processor agglomeration)
void operator=(const GAMGAgglomeration &)=delete
No copy assignment.
label nCellsInCoarsestLevel_
Number of cells in coarsest level.
void combineLevels(const label curLevel)
Combine a level with the previous one.
const FieldField< fvPatchField, Type > & ff(const FieldField< fvPatchField, Type > &bf)
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.