CompactListList.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) 2019-2022 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 "CompactListList.H"
30#include "labelRange.H"
31
32// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
33
34template<class T>
36(
37 const label idx,
38 const labelUList& localLens
39)
40{
42 << "Overflow : sum of sizes exceeds labelMax ("
43 << labelMax << ") after index " << idx;
44
45 if (!localLens.empty())
46 {
47 FatalError << " of " << flatOutput(localLens);
48 }
49
51 << nl
52 << "Please recompile with larger datatype for label." << nl
53 << exit(FatalError);
54}
55
56
57template<class T>
58template<class ListListType>
60(
61 const ListListType& lists,
62 const bool checkOverflow
63)
64{
65 CompactListList<T> compact;
66
67 auto& newOffsets = compact.offsets_;
68 auto& newValues = compact.values_;
69
70 label total = 0;
71 const label len = lists.size();
72
73 if (len)
74 {
75 newOffsets.resize(len+1, Zero);
76
77 for (label i = 0; i < len; ++i)
78 {
79 newOffsets[i] = total;
80 total += lists[i].size();
81
82 if (checkOverflow && total < newOffsets[i])
83 {
84 reportOverflowAndExit(i);
85 }
86 }
87 newOffsets[len] = total;
88 }
89
90 if (total)
91 {
92 // Copy in the data
93 newValues.resize(total);
94
95 auto outIter = newValues.begin();
96
97 for (const auto& list : lists)
98 {
99 forAll(list, i)
100 {
101 *outIter = list[i];
102 ++outIter;
103 }
104 }
105 }
106
107 return compact;
108}
109
110
111template<class T>
112template<class SubListType>
114(
115 const UList<SubListType>& lists,
116 const bool checkOverflow
117)
118{
120 (
121 lists,
122 checkOverflow
123 );
124}
125
126
127template<class T>
128template<class SubListType, class Addr>
130(
132 const bool checkOverflow
133)
134{
136 (
137 lists,
138 checkOverflow
139 );
140}
141
142
143// * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * * //
144
145template<class T>
147{
148 const label len = listSizes.size();
149
150 if (len)
151 {
152 offsets_.resize(len+1);
153
154 label total = 0;
155 for (label i = 0; i < len; ++i)
156 {
157 offsets_[i] = total;
158 total += listSizes[i];
159
160#ifdef FULLDEBUG
161 if (total < offsets_[i])
162 {
163 reportOverflowAndExit(i, listSizes);
164 }
165#endif
166 }
167
168 offsets_[len] = total;
169 values_.resize(total);
170 }
171}
172
173
174template<class T>
176(
177 const labelUList& listSizes,
178 const T& val
179)
180{
181 const label len = listSizes.size();
182
183 if (len)
184 {
185 offsets_.resize(len+1);
186
187 label total = 0;
188 for (label i = 0; i < len; ++i)
189 {
190 offsets_[i] = total;
191 total += listSizes[i];
192
193#ifdef FULLDEBUG
194 if (total < offsets_[i])
195 {
196 reportOverflowAndExit(i, listSizes);
197 }
198#endif
199 }
200
201 offsets_[len] = total;
202 values_.resize(total, val);
203 }
204}
205
206
207// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
208
209template<class T>
210Foam::label Foam::CompactListList<T>::maxNonLocalSize(const label rowi) const
211{
212 const label len = (offsets_.size() - 1);
213
214 if (len < 1)
215 {
216 return 0;
217 }
218
219 label maxLen = 0;
220
221 for (label i=0; i < len; ++i)
222 {
223 if (i != rowi)
224 {
225 const label localLen = (offsets_[i+1] - offsets_[i]);
226 maxLen = max(maxLen, localLen);
227 }
228 }
229
230 return maxLen;
231}
232
233
234template<class T>
236{
238 {
240 << "Invalid for non-contiguous data types"
241 << abort(FatalError);
242 }
243 return this->size_bytes();
244}
245
246
247template<class T>
249{
250 return labelRange(offsets_[i], offsets_[i+1] - offsets_[i]);
251}
252
253
254template<class T>
257{
258 List<labelRange> values;
259
260 const label len = (offsets_.size() - 1);
261
262 if (len < 1)
263 {
264 return values;
265 }
266
267 values.resize(len);
268
269 for (label i=0; i < len; ++i)
270 {
271 values[i].reset(offsets_[i], (offsets_[i+1] - offsets_[i]));
272 }
273
274 return values;
275}
276
277
278template<class T>
280{
281 const label len = listSizes.size();
282
283 if (len)
284 {
285 offsets_.resize(len+1);
286
287 label total = 0;
288 for (label i = 0; i < len; ++i)
289 {
290 offsets_[i] = total;
291 total += listSizes[i];
292#if 0
293 if (checkOverflow && total < offsets_[i])
294 {
295 reportOverflowAndExit(i, listSizes);
296 }
297#endif
298 }
299
300 offsets_[len] = total;
301 values_.resize(total);
302 }
303 else
304 {
305 clear();
306 }
307}
308
309
310template<class T>
311void Foam::CompactListList<T>::setLocalSize(const label rowi, const label len)
312{
313 if (rowi >= 0 && rowi+1 < offsets_.size() && len >= 0)
314 {
315 const label delta = (len - (offsets_[rowi+1] - offsets_[rowi]));
316
317 // TBD: additional overflow check
318 if (delta)
319 {
320 for (label i = rowi+1; i < offsets_.size(); ++i)
321 {
322 offsets_[i] += delta;
323 }
324 }
325 }
326}
327
328
329template<class T>
331{
332 labelList values;
333
334 const label len = (offsets_.size() - 1);
335
336 if (len < 1)
337 {
338 return values;
339 }
340
341 values.resize(len);
342
343 for (label i=0; i < len; ++i)
344 {
345 values[i] = offsets_[i+1] - offsets_[i];
346 }
347
348 return values;
349}
350
351
352template<class T>
354(
355 CompactListList<T>& other
356)
357{
358 if (this == &other)
359 {
360 return; // Self-swap is a no-op
361 }
362
363 offsets_.swap(other.offsets_);
364 values_.swap(other.values_);
365}
366
367
368template<class T>
370(
372)
373{
374 if (this == &list)
375 {
376 return; // Self-assignment is a no-op
377 }
378
379 offsets_.transfer(list.offsets_);
380 values_.transfer(list.values_);
381}
382
383
384template<class T>
385template<class SubListType>
388{
389 List<SubListType> lists(size());
390
391 forAll(lists, i)
392 {
393 lists[i] = SubListType(this->localList(i));
394 }
395
396 return lists;
397}
398
399
400template<class T>
401template<class SubListType>
404{
405 List<SubListType> lists(range.size());
406
407 auto outIter = lists.begin();
408
409 for (const label i : range)
410 {
411 *outIter = SubListType(this->localList(i));
412 ++outIter;
413 }
414
415 return lists;
416}
417
418
419// ************************************************************************* //
scalar range
scalar delta
Y[inertIndex] max(0.0)
A packed storage unstructured matrix of objects of type <T> using an offset table for access.
List< SubListType > unpack() const
Return non-compact list of lists.
List< labelRange > ranges() const
Return start/size ranges for all sub-lists.
static CompactListList< T > pack(const UList< SubListType > &lists, const bool checkOverflow=false)
Construct by packing together the list of lists.
std::streamsize byteSize() const
void setLocalSize(const label rowi, const label len)
Alter local addressing size for given row, does not change content.
labelList localSizes() const
The local row sizes.
void swap(CompactListList< T > &other)
Swap contents.
CompactListList() noexcept=default
Default construct.
virtual bool resize()
Resize the ODE solver.
Definition: Euler.C:53
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
void transfer(PtrList< T > &list)
Transfer into this list and annul the argument list.
Definition: PtrListI.H:269
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Definition: UList.H:94
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:329
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
label maxNonLocalSize() const
The max of localSizes, excluding current processor.
Definition: globalIndexI.H:220
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:58
const volScalarField & T
patchWriters clear()
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
constexpr label labelMax
Definition: label.H:61
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:215
errorManip< error > abort(error &err)
Definition: errorManip.H:144
error FatalError
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
A template class to specify that a data type can be considered as being contiguous in memory.
Definition: contiguous.H:78