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 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 "demandDrivenData.H"
31#include "scalarField.H"
32
33// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34
35void Foam::lduAddressing::calcLosort() const
36{
37 if (losortPtr_)
38 {
40 << "losort already calculated"
41 << abort(FatalError);
42 }
43
44 // Scan the neighbour list to find out how many times the cell
45 // appears as a neighbour of the face. Done this way to avoid guessing
46 // and resizing list
47 labelList nNbrOfFace(size(), Zero);
48
49 const labelUList& nbr = upperAddr();
50
51 forAll(nbr, nbrI)
52 {
53 nNbrOfFace[nbr[nbrI]]++;
54 }
55
56 // Create temporary neighbour addressing
57 labelListList cellNbrFaces(size());
58
59 forAll(cellNbrFaces, celli)
60 {
61 cellNbrFaces[celli].setSize(nNbrOfFace[celli]);
62 }
63
64 // Reset the list of number of neighbours to zero
65 nNbrOfFace = 0;
66
67 // Scatter the neighbour faces
68 forAll(nbr, nbrI)
69 {
70 cellNbrFaces[nbr[nbrI]][nNbrOfFace[nbr[nbrI]]] = nbrI;
71
72 nNbrOfFace[nbr[nbrI]]++;
73 }
74
75 // Gather the neighbours into the losort array
76 losortPtr_ = new labelList(nbr.size(), -1);
77
78 labelList& lst = *losortPtr_;
79
80 // Set counter for losort
81 label lstI = 0;
82
83 forAll(cellNbrFaces, celli)
84 {
85 const labelList& curNbr = cellNbrFaces[celli];
86
87 forAll(curNbr, curNbrI)
88 {
89 lst[lstI] = curNbr[curNbrI];
90 lstI++;
91 }
92 }
93}
94
95
96void Foam::lduAddressing::calcOwnerStart() const
97{
98 if (ownerStartPtr_)
99 {
101 << "owner start already calculated"
102 << abort(FatalError);
103 }
104
105 const labelList& own = lowerAddr();
106
107 ownerStartPtr_ = new labelList(size() + 1, own.size());
108
109 labelList& ownStart = *ownerStartPtr_;
110
111 // Set up first lookup by hand
112 ownStart[0] = 0;
113 label nOwnStart = 0;
114 label i = 1;
115
116 forAll(own, facei)
117 {
118 label curOwn = own[facei];
119
120 if (curOwn > nOwnStart)
121 {
122 while (i <= curOwn)
123 {
124 ownStart[i++] = facei;
125 }
126
127 nOwnStart = curOwn;
128 }
129 }
130}
131
132
133void Foam::lduAddressing::calcLosortStart() const
134{
135 if (losortStartPtr_)
136 {
138 << "losort start already calculated"
139 << abort(FatalError);
140 }
141
142 losortStartPtr_ = new labelList(size() + 1, Zero);
143
144 labelList& lsrtStart = *losortStartPtr_;
145
146 const labelList& nbr = upperAddr();
147
148 const labelList& lsrt = losortAddr();
149
150 // Set up first lookup by hand
151 lsrtStart[0] = 0;
152 label nLsrtStart = 0;
153 label i = 0;
154
155 forAll(lsrt, facei)
156 {
157 // Get neighbour
158 const label curNbr = nbr[lsrt[facei]];
159
160 if (curNbr > nLsrtStart)
161 {
162 while (i <= curNbr)
163 {
164 lsrtStart[i++] = facei;
165 }
166
167 nLsrtStart = curNbr;
168 }
169 }
170
171 // Set up last lookup by hand
172 lsrtStart[size()] = nbr.size();
173}
174
175
176// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
177
179{
180 deleteDemandDrivenData(losortPtr_);
181 deleteDemandDrivenData(ownerStartPtr_);
182 deleteDemandDrivenData(losortStartPtr_);
183}
184
185
186// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
187
189{
190 if (!losortPtr_)
191 {
192 calcLosort();
193 }
194
195 return *losortPtr_;
196}
197
198
200{
201 if (!ownerStartPtr_)
202 {
203 calcOwnerStart();
204 }
205
206 return *ownerStartPtr_;
207}
208
209
211{
212 if (!losortStartPtr_)
213 {
214 calcLosortStart();
215 }
216
217 return *losortStartPtr_;
218}
219
220
222{
223 deleteDemandDrivenData(losortPtr_);
224 deleteDemandDrivenData(ownerStartPtr_);
225 deleteDemandDrivenData(losortStartPtr_);
226}
227
228
229Foam::label Foam::lduAddressing::triIndex(const label a, const label b) const
230{
231 label own = min(a, b);
232
233 label nbr = max(a, b);
234
235 label startLabel = ownerStartAddr()[own];
236
237 label endLabel = ownerStartAddr()[own + 1];
238
239 const labelUList& neighbour = upperAddr();
240
241 for (label i=startLabel; i<endLabel; i++)
242 {
243 if (neighbour[i] == nbr)
244 {
245 return i;
246 }
247 }
248
249 // If neighbour has not been found, something has gone seriously
250 // wrong with the addressing mechanism
252 << "neighbour " << nbr << " not found for owner " << own << ". "
253 << "Problem with addressing"
254 << abort(FatalError);
255
256 return -1;
257}
258
259
261{
262 const labelUList& owner = lowerAddr();
263 const labelUList& neighbour = upperAddr();
264
265 labelList cellBandwidth(size(), Zero);
266
267 forAll(neighbour, facei)
268 {
269 label own = owner[facei];
270 label nei = neighbour[facei];
271
272 // Note: mag not necessary for correct (upper-triangular) ordering.
273 label diff = nei-own;
274 cellBandwidth[nei] = max(cellBandwidth[nei], diff);
275 }
276
277 label bandwidth = max(cellBandwidth);
278
279 // Do not use field algebra because of conversion label to scalar
280 scalar profile = 0.0;
281 forAll(cellBandwidth, celli)
282 {
283 profile += 1.0*cellBandwidth[celli];
284 }
285
286 return Tuple2<label, scalar>(bandwidth, profile);
287}
288
289
290// ************************************************************************* //
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: Tuple2.H:58
const labelUList & ownerStartAddr() const
Return owner start addressing.
virtual ~lduAddressing()
Destructor.
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.
label size() const
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.
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
List< label > labelList
A List of labels.
Definition: List.H:66
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:378
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
errorManip< error > abort(error &err)
Definition: errorManip.H:144
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
error FatalError
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
void deleteDemandDrivenData(DataPtr &dataPtr)
volScalarField & b
Definition: createFields.H:27
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333