From 8bcd1ff4ac4fae350d718c92ea8aed8fd3a845ae Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 28 Nov 2016 22:41:00 +0000 Subject: [PATCH 01/48] Particles only carry their time bin. --- src/Makefile.am | 2 +- src/active.h | 7 +- src/engine.h | 3 - src/gravity/Default/gravity.h | 3 +- src/gravity/Default/gravity_part.h | 16 ++--- src/hydro/Gadget2/hydro.h | 12 ++-- src/hydro/Gadget2/hydro_part.h | 17 +++-- src/kick.h | 7 +- src/part.h | 1 + src/runner.c | 6 +- src/space.c | 4 +- src/timeline.h | 102 +++++++++++++++++++++++++++++ 12 files changed, 146 insertions(+), 34 deletions(-) create mode 100644 src/timeline.h diff --git a/src/Makefile.am b/src/Makefile.am index 8b8dce698..d9ed64cc0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,7 +60,7 @@ AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \ nobase_noinst_HEADERS = align.h approx_math.h atomic.h cycle.h error.h inline.h kernel_hydro.h kernel_gravity.h \ kernel_long_gravity.h vector.h runner_doiact.h runner_doiact_grav.h runner_doiact_fft.h \ units.h intrinsics.h minmax.h kick.h timestep.h drift.h adiabatic_index.h io_properties.h \ - dimension.h equation_of_state.h active.h \ + dimension.h equation_of_state.h active.h timeline.h \ gravity.h gravity_io.h \ gravity/Default/gravity.h gravity/Default/gravity_iact.h gravity/Default/gravity_io.h \ gravity/Default/gravity_debug.h gravity/Default/gravity_part.h \ diff --git a/src/active.h b/src/active.h index f0aba74df..6d8a118fa 100644 --- a/src/active.h +++ b/src/active.h @@ -27,6 +27,7 @@ #include "const.h" #include "engine.h" #include "part.h" +#include "timeline.h" /** * @brief Check that a cell been drifted to the current time. @@ -107,7 +108,8 @@ __attribute__((always_inline)) INLINE static int part_is_active( p->ti_end, e->ti_current); #endif - return (p->ti_end == e->ti_current); + // return (p->ti_end == e->ti_current); + return (p->time_bin < get_max_active_bin(e->ti_current)); } /** @@ -126,7 +128,8 @@ __attribute__((always_inline)) INLINE static int gpart_is_active( gp->ti_end, e->ti_current); #endif - return (gp->ti_end == e->ti_current); + // return (gp->ti_end == e->ti_current); + return (gp->time_bin < get_max_active_bin(e->ti_current)); } #endif /* SWIFT_ACTIVE_H */ diff --git a/src/engine.h b/src/engine.h index 861e32162..54a0d9a3c 100644 --- a/src/engine.h +++ b/src/engine.h @@ -82,9 +82,6 @@ extern const char *engine_policy_names[]; /* The rank of the engine as a global variable (for messages). */ extern int engine_rank; -/* The maximal number of timesteps in a simulation */ -#define max_nr_timesteps (1 << 28) - /* Data structure for the engine. */ struct engine { diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 9e0ca81ed..4175040dc 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -53,8 +53,7 @@ gravity_compute_timestep_self(const struct gpart* const gp) { __attribute__((always_inline)) INLINE static void gravity_first_init_gpart( struct gpart* gp) { - gp->ti_begin = 0; - gp->ti_end = 0; + gp->time_bin = -1; gp->epsilon = 0.; // MATTHIEU } diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index f06e65e5b..cd16287db 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -19,12 +19,13 @@ #ifndef SWIFT_DEFAULT_GRAVITY_PART_H #define SWIFT_DEFAULT_GRAVITY_PART_H -/* Some standard headers. */ -#include - /* Gravity particle. */ struct gpart { + /* Particle ID. If negative, it is the negative offset of the #part with + which this gpart is linked. */ + long long id_or_neg_offset; + /* Particle position. */ double x[3]; @@ -44,14 +45,13 @@ struct gpart { float epsilon; /* Particle time of beginning of time-step. */ - int ti_begin; + // int ti_begin; /* Particle time of end of time-step. */ - int ti_end; + // int ti_end; - /* Particle ID. If negative, it is the negative offset of the #part with - which this gpart is linked. */ - long long id_or_neg_offset; + /* Time-step length */ + timebin_t time_bin; } SWIFT_STRUCT_ALIGN; diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 157893bc9..7a7d196ca 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -212,8 +212,7 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( __attribute__((always_inline)) INLINE static void hydro_first_init_part( struct part *restrict p, struct xpart *restrict xp) { - p->ti_begin = 0; - p->ti_end = 0; + p->time_bin = -1; xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; @@ -303,7 +302,10 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float abs_div_v = fabsf(p->density.div_v); /* Compute the pressure */ - const float half_dt = (ti_current - (p->ti_begin + p->ti_end) / 2) * timeBase; + const integertime_t ti_begin = + get_integer_time_begin(ti_current, p->time_bin); + const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); + const float half_dt = (ti_current - (ti_begin + ti_end) / 2) * timeBase; const float pressure = hydro_get_pressure(p, half_dt); /* Compute the sound speed */ @@ -383,7 +385,9 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->rho *= expf(w2); /* Drift the pressure */ - const float dt_entr = (t1 - (p->ti_begin + p->ti_end) / 2) * timeBase; + const integertime_t ti_begin = get_integer_time_begin(t1, p->time_bin); + const integertime_t ti_end = get_integer_time_end(t1, p->time_bin); + const float dt_entr = (t1 - (ti_begin + ti_end) / 2) * timeBase; const float pressure = hydro_get_pressure(p, dt_entr); /* Compute the new sound speed */ diff --git a/src/hydro/Gadget2/hydro_part.h b/src/hydro/Gadget2/hydro_part.h index 0c14da957..7c48f11b7 100644 --- a/src/hydro/Gadget2/hydro_part.h +++ b/src/hydro/Gadget2/hydro_part.h @@ -50,6 +50,12 @@ struct xpart { /* Data of a single particle. */ struct part { + /* Particle ID. */ + long long id; + + /* Pointer to corresponding gravity part. */ + struct gpart* gpart; + /* Particle position. */ double x[3]; @@ -66,10 +72,10 @@ struct part { float mass; /* Particle time of beginning of time-step. */ - int ti_begin; + // int ti_begin; /* Particle time of end of time-step. */ - int ti_end; + // int ti_end; /* Particle density. */ float rho; @@ -124,11 +130,8 @@ struct part { } force; }; - /* Particle ID. */ - long long id; - - /* Pointer to corresponding gravity part. */ - struct gpart* gpart; + /* Time-step length */ + timebin_t time_bin; } SWIFT_STRUCT_ALIGN; diff --git a/src/kick.h b/src/kick.h index e3fa3bf78..91177f91b 100644 --- a/src/kick.h +++ b/src/kick.h @@ -25,6 +25,7 @@ /* Local headers. */ #include "const.h" #include "debug.h" +#include "timeline.h" /** * @brief Perform the 'kick' operation on a #gpart @@ -68,8 +69,10 @@ __attribute__((always_inline)) INLINE static void kick_part( double timeBase) { /* Compute the time step for this kick */ - const int ti_start = (p->ti_begin + p->ti_end) / 2; - const int ti_end = p->ti_end + new_dti / 2; + const integertime_t ti_begin = get_integer_time_begin(t1, p->time_bin); + const integertime_t ti_end = get_integer_time_end(t1, p->time_bin); + const int ti_start = (ti_begin + ti_end) / 2; + const int ti_end = ti_end + new_dti / 2; const float dt = (ti_end - ti_start) * timeBase; const float half_dt = (ti_end - p->ti_end) * timeBase; diff --git a/src/part.h b/src/part.h index 6832e0c6c..b312f1656 100644 --- a/src/part.h +++ b/src/part.h @@ -33,6 +33,7 @@ /* Local headers. */ #include "align.h" #include "const.h" +#include "timeline.h" /* Some constants. */ #define part_align 128 diff --git a/src/runner.c b/src/runner.c index 2d6da4e4a..23e8aa0f6 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1029,7 +1029,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { const struct part *restrict parts = c->parts; - const struct gpart *restrict gparts = c->gparts; + // const struct gpart *restrict gparts = c->gparts; const size_t nr_parts = c->count; const size_t nr_gparts = c->gcount; // const int ti_current = r->e->ti_current; @@ -1045,14 +1045,14 @@ void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { /* Collect everything... */ for (size_t k = 0; k < nr_parts; k++) { - const int ti_end = parts[k].ti_end; + const int ti_end = 0; // parts[k].ti_end; //MATTHIEU // if(ti_end < ti_current) error("Received invalid particle !"); ti_end_min = min(ti_end_min, ti_end); ti_end_max = max(ti_end_max, ti_end); h_max = max(h_max, parts[k].h); } for (size_t k = 0; k < nr_gparts; k++) { - const int ti_end = gparts[k].ti_end; + const int ti_end = 0; // gparts[k].ti_end; //MATTHIEU // if(ti_end < ti_current) error("Received invalid particle !"); ti_end_min = min(ti_end_min, ti_end); ti_end_max = max(ti_end_max, ti_end); diff --git a/src/space.c b/src/space.c index e04aad220..0cc3c8d77 100644 --- a/src/space.c +++ b/src/space.c @@ -1529,7 +1529,7 @@ void space_split_mapper(void *map_data, int num_cells, void *extra_data) { struct part *p = &parts[k]; struct xpart *xp = &xparts[k]; const float h = p->h; - const int ti_end = p->ti_end; + const int ti_end = get_integer_time_end(e->ti_current, p->time_bin); xp->x_diff[0] = 0.f; xp->x_diff[1] = 0.f; xp->x_diff[2] = 0.f; @@ -1539,7 +1539,7 @@ void space_split_mapper(void *map_data, int num_cells, void *extra_data) { } for (int k = 0; k < gcount; k++) { struct gpart *gp = &gparts[k]; - const int ti_end = gp->ti_end; + const int ti_end = get_integer_time_end(e->ti_current, gp->time_bin); gp->x_diff[0] = 0.f; gp->x_diff[1] = 0.f; gp->x_diff[2] = 0.f; diff --git a/src/timeline.h b/src/timeline.h new file mode 100644 index 000000000..2d217a382 --- /dev/null +++ b/src/timeline.h @@ -0,0 +1,102 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + ******************************************************************************/ +#ifndef SWIFT_TIMELINE_H +#define SWIFT_TIMELINE_H + +/* Config parameters. */ +#include "../config.h" + +/* Local headers. */ +#include "inline.h" + +typedef long long integertime_t; +typedef char timebin_t; + +/*! The number of time bins */ +#define num_time_bins 20 + +/*! The maximal number of timesteps in a simulation */ +#define max_nr_timesteps (1LL << (num_time_bins + 1)) + +/** + * @brief Returns the integer time interval corresponding to a time bin + * + * @param bin The time bin of interest. + */ +static INLINE integertime_t get_integer_timestep(timebin_t bin) { + + if (bin == 0) return 0; + return 1LL << (bin + 1); +} + +/** + * @brief Returns the physical time interval corresponding to a time bin. + * + * @param bin The time bin of interest. + * @param timeBase the minimal time-step size of the simulation. + */ +static INLINE double get_timestep(timebin_t bin, double timeBase) { + + return get_integer_timestep(bin) * timeBase; +} + +/** + * @brief Returns the integer time corresponding to the start of the time-step + * given by a time-bin. + * + * @param ti_current The current time on the integer time line. + * @param bin The time bin of interest. + */ +static INLINE integertime_t get_integer_time_begin(integertime_t ti_current, + timebin_t bin) { + + const integertime_t dti = get_integer_timestep(bin); + return ti_current % dti; +} + +/** + * @brief Returns the integer time corresponding to the start of the time-step + * given by a time-bin. + * + * @param ti_current The current time on the integer time line. + * @param bin The time bin of interest. + */ +static INLINE integertime_t get_integer_time_end(integertime_t ti_current, + timebin_t bin) { + + const integertime_t dti = get_integer_timestep(bin); + return ti_current % dti + dti; +} + +/** + * @brief Returns the highest active time bin at a given point on the time line. + * + * @param time The current point on the time line. + */ +static INLINE timebin_t get_max_active_bin(integertime_t time) { + + if (time == 0) return num_time_bins; + + timebin_t bin = 1; + while (!((1LL << (bin + 1)) & time)) ++bin; + + return bin; +} + +#endif /* SWIFT_TIMELINE_H */ -- GitLab From d4a1703d801d1c2e60a573ce23be440d20d26fe0 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 29 Nov 2016 12:00:13 +0000 Subject: [PATCH 02/48] Missing includes in some header files. --- src/error.h | 9 +++++++-- src/intrinsics.h | 10 ++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/error.h b/src/error.h index 92a9ce71a..cad442fab 100644 --- a/src/error.h +++ b/src/error.h @@ -21,16 +21,21 @@ #ifndef SWIFT_ERROR_H #define SWIFT_ERROR_H +/* Config parameters. */ +#include "../config.h" + /* Some standard headers. */ #include - -#include "clocks.h" +#include /* MPI headers. */ #ifdef WITH_MPI #include #endif +/* Local headers. */ +#include "clocks.h" + /** * @brief Error macro. Prints the message given in argument and aborts. * diff --git a/src/intrinsics.h b/src/intrinsics.h index 27e0bcc72..42dddf77c 100644 --- a/src/intrinsics.h +++ b/src/intrinsics.h @@ -19,11 +19,17 @@ #ifndef SWIFT_INTRINSICS_H #define SWIFT_INTRINSICS_H +/* Config parameters. */ +#include "../config.h" + +/* Local headers. */ +#include "inline.h" + /** * @brief Returns the number of leading 0-bits in x, starting at the most * significant bit position. If x is 0, the result is undefined. * - * This is a wrapper for the GCC intrinsics with an implementation (from + * This is a wrapper for the GNU intrinsic with an implementation (from * Hacker's Delight) if the compiler intrinsics are not available. */ __attribute__((always_inline)) INLINE static int intrinsics_clz( @@ -63,7 +69,7 @@ __attribute__((always_inline)) INLINE static int intrinsics_clz( /** * @brief Returns the number of 1-bits in x. * - * This is a wrapper for the GCC intrinsics with an implementation (from + * This is a wrapper for the GNU intrinsic with an implementation (from * Hacker's Delight) if the compiler intrinsics are not available. */ __attribute__((always_inline)) INLINE static int intrinsics_popcount( -- GitLab From 655c97b9ace5c39d6859eb49cd2cb85b67a8b1cf Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 1 Dec 2016 09:53:36 +0000 Subject: [PATCH 03/48] Added two more intrinsics for long long types. --- src/intrinsics.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/intrinsics.h b/src/intrinsics.h index 42dddf77c..7a4f0870b 100644 --- a/src/intrinsics.h +++ b/src/intrinsics.h @@ -66,6 +66,23 @@ __attribute__((always_inline)) INLINE static int intrinsics_clz( #endif } +/** + * @brief Returns the number of leading 0-bits in x, starting at the most + * significant bit position. If x is 0, the result is undefined. + * + * This is a wrapper for the GNU intrinsic with an implementation. + */ +__attribute__((always_inline)) INLINE static int intrinsics_clzll( + unsigned long long x) { + +#ifdef __GNUC__ + /* Use GCC intrinsics if possible */ + return __builtin_clzll(x); +#else +#error "Missing definition of clz for long long on this platform." +#endif +} + /** * @brief Returns the number of 1-bits in x. * @@ -88,4 +105,21 @@ __attribute__((always_inline)) INLINE static int intrinsics_popcount( #endif } +/** + * @brief Returns the number of 1-bits in x. + * + * This is a wrapper for the GNU intrinsic with an implementation (from + * Hacker's Delight) if the compiler intrinsics are not available. + */ +__attribute__((always_inline)) INLINE static int intrinsics_popcountll( + unsigned long long x) { + +#ifdef __GNUC__ + /* Use GCC intrinsics if possible */ + return __builtin_popcountll(x); +#else +#error "Missing definition of popcount for long long on this platform." +#endif +} + #endif /* SWIFT_INTRINSICS_H */ -- GitLab From ba24398d38470261ff8bcb4a80b199cf2f4da467 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 1 Dec 2016 10:56:49 +0000 Subject: [PATCH 04/48] Replace ti_begin and ti_end by a time bin. Still need to fix cooling(), do_recv() statistics() and propagate types everywhere. --- examples/SedovBlast_3D/makeIC.py | 1 + src/active.h | 27 +++++++++++------ src/engine.c | 4 +++ src/gravity/Default/gravity.h | 2 +- src/gravity/Default/gravity_debug.h | 5 ++- src/hydro/Gadget2/hydro.h | 6 ++-- src/hydro/Gadget2/hydro_debug.h | 4 +-- src/kick.h | 46 ++++++++++++++++++---------- src/runner.c | 47 +++++++++++++++++++++++------ src/statistics.c | 10 ++++-- src/timeline.h | 28 +++++++++++++++-- src/timestep.h | 31 ++++++++++--------- 12 files changed, 147 insertions(+), 64 deletions(-) diff --git a/examples/SedovBlast_3D/makeIC.py b/examples/SedovBlast_3D/makeIC.py index e1b743c6c..7d1a78188 100644 --- a/examples/SedovBlast_3D/makeIC.py +++ b/examples/SedovBlast_3D/makeIC.py @@ -54,6 +54,7 @@ u[:] = P0 / (rho0 * (gamma - 1)) # Make the central particles detonate index = argsort(r) u[index[0:N_inject]] = E0 / (N_inject * m[0]) +print ids[index[0:N_inject]] #-------------------------------------------------- diff --git a/src/active.h b/src/active.h index cd0fb6cb2..2f2358134 100644 --- a/src/active.h +++ b/src/active.h @@ -101,14 +101,18 @@ __attribute__((always_inline)) INLINE static int cell_is_all_active( __attribute__((always_inline)) INLINE static int part_is_active( const struct part *p, const struct engine *e) { + const integertime_t ti_current = e->ti_current; + const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); + #ifdef SWIFT_DEBUG_CHECKS - if (p->ti_end < e->ti_current) - error("particle in an impossible time-zone! p->ti_end=%d e->ti_current=%d", - p->ti_end, e->ti_current); + if (ti_end < ti_current) + error( + "particle in an impossible time-zone! p->ti_end=%lld " + "e->ti_current=%lld", + ti_end, ti_current); #endif - // return (p->ti_end == e->ti_current); - return (p->time_bin < get_max_active_bin(e->ti_current)); + return (ti_end == ti_current); } /** @@ -120,15 +124,18 @@ __attribute__((always_inline)) INLINE static int part_is_active( __attribute__((always_inline)) INLINE static int gpart_is_active( const struct gpart *gp, const struct engine *e) { + const integertime_t ti_current = e->ti_current; + const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); + #ifdef SWIFT_DEBUG_CHECKS - if (gp->ti_end < e->ti_current) + if (ti_end < ti_current) error( - "g-particle in an impossible time-zone! gp->ti_end=%d e->ti_current=%d", - gp->ti_end, e->ti_current); + "g-particle in an impossible time-zone! gp->ti_end=%lld " + "e->ti_current=%lld", + ti_end, ti_current); #endif - // return (gp->ti_end == e->ti_current); - return (gp->time_bin < get_max_active_bin(e->ti_current)); + return (ti_end == ti_current); } #endif /* SWIFT_ACTIVE_H */ diff --git a/src/engine.c b/src/engine.c index e989aefd5..af6e222d1 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2643,6 +2643,10 @@ void engine_step(struct engine *e) { engine_launch(e, e->nr_threads); TIMER_TOC(timer_runners); + for (size_t i = 0; i < e->s->nr_parts; ++i) { + if (e->s->parts[i].time_bin == 0) error("Particle in bin 0"); + } + /* Save some statistics */ if (e->time - e->timeLastStatistics >= e->deltaTimeStatistics) { engine_print_stats(e); diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 4175040dc..89c7ac66d 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -53,7 +53,7 @@ gravity_compute_timestep_self(const struct gpart* const gp) { __attribute__((always_inline)) INLINE static void gravity_first_init_gpart( struct gpart* gp) { - gp->time_bin = -1; + gp->time_bin = 0; gp->epsilon = 0.; // MATTHIEU } diff --git a/src/gravity/Default/gravity_debug.h b/src/gravity/Default/gravity_debug.h index c284f543b..4c3c41c94 100644 --- a/src/gravity/Default/gravity_debug.h +++ b/src/gravity/Default/gravity_debug.h @@ -24,10 +24,9 @@ __attribute__((always_inline)) INLINE static void gravity_debug_particle( printf( "x=[%.3e,%.3e,%.3e], " "v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " - "mass=%.3e t_begin=%d, t_end=%d\n", + "mass=%.3e time_bin=%d\n", p->x[0], p->x[1], p->x[2], p->v_full[0], p->v_full[1], p->v_full[2], - p->a_grav[0], p->a_grav[1], p->a_grav[2], p->mass, p->ti_begin, - p->ti_end); + p->a_grav[0], p->a_grav[1], p->a_grav[2], p->mass, p->time_bin); } #endif /* SWIFT_DEFAULT_GRAVITY_DEBUG_H */ diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 7a7d196ca..e80ea9f0c 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -212,7 +212,7 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( __attribute__((always_inline)) INLINE static void hydro_first_init_part( struct part *restrict p, struct xpart *restrict xp) { - p->time_bin = -1; + p->time_bin = 0; xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; @@ -385,8 +385,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->rho *= expf(w2); /* Drift the pressure */ - const integertime_t ti_begin = get_integer_time_begin(t1, p->time_bin); - const integertime_t ti_end = get_integer_time_end(t1, p->time_bin); + const integertime_t ti_begin = get_integer_time_begin(t0, p->time_bin); + const integertime_t ti_end = get_integer_time_end(t0, p->time_bin); const float dt_entr = (t1 - (ti_begin + ti_end) / 2) * timeBase; const float pressure = hydro_get_pressure(p, dt_entr); diff --git a/src/hydro/Gadget2/hydro_debug.h b/src/hydro/Gadget2/hydro_debug.h index 656299b38..a9630a128 100644 --- a/src/hydro/Gadget2/hydro_debug.h +++ b/src/hydro/Gadget2/hydro_debug.h @@ -27,14 +27,14 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( "h=%.3e, wcount=%.3f, wcount_dh=%.3e, m=%.3e, dh_drho=%.3e, rho=%.3e, " "P=%.3e, P_over_rho2=%.3e, S=%.3e, dS/dt=%.3e, c=%.3e\n" "divV=%.3e, rotV=[%.3e,%.3e,%.3e], balsara=%.3e \n " - "v_sig=%e dh/dt=%.3e t_begin=%d, t_end=%d\n", + "v_sig=%e dh/dt=%.3e time_bin=%d\n", p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], xp->v_full[0], xp->v_full[1], xp->v_full[2], p->a_hydro[0], p->a_hydro[1], p->a_hydro[2], p->h, p->density.wcount, p->density.wcount_dh, p->mass, p->density.rho_dh, p->rho, hydro_get_pressure(p, 0.), p->force.P_over_rho2, p->entropy, p->entropy_dt, p->force.soundspeed, p->density.div_v, p->density.rot_v[0], p->density.rot_v[1], p->density.rot_v[2], p->force.balsara, - p->force.v_sig, p->force.h_dt, p->ti_begin, p->ti_end); + p->force.v_sig, p->force.h_dt, p->time_bin); } #endif /* SWIFT_GADGET2_HYDRO_DEBUG_H */ diff --git a/src/kick.h b/src/kick.h index 91177f91b..c2515e4f4 100644 --- a/src/kick.h +++ b/src/kick.h @@ -32,20 +32,27 @@ * * @param gp The #gpart to kick. * @param new_dti The (integer) time-step for this kick. + * @param ti_current The current (integer) time. * @param timeBase The minimal allowed time-step size. */ __attribute__((always_inline)) INLINE static void kick_gpart( - struct gpart *restrict gp, int new_dti, double timeBase) { + struct gpart *restrict gp, integertime_t new_dti, integertime_t ti_current, + double timeBase) { /* Compute the time step for this kick */ - const int ti_start = (gp->ti_begin + gp->ti_end) / 2; - const int ti_end = gp->ti_end + new_dti / 2; + const integertime_t old_ti_begin = + get_integer_time_begin(ti_current, gp->time_bin); + const integertime_t old_ti_end = + get_integer_time_end(ti_current, gp->time_bin); + const int ti_start = (old_ti_begin + old_ti_end) / 2; + const int ti_end = old_ti_end + new_dti / 2; const float dt = (ti_end - ti_start) * timeBase; - const float half_dt = (ti_end - gp->ti_end) * timeBase; + const float half_dt = (ti_end - old_ti_end) * timeBase; /* Move particle forward in time */ - gp->ti_begin = gp->ti_end; - gp->ti_end = gp->ti_begin + new_dti; + // gp->ti_begin = gp->ti_end; + // gp->ti_end = gp->ti_begin + new_dti; + gp->time_bin = get_time_bin(new_dti); /* Kick particles in momentum space */ gp->v_full[0] += gp->a_grav[0] * dt; @@ -62,26 +69,33 @@ __attribute__((always_inline)) INLINE static void kick_gpart( * @param p The #part to kick. * @param xp The #xpart of the particle. * @param new_dti The (integer) time-step for this kick. + * @param ti_current The current (integer) time. * @param timeBase The minimal allowed time-step size. */ __attribute__((always_inline)) INLINE static void kick_part( struct part *restrict p, struct xpart *restrict xp, int new_dti, - double timeBase) { + integertime_t ti_current, double timeBase) { /* Compute the time step for this kick */ - const integertime_t ti_begin = get_integer_time_begin(t1, p->time_bin); - const integertime_t ti_end = get_integer_time_end(t1, p->time_bin); - const int ti_start = (ti_begin + ti_end) / 2; - const int ti_end = ti_end + new_dti / 2; + const integertime_t old_ti_begin = + get_integer_time_begin(ti_current, p->time_bin); + const integertime_t old_ti_end = + get_integer_time_end(ti_current, p->time_bin); + const int ti_start = (old_ti_begin + old_ti_end) / 2; + const int ti_end = old_ti_end + new_dti / 2; const float dt = (ti_end - ti_start) * timeBase; - const float half_dt = (ti_end - p->ti_end) * timeBase; + const float half_dt = (ti_end - old_ti_end) * timeBase; /* Move particle forward in time */ - p->ti_begin = p->ti_end; - p->ti_end = p->ti_begin + new_dti; + // p->ti_begin = p->ti_end; + // p->ti_end = p->ti_begin + new_dti; + p->time_bin = get_time_bin(new_dti); + // if (p->id == 116650) message("Time bin=%d new_dti=%d", p->time_bin, + // new_dti); if (p->gpart != NULL) { - p->gpart->ti_begin = p->ti_begin; - p->gpart->ti_end = p->ti_end; + // p->gpart->ti_begin = p->ti_begin; + // p->gpart->ti_end = p->ti_end; + p->gpart->time_bin = get_time_bin(new_dti); } /* Get the acceleration */ diff --git a/src/runner.c b/src/runner.c index 23e8aa0f6..a4da82a23 100644 --- a/src/runner.c +++ b/src/runner.c @@ -113,6 +113,9 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, #include "runner_doiact_fft.h" #include "runner_doiact_grav.h" +#undef ICHECK +#define ICHECK -116650 + /** * @brief Perform source terms * @@ -205,7 +208,7 @@ void runner_do_cooling(struct runner *r, struct cell *c, int timer) { struct part *restrict parts = c->parts; struct xpart *restrict xparts = c->xparts; const int count = c->count; - const int ti_current = r->e->ti_current; + // const int ti_current = r->e->ti_current; const struct cooling_function_data *cooling_func = r->e->cooling_func; const struct phys_const *constants = r->e->physical_constants; const struct UnitSystem *us = r->e->internalUnits; @@ -227,9 +230,11 @@ void runner_do_cooling(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xp = &xparts[i]; /* Kick has already updated ti_end, so need to check ti_begin */ - if (p->ti_begin == ti_current) { + // if (p->ti_begin == ti_current) { + { - const double dt = (p->ti_end - p->ti_begin) * timeBase; + // const double dt = (p->ti_end - p->ti_begin) * timeBase; + const double dt = 1. * timeBase; // MATTHIEU cooling_cool_part(constants, us, cooling_func, p, xp, dt); } @@ -906,6 +911,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { const struct engine *e = r->e; const double timeBase = e->timeBase; + const int ti_current = e->ti_current; const int count = c->count; const int gcount = c->gcount; struct part *restrict parts = c->parts; @@ -946,15 +952,17 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { const int new_dti = get_gpart_timestep(gp, e); /* Now we have a time step, proceed with the kick */ - kick_gpart(gp, new_dti, timeBase); + kick_gpart(gp, new_dti, e->ti_current, timeBase); /* Number of updated g-particles */ g_updated++; } /* Minimal time for next end of time-step */ - ti_end_min = min(gp->ti_end, ti_end_min); - ti_end_max = max(gp->ti_end, ti_end_max); + const integertime_t ti_end = + get_integer_time_end(ti_current, gp->time_bin); + ti_end_min = min((int)ti_end, ti_end_min); + ti_end_max = max((int)ti_end, ti_end_max); } } @@ -967,9 +975,18 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { struct part *restrict p = &parts[k]; struct xpart *restrict xp = &xparts[k]; + /* Minimal time for next end of time-step */ + integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); + + if (p->id == ICHECK) + message("Particle in kick ti_end=%lld ti_current=%d", ti_end, + e->ti_current); + /* If particle needs to be kicked */ if (part_is_active(p, e)) { + if (p->id == ICHECK) message("Particle active in kick"); + /* First, finish the force loop */ hydro_end_force(p); if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); @@ -977,17 +994,27 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* Compute the next timestep (hydro condition) */ const int new_dti = get_part_timestep(p, xp, e); + if (p->id == ICHECK) + message("time_step=%d (%e)", new_dti, new_dti * e->timeBase); + /* Now we have a time step, proceed with the kick */ - kick_part(p, xp, new_dti, timeBase); + kick_part(p, xp, new_dti, e->ti_current, timeBase); + + // if (p->id == ICHECK) printParticle_single(p, xp); /* Number of updated particles */ updated++; if (p->gpart != NULL) g_updated++; + + ti_end += get_integer_timestep(p->time_bin); } - /* Minimal time for next end of time-step */ - ti_end_min = min(p->ti_end, ti_end_min); - ti_end_max = max(p->ti_end, ti_end_max); + if (p->id == ICHECK) + message("ti_current = %d dti=%lld ti_end=%lld (%f)", ti_current, + get_integer_timestep(p->time_bin), ti_end, + ti_end * e->timeBase); + ti_end_min = min((int)ti_end, ti_end_min); + ti_end_max = max((int)ti_end, ti_end_max); } } diff --git a/src/statistics.c b/src/statistics.c index 7a567a447..1130a790f 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -125,7 +125,10 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { const struct gpart *gp = (p->gpart != NULL) ? gp = p->gpart : NULL; /* Get useful variables */ - const float dt = (ti_current - (p->ti_begin + p->ti_end) / 2) * timeBase; + const integertime_t ti_begin = + get_integer_time_begin(ti_current, p->time_bin); + const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); + const float dt = (ti_current - (ti_begin + ti_end) / 2) * timeBase; const double x[3] = {p->x[0], p->x[1], p->x[2]}; float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; if (gp != NULL) { @@ -206,7 +209,10 @@ void stats_collect_gpart_mapper(void *map_data, int nr_gparts, if (gp->id_or_neg_offset < 0) continue; /* Get useful variables */ - const float dt = (ti_current - (gp->ti_begin + gp->ti_end) / 2) * timeBase; + const integertime_t ti_begin = + get_integer_time_begin(ti_current, gp->time_bin); + const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); + const float dt = (ti_current - (ti_begin + ti_end) / 2) * timeBase; const double x[3] = {gp->x[0], gp->x[1], gp->x[2]}; const float v[3] = {gp->v_full[0] + gp->a_grav[0] * dt, gp->v_full[1] + gp->a_grav[1] * dt, diff --git a/src/timeline.h b/src/timeline.h index 2d217a382..23d2e55e3 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -24,8 +24,11 @@ /* Local headers. */ #include "inline.h" +#include "intrinsics.h" -typedef long long integertime_t; +#include + +typedef unsigned long long integertime_t; typedef char timebin_t; /*! The number of time bins */ @@ -34,6 +37,8 @@ typedef char timebin_t; /*! The maximal number of timesteps in a simulation */ #define max_nr_timesteps (1LL << (num_time_bins + 1)) +//#define ceil_div(x ,y) (x + y - 1) / y + /** * @brief Returns the integer time interval corresponding to a time bin * @@ -45,6 +50,17 @@ static INLINE integertime_t get_integer_timestep(timebin_t bin) { return 1LL << (bin + 1); } +/** + * @brief Returns the time bin corresponding to a given time_step size. + * + * Assumes that integertime_t maps to an unsigned long long. + */ +static INLINE timebin_t get_time_bin(integertime_t time_step) { + + /* ((int) log_2(time_step)) - 1 */ + return 62 - intrinsics_clzll(time_step); +} + /** * @brief Returns the physical time interval corresponding to a time bin. * @@ -67,7 +83,10 @@ static INLINE integertime_t get_integer_time_begin(integertime_t ti_current, timebin_t bin) { const integertime_t dti = get_integer_timestep(bin); - return ti_current % dti; + if (dti == 0) + return 0; + else + return dti * ((ti_current - 1) / dti); } /** @@ -81,7 +100,10 @@ static INLINE integertime_t get_integer_time_end(integertime_t ti_current, timebin_t bin) { const integertime_t dti = get_integer_timestep(bin); - return ti_current % dti + dti; + if (dti == 0) + return 0; + else + return dti * ceil((double)ti_current / (double)dti); } /** diff --git a/src/timestep.h b/src/timestep.h index db52911ec..1ac934d3a 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -23,31 +23,34 @@ #include "../config.h" /* Local headers. */ -#include "const.h" #include "cooling.h" #include "debug.h" +#include "timeline.h" + /** * @brief Compute a valid integer time-step form a given time-step * * @param new_dt The time-step to convert. - * @param ti_begin The (integer) start of the previous time-step. - * @param ti_end The (integer) end of the previous time-step. + * @param old_bin The old time bin. + * @param ti_current The current time on the integer time-line. * @param timeBase_inv The inverse of the system's minimal time-step. */ -__attribute__((always_inline)) INLINE static int get_integer_timestep( - float new_dt, int ti_begin, int ti_end, double timeBase_inv) { +__attribute__((always_inline)) INLINE static int make_integer_timestep( + float new_dt, timebin_t old_bin, integertime_t ti_current, + double timeBase_inv) { /* Convert to integer time */ - int new_dti = (int)(new_dt * timeBase_inv); + integertime_t new_dti = (integertime_t)(new_dt * timeBase_inv); - /* Recover the current timestep */ - const int current_dti = ti_end - ti_begin; + /* Current time-step */ + integertime_t current_dti = get_integer_timestep(old_bin); + integertime_t ti_end = get_integer_time_end(ti_current, old_bin); /* Limit timestep increase */ - if (current_dti > 0) new_dti = min(new_dti, 2 * current_dti); + if (old_bin > 0) new_dti = min(new_dti, 2 * current_dti); /* Put this timestep on the time line */ - int dti_timeline = max_nr_timesteps; + integertime_t dti_timeline = max_nr_timesteps; while (new_dti < dti_timeline) dti_timeline /= 2; new_dti = dti_timeline; @@ -82,8 +85,8 @@ __attribute__((always_inline)) INLINE static int get_gpart_timestep( new_dt = max(new_dt, e->dt_min); /* Convert to integer time */ - const int new_dti = - get_integer_timestep(new_dt, gp->ti_begin, gp->ti_end, e->timeBase_inv); + const int new_dti = make_integer_timestep(new_dt, gp->time_bin, e->ti_current, + e->timeBase_inv); return new_dti; } @@ -138,8 +141,8 @@ __attribute__((always_inline)) INLINE static int get_part_timestep( new_dt = max(new_dt, e->dt_min); /* Convert to integer time */ - const int new_dti = - get_integer_timestep(new_dt, p->ti_begin, p->ti_end, e->timeBase_inv); + const int new_dti = make_integer_timestep(new_dt, p->time_bin, e->ti_current, + e->timeBase_inv); return new_dti; } -- GitLab From e8174afecb3f92704302b138eadc5628675fadad Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 20 Dec 2016 17:54:17 +0100 Subject: [PATCH 05/48] Post-merge fixes --- src/space.c | 4 ++-- tests/testDump.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/space.c b/src/space.c index a45cb68d3..7a6e34697 100644 --- a/src/space.c +++ b/src/space.c @@ -1555,7 +1555,7 @@ void space_split_recursive(struct space *s, struct cell *c, int *buff) { struct part *p = &parts[k]; struct xpart *xp = &xparts[k]; const float h = p->h; - const int ti_end = p->ti_end; + const int ti_end = get_integer_time_end(e->ti_current, p->time_bin); xp->x_diff[0] = 0.f; xp->x_diff[1] = 0.f; xp->x_diff[2] = 0.f; @@ -1565,7 +1565,7 @@ void space_split_recursive(struct space *s, struct cell *c, int *buff) { } for (int k = 0; k < gcount; k++) { struct gpart *gp = &gparts[k]; - const int ti_end = gp->ti_end; + const int ti_end = get_integer_time_end(e->ti_current, gp->time_bin); gp->x_diff[0] = 0.f; gp->x_diff[1] = 0.f; gp->x_diff[2] = 0.f; diff --git a/tests/testDump.c b/tests/testDump.c index 5f46d30a4..ab74a1b1f 100644 --- a/tests/testDump.c +++ b/tests/testDump.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) { /* Finalize the dump. */ dump_close(&d); - + /* Return a happy number. */ return 0; } -- GitLab From 70b8fb72e0666682bbcdb4d71891a91e8d53cacd Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 23 Dec 2016 16:26:31 +0100 Subject: [PATCH 06/48] Post-merge fix --- src/space.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/space.c b/src/space.c index 1e7ffd553..0801eeb85 100644 --- a/src/space.c +++ b/src/space.c @@ -1482,6 +1482,7 @@ void space_split_recursive(struct space *s, struct cell *c, int *buff) { struct part *parts = c->parts; struct gpart *gparts = c->gparts; struct xpart *xparts = c->xparts; + struct engine *e = s->e; /* If the buff is NULL, allocate it, and remember to free it. */ const int allocate_buffer = (buff == NULL); -- GitLab From 5d91cae27dfd20041a430d9d244145410123de22 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 24 Dec 2016 13:44:39 +0100 Subject: [PATCH 07/48] Started moving towards 50 time bins. Time-step of size 0 is assigned. --- src/active.h | 16 ++++++++----- src/cell.c | 8 +++---- src/cell.h | 8 +++---- src/engine.c | 6 ++--- src/engine.h | 8 +++---- src/hydro/Gadget2/hydro.h | 4 ++-- src/kick.h | 10 ++++---- src/runner.c | 48 +++++++++++++++++++++------------------ src/scheduler.c | 17 ++++++++------ src/space.c | 8 ++++--- src/timeline.h | 4 +--- src/timestep.h | 8 +++---- 12 files changed, 78 insertions(+), 67 deletions(-) diff --git a/src/active.h b/src/active.h index 2c9e1c8aa..edb276c5e 100644 --- a/src/active.h +++ b/src/active.h @@ -41,8 +41,8 @@ __attribute__((always_inline)) INLINE static int cell_is_drifted( #ifdef SWIFT_DEBUG_CHECKS if (c->ti_old > e->ti_current) error( - "Cell has been drifted too far forward in time! c->ti_old=%d " - "e->ti_current=%d", + "Cell has been drifted too far forward in time! c->ti_old=%lld " + "e->ti_current=%lld", c->ti_old, e->ti_current); #endif @@ -61,8 +61,10 @@ __attribute__((always_inline)) INLINE static int cell_is_active( #ifdef SWIFT_DEBUG_CHECKS if (c->ti_end_min < e->ti_current) - error("cell in an impossible time-zone! c->ti_end_min=%d e->ti_current=%d", - c->ti_end_min, e->ti_current); + error( + "cell in an impossible time-zone! c->ti_end_min=%lld " + "e->ti_current=%lld", + c->ti_end_min, e->ti_current); #endif return (c->ti_end_min == e->ti_current); @@ -80,8 +82,10 @@ __attribute__((always_inline)) INLINE static int cell_is_all_active( #ifdef SWIFT_DEBUG_CHECKS if (c->ti_end_max < e->ti_current) - error("cell in an impossible time-zone! c->ti_end_max=%d e->ti_current=%d", - c->ti_end_max, e->ti_current); + error( + "cell in an impossible time-zone! c->ti_end_max=%lld " + "e->ti_current=%lld", + c->ti_end_max, e->ti_current); #endif return (c->ti_end_max == e->ti_current); diff --git a/src/cell.c b/src/cell.c index c7b992bb7..1d580b929 100644 --- a/src/cell.c +++ b/src/cell.c @@ -715,10 +715,10 @@ void cell_clean_links(struct cell *c, void *data) { */ void cell_check_drift_point(struct cell *c, void *data) { - const int ti_current = *(int *)data; + integertime_t ti_current = *(int *)data; if (c->ti_old != ti_current && c->nodeID == engine_rank) - error("Cell in an incorrect time-zone! c->ti_old=%d ti_current=%d", + error("Cell in an incorrect time-zone! c->ti_old=%lld ti_current=%lld", c->ti_old, ti_current); } @@ -1007,8 +1007,8 @@ void cell_set_super(struct cell *c, struct cell *super) { void cell_drift(struct cell *c, const struct engine *e) { const double timeBase = e->timeBase; - const int ti_old = c->ti_old; - const int ti_current = e->ti_current; + const integertime_t ti_old = c->ti_old; + const integertime_t ti_current = e->ti_current; struct part *const parts = c->parts; struct xpart *const xparts = c->xparts; struct gpart *const gparts = c->gparts; diff --git a/src/cell.h b/src/cell.h index 3772cfe92..563a0af3f 100644 --- a/src/cell.h +++ b/src/cell.h @@ -67,7 +67,7 @@ struct pcell { /* Stats on this cell's particles. */ double h_max; - int ti_end_min, ti_end_max, ti_old; + integertime_t ti_end_min, ti_end_max, ti_old; /* Number of particles in this cell. */ int count, gcount; @@ -206,13 +206,13 @@ struct cell { #endif /*! Minimum end of (integer) time step in this cell. */ - int ti_end_min; + integertime_t ti_end_min; /*! Maximum end of (integer) time step in this cell. */ - int ti_end_max; + integertime_t ti_end_max; /*! Last (integer) time the cell's content was drifted forward in time. */ - int ti_old; + integertime_t ti_old; /*! Minimum dimension, i.e. smallest edge of this cell (min(width)). */ float dmin; diff --git a/src/engine.c b/src/engine.c index 453845252..fd641996f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1998,7 +1998,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements, void *extra_data) { /* Unpack the arguments. */ struct task *tasks = (struct task *)map_data; - const int ti_end = ((size_t *)extra_data)[0]; + const integertime_t ti_end = ((size_t *)extra_data)[0]; size_t *rebuild_space = &((size_t *)extra_data)[1]; struct scheduler *s = (struct scheduler *)(((size_t *)extra_data)[2]); @@ -2357,7 +2357,7 @@ void engine_collect_kick(struct cell *c) { /* Counters for the different quantities. */ int updated = 0, g_updated = 0; - int ti_end_min = max_nr_timesteps; + integertime_t ti_end_min = max_nr_timesteps; /* Only do something is the cell is non-empty */ if (c->count != 0 || c->gcount != 0) { @@ -2401,7 +2401,7 @@ void engine_collect_timestep(struct engine *e) { const ticks tic = getticks(); int updates = 0, g_updates = 0; - int ti_end_min = max_nr_timesteps; + integertime_t ti_end_min = max_nr_timesteps; const struct space *s = e->s; /* Collect the cell data. */ diff --git a/src/engine.h b/src/engine.h index a363d7d5b..72d54f6d2 100644 --- a/src/engine.h +++ b/src/engine.h @@ -114,11 +114,11 @@ struct engine { /* The previous system time. */ double timeOld; - int ti_old; + integertime_t ti_old; /* The current system time. */ double time; - int ti_current; + integertime_t ti_current; /* Time step */ double timeStep; @@ -128,7 +128,7 @@ struct engine { double timeBase_inv; /* Minimal ti_end for the next time-step */ - int ti_end_min; + integertime_t ti_end_min; /* Number of particles updated */ size_t updates, g_updates; @@ -139,7 +139,7 @@ struct engine { /* Snapshot information */ double timeFirstSnapshot; double deltaTimeSnapshot; - int ti_nextSnapshot; + integertime_t ti_nextSnapshot; char snapshotBaseName[200]; int snapshotCompression; struct UnitSystem *snapshotUnits; diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index e80ea9f0c..ace32c190 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -365,8 +365,8 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part *restrict p, const struct xpart *restrict xp, float dt, int t0, - int t1, double timeBase) { + struct part *restrict p, const struct xpart *restrict xp, float dt, + integertime_t t0, integertime_t t1, double timeBase) { const float h_inv = 1.f / p->h; diff --git a/src/kick.h b/src/kick.h index c2515e4f4..fe30a367f 100644 --- a/src/kick.h +++ b/src/kick.h @@ -44,8 +44,8 @@ __attribute__((always_inline)) INLINE static void kick_gpart( get_integer_time_begin(ti_current, gp->time_bin); const integertime_t old_ti_end = get_integer_time_end(ti_current, gp->time_bin); - const int ti_start = (old_ti_begin + old_ti_end) / 2; - const int ti_end = old_ti_end + new_dti / 2; + const integertime_t ti_start = (old_ti_begin + old_ti_end) / 2; + const integertime_t ti_end = old_ti_end + new_dti / 2; const float dt = (ti_end - ti_start) * timeBase; const float half_dt = (ti_end - old_ti_end) * timeBase; @@ -73,7 +73,7 @@ __attribute__((always_inline)) INLINE static void kick_gpart( * @param timeBase The minimal allowed time-step size. */ __attribute__((always_inline)) INLINE static void kick_part( - struct part *restrict p, struct xpart *restrict xp, int new_dti, + struct part *restrict p, struct xpart *restrict xp, integertime_t new_dti, integertime_t ti_current, double timeBase) { /* Compute the time step for this kick */ @@ -81,8 +81,8 @@ __attribute__((always_inline)) INLINE static void kick_part( get_integer_time_begin(ti_current, p->time_bin); const integertime_t old_ti_end = get_integer_time_end(ti_current, p->time_bin); - const int ti_start = (old_ti_begin + old_ti_end) / 2; - const int ti_end = old_ti_end + new_dti / 2; + const integertime_t ti_start = (old_ti_begin + old_ti_end) / 2; + const integertime_t ti_end = old_ti_end + new_dti / 2; const float dt = (ti_end - ti_start) * timeBase; const float half_dt = (ti_end - old_ti_end) * timeBase; diff --git a/src/runner.c b/src/runner.c index 2311e0d73..13705452d 100644 --- a/src/runner.c +++ b/src/runner.c @@ -114,7 +114,7 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, #include "runner_doiact_grav.h" #undef ICHECK -#define ICHECK -116650 +#define ICHECK 116650 /** * @brief Perform source terms @@ -594,7 +594,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xparts = c->xparts; int redo, count = c->count; const struct engine *e = r->e; - const int ti_current = e->ti_current; + const integertime_t ti_current = e->ti_current; const double timeBase = e->timeBase; const float target_wcount = e->hydro_properties->target_neighbours; const float max_wcount = @@ -837,7 +837,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { const struct engine *e = r->e; const double timeBase = e->timeBase; - const int ti_current = e->ti_current; + const integertime_t ti_current = e->ti_current; const int count = c->count; const int gcount = c->gcount; struct part *restrict parts = c->parts; @@ -855,7 +855,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { } int updated = 0, g_updated = 0; - int ti_end_min = max_nr_timesteps, ti_end_max = 0; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; /* No children? */ if (!c->split) { @@ -887,8 +887,8 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* Minimal time for next end of time-step */ const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); - ti_end_min = min((int)ti_end, ti_end_min); - ti_end_max = max((int)ti_end, ti_end_max); + ti_end_min = min(ti_end, ti_end_min); + ti_end_max = max(ti_end, ti_end_max); } } @@ -905,7 +905,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); if (p->id == ICHECK) - message("Particle in kick ti_end=%lld ti_current=%d", ti_end, + message("Particle in kick ti_end=%lld ti_current=%lld", ti_end, e->ti_current); /* If particle needs to be kicked */ @@ -918,10 +918,10 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); /* Compute the next timestep (hydro condition) */ - const int new_dti = get_part_timestep(p, xp, e); + const integertime_t new_dti = get_part_timestep(p, xp, e); if (p->id == ICHECK) - message("time_step=%d (%e)", new_dti, new_dti * e->timeBase); + message("time_step=%lld (%e)", new_dti, new_dti * e->timeBase); /* Now we have a time step, proceed with the kick */ kick_part(p, xp, new_dti, e->ti_current, timeBase); @@ -936,11 +936,11 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { } if (p->id == ICHECK) - message("ti_current = %d dti=%lld ti_end=%lld (%f)", ti_current, + message("ti_current = %lld dti=%lld ti_end=%lld (%f)", ti_current, get_integer_timestep(p->time_bin), ti_end, ti_end * e->timeBase); - ti_end_min = min((int)ti_end, ti_end_min); - ti_end_max = max((int)ti_end, ti_end_max); + ti_end_min = min(ti_end, ti_end_min); + ti_end_max = max(ti_end, ti_end_max); } } @@ -972,6 +972,8 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_kick); } +#ifdef WITH_MPI + /** * @brief Construct the cell properties from the received particles * @@ -989,8 +991,8 @@ void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { TIMER_TIC; - int ti_end_min = max_nr_timesteps; - int ti_end_max = 0; + integertime_t ti_end_min = max_nr_timesteps; + integertime_t ti_end_max = 0; float h_max = 0.f; /* If this cell is a leaf, collect the particle data. */ @@ -998,14 +1000,14 @@ void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { /* Collect everything... */ for (size_t k = 0; k < nr_parts; k++) { - const int ti_end = 0; // parts[k].ti_end; //MATTHIEU + const integertime_t ti_end = 0; // parts[k].ti_end; //MATTHIEU // if(ti_end < ti_current) error("Received invalid particle !"); ti_end_min = min(ti_end_min, ti_end); ti_end_max = max(ti_end_max, ti_end); h_max = max(h_max, parts[k].h); } for (size_t k = 0; k < nr_gparts; k++) { - const int ti_end = 0; // gparts[k].ti_end; //MATTHIEU + const integertime_t ti_end = 0; // gparts[k].ti_end; //MATTHIEU // if(ti_end < ti_current) error("Received invalid particle !"); ti_end_min = min(ti_end_min, ti_end); ti_end_max = max(ti_end_max, ti_end); @@ -1034,6 +1036,8 @@ void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_dorecv_cell); } +#endif /* WITH_MPI */ + /** * @brief The #runner main thread routine. * @@ -1084,8 +1088,8 @@ void *runner_main(void *data) { if (!cell_is_active(ci, e) && t->type != task_type_sort && t->type != task_type_send && t->type != task_type_recv) error( - "Task (type='%s/%s') should have been skipped ti_current=%d " - "c->ti_end_min=%d", + "Task (type='%s/%s') should have been skipped ti_current=%lld " + "c->ti_end_min=%lld", taskID_names[t->type], subtaskID_names[t->subtype], e->ti_current, ci->ti_end_min); @@ -1093,8 +1097,8 @@ void *runner_main(void *data) { if (!cell_is_active(ci, e) && t->type == task_type_sort && t->flags == 0) error( - "Task (type='%s/%s') should have been skipped ti_current=%d " - "c->ti_end_min=%d t->flags=%d", + "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); @@ -1103,8 +1107,8 @@ void *runner_main(void *data) { if (t->type != task_type_send && t->type != task_type_recv) error( - "Task (type='%s/%s') should have been skipped ti_current=%d " - "ci->ti_end_min=%d cj->ti_end_min=%d", + "Task (type='%s/%s') should have been skipped ti_current=%lld " + "ci->ti_end_min=%lld cj->ti_end_min=%lld", taskID_names[t->type], subtaskID_names[t->subtype], e->ti_current, ci->ti_end_min, cj->ti_end_min); } diff --git a/src/scheduler.c b/src/scheduler.c index a96a5923d..aca611710 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1056,7 +1056,7 @@ void scheduler_start(struct scheduler *s) { /* Check we have not missed an active task */ #ifdef SWIFT_DEBUG_CHECKS - const int ti_current = s->space->e->ti_current; + const integertime_t ti_current = s->space->e->ti_current; if (ti_current > 0) { @@ -1071,8 +1071,9 @@ void scheduler_start(struct scheduler *s) { if (ci->ti_end_min == ti_current && t->skip && t->type != task_type_sort && t->type) error( - "Task (type='%s/%s') should not have been skipped ti_current=%d " - "c->ti_end_min=%d", + "Task (type='%s/%s') should not have been skipped " + "ti_current=%lld " + "c->ti_end_min=%lld", taskID_names[t->type], subtaskID_names[t->subtype], ti_current, ci->ti_end_min); @@ -1080,8 +1081,9 @@ void scheduler_start(struct scheduler *s) { if (ci->ti_end_min == ti_current && t->skip && t->type == task_type_sort && t->flags == 0) error( - "Task (type='%s/%s') should not have been skipped ti_current=%d " - "c->ti_end_min=%d t->flags=%d", + "Task (type='%s/%s') should not have been skipped " + "ti_current=%lld " + "c->ti_end_min=%lld t->flags=%d", taskID_names[t->type], subtaskID_names[t->subtype], ti_current, ci->ti_end_min, t->flags); @@ -1090,8 +1092,9 @@ void scheduler_start(struct scheduler *s) { if ((ci->ti_end_min == ti_current || cj->ti_end_min == ti_current) && t->skip) error( - "Task (type='%s/%s') should not have been skipped ti_current=%d " - "ci->ti_end_min=%d cj->ti_end_min=%d", + "Task (type='%s/%s') should not have been skipped " + "ti_current=%lld " + "ci->ti_end_min=%lld cj->ti_end_min=%lld", taskID_names[t->type], subtaskID_names[t->subtype], ti_current, ci->ti_end_min, cj->ti_end_min); } diff --git a/src/space.c b/src/space.c index 0801eeb85..58c628c72 100644 --- a/src/space.c +++ b/src/space.c @@ -1477,7 +1477,7 @@ void space_split_recursive(struct space *s, struct cell *c, int *buff) { const int depth = c->depth; int maxdepth = 0; float h_max = 0.0f; - int ti_end_min = max_nr_timesteps, ti_end_max = 0; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; struct cell *temp; struct part *parts = c->parts; struct gpart *gparts = c->gparts; @@ -1565,7 +1565,8 @@ void space_split_recursive(struct space *s, struct cell *c, int *buff) { struct part *p = &parts[k]; struct xpart *xp = &xparts[k]; const float h = p->h; - const int ti_end = get_integer_time_end(e->ti_current, p->time_bin); + const integertime_t ti_end = + get_integer_time_end(e->ti_current, p->time_bin); xp->x_diff[0] = 0.f; xp->x_diff[1] = 0.f; xp->x_diff[2] = 0.f; @@ -1575,7 +1576,8 @@ void space_split_recursive(struct space *s, struct cell *c, int *buff) { } for (int k = 0; k < gcount; k++) { struct gpart *gp = &gparts[k]; - const int ti_end = get_integer_time_end(e->ti_current, gp->time_bin); + const integertime_t ti_end = + get_integer_time_end(e->ti_current, gp->time_bin); gp->x_diff[0] = 0.f; gp->x_diff[1] = 0.f; gp->x_diff[2] = 0.f; diff --git a/src/timeline.h b/src/timeline.h index 23d2e55e3..3ee8a1379 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -32,13 +32,11 @@ typedef unsigned long long integertime_t; typedef char timebin_t; /*! The number of time bins */ -#define num_time_bins 20 +#define num_time_bins 50 /*! The maximal number of timesteps in a simulation */ #define max_nr_timesteps (1LL << (num_time_bins + 1)) -//#define ceil_div(x ,y) (x + y - 1) / y - /** * @brief Returns the integer time interval corresponding to a time bin * diff --git a/src/timestep.h b/src/timestep.h index 1ac934d3a..d9778439a 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -85,8 +85,8 @@ __attribute__((always_inline)) INLINE static int get_gpart_timestep( new_dt = max(new_dt, e->dt_min); /* Convert to integer time */ - const int new_dti = make_integer_timestep(new_dt, gp->time_bin, e->ti_current, - e->timeBase_inv); + const integertime_t new_dti = make_integer_timestep( + new_dt, gp->time_bin, e->ti_current, e->timeBase_inv); return new_dti; } @@ -141,8 +141,8 @@ __attribute__((always_inline)) INLINE static int get_part_timestep( new_dt = max(new_dt, e->dt_min); /* Convert to integer time */ - const int new_dti = make_integer_timestep(new_dt, p->time_bin, e->ti_current, - e->timeBase_inv); + const integertime_t new_dti = make_integer_timestep( + new_dt, p->time_bin, e->ti_current, e->timeBase_inv); return new_dti; } -- GitLab From 9d579c4b16a82468af56a2eacbce6f83e38945fb Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 26 Dec 2016 16:31:12 +0100 Subject: [PATCH 08/48] Can now get the first few time-steps with a correct size. --- src/cell.c | 2 +- src/const.h | 2 ++ src/drift.h | 6 +++--- src/engine.c | 5 +++++ src/runner.c | 7 ------- src/runner_doiact_grav.h | 2 -- src/space.c | 2 +- src/space.h | 2 +- src/timeline.h | 2 +- src/timestep.h | 30 ++++++++++++++++++++++-------- 10 files changed, 36 insertions(+), 24 deletions(-) diff --git a/src/cell.c b/src/cell.c index 1d580b929..eb46f8804 100644 --- a/src/cell.c +++ b/src/cell.c @@ -715,7 +715,7 @@ void cell_clean_links(struct cell *c, void *data) { */ void cell_check_drift_point(struct cell *c, void *data) { - integertime_t ti_current = *(int *)data; + integertime_t ti_current = *(integertime_t *)data; if (c->ti_old != ti_current && c->nodeID == engine_rank) error("Cell in an incorrect time-zone! c->ti_old=%lld ti_current=%lld", diff --git a/src/const.h b/src/const.h index c290a3e73..f0ee63180 100644 --- a/src/const.h +++ b/src/const.h @@ -59,4 +59,6 @@ #define SOURCETERMS_NONE //#define SOURCETERMS_SN_FEEDBACK +#define ICHECK 116650 + #endif /* SWIFT_CONST_H */ diff --git a/src/drift.h b/src/drift.h index bd1b35926..478971e30 100644 --- a/src/drift.h +++ b/src/drift.h @@ -39,8 +39,8 @@ * @param ti_current Integer end of time-step */ __attribute__((always_inline)) INLINE static void drift_gpart( - struct gpart *restrict gp, float dt, double timeBase, int ti_old, - int ti_current) { + struct gpart *restrict gp, float dt, double timeBase, integertime_t ti_old, + integertime_t ti_current) { /* Drift... */ gp->x[0] += gp->v_full[0] * dt; gp->x[1] += gp->v_full[1] * dt; @@ -64,7 +64,7 @@ __attribute__((always_inline)) INLINE static void drift_gpart( */ __attribute__((always_inline)) INLINE static void drift_part( struct part *restrict p, struct xpart *restrict xp, float dt, - double timeBase, int ti_old, int ti_current) { + double timeBase, integertime_t ti_old, integertime_t ti_current) { /* Drift... */ p->x[0] += xp->v_full[0] * dt; diff --git a/src/engine.c b/src/engine.c index fd641996f..60630ec72 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2683,9 +2683,14 @@ void engine_step(struct engine *e) { engine_launch(e, e->nr_threads); TIMER_TOC(timer_runners); +#ifdef SWIFT_DEBUG_CHECKS for (size_t i = 0; i < e->s->nr_parts; ++i) { if (e->s->parts[i].time_bin == 0) error("Particle in bin 0"); } +#endif + + /* if(e->step > 2) */ + /* error("Done"); */ /* Save some statistics */ if (e->time - e->timeLastStatistics >= e->deltaTimeStatistics) { diff --git a/src/runner.c b/src/runner.c index 13705452d..c457f495f 100644 --- a/src/runner.c +++ b/src/runner.c @@ -113,9 +113,6 @@ const char runner_flip[27] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, #include "runner_doiact_fft.h" #include "runner_doiact_grav.h" -#undef ICHECK -#define ICHECK 116650 - /** * @brief Perform source terms * @@ -972,8 +969,6 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_kick); } -#ifdef WITH_MPI - /** * @brief Construct the cell properties from the received particles * @@ -1036,8 +1031,6 @@ void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_dorecv_cell); } -#endif /* WITH_MPI */ - /** * @brief The #runner main thread routine. * diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 59a5ae496..9d2606ceb 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,8 +25,6 @@ #include "gravity.h" #include "part.h" -#define ICHECK -1000 - /** * @brief Compute the recursive upward sweep, i.e. construct the * multipoles in a cell hierarchy. diff --git a/src/space.c b/src/space.c index 58c628c72..86611d381 100644 --- a/src/space.c +++ b/src/space.c @@ -1988,7 +1988,7 @@ void space_link_cleanup(struct space *s) { * @param s The #space to check. * @param ti_current The (integer) time. */ -void space_check_drift_point(struct space *s, int ti_current) { +void space_check_drift_point(struct space *s, integertime_t ti_current) { /* Recursively check all cells */ space_map_cells_pre(s, 1, cell_check_drift_point, &ti_current); diff --git a/src/space.h b/src/space.h index 4aea2a075..51a4f2a0d 100644 --- a/src/space.h +++ b/src/space.h @@ -185,7 +185,7 @@ void space_do_gparts_sort(); void space_init_parts(struct space *s); void space_init_gparts(struct space *s); void space_link_cleanup(struct space *s); -void space_check_drift_point(struct space *s, int ti_current); +void space_check_drift_point(struct space *s, integertime_t ti_current); void space_clean(struct space *s); #endif /* SWIFT_SPACE_H */ diff --git a/src/timeline.h b/src/timeline.h index 3ee8a1379..d9691ef84 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -101,7 +101,7 @@ static INLINE integertime_t get_integer_time_end(integertime_t ti_current, if (dti == 0) return 0; else - return dti * ceil((double)ti_current / (double)dti); + return dti * ceill((double)ti_current / (double)dti); } /** diff --git a/src/timestep.h b/src/timestep.h index d9778439a..c7529bd04 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -35,30 +35,40 @@ * @param ti_current The current time on the integer time-line. * @param timeBase_inv The inverse of the system's minimal time-step. */ -__attribute__((always_inline)) INLINE static int make_integer_timestep( - float new_dt, timebin_t old_bin, integertime_t ti_current, - double timeBase_inv) { +__attribute__((always_inline)) INLINE static integertime_t +make_integer_timestep(float new_dt, timebin_t old_bin, integertime_t ti_current, + double timeBase_inv, int verbose) { /* Convert to integer time */ integertime_t new_dti = (integertime_t)(new_dt * timeBase_inv); + if (verbose) message("new_dti=%lld", new_dti); + /* Current time-step */ integertime_t current_dti = get_integer_timestep(old_bin); integertime_t ti_end = get_integer_time_end(ti_current, old_bin); + if (verbose) + message("current_dti=%lld old_bin=%d ti_end=%lld", current_dti, old_bin, + ti_end); + /* Limit timestep increase */ if (old_bin > 0) new_dti = min(new_dti, 2 * current_dti); /* Put this timestep on the time line */ integertime_t dti_timeline = max_nr_timesteps; - while (new_dti < dti_timeline) dti_timeline /= 2; + while (new_dti < dti_timeline) dti_timeline /= 2LL; new_dti = dti_timeline; + if (verbose) message("new_dti=%lld", new_dti); + /* Make sure we are allowed to increase the timestep size */ if (new_dti > current_dti) { if ((max_nr_timesteps - ti_end) % new_dti > 0) new_dti = current_dti; } + if (verbose) message("new_dti=%lld", new_dti); + return new_dti; } @@ -68,7 +78,7 @@ __attribute__((always_inline)) INLINE static int make_integer_timestep( * @param gp The #gpart. * @param e The #engine (used to get some constants). */ -__attribute__((always_inline)) INLINE static int get_gpart_timestep( +__attribute__((always_inline)) INLINE static integertime_t get_gpart_timestep( const struct gpart *restrict gp, const struct engine *restrict e) { const float new_dt_external = external_gravity_timestep( @@ -86,7 +96,7 @@ __attribute__((always_inline)) INLINE static int get_gpart_timestep( /* Convert to integer time */ const integertime_t new_dti = make_integer_timestep( - new_dt, gp->time_bin, e->ti_current, e->timeBase_inv); + new_dt, gp->time_bin, e->ti_current, e->timeBase_inv, 0); return new_dti; } @@ -98,7 +108,7 @@ __attribute__((always_inline)) INLINE static int get_gpart_timestep( * @param xp The #xpart partner of p. * @param e The #engine (used to get some constants). */ -__attribute__((always_inline)) INLINE static int get_part_timestep( +__attribute__((always_inline)) INLINE static integertime_t get_part_timestep( const struct part *restrict p, const struct xpart *restrict xp, const struct engine *restrict e) { @@ -140,9 +150,13 @@ __attribute__((always_inline)) INLINE static int get_part_timestep( new_dt = min(new_dt, e->dt_max); new_dt = max(new_dt, e->dt_min); + if (p->id == ICHECK) message("new_dt=%e", new_dt); + /* Convert to integer time */ const integertime_t new_dti = make_integer_timestep( - new_dt, p->time_bin, e->ti_current, e->timeBase_inv); + new_dt, p->time_bin, e->ti_current, e->timeBase_inv, p->id == ICHECK); + + if (p->id == ICHECK) message("new_dti=%lld", new_dti); return new_dti; } -- GitLab From 4799b1981b4efbac7facca9e8a33c5011b0cb7f3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 27 Dec 2016 15:47:12 +0100 Subject: [PATCH 09/48] Also make use of the new data type for time in the space --- src/const.h | 2 +- src/hydro/Gadget2/hydro.h | 4 ++-- src/space.c | 4 ++-- src/timeline.h | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/const.h b/src/const.h index f0ee63180..4b46ec1cb 100644 --- a/src/const.h +++ b/src/const.h @@ -59,6 +59,6 @@ #define SOURCETERMS_NONE //#define SOURCETERMS_SN_FEEDBACK -#define ICHECK 116650 +#define ICHECK -116650 #endif /* SWIFT_CONST_H */ diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index ace32c190..9c5f51160 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -288,8 +288,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_prepare_force( - struct part *restrict p, struct xpart *restrict xp, int ti_current, - double timeBase) { + struct part *restrict p, struct xpart *restrict xp, + integertime_t ti_current, double timeBase) { const float fac_mu = 1.f; /* Will change with cosmological integration */ diff --git a/src/space.c b/src/space.c index 86611d381..23e97d998 100644 --- a/src/space.c +++ b/src/space.c @@ -246,7 +246,7 @@ void space_regrid(struct space *s, int verbose) { const size_t nr_parts = s->nr_parts; const ticks tic = getticks(); - const int ti_current = (s->e != NULL) ? s->e->ti_current : 0; + const integertime_t ti_current = (s->e != NULL) ? s->e->ti_current : 0; /* Run through the cells and get the current h_max. */ // tic = getticks(); @@ -480,7 +480,7 @@ void space_rebuild(struct space *s, int verbose) { size_t nr_parts = s->nr_parts; size_t nr_gparts = s->nr_gparts; struct cell *restrict cells_top = s->cells_top; - const int ti_current = (s->e != NULL) ? s->e->ti_current : 0; + const integertime_t ti_current = (s->e != NULL) ? s->e->ti_current : 0; /* Run through the particles and get their cell index. Allocates an index that is larger than the number of particles to avoid diff --git a/src/timeline.h b/src/timeline.h index d9691ef84..88f0c6f48 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -56,7 +56,7 @@ static INLINE integertime_t get_integer_timestep(timebin_t bin) { static INLINE timebin_t get_time_bin(integertime_t time_step) { /* ((int) log_2(time_step)) - 1 */ - return 62 - intrinsics_clzll(time_step); + return (timebin_t)(62 - intrinsics_clzll(time_step)); } /** -- GitLab From bec5932c874724e550e8afb8ab78f708db917fb4 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 27 Dec 2016 20:30:40 +0100 Subject: [PATCH 10/48] Statistics are now correct as well. --- examples/SedovBlast_3D/makeIC.py | 1 - src/statistics.c | 35 +++++++++++++++++++++----------- src/timeline.h | 4 ++-- src/timestep.h | 17 ++++++++-------- 4 files changed, 34 insertions(+), 23 deletions(-) diff --git a/examples/SedovBlast_3D/makeIC.py b/examples/SedovBlast_3D/makeIC.py index 7d1a78188..e1b743c6c 100644 --- a/examples/SedovBlast_3D/makeIC.py +++ b/examples/SedovBlast_3D/makeIC.py @@ -54,7 +54,6 @@ u[:] = P0 / (rho0 * (gamma - 1)) # Make the central particles detonate index = argsort(r) u[index[0:N_inject]] = E0 / (N_inject * m[0]) -print ids[index[0:N_inject]] #-------------------------------------------------- diff --git a/src/statistics.c b/src/statistics.c index 85b130f4d..55b76eba9 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -104,8 +104,8 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { const struct part *restrict parts = (struct part *)map_data; const struct xpart *restrict xparts = s->xparts + (ptrdiff_t)(parts - s->parts); - const int ti_current = s->e->ti_current; - const double timeBase = s->e->timeBase; + // const integertime_t ti_current = s->e->ti_current; + // const double timeBase = s->e->timeBase; const double time = s->e->time; struct statistics *const global_stats = data->stats; @@ -126,10 +126,13 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { const struct gpart *gp = (p->gpart != NULL) ? gp = p->gpart : NULL; /* Get useful variables */ - const integertime_t ti_begin = - get_integer_time_begin(ti_current, p->time_bin); - const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); - const float dt = (ti_current - (ti_begin + ti_end) / 2) * timeBase; + // const integertime_t ti_begin = + // get_integer_time_begin(ti_current, p->time_bin); + // const integertime_t ti_end = get_integer_time_end(ti_current, + // p->time_bin); + // const integertime_t dti = get_integer_timestep(p->time_bin); + const float dt = + 0.f; //(ti_current - (ti_begin + ti_end) / 2) * timeBase; //MATTHIEU const double x[3] = {p->x[0], p->x[1], p->x[2]}; float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; if (gp != NULL) { @@ -143,6 +146,12 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { const float m = hydro_get_mass(p); + /* if (p->id == ICHECK) */ + /* message("bin=%d dti=%lld ti_begin=%lld ti_end=%lld dt=%e v=[%e %e %e]", + */ + /* p->time_bin, dti, ti_begin, ti_end, */ + /* dt, v[0], v[1], v[2]); */ + /* Collect mass */ stats.mass += m; @@ -188,8 +197,8 @@ void stats_collect_gpart_mapper(void *map_data, int nr_gparts, const struct index_data *data = (struct index_data *)extra_data; const struct space *s = data->s; const struct gpart *restrict gparts = (struct gpart *)map_data; - const int ti_current = s->e->ti_current; - const double timeBase = s->e->timeBase; + // const integertime_t ti_current = s->e->ti_current; + // const double timeBase = s->e->timeBase; const double time = s->e->time; struct statistics *const global_stats = data->stats; @@ -211,10 +220,12 @@ void stats_collect_gpart_mapper(void *map_data, int nr_gparts, if (gp->id_or_neg_offset < 0) continue; /* Get useful variables */ - const integertime_t ti_begin = - get_integer_time_begin(ti_current, gp->time_bin); - const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); - const float dt = (ti_current - (ti_begin + ti_end) / 2) * timeBase; + // const integertime_t ti_begin = + // get_integer_time_begin(ti_current, gp->time_bin); + // const integertime_t ti_end = get_integer_time_end(ti_current, + // gp->time_bin); + const float dt = + 0.f; //(ti_current - (ti_begin + ti_end) / 2) * timeBase; // MATTHIEU const double x[3] = {gp->x[0], gp->x[1], gp->x[2]}; const float v[3] = {gp->v_full[0] + gp->a_grav[0] * dt, gp->v_full[1] + gp->a_grav[1] * dt, diff --git a/src/timeline.h b/src/timeline.h index 88f0c6f48..b6c411411 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -44,7 +44,7 @@ typedef char timebin_t; */ static INLINE integertime_t get_integer_timestep(timebin_t bin) { - if (bin == 0) return 0; + if (bin <= 0) return 0; return 1LL << (bin + 1); } @@ -101,7 +101,7 @@ static INLINE integertime_t get_integer_time_end(integertime_t ti_current, if (dti == 0) return 0; else - return dti * ceill((double)ti_current / (double)dti); + return dti * ceil((double)ti_current / (double)dti); } /** diff --git a/src/timestep.h b/src/timestep.h index c7529bd04..10e450987 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -42,15 +42,16 @@ make_integer_timestep(float new_dt, timebin_t old_bin, integertime_t ti_current, /* Convert to integer time */ integertime_t new_dti = (integertime_t)(new_dt * timeBase_inv); - if (verbose) message("new_dti=%lld", new_dti); + /* if (verbose) message("new_dti=%lld", new_dti); */ /* Current time-step */ integertime_t current_dti = get_integer_timestep(old_bin); integertime_t ti_end = get_integer_time_end(ti_current, old_bin); - if (verbose) - message("current_dti=%lld old_bin=%d ti_end=%lld", current_dti, old_bin, - ti_end); + /* if (verbose) */ + /* message("current_dti=%lld old_bin=%d ti_end=%lld", current_dti, old_bin, + */ + /* ti_end); */ /* Limit timestep increase */ if (old_bin > 0) new_dti = min(new_dti, 2 * current_dti); @@ -60,14 +61,14 @@ make_integer_timestep(float new_dt, timebin_t old_bin, integertime_t ti_current, while (new_dti < dti_timeline) dti_timeline /= 2LL; new_dti = dti_timeline; - if (verbose) message("new_dti=%lld", new_dti); + /* if (verbose) message("new_dti=%lld", new_dti); */ /* Make sure we are allowed to increase the timestep size */ if (new_dti > current_dti) { if ((max_nr_timesteps - ti_end) % new_dti > 0) new_dti = current_dti; } - if (verbose) message("new_dti=%lld", new_dti); + /* if (verbose) message("new_dti=%lld", new_dti); */ return new_dti; } @@ -150,13 +151,13 @@ __attribute__((always_inline)) INLINE static integertime_t get_part_timestep( new_dt = min(new_dt, e->dt_max); new_dt = max(new_dt, e->dt_min); - if (p->id == ICHECK) message("new_dt=%e", new_dt); + /* if (p->id == ICHECK) message("new_dt=%e", new_dt); */ /* Convert to integer time */ const integertime_t new_dti = make_integer_timestep( new_dt, p->time_bin, e->ti_current, e->timeBase_inv, p->id == ICHECK); - if (p->id == ICHECK) message("new_dti=%lld", new_dti); + /* if (p->id == ICHECK) message("new_dti=%lld", new_dti); */ return new_dti; } -- GitLab From 563e01f9b62bd71f250536ef89055e84ac588dd3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Tue, 27 Dec 2016 22:04:20 +0100 Subject: [PATCH 11/48] Cell reception task also updated to new time line. --- src/runner.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/runner.c b/src/runner.c index c457f495f..4a3ba2f85 100644 --- a/src/runner.c +++ b/src/runner.c @@ -979,10 +979,10 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { const struct part *restrict parts = c->parts; - // const struct gpart *restrict gparts = c->gparts; + const struct gpart *restrict gparts = c->gparts; const size_t nr_parts = c->count; const size_t nr_gparts = c->gcount; - const int ti_current = r->e->ti_current; + const integertime_t ti_current = r->e->ti_current; TIMER_TIC; @@ -995,14 +995,16 @@ void runner_do_recv_cell(struct runner *r, struct cell *c, int timer) { /* Collect everything... */ for (size_t k = 0; k < nr_parts; k++) { - const integertime_t ti_end = 0; // parts[k].ti_end; //MATTHIEU + const integertime_t ti_end = + get_integer_time_end(ti_current, parts[k].time_bin); // if(ti_end < ti_current) error("Received invalid particle !"); ti_end_min = min(ti_end_min, ti_end); ti_end_max = max(ti_end_max, ti_end); h_max = max(h_max, parts[k].h); } for (size_t k = 0; k < nr_gparts; k++) { - const integertime_t ti_end = 0; // gparts[k].ti_end; //MATTHIEU + const integertime_t ti_end = + get_integer_time_end(ti_current, gparts[k].time_bin); // if(ti_end < ti_current) error("Received invalid particle !"); ti_end_min = min(ti_end_min, ti_end); ti_end_max = max(ti_end_max, ti_end); -- GitLab From bb13af4cc50b67741971791e85c5a69fb7291b89 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 28 Dec 2016 15:46:57 +0100 Subject: [PATCH 12/48] Split the kick task into two different tasks --- src/cell.c | 3 +- src/cell.h | 7 ++- src/engine.c | 75 +++++++++++++++++------------ src/kick.h | 8 ++++ src/runner.c | 123 +++++++++++++++++++++++++++++++++++++++++++++++- src/scheduler.c | 11 +++-- src/space.c | 3 +- src/task.c | 11 +++-- src/task.h | 3 +- 9 files changed, 199 insertions(+), 45 deletions(-) diff --git a/src/cell.c b/src/cell.c index eb46f8804..a8281a292 100644 --- a/src/cell.c +++ b/src/cell.c @@ -971,7 +971,8 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { if (c->ghost != NULL) scheduler_activate(s, c->ghost); if (c->init != NULL) scheduler_activate(s, c->init); if (c->drift != NULL) scheduler_activate(s, c->drift); - if (c->kick != NULL) scheduler_activate(s, c->kick); + if (c->kick1 != NULL) scheduler_activate(s, c->kick1); + if (c->kick2 != NULL) scheduler_activate(s, c->kick2); if (c->cooling != NULL) scheduler_activate(s, c->cooling); if (c->sourceterms != NULL) scheduler_activate(s, c->sourceterms); diff --git a/src/cell.h b/src/cell.h index 563a0af3f..783a1fa77 100644 --- a/src/cell.h +++ b/src/cell.h @@ -150,8 +150,11 @@ struct cell { /*! The drift task */ struct task *drift; - /*! The kick task */ - struct task *kick; + /*! The first kick task */ + struct task *kick1; + + /*! The second kick task */ + struct task *kick2; /*! Task constructing the multipole from the particles */ struct task *grav_up; diff --git a/src/engine.c b/src/engine.c index 60630ec72..f1ddc3d4e 100644 --- a/src/engine.c +++ b/src/engine.c @@ -140,8 +140,12 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { c->init = scheduler_addtask(s, task_type_init, task_subtype_none, 0, 0, c, NULL, 0); - c->kick = scheduler_addtask(s, task_type_kick, task_subtype_none, 0, 0, c, - NULL, 0); + /* Add the two half kicks */ + c->kick1 = scheduler_addtask(s, task_type_kick1, task_subtype_none, 0, 0, + c, NULL, 0); + + c->kick2 = scheduler_addtask(s, task_type_kick2, task_subtype_none, 0, 0, + c, NULL, 0); /* Add the drift task and dependency. */ c->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, 0, 0, @@ -692,7 +696,7 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj, #ifdef EXTRA_HYDRO_LOOP - scheduler_addunlock(s, t_gradient, ci->super->kick); + scheduler_addunlock(s, t_gradient, ci->super->kick2); scheduler_addunlock(s, ci->super->extra_ghost, t_gradient); @@ -707,7 +711,7 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj, #else /* The send_rho task should unlock the super-cell's kick task. */ - scheduler_addunlock(s, t_rho, ci->super->kick); + scheduler_addunlock(s, t_rho, ci->super->kick2); /* The send_rho task depends on the cell's ghost task. */ scheduler_addunlock(s, ci->super->ghost, t_rho); @@ -719,7 +723,7 @@ void engine_addtasks_send(struct engine *e, struct cell *ci, struct cell *cj, #endif /* The super-cell's kick task should unlock the send_ti task. */ - if (t_ti != NULL) scheduler_addunlock(s, ci->super->kick, t_ti); + if (t_ti != NULL) scheduler_addunlock(s, ci->super->kick2, t_ti); } /* Add them to the local cell. */ @@ -1454,7 +1458,7 @@ static inline void engine_make_gravity_dependencies(struct scheduler *sched, /* init --> gravity --> kick */ scheduler_addunlock(sched, c->super->init, gravity); - scheduler_addunlock(sched, gravity, c->super->kick); + scheduler_addunlock(sched, gravity, c->super->kick2); /* grav_up --> gravity ( --> kick) */ scheduler_addunlock(sched, c->super->grav_up, gravity); @@ -1473,7 +1477,7 @@ static inline void engine_make_external_gravity_dependencies( /* init --> external gravity --> kick */ scheduler_addunlock(sched, c->super->init, gravity); - scheduler_addunlock(sched, gravity, c->super->kick); + scheduler_addunlock(sched, gravity, c->super->kick2); } /** @@ -1512,7 +1516,7 @@ void engine_link_gravity_tasks(struct engine *e) { /* Gather the multipoles --> mm interaction --> kick */ scheduler_addunlock(sched, gather, t); - scheduler_addunlock(sched, t, t->ci->super->kick); + scheduler_addunlock(sched, t, t->ci->super->kick2); /* init --> mm interaction */ scheduler_addunlock(sched, t->ci->super->init, t); @@ -1596,14 +1600,16 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, struct task *gradient, struct task *force, struct cell *c) { - /* init --> density loop --> ghost --> gradient loop --> extra_ghost */ - /* extra_ghost --> force loop --> kick */ + /* kick1 --> init --> density loop --> ghost --> gradient loop --> extra_ghost + */ + /* extra_ghost --> force loop --> kick2 */ + scheduler_addunlock(sched, c->super->kick1, c->super->init); scheduler_addunlock(sched, c->super->init, density); scheduler_addunlock(sched, density, c->super->ghost); scheduler_addunlock(sched, c->super->ghost, gradient); scheduler_addunlock(sched, gradient, c->super->extra_ghost); scheduler_addunlock(sched, c->super->extra_ghost, force); - scheduler_addunlock(sched, force, c->super->kick); + scheduler_addunlock(sched, force, c->super->kick2); } #else @@ -1620,11 +1626,12 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, struct task *density, struct task *force, struct cell *c) { - /* init --> density loop --> ghost --> force loop --> kick */ + /* kick1 --> init --> density loop --> ghost --> force loop --> kick2 */ + scheduler_addunlock(sched, c->super->kick1, c->super->init); scheduler_addunlock(sched, c->super->init, density); scheduler_addunlock(sched, density, c->super->ghost); scheduler_addunlock(sched, c->super->ghost, force); - scheduler_addunlock(sched, force, c->super->kick); + scheduler_addunlock(sched, force, c->super->kick2); } #endif @@ -1818,18 +1825,21 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { } #endif } - /* Cooling tasks should depend on kick and unlock sourceterms */ - else if (t->type == task_type_cooling) { - scheduler_addunlock(sched, t->ci->kick, t); - } - /* source terms depend on cooling if performed, else on kick. It is the last - task */ - else if (t->type == task_type_sourceterms) { - if (e->policy == engine_policy_cooling) - scheduler_addunlock(sched, t->ci->cooling, t); - else - scheduler_addunlock(sched, t->ci->kick, t); - } + + /* /\* Cooling tasks should depend on kick and unlock sourceterms *\/ */ + /* else if (t->type == task_type_cooling) { */ + /* scheduler_addunlock(sched, t->ci->kick, t); */ + /* } */ + /* /\* source terms depend on cooling if performed, else on kick. It is the + * last */ + /* task *\/ */ + /* else if (t->type == task_type_sourceterms) { */ + /* if (e->policy == engine_policy_cooling) */ + /* scheduler_addunlock(sched, t->ci->cooling, t); */ + /* else */ + /* scheduler_addunlock(sched, t->ci->kick, t); */ + /* } */ + // MATTHIEU } } @@ -2121,7 +2131,11 @@ void engine_marktasks_mapper(void *map_data, int num_elements, } /* Kick? */ - else if (t->type == task_type_kick) { + else if (t->type == task_type_kick1) { + if (t->ci->ti_end_min <= ti_end) scheduler_activate(s, t); + } + + else if (t->type == task_type_kick2) { t->ci->updated = 0; t->ci->g_updated = 0; if (t->ci->ti_end_min <= ti_end) scheduler_activate(s, t); @@ -2353,7 +2367,7 @@ void engine_barrier(struct engine *e, int tid) { void engine_collect_kick(struct cell *c) { /* Skip super-cells (Their values are already set) */ - if (c->kick != NULL) return; + if (c->kick2 != NULL) return; /* Counters for the different quantities. */ int updated = 0, g_updated = 0; @@ -2505,9 +2519,10 @@ void engine_skip_force_and_kick(struct engine *e) { struct task *t = &tasks[i]; /* Skip everything that updates the particles */ - if (t->subtype == task_subtype_force || t->type == task_type_kick || - t->type == task_type_cooling || t->type == task_type_sourceterms || - t->type == task_type_drift) + if (t->subtype == + task_subtype_force || // t->type == task_type_kick || //MATTHIEU + t->type == task_type_cooling || + t->type == task_type_sourceterms || t->type == task_type_drift) t->skip = 1; } } diff --git a/src/kick.h b/src/kick.h index fe30a367f..2a21a97ab 100644 --- a/src/kick.h +++ b/src/kick.h @@ -27,6 +27,8 @@ #include "debug.h" #include "timeline.h" +#if 0 + /** * @brief Perform the 'kick' operation on a #gpart * @@ -126,4 +128,10 @@ __attribute__((always_inline)) INLINE static void kick_part( if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt, half_dt); } +#endif + +__attribute__((always_inline)) INLINE static void kick_part( + struct part *restrict p, struct xpart *restrict xp, integertime_t ti_start, + integertime_t ti_end, integertime_t ti_current) {} + #endif /* SWIFT_KICK_H */ diff --git a/src/runner.c b/src/runner.c index 4a3ba2f85..2beea87e3 100644 --- a/src/runner.c +++ b/src/runner.c @@ -823,6 +823,121 @@ void runner_do_drift_mapper(void *map_data, int num_elements, } } +void runner_do_kick1(struct runner *r, struct cell *c, int timer) {} + +void runner_do_kick2(struct runner *r, struct cell *c, int timer) {} + +/** + * @brief Kick particles in momentum space and collect statistics. + * + * @param r The runner thread. + * @param c The cell. + * @param timer Are we timing this ? + */ +void runner_do_kick(struct runner *r, struct cell *c, int timer) { + + const struct engine *e = r->e; + // const double timeBase = e->timeBase; + const integertime_t ti_current = e->ti_current; + const int count = c->count; + // const int gcount = c->gcount; + struct part *restrict parts = c->parts; + struct xpart *restrict xparts = c->xparts; + // struct gpart *restrict gparts = c->gparts; + const double const_G = e->physical_constants->const_newton_G; + + TIMER_TIC; + + /* Anything to do here? */ + if (!cell_is_active(c, e)) { + c->updated = 0; + c->g_updated = 0; + return; + } + + int updated = 0, g_updated = 0; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; + + /* No children? */ + if (!c->split) { + + /* Loop over the particles and kick the active ones. */ + for (int k = 0; k < count; k++) { + + /* Get a handle on the part. */ + struct part *restrict p = &parts[k]; + struct xpart *restrict xp = &xparts[k]; + + /* If particle needs to be kicked */ + if (part_is_active(p, e)) { + + /* First, finish the force loop */ + hydro_end_force(p); + if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); + + 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); + const integertime_t ti_end = + get_integer_time_end(ti_current, p->time_bin); + + /* And finish the time-step with a second half-kick */ + kick_part(p, xp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current); + } + } + + /* Loop over the particles and kick the active ones. */ + for (int k = 0; k < count; k++) { + + /* Get a handle on the part. */ + struct part *restrict p = &parts[k]; + struct xpart *restrict xp = &xparts[k]; + + /* If particle needs to be kicked */ + if (part_is_active(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); + const integertime_t ti_end = + get_integer_time_end(ti_current, p->time_bin); + + /* And finish the time-step with a second half-kick */ + kick_part(p, xp, ti_begin, ti_end + ti_step / 2, ti_current); + } + } + } + + /* Otherwise, aggregate data from children. */ + else { + + /* Loop over the progeny. */ + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) { + struct cell *restrict cp = c->progeny[k]; + + /* Recurse */ + runner_do_kick(r, cp, 0); + + /* And aggregate */ + updated += cp->updated; + g_updated += cp->g_updated; + ti_end_min = min(cp->ti_end_min, ti_end_min); + ti_end_max = max(cp->ti_end_max, ti_end_max); + } + } + + /* Store the values. */ + c->updated = updated; + c->g_updated = g_updated; + c->ti_end_min = ti_end_min; + c->ti_end_max = ti_end_max; + + if (timer) TIMER_TOC(timer_kick); +} + +#ifdef OLD_KICK + /** * @brief Kick particles in momentum space and collect statistics. * @@ -968,6 +1083,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_kick); } +#endif /** * @brief Construct the cell properties from the received particles @@ -1192,8 +1308,11 @@ void *runner_main(void *data) { case task_type_drift: runner_do_drift(r, ci, 1); break; - case task_type_kick: - runner_do_kick(r, ci, 1); + case task_type_kick1: + runner_do_kick1(r, ci, 1); + break; + case task_type_kick2: + runner_do_kick2(r, ci, 1); break; #ifdef WITH_MPI case task_type_send: diff --git a/src/scheduler.c b/src/scheduler.c index aca611710..f0d895846 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -132,7 +132,8 @@ static void scheduler_splittask(struct task *t, struct scheduler *s) { /* Non-splittable task? */ if ((t->ci == NULL || (t->type == task_type_pair && t->cj == NULL)) || - ((t->type == task_type_kick) && t->ci->nodeID != s->nodeID) || + ((t->type == task_type_kick1) && t->ci->nodeID != s->nodeID) || + ((t->type == task_type_kick2) && t->ci->nodeID != s->nodeID) || ((t->type == task_type_drift) && t->ci->nodeID != s->nodeID) || ((t->type == task_type_init) && t->ci->nodeID != s->nodeID)) { t->type = task_type_none; @@ -963,7 +964,10 @@ void scheduler_reweight(struct scheduler *s, int verbose) { case task_type_ghost: if (t->ci == t->ci->super) cost = wscale * t->ci->count; break; - case task_type_kick: + case task_type_kick1: + cost = wscale * t->ci->count; + break; + case task_type_kick2: cost = wscale * t->ci->count; break; case task_type_init: @@ -1154,7 +1158,8 @@ void scheduler_enqueue(struct scheduler *s, struct task *t) { case task_type_sub_self: case task_type_sort: case task_type_ghost: - case task_type_kick: + case task_type_kick1: + case task_type_kick2: case task_type_drift: case task_type_init: qid = t->ci->super->owner; diff --git a/src/space.c b/src/space.c index 23e97d998..055d4b769 100644 --- a/src/space.c +++ b/src/space.c @@ -213,7 +213,8 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->init = NULL; c->extra_ghost = NULL; c->ghost = NULL; - c->kick = NULL; + c->kick1 = NULL; + c->kick2 = NULL; c->drift = NULL; c->cooling = NULL; c->sourceterms = NULL; diff --git a/src/task.c b/src/task.c index 71fb0af8a..a356299fa 100644 --- a/src/task.c +++ b/src/task.c @@ -48,10 +48,10 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub_self", - "sub_pair", "init", "ghost", "extra_ghost", "drift", - "kick", "send", "recv", "grav_gather_m", "grav_fft", - "grav_mm", "grav_up", "cooling", "sourceterms"}; + "none", "sort", "self", "pair", "sub_self", + "sub_pair", "init", "ghost", "extra_ghost", "drift", + "kick1", "kick2", "send", "recv", "grav_gather_m", + "grav_fft", "grav_mm", "grav_up", "cooling", "sourceterms"}; const char *subtaskID_names[task_subtype_count] = { "none", "density", "gradient", "force", "grav", "external_grav", "tend"}; @@ -147,7 +147,8 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( break; case task_type_init: - case task_type_kick: + case task_type_kick1: + case task_type_kick2: case task_type_send: case task_type_recv: case task_type_drift: diff --git a/src/task.h b/src/task.h index b4767f036..38b8e5c87 100644 --- a/src/task.h +++ b/src/task.h @@ -46,7 +46,8 @@ enum task_types { task_type_ghost, task_type_extra_ghost, task_type_drift, - task_type_kick, + task_type_kick1, + task_type_kick2, task_type_send, task_type_recv, task_type_grav_gather_m, -- GitLab From 71b648027aa0f8390defa02d21a99737274bb67b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 28 Dec 2016 16:23:46 +0100 Subject: [PATCH 13/48] Kick tasks in place. Need to add the kick operation and the calculation of new time-steps. --- src/kick.h | 4 ++ src/runner.c | 107 ++++++++++++++++++++++++++++++++++++++------------- src/timers.h | 3 +- 3 files changed, 87 insertions(+), 27 deletions(-) diff --git a/src/kick.h b/src/kick.h index 2a21a97ab..3429a16d1 100644 --- a/src/kick.h +++ b/src/kick.h @@ -134,4 +134,8 @@ __attribute__((always_inline)) INLINE static void kick_part( struct part *restrict p, struct xpart *restrict xp, integertime_t ti_start, integertime_t ti_end, integertime_t ti_current) {} +__attribute__((always_inline)) INLINE static void kick_gpart( + struct gpart *restrict gp, integertime_t ti_start, integertime_t ti_end, + integertime_t ti_current) {} + #endif /* SWIFT_KICK_H */ diff --git a/src/runner.c b/src/runner.c index 2beea87e3..f099361b6 100644 --- a/src/runner.c +++ b/src/runner.c @@ -823,27 +823,80 @@ void runner_do_drift_mapper(void *map_data, int num_elements, } } -void runner_do_kick1(struct runner *r, struct cell *c, int timer) {} +void runner_do_kick1(struct runner *r, struct cell *c, int timer) { -void runner_do_kick2(struct runner *r, struct cell *c, int timer) {} + const struct engine *e = r->e; + struct part *restrict parts = c->parts; + struct xpart *restrict xparts = c->xparts; + struct gpart *restrict gparts = c->gparts; + const int count = c->count; + const int gcount = c->gcount; + const integertime_t ti_current = e->ti_current; -/** - * @brief Kick particles in momentum space and collect statistics. - * - * @param r The runner thread. - * @param c The cell. - * @param timer Are we timing this ? - */ -void runner_do_kick(struct runner *r, struct cell *c, int timer) { + TIMER_TIC; + + /* Anything to do here? */ + if (!cell_is_active(c, e)) return; + + /* Recurse? */ + if (c->split) { + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) runner_do_kick1(r, c->progeny[k], 0); + } else { + + /* Loop over the parts in this cell. */ + for (int k = 0; k < count; k++) { + + /* Get a handle on the part. */ + struct part *restrict p = &parts[k]; + struct xpart *restrict xp = &xparts[k]; + + /* If particle needs to be kicked */ + if (part_is_active(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); + const integertime_t ti_end = + get_integer_time_end(ti_current, p->time_bin); + + /* do the kick */ + kick_part(p, xp, ti_begin, ti_end + ti_step / 2, ti_current); + } + } + + /* Loop over the parts in this cell. */ + for (int k = 0; k < gcount; k++) { + + /* Get a handle on the part. */ + struct gpart *restrict gp = &gparts[k]; + + /* If the g-particle has no counterpart and needs to be kicked */ + if (gp->id_or_neg_offset > 0 && gpart_is_active(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); + const integertime_t ti_end = + get_integer_time_end(ti_current, gp->time_bin); + + /* do the kick */ + kick_gpart(gp, ti_begin, ti_end + ti_step / 2, ti_current); + } + } + } + if (timer) TIMER_TOC(timer_kick1); +} + +void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const struct engine *e = r->e; - // const double timeBase = e->timeBase; const integertime_t ti_current = e->ti_current; const int count = c->count; - // const int gcount = c->gcount; + const int gcount = c->gcount; struct part *restrict parts = c->parts; struct xpart *restrict xparts = c->xparts; - // struct gpart *restrict gparts = c->gparts; + struct gpart *restrict gparts = c->gparts; const double const_G = e->physical_constants->const_newton_G; TIMER_TIC; @@ -861,7 +914,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { /* No children? */ if (!c->split) { - /* Loop over the particles and kick the active ones. */ + /* Loop over the particles in this cell. */ for (int k = 0; k < count; k++) { /* Get a handle on the part. */ @@ -886,24 +939,26 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { } } - /* Loop over the particles and kick the active ones. */ - for (int k = 0; k < count; k++) { + /* Loop over the particles in this cell. */ + for (int k = 0; k < gcount; k++) { /* Get a handle on the part. */ - struct part *restrict p = &parts[k]; - struct xpart *restrict xp = &xparts[k]; + struct gpart *restrict gp = &gparts[k]; - /* If particle needs to be kicked */ - if (part_is_active(p, e)) { + /* If the g-particle has no counterpart and needs to be kicked */ + if (gp->id_or_neg_offset > 0 && gpart_is_active(gp, e)) { + + /* First, finish the force loop */ + gravity_end_force(gp, const_G); - const integertime_t ti_step = get_integer_timestep(p->time_bin); + const integertime_t ti_step = get_integer_timestep(gp->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, p->time_bin); + get_integer_time_begin(ti_current, gp->time_bin); const integertime_t ti_end = - get_integer_time_end(ti_current, p->time_bin); + get_integer_time_end(ti_current, gp->time_bin); /* And finish the time-step with a second half-kick */ - kick_part(p, xp, ti_begin, ti_end + ti_step / 2, ti_current); + kick_gpart(gp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current); } } } @@ -917,7 +972,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { struct cell *restrict cp = c->progeny[k]; /* Recurse */ - runner_do_kick(r, cp, 0); + runner_do_kick2(r, cp, 0); /* And aggregate */ updated += cp->updated; @@ -933,7 +988,7 @@ void runner_do_kick(struct runner *r, struct cell *c, int timer) { c->ti_end_min = ti_end_min; c->ti_end_max = ti_end_max; - if (timer) TIMER_TOC(timer_kick); + if (timer) TIMER_TOC(timer_kick2); } #ifdef OLD_KICK diff --git a/src/timers.h b/src/timers.h index bc877d409..692bc0d51 100644 --- a/src/timers.h +++ b/src/timers.h @@ -33,7 +33,8 @@ enum { timer_prepare, timer_init, timer_drift, - timer_kick, + timer_kick1, + timer_kick2, timer_dosort, timer_doself_density, timer_doself_gradient, -- GitLab From a2e0376f1eb2eb2827599e85887aa3c13a4cabda Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 28 Dec 2016 16:55:35 +0100 Subject: [PATCH 14/48] Updated the kick operation to the new framework. Need to do the preparation for the prediction next. --- src/gravity/Default/gravity.h | 2 +- src/hydro/Gadget2/hydro.h | 7 +----- src/kick.h | 42 +++++++++++++++++++++++++++++++++-- src/runner.c | 28 +++++++++++++---------- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 89c7ac66d..e533055dd 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -99,6 +99,6 @@ __attribute__((always_inline)) INLINE static void gravity_end_force( * @param half_dt The half time-step for this kick */ __attribute__((always_inline)) INLINE static void gravity_kick_extra( - struct gpart* gp, float dt, float half_dt) {} + struct gpart* gp, float dt) {} #endif /* SWIFT_DEFAULT_GRAVITY_H */ diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 9c5f51160..b31e4449b 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -427,8 +427,7 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param half_dt The half time-step for this kick */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( - struct part *restrict p, struct xpart *restrict xp, float dt, - float half_dt) { + struct part *restrict p, struct xpart *restrict xp, float dt) { /* Do not decrease the entropy (temperature) by more than a factor of 2*/ const float entropy_change = p->entropy_dt * dt; @@ -437,10 +436,6 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( else p->entropy *= 0.5f; - /* Do not 'overcool' when timestep increases */ - if (p->entropy + p->entropy_dt * half_dt < 0.5f * p->entropy) - p->entropy_dt = -0.5f * p->entropy / half_dt; - /* Compute the pressure */ const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); diff --git a/src/kick.h b/src/kick.h index 3429a16d1..08dd0307e 100644 --- a/src/kick.h +++ b/src/kick.h @@ -132,10 +132,48 @@ __attribute__((always_inline)) INLINE static void kick_part( __attribute__((always_inline)) INLINE static void kick_part( struct part *restrict p, struct xpart *restrict xp, integertime_t ti_start, - integertime_t ti_end, integertime_t ti_current) {} + integertime_t ti_end, integertime_t ti_current, double timeBase) { + + /* Time interval for this half-kick */ + const float dt = (ti_end - ti_start) * timeBase; + + /* Get the acceleration */ + float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; + if (p->gpart != NULL) { + a_tot[0] += p->gpart->a_grav[0]; + a_tot[1] += p->gpart->a_grav[1]; + a_tot[2] += p->gpart->a_grav[2]; + } + + /* Kick particles in momentum space */ + xp->v_full[0] += a_tot[0] * dt; + xp->v_full[1] += a_tot[1] * dt; + xp->v_full[2] += a_tot[2] * dt; + if (p->gpart != NULL) { + p->gpart->v_full[0] = xp->v_full[0]; + p->gpart->v_full[1] = xp->v_full[1]; + p->gpart->v_full[2] = xp->v_full[2]; + } + + /* Extra kick work */ + hydro_kick_extra(p, xp, dt); + if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt); +} __attribute__((always_inline)) INLINE static void kick_gpart( struct gpart *restrict gp, integertime_t ti_start, integertime_t ti_end, - integertime_t ti_current) {} + integertime_t ti_current, double timeBase) { + + /* Time interval for this half-kick */ + const float dt = (ti_end - ti_start) * timeBase; + + /* Kick particles in momentum space */ + gp->v_full[0] += gp->a_grav[0] * dt; + gp->v_full[1] += gp->a_grav[1] * dt; + gp->v_full[2] += gp->a_grav[2] * dt; + + /* Kick extra variables */ + gravity_kick_extra(gp, dt); +} #endif /* SWIFT_KICK_H */ diff --git a/src/runner.c b/src/runner.c index f099361b6..6b284b32b 100644 --- a/src/runner.c +++ b/src/runner.c @@ -832,6 +832,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const int count = c->count; const int gcount = c->gcount; const integertime_t ti_current = e->ti_current; + const double timeBase = e->timeBase; TIMER_TIC; @@ -861,7 +862,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { get_integer_time_end(ti_current, p->time_bin); /* do the kick */ - kick_part(p, xp, ti_begin, ti_end + ti_step / 2, ti_current); + kick_part(p, xp, ti_begin, ti_end + ti_step / 2, ti_current, timeBase); } } @@ -874,14 +875,14 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { /* If the g-particle has no counterpart and needs to be kicked */ if (gp->id_or_neg_offset > 0 && gpart_is_active(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); + 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); const integertime_t ti_end = - get_integer_time_end(ti_current, gp->time_bin); - + get_integer_time_end(ti_current, gp->time_bin); + /* do the kick */ - kick_gpart(gp, ti_begin, ti_end + ti_step / 2, ti_current); + kick_gpart(gp, ti_begin, ti_end + ti_step / 2, ti_current, timeBase); } } } @@ -892,6 +893,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const struct engine *e = r->e; const integertime_t ti_current = e->ti_current; + const double timeBase = e->timeBase; const int count = c->count; const int gcount = c->gcount; struct part *restrict parts = c->parts; @@ -934,8 +936,9 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); - /* And finish the time-step with a second half-kick */ - kick_part(p, xp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current); + /* Finish the time-step with a second half-kick */ + kick_part(p, xp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current, + timeBase); } } @@ -947,7 +950,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* If the g-particle has no counterpart and needs to be kicked */ if (gp->id_or_neg_offset > 0 && gpart_is_active(gp, e)) { - + /* First, finish the force loop */ gravity_end_force(gp, const_G); @@ -957,8 +960,9 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); - /* And finish the time-step with a second half-kick */ - kick_gpart(gp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current); + /* Finish the time-step with a second half-kick */ + kick_gpart(gp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current, + timeBase); } } } -- GitLab From f8648c24cf0aa531193051ac66a6e5adc1470b28 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 28 Dec 2016 17:43:48 +0100 Subject: [PATCH 15/48] Predicted values are now correctly re-set in the second kick --- src/hydro/Gadget2/hydro.h | 9 +++++++++ src/runner.c | 20 ++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index b31e4449b..3b30c1b34 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -354,6 +354,15 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( p->force.v_sig = 0.0f; } +__attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( + struct part *restrict p, const struct xpart *restrict xp) { + + /* Re-set the predicted velocities */ + p->v[0] = xp->v_full[0]; + p->v[1] = xp->v_full[1]; + p->v[2] = xp->v_full[2]; +} + /** * @brief Predict additional particle fields forward in time when drifting * diff --git a/src/runner.c b/src/runner.c index 6b284b32b..3166c698c 100644 --- a/src/runner.c +++ b/src/runner.c @@ -858,11 +858,10 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { 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); - const integertime_t ti_end = - get_integer_time_end(ti_current, p->time_bin); /* do the kick */ - kick_part(p, xp, ti_begin, ti_end + ti_step / 2, ti_current, timeBase); + kick_part(p, xp, ti_begin, ti_begin + ti_step / 2, ti_current, + timeBase); } } @@ -878,11 +877,9 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { 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); - const integertime_t ti_end = - get_integer_time_end(ti_current, gp->time_bin); /* do the kick */ - kick_gpart(gp, ti_begin, ti_end + ti_step / 2, ti_current, timeBase); + kick_gpart(gp, ti_begin, ti_begin + ti_step / 2, ti_current, timeBase); } } } @@ -933,12 +930,13 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { 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); - const integertime_t ti_end = - get_integer_time_end(ti_current, p->time_bin); /* Finish the time-step with a second half-kick */ - kick_part(p, xp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current, + kick_part(p, xp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, timeBase); + + /* Prepare the values to be drifted */ + hydro_reset_predicted_values(p, xp); } } @@ -957,11 +955,9 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { 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); - const integertime_t ti_end = - get_integer_time_end(ti_current, gp->time_bin); /* Finish the time-step with a second half-kick */ - kick_gpart(gp, ti_begin + ti_step / 2, ti_end + ti_step, ti_current, + kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, timeBase); } } -- GitLab From 2aedd26834c9adac277a440c319d2fbd04cf3225 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 28 Dec 2016 18:08:06 +0100 Subject: [PATCH 16/48] Particles now get their time-step updated. Everything works. Need to improve handling of first time-step. --- src/engine.c | 10 ++++------ src/runner.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/engine.c b/src/engine.c index f1ddc3d4e..4dad55cd7 100644 --- a/src/engine.c +++ b/src/engine.c @@ -147,10 +147,11 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { c->kick2 = scheduler_addtask(s, task_type_kick2, task_subtype_none, 0, 0, c, NULL, 0); - /* Add the drift task and dependency. */ + /* 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. */ @@ -1600,10 +1601,8 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, struct task *gradient, struct task *force, struct cell *c) { - /* kick1 --> init --> density loop --> ghost --> gradient loop --> extra_ghost - */ + /* init --> density loop --> ghost --> gradient loop --> extra_ghost */ /* extra_ghost --> force loop --> kick2 */ - scheduler_addunlock(sched, c->super->kick1, c->super->init); scheduler_addunlock(sched, c->super->init, density); scheduler_addunlock(sched, density, c->super->ghost); scheduler_addunlock(sched, c->super->ghost, gradient); @@ -1626,8 +1625,7 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, struct task *density, struct task *force, struct cell *c) { - /* kick1 --> init --> density loop --> ghost --> force loop --> kick2 */ - scheduler_addunlock(sched, c->super->kick1, c->super->init); + /* init --> density loop --> ghost --> force loop --> kick2 */ scheduler_addunlock(sched, c->super->init, density); scheduler_addunlock(sched, density, c->super->ghost); scheduler_addunlock(sched, c->super->ghost, force); diff --git a/src/runner.c b/src/runner.c index 3166c698c..964e5018f 100644 --- a/src/runner.c +++ b/src/runner.c @@ -930,6 +930,8 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { 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); + const integertime_t ti_end = + get_integer_time_end(ti_current, p->time_bin); /* Finish the time-step with a second half-kick */ kick_part(p, xp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, @@ -937,6 +939,21 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Prepare the values to be drifted */ hydro_reset_predicted_values(p, xp); + + /* Get new time-step */ + const integertime_t ti_new_step = get_part_timestep(p, xp, e); + + /* Update particle */ + p->time_bin = get_time_bin(ti_new_step); + if (p->gpart != NULL) p->gpart->time_bin = get_time_bin(ti_new_step); + + /* Number of updated particles */ + updated++; + if (p->gpart != NULL) g_updated++; + + /* What is the next sync-point ? */ + ti_end_min = min(ti_end + ti_new_step, ti_end_min); + ti_end_max = max(ti_end + ti_new_step, ti_end_max); } } @@ -955,10 +972,25 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { 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); + const integertime_t ti_end = + get_integer_time_end(ti_current, gp->time_bin); /* Finish the time-step with a second half-kick */ kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, timeBase); + + /* Get new time-step */ + const integertime_t ti_new_step = get_gpart_timestep(gp, e); + + /* Update particle */ + gp->time_bin = get_time_bin(ti_new_step); + + /* Number of updated g-particles */ + g_updated++; + + /* What is the next sync-point ? */ + ti_end_min = min(ti_end + ti_new_step, ti_end_min); + ti_end_max = max(ti_end + ti_new_step, ti_end_max); } } } -- GitLab From 48a9957e78292979c9ba302e980d95f4072dc286 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 29 Dec 2016 15:41:44 +0100 Subject: [PATCH 17/48] Documentation and dead code elimination --- src/gravity/Default/gravity.h | 1 - src/hydro/Gadget2/hydro.h | 8 +- src/kick.h | 102 ++------------------ src/runner.c | 170 ++++------------------------------ src/timestep.h | 22 +---- 5 files changed, 38 insertions(+), 265 deletions(-) diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index e533055dd..bf8362a57 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -96,7 +96,6 @@ __attribute__((always_inline)) INLINE static void gravity_end_force( * * @param gp The particle to act upon * @param dt The time-step for this kick - * @param half_dt The half time-step for this kick */ __attribute__((always_inline)) INLINE static void gravity_kick_extra( struct gpart* gp, float dt) {} diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 3b30c1b34..eba1a0366 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -354,6 +354,13 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( p->force.v_sig = 0.0f; } +/** + * @brief Sets the values to be predicted in the drifts to their values at a + * kick time + * + * @param p The particle. + * @param xp The extended data of this particle. + */ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( struct part *restrict p, const struct xpart *restrict xp) { @@ -433,7 +440,6 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param p The particle to act upon * @param xp The particle extended data to act upon * @param dt The time-step for this kick - * @param half_dt The half time-step for this kick */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt) { diff --git a/src/kick.h b/src/kick.h index 08dd0307e..d532b2a9a 100644 --- a/src/kick.h +++ b/src/kick.h @@ -27,42 +27,29 @@ #include "debug.h" #include "timeline.h" -#if 0 - /** * @brief Perform the 'kick' operation on a #gpart * * @param gp The #gpart to kick. - * @param new_dti The (integer) time-step for this kick. + * @param ti_start The starting (integer) time of the kick + * @param ti_end The ending (integer) time of the kick * @param ti_current The current (integer) time. * @param timeBase The minimal allowed time-step size. */ __attribute__((always_inline)) INLINE static void kick_gpart( - struct gpart *restrict gp, integertime_t new_dti, integertime_t ti_current, - double timeBase) { + struct gpart *restrict gp, integertime_t ti_start, integertime_t ti_end, + integertime_t ti_current, double timeBase) { - /* Compute the time step for this kick */ - const integertime_t old_ti_begin = - get_integer_time_begin(ti_current, gp->time_bin); - const integertime_t old_ti_end = - get_integer_time_end(ti_current, gp->time_bin); - const integertime_t ti_start = (old_ti_begin + old_ti_end) / 2; - const integertime_t ti_end = old_ti_end + new_dti / 2; + /* Time interval for this half-kick */ const float dt = (ti_end - ti_start) * timeBase; - const float half_dt = (ti_end - old_ti_end) * timeBase; - - /* Move particle forward in time */ - // gp->ti_begin = gp->ti_end; - // gp->ti_end = gp->ti_begin + new_dti; - gp->time_bin = get_time_bin(new_dti); /* Kick particles in momentum space */ gp->v_full[0] += gp->a_grav[0] * dt; gp->v_full[1] += gp->a_grav[1] * dt; gp->v_full[2] += gp->a_grav[2] * dt; - /* Extra kick work */ - gravity_kick_extra(gp, dt, half_dt); + /* Kick extra variables */ + gravity_kick_extra(gp, dt); } /** @@ -70,66 +57,11 @@ __attribute__((always_inline)) INLINE static void kick_gpart( * * @param p The #part to kick. * @param xp The #xpart of the particle. - * @param new_dti The (integer) time-step for this kick. + * @param ti_start The starting (integer) time of the kick + * @param ti_end The ending (integer) time of the kick * @param ti_current The current (integer) time. * @param timeBase The minimal allowed time-step size. */ -__attribute__((always_inline)) INLINE static void kick_part( - struct part *restrict p, struct xpart *restrict xp, integertime_t new_dti, - integertime_t ti_current, double timeBase) { - - /* Compute the time step for this kick */ - const integertime_t old_ti_begin = - get_integer_time_begin(ti_current, p->time_bin); - const integertime_t old_ti_end = - get_integer_time_end(ti_current, p->time_bin); - const integertime_t ti_start = (old_ti_begin + old_ti_end) / 2; - const integertime_t ti_end = old_ti_end + new_dti / 2; - const float dt = (ti_end - ti_start) * timeBase; - const float half_dt = (ti_end - old_ti_end) * timeBase; - - /* Move particle forward in time */ - // p->ti_begin = p->ti_end; - // p->ti_end = p->ti_begin + new_dti; - p->time_bin = get_time_bin(new_dti); - // if (p->id == 116650) message("Time bin=%d new_dti=%d", p->time_bin, - // new_dti); - if (p->gpart != NULL) { - // p->gpart->ti_begin = p->ti_begin; - // p->gpart->ti_end = p->ti_end; - p->gpart->time_bin = get_time_bin(new_dti); - } - - /* Get the acceleration */ - float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; - if (p->gpart != NULL) { - a_tot[0] += p->gpart->a_grav[0]; - a_tot[1] += p->gpart->a_grav[1]; - a_tot[2] += p->gpart->a_grav[2]; - } - - /* Kick particles in momentum space */ - xp->v_full[0] += a_tot[0] * dt; - xp->v_full[1] += a_tot[1] * dt; - xp->v_full[2] += a_tot[2] * dt; - if (p->gpart != NULL) { - p->gpart->v_full[0] = xp->v_full[0]; - p->gpart->v_full[1] = xp->v_full[1]; - p->gpart->v_full[2] = xp->v_full[2]; - } - - /* Go back by half-step for the hydro velocity */ - p->v[0] = xp->v_full[0] - half_dt * a_tot[0]; - p->v[1] = xp->v_full[1] - half_dt * a_tot[1]; - p->v[2] = xp->v_full[2] - half_dt * a_tot[2]; - - /* Extra kick work */ - hydro_kick_extra(p, xp, dt, half_dt); - if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt, half_dt); -} - -#endif - __attribute__((always_inline)) INLINE static void kick_part( struct part *restrict p, struct xpart *restrict xp, integertime_t ti_start, integertime_t ti_end, integertime_t ti_current, double timeBase) { @@ -160,20 +92,4 @@ __attribute__((always_inline)) INLINE static void kick_part( if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt); } -__attribute__((always_inline)) INLINE static void kick_gpart( - struct gpart *restrict gp, integertime_t ti_start, integertime_t ti_end, - integertime_t ti_current, double timeBase) { - - /* Time interval for this half-kick */ - const float dt = (ti_end - ti_start) * timeBase; - - /* Kick particles in momentum space */ - gp->v_full[0] += gp->a_grav[0] * dt; - gp->v_full[1] += gp->a_grav[1] * dt; - gp->v_full[2] += gp->a_grav[2] * dt; - - /* Kick extra variables */ - gravity_kick_extra(gp, dt); -} - #endif /* SWIFT_KICK_H */ diff --git a/src/runner.c b/src/runner.c index 964e5018f..b7c7129f2 100644 --- a/src/runner.c +++ b/src/runner.c @@ -823,6 +823,13 @@ void runner_do_drift_mapper(void *map_data, int num_elements, } } +/** + * @brief Perform the first half-kick on all the active particles in a cell. + * + * @param r The runner thread. + * @param c The cell. + * @param timer Are we timing this ? + */ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const struct engine *e = r->e; @@ -865,7 +872,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { } } - /* Loop over the parts in this cell. */ + /* Loop over the gparts in this cell. */ for (int k = 0; k < gcount; k++) { /* Get a handle on the part. */ @@ -886,6 +893,16 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_kick1); } +/** + * @brief Perform the second half-kick on all the active particles in a cell. + * + * Also computes the next time-step of all active particles, prepare them to be + * drifted and update the cell's statistics. + * + * @param r The runner thread. + * @param c The cell. + * @param timer Are we timing this ? + */ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const struct engine *e = r->e; @@ -957,7 +974,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { } } - /* Loop over the particles in this cell. */ + /* Loop over the g-particles in this cell. */ for (int k = 0; k < gcount; k++) { /* Get a handle on the part. */ @@ -1023,155 +1040,6 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_kick2); } -#ifdef OLD_KICK - -/** - * @brief Kick particles in momentum space and collect statistics. - * - * @param r The runner thread. - * @param c The cell. - * @param timer Are we timing this ? - */ -void runner_do_kick(struct runner *r, struct cell *c, int timer) { - - const struct engine *e = r->e; - const double timeBase = e->timeBase; - const integertime_t ti_current = e->ti_current; - const int count = c->count; - const int gcount = c->gcount; - struct part *restrict parts = c->parts; - struct xpart *restrict xparts = c->xparts; - struct gpart *restrict gparts = c->gparts; - const double const_G = e->physical_constants->const_newton_G; - - TIMER_TIC; - - /* Anything to do here? */ - if (!cell_is_active(c, e)) { - c->updated = 0; - c->g_updated = 0; - return; - } - - int updated = 0, g_updated = 0; - integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; - - /* No children? */ - if (!c->split) { - - /* Loop over the g-particles and kick the active ones. */ - for (int k = 0; k < gcount; k++) { - - /* Get a handle on the part. */ - struct gpart *restrict gp = &gparts[k]; - - /* If the g-particle has no counterpart and needs to be kicked */ - if (gp->id_or_neg_offset > 0) { - - if (gpart_is_active(gp, e)) { - - /* First, finish the force calculation */ - gravity_end_force(gp, const_G); - - /* Compute the next timestep */ - const int new_dti = get_gpart_timestep(gp, e); - - /* Now we have a time step, proceed with the kick */ - kick_gpart(gp, new_dti, e->ti_current, timeBase); - - /* Number of updated g-particles */ - g_updated++; - } - - /* Minimal time for next end of time-step */ - const integertime_t ti_end = - get_integer_time_end(ti_current, gp->time_bin); - ti_end_min = min(ti_end, ti_end_min); - ti_end_max = max(ti_end, ti_end_max); - } - } - - /* Now do the hydro ones... */ - - /* Loop over the particles and kick the active ones. */ - for (int k = 0; k < count; k++) { - - /* Get a handle on the part. */ - struct part *restrict p = &parts[k]; - struct xpart *restrict xp = &xparts[k]; - - /* Minimal time for next end of time-step */ - integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); - - if (p->id == ICHECK) - message("Particle in kick ti_end=%lld ti_current=%lld", ti_end, - e->ti_current); - - /* If particle needs to be kicked */ - if (part_is_active(p, e)) { - - if (p->id == ICHECK) message("Particle active in kick"); - - /* First, finish the force loop */ - hydro_end_force(p); - if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); - - /* Compute the next timestep (hydro condition) */ - const integertime_t new_dti = get_part_timestep(p, xp, e); - - if (p->id == ICHECK) - message("time_step=%lld (%e)", new_dti, new_dti * e->timeBase); - - /* Now we have a time step, proceed with the kick */ - kick_part(p, xp, new_dti, e->ti_current, timeBase); - - // if (p->id == ICHECK) printParticle_single(p, xp); - - /* Number of updated particles */ - updated++; - if (p->gpart != NULL) g_updated++; - - ti_end += get_integer_timestep(p->time_bin); - } - - if (p->id == ICHECK) - message("ti_current = %lld dti=%lld ti_end=%lld (%f)", ti_current, - get_integer_timestep(p->time_bin), ti_end, - ti_end * e->timeBase); - ti_end_min = min(ti_end, ti_end_min); - ti_end_max = max(ti_end, ti_end_max); - } - } - - /* Otherwise, aggregate data from children. */ - else { - - /* Loop over the progeny. */ - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) { - struct cell *restrict cp = c->progeny[k]; - - /* Recurse */ - runner_do_kick(r, cp, 0); - - /* And aggregate */ - updated += cp->updated; - g_updated += cp->g_updated; - ti_end_min = min(cp->ti_end_min, ti_end_min); - ti_end_max = max(cp->ti_end_max, ti_end_max); - } - } - - /* Store the values. */ - c->updated = updated; - c->g_updated = g_updated; - c->ti_end_min = ti_end_min; - c->ti_end_max = ti_end_max; - - if (timer) TIMER_TOC(timer_kick); -} -#endif - /** * @brief Construct the cell properties from the received particles * diff --git a/src/timestep.h b/src/timestep.h index 10e450987..63a21bf3e 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -37,22 +37,15 @@ */ __attribute__((always_inline)) INLINE static integertime_t make_integer_timestep(float new_dt, timebin_t old_bin, integertime_t ti_current, - double timeBase_inv, int verbose) { + double timeBase_inv) { /* Convert to integer time */ integertime_t new_dti = (integertime_t)(new_dt * timeBase_inv); - /* if (verbose) message("new_dti=%lld", new_dti); */ - /* Current time-step */ integertime_t current_dti = get_integer_timestep(old_bin); integertime_t ti_end = get_integer_time_end(ti_current, old_bin); - /* if (verbose) */ - /* message("current_dti=%lld old_bin=%d ti_end=%lld", current_dti, old_bin, - */ - /* ti_end); */ - /* Limit timestep increase */ if (old_bin > 0) new_dti = min(new_dti, 2 * current_dti); @@ -61,15 +54,10 @@ make_integer_timestep(float new_dt, timebin_t old_bin, integertime_t ti_current, while (new_dti < dti_timeline) dti_timeline /= 2LL; new_dti = dti_timeline; - /* if (verbose) message("new_dti=%lld", new_dti); */ - /* Make sure we are allowed to increase the timestep size */ if (new_dti > current_dti) { if ((max_nr_timesteps - ti_end) % new_dti > 0) new_dti = current_dti; } - - /* if (verbose) message("new_dti=%lld", new_dti); */ - return new_dti; } @@ -97,7 +85,7 @@ __attribute__((always_inline)) INLINE static integertime_t get_gpart_timestep( /* Convert to integer time */ const integertime_t new_dti = make_integer_timestep( - new_dt, gp->time_bin, e->ti_current, e->timeBase_inv, 0); + new_dt, gp->time_bin, e->ti_current, e->timeBase_inv); return new_dti; } @@ -151,13 +139,9 @@ __attribute__((always_inline)) INLINE static integertime_t get_part_timestep( new_dt = min(new_dt, e->dt_max); new_dt = max(new_dt, e->dt_min); - /* if (p->id == ICHECK) message("new_dt=%e", new_dt); */ - /* Convert to integer time */ const integertime_t new_dti = make_integer_timestep( - new_dt, p->time_bin, e->ti_current, e->timeBase_inv, p->id == ICHECK); - - /* if (p->id == ICHECK) message("new_dti=%lld", new_dti); */ + new_dt, p->time_bin, e->ti_current, e->timeBase_inv); return new_dti; } -- GitLab From cbfb8a1938292ce58d97bd229ed94c2a9881e8e5 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 29 Dec 2016 15:47:10 +0100 Subject: [PATCH 18/48] Clean-up --- src/const.h | 2 -- src/gravity/Default/gravity_part.h | 6 ------ src/hydro/Gadget2/hydro_part.h | 6 ------ src/runner.c | 4 ++-- src/runner_doiact_grav.h | 2 ++ 5 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/const.h b/src/const.h index 4b46ec1cb..c290a3e73 100644 --- a/src/const.h +++ b/src/const.h @@ -59,6 +59,4 @@ #define SOURCETERMS_NONE //#define SOURCETERMS_SN_FEEDBACK -#define ICHECK -116650 - #endif /* SWIFT_CONST_H */ diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index cd16287db..18d524d39 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -44,12 +44,6 @@ struct gpart { /* Softening length */ float epsilon; - /* Particle time of beginning of time-step. */ - // int ti_begin; - - /* Particle time of end of time-step. */ - // int ti_end; - /* Time-step length */ timebin_t time_bin; diff --git a/src/hydro/Gadget2/hydro_part.h b/src/hydro/Gadget2/hydro_part.h index f10d72b90..56162055f 100644 --- a/src/hydro/Gadget2/hydro_part.h +++ b/src/hydro/Gadget2/hydro_part.h @@ -71,12 +71,6 @@ struct part { /* Particle mass. */ float mass; - /* Particle time of beginning of time-step. */ - // int ti_begin; - - /* Particle time of end of time-step. */ - // int ti_end; - /* Particle density. */ float rho; diff --git a/src/runner.c b/src/runner.c index b7c7129f2..d3b067f17 100644 --- a/src/runner.c +++ b/src/runner.c @@ -896,8 +896,8 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { /** * @brief Perform the second half-kick on all the active particles in a cell. * - * Also computes the next time-step of all active particles, prepare them to be - * drifted and update the cell's statistics. + * Also computes the next time-step of all active particles, prepare them to be + * drifted and update the cell's statistics. * * @param r The runner thread. * @param c The cell. diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 9d2606ceb..59a5ae496 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -25,6 +25,8 @@ #include "gravity.h" #include "part.h" +#define ICHECK -1000 + /** * @brief Compute the recursive upward sweep, i.e. construct the * multipoles in a cell hierarchy. -- GitLab From 347768166345546ae34aa9fccad60cb0c3247212 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 29 Dec 2016 16:29:18 +0100 Subject: [PATCH 19/48] Correctly initialise the particles before doing a time-integration --- src/engine.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/engine.c b/src/engine.c index 4dad55cd7..2b0389535 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2517,9 +2517,7 @@ void engine_skip_force_and_kick(struct engine *e) { struct task *t = &tasks[i]; /* Skip everything that updates the particles */ - if (t->subtype == - task_subtype_force || // t->type == task_type_kick || //MATTHIEU - t->type == task_type_cooling || + if (t->type == task_type_kick1 || t->type == task_type_cooling || t->type == task_type_sourceterms || t->type == task_type_drift) t->skip = 1; } -- GitLab From 520d3f958b0acadfdf3a96c0ec75068ca73bb63b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 2 Jan 2017 13:46:29 +0100 Subject: [PATCH 20/48] Move the drifting of the entropy to be like Gadget-3 --- src/cell.c | 3 ++- src/hydro/Gadget2/hydro.h | 42 ++++++++++++++++++---------------- src/hydro/Gadget2/hydro_part.h | 3 +++ src/statistics.c | 34 ++++++++++++--------------- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/cell.c b/src/cell.c index a8281a292..50d3a4415 100644 --- a/src/cell.c +++ b/src/cell.c @@ -686,9 +686,10 @@ void cell_sanitize(struct cell *c) { void cell_convert_hydro(struct cell *c, void *data) { struct part *p = c->parts; + struct xpart *xp = c->xparts; for (int i = 0; i < c->count; ++i) { - hydro_convert_quantities(&p[i]); + hydro_convert_quantities(&p[i], &xp[i]); } } diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index eba1a0366..581cb63d8 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -48,7 +48,7 @@ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( const struct part *restrict p, float dt) { - const float entropy = p->entropy + p->entropy_dt * dt; + const float entropy = p->entropy + dt * p->entropy_dt; return gas_internal_energy_from_entropy(p->rho, entropy); } @@ -62,7 +62,7 @@ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( __attribute__((always_inline)) INLINE static float hydro_get_pressure( const struct part *restrict p, float dt) { - const float entropy = p->entropy + p->entropy_dt * dt; + const float entropy = p->entropy + dt * p->entropy_dt; return gas_pressure_from_entropy(p->rho, entropy); } @@ -76,7 +76,7 @@ __attribute__((always_inline)) INLINE static float hydro_get_pressure( __attribute__((always_inline)) INLINE static float hydro_get_entropy( const struct part *restrict p, float dt) { - return p->entropy + p->entropy_dt * dt; + return p->entropy + dt * p->entropy_dt; } /** @@ -216,6 +216,7 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; + xp->entropy_full = p->entropy; } /** @@ -228,9 +229,10 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( */ __attribute__((always_inline)) INLINE static void hydro_init_part( struct part *restrict p) { + + p->rho = 0.f; p->density.wcount = 0.f; p->density.wcount_dh = 0.f; - p->rho = 0.f; p->density.rho_dh = 0.f; p->density.div_v = 0.f; p->density.rot_v[0] = 0.f; @@ -302,11 +304,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float abs_div_v = fabsf(p->density.div_v); /* Compute the pressure */ - const integertime_t ti_begin = - get_integer_time_begin(ti_current, p->time_bin); - const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); - const float half_dt = (ti_current - (ti_begin + ti_end) / 2) * timeBase; - const float pressure = hydro_get_pressure(p, half_dt); + const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); /* Compute the sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); @@ -368,6 +366,9 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( p->v[0] = xp->v_full[0]; p->v[1] = xp->v_full[1]; p->v[2] = xp->v_full[2]; + + /* Re-set the entropy */ + p->entropy = xp->entropy_full; } /** @@ -400,11 +401,11 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( else p->rho *= expf(w2); - /* Drift the pressure */ - const integertime_t ti_begin = get_integer_time_begin(t0, p->time_bin); - const integertime_t ti_end = get_integer_time_end(t0, p->time_bin); - const float dt_entr = (t1 - (ti_begin + ti_end) / 2) * timeBase; - const float pressure = hydro_get_pressure(p, dt_entr); + /* Predict the entropy */ + p->entropy += p->entropy_dt * dt; + + /* Re-compute the pressure */ + const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); /* Compute the new sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); @@ -446,13 +447,13 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( /* Do not decrease the entropy (temperature) by more than a factor of 2*/ const float entropy_change = p->entropy_dt * dt; - if (entropy_change > -0.5f * p->entropy) - p->entropy += entropy_change; + if (entropy_change > -0.5f * xp->entropy_full) + xp->entropy_full += entropy_change; else - p->entropy *= 0.5f; + xp->entropy_full *= 0.5f; /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); + const float pressure = gas_pressure_from_entropy(p->rho, xp->entropy_full); /* Compute the new sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); @@ -473,10 +474,11 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * @param p The particle to act upon */ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( - struct part *restrict p) { + struct part *restrict p, struct xpart *restrict xp) { /* We read u in the entropy field. We now get S from u */ - p->entropy = gas_entropy_from_internal_energy(p->rho, p->entropy); + xp->entropy_full = gas_entropy_from_internal_energy(p->rho, p->entropy); + p->entropy = xp->entropy_full; /* Compute the pressure */ const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); diff --git a/src/hydro/Gadget2/hydro_part.h b/src/hydro/Gadget2/hydro_part.h index 56162055f..8fb4b1d7b 100644 --- a/src/hydro/Gadget2/hydro_part.h +++ b/src/hydro/Gadget2/hydro_part.h @@ -42,6 +42,9 @@ struct xpart { /* Velocity at the last full step. */ float v_full[3]; + /* Entropy at the last full step. */ + float entropy_full; + /* Additional data used to record cooling information */ struct cooling_xpart_data cooling_data; diff --git a/src/statistics.c b/src/statistics.c index 55b76eba9..10ec276f5 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -104,8 +104,8 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { const struct part *restrict parts = (struct part *)map_data; const struct xpart *restrict xparts = s->xparts + (ptrdiff_t)(parts - s->parts); - // const integertime_t ti_current = s->e->ti_current; - // const double timeBase = s->e->timeBase; + const integertime_t ti_current = s->e->ti_current; + const double timeBase = s->e->timeBase; const double time = s->e->time; struct statistics *const global_stats = data->stats; @@ -125,32 +125,27 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { const struct xpart *xp = &xparts[k]; const struct gpart *gp = (p->gpart != NULL) ? gp = p->gpart : NULL; - /* Get useful variables */ - // const integertime_t ti_begin = - // get_integer_time_begin(ti_current, p->time_bin); - // const integertime_t ti_end = get_integer_time_end(ti_current, - // p->time_bin); - // const integertime_t dti = get_integer_timestep(p->time_bin); - const float dt = - 0.f; //(ti_current - (ti_begin + ti_end) / 2) * timeBase; //MATTHIEU - const double x[3] = {p->x[0], p->x[1], p->x[2]}; + /* Get useful time variables */ + const integertime_t ti_begin = + get_integer_time_begin(ti_current, p->time_bin); + const integertime_t ti_step = get_integer_timestep(p->time_bin); + const float dt = (ti_current - (ti_begin + ti_step / 2)) * timeBase; + + /* Get the total acceleration */ float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; if (gp != NULL) { a_tot[0] += gp->a_grav[0]; a_tot[1] += gp->a_grav[1]; a_tot[2] += gp->a_grav[2]; } + + /* Extrapolate velocities to current time */ const float v[3] = {xp->v_full[0] + a_tot[0] * dt, xp->v_full[1] + a_tot[1] * dt, xp->v_full[2] + a_tot[2] * dt}; const float m = hydro_get_mass(p); - - /* if (p->id == ICHECK) */ - /* message("bin=%d dti=%lld ti_begin=%lld ti_end=%lld dt=%e v=[%e %e %e]", - */ - /* p->time_bin, dti, ti_begin, ti_end, */ - /* dt, v[0], v[1], v[2]); */ + const double x[3] = {p->x[0], p->x[1], p->x[2]}; /* Collect mass */ stats.mass += m; @@ -167,13 +162,12 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { /* Collect energies. */ stats.E_kin += 0.5f * m * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + stats.E_int += m * hydro_get_internal_energy(p, dt); + stats.E_rad += cooling_get_radiated_energy(xp); stats.E_pot_self += 0.f; if (gp != NULL) stats.E_pot_ext += m * external_gravity_get_potential_energy( time, potential, phys_const, gp); - stats.E_int += m * hydro_get_internal_energy(p, dt); - stats.E_rad += cooling_get_radiated_energy(xp); - /* Collect entropy */ stats.entropy += m * hydro_get_entropy(p, dt); } -- GitLab From a9e78804b59e3932bf46593baae71d6b41f9cae3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 2 Jan 2017 14:33:52 +0100 Subject: [PATCH 21/48] Correctly gather the next time-step --- src/runner.c | 64 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/src/runner.c b/src/runner.c index 74c9fd034..94410adcb 100644 --- a/src/runner.c +++ b/src/runner.c @@ -972,6 +972,16 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { ti_end_min = min(ti_end + ti_new_step, ti_end_min); ti_end_max = max(ti_end + ti_new_step, ti_end_max); } + + else { /* part is inactive */ + + const integertime_t ti_end = + get_integer_time_end(ti_current, p->time_bin); + + /* What is the next sync-point ? */ + ti_end_min = min(ti_end, ti_end_min); + ti_end_max = max(ti_end, ti_end_max); + } } /* Loop over the g-particles in this cell. */ @@ -980,34 +990,46 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Get a handle on the part. */ struct gpart *restrict gp = &gparts[k]; - /* If the g-particle has no counterpart and needs to be kicked */ - if (gp->id_or_neg_offset > 0 && gpart_is_active(gp, e)) { + /* If the g-particle has no counterpart */ + if (gp->id_or_neg_offset > 0) { - /* First, finish the force loop */ - gravity_end_force(gp, const_G); + /* need to be kicked ? */ + if (gpart_is_active(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); - const integertime_t ti_end = - get_integer_time_end(ti_current, gp->time_bin); + /* First, finish the force loop */ + gravity_end_force(gp, const_G); - /* Finish the time-step with a second half-kick */ - kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, - timeBase); + 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); + const integertime_t ti_end = + get_integer_time_end(ti_current, gp->time_bin); - /* Get new time-step */ - const integertime_t ti_new_step = get_gpart_timestep(gp, e); + /* Finish the time-step with a second half-kick */ + kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, + timeBase); - /* Update particle */ - gp->time_bin = get_time_bin(ti_new_step); + /* Get new time-step */ + const integertime_t ti_new_step = get_gpart_timestep(gp, e); - /* Number of updated g-particles */ - g_updated++; + /* Update particle */ + gp->time_bin = get_time_bin(ti_new_step); - /* What is the next sync-point ? */ - ti_end_min = min(ti_end + ti_new_step, ti_end_min); - ti_end_max = max(ti_end + ti_new_step, ti_end_max); + /* Number of updated g-particles */ + g_updated++; + + /* What is the next sync-point ? */ + ti_end_min = min(ti_end + ti_new_step, ti_end_min); + ti_end_max = max(ti_end + ti_new_step, ti_end_max); + } else { /* gpart is inactive */ + + const integertime_t ti_end = + get_integer_time_end(ti_current, gp->time_bin); + + /* What is the next sync-point ? */ + ti_end_min = min(ti_end, ti_end_min); + ti_end_max = max(ti_end, ti_end_max); + } } } } -- GitLab From ffc0ef2d8e89f80912d807fb3bb03a1b65f1a134 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 2 Jan 2017 15:42:46 +0100 Subject: [PATCH 22/48] Correct position of the statistics calculator --- src/engine.c | 15 ++++++--------- src/timeline.h | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/engine.c b/src/engine.c index 2b0389535..baf4c52b6 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2689,6 +2689,12 @@ void engine_step(struct engine *e) { if (e->verbose) engine_print_task_counts(e); + /* Save some statistics */ + if (e->time - e->timeLastStatistics >= e->deltaTimeStatistics) { + engine_print_stats(e); + e->timeLastStatistics += e->deltaTimeStatistics; + } + /* Send off the runners. */ TIMER_TIC; engine_launch(e, e->nr_threads); @@ -2700,15 +2706,6 @@ void engine_step(struct engine *e) { } #endif - /* if(e->step > 2) */ - /* error("Done"); */ - - /* Save some statistics */ - if (e->time - e->timeLastStatistics >= e->deltaTimeStatistics) { - engine_print_stats(e); - e->timeLastStatistics += e->deltaTimeStatistics; - } - TIMER_TOC2(timer_step); clocks_gettime(&time2); diff --git a/src/timeline.h b/src/timeline.h index b6c411411..ff192533b 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -28,7 +28,7 @@ #include -typedef unsigned long long integertime_t; +typedef long long integertime_t; typedef char timebin_t; /*! The number of time bins */ -- GitLab From 00c3a2b198757bb4e9e92f13e0d03b8fddd3659a Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 4 Jan 2017 10:56:00 +0000 Subject: [PATCH 23/48] Also compute the time-step correctly for the gpart statistics --- src/statistics.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/statistics.c b/src/statistics.c index 10ec276f5..4febdf096 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -191,8 +191,8 @@ void stats_collect_gpart_mapper(void *map_data, int nr_gparts, const struct index_data *data = (struct index_data *)extra_data; const struct space *s = data->s; const struct gpart *restrict gparts = (struct gpart *)map_data; - // const integertime_t ti_current = s->e->ti_current; - // const double timeBase = s->e->timeBase; + const integertime_t ti_current = s->e->ti_current; + const double timeBase = s->e->timeBase; const double time = s->e->time; struct statistics *const global_stats = data->stats; @@ -214,18 +214,18 @@ void stats_collect_gpart_mapper(void *map_data, int nr_gparts, if (gp->id_or_neg_offset < 0) continue; /* Get useful variables */ - // const integertime_t ti_begin = - // get_integer_time_begin(ti_current, gp->time_bin); - // const integertime_t ti_end = get_integer_time_end(ti_current, - // gp->time_bin); - const float dt = - 0.f; //(ti_current - (ti_begin + ti_end) / 2) * timeBase; // MATTHIEU - const double x[3] = {gp->x[0], gp->x[1], gp->x[2]}; + const integertime_t ti_begin = + get_integer_time_begin(ti_current, gp->time_bin); + const integertime_t ti_step = get_integer_timestep(gp->time_bin); + const float dt = (ti_current - (ti_begin + ti_step / 2)) * timeBase; + + /* Extrapolate velocities */ const float v[3] = {gp->v_full[0] + gp->a_grav[0] * dt, gp->v_full[1] + gp->a_grav[1] * dt, gp->v_full[2] + gp->a_grav[2] * dt}; const float m = gp->mass; + const double x[3] = {gp->x[0], gp->x[1], gp->x[2]}; /* Collect mass */ stats.mass += m; -- GitLab From 7fb5b96d6f18f40d78a90e7c164f442e6ca41c44 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 5 Jan 2017 18:37:45 +0100 Subject: [PATCH 24/48] Separated the calculation of new time-steps from the second kick --- src/cell.c | 1 + src/cell.h | 3 ++ src/engine.c | 13 ++++- src/runner.c | 133 ++++++++++++++++++++++++++++++++++++++------------- src/space.c | 1 + src/task.c | 10 ++-- src/task.h | 1 + src/timers.h | 1 + 8 files changed, 123 insertions(+), 40 deletions(-) diff --git a/src/cell.c b/src/cell.c index 50d3a4415..509c82219 100644 --- a/src/cell.c +++ b/src/cell.c @@ -974,6 +974,7 @@ int cell_unskip_tasks(struct cell *c, struct scheduler *s) { if (c->drift != NULL) scheduler_activate(s, c->drift); if (c->kick1 != NULL) scheduler_activate(s, c->kick1); if (c->kick2 != NULL) scheduler_activate(s, c->kick2); + if (c->timestep != NULL) scheduler_activate(s, c->timestep); if (c->cooling != NULL) scheduler_activate(s, c->cooling); if (c->sourceterms != NULL) scheduler_activate(s, c->sourceterms); diff --git a/src/cell.h b/src/cell.h index 783a1fa77..c01594d48 100644 --- a/src/cell.h +++ b/src/cell.h @@ -156,6 +156,9 @@ struct cell { /*! The second kick task */ struct task *kick2; + /*! The task to compute time-steps */ + struct task *timestep; + /*! Task constructing the multipole from the particles */ struct task *grav_up; diff --git a/src/engine.c b/src/engine.c index baf4c52b6..10289cc73 100644 --- a/src/engine.c +++ b/src/engine.c @@ -147,6 +147,12 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { c->kick2 = scheduler_addtask(s, task_type_kick2, task_subtype_none, 0, 0, c, NULL, 0); + /* Add the time-step calculation task and its dependency */ + c->timestep = scheduler_addtask(s, task_type_timestep, task_subtype_none, + 0, 0, c, NULL, 0); + + scheduler_addunlock(s, c->kick2, c->timestep); + /* Add the drift task and its dependencies. */ c->drift = scheduler_addtask(s, task_type_drift, task_subtype_none, 0, 0, c, NULL, 0); @@ -2131,9 +2137,12 @@ void engine_marktasks_mapper(void *map_data, int num_elements, /* Kick? */ else if (t->type == task_type_kick1) { if (t->ci->ti_end_min <= ti_end) scheduler_activate(s, t); + } else if (t->type == task_type_kick2) { + if (t->ci->ti_end_min <= ti_end) scheduler_activate(s, t); } - else if (t->type == task_type_kick2) { + /* Time-step? */ + else if (t->type == task_type_timestep) { t->ci->updated = 0; t->ci->g_updated = 0; if (t->ci->ti_end_min <= ti_end) scheduler_activate(s, t); @@ -2365,7 +2374,7 @@ void engine_barrier(struct engine *e, int tid) { void engine_collect_kick(struct cell *c) { /* Skip super-cells (Their values are already set) */ - if (c->kick2 != NULL) return; + if (c->timestep != NULL) return; /* Counters for the different quantities. */ int updated = 0, g_updated = 0; diff --git a/src/runner.c b/src/runner.c index 94410adcb..50e72606b 100644 --- a/src/runner.c +++ b/src/runner.c @@ -896,8 +896,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { /** * @brief Perform the second half-kick on all the active particles in a cell. * - * Also computes the next time-step of all active particles, prepare them to be - * drifted and update the cell's statistics. + * Also prepares particles to be drifted. * * @param r The runner thread. * @param c The cell. @@ -918,17 +917,13 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { TIMER_TIC; /* Anything to do here? */ - if (!cell_is_active(c, e)) { - c->updated = 0; - c->g_updated = 0; - return; - } - - int updated = 0, g_updated = 0; - integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; + if (!cell_is_active(c, e)) return; - /* No children? */ - if (!c->split) { + /* Recurse? */ + if (c->split) { + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) runner_do_kick2(r, c->progeny[k], 0); + } else { /* Loop over the particles in this cell. */ for (int k = 0; k < count; k++) { @@ -947,8 +942,6 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { 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); - const integertime_t ti_end = - get_integer_time_end(ti_current, p->time_bin); /* Finish the time-step with a second half-kick */ kick_part(p, xp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, @@ -956,6 +949,82 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Prepare the values to be drifted */ hydro_reset_predicted_values(p, xp); + } + } + + /* Loop over the g-particles in this cell. */ + for (int k = 0; k < gcount; k++) { + + /* Get a handle on the part. */ + struct gpart *restrict gp = &gparts[k]; + + /* If the g-particle has no counterpart */ + if (gp->id_or_neg_offset > 0) { + + /* need to be kicked ? */ + if (gpart_is_active(gp, e)) { + + /* First, finish the force loop */ + gravity_end_force(gp, const_G); + + 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); + + /* Finish the time-step with a second half-kick */ + kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, + timeBase); + } + } + } + } + if (timer) TIMER_TOC(timer_kick2); +} + +/** + * @brief Computes the next time-step of all active particles in this cell + * and update the cell's statistics. + * + * @param r The runner thread. + * @param c The cell. + * @param timer Are we timing this ? + */ +void runner_do_timestep(struct runner *r, struct cell *c, int timer) { + + const struct engine *e = r->e; + const integertime_t ti_current = e->ti_current; + const int count = c->count; + const int gcount = c->gcount; + struct part *restrict parts = c->parts; + struct xpart *restrict xparts = c->xparts; + struct gpart *restrict gparts = c->gparts; + + TIMER_TIC; + + int updated = 0, g_updated = 0; + integertime_t ti_end_min = max_nr_timesteps, ti_end_max = 0; + + /* No children? */ + if (!c->split) { + + /* Loop over the particles in this cell. */ + for (int k = 0; k < count; k++) { + + /* Get a handle on the part. */ + struct part *restrict p = &parts[k]; + struct xpart *restrict xp = &xparts[k]; + + /* If particle needs updating */ + if (part_is_active(p, e)) { + +#ifdef SWIFT_DEBUG_CHECKS + /* Current end of time-step */ + const integertime_t ti_end = + get_integer_time_end(ti_current, p->time_bin); + + if (ti_end != ti_current) + error("Computing time-step of rogue particle."); +#endif /* Get new time-step */ const integertime_t ti_new_step = get_part_timestep(p, xp, e); @@ -969,8 +1038,8 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { if (p->gpart != NULL) g_updated++; /* What is the next sync-point ? */ - ti_end_min = min(ti_end + ti_new_step, ti_end_min); - ti_end_max = max(ti_end + ti_new_step, ti_end_max); + ti_end_min = min(ti_current + ti_new_step, ti_end_min); + ti_end_max = max(ti_current + ti_new_step, ti_end_max); } else { /* part is inactive */ @@ -993,21 +1062,17 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* If the g-particle has no counterpart */ if (gp->id_or_neg_offset > 0) { - /* need to be kicked ? */ + /* need to be updated ? */ if (gpart_is_active(gp, e)) { - /* First, finish the force loop */ - gravity_end_force(gp, const_G); - - 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); +#ifdef SWIFT_DEBUG_CHECKS + /* Current end of time-step */ const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); - /* Finish the time-step with a second half-kick */ - kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, - timeBase); + if (ti_end != ti_current) + error("Computing time-step of rogue particle."); +#endif /* Get new time-step */ const integertime_t ti_new_step = get_gpart_timestep(gp, e); @@ -1019,8 +1084,8 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { g_updated++; /* What is the next sync-point ? */ - ti_end_min = min(ti_end + ti_new_step, ti_end_min); - ti_end_max = max(ti_end + ti_new_step, ti_end_max); + ti_end_min = min(ti_current + ti_new_step, ti_end_min); + ti_end_max = max(ti_current + ti_new_step, ti_end_max); } else { /* gpart is inactive */ const integertime_t ti_end = @@ -1032,10 +1097,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { } } } - } - - /* Otherwise, aggregate data from children. */ - else { + } else { /* Loop over the progeny. */ for (int k = 0; k < 8; k++) @@ -1043,7 +1105,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { struct cell *restrict cp = c->progeny[k]; /* Recurse */ - runner_do_kick2(r, cp, 0); + runner_do_timestep(r, cp, 0); /* And aggregate */ updated += cp->updated; @@ -1059,7 +1121,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { c->ti_end_min = ti_end_min; c->ti_end_max = ti_end_max; - if (timer) TIMER_TOC(timer_kick2); + if (timer) TIMER_TOC(timer_timestep); } /** @@ -1297,6 +1359,9 @@ void *runner_main(void *data) { case task_type_kick2: runner_do_kick2(r, ci, 1); break; + case task_type_timestep: + runner_do_timestep(r, ci, 1); + break; #ifdef WITH_MPI case task_type_send: if (t->subtype == task_subtype_tend) { diff --git a/src/space.c b/src/space.c index 055d4b769..a0a36da64 100644 --- a/src/space.c +++ b/src/space.c @@ -215,6 +215,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->ghost = NULL; c->kick1 = NULL; c->kick2 = NULL; + c->timestep = NULL; c->drift = NULL; c->cooling = NULL; c->sourceterms = NULL; diff --git a/src/task.c b/src/task.c index a356299fa..ee4d92cf7 100644 --- a/src/task.c +++ b/src/task.c @@ -48,10 +48,11 @@ /* Task type names. */ const char *taskID_names[task_type_count] = { - "none", "sort", "self", "pair", "sub_self", - "sub_pair", "init", "ghost", "extra_ghost", "drift", - "kick1", "kick2", "send", "recv", "grav_gather_m", - "grav_fft", "grav_mm", "grav_up", "cooling", "sourceterms"}; + "none", "sort", "self", "pair", "sub_self", + "sub_pair", "init", "ghost", "extra_ghost", "drift", + "kick1", "kick2", "timestep", "send", "recv", + "grav_gather_m", "grav_fft", "grav_mm", "grav_up", "cooling", + "sourceterms"}; const char *subtaskID_names[task_subtype_count] = { "none", "density", "gradient", "force", "grav", "external_grav", "tend"}; @@ -149,6 +150,7 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( case task_type_init: case task_type_kick1: case task_type_kick2: + case task_type_timestep: case task_type_send: case task_type_recv: case task_type_drift: diff --git a/src/task.h b/src/task.h index 38b8e5c87..04aba60a1 100644 --- a/src/task.h +++ b/src/task.h @@ -48,6 +48,7 @@ enum task_types { task_type_drift, task_type_kick1, task_type_kick2, + task_type_timestep, task_type_send, task_type_recv, task_type_grav_gather_m, diff --git a/src/timers.h b/src/timers.h index 692bc0d51..fa0d10d55 100644 --- a/src/timers.h +++ b/src/timers.h @@ -35,6 +35,7 @@ enum { timer_drift, timer_kick1, timer_kick2, + timer_timestep, timer_dosort, timer_doself_density, timer_doself_gradient, -- GitLab From 36296f3a233137542eadd8045e75bd37e7c66ed8 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 5 Jan 2017 18:54:01 +0100 Subject: [PATCH 25/48] Added infrastructure to check that particles follow the Kick-Drift-Kick scheme correctly --- src/drift.h | 10 ++++++++++ src/hydro/Gadget2/hydro_part.h | 10 ++++++++++ src/kick.h | 12 +++++++++++- src/runner.c | 6 ++---- src/space.c | 5 +++++ 5 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/drift.h b/src/drift.h index 478971e30..c01b1a5c6 100644 --- a/src/drift.h +++ b/src/drift.h @@ -66,6 +66,16 @@ __attribute__((always_inline)) INLINE static void drift_part( struct part *restrict p, struct xpart *restrict xp, float dt, double timeBase, integertime_t ti_old, integertime_t ti_current) { +#ifdef SWIFT_DEBUG_CHECKS + if (p->ti_drift != ti_old) + error( + "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); + + p->ti_drift = ti_current; +#endif + /* Drift... */ p->x[0] += xp->v_full[0] * dt; p->x[1] += xp->v_full[1] * dt; diff --git a/src/hydro/Gadget2/hydro_part.h b/src/hydro/Gadget2/hydro_part.h index 8fb4b1d7b..69ae79666 100644 --- a/src/hydro/Gadget2/hydro_part.h +++ b/src/hydro/Gadget2/hydro_part.h @@ -130,6 +130,16 @@ struct part { /* Time-step length */ 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_GADGET2_HYDRO_PART_H */ diff --git a/src/kick.h b/src/kick.h index d532b2a9a..a679da274 100644 --- a/src/kick.h +++ b/src/kick.h @@ -64,11 +64,21 @@ __attribute__((always_inline)) INLINE static void kick_gpart( */ __attribute__((always_inline)) INLINE static void kick_part( struct part *restrict p, struct xpart *restrict xp, integertime_t ti_start, - integertime_t ti_end, integertime_t ti_current, double timeBase) { + integertime_t ti_end, double timeBase) { /* Time interval for this half-kick */ const float dt = (ti_end - ti_start) * timeBase; +#ifdef SWIFT_DEBUG_CHECKS + if (p->ti_kick != ti_start) + error( + "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); + + p->ti_kick = ti_end; +#endif + /* Get the acceleration */ float a_tot[3] = {p->a_hydro[0], p->a_hydro[1], p->a_hydro[2]}; if (p->gpart != NULL) { diff --git a/src/runner.c b/src/runner.c index 50e72606b..c224fd7cd 100644 --- a/src/runner.c +++ b/src/runner.c @@ -867,8 +867,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { get_integer_time_begin(ti_current, p->time_bin); /* do the kick */ - kick_part(p, xp, ti_begin, ti_begin + ti_step / 2, ti_current, - timeBase); + kick_part(p, xp, ti_begin, ti_begin + ti_step / 2, timeBase); } } @@ -944,8 +943,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { get_integer_time_begin(ti_current, p->time_bin); /* Finish the time-step with a second half-kick */ - kick_part(p, xp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, - timeBase); + kick_part(p, xp, ti_begin + ti_step / 2, ti_begin + ti_step, timeBase); /* Prepare the values to be drifted */ hydro_reset_predicted_values(p, xp); diff --git a/src/space.c b/src/space.c index a0a36da64..bca8a1653 100644 --- a/src/space.c +++ b/src/space.c @@ -1770,6 +1770,11 @@ void space_init_parts(struct space *s) { #endif hydro_first_init_part(&p[i], &xp[i]); + +#ifdef SWIFT_DEBUG_CHECKS + p->ti_drift = 0; + p->ti_kick = 0; +#endif } } -- GitLab From d949df55cb21bf06861793d4cc7205d32b2ec40a Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 5 Jan 2017 19:44:13 +0100 Subject: [PATCH 26/48] Check that the particles interacting in the SELF or PAIR tasks have been properly drifted to the current time --- src/runner_doiact.h | 80 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/runner_doiact.h b/src/runner_doiact.h index 8b860a013..e78d87e4b 100644 --- a/src/runner_doiact.h +++ b/src/runner_doiact.h @@ -780,6 +780,14 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2) { @@ -842,6 +850,14 @@ void DOPAIR1(struct runner *r, struct cell *ci, struct cell *cj) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hjg2) { @@ -1008,6 +1024,14 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2) { @@ -1059,6 +1083,14 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2) { @@ -1152,6 +1184,14 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hjg2 && r2 > hi * hi * kernel_gamma2) { @@ -1202,6 +1242,14 @@ void DOPAIR2(struct runner *r, struct cell *ci, struct cell *cj) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hjg2 && r2 > hi * hi * kernel_gamma2) { @@ -1348,6 +1396,14 @@ void DOSELF1(struct runner *r, struct cell *restrict c) { struct part *restrict pj = &parts[indt[pjd]]; const float hj = pj->h; +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Compute the pairwise distance. */ float r2 = 0.0f; float dx[3]; @@ -1412,6 +1468,14 @@ void DOSELF1(struct runner *r, struct cell *restrict c) { const int doj = (part_is_active(pj, e)) && (r2 < hj * hj * kernel_gamma2); +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2 || doj) { @@ -1589,6 +1653,14 @@ void DOSELF2(struct runner *r, struct cell *restrict c) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2 || r2 < hj * hj * kernel_gamma2) { @@ -1643,6 +1715,14 @@ void DOSELF2(struct runner *r, struct cell *restrict c) { r2 += dx[k] * dx[k]; } +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + /* Hit or miss? */ if (r2 < hig2 || r2 < hj * hj * kernel_gamma2) { -- GitLab From 663db381c86e805e75b6e4788d4b9751506b26f0 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 6 Jan 2017 15:45:47 +0000 Subject: [PATCH 27/48] More time integration checks --- src/runner.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/runner.c b/src/runner.c index dc1eb9f13..33f5fab55 100644 --- a/src/runner.c +++ b/src/runner.c @@ -867,6 +867,13 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const integertime_t ti_begin = get_integer_time_begin(ti_current, p->time_bin); +#ifdef SWIFT_DEBUG_CHECKS + const integertime_t ti_end = + get_integer_time_end(ti_current, p->time_bin); + + if (ti_end - ti_begin != ti_step) error("Particle in wrong time-bin"); +#endif + /* do the kick */ kick_part(p, xp, ti_begin, ti_begin + ti_step / 2, timeBase); } @@ -885,6 +892,13 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const integertime_t ti_begin = get_integer_time_begin(ti_current, gp->time_bin); +#ifdef SWIFT_DEBUG_CHECKS + const integertime_t ti_end = + get_integer_time_end(ti_current, gp->time_bin); + + if (ti_end - ti_begin != ti_step) error("Particle in wrong time-bin"); +#endif + /* do the kick */ kick_gpart(gp, ti_begin, ti_begin + ti_step / 2, ti_current, timeBase); } @@ -943,6 +957,11 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_begin = get_integer_time_begin(ti_current, p->time_bin); +#ifdef SWIFT_DEBUG_CHECKS + if (ti_begin + ti_step != ti_current) + error("Particle in wrong time-bin"); +#endif + /* Finish the time-step with a second half-kick */ kick_part(p, xp, ti_begin + ti_step / 2, ti_begin + ti_step, timeBase); @@ -970,6 +989,11 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_begin = get_integer_time_begin(ti_current, gp->time_bin); +#ifdef SWIFT_DEBUG_CHECKS + if (ti_begin + ti_step != ti_current) + error("Particle in wrong time-bin"); +#endif + /* Finish the time-step with a second half-kick */ kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, timeBase); -- GitLab From da06a73c9ac6c08b3ff29e91d0b0db619b0a07d3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 6 Jan 2017 18:14:09 +0000 Subject: [PATCH 28/48] Removed unnecessary parameters for the kick functions. --- src/kick.h | 4 +--- src/runner.c | 29 ++++++++++++----------------- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/src/kick.h b/src/kick.h index a679da274..b7dea7ffe 100644 --- a/src/kick.h +++ b/src/kick.h @@ -33,12 +33,11 @@ * @param gp The #gpart to kick. * @param ti_start The starting (integer) time of the kick * @param ti_end The ending (integer) time of the kick - * @param ti_current The current (integer) time. * @param timeBase The minimal allowed time-step size. */ __attribute__((always_inline)) INLINE static void kick_gpart( struct gpart *restrict gp, integertime_t ti_start, integertime_t ti_end, - integertime_t ti_current, double timeBase) { + double timeBase) { /* Time interval for this half-kick */ const float dt = (ti_end - ti_start) * timeBase; @@ -59,7 +58,6 @@ __attribute__((always_inline)) INLINE static void kick_gpart( * @param xp The #xpart of the particle. * @param ti_start The starting (integer) time of the kick * @param ti_end The ending (integer) time of the kick - * @param ti_current The current (integer) time. * @param timeBase The minimal allowed time-step size. */ __attribute__((always_inline)) INLINE static void kick_part( diff --git a/src/runner.c b/src/runner.c index 33f5fab55..d43f914ff 100644 --- a/src/runner.c +++ b/src/runner.c @@ -900,7 +900,7 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { #endif /* do the kick */ - kick_gpart(gp, ti_begin, ti_begin + ti_step / 2, ti_current, timeBase); + kick_gpart(gp, ti_begin, ti_begin + ti_step / 2, timeBase); } } } @@ -976,28 +976,23 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Get a handle on the part. */ struct gpart *restrict gp = &gparts[k]; - /* If the g-particle has no counterpart */ - if (gp->id_or_neg_offset > 0) { - - /* need to be kicked ? */ - if (gpart_is_active(gp, e)) { + /* If the g-particle has no counterpart and needs to be kicked */ + if (gp->id_or_neg_offset > 0 && gpart_is_active(gp, e)) { - /* First, finish the force loop */ - gravity_end_force(gp, const_G); + /* First, finish the force loop */ + gravity_end_force(gp, const_G); - 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); + 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); #ifdef SWIFT_DEBUG_CHECKS - if (ti_begin + ti_step != ti_current) - error("Particle in wrong time-bin"); + if (ti_begin + ti_step != ti_current) + error("Particle in wrong time-bin"); #endif - /* Finish the time-step with a second half-kick */ - kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, ti_current, - timeBase); - } + /* Finish the time-step with a second half-kick */ + kick_gpart(gp, ti_begin + ti_step / 2, ti_begin + ti_step, timeBase); } } } -- GitLab From 2b8b4e50f0d780b467adcc50be20bccb4055d204 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 7 Jan 2017 17:05:55 +0000 Subject: [PATCH 29/48] Initialisation step OK --- src/engine.c | 42 +++++++++++++++++++++++++++++++++++---- src/hydro/Gadget2/hydro.h | 41 ++++++++++++++++++++------------------ 2 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/engine.c b/src/engine.c index 3a01b03c5..3b61e7d2d 100644 --- a/src/engine.c +++ b/src/engine.c @@ -2515,7 +2515,7 @@ void engine_print_stats(struct engine *e) { } /** - * @brief Sets all the force and kick tasks to be skipped. + * @brief Sets all the force, drift and kick tasks to be skipped. * * @param e The #engine to act on. */ @@ -2529,8 +2529,31 @@ void engine_skip_force_and_kick(struct engine *e) { struct task *t = &tasks[i]; /* Skip everything that updates the particles */ - if (t->type == task_type_kick1 || t->type == task_type_cooling || - t->type == task_type_sourceterms || t->type == task_type_drift) + if (t->type == task_type_drift || t->type == task_type_kick1 || + t->type == task_type_kick2 || t->type == task_type_timestep || + t->subtype == task_subtype_force || t->type == task_type_cooling || + t->type == task_type_sourceterms) + t->skip = 1; + } +} + +/** + * @brief Sets all the drift and first kick tasks to be skipped. + * + * @param e The #engine to act on. + */ +void engine_skip_drift_and_kick(struct engine *e) { + + struct task *tasks = e->sched.tasks; + const int nr_tasks = e->sched.nr_tasks; + + for (int i = 0; i < nr_tasks; ++i) { + + struct task *t = &tasks[i]; + + /* Skip everything that updates the particles */ + if (t->type == task_type_drift || t->type == task_type_kick1 || + t->type == task_type_cooling || t->type == task_type_sourceterms) t->skip = 1; } } @@ -2590,7 +2613,7 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { struct clocks_time time1, time2; clocks_gettime(&time1); - if (e->nodeID == 0) message("Running initialisation fake time-step."); + if (e->nodeID == 0) message("Computing initial gas densities."); engine_prepare(e, 0, 0); @@ -2607,6 +2630,8 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs) { /* Apply some conversions (e.g. internal energy -> entropy) */ if (!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); @@ -2618,6 +2643,15 @@ 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."); + + engine_marktasks(e); + + engine_skip_drift_and_kick(e); + + engine_launch(e, e->nr_threads); + clocks_gettime(&time2); /* Ready to go */ diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 581cb63d8..c8be967eb 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -200,25 +200,6 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( return dt_cfl; } -/** - * @brief Initialises the particles for the first time - * - * This function is called only once just after the ICs have been - * read in to do some conversions. - * - * @param p The particle to act upon - * @param xp The extended particle data to act upon - */ -__attribute__((always_inline)) INLINE static void hydro_first_init_part( - struct part *restrict p, struct xpart *restrict xp) { - - p->time_bin = 0; - xp->v_full[0] = p->v[0]; - xp->v_full[1] = p->v[1]; - xp->v_full[2] = p->v[2]; - xp->entropy_full = p->entropy; -} - /** * @brief Prepares a particle for the density calculation. * @@ -494,4 +475,26 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( p->force.P_over_rho2 = P_over_rho2; } +/** + * @brief Initialises the particles for the first time + * + * This function is called only once just after the ICs have been + * read in to do some conversions. + * + * @param p The particle to act upon + * @param xp The extended particle data to act upon + */ +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part *restrict p, struct xpart *restrict xp) { + + p->time_bin = 0; + xp->v_full[0] = p->v[0]; + xp->v_full[1] = p->v[1]; + xp->v_full[2] = p->v[2]; + xp->entropy_full = p->entropy; + + hydro_reset_acceleration(p); + hydro_init_part(p); +} + #endif /* SWIFT_GADGET2_HYDRO_H */ -- GitLab From 6264dfea516e42c46a1b3e7bbc4c34a6e3c9ee95 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 7 Jan 2017 20:31:26 +0000 Subject: [PATCH 30/48] No unnecessary parameters --- src/drift.h | 2 +- src/hydro/Gadget2/hydro.h | 6 ++---- src/runner.c | 4 +--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/drift.h b/src/drift.h index c01b1a5c6..5ad0a8ad2 100644 --- a/src/drift.h +++ b/src/drift.h @@ -87,7 +87,7 @@ __attribute__((always_inline)) INLINE static void drift_part( p->v[2] += p->a_hydro[2] * dt; /* Predict the values of the extra fields */ - hydro_predict_extra(p, xp, dt, ti_old, ti_current, timeBase); + hydro_predict_extra(p, xp, dt); /* Compute offset since last cell construction */ xp->x_diff[0] -= xp->v_full[0] * dt; diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index c8be967eb..bcf60d9e2 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -271,8 +271,7 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_prepare_force( - struct part *restrict p, struct xpart *restrict xp, - integertime_t ti_current, double timeBase) { + struct part *restrict p, struct xpart *restrict xp) { const float fac_mu = 1.f; /* Will change with cosmological integration */ @@ -363,8 +362,7 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part *restrict p, const struct xpart *restrict xp, float dt, - integertime_t t0, integertime_t t1, double timeBase) { + struct part *restrict p, const struct xpart *restrict xp, float dt) { const float h_inv = 1.f / p->h; diff --git a/src/runner.c b/src/runner.c index d43f914ff..25b817173 100644 --- a/src/runner.c +++ b/src/runner.c @@ -592,8 +592,6 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xparts = c->xparts; int redo, count = c->count; const struct engine *e = r->e; - const integertime_t ti_current = e->ti_current; - const double timeBase = e->timeBase; const float target_wcount = e->hydro_properties->target_neighbours; const float max_wcount = target_wcount + e->hydro_properties->delta_neighbours; @@ -675,7 +673,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { /* As of here, particle force variables will be set. */ /* Compute variables required for the force loop */ - hydro_prepare_force(p, xp, ti_current, timeBase); + hydro_prepare_force(p, xp); /* The particle force values are now set. Do _NOT_ try to read any particle density variables! */ -- GitLab From 8ac9c614faa312f162840357882cb51f10575e4d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 7 Jan 2017 21:20:49 +0000 Subject: [PATCH 31/48] Updated Minimal-SPH to the new scheme --- src/hydro/Minimal/hydro.h | 102 ++++++++++++++++++-------------- src/hydro/Minimal/hydro_debug.h | 5 +- src/hydro/Minimal/hydro_part.h | 30 ++++++---- 3 files changed, 79 insertions(+), 58 deletions(-) diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index beb6f98b8..801e86470 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -210,26 +210,6 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( return dt_cfl; } -/** - * @brief Initialises the particles for the first time - * - * This function is called only once just after the ICs have been - * read in to do some conversions or assignments between the particle - * and extended particle fields. - * - * @param p The particle to act upon - * @param xp The extended particle data to act upon - */ -__attribute__((always_inline)) INLINE static void hydro_first_init_part( - struct part *restrict p, struct xpart *restrict xp) { - - p->ti_begin = 0; - p->ti_end = 0; - xp->v_full[0] = p->v[0]; - xp->v_full[1] = p->v[1]; - xp->v_full[2] = p->v[2]; -} - /** * @brief Prepares a particle for the density calculation. * @@ -292,16 +272,12 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( * * @param p The particle to act upon * @param xp The extended particle data to act upon - * @param ti_current The current time (on the timeline) - * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_prepare_force( - struct part *restrict p, struct xpart *restrict xp, int ti_current, - double timeBase) { + struct part *restrict p, struct xpart *restrict xp) { /* Compute the pressure */ - const float half_dt = (ti_current - (p->ti_begin + p->ti_end) / 2) * timeBase; - const float pressure = hydro_get_pressure(p, half_dt); + const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); /* Compute the sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); @@ -339,6 +315,25 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( p->force.v_sig = 0.0f; } +/** + * @brief Sets the values to be predicted in the drifts to their values at a + * kick time + * + * @param p The particle. + * @param xp The extended data of this particle. + */ +__attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( + struct part *restrict p, const struct xpart *restrict xp) { + + /* Re-set the predicted velocities */ + p->v[0] = xp->v_full[0]; + p->v[1] = xp->v_full[1]; + p->v[2] = xp->v_full[2]; + + /* Re-set the entropy */ + p->u = xp->u_full; +} + /** * @brief Predict additional particle fields forward in time when drifting * @@ -348,13 +343,9 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( * @param p The particle. * @param xp The extended data of the particle. * @param dt The drift time-step. - * @param t0 The time at the start of the drift (on the timeline). - * @param t1 The time at the end of the drift (on the timeline). - * @param timeBase The minimal time-step size. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part *restrict p, const struct xpart *restrict xp, float dt, int t0, - int t1, double timeBase) { + struct part *restrict p, const struct xpart *restrict xp, float dt) { const float h_inv = 1.f / p->h; @@ -372,9 +363,11 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( else p->rho *= expf(w2); - /* Drift the pressure */ - const float dt_entr = (t1 - (p->ti_begin + p->ti_end) / 2) * timeBase; - const float pressure = hydro_get_pressure(p, dt_entr); + /* Predict the internal energy */ + p->u += p->u_dt * dt; + + /* Compute the new pressure */ + const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); /* Compute the new sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); @@ -407,24 +400,19 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param p The particle to act upon * @param xp The particle extended data to act upon * @param dt The time-step for this kick - * @param half_dt The half time-step for this kick */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( - struct part *restrict p, struct xpart *restrict xp, float dt, - float half_dt) { + struct part *restrict p, struct xpart *restrict xp, float dt) { /* Do not decrease the energy by more than a factor of 2*/ const float u_change = p->u_dt * dt; - if (u_change > -0.5f * p->u) - p->u += u_change; + if (u_change > -0.5f * xp->u_full) + xp->u_full += u_change; else - p->u *= 0.5f; - - /* Do not 'overcool' when timestep increases */ - if (p->u + p->u_dt * half_dt < 0.5f * p->u) p->u_dt = -0.5f * p->u / half_dt; + xp->u_full *= 0.5f; /* Compute the pressure */ - const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); + const float pressure = gas_pressure_from_internal_energy(p->rho, xp->u_full); /* Compute the sound speed */ const float soundspeed = gas_soundspeed_from_internal_energy(p->rho, p->u); @@ -442,9 +430,10 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * This can be used to convert internal energy into entropy for instance. * * @param p The particle to act upon + * @param xp The extended particle to act upon */ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( - struct part *restrict p) { + struct part *restrict p, struct xpart *restrict xp) { /* Compute the pressure */ const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); @@ -456,4 +445,27 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( p->force.soundspeed = soundspeed; } +/** + * @brief Initialises the particles for the first time + * + * This function is called only once just after the ICs have been + * read in to do some conversions or assignments between the particle + * and extended particle fields. + * + * @param p The particle to act upon + * @param xp The extended particle data to act upon + */ +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part *restrict p, struct xpart *restrict xp) { + + p->time_bin = 0; + xp->v_full[0] = p->v[0]; + xp->v_full[1] = p->v[1]; + xp->v_full[2] = p->v[2]; + xp->u_full = p->u; + + hydro_reset_acceleration(p); + hydro_init_part(p); +} + #endif /* SWIFT_MINIMAL_HYDRO_H */ diff --git a/src/hydro/Minimal/hydro_debug.h b/src/hydro/Minimal/hydro_debug.h index 16ae62413..876ce1488 100644 --- a/src/hydro/Minimal/hydro_debug.h +++ b/src/hydro/Minimal/hydro_debug.h @@ -40,12 +40,11 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e], " "u=%.3e, du/dt=%.3e v_sig=%.3e, P=%.3e\n" "h=%.3e, dh/dt=%.3e wcount=%d, m=%.3e, dh_drho=%.3e, rho=%.3e, " - "t_begin=%d, t_end=%d\n", + "time_bin=%d\n", p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], xp->v_full[0], xp->v_full[1], xp->v_full[2], p->a_hydro[0], p->a_hydro[1], p->a_hydro[2], p->u, p->u_dt, p->force.v_sig, p->force.pressure, p->h, p->force.h_dt, - (int)p->density.wcount, p->mass, p->density.rho_dh, p->rho, p->ti_begin, - p->ti_end); + (int)p->density.wcount, p->mass, p->density.rho_dh, p->rho, p->time_bin); } #endif /* SWIFT_MINIMAL_HYDRO_DEBUG_H */ diff --git a/src/hydro/Minimal/hydro_part.h b/src/hydro/Minimal/hydro_part.h index 854217727..dabae1a54 100644 --- a/src/hydro/Minimal/hydro_part.h +++ b/src/hydro/Minimal/hydro_part.h @@ -49,6 +49,9 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; + /*! Internal energy at the last full step. */ + float u_full; + /*! Additional data used to record cooling information */ struct cooling_xpart_data cooling_data; @@ -63,6 +66,12 @@ struct xpart { */ struct part { + /*! Particle unique ID. */ + long long id; + + /*! Pointer to corresponding gravity part. */ + struct gpart* gpart; + /*! Particle position. */ double x[3]; @@ -78,12 +87,6 @@ struct part { /*! Particle smoothing length. */ float h; - /*! Time at the beginning of time-step. */ - int ti_begin; - - /*! Time at the end of time-step. */ - int ti_end; - /*! Particle internal energy. */ float u; @@ -143,11 +146,18 @@ struct part { } force; }; - /*! Particle unique ID. */ - long long id; + /*! Time-step length */ + timebin_t time_bin; - /*! Pointer to corresponding gravity part. */ - struct gpart* gpart; +#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; -- GitLab From b30fa01cb8b593e00868d5cb4951108eecfb3243 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 7 Jan 2017 22:39:19 +0000 Subject: [PATCH 32/48] Updated PressureEntropy-SPH to the new scheme --- src/hydro/PressureEntropy/hydro.h | 108 +++++++++++++----------- src/hydro/PressureEntropy/hydro_debug.h | 5 +- src/hydro/PressureEntropy/hydro_part.h | 30 ++++--- 3 files changed, 80 insertions(+), 63 deletions(-) diff --git a/src/hydro/PressureEntropy/hydro.h b/src/hydro/PressureEntropy/hydro.h index 8c063596e..8ef993e57 100644 --- a/src/hydro/PressureEntropy/hydro.h +++ b/src/hydro/PressureEntropy/hydro.h @@ -202,27 +202,6 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( return dt_cfl; } -/** - * @brief Initialises the particles for the first time - * - * This function is called only once just after the ICs have been - * read in to do some conversions. - * - * @param p The particle to act upon - * @param xp The extended particle data to act upon - */ -__attribute__((always_inline)) INLINE static void hydro_first_init_part( - struct part *restrict p, struct xpart *restrict xp) { - - p->ti_begin = 0; - p->ti_end = 0; - p->rho_bar = 0.f; - p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); - xp->v_full[0] = p->v[0]; - xp->v_full[1] = p->v[1]; - xp->v_full[2] = p->v[2]; -} - /** * @brief Prepares a particle for the density calculation. * @@ -302,12 +281,9 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( * * @param p The particle to act upon * @param xp The extended particle data to act upon - * @param ti_current The current time (on the timeline) - * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_prepare_force( - struct part *restrict p, struct xpart *restrict xp, int ti_current, - double timeBase) { + struct part *restrict p, struct xpart *restrict xp) { const float fac_mu = 1.f; /* Will change with cosmological integration */ @@ -320,9 +296,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float abs_div_v = fabsf(p->density.div_v); /* Compute the pressure */ - const float half_dt = (ti_current - (p->ti_begin + p->ti_end) / 2) * timeBase; - const float entropy = hydro_get_entropy(p, half_dt); - const float pressure = gas_pressure_from_entropy(p->rho_bar, entropy); + const float pressure = gas_pressure_from_entropy(p->rho_bar, p->entropy); /* Compute the sound speed from the pressure*/ const float soundspeed = gas_soundspeed_from_pressure(p->rho_bar, pressure); @@ -375,19 +349,34 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( p->force.v_sig = 0.0f; } +/** + * @brief Sets the values to be predicted in the drifts to their values at a + * kick time + * + * @param p The particle. + * @param xp The extended data of this particle. + */ +__attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( + struct part *restrict p, const struct xpart *restrict xp) { + + /* Re-set the predicted velocities */ + p->v[0] = xp->v_full[0]; + p->v[1] = xp->v_full[1]; + p->v[2] = xp->v_full[2]; + + /* Re-set the entropy */ + p->entropy = xp->entropy_full; +} + /** * @brief Predict additional particle fields forward in time when drifting * * @param p The particle * @param xp The extended data of the particle * @param dt The drift time-step. - * @param t0 The time at the start of the drift (on the timeline). - * @param t1 The time at the end of the drift (on the timeline). - * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part *restrict p, const struct xpart *restrict xp, float dt, int t0, - int t1, double timeBase) { + struct part *restrict p, const struct xpart *restrict xp, float dt) { const float h_inv = 1.f / p->h; @@ -408,12 +397,11 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->rho_bar *= expf(w2); } - /* Drift the entropy */ - const float dt_entr = (t1 - (p->ti_begin + p->ti_end) / 2) * timeBase; - const float entropy = hydro_get_entropy(p, dt_entr); + /* Predict the entropy */ + p->entropy += p->entropy_dt * dt; /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho_bar, entropy); + const float pressure = gas_pressure_from_entropy(p->rho_bar, p->entropy); /* Compute the new sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho_bar, pressure); @@ -423,7 +411,7 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( const float P_over_rho2 = pressure * rho_bar_inv * rho_bar_inv; /* Update the variables */ - p->entropy_one_over_gamma = pow_one_over_gamma(entropy); + p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); p->force.soundspeed = soundspeed; p->force.P_over_rho2 = P_over_rho2; } @@ -453,22 +441,18 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param half_dt The half time-step for this kick */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( - struct part *restrict p, struct xpart *restrict xp, float dt, - float half_dt) { + struct part *restrict p, struct xpart *restrict xp, float dt) { /* Do not decrease the entropy (temperature) by more than a factor of 2*/ const float entropy_change = p->entropy_dt * dt; - if (entropy_change > -0.5f * p->entropy) - p->entropy += entropy_change; + if (entropy_change > -0.5f * xp->entropy_full) + xp->entropy_full += entropy_change; else - p->entropy *= 0.5f; - - /* Do not 'overcool' when timestep increases */ - if (p->entropy + p->entropy_dt * half_dt < 0.5f * p->entropy) - p->entropy_dt = -0.5f * p->entropy / half_dt; + xp->entropy_full *= 0.5f; /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho_bar, p->entropy); + const float pressure = + gas_pressure_from_entropy(p->rho_bar, xp->entropy_full); /* Compute the new sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho_bar, pressure); @@ -490,10 +474,11 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * @param p The particle to act upon */ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( - struct part *restrict p) { + struct part *restrict p, struct xpart *restrict xp) { /* We read u in the entropy field. We now get S from u */ - p->entropy = gas_entropy_from_internal_energy(p->rho_bar, p->entropy); + xp->entropy_full = gas_entropy_from_internal_energy(p->rho_bar, p->entropy); + p->entropy = xp->entropy_full; p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); /* Compute the pressure */ @@ -510,4 +495,27 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( p->force.P_over_rho2 = P_over_rho2; } +/** + * @brief Initialises the particles for the first time + * + * This function is called only once just after the ICs have been + * read in to do some conversions. + * + * @param p The particle to act upon + * @param xp The extended particle data to act upon + */ +__attribute__((always_inline)) INLINE static void hydro_first_init_part( + struct part *restrict p, struct xpart *restrict xp) { + + p->time_bin = 0; + p->rho_bar = 0.f; + p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); + xp->v_full[0] = p->v[0]; + xp->v_full[1] = p->v[1]; + xp->v_full[2] = p->v[2]; + + hydro_reset_acceleration(p); + hydro_init_part(p); +} + #endif /* SWIFT_PRESSURE_ENTROPY_HYDRO_H */ diff --git a/src/hydro/PressureEntropy/hydro_debug.h b/src/hydro/PressureEntropy/hydro_debug.h index 486543793..1192d9653 100644 --- a/src/hydro/PressureEntropy/hydro_debug.h +++ b/src/hydro/PressureEntropy/hydro_debug.h @@ -29,7 +29,6 @@ * Follows eqautions (19), (21) and (22) of Hopkins, P., MNRAS, 2013, * Volume 428, Issue 4, pp. 2840-2856 with a simple Balsara viscosity term. */ - __attribute__((always_inline)) INLINE static void hydro_debug_particle( const struct part* p, const struct xpart* xp) { printf( @@ -37,14 +36,14 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( "v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e],\n " "h=%.3e, wcount=%.3f, wcount_dh=%.3e, m=%.3e, dh_drho=%.3e, rho=%.3e, " "rho_bar=%.3e, P=%.3e, dP_dh=%.3e, P_over_rho2=%.3e, S=%.3e, S^1/g=%.3e, " - "dS/dt=%.3e,\nc=%.3e v_sig=%e dh/dt=%.3e t_begin=%d, t_end=%d\n", + "dS/dt=%.3e,\nc=%.3e v_sig=%e dh/dt=%.3e time_bin=%d\n", p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], xp->v_full[0], xp->v_full[1], xp->v_full[2], p->a_hydro[0], p->a_hydro[1], p->a_hydro[2], p->h, p->density.wcount, p->density.wcount_dh, p->mass, p->density.rho_dh, p->rho, p->rho_bar, hydro_get_pressure(p, 0.), p->density.pressure_dh, p->force.P_over_rho2, p->entropy, p->entropy_one_over_gamma, p->entropy_dt, p->force.soundspeed, p->force.v_sig, p->force.h_dt, - p->ti_begin, p->ti_end); + p->time_bin); } #endif /* SWIFT_PRESSURE_ENTROPY_HYDRO_DEBUG_H */ diff --git a/src/hydro/PressureEntropy/hydro_part.h b/src/hydro/PressureEntropy/hydro_part.h index cac585ff7..b6e496918 100644 --- a/src/hydro/PressureEntropy/hydro_part.h +++ b/src/hydro/PressureEntropy/hydro_part.h @@ -41,6 +41,9 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; + /*! Entropy at the last full step. */ + float entropy_full; + /*! Additional data used to record cooling information */ struct cooling_xpart_data cooling_data; @@ -49,6 +52,12 @@ struct xpart { /* Data of a single particle. */ struct part { + /*! Particle ID. */ + long long id; + + /*! Pointer to corresponding gravity part. */ + struct gpart* gpart; + /*! Particle position. */ double x[3]; @@ -64,12 +73,6 @@ struct part { /*! Particle mass. */ float mass; - /*! Particle time of beginning of time-step. */ - int ti_begin; - - /*! Particle time of end of time-step. */ - int ti_end; - /*! Particle density. */ float rho; @@ -132,11 +135,18 @@ struct part { } force; }; - /*! Particle ID. */ - long long id; + /* Time-step length */ + timebin_t time_bin; - /*! Pointer to corresponding gravity part. */ - struct gpart* gpart; +#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; -- GitLab From ed505bf4441502e933ffbdf58e90f42c36c09e26 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 7 Jan 2017 23:40:09 +0000 Subject: [PATCH 33/48] Make GIZMO compile in the new scheme. --- src/hydro/Gizmo/hydro.h | 23 ++++++++++++++++------- src/hydro/Gizmo/hydro_debug.h | 9 ++++----- src/hydro/Gizmo/hydro_iact.h | 7 ++++++- src/hydro/Gizmo/hydro_part.h | 27 +++++++++++++++++---------- 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h index 1c64291ee..7e25dc329 100644 --- a/src/hydro/Gizmo/hydro.h +++ b/src/hydro/Gizmo/hydro.h @@ -178,11 +178,10 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( * @param timeBase Conversion factor between integer time and physical time. */ __attribute__((always_inline)) INLINE static void hydro_prepare_force( - struct part* restrict p, struct xpart* restrict xp, int ti_current, - double timeBase) { + struct part* restrict p, struct xpart* restrict xp) { /* Set the physical time step */ - p->force.dt = (p->ti_end - p->ti_begin) * timeBase; + p->force.dt = get_timestep(p->time_bin, 0.); // MATTHIEU 0 /* Initialize time step criterion variables */ p->timestepvars.vmax = 0.0f; @@ -233,6 +232,16 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( p->force.h_dt = 0.0f; } +/** + * @brief Sets the values to be predicted in the drifts to their values at a + * kick time + * + * @param p The particle. + * @param xp The extended data of this particle. + */ +__attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( + struct part* restrict p, const struct xpart* restrict xp) {} + /** * @brief Converts the hydrodynamic variables from the initial condition file to * conserved variables that can be used during the integration @@ -250,7 +259,7 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( * @param p The particle to act upon. */ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( - struct part* p) { + struct part* p, struct xpart* xp) { const float volume = p->geometry.volume; const float m = p->conserved.mass; @@ -283,8 +292,7 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( * @param timeBase Conversion factor between integer and physical time. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part* p, struct xpart* xp, float dt, int t0, int t1, - double timeBase) { + struct part* p, struct xpart* xp, float dt) { const float h_inv = 1.0f / p->h; @@ -367,9 +375,10 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param half_dt Half the physical time step. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( - struct part* p, struct xpart* xp, float dt, float half_dt) { + struct part* p, struct xpart* xp, float dt) { float oldm, oldp[3], anew[3]; + const float half_dt = 0.5f * dt; //MATTHIEU /* Retrieve the current value of the gravitational acceleration from the gpart. We are only allowed to do this because this is the kick. We still diff --git a/src/hydro/Gizmo/hydro_debug.h b/src/hydro/Gizmo/hydro_debug.h index f4c071023..a05ff9a7d 100644 --- a/src/hydro/Gizmo/hydro_debug.h +++ b/src/hydro/Gizmo/hydro_debug.h @@ -24,8 +24,7 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( "v=[%.3e,%.3e,%.3e], " "a=[%.3e,%.3e,%.3e], " "h=%.3e, " - "ti_begin=%d, " - "ti_end=%d, " + "time_bin=%d, " "primitives={" "v=[%.3e,%.3e,%.3e], " "rho=%.3e, " @@ -54,9 +53,9 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( "curl_v=[%.3e,%.3e,%.3e], " "wcount=%.3e}\n", p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], p->a_hydro[0], - p->a_hydro[1], p->a_hydro[2], p->h, p->ti_begin, p->ti_end, - p->primitives.v[0], p->primitives.v[1], p->primitives.v[2], - p->primitives.rho, p->primitives.P, p->primitives.gradients.rho[0], + p->a_hydro[1], p->a_hydro[2], p->h, p->time_bin, p->primitives.v[0], + p->primitives.v[1], p->primitives.v[2], p->primitives.rho, + p->primitives.P, p->primitives.gradients.rho[0], p->primitives.gradients.rho[1], p->primitives.gradients.rho[2], p->primitives.gradients.v[0][0], p->primitives.gradients.v[0][1], p->primitives.gradients.v[0][2], p->primitives.gradients.v[1][0], diff --git a/src/hydro/Gizmo/hydro_iact.h b/src/hydro/Gizmo/hydro_iact.h index cf2b9a223..aba6bd53c 100644 --- a/src/hydro/Gizmo/hydro_iact.h +++ b/src/hydro/Gizmo/hydro_iact.h @@ -411,7 +411,12 @@ __attribute__((always_inline)) INLINE static void runner_iact_fluxes_common( UPDATE particle j. ==> we update particle j if (MODE IS 1) OR (j IS INACTIVE) */ - if (mode == 1 || pj->ti_end > pi->ti_end) { + + // MATTHIEU + const integertime_t pj_ti_end = 0; // get_integer_time_end(pj->time_bin); + const integertime_t pi_ti_end = 0; // get_integer_time_end(pi->time_bin); + + if (mode == 1 || pj_ti_end > pi_ti_end) { /* Store mass flux */ mflux = dtj * Anorm * totflux[0]; pj->gravity.mflux[0] -= mflux * dx[0]; diff --git a/src/hydro/Gizmo/hydro_part.h b/src/hydro/Gizmo/hydro_part.h index c4919ff17..f6592ca10 100644 --- a/src/hydro/Gizmo/hydro_part.h +++ b/src/hydro/Gizmo/hydro_part.h @@ -38,6 +38,12 @@ struct xpart { /* Data of a single particle. */ struct part { + /* Particle ID. */ + long long id; + + /* Associated gravitas. */ + struct gpart *gpart; + /* Particle position. */ double x[3]; @@ -50,12 +56,6 @@ struct part { /* Particle smoothing length. */ float h; - /* Particle time of beginning of time-step. */ - int ti_begin; - - /* Particle time of end of time-step. */ - int ti_end; - /* Old internal energy flux */ float du_dt; @@ -197,11 +197,18 @@ struct part { } gravity; - /* Particle ID. */ - long long id; + /* Time-step length */ + timebin_t time_bin; - /* Associated gravitas. */ - struct gpart *gpart; +#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; -- GitLab From 541745c25eb063d2f738dd066060333076812fee Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 11 Jan 2017 18:09:06 +0000 Subject: [PATCH 34/48] Updated the cooling to the new integration scheme --- examples/CoolingBox/coolingBox.yml | 6 +-- examples/CoolingBox/run.sh | 2 +- src/cooling/const_du/cooling.h | 4 +- src/cooling/const_lambda/cooling.h | 36 ++++++------- src/engine.c | 19 ++----- src/hydro/Gadget2/hydro.h | 87 ++++++++---------------------- src/hydro/Gadget2/hydro_debug.h | 2 +- src/hydro/Gadget2/hydro_io.h | 4 +- src/hydro/Gizmo/hydro.h | 2 +- src/runner.c | 22 ++++---- src/statistics.c | 4 +- 11 files changed, 65 insertions(+), 123 deletions(-) diff --git a/examples/CoolingBox/coolingBox.yml b/examples/CoolingBox/coolingBox.yml index b90ae61e5..4bf621dfb 100644 --- a/examples/CoolingBox/coolingBox.yml +++ b/examples/CoolingBox/coolingBox.yml @@ -10,8 +10,8 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 4. # The end time of the simulation (in internal units). - dt_min: 1e-4 # The minimal time-step size of the simulation (in internal units). - dt_max: 1e-4 # The maximal time-step size of the simulation (in internal units). + dt_min: 1e-5 # The minimal time-step size of the simulation (in internal units). + dt_max: 1e-2 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots Snapshots: @@ -35,7 +35,7 @@ InitialConditions: # Dimensionless pre-factor for the time-step condition LambdaCooling: - lambda_cgs: 1.0e-22 # Cooling rate (in cgs units) + lambda_cgs: 0. #1.0e-22 # Cooling rate (in cgs units) minimum_temperature: 1.0e4 # Minimal temperature (Kelvin) mean_molecular_weight: 0.59 # Mean molecular weight hydrogen_mass_abundance: 0.75 # Hydrogen mass abundance (dimensionless) diff --git a/examples/CoolingBox/run.sh b/examples/CoolingBox/run.sh index cb3264808..7a8e804d5 100755 --- a/examples/CoolingBox/run.sh +++ b/examples/CoolingBox/run.sh @@ -5,7 +5,7 @@ echo "Generating initial conditions for the cooling box example..." python makeIC.py 10 -../swift -s -C -t 16 coolingBox.yml +../swift -s -C -t 1 coolingBox.yml #-C 2>&1 | tee output.log diff --git a/src/cooling/const_du/cooling.h b/src/cooling/const_du/cooling.h index 448af9c37..07961f830 100644 --- a/src/cooling/const_du/cooling.h +++ b/src/cooling/const_du/cooling.h @@ -63,7 +63,7 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( struct part* restrict p, struct xpart* restrict xp, float dt) { /* Get current internal energy (dt=0) */ - const float u_old = hydro_get_internal_energy(p, 0.f); + const float u_old = hydro_get_internal_energy(p); /* Get cooling function properties */ const float du_dt = -cooling->cooling_rate; @@ -102,7 +102,7 @@ __attribute__((always_inline)) INLINE static float cooling_timestep( const struct UnitSystem* restrict us, const struct part* restrict p) { const float cooling_rate = cooling->cooling_rate; - const float internal_energy = hydro_get_internal_energy(p, 0); + const float internal_energy = hydro_get_internal_energy(p); return cooling->cooling_tstep_mult * internal_energy / fabsf(cooling_rate); } diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index cb9db2dc3..50a21a68b 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -76,31 +76,28 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( const struct cooling_function_data* restrict cooling, struct part* restrict p, struct xpart* restrict xp, float dt) { - /* Get current internal energy (dt=0) */ - const float u_old = hydro_get_internal_energy(p, 0.f); - /* Internal energy floor */ const float u_floor = cooling->min_energy; - /* Calculate du_dt */ - const float du_dt = cooling_rate(phys_const, us, cooling, p); + /* Current energy */ + const float u_old = hydro_get_internal_energy(p); - /* Integrate cooling equation, but enforce energy floor */ - float u_new; - if (u_old + du_dt * dt > u_floor) { - u_new = u_old + du_dt * dt; - } else { - u_new = u_floor; - } + /* Current du_dt */ + const float hydro_du_dt = hydro_get_internal_energy_dt(p); + + /* Calculate cooling du_dt */ + float cooling_du_dt = cooling_rate(phys_const, us, cooling, p); - /* Don't allow particle to cool too much in one timestep */ - if (u_new < 0.5f * u_old) u_new = 0.5f * u_old; + /* Integrate cooling equation to enforce energy floor */ + if (u_old + cooling_du_dt * dt < u_floor) { + cooling_du_dt = (u_old - u_floor) / dt; + } - /* Update the internal energy */ - hydro_set_internal_energy(p, u_new); + /* Update the internal energy time derivative */ + hydro_set_internal_energy_dt(p, hydro_du_dt + cooling_du_dt); /* Store the radiated energy */ - xp->cooling_data.radiated_energy += hydro_get_mass(p) * (u_old - u_new); + xp->cooling_data.radiated_energy += hydro_get_mass(p) * cooling_du_dt * dt; } /** @@ -117,11 +114,10 @@ __attribute__((always_inline)) INLINE static float cooling_timestep( const struct UnitSystem* restrict us, const struct part* restrict p) { /* Get current internal energy (dt=0) */ - const float u = hydro_get_internal_energy(p, 0.f); + const float u = hydro_get_internal_energy(p); const float du_dt = cooling_rate(phys_const, us, cooling, p); - /* If we are close to (or below) the energy floor, we ignore cooling timestep - */ + /* If we are close to (or below) the energy floor, we ignore the condition */ if (u < 1.01f * cooling->min_energy) return FLT_MAX; else diff --git a/src/engine.c b/src/engine.c index 3b61e7d2d..c49f2c81b 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1833,20 +1833,11 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { #endif } - /* /\* Cooling tasks should depend on kick and unlock sourceterms *\/ */ - /* else if (t->type == task_type_cooling) { */ - /* scheduler_addunlock(sched, t->ci->kick, t); */ - /* } */ - /* /\* source terms depend on cooling if performed, else on kick. It is the - * last */ - /* task *\/ */ - /* else if (t->type == task_type_sourceterms) { */ - /* if (e->policy == engine_policy_cooling) */ - /* scheduler_addunlock(sched, t->ci->cooling, t); */ - /* else */ - /* scheduler_addunlock(sched, t->ci->kick, t); */ - /* } */ - // MATTHIEU + /* Cooling tasks take place after the second kick */ + else if (t->type == task_type_cooling) { + scheduler_addunlock(sched, t->ci->kick2, t); + scheduler_addunlock(sched, t, t->ci->timestep); + } } } diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index bcf60d9e2..3a964b459 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -43,40 +43,33 @@ * @brief Returns the internal energy of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( - const struct part *restrict p, float dt) { - - const float entropy = p->entropy + dt * p->entropy_dt; + const struct part *restrict p) { - return gas_internal_energy_from_entropy(p->rho, entropy); + return gas_internal_energy_from_entropy(p->rho, p->entropy); } /** * @brief Returns the pressure of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_pressure( - const struct part *restrict p, float dt) { - - const float entropy = p->entropy + dt * p->entropy_dt; + const struct part *restrict p) { - return gas_pressure_from_entropy(p->rho, entropy); + return gas_pressure_from_entropy(p->rho, p->entropy); } /** * @brief Returns the entropy of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_entropy( - const struct part *restrict p, float dt) { + const struct part *restrict p) { - return p->entropy + dt * p->entropy_dt; + return p->entropy; } /** @@ -86,7 +79,7 @@ __attribute__((always_inline)) INLINE static float hydro_get_entropy( * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( - const struct part *restrict p, float dt) { + const struct part *restrict p) { return p->force.soundspeed; } @@ -114,70 +107,32 @@ __attribute__((always_inline)) INLINE static float hydro_get_mass( } /** - * @brief Modifies the thermal state of a particle to the imposed internal - * energy + * @brief Returns the time derivative of internal energy of a particle * - * This overwrites the current state of the particle but does *not* change its - * time-derivatives. Entropy, pressure, sound-speed and signal velocity will be - * updated. + * We assume a constant density. * - * @param p The particle - * @param u The new internal energy + * @param p The particle of interest */ -__attribute__((always_inline)) INLINE static void hydro_set_internal_energy( - struct part *restrict p, float u) { - - p->entropy = gas_entropy_from_internal_energy(p->rho, u); - - /* Compute the new pressure */ - const float pressure = gas_pressure_from_internal_energy(p->rho, u); - - /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); - - /* Update the signal velocity */ - const float v_sig_old = p->force.v_sig; - const float v_sig_new = p->force.v_sig - p->force.soundspeed + soundspeed; - const float v_sig = max(v_sig_old, v_sig_new); - - const float rho_inv = 1.f / p->rho; +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy_dt( + const struct part *restrict p) { - p->force.soundspeed = soundspeed; - p->force.P_over_rho2 = pressure * rho_inv * rho_inv; - p->force.v_sig = v_sig; + return gas_internal_energy_from_entropy(p->rho, p->entropy_dt); } /** - * @brief Modifies the thermal state of a particle to the imposed entropy + * @brief Returns the time derivative of internal energy of a particle * - * This overwrites the current state of the particle but does *not* change its - * time-derivatives. Entropy, pressure, sound-speed and signal velocity will be - * updated. + * We assume a constant density. * - * @param p The particle - * @param S The new entropy + * @param p The particle of interest. + * @param du_dt The new time derivative of the internal energy. */ -__attribute__((always_inline)) INLINE static void hydro_set_entropy( - struct part *restrict p, float S) { - - p->entropy = S; - - /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); - - /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); - - /* Update the signal velocity */ - const float v_sig_old = p->force.v_sig; - const float v_sig_new = p->force.v_sig - p->force.soundspeed + soundspeed; - const float v_sig = max(v_sig_old, v_sig_new); +__attribute__((always_inline)) INLINE static void hydro_set_internal_energy_dt( + struct part *restrict p, float du_dt) { - const float rho_inv = 1.f / p->rho; + const float ds_dt = gas_entropy_from_internal_energy(p->rho, du_dt); - p->force.soundspeed = soundspeed; - p->force.P_over_rho2 = pressure * rho_inv * rho_inv; - p->force.v_sig = v_sig; + p->entropy_dt = ds_dt; } /** diff --git a/src/hydro/Gadget2/hydro_debug.h b/src/hydro/Gadget2/hydro_debug.h index a9630a128..6500d1126 100644 --- a/src/hydro/Gadget2/hydro_debug.h +++ b/src/hydro/Gadget2/hydro_debug.h @@ -31,7 +31,7 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], xp->v_full[0], xp->v_full[1], xp->v_full[2], p->a_hydro[0], p->a_hydro[1], p->a_hydro[2], p->h, p->density.wcount, p->density.wcount_dh, p->mass, p->density.rho_dh, - p->rho, hydro_get_pressure(p, 0.), p->force.P_over_rho2, p->entropy, + p->rho, hydro_get_pressure(p), p->force.P_over_rho2, p->entropy, p->entropy_dt, p->force.soundspeed, p->density.div_v, p->density.rot_v[0], p->density.rot_v[1], p->density.rot_v[2], p->force.balsara, p->force.v_sig, p->force.h_dt, p->time_bin); diff --git a/src/hydro/Gadget2/hydro_io.h b/src/hydro/Gadget2/hydro_io.h index 433aef64c..162d368dd 100644 --- a/src/hydro/Gadget2/hydro_io.h +++ b/src/hydro/Gadget2/hydro_io.h @@ -57,12 +57,12 @@ void hydro_read_particles(struct part* parts, struct io_props* list, float convert_u(struct engine* e, struct part* p) { - return hydro_get_internal_energy(p, 0); + return hydro_get_internal_energy(p); } float convert_P(struct engine* e, struct part* p) { - return hydro_get_pressure(p, 0); + return hydro_get_pressure(p); } /** diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h index 7e25dc329..bde24ed71 100644 --- a/src/hydro/Gizmo/hydro.h +++ b/src/hydro/Gizmo/hydro.h @@ -378,7 +378,7 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part* p, struct xpart* xp, float dt) { float oldm, oldp[3], anew[3]; - const float half_dt = 0.5f * dt; //MATTHIEU + const float half_dt = 0.5f * dt; // MATTHIEU /* Retrieve the current value of the gravitational acceleration from the gpart. We are only allowed to do this because this is the kick. We still diff --git a/src/runner.c b/src/runner.c index 25b817173..3dd27346f 100644 --- a/src/runner.c +++ b/src/runner.c @@ -206,14 +206,17 @@ void runner_do_cooling(struct runner *r, struct cell *c, int timer) { struct part *restrict parts = c->parts; struct xpart *restrict xparts = c->xparts; const int count = c->count; - // const int ti_current = r->e->ti_current; - const struct cooling_function_data *cooling_func = r->e->cooling_func; - const struct phys_const *constants = r->e->physical_constants; - const struct UnitSystem *us = r->e->internalUnits; - const double timeBase = r->e->timeBase; + const struct engine *e = r->e; + const struct cooling_function_data *cooling_func = e->cooling_func; + const struct phys_const *constants = e->physical_constants; + const struct UnitSystem *us = e->internalUnits; + const double timeBase = e->timeBase; TIMER_TIC; + /* Anything to do here? */ + if (!cell_is_active(c, e)) return; + /* Recurse? */ if (c->split) { for (int k = 0; k < 8; k++) @@ -227,13 +230,10 @@ void runner_do_cooling(struct runner *r, struct cell *c, int timer) { struct part *restrict p = &parts[i]; struct xpart *restrict xp = &xparts[i]; - /* Kick has already updated ti_end, so need to check ti_begin */ - // if (p->ti_begin == ti_current) { - { - - // const double dt = (p->ti_end - p->ti_begin) * timeBase; - const double dt = 1. * timeBase; // MATTHIEU + if (part_is_active(p, e)) { + /* Let's cool ! */ + const double dt = get_timestep(p->time_bin, timeBase); cooling_cool_part(constants, us, cooling_func, p, xp, dt); } } diff --git a/src/statistics.c b/src/statistics.c index 4febdf096..297d88c1f 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -162,14 +162,14 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { /* Collect energies. */ stats.E_kin += 0.5f * m * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - stats.E_int += m * hydro_get_internal_energy(p, dt); + stats.E_int += m * hydro_get_internal_energy(p); stats.E_rad += cooling_get_radiated_energy(xp); stats.E_pot_self += 0.f; if (gp != NULL) stats.E_pot_ext += m * external_gravity_get_potential_energy( time, potential, phys_const, gp); /* Collect entropy */ - stats.entropy += m * hydro_get_entropy(p, dt); + stats.entropy += m * hydro_get_entropy(p); } /* Now write back to memory */ -- GitLab From 8e101be6f9c21646bd38a18047a21d6d49e67b9e Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 12 Jan 2017 23:07:53 +0000 Subject: [PATCH 35/48] Create ICs for cooling box in a better way. --- examples/CoolingBox/coolingBox.yml | 2 +- examples/CoolingBox/getGlass.sh | 2 ++ examples/CoolingBox/makeIC.py | 50 +++++++++++++----------------- examples/CoolingBox/run.sh | 20 +++++++----- src/cooling/const_lambda/cooling.h | 4 +-- src/statistics.c | 2 +- 6 files changed, 40 insertions(+), 40 deletions(-) create mode 100755 examples/CoolingBox/getGlass.sh diff --git a/examples/CoolingBox/coolingBox.yml b/examples/CoolingBox/coolingBox.yml index 4bf621dfb..902472037 100644 --- a/examples/CoolingBox/coolingBox.yml +++ b/examples/CoolingBox/coolingBox.yml @@ -35,7 +35,7 @@ InitialConditions: # Dimensionless pre-factor for the time-step condition LambdaCooling: - lambda_cgs: 0. #1.0e-22 # Cooling rate (in cgs units) + lambda_cgs: 1.0e-22 # Cooling rate (in cgs units) minimum_temperature: 1.0e4 # Minimal temperature (Kelvin) mean_molecular_weight: 0.59 # Mean molecular weight hydrogen_mass_abundance: 0.75 # Hydrogen mass abundance (dimensionless) diff --git a/examples/CoolingBox/getGlass.sh b/examples/CoolingBox/getGlass.sh new file mode 100755 index 000000000..ffd92e88d --- /dev/null +++ b/examples/CoolingBox/getGlass.sh @@ -0,0 +1,2 @@ +#!/bin/bash +wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/glassCube_32.hdf5 diff --git a/examples/CoolingBox/makeIC.py b/examples/CoolingBox/makeIC.py index 5de012a17..f863e174b 100644 --- a/examples/CoolingBox/makeIC.py +++ b/examples/CoolingBox/makeIC.py @@ -1,6 +1,6 @@ ############################################################################### # This file is part of SWIFT. - # Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk), + # Copyright (c) 2016 Stefan Arridge (stefan.arridge@durhama.ac.uk) # Matthieu Schaller (matthieu.schaller@durham.ac.uk) # # This program is free software: you can redistribute it and/or modify @@ -22,13 +22,11 @@ import h5py import sys from numpy import * -# Generates a swift IC file containing a cartesian distribution of particles -# at a constant density and pressure in a cubic box +# Generates a SWIFT IC file with a constant density and pressure # Parameters periodic= 1 # 1 For periodic box boxSize = 1 # 1 kiloparsec -L = int(sys.argv[1]) # Number of particles along one axis rho = 3.2e3 # Density in code units (3.2e6 is 0.1 hydrogen atoms per cm^3) P = 4.5e6 # Pressure in code units (at 10^5K) gamma = 5./3. # Gas adiabatic index @@ -36,12 +34,17 @@ eta = 1.2349 # 48 ngbs with cubic spline kernel fileName = "coolingBox.hdf5" #--------------------------------------------------- -numPart = L**3 -mass = boxSize**3 * rho / numPart -print mass -internalEnergy = P / ((gamma - 1.)*rho) -#-------------------------------------------------- +# Read id, position and h from glass +glass = h5py.File("glassCube_32.hdf5", "r") +ids = glass["/PartType0/ParticleIDs"][:] +pos = glass["/PartType0/Coordinates"][:,:] * boxSize +h = glass["/PartType0/SmoothingLength"][:] * boxSize + +# Compute basic properties +numPart = size(pos) / 3 +mass = boxSize**3 * rho / numPart +internalEnergy = P / ((gamma - 1.) * rho) #File file = h5py.File(fileName, 'w') @@ -57,11 +60,11 @@ grp.attrs["NumFilesPerSnapshot"] = 1 grp.attrs["MassTable"] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] grp.attrs["Flag_Entropy_ICs"] = 0 -#Runtime parameters +# Runtime parameters grp = file.create_group("/RuntimePars") grp.attrs["PeriodicBoundariesOn"] = periodic -#Units +# Units grp = file.create_group("/Units") grp.attrs["Unit length in cgs (U_L)"] = 3.0857e21 grp.attrs["Unit mass in cgs (U_M)"] = 2.0e33 @@ -75,35 +78,26 @@ grp = file.create_group("/PartType0") v = zeros((numPart, 3)) ds = grp.create_dataset('Velocities', (numPart, 3), 'f') ds[()] = v -v = zeros(1) m = full((numPart, 1), mass) ds = grp.create_dataset('Masses', (numPart,1), 'f') ds[()] = m -m = zeros(1) -h = full((numPart, 1), eta * boxSize / L) -ds = grp.create_dataset('SmoothingLength', (numPart,1), 'f') +h = reshape(h, (numPart, 1)) +ds = grp.create_dataset('SmoothingLength', (numPart, 1), 'f') ds[()] = h -h = zeros(1) u = full((numPart, 1), internalEnergy) ds = grp.create_dataset('InternalEnergy', (numPart,1), 'f') ds[()] = u -u = zeros(1) - -ids = linspace(0, numPart, numPart, endpoint=False).reshape((numPart,1)) +ids = reshape(ids, (numPart, 1)) ds = grp.create_dataset('ParticleIDs', (numPart, 1), 'L') -ds[()] = ids + 1 -x = ids % L; -y = ((ids - x) / L) % L; -z = (ids - x - L * y) / L**2; -coords = zeros((numPart, 3)) -coords[:,0] = z[:,0] * boxSize / L + boxSize / (2*L) -coords[:,1] = y[:,0] * boxSize / L + boxSize / (2*L) -coords[:,2] = x[:,0] * boxSize / L + boxSize / (2*L) +ds[()] = ids + ds = grp.create_dataset('Coordinates', (numPart, 3), 'd') -ds[()] = coords +ds[()] = pos file.close() + +print numPart diff --git a/examples/CoolingBox/run.sh b/examples/CoolingBox/run.sh index 7a8e804d5..fae7fd4ac 100755 --- a/examples/CoolingBox/run.sh +++ b/examples/CoolingBox/run.sh @@ -1,14 +1,18 @@ #!/bin/bash # Generate the initial conditions if they are not present. -echo "Generating initial conditions for the cooling box example..." - -python makeIC.py 10 +if [ ! -e glassCube_32.hdf5 ] +then + echo "Fetching initial glass file for the cooling box example..." + ./getGlass.sh +fi +if [ ! -e coolingBox.hdf5 ] +then + echo "Generating initial conditions for the cooling box example..." + python makeIC.py +fi +# Run SWIFT ../swift -s -C -t 1 coolingBox.yml -#-C 2>&1 | tee output.log - -python energy_plot.py 0 - -#python test_energy_conservation.py 0 +# Check energy conservation and cooling rate diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index 50a21a68b..eced1910e 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -97,7 +97,7 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( hydro_set_internal_energy_dt(p, hydro_du_dt + cooling_du_dt); /* Store the radiated energy */ - xp->cooling_data.radiated_energy += hydro_get_mass(p) * cooling_du_dt * dt; + xp->cooling_data.radiated_energy += -hydro_get_mass(p) * cooling_du_dt * dt; } /** @@ -113,7 +113,7 @@ __attribute__((always_inline)) INLINE static float cooling_timestep( const struct phys_const* restrict phys_const, const struct UnitSystem* restrict us, const struct part* restrict p) { - /* Get current internal energy (dt=0) */ + /* Get current internal energy */ const float u = hydro_get_internal_energy(p); const float du_dt = cooling_rate(phys_const, us, cooling, p); diff --git a/src/statistics.c b/src/statistics.c index 297d88c1f..b40f7afb6 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -163,7 +163,7 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { /* Collect energies. */ stats.E_kin += 0.5f * m * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); stats.E_int += m * hydro_get_internal_energy(p); - stats.E_rad += cooling_get_radiated_energy(xp); + stats.E_rad += cooling_get_radiated_energy(xp) / 2.; stats.E_pot_self += 0.f; if (gp != NULL) stats.E_pot_ext += m * external_gravity_get_potential_energy( -- GitLab From ac592f056f58cce51f4190d0a9eab620095b7e2a Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 12 Jan 2017 23:52:59 +0000 Subject: [PATCH 36/48] Updated the cooling box example. --- examples/CoolingBox/coolingBox.yml | 24 ++--- examples/CoolingBox/energy_plot.py | 151 ++++++++++++++++------------- examples/CoolingBox/run.sh | 2 + 3 files changed, 100 insertions(+), 77 deletions(-) diff --git a/examples/CoolingBox/coolingBox.yml b/examples/CoolingBox/coolingBox.yml index 902472037..a8178d967 100644 --- a/examples/CoolingBox/coolingBox.yml +++ b/examples/CoolingBox/coolingBox.yml @@ -1,15 +1,15 @@ # Define the system of units to use internally. InternalUnitSystem: - UnitMass_in_cgs: 2.0e33 # Solar masses - UnitLength_in_cgs: 3.0857e21 # Kiloparsecs - UnitVelocity_in_cgs: 1.0e5 # Time unit is cooling time - UnitCurrent_in_cgs: 1 # Amperes - UnitTemp_in_cgs: 1 # Kelvin + UnitMass_in_cgs: 2.0e33 # Solar masses + UnitLength_in_cgs: 3.0857e21 # Kiloparsecs + UnitVelocity_in_cgs: 1.0e5 # Kilometers per second + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin # Parameters governing the time integration TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). - time_end: 4. # The end time of the simulation (in internal units). + time_end: 0.4 # The end time of the simulation (in internal units). dt_min: 1e-5 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-2 # The maximal time-step size of the simulation (in internal units). @@ -21,7 +21,7 @@ Snapshots: # Parameters governing the conserved quantities statistics Statistics: - delta_time: 1e-2 # Time between statistics output + delta_time: 1e-3 # Time between statistics output # Parameters for the hydrodynamics scheme SPH: @@ -35,8 +35,8 @@ InitialConditions: # Dimensionless pre-factor for the time-step condition LambdaCooling: - lambda_cgs: 1.0e-22 # Cooling rate (in cgs units) - minimum_temperature: 1.0e4 # Minimal temperature (Kelvin) - mean_molecular_weight: 0.59 # Mean molecular weight - hydrogen_mass_abundance: 0.75 # Hydrogen mass abundance (dimensionless) - cooling_tstep_mult: 1.0 # Dimensionless pre-factor for the time-step condition + lambda_cgs: 1.0e-22 # Cooling rate (in cgs units) + minimum_temperature: 1.0e4 # Minimal temperature (Kelvin) + mean_molecular_weight: 0.59 # Mean molecular weight + hydrogen_mass_abundance: 0.75 # Hydrogen mass abundance (dimensionless) + cooling_tstep_mult: 1.0 # Dimensionless pre-factor for the time-step condition diff --git a/examples/CoolingBox/energy_plot.py b/examples/CoolingBox/energy_plot.py index 00e6fd1df..56a220fc8 100644 --- a/examples/CoolingBox/energy_plot.py +++ b/examples/CoolingBox/energy_plot.py @@ -1,99 +1,120 @@ +import matplotlib +matplotlib.use("Agg") +from pylab import * +import h5py + +# Plot parameters +params = {'axes.labelsize': 10, +'axes.titlesize': 10, +'font.size': 12, +'legend.fontsize': 12, +'xtick.labelsize': 10, +'ytick.labelsize': 10, +'text.usetex': True, + 'figure.figsize' : (3.15,3.15), +'figure.subplot.left' : 0.145, +'figure.subplot.right' : 0.99, +'figure.subplot.bottom' : 0.11, +'figure.subplot.top' : 0.99, +'figure.subplot.wspace' : 0.15, +'figure.subplot.hspace' : 0.12, +'lines.markersize' : 6, +'lines.linewidth' : 3., +'text.latex.unicode': True +} +rcParams.update(params) +rc('font',**{'family':'sans-serif','sans-serif':['Times']}) + + import numpy as np -import matplotlib.pyplot as plt import h5py as h5 import sys +# File containing the total energy stats_filename = "./energy.txt" + +# First snapshot snap_filename = "coolingBox_000.hdf5" -#plot_dir = "./" -#some constants in cgs units +# Some constants in cgs units k_b = 1.38E-16 #boltzmann m_p = 1.67e-24 #proton mass -#initial conditions set in makeIC.py -rho = 3.2e3 -P = 4.5e6 -#n_H_cgs = 0.0001 -gamma = 5./3. + +# Initial conditions set in makeIC.py T_init = 1.0e5 -#Read the units parameters from the snapshot +# Read the initial state of the gas f = h5.File(snap_filename,'r') +rho = np.mean(f["/PartType0/Density"]) +pressure = np.mean(f["/PartType0/Pressure"]) + +# Read the units parameters from the snapshot units = f["InternalCodeUnits"] unit_mass = units.attrs["Unit mass in cgs (U_M)"] unit_length = units.attrs["Unit length in cgs (U_L)"] unit_time = units.attrs["Unit time in cgs (U_t)"] + +# Read the properties of the cooling function parameters = f["Parameters"] cooling_lambda = float(parameters.attrs["LambdaCooling:lambda_cgs"]) min_T = float(parameters.attrs["LambdaCooling:minimum_temperature"]) mu = float(parameters.attrs["LambdaCooling:mean_molecular_weight"]) X_H = float(parameters.attrs["LambdaCooling:hydrogen_mass_abundance"]) -#get number of particles -header = f["Header"] -n_particles = header.attrs["NumPart_ThisFile"][0] +# Read the adiabatic index +gamma = float(f["HydroScheme"].attrs["Adiabatic index"]) + +print "Initial density :", rho +print "Initial pressure:", pressure +print "Adiabatic index :", gamma -#read energy and time arrays +# Read energy and time arrays array = np.genfromtxt(stats_filename,skip_header = 1) time = array[:,0] -kin_plus_therm = array[:,2] -radiated = array[:,6] total_mass = array[:,1] - -#ignore first row where there are just zeros -time = time[1:] -kin_plus_therm = kin_plus_therm[1:] -radiated = radiated[1:] -total_mass = total_mass[1:] - -total_energy = kin_plus_therm + radiated +total_energy = array[:,2] +kinetic_energy = array[:,3] +internal_energy = array[:,4] +radiated_energy = array[:,8] initial_energy = total_energy[0] -#conversions to cgs + +# Conversions to cgs rho_cgs = rho * unit_mass / (unit_length)**3 time_cgs = time * unit_time -initial_energy_cgs = initial_energy/total_mass[0] * unit_length**2 / (unit_time)**2 -n_H_cgs = X_H * rho_cgs / m_p +total_energy_cgs = total_energy / total_mass[0] * unit_length**2 / (unit_time)**2 +kinetic_energy_cgs = kinetic_energy / total_mass[0] * unit_length**2 / (unit_time)**2 +internal_energy_cgs = kinetic_energy / total_mass[0] * unit_length**2 / (unit_time)**2 +radiated_energy_cgs = radiated_energy / total_mass[0] * unit_length**2 / (unit_time)**2 -#find the energy floor +# Find the energy floor u_floor_cgs = k_b * min_T / (mu * m_p * (gamma - 1.)) -#find analytic solution -analytic_time_cgs = np.linspace(0,time_cgs[-1],1000) +# Find analytic solution +initial_energy_cgs = initial_energy/total_mass[0] * unit_length**2 / (unit_time)**2 +n_H_cgs = X_H * rho_cgs / m_p du_dt_cgs = -cooling_lambda * n_H_cgs**2 / rho_cgs +cooling_time_cgs = (initial_energy_cgs/(-du_dt_cgs))[0] +analytic_time_cgs = np.linspace(0, cooling_time_cgs*1.5,1000) u_analytic_cgs = du_dt_cgs*analytic_time_cgs + initial_energy_cgs -cooling_time_cgs = initial_energy_cgs/(-du_dt_cgs) - -for i in range(u_analytic_cgs.size): - if u_analytic_cgs[i] Date: Fri, 13 Jan 2017 00:27:39 +0000 Subject: [PATCH 37/48] No spurious factor of two in the radiateed energy statistics calculation --- examples/CoolingBox/energy_plot.py | 10 +++++----- src/cooling/const_lambda/cooling.h | 6 ++++-- src/hydro/Gadget2/hydro.h | 12 ++++-------- src/statistics.c | 2 +- 4 files changed, 14 insertions(+), 16 deletions(-) diff --git a/examples/CoolingBox/energy_plot.py b/examples/CoolingBox/energy_plot.py index 56a220fc8..719431d73 100644 --- a/examples/CoolingBox/energy_plot.py +++ b/examples/CoolingBox/energy_plot.py @@ -94,7 +94,7 @@ initial_energy_cgs = initial_energy/total_mass[0] * unit_length**2 / (unit_time) n_H_cgs = X_H * rho_cgs / m_p du_dt_cgs = -cooling_lambda * n_H_cgs**2 / rho_cgs cooling_time_cgs = (initial_energy_cgs/(-du_dt_cgs))[0] -analytic_time_cgs = np.linspace(0, cooling_time_cgs*1.5,1000) +analytic_time_cgs = np.linspace(0, cooling_time_cgs * 1.8, 1000) u_analytic_cgs = du_dt_cgs*analytic_time_cgs + initial_energy_cgs u_analytic_cgs[u_analytic_cgs < u_floor_cgs] = u_floor_cgs @@ -103,11 +103,11 @@ print "Cooling time:", cooling_time_cgs, "[s]" figure() #plot(time_cgs, internal_energy_cgs, 'b-', lw=1.5, label="Gas internal energy") #plot(time_cgs, kinetic_energy_cgs, 'y-', lw=1.5, label="Gas kinetic energy") -plot(time_cgs, total_energy_cgs, 'r-', lw=1.5, label="Gas total energy") -plot(time_cgs, radiated_energy_cgs, 'g-', lw=1.5, label="Radiated energy") -plot(time_cgs, total_energy_cgs + radiated_energy_cgs, 'k-', lw=0.6, label="Gas+radiated") +plot(time_cgs, total_energy_cgs, 'r-', lw=1.6, label="Gas total energy") +plot(time_cgs, radiated_energy_cgs, 'g-', lw=1.6, label="Radiated energy") +plot(time_cgs, total_energy_cgs + radiated_energy_cgs, 'b-', lw=0.6, label="Gas total + radiated") -plot(analytic_time_cgs, u_analytic_cgs, '--', color='k', alpha=0.8, lw=1.2, label="Analytic solution") +plot(analytic_time_cgs, u_analytic_cgs, '--', color='k', alpha=0.8, lw=1.0, label="Analytic solution") legend(loc="upper right", fontsize=8) xlabel("${\\rm{Time~[s]}}$", labelpad=0) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index eced1910e..e2451993a 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -89,8 +89,10 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( float cooling_du_dt = cooling_rate(phys_const, us, cooling, p); /* Integrate cooling equation to enforce energy floor */ - if (u_old + cooling_du_dt * dt < u_floor) { - cooling_du_dt = (u_old - u_floor) / dt; + if (u_old + hydro_du_dt < u_floor) { + cooling_du_dt = 0.f; + } else if (u_old + (hydro_du_dt + cooling_du_dt) * dt < u_floor) { + cooling_du_dt = (u_old + dt * hydro_du_dt - u_floor) / dt; } /* Update the internal energy time derivative */ diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 3a964b459..a2544aff8 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -130,9 +130,7 @@ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy_dt( __attribute__((always_inline)) INLINE static void hydro_set_internal_energy_dt( struct part *restrict p, float du_dt) { - const float ds_dt = gas_entropy_from_internal_energy(p->rho, du_dt); - - p->entropy_dt = ds_dt; + p->entropy_dt = gas_entropy_from_internal_energy(p->rho, du_dt); } /** @@ -379,12 +377,10 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt) { - /* Do not decrease the entropy (temperature) by more than a factor of 2*/ + /* Do not decrease the entropy by more than a factor of 2 */ const float entropy_change = p->entropy_dt * dt; - if (entropy_change > -0.5f * xp->entropy_full) - xp->entropy_full += entropy_change; - else - xp->entropy_full *= 0.5f; + xp->entropy_full = + max(xp->entropy_full + entropy_change, 0.5f * xp->entropy_full); /* Compute the pressure */ const float pressure = gas_pressure_from_entropy(p->rho, xp->entropy_full); diff --git a/src/statistics.c b/src/statistics.c index b40f7afb6..297d88c1f 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -163,7 +163,7 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { /* Collect energies. */ stats.E_kin += 0.5f * m * (v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); stats.E_int += m * hydro_get_internal_energy(p); - stats.E_rad += cooling_get_radiated_energy(xp) / 2.; + stats.E_rad += cooling_get_radiated_energy(xp); stats.E_pot_self += 0.f; if (gp != NULL) stats.E_pot_ext += m * external_gravity_get_potential_energy( -- GitLab From 226ff24a74eaec4c470bd55d2964681e8d67c2ac Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 13 Jan 2017 00:36:59 +0000 Subject: [PATCH 38/48] Also updated the Minimal hydro scheme to the new cooling way --- .../CoolingBox/test_energy_conservation.py | 116 ------------------ src/hydro/Minimal/hydro.h | 90 ++++---------- src/hydro/Minimal/hydro_io.h | 4 +- 3 files changed, 23 insertions(+), 187 deletions(-) delete mode 100644 examples/CoolingBox/test_energy_conservation.py diff --git a/examples/CoolingBox/test_energy_conservation.py b/examples/CoolingBox/test_energy_conservation.py deleted file mode 100644 index bb15071c0..000000000 --- a/examples/CoolingBox/test_energy_conservation.py +++ /dev/null @@ -1,116 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt -import h5py as h5 -import sys - -stats_filename = "./energy.txt" -snap_filename = "coolingBox_000.hdf5" -#plot_dir = "./" -n_snaps = 41 -time_end = 4.0 -dt_snap = 0.1 -#some constants in cgs units -k_b = 1.38E-16 #boltzmann -m_p = 1.67e-24 #proton mass -#initial conditions set in makeIC.py -rho = 4.8e3 -P = 4.5e6 -#n_H_cgs = 0.0001 -gamma = 5./3. -T_init = 1.0e5 - -#find the sound speed - -#Read the units parameters from the snapshot -f = h5.File(snap_filename,'r') -units = f["InternalCodeUnits"] -unit_mass = units.attrs["Unit mass in cgs (U_M)"] -unit_length = units.attrs["Unit length in cgs (U_L)"] -unit_time = units.attrs["Unit time in cgs (U_t)"] -parameters = f["Parameters"] -cooling_lambda = float(parameters.attrs["LambdaCooling:lambda_cgs"]) -min_T = float(parameters.attrs["LambdaCooling:minimum_temperature"]) -mu = float(parameters.attrs["LambdaCooling:mean_molecular_weight"]) -X_H = float(parameters.attrs["LambdaCooling:hydrogen_mass_abundance"]) - -#get number of particles -header = f["Header"] -n_particles = header.attrs["NumPart_ThisFile"][0] -#read energy and time arrays -array = np.genfromtxt(stats_filename,skip_header = 1) -time = array[:,0] -total_energy = array[:,2] -total_mass = array[:,1] - -time = time[1:] -total_energy = total_energy[1:] -total_mass = total_mass[1:] - -#conversions to cgs -rho_cgs = rho * unit_mass / (unit_length)**3 -time_cgs = time * unit_time -u_init_cgs = total_energy[0]/(total_mass[0]) * unit_length**2 / (unit_time)**2 -n_H_cgs = X_H * rho_cgs / m_p - -#find the sound speed in cgs -c_s = np.sqrt((gamma - 1.)*k_b*T_init/(mu*m_p)) -#assume box size is unit length -sound_crossing_time = unit_length/c_s - -print "Sound speed = %g cm/s" %c_s -print "Sound crossing time = %g s" %sound_crossing_time -#find the energy floor -u_floor_cgs = k_b * min_T / (mu * m_p * (gamma - 1.)) -#find analytic solution -analytic_time_cgs = np.linspace(time_cgs[0],time_cgs[-1],1000) -du_dt_cgs = -cooling_lambda * n_H_cgs**2 / rho_cgs -u_analytic = du_dt_cgs*(analytic_time_cgs - analytic_time_cgs[0]) + u_init_cgs -cooling_time = u_init_cgs/(-du_dt_cgs) - -#put time in units of sound crossing time -time=time_cgs/sound_crossing_time -analytic_time = analytic_time_cgs/sound_crossing_time -#rescale energy to initial energy -total_energy /= total_energy[0] -u_analytic /= u_init_cgs -u_floor_cgs /= u_init_cgs -# plot_title = r"$\Lambda \, = \, %1.1g \mathrm{erg}\mathrm{cm^3}\mathrm{s^{-1}} \, \, T_{init} = %1.1g\mathrm{K} \, \, T_{floor} = %1.1g\mathrm{K} \, \, n_H = %1.1g\mathrm{cm^{-3}}$" %(cooling_lambda,T_init,T_floor,n_H) -# plot_filename = "energy_plot_creasey_no_cooling_T_init_1p0e5_n_H_0p1.png" -#analytic_solution = np.zeros(n_snaps-1) -for i in range(u_analytic.size): - if u_analytic[i]u + p->u_dt * dt; + return p->u; } /** * @brief Returns the pressure of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_pressure( - const struct part *restrict p, float dt) { - - const float u = p->u + p->u_dt * dt; + const struct part *restrict p) { - return gas_pressure_from_internal_energy(p->rho, u); + return gas_pressure_from_internal_energy(p->rho, p->u); } /** @@ -79,24 +75,20 @@ __attribute__((always_inline)) INLINE static float hydro_get_pressure( * the thermodynamic variable. * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_entropy( - const struct part *restrict p, float dt) { - - const float u = p->u + p->u_dt * dt; + const struct part *restrict p) { - return gas_entropy_from_internal_energy(p->rho, u); + return gas_entropy_from_internal_energy(p->rho, p->u); } /** * @brief Returns the sound speed of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( - const struct part *restrict p, float dt) { + const struct part *restrict p) { return p->force.soundspeed; } @@ -124,68 +116,31 @@ __attribute__((always_inline)) INLINE static float hydro_get_mass( } /** - * @brief Modifies the thermal state of a particle to the imposed internal - * energy + * @brief Returns the time derivative of internal energy of a particle * - * This overwrites the current state of the particle but does *not* change its - * time-derivatives. Internal energy, pressure, sound-speed and signal velocity - * will be updated. + * We assume a constant density. * - * @param p The particle - * @param u The new internal energy + * @param p The particle of interest */ -__attribute__((always_inline)) INLINE static void hydro_set_internal_energy( - struct part *restrict p, float u) { - - p->u = u; - - /* Compute the new pressure */ - const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); - - /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_internal_energy(p->rho, p->u); - - /* Update the signal velocity */ - const float v_sig_old = p->force.v_sig; - const float v_sig_new = p->force.v_sig - p->force.soundspeed + soundspeed; - const float v_sig = max(v_sig_old, v_sig_new); +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy_dt( + const struct part *restrict p) { - p->force.soundspeed = soundspeed; - p->force.pressure = pressure; - p->force.v_sig = v_sig; + return p->u_dt; } /** - * @brief Modifies the thermal state of a particle to the imposed entropy + * @brief Returns the time derivative of internal energy of a particle * - * This overwrites the current state of the particle but does *not* change its - * time-derivatives. Internal energy, pressure, sound-speed and signal velocity - * will be updated. + * We assume a constant density. * - * @param p The particle - * @param S The new entropy + * @param p The particle of interest. + * @param du_dt The new time derivative of the internal energy. */ -__attribute__((always_inline)) INLINE static void hydro_set_entropy( - struct part *restrict p, float S) { - - p->u = gas_internal_energy_from_entropy(p->rho, S); +__attribute__((always_inline)) INLINE static void hydro_set_internal_energy_dt( + struct part *restrict p, float du_dt) { - /* Compute the pressure */ - const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); - - /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_internal_energy(p->rho, p->u); - - /* Update the signal velocity */ - const float v_sig_old = p->force.v_sig; - const float v_sig_new = p->force.v_sig - p->force.soundspeed + soundspeed; - const float v_sig = max(v_sig_old, v_sig_new); - - p->force.soundspeed = soundspeed; - p->force.pressure = pressure; - p->force.v_sig = v_sig; + p->u_dt = du_dt; } - /** * @brief Computes the hydro time-step of a given particle * @@ -406,10 +361,7 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( /* Do not decrease the energy by more than a factor of 2*/ const float u_change = p->u_dt * dt; - if (u_change > -0.5f * xp->u_full) - xp->u_full += u_change; - else - xp->u_full *= 0.5f; + xp->u_full = max(xp->u_full + u_change, 0.5f * xp->u_full); /* Compute the pressure */ const float pressure = gas_pressure_from_internal_energy(p->rho, xp->u_full); diff --git a/src/hydro/Minimal/hydro_io.h b/src/hydro/Minimal/hydro_io.h index 01a75b17f..8c83349a3 100644 --- a/src/hydro/Minimal/hydro_io.h +++ b/src/hydro/Minimal/hydro_io.h @@ -71,12 +71,12 @@ void hydro_read_particles(struct part* parts, struct io_props* list, float convert_S(struct engine* e, struct part* p) { - return hydro_get_entropy(p, 0); + return hydro_get_entropy(p); } float convert_P(struct engine* e, struct part* p) { - return hydro_get_pressure(p, 0); + return hydro_get_pressure(p); } /** -- GitLab From be7b197a945bd16fb88a0edf3d1212dd9017cc34 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Fri, 13 Jan 2017 23:44:13 +0000 Subject: [PATCH 39/48] Finish the force calculation before triggereing the cooling. --- examples/CoolingBox/coolingBox.yml | 4 +- examples/CoolingBox/energy_plot.py | 20 ++++++--- src/cooling/const_lambda/cooling.h | 2 +- src/engine.c | 30 +++++++------ src/runner.c | 68 ++++++++++++++++++++++++++---- src/timers.h | 1 + 6 files changed, 95 insertions(+), 30 deletions(-) diff --git a/examples/CoolingBox/coolingBox.yml b/examples/CoolingBox/coolingBox.yml index a8178d967..7b8dbf4bd 100644 --- a/examples/CoolingBox/coolingBox.yml +++ b/examples/CoolingBox/coolingBox.yml @@ -9,7 +9,7 @@ InternalUnitSystem: # Parameters governing the time integration TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). - time_end: 0.4 # The end time of the simulation (in internal units). + time_end: 0.25 # The end time of the simulation (in internal units). dt_min: 1e-5 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-2 # The maximal time-step size of the simulation (in internal units). @@ -17,7 +17,7 @@ TimeIntegration: Snapshots: basename: coolingBox # Common part of the name of output files time_first: 0. # Time of the first output (in internal units) - delta_time: 1.0e-1 # Time difference between consecutive outputs (in internal units) + delta_time: 1e-2 # Time difference between consecutive outputs (in internal units) # Parameters governing the conserved quantities statistics Statistics: diff --git a/examples/CoolingBox/energy_plot.py b/examples/CoolingBox/energy_plot.py index 719431d73..c8948e7e2 100644 --- a/examples/CoolingBox/energy_plot.py +++ b/examples/CoolingBox/energy_plot.py @@ -83,7 +83,7 @@ rho_cgs = rho * unit_mass / (unit_length)**3 time_cgs = time * unit_time total_energy_cgs = total_energy / total_mass[0] * unit_length**2 / (unit_time)**2 kinetic_energy_cgs = kinetic_energy / total_mass[0] * unit_length**2 / (unit_time)**2 -internal_energy_cgs = kinetic_energy / total_mass[0] * unit_length**2 / (unit_time)**2 +internal_energy_cgs = internal_energy / total_mass[0] * unit_length**2 / (unit_time)**2 radiated_energy_cgs = radiated_energy / total_mass[0] * unit_length**2 / (unit_time)**2 # Find the energy floor @@ -100,19 +100,27 @@ u_analytic_cgs[u_analytic_cgs < u_floor_cgs] = u_floor_cgs print "Cooling time:", cooling_time_cgs, "[s]" +# Read snapshots +u_snapshots_cgs = zeros(25) +t_snapshots_cgs = zeros(25) +for i in range(25): + snap = h5.File("coolingBox_%0.3d.hdf5"%i,'r') + u_snapshots_cgs[i] = sum(snap["/PartType0/InternalEnergy"][:] * snap["/PartType0/Masses"][:]) / total_mass[0] * unit_length**2 / (unit_time)**2 + t_snapshots_cgs[i] = snap["/Header"].attrs["Time"] * unit_time + + figure() -#plot(time_cgs, internal_energy_cgs, 'b-', lw=1.5, label="Gas internal energy") -#plot(time_cgs, kinetic_energy_cgs, 'y-', lw=1.5, label="Gas kinetic energy") plot(time_cgs, total_energy_cgs, 'r-', lw=1.6, label="Gas total energy") +plot(t_snapshots_cgs, u_snapshots_cgs, 'rD', ms=3) plot(time_cgs, radiated_energy_cgs, 'g-', lw=1.6, label="Radiated energy") plot(time_cgs, total_energy_cgs + radiated_energy_cgs, 'b-', lw=0.6, label="Gas total + radiated") plot(analytic_time_cgs, u_analytic_cgs, '--', color='k', alpha=0.8, lw=1.0, label="Analytic solution") -legend(loc="upper right", fontsize=8) +legend(loc="upper right", fontsize=8, frameon=False, handlelength=3, ncol=1) xlabel("${\\rm{Time~[s]}}$", labelpad=0) -ylabel("${\\rm{Gas~internal~energy~[erg]}}$") -xlim(0, 1.8*cooling_time_cgs) +ylabel("${\\rm{Energy~[erg]}}$") +xlim(0, 1.5*cooling_time_cgs) ylim(0, 1.5*u_analytic_cgs[0]) savefig("energy.png", dpi=200) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index e2451993a..757c5e660 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -89,7 +89,7 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( float cooling_du_dt = cooling_rate(phys_const, us, cooling, p); /* Integrate cooling equation to enforce energy floor */ - if (u_old + hydro_du_dt < u_floor) { + if (u_old + hydro_du_dt * dt < u_floor) { cooling_du_dt = 0.f; } else if (u_old + (hydro_du_dt + cooling_du_dt) * dt < u_floor) { cooling_du_dt = (u_old + dt * hydro_du_dt - u_floor) / dt; diff --git a/src/engine.c b/src/engine.c index c49f2c81b..2bfe7ab1f 100644 --- a/src/engine.c +++ b/src/engine.c @@ -176,13 +176,18 @@ void engine_make_hierarchical_tasks(struct engine *e, struct cell *c) { #endif /* Cooling task */ - if (is_with_cooling) + if (is_with_cooling) { c->cooling = scheduler_addtask(s, task_type_cooling, task_subtype_none, 0, 0, c, NULL, 0); + + scheduler_addunlock(s, c->cooling, c->kick2); + } + /* add source terms */ - if (is_with_sourceterms) + if (is_with_sourceterms) { c->sourceterms = scheduler_addtask(s, task_type_sourceterms, task_subtype_none, 0, 0, c, NULL, 0); + } } } else { /* We are above the super-cell so need to go deeper */ @@ -1634,11 +1639,18 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, struct task *density, struct task *force, struct cell *c) { - /* init --> density loop --> ghost --> force loop --> kick2 */ + /* init --> density loop --> ghost --> force loop */ scheduler_addunlock(sched, c->super->init, density); scheduler_addunlock(sched, density, c->super->ghost); scheduler_addunlock(sched, c->super->ghost, force); - scheduler_addunlock(sched, force, c->super->kick2); + + if (c->super->cooling != NULL) { + /* force loop --> cooling (--> kick2) */ + scheduler_addunlock(sched, force, c->super->cooling); + } else { + /* force loop --> kick2 */ + scheduler_addunlock(sched, force, c->super->kick2); + } } #endif @@ -1832,12 +1844,6 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { } #endif } - - /* Cooling tasks take place after the second kick */ - else if (t->type == task_type_cooling) { - scheduler_addunlock(sched, t->ci->kick2, t); - scheduler_addunlock(sched, t, t->ci->timestep); - } } } @@ -2543,9 +2549,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->type == task_type_cooling || t->type == task_type_sourceterms) - t->skip = 1; + if (t->type == task_type_drift || t->type == task_type_kick1) t->skip = 1; } } diff --git a/src/runner.c b/src/runner.c index 3dd27346f..d52ca1555 100644 --- a/src/runner.c +++ b/src/runner.c @@ -924,7 +924,6 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { struct part *restrict parts = c->parts; struct xpart *restrict xparts = c->xparts; struct gpart *restrict gparts = c->gparts; - const double const_G = e->physical_constants->const_newton_G; TIMER_TIC; @@ -947,10 +946,6 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* If particle needs to be kicked */ if (part_is_active(p, e)) { - /* First, finish the force loop */ - hydro_end_force(p); - if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); - 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); @@ -977,9 +972,6 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* If the g-particle has no counterpart and needs to be kicked */ if (gp->id_or_neg_offset > 0 && gpart_is_active(gp, e)) { - /* First, finish the force loop */ - gravity_end_force(gp, const_G); - 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); @@ -1140,6 +1132,63 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_timestep); } +/** + * @brief End the force calculation of all active particles in a cell + * by multiplying the acccelerations by the relevant constants + * + * @param r The #runner thread. + * @param c The #cell. + * @param timer Are we timing this ? + */ +void runner_do_end_force(struct runner *r, struct cell *c, int timer) { + + const struct engine *e = r->e; + const int count = c->count; + const int gcount = c->gcount; + struct part *restrict parts = c->parts; + struct gpart *restrict gparts = c->gparts; + const double const_G = e->physical_constants->const_newton_G; + + TIMER_TIC; + + /* Anything to do here? */ + if (!cell_is_active(c, e)) return; + + /* Recurse? */ + if (c->split) { + for (int k = 0; k < 8; k++) + if (c->progeny[k] != NULL) runner_do_kick2(r, c->progeny[k], 0); + } else { + + /* Loop over the particles in this cell. */ + for (int k = 0; k < count; k++) { + + /* Get a handle on the part. */ + struct part *restrict p = &parts[k]; + + if (part_is_active(p, e)) { + + /* First, finish the force loop */ + hydro_end_force(p); + if (p->gpart != NULL) gravity_end_force(p->gpart, const_G); + } + } + + /* Loop over the g-particles in this cell. */ + for (int k = 0; k < gcount; k++) { + + /* Get a handle on the gpart. */ + struct gpart *restrict gp = &gparts[k]; + + if (gp->id_or_neg_offset > 0 && gpart_is_active(gp, e)) { + gravity_end_force(gp, const_G); + } + } + } + + if (timer) TIMER_TOC(timer_endforce); +} + /** * @brief Construct the cell properties from the received particles * @@ -1379,6 +1428,8 @@ void *runner_main(void *data) { runner_do_kick1(r, ci, 1); break; case task_type_kick2: + if (!(e->policy & engine_policy_cooling)) + runner_do_end_force(r, ci, 1); runner_do_kick2(r, ci, 1); break; case task_type_timestep: @@ -1411,6 +1462,7 @@ void *runner_main(void *data) { runner_do_grav_fft(r); break; case task_type_cooling: + if (e->policy & engine_policy_cooling) runner_do_end_force(r, ci, 1); runner_do_cooling(r, t->ci, 1); break; case task_type_sourceterms: diff --git a/src/timers.h b/src/timers.h index fa0d10d55..6106b93fd 100644 --- a/src/timers.h +++ b/src/timers.h @@ -36,6 +36,7 @@ enum { timer_kick1, timer_kick2, timer_timestep, + timer_endforce, timer_dosort, timer_doself_density, timer_doself_gradient, -- GitLab From fa9b8f221c40642c6c403c58c2a1642952848be6 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 14 Jan 2017 00:08:06 +0000 Subject: [PATCH 40/48] Cooling also fine with Pressure-Entropy --- src/hydro/Gadget2/hydro.h | 1 - src/hydro/PressureEntropy/hydro.h | 90 ++++++------------------- src/hydro/PressureEntropy/hydro_debug.h | 2 +- src/hydro/PressureEntropy/hydro_io.h | 4 +- src/timeline.h | 2 +- 5 files changed, 24 insertions(+), 75 deletions(-) diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index a2544aff8..0bfbf7ffe 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -76,7 +76,6 @@ __attribute__((always_inline)) INLINE static float hydro_get_entropy( * @brief Returns the sound speed of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( const struct part *restrict p) { diff --git a/src/hydro/PressureEntropy/hydro.h b/src/hydro/PressureEntropy/hydro.h index 8ef993e57..5ac0c73b7 100644 --- a/src/hydro/PressureEntropy/hydro.h +++ b/src/hydro/PressureEntropy/hydro.h @@ -43,50 +43,42 @@ * @brief Returns the internal energy of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( - const struct part *restrict p, float dt) { - - const float entropy = p->entropy + p->entropy_dt * dt; + const struct part *restrict p) { - return gas_internal_energy_from_entropy(p->rho_bar, entropy); + return gas_internal_energy_from_entropy(p->rho_bar, p->entropy); } /** * @brief Returns the pressure of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_pressure( - const struct part *restrict p, float dt) { - - const float entropy = p->entropy + p->entropy_dt * dt; + const struct part *restrict p) { - return gas_pressure_from_entropy(p->rho_bar, entropy); + return gas_pressure_from_entropy(p->rho_bar, p->entropy); } /** * @brief Returns the entropy of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_entropy( - const struct part *restrict p, float dt) { + const struct part *restrict p) { - return p->entropy + p->entropy_dt * dt; + return p->entropy; } /** * @brief Returns the sound speed of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( - const struct part *restrict p, float dt) { + const struct part *restrict p) { return p->force.soundspeed; } @@ -114,72 +106,30 @@ __attribute__((always_inline)) INLINE static float hydro_get_mass( } /** - * @brief Modifies the thermal state of a particle to the imposed internal - * energy + * @brief Returns the time derivative of internal energy of a particle * - * This overwrites the current state of the particle but does *not* change its - * time-derivatives. Entropy, pressure, sound-speed and signal velocity will be - * updated. + * We assume a constant density. * - * @param p The particle - * @param u The new internal energy + * @param p The particle of interest */ -__attribute__((always_inline)) INLINE static void hydro_set_internal_energy( - struct part *restrict p, float u) { - - p->entropy = gas_entropy_from_internal_energy(p->rho_bar, u); - p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); - - /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho_bar, p->entropy); - - /* Compute the sound speed from the pressure*/ - const float soundspeed = gas_soundspeed_from_pressure(p->rho_bar, pressure); - - /* Update the signal velocity */ - const float v_sig_old = p->force.v_sig; - const float v_sig_new = p->force.v_sig - p->force.soundspeed + soundspeed; - const float v_sig = max(v_sig_old, v_sig_new); - - const float rho_bar_inv = 1.f / p->rho_bar; +__attribute__((always_inline)) INLINE static float hydro_get_internal_energy_dt( + const struct part *restrict p) { - p->force.soundspeed = soundspeed; - p->force.P_over_rho2 = pressure * rho_bar_inv * rho_bar_inv; - p->force.v_sig = v_sig; + return gas_internal_energy_from_entropy(p->rho_bar, p->entropy_dt); } /** - * @brief Modifies the thermal state of a particle to the imposed entropy + * @brief Returns the time derivative of internal energy of a particle * - * This overwrites the current state of the particle but does *not* change its - * time-derivatives. Entropy, pressure, sound-speed and signal velocity will be - * updated. + * We assume a constant density. * - * @param p The particle - * @param S The new entropy + * @param p The particle of interest. + * @param du_dt The new time derivative of the internal energy. */ -__attribute__((always_inline)) INLINE static void hydro_set_entropy( - struct part *restrict p, float S) { +__attribute__((always_inline)) INLINE static void hydro_set_internal_energy_dt( + struct part *restrict p, float du_dt) { - p->entropy = S; - p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); - - /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho_bar, p->entropy); - - /* Compute the sound speed from the pressure*/ - const float soundspeed = gas_soundspeed_from_pressure(p->rho_bar, pressure); - - /* Update the signal velocity */ - const float v_sig_old = p->force.v_sig; - const float v_sig_new = p->force.v_sig - p->force.soundspeed + soundspeed; - const float v_sig = max(v_sig_old, v_sig_new); - - const float rho_bar_inv = 1.f / p->rho_bar; - - p->force.soundspeed = soundspeed; - p->force.P_over_rho2 = pressure * rho_bar_inv * rho_bar_inv; - p->force.v_sig = v_sig; + p->entropy_dt = gas_entropy_from_internal_energy(p->rho_bar, du_dt); } /** diff --git a/src/hydro/PressureEntropy/hydro_debug.h b/src/hydro/PressureEntropy/hydro_debug.h index 1192d9653..3a0a315a4 100644 --- a/src/hydro/PressureEntropy/hydro_debug.h +++ b/src/hydro/PressureEntropy/hydro_debug.h @@ -40,7 +40,7 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], xp->v_full[0], xp->v_full[1], xp->v_full[2], p->a_hydro[0], p->a_hydro[1], p->a_hydro[2], p->h, p->density.wcount, p->density.wcount_dh, p->mass, p->density.rho_dh, - p->rho, p->rho_bar, hydro_get_pressure(p, 0.), p->density.pressure_dh, + p->rho, p->rho_bar, hydro_get_pressure(p), p->density.pressure_dh, p->force.P_over_rho2, p->entropy, p->entropy_one_over_gamma, p->entropy_dt, p->force.soundspeed, p->force.v_sig, p->force.h_dt, p->time_bin); diff --git a/src/hydro/PressureEntropy/hydro_io.h b/src/hydro/PressureEntropy/hydro_io.h index 9914a6564..fcc8439f6 100644 --- a/src/hydro/PressureEntropy/hydro_io.h +++ b/src/hydro/PressureEntropy/hydro_io.h @@ -69,12 +69,12 @@ void hydro_read_particles(struct part* parts, struct io_props* list, float convert_u(struct engine* e, struct part* p) { - return hydro_get_internal_energy(p, 0); + return hydro_get_internal_energy(p); } float convert_P(struct engine* e, struct part* p) { - return hydro_get_pressure(p, 0); + return hydro_get_pressure(p); } /** diff --git a/src/timeline.h b/src/timeline.h index ff192533b..c73b2432b 100644 --- a/src/timeline.h +++ b/src/timeline.h @@ -32,7 +32,7 @@ typedef long long integertime_t; typedef char timebin_t; /*! The number of time bins */ -#define num_time_bins 50 +#define num_time_bins 56 /*! The maximal number of timesteps in a simulation */ #define max_nr_timesteps (1LL << (num_time_bins + 1)) -- GitLab From 4736f02804b20ea96bb10bff48802578313ad3f9 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 15 Jan 2017 22:36:43 +0000 Subject: [PATCH 41/48] Bug fix --- src/runner.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/runner.c b/src/runner.c index d52ca1555..08d44b9fa 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1157,7 +1157,7 @@ void runner_do_end_force(struct runner *r, struct cell *c, int timer) { /* Recurse? */ if (c->split) { for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_do_kick2(r, c->progeny[k], 0); + if (c->progeny[k] != NULL) runner_do_end_force(r, c->progeny[k], 0); } else { /* Loop over the particles in this cell. */ -- GitLab From 39804a1b94ee8d181934de4731fb9196bf663cd6 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 15 Jan 2017 22:37:00 +0000 Subject: [PATCH 42/48] Clearer code --- src/engine.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/engine.c b/src/engine.c index 2bfe7ab1f..a79a510c8 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1634,17 +1634,19 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, * @param density The density task to link. * @param force The force task to link. * @param c The cell. + * @param with_cooling Are we running with cooling switched on ? */ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, struct task *density, struct task *force, - struct cell *c) { + struct cell *c, + int with_cooling) { /* init --> density loop --> ghost --> force loop */ scheduler_addunlock(sched, c->super->init, density); scheduler_addunlock(sched, density, c->super->ghost); scheduler_addunlock(sched, c->super->ghost, force); - if (c->super->cooling != NULL) { + if (with_cooling) { /* force loop --> cooling (--> kick2) */ scheduler_addunlock(sched, force, c->super->cooling); } else { @@ -1671,6 +1673,7 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { struct scheduler *sched = &e->sched; const int nr_tasks = sched->nr_tasks; const int nodeID = e->nodeID; + const int with_cooling = (e->policy & engine_policy_cooling); for (int ind = 0; ind < nr_tasks; ind++) { struct task *t = &sched->tasks[ind]; @@ -1702,7 +1705,7 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { engine_addlink(e, &t->ci->force, t2); /* Now, build all the dependencies for the hydro */ - engine_make_hydro_loops_dependencies(sched, t, t2, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling); #endif } @@ -1744,10 +1747,10 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling); } if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - engine_make_hydro_loops_dependencies(sched, t, t2, t->cj); + engine_make_hydro_loops_dependencies(sched, t, t2, t->cj, with_cooling); } #endif @@ -1790,7 +1793,7 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling); } #endif } @@ -1837,10 +1840,10 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t->ci, with_cooling); } if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - engine_make_hydro_loops_dependencies(sched, t, t2, t->cj); + engine_make_hydro_loops_dependencies(sched, t, t2, t->cj, with_cooling); } #endif } -- GitLab From 20f932f3bcc36e4c8bd63064e05248052f95770f Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sun, 15 Jan 2017 23:39:44 +0000 Subject: [PATCH 43/48] Fixed all the tests but three. --- src/runner.h | 5 ++++- tests/test125cells.c | 34 ++++++++++++++++++++++++++-------- tests/test27cells.c | 11 +++++------ tests/testLogger.c | 1 + tests/testPair.c | 3 +-- tests/testSPHStep.c | 3 +-- tests/testTimeIntegration.c | 2 +- 7 files changed, 39 insertions(+), 20 deletions(-) diff --git a/src/runner.h b/src/runner.h index 2ee4b3e4c..53e78b006 100644 --- a/src/runner.h +++ b/src/runner.h @@ -56,7 +56,10 @@ struct runner { void runner_do_ghost(struct runner *r, struct cell *c, int timer); void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer); void runner_do_sort(struct runner *r, struct cell *c, int flag, int clock); -void runner_do_kick(struct runner *r, struct cell *c, int timer); +void runner_do_drift(struct runner *r, struct cell *c, int timer); +void runner_do_kick1(struct runner *r, struct cell *c, int timer); +void runner_do_kick2(struct runner *r, struct cell *c, int timer); +void runner_do_end_force(struct runner *r, struct cell *c, int timer); void runner_do_init(struct runner *r, struct cell *c, int timer); void runner_do_cooling(struct runner *r, struct cell *c, int timer); void runner_do_grav_external(struct runner *r, struct cell *c, int timer); diff --git a/tests/test125cells.c b/tests/test125cells.c index 3ae80d952..1c0e3e97b 100644 --- a/tests/test125cells.c +++ b/tests/test125cells.c @@ -272,8 +272,7 @@ struct cell *make_cell(size_t n, const double offset[3], double size, double h, hydro_first_init_part(part, xpart); part->id = ++(*partId); - part->ti_begin = 0; - part->ti_end = 1; + part->time_bin = 1; #if defined(GIZMO_SPH) part->geometry.volume = part->conserved.mass / density; @@ -292,6 +291,11 @@ struct cell *make_cell(size_t n, const double offset[3], double size, double h, part->conserved.mass; #endif +#ifdef SWIFT_DEBUG_CHECKS + part->ti_drift = 1; + part->ti_kick = 1; +#endif + ++part; ++xpart; } @@ -364,10 +368,10 @@ void dump_particle_fields(char *fileName, struct cell *main_cell, #else main_cell->parts[pid].density.div_v, #endif - hydro_get_entropy(&main_cell->parts[pid], 0.f), - hydro_get_internal_energy(&main_cell->parts[pid], 0.f), - hydro_get_pressure(&main_cell->parts[pid], 0.f), - hydro_get_soundspeed(&main_cell->parts[pid], 0.f), + hydro_get_entropy(&main_cell->parts[pid]), + hydro_get_internal_energy(&main_cell->parts[pid]), + hydro_get_pressure(&main_cell->parts[pid]), + hydro_get_soundspeed(&main_cell->parts[pid]), main_cell->parts[pid].a_hydro[0], main_cell->parts[pid].a_hydro[1], main_cell->parts[pid].a_hydro[2], main_cell->parts[pid].force.h_dt, #if defined(GADGET2_SPH) @@ -572,6 +576,12 @@ int main(int argc, char *argv[]) { const ticks tic = getticks(); + /* Start with a gentle kick */ + //runner_do_kick1(&runner, main_cell, 0); + + /* And a gentle drift */ + //runner_do_drift(&runner, main_cell, 0); + /* First, sort stuff */ for (int j = 0; j < 125; ++j) runner_do_sort(&runner, cells[j], 0x1FFF, 0); @@ -640,7 +650,8 @@ int main(int argc, char *argv[]) { #endif /* Finally, give a gentle kick */ - runner_do_kick(&runner, main_cell, 0); + runner_do_end_force(&runner, main_cell, 0); + //runner_do_kick2(&runner, main_cell, 0); const ticks toc = getticks(); time += toc - tic; @@ -663,6 +674,12 @@ int main(int argc, char *argv[]) { const ticks tic = getticks(); + /* Kick the central cell */ + //runner_do_kick1(&runner, main_cell, 0); + + /* And drift it */ + runner_do_drift(&runner, main_cell, 0); + /* Initialise the particles */ for (int j = 0; j < 125; ++j) runner_do_init(&runner, cells[j], 0); @@ -728,7 +745,8 @@ int main(int argc, char *argv[]) { #endif /* Finally, give a gentle kick */ - runner_do_kick(&runner, main_cell, 0); + runner_do_end_force(&runner, main_cell, 0); + //runner_do_kick2(&runner, main_cell, 0); const ticks toc = getticks(); diff --git a/tests/test27cells.c b/tests/test27cells.c index fe628e8a5..60d9ff835 100644 --- a/tests/test27cells.c +++ b/tests/test27cells.c @@ -128,8 +128,7 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, part->entropy_one_over_gamma = 1.f; #endif - part->ti_begin = 0; - part->ti_end = 1; + part->time_bin = 0; ++part; } } @@ -147,9 +146,9 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, cell->loc[1] = offset[1]; cell->loc[2] = offset[2]; - cell->ti_old = 1; - cell->ti_end_min = 1; - cell->ti_end_max = 1; + cell->ti_old = 0; + cell->ti_end_min = 0; + cell->ti_end_max = 0; shuffle_particles(cell->parts, cell->count); @@ -390,7 +389,7 @@ int main(int argc, char *argv[]) { struct engine engine; engine.s = &space; engine.time = 0.1f; - engine.ti_current = 1; + engine.ti_current = 0; struct runner runner; runner.e = &engine; diff --git a/tests/testLogger.c b/tests/testLogger.c index 943e1d8b4..ec3b33b6a 100644 --- a/tests/testLogger.c +++ b/tests/testLogger.c @@ -22,6 +22,7 @@ /* Some standard headers. */ #include +#include #include #include diff --git a/tests/testPair.c b/tests/testPair.c index ba1da815d..09d820c54 100644 --- a/tests/testPair.c +++ b/tests/testPair.c @@ -68,8 +68,7 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, #else part->mass = density * volume / count; #endif - part->ti_begin = 0; - part->ti_end = 1; + part->time_bin = 1; ++part; } } diff --git a/tests/testSPHStep.c b/tests/testSPHStep.c index ff2ec841b..0c7ae1d0d 100644 --- a/tests/testSPHStep.c +++ b/tests/testSPHStep.c @@ -61,8 +61,7 @@ struct cell *make_cell(size_t N, float cellSize, int offset[3], int id_offset) { offset[2] * cellSize + z * cellSize / N + cellSize / (2 * N); part->h = h; part->id = x * N * N + y * N + z + id_offset; - part->ti_begin = 0; - part->ti_end = 1; + part->time_bin = 1; ++part; } } diff --git a/tests/testTimeIntegration.c b/tests/testTimeIntegration.c index f39adaee9..42a3d224f 100644 --- a/tests/testTimeIntegration.c +++ b/tests/testTimeIntegration.c @@ -115,7 +115,7 @@ int main() { c.parts[0].a_hydro[1] = -(G * M_sun * c.parts[0].x[1] / r * r * r); /* Kick... */ - runner_do_kick(&run, &c, 0); + runner_do_kick2(&run, &c, 0); } /* Clean-up */ -- GitLab From 1bf1c0072086499e1ed33eebc901850a91918dfd Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 Jan 2017 12:02:48 +0000 Subject: [PATCH 44/48] Fixed the remaining tests --- src/Makefile.am | 4 ++-- src/swift.h | 2 ++ tests/test125cells.c | 22 +++++++++++----------- tests/test27cells.c | 16 +++++++++++----- tests/testPair.c | 14 ++++++++++---- 5 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 34bcaa99a..5982be729 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -45,7 +45,7 @@ include_HEADERS = space.h runner.h queue.h task.h lock.h cell.h part.h const.h \ physical_constants.h physical_constants_cgs.h potential.h version.h \ hydro_properties.h riemann.h threadpool.h cooling.h cooling_struct.h sourceterms.h \ sourceterms_struct.h statistics.h memswap.h cache.h runner_doiact_vec.h profiler.h \ - dump.h logger.h + dump.h logger.h active.h timeline.h # Common source files AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \ @@ -60,7 +60,7 @@ AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c \ nobase_noinst_HEADERS = align.h approx_math.h atomic.h cycle.h error.h inline.h kernel_hydro.h kernel_gravity.h \ kernel_long_gravity.h vector.h cache.h runner_doiact.h runner_doiact_vec.h runner_doiact_grav.h runner_doiact_fft.h \ units.h intrinsics.h minmax.h kick.h timestep.h drift.h adiabatic_index.h io_properties.h \ - dimension.h equation_of_state.h active.h timeline.h \ + dimension.h equation_of_state.h \ gravity.h gravity_io.h \ gravity/Default/gravity.h gravity/Default/gravity_iact.h gravity/Default/gravity_io.h \ gravity/Default/gravity_debug.h gravity/Default/gravity_part.h \ diff --git a/src/swift.h b/src/swift.h index 6c2bcf181..c08a4f320 100644 --- a/src/swift.h +++ b/src/swift.h @@ -23,6 +23,7 @@ #include "../config.h" /* Local headers. */ +#include "active.h" #include "atomic.h" #include "cache.h" #include "cell.h" @@ -54,6 +55,7 @@ #include "sourceterms.h" #include "space.h" #include "task.h" +#include "timeline.h" #include "timers.h" #include "tools.h" #include "units.h" diff --git a/tests/test125cells.c b/tests/test125cells.c index 1c0e3e97b..91b1cf6dc 100644 --- a/tests/test125cells.c +++ b/tests/test125cells.c @@ -292,8 +292,8 @@ struct cell *make_cell(size_t n, const double offset[3], double size, double h, #endif #ifdef SWIFT_DEBUG_CHECKS - part->ti_drift = 1; - part->ti_kick = 1; + part->ti_drift = 8; + part->ti_kick = 8; #endif ++part; @@ -315,9 +315,9 @@ struct cell *make_cell(size_t n, const double offset[3], double size, double h, cell->loc[1] = offset[1]; cell->loc[2] = offset[2]; - cell->ti_old = 1; - cell->ti_end_min = 1; - cell->ti_end_max = 1; + cell->ti_old = 8; + cell->ti_end_min = 8; + cell->ti_end_max = 8; // shuffle_particles(cell->parts, cell->count); @@ -531,7 +531,7 @@ int main(int argc, char *argv[]) { engine.physical_constants = &prog_const; engine.s = &space; engine.time = 0.1f; - engine.ti_current = 1; + engine.ti_current = 8; struct runner runner; runner.e = &engine; @@ -577,10 +577,10 @@ int main(int argc, char *argv[]) { const ticks tic = getticks(); /* Start with a gentle kick */ - //runner_do_kick1(&runner, main_cell, 0); + // runner_do_kick1(&runner, main_cell, 0); /* And a gentle drift */ - //runner_do_drift(&runner, main_cell, 0); + // runner_do_drift(&runner, main_cell, 0); /* First, sort stuff */ for (int j = 0; j < 125; ++j) runner_do_sort(&runner, cells[j], 0x1FFF, 0); @@ -651,7 +651,7 @@ int main(int argc, char *argv[]) { /* Finally, give a gentle kick */ runner_do_end_force(&runner, main_cell, 0); - //runner_do_kick2(&runner, main_cell, 0); + // runner_do_kick2(&runner, main_cell, 0); const ticks toc = getticks(); time += toc - tic; @@ -675,7 +675,7 @@ int main(int argc, char *argv[]) { const ticks tic = getticks(); /* Kick the central cell */ - //runner_do_kick1(&runner, main_cell, 0); + // runner_do_kick1(&runner, main_cell, 0); /* And drift it */ runner_do_drift(&runner, main_cell, 0); @@ -746,7 +746,7 @@ int main(int argc, char *argv[]) { /* Finally, give a gentle kick */ runner_do_end_force(&runner, main_cell, 0); - //runner_do_kick2(&runner, main_cell, 0); + // runner_do_kick2(&runner, main_cell, 0); const ticks toc = getticks(); diff --git a/tests/test27cells.c b/tests/test27cells.c index 60d9ff835..929a148d1 100644 --- a/tests/test27cells.c +++ b/tests/test27cells.c @@ -128,7 +128,13 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, part->entropy_one_over_gamma = 1.f; #endif - part->time_bin = 0; + part->time_bin = 1; + +#ifdef SWIFT_DEBUG_CHECKS + part->ti_drift = 8; + part->ti_kick = 8; +#endif + ++part; } } @@ -146,9 +152,9 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, cell->loc[1] = offset[1]; cell->loc[2] = offset[2]; - cell->ti_old = 0; - cell->ti_end_min = 0; - cell->ti_end_max = 0; + cell->ti_old = 8; + cell->ti_end_min = 8; + cell->ti_end_max = 8; shuffle_particles(cell->parts, cell->count); @@ -389,7 +395,7 @@ int main(int argc, char *argv[]) { struct engine engine; engine.s = &space; engine.time = 0.1f; - engine.ti_current = 0; + engine.ti_current = 8; struct runner runner; runner.e = &engine; diff --git a/tests/testPair.c b/tests/testPair.c index 09d820c54..8b23cc419 100644 --- a/tests/testPair.c +++ b/tests/testPair.c @@ -69,6 +69,12 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, part->mass = density * volume / count; #endif part->time_bin = 1; + +#ifdef SWIFT_DEBUG_CHECKS + part->ti_drift = 8; + part->ti_kick = 8; +#endif + ++part; } } @@ -86,9 +92,9 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, cell->loc[1] = offset[1]; cell->loc[2] = offset[2]; - cell->ti_old = 1; - cell->ti_end_min = 1; - cell->ti_end_max = 1; + cell->ti_old = 8; + cell->ti_end_min = 8; + cell->ti_end_max = 8; shuffle_particles(cell->parts, cell->count); @@ -245,7 +251,7 @@ int main(int argc, char *argv[]) { engine.s = &space; engine.time = 0.1f; - engine.ti_current = 1; + engine.ti_current = 8; runner.e = &engine; volume = particles * particles * particles; -- GitLab From 3860cd8488d018073a44fed0c42f17d7c10776ae Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 Jan 2017 12:35:06 +0000 Subject: [PATCH 45/48] Missing file --- src/partition.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/partition.c b/src/partition.c index 85745d880..4b899fe57 100644 --- a/src/partition.c +++ b/src/partition.c @@ -522,8 +522,9 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID, /* Skip un-interesting tasks. */ if (t->type != task_type_self && t->type != task_type_pair && t->type != task_type_sub_self && t->type != task_type_sub_self && - t->type != task_type_ghost && t->type != task_type_kick && - t->type != task_type_init) + t->type != task_type_ghost && t->type != task_type_kick1 && + t->type != task_type_kick2 && t->type != task_type_timestep && + t->type != task_type_drift && t->type != task_type_init) continue; /* Get the task weight. */ @@ -554,7 +555,9 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID, int cid = ci - cells; /* Different weights for different tasks. */ - if (t->type == task_type_ghost || t->type == task_type_kick) { + if (t->type == task_type_ghost || t->type == task_type_kick1 || + t->type == task_type_kick2 || t->type == task_type_timestep || + t->type == task_type_drift) { /* Particle updates add only to vertex weight. */ if (taskvweights) weights_v[cid] += w; -- GitLab From 329de16d9d6e1ede5332a16756a8e0ca0d18e2a5 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 Jan 2017 12:49:48 +0000 Subject: [PATCH 46/48] Small fixes to pass all tests from the suite on cosma. --- src/cooling/const_du/cooling.h | 28 ++++++++++++++++------------ src/engine.c | 26 +++++++++++++++++--------- src/hydro/Gizmo/hydro.h | 12 ++++-------- 3 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/cooling/const_du/cooling.h b/src/cooling/const_du/cooling.h index 07961f830..30ae644bd 100644 --- a/src/cooling/const_du/cooling.h +++ b/src/cooling/const_du/cooling.h @@ -62,26 +62,30 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( const struct cooling_function_data* restrict cooling, struct part* restrict p, struct xpart* restrict xp, float dt) { - /* Get current internal energy (dt=0) */ + /* Internal energy floor */ + const float u_floor = cooling->min_energy; + + /* Get current internal energy */ const float u_old = hydro_get_internal_energy(p); + /* Current du_dt */ + const float hydro_du_dt = hydro_get_internal_energy_dt(p); + /* Get cooling function properties */ - const float du_dt = -cooling->cooling_rate; - const float u_floor = cooling->min_energy; + float cooling_du_dt = -cooling->cooling_rate; - /* Constant cooling with a minimal floor */ - float u_new; - if (u_old - du_dt * dt > u_floor) { - u_new = u_old + du_dt * dt; - } else { - u_new = u_floor; + /* Integrate cooling equation to enforce energy floor */ + if (u_old + hydro_du_dt * dt < u_floor) { + cooling_du_dt = 0.f; + } else if (u_old + (hydro_du_dt + cooling_du_dt) * dt < u_floor) { + cooling_du_dt = (u_old + dt * hydro_du_dt - u_floor) / dt; } - /* Update the internal energy */ - hydro_set_internal_energy(p, u_new); + /* Update the internal energy time derivative */ + hydro_set_internal_energy_dt(p, hydro_du_dt + cooling_du_dt); /* Store the radiated energy */ - xp->cooling_data.radiated_energy += hydro_get_mass(p) * (u_old - u_new); + xp->cooling_data.radiated_energy += -hydro_get_mass(p) * cooling_du_dt * dt; } /** diff --git a/src/engine.c b/src/engine.c index a79a510c8..b68accde5 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1614,15 +1614,23 @@ static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, struct task *density, struct task *gradient, struct task *force, - struct cell *c) { + struct cell *c, + int with_cooling) { /* init --> density loop --> ghost --> gradient loop --> extra_ghost */ - /* extra_ghost --> force loop --> kick2 */ + /* extra_ghost --> force loop */ scheduler_addunlock(sched, c->super->init, density); scheduler_addunlock(sched, density, c->super->ghost); scheduler_addunlock(sched, c->super->ghost, gradient); scheduler_addunlock(sched, gradient, c->super->extra_ghost); scheduler_addunlock(sched, c->super->extra_ghost, force); - scheduler_addunlock(sched, force, c->super->kick2); + + if (with_cooling) { + /* force loop --> cooling (--> kick2) */ + scheduler_addunlock(sched, force, c->super->cooling); + } else { + /* force loop --> kick2 */ + scheduler_addunlock(sched, force, c->super->kick2); + } } #else @@ -1693,7 +1701,7 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { engine_addlink(e, &t->ci->force, t3); /* Now, build all the dependencies for the hydro */ - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); #else @@ -1728,10 +1736,10 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); } if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj, with_cooling); } #else @@ -1778,7 +1786,7 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); } #else @@ -1821,10 +1829,10 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); } if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj, with_cooling); } #else diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h index bde24ed71..c59af0546 100644 --- a/src/hydro/Gizmo/hydro.h +++ b/src/hydro/Gizmo/hydro.h @@ -450,10 +450,9 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * @brief Returns the internal energy of a particle * * @param p The particle of interest. - * @param dt Time since the last kick. */ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( - const struct part* restrict p, float dt) { + const struct part* restrict p) { return p->primitives.P / hydro_gamma_minus_one / p->primitives.rho; } @@ -462,10 +461,9 @@ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( * @brief Returns the entropy of a particle * * @param p The particle of interest. - * @param dt Time since the last kick. */ __attribute__((always_inline)) INLINE static float hydro_get_entropy( - const struct part* restrict p, float dt) { + const struct part* restrict p) { return p->primitives.P / pow_gamma(p->primitives.rho); } @@ -474,10 +472,9 @@ __attribute__((always_inline)) INLINE static float hydro_get_entropy( * @brief Returns the sound speed of a particle * * @param p The particle of interest. - * @param dt Time since the last kick. */ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( - const struct part* restrict p, float dt) { + const struct part* restrict p) { return sqrtf(hydro_gamma * p->primitives.P / p->primitives.rho); } @@ -486,10 +483,9 @@ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( * @brief Returns the pressure of a particle * * @param p The particle of interest - * @param dt Time since the last kick */ __attribute__((always_inline)) INLINE static float hydro_get_pressure( - const struct part* restrict p, float dt) { + const struct part* restrict p) { return p->primitives.P; } -- GitLab From fb4709d9dfaee5d39bca107cc9379de64085ce70 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 Jan 2017 12:54:04 +0000 Subject: [PATCH 47/48] Code formatting --- src/engine.c | 27 +++++++++++++++------------ src/partition.c | 8 ++++---- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/engine.c b/src/engine.c index b68accde5..ec8a09e02 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1610,12 +1610,9 @@ void engine_link_gravity_tasks(struct engine *e) { * @param force The force task to link. * @param c The cell. */ -static inline void engine_make_hydro_loops_dependencies(struct scheduler *sched, - struct task *density, - struct task *gradient, - struct task *force, - struct cell *c, - int with_cooling) { +static inline void engine_make_hydro_loops_dependencies( + struct scheduler *sched, struct task *density, struct task *gradient, + struct task *force, struct cell *c, int with_cooling) { /* init --> density loop --> ghost --> gradient loop --> extra_ghost */ /* extra_ghost --> force loop */ scheduler_addunlock(sched, c->super->init, density); @@ -1701,7 +1698,8 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { engine_addlink(e, &t->ci->force, t3); /* Now, build all the dependencies for the hydro */ - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, + with_cooling); #else @@ -1736,10 +1734,12 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, + with_cooling); } if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj, with_cooling); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj, + with_cooling); } #else @@ -1786,7 +1786,8 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, + with_cooling); } #else @@ -1829,10 +1830,12 @@ void engine_make_extra_hydroloop_tasks(struct engine *e) { /* Now, build all the dependencies for the hydro for the cells */ /* that are local and are not descendant of the same super-cells */ if (t->ci->nodeID == nodeID) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, with_cooling); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->ci, + with_cooling); } if (t->cj->nodeID == nodeID && t->ci->super != t->cj->super) { - engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj, with_cooling); + engine_make_hydro_loops_dependencies(sched, t, t2, t3, t->cj, + with_cooling); } #else diff --git a/src/partition.c b/src/partition.c index 4b899fe57..5a4d2f8d2 100644 --- a/src/partition.c +++ b/src/partition.c @@ -523,8 +523,8 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID, if (t->type != task_type_self && t->type != task_type_pair && t->type != task_type_sub_self && t->type != task_type_sub_self && t->type != task_type_ghost && t->type != task_type_kick1 && - t->type != task_type_kick2 && t->type != task_type_timestep && - t->type != task_type_drift && t->type != task_type_init) + t->type != task_type_kick2 && t->type != task_type_timestep && + t->type != task_type_drift && t->type != task_type_init) continue; /* Get the task weight. */ @@ -556,8 +556,8 @@ static void repart_edge_metis(int partweights, int bothweights, int nodeID, /* Different weights for different tasks. */ if (t->type == task_type_ghost || t->type == task_type_kick1 || - t->type == task_type_kick2 || t->type == task_type_timestep || - t->type == task_type_drift) { + t->type == task_type_kick2 || t->type == task_type_timestep || + t->type == task_type_drift) { /* Particle updates add only to vertex weight. */ if (taskvweights) weights_v[cid] += w; -- GitLab From 51f51665e4163a3a0b82d4a79daa817855e954a8 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 16 Jan 2017 16:02:05 +0000 Subject: [PATCH 48/48] Also update the vectorized version of doself to the new active/inactive style. --- src/runner_doiact_vec.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/runner_doiact_vec.c b/src/runner_doiact_vec.c index 5db0ec6f8..b91d28852 100644 --- a/src/runner_doiact_vec.c +++ b/src/runner_doiact_vec.c @@ -20,6 +20,8 @@ /* Config parameters. */ #include "../config.h" +#include "active.h" + /* This object's header. */ #include "runner_doiact_vec.h" @@ -270,7 +272,7 @@ __attribute__((always_inline)) INLINE void runner_doself1_density_vec( struct runner *r, struct cell *restrict c) { #ifdef WITH_VECTORIZATION - const int ti_current = r->e->ti_current; + const struct engine *e = r->e; int doi_mask; struct part *restrict pi; int count_align; @@ -283,8 +285,9 @@ __attribute__((always_inline)) INLINE void runner_doself1_density_vec( TIMER_TIC - if (c->ti_end_min > ti_current) return; - if (c->ti_end_max < ti_current) error("Cell in an impossible time-zone"); + if (!cell_is_active(c, e)) return; + + if (!cell_is_drifted(c, e)) cell_drift(c, e); /* Get the particle cache from the runner and re-allocate * the cache if it is not big enough for the cell. */ @@ -308,7 +311,7 @@ __attribute__((always_inline)) INLINE void runner_doself1_density_vec( pi = &parts[pid]; /* Is the ith particle active? */ - if (pi->ti_end > ti_current) continue; + if (!part_is_active(pi, e)) continue; vector pix, piy, piz; @@ -509,6 +512,7 @@ __attribute__((always_inline)) INLINE void runner_doself1_density_vec( /** * @brief Compute the cell self-interaction (non-symmetric) using vector * intrinsics with two particle pis at a time. + * * CURRENTLY BROKEN DO NOT USE. * * @param r The #runner. @@ -518,7 +522,7 @@ __attribute__((always_inline)) INLINE void runner_doself1_density_vec_2( struct runner *r, struct cell *restrict c) { #ifdef WITH_VECTORIZATION - const int ti_current = r->e->ti_current; + const struct engine *e = r->e; int doi_mask; int doi2_mask; struct part *restrict pi; @@ -530,9 +534,11 @@ __attribute__((always_inline)) INLINE void runner_doself1_density_vec_2( TIMER_TIC + if (!cell_is_active(c, e)) return; + + if (!cell_is_drifted(c, e)) cell_drift(c, e); + /* TODO: Need to find two active particles, not just one. */ - if (c->ti_end_min > ti_current) return; - if (c->ti_end_max < ti_current) error("Cell in an impossible time-zone"); struct part *restrict parts = c->parts; const int count = c->count; @@ -563,7 +569,7 @@ __attribute__((always_inline)) INLINE void runner_doself1_density_vec_2( pi2 = &parts[pid + 1]; /* Is the ith particle active? */ - if (pi->ti_end > ti_current) continue; + if (!part_is_active(pi, e)) continue; vector pix, piy, piz; vector pix2, piy2, piz2; -- GitLab