masterCoarsestGAMGProcAgglomeration.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-2014 OpenFOAM Foundation
9  Copyright (C) 2022-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 \*---------------------------------------------------------------------------*/
28 
31 #include "GAMGAgglomeration.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 namespace Foam
36 {
37  defineTypeNameAndDebug(masterCoarsestGAMGProcAgglomeration, 0);
38 
40  (
41  GAMGProcAgglomeration,
42  masterCoarsestGAMGProcAgglomeration,
43  GAMGAgglomeration
44  );
45 }
46 
47 
48 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
49 
50 Foam::masterCoarsestGAMGProcAgglomeration::masterCoarsestGAMGProcAgglomeration
51 (
52  GAMGAgglomeration& agglom,
53  const dictionary& controlDict
54 )
55 :
57  nProcessorsPerMaster_
58  (
59  controlDict.getOrDefault<label>
60  (
61  "nProcessorsPerMaster",
62  0,
63  keyType::LITERAL
64  )
65  ),
66  nCellsInMasterLevel_
67  (
68  controlDict.getOrDefault<label>("nCellsInMasterLevel", -1)
69  )
70 {
71  const auto* ePtr = controlDict.findEntry("nMasters", keyType::LITERAL);
72  if (ePtr)
73  {
74  if (nProcessorsPerMaster_ > 0)
75  {
77  << "Cannot specify both \"nMasters\" and"
78  << " \"nProcessorsPerMaster\"" << exit(FatalIOError);
79  }
80 
81  const label nMasters(readLabel(ePtr->stream()));
82 
83  if (nMasters <= 0)
84  {
86  << "Illegal value \"nMasters\" "
87  << nMasters << exit(FatalIOError);
88  }
89 
90  nProcessorsPerMaster_ =
91  (Pstream::nProcs(agglom.mesh().comm())+nMasters-1)
92  / nMasters;
93  }
94 
95  if (nProcessorsPerMaster_ < 0)
96  {
98  << "Illegal value \"nProcessorsPerMaster\" "
99  << nProcessorsPerMaster_ << exit(FatalIOError);
100  }
101 }
102 
103 
104 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
105 
108 {}
109 
110 
111 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
112 
114 {
115  if (debug & 2)
116  {
117  Pout<< nl << "Starting mesh overview" << endl;
118  printStats(Pout, agglom_);
119  }
120 
121  if (agglom_.size() >= 1)
122  {
123  // Agglomerate one but last level (since also agglomerating
124  // restrictAddressing)
125  label fineLevelIndex = agglom_.size()-1;
126 
127  if (agglom_.hasMeshLevel(fineLevelIndex))
128  {
129  // Get the fine mesh
130  const lduMesh& levelMesh = agglom_.meshLevel(fineLevelIndex);
131  label levelComm = levelMesh.comm();
132  label nProcs = UPstream::nProcs(levelComm);
133 
134  if (nProcs > 1)
135  {
136  // Processor restriction map: per processor the coarse processor
137  labelList procAgglomMap(nProcs);
138 
139  if (nProcessorsPerMaster_ > 0)
140  {
141  forAll(procAgglomMap, fineProci)
142  {
143  procAgglomMap[fineProci] =
144  (
145  fineProci
146  / nProcessorsPerMaster_
147  );
148  }
149  }
150  else
151  {
152  procAgglomMap = Zero;
153  }
154 
155  // Master processor
156  labelList masterProcs;
157  // Local processors that agglomerate. agglomProcIDs[0] is in
158  // masterProc.
159  List<label> agglomProcIDs;
161  (
162  levelComm,
163  procAgglomMap,
164  masterProcs,
165  agglomProcIDs
166  );
167 
168  if (debug)
169  {
170  if (masterProcs.size())
171  {
172  labelListList masterToProcs
173  (
175  (
176  masterProcs.size(),
177  procAgglomMap
178  )
179  );
180  Info<< typeName << " : agglomerating" << nl
181  << "\tmaster\tnProcs\tprocIDs" << endl;
182  for (const auto& p : masterToProcs)
183  {
184  Info<< '\t' << p[0]
185  << '\t' << p.size()
186  << '\t'
187  << flatOutput(SubList<label>(p, p.size()-1, 1))
188  << endl;
189  }
190  }
191  }
192 
193 
194  // Communicator for the processor-agglomerated matrix
195  comms_.push_back
196  (
198  (
199  levelComm,
200  masterProcs
201  )
202  );
203 
204  // Use processor agglomeration maps to do the actual collecting.
205  if (UPstream::myProcNo(levelComm) != -1)
206  {
208  (
209  fineLevelIndex,
210  procAgglomMap,
211  masterProcs,
212  agglomProcIDs,
213  comms_.back()
214  );
215 
216  if (nCellsInMasterLevel_ > 0)
217  {
218  const label levelI = agglom_.size();
219  if (agglom_.hasMeshLevel(levelI))
220  {
221  const lduMesh& fineMesh = agglom_.meshLevel(levelI);
222  const auto& addr = fineMesh.lduAddr();
223  const scalarField weights
224  (
225  addr.lowerAddr().size(),
226  1.0
227  );
228  agglom_.agglomerate
229  (
230  nCellsInMasterLevel_,
231  levelI,
232  weights,
233  false
234  );
235  }
236  }
237  }
238  }
239  }
240 
241 
242  // Note that at this point for nCellsInMasterLevel_ the non-master
243  // processors will have less levels. This does/should not matter since
244  // they are not involved in those levels
245  }
246 
247  // Print a bit
248  if (debug & 2)
249  {
250  Pout<< nl << "Agglomerated mesh overview" << endl;
251  printStats(Pout, agglom_);
252  }
253 
254  return true;
255 }
256 
257 
258 // ************************************************************************* //
A class for handling keywords in dictionaries.
Definition: keyType.H:66
virtual bool agglomerate()
Modify agglomeration. Return true if modified.
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
A list of keyword definitions, which are a keyword followed by a number of values (eg...
Definition: dictionary.H:129
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
label readLabel(const char *buf)
Parse entire buffer as a label, skipping leading/trailing whitespace.
Definition: label.H:63
virtual label comm() const =0
Return communicator used for parallel communication.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
List< labelList > labelListList
List of labelList.
Definition: labelList.H:38
Macros for easy insertion into run-time selection tables.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1065
labelListList invertOneToMany(const label len, const labelUList &map)
Invert one-to-many map. Unmapped elements will be size 0.
Definition: ListOps.C:107
const Mesh & mesh() const noexcept
Reference to the mesh.
Definition: MeshObject.H:157
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
String literal.
Definition: keyType.H:82
runTime controlDict().readEntry("adjustTimeStep"
The central control dictionary, the contents of which are either taken directly from the FOAM_CONTROL...
Definition: debug.C:142
int debug
Static debugging option.
defineTypeNameAndDebug(combustionModel, 0)
virtual bool agglomerate()=0
Modify agglomeration.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
Processor agglomeration of GAMGAgglomerations.
messageStream Info
Information stream (stdout output on master, null elsewhere)
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
Geometric agglomerated algebraic multigrid agglomeration class.
static void calculateRegionMaster(const label comm, const labelList &procAgglomMap, labelList &masterProcs, List< label > &agglomProcIDs)
Given fine to coarse processor map determine:
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
static label allocateCommunicator(const label parent, const labelRange &subRanks, const bool withComponents=true)
Allocate new communicator with contiguous sub-ranks on the parent communicator.
Definition: UPstream.C:258
Namespace for OpenFOAM.
addToRunTimeSelectionTable(functionObject, pointHistory, dictionary)
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127