mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: improve flexibilty of globalIndex
- construct or reset from a list of local sizes. It is generally
easier and safer to assemble sizes and let globalIndex determine the
corresponding offsets, when working with raw values.
- Can use reset() from sizes or fine-tune offsets with setLocalSize()
instead of using the potentially more fragile non-const access to
the offsets.
- add globalIndex const_iterator to iterate across the access ranges.
This is makes it simpler to use with the List slice() method to
access or operate on a sub-section of list.
For example,
scalarField allValues = ...;
globalIndex procAccess = ...;
for (const labelRange& range : procAccess)
{
someOutput(allValues.slice(range));
}
This commit is contained in:
@ -27,6 +27,84 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "globalIndex.H"
|
||||
#include "labelRange.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
Foam::labelList
|
||||
Foam::globalIndex::calcOffsets
|
||||
(
|
||||
const labelUList& localSizes,
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
labelList values;
|
||||
|
||||
const label len = localSizes.size();
|
||||
|
||||
if (len)
|
||||
{
|
||||
values.resize(len+1);
|
||||
|
||||
label start = 0;
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
values[i] = start;
|
||||
start += localSizes[i];
|
||||
|
||||
if (checkOverflow && start < values[i])
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Overflow : sum of sizes exceeds labelMax ("
|
||||
<< labelMax << ") after index " << i << " of "
|
||||
<< flatOutput(localSizes) << nl
|
||||
<< "Please recompile with larger datatype for label." << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
values[len] = start;
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::labelRange>
|
||||
Foam::globalIndex::calcRanges
|
||||
(
|
||||
const labelUList& localSizes,
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
List<labelRange> values;
|
||||
|
||||
const label len = localSizes.size();
|
||||
|
||||
if (len)
|
||||
{
|
||||
values.resize(len);
|
||||
|
||||
label start = 0;
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
values[i].reset(start, localSizes[i]);
|
||||
start += localSizes[i];
|
||||
|
||||
if (checkOverflow && start < values[i].start())
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Overflow : sum of sizes exceeds labelMax ("
|
||||
<< labelMax << ") after index " << i << " of "
|
||||
<< flatOutput(localSizes) << nl
|
||||
<< "Please recompile with larger datatype for label." << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
@ -52,8 +130,8 @@ void Foam::globalIndex::bin
|
||||
bins.m() = UIndirectList<label>(globalIds, order);
|
||||
|
||||
labelList& binOffsets = bins.offsets();
|
||||
binOffsets.setSize(offsets.size());
|
||||
binOffsets = 0;
|
||||
binOffsets.resize_nocopy(offsets.size());
|
||||
binOffsets = Zero;
|
||||
|
||||
validBins.clear();
|
||||
|
||||
@ -106,33 +184,80 @@ void Foam::globalIndex::reset
|
||||
const bool parallel
|
||||
)
|
||||
{
|
||||
offsets_.resize(Pstream::nProcs(comm)+1);
|
||||
const label len = Pstream::nProcs(comm);
|
||||
|
||||
labelList localSizes(Pstream::nProcs(comm), Zero);
|
||||
localSizes[Pstream::myProcNo(comm)] = localSize;
|
||||
|
||||
if (parallel)
|
||||
if (len)
|
||||
{
|
||||
Pstream::gatherList(localSizes, tag, comm);
|
||||
Pstream::scatterList(localSizes, tag, comm);
|
||||
}
|
||||
// Seed with localSize, zero elsewhere (for non-parallel branch)
|
||||
labelList localSizes(len, Zero);
|
||||
localSizes[Pstream::myProcNo(comm)] = localSize;
|
||||
|
||||
label offset = 0;
|
||||
offsets_[0] = 0;
|
||||
for (const int proci : Pstream::allProcs(comm))
|
||||
{
|
||||
const label oldOffset = offset;
|
||||
offset += localSizes[proci];
|
||||
|
||||
if (offset < oldOffset)
|
||||
if (parallel)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Overflow : sum of sizes " << localSizes
|
||||
<< " exceeds capability of label (" << labelMax
|
||||
<< "). Please recompile with larger datatype for label."
|
||||
<< exit(FatalError);
|
||||
Pstream::gatherList(localSizes, tag, comm);
|
||||
Pstream::scatterList(localSizes, tag, comm);
|
||||
}
|
||||
|
||||
reset(localSizes, true); // checkOverflow = true
|
||||
}
|
||||
else
|
||||
{
|
||||
offsets_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::globalIndex::reset
|
||||
(
|
||||
const labelUList& localSizes,
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
const label len = localSizes.size();
|
||||
|
||||
if (len)
|
||||
{
|
||||
offsets_.resize_nocopy(len+1);
|
||||
|
||||
label start = 0;
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
offsets_[i] = start;
|
||||
start += localSizes[i];
|
||||
|
||||
if (checkOverflow && start < offsets_[i])
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Overflow : sum of sizes exceeds labelMax ("
|
||||
<< labelMax << ") after index " << i << " of "
|
||||
<< flatOutput(localSizes) << nl
|
||||
<< "Please recompile with larger datatype for label." << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
offsets_[len] = start;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsets_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::globalIndex::setLocalSize(const label proci, const label len)
|
||||
{
|
||||
if (proci >= 0 && proci+1 < offsets_.size() && len >= 0)
|
||||
{
|
||||
const label delta = (len - (offsets_[proci+1] - offsets_[proci]));
|
||||
|
||||
// TBD: additional overflow check
|
||||
if (delta)
|
||||
{
|
||||
for (label i = proci+1; i < offsets_.size(); ++i)
|
||||
{
|
||||
offsets_[i] += delta;
|
||||
}
|
||||
}
|
||||
offsets_[proci+1] = offset;
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,6 +284,33 @@ Foam::labelList Foam::globalIndex::sizes() const
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::labelRange>
|
||||
Foam::globalIndex::ranges() const
|
||||
{
|
||||
List<labelRange> values;
|
||||
|
||||
const label len = (offsets_.size() - 1);
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
return values;
|
||||
}
|
||||
|
||||
values.resize(len);
|
||||
|
||||
for (label proci=0; proci < len; ++proci)
|
||||
{
|
||||
values[proci].reset
|
||||
(
|
||||
offsets_[proci],
|
||||
(offsets_[proci+1] - offsets_[proci])
|
||||
);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::globalIndex::maxNonLocalSize(const label proci) const
|
||||
{
|
||||
const label len = (offsets_.size() - 1);
|
||||
|
||||
@ -68,6 +68,12 @@ Ostream& operator<<(Ostream& os, const globalIndex& gi);
|
||||
|
||||
class globalIndex
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Start of proci. Size is nProcs()+1. (so like CompactListList)
|
||||
labelList offsets_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- Sort and bin. validBins contains bins with non-zero size.
|
||||
@ -80,26 +86,42 @@ class globalIndex
|
||||
DynamicList<label>& validBins
|
||||
);
|
||||
|
||||
|
||||
// Private Data
|
||||
|
||||
//- Start of proci. Size is nProcs()+1. (so like CompactListList)
|
||||
labelList offsets_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Public Data Types
|
||||
|
||||
//- Disambiguation tag (list construction dispatch)
|
||||
enum accessType : char { OFFSETS, SIZES };
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
globalIndex() = default;
|
||||
|
||||
//- Construct from local max size.
|
||||
// Does communication with default communicator and message tag.
|
||||
//- Copy construct from a list of offsets.
|
||||
//- No communication required
|
||||
inline explicit globalIndex(const labelUList& listOffsets);
|
||||
|
||||
//- Move construct from a list of offsets.
|
||||
//- No communication required
|
||||
inline explicit globalIndex(labelList&& listOffsets);
|
||||
|
||||
//- Copy construct from a list of offsets or sizes.
|
||||
//- No communication required
|
||||
inline globalIndex
|
||||
(
|
||||
const labelUList& offsetsOrSizes,
|
||||
enum accessType accType
|
||||
);
|
||||
|
||||
//- Construct from local size.
|
||||
// Communication with default communicator and message tag.
|
||||
inline explicit globalIndex(const label localSize);
|
||||
|
||||
//- Construct from local max size.
|
||||
// Does communication with given communicator and message tag
|
||||
//- Construct from local size.
|
||||
// Communication with given communicator and message tag,
|
||||
// unless parallel == false
|
||||
inline globalIndex
|
||||
(
|
||||
const label localSize,
|
||||
@ -108,13 +130,8 @@ public:
|
||||
const bool parallel //!< use parallel comms
|
||||
);
|
||||
|
||||
//- Copy construct from list of labels
|
||||
inline explicit globalIndex(const labelUList& offsets);
|
||||
|
||||
//- Move construct from list of labels
|
||||
inline explicit globalIndex(labelList&& offsets);
|
||||
|
||||
//- Construct from Istream
|
||||
//- Construct from Istream.
|
||||
//- No communication required
|
||||
explicit globalIndex(Istream& is);
|
||||
|
||||
|
||||
@ -123,9 +140,6 @@ public:
|
||||
//- Check for default constructed or global sum == 0
|
||||
inline bool empty() const;
|
||||
|
||||
//- The number of processors covered by the offsets
|
||||
inline label nProcs() const noexcept;
|
||||
|
||||
//- Global sum of localSizes
|
||||
inline label size() const;
|
||||
|
||||
@ -142,6 +156,18 @@ public:
|
||||
inline const labelList& offsets() const noexcept;
|
||||
|
||||
|
||||
// Dimensions
|
||||
|
||||
//- The number of processors covered by the offsets
|
||||
inline label nProcs() const noexcept;
|
||||
|
||||
//- Range of process indices for all addressed offsets (processes)
|
||||
inline labelRange allProcs() const noexcept;
|
||||
|
||||
//- Range of process indices for addressed sub-offsets (processes)
|
||||
inline labelRange subProcs() const noexcept;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
//- Write-access to the offsets, for changing after construction
|
||||
@ -152,7 +178,8 @@ public:
|
||||
inline void reset(const label localSize);
|
||||
|
||||
//- Reset from local size.
|
||||
// Does communication with given communicator and message tag
|
||||
// Does communication with given communicator and message tag,
|
||||
// unless parallel == false
|
||||
void reset
|
||||
(
|
||||
const label localSize,
|
||||
@ -161,8 +188,20 @@ public:
|
||||
const bool parallel //!< use parallel comms
|
||||
);
|
||||
|
||||
//- Reset from list of local sizes,
|
||||
//- with optional check for label overflow.
|
||||
//- No communication required
|
||||
void reset
|
||||
(
|
||||
const labelUList& sizes,
|
||||
const bool checkOverflow = false
|
||||
);
|
||||
|
||||
// Queries
|
||||
//- Alter local size for given processor
|
||||
void setLocalSize(const label proci, const label len);
|
||||
|
||||
|
||||
// Queries
|
||||
|
||||
// Queries relating to my processor (using world communicator)
|
||||
|
||||
@ -178,6 +217,9 @@ public:
|
||||
//- Return start/size range of local processor data
|
||||
inline labelRange range() const;
|
||||
|
||||
//- Return start/size ranges for all data
|
||||
List<labelRange> ranges() const;
|
||||
|
||||
//- Is on local processor
|
||||
inline bool isLocal(const label i) const;
|
||||
|
||||
@ -240,6 +282,99 @@ public:
|
||||
inline label whichProcID(const label i) const;
|
||||
|
||||
|
||||
// Iteration
|
||||
|
||||
//- Forward input iterator with const access
|
||||
class const_iterator
|
||||
{
|
||||
//- The parent class for which this is an iterator
|
||||
const globalIndex* parent_;
|
||||
|
||||
//- The index into the parent
|
||||
label proci_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from globalIndex list at given index
|
||||
explicit const_iterator
|
||||
(
|
||||
const globalIndex* globalIdx,
|
||||
const label proci = 0
|
||||
) noexcept;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- The associated local proc
|
||||
inline label proci() const noexcept;
|
||||
|
||||
//- The local start
|
||||
inline label start() const;
|
||||
|
||||
//- The local size
|
||||
inline label size() const;
|
||||
|
||||
//- The local range
|
||||
inline labelRange range() const;
|
||||
|
||||
//- The local range
|
||||
inline labelRange operator*() const;
|
||||
|
||||
inline const_iterator& operator++();
|
||||
inline const_iterator operator++(int);
|
||||
|
||||
inline const_iterator& operator--();
|
||||
inline const_iterator operator--(int);
|
||||
|
||||
inline bool operator==(const const_iterator& iter) const noexcept;
|
||||
inline bool operator!=(const const_iterator& iter) const noexcept;
|
||||
};
|
||||
|
||||
|
||||
//- A const_iterator set to the beginning
|
||||
inline const_iterator cbegin() const noexcept;
|
||||
|
||||
//- A const_iterator set to beyond the end
|
||||
inline const const_iterator cend() const noexcept;
|
||||
|
||||
//- A const_iterator set to the beginning
|
||||
inline const_iterator begin() const noexcept;
|
||||
|
||||
//- A const_iterator set to beyond the end
|
||||
inline const const_iterator end() const noexcept;
|
||||
|
||||
|
||||
// Helper Functions
|
||||
|
||||
//- Calculate offsets from a list of local sizes,
|
||||
//- with optional check for label overflow
|
||||
static labelList calcOffsets
|
||||
(
|
||||
const labelUList& localSizes,
|
||||
const bool checkOverflow = false
|
||||
);
|
||||
|
||||
//- Calculate offsets from list of lists,
|
||||
//- with optional check for label overflow
|
||||
template<class SubListType>
|
||||
static labelList calcListOffsets
|
||||
(
|
||||
const List<SubListType>& lists,
|
||||
const bool checkOverflow = false
|
||||
);
|
||||
|
||||
//- Calculate ranges (offset/size) from a list of local sizes,
|
||||
//- with optional check for label overflow
|
||||
static List<labelRange> calcRanges
|
||||
(
|
||||
const labelUList& localSizes,
|
||||
const bool checkOverflow = false
|
||||
);
|
||||
|
||||
|
||||
// Other
|
||||
|
||||
//- Collect data in processor order on master (== procIDs[0]).
|
||||
|
||||
@ -31,9 +31,53 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::globalIndex::globalIndex
|
||||
(
|
||||
const labelUList& listOffsets
|
||||
)
|
||||
{
|
||||
if (listOffsets.size() > 1)
|
||||
{
|
||||
offsets_ = listOffsets;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::globalIndex
|
||||
(
|
||||
labelList&& listOffsets
|
||||
)
|
||||
{
|
||||
if (listOffsets.size() > 1)
|
||||
{
|
||||
offsets_.transfer(listOffsets);
|
||||
}
|
||||
else
|
||||
{
|
||||
listOffsets.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::globalIndex
|
||||
(
|
||||
const labelUList& offsetsOrSizes,
|
||||
enum globalIndex::accessType accType
|
||||
)
|
||||
{
|
||||
if (accType == accessType::SIZES)
|
||||
{
|
||||
reset(offsetsOrSizes);
|
||||
}
|
||||
else if (offsetsOrSizes.size() > 1)
|
||||
{
|
||||
// accessType::OFFSETS
|
||||
offsets_ = offsetsOrSizes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::globalIndex(const label localSize)
|
||||
:
|
||||
globalIndex()
|
||||
{
|
||||
reset(localSize);
|
||||
}
|
||||
@ -46,25 +90,11 @@ inline Foam::globalIndex::globalIndex
|
||||
const label comm,
|
||||
const bool parallel
|
||||
)
|
||||
:
|
||||
globalIndex()
|
||||
{
|
||||
reset(localSize, tag, comm, parallel);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::globalIndex(const labelUList& offsets)
|
||||
:
|
||||
offsets_(offsets)
|
||||
{}
|
||||
|
||||
|
||||
inline Foam::globalIndex::globalIndex(labelList&& offsets)
|
||||
:
|
||||
offsets_(std::move(offsets))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline bool Foam::globalIndex::empty() const
|
||||
@ -76,7 +106,23 @@ inline bool Foam::globalIndex::empty() const
|
||||
inline Foam::label Foam::globalIndex::nProcs() const noexcept
|
||||
{
|
||||
const label len = (offsets_.size() - 1);
|
||||
return (len < 1) ? 0 : len;
|
||||
return (len < 1) ? static_cast<label>(0) : len;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::labelRange Foam::globalIndex::allProcs() const noexcept
|
||||
{
|
||||
// Proc 0 -> nProcs
|
||||
const label len = (offsets_.size() - 1);
|
||||
return (len < 1) ? labelRange() : labelRange(0, len);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::labelRange Foam::globalIndex::subProcs() const noexcept
|
||||
{
|
||||
// Proc 1 -> nProcs
|
||||
const label len = (offsets_.size() - 2);
|
||||
return (len < 1) ? labelRange() : labelRange(1, len);
|
||||
}
|
||||
|
||||
|
||||
@ -104,7 +150,7 @@ inline const Foam::labelUList Foam::globalIndex::localStarts() const
|
||||
|
||||
inline Foam::label Foam::globalIndex::size() const
|
||||
{
|
||||
return offsets_.empty() ? 0 : offsets_.last();
|
||||
return offsets_.empty() ? static_cast<label>(0) : offsets_.last();
|
||||
}
|
||||
|
||||
|
||||
@ -276,4 +322,143 @@ inline Foam::label Foam::globalIndex::whichProcID(const label i) const
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::globalIndex::const_iterator::
|
||||
const_iterator
|
||||
(
|
||||
const globalIndex* globalIdx,
|
||||
const label i
|
||||
) noexcept
|
||||
:
|
||||
parent_(globalIdx),
|
||||
proci_(i)
|
||||
{}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::const_iterator::
|
||||
proci() const noexcept
|
||||
{
|
||||
return proci_;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::const_iterator::
|
||||
start() const
|
||||
{
|
||||
return (*parent_).localStart(proci_);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::label Foam::globalIndex::const_iterator::
|
||||
size() const
|
||||
{
|
||||
return (*parent_).localSize(proci_);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::labelRange Foam::globalIndex::const_iterator::
|
||||
range() const
|
||||
{
|
||||
return (*parent_).range(proci_);
|
||||
}
|
||||
|
||||
|
||||
inline Foam::labelRange Foam::globalIndex::const_iterator::
|
||||
operator*() const
|
||||
{
|
||||
return this->range();
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::const_iterator&
|
||||
Foam::globalIndex::const_iterator::
|
||||
operator++()
|
||||
{
|
||||
++proci_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::const_iterator
|
||||
Foam::globalIndex::const_iterator::
|
||||
operator++(int)
|
||||
{
|
||||
const_iterator old(*this);
|
||||
++proci_;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::const_iterator&
|
||||
Foam::globalIndex::const_iterator::
|
||||
operator--()
|
||||
{
|
||||
--proci_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::const_iterator
|
||||
Foam::globalIndex::const_iterator::
|
||||
operator--(int)
|
||||
{
|
||||
const_iterator old(*this);
|
||||
--proci_;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
Foam::globalIndex::const_iterator::
|
||||
operator==
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const noexcept
|
||||
{
|
||||
return (proci_ == iter.proci_);
|
||||
}
|
||||
|
||||
|
||||
inline bool
|
||||
Foam::globalIndex::const_iterator::
|
||||
operator!=
|
||||
(
|
||||
const const_iterator& iter
|
||||
) const noexcept
|
||||
{
|
||||
return (proci_ != iter.proci_);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::globalIndex::const_iterator
|
||||
Foam::globalIndex::cbegin() const noexcept
|
||||
{
|
||||
return const_iterator(this);
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::globalIndex::const_iterator
|
||||
Foam::globalIndex::cend() const noexcept
|
||||
{
|
||||
return const_iterator(this, this->nProcs());
|
||||
}
|
||||
|
||||
|
||||
inline Foam::globalIndex::const_iterator
|
||||
Foam::globalIndex::begin() const noexcept
|
||||
{
|
||||
return const_iterator(this);
|
||||
}
|
||||
|
||||
|
||||
inline const Foam::globalIndex::const_iterator
|
||||
Foam::globalIndex::end() const noexcept
|
||||
{
|
||||
return const_iterator(this, this->nProcs());
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -28,6 +28,46 @@ License
|
||||
|
||||
#include "globalIndex.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class SubListType>
|
||||
Foam::labelList
|
||||
Foam::globalIndex::calcListOffsets
|
||||
(
|
||||
const List<SubListType>& lists,
|
||||
const bool checkOverflow
|
||||
)
|
||||
{
|
||||
labelList values;
|
||||
|
||||
const label len = lists.size();
|
||||
|
||||
if (len)
|
||||
{
|
||||
values.resize(len+1);
|
||||
|
||||
label start = 0;
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
values[i] = start;
|
||||
start += lists[i].size();
|
||||
|
||||
if (checkOverflow && start < values[i])
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "Overflow : sum of sizes exceeds labelMax ("
|
||||
<< labelMax << ") after index " << i << nl
|
||||
<< "Please recompile with larger datatype for label." << nl
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
values[len] = start;
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class Container, class Type>
|
||||
|
||||
Reference in New Issue
Block a user