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