54 MPI_Comm_rank(MPI_COMM_WORLD, &
ThisTask);
87 int child = ev->
child;
117 static void do_the_short_range_kick(
int i,
double dt_entr,
double Fgravkick,
double Fhydrokick,
const double atime,
const double MinEgySpec);
127 if(Ti_Current % 2 == 1)
129 message(0,
"Initial TimeStep at TimeInit %g Ti_Current = %d \n", TimeInit, Ti_Current);
151 if(i <= 0 || current <= 0)
197 #pragma omp parallel for reduction(min:dti_min)
203 if(
P[i].IsGarbage ||
P[i].Swallowed)
209 MPI_Allreduce(MPI_IN_PLACE, &dti_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
212 int64_t ntiaccel=0, nticourant=0, ntiaccrete=0, ntineighbour=0, ntihsml=0;
213 int badstepsizecount = 0;
214 int mTimeBin =
TIMEBINS, maxTimeBin = 0;
215 #pragma omp parallel for reduction(min: mTimeBin) reduction(+: badstepsizecount, ntiaccel, nticourant, ntiaccrete, ntineighbour, ntihsml) reduction(max:maxTimeBin)
220 if(
P[i].IsGarbage ||
P[i].Swallowed)
246 message(1,
"Time-step of integer size %d not allowed, id = %lu, debugging info follows.\n", dti,
P[i].ID);
249 int binold =
P[i].TimeBin;
271 MPI_Allreduce(MPI_IN_PLACE, &badstepsizecount, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD);
272 MPI_Allreduce(MPI_IN_PLACE, &mTimeBin, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
273 MPI_Allreduce(MPI_IN_PLACE, &maxTimeBin, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
275 MPI_Allreduce(MPI_IN_PLACE, &ntiaccel, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
276 MPI_Allreduce(MPI_IN_PLACE, &nticourant, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
277 MPI_Allreduce(MPI_IN_PLACE, &ntihsml, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
278 MPI_Allreduce(MPI_IN_PLACE, &ntiaccrete, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
279 MPI_Allreduce(MPI_IN_PLACE, &ntineighbour, 1,
MPI_INT64, MPI_SUM, MPI_COMM_WORLD);
286 message(0,
"PM timebin: %x (dloga: %g Max: %g). Criteria: Accel: %ld Soundspeed: %ld DivVel: %ld Accrete: %ld Neighbour: %ld\n",
288 ntiaccel, nticourant, ntihsml, ntiaccrete, ntineighbour);
293 if(isFirstTimeStep) {
294 #pragma omp parallel for
298 P[pa].TimeBin = mTimeBin;
304 return badstepsizecount;
312 #pragma omp parallel for
313 for(bin = 0; bin <=
TIMEBINS; bin++)
331 #pragma omp parallel for
351 #pragma omp parallel for
355 if(
P[i].Swallowed ||
P[i].IsGarbage)
357 int bin =
P[i].TimeBin;
359 endrun(4,
"Particle %d (type %d, id %ld) had unexpected timebin %d\n", i,
P[i].Type,
P[i].ID,
P[i].TimeBin);
361 if(isnan(gravkick[bin]) || gravkick[bin] == 0.)
362 endrun(5,
"Bad kicks %lg bin %d tik %d\n", gravkick[bin], bin, times->
Ti_kick[bin]);
382 #pragma omp parallel for
386 if(
P[i].Swallowed ||
P[i].IsGarbage)
388 for(j = 0; j < 3; j++)
389 P[i].Vel[j] +=
P[i].
GravPM[j] * Fgravkick;
396 do_the_short_range_kick(
int i,
double dt_entr,
double Fgravkick,
double Fhydrokick,
const double atime,
const double MinEgySpec)
399 for(j = 0; j < 3; j++)
400 P[i].Vel[j] +=
P[i].GravAccel[j] * Fgravkick;
404 for(j = 0; j < 3; j++){
405 P[i].Vel[j] +=
BHP(i).DFAccel[j] * Fgravkick;
406 P[i].Vel[j] +=
BHP(i).DragAccel[j] * Fgravkick;
412 for(j = 0; j < 3; j++) {
413 P[i].Vel[j] +=
SPHP(i).HydroAccel[j] * Fhydrokick;
419 vv +=
P[i].Vel[j] *
P[i].Vel[j];
431 SPHP(i).Entropy +=
SPHP(i).DtEntropy * dt_entr;
434 double a3inv = 1/(atime * atime * atime);
436 if(
SPHP(i).Entropy < MinEgySpec/enttou)
437 SPHP(i).Entropy = MinEgySpec / enttou;
441 if(isnan(
P[i].Vel[0]) || isnan(
P[i].Vel[1]) || isnan(
P[i].Vel[2])) {
442 message(1,
"Vel = %g %g %g Type = %d gk = %g a_g = %g %g %g\n",
443 P[i].Vel[0],
P[i].Vel[1],
P[i].Vel[2],
P[i].Type,
444 Fgravkick,
P[i].GravAccel[0],
P[i].GravAccel[1],
P[i].GravAccel[2]);
453 double dt = 0, dt_courant = 0, dt_hsml = 0;
457 const double a2inv = 1/(atime * atime);
459 double ax = a2inv *
P[p].GravAccel[0];
460 double ay = a2inv *
P[p].GravAccel[1];
461 double az = a2inv *
P[p].GravAccel[2];
463 ay += a2inv *
P[p].GravPM[1];
464 ax += a2inv *
P[p].GravPM[0];
465 az += a2inv *
P[p].GravPM[2];
469 const double fac2 = 1 / pow(atime, 3 *
GAMMA - 2);
470 ax += fac2 *
SPHP(p).HydroAccel[0];
471 ay += fac2 *
SPHP(p).HydroAccel[1];
472 az += fac2 *
SPHP(p).HydroAccel[2];
475 ac = sqrt(ax * ax + ay * ay + az * az);
487 const double fac3 = pow(atime, 3 * (1 -
GAMMA) / 2.0);
489 if(dt_courant < dt) {
504 if(
BHP(p).Mdot > 0 &&
BHP(p).Mass > 0)
506 double dt_accr = 0.25 *
BHP(p).Mass /
BHP(p).Mdot;
526 double dloga = dt * hubble;
552 if(dti > dti_max || dti < 0)
558 message(1,
"Bad timestep (%x)! titype %d. ID=%lu Type=%d dloga=%g dtmax=%x xyz=(%g|%g|%g) tree=(%g|%g|%g) PM=(%g|%g|%g) hydro-frc=(%g|%g|%g) dens=%g hsml=%g dh = %g Entropy=%g, dtEntropy=%g maxsignal=%g\n",
559 dti, *titype,
P[p].ID,
P[p].Type,
dloga, dti_max,
560 P[p].Pos[0],
P[p].Pos[1],
P[p].Pos[2],
561 P[p].GravAccel[0],
P[p].GravAccel[1],
P[p].GravAccel[2],
563 SPHP(p).HydroAccel[0],
SPHP(p).HydroAccel[1],
SPHP(p).HydroAccel[2],
564 SPHP(p).Density,
P[p].Hsml,
P[p].DtHsml,
SPHP(p).Entropy,
SPHP(p).DtEntropy,
SPHP(p).MaxSignalVel);
566 message(1,
"Bad timestep (%x)! titype %d. ID=%lu Type=%d dloga=%g dtmax=%x xyz=(%g|%g|%g) tree=(%g|%g|%g) PM=(%g|%g|%g)\n",
567 dti, *titype,
P[p].ID,
P[p].Type,
dloga, dti_max,
568 P[p].Pos[0],
P[p].Pos[1],
P[p].Pos[2],
569 P[p].GravAccel[0],
P[p].GravAccel[1],
P[p].GravAccel[2],
589 double v[6], v_sum[6], mim[6], min_mass[6];
592 for(type = 0; type < 6; type++)
601 v[
P[i].Type] +=
P[i].Vel[0] *
P[i].Vel[0] +
P[i].Vel[1] *
P[i].Vel[1] +
P[i].Vel[2] *
P[i].Vel[2];
604 if(mim[
P[i].Type] >
P[i].Mass)
605 mim[
P[i].Type] =
P[i].Mass;
610 MPI_Allreduce(v, v_sum, 6, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
611 MPI_Allreduce(mim, min_mass, 6, MPI_DOUBLE, MPI_MIN, MPI_COMM_WORLD);
617 v_sum[0] += v_sum[4];
621 v_sum[0] += v_sum[5];
626 min_mass[5] = min_mass[0];
629 for(type = 0; type < 6; type++)
633 double omega, dmean, dloga1;
635 if(type == 0 || type == 4 || type == 5) {
640 else if (type == 2) {
649 message(0,
"type=%d dmean=%g asmth=%g minmass=%g a=%g sqrt(<p^2>)=%g dloga=%g\n",
650 type, dmean, asmth, min_mass[type], atime, sqrt(v_sum[type] /
count_sum[type]), dloga1);
653 if(type != FastParticleType && dloga1 <
dloga)
676 endrun(0,
"Trying to go beyond the last sync point. This happens only at TimeMax \n");
725 int NumThreads = omp_get_max_threads();
740 int * TimeBinCountType = (
int *)
mymalloc(
"TimeBinCountType", 6*(
TIMEBINS+1)*NumThreads *
sizeof(int));
741 memset(TimeBinCountType, 0, 6 * (
TIMEBINS+1) * NumThreads *
sizeof(
int));
744 size_t *NActiveThread =
ta_malloc(
"NActiveThread",
size_t, NumThreads);
745 int **ActivePartSets =
ta_malloc(
"ActivePartSets",
int *, NumThreads);
751 #pragma omp parallel for schedule(static, schedsz)
754 const int bin =
P[i].TimeBin;
755 const int tid = omp_get_thread_num();
756 if(
P[i].IsGarbage ||
P[i].Swallowed)
760 endrun(5,
"Particle %d type %d has drift time %x not ti_current %x!",i,
P[i].Type,
P[i].Ti_drift, times->
Ti_Current);
766 ActivePartSets[tid][NActiveThread[tid]] = i;
767 NActiveThread[tid]++;
769 TimeBinCountType[(
TIMEBINS + 1) * (6* tid +
P[i].Type) + bin] ++;
810 int64_t tot = 0, tot_type[6] = {0};
811 int64_t tot_count[
TIMEBINS+1] = {0};
812 int64_t tot_count_type[6][
TIMEBINS+1] = {{0}};
813 int64_t tot_num_force = 0;
816 int NumThreads = omp_get_max_threads();
818 for(i = 1; i < NumThreads; i ++) {
821 TimeBinCountType[j] += TimeBinCountType[6 * (
TIMEBINS+1) * i + j];
824 for(i = 0; i < 6; i ++) {
831 tot_count[i] += tot_count_type[j][i];
833 TotNumType[j] += tot_count_type[j][i];
837 tot_num_force += tot_count[i];
840 char extra[20] = {0};
843 strcat(extra,
"PM-Step");
846 const double z = 1.0 / (Time) - 1;
847 message(0,
"Begin Step %d, Time: %g (%x), Redshift: %g, Nf = %014ld, Systemstep: %g, Dloga: %g, status: %s\n",
848 NumCurrentTiStep, Time, times->
Ti_Current, z, tot_num_force,
852 message(0,
"TotNumPart: %013ld SPH %013ld BH %010ld STAR %013ld \n",
853 TotNumPart, TotNumType[0], TotNumType[5], TotNumType[4]);
854 message(0,
"Occupied: % 12ld % 12ld % 12ld % 12ld % 12ld % 12ld dt\n", 0L, 1L, 2L, 3L, 4L, 5L);
857 if(tot_count[i] == 0)
continue;
858 message(0,
" %c bin=%2d % 12ld % 12ld % 12ld % 12ld % 12ld % 12ld %6g\n",
861 tot_count_type[0][i],
862 tot_count_type[1][i],
863 tot_count_type[2][i],
864 tot_count_type[3][i],
865 tot_count_type[4][i],
866 tot_count_type[5][i],
878 message(0,
" -----------------------------------\n");
879 message(0,
"Total: % 12ld % 12ld % 12ld % 12ld % 12ld % 12ld Sum:% 14ld\n",
880 tot_type[0], tot_type[1], tot_type[2], tot_type[3], tot_type[4], tot_type[5], tot);
double hubble_function(const Cosmology *CP, double a)
void message(int where, const char *fmt,...)
void endrun(int where, const char *fmt,...)
int event_listen(EventSpec *eh, eventfunc func, void *userdata)
int event_unlisten(EventSpec *eh, eventfunc func, void *userdata)
double FORCE_SOFTENING(int i, int type)
static struct gravpm_params GravPM
#define mymalloc(name, size)
#define ta_malloc(name, type, nele)
#define myrealloc(ptr, size)
double get_omega_nu(const _omega_nu *const omnu, const double a)
double param_get_double(ParameterSet *ps, const char *name)
int param_get_int(ParameterSet *ps, const char *name)
struct part_manager_type PartManager[1]
int64_t MaxActiveParticle
int64_t NumActiveParticle
inttime_t Ti_lastactivedrift[TIMEBINS+1]
inttime_t Ti_kick[TIMEBINS+1]
double MaxRMSDisplacementFac
void gadget_setup_thread_arrays(int *dest, int *srcs[], size_t sizes[], size_t total_size, int narrays)
int64_t count_sum(int64_t countLocal)
void sumup_large_ints(int n, int *src, int64_t *res)
size_t gadget_compact_thread_arrays(int *dest, int *srcs[], size_t sizes[], int narrays)
static int64_t atomic_fetch_and_add_64(int64_t *ptr, int64_t value)
double loga_from_ti(int ti)
inttime_t dti_from_dloga(double loga, const inttime_t Ti_Current)
inttime_t ti_from_loga(double loga)
SyncPoint * find_next_sync_point(inttime_t ti)
inttime_t round_down_power_of_two(inttime_t dti)
double dloga_from_dti(inttime_t dti, const inttime_t Ti_Current)
double get_dloga_for_bin(int timebin, const inttime_t Ti_Current)
static inttime_t dti_from_timebin(int bin)
double get_exact_hydrokick_factor(Cosmology *CP, inttime_t ti0, inttime_t ti1)
double get_exact_gravkick_factor(Cosmology *CP, inttime_t ti0, inttime_t ti1)
void apply_PM_half_kick(Cosmology *CP, DriftKickTimes *times)
static double get_timestep_dloga(const int p, const inttime_t Ti_Current, const double atime, const double hubble, enum TimeStepType *titype)
static void do_the_short_range_kick(int i, double dt_entr, double Fgravkick, double Fhydrokick, const double atime, const double MinEgySpec)
int is_PM_timestep(const DriftKickTimes *const times)
void set_timestep_params(ParameterSet *ps)
double get_atime(const inttime_t Ti_Current)
DriftKickTimes init_driftkicktime(inttime_t Ti_Current)
inttime_t init_timebins(double TimeInit)
double get_long_range_timestep_dloga(const double atime, const Cosmology *CP, const int FastParticleType, const double asmth)
static int timestep_eh_slots_fork(EIBase *event, void *userdata)
int find_timesteps(const ActiveParticles *act, DriftKickTimes *times, const double atime, int FastParticleType, const Cosmology *CP, const double asmth, const int isFirstTimeStep)
int rebuild_activelist(ActiveParticles *act, const DriftKickTimes *const times, int NumCurrentTiStep, const double Time)
static int get_active_particle(const ActiveParticles *act, int pa)
int is_timebin_active(int i, inttime_t current)
void apply_half_kick(const ActiveParticles *act, Cosmology *CP, DriftKickTimes *times, const double atime, const double MinEgySpec)
static struct timestep_params TimestepParams
inttime_t find_next_kick(inttime_t Ti_Current, int minTimeBin)
static inttime_t get_PM_timestep_ti(const DriftKickTimes *const times, const double atime, const Cosmology *CP, const int FastParticleType, const double asmth)
static inttime_t get_timestep_ti(const int p, const inttime_t dti_max, const inttime_t Ti_Current, const double atime, const double hubble, enum TimeStepType *titype)
static int get_timestep_bin(inttime_t dti)
void update_lastactive_drift(DriftKickTimes *times)
void free_activelist(ActiveParticles *act)
static void print_timebin_statistics(const DriftKickTimes *const times, const int NumCurrentTiStep, int *TimeBinCountType, const double Time)
#define walltime_measure(name)
static enum TransferType ptype