diff --git a/configure.ac b/configure.ac index 4b6308e96b81bbfd0a9256bb4914f1356fbfa6f8..386a18c0dfa7cb160046f748865cf19990479892 100644 --- a/configure.ac +++ b/configure.ac @@ -16,7 +16,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # Init the project. -AC_INIT([SWIFT],[0.4.0],[https://gitlab.cosma.dur.ac.uk/swift/swiftsim]) +AC_INIT([SWIFT],[0.5.0],[https://gitlab.cosma.dur.ac.uk/swift/swiftsim]) swift_config_flags="$*" # Need to define this, instead of using fifth argument of AC_INIT, until 2.64. diff --git a/examples/ExternalPointMass/energy_plot.py b/examples/ExternalPointMass/energy_plot.py index a75fcb835d33b3695170aab822092556f12db7d1..25640bcb5af2966dcd57efbe1a814bb18ac4f263 100644 --- a/examples/ExternalPointMass/energy_plot.py +++ b/examples/ExternalPointMass/energy_plot.py @@ -91,6 +91,9 @@ for i in range(402): E_tot_snap[i] = E_kin_snap[i] + E_pot_snap[i] Lz_snap[i] = np.sum(Lz) +print "Starting energy:", E_kin_stats[0], E_pot_stats[0], E_tot_stats[0] +print "Ending energy:", E_kin_stats[-1], E_pot_stats[-1], E_tot_stats[-1] + # Plot energy evolution figure() plot(time_stats, E_kin_stats, "r-", lw=0.5, label="Kinetic energy") diff --git a/examples/main.c b/examples/main.c index 3a8a7a123428abed7227da0cdd17a5f43f43fc09..3c1f4aab261bd7e031a42d408f4275d766948e86 100644 --- a/examples/main.c +++ b/examples/main.c @@ -334,10 +334,10 @@ int main(int argc, char *argv[]) { MPI_Bcast(params, sizeof(struct swift_params), MPI_BYTE, 0, MPI_COMM_WORLD); #endif -/* Prepare the domain decomposition scheme */ + /* Prepare the domain decomposition scheme */ + enum repartition_type reparttype = REPART_NONE; #ifdef WITH_MPI struct partition initial_partition; - enum repartition_type reparttype; partition_init(&initial_partition, &reparttype, params, nr_nodes); /* Let's report what we did */ @@ -515,8 +515,9 @@ int main(int argc, char *argv[]) { if (myrank == 0) clocks_gettime(&tic); struct engine e; engine_init(&e, &s, params, nr_nodes, myrank, nr_threads, with_aff, - engine_policies, talking, &us, &prog_const, &hydro_properties, - &gravity_properties, &potential, &cooling_func, &sourceterms); + engine_policies, talking, reparttype, &us, &prog_const, + &hydro_properties, &gravity_properties, &potential, &cooling_func, + &sourceterms); if (myrank == 0) { clocks_gettime(&toc); message("engine_init took %.3f %s.", clocks_diff(&tic, &toc), @@ -590,11 +591,6 @@ int main(int argc, char *argv[]) { /* Main simulation loop */ for (int j = 0; !engine_is_done(&e) && e.step != nsteps; j++) { -/* Repartition the space amongst the nodes? */ -#ifdef WITH_MPI - if (j % 100 == 2) e.forcerepart = reparttype; -#endif - /* Reset timers */ timers_reset(timers_mask_all); @@ -696,6 +692,7 @@ int main(int argc, char *argv[]) { #endif /* Write final output. */ + engine_drift_all(&e); engine_dump_snapshot(&e); #ifdef WITH_MPI diff --git a/src/active.h b/src/active.h index 0c22a745fed4fbdf72ef1377fad45b78c86f178f..38020fde8ed53a638231097643476b7ef72d6d49 100644 --- a/src/active.h +++ b/src/active.h @@ -50,8 +50,10 @@ __attribute__((always_inline)) INLINE static int cell_is_drifted( return (c->ti_old == e->ti_current); } +/* Are cells / particles active for regular tasks ? */ + /** - * @brief Does a cell contain any active particle ? + * @brief Does a cell contain any particle finishing their time-step now ? * * @param c The #cell. * @param e The #engine containing information about the current time. @@ -73,7 +75,7 @@ __attribute__((always_inline)) INLINE static int cell_is_active( } /** - * @brief Are *all* particles in a cell active ? + * @brief Are *all* particles in a cell finishing their time-step now ? * * @param c The #cell. * @param e The #engine containing information about the current time. @@ -94,7 +96,7 @@ __attribute__((always_inline)) INLINE static int cell_is_all_active( } /** - * @brief Is this particle active ? + * @brief Is this particle finishing its time-step now ? * * @param p The #part. * @param e The #engine containing information about the current time. @@ -118,7 +120,7 @@ __attribute__((always_inline)) INLINE static int part_is_active( } /** - * @brief Is this g-particle active ? + * @brief Is this g-particle finishing its time-step now ? * * @param gp The #gpart. * @param e The #engine containing information about the current time. @@ -142,7 +144,7 @@ __attribute__((always_inline)) INLINE static int gpart_is_active( } /** - * @brief Is this s-particle active ? + * @brief Is this s-particle finishing its time-step now ? * * @param sp The #spart. * @param e The #engine containing information about the current time. @@ -157,7 +159,7 @@ __attribute__((always_inline)) INLINE static int spart_is_active( #ifdef SWIFT_DEBUG_CHECKS if (ti_end < ti_current) error( - "s-particle in an impossible time-zone! gp->ti_end=%lld " + "s-particle in an impossible time-zone! sp->ti_end=%lld " "e->ti_current=%lld", ti_end, ti_current); #endif @@ -165,4 +167,102 @@ __attribute__((always_inline)) INLINE static int spart_is_active( return (ti_end == ti_current); } +/* Are cells / particles active for kick1 tasks ? */ + +/** + * @brief Does a cell contain any particle starting their time-step now ? + * + * @param c The #cell. + * @param e The #engine containing information about the current time. + * @return 1 if the #cell contains at least an active particle, 0 otherwise. + */ +__attribute__((always_inline)) INLINE static int cell_is_starting( + const struct cell *c, const struct engine *e) { + +#ifdef SWIFT_DEBUG_CHECKS + if (c->ti_beg_max > e->ti_current) + error( + "cell in an impossible time-zone! c->ti_beg_max=%lld (t=%e) and " + "e->ti_current=%lld (t=%e)", + c->ti_beg_max, c->ti_beg_max * e->timeBase, e->ti_current, + e->ti_current * e->timeBase); +#endif + + return (c->ti_beg_max == e->ti_current); +} + +/** + * @brief Is this particle starting its time-step now ? + * + * @param p The #part. + * @param e The #engine containing information about the current time. + * @return 1 if the #part is active, 0 otherwise. + */ +__attribute__((always_inline)) INLINE static int part_is_starting( + const struct part *p, const struct engine *e) { + + const integertime_t ti_current = e->ti_current; + const integertime_t ti_beg = + get_integer_time_begin(ti_current + 1, p->time_bin); + +#ifdef SWIFT_DEBUG_CHECKS + if (ti_beg > ti_current) + error( + "particle in an impossible time-zone! p->ti_beg=%lld " + "e->ti_current=%lld", + ti_beg, ti_current); +#endif + + return (ti_beg == ti_current); +} + +/** + * @brief Is this g-particle starting its time-step now ? + * + * @param gp The #gpart. + * @param e The #engine containing information about the current time. + * @return 1 if the #gpart is active, 0 otherwise. + */ +__attribute__((always_inline)) INLINE static int gpart_is_starting( + const struct gpart *gp, const struct engine *e) { + + const integertime_t ti_current = e->ti_current; + const integertime_t ti_beg = + get_integer_time_begin(ti_current + 1, gp->time_bin); + +#ifdef SWIFT_DEBUG_CHECKS + if (ti_beg > ti_current) + error( + "g-particle in an impossible time-zone! gp->ti_beg=%lld " + "e->ti_current=%lld", + ti_beg, ti_current); +#endif + + return (ti_beg == ti_current); +} + +/** + * @brief Is this s-particle starting its time-step now ? + * + * @param sp The #spart. + * @param e The #engine containing information about the current time. + * @return 1 if the #spart is active, 0 otherwise. + */ +__attribute__((always_inline)) INLINE static int spart_is_starting( + const struct spart *sp, const struct engine *e) { + + const integertime_t ti_current = e->ti_current; + const integertime_t ti_beg = + get_integer_time_begin(ti_current + 1, sp->time_bin); + +#ifdef SWIFT_DEBUG_CHECKS + if (ti_beg > ti_current) + error( + "s-particle in an impossible time-zone! sp->ti_beg=%lld " + "e->ti_current=%lld", + ti_beg, ti_current); +#endif + + return (ti_beg == ti_current); +} #endif /* SWIFT_ACTIVE_H */ diff --git a/src/cell.c b/src/cell.c index 941ee7a7623b0006f0291878da58f7c8fa966565..c5f414817e20f5857fd836cb86b99aea923f0b2b 100644 --- a/src/cell.c +++ b/src/cell.c @@ -1026,11 +1026,34 @@ void cell_clean_links(struct cell *c, void *data) { */ void cell_check_drift_point(struct cell *c, void *data) { - integertime_t ti_current = *(integertime_t *)data; +#ifdef SWIFT_DEBUG_CHECKS + + const integertime_t ti_drift = *(integertime_t *)data; + + /* Only check local cells */ + if (c->nodeID != engine_rank) return; + + if (c->ti_old != ti_drift) + error("Cell in an incorrect time-zone! c->ti_old=%lld ti_drift=%lld", + c->ti_old, ti_drift); + + for (int i = 0; i < c->count; ++i) + if (c->parts[i].ti_drift != ti_drift) + error("part in an incorrect time-zone! p->ti_drift=%lld ti_drift=%lld", + c->parts[i].ti_drift, ti_drift); + + for (int i = 0; i < c->gcount; ++i) + if (c->gparts[i].ti_drift != ti_drift) + error("g-part in an incorrect time-zone! gp->ti_drift=%lld ti_drift=%lld", + c->gparts[i].ti_drift, ti_drift); - if (c->ti_old != ti_current && c->nodeID == engine_rank) - error("Cell in an incorrect time-zone! c->ti_old=%lld ti_current=%lld", - c->ti_old, ti_current); + for (int i = 0; i < c->scount; ++i) + if (c->sparts[i].ti_drift != ti_drift) + error("s-part in an incorrect time-zone! sp->ti_drift=%lld ti_drift=%lld", + c->sparts[i].ti_drift, ti_drift); +#else + error("Calling debugging code without debugging flag activated."); +#endif } /** @@ -1155,6 +1178,8 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { struct engine *e = s->space->e; #endif + int rebuild = 0; + /* Un-skip the density tasks involved with this cell. */ for (struct link *l = c->density; l != NULL; l = l->next) { struct task *t = l->t; @@ -1180,7 +1205,7 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { (max(ci->h_max, cj->h_max) + ci->dx_max + cj->dx_max > cj->dmin || ci->dx_max > space_maxreldx * ci->h_max || cj->dx_max > space_maxreldx * cj->h_max)) - return 1; + rebuild = 1; #ifdef WITH_MPI /* Activate the send/recv flags. */ @@ -1277,7 +1302,7 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { if (c->cooling != NULL) scheduler_activate(s, c->cooling); if (c->sourceterms != NULL) scheduler_activate(s, c->sourceterms); - return 0; + return rebuild; } /** @@ -1424,5 +1449,7 @@ void cell_check_timesteps(struct cell *c) { if (c->parts[i].time_bin == 0) error("Particle without assigned time-bin"); } +#else + error("Calling debugging code without debugging flag activated."); #endif } diff --git a/src/cell.h b/src/cell.h index 0d5a46006bd34cce4e65e9c2f9761292c31f40be..6c90f38c51980fd742480c90864f2f901005c0f1 100644 --- a/src/cell.h +++ b/src/cell.h @@ -74,7 +74,7 @@ struct pcell { /* Stats on this cell's particles. */ double h_max; - integertime_t ti_end_min, ti_end_max, ti_old; + integertime_t ti_end_min, ti_end_max, ti_beg_max, ti_old; /* Number of particles in this cell. */ int count, gcount, scount; @@ -227,6 +227,9 @@ struct cell { /*! Maximum end of (integer) time step in this cell. */ integertime_t ti_end_max; + /*! Maximum beginning of (integer) time step in this cell. */ + integertime_t ti_beg_max; + /*! Last (integer) time the cell's content was drifted forward in time. */ integertime_t ti_old; diff --git a/src/drift.h b/src/drift.h index 687f8d8885a5fedca489f76d65ea8113101626c6..9957d829fd28e033df9db325186195a3b396738c 100644 --- a/src/drift.h +++ b/src/drift.h @@ -41,6 +41,18 @@ __attribute__((always_inline)) INLINE static void drift_gpart( struct gpart *restrict gp, float dt, double timeBase, integertime_t ti_old, integertime_t ti_current) { + +#ifdef SWIFT_DEBUG_CHECKS + if (gp->ti_drift != ti_old) + error( + "g-particle has not been drifted to the current time " + "gp->ti_drift=%lld, " + "c->ti_old=%lld, ti_current=%lld", + gp->ti_drift, ti_old, ti_current); + + gp->ti_drift = ti_current; +#endif + /* Drift... */ gp->x[0] += gp->v_full[0] * dt; gp->x[1] += gp->v_full[1] * dt; @@ -69,7 +81,7 @@ __attribute__((always_inline)) INLINE static void drift_part( #ifdef SWIFT_DEBUG_CHECKS if (p->ti_drift != ti_old) error( - "Particle has not been drifted to the current time p->ti_drift=%lld, " + "particle has not been drifted to the current time p->ti_drift=%lld, " "c->ti_old=%lld, ti_current=%lld", p->ti_drift, ti_old, ti_current); @@ -108,6 +120,17 @@ __attribute__((always_inline)) INLINE static void drift_spart( struct spart *restrict sp, float dt, double timeBase, integertime_t ti_old, integertime_t ti_current) { +#ifdef SWIFT_DEBUG_CHECKS + if (sp->ti_drift != ti_old) + error( + "s-particle has not been drifted to the current time " + "sp->ti_drift=%lld, " + "c->ti_old=%lld, ti_current=%lld", + sp->ti_drift, ti_old, ti_current); + + sp->ti_drift = ti_current; +#endif + /* Drift... */ sp->x[0] += sp->v[0] * dt; sp->x[1] += sp->v[1] * dt; diff --git a/src/engine.c b/src/engine.c index 531b84c471514341736b0e846efec4e6c734e43e..fbb6da306eb86ee69c47bb86b17e86d768ac24ae 100644 --- a/src/engine.c +++ b/src/engine.c @@ -157,12 +157,12 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { 0, 0, c, NULL, 0); scheduler_addunlock(s, c->kick2, c->timestep); + scheduler_addunlock(s, c->timestep, c->kick1); /* Add the drift task and its dependencies. */ c->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, 0, 0, c, NULL, 0); - scheduler_addunlock(s, c->kick1, c->drift); scheduler_addunlock(s, c->drift, c->init); /* Generate the ghost task. */ @@ -822,19 +822,18 @@ void engine_repartition(struct engine *e) { fflush(stdout); /* Check that all cells have been drifted to the current time */ - space_check_drift_point(e->s, e->ti_current); + space_check_drift_point(e->s, e->ti_old); #endif /* Clear the repartition flag. */ - enum repartition_type reparttype = e->forcerepart; - e->forcerepart = REPART_NONE; + e->forcerepart = 0; /* Nothing to do if only using a single node. Also avoids METIS * bug that doesn't handle this case well. */ if (e->nr_nodes == 1) return; /* Do the repartitioning. */ - partition_repartition(reparttype, e->nodeID, e->nr_nodes, e->s, + partition_repartition(e->reparttype, e->nodeID, e->nr_nodes, e->s, e->sched.tasks, e->sched.nr_tasks); /* Now comes the tricky part: Exchange particles between all nodes. @@ -2599,8 +2598,15 @@ void engine_rebuild(struct engine *e) { if (engine_marktasks(e)) error("engine_marktasks failed after space_rebuild."); - /* Print the status of the system */ - if (e->verbose) engine_print_task_counts(e); +/* Print the status of the system */ +// if (e->verbose) engine_print_task_counts(e); + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that all cells have been drifted to the current time. + * That can include cells that have not + * previously been active on this rank. */ + space_check_drift_point(e->s, e->ti_old); +#endif if (e->verbose) message("took %.3f %s.", clocks_from_ticks(getticks() - tic), @@ -2611,48 +2617,28 @@ void engine_rebuild(struct engine *e) { * @brief Prepare the #engine by re-building the cells and tasks. * * @param e The #engine to prepare. - * @param drift_all Whether to drift particles before rebuilding or not. Will - * not be necessary if all particles have already been - * drifted (before repartitioning for instance). - * @param postrepart If we have just repartitioned, if so we need to defer the - * skip until after the rebuild and not check the if all - * cells have been drifted. */ -void engine_prepare(struct engine *e, int drift_all, int postrepart) { +void engine_prepare(struct engine *e) { TIMER_TIC; - /* Unskip active tasks and check for rebuild */ - if (!postrepart) engine_unskip(e); - - /* Run through the tasks and mark as skip or not. */ - int rebuild = e->forcerebuild; - -/* Collect the values of rebuild from all nodes. */ -#ifdef WITH_MPI - int buff = 0; - if (MPI_Allreduce(&rebuild, &buff, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD) != - MPI_SUCCESS) - error("Failed to aggregate the rebuild flag across nodes."); - rebuild = buff; -#endif - - /* And rebuild if necessary. */ - if (rebuild) { - - /* Drift all particles to the current time if needed. */ - if (drift_all) engine_drift_all(e); - #ifdef SWIFT_DEBUG_CHECKS - /* Check that all cells have been drifted to the current time, unless - * we have just repartitioned, that can include cells that have not + if (e->forcerepart || e->forcerebuild) { + /* Check that all cells have been drifted to the current time. + * That can include cells that have not * previously been active on this rank. */ - if (!postrepart) space_check_drift_point(e->s, e->ti_current); + space_check_drift_point(e->s, e->ti_old); + } #endif - engine_rebuild(e); - } - if (postrepart) engine_unskip(e); + /* Do we need repartitioning ? */ + if (e->forcerepart) engine_repartition(e); + + /* Do we need rebuilding ? */ + if (e->forcerebuild) engine_rebuild(e); + + /* Unskip active tasks and check for rebuild */ + engine_unskip(e); /* Re-rank the tasks every now and then. */ if (e->tasks_age % engine_tasksreweight == 1) { @@ -2663,7 +2649,7 @@ void engine_prepare(struct engine *e, int drift_all, int postrepart) { TIMER_TOC(timer_prepare); if (e->verbose) - message("took %.3f %s (including drift all, rebuild and reweight).", + message("took %.3f %s (including unskip and reweight).", clocks_from_ticks(getticks() - tic), clocks_getunit()); } @@ -2722,7 +2708,7 @@ void engine_collect_kick(struct cell *c) { /* Counters for the different quantities. */ int updated = 0, g_updated = 0, s_updated = 0; - integertime_t ti_end_min = max_nr_timesteps; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0, ti_beg_max = 0; /* Collect the values from the progeny. */ for (int k = 0; k < 8; k++) { @@ -2734,6 +2720,8 @@ void engine_collect_kick(struct cell *c) { /* And update */ ti_end_min = min(ti_end_min, cp->ti_end_min); + ti_end_max = max(ti_end_max, cp->ti_end_max); + ti_beg_max = max(ti_beg_max, cp->ti_beg_max); updated += cp->updated; g_updated += cp->g_updated; s_updated += cp->s_updated; @@ -2747,6 +2735,8 @@ void engine_collect_kick(struct cell *c) { /* Store the collected values in the cell. */ c->ti_end_min = ti_end_min; + c->ti_end_max = ti_end_max; + c->ti_beg_max = ti_beg_max; c->updated = updated; c->g_updated = g_updated; c->s_updated = s_updated; @@ -2762,7 +2752,7 @@ void engine_collect_timestep(struct engine *e) { const ticks tic = getticks(); int updates = 0, g_updates = 0, s_updates = 0; - integertime_t ti_end_min = max_nr_timesteps; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0, ti_beg_max = 0; const struct space *s = e->s; /* Collect the cell data. */ @@ -2775,6 +2765,8 @@ void engine_collect_timestep(struct engine *e) { /* And aggregate */ ti_end_min = min(ti_end_min, c->ti_end_min); + ti_end_max = max(ti_end_max, c->ti_end_max); + ti_beg_max = max(ti_beg_max, c->ti_beg_max); updates += c->updated; g_updates += c->g_updated; s_updates += c->s_updated; @@ -2812,6 +2804,8 @@ void engine_collect_timestep(struct engine *e) { #endif e->ti_end_min = ti_end_min; + e->ti_end_max = ti_end_max; + e->ti_beg_max = ti_beg_max; e->updates = updates; e->g_updates = g_updates; e->s_updates = s_updates; @@ -2885,7 +2879,7 @@ void engine_skip_force_and_kick(struct engine *e) { * * @param e The #engine to act on. */ -void engine_skip_drift_and_kick(struct engine *e) { +void engine_skip_drift(struct engine *e) { struct task *tasks = e->sched.tasks; const int nr_tasks = e->sched.nr_tasks; @@ -2895,7 +2889,7 @@ void engine_skip_drift_and_kick(struct engine *e) { struct task *t = &tasks[i]; /* Skip everything that updates the particles */ - if (t->type == task_type_drift || t->type == task_type_kick1) t->skip = 1; + if (t->type == task_type_drift) t->skip = 1; } } @@ -2956,13 +2950,15 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { if (e->nodeID == 0) message("Computing initial gas densities."); - engine_prepare(e, 0, 0); - - engine_marktasks(e); + /* Construct all cells and tasks to start everything */ + engine_rebuild(e); /* No time integration. We just want the density and ghosts */ engine_skip_force_and_kick(e); + /* Print the number of active tasks ? */ + if (e->verbose) engine_print_task_counts(e); + /* Now, launch the calculation */ TIMER_TIC; engine_launch(e, e->nr_threads); @@ -2974,7 +2970,6 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { if (e->nodeID == 0) message("Converting internal energy variable."); /* Apply the conversion */ - // space_map_cells_pre(s, 0, cell_convert_hydro, NULL); for (size_t i = 0; i < s->nr_parts; ++i) hydro_convert_quantities(&s->parts[i], &s->xparts[i]); @@ -2989,12 +2984,21 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { /* Now time to get ready for the first time-step */ if (e->nodeID == 0) message("Running initial fake time-step."); + /* Prepare all the tasks again for a new round */ engine_marktasks(e); - engine_skip_drift_and_kick(e); + /* No drift this time */ + engine_skip_drift(e); + /* Print the number of active tasks ? */ + if (e->verbose) engine_print_task_counts(e); + + /* Run the 0th time-step */ engine_launch(e, e->nr_threads); + /* Recover the (integer) end of the next time-step */ + engine_collect_timestep(e); + clocks_gettime(&time2); #ifdef SWIFT_DEBUG_CHECKS @@ -3004,7 +3008,7 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { #endif /* Ready to go */ - e->step = 0; + e->step = -1; e->forcerebuild = 1; e->wallclock_time = (float)clocks_diff(&time1, &time2); @@ -3018,8 +3022,6 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { */ void engine_step(struct engine *e) { - double snapshot_drift_time = 0.; - TIMER_TIC2; struct clocks_time time1, time2; @@ -3027,36 +3029,13 @@ void engine_step(struct engine *e) { e->tic_step = getticks(); - /* Recover the (integer) end of the next time-step */ - engine_collect_timestep(e); - - /* Check for output */ - while (e->ti_end_min >= e->ti_nextSnapshot && e->ti_nextSnapshot > 0) { - - e->ti_old = e->ti_current; - e->ti_current = e->ti_nextSnapshot; - e->time = e->ti_current * e->timeBase + e->timeBegin; - e->timeOld = e->ti_old * e->timeBase + e->timeBegin; - e->timeStep = (e->ti_current - e->ti_old) * e->timeBase; - snapshot_drift_time = e->timeStep; - - /* Drift everybody to the snapshot position */ - engine_drift_all(e); - - /* Dump... */ - engine_dump_snapshot(e); - - /* ... and find the next output time */ - engine_compute_next_snapshot_time(e); - } - /* Move forward in time */ e->ti_old = e->ti_current; e->ti_current = e->ti_end_min; e->step += 1; e->time = e->ti_current * e->timeBase + e->timeBegin; e->timeOld = e->ti_old * e->timeBase + e->timeBegin; - e->timeStep = (e->ti_current - e->ti_old) * e->timeBase + snapshot_drift_time; + e->timeStep = (e->ti_current - e->ti_old) * e->timeBase; if (e->nodeID == 0) { @@ -3072,31 +3051,59 @@ void engine_step(struct engine *e) { fflush(e->file_timesteps); } - /* Drift only the necessary particles, that means all particles - * if we are about to repartition. */ - const int repart = (e->forcerepart != REPART_NONE); - const int drift_all = (e->policy & engine_policy_drift_all); - if (repart || drift_all) engine_drift_all(e); - - /* Re-distribute the particles amongst the nodes? */ - if (repart) engine_repartition(e); + /* Prepare the tasks to be launched, rebuild or repartition if needed. */ + engine_prepare(e); - /* Prepare the space. */ - engine_prepare(e, !(drift_all || repart), repart); +/* Repartition the space amongst the nodes? */ +#if defined(WITH_MPI) && defined(HAVE_METIS) + if (e->step % 100 == 2) e->forcerepart = 1; +#endif + /* Print the number of active tasks ? */ if (e->verbose) engine_print_task_counts(e); - /* Save some statistics */ + /* Save some statistics ? */ if (e->time - e->timeLastStatistics >= e->deltaTimeStatistics) { engine_print_stats(e); e->timeLastStatistics += e->deltaTimeStatistics; } - /* Send off the runners. */ + /* Start all the tasks. */ TIMER_TIC; engine_launch(e, e->nr_threads); TIMER_TOC(timer_runners); +/* Collect the values of rebuild from all nodes. */ +#ifdef WITH_MPI + int buff = 0; + if (MPI_Allreduce(&e->forcerebuild, &buff, 1, MPI_INT, MPI_MAX, + MPI_COMM_WORLD) != MPI_SUCCESS) + error("Failed to aggregate the rebuild flag across nodes."); + e->forcerebuild = buff; +#endif + + /* Do we want a snapshot? */ + if (e->ti_end_min >= e->ti_nextSnapshot && e->ti_nextSnapshot > 0) + e->dump_snapshot = 1; + + /* Drift everybody (i.e. what has not yet been drifted) */ + /* to the current time */ + if (e->dump_snapshot || e->forcerebuild || e->forcerepart) + engine_drift_all(e); + + /* Write a snapshot ? */ + if (e->dump_snapshot) { + + /* Dump... */ + engine_dump_snapshot(e); + + /* ... and find the next output time */ + engine_compute_next_snapshot_time(e); + } + + /* Recover the (integer) end of the next time-step */ + engine_collect_timestep(e); + TIMER_TOC2(timer_step); clocks_gettime(&time2); @@ -3353,6 +3360,13 @@ void engine_dump_snapshot(struct engine *e) { struct clocks_time time1, time2; clocks_gettime(&time1); +#ifdef SWIFT_DEBUG_CHECKS + /* Check that all cells have been drifted to the current time. + * That can include cells that have not + * previously been active on this rank. */ + space_check_drift_point(e->s, e->ti_current); +#endif + if (e->verbose) message("writing snapshot at t=%e.", e->time); /* Dump... */ @@ -3371,6 +3385,8 @@ void engine_dump_snapshot(struct engine *e) { e->snapshotUnits); #endif + e->dump_snapshot = 0; + clocks_gettime(&time2); if (e->verbose) message("writing particle properties took %.3f %s.", @@ -3445,6 +3461,7 @@ void engine_unpin() { * @param with_aff use processor affinity, if supported. * @param policy The queuing policy to use. * @param verbose Is this #engine talkative ? + * @param reparttype What type of repartition algorithm are we using ? * @param internal_units The system of units used internally. * @param physical_constants The #phys_const used for this run. * @param hydro The #hydro_props used for this run. @@ -3456,6 +3473,7 @@ void engine_unpin() { void engine_init(struct engine *e, struct space *s, const struct swift_params *params, int nr_nodes, int nodeID, int nr_threads, int with_aff, int policy, int verbose, + enum repartition_type reparttype, const struct unit_system *internal_units, const struct phys_const *physical_constants, const struct hydro_props *hydro, @@ -3477,7 +3495,9 @@ void engine_init(struct engine *e, struct space *s, e->proxy_ind = NULL; e->nr_proxies = 0; e->forcerebuild = 1; - e->forcerepart = REPART_NONE; + e->forcerepart = 0; + e->reparttype = reparttype; + e->dump_snapshot = 0; e->links = NULL; e->nr_links = 0; e->timeBegin = parser_get_param_double(params, "TimeIntegration:time_begin"); diff --git a/src/engine.h b/src/engine.h index 8a719a8952c157e2c567addce2f6fc6491730eca..2fec4b3d34bea58dc8a04cf84b9b09e75f01895b 100644 --- a/src/engine.h +++ b/src/engine.h @@ -132,6 +132,12 @@ struct engine { /* Minimal ti_end for the next time-step */ integertime_t ti_end_min; + /* Maximal ti_end for the next time-step */ + integertime_t ti_end_max; + + /* Maximal ti_beg for the next time-step */ + integertime_t ti_beg_max; + /* Number of particles updated */ size_t updates, g_updates, s_updates; @@ -180,7 +186,13 @@ struct engine { /* Force the engine to rebuild? */ int forcerebuild; - enum repartition_type forcerepart; + + /* Force the engine to repartition ? */ + int forcerepart; + enum repartition_type reparttype; + + /* Need to dump a snapshot ? */ + int dump_snapshot; /* How many steps have we done with the same set of tasks? */ int tasks_age; @@ -223,6 +235,7 @@ void engine_dump_snapshot(struct engine *e); void engine_init(struct engine *e, struct space *s, const struct swift_params *params, int nr_nodes, int nodeID, int nr_threads, int with_aff, int policy, int verbose, + enum repartition_type reparttype, const struct unit_system *internal_units, const struct phys_const *physical_constants, const struct hydro_props *hydro, @@ -231,8 +244,7 @@ void engine_init(struct engine *e, struct space *s, const struct cooling_function_data *cooling, struct sourceterms *sourceterms); void engine_launch(struct engine *e, int nr_runners); -void engine_prepare(struct engine *e, int drift_all, int postrepart); -void engine_print(struct engine *e); +void engine_prepare(struct engine *e); void engine_init_particles(struct engine *e, int flag_entropy_ICs); void engine_step(struct engine *e); void engine_maketasks(struct engine *e); diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index a0bfee05f8b7f93cce65e8b9a3e7e322e166569d..3f97070fbb80c8920a929e6df8d93def6ac6041a 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -85,6 +85,15 @@ __attribute__((always_inline)) INLINE static void gravity_end_force( __attribute__((always_inline)) INLINE static void gravity_kick_extra( struct gpart* gp, float dt) {} +/** + * @brief Sets the values to be predicted in the drifts to their values at a + * kick time + * + * @param gp The particle. + */ +__attribute__((always_inline)) INLINE static void +gravity_reset_predicted_values(struct gpart* gp) {} + /** * @brief Initialises the g-particles for the first time * diff --git a/src/kick.h b/src/kick.h index d6c85b5eab92a288f78f22fce2f03862bc34604f..7ccea7d26974297cfebc605808c4443633140ec1 100644 --- a/src/kick.h +++ b/src/kick.h @@ -43,6 +43,16 @@ __attribute__((always_inline)) INLINE static void kick_gpart( /* Time interval for this half-kick */ const float dt = (ti_end - ti_start) * timeBase; +#ifdef SWIFT_DEBUG_CHECKS + if (gp->ti_kick != ti_start) + error( + "g-particle has not been kicked to the current time gp->ti_kick=%lld, " + "ti_start=%lld, ti_end=%lld", + gp->ti_kick, ti_start, ti_end); + + gp->ti_kick = ti_end; +#endif + /* Kick particles in momentum space */ gp->v_full[0] += gp->a_grav[0] * dt; gp->v_full[1] += gp->a_grav[1] * dt; @@ -71,7 +81,7 @@ __attribute__((always_inline)) INLINE static void kick_part( #ifdef SWIFT_DEBUG_CHECKS if (p->ti_kick != ti_start) error( - "Particle has not been kicked to the current time p->ti_kick=%lld, " + "particle has not been kicked to the current time p->ti_kick=%lld, " "ti_start=%lld, ti_end=%lld", p->ti_kick, ti_start, ti_end); @@ -116,6 +126,16 @@ __attribute__((always_inline)) INLINE static void kick_spart( /* Time interval for this half-kick */ const float dt = (ti_end - ti_start) * timeBase; +#ifdef SWIFT_DEBUG_CHECKS + if (sp->ti_kick != ti_start) + error( + "s-particle has not been kicked to the current time sp->ti_kick=%lld, " + "ti_start=%lld, ti_end=%lld", + sp->ti_kick, ti_start, ti_end); + + sp->ti_kick = ti_end; +#endif + /* Acceleration from gravity */ const float a[3] = {sp->gpart->a_grav[0], sp->gpart->a_grav[1], sp->gpart->a_grav[2]}; diff --git a/src/runner.c b/src/runner.c index 9910c77f2c31b65014334c3df183854a5b7912eb..6f2f32c1f54a904deb7805b52b1d93bfa82c57b8 100644 --- a/src/runner.c +++ b/src/runner.c @@ -861,7 +861,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { TIMER_TIC; /* Anything to do here? */ - if (!cell_is_active(c, e)) return; + if (!cell_is_starting(c, e)) return; /* Recurse? */ if (c->split) { @@ -877,17 +877,17 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xp = &xparts[k]; /* If particle needs to be kicked */ - if (part_is_active(p, e)) { + if (part_is_starting(p, e)) { const integertime_t ti_step = get_integer_timestep(p->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, p->time_bin); + get_integer_time_begin(ti_current + 1, p->time_bin); #ifdef SWIFT_DEBUG_CHECKS const integertime_t ti_end = - get_integer_time_end(ti_current, p->time_bin); + get_integer_time_end(ti_current + 1, p->time_bin); - if (ti_end - ti_begin != ti_step) + if (ti_begin != ti_current) error( "Particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " "ti_step=%lld time_bin=%d ti_current=%lld", @@ -906,17 +906,21 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { struct gpart *restrict gp = &gparts[k]; /* If the g-particle has no counterpart and needs to be kicked */ - if (gp->type == swift_type_dark_matter && gpart_is_active(gp, e)) { + if (gp->type == swift_type_dark_matter && gpart_is_starting(gp, e)) { const integertime_t ti_step = get_integer_timestep(gp->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, gp->time_bin); + get_integer_time_begin(ti_current + 1, gp->time_bin); #ifdef SWIFT_DEBUG_CHECKS const integertime_t ti_end = - get_integer_time_end(ti_current, gp->time_bin); + get_integer_time_end(ti_current + 1, gp->time_bin); - if (ti_end - ti_begin != ti_step) error("Particle in wrong time-bin"); + if (ti_begin != ti_current) + error( + "Particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " + "ti_step=%lld time_bin=%d ti_current=%lld", + ti_end, ti_begin, ti_step, gp->time_bin, ti_current); #endif /* do the kick */ @@ -931,17 +935,21 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { struct spart *restrict sp = &sparts[k]; /* If particle needs to be kicked */ - if (spart_is_active(sp, e)) { + if (spart_is_starting(sp, e)) { const integertime_t ti_step = get_integer_timestep(sp->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, sp->time_bin); + get_integer_time_begin(ti_current + 1, sp->time_bin); #ifdef SWIFT_DEBUG_CHECKS const integertime_t ti_end = - get_integer_time_end(ti_current, sp->time_bin); + get_integer_time_end(ti_current + 1, sp->time_bin); - if (ti_end - ti_begin != ti_step) error("Particle in wrong time-bin"); + if (ti_begin != ti_current) + error( + "Particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " + "ti_step=%lld time_bin=%d ti_current=%lld", + ti_end, ti_begin, ti_step, sp->time_bin, ti_current); #endif /* do the kick */ @@ -1011,6 +1019,11 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Finish the time-step with a second half-kick */ kick_part(p, xp, ti_begin + ti_step / 2, ti_begin + ti_step, timeBase); +#ifdef SWIFT_DEBUG_CHECKS + /* Check that kick and the drift are synchronized */ + if (p->ti_drift != p->ti_kick) error("Error integrating part in time."); +#endif + /* Prepare the values to be drifted */ hydro_reset_predicted_values(p, xp); } @@ -1036,6 +1049,15 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Finish the time-step with a second half-kick */ kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, timeBase); + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that kick and the drift are synchronized */ + if (gp->ti_drift != gp->ti_kick) + error("Error integrating g-part in time."); +#endif + + /* Prepare the values to be drifted */ + gravity_reset_predicted_values(gp); } } @@ -1060,6 +1082,12 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Finish the time-step with a second half-kick */ kick_spart(sp, ti_begin + ti_step / 2, ti_begin + ti_step, timeBase); +#ifdef SWIFT_DEBUG_CHECKS + /* Check that kick and the drift are synchronized */ + if (sp->ti_drift != sp->ti_kick) + error("Error integrating s-part in time."); +#endif + /* Prepare the values to be drifted */ star_reset_predicted_values(sp); } @@ -1091,7 +1119,7 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { TIMER_TIC; int updated = 0, g_updated = 0, s_updated = 0; - integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0, ti_beg_max = 0; /* No children? */ if (!c->split) { @@ -1129,6 +1157,9 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { /* What is the next sync-point ? */ ti_end_min = min(ti_current + ti_new_step, ti_end_min); ti_end_max = max(ti_current + ti_new_step, ti_end_max); + + /* What is the next starting point for this cell ? */ + ti_beg_max = max(ti_current, ti_beg_max); } else { /* part is inactive */ @@ -1139,6 +1170,12 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { /* What is the next sync-point ? */ ti_end_min = min(ti_end, ti_end_min); ti_end_max = max(ti_end, ti_end_max); + + const integertime_t ti_beg = + get_integer_time_begin(ti_current + 1, p->time_bin); + + /* What is the next starting point for this cell ? */ + ti_beg_max = max(ti_beg, ti_beg_max); } } @@ -1176,6 +1213,9 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { ti_end_min = min(ti_current + ti_new_step, ti_end_min); ti_end_max = max(ti_current + ti_new_step, ti_end_max); + /* What is the next starting point for this cell ? */ + ti_beg_max = max(ti_current, ti_beg_max); + } else { /* gpart is inactive */ const integertime_t ti_end = @@ -1184,6 +1224,12 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { /* What is the next sync-point ? */ ti_end_min = min(ti_end, ti_end_min); ti_end_max = max(ti_end, ti_end_max); + + const integertime_t ti_beg = + get_integer_time_begin(ti_current + 1, gp->time_bin); + + /* What is the next starting point for this cell ? */ + ti_beg_max = max(ti_beg, ti_beg_max); } } } @@ -1220,6 +1266,9 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { ti_end_min = min(ti_current + ti_new_step, ti_end_min); ti_end_max = max(ti_current + ti_new_step, ti_end_max); + /* What is the next starting point for this cell ? */ + ti_beg_max = max(ti_current, ti_beg_max); + } else { /* star particle is inactive */ const integertime_t ti_end = @@ -1228,6 +1277,12 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { /* What is the next sync-point ? */ ti_end_min = min(ti_end, ti_end_min); ti_end_max = max(ti_end, ti_end_max); + + const integertime_t ti_beg = + get_integer_time_begin(ti_current + 1, sp->time_bin); + + /* What is the next starting point for this cell ? */ + ti_beg_max = max(ti_beg, ti_beg_max); } } } else { @@ -1246,6 +1301,7 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { s_updated += cp->s_updated; ti_end_min = min(cp->ti_end_min, ti_end_min); ti_end_max = max(cp->ti_end_max, ti_end_max); + ti_beg_max = max(cp->ti_beg_max, ti_beg_max); } } @@ -1255,6 +1311,7 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { c->s_updated = s_updated; c->ti_end_min = ti_end_min; c->ti_end_max = ti_end_max; + c->ti_beg_max = ti_beg_max; if (timer) TIMER_TOC(timer_timestep); } @@ -1433,6 +1490,11 @@ void runner_do_recv_gpart(struct runner *r, struct cell *c, int timer) { get_integer_time_end(ti_current, gparts[k].time_bin); ti_end_min = min(ti_end_min, ti_end); ti_end_max = max(ti_end_max, ti_end); + +#ifdef SWIFT_DEBUG_CHECKS + if (gparts[k].ti_drift != ti_current) + error("Received un-drifted g-particle !"); +#endif } } @@ -1584,7 +1646,8 @@ void *runner_main(void *data) { } else if (cj == NULL) { /* self */ if (!cell_is_active(ci, e) && t->type != task_type_sort && - t->type != task_type_send && t->type != task_type_recv) + t->type != task_type_send && t->type != task_type_recv && + t->type != task_type_kick1) error( "Task (type='%s/%s') should have been skipped ti_current=%lld " "c->ti_end_min=%lld", @@ -1600,6 +1663,15 @@ void *runner_main(void *data) { taskID_names[t->type], subtaskID_names[t->subtype], e->ti_current, ci->ti_end_min, t->flags); + /* Special case for kick1 */ + if (!cell_is_starting(ci, e) && t->type == task_type_kick1 && + t->flags == 0) + error( + "Task (type='%s/%s') should have been skipped ti_current=%lld " + "c->ti_end_min=%lld t->flags=%d", + taskID_names[t->type], subtaskID_names[t->subtype], e->ti_current, + ci->ti_end_min, t->flags); + } else { /* pair */ if (!cell_is_active(ci, e) && !cell_is_active(cj, e)) diff --git a/src/space.c b/src/space.c index 68d96397a3c85ed11d5e506519af699dfdd2cecf..7f0d9bcbf6341bd6074ddebf4b9d8c7cb8c04902 100644 --- a/src/space.c +++ b/src/space.c @@ -269,7 +269,7 @@ void space_regrid(struct space *s, int verbose) { const size_t nr_parts = s->nr_parts; const ticks tic = getticks(); - const integertime_t ti_current = (s->e != NULL) ? s->e->ti_current : 0; + const integertime_t ti_old = (s->e != NULL) ? s->e->ti_old : 0; /* Run through the cells and get the current h_max. */ // tic = getticks(); @@ -437,7 +437,7 @@ void space_regrid(struct space *s, int verbose) { c->gcount = 0; c->scount = 0; c->super = c; - c->ti_old = ti_current; + c->ti_old = ti_old; if (s->gravity) c->multipole = &s->multipoles_top[cid]; } @@ -522,7 +522,7 @@ void space_rebuild(struct space *s, int verbose) { size_t nr_gparts = s->nr_gparts; size_t nr_sparts = s->nr_sparts; struct cell *restrict cells_top = s->cells_top; - const integertime_t ti_current = (s->e != NULL) ? s->e->ti_current : 0; + const integertime_t ti_old = (s->e != NULL) ? s->e->ti_old : 0; /* Run through the particles and get their cell index. Allocates an index that is larger than the number of particles to avoid @@ -918,7 +918,7 @@ void space_rebuild(struct space *s, int verbose) { struct spart *sfinger = s->sparts; for (int k = 0; k < s->nr_cells; k++) { struct cell *restrict c = &cells_top[k]; - c->ti_old = ti_current; + c->ti_old = ti_old; c->parts = finger; c->xparts = xfinger; c->gparts = gfinger; @@ -1958,7 +1958,7 @@ void space_split_recursive(struct space *s, struct cell *c, const int depth = c->depth; int maxdepth = 0; float h_max = 0.0f; - integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0, ti_beg_max = 0; struct part *parts = c->parts; struct gpart *gparts = c->gparts; struct spart *sparts = c->sparts; @@ -2066,6 +2066,7 @@ void space_split_recursive(struct space *s, struct cell *c, h_max = max(h_max, c->progeny[k]->h_max); ti_end_min = min(ti_end_min, c->progeny[k]->ti_end_min); ti_end_max = max(ti_end_max, c->progeny[k]->ti_end_max); + ti_beg_max = max(ti_beg_max, c->progeny[k]->ti_beg_max); if (c->progeny[k]->maxdepth > maxdepth) maxdepth = c->progeny[k]->maxdepth; } @@ -2121,22 +2122,28 @@ void space_split_recursive(struct space *s, struct cell *c, const float h = p->h; const integertime_t ti_end = get_integer_time_end(e->ti_current, p->time_bin); + const integertime_t ti_beg = + get_integer_time_begin(e->ti_current + 1, p->time_bin); xp->x_diff[0] = 0.f; xp->x_diff[1] = 0.f; xp->x_diff[2] = 0.f; if (h > h_max) h_max = h; if (ti_end < ti_end_min) ti_end_min = ti_end; if (ti_end > ti_end_max) ti_end_max = ti_end; + if (ti_beg > ti_beg_max) ti_beg_max = ti_beg; } for (int k = 0; k < gcount; k++) { struct gpart *gp = &gparts[k]; const integertime_t ti_end = get_integer_time_end(e->ti_current, gp->time_bin); + const integertime_t ti_beg = + get_integer_time_begin(e->ti_current + 1, gp->time_bin); gp->x_diff[0] = 0.f; gp->x_diff[1] = 0.f; gp->x_diff[2] = 0.f; if (ti_end < ti_end_min) ti_end_min = ti_end; if (ti_end > ti_end_max) ti_end_max = ti_end; + if (ti_beg > ti_beg_max) ti_beg_max = ti_beg; } for (int k = 0; k < scount; k++) { struct spart *sp = &sparts[k]; @@ -2154,6 +2161,7 @@ void space_split_recursive(struct space *s, struct cell *c, c->h_max = h_max; c->ti_end_min = ti_end_min; c->ti_end_max = ti_end_max; + c->ti_beg_max = ti_beg_max; c->maxdepth = maxdepth; /* Set ownership according to the start of the parts array. */ @@ -2436,6 +2444,11 @@ void space_init_gparts(struct space *s) { #endif gravity_first_init_gpart(&gp[i]); + +#ifdef SWIFT_DEBUG_CHECKS + gp->ti_drift = 0; + gp->ti_kick = 0; +#endif } } @@ -2462,6 +2475,11 @@ void space_init_sparts(struct space *s) { #endif star_first_init_spart(&sp[i]); + +#ifdef SWIFT_DEBUG_CHECKS + sp->ti_drift = 0; + sp->ti_kick = 0; +#endif } } @@ -2794,17 +2812,17 @@ void space_link_cleanup(struct space *s) { } /** - * @brief Checks that all cells have been drifted to the current point in time + * @brief Checks that all cells have been drifted to a given point in time * * Expensive function. Should only be used for debugging purposes. * * @param s The #space to check. - * @param ti_current The (integer) time. + * @param ti_drift The (integer) time. */ -void space_check_drift_point(struct space *s, integertime_t ti_current) { +void space_check_drift_point(struct space *s, integertime_t ti_drift) { /* Recursively check all cells */ - space_map_cells_pre(s, 1, cell_check_drift_point, &ti_current); + space_map_cells_pre(s, 1, cell_check_drift_point, &ti_drift); } /** diff --git a/src/space.h b/src/space.h index cb16d7df56d4fb4c9f0206de7abb8216aacc1de9..4bbb8f32353c795772a461061096a366d0848f7e 100644 --- a/src/space.h +++ b/src/space.h @@ -212,7 +212,7 @@ void space_init_parts(struct space *s); void space_init_gparts(struct space *s); void space_init_sparts(struct space *s); void space_link_cleanup(struct space *s); -void space_check_drift_point(struct space *s, integertime_t ti_current); +void space_check_drift_point(struct space *s, integertime_t ti_drift); void space_check_timesteps(struct space *s); void space_replicate(struct space *s, int replicate, int verbose); void space_clean(struct space *s); diff --git a/src/stars/Default/star_part.h b/src/stars/Default/star_part.h index e958e3d68bc58855a4f57f24d876cfaf73362bd6..68dd4869c257e35b3be7dc21f36e6dcdb725dc17 100644 --- a/src/stars/Default/star_part.h +++ b/src/stars/Default/star_part.h @@ -47,6 +47,16 @@ struct spart { /*! Particle time bin */ timebin_t time_bin; +#ifdef SWIFT_DEBUG_CHECKS + + /* Time of the last drift */ + integertime_t ti_drift; + + /* Time of the last kick */ + integertime_t ti_kick; + +#endif + } SWIFT_STRUCT_ALIGN; #endif /* SWIFT_DEFAULT_STAR_PART_H */