lduAddressing.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) 2011-2016 OpenFOAM Foundation
9  Copyright (C) 2016-2024 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 
29 #include "lduAddressing.H"
30 #include "scalarField.H"
31 
32 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
33 
34 void Foam::lduAddressing::calcLosort() const
35 {
36  if (losortPtr_)
37  {
39  << "losort already calculated"
40  << abort(FatalError);
41  }
42 
43  // Scan the neighbour list to find out how many times the cell
44  // appears as a neighbour of the face. Done this way to avoid guessing
45  // and resizing list
46  labelList nNbrOfFace(size(), Foam::zero{});
47 
48  const labelUList& nbr = upperAddr();
49 
50  forAll(nbr, nbrI)
51  {
52  nNbrOfFace[nbr[nbrI]]++;
53  }
54 
55  // Create temporary neighbour addressing
56  labelListList cellNbrFaces(size());
57 
58  forAll(cellNbrFaces, celli)
59  {
60  cellNbrFaces[celli].setSize(nNbrOfFace[celli]);
61  }
62 
63  // Reset the list of number of neighbours to zero
64  nNbrOfFace = 0;
65 
66  // Scatter the neighbour faces
67  forAll(nbr, nbrI)
68  {
69  cellNbrFaces[nbr[nbrI]][nNbrOfFace[nbr[nbrI]]] = nbrI;
70 
71  nNbrOfFace[nbr[nbrI]]++;
72  }
73 
74  // Gather the neighbours into the losort array
75  losortPtr_ = std::make_unique<labelList>(nbr.size(), -1);
76  auto& lst = *losortPtr_;
77 
78  // Set counter for losort
79  label lstI = 0;
80 
81  forAll(cellNbrFaces, celli)
82  {
83  const labelUList& curNbr = cellNbrFaces[celli];
84 
85  forAll(curNbr, curNbrI)
86  {
87  lst[lstI] = curNbr[curNbrI];
88  lstI++;
89  }
90  }
91 }
92 
93 
94 void Foam::lduAddressing::calcOwnerStart() const
95 {
96  if (ownerStartPtr_)
97  {
99  << "owner start already calculated"
100  << abort(FatalError);
101  }
102 
103  const labelUList& own = lowerAddr();
104 
105  ownerStartPtr_ = std::make_unique<labelList>(size() + 1, own.size());
106  auto& ownStart = *ownerStartPtr_;
107 
108  // Set up first lookup by hand
109  ownStart[0] = 0;
110  label nOwnStart = 0;
111  label i = 1;
112 
113  forAll(own, facei)
114  {
115  label curOwn = own[facei];
116 
117  if (curOwn > nOwnStart)
118  {
119  while (i <= curOwn)
120  {
121  ownStart[i++] = facei;
122  }
123 
124  nOwnStart = curOwn;
125  }
126  }
127 }
128 
129 
130 void Foam::lduAddressing::calcLosortStart() const
131 {
132  if (losortStartPtr_)
133  {
135  << "losort start already calculated"
136  << abort(FatalError);
137  }
138 
139  const labelUList& nbr = upperAddr();
140  losortStartPtr_ = std::make_unique<labelList>(size() + 1, nbr.size());
141  auto& lsrtStart = *losortStartPtr_;
142 
143  const labelUList& lsrt = losortAddr();
144 
145  // Set up first lookup by hand
146  lsrtStart[0] = 0;
147  label nLsrtStart = 0;
148  label i = 0;
149 
150  forAll(lsrt, facei)
151  {
152  // Get neighbour
153  const label curNbr = nbr[lsrt[facei]];
154 
155  if (curNbr > nLsrtStart)
156  {
157  while (i <= curNbr)
158  {
159  lsrtStart[i++] = facei;
160  }
161 
162  nLsrtStart = curNbr;
163  }
164  }
165 
166  // Set up last lookup by hand
167  lsrtStart[size()] = nbr.size();
168 }
169 
170 
171 void Foam::lduAddressing::calcLoCSR() const
172 {
173  if (lowerCSRAddrPtr_)
174  {
176  << "lowerCSRAddr already calculated"
177  << abort(FatalError);
178  }
179 
180  lowerCSRAddrPtr_ = std::make_unique<labelList>(lowerAddr().size());
181  map(lowerAddr(), *lowerCSRAddrPtr_);
182 }
183 
184 
185 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
186 
188 {
189  if (!losortPtr_)
190  {
191  calcLosort();
192  }
193 
194  return *losortPtr_;
195 }
196 
197 
199 {
200  if (!ownerStartPtr_)
201  {
202  calcOwnerStart();
203  }
204 
205  return *ownerStartPtr_;
206 }
207 
208 
210 {
211  if (!losortStartPtr_)
212  {
213  calcLosortStart();
214  }
215 
216  return *losortStartPtr_;
217 }
218 
219 
221 {
222  if (!lowerCSRAddrPtr_)
223  {
224  calcLoCSR();
225  }
226 
227  return *lowerCSRAddrPtr_;
228 }
229 
230 
232 {
233  losortPtr_.reset(nullptr);
234  ownerStartPtr_.reset(nullptr);
235  losortStartPtr_.reset(nullptr);
236  lowerCSRAddrPtr_.reset(nullptr);
237 }
238 
239 
240 Foam::label Foam::lduAddressing::triIndex(const label a, const label b) const
241 {
242  label own = min(a, b);
243 
244  label nbr = max(a, b);
245 
246  label startLabel = ownerStartAddr()[own];
247 
248  label endLabel = ownerStartAddr()[own + 1];
249 
250  const labelUList& neighbour = upperAddr();
251 
252  for (label i=startLabel; i<endLabel; i++)
253  {
254  if (neighbour[i] == nbr)
255  {
256  return i;
257  }
258  }
259 
260  // If neighbour has not been found, something has gone seriously
261  // wrong with the addressing mechanism
263  << "neighbour " << nbr << " not found for owner " << own << ". "
264  << "Problem with addressing"
265  << abort(FatalError);
266 
267  return -1;
268 }
269 
270 
272 {
273  const labelUList& owner = lowerAddr();
274  const labelUList& neighbour = upperAddr();
275 
276  labelList cellBandwidth(size(), Foam::zero{});
277 
278  forAll(neighbour, facei)
279  {
280  label own = owner[facei];
281  label nei = neighbour[facei];
282 
283  // Note: mag not necessary for correct (upper-triangular) ordering.
284  label diff = nei-own;
285  cellBandwidth[nei] = max(cellBandwidth[nei], diff);
286  }
287 
288  label bandwidth = max(cellBandwidth);
289 
290  // Do not use field algebra because of conversion label to scalar
291  scalar profile = 0.0;
292  forAll(cellBandwidth, celli)
293  {
294  profile += 1.0*cellBandwidth[celli];
295  }
296 
297  return Tuple2<label, scalar>(bandwidth, profile);
298 }
299 
300 
301 // ************************************************************************* //
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:373
label triIndex(const label a, const label b) const
Return off-diagonal index given owner and neighbour label.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:600
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: stringOps.H:56
const labelUList & losortStartAddr() const
Return losort start addressing.
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
UList< label > labelUList
A UList of labels.
Definition: UList.H:76
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:286
label size() const noexcept
Return number of equations.
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
virtual const labelUList & upperAddr() const =0
Return upper addressing.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:26
errorManip< error > abort(error &err)
Definition: errorManip.H:139
Tuple2< label, scalar > band() const
Calculate bandwidth and profile of addressing.
const labelUList & lowerCSRAddr() const
Return CSR addressing.
const labelUList & losortAddr() const
Return losort addressing.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition: zero.H:57
List< label > labelList
A List of labels.
Definition: List.H:61
void clearOut()
Clear additional addressing.
const labelUList & ownerStartAddr() const
Return owner start addressing.