diff --git a/src/common_io.c b/src/common_io.c index b7495b1089ab0b46993f492deff6b955f7dc1ccf..37e2837fbaeee87916ddea9264439c824149479c 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -42,6 +42,7 @@ /* Local includes. */ #include "const.h" #include "error.h" +#include "hydro.h" #include "kernel_hydro.h" #include "part.h" #include "units.h" @@ -614,7 +615,7 @@ void duplicate_hydro_gparts(struct part* const parts, gparts[i + Ndm].v_full[1] = parts[i].v[1]; gparts[i + Ndm].v_full[2] = parts[i].v[2]; - gparts[i + Ndm].mass = parts[i].mass; + gparts[i + Ndm].mass = hydro_get_mass(&parts[i]); /* Link the particles */ gparts[i + Ndm].id_or_neg_offset = -i; diff --git a/src/drift.h b/src/drift.h index 880595dc59e3e5174ee5e888e595a9204ad383e2..bd1b35926740d49a67291ede4676f3387cd66748 100644 --- a/src/drift.h +++ b/src/drift.h @@ -65,8 +65,6 @@ __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) { - /* Useful quantity */ - const float h_inv = 1.0f / p->h; /* Drift... */ p->x[0] += xp->v_full[0] * dt; @@ -78,22 +76,8 @@ __attribute__((always_inline)) INLINE static void drift_part( p->v[1] += p->a_hydro[1] * dt; p->v[2] += p->a_hydro[2] * dt; - /* Predict smoothing length */ - const float w1 = p->force.h_dt * h_inv * dt; - if (fabsf(w1) < 0.2f) - p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */ - else - p->h *= expf(w1); - - /* Predict density */ - const float w2 = -hydro_dimension * w1; - if (fabsf(w2) < 0.2f) - p->rho *= approx_expf(w2); /* 4th order expansion of exp(w) */ - else - p->rho *= expf(w2); - /* Predict the values of the extra fields */ - hydro_predict_extra(p, xp, ti_old, ti_current, timeBase); + hydro_predict_extra(p, xp, dt, ti_old, ti_current, timeBase); /* Compute offset since last cell construction */ xp->x_diff[0] -= xp->v_full[0] * dt; diff --git a/src/hydro/Default/hydro.h b/src/hydro/Default/hydro.h index 021599cd2daf61ff35e5f29e3f13b2ad61c8947a..f61bff55821809fe1f5da27c95d75afbecbc04cc 100644 --- a/src/hydro/Default/hydro.h +++ b/src/hydro/Default/hydro.h @@ -73,6 +73,28 @@ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( return p->force.soundspeed; } +/** + * @brief Returns the density of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_density( + const struct part *restrict p) { + + return p->rho; +} + +/** + * @brief Returns the mass of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_mass( + const struct part *restrict p) { + + return p->mass; +} + /** * @brief Modifies the thermal state of a particle to the imposed internal * energy @@ -288,16 +310,31 @@ __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 * @param t1 The time at the end of the drift * @param timeBase The minimal time-step size */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part *restrict p, struct xpart *restrict xp, int t0, int t1, - double timeBase) { + struct part *restrict p, struct xpart *restrict xp, float dt, int t0, + int t1, double timeBase) { float u, w; - const float dt = (t1 - t0) * timeBase; + const float h_inv = 1.f / p->h; + + /* Predict smoothing length */ + const float w1 = p->force.h_dt * h_inv * dt; + if (fabsf(w1) < 0.2f) + p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */ + else + p->h *= expf(w1); + + /* Predict density */ + const float w2 = -hydro_dimension * w1; + if (fabsf(w2) < 0.2f) + p->rho *= approx_expf(w2); /* 4th order expansion of exp(w) */ + else + p->rho *= expf(w2); /* Predict internal energy */ w = p->force.u_dt / p->u * dt; diff --git a/src/hydro/Default/hydro_part.h b/src/hydro/Default/hydro_part.h index a2f4453dc69ed06ca4f315b6be29844c177d0435..f42c3dc886ae1ab8f472ffdf5ff508f6735d1bb1 100644 --- a/src/hydro/Default/hydro_part.h +++ b/src/hydro/Default/hydro_part.h @@ -28,6 +28,8 @@ struct xpart { /* Velocity at the last full step. */ float v_full[3]; + float u_full; + /* Old density. */ float omega; diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index e9d626cb8c147c0cf4fa8d27f8bab31d2471beae..09a8f50d5b2e9abd43c3b9bd43a12fad8a347258 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -20,6 +20,7 @@ #define SWIFT_GADGET2_HYDRO_H #include "adiabatic_index.h" +#include "approx_math.h" #include "dimension.h" #include "equation_of_state.h" #include "hydro_properties.h" @@ -77,6 +78,28 @@ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( return p->force.soundspeed; } +/** + * @brief Returns the density of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_density( + const struct part *restrict p) { + + return p->rho; +} + +/** + * @brief Returns the mass of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_mass( + const struct part *restrict p) { + + return p->mass; +} + /** * @brief Modifies the thermal state of a particle to the imposed internal * energy @@ -285,13 +308,30 @@ __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 * @param t1 The time at the end of the drift * @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, int t0, int t1, - double timeBase) { + struct part *restrict p, const struct xpart *restrict xp, float dt, int t0, + int t1, double timeBase) { + + const float h_inv = 1.f / p->h; + + /* Predict smoothing length */ + const float w1 = p->force.h_dt * h_inv * dt; + if (fabsf(w1) < 0.2f) + p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */ + else + p->h *= expf(w1); + + /* Predict density */ + const float w2 = -hydro_dimension * w1; + if (fabsf(w2) < 0.2f) + p->rho *= approx_expf(w2); /* 4th order expansion of exp(w) */ + else + p->rho *= expf(w2); /* Drift the pressure */ const float dt_entr = (t1 - (p->ti_begin + p->ti_end) / 2) * timeBase; diff --git a/src/hydro/Gizmo/hydro.h b/src/hydro/Gizmo/hydro.h index 056ac3c8627c3c2180fa151b495874fc7c726c52..8a474878f94cb9b8157185e15e33a71353a04e1b 100644 --- a/src/hydro/Gizmo/hydro.h +++ b/src/hydro/Gizmo/hydro.h @@ -275,6 +275,7 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( * * @param p Particle to act upon. * @param xp The extended particle data to act upon. + * @param dt The drift time-step. * @param t0 Integer start time of the drift interval. * @param t1 Integer end time of the drift interval. * @param timeBase Conversion factor between integer and physical time. @@ -282,10 +283,16 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part* p, struct xpart* xp, int t0, int t1, double timeBase) { - // return; - float dt = (t1 - t0) * timeBase; - float h_inv = 1.0f / p->h; - float w = -hydro_dimension * p->force.h_dt * h_inv * dt; + const float dt = (t1 - t0) * timeBase; + const float h_inv = 1.0f / p->h; + const float w = -hydro_dimension * p->force.h_dt * h_inv * dt; + + /* Predict smoothing length */ + const float w1 = p->force.h_dt * h_inv * dt; + if (fabsf(w1) < 0.2f) + p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */ + else + p->h *= expf(w1); if (fabsf(w) < 0.2f) { p->primitives.rho *= approx_expf(w); @@ -432,7 +439,6 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( * * @param p The particle of interest. * @param dt Time since the last kick. - * @return Internal energy of the particle. */ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( const struct part* restrict p, float dt) { @@ -445,7 +451,6 @@ __attribute__((always_inline)) INLINE static float hydro_get_internal_energy( * * @param p The particle of interest. * @param dt Time since the last kick. - * @return Entropy of the particle. */ __attribute__((always_inline)) INLINE static float hydro_get_entropy( const struct part* restrict p, float dt) { @@ -458,7 +463,6 @@ __attribute__((always_inline)) INLINE static float hydro_get_entropy( * * @param p The particle of interest. * @param dt Time since the last kick. - * @param Sound speed of the particle. */ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( const struct part* restrict p, float dt) { @@ -471,10 +475,31 @@ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( * * @param p The particle of interest * @param dt Time since the last kick - * @param Pressure of the particle. */ __attribute__((always_inline)) INLINE static float hydro_get_pressure( const struct part* restrict p, float dt) { return p->primitives.P; } + +/** + * @brief Returns the mass of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_mass( + const struct part* restrict p) { + + return p->conserved.mass; +} + +/** + * @brief Returns the density of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_density( + const struct part* restrict p) { + + return p->primitives.rho; +} diff --git a/src/hydro/Gizmo/hydro_debug.h b/src/hydro/Gizmo/hydro_debug.h index db672bab16662961a99558b563b9320d4e75ecc4..f4c071023a627b177fd06373856f25611fc9485d 100644 --- a/src/hydro/Gizmo/hydro_debug.h +++ b/src/hydro/Gizmo/hydro_debug.h @@ -52,8 +52,7 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( "div_v=%.3e, " "wcount_dh=%.3e, " "curl_v=[%.3e,%.3e,%.3e], " - "wcount=%.3e}, " - "mass=%.3e\n", + "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], @@ -79,5 +78,5 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( p->geometry.matrix_E[2][1], p->geometry.matrix_E[2][2], p->timestepvars.vmax, p->density.div_v, p->density.wcount_dh, p->density.curl_v[0], p->density.curl_v[1], p->density.curl_v[2], - p->density.wcount, p->mass); + p->density.wcount); } diff --git a/src/hydro/Gizmo/hydro_part.h b/src/hydro/Gizmo/hydro_part.h index a0313972c54a1ff4b7d11678e8a52756f501ac43..099c41a275477401eb98b392fa00483c627d85ce 100644 --- a/src/hydro/Gizmo/hydro_part.h +++ b/src/hydro/Gizmo/hydro_part.h @@ -25,6 +25,7 @@ struct xpart { /* Velocity at the last full step. */ float v_full[3]; + } __attribute__((aligned(xpart_align))); /* Data of a single particle. */ diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index a5d73aad02372aa22b840c2cb0d3100cd439e75d..0bbc77f4a2384c79f7d3329c20b92990598d5c63 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -35,6 +35,7 @@ */ #include "adiabatic_index.h" +#include "approx_math.h" #include "dimension.h" #include "equation_of_state.h" #include "hydro_properties.h" @@ -102,6 +103,28 @@ __attribute__((always_inline)) INLINE static float hydro_get_soundspeed( return gas_soundspeed_from_internal_energy(p->rho, u); } +/** + * @brief Returns the density of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_density( + const struct part *restrict p) { + + return p->rho; +} + +/** + * @brief Returns the mass of a particle + * + * @param p The particle of interest + */ +__attribute__((always_inline)) INLINE static float hydro_get_mass( + const struct part *restrict p) { + + return p->mass; +} + /** * @brief Modifies the thermal state of a particle to the imposed internal * energy @@ -286,15 +309,32 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( * Additional hydrodynamic quantites are drifted forward in time here. These * include thermal quantities (thermal energy or total energy or entropy, ...). * - * @param p The particle - * @param xp The extended data of the particle - * @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 + * @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, int t0, int t1, - double timeBase) { + struct part *restrict p, const struct xpart *restrict xp, float dt, int t0, + int t1, double timeBase) { + + const float h_inv = 1.f / p->h; + + /* Predict smoothing length */ + const float w1 = p->force.h_dt * h_inv * dt; + if (fabsf(w1) < 0.2f) + p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */ + else + p->h *= expf(w1); + + /* Predict density */ + const float w2 = -hydro_dimension * w1; + if (fabsf(w2) < 0.2f) + p->rho *= approx_expf(w2); /* 4th order expansion of exp(w) */ + else + p->rho *= expf(w2); /* Drift the pressure */ const float dt_entr = (t1 - (p->ti_begin + p->ti_end) / 2) * timeBase; diff --git a/src/runner.c b/src/runner.c index b21d27403a6a81cb598d0bded8b7220a3a60db63..f7c061c145a982e544439732bc5ad92febfc6afd 100644 --- a/src/runner.c +++ b/src/runner.c @@ -702,7 +702,8 @@ static void runner_do_drift(struct cell *c, struct engine *e) { const float v[3] = {xp->v_full[0] + p->a_hydro[0] * half_dt, xp->v_full[1] + p->a_hydro[1] * half_dt, xp->v_full[2] + p->a_hydro[2] * half_dt}; - const float m = p->mass; + + const float m = hydro_get_mass(p); /* Collect mass */ mass += m; diff --git a/src/tools.c b/src/tools.c index 148af4f612fd05d3724787c2908c0f229d3867c5..060bf1439f30dc6237938c060bc4ddc8d9be822b 100644 --- a/src/tools.c +++ b/src/tools.c @@ -442,43 +442,6 @@ void pairs_single_grav(double *dim, long long int pid, aabs[2]); } -/** - * @brief Test the density function by dumping it for two random parts. - * - * @param N number of intervals in [0,1]. - */ -void density_dump(int N) { - - int k; - float r2[4] = {0.0f, 0.0f, 0.0f, 0.0f}, hi[4], hj[4]; - struct part /**pi[4], *pj[4],*/ Pi[4], Pj[4]; - - /* Init the interaction parameters. */ - for (k = 0; k < 4; k++) { - Pi[k].mass = 1.0f; - Pi[k].rho = 0.0f; - Pi[k].density.wcount = 0.0f; - Pi[k].id = k; - Pj[k].mass = 1.0f; - Pj[k].rho = 0.0f; - Pj[k].density.wcount = 0.0f; - Pj[k].id = k + 4; - hi[k] = 1.0; - hj[k] = 1.0; - } - - for (k = 0; k <= N; k++) { - r2[3] = r2[2]; - r2[2] = r2[1]; - r2[1] = r2[0]; - r2[0] = ((float)k) / N; - Pi[0].density.wcount = 0; - Pj[0].density.wcount = 0; - runner_iact_density(r2[0], NULL, hi[0], hj[0], &Pi[0], &Pj[0]); - printf(" %e %e %e", r2[0], Pi[0].density.wcount, Pj[0].density.wcount); - } -} - /** * @brief Compute the force on a single particle brute-force. */ @@ -520,7 +483,7 @@ void engine_single_density(double *dim, long long int pid, /* Dump the result. */ hydro_end_density(&p, 0); message("part %lli (h=%e) has wcount=%e, rho=%e.", p.id, p.h, - p.density.wcount, p.rho); + p.density.wcount, hydro_get_density(&p)); fflush(stdout); }