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 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "GAMGProcAgglomeration.H"
29 #include "GAMGAgglomeration.H"
30 #include "lduMesh.H"
31 
32 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33 
34 namespace Foam
35 {
36  defineTypeNameAndDebug(GAMGProcAgglomeration, 0);
37  defineRunTimeSelectionTable(GAMGProcAgglomeration, GAMGAgglomeration);
38 }
39 
40 
41 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
42 
44 (
45  Ostream& os,
46  GAMGAgglomeration& agglom
47 ) const
48 {
49  for (label levelI = 0; levelI <= agglom.size(); levelI++)
50  {
51  if (agglom.hasMeshLevel(levelI))
52  {
53  os << agglom.meshLevel(levelI).info() << endl;
54  }
55  else
56  {
57  os << "Level " << levelI << " has no fine mesh:" << endl;
58  }
59 
60  if
61  (
62  levelI < agglom.restrictAddressing_.size()
63  && agglom.restrictAddressing_.set(levelI)
64  )
65  {
66  const labelList& cellRestrict =
67  agglom.restrictAddressing(levelI);
68  const labelList& faceRestrict =
69  agglom.faceRestrictAddressing(levelI);
70 
71  os << "Level " << levelI << " agglomeration:" << nl
72  << " nCoarseCells:" << agglom.nCells(levelI) << nl
73  << " nCoarseFaces:" << agglom.nFaces(levelI) << nl
74  << " cellRestriction:"
75  << " size:" << cellRestrict.size()
76  << " max:" << max(cellRestrict)
77  << nl
78  << " faceRestriction:"
79  << " size:" << faceRestrict.size()
80  << " max:" << max(faceRestrict)
81  << nl;
82 
83  const labelListList& patchFaceRestrict =
84  agglom.patchFaceRestrictAddressing(levelI);
85  forAll(patchFaceRestrict, i)
86  {
87  if (patchFaceRestrict[i].size())
88  {
89  const labelList& faceRestrict =
90  patchFaceRestrict[i];
91  os << " " << i
92  << " size:" << faceRestrict.size()
93  << " max:" << max(faceRestrict)
94  << nl;
95  }
96  }
97  }
98  if
99  (
100  levelI < agglom.procCellOffsets_.size()
101  && agglom.procCellOffsets_.set(levelI)
102  )
103  {
104  os << " procCellOffsets:" << agglom.procCellOffsets_[levelI]
105  << nl
106  << " procAgglomMap:" << agglom.procAgglomMap_[levelI]
107  << nl
108  << " procIDs:" << agglom.agglomProcIDs_[levelI]
109  << nl
110  << " comm:" << agglom.procCommunicator_[levelI]
111  << endl;
112  }
113 
114  os << endl;
115  }
116  os << endl;
117 }
118 
119 
121 (
122  const lduMesh& mesh
123 )
124 {
125  const lduAddressing& addr = mesh.lduAddr();
126  lduInterfacePtrsList interfaces = mesh.interfaces();
127 
128  const label myProcID = Pstream::myProcNo(mesh.comm());
129 
130  globalIndex globalNumbering
131  (
132  addr.size(),
133  Pstream::msgType(),
134  mesh.comm(),
135  Pstream::parRun()
136  );
137 
138  labelList globalIndices
139  (
140  identity
141  (
142  globalNumbering.localSize(myProcID),
143  globalNumbering.localStart(myProcID)
144  )
145  );
146 
147  // Get the interface cells
148  PtrList<labelList> nbrGlobalCells(interfaces.size());
149  {
150  const label nReq = Pstream::nRequests();
151 
152  // Initialise transfer of restrict addressing on the interface
153  forAll(interfaces, inti)
154  {
155  if (interfaces.set(inti))
156  {
157  interfaces[inti].initInternalFieldTransfer
158  (
159  Pstream::commsTypes::nonBlocking,
160  globalIndices
161  );
162  }
163  }
164 
165  if (Pstream::parRun())
166  {
167  Pstream::waitRequests(nReq);
168  }
169 
170  forAll(interfaces, inti)
171  {
172  if (interfaces.set(inti))
173  {
174  nbrGlobalCells.set
175  (
176  inti,
177  new labelList
178  (
179  interfaces[inti].internalFieldTransfer
180  (
181  Pstream::commsTypes::nonBlocking,
182  globalIndices
183  )
184  )
185  );
186  }
187  }
188  }
189 
190 
191  // Scan the neighbour list to find out how many times the cell
192  // appears as a neighbour of the face. Done this way to avoid guessing
193  // and resizing list
194  labelList nNbrs(addr.size(), 1);
195 
196  const labelUList& nbr = addr.upperAddr();
197  const labelUList& own = addr.lowerAddr();
198 
199  {
200  forAll(nbr, facei)
201  {
202  nNbrs[nbr[facei]]++;
203  nNbrs[own[facei]]++;
204  }
205 
206  forAll(interfaces, inti)
207  {
208  if (interfaces.set(inti))
209  {
210  const labelUList& faceCells = interfaces[inti].faceCells();
211 
212  forAll(faceCells, i)
213  {
214  nNbrs[faceCells[i]]++;
215  }
216  }
217  }
218  }
219 
220 
221  // Create cell-cells addressing
222  labelListList cellCells(addr.size());
223 
224  forAll(cellCells, celli)
225  {
226  cellCells[celli].setSize(nNbrs[celli], -1);
227  }
228 
229  // Reset the list of number of neighbours to zero
230  nNbrs = 0;
231 
232  // Scatter the neighbour faces
233  forAll(nbr, facei)
234  {
235  label c0 = own[facei];
236  label c1 = nbr[facei];
237 
238  cellCells[c0][nNbrs[c0]++] = globalIndices[c1];
239  cellCells[c1][nNbrs[c1]++] = globalIndices[c0];
240  }
241  forAll(interfaces, inti)
242  {
243  if (interfaces.set(inti))
244  {
245  const labelUList& faceCells = interfaces[inti].faceCells();
246 
247  forAll(faceCells, i)
248  {
249  label c0 = faceCells[i];
250  cellCells[c0][nNbrs[c0]++] = nbrGlobalCells[inti][i];
251  }
252  }
253  }
254 
255  forAll(cellCells, celli)
256  {
257  Foam::stableSort(cellCells[celli]);
258  }
259 
260  // Replace the initial element (always -1) with the local cell
261  forAll(cellCells, celli)
262  {
263  cellCells[celli][0] = globalIndices[celli];
264  }
265 
266  return cellCells;
267 }
268 
269 
271 (
272  const label fineLevelIndex,
273  const labelList& procAgglomMap,
274  const labelList& masterProcs,
275  const List<label>& agglomProcIDs,
276  const label procAgglomComm
277 )
278 {
279  const lduMesh& levelMesh = agglom_.meshLevels_[fineLevelIndex];
280  label levelComm = levelMesh.comm();
281 
282  if (Pstream::myProcNo(levelComm) != -1)
283  {
284  // Collect meshes and restrictAddressing onto master
285  // Overwrites the fine mesh (meshLevels_[index-1]) and addressing
286  // from fine mesh to coarse mesh (restrictAddressing_[index]).
287  agglom_.procAgglomerateLduAddressing
288  (
289  levelComm,
290  procAgglomMap,
291  agglomProcIDs,
292  procAgglomComm,
293 
294  fineLevelIndex //fine level index
295  );
296 
297  // Combine restrict addressing only onto master
298  for
299  (
300  label levelI = fineLevelIndex+1;
301  levelI < agglom_.meshLevels_.size();
302  levelI++
303  )
304  {
305  agglom_.procAgglomerateRestrictAddressing
306  (
307  levelComm,
308  agglomProcIDs,
309  levelI
310  );
311  }
312 
313  if (Pstream::myProcNo(levelComm) == agglomProcIDs[0])
314  {
315  // On master. Recreate coarse meshes from restrict addressing
316  for
317  (
318  label levelI = fineLevelIndex;
319  levelI < agglom_.meshLevels_.size();
320  levelI++
321  )
322  {
323  agglom_.agglomerateLduAddressing(levelI);
324  }
325  }
326  else
327  {
328  // Agglomerated away. Clear mesh storage.
329  for
330  (
331  label levelI = fineLevelIndex+1;
332  levelI <= agglom_.size();
333  levelI++
334  )
335  {
336  agglom_.clearLevel(levelI);
337  }
338  }
339  }
340 
341  // Should check!
342  return true;
343 }
344 
345 
346 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
347 
348 Foam::GAMGProcAgglomeration::GAMGProcAgglomeration
349 (
350  GAMGAgglomeration& agglom,
351  const dictionary& controlDict
352 )
353 :
354  agglom_(agglom)
355 {}
356 
357 
359 (
360  const word& type,
361  GAMGAgglomeration& agglom,
362  const dictionary& controlDict
363 )
364 {
365  DebugInFunction << "Constructing GAMGProcAgglomeration" << endl;
366 
367  auto cstrIter = GAMGAgglomerationConstructorTablePtr_->cfind(type);
368 
369  if (!cstrIter.found())
370  {
372  << "Unknown GAMGProcAgglomeration type "
373  << type << " for GAMGAgglomeration " << agglom.type() << nl << nl
374  << "Valid GAMGProcAgglomeration types :" << endl
375  << GAMGAgglomerationConstructorTablePtr_->sortedToc()
376  << exit(FatalError);
377  }
378 
379  return autoPtr<GAMGProcAgglomeration>(cstrIter()(agglom, controlDict));
380 }
381 
382 
383 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
384 
386 {}
387 
388 
389 // ************************************************************************* //
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:97
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
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:452
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:350
Foam::GAMGAgglomeration::hasMeshLevel
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
Definition: GAMGAgglomeration.C:467
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:268
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:365
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:62
Foam::GAMGProcAgglomeration::New
static autoPtr< GAMGProcAgglomeration > New(const word &type, GAMGAgglomeration &agglom, const dictionary &controlDict)
Return the selected agglomerator.
Definition: GAMGProcAgglomeration.C:359
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:44
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:121
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:381
Foam::UPtrList::set
const T * set(const label i) const
Return const pointer to element (can be nullptr),.
Definition: UPtrList.H:170
Foam::nl
constexpr char nl
Definition: Ostream.H:385
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:121
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:385
Foam::GAMGAgglomeration::procCommunicator_
labelList procCommunicator_
Communicator for given level.
Definition: GAMGAgglomeration.H:130