ENH: cleanup treeData items (#2609)

Changes / Improvements

- more consistent subsetting, interface

  * Extend the use of subset and non-subset collections with uniform
    internal getters to ensure that the subset/non-subset versions
    are robustly handled.

  * operator[](label) and objectIndex(label) for standardized access
    to the underlying item, or the original index, regardless of
    subsetting or not.

  * centres() and centre(label) for representative point cloud
    information.

  * nDim() returns the object dimensionality (0: point, 1: line, etc)
    these can be used to determine how 'fat' each shape may be
    and whether bounds(labelList) may contribute any useful information.

  * bounds(labelList) to return the full bound box required for
    specific items. Eg, the overall bounds for various 3D cells.

- easier construction of non-caching versions. The bounding boxes are
  rarely cached, so simpler constructors without the caching bool
  are provided.

- expose findNearest (bound sphere) method to allow general use
  since this does not actually need a tree.

- static helpers

  The boxes() static methods can be used by callers that need to build
  their own treeBoundBoxList of common shapes (edge, face, cell)
  that are also available as treeData types.

  The bounds() static methods can be used by callers to determine the
  overall bound-box size prior to constructing an indexedOctree
  without writing ad hoc code inplace.

  Not implemented for treeDataPrimitivePatch since similiar
  functionality is available directly from the PrimitivePatch::box()
  method with less typing.

========
BREAKING: cellLabels(), faceLabels(), edgeLabel() access methods

- it was always unsafe to use the treeData xxxLabels() methods without
  subsetting elements. However, since the various classes
  (treeDataCell, treeDataEdge, etc) automatically provided
  an identity lookup, this problem was not apparent.

  Use objectIndex(label) to safely de-reference to the original index
  and operator[](index) to de-reference to the original object.
This commit is contained in:
Mark Olesen
2022-10-11 18:34:41 +02:00
committed by Andrew Heather
parent f638db48c7
commit ac4f580d09
33 changed files with 2095 additions and 1033 deletions

View File

@ -88,7 +88,7 @@ void Foam::meshToMesh0::calcAddressing()
<< " bounding box (shifted) : " << shiftedBb << nl
<< " typical dimension : " << shiftedBb.avgDim() << endl;
indexedOctree<treeDataCell> oc
indexedOctree<treeDataCell> cellTree
(
treeDataCell(false, fromMesh_, polyMesh::CELL_TETS),
shiftedBb, // overall bounding box
@ -99,7 +99,7 @@ void Foam::meshToMesh0::calcAddressing()
if (debug)
{
oc.print(Pout, false, 0);
cellTree.print(Pout, false, 0);
}
cellAddresses
@ -108,7 +108,7 @@ void Foam::meshToMesh0::calcAddressing()
toMesh_.cellCentres(),
fromMesh_,
boundaryCell,
oc
cellTree
);
forAll(toMesh_.boundaryMesh(), patchi)
@ -125,7 +125,7 @@ void Foam::meshToMesh0::calcAddressing()
toPatch.faceCentres(),
fromMesh_,
boundaryCell,
oc
cellTree
);
}
else if
@ -160,7 +160,7 @@ void Foam::meshToMesh0::calcAddressing()
// Note: allow more levels than in meshSearch. Assume patch
// is not as big as all boundary faces
indexedOctree<treeDataFace> oc
indexedOctree<treeDataFace> faceTree
(
treeDataFace(false, fromPatch),
shiftedBb, // overall search domain
@ -178,7 +178,7 @@ void Foam::meshToMesh0::calcAddressing()
forAll(toPatch, toi)
{
boundaryAddressing_[patchi][toi] = oc.findNearest
boundaryAddressing_[patchi][toi] = faceTree.findNearest
(
centresToBoundary[toi],
distSqr
@ -199,7 +199,7 @@ void Foam::meshToMesh0::cellAddresses
const pointField& points,
const fvMesh& fromMesh,
const List<bool>& boundaryCell,
const indexedOctree<treeDataCell>& oc
const indexedOctree<treeDataCell>& cellTree
) const
{
// the implemented search method is a simple neighbour array search.
@ -263,7 +263,7 @@ void Foam::meshToMesh0::cellAddresses
// the octree search to find it.
if (boundaryCell[curCell])
{
cellAddressing_[toI] = oc.findInside(p);
cellAddressing_[toI] = cellTree.findInside(p);
if (cellAddressing_[toI] != -1)
{
@ -320,7 +320,7 @@ void Foam::meshToMesh0::cellAddresses
if (!found)
{
// Still not found so use the octree
cellAddressing_[toI] = oc.findInside(p);
cellAddressing_[toI] = cellTree.findInside(p);
if (cellAddressing_[toI] != -1)
{

View File

@ -116,7 +116,7 @@ class meshToMesh0
const pointField& points,
const fvMesh& fromMesh,
const List<bool>& boundaryCell,
const indexedOctree<treeDataCell>& oc
const indexedOctree<treeDataCell>& cellTree
) const;
void calculateInverseDistanceWeights() const;

View File

@ -107,14 +107,13 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
forAll(probeLocations(), probei)
{
const auto& treeData = boundaryTree.shapes();
const point sample = probeLocations()[probei];
const scalar span = boundaryTree.bb().mag();
pointIndexHit info = boundaryTree.findNearest
(
sample,
Foam::sqr(span)
Foam::sqr(boundaryTree.bb().mag())
);
if (!info.hit())
@ -122,7 +121,7 @@ void Foam::patchProbes::findElements(const fvMesh& mesh)
info = boundaryTree.findNearest(sample, Foam::sqr(GREAT));
}
label facei = boundaryTree.shapes().faceLabels()[info.index()];
const label facei = treeData.objectIndex(info.index());
const label patchi = bm.whichPatch(facei);

View File

@ -115,9 +115,11 @@ void Foam::patchCloudSet::calcSamples
forAll(sampleCoords_, sampleI)
{
const auto& treeData = patchTree.shapes();
const point& sample = sampleCoords_[sampleI];
pointIndexHit& nearInfo = nearest[sampleI].first();
auto& distSqrProc = nearest[sampleI].second();
// Find the nearest locally
if (patchFaces.size())
@ -133,17 +135,18 @@ void Foam::patchCloudSet::calcSamples
// Fill in the distance field and the processor field
if (!nearInfo.hit())
{
nearest[sampleI].second().first() = Foam::sqr(GREAT);
nearest[sampleI].second().second() = Pstream::myProcNo();
distSqrProc.first() = Foam::sqr(GREAT);
distSqrProc.second() = Pstream::myProcNo();
}
else
{
// Set nearest to mesh face label
nearInfo.setIndex(patchFaces[nearInfo.index()]);
const label objectIndex = treeData.objectIndex(nearInfo.index());
nearest[sampleI].second().first() =
nearInfo.point().distSqr(sample);
nearest[sampleI].second().second() = Pstream::myProcNo();
nearInfo.setIndex(objectIndex);
distSqrProc.first() = sample.distSqr(nearInfo.point());
distSqrProc.second() = Pstream::myProcNo();
}
}

View File

@ -136,9 +136,12 @@ void Foam::patchSeedSet::calcSamples
forAll(selectedLocations_, sampleI)
{
const auto& treeData = boundaryTree.shapes();
const point& sample = selectedLocations_[sampleI];
pointIndexHit& nearInfo = nearest[sampleI].first();
auto& distSqrProc = nearest[sampleI].second();
nearInfo = boundaryTree.findNearest
(
sample,
@ -147,17 +150,15 @@ void Foam::patchSeedSet::calcSamples
if (!nearInfo.hit())
{
nearest[sampleI].second().first() = Foam::sqr(GREAT);
nearest[sampleI].second().second() =
Pstream::myProcNo();
distSqrProc.first() = Foam::sqr(GREAT);
distSqrProc.second() = Pstream::myProcNo();
}
else
{
point fc(pp[nearInfo.index()].centre(pp.points()));
nearInfo.setPoint(fc);
nearest[sampleI].second().first() = sample.magSqr(fc);
nearest[sampleI].second().second() =
Pstream::myProcNo();
nearInfo.setPoint(treeData.centre(nearInfo.index()));
distSqrProc.first() = sample.distSqr(nearInfo.point());
distSqrProc.second() = Pstream::myProcNo();
}
}

View File

@ -159,7 +159,8 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
{
// Search for nearest cell
const indexedOctree<treeDataCell>& cellTree = meshSearcher.cellTree();
const auto& cellTree = meshSearcher.cellTree();
const auto& treeData = cellTree.shapes();
forAll(fc, facei)
{
@ -170,8 +171,10 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
if (info.hit())
{
const label objectIndex = treeData.objectIndex(info.index());
near.first() = info.point().distSqr(pt);
near.second() = globalCells.toGlobal(info.index());
near.second() = globalCells.toGlobal(objectIndex);
}
}
}
@ -180,6 +183,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
// Search for cell containing point
const auto& cellTree = meshSearcher.cellTree();
const auto& treeData = cellTree.shapes();
forAll(fc, facei)
{
@ -189,10 +193,13 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
if (cellTree.bb().contains(pt))
{
const label index = cellTree.findInside(pt);
if (index != -1)
{
const label objectIndex = treeData.objectIndex(index);
near.first() = 0;
near.second() = globalCells.toGlobal(index);
near.second() = globalCells.toGlobal(objectIndex);
}
}
}
@ -203,6 +210,7 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
// on all non-coupled boundary faces
const auto& bndTree = meshSearcher.nonCoupledBoundaryTree();
const auto& treeData = bndTree.shapes();
forAll(fc, facei)
{
@ -213,12 +221,10 @@ bool Foam::sampledMeshedSurface::update(const meshSearch& meshSearcher)
if (info.hit())
{
const label objectIndex = treeData.objectIndex(info.index());
near.first() = info.point().distSqr(pt);
near.second() =
globalCells.toGlobal
(
bndTree.shapes().faceLabels()[info.index()]
);
near.second() = globalCells.toGlobal(objectIndex);
}
}
}