From 4fc9291edd0f3200a8f0891ac603d4c60aaaf339 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 12:33:20 +0000 Subject: [PATCH 01/79] Updated dt_alpha to be more consistent with other schemes. --- src/runner.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/runner.c b/src/runner.c index dfbb9e214..98985207f 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1254,7 +1254,7 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xparts = c->hydro.xparts; const int count = c->hydro.count; const struct engine *e = r->e; - const integertime_t ti_end = e->ti_current; + const integertime_t ti_current = e->ti_current; const int with_cosmology = (e->policy & engine_policy_cosmology); const double time_base = e->time_base; const struct cosmology *cosmo = e->cosmology; @@ -1289,9 +1289,14 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer) { * This is the physical time between the start and end of the time-step * without any scale-factor powers. */ double dt_alpha; + if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); - dt_alpha = cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + + dt_alpha = + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } @@ -1470,13 +1475,16 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { * artificial viscosity and thermal conduction terms) */ const int with_cosmology = (e->policy & engine_policy_cosmology); const double time_base = e->time_base; - const integertime_t ti_end = e->ti_current; + const integertime_t ti_current = e->ti_current; double dt_alpha; if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + dt_alpha = - cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } @@ -1614,13 +1622,17 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { * the evolution of alpha factors (i.e. those involved in the artificial * viscosity and thermal conduction terms) */ const int with_cosmology = (e->policy & engine_policy_cosmology); - const integertime_t ti_end = e->ti_current; const double time_base = e->time_base; + const integertime_t ti_current = e->ti_current; double dt_alpha; if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); - dt_alpha = cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + + dt_alpha = + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } -- GitLab From 4d5da992b465f2a0d5178474a94ce9d83aa7a07c Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 14:54:58 +0000 Subject: [PATCH 02/79] Changed 3.f to hydro_dimension --- src/hydro/Gadget2/hydro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index bcef24808..f05e3229a 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -562,7 +562,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->density.rot_v[2] * p->density.rot_v[2]); /* Compute the norm of div v including the Hubble flow term */ - const float div_physical_v = p->density.div_v + 3.f * cosmo->H; + const float div_physical_v = p->density.div_v + hydro_dimension * cosmo->H; const float abs_div_physical_v = fabsf(div_physical_v); /* Compute the pressure */ -- GitLab From 0d1ebebab226160950a4a9283bfe04b572b79ca8 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 16:02:58 +0000 Subject: [PATCH 03/79] Added hydro_dimension in place of 3.f --- src/hydro/Minimal/hydro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index 1d5d25f73..e2fd00695 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -561,7 +561,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->density.rot_v[2] * p->density.rot_v[2]); /* Compute the norm of div v including the Hubble flow term */ - const float div_physical_v = p->density.div_v + 3.f * cosmo->H; + const float div_physical_v = p->density.div_v + hydro_dimension * cosmo->H; const float abs_div_physical_v = fabsf(div_physical_v); /* Compute the pressure */ -- GitLab From ff5b717ce72a9909c43cd0616312ed54573423bc Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 16:25:03 +0000 Subject: [PATCH 04/79] Fixes hubble term in Pressure-Energy schemes for DivV --- src/hydro/PressureEnergy/hydro.h | 4 ++-- src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index 0e53b5f2e..3fe3c805f 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -530,8 +530,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( /* Finish calculation of the velocity divergence, including hubble flow term */ - p->density.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->density.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->density.div_v += cosmo->H * hydro_dimension; } /** diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h index 9f981569e..819abeec9 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h @@ -526,8 +526,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( p->density.rot_v[2] *= h_inv_dim_plus_one * a_inv2 * rho_inv; /* Finish calculation of the velocity divergence */ - p->density.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->density.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->density.div_v += cosmo->H * hydro_dimension; } /** @@ -614,7 +614,11 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Artificial viscosity updates */ - const float inverse_tau = hydro_props->viscosity.length * soundspeed * h_inv; + /* Need to divide by a^2 here because this is a timescale and we need to + introduce the time-integration factor to balance out the scale-free + nature of the artificial viscosity (i.e. dt has a^2 built in) */ + const float inverse_tau = + (hydro_props->viscosity.length * cosmo->a2_inv) * soundspeed * h_inv; const float source_term = -1.f * min(p->density.div_v, 0.f); /* Compute da/dt */ @@ -869,4 +873,4 @@ hydro_set_init_internal_energy(struct part *p, float u_init) { __attribute__((always_inline)) INLINE static void hydro_remove_part( const struct part *p, const struct xpart *xp) {} -#endif /* SWIFT_PRESSURE_ENERGY_MORRIS_HYDRO_H */ +#endif /* SWIFT_PRESSURE_ENERGY_MORRIS_HYDRO_H */ \ No newline at end of file -- GitLab From b83abf424dbda881b33351cae26bedb5fe21417b Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 16:25:18 +0000 Subject: [PATCH 05/79] Fixes cosmological integration of the AV and AD in ANARCHY --- src/hydro/AnarchyPU/hydro.h | 44 +++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 37d182889..0403608fe 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -541,8 +541,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( p->density.rot_v[2] *= h_inv_dim_plus_one * a_inv2 * rho_inv; /* Finish calculation of the velocity divergence */ - p->viscosity.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->viscosity.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->viscosity.div_v += cosmo->H * hydro_dimension; } /** @@ -694,18 +694,37 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Here we need to update the artificial viscosity */ /* Timescale for decay */ - const float tau = - p->h / (2.f * p->viscosity.v_sig * hydro_props->viscosity.length); - /* Construct time differential of div.v implicitly */ - const float div_v_dt = + + const float a2 = cosmo->a * cosmo->a; + const float a_fac_soundspeed = cosmo->a_factor_sound_speed; + + /* We integrate the whole AV scheme in physical units as cancelling the cosmology terms + is just a nightmare, especially for non-standard gas_gamma. */ + + const float h_physical = p->h * cosmo->a; + const float v_sig_physical = p->viscosity.v_sig / a_fac_soundspeed; + const float div_v_physical = + (p->viscosity.div_v - cosmo->H * hydro_dimension) * a2; + const float div_v_prev_physical = + (p->viscosity.div_v_previous_step - cosmo->H * hydro_dimension) * a2; + const float dt_alpha_physical = dt_alpha / a2; + + const float tau = h_physical / (2.f * v_sig_physical * hydro_props->viscosity.length); + + /* Construct time differential of div.v implicitly following the ANARCHY spec */ + + float div_v_dt = dt_alpha == 0.f ? 0.f - : (p->viscosity.div_v - p->viscosity.div_v_previous_step) / dt_alpha; + : (div_v_physical - div_v_prev_physical) / dt_alpha_physical; + /* Construct the source term for the AV; if shock detected this is _positive_ * as div_v_dt should be _negative_ before the shock hits */ - const float S = p->h * p->h * max(0.f, -1.f * div_v_dt); - const float v_sig_square = p->viscosity.v_sig * p->viscosity.v_sig; + const float S = h_physical * h_physical * max(0.f, -1.f * div_v_dt); + const float v_sig_square = v_sig_physical * v_sig_physical; + /* Calculate the current appropriate value of the AV based on the above */ + /* Note this is v_sig_physical squared, not comoving */ const float alpha_loc = hydro_props->viscosity.alpha_max * S / (v_sig_square + S); @@ -717,7 +736,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float alpha_dt = (alpha_loc - p->viscosity.alpha) / tau; /* Finally, we can update the actual value of the alpha */ - p->viscosity.alpha += alpha_dt * dt_alpha; + p->viscosity.alpha += alpha_dt * dt_alpha_physical; } if (p->viscosity.alpha < hydro_props->viscosity.alpha_min) { @@ -732,7 +751,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ /* alpha_diff_dt is cosmology-less */ - /* Evolution term: following Schaller+ 2015 */ + /* Evolution term: following Schaller+ 2015. This is actually cosmology-less and + so requires no conversion to physical. */ float alpha_diff_dt = hydro_props->diffusion.beta * p->h * p->diffusion.laplace_u / sqrt_u; /* Decay term: not documented in Schaller+ 2015 but was present @@ -741,7 +761,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( (p->diffusion.alpha - hydro_props->diffusion.alpha_min) / tau; float new_diffusion_alpha = p->diffusion.alpha; - new_diffusion_alpha += alpha_diff_dt * dt_alpha; + new_diffusion_alpha += alpha_diff_dt * dt_alpha_physical; /* Consistency checks to ensure min < alpha < max */ if (new_diffusion_alpha > hydro_props->diffusion.alpha_max) { -- GitLab From 5d5433c05420ff4844f3a85dc1df59e07c39b75e Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 12:33:20 +0000 Subject: [PATCH 06/79] Updated dt_alpha to be more consistent with other schemes. --- src/runner.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/runner.c b/src/runner.c index 719c193e3..24956dc70 100644 --- a/src/runner.c +++ b/src/runner.c @@ -1259,7 +1259,7 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer) { struct xpart *restrict xparts = c->hydro.xparts; const int count = c->hydro.count; const struct engine *e = r->e; - const integertime_t ti_end = e->ti_current; + const integertime_t ti_current = e->ti_current; const int with_cosmology = (e->policy & engine_policy_cosmology); const double time_base = e->time_base; const struct cosmology *cosmo = e->cosmology; @@ -1294,9 +1294,14 @@ void runner_do_extra_ghost(struct runner *r, struct cell *c, int timer) { * This is the physical time between the start and end of the time-step * without any scale-factor powers. */ double dt_alpha; + if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); - dt_alpha = cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + + dt_alpha = + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } @@ -1475,13 +1480,16 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { * artificial viscosity and thermal conduction terms) */ const int with_cosmology = (e->policy & engine_policy_cosmology); const double time_base = e->time_base; - const integertime_t ti_end = e->ti_current; + const integertime_t ti_current = e->ti_current; double dt_alpha; if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + dt_alpha = - cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } @@ -1619,13 +1627,17 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { * the evolution of alpha factors (i.e. those involved in the artificial * viscosity and thermal conduction terms) */ const int with_cosmology = (e->policy & engine_policy_cosmology); - const integertime_t ti_end = e->ti_current; const double time_base = e->time_base; + const integertime_t ti_current = e->ti_current; double dt_alpha; if (with_cosmology) { const integertime_t ti_step = get_integer_timestep(p->time_bin); - dt_alpha = cosmology_get_delta_time(cosmo, ti_end - ti_step, ti_end); + const integertime_t ti_begin = + get_integer_time_begin(ti_current - 1, p->time_bin); + + dt_alpha = + cosmology_get_delta_time(cosmo, ti_begin, ti_begin + ti_step); } else { dt_alpha = get_timestep(p->time_bin, time_base); } -- GitLab From 0c8488f731ba7c72110f6712f67e05f9d3f6658e Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 14:54:58 +0000 Subject: [PATCH 07/79] Changed 3.f to hydro_dimension --- src/hydro/Gadget2/hydro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index bcef24808..f05e3229a 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -562,7 +562,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->density.rot_v[2] * p->density.rot_v[2]); /* Compute the norm of div v including the Hubble flow term */ - const float div_physical_v = p->density.div_v + 3.f * cosmo->H; + const float div_physical_v = p->density.div_v + hydro_dimension * cosmo->H; const float abs_div_physical_v = fabsf(div_physical_v); /* Compute the pressure */ -- GitLab From 884a8c0cb3dda2b6e27ddc3bc2575b5093abaede Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 16:02:58 +0000 Subject: [PATCH 08/79] Added hydro_dimension in place of 3.f --- src/hydro/Minimal/hydro.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index 1d5d25f73..e2fd00695 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -561,7 +561,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->density.rot_v[2] * p->density.rot_v[2]); /* Compute the norm of div v including the Hubble flow term */ - const float div_physical_v = p->density.div_v + 3.f * cosmo->H; + const float div_physical_v = p->density.div_v + hydro_dimension * cosmo->H; const float abs_div_physical_v = fabsf(div_physical_v); /* Compute the pressure */ -- GitLab From 91e7802c4e28cdc9981055cd171f8abed974a967 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 16:25:03 +0000 Subject: [PATCH 09/79] Fixes hubble term in Pressure-Energy schemes for DivV --- src/hydro/PressureEnergy/hydro.h | 4 ++-- src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index 0e53b5f2e..3fe3c805f 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -530,8 +530,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( /* Finish calculation of the velocity divergence, including hubble flow term */ - p->density.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->density.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->density.div_v += cosmo->H * hydro_dimension; } /** diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h index 9f981569e..819abeec9 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h @@ -526,8 +526,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( p->density.rot_v[2] *= h_inv_dim_plus_one * a_inv2 * rho_inv; /* Finish calculation of the velocity divergence */ - p->density.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->density.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->density.div_v += cosmo->H * hydro_dimension; } /** @@ -614,7 +614,11 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Artificial viscosity updates */ - const float inverse_tau = hydro_props->viscosity.length * soundspeed * h_inv; + /* Need to divide by a^2 here because this is a timescale and we need to + introduce the time-integration factor to balance out the scale-free + nature of the artificial viscosity (i.e. dt has a^2 built in) */ + const float inverse_tau = + (hydro_props->viscosity.length * cosmo->a2_inv) * soundspeed * h_inv; const float source_term = -1.f * min(p->density.div_v, 0.f); /* Compute da/dt */ @@ -869,4 +873,4 @@ hydro_set_init_internal_energy(struct part *p, float u_init) { __attribute__((always_inline)) INLINE static void hydro_remove_part( const struct part *p, const struct xpart *xp) {} -#endif /* SWIFT_PRESSURE_ENERGY_MORRIS_HYDRO_H */ +#endif /* SWIFT_PRESSURE_ENERGY_MORRIS_HYDRO_H */ \ No newline at end of file -- GitLab From 1615b7250502058352a48088e2237286f33a5aad Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 20 Mar 2019 16:25:18 +0000 Subject: [PATCH 10/79] Fixes cosmological integration of the AV and AD in ANARCHY --- src/hydro/AnarchyPU/hydro.h | 44 +++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 37d182889..0403608fe 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -541,8 +541,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_density( p->density.rot_v[2] *= h_inv_dim_plus_one * a_inv2 * rho_inv; /* Finish calculation of the velocity divergence */ - p->viscosity.div_v *= - h_inv_dim_plus_one * rho_inv * a_inv2 + cosmo->H * hydro_dimension; + p->viscosity.div_v *= h_inv_dim_plus_one * rho_inv * a_inv2; + p->viscosity.div_v += cosmo->H * hydro_dimension; } /** @@ -694,18 +694,37 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Here we need to update the artificial viscosity */ /* Timescale for decay */ - const float tau = - p->h / (2.f * p->viscosity.v_sig * hydro_props->viscosity.length); - /* Construct time differential of div.v implicitly */ - const float div_v_dt = + + const float a2 = cosmo->a * cosmo->a; + const float a_fac_soundspeed = cosmo->a_factor_sound_speed; + + /* We integrate the whole AV scheme in physical units as cancelling the cosmology terms + is just a nightmare, especially for non-standard gas_gamma. */ + + const float h_physical = p->h * cosmo->a; + const float v_sig_physical = p->viscosity.v_sig / a_fac_soundspeed; + const float div_v_physical = + (p->viscosity.div_v - cosmo->H * hydro_dimension) * a2; + const float div_v_prev_physical = + (p->viscosity.div_v_previous_step - cosmo->H * hydro_dimension) * a2; + const float dt_alpha_physical = dt_alpha / a2; + + const float tau = h_physical / (2.f * v_sig_physical * hydro_props->viscosity.length); + + /* Construct time differential of div.v implicitly following the ANARCHY spec */ + + float div_v_dt = dt_alpha == 0.f ? 0.f - : (p->viscosity.div_v - p->viscosity.div_v_previous_step) / dt_alpha; + : (div_v_physical - div_v_prev_physical) / dt_alpha_physical; + /* Construct the source term for the AV; if shock detected this is _positive_ * as div_v_dt should be _negative_ before the shock hits */ - const float S = p->h * p->h * max(0.f, -1.f * div_v_dt); - const float v_sig_square = p->viscosity.v_sig * p->viscosity.v_sig; + const float S = h_physical * h_physical * max(0.f, -1.f * div_v_dt); + const float v_sig_square = v_sig_physical * v_sig_physical; + /* Calculate the current appropriate value of the AV based on the above */ + /* Note this is v_sig_physical squared, not comoving */ const float alpha_loc = hydro_props->viscosity.alpha_max * S / (v_sig_square + S); @@ -717,7 +736,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float alpha_dt = (alpha_loc - p->viscosity.alpha) / tau; /* Finally, we can update the actual value of the alpha */ - p->viscosity.alpha += alpha_dt * dt_alpha; + p->viscosity.alpha += alpha_dt * dt_alpha_physical; } if (p->viscosity.alpha < hydro_props->viscosity.alpha_min) { @@ -732,7 +751,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ /* alpha_diff_dt is cosmology-less */ - /* Evolution term: following Schaller+ 2015 */ + /* Evolution term: following Schaller+ 2015. This is actually cosmology-less and + so requires no conversion to physical. */ float alpha_diff_dt = hydro_props->diffusion.beta * p->h * p->diffusion.laplace_u / sqrt_u; /* Decay term: not documented in Schaller+ 2015 but was present @@ -741,7 +761,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( (p->diffusion.alpha - hydro_props->diffusion.alpha_min) / tau; float new_diffusion_alpha = p->diffusion.alpha; - new_diffusion_alpha += alpha_diff_dt * dt_alpha; + new_diffusion_alpha += alpha_diff_dt * dt_alpha_physical; /* Consistency checks to ensure min < alpha < max */ if (new_diffusion_alpha > hydro_props->diffusion.alpha_max) { -- GitLab From 17d77af75b166384cd970a5c99f76b6cedd0c76c Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Thu, 21 Mar 2019 10:01:01 +0000 Subject: [PATCH 11/79] Added printing of lambda constant in internal units --- src/cooling/const_lambda/cooling.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index 1e50c162d..0d15c297f 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -352,6 +352,10 @@ static INLINE void cooling_print_backend( "* " "cm^3]", cooling->lambda_nH2_cgs); + + message( + "Lambda/n_H^2=%g [internal units]", cooling->lambda_nH2_cgs * cooling->conv_factor_energy_rate_from_cgs + ); if (cooling->cooling_tstep_mult == FLT_MAX) message("Cooling function time-step size is unlimited"); -- GitLab From 7d4fbe6015ed540f898f2630b80b46583546c6d7 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Fri, 22 Mar 2019 15:00:38 +0000 Subject: [PATCH 12/79] Added new example to test cosmology of cooling --- .../cooling_redshift_dependence_low_z.yml | 80 +++++++++++ .../cooling_redshift_dependence_no_z.yml | 72 ++++++++++ .../CoolingRedshiftDependence/getGlass.sh | 2 + .../CoolingRedshiftDependence/makeIC.py | 125 ++++++++++++++++++ .../CoolingRedshiftDependence/plotSolution.py | 111 ++++++++++++++++ .../Cooling/CoolingRedshiftDependence/run.sh | 22 +++ 6 files changed, 412 insertions(+) create mode 100644 examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml create mode 100644 examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml create mode 100755 examples/Cooling/CoolingRedshiftDependence/getGlass.sh create mode 100644 examples/Cooling/CoolingRedshiftDependence/makeIC.py create mode 100644 examples/Cooling/CoolingRedshiftDependence/plotSolution.py create mode 100755 examples/Cooling/CoolingRedshiftDependence/run.sh diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml new file mode 100644 index 000000000..c7c7d65e2 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml @@ -0,0 +1,80 @@ +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98848e43 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e24 # 1 Mpc + UnitVelocity_in_cgs: 1e5 # 1 km/s + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Cosmological parameters +Cosmology: + h: 0.6777 # Reduced Hubble constant + a_begin: 0.5 # Initial scale-factor of the simulation (z = 1.0) + a_end: 0.5061559 # Final scale factor of the simulation (~ 100 myr) + Omega_m: 0.307 # Matter density parameter + Omega_lambda: 0.693 # Dark-energy density parameter + Omega_b: 0.0455 # Baryon density parameter + +# Parameters governing the time integration +TimeIntegration: + dt_min: 1e-14 + dt_max: 5e-3 + +# Parameters governing the snapshots +Snapshots: + basename: redshift_dependence_low_z + delta_time: 1.000122373748838 + scale_factor_first: 0.5 + compression: 4 + +# Parameters governing the conserved quantities statistics +Statistics: + scale_factor_first: 0.5 + delta_time: 1.1 + +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. + minimal_temperature: 100 # K + +# Parameters related to the initial conditions +InitialConditions: + file_name: ./ics_low_z.hdf5 # The file to read + periodic: 1 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Solar abundances + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0. + init_abundance_Nitrogen: 0. + init_abundance_Oxygen: 0. + init_abundance_Neon: 0. + init_abundance_Magnesium: 0. + init_abundance_Silicon: 0. + init_abundance_Iron: 0. + +# Parameters for the EAGLE cooling +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] \ No newline at end of file diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml new file mode 100644 index 000000000..ba6fe62d4 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml @@ -0,0 +1,72 @@ +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98848e43 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e24 # 1 Mpc + UnitVelocity_in_cgs: 1e5 # 1 km/s + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Parameters governing the time integration +TimeIntegration: + time_begin: 0. + time_end: 1.02e-4 # ~ 100 myr + dt_min: 1e-14 + dt_max: 5e-8 + +# Parameters governing the snapshots +Snapshots: + basename: redshift_dependence_no_z + delta_time: 1.02e-6 + compression: 4 + +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1.02e-6 + +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. + minimal_temperature: 100 # K + +# Parameters related to the initial conditions +InitialConditions: + file_name: ./ics_no_z.hdf5 # The file to read + periodic: 1 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Solar abundances + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0. + init_abundance_Nitrogen: 0. + init_abundance_Oxygen: 0. + init_abundance_Neon: 0. + init_abundance_Magnesium: 0. + init_abundance_Silicon: 0. + init_abundance_Iron: 0. + +# Parameters for the EAGLE cooling +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] + cooling_tstep_mult: 1e5 # (Optional) Dimensionless pre-factor for the time-step condition. diff --git a/examples/Cooling/CoolingRedshiftDependence/getGlass.sh b/examples/Cooling/CoolingRedshiftDependence/getGlass.sh new file mode 100755 index 000000000..01b4474ac --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/getGlass.sh @@ -0,0 +1,2 @@ +#!/bin/bash +wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/gravity_glassCube_32.hdf5 diff --git a/examples/Cooling/CoolingRedshiftDependence/makeIC.py b/examples/Cooling/CoolingRedshiftDependence/makeIC.py new file mode 100644 index 000000000..47e3540d5 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/makeIC.py @@ -0,0 +1,125 @@ +""" +Creates a redshift-dependent cooling box such that it always has the same +_physical_ density at the given redshift. +""" + +from swiftsimio import Writer +from swiftsimio.units import cosmo_units + +from unyt import mh, cm, s, K, Mpc, kb +import numpy as np + +import h5py + +# Physics parameters. +boxsize = 1.0 * Mpc +physical_density = 1.0 * mh / cm ** 3 +mu_hydrogen = 0.5 # Fully ionised +temperature = 1e7 * K +gamma = 5.0 / 3.0 + + +def get_coordinates(glass_filename: str) -> np.array: + """ + Gets the coordinates from the glass file. + """ + + with h5py.File(glass_filename, "r") as handle: + coordinates = handle["PartType1/Coordinates"][...] + + return coordinates + + +def generate_ics(redshift: float, filename: str, glass_filename: str) -> None: + """ + Generate initial conditions for the CoolingRedshiftDependence example. + """ + + scale_factor = 1 / (1 + redshift) + energy_factor = scale_factor ** (-3.0 * (gamma - 1)) + comoving_boxsize = boxsize * scale_factor + + glass_coordinates = get_coordinates(glass_filename) + number_of_particles = len(glass_coordinates) + + gas_particle_mass = physical_density * (comoving_boxsize ** 3) / number_of_particles + + writer = Writer(cosmo_units, comoving_boxsize) + + writer.gas.coordinates = glass_coordinates * comoving_boxsize + + writer.gas.velocities = np.zeros_like(glass_coordinates) * cm / s + + writer.gas.masses = np.ones(number_of_particles, dtype=float) * gas_particle_mass + + writer.gas.internal_energy = ( + np.ones(number_of_particles, dtype=float) + * energy_factor + * (3.0 / 2.0) + * (temperature * kb) + / (mu_hydrogen * mh) + ) + + writer.gas.generate_smoothing_lengths(boxsize=comoving_boxsize, dimension=3) + + writer.write(filename) + + return + + +if __name__ == "__main__": + """ + Sets up the initial parameters. + """ + + import argparse as ap + + parser = ap.ArgumentParser( + description=""" + Sets up the initial conditions for the cooling test. Takes two + redshifts, and produces two files: ics_high_z.hdf5 and + ics_low_z.hdf5. + """ + ) + + parser.add_argument( + "-a", + "--high", + help="The high redshift to generate initial conditions for. Default: 10.0", + default=10, + type=float, + ) + + parser.add_argument( + "-b", + "--low", + help="The low redshift to generate initial conditions for. Default: 1.0", + default=1, + type=float, + ) + + parser.add_argument( + "-n", + "--nocosmo", + help="Generate a non-cosmological box? Default: Truthy", + default=1, + type=bool, + ) + + parser.add_argument( + "-g", + "--glass", + help="Glass filename. Default: gravity_glassCube_32.hdf5", + type=str, + default="gravity_glassCube_32.hdf5", + ) + + args = parser.parse_args() + + generate_ics(args.low, filename="ics_low_z.hdf5", glass_filename=args.glass) + generate_ics(args.high, filename="ics_high_z.hdf5", glass_filename=args.glass) + + if args.nocosmo: + generate_ics(1.0, filename="ics_no_z.hdf5", glass_filename=args.glass) + + exit(0) diff --git a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py new file mode 100644 index 000000000..44427be76 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py @@ -0,0 +1,111 @@ +""" +Plots the mean temperature. +""" + +import matplotlib.pyplot as plt + +from swiftsimio import load + +from unyt import Myr, K, mh, cm + +import numpy as np + + +def setup_axes(): + """ + Sets up the axes and returns fig, ax + """ + + fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(4, 8), sharex=True) + + ax = ax.flatten() + + ax[0].semilogy() + + ax[1].set_xlabel("Simulation time elapsed [Myr]") + ax[0].set_ylabel("Temperature of Universe [K]") + ax[1].set_ylabel("Physical Density of Universe [$n_H$ cm$^{-3}$]") + + ax[0].set_xlim(0, 50) + + fig.tight_layout() + + return fig, ax + + +def get_data(handle: float, n_snaps: int): + """ + Returns the elapsed simulation time, temperature, and density + """ + + t0 = 0.0 + + times = [] + temps = [] + densities = [] + + for snap in range(n_snaps): + data = load(f"{handle}_{snap:04d}.hdf5") + + if snap == 0: + t0 = data.metadata.t.to(Myr).value + + times.append(data.metadata.t.to(Myr).value - t0) + temps.append(np.mean(data.gas.temperature.to(K).value)) + densities.append(np.mean(data.gas.density.to(mh / cm**3).value) / (data.metadata.scale_factor**3) ) + + return times, temps, densities + + +def plot_single_data(handle: str, n_snaps: int, label: str, ax: plt.axes): + """ + Takes the a single simulation and plots it on the axes. + """ + + data = get_data(handle, n_snaps) + + ax[0].plot( + data[0], data[1], + label=label, + marker="o", + ms=2 + ) + + ax[1].plot( + data[0], data[2], + label=label, + marker="o", + ms=2 + ) + + + return + + +def make_plot(handles, names, n_snaps=100): + """ + Makes the whole plot and returns the fig, ax objects. + """ + + fig, ax = setup_axes() + + for handle, name in zip(handles, names): + plot_single_data(handle, n_snaps, name, ax) + + ax[0].legend() + + return fig, ax + + +if __name__ == "__main__": + """ + Plot everything! + """ + + handles = ["redshift_dependence_no_z", "redshift_dependence_low_z"] + names = ["No Cosmology", "Low Redshift"] + + fig, ax = make_plot(handles, names) + + fig.savefig("redshift_dependence.png", dpi=300) + diff --git a/examples/Cooling/CoolingRedshiftDependence/run.sh b/examples/Cooling/CoolingRedshiftDependence/run.sh new file mode 100755 index 000000000..25e600f65 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/run.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Generate the initial conditions if they are not present. +if [ ! -e gravity_glassCube_32.hdf5 ] +then + echo "Fetching initial gravity glass file for the constant cosmological box example..." + ./getGlass.sh +fi + +# Fetch the cooling tables +if [ ! -e ics_no_z.hdf5 ] +then + echo "Generating initial conditions for the uniform cosmo box example..." + python3 makeIC.py +fi + +swift_location="../../../build/anarchy-const-lambda/examples/swift" + +# Run SWIFT +$swift_location --hydro --cosmology --cooling --threads=4 cooling_redshift_dependence_low_z.yml 2>&1 | tee output_low.log +$swift_location --hydro --cooling --threads=4 cooling_redshift_dependence_no_z.yml 2>&1 | tee output_no.log + -- GitLab From d65deba5b730dc3b38f15ac7d3d913368dab7889 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Fri, 22 Mar 2019 17:30:25 +0000 Subject: [PATCH 13/79] Minor improvements to the new cooling test --- .../cooling_redshift_dependence_high_z.yml | 80 +++++++++++++++++++ .../cooling_redshift_dependence_low_z.yml | 10 +-- .../cooling_redshift_dependence_no_z.yml | 1 - .../CoolingRedshiftDependence/makeIC.py | 18 ++--- .../CoolingRedshiftDependence/plotSolution.py | 6 +- .../Cooling/CoolingRedshiftDependence/run.sh | 9 ++- .../ComovingSodShock_3D/sodShock.yml | 43 +++++++++- 7 files changed, 144 insertions(+), 23 deletions(-) create mode 100644 examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml new file mode 100644 index 000000000..e9fb6d995 --- /dev/null +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml @@ -0,0 +1,80 @@ +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98848e43 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e24 # 1 Mpc + UnitVelocity_in_cgs: 1e5 # 1 km/s + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Cosmological parameters +Cosmology: + h: 0.6777 # Reduced Hubble constant + a_begin: 0.5 # Initial scale-factor of the simulation (z = 1.0) + a_end: 0.5061559 # Final scale factor of the simulation (~ 100 myr) + Omega_m: 0.307 # Matter density parameter + Omega_lambda: 0.693 # Dark-energy density parameter + Omega_b: 0.0455 # Baryon density parameter + +# Parameters governing the time integration +TimeIntegration: + dt_min: 1e-14 + dt_max: 5e-3 + +# Parameters governing the snapshots +Snapshots: + basename: redshift_dependence_high_z + delta_time: 1.000122373748838 + scale_factor_first: 0.5 + compression: 4 + +# Parameters governing the conserved quantities statistics +Statistics: + scale_factor_first: 0.5 + delta_time: 1.1 + +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + CFL_condition: 0.1 # Courant-Friedrich-Levy condition for time integration. + minimal_temperature: 100 # K + +# Parameters related to the initial conditions +InitialConditions: + file_name: ./ics_high_z.hdf5 # The file to read + periodic: 1 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Solar abundances + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0. + init_abundance_Nitrogen: 0. + init_abundance_Oxygen: 0. + init_abundance_Neon: 0. + init_abundance_Magnesium: 0. + init_abundance_Silicon: 0. + init_abundance_Iron: 0. + +# Parameters for the EAGLE cooling +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] \ No newline at end of file diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml index c7c7d65e2..159a5e3f4 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml @@ -9,8 +9,8 @@ InternalUnitSystem: # Cosmological parameters Cosmology: h: 0.6777 # Reduced Hubble constant - a_begin: 0.5 # Initial scale-factor of the simulation (z = 1.0) - a_end: 0.5061559 # Final scale factor of the simulation (~ 100 myr) + a_begin: 0.99009 # Initial scale-factor of the simulation (z = 0.01) + a_end: 0.99700 # Final scale factor of the simulation (~ 100 myr) Omega_m: 0.307 # Matter density parameter Omega_lambda: 0.693 # Dark-energy density parameter Omega_b: 0.0455 # Baryon density parameter @@ -23,13 +23,13 @@ TimeIntegration: # Parameters governing the snapshots Snapshots: basename: redshift_dependence_low_z - delta_time: 1.000122373748838 - scale_factor_first: 0.5 + delta_time: 1.0000695206950205 + scale_factor_first: 0.99009 compression: 4 # Parameters governing the conserved quantities statistics Statistics: - scale_factor_first: 0.5 + scale_factor_first: 0.99009 delta_time: 1.1 # Parameters for the hydrodynamics scheme diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml index ba6fe62d4..8b00ca0ac 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml @@ -69,4 +69,3 @@ EAGLEEntropyFloor: LambdaCooling: lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] - cooling_tstep_mult: 1e5 # (Optional) Dimensionless pre-factor for the time-step condition. diff --git a/examples/Cooling/CoolingRedshiftDependence/makeIC.py b/examples/Cooling/CoolingRedshiftDependence/makeIC.py index 47e3540d5..489be7636 100644 --- a/examples/Cooling/CoolingRedshiftDependence/makeIC.py +++ b/examples/Cooling/CoolingRedshiftDependence/makeIC.py @@ -36,13 +36,12 @@ def generate_ics(redshift: float, filename: str, glass_filename: str) -> None: """ scale_factor = 1 / (1 + redshift) - energy_factor = scale_factor ** (-3.0 * (gamma - 1)) - comoving_boxsize = boxsize * scale_factor + comoving_boxsize = boxsize / scale_factor glass_coordinates = get_coordinates(glass_filename) number_of_particles = len(glass_coordinates) - gas_particle_mass = physical_density * (comoving_boxsize ** 3) / number_of_particles + gas_particle_mass = physical_density * (boxsize ** 3) / number_of_particles writer = Writer(cosmo_units, comoving_boxsize) @@ -52,10 +51,9 @@ def generate_ics(redshift: float, filename: str, glass_filename: str) -> None: writer.gas.masses = np.ones(number_of_particles, dtype=float) * gas_particle_mass + # Leave in physical units; handled by boxsize change. writer.gas.internal_energy = ( np.ones(number_of_particles, dtype=float) - * energy_factor - * (3.0 / 2.0) * (temperature * kb) / (mu_hydrogen * mh) ) @@ -85,16 +83,16 @@ if __name__ == "__main__": parser.add_argument( "-a", "--high", - help="The high redshift to generate initial conditions for. Default: 10.0", - default=10, + help="The high redshift to generate initial conditions for. Default: 1.0", + default=1, type=float, ) parser.add_argument( "-b", "--low", - help="The low redshift to generate initial conditions for. Default: 1.0", - default=1, + help="The low redshift to generate initial conditions for. Default: 0.01", + default=0.01, type=float, ) @@ -120,6 +118,6 @@ if __name__ == "__main__": generate_ics(args.high, filename="ics_high_z.hdf5", glass_filename=args.glass) if args.nocosmo: - generate_ics(1.0, filename="ics_no_z.hdf5", glass_filename=args.glass) + generate_ics(0.0, filename="ics_no_z.hdf5", glass_filename=args.glass) exit(0) diff --git a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py index 44427be76..d8a4ddc0f 100644 --- a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py +++ b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py @@ -26,7 +26,7 @@ def setup_axes(): ax[0].set_ylabel("Temperature of Universe [K]") ax[1].set_ylabel("Physical Density of Universe [$n_H$ cm$^{-3}$]") - ax[0].set_xlim(0, 50) + ax[0].set_xlim(0, 100) fig.tight_layout() @@ -102,8 +102,8 @@ if __name__ == "__main__": Plot everything! """ - handles = ["redshift_dependence_no_z", "redshift_dependence_low_z"] - names = ["No Cosmology", "Low Redshift"] + handles = ["redshift_dependence_no_z", "redshift_dependence_low_z", "redshift_dependence_high_z"] + names = ["No Cosmology", "Low Redshift ($z=0.01$)", "High Redshift ($z=1$)"] fig, ax = make_plot(handles, names) diff --git a/examples/Cooling/CoolingRedshiftDependence/run.sh b/examples/Cooling/CoolingRedshiftDependence/run.sh index 25e600f65..ba399811e 100755 --- a/examples/Cooling/CoolingRedshiftDependence/run.sh +++ b/examples/Cooling/CoolingRedshiftDependence/run.sh @@ -14,9 +14,16 @@ then python3 makeIC.py fi -swift_location="../../../build/anarchy-const-lambda/examples/swift" +swift_location="../../../build/gadget-const-lambda/examples/swift" + +rm redshift_dependence_*_z_*.hdf5 # Run SWIFT +$swift_location --hydro --cosmology --cooling --threads=4 cooling_redshift_dependence_high_z.yml 2>&1 | tee output_high.log +mv timesteps_4.txt timesteps_high.txt $swift_location --hydro --cosmology --cooling --threads=4 cooling_redshift_dependence_low_z.yml 2>&1 | tee output_low.log +mv timesteps_4.txt timesteps_low.txt $swift_location --hydro --cooling --threads=4 cooling_redshift_dependence_no_z.yml 2>&1 | tee output_no.log +mv timesteps_4.txt timesteps_no.txt +python3 plotSolution.py diff --git a/examples/Cosmology/ComovingSodShock_3D/sodShock.yml b/examples/Cosmology/ComovingSodShock_3D/sodShock.yml index 2d7a5727c..f7cf51ce0 100644 --- a/examples/Cosmology/ComovingSodShock_3D/sodShock.yml +++ b/examples/Cosmology/ComovingSodShock_3D/sodShock.yml @@ -1,14 +1,14 @@ # Define the system of units to use internally. InternalUnitSystem: - UnitMass_in_cgs: 2.94e55 # Grams + UnitMass_in_cgs: 2.94e45 # Grams UnitLength_in_cgs: 3.086e18 # pc - UnitVelocity_in_cgs: 1. # km per s + UnitVelocity_in_cgs: 1e10 # km per s UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin # Parameters governing the time integration TimeIntegration: - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-18 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-3 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots @@ -16,11 +16,13 @@ Snapshots: basename: sodShock # Common part of the name of output files time_first: 0. # Time of the first output (in internal units) delta_time: 1.06638 # Time difference between consecutive outputs (in internal units) + # scale_factor_first: 1.0 scale_factor_first: 0.001 compression: 1 # Parameters governing the conserved quantities statistics Statistics: + scale_factor_first: 1.0 delta_time: 1.02 # Time between statistics output # Parameters for the hydrodynamics scheme @@ -41,3 +43,38 @@ Cosmology: a_begin: 0.001 a_end: 0.00106638 +# Impose primoridal metallicity +EAGLEChemistry: + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0.0 + init_abundance_Nitrogen: 0.0 + init_abundance_Oxygen: 0.0 + init_abundance_Neon: 0.0 + init_abundance_Magnesium: 0.0 + init_abundance_Silicon: 0.0 + init_abundance_Iron: 0.0 + +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 11.5 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 0.1 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 8000 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 8000 # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +LambdaCooling: + lambda_nH2_cgs: 1e-48 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3]) + cooling_tstep_mult: 1.0 # (Optional) Dimensionless pre-factor for the time-step condition. -- GitLab From 242dda4f172c38746f174dbdfc162a27da9186a7 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Mon, 25 Mar 2019 20:17:23 +0000 Subject: [PATCH 14/79] Changed initial density --- examples/Cooling/CoolingRedshiftDependence/makeIC.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/makeIC.py b/examples/Cooling/CoolingRedshiftDependence/makeIC.py index 489be7636..61b875668 100644 --- a/examples/Cooling/CoolingRedshiftDependence/makeIC.py +++ b/examples/Cooling/CoolingRedshiftDependence/makeIC.py @@ -13,7 +13,7 @@ import h5py # Physics parameters. boxsize = 1.0 * Mpc -physical_density = 1.0 * mh / cm ** 3 +physical_density = 0.1 * mh / cm ** 3 mu_hydrogen = 0.5 # Fully ionised temperature = 1e7 * K gamma = 5.0 / 3.0 @@ -54,6 +54,7 @@ def generate_ics(redshift: float, filename: str, glass_filename: str) -> None: # Leave in physical units; handled by boxsize change. writer.gas.internal_energy = ( np.ones(number_of_particles, dtype=float) + * 3.0 / 2.0 * (temperature * kb) / (mu_hydrogen * mh) ) -- GitLab From 6169996ded76da0c66c3953aab44affe83d28962 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Mon, 25 Mar 2019 20:17:38 +0000 Subject: [PATCH 15/79] Changed to using a data directory --- .../cooling_redshift_dependence_high_z.yml | 9 +++++++-- .../cooling_redshift_dependence_low_z.yml | 17 +++++++++++------ .../cooling_redshift_dependence_no_z.yml | 7 ++++++- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml index e9fb6d995..13ed73554 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml @@ -22,7 +22,7 @@ TimeIntegration: # Parameters governing the snapshots Snapshots: - basename: redshift_dependence_high_z + basename: data/redshift_dependence_high_z delta_time: 1.000122373748838 scale_factor_first: 0.5 compression: 4 @@ -77,4 +77,9 @@ EAGLEEntropyFloor: Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor LambdaCooling: - lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] \ No newline at end of file + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] + +ConstCooling: + cooling_rate: 1. # Cooling rate (du/dt) (internal units) + min_energy: 1. # Minimal internal energy per unit mass (internal units) + cooling_tstep_mult: 1. # Dimensionless pre-factor for the time-step condition \ No newline at end of file diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml index 159a5e3f4..5b336bc4b 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml @@ -1,8 +1,8 @@ # Define the system of units to use internally. InternalUnitSystem: - UnitMass_in_cgs: 1.98848e43 # 10^10 M_sun - UnitLength_in_cgs: 3.08567758e24 # 1 Mpc - UnitVelocity_in_cgs: 1e5 # 1 km/s + UnitMass_in_cgs: 1.98848e33 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e21 # 1 kpc + UnitVelocity_in_cgs: 1 # 1 km/s UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin @@ -22,7 +22,7 @@ TimeIntegration: # Parameters governing the snapshots Snapshots: - basename: redshift_dependence_low_z + basename: data/redshift_dependence_low_z delta_time: 1.0000695206950205 scale_factor_first: 0.99009 compression: 4 @@ -44,7 +44,7 @@ InitialConditions: periodic: 1 # Parameters for the EAGLE chemistry -EAGLEChemistry: # Solar abundances +EAGLEChemistry: # Primordial init_abundance_metal: 0. init_abundance_Hydrogen: 0.752 init_abundance_Helium: 0.248 @@ -77,4 +77,9 @@ EAGLEEntropyFloor: Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor LambdaCooling: - lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] \ No newline at end of file + lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] + +ConstCooling: + cooling_rate: 1. # Cooling rate (du/dt) (internal units) + min_energy: 1. # Minimal internal energy per unit mass (internal units) + cooling_tstep_mult: 1. # Dimensionless pre-factor for the time-step condition diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml index 8b00ca0ac..35242f553 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml @@ -15,7 +15,7 @@ TimeIntegration: # Parameters governing the snapshots Snapshots: - basename: redshift_dependence_no_z + basename: data/redshift_dependence_no_z delta_time: 1.02e-6 compression: 4 @@ -69,3 +69,8 @@ EAGLEEntropyFloor: LambdaCooling: lambda_nH2_cgs: 2.13744785e-23 # Cooling rate divided by square Hydrogen number density (in cgs units [erg * s^-1 * cm^3] + +ConstCooling: + cooling_rate: 1. # Cooling rate (du/dt) (internal units) + min_energy: 1. # Minimal internal energy per unit mass (internal units) + cooling_tstep_mult: 1. # Dimensionless pre-factor for the time-step condition \ No newline at end of file -- GitLab From 1fbf625795efe2ced4d6789e1e7b7a62a47a6fef Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Mon, 25 Mar 2019 20:18:34 +0000 Subject: [PATCH 16/79] Moved to using data directory --- examples/Cooling/CoolingRedshiftDependence/run.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/run.sh b/examples/Cooling/CoolingRedshiftDependence/run.sh index ba399811e..c9bf2aea7 100755 --- a/examples/Cooling/CoolingRedshiftDependence/run.sh +++ b/examples/Cooling/CoolingRedshiftDependence/run.sh @@ -14,16 +14,18 @@ then python3 makeIC.py fi -swift_location="../../../build/gadget-const-lambda/examples/swift" +swift_location="../../swift" -rm redshift_dependence_*_z_*.hdf5 +rm data/redshift_dependence_*_z_*.hdf5 + +mkdir data # Run SWIFT -$swift_location --hydro --cosmology --cooling --threads=4 cooling_redshift_dependence_high_z.yml 2>&1 | tee output_high.log +$swift_location --hydro --cosmology --cooling --limiter --threads=4 cooling_redshift_dependence_high_z.yml 2>&1 | tee output_high.log mv timesteps_4.txt timesteps_high.txt -$swift_location --hydro --cosmology --cooling --threads=4 cooling_redshift_dependence_low_z.yml 2>&1 | tee output_low.log +$swift_location --hydro --cosmology --cooling --limiter --threads=4 cooling_redshift_dependence_low_z.yml 2>&1 | tee output_low.log mv timesteps_4.txt timesteps_low.txt -$swift_location --hydro --cooling --threads=4 cooling_redshift_dependence_no_z.yml 2>&1 | tee output_no.log +$swift_location --hydro --cooling --limiter --threads=4 cooling_redshift_dependence_no_z.yml 2>&1 | tee output_no.log mv timesteps_4.txt timesteps_no.txt python3 plotSolution.py -- GitLab From 61a81fb1def2b8b1a685f046a7f86b596b2f840a Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Mon, 25 Mar 2019 20:18:48 +0000 Subject: [PATCH 17/79] Added plot of diffusion and viscosity parameters. --- .../HydroTests/SedovBlast_3D/plotSolution.py | 48 ++++++++++++++++--- .../HydroTests/SodShock_3D/plotSolution.py | 46 +++++++++++++++--- 2 files changed, 82 insertions(+), 12 deletions(-) diff --git a/examples/HydroTests/SedovBlast_3D/plotSolution.py b/examples/HydroTests/SedovBlast_3D/plotSolution.py index ad34695d3..a87e3cd24 100644 --- a/examples/HydroTests/SedovBlast_3D/plotSolution.py +++ b/examples/HydroTests/SedovBlast_3D/plotSolution.py @@ -86,6 +86,18 @@ S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] rho = sim["/PartType0/Density"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + # Bin te data r_bin_edge = np.arange(0., 0.5, 0.01) r_bin = 0.5*(r_bin_edge[1:] + r_bin_edge[:-1]) @@ -105,6 +117,16 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(x, diffusion, statistic='mean', bins=r_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(x, diffusion**2, statistic='mean', bins=r_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(x, viscosity, statistic='mean', bins=r_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(x, viscosity**2, statistic='mean', bins=r_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) + # Now, work our the solution.... @@ -274,13 +296,27 @@ ylim(-2, 22) # Entropy profile --------------------------------- subplot(235) -plot(r, S, '.', color='r', ms=0.5, alpha=0.2) -plot(r_s, s_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) -xlabel("${\\rm{Radius}}~r$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) xlim(0, 1.3 * r_shock) -ylim(-5, 50) +xlabel("${\\rm{Radius}}~r$", labelpad=0) + + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(x, diffusion, ".", color='r', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_diff_bin, yerr=alpha_diff_sigma_bin, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion") + + if plot_viscosity: + plot(x, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(r, S, '.', color='r', ms=0.5, alpha=0.2) + plot(r_s, s_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(-5, 50) # Information ------------------------------------- subplot(236, frameon=False) diff --git a/examples/HydroTests/SodShock_3D/plotSolution.py b/examples/HydroTests/SodShock_3D/plotSolution.py index 6da7193bc..7cec619ef 100644 --- a/examples/HydroTests/SodShock_3D/plotSolution.py +++ b/examples/HydroTests/SodShock_3D/plotSolution.py @@ -84,6 +84,18 @@ S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] rho = sim["/PartType0/Density"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + x_min = -1. x_max = 1. x += x_min @@ -108,6 +120,15 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(x, diffusion, statistic='mean', bins=x_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(x, diffusion**2, statistic='mean', bins=x_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(x, viscosity, statistic='mean', bins=x_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(x, viscosity**2, statistic='mean', bins=x_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) # Analytic solution c_L = sqrt(gas_gamma * P_L / rho_L) # Speed of the rarefaction wave @@ -282,13 +303,26 @@ ylim(0.8, 2.2) # Entropy profile --------------------------------- subplot(235) -plot(x, S, '.', color='r', ms=0.5, alpha=0.2) -plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) -xlabel("${\\rm{Position}}~x$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) xlim(-0.5, 0.5) -ylim(0.8, 3.8) +xlabel("${\\rm{Position}}~x$", labelpad=0) + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(x, diffusion, ".", color='r', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_diff_bin, yerr=alpha_diff_sigma_bin, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion") + + if plot_viscosity: + plot(x, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(x, S, '.', color='r', ms=0.5, alpha=0.2) + plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(0.8, 3.8) # Information ------------------------------------- subplot(236, frameon=False) -- GitLab From 0eaff002fd3ae36d1b6d46ee49de0aac7f0b49c6 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Mon, 25 Mar 2019 20:19:30 +0000 Subject: [PATCH 18/79] Added steps to plotSolution --- .../CoolingRedshiftDependence/plotSolution.py | 34 +++++++++++++++---- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py index d8a4ddc0f..d7f4fe3b7 100644 --- a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py +++ b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py @@ -45,7 +45,7 @@ def get_data(handle: float, n_snaps: int): densities = [] for snap in range(n_snaps): - data = load(f"{handle}_{snap:04d}.hdf5") + data = load(f"data/{handle}_{snap:04d}.hdf5") if snap == 0: t0 = data.metadata.t.to(Myr).value @@ -57,7 +57,17 @@ def get_data(handle: float, n_snaps: int): return times, temps, densities -def plot_single_data(handle: str, n_snaps: int, label: str, ax: plt.axes): +def get_n_steps(timesteps_filename: str) -> int: + """ + Reads the number of steps from the timesteps file. + """ + + data = np.genfromtxt(timesteps_filename) + + return int(data[-1][0]) + + +def plot_single_data(handle: str, n_snaps: int, label: str, ax: plt.axes, n_steps:int = 0): """ Takes the a single simulation and plots it on the axes. """ @@ -73,7 +83,7 @@ def plot_single_data(handle: str, n_snaps: int, label: str, ax: plt.axes): ax[1].plot( data[0], data[2], - label=label, + label=f"Steps: {n_steps}", marker="o", ms=2 ) @@ -82,17 +92,26 @@ def plot_single_data(handle: str, n_snaps: int, label: str, ax: plt.axes): return -def make_plot(handles, names, n_snaps=100): +def make_plot(handles, names, timestep_names, n_snaps=100): """ Makes the whole plot and returns the fig, ax objects. """ fig, ax = setup_axes() - for handle, name in zip(handles, names): - plot_single_data(handle, n_snaps, name, ax) + for handle, name, timestep_name in zip(handles, names, timestep_names): + try: + n_steps = get_n_steps(timestep_name) + except: + n_steps = "Unknown" + + try: + plot_single_data(handle, n_snaps, name, ax, n_steps=n_steps) + except: + pass ax[0].legend() + ax[1].legend() return fig, ax @@ -104,8 +123,9 @@ if __name__ == "__main__": handles = ["redshift_dependence_no_z", "redshift_dependence_low_z", "redshift_dependence_high_z"] names = ["No Cosmology", "Low Redshift ($z=0.01$)", "High Redshift ($z=1$)"] + timestep_names = ["timesteps_no.txt", "timesteps_low.txt", "timesteps_high.txt"] - fig, ax = make_plot(handles, names) + fig, ax = make_plot(handles, names, timestep_names) fig.savefig("redshift_dependence.png", dpi=300) -- GitLab From fb670c26086d5622201a7f593313ccd41db929ef Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Tue, 26 Mar 2019 11:11:23 +0000 Subject: [PATCH 19/79] Used more physically meaningful variable names in anarchy-pu sph --- src/hydro/AnarchyPU/hydro.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 0403608fe..998c00996 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -218,6 +218,7 @@ hydro_get_comoving_soundspeed(const struct part *restrict p) { /* Compute the sound speed -- see theory section for justification */ /* IDEAL GAS ONLY -- P-U does not work with generic EoS. */ + const float square_rooted = sqrtf(hydro_gamma * p->pressure_bar / p->rho); return square_rooted; @@ -233,7 +234,7 @@ __attribute__((always_inline)) INLINE static float hydro_get_physical_soundspeed(const struct part *restrict p, const struct cosmology *cosmo) { - return cosmo->a_factor_sound_speed * p->force.soundspeed; + return cosmo->a_factor_sound_speed * hydro_get_comoving_soundspeed(p); } /** @@ -703,13 +704,14 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float h_physical = p->h * cosmo->a; const float v_sig_physical = p->viscosity.v_sig / a_fac_soundspeed; + const float soundspeed_physical = hydro_get_physical_soundspeed(p, cosmo); const float div_v_physical = (p->viscosity.div_v - cosmo->H * hydro_dimension) * a2; const float div_v_prev_physical = (p->viscosity.div_v_previous_step - cosmo->H * hydro_dimension) * a2; const float dt_alpha_physical = dt_alpha / a2; - const float tau = h_physical / (2.f * v_sig_physical * hydro_props->viscosity.length); + const float sound_crossing_time_inverse = soundspeed_physical / h_physical; /* Construct time differential of div.v implicitly following the ANARCHY spec */ @@ -733,7 +735,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->viscosity.alpha = alpha_loc; } else { /* Integrate the alpha forward in time to decay back to alpha = 0 */ - const float alpha_dt = (alpha_loc - p->viscosity.alpha) / tau; + const float alpha_dt = (alpha_loc - p->viscosity.alpha) * sound_crossing_time_inverse * hydro_props->viscosity.length; /* Finally, we can update the actual value of the alpha */ p->viscosity.alpha += alpha_dt * dt_alpha_physical; @@ -748,6 +750,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Now for the diffusive alpha */ + const float diffusion_timescale_physical_inverse = v_sig_physical / h_physical; + const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ /* alpha_diff_dt is cosmology-less */ @@ -758,7 +762,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Decay term: not documented in Schaller+ 2015 but was present * in the original EAGLE code and in Schaye+ 2015 */ alpha_diff_dt -= - (p->diffusion.alpha - hydro_props->diffusion.alpha_min) / tau; + (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * diffusion_timescale_physical_inverse; float new_diffusion_alpha = p->diffusion.alpha; new_diffusion_alpha += alpha_diff_dt * dt_alpha_physical; -- GitLab From 9a1a9b600d72d6106489561881620e4ab061c8a6 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Tue, 26 Mar 2019 12:52:00 +0000 Subject: [PATCH 20/79] Updated to use "correct" alpha --- src/hydro/AnarchyPU/hydro.h | 16 ++++++++++------ src/hydro/AnarchyPU/hydro_iact.h | 12 ++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 998c00996..cba932b89 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -735,16 +735,20 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->viscosity.alpha = alpha_loc; } else { /* Integrate the alpha forward in time to decay back to alpha = 0 */ - const float alpha_dt = (alpha_loc - p->viscosity.alpha) * sound_crossing_time_inverse * hydro_props->viscosity.length; - - /* Finally, we can update the actual value of the alpha */ - p->viscosity.alpha += alpha_dt * dt_alpha_physical; + p->viscosity.alpha = + alpha_loc + (p->viscosity.alpha - alpha_loc) * + expf(-dt_alpha_physical * sound_crossing_time_inverse * + hydro_props->viscosity.length); } if (p->viscosity.alpha < hydro_props->viscosity.alpha_min) { p->viscosity.alpha = hydro_props->viscosity.alpha_min; } + if (p->viscosity.alpha > hydro_props->viscosity.alpha_max) { + p->viscosity.alpha = hydro_props->viscosity.alpha_max; + } + /* Set our old div_v to the one for the next loop */ p->viscosity.div_v_previous_step = p->viscosity.div_v; @@ -761,8 +765,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( hydro_props->diffusion.beta * p->h * p->diffusion.laplace_u / sqrt_u; /* Decay term: not documented in Schaller+ 2015 but was present * in the original EAGLE code and in Schaye+ 2015 */ - alpha_diff_dt -= - (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * diffusion_timescale_physical_inverse; + alpha_diff_dt -= (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * + diffusion_timescale_physical_inverse; float new_diffusion_alpha = p->diffusion.alpha; new_diffusion_alpha += alpha_diff_dt * dt_alpha_physical; diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index c214db3b0..870f30acd 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -204,10 +204,10 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); + const float dv_dx_factor = min(0, dv_dx); const float new_v_sig = - pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor; + 0.5 * (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -257,10 +257,10 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); + const float dv_dx_factor = min(0, dv_dx); const float new_v_sig = - pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor; + 0.5 * (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -353,7 +353,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float rho_ij = rhoi + rhoj; const float alpha = pi->viscosity.alpha + pj->viscosity.alpha; const float visc = - -0.25f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; + -1.f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; /* Convolve with the kernel */ const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; @@ -484,7 +484,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float rho_ij = rhoi + rhoj; const float alpha = pi->viscosity.alpha + pj->viscosity.alpha; const float visc = - -0.25f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; + -1.f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; /* Convolve with the kernel */ const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; -- GitLab From 75ba2e13c06960b5d0eb239c0b22b27304c037eb Mon Sep 17 00:00:00 2001 From: JBorrow Date: Wed, 27 Mar 2019 16:02:35 +0000 Subject: [PATCH 21/79] Added viscosity coefficients to plotting Gresho --- .../GreshoVortex_3D/plotSolution.py | 53 ++++++++++++++++--- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/examples/HydroTests/GreshoVortex_3D/plotSolution.py b/examples/HydroTests/GreshoVortex_3D/plotSolution.py index 8fddf148b..545440c99 100644 --- a/examples/HydroTests/GreshoVortex_3D/plotSolution.py +++ b/examples/HydroTests/GreshoVortex_3D/plotSolution.py @@ -108,6 +108,18 @@ u = sim["/PartType0/InternalEnergy"][:] S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + # Bin te data r_bin_edge = np.arange(0., 1., 0.02) r_bin = 0.5*(r_bin_edge[1:] + r_bin_edge[:-1]) @@ -127,6 +139,15 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(r, diffusion, statistic='mean', bins=r_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(r, diffusion**2, statistic='mean', bins=r_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(r, viscosity, statistic='mean', bins=r_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(r, viscosity**2, statistic='mean', bins=r_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) # Plot the interesting quantities figure() @@ -188,16 +209,32 @@ ylim(7.3, 9.1) # Radial entropy profile -------------------------------- subplot(235) - -plot(r, S, '.', color='r', ms=0.5) -plot(solution_r, solution_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) -plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) -plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) xlabel("${\\rm{Radius}}~r$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) + xlim(0, R_max) -ylim(4.9 + P0, P0 + 6.1) + +xlabel("${\\rm{Radius}}~r$", labelpad=0) + + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(r, diffusion, ".", color='r', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_diff_bin, yerr=alpha_diff_sigma_bin, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion") + + if plot_viscosity: + plot(r, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(r_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(r, S, '.', color='r', ms=0.5) + plot(solution_r, solution_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(r_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + plot([0.2, 0.2], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) + plot([0.4, 0.4], [-100, 100], ':', color='k', alpha=0.4, lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(4.9 + P0, P0 + 6.1) # Image -------------------------------------------------- #subplot(234) -- GitLab From 48f4f09f9d36b3cd49d74e1edce15e1c54238c47 Mon Sep 17 00:00:00 2001 From: JBorrow Date: Wed, 27 Mar 2019 16:03:12 +0000 Subject: [PATCH 22/79] Fixed bug with Sedov plotting --- .../HydroTests/SedovBlast_3D/plotSolution.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/HydroTests/SedovBlast_3D/plotSolution.py b/examples/HydroTests/SedovBlast_3D/plotSolution.py index a87e3cd24..b0f2e0844 100644 --- a/examples/HydroTests/SedovBlast_3D/plotSolution.py +++ b/examples/HydroTests/SedovBlast_3D/plotSolution.py @@ -24,7 +24,7 @@ # Parameters rho_0 = 1. # Background Density P_0 = 1.e-6 # Background Pressure -E_0 = 1. # Energy of the explosion +E_0 = 1.0 # Energy of the explosion gas_gamma = 5./3. # Gas polytropic index @@ -118,13 +118,13 @@ S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) if plot_diffusion: - alpha_diff_bin,_,_ = stats.binned_statistic(x, diffusion, statistic='mean', bins=r_bin_edge) - alpha2_diff_bin,_,_ = stats.binned_statistic(x, diffusion**2, statistic='mean', bins=r_bin_edge) + alpha_diff_bin,_,_ = stats.binned_statistic(r, diffusion, statistic='mean', bins=r_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(r, diffusion**2, statistic='mean', bins=r_bin_edge) alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) if plot_viscosity: - alpha_visc_bin,_,_ = stats.binned_statistic(x, viscosity, statistic='mean', bins=r_bin_edge) - alpha2_visc_bin,_,_ = stats.binned_statistic(x, viscosity**2, statistic='mean', bins=r_bin_edge) + alpha_visc_bin,_,_ = stats.binned_statistic(r, viscosity, statistic='mean', bins=r_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(r, viscosity**2, statistic='mean', bins=r_bin_edge) alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) @@ -296,17 +296,16 @@ ylim(-2, 22) # Entropy profile --------------------------------- subplot(235) -xlim(0, 1.3 * r_shock) xlabel("${\\rm{Radius}}~r$", labelpad=0) if plot_diffusion or plot_viscosity: if plot_diffusion: - plot(x, diffusion, ".", color='r', ms=0.5, alpha=0.2) + plot(r, diffusion, ".", color='r', ms=0.5, alpha=0.2) errorbar(r_bin, alpha_diff_bin, yerr=alpha_diff_sigma_bin, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion") if plot_viscosity: - plot(x, viscosity, ".", color='g', ms=0.5, alpha=0.2) + plot(r, viscosity, ".", color='g', ms=0.5, alpha=0.2) errorbar(r_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) @@ -318,6 +317,7 @@ else: ylabel("${\\rm{Entropy}}~S$", labelpad=0) ylim(-5, 50) +xlim(0, 1.3 * r_shock) # Information ------------------------------------- subplot(236, frameon=False) -- GitLab From 6b4d59acea7b6e3e4468e875ef0dc8642aba8913 Mon Sep 17 00:00:00 2001 From: JBorrow Date: Wed, 27 Mar 2019 16:04:58 +0000 Subject: [PATCH 23/79] Minor bugfixes in ANARCHY scheme --- src/hydro/AnarchyPU/hydro.h | 8 +++++--- src/hydro/AnarchyPU/hydro_iact.h | 24 ++++++++++++++---------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index cba932b89..1fc4e9d8e 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -218,7 +218,7 @@ hydro_get_comoving_soundspeed(const struct part *restrict p) { /* Compute the sound speed -- see theory section for justification */ /* IDEAL GAS ONLY -- P-U does not work with generic EoS. */ - + const float square_rooted = sqrtf(hydro_gamma * p->pressure_bar / p->rho); return square_rooted; @@ -702,7 +702,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* We integrate the whole AV scheme in physical units as cancelling the cosmology terms is just a nightmare, especially for non-standard gas_gamma. */ - const float h_physical = p->h * cosmo->a; + /* We use in this function that h is the radius of support */ + const float h_physical = p->h * cosmo->a * kernel_gamma; const float v_sig_physical = p->viscosity.v_sig / a_fac_soundspeed; const float soundspeed_physical = hydro_get_physical_soundspeed(p, cosmo); const float div_v_physical = @@ -723,7 +724,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Construct the source term for the AV; if shock detected this is _positive_ * as div_v_dt should be _negative_ before the shock hits */ const float S = h_physical * h_physical * max(0.f, -1.f * div_v_dt); - const float v_sig_square = v_sig_physical * v_sig_physical; + /* 0.25 factor comes from our definition of v_sig */ + const float v_sig_square = 0.25 * v_sig_physical * v_sig_physical; /* Calculate the current appropriate value of the AV based on the above */ /* Note this is v_sig_physical squared, not comoving */ diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index 870f30acd..a7fc22b79 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -200,14 +200,17 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( /* We need to construct the maximal signal velocity between our particle * and all of it's neighbours */ + const float r = sqrtf(r2); + const float r_inv = 1.f / r; + const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, dv_dx); + const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); const float new_v_sig = - 0.5 * (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor; + pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor * r_inv; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -217,14 +220,13 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( /* Need to get some kernel values F_ij = wi_dx */ float wi, wi_dx, wj, wj_dx; - const float r = sqrtf(r2); const float ui = r / hi; const float uj = r / hj; kernel_deval(ui, &wi, &wi_dx); kernel_deval(uj, &wj, &wj_dx); - const float delta_u_factor = (pi->u - pj->u) / r; + const float delta_u_factor = (pi->u - pj->u) * r_inv; pi->diffusion.laplace_u += pj->mass * delta_u_factor * wi_dx / pj->rho; pj->diffusion.laplace_u -= pi->mass * delta_u_factor * wj_dx / pi->rho; } @@ -253,14 +255,17 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( /* We need to construct the maximal signal velocity between our particle * and all of it's neighbours */ + const float r = sqrtf(r2); + const float r_inv = 1.f / r; + const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, dv_dx); + const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); const float new_v_sig = - 0.5 * (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor; + pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor * r_inv; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -269,12 +274,11 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( /* Need to get some kernel values F_ij = wi_dx */ float wi, wi_dx; - const float r = sqrtf(r2); const float ui = r / hi; kernel_deval(ui, &wi, &wi_dx); - const float delta_u_factor = (pi->u - pj->u) / r; + const float delta_u_factor = (pi->u - pj->u) * r_inv; pi->diffusion.laplace_u += pj->mass * delta_u_factor * wi_dx / pj->rho; } @@ -385,7 +389,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( wj_dr * dvdr * r_inv; /* Viscosity term */ - const float visc_du_term = 0.5f * visc_acc_term * dvdr_Hubble; + const float visc_du_term = 0.5 * visc_acc_term * dvdr_Hubble; /* Diffusion term */ const float v_diff = @@ -509,7 +513,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( wi_dr * dvdr * r_inv; /* Viscosity term */ - const float visc_du_term = 0.5f * visc_acc_term * dvdr_Hubble; + const float visc_du_term = 0.5 * visc_acc_term * dvdr_Hubble; /* Diffusion term */ const float v_diff = -- GitLab From 469fb7b5126e7b736c167df9fb453682f3dca5e0 Mon Sep 17 00:00:00 2001 From: JBorrow Date: Wed, 27 Mar 2019 16:05:48 +0000 Subject: [PATCH 24/79] Updated ANARCHY defaults --- src/hydro_properties.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hydro_properties.c b/src/hydro_properties.c index ff578aec1..9edd72f77 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -50,7 +50,7 @@ /* This nasty #ifdef is only temporary until we separate the viscosity * and hydro components. If it is not removed by July 2019, shout at JB. */ #define hydro_props_default_viscosity_alpha_min \ - 0.01f /* values taken from Schaller+ 2015 */ + 0.1f /* values NOT the same as Schaller+ 2015 */ #define hydro_props_default_viscosity_alpha_max \ 2.0f /* values taken from Schaller+ 2015 */ #define hydro_props_default_viscosity_length \ -- GitLab From 77ba30bd19c9765baef03b66b6ca7a93cdb917eb Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 27 Mar 2019 17:47:43 +0000 Subject: [PATCH 25/79] Attempting to fix soundspeed --- src/hydro/AnarchyPU/hydro.h | 3 +-- src/hydro/AnarchyPU/hydro_iact.h | 24 ++++++++++++++++++++---- src/hydro_properties.c | 3 +++ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 1fc4e9d8e..dbd78eee5 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -697,14 +697,13 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Timescale for decay */ const float a2 = cosmo->a * cosmo->a; - const float a_fac_soundspeed = cosmo->a_factor_sound_speed; /* We integrate the whole AV scheme in physical units as cancelling the cosmology terms is just a nightmare, especially for non-standard gas_gamma. */ /* We use in this function that h is the radius of support */ const float h_physical = p->h * cosmo->a * kernel_gamma; - const float v_sig_physical = p->viscosity.v_sig / a_fac_soundspeed; + const float v_sig_physical = p->viscosity.v_sig / cosmo->a_factor_sound_speed; const float soundspeed_physical = hydro_get_physical_soundspeed(p, cosmo); const float div_v_physical = (p->viscosity.div_v - cosmo->H * hydro_dimension) * a2; diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index a7fc22b79..887783be4 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -203,14 +203,22 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( const float r = sqrtf(r2); const float r_inv = 1.f / r; + /* Cosmology terms for the signal velocity */ + const float fac_mu = pow_three_gamma_minus_five_over_two(a); + const float a2_Hubble = a * a * H; + const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); + /* Add Hubble flow */ + const float dv_dx_Hubble = dv_dx + a2_Hubble * r2; + + const float dv_dx_factor = min(0, const_viscosity_beta * fac_mu * dv_dx_Hubble); + /* Store this as a _physical_ variable because of weird combinations of a-factors */ const float new_v_sig = - pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor * r_inv; + (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor * r_inv; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -257,15 +265,23 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( const float r = sqrtf(r2); const float r_inv = 1.f / r; + + /* Cosmology terms for the signal velocity */ + const float fac_mu = pow_three_gamma_minus_five_over_two(a); + const float a2_Hubble = a * a * H; const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; - const float dv_dx_factor = min(0, const_viscosity_beta * dv_dx); + /* Add Hubble flow */ + const float dv_dx_Hubble = dv_dx + a2_Hubble * r2; + + const float dv_dx_factor = min(0, const_viscosity_beta * fac_mu * dv_dx_Hubble); + /* Store this as a _physical_ variable because of weird combinations of a-factors */ const float new_v_sig = - pi->force.soundspeed + pj->force.soundspeed - dv_dx_factor * r_inv; + (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor * r_inv; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); diff --git a/src/hydro_properties.c b/src/hydro_properties.c index 9edd72f77..7d2b03be7 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -49,6 +49,9 @@ #ifdef ANARCHY_PU_SPH /* This nasty #ifdef is only temporary until we separate the viscosity * and hydro components. If it is not removed by July 2019, shout at JB. */ +#undef hydro_props_default_viscosity_alpha +#define hydro_props_default_viscosity_alpha \ + 0.1f /* Use a very low initial AV paramater for hydrodynamics tests */ #define hydro_props_default_viscosity_alpha_min \ 0.1f /* values NOT the same as Schaller+ 2015 */ #define hydro_props_default_viscosity_alpha_max \ -- GitLab From e250e7988baffb0555f93b13f4f53afbdefa5f85 Mon Sep 17 00:00:00 2001 From: JBorrow Date: Thu, 28 Mar 2019 21:34:31 +0000 Subject: [PATCH 26/79] Slowly converging on cosmology fixes --- src/hydro/AnarchyPU/hydro.h | 34 +++++++++----------------------- src/hydro/AnarchyPU/hydro_iact.h | 30 +++++++++++++++++----------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index dbd78eee5..26845d928 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -694,22 +694,10 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Here we need to update the artificial viscosity */ - /* Timescale for decay */ - - const float a2 = cosmo->a * cosmo->a; - - /* We integrate the whole AV scheme in physical units as cancelling the cosmology terms - is just a nightmare, especially for non-standard gas_gamma. */ - /* We use in this function that h is the radius of support */ const float h_physical = p->h * cosmo->a * kernel_gamma; - const float v_sig_physical = p->viscosity.v_sig / cosmo->a_factor_sound_speed; + const float v_sig_physical = p->viscosity.v_sig * cosmo->a_factor_sound_speed; const float soundspeed_physical = hydro_get_physical_soundspeed(p, cosmo); - const float div_v_physical = - (p->viscosity.div_v - cosmo->H * hydro_dimension) * a2; - const float div_v_prev_physical = - (p->viscosity.div_v_previous_step - cosmo->H * hydro_dimension) * a2; - const float dt_alpha_physical = dt_alpha / a2; const float sound_crossing_time_inverse = soundspeed_physical / h_physical; @@ -718,16 +706,17 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( float div_v_dt = dt_alpha == 0.f ? 0.f - : (div_v_physical - div_v_prev_physical) / dt_alpha_physical; + : (p->viscosity.div_v - p->viscosity.div_v_previous_step) / dt_alpha; /* Construct the source term for the AV; if shock detected this is _positive_ * as div_v_dt should be _negative_ before the shock hits */ const float S = h_physical * h_physical * max(0.f, -1.f * div_v_dt); - /* 0.25 factor comes from our definition of v_sig */ + /* 0.25 factor comes from our definition of v_sig (sum of soundspeeds rather + * than mean). */ + /* Note this is v_sig_physical squared, not comoving */ const float v_sig_square = 0.25 * v_sig_physical * v_sig_physical; /* Calculate the current appropriate value of the AV based on the above */ - /* Note this is v_sig_physical squared, not comoving */ const float alpha_loc = hydro_props->viscosity.alpha_max * S / (v_sig_square + S); @@ -735,10 +724,10 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Reset the value of alpha to the appropriate value */ p->viscosity.alpha = alpha_loc; } else { - /* Integrate the alpha forward in time to decay back to alpha = 0 */ + /* Integrate the alpha forward in time to decay back to alpha = alpha_loc */ p->viscosity.alpha = alpha_loc + (p->viscosity.alpha - alpha_loc) * - expf(-dt_alpha_physical * sound_crossing_time_inverse * + expf(-dt_alpha * sound_crossing_time_inverse * hydro_props->viscosity.length); } @@ -746,10 +735,6 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( p->viscosity.alpha = hydro_props->viscosity.alpha_min; } - if (p->viscosity.alpha > hydro_props->viscosity.alpha_max) { - p->viscosity.alpha = hydro_props->viscosity.alpha_max; - } - /* Set our old div_v to the one for the next loop */ p->viscosity.div_v_previous_step = p->viscosity.div_v; @@ -759,18 +744,17 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ - /* alpha_diff_dt is cosmology-less */ /* Evolution term: following Schaller+ 2015. This is actually cosmology-less and so requires no conversion to physical. */ float alpha_diff_dt = - hydro_props->diffusion.beta * p->h * p->diffusion.laplace_u / sqrt_u; + hydro_props->diffusion.beta * h_physical * cosmo->a_factor_sound_speed * p->diffusion.laplace_u / sqrt_u; /* Decay term: not documented in Schaller+ 2015 but was present * in the original EAGLE code and in Schaye+ 2015 */ alpha_diff_dt -= (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * diffusion_timescale_physical_inverse; float new_diffusion_alpha = p->diffusion.alpha; - new_diffusion_alpha += alpha_diff_dt * dt_alpha_physical; + new_diffusion_alpha += alpha_diff_dt * dt_alpha / (cosmo->a * cosmo->a); /* Consistency checks to ensure min < alpha < max */ if (new_diffusion_alpha > hydro_props->diffusion.alpha_max) { diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index 887783be4..6d49b8d40 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -202,23 +202,26 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( const float r = sqrtf(r2); const float r_inv = 1.f / r; + const float ci = pi->force.soundspeed; + const float cj = pi->force.soundspeed; /* Cosmology terms for the signal velocity */ const float fac_mu = pow_three_gamma_minus_five_over_two(a); const float a2_Hubble = a * a * H; - const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + + const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; /* Add Hubble flow */ - const float dv_dx_Hubble = dv_dx + a2_Hubble * r2; - const float dv_dx_factor = min(0, const_viscosity_beta * fac_mu * dv_dx_Hubble); + const float dvdr_Hubble = dvdr + a2_Hubble * r2; + /* Are the particles moving towards each others ? */ + const float omega_ij = min(dvdr_Hubble, 0.f); + const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ - /* Store this as a _physical_ variable because of weird combinations of a-factors */ - const float new_v_sig = - (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor * r_inv; + /* Signal velocity */ + const float new_v_sig = ci + cj - const_viscosity_beta * mu_ij; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); @@ -265,23 +268,26 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( const float r = sqrtf(r2); const float r_inv = 1.f / r; + const float ci = pi->force.soundspeed; + const float cj = pi->force.soundspeed; /* Cosmology terms for the signal velocity */ const float fac_mu = pow_three_gamma_minus_five_over_two(a); const float a2_Hubble = a * a * H; - const float dv_dx = (pi->v[0] - pj->v[0]) * dx[0] + + const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + (pi->v[1] - pj->v[1]) * dx[1] + (pi->v[2] - pj->v[2]) * dx[2]; /* Add Hubble flow */ - const float dv_dx_Hubble = dv_dx + a2_Hubble * r2; - const float dv_dx_factor = min(0, const_viscosity_beta * fac_mu * dv_dx_Hubble); + const float dvdr_Hubble = dvdr + a2_Hubble * r2; + /* Are the particles moving towards each others ? */ + const float omega_ij = min(dvdr_Hubble, 0.f); + const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ - /* Store this as a _physical_ variable because of weird combinations of a-factors */ - const float new_v_sig = - (pi->force.soundspeed + pj->force.soundspeed) - dv_dx_factor * r_inv; + /* Signal velocity */ + const float new_v_sig = ci + cj - const_viscosity_beta * mu_ij; /* Update if we need to */ pi->viscosity.v_sig = max(pi->viscosity.v_sig, new_v_sig); -- GitLab From 8b6871f0d6c0e71ac6485533d87eabed0758e526 Mon Sep 17 00:00:00 2001 From: JBorrow Date: Fri, 29 Mar 2019 17:15:37 +0000 Subject: [PATCH 27/79] Fixes to the diffusion cosmology dependence. --- src/hydro/AnarchyPU/hydro.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 26845d928..d4a86085e 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -747,14 +747,14 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Evolution term: following Schaller+ 2015. This is actually cosmology-less and so requires no conversion to physical. */ float alpha_diff_dt = - hydro_props->diffusion.beta * h_physical * cosmo->a_factor_sound_speed * p->diffusion.laplace_u / sqrt_u; + hydro_props->diffusion.beta * h_physical * p->diffusion.laplace_u * cosmo->a_factor_sound_speed / (sqrt_u * cosmo->a * cosmo->a); /* Decay term: not documented in Schaller+ 2015 but was present * in the original EAGLE code and in Schaye+ 2015 */ alpha_diff_dt -= (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * diffusion_timescale_physical_inverse; float new_diffusion_alpha = p->diffusion.alpha; - new_diffusion_alpha += alpha_diff_dt * dt_alpha / (cosmo->a * cosmo->a); + new_diffusion_alpha += alpha_diff_dt * dt_alpha; /* Consistency checks to ensure min < alpha < max */ if (new_diffusion_alpha > hydro_props->diffusion.alpha_max) { -- GitLab From 356bd46925ca54148a70995e9e8764747a2b1d6c Mon Sep 17 00:00:00 2001 From: JBorrow Date: Fri, 29 Mar 2019 17:16:03 +0000 Subject: [PATCH 28/79] Plotted 100x diffusion coefficient to fit both nicely on page. --- .../ComovingSodShock_3D/plotSolution.py | 47 ++++++++++++++++--- 1 file changed, 40 insertions(+), 7 deletions(-) diff --git a/examples/Cosmology/ComovingSodShock_3D/plotSolution.py b/examples/Cosmology/ComovingSodShock_3D/plotSolution.py index f05a385e8..d85f4be9a 100644 --- a/examples/Cosmology/ComovingSodShock_3D/plotSolution.py +++ b/examples/Cosmology/ComovingSodShock_3D/plotSolution.py @@ -88,6 +88,18 @@ S = sim["/PartType0/Entropy"][:] P = sim["/PartType0/Pressure"][:] rho = sim["/PartType0/Density"][:] +try: + diffusion = sim["/PartType0/Diffusion"][:] + plot_diffusion = True +except: + plot_diffusion = False + +try: + viscosity = sim["/PartType0/Viscosity"][:] + plot_viscosity = True +except: + plot_viscosity = False + x_min = -1. x_max = 1. x += x_min @@ -112,6 +124,15 @@ P_sigma_bin = np.sqrt(P2_bin - P_bin**2) S_sigma_bin = np.sqrt(S2_bin - S_bin**2) u_sigma_bin = np.sqrt(u2_bin - u_bin**2) +if plot_diffusion: + alpha_diff_bin,_,_ = stats.binned_statistic(x, diffusion, statistic='mean', bins=x_bin_edge) + alpha2_diff_bin,_,_ = stats.binned_statistic(x, diffusion**2, statistic='mean', bins=x_bin_edge) + alpha_diff_sigma_bin = np.sqrt(alpha2_diff_bin - alpha_diff_bin**2) + +if plot_viscosity: + alpha_visc_bin,_,_ = stats.binned_statistic(x, viscosity, statistic='mean', bins=x_bin_edge) + alpha2_visc_bin,_,_ = stats.binned_statistic(x, viscosity**2, statistic='mean', bins=x_bin_edge) + alpha_visc_sigma_bin = np.sqrt(alpha2_visc_bin - alpha_visc_bin**2) # Analytic solution c_L = sqrt(gas_gamma * P_L / rho_L) # Speed of the rarefaction wave @@ -285,13 +306,26 @@ ylim(0.8, 2.2) # Entropy profile --------------------------------- subplot(235) -plot(x, S, '.', color='r', ms=0.5, alpha=0.2) -plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) -errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) -xlabel("${\\rm{Position}}~x$", labelpad=0) -ylabel("${\\rm{Entropy}}~S$", labelpad=0) xlim(-0.5, 0.5) -ylim(0.8, 3.8) +xlabel("${\\rm{Position}}~x$", labelpad=0) + +if plot_diffusion or plot_viscosity: + if plot_diffusion: + plot(x, diffusion * 100, ".", color='r', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_diff_bin * 100, yerr=alpha_diff_sigma_bin * 100, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion (100x)") + + if plot_viscosity: + plot(x, viscosity, ".", color='g', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_visc_bin, yerr=alpha_visc_sigma_bin, fmt=".", ms=8.0, color='y', lw=1.2, label="Viscosity") + + ylabel("${\\rm{Rate~Coefficient}}~\\alpha$", labelpad=0) + legend() +else: + plot(x, S, '.', color='r', ms=0.5, alpha=0.2) + plot(x_s, s_s, '--', color='k', alpha=0.8, lw=1.2) + errorbar(x_bin, S_bin, yerr=S_sigma_bin, fmt='.', ms=8.0, color='b', lw=1.2) + ylabel("${\\rm{Entropy}}~S$", labelpad=0) + ylim(0.8, 3.8) # Information ------------------------------------- subplot(236, frameon=False) @@ -312,5 +346,4 @@ ylim(0, 1) xticks([]) yticks([]) -tight_layout() savefig("SodShock.png", dpi=200) -- GitLab From f80db4ad52a7ddcf12117756b8d2d36102234c5d Mon Sep 17 00:00:00 2001 From: JBorrow Date: Fri, 29 Mar 2019 17:16:31 +0000 Subject: [PATCH 29/79] Fixed units in comoving sodshock example --- examples/Cosmology/ComovingSodShock_3D/sodShock.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/Cosmology/ComovingSodShock_3D/sodShock.yml b/examples/Cosmology/ComovingSodShock_3D/sodShock.yml index f7cf51ce0..b5b2ff8fd 100644 --- a/examples/Cosmology/ComovingSodShock_3D/sodShock.yml +++ b/examples/Cosmology/ComovingSodShock_3D/sodShock.yml @@ -1,8 +1,8 @@ # Define the system of units to use internally. InternalUnitSystem: - UnitMass_in_cgs: 2.94e45 # Grams + UnitMass_in_cgs: 2.94e55 # Grams UnitLength_in_cgs: 3.086e18 # pc - UnitVelocity_in_cgs: 1e10 # km per s + UnitVelocity_in_cgs: 1 # km per s UnitCurrent_in_cgs: 1 # Amperes UnitTemp_in_cgs: 1 # Kelvin -- GitLab From 2a16d47bd10d48381353f6ea47975cf5e9d5da7d Mon Sep 17 00:00:00 2001 From: JBorrow Date: Fri, 29 Mar 2019 17:17:18 +0000 Subject: [PATCH 30/79] Minor change to sodshock plotting script --- examples/HydroTests/SodShock_3D/plotSolution.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/HydroTests/SodShock_3D/plotSolution.py b/examples/HydroTests/SodShock_3D/plotSolution.py index 7cec619ef..69b2fe488 100644 --- a/examples/HydroTests/SodShock_3D/plotSolution.py +++ b/examples/HydroTests/SodShock_3D/plotSolution.py @@ -308,8 +308,8 @@ xlabel("${\\rm{Position}}~x$", labelpad=0) if plot_diffusion or plot_viscosity: if plot_diffusion: - plot(x, diffusion, ".", color='r', ms=0.5, alpha=0.2) - errorbar(x_bin, alpha_diff_bin, yerr=alpha_diff_sigma_bin, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion") + plot(x, diffusion * 100, ".", color='r', ms=0.5, alpha=0.2) + errorbar(x_bin, alpha_diff_bin * 100, yerr=alpha_diff_sigma_bin * 100, fmt=".", ms=8.0, color='b', lw=1.2, label="Diffusion (100x)") if plot_viscosity: plot(x, viscosity, ".", color='g', ms=0.5, alpha=0.2) -- GitLab From ac4f739121f3dfed0432aaf9bf9366a1dc892be1 Mon Sep 17 00:00:00 2001 From: JBorrow Date: Fri, 29 Mar 2019 17:17:37 +0000 Subject: [PATCH 31/79] Made UniformBox_3D work with python3 --- examples/HydroTests/UniformBox_3D/makeICbig.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/HydroTests/UniformBox_3D/makeICbig.py b/examples/HydroTests/UniformBox_3D/makeICbig.py index bd5cf627f..8841b6016 100644 --- a/examples/HydroTests/UniformBox_3D/makeICbig.py +++ b/examples/HydroTests/UniformBox_3D/makeICbig.py @@ -45,7 +45,7 @@ internalEnergy = P / ((gamma - 1.)*rho) n_iterations = numPart / N remainder = numPart % N -print "Writing", numPart, "in", n_iterations, "iterations of size", N, "and a remainder of", remainder +print("Writing", numPart, "in", n_iterations, "iterations of size", N, "and a remainder of", remainder) #--------------------------------------------------- @@ -55,8 +55,8 @@ file = h5py.File(fileName, 'w') # Header grp = file.create_group("/Header") grp.attrs["BoxSize"] = boxSize -grp.attrs["NumPart_Total"] = [numPart % (long(1)<<32), 0, 0, 0, 0, 0] -grp.attrs["NumPart_Total_HighWord"] = [numPart / (long(1)<<32), 0, 0, 0, 0, 0] +grp.attrs["NumPart_Total"] = [numPart % (int(1)<<32), 0, 0, 0, 0, 0] +grp.attrs["NumPart_Total_HighWord"] = [numPart / (int(1)<<32), 0, 0, 0, 0, 0] grp.attrs["NumPart_ThisFile"] = [numPart, 0, 0, 0, 0, 0] grp.attrs["Time"] = 0.0 grp.attrs["NumFilesPerSnapshot"] = 1 @@ -120,7 +120,7 @@ for n in range(n_iterations): coords = zeros((1,3)) offset += N - print "Done", offset,"/", numPart, "(%.1f %%)"%(100*(float)(offset)/numPart) + print("Done", offset,"/", numPart, "(%.1f %%)"%(100*(float)(offset)/numPart)) # And now, the remainder v = zeros((remainder, 3)) @@ -150,7 +150,7 @@ coords[:,1] = y[:,0] * boxSize / L + boxSize / (2*L) coords[:,2] = x[:,0] * boxSize / L + boxSize / (2*L) ods_x[offset:offset+remainder,:] = coords -print "Done", offset+remainder,"/", numPart +print("Done", offset+remainder,"/", numPart) -- GitLab From e7f02f30472eb946f03ec761f92a6fc23726f7b3 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Fri, 29 Mar 2019 17:20:08 +0000 Subject: [PATCH 32/79] Code formatting --- src/cooling/const_lambda/cooling.h | 7 +++---- src/hydro/AnarchyPU/hydro.h | 17 ++++++++++------- src/hydro/AnarchyPU/hydro_iact.h | 14 +++++++------- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index 0d15c297f..f5816b53e 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -352,10 +352,9 @@ static INLINE void cooling_print_backend( "* " "cm^3]", cooling->lambda_nH2_cgs); - - message( - "Lambda/n_H^2=%g [internal units]", cooling->lambda_nH2_cgs * cooling->conv_factor_energy_rate_from_cgs - ); + + message("Lambda/n_H^2=%g [internal units]", + cooling->lambda_nH2_cgs * cooling->conv_factor_energy_rate_from_cgs); if (cooling->cooling_tstep_mult == FLT_MAX) message("Cooling function time-step size is unlimited"); diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index d4a86085e..683917143 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -218,7 +218,7 @@ hydro_get_comoving_soundspeed(const struct part *restrict p) { /* Compute the sound speed -- see theory section for justification */ /* IDEAL GAS ONLY -- P-U does not work with generic EoS. */ - + const float square_rooted = sqrtf(hydro_gamma * p->pressure_bar / p->rho); return square_rooted; @@ -701,7 +701,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float sound_crossing_time_inverse = soundspeed_physical / h_physical; - /* Construct time differential of div.v implicitly following the ANARCHY spec */ + /* Construct time differential of div.v implicitly following the ANARCHY spec + */ float div_v_dt = dt_alpha == 0.f @@ -740,14 +741,16 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Now for the diffusive alpha */ - const float diffusion_timescale_physical_inverse = v_sig_physical / h_physical; + const float diffusion_timescale_physical_inverse = + v_sig_physical / h_physical; const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ - /* Evolution term: following Schaller+ 2015. This is actually cosmology-less and - so requires no conversion to physical. */ - float alpha_diff_dt = - hydro_props->diffusion.beta * h_physical * p->diffusion.laplace_u * cosmo->a_factor_sound_speed / (sqrt_u * cosmo->a * cosmo->a); + /* Evolution term: following Schaller+ 2015. This is actually cosmology-less + and so requires no conversion to physical. */ + float alpha_diff_dt = hydro_props->diffusion.beta * h_physical * + p->diffusion.laplace_u * cosmo->a_factor_sound_speed / + (sqrt_u * cosmo->a * cosmo->a); /* Decay term: not documented in Schaller+ 2015 but was present * in the original EAGLE code and in Schaye+ 2015 */ alpha_diff_dt -= (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index 6d49b8d40..d04cd10f3 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -205,13 +205,13 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( const float ci = pi->force.soundspeed; const float cj = pi->force.soundspeed; - /* Cosmology terms for the signal velocity */ + /* Cosmology terms for the signal velocity */ const float fac_mu = pow_three_gamma_minus_five_over_two(a); const float a2_Hubble = a * a * H; const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + - (pi->v[1] - pj->v[1]) * dx[1] + - (pi->v[2] - pj->v[2]) * dx[2]; + (pi->v[1] - pj->v[1]) * dx[1] + + (pi->v[2] - pj->v[2]) * dx[2]; /* Add Hubble flow */ @@ -270,14 +270,14 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( const float r_inv = 1.f / r; const float ci = pi->force.soundspeed; const float cj = pi->force.soundspeed; - - /* Cosmology terms for the signal velocity */ + + /* Cosmology terms for the signal velocity */ const float fac_mu = pow_three_gamma_minus_five_over_two(a); const float a2_Hubble = a * a * H; const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + - (pi->v[1] - pj->v[1]) * dx[1] + - (pi->v[2] - pj->v[2]) * dx[2]; + (pi->v[1] - pj->v[1]) * dx[1] + + (pi->v[2] - pj->v[2]) * dx[2]; /* Add Hubble flow */ -- GitLab From 2510cdb20592bd62a6a49324b84cfb41cc6b1eb4 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Fri, 29 Mar 2019 17:21:11 +0000 Subject: [PATCH 33/79] Added comments explaining cosmology --- src/hydro/AnarchyPU/hydro.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 683917143..7f6428c66 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -746,8 +746,9 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ - /* Evolution term: following Schaller+ 2015. This is actually cosmology-less - and so requires no conversion to physical. */ + /* Evolution term: following Schaller+ 2015. This is made up of several + cosmology factors: physical h, sound speed from u / sqrt(u), and the + 1 / a^2 coming from the laplace operator. */ float alpha_diff_dt = hydro_props->diffusion.beta * h_physical * p->diffusion.laplace_u * cosmo->a_factor_sound_speed / (sqrt_u * cosmo->a * cosmo->a); -- GitLab From 1835710d6d6fc1e4ba95ce561c0e946281c898fb Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Sun, 31 Mar 2019 09:57:45 +0100 Subject: [PATCH 34/79] Changed variable name from h -> kernel support --- src/hydro/AnarchyPU/hydro.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 7f6428c66..0ac52165e 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -695,11 +695,12 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Here we need to update the artificial viscosity */ /* We use in this function that h is the radius of support */ - const float h_physical = p->h * cosmo->a * kernel_gamma; + const float kernel_support_physical = p->h * cosmo->a * kernel_gamma; const float v_sig_physical = p->viscosity.v_sig * cosmo->a_factor_sound_speed; const float soundspeed_physical = hydro_get_physical_soundspeed(p, cosmo); - const float sound_crossing_time_inverse = soundspeed_physical / h_physical; + const float sound_crossing_time_inverse = + soundspeed_physical / kernel_support_physical; /* Construct time differential of div.v implicitly following the ANARCHY spec */ @@ -711,7 +712,8 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Construct the source term for the AV; if shock detected this is _positive_ * as div_v_dt should be _negative_ before the shock hits */ - const float S = h_physical * h_physical * max(0.f, -1.f * div_v_dt); + const float S = kernel_support_physical * kernel_support_physical * + max(0.f, -1.f * div_v_dt); /* 0.25 factor comes from our definition of v_sig (sum of soundspeeds rather * than mean). */ /* Note this is v_sig_physical squared, not comoving */ @@ -742,14 +744,14 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Now for the diffusive alpha */ const float diffusion_timescale_physical_inverse = - v_sig_physical / h_physical; + v_sig_physical / kernel_support_physical; const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ /* Evolution term: following Schaller+ 2015. This is made up of several cosmology factors: physical h, sound speed from u / sqrt(u), and the 1 / a^2 coming from the laplace operator. */ - float alpha_diff_dt = hydro_props->diffusion.beta * h_physical * + float alpha_diff_dt = hydro_props->diffusion.beta * kernel_support_physical * p->diffusion.laplace_u * cosmo->a_factor_sound_speed / (sqrt_u * cosmo->a * cosmo->a); /* Decay term: not documented in Schaller+ 2015 but was present -- GitLab From 911a3fedaf1dd60ae26b1b3feaf1e60bc0bcf689 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Sun, 31 Mar 2019 10:00:59 +0100 Subject: [PATCH 35/79] Fixed incorrect soundspeed in gradient loop for anarchy --- src/hydro/AnarchyPU/hydro_iact.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index d04cd10f3..cc2128b03 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -203,7 +203,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_gradient( const float r = sqrtf(r2); const float r_inv = 1.f / r; const float ci = pi->force.soundspeed; - const float cj = pi->force.soundspeed; + const float cj = pj->force.soundspeed; /* Cosmology terms for the signal velocity */ const float fac_mu = pow_three_gamma_minus_five_over_two(a); @@ -269,7 +269,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_gradient( const float r = sqrtf(r2); const float r_inv = 1.f / r; const float ci = pi->force.soundspeed; - const float cj = pi->force.soundspeed; + const float cj = pj->force.soundspeed; /* Cosmology terms for the signal velocity */ const float fac_mu = pow_three_gamma_minus_five_over_two(a); @@ -369,7 +369,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ /* Compute sound speeds and signal velocity */ - const float v_sig = 0.5 * (pi->viscosity.v_sig + pj->viscosity.v_sig); + const float v_sig = 0.5f * (pi->viscosity.v_sig + pj->viscosity.v_sig); /* Balsara term */ const float balsara_i = pi->force.balsara; @@ -411,12 +411,12 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( wj_dr * dvdr * r_inv; /* Viscosity term */ - const float visc_du_term = 0.5 * visc_acc_term * dvdr_Hubble; + const float visc_du_term = 0.5f * visc_acc_term * dvdr_Hubble; /* Diffusion term */ const float v_diff = max(pi->force.soundspeed + pj->force.soundspeed + dvdr_Hubble, 0.f); - const float alpha_diff = 0.5 * (pi->diffusion.alpha + pj->diffusion.alpha); + const float alpha_diff = 0.5f * (pi->diffusion.alpha + pj->diffusion.alpha); /* wi_dx + wj_dx / 2 is F_ij */ const float diff_du_term = alpha_diff * fac_mu * v_diff * (pi->u - pj->u) * (wi_dr + wj_dr) / rho_ij; @@ -500,7 +500,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ /* Compute sound speeds and signal velocity */ - const float v_sig = 0.5 * (pi->viscosity.v_sig + pj->viscosity.v_sig); + const float v_sig = 0.5f * (pi->viscosity.v_sig + pj->viscosity.v_sig); /* Balsara term */ const float balsara_i = pi->force.balsara; @@ -535,12 +535,12 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( wi_dr * dvdr * r_inv; /* Viscosity term */ - const float visc_du_term = 0.5 * visc_acc_term * dvdr_Hubble; + const float visc_du_term = f * visc_acc_term * dvdr_Hubble; /* Diffusion term */ const float v_diff = max(pi->force.soundspeed + pj->force.soundspeed + dvdr_Hubble, 0.f); - const float alpha_diff = 0.5 * (pi->diffusion.alpha + pj->diffusion.alpha); + const float alpha_diff = 0.5f * (pi->diffusion.alpha + pj->diffusion.alpha); /* wi_dx + wj_dx / 2 is F_ij */ const float diff_du_term = alpha_diff * fac_mu * v_diff * (pi->u - pj->u) * (wi_dr + wj_dr) / rho_ij; -- GitLab From 2399e7823b4a5c79573711c843150338c359d24b Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Sun, 31 Mar 2019 10:03:09 +0100 Subject: [PATCH 36/79] Fixed accidental deletion of a constant in anarchy --- src/hydro/AnarchyPU/hydro_iact.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index cc2128b03..199617a8f 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -535,7 +535,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( wi_dr * dvdr * r_inv; /* Viscosity term */ - const float visc_du_term = f * visc_acc_term * dvdr_Hubble; + const float visc_du_term = 0.5f * visc_acc_term * dvdr_Hubble; /* Diffusion term */ const float v_diff = -- GitLab From 91d71b1bde4d17081ae9a6b884ac6fe30921db57 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Tue, 2 Apr 2019 11:19:13 +0100 Subject: [PATCH 37/79] Attempted a minor fix to the viscosity --- src/hydro/AnarchyPU/hydro_iact.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index 199617a8f..d091ebebc 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -379,7 +379,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float rho_ij = rhoi + rhoj; const float alpha = pi->viscosity.alpha + pj->viscosity.alpha; const float visc = - -1.f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; + -0.25f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; /* Convolve with the kernel */ const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; @@ -510,7 +510,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float rho_ij = rhoi + rhoj; const float alpha = pi->viscosity.alpha + pj->viscosity.alpha; const float visc = - -1.f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; + -0.25f * alpha * v_sig * mu_ij * (balsara_i + balsara_j) / rho_ij; /* Convolve with the kernel */ const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; -- GitLab From b7cf1576678ea17f1425c2abec7c3f37b3320201 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Tue, 2 Apr 2019 13:46:30 +0100 Subject: [PATCH 38/79] Updated ANARCHY defaults --- src/hydro_properties.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hydro_properties.c b/src/hydro_properties.c index 7d2b03be7..eb506839c 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -53,11 +53,11 @@ #define hydro_props_default_viscosity_alpha \ 0.1f /* Use a very low initial AV paramater for hydrodynamics tests */ #define hydro_props_default_viscosity_alpha_min \ - 0.1f /* values NOT the same as Schaller+ 2015 */ + 0.0f /* values NOT the same as Schaller+ 2015 */ #define hydro_props_default_viscosity_alpha_max \ 2.0f /* values taken from Schaller+ 2015 */ #define hydro_props_default_viscosity_length \ - 0.01f /* values taken from Schaller+ 2015 */ + 0.25f /* values taken from Schaller+ 2015 */ #else #define hydro_props_default_viscosity_alpha_min \ 0.1f /* values taken from (price,2004), not used in legacy gadget mode */ -- GitLab From 4efc2605473e2db2b6e6187bf062db2fb098b4ab Mon Sep 17 00:00:00 2001 From: JBorrow Date: Wed, 3 Apr 2019 12:41:46 +0100 Subject: [PATCH 39/79] Updated min-dt values --- .../InteractingBlastWaves_1D/interactingBlastWaves.yml | 2 +- examples/HydroTests/Noh_1D/noh.yml | 4 ++-- examples/HydroTests/Noh_2D/noh.yml | 2 +- examples/HydroTests/SedovBlast_2D/sedov.yml | 2 +- examples/HydroTests/SedovBlast_3D/sedov.yml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml b/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml index c4960dfa2..aaad57dc0 100644 --- a/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml +++ b/examples/HydroTests/InteractingBlastWaves_1D/interactingBlastWaves.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 3.8e-2 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-5 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots diff --git a/examples/HydroTests/Noh_1D/noh.yml b/examples/HydroTests/Noh_1D/noh.yml index 58e13ddda..3a7e328df 100644 --- a/examples/HydroTests/Noh_1D/noh.yml +++ b/examples/HydroTests/Noh_1D/noh.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 0.6 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-3 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots @@ -33,4 +33,4 @@ InitialConditions: file_name: ./noh.hdf5 # The file to read periodic: 1 - \ No newline at end of file + diff --git a/examples/HydroTests/Noh_2D/noh.yml b/examples/HydroTests/Noh_2D/noh.yml index eaf991631..76ac8eb91 100644 --- a/examples/HydroTests/Noh_2D/noh.yml +++ b/examples/HydroTests/Noh_2D/noh.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 0.6 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units). dt_max: 1e-3 # The maximal time-step size of the simulation (in internal units). # Parameters governing the snapshots diff --git a/examples/HydroTests/SedovBlast_2D/sedov.yml b/examples/HydroTests/SedovBlast_2D/sedov.yml index b4252581d..208e4ac72 100644 --- a/examples/HydroTests/SedovBlast_2D/sedov.yml +++ b/examples/HydroTests/SedovBlast_2D/sedov.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 5e-2 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-9 # 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 diff --git a/examples/HydroTests/SedovBlast_3D/sedov.yml b/examples/HydroTests/SedovBlast_3D/sedov.yml index 19e8c7253..00419ba94 100644 --- a/examples/HydroTests/SedovBlast_3D/sedov.yml +++ b/examples/HydroTests/SedovBlast_3D/sedov.yml @@ -10,7 +10,7 @@ InternalUnitSystem: TimeIntegration: time_begin: 0. # The starting time of the simulation (in internal units). time_end: 5e-2 # The end time of the simulation (in internal units). - dt_min: 1e-7 # The minimal time-step size of the simulation (in internal units). + dt_min: 1e-9 # 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 -- GitLab From d69708edbee30a60c4ad081b1c564538571b7ad5 Mon Sep 17 00:00:00 2001 From: JBorrow Date: Wed, 3 Apr 2019 12:43:14 +0100 Subject: [PATCH 40/79] Minor changes to documentation --- doc/RTD/source/GettingStarted/running_example.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/RTD/source/GettingStarted/running_example.rst b/doc/RTD/source/GettingStarted/running_example.rst index 9dfbdd8c8..a5614fb2a 100644 --- a/doc/RTD/source/GettingStarted/running_example.rst +++ b/doc/RTD/source/GettingStarted/running_example.rst @@ -11,7 +11,7 @@ as ``wget`` for grabbing the glass). .. code-block:: bash - cd examples/SodShock_3D + cd examples/HydroTests/SodShock_3D ./getGlass.sh python makeIC.py ../swift --hydro --threads=4 sodShock.yml -- GitLab From 48f58459b7630d87474a2861d1535c0334f0c27b Mon Sep 17 00:00:00 2001 From: JBorrow Date: Wed, 3 Apr 2019 12:53:25 +0100 Subject: [PATCH 41/79] Added anarchy sph to docs --- doc/RTD/source/HydroSchemes/anarchy_sph.rst | 33 +++++++++++++++++++++ doc/RTD/source/HydroSchemes/index.rst | 1 + 2 files changed, 34 insertions(+) create mode 100644 doc/RTD/source/HydroSchemes/anarchy_sph.rst diff --git a/doc/RTD/source/HydroSchemes/anarchy_sph.rst b/doc/RTD/source/HydroSchemes/anarchy_sph.rst new file mode 100644 index 000000000..8d0928003 --- /dev/null +++ b/doc/RTD/source/HydroSchemes/anarchy_sph.rst @@ -0,0 +1,33 @@ +.. ANARCHY-SPH + Josh Borrow 5th April 2018 + +ANARCHY-PU SPH +============== + +This scheme is similar to the one used in the EAGLE code. This scheme +includes: + ++ Durier & Dalla Vecchia (2012) time-step limiter ++ Pressure-Energy SPH ++ Thermal diffusion following Price (2012) ++ A simplified version of the 'Inviscid SPH' artificial viscosity + (Cullen & Denhen 2010). + +More information will be made available in a forthcoming publication. + +The scheme as-implemented in SWIFT is slightly different to the one +implemented in the original EAGLE code: + ++ Pressure-Energy SPH is used instead of Pressure-Entropy SPH ++ Artificial viscosity coefficients have changed -- from minimal + value of 0.1 to 0.0, and from length of 0.1 to 0.25. This + is based on performance of hydrodynamics tests in SWIFT and may + be to do with our choice of smoothing length definition. ++ Recommended kernel changed from Wendland-C2 (with 100 Ngb) to + Quintic Spline (with ~82 Ngb). + + +.. code-block:: bash + + ./configure --with-hydro=anarchy-pu --with-kernel=quintic-spline --disable-hand-vec + diff --git a/doc/RTD/source/HydroSchemes/index.rst b/doc/RTD/source/HydroSchemes/index.rst index 462bb7378..7331331bd 100644 --- a/doc/RTD/source/HydroSchemes/index.rst +++ b/doc/RTD/source/HydroSchemes/index.rst @@ -17,6 +17,7 @@ schemes available in SWIFT, as well as how to implement your own. minimal_sph planetary hopkins_sph + anarchy_sph gizmo adding_your_own -- GitLab From fa1a141da984014ae24750036c55aeec900b045e Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 3 Apr 2019 14:25:41 +0100 Subject: [PATCH 42/79] Added build folder --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 798b187d4..e0e0be678 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ config.h.in config.sub ltmain.sh libtool +build src/version_string.h swift*.tar.gz -- GitLab From 617afd4fe30fff9afffd64c4d54f597d672334f5 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 3 Apr 2019 16:38:09 +0100 Subject: [PATCH 43/79] Increase the maximal time-step size of the non-cosmological cooling example. --- .../cooling_redshift_dependence_no_z.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml index 35242f553..8bce64984 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml @@ -11,7 +11,7 @@ TimeIntegration: time_begin: 0. time_end: 1.02e-4 # ~ 100 myr dt_min: 1e-14 - dt_max: 5e-8 + dt_max: 5e-5 # Parameters governing the snapshots Snapshots: -- GitLab From 25ad838f154681d2dfba68f50656b6496791f2b2 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 3 Apr 2019 16:46:41 +0100 Subject: [PATCH 44/79] Working version of the cosmological constant lambda cooling model. --- src/cooling/const_lambda/cooling.h | 77 ++++++++++++++++-------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index f5816b53e..8e53c044e 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -123,10 +123,10 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( if (dt == 0.) return; /* Current energy */ - const float u_old = hydro_get_physical_internal_energy(p, xp, cosmo); + // const float u_old = hydro_get_physical_internal_energy(p, xp, cosmo); - /* Current du_dt in physical coordinates (internal units) */ - const float hydro_du_dt = hydro_get_physical_internal_energy_dt(p, cosmo); + /* Y' */ + const float hydro_du_dt_com = hydro_get_comoving_internal_energy_dt(p); /* Calculate cooling du_dt (in cgs units) */ const double cooling_du_dt_cgs = @@ -136,45 +136,49 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( float cooling_du_dt = cooling_du_dt_cgs * cooling->conv_factor_energy_rate_from_cgs; - /* Add cosmological term */ - cooling_du_dt *= cosmo->a * cosmo->a; + /* Add cosmological term to get Y_cooling' */ + cooling_du_dt *= cosmo->a * cosmo->a / cosmo->a_factor_internal_energy; - float total_du_dt = hydro_du_dt + cooling_du_dt; + /* Y_total' */ + float total_du_dt = hydro_du_dt_com + cooling_du_dt; /* We now need to check that we are not going to go below any of the limits */ - /* Limit imposed by the entropy floor */ - const float A_floor = entropy_floor(p, cosmo, floor_props); - const float rho = hydro_get_physical_density(p, cosmo); - const float u_floor = gas_internal_energy_from_entropy(rho, A_floor); - - /* Absolute minimum */ - const float u_minimal = hydro_props->minimal_internal_energy; - - /* Largest of both limits */ - const float u_limit = max(u_minimal, u_floor); - - /* First, check whether we may end up below the minimal energy after - * this step 1/2 kick + another 1/2 kick that could potentially be for - * a time-step twice as big. We hence check for 1.5 delta_t. */ - if (u_old + total_du_dt * 1.5 * dt_therm < u_limit) { - total_du_dt = (u_limit - u_old) / (1.5f * dt_therm); - } - - /* Second, check whether the energy used in the prediction could get negative. - * We need to check for the 1/2 dt kick followed by a full time-step drift - * that could potentially be for a time-step twice as big. We hence check - * for 2.5 delta_t but this time against 0 energy not the minimum */ - if (u_old + total_du_dt * 2.5 * dt_therm < 0.) { - total_du_dt = -u_old / ((2.5f + 0.0001f) * dt_therm); - } + /* /\* Limit imposed by the entropy floor *\/ */ + /* const float A_floor = entropy_floor(p, cosmo, floor_props); */ + /* const float rho = hydro_get_physical_density(p, cosmo); */ + /* const float u_floor = gas_internal_energy_from_entropy(rho, A_floor); */ + + /* /\* Absolute minimum *\/ */ + /* const float u_minimal = hydro_props->minimal_internal_energy; */ + + /* /\* Largest of both limits *\/ */ + /* const float u_limit = max(u_minimal, u_floor); */ + + /* /\* First, check whether we may end up below the minimal energy after */ + /* * this step 1/2 kick + another 1/2 kick that could potentially be for */ + /* * a time-step twice as big. We hence check for 1.5 delta_t. *\/ */ + /* if (u_old + total_du_dt * 1.5 * dt_therm < u_limit) { */ + /* total_du_dt = (u_limit - u_old) / (1.5f * dt_therm); */ + /* } */ + + /* /\* Second, check whether the energy used in the prediction could get + * negative. */ + /* * We need to check for the 1/2 dt kick followed by a full time-step drift + */ + /* * that could potentially be for a time-step twice as big. We hence check + */ + /* * for 2.5 delta_t but this time against 0 energy not the minimum *\/ */ + /* if (u_old + total_du_dt * 2.5 * dt_therm < 0.) { */ + /* total_du_dt = -u_old / ((2.5f + 0.0001f) * dt_therm); */ + /* } */ /* Update the internal energy time derivative */ - hydro_set_physical_internal_energy_dt(p, cosmo, total_du_dt); + hydro_set_comoving_internal_energy_dt(p, total_du_dt); /* Store the radiated energy (assuming dt will not change) */ - xp->cooling_data.radiated_energy += - -hydro_get_mass(p) * (total_du_dt - hydro_du_dt) * dt_therm; + /* xp->cooling_data.radiated_energy += */ + /* -hydro_get_mass(p) * (total_du_dt - hydro_du_dt) * dt_therm; */ } /** @@ -208,8 +212,9 @@ __attribute__((always_inline)) INLINE static float cooling_timestep( cooling_rate_cgs(cosmo, hydro_props, cooling, p); /* Convert to internal units */ - const float cooling_du_dt = - cooling_du_dt_cgs * cooling->conv_factor_energy_rate_from_cgs; + const float cooling_du_dt = cooling_du_dt_cgs * + cooling->conv_factor_energy_rate_from_cgs / + cosmo->a_factor_internal_energy; /* If we are close to (or below) the limit, we ignore the condition */ if (u < 1.01f * hydro_props->minimal_internal_energy || cooling_du_dt == 0.f) -- GitLab From 429a7cc90561303517cba2cfb17c7943d0e10484 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 3 Apr 2019 17:03:01 +0100 Subject: [PATCH 45/79] Update the const-lambda cooling scheme to obey the minimal temperature floor. --- src/cooling/const_lambda/cooling.h | 69 +++++++++++++++--------------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index 8e53c044e..51ac66074 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -122,8 +122,8 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( /* Nothing to do here? */ if (dt == 0.) return; - /* Current energy */ - // const float u_old = hydro_get_physical_internal_energy(p, xp, cosmo); + /* Current energy (in internal units) */ + const float u_old_com = hydro_get_comoving_internal_energy(p, xp); /* Y' */ const float hydro_du_dt_com = hydro_get_comoving_internal_energy_dt(p); @@ -133,52 +133,53 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( cooling_rate_cgs(cosmo, hydro_props, cooling, p); /* Convert to internal units */ - float cooling_du_dt = + const float cooling_du_dt_physical = cooling_du_dt_cgs * cooling->conv_factor_energy_rate_from_cgs; /* Add cosmological term to get Y_cooling' */ - cooling_du_dt *= cosmo->a * cosmo->a / cosmo->a_factor_internal_energy; + const float cooling_du_dt = cooling_du_dt_physical * cosmo->a * cosmo->a / + cosmo->a_factor_internal_energy; /* Y_total' */ float total_du_dt = hydro_du_dt_com + cooling_du_dt; /* We now need to check that we are not going to go below any of the limits */ - /* /\* Limit imposed by the entropy floor *\/ */ - /* const float A_floor = entropy_floor(p, cosmo, floor_props); */ - /* const float rho = hydro_get_physical_density(p, cosmo); */ - /* const float u_floor = gas_internal_energy_from_entropy(rho, A_floor); */ - - /* /\* Absolute minimum *\/ */ - /* const float u_minimal = hydro_props->minimal_internal_energy; */ - - /* /\* Largest of both limits *\/ */ - /* const float u_limit = max(u_minimal, u_floor); */ - - /* /\* First, check whether we may end up below the minimal energy after */ - /* * this step 1/2 kick + another 1/2 kick that could potentially be for */ - /* * a time-step twice as big. We hence check for 1.5 delta_t. *\/ */ - /* if (u_old + total_du_dt * 1.5 * dt_therm < u_limit) { */ - /* total_du_dt = (u_limit - u_old) / (1.5f * dt_therm); */ - /* } */ - - /* /\* Second, check whether the energy used in the prediction could get - * negative. */ - /* * We need to check for the 1/2 dt kick followed by a full time-step drift - */ - /* * that could potentially be for a time-step twice as big. We hence check - */ - /* * for 2.5 delta_t but this time against 0 energy not the minimum *\/ */ - /* if (u_old + total_du_dt * 2.5 * dt_therm < 0.) { */ - /* total_du_dt = -u_old / ((2.5f + 0.0001f) * dt_therm); */ - /* } */ + /* Limit imposed by the entropy floor (comoving) + * (Recall entropy is the same in physical and comoving frames) */ + const float A_floor_com = entropy_floor(p, cosmo, floor_props); + const float rho_com = hydro_get_comoving_density(p); + const float u_floor_com = + gas_internal_energy_from_entropy(rho_com, A_floor_com); + + /* Absolute minimum */ + const float u_minimal_com = + hydro_props->minimal_internal_energy / cosmo->a_factor_internal_energy; + + /* Largest of both limits */ + const float u_limit_com = max(u_minimal_com, u_floor_com); + + /* First, check whether we may end up below the minimal energy after + * this step 1/2 kick + another 1/2 kick that could potentially be for + * a time-step twice as big. We hence check for 1.5 delta_t. */ + if (u_old_com + total_du_dt * 1.5 * dt_therm < u_limit_com) { + total_du_dt = (u_limit_com - u_old_com) / (1.5f * dt_therm); + } + + /* Second, check whether the energy used in the prediction could get negative. + * We need to check for the 1/2 dt kick followed by a full time-step drift + * that could potentially be for a time-step twice as big. We hence check + * for 2.5 delta_t but this time against 0 energy not the minimum */ + if (u_old_com + total_du_dt * 2.5 * dt_therm < 0.) { + total_du_dt = -u_old_com / ((2.5f + 0.0001f) * dt_therm); + } /* Update the internal energy time derivative */ hydro_set_comoving_internal_energy_dt(p, total_du_dt); /* Store the radiated energy (assuming dt will not change) */ - /* xp->cooling_data.radiated_energy += */ - /* -hydro_get_mass(p) * (total_du_dt - hydro_du_dt) * dt_therm; */ + xp->cooling_data.radiated_energy += + -hydro_get_mass(p) * cooling_du_dt_physical * dt; } /** -- GitLab From d0f76d64c27324bcf5068210b78ac39bacda9548 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 3 Apr 2019 17:23:07 +0100 Subject: [PATCH 46/79] Add the radiated energy to the fields output by the const-lambda cooling. --- src/cooling/const_lambda/cooling_io.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/cooling/const_lambda/cooling_io.h b/src/cooling/const_lambda/cooling_io.h index 9437f0f94..2e2ba799a 100644 --- a/src/cooling/const_lambda/cooling_io.h +++ b/src/cooling/const_lambda/cooling_io.h @@ -76,7 +76,10 @@ __attribute__((always_inline)) INLINE static int cooling_write_particles( UNIT_CONV_TEMPERATURE, parts, xparts, convert_part_T); - return 1; + list[1] = io_make_output_field("RadiatedEnergy", FLOAT, 1, UNIT_CONV_ENERGY, + xparts, cooling_data.radiated_energy); + + return 2; } #endif /* SWIFT_COOLING_CONST_LAMBDA_IO_H */ -- GitLab From 389bfb4372fef915909547142002d87fd67467ce Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 3 Apr 2019 17:56:42 +0100 Subject: [PATCH 47/79] Added panel to show energy radiated --- .../CoolingRedshiftDependence/plotSolution.py | 136 ++++++++++++++---- 1 file changed, 111 insertions(+), 25 deletions(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py index d7f4fe3b7..7b750a240 100644 --- a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py +++ b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py @@ -6,29 +6,69 @@ import matplotlib.pyplot as plt from swiftsimio import load -from unyt import Myr, K, mh, cm +from unyt import Myr, K, mh, cm, erg import numpy as np +def get_data_dump(metadata): + """ + Gets a big data dump from the SWIFT metadata + """ + + try: + viscosity = metadata.viscosity_info + except: + viscosity = "No info" + + try: + diffusion = metadata.diffusion_info + except: + diffusion = "No info" + + output = ( + "$\\bf{SWIFT}$\n" + + metadata.code_info + + "\n\n" + + "$\\bf{Compiler}$\n" + + metadata.compiler_info + + "\n\n" + + "$\\bf{Hydrodynamics}$\n" + + metadata.hydro_info + + "\n\n" + + "$\\bf{Viscosity}$\n" + + viscosity + + "\n\n" + + "$\\bf{Diffusion}$\n" + + diffusion + ) + + return output + + def setup_axes(): """ Sets up the axes and returns fig, ax """ - fig, ax = plt.subplots(nrows=2, ncols=1, figsize=(4, 8), sharex=True) + fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(8, 8)) ax = ax.flatten() ax[0].semilogy() + ax[2].semilogy() ax[1].set_xlabel("Simulation time elapsed [Myr]") + ax[2].set_xlabel("Simulation time elapsed [Myr]") + ax[0].set_ylabel("Temperature of Universe [K]") ax[1].set_ylabel("Physical Density of Universe [$n_H$ cm$^{-3}$]") + ax[2].set_ylabel("Physical Energy [erg]") - ax[0].set_xlim(0, 100) + for a in ax[:-1]: + a.set_xlim(0, 100) - fig.tight_layout() + fig.tight_layout(pad=0.5) return fig, ax @@ -43,6 +83,8 @@ def get_data(handle: float, n_snaps: int): times = [] temps = [] densities = [] + energies = [] + radiated_energies = [] for snap in range(n_snaps): data = load(f"data/{handle}_{snap:04d}.hdf5") @@ -52,9 +94,18 @@ def get_data(handle: float, n_snaps: int): times.append(data.metadata.t.to(Myr).value - t0) temps.append(np.mean(data.gas.temperature.to(K).value)) - densities.append(np.mean(data.gas.density.to(mh / cm**3).value) / (data.metadata.scale_factor**3) ) + densities.append( + np.mean(data.gas.density.to(mh / cm ** 3).value) + / (data.metadata.scale_factor ** 3) + ) + + energies.append( + np.mean((data.gas.internal_energy * data.gas.masses).to(erg).value) + * data.metadata.scale_factor ** (2) + ) + radiated_energies.append(np.mean(data.gas.radiated_energy.to(erg).value)) - return times, temps, densities + return times, temps, densities, energies, radiated_energies def get_n_steps(timesteps_filename: str) -> int: @@ -67,28 +118,49 @@ def get_n_steps(timesteps_filename: str) -> int: return int(data[-1][0]) -def plot_single_data(handle: str, n_snaps: int, label: str, ax: plt.axes, n_steps:int = 0): +def plot_single_data( + handle: str, n_snaps: int, label: str, ax: plt.axes, n_steps: int = 0, run: int = 0 +): """ Takes the a single simulation and plots it on the axes. """ data = get_data(handle, n_snaps) - ax[0].plot( - data[0], data[1], - label=label, - marker="o", - ms=2 - ) + ax[0].plot(data[0], data[1], label=label, marker="o", ms=2, c=f"C{run}") ax[1].plot( - data[0], data[2], - label=f"Steps: {n_steps}", - marker="o", - ms=2 + data[0], data[2], label=f"Steps: {n_steps}", marker="o", ms=2, c=f"C{run}" + ) + + if run == 0: + label_energy = "Particle Energy" + label_radiated = "Radiated Energy" + label_sum = "Sum" + else: + label_energy = "" + label_radiated = "" + label_sum = "" + + ax[2].plot( + data[0], data[3], label=label_energy, ls="dotted", C=f"C{run}" + ) + + ax[2].plot( + data[0], + data[4], + label=label_radiated, + ls="dashed", + C=f"C{run}", + ) + + ax[2].plot( + data[0], + [x + y for x, y in zip(*data[3:5])], + label=label_sum, + C=f"C{run}", ) - return @@ -99,21 +171,32 @@ def make_plot(handles, names, timestep_names, n_snaps=100): fig, ax = setup_axes() + run = 0 + for handle, name, timestep_name in zip(handles, names, timestep_names): try: n_steps = get_n_steps(timestep_name) except: n_steps = "Unknown" - try: - plot_single_data(handle, n_snaps, name, ax, n_steps=n_steps) - except: - pass + plot_single_data(handle, n_snaps, name, ax, n_steps=n_steps, run=run) + run += 1 ax[0].legend() ax[1].legend() + ax[2].legend() - return fig, ax + info_axis = ax[-1] + + info = get_data_dump(load(f"data/{handles[0]}_0000.hdf5").metadata) + + info_axis.text( + 0.5, 0.45, info, ha="center", va="center", fontsize=7, transform=info_axis.transAxes + ) + + info_axis.axis("off") + + return fig, ax if __name__ == "__main__": @@ -121,11 +204,14 @@ if __name__ == "__main__": Plot everything! """ - handles = ["redshift_dependence_no_z", "redshift_dependence_low_z", "redshift_dependence_high_z"] + handles = [ + "redshift_dependence_no_z", + "redshift_dependence_low_z", + "redshift_dependence_high_z", + ] names = ["No Cosmology", "Low Redshift ($z=0.01$)", "High Redshift ($z=1$)"] timestep_names = ["timesteps_no.txt", "timesteps_low.txt", "timesteps_high.txt"] fig, ax = make_plot(handles, names, timestep_names) fig.savefig("redshift_dependence.png", dpi=300) - -- GitLab From fb614b04aab9f51c15f686392772e525d2226a45 Mon Sep 17 00:00:00 2001 From: Josh Borrow Date: Wed, 3 Apr 2019 18:24:23 +0100 Subject: [PATCH 48/79] Made having the energies radiated optional --- .../CoolingRedshiftDependence/plotSolution.py | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py index 7b750a240..2be73a165 100644 --- a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py +++ b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py @@ -99,11 +99,14 @@ def get_data(handle: float, n_snaps: int): / (data.metadata.scale_factor ** 3) ) - energies.append( - np.mean((data.gas.internal_energy * data.gas.masses).to(erg).value) - * data.metadata.scale_factor ** (2) - ) - radiated_energies.append(np.mean(data.gas.radiated_energy.to(erg).value)) + try: + energies.append( + np.mean((data.gas.internal_energy * data.gas.masses).to(erg).value) + * data.metadata.scale_factor ** (2) + ) + radiated_energies.append(np.mean(data.gas.radiated_energy.to(erg).value)) + except AttributeError: + continue return times, temps, densities, energies, radiated_energies @@ -142,23 +145,12 @@ def plot_single_data( label_radiated = "" label_sum = "" - ax[2].plot( - data[0], data[3], label=label_energy, ls="dotted", C=f"C{run}" - ) + ax[2].plot(data[0], data[3], label=label_energy, ls="dotted", C=f"C{run}") - ax[2].plot( - data[0], - data[4], - label=label_radiated, - ls="dashed", - C=f"C{run}", - ) + ax[2].plot(data[0], data[4], label=label_radiated, ls="dashed", C=f"C{run}") ax[2].plot( - data[0], - [x + y for x, y in zip(*data[3:5])], - label=label_sum, - C=f"C{run}", + data[0], [x + y for x, y in zip(*data[3:5])], label=label_sum, C=f"C{run}" ) return @@ -191,7 +183,13 @@ def make_plot(handles, names, timestep_names, n_snaps=100): info = get_data_dump(load(f"data/{handles[0]}_0000.hdf5").metadata) info_axis.text( - 0.5, 0.45, info, ha="center", va="center", fontsize=7, transform=info_axis.transAxes + 0.5, + 0.45, + info, + ha="center", + va="center", + fontsize=7, + transform=info_axis.transAxes, ) info_axis.axis("off") -- GitLab From 89f3d1c61f171df6ef23bffd301799dddb9ff986 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 4 Apr 2019 09:53:19 +0100 Subject: [PATCH 49/79] Use the drifted internal energy for the temperature calculation in the i/o. --- src/cooling/const_lambda/cooling.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index 51ac66074..3518fe21f 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -276,7 +276,7 @@ INLINE static float cooling_get_temperature( const double mu_ionised = hydro_props->mu_ionised; /* Particle temperature */ - const double u = hydro_get_physical_internal_energy(p, xp, cosmo); + const double u = hydro_get_drifted_physical_internal_energy(p, cosmo); /* Temperature over mean molecular weight */ const double T_over_mu = hydro_gamma_minus_one * u * m_H / k_B; -- GitLab From 233ab52cac06b6444fb18502a93313da0f9acf51 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 4 Apr 2019 16:38:45 +0100 Subject: [PATCH 50/79] Fix the script for non completed runs. --- .../CoolingRedshiftDependence/plotSolution.py | 70 +++++++++++-------- 1 file changed, 39 insertions(+), 31 deletions(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py index 2be73a165..9cde36cb0 100644 --- a/examples/Cooling/CoolingRedshiftDependence/plotSolution.py +++ b/examples/Cooling/CoolingRedshiftDependence/plotSolution.py @@ -87,25 +87,30 @@ def get_data(handle: float, n_snaps: int): radiated_energies = [] for snap in range(n_snaps): - data = load(f"data/{handle}_{snap:04d}.hdf5") - - if snap == 0: - t0 = data.metadata.t.to(Myr).value + try: + data = load(f"data/{handle}_{snap:04d}.hdf5") - times.append(data.metadata.t.to(Myr).value - t0) - temps.append(np.mean(data.gas.temperature.to(K).value)) - densities.append( - np.mean(data.gas.density.to(mh / cm ** 3).value) - / (data.metadata.scale_factor ** 3) - ) + if snap == 0: + t0 = data.metadata.t.to(Myr).value - try: - energies.append( - np.mean((data.gas.internal_energy * data.gas.masses).to(erg).value) - * data.metadata.scale_factor ** (2) + times.append(data.metadata.t.to(Myr).value - t0) + temps.append(np.mean(data.gas.temperature.to(K).value)) + densities.append( + np.mean(data.gas.density.to(mh / cm ** 3).value) + / (data.metadata.scale_factor ** 3) ) - radiated_energies.append(np.mean(data.gas.radiated_energy.to(erg).value)) - except AttributeError: + + try: + energies.append( + np.mean((data.gas.internal_energy * data.gas.masses).to(erg).value) + * data.metadata.scale_factor ** (2) + ) + radiated_energies.append( + np.mean(data.gas.radiated_energy.to(erg).value) + ) + except AttributeError: + continue + except OSError: continue return times, temps, densities, energies, radiated_energies @@ -147,11 +152,11 @@ def plot_single_data( ax[2].plot(data[0], data[3], label=label_energy, ls="dotted", C=f"C{run}") - ax[2].plot(data[0], data[4], label=label_radiated, ls="dashed", C=f"C{run}") + # ax[2].plot(data[0], data[4], label=label_radiated, ls="dashed", C=f"C{run}") - ax[2].plot( - data[0], [x + y for x, y in zip(*data[3:5])], label=label_sum, C=f"C{run}" - ) + # ax[2].plot( + # data[0], [x + y for x, y in zip(*data[3:5])], label=label_sum, C=f"C{run}" + # ) return @@ -180,17 +185,20 @@ def make_plot(handles, names, timestep_names, n_snaps=100): info_axis = ax[-1] - info = get_data_dump(load(f"data/{handles[0]}_0000.hdf5").metadata) - - info_axis.text( - 0.5, - 0.45, - info, - ha="center", - va="center", - fontsize=7, - transform=info_axis.transAxes, - ) + try: + info = get_data_dump(load(f"data/{handles[0]}_0000.hdf5").metadata) + + info_axis.text( + 0.5, + 0.45, + info, + ha="center", + va="center", + fontsize=7, + transform=info_axis.transAxes, + ) + except OSError: + pass info_axis.axis("off") -- GitLab From 8d5ca620bd8244c0ebc2a7b817502f74c6c71415 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 4 Apr 2019 17:11:02 +0100 Subject: [PATCH 51/79] Correct the metallicity comment in the cooling test YML files. --- .../cooling_redshift_dependence_high_z.yml | 15 ++++++++++++++- .../cooling_redshift_dependence_low_z.yml | 15 ++++++++++++++- .../cooling_redshift_dependence_no_z.yml | 15 ++++++++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml index 13ed73554..dc1041fe3 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_high_z.yml @@ -44,7 +44,20 @@ InitialConditions: periodic: 1 # Parameters for the EAGLE chemistry -EAGLEChemistry: # Solar abundances +# EAGLEChemistry: # Solar abundances +# init_abundance_metal: 0.014 +# init_abundance_Hydrogen: 0.70649785 +# init_abundance_Helium: 0.28055534 +# init_abundance_Carbon: 2.0665436e-3 +# init_abundance_Nitrogen: 8.3562563e-4 +# init_abundance_Oxygen: 5.4926244e-3 +# init_abundance_Neon: 1.4144605e-3 +# init_abundance_Magnesium: 5.907064e-4 +# init_abundance_Silicon: 6.825874e-4 +# init_abundance_Iron: 1.1032152e-3 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Primoridal abundances init_abundance_metal: 0. init_abundance_Hydrogen: 0.752 init_abundance_Helium: 0.248 diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml index 5b336bc4b..4b12ff692 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_low_z.yml @@ -44,7 +44,19 @@ InitialConditions: periodic: 1 # Parameters for the EAGLE chemistry -EAGLEChemistry: # Primordial +# EAGLEChemistry: # Solar abundances +# init_abundance_metal: 0.014 +# init_abundance_Hydrogen: 0.70649785 +# init_abundance_Helium: 0.28055534 +# init_abundance_Carbon: 2.0665436e-3 +# init_abundance_Nitrogen: 8.3562563e-4 +# init_abundance_Oxygen: 5.4926244e-3 +# init_abundance_Neon: 1.4144605e-3 +# init_abundance_Magnesium: 5.907064e-4 +# init_abundance_Silicon: 6.825874e-4 +# init_abundance_Iron: 1.1032152e-3 + +EAGLEChemistry: # Primordial abundances init_abundance_metal: 0. init_abundance_Hydrogen: 0.752 init_abundance_Helium: 0.248 @@ -56,6 +68,7 @@ EAGLEChemistry: # Primordial init_abundance_Silicon: 0. init_abundance_Iron: 0. + # Parameters for the EAGLE cooling EAGLECooling: dir_name: ./coolingtables/ diff --git a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml index 8bce64984..6f2c88a7d 100644 --- a/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml +++ b/examples/Cooling/CoolingRedshiftDependence/cooling_redshift_dependence_no_z.yml @@ -35,7 +35,20 @@ InitialConditions: periodic: 1 # Parameters for the EAGLE chemistry -EAGLEChemistry: # Solar abundances +# EAGLEChemistry: # Solar abundances +# init_abundance_metal: 0.014 +# init_abundance_Hydrogen: 0.70649785 +# init_abundance_Helium: 0.28055534 +# init_abundance_Carbon: 2.0665436e-3 +# init_abundance_Nitrogen: 8.3562563e-4 +# init_abundance_Oxygen: 5.4926244e-3 +# init_abundance_Neon: 1.4144605e-3 +# init_abundance_Magnesium: 5.907064e-4 +# init_abundance_Silicon: 6.825874e-4 +# init_abundance_Iron: 1.1032152e-3 + +# Parameters for the EAGLE chemistry +EAGLEChemistry: # Primoridal abundances init_abundance_metal: 0. init_abundance_Hydrogen: 0.752 init_abundance_Helium: 0.248 -- GitLab From 400fbc80b6b9655a0015fc3620882c365b422df7 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 4 Apr 2019 17:11:49 +0100 Subject: [PATCH 52/79] Do not restrict the cooling rate in the EAGLE cooling by using 2.5x the time-step size. --- src/cooling/EAGLE/cooling.c | 43 +++++++++++-------------------------- 1 file changed, 13 insertions(+), 30 deletions(-) diff --git a/src/cooling/EAGLE/cooling.c b/src/cooling/EAGLE/cooling.c index 2e5da9576..059d86e47 100644 --- a/src/cooling/EAGLE/cooling.c +++ b/src/cooling/EAGLE/cooling.c @@ -57,7 +57,7 @@ static const int bisection_max_iterations = 150; static const float explicit_tolerance = 0.05; static const float newton_tolerance = 1.0e-4; static const float bisection_tolerance = 1.0e-6; -static const float rounding_tolerance = 1.0e-4; +// static const float rounding_tolerance = 1.0e-4; static const double bracket_factor = 1.5; static const double newton_log_u_guess_cgs = 12; @@ -494,6 +494,8 @@ void cooling_cool_part(const struct phys_const *phys_const, #endif /* Get internal energy at the last kick step */ + /* MATTHIEU: Is this really what we want? Shouldn't it be the drifted energy? + */ const float u_start = hydro_get_physical_internal_energy(p, xp, cosmo); /* Get the change in internal energy due to hydro forces */ @@ -507,7 +509,6 @@ void cooling_cool_part(const struct phys_const *phys_const, u_0 = max(u_0, hydro_properties->minimal_internal_energy); /* Convert to CGS units */ - const double u_start_cgs = u_start * cooling->internal_energy_to_cgs; const double u_0_cgs = u_0 * cooling->internal_energy_to_cgs; const double dt_cgs = dt * units_cgs_conversion_factor(us, UNIT_CONV_TIME); @@ -532,7 +533,7 @@ void cooling_cool_part(const struct phys_const *phys_const, * metal-free Helium mass fraction as per the Wiersma+08 definition */ const float HeFrac = XHe / (XH + XHe); - /* convert Hydrogen mass fraction into Hydrogen number density */ + /* convert Hydrogen mass fraction into physical Hydrogen number density */ const double n_H = hydro_get_physical_density(p, cosmo) * XH / phys_const->const_proton_mass; const double n_H_cgs = n_H * cooling->number_density_to_cgs; @@ -616,42 +617,24 @@ void cooling_cool_part(const struct phys_const *phys_const, } } - /* Expected change in energy over the next kick step - (assuming no change in dt) */ - const double delta_u_cgs = u_final_cgs - u_start_cgs; - /* Convert back to internal units */ - double delta_u = delta_u_cgs * cooling->internal_energy_from_cgs; + double u_final = u_final_cgs * cooling->internal_energy_from_cgs; /* We now need to check that we are not going to go below any of the limits */ + /* Absolute minimum */ + const double u_minimal = hydro_properties->minimal_internal_energy; + u_final = max(u_final, u_minimal); + /* Limit imposed by the entropy floor */ const double A_floor = entropy_floor(p, cosmo, floor_props); const double rho = hydro_get_physical_density(p, cosmo); const double u_floor = gas_internal_energy_from_entropy(rho, A_floor); + u_final = max(u_final, u_floor); - /* Absolute minimum */ - const double u_minimal = hydro_properties->minimal_internal_energy; - - /* Largest of both limits */ - const double u_limit = max(u_minimal, u_floor); - - /* First, check whether we may end up below the minimal energy after - * this step 1/2 kick + another 1/2 kick that could potentially be for - * a time-step twice as big. We hence check for 1.5 delta_u. */ - if (u_start + 1.5 * delta_u < u_limit) { - delta_u = (u_limit - u_start) / 1.5; - } - - /* Second, check whether the energy used in the prediction could get negative. - * We need to check for the 1/2 dt kick followed by a full time-step drift - * that could potentially be for a time-step twice as big. We hence check - * for 2.5 delta_u but this time against 0 energy not the minimum. - * To avoid numerical rounding bringing us below 0., we add a tiny tolerance. - */ - if (u_start + 2.5 * delta_u < 0.) { - delta_u = -u_start / (2.5 + rounding_tolerance); - } + /* Expected change in energy over the next kick step + (assuming no change in dt) */ + const double delta_u = u_final - u_start; /* Turn this into a rate of change (including cosmology term) */ const float cooling_du_dt = delta_u / dt_therm; -- GitLab From 624c76378e3b9e8032cbca7b5499d63083af618b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 4 Apr 2019 17:13:05 +0100 Subject: [PATCH 53/79] When drifting particles, make sure they do not cross the entropy floor. --- src/cell.c | 15 +++++++++++++++ src/hydro/AnarchyPU/hydro.h | 30 ++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/src/cell.c b/src/cell.c index 675c30066..0ee08c518 100644 --- a/src/cell.c +++ b/src/cell.c @@ -52,6 +52,7 @@ #include "chemistry.h" #include "drift.h" #include "engine.h" +#include "entropy_floor.h" #include "error.h" #include "gravity.h" #include "hydro.h" @@ -3759,6 +3760,7 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) { const integertime_t ti_current = e->ti_current; struct part *const parts = c->hydro.parts; struct xpart *const xparts = c->hydro.xparts; + const struct entropy_floor_properties *floor = e->entropy_floor; float dx_max = 0.f, dx2_max = 0.f; float dx_max_sort = 0.0f, dx2_max_sort = 0.f; @@ -3851,6 +3853,19 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) { drift_part(p, xp, dt_drift, dt_kick_hydro, dt_kick_grav, dt_therm, ti_old_part, ti_current); + /* Limit imposed by the absolute minimum */ + const float u_minimum = e->hydro_properties->minimal_internal_energy; + const float u_part = + hydro_get_drifted_physical_internal_energy(p, e->cosmology); + const float u_final = max(u_minimum, u_part); + hydro_set_drifted_physical_internal_energy(p, e->cosmology, u_final); + + /* Limit imposed by the entropy floor */ + const float A_floor = entropy_floor(p, e->cosmology, floor); + const float A_part = hydro_get_drifted_physical_entropy(p, e->cosmology); + const float A_final = max(A_floor, A_part); + hydro_set_drifted_physical_entropy(p, e->cosmology, A_final); + /* Update the tracers properties */ tracers_after_drift(p, xp, e->internal_units, e->physical_constants, with_cosmology, e->cosmology, e->hydro_properties, diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 0ac52165e..615b8f16a 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -380,6 +380,32 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical entropy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + /* Note there is no conversion from physical to comoving entropy */ + const float comoving_entropy = entropy; + + p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); + + /* Now recompute the extra quantities */ + + /* Compute the sound speed */ + const float soundspeed = hydro_get_comoving_soundspeed(p); + + /* Update variables. */ + p->force.soundspeed = soundspeed; +} + /** * @brief Sets the physical internal energy of a particle * @@ -441,8 +467,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( const float dt_cfl = 2.f * kernel_gamma * CFL_condition * cosmo->a * p->h / (cosmo->a_factor_sound_speed * p->viscosity.v_sig); - const float dt_u_change = - (p->u_dt != 0.0f) ? fabsf(const_max_u_change * p->u / p->u_dt) : FLT_MAX; + const float dt_u_change = FLT_MAX; + //(p->u_dt != 0.0f) ? fabsf(const_max_u_change * p->u / p->u_dt) : FLT_MAX; return fminf(dt_cfl, dt_u_change); } -- GitLab From ac203cd59bf5b11aa3d8ee0dd4e20c1c5808f93b Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 4 Apr 2019 17:30:47 +0100 Subject: [PATCH 54/79] Also update the Gadget2 SPH scheme to work with the new limitation of the entropy floor in the drift. --- src/hydro/Gadget2/hydro.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index f05e3229a..d51e1e414 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -348,6 +348,40 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->entropy_full = entropy; } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical internal energy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + /* Note there is no conversion from physical to comoving entropy */ + p->entropy = entropy; + + /* Now recompute the extra quantities */ + + /* Inverse of the co-moving density */ + const float rho_inv = 1.f / p->rho; + + /* Compute the pressure */ + 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); + + /* Divide the pressure by the density squared to get the SPH term */ + const float P_over_rho2 = pressure * rho_inv * rho_inv; + + /* Update variables. */ + p->force.P_over_rho2 = P_over_rho2; + p->force.soundspeed = soundspeed; +} + /** * @brief Sets the physical internal energy of a particle * -- GitLab From 25e636068c3f978e1a513895e3830c88f036eee5 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 10 Apr 2019 19:50:39 +0100 Subject: [PATCH 55/79] Also updated the minimal hydro scheme. --- src/hydro/Minimal/hydro.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index e2fd00695..446198343 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -354,6 +354,35 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical entropy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + /* Note there is no conversion from physical to comoving entropy */ + const float comoving_entropy = entropy; + + p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); + + /* Now recompute the extra quantities */ + + /* Compute the sound speed */ + const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); + const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); + + /* Update variables. */ + p->force.pressure = pressure; + p->force.soundspeed = soundspeed; +} + + /** * @brief Sets the physical internal energy of a particle * -- GitLab From a8d5708e6d42c91fb8754f28541d464c195c5c3f Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Sat, 13 Apr 2019 22:26:35 +0200 Subject: [PATCH 56/79] Do not reallocate the full sort arrays. --- src/cell.h | 133 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 44 deletions(-) diff --git a/src/cell.h b/src/cell.h index b9b77a002..eb8e2b381 100644 --- a/src/cell.h +++ b/src/cell.h @@ -1087,28 +1087,44 @@ __attribute__((always_inline)) INLINE static void cell_ensure_tagged( __attribute__((always_inline)) INLINE static void cell_malloc_hydro_sorts( struct cell *c, int flags) { - /* Count the memory needed for all active dimensions. */ - int count = 0; - for (int j = 0; j < 13; j++) { - if ((flags & (1 << j)) && c->hydro.sort[j] == NULL) - count += (c->hydro.count + 1); - } - - /* Allocate as a single chunk. */ - struct entry *memptr = NULL; - if ((memptr = (struct entry *)swift_malloc( - "hydro.sort", sizeof(struct entry) * count)) == NULL) - error("Failed to allocate sort memory."); - - c->hydro.sortptr = memptr; + const int count = c->hydro.count; - /* And attach spans as needed. */ for (int j = 0; j < 13; j++) { if ((flags & (1 << j)) && c->hydro.sort[j] == NULL) { - c->hydro.sort[j] = memptr; - memptr += (c->hydro.count + 1); + if ((c->hydro.sort[j] = (struct entry *)swift_malloc( + "hydro.sort", sizeof(struct entry) * (count + 1))) == NULL) + error("Failed to allocate sort memory."); } } + + /* /\* Count the memory needed for all active dimensions. *\/ */ + /* int count = 0; */ + /* for (int j = 0; j < 13; j++) { */ + /* if ((flags & (1 << j)) && c->hydro.sort[j] == NULL) */ + /* count += (c->hydro.count + 1); */ + /* } */ + + /* if(c->hydro.sortptr != NULL) */ + /* error("Reallocating hydro sorts!"); */ + + /* /\* Allocate as a single chunk. *\/ */ + /* struct entry *memptr = NULL; */ + /* /\* if ((memptr = (struct entry *)swift_malloc( *\/ */ + /* /\* "hydro.sort", sizeof(struct entry) * count)) == NULL) *\/ */ + /* if ((memptr = (struct entry *)malloc( */ + /* sizeof(struct entry) * count)) == NULL) + */ + /* error("Failed to allocate sort memory."); */ + + /* c->hydro.sortptr = memptr; */ + + /* /\* And attach spans as needed. *\/ */ + /* for (int j = 0; j < 13; j++) { */ + /* if ((flags & (1 << j)) && c->hydro.sort[j] == NULL) { */ + /* c->hydro.sort[j] = memptr; */ + /* memptr += (c->hydro.count + 1); */ + /* } */ + /* } */ } /** @@ -1119,12 +1135,20 @@ __attribute__((always_inline)) INLINE static void cell_malloc_hydro_sorts( __attribute__((always_inline)) INLINE static void cell_free_hydro_sorts( struct cell *c) { - /* Note only one allocation for the dimensions. */ - if (c->hydro.sortptr != NULL) { - swift_free("hydro.sort", c->hydro.sortptr); - c->hydro.sortptr = NULL; - for (int i = 0; i < 13; i++) c->hydro.sort[i] = NULL; + for (int i = 0; i < 13; i++) { + if (c->hydro.sort[i] != NULL) { + swift_free("hydro.sort", c->hydro.sort[i]); + c->hydro.sort[i] = NULL; + } } + + /* /\* Note only one allocation for the dimensions. *\/ */ + /* if (c->hydro.sortptr != NULL) { */ + /* //swift_free("hydro.sort", c->hydro.sortptr); */ + /* free(c->hydro.sortptr); */ + /* c->hydro.sortptr = NULL; */ + /* for (int i = 0; i < 13; i++) c->hydro.sort[i] = NULL; */ + /* } */ } /** @@ -1136,28 +1160,41 @@ __attribute__((always_inline)) INLINE static void cell_free_hydro_sorts( __attribute__((always_inline)) INLINE static void cell_malloc_stars_sorts( struct cell *c, int flags) { - /* Count the memory needed for all active dimensions. */ - int count = 0; - for (int j = 0; j < 13; j++) { - if ((flags & (1 << j)) && c->stars.sort[j] == NULL) - count += (c->stars.count + 1); - } - - /* Allocate as a single chunk. */ - struct entry *memptr = NULL; - if ((memptr = (struct entry *)swift_malloc( - "stars.sort", sizeof(struct entry) * count)) == NULL) - error("Failed to allocate sort memory."); - - c->stars.sortptr = memptr; + const int count = c->stars.count; - /* And attach spans as needed. */ for (int j = 0; j < 13; j++) { if ((flags & (1 << j)) && c->stars.sort[j] == NULL) { - c->stars.sort[j] = memptr; - memptr += (c->stars.count + 1); + if ((c->stars.sort[j] = (struct entry *)swift_malloc( + "stars.sort", sizeof(struct entry) * (count + 1))) == NULL) + error("Failed to allocate sort memory."); } } + + /* /\* Count the memory needed for all active dimensions. *\/ */ + /* int count = 0; */ + /* for (int j = 0; j < 13; j++) { */ + /* if ((flags & (1 << j)) && c->stars.sort[j] == NULL) */ + /* count += (c->stars.count + 1); */ + /* } */ + + /* /\* Allocate as a single chunk. *\/ */ + /* struct entry *memptr = NULL; */ + /* /\* if ((memptr = (struct entry *)swift_malloc( *\/ */ + /* /\* "stars.sort", sizeof(struct entry) * count)) == NULL) *\/ */ + /* if ((memptr = (struct entry *)malloc( */ + /* sizeof(struct entry) * count)) == NULL) + */ + /* error("Failed to allocate sort memory."); */ + + /* c->stars.sortptr = memptr; */ + + /* /\* And attach spans as needed. *\/ */ + /* for (int j = 0; j < 13; j++) { */ + /* if ((flags & (1 << j)) && c->stars.sort[j] == NULL) { */ + /* c->stars.sort[j] = memptr; */ + /* memptr += (c->stars.count + 1); */ + /* } */ + /* } */ } /** @@ -1168,12 +1205,20 @@ __attribute__((always_inline)) INLINE static void cell_malloc_stars_sorts( __attribute__((always_inline)) INLINE static void cell_free_stars_sorts( struct cell *c) { - /* Note only one allocation for the dimensions. */ - if (c->stars.sortptr != NULL) { - swift_free("stars.sort", c->stars.sortptr); - c->stars.sortptr = NULL; - for (int i = 0; i < 13; i++) c->stars.sort[i] = NULL; + for (int i = 0; i < 13; i++) { + if (c->stars.sort[i] != NULL) { + swift_free("stars.sort", c->stars.sort[i]); + c->stars.sort[i] = NULL; + } } + + /* /\* Note only one allocation for the dimensions. *\/ */ + /* if (c->stars.sortptr != NULL) { */ + /* //swift_free("stars.sort", c->stars.sortptr); */ + /* free(c->stars.sortptr); */ + /* c->stars.sortptr = NULL; */ + /* for (int i = 0; i < 13; i++) c->stars.sort[i] = NULL; */ + /* } */ } #endif /* SWIFT_CELL_H */ -- GitLab From 277df956524baaa7f21027e178116e19bdc25c1e Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 22 Apr 2019 15:27:50 +0200 Subject: [PATCH 57/79] Revert the change in time-step size condition for ANARCHY P-U --- src/hydro/AnarchyPU/hydro.h | 4 ++-- src/hydro/Minimal/hydro.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 615b8f16a..0ed117020 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -467,8 +467,8 @@ __attribute__((always_inline)) INLINE static float hydro_compute_timestep( const float dt_cfl = 2.f * kernel_gamma * CFL_condition * cosmo->a * p->h / (cosmo->a_factor_sound_speed * p->viscosity.v_sig); - const float dt_u_change = FLT_MAX; - //(p->u_dt != 0.0f) ? fabsf(const_max_u_change * p->u / p->u_dt) : FLT_MAX; + const float dt_u_change = + (p->u_dt != 0.0f) ? fabsf(const_max_u_change * p->u / p->u_dt) : FLT_MAX; return fminf(dt_cfl, dt_u_change); } diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index 446198343..ce7a0e7b8 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -382,7 +382,6 @@ hydro_set_drifted_physical_entropy(struct part *p, p->force.soundspeed = soundspeed; } - /** * @brief Sets the physical internal energy of a particle * -- GitLab From 2c52bcf12be442c3554bdc2f15f4b9c820d6bbe7 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 22 Apr 2019 17:08:41 +0200 Subject: [PATCH 58/79] The chemistry code should not assume that p->rho exists. --- src/chemistry/EAGLE/chemistry.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/chemistry/EAGLE/chemistry.h b/src/chemistry/EAGLE/chemistry.h index 8c0061eef..a04d7f94e 100644 --- a/src/chemistry/EAGLE/chemistry.h +++ b/src/chemistry/EAGLE/chemistry.h @@ -90,8 +90,9 @@ __attribute__((always_inline)) INLINE static void chemistry_end_density( /* Some smoothing length multiples. */ const float h = p->h; - const float h_inv = 1.0f / h; /* 1/h */ - const float factor = pow_dimension(h_inv) / p->rho; /* 1 / h^d * rho */ + const float h_inv = 1.0f / h; /* 1/h */ + const float rho = hydro_get_comoving_density(p); + const float factor = pow_dimension(h_inv) / rho; /* 1 / (h^d * rho) */ const float m = hydro_get_mass(p); struct chemistry_part_data* cpd = &p->chemistry_data; -- GitLab From 8fc5f1a95858e83aacee1d1b03b86203091fd552 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 22 Apr 2019 17:30:51 +0200 Subject: [PATCH 59/79] Updated the other hydro schemes. --- src/hydro/Default/hydro.h | 21 +++++++++++ src/hydro/GizmoMFM/hydro.h | 14 ++++++++ src/hydro/GizmoMFV/hydro.h | 14 ++++++++ src/hydro/Planetary/hydro.h | 30 ++++++++++++++++ src/hydro/PressureEnergy/hydro.h | 26 ++++++++++++++ .../PressureEnergyMorrisMonaghanAV/hydro.h | 26 ++++++++++++++ src/hydro/PressureEntropy/hydro.h | 36 +++++++++++++++++++ 7 files changed, 167 insertions(+) diff --git a/src/hydro/Default/hydro.h b/src/hydro/Default/hydro.h index 175265dd4..7db6efd60 100644 --- a/src/hydro/Default/hydro.h +++ b/src/hydro/Default/hydro.h @@ -335,6 +335,27 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical entropy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + /* Note there is no conversion from physical to comoving entropy */ + const float comoving_entropy = entropy; + + p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); + + /* Now recompute the extra quantities */ + error("Matthieu: This needs implementing"); +} + /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/GizmoMFM/hydro.h b/src/hydro/GizmoMFM/hydro.h index 3456e6f9e..5a33d5518 100644 --- a/src/hydro/GizmoMFM/hydro.h +++ b/src/hydro/GizmoMFM/hydro.h @@ -987,6 +987,20 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( error("Needs implementing"); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical internal energy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part* p, + const struct cosmology* cosmo, + const float entropy) { + error("Needs implementing"); +} + /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/GizmoMFV/hydro.h b/src/hydro/GizmoMFV/hydro.h index 526d84289..80e9be47e 100644 --- a/src/hydro/GizmoMFV/hydro.h +++ b/src/hydro/GizmoMFV/hydro.h @@ -1061,6 +1061,20 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( error("Needs implementing"); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical internal energy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part* p, + const struct cosmology* cosmo, + const float entropy) { + error("Needs implementing"); +} + /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/Planetary/hydro.h b/src/hydro/Planetary/hydro.h index e03b307bc..99960b7c3 100644 --- a/src/hydro/Planetary/hydro.h +++ b/src/hydro/Planetary/hydro.h @@ -378,6 +378,36 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( gas_internal_energy_from_entropy(p->rho, comoving_entropy, p->mat_id); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical entropy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + /* Note there is no conversion from physical to comoving entropy */ + const float comoving_entropy = entropy; + + p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy, p->mat_id); + + /* Now recompute the extra quantities */ + + /* Compute the sound speed */ + const float pressure = + gas_pressure_from_internal_energy(p->rho, p->u, p->mat_id); + const float soundspeed = + gas_soundspeed_from_pressure(p->rho, pressure, p->mat_id); + + /* Update variables. */ + p->force.pressure = pressure; + p->force.soundspeed = soundspeed; +} + /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index 3fe3c805f..d4fc2cd07 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -379,6 +379,32 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical entropy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + /* Note there is no conversion from physical to comoving entropy */ + const float comoving_entropy = entropy; + + p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); + + /* Now recompute the extra quantities */ + + /* Compute the sound speed */ + const float soundspeed = hydro_get_comoving_soundspeed(p); + + /* Update variables. */ + p->force.soundspeed = soundspeed; +} + /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h index be6a789eb..a54db28f1 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h @@ -376,6 +376,32 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical entropy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + /* Note there is no conversion from physical to comoving entropy */ + const float comoving_entropy = entropy; + + p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); + + /* Now recompute the extra quantities */ + + /* Compute the sound speed */ + const float soundspeed = hydro_get_comoving_soundspeed(p); + + /* Update variables. */ + p->force.soundspeed = soundspeed; +} + /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/PressureEntropy/hydro.h b/src/hydro/PressureEntropy/hydro.h index 578bebf63..f38194901 100644 --- a/src/hydro/PressureEntropy/hydro.h +++ b/src/hydro/PressureEntropy/hydro.h @@ -373,6 +373,42 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->entropy_full = entropy; } +/** + * @brief Sets the drifted physical entropy of a particle + * + * @param p The particle of interest. + * @param cosmo Cosmology data structure + * @param entropy The physical internal energy + */ +__attribute__((always_inline)) INLINE static void +hydro_set_drifted_physical_entropy(struct part *p, + const struct cosmology *cosmo, + const float entropy) { + + error("Matthieu: Check that this is correct when running P-E"); + + /* Note there is no conversion from physical to comoving entropy */ + p->entropy = entropy; + + /* Now recompute the extra quantities */ + + /* Inverse of the co-moving density */ + const float rho_inv = 1.f / p->rho; + + /* Compute the pressure */ + 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); + + /* Divide the pressure by the density squared to get the SPH term */ + const float P_over_rho2 = pressure * rho_inv * rho_inv; + + /* Update variables. */ + p->force.P_over_rho2 = P_over_rho2; + p->force.soundspeed = soundspeed; +} + /** * @brief Computes the hydro time-step of a given particle * -- GitLab From a3556dfbc2a2cf245634f4c9ed50b157593834a5 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 22 Apr 2019 17:32:36 +0200 Subject: [PATCH 60/79] Removed the defunct 'debug' hysro scheme from the configure help string. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index c0ce63035..1130f5d87 100644 --- a/configure.ac +++ b/configure.ac @@ -1371,7 +1371,7 @@ esac # Hydro scheme. AC_ARG_WITH([hydro], [AS_HELP_STRING([--with-hydro=], - [Hydro dynamics to use @<:@gadget2, minimal, pressure-entropy, pressure-energy, pressure-energy-monaghan, default, gizmo-mfv, gizmo-mfm, shadowfax, planetary, anarchy-pu debug default: gadget2@:>@] + [Hydro dynamics to use @<:@gadget2, minimal, pressure-entropy, pressure-energy, pressure-energy-monaghan, default, gizmo-mfv, gizmo-mfm, shadowfax, planetary, anarchy-pu default: gadget2@:>@] )], [with_hydro="$withval"], [with_hydro="gadget2"] -- GitLab From b02abdcb6ce64801b0b498f50b02f0c8150b484f Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 11:24:47 +0200 Subject: [PATCH 61/79] Correct missing inclusion in the entropy floor headers. --- src/entropy_floor/EAGLE/entropy_floor.h | 1 + src/entropy_floor/none/entropy_floor.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/entropy_floor/EAGLE/entropy_floor.h b/src/entropy_floor/EAGLE/entropy_floor.h index 5a53b3b39..c52f8d111 100644 --- a/src/entropy_floor/EAGLE/entropy_floor.h +++ b/src/entropy_floor/EAGLE/entropy_floor.h @@ -21,6 +21,7 @@ #include "adiabatic_index.h" #include "cosmology.h" +#include "equation_of_state.h" #include "hydro.h" #include "hydro_properties.h" #include "parser.h" diff --git a/src/entropy_floor/none/entropy_floor.h b/src/entropy_floor/none/entropy_floor.h index 6ce5319c8..8c89e08ab 100644 --- a/src/entropy_floor/none/entropy_floor.h +++ b/src/entropy_floor/none/entropy_floor.h @@ -64,6 +64,7 @@ static INLINE float entropy_floor( static INLINE float entropy_floor_temperature( const struct part *p, const struct cosmology *cosmo, const struct entropy_floor_properties *props) { + return 0.f; } -- GitLab From 21729e9126925d1afb8c1c793b1af95ee863e023 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 11:25:53 +0200 Subject: [PATCH 62/79] Add the entropy floor checks to the drift operation. --- src/cell.c | 17 +------- src/drift.h | 11 ++++- src/entropy_floor.h | 5 +++ src/hydro/Gadget2/hydro.h | 88 +++++++++++++++++++++++---------------- src/kick.h | 13 ++---- 5 files changed, 70 insertions(+), 64 deletions(-) diff --git a/src/cell.c b/src/cell.c index 1ba89859b..b52b51fea 100644 --- a/src/cell.c +++ b/src/cell.c @@ -4093,7 +4093,6 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) { const integertime_t ti_current = e->ti_current; struct part *const parts = c->hydro.parts; struct xpart *const xparts = c->hydro.xparts; - const struct entropy_floor_properties *floor = e->entropy_floor; float dx_max = 0.f, dx2_max = 0.f; float dx_max_sort = 0.0f, dx2_max_sort = 0.f; @@ -4184,20 +4183,8 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) { /* Drift... */ drift_part(p, xp, dt_drift, dt_kick_hydro, dt_kick_grav, dt_therm, - ti_old_part, ti_current); - - /* Limit imposed by the absolute minimum */ - const float u_minimum = e->hydro_properties->minimal_internal_energy; - const float u_part = - hydro_get_drifted_physical_internal_energy(p, e->cosmology); - const float u_final = max(u_minimum, u_part); - hydro_set_drifted_physical_internal_energy(p, e->cosmology, u_final); - - /* Limit imposed by the entropy floor */ - const float A_floor = entropy_floor(p, e->cosmology, floor); - const float A_part = hydro_get_drifted_physical_entropy(p, e->cosmology); - const float A_final = max(A_floor, A_part); - hydro_set_drifted_physical_entropy(p, e->cosmology, A_final); + ti_old_part, ti_current, e->cosmology, e->hydro_properties, + e->entropy_floor); /* Update the tracers properties */ tracers_after_drift(p, xp, e->internal_units, e->physical_constants, diff --git a/src/drift.h b/src/drift.h index faa8743a8..18f2ef998 100644 --- a/src/drift.h +++ b/src/drift.h @@ -27,7 +27,9 @@ #include "const.h" #include "debug.h" #include "dimension.h" +#include "entropy_floor.h" #include "hydro.h" +#include "hydro_properties.h" #include "part.h" #include "stars.h" @@ -71,11 +73,16 @@ __attribute__((always_inline)) INLINE static void drift_gpart( * @param dt_therm The drift time-step for thermodynamic quantities. * @param ti_old Integer start of time-step (for debugging checks). * @param ti_current Integer end of time-step (for debugging checks). + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void drift_part( struct part *restrict p, struct xpart *restrict xp, double dt_drift, double dt_kick_hydro, double dt_kick_grav, double dt_therm, - integertime_t ti_old, integertime_t ti_current) { + integertime_t ti_old, integertime_t ti_current, + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor) { #ifdef SWIFT_DEBUG_CHECKS if (p->ti_drift != ti_old) @@ -102,7 +109,7 @@ __attribute__((always_inline)) INLINE static void drift_part( p->v[2] += xp->a_grav[2] * dt_kick_grav; /* Predict the values of the extra fields */ - hydro_predict_extra(p, xp, dt_drift, dt_therm); + hydro_predict_extra(p, xp, dt_drift, dt_therm, cosmo, hydro_props, floor); /* Compute offsets since last cell construction */ for (int k = 0; k < 3; k++) { diff --git a/src/entropy_floor.h b/src/entropy_floor.h index 9f2e97ccc..1821f7a25 100644 --- a/src/entropy_floor.h +++ b/src/entropy_floor.h @@ -31,6 +31,11 @@ #include "error.h" #include "inline.h" +/* Pre-declarations to avoid cyclic inclusions */ +static float hydro_get_physical_density(const struct part *restrict p, + const struct cosmology *cosmo); +static float hydro_get_comoving_density(const struct part *restrict p); + /* Import the right entropy floor definition */ #if defined(ENTROPY_FLOOR_NONE) #include "./entropy_floor/none/entropy_floor.h" diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 6fe3891cd..7abb388ed 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -35,6 +35,7 @@ #include "approx_math.h" #include "cosmology.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -672,6 +673,20 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( /* Re-set the entropy */ p->entropy = xp->entropy_full; + + /* 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); + + /* Divide the pressure by the density squared to get the SPH term */ + const float rho_inv = 1.f / p->rho; + const float P_over_rho2 = pressure * rho_inv * rho_inv; + + /* Update variables */ + p->force.soundspeed = soundspeed; + p->force.P_over_rho2 = P_over_rho2; } /** @@ -681,10 +696,27 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, const struct xpart *restrict xp, float dt_drift, - float dt_therm) { + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the entropy */ + p->entropy += p->entropy_dt * dt_therm; + + /* Check against entropy floor */ + const float floor = entropy_floor(p, cosmo, floor_props); + const float min_u = hydro_props->minimal_internal_energy; + const float min_A = + gas_entropy_from_internal_energy(p->rho * cosmo->a3_inv, min_u); + + p->entropy = max(p->entropy, floor); + p->entropy = max(p->entropy, min_A); const float h_inv = 1.f / p->h; @@ -702,16 +734,6 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( else p->rho *= expf(w2); - /* Predict the entropy */ -#ifdef SWIFT_DEBUG_CHECKS - if (p->entropy + p->entropy_dt * dt_therm <= 0) - error( - "Negative entropy for particle id %llu old entropy %.e d_entropy %.e " - "entropy_dt %.e dt therm %.e", - p->id, p->entropy, p->entropy_dt * dt_therm, p->entropy_dt, dt_therm); -#endif - p->entropy += p->entropy_dt * dt_therm; - /* Re-compute the pressure */ const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); @@ -759,37 +781,29 @@ __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_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) { - - /* Do not decrease the entropy by more than a factor of 2 */ - if (dt_therm > 0. && p->entropy_dt * dt_therm < -0.5f * xp->entropy_full) { - p->entropy_dt = -0.5f * xp->entropy_full / dt_therm; - } - xp->entropy_full += p->entropy_dt * dt_therm; + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { - /* Apply the minimal energy limit */ - const float physical_density = p->rho * cosmo->a3_inv; - const float min_physical_energy = hydro_props->minimal_internal_energy; - const float min_physical_entropy = - gas_entropy_from_internal_energy(physical_density, min_physical_energy); - const float min_comoving_entropy = min_physical_entropy; /* A' = A */ - if (xp->entropy_full < min_comoving_entropy) { - xp->entropy_full = min_comoving_entropy; - p->entropy_dt = 0.f; - } + /* Integrate the entropy forward in time */ + const float delta_entropy = p->entropy_dt * dt_therm; - /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, xp->entropy_full); + /* Do not decrease the entropy by more than a factor of 2 */ + xp->entropy_full = + max(xp->entropy_full + delta_entropy, 0.5f * xp->entropy_full); - /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); + /* Check against entropy floor */ + const float floor = entropy_floor(p, cosmo, floor_props); + const float min_u = hydro_props->minimal_internal_energy; + const float min_A = + gas_entropy_from_internal_energy(p->rho * cosmo->a3_inv, min_u); - /* Divide the pressure by the density squared to get the SPH term */ - const float rho_inv = 1.f / p->rho; - const float P_over_rho2 = pressure * rho_inv * rho_inv; + /* Take highest of both limits */ + const float entropy_min = max(min_A, floor); - p->force.soundspeed = soundspeed; - p->force.P_over_rho2 = P_over_rho2; + if (xp->entropy_full < entropy_min) { + xp->entropy_full = entropy_min; + p->entropy_dt = 0.f; + } } /** diff --git a/src/kick.h b/src/kick.h index f2085bf1f..730dfebbd 100644 --- a/src/kick.h +++ b/src/kick.h @@ -80,8 +80,8 @@ __attribute__((always_inline)) INLINE static void kick_part( struct part *restrict p, struct xpart *restrict xp, double dt_kick_hydro, double dt_kick_grav, double dt_kick_therm, double dt_kick_corr, const struct cosmology *cosmo, const struct hydro_props *hydro_props, - const struct entropy_floor_properties *entropy_floor_props, - integertime_t ti_start, integertime_t ti_end) { + const struct entropy_floor_properties *floor_props, integertime_t ti_start, + integertime_t ti_end) { #ifdef SWIFT_DEBUG_CHECKS if (p->ti_kick != ti_start) @@ -114,15 +114,8 @@ __attribute__((always_inline)) INLINE static void kick_part( /* Extra kick work */ hydro_kick_extra(p, xp, dt_kick_therm, dt_kick_grav, dt_kick_hydro, - dt_kick_corr, cosmo, hydro_props); + dt_kick_corr, cosmo, hydro_props, floor_props); if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt_kick_grav); - - /* Verify that the particle is not below the entropy floor */ - const float floor = entropy_floor(p, cosmo, entropy_floor_props); - if (hydro_get_physical_entropy(p, xp, cosmo) < floor) { - hydro_set_physical_entropy(p, xp, cosmo, floor); - hydro_set_physical_internal_energy_dt(p, cosmo, 0.f); - } } /** -- GitLab From 525e68aec903c9a81e74ffe9c973c2d59bc396a4 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 11:32:52 +0200 Subject: [PATCH 63/79] Simplified the EAGLE cooling to not attempt doing the newton scheme. --- src/cooling/EAGLE/cooling.c | 41 ++++-------------------------- src/cooling/EAGLE/cooling_struct.h | 3 --- 2 files changed, 5 insertions(+), 39 deletions(-) diff --git a/src/cooling/EAGLE/cooling.c b/src/cooling/EAGLE/cooling.c index 4c7266e7c..8e9255a55 100644 --- a/src/cooling/EAGLE/cooling.c +++ b/src/cooling/EAGLE/cooling.c @@ -587,38 +587,11 @@ void cooling_cool_part(const struct phys_const *phys_const, } else { - int bisection_flag = 1; - - // MATTHIEU: TO DO restore the Newton-Raphson scheme - if (0 && cooling->newton_flag) { - - /* Ok, try a Newton-Raphson scheme instead */ - double log_u_final_cgs = - newton_iter(log(u_0_cgs), u_0_cgs, n_H_index, d_n_H, He_index, d_He, - Lambda_He_reion_cgs, p, cosmo, cooling, phys_const, - abundance_ratio, dt_cgs, &bisection_flag); - - /* Check if newton scheme sent us to a higher energy despite being in - a cooling regime If it did try newton scheme with a better guess. - (Guess internal energy near equilibrium solution). */ - if (LambdaNet_cgs < 0 && log_u_final_cgs > log(u_0_cgs)) { - bisection_flag = 0; - log_u_final_cgs = - newton_iter(newton_log_u_guess_cgs, u_0_cgs, n_H_index, d_n_H, - He_index, d_He, Lambda_He_reion_cgs, p, cosmo, cooling, - phys_const, abundance_ratio, dt_cgs, &bisection_flag); - } - - u_final_cgs = exp(log_u_final_cgs); - } - - /* Alright, all else failed, let's bisect */ - if (bisection_flag || !(cooling->newton_flag)) { - u_final_cgs = - bisection_iter(u_0_cgs, n_H_cgs, cosmo->z, n_H_index, d_n_H, He_index, - d_He, Lambda_He_reion_cgs, ratefact_cgs, cooling, - abundance_ratio, dt_cgs, p->id); - } + /* Otherwise, go the bisection route. */ + u_final_cgs = + bisection_iter(u_0_cgs, n_H_cgs, cosmo->z, n_H_index, d_n_H, He_index, + d_He, Lambda_He_reion_cgs, ratefact_cgs, cooling, + abundance_ratio, dt_cgs, p->id); } /* Convert back to internal units */ @@ -923,10 +896,6 @@ void cooling_init_backend(struct swift_params *parameter_file, /* set previous_z_index and to last value of redshift table*/ cooling->previous_z_index = eagle_cooling_N_redshifts - 2; - - /* Check if we are running with the newton scheme */ - cooling->newton_flag = parser_get_opt_param_int( - parameter_file, "EAGLECooling:newton_integration", 0); } /** diff --git a/src/cooling/EAGLE/cooling_struct.h b/src/cooling/EAGLE/cooling_struct.h index 88e49036f..f62b199a5 100644 --- a/src/cooling/EAGLE/cooling_struct.h +++ b/src/cooling/EAGLE/cooling_struct.h @@ -126,9 +126,6 @@ struct cooling_function_data { /*! Index of the previous tables along the redshift index of the tables */ int previous_z_index; - - /*! Are we doing Newton-Raphson iterations? */ - int newton_flag; }; /** -- GitLab From befb9343381eb02b68b60402beb21f438ec84089 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 11:59:46 +0200 Subject: [PATCH 64/79] In the EAGLE cooling limit the initial energy to also be above the floor. --- src/cooling/EAGLE/cooling.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/cooling/EAGLE/cooling.c b/src/cooling/EAGLE/cooling.c index 8e9255a55..ee4be9b1a 100644 --- a/src/cooling/EAGLE/cooling.c +++ b/src/cooling/EAGLE/cooling.c @@ -498,14 +498,12 @@ void cooling_cool_part(const struct phys_const *phys_const, #endif /* Get internal energy at the last kick step */ - /* MATTHIEU: Is this really what we want? Shouldn't it be the drifted energy? - */ const float u_start = hydro_get_physical_internal_energy(p, xp, cosmo); /* Get the change in internal energy due to hydro forces */ const float hydro_du_dt = hydro_get_physical_internal_energy_dt(p, cosmo); - /* Get internal energy at the end of the next kick step (assuming dt does not + /* Get internal energy at the end of the step (assuming dt does not * increase) */ double u_0 = (u_start + hydro_du_dt * dt_therm); @@ -605,13 +603,13 @@ void cooling_cool_part(const struct phys_const *phys_const, /* Limit imposed by the entropy floor */ const double A_floor = entropy_floor(p, cosmo, floor_props); - const double rho = hydro_get_physical_density(p, cosmo); - const double u_floor = gas_internal_energy_from_entropy(rho, A_floor); + const double rho_physical = hydro_get_physical_density(p, cosmo); + const double u_floor = gas_internal_energy_from_entropy(rho_physical, A_floor); u_final = max(u_final, u_floor); /* Expected change in energy over the next kick step (assuming no change in dt) */ - const double delta_u = u_final - u_start; + const double delta_u = u_final - max(u_start, u_floor); /* Turn this into a rate of change (including cosmology term) */ const float cooling_du_dt = delta_u / dt_therm; -- GitLab From f3314cda50c49a8115b54c02419dd5486185bb66 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 12:04:02 +0200 Subject: [PATCH 65/79] Removed unused function in the Gadget2 hydro scheme. --- src/hydro/Gadget2/hydro.h | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 7abb388ed..797d9dcb3 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -349,40 +349,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->entropy_full = entropy; } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical internal energy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - /* Note there is no conversion from physical to comoving entropy */ - p->entropy = entropy; - - /* Now recompute the extra quantities */ - - /* Inverse of the co-moving density */ - const float rho_inv = 1.f / p->rho; - - /* Compute the pressure */ - 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); - - /* Divide the pressure by the density squared to get the SPH term */ - const float P_over_rho2 = pressure * rho_inv * rho_inv; - - /* Update variables. */ - p->force.P_over_rho2 = P_over_rho2; - p->force.soundspeed = soundspeed; -} - /** * @brief Sets the physical internal energy of a particle * -- GitLab From d3c73b72032c4807e5bc2dc039db001bc2c4395c Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 12:05:34 +0200 Subject: [PATCH 66/79] Revert "Updated the other hydro schemes." This reverts commit 8fc5f1a95858e83aacee1d1b03b86203091fd552. --- src/hydro/Default/hydro.h | 21 ----------- src/hydro/GizmoMFM/hydro.h | 14 -------- src/hydro/GizmoMFV/hydro.h | 14 -------- src/hydro/Planetary/hydro.h | 30 ---------------- src/hydro/PressureEnergy/hydro.h | 26 -------------- .../PressureEnergyMorrisMonaghanAV/hydro.h | 26 -------------- src/hydro/PressureEntropy/hydro.h | 36 ------------------- 7 files changed, 167 deletions(-) diff --git a/src/hydro/Default/hydro.h b/src/hydro/Default/hydro.h index 7db6efd60..175265dd4 100644 --- a/src/hydro/Default/hydro.h +++ b/src/hydro/Default/hydro.h @@ -335,27 +335,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical entropy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - /* Note there is no conversion from physical to comoving entropy */ - const float comoving_entropy = entropy; - - p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); - - /* Now recompute the extra quantities */ - error("Matthieu: This needs implementing"); -} - /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/GizmoMFM/hydro.h b/src/hydro/GizmoMFM/hydro.h index 5a33d5518..3456e6f9e 100644 --- a/src/hydro/GizmoMFM/hydro.h +++ b/src/hydro/GizmoMFM/hydro.h @@ -987,20 +987,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( error("Needs implementing"); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical internal energy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part* p, - const struct cosmology* cosmo, - const float entropy) { - error("Needs implementing"); -} - /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/GizmoMFV/hydro.h b/src/hydro/GizmoMFV/hydro.h index 80e9be47e..526d84289 100644 --- a/src/hydro/GizmoMFV/hydro.h +++ b/src/hydro/GizmoMFV/hydro.h @@ -1061,20 +1061,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( error("Needs implementing"); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical internal energy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part* p, - const struct cosmology* cosmo, - const float entropy) { - error("Needs implementing"); -} - /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/Planetary/hydro.h b/src/hydro/Planetary/hydro.h index 99960b7c3..e03b307bc 100644 --- a/src/hydro/Planetary/hydro.h +++ b/src/hydro/Planetary/hydro.h @@ -378,36 +378,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( gas_internal_energy_from_entropy(p->rho, comoving_entropy, p->mat_id); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical entropy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - /* Note there is no conversion from physical to comoving entropy */ - const float comoving_entropy = entropy; - - p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy, p->mat_id); - - /* Now recompute the extra quantities */ - - /* Compute the sound speed */ - const float pressure = - gas_pressure_from_internal_energy(p->rho, p->u, p->mat_id); - const float soundspeed = - gas_soundspeed_from_pressure(p->rho, pressure, p->mat_id); - - /* Update variables. */ - p->force.pressure = pressure; - p->force.soundspeed = soundspeed; -} - /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index d4fc2cd07..3fe3c805f 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -379,32 +379,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical entropy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - /* Note there is no conversion from physical to comoving entropy */ - const float comoving_entropy = entropy; - - p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); - - /* Now recompute the extra quantities */ - - /* Compute the sound speed */ - const float soundspeed = hydro_get_comoving_soundspeed(p); - - /* Update variables. */ - p->force.soundspeed = soundspeed; -} - /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h index a54db28f1..be6a789eb 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h @@ -376,32 +376,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical entropy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - /* Note there is no conversion from physical to comoving entropy */ - const float comoving_entropy = entropy; - - p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); - - /* Now recompute the extra quantities */ - - /* Compute the sound speed */ - const float soundspeed = hydro_get_comoving_soundspeed(p); - - /* Update variables. */ - p->force.soundspeed = soundspeed; -} - /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/PressureEntropy/hydro.h b/src/hydro/PressureEntropy/hydro.h index f38194901..578bebf63 100644 --- a/src/hydro/PressureEntropy/hydro.h +++ b/src/hydro/PressureEntropy/hydro.h @@ -373,42 +373,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->entropy_full = entropy; } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical internal energy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - error("Matthieu: Check that this is correct when running P-E"); - - /* Note there is no conversion from physical to comoving entropy */ - p->entropy = entropy; - - /* Now recompute the extra quantities */ - - /* Inverse of the co-moving density */ - const float rho_inv = 1.f / p->rho; - - /* Compute the pressure */ - 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); - - /* Divide the pressure by the density squared to get the SPH term */ - const float P_over_rho2 = pressure * rho_inv * rho_inv; - - /* Update variables. */ - p->force.P_over_rho2 = P_over_rho2; - p->force.soundspeed = soundspeed; -} - /** * @brief Computes the hydro time-step of a given particle * -- GitLab From b3df603f5a6e21668ee257728a9e6f1a2fa7ebc3 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 12:07:22 +0200 Subject: [PATCH 67/79] Removed unnecessary function in the Minimal and AnarchyPU hydro schemes. --- src/hydro/AnarchyPU/hydro.h | 26 -------------------------- src/hydro/Minimal/hydro.h | 28 ---------------------------- 2 files changed, 54 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 0ed117020..0ac52165e 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -380,32 +380,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical entropy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - /* Note there is no conversion from physical to comoving entropy */ - const float comoving_entropy = entropy; - - p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); - - /* Now recompute the extra quantities */ - - /* Compute the sound speed */ - const float soundspeed = hydro_get_comoving_soundspeed(p); - - /* Update variables. */ - p->force.soundspeed = soundspeed; -} - /** * @brief Sets the physical internal energy of a particle * diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index ce7a0e7b8..e2fd00695 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -354,34 +354,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_physical_entropy( xp->u_full = gas_internal_energy_from_entropy(p->rho, comoving_entropy); } -/** - * @brief Sets the drifted physical entropy of a particle - * - * @param p The particle of interest. - * @param cosmo Cosmology data structure - * @param entropy The physical entropy - */ -__attribute__((always_inline)) INLINE static void -hydro_set_drifted_physical_entropy(struct part *p, - const struct cosmology *cosmo, - const float entropy) { - - /* Note there is no conversion from physical to comoving entropy */ - const float comoving_entropy = entropy; - - p->u = gas_internal_energy_from_entropy(p->rho, comoving_entropy); - - /* Now recompute the extra quantities */ - - /* Compute the sound speed */ - const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); - - /* Update variables. */ - p->force.pressure = pressure; - p->force.soundspeed = soundspeed; -} - /** * @brief Sets the physical internal energy of a particle * -- GitLab From d3182adcba3293a8cddc00a24db3eaea9f8f9181 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 14:18:51 +0200 Subject: [PATCH 68/79] Update the minimal hydro scheme to also use the new signatures. --- src/hydro/Gadget2/hydro.h | 15 +++++--- src/hydro/Minimal/hydro.h | 75 ++++++++++++++++++++++++++------------- 2 files changed, 61 insertions(+), 29 deletions(-) diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index 797d9dcb3..e89396182 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -676,12 +676,14 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->entropy += p->entropy_dt * dt_therm; /* Check against entropy floor */ - const float floor = entropy_floor(p, cosmo, floor_props); + const float floor_A = entropy_floor(p, cosmo, floor_props); + + /* Check against absolute minimum */ const float min_u = hydro_props->minimal_internal_energy; const float min_A = gas_entropy_from_internal_energy(p->rho * cosmo->a3_inv, min_u); - p->entropy = max(p->entropy, floor); + p->entropy = max(p->entropy, floor_A); p->entropy = max(p->entropy, min_A); const float h_inv = 1.f / p->h; @@ -742,7 +744,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_hydro The time-step for this kick (for hydro forces) * @param dt_kick_corr The time-step for this kick (for correction of the kick) * @param cosmo The cosmological model. - * @param hydro_props The constants used in the scheme + * @param hydro_props The constants used in the scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt_therm, @@ -758,13 +761,15 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( max(xp->entropy_full + delta_entropy, 0.5f * xp->entropy_full); /* Check against entropy floor */ - const float floor = entropy_floor(p, cosmo, floor_props); + const float floor_A = entropy_floor(p, cosmo, floor_props); + + /* Check against absolute minimum */ const float min_u = hydro_props->minimal_internal_energy; const float min_A = gas_entropy_from_internal_energy(p->rho * cosmo->a3_inv, min_u); /* Take highest of both limits */ - const float entropy_min = max(min_A, floor); + const float entropy_min = max(min_A, floor_A); if (xp->entropy_full < entropy_min) { xp->entropy_full = entropy_min; diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index e2fd00695..13366a29e 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -37,6 +37,7 @@ #include "approx_math.h" #include "cosmology.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -628,6 +629,16 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( /* Re-set the entropy */ p->u = xp->u_full; + + /* Re-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_pressure(p->rho, pressure); + + /* Update variables */ + p->force.pressure = pressure; + p->force.soundspeed = soundspeed; } /** @@ -643,10 +654,29 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle. * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, const struct xpart *restrict xp, float dt_drift, - float dt_therm) { + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the internal energy */ + p->u += p->u_dt * dt_therm; + + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); + + /* Check agains absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + + p->u = max(p->u, floor_u); + p->u = max(p->u, min_u); const float h_inv = 1.f / p->h; @@ -664,9 +694,6 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( else p->rho *= expf(w2); - /* Predict the internal energy */ - p->u += p->u_dt * dt_therm; - /* Compute the new pressure */ const float pressure = gas_pressure_from_internal_energy(p->rho, p->u); @@ -708,36 +735,36 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_hydro The time-step for this kick (for hydro quantities). * @param dt_kick_corr The time-step for this kick (for gravity corrections). * @param cosmo The cosmological model. - * @param hydro_props The constants used in the scheme + * @param hydro_props The constants used in the scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) { + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Integrate the internal energy forward in time */ + const float delta_u = p->u_dt * dt_therm; /* Do not decrease the energy by more than a factor of 2*/ - if (dt_therm > 0. && p->u_dt * dt_therm < -0.5f * xp->u_full) { - p->u_dt = -0.5f * xp->u_full / dt_therm; - } - xp->u_full += p->u_dt * dt_therm; + xp->u_full = max(xp->u_full + delta_u, 0.5f * xp->u_full); - /* Apply the minimal energy limit */ - const float min_comoving_energy = - hydro_props->minimal_internal_energy / cosmo->a_factor_internal_energy; - if (xp->u_full < min_comoving_energy) { - xp->u_full = min_comoving_energy; - p->u_dt = 0.f; - } + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); - /* Compute the pressure */ - const float pressure = gas_pressure_from_internal_energy(p->rho, xp->u_full); + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; - /* Compute the sound speed */ - const float soundspeed = - gas_soundspeed_from_internal_energy(p->rho, xp->u_full); + /* Take highest of both limits */ + const float energy_min = max(min_u, floor_u); - p->force.pressure = pressure; - p->force.soundspeed = soundspeed; + if (xp->u_full < energy_min) { + xp->u_full = energy_min; + p->u_dt = 0.f; + } } /** -- GitLab From 0c5ede868fcb97cd0ace2ac125f6ca2761303cfa Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 14:59:17 +0200 Subject: [PATCH 69/79] Style improvement in hydro_prepare_force() of the Anarchy-PU scheme, --- src/hydro/AnarchyPU/hydro.h | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 0ac52165e..ac755759d 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -696,16 +696,17 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* We use in this function that h is the radius of support */ const float kernel_support_physical = p->h * cosmo->a * kernel_gamma; + const float kernel_support_physical_inv = 1.f / kernel_support_physical; const float v_sig_physical = p->viscosity.v_sig * cosmo->a_factor_sound_speed; const float soundspeed_physical = hydro_get_physical_soundspeed(p, cosmo); const float sound_crossing_time_inverse = - soundspeed_physical / kernel_support_physical; + soundspeed_physical * kernel_support_physical_inv; /* Construct time differential of div.v implicitly following the ANARCHY spec */ - float div_v_dt = + const float div_v_dt = dt_alpha == 0.f ? 0.f : (p->viscosity.div_v - p->viscosity.div_v_previous_step) / dt_alpha; @@ -734,9 +735,9 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( hydro_props->viscosity.length); } - if (p->viscosity.alpha < hydro_props->viscosity.alpha_min) { - p->viscosity.alpha = hydro_props->viscosity.alpha_min; - } + /* Check that we did not hit the minimum */ + p->viscosity.alpha = + max(p->viscosity.alpha, hydro_props->viscosity.alpha_min); /* Set our old div_v to the one for the next loop */ p->viscosity.div_v_previous_step = p->viscosity.div_v; @@ -744,18 +745,20 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Now for the diffusive alpha */ const float diffusion_timescale_physical_inverse = - v_sig_physical / kernel_support_physical; + v_sig_physical * kernel_support_physical_inv; + + const float sqrt_u_inv = 1.f / sqrtf(p->u); - const float sqrt_u = sqrtf(p->u); /* Calculate initial value of alpha dt before bounding */ /* Evolution term: following Schaller+ 2015. This is made up of several - cosmology factors: physical h, sound speed from u / sqrt(u), and the - 1 / a^2 coming from the laplace operator. */ + cosmology factors: physical smoothing length, sound speed from laplace(u) / + sqrt(u), and the 1 / a^2 coming from the laplace operator. */ float alpha_diff_dt = hydro_props->diffusion.beta * kernel_support_physical * - p->diffusion.laplace_u * cosmo->a_factor_sound_speed / - (sqrt_u * cosmo->a * cosmo->a); + p->diffusion.laplace_u * cosmo->a_factor_sound_speed * + sqrt_u_inv * cosmo->a2_inv; + /* Decay term: not documented in Schaller+ 2015 but was present - * in the original EAGLE code and in Schaye+ 2015 */ + * in the original EAGLE code and in appendix of Schaye+ 2015 */ alpha_diff_dt -= (p->diffusion.alpha - hydro_props->diffusion.alpha_min) * diffusion_timescale_physical_inverse; @@ -763,11 +766,10 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( new_diffusion_alpha += alpha_diff_dt * dt_alpha; /* Consistency checks to ensure min < alpha < max */ - if (new_diffusion_alpha > hydro_props->diffusion.alpha_max) { - new_diffusion_alpha = hydro_props->diffusion.alpha_max; - } else if (new_diffusion_alpha < hydro_props->diffusion.alpha_min) { - new_diffusion_alpha = hydro_props->diffusion.alpha_min; - } + new_diffusion_alpha = + min(new_diffusion_alpha, hydro_props->diffusion.alpha_max); + new_diffusion_alpha = + max(new_diffusion_alpha, hydro_props->diffusion.alpha_min); p->diffusion.alpha = new_diffusion_alpha; } -- GitLab From b7aafa1ad81fef8192b107069492844b60f4987f Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 18:28:15 +0200 Subject: [PATCH 70/79] Backed up the Newton cooling scheme into a separate file. --- src/cooling/EAGLE/newton_cooling.c | 678 +++++++++++++++++++++++++++++ 1 file changed, 678 insertions(+) create mode 100644 src/cooling/EAGLE/newton_cooling.c diff --git a/src/cooling/EAGLE/newton_cooling.c b/src/cooling/EAGLE/newton_cooling.c new file mode 100644 index 000000000..d434c2de0 --- /dev/null +++ b/src/cooling/EAGLE/newton_cooling.c @@ -0,0 +1,678 @@ +/** + * @file Backup file containing the now-defunct Newton integration scheme + * for the cooling. + */ + +/** + * @brief Computes the log_10 of the temperature corresponding to a given + * internal energy, hydrogen number density, Helium fraction and redshift. + * + * Note that the redshift is implicitly passed in via the currently loaded + * tables in the #cooling_function_data. + * + * For the low-z case, we interpolate the flattened 4D table 'u_to_temp' that + * is arranged in the following way: + * - 1st dim: redshift, length = eagle_cooling_N_loaded_redshifts + * - 2nd dim: Hydrogen density, length = eagle_cooling_N_density + * - 3rd dim: Helium fraction, length = eagle_cooling_N_He_frac + * - 4th dim: Internal energy, length = eagle_cooling_N_temperature + * + * For the high-z case, we interpolate the flattened 3D table 'u_to_temp' that + * is arranged in the following way: + * - 1st dim: Hydrogen density, length = eagle_cooling_N_density + * - 2nd dim: Helium fraction, length = eagle_cooling_N_He_frac + * - 3rd dim: Internal energy, length = eagle_cooling_N_temperature + * + * @param log_10_u_cgs Log base 10 of internal energy in cgs. + * @param redshift Current redshift. + * @param n_H_index Index along the Hydrogen density dimension. + * @param He_index Index along the Helium fraction dimension. + * @param d_n_H Offset between Hydrogen density and table[n_H_index]. + * @param d_He Offset between helium fraction and table[He_index]. + * @param cooling #cooling_function_data structure. + * + * @param compute_dT_du Do we want to compute dT/du ? + * @param dT_du (return) The value of dT/du + * + * @return log_10 of the temperature. + */ +__attribute__((always_inline)) INLINE double eagle_convert_u_to_temp( + const double log_10_u_cgs, const float redshift, const int compute_dT_du, + float *dT_du, int n_H_index, int He_index, float d_n_H, float d_He, + const struct cooling_function_data *restrict cooling) { + + /* Get index of u along the internal energy axis */ + int u_index; + float d_u; + get_index_1d(cooling->Therm, eagle_cooling_N_temperature, log_10_u_cgs, + &u_index, &d_u); + + /* Interpolate temperature table to return temperature for current + * internal energy (use 3D interpolation for high redshift table, + * otherwise 4D) */ + float log_10_T; + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { + + log_10_T = interpolation_3d(cooling->table.temperature, /* */ + n_H_index, He_index, u_index, /* */ + d_n_H, d_He, d_u, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + } else { + + log_10_T = + interpolation_4d(cooling->table.temperature, /* */ + /*z_index=*/0, n_H_index, He_index, u_index, /* */ + cooling->dz, d_n_H, d_He, d_u, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + } + + if (compute_dT_du) { + + float log_10_T_high, log_10_T_low; + + /* Interpolate temperature table to return temperature for internal energy + * at grid point above current internal energy for computing dT_du used for + * calculation of dlambda_du in cooling.c (use 3D interpolation for high + * redshift table, otherwise 4D) */ + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { + + log_10_T_high = interpolation_3d(cooling->table.temperature, /* */ + n_H_index, He_index, u_index, /* */ + d_n_H, d_He, /*delta_u=*/1.f, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + + } else { + + log_10_T_high = + interpolation_4d(cooling->table.temperature, /* */ + /*z_index=*/0, n_H_index, He_index, u_index, /* */ + cooling->dz, d_n_H, d_He, /*delta_u=*/1.f, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + } + + /* Interpolate temperature table to return temperature for internal energy + * at grid point below current internal energy for computing dT_du used for + * calculation of dlambda_du in cooling.c (use 3D interpolation for high + * redshift table, otherwise 4D) */ + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { + + log_10_T_low = interpolation_3d(cooling->table.temperature, /* */ + n_H_index, He_index, u_index, /* */ + d_n_H, d_He, /*delta_u=*/0.f, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + + } else { + + log_10_T_low = + interpolation_4d(cooling->table.temperature, /* */ + /*z_index=*/0, n_H_index, He_index, u_index, /* */ + cooling->dz, d_n_H, d_He, /*delta_u=*/0.f, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + } + + /* Calculate dT/du */ + const float delta_u = exp(cooling->Therm[u_index + 1] * M_LN10) - + exp(cooling->Therm[u_index] * M_LN10); + *dT_du = + (exp(M_LN10 * log_10_T_high) - exp(M_LN10 * log_10_T_low)) / delta_u; + } + + /* Special case for temperatures below the start of the table */ + if (u_index == 0 && d_u == 0.f) { + + /* The temperature is multiplied by u / 10^T[0] + * where T[0] is the first entry in the table */ + log_10_T += log_10_u_cgs - cooling->Temp[0]; + } + + return log_10_T; +} + + +/** + * @brief Computes the cooling rate corresponding to a given internal energy, + * hydrogen number density, Helium fraction, redshift and metallicity from + * all the possible channels. + * + * 1) Metal-free cooling: + * We interpolate the flattened 4D table 'H_and_He_net_heating' that is + * arranged in the following way: + * - 1st dim: redshift, length = eagle_cooling_N_loaded_redshifts + * - 2nd dim: Hydrogen density, length = eagle_cooling_N_density + * - 3rd dim: Helium fraction, length = eagle_cooling_N_He_frac + * - 4th dim: Internal energy, length = eagle_cooling_N_temperature + * + * 2) Electron abundance + * We compute the electron abundance by interpolating the flattened 4d table + * 'H_and_He_electron_abundance' that is arranged in the following way: + * - 1st dim: redshift, length = eagle_cooling_N_loaded_redshifts + * - 2nd dim: Hydrogen density, length = eagle_cooling_N_density + * - 3rd dim: Helium fraction, length = eagle_cooling_N_He_frac + * - 4th dim: Internal energy, length = eagle_cooling_N_temperature + * + * 3) Compton cooling is applied via the analytic formula. + * + * 4) Solar electron abudance + * We compute the solar electron abundance by interpolating the flattened 3d + * table 'solar_electron_abundance' that is arranged in the following way: + * - 1st dim: redshift, length = eagle_cooling_N_loaded_redshifts + * - 2nd dim: Hydrogen density, length = eagle_cooling_N_density + * - 3rd dim: Internal energy, length = eagle_cooling_N_temperature + * + * 5) Metal-line cooling + * For each tracked element we interpolate the flattened 4D table + * 'table_metals_net_heating' that is arrange in the following way: + * - 1st dim: element, length = eagle_cooling_N_metal + * - 2nd dim: redshift, length = eagle_cooling_N_loaded_redshifts + * - 3rd dim: Hydrogen density, length = eagle_cooling_N_density + * - 4th dim: Internal energy, length = eagle_cooling_N_temperature + * + * Note that this is a fake 4D interpolation as we do not interpolate + * along the 1st dimension. We just do this once per element. + * + * Since only the temperature changes when cooling a given particle, + * the redshift, hydrogen number density and helium fraction indices + * and offsets passed in. + * + * If the arguement dlambda_du is non-NULL, the routine also + * calculates derivative of cooling rate with respect to internal + * energy. + * + * If the argument element_lambda is non-NULL, the routine also + * returns the cooling rate per element in the array. + * + * @param log10_u_cgs Log base 10 of internal energy per unit mass in CGS units. + * @param redshift The current redshift + * @param n_H_cgs The Hydrogen number density in CGS units. + * @param solar_ratio Array of ratios of particle metal abundances + * to solar metal abundances + * + * @param n_H_index Particle hydrogen number density index + * @param d_n_H Particle hydrogen number density offset + * @param He_index Particle helium fraction index + * @param d_He Particle helium fraction offset + * @param cooling Cooling data structure + * + * @param dlambda_du (return) Derivative of the cooling rate with respect to u. + * @param element_lambda (return) Cooling rate from each element + * + * @return The cooling rate + */ +INLINE static double eagle_metal_cooling_rate( + double log10_u_cgs, double redshift, double n_H_cgs, + const float solar_ratio[chemistry_element_count + 2], int n_H_index, + float d_n_H, int He_index, float d_He, + const struct cooling_function_data *restrict cooling, double *dlambda_du, + double *element_lambda) { + + /* used for calculating dlambda_du */ + double temp_lambda_high = 0, temp_lambda_low = 0; + double h_plus_he_electron_abundance_high = 0; + double h_plus_he_electron_abundance_low = 0; + double solar_electron_abundance_high = 0; + double solar_electron_abundance_low = 0; + double elem_cool_low = 0, elem_cool_high = 0; + + /* We only need dT_du if dLambda_du is non-NULL */ + const int compute_dT_du = (dlambda_du != NULL) ? 1 : 0; + + /* Temperature */ + float dT_du = -1.f; + const double log_10_T = + eagle_convert_u_to_temp(log10_u_cgs, redshift, compute_dT_du, &dT_du, + n_H_index, He_index, d_n_H, d_He, cooling); + + /* Get index along temperature dimension of the tables */ + int T_index; + float d_T; + get_index_1d(cooling->Temp, eagle_cooling_N_temperature, log_10_T, &T_index, + &d_T); + + /* Difference between entries on the temperature table around u */ + const float delta_T = exp(M_LN10 * cooling->Temp[T_index + 1]) - + exp(M_LN10 * cooling->Temp[T_index]); + + /**********************/ + /* Metal-free cooling */ + /**********************/ + + double Lambda_free; + + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { + + /* If we're using the high redshift tables then we don't interpolate + * in redshift */ + Lambda_free = interpolation_3d(cooling->table.H_plus_He_heating, /* */ + n_H_index, He_index, T_index, /* */ + d_n_H, d_He, d_T, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du. Pass in NULL pointer for + * dlambda_du in order to skip */ + if (dlambda_du != NULL) { + temp_lambda_high = interpolation_3d( + cooling->table.H_plus_He_heating, n_H_index, He_index, T_index, d_n_h, + d_He, 1.f, cooling->N_nH, cooling->N_He, cooling->N_Temp); + temp_lambda_low = interpolation_3d( + cooling->table.H_plus_He_heating, n_H_index, He_index, T_index, d_n_h, + d_He, 0.f, cooling->N_nH, cooling->N_He, cooling->N_Temp); + } + + } else { + + /* Using normal tables, have to interpolate in redshift */ + Lambda_free = + interpolation_4d(cooling->table.H_plus_He_heating, /* */ + /*z_index=*/0, n_H_index, He_index, T_index, /* */ + cooling->dz, d_n_H, d_He, d_T, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + if (dlambda_du != NULL) { + temp_lambda_high = + interpolation_4d(cooling->table.H_plus_He_heating, 0, n_H_index, + He_index, T_index, cooling->dz, d_n_h, d_He, 1.f, 2, + cooling->N_nH, cooling->N_He, cooling->N_Temp); + temp_lambda_low = + interpolation_4d(cooling->table.H_plus_He_heating, 0, n_H_index, + He_index, T_index, cooling->dz, d_n_h, d_He, 0.f, 2, + cooling->N_nH, cooling->N_He, cooling->N_Temp); + } + } + + if (dlambda_du != NULL) { + *dlambda_du += (temp_lambda_high - temp_lambda_low) / delta_T * dT_du; + } + + /* If we're testing cooling rate contributions write to array */ + if (element_lambda != NULL) { + element_lambda[0] = Lambda_free; + } + + /**********************/ + /* Electron abundance */ + /**********************/ + + double H_plus_He_electron_abundance; + + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { + + H_plus_He_electron_abundance = + interpolation_3d(cooling->table.H_plus_He_electron_abundance, /* */ + n_H_index, He_index, T_index, /* */ + d_n_H, d_He, d_T, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du. Pass in NULL pointer for + * dlambda_du in order to skip */ + + h_plus_he_electron_abundance_high = + interpolation_3d(cooling->table.H_plus_He_electron_abundance, n_H_index, + He_index, T_index, d_n_h, d_He, 1.f, cooling->N_nH, + cooling->N_He, cooling->N_Temp); + h_plus_he_electron_abundance_low = + interpolation_3d(cooling->table.H_plus_He_electron_abundance, n_H_index, + He_index, T_index, d_n_h, d_He, 0.f, cooling->N_nH, + cooling->N_He, cooling->N_Temp); + + } else { + + H_plus_He_electron_abundance = + interpolation_4d(cooling->table.H_plus_He_electron_abundance, /* */ + /*z_index=*/0, n_H_index, He_index, T_index, /* */ + cooling->dz, d_n_H, d_He, d_T, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_He_frac, /* */ + eagle_cooling_N_temperature); /* */ + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + h_plus_he_electron_abundance_high = + interpolation_4d(cooling->table.H_plus_He_electron_abundance, 0, + n_H_index, He_index, T_index, cooling->dz, d_n_h, d_He, + 1.f, 2, cooling->N_nH, cooling->N_He, cooling->N_Temp); + h_plus_he_electron_abundance_low = + interpolation_4d(cooling->table.H_plus_He_electron_abundance, 0, + n_H_index, He_index, T_index, cooling->dz, d_n_h, d_He, + 0.f, 2, cooling->N_nH, cooling->N_He, cooling->N_Temp); + } + + /**********************/ + /* Compton cooling */ + /**********************/ + + double Lambda_Compton = 0.; + + /* Do we need to add the inverse Compton cooling? */ + /* It is *not* stored in the tables before re-ionisation */ + if ((redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) || + (redshift > cooling->H_reion_z)) { + + const double T = exp10(log_10_T); + + /* Note the minus sign */ + Lambda_Compton -= eagle_Compton_cooling_rate(cooling, redshift, n_H_cgs, T, + H_plus_He_electron_abundance); + } + + /* If we're testing cooling rate contributions write to array */ + if (element_lambda != NULL) { + element_lambda[1] = Lambda_Compton; + } + + /*******************************/ + /* Solar electron abundance */ + /*******************************/ + + double solar_electron_abundance; + + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { + + /* If we're using the high redshift tables then we don't interpolate + * in redshift */ + solar_electron_abundance = + interpolation_2d(cooling->table.electron_abundance, /* */ + n_H_index, T_index, /* */ + d_n_H, d_T, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_temperature); /* */ + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + if (dlambda_du != NULL) { + solar_electron_abundance_high = + interpolation_2d(cooling->table.electron_abundance, n_H_index, + T_index, d_n_h, 1.f, cooling->N_nH, cooling->N_Temp); + solar_electron_abundance_low = + interpolation_2d(cooling->table.electron_abundance, n_H_index, + T_index, d_n_h, 0.f, cooling->N_nH, cooling->N_Temp); + } + + } else { + + /* Using normal tables, have to interpolate in redshift */ + solar_electron_abundance = + interpolation_3d(cooling->table.electron_abundance, /* */ + /*z_index=*/0, n_H_index, T_index, /* */ + cooling->dz, d_n_H, d_T, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_temperature); /* */ + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + if (dlambda_du != NULL) { + solar_electron_abundance_high = interpolation_3d( + cooling->table.electron_abundance, 0, n_H_index, T_index, cooling->dz, + d_n_h, 1.f, 2, cooling->N_nH, cooling->N_Temp); + solar_electron_abundance_low = interpolation_3d( + cooling->table.electron_abundance, 0, n_H_index, T_index, cooling->dz, + d_n_h, 0.f, 2, cooling->N_nH, cooling->N_Temp); + } + + const double electron_abundance_ratio = + H_plus_He_electron_abundance / solar_electron_abundance; + + /**********************/ + /* Metal-line cooling */ + /**********************/ + + /* for each element the cooling rate is multiplied by the ratio of H, He + * electron abundance to solar electron abundance then by the ratio of the + * particle metal abundance to solar metal abundance. */ + + double lambda_metal[eagle_cooling_N_metal + 2] = {0.}; + + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { + + /* Loop over the metals (ignore H and He) */ + for (int elem = 2; elem < eagle_cooling_N_metal + 2; elem++) { + + if (solar_ratio[elem] > 0.) { + + /* Note that we do not interpolate along the x-axis + * (element dimension) */ + lambda_metal[elem] = + interpolation_3d_no_x(cooling->table.metal_heating, /* */ + elem - 2, n_H_index, T_index, /* */ + /*delta_elem=*/0.f, d_n_H, d_T, /* */ + eagle_cooling_N_metal, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_temperature); /* */ + + lambda_metal[elem] *= electron_abundance_ratio; + lambda_metal[elem] *= solar_ratio[elem]; + } + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + if (dlambda_du != NULL) { + elem_cool_high = interpolation_3d_no_x( + cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, d_n_h, + 1.f, cooling->N_Elements, cooling->N_nH, cooling->N_Temp); + + elem_cool_low = interpolation_3d_no_x( + cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, d_n_h, + 0.f, cooling->N_nH, cooling->N_Temp, cooling->N_Elements); + + *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / + solar_electron_abundance_high - + elem_cool_low * h_plus_he_electron_abundance_low / + solar_electron_abundance_low) / + delta_T * dT_du * solar_ratio[elem + 2]; + } + } + + } else { + + /* Loop over the metals (ignore H and He) */ + for (int elem = 2; elem < eagle_cooling_N_metal + 2; elem++) { + + if (solar_ratio[elem] > 0.) { + + /* Note that we do not interpolate along the x-axis + * (element dimension) */ + lambda_metal[elem] = interpolation_4d_no_x( + cooling->table.metal_heating, /* */ + elem - 2, /*z_index=*/0, n_H_index, T_index, /* */ + /*delta_elem=*/0.f, cooling->dz, d_n_H, d_T, /* */ + eagle_cooling_N_metal, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_temperature); /* */ + + lambda_metal[elem] *= electron_abundance_ratio; + lambda_metal[elem] *= solar_ratio[elem]; + } + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + if (dlambda_du != NULL) { + elem_cool_high = interpolation_4d_no_x( + cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., + cooling->dz, d_n_h, 1.f, cooling->N_Elements, 2, cooling->N_nH, + cooling->N_Temp); + + elem_cool_low = interpolation_4d_no_x( + cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., + cooling->dz, d_n_h, 0.f, cooling->N_Elements, 2, cooling->N_nH, + cooling->N_Temp); + + *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / + solar_electron_abundance_high - + elem_cool_low * h_plus_he_electron_abundance_low / + solar_electron_abundance_low) / + delta_T * dT_du * solar_ratio[elem + 2]; + } + } + } + + if (element_lambda != NULL) { + for (int elem = 2; elem < eagle_cooling_N_metal + 2; ++elem) { + element_lambda[elem] = lambda_metal[elem]; + } + } + + /* Sum up all the contributions */ + double Lambda_net = Lambda_free + Lambda_Compton; + for (int elem = 2; elem < eagle_cooling_N_metal + 2; ++elem) { + Lambda_net += lambda_metal[elem]; + } + + return Lambda_net; +} + +/** + * @brief Wrapper function used to calculate cooling rate and dLambda_du. + * Table indices and offsets for redshift, hydrogen number density and + * helium fraction are passed it so as to compute them only once per particle. + * + * @param log_u_cgs Natural log of internal energy per unit mass in CGS units. + * @param redshift The current redshift. + * @param n_H_cgs Hydrogen number density in CGS units. + * @param abundance_ratio Ratio of element abundance to solar. + * + * @param n_H_index Particle hydrogen number density index + * @param d_n_H Particle hydrogen number density offset + * @param He_index Particle helium fraction index + * @param d_He Particle helium fraction offset + * @param cooling #cooling_function_data structure + * + * @param dLambdaNet_du (return) Derivative of the cooling rate with respect to + * u. + * + * @return The cooling rate + */ +INLINE static double eagle_cooling_rate( + double log_u_cgs, double redshift, double n_H_cgs, + const float abundance_ratio[chemistry_element_count + 2], int n_H_index, + float d_n_H, int He_index, float d_He, + const struct cooling_function_data *restrict cooling, + double *dLambdaNet_du) { + + return eagle_metal_cooling_rate(log_u_cgs / M_LN10, redshift, n_H_cgs, + abundance_ratio, n_H_index, d_n_H, He_index, + d_He, cooling, dLambdaNet_du, + /*element_lambda=*/NULL); +} + +/** + * @brief Newton Raphson integration scheme to calculate particle cooling over + * timestep. This replaces bisection scheme used in EAGLE to minimize the + * number of array accesses. Integration defaults to bisection scheme (see + * function bisection_iter) if this function does not converge within a + * specified number of steps + * + * @param logu_init Initial guess for log(internal energy) + * @param u_ini Internal energy at beginning of hydro step + * @param n_H_index Particle hydrogen number density index + * @param d_n_H Particle hydrogen number density offset + * @param He_index Particle helium fraction index + * @param d_He Particle helium fraction offset + * @param He_reion_heat Heating due to helium reionization + * (only depends on redshift, so passed as parameter) + * @param p #part structure + * @param cosmo #cosmology structure + * @param cooling #cooling_function_data structure + * @param phys_const #phys_const data structure + * @param abundance_ratio Array of ratios of metal abundance to solar + * @param dt timestep + * @param bisection_flag Flag to identify if scheme failed to converge + */ +float newton_iter( + float logu_init, double u_ini, int n_H_index, float d_n_H, int He_index, + float d_He, float He_reion_heat, struct part *restrict p, + const struct cosmology *restrict cosmo, + const struct cooling_function_data *restrict cooling, + const struct phys_const *restrict phys_const, + const float abundance_ratio[chemistry_element_count + 2], float dt, + int *bisection_flag) { + + double logu, logu_old; + double dLambdaNet_du = 0.0, LambdaNet; + + /* table bounds */ + const float log_table_bound_high = + (cooling->Therm[eagle_cooling_N_temperature - 1] - 0.05) / M_LOG10E; + const float log_table_bound_low = (cooling->Therm[0] + 0.05) / M_LOG10E; + + /* convert Hydrogen mass fraction in Hydrogen number density */ + const float XH = + p->chemistry_data.smoothed_metal_mass_fraction[chemistry_element_H]; + const double n_H = + hydro_get_physical_density(p, cosmo) * XH / phys_const->const_proton_mass; + const double n_H_cgs = n_H * cooling->number_density_to_cgs; + + /* compute ratefact = n_H * n_H / rho; Might lead to round-off error: + * replaced by equivalent expression below */ + const double ratefact_cgs = n_H_cgs * XH * cooling->inv_proton_mass_cgs; + + logu_old = logu_init; + logu = logu_old; + int i = 0; + + float LambdaNet_old = 0; + LambdaNet = 0; + do /* iterate to convergence */ + { + logu_old = logu; + LambdaNet_old = LambdaNet; + LambdaNet = (He_reion_heat / (dt * ratefact_cgs)) + + eagle_cooling_rate(logu_old, cosmo->z, n_H_cgs, abundance_ratio, + n_H_index, d_n_H, He_index, d_He, cooling, + &dLambdaNet_du); + + /* Newton iteration. For details on how the cooling equation is integrated + * see documentation in theory/Cooling/ */ + logu = logu_old - (1.0 - u_ini * exp(-logu_old) - + LambdaNet * ratefact_cgs * dt * exp(-logu_old)) / + (1.0 - dLambdaNet_du * ratefact_cgs * dt); + /* Check if first step passes over equilibrium solution, if it does adjust + * next guess */ + if (i == 1 && LambdaNet_old * LambdaNet < 0) logu = newton_log_u_guess_cgs; + + /* check whether iterations go within about 10% of the table bounds, + * if they do default to bisection method */ + if (logu > log_table_bound_high) { + i = newton_max_iterations; + break; + } else if (logu < log_table_bound_low) { + i = newton_max_iterations; + break; + } + + i++; + } while (fabs(logu - logu_old) > newton_tolerance && + i < newton_max_iterations); + if (i >= newton_max_iterations) { + /* flag to trigger bisection scheme */ + *bisection_flag = 1; + } + + return logu; +} -- GitLab From d71b6ee0c1032c604d8d2095b8a20ab1e98c93d2 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 18:31:22 +0200 Subject: [PATCH 71/79] Moved the cooling Newton scheme out of the main EAGLE cooling. Corrected the function signature in the stand-alone example. Corrected a typo in the calculation of the abundance pattern for metallicity. --- examples/Cooling/CoolingRates/cooling_rates.c | 24 +- src/cooling/EAGLE/cooling.c | 167 ++--------- src/cooling/EAGLE/cooling_rates.h | 267 ++---------------- src/cooling/EAGLE/cooling_struct.h | 2 +- src/cooling/EAGLE/cooling_tables.c | 1 + 5 files changed, 69 insertions(+), 392 deletions(-) diff --git a/examples/Cooling/CoolingRates/cooling_rates.c b/examples/Cooling/CoolingRates/cooling_rates.c index 5ffdc7f8d..07d82b305 100644 --- a/examples/Cooling/CoolingRates/cooling_rates.c +++ b/examples/Cooling/CoolingRates/cooling_rates.c @@ -104,9 +104,9 @@ INLINE static double eagle_print_metal_cooling_rate( /* calculate cooling rates */ for (int j = 0; j < eagle_cooling_N_metal + 2; j++) element_lambda[j] = 0.0; - lambda_net = eagle_metal_cooling_rate( - log10(u), cosmo->z, n_h, abundance_ratio, n_h_i, d_n_h, He_i, d_He, - cooling, /*dLambdaNet_du=*/NULL, element_lambda); + lambda_net = + eagle_metal_cooling_rate(log10(u), cosmo->z, n_h, abundance_ratio, n_h_i, + d_n_h, He_i, d_He, cooling, element_lambda); /* write cooling rate contributions to their own files. */ for (int j = 0; j < eagle_cooling_N_metal + 2; j++) { @@ -235,18 +235,26 @@ int main(int argc, char **argv) { // Init cooling cooling_init(params, &us, &internal_const, &hydro_properties, &cooling); + cooling.H_reion_done = 1; cooling_print(&cooling); cooling_update(&cosmo, &cooling, &s); + // Copy over the raw metals into the smoothed metals + memcpy(&p.chemistry_data.smoothed_metal_mass_fraction, + &p.chemistry_data.metal_mass_fraction, + chemistry_element_count * sizeof(float)); + p.chemistry_data.smoothed_metal_mass_fraction_total = + p.chemistry_data.metal_mass_fraction_total; + // Calculate abundance ratios float abundance_ratio[(chemistry_element_count + 2)]; abundance_ratio_to_solar(&p, &cooling, abundance_ratio); // extract mass fractions, calculate table indices and offsets - float XH = p.chemistry_data.metal_mass_fraction[chemistry_element_H]; - float HeFrac = - p.chemistry_data.metal_mass_fraction[chemistry_element_He] / - (XH + p.chemistry_data.metal_mass_fraction[chemistry_element_He]); + float XH = p.chemistry_data.smoothed_metal_mass_fraction[chemistry_element_H]; + float XHe = + p.chemistry_data.smoothed_metal_mass_fraction[chemistry_element_He]; + float HeFrac = XHe / (XH + XHe); int He_i, n_h_i; float d_He, d_n_h; get_index_1d(cooling.HeFrac, eagle_cooling_N_He_frac, HeFrac, &He_i, &d_He); @@ -286,7 +294,7 @@ int main(int argc, char **argv) { // calculate cooling rates const double temperature = eagle_convert_u_to_temp( - log10(u), cosmo.z, 0, NULL, n_h_i, He_i, d_n_h, d_He, &cooling); + log10(u), cosmo.z, n_h_i, He_i, d_n_h, d_He, &cooling); const double cooling_du_dt = eagle_print_metal_cooling_rate( n_h_i, d_n_h, He_i, d_He, &p, &xp, &cooling, &cosmo, &internal_const, diff --git a/src/cooling/EAGLE/cooling.c b/src/cooling/EAGLE/cooling.c index ee4be9b1a..0b5fcde02 100644 --- a/src/cooling/EAGLE/cooling.c +++ b/src/cooling/EAGLE/cooling.c @@ -48,18 +48,13 @@ #include "space.h" #include "units.h" -/* Maximum number of iterations for newton - * and bisection integration schemes */ -static const int newton_max_iterations = 15; +/* Maximum number of iterations for bisection scheme */ static const int bisection_max_iterations = 150; /* Tolerances for termination criteria. */ static const float explicit_tolerance = 0.05; -static const float newton_tolerance = 1.0e-4; static const float bisection_tolerance = 1.0e-6; -// static const float rounding_tolerance = 1.0e-4; static const double bracket_factor = 1.5; -static const double newton_log_u_guess_cgs = 12; /** * @brief Find the index of the current redshift along the redshift dimension @@ -189,102 +184,6 @@ void cooling_update(const struct cosmology *cosmo, cooling->z_index = z_index; } -/** - * @brief Newton Raphson integration scheme to calculate particle cooling over - * timestep. This replaces bisection scheme used in EAGLE to minimize the - * number of array accesses. Integration defaults to bisection scheme (see - * function bisection_iter) if this function does not converge within a - * specified number of steps - * - * @param logu_init Initial guess for log(internal energy) - * @param u_ini Internal energy at beginning of hydro step - * @param n_H_index Particle hydrogen number density index - * @param d_n_H Particle hydrogen number density offset - * @param He_index Particle helium fraction index - * @param d_He Particle helium fraction offset - * @param He_reion_heat Heating due to helium reionization - * (only depends on redshift, so passed as parameter) - * @param p #part structure - * @param cosmo #cosmology structure - * @param cooling #cooling_function_data structure - * @param phys_const #phys_const data structure - * @param abundance_ratio Array of ratios of metal abundance to solar - * @param dt timestep - * @param bisection_flag Flag to identify if scheme failed to converge - */ -INLINE static float newton_iter( - float logu_init, double u_ini, int n_H_index, float d_n_H, int He_index, - float d_He, float He_reion_heat, struct part *restrict p, - const struct cosmology *restrict cosmo, - const struct cooling_function_data *restrict cooling, - const struct phys_const *restrict phys_const, - const float abundance_ratio[chemistry_element_count + 2], float dt, - int *bisection_flag) { - - double logu, logu_old; - double dLambdaNet_du = 0.0, LambdaNet; - - /* table bounds */ - const float log_table_bound_high = - (cooling->Therm[eagle_cooling_N_temperature - 1] - 0.05) / M_LOG10E; - const float log_table_bound_low = (cooling->Therm[0] + 0.05) / M_LOG10E; - - /* convert Hydrogen mass fraction in Hydrogen number density */ - const float XH = - p->chemistry_data.smoothed_metal_mass_fraction[chemistry_element_H]; - const double n_H = - hydro_get_physical_density(p, cosmo) * XH / phys_const->const_proton_mass; - const double n_H_cgs = n_H * cooling->number_density_to_cgs; - - /* compute ratefact = n_H * n_H / rho; Might lead to round-off error: - * replaced by equivalent expression below */ - const double ratefact_cgs = n_H_cgs * XH * cooling->inv_proton_mass_cgs; - - logu_old = logu_init; - logu = logu_old; - int i = 0; - - float LambdaNet_old = 0; - LambdaNet = 0; - do /* iterate to convergence */ - { - logu_old = logu; - LambdaNet_old = LambdaNet; - LambdaNet = (He_reion_heat / (dt * ratefact_cgs)) + - eagle_cooling_rate(logu_old, cosmo->z, n_H_cgs, abundance_ratio, - n_H_index, d_n_H, He_index, d_He, cooling, - &dLambdaNet_du); - - /* Newton iteration. For details on how the cooling equation is integrated - * see documentation in theory/Cooling/ */ - logu = logu_old - (1.0 - u_ini * exp(-logu_old) - - LambdaNet * ratefact_cgs * dt * exp(-logu_old)) / - (1.0 - dLambdaNet_du * ratefact_cgs * dt); - /* Check if first step passes over equilibrium solution, if it does adjust - * next guess */ - if (i == 1 && LambdaNet_old * LambdaNet < 0) logu = newton_log_u_guess_cgs; - - /* check whether iterations go within about 10% of the table bounds, - * if they do default to bisection method */ - if (logu > log_table_bound_high) { - i = newton_max_iterations; - break; - } else if (logu < log_table_bound_low) { - i = newton_max_iterations; - break; - } - - i++; - } while (fabs(logu - logu_old) > newton_tolerance && - i < newton_max_iterations); - if (i >= newton_max_iterations) { - /* flag to trigger bisection scheme */ - *bisection_flag = 1; - } - - return logu; -} - /** * @brief Bisection integration scheme * @@ -304,11 +203,12 @@ INLINE static float newton_iter( */ INLINE static double bisection_iter( const double u_ini_cgs, const double n_H_cgs, const double redshift, - int n_H_index, float d_n_H, int He_index, float d_He, - double Lambda_He_reion_cgs, double ratefact_cgs, + const int n_H_index, const float d_n_H, const int He_index, + const float d_He, const double Lambda_He_reion_cgs, + const double ratefact_cgs, const struct cooling_function_data *restrict cooling, - const float abundance_ratio[chemistry_element_count + 2], double dt_cgs, - long long ID) { + const float abundance_ratio[chemistry_element_count + 2], + const double dt_cgs, const long long ID) { /* Bracketing */ double u_lower_cgs = u_ini_cgs; @@ -320,9 +220,8 @@ INLINE static double bisection_iter( double LambdaNet_cgs = Lambda_He_reion_cgs + - eagle_cooling_rate(log(u_ini_cgs), redshift, n_H_cgs, abundance_ratio, - n_H_index, d_n_H, He_index, d_He, cooling, - /*dLambdaNet_du=*/NULL); + eagle_cooling_rate(log10(u_ini_cgs), redshift, n_H_cgs, abundance_ratio, + n_H_index, d_n_H, He_index, d_He, cooling); /*************************************/ /* Let's try to bracket the solution */ @@ -335,11 +234,10 @@ INLINE static double bisection_iter( u_upper_cgs *= bracket_factor; /* Compute a new rate */ - LambdaNet_cgs = - Lambda_He_reion_cgs + - eagle_cooling_rate(log(u_lower_cgs), redshift, n_H_cgs, abundance_ratio, - n_H_index, d_n_H, He_index, d_He, cooling, - /*dLambdaNet_du=*/NULL); + LambdaNet_cgs = Lambda_He_reion_cgs + + eagle_cooling_rate(log10(u_lower_cgs), redshift, n_H_cgs, + abundance_ratio, n_H_index, d_n_H, + He_index, d_He, cooling); int i = 0; while (u_lower_cgs - u_ini_cgs - LambdaNet_cgs * ratefact_cgs * dt_cgs > @@ -351,10 +249,9 @@ INLINE static double bisection_iter( /* Compute a new rate */ LambdaNet_cgs = Lambda_He_reion_cgs + - eagle_cooling_rate(log(u_lower_cgs), redshift, n_H_cgs, + eagle_cooling_rate(log10(u_lower_cgs), redshift, n_H_cgs, abundance_ratio, n_H_index, d_n_H, - He_index, d_He, cooling, - /*dLambdaNet_du=*/NULL); + He_index, d_He, cooling); i++; } @@ -371,11 +268,10 @@ INLINE static double bisection_iter( u_upper_cgs *= bracket_factor; /* Compute a new rate */ - LambdaNet_cgs = - Lambda_He_reion_cgs + - eagle_cooling_rate(log(u_upper_cgs), redshift, n_H_cgs, abundance_ratio, - n_H_index, d_n_H, He_index, d_He, cooling, - /*dLambdaNet_du=*/NULL); + LambdaNet_cgs = Lambda_He_reion_cgs + + eagle_cooling_rate(log10(u_upper_cgs), redshift, n_H_cgs, + abundance_ratio, n_H_index, d_n_H, + He_index, d_He, cooling); int i = 0; while (u_upper_cgs - u_ini_cgs - LambdaNet_cgs * ratefact_cgs * dt_cgs < @@ -387,10 +283,9 @@ INLINE static double bisection_iter( /* Compute a new rate */ LambdaNet_cgs = Lambda_He_reion_cgs + - eagle_cooling_rate(log(u_upper_cgs), redshift, n_H_cgs, + eagle_cooling_rate(log10(u_upper_cgs), redshift, n_H_cgs, abundance_ratio, n_H_index, d_n_H, - He_index, d_He, cooling, - /*dLambdaNet_du=*/NULL); + He_index, d_He, cooling); i++; } @@ -417,11 +312,10 @@ INLINE static double bisection_iter( u_next_cgs = 0.5 * (u_lower_cgs + u_upper_cgs); /* New rate */ - LambdaNet_cgs = - Lambda_He_reion_cgs + - eagle_cooling_rate(log(u_next_cgs), redshift, n_H_cgs, abundance_ratio, - n_H_index, d_n_H, He_index, d_He, cooling, - /*dLambdaNet_du=*/NULL); + LambdaNet_cgs = Lambda_He_reion_cgs + + eagle_cooling_rate(log10(u_next_cgs), redshift, n_H_cgs, + abundance_ratio, n_H_index, d_n_H, + He_index, d_He, cooling); // Debugging if (u_next_cgs <= 0) @@ -572,10 +466,9 @@ void cooling_cool_part(const struct phys_const *phys_const, /* First try an explicit integration (note we ignore the derivative) */ const double LambdaNet_cgs = - Lambda_He_reion_cgs + eagle_cooling_rate(log(u_0_cgs), cosmo->z, n_H_cgs, - abundance_ratio, n_H_index, - d_n_H, He_index, d_He, cooling, - /*dLambdaNet_du=*/NULL); + Lambda_He_reion_cgs + + eagle_cooling_rate(log10(u_0_cgs), cosmo->z, n_H_cgs, abundance_ratio, + n_H_index, d_n_H, He_index, d_He, cooling); /* if cooling rate is small, take the explicit solution */ if (fabs(ratefact_cgs * LambdaNet_cgs * dt_cgs) < @@ -604,7 +497,8 @@ void cooling_cool_part(const struct phys_const *phys_const, /* Limit imposed by the entropy floor */ const double A_floor = entropy_floor(p, cosmo, floor_props); const double rho_physical = hydro_get_physical_density(p, cosmo); - const double u_floor = gas_internal_energy_from_entropy(rho_physical, A_floor); + const double u_floor = + gas_internal_energy_from_entropy(rho_physical, A_floor); u_final = max(u_final, u_floor); /* Expected change in energy over the next kick step @@ -728,8 +622,7 @@ float cooling_get_temperature( /* Compute the log10 of the temperature by interpolating the table */ const double log_10_T = eagle_convert_u_to_temp( - log10(u_cgs), cosmo->z, /*compute_dT_du=*/0, /*dT_du=*/NULL, n_H_index, - He_index, d_n_H, d_He, cooling); + log10(u_cgs), cosmo->z, n_H_index, He_index, d_n_H, d_He, cooling); /* Undo the log! */ return exp10(log_10_T); diff --git a/src/cooling/EAGLE/cooling_rates.h b/src/cooling/EAGLE/cooling_rates.h index 35a53b43f..6707a9a9d 100644 --- a/src/cooling/EAGLE/cooling_rates.h +++ b/src/cooling/EAGLE/cooling_rates.h @@ -99,7 +99,7 @@ __attribute__((always_inline)) INLINE void abundance_ratio_to_solar( cooling->Ca_over_Si_ratio_in_solar; ratio_solar[10] = - p->chemistry_data.metal_mass_fraction[chemistry_element_Fe] * + p->chemistry_data.smoothed_metal_mass_fraction[chemistry_element_Fe] * cooling->SolarAbundances_inv[10 /* Fe */]; } @@ -118,7 +118,8 @@ __attribute__((always_inline)) INLINE void abundance_ratio_to_solar( */ __attribute__((always_inline)) INLINE double eagle_helium_reionization_extraheat( - double z, double delta_z, const struct cooling_function_data *cooling) { + const double z, const double delta_z, + const struct cooling_function_data *cooling) { #ifdef SWIFT_DEBUG_CHECKS if (delta_z > 0.f) error("Invalid value for delta_z. Should be negative."); @@ -169,15 +170,12 @@ eagle_helium_reionization_extraheat( * @param d_He Offset between helium fraction and table[He_index]. * @param cooling #cooling_function_data structure. * - * @param compute_dT_du Do we want to compute dT/du ? - * @param dT_du (return) The value of dT/du - * * @return log_10 of the temperature. */ __attribute__((always_inline)) INLINE double eagle_convert_u_to_temp( - const double log_10_u_cgs, const float redshift, const int compute_dT_du, - float *dT_du, int n_H_index, int He_index, float d_n_H, float d_He, - const struct cooling_function_data *restrict cooling) { + const double log_10_u_cgs, const float redshift, const int n_H_index, + const int He_index, const float d_n_H, const float d_He, + const struct cooling_function_data *cooling) { /* Get index of u along the internal energy axis */ int u_index; @@ -209,67 +207,6 @@ __attribute__((always_inline)) INLINE double eagle_convert_u_to_temp( eagle_cooling_N_temperature); /* */ } - if (compute_dT_du) { - - float log_10_T_high, log_10_T_low; - - /* Interpolate temperature table to return temperature for internal energy - * at grid point above current internal energy for computing dT_du used for - * calculation of dlambda_du in cooling.c (use 3D interpolation for high - * redshift table, otherwise 4D) */ - if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { - - log_10_T_high = interpolation_3d(cooling->table.temperature, /* */ - n_H_index, He_index, u_index, /* */ - d_n_H, d_He, /*delta_u=*/1.f, /* */ - eagle_cooling_N_density, /* */ - eagle_cooling_N_He_frac, /* */ - eagle_cooling_N_temperature); /* */ - - } else { - - log_10_T_high = - interpolation_4d(cooling->table.temperature, /* */ - /*z_index=*/0, n_H_index, He_index, u_index, /* */ - cooling->dz, d_n_H, d_He, /*delta_u=*/1.f, /* */ - eagle_cooling_N_loaded_redshifts, /* */ - eagle_cooling_N_density, /* */ - eagle_cooling_N_He_frac, /* */ - eagle_cooling_N_temperature); /* */ - } - - /* Interpolate temperature table to return temperature for internal energy - * at grid point below current internal energy for computing dT_du used for - * calculation of dlambda_du in cooling.c (use 3D interpolation for high - * redshift table, otherwise 4D) */ - if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { - - log_10_T_low = interpolation_3d(cooling->table.temperature, /* */ - n_H_index, He_index, u_index, /* */ - d_n_H, d_He, /*delta_u=*/0.f, /* */ - eagle_cooling_N_density, /* */ - eagle_cooling_N_He_frac, /* */ - eagle_cooling_N_temperature); /* */ - - } else { - - log_10_T_low = - interpolation_4d(cooling->table.temperature, /* */ - /*z_index=*/0, n_H_index, He_index, u_index, /* */ - cooling->dz, d_n_H, d_He, /*delta_u=*/0.f, /* */ - eagle_cooling_N_loaded_redshifts, /* */ - eagle_cooling_N_density, /* */ - eagle_cooling_N_He_frac, /* */ - eagle_cooling_N_temperature); /* */ - } - - /* Calculate dT/du */ - const float delta_u = exp(cooling->Therm[u_index + 1] * M_LN10) - - exp(cooling->Therm[u_index] * M_LN10); - *dT_du = - (exp(M_LN10 * log_10_T_high) - exp(M_LN10 * log_10_T_low)) / delta_u; - } - /* Special case for temperatures below the start of the table */ if (u_index == 0 && d_u == 0.f) { @@ -355,10 +292,6 @@ __attribute__((always_inline)) INLINE double eagle_Compton_cooling_rate( * the redshift, hydrogen number density and helium fraction indices * and offsets passed in. * - * If the arguement dlambda_du is non-NULL, the routine also - * calculates derivative of cooling rate with respect to internal - * energy. - * * If the argument element_lambda is non-NULL, the routine also * returns the cooling rate per element in the array. * @@ -374,36 +307,19 @@ __attribute__((always_inline)) INLINE double eagle_Compton_cooling_rate( * @param d_He Particle helium fraction offset * @param cooling Cooling data structure * - * @param dlambda_du (return) Derivative of the cooling rate with respect to u. * @param element_lambda (return) Cooling rate from each element * * @return The cooling rate */ INLINE static double eagle_metal_cooling_rate( - double log10_u_cgs, double redshift, double n_H_cgs, - const float solar_ratio[chemistry_element_count + 2], int n_H_index, - float d_n_H, int He_index, float d_He, - const struct cooling_function_data *restrict cooling, double *dlambda_du, - double *element_lambda) { - -#ifdef TO_BE_DONE - /* used for calculating dlambda_du */ - double temp_lambda_high = 0, temp_lambda_low = 0; - double h_plus_he_electron_abundance_high = 0; - double h_plus_he_electron_abundance_low = 0; - double solar_electron_abundance_high = 0; - double solar_electron_abundance_low = 0; - double elem_cool_low = 0, elem_cool_high = 0; -#endif - - /* We only need dT_du if dLambda_du is non-NULL */ - const int compute_dT_du = (dlambda_du != NULL) ? 1 : 0; + const double log10_u_cgs, const double redshift, const double n_H_cgs, + const float solar_ratio[chemistry_element_count + 2], const int n_H_index, + const float d_n_H, const int He_index, const float d_He, + const struct cooling_function_data *cooling, double *element_lambda) { /* Temperature */ - float dT_du = -1.f; - const double log_10_T = - eagle_convert_u_to_temp(log10_u_cgs, redshift, compute_dT_du, &dT_du, - n_H_index, He_index, d_n_H, d_He, cooling); + const double log_10_T = eagle_convert_u_to_temp( + log10_u_cgs, redshift, n_H_index, He_index, d_n_H, d_He, cooling); /* Get index along temperature dimension of the tables */ int T_index; @@ -411,12 +327,6 @@ INLINE static double eagle_metal_cooling_rate( get_index_1d(cooling->Temp, eagle_cooling_N_temperature, log_10_T, &T_index, &d_T); -#ifdef TO_BE_DONE - /* Difference between entries on the temperature table around u */ - const float delta_T = exp(M_LN10 * cooling->Temp[T_index + 1]) - - exp(M_LN10 * cooling->Temp[T_index]); -#endif - /**********************/ /* Metal-free cooling */ /**********************/ @@ -433,21 +343,6 @@ INLINE static double eagle_metal_cooling_rate( eagle_cooling_N_density, /* */ eagle_cooling_N_He_frac, /* */ eagle_cooling_N_temperature); /* */ - -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du. Pass in NULL pointer for - * dlambda_du in order to skip */ - if (dlambda_du != NULL) { - temp_lambda_high = interpolation_3d( - cooling->table.H_plus_He_heating, n_H_index, He_index, T_index, d_n_h, - d_He, 1.f, cooling->N_nH, cooling->N_He, cooling->N_Temp); - temp_lambda_low = interpolation_3d( - cooling->table.H_plus_He_heating, n_H_index, He_index, T_index, d_n_h, - d_He, 0.f, cooling->N_nH, cooling->N_He, cooling->N_Temp); - } -#endif - } else { /* Using normal tables, have to interpolate in redshift */ @@ -459,29 +354,8 @@ INLINE static double eagle_metal_cooling_rate( eagle_cooling_N_density, /* */ eagle_cooling_N_He_frac, /* */ eagle_cooling_N_temperature); /* */ - -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - if (dlambda_du != NULL) { - temp_lambda_high = - interpolation_4d(cooling->table.H_plus_He_heating, 0, n_H_index, - He_index, T_index, cooling->dz, d_n_h, d_He, 1.f, 2, - cooling->N_nH, cooling->N_He, cooling->N_Temp); - temp_lambda_low = - interpolation_4d(cooling->table.H_plus_He_heating, 0, n_H_index, - He_index, T_index, cooling->dz, d_n_h, d_He, 0.f, 2, - cooling->N_nH, cooling->N_He, cooling->N_Temp); - } -#endif } -#ifdef TO_BE_DONE - if (dlambda_du != NULL) { - *dlambda_du += (temp_lambda_high - temp_lambda_low) / delta_T * dT_du; - } -#endif - /* If we're testing cooling rate contributions write to array */ if (element_lambda != NULL) { element_lambda[0] = Lambda_free; @@ -502,21 +376,6 @@ INLINE static double eagle_metal_cooling_rate( eagle_cooling_N_density, /* */ eagle_cooling_N_He_frac, /* */ eagle_cooling_N_temperature); /* */ -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du. Pass in NULL pointer for - * dlambda_du in order to skip */ - - h_plus_he_electron_abundance_high = - interpolation_3d(cooling->table.H_plus_He_electron_abundance, n_H_index, - He_index, T_index, d_n_h, d_He, 1.f, cooling->N_nH, - cooling->N_He, cooling->N_Temp); - h_plus_he_electron_abundance_low = - interpolation_3d(cooling->table.H_plus_He_electron_abundance, n_H_index, - He_index, T_index, d_n_h, d_He, 0.f, cooling->N_nH, - cooling->N_He, cooling->N_Temp); - -#endif } else { @@ -528,19 +387,6 @@ INLINE static double eagle_metal_cooling_rate( eagle_cooling_N_density, /* */ eagle_cooling_N_He_frac, /* */ eagle_cooling_N_temperature); /* */ - -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - h_plus_he_electron_abundance_high = - interpolation_4d(cooling->table.H_plus_He_electron_abundance, 0, - n_H_index, He_index, T_index, cooling->dz, d_n_h, d_He, - 1.f, 2, cooling->N_nH, cooling->N_He, cooling->N_Temp); - h_plus_he_electron_abundance_low = - interpolation_4d(cooling->table.H_plus_He_electron_abundance, 0, - n_H_index, He_index, T_index, cooling->dz, d_n_h, d_He, - 0.f, 2, cooling->N_nH, cooling->N_He, cooling->N_Temp); -#endif } /**********************/ @@ -583,19 +429,6 @@ INLINE static double eagle_metal_cooling_rate( eagle_cooling_N_density, /* */ eagle_cooling_N_temperature); /* */ -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - if (dlambda_du != NULL) { - solar_electron_abundance_high = - interpolation_2d(cooling->table.electron_abundance, n_H_index, - T_index, d_n_h, 1.f, cooling->N_nH, cooling->N_Temp); - solar_electron_abundance_low = - interpolation_2d(cooling->table.electron_abundance, n_H_index, - T_index, d_n_h, 0.f, cooling->N_nH, cooling->N_Temp); - } -#endif - } else { /* Using normal tables, have to interpolate in redshift */ @@ -606,19 +439,6 @@ INLINE static double eagle_metal_cooling_rate( eagle_cooling_N_loaded_redshifts, /* */ eagle_cooling_N_density, /* */ eagle_cooling_N_temperature); /* */ - -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - if (dlambda_du != NULL) { - solar_electron_abundance_high = interpolation_3d( - cooling->table.electron_abundance, 0, n_H_index, T_index, cooling->dz, - d_n_h, 1.f, 2, cooling->N_nH, cooling->N_Temp); - solar_electron_abundance_low = interpolation_3d( - cooling->table.electron_abundance, 0, n_H_index, T_index, cooling->dz, - d_n_h, 0.f, 2, cooling->N_nH, cooling->N_Temp); - } -#endif } const double electron_abundance_ratio = @@ -654,26 +474,6 @@ INLINE static double eagle_metal_cooling_rate( lambda_metal[elem] *= electron_abundance_ratio; lambda_metal[elem] *= solar_ratio[elem]; } - -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - if (dlambda_du != NULL) { - elem_cool_high = interpolation_3d_no_x( - cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, d_n_h, - 1.f, cooling->N_Elements, cooling->N_nH, cooling->N_Temp); - - elem_cool_low = interpolation_3d_no_x( - cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, d_n_h, - 0.f, cooling->N_nH, cooling->N_Temp, cooling->N_Elements); - - *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / - solar_electron_abundance_high - - elem_cool_low * h_plus_he_electron_abundance_low / - solar_electron_abundance_low) / - delta_T * dT_du * solar_ratio[elem + 2]; - } -#endif } } else { @@ -696,29 +496,9 @@ INLINE static double eagle_metal_cooling_rate( lambda_metal[elem] *= electron_abundance_ratio; lambda_metal[elem] *= solar_ratio[elem]; - } -#ifdef TO_BE_DONE - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - if (dlambda_du != NULL) { - elem_cool_high = interpolation_4d_no_x( - cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., - cooling->dz, d_n_h, 1.f, cooling->N_Elements, 2, cooling->N_nH, - cooling->N_Temp); - - elem_cool_low = interpolation_4d_no_x( - cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., - cooling->dz, d_n_h, 0.f, cooling->N_Elements, 2, cooling->N_nH, - cooling->N_Temp); - - *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / - solar_electron_abundance_high - - elem_cool_low * h_plus_he_electron_abundance_low / - solar_electron_abundance_low) / - delta_T * dT_du * solar_ratio[elem + 2]; + // message("lambda[%d]=%e", elem, lambda_metal[elem]); } -#endif } } @@ -738,11 +518,11 @@ INLINE static double eagle_metal_cooling_rate( } /** - * @brief Wrapper function used to calculate cooling rate and dLambda_du. + * @brief Wrapper function used to calculate cooling rate. * Table indices and offsets for redshift, hydrogen number density and * helium fraction are passed it so as to compute them only once per particle. * - * @param log_u_cgs Natural log of internal energy per unit mass in CGS units. + * @param log10_u_cgs Log base 10 of internal energy per unit mass in CGS units. * @param redshift The current redshift. * @param n_H_cgs Hydrogen number density in CGS units. * @param abundance_ratio Ratio of element abundance to solar. @@ -753,22 +533,17 @@ INLINE static double eagle_metal_cooling_rate( * @param d_He Particle helium fraction offset * @param cooling #cooling_function_data structure * - * @param dLambdaNet_du (return) Derivative of the cooling rate with respect to - * u. - * * @return The cooling rate */ INLINE static double eagle_cooling_rate( - double log_u_cgs, double redshift, double n_H_cgs, - const float abundance_ratio[chemistry_element_count + 2], int n_H_index, - float d_n_H, int He_index, float d_He, - const struct cooling_function_data *restrict cooling, - double *dLambdaNet_du) { + const double log10_u_cgs, const double redshift, const double n_H_cgs, + const float abundance_ratio[chemistry_element_count + 2], + const int n_H_index, const float d_n_H, const int He_index, + const float d_He, const struct cooling_function_data *cooling) { - return eagle_metal_cooling_rate(log_u_cgs / M_LN10, redshift, n_H_cgs, + return eagle_metal_cooling_rate(log10_u_cgs, redshift, n_H_cgs, abundance_ratio, n_H_index, d_n_H, He_index, - d_He, cooling, dLambdaNet_du, - /*element_lambda=*/NULL); + d_He, cooling, /* element_lambda=*/NULL); } #endif /* SWIFT_EAGLE_COOLING_RATES_H */ diff --git a/src/cooling/EAGLE/cooling_struct.h b/src/cooling/EAGLE/cooling_struct.h index f62b199a5..8c7c44e6b 100644 --- a/src/cooling/EAGLE/cooling_struct.h +++ b/src/cooling/EAGLE/cooling_struct.h @@ -112,7 +112,7 @@ struct cooling_function_data { /*! Inverse of proton mass in cgs (for quick access) */ double inv_proton_mass_cgs; - /*! Temperatur of the CMB at present day (for quick access) */ + /*! Temperature of the CMB at present day (for quick access) */ double T_CMB_0; /*! Compton rate in cgs units */ diff --git a/src/cooling/EAGLE/cooling_tables.c b/src/cooling/EAGLE/cooling_tables.c index cd6678c70..cddc8d50e 100644 --- a/src/cooling/EAGLE/cooling_tables.c +++ b/src/cooling/EAGLE/cooling_tables.c @@ -296,6 +296,7 @@ void read_cooling_header(const char *fname, for (int i = 0; i < N_nH; i++) { cooling->nH[i] = log10(cooling->nH[i]); } + /* Compute inverse of solar mass fractions */ for (int i = 0; i < N_SolarAbundances; ++i) { cooling->SolarAbundances_inv[i] = 1.f / cooling->SolarAbundances[i]; -- GitLab From 61af330b73b1b1750df856f9ba873afc8528eb52 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 19:23:50 +0200 Subject: [PATCH 72/79] Applied code formatting to the newton eagle cooling. --- src/cooling/EAGLE/newton_cooling.c | 438 ++++++++++++++--------------- 1 file changed, 219 insertions(+), 219 deletions(-) diff --git a/src/cooling/EAGLE/newton_cooling.c b/src/cooling/EAGLE/newton_cooling.c index d434c2de0..c68a77614 100644 --- a/src/cooling/EAGLE/newton_cooling.c +++ b/src/cooling/EAGLE/newton_cooling.c @@ -143,7 +143,6 @@ __attribute__((always_inline)) INLINE double eagle_convert_u_to_temp( return log_10_T; } - /** * @brief Computes the cooling rate corresponding to a given internal energy, * hydrogen number density, Helium fraction, redshift and metallicity from @@ -435,244 +434,245 @@ INLINE static double eagle_metal_cooling_rate( d_n_h, 0.f, 2, cooling->N_nH, cooling->N_Temp); } - const double electron_abundance_ratio = - H_plus_He_electron_abundance / solar_electron_abundance; - - /**********************/ - /* Metal-line cooling */ - /**********************/ - - /* for each element the cooling rate is multiplied by the ratio of H, He - * electron abundance to solar electron abundance then by the ratio of the - * particle metal abundance to solar metal abundance. */ - - double lambda_metal[eagle_cooling_N_metal + 2] = {0.}; + const double electron_abundance_ratio = + H_plus_He_electron_abundance / solar_electron_abundance; - if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { - - /* Loop over the metals (ignore H and He) */ - for (int elem = 2; elem < eagle_cooling_N_metal + 2; elem++) { + /**********************/ + /* Metal-line cooling */ + /**********************/ - if (solar_ratio[elem] > 0.) { + /* for each element the cooling rate is multiplied by the ratio of H, He + * electron abundance to solar electron abundance then by the ratio of the + * particle metal abundance to solar metal abundance. */ - /* Note that we do not interpolate along the x-axis - * (element dimension) */ - lambda_metal[elem] = - interpolation_3d_no_x(cooling->table.metal_heating, /* */ - elem - 2, n_H_index, T_index, /* */ - /*delta_elem=*/0.f, d_n_H, d_T, /* */ - eagle_cooling_N_metal, /* */ - eagle_cooling_N_density, /* */ - eagle_cooling_N_temperature); /* */ + double lambda_metal[eagle_cooling_N_metal + 2] = {0.}; - lambda_metal[elem] *= electron_abundance_ratio; - lambda_metal[elem] *= solar_ratio[elem]; - } + if (redshift > cooling->Redshifts[eagle_cooling_N_redshifts - 1]) { - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - if (dlambda_du != NULL) { - elem_cool_high = interpolation_3d_no_x( - cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, d_n_h, - 1.f, cooling->N_Elements, cooling->N_nH, cooling->N_Temp); - - elem_cool_low = interpolation_3d_no_x( - cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, d_n_h, - 0.f, cooling->N_nH, cooling->N_Temp, cooling->N_Elements); - - *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / - solar_electron_abundance_high - - elem_cool_low * h_plus_he_electron_abundance_low / - solar_electron_abundance_low) / - delta_T * dT_du * solar_ratio[elem + 2]; + /* Loop over the metals (ignore H and He) */ + for (int elem = 2; elem < eagle_cooling_N_metal + 2; elem++) { + + if (solar_ratio[elem] > 0.) { + + /* Note that we do not interpolate along the x-axis + * (element dimension) */ + lambda_metal[elem] = + interpolation_3d_no_x(cooling->table.metal_heating, /* */ + elem - 2, n_H_index, T_index, /* */ + /*delta_elem=*/0.f, d_n_H, d_T, /* */ + eagle_cooling_N_metal, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_temperature); /* */ + + lambda_metal[elem] *= electron_abundance_ratio; + lambda_metal[elem] *= solar_ratio[elem]; + } + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + if (dlambda_du != NULL) { + elem_cool_high = interpolation_3d_no_x( + cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, + d_n_h, 1.f, cooling->N_Elements, cooling->N_nH, cooling->N_Temp); + + elem_cool_low = interpolation_3d_no_x( + cooling->table.metal_heating, elem, n_H_index, T_index, 0.f, + d_n_h, 0.f, cooling->N_nH, cooling->N_Temp, cooling->N_Elements); + + *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / + solar_electron_abundance_high - + elem_cool_low * h_plus_he_electron_abundance_low / + solar_electron_abundance_low) / + delta_T * dT_du * solar_ratio[elem + 2]; + } } - } - } else { - - /* Loop over the metals (ignore H and He) */ - for (int elem = 2; elem < eagle_cooling_N_metal + 2; elem++) { - - if (solar_ratio[elem] > 0.) { - - /* Note that we do not interpolate along the x-axis - * (element dimension) */ - lambda_metal[elem] = interpolation_4d_no_x( - cooling->table.metal_heating, /* */ - elem - 2, /*z_index=*/0, n_H_index, T_index, /* */ - /*delta_elem=*/0.f, cooling->dz, d_n_H, d_T, /* */ - eagle_cooling_N_metal, /* */ - eagle_cooling_N_loaded_redshifts, /* */ - eagle_cooling_N_density, /* */ - eagle_cooling_N_temperature); /* */ + } else { - lambda_metal[elem] *= electron_abundance_ratio; - lambda_metal[elem] *= solar_ratio[elem]; + /* Loop over the metals (ignore H and He) */ + for (int elem = 2; elem < eagle_cooling_N_metal + 2; elem++) { + + if (solar_ratio[elem] > 0.) { + + /* Note that we do not interpolate along the x-axis + * (element dimension) */ + lambda_metal[elem] = interpolation_4d_no_x( + cooling->table.metal_heating, /* */ + elem - 2, /*z_index=*/0, n_H_index, T_index, /* */ + /*delta_elem=*/0.f, cooling->dz, d_n_H, d_T, /* */ + eagle_cooling_N_metal, /* */ + eagle_cooling_N_loaded_redshifts, /* */ + eagle_cooling_N_density, /* */ + eagle_cooling_N_temperature); /* */ + + lambda_metal[elem] *= electron_abundance_ratio; + lambda_metal[elem] *= solar_ratio[elem]; + } + + /* compute values at temperature gridpoints above and below input + * temperature for calculation of dlambda_du */ + if (dlambda_du != NULL) { + elem_cool_high = interpolation_4d_no_x( + cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., + cooling->dz, d_n_h, 1.f, cooling->N_Elements, 2, cooling->N_nH, + cooling->N_Temp); + + elem_cool_low = interpolation_4d_no_x( + cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., + cooling->dz, d_n_h, 0.f, cooling->N_Elements, 2, cooling->N_nH, + cooling->N_Temp); + + *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / + solar_electron_abundance_high - + elem_cool_low * h_plus_he_electron_abundance_low / + solar_electron_abundance_low) / + delta_T * dT_du * solar_ratio[elem + 2]; + } } + } - /* compute values at temperature gridpoints above and below input - * temperature for calculation of dlambda_du */ - if (dlambda_du != NULL) { - elem_cool_high = interpolation_4d_no_x( - cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., - cooling->dz, d_n_h, 1.f, cooling->N_Elements, 2, cooling->N_nH, - cooling->N_Temp); - - elem_cool_low = interpolation_4d_no_x( - cooling->table.metal_heating, elem, 0, n_H_index, T_index, 0., - cooling->dz, d_n_h, 0.f, cooling->N_Elements, 2, cooling->N_nH, - cooling->N_Temp); - - *dlambda_du += (elem_cool_high * h_plus_he_electron_abundance_high / - solar_electron_abundance_high - - elem_cool_low * h_plus_he_electron_abundance_low / - solar_electron_abundance_low) / - delta_T * dT_du * solar_ratio[elem + 2]; + if (element_lambda != NULL) { + for (int elem = 2; elem < eagle_cooling_N_metal + 2; ++elem) { + element_lambda[elem] = lambda_metal[elem]; } } - } - if (element_lambda != NULL) { + /* Sum up all the contributions */ + double Lambda_net = Lambda_free + Lambda_Compton; for (int elem = 2; elem < eagle_cooling_N_metal + 2; ++elem) { - element_lambda[elem] = lambda_metal[elem]; + Lambda_net += lambda_metal[elem]; } - } - /* Sum up all the contributions */ - double Lambda_net = Lambda_free + Lambda_Compton; - for (int elem = 2; elem < eagle_cooling_N_metal + 2; ++elem) { - Lambda_net += lambda_metal[elem]; + return Lambda_net; } - return Lambda_net; -} - -/** - * @brief Wrapper function used to calculate cooling rate and dLambda_du. - * Table indices and offsets for redshift, hydrogen number density and - * helium fraction are passed it so as to compute them only once per particle. - * - * @param log_u_cgs Natural log of internal energy per unit mass in CGS units. - * @param redshift The current redshift. - * @param n_H_cgs Hydrogen number density in CGS units. - * @param abundance_ratio Ratio of element abundance to solar. - * - * @param n_H_index Particle hydrogen number density index - * @param d_n_H Particle hydrogen number density offset - * @param He_index Particle helium fraction index - * @param d_He Particle helium fraction offset - * @param cooling #cooling_function_data structure - * - * @param dLambdaNet_du (return) Derivative of the cooling rate with respect to - * u. - * - * @return The cooling rate - */ -INLINE static double eagle_cooling_rate( - double log_u_cgs, double redshift, double n_H_cgs, - const float abundance_ratio[chemistry_element_count + 2], int n_H_index, - float d_n_H, int He_index, float d_He, - const struct cooling_function_data *restrict cooling, - double *dLambdaNet_du) { + /** + * @brief Wrapper function used to calculate cooling rate and dLambda_du. + * Table indices and offsets for redshift, hydrogen number density and + * helium fraction are passed it so as to compute them only once per particle. + * + * @param log_u_cgs Natural log of internal energy per unit mass in CGS units. + * @param redshift The current redshift. + * @param n_H_cgs Hydrogen number density in CGS units. + * @param abundance_ratio Ratio of element abundance to solar. + * + * @param n_H_index Particle hydrogen number density index + * @param d_n_H Particle hydrogen number density offset + * @param He_index Particle helium fraction index + * @param d_He Particle helium fraction offset + * @param cooling #cooling_function_data structure + * + * @param dLambdaNet_du (return) Derivative of the cooling rate with respect + * to u. + * + * @return The cooling rate + */ + INLINE static double eagle_cooling_rate( + double log_u_cgs, double redshift, double n_H_cgs, + const float abundance_ratio[chemistry_element_count + 2], int n_H_index, + float d_n_H, int He_index, float d_He, + const struct cooling_function_data *restrict cooling, + double *dLambdaNet_du) { + + return eagle_metal_cooling_rate(log_u_cgs / M_LN10, redshift, n_H_cgs, + abundance_ratio, n_H_index, d_n_H, He_index, + d_He, cooling, dLambdaNet_du, + /*element_lambda=*/NULL); + } - return eagle_metal_cooling_rate(log_u_cgs / M_LN10, redshift, n_H_cgs, - abundance_ratio, n_H_index, d_n_H, He_index, - d_He, cooling, dLambdaNet_du, - /*element_lambda=*/NULL); -} + /** + * @brief Newton Raphson integration scheme to calculate particle cooling over + * timestep. This replaces bisection scheme used in EAGLE to minimize the + * number of array accesses. Integration defaults to bisection scheme (see + * function bisection_iter) if this function does not converge within a + * specified number of steps + * + * @param logu_init Initial guess for log(internal energy) + * @param u_ini Internal energy at beginning of hydro step + * @param n_H_index Particle hydrogen number density index + * @param d_n_H Particle hydrogen number density offset + * @param He_index Particle helium fraction index + * @param d_He Particle helium fraction offset + * @param He_reion_heat Heating due to helium reionization + * (only depends on redshift, so passed as parameter) + * @param p #part structure + * @param cosmo #cosmology structure + * @param cooling #cooling_function_data structure + * @param phys_const #phys_const data structure + * @param abundance_ratio Array of ratios of metal abundance to solar + * @param dt timestep + * @param bisection_flag Flag to identify if scheme failed to converge + */ + float newton_iter(float logu_init, double u_ini, int n_H_index, float d_n_H, + int He_index, float d_He, float He_reion_heat, + struct part *restrict p, + const struct cosmology *restrict cosmo, + const struct cooling_function_data *restrict cooling, + const struct phys_const *restrict phys_const, + const float abundance_ratio[chemistry_element_count + 2], + float dt, int *bisection_flag) { + + double logu, logu_old; + double dLambdaNet_du = 0.0, LambdaNet; + + /* table bounds */ + const float log_table_bound_high = + (cooling->Therm[eagle_cooling_N_temperature - 1] - 0.05) / M_LOG10E; + const float log_table_bound_low = (cooling->Therm[0] + 0.05) / M_LOG10E; + + /* convert Hydrogen mass fraction in Hydrogen number density */ + const float XH = + p->chemistry_data.smoothed_metal_mass_fraction[chemistry_element_H]; + const double n_H = hydro_get_physical_density(p, cosmo) * XH / + phys_const->const_proton_mass; + const double n_H_cgs = n_H * cooling->number_density_to_cgs; + + /* compute ratefact = n_H * n_H / rho; Might lead to round-off error: + * replaced by equivalent expression below */ + const double ratefact_cgs = n_H_cgs * XH * cooling->inv_proton_mass_cgs; + + logu_old = logu_init; + logu = logu_old; + int i = 0; + + float LambdaNet_old = 0; + LambdaNet = 0; + do /* iterate to convergence */ + { + logu_old = logu; + LambdaNet_old = LambdaNet; + LambdaNet = (He_reion_heat / (dt * ratefact_cgs)) + + eagle_cooling_rate(logu_old, cosmo->z, n_H_cgs, + abundance_ratio, n_H_index, d_n_H, + He_index, d_He, cooling, &dLambdaNet_du); + + /* Newton iteration. For details on how the cooling equation is integrated + * see documentation in theory/Cooling/ */ + logu = logu_old - (1.0 - u_ini * exp(-logu_old) - + LambdaNet * ratefact_cgs * dt * exp(-logu_old)) / + (1.0 - dLambdaNet_du * ratefact_cgs * dt); + /* Check if first step passes over equilibrium solution, if it does adjust + * next guess */ + if (i == 1 && LambdaNet_old * LambdaNet < 0) + logu = newton_log_u_guess_cgs; + + /* check whether iterations go within about 10% of the table bounds, + * if they do default to bisection method */ + if (logu > log_table_bound_high) { + i = newton_max_iterations; + break; + } else if (logu < log_table_bound_low) { + i = newton_max_iterations; + break; + } -/** - * @brief Newton Raphson integration scheme to calculate particle cooling over - * timestep. This replaces bisection scheme used in EAGLE to minimize the - * number of array accesses. Integration defaults to bisection scheme (see - * function bisection_iter) if this function does not converge within a - * specified number of steps - * - * @param logu_init Initial guess for log(internal energy) - * @param u_ini Internal energy at beginning of hydro step - * @param n_H_index Particle hydrogen number density index - * @param d_n_H Particle hydrogen number density offset - * @param He_index Particle helium fraction index - * @param d_He Particle helium fraction offset - * @param He_reion_heat Heating due to helium reionization - * (only depends on redshift, so passed as parameter) - * @param p #part structure - * @param cosmo #cosmology structure - * @param cooling #cooling_function_data structure - * @param phys_const #phys_const data structure - * @param abundance_ratio Array of ratios of metal abundance to solar - * @param dt timestep - * @param bisection_flag Flag to identify if scheme failed to converge - */ -float newton_iter( - float logu_init, double u_ini, int n_H_index, float d_n_H, int He_index, - float d_He, float He_reion_heat, struct part *restrict p, - const struct cosmology *restrict cosmo, - const struct cooling_function_data *restrict cooling, - const struct phys_const *restrict phys_const, - const float abundance_ratio[chemistry_element_count + 2], float dt, - int *bisection_flag) { - - double logu, logu_old; - double dLambdaNet_du = 0.0, LambdaNet; - - /* table bounds */ - const float log_table_bound_high = - (cooling->Therm[eagle_cooling_N_temperature - 1] - 0.05) / M_LOG10E; - const float log_table_bound_low = (cooling->Therm[0] + 0.05) / M_LOG10E; - - /* convert Hydrogen mass fraction in Hydrogen number density */ - const float XH = - p->chemistry_data.smoothed_metal_mass_fraction[chemistry_element_H]; - const double n_H = - hydro_get_physical_density(p, cosmo) * XH / phys_const->const_proton_mass; - const double n_H_cgs = n_H * cooling->number_density_to_cgs; - - /* compute ratefact = n_H * n_H / rho; Might lead to round-off error: - * replaced by equivalent expression below */ - const double ratefact_cgs = n_H_cgs * XH * cooling->inv_proton_mass_cgs; - - logu_old = logu_init; - logu = logu_old; - int i = 0; - - float LambdaNet_old = 0; - LambdaNet = 0; - do /* iterate to convergence */ - { - logu_old = logu; - LambdaNet_old = LambdaNet; - LambdaNet = (He_reion_heat / (dt * ratefact_cgs)) + - eagle_cooling_rate(logu_old, cosmo->z, n_H_cgs, abundance_ratio, - n_H_index, d_n_H, He_index, d_He, cooling, - &dLambdaNet_du); - - /* Newton iteration. For details on how the cooling equation is integrated - * see documentation in theory/Cooling/ */ - logu = logu_old - (1.0 - u_ini * exp(-logu_old) - - LambdaNet * ratefact_cgs * dt * exp(-logu_old)) / - (1.0 - dLambdaNet_du * ratefact_cgs * dt); - /* Check if first step passes over equilibrium solution, if it does adjust - * next guess */ - if (i == 1 && LambdaNet_old * LambdaNet < 0) logu = newton_log_u_guess_cgs; - - /* check whether iterations go within about 10% of the table bounds, - * if they do default to bisection method */ - if (logu > log_table_bound_high) { - i = newton_max_iterations; - break; - } else if (logu < log_table_bound_low) { - i = newton_max_iterations; - break; + i++; + } while (fabs(logu - logu_old) > newton_tolerance && + i < newton_max_iterations); + if (i >= newton_max_iterations) { + /* flag to trigger bisection scheme */ + *bisection_flag = 1; } - i++; - } while (fabs(logu - logu_old) > newton_tolerance && - i < newton_max_iterations); - if (i >= newton_max_iterations) { - /* flag to trigger bisection scheme */ - *bisection_flag = 1; + return logu; } - - return logu; -} -- GitLab From d07b2d173a5d83830b5a11321bb7f00ab8b2b627 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Thu, 25 Apr 2019 20:22:39 +0200 Subject: [PATCH 73/79] Fix compilation in the case without EAGLE model. --- src/entropy_floor.h | 7 ++++--- src/star_formation.h | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/entropy_floor.h b/src/entropy_floor.h index 1821f7a25..771bd098b 100644 --- a/src/entropy_floor.h +++ b/src/entropy_floor.h @@ -27,14 +27,15 @@ /* Config parameters. */ #include "../config.h" +/* Local includes */ #include "common_io.h" #include "error.h" #include "inline.h" /* Pre-declarations to avoid cyclic inclusions */ -static float hydro_get_physical_density(const struct part *restrict p, - const struct cosmology *cosmo); -static float hydro_get_comoving_density(const struct part *restrict p); +static INLINE float hydro_get_physical_density(const struct part *restrict p, + const struct cosmology *cosmo); +static INLINE float hydro_get_comoving_density(const struct part *restrict p); /* Import the right entropy floor definition */ #if defined(ENTROPY_FLOOR_NONE) diff --git a/src/star_formation.h b/src/star_formation.h index 5f873d2da..3fb6a9324 100644 --- a/src/star_formation.h +++ b/src/star_formation.h @@ -27,6 +27,9 @@ /* Config parameters. */ #include "../config.h" +/* Local includes */ +#include "hydro.h" + /* Import the right star formation law definition */ #if defined(STAR_FORMATION_NONE) #include "./star_formation/none/star_formation.h" -- GitLab From aa7d84828e247b63ba95161b5edfe6d48d68a442 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 29 Apr 2019 10:18:38 +0200 Subject: [PATCH 74/79] Minor style improvements. --- src/cooling/EAGLE/cooling.c | 3 ++- src/hydro/AnarchyPU/hydro.h | 3 ++- src/hydro/AnarchyPU/hydro_iact.h | 6 +++--- src/hydro/Minimal/hydro.h | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/cooling/EAGLE/cooling.c b/src/cooling/EAGLE/cooling.c index ee4be9b1a..5a83b00bf 100644 --- a/src/cooling/EAGLE/cooling.c +++ b/src/cooling/EAGLE/cooling.c @@ -604,7 +604,8 @@ void cooling_cool_part(const struct phys_const *phys_const, /* Limit imposed by the entropy floor */ const double A_floor = entropy_floor(p, cosmo, floor_props); const double rho_physical = hydro_get_physical_density(p, cosmo); - const double u_floor = gas_internal_energy_from_entropy(rho_physical, A_floor); + const double u_floor = + gas_internal_energy_from_entropy(rho_physical, A_floor); u_final = max(u_final, u_floor); /* Expected change in energy over the next kick step diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index ac755759d..b28ecfb1a 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -604,6 +604,7 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_gradient( */ __attribute__((always_inline)) INLINE static void hydro_reset_gradient( struct part *restrict p) { + p->viscosity.v_sig = 2.f * p->force.soundspeed; } @@ -628,7 +629,7 @@ __attribute__((always_inline)) INLINE static void hydro_end_gradient( /* Include the extra factors in the del^2 u */ - p->diffusion.laplace_u *= 2 * h_inv_dim_plus_one; + p->diffusion.laplace_u *= 2.f * h_inv_dim_plus_one; } /** diff --git a/src/hydro/AnarchyPU/hydro_iact.h b/src/hydro/AnarchyPU/hydro_iact.h index d091ebebc..f3a8734fb 100644 --- a/src/hydro/AnarchyPU/hydro_iact.h +++ b/src/hydro/AnarchyPU/hydro_iact.h @@ -364,7 +364,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( /* Includes the hubble flow term; not used for du/dt */ const float dvdr_Hubble = dvdr + a2_Hubble * r2; - /* Are the part*icles moving towards each others ? */ + /* Are the particles moving towards each others ? */ const float omega_ij = min(dvdr_Hubble, 0.f); const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ @@ -495,7 +495,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( /* Includes the hubble flow term; not used for du/dt */ const float dvdr_Hubble = dvdr + a2_Hubble * r2; - /* Are the part*icles moving towards each others ? */ + /* Are the particles moving towards each others ? */ const float omega_ij = min(dvdr_Hubble, 0.f); const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */ @@ -600,4 +600,4 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_limiter( } } -#endif /* SWIFT_MINIMAL_HYDRO_IACT_H */ +#endif /* SWIFT_ANARCHY_PU_HYDRO_IACT_H */ diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index 13366a29e..6169bcdfe 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -672,7 +672,7 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( const float floor_u = gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); - /* Check agains absolute minimum */ + /* Check against absolute minimum */ const float min_u = hydro_props->minimal_internal_energy; p->u = max(p->u, floor_u); -- GitLab From 293c6ca02afa60278d3d7b5889c0e2926714d0f7 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 29 Apr 2019 10:20:02 +0200 Subject: [PATCH 75/79] Better choice of softening length for the isolated galaxy with feedback example. --- .../isolated_galaxy.yml | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml index b7e29d8df..e4e084f30 100644 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml @@ -10,8 +10,8 @@ InternalUnitSystem: Gravity: eta: 0.025 # Constant dimensionless multiplier for time integration. theta: 0.7 # Opening angle (Multipole acceptance criterion). - comoving_softening: 0.01 # Comoving softening length (in internal units). - max_physical_softening: 0.01 # Physical softening length (in internal units). + comoving_softening: 0.1 # Comoving softening length (in internal units). + max_physical_softening: 0.1 # Physical softening length (in internal units). # Parameters governing the time integration (Set dt_min and dt_max to the same value for a fixed time-step run.) TimeIntegration: @@ -69,16 +69,16 @@ EAGLEChemistry: # Hernquist potential parameters HernquistPotential: - useabspos: 0 # 0 -> positions based on centre, 1 -> absolute positions + useabspos: 0 # 0 -> positions based on centre, 1 -> absolute positions position: [0.,0.,0.] # Location of centre of isothermal potential with respect to centre of the box (if 0) otherwise absolute (if 1) (internal units) - idealizeddisk: 1 # Run with an idealized galaxy disk + idealizeddisk: 1 # Run with an idealized galaxy disk M200: 137.0 # M200 of the galaxy disk - h: 0.704 # reduced Hubble constant (value does not specify the used units!) - concentration: 9.0 # concentration of the Halo - diskfraction: 0.040 # Disk mass fraction - bulgefraction: 0.014 # Bulge mass fraction - timestep_mult: 0.01 # Dimensionless pre-factor for the time-step condition, basically determines the fraction of the orbital time we use to do the time integration - epsilon: 0.01 # Softening size (internal units) + h: 0.704 # reduced Hubble constant (value does not specify the used units!) + concentration: 9.0 # concentration of the Halo + diskfraction: 0.040 # Disk mass fraction + bulgefraction: 0.014 # Bulge mass fraction + timestep_mult: 0.01 # Dimensionless pre-factor for the time-step condition, basically determines the fraction of the orbital time we use to do the time integration + epsilon: 0.1 # Softening size (internal units) # EAGLE star formation parameters EAGLEStarFormation: -- GitLab From 51dc2a3321703d273631418b747f52bd0fe9e076 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 29 Apr 2019 10:58:32 +0200 Subject: [PATCH 76/79] Also update the Planetary SPH for the new signature. --- src/hydro/Planetary/hydro.h | 63 ++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 25 deletions(-) diff --git a/src/hydro/Planetary/hydro.h b/src/hydro/Planetary/hydro.h index e03b307bc..ba9228289 100644 --- a/src/hydro/Planetary/hydro.h +++ b/src/hydro/Planetary/hydro.h @@ -39,6 +39,7 @@ #include "cosmology.h" #include "debug.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -638,6 +639,17 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( /* Re-set the entropy */ p->u = xp->u_full; + + /* Compute the pressure */ + const float pressure = + gas_pressure_from_internal_energy(p->rho, xp->u_full, p->mat_id); + + /* Compute the sound speed */ + const float soundspeed = + gas_soundspeed_from_internal_energy(p->rho, p->u, p->mat_id); + + p->force.pressure = pressure; + p->force.soundspeed = soundspeed; } /** @@ -653,10 +665,23 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle. * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The constants used in the scheme + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, const struct xpart *restrict xp, float dt_drift, - float dt_therm) { + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the internal energy */ + p->u += p->u_dt * dt_therm; + + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + + p->u = max(p->u, min_u); const float h_inv = 1.f / p->h; @@ -674,9 +699,6 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( else p->rho *= expf(w2); - /* Predict the internal energy */ - p->u += p->u_dt * dt_therm; - /* Compute the new pressure */ const float pressure = gas_pressure_from_internal_energy(p->rho, p->u, p->mat_id); @@ -718,36 +740,27 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_therm The time-step for this kick (for thermodynamic quantities). * @param cosmo The cosmological model. * @param hydro_props The constants used in the scheme + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) { + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Integrate the internal energy forward in time */ + const float delta_u = p->u_dt * dt_therm; /* Do not decrease the energy by more than a factor of 2*/ - if (dt_therm > 0. && p->u_dt * dt_therm < -0.5f * xp->u_full) { - p->u_dt = -0.5f * xp->u_full / dt_therm; - } - xp->u_full += p->u_dt * dt_therm; + xp->u_full = max(xp->u_full + delta_u, 0.5f * xp->u_full); + + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; - /* Apply the minimal energy limit */ - const float min_energy = - hydro_props->minimal_internal_energy * cosmo->a_factor_internal_energy; - if (xp->u_full < min_energy) { - xp->u_full = min_energy; + if (xp->u_full < min_u) { + xp->u_full = min_u; p->u_dt = 0.f; } - - /* Compute the pressure */ - const float pressure = - gas_pressure_from_internal_energy(p->rho, xp->u_full, p->mat_id); - - /* Compute the sound speed */ - const float soundspeed = - gas_soundspeed_from_internal_energy(p->rho, p->u, p->mat_id); - - p->force.pressure = pressure; - p->force.soundspeed = soundspeed; } /** -- GitLab From 8962d2416e954dc3b29f4b2c54bbbf6e4bd46e35 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 29 Apr 2019 11:14:20 +0200 Subject: [PATCH 77/79] Update the Anarchy scheme to check for the floor at the drift and kick --- src/hydro/AnarchyPU/hydro.h | 65 ++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 19 deletions(-) diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index b28ecfb1a..6d340f2e9 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -40,6 +40,7 @@ #include "approx_math.h" #include "cosmology.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -813,6 +814,11 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( /* Re-set the entropy */ p->u = xp->u_full; + + /* Compute the sound speed */ + const float soundspeed = hydro_get_comoving_soundspeed(p); + + p->force.soundspeed = soundspeed; } /** @@ -828,10 +834,29 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle. * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, const struct xpart *restrict xp, float dt_drift, - float dt_therm) { + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the internal energy */ + p->u += p->u_dt * dt_therm; + + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); + + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + + p->u = max(p->u, floor_u); + p->u = max(p->u, min_u); const float h_inv = 1.f / p->h; @@ -855,9 +880,6 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->pressure_bar *= expf_exact; } - /* Predict the internal energy */ - p->u += p->u_dt * dt_therm; - /* Compute the new sound speed */ const float soundspeed = hydro_get_comoving_soundspeed(p); @@ -896,30 +918,35 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_kick_corr The time-step for this kick (for gravity corrections). * @param cosmo The cosmological model. * @param hydro_props The constants used in the scheme + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) { + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Integrate the internal energy forward in time */ + const float delta_u = p->u_dt * dt_therm; /* Do not decrease the energy by more than a factor of 2*/ - if (dt_therm > 0. && p->u_dt * dt_therm < -0.5f * xp->u_full) { - p->u_dt = -0.5f * xp->u_full / dt_therm; - } - xp->u_full += p->u_dt * dt_therm; + xp->u_full = max(xp->u_full + delta_u, 0.5f * xp->u_full); - /* Apply the minimal energy limit */ - const float min_energy = - hydro_props->minimal_internal_energy / cosmo->a_factor_internal_energy; - if (xp->u_full < min_energy) { - xp->u_full = min_energy; - p->u_dt = 0.f; - } + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); - /* Compute the sound speed */ - const float soundspeed = hydro_get_comoving_soundspeed(p); + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; - p->force.soundspeed = soundspeed; + /* Take highest of both limits */ + const float energy_min = max(min_u, floor_u); + + if (xp->u_full < energy_min) { + xp->u_full = energy_min; + p->u_dt = 0.f; + } } /** -- GitLab From 11f3db6d35267dee51a17f4047518064cbab2299 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Mon, 29 Apr 2019 16:04:20 +0200 Subject: [PATCH 78/79] Documentation fixes. --- doc/Doxyfile.in | 2 +- src/drift.h | 2 +- src/kick.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 8e5fa52b2..a3da1b4f8 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -811,7 +811,7 @@ RECURSIVE = NO # Note that relative paths are relative to the directory from which doxygen is # run. -EXCLUDE = +EXCLUDE = @top_srcdir@/src/cooling/EAGLE/newton_cooling.c # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded diff --git a/src/drift.h b/src/drift.h index 18f2ef998..b0b3e9729 100644 --- a/src/drift.h +++ b/src/drift.h @@ -75,7 +75,7 @@ __attribute__((always_inline)) INLINE static void drift_gpart( * @param ti_current Integer end of time-step (for debugging checks). * @param cosmo The cosmological model. * @param hydro_props The properties of the hydro scheme. - * @param floor_props The properties of the entropy floor. + * @param floor The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void drift_part( struct part *restrict p, struct xpart *restrict xp, double dt_drift, diff --git a/src/kick.h b/src/kick.h index 730dfebbd..404f7f311 100644 --- a/src/kick.h +++ b/src/kick.h @@ -71,7 +71,7 @@ __attribute__((always_inline)) INLINE static void kick_gpart( * @param dt_kick_corr The kick time-step for the gizmo-mfv gravity correction. * @param cosmo The cosmological model. * @param hydro_props The constants used in the scheme. - * @param entropy_floor_props Properties of the entropy floor. + * @param floor_props Properties of the entropy floor. * @param ti_start The starting (integer) time of the kick (for debugging * checks). * @param ti_end The ending (integer) time of the kick (for debugging checks). -- GitLab From 42cb1b4d531f8c5b27b4dd7ad6d158f7d746dbaf Mon Sep 17 00:00:00 2001 From: Matthieu Schaller Date: Wed, 1 May 2019 14:04:13 +0200 Subject: [PATCH 79/79] Updated the other hydro schemes with the new kick/drift signatures. --- src/hydro/Default/hydro.h | 35 +++++--- src/hydro/GizmoMFM/hydro.h | 20 ++++- src/hydro/GizmoMFV/hydro.h | 17 +++- src/hydro/PressureEnergy/hydro.h | 65 ++++++++++---- .../PressureEnergyMorrisMonaghanAV/hydro.h | 65 ++++++++++---- src/hydro/PressureEntropy/hydro.h | 88 ++++++++++++------- src/hydro/Shadowswift/hydro.h | 8 +- 7 files changed, 210 insertions(+), 88 deletions(-) diff --git a/src/hydro/Default/hydro.h b/src/hydro/Default/hydro.h index 175265dd4..c575fc54f 100644 --- a/src/hydro/Default/hydro.h +++ b/src/hydro/Default/hydro.h @@ -23,6 +23,7 @@ #include "approx_math.h" #include "cosmology.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -617,11 +618,29 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, struct xpart *restrict xp, float dt_drift, - float dt_therm) { - float u, w; + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the internal energy */ + p->u += p->force.u_dt * dt_therm; + + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); + + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + + p->u = max(p->u, floor_u); + p->u = max(p->u, min_u); const float h_inv = 1.f / p->h; @@ -639,15 +658,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( else p->rho *= expf(w2); - /* Predict internal energy */ - w = p->force.u_dt / p->u * dt_therm; - if (fabsf(w) < 0.2f) - u = p->u *= approx_expf(w); - else - u = p->u *= expf(w); - /* Predict gradient term */ - p->force.P_over_rho2 = u * hydro_gamma_minus_one / (p->rho * xp->omega); + p->force.P_over_rho2 = p->u * hydro_gamma_minus_one / (p->rho * xp->omega); } /** @@ -673,7 +685,8 @@ __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_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) {} + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) {} /** * @brief Converts hydro quantity of a particle at the start of a run diff --git a/src/hydro/GizmoMFM/hydro.h b/src/hydro/GizmoMFM/hydro.h index 3456e6f9e..c744a189a 100644 --- a/src/hydro/GizmoMFM/hydro.h +++ b/src/hydro/GizmoMFM/hydro.h @@ -23,6 +23,7 @@ #include "adiabatic_index.h" #include "approx_math.h" #include "cosmology.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_gradients.h" #include "hydro_properties.h" @@ -498,7 +499,9 @@ __attribute__((always_inline)) INLINE static void hydro_reset_acceleration( * @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) {} + struct part* restrict p, const struct xpart* restrict xp) { + // MATTHIEU: Do we need something here? +} /** * @brief Converts the hydrodynamic variables from the initial condition file to @@ -524,9 +527,14 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( * @param xp The extended particle data to act upon. * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part* p, struct xpart* xp, float dt_drift, float dt_therm) { + struct part* p, struct xpart* xp, float dt_drift, float dt_therm, + const struct cosmology* cosmo, const struct hydro_props* hydro_props, + const struct entropy_floor_properties* floor_props) { const float h_inv = 1.0f / p->h; @@ -565,6 +573,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( #endif } + // MATTHIEU: Apply the entropy floor here. + #ifdef SWIFT_DEBUG_CHECKS if (p->h <= 0.0f) { error("Zero or negative smoothing length (%g)!", p->h); @@ -611,11 +621,13 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_kick_corr Gravity correction time-step @f$adt@f$. * @param cosmo Cosmology. * @param hydro_props Additional hydro properties. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part* p, struct xpart* xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, const struct cosmology* cosmo, - const struct hydro_props* hydro_props) { + const struct hydro_props* hydro_props, + const struct entropy_floor_properties* floor_props) { float a_grav[3]; @@ -646,6 +658,8 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( p->flux.energy = 0.0f; } + // MATTHIEU: Apply the entropy floor here. + gizmo_check_physical_quantities( "mass", "energy", p->conserved.mass, p->conserved.momentum[0], p->conserved.momentum[1], p->conserved.momentum[2], p->conserved.energy); diff --git a/src/hydro/GizmoMFV/hydro.h b/src/hydro/GizmoMFV/hydro.h index 526d84289..1f26f29fa 100644 --- a/src/hydro/GizmoMFV/hydro.h +++ b/src/hydro/GizmoMFV/hydro.h @@ -23,6 +23,7 @@ #include "adiabatic_index.h" #include "approx_math.h" #include "cosmology.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_gradients.h" #include "hydro_properties.h" @@ -540,7 +541,9 @@ __attribute__((always_inline)) INLINE static void hydro_reset_gradient( * @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) {} + struct part* restrict p, const struct xpart* restrict xp) { + // MATTHIEU: Apply the entropy floor here. +} /** * @brief Converts the hydrodynamic variables from the initial condition file to @@ -568,7 +571,9 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( * @param dt_therm The drift time-step for thermal quantities. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part* p, struct xpart* xp, float dt_drift, float dt_therm) { + struct part* p, struct xpart* xp, float dt_drift, float dt_therm, + const struct cosmology* cosmo, const struct hydro_props* hydro_props, + const struct entropy_floor_properties* floor_props) { #ifdef GIZMO_LLOYD_ITERATION return; @@ -620,6 +625,8 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( #endif } + // MATTHIEU: Apply the entropy floor here. + /* we use a sneaky way to get the gravitational contribution to the velocity update */ p->primitives.v[0] += p->v[0] - xp->v_full[0]; @@ -671,11 +678,13 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_kick_corr Gravity correction time-step @f$adt@f$. * @param cosmo Cosmology. * @param hydro_props Additional hydro properties. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part* p, struct xpart* xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, const struct cosmology* cosmo, - const struct hydro_props* hydro_props) { + const struct hydro_props* hydro_props, + const struct entropy_floor_properties* floor_props) { float a_grav[3]; @@ -741,6 +750,8 @@ __attribute__((always_inline)) INLINE static void hydro_kick_extra( p->conserved.flux.energy = 0.f; } + // MATTHIEU: Apply the entropy floor here. + gizmo_check_physical_quantities( "mass", "energy", p->conserved.mass, p->conserved.momentum[0], p->conserved.momentum[1], p->conserved.momentum[2], p->conserved.energy); diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index 3fe3c805f..b342120f1 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -40,6 +40,7 @@ #include "approx_math.h" #include "cosmology.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -660,6 +661,11 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( /* Re-set the entropy */ p->u = xp->u_full; + + /* Compute the sound speed */ + const float soundspeed = hydro_get_comoving_soundspeed(p); + + p->force.soundspeed = soundspeed; } /** @@ -675,10 +681,29 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle. * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, const struct xpart *restrict xp, float dt_drift, - float dt_therm) { + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the internal energy */ + p->u += p->u_dt * dt_therm; + + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); + + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + + p->u = max(p->u, floor_u); + p->u = max(p->u, min_u); const float h_inv = 1.f / p->h; @@ -702,9 +727,6 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->pressure_bar *= expf_exact; } - /* Predict the internal energy */ - p->u += p->u_dt * dt_therm; - /* Compute the new sound speed */ const float soundspeed = hydro_get_comoving_soundspeed(p); @@ -743,30 +765,35 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_kick_corr The time-step for this kick (for gravity corrections). * @param cosmo The cosmological model. * @param hydro_props The constants used in the scheme + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) { + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Integrate the internal energy forward in time */ + const float delta_u = p->u_dt * dt_therm; /* Do not decrease the energy by more than a factor of 2*/ - if (dt_therm > 0. && p->u_dt * dt_therm < -0.5f * xp->u_full) { - p->u_dt = -0.5f * xp->u_full / dt_therm; - } - xp->u_full += p->u_dt * dt_therm; + xp->u_full = max(xp->u_full + delta_u, 0.5f * xp->u_full); - /* Apply the minimal energy limit */ - const float min_energy = - hydro_props->minimal_internal_energy / cosmo->a_factor_internal_energy; - if (xp->u_full < min_energy) { - xp->u_full = min_energy; - p->u_dt = 0.f; - } + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); - /* Compute the sound speed */ - const float soundspeed = hydro_get_comoving_soundspeed(p); + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; - p->force.soundspeed = soundspeed; + /* Take highest of both limits */ + const float energy_min = max(min_u, floor_u); + + if (xp->u_full < energy_min) { + xp->u_full = energy_min; + p->u_dt = 0.f; + } } /** diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h index be6a789eb..de5ebafb2 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h @@ -41,6 +41,7 @@ #include "approx_math.h" #include "cosmology.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -674,6 +675,11 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( /* Re-set the entropy */ p->u = xp->u_full; + + /* Compute the sound speed */ + const float soundspeed = hydro_get_comoving_soundspeed(p); + + p->force.soundspeed = soundspeed; } /** @@ -689,10 +695,29 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle. * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, const struct xpart *restrict xp, float dt_drift, - float dt_therm) { + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the internal energy */ + p->u += p->u_dt * dt_therm; + + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); + + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + + p->u = max(p->u, floor_u); + p->u = max(p->u, min_u); const float h_inv = 1.f / p->h; @@ -716,9 +741,6 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->pressure_bar *= expf_exact; } - /* Predict the internal energy */ - p->u += p->u_dt * dt_therm; - /* Compute the new sound speed */ const float soundspeed = hydro_get_comoving_soundspeed(p); @@ -757,30 +779,35 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_kick_corr The time-step for this kick (for gravity corrections). * @param cosmo The cosmological model. * @param hydro_props The constants used in the scheme + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) { + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Integrate the internal energy forward in time */ + const float delta_u = p->u_dt * dt_therm; /* Do not decrease the energy by more than a factor of 2*/ - if (dt_therm > 0. && p->u_dt * dt_therm < -0.5f * xp->u_full) { - p->u_dt = -0.5f * xp->u_full / dt_therm; - } - xp->u_full += p->u_dt * dt_therm; + xp->u_full = max(xp->u_full + delta_u, 0.5f * xp->u_full); - /* Apply the minimal energy limit */ - const float min_energy = - hydro_props->minimal_internal_energy / cosmo->a_factor_internal_energy; - if (xp->u_full < min_energy) { - xp->u_full = min_energy; - p->u_dt = 0.f; - } + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + const float floor_u = + gas_internal_energy_from_entropy(p->rho * cosmo->a3_inv, floor_A); - /* Compute the sound speed */ - const float soundspeed = hydro_get_comoving_soundspeed(p); + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; - p->force.soundspeed = soundspeed; + /* Take highest of both limits */ + const float energy_min = max(min_u, floor_u); + + if (xp->u_full < energy_min) { + xp->u_full = energy_min; + p->u_dt = 0.f; + } } /** diff --git a/src/hydro/PressureEntropy/hydro.h b/src/hydro/PressureEntropy/hydro.h index 578bebf63..8fdd201cf 100644 --- a/src/hydro/PressureEntropy/hydro.h +++ b/src/hydro/PressureEntropy/hydro.h @@ -35,6 +35,7 @@ #include "approx_math.h" #include "cosmology.h" #include "dimension.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_properties.h" #include "hydro_space.h" @@ -614,6 +615,21 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( /* Re-set the entropy */ p->entropy = xp->entropy_full; + + /* 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); + + /* Divide the pressure by the density squared to get the SPH term */ + const float rho_inv = 1.f / p->rho; + const float P_over_rho2 = pressure * rho_inv * rho_inv; + + /* Update variables */ + p->force.soundspeed = soundspeed; + p->force.P_over_rho2 = P_over_rho2; + p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); } /** @@ -623,10 +639,29 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( * @param xp The extended data of the particle * @param dt_drift The drift time-step for positions. * @param dt_therm The drift time-step for thermal quantities. + * @param cosmo The cosmological model. + * @param hydro_props The properties of the hydro scheme. + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( struct part *restrict p, const struct xpart *restrict xp, float dt_drift, - float dt_therm) { + float dt_therm, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { + + /* Predict the entropy */ + p->entropy += p->entropy_dt * dt_therm; + + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); + + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + const float min_A = + gas_entropy_from_internal_energy(p->rho * cosmo->a3_inv, min_u); + + p->entropy = max(p->entropy, floor_A); + p->entropy = max(p->entropy, min_A); const float h_inv = 1.f / p->h; @@ -647,9 +682,6 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->rho_bar *= expf(w2); } - /* Predict the entropy */ - p->entropy += p->entropy_dt * dt_therm; - /* Compute the pressure */ const float pressure = gas_pressure_from_entropy(p->rho_bar, p->entropy); @@ -691,42 +723,36 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( * @param dt_therm The time-step for this kick (for thermodynamic quantities) * @param cosmo The cosmological model. * @param hydro_props The constants used in the scheme + * @param floor_props The properties of the entropy floor. */ __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part *restrict p, struct xpart *restrict xp, float dt_therm, float dt_grav, float dt_hydro, float dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props) { + const struct cosmology *cosmo, const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props) { - /* Do not decrease the entropy (temperature) by more than a factor of 2*/ - if (dt_therm > 0. && p->entropy_dt * dt_therm < -0.5f * xp->entropy_full) { - p->entropy_dt = -0.5f * xp->entropy_full / dt_therm; - } - xp->entropy_full += p->entropy_dt * dt_therm; - - /* Apply the minimal energy limit */ - const float density = p->rho_bar * cosmo->a3_inv; - const float min_energy = hydro_props->minimal_internal_energy; - const float min_entropy = - gas_entropy_from_internal_energy(density, min_energy); - if (xp->entropy_full < min_entropy) { - xp->entropy_full = min_entropy; - p->entropy_dt = 0.f; - } + /* Integrate the entropy forward in time */ + const float delta_entropy = p->entropy_dt * dt_therm; - /* Compute the pressure */ - const float pressure = - gas_pressure_from_entropy(p->rho_bar, xp->entropy_full); + /* Do not decrease the entropy by more than a factor of 2 */ + xp->entropy_full = + max(xp->entropy_full + delta_entropy, 0.5f * xp->entropy_full); - /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho_bar, pressure); + /* Check against entropy floor */ + const float floor_A = entropy_floor(p, cosmo, floor_props); - /* Divide the pressure by the density squared to get the SPH term */ - const float rho_bar_inv = 1.f / p->rho_bar; - const float P_over_rho2 = pressure * rho_bar_inv * rho_bar_inv; + /* Check against absolute minimum */ + const float min_u = hydro_props->minimal_internal_energy; + const float min_A = + gas_entropy_from_internal_energy(p->rho * cosmo->a3_inv, min_u); - p->entropy_one_over_gamma = pow_one_over_gamma(p->entropy); - p->force.soundspeed = soundspeed; - p->force.P_over_rho2 = P_over_rho2; + /* Take highest of both limits */ + const float entropy_min = max(min_A, floor_A); + + if (xp->entropy_full < entropy_min) { + xp->entropy_full = entropy_min; + p->entropy_dt = 0.f; + } } /** diff --git a/src/hydro/Shadowswift/hydro.h b/src/hydro/Shadowswift/hydro.h index 9ac89fa02..ed1b00019 100644 --- a/src/hydro/Shadowswift/hydro.h +++ b/src/hydro/Shadowswift/hydro.h @@ -23,6 +23,7 @@ #include "adiabatic_index.h" #include "approx_math.h" #include "cosmology.h" +#include "entropy_floor.h" #include "equation_of_state.h" #include "hydro_gradients.h" #include "hydro_properties.h" @@ -431,7 +432,9 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( * @param dt The drift time-step. */ __attribute__((always_inline)) INLINE static void hydro_predict_extra( - struct part* p, struct xpart* xp, float dt_drift, float dt_therm) {} + struct part* p, struct xpart* xp, float dt_drift, float dt_therm, + const struct cosmology* cosmo, const struct hydro_props* hydro_props, + const struct entropy_floor_properties* floor_props) {} /** * @brief Set the particle acceleration after the flux loop. @@ -453,7 +456,8 @@ __attribute__((always_inline)) INLINE static void hydro_end_force( __attribute__((always_inline)) INLINE static void hydro_kick_extra( struct part* p, struct xpart* xp, float dt, float dt_grav, float dt_hydro, float dt_kick_corr, const struct cosmology* cosmo, - const struct hydro_props* hydro_props) { + const struct hydro_props* hydro_props, + const struct entropy_floor_properties* floor_props) { /* Update the conserved variables. We do this here and not in the kick, since we need the updated variables below. */ -- GitLab