LCOV - code coverage report
Current view: top level - ugbase/common/space_partitioning - ntree_traverser.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 57 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 24 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2013-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #ifndef __H__UG__ntree_traverser__
      34              : #define __H__UG__ntree_traverser__
      35              : 
      36              : #include <algorithm>
      37              : #include <utility>
      38              : #include <vector>
      39              : #include "ntree_traversal.h"
      40              : 
      41              : namespace ug{
      42              : 
      43              : template <class tree_t>
      44              : class Traverser_FindLowestLeafNodeLevel
      45              : {
      46              :         public:
      47            0 :                 Traverser_FindLowestLeafNodeLevel() :
      48            0 :                         m_lowestLeafNodeLvl(0)  {}
      49              : 
      50              :                 void begin_traversal(const tree_t& tree)
      51              :                 {
      52            0 :                         m_lowestLeafNodeLvl = 0;
      53            0 :                 }
      54              : 
      55              :                 int visit_up(const tree_t& tree, size_t node)
      56              :                 {
      57              :                         if(tree.num_child_nodes(node) == 0){
      58            0 :                                 m_lowestLeafNodeLvl = tree.level(node);
      59              :                                 return ABORT_TRAVERSAL;
      60              :                         }
      61              :                         return TRAVERSE_CHILDREN;
      62              :                 }
      63              : 
      64              :                 void visit_down(const tree_t&, size_t)      {}
      65              : 
      66              :                 void end_traversal(const tree_t&)   {}
      67              : 
      68            0 :                 size_t result() const {return m_lowestLeafNodeLvl;}
      69              : 
      70              :         private:
      71              :                 size_t m_lowestLeafNodeLvl;
      72              : };
      73              : 
      74              : template <class tree_t>
      75              : size_t FindLowestLeafNodeLevel(const tree_t& tree)
      76              : {
      77              :         Traverser_FindLowestLeafNodeLevel<tree_t> trav;
      78            0 :         TraverseBreadthFirst(tree, trav);
      79              :         return trav.result();
      80              : }
      81              : 
      82              : 
      83              : ///     returns the minimum and maximum number of elements in all subtrees of nodes of the given level
      84              : template <class tree_t>
      85              : class Traverser_MinMaxNumElements
      86              : {
      87              :         public:
      88            0 :                 Traverser_MinMaxNumElements(size_t lvl) :
      89            0 :                         m_lvl(lvl), m_minNumElements(0), m_maxNumElements(0),
      90            0 :                         m_elemCount(0), m_firstEval(true)       {}
      91              : 
      92              :                 void begin_traversal(const tree_t& tree)
      93              :                 {
      94              :                         m_minNumElements = m_maxNumElements = 0;
      95              :                         m_elemCount = 0;
      96              :                         m_firstEval = true;
      97              :                 }
      98              : 
      99              :                 int visit_up(const tree_t& tree, size_t node)
     100              :                 {
     101            0 :                         if(tree.level(node) == m_lvl)
     102            0 :                                 m_elemCount = 0;
     103              : 
     104            0 :                         if(tree.level(node) >= m_lvl)
     105            0 :                                 m_elemCount += tree.num_elements(node);
     106              : 
     107              :                         return TRAVERSE_CHILDREN;
     108              :                 }
     109              : 
     110            0 :                 void visit_down(const tree_t& tree, size_t node)
     111              :                 {
     112            0 :                         if(tree.level(node) == m_lvl){
     113            0 :                                 if(m_firstEval){
     114            0 :                                         m_minNumElements = m_maxNumElements= m_elemCount;
     115            0 :                                         m_firstEval = false;
     116              :                                 }
     117              :                                 else{
     118            0 :                                         m_minNumElements = std::min(m_minNumElements, m_elemCount);
     119            0 :                                         m_maxNumElements = std::max(m_maxNumElements, m_elemCount);
     120              :                                 }
     121              :                         }
     122            0 :                 }
     123              : 
     124              :                 void end_traversal(const tree_t&)   {}
     125              : 
     126            0 :                 size_t min_num_elements() const {return m_minNumElements;}
     127            0 :                 size_t max_num_elements() const {return m_maxNumElements;}
     128              : 
     129              :         private:
     130              :                 size_t m_lvl;
     131              :                 size_t m_minNumElements;
     132              :                 size_t m_maxNumElements;
     133              :                 size_t m_elemCount;
     134              :                 bool m_firstEval;
     135              : };
     136              : 
     137              : template <class tree_t>
     138            0 : std::pair<size_t, size_t> GetMinMaxNumElements(const tree_t& tree, size_t lvl)
     139              : {
     140              :         Traverser_MinMaxNumElements<tree_t> trav(lvl);
     141              :         TraverseDepthFirst(tree, trav);
     142            0 :         return std::make_pair(trav.min_num_elements(), trav.max_num_elements());
     143              : }
     144              : 
     145              : 
     146              : template <class tree_t>
     147              : class Traverser_FindContainingElement
     148              : {
     149              :         public:
     150              :                 typedef typename tree_t::elem_t         elem_t;
     151              :                 typedef typename tree_t::vector_t       vector_t;
     152              : 
     153            0 :                 Traverser_FindContainingElement(const vector_t& point) :
     154              :                         m_point(point),
     155            0 :                         m_foundElem(false)
     156              :                 {}
     157              : 
     158              :                 void begin_traversal(const tree_t& tree)
     159              :                 {
     160              :                         m_foundElem = false;
     161            0 :                         m_numElemsChecked = 0;
     162              :                 }
     163              : 
     164            0 :                 int visit_up(const tree_t& tree, size_t node)
     165              :                 {
     166              :                 //      if the point doesn't lie in the node's bounding box, we don't have
     167              :                 //      to check it's elements at all.
     168            0 :                         if(!tree_t::traits::box_contains_point(tree.bounding_box(node), m_point))
     169              :                                 return DONT_TRAVERSE_CHILDREN;
     170              : 
     171              :                 //      first check whether the nodes box contains the given point
     172              :                         if(tree.num_child_nodes(node) == 0){
     173              :                         //      iterate over all elements. If an element contains the given point,
     174              :                         //      we're done and we may return.
     175              :                                 for(typename tree_t::elem_iterator_t iter = tree.elems_begin(node);
     176            0 :                                         iter != tree.elems_end(node); ++iter)
     177              :                                 {
     178            0 :                                         ++m_numElemsChecked;
     179            0 :                                         if(tree_t::traits::contains_point(*iter, m_point, tree.common_data())){
     180            0 :                                                 m_foundElem = true;
     181            0 :                                                 m_elem = *iter;
     182              :                                                 return ABORT_TRAVERSAL;
     183              :                                         }
     184              :                                 }
     185              :                         }
     186              :                         return TRAVERSE_CHILDREN;
     187              :                 }
     188              : 
     189              :                 void visit_down(const tree_t&, size_t)      {}
     190              : 
     191              :                 void end_traversal(const tree_t&)   {}
     192              : 
     193              :                 bool result(elem_t& foundElemOut) const
     194              :                 {
     195            0 :                         if(m_foundElem)
     196            0 :                                 foundElemOut = m_elem;
     197              :                         return m_foundElem;
     198              :                 }
     199              : 
     200              :                 size_t num_elems_checked() const        {return m_numElemsChecked;}
     201              : 
     202              :         private:
     203              :                 vector_t        m_point;
     204              :                 elem_t          m_elem;
     205              :                 size_t          m_numElemsChecked;
     206              :                 bool            m_foundElem;
     207              : };
     208              : 
     209              : template <class tree_t>
     210            0 : bool FindContainingElement(typename tree_t::elem_t& elemOut, const tree_t& tree,
     211              :                                                    const typename tree_t::vector_t& point)
     212              : {
     213              :         Traverser_FindContainingElement<tree_t> trav(point);
     214              :         TraverseDepthFirst(tree, trav);
     215              :         //UG_LOG("num elems checked for one pick: " << trav.num_elems_checked() << "\n");
     216              :         typename tree_t::elem_t tmpElem;
     217              :         if(trav.result(tmpElem)){
     218            0 :                 elemOut = tmpElem;
     219            0 :                 return true;
     220              :         }
     221              :         return false;
     222              : }
     223              : 
     224              : 
     225              : template <class tree_t>
     226              : class Traverser_FindElementsInIntersectingNodes
     227              : {
     228              :         public:
     229              :                 typedef typename tree_t::elem_t         elem_t;
     230              :                 typedef typename tree_t::vector_t       vector_t;
     231              :                 typedef typename tree_t::box_t          box_t;
     232              : 
     233              :                 Traverser_FindElementsInIntersectingNodes(const box_t& bbox) :
     234              :                         m_bbox(bbox)
     235              :                 {}
     236              : 
     237              :                 void begin_traversal(const tree_t& tree)
     238              :                 {
     239              :                         m_foundElems.clear();
     240              :                 }
     241              : 
     242              :                 int visit_up(const tree_t& tree, size_t node)
     243              :                 {
     244              :                 //      if our bounding box doesn't intersect the nodes bounding box,
     245              :                 //      then there's nothing to do
     246              :                         if(!tree_t::traits::box_box_intersection(tree.bounding_box(node), m_bbox))
     247              :                                 return DONT_TRAVERSE_CHILDREN;
     248              : 
     249              :                 //      first check whether the nodes box contains the given point
     250              :                         if(tree.num_child_nodes(node) == 0){
     251              :                         //      iterate over all elements. If an element contains the given point,
     252              :                         //      we're done and we may return.
     253              :                                 for(typename tree_t::elem_iterator_t iter = tree.elems_begin(node);
     254              :                                         iter != tree.elems_end(node); ++iter)
     255              :                                 {
     256              :                                         m_foundElems.push_back(*iter);
     257              :                                 }
     258              :                         }
     259              :                         return TRAVERSE_CHILDREN;
     260              :                 }
     261              : 
     262              :                 void visit_down(const tree_t&, size_t)      {}
     263              : 
     264              :                 void end_traversal(const tree_t&)   {}
     265              : 
     266              :                 const std::vector<elem_t>& result() const     {return m_foundElems;}
     267              : 
     268              :         private:
     269              :                 box_t                                   m_bbox;
     270              :                 std::vector<elem_t>               m_foundElems;
     271              : };
     272              : 
     273              : template <class tree_t>
     274              : bool FindElementsInIntersectingNodes(std::vector<typename tree_t::elem_t>& elemsOut,
     275              :                                                                          const tree_t& tree,
     276              :                                                                          const typename tree_t::box_t& bbox)
     277              : {
     278              :         Traverser_FindElementsInIntersectingNodes<tree_t> trav(bbox);
     279              :         TraverseDepthFirst(tree, trav);
     280              :         //UG_LOG("num elems checked for one pick: " << trav.num_elems_checked() << "\n");
     281              :         elemsOut = trav.result();
     282              :         return !elemsOut.empty();
     283              : }
     284              : 
     285              : 
     286              : 
     287              : // template <class TVector, class TData>
     288              : // class TraceRecorder {
     289              : //      public:
     290              : //              typedef TVector         vector_t;
     291              : //              typedef TData           data_t;
     292              : 
     293              : //              void clear              ();
     294              : //              void set_ray    (const vector_t& from, const vector_t& dir);
     295              : //              void add_point  (const vector_t& p, const data_t& d);
     296              : //              void add_point  (number t, const data_t& d);
     297              : 
     298              : //              size_t                          num_points                              () const;
     299              : //              const vector_t&             point                                   (size_t i) const;
     300              : //              const point_data&   point_data                              (size_t i) const;
     301              : //              number                          local_point_coordinate  (size_t i) const;
     302              : 
     303              : //              size_t  closest_point_index                             () const;
     304              : //              size_t  closest_positive_point_index    () const;
     305              : //              size_t  closest_negative_point_index    () const;
     306              : // };
     307              : 
     308              : template <class TElem>
     309              : struct RayElemIntersectionRecord
     310              : {
     311              :         RayElemIntersectionRecord()     {}
     312            0 :         RayElemIntersectionRecord(number _smin, number _smax, TElem _elem) :
     313            0 :                 smin(_smin), smax(_smax), elem(_elem)   {}
     314              : 
     315              :         number  smin;   ///< relative coordinate where the ray enters the element
     316              :         number  smax;   ///< relative coordinate where the ray leaves the element. May be equal to smin.
     317              :         TElem   elem; ///< the element that was intersected
     318              : };
     319              : 
     320              : template <class tree_t>
     321            0 : class Traverser_RayElementIntersection
     322              : {
     323              :         public:
     324              :                 typedef typename tree_t::elem_t                         elem_t;
     325              :                 typedef typename tree_t::vector_t                       vector_t;
     326              :                 typedef typename tree_t::box_t                          box_t;
     327              :                 typedef RayElemIntersectionRecord<elem_t> intersection_record_t;
     328              : 
     329              :                 Traverser_RayElementIntersection(const vector_t& rayFrom,
     330              :                                                                                  const vector_t rayDir,
     331              :                                                                                  const number small = 1.e-12) :
     332              :                         m_rayFrom(rayFrom),
     333              :                         m_rayDir(rayDir),
     334            0 :                         m_small(small)
     335              :                 {}
     336              : 
     337              :                 void begin_traversal(const tree_t& tree)
     338              :                 {
     339              :                         m_intersections.clear();
     340              :                 }
     341              : 
     342            0 :                 int visit_up(const tree_t& tree, size_t node)
     343              :                 {
     344              :                         box_t box = tree.bounding_box(node);
     345              :                         vector_t vsmall;
     346            0 :                         VecSet(vsmall, m_small);
     347            0 :                         VecScale(vsmall, vsmall, VecLength(tree_t::traits::box_diagonal(box)));
     348              :                         tree_t::traits::grow_box(box, box, vsmall);
     349              : 
     350            0 :                         if(!tree_t::traits::ray_box_intersection(m_rayFrom, m_rayDir, box))
     351              :                                 return DONT_TRAVERSE_CHILDREN;
     352              : 
     353              :                         if(tree.num_child_nodes(node) == 0){
     354              :                         //      iterate over all elements. If an element intersects the given ray,
     355              :                         //      we'll record the intersection point
     356              :                                 vector_t v;
     357            0 :                                 number smin = 0, smax = 0;
     358              :                                 for(typename tree_t::elem_iterator_t iter = tree.elems_begin(node);
     359            0 :                                         iter != tree.elems_end(node); ++iter)
     360              :                                 {
     361            0 :                                         if(tree_t::traits::intersects_ray(
     362              :                                                         *iter, m_rayFrom, m_rayDir, tree.common_data(),
     363            0 :                                                         smin, smax, m_small))
     364              :                                         {
     365            0 :                                                 m_intersections.push_back(intersection_record_t(smin, smax, *iter));
     366              :                                         }
     367              :                                 }
     368              :                         }
     369              :                         return TRAVERSE_CHILDREN;
     370              :                 }
     371              : 
     372              :                 void visit_down(const tree_t&, size_t)      {}
     373              : 
     374              :                 void end_traversal(const tree_t&)   {}
     375              : 
     376              :                 const std::vector<intersection_record_t>& result() const      {return m_intersections;}
     377              : 
     378              :         private:
     379              :                 vector_t                                                        m_rayFrom;
     380              :                 vector_t                                                        m_rayDir;
     381              :                 const number                                            m_small;
     382              :                 std::vector<intersection_record_t>        m_intersections;
     383              : };
     384              : 
     385              : template <class tree_t>
     386            0 : bool RayElementIntersections(
     387              :         std::vector<RayElemIntersectionRecord<typename tree_t::elem_t> >& intersectionsOut,
     388              :         const tree_t& tree,
     389              :         const typename tree_t::vector_t& rayFrom,
     390              :         const typename tree_t::vector_t& rayDir,
     391              :         const number small = 1.e-12)
     392              : {
     393              :         Traverser_RayElementIntersection<tree_t> trav(rayFrom, rayDir, small);
     394              :         TraverseDepthFirst(tree, trav);
     395              :         //UG_LOG("num elems checked for one pick: " << trav.num_elems_checked() << "\n");
     396            0 :         intersectionsOut = trav.result();
     397            0 :         return !intersectionsOut.empty();
     398              : }
     399              : 
     400              : }// end of namespace
     401              : 
     402              : #endif
        

Generated by: LCOV version 2.0-1