Add the OpenFOAM source tree

This commit is contained in:
Henry
2014-12-10 22:40:10 +00:00
parent ee487c860d
commit 446e5777f0
13379 changed files with 3983377 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,693 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::dynamicIndexedOctree
Description
Non-pointer based hierarchical recursive searching.
Storage is dynamic, so elements can be deleted.
SourceFiles
dynamicIndexedOctree.C
\*---------------------------------------------------------------------------*/
#ifndef dynamicIndexedOctree_H
#define dynamicIndexedOctree_H
#include "treeBoundBox.H"
#include "pointIndexHit.H"
#include "FixedList.H"
#include "Ostream.H"
#include "HashSet.H"
#include "labelBits.H"
#include "PackedList.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef DynamicList<autoPtr<DynamicList<label > > > contentListList;
// Forward declaration of classes
template<class Type> class dynamicIndexedOctree;
template<class Type> Ostream& operator<<
(
Ostream&,
const dynamicIndexedOctree<Type>&
);
class Istream;
/*---------------------------------------------------------------------------*\
Class dynamicIndexedOctreeName Declaration
\*---------------------------------------------------------------------------*/
TemplateName(dynamicIndexedOctree);
/*---------------------------------------------------------------------------*\
Class dynamicIndexedOctree Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class dynamicIndexedOctree
:
public dynamicIndexedOctreeName
{
public:
// Data types
//- Tree node. Has up pointer and down pointers.
class node
{
public:
//- Bounding box of this node
treeBoundBox bb_;
//- parent node (index into nodes_ of tree)
label parent_;
//- IDs of the 8 nodes on all sides of the mid point
FixedList<labelBits, 8> subNodes_;
friend Ostream& operator<< (Ostream& os, const node& n)
{
return os << n.bb_ << token::SPACE
<< n.parent_ << token::SPACE << n.subNodes_;
}
friend Istream& operator>> (Istream& is, node& n)
{
return is >> n.bb_ >> n.parent_ >> n.subNodes_;
}
friend bool operator==(const node& a, const node& b)
{
return
a.bb_ == b.bb_
&& a.parent_ == b.parent_
&& a.subNodes_ == b.subNodes_;
}
friend bool operator!=(const node& a, const node& b)
{
return !(a == b);
}
};
private:
// Static data
//- Relative peturbation tolerance. Determines when point is
// considered to be close to face/edge of bb of node.
// The tolerance is relative to the bounding box of the smallest
// node.
static scalar perturbTol_;
// Private data
//- Underlying shapes for geometric queries.
const Type shapes_;
const treeBoundBox bb_;
const label maxLevels_;
//- Current number of levels in the tree.
label nLevelsMax_;
const scalar maxLeafRatio_;
const label minSize_;
const scalar maxDuplicity_;
//- List of all nodes
DynamicList<node> nodes_;
//- List of all contents (referenced by those nodes that are contents)
contentListList contents_;
//- Per node per octant whether is fully inside/outside/mixed.
mutable PackedList<2> nodeTypes_;
// Private Member Functions
//- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample.
// (bb is implicitly provided as parent bb + octant)
static bool overlaps
(
const treeBoundBox& parentBb,
const direction octant,
const scalar nearestDistSqr,
const point& sample
);
// Construction
//- Split list of indices into 8 bins
// according to where they are in relation to mid.
void divide
(
const autoPtr<DynamicList<label> >& indices,
const treeBoundBox& bb,
contentListList& result
) const;
//- Subdivide the contents node at position contentI.
// Appends to contents.
node divide
(
const treeBoundBox& bb,
const label contentI,
const label parentNodeIndex,
const label octantToBeDivided
);
// Recursively call the divide function
void recursiveSubDivision
(
const treeBoundBox& subBb,
const label contentI,
const label parentIndex,
const label octant,
label& nLevels
);
// static label compactContents
// (
// DynamicList<node>& nodes,
// DynamicList<labelList>& contents,
// const label compactLevel,
// const label nodeI,
// const label level,
// List<labelList>& compactedContents,
// label& compactI
// );
//- Determine inside/outside per node (mixed if cannot be
// determined). Only valid for closed shapes.
volumeType calcVolumeType(const label nodeI) const;
//- Search cached volume type.
volumeType getVolumeType(const label nodeI, const point&) const;
// Query
//- Find nearest point to line.
void findNearest
(
const label nodeI,
const linePointRef& ln,
treeBoundBox& tightest,
label& nearestShapeI,
point& linePoint,
point& nearestPoint
) const;
//- Return bbox of octant
treeBoundBox subBbox
(
const label parentNodeI,
const direction octant
) const;
//- Helper: take a point on/close to face of bb and push it
// inside or outside of bb.
static point pushPoint
(
const treeBoundBox&,
const point&,
const bool pushInside
);
//- Helper: take a point on face of bb and push it
// inside or outside of bb.
static point pushPoint
(
const treeBoundBox&,
const direction,
const point&,
const bool pushInside
);
//- Helper: take point on face(s) of bb and push it away from
// edges of face.
static point pushPointIntoFace
(
const treeBoundBox& bb,
const vector& dir, // end-start
const point& pt
);
////- Push point on multiple faces away from any corner/edge.
//static void checkMultipleFaces
//(
// const treeBoundBox& bb,
// const vector& dir, // end-start
// pointIndexHit& faceHitInfo,
// direction& faceID
//);
//- Walk to parent of node+octant.
bool walkToParent
(
const label nodeI,
const direction octant,
label& parentNodeI,
label& parentOctant
) const;
//- Walk tree to neighbouring node. Return false if edge of tree
// hit.
bool walkToNeighbour
(
const point& facePoint,
const direction faceID, // direction to walk in
label& nodeI,
direction& octant
) const;
//- Debug: return verbose the bounding box faces
static word faceString(const direction faceID);
//- Traverse a node. If intersects a triangle return first
// intersection point.
// findAny=true : return any intersection
// findAny=false: return nearest (to start) intersection
void traverseNode
(
const bool findAny,
const point& treeStart,
const vector& treeVec,
const point& start,
const point& end,
const label nodeI,
const direction octantI,
pointIndexHit& hitInfo,
direction& faceID
) const;
//- Find any or nearest intersection
pointIndexHit findLine
(
const bool findAny,
const point& treeStart,
const point& treeEnd,
const label startNodeI,
const direction startOctantI,
const bool verbose = false
) const;
//- Find any or nearest intersection of line between start and end.
pointIndexHit findLine
(
const bool findAny,
const point& start,
const point& end
) const;
//- Find all elements intersecting box.
void findBox
(
const label nodeI,
const treeBoundBox& searchBox,
labelHashSet& elements
) const;
//- Find all elements intersecting sphere.
void findSphere
(
const label nodeI,
const point& centre,
const scalar radiusSqr,
labelHashSet& elements
) const;
template<class CompareOp>
static void findNear
(
const scalar nearDist,
const bool okOrder,
const dynamicIndexedOctree<Type>& tree1,
const labelBits index1,
const treeBoundBox& bb1,
const dynamicIndexedOctree<Type>& tree2,
const labelBits index2,
const treeBoundBox& bb2,
CompareOp& cop
);
// Other
//- Count number of elements on this and sublevels
label countElements(const labelBits index) const;
//- Dump node+octant to an obj file
void writeOBJ(const label nodeI, const direction octant) const;
//- From index into contents_ to subNodes_ entry
static labelBits contentPlusOctant
(
const label i,
const direction octant
)
{
return labelBits(-i - 1, octant);
}
//- From index into nodes_ to subNodes_ entry
static labelBits nodePlusOctant
(
const label i,
const direction octant
)
{
return labelBits(i + 1, octant);
}
//- From empty to subNodes_ entry
static labelBits emptyPlusOctant
(
const direction octant
)
{
return labelBits(0, octant);
}
public:
//- Get the perturbation tolerance
static scalar& perturbTol();
// Constructors
//- Construct from shapes
dynamicIndexedOctree
(
const Type& shapes,
const treeBoundBox& bb,
const label maxLevels, // maximum number of levels
const scalar maxLeafRatio, // how many elements per leaf
const scalar maxDuplicity // in how many leaves is a shape on
// average
);
//- Clone
autoPtr<dynamicIndexedOctree<Type> > clone() const
{
return autoPtr<dynamicIndexedOctree<Type> >
(
new dynamicIndexedOctree<Type>(*this)
);
}
// Member Functions
// Access
//- Reference to shape
const Type& shapes() const
{
return shapes_;
}
//- List of all nodes
const List<node>& nodes() const
{
return nodes_;
}
//- List of all contents (referenced by those nodes that are
// contents)
const contentListList& contents() const
{
return contents_;
}
//- Top bounding box
const treeBoundBox& bb() const
{
if (nodes_.empty())
{
FatalErrorIn("dynamicIndexedOctree<Type>::bb() const")
<< "Tree is empty" << abort(FatalError);
}
return nodes_[0].bb_;
}
// Conversions for entries in subNodes_.
static bool isContent(const labelBits i)
{
return i.val() < 0;
}
static bool isEmpty(const labelBits i)
{
return i.val() == 0;
}
static bool isNode(const labelBits i)
{
return i.val() > 0;
}
static label getContent(const labelBits i)
{
if (!isContent(i))
{
FatalErrorIn("getContent(const label)")
<< abort(FatalError);
}
return -i.val()-1;
}
static label getNode(const labelBits i)
{
if (!isNode(i))
{
FatalErrorIn("getNode(const label)")
<< abort(FatalError);
}
return i.val() - 1;
}
static direction getOctant(const labelBits i)
{
return i.bits();
}
// Queries
//- Calculate nearest point on nearest shape.
// Returns
// - bool : any point found nearer than nearestDistSqr
// - label: index in shapes
// - point: actual nearest point found
pointIndexHit findNearest
(
const point& sample,
const scalar nearestDistSqr
) const;
//- Low level: calculate nearest starting from subnode.
void findNearest
(
const label nodeI,
const point&,
scalar& nearestDistSqr,
label& nearestShapeI,
point& nearestPoint
) const;
//- Find nearest to line.
// Returns
// - bool : any point found?
// - label: index in shapes
// - point: actual nearest point found
// sets:
// - linePoint : corresponding nearest point on line
pointIndexHit findNearest
(
const linePointRef& ln,
treeBoundBox& tightest,
point& linePoint
) const;
//- Find nearest intersection of line between start and end.
pointIndexHit findLine
(
const point& start,
const point& end
) const;
//- Find any intersection of line between start and end.
pointIndexHit findLineAny
(
const point& start,
const point& end
) const;
//- Find (in no particular order) indices of all shapes inside or
// overlapping bounding box (i.e. all shapes not outside box)
labelList findBox(const treeBoundBox& bb) const;
//- Find (in no particular order) indices of all shapes inside or
// overlapping a bounding sphere (i.e. all shapes not outside
// sphere)
labelList findSphere
(
const point& centre,
const scalar radiusSqr
) const;
//- Find deepest node (as parent+octant) containing point. Starts
// off from starting index in nodes_ (use 0 to start from top)
// Use getNode and getOctant to extract info, or call findIndices.
labelBits findNode(const label nodeI, const point&) const;
//- Find shape containing point. Only implemented for certain
// shapes.
label findInside(const point&) const;
//- Find the shape indices that occupy the result of findNode
const labelList& findIndices(const point&) const;
//- Determine type (inside/outside/mixed) for point. unknown if
// cannot be determined (e.g. non-manifold surface)
volumeType getVolumeType(const point&) const;
//- Helper function to return the side. Returns outside if
// outsideNormal&vec >= 0, inside otherwise
static volumeType getSide
(
const vector& outsideNormal,
const vector& vec
);
//- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample.
static bool overlaps
(
const point& bbMin,
const point& bbMax,
const scalar nearestDistSqr,
const point& sample
);
//- Find near pairs and apply CompareOp to them.
// tree2 can be *this or different tree.
template<class CompareOp>
void findNear
(
const scalar nearDist,
const dynamicIndexedOctree<Type>& tree2,
CompareOp& cop
) const;
// Edit
//- Insert a new object into the tree.
bool insert(label startIndex, label endIndex);
bool insertIndex
(
const label nodIndex,
const label index,
label& nLevels
);
//- Remove an object from the tree.
bool remove(const label index);
label removeIndex(const label nodIndex, const label index);
// Write
//- Print tree. Either print all indices (printContent = true) or
// just size of contents nodes.
void print
(
prefixOSstream&,
const bool printContents,
const label
) const;
bool write(Ostream& os) const;
void writeTreeInfo() const;
// IOstream Operators
friend Ostream& operator<< <Type>
(
Ostream&,
const dynamicIndexedOctree<Type>&
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "dynamicIndexedOctree.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "dynamicIndexedOctree.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(dynamicIndexedOctreeName, 0);
}
// ************************************************************************* //

View File

@ -0,0 +1,187 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "dynamicTreeDataPoint.H"
#include "treeBoundBox.H"
#include "dynamicIndexedOctree.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(dynamicTreeDataPoint, 0);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dynamicTreeDataPoint::dynamicTreeDataPoint
(
const DynamicList<point>& points
)
:
points_(points)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::DynamicList<Foam::point>&
Foam::dynamicTreeDataPoint::shapePoints() const
{
return points_;
}
//- Get type (inside,outside,mixed,unknown) of point w.r.t. surface.
// Only makes sense for closed surfaces.
Foam::volumeType Foam::dynamicTreeDataPoint::getVolumeType
(
const dynamicIndexedOctree<dynamicTreeDataPoint>& oc,
const point& sample
) const
{
return volumeType::UNKNOWN;
}
// Check if any point on shape is inside cubeBb.
bool Foam::dynamicTreeDataPoint::overlaps
(
const label index,
const treeBoundBox& cubeBb
) const
{
return cubeBb.contains(points_[index]);
}
// Check if any point on shape is inside sphere.
bool Foam::dynamicTreeDataPoint::overlaps
(
const label index,
const point& centre,
const scalar radiusSqr
) const
{
const point& p = points_[index];
const scalar distSqr = magSqr(p - centre);
if (distSqr <= radiusSqr)
{
return true;
}
return false;
}
// Calculate nearest point to sample. Updates (if any) nearestDistSqr, minIndex,
// nearestPoint.
void Foam::dynamicTreeDataPoint::findNearest
(
const labelUList& indices,
const point& sample,
scalar& nearestDistSqr,
label& minIndex,
point& nearestPoint
) const
{
forAll(indices, i)
{
const label index = indices[i];
const point& pt = points_[index];
scalar distSqr = magSqr(pt - sample);
if (distSqr < nearestDistSqr)
{
nearestDistSqr = distSqr;
minIndex = index;
nearestPoint = pt;
}
}
}
//- Calculates nearest (to line) point in shape.
// Returns point and distance (squared)
void Foam::dynamicTreeDataPoint::findNearest
(
const labelUList& indices,
const linePointRef& ln,
treeBoundBox& tightest,
label& minIndex,
point& linePoint,
point& nearestPoint
) const
{
// Best so far
scalar nearestDistSqr = magSqr(linePoint - nearestPoint);
forAll(indices, i)
{
const label index = indices[i];
const point& shapePt = points_[index];
if (tightest.contains(shapePt))
{
// Nearest point on line
pointHit pHit = ln.nearestDist(shapePt);
scalar distSqr = sqr(pHit.distance());
if (distSqr < nearestDistSqr)
{
nearestDistSqr = distSqr;
minIndex = index;
linePoint = pHit.rawPoint();
nearestPoint = shapePt;
{
point& minPt = tightest.min();
minPt = min(ln.start(), ln.end());
minPt.x() -= pHit.distance();
minPt.y() -= pHit.distance();
minPt.z() -= pHit.distance();
}
{
point& maxPt = tightest.max();
maxPt = max(ln.start(), ln.end());
maxPt.x() += pHit.distance();
maxPt.y() += pHit.distance();
maxPt.z() += pHit.distance();
}
}
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,172 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2012-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::dynamicTreeDataPoint
Description
Holds (reference to) pointField. Encapsulation of data needed for
octree searches.
Used for searching for nearest point. No bounding boxes around points.
Only overlaps and calcNearest are implemented, rest makes little sense.
Optionally works on subset of points.
SourceFiles
dynamicTreeDataPoint.C
\*---------------------------------------------------------------------------*/
#ifndef dynamicTreeDataPoint_H
#define dynamicTreeDataPoint_H
#include "pointField.H"
#include "treeBoundBox.H"
#include "linePointRef.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
template<class Type> class dynamicIndexedOctree;
/*---------------------------------------------------------------------------*\
Class dynamicTreeDataPoint Declaration
\*---------------------------------------------------------------------------*/
class dynamicTreeDataPoint
{
// Private data
const DynamicList<point>& points_;
public:
// Declare name of the class and its debug switch
ClassName("dynamicTreeDataPoint");
// Constructors
//- Construct from List. Holds reference!
dynamicTreeDataPoint(const DynamicList<point>& points);
// Member Functions
// Access
inline label size() const
{
return points_.size();
}
//- Get representative point cloud for all shapes inside
// (one point per shape)
const DynamicList<point>& shapePoints() const;
// Search
//- Get type (inside,outside,mixed,unknown) of point w.r.t. surface.
// Only makes sense for closed surfaces.
volumeType getVolumeType
(
const dynamicIndexedOctree<dynamicTreeDataPoint>&,
const point&
) const;
//- Does (bb of) shape at index overlap bb
bool overlaps
(
const label index,
const treeBoundBox& sampleBb
) const;
//- Check if any point on shape is inside sphere.
bool overlaps
(
const label index,
const point& centre,
const scalar radiusSqr
) const;
//- Calculates nearest (to sample) point in shape.
// Returns actual point and distance (squared)
void findNearest
(
const labelUList& indices,
const point& sample,
scalar& nearestDistSqr,
label& nearestIndex,
point& nearestPoint
) const;
//- Calculates nearest (to line) point in shape.
// Returns point and distance (squared)
void findNearest
(
const labelUList& indices,
const linePointRef& ln,
treeBoundBox& tightest,
label& minIndex,
point& linePoint,
point& nearestPoint
) const;
//- Calculate intersection of shape with ray. Sets result
// accordingly
bool intersects
(
const label index,
const point& start,
const point& end,
point& result
) const
{
notImplemented
(
"dynamicTreeDataPoint::intersects"
"(const label, const point&, const point&, point&)"
);
return false;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,707 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::indexedOctree
Description
Non-pointer based hierarchical recursive searching
SourceFiles
indexedOctree.C
\*---------------------------------------------------------------------------*/
#ifndef indexedOctree_H
#define indexedOctree_H
#include "treeBoundBox.H"
#include "pointIndexHit.H"
#include "FixedList.H"
#include "Ostream.H"
#include "HashSet.H"
#include "labelBits.H"
#include "PackedList.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
template<class Type> class indexedOctree;
template<class Type> Ostream& operator<<(Ostream&, const indexedOctree<Type>&);
class Istream;
/*---------------------------------------------------------------------------*\
Class indexedOctreeName Declaration
\*---------------------------------------------------------------------------*/
TemplateName(indexedOctree);
/*---------------------------------------------------------------------------*\
Class indexedOctree Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class indexedOctree
:
public indexedOctreeName
{
public:
// Data types
//- Tree node. Has up pointer and down pointers.
class node
{
public:
//- Bounding box of this node
treeBoundBox bb_;
//- parent node (index into nodes_ of tree)
label parent_;
//- IDs of the 8 nodes on all sides of the mid point
FixedList<labelBits, 8> subNodes_;
friend Ostream& operator<< (Ostream& os, const node& n)
{
return os << n.bb_ << token::SPACE
<< n.parent_ << token::SPACE << n.subNodes_;
}
friend Istream& operator>> (Istream& is, node& n)
{
return is >> n.bb_ >> n.parent_ >> n.subNodes_;
}
friend bool operator==(const node& a, const node& b)
{
return
a.bb_ == b.bb_
&& a.parent_ == b.parent_
&& a.subNodes_ == b.subNodes_;
}
friend bool operator!=(const node& a, const node& b)
{
return !(a == b);
}
};
private:
// Static data
//- Relative peturbation tolerance. Determines when point is
// considered to be close to face/edge of bb of node.
// The tolerance is relative to the bounding box of the smallest
// node.
static scalar perturbTol_;
// Private data
//- Underlying shapes for geometric queries.
const Type shapes_;
//- List of all nodes
List<node> nodes_;
//- List of all contents (referenced by those nodes that are contents)
labelListList contents_;
//- Per node per octant whether is fully inside/outside/mixed.
mutable PackedList<2> nodeTypes_;
// Private Member Functions
//- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample.
// (bb is implicitly provided as parent bb + octant)
static bool overlaps
(
const treeBoundBox& parentBb,
const direction octant,
const scalar nearestDistSqr,
const point& sample
);
// Construction
//- Split list of indices into 8 bins
// according to where they are in relation to mid.
void divide
(
const labelList& indices,
const treeBoundBox& bb,
labelListList& result
) const;
//- Subdivide the contents node at position contentI.
// Appends to contents.
node divide
(
const treeBoundBox& bb,
DynamicList<labelList>& contents,
const label contentI
) const;
//- Split any contents node with more than minSize elements.
void splitNodes
(
const label minSize,
DynamicList<node>& nodes,
DynamicList<labelList>& contents
) const;
static label compactContents
(
DynamicList<node>& nodes,
DynamicList<labelList>& contents,
const label compactLevel,
const label nodeI,
const label level,
List<labelList>& compactedContents,
label& compactI
);
//- Determine inside/outside per node (mixed if cannot be
// determined). Only valid for closed shapes.
volumeType calcVolumeType(const label nodeI) const;
//- Search cached volume type.
volumeType getVolumeType(const label nodeI, const point&) const;
// Query
//- Find nearest point to line.
template<class FindNearestOp>
void findNearest
(
const label nodeI,
const linePointRef& ln,
treeBoundBox& tightest,
label& nearestShapeI,
point& linePoint,
point& nearestPoint,
const FindNearestOp& fnOp
) const;
//- Return bbox of octant
treeBoundBox subBbox
(
const label parentNodeI,
const direction octant
) const;
//- Helper: take a point on/close to face of bb and push it
// inside or outside of bb.
static point pushPoint
(
const treeBoundBox&,
const point&,
const bool pushInside
);
//- Helper: take a point on face of bb and push it
// inside or outside of bb.
static point pushPoint
(
const treeBoundBox&,
const direction,
const point&,
const bool pushInside
);
//- Helper: take point on face(s) of bb and push it away from
// edges of face.
static point pushPointIntoFace
(
const treeBoundBox& bb,
const vector& dir, // end-start
const point& pt
);
////- Push point on multiple faces away from any corner/edge.
//static void checkMultipleFaces
//(
// const treeBoundBox& bb,
// const vector& dir, // end-start
// pointIndexHit& faceHitInfo,
// direction& faceID
//);
//- Walk to parent of node+octant.
bool walkToParent
(
const label nodeI,
const direction octant,
label& parentNodeI,
label& parentOctant
) const;
//- Walk tree to neighbouring node. Return false if edge of tree
// hit.
bool walkToNeighbour
(
const point& facePoint,
const direction faceID, // direction to walk in
label& nodeI,
direction& octant
) const;
//- Debug: return verbose the bounding box faces
static word faceString(const direction faceID);
//- Traverse a node. If intersects a triangle return first
// intersection point.
// findAny=true : return any intersection
// findAny=false: return nearest (to start) intersection
template<class FindIntersectOp>
void traverseNode
(
const bool findAny,
const point& treeStart,
const vector& treeVec,
const point& start,
const point& end,
const label nodeI,
const direction octantI,
pointIndexHit& hitInfo,
direction& faceID,
const FindIntersectOp& fiOp
) const;
//- Find any or nearest intersection
template<class FindIntersectOp>
pointIndexHit findLine
(
const bool findAny,
const point& treeStart,
const point& treeEnd,
const label startNodeI,
const direction startOctantI,
const FindIntersectOp& fiOp,
const bool verbose = false
) const;
//- Find any or nearest intersection of line between start and end.
template<class FindIntersectOp>
pointIndexHit findLine
(
const bool findAny,
const point& start,
const point& end,
const FindIntersectOp& fiOp
) const;
//- Find all elements intersecting box.
void findBox
(
const label nodeI,
const treeBoundBox& searchBox,
labelHashSet& elements
) const;
//- Find all elements intersecting sphere.
void findSphere
(
const label nodeI,
const point& centre,
const scalar radiusSqr,
labelHashSet& elements
) const;
template<class CompareOp>
static void findNear
(
const scalar nearDist,
const bool okOrder,
const indexedOctree<Type>& tree1,
const labelBits index1,
const treeBoundBox& bb1,
const indexedOctree<Type>& tree2,
const labelBits index2,
const treeBoundBox& bb2,
CompareOp& cop
);
// Other
//- Count number of elements on this and sublevels
label countElements(const labelBits index) const;
//- Dump node+octant to an obj file
void writeOBJ(const label nodeI, const direction octant) const;
//- From index into contents_ to subNodes_ entry
static labelBits contentPlusOctant
(
const label i,
const direction octant
)
{
return labelBits(-i - 1, octant);
}
//- From index into nodes_ to subNodes_ entry
static labelBits nodePlusOctant
(
const label i,
const direction octant
)
{
return labelBits(i + 1, octant);
}
//- From empty to subNodes_ entry
static labelBits emptyPlusOctant
(
const direction octant
)
{
return labelBits(0, octant);
}
public:
//- Get the perturbation tolerance
static scalar& perturbTol();
// Constructors
//- Construct null
indexedOctree(const Type& shapes);
//- Construct from components
indexedOctree
(
const Type& shapes,
const List<node>& nodes,
const labelListList& contents
);
//- Construct from shapes
indexedOctree
(
const Type& shapes,
const treeBoundBox& bb,
const label maxLevels, // maximum number of levels
const scalar maxLeafRatio, // how many elements per leaf
const scalar maxDuplicity // in how many leaves is a shape on
// average
);
//- Construct from Istream
indexedOctree(const Type& shapes, Istream& is);
//- Clone
autoPtr<indexedOctree<Type> > clone() const
{
return autoPtr<indexedOctree<Type> >
(
new indexedOctree<Type>(*this)
);
}
// Member Functions
// Access
//- Reference to shape
const Type& shapes() const
{
return shapes_;
}
//- List of all nodes
const List<node>& nodes() const
{
return nodes_;
}
//- List of all contents (referenced by those nodes that are
// contents)
const labelListList& contents() const
{
return contents_;
}
//- Top bounding box
const treeBoundBox& bb() const
{
if (nodes_.empty())
{
FatalErrorIn("indexedOctree<Type>::bb() const")
<< "Tree is empty" << abort(FatalError);
}
return nodes_[0].bb_;
}
// Conversions for entries in subNodes_.
static bool isContent(const labelBits i)
{
return i.val() < 0;
}
static bool isEmpty(const labelBits i)
{
return i.val() == 0;
}
static bool isNode(const labelBits i)
{
return i.val() > 0;
}
static label getContent(const labelBits i)
{
if (!isContent(i))
{
FatalErrorIn("getContent(const label)")
<< abort(FatalError);
}
return -i.val()-1;
}
static label getNode(const labelBits i)
{
if (!isNode(i))
{
FatalErrorIn("getNode(const label)")
<< abort(FatalError);
}
return i.val() - 1;
}
static direction getOctant(const labelBits i)
{
return i.bits();
}
// Queries
pointIndexHit findNearest
(
const point& sample,
const scalar nearestDistSqr
) const;
//- Calculate nearest point on nearest shape.
// Returns
// - bool : any point found nearer than nearestDistSqr
// - label: index in shapes
// - point: actual nearest point found
template<class FindNearestOp>
pointIndexHit findNearest
(
const point& sample,
const scalar nearestDistSqr,
const FindNearestOp& fnOp
) const;
//- Low level: calculate nearest starting from subnode.
template<class FindNearestOp>
void findNearest
(
const label nodeI,
const point&,
scalar& nearestDistSqr,
label& nearestShapeI,
point& nearestPoint,
const FindNearestOp& fnOp
) const;
//- Find nearest to line.
// Returns
// - bool : any point found?
// - label: index in shapes
// - point: actual nearest point found
// sets:
// - linePoint : corresponding nearest point on line
pointIndexHit findNearest
(
const linePointRef& ln,
treeBoundBox& tightest,
point& linePoint
) const;
template<class FindNearestOp>
pointIndexHit findNearest
(
const linePointRef& ln,
treeBoundBox& tightest,
point& linePoint,
const FindNearestOp& fnOp
) const;
//- Find nearest intersection of line between start and end.
pointIndexHit findLine
(
const point& start,
const point& end
) const;
//- Find any intersection of line between start and end.
pointIndexHit findLineAny
(
const point& start,
const point& end
) const;
//- Find nearest intersection of line between start and end.
template<class FindIntersectOp>
pointIndexHit findLine
(
const point& start,
const point& end,
const FindIntersectOp& fiOp
) const;
//- Find any intersection of line between start and end.
template<class FindIntersectOp>
pointIndexHit findLineAny
(
const point& start,
const point& end,
const FindIntersectOp& fiOp
) const;
//- Find (in no particular order) indices of all shapes inside or
// overlapping bounding box (i.e. all shapes not outside box)
labelList findBox(const treeBoundBox& bb) const;
//- Find (in no particular order) indices of all shapes inside or
// overlapping a bounding sphere (i.e. all shapes not outside
// sphere)
labelList findSphere
(
const point& centre,
const scalar radiusSqr
) const;
//- Find deepest node (as parent+octant) containing point. Starts
// off from starting index in nodes_ (use 0 to start from top)
// Use getNode and getOctant to extract info, or call findIndices.
labelBits findNode(const label nodeI, const point&) const;
//- Find shape containing point. Only implemented for certain
// shapes.
label findInside(const point&) const;
//- Find the shape indices that occupy the result of findNode
const labelList& findIndices(const point&) const;
//- Determine type (inside/outside/mixed) for point. unknown if
// cannot be determined (e.g. non-manifold surface)
volumeType getVolumeType(const point&) const;
//- Helper function to return the side. Returns outside if
// outsideNormal&vec >= 0, inside otherwise
static volumeType getSide
(
const vector& outsideNormal,
const vector& vec
);
//- Helper: does bb intersect a sphere around sample? Or is any
// corner point of bb closer than nearestDistSqr to sample.
static bool overlaps
(
const point& bbMin,
const point& bbMax,
const scalar nearestDistSqr,
const point& sample
);
//- Find near pairs and apply CompareOp to them.
// tree2 can be *this or different tree.
template<class CompareOp>
void findNear
(
const scalar nearDist,
const indexedOctree<Type>& tree2,
CompareOp& cop
) const;
// Write
//- Print tree. Either print all indices (printContent = true) or
// just size of contents nodes.
void print
(
prefixOSstream&,
const bool printContents,
const label
) const;
bool write(Ostream& os) const;
// IOstream Operators
friend Ostream& operator<< <Type>(Ostream&, const indexedOctree<Type>&);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "indexedOctree.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "indexedOctree.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(indexedOctreeName, 0);
}
// ************************************************************************* //

View File

@ -0,0 +1,155 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::labelBits
Description
A 29bits label and 3bits direction packed into single label
SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef labelBits_H
#define labelBits_H
#include "label.H"
//#include "uLabel.H"
#include "direction.H"
#include "error.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class labelBits Declaration
\*---------------------------------------------------------------------------*/
class labelBits
{
// Private data
label data_;
inline static label pack(const label val, const direction bits)
{
# ifdef FULLDEBUG
if (bits > 7 || (((val<<3)>>3) != val))
{
FatalErrorIn
(
"labelBits::pack(const label, const direction)"
) << "Direction " << bits << " outside range 0..7"
<< " or value " << val << " negative or larger than "
<< label(8*sizeof(label)-3) << " bit representation"
<< abort(FatalError);
}
# endif
return (val<<3) | bits;
}
public:
// Constructors
//- Construct null
inline labelBits()
{}
//- Construct from components
inline labelBits(const label val, const direction bits)
:
data_(pack(val, bits))
{}
//- Construct from Istream
inline labelBits(Istream& is)
{
is >> data_;
}
// Member Functions
inline label val() const
{
return data_ >> 3;
}
inline direction bits() const
{
return data_ & 7;
}
inline void setVal(const label val)
{
data_ = pack(val, bits());
}
inline void setBits(const direction bits)
{
data_ = pack(val(), bits);
}
// Member Operators
inline friend bool operator==(const labelBits& a, const labelBits& b)
{
return a.data_ == b.data_;
}
inline friend bool operator!=(const labelBits& a, const labelBits& b)
{
return !(a == b);
}
// IOstream Operators
inline friend Istream& operator>>(Istream& is, labelBits& lb)
{
return is >> lb.data_;
}
inline friend Ostream& operator<<(Ostream& os, const labelBits& lb)
{
return os << lb.data_;
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,325 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "treeDataCell.H"
#include "indexedOctree.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(treeDataCell, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::treeBoundBox Foam::treeDataCell::calcCellBb(const label cellI) const
{
const cellList& cells = mesh_.cells();
const faceList& faces = mesh_.faces();
const pointField& points = mesh_.points();
treeBoundBox cellBb
(
vector(GREAT, GREAT, GREAT),
vector(-GREAT, -GREAT, -GREAT)
);
const cell& cFaces = cells[cellI];
forAll(cFaces, cFaceI)
{
const face& f = faces[cFaces[cFaceI]];
forAll(f, fp)
{
const point& p = points[f[fp]];
cellBb.min() = min(cellBb.min(), p);
cellBb.max() = max(cellBb.max(), p);
}
}
return cellBb;
}
void Foam::treeDataCell::update()
{
if (cacheBb_)
{
bbs_.setSize(cellLabels_.size());
forAll(cellLabels_, i)
{
bbs_[i] = calcCellBb(cellLabels_[i]);
}
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::treeDataCell::treeDataCell
(
const bool cacheBb,
const polyMesh& mesh,
const labelUList& cellLabels,
const polyMesh::cellRepresentation decompMode
)
:
mesh_(mesh),
cellLabels_(cellLabels),
cacheBb_(cacheBb),
decompMode_(decompMode)
{
update();
}
Foam::treeDataCell::treeDataCell
(
const bool cacheBb,
const polyMesh& mesh,
const Xfer<labelList>& cellLabels,
const polyMesh::cellRepresentation decompMode
)
:
mesh_(mesh),
cellLabels_(cellLabels),
cacheBb_(cacheBb),
decompMode_(decompMode)
{
update();
}
Foam::treeDataCell::treeDataCell
(
const bool cacheBb,
const polyMesh& mesh,
const polyMesh::cellRepresentation decompMode
)
:
mesh_(mesh),
cellLabels_(identity(mesh_.nCells())),
cacheBb_(cacheBb),
decompMode_(decompMode)
{
update();
}
Foam::treeDataCell::findNearestOp::findNearestOp
(
const indexedOctree<treeDataCell>& tree
)
:
tree_(tree)
{}
Foam::treeDataCell::findIntersectOp::findIntersectOp
(
const indexedOctree<treeDataCell>& tree
)
:
tree_(tree)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::pointField Foam::treeDataCell::shapePoints() const
{
pointField cc(cellLabels_.size());
forAll(cellLabels_, i)
{
cc[i] = mesh_.cellCentres()[cellLabels_[i]];
}
return cc;
}
bool Foam::treeDataCell::overlaps
(
const label index,
const treeBoundBox& cubeBb
) const
{
if (cacheBb_)
{
return cubeBb.overlaps(bbs_[index]);
}
else
{
return cubeBb.overlaps(calcCellBb(cellLabels_[index]));
}
}
bool Foam::treeDataCell::contains
(
const label index,
const point& sample
) const
{
return mesh_.pointInCell(sample, cellLabels_[index], decompMode_);
}
void Foam::treeDataCell::findNearestOp::operator()
(
const labelUList& indices,
const point& sample,
scalar& nearestDistSqr,
label& minIndex,
point& nearestPoint
) const
{
const treeDataCell& shape = tree_.shapes();
forAll(indices, i)
{
label index = indices[i];
label cellI = shape.cellLabels()[index];
scalar distSqr = magSqr(sample - shape.mesh().cellCentres()[cellI]);
if (distSqr < nearestDistSqr)
{
nearestDistSqr = distSqr;
minIndex = index;
nearestPoint = shape.mesh().cellCentres()[cellI];
}
}
}
void Foam::treeDataCell::findNearestOp::operator()
(
const labelUList& indices,
const linePointRef& ln,
treeBoundBox& tightest,
label& minIndex,
point& linePoint,
point& nearestPoint
) const
{
notImplemented
(
"treeDataCell::findNearestOp::operator()"
"("
" const labelUList&,"
" const linePointRef&,"
" treeBoundBox&,"
" label&,"
" point&,"
" point&"
") const"
);
}
bool Foam::treeDataCell::findIntersectOp::operator()
(
const label index,
const point& start,
const point& end,
point& intersectionPoint
) const
{
const treeDataCell& shape = tree_.shapes();
// Do quick rejection test
if (shape.cacheBb_)
{
const treeBoundBox& cellBb = shape.bbs_[index];
if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
{
// start and end in same block outside of cellBb.
return false;
}
}
else
{
const treeBoundBox cellBb = shape.calcCellBb(shape.cellLabels_[index]);
if ((cellBb.posBits(start) & cellBb.posBits(end)) != 0)
{
// start and end in same block outside of cellBb.
return false;
}
}
// Do intersection with all faces of cell
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Disable picking up intersections behind us.
scalar oldTol = intersection::setPlanarTol(0.0);
const cell& cFaces = shape.mesh_.cells()[shape.cellLabels_[index]];
const vector dir(end - start);
scalar minDistSqr = magSqr(dir);
bool hasMin = false;
forAll(cFaces, i)
{
const face& f = shape.mesh_.faces()[cFaces[i]];
pointHit inter = f.ray
(
start,
dir,
shape.mesh_.points(),
intersection::HALF_RAY
);
if (inter.hit() && sqr(inter.distance()) <= minDistSqr)
{
// Note: no extra test on whether intersection is in front of us
// since using half_ray AND zero tolerance. (note that tolerance
// is used to look behind us)
minDistSqr = sqr(inter.distance());
intersectionPoint = inter.hitPoint();
hasMin = true;
}
}
// Restore picking tolerance
intersection::setPlanarTol(oldTol);
return hasMin;
}
// ************************************************************************* //

View File

@ -0,0 +1,239 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::treeDataCell
Description
Encapsulation of data needed to search in/for cells. Used to find the
cell containing a point (e.g. cell-cell mapping).
SourceFiles
treeDataCell.C
\*---------------------------------------------------------------------------*/
#ifndef treeDataCell_H
#define treeDataCell_H
#include "polyMesh.H"
#include "treeBoundBoxList.H"
#include "volumeType.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
template<class Type> class indexedOctree;
/*---------------------------------------------------------------------------*\
Class treeDataCell Declaration
\*---------------------------------------------------------------------------*/
class treeDataCell
{
// Private data
const polyMesh& mesh_;
//- Subset of cells to work on
const labelList cellLabels_;
//- Whether to precalculate and store cell bounding box
const bool cacheBb_;
//- How to decide if point is inside cell
const polyMesh::cellRepresentation decompMode_;
//- cell bounding boxes (valid only if cacheBb_)
treeBoundBoxList bbs_;
// Private Member Functions
//- Calculate cell bounding box
treeBoundBox calcCellBb(const label cellI) const;
//- Initialise all member data
void update();
public:
class findNearestOp
{
const indexedOctree<treeDataCell>& tree_;
public:
findNearestOp(const indexedOctree<treeDataCell>& tree);
void operator()
(
const labelUList& indices,
const point& sample,
scalar& nearestDistSqr,
label& minIndex,
point& nearestPoint
) const;
void operator()
(
const labelUList& indices,
const linePointRef& ln,
treeBoundBox& tightest,
label& minIndex,
point& linePoint,
point& nearestPoint
) const;
};
class findIntersectOp
{
const indexedOctree<treeDataCell>& tree_;
public:
findIntersectOp(const indexedOctree<treeDataCell>& tree);
bool operator()
(
const label index,
const point& start,
const point& end,
point& intersectionPoint
) const;
};
// Declare name of the class and its debug switch
ClassName("treeDataCell");
// Constructors
//- Construct from mesh and subset of cells.
treeDataCell
(
const bool cacheBb,
const polyMesh&,
const labelUList&,
const polyMesh::cellRepresentation decompMode
);
//- Construct from mesh and subset of cells, transferring contents
treeDataCell
(
const bool cacheBb,
const polyMesh&,
const Xfer<labelList>&,
const polyMesh::cellRepresentation decompMode
);
//- Construct from mesh. Uses all cells in mesh.
treeDataCell
(
const bool cacheBb,
const polyMesh&,
const polyMesh::cellRepresentation decompMode
);
// Member Functions
// Access
inline const labelList& cellLabels() const
{
return cellLabels_;
}
inline const polyMesh& mesh() const
{
return mesh_;
}
inline polyMesh::cellRepresentation decompMode() const
{
return decompMode_;
}
inline label size() const
{
return cellLabels_.size();
}
//- Get representative point cloud for all shapes inside
// (one point per shape)
pointField shapePoints() const;
// Search
//- Get type (inside,outside,mixed,unknown) of point w.r.t. surface.
// Only makes sense for closed surfaces.
volumeType getVolumeType
(
const indexedOctree<treeDataCell>&,
const point&
) const
{
notImplemented
(
"treeDataCell::getVolumeType"
"(const indexedOctree<treeDataCell>&, const point&)"
);
return volumeType::UNKNOWN;
}
//- Does (bb of) shape at index overlap bb
bool overlaps
(
const label index,
const treeBoundBox& sampleBb
) const;
//- Does shape at index contain sample
bool contains
(
const label index,
const point& sample
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,79 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "volumeType.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
template<>
const char* Foam::NamedEnum
<
Foam::volumeType,
4
>::names[] =
{
"unknown",
"mixed",
"inside",
"outside"
};
}
const Foam::NamedEnum<Foam::volumeType, 4> Foam::volumeType::names;
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
Foam::Istream& Foam::operator>>(Istream& is, volumeType& vt)
{
// Read beginning of volumeType
is.readBegin("volumeType");
int type;
is >> type;
vt.t_ = static_cast<volumeType::type>(type);
// Read end of volumeType
is.readEnd("volumeType");
// Check state of Istream
is.check("operator>>(Istream&, volumeType&)");
return is;
}
Foam::Ostream& Foam::operator<<(Ostream& os, const volumeType& vt)
{
os << static_cast<int>(vt.t_);
return os;
}
// ************************************************************************* //

View File

@ -0,0 +1,127 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2013 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::volumeType
Description
SourceFiles
volumeType.C
\*---------------------------------------------------------------------------*/
#ifndef volumeType_H
#define volumeType_H
#include "NamedEnum.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of friend functions and operators
class volumeType;
Istream& operator>>(Istream& is, volumeType&);
Ostream& operator<<(Ostream& os, const volumeType& C);
/*---------------------------------------------------------------------------*\
Class volumeType Declaration
\*---------------------------------------------------------------------------*/
class volumeType
{
public:
//- Volume types
enum type
{
UNKNOWN = 0,
MIXED = 1,
INSIDE = 2,
OUTSIDE = 3
};
private:
// Private data
//- Volume type
type t_;
public:
// Static data
static const NamedEnum<volumeType, 4> names;
// Constructors
//- Construct null
volumeType()
:
t_(UNKNOWN)
{}
//- Construct from components
volumeType(type t)
:
t_(t)
{}
// Member Functions
operator type() const
{
return t_;
}
// IOstream operators
friend Istream& operator>>(Istream& is, volumeType& vt);
friend Ostream& operator<<(Ostream& os, const volumeType& vt);
};
//- Data associated with volumeType type are contiguous
template<>
inline bool contiguous<volumeType>() {return true;}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,153 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2012 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::subCycle
Description
Perform a subCycleTime on a field
\*---------------------------------------------------------------------------*/
#ifndef subCycle_H
#define subCycle_H
#include "subCycleTime.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class subCycleField Declaration
\*---------------------------------------------------------------------------*/
template<class GeometricField>
class subCycleField
{
// Private data
//- Reference to the field being sub-cycled
GeometricField& gf_;
//- Reference to the field old-time field being sub-cycled
// Needed to avoid calls to oldTime() which may cause
// unexpected updates of the old-time field
GeometricField& gf0_;
//- Copy of the "real" old-time value of the field
GeometricField gf_0_;
public:
// Constructors
//- Construct field and number of sub-cycles
subCycleField(GeometricField& gf)
:
gf_(gf),
gf0_(gf.oldTime()),
gf_0_(gf0_.name() + "_", gf0_)
{}
//- Destructor
~subCycleField()
{
// Reset the old-time field
gf0_ = gf_0_;
// Correct the time index of the field to correspond to the global time
gf_.timeIndex() = gf_.time().timeIndex();
gf0_.timeIndex() = gf_.time().timeIndex();
}
//- Correct the time index of the field to correspond to
// the sub-cycling time.
//
// The time index is incremented to protect the old-time value from
// being updated at the beginning of the time-loop in the case of
// outer iteration
void updateTimeIndex()
{
gf_.timeIndex() = gf_.time().timeIndex() + 1;
gf0_.timeIndex() = gf_.time().timeIndex() + 1;
}
};
/*---------------------------------------------------------------------------*\
Class subCycle Declaration
\*---------------------------------------------------------------------------*/
template<class GeometricField>
class subCycle
:
public subCycleField<GeometricField>,
public subCycleTime
{
// Private Member Functions
//- Disallow default bitwise copy construct
subCycle(const subCycle<GeometricField>&);
//- Disallow default bitwise assignment
void operator=(const subCycle<GeometricField>&);
public:
// Constructors
//- Construct field and number of sub-cycles
subCycle(GeometricField& gf, const label nSubCycles)
:
subCycleField<GeometricField>(gf),
subCycleTime(const_cast<Time&>(gf.time()), nSubCycles)
{
// Update the field time index to correspond to the sub-cycle time
this->updateTimeIndex();
}
//- Destructor
// End the subCycleTime, which restores the time state
~subCycle()
{
endSubCycle();
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //