7#ifndef GENERICTREENODE_H
8#define GENERICTREENODE_H
18#include "OrientedBox.h"
36 static const int NodeKeyBits = 8*
sizeof(
NodeKey);
54 extern int numEmptyNodes;
59 class GenericTreeNode {
60#ifdef CHANGA_REFACTOR_WALKCHECK
79 bucketArrayIndex = -1;
82#ifdef CHANGA_REFACTOR_WALKCHECK
132 int bucketArrayIndex;
156 bucketArrayIndex = -1;
192 return (myType != Invalid);
197 return (myType == Cached ||
198 myType == CachedBucket ||
199 myType == CachedEmpty);
204 return (myType == Bucket ||
205 myType == CachedBucket ||
206 myType == NonLocalBucket);
226 if(
moments.getRadius() <= 0.0) {
243 double fBallMax = part[i].fBallMax();
245 + Vector3D<double>(fBallMax, fBallMax, fBallMax));
247 - Vector3D<double>(fBallMax, fBallMax, fBallMax));
278 CkAbort(
"getLongestCommonPrefix not implemented\n");
285 virtual GenericTreeNode *
clone()
const = 0;
288 virtual void pup(PUP::er &p,
int depth) = 0;
290 virtual void pup(PUP::er &p) {
292 if(p.isUnpacking()) {
299 bucketArrayIndex = -1;
302 iType = (int) myType;
322#ifdef CHANGA_REFACTOR_WALKCHECK
336 std::list<BinaryTreeNode *> pools;
355 class BinaryTreeNode :
public GenericTreeNode {
358 BinaryTreeNode* children[2];
360 BinaryTreeNode() : GenericTreeNode() {
366 BinaryTreeNode(
NodeKey k,
NodeType type,
int first,
int nextlast, BinaryTreeNode *p) : GenericTreeNode(k, type, first, nextlast, p) {
372 if (children[0] != NULL) children[0]->fullyDelete();
374 if (children[1] != NULL) children[1]->fullyDelete();
383 CkAssert(i>=0 && i<2);
388 CkAssert(i>=0 && i<2);
389 children[i] = (BinaryTreeNode*)node;
393 CkAssert(i>=0 && i<2);
416 NodeKey a1 = k1 << (NodeKeyBits-l1);
417 NodeKey a2 = k2 << (NodeKeyBits-l2);
421 while( a < (
NodeKey(1)<<(NodeKeyBits-1)) )
426 return (k1 >> (l1-i));
433 return ((child >> (childLevel-thisLevel-1)) ^ (key << 1));
441 if(nodeLevel<thisLevel)
return false;
443 return ((node>>(nodeLevel-thisLevel))==key);
447 bool isLeftChild()
const {
451 bool isRightChild()
const {
452 return (
dynamic_cast<BinaryTreeNode *
>(
parent) &&
dynamic_cast<BinaryTreeNode *
>(
parent)->children[1] ==
this);
455 BinaryTreeNode* getSibling()
const {
456 BinaryTreeNode* p =
dynamic_cast<BinaryTreeNode *
>(
parent);
458 return (p->children[0] ==
this ? p->children[1] : p->children[0]);
476 children[0] = pool->alloc_one();
477 children[1] = pool->alloc_one();
480 children[0] =
new BinaryTreeNode();
481 children[1] =
new BinaryTreeNode();
483 children[0]->parent =
this;
484 children[1]->parent =
this;
491 children[0]->boundingBox.greater_corner.x = split;
492 children[1]->boundingBox.lesser_corner.x = split;
496 children[0]->boundingBox.greater_corner.y = split;
497 children[1]->boundingBox.lesser_corner.y = split;
501 children[0]->boundingBox.greater_corner.z = split;
502 children[1]->boundingBox.lesser_corner.z = split;
505 children[0]->key = key << 1;
506 children[1]->key = (key << 1) + 1;
512 SFC::Key mask = SFC::Key(1) << ((SFC::KeyBits-1) - level);
516 if (leftBit == rightBit) {
523 children[0]->myType = NonLocal;
524 children[1]->myType = Boundary;
526 children[0]->makeEmpty();
527 children[1]->myType =
lastParticle==totalPart+1 ? Boundary : Internal;
530 children[0]->particleCount = 0;
538 children[1]->myType = NonLocal;
539 children[0]->myType = Boundary;
541 children[1]->makeEmpty();
542 children[0]->myType =
firstParticle==0 ? Boundary : Internal;
545 children[1]->particleCount = 0;
549 }
else if (leftBit < rightBit) {
555 children[0]->myType = NonLocal;
557 children[1]->myType =
lastParticle==totalPart+1 ? Boundary : Internal;
560 }
else if (
lastParticle == totalPart+1 && rightBit != (part[totalPart].key & mask)) {
564 children[1]->myType = NonLocal;
566 children[0]->myType =
firstParticle==0 ? Boundary : Internal;
576 & ((~ (SFC::Key)0) << ((SFC::KeyBits-1)-level))));
577 children[0]->lastParticle = splitParticle - part - 1;
578 children[1]->firstParticle = splitParticle - part;
579 children[0]->particleCount = children[0]->lastParticle -
firstParticle + 1;
580 children[1]->particleCount =
lastParticle - children[1]->firstParticle + 1;
581 children[0]->myType = children[0]->particleCount==0 ? Empty : (
firstParticle==0 ? Boundary : Internal);
582 children[1]->myType = children[1]->particleCount==0 ? Empty : (
lastParticle==totalPart+1 ? Boundary : Internal);
583 if (children[0]->myType==Empty) children[0]->makeEmpty();
584 if (children[1]->myType==Empty) children[1]->makeEmpty();
586 if (
lastParticle == totalPart+1) children[1]->particleCount --;
589 CkAbort(
"Ok, the particles should be ordered so, how the hell did we get here?!?");
591 children[0]->particlePointer = &part[children[0]->firstParticle];
592 children[1]->particlePointer = &part[children[1]->firstParticle];
594 if(children[0]->myType == NonLocal) children[0]->numBucketsBeneath = 0;
595 if(children[1]->myType == NonLocal) children[1]->numBucketsBeneath = 0;
604 bool spatial,
NodePool *pool=NULL) {
607 children[0] = pool->alloc_one();
608 children[1] = pool->alloc_one();
611 children[0] =
new BinaryTreeNode();
612 children[1] =
new BinaryTreeNode();
614 children[0]->parent =
this;
615 children[1]->parent =
this;
619 children[0]->key = key << 1;
620 children[1]->key = (key << 1) + 1;
625 if(level<rootsLevel){
628 SFC::Key tmp = 1 << (level+1);
629 tmp = children[0]->key - tmp;
630 SFC::Key tmp2 = part[0].key >> (rootsLevel-level-1);
632 if(level+1 != rootsLevel){
634 children[0]->myType = Boundary;
635 children[1]->myType = NonLocal;
641 children[0]->myType = NonLocal;
642 children[1]->myType = Boundary;
650 children[0]->myType = Internal;
651 children[1]->myType = NonLocal;
661 children[0]->myType = NonLocal;
662 children[1]->myType = Internal;
674 float len=0.0,len2=0.0;
688 if(len2>len) { len = len2; dim=1; }
691 if(len2>len) { len = len2; dim=2; }
717 GravityParticle dummy;
719 Vector3D<double> divide(0.0,0.0,0.0);
721 dummy.position = divide;
722 GravityParticle* divEnd
724 dummy,compFnPtr[dim]);
725 children[0]->lastParticle =
firstParticle + (divEnd - divStart) - 1;
726 children[1]->firstParticle =
firstParticle + (divEnd - divStart);
727 children[0]->particleCount = divEnd - divStart;
729 - (divEnd - divStart);
734 children[0]->myType = Internal;
735 children[1]->myType = Internal;
738 children[0]->boundingBox.lesser_corner =
boundingBox.lesser_corner;
739 children[0]->boundingBox.greater_corner =
boundingBox.greater_corner;
740 children[0]->boundingBox.greater_corner[dim] = part[children[0]->lastParticle].position[dim];
742 children[1]->boundingBox.lesser_corner =
boundingBox.lesser_corner;
743 children[1]->boundingBox.lesser_corner[dim] = part[children[1]->firstParticle].position[dim];
744 children[1]->boundingBox.greater_corner =
boundingBox.greater_corner;
747 children[0]->particlePointer = &part[children[0]->firstParticle];
748 children[1]->particlePointer = &part[children[1]->firstParticle];
753 GenericTreeNode *
clone()
const;
769 int additional = num - base;
770 if (ret==NULL) ret =
new NodeKey[num];
771 for (
int j=additional, k=additional*2; j<base; ++j, ++k) ret[k] = j + base;
773 for (
int j=0; j<additional*2; ++j) ret[j] = j + base;
777 int countDepth(
int depth) {
780 if (children[0] != NULL) count += children[0]->countDepth(depth-1);
781 if (children[1] != NULL) count += children[1]->countDepth(depth-1);
788 int packNodes(BinaryTreeNode *buffer,
int depth,
int extraSpace=0) {
791 memcpy((
void *)buffer, (
void *)
this,
sizeof(*
this));
792 buffer->parent = NULL;
793 buffer->particlePointer = NULL;
794#if INTERLIST_VER > 0 && defined CUDA
795 buffer->nodeArrayIndex = -1;
796 buffer->bucketArrayIndex = -1;
800 if (children[0] != NULL) {
801 BinaryTreeNode *nextBuf = (BinaryTreeNode *) (((
char*)buffer) + used * ALIGN_DEFAULT(
sizeof(BinaryTreeNode)+extraSpace));
802 buffer->children[0] = (BinaryTreeNode*)(((
char*)nextBuf) - ((
char*)buffer));
804 used += children[0]->packNodes(nextBuf, depth-1, extraSpace);
807 buffer->children[0] = NULL;
809 if (children[1] != NULL) {
810 BinaryTreeNode *nextBuf = (BinaryTreeNode *) (((
char*)buffer) + used * ALIGN_DEFAULT(
sizeof(BinaryTreeNode)+extraSpace));
811 buffer->children[1] = (BinaryTreeNode*)(((
char*)nextBuf) - ((
char*)buffer));
813 used += children[1]->packNodes(nextBuf, depth-1, extraSpace);
816 buffer->children[1] = NULL;
820 buffer->children[0] = buffer->children[1] = NULL;
829 if (children[0] != NULL) {
831 children[0] = (BinaryTreeNode*)(((
long int)children[0]) + ((
char*)
this));
832 children[0]->parent =
this;
833 children[0]->unpackNodes();
835 if (children[1] != NULL) {
837 children[1] = (BinaryTreeNode*)(((
long int)children[1]) + ((
char*)
this));
838 children[1]->parent =
this;
839 children[1]->unpackNodes();
844 void pup(PUP::er &p,
int depth);
862NodePool::~NodePool() {
863 while(!pools.empty()) {
864 delete [] pools.front();
874 pools.push_front(nodes);
876 return &pools.front()[next++];
887 class OctTreeNode :
public GenericTreeNode {
893 OctTreeNode() : GenericTreeNode() {
894 for (
int i = 0; i < 8; i++) {
901 for (
int i = 0; i < 8; i++) {
920 CkAssert(i>=0 && i<8);
925 CkAssert(i>=0 && i<8);
930 CkAssert(i>=0 && i<8);
939 return (child ^ (key<<3));
966 OctTreeNode *tmp =
new OctTreeNode();
987 void pup(PUP::er &p,
int depth);
1013 while(tmp<=key1 || tmp<=key2){
1016 if(len1==0 && tmp>key1){
1019 if(len2==0 && tmp>key2){
1041 if (p.isUnpacking()) {
1053 if (p.isUnpacking()) {
std::map< NodeKey, GenericTreeNode * > NodeLookupType
Definition GenericTreeNode.h:352
GenericTrees
Definition GenericTreeNode.h:995
void operator|(PUP::er &p, NodeType &nt)
PUP a NodeType.
Definition GenericTreeNode.h:1039
NodeType
This enumeration determines the different types of node a GenericTreeNode can be.
Definition GenericTreeNode.h:39
KeyType NodeKey
This key is the identification of a node inside the global tree, and it is unique for the node....
Definition GenericTreeNode.h:35
int TYPETest(const GravityParticle *a, unsigned int b)
Test for a type flag.
Definition GravityParticle.h:606
void calculateRadiusBox(MultipoleMoments &m, const OrientedBox< double > &box)
Definition MultipoleMoments.h:475
void calculateRadiusFirstParticle(MultipoleMoments &m, const ParticleType *begin, const ParticleType *end)
Definition MultipoleMoments.h:510
void calculateRadiusFarthestParticle(MultipoleMoments &m, const ParticleType *begin, const ParticleType *end)
Given the positions that make up a multipole expansion, set the distance to the farthest particle fro...
Definition MultipoleMoments.h:488
Fundamental type for a particle.
Definition GravityParticle.h:364
int rung
the current rung (greater means faster)
Definition GravityParticle.h:389
unsigned int iType
Bitmask to hold particle type information.
Definition GravityParticle.h:390
A representation of a multipole expansion.
Definition MultipoleMoments.h:163
A TreeNode with two children.
Definition GenericTreeNode.h:355
void pup(PUP::er &p)
PUP just this node.
Definition GenericTreeNode.h:843
NodeKey getLongestCommonPrefix(NodeKey k1, NodeKey k2)
return the NodeKey of the lowest common ancestor.
Definition GenericTreeNode.h:411
NodeKey getChildKey(int i)
return the keys for the specified child
Definition GenericTreeNode.h:392
unsigned int numChildren() const
return the number of children this node has
Definition GenericTreeNode.h:378
NodeKey getParentKey()
return the key for the parent
Definition GenericTreeNode.h:397
int getLevel(NodeKey k)
depth of node corresponding to NodeKey
Definition GenericTreeNode.h:401
void makeOctChildren(GravityParticle *part, int totalPart, int level, NodePool *pool=NULL)
Definition GenericTreeNode.h:473
GenericTreeNode * getChildren(int i)
return the pointers to the specified child of this node
Definition GenericTreeNode.h:382
void setChildren(int i, GenericTreeNode *node)
set the specified child of this node to the passed pointer
Definition GenericTreeNode.h:387
void getChunks(int num, NodeKey *&ret)
Get a number of top level NodeKeys which together make a complete tree.
Definition GenericTreeNode.h:760
GenericTreeNode * clone() const
make a copy of the node
Definition GenericTreeNode.cpp:6
void fullyDelete()
Recursively delete all nodes beneath this node.
Definition GenericTreeNode.h:371
int whichChild(NodeKey child)
return an integer with the number of the child reflecting the key
Definition GenericTreeNode.h:430
bool contains(NodeKey node)
Is nodekey contained by this node.
Definition GenericTreeNode.h:437
Base class for tree nodes.
Definition GenericTreeNode.h:59
virtual int whichChild(NodeKey childkey)=0
return an integer with the number of the child reflecting the key
Vector3D< double > centerSm
center of smoothActive particles during smooth operation
Definition GenericTreeNode.h:136
virtual GenericTreeNode * getChildren(int)=0
return the pointers to the specified child of this node
unsigned int particleCount
Total number of particles contained (across all chares)
Definition GenericTreeNode.h:115
int rungs
Definition GenericTreeNode.h:122
GenericTreeNode * parent
The parent of this node, or null if none.
Definition GenericTreeNode.h:96
GenericTreeNode(NodeKey k, NodeType type, int first, int last, GenericTreeNode *p)
Construct GenericTreeNode.
Definition GenericTreeNode.h:150
bool isValid()
Is the NodeType valid.
Definition GenericTreeNode.h:191
virtual GenericTreeNode * clone() const =0
make a copy of the node
double fKeyMax
Maximum smoothing radius of smoothActive particles.
Definition GenericTreeNode.h:140
NodeType getType() const
return Tree::NodeType of node
Definition GenericTreeNode.h:166
virtual int getLevel(NodeKey k)=0
depth of node corresponding to NodeKey
int lastParticle
An index to the last particle contained by this node, myNumParticles+1 means outside the node.
Definition GenericTreeNode.h:108
int iRank
SMP rank of node owner.
Definition GenericTreeNode.h:142
void setType(NodeType t)
set Tree::NodeType of node
Definition GenericTreeNode.h:168
bool isBucket()
Is this a node a bucket.
Definition GenericTreeNode.h:203
void getGraphViz(std::ostream &out)
print out a visualization of the tree for diagnostics
Definition ParallelGravity.cpp:4614
virtual NodeKey getChildKey(int)=0
return the keys for the specified child
NodeKey getKey() const
return unique Tree::NodeKey
Definition GenericTreeNode.h:171
virtual void setChildren(int, GenericTreeNode *)=0
set the specified child of this node to the passed pointer
OrientedBox< cosmoType > boundingBox
The axis-aligned bounding box of this node.
Definition GenericTreeNode.h:98
virtual void pup(PUP::er &p, int depth)=0
PUP node and children down to depth.
virtual void getChunks(int num, NodeKey *&ret)=0
double sizeSm
Radius of bounding sphere of smoothActive particles.
Definition GenericTreeNode.h:138
int numBucketsBeneath
Number of buckets in this node.
Definition GenericTreeNode.h:126
virtual bool contains(NodeKey nodekey)=0
Is nodekey contained by this node.
GravityParticle * particlePointer
Pointer to the first particle in this node.
Definition GenericTreeNode.h:117
virtual void fullyDelete()=0
Recursively delete all nodes beneath this node.
void makeBucket(GravityParticle *part)
transform an internal node into a bucket
Definition GenericTreeNode.h:219
unsigned int iParticleTypes
Mask of particle types contatained in this node.
Definition GenericTreeNode.h:102
virtual void pup(PUP::er &p)
PUP just this node.
Definition GenericTreeNode.h:290
int firstParticle
An index for the first particle contained by this node, 0 means outside the node.
Definition GenericTreeNode.h:106
virtual NodeKey getParentKey()=0
return the key for the parent
void makeEmpty()
initialize an empty node
Definition GenericTreeNode.h:259
int startBucket
index of first bucket in this node
Definition GenericTreeNode.h:128
virtual void makeOctChildren(GravityParticle *part, int totalPart, int level, NodePool *pool=NULL)=0
construct the children of the "this" node following the given logical criteria (Oct/Orb)
OrientedBox< double > bndBoxBall
The bounding box including search balls of this node.
Definition GenericTreeNode.h:100
MultipoleMoments moments
The moments for the gravity computation.
Definition GenericTreeNode.h:94
virtual unsigned int numChildren() const =0
return the number of children this node has
virtual NodeKey getLongestCommonPrefix(NodeKey k1, NodeKey k2)
return the NodeKey of the lowest common ancestor.
Definition GenericTreeNode.h:276
int64_t nSPH
The number of SPH particles this node contains.
Definition GenericTreeNode.h:104
bool isCached()
Is this a node in the cache.
Definition GenericTreeNode.h:196
int remoteIndex
Definition GenericTreeNode.h:113
Utility to pool allocations of tree nodes.
Definition GenericTreeNode.h:332
BinaryTreeNode * alloc_one()
give out one node from the pool, allocating a new pool block if needed.
Definition GenericTreeNode.h:870
Class for Oct tree where each node has 8 direct children.
Definition GenericTreeNode.h:887
bool contains(NodeKey node)
Is nodekey contained by this node.
Definition GenericTreeNode.h:953
virtual GenericTreeNode * getChildren(int i)
return the pointers to the specified child of this node
Definition GenericTreeNode.h:919
int whichChild(NodeKey child)
return an integer with the number of the child reflecting the key
Definition GenericTreeNode.h:938
void pup(PUP::er &p, int depth)
PUP node and children down to depth.
int getLevel(NodeKey k)
depth of node corresponding to NodeKey
Definition GenericTreeNode.h:942
virtual unsigned int numChildren() const
return the number of children this node has
Definition GenericTreeNode.h:915
OctTreeNode * children[8]
the 8 different children
Definition GenericTreeNode.h:891
GenericTreeNode * clone() const
make a copy of the node
Definition GenericTreeNode.h:965
NodeKey getParentKey()
return the key for the parent
Definition GenericTreeNode.h:934
NodeKey getChildKey(int i)
return the keys for the specified child
Definition GenericTreeNode.h:929
void makeOctChildren(GravityParticle *part, int totalPart, int level, NodePool *pool=NULL)
construct the children of the "this" node following the given logical criteria (Oct/Orb)
Definition GenericTreeNode.h:959
void getChunks(int num, NodeKey *&ret)
Definition GenericTreeNode.h:982
virtual void setChildren(int i, GenericTreeNode *node)
set the specified child of this node to the passed pointer
Definition GenericTreeNode.h:924
void fullyDelete()
Recursively delete all nodes beneath this node.
Definition GenericTreeNode.h:906
void pup(PUP::er &p)
PUP just this node.