12 #include "utilities.h"
22 #ifndef IndexType_declare
23 #define IndexType_declare
24 typedef unsigned long IndexType;
40 template <
typename PType = Po
int_3d<PosType>,
typename DType = PosType >
58 root_inv_density = 0.0;
75 if(children !=
nullptr)
delete[] children;
90 PosType root_inv_density;
96 Branch *children =
nullptr;
107 PosType xcm[3] = {0.0, 0.0, 0.0};
109 PosType quad[3] = {0.0, 0.0, 0.0};
131 current = it.current;
146 if (current->
prev ==
nullptr)
151 current = current->
prev;
158 assert(child >= 0 && child < 8);
159 current = current->child;
164 if (current->
prev ==
nullptr)
171 for (
int i = 0; i < 8; ++i)
173 if (current->child !=
nullptr)
188 if (current ==
nullptr)
192 if (allowDescent && current->child !=
nullptr){
193 current = current->child;
202 current = end.current;
209 OTreeNB(PType *xp,IndexType nparticles):
212 index.resize(nparticles);
213 for(
unsigned long i=0;i<nparticles;++i) index[i] = i;
217 top.nparticles = nparticles;
224 for(IndexType i = 1 ; i < nparticles ; ++i)
226 for(
int j=0;j<3;++j){
238 PosType max_length = length[0];
240 for(
int j=1;j<3;++j){
241 if(length[j] > max_length){
242 max_length = length[j];
246 for(
int j=0;j<3;++j){
253 top.boxsize = max_length;
254 top.root_inv_density = max_length/pow(top.nparticles,1.0/3.);
260 unsigned long size() {
return Nbranches; };
263 void build(
int Nbucket){
265 if((*it)->child !=
nullptr){
266 throw std::runtime_error(
"OTreeNB Error: calling build() on already built tree");
270 while(it.walk(
true,begin())){
277 if((*it)->nparticles > Nbucket) span8(*it);
283 void build_size(
int Nbucket){
285 if((*it)->child !=
nullptr){
286 throw std::runtime_error(
"OTreeNB Error: calling build() on already built tree");
289 while(it.walk(
true,begin())){
292 double max_size = 0.0;
293 for(IndexType i=0;i<(*it)->nparticles;++i){
294 max_size = max(max_size, xxp[(*it)->particles[i]].size);
300 if((*it)->nparticles > Nbucket && max_size < (*it)->boxsize ) span8(*it);
307 while(it.walk(
true,begin())){
311 branch->xcm[0] = 0.0;
312 branch->xcm[1] = 0.0;
313 branch->xcm[2] = 0.0;
314 if(branch->nparticles == 0){
318 for(IndexType i=0;i<branch->nparticles;++i){
319 PType &x = xxp[branch->particles[i]];
320 branch->xcm[0] += x[0];
321 branch->xcm[1] += x[1];
322 branch->xcm[2] += x[2];
324 branch->xcm[0] /= branch->nparticles;
325 branch->xcm[1] /= branch->nparticles;
326 branch->xcm[2] /= branch->nparticles;
327 branch->mass = branch->nparticles;
350 while(it.walk(
true,begin())){
353 if(branch->nparticles == 0)
continue;
356 branch->xcm[0] = 0.0;
357 branch->xcm[1] = 0.0;
358 branch->xcm[2] = 0.0;
361 for(IndexType i=0;i<branch->nparticles;++i){
362 IndexType j = branch->particles[i];
364 double m = masses[j];
365 branch->xcm[0] += x[0]*m;
366 branch->xcm[1] += x[1]*m;
367 branch->xcm[2] += x[2]*m;
370 branch->xcm[0] /= branch->mass;
371 branch->xcm[1] /= branch->mass;
372 branch->xcm[2] /= branch->mass;
392 template<
typename HType>
396 while(it.walk(
true,begin())){
399 if(branch->nparticles == 0)
continue;
402 branch->xcm[0] = 0.0;
403 branch->xcm[1] = 0.0;
404 branch->xcm[2] = 0.0;
407 for(IndexType i=0;i<branch->nparticles;++i){
408 IndexType j = branch->particles[i];
410 double m = halos[j].get_mass();
412 branch->xcm[0] += x[0]*m;
413 branch->xcm[1] += x[1]*m;
414 branch->xcm[2] += x[2]*m;
417 branch->xcm[0] /= branch->mass;
418 branch->xcm[1] /= branch->mass;
419 branch->xcm[2] /= branch->mass;
440 void force2D(
const PosType *ray
441 ,PosType particle_mass
442 ,PosType smooth_factor
454 PosType inv_area_pi = inv_area*PI;
458 while(it.walk(decend,begin())){
460 xcm[0] = (*it)->xcm[0] - ray[0];
461 xcm[1] = (*it)->xcm[1] - ray[1];
462 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
464 if( r2cm*theta2 > ((*it)->boxsize)*((*it)->boxsize) ){
466 if(r2cm*inv_area_pi < 1){
468 double mass = (*it)->mass * particle_mass;
469 double prefac = mass/r2cm/PI;
470 double tmp = -( prefac - mass*inv_area);
472 alpha[0] -= tmp*xcm[0];
473 alpha[1] -= tmp*xcm[1];
475 tmp = -2.0*prefac/r2cm;
477 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
478 gamma[1] += xcm[0]*xcm[1]*tmp;
480 *kappa -= mass*inv_area;
481 *phi += (prefac*log(r2cm) - mass*inv_area)*r2cm*0.5;
486 if((*it)->child ==
nullptr){
488 for(IndexType i=0;i<(*it)->nparticles;++i){
490 PType &x = xxp[(*it)->particles[i]];
491 xcm[0] = x[0] - ray[0];
492 xcm[1] = x[1] - ray[1];
493 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
494 if(r2cm*inv_area_pi < 1){
495 double prefac = particle_mass /r2cm/PI;
496 double tmp = -( prefac - particle_mass*inv_area);
498 alpha[0] -= tmp*xcm[0];
499 alpha[1] -= tmp*xcm[1];
501 tmp = -2.0*prefac/r2cm;
503 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
504 gamma[1] += xcm[0]*xcm[1]*tmp;
506 *kappa -= particle_mass*inv_area;
507 *phi += (prefac*log(r2cm)- particle_mass*inv_area)*r2cm*0.5;
509 double scale = smooth_factor*(*it)->root_inv_density;
510 if(r2cm < 4*scale*scale){
517 ,alpha,kappa,gamma,phi
531 void force2D(
const PosType *ray
533 ,PosType smooth_factor
542 assert( moments_set );
545 PosType inv_area_pi = inv_area*PI;
549 while(it.walk(decend,begin())){
551 xcm[0] = (*it)->xcm[0] - ray[0];
552 xcm[1] = (*it)->xcm[1] - ray[1];
553 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
555 if( r2cm*theta2 > ((*it)->boxsize)*((*it)->boxsize) ){
557 if(r2cm*inv_area_pi < 1){
559 DType mass = (*it)->mass;
560 double prefac = mass/r2cm/PI;
561 double tmp = -( prefac - mass*inv_area);
563 alpha[0] -= tmp*xcm[0];
564 alpha[1] -= tmp*xcm[1];
566 tmp = -2.0*prefac/r2cm;
568 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
569 gamma[1] += xcm[0]*xcm[1]*tmp;
571 *kappa -= mass*inv_area;
572 *phi += (prefac*log(r2cm) - mass*inv_area)*r2cm*0.5;
577 if((*it)->child ==
nullptr){
579 for(IndexType i=0;i<(*it)->nparticles;++i){
580 IndexType j = (*it)->particles[i];
582 DType mass = masses[j];
584 xcm[0] = x[0] - ray[0];
585 xcm[1] = x[1] - ray[1];
586 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
587 if(r2cm*inv_area_pi < 1){
588 double prefac = mass /r2cm/PI;
589 double tmp = -( prefac - mass * inv_area);
591 alpha[0] -= tmp*xcm[0];
592 alpha[1] -= tmp*xcm[1];
594 tmp = -2.0*prefac/r2cm;
596 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
597 gamma[1] += xcm[0]*xcm[1]*tmp;
599 *kappa -= mass * inv_area;
600 *phi += (prefac*log(r2cm)- mass * inv_area)*r2cm*0.5;
602 double scale = smooth_factor*(*it)->root_inv_density;
603 if(r2cm < 4*scale*scale){
610 ,alpha,kappa,gamma,phi
625 void force2D_hole(
const PosType *ray
626 ,PosType particle_mass
627 ,PosType smooth_factor
640 PosType inv_area_pi = inv_area*PI;
641 PosType xcm[2],r2cm,dx[2];
645 while(it.walk(decend,begin())){
647 dx[0] = (*it)->center[0] - xo[0];
648 dx[1] = (*it)->center[1] - xo[1];
649 PosType d = sqrt(dx[0]*dx[0] + dx[1]*dx[1]);
651 if(d < rmin - (*it)->boxsize) {
657 xcm[0] = (*it)->xcm[0] - ray[0];
658 xcm[1] = (*it)->xcm[1] - ray[1];
659 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
661 if(d > rmin + (*it)->boxsize){
662 if( r2cm*theta2 > ((*it)->boxsize)*((*it)->boxsize) ){
664 if(r2cm*inv_area_pi < 1){
666 double mass = (*it)->nparticles * particle_mass;
667 double prefac = mass/r2cm/PI;
668 double tmp = ( prefac - mass*inv_area);
670 alpha[0] += tmp*xcm[0];
671 alpha[1] += tmp*xcm[1];
673 tmp = -2.0*prefac/r2cm;
675 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
676 gamma[1] += xcm[0]*xcm[1]*tmp;
678 *kappa -= mass*inv_area;
679 *phi += (prefac*log(r2cm) - mass*inv_area)*r2cm*0.5;
684 if((*it)->child ==
nullptr){
686 for(IndexType i=0;i<(*it)->nparticles;++i){
688 PType &x = xxp[(*it)->particles[i]];
689 xcm[0] = x[0] - ray[0];
690 xcm[1] = x[1] - ray[1];
691 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
692 if(r2cm*inv_area_pi < 1){
693 double prefac = particle_mass /r2cm/PI;
694 double tmp = -( prefac - particle_mass*inv_area);
696 alpha[0] -= tmp*xcm[0];
697 alpha[1] -= tmp*xcm[1];
699 tmp = -2.0*prefac/r2cm;
701 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
702 gamma[1] += xcm[0]*xcm[1]*tmp;
704 *kappa -= particle_mass*inv_area;
705 *phi += (prefac*log(r2cm)- particle_mass*inv_area)*r2cm*0.5;
707 double scale = smooth_factor*(*it)->root_inv_density;
708 if(r2cm < 4*scale*scale){
715 ,alpha,kappa,gamma,phi
728 if((*it)->child ==
nullptr){
730 for(IndexType i=0;i<(*it)->nparticles;++i){
732 PType &x = xxp[(*it)->particles[i]];
733 xcm[0] = x[0] - ray[0];
734 xcm[1] = x[1] - ray[1];
735 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
737 dx[0] = x[0] - xo[0];
738 dx[1] = x[1] - xo[1];
740 if( dx[0]*dx[0] + dx[1]*dx[1] > rmin*rmin &&
741 r2cm*inv_area_pi < 1){
742 double prefac = particle_mass /r2cm/PI;
743 double tmp = -( prefac - particle_mass*inv_area);
745 alpha[0] -= tmp*xcm[0];
746 alpha[1] -= tmp*xcm[1];
748 tmp = -2.0*prefac/r2cm;
750 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
751 gamma[1] += xcm[0]*xcm[1]*tmp;
753 *kappa -= particle_mass*inv_area;
754 *phi += (prefac*log(r2cm)- particle_mass*inv_area)*r2cm*0.5;
756 double scale = smooth_factor*(*it)->root_inv_density;
757 if(r2cm < 4*scale*scale){
764 ,alpha,kappa,gamma,phi
781 ,PosType smooth_factor
792 assert( moments_set );
796 PosType inv_area_pi = inv_area*PI;
797 PosType xcm[2],r2cm,dx[2];
801 while(it.walk(decend,begin())){
803 dx[0] = (*it)->center[0] - xo[0];
804 dx[1] = (*it)->center[1] - xo[1];
805 PosType d = sqrt(dx[0]*dx[0] + dx[1]*dx[1]);
807 if(d < rmin - (*it)->boxsize) {
813 xcm[0] = (*it)->xcm[0] - ray[0];
814 xcm[1] = (*it)->xcm[1] - ray[1];
815 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
817 if(d > rmin + (*it)->boxsize){
818 if( r2cm*theta2 > ((*it)->boxsize)*((*it)->boxsize) ){
820 if(r2cm*inv_area_pi < 1){
822 DType mass = (*it)->mass;
823 double prefac = mass/r2cm/PI;
824 double tmp = -( prefac - mass*inv_area);
826 alpha[0] -= tmp*xcm[0];
827 alpha[1] -= tmp*xcm[1];
829 tmp = -2.0*prefac/r2cm;
831 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
832 gamma[1] += xcm[0]*xcm[1]*tmp;
834 *kappa -= mass*inv_area;
835 *phi += (prefac*log(r2cm) - mass*inv_area)*r2cm*0.5;
840 if((*it)->child ==
nullptr){
842 for(IndexType i=0;i<(*it)->nparticles;++i){
843 IndexType j = (*it)->particles[i];
845 xcm[0] = x[0] - ray[0];
846 xcm[1] = x[1] - ray[1];
847 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
848 if(r2cm*inv_area_pi < 1){
849 DType mass = masses[j];
850 double prefac = mass /r2cm/PI;
851 double tmp = -( prefac - mass * inv_area);
853 alpha[0] -= tmp*xcm[0];
854 alpha[1] -= tmp*xcm[1];
856 tmp = -2.0*prefac/r2cm;
858 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
859 gamma[1] += xcm[0]*xcm[1]*tmp;
861 *kappa -= mass * inv_area;
862 *phi += (prefac*log(r2cm) - mass * inv_area)*r2cm*0.5;
864 double scale = smooth_factor*(*it)->root_inv_density;
865 if(r2cm < 4*scale*scale){
872 ,alpha,kappa,gamma,phi
885 if((*it)->child ==
nullptr){
887 for(IndexType i=0;i<(*it)->nparticles;++i){
888 IndexType j = (*it)->particles[i];
890 xcm[0] = x[0] - ray[0];
891 xcm[1] = x[1] - ray[1];
892 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
894 dx[0] = x[0] - xo[0];
895 dx[1] = x[1] - xo[1];
897 if( dx[0]*dx[0] + dx[1]*dx[1] > rmin*rmin &&
898 r2cm*inv_area_pi < 1){
899 DType mass = masses[j];
900 double prefac = mass /r2cm/PI;
901 double tmp = -( prefac - mass * inv_area);
903 alpha[0] -= tmp*xcm[0];
904 alpha[1] -= tmp*xcm[1];
906 tmp = -2.0*prefac/r2cm;
908 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
909 gamma[1] += xcm[0]*xcm[1]*tmp;
911 *kappa -= mass * inv_area;
912 *phi += (prefac*log(r2cm)- mass * inv_area)*r2cm*0.5;
914 double scale = smooth_factor*(*it)->root_inv_density;
915 if(r2cm < 4*scale*scale){
922 ,alpha,kappa,gamma,phi
936 template<
typename HType>
951 assert( moments_set );
954 PosType inv_area_pi = inv_area*PI;
955 PosType xcm[2],r2cm,dx[2], tmp_v[2];
959 while(it.walk(decend,begin())){
961 assert( (*it)->nparticles > 0 );
963 dx[0] = (*it)->center[0] - xo[0];
964 dx[1] = (*it)->center[1] - xo[1];
965 PosType d = sqrt(dx[0]*dx[0] + dx[1]*dx[1]);
967 if(d < rmin - (*it)->boxsize) {
969 for(IndexType i=0;i<(*it)->nparticles;++i){
970 IndexType j = (*it)->particles[i];
972 xcm[0] = x[0] - ray[0];
973 xcm[1] = x[1] - ray[1];
974 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
975 if(r2cm*inv_area_pi < 1){
977 DType mass = halos[j].get_mass();
978 double prefac = mass /r2cm/PI;
979 double tmp = - mass * inv_area;
981 alpha[0] += tmp*xcm[0];
982 alpha[1] += tmp*xcm[1];
984 *kappa -= mass * inv_area;
985 *phi += - mass * inv_area*r2cm*0.5;
1004 halos[j].force_halo(tmp_v,kappa,gamma,phi,xcm);
1005 alpha[0] -= tmp_v[0];
1006 alpha[1] -= tmp_v[1];
1012 xcm[0] = (*it)->xcm[0] - ray[0];
1013 xcm[1] = (*it)->xcm[1] - ray[1];
1014 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
1016 if(d > rmin + (*it)->boxsize){
1018 if( r2cm*theta2 > ((*it)->boxsize)*((*it)->boxsize) ){
1020 if(r2cm*inv_area_pi < 1){
1022 DType mass = (*it)->mass;
1023 double prefac = mass/r2cm/PI;
1024 double tmp = ( prefac - mass*inv_area);
1026 alpha[0] += tmp*xcm[0];
1027 alpha[1] += tmp*xcm[1];
1029 tmp = -2.0*prefac/r2cm;
1031 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
1032 gamma[1] += xcm[0]*xcm[1]*tmp;
1034 *kappa -= mass*inv_area;
1035 *phi += (prefac*log(r2cm) - mass*inv_area)*r2cm*0.5;
1040 if((*it)->child ==
nullptr){
1042 for(IndexType i=0;i<(*it)->nparticles;++i){
1043 IndexType j = (*it)->particles[i];
1045 xcm[0] = x[0] - ray[0];
1046 xcm[1] = x[1] - ray[1];
1047 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
1049 if(r2cm*inv_area_pi < 1){
1050 DType mass = halos[j].get_mass();
1051 double prefac = mass /r2cm/PI;
1052 double tmp = ( prefac - mass * inv_area);
1054 alpha[0] += tmp*xcm[0];
1055 alpha[1] += tmp*xcm[1];
1057 tmp = -2.0*prefac/r2cm;
1059 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
1060 gamma[1] += xcm[0]*xcm[1]*tmp;
1062 *kappa -= mass * inv_area;
1063 *phi += (prefac*log(r2cm) - mass * inv_area)*r2cm*0.5;
1076 if((*it)->child ==
nullptr){
1078 for(IndexType i=0 ; i<(*it)->nparticles ; ++i){
1079 IndexType j = (*it)->particles[i];
1081 xcm[0] = x[0] - ray[0];
1082 xcm[1] = x[1] - ray[1];
1083 r2cm = xcm[0]*xcm[0] + xcm[1]*xcm[1];
1084 if(r2cm*inv_area_pi < 1){
1086 dx[0] = x[0] - xo[0];
1087 dx[1] = x[1] - xo[1];
1089 if( dx[0]*dx[0] + dx[1]*dx[1] < rmin*rmin){
1090 DType mass = halos[j].get_mass();
1091 double prefac = mass /r2cm/PI;
1092 double tmp = - mass * inv_area;
1094 alpha[0] += tmp*xcm[0];
1095 alpha[1] += tmp*xcm[1];
1097 *kappa -= mass * inv_area;
1098 *phi += - mass * inv_area*r2cm*0.5;
1102 halos[j].force_halo(tmp_v,kappa,gamma,phi,xcm);
1103 alpha[0] -= tmp_v[0];
1104 alpha[1] -= tmp_v[1];
1109 DType mass = halos[j].get_mass();
1110 double prefac = mass/r2cm/PI;
1111 double tmp = ( prefac - mass*inv_area);
1113 alpha[0] += tmp*xcm[0];
1114 alpha[1] += tmp*xcm[1];
1116 tmp = -2.0*prefac/r2cm;
1118 gamma[0] += 0.5*(xcm[0]*xcm[0]-xcm[1]*xcm[1])*tmp;
1119 gamma[1] += xcm[0]*xcm[1]*tmp;
1121 *kappa -= mass*inv_area;
1122 *phi += (prefac*log(r2cm) - mass*inv_area)*r2cm*0.5;
1139 size_t getUsedBranches() {
return Nbranches; }
1140 size_t getTotalBranches() {
return total_branches; }
1144 return iterator(&top);
1148 int getDepth()
const
1162 void span8(
Branch *current);
1167 std::vector<unsigned long> index;
1170 unsigned long Nbranches;
1171 unsigned long total_branches = 1;
1173 bool moments_set =
false;
1175 PosType phiintconst = (120*log(2.) - 631.)/840 + 19./70;
1181 inline void b_spline_profile(
1199 PosType q2=q*q,q3=q2*q,q4=q2*q2,q5=q4*q;
1201 sigma = (8 - 12*q + 6*q2 - q3)/4;
1203 sigma *= 10/size/size/7/PI;
1204 M = (-1 + 20*q2*(1 - q + 3*q2/8 - q3/20) )/7;
1205 *phi += Mass*(-1232. + 1200*q2 - 800.*q3 + 225.*q4 - 24*q5 + 120*log(2./q) )/840/PI;
1207 sigma = 10*( sigma - 1 + 3*q - 3*q2 + q3)/size/size/7/PI;
1208 M = 10*q2*(1 - 3*q/4 + 3*q3/10)/7;
1210 *phi += Mass*( phiintconst + 10*(q2/2 - 3*q4/4 + 3*q5/50)/7
1216 alpha_r = (M-1)/PI/r;
1217 gt = alpha_r/r - sigma;
1219 alpha[0] += Mass*alpha_r*xcm[0]/r;
1220 alpha[1] += Mass*alpha_r*xcm[1]/r;
1221 gamma[0] -= gt*Mass*(xcm[0]*xcm[0]-xcm[1]*xcm[1])/r/r;
1222 gamma[1] -= gt*Mass*2*xcm[0]*xcm[1]/r/r;
1223 *kappa += Mass*sigma;
1224 *phi -= Mass*log(r)/PI;
1231 template <
typename PType,
typename DType>
1234 if (current ==
nullptr)
1237 std::cerr <<
"OTreeNB Error: calling spon() on empty tree" << std::endl;
1241 current->children =
new Branch[8];
1242 Branch *children = current->children;
1244 for(
int i=0; i<8; ++i)
1246 children[i].prev = current;
1247 children[i].level = current->level + 1;
1249 total_branches += 8;
1250 if(depth < current->level + 1) depth = current->level + 1;
1252 PType ¢er = current->center;
1256 PosType boxsize = current->boxsize / 2.0;
1259 for (
int i = -1; i < 2; i += 2)
1261 for (
int j = -1; j < 2; j += 2)
1263 for (
int k = -1; k < 2; k += 2)
1266 children[m].boundary_p1[0] = ((1 - i) / 2) * current->boundary_p1[0]
1267 + ((1 + i) / 2) * center[0];
1268 children[m].boundary_p1[1] = ((1 - j) / 2) * current->boundary_p1[1]
1269 + ((1 + j) / 2) * center[1];
1270 children[m].boundary_p1[2] = ((1 - k) / 2) * current->boundary_p1[2]
1271 + ((1 + k) / 2) * center[2];
1273 children[m].boundary_p2[0] = ((1 + i) / 2) * current->boundary_p2[0]
1274 + ((1 - i) / 2) * center[0];
1275 children[m].boundary_p2[1] = ((1 + j) / 2) * current->boundary_p2[1]
1276 + ((1 - j) / 2) * center[1];
1277 children[m].boundary_p2[2] = ((1 + k) / 2) * current->boundary_p2[2]
1278 + ((1 - k) / 2) * center[2];
1280 children[m].center = (children[m].boundary_p1 + children[m].boundary_p2) * 0.5;
1282 children[m].boxsize = boxsize;
1289 IndexType *p = current->particles;
1291 IndexType *p_end = p + current->nparticles;
1293 for (
int m = 0; m < 8; ++m)
1295 children[m].particles = p;
1302 PType &x = xxp[*pp];
1303 if (x[0] >= children[m].boundary_p1[0] &&
1304 x[0] <= children[m].boundary_p2[0] &&
1305 x[1] >= children[m].boundary_p1[1] &&
1306 x[1] <= children[m].boundary_p2[1] &&
1307 x[2] >= children[m].boundary_p1[2] &&
1308 x[2] <= children[m].boundary_p2[2])
1311 children[m].nparticles++;
1316 np += children[m].nparticles;
1318 children[m].root_inv_density = children[m].boxsize/pow(children[m].nparticles,1.0/3.);
1320 assert( current->nparticles == np );
1324 while(children[i].nparticles==0 && i<8) ++i;
1326 current->child = children+i;
1330 if(children[j].nparticles > 0){
1331 children[i].brother = children + j;
1337 children[i].brother = current->brother;