1 /*---------------------------------------------------------------------------*\
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
5 \\ / A nd | Copyright (C) 2004-2011 OpenCFD Ltd.
7 -------------------------------------------------------------------------------
9 This file is part of OpenFOAM.
11 OpenFOAM is free software: you can redistribute it and/or modify it
12 under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 3 of the License, or
14 (at your option) any later version.
16 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 You should have received a copy of the GNU General Public License
22 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
28 Octree, templated on type of shapes it refers to.
30 Uses the octreeData class, which is a list of 1D, 2D or 3D shapes.
31 Various implementations of octreeData which know about cell&meshes,
32 patches&meshes and points.
34 The octree can be used to
35 - find the "nearest" shape to a point
36 - find the shape which contains a point (only sensible for 3D shapes)
37 - find intersections of line with shapes
40 - treeNode : holds sub-treeNodes or treeLeaves
41 - treeLeaf : is the one that actually holds data
43 The data is stored purely as a list of indices into octreeData.
45 The construction on the depth of the tree is:
46 - one can specify a minimum depth
47 (though the tree will never be refined if all leaves contain <=1
49 - after the minimum depth two statistics are used to decide further
51 - average number of entries per leaf (leafRatio). Since inside a
52 leaf most algorithms are n or n^2 this value has to be small.
53 - average number of leaves a shape is in. Because of bounding boxes,
54 a single shape can be in multiple leaves. If the bbs are large
55 compared to the leaf size this multiplicity can become extremely
56 large and will become larger with more levels.
58 Note: the octree gets constructed with an overall bounding box. If your
59 mesh is regular it is a good idea to make this overall bb a bit wider than
60 the bb of the shapes itself. Otherwise lots of shapes end up exactly on the
61 edge of a bb and hence go into more than one subcube.
63 E.g. octree of face centres of lid driven cavity.
65 -# bb exact -> total 1457 leaves (every point in 7.1 leaves)
66 -# bb.max incremented by 1% -> total 80 leaves
67 (every point in exactly 1 leaf)
69 \par Ideas for parallel implementation:
71 The data inserted into the octree (the
72 'octreeData') has to be local to the processor. The data to be looked
73 for (usually a sample point) can be global to the domain.
75 - search for all my points
76 - collect results which have to do with a processor patch
77 - global sum all these. If 0 exit.
78 - exchange data on all processor patches
81 So data transfers one processor per iteration. One could think of having
82 an extra search mechanism one level above which does an initial search
83 knowing the average shape of a processor distribution (square/cube for
84 most decomposition methods) and can assign sample points to the (almost)
85 correct processor at once.
90 \*---------------------------------------------------------------------------*/
95 #include "treeBoundBoxList.H"
97 #include "pointIndexHit.H"
98 #include "linePointRef.H"
100 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
105 // Forward declaration of classes
106 template<class Type> class treeNode;
108 // Forward declaration of friend functions and operators
111 Ostream& operator<<(Ostream&, const octree<Type>&);
114 /*---------------------------------------------------------------------------*\
115 Class octreeName Declaration
116 \*---------------------------------------------------------------------------*/
118 TemplateName(octree);
122 /*---------------------------------------------------------------------------*\
123 Class octree Declaration
124 \*---------------------------------------------------------------------------*/
126 template <class Type>
133 //- Top treeNode. Modified by lower levels.
134 treeNode<Type>* topNode_;
139 //- Overall bb of octree
140 const treeBoundBox octreeBb_;
142 //- Refinement crit: size of leaves. Average number of entries per
143 // leaf. Should be fine enough for efficient searching at lowest level.
144 const scalar maxLeafRatio_;
146 //- Refinement crit: multiplicity of entries (so in how many leaves
147 // each shape is mentioned)
148 const scalar maxShapeRatio_;
150 //- Refinement crit: min no. of levels
151 const label minNLevels_;
156 //- Total number of (references to) shapes in octree
157 // (shapes can be stored in more than one treeLeaf)
160 //- Total number of treeNodes
163 //- Total number of treeLeaves
167 // Static data members
168 //- Refinement crit: max number of level
169 static const label maxNLevels = 20;
173 // Private Member Functions
189 // Static data members
191 //- for debugging:return printable representation of volumeType
192 static string volType(const label);
194 //- Code the vector with respect to the geometry. geomNormal guaranteed
196 static label getVolType
198 const vector& geomNormal,
204 //- Construct from components
207 const treeBoundBox& octreeBb,
209 const label minNLevels, // minimum number of levels
210 const scalar maxLeafRatio, // max avg. size of leaves
211 const scalar maxShapeRatio // max avg. duplicity.
223 const Type& shapes() const
228 const treeBoundBox& octreeBb() const
233 scalar maxShapeRatio() const
235 return maxShapeRatio_;
238 scalar maxLeafRatio() const
240 return maxLeafRatio_;
243 label minNLevels() const
248 // After construction: octree statistics
250 treeNode<Type>* topNode() const
255 label deepestLevel() const
257 return deepestLevel_;
260 label nEntries() const
270 label nLeaves() const
275 void setEntries(const label n)
280 void setNodes(const label n)
285 void setLeaves(const label n)
292 //- Returns type of sample with respect to nearest shape.
293 // Meaning of type is determined by shapes.getSampleType().
294 // Normally based on outwards pointing normal. For e.g.
295 // octreeDataFace returns one of
296 // inside : on other side of normal on nearest face
297 // outside : on same side as normal on nearest face
298 // unknown : not above nearest face; surface probably not
300 // mixed : should never happen
301 label getSampleType(const point& sample) const;
303 //- Find shape containing point in tree
304 // Returns -1 if not in found. Uses Type::contains.
305 label find(const point& sample) const;
307 //- Calculate tightest fitting bounding box. Uses
308 // Type::findTightest.
312 treeBoundBox& tightest
315 //- Find nearest shape. Returns index of shape or -1 if not found.
316 // tightestDist is both input and output. Uses Type::calcNearest.
320 treeBoundBox& tightest,
324 //- Find nearest to line. Returns -1 or index of shape and
326 // - tightest (is both input and output).
327 // - linePoint : point on line (-GREAT,-GREAT,-GREAT if not found)
328 // - shapePoint : point on shape (GREAT, GREAT, GREAT if not found)
329 // Uses Type::calcNearest.
332 const linePointRef& ln,
333 treeBoundBox& tightest,
338 //- Find (in no particular order) indices of all shapes inside or
339 // overlapping bounding box (i.e. all shapes not outside box)
340 labelList findBox(const boundBox& bb) const;
342 //- Find intersected shape along line. pointIndexHit contains index
343 // of nearest shape intersected and the intersection point. Uses
345 pointIndexHit findLine(const point& start, const point& end) const;
347 //- Like above but just tests whether line hits anything. So
348 // returns first intersection found, not nessecarily nearest.
349 pointIndexHit findLineAny(const point& start, const point& end)
352 //- Find leaf along line. Set leafIntPoint to leave point of
354 const treeLeaf<Type>* findLeafLine
364 //- Dump graphical representation in .obj format
365 void writeOBJ(Ostream& os, label& vertNo) const;
367 //- Print some stats on octree
368 void printStats(Ostream& os) const;
374 friend class iterator;
376 //- An STL iterator for octree
381 //- Reference to the octree this is an iterator for
384 //- List of pointers to treeLeaves
385 List<treeLeaf<Type>*> leaves_;
387 //- Current treeLeaf index
392 //- Construct for a given octree
395 //- Contruct for a given octree, at a certain position
396 iterator(octree& oc, const label index);
401 void operator=(const iterator&);
403 bool operator==(const iterator&) const;
404 bool operator!=(const iterator&) const;
406 treeLeaf<Type>& operator*();
408 iterator& operator++();
409 iterator operator++(int);
412 //- iterator set to the begining of the octree
415 //- iterator set to beyond the end of the octree
416 const iterator& end();
419 // STL const_iterator
421 class const_iterator;
422 friend class const_iterator;
424 //- An STL const_iterator for octree
429 //- Reference to the list this is an iterator for
430 const octree& octree_;
432 //- List of treeLeafs
433 List<const treeLeaf<Type>*> leaves_;
435 //- Current treeLeaf index
440 //- Construct for a given octree
441 const_iterator(const octree&);
443 //- Construct for a given octree and index
444 const_iterator(const octree&, label);
448 void operator=(const const_iterator&);
450 bool operator==(const const_iterator&) const;
451 bool operator!=(const const_iterator&) const;
453 const treeLeaf<Type>& operator*();
455 const_iterator& operator++();
456 const_iterator operator++(int);
460 //- const_iterator set to the begining of the octree
461 inline const_iterator begin() const;
462 inline const_iterator cbegin() const;
464 //- const_iterator set to beyond the end of the octree
465 inline const const_iterator& end() const;
466 inline const const_iterator& cend() const;
469 // IOstream Operators
471 friend Ostream& operator<< <Type>(Ostream&, const octree<Type>&);
476 //- iterator returned by end()
479 //- const_iterator returned by end()
480 const_iterator endConstIter_;
484 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
486 } // End namespace Foam
488 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
494 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
498 // ************************************************************************* //