ENH: general boundBox/treeBoundBox improvements

- null() static method
  * as const reference to the invertedBox with the appropriate casting.

- boundBox inflate(random)
  * refactored from treeBoundBox::extend, but allows in-place modification

- boundBox::hexFaces() instead of boundBox::faces
  * rarely used, but avoids confusion with treeBoundBox::faces
    and reuses hexCell face definitions without code duplication

- boundBox::hexCorners() for corner points corresponding to a hexCell.
  Can also be accessed from a treeBoundBox without ambiguity with
  points(), which could be hex corners (boundBox) or octant corners
  (treeBoundBox)

- boundBox::add with pairs of points
  * convenient (for example) when adding edges or a 'box' that has
    been extracted from a primitive mesh shape.

- declare boundBox nPoints(), nFaces(), nEdges() as per hexCell

ENH: return invertedBox instead of FatalError for empty trees

- similar to #2612

ENH: cellShape(HEX, ...) + boundBox hexCorners for block meshes

STYLE: cellModel::ref(...) instead of de-reference cellModel::ptr(...)
This commit is contained in:
Mark Olesen
2022-11-01 12:15:08 +01:00
committed by Andrew Heather
parent 0ba458fdbc
commit 1339c3357b
26 changed files with 373 additions and 219 deletions

View File

@ -34,7 +34,6 @@ Description
#include "line.H" #include "line.H"
#include "Random.H" #include "Random.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"
#include "cellModel.H"
#include "bitSet.H" #include "bitSet.H"
#include "HashSet.H" #include "HashSet.H"
#include "ListOps.H" #include "ListOps.H"
@ -59,8 +58,7 @@ int main(int argc, char *argv[])
{ {
#include "setRootCase.H" #include "setRootCase.H"
Info<<"boundBox faces: " << boundBox::faces << nl Info<<"boundBox faces: " << boundBox::hexFaces() << nl
<<"hex faces: " << cellModel::ref(cellModel::HEX).modelFaces() << nl
<<"tree-bb faces: " << treeBoundBox::faces << nl <<"tree-bb faces: " << treeBoundBox::faces << nl
<<"tree-bb edges: " << treeBoundBox::edges << endl; <<"tree-bb edges: " << treeBoundBox::edges << endl;
@ -113,10 +111,8 @@ int main(int argc, char *argv[])
Info<<"enclose point " << pt << " -> " << bb << endl; Info<<"enclose point " << pt << " -> " << bb << endl;
// restart with same points // restart with same points
bb = boundBox::invertedBox; bb.reset(point::zero);
bb.add(point(1,1,1)); bb.add(point(1,1,1), point(0,1.5,0.5));
bb.add(point::zero);
bb.add(point(0,1.5,0.5));
bb.add(point(5,2,-2)); bb.add(point(5,2,-2));
Info<<"repeated " << bb << endl; Info<<"repeated " << bb << endl;

View File

@ -293,7 +293,7 @@ bool Foam::fileFormats::ensightMeshReader::readGoldPart
elemIdToCells elemIdToCells
); );
const auto& model = *cellModel::ptr(cellModel::TET); const auto& model = cellModel::ref(cellModel::TET);
for (label shapei = 0; shapei < nShapes; shapei++) for (label shapei = 0; shapei < nShapes; shapei++)
{ {
readVerts(is, 4, nodeIdToPoints, verts); readVerts(is, 4, nodeIdToPoints, verts);
@ -326,7 +326,7 @@ bool Foam::fileFormats::ensightMeshReader::readGoldPart
elemIdToCells elemIdToCells
); );
const auto& model = *cellModel::ptr(cellModel::PYR); const auto& model = cellModel::ref(cellModel::PYR);
for (label shapei = 0; shapei < nShapes; shapei++) for (label shapei = 0; shapei < nShapes; shapei++)
{ {
readVerts(is, 5, nodeIdToPoints, verts); readVerts(is, 5, nodeIdToPoints, verts);
@ -359,7 +359,7 @@ bool Foam::fileFormats::ensightMeshReader::readGoldPart
elemIdToCells elemIdToCells
); );
const auto& model = *cellModel::ptr(cellModel::PRISM); const auto& model = cellModel::ref(cellModel::PRISM);
for (label shapei = 0; shapei < nShapes; shapei++) for (label shapei = 0; shapei < nShapes; shapei++)
{ {
readVerts(is, 6, nodeIdToPoints, verts); readVerts(is, 6, nodeIdToPoints, verts);
@ -392,7 +392,7 @@ bool Foam::fileFormats::ensightMeshReader::readGoldPart
elemIdToCells elemIdToCells
); );
const auto& model = *cellModel::ptr(cellModel::HEX); const auto& model = cellModel::ref(cellModel::HEX);
for (label shapei = 0; shapei < nShapes; shapei++) for (label shapei = 0; shapei < nShapes; shapei++)
{ {
readVerts(is, 8, nodeIdToPoints, verts); readVerts(is, 8, nodeIdToPoints, verts);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2019-2021 OpenCFD Ltd. Copyright (C) 2019-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -389,7 +389,7 @@ Foam::meshedSurface Foam::PDRobstacle::surface() const
boundBox box(obs.pt, obs.pt + obs.span); boundBox box(obs.pt, obs.pt + obs.span);
pointField pts(box.points()); pointField pts(box.points());
faceList fcs(boundBox::faces); faceList fcs(boundBox::hexFaces());
surf.transfer(pts, fcs); surf.transfer(pts, fcs);
@ -436,7 +436,7 @@ Foam::meshedSurface Foam::PDRobstacle::surface() const
); );
pointField pts0(box.points()); pointField pts0(box.points());
faceList fcs(boundBox::faces); faceList fcs(boundBox::hexFaces());
pointField pts(cs.globalPosition(pts0)); pointField pts(cs.globalPosition(pts0));

