diff --git a/configure.ac b/configure.ac index 24b103480a7bbd2001d0ee473d6f2f7751a6c85f..0f8feb9907441e4ca6943f7786c70f7c2104e6d0 100644 --- a/configure.ac +++ b/configure.ac @@ -1327,6 +1327,7 @@ with_subgrid_cooling=none with_subgrid_chemistry=none with_subgrid_tracers=none with_subgrid_entropy_floor=none +with_subgrid_pressure_floor=none with_subgrid_stars=none with_subgrid_star_formation=none with_subgrid_feedback=none @@ -1338,10 +1339,9 @@ case "$with_subgrid" in none) ;; GEAR) - with_subgrid_cooling=grackle + with_subgrid_cooling=grackle_0 with_subgrid_chemistry=GEAR - with_subgrid_tracers=none - with_subgrid_entropy_floor=none + with_subgrid_pressure_floor=GEAR with_subgrid_stars=GEAR with_subgrid_star_formation=GEAR with_subgrid_feedback=none @@ -1400,6 +1400,12 @@ AC_ARG_WITH([gravity], [with_gravity="default"] ) +if test "$with_subgrid" = "EAGLE"; then + if test "$with_gravity" = "default"; then + with_gravity="with-potential" + fi +fi + case "$with_gravity" in with-potential) AC_DEFINE([POTENTIAL_GRAVITY], [1], [Gravity scheme with potential calculation]) @@ -1643,7 +1649,8 @@ esac # Cooling function AC_ARG_WITH([cooling], [AS_HELP_STRING([--with-cooling=<function>], - [cooling function @<:@none, const-du, const-lambda, EAGLE, grackle, grackle1, grackle2, grackle3 default: none@:>@] + [cooling function @<:@none, const-du, const-lambda, EAGLE, grackle_* default: none@:>@. + For Grackle, you need to provide the primordial chemistry parameter (e.g. grackle_0)] )], [with_cooling="$withval"], [with_cooling="none"] @@ -1670,21 +1677,10 @@ case "$with_cooling" in compton) AC_DEFINE([COOLING_COMPTON], [1], [Compton cooling off the CMB]) ;; - grackle) - AC_DEFINE([COOLING_GRACKLE], [1], [Cooling via the grackle library]) - AC_DEFINE([COOLING_GRACKLE_MODE], [0], [Grackle chemistry network, mode 0]) - ;; - grackle1) - AC_DEFINE([COOLING_GRACKLE], [1], [Cooling via the grackle library]) - AC_DEFINE([COOLING_GRACKLE_MODE], [1], [Grackle chemistry network, mode 1]) - ;; - grackle2) + grackle_*) AC_DEFINE([COOLING_GRACKLE], [1], [Cooling via the grackle library]) - AC_DEFINE([COOLING_GRACKLE_MODE], [2], [Grackle chemistry network, mode 2]) - ;; - grackle3) - AC_DEFINE([COOLING_GRACKLE], [1], [Cooling via the grackle library]) - AC_DEFINE([COOLING_GRACKLE_MODE], [3], [Grackle chemistry network, mode 3]) + primordial_chemistry=${with_cooling:8} + AC_DEFINE_UNQUOTED([COOLING_GRACKLE_MODE], [$primordial_chemistry], [Grackle chemistry network]) ;; EAGLE) AC_DEFINE([COOLING_EAGLE], [1], [Cooling following the EAGLE model]) @@ -1919,6 +1915,35 @@ case "$with_entropy_floor" in ;; esac +# Pressure floor +AC_ARG_WITH([pressure-floor], + [AS_HELP_STRING([--with-pressure-floor=<floor>], + [pressure floor @<:@none, GEAR, default: none@:>@ + The hydro model needs to be compatible.] + )], + [with_pressure_floor="$withval"], + [with_pressure_floor="none"] +) +if test "$with_subgrid" != "none"; then + if test "$with_pressure_floor" != "none"; then + AC_MSG_ERROR([Cannot provide with-subgrid and with-pressure-floor together]) + else + with_pressure_floor="$with_subgrid_pressure_floor" + fi +fi + +case "$with_pressure_floor" in + none) + AC_DEFINE([PRESSURE_FLOOR_NONE], [1], [No pressure floor]) + ;; + GEAR) + AC_DEFINE([PRESSURE_FLOOR_GEAR], [1], [GEAR pressure floor]) + ;; + *) + AC_MSG_ERROR([Unknown pressure floor model]) + ;; +esac + # Star formation AC_ARG_WITH([star-formation], [AS_HELP_STRING([--with-star-formation=<sfm>], @@ -1964,6 +1989,13 @@ AC_DEFINE_UNQUOTED([SELF_GRAVITY_MULTIPOLE_ORDER], [$with_multipole_order], [Mul AC_PATH_PROG([GIT_CMD], [git]) AC_SUBST([GIT_CMD]) +# Check that the gravity model is compatible with the subgrid +if test $with_black_holes = "EAGLE"; then + if test $with_gravity != "with-potential"; then + AC_MSG_ERROR([The EAGLE BH model needs the gravity scheme to provide potentials. The code must be compile with --with-gravity=with-potential.]) + fi +fi + # Make the documentation. Add conditional to handle disable option. DX_INIT_DOXYGEN(libswift,doc/Doxyfile,doc/) AM_CONDITIONAL([HAVE_DOXYGEN], [test "$ac_cv_path_ac_pt_DX_DOXYGEN" != ""]) @@ -2046,6 +2078,7 @@ AC_MSG_RESULT([ External potential : $with_potential Entropy floor : $with_entropy_floor + Pressure floor : $with_pressure_floor Cooling function : $with_cooling Chemistry : $with_chemistry Tracers : $with_tracers diff --git a/doc/RTD/source/SubgridModels/EAGLE/index.rst b/doc/RTD/source/SubgridModels/EAGLE/index.rst index 56736cc4cca4bd9042a2c84d07dcf535f48c566c..cac6716c7568b7c7d2168a77586cc80123df7127 100644 --- a/doc/RTD/source/SubgridModels/EAGLE/index.rst +++ b/doc/RTD/source/SubgridModels/EAGLE/index.rst @@ -577,6 +577,11 @@ Black-hole creation Black-hole accretion ~~~~~~~~~~~~~~~~~~~~ +.. _EAGLE_black_hole_reposition: + +Black-hole repositioning +~~~~~~~~~~~~~~~~~~~~~~~~ + .. _EAGLE_black_hole_feedback: AGN feedback diff --git a/doc/RTD/source/SubgridModels/GEAR/index.rst b/doc/RTD/source/SubgridModels/GEAR/index.rst index 2a211759bfc4895fd07279b72f78200d6ea47546..152056ef2eb60da189bf18b3b3c9909f88ace6de 100644 --- a/doc/RTD/source/SubgridModels/GEAR/index.rst +++ b/doc/RTD/source/SubgridModels/GEAR/index.rst @@ -5,6 +5,29 @@ GEAR model =========== +Pressure Floor +~~~~~~~~~~~~~~ + +In order to avoid the artificial collapse of unresolved clumps, a minimum in pressure is applied to the particles. +This additional pressure can be seen as the pressure due to unresolved hydrodynamics turbulence and is given by: + +.. math:: + P_\textrm{Jeans} = \frac{\rho}{\gamma} \left( \frac{4}{\pi} G h^2 \rho N_\textrm{Jeans}^{2/3} - \sigma^2 \right) + +where :math:`\rho` is the density, :math:`\gamma` the adiabatic index, :math:`G` is the gravitational constant, +:math:`h` the smoothing length, :math:`N_\textrm{Jeans}` is the number of particle required in order to resolve a clump and +:math:`\sigma` the velocity dispersion. + + +This must be directly implemented into the hydro schemes, therefore only a subset of schemes (Gadget-2 and Pressure-Energy) are currently implemented. +In order to implement it, you need equation 12 in `Hopkins 2013 <https://arxiv.org/abs/1206.5006>`_: + +.. math:: + m_i \frac{\mathrm{d}v_i}{\mathrm{d}t} = - \sum_j x_i x_j \left[ \frac{P_i}{y_i^2} f_{ij} \nabla_i W_{ij}(h_i) + \frac{P_j}{y_j^2} f_{ji} \nabla_j W_{ji}(h_j) \right] + +and simply replace the :math:`P_i, P_j` by the pressure with the floor. +Here the :math:`x, y` are simple weights that should never have the pressure floor included even if they are related to the pressure (e.g. pressure-entropy). + Cooling: Grackle ~~~~~~~~~~~~~~~~ diff --git a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml index 3270af86afffba13cfac6be7c7c21dd84980adc5..b5122afdba28ffaed1e52cdd8bd2db8a4e566c03 100644 --- a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml @@ -170,3 +170,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file diff --git a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml index 6461982f70c9635652b8253887a9998777f37c69..888009f27761feda91d3cb70df2366b9f04fd3eb 100644 --- a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml @@ -171,3 +171,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file diff --git a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml index c6f7f0e01bd292b03b0eb31c6c1b57d5163dafe7..f2e3b0656541ca698c20a85a308e538871d4fdc4 100644 --- a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml @@ -171,5 +171,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - - + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. diff --git a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml index 9205b9f6f560398b046625f6c65fcc887492991d..685d24d20f14f567175e1d7086a65455017199e0 100644 --- a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml @@ -162,3 +162,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file diff --git a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml index ccd89efbead0c511316bd664f6754ed0797c7c50..b782631d7e264e582455f70b4fb399f7db1f4731 100644 --- a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml @@ -169,3 +169,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file diff --git a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml index e2a98725a94c9fd34b45a95530f480562c0aaec8..53afda9445b4f8ee7c258b5c42af2a605eba4755 100644 --- a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml @@ -161,3 +161,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file diff --git a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml index 9136f85424beaf70b614cde0e70b67c134056831..694c1c111d8f5b2455d4cfcdc567b8854b12ff2c 100644 --- a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml +++ b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml @@ -171,3 +171,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file diff --git a/examples/SmallCosmoVolume/SmallCosmoVolume_cooling/small_cosmo_volume.yml b/examples/SmallCosmoVolume/SmallCosmoVolume_cooling/small_cosmo_volume.yml index b108290fcd146461827d5858742bd0971ac66945..94a9082af95e96b161cf5fe469eb082774e5007f 100644 --- a/examples/SmallCosmoVolume/SmallCosmoVolume_cooling/small_cosmo_volume.yml +++ b/examples/SmallCosmoVolume/SmallCosmoVolume_cooling/small_cosmo_volume.yml @@ -99,3 +99,6 @@ GrackleCooling: GearChemistry: InitialMetallicity: 0.01295 + +GEARPressureFloor: + Jeans_factor: 10. # Number of particles required to suppose a resolved clump and avoid the pressure floor. diff --git a/examples/main.c b/examples/main.c index 34bd9ff7ec68941f36da9a4992cb8318972bdd98..cf8734532a9b8e48997729d5d1b086b15c6859fc 100644 --- a/examples/main.c +++ b/examples/main.c @@ -771,6 +771,13 @@ int main(int argc, char *argv[]) { else bzero(&entropy_floor, sizeof(struct entropy_floor_properties)); + /* Initialise the pressure floor */ + if (with_hydro) + pressure_floor_init(&pressure_floor_props, &prog_const, &us, + &hydro_properties, params); + else + bzero(&pressure_floor_props, sizeof(struct pressure_floor_properties)); + /* Initialise the stars properties */ if (with_stars) stars_props_init(&stars_properties, &prog_const, &us, params, diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 8afe5b7b39afacfa23aaf8240c1d70ad33278385..3607690f7cbf07c86eb2d84cd742c734b33bd266 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -288,6 +288,11 @@ EAGLEEntropyFloor: 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 +# Parameters related to pressure floors ---------------------------------------------- + +GEARPressureFloor: + Jeans_factor: 10. # Number of particles required to suppose a resolved clump and avoid the pressure floor. + # Parameters related to cooling function ---------------------------------------------- # Constant du/dt cooling function @@ -341,6 +346,11 @@ EAGLEChemistry: # Parameters related to star formation models ----------------------------------------------- +# GEAR star formation model (Revaz and Jablonka 2018) +GEARStarFormation: + star_formation_efficiency: 0.01 # star formation efficiency (c_*) + maximal_temperature: 3e4 # Upper limit to the temperature of a star forming particle + # EAGLE star formation model (Schaye and Dalla Vecchia 2008) EAGLEStarFormation: EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. @@ -406,4 +416,4 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. diff --git a/src/Makefile.am b/src/Makefile.am index 0f7cef5e3c6b861ebde639d90624a360f1be7047..3d748b135c93cf409464a199232b243c699fabe1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -79,7 +79,7 @@ AM_SOURCES = space.c runner.c queue.c task.c cell.c engine.c engine_maketasks.c collectgroup.c hydro_space.c equation_of_state.c \ chemistry.c cosmology.c restart.c mesh_gravity.c velociraptor_interface.c \ outputlist.c velociraptor_dummy.c logger_io.c memuse.c fof.c \ - hashmap.c \ + hashmap.c pressure_floor.c \ $(EAGLE_COOLING_SOURCES) $(EAGLE_FEEDBACK_SOURCES) # Include files for distribution, not installation. @@ -98,28 +98,28 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h hydro.h hydro_io.h hydro_parameters.h \ hydro/Minimal/hydro.h hydro/Minimal/hydro_iact.h hydro/Minimal/hydro_io.h \ hydro/Minimal/hydro_debug.h hydro/Minimal/hydro_part.h \ - hydro/Minimal/hydro_parameters.h \ + hydro/Minimal/hydro_parameters.h \ hydro/Default/hydro.h hydro/Default/hydro_iact.h hydro/Default/hydro_io.h \ hydro/Default/hydro_debug.h hydro/Default/hydro_part.h \ - hydro/Default/hydro_parameters.h \ + hydro/Default/hydro_parameters.h \ hydro/Gadget2/hydro.h hydro/Gadget2/hydro_iact.h hydro/Gadget2/hydro_io.h \ hydro/Gadget2/hydro_debug.h hydro/Gadget2/hydro_part.h \ - hydro/Gadget2/hydro_parameters.h \ + hydro/Gadget2/hydro_parameters.h \ hydro/PressureEntropy/hydro.h hydro/PressureEntropy/hydro_iact.h hydro/PressureEntropy/hydro_io.h \ hydro/PressureEntropy/hydro_debug.h hydro/PressureEntropy/hydro_part.h \ - hydro/PressureEntropy/hydro_parameters.h \ + hydro/PressureEntropy/hydro_parameters.h \ hydro/PressureEnergy/hydro.h hydro/PressureEnergy/hydro_iact.h hydro/PressureEnergy/hydro_io.h \ hydro/PressureEnergy/hydro_debug.h hydro/PressureEnergy/hydro_part.h \ - hydro/PressureEnergy/hydro_parameters.h \ + hydro/PressureEnergy/hydro_parameters.h \ hydro/PressureEnergyMorrisMonaghanAV/hydro.h hydro/PressureEnergyMorrisMonaghanAV/hydro_iact.h hydro/PressureEnergyMorrisMonaghanAV/hydro_io.h \ hydro/PressureEnergyMorrisMonaghanAV/hydro_debug.h hydro/PressureEnergyMorrisMonaghanAV/hydro_part.h \ - hydro/PressureEnergyMorrisMonaghanAV/hydro_parameters.h \ + hydro/PressureEnergyMorrisMonaghanAV/hydro_parameters.h \ hydro/AnarchyPU/hydro.h hydro/PressureEnergy/hydro_iact.h hydro/PressureEnergy/hydro_io.h \ hydro/AnarchyPU/hydro_debug.h hydro/PressureEnergy/hydro_part.h \ - hydro/AnarchyPU/hydro_parameters.h \ + hydro/AnarchyPU/hydro_parameters.h \ hydro/AnarchyDU/hydro.h hydro/PressureEnergy/hydro_iact.h hydro/PressureEnergy/hydro_io.h \ hydro/AnarchyDU/hydro_debug.h hydro/PressureEnergy/hydro_part.h \ - hydro/AnarchyDU/hydro_parameters.h \ + hydro/AnarchyDU/hydro_parameters.h \ hydro/GizmoMFV/hydro.h hydro/GizmoMFV/hydro_iact.h \ hydro/GizmoMFV/hydro_io.h hydro/GizmoMFV/hydro_debug.h \ hydro/GizmoMFV/hydro_part.h \ @@ -131,7 +131,7 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h hydro/GizmoMFV/hydro_slope_limiters.h \ hydro/GizmoMFV/hydro_unphysical.h \ hydro/GizmoMFV/hydro_velocities.h \ - hydro/GizmoMFV/hydro_parameters.h \ + hydro/GizmoMFV/hydro_parameters.h \ hydro/GizmoMFM/hydro.h hydro/GizmoMFM/hydro_iact.h \ hydro/GizmoMFM/hydro_io.h hydro/GizmoMFM/hydro_debug.h \ hydro/GizmoMFM/hydro_part.h \ @@ -142,7 +142,7 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h hydro/GizmoMFM/hydro_slope_limiters_face.h \ hydro/GizmoMFM/hydro_slope_limiters.h \ hydro/GizmoMFM/hydro_unphysical.h \ - hydro/GizmoMFM/hydro_parameters.h \ + hydro/GizmoMFM/hydro_parameters.h \ hydro/Shadowswift/hydro_debug.h \ hydro/Shadowswift/hydro_gradients.h hydro/Shadowswift/hydro.h \ hydro/Shadowswift/hydro_iact.h \ @@ -190,7 +190,7 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h cooling/const_lambda/cooling_io.h \ cooling/grackle/cooling.h cooling/grackle/cooling_struct.h \ cooling/grackle/cooling_io.h \ - cooling/EAGLE/cooling.h cooling/EAGLE/cooling_struct.h \ + cooling/EAGLE/cooling.h cooling/EAGLE/cooling_struct.h cooling/EAGLE/cooling_tables.h \ cooling/EAGLE/cooling_io.h cooling/EAGLE/interpolate.h cooling/EAGLE/cooling_rates.h \ chemistry/none/chemistry.h \ chemistry/none/chemistry_io.h \ @@ -221,7 +221,10 @@ nobase_noinst_HEADERS = align.h approx_math.h atomic.h barrier.h cycle.h error.h black_holes/Default/black_holes_struct.h \ black_holes/EAGLE/black_holes.h black_holes/EAGLE/black_holes_io.h \ black_holes/EAGLE/black_holes_part.h black_holes/EAGLE/black_holes_iact.h \ - black_holes/EAGLE/black_holes_properties.h + black_holes/EAGLE/black_holes_properties.h \ + black_holes/EAGLE/black_holes_struct.h \ + pressure_floor.h \ + pressure_floor/GEAR/pressure_floor.h pressure_floor/none/pressure_floor.h # Sources and flags for regular library diff --git a/src/black_holes/Default/black_holes.h b/src/black_holes/Default/black_holes.h index 56866764fe4b65603309856bfb2c5ae6b8d82f00..082134cc78f5a7f5e0aa9adeb231c92b9d66c233 100644 --- a/src/black_holes/Default/black_holes.h +++ b/src/black_holes/Default/black_holes.h @@ -187,6 +187,20 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( const struct phys_const* constants, const struct cosmology* cosmo, const double dt) {} +/** + * @brief Finish the calculation of the new BH position. + * + * Nothing to do here. + * + * @param bp The black hole particle. + * @param props The properties of the black hole scheme. + * @param constants The physical constants (in internal units). + * @param cosmo The cosmological model. + */ +__attribute__((always_inline)) INLINE static void black_holes_end_reposition( + struct bpart* restrict bp, const struct black_holes_props* props, + const struct phys_const* constants, const struct cosmology* cosmo) {} + /** * @brief Reset acceleration fields of a particle * diff --git a/src/black_holes/Default/black_holes_iact.h b/src/black_holes/Default/black_holes_iact.h index ccb1e8c90cd8fef42dd0bb5b6e2d9c6eb9382226..b26b8a50f40599402f4ea9886dbbd7495e8efd59 100644 --- a/src/black_holes/Default/black_holes_iact.h +++ b/src/black_holes/Default/black_holes_iact.h @@ -30,16 +30,15 @@ * @param pj Second particle (gas, not updated). * @param xpj The extended data of the second particle (not updated). * @param cosmo The cosmological model. + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void -runner_iact_nonsym_bh_gas_density(const float r2, const float *dx, - const float hi, const float hj, - struct bpart *restrict bi, - const struct part *restrict pj, - const struct xpart *restrict xpj, - const struct cosmology *cosmo, - const integertime_t ti_current) { +runner_iact_nonsym_bh_gas_density( + const float r2, const float *dx, const float hi, const float hj, + struct bpart *restrict bi, const struct part *restrict pj, + const struct xpart *restrict xpj, const struct cosmology *cosmo, + const struct gravity_props *grav_props, const integertime_t ti_current) { float wi, wi_dx; @@ -80,16 +79,15 @@ runner_iact_nonsym_bh_gas_density(const float r2, const float *dx, * @param pj Second particle (gas) * @param xpj The extended data of the second particle. * @param cosmo The cosmological model. + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void -runner_iact_nonsym_bh_gas_swallow(const float r2, const float *dx, - const float hi, const float hj, - const struct bpart *restrict bi, - struct part *restrict pj, - struct xpart *restrict xpj, - const struct cosmology *cosmo, - const integertime_t ti_current) {} +runner_iact_nonsym_bh_gas_swallow( + const float r2, const float *dx, const float hi, const float hj, + const struct bpart *restrict bi, struct part *restrict pj, + struct xpart *restrict xpj, const struct cosmology *cosmo, + const struct gravity_props *grav_props, const integertime_t ti_current) {} /** * @brief Swallowing interaction between two BH particles (non-symmetric). @@ -104,7 +102,7 @@ runner_iact_nonsym_bh_gas_swallow(const float r2, const float *dx, * @param bi First particle (black hole). * @param bj Second particle (black hole) * @param cosmo The cosmological model. - * @param grav_props The properties of the gravity scheme (softening, G, ...) + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void @@ -127,16 +125,15 @@ runner_iact_nonsym_bh_bh_swallow(const float r2, const float *dx, * @param pj Second particle (gas) * @param xpj The extended data of the second particle. * @param cosmo The cosmological model. + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void -runner_iact_nonsym_bh_gas_feedback(const float r2, const float *dx, - const float hi, const float hj, - struct bpart *restrict bi, - struct part *restrict pj, - struct xpart *restrict xpj, - const struct cosmology *cosmo, - const integertime_t ti_current) { +runner_iact_nonsym_bh_gas_feedback( + const float r2, const float *dx, const float hi, const float hj, + struct bpart *restrict bi, struct part *restrict pj, + struct xpart *restrict xpj, const struct cosmology *cosmo, + const struct gravity_props *grav_props, const integertime_t ti_current) { #ifdef DEBUG_INTERACTIONS_BH /* Update ngb counters */ if (si->num_ngb_force < MAX_NUM_OF_NEIGHBOURS_BH) diff --git a/src/black_holes/Default/black_holes_io.h b/src/black_holes/Default/black_holes_io.h index 5288ae595663871bb3187782712d52708fac7931..53322da1dd90a98fb0f1f2529774a20dc718b30c 100644 --- a/src/black_holes/Default/black_holes_io.h +++ b/src/black_holes/Default/black_holes_io.h @@ -102,6 +102,7 @@ INLINE static void convert_bpart_vel(const struct engine* e, * @param bparts The b-particle array. * @param list The list of i/o properties to write. * @param num_fields The number of i/o fields to write. + * @param with_cosmology Are we running a cosmological simulation? */ INLINE static void black_holes_write_particles(const struct bpart* bparts, struct io_props* list, diff --git a/src/black_holes/EAGLE/black_holes.h b/src/black_holes/EAGLE/black_holes.h index 3bf4e2295e1e5f13993e94f76ef6b83882a5e2e7..a1b41f0954e1bec890329779d0edb7fcd31265f1 100644 --- a/src/black_holes/EAGLE/black_holes.h +++ b/src/black_holes/EAGLE/black_holes.h @@ -24,6 +24,7 @@ #include "black_holes_struct.h" #include "cosmology.h" #include "dimension.h" +#include "gravity.h" #include "kernel_hydro.h" #include "minmax.h" #include "physical_constants.h" @@ -89,16 +90,43 @@ __attribute__((always_inline)) INLINE static void black_holes_init_bpart( bp->circular_velocity_gas[2] = 0.f; bp->ngb_mass = 0.f; bp->num_ngbs = 0; + bp->reposition.x[0] = -FLT_MAX; + bp->reposition.x[1] = -FLT_MAX; + bp->reposition.x[2] = -FLT_MAX; + bp->reposition.min_potential = FLT_MAX; } /** * @brief Predict additional particle fields forward in time when drifting * + * The fields do not get predicted but we move the BH to its new position + * if a new one was calculated in the repositioning loop. + * * @param bp The particle * @param dt_drift The drift time-step for positions. */ __attribute__((always_inline)) INLINE static void black_holes_predict_extra( - struct bpart* restrict bp, float dt_drift) {} + struct bpart* restrict bp, float dt_drift) { + + /* Are we doing some repositioning? */ + if (bp->reposition.min_potential != FLT_MAX) { + +#ifdef SWIFT_DEBUG_CHECKS + if (bp->reposition.x[0] == -FLT_MAX || bp->reposition.x[1] == -FLT_MAX || + bp->reposition.x[2] == -FLT_MAX) { + error("Something went wrong with the new repositioning position"); + } +#endif + + bp->x[0] = bp->reposition.x[0]; + bp->x[1] = bp->reposition.x[1]; + bp->x[2] = bp->reposition.x[2]; + + bp->gpart->x[0] = bp->reposition.x[0]; + bp->gpart->x[1] = bp->reposition.x[1]; + bp->gpart->x[2] = bp->reposition.x[2]; + } +} /** * @brief Sets the values to be predicted in the drifts to their values at a @@ -430,6 +458,35 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( } } +/** + * @brief Finish the calculation of the new BH position. + * + * Here, we check that the BH should indeed be moved in the next drift. + * + * @param bp The black hole particle. + * @param props The properties of the black hole scheme. + * @param constants The physical constants (in internal units). + * @param cosmo The cosmological model. + */ +__attribute__((always_inline)) INLINE static void black_holes_end_reposition( + struct bpart* restrict bp, const struct black_holes_props* props, + const struct phys_const* constants, const struct cosmology* cosmo) { + + const float potential = gravity_get_comoving_potential(bp->gpart); + + /* Is the potential lower (i.e. the BH is at the bottom already) + * OR is the BH massive enough that we don't reposition? */ + if (potential < bp->reposition.min_potential || + bp->subgrid_mass > props->max_reposition_mass) { + + /* No need to reposition */ + bp->reposition.min_potential = FLT_MAX; + bp->reposition.x[0] = -FLT_MAX; + bp->reposition.x[1] = -FLT_MAX; + bp->reposition.x[2] = -FLT_MAX; + } +} + /** * @brief Reset acceleration fields of a particle * diff --git a/src/black_holes/EAGLE/black_holes_iact.h b/src/black_holes/EAGLE/black_holes_iact.h index fb787df2e34fcfec7cb2192c45f5bf5b4040ebe5..8fa27f162dacf11f7127e7cd473b36c4e2e00236 100644 --- a/src/black_holes/EAGLE/black_holes_iact.h +++ b/src/black_holes/EAGLE/black_holes_iact.h @@ -20,6 +20,7 @@ #define SWIFT_EAGLE_BH_IACT_H /* Local includes */ +#include "gravity.h" #include "hydro.h" #include "random.h" #include "space.h" @@ -35,16 +36,15 @@ * @param pj Second particle (gas, not updated). * @param xpj The extended data of the second particle (not updated). * @param cosmo The cosmological model. + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void -runner_iact_nonsym_bh_gas_density(const float r2, const float *dx, - const float hi, const float hj, - struct bpart *restrict bi, - const struct part *restrict pj, - const struct xpart *restrict xpj, - const struct cosmology *cosmo, - const integertime_t ti_current) { +runner_iact_nonsym_bh_gas_density( + const float r2, const float *dx, const float hi, const float hj, + struct bpart *restrict bi, const struct part *restrict pj, + const struct xpart *restrict xpj, const struct cosmology *cosmo, + const struct gravity_props *grav_props, const integertime_t ti_current) { float wi, wi_dx; @@ -117,16 +117,15 @@ runner_iact_nonsym_bh_gas_density(const float r2, const float *dx, * @param pj Second particle (gas) * @param xpj The extended data of the second particle. * @param cosmo The cosmological model. + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void -runner_iact_nonsym_bh_gas_swallow(const float r2, const float *dx, - const float hi, const float hj, - const struct bpart *restrict bi, - struct part *restrict pj, - struct xpart *restrict xpj, - const struct cosmology *cosmo, - const integertime_t ti_current) { +runner_iact_nonsym_bh_gas_swallow( + const float r2, const float *dx, const float hi, const float hj, + struct bpart *restrict bi, struct part *restrict pj, + struct xpart *restrict xpj, const struct cosmology *cosmo, + const struct gravity_props *grav_props, const integertime_t ti_current) { float wi; @@ -140,6 +139,44 @@ runner_iact_nonsym_bh_gas_swallow(const float r2, const float *dx, const float ui = r * hi_inv; kernel_eval(ui, &wi); + /* Start by checking the repositioning criteria */ + + /* Note the factor 9 is taken from EAGLE. Will be turned into a parameter */ + const float max_dist_repos2 = + kernel_gravity_softening_plummer_equivalent_inv * + kernel_gravity_softening_plummer_equivalent_inv * 9.f * + grav_props->epsilon_cur2; + + /* This gas neighbour is close enough that we can consider it's potential + for repositioning */ + if (r2 < max_dist_repos2) { + + /* Compute relative peculiar velocity between the two BHs + * Recall that in SWIFT v is (v_pec * a) */ + const float delta_v[3] = {bi->v[0] - pj->v[0], bi->v[1] - pj->v[1], + bi->v[2] - pj->v[2]}; + const float v2 = delta_v[0] * delta_v[0] + delta_v[1] * delta_v[1] + + delta_v[2] * delta_v[2]; + + const float v2_pec = v2 * cosmo->a2_inv; + + /* Check the velocity criterion */ + if (v2_pec < 0.25f * bi->sound_speed_gas * bi->sound_speed_gas) { + + const float potential = gravity_get_comoving_potential(pj->gpart); + + /* Is the potential lower? */ + if (potential < bi->reposition.min_potential) { + + /* Store this as our new best */ + bi->reposition.min_potential = potential; + bi->reposition.x[0] = pj->x[0]; + bi->reposition.x[1] = pj->x[1]; + bi->reposition.x[2] = pj->x[2]; + } + } + } + /* Is the BH hungry? */ if (bi->subgrid_mass > bi->mass) { @@ -188,13 +225,13 @@ runner_iact_nonsym_bh_gas_swallow(const float r2, const float *dx, * @param bi First particle (black hole). * @param bj Second particle (black hole) * @param cosmo The cosmological model. - * @param grav_props The properties of the gravity scheme (softening, G, ...) + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_bh_bh_swallow(const float r2, const float *dx, const float hi, const float hj, - const struct bpart *restrict bi, + struct bpart *restrict bi, struct bpart *restrict bj, const struct cosmology *cosmo, const struct gravity_props *grav_props, @@ -209,6 +246,33 @@ runner_iact_nonsym_bh_bh_swallow(const float r2, const float *dx, const float v2_pec = v2 * cosmo->a2_inv; + /* Note the factor 9 is taken from EAGLE. Will be turned into a parameter */ + const float max_dist_repos2 = + kernel_gravity_softening_plummer_equivalent_inv * + kernel_gravity_softening_plummer_equivalent_inv * 9.f * + grav_props->epsilon_cur2; + + /* This gas neighbour is close enough that we can consider it's potential + for repositioning */ + if (r2 < max_dist_repos2) { + + /* Check the velocity criterion */ + if (v2_pec < 0.25f * bi->sound_speed_gas * bi->sound_speed_gas) { + + const float potential = gravity_get_comoving_potential(bj->gpart); + + /* Is the potential lower? */ + if (potential < bi->reposition.min_potential) { + + /* Store this as our new best */ + bi->reposition.min_potential = potential; + bi->reposition.x[0] = bj->x[0]; + bi->reposition.x[1] = bj->x[1]; + bi->reposition.x[2] = bj->x[2]; + } + } + } + /* Find the most massive of the two BHs */ float M = bi->subgrid_mass; float h = hi; @@ -218,10 +282,11 @@ runner_iact_nonsym_bh_bh_swallow(const float r2, const float *dx, } /* Note the factor 9 is taken from EAGLE. Will be turned into a parameter */ - const float max_distance2 = kernel_gravity_softening_plummer_equivalent_inv * - kernel_gravity_softening_plummer_equivalent_inv * - grav_props->epsilon_baryon_cur * - grav_props->epsilon_baryon_cur * 9.f; + const float max_dist_merge2 = + kernel_gravity_softening_plummer_equivalent_inv * + kernel_gravity_softening_plummer_equivalent_inv * 9.f * + grav_props->epsilon_baryon_cur * + grav_props->epsilon_baryon_cur; const float G_Newton = grav_props->G_Newton; @@ -235,7 +300,7 @@ runner_iact_nonsym_bh_bh_swallow(const float r2, const float *dx, /* Merge if gravitationally bound AND if within max distance * Note that we use the kernel support here as the size and not just the * smoothing length */ - if (v2_pec < G_Newton * M / (kernel_gamma * h) && (r2 < max_distance2)) { + if (v2_pec < G_Newton * M / (kernel_gamma * h) && (r2 < max_dist_merge2)) { /* This particle is swallowed by the BH with the largest ID of all the * candidates wanting to swallow it */ @@ -270,16 +335,15 @@ runner_iact_nonsym_bh_bh_swallow(const float r2, const float *dx, * @param pj Second particle (gas) * @param xpj The extended data of the second particle. * @param cosmo The cosmological model. + * @param grav_props The properties of the gravity scheme (softening, G, ...). * @param ti_current Current integer time value (for random numbers). */ __attribute__((always_inline)) INLINE static void -runner_iact_nonsym_bh_gas_feedback(const float r2, const float *dx, - const float hi, const float hj, - const struct bpart *restrict bi, - struct part *restrict pj, - struct xpart *restrict xpj, - const struct cosmology *cosmo, - const integertime_t ti_current) { +runner_iact_nonsym_bh_gas_feedback( + const float r2, const float *dx, const float hi, const float hj, + const struct bpart *restrict bi, struct part *restrict pj, + struct xpart *restrict xpj, const struct cosmology *cosmo, + const struct gravity_props *grav_props, const integertime_t ti_current) { /* Get the heating probability */ const float prob = bi->to_distribute.AGN_heating_probability; diff --git a/src/black_holes/EAGLE/black_holes_io.h b/src/black_holes/EAGLE/black_holes_io.h index ea8b6f70d2847e65128cb23051ee059a1460b52d..cd6c4599f93b3a324ed2be16e6e3fb4ee06ec02c 100644 --- a/src/black_holes/EAGLE/black_holes_io.h +++ b/src/black_holes/EAGLE/black_holes_io.h @@ -104,6 +104,7 @@ INLINE static void convert_bpart_vel(const struct engine* e, * @param bparts The b-particle array. * @param list The list of i/o properties to write. * @param num_fields The number of i/o fields to write. + * @param with_cosmology Are we running a cosmological simulation? */ INLINE static void black_holes_write_particles(const struct bpart* bparts, struct io_props* list, diff --git a/src/black_holes/EAGLE/black_holes_part.h b/src/black_holes/EAGLE/black_holes_part.h index 39ed9d12849c4bd8a4bff62b1ef4853d858ebaac..4d8a9c8e177cc64d7e3191c046ff95c374b2d4a4 100644 --- a/src/black_holes/EAGLE/black_holes_part.h +++ b/src/black_holes/EAGLE/black_holes_part.h @@ -122,6 +122,16 @@ struct bpart { } to_distribute; + struct { + + /*! Value of the minimum potential across all neighbours. */ + float min_potential; + + /*! New position of the BH following the reposition procedure */ + double x[3]; + + } reposition; + /*! Chemistry information (e.g. metal content at birth, swallowed metal * content, etc.) */ struct chemistry_bpart_data chemistry_data; diff --git a/src/black_holes/EAGLE/black_holes_properties.h b/src/black_holes/EAGLE/black_holes_properties.h index 50981b43e1ec23927d9958c95ec396fe4a4e4d3a..db50e5b3e08b1a66497aaf75da9d3acdea3287ee 100644 --- a/src/black_holes/EAGLE/black_holes_properties.h +++ b/src/black_holes/EAGLE/black_holes_properties.h @@ -74,6 +74,11 @@ struct black_holes_props { /*! Number of gas neighbours to heat in a feedback event */ float num_ngbs_to_heat; + /* ---- Properties of the repositioning model --- */ + + /*! Maximal mass of BH to reposition */ + float max_reposition_mass; + /* ---- Common conversion factors --------------- */ /*! Conversion factor from temperature to internal energy */ @@ -157,6 +162,14 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, bp->num_ngbs_to_heat = parser_get_param_float(params, "EAGLEAGN:AGN_num_ngb_to_heat"); + /* Reposition parameters --------------------------------- */ + + bp->max_reposition_mass = + parser_get_param_float(params, "EAGLEAGN:max_reposition_mass"); + + /* Convert to internal units */ + bp->max_reposition_mass *= phys_const->const_solar_mass; + /* Common conversion factors ----------------------------- */ /* Calculate temperature to internal energy conversion factor (all internal diff --git a/src/cell.c b/src/cell.c index 0b949f3a27edf6e35e4c7679a9daf06f3829397b..3aa95a72c5e3c1af29b3f1180ea9f37d8e219020 100644 --- a/src/cell.c +++ b/src/cell.c @@ -4419,7 +4419,7 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) { if (part_is_active(p, e)) { hydro_init_part(p, &e->s->hs); chemistry_init_part(p, e->chemistry); - star_formation_init_part(p, e->star_formation); + star_formation_init_part(p, xp, e->star_formation); tracers_after_init(p, xp, e->internal_units, e->physical_constants, with_cosmology, e->cosmology, e->hydro_properties, e->cooling_func, e->time); diff --git a/src/collectgroup.c b/src/collectgroup.c index d17608d67a291ae412728b3fcd9ea80c192802bf..8dd9e974f41c979f4c50e84fb555f9b80db19e25 100644 --- a/src/collectgroup.c +++ b/src/collectgroup.c @@ -122,7 +122,8 @@ void collectgroup1_apply(const struct collectgroup1 *grp1, struct engine *e) { e->total_nr_cells = grp1->total_nr_cells; e->total_nr_tasks = grp1->total_nr_tasks; e->tasks_per_cell_max = grp1->tasks_per_cell_max; - e->sfh = grp1->sfh; + + star_formation_logger_add_to_accumulator(&e->sfh, &grp1->sfh); } /** diff --git a/src/cooling/EAGLE/cooling.c b/src/cooling/EAGLE/cooling.c index 3fda0c80040b6ad139b9100064b937e695e6030f..674631ae52329611eeddb490df1ed205333c0322 100644 --- a/src/cooling/EAGLE/cooling.c +++ b/src/cooling/EAGLE/cooling.c @@ -207,7 +207,7 @@ INLINE static double bisection_iter( 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], + const float abundance_ratio[eagle_cooling_N_abundances], const double dt_cgs, const long long ID) { /* Bracketing */ @@ -419,7 +419,7 @@ void cooling_cool_part(const struct phys_const *phys_const, * Note that we need to add S and Ca that are in the tables but not tracked * by the particles themselves. * The order is [H, He, C, N, O, Ne, Mg, Si, S, Ca, Fe] */ - float abundance_ratio[chemistry_element_count + 2]; + float abundance_ratio[eagle_cooling_N_abundances]; abundance_ratio_to_solar(p, cooling, abundance_ratio); /* Get the Hydrogen and Helium mass fractions */ diff --git a/src/cooling/EAGLE/cooling_rates.h b/src/cooling/EAGLE/cooling_rates.h index 6707a9a9d70b58eb218cfc8ebeca9b1f08fdcb12..bf908c3a7cfc6008995b0d60ab911ceedc2f60dc 100644 --- a/src/cooling/EAGLE/cooling_rates.h +++ b/src/cooling/EAGLE/cooling_rates.h @@ -43,16 +43,13 @@ * We also re-order the elements such that they match the order of the * tables. This is [H, He, C, N, O, Ne, Mg, Si, S, Ca, Fe]. * - * The solar abundances table (from the cooling struct) is arranged as - * [H, He, C, N, O, Ne, Mg, Si, S, Ca, Fe]. - * * @param p Pointer to #part struct. * @param cooling #cooling_function_data struct. * @param ratio_solar (return) Array of ratios to solar abundances. */ __attribute__((always_inline)) INLINE void abundance_ratio_to_solar( const struct part *p, const struct cooling_function_data *cooling, - float ratio_solar[chemistry_element_count + 2]) { + float ratio_solar[eagle_cooling_N_abundances]) { ratio_solar[0] = p->chemistry_data.smoothed_metal_mass_fraction[chemistry_element_H] * @@ -313,7 +310,7 @@ __attribute__((always_inline)) INLINE double eagle_Compton_cooling_rate( */ INLINE static double eagle_metal_cooling_rate( 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 solar_ratio[eagle_cooling_N_abundances], 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) { @@ -537,7 +534,7 @@ INLINE static double eagle_metal_cooling_rate( */ INLINE static double eagle_cooling_rate( const double log10_u_cgs, const double redshift, const double n_H_cgs, - const float abundance_ratio[chemistry_element_count + 2], + const float abundance_ratio[eagle_cooling_N_abundances], const int n_H_index, const float d_n_H, const int He_index, const float d_He, const struct cooling_function_data *cooling) { diff --git a/src/cooling/EAGLE/cooling_tables.c b/src/cooling/EAGLE/cooling_tables.c index cddc8d50e0c2f00c30846ebaf65b2bf250e9cc8a..4261e9ac0a6fee9f77c03afe22b7a9b66ade487d 100644 --- a/src/cooling/EAGLE/cooling_tables.c +++ b/src/cooling/EAGLE/cooling_tables.c @@ -213,10 +213,6 @@ void read_cooling_header(const char *fname, if (N_SolarAbundances != eagle_cooling_N_abundances) error("Invalid solar abundances array length."); - /* Check value */ - if (N_SolarAbundances != chemistry_element_count + 2) - error("Number of abundances not compatible with the chemistry model."); - dataset = H5Dopen(tempfile_id, "/Header/Number_of_metals", H5P_DEFAULT); status = H5Dread(dataset, H5T_NATIVE_INT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &N_Elements); diff --git a/src/cooling/EAGLE/newton_cooling.c b/src/cooling/EAGLE/newton_cooling.c index c68a77614425f85da011ab45d2ec488710e068dc..e86ebb7a2f38c29b2d889fb96c4a7d5f791b699c 100644 --- a/src/cooling/EAGLE/newton_cooling.c +++ b/src/cooling/EAGLE/newton_cooling.c @@ -214,7 +214,7 @@ __attribute__((always_inline)) INLINE double eagle_convert_u_to_temp( */ 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, + const float solar_ratio[eagle_cooling_N_abundances], 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) { @@ -569,7 +569,7 @@ INLINE static double eagle_metal_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, + const float abundance_ratio[eagle_cooling_N_abundances], int n_H_index, float d_n_H, int He_index, float d_He, const struct cooling_function_data *restrict cooling, double *dLambdaNet_du) { @@ -609,7 +609,7 @@ INLINE static double eagle_metal_cooling_rate( 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], + const float abundance_ratio[eagle_cooling_N_abundances], float dt, int *bisection_flag) { double logu, logu_old; diff --git a/src/cooling/grackle/cooling.h b/src/cooling/grackle/cooling.h index 1abbe5d3827726bde34502cd2b6a1d18cd309950..98d34dc630aa0c83198ddd60b6ee9e2775778d0f 100644 --- a/src/cooling/grackle/cooling.h +++ b/src/cooling/grackle/cooling.h @@ -52,7 +52,7 @@ static gr_float cooling_time( const struct unit_system* restrict us, const struct cosmology* restrict cosmo, const struct cooling_function_data* restrict cooling, - const struct part* restrict p, const struct xpart* restrict xp); + const struct part* restrict p, struct xpart* restrict xp); static gr_float cooling_new_energy( const struct phys_const* restrict phys_const, const struct unit_system* restrict us, @@ -573,7 +573,7 @@ __attribute__((always_inline)) INLINE static gr_float cooling_time( const struct unit_system* restrict us, const struct cosmology* restrict cosmo, const struct cooling_function_data* restrict cooling, - const struct part* restrict p, const struct xpart* restrict xp) { + const struct part* restrict p, struct xpart* restrict xp) { /* set current time */ code_units units = cooling->units; @@ -697,6 +697,17 @@ __attribute__((always_inline)) INLINE static void cooling_cool_part( xp->cooling_data.radiated_energy -= hydro_get_mass(p) * cooling_du_dt * dt; } +/** + * @brief Compute the temperature of a #part based on the cooling function. + * + * @param phys_const #phys_const data structure. + * @param hydro_props The properties of the hydro scheme. + * @param us The internal system of units. + * @param cosmo #cosmology data structure. + * @param cooling #cooling_function_data struct. + * @param p #part data. + * @param xp Pointer to the #xpart data. + */ static INLINE float cooling_get_temperature( const struct phys_const* restrict phys_const, const struct hydro_props* restrict hydro_props, @@ -704,9 +715,30 @@ static INLINE float cooling_get_temperature( const struct cosmology* restrict cosmo, const struct cooling_function_data* restrict cooling, const struct part* restrict p, const struct xpart* restrict xp) { + // TODO use the grackle library - error("This function needs implementing!!"); - return 0.; + /* Physical constants */ + const double m_H = phys_const->const_proton_mass; + const double k_B = phys_const->const_boltzmann_k; + + /* Gas properties */ + const double T_transition = hydro_props->hydrogen_ionization_temperature; + const double mu_neutral = hydro_props->mu_neutral; + const double mu_ionised = hydro_props->mu_ionised; + + /* Particle temperature */ + const double u = hydro_get_physical_internal_energy(p, xp, cosmo); + + /* Temperature over mean molecular weight */ + const double T_over_mu = hydro_gamma_minus_one * u * m_H / k_B; + + /* Are we above or below the HII -> HI transition? */ + if (T_over_mu > (T_transition + 1.) / mu_ionised) + return T_over_mu * mu_ionised; + else if (T_over_mu < (T_transition - 1.) / mu_neutral) + return T_over_mu * mu_neutral; + else + return T_transition; } /** diff --git a/src/engine.c b/src/engine.c index e9c250939c20908392086cb811351343aab1c26c..75ff70b693c121770e7b1331ec3e7e1b87aecbbe 100644 --- a/src/engine.c +++ b/src/engine.c @@ -5069,6 +5069,11 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params, parser_get_opt_param_double(params, "FOF:delta_time", -1.); } + /* Initialize the star formation history structure */ + if (e->policy & engine_policy_star_formation) { + star_formation_logger_accumulator_init(&e->sfh); + } + engine_init_output_lists(e, params); } diff --git a/src/engine.h b/src/engine.h index 8296933561b5f7664904d439ec6ca20f1e37a4b8..967a430871648ac4cb91f390f8b85675a314d3a8 100644 --- a/src/engine.h +++ b/src/engine.h @@ -237,7 +237,7 @@ struct engine { long long b_updates_since_rebuild; /* Star formation logger information */ - struct star_formation_history sfh; + struct star_formation_history_accumulator sfh; /* Properties of the previous step */ int step_props; diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index afc9c17d5b6ed691685bf42df2562ecb6f4409d8..93c0e58068341ab29a7ed0fb6b0d21f76980d952 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -41,6 +41,7 @@ #include "hydro_space.h" #include "kernel_hydro.h" #include "minmax.h" +#include "pressure_floor.h" #include "./hydro_parameters.h" @@ -109,7 +110,8 @@ hydro_get_drifted_physical_internal_energy(const struct part *restrict p, __attribute__((always_inline)) INLINE static float hydro_get_comoving_pressure( const struct part *restrict p) { - return gas_pressure_from_entropy(p->rho, p->entropy); + const float comoving_pressure = gas_pressure_from_entropy(p->rho, p->entropy); + return pressure_floor_get_pressure(p, p->rho, comoving_pressure); } /** @@ -121,7 +123,10 @@ __attribute__((always_inline)) INLINE static float hydro_get_comoving_pressure( __attribute__((always_inline)) INLINE static float hydro_get_physical_pressure( const struct part *restrict p, const struct cosmology *cosmo) { - return gas_pressure_from_entropy(p->rho * cosmo->a3_inv, p->entropy); + const float phys_pressure = + gas_pressure_from_entropy(p->rho * cosmo->a3_inv, p->entropy); + const float phys_rho = hydro_get_physical_density(p, cosmo); + return pressure_floor_get_pressure(p, phys_rho, phys_pressure); } /** @@ -388,13 +393,15 @@ hydro_set_drifted_physical_internal_energy(struct part *p, const float rho_inv = 1.f / p->rho; /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); + float comoving_pressure = gas_pressure_from_entropy(p->rho, p->entropy); + comoving_pressure = pressure_floor_get_pressure(p, p->rho, comoving_pressure); /* Compute the sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); + const float soundspeed = + gas_soundspeed_from_pressure(p->rho, comoving_pressure); /* Divide the pressure by the density squared to get the SPH term */ - const float P_over_rho2 = pressure * rho_inv * rho_inv; + const float P_over_rho2 = comoving_pressure * rho_inv * rho_inv; /* Update variables. */ p->force.P_over_rho2 = P_over_rho2; @@ -591,13 +598,15 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( const float abs_div_physical_v = fabsf(div_physical_v); /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); + float comoving_pressure = gas_pressure_from_entropy(p->rho, p->entropy); + comoving_pressure = pressure_floor_get_pressure(p, p->rho, comoving_pressure); /* Compute the sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); + const float soundspeed = + gas_soundspeed_from_pressure(p->rho, comoving_pressure); /* Divide the pressure by the density squared to get the SPH term */ - const float P_over_rho2 = pressure * rho_inv * rho_inv; + const float P_over_rho2 = comoving_pressure * rho_inv * rho_inv; /* Compute the Balsara switch */ /* Pre-multiply in the AV factor; hydro_props are not passed to the iact @@ -665,14 +674,16 @@ __attribute__((always_inline)) INLINE static void hydro_reset_predicted_values( p->entropy = xp->entropy_full; /* Re-compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); + float comoving_pressure = gas_pressure_from_entropy(p->rho, p->entropy); + comoving_pressure = pressure_floor_get_pressure(p, p->rho, comoving_pressure); /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); + const float soundspeed = + gas_soundspeed_from_pressure(p->rho, comoving_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; + const float P_over_rho2 = comoving_pressure * rho_inv * rho_inv; /* Update variables */ p->force.soundspeed = soundspeed; @@ -730,14 +741,16 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( p->rho *= expf(w2); /* Re-compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); + float comoving_pressure = gas_pressure_from_entropy(p->rho, p->entropy); + comoving_pressure = pressure_floor_get_pressure(p, p->rho, comoving_pressure); /* Compute the new sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); + const float soundspeed = + gas_soundspeed_from_pressure(p->rho, comoving_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; + const float P_over_rho2 = comoving_pressure * rho_inv * rho_inv; /* Update variables */ p->force.soundspeed = soundspeed; @@ -840,14 +853,16 @@ __attribute__((always_inline)) INLINE static void hydro_convert_quantities( } /* Compute the pressure */ - const float pressure = gas_pressure_from_entropy(p->rho, p->entropy); + float comoving_pressure = gas_pressure_from_entropy(p->rho, p->entropy); + comoving_pressure = pressure_floor_get_pressure(p, p->rho, comoving_pressure); /* Compute the sound speed */ - const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); + const float soundspeed = + gas_soundspeed_from_pressure(p->rho, comoving_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; + const float P_over_rho2 = comoving_pressure * rho_inv * rho_inv; p->force.soundspeed = soundspeed; p->force.P_over_rho2 = P_over_rho2; diff --git a/src/hydro/Gadget2/hydro_part.h b/src/hydro/Gadget2/hydro_part.h index 7a8844d560561dae80c676a0b5bb72b34416d080..853d2adf17bc069434562fa96ddb881f760f6830 100644 --- a/src/hydro/Gadget2/hydro_part.h +++ b/src/hydro/Gadget2/hydro_part.h @@ -155,6 +155,9 @@ struct part { /*! Black holes information (e.g. swallowing ID) */ struct black_holes_part_data black_holes_data; + /* Additional data used by the star formation */ + struct star_formation_part_data sf_data; + /* Time-step length */ timebin_t time_bin; diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index e3a4f98160150717e50651760d8af68af2a70662..15f9a958a6c5d4fc199a1c1d7d85d3f909520d23 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -46,6 +46,7 @@ #include "hydro_space.h" #include "kernel_hydro.h" #include "minmax.h" +#include "pressure_floor.h" #include "./hydro_parameters.h" @@ -221,7 +222,9 @@ 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); + const float comoving_pressure = + pressure_floor_get_pressure(p, p->rho, p->pressure_bar); + const float square_rooted = sqrtf(hydro_gamma * comoving_pressure / p->rho); return square_rooted; } @@ -236,7 +239,10 @@ __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; + const float phys_rho = hydro_get_physical_density(p, cosmo); + + return pressure_floor_get_pressure( + p, phys_rho, cosmo->a_factor_sound_speed * p->force.soundspeed); } /** @@ -640,10 +646,15 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( hydro_one_over_gamma_minus_one) / (1.f + common_factor * p->density.wcount_dh); + /* Get the pressures */ + const float comoving_pressure_with_floor = + pressure_floor_get_pressure(p, p->rho, p->pressure_bar); + /* Update variables. */ p->force.f = grad_h_term; p->force.soundspeed = soundspeed; p->force.balsara = balsara; + p->force.pressure_bar_with_floor = comoving_pressure_with_floor; } /** @@ -755,6 +766,11 @@ __attribute__((always_inline)) INLINE static void hydro_predict_extra( const float soundspeed = hydro_get_comoving_soundspeed(p); p->force.soundspeed = soundspeed; + + /* update the required variables */ + const float comoving_pressure_with_floor = + pressure_floor_get_pressure(p, p->rho, p->pressure_bar); + p->force.pressure_bar_with_floor = comoving_pressure_with_floor; } /** diff --git a/src/hydro/PressureEnergy/hydro_iact.h b/src/hydro/PressureEnergy/hydro_iact.h index b59fdbbe418d0442fd290b3596fd08531fae88e6..aab8237c7b26c50d9e04610c6c1029f97e5d73ed 100644 --- a/src/hydro/PressureEnergy/hydro_iact.h +++ b/src/hydro/PressureEnergy/hydro_iact.h @@ -259,11 +259,18 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( /* Convolve with the kernel */ const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; + /* Compute the ratio of pressures */ + const float pressure_inverse_i = + pi->force.pressure_bar_with_floor / (pi->pressure_bar * pi->pressure_bar); + const float pressure_inverse_j = + pj->force.pressure_bar_with_floor / (pj->pressure_bar * pj->pressure_bar); + /* SPH acceleration term */ - const float sph_acc_term = - pj->u * pi->u * hydro_gamma_minus_one * hydro_gamma_minus_one * - ((f_ij / pi->pressure_bar) * wi_dr + (f_ji / pj->pressure_bar) * wj_dr) * - r_inv; + const float sph_acc_term = pj->u * pi->u * hydro_gamma_minus_one * + hydro_gamma_minus_one * + ((f_ij * pressure_inverse_i) * wi_dr + + (f_ji * pressure_inverse_j) * wj_dr) * + r_inv; /* Assemble the acceleration */ const float acc = sph_acc_term + visc_acc_term; @@ -278,11 +285,13 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( pj->a_hydro[2] += mi * acc * dx[2]; /* Get the time derivative for u. */ + const float sph_du_term_i = hydro_gamma_minus_one * hydro_gamma_minus_one * - pj->u * pi->u * (f_ij / pi->pressure_bar) * + pj->u * pi->u * (f_ij * pressure_inverse_i) * wi_dr * dvdr * r_inv; + const float sph_du_term_j = hydro_gamma_minus_one * hydro_gamma_minus_one * - pi->u * pj->u * (f_ji / pj->pressure_bar) * + pi->u * pj->u * (f_ji * pressure_inverse_j) * wj_dr * dvdr * r_inv; /* Viscosity term */ @@ -386,11 +395,18 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( /* Convolve with the kernel */ const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; + /* Compute the ratio of pressures */ + const float pressure_inverse_i = + pi->force.pressure_bar_with_floor / (pi->pressure_bar * pi->pressure_bar); + const float pressure_inverse_j = + pj->force.pressure_bar_with_floor / (pj->pressure_bar * pj->pressure_bar); + /* SPH acceleration term */ - const float sph_acc_term = - pj->u * pi->u * hydro_gamma_minus_one * hydro_gamma_minus_one * - ((f_ij / pi->pressure_bar) * wi_dr + (f_ji / pj->pressure_bar) * wj_dr) * - r_inv; + const float sph_acc_term = pj->u * pi->u * hydro_gamma_minus_one * + hydro_gamma_minus_one * + ((f_ij * pressure_inverse_i) * wi_dr + + (f_ji * pressure_inverse_j) * wj_dr) * + r_inv; /* Assemble the acceleration */ const float acc = sph_acc_term + visc_acc_term; @@ -402,7 +418,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( /* Get the time derivative for u. */ const float sph_du_term_i = hydro_gamma_minus_one * hydro_gamma_minus_one * - pj->u * pi->u * (f_ij / pi->pressure_bar) * + pj->u * pi->u * (f_ij * pressure_inverse_i) * wi_dr * dvdr * r_inv; /* Viscosity term */ diff --git a/src/hydro/PressureEnergy/hydro_part.h b/src/hydro/PressureEnergy/hydro_part.h index ded83d70176409332b669517ed203fdf95ecfd5e..c8f02f518cfde536965c0e6d000999a0e07e4aab 100644 --- a/src/hydro/PressureEnergy/hydro_part.h +++ b/src/hydro/PressureEnergy/hydro_part.h @@ -168,6 +168,9 @@ struct part { /*! Balsara switch */ float balsara; + + /*! Pressure term including the pressure floor */ + float pressure_bar_with_floor; } force; }; diff --git a/src/hydro_properties.c b/src/hydro_properties.c index b24aff140b4b9cb53af0c09a136a2aa23bf4938c..d28cc1dff363517e72ebb3607ec5aa8121f828b2 100644 --- a/src/hydro_properties.c +++ b/src/hydro_properties.c @@ -34,6 +34,7 @@ #include "hydro.h" #include "kernel_hydro.h" #include "parser.h" +#include "pressure_floor.h" #include "units.h" #define hydro_props_default_max_iterations 30 @@ -186,6 +187,9 @@ void hydro_props_print(const struct hydro_props *p) { /* Print equation of state first */ eos_print(&eos); + /* Then the pressure floor */ + pressure_floor_print(&pressure_floor_props); + /* Now SPH */ message("Hydrodynamic scheme: %s in %dD.", SPH_IMPLEMENTATION, (int)hydro_dimension); @@ -238,6 +242,7 @@ void hydro_props_print(const struct hydro_props *p) { void hydro_props_print_snapshot(hid_t h_grpsph, const struct hydro_props *p) { eos_print_snapshot(h_grpsph, &eos); + pressure_floor_print_snapshot(h_grpsph); io_write_attribute_i(h_grpsph, "Dimension", (int)hydro_dimension); io_write_attribute_s(h_grpsph, "Scheme", SPH_IMPLEMENTATION); diff --git a/src/pressure_floor.c b/src/pressure_floor.c new file mode 100644 index 0000000000000000000000000000000000000000..2901241f1a2ff42d526a0122008dcf6ab2d8ea6f --- /dev/null +++ b/src/pressure_floor.c @@ -0,0 +1,24 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +/* This object's header. */ +#include "pressure_floor.h" + +/* Pressure floor for the physics model. */ +struct pressure_floor_properties pressure_floor_props; diff --git a/src/pressure_floor.h b/src/pressure_floor.h new file mode 100644 index 0000000000000000000000000000000000000000..4389dfe0891dd6bfbc1e6730cac1c6ddcc920547 --- /dev/null +++ b/src/pressure_floor.h @@ -0,0 +1,54 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2019 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_PRESSURE_FLOOR_H +#define SWIFT_PRESSURE_FLOOR_H + +/** + * @file src/pressure_floor.h + * @brief Branches between the different pressure floor models + */ + +/* Config parameters. */ +#include "../config.h" + +/* Local includes */ +#include "common_io.h" +#include "cosmology.h" +#include "error.h" +#include "inline.h" + +extern struct pressure_floor_properties pressure_floor_props; + +/* Check if pressure floor is implemented in hydro */ +#ifndef PRESSURE_FLOOR_NONE +#if defined(GADGET2_SPH) || defined(HOPKINS_PU_SPH) +/* Implemented */ +#else +#error Pressure floor not implemented with this hydro scheme +#endif + +#endif +/* Import the right pressure floor definition */ +#if defined(PRESSURE_FLOOR_NONE) +#include "./pressure_floor/none/pressure_floor.h" +#elif defined(PRESSURE_FLOOR_GEAR) +#include "./pressure_floor/GEAR/pressure_floor.h" +#endif + +#endif /* SWIFT_PRESSURE_FLOOR_H */ diff --git a/src/pressure_floor/GEAR/pressure_floor.h b/src/pressure_floor/GEAR/pressure_floor.h new file mode 100644 index 0000000000000000000000000000000000000000..dd715c155a095f9ad5f97b1d14cabfc94d9b11b0 --- /dev/null +++ b/src/pressure_floor/GEAR/pressure_floor.h @@ -0,0 +1,124 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2019 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_PRESSURE_FLOOR_GEAR_H +#define SWIFT_PRESSURE_FLOOR_GEAR_H + +#include "adiabatic_index.h" +#include "cosmology.h" +#include "equation_of_state.h" +#include "hydro_properties.h" +#include "parser.h" +#include "part.h" +#include "units.h" + +/** + * @file src/pressure_floor/GEAR/pressure_floor.h + * @brief Pressure floor used in the GEAR model + */ + +/** + * @brief Properties of the pressure floor in the GEAR model. + */ +struct pressure_floor_properties { + + /*! Jeans factor */ + float n_jeans; + + /*! The constants in internal units (4 G N_jeans^(2/3) / PI) */ + float constants; +}; + +/** + * @brief Compute the physical pressure floor of a given #part. + * + * Note that the particle is not updated!! + * + * The inputs can be either in physical or comoving coordinates (the output is + * in the same coordinates). + * + * @param p The #part. + * @param rho The physical or comoving density. + * @param pressure The physical or comoving pressure without any pressure floor. + * + * @return The physical or comoving pressure with the floor. + */ +static INLINE float pressure_floor_get_pressure(const struct part *p, + const float rho, + const float pressure) { + + /* Compute pressure floor */ + float floor = p->h * p->h * rho * pressure_floor_props.constants; + // TODO add sigma (will be done once the SF is merged) + floor *= rho * hydro_one_over_gamma; + + return fmax(pressure, floor); +} + +/** + * @brief Initialise the pressure floor by reading the parameters and converting + * to internal units. + * + * The input temperatures and number densities are converted to pressure and + * density assuming a neutral gas of primoridal abundance. + * + * @param params The YAML parameter file. + * @param us The system of units used internally. + * @param phys_const The physical constants. + * @param hydro_props The propoerties of the hydro scheme. + * @param props The pressure floor properties to fill. + */ +static INLINE void pressure_floor_init(struct pressure_floor_properties *props, + const struct phys_const *phys_const, + const struct unit_system *us, + const struct hydro_props *hydro_props, + struct swift_params *params) { + + /* Read the Jeans factor */ + props->n_jeans = + parser_get_param_float(params, "GEARPressureFloor:Jeans_factor"); + + /* Compute the constants */ + props->constants = + 4.0 * M_1_PI * phys_const->const_newton_G * pow(props->n_jeans, 2. / 3.); +} + +/** + * @brief Print the properties of the pressure floor to stdout. + * + * @param props The pressure floor properties. + */ +static INLINE void pressure_floor_print( + const struct pressure_floor_properties *props) { + + message("Pressure floor is 'GEAR' with:"); + message("Jeans factor: %g", props->n_jeans); +} + +#ifdef HAVE_HDF5 + +/** + * @brief Writes the current model of pressure floor to the file + * @param h_grp The HDF5 group in which to write + */ +INLINE static void pressure_floor_print_snapshot(hid_t h_grp) { + + io_write_attribute_s(h_grp, "Pressure floor", "GEAR"); +} +#endif +#endif /* SWIFT_PRESSURE_FLOOR_GEAR_H */ diff --git a/src/pressure_floor/none/pressure_floor.h b/src/pressure_floor/none/pressure_floor.h new file mode 100644 index 0000000000000000000000000000000000000000..2d0b95a71f9ccce6697e79760aa43b560933e7bd --- /dev/null +++ b/src/pressure_floor/none/pressure_floor.h @@ -0,0 +1,99 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2019 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_PRESSURE_FLOOR_NONE_H +#define SWIFT_PRESSURE_FLOOR_NONE_H + +#include "adiabatic_index.h" +#include "cosmology.h" +#include "equation_of_state.h" +#include "hydro_properties.h" +#include "parser.h" +#include "part.h" +#include "units.h" + +/** + * @file src/pressure_floor/none/pressure_floor.h + * @brief Model without pressure floor + */ + +/** + * @brief Properties of the pressure floor in the NONE model. + */ +struct pressure_floor_properties {}; + +/** + * @brief Compute the physical pressure floor of a given #part. + * + * Note that the particle is not updated!! + * + * The inputs can be either in physical or comoving coordinates (the output is + * in the same coordinates). + * + * @param p The #part. + * @param rho The physical or comoving density. + * @param pressure The physical or comoving pressure without any pressure floor. + * + * @return The physical or comoving pressure with the floor. + */ +static INLINE float pressure_floor_get_pressure(const struct part *p, + const float rho, + const float pressure) { + return pressure; +} + +/** + * @brief Initialise the pressure floor by reading the parameters and converting + * to internal units. + * + * The input temperatures and number densities are converted to pressure and + * density assuming a neutral gas of primoridal abundance. + * + * @param params The YAML parameter file. + * @param us The system of units used internally. + * @param phys_const The physical constants. + * @param hydro_props The propoerties of the hydro scheme. + * @param props The pressure floor properties to fill. + */ +static INLINE void pressure_floor_init(struct pressure_floor_properties *props, + const struct phys_const *phys_const, + const struct unit_system *us, + const struct hydro_props *hydro_props, + struct swift_params *params) {} + +/** + * @brief Print the properties of the pressure floor to stdout. + * + * @param props The pressure floor properties. + */ +static INLINE void pressure_floor_print( + const struct pressure_floor_properties *props) {} + +#ifdef HAVE_HDF5 + +/** + * @brief Writes the current model of pressure floor to the file + * @param h_grp The HDF5 group in which to write + */ +INLINE static void pressure_floor_print_snapshot(hid_t h_grp) { + + io_write_attribute_s(h_grp, "Pressure floor", "none"); +} +#endif + +#endif /* SWIFT_PRESSURE_FLOOR_NONE_H */ diff --git a/src/runner.c b/src/runner.c index 9249924a92dbcffba30baafa76df1a18e9962c16..7d41019ed3dc00364e7c170e3310d93f303e7414 100644 --- a/src/runner.c +++ b/src/runner.c @@ -905,6 +905,10 @@ void runner_do_black_holes_swallow_ghost(struct runner *r, struct cell *c, if (bpart_is_active(bp, e)) { + /* Compute the final operations for repositioning of this BH */ + black_holes_end_reposition(bp, e->black_holes_properties, + e->physical_constants, e->cosmology); + /* Get particle time-step */ double dt; if (with_cosmology) { @@ -2272,7 +2276,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { /* Re-initialise everything */ hydro_init_part(p, hs); chemistry_init_part(p, chemistry); - star_formation_init_part(p, star_formation); + star_formation_init_part(p, xp, star_formation); tracers_after_init(p, xp, e->internal_units, e->physical_constants, with_cosmology, e->cosmology, e->hydro_properties, e->cooling_func, e->time); diff --git a/src/runner_doiact.h b/src/runner_doiact.h index 6caa287cf726f85778ef5abdc184acaf759e8b0e..1a39c8d49f2c4234c04982e255705f06ec1c5d38 100644 --- a/src/runner_doiact.h +++ b/src/runner_doiact.h @@ -884,7 +884,6 @@ void DOSELF_SUBSET(struct runner *r, struct cell *restrict ci, const int count_i = ci->hydro.count; struct part *restrict parts_j = ci->hydro.parts; - /* Loop over the parts in ci. */ for (int pid = 0; pid < count; pid++) { diff --git a/src/runner_doiact_black_holes.h b/src/runner_doiact_black_holes.h index 71ce7aefcfc3689cc8476884729e4e7cd77bef66..ce159c7ac24a508bc625070ed50b3aad7dd9fa8d 100644 --- a/src/runner_doiact_black_holes.h +++ b/src/runner_doiact_black_holes.h @@ -159,7 +159,8 @@ void DOSELF1_BH(struct runner *r, struct cell *c, int timer) { #endif if (r2 < hig2) { - IACT_BH_GAS(r2, dx, hi, hj, bi, pj, xpj, cosmo, ti_current); + IACT_BH_GAS(r2, dx, hi, hj, bi, pj, xpj, cosmo, e->gravity_properties, + ti_current); } } /* loop over the parts in ci. */ } /* loop over the bparts in ci. */ @@ -310,7 +311,8 @@ void DO_NONSYM_PAIR1_BH_NAIVE(struct runner *r, struct cell *restrict ci, #endif if (r2 < hig2) { - IACT_BH_GAS(r2, dx, hi, hj, bi, pj, xpj, cosmo, ti_current); + IACT_BH_GAS(r2, dx, hi, hj, bi, pj, xpj, cosmo, e->gravity_properties, + ti_current); } } /* loop over the parts in cj. */ } /* loop over the bparts in ci. */ @@ -475,7 +477,8 @@ void DOPAIR1_SUBSET_BH_NAIVE(struct runner *r, struct cell *restrict ci, #endif /* Hit or miss? */ if (r2 < hig2) { - IACT_BH_GAS(r2, dx, hi, hj, bi, pj, xpj, cosmo, ti_current); + IACT_BH_GAS(r2, dx, hi, hj, bi, pj, xpj, cosmo, e->gravity_properties, + ti_current); } } /* loop over the parts in cj. */ } /* loop over the parts in ci. */ @@ -550,7 +553,8 @@ void DOSELF1_SUBSET_BH(struct runner *r, struct cell *restrict ci, /* Hit or miss? */ if (r2 < hig2) { - IACT_BH_GAS(r2, dx, hi, pj->h, bi, pj, xpj, cosmo, ti_current); + IACT_BH_GAS(r2, dx, hi, pj->h, bi, pj, xpj, cosmo, + e->gravity_properties, ti_current); } } /* loop over the parts in cj. */ } /* loop over the parts in ci. */ diff --git a/src/space.c b/src/space.c index cea579d09f438ff07611eb4c674decd7a3547de8..2fd83785451b634b97610bea34fb0bce032f9acc 100644 --- a/src/space.c +++ b/src/space.c @@ -4373,7 +4373,7 @@ void space_init_parts_mapper(void *restrict map_data, int count, for (int k = 0; k < count; k++) { hydro_init_part(&parts[k], hs); chemistry_init_part(&parts[k], e->chemistry); - star_formation_init_part(&parts[k], e->star_formation); + star_formation_init_part(&parts[k], &xparts[k], e->star_formation); tracers_after_init(&parts[k], &xparts[k], e->internal_units, e->physical_constants, with_cosmology, e->cosmology, e->hydro_properties, e->cooling_func, e->time); diff --git a/src/space.h b/src/space.h index 94ba0654352c6c33f1115337073bb76d099a0354..0b332716645e733636b7ab0da57a0a31b28e3d31 100644 --- a/src/space.h +++ b/src/space.h @@ -115,9 +115,6 @@ struct space { /*! The minimum top-level cell width allowed. */ double cell_min; - /*! Current maximum displacement for particles. */ - float dx_max; - /*! Space dimensions in number of top-cells. */ int cdim[3]; diff --git a/src/star_formation.c b/src/star_formation.c index 698a64cc636dd79f00feac3f6cc88bf519fe09c1..60cff1e2e68feaf7e71705b5079294ec478fad42 100644 --- a/src/star_formation.c +++ b/src/star_formation.c @@ -24,6 +24,7 @@ #include "part.h" #include "restart.h" #include "star_formation.h" +#include "star_formation_io.h" #include "units.h" /** diff --git a/src/star_formation/EAGLE/star_formation.h b/src/star_formation/EAGLE/star_formation.h index 694cac1512d91ef3d640185cbf9b614773263a75..f2c77e036842b4ca040c58a6bcad1513b03a42bd 100644 --- a/src/star_formation/EAGLE/star_formation.h +++ b/src/star_formation/EAGLE/star_formation.h @@ -691,6 +691,7 @@ star_formation_first_init_part(const struct phys_const* restrict phys_const, * @param data The global star_formation information. */ __attribute__((always_inline)) INLINE static void star_formation_init_part( - struct part* restrict p, const struct star_formation* data) {} + struct part* restrict p, struct xpart* restrict xp, + const struct star_formation* data) {} #endif /* SWIFT_EAGLE_STAR_FORMATION_H */ diff --git a/src/star_formation/EAGLE/star_formation_logger.h b/src/star_formation/EAGLE/star_formation_logger.h index d634c876e52d45588ed0b93c0afc09731317c037..fea15242e9a83b81cf5c7801c0546a1bbb5a8eae 100644 --- a/src/star_formation/EAGLE/star_formation_logger.h +++ b/src/star_formation/EAGLE/star_formation_logger.h @@ -87,6 +87,28 @@ INLINE static void star_formation_logger_add( sf_update->SFR_inactive += sf_add->SFR_inactive; } +/** + * @brief add a star formation history struct to the engine star formation + * history accumulator struct + * + * @param sf_add the star formation accumulator struct which we want to add to + * the star formation history + * @param sf_update the star formation structure which we want to update + */ +INLINE static void star_formation_logger_add_to_accumulator( + struct star_formation_history_accumulator *sf_update, + const struct star_formation_history *sf_add) { + + /* Update the SFH structure */ + sf_update->new_stellar_mass = sf_add->new_stellar_mass; + + sf_update->SFR_active = sf_add->SFR_active; + + sf_update->SFRdt_active = sf_add->SFRdt_active; + + sf_update->SFR_inactive = sf_add->SFR_inactive; +} + /** * @brief Initialize the star formation history structure in the #engine * @@ -105,6 +127,24 @@ INLINE static void star_formation_logger_init( sfh->SFR_inactive = 0.f; } +/** + * @brief Initialize the star formation history structure in the #engine + * + * @param sfh The pointer to the star formation history structure + */ +INLINE static void star_formation_logger_accumulator_init( + struct star_formation_history_accumulator *sfh) { + + /* Initialize the collecting SFH structure to zero */ + sfh->new_stellar_mass = 0.f; + + sfh->SFR_active = 0.f; + + sfh->SFRdt_active = 0.f; + + sfh->SFR_inactive = 0.f; +} + /** * @brief Write the final SFH to a file * @@ -117,7 +157,7 @@ INLINE static void star_formation_logger_init( */ INLINE static void star_formation_logger_write_to_log_file( FILE *fp, const double time, const double a, const double z, - const struct star_formation_history sf, const int step) { + const struct star_formation_history_accumulator sf, const int step) { /* Calculate the total SFR */ const float totalSFR = sf.SFR_active + sf.SFR_inactive; diff --git a/src/star_formation/EAGLE/star_formation_logger_struct.h b/src/star_formation/EAGLE/star_formation_logger_struct.h index 2a23659c4d931735d1b82a6143b3d9f871f7137a..c03a00c97ead46f552350a43574c5bbe7ac6df1b 100644 --- a/src/star_formation/EAGLE/star_formation_logger_struct.h +++ b/src/star_formation/EAGLE/star_formation_logger_struct.h @@ -34,4 +34,21 @@ struct star_formation_history { float SFRdt_active; }; +/* Starformation history struct for the engine. + Allows to integrate in time some values. + Nothing to do in EAGLE => copy of star_formation_history */ +struct star_formation_history_accumulator { + /*! Total new stellar mass */ + float new_stellar_mass; + + /*! SFR of all particles */ + float SFR_inactive; + + /*! SFR of active particles */ + float SFR_active; + + /*! SFR*dt of active particles */ + float SFRdt_active; +}; + #endif /* SWIFT_EAGLE_STAR_FORMATION_LOGGER_STRUCT_H */ diff --git a/src/star_formation/EAGLE/star_formation_struct.h b/src/star_formation/EAGLE/star_formation_struct.h index 41247e160a3eddbc9184c59b67cfa2a1d7259a05..8caac49d4b57652c5db9ae93e3789dc690e6d23f 100644 --- a/src/star_formation/EAGLE/star_formation_struct.h +++ b/src/star_formation/EAGLE/star_formation_struct.h @@ -29,4 +29,6 @@ struct star_formation_xpart_data { float SFR; }; +struct star_formation_part_data {}; + #endif /* SWIFT_EAGLE_STAR_FORMATION_STRUCT_H */ diff --git a/src/star_formation/GEAR/star_formation.h b/src/star_formation/GEAR/star_formation.h index c479feb5c66328f9fab8bf62593ca66b6658b79e..ac423a51865609460e870f65b1eeeb266182e2ef 100644 --- a/src/star_formation/GEAR/star_formation.h +++ b/src/star_formation/GEAR/star_formation.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. - * Copyright (c) 2018 Folkert Nobels (nobels@strw.leidenuniv.nl) + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * 2019 Fabien Jeanquartier (fabien.jeanquartier@epfl.ch) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -20,20 +21,24 @@ #define SWIFT_GEAR_STAR_FORMATION_H /* Local includes */ +#include "cooling.h" #include "cosmology.h" +#include "engine.h" #include "entropy_floor.h" #include "error.h" #include "hydro_properties.h" #include "parser.h" #include "part.h" #include "physical_constants.h" +#include "random.h" +#include "star_formation_struct.h" #include "units.h" /** * @brief Calculate if the gas has the potential of becoming * a star. * - * No star formation should occur, so return 0. + * Use the star formation criterion given by eq. 3 in Revaz & Jablonka 2018. * * @param starform the star formation law properties to use. * @param p the gas particles. @@ -46,7 +51,7 @@ * */ INLINE static int star_formation_is_star_forming( - const struct part* restrict p, const struct xpart* restrict xp, + struct part* restrict p, struct xpart* restrict xp, const struct star_formation* starform, const struct phys_const* phys_const, const struct cosmology* cosmo, const struct hydro_props* restrict hydro_props, @@ -54,14 +59,43 @@ INLINE static int star_formation_is_star_forming( const struct cooling_function_data* restrict cooling, const struct entropy_floor_properties* restrict entropy_floor) { - return 0; + const float temperature = cooling_get_temperature(phys_const, hydro_props, us, + cosmo, cooling, p, xp); + + const float temperature_max = starform->maximal_temperature; + + /* Check the temperature criterion */ + if (temperature > temperature_max) { + return 0; + } + + /* Get the required variables */ + const float sigma2 = p->sf_data.sigma2; + const float n_jeans_2_3 = starform->n_jeans_2_3; + + const float h = p->h; + const float density = hydro_get_physical_density(p, cosmo); + + // TODO use GRACKLE */ + const float mu = hydro_props->mu_neutral; + + /* Compute the density criterion */ + const float coef = + M_PI_4 / (phys_const->const_newton_G * n_jeans_2_3 * h * h); + const float density_criterion = + coef * (hydro_gamma * phys_const->const_boltzmann_k * temperature / + (mu * phys_const->const_proton_mass) + + sigma2); + + /* Check the density criterion */ + return density > density_criterion; } /** - * @brief Compute the star-formation rate of a given particle and store - * it into the #xpart. + * @brief Compute the star-formation rate of a given particle. * - * Nothing to do here. + * Nothing to do here. Everything is done in + * #star_formation_should_convert_to_star. * * @param p #part. * @param xp the #xpart. @@ -71,15 +105,15 @@ INLINE static int star_formation_is_star_forming( * @param dt_star The time-step of this particle. */ INLINE static void star_formation_compute_SFR( - const struct part* restrict p, struct xpart* restrict xp, + struct part* restrict p, struct xpart* restrict xp, const struct star_formation* starform, const struct phys_const* phys_const, const struct cosmology* cosmo, const double dt_star) {} /** * @brief Decides whether a particle should be converted into a * star or not. - * - * No SF should occur, so return 0. + + * Compute the star formation rate from eq. 4 in Revaz & Jablonka 2012. * * @param p The #part. * @param xp The #xpart. @@ -89,18 +123,38 @@ INLINE static void star_formation_compute_SFR( * @return 1 if a conversion should be done, 0 otherwise. */ INLINE static int star_formation_should_convert_to_star( - const struct part* p, const struct xpart* xp, - const struct star_formation* starform, const struct engine* e, - const double dt_star) { + struct part* p, struct xpart* xp, const struct star_formation* starform, + const struct engine* e, const double dt_star) { + + const struct phys_const* phys_const = e->physical_constants; + const struct cosmology* cosmo = e->cosmology; + + /* Check that we are running a full time step */ + if (dt_star == 0.) { + return 0; + } + + /* Get a few variables */ + const float G = phys_const->const_newton_G; + const float density = hydro_get_physical_density(p, cosmo); + + /* Compute the probability */ + const float inv_free_fall_time = + sqrtf(density * 32.f * G * 0.33333333f * M_1_PI); + const float prob = 1.f - exp(-starform->star_formation_efficiency * + inv_free_fall_time * dt_star); + + /* Roll the dice... */ + const float random_number = + random_unit_interval(p->id, e->ti_current, random_number_star_formation); - return 0; + /* Can we form a star? */ + return random_number < prob; } /** * @brief Update the SF properties of a particle that is not star forming. * - * Nothing to do here. - * * @param p The #part. * @param xp The #xpart. * @param e The #engine. @@ -115,8 +169,6 @@ INLINE static void star_formation_update_part_not_SFR( * @brief Copies the properties of the gas particle over to the * star particle. * - * Nothing to do here. - * * @param e The #engine * @param p the gas particles. * @param xp the additional properties of the gas particles. @@ -133,21 +185,33 @@ INLINE static void star_formation_copy_properties( const struct phys_const* phys_const, const struct hydro_props* restrict hydro_props, const struct unit_system* restrict us, - const struct cooling_function_data* restrict cooling) {} + const struct cooling_function_data* restrict cooling) { -/** - * @brief initialization of the star formation law - * - * @param parameter_file The parsed parameter file - * @param phys_const Physical constants in internal units - * @param us The current internal system of units - * @param starform the star formation law properties to initialize - * - */ -INLINE static void starformation_init_backend( - struct swift_params* parameter_file, const struct phys_const* phys_const, - const struct unit_system* us, const struct hydro_props* hydro_props, - const struct star_formation* starform) {} + /* Store the current mass */ + sp->mass = hydro_get_mass(p); + sp->birth.mass = sp->mass; + + /* Store either the birth_scale_factor or birth_time depending */ + if (with_cosmology) { + sp->birth_scale_factor = cosmo->a; + } else { + sp->birth_time = e->time; + } + + // TODO copy only metals + /* Store the chemistry struct in the star particle */ + sp->chemistry_data = p->chemistry_data; + + /* Store the tracers data */ + sp->tracers_data = xp->tracers_data; + + /* Store the birth density in the star particle */ + sp->birth.density = hydro_get_physical_density(p, cosmo); + + /* Store the birth temperature*/ + sp->birth.temperature = cooling_get_temperature(phys_const, hydro_props, us, + cosmo, cooling, p, xp); +} /** * @brief Prints the used parameters of the star formation law @@ -156,7 +220,6 @@ INLINE static void starformation_init_backend( */ INLINE static void starformation_print_backend( const struct star_formation* starform) { - message("Star formation law is 'GEAR'"); } @@ -164,12 +227,22 @@ INLINE static void starformation_print_backend( * @brief Finishes the density calculation. * * @param p The particle to act upon - * @param cd The global star_formation information. + * @param xp The extended particle data to act upon + * @param sf The global star_formation information. * @param cosmo The current cosmological model. */ __attribute__((always_inline)) INLINE static void star_formation_end_density( - struct part* restrict p, const struct star_formation* cd, - const struct cosmology* cosmo) {} + struct part* restrict p, const struct star_formation* sf, + const struct cosmology* cosmo) { + + // TODO move into pressure floor + /* To finish the turbulence estimation we devide by the density */ + p->sf_data.sigma2 /= + pow_dimension(p->h) * hydro_get_physical_density(p, cosmo); + + /* Add the cosmological factor */ + p->sf_data.sigma2 *= cosmo->a * cosmo->a; +} /** * @brief Sets all particle fields to sensible values when the #part has 0 ngbs. @@ -183,39 +256,46 @@ __attribute__((always_inline)) INLINE static void star_formation_part_has_no_neighbours(struct part* restrict p, struct xpart* restrict xp, const struct star_formation* cd, - const struct cosmology* cosmo) {} + const struct cosmology* cosmo) { + + // TODO move into pressure floor + /* If part has 0 neighbours, the estimation of turbulence is 0 */ + p->sf_data.sigma2 = 0.f; +} /** * @brief Sets the star_formation properties of the (x-)particles to a valid * start state. * - * Nothing to do here. - * + * @param p Pointer to the particle data. + * @param xp Pointer to extended particle data + * @param data The global star_formation information. + */ +__attribute__((always_inline)) INLINE static void star_formation_init_part( + struct part* restrict p, struct xpart* restrict xp, + const struct star_formation* data) { + p->sf_data.sigma2 = 0.f; +} + +/** + * @brief Sets the star_formation properties of the (x-)particles to a valid + * start state. * @param phys_const The physical constant in internal units. * @param us The unit system. * @param cosmo The current cosmological model. * @param data The global star_formation information used for this run. * @param p Pointer to the particle data. - * @param xp Pointer to the extended particle data. */ __attribute__((always_inline)) INLINE static void star_formation_first_init_part(const struct phys_const* restrict phys_const, const struct unit_system* restrict us, const struct cosmology* restrict cosmo, const struct star_formation* data, - const struct part* restrict p, - struct xpart* restrict xp) {} + struct part* restrict p, + struct xpart* restrict xp) { -/** - * @brief Sets the star_formation properties of the (x-)particles to a valid - * start state. - * - * Nothing to do here. - * - * @param p Pointer to the particle data. - * @param data The global star_formation information. - */ -__attribute__((always_inline)) INLINE static void star_formation_init_part( - struct part* restrict p, const struct star_formation* data) {} + /* Nothing special here */ + star_formation_init_part(p, xp, data); +} #endif /* SWIFT_GEAR_STAR_FORMATION_H */ diff --git a/src/star_formation/GEAR/star_formation_iact.h b/src/star_formation/GEAR/star_formation_iact.h index 749b608068650a27cbe4c9a0ca4126d2740337f3..7325b92af2840b317cf1a924a1e509b34bdffba3 100644 --- a/src/star_formation/GEAR/star_formation_iact.h +++ b/src/star_formation/GEAR/star_formation_iact.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. - * Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * 2019 Fabien Jeanquartier (fabien.jeanquartier@epfl.ch) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -28,6 +29,8 @@ * @brief do star_formation computation after the runner_iact_density (symmetric * version) * + * Compute the velocity dispersion follow eq. 2 in Revaz & Jablonka 2018. + * * @param r2 Comoving square distance between the two particles. * @param dx Comoving vector separating both particles (pi - pj). * @param hi Comoving smoothing-length of particle i. @@ -39,7 +42,28 @@ */ __attribute__((always_inline)) INLINE static void runner_iact_star_formation( float r2, const float *dx, float hi, float hj, struct part *restrict pi, - struct part *restrict pj, float a, float H) {} + struct part *restrict pj, float a, float H) { + + float wi; + float wj; + /* Evaluation of the SPH kernel */ + kernel_eval(sqrt(r2) / hi, &wi); + kernel_eval(sqrt(r2) / hj, &wj); + + /* Delta v */ + float dv[3] = {pi->v[0] - pj->v[0], pi->v[1] - pj->v[1], pi->v[2] - pj->v[2]}; + + /* Norms at power 2 */ + const float norm_v2 = dv[0] * dv[0] + dv[1] * dv[1] + dv[2] * dv[2]; + const float norm_x2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + + /* Compute the velocity dispersion */ + const float sigma2 = norm_v2 + H * norm_x2; + + /* Compute the velocity dispersion */ + pi->sf_data.sigma2 += sigma2 * wi * hydro_get_mass(pj); + pj->sf_data.sigma2 += sigma2 * wj * hydro_get_mass(pi); +} /** * @brief do star_formation computation after the runner_iact_density (non @@ -58,6 +82,23 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_star_formation(float r2, const float *dx, float hi, float hj, struct part *restrict pi, const struct part *restrict pj, float a, - float H) {} + float H) { + float wi; + /* Evaluation of the SPH kernel */ + kernel_eval(sqrt(r2) / hi, &wi); + + /* Delta v */ + float dv[3] = {pi->v[0] - pj->v[0], pi->v[1] - pj->v[1], pi->v[2] - pj->v[2]}; + + /* Norms at power 2 */ + const float norm_v2 = dv[0] * dv[0] + dv[1] * dv[1] + dv[2] * dv[2]; + const float norm_x2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + + /* Compute the velocity dispersion */ + const float sigma2 = norm_v2 + H * norm_x2; + + /* Compute the velocity dispersion */ + pi->sf_data.sigma2 += sigma2 * wi * hydro_get_mass(pj); +} #endif /* SWIFT_GEAR_STAR_FORMATION_IACT_H */ diff --git a/src/star_formation/GEAR/star_formation_io.h b/src/star_formation/GEAR/star_formation_io.h index 6ef04c49c4abcd00175aaa164271628a9ff89360..3e021f7844c1deaeca40d7144d6f7b69cb6c2bdb 100644 --- a/src/star_formation/GEAR/star_formation_io.h +++ b/src/star_formation/GEAR/star_formation_io.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. - * Copyright (c) 2018 Folkert Nobels (nobels@strw.leidenuniv.nl) + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * 2019 Fabien Jeanquartier (fabien.jeanquartier@epfl.ch) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -37,8 +38,40 @@ __attribute__((always_inline)) INLINE static int star_formation_write_particles( const struct part* parts, const struct xpart* xparts, struct io_props* list) { - + /* Nothing to write here */ return 0; } +/** + * @brief initialization of the star formation law + * + * @param parameter_file The parsed parameter file + * @param phys_const Physical constants in internal units + * @param us The current internal system of units + * @param starform the star formation law properties to initialize + * + */ +INLINE static void starformation_init_backend( + struct swift_params* parameter_file, const struct phys_const* phys_const, + const struct unit_system* us, const struct hydro_props* hydro_props, + struct star_formation* starform) { + + // TODO move into pressure floor + starform->n_jeans_2_3 = + parser_get_param_float(parameter_file, "GEARStarFormation:NJeans"); + starform->n_jeans_2_3 = pow(starform->n_jeans_2_3, 2. / 3.); + + /* Star formation efficiency */ + starform->star_formation_efficiency = parser_get_param_double( + parameter_file, "GEARStarFormation:star_formation_efficiency"); + + /* Maximum temperature for star formation */ + starform->maximal_temperature = parser_get_param_double( + parameter_file, "GEARStarFormation:maximal_temperature"); + + /* Apply unit change */ + starform->maximal_temperature *= + units_cgs_conversion_factor(us, UNIT_CONV_TEMPERATURE); +} + #endif /* SWIFT_STAR_FORMATION_GEAR_IO_H */ diff --git a/src/star_formation/GEAR/star_formation_logger.h b/src/star_formation/GEAR/star_formation_logger.h index 5b9e033d21d3d202f3c289d1dd6a843ba17fa524..84475909c0f524a4f930a48dbcc3b0943719f8b0 100644 --- a/src/star_formation/GEAR/star_formation_logger.h +++ b/src/star_formation/GEAR/star_formation_logger.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. - * Copyright (c) 2019 Folkert Nobels (nobels@strw.leidenuniv.nl) + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * 2019 Fabien Jeanquartier (fabien.jeanquartier@epfl.ch) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -27,16 +28,28 @@ #include "hydro.h" #include "part.h" #include "star_formation_logger_struct.h" +#include "units.h" /** - * @brief Update the stellar mass in the current cell after creating - * the new star particle spart sp + * @brief Update the stellar quantities in the current cell after creating + * the new star particle spart sp. * + * @param time_step, the current time step of the simulation * @param sp new created star particle * @param sf the star_formation_history struct of the current cell */ INLINE static void star_formation_logger_log_new_spart( - struct spart *sp, struct star_formation_history *sf) {} + const struct spart *sp, struct star_formation_history *sf) { + + /* Add mass of created sparticle to the total stellar mass in this cell */ + sf->new_stellar_mass += sp->mass; + + /* Increase the number of stars */ + sf->number_new_stars += 1; + + /* No need to deal with the integrated quantities, only the engine's one is + * updated */ +} /** * @brief Initialize the star formation history struct in the case the cell is @@ -45,41 +58,42 @@ INLINE static void star_formation_logger_log_new_spart( * @param sf the star_formation_history struct we want to initialize */ INLINE static void star_formation_logger_log_inactive_cell( - struct star_formation_history *sf) {} + struct star_formation_history *sf) { -/** - * @brief add a star formation history struct to an other star formation history - * struct - * - * @param sf_add the star formation struct which we want to add to the star - * formation history - * @param sf_update the star formation structure which we want to update - */ -INLINE static void star_formation_logger_add( - struct star_formation_history *sf_update, - const struct star_formation_history *sf_add) {} + /* Initialize the stellar mass to zero */ + sf->new_stellar_mass = 0.f; + /* initialize number of stars to zero*/ + sf->number_new_stars = 0; +} /** * @brief Initialize the star formation history structure in the #engine * * @param sfh The pointer to the star formation history structure */ INLINE static void star_formation_logger_init( - struct star_formation_history *sfh) {} + struct star_formation_history *sfh) { + /* Initialize the collecting SFH structure to zero */ + sfh->new_stellar_mass = 0.f; + sfh->number_new_stars = 0; +} /** - * @brief Write the final SFH to a file + * @brief add a star formation history struct to an other star formation history + * struct * - * @param fp The file to write to. - * @param time the simulation time (time since Big Bang) in internal units. - * @param a the scale factor. - * @param z the redshift. - * @param sf the #star_formation_history struct. - * @param step The time-step of the simulation. + * @param sf_add the star formation struct which we want to add to the star + * formation history + * @param sf_update the star formation structure which we want to update */ -INLINE static void star_formation_logger_write_to_log_file( - FILE *fp, const double time, const double a, const double z, - const struct star_formation_history sf, const int step) {} +INLINE static void star_formation_logger_add( + struct star_formation_history *sf_update, + const struct star_formation_history *sf_add) { + + /* Update the SFH structure */ + sf_update->number_new_stars += sf_add->number_new_stars; + sf_update->new_stellar_mass += sf_add->new_stellar_mass; +} /** * @brief Initialize the SFH logger file @@ -90,13 +104,47 @@ INLINE static void star_formation_logger_write_to_log_file( */ INLINE static void star_formation_logger_init_log_file( FILE *fp, const struct unit_system *restrict us, - const struct phys_const *phys_const) {} + const struct phys_const *phys_const) { + + /* Write some general text to the logger file */ + fprintf(fp, "# Star Formation History Logger file\n"); + fprintf(fp, "######################################################\n"); + fprintf(fp, "# The quantities are all given in internal physical units!\n"); + fprintf(fp, "#\n"); + fprintf(fp, "# (0) Simulation step\n"); + fprintf(fp, + "# (1) Time since Big Bang (cosmological run), Time since start of " + "the simulation (non-cosmological run).\n"); + fprintf(fp, "# Unit = %e seconds\n", us->UnitTime_in_cgs); + fprintf(fp, "# Unit = %e yr or %e Myr\n", 1.f / phys_const->const_year, + 1.f / phys_const->const_year / 1e6); + fprintf(fp, "# (2) Scale factor (no unit)\n"); + fprintf(fp, "# (3) Redshift (no unit)\n"); + fprintf(fp, + "# (4) Total number of stars formed in the simulation (no unit)\n"); + fprintf(fp, "# (5) Total stellar mass formed in the simulation.\n"); + fprintf(fp, "# Unit = %e gram\n", us->UnitMass_in_cgs); + fprintf(fp, "# Unit = %e solar mass\n", + 1.f / phys_const->const_solar_mass); + fprintf(fp, + "# (6) Number of stars formed in the current time step (no unit).\n"); + fprintf(fp, "# (7) Mass of stars formed in the current time step.\n"); + fprintf(fp, "# Unit = %e gram\n", us->UnitMass_in_cgs); + fprintf(fp, "# Unit = %e solar mass\n", + 1.f / phys_const->const_solar_mass); + fprintf(fp, + "# (0) (1) (2) (3) (4) " + " (5) (6) (7)\n"); +} /** * @brief Add the SFR tracer to the total active SFR of this cell * + * Nothing to do here + * * @param p the #part * @param xp the #xpart + * * @param sf the SFH logger struct * @param dt_star The length of the time-step in physical internal units. */ @@ -108,6 +156,8 @@ INLINE static void star_formation_logger_log_active_part( * @brief Add the SFR tracer to the total inactive SFR of this cell as long as * the SFR tracer is larger than 0 * + * Nothing to do here + * * @param p the #part * @param xp the #xpart * @param sf the SFH logger struct @@ -116,4 +166,57 @@ INLINE static void star_formation_logger_log_inactive_part( const struct part *p, const struct xpart *xp, struct star_formation_history *sf) {} +/** + * @brief add a star formation history struct to an other star formation history + * struct + * + * @param sf_add the star formation struct which we want to add to the star + * formation history + * @param sf_update the star formation structure which we want to update + */ +INLINE static void star_formation_logger_add_to_accumulator( + struct star_formation_history_accumulator *sf_update, + const struct star_formation_history *sf_add) { + + /* Update the SFH structure */ + sf_update->number_new_stars = sf_add->number_new_stars; + sf_update->new_stellar_mass = sf_add->new_stellar_mass; + sf_update->total_number_stars += sf_add->number_new_stars; + sf_update->total_stellar_mass += sf_add->new_stellar_mass; +} + +/** + * @brief Write the final SFH to a file + * + * @param fp The file to write to. + * @param time the simulation time (time since Big Bang) in internal units. + * @param a the scale factor. + * @param z the redshift. + * @param sf the #star_formation_history struct. + * @param step The time-step of the simulation. + */ +INLINE static void star_formation_logger_write_to_log_file( + FILE *fp, const double time, const double a, const double z, + struct star_formation_history_accumulator sf, const int step) { + + fprintf(fp, "%6d %16e %12.7f %14e %14ld %14e %14ld %14e\n", step, time, a, z, + sf.total_number_stars, sf.total_stellar_mass, sf.number_new_stars, + sf.new_stellar_mass); +} + +/** + * @brief Initialize the star formation history struct in the #engine when + * starting the simulation. + * + * @param sfh the star_formation_history struct we want to initialize + */ +INLINE static void star_formation_logger_accumulator_init( + struct star_formation_history_accumulator *sfh) { + /* Initialize all values to zero */ + sfh->new_stellar_mass = 0.f; + sfh->number_new_stars = 0; + sfh->total_number_stars = 0; + sfh->total_stellar_mass = 0.f; +} + #endif /* SWIFT_GEAR_STARFORMATION_LOGGER_H */ diff --git a/src/star_formation/GEAR/star_formation_logger_struct.h b/src/star_formation/GEAR/star_formation_logger_struct.h index 04b5dfdc038f7b684cfb1f2079d13eb312624b3f..63e3af06a7cd5af375662a1ba28dc5000a69dc3f 100644 --- a/src/star_formation/GEAR/star_formation_logger_struct.h +++ b/src/star_formation/GEAR/star_formation_logger_struct.h @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. - * Copyright (c) 2019 Folkert Nobels (nobels@strw.leidenuniv.nl) + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * 2019 Fabien Jeanquartier (fabien.jeanquartier@epfl.ch) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -19,7 +20,33 @@ #ifndef SWIFT_GEAR_STAR_FORMATION_LOGGER_STRUCT_H #define SWIFT_GEAR_STAR_FORMATION_LOGGER_STRUCT_H -/* Starformation history struct */ -struct star_formation_history {}; +/** + * Structure containing the star formation information from the cells. + */ +struct star_formation_history { + /*! Stellar mass created in the current timestep */ + float new_stellar_mass; -#endif /* SWIFT_NONE_STAR_FORMATION_STRUCT_H */ + /*! Number of stars created in this timestep */ + long int number_new_stars; +}; + +/** + * Structure containing the global star formation information (including time + * integrated variables). + */ +struct star_formation_history_accumulator { + /*! Total stellar mass from the begining of the simulation */ + float total_stellar_mass; + + /*! Total number of stars */ + long int total_number_stars; + + /*! Stellar mass created in the current timestep */ + float new_stellar_mass; + + /*! Number of stars created in this timestep */ + long int number_new_stars; +}; + +#endif /* SWIFT_GEAR_STAR_FORMATION_LOGGER_STRUCT_H */ diff --git a/src/star_formation/GEAR/star_formation_struct.h b/src/star_formation/GEAR/star_formation_struct.h index 9b4e216fd2955f29d89dade6ee46c0e1af715cdb..2e9a7548f83ca6ae9bb78ee7bcf4be69a0a31489 100644 --- a/src/star_formation/GEAR/star_formation_struct.h +++ b/src/star_formation/GEAR/star_formation_struct.h @@ -25,7 +25,27 @@ */ struct star_formation_xpart_data {}; -/* Starformation struct */ -struct star_formation {}; +struct star_formation_part_data { + // TODO move it to the pressure floor + /*! Estimation of local turbulence (squared) */ + float sigma2; +}; + +/** + * @brief Global star formation properties + */ +struct star_formation { + + // TODO move it to pressure floor + /*! Number of particle required to resolved the Jeans criterion (at power 2/3) + */ + float n_jeans_2_3; + + /*! Maximal temperature for forming a star */ + float maximal_temperature; + + /*! Star formation efficiency */ + float star_formation_efficiency; +}; #endif /* SWIFT_GEAR_STAR_FORMATION_STRUCT_H */ diff --git a/src/star_formation/none/star_formation.h b/src/star_formation/none/star_formation.h index 412bda2cc356729bb9f3e3657689fb5bb7b36d8f..6b83010ec5f8935778af8c9ad21010ff3452fc0e 100644 --- a/src/star_formation/none/star_formation.h +++ b/src/star_formation/none/star_formation.h @@ -220,6 +220,7 @@ star_formation_first_init_part(const struct phys_const* restrict phys_const, * @param data The global star_formation information. */ __attribute__((always_inline)) INLINE static void star_formation_init_part( - struct part* restrict p, const struct star_formation* data) {} + struct part* restrict p, struct xpart* restrict xp, + const struct star_formation* data) {} #endif /* SWIFT_NONE_STAR_FORMATION_H */ diff --git a/src/star_formation/none/star_formation_logger.h b/src/star_formation/none/star_formation_logger.h index b4e6987c03d295348fc8c22d66cb20d10e54378c..552df0c6cae533d1eb2678cb23dd675e0a058715 100644 --- a/src/star_formation/none/star_formation_logger.h +++ b/src/star_formation/none/star_formation_logger.h @@ -59,6 +59,18 @@ INLINE static void star_formation_logger_add( struct star_formation_history *sf_update, const struct star_formation_history *sf_add) {} +/** + * @brief add a star formation history accumulator struct to an other star + * formation history struct + * + * @param sf_add the star formation accumulator struct which we want to add to + * the star formation history + * @param sf_update the star formation structure which we want to update + */ +INLINE static void star_formation_logger_add_to_accumulator( + struct star_formation_history_accumulator *sf_update, + const struct star_formation_history *sf_add) {} + /** * @brief Initialize the star formation history structure in the #engine * @@ -67,6 +79,14 @@ INLINE static void star_formation_logger_add( INLINE static void star_formation_logger_init( struct star_formation_history *sfh) {} +/** + * @brief Initialize the star formation history structure in the #engine + * + * @param sfh The pointer to the star formation history structure + */ +INLINE static void star_formation_logger_accumulator_init( + struct star_formation_history_accumulator *sfh) {} + /** * @brief Write the final SFH to a file * @@ -74,12 +94,12 @@ INLINE static void star_formation_logger_init( * @param time the simulation time (time since Big Bang) in internal units. * @param a the scale factor. * @param z the redshift. - * @param sf the #star_formation_history struct. + * @param sf the #star_formation_history_accumulator struct. * @param step The time-step of the simulation. */ INLINE static void star_formation_logger_write_to_log_file( FILE *fp, const double time, const double a, const double z, - const struct star_formation_history sf, const int step) {} + const struct star_formation_history_accumulator sf, const int step) {} /** * @brief Initialize the SFH logger file diff --git a/src/star_formation/none/star_formation_logger_struct.h b/src/star_formation/none/star_formation_logger_struct.h index 9efda271da96faf2088169fd75d0e3c01247a429..b60c64f2eb47894db828a1bde0ca20803892c7db 100644 --- a/src/star_formation/none/star_formation_logger_struct.h +++ b/src/star_formation/none/star_formation_logger_struct.h @@ -22,4 +22,10 @@ /* Starformation history struct */ struct star_formation_history {}; +/* Starformation history accumulator struct. + This structure is only defined in the engine and + allows the user to integrate some quantities over time. +*/ +struct star_formation_history_accumulator {}; + #endif /* SWIFT_NONE_STAR_FORMATION_STRUCT_H */ diff --git a/src/star_formation/none/star_formation_struct.h b/src/star_formation/none/star_formation_struct.h index 27a2adaf83d0a02a0d08e7eef8b45bea630689e4..2f5241a58caf1ca70fa98a40d467c8ff5a3237f7 100644 --- a/src/star_formation/none/star_formation_struct.h +++ b/src/star_formation/none/star_formation_struct.h @@ -25,4 +25,10 @@ */ struct star_formation_xpart_data {}; +/** + * @brief Star-formation-related properties stored in the particle + * data. + */ +struct star_formation_part_data {}; + #endif /* SWIFT_NONE_STAR_FORMATION_STRUCT_H */ diff --git a/src/stars.h b/src/stars.h index dd8390e0206580fc2a07a08e51bb69c6ee5ab5ed..dea6e07a87cabd7d1778ec2a850be4f3b16b04b0 100644 --- a/src/stars.h +++ b/src/stars.h @@ -29,6 +29,9 @@ #elif defined(STARS_EAGLE) #include "./stars/EAGLE/stars.h" #include "./stars/EAGLE/stars_iact.h" +#elif defined(STARS_GEAR) +#include "./stars/GEAR/stars.h" +#include "./stars/GEAR/stars_iact.h" #else #error "Invalid choice of star model" #endif diff --git a/src/stars/GEAR/stars.h b/src/stars/GEAR/stars.h new file mode 100644 index 0000000000000000000000000000000000000000..467aaa164ba9762d85f8dfae85db86ff76ae779e --- /dev/null +++ b/src/stars/GEAR/stars.h @@ -0,0 +1,172 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_GEAR_STARS_H +#define SWIFT_GEAR_STARS_H + +#include <float.h> +#include "minmax.h" + +/** + * @brief Computes the gravity time-step of a given star particle. + * + * @param sp Pointer to the s-particle data. + */ +__attribute__((always_inline)) INLINE static float stars_compute_timestep( + const struct spart* const sp) { + + return FLT_MAX; +} + +/** + * @brief Initialises the s-particles for the first time + * + * This function is called only once just after the ICs have been + * read in to do some conversions. + * + * @param sp The particle to act upon + * @param stars_properties The properties of the stellar model. + */ +__attribute__((always_inline)) INLINE static void stars_first_init_spart( + struct spart* sp, const struct stars_props* stars_properties) { + + sp->time_bin = 0; +} + +/** + * @brief Prepares a s-particle for its interactions + * + * @param sp The particle to act upon + */ +__attribute__((always_inline)) INLINE static void stars_init_spart( + struct spart* sp) { + +#ifdef DEBUG_INTERACTIONS_STARS + for (int i = 0; i < MAX_NUM_OF_NEIGHBOURS_STARS; ++i) + sp->ids_ngbs_density[i] = -1; + sp->num_ngb_density = 0; +#endif + + sp->density.wcount = 0.f; + sp->density.wcount_dh = 0.f; +} + +/** + * @brief Predict additional particle fields forward in time when drifting + * + * @param sp The particle + * @param dt_drift The drift time-step for positions. + */ +__attribute__((always_inline)) INLINE static void stars_predict_extra( + struct spart* restrict sp, float dt_drift) {} + +/** + * @brief Sets the values to be predicted in the drifts to their values at a + * kick time + * + * @param sp The particle. + */ +__attribute__((always_inline)) INLINE static void stars_reset_predicted_values( + struct spart* restrict sp) {} + +/** + * @brief Finishes the calculation of (non-gravity) forces acting on stars + * + * @param sp The particle to act upon + */ +__attribute__((always_inline)) INLINE static void stars_end_feedback( + struct spart* sp) {} + +/** + * @brief Kick the additional variables + * + * @param sp The particle to act upon + * @param dt The time-step for this kick + */ +__attribute__((always_inline)) INLINE static void stars_kick_extra( + struct spart* sp, float dt) {} + +/** + * @brief Finishes the calculation of density on stars + * + * @param sp The particle to act upon + * @param cosmo The current cosmological model. + */ +__attribute__((always_inline)) INLINE static void stars_end_density( + struct spart* sp, const struct cosmology* cosmo) { + + /* Some smoothing length multiples. */ + const float h = sp->h; + const float h_inv = 1.0f / h; /* 1/h */ + const float h_inv_dim = pow_dimension(h_inv); /* 1/h^d */ + const float h_inv_dim_plus_one = h_inv_dim * h_inv; /* 1/h^(d+1) */ + + /* Finish the calculation by inserting the missing h-factors */ + sp->density.wcount *= h_inv_dim; + sp->density.wcount_dh *= h_inv_dim_plus_one; +} + +/** + * @brief Sets all particle fields to sensible values when the #spart has 0 + * ngbs. + * + * @param sp The particle to act upon + * @param cosmo The current cosmological model. + */ +__attribute__((always_inline)) INLINE static void stars_spart_has_no_neighbours( + struct spart* restrict sp, const struct cosmology* cosmo) { + + /* Some smoothing length multiples. */ + const float h = sp->h; + const float h_inv = 1.0f / h; /* 1/h */ + const float h_inv_dim = pow_dimension(h_inv); /* 1/h^d */ + + /* Re-set problematic values */ + sp->density.wcount = kernel_root * h_inv_dim; + sp->density.wcount_dh = 0.f; +} + +/** + * @brief Reset acceleration fields of a particle + * + * This is the equivalent of hydro_reset_acceleration. + * We do not compute the acceleration on star, therefore no need to use it. + * + * @param p The particle to act upon + */ +__attribute__((always_inline)) INLINE static void stars_reset_feedback( + struct spart* restrict p) { + +#ifdef DEBUG_INTERACTIONS_STARS + for (int i = 0; i < MAX_NUM_OF_NEIGHBOURS_STARS; ++i) + p->ids_ngbs_force[i] = -1; + p->num_ngb_force = 0; +#endif +} + +/** + * @brief Initializes constants related to stellar evolution, initializes imf, + * reads and processes yield tables + * + * @param params swift_params parameters structure + * @param stars stars_props data structure + */ +inline static void stars_evolve_init(struct swift_params* params, + struct stars_props* restrict stars) {} + +#endif /* SWIFT_GEAR_STARS_H */ diff --git a/src/stars/GEAR/stars_debug.h b/src/stars/GEAR/stars_debug.h new file mode 100644 index 0000000000000000000000000000000000000000..41953367f6c8771ffd7460cee493c8330ecd874b --- /dev/null +++ b/src/stars/GEAR/stars_debug.h @@ -0,0 +1,31 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_GEAR_STARS_DEBUG_H +#define SWIFT_GEAR_STARS_DEBUG_H + +__attribute__((always_inline)) INLINE static void stars_debug_particle( + const struct spart* p) { + printf( + "x=[%.3e,%.3e,%.3e], " + "v_full=[%.3e,%.3e,%.3e] p->mass=%.3e \n t_begin=%d, t_end=%d\n", + p->x[0], p->x[1], p->x[2], p->v_full[0], p->v_full[1], p->v_full[2], + p->mass, p->ti_begin, p->ti_end); +} + +#endif /* SWIFT_GEAR_STARS_DEBUG_H */ diff --git a/src/stars/GEAR/stars_iact.h b/src/stars/GEAR/stars_iact.h new file mode 100644 index 0000000000000000000000000000000000000000..c7bda43fc0c66fcc890e6b05bacf871edfd10b5a --- /dev/null +++ b/src/stars/GEAR/stars_iact.h @@ -0,0 +1,94 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_GEAR_STARS_IACT_H +#define SWIFT_GEAR_STARS_IACT_H + +/** + * @brief Density interaction between two particles (non-symmetric). + * + * @param r2 Comoving square distance between the two particles. + * @param dx Comoving vector separating both particles (pi - pj). + * @param hi Comoving smoothing-length of particle i. + * @param hj Comoving smoothing-length of particle j. + * @param si First sparticle. + * @param pj Second particle (not updated). + * @param a Current scale factor. + * @param H Current Hubble parameter. + */ +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_stars_density(const float r2, const float *dx, + const float hi, const float hj, + struct spart *restrict si, + const struct part *restrict pj, const float a, + const float H) { + + float wi, wi_dx; + + /* Get r and 1/r. */ + const float r_inv = 1.0f / sqrtf(r2); + const float r = r2 * r_inv; + + /* Compute the kernel function */ + const float hi_inv = 1.0f / hi; + const float ui = r * hi_inv; + kernel_deval(ui, &wi, &wi_dx); + + /* Compute contribution to the number of neighbours */ + si->density.wcount += wi; + si->density.wcount_dh -= (hydro_dimension * wi + ui * wi_dx); + +#ifdef DEBUG_INTERACTIONS_STARS + /* Update ngb counters */ + if (si->num_ngb_density < MAX_NUM_OF_NEIGHBOURS_STARS) + si->ids_ngbs_density[si->num_ngb_density] = pj->id; + + /* Update ngb counters */ + ++si->num_ngb_density; +#endif +} + +/** + * @brief Feedback interaction between two particles (non-symmetric). + * + * @param r2 Comoving square distance between the two particles. + * @param dx Comoving vector separating both particles (pi - pj). + * @param hi Comoving smoothing-length of particle i. + * @param hj Comoving smoothing-length of particle j. + * @param si First sparticle. + * @param pj Second particle (not updated). + * @param a Current scale factor. + * @param H Current Hubble parameter. + */ +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_stars_feedback(const float r2, const float *dx, + const float hi, const float hj, + struct spart *restrict si, + struct part *restrict pj, const float a, + const float H) { +#ifdef DEBUG_INTERACTIONS_STARS + /* Update ngb counters */ + if (si->num_ngb_force < MAX_NUM_OF_NEIGHBOURS_STARS) + si->ids_ngbs_force[si->num_ngb_force] = pj->id; + + /* Update ngb counters */ + ++si->num_ngb_force; +#endif +} + +#endif diff --git a/src/stars/GEAR/stars_io.h b/src/stars/GEAR/stars_io.h new file mode 100644 index 0000000000000000000000000000000000000000..ebd72aa50a4194bf8c6f747e55d265ace0550c35 --- /dev/null +++ b/src/stars/GEAR/stars_io.h @@ -0,0 +1,248 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_GEAR_STARS_IO_H +#define SWIFT_GEAR_STARS_IO_H + +#include "io_properties.h" +#include "stars_part.h" + +/** + * @brief Specifies which s-particle fields to read from a dataset + * + * @param sparts The s-particle array. + * @param list The list of i/o properties to read. + * @param num_fields The number of i/o fields to read. + */ +INLINE static void stars_read_particles(struct spart *sparts, + struct io_props *list, + int *num_fields) { + + /* Say how much we want to read */ + *num_fields = 5; + + /* List what we want to read */ + list[0] = io_make_input_field("Coordinates", DOUBLE, 3, COMPULSORY, + UNIT_CONV_LENGTH, sparts, x); + list[1] = io_make_input_field("Velocities", FLOAT, 3, COMPULSORY, + UNIT_CONV_SPEED, sparts, v); + list[2] = io_make_input_field("Masses", FLOAT, 1, COMPULSORY, UNIT_CONV_MASS, + sparts, mass); + list[3] = io_make_input_field("ParticleIDs", LONGLONG, 1, COMPULSORY, + UNIT_CONV_NO_UNITS, sparts, id); + list[4] = io_make_input_field("SmoothingLength", FLOAT, 1, OPTIONAL, + UNIT_CONV_LENGTH, sparts, h); +} + +/** + * @brief Specifies which s-particle fields to write to a dataset + * + * @param sparts The s-particle array. + * @param list The list of i/o properties to write. + * @param num_fields The number of i/o fields to write. + * @param with_cosmology Is it a cosmological run? + */ +INLINE static void stars_write_particles(const struct spart *sparts, + struct io_props *list, int *num_fields, + const int with_cosmology) { + + /* Say how much we want to write */ + *num_fields = 9; + + /* List what we want to write */ + list[0] = + io_make_output_field("Coordinates", DOUBLE, 3, UNIT_CONV_LENGTH, 1., + sparts, x, "Co-moving positions of the particles"); + + list[1] = io_make_output_field( + "Velocities", FLOAT, 3, UNIT_CONV_SPEED, 0.f, sparts, v, + "Peculiar velocities of the stars. This is (a * dx/dt) where x is the " + "co-moving positions of the particles"); + + list[2] = io_make_output_field("Masses", FLOAT, 1, UNIT_CONV_MASS, 0.f, + sparts, mass, "Masses of the particles"); + + list[3] = + io_make_output_field("ParticleIDs", LONGLONG, 1, UNIT_CONV_NO_UNITS, 0.f, + sparts, id, "Unique IDs of the particles"); + + list[4] = io_make_output_field( + "SmoothingLength", FLOAT, 1, UNIT_CONV_LENGTH, 1.f, sparts, h, + "Co-moving smoothing lengths (FWHM of the kernel) of the particles"); + + if (with_cosmology) { + list[5] = io_make_output_field( + "BirthScaleFactors", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, sparts, + birth_scale_factor, "Scale-factors at which the stars were born"); + } else { + list[5] = io_make_output_field("BirthTimes", FLOAT, 1, UNIT_CONV_TIME, 0.f, + sparts, birth_time, + "Times at which the stars were born"); + } + + list[6] = io_make_output_field( + "BirthDensities", FLOAT, 1, UNIT_CONV_DENSITY, 0.f, sparts, birth.density, + "Physical densities at the time of birth of the gas particles that " + "turned into stars (note that " + "we store the physical density at the birth redshift, no conversion is " + "needed)"); + + list[7] = + io_make_output_field("BirthTemperatures", FLOAT, 1, UNIT_CONV_TEMPERATURE, + 0.f, sparts, birth.temperature, + "Temperatures at the time of birth of the gas " + "particles that turned into stars"); + + list[7] = io_make_output_field("BirthMasses", FLOAT, 1, UNIT_CONV_MASS, 0.f, + sparts, birth.mass, + "Masses of the star particles at birth time"); + +#ifdef DEBUG_INTERACTIONS_STARS + + list += *num_fields; + *num_fields += 4; + + list[0] = io_make_output_field("Num_ngb_density", INT, 1, UNIT_CONV_NO_UNITS, + sparts, num_ngb_density); + list[1] = io_make_output_field("Num_ngb_force", INT, 1, UNIT_CONV_NO_UNITS, + sparts, num_ngb_force); + list[2] = io_make_output_field("Ids_ngb_density", LONGLONG, + MAX_NUM_OF_NEIGHBOURS_STARS, + UNIT_CONV_NO_UNITS, sparts, ids_ngbs_density); + list[3] = io_make_output_field("Ids_ngb_force", LONGLONG, + MAX_NUM_OF_NEIGHBOURS_STARS, + UNIT_CONV_NO_UNITS, sparts, ids_ngbs_force); +#endif +} + +/** + * @brief Initialize the global properties of the stars scheme. + * + * By default, takes the values provided by the hydro. + * + * @param sp The #stars_props. + * @param phys_const The physical constants in the internal unit system. + * @param us The internal unit system. + * @param params The parsed parameters. + * @param p The already read-in properties of the hydro scheme. + * @param cosmo The cosmological model. + */ +INLINE static void stars_props_init(struct stars_props *sp, + const struct phys_const *phys_const, + const struct unit_system *us, + struct swift_params *params, + const struct hydro_props *p, + const struct cosmology *cosmo) { + + /* Kernel properties */ + sp->eta_neighbours = parser_get_opt_param_float( + params, "Stars:resolution_eta", p->eta_neighbours); + + /* Tolerance for the smoothing length Newton-Raphson scheme */ + sp->h_tolerance = + parser_get_opt_param_float(params, "Stars:h_tolerance", p->h_tolerance); + + /* Get derived properties */ + sp->target_neighbours = pow_dimension(sp->eta_neighbours) * kernel_norm; + const float delta_eta = sp->eta_neighbours * (1.f + sp->h_tolerance); + sp->delta_neighbours = + (pow_dimension(delta_eta) - pow_dimension(sp->eta_neighbours)) * + kernel_norm; + + /* Number of iterations to converge h */ + sp->max_smoothing_iterations = parser_get_opt_param_int( + params, "Stars:max_ghost_iterations", p->max_smoothing_iterations); + + /* Time integration properties */ + const float max_volume_change = + parser_get_opt_param_float(params, "Stars:max_volume_change", -1); + if (max_volume_change == -1) + sp->log_max_h_change = p->log_max_h_change; + else + sp->log_max_h_change = logf(powf(max_volume_change, hydro_dimension_inv)); +} + +/** + * @brief Print the global properties of the stars scheme. + * + * @param sp The #stars_props. + */ +INLINE static void stars_props_print(const struct stars_props *sp) { + + /* Now stars */ + message("Stars kernel: %s with eta=%f (%.2f neighbours).", kernel_name, + sp->eta_neighbours, sp->target_neighbours); + + message("Stars relative tolerance in h: %.5f (+/- %.4f neighbours).", + sp->h_tolerance, sp->delta_neighbours); + + message( + "Stars integration: Max change of volume: %.2f " + "(max|dlog(h)/dt|=%f).", + pow_dimension(expf(sp->log_max_h_change)), sp->log_max_h_change); + + message("Maximal iterations in ghost task set to %d", + sp->max_smoothing_iterations); +} + +#if defined(HAVE_HDF5) +INLINE static void stars_props_print_snapshot(hid_t h_grpstars, + const struct stars_props *sp) { + + io_write_attribute_s(h_grpstars, "Kernel function", kernel_name); + io_write_attribute_f(h_grpstars, "Kernel target N_ngb", + sp->target_neighbours); + io_write_attribute_f(h_grpstars, "Kernel delta N_ngb", sp->delta_neighbours); + io_write_attribute_f(h_grpstars, "Kernel eta", sp->eta_neighbours); + io_write_attribute_f(h_grpstars, "Smoothing length tolerance", + sp->h_tolerance); + io_write_attribute_f(h_grpstars, "Volume log(max(delta h))", + sp->log_max_h_change); + io_write_attribute_f(h_grpstars, "Volume max change time-step", + pow_dimension(expf(sp->log_max_h_change))); + io_write_attribute_i(h_grpstars, "Max ghost iterations", + sp->max_smoothing_iterations); +} +#endif + +/** + * @brief Write a #stars_props struct to the given FILE as a stream of bytes. + * + * @param p the struct + * @param stream the file stream + */ +INLINE static void stars_props_struct_dump(const struct stars_props *p, + FILE *stream) { + restart_write_blocks((void *)p, sizeof(struct stars_props), 1, stream, + "starsprops", "stars props"); +} + +/** + * @brief Restore a stars_props struct from the given FILE as a stream of + * bytes. + * + * @param p the struct + * @param stream the file stream + */ +INLINE static void stars_props_struct_restore(const struct stars_props *p, + FILE *stream) { + restart_read_blocks((void *)p, sizeof(struct stars_props), 1, stream, NULL, + "stars props"); +} + +#endif /* SWIFT_GEAR_STAR_IO_H */ diff --git a/src/stars/GEAR/stars_part.h b/src/stars/GEAR/stars_part.h new file mode 100644 index 0000000000000000000000000000000000000000..bf68a580ef009f5a814fa17123301b5585d6084c --- /dev/null +++ b/src/stars/GEAR/stars_part.h @@ -0,0 +1,154 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_GEAR_STAR_PART_H +#define SWIFT_GEAR_STAR_PART_H + +/* Some standard headers. */ +#include <stdlib.h> + +/* Read additional subgrid models */ +#include "chemistry_struct.h" +#include "feedback_struct.h" +#include "tracers_struct.h" + +/** + * @brief Particle fields for the star particles. + * + * All quantities related to gravity are stored in the associate #gpart. + */ +struct spart { + + /*! Particle ID. */ + long long id; + + /*! Pointer to corresponding gravity part. */ + struct gpart* gpart; + + /*! Particle position. */ + double x[3]; + + /* Offset between current position and position at last tree rebuild. */ + float x_diff[3]; + + /* Offset between current position and position at last tree rebuild. */ + float x_diff_sort[3]; + + /*! Particle velocity. */ + float v[3]; + + /*! Star mass */ + float mass; + + /* Particle cutoff radius. */ + float h; + + /*! Union for the birth time and birth scale factor */ + union { + + /*! Birth time */ + float birth_time; + + /*! Birth scale factor */ + float birth_scale_factor; + }; + + /*! Particle time bin */ + timebin_t time_bin; + + struct { + + /* Number of neighbours. */ + float wcount; + + /* Number of neighbours spatial derivative. */ + float wcount_dh; + + } density; + + struct { + /*! birth density*/ + float density; + + /*! birth temperature*/ + float temperature; + + /*! birth mass */ + float mass; + } birth; + + /*! Feedback structure */ + struct feedback_spart_data feedback_data; + + /*! Tracer structure */ + struct tracers_xpart_data tracers_data; + + /*! Chemistry structure */ + struct chemistry_part_data chemistry_data; + +#ifdef SWIFT_DEBUG_CHECKS + + /* Time of the last drift */ + integertime_t ti_drift; + + /* Time of the last kick */ + integertime_t ti_kick; + +#endif + +#ifdef DEBUG_INTERACTIONS_STARS + /*! Number of interactions in the density SELF and PAIR */ + int num_ngb_density; + + /*! List of interacting particles in the density SELF and PAIR */ + long long ids_ngbs_density[MAX_NUM_OF_NEIGHBOURS_STARS]; + + /*! Number of interactions in the force SELF and PAIR */ + int num_ngb_force; + + /*! List of interacting particles in the force SELF and PAIR */ + long long ids_ngbs_force[MAX_NUM_OF_NEIGHBOURS_STARS]; +#endif + +} SWIFT_STRUCT_ALIGN; + +/** + * @brief Contains all the constants and parameters of the stars scheme + */ +struct stars_props { + + /*! Resolution parameter */ + float eta_neighbours; + + /*! Target weightd number of neighbours (for info only)*/ + float target_neighbours; + + /*! Smoothing length tolerance */ + float h_tolerance; + + /*! Tolerance on neighbour number (for info only)*/ + float delta_neighbours; + + /*! Maximal number of iterations to converge h */ + int max_smoothing_iterations; + + /*! Maximal change of h over one time-step */ + float log_max_h_change; +}; + +#endif /* SWIFT_GEAR_STAR_PART_H */ diff --git a/src/swift.h b/src/swift.h index b9f8818d8b833231971abb1afb36ee4507648488..7790ec6f9203a6534e2f569017d90090352d8f28 100644 --- a/src/swift.h +++ b/src/swift.h @@ -64,6 +64,7 @@ #include "periodic.h" #include "physical_constants.h" #include "potential.h" +#include "pressure_floor.h" #include "profiler.h" #include "queue.h" #include "random.h"