GAMGProcAgglomeration.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2013-2017 OpenFOAM Foundation
9  Copyright (C) 2021 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "GAMGProcAgglomeration.H"
30 #include "GAMGAgglomeration.H"
31 #include "lduMesh.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(GAMGProcAgglomeration, 0);
38  defineRunTimeSelectionTable(GAMGProcAgglomeration, GAMGAgglomeration);
39 }
40 
41 
42 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
43 
45 (
46  Ostream& os,
47  GAMGAgglomeration& agglom
48 ) const
49 {
50  for (label levelI = 0; levelI <= agglom.size(); levelI++)
51  {
52  if (agglom.hasMeshLevel(levelI))
53  {
54  os << agglom.meshLevel(levelI).info() << endl;
55  }
56  else
57  {
58  os << "Level " << levelI << " has no fine mesh:" << endl;
59  }
60 
61  if
62  (
63  levelI < agglom.restrictAddressing_.size()
64  && agglom.restrictAddressing_.set(levelI)
65  )
66  {
67  const labelList& cellRestrict =
68  agglom.restrictAddressing(levelI);
69  const labelList& faceRestrict =
70  agglom.faceRestrictAddressing(levelI);
71 
72  os << "Level " << levelI << " agglomeration:" << nl
73  << " nCoarseCells:" << agglom.nCells(levelI) << nl
74  << " nCoarseFaces:" << agglom.nFaces(levelI) << nl
75  << " cellRestriction:"
76  << " size:" << cellRestrict.size()
77  << " max:" << max(cellRestrict)
78  << nl
79  << " faceRestriction:"
80  << " size:" << faceRestrict.size()
81  << " max:" << max(faceRestrict)
82  << nl;
83 
84  const labelListList& patchFaceRestrict =
85  agglom.patchFaceRestrictAddressing(levelI);
86  forAll(patchFaceRestrict, i)
87  {
88  if (patchFaceRestrict[i].size())
89  {
90  const labelList& faceRestrict =
91  patchFaceRestrict[i];
92  os << " " << i
93  << " size:" << faceRestrict.size()
94  << " max:" << max(faceRestrict)
95  << nl;
96  }
97  }
98  }
99  if
100  (
101  levelI < agglom.procCellOffsets_.size()
102  && agglom.procCellOffsets_.set(levelI)
103  )
104  {
105  os << " procCellOffsets:" << agglom.procCellOffsets_[levelI]
106  << nl
107  << " procAgglomMap:" << agglom.procAgglomMap_[levelI]
108  << nl
109  << " procIDs:" << agglom.agglomProcIDs_[levelI]
110  << nl
111  << " comm:" << agglom.procCommunicator_[levelI]
112  << endl;
113  }
114 
115  os << endl;
116  }
117  os << endl;
118 }
119 
120 
122 (
123  const lduMesh& mesh
124 )
125 {
126  const lduAddressing& addr = mesh.lduAddr();
127  lduInterfacePtrsList interfaces = mesh.interfaces();
128 
129  const label myProcID = Pstream::myProcNo(mesh.comm());
130 
131  globalIndex globalNumbering
132  (
133  addr.size(),
134  Pstream::msgType(),
135  mesh.comm(),
136  Pstream::parRun()
137  );
138 
139  labelList globalIndices
140  (
141  identity
142  (
143  globalNumbering.localSize(myProcID),
144  globalNumbering.localStart(myProcID)
145  )
146  );
147 
148  // Get the interface cells
149  PtrList<labelList> nbrGlobalCells(interfaces.size());
150  {
151  const label nReq = Pstream::nRequests();
152 
153  // Initialise transfer of restrict addressing on the interface
154  forAll(interfaces, inti)
155  {
156  if (interfaces.set(inti))
157  {
158  interfaces[inti].initInternalFieldTransfer
159  (
160  Pstream::commsTypes::nonBlocking,
161  globalIndices
162  );
163  }
164  }
165 
166  if (Pstream::parRun())
167  {
168  Pstream::waitRequests(nReq);
169  }
170 
171  forAll(interfaces, inti)
172  {
173  if (interfaces.set(inti))
174  {
175  nbrGlobalCells.set
176  (
177  inti,
178  new labelList
179  (
180  interfaces[inti].internalFieldTransfer
181  (
182  Pstream::commsTypes::nonBlocking,
183  globalIndices
184  )
185  )
186  );
187  }
188  }
189  }
190 
191 
192  // Scan the neighbour list to find out how many times the cell
193  // appears as a neighbour of the face. Done this way to avoid guessing
194  // and resizing list
195  labelList nNbrs(addr.size(), 1);
196 
197  const labelUList& nbr = addr.upperAddr();
198  const labelUList& own = addr.lowerAddr();
199 
200  {
201  forAll(nbr, facei)
202  {
203  nNbrs[nbr[facei]]++;
204  nNbrs[own[facei]]++;
205  }
206 
207  forAll(interfaces, inti)
208  {
209  if (interfaces.set(inti))
210  {
211  const labelUList& faceCells = interfaces[inti].faceCells();
212 
213  forAll(faceCells, i)
214  {
215  nNbrs[faceCells[i]]++;
216  }
217  }
218  }
219  }
220 
221 
222  // Create cell-cells addressing
223  labelListList cellCells(addr.size());
224 
225  forAll(cellCells, celli)
226  {
227  cellCells[celli].setSize(nNbrs[celli], -1);
228  }
229 
230  // Reset the list of number of neighbours to zero
231  nNbrs = 0;
232 
233  // Scatter the neighbour faces
234  forAll(nbr, facei)
235  {
236  label c0 = own[facei];
237  label c1 = nbr[facei];
238 
239  cellCells[c0][nNbrs[c0]++] = globalIndices[c1];
240  cellCells[c1][nNbrs[c1]++] = globalIndices[c0];
241  }
242  forAll(interfaces, inti)
243  {
244  if (interfaces.set(inti))
245  {
246  const labelUList& faceCells = interfaces[inti].faceCells();
247 
248  forAll(faceCells, i)
249  {
250  label c0 = faceCells[i];
251  cellCells[c0][nNbrs[c0]++] = nbrGlobalCells[inti][i];
252  }
253  }
254  }
255 
256  forAll(cellCells, celli)
257  {
258  Foam::stableSort(cellCells[celli]);
259  }
260 
261  // Replace the initial element (always -1) with the local cell
262  forAll(cellCells, celli)
263  {
264  cellCells[celli][0] = globalIndices[celli];
265  }
266 
267  return cellCells;
268 }
269 
270 
272 (
273  const label fineLevelIndex,
274  const labelList& procAgglomMap,
275  const labelList& masterProcs,
276  const List<label>& agglomProcIDs,
277  const label procAgglomComm
278 )
279 {
280  const lduMesh& levelMesh = agglom_.meshLevels_[fineLevelIndex];
281  label levelComm = levelMesh.comm();
282 
283  if (Pstream::myProcNo(levelComm) != -1)
284  {
285  // Collect meshes and restrictAddressing onto master
286  // Overwrites the fine mesh (meshLevels_[index-1]) and addressing
287  // from fine mesh to coarse mesh (restrictAddressing_[index]).
288  agglom_.procAgglomerateLduAddressing
289  (
290  levelComm,
291  procAgglomMap,
292  agglomProcIDs,
293  procAgglomComm,
294 
295  fineLevelIndex //fine level index
296  );
297 
298  // Combine restrict addressing only onto master
299  for
300  (
301  label levelI = fineLevelIndex+1;
302  levelI < agglom_.meshLevels_.size();
303  levelI++
304  )
305  {
306  agglom_.procAgglomerateRestrictAddressing
307  (
308  levelComm,
309  agglomProcIDs,
310  levelI
311  );
312  }
313 
314  if (Pstream::myProcNo(levelComm) == agglomProcIDs[0])
315  {
316  // On master. Recreate coarse meshes from restrict addressing
317  for
318  (
319  label levelI = fineLevelIndex;
320  levelI < agglom_.meshLevels_.size();
321  levelI++
322  )
323  {
324  agglom_.agglomerateLduAddressing(levelI);
325  }
326  }
327  else
328  {
329  // Agglomerated away. Clear mesh storage.
330  for
331  (
332  label levelI = fineLevelIndex+1;
333  levelI <= agglom_.size();
334  levelI++
335  )
336  {
337  agglom_.clearLevel(levelI);
338  }
339  }
340  }
341 
342  // Should check!
343  return true;
344 }
345 
346 
347 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
348 
349 Foam::GAMGProcAgglomeration::GAMGProcAgglomeration
350 (
351  GAMGAgglomeration& agglom,
352  const dictionary& controlDict
353 )
354 :
355  agglom_(agglom)
356 {}
357 
358 
360 (
361  const word& type,
362  GAMGAgglomeration& agglom,
363  const dictionary& controlDict
364 )
365 {
366  DebugInFunction << "Constructing GAMGProcAgglomeration" << endl;
367 
368  auto* ctorPtr = GAMGAgglomerationConstructorTable(type);
369 
370  if (!ctorPtr)
371  {
373  << "Unknown GAMGProcAgglomeration type "
374  << type << " for GAMGAgglomeration " << agglom.type() << nl << nl
375  << "Valid GAMGProcAgglomeration types :" << endl
376  << GAMGAgglomerationConstructorTablePtr_->sortedToc()
377  << exit(FatalError);
378  }
379 
380  return autoPtr<GAMGProcAgglomeration>(ctorPtr(agglom, controlDict));
381 }
382 
383 
384 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
385 
387 {}
388 
389 
390 // ************************************************************************* //
Foam::lduAddressing
The class contains the addressing required by the lduMatrix: upper, lower and losort.
Definition: lduAddressing.H:114
GAMGProcAgglomeration.H
Foam::GAMGAgglomeration::faceRestrictAddressing
const labelList & faceRestrictAddressing(const label leveli) const
Return face restrict addressing of given level.
Definition: GAMGAgglomeration.H:349
Foam::UPtrList::size
label size() const noexcept
The number of elements in the list.
Definition: UPtrListI.H:106
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::GAMGAgglomeration
Geometric agglomerated algebraic multigrid agglomeration class.
Definition: GAMGAgglomeration.H:64
Foam::GAMGAgglomeration::nFaces
label nFaces(const label leveli) const
Return number of coarse faces (before processor agglomeration)
Definition: GAMGAgglomeration.H:373
Foam::defineRunTimeSelectionTable
defineRunTimeSelectionTable(reactionRateFlameArea, dictionary)
Foam::GAMGAgglomeration::meshLevel
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
Definition: GAMGAgglomeration.C:455
Foam::GAMGAgglomeration::patchFaceRestrictAddressing
const labelListList & patchFaceRestrictAddressing(const label leveli) const
Definition: GAMGAgglomeration.H:354
GAMGAgglomeration.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::GAMGAgglomeration::hasMeshLevel
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
Definition: GAMGAgglomeration.C:470
Foam::lduAddressing::size
label size() const
Return number of equations.
Definition: lduAddressing.H:171
Foam::lduAddressing::upperAddr
virtual const labelUList & upperAddr() const =0
Return upper addressing.
Foam::GAMGAgglomeration::restrictAddressing_
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
Definition: GAMGAgglomeration.H:88
Foam::GAMGAgglomeration::size
label size() const
Definition: GAMGAgglomeration.H:325
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::stableSort
void stableSort(UList< T > &a)
Definition: UList.C:275
Foam::GAMGAgglomeration::restrictAddressing
const labelField & restrictAddressing(const label leveli) const
Return cell restrict addressing of given level.
Definition: GAMGAgglomeration.H:343
Foam::constant::physicoChemical::c1
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:388
Foam::GAMGProcAgglomeration::agglomerate
virtual bool agglomerate()=0
Modify agglomeration. Return true if modified.
controlDict
runTime controlDict().readEntry("adjustTimeStep"
Definition: debug.C:143
Foam::UPtrList< const lduInterface >
Foam::PtrList
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition: List.H:59
Foam::GAMGProcAgglomeration::New
static autoPtr< GAMGProcAgglomeration > New(const word &type, GAMGAgglomeration &agglom, const dictionary &controlDict)
Return the selected agglomerator.
Definition: GAMGProcAgglomeration.C:360
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::GAMGProcAgglomeration::printStats
void printStats(Ostream &os, GAMGAgglomeration &agglom) const
Debug: write agglomeration info.
Definition: GAMGProcAgglomeration.C:45
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
os
OBJstream os(runTime.globalPath()/outputName)
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::GAMGAgglomeration::procAgglomMap_
PtrList< labelList > procAgglomMap_
Per level, per processor the processor it agglomerates into.
Definition: GAMGAgglomeration.H:123
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:68
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::lduMesh::info
InfoProxy< lduMesh > info() const
Return info proxy.
Definition: lduMesh.H:110
Foam::autoPtr< Foam::GAMGProcAgglomeration >
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::UPtrList::set
const T * set(const label i) const
Definition: UPtrList.H:176
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::lduAddressing::lowerAddr
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
Foam::List< label >
Foam::UList< label >
Foam::identity
labelList identity(const label len, label start=0)
Create identity map of the given length with (map[i] == i)
Definition: labelList.C:38
Foam::roots::type
type
Types of root.
Definition: Roots.H:54
Foam::lduMesh::comm
virtual label comm() const =0
Return communicator used for parallel communication.
Foam::GAMGProcAgglomeration::globalCellCells
static labelListList globalCellCells(const lduMesh &)
Debug: calculate global cell-cells.
Definition: GAMGProcAgglomeration.C:122
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::GAMGAgglomeration::nCells
label nCells(const label leveli) const
Return number of coarse cells (before processor agglomeration)
Definition: GAMGAgglomeration.H:367
lduMesh.H
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::faceCells
Smooth ATC in cells next to a set of patches supplied by type.
Definition: faceCells.H:56
Foam::GAMGAgglomeration::procCellOffsets_
PtrList< labelList > procCellOffsets_
Mapping from processor to procMeshLevel cells.
Definition: GAMGAgglomeration.H:133
Foam::GAMGAgglomeration::agglomProcIDs_
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
Definition: GAMGAgglomeration.H:127
Foam::lduMesh
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition: lduMesh.H:62
Foam::GAMGProcAgglomeration::~GAMGProcAgglomeration
virtual ~GAMGProcAgglomeration()
Destructor.
Definition: GAMGProcAgglomeration.C:386
Foam::GAMGAgglomeration::procCommunicator_
labelList procCommunicator_
Communicator for given level.
Definition: GAMGAgglomeration.H:130