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_.clear();
44  distrib_.resize(nDomain);
45 
46  for (labelList& subdist : distrib_)
47  {
48  subdist.clear();
49  subdist.resize(nDomain, Zero);
50  }
51 
52  // Protect against zero-sized offset list
53  const label numCells = max(0, (xadj.size()-1));
54 
55  for (label celli = 0; celli < numCells; ++celli)
56  {
57  const label ownProc = decomp[celli];
58 
59  labelList& subdist = distrib_[ownProc];
60 
61  // Number of cells
62  ++subdist[ownProc];
63 
64  for (label i = xadj[celli]; i < xadj[celli+1]; ++i)
65  {
66  const label neiProc = decomp[adjncy[i]];
67 
68  if (neiProc != ownProc)
69  {
70  // Number of processor faces
71  ++subdist[neiProc];
72  }
73  }
74  }
75 
76  // Build summary
77 
78  labelList cellsCount(nDomains_, Zero);
79  labelList neighCount(nDomains_, Zero);
80  labelList facesCount(nDomains_, Zero);
81 
82  forAll(distrib_, ownProc)
83  {
84  const labelList& subdist = distrib_[ownProc];
85 
86  cellsCount[ownProc] = subdist[ownProc];
87 
88  forAll(subdist, neiProc)
89  {
90  const label n = subdist[neiProc];
91 
92  if (n && ownProc != neiProc)
93  {
94  ++neighCount[ownProc];
95  facesCount[ownProc] += n;
96  }
97  }
98  }
99 
100  const label n2 = (nDomains_ / 2);
101 
102  sort(cellsCount);
103  cellsInfo_.min = cellsCount.first();
104  cellsInfo_.max = cellsCount.last();
105  cellsInfo_.median = cellsCount[n2];
106 
107  sort(neighCount);
108  neighInfo_.min = neighCount.first();
109  neighInfo_.max = neighCount.last();
110  neighInfo_.median = neighCount[n2];
111 
112  sort(facesCount);
113  facesInfo_.min = facesCount.first();
114  facesInfo_.max = facesCount.last();
115  facesInfo_.median = facesCount[n2];
116 }
117 
118 
119 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
120 
121 Foam::decompositionInformation::decompositionInformation
122 (
123  const labelUList& adjncy,
124  const labelUList& xadj,
125  const labelUList& decomp,
126  const label nDomains
127 )
128 :
129  distrib_(),
130  nDomains_(0)
131 {
132  populate(adjncy, xadj, decomp, nDomains);
133 }
134 
135 
136 Foam::decompositionInformation::decompositionInformation
137 (
138  const CompactListList<label>& cellCells,
139  const labelUList& decomp,
140  const label nDomains
141 )
142 :
143  distrib_(),
144  nDomains_(0)
145 {
146  populate(cellCells.values(), cellCells.offsets(), decomp, nDomains);
147 }
148 
149 
150 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
151 
153 {
154  distrib_.clear();
155  cellsInfo_.clear();
156  neighInfo_.clear();
157  facesInfo_.clear();
158 }
159 
160 
162 {
163  os << "Cells "; cellsInfo_.print(os) << nl;
164  os << "Neigh "; neighInfo_.print(os)<< nl;
165  os << "Faces "; facesInfo_.print(os)<< nl;
166 }
167 
168 
170 {
171  os << "Decomposition details with (proc faces) "
172  "for each processor connection" << nl << nl;
173 
174  forAll(distrib_, ownProc)
175  {
176  const labelList& subdist = distrib_[ownProc];
177 
178  // First pass:
179  label neighCount = 0;
180  label facesCount = 0;
181 
182  forAll(subdist, neiProc)
183  {
184  const label n = subdist[neiProc];
185 
186  if (n && ownProc != neiProc)
187  {
188  ++neighCount;
189  facesCount += n;
190  }
191  }
192 
193  os << "Part[" << ownProc << "] cells:" << subdist[ownProc]
194  << " neigh:" << neighCount
195  << " faces:" << facesCount;
196 
197  // Second pass with details:
198  if (facesCount)
199  {
200  os << ' ';
201 
202  forAll(subdist, neiProc)
203  {
204  const label n = subdist[neiProc];
205 
206  if (n && ownProc != neiProc)
207  {
208  os << " (" << neiProc << ' ' << n << ')';
209  }
210  }
211  }
212 
213  os << nl;
214  }
215 }
216 
217 
218 void Foam::decompositionInformation::printAll(Ostream& os) const
219 {
220  printDetails(os);
221  printSummary(os);
222 }
223 
224 
225 // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
226 
228 {
229  os << "min:" << this->min
230  << " max:" << this->max
231  << " median:" << this->median;
232 
233  if (this->median)
234  {
235  const scalar ratio = scalar(100*this->max)/this->median;
236 
237  os << " (" << ratio << "%)";
238  }
239 
240  return os;
241 }
242 
243 
244 // ************************************************************************* //
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)
label n
const List< T > & values() const noexcept
Return the packed values.
List< label > labelList
A List of labels.
Definition: List.H:62
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127