ENH: add sync() for faceBitSet, faceBoolSet, pointBitSet (#1060)

- fix range checks
This commit is contained in:
Mark Olesen
2018-11-14 11:55:38 +01:00
parent c599810533
commit a072d18380
19 changed files with 402 additions and 144 deletions

View File

@ -190,34 +190,40 @@ void Foam::cellSet::updateMesh(const mapPolyMesh& morphMap)
void Foam::cellSet::distribute(const mapDistributePolyMesh& map)
{
boolList inSet(map.nOldCells());
labelHashSet& labels = *this;
const labelHashSet& labels = *this;
boolList contents(map.nOldCells(), false);
for (const label celli : labels)
{
inSet[celli] = true;
contents.set(celli);
}
map.distributeCellData(inSet);
map.distributeCellData(contents);
// The new length
const label len = contents.size();
// Count
label n = 0;
forAll(inSet, celli)
for (label i=0; i < len; ++i)
{
if (inSet[celli])
if (contents.test(i))
{
++n;
}
}
clear();
resize(n);
forAll(inSet, celli)
// Update labelHashSet
labels.clear();
labels.resize(2*n);
for (label i=0; i < len; ++i)
{
if (inSet[celli])
if (contents.test(i))
{
insert(celli);
labels.set(i);
}
}
}

View File

@ -276,9 +276,8 @@ void Foam::cellZoneSet::updateMesh(const mapPolyMesh& morphMap)
labelList newAddressing(addressing_.size());
label n = 0;
forAll(addressing_, i)
for (const label celli : addressing_)
{
label celli = addressing_[i];
label newCelli = morphMap.reverseCellMap()[celli];
if (newCelli >= 0)
{
@ -286,7 +285,7 @@ void Foam::cellZoneSet::updateMesh(const mapPolyMesh& morphMap)
++n;
}
}
newAddressing.setSize(n);
newAddressing.resize(n);
addressing_.transfer(newAddressing);

View File

@ -25,6 +25,9 @@ License
#include "faceBitSet.H"
#include "polyMesh.H"
#include "mapPolyMesh.H"
#include "syncTools.H"
#include "mapDistributePolyMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -70,12 +73,37 @@ Foam::faceBitSet::faceBitSet
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faceBitSet::sync(const polyMesh& mesh)
{
syncTools::syncFaceList(mesh, selected_, orEqOp<unsigned int>());
}
Foam::label Foam::faceBitSet::maxSize(const polyMesh& mesh) const
{
return mesh.nFaces();
}
void Foam::faceBitSet::updateMesh(const mapPolyMesh& morphMap)
{
updateLabels(morphMap.reverseFaceMap());
}
void Foam::faceBitSet::distribute(const mapDistributePolyMesh& map)
{
bitSet& labels = selected_;
boolList contents(labels.values());
map.distributeFaceData(contents);
// The new length is contents.size();
labels.assign(contents);
}
void Foam::faceBitSet::writeDebug
(
Ostream& os,

View File

@ -79,19 +79,16 @@ public:
// Member Functions
//- Sync faceBitSet across coupled patches.
virtual void sync(const polyMesh& mesh)
{}
virtual void sync(const polyMesh& mesh);
//- Return max index+1.
virtual label maxSize(const polyMesh& mesh) const;
//- Update any stored data for new labels.
virtual void updateMesh(const mapPolyMesh& morphMap)
{}
virtual void updateMesh(const mapPolyMesh& morphMap);
//- Update any stored data for mesh redistribution.
virtual void distribute(const mapDistributePolyMesh& map)
{}
virtual void distribute(const mapDistributePolyMesh& map);
//- Write maxLen items with label and coordinates.
virtual void writeDebug

View File

@ -25,7 +25,9 @@ License
#include "faceBoolSet.H"
#include "polyMesh.H"
#include "Time.H"
#include "mapPolyMesh.H"
#include "syncTools.H"
#include "mapDistributePolyMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -71,12 +73,30 @@ Foam::faceBoolSet::faceBoolSet
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::faceBoolSet::sync(const polyMesh& mesh)
{
syncTools::syncFaceList(mesh, selected_, orEqOp<bool>());
}
Foam::label Foam::faceBoolSet::maxSize(const polyMesh& mesh) const
{
return mesh.nFaces();
}
void Foam::faceBoolSet::updateMesh(const mapPolyMesh& morphMap)
{
updateLabels(morphMap.reverseFaceMap());
}
void Foam::faceBoolSet::distribute(const mapDistributePolyMesh& map)
{
map.distributeFaceData(selected_);
}
void Foam::faceBoolSet::writeDebug
(
Ostream& os,

View File

@ -79,19 +79,16 @@ public:
// Member Functions
//- Sync faceBoolSet across coupled patches.
virtual void sync(const polyMesh& mesh)
{}
virtual void sync(const polyMesh& mesh);
//- Return max index+1.
virtual label maxSize(const polyMesh& mesh) const;
//- Update any stored data for new labels.
virtual void updateMesh(const mapPolyMesh& morphMap)
{}
virtual void updateMesh(const mapPolyMesh& morphMap);
//- Update any stored data for mesh redistribution.
virtual void distribute(const mapDistributePolyMesh& map)
{}
virtual void distribute(const mapDistributePolyMesh& map);
//- Write maxLen items with label and coordinates.
virtual void writeDebug

View File

@ -24,8 +24,8 @@ License
\*---------------------------------------------------------------------------*/
#include "faceSet.H"
#include "mapPolyMesh.H"
#include "polyMesh.H"
#include "mapPolyMesh.H"
#include "syncTools.H"
#include "mapDistributePolyMesh.H"
#include "addToRunTimeSelectionTable.H"
@ -126,42 +126,31 @@ Foam::faceSet::faceSet
void Foam::faceSet::sync(const polyMesh& mesh)
{
boolList set(mesh.nFaces(), false);
labelHashSet& labels = *this;
const labelHashSet& labels = *this;
// Convert to boolList
// TBD: could change to using bitSet for the synchronization
const label len = mesh.nFaces();
boolList contents(len, false);
for (const label facei : labels)
{
set[facei] = true;
contents.set(facei);
}
syncTools::syncFaceList(mesh, set, orEqOp<bool>());
syncTools::syncFaceList(mesh, contents, orEqOp<bool>());
label nAdded = 0;
forAll(set, facei)
// Update labelHashSet
for (label i=0; i < len; ++i)
{
if (set[facei])
if (contents.test(i))
{
if (this->set(facei))
{
++nAdded;
}
labels.set(i);
}
else if (found(facei))
{
FatalErrorInFunction
<< "Problem : syncing removed faces from set."
<< abort(FatalError);
}
}
reduce(nAdded, sumOp<label>());
if (debug && nAdded > 0)
{
Info<< "Added an additional " << nAdded
<< " faces on coupled patches. "
<< "(processorPolyPatch, cyclicPolyPatch)" << endl;
}
}
@ -180,34 +169,40 @@ void Foam::faceSet::updateMesh(const mapPolyMesh& morphMap)
void Foam::faceSet::distribute(const mapDistributePolyMesh& map)
{
boolList inSet(map.nOldFaces());
labelHashSet& labels = *this;
const labelHashSet& labels = *this;
boolList contents(map.nOldFaces(), false);
for (const label facei : labels)
{
inSet[facei] = true;
contents.set(facei);
}
map.distributeFaceData(inSet);
map.distributeFaceData(contents);
// Count
// The new length
const label len = contents.size();
// Count - as per BitOps::count(contents)
label n = 0;
forAll(inSet, facei)
for (label i=0; i < len; ++i)
{
if (inSet[facei])
if (contents.test(i))
{
++n;
}
}
clear();
resize(n);
forAll(inSet, facei)
// Update labelHashSet
labels.clear();
labels.resize(2*n);
for (label i=0; i < len; ++i)
{
if (inSet[facei])
if (contents.test(i))
{
this->set(facei);
labels.set(i);
}
}
}

View File

@ -497,7 +497,7 @@ void Foam::faceZoneSet::updateMesh(const mapPolyMesh& morphMap)
{
// faceZone
labelList newAddressing(addressing_.size());
boolList newFlipMap(flipMap_.size());
boolList newFlipMap(flipMap_.size(), false);
label n = 0;
forAll(addressing_, i)

View File

@ -25,6 +25,9 @@ License
#include "pointBitSet.H"
#include "polyMesh.H"
#include "mapPolyMesh.H"
#include "syncTools.H"
#include "mapDistributePolyMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -70,12 +73,38 @@ Foam::pointBitSet::pointBitSet
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::pointBitSet::sync(const polyMesh& mesh)
{
// The nullValue = '0u'
syncTools::syncPointList(mesh, selected_, orEqOp<unsigned int>(), 0u);
}
Foam::label Foam::pointBitSet::maxSize(const polyMesh& mesh) const
{
return mesh.nPoints();
}
void Foam::pointBitSet::updateMesh(const mapPolyMesh& morphMap)
{
updateLabels(morphMap.reversePointMap());
}
void Foam::pointBitSet::distribute(const mapDistributePolyMesh& map)
{
bitSet& labels = selected_;
boolList contents(labels.values());
map.distributePointData(contents);
// The new length is contents.size();
labels.assign(contents);
}
void Foam::pointBitSet::writeDebug
(
Ostream& os,

View File

@ -79,19 +79,16 @@ public:
// Member Functions
//- Sync pointBitSet across coupled patches.
virtual void sync(const polyMesh& mesh)
{}
virtual void sync(const polyMesh& mesh);
//- Return max index+1.
virtual label maxSize(const polyMesh& mesh) const;
//- Update any stored data for new labels.
virtual void updateMesh(const mapPolyMesh& morphMap)
{}
virtual void updateMesh(const mapPolyMesh& morphMap);
//- Update any stored data for mesh redistribution.
virtual void distribute(const mapDistributePolyMesh& map)
{}
virtual void distribute(const mapDistributePolyMesh& map);
//- Write maxLen items with label and coordinates.
virtual void writeDebug

View File

@ -126,38 +126,33 @@ Foam::pointSet::pointSet
void Foam::pointSet::sync(const polyMesh& mesh)
{
labelHashSet& labels = *this;
// Convert to boolList
// TBD: could change to using bitSet for the synchronization
boolList contents(mesh.nPoints(), false);
const label len = mesh.nPoints();
const labelHashSet& labels = *this;
boolList contents(len, false);
for (const label pointi : labels)
{
contents[pointi] = true;
contents.set(pointi);
}
syncTools::syncPointList
(
mesh,
contents,
orEqOp<bool>(),
false // null value
);
// The nullValue = 'false'
syncTools::syncPointList(mesh, contents, orEqOp<bool>(), false);
// Convert back to labelHashSet
labelHashSet newContents(size());
// Update labelHashSet
forAll(contents, pointi)
for (label pointi=0; pointi < len; ++pointi)
{
if (contents[pointi])
if (contents.test(pointi))
{
newContents.set(pointi);
labels.set(pointi);
}
}
transfer(newContents);
}
@ -175,34 +170,41 @@ void Foam::pointSet::updateMesh(const mapPolyMesh& morphMap)
void Foam::pointSet::distribute(const mapDistributePolyMesh& map)
{
boolList inSet(map.nOldPoints());
labelHashSet& labels = *this;
const labelHashSet& labels = *this;
boolList contents(map.nOldPoints(), false);
for (const label pointi : labels)
{
inSet[pointi] = true;
contents.set(pointi);
}
map.distributePointData(inSet);
map.distributePointData(contents);
// Count
// The new length
const label len = contents.size();
// Count - as per BitOps::count(contents)
label n = 0;
forAll(inSet, pointi)
for (label i=0; i < len; ++i)
{
if (inSet[pointi])
if (contents.test(i))
{
++n;
}
}
clear();
resize(n);
forAll(inSet, pointi)
// Update labelHashSet
labels.clear();
labels.resize(2*n);
for (label i=0; i < len; ++i)
{
if (inSet[pointi])
if (contents.test(i))
{
this->set(pointi);
labels.set(i);
}
}
}
@ -218,4 +220,5 @@ void Foam::pointSet::writeDebug
topoSet::writeDebug(os, mesh.points(), maxLen);
}
// ************************************************************************* //

View File

@ -131,9 +131,6 @@ public:
//- Update any stored data for new labels
virtual void updateMesh(const mapPolyMesh& morphMap);
//- Update any stored data for new labels
//virtual void updateMesh(const polyTopoChange& meshMod);
//- Update any stored data for mesh redistribution.
virtual void distribute(const mapDistributePolyMesh&);

View File

@ -276,17 +276,16 @@ void Foam::pointZoneSet::updateMesh(const mapPolyMesh& morphMap)
labelList newAddressing(addressing_.size());
label n = 0;
forAll(addressing_, i)
for (const label pointi : addressing_)
{
label pointi = addressing_[i];
label newPointi = morphMap.reversePointMap()[pointi];
const label newPointi = morphMap.reversePointMap()[pointi];
if (newPointi >= 0)
{
newAddressing[n] = newPointi;
++n;
}
}
newAddressing.setSize(n);
newAddressing.resize(n);
addressing_.transfer(newAddressing);

View File

@ -27,6 +27,84 @@ License
#include "polyMesh.H"
#include "Time.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// Update stored cell numbers using map.
// Do in two passes to prevent allocation if nothing changed.
void Foam::topoBitSet::updateLabels(const labelUList& map)
{
bitSet& labels = selected_;
{
const label oldId = labels.find_last();
if (oldId >= map.size())
{
FatalErrorInFunction
<< "Illegal content " << oldId << " of set:" << name()
<< " of type " << type() << nl
<< "Value should be between [0," << map.size() << ')'
<< endl
<< abort(FatalError);
}
}
// Iterate over map to see if anything changed
bool changed = false;
for (const label oldId : labels)
{
const label newId = map[oldId];
if (newId != oldId)
{
changed = true;
break;
}
}
if (!changed)
{
return;
}
// Relabel. Use second bitSet to prevent overlapping.
// The new length is given by the map
const label len = map.size();
bitSet newLabels(len);
for (const label oldId : labels)
{
const label newId = map[oldId];
newLabels.set(newId); // Ignores -ve indices
}
labels.transfer(newLabels);
}
void Foam::topoBitSet::check(const label maxSize)
{
const bitSet& labels = selected_;
const label oldId = labels.find_last();
if (oldId >= maxSize)
{
FatalErrorInFunction
<< "Illegal content " << oldId << " of set:" << name()
<< " of type " << type() << nl
<< "Value should be between [0," << maxSize << ')'
<< endl
<< abort(FatalError);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::topoBitSet::topoBitSet

View File

@ -60,6 +60,14 @@ protected:
// Protected Member Functions
//- Update map from map.
// Used to update cell/face labels after morphing
virtual void updateLabels(const labelUList& map);
//- Check limits on addressable range.
virtual void check(const label maxSize);
//- Construct with empty selection
topoBitSet(const polyMesh& mesh, const word& setName);

View File

@ -27,6 +27,93 @@ License
#include "polyMesh.H"
#include "Time.H"
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
// Update stored cell numbers using map.
// Do in two passes to prevent allocation if nothing changed.
void Foam::topoBoolSet::updateLabels(const labelUList& map)
{
boolList& labels = selected_;
// Iterate over map to see if anything changed
// Must iterate over ALL elements, to properly trap bounds errors
bool changed = false;
forAll(labels, oldId)
{
if (!labels.test(oldId))
{
continue;
}
if (oldId >= map.size())
{
FatalErrorInFunction
<< "Illegal content " << oldId << " of set:" << name()
<< " of type " << type() << nl
<< "Value should be between [0," << map.size() << ')'
<< endl
<< abort(FatalError);
}
const label newId = map[oldId];
if (newId != oldId)
{
changed = true;
#ifdef FULLDEBUG
continue; // Check all elements in FULLDEBUG mode
#endif
break;
}
}
if (!changed)
{
return;
}
// Relabel. Use second boolList to prevent overlapping.
// The new length is given by the map
const label len = map.size();
boolList newLabels(len, false);
forAll(labels, oldId)
{
const label newId = map[oldId];
if (newId >= 0)
{
newLabels.set(newId); // Ignores -ve indices
}
}
labels.transfer(newLabels);
}
void Foam::topoBoolSet::check(const label maxSize)
{
const boolList& labels = selected_;
const label oldId = labels.rfind(true);
if (oldId >= maxSize)
{
FatalErrorInFunction
<< "Illegal content " << oldId << " of set:" << name()
<< " of type " << type() << nl
<< "Value should be between [0," << maxSize << ')'
<< endl
<< abort(FatalError);
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::topoBoolSet::topoBoolSet

View File

@ -60,6 +60,14 @@ protected:
// Protected Member Functions
//- Update map from map.
// Used to update cell/face labels after morphing
virtual void updateLabels(const labelUList& map);
//- Check limits on addressable range.
virtual void check(const label maxSize);
//- Construct with empty selection
topoBoolSet(const polyMesh& mesh, const word& setName);

View File

@ -45,7 +45,7 @@ namespace Foam
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::topoSet> Foam::topoSet::New
(
@ -122,6 +122,8 @@ Foam::autoPtr<Foam::topoSet> Foam::topoSet::New
}
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::fileName Foam::topoSet::localPath
(
const polyMesh& mesh,
@ -136,21 +138,23 @@ Foam::fileName Foam::topoSet::localPath
// Update stored cell numbers using map.
// Do in two passes to prevent allocation if nothing changed.
void Foam::topoSet::updateLabels(const labelList& map)
void Foam::topoSet::updateLabels(const labelUList& map)
{
// Iterate over map to see if anything changed
bool changed = false;
labelHashSet& labels = *this;
const labelHashSet& labels = *this;
// Iterate over map to see if anything changed
bool changed = false;
for (const label oldId : labels)
{
if (oldId < 0 || oldId > map.size())
if (oldId < 0 || oldId >= map.size())
{
FatalErrorInFunction
<< "Illegal content " << oldId << " of set:" << name()
<< " of type " << type() << endl
<< " of type " << type() << nl
<< "Value should be between [0," << map.size() << ')'
<< endl
<< abort(FatalError);
}
@ -159,42 +163,50 @@ void Foam::topoSet::updateLabels(const labelList& map)
if (newId != oldId)
{
changed = true;
#ifdef FULLDEBUG
continue; // Check all elements in FULLDEBUG mode
#endif
break;
}
}
// Relabel (use second Map to prevent overlapping)
if (changed)
if (!changed)
{
labelHashSet newSet(2*size());
for (const label oldId : labels)
{
const label newId = map[oldId];
if (newId >= 0)
{
newSet.set(newId);
}
}
transfer(newSet);
return;
}
// Relabel. Use second labelHashSet to prevent overlapping.
labelHashSet newLabels(2*labels.size());
for (const label oldId : labels)
{
const label newId = map[oldId];
if (newId >= 0)
{
newLabels.set(newId);
}
}
labels.transfer(newLabels);
}
void Foam::topoSet::check(const label maxLabel)
void Foam::topoSet::check(const label maxSize)
{
const labelHashSet& labels = *this;
for (const label oldId : labels)
{
if (oldId < 0 || oldId > maxLabel)
if (oldId < 0 || oldId >= maxSize)
{
FatalErrorInFunction
<< "Illegal content " << oldId << " of set:" << name()
<< " of type " << type() << nl
<< "Value should be between [0," << maxLabel << ']'
<< "Value should be between [0," << maxSize << ')'
<< endl
<< abort(FatalError);
}
}

View File

@ -70,12 +70,12 @@ protected:
// Protected Member Functions
//- Update map from map. Used to update cell/face labels
// after morphing
void updateLabels(const labelList& map);
//- Update map from map.
// Used to update cell/face labels after morphing
virtual void updateLabels(const labelUList& map);
//- Check validity of contents.
void check(const label maxLabel);
//- Check limits on addressable range.
virtual void check(const label maxSize);
//- Write part of contents nicely formatted. Prints labels only.
void writeDebug
@ -106,12 +106,6 @@ protected:
) const;
//- No copy construct
topoSet(const topoSet&) = delete;
protected:
//- Helper for constructor - return IOobject in the polyMesh/sets
static IOobject findIOobject
(
@ -131,6 +125,10 @@ protected:
);
//- No copy construct
topoSet(const topoSet&) = delete;
public:
//- Runtime type information