Merge branch 'extend-list-functionality' into 'develop'
Add SubList re-slicing, find within a List sub-section, uniformity enumeration See merge request Development/openfoam!626
This commit is contained in:
commit
f49403969e
@ -1,2 +1,2 @@
|
||||
api=2306
|
||||
api=2307
|
||||
patch=0
|
||||
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,6 +37,7 @@ Description
|
||||
#include "scalarField.H"
|
||||
#include "SubField.H"
|
||||
#include "labelRange.H"
|
||||
#include "ListOps.H"
|
||||
#include <numeric>
|
||||
|
||||
using namespace Foam;
|
||||
@ -57,26 +58,26 @@ int main(int argc, char *argv[])
|
||||
argList::noFunctionObjects();
|
||||
|
||||
{
|
||||
List<scalar> ident(25);
|
||||
List<label> ident(25);
|
||||
std::iota(ident.begin(), ident.end(), 0);
|
||||
|
||||
print(ident);
|
||||
|
||||
SubList<scalar>(ident, 10) = -10;
|
||||
SubList<label>(ident, 10) = -10;
|
||||
print(ident);
|
||||
|
||||
SubField<scalar>(ident, 10) = 10;
|
||||
SubField<label>(ident, 10) = 10;
|
||||
print(ident);
|
||||
|
||||
SubField<scalar>(ident, 10) += 10;
|
||||
SubField<label>(ident, 10) += 10;
|
||||
print(ident);
|
||||
|
||||
SubField<scalar>{ident, 10, 10} *= 5;
|
||||
SubField<label>{ident, 10, 10} *= 5;
|
||||
print(ident);
|
||||
|
||||
|
||||
// NOTE: Need {} instead of ()
|
||||
// SubList<scalar>(ident) = 100;
|
||||
// SubList<label>(ident) = 100;
|
||||
|
||||
// GCC
|
||||
// error: conflicting declaration 'Foam::SubList<double> ident'
|
||||
@ -85,7 +86,30 @@ int main(int argc, char *argv[])
|
||||
// warning: parentheses were disambiguated as redundant parentheses
|
||||
// around declaration of variable named 'ident' [-Wvexing-parse]
|
||||
|
||||
SubList<scalar>{ident} = 100;
|
||||
SubList<label>{ident} = 100;
|
||||
print(ident);
|
||||
|
||||
SubList<label> sub(ident);
|
||||
sub = 1;
|
||||
print(sub);
|
||||
|
||||
sub.reset(ident, labelRange(4, 5)) = 5;
|
||||
print(sub);
|
||||
print(ident);
|
||||
|
||||
sub.reset(ident, labelRange(14, 5)) = 15;
|
||||
print(sub);
|
||||
print(ident);
|
||||
|
||||
// Cryptic, probably not a great idea to write this
|
||||
sub.reset(ident, {20, 3}) = -1;
|
||||
print(sub);
|
||||
print(ident);
|
||||
|
||||
// This is also possible since we hold a concrete pointer/size
|
||||
// and not an intermediate
|
||||
ListOps::identity(sub.reset(ident, 8, 8));
|
||||
print(sub);
|
||||
print(ident);
|
||||
}
|
||||
|
||||
|
@ -51,13 +51,30 @@ int main(int argc, char *argv[])
|
||||
hmm.source()[1] = vector(1.0, 4.0, 3.0);
|
||||
hmm.source()[2] = vector(0.0, 5.0, 2.0);
|
||||
|
||||
Info<< hmm << endl;
|
||||
Info<< hmm.solve() << endl;
|
||||
Info<< hmm << endl;
|
||||
Info<< hmm.LUsolve() << endl;
|
||||
Info<< hmm << endl;
|
||||
Info<< hmm << nl;
|
||||
Info<< hmm.solve() << nl;
|
||||
Info<< hmm << nl;
|
||||
Info<< hmm.LUsolve() << nl;
|
||||
Info<< hmm << nl;
|
||||
|
||||
Info<< "End\n" << endl;
|
||||
{
|
||||
scalarSquareMatrix mat0;
|
||||
Info<< "empty: " << mat0 << endl;
|
||||
|
||||
mat0.resize_nocopy(1);
|
||||
mat0 = Identity<scalar>();
|
||||
Info<< "ident (1x1): " << mat0 << endl;
|
||||
|
||||
mat0.resize_nocopy(3);
|
||||
mat0 = Identity<scalar>();
|
||||
Info<< "ident (3x3): " << mat0 << endl;
|
||||
|
||||
mat0.resize_nocopy(5);
|
||||
mat0 = Identity<scalar>();
|
||||
Info<< "ident (5x5): " << mat0 << endl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ unset cmd
|
||||
|
||||
case "$WM_MPLIB" in
|
||||
*OPENMPI*)
|
||||
cmd="mpirun -app $PWD/mpirun.schema </dev/null"
|
||||
cmd="mpirun --oversubscribe -app $PWD/mpirun.schema </dev/null"
|
||||
;;
|
||||
MPICH)
|
||||
cmd="mpiexec"
|
||||
|
@ -304,16 +304,21 @@ runApplication()
|
||||
#
|
||||
runParallel()
|
||||
{
|
||||
local appName appRun optValue logFile logMode nProcs
|
||||
local appName appRun optValue logFile logMode
|
||||
local mpiopts nProcs
|
||||
|
||||
# Any additional parsed arguments (eg, decomposeParDict)
|
||||
local appArgs="-parallel"
|
||||
|
||||
local mpirun="mpirun"
|
||||
if [ "$FOAM_MPI" = msmpi ]
|
||||
then
|
||||
case "$FOAM_MPI" in
|
||||
(msmpi*)
|
||||
mpirun="mpiexec"
|
||||
fi
|
||||
;;
|
||||
(*openmpi*)
|
||||
mpiopts="--oversubscribe"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Parse options until executable is encountered
|
||||
while [ "$#" -gt 0 ] && [ -z "$appRun" ]
|
||||
@ -378,11 +383,11 @@ runParallel()
|
||||
if [ "$logMode" = append ]
|
||||
then
|
||||
(
|
||||
$mpirun -n $nProcs $appRun $appArgs "$@" </dev/null >> $logFile 2>&1
|
||||
"$mpirun" $mpiopts -n "${nProcs:?}" $appRun $appArgs "$@" </dev/null >> $logFile 2>&1
|
||||
)
|
||||
else
|
||||
(
|
||||
$mpirun -n $nProcs $appRun $appArgs "$@" </dev/null > $logFile 2>&1
|
||||
"$mpirun" $mpiopts -n "${nProcs:?}" $appRun $appArgs "$@" </dev/null > $logFile 2>&1
|
||||
)
|
||||
fi
|
||||
fi
|
||||
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018-2019 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -102,48 +102,51 @@ bool Foam::PackedList<Width>::uniform() const
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// The value of the first element for testing
|
||||
const unsigned int val = get(0);
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
bool identical = true;
|
||||
|
||||
if (!val)
|
||||
{
|
||||
// Zero value: can just check block content directly
|
||||
// No bits set: just check there are no non-zero blocks
|
||||
// - like bitSet::none()
|
||||
identical = (-1 == first_block());
|
||||
}
|
||||
else if (val == PackedList<Width>::max_value)
|
||||
{
|
||||
// All bits set: just check there are no zero blocks
|
||||
// - like bitSet::all()
|
||||
identical = (-1 == first_not_block());
|
||||
}
|
||||
else
|
||||
{
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki = 0; identical && blocki < nblocks; ++blocki)
|
||||
if (nblocks > 1)
|
||||
{
|
||||
identical = !blocks_[blocki];
|
||||
// Fill value for complete blocks
|
||||
const unsigned int blockval = repeated_value(val);
|
||||
|
||||
// Check each complete block (nblocks-1)
|
||||
for (label blocki = 0; identical && blocki < (nblocks-1); ++blocki)
|
||||
{
|
||||
identical = (blocks_[blocki] == blockval);
|
||||
}
|
||||
}
|
||||
|
||||
return identical;
|
||||
}
|
||||
else if (nblocks > 1)
|
||||
{
|
||||
// Fill value for complete blocks
|
||||
const unsigned int blockval = repeated_value(val);
|
||||
|
||||
// Check each complete block (nblocks-1)
|
||||
for (label blocki = 0; identical && blocki < (nblocks-1); ++blocki)
|
||||
// Partial block: check manually
|
||||
for
|
||||
(
|
||||
label elemi = elem_per_block*(nblocks-1);
|
||||
identical && elemi < size();
|
||||
++elemi
|
||||
)
|
||||
{
|
||||
identical = (blocks_[blocki] == blockval);
|
||||
identical = (val == get(elemi));
|
||||
}
|
||||
}
|
||||
|
||||
// Partial block: check manually
|
||||
for
|
||||
(
|
||||
label elemi = elem_per_block*(nblocks-1);
|
||||
identical && elemi < size();
|
||||
++elemi
|
||||
)
|
||||
{
|
||||
identical = (val == get(elemi));
|
||||
}
|
||||
|
||||
return identical;
|
||||
}
|
||||
|
||||
@ -194,16 +197,20 @@ Foam::PackedList<Width>::unpack() const
|
||||
"Width of IntType is too small to hold result"
|
||||
);
|
||||
|
||||
List<IntType> output(size());
|
||||
|
||||
if (empty())
|
||||
{
|
||||
return List<IntType>(0);
|
||||
return output;
|
||||
}
|
||||
else if (uniform())
|
||||
{
|
||||
return List<IntType>(size(), static_cast<IntType>(get(0)));
|
||||
output = static_cast<IntType>(get(0));
|
||||
return output;
|
||||
}
|
||||
|
||||
List<IntType> output(size());
|
||||
// NON-UNIFORM and len > 0
|
||||
|
||||
label outi = 0;
|
||||
|
||||
// Process n-1 complete blocks
|
||||
@ -215,7 +222,7 @@ Foam::PackedList<Width>::unpack() const
|
||||
|
||||
for (unsigned nget = elem_per_block; nget; --nget, ++outi)
|
||||
{
|
||||
output[outi] = IntType(blockval & max_value);
|
||||
output[outi] = IntType(blockval & PackedList<Width>::max_value);
|
||||
blockval >>= Width;
|
||||
}
|
||||
}
|
||||
|
@ -221,6 +221,14 @@ protected:
|
||||
//- Copy assignment
|
||||
inline void copyAssign(const PackedList<Width>& rhs);
|
||||
|
||||
//- Find the first block with a '1' bit
|
||||
// \return block number or -1 for an list or if all bits are OFF.
|
||||
inline label first_block() const;
|
||||
|
||||
//- Find the first block with a '0' bit
|
||||
// \return block number or -1 for an list or if all bits are ON.
|
||||
inline label first_not_block() const;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
@ -292,7 +300,7 @@ public:
|
||||
//- Number of elements that can be stored without reallocating
|
||||
inline label capacity() const noexcept;
|
||||
|
||||
//- True if all entries have identical values, and list is non-empty
|
||||
//- True if all entries have identical values (and list is non-empty)
|
||||
bool uniform() const;
|
||||
|
||||
//- Test for equality of sizes and the bits set
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -147,6 +147,73 @@ inline void Foam::PackedList<Width>::copyAssign(const PackedList<Width>& rhs)
|
||||
}
|
||||
|
||||
|
||||
template<unsigned Width>
|
||||
inline Foam::label Foam::PackedList<Width>::first_block() const
|
||||
{
|
||||
if (size())
|
||||
{
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (blocks_[blocki])
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
template<unsigned Width>
|
||||
inline Foam::label Foam::PackedList<Width>::first_not_block() const
|
||||
{
|
||||
if (!size())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check on complement (changes 0 <-> 1).
|
||||
// If any 1's now appear, there was a 0 bit before
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
// Extra bits in the final block?
|
||||
const unsigned int off = size() % elem_per_block;
|
||||
|
||||
if (!off)
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks-1; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
|
||||
// The final block needs masking
|
||||
if (~(blocks_[nblocks-1]) & mask_lower(off))
|
||||
{
|
||||
return nblocks-1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Specializations * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
|
@ -18,8 +18,8 @@ Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef PackedBoolList_H
|
||||
#define PackedBoolList_H
|
||||
#ifndef FoamCompat_PackedBoolList_H
|
||||
#define FoamCompat_PackedBoolList_H
|
||||
|
||||
#include "bitSet.H"
|
||||
|
||||
|
@ -65,13 +65,6 @@ class bitSet
|
||||
:
|
||||
public PackedList<1>
|
||||
{
|
||||
// Private Member Functions
|
||||
|
||||
//- Find the first block with a '0' bit
|
||||
// \return block number or -1 if the set is empty or all bits are on.
|
||||
inline label first_not_block() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Logic/Set Operations
|
||||
@ -138,7 +131,7 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Default construct an empty, zero-sized bitSet
|
||||
inline bitSet() noexcept;
|
||||
inline constexpr bitSet() noexcept;
|
||||
|
||||
//- Construct from Istream
|
||||
explicit bitSet(Istream& is);
|
||||
@ -246,9 +239,6 @@ public:
|
||||
// \note Method name compatibility with boost::dynamic_bitset
|
||||
inline bool none() const;
|
||||
|
||||
//- True if all entries have identical values, and the set is non-empty
|
||||
inline bool uniform() const;
|
||||
|
||||
//- Count number of bits set.
|
||||
// \param on can be set to false to count the number of unset bits
|
||||
// instead.
|
||||
|
@ -25,56 +25,9 @@ License
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
inline Foam::label Foam::bitSet::first_not_block() const
|
||||
{
|
||||
if (empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Use complement to change 0 <-> 1 and check if any 1's now appear
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
// Extra bits in the final block?
|
||||
const unsigned int off = size() % elem_per_block;
|
||||
|
||||
if (!off)
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (label blocki=0; blocki < nblocks-1; ++blocki)
|
||||
{
|
||||
if (~(blocks_[blocki]))
|
||||
{
|
||||
return blocki;
|
||||
}
|
||||
}
|
||||
|
||||
// The final block needs masking
|
||||
if (~(blocks_[nblocks-1]) & mask_lower(off))
|
||||
{
|
||||
return nblocks-1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
inline Foam::bitSet::bitSet() noexcept
|
||||
inline constexpr Foam::bitSet::bitSet() noexcept
|
||||
:
|
||||
PackedList<1>()
|
||||
{}
|
||||
@ -313,14 +266,14 @@ inline Foam::bitSet::const_iterator Foam::bitSet::cend() const noexcept
|
||||
|
||||
inline Foam::label Foam::bitSet::find_first() const
|
||||
{
|
||||
// Process block-wise, detecting any '1' bits
|
||||
const label blocki = first_block();
|
||||
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki = 0; blocki < nblocks; ++blocki)
|
||||
if (blocki >= 0)
|
||||
{
|
||||
label pos = (blocki * elem_per_block);
|
||||
|
||||
// Detect first '1' bit within the block
|
||||
|
||||
for
|
||||
(
|
||||
unsigned int blockval = blocks_[blocki];
|
||||
@ -348,7 +301,7 @@ inline Foam::label Foam::bitSet::find_first_not() const
|
||||
{
|
||||
label pos = (blocki * elem_per_block);
|
||||
|
||||
// Detect first '0' bit by checking the complement.
|
||||
// Detect first '0' bit within the block (check the complement)
|
||||
|
||||
// No special masking for the final block, that was already checked
|
||||
// in the first_not_block() call.
|
||||
@ -461,39 +414,19 @@ inline const Foam::bitSet& Foam::bitSet::null()
|
||||
inline bool Foam::bitSet::all() const
|
||||
{
|
||||
if (empty()) return true; // SIC. boost convention
|
||||
|
||||
return -1 == first_not_block();
|
||||
return (-1 == first_not_block());
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::bitSet::any() const
|
||||
{
|
||||
if (size())
|
||||
{
|
||||
const label nblocks = num_blocks(size());
|
||||
|
||||
for (label blocki=0; blocki < nblocks; ++blocki)
|
||||
{
|
||||
if (blocks_[blocki])
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return (-1 != first_block());
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::bitSet::none() const
|
||||
{
|
||||
return !any();
|
||||
}
|
||||
|
||||
|
||||
inline bool Foam::bitSet::uniform() const
|
||||
{
|
||||
return (size() == 1 || (size() > 1 && (test(0) ? all() : none())));
|
||||
return (-1 == first_block());
|
||||
}
|
||||
|
||||
|
||||
|
@ -108,6 +108,8 @@ const Foam::SubList<T> Foam::CircularBuffer<T>::array_two() const
|
||||
template<class T>
|
||||
Foam::label Foam::CircularBuffer<T>::find(const T& val, label pos) const
|
||||
{
|
||||
if (pos < 0) return -1; // no-op
|
||||
|
||||
label i = -1;
|
||||
|
||||
const auto list1 = this->array_one();
|
||||
|
@ -282,18 +282,21 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- True if the value is contained in the list.
|
||||
inline bool contains(const T& val) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Stack-like Operations
|
||||
|
||||
|
@ -255,6 +255,13 @@ inline void Foam::CircularBuffer<T>::reserve_nocopy(const label len)
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
bool Foam::CircularBuffer<T>::contains(const T& val) const
|
||||
{
|
||||
return (this->array_one().contains(val) || this->array_two().contains(val));
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::CircularBuffer<T>::contains(const T& val, label pos) const
|
||||
{
|
||||
|
@ -31,13 +31,21 @@ template<class T, class Addr>
|
||||
Foam::label Foam::IndirectListBase<T, Addr>::find
|
||||
(
|
||||
const T& val,
|
||||
label pos
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
const label len = addr_.size();
|
||||
|
||||
if (pos >= 0 && len)
|
||||
if (pos >= 0 && pos < addr_.size())
|
||||
{
|
||||
// Change sub-length to (one-past) end position
|
||||
// len == -1 (like std::string::npos) - search until end
|
||||
|
||||
if (len > 0) len += pos;
|
||||
if (len < 0 || len > addr_.size())
|
||||
{
|
||||
len = addr_.size();
|
||||
}
|
||||
|
||||
const T* const vals = values_.begin();
|
||||
|
||||
while (pos < len)
|
||||
@ -62,7 +70,7 @@ Foam::label Foam::IndirectListBase<T, Addr>::rfind
|
||||
label pos
|
||||
) const
|
||||
{
|
||||
// pos == -1 has same meaning as std::string::npos - search from end
|
||||
// pos == -1 (like std::string::npos) - search from end
|
||||
|
||||
if (pos < 0 || pos >= addr_.size())
|
||||
{
|
||||
|
@ -179,11 +179,19 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (default: 0, no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0, label len = -1) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \return -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (default: 0, no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos = 0, label len = -1) const;
|
||||
|
||||
//- Find index of the last occurrence of the value.
|
||||
// Any occurrences after the end pos are ignored.
|
||||
@ -191,12 +199,6 @@ public:
|
||||
// \return -1 if not found.
|
||||
label rfind(const T& val, label pos = -1) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
|
@ -102,10 +102,11 @@ template<class T, class Addr>
|
||||
inline bool Foam::IndirectListBase<T, Addr>::contains
|
||||
(
|
||||
const T& val,
|
||||
label pos
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
return (this->find(val, pos) >= 0);
|
||||
return (this->find(val, pos, len) >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -222,6 +222,27 @@ Foam::Istream& Foam::DynamicList<T, SizeMin>::readList(Istream& is)
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (std::is_same<char, T>::value)
|
||||
{
|
||||
// Special treatment for char data (always binary and contiguous)
|
||||
// (see List<char>::readList)
|
||||
|
||||
if (len)
|
||||
{
|
||||
const auto oldFmt = is.format(IOstreamOption::BINARY);
|
||||
|
||||
// read(...) includes surrounding start/end delimiters
|
||||
is.read(list.data_bytes(), list.size_bytes());
|
||||
|
||||
is.format(oldFmt);
|
||||
|
||||
is.fatalCheck
|
||||
(
|
||||
"DynamicList<char>::readList(Istream&) : "
|
||||
"reading binary block"
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Begin of contents marker
|
||||
|
@ -46,24 +46,42 @@ std::streamsize Foam::FixedList<T, N>::byteSize()
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T, unsigned N>
|
||||
Foam::label Foam::FixedList<T, N>::find(const T& val, label pos) const
|
||||
Foam::label Foam::FixedList<T, N>::find(const T& val) const
|
||||
{
|
||||
if (pos >= 0)
|
||||
const auto iter = std::find(this->cbegin(), this->cend(), val);
|
||||
return (iter != this->cend() ? label(iter - this->cbegin()) : label(-1));
|
||||
}
|
||||
|
||||
|
||||
template<class T, unsigned N>
|
||||
Foam::label Foam::FixedList<T, N>::find
|
||||
(
|
||||
const T& val,
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
if (pos >= 0 && pos < label(N))
|
||||
{
|
||||
// auto iter = std::find(this->begin(pos), this->end(), val);
|
||||
// if (iter != this->end())
|
||||
// {
|
||||
// return label(iter - this->begin());
|
||||
// }
|
||||
// Change sub-length to (one-past) end position
|
||||
// len == -1 (like std::string::npos) - search until end
|
||||
|
||||
while (pos < label(N))
|
||||
if (len > 0) len += pos;
|
||||
if (len < 0 || len > label(N))
|
||||
{
|
||||
if (this->v_[pos] == val)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
len = label(N);
|
||||
}
|
||||
|
||||
++pos;
|
||||
const auto iter = std::find
|
||||
(
|
||||
(this->cbegin() + pos),
|
||||
(this->cbegin() + len),
|
||||
val
|
||||
);
|
||||
|
||||
if (iter != (this->cbegin() + len))
|
||||
{
|
||||
return label(iter - this->cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +92,8 @@ Foam::label Foam::FixedList<T, N>::find(const T& val, label pos) const
|
||||
template<class T, unsigned N>
|
||||
Foam::label Foam::FixedList<T, N>::rfind(const T& val, label pos) const
|
||||
{
|
||||
// pos == -1 has same meaning as std::string::npos - search from end
|
||||
// pos == -1 (like std::string::npos) - search from end
|
||||
|
||||
if (pos < 0 || pos >= label(N))
|
||||
{
|
||||
pos = label(N)-1;
|
||||
|
@ -275,11 +275,27 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- True if the value is contained in the list.
|
||||
inline bool contains(const T& val) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \return -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
// \param val The value to search for
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the last occurrence of the value.
|
||||
// Any occurrences after the end pos are ignored.
|
||||
@ -287,12 +303,6 @@ public:
|
||||
// \return position in list or -1 if not found.
|
||||
label rfind(const T& val, label pos = -1) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
|
@ -307,9 +307,22 @@ inline bool Foam::FixedList<T, N>::uniform() const
|
||||
|
||||
|
||||
template<class T, unsigned N>
|
||||
inline bool Foam::FixedList<T, N>::contains(const T& val, label pos) const
|
||||
inline bool Foam::FixedList<T, N>::contains(const T& val) const
|
||||
{
|
||||
return (this->find(val, pos) >= 0);
|
||||
const auto iter = std::find(this->cbegin(), this->cend(), val);
|
||||
return (iter != this->cend());
|
||||
}
|
||||
|
||||
|
||||
template<class T, unsigned N>
|
||||
inline bool Foam::FixedList<T, N>::contains
|
||||
(
|
||||
const T& val,
|
||||
label pos,
|
||||
label len
|
||||
) const
|
||||
{
|
||||
return (this->find(val, pos, len) >= 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -89,7 +89,7 @@ public:
|
||||
// Constructors
|
||||
|
||||
//- Construct from UList, the entire size
|
||||
inline explicit SubList(const UList<T>& list);
|
||||
inline explicit SubList(const UList<T>& list) noexcept;
|
||||
|
||||
//- Construct from FixedList, the entire size
|
||||
template<unsigned N>
|
||||
@ -128,6 +128,47 @@ public:
|
||||
);
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Reset to zero-sized and nullptr
|
||||
inline UList<T>& reset(std::nullptr_t) noexcept;
|
||||
|
||||
//- Reset to use entire UList
|
||||
inline UList<T>& reset(const UList<T>& list) noexcept;
|
||||
|
||||
//- Reset to use UList with sub-list size, start at 0
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize
|
||||
);
|
||||
|
||||
//- Reset to use UList with sub-list size and start index
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize,
|
||||
const label startIndex
|
||||
);
|
||||
|
||||
//- Reset to use UList with a (start,size) range.
|
||||
// The range is subsetted with the list size itself to ensure that the
|
||||
// result always addresses a valid section of the list.
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const labelRange& range
|
||||
);
|
||||
|
||||
//- Reset to use UList with a (start,size) range, but bypassing
|
||||
//- run-time range checking.
|
||||
inline UList<T>& reset
|
||||
(
|
||||
const labelRange& range,
|
||||
const UList<T>& list
|
||||
);
|
||||
|
||||
|
||||
// Member Operators
|
||||
|
||||
//- Allow cast to a const List\<T\>&
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -28,13 +28,22 @@ License
|
||||
|
||||
#include "FixedList.H"
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline const Foam::SubList<T>& Foam::SubList<T>::null()
|
||||
{
|
||||
return NullObjectRef<SubList<T>>();
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline Foam::SubList<T>::SubList
|
||||
(
|
||||
const UList<T>& list
|
||||
)
|
||||
) noexcept
|
||||
:
|
||||
UList<T>(const_cast<T*>(list.cdata()), list.size())
|
||||
{}
|
||||
@ -113,9 +122,102 @@ inline Foam::SubList<T>::SubList
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
template<class T>
|
||||
inline const Foam::SubList<T>& Foam::SubList<T>::null()
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset(std::nullptr_t) noexcept
|
||||
{
|
||||
return NullObjectRef<SubList<T>>();
|
||||
UList<T>::shallowCopy(nullptr, 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list
|
||||
) noexcept
|
||||
{
|
||||
UList<T>::shallowCopy(list);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
list.checkSize(subSize);
|
||||
#endif
|
||||
|
||||
UList<T>::shallowCopy(const_cast<T*>(list.cdata()), subSize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const label subSize,
|
||||
const label startIndex
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
list.checkRange(startIndex, subSize);
|
||||
#endif
|
||||
|
||||
UList<T>::shallowCopy
|
||||
(
|
||||
const_cast<T*>(list.cdata() + startIndex),
|
||||
subSize
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const UList<T>& list,
|
||||
const labelRange& range
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
// subset0() always produces valid ranges but want to check
|
||||
// that the input itself was valid
|
||||
list.checkRange(range.start(), range.size());
|
||||
#endif
|
||||
|
||||
labelRange clamped(range.subset0(list.size()));
|
||||
|
||||
UList<T>::shallowCopy
|
||||
(
|
||||
const_cast<T*>(list.cdata() + clamped.start()),
|
||||
clamped.size()
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline Foam::UList<T>& Foam::SubList<T>::reset
|
||||
(
|
||||
const labelRange& range,
|
||||
const UList<T>& list
|
||||
)
|
||||
{
|
||||
#ifdef FULLDEBUG
|
||||
list.checkRange(range.start(), range.size());
|
||||
#endif
|
||||
|
||||
UList<T>::shallowCopy
|
||||
(
|
||||
const_cast<T*>(list.cdata() + range.start()),
|
||||
range.size()
|
||||
);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -177,26 +177,37 @@ std::streamsize Foam::UList<T>::byteSize() const
|
||||
|
||||
|
||||
template<class T>
|
||||
Foam::label Foam::UList<T>::find(const T& val, label pos) const
|
||||
Foam::label Foam::UList<T>::find(const T& val) const
|
||||
{
|
||||
const label len = this->size();
|
||||
const auto iter = std::find(this->cbegin(), this->cend(), val);
|
||||
return (iter != this->cend() ? label(iter - this->cbegin()) : label(-1));
|
||||
}
|
||||
|
||||
if (pos >= 0)
|
||||
|
||||
template<class T>
|
||||
Foam::label Foam::UList<T>::find(const T& val, label pos, label len) const
|
||||
{
|
||||
if (pos >= 0 && pos < this->size())
|
||||
{
|
||||
// auto iter = std::find(this->begin(pos), this->end(), val);
|
||||
// if (iter != this->end())
|
||||
// {
|
||||
// return label(iter - this->begin());
|
||||
// }
|
||||
// Change sub-length to (one-past) end position
|
||||
// len == -1 (like std::string::npos) - search until end
|
||||
|
||||
while (pos < len)
|
||||
if (len > 0) len += pos;
|
||||
if (len < 0 || len > this->size())
|
||||
{
|
||||
if (this->v_[pos] == val)
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
len = this->size();
|
||||
}
|
||||
|
||||
++pos;
|
||||
const auto iter = std::find
|
||||
(
|
||||
(this->cbegin() + pos),
|
||||
(this->cbegin() + len),
|
||||
val
|
||||
);
|
||||
|
||||
if (iter != (this->cbegin() + len))
|
||||
{
|
||||
return label(iter - this->cbegin());
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,7 +218,8 @@ Foam::label Foam::UList<T>::find(const T& val, label pos) const
|
||||
template<class T>
|
||||
Foam::label Foam::UList<T>::rfind(const T& val, label pos) const
|
||||
{
|
||||
// pos == -1 has same meaning as std::string::npos - search from end
|
||||
// pos == -1 (like std::string::npos) - search from end
|
||||
|
||||
if (pos < 0 || pos >= this->size())
|
||||
{
|
||||
pos = this->size()-1;
|
||||
|
@ -318,11 +318,27 @@ public:
|
||||
|
||||
// Search
|
||||
|
||||
//- True if the value is contained in the list.
|
||||
inline bool contains(const T& val) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// Linear search.
|
||||
// \param val The value to search for
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos = 0) const;
|
||||
label find(const T& val) const;
|
||||
|
||||
//- Find index of the first occurrence of the value.
|
||||
// \param val The value to search for
|
||||
// \param pos The first position to examine (no-op if -ve)
|
||||
// \param len The length of the search region (-ve until the end)
|
||||
// \return position in list or -1 if not found.
|
||||
label find(const T& val, label pos, label len = -1) const;
|
||||
|
||||
//- Find index of the last occurrence of the value.
|
||||
// Any occurrences after the end pos are ignored.
|
||||
@ -330,12 +346,6 @@ public:
|
||||
// \return position in list or -1 if not found.
|
||||
label rfind(const T& val, label pos = -1) const;
|
||||
|
||||
//- Is the value contained in the list?
|
||||
// Linear search from start pos until the end of the list.
|
||||
// Any occurrences before the start pos are ignored.
|
||||
// \return true if found.
|
||||
inline bool contains(const T& val, label pos = 0) const;
|
||||
|
||||
|
||||
// Edit
|
||||
|
||||
@ -354,6 +364,9 @@ public:
|
||||
|
||||
// Copy
|
||||
|
||||
//- Copy the pointer and size
|
||||
inline void shallowCopy(T* __restrict__ ptr, const label len) noexcept;
|
||||
|
||||
//- Copy the pointer and size held by the given UList
|
||||
inline void shallowCopy(const UList<T>& list) noexcept;
|
||||
|
||||
|
@ -304,9 +304,29 @@ inline std::streamsize Foam::UList<T>::size_bytes() const noexcept
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::UList<T>::contains(const T& val, label pos) const
|
||||
inline bool Foam::UList<T>::contains(const T& val) const
|
||||
{
|
||||
return (this->find(val, pos) >= 0);
|
||||
const auto iter = std::find(this->begin(), this->end(), val);
|
||||
return (iter != this->end());
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline bool Foam::UList<T>::contains(const T& val, label pos, label len) const
|
||||
{
|
||||
return (this->find(val, pos, len) >= 0);
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
inline void Foam::UList<T>::shallowCopy
|
||||
(
|
||||
T* __restrict__ ptr,
|
||||
const label len
|
||||
) noexcept
|
||||
{
|
||||
size_ = len;
|
||||
v_ = ptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -187,10 +187,7 @@ Foam::Istream& Foam::UList<T>::readList(Istream& is)
|
||||
<< exit(FatalIOError);
|
||||
}
|
||||
|
||||
for (label i = 0; i < len; ++i)
|
||||
{
|
||||
list[i] = std::move(elems[i]);
|
||||
}
|
||||
std::move(elems.begin(), elems.end(), list.begin());
|
||||
}
|
||||
else if (tok.isLabel())
|
||||
{
|
||||
|
@ -42,11 +42,12 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const std::vector<T>& list)
|
||||
|
||||
os << label(list.size()) << token::BEGIN_LIST;
|
||||
|
||||
// Contents
|
||||
if (iter != last)
|
||||
{
|
||||
os << *iter;
|
||||
|
||||
while (++iter != last)
|
||||
for (++iter; (iter != last); (void)++iter)
|
||||
{
|
||||
os << token::SPACE << *iter;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2019 OpenCFD Ltd.
|
||||
Copyright (C) 2019-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -88,6 +88,41 @@ template<> struct no_linebreak<word> : std::true_type {};
|
||||
template<> struct no_linebreak<wordRe> : std::true_type {};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
//- Classification of list/container uniformity.
|
||||
//- The values can be used with bit-wise \c or reduction
|
||||
enum uniformity : unsigned char
|
||||
{
|
||||
EMPTY = 0, //!< An empty container
|
||||
UNIFORM = 0x1, //!< Container (non-empty) with identical values
|
||||
NONUNIFORM = 0x2, //!< Container (non-empty) with different values
|
||||
MIXED = 0x3 //!< Mixed uniform/non-uniform (eg, after reduction)
|
||||
};
|
||||
|
||||
//- Algorithm to determine list/container uniformity
|
||||
template<class InputIt>
|
||||
enum uniformity check_uniformity(InputIt first, InputIt last)
|
||||
{
|
||||
if (first == last) return uniformity::EMPTY;
|
||||
|
||||
// Like std::all_of() with checking against element 0,
|
||||
// but without using a lambda with auto type (pre C++14) etc.
|
||||
|
||||
const auto& elem0 = *first;
|
||||
|
||||
for ((void)++first; (first != last); (void)++first)
|
||||
{
|
||||
if (elem0 != *first)
|
||||
{
|
||||
return uniformity::NONUNIFORM;
|
||||
}
|
||||
}
|
||||
|
||||
return uniformity::UNIFORM;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace ListPolicy
|
||||
|
@ -172,7 +172,7 @@ public:
|
||||
|
||||
#include "SubFieldI.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * * * Implementations * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::SubField<Type>
|
||||
|
@ -146,9 +146,9 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
|
||||
) const
|
||||
{
|
||||
const Matrix<Form, Type>& mat = *this;
|
||||
const label len = mat.size(); // Total size (rows * cols)
|
||||
|
||||
// The total size
|
||||
const label len = mat.size();
|
||||
auto iter = mat.cbegin(); // element-wise iterator
|
||||
|
||||
// Rows, columns size
|
||||
os << mat.nRows() << token::SPACE << mat.nCols();
|
||||
@ -163,73 +163,101 @@ Foam::Ostream& Foam::Matrix<Form, Type>::writeMatrix
|
||||
os.write(mat.cdata_bytes(), mat.size_bytes());
|
||||
}
|
||||
}
|
||||
else if (len > 1 && is_contiguous<Type>::value && mat.uniform())
|
||||
{
|
||||
// Two or more entries, and all entries have identical values.
|
||||
os << token::BEGIN_BLOCK << *iter << token::END_BLOCK;
|
||||
}
|
||||
else if
|
||||
(
|
||||
(len <= 1 || !shortLen)
|
||||
|| (len <= shortLen && is_contiguous<Type>::value)
|
||||
)
|
||||
{
|
||||
// Single-line output (entire matrix)
|
||||
|
||||
// Begin matrix
|
||||
os << token::BEGIN_LIST;
|
||||
|
||||
// Loop over rows
|
||||
for (label i = 0; i < mat.nRows(); ++i)
|
||||
{
|
||||
// Begin row
|
||||
os << token::BEGIN_LIST;
|
||||
|
||||
// Write row
|
||||
for (label j = 0; j < mat.nCols(); ++j)
|
||||
{
|
||||
if (j) os << token::SPACE;
|
||||
os << *iter;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// End row
|
||||
os << token::END_LIST;
|
||||
}
|
||||
|
||||
// End matrix
|
||||
os << token::END_LIST;
|
||||
}
|
||||
else if
|
||||
(
|
||||
(mat.nCols() <= 1 || !shortLen)
|
||||
|| (mat.nCols() <= shortLen && is_contiguous<Type>::value)
|
||||
)
|
||||
{
|
||||
// Multi-line matrix, single-line rows
|
||||
|
||||
// Begin matrix
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
// Loop over rows
|
||||
for (label i = 0; i < mat.nRows(); ++i)
|
||||
{
|
||||
// Begin row
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
// Write row
|
||||
for (label j = 0; j < mat.nCols(); ++j)
|
||||
{
|
||||
if (j) os << token::SPACE;
|
||||
os << *iter;
|
||||
++iter;
|
||||
}
|
||||
|
||||
// End row
|
||||
os << token::END_LIST;
|
||||
}
|
||||
|
||||
// End matrix
|
||||
os << nl << token::END_LIST << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len)
|
||||
// Multi-line output
|
||||
|
||||
// Begin matrix
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
// Loop over rows
|
||||
for (label i=0; i < mat.nRows(); ++i)
|
||||
{
|
||||
const Type* v = mat.cdata();
|
||||
// Begin row
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
// Can the contents be considered 'uniform' (ie, identical)
|
||||
if (len > 1 && is_contiguous<Type>::value && mat.uniform())
|
||||
// Write row
|
||||
for (label j = 0; j < mat.nCols(); ++j)
|
||||
{
|
||||
// Two or more entries, and all entries have identical values.
|
||||
os << token::BEGIN_BLOCK << v[0] << token::END_BLOCK;
|
||||
os << nl << *iter;
|
||||
++iter;
|
||||
}
|
||||
else if (len < shortLen && is_contiguous<Type>::value)
|
||||
{
|
||||
// Write start contents delimiter
|
||||
os << token::BEGIN_LIST;
|
||||
|
||||
label idx = 0;
|
||||
|
||||
// Loop over rows
|
||||
for (label i = 0; i < mat.nRows(); ++i)
|
||||
{
|
||||
os << token::BEGIN_LIST;
|
||||
|
||||
// Write row
|
||||
for (label j = 0; j < mat.nCols(); ++j)
|
||||
{
|
||||
if (j) os << token::SPACE;
|
||||
os << v[idx++];
|
||||
}
|
||||
|
||||
os << token::END_LIST;
|
||||
}
|
||||
|
||||
// Write end of contents delimiter
|
||||
os << token::END_LIST;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Write start contents delimiter
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
label idx = 0;
|
||||
|
||||
// Loop over rows
|
||||
for (label i=0; i < mat.nRows(); ++i)
|
||||
{
|
||||
os << nl << token::BEGIN_LIST;
|
||||
|
||||
// Write row
|
||||
for (label j = 0; j < mat.nCols(); ++j)
|
||||
{
|
||||
os << nl << v[idx++];
|
||||
}
|
||||
|
||||
os << nl << token::END_LIST;
|
||||
}
|
||||
|
||||
// Write end of contents delimiter
|
||||
os << nl << token::END_LIST << nl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Empty matrix
|
||||
os << token::BEGIN_LIST << token::END_LIST << nl;
|
||||
// End row
|
||||
os << nl << token::END_LIST;
|
||||
}
|
||||
|
||||
// End matrix
|
||||
os << nl << token::END_LIST << nl;
|
||||
}
|
||||
|
||||
os.check(FUNCTION_NAME);
|
||||
|
@ -150,6 +150,9 @@ public:
|
||||
//- Resize the matrix preserving the elements
|
||||
inline void resize(const label m);
|
||||
|
||||
//- Resize the matrix \em without preserving existing content
|
||||
inline void resize_nocopy(const label n);
|
||||
|
||||
//- Resize the matrix preserving the elements (compatibility)
|
||||
inline void resize(const label m, const label n);
|
||||
|
||||
|
@ -218,6 +218,13 @@ inline void Foam::SquareMatrix<Type>::resize(const label m)
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
inline void Foam::SquareMatrix<Type>::resize_nocopy(const label m)
|
||||
{
|
||||
Matrix<SquareMatrix<Type>, Type>::resize_nocopy(m, m);
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
inline void Foam::SquareMatrix<Type>::resize(const label m, const label n)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
#-------------------------------*- makefile -*---------------------------------
|
||||
WM_VERSION = OPENFOAM=2306
|
||||
WM_VERSION = OPENFOAM=2307
|
||||
|
||||
AR = ar
|
||||
ARFLAGS = cr
|
||||
|
Loading…
Reference in New Issue
Block a user