Loading...
Searching...
No Matches
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-2023 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
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
31#include "lduMesh.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
35namespace Foam
36{
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 << "Level " << levelI << " mesh:"
55 << agglom.meshLevel(levelI).info() << endl;
56 }
57 else
58 {
59 os << "Level " << levelI << " has no fine mesh:" << endl;
60 }
61
62 if
63 (
64 levelI < agglom.restrictAddressing_.size()
65 && agglom.restrictAddressing_.set(levelI)
66 )
67 {
68 const labelList& cellRestrict =
69 agglom.restrictAddressing(levelI);
70 const labelList& faceRestrict =
71 agglom.faceRestrictAddressing(levelI);
72
73 os << "Level " << levelI << " agglomeration:" << nl
74 << " nCoarseCells:" << agglom.nCells(levelI) << nl
75 << " nCoarseFaces:" << agglom.nFaces(levelI) << nl
76 << " cellRestriction:"
77 << " size:" << cellRestrict.size()
78 << " max:" << max(cellRestrict)
79 << nl
80 << " faceRestriction:"
81 << " size:" << faceRestrict.size()
82 << " max:" << max(faceRestrict)
83 << nl;
84
85 const labelListList& patchFaceRestrict =
86 agglom.patchFaceRestrictAddressing(levelI);
87 forAll(patchFaceRestrict, i)
88 {
89 if (patchFaceRestrict[i].size())
90 {
91 const labelList& faceRestrict =
92 patchFaceRestrict[i];
93 os << " " << i
94 << " size:" << faceRestrict.size()
95 << " max:" << max(faceRestrict)
96 << nl;
97 }
98 }
99 }
100 if
101 (
102 levelI < agglom.procCellOffsets_.size()
103 && agglom.procCellOffsets_.set(levelI)
104 )
105 {
106 os << " procCellOffsets:" << agglom.procCellOffsets_[levelI]
107 << nl
108 << " procAgglomMap:" << agglom.procAgglomMap_[levelI]
109 << nl
110 << " procIDs:" << agglom.agglomProcIDs_[levelI]
111 << nl
112 << " comm:" << agglom.procCommunicator_[levelI]
113 << endl;
114 }
116 os << endl;
117 }
118 os << endl;
119}
120
121
123(
124 const lduMesh& mesh
125)
126{
127 const lduAddressing& addr = mesh.lduAddr();
128 lduInterfacePtrsList interfaces = mesh.interfaces();
129
130 const label myProci = UPstream::myProcNo(mesh.comm());
131
132 const globalIndex globalNumbering
133 (
134 addr.size(),
135 mesh.comm(),
137 );
138
139 const labelList globalIndices
140 (
141 Foam::identity(globalNumbering.range(myProci))
142 );
143
144 // Get the interface cells
145 PtrList<labelList> nbrGlobalCells(interfaces.size());
146 {
147 const label startOfRequests = UPstream::nRequests();
148
149 // Initialise transfer of restrict addressing on the interface
150 forAll(interfaces, inti)
151 {
152 if (interfaces.set(inti))
153 {
154 interfaces[inti].initInternalFieldTransfer
155 (
157 globalIndices
158 );
159 }
160 }
161
162 UPstream::waitRequests(startOfRequests);
163
164 forAll(interfaces, inti)
165 {
166 if (interfaces.set(inti))
167 {
168 nbrGlobalCells.set
169 (
170 inti,
171 new labelList
172 (
173 interfaces[inti].internalFieldTransfer
174 (
176 globalIndices
177 )
178 )
179 );
180 }
181 }
182 }
183
184
185 // Scan the neighbour list to find out how many times the cell
186 // appears as a neighbour of the face. Done this way to avoid guessing
187 // and resizing list
188 labelList nNbrs(addr.size(), 1);
189
190 const labelUList& nbr = addr.upperAddr();
191 const labelUList& own = addr.lowerAddr();
192
193 {
194 forAll(nbr, facei)
195 {
196 nNbrs[nbr[facei]]++;
197 nNbrs[own[facei]]++;
198 }
199
200 forAll(interfaces, inti)
201 {
202 if (interfaces.set(inti))
203 {
204 const labelUList& faceCells = interfaces[inti].faceCells();
205
206 forAll(faceCells, i)
207 {
208 nNbrs[faceCells[i]]++;
209 }
210 }
211 }
212 }
213
214
215 // Create cell-cells addressing
216 labelListList cellCells(addr.size());
217
218 forAll(cellCells, celli)
219 {
220 cellCells[celli].setSize(nNbrs[celli], -1);
221 }
222
223 // Reset the list of number of neighbours to zero
224 nNbrs = 0;
225
226 // Scatter the neighbour faces
227 forAll(nbr, facei)
228 {
229 label c0 = own[facei];
230 label c1 = nbr[facei];
231
232 cellCells[c0][nNbrs[c0]++] = globalIndices[c1];
233 cellCells[c1][nNbrs[c1]++] = globalIndices[c0];
234 }
235 forAll(interfaces, inti)
236 {
237 if (interfaces.set(inti))
238 {
239 const labelUList& faceCells = interfaces[inti].faceCells();
240
241 forAll(faceCells, i)
242 {
243 label c0 = faceCells[i];
244 cellCells[c0][nNbrs[c0]++] = nbrGlobalCells[inti][i];
245 }
246 }
247 }
248
249 forAll(cellCells, celli)
250 {
251 Foam::stableSort(cellCells[celli]);
252 }
253
254 // Replace the initial element (always -1) with the local cell
255 forAll(cellCells, celli)
256 {
257 cellCells[celli][0] = globalIndices[celli];
258 }
259
260 return cellCells;
261}
262
263
265(
266 const label fineLevelIndex,
267 const labelList& procAgglomMap,
268 const labelList& masterProcs,
269 const List<label>& agglomProcIDs,
270 const label procAgglomComm
271)
272{
273 const lduMesh& levelMesh = agglom_.meshLevels_[fineLevelIndex];
274 label levelComm = levelMesh.comm();
275
276 if (fineLevelIndex > 0 && Pstream::myProcNo(levelComm) != -1)
277 {
278 // Collect meshes and restrictAddressing onto master
279 // Overwrites the fine mesh (meshLevels_[index-1]) and addressing
280 // from fine mesh to coarse mesh (restrictAddressing_[index]).
281 agglom_.procAgglomerateLduAddressing
282 (
283 levelComm,
284 procAgglomMap,
285 agglomProcIDs,
286 procAgglomComm,
287
288 fineLevelIndex //fine level index
289 );
290
291 // Combine restrict addressing only onto master
292 for
293 (
294 label levelI = fineLevelIndex+1;
295 levelI < agglom_.meshLevels_.size();
296 levelI++
297 )
298 {
299 agglom_.procAgglomerateRestrictAddressing
300 (
301 levelComm,
302 agglomProcIDs,
303 levelI
304 );
305 }
306
307 if (Pstream::myProcNo(levelComm) == agglomProcIDs[0])
308 {
309 // On master. Recreate coarse meshes from restrict addressing
310 for
311 (
312 label levelI = fineLevelIndex;
313 levelI < agglom_.meshLevels_.size();
314 levelI++
315 )
316 {
317 agglom_.agglomerateLduAddressing(levelI);
318 }
319 }
320 else
321 {
322 // Agglomerated away. Clear mesh storage.
323 for
324 (
325 label levelI = fineLevelIndex+1;
326 levelI <= agglom_.size();
327 levelI++
328 )
329 {
330 agglom_.clearLevel(levelI);
331 }
332 }
333 }
334
335 // Should check!
336 return true;
337}
338
339
340// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
341
343(
344 GAMGAgglomeration& agglom,
346)
347:
348 agglom_(agglom)
349{}
350
351
353(
354 const word& type,
355 GAMGAgglomeration& agglom,
357)
358{
359 DebugInFunction << "Constructing GAMGProcAgglomeration" << endl;
360
361 auto* ctorPtr = GAMGAgglomerationConstructorTable(type);
362
363 if (!ctorPtr)
364 {
366 << "Unknown GAMGProcAgglomeration type "
367 << type << " for GAMGAgglomeration " << agglom.type() << nl << nl
368 << "Valid GAMGProcAgglomeration types :" << endl
369 << GAMGAgglomerationConstructorTablePtr_->sortedToc()
370 << exit(FatalError);
371 }
373 return autoPtr<GAMGProcAgglomeration>(ctorPtr(agglom, controlDict));
374}
375
376
377// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
378
382}
383
384
385// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
386
388{
389 forAllReverse(comms_, i)
390 {
392 }
393 comms_.clear();
394}
395
396
397// ************************************************************************* //
Geometric agglomerated algebraic multigrid agglomeration class.
const labelList & faceRestrictAddressing(const label leveli) const
Return face restrict addressing of given level.
const labelListList & patchFaceRestrictAddressing(const label leveli) const
labelList procCommunicator_
Communicator for given level.
PtrList< labelList > agglomProcIDs_
Per level the set of processors to agglomerate. Element 0 is.
PtrList< labelList > procAgglomMap_
Per level, per processor the processor it agglomerates into.
PtrList< labelList > procCellOffsets_
Mapping from processor to procMeshLevel cells.
PtrList< labelField > restrictAddressing_
Cell restriction addressing array.
const labelField & restrictAddressing(const label leveli) const
Return cell restrict addressing of given level.
bool hasMeshLevel(const label leveli) const
Do we have mesh for given level?
label nCells(const label leveli) const
Return number of coarse cells (before processor agglomeration).
const lduMesh & meshLevel(const label leveli) const
Return LDU mesh of given level.
label nFaces(const label leveli) const
Return number of coarse faces (before processor agglomeration).
Processor agglomeration of GAMGAgglomerations.
virtual bool agglomerate()=0
Modify agglomeration.
GAMGAgglomeration & agglom_
Reference to agglomeration.
static autoPtr< GAMGProcAgglomeration > New(const word &type, GAMGAgglomeration &agglom, const dictionary &controlDict)
Return the selected agglomerator.
void printStats(Ostream &os, GAMGAgglomeration &agglom) const
Debug: write agglomeration info.
void clearCommunicators()
Clear/free allocated communicators.
DynamicList< label > comms_
Allocated communicators.
static labelListList globalCellCells(const lduMesh &)
Debug: calculate global cell-cells.
virtual ~GAMGProcAgglomeration()
Destructor. Clears allocated communicators.
GAMGProcAgglomeration(const GAMGProcAgglomeration &)=delete
No copy construct.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
void setSize(label n)
Alias for resize().
Definition List.H:536
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition Ostream.H:59
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Definition PtrList.H:67
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Definition PtrList.H:171
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition UPstream.H:1706
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests).
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
Definition UPstream.H:84
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static void waitRequests()
Wait for all requests to finish.
Definition UPstream.H:2497
static void freeCommunicator(const label communicator, const bool withComponents=true)
Free a previously allocated communicator.
Definition UPstream.C:622
static bool & parRun() noexcept
Test if this a parallel run.
Definition UPstream.H:1681
const T * set(const label i) const
Return const pointer to element (can be nullptr), or nullptr for out-of-range access (ie,...
Definition UPtrList.H:366
label size() const noexcept
The number of entries in the list.
Definition UPtrListI.H:106
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition dictionary.H:133
Smooth ATC in cells next to a set of patches supplied by type.
Definition faceCells.H:55
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
Definition globalIndex.H:77
labelRange range(label proci) const noexcept
Return start/size range of proci data.
The class contains the addressing required by the lduMatrix: upper, lower and losort.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
label size() const noexcept
Return number of equations.
Abstract base class for meshes which provide LDU addressing for the construction of lduMatrix and LDU...
Definition lduMesh.H:54
virtual label comm() const =0
Return communicator used for parallel communication.
InfoProxy< lduMesh > info() const noexcept
Return info proxy, used to print mesh information to a stream.
Definition lduMesh.H:115
A class for handling words, derived from Foam::string.
Definition word.H:66
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition className.H:142
runTime controlDict().readEntry("adjustTimeStep"
dynamicFvMesh & mesh
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
OBJstream os(runTime.globalPath()/outputName)
#define DebugInFunction
Report an information message using Foam::Info.
const dimensionedScalar c1
First radiation constant: default SI units: [W/m2].
Namespace for OpenFOAM.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition hashSets.C:40
List< labelList > labelListList
List of labelList.
Definition labelList.H:38
List< label > labelList
A List of labels.
Definition List.H:62
UPtrList< const lduInterface > lduInterfacePtrsList
Store lists of lduInterface as a UPtrList.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition errorManip.H:125
UList< label > labelUList
A UList of labels.
Definition UList.H:75
void stableSort(UList< T > &list)
Stable sort the list.
Definition UList.C:299
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
#define defineRunTimeSelectionTable(baseType, argNames)
Define run-time selection table.
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition stdFoam.H:315