ENH: use SubList for CompactListList access

- this was previously a UList instead of SubList,
  but SubList supports better assignment of values

ENH: add invertOneToManyCompact

- returns a CompactListList<label> instead of labelListList, which
  allows for reuse as partitioning table etc and/or slightly reduced
  memory overhead
This commit is contained in:
Mark Olesen 2024-03-05 09:22:27 +01:00
parent 78fc102df1
commit 5a70be0846
6 changed files with 111 additions and 54 deletions

View File

@ -70,7 +70,10 @@ int main(int argc, char *argv[])
);
labelList cellToCoarse(identity(mesh.nCells()));
labelListList coarseToCell(invertOneToMany(mesh.nCells(), cellToCoarse));
CompactListList<label> coarseToCell
(
invertOneToManyCompact(mesh.nCells(), cellToCoarse)
);
++runTime;
@ -78,16 +81,11 @@ int main(int argc, char *argv[])
{
volScalarField scalarAgglomeration
(
IOobject
(
"agglomeration",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh.thisDb().newIOobject("agglomeration"),
mesh,
dimensionedScalar(dimless, Zero)
Foam::zero{},
dimless,
fvPatchFieldBase::zeroGradientType()
);
scalarField& fld = scalarAgglomeration.primitiveFieldRef();
forAll(fld, celli)
@ -142,31 +140,23 @@ int main(int argc, char *argv[])
}
forAll(addr, fineI)
forAll(addr, finei)
{
const labelList& cellLabels = coarseToCell[fineI];
forAll(cellLabels, i)
{
cellToCoarse[cellLabels[i]] = addr[fineI];
}
labelUIndList(cellToCoarse, coarseToCell[finei]) = addr[finei];
}
coarseToCell = invertOneToMany(coarseSize, cellToCoarse);
coarseToCell = invertOneToManyCompact(coarseSize, cellToCoarse);
// Write agglomeration
{
volScalarField scalarAgglomeration
(
IOobject
(
"agglomeration",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh.thisDb().newIOobject("agglomeration"),
mesh,
dimensionedScalar(dimless, Zero)
Foam::zero{},
dimless,
fvPatchFieldBase::zeroGradientType()
);
scalarField& fld = scalarAgglomeration.primitiveFieldRef();
forAll(fld, celli)
{
@ -193,9 +183,9 @@ int main(int argc, char *argv[])
}
// Determine coarse cc
forAll(coarseToCell, coarseI)
forAll(coarseToCell, coarsei)
{
const labelList& cellLabels = coarseToCell[coarseI];
const auto& cellLabels = coarseToCell[coarsei];
point coarseCc = average
(
@ -204,10 +194,8 @@ int main(int argc, char *argv[])
meshTools::writeOBJ(str, coarseCc);
vertI++;
forAll(cellLabels, i)
for (label celli : cellLabels)
{
label celli = cellLabels[i];
str << "l " << celli+1 << ' ' << vertI << nl;
}
}

View File

@ -65,16 +65,19 @@ void Foam::meshDualiser::checkPolyTopoChange(const polyTopoChange& meshMod)
if (nUnique < points.size())
{
labelListList newToOld(invertOneToMany(nUnique, oldToNew));
CompactListList<label> newToOld
(
invertOneToManyCompact(nUnique, oldToNew)
);
forAll(newToOld, newI)
forAll(newToOld, newi)
{
if (newToOld[newI].size() != 1)
if (newToOld[newi].size() != 1)
{
FatalErrorInFunction
<< "duplicate verts:" << newToOld[newI]
<< "duplicate verts:" << newToOld[newi]
<< " coords:"
<< UIndirectList<point>(points, newToOld[newI])
<< UIndirectList<point>(points, newToOld[newi])
<< abort(FatalError);
}
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -63,6 +63,11 @@ template<class T> class CompactListList;
template<class T> Istream& operator>>(Istream&, CompactListList<T>&);
template<class T> Ostream& operator<<(Ostream&, const CompactListList<T>&);
// Common list types
//! A CompactListList of labels
typedef CompactListList<label> labelCompactListList;
/*---------------------------------------------------------------------------*\
Class CompactListList Declaration
@ -422,17 +427,17 @@ public:
// Row-based access
//- Return const access to sub-list (no subscript checking)
inline const SubList<T> localList(const label i) const;
//- Return non-const access to sub-list (no subscript checking)
inline UList<T> localList(const label i);
inline SubList<T> localList(const label i);
//- Return const access to sub-list (no subscript checking)
inline const UList<T> localList(const label i) const;
inline const SubList<T> operator[](const label i) const;
//- Return row as UList - same as localList method
inline UList<T> operator[](const label i);
//- Return row as const UList - same as localList method
inline const UList<T> operator[](const label i) const;
//- Return non-const access to sub-list (no subscript checking)
inline SubList<T> operator[](const label i);
// Element access

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2024 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -81,7 +81,6 @@ inline Foam::CompactListList<T>::CompactListList
{}
template<class T>
inline Foam::CompactListList<T>::CompactListList
(
@ -259,16 +258,16 @@ inline Foam::label Foam::CompactListList<T>::localSize(const label i) const
template<class T>
inline Foam::UList<T>
Foam::CompactListList<T>::localList(const label i)
inline const Foam::SubList<T>
Foam::CompactListList<T>::localList(const label i) const
{
return SubList<T>(values_, (offsets_[i+1] - offsets_[i]), offsets_[i]);
}
template<class T>
inline const Foam::UList<T>
Foam::CompactListList<T>::localList(const label i) const
inline Foam::SubList<T>
Foam::CompactListList<T>::localList(const label i)
{
return SubList<T>(values_, (offsets_[i+1] - offsets_[i]), offsets_[i]);
}
@ -476,17 +475,19 @@ inline void Foam::CompactListList<T>::operator=(const Foam::zero)
template<class T>
inline Foam::UList<T>
Foam::CompactListList<T>::operator[](const label i)
inline const Foam::SubList<T>
Foam::CompactListList<T>::operator[](const label i) const
{
// return SubList<T>(values_, (offsets_[i+1] - offsets_[i]), offsets_[i]);
return this->localList(i);
}
template<class T>
inline const Foam::UList<T>
Foam::CompactListList<T>::operator[](const label i) const
inline Foam::SubList<T>
Foam::CompactListList<T>::operator[](const label i)
{
// return SubList<T>(values_, (offsets_[i+1] - offsets_[i]), offsets_[i]);
return this->localList(i);
}

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "ListOps.H"
#include "CompactListList.H"
#include "HashSet.H"
#include <numeric>
@ -177,6 +178,54 @@ Foam::labelListList Foam::invertOneToMany
}
Foam::CompactListList<Foam::label>
Foam::invertOneToManyCompact
(
const label len,
const labelUList& map
)
{
labelList sizes(len, Foam::zero{});
for (const label newIdx : map)
{
if (newIdx >= 0)
{
#ifdef FULLDEBUG
if (newIdx >= len)
{
FatalErrorInFunction
<< "Inverse location " << newIdx
<< " is out of range. List has size " << len
<< abort(FatalError);
}
#endif
++sizes[newIdx];
}
}
CompactListList<label> inverse(sizes);
// Reuse sizes as output offset into inverse.values()
sizes = labelList::subList(inverse.offsets(), inverse.size());
labelList& values = inverse.values();
label i = 0;
for (const label newIdx : map)
{
if (newIdx >= 0)
{
values[sizes[newIdx]++] = i;
}
++i;
}
return inverse;
}
Foam::bitSet Foam::reorder
(
const labelUList& oldToNew,

View File

@ -59,6 +59,10 @@ SourceFiles
namespace Foam
{
// Forward Declarations
template<class T> class CompactListList;
//- Renumber the values within a list.
// Negative input values are left untouched.
template<class IntListType>
@ -378,6 +382,13 @@ Map<label> invertToMap(const labelUList& values);
//- Invert one-to-many map. Unmapped elements will be size 0.
labelListList invertOneToMany(const label len, const labelUList& map);
//- Invert one-to-many compact map. Unmapped elements will be size 0.
CompactListList<label> invertOneToManyCompact
(
const label len,
const labelUList& map
);
//- Invert many-to-many.
// Input and output types must be inherited from List and also
// contain ints/labels. Used, for example, for faces to pointFaces.