Dendro  5.01
Dendro in Greek language means tree. The Dendro library is a large scale (262K cores on ORNL's Titan) distributed memory adaptive octree framework. The main goal of Dendro is to perform large scale multiphysics simulations efficeiently in mordern supercomputers. Dendro consists of efficient parallel data structures and algorithms to perform variational ( finite element) methods and finite difference mthods on 2:1 balanced arbitary adaptive octrees which enables the users to perform simulations raning from black holes (binary black hole mergers) to blood flow in human body, where applications ranging from relativity, astrophysics to biomedical engineering.
TreeNode.h
1 //
2 // Created by milinda on 2/8/16.
3 //
4 
13 #ifndef SFCSORTBENCH_TREENODE_H
14 #define SFCSORTBENCH_TREENODE_H
15 
16 static unsigned int MAX_LEVEL=31;
17 //#define m_uiMaxDepth 30
18 extern unsigned int m_uiMaxDepth;
19 
20 
21 #include "hcurvedata.h"
22 #include "binUtils.h"
23 #include "mpi.h"
24 #include "point.h"
25 #include <algorithm>
26 #include "dendro.h"
27 
28 
29 namespace ot {
30 
35  class TreeNode {
36  protected:
37  //Level is also used as a flag.
38  unsigned int m_uiX, m_uiY, m_uiZ, m_uiLevel;
39  //unsigned int m_uiMaxDepth;
40 
41  public:
42 
43  TreeNode (const int dummy, const unsigned int x,const unsigned int y,
44  const unsigned int z,const unsigned int level, const unsigned int dim,
45  const unsigned int maxDepth);
46 
47  TreeNode (const unsigned int x,const unsigned int y,
48  const unsigned int z,const unsigned int level, const unsigned int dim,
49  const unsigned int maxDepth);
50 
51  TreeNode(const unsigned int dim, const unsigned int maxDepth );
52 
53  TreeNode();
54 
55  public:
60  unsigned int getDim() const;
65  unsigned int getMaxDepth() const;
66 
71  unsigned int getLevel() const;
72 
78  inline void setFlag(unsigned int flag);
79 
84  inline unsigned int getFlag() const;
85 
90  unsigned int getX() const;
91  unsigned int getY() const;
92  unsigned int getZ() const;
93 
98  bool isRoot() const;
99 
104  void incrementLevel();
105 
111  bool operator == ( TreeNode const &other) const;
112 
118  bool operator != (TreeNode const &other) const;
119 
120 
129  bool operator < ( TreeNode const &other) const;
130 
136  bool operator > ( TreeNode const &other) const;
137 
143  bool operator <= ( TreeNode const &other) const;
144 
150  bool operator >= ( TreeNode const &other) const;
151 
152  unsigned int genHkey_Bonsai_sc16() const ;
153 
154  TreeNode getNCA(TreeNode const & other ) const ;
155 
156  inline bool isAncestor(const TreeNode & other) const;
157 
158 
164  inline unsigned int minX() const {
165  return getX();
166  } //end fn.
167 
168  inline unsigned int minY() const {
169  if (m_uiDim < 2) { return 0; }
170  return getY();
171  } //end fn.
172 
173  inline unsigned int minZ() const {
174  if (m_uiDim < 3) { return 0; }
175  return getZ();
176  } //end fn.
177 
178  inline unsigned int maxX() const {
179  unsigned int len = (1u << (m_uiMaxDepth - getLevel()));
180  return (minX() + len);
181  } //end fn.
182 
183  inline unsigned int maxY() const {
184  if (m_uiDim < 2) { return 1; }
185  unsigned int len = (1u << (m_uiMaxDepth - getLevel()));
186  return (minY() + len);
187  } //end fn.
188 
189  inline unsigned int maxZ() const {
190  if (m_uiDim < 3) { return 1; }
191  unsigned int len = (1u << (m_uiMaxDepth - getLevel()));
192  return (minZ() + len);
193  } //end fn.
194 
199  TreeNode getParent() const;
200 
201 
206  TreeNode getDFDMorton() const;
207 
208 
210  TreeNode getDFD() const;
211 
213  TreeNode getDLD() const;
214 
215 
216 
223  TreeNode getLeft() const;
224  TreeNode getRight() const;
225  TreeNode getTop() const;
226  TreeNode getBottom() const;
227  TreeNode getFront() const;
228  TreeNode getBack() const;
229  TreeNode getTopLeft() const;
230  TreeNode getTopRight() const;
231  TreeNode getBottomLeft() const;
232  TreeNode getBottomRight() const;
233  TreeNode getLeftFront() const;
234  TreeNode getRightFront() const;
235  TreeNode getTopFront() const;
236  TreeNode getBottomFront() const;
237  TreeNode getTopLeftFront() const;
238  TreeNode getTopRightFront() const;
239  TreeNode getBottomLeftFront() const;
240  TreeNode getBottomRightFront() const;
241  TreeNode getLeftBack() const;
242  TreeNode getRightBack() const;
243  TreeNode getTopBack() const;
244  TreeNode getBottomBack() const;
245  TreeNode getTopLeftBack() const;
246  TreeNode getTopRightBack() const;
247  TreeNode getBottomLeftBack() const;
248  TreeNode getBottomRightBack() const;
249  std::vector<TreeNode> getAllNeighbours() const;
250 
251 
252  int getAnchor(unsigned int &x, unsigned int&y, unsigned int&z) const;
253  Point getAnchor() const { return Point(m_uiX, m_uiY, m_uiZ); };
254 
255  inline unsigned int getMortonIndex() const;
256 
257 
265  //==================================================================================================================
266 
270  enum BoundaryType1 { NEGATIVE= 2, POSITIVE= 4};
271 
276  X_NEG_BDY=1, Y_NEG_BDY=2, Z_NEG_BDY=4, NEG_POS_DEMARCATION=8,
277  EXTERNAL_BDY=16, X_POS_BDY=32, Y_POS_BDY=64, Z_POS_BDY=128
278  };
279 
284  FACE_BDY=1, EDGE_BDY=2, CORNER_BDY=3
285  };
286 
287  enum OctantFlagType {
288  MAX_LEVEL=31, BOUNDARY=64, NODE=128
289  };
290 
291 
298  bool isBoundaryOctant(int type=POSITIVE, unsigned char *flags=NULL) const;
299 
306  bool isBoundaryOctant(const TreeNode &block, int type=POSITIVE, unsigned char *flags=NULL) const;
307 
308 
309  //=====================================================Mesh Definitions End ==============================================
310 
311  int addChildren(std::vector<ot::TreeNode>& children) const;
312 
313  int getChildrenInMortonOrdering(std::vector<ot::TreeNode>& children) const
314  {
315  unsigned int dim = m_uiDim;
316  unsigned int maxDepth = m_uiMaxDepth;
317  children.resize((1 << dim));
318 
319  //#define MORTON_ORDERING
320 
321  if ((m_uiLevel & ot::TreeNode::MAX_LEVEL) == maxDepth) {
322  for (int i = 0; i < (1 << dim); i++) {
323  children[i] = *this;
324  }
325  return 1;
326  }
327  //The check that lev < maxD is taken care of in the constructor.
328  //Order: X first, Y next and Z last
329 
330  unsigned int len = (unsigned int)(1u << (maxDepth - ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1)));
331 
332  TreeNode tmpNode0(m_uiX, m_uiY, m_uiZ, ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
333  children[0] = tmpNode0;
334 
335  TreeNode tmpNode1((m_uiX + len), m_uiY, m_uiZ, ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
336  children[1] = tmpNode1;
337 
338  if (dim >= 2) {
339  TreeNode tmpNode2(m_uiX, (m_uiY + len), m_uiZ, ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
340  children[2] = tmpNode2;
341 
342  TreeNode tmpNode3((m_uiX + len), (m_uiY + len), m_uiZ, ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
343  children[3] = tmpNode3;
344  }
345 
346  if (dim == 3) {
347  TreeNode tmpNode4(m_uiX, m_uiY, (m_uiZ + len), ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
348  children[4] = tmpNode4;
349 
350  TreeNode tmpNode5((m_uiX + len), m_uiY, (m_uiZ + len), ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
351  children[5] = tmpNode5;
352 
353  TreeNode tmpNode6(m_uiX, (m_uiY + len), (m_uiZ + len), ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
354  children[6] = tmpNode6;
355 
356  TreeNode tmpNode7((m_uiX + len), (m_uiY + len), (m_uiZ + len), ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
357  children[7] = tmpNode7;
358  } //end if
359  return 1;
360 
361  }
362 
363  };
364 
365 
366  inline unsigned int TreeNode::getX() const {
367  return m_uiX;
368  }
369 
370  inline unsigned int TreeNode::getY() const {
371  return m_uiY;
372  }
373 
374  inline unsigned int TreeNode::getZ() const {
375  return m_uiZ;
376  }
377 
378 
379  inline unsigned int TreeNode::getDim() const {
380  return m_uiDim;
381  }
382 
383  inline unsigned int TreeNode::getMaxDepth() const {
384  return m_uiMaxDepth;
385  }
386 
387  inline unsigned int TreeNode::getLevel() const {
388  return (m_uiLevel & MAX_LEVEL);
389  }
390 
391  inline bool TreeNode::isRoot() const {
392  return ((this->getLevel()==0) & (m_uiX==0) & (m_uiY==0) & (m_uiZ==0));
393  }
394 
396  {
397  if(this->getLevel()<m_uiMaxDepth)
398  m_uiLevel++;
399  }
400 
401  inline void TreeNode::setFlag(unsigned int flag) { m_uiLevel=flag; }
402  inline unsigned int TreeNode::getFlag() const { return m_uiLevel; }
403 
404  inline bool TreeNode::isAncestor(const TreeNode & other) const
405  {
406  /*unsigned int min1[3], min2[3], max1[3], max2[3];
407 
408  min1[0] = this->minX(); min1[1] = this->minY(); min1[2] = this->minZ();
409  min2[0] = other.minX(); min2[1] = other.minY(); min2[2] = other.minZ();
410 
411  max1[0] = this->maxX(); max1[1] = this->maxY(); max1[2] = this->maxZ();
412  max2[0] = other.maxX(); max2[1] = other.maxY(); max2[2] = other.maxZ();
413 
414  bool state1=( (this->getLevel() < other.getLevel()) && ( (min2[0] >= min1[0]) && (min2[1] >= min1[1]) && (min2[2] >= min1[2]) && (max2[0] <= max1[0]) && (max2[1] <= max1[1]) && (max2[2] <= max1[2]) ));
415 
416  return state1;*/
417 
418  return ( (this->getLevel() < other.getLevel()) && ( (other.minX() >= this->minX()) && (other.minY() >= this->minY()) && (other.minZ() >= this->minZ()) && (other.maxX() <= this->maxX()) && (other.maxY() <= this->maxY()) && (other.maxZ() <= this->maxZ()) ));
419 
420  }
421 
422 
423  std::ostream & operator << (std::ostream & os,TreeNode const & node) ;
424 
425 
426  inline bool TreeNode::operator<(TreeNode const &other) const {
427 
428 
429 #ifdef __DEBUG_TN__
430  if (((this->m_uiDim) != (other.m_uiDim)) || ((this->m_uiMaxDepth) != (other.m_uiMaxDepth))) {
431  std::cout << "Me: " << (*this) << " Other: " << other << std::endl;
432  std::cout << "My Dim: " << m_uiDim << " OthDim: " << other.m_uiDim << " My MaxD: " << m_uiMaxDepth << " othMD: " << other.m_uiMaxDepth << std::endl;
433  assert(false);
434  }
435 #endif
436 
437  if ((this->m_uiX == other.m_uiX) && (this->m_uiY == other.m_uiY) && (this->m_uiZ == other.m_uiZ)) {
438  return ((this->m_uiLevel & MAX_LEVEL) < (other.m_uiLevel & MAX_LEVEL));
439  } //end if
440 
441 #ifdef HILBERT_ORDERING
442 
443  // #pragma message "Hilbert NCA"
444  // If you need to initilize the Hilbert table and the rotations for 2D you need to define DENDRO_DIM2
445  // Default initialization for 3D case.
446  // NOTE: To work the Hilbert Ordering You need the Hilbert Table Initialized.
447  //std::cout<<"Using H Sort:"<<std::endl;
448  unsigned int x1 = m_uiX;
449  unsigned int x2 = other.getX();
450 
451  unsigned int y1 = m_uiY;
452  unsigned int y2 = other.getY();
453 
454  unsigned int z1 = m_uiZ;
455  unsigned int z2 = other.getZ();
456 
457  unsigned len;
458  unsigned int maxDepth = m_uiMaxDepth;
459 
460  if(this->getLevel()>other.getLevel())
461  {
462  len=1u<<(this->getMaxDepth()-other.getLevel());
463  if(!((x1<x2 || x1>=(x2+len)) || (y1<y2 || y1>=(y2+len)) ||(z1<z2 || z1>=(z2+len))))
464  return false;
465 
466 
467  }else if(this->getLevel()<other.getLevel())
468  {
469  len=1u<<(this->getMaxDepth()-this->getLevel());
470  if(!((x2<x1 || x2>=(x1+len))||(y2<y1 || y2>=(y1+len))||(z2<z1 || z2>=(z1+len))))
471  return true;
472 
473 
474  }
475 
476  unsigned int maxDiff = (unsigned int)(std::max((std::max((x1^x2),(y1^y2))),(z1^z2)));
477  int dim=m_uiDim;
478 
479 
480 
481 
482  unsigned int maxDiffBinLen = binOp::binLength(maxDiff);
483  //Eliminate the last maxDiffBinLen bits.
484  unsigned int ncaX = ((x1>>maxDiffBinLen)<<maxDiffBinLen);
485  unsigned int ncaY = ((y1>>maxDiffBinLen)<<maxDiffBinLen);
486  unsigned int ncaZ = ((z1>>maxDiffBinLen)<<maxDiffBinLen);
487  unsigned int ncaLev = (maxDepth - maxDiffBinLen);
488 
489 // if(ncaLev>std::min(this->getLevel(),other.getLevel()))
490 // {
491 //
492 // std::cout<<"P1:"<<*(this)<<"\t P2:"<<other<<std::endl;
493 // std::cout<<"MaxDiff:"<<maxDiff<<std::endl;
494 // std::cout<<"MaxDiffLen:"<<maxDiffBinLen<<std::endl;
495 // std::cout<<"NCALEV:"<<ncaLev<<"\t this_lev:"<<this->getLevel()<<"\t other_lev:"<<other.getLevel()<<std::endl;
496 //
497 // std::cout<<std::endl;
498 //
499 // }
500 
501  unsigned int index1=0;
502  unsigned int index2=0;
503  unsigned int num_children=1u<<dim; // This is basically the hilbert table offset
504  unsigned int rot_offset=num_children<<1;
505  char index_temp=0;
506  int current_rot=0;
507 
508  //unsigned int b_x,b_y,b_z;
509  //unsigned int a,b,c;
510  unsigned int mid_bit=m_uiMaxDepth;
511 
512  for(int i=0; i<ncaLev;i++)
513  {
514  mid_bit=m_uiMaxDepth-i-1;
515 
516  //b_x=((ncaX&(1<<mid_bit))>>mid_bit);
517  //b_y=((ncaY&(1<<mid_bit))>>mid_bit);
518  //b_z=((ncaZ&(1<<mid_bit))>>mid_bit);
519 
520  // index1=(b_z<<2) + ((b_x^b_z)<<1) + (b_x^b_y^b_z);
521  index1= ((((ncaZ & (1u << mid_bit)) >> mid_bit) << 2u) |(((ncaY & (1u << mid_bit)) >> mid_bit) << 1u) | ((ncaX & (1u << mid_bit)) >> mid_bit));
522  //index_temp=rotations[rot_offset*current_rot+num_children+index1]-'0';
523  current_rot=HILBERT_TABLE[current_rot*num_children+index1];
524  }
525  mid_bit--;
526  index1= ((((z1 & (1u << mid_bit)) >> mid_bit) << 2u) |(((y1 & (1u << mid_bit)) >> mid_bit) << 1u) | ((x1 & (1u << mid_bit)) >> mid_bit));
527  index2= ((((z2 & (1u << mid_bit)) >> mid_bit) << 2u) |(((y2 & (1u << mid_bit)) >> mid_bit) << 1u) | ((x2 & (1u << mid_bit)) >> mid_bit));
528 
529  return rotations[rot_offset*current_rot+num_children+index1] < rotations[rot_offset*current_rot+num_children+index2];
530 
531 
532 #else
533  //#ifdef USE_NCA_PROPERTY
534 
535  // #pragma message "Morton NCA"
536  // return morton_order_NCA(p1,p2);
537  // #else
538  #pragma message "Morton"
539  // -- original Morton
540  // first compare the x, y, and z to determine which one dominates ...
541  //Ancestor is smaller.
542  if ((this->m_uiX == other.m_uiX) && (this->m_uiY == other.m_uiY) && (this->m_uiZ == other.m_uiZ)) {
543  return ((this->m_uiLevel & MAX_LEVEL) < (other.m_uiLevel & MAX_LEVEL));
544  } //end if
545 
546  unsigned int x = (m_uiX ^ other.m_uiX);
547  unsigned int y = (m_uiY ^ other.m_uiY);
548  unsigned int z = (m_uiZ ^ other.m_uiZ);
549 
550  //Default pref: z > y > x.
551  unsigned int maxC = z;
552  unsigned int yOrx = y;
553  if (yOrx < x) {if ((x ^ yOrx) >= yOrx) {yOrx = x;}
554  }
555  if (maxC < yOrx) {if ((maxC ^ yOrx) >= maxC) {maxC = yOrx;}
556  }
557 
558  if (maxC == z) {return (m_uiZ < other.m_uiZ); } else if (maxC == y) {return (m_uiY < other.m_uiY); } else {return (m_uiX < other.m_uiX); }
559  // -- original Morton
560 
561  // #endif
562 #endif
563 
564  } //end function
565 
566  inline bool TreeNode::operator<=(TreeNode const &other) const {
567 #ifdef __DEBUG_TN__
568  if (((this->m_uiDim) != (other.m_uiDim)) || ((this->m_uiMaxDepth) != (other.m_uiMaxDepth))) {
569  std::cout << "Me: " << (*this) << " Other: " << other << std::endl;
570  std::cout << "My Dim: " << m_uiDim << " OthDim: " << other.m_uiDim << " My MaxD: " << m_uiMaxDepth << " othMD: " << other.m_uiMaxDepth << std::endl;
571  assert(false);
572  }
573 #endif
574  return (((*this) < other) || ((*this) == other));
575  } //end fn.
576 
577  inline bool TreeNode::operator>(TreeNode const &other) const {
578 #ifdef __DEBUG_TN__
579  if (((this->m_uiDim) != (other.m_uiDim)) || ((this->m_uiMaxDepth) != (other.m_uiMaxDepth))) {
580  std::cout << "Me: " << (*this) << " Other: " << other << std::endl;
581  std::cout << "My Dim: " << m_uiDim << " OthDim: " << other.m_uiDim << " My MaxD: " << m_uiMaxDepth << " othMD: " << other.m_uiMaxDepth << std::endl;
582  assert(false);
583  }
584 #endif
585  return ((!((*this) < other)) && (!((*this) == other)));
586  } //end fn.
587 
588  inline bool TreeNode::operator>=(TreeNode const &other) const {
589 #ifdef __DEBUG_TN__
590  if (((this->m_uiDim) != (other.m_uiDim)) || ((this->m_uiMaxDepth) != (other.m_uiMaxDepth))) {
591  std::cout << "Me: " << (*this) << " Other: " << other << std::endl;
592  std::cout << "My Dim: " << m_uiDim << " OthDim: " << other.m_uiDim << " My MaxD: " << m_uiMaxDepth << " othMD: " << other.m_uiMaxDepth << std::endl;
593  assert(false);
594  }
595 #endif
596  return (!((*this) < other));
597  } //end fn.
598 
599  inline bool TreeNode::operator==(TreeNode const &other) const {
600 #ifdef __DEBUG_TN__
601  if (((this->m_uiDim) != (other.m_uiDim)) || ((this->m_uiMaxDepth) != (other.m_uiMaxDepth))) {
602  std::cout << "Me: " << (*this) << " Other: " << other << std::endl;
603  std::cout << "My Dim: " << m_uiDim << " OthDim: " << other.m_uiDim << " My MaxD: " << m_uiMaxDepth << " othMD: " << other.m_uiMaxDepth << std::endl;
604  assert(false);
605  }
606 #endif
607  if ((m_uiX == other.m_uiX) && (m_uiY == other.m_uiY) && (m_uiZ == other.m_uiZ) &&
608  ((m_uiLevel & MAX_LEVEL) == (other.m_uiLevel & MAX_LEVEL))) {
609  return true;
610  } else {
611  return false;
612  }
613  } //end fn.
614 
615  inline bool TreeNode::operator!=(TreeNode const &other) const {
616 #ifdef __DEBUG_TN__
617  if (((this->m_uiDim) != (other.m_uiDim)) || ((this->m_uiMaxDepth) != (other.m_uiMaxDepth))) {
618  std::cout << "Me: " << (*this) << " Other: " << other << std::endl;
619  std::cout << "My Dim: " << m_uiDim << " OthDim: " << other.m_uiDim << " My MaxD: " << m_uiMaxDepth << " othMD: " << other.m_uiMaxDepth << std::endl;
620  assert(false);
621  }
622 #endif
623  return (!((*this) == other));
624  } //end fn.
625 
626 
627  inline TreeNode TreeNode::getParent() const {
628  //For any node at level l, the last (maxD-l) bits are 0.
629  //By convention, root's parent is also root.
630  unsigned int parX, parY, parZ;
631  unsigned int parLev = (((m_uiLevel & MAX_LEVEL) > 0) ? ((m_uiLevel & MAX_LEVEL) - 1) : 0);
632  parX = ((m_uiX >> (m_uiMaxDepth - parLev)) << (m_uiMaxDepth - parLev));
633  parY = ((m_uiY >> (m_uiMaxDepth - parLev)) << (m_uiMaxDepth - parLev));
634  parZ = ((m_uiZ >> (m_uiMaxDepth - parLev)) << (m_uiMaxDepth - parLev));
635  return TreeNode(1, parX, parY, parZ, parLev, m_uiDim, m_uiMaxDepth);
636  } //end function
637 
638 
639  inline TreeNode TreeNode::getLeft() const {
640  //-ve X
641  if (minX() > 0) {
642  unsigned int len = (1u << (m_uiMaxDepth - getLevel()));
643  unsigned int xres = (minX() - len);
644  unsigned int yres = minY();
645  unsigned int zres = minZ();
646  TreeNode res(1, xres, yres, zres, getLevel(), m_uiDim, m_uiMaxDepth);
647  return res;
648  } else {
649  TreeNode res(m_uiDim, m_uiMaxDepth);
650  return res;
651  }
652  } //end fn.
653 
654  inline TreeNode TreeNode::getRight() const {
655  //+ve X
656  if (maxX() < (1u << m_uiMaxDepth)) {
657  unsigned int xres = maxX();
658  unsigned int yres = minY();
659  unsigned int zres = minZ();
660  TreeNode res(1, xres, yres, zres, getLevel(), m_uiDim, m_uiMaxDepth);
661  return res;
662  } else {
663  TreeNode res(m_uiDim, m_uiMaxDepth);
664  return res;
665  }
666  } //end fn.
667 
668  inline TreeNode TreeNode::getBack() const {
669  //+ve Y
670  if ((m_uiDim > 1) && (maxY() < (1u << m_uiMaxDepth))) {
671  unsigned int xres = minX();
672  unsigned int yres = maxY();
673  unsigned int zres = minZ();
674  TreeNode res(1, xres, yres, zres, getLevel(), m_uiDim, m_uiMaxDepth);
675  return res;
676  } else {
677  TreeNode res(m_uiDim, m_uiMaxDepth);
678  return res;
679  }
680  } //end fn.
681 
682  inline TreeNode TreeNode::getFront() const {
683  //-ve Y
684  if (minY() > 0) {
685  unsigned int len = (1u << (m_uiMaxDepth - getLevel()));
686  unsigned int xres = minX();
687  unsigned int yres = minY() - len;
688  unsigned int zres = minZ();
689  TreeNode res(1, xres, yres, zres, getLevel(), m_uiDim, m_uiMaxDepth);
690  return res;
691  } else {
692  TreeNode res(m_uiDim, m_uiMaxDepth);
693  return res;
694  }
695  } //end fn.
696 
697  inline TreeNode TreeNode::getBottom() const {
698  //-ve Z
699  if (minZ() > 0) {
700  unsigned int len = (1u << (m_uiMaxDepth - getLevel()));
701  unsigned int xres = minX();
702  unsigned int yres = minY();
703  unsigned int zres = minZ() - len;
704  TreeNode res(1, xres, yres, zres, getLevel(), m_uiDim, m_uiMaxDepth);
705  return res;
706  } else {
707  TreeNode res(m_uiDim, m_uiMaxDepth);
708  return res;
709  }
710  } //end fn.
711 
712  inline TreeNode TreeNode::getTop() const {
713  //+ve Z
714  if ((m_uiDim == 3) && (maxZ() < (1u << m_uiMaxDepth))) {
715  unsigned int xres = minX();
716  unsigned int yres = minY();
717  unsigned int zres = maxZ();
718  TreeNode res(1, xres, yres, zres, getLevel(), m_uiDim, m_uiMaxDepth);
719  return res;
720  } else {
721  TreeNode res(m_uiDim, m_uiMaxDepth);
722  return res;
723  }
724  } //end fn.
725 
726  inline TreeNode TreeNode::getLeftBack() const {
727  return (getLeft().getBack());
728  } //end fn.
729 
730  inline TreeNode TreeNode::getRightBack() const {
731  return (getRight().getBack());
732  } //end fn.
733 
734  inline TreeNode TreeNode::getLeftFront() const {
735  return (getLeft().getFront());
736  } //end fn.
737 
738  inline TreeNode TreeNode::getRightFront() const {
739  return (getRight().getFront());
740  } //end fn.
741 
742  inline TreeNode TreeNode::getBottomLeft() const {
743  return (getBottom().getLeft());
744  } //end fn.
745 
746  inline TreeNode TreeNode::getBottomRight() const {
747  return (getBottom().getRight());
748  } //end fn.
749 
750  inline TreeNode TreeNode::getBottomBack() const {
751  return (getBottom().getBack());
752  } //end fn.
753 
754  inline TreeNode TreeNode::getBottomFront() const {
755  return (getBottom().getFront());
756  } //end fn.
757 
758  inline TreeNode TreeNode::getBottomLeftBack() const {
759  return (getBottomLeft().getBack());
760  } //end fn.
761 
762  inline TreeNode TreeNode::getBottomRightBack() const {
763  return (getBottomRight().getBack());
764  } //end fn.
765 
766  inline TreeNode TreeNode::getBottomLeftFront() const {
767  return (getBottomLeft().getFront());
768  } //end fn.
769 
770  inline TreeNode TreeNode::getBottomRightFront() const {
771  return (getBottomRight().getFront());
772  } //end fn.
773 
774  inline TreeNode TreeNode::getTopLeft() const {
775  return (getTop().getLeft());
776  } //end fn.
777 
778  inline TreeNode TreeNode::getTopRight() const {
779  return (getTop().getRight());
780  } //end fn.
781 
782  inline TreeNode TreeNode::getTopBack() const {
783  return (getTop().getBack());
784  } //end fn.
785 
786  inline TreeNode TreeNode::getTopFront() const {
787  return (getTop().getFront());
788  } //end fn.
789 
790  inline TreeNode TreeNode::getTopLeftBack() const {
791  return (getTopLeft().getBack());
792  } //end fn.
793 
794  inline TreeNode TreeNode::getTopRightBack() const {
795  return (getTopRight().getBack());
796  } //end fn.
797 
798  inline TreeNode TreeNode::getTopLeftFront() const {
799  return (getTopLeft().getFront());
800  } //end fn.
801 
802  inline TreeNode TreeNode::getTopRightFront() const {
803  return (getTopRight().getFront());
804  } //end fn.
805 
806 
807  inline int TreeNode::getAnchor(unsigned int &x, unsigned int &y, unsigned int &z) const {
808  x = m_uiX;
809  y = m_uiY;
810  z = m_uiZ;
811  return 1;
812  }
813 
814 
815 
816  inline std::vector<TreeNode> TreeNode::getAllNeighbours() const {
817  /*
818  0 = Left; 1 = Right; 2 = Front; 3 = Back; 4 = LeftBack; 5 = RightBack; 6 = LeftFront; 7 = RightFront; 8 = Top;
819  9 = TopRight; 10 = TopBack; 11 = TopRightBack; 12 = Bottom; 13 = BottomBack; 14 = TopLeft; 15 = BottomLeft;
820  16 = BottomRight; 17 = TopFront; 18 = BottomFront; 19 = TopLeftFront; 20 = TopRightFront; 21 = BottomLeftFront;
821  22 = BottomRightFront; 23 = TopLeftBack; 24 = BottomLeftBack; 25 = BottomRightBack;
822  */
823  std::vector<TreeNode> neighList;
824 
825  if (m_uiDim == 3) {
826  neighList.resize(26);
827  neighList[0] = getLeft();
828  neighList[1] = getRight();
829  neighList[2] = getFront();
830  neighList[3] = getBack();
831  neighList[4] = getLeftBack();
832  neighList[5] = getRightBack();
833  neighList[6] = getLeftFront();
834  neighList[7] = getRightFront();
835  neighList[8] = getTop();
836  neighList[9] = getTopRight();
837  neighList[10] = getTopBack();
838  neighList[11] = getTopRightBack();
839  neighList[12] = getBottom();
840  neighList[13] = getBottomBack();
841  neighList[14] = getTopLeft();
842  neighList[15] = getBottomLeft();
843  neighList[16] = getBottomRight();
844  neighList[17] = getTopFront();
845  neighList[18] = getBottomFront();
846  neighList[19] = getTopLeftFront();
847  neighList[20] = getTopRightFront();
848  neighList[21] = getBottomLeftFront();
849  neighList[22] = getBottomRightFront();
850  neighList[23] = getTopLeftBack();
851  neighList[24] = getBottomLeftBack();
852  neighList[25] = getBottomRightBack();
853  } else if (m_uiDim == 2) {
854  neighList.resize(8);
855  neighList[0] = getLeft();
856  neighList[1] = getRight();
857  neighList[2] = getFront();
858  neighList[3] = getBack();
859  neighList[4] = getLeftBack();
860  neighList[5] = getRightBack();
861  neighList[6] = getLeftFront();
862  neighList[7] = getRightFront();
863  } else {
864  neighList.resize(2);
865  neighList[0] = getLeft();
866  neighList[1] = getRight();
867  }
868  return neighList;
869  }
870 
871  inline unsigned int ot::TreeNode::getMortonIndex() const
872  {
873  // to get the morton child number.
874  unsigned int mid_bit = m_uiMaxDepth - this->getLevel();
875  return( (((m_uiZ >> mid_bit) & 1u) << 2u) | (((m_uiY >> mid_bit) & 1u) << 1u) | ((m_uiX >>mid_bit) & 1u));
876 
877  }
878 
879 }
880 
881 
882 namespace par {
883 
884  //Forward Declaration
885  template <typename T>
886  class Mpi_datatype;
887 
892  template <>
893  class Mpi_datatype< ot::TreeNode > {
894 
895  static void Node_MAX_LEVEL(void *in, void *inout, int* len, MPI_Datatype * dptr) {
896  for(int i = 0; i < (*len); i++) {
897  ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
898  ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
899  (static_cast<ot::TreeNode*>(inout))[i] =
900  ( ( (first.getLevel()) > (second.getLevel()) )? first : second );
901  }//end for
902  }//end function
903 
904  static void Node_MAX(void *in, void *inout, int* len, MPI_Datatype * dptr) {
905  for(int i = 0; i < (*len); i++) {
906  ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
907  ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
908  (static_cast<ot::TreeNode*>(inout))[i] = ( ( first > second )? first : second );
909  }//end for
910  }//end function
911 
912  static void Node_MIN(void *in, void *inout, int* len, MPI_Datatype * dptr) {
913  for(int i = 0; i < (*len); i++) {
914  ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
915  ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
916  (static_cast<ot::TreeNode*>(inout))[i] = ( ( first < second )? first : second );
917  }//end for
918  }//end function
919 
920  /* static void Node_NCA(void *in, void *inout, int* len, MPI_Datatype * dptr) {
921  for(int i = 0; i < (*len); i++) {
922  ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
923  ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
924  if( first != second ) {
925  (static_cast<ot::TreeNode*>(inout))[i] = ot::getNCA(first, second);
926  }//end if
927  }//end for
928  }//end function*/
929 
930  public:
935  /*static MPI_Op MAX_LEVEL(){
936  static bool first = true;
937  static MPI_Op maxLev;
938  if (first) {
939  first = false;
940  MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_MAX_LEVEL ,true ,&maxLev);
941  }
942  return maxLev;
943  }*/
944 
950  static MPI_Op _MAX() {
951  static bool first = true;
952  static MPI_Op max;
953  if (first) {
954  first = false;
955  MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_MAX ,true ,&max);
956  }
957  return max;
958  }
959 
965  static MPI_Op _MIN() {
966  static bool first = true;
967  static MPI_Op min;
968  if (first) {
969  first = false;
970  MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_MIN ,true ,&min);
971  }
972  return min;
973  }
974 
980  /*static MPI_Op NCA() {
981  static bool first = true;
982  static MPI_Op nca;
983  if (first) {
984  first = false;
985  MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_NCA ,true ,&nca);
986  }
987  return nca;
988  }*/
989 
993  static MPI_Datatype value()
994  {
995  static bool first = true;
996  static MPI_Datatype datatype;
997 
998  if (first)
999  {
1000  first = false;
1001  MPI_Type_contiguous(sizeof(ot::TreeNode), MPI_BYTE, &datatype);
1002  MPI_Type_commit(&datatype);
1003  }
1004 
1005  return datatype;
1006  }
1007 
1008  };
1009 
1010 }//end namespace par
1011 
1012 
1013 
1014 
1015 
1016 
1017 
1018 #endif //SFCSORTBENCH_TREENODE_H
1019 
1020 
bool operator==(TreeNode const &other) const
Two octants are equal if their respective anchors are equal and their levels are equal.
Definition: TreeNode.h:599
Simple class to manage async data transfer in the ODA class.
Definition: asyncExchangeContex.h:16
bool operator<(TreeNode const &other) const
The comparisons are based on the Morton/Hilbert ordering of the octants.
Definition: TreeNode.h:426
bool operator>=(TreeNode const &other) const
The comparisons are based on the Morton/Hilbert ordering of the octants.
Definition: TreeNode.h:588
static MPI_Op _MAX()
User defined MPI_Operation that sets second[i] to first[i] if first[i] is at a greater level than sec...
Definition: TreeNode.h:950
unsigned int getFlag() const
get the m_uiFlag value. Which is used to store the level and other aditional info.
Definition: TreeNode.h:402
static MPI_Op _MIN()
User defined MPI_Operation that computes: second[i] = Min(first[i], second[i]),.
Definition: TreeNode.h:965
unsigned int minX() const
returns true min corner(anchor) and the max corner coordinates of a octant.
Definition: TreeNode.h:164
void incrementLevel()
Can be used the increment octant level by 1. Used in SFC treeSearch function.
Definition: TreeNode.h:395
A class to manage octants.
Definition: TreeNode.h:35
A point class.
Definition: point.h:36
BoundaryType2
The type of boundary.
Definition: TreeNode.h:275
bool operator>(TreeNode const &other) const
The comparisons are based on the Morton/Hilbert ordering of the octants.
Definition: TreeNode.h:577
TreeNode getDFDMorton() const
Definition: TreeNode.cpp:216
TreeNode getParent() const
returns the parent of the current octant
Definition: TreeNode.h:627
unsigned int getMaxDepth() const
return the maxDepth of the octant based of the global value.
Definition: TreeNode.h:383
static MPI_Datatype value()
User defined MPI_Operation that computes: second[i] = NCA(first[i], second[i]),.
Definition: TreeNode.h:993
unsigned int binLength(unsigned int num)
Definition: binUtils.cpp:24
TreeNode getDLD() const
Definition: TreeNode.cpp:253
bool operator!=(TreeNode const &other) const
Two octants are equal if their respective anchors are equal and their levels are equal.
Definition: TreeNode.h:615
unsigned int getLevel() const
return the level of the of the octant
Definition: TreeNode.h:387
bool isBoundaryOctant(int type=POSITIVE, unsigned char *flags=NULL) const
flags is a datastructure which will store which boundaries were touched. highest 3 bits are for +Z...
Definition: TreeNode.cpp:132
bool isRoot() const
returns true if the current considering node is a root node.
Definition: TreeNode.h:391
BoundaryType1
The type of boundary.
Definition: TreeNode.h:270
TreeNode getLeft() const
returns the neighbour octants (right, left top bottom etc)
Definition: TreeNode.h:639
An abstract class used for communicating messages using user-defined datatypes. The user must impleme...
Definition: zoltan_hilbert.h:76
unsigned int getDim() const
return the dimension of the octant
Definition: TreeNode.h:379
A set of efficient functions that use binary operations to perform some small computations.
bool operator<=(TreeNode const &other) const
The comparisons are based on the Morton/Hilbert ordering of the octants.
Definition: TreeNode.h:566
Collection of Generic Parallel Functions: Sorting, Partitioning, Searching,...
Definition: zoltan_hilbert.h:72
unsigned int getX() const
get integer values of the octree coordinates.
Definition: TreeNode.h:366
BoundaryType3
The type of boundary.
Definition: TreeNode.h:283
void setFlag(unsigned int flag)
set the m_uiFlag value. Which is used to store the level and other aditional info.
Definition: TreeNode.h:401
TreeNode getDFD() const
Definition: TreeNode.cpp:224