tree_node.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /**
  2. * \file tree_node.cpp
  3. * \author Dhairya Malhotra, dhairya.malhotra@gmail.com
  4. * \date 12-10-2010
  5. * \brief This file contains the implementation of the class TreeNode.
  6. */
  7. #include <tree_node.hpp>
  8. #include <assert.h>
  9. #include <iostream>
  10. #include <mem_mgr.hpp>
  11. namespace pvfmm{
  12. TreeNode::~TreeNode(){
  13. if(!child) return;
  14. int n=(1UL<<dim);
  15. //Delete the children.
  16. for(int i=0;i<n;i++){
  17. if(child[i]!=NULL)
  18. mem::aligned_delete(child[i]);
  19. }
  20. mem::aligned_delete(child);
  21. child=NULL;
  22. }
  23. void TreeNode::Initialize(TreeNode* parent_, int path2node_, NodeData* data_){
  24. parent=parent_;
  25. depth=(parent==NULL?0:parent->Depth()+1);
  26. if(data_!=NULL){
  27. dim=data_->dim;
  28. max_depth=data_->max_depth;
  29. if(max_depth>MAX_DEPTH) max_depth=MAX_DEPTH;
  30. }else if(parent!=NULL){
  31. dim=parent->dim;
  32. max_depth=parent->max_depth;
  33. }
  34. assert(path2node_>=0 && path2node_<(1U<<dim));
  35. path2node=path2node_;
  36. //assert(parent_==NULL?true:parent_->Child(path2node_)==this);
  37. }
  38. TreeNode* TreeNode::Child(int id){
  39. assert(id<(1<<dim));
  40. if(child==NULL) return NULL;
  41. return child[id];
  42. }
  43. TreeNode* TreeNode::Parent(){
  44. return parent;
  45. }
  46. int TreeNode::Path2Node(){
  47. return path2node;
  48. }
  49. TreeNode* TreeNode::NewNode(TreeNode* n_){
  50. TreeNode* n=(n_==NULL?mem::aligned_new<TreeNode>():n_);
  51. n->dim=dim;
  52. n->max_depth=max_depth;
  53. return n_;
  54. }
  55. bool TreeNode::SubdivCond(){
  56. if(!IsLeaf()){
  57. int n=(1UL<<dim);
  58. for(int i=0;i<n;i++){
  59. TreeNode* ch=this->Child(i);
  60. assert(ch!=NULL); //This should never happen
  61. if(!ch->IsLeaf()) return true;
  62. }
  63. if(Depth()>=max_depth) return false;
  64. return true;
  65. }else{
  66. if(this->Depth()>=max_depth) return false;
  67. return false;
  68. }
  69. }
  70. void TreeNode::Subdivide() {
  71. if(child) return;
  72. SetStatus(1);
  73. int n=(1UL<<dim);
  74. child=mem::aligned_new<TreeNode*>(n);
  75. for(int i=0;i<n;i++){
  76. child[i]=this->NewNode();
  77. child[i]->parent=this;
  78. child[i]->Initialize(this,i,NULL);
  79. }
  80. }
  81. void TreeNode::Truncate() {
  82. if(!child) return;
  83. SetStatus(1);
  84. int n=(1UL<<dim);
  85. for(int i=0;i<n;i++){
  86. if(child[i]!=NULL)
  87. delete child[i];
  88. }
  89. delete[] child;
  90. child=NULL;
  91. }
  92. void TreeNode::SetParent(TreeNode* p, int path2node_) {
  93. assert(path2node_>=0 && path2node_<(1<<dim));
  94. assert(p==NULL?true:p->Child(path2node_)==this);
  95. parent=p;
  96. path2node=path2node_;
  97. depth=(parent==NULL?0:parent->Depth()+1);
  98. if(parent!=NULL) max_depth=parent->max_depth;
  99. }
  100. void TreeNode::SetChild(TreeNode* c, int id) {
  101. assert(id<(1<<dim));
  102. //assert(child!=NULL);
  103. //if(child[id]!=NULL)
  104. // delete child[id];
  105. child[id]=c;
  106. if(c!=NULL) child[id]->SetParent(this,id);
  107. }
  108. int& TreeNode::GetStatus(){
  109. return status;
  110. }
  111. void TreeNode::SetStatus(int flag){
  112. status=(status|flag);
  113. if(parent && !(parent->GetStatus() & flag))
  114. parent->SetStatus(flag);
  115. }
  116. }//end namespace