GLAMERDOC++
Gravitational Lensing Code Library
Loading...
Searching...
No Matches
qTreeNB.h
1//
2// qTreeNB.h
3// GLAMER
4//
5// Created by Ben Metcalf on 11/11/2018.
6//
7
8#ifndef qTreeNB_h
9#define qTreeNB_h
10
11#include "utilities.h"
12#include "cosmo.h"
13
14#ifndef PI
15#define PI 3.141593
16#endif
17
18#ifndef treeNBdim
19#define treeNBdim 2 // dimension of boxes in tree
20#endif
21
24#ifndef IndexType_declare
25#define IndexType_declare
26typedef unsigned long IndexType;
27#endif
28
31struct QBranchNB{
32 QBranchNB(QBranchNB *parent):prev(parent){
33 static unsigned long n=0;
34 child0 = NULL;
35 child1 = NULL;
36 child2 = NULL;
37 child3 = NULL;
38 brother = NULL;
39 particles = NULL;
40 nparticles = 0;
41 number = n;
42 ++n;
43 };
44
45 ~QBranchNB(){ };
46
48 IndexType *particles;
49 std::unique_ptr<IndexType[]> big_particles;
50 IndexType nparticles;
52 IndexType Nbig_particles;
54 PosType maxrsph;
56 PosType center[2];
57 PosType mass;
59 int level;
60 unsigned long number;
62 PosType boundary_p1[2];
64 PosType boundary_p2[2];
65 PosType boxsize2;
66
67 QBranchNB *child0;
68 QBranchNB *child1;
69 QBranchNB *child2;
70 QBranchNB *child3;
71
77
78 /* projected quantities */
80 PosType quad[3];
82 PosType rmax;
84 PosType r2crit_angle;
85 /* force calculation */
86 PosType rcrit_part;
87 //PosType cm[2]; /* projected center of mass */
88};
89
97template<typename PType = double*>
98struct QTreeNB{
99 QTreeNB(PType *xp,IndexType *particles,IndexType nparticles
100 ,PosType boundary_p1[],PosType boundary_p2[]);
102
103 const bool isEmpty();
104 const bool atTop();
105 const bool noChild();
106 const bool offEnd();
107 const unsigned long getNbranches();
108 const bool atLeaf(QBranchNB *branch){
109 return (branch->child0 == NULL)*(branch->child1 == NULL)
110 *(branch->child2 == NULL)*(branch->child3 == NULL);
111 }
112
113
114 void getCurrent(IndexType *particles,IndexType *nparticles);
115 void moveTop();
116 void moveUp();
117 void moveToChild(int child);
118 bool WalkStep(bool allowDescent);
119
120 short empty();
121 void attachChildrenToCurrent(QBranchNB *branch0,QBranchNB *branch1
122 ,QBranchNB *branch2,QBranchNB *branch3);
123
124 QBranchNB *top;
125 QBranchNB *current;
127 PType *xxp;
128
129private:
131 unsigned long Nbranches;
132 void _freeQTree(short child);
133};
134
135/************************************************************************
136 * This constructor just creates a root branch. To construct a full tree
137 * an external function must be used. For example, TreeQuad uses QTreeNB
138 ************************************************************************/
139template<typename PType>
140QTreeNB<PType>::QTreeNB(PType *xp,IndexType *particles,IndexType nparticles
141 ,PosType boundary_p1[],PosType boundary_p2[]): xxp(xp) {
142
143 top = new QBranchNB(nullptr);
144
145 top->boundary_p1[0] = boundary_p1[0];
146 top->boundary_p1[1] = boundary_p1[1];
147 top->boundary_p2[0] = boundary_p2[0];
148 top->boundary_p2[1] = boundary_p2[1];
149
150 top->boxsize2 = (boundary_p2[0]-boundary_p1[0])*(boundary_p2[0]-boundary_p1[0]);
151
152 top->nparticles = nparticles;
153 top->level = 0;
154 top->particles = particles;
155
156 top->center[0] = (boundary_p1[0] + boundary_p2[0])/2;
157 top->center[1] = (boundary_p1[1] + boundary_p2[1])/2;
158
159 Nbranches = 1;
160 current = top;
161
162}
163
164
172template<typename PType>
174
175private:
176 QBranchNB *current;
177 QBranchNB *top;
178 size_t nbranches;
179
180public:
182 QBiterator(QTreeNB<PType> * tree){current = top = tree->top; nbranches = tree->getNbranches(); }
184 QBiterator(QBranchNB *branch){current = top = branch;}
185
187 QBranchNB *operator*(){return current;}
188
189 void movetop(){current = top;}
190
192 bool operator++(){ return up();}
193
195 bool operator++(int){ return up();}
196
197 bool up();
199 bool down(short child);
200 const bool atLeaf(){
201 return (current->child0 == NULL)*(current->child1 == NULL)
202 *(current->child2 == NULL)*(current->child3 == NULL);
203 }
204 bool TreeWalkStep(bool allowDescent);
205
206 size_t getNbranches(){return nbranches;}
207};
208
209
210
212template<typename PType>
214 // void TreeQuad::freeQTreeNB(QTreeNBHndl tree){
215
216 empty();
217 delete top;
218 --Nbranches;
219
220 assert(Nbranches ==0);
221 return;
222}
223
224template<typename PType>
226
227 if(Nbranches <= 1) return 1;
228 moveTop();
229 _freeQTree(0);
230
231 assert(Nbranches == 1);
232
233 return 1;
234}
235
236template<typename PType>
237void QTreeNB<PType>::_freeQTree(short child){
238 QBranchNB *branch;
239
240 assert(current);
241 //if(current->particles != current->big_particles
242 // && current->big_particles != NULL) delete[] current->big_particles;
243
244 if(current->child0 != NULL){
245 moveToChild(0);
246 _freeQTree(0);
247 }
248
249 if(current->child1 != NULL){
250 moveToChild(1);
251 _freeQTree(1);
252 }
253
254 if(current->child2 != NULL){
255 moveToChild(2);
256 _freeQTree(2);
257 }
258
259 if(current->child3 != NULL){
260 moveToChild(3);
261 _freeQTree(3);
262 }
263
264 if( atLeaf(current) ){
265
266 if(atTop()) return;
267
268 branch = current;
269 moveUp();
270 delete branch;
271 --Nbranches;
272
273 /*printf("*** removing branch %i number of branches %i\n",branch->number
274 ,Nbranches-1);*/
275
276 if(child==0) current->child0 = NULL;
277 if(child==1) current->child1 = NULL;
278 if(child==2) current->child2 = NULL;
279 if(child==3) current->child3 = NULL;
280
281
282 return;
283 }
284
285 return;
286}
287
288/************************************************************************
289 * isEmpty
290 * Returns "true" if the QTreeNB is empty and "false" otherwise. Exported.
291 ************************************************************************/
292template<typename PType>
293const bool QTreeNB<PType>::isEmpty(){
294
295 return(Nbranches == 0);
296}
297
298/************************************************************************
299 * atTop
300 * Returns "true" if current is the same as top and "false" otherwise.
301 * Exported.
302 * Pre: !isEmptyNB(tree)
303 ************************************************************************/
304template<typename PType>
305const bool QTreeNB<PType>::atTop(){
306
307 if( isEmpty() ){
308 ERROR_MESSAGE();
309 std::cerr << "QTreeNB Error: calling atTop() on empty tree" << std::endl;
310 exit(1);
311 }
312 return(current == top);
313}
314
315/************************************************************************
316 * offEndNB
317 * Returns "true" if current is off end and "false" otherwise. Exported.
318 ************************************************************************/
319template<typename PType>
320const bool QTreeNB<PType>::offEnd(){
321
322 return(current == NULL);
323}
324
325/************************************************************************
326 * getCurrentNB
327 * Returns the particles of current. Exported.
328 * Pre: !offEnd()
329 ************************************************************************/
330template<typename PType>
331void QTreeNB<PType>::getCurrent(IndexType *particles,IndexType *nparticles){
332
333 if( offEnd() ){
334 ERROR_MESSAGE();
335 std::cerr << "QTreeNB Error: calling getCurrent() when current is off end" << std::endl;
336 exit(1);
337 }
338
339 *nparticles = current->nparticles;
340 particles = current->particles;
341
342 return;
343}
344
345/************************************************************************
346 * getNbranches
347 * Returns the NbranchNBes of tree. Exported.
348 ************************************************************************/
349template<typename PType>
350const unsigned long QTreeNB<PType>::getNbranches(){
351
352 return(Nbranches);
353}
354
355/***** Manipulation procedures *****/
356
357/************************************************************************
358 * moveTop
359 * Moves current to the front of tree. Exported.
360 * Pre: !isEmpty(tree)
361 ************************************************************************/
362template<typename PType>
364 //std::cout << tree << std::endl;
365 //std::cout << tree->current << std::endl;
366 //std::cout << tree->top << std::endl;
367
368 if( isEmpty() ){
369 ERROR_MESSAGE();
370 std::cerr << "QTreeNB Error: calling moveTop() on empty tree" << std::endl;
371 exit(1);
372 }
373
374 current = top;
375
376 return;
377}
378
379/************************************************************************
380 * movePrev
381 * Moves current to the branchNB before it in tree. This can move current
382 * off end. Exported.
383 * Pre: !offEndNB(tree)
384 ************************************************************************/
385template<typename PType>
387
388 if( offEnd() ){
389 ERROR_MESSAGE();
390 std::cerr << "QTreeNB Error: call to moveUp() when current is off end" << std::endl;
391 exit(1);
392 }
393 if( current == top ){
394 ERROR_MESSAGE();
395 std::cerr << "QTreeNB Error: call to moveUp() tried to move off the top" << std::endl;
396 exit(1);
397 }
398
399 current = current->prev; /* can move off end */
400 return;
401}
402
403/************************************************************************
404 * moveToChild
405 * Moves current to child branchNB after it in tree. This can move current off
406 * end. Exported.
407 * Pre: !offEnd(tree)
408 ************************************************************************/
409template<typename PType>
410void QTreeNB<PType>::moveToChild(int child){
411
412 if( offEnd() ){
413 ERROR_MESSAGE(); std::cout << "QTreeNB Error: calling moveChildren() when current is off end" << std::endl;
414 exit(1);
415 }
416 if(child==0){
417 if( current->child0 == NULL ){
418 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child1 when it doesn't exist" << std::endl;
419 exit(1);
420 }
421 current = current->child0;
422 }
423 if(child==1){
424 if( current->child1 == NULL ){
425 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child1 when it doesn't exist" << std::endl;
426 exit(1);
427 }
428 current = current->child1;
429 }
430 if(child==2){
431 if( current->child2 == NULL ){
432 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child2 when it doesn't exist" << std::endl;
433 exit(1);
434 }
435 current = current->child2;
436 }
437 if(child==3){
438 if( current->child3 == NULL ){
439 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child2 when it doesn't exist" << std::endl;
440 exit(1);
441 }
442 current = current->child3;
443 }
444 return;
445}
446
447template<typename PType>
449 ,QBranchNB *branch2,QBranchNB *branch3){
450
451 Nbranches += 4;
452 current->child0 = branch0;
453 current->child1 = branch1;
454 current->child2 = branch2;
455 current->child3 = branch3;
456
457 int level = current->level+1;
458 branch0->level = level;
459 branch1->level = level;
460 branch2->level = level;
461 branch3->level = level;
462
463 // work out brothers for children
464 branch0->brother = branch1;
465 branch1->brother = branch2;
466 branch2->brother = branch3;
467 branch3->brother = current->brother;
468
469 branch0->prev = current;
470 branch1->prev = current;
471 branch2->prev = current;
472 branch3->prev = current;
473
474 return;
475}
476
477// step for walking tree by iteration instead of recursion
478template<typename PType>
479bool QTreeNB<PType>::WalkStep(bool allowDescent){
480 if(allowDescent && current->child0 != NULL){
481 moveToChild(0);
482 return true;
483 }
484
485 if(current->brother != NULL){
486 current=current->brother;
487 return true;
488 }
489 return false;
490}
491
492template<typename PType>
494 if( current == top ){
495 return false;
496 }
497 current = current->prev; /* can move off end */
498 return true;
499}
500
502template<typename PType>
503bool QBiterator<PType>::down(short child){
504
505 if(child==0){
506 if( current->child0 == NULL ){
507 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child1 when it doesn't exist" << std::endl;
508 return false;
509 }
510 current = current->child0;
511 return true;
512 }
513 if(child==1){
514 if( current->child1 == NULL ){
515 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child1 when it doesn't exist" << std::endl;
516 return false;
517 }
518 current = current->child1;
519 return true;
520 }
521 if(child==2){
522 if( current->child2 == NULL ){
523 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child2 when it doesn't exist" << std::endl;
524 return false;
525 }
526 current = current->child2;
527 return true;
528 }
529 if(child==3){
530 if( current->child3 == NULL ){
531 ERROR_MESSAGE(); std::cout << "QTreeNB Error: moveToChild() typing to move to child2 when it doesn't exist" << std::endl;
532 return false;
533 }
534 current = current->child3;
535 return true;
536 }
537 return true;
538}
539
540template<typename PType>
541bool QBiterator<PType>::TreeWalkStep(bool allowDescent){
542 if(allowDescent && current->child0 != NULL){
543 down(0);
544 return true;
545 }
546
547 if(current->brother != NULL){
548 current=current->brother;
549 return true;
550 }
551 return false;
552}
553
554#endif /* qTreeNB_h */
A iterator class fore TreeStruct that allows for movement through the tree without changing anything ...
Definition qTreeNB.h:173
QBiterator(QBranchNB *branch)
Sets the root to the input branch so that this will be a subtree in branch is not the real root.
Definition qTreeNB.h:184
QBranchNB * operator*()
Returns a pointer to the current Branch.
Definition qTreeNB.h:187
bool down(short child)
Move to child.
Definition qTreeNB.h:503
QBiterator(QTreeNB< PType > *tree)
Sets the top or root to the top of "tree".
Definition qTreeNB.h:182
bool operator++()
Same as up()
Definition qTreeNB.h:192
bool operator++(int)
Same as up()
Definition qTreeNB.h:195
Box representing a branch in a tree. It has four children. Used in QTreeNB which is used in TreeQuad.
Definition qTreeNB.h:31
PosType maxrsph
Size of largest particle in branch.
Definition qTreeNB.h:54
QBranchNB * brother
Definition qTreeNB.h:76
PosType r2crit_angle
the critical distance below which a branch is opened in the
Definition qTreeNB.h:84
PosType center[2]
center of mass
Definition qTreeNB.h:56
PosType quad[3]
quadropole moment of branch
Definition qTreeNB.h:80
int level
level in tree
Definition qTreeNB.h:59
PosType rmax
largest dimension of box
Definition qTreeNB.h:82
PosType boundary_p1[2]
bottom, left, back corner of box
Definition qTreeNB.h:62
QBranchNB * prev
father of branch
Definition qTreeNB.h:73
IndexType * particles
array of particles in QBranchNB
Definition qTreeNB.h:48
IndexType Nbig_particles
the number of particles that aren't in children
Definition qTreeNB.h:52
PosType boundary_p2[2]
top, right, front corner of box
Definition qTreeNB.h:64
QTreeNB: Tree structure used for force calculation with particles (i.e. stars, Nbody or halos).
Definition qTreeNB.h:98
~QTreeNB()
Free treeNB. Does not free the particle positions, masses or sizes.
Definition qTreeNB.h:213
PType * xxp
Array of particle positions.
Definition qTreeNB.h:127