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  // Initialise transfer of restrict addressing on the interface
151  forAll(interfaces, inti)
152  {
153  if (interfaces.set(inti))
154  {
155  interfaces[inti].initInternalFieldTransfer
156  (
157  Pstream::commsTypes::nonBlocking,
158  globalIndices
159  );
160  }
161  }
162 
163  if (Pstream::parRun())
164  {
165  Pstream::waitRequests();
166  }
167 
168  forAll(interfaces, inti)
169  {
170  if (interfaces.set(inti))
171  {
172  nbrGlobalCells.set
173  (
174  inti,
175  new labelList
176  (
177  interfaces[inti].internalFieldTransfer
178  (
179  Pstream::commsTypes::nonBlocking,
180  globalIndices
181  )
182  )
183  );
184  }
185  }
186  }
187 
188 
189  // Scan the neighbour list to find out how many times the cell
190  // appears as a neighbour of the face. Done this way to avoid guessing
191  // and resizing list
192  labelList nNbrs(addr.size(), 1);
193 
194  const labelUList& nbr = addr.upperAddr();
195  const labelUList& own = addr.lowerAddr();
196 
197  {
198  forAll(nbr, facei)
199  {
200  nNbrs[nbr[facei]]++;
201  nNbrs[own[facei]]++;
202  }
203 
204  forAll(interfaces, inti)
205  {
206  if (interfaces.set(inti))
207  {
208  const labelUList& faceCells = interfaces[inti].faceCells();
209 
210  forAll(faceCells, i)
211  {
212  nNbrs[faceCells[i]]++;
213  }
214  }
215  }
216  }
217 
218 
219  // Create cell-cells addressing
220  labelListList cellCells(addr.size());
221 
222  forAll(cellCells, celli)
223  {
224  cellCells[celli].setSize(nNbrs[celli], -1);
225  }
226 
227  // Reset the list of number of neighbours to zero
228  nNbrs = 0;
229 
230  // Scatter the neighbour faces
231  forAll(nbr, facei)
232  {
233  label c0 = own[facei];
234  label c1 = nbr[facei];
235 
236  cellCells[c0][nNbrs[c0]++] = globalIndices[c1];
237  cellCells[c1][nNbrs[c1]++] = globalIndices[c0];
238  }
239  forAll(interfaces, inti)
240  {
241  if (interfaces.set(inti))
242  {
243  const labelUList& faceCells = interfaces[inti].faceCells();
244 
245  forAll(faceCells, i)
246  {
247  label c0 = faceCells[i];
248  cellCells[c0][nNbrs[c0]++] = nbrGlobalCells[inti][i];
249  }
250  }
251  }
252 
253  forAll(cellCells, celli)
254  {
255  Foam::stableSort(cellCells[celli]);
256  }
257 
258  // Replace the initial element (always -1) with the local cell
259  forAll(cellCells, celli)
260  {
261  cellCells[celli][0] = globalIndices[celli];
262  }
263 
264  return cellCells;
265 }
266 
267 
269 (
270  const label fineLevelIndex,
271  const labelList& procAgglomMap,
272  const labelList& masterProcs,
273  const List<label>& agglomProcIDs,
274  const label procAgglomComm
275 )
276 {
277  const lduMesh& levelMesh = agglom_.meshLevels_[fineLevelIndex];
278  label levelComm = levelMesh.comm();
279 
280  if (Pstream::myProcNo(levelComm) != -1)
281  {
282  // Collect meshes and restrictAddressing onto master
283  // Overwrites the fine mesh (meshLevels_[index-1]) and addressing
284  // from fine mesh to coarse mesh (restrictAddressing_[index]).
285  agglom_.procAgglomerateLduAddressing
286  (
287  levelComm,
288  procAgglomMap,
289  agglomProcIDs,
290  procAgglomComm,
291 
292  fineLevelIndex //fine level index
293  );
294 
295  // Combine restrict addressing only onto master
296  for
297  (
298  label levelI = fineLevelIndex+1;
299  levelI < agglom_.meshLevels_.size();
300  levelI++
301  )
302  {
303  agglom_.procAgglomerateRestrictAddressing
304  (
305  levelComm,
306  agglomProcIDs,
307  levelI
308  );
309  }
310 
311  if (Pstream::myProcNo(levelComm) == agglomProcIDs[0])
312  {
313  // On master. Recreate coarse meshes from restrict addressing
314  for
315  (
316  label levelI = fineLevelIndex;
317  levelI < agglom_.meshLevels_.size();
318  levelI++
319  )
320  {
321  agglom_.agglomerateLduAddressing(levelI);
322  }
323  }
324  else
325  {
326  // Agglomerated away. Clear mesh storage.
327  for
328  (
329  label levelI = fineLevelIndex+1;
330  levelI <= agglom_.size();
331  levelI++
332  )
333  {
334  agglom_.clearLevel(levelI);
335  }
336  }
337  }
338 
339  // Should check!
340  return true;
341 }
342 
343 
344 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
345 
346 Foam::GAMGProcAgglomeration::GAMGProcAgglomeration
347 (
348  GAMGAgglomeration& agglom,
349  const dictionary& controlDict
350 )
351 :
352  agglom_(agglom)
353 {}
354 
355 
357 (
358  const word& type,
359  GAMGAgglomeration& agglom,
360  const dictionary& controlDict
361 )
362 {
363  DebugInFunction << "Constructing GAMGProcAgglomeration" << endl;
364 
365  auto cstrIter = GAMGAgglomerationConstructorTablePtr_->cfind(type);
366 
367  if (!cstrIter.found())
368  {
370  << "Unknown GAMGProcAgglomeration type "
371  << type << " for GAMGAgglomeration " << agglom.type() << nl << nl
372  << "Valid GAMGProcAgglomeration types :" << endl
373  << GAMGAgglomerationConstructorTablePtr_->sortedToc()
374  << exit(FatalError);
375  }
376 
377  return autoPtr<GAMGProcAgglomeration>(cstrIter()(agglom, controlDict));
378 }
379 
380 
381 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
382 
384 {}
385 
386 
387 // ************************************************************************* //
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:90
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
Foam::UPtrList::set
const T * set(const label i) const
Return const pointer to element (if set) or nullptr.
Definition: UPtrListI.H:176
GAMGAgglomeration.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:337
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:290
Foam::stableSort
void stableSort(UList< T > &a)
Definition: UList.C:255
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].
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
DebugInFunction
#define DebugInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:356
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:65
Foam::GAMGProcAgglomeration::New
static autoPtr< GAMGProcAgglomeration > New(const word &type, GAMGAgglomeration &agglom, const dictionary &controlDict)
Return the selected agglomerator.
Definition: GAMGProcAgglomeration.C:357
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:355
Foam::nl
constexpr char nl
Definition: Ostream.H:372
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:383
Foam::GAMGAgglomeration::procCommunicator_
labelList procCommunicator_
Communicator for given level.
Definition: GAMGAgglomeration.H:130