decompositionInformation.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 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 
29 #include "ListOps.H"
30 
31 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32 
33 void Foam::decompositionInformation::populate
34 (
35  const labelUList& adjncy,
36  const labelUList& xadj,
37  const labelUList& decomp,
38  const label nDomain
39 )
40 {
41  nDomains_ = nDomain;
42 
43  distrib_.resize_nocopy(nDomain);
44 
45  for (labelList& subdist : distrib_)
46  {
47  subdist.resize_nocopy(nDomain);
48  subdist = Foam::zero{};
49  }
50 
51  // Protect against zero-sized offset list
52  const label numCells = Foam::max(0, (xadj.size()-1));
53 
54  for (label celli = 0; celli < numCells; ++celli)
55  {
56  const label ownProc = decomp[celli];
57 
58  labelList& subdist = distrib_[ownProc];
59 
60  // Number of cells
61  ++subdist[ownProc];
62 
63  for (label i = xadj[celli]; i < xadj[celli+1]; ++i)
64  {
65  const label neiProc = decomp[adjncy[i]];
66 
67  if (neiProc != ownProc)
68  {
69  // Number of processor faces
70  ++subdist[neiProc];
71  }
72  }
73  }
74 
75  // Build summary
76 
77  labelList cellsCount(nDomains_, Foam::zero{});
78  labelList neighCount(nDomains_, Foam::zero{});
79  labelList facesCount(nDomains_, Foam::zero{});
80 
81  forAll(distrib_, ownProc)
82  {
83  const labelList& subdist = distrib_[ownProc];
84 
85  cellsCount[ownProc] = subdist[ownProc];
86 
87  forAll(subdist, neiProc)
88  {
89  const label n = subdist[neiProc];
90 
91  if (n && ownProc != neiProc)
92  {
93  ++neighCount[ownProc];
94  facesCount[ownProc] += n;
95  }
96  }
97  }
98 
99  const label n2 = (nDomains_ / 2);
100 
101  sort(cellsCount);
102  cellsInfo_.min = cellsCount.first();
103  cellsInfo_.max = cellsCount.last();
104  cellsInfo_.median = cellsCount[n2];
105 
106  sort(neighCount);
107  neighInfo_.min = neighCount.first();
108  neighInfo_.max = neighCount.last();
109  neighInfo_.median = neighCount[n2];
110 
111  sort(facesCount);
112  facesInfo_.min = facesCount.first();
113  facesInfo_.max = facesCount.last();
114  facesInfo_.median = facesCount[n2];
115 }
116 
117 
118 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
119 
120 Foam::decompositionInformation::decompositionInformation
121 (
122  const labelUList& adjncy,
123  const labelUList& xadj,
124  const labelUList& decomp,
125  const label nDomains
126 )
127 :
128  distrib_(),
129  nDomains_(0)
130 {
131  populate(adjncy, xadj, decomp, nDomains);
132 }
133 
134 
135 Foam::decompositionInformation::decompositionInformation
136 (
137  const CompactListList<label>& cellCells,
138  const labelUList& decomp,
139  const label nDomains
140 )
141 :
142  distrib_(),
143  nDomains_(0)
144 {
145  populate(cellCells.values(), cellCells.offsets(), decomp, nDomains);
146 }
147 
148 
149 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
150 
152 {
153  distrib_.clear();
154  cellsInfo_.clear();
155  neighInfo_.clear();
156  facesInfo_.clear();
157 }
158 
159 
161 {
162  os << "Cells "; cellsInfo_.print(os) << nl;
163  os << "Neigh "; neighInfo_.print(os)<< nl;
164  os << "Faces "; facesInfo_.print(os)<< nl;
165 }
166 
167 
169 {
170  os << "Decomposition details with (proc faces) "
171  "for each processor connection" << nl << nl;
172 
173  forAll(distrib_, ownProc)
174  {
175  const labelList& subdist = distrib_[ownProc];
176 
177  // First pass:
178  label neighCount = 0;
179  label facesCount = 0;
180 
181  forAll(subdist, neiProc)
182  {
183  const label n = subdist[neiProc];
184 
185  if (n && ownProc != neiProc)
186  {
187  ++neighCount;
188  facesCount += n;
189  }
190  }
191 
192  os << "Part[" << ownProc << "] cells:" << subdist[ownProc]
193  << " neigh:" << neighCount
194  << " faces:" << facesCount;
195 
196  // Second pass with details:
197  if (facesCount)
198  {
199  os << ' ';
200 
201  forAll(subdist, neiProc)
202  {
203  const label n = subdist[neiProc];
204 
205  if (n && ownProc != neiProc)
206  {
207  os << " (" << neiProc << ' ' << n << ')';
208  }
209  }
210  }
211 
212  os << nl;
213  }
214 }
215 
216 
217 void Foam::decompositionInformation::printAll(Ostream& os) const
218 {
219  printDetails(os);
220  printSummary(os);
221 }
222 
223 
224 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
225 
227 {
228  os << "min:" << this->min
229  << " max:" << this->max
230  << " median:" << this->median;
231 
232  if (this->median)
233  {
234  const scalar ratio = scalar(100*this->max)/this->median;
235 
236  os << " (" << ratio << "%)";
237  }
238 
239  return os;
240 }
241 
242 
243 // ************************************************************************* //
const labelList & offsets() const noexcept
Return the offset table (= size()+1)
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:40
Ostream & print(Ostream &os, UIntType value, char off='0', char on='1')
Print 0/1 bits in the (unsigned) integral type.
Definition: BitOps.H:323
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
void print(Ostream &os) const override
Print stream description.
Definition: OFstream.C:164
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
A packed storage of objects of type <T> using an offset table for access.
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
OBJstream os(runTime.globalPath()/outputName)
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
label n
const List< T > & values() const noexcept
Return the packed values.
List< label > labelList
A List of labels.
Definition: List.H:62