mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: new bitSet class and improved PackedList class (closes #751)
- The bitSet class replaces the old PackedBoolList class.
The redesign provides better block-wise access and reduced method
calls. This helps both in cases where the bitSet may be relatively
sparse, and in cases where advantage of contiguous operations can be
made. This makes it easier to work with a bitSet as top-level object.
In addition to the previously available count() method to determine
if a bitSet is being used, now have simpler queries:
- all() - true if all bits in the addressable range are empty
- any() - true if any bits are set at all.
- none() - true if no bits are set.
These are faster than count() and allow early termination.
The new test() method tests the value of a single bit position and
returns a bool without any ambiguity caused by the return type
(like the get() method), nor the const/non-const access (like
operator[] has). The name corresponds to what std::bitset uses.
The new find_first(), find_last(), find_next() methods provide a faster
means of searching for bits that are set.
This can be especially useful when using a bitSet to control an
conditional:
OLD (with macro):
forAll(selected, celli)
{
if (selected[celli])
{
sumVol += mesh_.cellVolumes()[celli];
}
}
NEW (with const_iterator):
for (const label celli : selected)
{
sumVol += mesh_.cellVolumes()[celli];
}
or manually
for
(
label celli = selected.find_first();
celli != -1;
celli = selected.find_next()
)
{
sumVol += mesh_.cellVolumes()[celli];
}
- When marking up contiguous parts of a bitset, an interval can be
represented more efficiently as a labelRange of start/size.
For example,
OLD:
if (isA<processorPolyPatch>(pp))
{
forAll(pp, i)
{
ignoreFaces.set(i);
}
}
NEW:
if (isA<processorPolyPatch>(pp))
{
ignoreFaces.set(pp.range());
}
This commit is contained in:
@ -25,7 +25,7 @@ License
|
||||
|
||||
#include "AABBTree.H"
|
||||
#include "meshTools.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
//#include "OFstream.H"
|
||||
|
||||
template<class Type>
|
||||
@ -157,7 +157,7 @@ void Foam::AABBTree<Type>::createBoxes
|
||||
{
|
||||
// Pick up points used by this set of objects
|
||||
|
||||
PackedBoolList isUsedPoint(points.size());
|
||||
bitSet isUsedPoint(points.size());
|
||||
DynamicList<scalar> component(points.size());
|
||||
|
||||
for (const label objI : objectIDs)
|
||||
|
||||
@ -47,7 +47,7 @@ SourceFiles
|
||||
#ifndef FaceCellWave_H
|
||||
#define FaceCellWave_H
|
||||
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "DynamicList.H"
|
||||
#include "primitiveFieldsFwd.H"
|
||||
#include "labelPair.H"
|
||||
@ -106,13 +106,13 @@ protected:
|
||||
TrackingData& td_;
|
||||
|
||||
//- Has face changed
|
||||
PackedBoolList changedFace_;
|
||||
bitSet changedFace_;
|
||||
|
||||
//- List of changed faces
|
||||
DynamicList<label> changedFaces_;
|
||||
|
||||
//- Has cell changed
|
||||
PackedBoolList changedCell_;
|
||||
bitSet changedCell_;
|
||||
|
||||
// Cells that have changed
|
||||
DynamicList<label> changedCells_;
|
||||
|
||||
@ -170,7 +170,7 @@ syncEdges()
|
||||
{
|
||||
const globalMeshData& globalData = mesh_.globalData();
|
||||
const mapDistribute& map = globalData.globalEdgeSlavesMap();
|
||||
const PackedBoolList& cppOrientation = globalData.globalEdgeOrientation();
|
||||
const bitSet& cppOrientation = globalData.globalEdgeOrientation();
|
||||
|
||||
// Convert patch-edge data into cpp-edge data
|
||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@ -37,8 +37,8 @@ SourceFiles
|
||||
#ifndef PatchEdgeFaceWave_H
|
||||
#define PatchEdgeFaceWave_H
|
||||
|
||||
#include "bitSet.H"
|
||||
#include "scalarField.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "PrimitivePatch.H"
|
||||
#include "vectorTensorTransform.H"
|
||||
|
||||
@ -101,13 +101,13 @@ class PatchEdgeFaceWave
|
||||
TrackingData& td_;
|
||||
|
||||
//- Has edge changed
|
||||
PackedBoolList changedEdge_;
|
||||
bitSet changedEdge_;
|
||||
|
||||
//- List of changed edges
|
||||
DynamicList<label> changedEdges_;
|
||||
|
||||
//- Has face changed
|
||||
PackedBoolList changedFace_;
|
||||
bitSet changedFace_;
|
||||
|
||||
//- List of changed faces
|
||||
DynamicList<label> changedFaces_;
|
||||
@ -123,7 +123,7 @@ class PatchEdgeFaceWave
|
||||
// Addressing between edges of patch_ and globalData.coupledPatch()
|
||||
labelList patchEdges_;
|
||||
labelList coupledEdges_;
|
||||
PackedBoolList sameEdgeOrientation_;
|
||||
bitSet sameEdgeOrientation_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
@ -58,7 +58,7 @@ SourceFiles
|
||||
#ifndef PointEdgeWave_H
|
||||
#define PointEdgeWave_H
|
||||
|
||||
#include "boolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "scalarField.H"
|
||||
#include "tensorField.H"
|
||||
|
||||
@ -114,7 +114,7 @@ class PointEdgeWave
|
||||
TrackingData& td_;
|
||||
|
||||
//- Has point changed
|
||||
boolList changedPoint_;
|
||||
bitSet changedPoint_;
|
||||
|
||||
//- List of changed points
|
||||
labelList changedPoints_;
|
||||
@ -123,7 +123,8 @@ class PointEdgeWave
|
||||
label nChangedPoints_;
|
||||
|
||||
//- Edges that have changed
|
||||
boolList changedEdge_;
|
||||
bitSet changedEdge_;
|
||||
|
||||
labelList changedEdges_;
|
||||
label nChangedEdges_;
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ License
|
||||
#include "addToMemberFunctionSelectionTable.H"
|
||||
#include "ListOps.H"
|
||||
#include "edgeHashes.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
@ -237,7 +237,7 @@ void Foam::edgeMesh::mergePoints(const scalar mergeDist)
|
||||
void Foam::edgeMesh::mergeEdges()
|
||||
{
|
||||
edgeHashSet uniqEdges(2*edges_.size());
|
||||
PackedBoolList pointIsUsed(points_.size());
|
||||
bitSet pointIsUsed(points_.size());
|
||||
|
||||
label nUniqEdges = 0;
|
||||
label nUniqPoints = 0;
|
||||
|
||||
@ -26,7 +26,7 @@ License
|
||||
#include "NASedgeFormat.H"
|
||||
#include "IFstream.H"
|
||||
#include "StringStream.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
@ -173,7 +173,7 @@ bool Foam::fileFormats::NASedgeFormat::read
|
||||
}
|
||||
|
||||
// note which points were really used and which can be culled
|
||||
PackedBoolList usedPoints(points().size());
|
||||
bitSet usedPoints(points().size());
|
||||
|
||||
|
||||
// Pass1: relabel edges
|
||||
@ -189,29 +189,25 @@ bool Foam::fileFormats::NASedgeFormat::read
|
||||
pointId.clearStorage();
|
||||
mapPointId.clear();
|
||||
|
||||
// Not all the points were used, cull them accordingly
|
||||
if (unsigned(points().size()) != usedPoints.count())
|
||||
// Not all points were used, subset/cull them accordingly
|
||||
if (!usedPoints.all())
|
||||
{
|
||||
label nUsed = 0;
|
||||
|
||||
pointField& pts = storedPoints();
|
||||
forAll(pts, pointi)
|
||||
for (const label pointi : usedPoints)
|
||||
{
|
||||
if (usedPoints.test(pointi))
|
||||
if (nUsed != pointi)
|
||||
{
|
||||
if (nUsed != pointi)
|
||||
{
|
||||
pts[nUsed] = pts[pointi];
|
||||
}
|
||||
|
||||
// map prev -> new id
|
||||
mapPointId[pointi] = nUsed;
|
||||
|
||||
++nUsed;
|
||||
pts[nUsed] = pts[pointi];
|
||||
}
|
||||
}
|
||||
|
||||
pts.setSize(nUsed);
|
||||
// map prev -> new id
|
||||
mapPointId.set(pointi, nUsed);
|
||||
|
||||
++nUsed;
|
||||
}
|
||||
pts.resize(nUsed);
|
||||
|
||||
// Renumber edge vertices
|
||||
for (edge& e : dynEdges)
|
||||
@ -221,8 +217,6 @@ bool Foam::fileFormats::NASedgeFormat::read
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// transfer to normal lists
|
||||
storedEdges().transfer(dynEdges);
|
||||
|
||||
return true;
|
||||
|
||||
@ -26,7 +26,7 @@ License
|
||||
#include "STARCDedgeFormat.H"
|
||||
#include "ListOps.H"
|
||||
#include "clock.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "StringStream.H"
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
@ -132,7 +132,7 @@ bool Foam::fileFormats::STARCDedgeFormat::read
|
||||
pointId.clear();
|
||||
|
||||
// note which points were really used and which can be culled
|
||||
PackedBoolList usedPoints(points().size());
|
||||
bitSet usedPoints(points().size());
|
||||
|
||||
//
|
||||
// read .cel file
|
||||
@ -187,31 +187,27 @@ bool Foam::fileFormats::STARCDedgeFormat::read
|
||||
|
||||
mapPointId.clear();
|
||||
|
||||
// not all the points were used, cull them accordingly
|
||||
if (unsigned(points().size()) != usedPoints.count())
|
||||
// Not all points were used, subset/cull them accordingly
|
||||
if (!usedPoints.all())
|
||||
{
|
||||
label nUsed = 0;
|
||||
|
||||
pointField& pts = storedPoints();
|
||||
forAll(pts, pointi)
|
||||
for (const label pointi : usedPoints)
|
||||
{
|
||||
if (usedPoints.test(pointi))
|
||||
if (nUsed != pointi)
|
||||
{
|
||||
if (nUsed != pointi)
|
||||
{
|
||||
pts[nUsed] = pts[pointi];
|
||||
}
|
||||
|
||||
// map prev -> new id
|
||||
mapPointId.set(pointi, nUsed);
|
||||
|
||||
++nUsed;
|
||||
pts[nUsed] = pts[pointi];
|
||||
}
|
||||
|
||||
// map prev -> new id
|
||||
mapPointId.set(pointi, nUsed);
|
||||
|
||||
++nUsed;
|
||||
}
|
||||
pts.resize(nUsed);
|
||||
|
||||
pts.setSize(nUsed);
|
||||
|
||||
// renumber edge vertices
|
||||
// Renumber edge vertices
|
||||
forAll(dynEdges, edgeI)
|
||||
{
|
||||
edge& e = dynEdges[edgeI];
|
||||
@ -221,7 +217,6 @@ bool Foam::fileFormats::STARCDedgeFormat::read
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
storedEdges().transfer(dynEdges);
|
||||
|
||||
return true;
|
||||
|
||||
@ -1481,7 +1481,7 @@ void Foam::extendedEdgeMesh::autoMap
|
||||
// Compact region edges
|
||||
labelList subRegionEdges;
|
||||
{
|
||||
PackedBoolList isRegionEdge(edges().size(), regionEdges());
|
||||
bitSet isRegionEdge(edges().size(), regionEdges());
|
||||
|
||||
DynamicList<label> newRegionEdges(regionEdges().size());
|
||||
forAll(edgeMap, subEdgeI)
|
||||
@ -1525,7 +1525,7 @@ void Foam::extendedEdgeMesh::autoMap
|
||||
DynamicList<label> normalMap(normals().size());
|
||||
|
||||
{
|
||||
PackedBoolList isSubNormal(normals().size());
|
||||
bitSet isSubNormal(normals().size());
|
||||
for (label subPointI = 0; subPointI < subNonFeatStart; subPointI++)
|
||||
{
|
||||
label pointI = pointMap[subPointI];
|
||||
|
||||
@ -26,7 +26,7 @@ License
|
||||
#include "extendedEdgeMesh.H"
|
||||
#include "ListListOps.H"
|
||||
#include "unitConversion.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "PatchTools.H"
|
||||
#include "searchableBox.H"
|
||||
|
||||
@ -98,7 +98,7 @@ void Foam::extendedEdgeMesh::sortPointsAndEdges
|
||||
// All feature points have been added
|
||||
nonFeatureStart_ = tmpPts.size();
|
||||
|
||||
PackedBoolList isRegionFeatureEdge(regionFeatureEdges);
|
||||
bitSet isRegionFeatureEdge(regionFeatureEdges);
|
||||
|
||||
forAll(featureEdges, i)
|
||||
{
|
||||
|
||||
@ -26,7 +26,7 @@ License
|
||||
#include "extendedFeatureEdgeMesh.H"
|
||||
#include "ListListOps.H"
|
||||
#include "unitConversion.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "PatchTools.H"
|
||||
#include "searchableBox.H"
|
||||
|
||||
@ -98,7 +98,7 @@ void Foam::extendedFeatureEdgeMesh::sortPointsAndEdges
|
||||
// All feature points have been added
|
||||
nonFeatureStart_ = tmpPts.size();
|
||||
|
||||
PackedBoolList isRegionFeatureEdge(regionFeatureEdges);
|
||||
bitSet isRegionFeatureEdge(regionFeatureEdges);
|
||||
|
||||
forAll(featureEdges, i)
|
||||
{
|
||||
|
||||
@ -38,7 +38,7 @@ SourceFiles
|
||||
#include "face.H"
|
||||
#include "indexedOctree.H"
|
||||
#include "treeBoundBoxList.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "primitiveMesh.H"
|
||||
#include "volumeType.H"
|
||||
|
||||
@ -72,7 +72,7 @@ class treeDataFace
|
||||
const labelList faceLabels_;
|
||||
|
||||
//- Inverse of faceLabels. For every mesh whether face is in faceLabels.
|
||||
PackedBoolList isTreeFace_;
|
||||
bitSet isTreeFace_;
|
||||
|
||||
//- Whether to precalculate and store face bounding box
|
||||
const bool cacheBb_;
|
||||
|
||||
@ -716,7 +716,7 @@ void Foam::mappedPatchBase::calcMapping() const
|
||||
if (debug)
|
||||
{
|
||||
// Check that all elements get a value.
|
||||
PackedBoolList used(patch_.size());
|
||||
bitSet used(patch_.size());
|
||||
forAll(constructMap, proci)
|
||||
{
|
||||
const labelList& map = constructMap[proci];
|
||||
|
||||
@ -67,10 +67,10 @@ void Foam::regionSplit::calcNonCompactRegionSplit
|
||||
// Seed all faces on (real) boundaries and cell faces next to blockFace,
|
||||
// since regions can only occur because of boundaries (or blocked faces)
|
||||
|
||||
PackedBoolList isSeed(mesh().nFaces());
|
||||
bitSet isSeed(mesh().nFaces());
|
||||
|
||||
// Get internal or coupled faces
|
||||
PackedBoolList isConnection(syncTools::getInternalOrCoupledFaces(mesh()));
|
||||
bitSet isConnection(syncTools::getInternalOrCoupledFaces(mesh()));
|
||||
|
||||
// 1. Seed (real) boundaries
|
||||
for
|
||||
@ -145,7 +145,7 @@ void Foam::regionSplit::calcNonCompactRegionSplit
|
||||
}
|
||||
}
|
||||
|
||||
List<label> seedFaces(isSeed.used());
|
||||
List<label> seedFaces(isSeed.toc());
|
||||
List<minData> seedData(seedFaces.size());
|
||||
|
||||
// Seed face with globally unique number
|
||||
|
||||
@ -57,7 +57,7 @@ Foam::topoSetSource::addToUsageTable Foam::targetVolumeToCell::usage_
|
||||
|
||||
Foam::scalar Foam::targetVolumeToCell::volumeOfSet
|
||||
(
|
||||
const PackedBoolList& selected
|
||||
const bitSet& selected
|
||||
) const
|
||||
{
|
||||
scalar sumVol = 0.0;
|
||||
@ -76,8 +76,8 @@ Foam::scalar Foam::targetVolumeToCell::volumeOfSet
|
||||
Foam::label Foam::targetVolumeToCell::selectCells
|
||||
(
|
||||
const scalar normalComp,
|
||||
const PackedBoolList& maskSet,
|
||||
PackedBoolList& selected
|
||||
const bitSet& maskSet,
|
||||
bitSet& selected
|
||||
) const
|
||||
{
|
||||
selected.resize(mesh_.nCells());
|
||||
@ -89,7 +89,7 @@ Foam::label Foam::targetVolumeToCell::selectCells
|
||||
{
|
||||
const point& cc = mesh_.cellCentres()[celli];
|
||||
|
||||
if (maskSet[celli] && ((cc&n_) < normalComp))
|
||||
if (maskSet.test(celli) && ((cc&n_) < normalComp))
|
||||
{
|
||||
selected.set(celli);
|
||||
nSelected++;
|
||||
@ -108,7 +108,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
|
||||
}
|
||||
|
||||
|
||||
PackedBoolList maskSet(mesh_.nCells(), true);
|
||||
bitSet maskSet(mesh_.nCells(), true);
|
||||
label nTotCells = mesh_.globalData().nTotalCells();
|
||||
if (maskSetName_.size())
|
||||
{
|
||||
@ -157,7 +157,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
|
||||
}
|
||||
}
|
||||
|
||||
PackedBoolList maxSelected(mesh_.nCells());
|
||||
bitSet maxSelected(mesh_.nCells());
|
||||
maxCells = selectCells(maxComp, maskSet, maxSelected);
|
||||
//maxVol = volumeOfSet(maxSelected);
|
||||
|
||||
@ -177,7 +177,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
|
||||
// Bisection
|
||||
// ~~~~~~~~~
|
||||
|
||||
PackedBoolList selected(mesh_.nCells());
|
||||
bitSet selected(mesh_.nCells());
|
||||
label nSelected = -1;
|
||||
scalar selectedVol = 0.0;
|
||||
//scalar selectedComp = 0.0;
|
||||
@ -204,7 +204,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
|
||||
{
|
||||
low = mid;
|
||||
|
||||
PackedBoolList highSelected(mesh_.nCells());
|
||||
bitSet highSelected(mesh_.nCells());
|
||||
label nHigh = selectCells(high, maskSet, selected);
|
||||
if (nSelected == nHigh)
|
||||
{
|
||||
@ -215,7 +215,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
|
||||
{
|
||||
high = mid;
|
||||
|
||||
PackedBoolList lowSelected(mesh_.nCells());
|
||||
bitSet lowSelected(mesh_.nCells());
|
||||
label nLow = selectCells(low, maskSet, selected);
|
||||
if (nSelected == nLow)
|
||||
{
|
||||
@ -259,7 +259,7 @@ void Foam::targetVolumeToCell::combine(topoSet& set, const bool add) const
|
||||
|
||||
forAll(selected, celli)
|
||||
{
|
||||
if (selected[celli])
|
||||
if (selected.test(celli))
|
||||
{
|
||||
addOrDelete(set, celli, add);
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ SourceFiles
|
||||
#define targetVolumeToCell_H
|
||||
|
||||
#include "topoSetSource.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -70,13 +70,13 @@ class targetVolumeToCell
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
scalar volumeOfSet(const PackedBoolList&) const;
|
||||
scalar volumeOfSet(const bitSet&) const;
|
||||
|
||||
label selectCells
|
||||
(
|
||||
const scalar normalComp,
|
||||
const PackedBoolList&,
|
||||
PackedBoolList& selected
|
||||
const bitSet&,
|
||||
bitSet& selected
|
||||
) const;
|
||||
|
||||
void combine(topoSet& set, const bool add) const;
|
||||
|
||||
@ -37,7 +37,7 @@ SourceFiles
|
||||
#define regionToFace_H
|
||||
|
||||
#include "topoSetSource.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "indirectPrimitivePatch.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -383,7 +383,7 @@ void Foam::faceZoneSet::sync(const polyMesh& mesh)
|
||||
syncTools::swapBoundaryFaceList(mesh, neiZoneFace);
|
||||
|
||||
|
||||
const PackedBoolList isMasterFace(syncTools::getMasterFaces(mesh));
|
||||
const bitSet isMasterFace(syncTools::getMasterFaces(mesh));
|
||||
|
||||
|
||||
// Rebuild faceZone addressing and flipMap
|
||||
|
||||
@ -27,7 +27,7 @@ License
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "OBJstream.H"
|
||||
#include "labelPairHashes.H"
|
||||
#include "PackedBoolList.H"
|
||||
#include "bitSet.H"
|
||||
#include "triSurface.H"
|
||||
#include "pointIndexHit.H"
|
||||
#include "mergePoints.H"
|
||||
@ -820,7 +820,7 @@ void Foam::surfaceIntersection::doCutEdges
|
||||
|
||||
// Optionally prevent intersection within a single region.
|
||||
// Like self-intersect, but only if regions are different
|
||||
PackedBoolList maskRegions(32);
|
||||
bitSet maskRegions(32);
|
||||
|
||||
treeDataTriSurface::findAllIntersectOp
|
||||
allIntersectOp(searchTree, maskFaces);
|
||||
|
||||
Reference in New Issue
Block a user