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 -------------------------------------------------------------------------------
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 "demandDrivenData.H"
31 #include "scalarField.H"
32 
33 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
34 
35 void 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 
96 void 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 
133 void 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 
229 Foam::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 // ************************************************************************* //
Foam::labelList
List< label > labelList
A List of labels.
Definition: List.H:67
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
scalarField.H
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::lduAddressing::losortStartAddr
const labelUList & losortStartAddr() const
Return losort start addressing.
Definition: lduAddressing.C:210
Foam::lduAddressing::ownerStartAddr
const labelUList & ownerStartAddr() const
Return owner start addressing.
Definition: lduAddressing.C:199
Foam::lduAddressing::size
label size() const
Return number of equations.
Definition: lduAddressing.H:171
Foam::lduAddressing::upperAddr
virtual const labelUList & upperAddr() const =0
Return upper addressing.
Foam::min
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:33
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::lduAddressing::losortAddr
const labelUList & losortAddr() const
Return losort addressing.
Definition: lduAddressing.C:188
Foam::diff
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:378
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:42
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
lduAddressing.H
Foam::FatalError
error FatalError
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:144
Foam::labelListList
List< labelList > labelListList
A List of labelList.
Definition: labelList.H:56
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::lduAddressing::clearOut
void clearOut()
Clear additional addressing.
Definition: lduAddressing.C:221
Foam::List< label >
Foam::UList< label >
Foam::lduAddressing::triIndex
label triIndex(const label a, const label b) const
Return off-diagonal index given owner and neighbour label.
Definition: lduAddressing.C:229
Foam::Tuple2
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition: stringOps.H:60
Foam::labelUList
UList< label > labelUList
A UList of labels.
Definition: UList.H:85
Foam::lduAddressing::~lduAddressing
virtual ~lduAddressing()
Destructor.
Definition: lduAddressing.C:178
Foam::lduAddressing::band
Tuple2< label, scalar > band() const
Calculate bandwidth and profile of addressing.
Definition: lduAddressing.C:260