12#include "gadgetconfig.h"
20#include "../data/allvars.h"
21#include "../data/dtypes.h"
22#include "../data/intposconvert.h"
23#include "../data/mymalloc.h"
24#include "../domain/domain.h"
25#include "../gravtree/gravtree.h"
27#include "../logs/logs.h"
28#include "../logs/timer.h"
29#include "../main/simulation.h"
30#include "../mpi_utils/mpi_utils.h"
31#include "../ngbtree/ngbtree.h"
33#include "../sort/cxxsort.h"
34#include "../sort/peano.h"
35#include "../system/system.h"
36#include "../time_integration/timestep.h"
52template <
typename partset>
58 long long tot_imported;
60 MPI_Reduce(&NumPartImported, &max_imported, 1, MPI_INT, MPI_MAX, 0, D->Communicator);
62 MyReal numnodes = NumNodes, tot_numnodes;
63 MPI_Reduce(&numnodes, &tot_numnodes, 1, MPI_DOUBLE, MPI_SUM, 0, D->Communicator);
65 if(Ninsert == Tp->NumPart)
67 "GRAVTREE: Tree construction done. took %g sec <numnodes>=%g NTopnodes=%d NTopleaves=%d tree-build-scalability=%g\n",
68 Buildtime, tot_numnodes / D->NTask, D->NTopnodes, D->NTopleaves,
69 ((
double)((tot_numnodes - D->NTask * ((
double)D->NTopnodes)) + D->NTopnodes)) / (tot_numnodes > 0 ? tot_numnodes : 1));
78 for(
int j = 0; j < 3; j++)
79 exp_point->
IntPos[j] =
Tp->P[i].IntPos[j];
81 exp_point->
Mass =
Tp->P[i].getMass();
84 exp_point->
Type =
Tp->P[i].getType();
89#ifndef HIERARCHICAL_GRAVITY
90 if(
Tp->TimeBinSynchronized[
Tp->P[i].TimeBinGrav])
95#if defined(PMGRID) && defined(PLACEHIGHRESREGION)
96 exp_point->InsideOutsideFlag =
Tp->P[i].InsideOutsideFlag;
100#if defined(LIGHTCONE) && (defined(LIGHTCONE_PARTICLES_GROUPS) || defined(LIGHTCONE_IMAGE_COMP_HSML_VELDISP))
106 for(
int j = 0; j < 3; j++)
107 exp_point->
IntPos[j] = Tp->P[i].IntPos[j];
109 exp_point->
Mass = Tp->P[i].getMass();
111 exp_point->
index = i;
112 exp_point->
Type = Tp->P[i].getType();
125template <
typename partset>
132#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
135#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
138#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
141#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
147 unsigned char not_empty;
149 unsigned char maxsofttype;
150 unsigned char minsofttype;
153#if defined(PMGRID) && defined(PLACEHIGHRESREGION)
154 unsigned char overlap_flag : 2;
157 leafnode_data *glob_leaf_node_data, *loc_leaf_node_data;
159 glob_leaf_node_data = (leafnode_data *)
Mem.mymalloc(
"glob_leaf_node_data", D->NTopleaves *
sizeof(leafnode_data));
162 int *recvcounts = (
int *)
Mem.mymalloc(
"recvcounts",
sizeof(
int) * D->NTask);
163 int *recvoffset = (
int *)
Mem.mymalloc(
"recvoffset",
sizeof(
int) * D->NTask);
164 int *bytecounts = (
int *)
Mem.mymalloc(
"bytecounts",
sizeof(
int) * D->NTask);
165 int *byteoffset = (
int *)
Mem.mymalloc(
"byteoffset",
sizeof(
int) * D->NTask);
167 for(
int task = 0; task < D->NTask; task++)
168 recvcounts[task] = 0;
170 for(
int n = 0; n < D->NTopleaves; n++)
171 recvcounts[D->TaskOfLeaf[n]]++;
173 for(
int task = 0; task < D->NTask; task++)
174 bytecounts[task] = recvcounts[task] *
sizeof(leafnode_data);
179 for(
int task = 1; task < D->NTask; task++)
181 recvoffset[task] = recvoffset[task - 1] + recvcounts[task - 1];
182 byteoffset[task] = byteoffset[task - 1] + bytecounts[task - 1];
185 loc_leaf_node_data = (leafnode_data *)
Mem.mymalloc(
"loc_leaf_node_data", recvcounts[D->ThisTask] *
sizeof(leafnode_data));
189 for(
int n = 0; n < D->NTopleaves; n++)
191 if(D->TaskOfLeaf[n] == D->ThisTask)
193 int no = NodeIndex[n];
196 leafnode_data *locp = &loc_leaf_node_data[idx];
200 locp->mass = nop->
mass;
201#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
202 locp->Q2Tensor = nop->Q2Tensor;
204#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
205 locp->Q3Tensor = nop->Q3Tensor;
207#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
208 locp->Q4Tensor = nop->Q4Tensor;
210#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
211 locp->Q5Tensor = nop->Q5Tensor;
218 locp->MinOldAcc = nop->MinOldAcc;
221 locp->level = nop->
level;
222#if defined(PMGRID) && defined(PLACEHIGHRESREGION)
223 locp->overlap_flag = nop->overlap_flag;
231 myMPI_Allgatherv(loc_leaf_node_data, bytecounts[D->ThisTask], MPI_BYTE, glob_leaf_node_data, bytecounts, byteoffset, MPI_BYTE,
234 for(
int task = 0; task < D->NTask; task++)
235 recvcounts[task] = 0;
237 for(
int n = 0; n < D->NTopleaves; n++)
239 int task = D->TaskOfLeaf[n];
240 if(task != D->ThisTask)
242 int no = NodeIndex[n];
245 idx = recvoffset[task] + recvcounts[task]++;
246 leafnode_data *globp = &glob_leaf_node_data[idx];
249 nop->
mass = globp->mass;
250#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
251 nop->Q2Tensor = globp->Q2Tensor;
253#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
254 nop->Q3Tensor = globp->Q3Tensor;
256#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
257 nop->Q4Tensor = globp->Q4Tensor;
259#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
260 nop->Q5Tensor = globp->Q5Tensor;
268 nop->MinOldAcc = globp->MinOldAcc;
270 nop->
level = globp->level;
271#if defined(PMGRID) && defined(PLACEHIGHRESREGION)
272 nop->overlap_flag = globp->overlap_flag;
277 Mem.myfree(loc_leaf_node_data);
278 Mem.myfree(byteoffset);
279 Mem.myfree(bytecounts);
280 Mem.myfree(recvoffset);
281 Mem.myfree(recvcounts);
282 Mem.myfree(glob_leaf_node_data);
291template <
typename partset>
294 if(!(no >= MaxPart && no < MaxPart + MaxNodes))
304 if(p < MaxPart || p >= FirstNonTopLevelNode)
311#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
314#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
317#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
320#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
327 unsigned char not_empty = 0;
338 if(p >= MaxPart && p < MaxPart + MaxNodes)
340 int nextsib = get_nodep(p)->sibling;
342 update_node_recursive(p, nextsib, mode);
348 Tp->nearest_image_intpos_to_pos(Tp->P[p].IntPos, nop->
center.da, dxyz.
da);
350 MyReal m = Tp->P[p].getMass();
355#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
360#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
364#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
368#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
373#ifndef HIERARCHICAL_GRAVITY
374 if(Tp->getTimeBinSynchronized(Tp->P[p].getTimeBinGrav()))
378 if(minOldAcc > Tp->P[p].getOldAcc())
379 minOldAcc = Tp->P[p].getOldAcc();
385 maxsofttype = Tp->P[p].getSofteningClass();
387 minsofttype = Tp->P[p].getSofteningClass();
391 else if(p < MaxPart + MaxNodes)
396 Tp->nearest_image_intpos_to_pos(noptr->
s.da, nop->
center.da, dxyz.
da);
403#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
404 Q2Tensor += noptr->Q2Tensor;
410#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
411 Q3Tensor += noptr->Q3Tensor;
418#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
419 Q4Tensor += noptr->Q4Tensor;
428#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
429 Q5Tensor += noptr->Q5Tensor;
448 if(minOldAcc > noptr->MinOldAcc)
449 minOldAcc = noptr->MinOldAcc;
454 else if(p < MaxPart + MaxNodes + D->NTopleaves)
459 p = Nextnode[p - MaxNodes];
464 int n = p - ImportedNodeOffset;
466 if(n >= NumPartImported)
467 Terminate(
"n=%d >= NumPartImported=%d MaxPart=%d MaxNodes=%d D->NTopleaves=%d", n, NumPartImported, MaxPart,
468 MaxNodes, D->NTopleaves);
471 Tp->nearest_image_intpos_to_pos(Points[n].IntPos, nop->
center.da, dxyz.
da);
473 MyReal m = Points[n].Mass;
477#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
482#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
486#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
490#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
495#ifndef HIERARCHICAL_GRAVITY
496 if(Points[n].ActiveFlag)
500 if(minOldAcc > Points[n].OldAcc)
501 minOldAcc = Points[n].OldAcc;
506 maxsofttype = Points[n].SofteningClass;
508 minsofttype = Points[n].SofteningClass;
510 p = Nextnode[p - MaxNodes];
523 Tp->pos_to_signedintpos(s.da, off.
da);
525 nop->
s[0] = off[0] + nop->
center[0];
526 nop->
s[1] = off[1] + nop->
center[1];
527 nop->
s[2] = off[2] + nop->
center[2];
529#if(MULTIPOLE_ORDER >= 3) || (MULTIPOLE_ORDER >= 2 && defined(EXTRAPOTTERM))
533 nop->Q2Tensor = Q2Tensor;
536#if(MULTIPOLE_ORDER >= 4) || (MULTIPOLE_ORDER >= 3 && defined(EXTRAPOTTERM))
540 nop->Q3Tensor = Q3Tensor;
543#if(MULTIPOLE_ORDER >= 5) || (MULTIPOLE_ORDER >= 4 && defined(EXTRAPOTTERM))
549 nop->Q4Tensor = Q4Tensor;
552#if(MULTIPOLE_ORDER >= 5 && defined(EXTRAPOTTERM))
559 nop->Q5Tensor = Q5Tensor;
569 nop->MinOldAcc = minOldAcc;
571#if defined(PMGRID) && defined(PLACEHIGHRESREGION)
573 nop->overlap_flag = Tp->check_high_res_overlap(nop->
center.da, halflen);
583template <
typename partset>
600#ifdef ADAPTIVE_HYDRO_SOFTENING
604 if(
All.AdaptiveHydroSofteningSpacing < 1)
605 Terminate(
"All.AdaptiveHydroSofteningSpacing < 1");
609 Terminate(
"All.SofteningClassOfPartType[0] != 0");
611 for(
int i = 1; i <
NTYPES; i++)
613 Terminate(
"i=%d: All.SofteningClassOfPartType[i] == All.SofteningClassOfPartType[0]", i);
627#include "../data/simparticles.h"
631#if defined(LIGHTCONE) && (defined(LIGHTCONE_PARTICLES_GROUPS) || defined(LIGHTCONE_IMAGE_COMP_HSML_VELDISP))
632#include "../data/lcparticles.h"
global_data_all_processes All
void set_softenings(void)
This function sets the (comoving) softening length of all particle types in the table All....
#define NSOFTCLASSES_HYDRO
#define BITS_FOR_POSITIONS
int myMPI_Allgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int *recvcount, int *displs, MPI_Datatype recvtype, MPI_Comm comm)
#define TIMER_START(counter)
Starts the timer counter.
#define TIMER_STOP(counter)
Stops the timer counter.
void sumup_large_ints(int n, int *src, long long *res, MPI_Comm comm)
expr pow(half base, half exp)
std::atomic< unsigned char > cannot_be_opened_locally
vector< MyIntPosType > center
int SofteningClassOfPartType[NTYPES]
double SofteningMaxPhys[NSOFTCLASSES]
int ComovingIntegrationOn
double SofteningComoving[NSOFTCLASSES]
double ForceSoftening[NSOFTCLASSES+NSOFTCLASSES_HYDRO+2]
double SofteningTable[NSOFTCLASSES+NSOFTCLASSES_HYDRO]
unsigned char maxsofttype
unsigned char minsofttype
unsigned char SofteningClass
symtensor3< typename which_return< T1, T2 >::type > outer_prod_sum(const symtensor2< T1 > &D, const vector< T2 > &v)
#define TREE_MODE_TOPLEVEL