Loading...
Searching...
No Matches
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-2025 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 "ListOps.H"
30
31// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
32
34Foam::globalIndex::range_impl(label proci) const noexcept
35{
36 if
37 (
38 const auto len = (offsets_.size() - 1);
39 (len > 0 && proci >= 0 && proci < len)
40 )
41 {
42 const auto* off = offsets_.cdata();
43 return { off[proci], (off[proci+1] - off[proci]) };
44 }
45 else
46 {
47 return {};
48 }
49}
50
51
53Foam::globalIndex::slice_impl(label proci) const noexcept
54{
55 if
56 (
57 const auto len = (offsets_.size() - 1);
58 (len > 0 && proci >= 0 && proci < len)
59 )
60 {
61 const auto* off = offsets_.cdata();
62 return { off[proci], (off[proci+1] - off[proci]), off[len] };
63 }
64 else
65 {
66 return {};
67 }
68}
69
70
71// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
72
73inline void Foam::globalIndex::checkOverflowAndExit
74(
75 const label idx,
76 const label prevOffset,
77 const label count
78)
79{
80 if (prevOffset >= 0 && count >= 0)
81 {
82 if (label next = (prevOffset + count); next < prevOffset)
83 {
84 reportOverflowAndExit(idx, prevOffset, count);
85 }
86 }
87}
88
89
90// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
91
93(
94 const labelUList& listOffsets
95)
96{
97 if (listOffsets.size() > 1) // Enforce sizing sanity
98 {
99 offsets_ = listOffsets;
100 }
101}
102
103
105(
106 labelList&& listOffsets
107)
108:
109 offsets_(std::move(listOffsets))
110{
111 if (offsets_.size() == 1) // Enforce sizing sanity
112 {
113 offsets_.clear();
114 }
115}
116
117
119(
122)
123{
125}
126
127
129(
130 label localSize,
131 const label comm,
132 const bool parallel
133)
134{
135 reset(localSize, comm, parallel);
136}
137
138
140(
142 label localSize,
143 int communicator /* unused: (not applicable) */
144)
145:
146 offsets_(2)
147{
148 offsets_[0] = 0;
149 offsets_[1] = localSize;
150}
151
152
154(
156 label localSize,
157 const label comm
159{
160 // one-sided
162}
163
164
166(
168 label localSize,
169 const label comm
170)
171{
172 // one-sided: non-master sizes only
175}
176
177
178// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
179
181{
182 const label len = (offsets_.size() - 1);
183 return (len < 1) || (*(offsets_.cdata() + len) == 0);
184}
185
187inline bool Foam::globalIndex::single() const noexcept
188{
189 return (offsets_.size() == 2);
190}
191
192
193inline Foam::label Foam::globalIndex::length() const noexcept
194{
195 const label len = (offsets_.size() - 1);
196 return (len < 1) ? 0 : len;
197}
198
200inline Foam::label Foam::globalIndex::span() const noexcept
201{
202 return (end_value() - begin_value());
203}
204
206inline Foam::label Foam::globalIndex::begin_value() const noexcept
207{
208 return (offsets_.empty() ? 0 : *(offsets_.cdata()));
209}
210
211
212inline Foam::label Foam::globalIndex::end_value() const noexcept
213{
214 const label len = (offsets_.size() - 1);
215 return (len < 1) ? 0 : *(offsets_.cdata() + len);
216}
217
219inline bool Foam::globalIndex::contains(const label i) const noexcept
220{
221 return (begin_value() <= i) && (i < end_value());
222}
223
225inline Foam::label Foam::globalIndex::totalSize() const noexcept
226{
227 return end_value();
228}
229
232{
233 return localSizes();
234}
235
237inline Foam::label Foam::globalIndex::nProcs() const noexcept
238{
239 return length();
240}
241
242
245 // Proc 0 -> nProcs
246 const label len = (offsets_.size() - 1);
247 return (len < 1) ? labelRange() : labelRange(0, len);
248}
249
250
253 // Proc 1 -> nProcs
254 const label len = (offsets_.size() - 2);
255 return (len < 1) ? labelRange() : labelRange(1, len);
256}
257
260{
261 return offsets_;
262}
263
266{
267 return offsets_;
268}
269
271inline void Foam::globalIndex::clear()
272{
273 offsets_.clear();
274}
275
276
278{
279 if (const label len = (offsets_.size() - 1); len > 0)
280 {
281 return labelList::subList(offsets_, len);
282 }
283 else
284 {
285 return labelUList::null();
286 }
287}
288
290inline Foam::label Foam::globalIndex::localStart(const label proci) const
291{
292 return offsets_[proci];
293}
294
296inline Foam::label Foam::globalIndex::localStart() const
297{
299}
300
302inline Foam::label Foam::globalIndex::localEnd(const label proci) const
303{
304 return offsets_[proci+1];
305}
306
308inline Foam::label Foam::globalIndex::localEnd() const
309{
311}
312
314inline Foam::label Foam::globalIndex::localSize(const label proci) const
315{
316 return offsets_[proci+1] - offsets_[proci];
317}
318
320inline Foam::label Foam::globalIndex::localSize() const
321{
323}
324
325
326inline Foam::label Foam::globalIndex::maxSize() const
327{
328 // Use out-of-range proci to avoid excluding any processor
329 return maxNonLocalSize(-1);
330}
331
336}
337
339inline Foam::labelRange Foam::globalIndex::range(label proci) const noexcept
340{
341 return range_impl(proci);
342}
343
344
346{
347 return range_impl(UPstream::myProcNo(UPstream::worldComm));
348}
349
350
352Foam::globalIndex::slice(label proci) const noexcept
353{
354 return slice_impl(proci);
355}
356
357
363
364
365inline bool Foam::globalIndex::isLocal(const label proci, const label i) const
366{
367 // range contains()
368 return (offsets_[proci] <= i) && (i < offsets_[proci+1]);
369}
370
372inline bool Foam::globalIndex::isLocal(const label i) const
373{
375}
376
377
378inline Foam::label Foam::globalIndex::toGlobal
379(
380 const label proci,
381 const label i
382) const
383{
384 return i + offsets_[proci];
385}
386
388inline Foam::label Foam::globalIndex::toGlobal(const label i) const
389{
391}
392
393
395(
396 const label proci,
397 const labelUList& labels
398) const
399{
400 // Or using std::transform
401
402 //std::transform(labels.begin(), labels.end(), result.begin(),
403 // [=](label id) { return id += off });
404
405 labelList result(labels);
406 inplaceToGlobal(proci, result);
407
408 return result;
409}
410
411
413(
414 const labelUList& labels
415) const
416{
418}
419
420
422(
423 const label proci,
424 labelUList& labels
425) const
426{
427 if (const auto beg = offsets_[proci]; beg)
428 {
429 for (auto& val : labels)
431 val += beg;
432 }
433 }
434}
435
436
438{
440}
441
442
443inline Foam::label
444Foam::globalIndex::toLocal(const label proci, const label i) const
445{
446 // range !contains()
447 if (i < offsets_[proci] || i >= offsets_[proci+1])
448 {
450 << "Global id:" << i << " does not belong on processor "
451 << proci << nl
452 << " Offsets:" << offsets_
453 << abort(FatalError);
454 }
455 return (i - offsets_[proci]);
456}
457
459inline Foam::label Foam::globalIndex::toLocal(const label i) const
460{
462}
463
464
465inline Foam::label Foam::globalIndex::findProc
466(
467 const label proci,
468 const label i
469) const
470{
471 // Simple checks first
472 if
473 (
474 (proci < 0) // Invalid proc
475 || (proci+1 > offsets_.size()) // Invalid proc
476 || (i < offsets_.front()) // Below the start
477 || (i >= offsets_.back()) // Beyond the end
478 )
479 {
480 return -1;
481 }
482
483 // Assume that in many cases we have many queries for the local proci,
484 // so query that first but also make it the split point for
485 // restricting the binary searches
486
487 if (isLocal(proci, i))
488 {
489 return proci;
490 }
491
492 if (i < offsets_[proci])
493 {
494 // Can restrict search to procs below proci
495 const labelList::subList slice(offsets_, proci);
496 return findLower(slice, i+1);
498
499 // Search starts at proci+1 (and above)
500 return findLower(offsets_, i+1, proci+1);
501}
502
503
504inline Foam::label Foam::globalIndex::findProcAbove
505(
506 const label proci,
507 const label i
508) const
509{
510 // Simple checks first
511 if
512 (
513 (proci < 0) // Invalid proci
514 || (proci+1 >= offsets_.size()) // Nothing above last proc
515 || (i < offsets_[proci+1]) // Exclude proc-local and below
516 || (i >= offsets_.back()) // Beyond the end
517 )
518 {
519 return -1;
521
522 // Search starts at proci+1 (and above)
523 return findLower(offsets_, i+1, (proci+1));
524}
525
526
527inline Foam::label Foam::globalIndex::findProcBelow
528(
529 const label proci,
530 const label i
531) const
532{
533 if
534 (
535 (proci <= 0) // Nothing below first proc
536 || (proci >= offsets_.size()) // Invalid proci
537 || (i >= offsets_[proci]) // Exclude proc-local and above
538 || (i < offsets_[0]) // Beyond the begin
539 )
540 {
541 return -1;
542 }
543
544 // Restrict search to procs below proci
545 const labelList::subList slice(offsets_, proci);
546 return findLower(slice, i+1);
547}
548
549
550// Note: could split this into failsafe/non-failsafe versions
551inline Foam::label Foam::globalIndex::whichProcID
552(
553 const label proci,
554 const label i
555) const
556{
557 label foundProc = findProc(proci, i);
558
559 if (foundProc < 0)
560 {
562 << "Global id:" << i << " does not belong on any processor." << nl
563 << "Offsets:" << offsets_
565 }
566
567 return foundProc;
568}
569
570
571inline Foam::label Foam::globalIndex::whichProcID
572(
573 const label i
574) const
575{
577}
578
579
580inline void Foam::globalIndex::reset
581(
583 label localSize,
584 int communicator /* unused: (not applicable) */
585)
587 offsets_.resize_nocopy(2);
588 offsets_[0] = 0;
589 offsets_[1] = localSize;
590}
591
592
593inline void Foam::globalIndex::reset
594(
596 label localSize,
597 const label comm
599{
600 // one-sided
602}
603
604
605inline void Foam::globalIndex::reset
606(
608 label localSize,
609 const label comm
610)
612 // one-sided: non-master sizes only
613 if (UPstream::master(comm)) localSize = 0;
615}
616
617
618inline void Foam::globalIndex::reset(const globalIndex& rhs)
619{
620 if (this == &rhs)
621 {
622 return; // Self-assignment is a no-op
624 this->offsets_ = rhs.offsets_;
625}
626
627
628// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
629
632(
633 const globalIndex* globalIdx,
634 const label i
636:
637 parent_(globalIdx),
638 index_(i)
639{}
640
641
643index() const noexcept
644{
645 return index_;
646}
647
648
650start() const
651{
652 return (*parent_).localStart(index_);
653}
654
655
657size() const
658{
659 return (*parent_).localSize(index_);
660}
661
662
664range() const
665{
666 return (*parent_).range(index_);
667}
668
669
672{
673 return this->range();
674}
675
676
681 ++index_;
682 return *this;
683}
684
685
688operator++(int)
689{
690 const_iterator old(*this);
691 ++index_;
692 return old;
693}
694
695
700 --index_;
701 return *this;
702}
703
704
707operator--(int)
708{
709 const_iterator old(*this);
710 --index_;
711 return old;
712}
713
714
715inline bool
716Foam::globalIndex::const_iterator::
717operator==
718(
719 const const_iterator& iter
720) const noexcept
721{
722 return (index_ == iter.index_);
723}
724
725
726inline bool
727Foam::globalIndex::const_iterator::
728operator!=
729(
730 const const_iterator& iter
731) const noexcept
732{
733 return (index_ != iter.index_);
734}
735
736
737// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
738
741{
742 return const_iterator(this);
743}
744
745
748{
749 return const_iterator(this, this->length());
750}
751
752
755{
756 return const_iterator(this);
757}
758
759
762{
763 return const_iterator(this, this->length());
764}
765
766
768Foam::globalIndex::cbegin(const label i) const noexcept
770 const label len = this->length();
771 return const_iterator(this, (i < 0 ? 0 : len < i ? len : i));
772}
773
774
776Foam::globalIndex::begin(const label i) const noexcept
777{
778 return this->cbegin(i);
779}
780
781
782// ************************************************************************* //
scalar range
Various functions to operate on Lists.
SubList< label > subList
Definition List.H:129
A tuple of integers comprising start, size, total.
Definition OffsetRange.H:82
static const UList< label > & null() noexcept
Definition UList.H:225
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition UPstream.H:1706
static List< T > listGatherValues(const T &localValue, const int communicator=UPstream::worldComm)
Gather individual values into list locations.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition UPstream.H:1069
Forward input iterator with const access that is used to iterate across the globalIndex offsets() tab...
labelRange operator*() const
The local range.
labelRange range() const
The local range.
label size() const
The local size.
label index() const noexcept
The index into the arrays.
const_iterator(const globalIndex *globalIdx, const label i=0) noexcept
Construct from globalIndex list at given index.
label start() const
The local start.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
Definition globalIndex.H:77
globalIndex() noexcept=default
Default construct (empty).
bool single() const noexcept
True if local-only content (ie, nProcs == 1). Such content is often created with gatherNone.
label localEnd(const label proci) const
End of proci data.
const const_iterator end() const noexcept
A const_iterator set to beyond the end.
label maxSize() const
Global max of localSizes.
label totalSize() const noexcept
The total addressed size, which corresponds to the end offset and also the sum of all localSizes.
label localSize() const
Local size on myProcNo().
const_iterator cbegin() const noexcept
A const_iterator set to the beginning.
const const_iterator cend() const noexcept
A const_iterator set to beyond the end.
bool empty() const noexcept
Check for default constructed or total-size == 0.
labelRange range() const
Return start/size range of local (myProcNo) data.
label findProcBelow(const label proci, const label i) const
Find processor below proci with specified global id - binary search.
label toLocal(const label proci, const label i) const
From global to local on proci.
label maxNonLocalSize(const label proci) const
The max of localSizes, excluding the specified processor.
OffsetRange< label > slice(label proci) const noexcept
Return start/size/total slab addressing for proci data.
label span() const noexcept
The span size covered by the offsets, zero if empty.
label localStart() const
Local start on myProcNo().
label findProc(const label proci, const label i) const
Find processor with specified global id. Check proci first, followed by binary search.
label nProcs() const noexcept
The number of processors covered by the offsets, same as the primary length().
void inplaceToGlobal(const label proci, labelUList &labels) const
From local to global index on proci (inplace).
labelList localSizes() const
The local sizes.
const labelUList localStarts() const
The local starts.
label end_value() const noexcept
The value corresponding to the last offset (end offset), which is 1 beyond the end of the range.
label length() const noexcept
The number of items covered by the offsets.
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes).
label maxNonLocalSize() const
The max of localSizes, excluding current (myProcNo) rank.
label whichProcID(const label proci, const label i) const
Which processor does global id come from? Checks proci first (assumed to occur reasonably frequently)...
OffsetRange< label > slice() const
Return start/size/total slab addressing for local (myProcNo) data.
bool isLocal(const label proci, const label i) const
Is on processor proci.
bool contains(const label i) const noexcept
True if contained within the offsets range.
labelList sizes() const
The local sizes. Same as localSizes().
label toGlobal(const label proci, const label i) const
From local to global on proci.
label localStart(const label proci) const
Start of proci data.
labelRange allProcs() const noexcept
Range of process indices for all addressed offsets (processes).
void clear()
Reset to be empty (no offsets).
label localEnd() const
Local end on myProcNo().
const_iterator begin() const noexcept
A const_iterator set to the beginning.
void reset(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.
label localSize(const label proci) const
Size of proci data.
label begin_value() const noexcept
The value corresponding to the first offset.
const labelList & offsets() const noexcept
Const-access to the offsets.
label findProcAbove(const label proci, const label i) const
Find processor above proci with specified global id - binary search.
A range or interval of labels defined by a start and a size.
Definition labelRange.H:66
limits reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
List< label > labelList
A List of labels.
Definition List.H:62
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.
errorManip< error > abort(error &err)
Definition errorManip.H:139
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
const direction noexcept
Definition scalarImpl.H:265
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
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
Dispatch tag: Construct 'one-sided' from the non-master local sizes using gather but no broadcast.
Dispatch tag: Construct with a single (local size) entry, no communication.
Dispatch tag: Construct 'one-sided' from local sizes, using gather but no broadcast.