13 #ifndef SFCSORTBENCH_TREENODE_H 14 #define SFCSORTBENCH_TREENODE_H 16 static unsigned int MAX_LEVEL=31;
18 extern unsigned int m_uiMaxDepth;
21 #include "hcurvedata.h" 38 unsigned int m_uiX, m_uiY, m_uiZ, m_uiLevel;
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);
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);
51 TreeNode(
const unsigned int dim,
const unsigned int maxDepth );
60 unsigned int getDim()
const;
78 inline void setFlag(
unsigned int flag);
84 inline unsigned int getFlag()
const;
90 unsigned int getX()
const;
91 unsigned int getY()
const;
92 unsigned int getZ()
const;
152 unsigned int genHkey_Bonsai_sc16()
const ;
156 inline bool isAncestor(
const TreeNode & other)
const;
164 inline unsigned int minX()
const {
168 inline unsigned int minY()
const {
169 if (m_uiDim < 2) {
return 0; }
173 inline unsigned int minZ()
const {
174 if (m_uiDim < 3) {
return 0; }
178 inline unsigned int maxX()
const {
179 unsigned int len = (1u << (m_uiMaxDepth -
getLevel()));
180 return (
minX() + len);
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);
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);
239 TreeNode getBottomLeftFront()
const;
240 TreeNode getBottomRightFront()
const;
248 TreeNode getBottomRightBack()
const;
249 std::vector<TreeNode> getAllNeighbours()
const;
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); };
255 inline unsigned int getMortonIndex()
const;
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
284 FACE_BDY=1, EDGE_BDY=2, CORNER_BDY=3
287 enum OctantFlagType {
288 MAX_LEVEL=31, BOUNDARY=64, NODE=128
311 int addChildren(std::vector<ot::TreeNode>& children)
const;
313 int getChildrenInMortonOrdering(std::vector<ot::TreeNode>& children)
const 315 unsigned int dim = m_uiDim;
316 unsigned int maxDepth = m_uiMaxDepth;
317 children.resize((1 << dim));
321 if ((m_uiLevel & ot::TreeNode::MAX_LEVEL) == maxDepth) {
322 for (
int i = 0; i < (1 << dim); i++) {
330 unsigned int len = (
unsigned int)(1u << (maxDepth - ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1)));
332 TreeNode tmpNode0(m_uiX, m_uiY, m_uiZ, ((m_uiLevel & ot::TreeNode::MAX_LEVEL) + 1), m_uiDim, m_uiMaxDepth);
333 children[0] = tmpNode0;
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;
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;
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;
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;
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;
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;
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;
370 inline unsigned int TreeNode::getY()
const {
374 inline unsigned int TreeNode::getZ()
const {
388 return (m_uiLevel & MAX_LEVEL);
392 return ((this->
getLevel()==0) & (m_uiX==0) & (m_uiY==0) & (m_uiZ==0));
404 inline bool TreeNode::isAncestor(
const TreeNode & other)
const 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()) ));
423 std::ostream & operator << (std::ostream & os,
TreeNode const & node) ;
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;
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));
441 #ifdef HILBERT_ORDERING 448 unsigned int x1 = m_uiX;
449 unsigned int x2 = other.
getX();
451 unsigned int y1 = m_uiY;
452 unsigned int y2 = other.getY();
454 unsigned int z1 = m_uiZ;
455 unsigned int z2 = other.getZ();
458 unsigned int maxDepth = m_uiMaxDepth;
463 if(!((x1<x2 || x1>=(x2+len)) || (y1<y2 || y1>=(y2+len)) ||(z1<z2 || z1>=(z2+len))))
470 if(!((x2<x1 || x2>=(x1+len))||(y2<y1 || y2>=(y1+len))||(z2<z1 || z2>=(z1+len))))
476 unsigned int maxDiff = (
unsigned int)(std::max((std::max((x1^x2),(y1^y2))),(z1^z2)));
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);
501 unsigned int index1=0;
502 unsigned int index2=0;
503 unsigned int num_children=1u<<dim;
504 unsigned int rot_offset=num_children<<1;
510 unsigned int mid_bit=m_uiMaxDepth;
512 for(
int i=0; i<ncaLev;i++)
514 mid_bit=m_uiMaxDepth-i-1;
521 index1= ((((ncaZ & (1u << mid_bit)) >> mid_bit) << 2u) |(((ncaY & (1u << mid_bit)) >> mid_bit) << 1u) | ((ncaX & (1u << mid_bit)) >> mid_bit));
523 current_rot=HILBERT_TABLE[current_rot*num_children+index1];
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));
529 return rotations[rot_offset*current_rot+num_children+index1] < rotations[rot_offset*current_rot+num_children+index2];
538 #pragma message "Morton" 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));
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);
551 unsigned int maxC = z;
552 unsigned int yOrx = y;
553 if (yOrx < x) {
if ((x ^ yOrx) >= yOrx) {yOrx = x;}
555 if (maxC < yOrx) {
if ((maxC ^ yOrx) >= maxC) {maxC = yOrx;}
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); }
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;
574 return (((*
this) < other) || ((*
this) == other));
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;
585 return ((!((*
this) < other)) && (!((*
this) == other)));
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;
596 return (!((*
this) < other));
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;
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))) {
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;
623 return (!((*
this) == other));
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);
642 unsigned int len = (1u << (m_uiMaxDepth -
getLevel()));
643 unsigned int xres = (
minX() - len);
644 unsigned int yres = minY();
645 unsigned int zres = minZ();
649 TreeNode res(m_uiDim, m_uiMaxDepth);
654 inline TreeNode TreeNode::getRight()
const {
656 if (maxX() < (1u << m_uiMaxDepth)) {
657 unsigned int xres = maxX();
658 unsigned int yres = minY();
659 unsigned int zres = minZ();
663 TreeNode res(m_uiDim, m_uiMaxDepth);
668 inline TreeNode TreeNode::getBack()
const {
670 if ((m_uiDim > 1) && (maxY() < (1u << m_uiMaxDepth))) {
671 unsigned int xres =
minX();
672 unsigned int yres = maxY();
673 unsigned int zres = minZ();
677 TreeNode res(m_uiDim, m_uiMaxDepth);
682 inline TreeNode TreeNode::getFront()
const {
685 unsigned int len = (1u << (m_uiMaxDepth -
getLevel()));
686 unsigned int xres =
minX();
687 unsigned int yres = minY() - len;
688 unsigned int zres = minZ();
692 TreeNode res(m_uiDim, m_uiMaxDepth);
697 inline TreeNode TreeNode::getBottom()
const {
700 unsigned int len = (1u << (m_uiMaxDepth -
getLevel()));
701 unsigned int xres =
minX();
702 unsigned int yres = minY();
703 unsigned int zres = minZ() - len;
707 TreeNode res(m_uiDim, m_uiMaxDepth);
712 inline TreeNode TreeNode::getTop()
const {
714 if ((m_uiDim == 3) && (maxZ() < (1u << m_uiMaxDepth))) {
715 unsigned int xres =
minX();
716 unsigned int yres = minY();
717 unsigned int zres = maxZ();
721 TreeNode res(m_uiDim, m_uiMaxDepth);
726 inline TreeNode TreeNode::getLeftBack()
const {
730 inline TreeNode TreeNode::getRightBack()
const {
731 return (getRight().getBack());
734 inline TreeNode TreeNode::getLeftFront()
const {
738 inline TreeNode TreeNode::getRightFront()
const {
739 return (getRight().getFront());
742 inline TreeNode TreeNode::getBottomLeft()
const {
743 return (getBottom().
getLeft());
746 inline TreeNode TreeNode::getBottomRight()
const {
747 return (getBottom().getRight());
750 inline TreeNode TreeNode::getBottomBack()
const {
751 return (getBottom().getBack());
754 inline TreeNode TreeNode::getBottomFront()
const {
755 return (getBottom().getFront());
758 inline TreeNode TreeNode::getBottomLeftBack()
const {
759 return (getBottomLeft().getBack());
762 inline TreeNode TreeNode::getBottomRightBack()
const {
763 return (getBottomRight().getBack());
766 inline TreeNode TreeNode::getBottomLeftFront()
const {
767 return (getBottomLeft().getFront());
770 inline TreeNode TreeNode::getBottomRightFront()
const {
771 return (getBottomRight().getFront());
774 inline TreeNode TreeNode::getTopLeft()
const {
778 inline TreeNode TreeNode::getTopRight()
const {
779 return (getTop().getRight());
782 inline TreeNode TreeNode::getTopBack()
const {
783 return (getTop().getBack());
786 inline TreeNode TreeNode::getTopFront()
const {
787 return (getTop().getFront());
790 inline TreeNode TreeNode::getTopLeftBack()
const {
791 return (getTopLeft().getBack());
794 inline TreeNode TreeNode::getTopRightBack()
const {
795 return (getTopRight().getBack());
798 inline TreeNode TreeNode::getTopLeftFront()
const {
799 return (getTopLeft().getFront());
802 inline TreeNode TreeNode::getTopRightFront()
const {
803 return (getTopRight().getFront());
807 inline int TreeNode::getAnchor(
unsigned int &x,
unsigned int &y,
unsigned int &z)
const {
816 inline std::vector<TreeNode> TreeNode::getAllNeighbours()
const {
823 std::vector<TreeNode> neighList;
826 neighList.resize(26);
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) {
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();
866 neighList[1] = getRight();
871 inline unsigned int ot::TreeNode::getMortonIndex()
const 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));
885 template <
typename T>
895 static void Node_MAX_LEVEL(
void *in,
void *inout,
int* len, MPI_Datatype * dptr) {
896 for(
int i = 0; i < (*len); i++) {
904 static void Node_MAX(
void *in,
void *inout,
int* len, MPI_Datatype * dptr) {
905 for(
int i = 0; i < (*len); i++) {
908 (
static_cast<ot::TreeNode*
>(inout))[i] = ( ( first > second )? first : second );
912 static void Node_MIN(
void *in,
void *inout,
int* len, MPI_Datatype * dptr) {
913 for(
int i = 0; i < (*len); i++) {
916 (
static_cast<ot::TreeNode*
>(inout))[i] = ( ( first < second )? first : second );
951 static bool first =
true;
966 static bool first =
true;
995 static bool first =
true;
996 static MPI_Datatype datatype;
1001 MPI_Type_contiguous(
sizeof(
ot::TreeNode), MPI_BYTE, &datatype);
1002 MPI_Type_commit(&datatype);
1018 #endif //SFCSORTBENCH_TREENODE_H 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