globalIndexI.H
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) 2018-2022 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 "ListOps.H"
30 
31 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
32 
34 (
35  const labelUList& listOffsets
36 )
37 {
38  if (listOffsets.size() > 1)
39  {
40  offsets_ = listOffsets;
41  }
42 }
43 
44 
46 (
47  labelList&& listOffsets
48 )
49 {
50  if (listOffsets.size() > 1)
51  {
52  offsets_.transfer(listOffsets);
53  }
54  else
55  {
56  listOffsets.clear();
57  }
58 }
59 
60 
62 (
63  const labelUList& offsetsOrSizes,
64  enum globalIndex::accessType accType
65 )
66 {
67  if (accType == accessType::SIZES)
68  {
69  reset(offsetsOrSizes);
70  }
71  else if (offsetsOrSizes.size() > 1)
72  {
73  // accessType::OFFSETS
74  offsets_ = offsetsOrSizes;
75  }
76 }
77 
78 
80 (
81  const label localSize,
82  const label comm,
83  const bool parallel
84 )
85 {
86  reset(localSize, comm, parallel);
87 }
88 
89 
91 (
93  const label localSize,
94  const label /* comm (ignored) */
95 )
96 :
97  offsets_(2)
98 {
99  offsets_[0] = 0;
100  offsets_[1] = localSize;
101 }
102 
103 
105 (
107  const label localSize,
108  const label comm
109 )
110 {
111  // one-sided
112  reset(UPstream::listGatherValues(localSize, comm));
113 }
114 
115 
117 (
119  const label localSize,
120  const label comm
121 )
122 {
123  // one-sided: non-master sizes only
124  reset
125  (
127  (
128  (UPstream::master() ? label(0) : localSize),
129  comm
130  )
131  );
132 }
133 
134 
135 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
137 inline bool Foam::globalIndex::empty() const
138 {
139  return offsets_.empty() || offsets_.back() == 0;
140 }
141 
142 
143 inline Foam::label Foam::globalIndex::totalSize() const
144 {
145  const label len = (offsets_.size() - 1);
146  return (len < 1) ? 0 : offsets_[len];
147 }
148 
150 inline Foam::label Foam::globalIndex::size() const
151 {
152  return totalSize();
153 }
154 
157 {
158  return localSizes();
159 }
160 
161 
162 inline Foam::label Foam::globalIndex::nProcs() const noexcept
163 {
164  const label len = (offsets_.size() - 1);
165  return (len < 1) ? 0 : len;
166 }
167 
168 
170 {
171  // Proc 0 -> nProcs
172  const label len = (offsets_.size() - 1);
173  return (len < 1) ? labelRange() : labelRange(0, len);
174 }
175 
176 
178 {
179  // Proc 1 -> nProcs
180  const label len = (offsets_.size() - 2);
181  return (len < 1) ? labelRange() : labelRange(1, len);
182 }
183 
186 {
187  return offsets_;
188 }
189 
192 {
193  return offsets_;
194 }
195 
197 inline void Foam::globalIndex::clear()
198 {
199  offsets_.clear();
200 }
201 
202 
204 {
205  const label len = (offsets_.size() - 1);
207  if (len < 1) return labelUList::null();
208 
209  return labelList::subList(offsets_, len);
210 }
211 
213 inline Foam::label Foam::globalIndex::localStart(const label proci) const
214 {
215  return offsets_[proci];
216 }
217 
219 inline Foam::label Foam::globalIndex::localStart() const
220 {
221  return localStart(UPstream::myProcNo());
222 }
223 
225 inline Foam::label Foam::globalIndex::localSize(const label proci) const
226 {
227  return offsets_[proci+1] - offsets_[proci];
228 }
229 
231 inline Foam::label Foam::globalIndex::localSize() const
232 {
233  return localSize(UPstream::myProcNo());
234 }
235 
236 
237 inline Foam::label Foam::globalIndex::maxSize() const
238 {
239  // Use out-of-range proci to avoid excluding any processor
240  return maxNonLocalSize(-1);
241 }
242 
244 inline Foam::label Foam::globalIndex::maxNonLocalSize() const
245 {
246  return maxNonLocalSize(UPstream::myProcNo());
247 }
248 
250 inline Foam::labelRange Foam::globalIndex::range(const label proci) const
251 {
252  return labelRange(offsets_[proci], offsets_[proci+1] - offsets_[proci]);
253 }
254 
257 {
258  return range(UPstream::myProcNo());
259 }
260 
262 inline bool Foam::globalIndex::isLocal(const label proci, const label i) const
263 {
264  return i >= offsets_[proci] && i < offsets_[proci+1];
265 }
266 
267 
268 inline bool Foam::globalIndex::isLocal(const label i) const
269 {
270  return isLocal(UPstream::myProcNo(), i);
271 }
272 
273 
274 inline Foam::label Foam::globalIndex::toGlobal
275 (
276  const label proci,
277  const label i
278 ) const
279 {
280  return i + offsets_[proci];
281 }
282 
283 
284 inline Foam::label Foam::globalIndex::toGlobal(const label i) const
285 {
286  return toGlobal(UPstream::myProcNo(), i);
287 }
288 
289 
291 (
292  const label proci,
293  const labelUList& labels
294 ) const
295 {
296  labelList result(labels);
297  inplaceToGlobal(proci, result);
298 
299  return result;
300 }
301 
302 
304 (
305  const labelUList& labels
306 ) const
307 {
308  return toGlobal(UPstream::myProcNo(), labels);
309 }
310 
311 
313 (
314  const label proci,
315  labelUList& labels
316 ) const
317 {
318  const label off = offsets_[proci];
319 
320  for (label& val : labels)
321  {
322  val += off;
323  }
324 }
325 
326 
328 {
329  inplaceToGlobal(UPstream::myProcNo(), labels);
330 }
331 
332 
333 inline Foam::label
334 Foam::globalIndex::toLocal(const label proci, const label i) const
335 {
336  const label locali = i - offsets_[proci];
337 
338  if (locali < 0 || i >= offsets_[proci+1])
339  {
341  << "Global " << i << " does not belong on processor "
342  << proci << nl << "Offsets:" << offsets_
343  << abort(FatalError);
344  }
345  return locali;
346 }
347 
349 inline Foam::label Foam::globalIndex::toLocal(const label i) const
350 {
351  return toLocal(UPstream::myProcNo(), i);
352 }
353 
354 
355 inline Foam::label Foam::globalIndex::whichProcID(const label i) const
356 {
357  if (i < 0 || i >= totalSize())
358  {
360  << "Global " << i << " does not belong on any processor."
361  << " Offsets:" << offsets_
362  << abort(FatalError);
363  }
364 
365  const int proci = UPstream::myProcNo();
366 
367  return isLocal(proci, i) ? proci : findLower(offsets_, i+1);
368 }
369 
370 
371 inline void Foam::globalIndex::reset
372 (
374  const label localSize,
375  const label /* comm (ignored) */
376 )
377 {
378  offsets_.resize_nocopy(2);
379  offsets_[0] = 0;
380  offsets_[1] = localSize;
381 }
382 
383 
384 inline void Foam::globalIndex::reset
385 (
387  const label localSize,
388  const label comm
389 )
390 {
391  // one-sided
392  reset(UPstream::listGatherValues(localSize, comm));
393 }
394 
395 
396 inline void Foam::globalIndex::reset
397 (
399  const label localSize,
400  const label comm
401 )
402 {
403  // one-sided: non-master sizes only
404  reset
405  (
407  (
408  (UPstream::master() ? label(0) : localSize),
409  comm
410  )
411  );
412 }
413 
414 
415 // * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
416 
419 (
420  const globalIndex* globalIdx,
421  const label i
422 ) noexcept
423 :
424  parent_(globalIdx),
425  proci_(i)
426 {}
427 
428 
429 inline Foam::label Foam::globalIndex::const_iterator::
431 {
432  return proci_;
433 }
434 
435 
436 inline Foam::label Foam::globalIndex::const_iterator::
437 start() const
438 {
439  return (*parent_).localStart(proci_);
440 }
441 
442 
443 inline Foam::label Foam::globalIndex::const_iterator::
444 size() const
445 {
446  return (*parent_).localSize(proci_);
447 }
448 
449 
451 range() const
452 {
453  return (*parent_).range(proci_);
454 }
455 
456 
458 operator*() const
459 {
460  return this->range();
461 }
462 
463 
466 operator++()
467 {
468  ++proci_;
469  return *this;
470 }
471 
472 
475 operator++(int)
476 {
477  const_iterator old(*this);
478  ++proci_;
479  return old;
480 }
481 
482 
485 operator--()
486 {
487  --proci_;
488  return *this;
489 }
490 
491 
494 operator--(int)
495 {
496  const_iterator old(*this);
497  --proci_;
498  return old;
499 }
500 
501 
502 inline bool
503 Foam::globalIndex::const_iterator::
504 operator==
505 (
506  const const_iterator& iter
507 ) const noexcept
508 {
509  return (proci_ == iter.proci_);
510 }
511 
512 
513 inline bool
514 Foam::globalIndex::const_iterator::
515 operator!=
516 (
517  const const_iterator& iter
518 ) const noexcept
519 {
520  return (proci_ != iter.proci_);
521 }
522 
523 
524 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
525 
528 {
529  return const_iterator(this);
530 }
531 
532 
535 {
536  return const_iterator(this, this->nProcs());
537 }
538 
539 
542 {
543  return const_iterator(this);
544 }
545 
546 
549 {
550  return const_iterator(this, this->nProcs());
551 }
552 
553 
554 // ************************************************************************* //
bool isLocal(const label i) const
Is on local processor.
Definition: globalIndexI.H:261
void reset(const label localSize, const label comm=UPstream::worldComm, const bool parallel=UPstream::parRun())
Reset from local size, using gather/broadcast with default/specified communicator if parallel...
Definition: globalIndex.C:187
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
label findLower(const ListType &input, const T &val, const label start, const ComparePredicate &comp)
Binary search to find the index of the last element in a sorted list that is less than value...
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:578
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:51
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:49
static List< T > listGatherValues(const T &localValue, const label communicator=worldComm)
Gather individual values into list locations.
Dispatch tag. Construct &#39;one-sided&#39; from local sizes, using gather but no broadcast.
Definition: globalIndex.H:115
SubList< label > subList
Declare type of subList.
Definition: List.H:122
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1029
void inplaceToGlobal(labelUList &labels) const
From local to global index (inplace)
Definition: globalIndexI.H:320
label proci() const noexcept
The associated local proc.
Definition: globalIndexI.H:423
scalar range
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
labelRange range() const
Return start/size range of local processor data.
Definition: globalIndexI.H:249
label nProcs() const noexcept
The number of processors covered by the offsets.
Definition: globalIndexI.H:155
Various functions to operate on Lists.
globalIndex() noexcept=default
Default construct (empty)
const labelList & offsets() const noexcept
Const-access to the offsets.
Definition: globalIndexI.H:178
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:62
Dispatch tag. Construct with a single (local size) entry, no communication.
Definition: globalIndex.H:108
Forward input iterator with const access.
Definition: globalIndex.H:486
const_iterator cbegin() const noexcept
A const_iterator set to the beginning.
Definition: globalIndexI.H:520
const_iterator begin() const noexcept
A const_iterator set to the beginning.
Definition: globalIndexI.H:534
label size() const
Global sum of localSizes. Same as totalSize()
Definition: globalIndexI.H:143
labelRange range() const
The local range.
Definition: globalIndexI.H:444
label toLocal(const label i) const
From global to local on current processor.
Definition: globalIndexI.H:342
label whichProcID(const label i) const
Which processor does global id come from?
Definition: globalIndexI.H:348
labelRange operator*() const
The local range.
Definition: globalIndexI.H:451
errorManip< error > abort(error &err)
Definition: errorManip.H:139
label size() const
The local size.
Definition: globalIndexI.H:437
const direction noexcept
Definition: Scalar.H:258
labelList sizes() const
The local sizes. Same as localSizes()
Definition: globalIndexI.H:149
static const UList< label > & null()
Return a UList reference to a nullObject.
Definition: UListI.H:45
const const_iterator end() const noexcept
A const_iterator set to beyond the end.
Definition: globalIndexI.H:541
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
Definition: globalIndexI.H:170
labelRange allProcs() const noexcept
Range of process indices for all addressed offsets (processes)
Definition: globalIndexI.H:162
label toGlobal(const label i) const
From local to global index.
Definition: globalIndexI.H:277
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1037
accessType
Disambiguation tag (list construction dispatch)
Definition: globalIndex.H:102
label localStart() const
My local start.
Definition: globalIndexI.H:212
bool empty() const
Check for default constructed or global sum == 0.
Definition: globalIndexI.H:130
const const_iterator cend() const noexcept
A const_iterator set to beyond the end.
Definition: globalIndexI.H:527
List< label > labelList
A List of labels.
Definition: List.H:62
label start() const
The local start.
Definition: globalIndexI.H:430
label maxSize() const
Global max of localSizes.
Definition: globalIndexI.H:230
void clear()
Reset to be empty (no offsets)
Definition: globalIndexI.H:190
Dispatch tag. Construct &#39;one-sided&#39; from the non-master local sizes using gather but no broadcast...
Definition: globalIndex.H:122
label totalSize() const
Global sum of localSizes.
Definition: globalIndexI.H:136
const_iterator(const globalIndex *globalIdx, const label proci=0) noexcept
Construct from globalIndex list at given index.
Definition: globalIndexI.H:412
label maxNonLocalSize() const
The max of localSizes, excluding current processor.
Definition: globalIndexI.H:237
label localSize() const
My local size.
Definition: globalIndexI.H:224
const labelUList localStarts() const
The local starts.
Definition: globalIndexI.H:196