00001
00009 #ifndef _TREENODE_H_
00010 #define _TREENODE_H_
00011
00012 #include "octUtils.h"
00013 #include "Point.h"
00014 #include <iostream>
00015
00016 #ifdef __DEBUG__
00017 #ifndef __DEBUG_TN__
00018 #define __DEBUG_TN__
00019 #endif
00020 #endif
00021
00022 namespace ot {
00023
00028 class TreeNode {
00029 protected:
00030
00031 unsigned int m_uiX, m_uiY, m_uiZ, m_uiLevel, m_uiWeight, m_uiDim, m_uiMaxDepth;
00032
00033 TreeNode (const int dummy, const unsigned int x,const unsigned int y,
00034 const unsigned int z,const unsigned int level, const unsigned int dim,
00035 const unsigned int maxDepth);
00036
00037 public:
00038
00042 enum BoundaryType1 { NEGATIVE= 2, POSITIVE= 4};
00043
00047 enum BoundaryType2 {
00048 X_NEG_BDY=1, Y_NEG_BDY=2, Z_NEG_BDY=4, NEG_POS_DEMARCATION=8,
00049 EXTERNAL_BDY=16, X_POS_BDY=32, Y_POS_BDY=64, Z_POS_BDY=128
00050 };
00051
00055 enum BoundaryType3 {
00056 FACE_BDY=1, EDGE_BDY=2, CORNER_BDY=3
00057 };
00058
00059 enum OctantFlagType {
00060 MAX_LEVEL=31, BOUNDARY=64, NODE=128
00061 };
00062
00074 int addBalancingDescendants(TreeNode other, std::vector<TreeNode> &seeds,
00075 bool incCorners) const;
00076
00085 int balanceSubtree(std::vector<TreeNode > & in, std::vector<TreeNode > & out,
00086 bool incCorners, bool isSortedCompleteLinear) const;
00087
00095 int completeSubtree(std::vector<TreeNode > & in, std::vector<TreeNode > & out) const;
00096
00104 int pickInternalBoundaryCells(std::vector<TreeNode >& in, std::vector<TreeNode > & out) const;
00105
00115 int splitInternalAndBoundaryCells(std::vector<TreeNode> & allInternal,
00116 std::vector<TreeNode> & onlyInternal,std::vector<TreeNode> & boundary) const;
00117
00120
00128 TreeNode (const unsigned int dim, const unsigned int maxDepth);
00129
00139 TreeNode (const unsigned int x,const unsigned int y,const unsigned int z,
00140 const unsigned int level, const unsigned int dim, const unsigned int maxDepth);
00141
00146 TreeNode (const TreeNode & other);
00147
00152 TreeNode ();
00154
00157
00163 TreeNode & operator = (TreeNode const & other);
00164
00170 bool operator == ( TreeNode const &other) const;
00171
00177 bool operator != (TreeNode const &other) const;
00178
00184 bool operator < ( TreeNode const &other) const;
00185
00190 bool operator > ( TreeNode const &other) const;
00191
00196 bool operator <= ( TreeNode const &other) const;
00197
00202 bool operator >= ( TreeNode const &other) const;
00203
00208 friend std::ostream & operator << (std::ostream & os,TreeNode const & node) ;
00210
00216 unsigned int getDim() const;
00217 unsigned int getMaxDepth() const;
00218 unsigned int getWeight() const;
00219 unsigned int getLevel() const;
00220 unsigned int getFlag() const;
00221 unsigned int getX() const;
00222 unsigned int getY() const;
00223 unsigned int getZ() const;
00224 int getAnchor(unsigned int &x, unsigned int&y, unsigned int&z) const;
00225 Point getAnchor() const { return Point(m_uiX, m_uiY, m_uiZ); };
00226 unsigned int getParentX() const;
00227 unsigned int getParentY() const;
00228 unsigned int getParentZ() const;
00229 unsigned char getChildNumber() const;
00230 int setWeight(unsigned int w);
00231 int addWeight(unsigned int w);
00232 int setFlag(unsigned int w);
00233 int orFlag(unsigned int w);
00235
00241 bool isAncestor(const TreeNode & other) const;
00242
00249 bool isBoundaryOctant(int type=POSITIVE, unsigned char *flags=NULL) const;
00250
00257 bool isBoundaryOctant(const TreeNode &block, int type=POSITIVE, unsigned char *flags=NULL) const;
00258
00263 int addChildren(std::vector<TreeNode > &list) const;
00264
00269 int addBrothers(std::vector<TreeNode>&brothers) const;
00270
00275 TreeNode getParent() const;
00276
00282 TreeNode getAncestor(unsigned int ancLev) const;
00283
00288 TreeNode getDFD() const;
00289
00294 TreeNode getDLD() const;
00295
00300 std::vector<bool> getMorton() const;
00301
00302 unsigned int minX() const;
00303 unsigned int minY() const;
00304 unsigned int minZ() const;
00305 unsigned int maxX() const;
00306 unsigned int maxY() const;
00307 unsigned int maxZ() const;
00308
00309 std::vector<TreeNode> getSearchKeys(bool incCorners);
00310
00316 TreeNode getLeft() const;
00317 TreeNode getRight() const;
00318 TreeNode getTop() const;
00319 TreeNode getBottom() const;
00320 TreeNode getFront() const;
00321 TreeNode getBack() const;
00322 TreeNode getTopLeft() const;
00323 TreeNode getTopRight() const;
00324 TreeNode getBottomLeft() const;
00325 TreeNode getBottomRight() const;
00326 TreeNode getLeftFront() const;
00327 TreeNode getRightFront() const;
00328 TreeNode getTopFront() const;
00329 TreeNode getBottomFront() const;
00330 TreeNode getTopLeftFront() const;
00331 TreeNode getTopRightFront() const;
00332 TreeNode getBottomLeftFront() const;
00333 TreeNode getBottomRightFront() const;
00334 TreeNode getLeftBack() const;
00335 TreeNode getRightBack() const;
00336 TreeNode getTopBack() const;
00337 TreeNode getBottomBack() const;
00338 TreeNode getTopLeftBack() const;
00339 TreeNode getTopRightBack() const;
00340 TreeNode getBottomLeftBack() const;
00341 TreeNode getBottomRightBack() const;
00342 std::vector<TreeNode> getAllNeighbours() const;
00344
00350 std::vector<TreeNode > getB_Left() const;
00351 std::vector<TreeNode > getB_Right() const;
00352 std::vector<TreeNode > getB_Top() const;
00353 std::vector<TreeNode > getB_Bottom() const;
00354 std::vector<TreeNode > getB_Front() const;
00355 std::vector<TreeNode > getB_Back() const;
00356 std::vector<TreeNode > getB_TopLeft() const;
00357 std::vector<TreeNode > getB_TopRight() const;
00358 std::vector<TreeNode > getB_BottomLeft() const;
00359 std::vector<TreeNode > getB_BottomRight() const;
00360 std::vector<TreeNode > getB_LeftFront() const;
00361 std::vector<TreeNode > getB_RightFront() const;
00362 std::vector<TreeNode > getB_TopFront() const;
00363 std::vector<TreeNode > getB_BottomFront() const;
00364 std::vector<TreeNode > getB_TopLeftFront() const;
00365 std::vector<TreeNode > getB_TopRightFront() const;
00366 std::vector<TreeNode > getB_BottomLeftFront() const;
00367 std::vector<TreeNode > getB_BottomRightFront() const;
00368 std::vector<TreeNode > getB_LeftBack() const;
00369 std::vector<TreeNode > getB_RightBack() const;
00370 std::vector<TreeNode > getB_TopBack() const;
00371 std::vector<TreeNode > getB_BottomBack() const;
00372 std::vector<TreeNode > getB_TopLeftBack() const;
00373 std::vector<TreeNode > getB_TopRightBack() const;
00374 std::vector<TreeNode > getB_BottomLeftBack() const;
00375 std::vector<TreeNode > getB_BottomRightBack() const;
00376 std::vector<std::vector<TreeNode> > getAllB_Neighbours() const;
00378
00379 };
00380
00381 }
00382
00383 #include "TreeNode.txx"
00384
00385 namespace par {
00386
00387
00388 template <typename T>
00389 class Mpi_datatype;
00390
00395 template <>
00396 class Mpi_datatype< ot::TreeNode > {
00397
00398 static void Node_MAX_LEVEL(void *in, void *inout, int* len, MPI_Datatype * dptr) {
00399 for(int i = 0; i < (*len); i++) {
00400 ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
00401 ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
00402 (static_cast<ot::TreeNode*>(inout))[i] =
00403 ( ( (first.getLevel()) > (second.getLevel()) )? first : second );
00404 }
00405 }
00406
00407 static void Node_MAX(void *in, void *inout, int* len, MPI_Datatype * dptr) {
00408 for(int i = 0; i < (*len); i++) {
00409 ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
00410 ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
00411 (static_cast<ot::TreeNode*>(inout))[i] = ( ( first > second )? first : second );
00412 }
00413 }
00414
00415 static void Node_MIN(void *in, void *inout, int* len, MPI_Datatype * dptr) {
00416 for(int i = 0; i < (*len); i++) {
00417 ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
00418 ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
00419 (static_cast<ot::TreeNode*>(inout))[i] = ( ( first < second )? first : second );
00420 }
00421 }
00422
00423 static void Node_NCA(void *in, void *inout, int* len, MPI_Datatype * dptr) {
00424 for(int i = 0; i < (*len); i++) {
00425 ot::TreeNode first = (static_cast<ot::TreeNode*>(in))[i];
00426 ot::TreeNode second = (static_cast<ot::TreeNode*>(inout))[i];
00427 if( first != second ) {
00428 (static_cast<ot::TreeNode*>(inout))[i] = ot::getNCA(first, second);
00429 }
00430 }
00431 }
00432
00433 public:
00438 static MPI_Op MAX_LEVEL() {
00439 static bool first = true;
00440 static MPI_Op maxLev;
00441 if (first) {
00442 first = false;
00443 MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_MAX_LEVEL ,true ,&maxLev);
00444 }
00445 return maxLev;
00446 }
00447
00453 static MPI_Op _MAX() {
00454 static bool first = true;
00455 static MPI_Op max;
00456 if (first) {
00457 first = false;
00458 MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_MAX ,true ,&max);
00459 }
00460 return max;
00461 }
00462
00468 static MPI_Op _MIN() {
00469 static bool first = true;
00470 static MPI_Op min;
00471 if (first) {
00472 first = false;
00473 MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_MIN ,true ,&min);
00474 }
00475 return min;
00476 }
00477
00483 static MPI_Op NCA() {
00484 static bool first = true;
00485 static MPI_Op nca;
00486 if (first) {
00487 first = false;
00488 MPI_Op_create(Mpi_datatype<ot::TreeNode>::Node_NCA ,true ,&nca);
00489 }
00490 return nca;
00491 }
00492
00496 static MPI_Datatype value()
00497 {
00498 static bool first = true;
00499 static MPI_Datatype datatype;
00500
00501 if (first)
00502 {
00503 first = false;
00504 MPI_Type_contiguous(sizeof(ot::TreeNode), MPI_BYTE, &datatype);
00505 MPI_Type_commit(&datatype);
00506 }
00507
00508 return datatype;
00509 }
00510
00511 };
00512
00513 }
00514
00515 #endif
00516