KratosMultiphysics
KRATOS Multiphysics (Kratos) is a framework for building parallel, multi-disciplinary simulation software, aiming at modularity, extensibility, and high performance. Kratos is written in C++, and counts with an extensive Python interface.
kd_tree.h
Go to the documentation of this file.
1 // | / |
2 // ' / __| _` | __| _ \ __|
3 // . \ | ( | | ( |\__ `
4 // _|\_\_| \__,_|\__|\___/ ____/
5 // Multi-Physics
6 //
7 // License: BSD License
8 // Kratos default license: kratos/license.txt
9 //
10 // Main authors: clabra
11 //
12 
13 #pragma once
14 
15 // System includes
16 #include <string>
17 #include <iostream>
18 #include <cstddef>
19 #include <vector>
20 
21 // External includes
22 
23 // Project includes
24 #include "tree.h"
25 
26 namespace Kratos
27 {
30 
34 
38 
42 
46 
47 
49 
51 template< class TLeafType >
52 class KDTreePartitionBase : public TreeNode< TLeafType::Dimension,
53  typename TLeafType::PointType,
54  typename TLeafType::PointerType,
55  typename TLeafType::IteratorType,
56  typename TLeafType::DistanceIteratorType >
57 {
58 public:
61 
64 
65  typedef TLeafType LeafType;
66 
67  typedef typename LeafType::PointType PointType;
68 
70 
72 
73  typedef typename LeafType::DistanceIteratorType DistanceIteratorType;
74 
75  typedef typename LeafType::PointerType PointerType;
76 
77  typedef typename LeafType::DistanceFunction DistanceFunction;
78 
79  enum { Dimension = LeafType::Dimension };
80 
82 
84 
85  typedef typename TreeNodeType::SizeType SizeType;
86 
88 
89  //typedef typename TreeNodeType::SearchStructureType SearchStructureType;
90  typedef typename LeafType::SearchStructureType SearchStructureType;
91 
95 
96 
98  KDTreePartitionBase(IndexType CutingDimension, CoordinateType Position,
99  CoordinateType LeftEnd, CoordinateType RightEnd,
100  TreeNodeType* pLeftChild = NULL, TreeNodeType* pRightChild = NULL)
101  : mCutingDimension(CutingDimension), mPosition(Position), mLeftEnd(LeftEnd), mRightEnd(RightEnd)
102  {
103  mpChilds[0] = pLeftChild;
104  mpChilds[1] = pRightChild;
105  }
106 
107  void PrintData(std::ostream& rOStream, std::string const& Perfix = std::string()) const override
108  {
109  rOStream << Perfix << "Partition at ";
110  switch(mCutingDimension)
111  {
112  case 0:
113  rOStream << "X =";
114  break;
115  case 1:
116  rOStream << "Y =";
117  break;
118  case 2:
119  rOStream << "Z =";
120  break;
121  default:
122  rOStream << mCutingDimension << " in";
123  break;
124  }
125  rOStream << mPosition << " from " << mLeftEnd << " to " << mRightEnd << std::endl;
126 
127  mpChilds[0]->PrintData(rOStream, Perfix + " ");
128  mpChilds[1]->PrintData(rOStream, Perfix + " ");
129 
130  }
131 
134  {
135  delete mpChilds[0];
136  delete mpChilds[1];
137  }
138 
139 
143 
145  PointType const& rThisPoint,
146  PointerType& rResult,
147  CoordinateType& rResultDistance
148  ) override
149  {
150  SearchStructureType Auxiliar;
151  for(SizeType i = 0 ; i < Dimension; i++)
152  Auxiliar.residual_distance[i] = 0.00;
153  SearchNearestPoint(rThisPoint, rResult, rResultDistance, Auxiliar );
154  }
155 
157  PointType const& rThisPoint,
158  PointerType& rResult,
159  CoordinateType& rResultDistance,
160  SearchStructureType& Auxiliar
161  ) override
162  {
163  CoordinateType temp = Auxiliar.residual_distance[mCutingDimension];
164  CoordinateType distance_to_partition = rThisPoint[mCutingDimension] - mPosition;
165 
166  if( distance_to_partition < 0.0 ) // The point is in the left partition
167  {
168  //searching in the left child
169  mpChilds[0]->SearchNearestPoint(rThisPoint, rResult, rResultDistance, Auxiliar );
170 
171  // compare with distance to right partition
172  Auxiliar.residual_distance[mCutingDimension] = distance_to_partition * distance_to_partition;
173  Auxiliar.distance_to_partition2 = Auxiliar.residual_distance[0];
174  for(SizeType i = 1; i < Dimension; i++)
175  Auxiliar.distance_to_partition2 += Auxiliar.residual_distance[i];
176  if( rResultDistance > Auxiliar.distance_to_partition2 )
177  mpChilds[1]->SearchNearestPoint(rThisPoint, rResult, rResultDistance, Auxiliar );
178 
179  }
180  else // The point is in the right partition
181  {
182  //Searching in the right child
183  mpChilds[1]->SearchNearestPoint(rThisPoint, rResult, rResultDistance, Auxiliar );
184 
185  // compare with distance to left partition
186  Auxiliar.residual_distance[mCutingDimension] = distance_to_partition * distance_to_partition;
187  Auxiliar.distance_to_partition2 = Auxiliar.residual_distance[0];
188  for(SizeType i = 1; i < Dimension; i++)
189  Auxiliar.distance_to_partition2 += Auxiliar.residual_distance[i];
190  if( rResultDistance > Auxiliar.distance_to_partition2 )
191  mpChilds[0]->SearchNearestPoint( rThisPoint, rResult, rResultDistance, Auxiliar );
192  }
193  Auxiliar.residual_distance[mCutingDimension] = temp;
194 
195  }
196 
198  PointType const& ThisPoint,
199  CoordinateType const& Radius,
200  CoordinateType const& Radius2,
201  IteratorType& Results,
202  DistanceIteratorType& ResultsDistances,
203  SizeType& NumberOfResults,
204  SizeType const& MaxNumberOfResults
205  ) override
206  {
207  SearchStructureType Auxiliar;
208  for(SizeType i = 0 ; i < Dimension; i++)
209  Auxiliar.residual_distance[i] = 0.00;
210  SearchInRadius(ThisPoint, Radius, Radius2, Results, ResultsDistances, NumberOfResults, MaxNumberOfResults, Auxiliar );
211  }
212 
214  PointType const& ThisPoint,
215  CoordinateType const& Radius,
216  CoordinateType const& Radius2,
217  IteratorType& Results,
218  DistanceIteratorType& ResultsDistances,
219  SizeType& NumberOfResults,
220  SizeType const& MaxNumberOfResults,
221  SearchStructureType& Auxiliar
222  ) override
223  {
224  const CoordinateType temp = Auxiliar.residual_distance[mCutingDimension];
225  const CoordinateType distance_to_partition = ThisPoint[mCutingDimension] - mPosition;
226 
227  if(distance_to_partition < 0) // The point is in the left partition
228  {
229  //searching in the left child
230  mpChilds[0]->SearchInRadius(ThisPoint, Radius, Radius2, Results, ResultsDistances, NumberOfResults, MaxNumberOfResults, Auxiliar );
231 
232  Auxiliar.residual_distance[mCutingDimension] = distance_to_partition * distance_to_partition;
233  Auxiliar.distance_to_partition2 = Auxiliar.residual_distance[0];
234  for(SizeType i = 1; i < Dimension; i++)
235  Auxiliar.distance_to_partition2 += Auxiliar.residual_distance[i];
236  // The points is too near to the wall and the other child is in the searching radius
237  if( Radius2 >= Auxiliar.distance_to_partition2 )
238  mpChilds[1]->SearchInRadius(ThisPoint, Radius, Radius2, Results, ResultsDistances, NumberOfResults, MaxNumberOfResults, Auxiliar );
239  }
240  else // The point is in the right partition
241  {
242  //searching in the left child
243  mpChilds[1]->SearchInRadius(ThisPoint, Radius, Radius2, Results, ResultsDistances, NumberOfResults, MaxNumberOfResults, Auxiliar );
244 
245  Auxiliar.residual_distance[mCutingDimension] = distance_to_partition * distance_to_partition;
246  Auxiliar.distance_to_partition2 = Auxiliar.residual_distance[0];
247  for(SizeType i = 1; i < Dimension; i++)
248  Auxiliar.distance_to_partition2 += Auxiliar.residual_distance[i];
249  // The points is too near to the wall and the other child is in the searching radius
250  if( Radius2 >= Auxiliar.distance_to_partition2 )
251  mpChilds[0]->SearchInRadius(ThisPoint, Radius, Radius2, Results, ResultsDistances, NumberOfResults, MaxNumberOfResults, Auxiliar );
252  }
253  Auxiliar.residual_distance[mCutingDimension] = temp;
254 
255  }
256 
258  PointType const& ThisPoint,
259  CoordinateType const& Radius,
260  CoordinateType const& Radius2,
261  IteratorType& Results,
262  SizeType& NumberOfResults,
263  SizeType const& MaxNumberOfResults
264  ) override
265  {
266  SearchStructureType Auxiliar;
267  for(SizeType i = 0 ; i < Dimension; i++)
268  Auxiliar.residual_distance[i] = 0.00;
269  SearchInRadius(ThisPoint, Radius, Radius2, Results, NumberOfResults, MaxNumberOfResults, Auxiliar );
270  }
271 
273  PointType const& ThisPoint,
274  CoordinateType const& Radius,
275  CoordinateType const& Radius2,
276  IteratorType& Results,
277  SizeType& NumberOfResults,
278  SizeType const& MaxNumberOfResults,
279  SearchStructureType& Auxiliar
280  ) override
281  {
282  CoordinateType temp = Auxiliar.residual_distance[mCutingDimension];
283  CoordinateType distance_to_partition = ThisPoint[mCutingDimension] - mPosition;
284 
285  if(distance_to_partition < 0) // The point is in the left partition
286  {
287  //searching in the left child
288  mpChilds[0]->SearchInRadius(ThisPoint, Radius, Radius2, Results, NumberOfResults, MaxNumberOfResults, Auxiliar );
289 
290  Auxiliar.residual_distance[mCutingDimension] = distance_to_partition * distance_to_partition;
291  Auxiliar.distance_to_partition2 = Auxiliar.residual_distance[0];
292  for(SizeType i = 1; i < Dimension; i++)
293  Auxiliar.distance_to_partition2 += Auxiliar.residual_distance[i];
294  // The points is too near to the wall and the other child is in the searching radius
295  if( Radius2 >= Auxiliar.distance_to_partition2 )
296  mpChilds[1]->SearchInRadius(ThisPoint, Radius, Radius2, Results, NumberOfResults, MaxNumberOfResults, Auxiliar );
297  Auxiliar.residual_distance[mCutingDimension] = temp;
298  }
299  else // The point is in the right partition
300  {
301  //searching in the left child
302  mpChilds[1]->SearchInRadius(ThisPoint, Radius, Radius2, Results, NumberOfResults, MaxNumberOfResults, Auxiliar );
303 
304  Auxiliar.residual_distance[mCutingDimension] = distance_to_partition * distance_to_partition;
305  Auxiliar.distance_to_partition2 = Auxiliar.residual_distance[0];
306  for(SizeType i = 1; i < Dimension; i++)
307  Auxiliar.distance_to_partition2 += Auxiliar.residual_distance[i];
308  // The points is too near to the wall and the other child is in the searching radius
309  if( Radius2 >= Auxiliar.distance_to_partition2 )
310  mpChilds[0]->SearchInRadius(ThisPoint, Radius, Radius2, Results, NumberOfResults, MaxNumberOfResults, Auxiliar );
311  Auxiliar.residual_distance[mCutingDimension] = temp;
312  }
313 
314  }
315 
317  PointType const& SearchMinPoint,
318  PointType const& SearchMaxPoint,
319  IteratorType& Results,
320  SizeType& NumberOfResults,
321  SizeType const& MaxNumberOfResults
322  ) override
323  {
324  if( SearchMinPoint[mCutingDimension] <= mPosition )
325  mpChilds[0]->SearchInBox(SearchMinPoint,SearchMaxPoint,Results,NumberOfResults,MaxNumberOfResults);
326  if( SearchMaxPoint[mCutingDimension] >= mPosition )
327  mpChilds[1]->SearchInBox(SearchMinPoint,SearchMaxPoint,Results,NumberOfResults,MaxNumberOfResults);
328  }
329 
330 
332 
333  /* virtual static IteratorType Partition( IteratorType PointsBegin, IteratorType PointsEnd, IndexType& rCuttingDimension, CoordinateType& rCuttingValue ) = 0; */
334 
335 public:
336 
337  /* virtual TreeNodeType* Construct(IteratorType PointsBegin, IteratorType PointsEnd, PointType HighPoint, PointType LowPoint, SizeType BucketSize) = 0; */
338 
339 private:
340 
341  IndexType mCutingDimension;
342  CoordinateType mPosition; // Position of partition
343  CoordinateType mLeftEnd; // Left extend of partition
344  CoordinateType mRightEnd; // Right end of partition
345  TreeNodeType* mpChilds[2]; // The mpChilds[0] is the left child
346  // and mpChilds[1] is the right child.
347 
348 };
349 
350 //
351 //
352 //
353 // Median Split KD_Tree Partition
354 //
355 //
356 //
357 //
358 
359 
360 template< class TLeafType >
361 class KDTreePartition : public KDTreePartitionBase<TLeafType>
362 {
363 public:
366 
369 
371 
372  typedef TLeafType LeafType;
373 
374  typedef typename LeafType::PointType PointType;
375 
377 
379 
380  typedef typename LeafType::DistanceIteratorType DistanceIteratorType;
381 
382  typedef typename LeafType::PointerType PointerType;
383 
384  typedef typename LeafType::DistanceFunction DistanceFunction;
385 
386  enum { Dimension = LeafType::Dimension };
387 
389 
391 
393 
395 
396  //typedef typename TreeNodeType::SearchStructureType SearchStructureType;
397  typedef typename LeafType::SearchStructureType SearchStructureType;
398 
402 
403 
405  KDTreePartition( IndexType CutingDimension, CoordinateType Position, CoordinateType LeftEnd, CoordinateType RightEnd,
406  TreeNodeType* pLeftChild = NULL, TreeNodeType* pRightChild = NULL )
407  : BaseType(CutingDimension,Position,LeftEnd,RightEnd,pLeftChild,pRightChild) {}
408 
411 
412 
416 
418 
420  IteratorType PointsBegin,
421  IteratorType PointsEnd,
422  IndexType& rCuttingDimension,
423  CoordinateType& rCuttingValue
424  )
425  {
426  const SizeType n = SearchUtils::PointerDistance(PointsBegin, PointsEnd);
427  // find dimension of maximum spread
428  rCuttingDimension = MaxSpread(PointsBegin, PointsEnd);
429  IteratorType partition = PointsBegin + n / 2;
430 
431  MedianSplit(PointsBegin, partition, PointsEnd, rCuttingDimension, rCuttingValue);
432 
433  return partition;
434  }
435 
437  IteratorType PointsBegin,
438  IteratorType PointsEnd
439  )
440  {
441  SizeType max_dimension = 0; // dimension of max spread
442  CoordinateType max_spread = 0; // amount of max spread
443 
444  /* if(PointsBegin == PointsEnd) // If there is no point return the first coordinate */
445  /* return max_dimension; */
446 
449  for (SizeType d = 0; d < Dimension; d++)
450  {
451  min[d] = (**PointsBegin)[d];
452  max[d] = (**PointsBegin)[d];
453  }
454  for (IteratorType i_point = PointsBegin; i_point != PointsEnd; i_point++)
455  {
456  for (SizeType d = 0; d < Dimension; d++)
457  {
458  CoordinateType c = (**i_point)[d];
459  if (c < min[d])
460  min[d] = c;
461  else if (c > max[d])
462  max[d] = c;
463  }
464  }
465  max_dimension = 0;
466  max_spread = max[0] - min[0];
467  for (SizeType d = 1; d < Dimension; d++)
468  {
469  CoordinateType spread = max[d] - min[d];
470  if (spread > max_spread)
471  {
472  max_spread = spread;
473  max_dimension = d;
474  }
475  }
476 
477  return max_dimension;
478  }
479 
480  static void MedianSplit(
481  IteratorType PointsBegin,
482  IteratorType PartitionPosition,
483  IteratorType PointsEnd,
484  IndexType CuttingDimension,
485  CoordinateType& rCuttingValue
486  )
487  {
488  IteratorType left = PointsBegin;
489  IteratorType right = PointsEnd - 1;
490  while (left < right) // Iterating to find the partition point
491  {
492 
493  IteratorType i = left; // selecting left as pivot
494  if ((**i)[CuttingDimension] > (**right)[CuttingDimension])
495  std::swap(*i,*right);
496 
497  CoordinateType value = (**i)[CuttingDimension];
498  IteratorType j = right;
499  for(;;)
500  {
501  while ((**(++i))[CuttingDimension] < value)
502  ;
503 
504  while ((**(--j))[CuttingDimension] > value)
505  ;
506  if (i < j) std::swap(*i,*j);
507  else break;
508  }
509  std::swap(*left,*j);
510 
511  if (j > PartitionPosition)
512  right = j - 1;
513  else if (j < PartitionPosition)
514  left = j + 1;
515  else break;
516  }
517 
518  CoordinateType max = (**PointsBegin)[CuttingDimension];
519  IteratorType k = PointsBegin;
520  IteratorType last = PartitionPosition;
521 
522  for(IteratorType i = PointsBegin ; i != PartitionPosition ; ++i)
523  if((**i)[CuttingDimension] > max)
524  {
525  max = (**i)[CuttingDimension];
526  k = i;
527  }
528 
529  if(k != PointsBegin)
530  std::swap(--last, k);
531 
532  rCuttingValue = ((**last)[CuttingDimension] + (**PartitionPosition)[CuttingDimension])/2.0;
533  }
534 
535 public:
536 
537 // static TreeNodeType* Construct(IteratorType PointsBegin, IteratorType PointsEnd, PointType HighPoint, PointType LowPoint, SizeType BucketSize)
539  IteratorType PointsBegin,
540  IteratorType PointsEnd,
541  const PointType& HighPoint,
542  const PointType& LowPoint,
543  SizeType BucketSize
544  )
545  {
546  SizeType number_of_points = SearchUtils::PointerDistance(PointsBegin,PointsEnd);
547  if (number_of_points == 0)
548  return NULL;
549  else if (number_of_points <= BucketSize)
550  {
551  return new LeafType(PointsBegin, PointsEnd);
552  }
553  else
554  {
555  IndexType cutting_dimension;
556  CoordinateType cutting_value;
557 
558  IteratorType partition = Partition(PointsBegin, PointsEnd, cutting_dimension, cutting_value);
559 
560 // PointType partition_high_point = HighPoint;
561 // PointType partition_low_point = LowPoint;
562  PointType partition_high_point;
563  partition_high_point.Coordinates() = HighPoint.Coordinates();
564  PointType partition_low_point;
565  partition_low_point.Coordinates() = LowPoint.Coordinates();
566 
567  partition_high_point[cutting_dimension] = cutting_value;
568  partition_low_point[cutting_dimension] = cutting_value;
569 
570  return new KDTreePartition( cutting_dimension, cutting_value,
571  HighPoint[cutting_dimension], LowPoint[cutting_dimension],
572  Construct(PointsBegin, partition, partition_high_point, LowPoint, BucketSize),
573  Construct(partition, PointsEnd, HighPoint, partition_low_point, BucketSize) );
574 
575  }
576  }
577 
578 };
579 
580 //
581 //
582 //
583 // Average Split KD_Tree Partition
584 //
585 //
586 //
587 //
588 
589 
590 template< class TLeafType >
592 {
593 public:
596 
599 
601 
602  typedef TLeafType LeafType;
603 
604  typedef typename LeafType::PointType PointType;
605 
607 
609 
610  typedef typename LeafType::DistanceIteratorType DistanceIteratorType;
611 
612  typedef typename LeafType::PointerType PointerType;
613 
614  typedef typename LeafType::DistanceFunction DistanceFunction;
615 
616  enum { Dimension = LeafType::Dimension };
617 
619 
621 
623 
625 
626  //typedef typename TreeNodeType::SearchStructureType SearchStructureType;
627  typedef typename LeafType::SearchStructureType SearchStructureType;
628 
632 
633 
636  IndexType CutingDimension,
637  CoordinateType Position,
638  CoordinateType LeftEnd,
639  CoordinateType RightEnd,
640  TreeNodeType* pLeftChild = NULL,
641  TreeNodeType* pRightChild = NULL
642  )
643  : BaseType(CutingDimension,Position,LeftEnd,RightEnd,pLeftChild,pRightChild)
644  {
645  }
646 
649 
653 
654 
656 
658  IteratorType PointsBegin,
659  IteratorType PointsEnd,
660  IndexType& rCuttingDimension,
661  CoordinateType& rCuttingValue
662  )
663  {
664 
665  rCuttingDimension = MaxSpread( PointsBegin, PointsEnd, rCuttingValue );
666 
667  IteratorType partition;
668  AverageSplit(PointsBegin, partition, PointsEnd, rCuttingDimension, rCuttingValue);
669 
670  return partition;
671 
672  }
673 
675  IteratorType PointsBegin,
676  IteratorType PointsEnd,
677  CoordinateType& AverageValue
678  )
679  {
680  SizeType max_dimension = 0; // dimension of max spread
681  CoordinateType max_spread = 0; // amount of max spread
682  AverageValue = 0.0;
683 
684  CoordinateType size = static_cast<CoordinateType>(SearchUtils::PointerDistance(PointsBegin,PointsEnd));
685 
689  for (SizeType d = 0; d < Dimension; d++)
690  {
691  Average[d] = 0.0;
692  min[d] = (**PointsBegin)[d];
693  max[d] = (**PointsBegin)[d];
694  }
695  for (IteratorType i_point = PointsBegin; i_point != PointsEnd; i_point++)
696  {
697  for (SizeType d = 0; d < Dimension; d++)
698  {
699  CoordinateType c = (**i_point)[d];
700  Average[d] += c;
701  if (c < min[d])
702  min[d] = c;
703  else if (c > max[d])
704  max[d] = c;
705  }
706  }
707  max_dimension = 0;
708  max_spread = max[0] - min[0];
709  AverageValue = Average[0] / size;
710  for (SizeType d = 1; d < Dimension; d++)
711  {
712  CoordinateType spread = max[d] - min[d];
713  if (spread > max_spread)
714  {
715  max_spread = spread;
716  max_dimension = d;
717  AverageValue = Average[d] / size;
718  }
719  }
720 
721  return max_dimension;
722  }
723 
724 
725  static void AverageSplit(
726  IteratorType PointsBegin,
727  IteratorType& PartitionPosition,
728  IteratorType PointsEnd,
729  IndexType& CuttingDimension,
730  CoordinateType& rCuttingValue
731  )
732  {
733  // reorder by cutting_dimension
734  IteratorType left = PointsBegin;
735  IteratorType right = PointsEnd - 1;
736  for(;;)
737  {
738  while( left < PointsEnd && (**left)[CuttingDimension] < rCuttingValue ) left++;
739  while( right > PointsBegin && (**right)[CuttingDimension] >= rCuttingValue ) right--;
740  if (left <= right) std::swap(*left,*right);
741  else break;
742  }
743 
744  PartitionPosition = left;
745  }
746 
747 public:
749  IteratorType PointsBegin,
750  IteratorType PointsEnd,
751  PointType HighPoint,
752  PointType LowPoint,
753  SizeType BucketSize
754  )
755  {
756  SizeType number_of_points = SearchUtils::PointerDistance(PointsBegin,PointsEnd);
757  if (number_of_points == 0)
758  return NULL;
759  else if (number_of_points <= BucketSize)
760  {
761  return new LeafType(PointsBegin, PointsEnd);
762  }
763  else
764  {
765  IndexType cutting_dimension;
766  CoordinateType cutting_value;
767 
768  IteratorType partition = Partition(PointsBegin, PointsEnd, cutting_dimension, cutting_value);
769 
770  PointType partition_high_point = HighPoint;
771  PointType partition_low_point = LowPoint;
772 
773  partition_high_point[cutting_dimension] = cutting_value;
774  partition_low_point[cutting_dimension] = cutting_value;
775 
776  return new KDTreePartitionAverageSplit( cutting_dimension, cutting_value,
777  HighPoint[cutting_dimension], LowPoint[cutting_dimension],
778  Construct(PointsBegin, partition, partition_high_point, LowPoint, BucketSize),
779  Construct(partition, PointsEnd, HighPoint, partition_low_point, BucketSize) );
780 
781  }
782  }
783 
784 };
785 
786 //
787 //
788 //
789 // MidPoint Split KD_Tree Partition
790 //
791 //
792 //
793 //
794 
795 template< class TLeafType >
797 {
798 public:
801 
804 
806 
807  typedef TLeafType LeafType;
808 
809  typedef typename LeafType::PointType PointType;
810 
812 
814 
815  typedef typename LeafType::DistanceIteratorType DistanceIteratorType;
816 
817  typedef typename LeafType::PointerType PointerType;
818 
819  typedef typename LeafType::DistanceFunction DistanceFunction;
820 
821  enum { Dimension = LeafType::Dimension };
822 
824 
826 
828 
830 
831  //typedef typename TreeNodeType::SearchStructureType SearchStructureType;
832  typedef typename LeafType::SearchStructureType SearchStructureType;
833 
837 
840  TreeNodeType* pLeftChild = NULL, TreeNodeType* pRightChild = NULL)
841  : BaseType(CutingDimension,Position,LeftEnd,RightEnd,pLeftChild,pRightChild) {}
842 
845 
849 
851 
853  IteratorType PointsBegin,
854  IteratorType PointsEnd,
855  PointType const& HighPoint,
856  PointType const& LowPoint,
857  IndexType& rCuttingDimension,
858  CoordinateType& rCuttingValue
859  )
860  {
861  rCuttingDimension = MaxSpread( PointsBegin, PointsEnd, HighPoint, LowPoint, rCuttingValue );
862  /*
863  rCuttingDimension = 0;
864  double max_spread = HighPoint[0] - LowPoint[0];
865  double spread;
866  for (SizeType i = 1; i < Dimension; i++)
867  {
868  spread = HighPoint[i] - LowPoint[i];
869  if (spread > max_spread)
870  {
871  rCuttingDimension = i;
872  max_spread = spread;
873  }
874  }
875  rCuttingValue = (LowPoint[rCuttingDimension] + HighPoint[rCuttingDimension]) / 2.00;
876  */
877  return Split(PointsBegin, PointsEnd, rCuttingDimension, rCuttingValue);
878  }
879 
881  IteratorType PointsBegin,
882  IteratorType PointsEnd,
883  PointType const& HighPoint,
884  PointType const& LowPoint,
885  CoordinateType& CuttingValue
886  )
887  {
888 
889  //CoordinateType size = static_cast<CoordinateType>(SearchUtils::PointerDistance(PointsBegin,PointsEnd));
890 
893  for (SizeType d = 0; d < Dimension; d++)
894  {
895  min[d] = (**PointsBegin)[d];
896  max[d] = (**PointsBegin)[d];
897  }
898  for (IteratorType i_point = PointsBegin; i_point != PointsEnd; i_point++)
899  for (SizeType d = 0; d < Dimension; d++)
900  {
901  CoordinateType c = (**i_point)[d];
902  if (c < min[d])
903  min[d] = c;
904  else if (c > max[d])
905  max[d] = c;
906  }
907  SizeType max_dimension = 0;
908  CoordinateType max_spread = max[0] - min[0];
909  for (SizeType d = 1; d < Dimension; d++)
910  {
911  CoordinateType spread = max[d] - min[d];
912  if (spread > max_spread)
913  {
914  max_spread = spread;
915  max_dimension = d;
916  }
917  }
918  CuttingValue = (max[max_dimension]+min[max_dimension]) / 2.00;
919 
920  return max_dimension;
921  }
922 
924  IteratorType PointsBegin,
925  IteratorType PointsEnd,
926  IndexType& CuttingDimension,
927  CoordinateType& rCuttingValue
928  )
929  {
930  // reorder by cutting_dimension
931  IteratorType left = PointsBegin;
932  IteratorType right = PointsEnd - 1;
933  for(;;)
934  {
935  while( (**left)[CuttingDimension] < rCuttingValue ) left++;
936  while( (**right)[CuttingDimension] >= rCuttingValue ) right--;
937  if (left < right) std::swap(*left,*right);
938  else break;
939  }
940 
941  return left;
942  }
943 
944 public:
946  IteratorType PointsBegin,
947  IteratorType PointsEnd,
948  PointType HighPoint,
949  PointType LowPoint,
950  SizeType BucketSize
951  )
952  {
953  SizeType number_of_points = SearchUtils::PointerDistance(PointsBegin,PointsEnd);
954  if (number_of_points == 0)
955  return NULL;
956  else if (number_of_points <= BucketSize)
957  {
958  return new LeafType(PointsBegin, PointsEnd);
959  }
960  else
961  {
962  IndexType cutting_dimension;
963  CoordinateType cutting_value;
964 
965  IteratorType partition = Partition(PointsBegin, PointsEnd, HighPoint, LowPoint, cutting_dimension, cutting_value);
966 
967  PointType partition_high_point = HighPoint;
968  PointType partition_low_point = LowPoint;
969 
970  partition_high_point[cutting_dimension] = cutting_value;
971  partition_low_point[cutting_dimension] = cutting_value;
972 
973  return new KDTreePartitionMidPointSplit( cutting_dimension, cutting_value,
974  HighPoint[cutting_dimension], LowPoint[cutting_dimension],
975  Construct(PointsBegin, partition, partition_high_point, LowPoint, BucketSize),
976  Construct(partition, PointsEnd, HighPoint, partition_low_point, BucketSize) );
977 
978  }
979  }
980 
981 };
982 
983 } // namespace Kratos.
Definition: kd_tree.h:592
static void AverageSplit(IteratorType PointsBegin, IteratorType &PartitionPosition, IteratorType PointsEnd, IndexType &CuttingDimension, CoordinateType &rCuttingValue)
Definition: kd_tree.h:725
static IteratorType Partition(IteratorType PointsBegin, IteratorType PointsEnd, IndexType &rCuttingDimension, CoordinateType &rCuttingValue)
Definition: kd_tree.h:657
static SizeType MaxSpread(IteratorType PointsBegin, IteratorType PointsEnd, CoordinateType &AverageValue)
Definition: kd_tree.h:674
virtual ~KDTreePartitionAverageSplit()
Destructor.
Definition: kd_tree.h:648
TLeafType LeafType
Definition: kd_tree.h:602
TreeNodeType::SizeType SizeType
Definition: kd_tree.h:622
@ Dimension
Definition: kd_tree.h:616
static TreeNodeType * Construct(IteratorType PointsBegin, IteratorType PointsEnd, PointType HighPoint, PointType LowPoint, SizeType BucketSize)
Definition: kd_tree.h:748
LeafType::PointerType PointerType
Definition: kd_tree.h:612
LeafType::PointType PointType
Definition: kd_tree.h:604
LeafType::SearchStructureType SearchStructureType
Definition: kd_tree.h:627
LeafType::DistanceFunction DistanceFunction
Definition: kd_tree.h:614
LeafType::ContainerType ContainerType
Definition: kd_tree.h:606
TreeNode< Dimension, PointType, PointerType, IteratorType, DistanceIteratorType > TreeNodeType
Definition: kd_tree.h:618
KRATOS_CLASS_POINTER_DEFINITION(KDTreePartitionAverageSplit)
Pointer definition of KDTree.
TreeNodeType::CoordinateType CoordinateType
Definition: kd_tree.h:620
TreeNodeType::IndexType IndexType
Definition: kd_tree.h:624
KDTreePartitionAverageSplit(IndexType CutingDimension, CoordinateType Position, CoordinateType LeftEnd, CoordinateType RightEnd, TreeNodeType *pLeftChild=NULL, TreeNodeType *pRightChild=NULL)
Partition constructor.
Definition: kd_tree.h:635
KDTreePartitionBase< TLeafType > BaseType
Definition: kd_tree.h:600
LeafType::IteratorType IteratorType
Definition: kd_tree.h:608
LeafType::DistanceIteratorType DistanceIteratorType
Definition: kd_tree.h:610
Short class definition.
Definition: kd_tree.h:57
TreeNodeType::IndexType IndexType
Definition: kd_tree.h:87
LeafType::ContainerType ContainerType
Definition: kd_tree.h:69
void SearchInRadius(PointType const &ThisPoint, CoordinateType const &Radius, CoordinateType const &Radius2, IteratorType &Results, DistanceIteratorType &ResultsDistances, SizeType &NumberOfResults, SizeType const &MaxNumberOfResults) override
Definition: kd_tree.h:197
void SearchInRadius(PointType const &ThisPoint, CoordinateType const &Radius, CoordinateType const &Radius2, IteratorType &Results, SizeType &NumberOfResults, SizeType const &MaxNumberOfResults) override
Definition: kd_tree.h:257
LeafType::PointerType PointerType
Definition: kd_tree.h:75
void SearchInBox(PointType const &SearchMinPoint, PointType const &SearchMaxPoint, IteratorType &Results, SizeType &NumberOfResults, SizeType const &MaxNumberOfResults) override
Definition: kd_tree.h:316
TreeNode< Dimension, PointType, PointerType, IteratorType, DistanceIteratorType > TreeNodeType
Definition: kd_tree.h:81
TLeafType LeafType
Definition: kd_tree.h:65
void SearchInRadius(PointType const &ThisPoint, CoordinateType const &Radius, CoordinateType const &Radius2, IteratorType &Results, SizeType &NumberOfResults, SizeType const &MaxNumberOfResults, SearchStructureType &Auxiliar) override
Definition: kd_tree.h:272
void SearchNearestPoint(PointType const &rThisPoint, PointerType &rResult, CoordinateType &rResultDistance) override
Definition: kd_tree.h:144
KRATOS_CLASS_POINTER_DEFINITION(KDTreePartitionBase)
Pointer definition of KDTree.
LeafType::PointType PointType
Definition: kd_tree.h:67
@ Dimension
Definition: kd_tree.h:79
LeafType::DistanceFunction DistanceFunction
Definition: kd_tree.h:77
KDTreePartitionBase(IndexType CutingDimension, CoordinateType Position, CoordinateType LeftEnd, CoordinateType RightEnd, TreeNodeType *pLeftChild=NULL, TreeNodeType *pRightChild=NULL)
Partition constructor.
Definition: kd_tree.h:98
void PrintData(std::ostream &rOStream, std::string const &Perfix=std::string()) const override
Definition: kd_tree.h:107
void SearchInRadius(PointType const &ThisPoint, CoordinateType const &Radius, CoordinateType const &Radius2, IteratorType &Results, DistanceIteratorType &ResultsDistances, SizeType &NumberOfResults, SizeType const &MaxNumberOfResults, SearchStructureType &Auxiliar) override
Definition: kd_tree.h:213
void SearchNearestPoint(PointType const &rThisPoint, PointerType &rResult, CoordinateType &rResultDistance, SearchStructureType &Auxiliar) override
Definition: kd_tree.h:156
LeafType::DistanceIteratorType DistanceIteratorType
Definition: kd_tree.h:73
LeafType::IteratorType IteratorType
Definition: kd_tree.h:71
TreeNodeType::CoordinateType CoordinateType
Definition: kd_tree.h:83
virtual ~KDTreePartitionBase()
Destructor.
Definition: kd_tree.h:133
TreeNodeType::SizeType SizeType
Definition: kd_tree.h:85
LeafType::SearchStructureType SearchStructureType
Definition: kd_tree.h:90
Definition: kd_tree.h:362
static IteratorType Partition(IteratorType PointsBegin, IteratorType PointsEnd, IndexType &rCuttingDimension, CoordinateType &rCuttingValue)
Definition: kd_tree.h:419
static void MedianSplit(IteratorType PointsBegin, IteratorType PartitionPosition, IteratorType PointsEnd, IndexType CuttingDimension, CoordinateType &rCuttingValue)
Definition: kd_tree.h:480
LeafType::IteratorType IteratorType
Definition: kd_tree.h:378
KDTreePartitionBase< TLeafType > BaseType
Definition: kd_tree.h:370
LeafType::PointType PointType
Definition: kd_tree.h:374
KRATOS_CLASS_POINTER_DEFINITION(KDTreePartition)
Pointer definition of KDTree.
TreeNodeType::CoordinateType CoordinateType
Definition: kd_tree.h:390
KDTreePartition(IndexType CutingDimension, CoordinateType Position, CoordinateType LeftEnd, CoordinateType RightEnd, TreeNodeType *pLeftChild=NULL, TreeNodeType *pRightChild=NULL)
Partition constructor.
Definition: kd_tree.h:405
LeafType::ContainerType ContainerType
Definition: kd_tree.h:376
LeafType::DistanceIteratorType DistanceIteratorType
Definition: kd_tree.h:380
TreeNode< Dimension, PointType, PointerType, IteratorType, DistanceIteratorType > TreeNodeType
Definition: kd_tree.h:388
~KDTreePartition()
Destructor.
Definition: kd_tree.h:410
LeafType::DistanceFunction DistanceFunction
Definition: kd_tree.h:384
TreeNodeType::SizeType SizeType
Definition: kd_tree.h:392
@ Dimension
Definition: kd_tree.h:386
static TreeNodeType * Construct(IteratorType PointsBegin, IteratorType PointsEnd, const PointType &HighPoint, const PointType &LowPoint, SizeType BucketSize)
Definition: kd_tree.h:538
TLeafType LeafType
Definition: kd_tree.h:372
TreeNodeType::IndexType IndexType
Definition: kd_tree.h:394
LeafType::SearchStructureType SearchStructureType
Definition: kd_tree.h:397
LeafType::PointerType PointerType
Definition: kd_tree.h:382
static SizeType MaxSpread(IteratorType PointsBegin, IteratorType PointsEnd)
Definition: kd_tree.h:436
Definition: kd_tree.h:797
TreeNodeType::IndexType IndexType
Definition: kd_tree.h:829
LeafType::PointType PointType
Definition: kd_tree.h:809
KDTreePartitionBase< TLeafType > BaseType
Definition: kd_tree.h:805
TLeafType LeafType
Definition: kd_tree.h:807
LeafType::DistanceIteratorType DistanceIteratorType
Definition: kd_tree.h:815
LeafType::SearchStructureType SearchStructureType
Definition: kd_tree.h:832
KRATOS_CLASS_POINTER_DEFINITION(KDTreePartitionMidPointSplit)
Pointer definition of KDTree.
static IteratorType Split(IteratorType PointsBegin, IteratorType PointsEnd, IndexType &CuttingDimension, CoordinateType &rCuttingValue)
Definition: kd_tree.h:923
TreeNodeType::SizeType SizeType
Definition: kd_tree.h:827
static IteratorType Partition(IteratorType PointsBegin, IteratorType PointsEnd, PointType const &HighPoint, PointType const &LowPoint, IndexType &rCuttingDimension, CoordinateType &rCuttingValue)
Definition: kd_tree.h:852
LeafType::IteratorType IteratorType
Definition: kd_tree.h:813
TreeNode< Dimension, PointType, PointerType, IteratorType, DistanceIteratorType > TreeNodeType
Definition: kd_tree.h:823
virtual ~KDTreePartitionMidPointSplit()
Destructor.
Definition: kd_tree.h:844
TreeNodeType::CoordinateType CoordinateType
Definition: kd_tree.h:825
static SizeType MaxSpread(IteratorType PointsBegin, IteratorType PointsEnd, PointType const &HighPoint, PointType const &LowPoint, CoordinateType &CuttingValue)
Definition: kd_tree.h:880
LeafType::PointerType PointerType
Definition: kd_tree.h:817
LeafType::ContainerType ContainerType
Definition: kd_tree.h:811
LeafType::DistanceFunction DistanceFunction
Definition: kd_tree.h:819
static TreeNodeType * Construct(IteratorType PointsBegin, IteratorType PointsEnd, PointType HighPoint, PointType LowPoint, SizeType BucketSize)
Definition: kd_tree.h:945
KDTreePartitionMidPointSplit(IndexType CutingDimension, CoordinateType Position, CoordinateType LeftEnd, CoordinateType RightEnd, TreeNodeType *pLeftChild=NULL, TreeNodeType *pRightChild=NULL)
Partition constructor.
Definition: kd_tree.h:839
@ Dimension
Definition: kd_tree.h:821
Short class definition.
Definition: tree.h:61
virtual void SearchInBox(PointType const &SearchMinPoint, PointType const &SearchMaxPoint, IteratorType &Results, SizeType &NumberOfResults, SizeType const &MaxNumberOfResults)
Definition: tree.h:138
virtual void SearchNearestPoint(PointType const &ThisPoint, PointerType &rResult, CoordinateType &rResultDistance)
Definition: tree.h:105
virtual void SearchInRadius(PointType const &ThisPoint, CoordinateType const &Radius, CoordinateType const &Radius2, IteratorType &Results, DistanceIteratorType &ResultsDistances, SizeType &NumberOfResults, SizeType const &MaxNumberOfResults)
Definition: tree.h:110
double CoordinateType
Define CoordinateType as double.
Definition: tree.h:76
virtual void PrintData(std::ostream &rOStream, std::string const &Perfix=std::string()) const
Definition: tree.h:99
std::size_t IndexType
Define IndexType as std::size_t.
Definition: tree.h:73
std::size_t SizeType
Define SizeType as std::size_t.
Definition: tree.h:70
std::size_t IndexType
The definition of the index type.
Definition: key_hash.h:35
static double max(double a, double b)
Definition: GeometryFunctions.h:79
static double min(double a, double b)
Definition: GeometryFunctions.h:71
std::size_t PointerDistance(TPointerType const &PointerBegin, TPointerType const &PointerEnd)
Definition: search_structure.h:91
REF: G. R. Cowper, GAUSSIAN QUADRATURE FORMULAS FOR TRIANGLES.
Definition: mesh_condition.cpp:21
left
Definition: exact_hinsberg_test.py:140
c
Definition: generate_weakly_compressible_navier_stokes_element.py:108
def Average(vector_container, current_values, k_calc, pp)
Definition: initial_time_bounds.py:102
int d
Definition: ode_solve.py:397
int n
manufactured solution and derivatives (u=0 at z=0 dudz=0 at z=domain_height)
Definition: ode_solve.py:402
int k
Definition: quadrature.py:595
int j
Definition: quadrature.py:648
float temp
Definition: rotating_cone.py:85
integer i
Definition: TensorModule.f:17
Configure::IteratorType IteratorType
Definition: transfer_utility.h:249
Configure::PointType PointType
Definition: transfer_utility.h:245
Configure::ContainerType ContainerType
Definition: transfer_utility.h:247