From d44155a8bc3cb9c48dcafe22c6a3f0d9aa127e9b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller <matthieu.schaller@durham.ac.uk> Date: Mon, 13 Jun 2016 00:04:57 +0100 Subject: [PATCH] Use the long-range smoothing kernel --- src/const.h | 4 +- src/gravity/Default/gravity_iact.h | 66 +++++++++++++++++++----------- src/multipole.c | 24 ++++++----- src/multipole.h | 12 +++--- src/runner_doiact_grav.h | 17 ++++---- src/tools.c | 4 +- 6 files changed, 76 insertions(+), 51 deletions(-) diff --git a/src/const.h b/src/const.h index f7cf611336..ba71e3aeb1 100644 --- a/src/const.h +++ b/src/const.h @@ -53,7 +53,9 @@ //#define DEFAULT_SPH /* Self gravity stuff. */ -#define multipole_order 2 +#define const_gravity_multipole_order 2 +#define const_gravity_a_smooth 1.25f +#define const_gravity_r_cut 4.5f #define const_gravity_eta 0.025f /* External gravity properties */ diff --git a/src/gravity/Default/gravity_iact.h b/src/gravity/Default/gravity_iact.h index 997bff0fb1..2b3dfc8555 100644 --- a/src/gravity/Default/gravity_iact.h +++ b/src/gravity/Default/gravity_iact.h @@ -31,7 +31,8 @@ * @brief Gravity forces between particles */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( - float r2, const float *dx, struct gpart *gpi, struct gpart *gpj) { + float rlr_inv, float r2, const float *dx, struct gpart *gpi, + struct gpart *gpj) { /* Apply the gravitational acceleration. */ const float r = sqrtf(r2); @@ -39,37 +40,45 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( const float mi = gpi->mass; const float mj = gpj->mass; const float hi = gpi->epsilon; - const float hi_inv = 1.f / hi; - const float hi_inv3 = hi_inv * hi_inv * hi_inv; const float hj = gpj->epsilon; - const float hj_inv = 1.f / hj; - const float hj_inv3 = hj_inv * hj_inv * hj_inv; - const float ui = r * hi_inv; - const float uj = r * hj_inv; - float fi, fj, W; + const float u = r * rlr_inv; + float f_lr, fi, fj, W; + + /* Get long-range correction */ + kernel_long_grav_eval(u, &f_lr); if (r >= hi) { /* Get Newtonian gravity */ - fi = mj * ir * ir * ir; + fi = mj * ir * ir * ir * f_lr; } else { - /* Get softened gravity */ + const float hi_inv = 1.f / hi; + const float hi_inv3 = hi_inv * hi_inv * hi_inv; + const float ui = r * hi_inv; + kernel_grav_eval(ui, &W); - fi = mj * hi_inv3 * W; + + /* Get softened gravity */ + fi = mj * hi_inv3 * W * f_lr; } if (r >= hj) { /* Get Newtonian gravity */ - fj = mi * ir * ir * ir; + fj = mi * ir * ir * ir * f_lr; } else { - /* Get softened gravity */ + const float hj_inv = 1.f / hj; + const float hj_inv3 = hj_inv * hj_inv * hj_inv; + const float uj = r * hj_inv; + kernel_grav_eval(uj, &W); - fj = mi * hj_inv3 * W; + + /* Get softened gravity */ + fj = mi * hj_inv3 * W * f_lr; } const float fidx[3] = {fi * dx[0], fi * dx[1], fi * dx[2]}; @@ -89,28 +98,35 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp( * @brief Gravity forces between particles (non-symmetric version) */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( - float r2, const float *dx, struct gpart *gpi, const struct gpart *gpj) { + float rlr_inv, float r2, const float *dx, struct gpart *gpi, + const struct gpart *gpj) { /* Apply the gravitational acceleration. */ const float r = sqrtf(r2); const float ir = 1.f / r; const float mj = gpj->mass; const float hi = gpi->epsilon; - const float hi_inv = 1.f / hi; - const float hi_inv3 = hi_inv * hi_inv * hi_inv; - const float ui = r * hi_inv; - float f, W; + const float u = r * rlr_inv; + float f_lr, f, W; + + /* Get long-range correction */ + kernel_long_grav_eval(u, &f_lr); if (r >= hi) { /* Get Newtonian gravity */ - f = mj * ir * ir * ir; + f = mj * ir * ir * ir * f_lr; } else { - /* Get softened gravity */ + const float hi_inv = 1.f / hi; + const float hi_inv3 = hi_inv * hi_inv * hi_inv; + const float ui = r * hi_inv; + kernel_grav_eval(ui, &W); - f = mj * hi_inv3 * W; + + /* Get softened gravity */ + f = mj * hi_inv3 * W * f_lr; } const float fdx[3] = {f * dx[0], f * dx[1], f * dx[2]}; @@ -125,7 +141,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pp_nonsym( * @brief Gravity forces between particle and multipole */ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( - float r2, const float *dx, struct gpart *gp, + float rlr_inv, float r2, const float *dx, struct gpart *gp, const struct multipole *multi) { /* Apply the gravitational acceleration. */ @@ -133,7 +149,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( const float ir = 1.f / r; const float mrinv3 = multi->mass * ir * ir * ir; -#if multipole_order < 2 +#if const_gravity_multipole_order < 2 /* 0th and 1st order terms */ gp->a_grav[0] += mrinv3 * dx[0]; @@ -141,7 +157,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_grav_pm( gp->a_grav[2] += mrinv3 * dx[2]; gp->mass_interacted += multi->mass; -#elif multipole_order == 2 +#elif const_gravity_multipole_order == 2 /* Terms up to 2nd order (quadrupole) */ /* Follows the notation in Bonsai */ diff --git a/src/multipole.c b/src/multipole.c index dcd4f120d1..f0d0c7084f 100644 --- a/src/multipole.c +++ b/src/multipole.c @@ -48,7 +48,7 @@ void multipole_reset(struct multipole *m) { void multipole_init(struct multipole *m, const struct gpart *gparts, int gcount) { -#if multipole_order > 2 +#if const_gravity_multipole_order > 2 #error "Multipoles of order >2 not yet implemented." #endif @@ -59,7 +59,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, double mass = 0.0; double com[3] = {0.0, 0.0, 0.0}; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 double I_xx = 0.0, I_yy = 0.0, I_zz = 0.0; double I_xy = 0.0, I_xz = 0.0, I_yz = 0.0; #endif @@ -73,7 +73,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, com[1] += gparts[k].x[1] * w; com[2] += gparts[k].x[2] * w; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 I_xx += gparts[k].x[0] * gparts[k].x[0] * w; I_yy += gparts[k].x[1] * gparts[k].x[1] * w; I_zz += gparts[k].x[2] * gparts[k].x[2] * w; @@ -91,7 +91,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, m->CoM[1] = com[1] * imass; m->CoM[2] = com[2] * imass; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 m->I_xx = I_xx - imass * com[0] * com[0]; m->I_yy = I_yy - imass * com[1] * com[1]; m->I_zz = I_zz - imass * com[2] * com[2]; @@ -110,7 +110,7 @@ void multipole_init(struct multipole *m, const struct gpart *gparts, void multipole_add(struct multipole *ma, const struct multipole *mb) { -#if multipole_order > 2 +#if const_gravity_multipole_order > 2 #error "Multipoles of order >2 not yet implemented." #endif @@ -123,7 +123,7 @@ void multipole_add(struct multipole *ma, const struct multipole *mb) { const double ma_CoM[3] = {ma->CoM[0], ma->CoM[1], ma->CoM[2]}; const double mb_CoM[3] = {mb->CoM[0], mb->CoM[1], mb->CoM[2]}; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 const double ma_I_xx = (double)ma->I_xx + ma_mass * ma_CoM[0] * ma_CoM[0]; const double ma_I_yy = (double)ma->I_yy + ma_mass * ma_CoM[1] * ma_CoM[1]; const double ma_I_zz = (double)ma->I_zz + ma_mass * ma_CoM[2] * ma_CoM[2]; @@ -148,7 +148,7 @@ void multipole_add(struct multipole *ma, const struct multipole *mb) { ma->CoM[2] = (ma_CoM[2] * ma_mass + mb_CoM[2] * mb_mass) * M_tot_inv; /* New quadrupole */ -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 ma->I_xx = (ma_I_xx + mb_I_xx) - M_tot * ma->CoM[0] * ma->CoM[0]; ma->I_yy = (ma_I_yy + mb_I_yy) - M_tot * ma->CoM[1] * ma->CoM[1]; ma->I_zz = (ma_I_zz + mb_I_zz) - M_tot * ma->CoM[2] * ma->CoM[2]; @@ -167,7 +167,7 @@ void multipole_add(struct multipole *ma, const struct multipole *mb) { void multipole_addpart(struct multipole *m, struct gpart *p) { - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* /\* Correct the position. *\/ */ /* float mm = m->coeffs[0], mp = p->mass; */ @@ -179,7 +179,8 @@ void multipole_addpart(struct multipole *m, struct gpart *p) { /* m->coeffs[0] = mm + mp; */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } @@ -194,7 +195,7 @@ void multipole_addpart(struct multipole *m, struct gpart *p) { void multipole_addparts(struct multipole *m, struct gpart *p, int N) { - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* /\* Get the combined mass and positions. *\/ */ /* double xp[3] = {0.0, 0.0, 0.0}; */ @@ -216,7 +217,8 @@ void multipole_addparts(struct multipole *m, struct gpart *p, int N) { /* m->coeffs[0] = mm + mp; */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } diff --git a/src/multipole.h b/src/multipole.h index e9fa348b35..dc1f914dd7 100644 --- a/src/multipole.h +++ b/src/multipole.h @@ -38,7 +38,7 @@ struct multipole { /* Multipole mass */ float mass; -#if multipole_order >= 2 +#if const_gravity_multipole_order >= 2 /* Quadrupole terms */ float I_xx, I_yy, I_zz; float I_xy, I_xz, I_yz; @@ -85,14 +85,15 @@ __attribute__((always_inline)) INLINE static void multipole_iact_mm( /* acc *= const_G * ir * ir * ir; */ /* /\* Compute the forces on both multipoles. *\/ */ - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* float mma = ma->coeffs[0], mmb = mb->coeffs[0]; */ /* for (k = 0; k < 3; k++) { */ /* ma->a[k] -= dx[k] * acc * mmb; */ /* mb->a[k] += dx[k] * acc * mma; */ /* } */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } @@ -127,10 +128,11 @@ __attribute__((always_inline)) INLINE static void multipole_iact_mp( /* acc *= const_G * ir * ir * ir * m->coeffs[0]; */ /* /\* Compute the forces on both multipoles. *\/ */ - /* #if multipole_order == 1 */ + /* #if const_gravity_multipole_order == 1 */ /* for (k = 0; k < 3; k++) p->a_grav[k] += dx[k] * acc; */ /* #else */ - /* #error( "Multipoles of order %i not yet implemented." , multipole_order ) + /* #error( "Multipoles of order %i not yet implemented." , + * const_gravity_multipole_order ) */ /* #endif */ } diff --git a/src/runner_doiact_grav.h b/src/runner_doiact_grav.h index 86bb47ae66..b8c820ea9f 100644 --- a/src/runner_doiact_grav.h +++ b/src/runner_doiact_grav.h @@ -97,6 +97,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( struct gpart *restrict gparts = ci->gparts; const struct multipole multi = cj->multipole; const int ti_current = e->ti_current; + const float rlr_inv = 1.f; TIMER_TIC; @@ -137,7 +138,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pm( const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; /* Interact !*/ - runner_iact_grav_pm(r2, dx, gp, &multi); + runner_iact_grav_pm(rlr_inv, r2, dx, gp, &multi); } TIMER_TOC(TIMER_DOPAIR); // MATTHIEU @@ -162,6 +163,7 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( struct gpart *restrict gparts_i = ci->gparts; struct gpart *restrict gparts_j = cj->gparts; const int ti_current = e->ti_current; + const float rlr_inv = 1.f; TIMER_TIC; @@ -216,20 +218,20 @@ __attribute__((always_inline)) INLINE static void runner_dopair_grav_pp( /* Interact ! */ if (gpi->ti_end <= ti_current && gpj->ti_end <= ti_current) { - runner_iact_grav_pp(r2, dx, gpi, gpj); + runner_iact_grav_pp(rlr_inv, r2, dx, gpi, gpj); } else { if (gpi->ti_end <= ti_current) { - runner_iact_grav_pp_nonsym(r2, dx, gpi, gpj); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpi, gpj); } else if (gpj->ti_end <= ti_current) { dx[0] = -dx[0]; dx[1] = -dx[1]; dx[2] = -dx[2]; - runner_iact_grav_pp_nonsym(r2, dx, gpj, gpi); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpj, gpi); } } } @@ -253,6 +255,7 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( const int gcount = c->gcount; struct gpart *restrict gparts = c->gparts; const int ti_current = e->ti_current; + const float rlr_inv = 1.f; TIMER_TIC; @@ -297,20 +300,20 @@ __attribute__((always_inline)) INLINE static void runner_doself_grav_pp( /* Interact ! */ if (gpi->ti_end <= ti_current && gpj->ti_end <= ti_current) { - runner_iact_grav_pp(r2, dx, gpi, gpj); + runner_iact_grav_pp(rlr_inv, r2, dx, gpi, gpj); } else { if (gpi->ti_end <= ti_current) { - runner_iact_grav_pp_nonsym(r2, dx, gpi, gpj); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpi, gpj); } else if (gpj->ti_end <= ti_current) { dx[0] = -dx[0]; dx[1] = -dx[1]; dx[2] = -dx[2]; - runner_iact_grav_pp_nonsym(r2, dx, gpj, gpi); + runner_iact_grav_pp_nonsym(rlr_inv, r2, dx, gpj, gpi); } } } diff --git a/src/tools.c b/src/tools.c index 3af35051cd..743b282288 100644 --- a/src/tools.c +++ b/src/tools.c @@ -305,7 +305,7 @@ void pairs_single_grav(double *dim, long long int pid, fdx[i] = dx[i]; } r2 = fdx[0] * fdx[0] + fdx[1] * fdx[1] + fdx[2] * fdx[2]; - runner_iact_grav_pp(r2, fdx, &pi, &pj); + runner_iact_grav_pp(0.f, r2, fdx, &pi, &pj); a[0] += pi.a_grav[0]; a[1] += pi.a_grav[1]; a[2] += pi.a_grav[2]; @@ -519,7 +519,7 @@ void gravity_n2(struct gpart *gparts, const int gcount, const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; /* Apply the gravitational acceleration. */ - runner_iact_grav_pp(r2, dx, gpi, gpj); + runner_iact_grav_pp(0.f, r2, dx, gpi, gpj); } } -- GitLab