ENH: add primitiveMesh cellBb()

- the boundBox for a given cell, using the cheapest calculation:

  - cellPoints if already available, since this will involve the
    fewest number of min/max comparisions.

  - otherwise walk the cell faces: via the cell box() method
    to avoid creating demand-driven cellPoints etc.
This commit is contained in:
Mark Olesen
2022-11-01 12:15:08 +01:00
committed by Andrew Heather
parent 27c2cdc040
commit 0ba458fdbc
12 changed files with 68 additions and 141 deletions

View File

@ -167,7 +167,7 @@ void Foam::backgroundMeshDecomposition::initialRefinement()
{ {
if (volumeStatus[celli] == volumeType::UNKNOWN) if (volumeStatus[celli] == volumeType::UNKNOWN)
{ {
treeBoundBox cellBb(mesh_.cells()[celli].box(mesh_)); treeBoundBox cellBb(mesh_.cellBb(celli));
if (geometry.overlaps(cellBb)) if (geometry.overlaps(cellBb))
{ {
@ -279,7 +279,7 @@ void Foam::backgroundMeshDecomposition::initialRefinement()
{ {
if (volumeStatus[celli] == volumeType::UNKNOWN) if (volumeStatus[celli] == volumeType::UNKNOWN)
{ {
treeBoundBox cellBb(mesh_.cells()[celli].box(mesh_)); treeBoundBox cellBb(mesh_.cellBb(celli));
if (geometry.overlaps(cellBb)) if (geometry.overlaps(cellBb))
{ {
@ -498,7 +498,7 @@ bool Foam::backgroundMeshDecomposition::refineCell
// const conformationSurfaces& geometry = geometryToConformTo_; // const conformationSurfaces& geometry = geometryToConformTo_;
treeBoundBox cellBb(mesh_.cells()[celli].box(mesh_)); treeBoundBox cellBb(mesh_.cellBb(celli));
weightEstimate = 1.0; weightEstimate = 1.0;

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2018-2021 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -71,6 +71,7 @@ namespace Foam
// Forward Declarations // Forward Declarations
class bitSet; class bitSet;
class boundBox;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class primitiveMesh Declaration Class primitiveMesh Declaration
@ -769,6 +770,9 @@ public:
// Useful derived info // Useful derived info
//- The bounding box for given cell index
boundBox cellBb(const label celli) const;
//- Return true if the point in the cell bounding box. //- Return true if the point in the cell bounding box.
// The bounding box may be isotropically inflated by the fraction // The bounding box may be isotropically inflated by the fraction
// inflationFraction // inflationFraction

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2017 OpenCFD Ltd. Copyright (C) 2017-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -32,6 +32,18 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::boundBox Foam::primitiveMesh::cellBb(const label celli) const
{
if (hasCellPoints())
{
// No reduction!
return boundBox(points(), cellPoints()[celli], false);
}
return boundBox(cells()[celli].box(points(), faces()));
}
bool Foam::primitiveMesh::pointInCellBB bool Foam::primitiveMesh::pointInCellBB
( (
const point& p, const point& p,
@ -39,15 +51,7 @@ bool Foam::primitiveMesh::pointInCellBB
scalar inflationFraction scalar inflationFraction
) const ) const
{ {
boundBox bb boundBox bb(cellBb(celli));
(
cells()[celli].points
(
faces(),
points()
),
false
);
if (inflationFraction > SMALL) if (inflationFraction > SMALL)
{ {

View File

@ -150,13 +150,7 @@ bool Foam::functionObjects::energySpectrum::read(const dictionary& dict)
const boundBox meshBb(mesh_.bounds()); const boundBox meshBb(mesh_.bounds());
// Assume all cells are the same size... // Assume all cells are the same size...
const cell& c = mesh_.cells()[0]; boundBox cellBb(mesh_.cellBb(0));
boundBox cellBb(boundBox::invertedBox);
forAll(c, facei)
{
const face& f = mesh_.faces()[c[facei]];
cellBb.add(mesh_.points(), f);
}
const vector L(meshBb.max() - meshBb.min()); const vector L(meshBb.max() - meshBb.min());
const vector nCellXYZ(cmptDivide(L, cellBb.max() - cellBb.min())); const vector nCellXYZ(cmptDivide(L, cellBb.max() - cellBb.min()));

View File

@ -133,9 +133,9 @@ void Foam::snappyVoxelMeshDriver::isInside
} }
else else
{ {
for (const cell& c : mesh.cells()) for (label celli = 0; celli < mesh.nCells(); ++celli)
{ {
const boundBox cellBb(c.box(mesh)); const boundBox cellBb(mesh.cellBb(celli));
voxelMeshSearch::fill voxelMeshSearch::fill
( (

View File

@ -236,20 +236,6 @@ void Foam::cellCellStencils::inverseDistance::markBoundaries
} }
Foam::treeBoundBox Foam::cellCellStencils::inverseDistance::cellBb
(
const primitiveMesh& mesh,
const label celli
)
{
if (mesh.hasCellPoints())
{
return treeBoundBox(mesh.points(), mesh.cellPoints(celli));
}
return treeBoundBox(mesh.cells()[celli].box(mesh));
}
bool Foam::cellCellStencils::inverseDistance::overlaps bool Foam::cellCellStencils::inverseDistance::overlaps
( (
const boundBox& bb, const boundBox& bb,
@ -326,7 +312,7 @@ void Foam::cellCellStencils::inverseDistance::markPatchesAsHoles
forAll(tgtCellMap, tgtCelli) forAll(tgtCellMap, tgtCelli)
{ {
label celli = tgtCellMap[tgtCelli]; label celli = tgtCellMap[tgtCelli];
treeBoundBox cBb(cellBb(mesh_, celli)); treeBoundBox cBb(mesh_.cellBb(celli));
cBb.min() -= smallVec_; cBb.min() -= smallVec_;
cBb.max() += smallVec_; cBb.max() += smallVec_;
@ -396,9 +382,10 @@ void Foam::cellCellStencils::inverseDistance::markPatchesAsHoles
forAll(tgtCellMap, tgtCelli) forAll(tgtCellMap, tgtCelli)
{ {
label celli = tgtCellMap[tgtCelli]; label celli = tgtCellMap[tgtCelli];
treeBoundBox cBb(cellBb(mesh_, celli)); treeBoundBox cBb(mesh_.cellBb(celli));
cBb.min() -= smallVec_; cBb.min() -= smallVec_;
cBb.max() += smallVec_; cBb.max() += smallVec_;
if if
( (
overlaps overlaps
@ -554,7 +541,7 @@ void Foam::cellCellStencils::inverseDistance::markDonors
label celli = tgtCellMap[tgtCelli]; label celli = tgtCellMap[tgtCelli];
if (srcOverlapProcs.size()) if (srcOverlapProcs.size())
{ {
treeBoundBox subBb(cellBb(mesh_, celli)); treeBoundBox subBb(mesh_.cellBb(celli));
subBb.min() -= smallVec_; subBb.min() -= smallVec_;
subBb.max() += smallVec_; subBb.max() += smallVec_;

View File

@ -179,13 +179,6 @@ protected:
labelList& patchCellTypes labelList& patchCellTypes
); );
//- Calculate bounding box of cell
static treeBoundBox cellBb
(
const primitiveMesh& mesh,
const label celli
);
//- Mark all cells overlapping (a voxel covered by) a src patch //- Mark all cells overlapping (a voxel covered by) a src patch
// with type HOLE // with type HOLE
void markPatchesAsHoles void markPatchesAsHoles

View File

@ -206,9 +206,6 @@ void Foam::cellCellStencils::trackingInverseDistance::markPatchesAsHoles
labelList& allCellTypes labelList& allCellTypes
) const ) const
{ {
const pointField& allPoints = mesh_.points();
const labelListList& allCellPoints = mesh_.cellPoints();
const treeBoundBoxList& srcPatchBbs = patchBb[srcI]; const treeBoundBoxList& srcPatchBbs = patchBb[srcI];
const treeBoundBoxList& tgtPatchBbs = patchBb[tgtI]; const treeBoundBoxList& tgtPatchBbs = patchBb[tgtI];
const labelList& tgtCellMap = meshParts_[tgtI].cellMap(); const labelList& tgtCellMap = meshParts_[tgtI].cellMap();
@ -226,7 +223,7 @@ void Foam::cellCellStencils::trackingInverseDistance::markPatchesAsHoles
forAll(tgtCellMap, tgtCelli) forAll(tgtCellMap, tgtCelli)
{ {
label celli = tgtCellMap[tgtCelli]; label celli = tgtCellMap[tgtCelli];
boundBox cBb(allPoints, allCellPoints[celli], false); boundBox cBb(mesh_.cellBb(celli));
cBb.min() -= smallVec_; cBb.min() -= smallVec_;
cBb.max() += smallVec_; cBb.max() += smallVec_;
@ -295,7 +292,7 @@ void Foam::cellCellStencils::trackingInverseDistance::markPatchesAsHoles
forAll(tgtCellMap, tgtCelli) forAll(tgtCellMap, tgtCelli)
{ {
label celli = tgtCellMap[tgtCelli]; label celli = tgtCellMap[tgtCelli];
boundBox cBb(allPoints, allCellPoints[celli], false); boundBox cBb(mesh_.cellBb(celli));
cBb.min() -= smallVec_; cBb.min() -= smallVec_;
cBb.max() += smallVec_; cBb.max() += smallVec_;
@ -412,7 +409,7 @@ void Foam::cellCellStencils::trackingInverseDistance::markDonors
label celli = tgtCellMap[tgtCelli]; label celli = tgtCellMap[tgtCelli];
if (srcOverlapProcs.size()) if (srcOverlapProcs.size())
{ {
treeBoundBox subBb(cellBb(mesh_, celli)); treeBoundBox subBb(mesh_.cellBb(celli));
subBb.min() -= smallVec_; subBb.min() -= smallVec_;
subBb.max() += smallVec_; subBb.max() += smallVec_;

View File

@ -54,23 +54,20 @@ Foam::labelList Foam::meshToMeshMethod::maskCells() const
intersectBb.inflate(0.01); intersectBb.inflate(0.01);
const cellList& srcCells = src_.cells();
const faceList& srcFaces = src_.faces();
const pointField& srcPts = src_.points();
DynamicList<label> cells(src_.nCells()); DynamicList<label> cells(src_.nCells());
forAll(srcCells, srcI)
for (label srcCelli = 0; srcCelli < src_.nCells(); ++srcCelli)
{ {
boundBox cellBb(srcCells[srcI].points(srcFaces, srcPts), false); boundBox cellBb(src_.cellBb(srcCelli));
if (intersectBb.overlaps(cellBb)) if (intersectBb.overlaps(cellBb))
{ {
cells.append(srcI); cells.append(srcCelli);
} }
} }
if (debug) if (debug)
{ {
Pout<< "participating source mesh cells: " << cells.size() << endl; Pout<< "participating source mesh cells: " << src_.nCells() << endl;
} }
return cells; return cells;
@ -87,14 +84,7 @@ bool Foam::meshToMeshMethod::intersect
tetOverlapVolume overlapEngine; tetOverlapVolume overlapEngine;
// Note: avoid demand-driven construction of cellPoints treeBoundBox bbTgtCell(tgt_.cellBb(tgtCelli));
// treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCelli]);
const UList<label>& cellFaces = tgt_.cells()[tgtCelli];
treeBoundBox bbTgtCell(tgt_.points(), tgt_.faces()[cellFaces[0]]);
for (label i = 1; i < cellFaces.size(); ++i)
{
bbTgtCell.add(tgt_.points(), tgt_.faces()[cellFaces[i]]);
}
return overlapEngine.cellCellOverlapMinDecomp return overlapEngine.cellCellOverlapMinDecomp
( (
@ -116,14 +106,7 @@ Foam::scalar Foam::meshToMeshMethod::interVol
{ {
tetOverlapVolume overlapEngine; tetOverlapVolume overlapEngine;
// Note: avoid demand-driven construction of cellPoints treeBoundBox bbTgtCell(tgt_.cellBb(tgtCelli));
// treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCelli]);
const UList<label>& cellFaces = tgt_.cells()[tgtCelli];
treeBoundBox bbTgtCell(tgt_.points(), tgt_.faces()[cellFaces[0]]);
for (label i = 1; i < cellFaces.size(); ++i)
{
bbTgtCell.add(tgt_.points(), tgt_.faces()[cellFaces[i]]);
}
scalar vol = overlapEngine.cellCellOverlapVolumeMinDecomp scalar vol = overlapEngine.cellCellOverlapVolumeMinDecomp
( (
@ -147,14 +130,7 @@ Foam::meshToMeshMethod::interVolAndCentroid
{ {
tetOverlapVolume overlapEngine; tetOverlapVolume overlapEngine;
// Note: avoid demand-driven construction of cellPoints treeBoundBox bbTgtCell(tgt_.cellBb(tgtCelli));
// treeBoundBox bbTgtCell(tgt_.points(), tgt_.cellPoints()[tgtCelli]);
const UList<label>& cellFaces = tgt_.cells()[tgtCelli];
treeBoundBox bbTgtCell(tgt_.points(), tgt_.faces()[cellFaces[0]]);
for (label i = 1; i < cellFaces.size(); ++i)
{
bbTgtCell.add(tgt_.points(), tgt_.faces()[cellFaces[i]]);
}
Tuple2<scalar, point> volAndInertia = Tuple2<scalar, point> volAndInertia =
overlapEngine.cellCellOverlapMomentMinDecomp overlapEngine.cellCellOverlapMomentMinDecomp

View File

@ -178,12 +178,8 @@ Foam::autoPtr<Foam::mapDistribute> Foam::meshToMesh::calcProcMap
} }
// determine which cells of tgt mesh overlaps src mesh per proc // Determine which cells of tgt mesh overlaps src mesh per proc
const cellList& cells = tgt.cells(); labelListList sendMap(Pstream::nProcs());
const faceList& faces = tgt.faces();
const pointField& points = tgt.points();
labelListList sendMap;
{ {
// per processor indices into all segments to send // per processor indices into all segments to send
@ -198,20 +194,11 @@ Foam::autoPtr<Foam::mapDistribute> Foam::meshToMesh::calcProcMap
// work array - whether src processor bb overlaps the tgt cell // work array - whether src processor bb overlaps the tgt cell
// bounds // bounds
boolList procBbOverlaps(Pstream::nProcs()); boolList procBbOverlaps(Pstream::nProcs());
forAll(cells, celli)
{
const cell& c = cells[celli];
// determine bounding box of tgt cell for (label celli = 0; celli < tgt.nCells(); ++celli)
boundBox cellBb(boundBox::invertedBox);
forAll(c, facei)
{ {
const face& f = faces[c[facei]]; // Bounding box of tgt cell
forAll(f, fp) boundBox cellBb(tgt.cellBb(celli));
{
cellBb.add(points, f);
}
}
// find the overlapping tgt cells on each src processor // find the overlapping tgt cells on each src processor
(void)calcOverlappingProcs(procBb, cellBb, procBbOverlaps); (void)calcOverlappingProcs(procBb, cellBb, procBbOverlaps);
@ -226,23 +213,22 @@ Foam::autoPtr<Foam::mapDistribute> Foam::meshToMesh::calcProcMap
} }
// convert dynamicList to labelList // convert dynamicList to labelList
sendMap.setSize(Pstream::nProcs());
forAll(sendMap, proci) forAll(sendMap, proci)
{ {
sendMap[proci].transfer(dynSendMap[proci]); sendMap[proci].transfer(dynSendMap[proci]);
} }
}
// debug printing // debug printing
if (debug) if (debug)
{ {
Pout<< "Of my " << cells.size() Pout<< "Of my " << tgt.nCells()
<< " target cells I need to send to:" << nl << " target cells I need to send to:" << nl
<< "\tproc\tcells" << endl; << "\tproc\tcells" << endl;
forAll(sendMap, proci) forAll(sendMap, proci)
{ {
Pout<< '\t' << proci << '\t' << sendMap[proci].size() Pout<< '\t' << proci << '\t'
<< endl; << sendMap[proci].size() << endl;
}
} }
} }
@ -250,7 +236,7 @@ Foam::autoPtr<Foam::mapDistribute> Foam::meshToMesh::calcProcMap
// send over how many tgt cells I need to receive from each // send over how many tgt cells I need to receive from each
// processor // processor
labelListList sendSizes(Pstream::nProcs()); labelListList sendSizes(Pstream::nProcs());
sendSizes[Pstream::myProcNo()].setSize(Pstream::nProcs()); sendSizes[Pstream::myProcNo()].resize(Pstream::nProcs());
forAll(sendMap, proci) forAll(sendMap, proci)
{ {
sendSizes[Pstream::myProcNo()][proci] = sendMap[proci].size(); sendSizes[Pstream::myProcNo()][proci] = sendMap[proci].size();

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -89,20 +89,14 @@ void Foam::cuttingSurface::calcCellCuts
); );
boundBox cellBb;
for (const label celli : cellCuts) for (const label celli : cellCuts)
{ {
cellBb.clear(); if (!fvm.cellBb(celli).contains(nearest[celli].point()))
cellBb.add(pts, fvm.cellPoints(celli));
if (!cellBb.contains(nearest[celli].hitPoint()))
{ {
cellCuts.unset(celli); cellCuts.unset(celli);
} }
} }
if (debug) if (debug)
{ {
volScalarField cCuts volScalarField cCuts

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2021 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -204,23 +204,18 @@ static bitSet simpleGeometricFilter
// A deny filter. Initially false (accept everything) // A deny filter. Initially false (accept everything)
ignoreCells.resize(mesh.nCells()); ignoreCells.resize(mesh.nCells());
bitSet pointFilter; bitSet ignorePoints;
if (WantPointFilter) if (WantPointFilter)
{ {
// Create as accept filter. Initially false (deny everything) // Create deny filter
pointFilter.resize(mesh.nPoints()); ignorePoints.resize(mesh.nPoints(), true);
} }
boundBox cellBb;
forAll(nearest, celli) forAll(nearest, celli)
{ {
const point& pt = nearest[celli].point(); const point& pt = nearest[celli].point();
const labelList& cPoints = mesh.cellPoints(celli); boundBox cellBb(mesh.cellBb(celli));
cellBb.clear();
cellBb.add(mesh.points(), cPoints);
cellBb.inflate(boundBoxInflate); cellBb.inflate(boundBoxInflate);
if (!cellBb.contains(pt)) if (!cellBb.contains(pt))
@ -229,15 +224,12 @@ static bitSet simpleGeometricFilter
} }
else if (WantPointFilter) else if (WantPointFilter)
{ {
// Good cell candidate, accept its points // Good cell candidate, do not ignore its points
pointFilter.set(cPoints); ignorePoints.unset(mesh.cellPoints(celli));
} }
} }
// Flip from accept to deny filter return ignorePoints;
pointFilter.flip();
return pointFilter;
} }