FreeFOAM The Cross-Platform CFD Toolkit
Hosted by SourceForge:
Get FreeFOAM at SourceForge.net.
            Fast, secure and Free Open Source software downloads

octree.H

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------------*\
00002   =========                 |
00003   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
00004    \\    /   O peration     |
00005     \\  /    A nd           | Copyright (C) 1991-2010 OpenCFD Ltd.
00006      \\/     M anipulation  |
00007 -------------------------------------------------------------------------------
00008 License
00009     This file is part of OpenFOAM.
00010 
00011     OpenFOAM is free software: you can redistribute it and/or modify it
00012     under the terms of the GNU General Public License as published by
00013     the Free Software Foundation, either version 3 of the License, or
00014     (at your option) any later version.
00015 
00016     OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
00017     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018     FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00019     for more details.
00020 
00021     You should have received a copy of the GNU General Public License
00022     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
00023 
00024 Class
00025     Foam::octree
00026 
00027 Description
00028     Octree, templated on type of shapes it refers to.
00029 
00030     Uses the octreeData class, which is a list of 1D, 2D or 3D shapes.
00031     Various implementations of octreeData which know about cell&meshes,
00032     patches&meshes and points.
00033 
00034     The octree can be used to
00035       - find the "nearest" shape to a point
00036       - find the shape which contains a point (only sensible for 3D shapes)
00037       - find intersections of line with shapes
00038 
00039     The tree consists of
00040       - treeNode : holds sub-treeNodes or treeLeaves
00041       - treeLeaf : is the one that actually holds data
00042 
00043     The data is stored purely as a list of indices into octreeData.
00044 
00045     The construction on the depth of the tree is:
00046       - one can specify a minimum depth
00047         (though the tree will never be refined if all leaves contain <=1
00048          shapes)
00049       - after the minimum depth two statistics are used to decide further
00050         refinement:
00051         - average number of entries per leaf (leafRatio). Since inside a
00052           leaf most algorithms are n or n^2 this value has to be small.
00053         - average number of leaves a shape is in. Because of bounding boxes,
00054           a single shape can be in multiple leaves. If the bbs are large
00055           compared to the leaf size this multiplicity can become extremely
00056           large and will become larger with more levels.
00057 
00058     Note: the octree gets constructed with an overall bounding box. If your
00059     mesh is regular it is a good idea to make this overall bb a bit wider than
00060     the bb of the shapes itself. Otherwise lots of shapes end up exactly on the
00061     edge of a bb and hence go into more than one subcube.
00062 
00063     E.g. octree of face centres of lid driven cavity.
00064 
00065       -# bb exact -> total 1457 leaves (every point in 7.1 leaves)
00066       -# bb.max incremented by 1% -> total 80 leaves
00067          (every point in exactly 1 leaf)
00068 
00069     @par Ideas for parallel implementation:
00070 
00071     The data inserted into the octree (the
00072     'octreeData') has to be local to the processor. The data to be looked
00073     for (usually a sample point) can be global to the domain.
00074     The algorithm:
00075       - search for all my points
00076       - collect results which have to do with a processor patch
00077       - global sum all these. If 0 exit.
00078       - exchange data on all processor patches
00079       - start again
00080 
00081     So data transfers one processor per iteration. One could think of having
00082     an extra search mechanism one level above which does an initial search
00083     knowing the average shape of a processor distribution (square/cube for
00084     most decomposition methods) and can assign sample points to the (almost)
00085     correct processor at once.
00086 
00087 SourceFiles
00088     octree.C
00089 
00090 \*---------------------------------------------------------------------------*/
00091 
00092 #ifndef octree_H
00093 #define octree_H
00094 
00095 #include "treeBoundBoxList.H"
00096 #include "treeLeaf.H"
00097 #include "pointIndexHit.H"
00098 #include <OpenFOAM/linePointRef.H>
00099 
00100 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00101 
00102 namespace Foam
00103 {
00104 
00105 // Forward declaration of classes
00106 template<class Type> class treeNode;
00107 
00108 // Forward declaration of friend functions and operators
00109 
00110 template<class Type>
00111 Ostream& operator<<(Ostream&, const octree<Type>&);
00112 
00113 
00114 /*---------------------------------------------------------------------------*\
00115                         Class octreeName Declaration
00116 \*---------------------------------------------------------------------------*/
00117 
00118 TemplateName(octree);
00119 
00120 
00121 
00122 /*---------------------------------------------------------------------------*\
00123                            Class octree Declaration
00124 \*---------------------------------------------------------------------------*/
00125 
00126 template <class Type>
00127 class octree
00128 :
00129     public octreeName
00130 {
00131     // Private data
00132 
00133         //- Top treeNode. Modified by lower levels.
00134         treeNode<Type>* topNode_;
00135 
00136         //- all shapes
00137         const Type shapes_;
00138 
00139         //- Overall bb of octree
00140         const treeBoundBox octreeBb_;
00141 
00142         //- Refinement crit: size of leaves. Average number of entries per
00143         //  leaf. Should be fine enough for efficient searching at lowest level.
00144         const scalar maxLeafRatio_;
00145 
00146         //- Refinement crit: multiplicity of entries (so in how many leaves
00147         //  each shape is mentioned)
00148         const scalar maxShapeRatio_;
00149 
00150         //- Refinement crit: min no. of levels
00151         const label minNLevels_;
00152 
00153         //- Actual depth
00154         label deepestLevel_;
00155 
00156         //- Total number of (references to) shapes in octree
00157         //  (shapes can be stored in more than one treeLeaf)
00158         label nEntries_;
00159 
00160         //- Total number of treeNodes
00161         label nNodes_;
00162 
00163         //- Total number of treeLeaves
00164         label nLeaves_;
00165 
00166 
00167     // Static data members
00168         //- Refinement crit: max number of level
00169         static const label maxNLevels = 20;
00170 
00171 
00172 
00173     // Private Member Functions
00174 
00175 public:
00176 
00177     // Data types
00178 
00179         //- volume types
00180         enum volumeType
00181         {
00182             UNKNOWN,
00183             MIXED,
00184             INSIDE,
00185             OUTSIDE
00186         };
00187 
00188 
00189     // Static data members
00190 
00191         //- for debugging:return printable representation of volumeType
00192         static string volType(const label);
00193 
00194         //- Code the vector with respect to the geometry. geomNormal guaranteed
00195         //  to point outside.
00196         static label getVolType
00197         (
00198             const vector& geomNormal,
00199             const vector& vec
00200         );
00201 
00202     // Constructors
00203 
00204         //- Construct from components
00205         octree
00206         (
00207             const treeBoundBox& octreeBb,
00208             const Type& shapes,
00209             const label minNLevels,     // minimum number of levels
00210             const scalar maxLeafRatio,  // max avg. size of leaves
00211             const scalar maxShapeRatio  // max avg. duplicity.
00212         );
00213 
00214 
00215     // Destructor
00216 
00217         ~octree();
00218 
00219 
00220     // Member Functions
00221 
00222         // Access
00223 
00224             const Type& shapes() const
00225             {
00226                 return shapes_;
00227             }
00228 
00229             const treeBoundBox& octreeBb() const
00230             {
00231                 return octreeBb_;
00232             }
00233 
00234             scalar maxShapeRatio() const
00235             {
00236                 return maxShapeRatio_;
00237             }
00238 
00239             scalar maxLeafRatio() const
00240             {
00241                 return maxLeafRatio_;
00242             }
00243 
00244             label minNLevels() const
00245             {
00246                 return minNLevels_;
00247             }
00248 
00249         // After construction: octree statistics
00250 
00251             treeNode<Type>* topNode() const
00252             {
00253                 return topNode_;
00254             }
00255 
00256             label deepestLevel() const
00257             {
00258                 return deepestLevel_;
00259             }
00260 
00261             label nEntries() const
00262             {
00263                 return nEntries_;
00264             }
00265 
00266             label nNodes() const
00267             {
00268                 return nNodes_;
00269             }
00270 
00271             label nLeaves() const
00272             {
00273                 return nLeaves_;
00274             }
00275 
00276             void setEntries(const label n)
00277             {
00278                 nEntries_ = n;
00279             }
00280 
00281             void setNodes(const label n)
00282             {
00283                 nNodes_ = n;
00284             }
00285 
00286             void setLeaves(const label n)
00287             {
00288                 nLeaves_ = n;
00289             }
00290 
00291         // Queries
00292 
00293             //- Returns type of sample with respect to nearest shape.
00294             //  Meaning of type is determined by shapes.getSampleType().
00295             //  Normally based on outwards pointing normal. For e.g.
00296             //  octreeDataFace returns one of
00297             //      inside  : on other side of normal on nearest face
00298             //      outside : on same side as normal on nearest face
00299             //      unknown : not above nearest face; surface probably not
00300             //                closed.
00301             //      mixed   : should never happen
00302             label getSampleType(const point& sample) const;
00303 
00304             //- Find shape containing point in tree
00305             //  Returns -1 if not in found. Uses Type::contains.
00306             label find(const point& sample) const;
00307 
00308             //- Calculate tightest fitting bounding box. Uses
00309             //  Type::findTightest.
00310             bool findTightest
00311             (
00312                 const point& sample,
00313                 treeBoundBox& tightest
00314             ) const;
00315 
00316             //- Find nearest shape. Returns index of shape or -1 if not found.
00317             //  tightestDist is both input and output. Uses Type::calcNearest.
00318             label findNearest
00319             (
00320                 const point& sample,
00321                 treeBoundBox& tightest,
00322                 scalar& tightestDist
00323             ) const;
00324 
00325             //- Find nearest to line. Returns -1 or index of shape and
00326             //  sets:
00327             //  - tightest (is both input and output).
00328             //  - linePoint : point on line (-GREAT,-GREAT,-GREAT if not found)
00329             //  - shapePoint : point on shape (GREAT, GREAT, GREAT if not found)
00330             //  Uses Type::calcNearest.
00331             label findNearest
00332             (
00333                 const linePointRef& ln,
00334                 treeBoundBox& tightest,
00335                 point& linePoint,
00336                 point& shapePoint
00337             ) const;
00338 
00339             //- Find (in no particular order) indices of all shapes inside or
00340             //  overlapping bounding box (i.e. all shapes not outside box)
00341             labelList findBox(const boundBox& bb) const;
00342 
00343             //- Find intersected shape along line. pointIndexHit contains index
00344             //  of nearest shape intersected and the intersection point. Uses
00345             //  findLeafLine.
00346             pointIndexHit findLine(const point& start, const point& end) const;
00347 
00348             //- Like above but just tests whether line hits anything. So
00349             //   returns first intersection found, not nessecarily nearest.
00350             pointIndexHit findLineAny(const point& start, const point& end)
00351              const;
00352 
00353             //- Find leaf along line. Set leafIntPoint to leave point of
00354             //  treeLeaf.
00355             const treeLeaf<Type>* findLeafLine
00356             (
00357                 const point& start,
00358                 const point& end,
00359                 point& leafIntPoint
00360             ) const;
00361 
00362 
00363         // Write
00364 
00365             //- Dump graphical representation in .obj format
00366             void writeOBJ(Ostream& os, label& vertNo) const;
00367 
00368             //- Print some stats on octree
00369             void printStats(Ostream& os) const;
00370 
00371 
00372     // STL iterator
00373 
00374         class iterator;
00375         friend class iterator;
00376 
00377         //- An STL iterator for octree
00378         class iterator
00379         {
00380             // Private data
00381 
00382                 //- Reference to the octree this is an iterator for
00383                 octree& octree_;
00384 
00385                 //- List of pointers to treeLeaves
00386                 List<treeLeaf<Type>*> leaves_;
00387 
00388                 //- Current treeLeaf index
00389                 label curLeaf_;
00390 
00391         public:
00392 
00393             //- Construct for a given octree
00394             iterator(octree&);
00395 
00396             //- Contruct for a given octree, at a certain position
00397             iterator(octree& oc, const label index);
00398 
00399 
00400             // Member operators
00401 
00402                 void operator=(const iterator&);
00403 
00404                 bool operator==(const iterator&) const;
00405                 bool operator!=(const iterator&) const;
00406 
00407                 treeLeaf<Type>& operator*();
00408 
00409                 iterator& operator++();
00410                 iterator operator++(int);
00411         };
00412 
00413         //- iterator set to the begining of the octree
00414         iterator begin();
00415 
00416         //- iterator set to beyond the end of the octree
00417         const iterator& end();
00418 
00419 
00420     // STL const_iterator
00421 
00422         class const_iterator;
00423         friend class const_iterator;
00424 
00425         //- An STL const_iterator for octree
00426         class const_iterator
00427         {
00428             // Private data
00429 
00430                 //- Reference to the list this is an iterator for
00431                 const octree& octree_;
00432 
00433                 //- List of treeLeafs
00434                 List<const treeLeaf<Type>*> leaves_;
00435 
00436                 //- Current treeLeaf index
00437                 label curLeaf_;
00438 
00439         public:
00440 
00441             //- Construct for a given octree
00442             const_iterator(const octree&);
00443 
00444             //- Construct for a given octree and index
00445             const_iterator(const octree&, label);
00446 
00447             // Member operators
00448 
00449                 void operator=(const const_iterator&);
00450 
00451                 bool operator==(const const_iterator&) const;
00452                 bool operator!=(const const_iterator&) const;
00453 
00454                 const treeLeaf<Type>& operator*();
00455 
00456                 const_iterator& operator++();
00457                 const_iterator operator++(int);
00458         };
00459 
00460 
00461         //- const_iterator set to the begining of the octree
00462         inline const_iterator begin() const;
00463         inline const_iterator cbegin() const;
00464 
00465         //- const_iterator set to beyond the end of the octree
00466         inline const const_iterator& end() const;
00467         inline const const_iterator& cend() const;
00468 
00469 
00470     // IOstream Operators
00471 
00472         friend Ostream& operator<< <Type>(Ostream&, const octree<Type>&);
00473 
00474 
00475 private:
00476 
00477         //- iterator returned by end()
00478         iterator endIter_;
00479 
00480         //- const_iterator returned by end()
00481         const_iterator endConstIter_;
00482 };
00483 
00484 
00485 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00486 
00487 } // End namespace Foam
00488 
00489 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00490 
00491 #ifdef NoRepository
00492 #   include "octree.C"
00493 #endif
00494 
00495 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
00496 
00497 #endif
00498 
00499 // ************************ vim: set sw=4 sts=4 et: ************************ //
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines