Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
11License
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
34void 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
94void 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
130void 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
171void 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
240Foam::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// ************************************************************************* //
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition Tuple2.H:51
void map(const UList< Type > &faceVals, List< Type > &vals) const
Helper to convert lower addressing & data into CSR format.
const labelUList & ownerStartAddr() const
Return owner start addressing.
const labelUList & losortStartAddr() const
Return losort start addressing.
Tuple2< label, scalar > band() const
Calculate bandwidth and profile of addressing.
virtual const labelUList & upperAddr() const =0
Return upper addressing.
virtual const labelUList & lowerAddr() const =0
Return lower addressing.
const labelUList & lowerCSRAddr() const
Return CSR addressing.
label size() const noexcept
Return number of equations.
const labelUList & losortAddr() const
Return losort addressing.
void clearOut()
Clear additional addressing.
label triIndex(const label a, const label b) const
Return off-diagonal index given owner and neighbour label.
A class representing the concept of 0 (zero) that can be used to avoid manipulating objects known to ...
Definition zero.H:58
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
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
List< label > labelList
A List of labels.
Definition List.H:62
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition triad.C:373
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
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
UList< label > labelUList
A UList of labels.
Definition UList.H:75
volScalarField & b
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299