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