Commit ec1b7f70 authored by mattijs's avatar mattijs
Browse files

switch to indexedOctree

parent 6093824d
......@@ -22,14 +22,11 @@ License
along with OpenFOAM; if not, write to the Free Software Foundation,
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Description
\*---------------------------------------------------------------------------*/
#include "polyMesh.H"
#include "meshSearch.H"
#include "triPointRef.H"
#include "octree.H"
#include "polyMesh.H"
#include "indexedOctree.H"
#include "pointIndexHit.H"
#include "DynamicList.H"
#include "demandDrivenData.H"
......@@ -43,14 +40,75 @@ Foam::scalar Foam::meshSearch::tol_ = 1E-3;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
bool Foam::meshSearch::findNearer
(
const point& sample,
const pointField& points,
label& nearestI,
scalar& nearestDistSqr
)
{
bool nearer = false;
forAll(points, pointI)
{
scalar distSqr = magSqr(points[pointI] - sample);
if (distSqr < nearestDistSqr)
{
nearestDistSqr = distSqr;
nearestI = pointI;
nearer = true;
}
}
return nearer;
}
bool Foam::meshSearch::findNearer
(
const point& sample,
const pointField& points,
const labelList& indices,
label& nearestI,
scalar& nearestDistSqr
)
{
bool nearer = false;
forAll(indices, i)
{
label pointI = indices[i];
scalar distSqr = magSqr(points[pointI] - sample);
if (distSqr < nearestDistSqr)
{
nearestDistSqr = distSqr;
nearestI = i;
nearer = true;
}
}
return nearer;
}
// tree based searching
Foam::label Foam::meshSearch::findNearestCellTree(const point& location) const
{
treeBoundBox tightest(treeBoundBox::greatBox);
const indexedOctree<treeDataPoint>& tree = cellCentreTree();
scalar span = mag(tree.bb().max() - tree.bb().min());
scalar tightestDist = GREAT;
pointIndexHit info = tree.findNearest(location, Foam::sqr(span));
return cellCentreTree().findNearest(location, tightest, tightestDist);
if (!info.hit())
{
info = tree.findNearest(location, Foam::sqr(GREAT));
}
return info.index();
}
......@@ -60,18 +118,15 @@ Foam::label Foam::meshSearch::findNearestCellLinear(const point& location) const
const vectorField& centres = mesh_.cellCentres();
label nearestCelli = 0;
scalar minProximity = magSqr(centres[0] - location);
scalar minProximity = magSqr(centres[nearestCelli] - location);
forAll(centres, celli)
{
scalar proximity = magSqr(centres[celli] - location);
if (proximity < minProximity)
{
nearestCelli = celli;
minProximity = proximity;
}
}
findNearer
(
location,
centres,
nearestCelli,
minProximity
);
return nearestCelli;
}
......@@ -105,27 +160,134 @@ Foam::label Foam::meshSearch::findNearestCellWalk
do
{
closer = false;
closer = findNearer
(
location,
centres,
cc[curCell],
curCell,
distanceSqr
);
} while (closer);
return curCell;
}
// tree based searching
Foam::label Foam::meshSearch::findNearestFaceTree(const point& location) const
{
// Search nearest cell centre.
const indexedOctree<treeDataPoint>& tree = cellCentreTree();
scalar span = mag(tree.bb().max() - tree.bb().min());
// Search with decent span
pointIndexHit info = tree.findNearest(location, Foam::sqr(span));
if (!info.hit())
{
// Search with desparate span
info = tree.findNearest(location, Foam::sqr(GREAT));
}
// Now check any of the faces of the nearest cell
const vectorField& centres = mesh_.faceCentres();
const cell& ownFaces = mesh_.cells()[info.index()];
label nearestFaceI = ownFaces[0];
scalar minProximity = magSqr(centres[nearestFaceI] - location);
findNearer
(
location,
centres,
ownFaces,
nearestFaceI,
minProximity
);
return nearestFaceI;
}
// linear searching
Foam::label Foam::meshSearch::findNearestFaceLinear(const point& location) const
{
const vectorField& centres = mesh_.faceCentres();
label nearestFaceI = 0;
scalar minProximity = magSqr(centres[nearestFaceI] - location);
findNearer
(
location,
centres,
nearestFaceI,
minProximity
);
return nearestFaceI;
}
// walking from seed
Foam::label Foam::meshSearch::findNearestFaceWalk
(
const point& location,
const label seedFaceI
) const
{
if (seedFaceI < 0)
{
FatalErrorIn
(
"meshSearch::findNearestFaceWalk(const point&, const label)"
) << "illegal seedFace:" << seedFaceI << exit(FatalError);
}
// set the current list of neighbouring cells
const labelList& neighbours = cc[curCell];
const vectorField& centres = mesh_.faceCentres();
// Walk in direction of face that decreases distance
label curFace = seedFaceI;
scalar distanceSqr = magSqr(centres[curFace] - location);
while (true)
{
label betterFace = curFace;
findNearer
(
location,
centres,
mesh_.cells()[mesh_.faceOwner()[curFace]],
betterFace,
distanceSqr
);
forAll (neighbours, nI)
if (mesh_.isInternalFace(curFace))
{
scalar curDistSqr = magSqr(centres[neighbours[nI]] - location);
findNearer
(
location,
centres,
mesh_.cells()[mesh_.faceNeighbour()[curFace]],
betterFace,
distanceSqr
);
}
// search through all the neighbours.
// If the cell is closer, reset current cell and distance
if (curDistSqr < distanceSqr)
{
distanceSqr = curDistSqr;
curCell = neighbours[nI];
closer = true; // a closer neighbour has been found
}
if (betterFace == curFace)
{
break;
}
} while (closer);
return curCell;
curFace = betterFace;
}
return curFace;
}
......@@ -180,12 +342,11 @@ Foam::label Foam::meshSearch::findNearestBoundaryFaceWalk
const face& f = mesh_.faces()[curFaceI];
scalar minDist =
f.nearestPoint
(
location,
mesh_.points()
).distance();
scalar minDist = f.nearestPoint
(
location,
mesh_.points()
).distance();
bool closer;
......@@ -202,8 +363,7 @@ Foam::label Foam::meshSearch::findNearestBoundaryFaceWalk
forAll (myEdges, myEdgeI)
{
const labelList& neighbours =
mesh_.edgeFaces()[myEdges[myEdgeI]];
const labelList& neighbours = mesh_.edgeFaces()[myEdges[myEdgeI]];
// Check any face which uses edge, is boundary face and
// is not curFaceI itself.
......@@ -220,12 +380,11 @@ Foam::label Foam::meshSearch::findNearestBoundaryFaceWalk
{
const face& f = mesh_.faces()[faceI];
pointHit curHit =
f.nearestPoint
(
location,
mesh_.points()
);
pointHit curHit = f.nearestPoint
(
location,
mesh_.points()
);
// If the face is closer, reset current face and distance
if (curHit.distance() < minDist)
......@@ -283,9 +442,11 @@ Foam::meshSearch::~meshSearch()
clearOut();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::octree<Foam::octreeDataFace>& Foam::meshSearch::boundaryTree() const
const Foam::indexedOctree<Foam::treeDataFace>& Foam::meshSearch::boundaryTree()
const
{
if (!boundaryTreePtr_)
{
......@@ -294,17 +455,26 @@ const Foam::octree<Foam::octreeDataFace>& Foam::meshSearch::boundaryTree() const
//
// all boundary faces (not just walls)
octreeDataFace shapes(mesh_);
labelList bndFaces(mesh_.nFaces()-mesh_.nInternalFaces());
forAll(bndFaces, i)
{
bndFaces[i] = mesh_.nInternalFaces() + i;
}
treeBoundBox overallBb(mesh_.points());
boundaryTreePtr_ = new octree<octreeDataFace>
boundaryTreePtr_ = new indexedOctree<treeDataFace>
(
overallBb, // overall search domain
shapes, // all information needed to do checks on cells
1, // min levels
20.0, // maximum ratio of cubes v.s. cells
10.0
treeDataFace // all information needed to search faces
(
false, // do not cache bb
mesh_,
bndFaces // boundary faces only
),
overallBb, // overall search domain
8, // maxLevel
10, // leafsize
3.0 // duplicity
);
}
......@@ -312,7 +482,8 @@ const Foam::octree<Foam::octreeDataFace>& Foam::meshSearch::boundaryTree() const
}
const Foam::octree<Foam::octreeDataCell>& Foam::meshSearch::cellTree() const
const Foam::indexedOctree<Foam::treeDataCell>& Foam::meshSearch::cellTree()
const
{
if (!cellTreePtr_)
{
......@@ -320,17 +491,19 @@ const Foam::octree<Foam::octreeDataCell>& Foam::meshSearch::cellTree() const
// Construct tree
//
octreeDataCell shapes(mesh_);
treeBoundBox overallBb(mesh_.points());
cellTreePtr_ = new octree<octreeDataCell>
cellTreePtr_ = new indexedOctree<treeDataCell>
(
treeDataCell
(
false, // not cache bb
mesh_
),
overallBb, // overall search domain
shapes, // all information needed to do checks on cells
1, // min levels
20.0, // maximum ratio of cubes v.s. cells
2.0
8, // maxLevel
10, // leafsize
3.0 // duplicity
);
}
......@@ -339,8 +512,8 @@ const Foam::octree<Foam::octreeDataCell>& Foam::meshSearch::cellTree() const
}
const Foam::octree<Foam::octreeDataPoint>& Foam::meshSearch::cellCentreTree()
const
const Foam::indexedOctree<Foam::treeDataPoint>&
Foam::meshSearch::cellCentreTree() const
{
if (!cellCentreTreePtr_)
{
......@@ -348,17 +521,14 @@ const Foam::octree<Foam::octreeDataPoint>& Foam::meshSearch::cellCentreTree()
// Construct tree
//
// shapes holds reference to cellCentres!
octreeDataPoint shapes(mesh_.cellCentres());
treeBoundBox overallBb(mesh_.cellCentres());
cellCentreTreePtr_ = new octree<octreeDataPoint>
cellCentreTreePtr_ = new indexedOctree<treeDataPoint>
(
treeDataPoint(mesh_.cellCentres()),
overallBb, // overall search domain
shapes, // all information needed to do checks on cells
1, // min levels
20.0, // maximum ratio of cubes v.s. cells
10, // max levels
10.0, // maximum ratio of cubes v.s. cells
100.0 // max. duplicity; n/a since no bounding boxes.
);
}
......@@ -396,15 +566,14 @@ bool Foam::meshSearch::pointInCell(const point& p, label cellI) const
forAll(f, fp)
{
pointHit inter =
f.ray
(
ctr,
dir,
mesh_.points(),
intersection::HALF_RAY,
intersection::VECTOR
);
pointHit inter = f.ray
(
ctr,
dir,
mesh_.points(),
intersection::HALF_RAY,
intersection::VECTOR
);
if (inter.hit())
{
......@@ -484,6 +653,31 @@ Foam::label Foam::meshSearch::findNearestCell
}
Foam::label Foam::meshSearch::findNearestFace
(
const point& location,
const label seedFaceI,
const bool useTreeSearch
) const
{
if (seedFaceI == -1)
{
if (useTreeSearch)
{
return findNearestFaceTree(location);
}
else
{
return findNearestFaceLinear(location);
}
}
else
{
return findNearestFaceWalk(location, seedFaceI);
}
}
Foam::label Foam::meshSearch::findCell
(
const point& location,
......@@ -607,19 +801,26 @@ Foam::label Foam::meshSearch::findNearestBoundaryFace
{
if (useTreeSearch)
{
treeBoundBox tightest(treeBoundBox::greatBox);
const indexedOctree<treeDataFace>& tree = boundaryTree();
scalar tightestDist = GREAT;
scalar span = mag(tree.bb().max() - tree.bb().min());
label index =
boundaryTree().findNearest
pointIndexHit info = boundaryTree().findNearest
(
location,
Foam::sqr(span)
);
if (!info.hit())
{
info = boundaryTree().findNearest
(
location,
tightest,
tightestDist
Foam::sqr(GREAT)
);
}
return boundaryTree().shapes().meshFaces()[index];
return tree.shapes().faceLabels()[info.index()];
}
else
{
......@@ -670,7 +871,7 @@ Foam::pointIndexHit Foam::meshSearch::intersection
if (curHit.hit())
{
// Change index into octreeData into face label
curHit.setIndex(boundaryTree().shapes().meshFaces()[curHit.index()]);
curHit.setIndex(boundaryTree().shapes().faceLabels()[curHit.index()]);
}
return curHit;
}
......@@ -733,7 +934,9 @@ Foam::List<Foam::pointIndexHit> Foam::meshSearch::intersections
bool Foam::meshSearch::isInside(const point& p) const
{
return boundaryTree().getSampleType(p) == octree<octreeDataFace>::INSIDE;
return
boundaryTree().getVolumeType(p)
== indexedOctree<treeDataFace>::INSIDE;
}
......
......@@ -26,7 +26,8 @@ Class
Foam::meshSearch
Description
Various searches on polyMesh; uses (demand driven) octree to search.
Various (local, not parallel) searches on polyMesh;
uses (demand driven) octree to search.
SourceFiles
meshSearch.C
......@@ -36,11 +37,10 @@ SourceFiles
#ifndef meshSearch_H
#define meshSearch_H
#include "octreeDataCell.H"
#include "octreeDataFace.H"
#include "octreeDataPoint.H"
#include "treeDataCell.H"
#include "treeDataFace.H"
#include "treeDataPoint.H"
#include "pointIndexHit.H"
#include "className.H"
#include "Cloud.H"
#include "passiveParticle.H"
......@@ -71,46 +71,77 @@ class meshSearch
//- demand driven octrees
mutable octree<octreeDataFace>* boundaryTreePtr_;
mutable octree<octreeDataCell>* cellTreePtr_;
mutable octree<octreeDataPoint>* cellCentreTreePtr_;
mutable indexedOctree<treeDataFace>* boundaryTreePtr_;
mutable indexedOctree<treeDataCell>* cellTreePtr_;
mutable indexedOctree<treeDataPoint>* cellCentreTreePtr_;
// Private Member Functions
//- nearest cell centre using octree
label findNearestCellTree(const point& location) const;
//- Updates nearestI, nearestDistSqr from any closer ones.
static bool findNearer
(
const point& sample,
const pointField& points,
label& nearestI,
scalar& nearestDistSqr
);
//- Updates nearestI, nearestDistSqr from any selected closer ones.
static bool findNearer
(
const point& sample,
const pointField& points,
const labelList& indices,
label& nearestI,
scalar& nearestDistSqr
);
//- nearest cell centre going through all cells
label findNearestCellLinear(const point& location) const;
//- walk from seed. Does not 'go around' boundary, just returns
// last cell before boundary.
label findNearestCellWalk
(
const point& location,
const label seedCellI
) const;
// Cells
//- cell containing location. Linear search.
label findCellLinear(const point& location) const;
//- nearest cell centre using octree
label findNearestCellTree(const point&) const;
//- nearest cell centre going through all cells
label findNearestCellLinear(const point&) const;
//- walk from seed. Does not 'go around' boundary, just returns
// last cell before boundary.
label findNearestCellWalk(const point&, const label) const;
//- cell containing location. Linear search.
label findCellLinear(const point&) const;
// Cells
label findNearestFaceTree(const point&) const;