View File

@ -1,5 +1,3 @@
const cellModel& hex = cellModel::ref(cellModel::HEX);
cellShapeList cellShapes; cellShapeList cellShapes;
faceListList boundary; faceListList boundary;
pointField points; pointField points;
@ -8,20 +6,8 @@ pointField points;
block b block b
( (
cellShape(hex, identity(8)), cellShape(cellModel::HEX, identity(8)),
pointField pointField(boundBox(point::zero, L).hexCorners()),
(
{
point(0, 0, 0),
point(L.x(), 0, 0),
point(L.x(), L.y(), 0),
point(0, L.y(), 0),
point(0, 0, L.z()),
point(L.x(), 0, L.z()),
point(L.x(), L.y(), L.z()),
point(0, L.y(), L.z())
}
),
blockEdgeList(), blockEdgeList(),
blockFaceList(), blockFaceList(),
N N

View File

@ -533,6 +533,7 @@ $(primitiveShapes)/line/line.C
$(primitiveShapes)/plane/plane.C $(primitiveShapes)/plane/plane.C
$(primitiveShapes)/triangle/intersection.C $(primitiveShapes)/triangle/intersection.C
$(primitiveShapes)/objectHit/pointIndexHitIOList.C $(primitiveShapes)/objectHit/pointIndexHitIOList.C
$(primitiveShapes)/volumeType/volumeType.C
meshShapes = meshes/meshShapes meshShapes = meshes/meshShapes
$(meshShapes)/edge/edge.C $(meshShapes)/edge/edge.C
@ -550,11 +551,8 @@ $(cell)/cell.C
$(cell)/oppositeCellFace.C $(cell)/oppositeCellFace.C
$(cell)/cellIOList.C $(cell)/cellIOList.C
hexCell = $(meshShapes)/hexCell $(meshShapes)/hexCell/hexCell.C
$(hexCell)/hexCell.C $(meshShapes)/tetCell/tetCell.C
tetCell = $(meshShapes)/tetCell
$(tetCell)/tetCell.C
cellModel = $(meshShapes)/cellModel cellModel = $(meshShapes)/cellModel
$(cellModel)/cellModel.C $(cellModel)/cellModel.C
@ -826,7 +824,6 @@ algorithms/indexedOctree/indexedOctreeName.C
algorithms/indexedOctree/treeDataCell.C algorithms/indexedOctree/treeDataCell.C
algorithms/indexedOctree/treeDataEdge.C algorithms/indexedOctree/treeDataEdge.C
algorithms/indexedOctree/treeDataPoint.C algorithms/indexedOctree/treeDataPoint.C
algorithms/indexedOctree/volumeType.C
algorithms/dynamicIndexedOctree/dynamicIndexedOctreeName.C algorithms/dynamicIndexedOctree/dynamicIndexedOctreeName.C
algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C algorithms/dynamicIndexedOctree/dynamicTreeDataPoint.C

View File

@ -452,8 +452,7 @@ public:
{ {
if (nodes_.empty()) if (nodes_.empty())
{ {
FatalErrorInFunction return treeBoundBox::null();
<< "Tree is empty" << abort(FatalError);
} }
return nodes_[0].bb_; return nodes_[0].bb_;
} }

View File

@ -465,8 +465,7 @@ public:
{ {
if (nodes_.empty()) if (nodes_.empty())
{ {
FatalErrorInFunction return treeBoundBox::null();
<< "Tree is empty" << abort(FatalError);
} }
return nodes_[0].bb_; return nodes_[0].bb_;
} }

View File

@ -29,7 +29,10 @@ License
#include "boundBox.H" #include "boundBox.H"
#include "PstreamReduceOps.H" #include "PstreamReduceOps.H"
#include "plane.H" #include "plane.H"
#include "hexCell.H"
#include "triangle.H" #include "triangle.H"
#include "MinMax.H"
#include "Random.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -45,17 +48,6 @@ const Foam::boundBox Foam::boundBox::invertedBox
point::uniform(-ROOTVGREAT) point::uniform(-ROOTVGREAT)
); );
const Foam::faceList Foam::boundBox::faces
({
// Point and face order as per hex cellmodel
face({0, 4, 7, 3}), // 0: x-min, left
face({1, 2, 6, 5}), // 1: x-max, right
face({0, 1, 5, 4}), // 2: y-min, bottom
face({3, 7, 6, 2}), // 3: y-max, top
face({0, 3, 2, 1}), // 4: z-min, back
face({4, 5, 6, 7}) // 5: z-max, front
});
const Foam::FixedList<Foam::vector, 6> Foam::boundBox::faceNormals const Foam::FixedList<Foam::vector, 6> Foam::boundBox::faceNormals
({ ({
vector(-1, 0, 0), // 0: x-min, left vector(-1, 0, 0), // 0: x-min, left
@ -67,6 +59,14 @@ const Foam::FixedList<Foam::vector, 6> Foam::boundBox::faceNormals
}); });
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
const Foam::faceList& Foam::boundBox::hexFaces()
{
return hexCell::modelFaces();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::boundBox::boundBox(const boundBox& bb, const bool doReduce) Foam::boundBox::boundBox(const boundBox& bb, const bool doReduce)
@ -126,9 +126,9 @@ Foam::boundBox::boundBox
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
Foam::tmp<Foam::pointField> Foam::boundBox::points() const Foam::tmp<Foam::pointField> Foam::boundBox::hexCorners() const
{ {
auto tpts = tmp<pointField>::New(8); auto tpts = tmp<pointField>::New(boundBox::nPoints());
auto& pts = tpts.ref(); auto& pts = tpts.ref();
pts[0] = hexCorner<0>(); pts[0] = hexCorner<0>();
@ -146,10 +146,10 @@ Foam::tmp<Foam::pointField> Foam::boundBox::points() const
Foam::tmp<Foam::pointField> Foam::boundBox::faceCentres() const Foam::tmp<Foam::pointField> Foam::boundBox::faceCentres() const
{ {
auto tpts = tmp<pointField>::New(6); auto tpts = tmp<pointField>::New(boundBox::nFaces());
auto& pts = tpts.ref(); auto& pts = tpts.ref();
forAll(pts, facei) for (direction facei = 0; facei < boundBox::nFaces(); ++facei)
{ {
pts[facei] = faceCentre(facei); pts[facei] = faceCentre(facei);
} }
@ -281,6 +281,35 @@ Foam::point Foam::boundBox::nearest(const point& p) const
} }
void Foam::boundBox::inflate(Random& rndGen, const scalar factor)
{
vector newSpan(span());
// Make 3D
const scalar minSpan = factor * Foam::mag(newSpan);
for (direction dir = 0; dir < vector::nComponents; ++dir)
{
newSpan[dir] = Foam::max(newSpan[dir], minSpan);
}
min_ -= cmptMultiply(factor*rndGen.sample01<vector>(), newSpan);
max_ += cmptMultiply(factor*rndGen.sample01<vector>(), newSpan);
}
void Foam::boundBox::inflate
(
Random& rndGen,
const scalar factor,
const scalar delta
)
{
inflate(rndGen, factor);
grow(delta);
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
void Foam::boundBox::operator&=(const boundBox& bb) void Foam::boundBox::operator&=(const boundBox& bb)

View File

@ -55,6 +55,7 @@ namespace Foam
// Forward Declarations // Forward Declarations
class boundBox; class boundBox;
class plane; class plane;
class Random;
template<class T> class MinMax; template<class T> class MinMax;
Istream& operator>>(Istream& is, boundBox& bb); Istream& operator>>(Istream& is, boundBox& bb);
@ -76,12 +77,12 @@ public:
// Static Data Members // Static Data Members
//- Bits used for (x/y/z) direction encoding. //- Bits used for (x/y/z) directional encoding.
enum directionBit : direction enum directionBit : direction
{ {
XDIR = 0x1, //!< 1: x-direction (vector component 0) XDIR = 1, //!< 1: x-direction. Same as (1 << vector::X)
YDIR = 0x2, //!< 2: y-direction (vector component 1) YDIR = 2, //!< 2: y-direction. Same as (1 << vector::Y)
ZDIR = 0x4 //!< 4: z-direction (vector component 2) ZDIR = 4 //!< 4: z-direction. Same as (1 << vector::Z)
}; };
//- A large boundBox: min/max == -/+ ROOTVGREAT //- A large boundBox: min/max == -/+ ROOTVGREAT
@ -90,13 +91,32 @@ public:
//- A large inverted boundBox: min/max == +/- ROOTVGREAT //- A large inverted boundBox: min/max == +/- ROOTVGREAT
static const boundBox invertedBox; static const boundBox invertedBox;
//- Faces to point addressing, as per a 'hex' cell
static const faceList faces;
//- The unit normal per face //- The unit normal per face
static const FixedList<vector, 6> faceNormals; static const FixedList<vector, 6> faceNormals;
// Static Methods
//- The null boundBox is the same as an inverted box
static const boundBox& null() noexcept
{
return invertedBox;
}
//- The boundBox faces as a hexCell, using hexCorner points.
//- Same as hexCell::modelFaces()
static const Foam::faceList& hexFaces();
//- Number of points for boundBox and HEX
static constexpr label nPoints() noexcept { return 8; }
//- Number of edges for boundBox and HEX
static constexpr label nEdges() noexcept { return 12; }
//- Number of faces for boundBox and HEX
static constexpr label nFaces() noexcept { return 6; }
// Standard (Generated) Methods // Standard (Generated) Methods
//- Default construct: an inverted bounding box //- Default construct: an inverted bounding box
@ -190,9 +210,12 @@ public:
//- The bounding box span (from minimum to maximum) //- The bounding box span (from minimum to maximum)
inline vector span() const; inline vector span() const;
//- The magnitude of the bounding box span //- The magnitude/length of the bounding box diagonal
inline scalar mag() const; inline scalar mag() const;
//- The magnitude/length squared of bounding box diagonal
inline scalar magSqr() const;
//- The volume of the bound box //- The volume of the bound box
inline scalar volume() const; inline scalar volume() const;
@ -205,6 +228,12 @@ public:
//- Average length/height/width dimension //- Average length/height/width dimension
inline scalar avgDim() const; inline scalar avgDim() const;
//- Direction (X/Y/Z) of the smallest span (for empty box: 0)
inline direction minDir() const;
//- Direction (X/Y/Z) of the largest span (for empty box: 0)
inline direction maxDir() const;
//- Count the number of positive, non-zero dimensions. //- Count the number of positive, non-zero dimensions.
// \return // \return
// - -1 : if any dimensions are negative // - -1 : if any dimensions are negative
@ -219,7 +248,10 @@ public:
inline point hexCorner() const; inline point hexCorner() const;
//- Corner points in an order corresponding to a 'hex' cell //- Corner points in an order corresponding to a 'hex' cell
tmp<pointField> points() const; tmp<pointField> hexCorners() const;
//- Corner points in an order corresponding to a 'hex' cell
tmp<pointField> points() const { return hexCorners(); }
//- Face midpoints //- Face midpoints
tmp<pointField> faceCentres() const; tmp<pointField> faceCentres() const;
@ -248,6 +280,12 @@ public:
//- Extend to include the point. //- Extend to include the point.
inline void add(const point& pt); inline void add(const point& pt);
//- Extend to include two additional points.
inline void add(const point& pt0, const point& pt1);
//- Extend to include two additional points.
inline void add(const Pair<point>& points);
//- Extend to include the points. //- Extend to include the points.
inline void add(const UList<point>& points); inline void add(const UList<point>& points);
@ -288,6 +326,15 @@ public:
//- Expand box by factor*mag(span) in all dimensions //- Expand box by factor*mag(span) in all dimensions
inline void inflate(const scalar factor); inline void inflate(const scalar factor);
//- Expand box slightly by expanding all dimensions with
//- factor*span*(random 0-1) and guarantees
//- factor*mag(span) minimum width in any direction
void inflate(Random& rndGen, const scalar factor);
//- As per two parameter version but with additional
//- grow() by given amount in each dimension
void inflate(Random& r, const scalar factor, const scalar delta);
// Parallel // Parallel

View File

@ -38,48 +38,56 @@ namespace Foam
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<0>() const inline Foam::point Foam::boundBox::hexCorner<0>() const
{ {
// == octCorner<0>()
return min_; return min_;
} }
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<1>() const inline Foam::point Foam::boundBox::hexCorner<1>() const
{ {
// == octCorner<1>()
return point(max_.x(), min_.y(), min_.z()); return point(max_.x(), min_.y(), min_.z());
} }
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<2>() const inline Foam::point Foam::boundBox::hexCorner<2>() const
{ {
// == octCorner<3>()
return point(max_.x(), max_.y(), min_.z()); return point(max_.x(), max_.y(), min_.z());
} }
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<3>() const inline Foam::point Foam::boundBox::hexCorner<3>() const
{ {
// == octCorner<2>()
return point(min_.x(), max_.y(), min_.z()); return point(min_.x(), max_.y(), min_.z());
} }
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<4>() const inline Foam::point Foam::boundBox::hexCorner<4>() const
{ {
// == octCorner<4>()
return point(min_.x(), min_.y(), max_.z()); return point(min_.x(), min_.y(), max_.z());
} }
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<5>() const inline Foam::point Foam::boundBox::hexCorner<5>() const
{ {
// == octCorner<5>()
return point(max_.x(), min_.y(), max_.z()); return point(max_.x(), min_.y(), max_.z());
} }
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<6>() const inline Foam::point Foam::boundBox::hexCorner<6>() const
{ {
// == octCorner<7>()
return max_; return max_;
} }
template<> template<>
inline Foam::point Foam::boundBox::hexCorner<7>() const inline Foam::point Foam::boundBox::hexCorner<7>() const
{ {
// == octCorner<6>()
return point(min_.x(), max_.y(), max_.z()); return point(min_.x(), max_.y(), max_.z());
} }
@ -189,7 +197,13 @@ inline Foam::vector Foam::boundBox::span() const
inline Foam::scalar Foam::boundBox::mag() const inline Foam::scalar Foam::boundBox::mag() const
{ {
return ::Foam::mag(max_ - min_); return min_.dist(max_);
}
inline Foam::scalar Foam::boundBox::magSqr() const
{
return min_.distSqr(max_);
} }
@ -217,18 +231,58 @@ inline Foam::scalar Foam::boundBox::avgDim() const
} }
inline Foam::direction Foam::boundBox::minDir() const
{
direction cmpt = 0;
scalar best = ROOTVGREAT;
for (direction dir = 0; dir < vector::nComponents; ++dir)
{
const scalar dist = (max_[dir] - min_[dir]);
if (dist < best && dist > 0)
{
best = dist;
cmpt = dir;
}
}
return cmpt;
}
inline Foam::direction Foam::boundBox::maxDir() const
{
direction cmpt = 0;
scalar best = 0;
for (direction dir = 0; dir < vector::nComponents; ++dir)
{
const scalar dist = (max_[dir] - min_[dir]);
if (dist > best)
{
best = dist;
cmpt = dir;
}
}
return cmpt;
}
inline int Foam::boundBox::nDim() const inline int Foam::boundBox::nDim() const
{ {
int ngood = 0; int ngood = 0;
for (direction dir = 0; dir < vector::nComponents; ++dir) for (direction dir = 0; dir < vector::nComponents; ++dir)
{ {
const scalar diff = (max_[dir] - min_[dir]); const scalar dist = (max_[dir] - min_[dir]);
if (diff < 0) if (dist < 0)
{ {
return -1; return -1;
} }
else if (diff > 0) else if (dist > 0)
{ {
++ngood; ++ngood;
} }
@ -273,6 +327,20 @@ inline void Foam::boundBox::add(const point& pt)
} }
inline void Foam::boundBox::add(const point& pt0, const point& pt1)
{
add(pt0);
add(pt1);
}
inline void Foam::boundBox::add(const Pair<point>& points)
{
add(points.first());
add(points.second());
}
inline void Foam::boundBox::add(const UList<point>& points) inline void Foam::boundBox::add(const UList<point>& points)
{ {
for (const point& p : points) for (const point& p : points)

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020-2021 OpenCFD Ltd. Copyright (C) 2020-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -41,8 +41,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef cellShape_H #ifndef Foam_cellShape_H
#define cellShape_H #define Foam_cellShape_H
#include "pointField.H" #include "pointField.H"
#include "labelList.H" #include "labelList.H"
@ -109,6 +109,22 @@ public:
const bool doCollapse = false const bool doCollapse = false
); );
//- Copy construct from components, lookup cellModel by type
inline cellShape
(
const cellModel::modelType model,
const labelUList& labels,
const bool doCollapse = false
);
//- Move construct from components, lookup cellModel by type
inline cellShape
(
const cellModel::modelType model,
labelList&& labels,
const bool doCollapse = false
);
//- Copy construct from components, lookup cellModel by name //- Copy construct from components, lookup cellModel by name
inline cellShape inline cellShape
( (

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020-2021 OpenCFD Ltd. Copyright (C) 2020-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -92,6 +92,40 @@ inline Foam::cellShape::cellShape
} }
inline Foam::cellShape::cellShape
(
const cellModel::modelType model,
const labelUList& labels,
const bool doCollapse
)
:
labelList(labels),
m(cellModel::ptr(model))
{
if (doCollapse)
{
collapse();
}
}
inline Foam::cellShape::cellShape
(
const cellModel::modelType model,
labelList&& labels,
const bool doCollapse
)
:
labelList(std::move(labels)),
m(cellModel::ptr(model))
{
if (doCollapse)
{
collapse();
}
}
inline Foam::cellShape::cellShape inline Foam::cellShape::cellShape
( (
const word& modelName, const word& modelName,

View File

@ -31,8 +31,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef cellShapeIOList_H #ifndef Foam_cellShapeIOList_H
#define cellShapeIOList_H #define Foam_cellShapeIOList_H
#include "cellShape.H" #include "cellShape.H"
#include "IOList.H" #include "IOList.H"

View File

@ -31,8 +31,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef cellShapeList_H #ifndef Foam_cellShapeList_H
#define cellShapeList_H #define Foam_cellShapeList_H
#include "cellShape.H" #include "cellShape.H"
#include "List.H" #include "List.H"

View File

@ -38,8 +38,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef hexCell_H #ifndef Foam_hexCell_H
#define hexCell_H #define Foam_hexCell_H
#include "FixedList.H" #include "FixedList.H"
#include "faceList.H" #include "faceList.H"

View File

@ -227,9 +227,9 @@ public:
// If the nearest point is on the line, return a hit // If the nearest point is on the line, return a hit
PointHit<Point> nearestDist(const Point& p) const; PointHit<Point> nearestDist(const Point& p) const;
//- Return nearest distance from line to line. Returns distance //- Return nearest distance from line to line.
// and sets both points (one on *this, one on the provided //- Returns distance and sets both points
// linePointRef. //- (one on *this, one on the provided linePointRef.
scalar nearestDist scalar nearestDist
( (
const line<Point, const Point&>& edge, const line<Point, const Point&>& edge,

View File

@ -48,7 +48,6 @@ namespace Foam
{ {
// Forward Declarations // Forward Declarations
class dictionary;
class volumeType; class volumeType;
Istream& operator>>(Istream& is, volumeType& vt); Istream& operator>>(Istream& is, volumeType& vt);
Ostream& operator<<(Ostream& os, const volumeType& vt); Ostream& operator<<(Ostream& os, const volumeType& vt);
@ -113,8 +112,8 @@ public:
// Member Functions // Member Functions
//- Return the enumeration //- Implicit cast to the enumeration
operator type() const operator type() const noexcept
{ {
return t_; return t_;
} }

View File

@ -459,7 +459,7 @@ Foam::scalar Foam::treeBoundBox::maxDist(const point& pt) const
point near, far; point near, far;
calcExtremities(pt, near, far); calcExtremities(pt, near, far);
return Foam::mag(far - pt); return pt.dist(far);
} }
@ -478,14 +478,8 @@ Foam::label Foam::treeBoundBox::distanceCmp
// get nearest and furthest away vertex // get nearest and furthest away vertex
calcExtremities(pt, nearThis, farThis); calcExtremities(pt, nearThis, farThis);
const scalar minDistThis = const scalar minDistThis = pt.distSqr(nearThis);
sqr(nearThis.x() - pt.x()) const scalar maxDistThis = pt.distSqr(farThis);
+ sqr(nearThis.y() - pt.y())
+ sqr(nearThis.z() - pt.z());
const scalar maxDistThis =
sqr(farThis.x() - pt.x())
+ sqr(farThis.y() - pt.y())
+ sqr(farThis.z() - pt.z());
// //
// Distance point <-> other // Distance point <-> other
@ -496,14 +490,8 @@ Foam::label Foam::treeBoundBox::distanceCmp
// get nearest and furthest away vertex // get nearest and furthest away vertex
other.calcExtremities(pt, nearOther, farOther); other.calcExtremities(pt, nearOther, farOther);
const scalar minDistOther = const scalar minDistOther = pt.distSqr(nearOther);
sqr(nearOther.x() - pt.x()) const scalar maxDistOther = pt.distSqr(farOther);
+ sqr(nearOther.y() - pt.y())
+ sqr(nearOther.z() - pt.z());
const scalar maxDistOther =
sqr(farOther.x() - pt.x())
+ sqr(farOther.y() - pt.y())
+ sqr(farOther.z() - pt.z());
// //
// Categorize // Categorize

View File

@ -30,30 +30,37 @@ Class
Description Description
Standard boundBox with extra functionality for use in octree. Standard boundBox with extra functionality for use in octree.
Numbering of corner points is according to octant numbering. Numbering of corner points is according to octant numbering as shown below.
For vertex numbering in the sequence 0 to 7:
On the back plane (z=0): - faces 0 and 1 are x-min and x-max, respectively;
- faces 2 and 3 are y-min and y-max, respectively;
- faces 4 and 5 are z-min and z-max, respectively.
.
\verbatim \verbatim
Y Octant vertex ordering | Hex cell ordering
^ (treeBoundBox) | (boundBox, blockMesh, hexCell)
| |
+--------+ 6 ---- 7 | 7 ---- 6
|2 3| f5 |\ :\ f3 | f5 |\ :\ f3
| | | | 4 ---- 5 \ | | | 4 ---- 5 \
| | | 2.|....3 | \ | | 3.|....2 | \
| | | \| \| f2 | | \| \| f2
|0 1| f4 0 ---- 1 | f4 0 ---- 1
+--------+->X Y Z |
\endverbatim \ | f0 ------ f1 | f0 ------ f1
\| |
For the front plane add 4 to the point labels. o--- X |
\endverbatim
Note Note
When a bounding box is created without any points, it creates an inverted When a bounding box is created without any points, it creates an inverted
bounding box. Points can be added later and the bounding box will grow to bounding box. Points can be added later and the bounding box will grow to
include them. include them.
SeeAlso
Foam::boundBox
SourceFiles SourceFiles
treeBoundBoxI.H treeBoundBoxI.H
treeBoundBox.C treeBoundBox.C
@ -72,7 +79,6 @@ namespace Foam
{ {
// Forward Declarations // Forward Declarations
class Random;
class treeBoundBox; class treeBoundBox;
Istream& operator>>(Istream& is, treeBoundBox& bb); Istream& operator>>(Istream& is, treeBoundBox& bb);
@ -94,37 +100,42 @@ public:
// Enumerations // Enumerations
//- Bits used for octant/point encoding. //- Bits used for octant/point directional encoding.
// Every octant/corner point is the combination of three directions. // Every octant/corner point is the combination of three directions.
// Defined as (1 << vector::components).
enum octantBit : direction enum octantBit : direction
{ {
RIGHTHALF = 0x1, //!< 1: positive x-direction RIGHTHALF = 1, //!< 1: positive x-direction
TOPHALF = 0x2, //!< 2: positive y-direction TOPHALF = 2, //!< 2: positive y-direction
FRONTHALF = 0x4 //!< 4: positive z-direction FRONTHALF = 4 //!< 4: positive z-direction
}; };
//- Face codes. Identical order and meaning as per hex cellmodel //- Face codes. Identical order and meaning as per hex cellmodel
//- and boundBox, but have a different point ordering. //- and boundBox, but have a different point ordering.
enum faceId // Defined as (2 * vector::components + positive).
enum faceId : direction
{ {
LEFT = 0, //!< 0: x-min, left LEFT = 0, //!< 0: x-min face
RIGHT = 1, //!< 1: x-max, right RIGHT = 1, //!< 1: x-max face
BOTTOM = 2, //!< 2: y-min, bottom BOTTOM = 2, //!< 2: y-min face
TOP = 3, //!< 3: y-max, top TOP = 3, //!< 3: y-max face
BACK = 4, //!< 4: z-min, back BACK = 4, //!< 4: z-min face
FRONT = 5 //!< 5: z-max, front FRONT = 5 //!< 5: z-max face
}; };
//- Bits used for face encoding //- Bits used for face encoding.
// Defined as (1 << (2 * vector::components + positive)).
// For example, the positive Z-face:
// (1 << (2 * vector::Z + 1))
enum faceBit : direction enum faceBit : direction
{ {
NOFACE = 0, //!< 0: none NOFACE = 0, //!< 0: none
LEFTBIT = 0x1 << LEFT, //!< 1: x-min, left LEFTBIT = (1 << LEFT), //!< 1: x-min face
RIGHTBIT = 0x1 << RIGHT, //!< 2: x-max, right RIGHTBIT = (1 << RIGHT), //!< 2: x-max face
BOTTOMBIT = 0x1 << BOTTOM, //!< 4: y-min, bottom BOTTOMBIT = (1 << BOTTOM), //!< 4: y-min face
TOPBIT = 0x1 << TOP, //!< 8: y-max, top TOPBIT = (1 << TOP), //!< 8: y-max face
BACKBIT = 0x1 << BACK, //!< 16: z-min, back BACKBIT = (1 << BACK), //!< 16: z-min face
FRONTBIT = 0x1 << FRONT //!< 32: z-max, front FRONTBIT = (1 << FRONT) //!< 32: z-max face
}; };
//- Edges codes. //- Edges codes.
@ -150,13 +161,23 @@ public:
// Static Data Members // Static Data Members
//- Face to point addressing //- Face to point addressing, using octant corner points.
static const faceList faces; static const faceList faces;
//- Edge to point addressing //- Edge to point addressing, using octant corner points.
static const edgeList edges; static const edgeList edges;
// Static Methods
//- The null treeBoundBox is the same as an inverted box
static const treeBoundBox& null() noexcept
{
return
reinterpret_cast<const treeBoundBox&>(boundBox::invertedBox);
}
// Standard (Generated) Methods // Standard (Generated) Methods
//- Default construct: an inverted bounding box //- Default construct: an inverted bounding box
@ -218,14 +239,11 @@ public:
// Access // Access
//- Typical dimension length,height,width
inline scalar typDim() const;
//- Vertex coordinates. In octant coding. //- Vertex coordinates. In octant coding.
tmp<pointField> points() const; tmp<pointField> points() const;
// Check // Octant handling
//- Corner point of given octant //- Corner point of given octant
inline point corner(const direction octant) const; inline point corner(const direction octant) const;
@ -288,6 +306,12 @@ public:
FixedList<direction, 8>& octantOrder FixedList<direction, 8>& octantOrder
) const; ) const;
//- Return optimal search order to look for nearest to point.
inline FixedList<direction, 8> searchOrder(const point& pt) const;
// Check
//- Overlaps with other bounding box, sphere etc? //- Overlaps with other bounding box, sphere etc?
using boundBox::overlaps; using boundBox::overlaps;
@ -376,6 +400,12 @@ public:
friend Istream& operator>>(Istream& is, treeBoundBox& bb); friend Istream& operator>>(Istream& is, treeBoundBox& bb);
friend Ostream& operator<<(Ostream& os, const treeBoundBox& bb); friend Ostream& operator<<(Ostream& os, const treeBoundBox& bb);
// Housekeeping
//- Typical dimension length,height,width. Identical to avgDim()
scalar typDim() const { return avgDim(); }
}; };

View File

@ -57,12 +57,6 @@ inline Foam::treeBoundBox::treeBoundBox(Istream& is)
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::scalar Foam::treeBoundBox::typDim() const
{
return avgDim();
}
inline Foam::point Foam::treeBoundBox::corner(const direction octant) const inline Foam::point Foam::treeBoundBox::corner(const direction octant) const
{ {
return point return point
@ -223,8 +217,6 @@ inline Foam::direction Foam::treeBoundBox::subOctant
} }
// Returns reference to octantOrder which defines the
// order to do the search.
inline void Foam::treeBoundBox::searchOrder inline void Foam::treeBoundBox::searchOrder
( (
const point& pt, const point& pt,
@ -315,6 +307,15 @@ inline void Foam::treeBoundBox::searchOrder
} }
inline Foam::FixedList<Foam::direction, 8>
Foam::treeBoundBox::searchOrder(const point& pt) const
{
FixedList<direction, 8> octantOrder;
searchOrder(pt, octantOrder);
return octantOrder;
}
inline bool Foam::treeBoundBox::intersects inline bool Foam::treeBoundBox::intersects
( (
const linePointRef& ln, const linePointRef& ln,
@ -328,23 +329,12 @@ inline bool Foam::treeBoundBox::intersects
inline Foam::treeBoundBox Foam::treeBoundBox::extend inline Foam::treeBoundBox Foam::treeBoundBox::extend
( (
Random& rndGen, Random& rndGen,
const scalar s const scalar factor
) const ) const
{ {
treeBoundBox bb(*this); treeBoundBox bb(*this);
vector newSpan = bb.span(); bb.inflate(rndGen, factor);
// Make 3D
const scalar minSpan = s * Foam::mag(newSpan);
for (direction dir = 0; dir < vector::nComponents; ++dir)
{
newSpan[dir] = Foam::max(newSpan[dir], minSpan);
}
bb.min() -= cmptMultiply(s*rndGen.sample01<vector>(), newSpan);
bb.max() += cmptMultiply(s*rndGen.sample01<vector>(), newSpan);
return bb; return bb;
} }
@ -357,8 +347,9 @@ inline Foam::treeBoundBox Foam::treeBoundBox::extend
const scalar delta const scalar delta
) const ) const
{ {
treeBoundBox bb(extend(rndGen, factor)); treeBoundBox bb(*this);
bb.grow(delta);
bb.inflate(rndGen, factor, delta);
return bb; return bb;
} }

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.
@ -26,6 +26,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "hexCellFvMesh.H" #include "hexCellFvMesh.H"
#include "hexCell.H"
#include "emptyPolyPatch.H" #include "emptyPolyPatch.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
@ -65,22 +66,10 @@ Foam::simplifiedMeshes::hexCellFvMesh::hexCellFvMesh
IOobject::READ_IF_PRESENT, IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE IOobject::NO_WRITE
), ),
pointField pointField(boundBox(point::zero, point::uniform(d)).hexCorners()),
( faceList(boundBox::hexFaces()),
{ labelList(6, Zero), // Owner
point(0, 0, 0), labelList() // Neighbour
point(d, 0, 0),
point(d, d, 0),
point(0, d, 0),
point(0, 0, d),
point(d, 0, d),
point(d, d, d),
point(0, d, d)
}
),
faceList(cellModel::ref(cellModel::HEX).modelFaces()),
labelList(6, Zero),
labelList()
) )
{ {
polyPatchList patches(1); polyPatchList patches(1);

View File

@ -542,7 +542,7 @@ void Foam::searchableBox::findLineAll
// we need something bigger since we're doing calculations) // we need something bigger since we're doing calculations)
// - if the start-end vector is zero we still progress // - if the start-end vector is zero we still progress
const vectorField dirVec(end-start); const vectorField dirVec(end-start);
const scalarField magSqrDirVec(magSqr(dirVec)); const scalarField magSqrDirVec(Foam::magSqr(dirVec));
const vectorField smallVec const vectorField smallVec
( (
ROOTSMALL*dirVec + vector::uniform(ROOTVSMALL) ROOTSMALL*dirVec + vector::uniform(ROOTVSMALL)
@ -630,24 +630,16 @@ void Foam::searchableBox::getVolumeType
List<volumeType>& volType List<volumeType>& volType
) const ) const
{ {
volType.setSize(points.size()); volType.resize_nocopy(points.size());
forAll(points, pointi) forAll(points, pointi)
{ {
const point& pt = points[pointi]; volType[pointi] =
(
volumeType vt = volumeType::INSIDE; treeBoundBox::contains(points[pointi])
? volumeType::INSIDE
for (direction dir=0; dir < vector::nComponents; ++dir) : volumeType::OUTSIDE
{ );
if (pt[dir] < min()[dir] || pt[dir] > max()[dir])
{
vt = volumeType::OUTSIDE;
break;
}
}
volType[pointi] = vt;
} }
} }

View File

@ -51,8 +51,8 @@ SourceFiles
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#ifndef searchableBox_H #ifndef Foam_searchableBox_H
#define searchableBox_H #define Foam_searchableBox_H
#include "searchableSurface.H" #include "searchableSurface.H"
#include "treeBoundBox.H" #include "treeBoundBox.H"

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
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.
@ -28,7 +28,7 @@ License
#include "rotatedBoxToCell.H" #include "rotatedBoxToCell.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "cellModel.H" #include "hexCell.H"
#include "addToRunTimeSelectionTable.H" #include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -71,22 +71,18 @@ Foam::topoSetSource::addToUsageTable Foam::rotatedBoxToCell::usage_
void Foam::rotatedBoxToCell::combine(topoSet& set, const bool add) const void Foam::rotatedBoxToCell::combine(topoSet& set, const bool add) const
{ {
// Define a cell for the box // Define a cell for the box
pointField boxPoints(8); pointField boxPoints(8, origin_);
boxPoints[0] = origin_; // boxPoints[0] = origin_;
boxPoints[1] = origin_ + i_; boxPoints[1] += i_;
boxPoints[2] = origin_ + i_ + j_; boxPoints[2] += i_ + j_;
boxPoints[3] = origin_ + j_; boxPoints[3] += j_;
boxPoints[4] = origin_ + k_; boxPoints[4] += k_;
boxPoints[5] = origin_ + k_ + i_; boxPoints[5] += k_ + i_;
boxPoints[6] = origin_ + k_ + i_ + j_; boxPoints[6] += k_ + i_ + j_;
boxPoints[7] = origin_ + k_ + j_; boxPoints[7] += k_ + j_;
labelList boxVerts(identity(8));
const cellModel& hex = cellModel::ref(cellModel::HEX);
// Get outwards pointing faces. // Get outwards pointing faces.
faceList boxFaces(cellShape(hex, boxVerts).faces()); faceList boxFaces(hexCell::modelFaces());
// Precalculate normals // Precalculate normals
vectorField boxFaceNormals(boxFaces.size()); vectorField boxFaceNormals(boxFaces.size());

View File

@ -496,8 +496,6 @@ Foam::autoPtr<Foam::fvMesh> Foam::voxelMeshSearch::makeMesh
const IOobject& io const IOobject& io
) const ) const
{ {
const cellModel& hex = cellModel::ref(cellModel::HEX);
cellShapeList cellShapes; cellShapeList cellShapes;
faceListList boundary; faceListList boundary;
pointField points; pointField points;
@ -506,7 +504,7 @@ Foam::autoPtr<Foam::fvMesh> Foam::voxelMeshSearch::makeMesh
block b block b
( (
cellShape(hex, identity(8)), cellShape(cellModel::HEX, identity(8)),
localBb_.points(), localBb_.points(),
blockEdgeList(), blockEdgeList(),
blockFaceList(), blockFaceList(),