16 #ifndef QUAD_TREE_HALO_
17 #define QUAD_TREE_HALO_
43 template<
typename PType>
49 ,PosType my_inv_area = 0
51 ,PosType theta_force = 0.1
52 ,PosType my_inv_screening_scale = 0
57 void force2D(PosType
const *ray,PosType *alpha,KappaType *kappa,KappaType *gamma
58 ,KappaType *phi)
const;
63 void printParticlesInBranch(
unsigned long number);
64 void printBranchs(
int level = -1);
78 std::unique_ptr<QTreeNB<PType> > tree;
79 std::vector<IndexType> index;
80 std::vector<PosType> workspace;
87 PosType inv_screening_scale2;
92 void BuildQTreeNB(PType *xp,IndexType Nparticles);
98 inline bool inbox(
const PosType *ray,
const PosType *p1,
const PosType *p2){
99 return (ray[0]>=p1[0])*(ray[0]<=p2[0])*(ray[1]>=p1[1])*(ray[1]<=p2[1]);
107 inline PosType alpha_h(PosType r2s2,PosType sigma)
const{
108 return (sigma > 0.0 ) ? ( exp(-0.5*r2s2) - 1.0 ) : -1.0;
110 inline PosType kappa_h(PosType r2s2,PosType sigma)
const{
111 return 0.5*r2s2*exp(-0.5*r2s2);
113 inline PosType gamma_h(PosType r2s2,PosType sigma)
const{
114 return (sigma > 0.0 ) ? (-2.0 + (2.0 + r2s2)*exp(-0.5*r2s2) ) : -2.0;
116 inline PosType phi_h(PosType r2s2,PosType sigma)
const{
122 void walkTree_iter(
QBiterator<PType> &treeit, PosType
const *ray,PosType *alpha,KappaType *kappa
123 ,KappaType *gamma,KappaType *phi)
const;
128 QBranch(QBranch *parent):prev(parent){
129 static unsigned long n=0;
144 IndexType *particles;
145 std::unique_ptr<IndexType[]> big_particles;
146 IndexType nparticles;
148 IndexType Nbig_particles;
156 unsigned long number;
158 PosType boundary_p1[2];
160 PosType boundary_p2[2];
179 PosType r2crit_angle;
188 template<
typename PType>
195 ,
bool my_periodic_buffer
196 ,PosType my_inv_screening_scale
197 ,PosType maximum_range
201 ,inv_area(my_inv_area)
204 ,force_theta(theta_force)
205 ,max_range(maximum_range)
206 ,periodic_buffer(my_periodic_buffer)
207 ,inv_screening_scale2(my_inv_screening_scale*my_inv_screening_scale)
209 index.resize(Npoints);
211 if(mass_fixed <= 0 ) MultiMass =
true;
else MultiMass =
false;
212 if(size_fixed <= 0 ) MultiRadius =
true;
else MultiRadius =
false;
214 for(ii=0;ii<Npoints;++ii) index[ii] = ii;
217 BuildQTreeNB(xxp,Npoints);
221 phiintconst = (120*log(2.) - 631.)/840 + 19./70;
227 template<
typename PType>
230 if(Nparticles == 0)
return;
234 template<
typename PType>
247 for(i=0;i<Nparticles;++i){
249 if(xxp[i][j] < p1[j] ) p1[j]=xxp[i][j];
250 if(xxp[i][j] > p2[j] ) p2[j]=xxp[i][j];
262 PosType lengths[2] = {p2[0]-p1[0],p2[1]-p1[1]};
263 original_xl = lengths[0];
264 original_yl = lengths[1];
266 if(lengths[0] == 0 || lengths[1] == 0){
267 throw std::invalid_argument(
"particles in same place.");
271 j = lengths[0] > lengths[1] ? 1 : 0;
272 p2[j] = p1[j] + lengths[!j];
275 tree.reset(
new QTreeNB<PType>(xxp,index.data(),Nparticles,p1,p2) );
278 workspace.resize(Nparticles);
279 _BuildQTreeNB(Nparticles,index.data());
281 workspace.shrink_to_fit();
290 template<
typename PType>
292 return (x[0] < branch.center[0]) + 2*(x[1] < branch.center[1]);
296 template<
typename PType>
299 QBranch *cbranch = tree->current;
300 IndexType i,j,cut,cut2;
302 cbranch->center[0] = (cbranch->boundary_p1[0] + cbranch->boundary_p2[0])/2;
303 cbranch->center[1] = (cbranch->boundary_p1[1] + cbranch->boundary_p2[1])/2;
304 cbranch->quad[0] = cbranch->quad[1]=cbranch->quad[2]=0;
307 double theta_range = 2*force_theta;
309 double boxsize = 1.732*(cbranch->boundary_p2[0] - cbranch->boundary_p1[0]);
310 theta_range = boxsize / MAX(sqrt(cbranch->center[0]*cbranch->center[0]
311 + cbranch->center[1]*cbranch->center[1] )
312 - max_range, boxsize );
316 if(cbranch->nparticles <= Nbucket
317 || force_theta > theta_range
320 cbranch->Nbig_particles = 0;
321 PosType boxsize = cbranch->boundary_p2[0]-cbranch->boundary_p1[0];
322 for(i=0;i<cbranch->nparticles;++i){
323 if(xxp[particles[i]*MultiRadius].size() < boxsize) ++cbranch->Nbig_particles;
325 if(cbranch->Nbig_particles){
326 cbranch->big_particles.reset(
new IndexType[cbranch->Nbig_particles]);
328 for(i=0,j=0;i<cbranch->nparticles;++i){
329 if(xxp[particles[i]*MultiRadius].size() < boxsize) cbranch->big_particles[j++] = particles[i];
332 cbranch->big_particles.reset(
nullptr);
341 PosType *x = workspace.data();
343 cbranch->Nbig_particles=0;
347 for(i=0;i<cbranch->nparticles;++i){
348 x[i] = xxp[particles[i]].size();
350 PosType maxsize = (cbranch->boundary_p2[0]-cbranch->boundary_p1[0])/2;
354 Utilities::quickPartition(maxsize,&cut,particles,x,cbranch->nparticles);
356 if(cut < cbranch->nparticles){
358 cbranch->Nbig_particles = cut2 = cbranch->nparticles-cut;
360 Utilities::quickPartition(2*maxsize,&cut2,&particles[cut],&x[cut],cbranch->nparticles-cut);
361 cbranch->Nbig_particles = cut2;
364 cbranch->big_particles.reset(
new IndexType[cbranch->Nbig_particles]);
365 for(i=cut;i<(cut+cut2);++i) cbranch->big_particles[i-cut] = particles[i];
371 if(x[0] > (cbranch->boundary_p2[0]-cbranch->boundary_p1[0])/2
372 && x[0] < (cbranch->boundary_p2[0]-cbranch->boundary_p1[0])){
373 cbranch->Nbig_particles = cbranch->nparticles;
375 cbranch->big_particles.reset(
new IndexType[cbranch->Nbig_particles]);
376 for(i=0;i<cbranch->nparticles;++i) cbranch->big_particles[i] = cbranch->particles[particles[i]];
380 assert( cbranch->nparticles >= cbranch->Nbig_particles );
381 IndexType NpInChildren = cbranch->nparticles;
382 assert(NpInChildren >= 0);
384 if(NpInChildren == 0){
392 QBranch *child0 =
new QBranch(cbranch);
393 QBranch *child1 =
new QBranch(cbranch);
394 QBranch *child2 =
new QBranch(cbranch);
395 QBranch *child3 =
new QBranch(cbranch);
397 tree->attachChildrenToCurrent(child0,child1,child2,child3);
401 child0->boundary_p1[0]=cbranch->center[0];
402 child0->boundary_p1[1]=cbranch->center[1];
403 child0->boundary_p2[0]=cbranch->boundary_p2[0];
404 child0->boundary_p2[1]=cbranch->boundary_p2[1];
406 child1->boundary_p1[0]=cbranch->boundary_p1[0];
407 child1->boundary_p1[1]=cbranch->center[1];
408 child1->boundary_p2[0]=cbranch->center[0];
409 child1->boundary_p2[1]=cbranch->boundary_p2[1];
411 child2->boundary_p1[0]=cbranch->center[0];
412 child2->boundary_p1[1]=cbranch->boundary_p1[1];
413 child2->boundary_p2[0]=cbranch->boundary_p2[0];
414 child2->boundary_p2[1]=cbranch->center[1];
416 child3->boundary_p1[0]=cbranch->boundary_p1[0];
417 child3->boundary_p1[1]=cbranch->boundary_p1[1];
418 child3->boundary_p2[0]=cbranch->center[0];
419 child3->boundary_p2[1]=cbranch->center[1];
424 xcut = cbranch->center[0];
425 ycut = cbranch->center[1];
428 for(i=0;i<NpInChildren;++i) x[i] = tree->xxp[particles[i]][1];
429 Utilities::quickPartition(ycut,&cuty,particles,x,NpInChildren);
433 for(i=0;i<cuty;++i) x[i] = tree->xxp[particles[i]][0];
434 Utilities::quickPartition(xcut,&cutx,particles,x,cuty);
436 child3->nparticles=cutx;
437 assert(child3->nparticles >= 0);
438 if(child3->nparticles > 0)
439 child3->particles = particles;
440 else child3->particles = NULL;
442 child2->nparticles = cuty - cutx;
443 assert(child2->nparticles >= 0);
444 if(child2->nparticles > 0)
445 child2->particles = &particles[cutx];
446 else child2->particles = NULL;
449 child3->nparticles = 0;
450 child3->particles = NULL;
452 child2->nparticles = 0;
453 child2->particles = NULL;
456 if(cuty < NpInChildren){
458 for(i=cuty;i<NpInChildren;++i) x[i-cuty] = tree->xxp[particles[i]][0];
459 Utilities::quickPartition(xcut,&cutx,&particles[cuty],x,NpInChildren-cuty);
461 child1->nparticles=cutx;
462 assert(child1->nparticles >= 0);
463 if(child1->nparticles > 0)
464 child1->particles = &particles[cuty];
465 else child1->particles = NULL;
467 child0->nparticles=NpInChildren - cuty - cutx;
468 assert(child0->nparticles >= 0);
469 if(child0->nparticles > 0)
470 child0->particles = &particles[cuty + cutx];
471 else child0->particles = NULL;
474 child1->nparticles = 0;
475 child1->particles = NULL;
477 child0->nparticles = 0;
478 child0->particles = NULL;
483 tree->moveToChild(0);
484 _BuildQTreeNB(child0->nparticles,child0->particles);
487 tree->moveToChild(1);
488 _BuildQTreeNB(child1->nparticles,child1->particles);
491 tree->moveToChild(2);
492 _BuildQTreeNB(child2->nparticles,child2->particles);
495 tree->moveToChild(3);
496 _BuildQTreeNB(child3->nparticles,child3->particles);
503 template<
typename PType>
508 PosType rcom,xcm[2],xcut;
515 cbranch=tree->current;
517 cbranch->rmax = sqrt( pow(cbranch->boundary_p2[0]-cbranch->boundary_p1[0],2)
518 + pow(cbranch->boundary_p2[1]-cbranch->boundary_p1[1],2) );
521 for(i=0,cbranch->mass=0,absmass=0;i<cbranch->nparticles;++i){
522 cbranch->mass += xxp[cbranch->particles[i]*MultiMass].mass();
523 absmass += fabs(xxp[cbranch->particles[i]*MultiMass].mass());
526 cbranch->center[0]=cbranch->center[1]=0;
527 for(i=0;i<cbranch->nparticles;++i){
528 tmp = fabs(xxp[cbranch->particles[i]*MultiMass].mass());
531 cbranch->center[0] += tmp*tree->xxp[cbranch->particles[i]][0]/absmass;
532 cbranch->center[1] += tmp*tree->xxp[cbranch->particles[i]][1]/absmass;
537 cbranch->quad[0]=cbranch->quad[1]=cbranch->quad[2]=0;
538 for(i=0;i<cbranch->nparticles;++i){
539 xcm[0]=tree->xxp[cbranch->particles[i]][0]-cbranch->center[0];
540 xcm[1]=tree->xxp[cbranch->particles[i]][1]-cbranch->center[1];
541 xcut = pow(xcm[0],2) + pow(xcm[1],2);
542 tmp = xxp[cbranch->particles[i]*MultiMass].mass();
544 cbranch->quad[0] += (xcut-2*xcm[0]*xcm[0])*tmp;
545 cbranch->quad[1] += (xcut-2*xcm[1]*xcm[1])*tmp;
546 cbranch->quad[2] += -2*xcm[0]*xcm[1]*tmp;
550 for(i=0,rcom=0.0;i<2;++i) rcom += ( pow(cbranch->center[i]-cbranch->boundary_p1[i],2) > pow(cbranch->center[i]-cbranch->boundary_p2[i],2) ) ?
551 pow(cbranch->center[i]-cbranch->boundary_p1[i],2) : pow(cbranch->center[i]-cbranch->boundary_p2[i],2);
555 if(force_theta > 0.0){
556 cbranch->r2crit_angle = 1.15470*rcom/(force_theta);
557 cbranch->r2crit_angle *= cbranch->r2crit_angle;
558 }
else cbranch->r2crit_angle=1.0e100;
560 }
while(tree->WalkStep(
true));
566 template<
typename PType>
573 for(i=0;i<tree->top->nparticles;++i){
574 for(j=0;j<3;++j) tmp[j]=0.0;
576 tmp[0]+=coord[0][j]*xxp[i][j];
577 tmp[1]+=coord[1][j]*xxp[i][j];
578 tmp[2]+=coord[2][j]*xxp[i][j];
580 for(j=0;j<3;++j) xxp[i][j]=tmp[j];
607 template<
typename PType>
610 alpha[0]=alpha[1]=gamma[0]=gamma[1]=gamma[2]=0.0;
613 if(Nparticles == 0)
return;
621 for(
int i = -1;i<2;++i){
622 for(
int j = -1;j<2;++j){
623 tmp_ray[0] = ray[0] + i*original_xl;
624 tmp_ray[1] = ray[1] + j*original_yl;
625 walkTree_iter(it,tmp_ray,alpha,kappa,gamma,phi);
629 walkTree_iter(it,ray,alpha,kappa,gamma,phi);
643 template<
typename PType>
648 PosType r2 = rmax*rmax;
652 int cut = Utilities::cutbox(ray,(*it)->boundary_p1,(*it)->boundary_p2,rmax);
658 for(
int i=0;i<(*it)->nparticles;++i) neighbors.push_back((*it)->particles[i]);
660 }
else if((*it)->child0 == NULL){
661 for(
int i=0;i<(*it)->nparticles;++i){
662 if( (tree->xxp[(*it)->particles[i]][0] - ray[0])*(tree->xxp[(*it)->particles[i]][0] - ray[0])
663 + (tree->xxp[(*it)->particles[i]][1] - ray[1])*(tree->xxp[(*it)->particles[i]][1] - ray[1]) < r2) neighbors.push_back((*it)->particles[i]);
667 }
while(it.TreeWalkStep(decend));
671 template<
typename PType>
681 PosType xcm[2],rcm2cell,rcm2,tmp,boxarea;
683 bool allowDescent=
true;
684 unsigned long count=0,tmp_index;
703 if((*treeit)->nparticles > 0)
706 xcm[0]=(*treeit)->center[0]-ray[0];
707 xcm[1]=(*treeit)->center[1]-ray[1];
709 rcm2cell = xcm[0]*xcm[0] + xcm[1]*xcm[1];
711 boxarea = ((*treeit)->boundary_p2[0]-(*treeit)->boundary_p1[0])*((*treeit)->boundary_p2[0]-(*treeit)->boundary_p1[0]);
713 if( rcm2cell < ((*treeit)->rcrit_angle)*((*treeit)->rcrit_angle) || rcm2cell < 5.83*boxarea)
724 for(i = 0 ; i < (*treeit)->nparticles ; ++i)
727 xcm[0] = tree->xp[(*treeit)->particles[i]][0] - ray[0];
728 xcm[1] = tree->xp[(*treeit)->particles[i]][1] - ray[1];
730 rcm2 = xcm[0]*xcm[0] + xcm[1]*xcm[1];
731 double screening = exp(-rcm2*inv_screening_scale2);
732 if(rcm2 < 1e-20) rcm2 = 1e-20;
740 if(MultiMass) mass = xxp[(*treeit)->particles[i]].Mass();
741 else mass = mass_fixed;
743 prefac = mass/rcm2/PI*screening;
744 tmp = -mass*( screening/rcm2/PI - inv_area);
746 alpha[0] += tmp*xcm[0];
747 alpha[1] += tmp*xcm[1];
749 tmp = -2.0*prefac/rcm2;
751 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
752 gamma[1] += xcm[0]*xcm[1]*tmp;
754 *kappa -= mass*inv_area;
755 *phi += (prefac*log(rcm2) - mass*inv_area)*rcm2*0.5;
762 if(rcm2cell < 5.83*boxarea)
765 for(i = 0 ; i < (*treeit)->Nbig_particles ; ++i)
768 tmp_index = (*treeit)->big_particles[i];
770 xcm[0] = tree->xp[tmp_index][0] - ray[0];
771 xcm[1] = tree->xp[tmp_index][1] - ray[1];
773 rcm2 = xcm[0]*xcm[0] + xcm[1]*xcm[1];
775 if(rcm2 < 1e-20) rcm2 = 1e-20;
778 PosType size = xxp[tmp_index*MultiRadius].size();
781 if(rcm2 < 4*size*size)
783 b_spline_profile(xcm,sqrt(rcm2),xxp[MultiMass*tmp_index].Mass(),size,alpha,kappa,gamma,phi);
796 double screening = exp(-rcm2cell*inv_screening_scale2);
798 double tmp = (*treeit)->mass*( inv_area - screening/rcm2cell/PI );
800 alpha[0] += tmp*xcm[0];
801 alpha[1] += tmp*xcm[1];
804 tmp=-2.0*(*treeit)->mass/PI/rcm2cell/rcm2cell*screening;
805 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
806 gamma[1] += xcm[0]*xcm[1]*tmp;
808 *phi += 0.5*(*treeit)->mass*log( rcm2cell )/PI*screening;
809 *phi -= 0.5*( (*treeit)->quad[0]*xcm[0]*xcm[0] + (*treeit)->quad[1]*xcm[1]*xcm[1] + 2*(*treeit)->quad[2]*xcm[0]*xcm[1] )/(PI*rcm2cell*rcm2cell)*screening;
814 alpha[0] -= ((*treeit)->quad[0]*xcm[0] + (*treeit)->quad[2]*xcm[1])
815 /(rcm2cell*rcm2cell)/PI*screening;
816 alpha[1] -= ((*treeit)->quad[1]*xcm[1] + (*treeit)->quad[2]*xcm[0])
817 /(rcm2cell*rcm2cell)/PI*screening;
819 tmp = 4*((*treeit)->quad[0]*xcm[0]*xcm[0] + (*treeit)->quad[1]*xcm[1]*xcm[1]
820 + 2*(*treeit)->quad[2]*xcm[0]*xcm[1])/(rcm2cell*rcm2cell*rcm2cell)/PI*screening;
822 alpha[0] += tmp*xcm[0];
823 alpha[1] += tmp*xcm[1];
825 *kappa -= (*treeit)->mass * inv_area;
826 *phi -= 0.5*(*treeit)->mass*inv_area;
829 }
while(treeit.TreeWalkStep(allowDescent));
869 template<
typename PType>
873 alpha[0]=alpha[1]=gamma[0]=gamma[1]=gamma[2]=0.0;
876 if(Nparticles == 0)
return;
882 PosType tmp_ray[2],tmp_c[2];
905 for(
int i = -1;i<2;++i){
906 for(
int j = -1;j<2;++j){
907 tmp_ray[0] = tmp_c[0] + i*original_xl;
908 tmp_ray[1] = tmp_c[1] + j*original_yl;
909 walkTree_recur(tree->top,tmp_ray,alpha,kappa,gamma,phi);
913 walkTree_recur(tree->top,ray,alpha,kappa,gamma,phi);
927 template<
typename PType>
930 PosType xcm[2],rcm2cell,rcm2,tmp,boxsize2;
932 std::size_t tmp_index;
938 if(branch->nparticles > 0)
940 xcm[0]=branch->center[0]-ray[0];
941 xcm[1]=branch->center[1]-ray[1];
943 rcm2cell = xcm[0]*xcm[0] + xcm[1]*xcm[1];
945 boxsize2 = (branch->boundary_p2[0]-branch->boundary_p1[0])*(branch->boundary_p2[0]-branch->boundary_p1[0]);
947 if( rcm2cell < branch->r2crit_angle || rcm2cell < 5.83*boxsize2)
951 if(tree->atLeaf(branch))
954 for(i = 0 ; i < branch->nparticles ; ++i){
956 xcm[0] = tree->xxp[branch->particles[i]][0] - ray[0];
957 xcm[1] = tree->xxp[branch->particles[i]][1] - ray[1];
959 rcm2 = xcm[0]*xcm[0] + xcm[1]*xcm[1];
960 double screening = exp(-rcm2*inv_screening_scale2);
961 if(rcm2 < 1e-20) rcm2 = 1e-20;
963 tmp_index = MultiMass*branch->particles[i];
967 double mass = xxp[tmp_index].mass();
968 prefac = mass*screening/rcm2/PI;
972 alpha[0] += (inv_area*mass - prefac)*xcm[0];
973 alpha[1] += (inv_area*mass - prefac)*xcm[1];
976 tmp = -2.0*prefac/rcm2;
978 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
979 gamma[1] += xcm[0]*xcm[1]*tmp;
981 *kappa -= mass*inv_area;
982 *phi += prefac*rcm2*0.5*log(rcm2) - mass*inv_area*rcm2/2;
988 if(rcm2cell < 5.83*boxsize2)
991 for(i = 0 ; i < branch->Nbig_particles ; ++i)
994 tmp_index = branch->big_particles[i];
996 xcm[0] = tree->xxp[tmp_index][0] - ray[0];
997 xcm[1] = tree->xxp[tmp_index][1] - ray[1];
998 rcm2 = xcm[0]*xcm[0] + xcm[1]*xcm[1];
1001 if(rcm2 < 1e-20) rcm2 = 1e-20;
1003 PosType size = xxp[tmp_index*MultiRadius].size();
1006 if(rcm2 < 4*size*size)
1009 b_spline_profile(xcm,sqrt(rcm2),xxp[MultiMass*tmp_index].mass(),size,alpha,kappa,gamma,phi);
1016 if(branch->child0 != NULL)
1017 walkTree_recur(branch->child0,&ray[0],&alpha[0],kappa,&gamma[0],&phi[0]);
1018 if(branch->child1 != NULL)
1019 walkTree_recur(branch->child1,&ray[0],&alpha[0],kappa,&gamma[0],&phi[0]);
1020 if(branch->child2 != NULL)
1021 walkTree_recur(branch->child2,&ray[0],&alpha[0],kappa,&gamma[0],&phi[0]);
1022 if(branch->child3 != NULL)
1023 walkTree_recur(branch->child3,&ray[0],&alpha[0],kappa,&gamma[0],&phi[0]);
1029 double screening = exp(-rcm2cell*inv_screening_scale2);
1030 double tmp = branch->mass*inv_area - branch->mass/rcm2cell/PI*screening;
1032 alpha[0] += tmp*xcm[0];
1033 alpha[1] += tmp*xcm[1];
1036 tmp=-2.0*branch->mass/PI/rcm2cell/rcm2cell*screening;
1037 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
1038 gamma[1] += xcm[0]*xcm[1]*tmp;
1040 *phi += 0.5*tree->current->mass*log( rcm2cell )/PI*screening;
1041 *phi -= 0.5*( tree->current->quad[0]*xcm[0]*xcm[0] + tree->current->quad[1]*xcm[1]*xcm[1] + 2*tree->current->quad[2]*xcm[0]*xcm[1] )/(PI*rcm2cell*rcm2cell)*screening;
1046 alpha[0] -= (branch->quad[0]*xcm[0] + branch->quad[2]*xcm[1])
1047 /(rcm2cell*rcm2cell)/PI*screening;
1048 alpha[1] -= (branch->quad[1]*xcm[1] + branch->quad[2]*xcm[0])
1049 /(rcm2cell*rcm2cell)/PI*screening;
1051 tmp = 4*(branch->quad[0]*xcm[0]*xcm[0] + branch->quad[1]*xcm[1]*xcm[1]
1052 + 2*branch->quad[2]*xcm[0]*xcm[1])/(rcm2cell*rcm2cell*rcm2cell)/PI*screening;
1054 alpha[0] += tmp*xcm[0];
1055 alpha[1] += tmp*xcm[1];
1057 *kappa -= inv_area * branch->mass;
1058 *phi -= 0.5*branch->mass*rcm2cell*inv_area;
1070 template<
typename PType>
1076 if(tree->current->number == number){
1077 std::cout << tree->current->nparticles << std::endl;
1078 for(i=0;i<tree->current->nparticles;++i){
1079 std::cout << xxp[tree->current->particles[i]][0] <<
" "
1080 << xxp[tree->current->particles[i]][1] << std::endl;
1084 }
while(tree->WalkStep(
true));
1092 template<
typename PType>
1098 std::cout << tree->current->boundary_p1[0] <<
" " << tree->current->boundary_p1[1] <<
" "
1099 << tree->current->boundary_p2[0] <<
" " << tree->current->boundary_p2[1] << std::endl;
1100 if(tree->current->level == level) decend =
false;
1102 }
while(tree->WalkStep(decend));