G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsHDomain.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsCore/gsLinearAlgebra.h>
18 #include <gsCore/gsBoundary.h>
19 
20 namespace gismo
21 {
22 
23 template<typename T, unsigned d>
25 
26 template<class T>
27 class gsSegment;
28 
29 // template <short_t d, class Z>
30 // class gsKdNode;
31 
32 template <class T>
33 class gsVSegment;
34 
74 template<short_t d, class Z = index_t>
75 class gsHDomain
76 {
77 public:
78  typedef gsKdNode<d, Z> node;
79 
80  typedef typename node::point point; // it's a gsVector<index_t,d>
81 
82  typedef typename node::kdBox box; // it's a gsAABB<d,unsigned>
83 
85 
87 
88  template <class U, unsigned dd> friend class gsHDomainIterator;
89 
90 private:
91 
92  struct numLeaves_visitor;
93  struct numNodes_visitor;
94  struct levelUp_visitor;
95 
96 private:
97 
99  node * m_root;
100 
103 # define Eigen gsEigen
104  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
105 # undef Eigen
106 
108  unsigned m_indexLevel;
109 
111  unsigned m_maxInsLevel;
112 
113  unsigned m_maxPath;
114 
115 public:
116 
117  gsHDomain() : m_indexLevel(0)
118  {
119  m_root = nullptr;
120  m_maxInsLevel = 0;
121  m_maxPath = 0;
122  }
123 
124  gsHDomain(point const & upp)
125  {
126  m_root = nullptr;
127  m_maxInsLevel = 0;
128  m_maxPath = 0;
129  init(upp);
130  }
131 
133  gsHDomain( const gsHDomain & o) :
137  m_maxPath(o.m_maxPath)
138  {
139  m_root = new node(*o.m_root);
140  }
141 
144  {
145  if ( this == &o )
146  return *this;
147 
148  m_root = new node(*o.m_root);
149 
153  m_maxPath = o.m_maxPath;
154 
155  return *this;
156  }
157 
158 #if EIGEN_HAS_RVALUE_REFERENCES
159  gsHDomain(gsHDomain&& o) :
160  m_root(o.m_root),
161  m_upperIndex(std::move(o.m_upperIndex)),
164  m_maxPath(o.m_maxPath)
165  {
166  o.m_root = nullptr;
167  }
168 
169  gsHDomain & operator=(gsHDomain&& o)
170  {
171  delete m_root; m_root = o.m_root; o.m_root = nullptr;
172  m_upperIndex = std::move(o.m_upperIndex);
173  m_indexLevel = o.m_indexLevel;
174  m_maxInsLevel = o.m_maxInsLevel;
175  m_maxPath = o.m_maxPath;
176  return *this;
177  }
178 #endif
179 
181  void init(point const & upp, unsigned index_level)
182  {
183  m_indexLevel = index_level;
184  m_maxInsLevel = 0;
185 
186  if ( m_root )
187  delete m_root;
188 
189  for (short_t i=0; i<d; ++i)
190  m_upperIndex[i] = (upp[i]<< m_indexLevel);
191 
192  m_root = new node(m_upperIndex);
193  m_maxPath = 1;
194  }
195 
197  void init(point const & upp)
198  {
199  // Idea: find index_level so that for each i, upp[i] * (2 ^ index_level) does not overflow in Z.
200  // See issue #672 for more details.
201 
202  // backwards compatibility
203  Z oldMax = 13;
204 
205  Z numMax = std::numeric_limits<Z>::max();
206 
207  std::vector<Z> logUpps(d);
208  for(short_t i=0; i<d; i++)
209  {
210  // prevent division by zero
211  if(upp[i] == 1)
212  logUpps[i] = oldMax;
213  else
214  {
215  // floor of log_2 (numMax / upp[i]):
216  logUpps[i] = math::floor( (math::log(numMax) - math::log(upp[i])) / math::log(2) );
217  }
218  }
219 
220  // If the computed number would be too big we take 13 as we used to.
221  init(upp, std::min( *std::min_element(logUpps.begin(), logUpps.end()), oldMax) );
222  }
223 
225  ~gsHDomain() { delete m_root; }
226 
228  gsHDomain * clone() const;
229 
230 public:
231 
232  void computeFinestIndex(gsVector<Z, d> const & index,
233  unsigned lvl,
234  gsVector<Z, d> & result) const;
235 
236  void computeLevelIndex(gsVector<Z, d> const & index,
237  unsigned lvl,
238  gsVector<Z, d> & result) const;
239 
240  void local2globalIndex(gsVector<Z, d> const & index,
241  unsigned lvl,
242  gsVector<Z, d> & result) const;
243 
244  void global2localIndex(gsVector<Z, d> const & index,
245  unsigned lvl,
246  gsVector<Z, d> & result) const;
247 
249  const point & upperCorner() const
250  {
251  return m_upperIndex;
252  }
253 
255  const point upperCornerIndex() const
256  {
257  point ind = m_upperIndex;
258  for (short_t i=0; i<d; ++i)
259  ind[i] = (ind[i] >> m_indexLevel);
260  return ind;
261  }
262 
278  void insertBox (point const & lower, point const & upper,
279  node * _node, int lvl);
280 
290  void insertBox (point const & lower, point const & upper, int lvl)
291  { insertBox(lower, upper, m_root, lvl); }
292 
303  void clearBox (point const & lower, point const & upper,
304  int lvl);
305 
315  void sinkBox (point const & lower, point const & upper, int lvl);
316 
318  void internalIndex (point const & point_idx, int lvl, point & internal_idx)
319  {
320  for ( short_t i = 0; i!=d; ++i )
321  internal_idx[i] = point_idx[i] << (m_indexLevel-lvl);
322  }
323 
324 
344  bool query1 (point const & lower, point const & upper,
345  int level, node * _node ) const;
346 
388  bool query1 (point const & lower, point const & upper,
389  int level) const;
390 
403  bool query2 (point const & lower, point const & upper,
404  int level, node *_node ) const;
405 
416  bool query2 (point const & lower, point const & upper,
417  int level) const;
418 
427  int query3(point const & k1, point const & k2,
428  int level, node *_node ) const;
429 
442  int query3(point const & lower, point const & upper,
443  int level) const;
444 
447  int query4(point const & lower, point const & upper,
448  int level, node *_node) const;
449 
459  int query4(point const & lower, point const & upper,
460  int level) const;
461 
462  std::pair<point,point> queryLevelCell(point const & lower,
463  point const & upper,
464  int level) const;
465 
467  int levelOf(point const & p, int level) const
468  { return pointSearch(p,level,m_root)->level;}
469 
471  void incrementLevel();
472 
474  void multiplyByTwo();
475 
477  void divideByTwo();
478 
480  void decrementLevel();
481 
482  literator beginLeafIterator()
483  {
484  return literator(m_root, m_indexLevel);
485  }
486 
487  const_literator beginLeafIterator() const
488  {
489  return const_literator(m_root, m_indexLevel);
490  }
491 
492  void makeCompressed();
493 
495  int size() const;
496 
498  int numBreaks(int lvl, int k) const
499  {
500  return m_upperIndex[k] >> (m_indexLevel - lvl);
501  }
502 
504  int leafSize() const;
505 
507  std::pair<int,int> minMaxPath() const;
508 
510  void printLeaves() const;
511 
531  // getBoxes-functions might get removed at some point of time.
532  // Use iterators instead whenever possible.
533  void getBoxes(gsMatrix<Z>& b1,
534  gsMatrix<Z>& b2,
535  gsVector<Z>& level) const;
536 
548  // getBoxes-functions might get removed at some point of time.
549  // Use iterators instead whenever possible.
551  gsMatrix<Z>& b1,
552  gsMatrix<Z>& b2,
553  gsVector<Z>& level) const;
554 
555 
556 
564  // getBoxes-functions might get removed at some point of time.
565  // Use iterators instead whenever possible.
567  gsMatrix<Z>& b2,
568  gsVector<index_t>& level) const;
569 
572  std::vector<std::vector<std::vector<std::vector<Z>>>> getPolylines() const;
573 
574  std::vector<std::vector<std::vector<Z>>> getPolylinesSingleLevel(std::vector<gsVSegment<Z>>& seg) const;
575 
576 
577  inline unsigned getIndexLevel() const
578  {
579  return m_indexLevel;
580  }
581 
582  inline unsigned getMaxInsLevel() const
583  {
584  return m_maxInsLevel;
585  }
586 
587  void computeMaxInsLevel();
588 
589 private:
590 
595  static bool haveOverlap(box const & box1, box const & box2);
596 
598  static bool isContained(box const & box1, box const & box2);
599 
606  static std::pair<point,point> select_part(point const & k1, point const & k2,
607  point const & k3, point const & k4);
608 
609  static void bisectBox(box const & original,
610  int k, Z coord,
611  box & leftBox,
612  box & rightBox );
613 
619  static void setLevel(node *_node, int lvl);
620 
622  static bool isDegenerate(box const & someBox);
623 
625  void setIndexLevel(int) const
626  {
628  }
629 
640  // getBoxes-functions might get removed at some point of time.
641  // Use iterators instead whenever possible.
642  void getBoxes_vec(std::vector<std::vector<Z>>& boxes) const;
643 
654  void connect_Boxes(std::vector<std::vector<Z> > &boxes) const;
655  void connect_Boxes2d(std::vector<std::vector<Z> > &boxes) const;
656 
657  void connect_Boxes_2(std::vector<std::vector<Z> > &boxes) const;
658 
662  void getRidOfOverlaps( std::list< std::list< gsVSegment<Z> > >& vert_seg_lists ) const;
663 
665  void sweeplineConnectAndMerge( std::vector< std::vector< std::vector<Z> > >& result,
666  std::list< std::list< gsVSegment<Z> > >& vert_seg_lists ) const;
667 
668 
669 private:
670 
674  template<typename visitor>
675  typename visitor::return_type
676  boxSearch(point const & k1, point const & k2,
677  int level, node *_node) const;
678 
681  template<typename visitor>
682  typename visitor::return_type
683  leafSearch() const;
684 
687  template<typename visitor>
688  typename visitor::return_type
689  nodeSearch() const;
690 
695  node * pointSearch(const point & p, int level, node *_node) const;
696 
699  {
700  typedef int return_type;
701  static return_type init() {return 0;}
702 
703  static void visitLeaf(gsKdNode<d, Z> * leafNode, return_type &i)
704  {
705  if (leafNode->level>i) i=leafNode->level;
706  }
707  };
708 
711  {
712  typedef int return_type;
713  static return_type init() {return 0;}
714 
715  static void visitLeaf(gsKdNode<d, Z> * leafNode, return_type &)
716  {
717  leafNode->level++;
718  }
719  };
720 
723  {
724  typedef int return_type;
725  static return_type init() {return 0;}
726 
727  static void visitLeaf(gsKdNode<d, Z> * leafNode, return_type &)
728  {
729  leafNode->level--;
730  }
731  };
732 
735  {
736  typedef int return_type;
737  static return_type init() {return 0;}
738 
739  static void visitLeaf(gsKdNode<d, Z> * , return_type & i)
740  {
741  i++;
742  }
743  };
744 
747  {
748  typedef int return_type;
749  static return_type init() {return 0;}
750 
751  static void visitNode(gsKdNode<d, Z> * , return_type & i)
752  {
753  i++;
754  }
755  };
756 
759  {
760  typedef int return_type;
761  static return_type init() {return 0;}
762 
763  static void visitNode(gsKdNode<d, Z> * leafNode, return_type &)
764  {
765  leafNode->multiplyByTwo();
766  }
767  };
768 
771  {
772  typedef int return_type;
773  static return_type init() {return 0;}
774 
775  static void visitNode(gsKdNode<d, Z> * leafNode, return_type &)
776  {
777  leafNode->divideByTwo();
778  }
779  };
780 
783  {
784  typedef int return_type;
785  static return_type init() {return 0;}
786 
787  static void visitLeaf(gsKdNode<d, Z> * leafNode, return_type &)
788  {
789  gsInfo << *leafNode;
790  }
791  };
792 
794  // TODO: stop traverse as soon as it is found for the first time..
796  {
797  typedef std::pair<point,point> return_type;
798 
799  // initialize result
800  static return_type init()
801  {
802  return std::make_pair(point::Zero(),point::Zero());
803  //return return_type();//!does not properly initialize the points
804  }
805 
806  static void visitLeaf(gismo::gsKdNode<d, Z> * leafNode , int level, return_type & res)
807  {
808  if ( leafNode->level == level )
809  {
810  res.first = leafNode->lowCorner();
811  res.second = leafNode->uppCorner();
812  }
813  }
814  };
815 
816 };
817 
818 
819 }// end namespace gismo
820 
821 
822 #ifndef GISMO_BUILD_LIB
823 #include GISMO_HPP_HEADER(gsHDomain.hpp)
824 #endif
825 
Re-implements gsDomainIterator for iteration over all boundary elements of a hierarchical parameter d...
Definition: gsHDomain.h:24
void decrementLevel()
Decrement the level index globally.
Definition: gsHDomain.hpp:1380
static bool isDegenerate(box const &someBox)
Returns true if the box is degenerate (has zero volume)
Definition: gsHDomain.hpp:136
gsHDomain(const gsHDomain &o)
Copy constructor (makes a deep copy)
Definition: gsHDomain.h:133
gsHDomain * clone() const
Clones the object.
Definition: gsHDomain.hpp:96
static std::pair< point, point > select_part(point const &k1, point const &k2, point const &k3, point const &k4)
Definition: gsHDomain.hpp:488
Class for representing a vertical line segment in 2D. Helper for the class gsAAPolyline.
Definition: gsHDomain.h:33
bool query2(point const &lower, point const &upper, int level, node *_node) const
Returns true if the box defined by lower and upper is contained in a domain with a higher level than ...
Definition: gsHDomain.hpp:434
Decreases the level by 1 for all leaves.
Definition: gsHDomain.h:722
static bool haveOverlap(box const &box1, box const &box2)
Definition: gsHDomain.hpp:103
#define GISMO_NO_IMPLEMENTATION
Definition: gsDebug.h:129
visitor::return_type nodeSearch() const
Definition: gsHDomain.hpp:610
Iterates over the leaves of an gsHDomain (tree).
Definition: gsHDomainLeafIter.h:29
int leafSize() const
Returns the number of leaves in the tree.
Definition: gsHDomain.hpp:1393
void setIndexLevel(int) const
Adds nlevels new index levels in the tree.
Definition: gsHDomain.h:625
bool query1(point const &lower, point const &upper, int level, node *_node) const
Returns true if the box defined by lower and upper is completely contained in level and does not over...
Definition: gsHDomain.hpp:420
#define short_t
Definition: gsConfig.h:35
unsigned m_maxInsLevel
Maximum level present in the tree.
Definition: gsHDomain.h:111
Provides structs and classes related to interfaces and boundaries.
static bool isContained(box const &box1, box const &box2)
Returns true if box1 is contained in box2.
Definition: gsHDomain.hpp:110
void init(point const &upp, unsigned index_level)
Initialize the tree.
Definition: gsHDomain.h:181
void insertBox(point const &lower, point const &upper, int lvl)
The insert function which insert box defined by points lower and upper to level lvl.
Definition: gsHDomain.h:290
side
Identifiers for topological sides.
Definition: gsBoundary.h:58
void multiplyByTwo()
Multiply all coordinates by two.
Definition: gsHDomain.hpp:1366
Struct representing a kd-tree node.
Definition: gsKdNode.h:34
void incrementLevel()
Increment the level index globally.
Definition: gsHDomain.hpp:1355
void getBoxesInLevelIndex(gsMatrix< Z > &b1, gsMatrix< Z > &b2, gsVector< index_t > &level) const
Definition: gsHDomain.hpp:790
std::vector< std::vector< std::vector< std::vector< Z > > > > getPolylines() const
Definition: gsHDomain.hpp:1094
void sweeplineConnectAndMerge(std::vector< std::vector< std::vector< Z > > > &result, std::list< std::list< gsVSegment< Z > > > &vert_seg_lists) const
Sweepline algorithm.
Definition: gsHDomain.hpp:1216
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition: gsMatrix.h:38
Decreases the level by 1 for all leaves.
Definition: gsHDomain.h:698
void init(point const &upp)
Initialize the tree with computing the index_level.
Definition: gsHDomain.h:197
int levelOf(point const &p, int level) const
Returns the level of the point p.
Definition: gsHDomain.h:467
void clearBox(point const &lower, point const &upper, int lvl)
The clear function which clears box defined by points lower and upper to level lvl.
Definition: gsHDomain.hpp:225
Counts number of nodes in the tree.
Definition: gsHDomain.h:782
Increases the level by 1 for all leaves.
Definition: gsHDomain.h:710
int query3(point const &k1, point const &k2, int level, node *_node) const
Definition: gsHDomain.hpp:448
void getBoxes(gsMatrix< Z > &b1, gsMatrix< Z > &b2, gsVector< Z > &level) const
Returns the boxes which make up the hierarchical domain and the respective levels.
Definition: gsHDomain.hpp:710
void internalIndex(point const &point_idx, int lvl, point &internal_idx)
Returns the internal coordinates of point point_idx of level lvl.
Definition: gsHDomain.h:318
Provides declaration of HDomainLeafIter class.
Multiplies everything by 2.
Definition: gsHDomain.h:770
#define gsInfo
Definition: gsDebug.h:43
Counts number of nodes in the tree.
Definition: gsHDomain.h:734
void printLeaves() const
Prints out the leaves of the kd-tree.
Definition: gsHDomain.hpp:1399
void sinkBox(point const &lower, point const &upper, int lvl)
Sinks the box defined by points lower and upper to one level higher.
Definition: gsHDomain.hpp:304
~gsHDomain()
Destructor deletes the whole tree.
Definition: gsHDomain.h:225
std::pair< int, int > minMaxPath() const
Returns the minimim and maximum path length in the tree.
Definition: gsHDomain.hpp:675
node * pointSearch(const point &p, int level, node *_node) const
Definition: gsHDomain.hpp:572
void getRidOfOverlaps(std::list< std::list< gsVSegment< Z > > > &vert_seg_lists) const
Definition: gsHDomain.hpp:1176
int size() const
Returns the number of nodes in the tree.
Definition: gsHDomain.hpp:1387
Class with a hierarchical domain structure represented by a box k-d-tree.
Definition: gsHDomain.h:75
static void setLevel(node *_node, int lvl)
Definition: gsHDomain.hpp:117
Counts number of nodes in the tree.
Definition: gsHDomain.h:746
int level
Definition: gsKdNode.h:49
void getBoxes_vec(std::vector< std::vector< Z >> &boxes) const
Represents boxes of the tree in a big vector.
Definition: gsHDomain.hpp:1044
Returns an cell/element box of a requested level.
Definition: gsHDomain.h:795
const point & upperCorner() const
Accessor for gsHDomain::m_upperIndex.
Definition: gsHDomain.h:249
void insertBox(point const &lower, point const &upper, node *_node, int lvl)
The insert function which insert box defined by points lower and upper to level lvl.
Definition: gsHDomain.hpp:143
gsHDomain & operator=(const gsHDomain &o)
Assignment operator (makes a deep copy)
Definition: gsHDomain.h:143
const point upperCornerIndex() const
Return the upper corner of the tree in level 0.
Definition: gsHDomain.h:255
Struct of for an Axis-aligned bounding box.
Definition: gsAABB.h:30
int numBreaks(int lvl, int k) const
Returns the number of distinct knots in direction k of level lvl.
Definition: gsHDomain.h:498
This is the main header file that collects wrappers of Eigen for linear algebra.
visitor::return_type leafSearch() const
Definition: gsHDomain.hpp:642
visitor::return_type boxSearch(point const &k1, point const &k2, int level, node *_node) const
Definition: gsHDomain.hpp:518
node * m_root
Pointer to the root node of the tree.
Definition: gsHDomain.h:94
EIGEN_MAKE_ALIGNED_OPERATOR_NEW unsigned m_indexLevel
The level of the box representation (global indices)
Definition: gsHDomain.h:108
Multiplies everything by 2.
Definition: gsHDomain.h:758
void divideByTwo()
Divide all coordinates by two.
Definition: gsHDomain.hpp:1373
void getBoxesOnSide(boundary::side s, gsMatrix< Z > &b1, gsMatrix< Z > &b2, gsVector< Z > &level) const
Returns the boxes which make up the hierarchical domain and the respective levels touching side s...
Definition: gsHDomain.hpp:739
void connect_Boxes(std::vector< std::vector< Z > > &boxes) const
connect the boxes returned from quadtree getBoxes_vec()
Definition: gsHDomain.hpp:898
int query4(point const &lower, point const &upper, int level, node *_node) const
Definition: gsHDomain.hpp:462
point m_upperIndex
Keeps the highest upper indices (at level gsHDomain::m_indexLevel)
Definition: gsHDomain.h:102