metisLikeDecomp.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) 2017-2021 OpenCFD Ltd.
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 "metisLikeDecomp.H"
29 #include "Time.H"
30 #include "globalIndex.H"
31 
32 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
33 
35 (
36  const labelList& adjncy,
37  const labelList& xadj,
38  const List<scalar>& cWeights,
39  labelList& decomp
40 ) const
41 {
42  if (!Pstream::parRun())
43  {
44  return decomposeSerial
45  (
46  adjncy,
47  xadj,
48  cWeights,
49  decomp
50  );
51  }
52 
53  if (debug)
54  {
55  Info<< type() << "Decomp : running in parallel."
56  << " Decomposing all of graph on master processor." << endl;
57  }
58  globalIndex globalCells(xadj.size()-1);
59  label nTotalConnections = returnReduce(adjncy.size(), sumOp<label>());
60 
61  // Send all to master. Use scheduled to save some storage.
62  if (Pstream::master())
63  {
64  List<label> allAdjncy(nTotalConnections);
65  List<label> allXadj(globalCells.size()+1);
66  List<scalar> allWeights(globalCells.size());
67 
68  // Insert my own
69  label nTotalCells = 0;
70  forAll(cWeights, celli)
71  {
72  allXadj[nTotalCells] = xadj[celli];
73  allWeights[nTotalCells++] = cWeights[celli];
74  }
75  nTotalConnections = 0;
76  forAll(adjncy, i)
77  {
78  allAdjncy[nTotalConnections++] = adjncy[i];
79  }
80 
81  for (const int slave : Pstream::subProcs())
82  {
83  IPstream fromSlave(Pstream::commsTypes::scheduled, slave);
84  List<label> nbrAdjncy(fromSlave);
85  List<label> nbrXadj(fromSlave);
86  List<scalar> nbrWeights(fromSlave);
87 
88  // Append.
89  forAll(nbrXadj, celli)
90  {
91  allXadj[nTotalCells] = nTotalConnections+nbrXadj[celli];
92  allWeights[nTotalCells++] = nbrWeights[celli];
93  }
94  // No need to renumber xadj since already global.
95  forAll(nbrAdjncy, i)
96  {
97  allAdjncy[nTotalConnections++] = nbrAdjncy[i];
98  }
99  }
100  allXadj[nTotalCells] = nTotalConnections;
101 
102  labelList allDecomp;
103  decomposeSerial
104  (
105  allAdjncy,
106  allXadj,
107  allWeights,
108  allDecomp
109  );
110 
111 
112  // Send allFinalDecomp back
113  for (const int slave : Pstream::subProcs())
114  {
115  OPstream toSlave(Pstream::commsTypes::scheduled, slave);
116  toSlave << SubList<label>
117  (
118  allDecomp,
119  globalCells.localSize(slave),
120  globalCells.offset(slave)
121  );
122  }
123 
124  // Get my own part (always first)
125  decomp = SubList<label>(allDecomp, globalCells.localSize());
126  }
127  else
128  {
129  // Send my part of the graph (already in global numbering)
130  {
131  OPstream toMaster
132  (
133  Pstream::commsTypes::scheduled,
134  Pstream::masterNo()
135  );
136  toMaster
137  << adjncy
138  << SubList<label>(xadj, xadj.size()-1)
139  << cWeights;
140  }
141 
142  // Receive back decomposition
143  IPstream fromMaster
144  (
145  Pstream::commsTypes::scheduled,
146  Pstream::masterNo()
147  );
148  fromMaster >> decomp;
149  }
150 
151  return 0;
152 }
153 
154 
155 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
156 
158 (
159  const word& derivedType,
160  const dictionary& decompDict,
161  const word& regionName,
162  int select
163 )
164 :
165  decompositionMethod(decompDict, regionName),
166  coeffsDict_(findCoeffsDict(derivedType + "Coeffs", select))
167 {}
168 
169 
170 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
171 
173 (
174  const polyMesh& mesh,
175  const pointField& points,
176  const scalarField& pointWeights
177 ) const
178 {
179  if (points.size() != mesh.nCells())
180  {
182  << "Can only use this decomposition method for entire mesh" << nl
183  << "and supply one coordinate (cellCentre) for every cell." << nl
184  << "The number of coordinates " << points.size() << nl
185  << "The number of cells in the mesh " << mesh.nCells() << nl
186  << exit(FatalError);
187  }
188 
189  CompactListList<label> cellCells;
190  calcCellCells
191  (
192  mesh,
193  identity(mesh.nCells()),
194  mesh.nCells(),
195  true,
196  cellCells
197  );
198 
199  // Decompose using default weights
200  labelList decomp;
201  decomposeGeneral(cellCells.m(), cellCells.offsets(), pointWeights, decomp);
202 
203  return decomp;
204 }
205 
206 
208 (
209  const polyMesh& mesh,
210  const labelList& agglom,
211  const pointField& agglomPoints,
212  const scalarField& agglomWeights
213 ) const
214 {
215  if (agglom.size() != mesh.nCells())
216  {
218  << "Size of cell-to-coarse map " << agglom.size()
219  << " differs from number of cells in mesh " << mesh.nCells()
220  << exit(FatalError);
221  }
222 
223  // Make Metis CSR (Compressed Storage Format) storage
224  // adjncy : contains neighbours (= edges in graph)
225  // xadj(celli) : start of information in adjncy for celli
226 
227  CompactListList<label> cellCells;
228  calcCellCells
229  (
230  mesh,
231  agglom,
232  agglomPoints.size(),
233  true,
234  cellCells
235  );
236 
237  // Decompose using default weights
238  labelList decomp;
239  decomposeGeneral(cellCells.m(), cellCells.offsets(), agglomWeights, decomp);
240 
241 
242  // Rework back into decomposition for original mesh
243  labelList fineDistribution(agglom.size());
244 
245  forAll(fineDistribution, i)
246  {
247  fineDistribution[i] = decomp[agglom[i]];
248  }
249 
250  return fineDistribution;
251 }
252 
253 
255 (
256  const labelListList& globalCellCells,
257  const pointField& cellCentres,
258  const scalarField& cellWeights
259 ) const
260 {
261  if (cellCentres.size() != globalCellCells.size())
262  {
264  << "Inconsistent number of cells (" << globalCellCells.size()
265  << ") and number of cell centres (" << cellCentres.size()
266  << ")." << exit(FatalError);
267  }
268 
269  // Make Metis CSR (Compressed Storage Format) storage
270  // adjncy : contains neighbours (= edges in graph)
271  // xadj(celli) : start of information in adjncy for celli
272 
273  CompactListList<label> cellCells(globalCellCells);
274 
275  // Decompose using default weights
276  labelList decomp;
277  decomposeGeneral(cellCells.m(), cellCells.offsets(), cellWeights, decomp);
278 
279  return decomp;
280 }
281 
282 // ************************************************************************* //
Foam::CompactListList::offsets
const List< label > & offsets() const
Return the offset table (= size()+1)
Definition: CompactListListI.H:142
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::CompactListList::m
const List< T > & m() const
Return the packed matrix of data.
Definition: CompactListListI.H:156
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::metisLikeDecomp::decomposeGeneral
virtual label decomposeGeneral(const labelList &adjncy, const labelList &xadj, const List< scalar > &cellWeights, labelList &decomp) const
Serial and/or collect/distribute for parallel operation.
Definition: metisLikeDecomp.C:35
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:94
Foam::OPstream
Output inter-processor communications stream.
Definition: OPstream.H:53
Foam::SubList
A List obtained as a section of another List.
Definition: SubList.H:54
Foam::CompactListList
A packed storage unstructured matrix of objects of type <T> using an offset table for access.
Definition: CompactListList.H:63
globalIndex.H
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:77
Foam::sumOp
Definition: ops.H:213
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
regionName
Foam::word regionName
Definition: createNamedDynamicFvMesh.H:1
Foam::Field< vector >
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
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
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::decompositionMethod
Abstract base class for domain decomposition.
Definition: decompositionMethod.H:51
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::metisLikeDecomp::decompose
virtual labelList decompose(const polyMesh &mesh, const pointField &points, const scalarField &pointWeights) const
Return for every coordinate the wanted processor number.
Definition: metisLikeDecomp.C:173
Time.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
metisLikeDecomp.H
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::List< label >
Foam::metisLikeDecomp::metisLikeDecomp
metisLikeDecomp(const metisLikeDecomp &)=delete
No copy construct.
points
const pointField & points
Definition: gmvOutputHeader.H:1
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::IPstream
Input inter-processor communications stream.
Definition: IPstream.H:53