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

View File

@ -65,16 +65,19 @@ void Foam::meshDualiser::checkPolyTopoChange(const polyTopoChange& meshMod)
if (nUnique < points.size()) 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 FatalErrorInFunction
<< "duplicate verts:" << newToOld[newI] << "duplicate verts:" << newToOld[newi]
<< " coords:" << " coords:"
<< UIndirectList<point>(points, newToOld[newI]) << UIndirectList<point>(points, newToOld[newi])
<< abort(FatalError); << abort(FatalError);
} }
} }

View File

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

View File

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

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "ListOps.H" #include "ListOps.H"
#include "CompactListList.H"
#include "HashSet.H" #include "HashSet.H"
#include <numeric> #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 Foam::bitSet Foam::reorder
( (
const labelUList& oldToNew, const labelUList& oldToNew,

View File

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