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