diff --git a/configure.ac b/configure.ac index de43445462fb0b44ebf72964d5d51a2ae0d32776..5e83a497add952997500694d1d477ee74a237038 100644 --- a/configure.ac +++ b/configure.ac @@ -1612,16 +1612,13 @@ AM_CONDITIONAL([HAVESTANDALONEFOF],[test $enable_standalone_fof = "yes"]) # Gravity scheme. AC_ARG_WITH([gravity], [AS_HELP_STRING([--with-gravity=<scheme>], - [Gravity scheme to use @<:@basic, with-potential, with-multi-softening default: with-multi-softening@:>@] + [Gravity scheme to use @<:@basic, with-multi-softening default: with-multi-softening@:>@] )], [with_gravity="$withval"], [with_gravity="with-multi-softening"] ) case "$with_gravity" in - with-potential) - AC_DEFINE([POTENTIAL_GRAVITY], [1], [Basic gravity scheme with potential calculation]) - ;; with-multi-softening) AC_DEFINE([MULTI_SOFTENING_GRAVITY], [1], [Gravity scheme with per-particle type softening value and background particles]) ;; @@ -1633,13 +1630,24 @@ case "$with_gravity" in ;; esac +AC_ARG_ENABLE([gravitational-potential], + [AS_HELP_STRING([--disable-gravitational-potential], + [Disable calculation of the gravitational potential.] + )], + [enable_gravitational_potential="$enableval"], + [enable_gravitational_potential="yes"] +) +if test "$enable_gravitational_potential" = "no"; then + AC_DEFINE([SWIFT_GRAVITY_NO_POTENTIAL],1,[Disable calculation of the gravitational potential]) +fi + # Hydro scheme. AC_ARG_WITH([hydro], [AS_HELP_STRING([--with-hydro=<scheme>], - [Hydro dynamics to use @<:@gadget2, minimal, pressure-entropy, pressure-energy, pressure-energy-monaghan, default, gizmo-mfv, gizmo-mfm, shadowfax, planetary, sphenix, anarchy-pu default: gadget2@:>@] + [Hydro dynamics to use @<:@gadget2, minimal, pressure-entropy, pressure-energy, pressure-energy-monaghan, phantom, gizmo-mfv, gizmo-mfm, shadowfax, planetary, sphenix, anarchy-pu default: sphenix@:>@] )], [with_hydro="$withval"], - [with_hydro="gadget2"] + [with_hydro="sphenix"] ) case "$with_hydro" in @@ -1658,8 +1666,8 @@ case "$with_hydro" in pressure-energy-monaghan) AC_DEFINE([HOPKINS_PU_SPH_MONAGHAN], [1], [Pressure-Energy SPH with M&M Variable A.V.]) ;; - default) - AC_DEFINE([DEFAULT_SPH], [1], [Default SPH]) + phantom) + AC_DEFINE([PHANTOM_SPH], [1], [Phantom SPH]) ;; gizmo-mfv) AC_DEFINE([GIZMO_MFV_SPH], [1], [GIZMO MFV SPH]) @@ -1731,6 +1739,24 @@ if test "$enable_debug_interactions" != "no"; then fi fi +# Check if debugging interactions sinks is switched on. +AC_ARG_ENABLE([debug-interactions-sinks], + [AS_HELP_STRING([--enable-debug-interactions-sinks], + [Activate interaction debugging for sinks, logging a maximum of @<:@N@:>@ neighbours. Defaults to 256 if no value set.] + )], + [enable_debug_interactions_sinks="$enableval"], + [enable_debug_interactions_sinks="no"] +) +if test "$enable_debug_interactions_sinks" != "no"; then + AC_DEFINE([DEBUG_INTERACTIONS_SINKS],1,[Enable interaction debugging for sinks]) + if test "$enable_debug_interactions_sinks" == "yes"; then + AC_DEFINE([MAX_NUM_OF_NEIGHBOURS_SINKS],256,[The maximum number of particle neighbours to be logged for sinks]) + [enable_debug_interactions_sinks="yes (Logging up to 256 neighbours)"] + else + AC_DEFINE_UNQUOTED([MAX_NUM_OF_NEIGHBOURS_SINKS], [$enableval] ,[The maximum number of particle neighbours to be logged for sinks]) + [enable_debug_interactions_sinks="yes (Logging up to $enableval neighbours)"] + fi +fi # SPH Kernel function AC_ARG_WITH([kernel], @@ -1864,7 +1890,7 @@ esac # Cooling function AC_ARG_WITH([cooling], [AS_HELP_STRING([--with-cooling=<model>], - [cooling function @<:@none, const-du, const-lambda, QLA, EAGLE, grackle_* default: none@:>@. + [cooling function @<:@none, const-du, const-lambda, QLA, EAGLE, COLIBRE, Wiersma, Ploeckinger, grackle_* default: none@:>@. For Grackle, you need to provide the primordial chemistry parameter (e.g. grackle_0)] )], [with_cooling="$withval"], @@ -1899,12 +1925,23 @@ case "$with_cooling" in ;; QLA) AC_DEFINE([COOLING_QLA], [1], [Cooling following the Quick-Lyman-alpha model]) + with_cooling="QLA (Ploeckinger+20 tables) with constant primordial Z" ;; EAGLE) - AC_DEFINE([COOLING_EAGLE], [1], [Cooling following the EAGLE model]) + AC_DEFINE([COOLING_EAGLE], [1], [Cooling following the EAGLE model (Wiersma+09 tables)]) + with_cooling="EAGLE (Wiersma+09 tables)" + ;; + Wiersma) + AC_DEFINE([COOLING_EAGLE], [1], [Cooling following the EAGLE model (Wiersma+09 tables)]) + with_cooling="EAGLE (Wiersma+09 tables)" ;; COLIBRE) - AC_DEFINE([COOLING_COLIBRE], [1], [Cooling following the COLIBRE model]) + AC_DEFINE([COOLING_COLIBRE], [1], [Cooling following the COLIBRE model (Ploeckinger+20 tables)]) + with_cooling="COLIBRE (Ploeckinger+20 tables)" + ;; + Ploeckinger) + AC_DEFINE([COOLING_COLIBRE], [1], [Cooling following the COLIBRE model (Ploeckinger+20 tables)]) + with_cooling="COLIBRE (Ploeckinger+20 tables)" ;; *) AC_MSG_ERROR([Unknown cooling function: $with_cooling]) @@ -2306,22 +2343,22 @@ DX_INIT_DOXYGEN(SWIFT, doc/Doxyfile, doc/) AM_CONDITIONAL([HAVE_DOXYGEN], [test "$ac_cv_path_ac_pt_DX_DOXYGEN" != ""]) # Check if using QLA cooling -AM_CONDITIONAL([HAVEQLACOOLING], [test $with_cooling = "QLA"]) +AM_CONDITIONAL([HAVEQLACOOLING], [test "${with_cooling:0:3}" == "QLA"]) # Check if using EAGLE cooling -AM_CONDITIONAL([HAVEEAGLECOOLING], [test $with_cooling = "EAGLE"]) +AM_CONDITIONAL([HAVEEAGLECOOLING], [test "${with_cooling:0:5}" == "EAGLE"]) # Check if using COLIBRE cooling -AM_CONDITIONAL([HAVECOLIBRECOOLING], [test $with_cooling = "COLIBRE"]) +AM_CONDITIONAL([HAVECOLIBRECOOLING], [test "${with_cooling:0:7}" == "COLIBRE"]) # Check if using EAGLE feedback -AM_CONDITIONAL([HAVEEAGLEFEEDBACK], [test $with_feedback = "EAGLE"]) +AM_CONDITIONAL([HAVEEAGLEFEEDBACK], [test "$with_feedback" == "EAGLE"]) # check if using grackle cooling -AM_CONDITIONAL([HAVEGRACKLECOOLING], [test ${with_cooling:0:7} == "grackle"]) +AM_CONDITIONAL([HAVEGRACKLECOOLING], [test "${with_cooling:0:7}" == "grackle"]) # check if using gear feedback -AM_CONDITIONAL([HAVEGEARFEEDBACK], [test $with_feedback == "GEAR"]) +AM_CONDITIONAL([HAVEGEARFEEDBACK], [test "$with_feedback" == "GEAR"]) # Handle .in files. AC_CONFIG_FILES([Makefile src/Makefile examples/Makefile examples/Cooling/CoolingRates/Makefile doc/Makefile doc/Doxyfile tests/Makefile]) @@ -2389,6 +2426,7 @@ AC_MSG_RESULT([ Gravity scheme : $with_gravity Multipole order : $with_multipole_order + Compute potential : $enable_gravitational_potential No gravity below ID : $no_gravity_below_id Make gravity glass : $gravity_glass_making External potential : $with_potential diff --git a/doc/RTD/source/HydroSchemes/index.rst b/doc/RTD/source/HydroSchemes/index.rst index a59ba7c71c22933466be110969d8582e702852e4..d276b56abf3b6b77c1c9af569c6d37143a117c06 100644 --- a/doc/RTD/source/HydroSchemes/index.rst +++ b/doc/RTD/source/HydroSchemes/index.rst @@ -19,6 +19,7 @@ schemes available in SWIFT, as well as how to implement your own. hopkins_sph anarchy_sph sphenix_sph + phantom_sph gizmo adding_your_own diff --git a/doc/RTD/source/HydroSchemes/phantom_sph.rst b/doc/RTD/source/HydroSchemes/phantom_sph.rst new file mode 100644 index 0000000000000000000000000000000000000000..9b63759bc7dc3af6f54f5469f25a12f4fbfe9279 --- /dev/null +++ b/doc/RTD/source/HydroSchemes/phantom_sph.rst @@ -0,0 +1,52 @@ +.. PHANTOM SPH + Josh Borrow 13th October 2020 + +Phantom +======= + +This scheme is a reference implementation similar to the one presented in +Price (2018), the PHANTOM paper (not including MHD). It uses: + ++ A simplified Cullen & Dehnen AV limiter (note that this is different to + PHANTOM as we do not explicitly include the matrix calculation). ++ A fixed alpha artificial conduction scheme used for hydro-only problems + as presented in the PHANTOM paper (i.e. we use the 'hydro-only' conduction + velocity, rather than the one used for gravitational problems). ++ Base Density-Energy SPH + +The simplified version of the 'Inviscid SPH' artificial viscosity calculates +the time differential of the velocity divergence explicitly, using the value +from the previous step. We also use the Balsara switch instead of the improved +neighbour-based limiter from Cullen & Dehnen 2010, to avoid matrix +calculations. We also use a different value for the 'h-factors' due to SWIFT +using neighbour finding based on particle number density, rather than local +mass density. + + +To configure with this scheme, use + +.. code-block:: bash + + ./configure --with-hydro=phantom --disable-hand-vec + + +The parameters available for this scheme, and their defaults, are: + +.. code-block:: yaml + + SPH: + viscosity_alpha: 0.1 # Initial value for the alpha viscosity + viscosity_length: 0.25 # Viscosity decay length (in terms of sound-crossing time) + # These are enforced each time-step + viscosity_alpha_max: 2.0 # Maximal allowed value for the viscosity alpha + viscosity_alpha_min: 0.0 # Minimal allowed value for the viscosity alpha + + diffusion_alpha: 1.0 # Fixed value for the diffusion alpha + + +There is also a compile-time parameter, ``viscosity_beta`` that we set to +3.0. During feedback events, the viscosity is set to the compile-time +``hydro_props_default_viscosity_alpha_feedback_reset = 2.0`` and the +diffusion is set to ``hydro_props_default_diffusion_alpha_feedback_reset = +0.0``. These can be changed in ``src/hydro/Phantom/hydro_parameters.h``. + diff --git a/doc/RTD/source/ParameterFiles/parameter_description.rst b/doc/RTD/source/ParameterFiles/parameter_description.rst index 5505ae1e42d0ae113e6ad6dced1e6c8fe06583ec..089d3538b16e39005ee1f7f72e18cea57a1d3897 100644 --- a/doc/RTD/source/ParameterFiles/parameter_description.rst +++ b/doc/RTD/source/ParameterFiles/parameter_description.rst @@ -217,7 +217,7 @@ to be supplied. In case of zoom simulations, the softening of the additional, more massive, background particles is specified via the parameter ``softening_ratio_background``. Since these particles will typically have -different masses to degrade the resolution away from the zoom region, the +different masses to degrade the resolution away from the zoom-in region, the particles won't have a single softening value. Instead, we specify the fraction of the mean inter-particle separation to use. The code will then derive the softening length of each particle assuming the mean density of @@ -225,11 +225,22 @@ the Universe. That is :math:`\epsilon_{\rm background} = f\sqrt[3]{\frac{m}{\Omega_m\rho_{\rm crit}}}`, where :math:`f` is the user-defined value (typically of order 0.05). -The accuracy of the gravity calculation is governed by the following two parameters: +The accuracy of the gravity calculation is governed by the following four parameters: -* The opening angle (multipole acceptance criterion) used in the FMM :math:`\theta`: ``theta``, +* The multipole acceptance criterion: ``MAC`` +* The fixed opening angle used in the geometric MAC :math:`\theta_{\rm cr}`: ``theta_cr``, +* The accuracy criterion used in the adaptive MAC: :math:`\epsilon_{\rm fmm}`: ``epsilon_fmm``, * The time-step size pre-factor :math:`\eta`: ``eta``, +The first three parameters govern the way the Fast-Multipole method +tree-walk is done (see the theory documents for full details). The ``MAC`` +parameter can take two values: ``adaptive`` or ``geometric``. In the first +case, the tree recursion decision is based on the estimated accelerations +that a given tree node will produce, trying to recurse to levels where the +fractional contribution of the accelerations to the cell is less than +:math:`\epsilon_{\rm fmm}`. In the second case, a fixed Barnes-Hut-like +opening angle :math:`\theta_{\rm cr}` is used. + The time-step of a given particle is given by :math:`\Delta t = \sqrt{2\eta\epsilon_i/|\overrightarrow{a}_i|}`, where :math:`\overrightarrow{a}_i` is the particle's acceleration and @@ -237,13 +248,20 @@ The time-step of a given particle is given by :math:`\Delta t = <http://adsabs.harvard.edu/abs/2003MNRAS.338...14P>`_ recommend using :math:`\eta=0.025`. -The last tree-related parameter is +The last tree-related parameters are: * The tree rebuild frequency: ``rebuild_frequency``. +* Whether or not to use the approximate gravity from the FMM tree below the + softening scale: ``use_tree_below_softening`` (default: 0) +* Whether or not the truncated force estimator in the adaptive tree-walk + considers the exponential mesh-related cut-off: + ``allow_truncation_in_MAC`` (default: 0) The tree rebuild frequency is an optional parameter defaulting to -:math:`0.01`. It is used to trigger the re-construction of the tree every time a -fraction of the particles have been integrated (kicked) forward in time. +:math:`0.01`. It is used to trigger the re-construction of the tree every +time a fraction of the particles have been integrated (kicked) forward in +time. The other two parameters default to good all-around choices. See the +theory documentation about their exact effects. Simulations using periodic boundary conditions use additional parameters for the Particle-Mesh part of the calculation. The last five are optional: @@ -257,17 +275,9 @@ Particle-Mesh part of the calculation. The last five are optional: * The scale below which the short-range forces are assumed to be exactly Newtonian (in units of the mesh cell-size multiplied by :math:`a_{\rm smooth}`) :math:`r_{\rm cut,min}`: ``r_cut_min`` (default: ``0.1``), -* Whether or not to dither the particles randomly at each tree rebuild: - ``dithering`` (default: ``1``), -* The magnitude of each component of the dithering vector to use in units of the - top-level cell sizes: ``dithering_ratio`` (default: ``1.0``). For most runs, the default values can be used. Only the number of cells along -each axis needs to be specified. The mesh dithering is only used for simulations -using periodic boundary conditions and in the absence of an external potential. -At each tree rebuild time, all the particles are moved by a random vector (the -same for all particles) and the periodic BCs are then applied. This reduces the -correlation of erros across time. The remaining three values are best described +each axis needs to be specified. The remaining three values are best described in the context of the full set of equations in the theory documents. As a summary, here are the values used for the EAGLE :math:`100^3~{\rm Mpc}^3` @@ -278,7 +288,9 @@ simulation: # Parameters for the self-gravity scheme for the EAGLE-100 box Gravity: eta: 0.025 - theta: 0.6 + MAC: adaptive + theta_cr: 0.6 + epsilon_fmm: 0.001 mesh_side_length: 512 comoving_DM_softening: 0.0026994 # 0.7 proper kpc at z=2.8. max_physical_DM_softening: 0.0007 # 0.7 proper kpc @@ -288,8 +300,8 @@ simulation: a_smooth: 1.25 # Default optional value r_cut_max: 4.5 # Default optional value r_cut_min: 0.1 # Default optional value - dithering: 1 # Default optional value - dithering_ratio: 1.0 # Default optional value + use_tree_below_softening: 0 # Default optional value + allow_truncation_in_MAC: 0 # Default optional value .. _Parameters_SPH: @@ -551,7 +563,8 @@ the start and end times or scale factors from the parameter file. * Dimensionless pre-factor of the maximal allowed displacement: ``max_dt_RMS_factor`` (default: ``0.25``) -This value rarely needs altering. +This value rarely needs altering. See the theory documents for its +precise meaning. A full time-step section for a non-cosmological run would be: diff --git a/doc/RTD/source/Task/adding_your_own.rst b/doc/RTD/source/Task/adding_your_own.rst index 9850adc53da59f47f3d0b5ed085cbb92ac18bbad..6d815b99655ae498314bdc7963f9fdf1be908931 100644 --- a/doc/RTD/source/Task/adding_your_own.rst +++ b/doc/RTD/source/Task/adding_your_own.rst @@ -232,9 +232,17 @@ and give the task an estimate of the computational cost that it will have in cost = wscale * count_i; break; +This activates your tasks once they've been created. + Initially, the engine will need to skip the task that updates the particles. It is the case for the cooling, therefore you will need to add it in -``engine_skip_force_and_kick``. +``engine_skip_force_and_kick()``. +Additionally, the tasks will be marked as 'to be skipped' once they've been +executed during a time step, and then reactivated during the next time step if +they need to be executed again. This way, all the created tasks can be kept and +don't need to be recreated every time step. In order to be unskipped however, +you need to add the unskipping manually to ``engine_do_unskip_mapper()`` in +``engine_unskip.c``. Finally, you also need to initialize your new variables and pointers in ``space_rebuild_recycle_mapper`` in ``space.c``. diff --git a/doc/RTD/source/Task/adding_your_own_neighbour_loop.rst b/doc/RTD/source/Task/adding_your_own_neighbour_loop.rst index 7e4ed2e641f1f3771b98bafb0a0bd5d57ed6522d..18e0687066f4a79643dba1900f9a65e0d2251182 100644 --- a/doc/RTD/source/Task/adding_your_own_neighbour_loop.rst +++ b/doc/RTD/source/Task/adding_your_own_neighbour_loop.rst @@ -350,10 +350,18 @@ and give the task an estimate of the computational cost that it will have in Similarly, you'll need to update ``case task_type_sub_self``, ``task_type_pair``, and ``task_type_sub_pair`` as well. +This activates your tasks once they've been created. Initially, the engine will need to skip the task that updates the particles. If this is the case for your task, you will need to add it in ``engine_skip_force_and_kick``. +Additionally, the tasks will be marked as 'to be skipped' once they've been +executed during a time step, and then reactivated during the next time step if +they need to be executed again. This way, all the created tasks can be kept and +don't need to be recreated every time step. In order to be unskipped however, +you need to add the unskipping manually to ``engine_do_unskip_mapper()`` in +``engine_unskip.c``. + Finally, you also need to initialize your new variables and pointers in ``space_rebuild_recycle_mapper`` in ``space.c``. Additionally, you need to diff --git a/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml b/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml index 2c0f76862f0be8193b36bafd8083879dfd0d45b0..a60e3ff62b6f8c33ed60d9d04cd392654b23b63b 100644 --- a/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml +++ b/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml @@ -185,7 +185,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: Exponential # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_exp_timescale_Gyr: 2.0 # Time-scale of the exponential decay of the SNIa rates in Gyr. @@ -225,13 +226,15 @@ EAGLEAGN: AGN_with_locally_adaptive_delta_T: 1 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). AGN_delta_T_mass_norm: 3e8 # Normalisation temperature of AGN dT scaling with BH subgrid mass [K] (only used if use_variable_delta_T is 1). AGN_delta_T_mass_reference: 1e8 # BH subgrid mass at which the normalisation temperature set above applies [M_Sun] (only used if use_variable_delta_T is 1). - AGN_delta_T_mass_exponent: 0.666667. # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_exponent: 0.666667 # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). AGN_delta_T_crit_factor: 1.0 # Multiple of critical dT for numerical efficiency (Dalla Vecchia & Schaye 2012) to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_background_factor: 0.0 # Multiple of local gas temperature to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_min: 1e7 # Minimum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). AGN_delta_T_max: 3e9 # Maximum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 1e20 # Maximal BH mass considered for BH repositioning in solar masses (large number implies we always reposition). max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 0 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml index 70a81b15089288909ad3d855ecd4d66f04cf3259..ee71b3acb6132c917ab1581f554c43ed0b9f7d9f 100644 --- a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml @@ -184,7 +184,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: Exponential # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_exp_timescale_Gyr: 2.0 # Time-scale of the exponential decay of the SNIa rates in Gyr. @@ -224,13 +225,15 @@ EAGLEAGN: AGN_with_locally_adaptive_delta_T: 1 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). AGN_delta_T_mass_norm: 3e8 # Normalisation temperature of AGN dT scaling with BH subgrid mass [K] (only used if use_variable_delta_T is 1). AGN_delta_T_mass_reference: 1e8 # BH subgrid mass at which the normalisation temperature set above applies [M_Sun] (only used if use_variable_delta_T is 1). - AGN_delta_T_mass_exponent: 0.666667. # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_exponent: 0.666667 # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). AGN_delta_T_crit_factor: 1.0 # Multiple of critical dT for numerical efficiency (Dalla Vecchia & Schaye 2012) to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_background_factor: 0.0 # Multiple of local gas temperature to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_min: 1e7 # Minimum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). AGN_delta_T_max: 3e9 # Maximum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 1e20 # Maximal BH mass considered for BH repositioning in solar masses (large number implies we always reposition). max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 0 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml index 017fb4d25da56506f1735b336d7cc0eb197aa8c6..7ddf078d36e1f7220a83b1266112de4e77a753c7 100644 --- a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml @@ -184,7 +184,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: Exponential # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_exp_timescale_Gyr: 2.0 # Time-scale of the exponential decay of the SNIa rates in Gyr. @@ -224,13 +225,15 @@ EAGLEAGN: AGN_with_locally_adaptive_delta_T: 1 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). AGN_delta_T_mass_norm: 3e8 # Normalisation temperature of AGN dT scaling with BH subgrid mass [K] (only used if use_variable_delta_T is 1). AGN_delta_T_mass_reference: 1e8 # BH subgrid mass at which the normalisation temperature set above applies [M_Sun] (only used if use_variable_delta_T is 1). - AGN_delta_T_mass_exponent: 0.666667. # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_exponent: 0.666667 # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). AGN_delta_T_crit_factor: 1.0 # Multiple of critical dT for numerical efficiency (Dalla Vecchia & Schaye 2012) to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_background_factor: 0.0 # Multiple of local gas temperature to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_min: 1e7 # Minimum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). AGN_delta_T_max: 3e9 # Maximum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 1e20 # Maximal BH mass considered for BH repositioning in solar masses (large number implies we always reposition). max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 0 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml index e0e82c52b17ef71bbf34e0eedd83a15bd9225a4b..bf4c28dd96619f2e113f29b1e2c27c2e0cb49a19 100644 --- a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml @@ -182,7 +182,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: Exponential # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_exp_timescale_Gyr: 2.0 # Time-scale of the exponential decay of the SNIa rates in Gyr. @@ -222,13 +223,15 @@ EAGLEAGN: AGN_with_locally_adaptive_delta_T: 1 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). AGN_delta_T_mass_norm: 3e8 # Normalisation temperature of AGN dT scaling with BH subgrid mass [K] (only used if use_variable_delta_T is 1). AGN_delta_T_mass_reference: 1e8 # BH subgrid mass at which the normalisation temperature set above applies [M_Sun] (only used if use_variable_delta_T is 1). - AGN_delta_T_mass_exponent: 0.666667. # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_exponent: 0.666667 # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). AGN_delta_T_crit_factor: 1.0 # Multiple of critical dT for numerical efficiency (Dalla Vecchia & Schaye 2012) to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_background_factor: 0.0 # Multiple of local gas temperature to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_min: 1e7 # Minimum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). AGN_delta_T_max: 3e9 # Maximum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 1e20 # Maximal BH mass considered for BH repositioning in solar masses (large number implies we always reposition). max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 0 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_ICs/EAGLE_50_low_res/eagle_50.yml b/examples/EAGLE_ICs/EAGLE_50_low_res/eagle_50.yml index 2566c28ecc154c66b172f855c0ad616986c59bfe..2373e005d1e7c4208a0fdfc9891ff9c2a043790e 100644 --- a/examples/EAGLE_ICs/EAGLE_50_low_res/eagle_50.yml +++ b/examples/EAGLE_ICs/EAGLE_50_low_res/eagle_50.yml @@ -181,7 +181,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: Exponential # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_exp_timescale_Gyr: 2.0 # Time-scale of the exponential decay of the SNIa rates in Gyr. @@ -221,13 +222,15 @@ EAGLEAGN: AGN_with_locally_adaptive_delta_T: 1 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). AGN_delta_T_mass_norm: 3e8 # Normalisation temperature of AGN dT scaling with BH subgrid mass [K] (only used if use_variable_delta_T is 1). AGN_delta_T_mass_reference: 1e8 # BH subgrid mass at which the normalisation temperature set above applies [M_Sun] (only used if use_variable_delta_T is 1). - AGN_delta_T_mass_exponent: 0.666667. # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_exponent: 0.666667 # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). AGN_delta_T_crit_factor: 1.0 # Multiple of critical dT for numerical efficiency (Dalla Vecchia & Schaye 2012) to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_background_factor: 0.0 # Multiple of local gas temperature to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_min: 1e7 # Minimum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). AGN_delta_T_max: 3e9 # Maximum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 1e20 # Maximal BH mass considered for BH repositioning in solar masses (large number implies we always reposition). max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 0 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml b/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml index 4607a488f631bbcf887a44385dbb3f7efcce1511..0b11bd5585baca35d2a1b93bb7ca11b4e3a82c53 100644 --- a/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml +++ b/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml @@ -184,7 +184,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: Exponential # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_exp_timescale_Gyr: 2.0 # Time-scale of the exponential decay of the SNIa rates in Gyr. @@ -224,13 +225,15 @@ EAGLEAGN: AGN_with_locally_adaptive_delta_T: 1 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). AGN_delta_T_mass_norm: 3e8 # Normalisation temperature of AGN dT scaling with BH subgrid mass [K] (only used if use_variable_delta_T is 1). AGN_delta_T_mass_reference: 1e8 # BH subgrid mass at which the normalisation temperature set above applies [M_Sun] (only used if use_variable_delta_T is 1). - AGN_delta_T_mass_exponent: 0.666667. # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_exponent: 0.666667 # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). AGN_delta_T_crit_factor: 1.0 # Multiple of critical dT for numerical efficiency (Dalla Vecchia & Schaye 2012) to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_background_factor: 0.0 # Multiple of local gas temperature to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). AGN_delta_T_min: 1e7 # Minimum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). AGN_delta_T_max: 3e9 # Maximum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 1e20 # Maximal BH mass considered for BH repositioning in solar masses (large number implies we always reposition). max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 0 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml index b53438b1976012964d631c93078beb1046c2db7a..1cc80ab7251296273034a23f0bfb4785d77ff180 100644 --- a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml @@ -169,7 +169,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 1 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 1 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 1 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: PowerLaw # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_power_law_norm_p_Msun: 0.0012 # Normalization of the SNIa delay time distribution (in Msun^-1). @@ -206,8 +207,10 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. use_variable_delta_T: 0 # Switch to enable adaptive calculation of AGN dT [1], rather than using a constant value [0]. AGN_with_locally_adaptive_delta_T: 0 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 1 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml index 75a85348259bb9dff0119fad358d726bf9e4dde8..c11d1e4bde13769a57cef0d8feef861b1f762fa4 100644 --- a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml @@ -177,7 +177,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 1 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 1 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 1 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: PowerLaw # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_power_law_norm_p_Msun: 0.0012 # Normalization of the SNIa delay time distribution (in Msun^-1). @@ -214,8 +215,10 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. use_variable_delta_T: 0 # Switch to enable adaptive calculation of AGN dT [1], rather than using a constant value [0]. AGN_with_locally_adaptive_delta_T: 0 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 1 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml index 8894944c4c1910bd410ef1a79ff4b23b1f54ba3c..03243c303cc16d9bcde8b8f57ef8d09ce24ee08f 100644 --- a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml @@ -168,7 +168,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 1 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 1 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 1 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: PowerLaw # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_power_law_norm_p_Msun: 0.0012 # Normalization of the SNIa delay time distribution (in Msun^-1). @@ -205,8 +206,10 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. use_variable_delta_T: 0 # Switch to enable adaptive calculation of AGN dT [1], rather than using a constant value [0]. AGN_with_locally_adaptive_delta_T: 0 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 1 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml index 9f59343e4f0820024b4b2ec3348131dc9ee99ab5..254b92d6b377a77f9babe90a053520add0f24366 100644 --- a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml +++ b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml @@ -180,7 +180,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 1 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 1 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 1 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: PowerLaw # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_power_law_norm_p_Msun: 0.0012 # Normalization of the SNIa delay time distribution (in Msun^-1). @@ -217,8 +218,10 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. use_variable_delta_T: 0 # Switch to enable adaptive calculation of AGN dT [1], rather than using a constant value [0]. AGN_with_locally_adaptive_delta_T: 0 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). - AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0). - AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (only used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1). + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold. + AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event (only used if AGN_use_adaptive_energy_reservoir_threshold is 0). max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. with_reposition_velocity_threshold: 1 # Should we only reposition to particles that move slowly w.r.t. the black hole? diff --git a/examples/HydroTests/BlobTest_3D/makeMovie.py b/examples/HydroTests/BlobTest_3D/makeMovie.py index 55acdaab01e22ecf8bae0dd24967a348ceabf34b..c8bd1c68eae7fbaa5ede0d79c701da0b3d9eb7ca 100644 --- a/examples/HydroTests/BlobTest_3D/makeMovie.py +++ b/examples/HydroTests/BlobTest_3D/makeMovie.py @@ -50,7 +50,10 @@ def get_image(n): masked_x = x[mask] - np.float64(box) masked_y = y[mask] - hsml = data.gas.smoothing_length.value[mask] + try: + hsml = data.gas.smoothing_length.value[mask] + except: + hsml = data.gas.smoothing_lengths.value[mask] if plot == "density": mass = data.gas.masses.value[mask] @@ -166,4 +169,4 @@ animation = FuncAnimation( fig, animate, range(start_frame - info_frames, end_frame), interval=40 ) -animation.save("blob.mp4") +animation.save(filename="blob.mp4") diff --git a/examples/HydroTests/BlobTest_3D/makeSliceMovie.py b/examples/HydroTests/BlobTest_3D/makeSliceMovie.py index 726c4ac01b9ae5b046a8bb3b6c1b9206764907bb..4c84ae0182a896263dd6f910f00d41e02809e82e 100644 --- a/examples/HydroTests/BlobTest_3D/makeSliceMovie.py +++ b/examples/HydroTests/BlobTest_3D/makeSliceMovie.py @@ -51,7 +51,10 @@ def get_image(n): masked_y = y[mask] masked_z = z[mask] - hsml = data.gas.smoothing_length.value[mask] + try: + hsml = data.gas.smoothing_length.value[mask] + except: + hsml = data.gas.smoothing_lengths.value[mask] if plot == "density": mass = data.gas.masses.value[mask] @@ -187,4 +190,4 @@ animation = FuncAnimation( fig, animate, range(start_frame - info_frames, end_frame), interval=40 ) -animation.save("blob_slice.mp4") +animation.save(filename="blob_slice.mp4") diff --git a/examples/HydroTests/BlobTest_3D/run.sh b/examples/HydroTests/BlobTest_3D/run.sh index b59594227ceee4f95db133665381acee2f7efbcf..94aa5ba7bc3afe7aff84ad62e448d1f346848a2c 100755 --- a/examples/HydroTests/BlobTest_3D/run.sh +++ b/examples/HydroTests/BlobTest_3D/run.sh @@ -3,8 +3,8 @@ # Generate the initial conditions if they are not present. if [ ! -e blob.hdf5 ] then - echo "Generating initial conditions for the Sod shock example..." - python makeIC.py + echo "Generating initial conditions for the 'blob test'..." + python3 makeIC.py fi # Run SWIFT diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml index d3fdce0562b536958683664454b99f1b7456a045..17c87266c646b9a1b4e866210e0f911ccae4cd90 100644 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml @@ -158,7 +158,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 1.4588 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_fraction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compuote f_E or at feedback time? SNIa_DTD: Exponential # Functional form of the SNIa delay time distribution. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_exp_timescale_Gyr: 2.0 # Time-scale of the exponential decay of the SNIa rates in Gyr. diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh index d64639e1d51465ce0326d0858db030e723da2648..c040e9b1989f42136bca6c1f7e0899e24d4846b2 100755 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_sink/run.sh @@ -14,4 +14,4 @@ then ./getIC.sh $filename fi -../../swift --hydro --sinks --external-gravity --self-gravity --threads=1 isolated_galaxy.yml 2>&1 | tee output.log +../../swift --hydro --sinks --external-gravity --self-gravity --threads=8 isolated_galaxy.yml 2>&1 | tee output.log diff --git a/examples/SubgridTests/BlackHoleSwallowing/swallowing.yml b/examples/SubgridTests/BlackHoleSwallowing/swallowing.yml index 69d5d529e6ae920e6849d6b9cc600db6674abf47..73b24e8348f64e18bc69293b451c68c400589bdb 100644 --- a/examples/SubgridTests/BlackHoleSwallowing/swallowing.yml +++ b/examples/SubgridTests/BlackHoleSwallowing/swallowing.yml @@ -43,7 +43,6 @@ Gravity: max_physical_DM_softening: 0.001300 # Physical softening for DM (1.30 pkpc) comoving_baryon_softening: 0.001790 # Comoving softening for baryons (1.79 ckpc) max_physical_baryon_softening: 0.000700 # Physical softening for baryons (0.70 pkpc) - dithering: 0 # Parameters for the hydrodynamics scheme SPH: diff --git a/examples/main.c b/examples/main.c index 51cabd7132d25ffd01b395a56e008a66e2758eca..e394b32a2d04e770509c2bc4d8d0af9d457dbd39 100644 --- a/examples/main.c +++ b/examples/main.c @@ -1601,7 +1601,7 @@ int main(int argc, char *argv[]) { } /* Write final output. */ - if (!force_stop) { + if (!force_stop && nsteps == 0) { /* Move forward in time */ e.ti_old = e.ti_current; diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 43dce9198cf8ddf1fd06b3a5e30c94c3f8967388..88915accb686370f78afa64819518a6feca4f8ce 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -87,8 +87,6 @@ Gravity: a_smooth: 1.25 # (Optional) Smoothing scale in top-level cell sizes to smooth the long-range forces over (this is the default value). r_cut_max: 4.5 # (Optional) Cut-off in number of top-level cells beyond which no FMM forces are computed (this is the default value). r_cut_min: 0.1 # (Optional) Cut-off in number of top-level cells below which no truncation of FMM forces are performed (this is the default value). - dithering: 0 # (Optional) Activate the dithering of the gravity mesh at every rebuild (this is the default value). - dithering_ratio: 1.0 # (Optional) Magnitude of each component of the dithering vector in units of the top-level cell sizes (this is the default value). # Parameters when running with SWIFT_GRAVITY_FORCE_CHECKS ForceChecks: @@ -185,6 +183,8 @@ InitialConditions: cleanup_velocity_factors: 0 # (Optional) Clean up the scale-factors used in the definition of the velocity variable in the ICs (e.g. in Gadget files). cleanup_smoothing_lengths: 0 # (Optional) Clean the values of the smoothing lengths that are read in to remove stupid values. Set to 1 to activate. smoothing_length_scaling: 1. # (Optional) A scaling factor to apply to all smoothing lengths in the ICs. + stars_smoothing_length: -1. # (Optional) Set the smoothing length of all the stars to this value (disabled by default). + black_holes_smoothing_length: -1. # (Optional) Set the smoothing length of all the black hole to this value (disabled by default). shift: [0.0,0.0,0.0] # (Optional) A shift to apply to all particles read from the ICs (in internal units). replicate: 2 # (Optional) Replicate all particles along each axis a given integer number of times. Default 1. remap_ids: 0 # (Optional) Remap all the particle IDs to the range [1, NumPart]. @@ -512,7 +512,8 @@ EAGLEFeedback: SNII_energy_fraction_n_0_H_p_cm3: 0.67 # Pivot point for the birth density dependance of the SNII energy fraction in cm^-3. SNII_energy_fraction_n_Z: 0.8686 # Power-law for the metallicity dependance of the SNII energy fraction. SNII_energy_fraction_n_n: 0.8686 # Power-law for the birth density dependance of the SNII energy fraction. - SNII_energy_faction_use_birth_props: 0 # Are we using the density and metallicity at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_density: 0 # Are we using the density at birth to compute f_E or at feedback time? + SNII_energy_fraction_use_birth_metallicity: 0 # Are we using the metallicity at birth to compute f_E or at feedback time? SNIa_DTD: PowerLaw # Functional form of the SNIa delay time distribution Two choices: 'PowerLaw' or 'Exponential'. SNIa_DTD_delay_Gyr: 0.04 # Stellar age after which SNIa start in Gyr (40 Myr corresponds to stars ~ 8 Msun). SNIa_DTD_power_law_norm_p_Msun: 0.0012 # Normalization of the SNIa delay time distribution in the power-law DTD case (in Msun^-1). @@ -564,6 +565,20 @@ EAGLEAGN: min_gas_mass_for_nibbling: 9e5 # Minimum mass for a gas particle to be nibbled from [M_Sun]. Only used if use_nibbling is 1. 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. + use_variable_delta_T: 1 # Switch to enable adaptive calculation of AGN dT [1], rather than using a constant value [0]. + AGN_with_locally_adaptive_delta_T: 1 # Switch to enable additional dependence of AGN dT on local gas density and temperature (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_norm: 3e8 # Normalisation temperature of AGN dT scaling with BH subgrid mass [K] (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_reference: 1e8 # BH subgrid mass at which the normalisation temperature set above applies [M_Sun] (only used if use_variable_delta_T is 1). + AGN_delta_T_mass_exponent: 0.666667 # Power-law index of AGN dT scaling with BH subgrid mass (only used if use_variable_delta_T is 1). + AGN_delta_T_crit_factor: 1.0 # Multiple of critical dT for numerical efficiency (Dalla Vecchia & Schaye 2012) to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). + AGN_delta_T_background_factor: 0.0 # Multiple of local gas temperature to use as dT floor (only used if use_variable_delta_T and AGN_with_locally_adaptive_delta_T are both 1). + AGN_delta_T_min: 1e7 # Minimum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). + AGN_delta_T_max: 3e9 # Maximum allowed value of AGN dT [K] (only used if use_variable_delta_T is 1). + AGN_use_nheat_with_fixed_dT: 0 # Switch to use the constant AGN dT, rather than the adaptive one, for calculating the energy reservoir threshold (only used if use_variable_delta_T is 1). + AGN_use_adaptive_energy_reservoir_threshold: 0 # Switch to calculate an adaptive AGN energy reservoir threshold. + AGN_nheat_alpha: -1.0 # Number of particles to be heatable in a feedback event, at the reference accretion rate (only used if AGN_use_adaptive_energy_reservoir_threshold is 1). + AGN_nheat_maccr_normalisation: -1.0 # Reference accretion rate for energy reservoir threshold [M_sun / yr] (only used if AGN_use_adaptive_energy_reservoir_threshold is 1). + AGN_nheat_limit: -1.0 # Hard limit for the energy reservoir threshold; above the reference accretion rate, it exponentially tapers off towards this (only used if AGN_use_adaptive_energy_reservoir_threshold is 1). 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. max_reposition_distance_ratio: 3.0 # Maximal distance a BH can be repositioned, in units of the softening length. @@ -571,8 +586,11 @@ EAGLEAGN: max_reposition_velocity_ratio: 0.5 # Maximal velocity offset of a particle to reposition a BH to, in units of the ambient sound speed of the BH. Only meaningful if with_reposition_velocity_ratio is 1. min_reposition_velocity_threshold: -1.0 # Minimal value of the velocity threshold for repositioning [km/s], set to < 0 for no effect. Only meaningful if with_reposition_velocity_ratio is 1. set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? - reposition_coefficient_upsilon: 0.0001 # Repositioning speed normalisation [km/s/M_sun]. Only meaningful if set_reposition_speed is 1. - reposition_exponent_xi: 1.0 # (Optional) Scaling of repositioning velocity with BH subgrid mass (default: 1.0, linear). Only meaningful if set_reposition_speed is 1. + reposition_coefficient_upsilon: 50.0 # Repositioning speed normalisation [km/s/M_sun]. Only meaningful if set_reposition_speed is 1. + reposition_reference_mass: 1e5 # Reference mass for scaling of reposition speed [M_sun]. Only meaningful if set_reposition_speed is 1. + reposition_exponent_mass: 2.0 # (Optional) Exponent for scaling of repositioning velocity with BH mass; default = 2.0. Only meaningful if set_reposition_speed is 1. + reposition_reference_n_H: 1.0 # Reference gas density around the black holes for scaling of repositioning speed [N_H cm^-3]. Only meaningful if set_reposition_speed is 1. + reposition_exponent_n_H: 1.0 # (Optional) Exponent for scaling of repositioning velocity with gas density; default = 1.0. Only meaningful if set_reposition_speed is 1. threshold_major_merger: 0.333 # Mass ratio threshold to consider a BH merger as 'major' threshold_minor_merger: 0.1 # Mass ratio threshold to consider a BH merger as 'minor' merger_threshold_type: 2 # Type of velocity threshold for BH mergers (0: v_circ at kernel edge, 1: v_esc at actual distance, with softening, 2: v_esc at actual distance, no softening). diff --git a/logger/logger_hydro.h b/logger/logger_hydro.h index dc9cc4e581f2f2c309a3da65dbcb507a8d81e92a..f9729c55c4bc1e7b6b85e0977a517a23d80305d3 100644 --- a/logger/logger_hydro.h +++ b/logger/logger_hydro.h @@ -37,9 +37,9 @@ #elif defined(HOPKINS_PU_SPH_MONAGHAN) #error TODO #include "./hydro/PressureEnergyMorrisMonaghanAV/logger_hydro.h" -#elif defined(DEFAULT_SPH) +#elif defined(PHANTOM_SPH) #error TODO -#include "./hydro/Default/logger_hydro.h" +#include "./hydro/Phantom/logger_hydro.h" #elif defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH) #error TODO #include "./hydro/Gizmo/logger_hydro.h" diff --git a/src/Makefile.am b/src/Makefile.am index 253b86fcd3f823e664d0cb724656f18d5048d8c1..b03ee5ec42d3061c8594f27276e93248142697be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -102,7 +102,7 @@ endif AM_SOURCES = space.c runner_main.c runner_doiact_hydro.c runner_doiact_limiter.c \ runner_doiact_stars.c runner_doiact_black_holes.c runner_ghost.c runner_recv.c \ runner_sort.c runner_drift.c runner_black_holes.c runner_time_integration.c \ - runner_doiact_hydro_vec.c runner_others.c \ + runner_doiact_hydro_vec.c runner_others.c runner_doiact_sinks.c \ runner_doiact_rt.c\ queue.c task.c cell.c engine.c engine_maketasks.c engine_split_particles.c \ engine_marktasks.c engine_drift.c engine_unskip.c engine_collect_end_of_step.c \ @@ -128,14 +128,12 @@ nobase_noinst_HEADERS += gravity_iact.h kernel_long_gravity.h vector.h accumulat nobase_noinst_HEADERS += runner_doiact_nosort.h runner_doiact_hydro.h runner_doiact_stars.h runner_doiact_black_holes.h runner_doiact_grav.h nobase_noinst_HEADERS += runner_doiact_functions_hydro.h runner_doiact_functions_stars.h runner_doiact_functions_black_holes.h nobase_noinst_HEADERS += runner_doiact_functions_limiter.h runner_doiact_limiter.h units.h intrinsics.h minmax.h -nobase_noinst_HEADERS += runner_doiact_rt.h runner_doiact_functions_rt.h +nobase_noinst_HEADERS += runner_doiact_rt.h runner_doiact_functions_rt.h runner_doiact_sinks.h nobase_noinst_HEADERS += kick.h timestep.h drift.h adiabatic_index.h io_properties.h dimension.h part_type.h periodic.h memswap.h nobase_noinst_HEADERS += timestep_limiter.h timestep_limiter_iact.h timestep_sync.h timestep_sync_part.h timestep_limiter_struct.h nobase_noinst_HEADERS += dump.h logger.h sign.h logger_io.h hashmap.h gravity.h gravity_io.h gravity_logger.h gravity_cache.h output_options.h nobase_noinst_HEADERS += gravity/Default/gravity.h gravity/Default/gravity_iact.h gravity/Default/gravity_io.h nobase_noinst_HEADERS += gravity/Default/gravity_debug.h gravity/Default/gravity_part.h -nobase_noinst_HEADERS += gravity/Potential/gravity.h gravity/Potential/gravity_iact.h gravity/Potential/gravity_io.h -nobase_noinst_HEADERS += gravity/Potential/gravity_debug.h gravity/Potential/gravity_part.h nobase_noinst_HEADERS += gravity/MultiSoftening/gravity.h gravity/MultiSoftening/gravity_iact.h gravity/MultiSoftening/gravity_io.h nobase_noinst_HEADERS += gravity/MultiSoftening/gravity_debug.h gravity/MultiSoftening/gravity_part.h nobase_noinst_HEADERS += gravity/MultiSoftening/gravity_logger.h @@ -145,9 +143,9 @@ nobase_noinst_HEADERS += hydro.h hydro_io.h hydro_logger.h hydro_parameters.h nobase_noinst_HEADERS += hydro/Minimal/hydro.h hydro/Minimal/hydro_iact.h hydro/Minimal/hydro_io.h nobase_noinst_HEADERS += hydro/Minimal/hydro_debug.h hydro/Minimal/hydro_part.h nobase_noinst_HEADERS += hydro/Minimal/hydro_parameters.h -nobase_noinst_HEADERS += hydro/Default/hydro.h hydro/Default/hydro_iact.h hydro/Default/hydro_io.h -nobase_noinst_HEADERS += hydro/Default/hydro_debug.h hydro/Default/hydro_part.h -nobase_noinst_HEADERS += hydro/Default/hydro_parameters.h +nobase_noinst_HEADERS += hydro/Phantom/hydro.h hydro/Phantom/hydro_iact.h hydro/Phantom/hydro_io.h +nobase_noinst_HEADERS += hydro/Phantom/hydro_debug.h hydro/Phantom/hydro_part.h +nobase_noinst_HEADERS += hydro/Phantom/hydro_parameters.h nobase_noinst_HEADERS += hydro/Gadget2/hydro.h hydro/Gadget2/hydro_iact.h hydro/Gadget2/hydro_io.h nobase_noinst_HEADERS += hydro/Gadget2/hydro_debug.h hydro/Gadget2/hydro_part.h nobase_noinst_HEADERS += hydro/Gadget2/hydro_parameters.h hydro/Gadget2/hydro_logger.h @@ -314,7 +312,8 @@ nobase_noinst_HEADERS += pressure_floor/GEAR/pressure_floor.h pressure_floor/non nobase_noinst_HEADERS += pressure_floor/GEAR/pressure_floor_iact.h pressure_floor/none/pressure_floor_iact.h nobase_noinst_HEADERS += pressure_floor/GEAR/pressure_floor_struct.h pressure_floor/none/pressure_floor_struct.h nobase_noinst_HEADERS += sink/Default/sink.h sink/Default/sink_io.h sink/Default/sink_part.h sink/Default/sink_properties.h -nobase_noinst_HEADERS += sink.h sink_io.h sink_properties.h +nobase_noinst_HEADERS += sink/Default/sink_iact.h +nobase_noinst_HEADERS += sink.h sink_io.h sink_properties.h runner_doiact_functions_sinks.h # Sources and special flags for the gravity library diff --git a/src/black_holes/Default/black_holes.h b/src/black_holes/Default/black_holes.h index be6f039e980f7c2abd0bb8f4e43a037b60c22ce4..726d9e0db2d8ad7d709535cf22184cd569ca14a7 100644 --- a/src/black_holes/Default/black_holes.h +++ b/src/black_holes/Default/black_holes.h @@ -144,6 +144,30 @@ black_holes_bpart_has_no_neighbours(struct bpart* restrict bp, bp->density.wcount_dh = 0.f; } +/** + * @brief Return the current instantaneous accretion rate of the BH. + * + * Empty BH model --> return 0. + * + * @param bp the #bpart. + */ +__attribute__((always_inline)) INLINE static double +black_holes_get_accretion_rate(const struct bpart* bp) { + return 0.; +} + +/** + * @brief Return the total accreted gas mass of this BH. + * + * Empty BH model --> return 0. + * + * @param bp the #bpart. + */ +__attribute__((always_inline)) INLINE static double +black_holes_get_accreted_mass(const struct bpart* bp) { + return 0.; +} + /** * @brief Update the properties of a black hole particles by swallowing * a gas particle. diff --git a/src/black_holes/Default/black_holes_io.h b/src/black_holes/Default/black_holes_io.h index 6ca174b7fef2545af0f3191bba3037ed2b31805a..28f6c3964cb185700a7c9309a42d774b4d78eab3 100644 --- a/src/black_holes/Default/black_holes_io.h +++ b/src/black_holes/Default/black_holes_io.h @@ -54,9 +54,9 @@ INLINE static void convert_bpart_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(bp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(bp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(bp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(bp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(bp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(bp->x[2], 0.0, s->dim[2]); } else { ret[0] = bp->x[0]; ret[1] = bp->x[1]; diff --git a/src/black_holes/EAGLE/black_holes.h b/src/black_holes/EAGLE/black_holes.h index f0d78c04ce8871c2c15d5434fa661d95793b0f17..13483ec4ad048a7dd920c5142d3f25cbc57f66bf 100644 --- a/src/black_holes/EAGLE/black_holes.h +++ b/src/black_holes/EAGLE/black_holes.h @@ -69,7 +69,7 @@ __attribute__((always_inline)) INLINE static float black_holes_compute_timestep( * rate. The time is multiplied by the number of Ngbs to heat because * if more particles are heated at once then the time between different * AGN feedback events increases proportionally. */ - const double dt_heat = E_heat * props->num_ngbs_to_heat / Energy_rate; + const double dt_heat = E_heat * bp->num_ngbs_to_heat / Energy_rate; /* The new timestep of the BH cannot be smaller than the miminum allowed * time-step */ @@ -125,6 +125,8 @@ __attribute__((always_inline)) INLINE static void black_holes_first_init_bpart( bp->accreted_angular_momentum[0] = 0.f; bp->accreted_angular_momentum[1] = 0.f; bp->accreted_angular_momentum[2] = 0.f; + bp->last_repos_vel = 0.f; + bp->num_ngbs_to_heat = props->num_ngbs_to_heat; /* Filler value */ black_holes_mark_bpart_as_not_swallowed(&bp->merger_data); } @@ -165,6 +167,7 @@ __attribute__((always_inline)) INLINE static void black_holes_init_bpart( bp->reposition.potential = FLT_MAX; bp->accretion_rate = 0.f; /* Optionally accumulated ngb-by-ngb */ bp->f_visc = FLT_MAX; + bp->accretion_boost_factor = -FLT_MAX; bp->mass_at_start_of_step = bp->mass; /* bp->mass may grow in nibbling mode */ } @@ -304,6 +307,28 @@ black_holes_bpart_has_no_neighbours(struct bpart* bp, bp->velocity_gas[0] = FLT_MAX; bp->velocity_gas[1] = FLT_MAX; bp->velocity_gas[2] = FLT_MAX; + + bp->internal_energy_gas = -FLT_MAX; +} + +/** + * @brief Return the current instantaneous accretion rate of the BH. + * + * @param bp the #bpart. + */ +__attribute__((always_inline)) INLINE static double +black_holes_get_accretion_rate(const struct bpart* bp) { + return bp->accretion_rate; +} + +/** + * @brief Return the total accreted gas mass of this BH. + * + * @param bp the #bpart. + */ +__attribute__((always_inline)) INLINE static double +black_holes_get_accreted_mass(const struct bpart* bp) { + return bp->total_accreted_mass; } /** @@ -518,6 +543,37 @@ __attribute__((always_inline)) INLINE static double black_hole_feedback_delta_T( return min(delta_T, props->AGN_delta_T_max); } +/** + * @brief Computes the energy reservoir threshold for AGN feedback. + * + * If adaptive, this is proportional to the accretion rate, with an + * asymptotic upper limit. + * + * @param bp The #bpart. + * @param props The properties of the black hole model. + */ +__attribute__((always_inline)) INLINE static double +black_hole_energy_reservoir_threshold(struct bpart* bp, + const struct black_holes_props* props) { + + /* If we want a constant threshold, this is short and sweet. */ + if (!props->use_adaptive_energy_reservoir_threshold) + return props->num_ngbs_to_heat; + + double num_to_heat = props->nheat_alpha * + (bp->accretion_rate / props->nheat_maccr_normalisation); + + /* Impose smooth truncation of num_to_heat towards props->nheat_limit */ + if (num_to_heat > props->nheat_alpha) { + const double coeff_b = 1. / (props->nheat_limit - props->nheat_alpha); + const double coeff_a = exp(coeff_b * props->nheat_alpha) / coeff_b; + num_to_heat = props->nheat_limit - coeff_a * exp(-coeff_b * num_to_heat); + } + + bp->num_ngbs_to_heat = num_to_heat; + return num_to_heat; +} + /** * @brief Compute the accretion rate of the black hole and all the quantites * required for the feedback loop. @@ -555,7 +611,6 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( const double f_Edd_recording = props->f_Edd_recording; const double epsilon_r = props->epsilon_r; const double epsilon_f = props->epsilon_f; - const double num_ngbs_to_heat = props->num_ngbs_to_heat; const int with_angmom_limiter = props->with_angmom_limiter; /* (Subgrid) mass of the BH (internal units) */ @@ -700,8 +755,13 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( const double n_H = gas_rho_phys * XH / proton_mass; const double boost_ratio = n_H / props->boost_n_h_star; const double boost_factor = - max(pow(boost_ratio, props->boost_beta), props->boost_alpha); + (props->boost_alpha_only) + ? max(pow(boost_ratio, props->boost_beta), props->boost_alpha) + : props->boost_alpha; Bondi_rate *= boost_factor; + bp->accretion_boost_factor = boost_factor; + } else { + bp->accretion_boost_factor = 1.; } /* Compute the reduction factor from Rosas-Guevara et al. (2015) */ @@ -740,6 +800,7 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( /* Limit the accretion rate to a fraction of the Eddington rate */ const double accr_rate = min(Bondi_rate, f_Edd * Eddington_rate); bp->accretion_rate = accr_rate; + bp->eddington_fraction = Bondi_rate / Eddington_rate; /* Factor in the radiative efficiency */ const double mass_rate = (1. - epsilon_r) * accr_rate; @@ -763,10 +824,9 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( } /* Increase the subgrid angular momentum according to what we accreted - * Note that this is already in physical units, a factors from velocity and r - * adius cancel each others. - * Also, the circular velocity contains an extra smoothing length factor that - * we undo here. */ + * Note that this is already in physical units, a factors from velocity and + * radius cancel each other. Also, the circular velocity contains an extra + * smoothing length factor that we undo here. */ bp->accreted_angular_momentum[0] += bp->circular_velocity_gas[0] * mass_rate * dt / bp->h; bp->accreted_angular_momentum[1] += @@ -778,12 +838,19 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( const double delta_T = black_hole_feedback_delta_T(bp, props, cosmo); bp->AGN_delta_T = delta_T; const double delta_u = delta_T * props->temp_to_u_factor; - - /* Energy required to have a feedback event - * Note that we have subtracted the particles we swallowed from the ngb_mass - * and num_ngbs accumulators. */ + const double delta_u_ref = + props->AGN_use_nheat_with_fixed_dT + ? props->AGN_delta_T_desired * props->temp_to_u_factor + : delta_u; + + /* Energy required to have a feedback event. + * Note that we have subtracted particles we may have swallowed from the + * ngb_mass and num_ngbs accumulators already. */ + const double num_ngbs_to_heat = + black_hole_energy_reservoir_threshold(bp, props); const double mean_ngb_mass = bp->ngb_mass / ((double)bp->num_ngbs); - const double E_feedback_event = num_ngbs_to_heat * delta_u * mean_ngb_mass; + const double E_feedback_event = + num_ngbs_to_heat * delta_u_ref * mean_ngb_mass; /* Are we doing some feedback? */ if (bp->energy_reservoir > E_feedback_event) { @@ -826,6 +893,40 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( } } +/** + * @brief Computes the (maximal) repositioning speed for a black hole. + * + * Calculated as upsilon * (m_BH / m_ref) ^ beta_m * (n_H_BH / n_ref) ^ beta_n + * where m_BH = BH subgrid mass, n_H_BH = physical gas density around BH + * and upsilon, m_ref, beta_m, n_ref, and beta_n are parameters. + * + * @param bp The #bpart. + * @param props The properties of the black hole model. + * @param cosmo The current cosmological model. + */ +__attribute__((always_inline)) INLINE static double +black_holes_get_repositioning_speed(const struct bpart* restrict bp, + const struct black_holes_props* props, + const struct cosmology* cosmo) { + + const double n_gas_phys = bp->rho_gas * cosmo->a3_inv * props->rho_to_n_cgs; + const double v_repos = + props->reposition_coefficient_upsilon * + pow(bp->subgrid_mass / props->reposition_reference_mass, + props->reposition_exponent_mass) * + pow(n_gas_phys / props->reposition_reference_n_H, + props->reposition_exponent_n_H); + + /* Make sure the repositioning is not back-firing... */ + if (v_repos < 0) + error( + "BH %lld wants to reposition at negative speed (%g U_V). Do you " + "think you are being funny? No-one is laughing.", + bp->id, v_repos); + + return v_repos; +} + /** * @brief Finish the calculation of the new BH position. * @@ -863,21 +964,17 @@ __attribute__((always_inline)) INLINE static void black_holes_end_reposition( } else if (props->set_reposition_speed) { /* If we are re-positioning, move the BH a fraction of delta_x, so - * that we have a well-defined re-positioning velocity. We have - * checked already that reposition_coefficient_upsilon is positive. */ - const float repos_vel = - props->reposition_coefficient_upsilon * - pow(bp->subgrid_mass / constants->const_solar_mass, - props->reposition_exponent_xi); + * that we have a well-defined re-positioning velocity (repos_vel + * cannot be negative). */ + double repos_vel = black_holes_get_repositioning_speed(bp, props, cosmo); + /* Convert target reposition velocity to a fractional reposition + * along reposition.delta_x */ const double dx = bp->reposition.delta_x[0]; const double dy = bp->reposition.delta_x[1]; const double dz = bp->reposition.delta_x[2]; const double d = sqrt(dx * dx + dy * dy + dz * dz); - /* Convert target reposition velocity to a fractional reposition - * along reposition.delta_x */ - /* Exclude the pathological case of repositioning by zero distance */ if (d > 0) { double repos_frac = repos_vel * dt / d; @@ -889,8 +986,12 @@ __attribute__((always_inline)) INLINE static void black_holes_end_reposition( /* ... but fractions > 1 can occur if the target velocity is high. * We do not want this, because it could lead to overshooting the * actual potential minimum. */ - if (repos_frac > 1) repos_frac = 1.; + if (repos_frac > 1) { + repos_frac = 1.; + repos_vel = repos_frac * d / dt; + } + bp->last_repos_vel = (float)repos_vel; bp->reposition.delta_x[0] *= repos_frac; bp->reposition.delta_x[1] *= repos_frac; bp->reposition.delta_x[2] *= repos_frac; @@ -984,9 +1085,13 @@ INLINE static void black_holes_create_from_gas( bp->number_of_direct_gas_swallows = 0; bp->number_of_time_steps = 0; + /* Initialise the energy reservoir threshold to the constant default */ + bp->num_ngbs_to_heat = props->num_ngbs_to_heat; /* Filler value */ + /* We haven't repositioned yet, nor attempted it */ bp->number_of_repositions = 0; bp->number_of_reposition_attempts = 0; + bp->last_repos_vel = 0.f; /* Initial metal masses */ const float gas_mass = hydro_get_mass(p); diff --git a/src/black_holes/EAGLE/black_holes_iact.h b/src/black_holes/EAGLE/black_holes_iact.h index cd4678d0e8481afce22db287ce44f9895add649c..4f060428ae6f926be2e4d614b5b90fc5caa68e30 100644 --- a/src/black_holes/EAGLE/black_holes_iact.h +++ b/src/black_holes/EAGLE/black_holes_iact.h @@ -81,11 +81,9 @@ runner_iact_nonsym_bh_gas_density( /* Contribution to the total neighbour mass */ bi->ngb_mass += mj; - /* Neighbour sound speed */ - const float cj = hydro_get_comoving_soundspeed(pj); - /* Contribution to the smoothed sound speed */ - bi->sound_speed_gas += mj * cj * wi; + const float cj = hydro_get_comoving_soundspeed(pj); + bi->sound_speed_gas += mj * wi * cj; /* Neighbour internal energy */ const float uj = hydro_get_drifted_comoving_internal_energy(pj); diff --git a/src/black_holes/EAGLE/black_holes_io.h b/src/black_holes/EAGLE/black_holes_io.h index 370d3579b6b37479f39994234d14d2fafd65ed33..2ad9232d2756e4f6ff9900e969063510f89fb680 100644 --- a/src/black_holes/EAGLE/black_holes_io.h +++ b/src/black_holes/EAGLE/black_holes_io.h @@ -21,6 +21,7 @@ #include "adiabatic_index.h" #include "black_holes_part.h" +#include "black_holes_properties.h" #include "io_properties.h" /** @@ -59,9 +60,9 @@ INLINE static void convert_bpart_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(bp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(bp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(bp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(bp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(bp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(bp->x[2], 0.0, s->dim[2]); } else { ret[0] = bp->x[0]; ret[1] = bp->x[1]; @@ -125,6 +126,18 @@ INLINE static void convert_bpart_gas_circular_vel(const struct engine* e, ret[2] = bp->circular_velocity_gas[2] * cosmo->a_inv; } +INLINE static void convert_bpart_gas_temperatures(const struct engine* e, + const struct bpart* bp, + float* ret) { + + const struct black_holes_props* props = e->black_holes_properties; + const struct cosmology* cosmo = e->cosmology; + + /* Conversion from specific internal energy to temperature */ + ret[0] = bp->internal_energy_gas * cosmo->a_factor_internal_energy / + props->temp_to_u_factor; +} + /** * @brief Specifies which b-particle fields to write to a dataset * @@ -139,7 +152,7 @@ INLINE static void black_holes_write_particles(const struct bpart* bparts, int with_cosmology) { /* Say how much we want to write */ - *num_fields = 33; + *num_fields = 38; /* List what we want to write */ list[0] = io_make_output_field_convert_bpart( @@ -353,6 +366,39 @@ INLINE static void black_holes_write_particles(const struct bpart* bparts, "Temperature by which gas particles have been heated by the black hole " "particles in the most recent feedback event."); + list[33] = io_make_output_field( + "LastRepositionVelocities", FLOAT, 1, UNIT_CONV_SPEED, 0.f, bparts, + last_repos_vel, + "Physical speeds at which the black holes repositioned most recently. " + "This is 0 for black holes that have never repositioned, or if the " + "simulation has been run without prescribed repositioning speed."); + + list[34] = io_make_output_field( + "AccretionBoostFactors", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, bparts, + accretion_boost_factor, + "Multiplicative factors by which the Bondi-Hoyle-Lyttleton accretion " + "rates have been increased by the density-dependent Booth & Schaye " + "(2009) accretion model."); + + list[35] = io_make_output_field_convert_bpart( + "GasTemperatures", FLOAT, 1, UNIT_CONV_TEMPERATURE, 0.f, bparts, + convert_bpart_gas_temperatures, + "Temperature of the gas surrounding the black holes."); + + list[36] = io_make_output_field( + "EnergyReservoirThresholds", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, bparts, + num_ngbs_to_heat, + "Minimum energy reservoir required for the black holes to do feedback, " + "expressed in units of the (constant) target heating temperature " + "increase."); + + list[37] = io_make_output_field( + "EddingtonFractions", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, bparts, + eddington_fraction, + "Accretion rates of black holes in units of their Eddington rates. " + "This is based on the unlimited accretion rates, so these fractions " + "can be above the limiting fEdd."); + #ifdef DEBUG_INTERACTIONS_BLACK_HOLES list += *num_fields; diff --git a/src/black_holes/EAGLE/black_holes_part.h b/src/black_holes/EAGLE/black_holes_part.h index 95358284480caee5196108c9f2d3eb1d90c2fcd3..0be3e8fc86f81af77d103a8f88e674e95a89cb89 100644 --- a/src/black_holes/EAGLE/black_holes_part.h +++ b/src/black_holes/EAGLE/black_holes_part.h @@ -151,18 +151,30 @@ struct bpart { * lower potential than all eligible neighbours) */ int number_of_reposition_attempts; + /* Velocity of most recent reposition jump */ + float last_repos_vel; + /*! Total number of time steps in which the black hole was active. */ int number_of_time_steps; /*! Total (physical) angular momentum accumulated by swallowing particles */ float swallowed_angular_momentum[3]; + /*! Accretion boost factor */ + float accretion_boost_factor; + /*! Total (physical) angular momentum accumulated from subgrid accretion */ float accreted_angular_momentum[3]; /*! Instantaneous temperature increase for feedback */ float AGN_delta_T; + /*! Instantaneous energy reservoir threshold (num-to-heat) */ + float num_ngbs_to_heat; + + /*! Eddington fractions */ + float eddington_fraction; + /*! Union for the last high Eddington ratio point in time */ union { diff --git a/src/black_holes/EAGLE/black_holes_properties.h b/src/black_holes/EAGLE/black_holes_properties.h index b80edbc33a73410f8ad80a4d9ee82a53113c76c4..5060cad4ae950ecbac3b75beba73beb121ef999d 100644 --- a/src/black_holes/EAGLE/black_holes_properties.h +++ b/src/black_holes/EAGLE/black_holes_properties.h @@ -85,6 +85,9 @@ struct black_holes_props { /*! Switch for the Booth & Schaye 2009 model */ int with_boost_factor; + /*! Use constant-alpha version of Booth & Schaye (2009) model? */ + int boost_alpha_only; + /*! Lowest value of the boost of the Booth & Schaye 2009 model */ float boost_alpha; @@ -135,9 +138,24 @@ struct black_holes_props { float AGN_delta_T_max; float AGN_delta_T_min; + /*! Vary the energy reservoir according to the BH accretion rate? */ + int use_adaptive_energy_reservoir_threshold; + + /*! Normalisation for energy reservoir threshold, at upper end */ + float nheat_alpha; + + /*! Reference max accretion rate for energy reservoir variation */ + float nheat_maccr_normalisation; + + /*! Hard limit to the energy reservoir threshold */ + float nheat_limit; + /*! Number of gas neighbours to heat in a feedback event */ float num_ngbs_to_heat; + /*! Switch to make nheat use the constant dT as basis, not actual dT */ + int AGN_use_nheat_with_fixed_dT; + /* ---- Properties of the repositioning model --- */ /*! Maximal mass of BH to reposition */ @@ -163,8 +181,17 @@ struct black_holes_props { /*! Normalisation factor for repositioning velocity */ float reposition_coefficient_upsilon; + /*! Reference black hole mass for repositioning scaling */ + float reposition_reference_mass; + /*! Repositioning velocity scaling with black hole mass */ - float reposition_exponent_xi; + float reposition_exponent_mass; + + /*! Reference gas density for repositioning scaling */ + float reposition_reference_n_H; + + /*! Repositioning velocity scaling with gas density */ + float reposition_exponent_n_H; /* ---- Properties of the merger model ---------- */ @@ -295,14 +322,18 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, parser_get_param_int(params, "EAGLEAGN:with_boost_factor"); if (bp->with_boost_factor) { + bp->boost_alpha_only = + parser_get_param_int(params, "EAGLEAGN:boost_alpha_only"); bp->boost_alpha = parser_get_param_float(params, "EAGLEAGN:boost_alpha"); - bp->boost_beta = parser_get_param_float(params, "EAGLEAGN:boost_beta"); + if (!bp->boost_alpha_only) { + bp->boost_beta = parser_get_param_float(params, "EAGLEAGN:boost_beta"); - /* Load the density in cgs and convert to internal units */ - bp->boost_n_h_star = - parser_get_param_float(params, "EAGLEAGN:boost_n_h_star_H_p_cm3") / - units_cgs_conversion_factor(us, UNIT_CONV_NUMBER_DENSITY); + /* Load the density in cgs and convert to internal units */ + bp->boost_n_h_star = + parser_get_param_float(params, "EAGLEAGN:boost_n_h_star_H_p_cm3") / + units_cgs_conversion_factor(us, UNIT_CONV_NUMBER_DENSITY); + } } bp->use_nibbling = parser_get_param_int(params, "EAGLEAGN:use_nibbling"); @@ -345,20 +376,40 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, parser_get_param_float(params, "EAGLEAGN:AGN_delta_T_max") * T_K_to_int; bp->AGN_delta_T_min = parser_get_param_float(params, "EAGLEAGN:AGN_delta_T_min") * T_K_to_int; + bp->AGN_use_nheat_with_fixed_dT = + parser_get_param_int(params, "EAGLEAGN:AGN_use_nheat_with_fixed_dT"); + if (bp->AGN_use_nheat_with_fixed_dT) { + bp->AGN_delta_T_desired = + parser_get_param_float(params, "EAGLEAGN:AGN_delta_T_K"); + } + } else { bp->AGN_delta_T_desired = parser_get_param_float(params, "EAGLEAGN:AGN_delta_T_K"); } + bp->use_adaptive_energy_reservoir_threshold = parser_get_param_int( + params, "EAGLEAGN:AGN_use_adaptive_energy_reservoir_threshold"); + if (bp->use_adaptive_energy_reservoir_threshold) { + bp->nheat_alpha = + parser_get_param_float(params, "EAGLEAGN:AGN_nheat_alpha"); + bp->nheat_maccr_normalisation = + parser_get_param_float(params, + "EAGLEAGN:AGN_nheat_maccr_normalisation") * + phys_const->const_solar_mass / phys_const->const_year; + bp->nheat_limit = + parser_get_param_float(params, "EAGLEAGN:AGN_nheat_limit"); + } + + /* We must always read a default value to initialize BHs to */ 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; + parser_get_param_float(params, "EAGLEAGN:max_reposition_mass") * + phys_const->const_solar_mass; bp->max_reposition_distance_ratio = parser_get_param_float(params, "EAGLEAGN:max_reposition_distance_ratio"); @@ -399,8 +450,16 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, bp->reposition_coefficient_upsilon *= (1e5 / (us->UnitLength_in_cgs / us->UnitTime_in_cgs)); - bp->reposition_exponent_xi = parser_get_opt_param_float( - params, "EAGLEAGN:reposition_exponent_xi", 1.0); + /* Scaling parameters with BH mass and gas density */ + bp->reposition_reference_mass = + parser_get_param_float(params, "EAGLEAGN:reposition_reference_mass") * + phys_const->const_solar_mass; + bp->reposition_exponent_mass = parser_get_opt_param_float( + params, "EAGLEAGN:reposition_exponent_mass", 2.0); + bp->reposition_reference_n_H = + parser_get_param_float(params, "EAGLEAGN:reposition_reference_n_H"); + bp->reposition_exponent_n_H = parser_get_opt_param_float( + params, "EAGLEAGN:reposition_exponent_n_H", 1.0); } /* Merger parameters ------------------------------------- */ diff --git a/src/cell.c b/src/cell.c index 07f5f191d9ee2f188c6b06ed04037f2a6c214969..05220bd4149834d068f38626b3a9dcbe5dcc658f 100644 --- a/src/cell.c +++ b/src/cell.c @@ -540,21 +540,30 @@ int cell_pack(struct cell *restrict c, struct pcell *restrict pc, pc->hydro.h_max = c->hydro.h_max; pc->stars.h_max = c->stars.h_max; pc->black_holes.h_max = c->black_holes.h_max; + pc->sinks.r_cut_max = c->sinks.r_cut_max; + pc->hydro.ti_end_min = c->hydro.ti_end_min; pc->hydro.ti_end_max = c->hydro.ti_end_max; pc->grav.ti_end_min = c->grav.ti_end_min; pc->grav.ti_end_max = c->grav.ti_end_max; pc->stars.ti_end_min = c->stars.ti_end_min; pc->stars.ti_end_max = c->stars.ti_end_max; + pc->sinks.ti_end_min = c->sinks.ti_end_min; + pc->sinks.ti_end_max = c->sinks.ti_end_max; pc->black_holes.ti_end_min = c->black_holes.ti_end_min; pc->black_holes.ti_end_max = c->black_holes.ti_end_max; + pc->hydro.ti_old_part = c->hydro.ti_old_part; pc->grav.ti_old_part = c->grav.ti_old_part; pc->grav.ti_old_multipole = c->grav.ti_old_multipole; pc->stars.ti_old_part = c->stars.ti_old_part; + pc->black_holes.ti_old_part = c->black_holes.ti_old_part; + pc->sinks.ti_old_part = c->sinks.ti_old_part; + pc->hydro.count = c->hydro.count; pc->grav.count = c->grav.count; pc->stars.count = c->stars.count; + pc->sinks.count = c->sinks.count; pc->black_holes.count = c->black_holes.count; pc->maxdepth = c->maxdepth; @@ -693,6 +702,8 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c, c->hydro.h_max = pc->hydro.h_max; c->stars.h_max = pc->stars.h_max; c->black_holes.h_max = pc->black_holes.h_max; + c->sinks.r_cut_max = pc->sinks.r_cut_max; + c->hydro.ti_end_min = pc->hydro.ti_end_min; c->hydro.ti_end_max = pc->hydro.ti_end_max; c->grav.ti_end_min = pc->grav.ti_end_min; @@ -701,14 +712,20 @@ int cell_unpack(struct pcell *restrict pc, struct cell *restrict c, c->stars.ti_end_max = pc->stars.ti_end_max; c->black_holes.ti_end_min = pc->black_holes.ti_end_min; c->black_holes.ti_end_max = pc->black_holes.ti_end_max; + c->sinks.ti_end_min = pc->sinks.ti_end_min; + c->sinks.ti_end_max = pc->sinks.ti_end_max; + c->hydro.ti_old_part = pc->hydro.ti_old_part; c->grav.ti_old_part = pc->grav.ti_old_part; c->grav.ti_old_multipole = pc->grav.ti_old_multipole; c->stars.ti_old_part = pc->stars.ti_old_part; c->black_holes.ti_old_part = pc->black_holes.ti_old_part; + c->sinks.ti_old_part = pc->sinks.ti_old_part; + c->hydro.count = pc->hydro.count; c->grav.count = pc->grav.count; c->stars.count = pc->stars.count; + c->sinks.count = pc->sinks.count; c->black_holes.count = pc->black_holes.count; c->maxdepth = pc->maxdepth; @@ -1739,11 +1756,14 @@ void cell_bunlocktree(struct cell *c) { * @param sinkbuff A buffer with at least max(c->sinks.count, c->grav.count) * entries, used for sorting indices for the sinks. */ -void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, - ptrdiff_t bparts_offset, ptrdiff_t sinks_offset, - struct cell_buff *buff, struct cell_buff *sbuff, - struct cell_buff *bbuff, struct cell_buff *gbuff, - struct cell_buff *sinkbuff) { +void cell_split(struct cell *c, const ptrdiff_t parts_offset, + const ptrdiff_t sparts_offset, const ptrdiff_t bparts_offset, + const ptrdiff_t sinks_offset, struct cell_buff *restrict buff, + struct cell_buff *restrict sbuff, + struct cell_buff *restrict bbuff, + struct cell_buff *restrict gbuff, + struct cell_buff *restrict sinkbuff) { + const int count = c->hydro.count, gcount = c->grav.count, scount = c->stars.count, bcount = c->black_holes.count, sink_count = c->sinks.count; @@ -2102,7 +2122,7 @@ void cell_split(struct cell *c, ptrdiff_t parts_offset, ptrdiff_t sparts_offset, j++; bucket_count[bid]++; } - memswap(&gparts[j], &gpart, sizeof(struct gpart)); + memswap_unaligned(&gparts[j], &gpart, sizeof(struct gpart)); memswap(&gbuff[j], &temp_buff, sizeof(struct cell_buff)); if (gparts[j].type == swift_type_gas) { parts[-gparts[j].id_or_neg_offset - parts_offset].gpart = @@ -3703,45 +3723,67 @@ void cell_activate_subcell_sinks_tasks(struct cell *ci, struct cell *cj, /* Otherwise, pair interation */ else { - error("Not implemented yet."); - /* /\* Should we even bother? *\/ */ - /* if (!cell_is_active_sinks(ci, e) && */ - /* !cell_is_active_sinks(cj, e)) */ - /* return; */ - - /* /\* Get the orientation of the pair. *\/ */ - /* double shift[3]; */ - /* const int sid = space_getsid(s->space, &ci, &cj, shift); */ - - /* /\* recurse? *\/ */ - /* if (cell_can_recurse_in_pair_sinks_task(ci, cj) && */ - /* cell_can_recurse_in_pair_sinks_task(cj, ci)) { */ - /* const struct cell_split_pair *csp = &cell_split_pairs[sid]; */ - /* for (int k = 0; k < csp->count; k++) { */ - /* const int pid = csp->pairs[k].pid; */ - /* const int pjd = csp->pairs[k].pjd; */ - /* if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL) */ - /* cell_activate_subcell_sinks_tasks( */ - /* ci->progeny[pid], cj->progeny[pjd], s, with_timestep_sync); */ - /* } */ - /* } */ - - /* /\* Otherwise, activate the drifts. *\/ */ - /* else if (cell_is_active_sinks(ci, e) || */ - /* cell_is_active_sinks(cj, e)) { */ - - /* /\* Activate the drifts if the cells are local. *\/ */ - /* if (ci->nodeID == engine_rank) cell_activate_drift_sinks(ci, s); */ - /* if (cj->nodeID == engine_rank) cell_activate_drift_part(cj, s); */ - /* if (cj->nodeID == engine_rank && with_timestep_sync) */ - /* cell_activate_sync_part(cj, s); */ - - /* /\* Activate the drifts if the cells are local. *\/ */ - /* if (ci->nodeID == engine_rank) cell_activate_drift_part(ci, s); */ - /* if (cj->nodeID == engine_rank) cell_activate_drift_sinks(cj, s); */ - /* if (ci->nodeID == engine_rank && with_timestep_sync) */ - /* cell_activate_sync_part(ci, s); */ - /* } */ + /* Get the orientation of the pair. */ + double shift[3]; + const int sid = space_getsid(s->space, &ci, &cj, shift); + + const int ci_active = + cell_is_active_sinks(ci, e) || cell_is_active_hydro(ci, e); + const int cj_active = + cell_is_active_sinks(cj, e) || cell_is_active_hydro(cj, e); + + /* Should we even bother? */ + if (!ci_active && !cj_active) return; + + /* recurse? */ + if (cell_can_recurse_in_pair_sinks_task(ci, cj) && + cell_can_recurse_in_pair_sinks_task(cj, ci)) { + + const struct cell_split_pair *csp = &cell_split_pairs[sid]; + for (int k = 0; k < csp->count; k++) { + const int pid = csp->pairs[k].pid; + const int pjd = csp->pairs[k].pjd; + if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL) + cell_activate_subcell_sinks_tasks(ci->progeny[pid], cj->progeny[pjd], + s, with_timestep_sync); + } + } + + /* Otherwise, activate the sorts and drifts. */ + else { + + if (ci_active) { + + /* We are going to interact this pair, so store some values. */ + atomic_or(&cj->hydro.requires_sorts, 1 << sid); + cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort; + + /* Activate the drifts if the cells are local. */ + if (ci->nodeID == engine_rank) cell_activate_drift_sink(ci, s); + if (cj->nodeID == engine_rank) cell_activate_drift_part(cj, s); + if (cj->nodeID == engine_rank && with_timestep_sync) + cell_activate_sync_part(cj, s); + + /* Do we need to sort the cells? */ + cell_activate_hydro_sorts(cj, sid, s); + } + + if (cj_active) { + + /* We are going to interact this pair, so store some values. */ + atomic_or(&ci->hydro.requires_sorts, 1 << sid); + ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort; + + /* Activate the drifts if the cells are local. */ + if (ci->nodeID == engine_rank) cell_activate_drift_part(ci, s); + if (cj->nodeID == engine_rank) cell_activate_drift_sink(cj, s); + if (ci->nodeID == engine_rank && with_timestep_sync) + cell_activate_sync_part(ci, s); + + /* Do we need to sort the cells? */ + cell_activate_hydro_sorts(ci, sid, s); + } + } } /* Otherwise, pair interation */ } @@ -4391,7 +4433,6 @@ int cell_unskip_gravity_tasks(struct cell *c, struct scheduler *s) { if (c->timestep != NULL) scheduler_activate(s, c->timestep); if (c->grav.down != NULL) scheduler_activate(s, c->grav.down); if (c->grav.down_in != NULL) scheduler_activate(s, c->grav.down_in); - if (c->grav.mesh != NULL) scheduler_activate(s, c->grav.mesh); if (c->grav.long_range != NULL) scheduler_activate(s, c->grav.long_range); if (c->grav.end_force != NULL) scheduler_activate(s, c->grav.end_force); #ifdef WITH_LOGGER @@ -4985,11 +5026,10 @@ int cell_unskip_rt_tasks(struct cell *c, struct scheduler *s) { struct engine *e = s->space->e; const int nodeID = e->nodeID; + /* TODO: implement rebuild conditions */ int rebuild = 0; - int counter = 0; for (struct link *l = c->hydro.rt_inject; l != NULL; l = l->next) { - counter++; struct task *t = l->t; struct cell *ci = t->ci; struct cell *cj = t->cj; @@ -5019,6 +5059,15 @@ int cell_unskip_rt_tasks(struct cell *c, struct scheduler *s) { } } + /* Unskip all the other task types */ + if (c->nodeID == nodeID) { + if (cell_is_active_hydro(c, e)) { + if (c->hydro.rt_in != NULL) scheduler_activate(s, c->hydro.rt_in); + if (c->hydro.rt_ghost1 != NULL) scheduler_activate(s, c->hydro.rt_ghost1); + if (c->hydro.rt_out != NULL) scheduler_activate(s, c->hydro.rt_out); + } + } + return rebuild; } @@ -7512,7 +7561,8 @@ void cell_reorder_extra_gparts(struct cell *c, struct part *parts, #endif /* Swap everything (including pointers) */ - memswap(&gparts[i], &gparts[first_not_extra], sizeof(struct gpart)); + memswap_unaligned(&gparts[i], &gparts[first_not_extra], + sizeof(struct gpart)); if (gparts[i].type == swift_type_gas) { parts[-gparts[i].id_or_neg_offset].gpart = &gparts[i]; } else if (gparts[i].type == swift_type_stars) { diff --git a/src/cell.h b/src/cell.h index f92c4a2ec293e3e88fc7db3fb11d99869e58fcfb..3a3f2aac43e1d0b0a9014f8515a8b80af0e468c1 100644 --- a/src/cell.h +++ b/src/cell.h @@ -194,6 +194,26 @@ struct pcell { } black_holes; + /*! Sink variables */ + struct { + + /*! Number of #sink in this cell. */ + int count; + + /*! Maximal cut off radius. */ + float r_cut_max; + + /*! Minimal integer end-of-timestep in this cell for sinks tasks */ + integertime_t ti_end_min; + + /*! Maximal integer end-of-timestep in this cell for sinks tasks */ + integertime_t ti_end_max; + + /*! Integer time of the last drift of the #sink in this cell */ + integertime_t ti_old_part; + + } sinks; + /*! Maximal depth in that part of the tree */ int maxdepth; @@ -416,6 +436,9 @@ struct cell { /*! Radiative transfer ghost out task */ struct task *rt_out; + /*! Radiative transfer ghost1 task (finishes up injection) */ + struct task *rt_ghost1; + /*! Task for self/pair injection step of radiative transfer */ struct link *rt_inject; @@ -526,9 +549,6 @@ struct cell { /*! Implicit task for the down propagation */ struct task *down_in; - /*! Task propagating the mesh forces to the particles */ - struct task *mesh; - /*! Task propagating the multipole to the particles */ struct task *down; @@ -772,6 +792,9 @@ struct cell { /*! Pointer to the #sink data. */ struct sink *parts; + /*! Linked list of the tasks computing this cell's sink formation checks. */ + struct link *compute_formation; + /*! Nr of #sink in this cell. */ int count; @@ -1016,6 +1039,9 @@ void cell_activate_subcell_stars_tasks(struct cell *ci, struct cell *cj, struct scheduler *s, const int with_star_formation, const int with_timestep_sync); +void cell_activate_subcell_sinks_tasks(struct cell *ci, struct cell *cj, + struct scheduler *s, + const int with_timestep_sync); void cell_activate_subcell_black_holes_tasks(struct cell *ci, struct cell *cj, struct scheduler *s, const int with_timestep_sync); @@ -1203,6 +1229,28 @@ cell_can_recurse_in_self_stars_task(const struct cell *c) { (kernel_gamma * c->hydro.h_max_old < 0.5f * c->dmin); } +/** + * @brief Can a sub-pair sink task recurse to a lower level based + * on the status of the particles in the cell. + * + * @param ci The #cell with stars. + * @param cj The #cell with hydro parts. + */ +__attribute__((always_inline)) INLINE static int +cell_can_recurse_in_pair_sinks_task(const struct cell *ci, + const struct cell *cj) { + + /* Is the cell split ? */ + /* If so, is the cut-off radius plus the max distance the parts have moved */ + /* smaller than the sub-cell sizes ? */ + /* Note: We use the _old values as these might have been updated by a drift */ + return ci->split && cj->split && + ((ci->sinks.r_cut_max_old + ci->sinks.dx_max_part_old) < + 0.5f * ci->dmin) && + ((kernel_gamma * cj->hydro.h_max_old + cj->hydro.dx_max_part_old) < + 0.5f * cj->dmin); +} + /** * @brief Can a sub-pair black hole task recurse to a lower level based * on the status of the particles in the cell. @@ -1377,6 +1425,27 @@ cell_need_rebuild_for_stars_pair(const struct cell *ci, const struct cell *cj) { return 0; } +/** + * @brief Have sink particles in a pair of cells moved too much and require a + * rebuild? + * + * @param ci The first #cell. + * @param cj The second #cell. + */ +__attribute__((always_inline, nonnull)) INLINE static int +cell_need_rebuild_for_sinks_pair(const struct cell *ci, const struct cell *cj) { + + /* Is the cut-off radius plus the max distance the parts in both cells have */ + /* moved larger than the cell size ? */ + /* Note ci->dmin == cj->dmin */ + if (max(ci->sinks.r_cut_max, kernel_gamma * cj->hydro.h_max) + + ci->sinks.dx_max_part + cj->hydro.dx_max_part > + cj->dmin) { + return 1; + } + return 0; +} + /** * @brief Have star particles in a pair of cells moved too much and require a * rebuild? diff --git a/src/common_io.c b/src/common_io.c index 7a5f28c27d31130c2318178ebee4aa0f872d7465..ec0d085d914dffa8093b4a67b0b08647097159c5 100644 --- a/src/common_io.c +++ b/src/common_io.c @@ -724,6 +724,10 @@ void io_write_code_description(hid_t h_file) { #ifdef HAVE_LIBGSL io_write_attribute_s(h_grpcode, "GSL library version", libgsl_version()); #endif +#ifdef HAVE_SUNDIALS + io_write_attribute_s(h_grpcode, "SUNDIALS library version", + sundials_version()); +#endif #ifdef WITH_MPI io_write_attribute_s(h_grpcode, "MPI library", mpi_version()); #ifdef HAVE_METIS @@ -899,7 +903,6 @@ void io_write_array(hid_t h_grp, const int n, const void* array, } void io_write_cell_offsets(hid_t h_grp, const int cdim[3], const double dim[3], - const double pos_dithering[3], const struct cell* cells_top, const int nr_cells, const double width[3], const int nodeID, const int distributed, @@ -986,12 +989,6 @@ void io_write_cell_offsets(hid_t h_grp, const int cdim[3], const double dim[3], centres[i * 3 + 1] = cells_top[i].loc[1] + cell_width[1] * 0.5; centres[i * 3 + 2] = cells_top[i].loc[2] + cell_width[2] * 0.5; - /* Undo the dithering since the particles will have this vector applied to - * them */ - centres[i * 3 + 0] = centres[i * 3 + 0] - pos_dithering[0]; - centres[i * 3 + 1] = centres[i * 3 + 1] - pos_dithering[1]; - centres[i * 3 + 2] = centres[i * 3 + 2] - pos_dithering[2]; - /* Finish by box wrapping to match what is done to the particles */ centres[i * 3 + 0] = box_wrap(centres[i * 3 + 0], 0.0, dim[0]); centres[i * 3 + 1] = box_wrap(centres[i * 3 + 1], 0.0, dim[1]); diff --git a/src/common_io.h b/src/common_io.h index 4dc227d10452776bfaf65e4eafafb214054c1ddd..e8fc1fc4f68fbdcae027974593b6d4f124cd1fc7 100644 --- a/src/common_io.h +++ b/src/common_io.h @@ -103,7 +103,6 @@ void io_write_code_description(hid_t h_file); void io_write_engine_policy(hid_t h_file, const struct engine* e); void io_write_cell_offsets(hid_t h_grp, const int cdim[3], const double dim[3], - const double pos_dithering[3], const struct cell* cells_top, const int nr_cells, const double width[3], const int nodeID, const int distributed, diff --git a/src/cooling/COLIBRE/cooling_rates.h b/src/cooling/COLIBRE/cooling_rates.h index 59fd1442f48e16bb87331e50c88fffddec31e12a..881b5d1aeb3016dece14c951b422ef77d3c8e734 100644 --- a/src/cooling/COLIBRE/cooling_rates.h +++ b/src/cooling/COLIBRE/cooling_rates.h @@ -348,12 +348,17 @@ __attribute__((always_inline)) INLINE static float colibre_convert_u_to_temp( colibre_cooling_N_internalenergy, colibre_cooling_N_metallicity, colibre_cooling_N_density); - /* Special case for temperatures below the start of the table */ + /* General interpolation returns u for the first (or last) element + * but we want to extrapolate in this case. We assume that the u-T relation + * does not change outside the table range */ if (u_index == 0 && d_u == 0.f) { - /* The temperature is multiplied by u / 10^T[0] - * where T[0] is the first entry in the table */ - log_10_T += log_10_u_cgs - cooling->Temp[0]; + log_10_T += log_10_u_cgs - cooling->Therm[0]; + + } else if (u_index >= colibre_cooling_N_internalenergy - 2 && d_u == 1.f) { + + log_10_T += + log_10_u_cgs - cooling->Therm[colibre_cooling_N_internalenergy - 1]; } return log_10_T; @@ -401,6 +406,17 @@ __attribute__((always_inline)) INLINE static float colibre_convert_temp_to_u( colibre_cooling_N_temperature, colibre_cooling_N_metallicity, colibre_cooling_N_density); + /* General interpolation returns u for the first (or last) element + * but we want to extrapolate in this case. We assume that the u-T relation + * does not change outside the table range */ + if (T_index == 0 && d_T == 0.f) { + + log_10_U += cooling->Temp[0] - log_10_T; + } else if (T_index >= colibre_cooling_N_temperature - 2 && d_T == 1.f) { + + log_10_U += cooling->Temp[colibre_cooling_N_temperature - 1] - log_10_T; + } + return log_10_U; } diff --git a/src/cooling/QLA/cooling_rates.h b/src/cooling/QLA/cooling_rates.h index 55674a1b4369707a2c7680aa6f20486de8ca5cf4..b668694be66b7e551e8c4c0e5fb0016574021b94 100644 --- a/src/cooling/QLA/cooling_rates.h +++ b/src/cooling/QLA/cooling_rates.h @@ -253,12 +253,16 @@ __attribute__((always_inline)) INLINE static float qla_convert_u_to_temp( d_u, d_met, d_n_H, qla_cooling_N_redshifts, qla_cooling_N_internalenergy, qla_cooling_N_metallicity, qla_cooling_N_density); - /* Special case for temperatures below the start of the table */ + /* General interpolation returns u for the first (or last) element + * but we want to extrapolate in this case. We assume that the u-T relation + * does not change outside the table range */ if (u_index == 0 && d_u == 0.f) { - /* The temperature is multiplied by u / 10^T[0] - * where T[0] is the first entry in the table */ - log_10_T += log_10_u_cgs - cooling->Temp[0]; + log_10_T += log_10_u_cgs - cooling->Therm[0]; + + } else if (u_index >= qla_cooling_N_internalenergy - 2 && d_u == 1.f) { + + log_10_T += log_10_u_cgs - cooling->Therm[qla_cooling_N_internalenergy - 1]; } return log_10_T; @@ -305,6 +309,17 @@ __attribute__((always_inline)) INLINE static float qla_convert_temp_to_u( d_T, d_met, d_n_H, qla_cooling_N_redshifts, qla_cooling_N_temperature, qla_cooling_N_metallicity, qla_cooling_N_density); + /* General interpolation returns u for the first (or last) element + * but we want to extrapolate in this case. We assume that the u-T relation + * does not change outside the table range */ + if (T_index == 0 && d_T == 0.f) { + + log_10_U += cooling->Temp[0] - log_10_T; + } else if (T_index >= qla_cooling_N_temperature - 2 && d_T == 1.f) { + + log_10_U += cooling->Temp[qla_cooling_N_temperature - 1] - log_10_T; + } + return log_10_U; } diff --git a/src/debug.c b/src/debug.c index 6af9bd2d20502ea1bfa419054ddc8d9b0538e078..3f02810564ce601bd8c73fb2224f40b63ff55a6a 100644 --- a/src/debug.c +++ b/src/debug.c @@ -50,8 +50,8 @@ #include "./hydro/PressureEnergy/hydro_debug.h" #elif defined(HOPKINS_PU_SPH_MONAGHAN) #include "./hydro/PressureEnergyMorrisMonaghanAV/hydro_debug.h" -#elif defined(DEFAULT_SPH) -#include "./hydro/Default/hydro_debug.h" +#elif defined(PHANTOM_SPH) +#include "./hydro/Phantom/hydro_debug.h" #elif defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH) #include "./hydro/Gizmo/hydro_debug.h" #elif defined(SHADOWFAX_SPH) diff --git a/src/distributed_io.c b/src/distributed_io.c index 33073426c382f732b1cf0d035c616a7db96243ad..3ab6d39a9a519e3fa9440fb275fbc6c868692dd8 100644 --- a/src/distributed_io.c +++ b/src/distributed_io.c @@ -457,8 +457,8 @@ void write_output_distributed(struct engine* e, if (h_grp < 0) error("Error while creating cells group"); /* Write the location of the particles in the arrays */ - io_write_cell_offsets(h_grp, e->s->cdim, e->s->dim, e->s->pos_dithering, - e->s->cells_top, e->s->nr_cells, e->s->width, mpi_rank, + io_write_cell_offsets(h_grp, e->s->cdim, e->s->dim, e->s->cells_top, + e->s->nr_cells, e->s->width, mpi_rank, /*distributed=*/1, N_total, global_offsets, numFields, internal_units, snapshot_units); H5Gclose(h_grp); diff --git a/src/drift.h b/src/drift.h index ef0eab0ac662e4448ddac20efc82a3fd7d0b68e4..e994e4fde7339d6eedbe376ccc136152564106ae 100644 --- a/src/drift.h +++ b/src/drift.h @@ -149,9 +149,12 @@ __attribute__((always_inline)) INLINE static void drift_part( p->v[1] += p->a_hydro[1] * dt_kick_hydro; p->v[2] += p->a_hydro[2] * dt_kick_hydro; - p->v[0] += xp->a_grav[0] * dt_kick_grav; - p->v[1] += xp->a_grav[1] * dt_kick_grav; - p->v[2] += xp->a_grav[2] * dt_kick_grav; + /* Predict velocities (for gravity terms) */ + if (p->gpart != NULL) { + p->v[0] += (p->gpart->a_grav[0] + p->gpart->a_grav_mesh[0]) * dt_kick_grav; + p->v[1] += (p->gpart->a_grav[1] + p->gpart->a_grav_mesh[1]) * dt_kick_grav; + p->v[2] += (p->gpart->a_grav[2] + p->gpart->a_grav_mesh[2]) * dt_kick_grav; + } /* Predict the values of the extra fields */ hydro_predict_extra(p, xp, dt_drift, dt_therm, cosmo, hydro_props, floor); diff --git a/src/engine.c b/src/engine.c index c72984c1fe9368ee1f493cc520176b7b8dfe6d1d..21e2e941dcfe22c41f43688baddc95d5a7f87f8e 100644 --- a/src/engine.c +++ b/src/engine.c @@ -71,6 +71,7 @@ #include "gravity.h" #include "gravity_cache.h" #include "hydro.h" +#include "kick.h" #include "line_of_sight.h" #include "logger.h" #include "logger_io.h" @@ -1635,8 +1636,8 @@ int engine_estimate_nr_tasks(const struct engine *e) { #endif if (e->policy & engine_policy_rt) { /* inject: 1 self + (3^3-1)/2 = 26/2 = 13 pairs | 14 - * ghosts: in + out | + 2 */ - n1 += 16; + * ghosts: in + out, ghost1, | + 3 */ + n1 += 17; } #ifdef WITH_MPI @@ -1787,20 +1788,6 @@ void engine_rebuild(struct engine *e, const int repartitioned, message("updating particle counts took %.3f %s.", clocks_from_ticks(getticks() - tic2), clocks_getunit()); - /* Re-compute the mesh forces */ - if ((e->policy & engine_policy_self_gravity) && e->s->periodic) { - - /* Re-allocate the PM grid if we freed it... */ - if (repartitioned) pm_mesh_allocate(e->mesh); - - /* ... and recompute */ - pm_mesh_compute_potential(e->mesh, e->s, &e->threadpool, e->verbose); - } - - /* Re-compute the maximal RMS displacement constraint */ - if (e->policy & engine_policy_cosmology) - engine_recompute_displacement_constraint(e); - #ifdef SWIFT_DEBUG_CHECKS part_verify_links(e->s->parts, e->s->gparts, e->s->sinks, e->s->sparts, e->s->bparts, e->s->nr_parts, e->s->nr_gparts, @@ -1881,8 +1868,10 @@ void engine_rebuild(struct engine *e, const int repartitioned, * @brief Prepare the #engine by re-building the cells and tasks. * * @param e The #engine to prepare. + * + * @return 1 if the function drifted all particles 0 if not. */ -void engine_prepare(struct engine *e) { +int engine_prepare(struct engine *e) { TIMER_TIC2; const ticks tic = getticks(); @@ -1941,6 +1930,10 @@ void engine_prepare(struct engine *e) { /* And repartition */ engine_repartition(e); repartitioned = 1; + + /* Reallocate the mesh */ + if ((e->policy & engine_policy_self_gravity) && e->s->periodic) + pm_mesh_allocate(e->mesh); } /* Do we need rebuilding ? */ @@ -1949,6 +1942,8 @@ void engine_prepare(struct engine *e) { /* Let's start by drifting everybody to the current time */ if (!e->restarting && !drifted_all) engine_drift_all(e, /*drift_mpole=*/0); + drifted_all = 1; + /* And rebuild */ engine_rebuild(e, repartitioned, 0); } @@ -1975,6 +1970,8 @@ void engine_prepare(struct engine *e) { if (e->verbose) message("took %.3f %s (including unskip, rebuild and reweight).", clocks_from_ticks(getticks() - tic), clocks_getunit()); + + return drifted_all; } /** @@ -2092,7 +2089,8 @@ void engine_skip_force_and_kick(struct engine *e) { t->type == task_type_bh_swallow_ghost1 || t->type == task_type_bh_swallow_ghost2 || t->type == task_type_bh_swallow_ghost3 || t->type == task_type_bh_in || - t->type == task_type_bh_out || t->subtype == task_subtype_force || + t->type == task_type_bh_out || t->type == task_type_rt_ghost1 || + t->subtype == task_subtype_force || t->subtype == task_subtype_limiter || t->subtype == task_subtype_gradient || t->subtype == task_subtype_stars_feedback || @@ -2258,6 +2256,18 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs, /* Construct all cells and tasks to start everything */ engine_rebuild(e, 0, clean_h_values); + /* Compute the mesh forces for the first time */ + if ((e->policy & engine_policy_self_gravity) && e->s->periodic) { + + /* Compute mesh forces */ + pm_mesh_compute_potential(e->mesh, e->s, &e->threadpool, e->verbose); + + /* Compute mesh time-step length */ + engine_recompute_displacement_constraint(e); + + e->step_props |= engine_step_prop_mesh; + } + /* No time integration. We just want the density and ghosts */ engine_skip_force_and_kick(e); @@ -2674,7 +2684,7 @@ void engine_step(struct engine *e) { #endif /* Prepare the tasks to be launched, rebuild or repartition if needed. */ - engine_prepare(e); + const int drifted_all = engine_prepare(e); #ifdef SWIFT_DEBUG_CHECKS /* Print the number of active tasks */ @@ -2733,6 +2743,22 @@ void engine_step(struct engine *e) { } #endif + /* Re-compute the mesh forces */ + if ((e->policy & engine_policy_self_gravity) && e->s->periodic && + e->mesh->ti_end_mesh_next == e->ti_current) { + + /* We might need to drift things */ + if (!drifted_all) engine_drift_all(e, /*drift_mpole=*/0); + + /* ... and recompute */ + pm_mesh_compute_potential(e->mesh, e->s, &e->threadpool, e->verbose); + + /* Check whether we need to update the mesh time-step length */ + engine_recompute_displacement_constraint(e); + + e->step_props |= engine_step_prop_mesh; + } + /* Get current CPU times.*/ #ifdef WITH_MPI double start_usertime = 0.0; @@ -3697,6 +3723,19 @@ void engine_dump_snapshot(struct engine *e) { engine_collect_stars_counter(e); #endif + /* Get time-step since the last mesh kick */ + if ((e->policy & engine_policy_self_gravity) && e->s->periodic) { + const int with_cosmology = e->policy & engine_policy_cosmology; + + e->dt_kick_grav_mesh_for_io = + kick_get_grav_kick_dt(e->mesh->ti_beg_mesh_next, e->ti_current, + e->time_base, with_cosmology, e->cosmology) - + kick_get_grav_kick_dt( + e->mesh->ti_beg_mesh_next, + (e->mesh->ti_beg_mesh_next + e->mesh->ti_end_mesh_next) / 2, + e->time_base, with_cosmology, e->cosmology); + } + /* Dump (depending on the chosen strategy) ... */ #if defined(HAVE_HDF5) #if defined(WITH_MPI) @@ -4000,6 +4039,7 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params, e->dt_max_RMS_displacement = FLT_MAX; e->max_RMS_displacement_factor = parser_get_opt_param_double( params, "TimeIntegration:max_dt_RMS_factor", 0.25); + e->dt_kick_grav_mesh_for_io = 0.f; e->a_first_statistics = parser_get_opt_param_double(params, "Statistics:scale_factor_first", 0.1); e->time_first_statistics = @@ -4388,11 +4428,12 @@ void engine_config(int restart, int fof, struct engine *e, fprintf( e->file_timesteps, "# Step Properties: Rebuild=%d, Redistribute=%d, Repartition=%d, " - "Statistics=%d, Snapshot=%d, Restarts=%d STF=%d, FOF=%d, logger=%d\n", + "Statistics=%d, Snapshot=%d, Restarts=%d STF=%d, FOF=%d, mesh=%d, " + "logger=%d\n", engine_step_prop_rebuild, engine_step_prop_redistribute, engine_step_prop_repartition, engine_step_prop_statistics, engine_step_prop_snapshot, engine_step_prop_restarts, - engine_step_prop_stf, engine_step_prop_fof, + engine_step_prop_stf, engine_step_prop_fof, engine_step_prop_mesh, engine_step_prop_logger_index); fprintf(e->file_timesteps, @@ -5280,6 +5321,7 @@ void engine_recompute_displacement_constraint(struct engine *e) { const ticks tic = getticks(); /* Get the cosmological information */ + const int with_cosmology = e->policy & engine_policy_cosmology; const struct cosmology *cosmo = e->cosmology; const float Om = cosmo->Omega_m; const float Ob = cosmo->Omega_b; @@ -5288,113 +5330,160 @@ void engine_recompute_displacement_constraint(struct engine *e) { const float G_newton = e->physical_constants->const_newton_G; const float rho_crit0 = 3.f * H0 * H0 / (8.f * M_PI * G_newton); - /* Start by reducing the minimal mass of each particle type */ - float min_mass[swift_type_count] = { - e->s->min_part_mass, e->s->min_gpart_mass, FLT_MAX, - e->s->min_sink_mass, e->s->min_spart_mass, e->s->min_bpart_mass}; + if (with_cosmology) { + + /* Start by reducing the minimal mass of each particle type */ + float min_mass[swift_type_count] = { + e->s->min_part_mass, e->s->min_gpart_mass, FLT_MAX, + e->s->min_sink_mass, e->s->min_spart_mass, e->s->min_bpart_mass}; #ifdef WITH_MPI - MPI_Allreduce(MPI_IN_PLACE, min_mass, swift_type_count, MPI_FLOAT, MPI_MIN, - MPI_COMM_WORLD); + MPI_Allreduce(MPI_IN_PLACE, min_mass, swift_type_count, MPI_FLOAT, MPI_MIN, + MPI_COMM_WORLD); #endif #ifdef SWIFT_DEBUG_CHECKS - /* Check that the minimal mass collection worked */ - float min_part_mass_check = FLT_MAX; - for (size_t i = 0; i < e->s->nr_parts; ++i) { - if (e->s->parts[i].time_bin >= num_time_bins) continue; - min_part_mass_check = - min(min_part_mass_check, hydro_get_mass(&e->s->parts[i])); - } - if (min_part_mass_check < min_mass[swift_type_gas]) - error("Error collecting minimal mass of gas particles."); + /* Check that the minimal mass collection worked */ + float min_part_mass_check = FLT_MAX; + for (size_t i = 0; i < e->s->nr_parts; ++i) { + if (e->s->parts[i].time_bin >= num_time_bins) continue; + min_part_mass_check = + min(min_part_mass_check, hydro_get_mass(&e->s->parts[i])); + } + if (min_part_mass_check < min_mass[swift_type_gas]) + error("Error collecting minimal mass of gas particles."); #endif - /* Do the same for the velocity norm sum */ - float vel_norm[swift_type_count] = {e->s->sum_part_vel_norm, - e->s->sum_gpart_vel_norm, - 0.f, - e->s->sum_sink_vel_norm, - e->s->sum_spart_vel_norm, - e->s->sum_spart_vel_norm}; + /* Do the same for the velocity norm sum */ + float vel_norm[swift_type_count] = {e->s->sum_part_vel_norm, + e->s->sum_gpart_vel_norm, + 0.f, + e->s->sum_sink_vel_norm, + e->s->sum_spart_vel_norm, + e->s->sum_spart_vel_norm}; #ifdef WITH_MPI - MPI_Allreduce(MPI_IN_PLACE, vel_norm, swift_type_count, MPI_FLOAT, MPI_SUM, - MPI_COMM_WORLD); + MPI_Allreduce(MPI_IN_PLACE, vel_norm, swift_type_count, MPI_FLOAT, MPI_SUM, + MPI_COMM_WORLD); #endif - /* Get the counts of each particle types */ - const long long total_nr_baryons = - e->total_nr_parts + e->total_nr_sparts + e->total_nr_bparts; - const long long total_nr_dm_gparts = - e->total_nr_gparts - e->total_nr_DM_background_gparts - total_nr_baryons; - float count_parts[swift_type_count] = { - (float)e->total_nr_parts, - (float)total_nr_dm_gparts, - (float)e->total_nr_DM_background_gparts, - (float)e->total_nr_sinks, - (float)e->total_nr_sparts, - (float)e->total_nr_bparts}; - - /* Count of particles for the two species */ - const float N_dm = count_parts[1]; - const float N_b = - count_parts[0] + count_parts[3] + count_parts[4] + count_parts[5]; - - /* Peculiar motion norm for the two species */ - const float vel_norm_dm = vel_norm[1]; - const float vel_norm_b = - vel_norm[0] + vel_norm[3] + vel_norm[4] + vel_norm[5]; - - /* Mesh forces smoothing scale */ - float r_s; - if ((e->policy & engine_policy_self_gravity) && e->s->periodic) - r_s = e->mesh->r_s; - else - r_s = FLT_MAX; + /* Get the counts of each particle types */ + const long long total_nr_baryons = + e->total_nr_parts + e->total_nr_sparts + e->total_nr_bparts; + const long long total_nr_dm_gparts = e->total_nr_gparts - + e->total_nr_DM_background_gparts - + total_nr_baryons; + float count_parts[swift_type_count] = { + (float)e->total_nr_parts, + (float)total_nr_dm_gparts, + (float)e->total_nr_DM_background_gparts, + (float)e->total_nr_sinks, + (float)e->total_nr_sparts, + (float)e->total_nr_bparts}; + + /* Count of particles for the two species */ + const float N_dm = count_parts[1]; + const float N_b = + count_parts[0] + count_parts[3] + count_parts[4] + count_parts[5]; + + /* Peculiar motion norm for the two species */ + const float vel_norm_dm = vel_norm[1]; + const float vel_norm_b = + vel_norm[0] + vel_norm[3] + vel_norm[4] + vel_norm[5]; + + /* Mesh forces smoothing scale */ + float r_s; + if ((e->policy & engine_policy_self_gravity) && e->s->periodic) + r_s = e->mesh->r_s; + else + r_s = FLT_MAX; - float dt_dm = FLT_MAX, dt_b = FLT_MAX; + float dt_dm = FLT_MAX, dt_b = FLT_MAX; - /* DM case */ - if (N_dm > 0.f) { + /* DM case */ + if (N_dm > 0.f) { - /* Minimal mass for the DM */ - const float min_mass_dm = min_mass[1]; + /* Minimal mass for the DM */ + const float min_mass_dm = min_mass[1]; - /* Inter-particle sepration for the DM */ - const float d_dm = cbrtf(min_mass_dm / ((Om - Ob) * rho_crit0)); + /* Inter-particle sepration for the DM */ + const float d_dm = cbrtf(min_mass_dm / ((Om - Ob) * rho_crit0)); - /* RMS peculiar motion for the DM */ - const float rms_vel_dm = vel_norm_dm / N_dm; + /* RMS peculiar motion for the DM */ + const float rms_vel_dm = vel_norm_dm / N_dm; - /* Time-step based on maximum displacement */ - dt_dm = a * a * min(r_s, d_dm) / sqrtf(rms_vel_dm); + /* Time-step based on maximum displacement */ + dt_dm = a * a * min(r_s, d_dm) / sqrtf(rms_vel_dm); + } + + /* Baryon case */ + if (N_b > 0.f) { + + /* Minimal mass for the baryons */ + const float min_mass_b = + min4(min_mass[0], min_mass[3], min_mass[4], min_mass[5]); + + /* Inter-particle sepration for the baryons */ + const float d_b = cbrtf(min_mass_b / (Ob * rho_crit0)); + + /* RMS peculiar motion for the baryons */ + const float rms_vel_b = vel_norm_b / N_b; + + /* Time-step based on maximum displacement */ + dt_b = a * a * min(r_s, d_b) / sqrtf(rms_vel_b); + } + + /* Use the minimum */ + const float dt = min(dt_dm, dt_b); + + /* Apply the dimensionless factor */ + e->dt_max_RMS_displacement = dt * e->max_RMS_displacement_factor; + + if (e->verbose) + message("max_dt_RMS_displacement = %e", e->dt_max_RMS_displacement); } - /* Baryon case */ - if (N_b > 0.f) { + /* Now, update the mesh time-step */ + + /* Store the previous time-step size */ + e->mesh->ti_end_mesh_last = e->mesh->ti_end_mesh_next; + e->mesh->ti_beg_mesh_last = e->mesh->ti_beg_mesh_next; + const integertime_t old_dti = + e->mesh->ti_end_mesh_last - e->mesh->ti_beg_mesh_last; + +#ifdef SWIFT_DEBUG_CHECKS + if (e->step > 1 && e->mesh->ti_end_mesh_last != e->ti_current) + error("Weird time integration issue"); +#endif - /* Minimal mass for the baryons */ - const float min_mass_b = - min4(min_mass[0], min_mass[3], min_mass[4], min_mass[5]); + /* What is the allowed time-step size + * Note: The cosmology factor is 1 in non-cosmo runs */ + double dt_mesh = e->dt_max_RMS_displacement * e->cosmology->time_step_factor; + dt_mesh = min(dt_mesh, e->dt_max); - /* Inter-particle sepration for the baryons */ - const float d_b = cbrtf(min_mass_b / (Ob * rho_crit0)); + /* Convert to integer time */ + integertime_t new_dti = (integertime_t)(dt_mesh * e->time_base_inv); - /* RMS peculiar motion for the baryons */ - const float rms_vel_b = vel_norm_b / N_b; + /* Find the max integer time-step on the timeline below new_dti */ + integertime_t dti_timeline = max_nr_timesteps; + while (new_dti < dti_timeline) dti_timeline /= ((integertime_t)2); + new_dti = dti_timeline; - /* Time-step based on maximum displacement */ - dt_b = a * a * min(r_s, d_b) / sqrtf(rms_vel_b); + /* Make sure we are allowed to increase the timestep size */ + const integertime_t current_dti = e->step > 0 ? old_dti : max_nr_timesteps; + if (new_dti > current_dti) { + if ((max_nr_timesteps - e->ti_current) % new_dti > 0) { + new_dti = current_dti; + } } - /* Use the minimum */ - const float dt = min(dt_dm, dt_b); + e->mesh->ti_beg_mesh_next = e->ti_current; + e->mesh->ti_end_mesh_next = e->ti_current + new_dti; - /* Apply the dimensionless factor */ - e->dt_max_RMS_displacement = dt * e->max_RMS_displacement_factor; + const timebin_t bin = get_time_bin(new_dti); - if (e->verbose) - message("max_dt_RMS_displacement = %e", e->dt_max_RMS_displacement); + if (new_dti != old_dti) + message("Mesh time-step changed to %e (time-bin %d)", + get_timestep(bin, e->time_base), bin); if (e->verbose) message("took %.3f %s.", clocks_from_ticks(getticks() - tic), diff --git a/src/engine.h b/src/engine.h index ab18392e0bd5325b249fd788d509d6b5c8a0c49f..7d8561fb3a8d0eff7355d0d355a9d33279f660df 100644 --- a/src/engine.h +++ b/src/engine.h @@ -100,8 +100,9 @@ enum engine_step_properties { engine_step_prop_restarts = (1 << 5), engine_step_prop_stf = (1 << 6), engine_step_prop_fof = (1 << 7), - engine_step_prop_logger_index = (1 << 8), - engine_step_prop_done = (1 << 9) + engine_step_prop_mesh = (1 << 8), + engine_step_prop_logger_index = (1 << 9), + engine_step_prop_done = (1 << 10), }; /* Some constants */ @@ -509,6 +510,10 @@ struct engine { /* The globally agreed runtime, in hours. */ float runtime; + /* Time-integration mesh kick to apply to the particle velocities for + * snapshots */ + float dt_kick_grav_mesh_for_io; + /* Label of the run */ char run_name[PARSER_MAX_LINE_SIZE]; @@ -587,7 +592,7 @@ void engine_config(int restart, int fof, struct engine *e, const char *restart_file); void engine_dump_index(struct engine *e); void engine_launch(struct engine *e, const char *call); -void engine_prepare(struct engine *e); +int engine_prepare(struct engine *e); void engine_init_particles(struct engine *e, int flag_entropy_ICs, int clean_h_values); void engine_step(struct engine *e); diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c index 4b259d0dfc42807d828c5cffa2932aba37736df5..cb41018a11d228f26cb0516b6bcecffbc369d3ed 100644 --- a/src/engine_maketasks.c +++ b/src/engine_maketasks.c @@ -939,7 +939,6 @@ void engine_make_hierarchical_tasks_common(struct engine *e, struct cell *c) { void engine_make_hierarchical_tasks_gravity(struct engine *e, struct cell *c) { struct scheduler *s = &e->sched; - const int periodic = e->s->periodic; const int is_self_gravity = (e->policy & engine_policy_self_gravity); const int stars_only_gravity = (e->policy & engine_policy_stars) && !(e->policy & engine_policy_hydro); @@ -991,13 +990,7 @@ void engine_make_hierarchical_tasks_gravity(struct engine *e, struct cell *c) { c->grav.down_in = scheduler_addtask(s, task_type_grav_down_in, task_subtype_none, 0, 1, c, NULL); - /* Gravity mesh force propagation */ - if (periodic) - c->grav.mesh = scheduler_addtask(s, task_type_grav_mesh, - task_subtype_none, 0, 0, c, NULL); - - if (periodic) scheduler_addunlock(s, c->grav.drift, c->grav.mesh); - if (periodic) scheduler_addunlock(s, c->grav.mesh, c->grav.down); + /* Long-range gravity forces (not the mesh ones!) */ scheduler_addunlock(s, c->grav.init, c->grav.long_range); scheduler_addunlock(s, c->grav.long_range, c->grav.down); scheduler_addunlock(s, c->grav.down, c->grav.super->grav.end_force); @@ -1283,6 +1276,11 @@ void engine_make_hierarchical_tasks_hydro(struct engine *e, struct cell *c, scheduler_addtask(s, task_type_rt_out, task_subtype_none, 0, /* implicit= */ 1, c, NULL); scheduler_addunlock(s, c->hydro.rt_out, c->super->timestep); + + /* non-implicit ghost 1 */ + c->hydro.rt_ghost1 = scheduler_addtask( + s, task_type_rt_ghost1, task_subtype_none, 0, 0, c, NULL); + scheduler_addunlock(s, c->hydro.rt_ghost1, c->hydro.rt_out); } /* Subgrid tasks: sink */ @@ -1921,6 +1919,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, const int with_feedback = (e->policy & engine_policy_feedback); const int with_black_holes = (e->policy & engine_policy_black_holes); const int with_rt = (e->policy & engine_policy_rt); + const int with_sink = (e->policy & engine_policy_sinks); #ifdef EXTRA_HYDRO_LOOP struct task *t_gradient = NULL; #endif @@ -1934,6 +1933,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, struct task *t_do_bh_swallow = NULL; struct task *t_bh_feedback = NULL; struct task *t_rt_inject = NULL; + struct task *t_sink_formation = NULL; for (int ind = 0; ind < num_elements; ind++) { @@ -1988,6 +1988,13 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, task_subtype_stars_feedback, flags, 0, ci, NULL); } + /* The sink tasks */ + if (with_sink) { + t_sink_formation = scheduler_addtask( + sched, task_type_self, task_subtype_sink_compute_formation, flags, + 0, ci, NULL); + } + /* The black hole feedback tasks */ if (with_black_holes && bcount_i > 0) { t_bh_density = scheduler_addtask( @@ -2019,6 +2026,9 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, engine_addlink(e, &ci->stars.density, t_star_density); engine_addlink(e, &ci->stars.feedback, t_star_feedback); } + if (with_sink) { + engine_addlink(e, &ci->sinks.compute_formation, t_sink_formation); + } if (with_black_holes && bcount_i > 0) { engine_addlink(e, &ci->black_holes.density, t_bh_density); engine_addlink(e, &ci->black_holes.swallow, t_bh_swallow); @@ -2069,6 +2079,19 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, ci->hydro.super->stars.stars_out); } + /* The sink's tasks. */ + if (with_sink) { + + scheduler_addunlock(sched, ci->hydro.super->sinks.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->hydro.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->sinks.sink_in, + t_sink_formation); + scheduler_addunlock(sched, t_sink_formation, + ci->hydro.super->hydro.sink_formation); + } + if (with_black_holes && bcount_i > 0) { scheduler_addunlock(sched, ci->hydro.super->black_holes.drift, @@ -2125,7 +2148,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, } else { scheduler_addunlock(sched, ci->hydro.super->hydro.rt_in, t_rt_inject); } - scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_out); + scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_ghost1); } } @@ -2169,6 +2192,13 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, task_subtype_stars_feedback, flags, 0, ci, cj); } + /* The sink tasks */ + if (with_sink) { + t_sink_formation = scheduler_addtask( + sched, task_type_pair, task_subtype_sink_compute_formation, flags, + 0, ci, cj); + } + /* The black hole feedback tasks */ if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { t_bh_density = scheduler_addtask( @@ -2202,6 +2232,10 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, engine_addlink(e, &ci->stars.feedback, t_star_feedback); engine_addlink(e, &cj->stars.feedback, t_star_feedback); } + if (with_sink) { + engine_addlink(e, &ci->sinks.compute_formation, t_sink_formation); + engine_addlink(e, &cj->sinks.compute_formation, t_sink_formation); + } if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { engine_addlink(e, &ci->black_holes.density, t_bh_density); engine_addlink(e, &cj->black_holes.density, t_bh_density); @@ -2266,7 +2300,15 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, t_star_density); } } + if (with_sink) { + scheduler_addunlock(sched, ci->hydro.super->hydro.sorts, + t_sink_formation); + if (ci->hydro.super != cj->hydro.super) { + scheduler_addunlock(sched, cj->hydro.super->hydro.sorts, + t_sink_formation); + } + } if (ci->nodeID == nodeID) { scheduler_addunlock(sched, t_force, ci->hydro.super->hydro.end_force); @@ -2288,6 +2330,18 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, ci->hydro.super->stars.stars_out); } + if (with_sink) { + + scheduler_addunlock(sched, ci->hydro.super->sinks.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->hydro.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->sinks.sink_in, + t_sink_formation); + scheduler_addunlock(sched, t_sink_formation, + ci->hydro.super->hydro.sink_formation); + } + if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { scheduler_addunlock(sched, ci->hydro.super->black_holes.drift, @@ -2347,7 +2401,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, scheduler_addunlock(sched, ci->hydro.super->hydro.rt_in, t_rt_inject); } - scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_out); + scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_ghost1); } } else /*(ci->nodeID != nodeID) */ { @@ -2386,6 +2440,18 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, cj->hydro.super->stars.stars_out); } + if (with_sink) { + + scheduler_addunlock(sched, cj->hydro.super->sinks.drift, + t_sink_formation); + scheduler_addunlock(sched, cj->hydro.super->hydro.drift, + t_sink_formation); + scheduler_addunlock(sched, cj->hydro.super->sinks.sink_in, + t_sink_formation); + scheduler_addunlock(sched, t_sink_formation, + cj->hydro.super->hydro.sink_formation); + } + if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { scheduler_addunlock(sched, cj->hydro.super->black_holes.drift, @@ -2432,7 +2498,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, scheduler_addunlock(sched, cj->hydro.super->hydro.rt_in, t_rt_inject); } - scheduler_addunlock(sched, t_rt_inject, cj->super->hydro.rt_out); + scheduler_addunlock(sched, t_rt_inject, cj->super->hydro.rt_ghost1); } if (with_timestep_limiter) { @@ -2502,6 +2568,13 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, task_subtype_stars_feedback, flags, 0, ci, NULL); } + /* The sink tasks */ + if (with_sink) { + t_sink_formation = scheduler_addtask( + sched, task_type_sub_self, task_subtype_sink_compute_formation, + flags, 0, ci, NULL); + } + /* The black hole feedback tasks */ if (with_black_holes && bcount_i > 0) { t_bh_density = @@ -2539,6 +2612,9 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, engine_addlink(e, &ci->stars.density, t_star_density); engine_addlink(e, &ci->stars.feedback, t_star_feedback); } + if (with_sink) { + engine_addlink(e, &ci->sinks.compute_formation, t_sink_formation); + } if (with_black_holes && bcount_i > 0) { engine_addlink(e, &ci->black_holes.density, t_bh_density); engine_addlink(e, &ci->black_holes.swallow, t_bh_swallow); @@ -2595,6 +2671,20 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, ci->hydro.super->stars.stars_out); } + if (with_sink) { + + scheduler_addunlock(sched, ci->hydro.super->sinks.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->hydro.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->hydro.sorts, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->sinks.sink_in, + t_sink_formation); + scheduler_addunlock(sched, t_sink_formation, + ci->hydro.super->hydro.sink_formation); + } + if (with_black_holes && bcount_i > 0) { scheduler_addunlock(sched, ci->hydro.super->black_holes.drift, @@ -2651,7 +2741,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, } else { scheduler_addunlock(sched, ci->hydro.super->hydro.rt_in, t_rt_inject); } - scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_out); + scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_ghost1); } } @@ -2696,6 +2786,13 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, task_subtype_stars_feedback, flags, 0, ci, cj); } + /* The sink tasks */ + if (with_sink) { + t_sink_formation = scheduler_addtask( + sched, task_type_sub_pair, task_subtype_sink_compute_formation, + flags, 0, ci, cj); + } + /* The black hole feedback tasks */ if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { t_bh_density = @@ -2733,6 +2830,10 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, engine_addlink(e, &ci->stars.feedback, t_star_feedback); engine_addlink(e, &cj->stars.feedback, t_star_feedback); } + if (with_sink) { + engine_addlink(e, &ci->sinks.compute_formation, t_sink_formation); + engine_addlink(e, &cj->sinks.compute_formation, t_sink_formation); + } if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { engine_addlink(e, &ci->black_holes.density, t_bh_density); engine_addlink(e, &cj->black_holes.density, t_bh_density); @@ -2797,6 +2898,15 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, } } + if (with_sink) { + scheduler_addunlock(sched, ci->hydro.super->hydro.sorts, + t_sink_formation); + if (ci->hydro.super != cj->hydro.super) { + scheduler_addunlock(sched, cj->hydro.super->hydro.sorts, + t_sink_formation); + } + } + if (ci->nodeID == nodeID) { scheduler_addunlock(sched, t_force, ci->hydro.super->hydro.end_force); @@ -2818,6 +2928,18 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, ci->hydro.super->stars.stars_out); } + if (with_sink) { + + scheduler_addunlock(sched, ci->hydro.super->sinks.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->hydro.drift, + t_sink_formation); + scheduler_addunlock(sched, ci->hydro.super->sinks.sink_in, + t_sink_formation); + scheduler_addunlock(sched, t_sink_formation, + ci->hydro.super->hydro.sink_formation); + } + if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { scheduler_addunlock(sched, ci->hydro.super->black_holes.drift, @@ -2877,7 +2999,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, scheduler_addunlock(sched, ci->hydro.super->hydro.rt_in, t_rt_inject); } - scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_out); + scheduler_addunlock(sched, t_rt_inject, ci->super->hydro.rt_ghost1); } } else /* ci->nodeID != nodeID */ { @@ -2915,6 +3037,17 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, scheduler_addunlock(sched, t_star_feedback, cj->hydro.super->stars.stars_out); } + if (with_sink) { + + scheduler_addunlock(sched, cj->hydro.super->sinks.drift, + t_sink_formation); + scheduler_addunlock(sched, cj->hydro.super->hydro.drift, + t_sink_formation); + scheduler_addunlock(sched, cj->hydro.super->sinks.sink_in, + t_sink_formation); + scheduler_addunlock(sched, t_sink_formation, + cj->hydro.super->hydro.sink_formation); + } if (with_black_holes && (bcount_i > 0 || bcount_j > 0)) { @@ -2961,7 +3094,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, scheduler_addunlock(sched, cj->hydro.super->hydro.rt_in, t_rt_inject); } - scheduler_addunlock(sched, t_rt_inject, cj->super->hydro.rt_out); + scheduler_addunlock(sched, t_rt_inject, cj->super->hydro.rt_ghost1); } if (with_timestep_limiter) { @@ -3000,6 +3133,7 @@ void engine_make_extra_hydroloop_tasks_mapper(void *map_data, int num_elements, } } } + /** * @brief Constructs the top-level pair tasks for the first hydro loop over * neighbours diff --git a/src/engine_marktasks.c b/src/engine_marktasks.c index 4aaf85c5891706418897b0aa86818433961c0ae9..785143d86a66640f80de837e7a5f709ef946ec4c 100644 --- a/src/engine_marktasks.c +++ b/src/engine_marktasks.c @@ -95,6 +95,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements, const int ci_active_black_holes = cell_is_active_black_holes(ci, e); const int ci_active_stars = cell_is_active_stars(ci, e) || (with_star_formation && ci_active_hydro); + const int ci_active_sinks = + cell_is_active_sinks(ci, e) || ci_active_hydro; /* Activate the hydro drift */ if (t_type == task_type_self && t_subtype == task_subtype_density) { @@ -176,6 +178,26 @@ void engine_marktasks_mapper(void *map_data, int num_elements, if (ci_active_stars) scheduler_activate(s, t); } + /* Activate the sink formation */ + else if (t_type == task_type_self && + t_subtype == task_subtype_sink_compute_formation) { + if (ci_active_sinks) { + scheduler_activate(s, t); + cell_activate_drift_part(ci, s); + cell_activate_drift_sink(ci, s); + if (with_timestep_sync) cell_activate_sync_part(ci, s); + } + } + + /* Store current values of dx_max and h_max. */ + else if (t_type == task_type_sub_self && + t_subtype == task_subtype_sink_compute_formation) { + if (ci_active_sinks) { + scheduler_activate(s, t); + cell_activate_subcell_sinks_tasks(ci, NULL, s, with_timestep_sync); + } + } + /* Activate the black hole density */ else if (t_type == task_type_self && t_subtype == task_subtype_bh_density) { @@ -302,6 +324,11 @@ void engine_marktasks_mapper(void *map_data, int num_elements, const int cj_active_stars = cell_is_active_stars(cj, e) || (with_star_formation && cj_active_hydro); + const int ci_active_sinks = + cell_is_active_sinks(ci, e) || ci_active_hydro; + const int cj_active_sinks = + cell_is_active_sinks(cj, e) || cj_active_hydro; + /* Only activate tasks that involve a local active cell. */ if ((t_subtype == task_subtype_density || t_subtype == task_subtype_gradient || @@ -478,6 +505,58 @@ void engine_marktasks_mapper(void *map_data, int num_elements, #endif } + /* Sink formation */ + else if ((t_subtype == task_subtype_sink_compute_formation) && + (ci_active_sinks || cj_active_sinks) && + (ci_nodeID == nodeID || cj_nodeID == nodeID)) { + + scheduler_activate(s, t); + + /* Set the correct sorting flags */ + if (t_type == task_type_pair) { + + /* Do ci */ + if (ci_active_sinks) { + + /* hydro for cj */ + atomic_or(&cj->hydro.requires_sorts, 1 << t->flags); + cj->hydro.dx_max_sort_old = cj->hydro.dx_max_sort; + + /* Activate the drift tasks. */ + if (ci_nodeID == nodeID) cell_activate_drift_sink(ci, s); + if (cj_nodeID == nodeID) cell_activate_drift_part(cj, s); + if (cj_nodeID == nodeID && with_timestep_sync) + cell_activate_sync_part(cj, s); + + /* Check the sorts and activate them if needed. */ + cell_activate_hydro_sorts(cj, t->flags, s); + } + + /* Do cj */ + if (cj_active_sinks) { + + /* hydro for ci */ + atomic_or(&ci->hydro.requires_sorts, 1 << t->flags); + ci->hydro.dx_max_sort_old = ci->hydro.dx_max_sort; + + /* Activate the drift tasks. */ + if (ci_nodeID == nodeID) cell_activate_drift_part(ci, s); + if (cj_nodeID == nodeID) cell_activate_drift_sink(cj, s); + if (ci_nodeID == nodeID && with_timestep_sync) + cell_activate_sync_part(ci, s); + + /* Check the sorts and activate them if needed. */ + cell_activate_hydro_sorts(ci, t->flags, s); + } + } + + /* Store current values of dx_max and h_max. */ + else if (t_type == task_type_sub_pair && + t_subtype == task_subtype_sink_compute_formation) { + cell_activate_subcell_sinks_tasks(ci, cj, s, with_timestep_sync); + } + } + /* RT injection tasks */ else if (t_subtype == task_subtype_rt_inject) { /* We only want to activate the task if the cell is active and is @@ -727,6 +806,18 @@ void engine_marktasks_mapper(void *map_data, int num_elements, #endif } + /* Only interested in sink_compute_formation tasks as of here. */ + else if (t->subtype == task_subtype_sink_compute_formation) { + + /* Too much particle movement? */ + if (cell_need_rebuild_for_sinks_pair(ci, cj)) *rebuild_space = 1; + if (cell_need_rebuild_for_sinks_pair(cj, ci)) *rebuild_space = 1; + +#ifdef WITH_MPI + error("TODO"); +#endif + } + /* Only interested in black hole density tasks as of here. */ else if (t->subtype == task_subtype_bh_density) { @@ -933,7 +1024,7 @@ void engine_marktasks_mapper(void *map_data, int num_elements, } /* Gravity stuff ? */ - else if (t_type == task_type_grav_down || t_type == task_type_grav_mesh || + else if (t_type == task_type_grav_down || t_type == task_type_grav_long_range || t_type == task_type_init_grav || t_type == task_type_init_grav_out || @@ -1029,8 +1120,8 @@ void engine_marktasks_mapper(void *map_data, int num_elements, scheduler_activate(s, t); } - /* Radiative transfer ghost out */ - else if (t->type == task_type_rt_out) { + /* Radiative transfer ghost out and others*/ + else if (t->type == task_type_rt_out || t->type == task_type_rt_ghost1) { if (cell_is_active_hydro(t->ci, e) || cell_is_active_stars(t->ci, e)) scheduler_activate(s, t); } diff --git a/src/engine_redistribute.c b/src/engine_redistribute.c index a7d954655f6dce4b18d16814106dde3098785c30..ddd86886c16af16395d972b040e28386cb356ad0 100644 --- a/src/engine_redistribute.c +++ b/src/engine_redistribute.c @@ -615,7 +615,8 @@ void engine_redistribute(struct engine *e) { nr_gparts -= 1; /* Swap the particle */ - memswap(&s->gparts[k], &s->gparts[nr_gparts], sizeof(struct gpart)); + memswap_unaligned(&s->gparts[k], &s->gparts[nr_gparts], + sizeof(struct gpart)); /* Swap the link with part/spart */ if (s->gparts[k].type == swift_type_gas) { diff --git a/src/feedback/EAGLE/feedback.c b/src/feedback/EAGLE/feedback.c index 1b6a4a4abee396625199e0d4ebc61dd5d1735c65..df01c1ddddfc4a53e4308a5eb7ce97e72995ea68 100644 --- a/src/feedback/EAGLE/feedback.c +++ b/src/feedback/EAGLE/feedback.c @@ -250,8 +250,8 @@ double eagle_feedback_energy_fraction(const struct spart* sp, /* Choose either the birth properties or current properties */ const double nH = - props->use_birth_props_for_feedback ? n_birth_cgs : ngb_nH_cgs; - const double Z = props->use_birth_props_for_feedback ? Z_birth : ngb_Z; + props->use_birth_density_for_f_th ? n_birth_cgs : ngb_nH_cgs; + const double Z = props->use_birth_Z_for_f_th ? Z_birth : ngb_Z; /* Calculate f_E */ const double Z_term = pow(max(Z, 1e-6) / Z_0, n_Z); @@ -273,6 +273,8 @@ double eagle_feedback_energy_fraction(const struct spart* sp, * @param dt Length of time-step in internal units. * @param ngb_gas_mass Total un-weighted mass in the star's kernel (internal * units) + * @param num_gas_ngbs Total (integer) number of gas neighbours within the + * star's kernel. * @param ngb_nH_cgs Hydrogen number density of the gas surrounding the star * (physical cgs units). * @param ngb_Z Metallicity (metal mass fraction) of the gas surrounding the @@ -285,8 +287,8 @@ double eagle_feedback_energy_fraction(const struct spart* sp, */ INLINE static void compute_SNII_feedback( struct spart* sp, const double star_age, const double dt, - const float ngb_gas_mass, const double ngb_nH_cgs, const double ngb_Z, - const struct feedback_props* feedback_props, + const float ngb_gas_mass, const int num_gas_ngbs, const double ngb_nH_cgs, + const double ngb_Z, const struct feedback_props* feedback_props, const double min_dying_mass_Msun, const double max_dying_mass_Msun) { /* Are we sampling the delay function or using a fixed delay? */ @@ -329,13 +331,14 @@ INLINE static void compute_SNII_feedback( } /* Abort if there are no SNe exploding this step */ - if (N_SNe == 0.) return; + if (N_SNe <= 0.) return; /* Conversion factor from T to internal energy */ const double conv_factor = feedback_props->temp_to_u_factor; - /* Calculate the default heating probability */ + /* Calculate the default heating probability (accounting for round-off) */ double prob = f_E * E_SNe * N_SNe / (conv_factor * delta_T * ngb_gas_mass); + prob = max(prob, 0.0); /* Calculate the change in internal energy of the gas particles that get * heated */ @@ -370,6 +373,7 @@ INLINE static void compute_SNII_feedback( sp->number_of_SNII_events++; sp->feedback_data.to_distribute.SNII_heating_probability = prob; sp->feedback_data.to_distribute.SNII_delta_u = delta_u; + sp->number_of_heating_events += (prob * num_gas_ngbs); } } @@ -856,6 +860,7 @@ INLINE static void evolve_AGB(const double log10_min_mass, * @param dt length of current timestep */ void compute_stellar_evolution(const struct feedback_props* feedback_props, + const struct phys_const* phys_const, const struct cosmology* cosmo, struct spart* sp, const struct unit_system* us, const double age, const double dt) { @@ -870,11 +875,9 @@ void compute_stellar_evolution(const struct feedback_props* feedback_props, #endif /* Convert dt and stellar age from internal units to Gyr. */ - const double Gyr_in_cgs = 1e9 * 365.25 * 24. * 3600.; - const double time_to_cgs = units_cgs_conversion_factor(us, UNIT_CONV_TIME); - const double conversion_factor = time_to_cgs / Gyr_in_cgs; - const double dt_Gyr = dt * conversion_factor; - const double star_age_Gyr = age * conversion_factor; + const double Gyr_inv = 1. / (phys_const->const_year * 1e9); + const double dt_Gyr = dt * Gyr_inv; + const double star_age_Gyr = age * Gyr_inv; /* Get the birth mass of the star */ const double M_init = sp->mass_init; @@ -891,6 +894,7 @@ void compute_stellar_evolution(const struct feedback_props* feedback_props, /* Properties collected in the stellar density loop. */ const float ngb_gas_mass = sp->feedback_data.to_collect.ngb_mass; + const int num_gas_ngbs = sp->feedback_data.to_collect.num_ngbs; const float ngb_gas_Z = sp->feedback_data.to_collect.ngb_Z; const float ngb_gas_rho = sp->feedback_data.to_collect.ngb_rho; const float ngb_gas_phys_nH_cgs = @@ -943,9 +947,9 @@ void compute_stellar_evolution(const struct feedback_props* feedback_props, /* Compute properties of the stochastic SNII feedback model. */ if (feedback_props->with_SNII_feedback) { - compute_SNII_feedback(sp, age, dt, ngb_gas_mass, ngb_gas_phys_nH_cgs, - ngb_gas_Z, feedback_props, min_dying_mass_Msun, - max_dying_mass_Msun); + compute_SNII_feedback(sp, age, dt, ngb_gas_mass, num_gas_ngbs, + ngb_gas_phys_nH_cgs, ngb_gas_Z, feedback_props, + min_dying_mass_Msun, max_dying_mass_Msun); } /* Integration interval is zero - this can happen if minimum and maximum @@ -1014,8 +1018,6 @@ void feedback_props_init(struct feedback_props* fp, const struct hydro_props* hydro_props, const struct cosmology* cosmo) { - const double Gyr_in_cgs = 1.0e9 * 365.25 * 24. * 3600.; - /* Main operation modes ------------------------------------------------- */ fp->with_SNII_feedback = @@ -1064,7 +1066,7 @@ void feedback_props_init(struct feedback_props* fp, /* Set the delay time before SNII occur */ fp->SNII_wind_delay = parser_get_param_double(params, "EAGLEFeedback:SNII_wind_delay_Gyr") * - Gyr_in_cgs / units_cgs_conversion_factor(us, UNIT_CONV_TIME); + phys_const->const_year * 1e9; } /* Read the temperature change to use in stochastic heating */ @@ -1115,8 +1117,10 @@ void feedback_props_init(struct feedback_props* fp, } /* Are we using the stars' birth properties or at feedback time? */ - fp->use_birth_props_for_feedback = parser_get_param_int( - params, "EAGLEFeedback:SNII_energy_fraction_use_birth_props"); + fp->use_birth_density_for_f_th = parser_get_param_int( + params, "EAGLEFeedback:SNII_energy_fraction_use_birth_density"); + fp->use_birth_Z_for_f_th = parser_get_param_int( + params, "EAGLEFeedback:SNII_energy_fraction_use_birth_metallicity"); /* Properties of the SNII enrichment model -------------------------------- */ @@ -1191,7 +1195,7 @@ void feedback_props_init(struct feedback_props* fp, fp->stellar_evolution_age_cut = parser_get_param_double(params, "EAGLEFeedback:stellar_evolution_age_cut_Gyr") * - Gyr_in_cgs / units_cgs_conversion_factor(us, UNIT_CONV_TIME); + phys_const->const_year * 1e9; fp->stellar_evolution_sampling_rate = parser_get_param_double( params, "EAGLEFeedback:stellar_evolution_sampling_rate"); diff --git a/src/feedback/EAGLE/feedback.h b/src/feedback/EAGLE/feedback.h index c8cd66b30ca964cad5fe1cb33f0c20d4388763d1..a5530bb9518db929d0154d751699c608c8d004e4 100644 --- a/src/feedback/EAGLE/feedback.h +++ b/src/feedback/EAGLE/feedback.h @@ -29,6 +29,7 @@ #include <strings.h> void compute_stellar_evolution(const struct feedback_props* feedback_props, + const struct phys_const* phys_const, const struct cosmology* cosmo, struct spart* sp, const struct unit_system* us, const double age, const double dt); @@ -74,6 +75,7 @@ __attribute__((always_inline)) INLINE static void feedback_init_spart( sp->feedback_data.to_collect.ngb_mass = 0.f; sp->feedback_data.to_collect.ngb_rho = 0.f; sp->feedback_data.to_collect.ngb_Z = 0.f; + sp->feedback_data.to_collect.num_ngbs = 0; } /** @@ -203,8 +205,8 @@ __attribute__((always_inline)) INLINE static void feedback_evolve_spart( /* Compute amount of enrichment and feedback that needs to be done in this * step */ - compute_stellar_evolution(feedback_props, cosmo, sp, us, star_age_beg_step, - dt); + compute_stellar_evolution(feedback_props, phys_const, cosmo, sp, us, + star_age_beg_step, dt); /* Decrease star mass by amount of mass distributed to gas neighbours */ sp->mass -= sp->feedback_data.to_distribute.mass; diff --git a/src/feedback/EAGLE/feedback_iact.h b/src/feedback/EAGLE/feedback_iact.h index 382588b25b5c219b391944840f3c0ca041b0d8d5..1684e910512ffcf5cb8a9561e376b4c5e2f1c173 100644 --- a/src/feedback/EAGLE/feedback_iact.h +++ b/src/feedback/EAGLE/feedback_iact.h @@ -60,6 +60,9 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, /* Add mass of pj to neighbour mass of si */ si->feedback_data.to_collect.ngb_mass += mj; + /* Update counter of total (integer) neighbours */ + si->feedback_data.to_collect.num_ngbs++; + /* Contribution to the star's surrounding gas density */ si->feedback_data.to_collect.ngb_rho += mj * wi; diff --git a/src/feedback/EAGLE/feedback_properties.h b/src/feedback/EAGLE/feedback_properties.h index b32d2215dcab9312712c9c713f4d476fbeb3bc35..2a75e8f42d24902f79acc01199f6f091add55b74 100644 --- a/src/feedback/EAGLE/feedback_properties.h +++ b/src/feedback/EAGLE/feedback_properties.h @@ -265,9 +265,13 @@ struct feedback_props { */ double n_Z; - /*! Are we using the birth properties to compute f_th or the properties at + /*! Are we using the birth density to compute f_th or the properties at * feedback time? */ - int use_birth_props_for_feedback; + int use_birth_density_for_f_th; + + /*! Are we using the birth metallicity to compute f_th or the properties at + * feedback time? */ + int use_birth_Z_for_f_th; /* ------------ Enrichment sampling properties ------------ */ diff --git a/src/feedback/EAGLE/feedback_struct.h b/src/feedback/EAGLE/feedback_struct.h index 5d626cd1dbb58782ea743521e56cad8cd186a6b4..bc3a2d44d71e5e48060b0c8e6d05d753a2866a9d 100644 --- a/src/feedback/EAGLE/feedback_struct.h +++ b/src/feedback/EAGLE/feedback_struct.h @@ -44,12 +44,15 @@ struct feedback_spart_data { /*! Total mass (unweighted) of neighbouring gas particles */ float ngb_mass; + /*! Integer number of neighbouring gas particles */ + int num_ngbs; + /*! SPH-weighted density of the neighbouring gas particles (internal * comoving units) */ float ngb_rho; - /*! SPH-weighted metallicity of the neighbouring gas particles (internal - * units) */ + /*! SPH-weighted metallicity of the neighbouring gas particles + * (dimensionless) */ float ngb_Z; } to_collect; diff --git a/src/gravity.c b/src/gravity.c index 8c013139aa6771342e598bd543558bfa0ffb98fa..b32f95c656a4d37c84faf3c95b64e4bd0b934b18 100644 --- a/src/gravity.c +++ b/src/gravity.c @@ -726,15 +726,18 @@ void gravity_exact_force_check(struct space *s, const struct engine *e, "%18lld %16.8e %16.8e %16.8e %16.8e %16.8e %16.8e %16.8e %16.8e " "%16.8e %16.8e %16.8e %16.8e %16.8e %16.8e %16.8e %16.8e %16.8e " "%16.8e %16.8e %16.8e %16lld %16lld %16lld %16lld\n", - id, gpi->x[0], gpi->x[1], gpi->x[2], gpi->a_grav[0], - gpi->a_grav[1], gpi->a_grav[2], - gravity_get_comoving_potential(gpi), gpi->a_grav_PM[0], - gpi->a_grav_PM[1], gpi->a_grav_PM[2], gpi->potential_PM, - gpi->a_grav_p2p[0], gpi->a_grav_p2p[1], gpi->a_grav_p2p[2], - gpi->a_grav_m2p[0], gpi->a_grav_m2p[1], gpi->a_grav_m2p[2], - gpi->a_grav_m2l[0], gpi->a_grav_m2l[1], gpi->a_grav_m2l[2], - gpi->num_interacted_p2p, gpi->num_interacted_m2p, - gpi->num_interacted_m2l, gpi->num_interacted_pm); + id, gpi->x[0], gpi->x[1], gpi->x[2], + gpi->a_grav[0] + gpi->a_grav_mesh[0], + gpi->a_grav[1] + gpi->a_grav_mesh[1], + gpi->a_grav[2] + gpi->a_grav_mesh[2], + gravity_get_comoving_potential(gpi), gpi->a_grav_mesh[0], + gpi->a_grav_mesh[1], gpi->a_grav_mesh[2], + gravity_get_comoving_mesh_potential(gpi), gpi->a_grav_p2p[0], + gpi->a_grav_p2p[1], gpi->a_grav_p2p[2], gpi->a_grav_m2p[0], + gpi->a_grav_m2p[1], gpi->a_grav_m2p[2], gpi->a_grav_m2l[0], + gpi->a_grav_m2l[1], gpi->a_grav_m2l[2], gpi->num_interacted_p2p, + gpi->num_interacted_m2p, gpi->num_interacted_m2l, + gpi->num_interacted_pm); } } diff --git a/src/gravity.h b/src/gravity.h index 4e255d2cbaaae012ab1282c82c8f6f15410e6b4b..967a88afead3c6e1093f8d65a8de2762c33856c8 100644 --- a/src/gravity.h +++ b/src/gravity.h @@ -30,10 +30,7 @@ /* Import the right functions */ #if defined(DEFAULT_GRAVITY) #include "./gravity/Default/gravity.h" -#define GRAVITY_IMPLEMENTATION "Default (no potential)" -#elif defined(POTENTIAL_GRAVITY) -#include "./gravity/Potential/gravity.h" -#define GRAVITY_IMPLEMENTATION "With potential calculation" +#define GRAVITY_IMPLEMENTATION "Basic scheme" #elif defined(MULTI_SOFTENING_GRAVITY) #include "./gravity/MultiSoftening/gravity.h" #define GRAVITY_IMPLEMENTATION "With per-particle softening" diff --git a/src/gravity/Default/gravity.h b/src/gravity/Default/gravity.h index 09f32f9587500afe4cb40116ab7d03054887dc1d..06ebc522a977c7ccdcd870fe827f4939a1d34433 100644 --- a/src/gravity/Default/gravity.h +++ b/src/gravity/Default/gravity.h @@ -56,35 +56,66 @@ __attribute__((always_inline)) INLINE static float gravity_get_softening( } /** - * @brief Add a contribution to this particle's potential. + * @brief Add a contribution to this particle's potential from the tree. * - * Here we do nothing as this version does not accumulate potential. + * @param gp The particle. + * @param pot The contribution to add. + */ +__attribute__((always_inline)) INLINE static void +gravity_add_comoving_potential(struct gpart* restrict gp, const float pot) { + +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential += pot; +#endif +} + +/** + * @brief Add a contribution to this particle's potential from the mesh. * * @param gp The particle. * @param pot The contribution to add. */ __attribute__((always_inline)) INLINE static void -gravity_add_comoving_potential(struct gpart* restrict gp, float pot) {} +gravity_add_comoving_mesh_potential(struct gpart* restrict gp, + const float pot) { + +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential_mesh += pot; +#endif +} /** * @brief Returns the comoving potential of a particle. * - * This returns 0 as this flavour of gravity does not compute the - * particles' potential. - * * @param gp The particle of interest */ __attribute__((always_inline)) INLINE static float gravity_get_comoving_potential(const struct gpart* restrict gp) { +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + return gp->potential; +#else return 0.f; +#endif } /** - * @brief Returns the physical potential of a particle + * @brief Returns the comoving potential of a particle. * - * This returns 0 as this flavour of gravity does not compute the - * particles' potential. + * @param gp The particle of interest + */ +__attribute__((always_inline)) INLINE static float +gravity_get_comoving_mesh_potential(const struct gpart* restrict gp) { + +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + return gp->potential_mesh; +#else + return 0.f; +#endif +} + +/** + * @brief Returns the physical potential of a particle * * @param gp The particle of interest. * @param cosmo The cosmological model. @@ -93,7 +124,11 @@ __attribute__((always_inline)) INLINE static float gravity_get_physical_potential(const struct gpart* restrict gp, const struct cosmology* cosmo) { +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + return gp->potential * cosmo->a_inv; +#else return 0.f; +#endif } /** @@ -117,6 +152,11 @@ gravity_compute_timestep_self(const struct gpart* const gp, float a_phys_y = gp->a_grav[1] * cosmo->a_factor_grav_accel; float a_phys_z = gp->a_grav[2] * cosmo->a_factor_grav_accel; + /* Get physical acceleration (gravity mesh contribution) */ + a_phys_x += gp->a_grav_mesh[0] * cosmo->a_factor_grav_accel; + a_phys_y += gp->a_grav_mesh[1] * cosmo->a_factor_grav_accel; + a_phys_z += gp->a_grav_mesh[2] * cosmo->a_factor_grav_accel; + /* Get physical acceleration (hydro contribution) */ a_phys_x += a_hydro[0] * cosmo->a_factor_hydro_accel; a_phys_y += a_hydro[1] * cosmo->a_factor_hydro_accel; @@ -151,12 +191,15 @@ __attribute__((always_inline)) INLINE static void gravity_init_gpart( gp->a_grav[1] = 0.f; gp->a_grav[2] = 0.f; + /* Zero the potential */ +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential = 0.f; +#endif + #ifdef SWIFT_GRAVITY_FORCE_CHECKS - gp->potential_PM = 0.f; /* Track accelerations of each component. */ for (int i = 0; i < 3; i++) { - gp->a_grav_PM[i] = 0.f; gp->a_grav_p2p[i] = 0.f; gp->a_grav_m2p[i] = 0.f; gp->a_grav_m2l[i] = 0.f; @@ -194,13 +237,24 @@ __attribute__((always_inline)) INLINE static void gravity_end_force( struct gpart* gp, const float const_G, const float potential_normalisation, const int periodic, const int with_self_gravity) { + /* Apply the periodic correction to the peculiar potential */ +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + if (periodic) gp->potential += potential_normalisation; +#endif + + /* Add back the long-range forces + * Note that the mesh gravity had been multiplied by G. We undo this here. */ + float a_grav[3]; + a_grav[0] = gp->a_grav[0] + gp->a_grav_mesh[0] / const_G; + a_grav[1] = gp->a_grav[1] + gp->a_grav_mesh[1] / const_G; + a_grav[2] = gp->a_grav[2] + gp->a_grav_mesh[2] / const_G; + /* Record the norm of the acceleration for the adaptive opening criteria. * Will always be an (active) timestep behind. */ - gp->old_a_grav_norm = gp->a_grav[0] * gp->a_grav[0] + - gp->a_grav[1] * gp->a_grav[1] + - gp->a_grav[2] * gp->a_grav[2]; + const float old_a_grav_norm = + a_grav[0] * a_grav[0] + a_grav[1] * a_grav[1] + a_grav[2] * a_grav[2]; - gp->old_a_grav_norm = sqrtf(gp->old_a_grav_norm); + gp->old_a_grav_norm = sqrtf(old_a_grav_norm); #ifdef SWIFT_DEBUG_CHECKS if (with_self_gravity && gp->old_a_grav_norm == 0.f) @@ -211,11 +265,17 @@ __attribute__((always_inline)) INLINE static void gravity_end_force( gp->a_grav[0] *= const_G; gp->a_grav[1] *= const_G; gp->a_grav[2] *= const_G; +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential *= const_G; +#endif + + /* Add the mesh contribution to the potential */ +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential += gp->potential_mesh; +#endif #ifdef SWIFT_GRAVITY_FORCE_CHECKS - gp->potential_PM *= const_G; for (int i = 0; i < 3; i++) { - gp->a_grav_PM[i] *= const_G; gp->a_grav_p2p[i] *= const_G; gp->a_grav_m2p[i] *= const_G; gp->a_grav_m2l[i] *= const_G; diff --git a/src/gravity/Default/gravity_debug.h b/src/gravity/Default/gravity_debug.h index dce038c58e1769446861bdf6c9a2a44415642c68..ba79c95b707d4b6b5a0793753573a852a5ee7a70 100644 --- a/src/gravity/Default/gravity_debug.h +++ b/src/gravity/Default/gravity_debug.h @@ -26,6 +26,9 @@ __attribute__((always_inline)) INLINE static void gravity_debug_particle( "x=[%.5e,%.5e,%.5e], v_full=[%.5e,%.5e,%.5e], a=[%.5e,%.5e,%.5e]\n", p->mass, p->time_bin, p->x[0], p->x[1], p->x[2], p->v_full[0], p->v_full[1], p->v_full[2], p->a_grav[0], p->a_grav[1], p->a_grav[2]); +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + printf("pot=%e\n", p->potential); +#endif #ifdef SWIFT_DEBUG_CHECKS printf("num_interacted=%lld ti_drift=%lld ti_kick=%lld\n", p->num_interacted, p->ti_drift, p->ti_kick); diff --git a/src/gravity/Default/gravity_io.h b/src/gravity/Default/gravity_io.h index fb828b2239bcdf998f6d3e20123ad44400e0fa8c..4ae856606ef2dd83be070837becd62ef96abd233 100644 --- a/src/gravity/Default/gravity_io.h +++ b/src/gravity/Default/gravity_io.h @@ -20,15 +20,16 @@ #define SWIFT_DEFAULT_GRAVITY_IO_H #include "io_properties.h" +#include "kick.h" INLINE static void convert_gpart_pos(const struct engine* e, - const struct gpart* gp, double* ret) { + const struct gpart* gp, double ret[3]) { const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(gp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(gp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(gp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(gp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(gp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(gp->x[2], 0.0, s->dim[2]); } else { ret[0] = gp->x[0]; ret[1] = gp->x[1]; @@ -37,31 +38,34 @@ INLINE static void convert_gpart_pos(const struct engine* e, } INLINE static void convert_gpart_vel(const struct engine* e, - const struct gpart* gp, float* ret) { + const struct gpart* gp, float ret[3]) { const int with_cosmology = (e->policy & engine_policy_cosmology); const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, gp->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); /* Get time-step since the last kick */ - float dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_beg, ti_current); - dt_kick_grav -= - cosmology_get_grav_kick_factor(cosmo, ti_beg, (ti_beg + ti_end) / 2); - } else { - dt_kick_grav = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; - } + const float dt_kick_grav = + kick_get_grav_kick_dt(ti_beg, ti_current, time_base, with_cosmology, + cosmo) - + kick_get_grav_kick_dt(ti_beg, (ti_beg + ti_end) / 2, time_base, + with_cosmology, cosmo); /* Extrapolate the velocites to the current time */ ret[0] = gp->v_full[0] + gp->a_grav[0] * dt_kick_grav; ret[1] = gp->v_full[1] + gp->a_grav[1] * dt_kick_grav; ret[2] = gp->v_full[2] + gp->a_grav[2] * dt_kick_grav; + /* Extrapolate the velocites to the current time (mesh forces) */ + ret[0] += gp->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += gp->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += gp->a_grav_mesh[2] * dt_kick_grav_mesh; + /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; ret[1] *= cosmo->a_inv; diff --git a/src/gravity/Default/gravity_part.h b/src/gravity/Default/gravity_part.h index 41162901cad6d3fd9778f5d4edcf1e4d06ad2573..a1dbfe79f4ca5481cf4d5740c6c36ff0b0eb798f 100644 --- a/src/gravity/Default/gravity_part.h +++ b/src/gravity/Default/gravity_part.h @@ -36,9 +36,22 @@ struct gpart { /*! Particle velocity. */ float v_full[3]; - /*! Particle acceleration. */ + /*! Particle acceleration from the tree. */ float a_grav[3]; + /*! Particle acceleration from the mesh. */ + float a_grav_mesh[3]; + +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + + /*! Gravitational potential from the tree.*/ + float potential; + + /*! Gravitational potential from the mesh.*/ + float potential_mesh; + +#endif + /*! Particle mass. */ float mass; @@ -73,6 +86,9 @@ struct gpart { /* Time of the last kick */ integertime_t ti_kick; + /* Time of the last mesh kick */ + integertime_t ti_kick_mesh; + /* Has this particle been initialised? */ int initialised; @@ -82,12 +98,6 @@ struct gpart { #ifdef SWIFT_GRAVITY_FORCE_CHECKS - /*! Acceleration taken from the mesh only */ - float a_grav_PM[3]; - - /*! Potential taken from the mesh only */ - float potential_PM; - /* Acceleration taken from each component of the tree */ float a_grav_p2p[3]; float a_grav_m2p[3]; @@ -107,7 +117,6 @@ struct gpart { long long num_interacted_p2p; long long num_interacted_pm; #endif - -} SWIFT_STRUCT_ALIGN; +}; #endif /* SWIFT_DEFAULT_GRAVITY_PART_H */ diff --git a/src/gravity/MultiSoftening/gravity.h b/src/gravity/MultiSoftening/gravity.h index 8cd09a168d6984d5a60be2522638f373d11b1c74..025d99de50aab60e26156439b80a32b08071e59e 100644 --- a/src/gravity/MultiSoftening/gravity.h +++ b/src/gravity/MultiSoftening/gravity.h @@ -52,15 +52,32 @@ __attribute__((always_inline)) INLINE static float gravity_get_softening( } /** - * @brief Add a contribution to this particle's potential. + * @brief Add a contribution to this particle's potential from the tree. * * @param gp The particle. * @param pot The contribution to add. */ __attribute__((always_inline)) INLINE static void -gravity_add_comoving_potential(struct gpart* restrict gp, float pot) { +gravity_add_comoving_potential(struct gpart* restrict gp, const float pot) { +#ifndef SWIFT_GRAVITY_NO_POTENTIAL gp->potential += pot; +#endif +} + +/** + * @brief Add a contribution to this particle's potential from the mesh. + * + * @param gp The particle. + * @param pot The contribution to add. + */ +__attribute__((always_inline)) INLINE static void +gravity_add_comoving_mesh_potential(struct gpart* restrict gp, + const float pot) { + +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential_mesh += pot; +#endif } /** @@ -71,7 +88,26 @@ gravity_add_comoving_potential(struct gpart* restrict gp, float pot) { __attribute__((always_inline)) INLINE static float gravity_get_comoving_potential(const struct gpart* restrict gp) { +#ifndef SWIFT_GRAVITY_NO_POTENTIAL return gp->potential; +#else + return 0.f; +#endif +} + +/** + * @brief Returns the comoving potential of a particle. + * + * @param gp The particle of interest + */ +__attribute__((always_inline)) INLINE static float +gravity_get_comoving_mesh_potential(const struct gpart* restrict gp) { + +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + return gp->potential_mesh; +#else + return 0.f; +#endif } /** @@ -84,7 +120,11 @@ __attribute__((always_inline)) INLINE static float gravity_get_physical_potential(const struct gpart* restrict gp, const struct cosmology* cosmo) { +#ifndef SWIFT_GRAVITY_NO_POTENTIAL return gp->potential * cosmo->a_inv; +#else + return 0.f; +#endif } /** @@ -108,6 +148,11 @@ gravity_compute_timestep_self(const struct gpart* const gp, float a_phys_y = gp->a_grav[1] * cosmo->a_factor_grav_accel; float a_phys_z = gp->a_grav[2] * cosmo->a_factor_grav_accel; + /* Get physical acceleration (gravity mesh contribution) */ + a_phys_x += gp->a_grav_mesh[0] * cosmo->a_factor_grav_accel; + a_phys_y += gp->a_grav_mesh[1] * cosmo->a_factor_grav_accel; + a_phys_z += gp->a_grav_mesh[2] * cosmo->a_factor_grav_accel; + /* Get physical acceleration (hydro contribution) */ a_phys_x += a_hydro[0] * cosmo->a_factor_hydro_accel; a_phys_y += a_hydro[1] * cosmo->a_factor_hydro_accel; @@ -141,14 +186,16 @@ __attribute__((always_inline)) INLINE static void gravity_init_gpart( gp->a_grav[0] = 0.f; gp->a_grav[1] = 0.f; gp->a_grav[2] = 0.f; + + /* Zero the potential */ +#ifndef SWIFT_GRAVITY_NO_POTENTIAL gp->potential = 0.f; +#endif #ifdef SWIFT_GRAVITY_FORCE_CHECKS - gp->potential_PM = 0.f; /* Track accelerations of each component. */ for (int i = 0; i < 3; i++) { - gp->a_grav_PM[i] = 0.f; gp->a_grav_p2p[i] = 0.f; gp->a_grav_m2p[i] = 0.f; gp->a_grav_m2l[i] = 0.f; @@ -187,15 +234,23 @@ __attribute__((always_inline)) INLINE static void gravity_end_force( const int periodic, const int with_self_gravity) { /* Apply the periodic correction to the peculiar potential */ +#ifndef SWIFT_GRAVITY_NO_POTENTIAL if (periodic) gp->potential += potential_normalisation; +#endif + + /* Add back the long-range forces + * Note that the mesh gravity had been multiplied by G. We undo this here. */ + float a_grav[3]; + a_grav[0] = gp->a_grav[0] + gp->a_grav_mesh[0] / const_G; + a_grav[1] = gp->a_grav[1] + gp->a_grav_mesh[1] / const_G; + a_grav[2] = gp->a_grav[2] + gp->a_grav_mesh[2] / const_G; /* Record the norm of the acceleration for the adaptive opening criteria. * Will always be an (active) timestep behind. */ - gp->old_a_grav_norm = gp->a_grav[0] * gp->a_grav[0] + - gp->a_grav[1] * gp->a_grav[1] + - gp->a_grav[2] * gp->a_grav[2]; + const float old_a_grav_norm = + a_grav[0] * a_grav[0] + a_grav[1] * a_grav[1] + a_grav[2] * a_grav[2]; - gp->old_a_grav_norm = sqrtf(gp->old_a_grav_norm); + gp->old_a_grav_norm = sqrtf(old_a_grav_norm); #ifdef SWIFT_DEBUG_CHECKS if (with_self_gravity && gp->old_a_grav_norm == 0.f) @@ -206,12 +261,17 @@ __attribute__((always_inline)) INLINE static void gravity_end_force( gp->a_grav[0] *= const_G; gp->a_grav[1] *= const_G; gp->a_grav[2] *= const_G; +#ifndef SWIFT_GRAVITY_NO_POTENTIAL gp->potential *= const_G; +#endif + + /* Add the mesh contribution to the potential */ +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential += gp->potential_mesh; +#endif #ifdef SWIFT_GRAVITY_FORCE_CHECKS - gp->potential_PM *= const_G; for (int i = 0; i < 3; i++) { - gp->a_grav_PM[i] *= const_G; gp->a_grav_p2p[i] *= const_G; gp->a_grav_m2p[i] *= const_G; gp->a_grav_m2l[i] *= const_G; diff --git a/src/gravity/MultiSoftening/gravity_debug.h b/src/gravity/MultiSoftening/gravity_debug.h index 7deea93f385d77871ed4bb28b881d7e93ce59436..a0fe978bf61643adb490268ba369b1f63e10a542 100644 --- a/src/gravity/MultiSoftening/gravity_debug.h +++ b/src/gravity/MultiSoftening/gravity_debug.h @@ -24,10 +24,13 @@ __attribute__((always_inline)) INLINE static void gravity_debug_particle( printf( "mass=%.3e time_bin=%d\n" "x=[%.5e,%.5e,%.5e], v_full=[%.5e,%.5e,%.5e], type=%d, " - "a=[%.5e,%.5e,%.5e], pot=%.5e\n", + "a=[%.5e,%.5e,%.5e]\n", p->mass, p->time_bin, p->x[0], p->x[1], p->x[2], p->v_full[0], p->v_full[1], p->v_full[2], (int)p->type, p->a_grav[0], p->a_grav[1], - p->a_grav[2], p->potential); + p->a_grav[2]); +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + printf("pot=%e\n", p->potential); +#endif #ifdef SWIFT_DEBUG_CHECKS printf("num_interacted=%lld ti_drift=%lld ti_kick=%lld\n", p->num_interacted, p->ti_drift, p->ti_kick); diff --git a/src/gravity/MultiSoftening/gravity_io.h b/src/gravity/MultiSoftening/gravity_io.h index 1c6f254427de9bf55fc77ca28a7e19090e86de19..b58a1a1650cfd31c687bf8b34a22d3220172684f 100644 --- a/src/gravity/MultiSoftening/gravity_io.h +++ b/src/gravity/MultiSoftening/gravity_io.h @@ -20,15 +20,16 @@ #define SWIFT_MULTI_SOFTENING_GRAVITY_IO_H #include "io_properties.h" +#include "kick.h" INLINE static void convert_gpart_pos(const struct engine* e, - const struct gpart* gp, double* ret) { + const struct gpart* gp, double ret[3]) { const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(gp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(gp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(gp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(gp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(gp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(gp->x[2], 0.0, s->dim[2]); } else { ret[0] = gp->x[0]; ret[1] = gp->x[1]; @@ -37,31 +38,34 @@ INLINE static void convert_gpart_pos(const struct engine* e, } INLINE static void convert_gpart_vel(const struct engine* e, - const struct gpart* gp, float* ret) { + const struct gpart* gp, float ret[3]) { const int with_cosmology = (e->policy & engine_policy_cosmology); const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, gp->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); /* Get time-step since the last kick */ - float dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_beg, ti_current); - dt_kick_grav -= - cosmology_get_grav_kick_factor(cosmo, ti_beg, (ti_beg + ti_end) / 2); - } else { - dt_kick_grav = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; - } + const float dt_kick_grav = + kick_get_grav_kick_dt(ti_beg, ti_current, time_base, with_cosmology, + cosmo) - + kick_get_grav_kick_dt(ti_beg, (ti_beg + ti_end) / 2, time_base, + with_cosmology, cosmo); /* Extrapolate the velocites to the current time */ ret[0] = gp->v_full[0] + gp->a_grav[0] * dt_kick_grav; ret[1] = gp->v_full[1] + gp->a_grav[1] * dt_kick_grav; ret[2] = gp->v_full[2] + gp->a_grav[2] * dt_kick_grav; + /* Extrapolate the velocites to the current time (mesh forces) */ + ret[0] += gp->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += gp->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += gp->a_grav_mesh[2] * dt_kick_grav_mesh; + /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; ret[1] *= cosmo->a_inv; diff --git a/src/gravity/MultiSoftening/gravity_part.h b/src/gravity/MultiSoftening/gravity_part.h index 39cecdfb6f1adbd3b5216fd2b07f2e24dfef9b1f..9183637c7940b63ec3576ecb8665feacb448f0d2 100644 --- a/src/gravity/MultiSoftening/gravity_part.h +++ b/src/gravity/MultiSoftening/gravity_part.h @@ -34,12 +34,22 @@ struct gpart { /*! Particle velocity. */ float v_full[3]; - /*! Particle acceleration. */ + /*! Particle acceleration from the tree. */ float a_grav[3]; - /*! Gravitational potential */ + /*! Particle acceleration from the mesh. */ + float a_grav_mesh[3]; + +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + + /*! Gravitational potential from the tree.*/ float potential; + /*! Gravitational potential from the mesh.*/ + float potential_mesh; + +#endif + /*! Particle mass. */ float mass; @@ -77,6 +87,9 @@ struct gpart { /* Time of the last kick */ integertime_t ti_kick; + /* Time of the last mesh kick */ + integertime_t ti_kick_mesh; + /* Has this particle been initialised? */ int initialised; @@ -86,12 +99,6 @@ struct gpart { #ifdef SWIFT_GRAVITY_FORCE_CHECKS - /*! Acceleration taken from the mesh only */ - float a_grav_PM[3]; - - /*! Potential taken from the mesh only */ - float potential_PM; - /* Acceleration taken from each component of the tree */ float a_grav_p2p[3]; float a_grav_m2p[3]; @@ -111,7 +118,6 @@ struct gpart { long long num_interacted_p2p; long long num_interacted_pm; #endif - -} SWIFT_STRUCT_ALIGN; +}; #endif /* SWIFT_MULTI_SOFTENING_GRAVITY_PART_H */ diff --git a/src/gravity/Potential/gravity.h b/src/gravity/Potential/gravity.h deleted file mode 100644 index f1cfb300a97e0edbd54020066c1148bf9ac93249..0000000000000000000000000000000000000000 --- a/src/gravity/Potential/gravity.h +++ /dev/null @@ -1,261 +0,0 @@ -/******************************************************************************* - * This file is part of SWIFT. - * Coypright (c) 2015 Matthieu Schaller (matthieu.schaller@durham.ac.uk) - * 2016 Tom Theuns (tom.theuns@durham.ac.uk) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - ******************************************************************************/ -#ifndef SWIFT_POTENTIAL_GRAVITY_H -#define SWIFT_POTENTIAL_GRAVITY_H - -#include <float.h> - -/* Local includes. */ -#include "cosmology.h" -#include "gravity_properties.h" -#include "kernel_gravity.h" -#include "minmax.h" - -/** - * @brief Returns the mass of a particle - * - * @param gp The particle of interest - */ -__attribute__((always_inline)) INLINE static float gravity_get_mass( - const struct gpart* restrict gp) { - - return gp->mass; -} - -/** - * @brief Returns the current co-moving softening of a particle - * - * Note that in this basic gravity scheme, all particles have - * the same softening length. - * - * @param gp The particle of interest - * @param grav_props The global gravity properties. - */ -__attribute__((always_inline)) INLINE static float gravity_get_softening( - const struct gpart* gp, const struct gravity_props* restrict grav_props) { - - return grav_props->epsilon_DM_cur; -} - -/** - * @brief Add a contribution to this particle's potential. - * - * @param gp The particle. - * @param pot The contribution to add. - */ -__attribute__((always_inline)) INLINE static void -gravity_add_comoving_potential(struct gpart* restrict gp, float pot) { - - gp->potential += pot; -} - -/** - * @brief Returns the comoving potential of a particle - * - * @param gp The particle of interest - */ -__attribute__((always_inline)) INLINE static float -gravity_get_comoving_potential(const struct gpart* restrict gp) { - - return gp->potential; -} - -/** - * @brief Returns the physical potential of a particle - * - * @param gp The particle of interest. - * @param cosmo The cosmological model. - */ -__attribute__((always_inline)) INLINE static float -gravity_get_physical_potential(const struct gpart* restrict gp, - const struct cosmology* cosmo) { - - return gp->potential * cosmo->a_inv; -} - -/** - * @brief Computes the gravity time-step of a given particle due to self-gravity - * - * We use Gadget-2's type 0 time-step criterion. - * - * @param gp Pointer to the g-particle data. - * @param a_hydro The accelerations coming from the hydro scheme (can be 0). - * @param grav_props Constants used in the gravity scheme. - * @param cosmo The current cosmological model. - */ -__attribute__((always_inline)) INLINE static float -gravity_compute_timestep_self(const struct gpart* const gp, - const float a_hydro[3], - const struct gravity_props* restrict grav_props, - const struct cosmology* cosmo) { - - /* Get physical acceleration (gravity contribution) */ - float a_phys_x = gp->a_grav[0] * cosmo->a_factor_grav_accel; - float a_phys_y = gp->a_grav[1] * cosmo->a_factor_grav_accel; - float a_phys_z = gp->a_grav[2] * cosmo->a_factor_grav_accel; - - /* Get physical acceleration (hydro contribution) */ - a_phys_x += a_hydro[0] * cosmo->a_factor_hydro_accel; - a_phys_y += a_hydro[1] * cosmo->a_factor_hydro_accel; - a_phys_z += a_hydro[2] * cosmo->a_factor_hydro_accel; - - const float ac2 = - a_phys_x * a_phys_x + a_phys_y * a_phys_y + a_phys_z * a_phys_z; - - const float ac_inv = (ac2 > 0.f) ? 1.f / sqrtf(ac2) : FLT_MAX; - - const float epsilon = gravity_get_softening(gp, grav_props); - - const float dt = sqrtf(2. * kernel_gravity_softening_plummer_equivalent_inv * - cosmo->a * grav_props->eta * epsilon * ac_inv); - - return dt; -} - -/** - * @brief Prepares a g-particle for the gravity calculation - * - * Zeroes all the relevant arrays in preparation for the sums taking place in - * the variaous tasks - * - * @param gp The particle to act upon - */ -__attribute__((always_inline)) INLINE static void gravity_init_gpart( - struct gpart* gp) { - - /* Zero the acceleration */ - gp->a_grav[0] = 0.f; - gp->a_grav[1] = 0.f; - gp->a_grav[2] = 0.f; - gp->potential = 0.f; - -#ifdef SWIFT_GRAVITY_FORCE_CHECKS - gp->potential_PM = 0.f; - gp->a_grav_PM[0] = 0.f; - gp->a_grav_PM[1] = 0.f; - gp->a_grav_PM[2] = 0.f; -#endif - -#ifdef SWIFT_DEBUG_CHECKS - gp->num_interacted = 0; - gp->initialised = 1; -#endif -} - -/** - * @brief Finishes the gravity calculation. - * - * Multiplies the forces and accelerations by the appropiate constants. - * Applies cosmological correction for periodic BCs. - * - * @param gp The particle to act upon - * @param const_G Newton's constant in internal units. - * @param potential_normalisation Term to be added to all the particles. - * @param with_self_gravity Are we running with self-gravity? - */ -__attribute__((always_inline)) INLINE static void gravity_end_force( - struct gpart* gp, const float const_G, const float potential_normalisation, - const int periodic, const int with_self_gravity) { - - /* Apply the periodic correction to the peculiar potential */ - if (periodic) gp->potential += potential_normalisation; - - /* Record the norm of the acceleration for the adaptive opening criteria. - * Will always be an (active) timestep behind. */ - gp->old_a_grav_norm = gp->a_grav[0] * gp->a_grav[0] + - gp->a_grav[1] * gp->a_grav[1] + - gp->a_grav[2] * gp->a_grav[2]; - - gp->old_a_grav_norm = sqrtf(gp->old_a_grav_norm); - -#ifdef SWIFT_DEBUG_CHECKS - if (with_self_gravity && gp->old_a_grav_norm == 0.f) - error("Old acceleration is 0!"); -#endif - - /* Let's get physical... */ - gp->a_grav[0] *= const_G; - gp->a_grav[1] *= const_G; - gp->a_grav[2] *= const_G; - gp->potential *= const_G; - -#ifdef SWIFT_GRAVITY_FORCE_CHECKS - gp->potential_PM *= const_G; - gp->a_grav_PM[0] *= const_G; - gp->a_grav_PM[1] *= const_G; - gp->a_grav_PM[2] *= const_G; -#endif - -#ifdef SWIFT_DEBUG_CHECKS - gp->initialised = 0; /* Ready for next step */ -#endif -} - -/** - * @brief Update the #gpart after a drift step. - * - * This is typically used to update the softening lengths. - * - * @param gp The particle to act upon - * @param grav_props The global properties of the gravity calculation. - */ -__attribute__((always_inline)) INLINE static void gravity_predict_extra( - struct gpart* gp, const struct gravity_props* grav_props) {} - -/** - * @brief Kick the additional variables - * - * @param gp The particle to act upon - * @param dt The time-step for this kick - */ -__attribute__((always_inline)) INLINE static void gravity_kick_extra( - struct gpart* gp, float dt) {} - -/** - * @brief Sets the values to be predicted in the drifts to their values at a - * kick time - * - * @param gp The particle. - */ -__attribute__((always_inline)) INLINE static void -gravity_reset_predicted_values(struct gpart* gp) {} - -/** - * @brief Initialises the g-particles for the first time - * - * This function is called only once just after the ICs have been - * read in to do some conversions. - * - * @param gp The particle to act upon - * @param grav_props The global properties of the gravity calculation. - */ -__attribute__((always_inline)) INLINE static void gravity_first_init_gpart( - struct gpart* gp, const struct gravity_props* grav_props) { - - gp->time_bin = 0; - gp->old_a_grav_norm = 0.f; -#ifdef HAVE_VELOCIRAPTOR_ORPHANS - gp->has_been_most_bound = 0; -#endif - - gravity_init_gpart(gp); -} - -#endif /* SWIFT_POTENTIAL_GRAVITY_H */ diff --git a/src/gravity/Potential/gravity_iact.h b/src/gravity/Potential/gravity_iact.h deleted file mode 100644 index feb0abecdb3ecd43a4b9f2d9152ddb0028939e8a..0000000000000000000000000000000000000000 --- a/src/gravity/Potential/gravity_iact.h +++ /dev/null @@ -1,204 +0,0 @@ -/******************************************************************************* - * This file is part of SWIFT. - * Copyright (c) 2013 Pedro Gonnet (pedro.gonnet@durham.ac.uk) - * Matthieu Schaller (matthieu.schaller@durham.ac.uk) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - ******************************************************************************/ -#ifndef SWIFT_POTENTIAL_GRAVITY_IACT_H -#define SWIFT_POTENTIAL_GRAVITY_IACT_H - -/* Includes. */ -#include "kernel_gravity.h" -#include "kernel_long_gravity.h" -#include "multipole.h" - -/* Standard headers */ -#include <float.h> - -/** - * @brief Computes the intensity of the force at a point generated by a - * point-mass. - * - * The returned quantity needs to be multiplied by the distance vector to obtain - * the force vector. - * - * @param r2 Square of the distance to the point-mass. - * @param h2 Square of the softening length. - * @param h_inv Inverse of the softening length. - * @param h_inv3 Cube of the inverse of the softening length. - * @param mass Mass of the point-mass. - * @param f_ij (return) The force intensity. - * @param pot_ij (return) The potential. - */ -__attribute__((always_inline, nonnull)) INLINE static void -runner_iact_grav_pp_full(const float r2, const float h2, const float h_inv, - const float h_inv3, const float mass, - float *restrict f_ij, float *restrict pot_ij) { - - /* Get the inverse distance */ - const float r_inv = 1.f / sqrtf(r2 + FLT_MIN); - - /* Should we soften ? */ - if (r2 >= h2) { - - /* Get Newtonian gravity */ - *f_ij = mass * r_inv * r_inv * r_inv; - *pot_ij = -mass * r_inv; - - } else { - - const float r = r2 * r_inv; - const float ui = r * h_inv; - const float W_f_ij = kernel_grav_force_eval(ui); - const float W_pot_ij = kernel_grav_pot_eval(ui); - - /* Get softened gravity */ - *f_ij = mass * h_inv3 * W_f_ij; - *pot_ij = mass * h_inv * W_pot_ij; - } -} - -/** - * @brief Computes the intensity of the force at a point generated by a - * point-mass truncated for long-distance periodicity. - * - * The returned quantity needs to be multiplied by the distance vector to obtain - * the force vector. - * - * @param r2 Square of the distance to the point-mass. - * @param h2 Square of the softening length. - * @param h_inv Inverse of the softening length. - * @param h_inv3 Cube of the inverse of the softening length. - * @param mass Mass of the point-mass. - * @param r_s_inv Inverse of the mesh smoothing scale. - * @param f_ij (return) The force intensity. - * @param pot_ij (return) The potential. - */ -__attribute__((always_inline, nonnull)) INLINE static void -runner_iact_grav_pp_truncated(const float r2, const float h2, const float h_inv, - const float h_inv3, const float mass, - const float r_s_inv, float *restrict f_ij, - float *restrict pot_ij) { - - /* Get the inverse distance */ - const float r_inv = 1.f / sqrtf(r2 + FLT_MIN); - const float r = r2 * r_inv; - - /* Should we soften ? */ - if (r2 >= h2) { - - /* Get Newtonian gravity */ - *f_ij = mass * r_inv * r_inv * r_inv; - *pot_ij = -mass * r_inv; - - } else { - - const float ui = r * h_inv; - const float W_f_ij = kernel_grav_force_eval(ui); - const float W_pot_ij = kernel_grav_pot_eval(ui); - - /* Get softened gravity */ - *f_ij = mass * h_inv3 * W_f_ij; - *pot_ij = mass * h_inv * W_pot_ij; - } - - /* Get long-range correction */ - const float u_lr = r * r_s_inv; - float corr_f_lr, corr_pot_lr; - kernel_long_grav_eval(u_lr, &corr_f_lr, &corr_pot_lr); - *f_ij *= corr_f_lr; - *pot_ij *= corr_pot_lr; -} - -/** - * @brief Computes the forces at a point generated by a multipole. - * - * @param r_x x-component of the distance vector to the multipole. - * @param r_y y-component of the distance vector to the multipole. - * @param r_z z-component of the distance vector to the multipole. - * @param r2 Square of the distance vector to the multipole. - * @param h The softening length. - * @param h_inv Inverse of the softening length. - * @param m The multipole. - * @param f_x (return) The x-component of the acceleration. - * @param f_y (return) The y-component of the acceleration. - * @param f_z (return) The z-component of the acceleration. - * @param pot (return) The potential. - */ -__attribute__((always_inline, nonnull)) INLINE static void -runner_iact_grav_pm_full(const float r_x, const float r_y, const float r_z, - const float r2, const float h, const float h_inv, - const struct multipole *m, float *restrict f_x, - float *restrict f_y, float *restrict f_z, - float *restrict pot) { - - /* Use the M2P kernel */ - struct reduced_grav_tensor l; - l.F_000 = 0.f; - l.F_100 = 0.f; - l.F_010 = 0.f; - l.F_001 = 0.f; - - gravity_M2P(m, r_x, r_y, r_z, r2, h, /*periodic=*/0, /*rs_inv=*/0.f, &l); - - /* Write back */ - *pot = l.F_000; - *f_x = l.F_100; - *f_y = l.F_010; - *f_z = l.F_001; -} - -/** - * @brief Computes the forces at a point generated by a multipole, truncated for - * long-range periodicity. - * - * @param r_x x-component of the distance vector to the multipole. - * @param r_y y-component of the distance vector to the multipole. - * @param r_z z-component of the distance vector to the multipole. - * @param r2 Square of the distance vector to the multipole. - * @param h The softening length. - * @param h_inv Inverse of the softening length. - * @param r_s_inv The inverse of the gravity mesh-smoothing scale. - * @param m The multipole. - * @param f_x (return) The x-component of the acceleration. - * @param f_y (return) The y-component of the acceleration. - * @param f_z (return) The z-component of the acceleration. - * @param pot (return) The potential. - */ -__attribute__((always_inline, nonnull)) INLINE static void -runner_iact_grav_pm_truncated(const float r_x, const float r_y, const float r_z, - const float r2, const float h, const float h_inv, - const float r_s_inv, const struct multipole *m, - float *restrict f_x, float *restrict f_y, - float *restrict f_z, float *restrict pot) { - - /* Use the M2P kernel */ - struct reduced_grav_tensor l; - l.F_000 = 0.f; - l.F_100 = 0.f; - l.F_010 = 0.f; - l.F_001 = 0.f; - - gravity_M2P(m, r_x, r_y, r_z, r2, h, /*periodic=*/1, r_s_inv, &l); - - /* Write back */ - *pot = l.F_000; - *f_x = l.F_100; - *f_y = l.F_010; - *f_z = l.F_001; -} - -#endif /* SWIFT_POTENTIAL_GRAVITY_IACT_H */ diff --git a/src/gravity/Potential/gravity_io.h b/src/gravity/Potential/gravity_io.h deleted file mode 100644 index 38dbeb546673bdaf8a796032aa5f6887e364838d..0000000000000000000000000000000000000000 --- a/src/gravity/Potential/gravity_io.h +++ /dev/null @@ -1,131 +0,0 @@ -/******************************************************************************* - * This file is part of SWIFT. - * Coypright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - ******************************************************************************/ -#ifndef SWIFT_POTENTIAL_GRAVITY_IO_H -#define SWIFT_POTENTIAL_GRAVITY_IO_H - -#include "io_properties.h" - -INLINE static void convert_gpart_pos(const struct engine* e, - const struct gpart* gp, double* ret) { - const struct space* s = e->s; - if (s->periodic) { - ret[0] = box_wrap(gp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(gp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(gp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); - } else { - ret[0] = gp->x[0]; - ret[1] = gp->x[1]; - ret[2] = gp->x[2]; - } -} - -INLINE static void convert_gpart_vel(const struct engine* e, - const struct gpart* gp, float* ret) { - - const int with_cosmology = (e->policy & engine_policy_cosmology); - const struct cosmology* cosmo = e->cosmology; - const integertime_t ti_current = e->ti_current; - const double time_base = e->time_base; - - const integertime_t ti_beg = get_integer_time_begin(ti_current, gp->time_bin); - const integertime_t ti_end = get_integer_time_end(ti_current, gp->time_bin); - - /* Get time-step since the last kick */ - float dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_beg, ti_current); - dt_kick_grav -= - cosmology_get_grav_kick_factor(cosmo, ti_beg, (ti_beg + ti_end) / 2); - } else { - dt_kick_grav = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; - } - - /* Extrapolate the velocites to the current time */ - ret[0] = gp->v_full[0] + gp->a_grav[0] * dt_kick_grav; - ret[1] = gp->v_full[1] + gp->a_grav[1] * dt_kick_grav; - ret[2] = gp->v_full[2] + gp->a_grav[2] * dt_kick_grav; - - /* Conversion from internal units to peculiar velocities */ - ret[0] *= cosmo->a_inv; - ret[1] *= cosmo->a_inv; - ret[2] *= cosmo->a_inv; -} - -/** - * @brief Specifies which g-particle fields to read from a dataset - * - * @param gparts The g-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 darkmatter_read_particles(struct gpart* gparts, - struct io_props* list, - int* num_fields) { - - /* Say how much we want to read */ - *num_fields = 4; - - /* List what we want to read */ - list[0] = io_make_input_field("Coordinates", DOUBLE, 3, COMPULSORY, - UNIT_CONV_LENGTH, gparts, x); - list[1] = io_make_input_field("Velocities", FLOAT, 3, COMPULSORY, - UNIT_CONV_SPEED, gparts, v_full); - list[2] = io_make_input_field("Masses", FLOAT, 1, COMPULSORY, UNIT_CONV_MASS, - gparts, mass); - list[3] = io_make_input_field("ParticleIDs", ULONGLONG, 1, COMPULSORY, - UNIT_CONV_NO_UNITS, gparts, id_or_neg_offset); -} - -/** - * @brief Specifies which g-particle fields to write to a dataset - * - * @param gparts The g-particle array. - * @param list The list of i/o properties to write. - * @param num_fields The number of i/o fields to write. - */ -INLINE static void darkmatter_write_particles(const struct gpart* gparts, - struct io_props* list, - int* num_fields) { - - /* Say how much we want to write */ - *num_fields = 5; - - /* List what we want to write */ - list[0] = io_make_output_field_convert_gpart( - "Coordinates", DOUBLE, 3, UNIT_CONV_LENGTH, 1.f, gparts, - convert_gpart_pos, "Co-moving position of the particles"); - - list[1] = io_make_output_field_convert_gpart( - "Velocities", FLOAT, 3, UNIT_CONV_SPEED, 0.f, gparts, convert_gpart_vel, - "Peculiar velocities of the stars. This is a * dx/dt where x is the " - "co-moving position of the particles."); - - list[2] = io_make_output_field("Masses", FLOAT, 1, UNIT_CONV_MASS, 0.f, - gparts, mass, "Masses of the particles"); - - list[3] = io_make_output_field( - "ParticleIDs", ULONGLONG, 1, UNIT_CONV_NO_UNITS, 0.f, gparts, - id_or_neg_offset, "Unique ID of the particles"); - - list[4] = io_make_output_field( - "Potentials", FLOAT, 1, UNIT_CONV_POTENTIAL, -1.f, gparts, potential, - "Co-moving gravitational potential at position of the particles"); -} - -#endif /* SWIFT_POTENTIAL_GRAVITY_IO_H */ diff --git a/src/gravity/Potential/gravity_part.h b/src/gravity/Potential/gravity_part.h deleted file mode 100644 index c63301504c0111bf31c7b9a14cf78ae96e239a83..0000000000000000000000000000000000000000 --- a/src/gravity/Potential/gravity_part.h +++ /dev/null @@ -1,99 +0,0 @@ -/******************************************************************************* - * This file is part of SWIFT. - * Copyright (c) 2012 Pedro Gonnet (pedro.gonnet@durham.ac.uk) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - ******************************************************************************/ -#ifndef SWIFT_POTENTIAL_GRAVITY_PART_H -#define SWIFT_POTENTIAL_GRAVITY_PART_H - -#include "fof_struct.h" - -/** - * @brief Gravity particle. - */ -struct gpart { - - /*! Particle ID. If negative, it is the negative offset of the #part with - which this gpart is linked. */ - long long id_or_neg_offset; - - /*! Particle position. */ - double x[3]; - - /*! Particle velocity. */ - float v_full[3]; - - /*! Particle acceleration. */ - float a_grav[3]; - - /*! Gravitational potential */ - float potential; - - /*! Particle mass. */ - float mass; - - /*! Norm of the acceleration at the previous step. */ - float old_a_grav_norm; - - /*! Particle FoF properties (group ID, group size, ...) */ - struct fof_gpart_data fof_data; - - /*! Time-step length */ - timebin_t time_bin; - - /*! Type of the #gpart (DM, gas, star, ...) */ - enum part_type type; - -#ifdef HAVE_VELOCIRAPTOR_ORPHANS - /* Flag to indicate this particle should be output at subsequent VR - invocations because it was the most bound in a group at some point */ - char has_been_most_bound; -#endif - -#ifdef SWIFT_DEBUG_CHECKS - - /* Numer of gparts this gpart interacted with */ - long long num_interacted; - - /* Time of the last drift */ - integertime_t ti_drift; - - /* Time of the last kick */ - integertime_t ti_kick; - - /* Has this particle been initialised? */ - int initialised; - -#endif - -#ifdef SWIFT_GRAVITY_FORCE_CHECKS - - /*! Acceleration taken from the mesh only */ - float a_grav_PM[3]; - - /*! Potential taken from the mesh only */ - float potential_PM; - - /* Brute-force particle acceleration. */ - double a_grav_exact[3]; - - /* Brute-force particle potential. */ - double potential_exact; -#endif - -} SWIFT_STRUCT_ALIGN; - -#endif /* SWIFT_POTENTIAL_GRAVITY_PART_H */ diff --git a/src/gravity_iact.h b/src/gravity_iact.h index 4c8d707fe33d0955809f8cb394d75c3a2f580fb7..19684d0f061092be604e65d53c847418bbbcffe3 100644 --- a/src/gravity_iact.h +++ b/src/gravity_iact.h @@ -30,8 +30,6 @@ /* Import the right functions */ #if defined(DEFAULT_GRAVITY) #include "./gravity/Default/gravity_iact.h" -#elif defined(POTENTIAL_GRAVITY) -#include "./gravity/Potential/gravity_iact.h" #elif defined(MULTI_SOFTENING_GRAVITY) #include "./gravity/MultiSoftening/gravity_iact.h" #else diff --git a/src/gravity_io.h b/src/gravity_io.h index 44f392ee06d43228f7aa46faa5c7d9015fde790b..e3fe6e60d69c096bf6b59c6aa1e5d0ddf7071c97 100644 --- a/src/gravity_io.h +++ b/src/gravity_io.h @@ -28,8 +28,6 @@ /* Import the right functions */ #if defined(DEFAULT_GRAVITY) #include "./gravity/Default/gravity_io.h" -#elif defined(POTENTIAL_GRAVITY) -#include "./gravity/Potential/gravity_io.h" #elif defined(MULTI_SOFTENING_GRAVITY) #include "./gravity/MultiSoftening/gravity_io.h" #else diff --git a/src/gravity_logger.h b/src/gravity_logger.h index 28158a061f5e57e5d07a4f0d22895af08184214b..c87831b37b682c368ca5413cb5fa2e09e8ab4752 100644 --- a/src/gravity_logger.h +++ b/src/gravity_logger.h @@ -32,8 +32,6 @@ /* Import the right functions */ #if defined(DEFAULT_GRAVITY) #error TODO -#elif defined(POTENTIAL_GRAVITY) -#error TODO #elif defined(MULTI_SOFTENING_GRAVITY) #include "./gravity/MultiSoftening/gravity_logger.h" #else diff --git a/src/gravity_properties.c b/src/gravity_properties.c index a58e822ab808d08aab48b746912c601f20fcaa54..071730ae428013a12bc3305b5a2f4dc4c894fa98 100644 --- a/src/gravity_properties.c +++ b/src/gravity_properties.c @@ -134,16 +134,6 @@ void gravity_props_init(struct gravity_props *p, struct swift_params *params, "Gadget2-type softening kernel"); #endif - /* Mesh dithering */ - if (periodic && !with_external_potential) { - p->with_dithering = - parser_get_opt_param_int(params, "Gravity:dithering", 0); - if (p->with_dithering) { - p->dithering_ratio = - parser_get_opt_param_double(params, "Gravity:dithering_ratio", 1.0); - } - } - /* Softening parameters */ if (with_cosmology) { @@ -293,8 +283,6 @@ void gravity_props_print(const struct gravity_props *p) { message("Self-gravity truncation cut-off ratio: r_cut_min=%f", p->r_cut_min_ratio); - message("Self-gravity mesh dithering ratio: %f", p->dithering_ratio); - message("Self-gravity mesh truncation function: %s", kernel_long_gravity_truncation_name); @@ -348,7 +336,6 @@ void gravity_props_print_snapshot(hid_t h_grpgrav, io_write_attribute_f(h_grpgrav, "Mesh a_smooth", p->a_smooth); io_write_attribute_f(h_grpgrav, "Mesh r_cut_max ratio", p->r_cut_max_ratio); io_write_attribute_f(h_grpgrav, "Mesh r_cut_min ratio", p->r_cut_min_ratio); - io_write_attribute_f(h_grpgrav, "Mesh dithering ratio", p->dithering_ratio); io_write_attribute_f(h_grpgrav, "Tree update frequency", p->rebuild_frequency); io_write_attribute_s(h_grpgrav, "Mesh truncation function", diff --git a/src/gravity_properties.h b/src/gravity_properties.h index 51ac0cc11e3535a32bb837586851a256d35bf207..486fadc21c569be06dfb51f0b06cac5cfca02c87 100644 --- a/src/gravity_properties.h +++ b/src/gravity_properties.h @@ -122,12 +122,6 @@ struct gravity_props { /*! Inverse of the long-range gravity mesh scale. */ float r_s_inv; - /*! Are we dithering the particles at every rebuild? */ - int with_dithering; - - /*! Fraction of the top-level cell size used to normalize the dithering */ - double dithering_ratio; - /* ------------- Physical constants ---------------------------------- */ /*! Gravitational constant (in internal units, copied from the physical diff --git a/src/hydro.h b/src/hydro.h index b38276c3d482bcbbbb39595ecf29cbb8dba23459..7c514c74a8ad113afd6e626b422af0b7b8f0a78a 100644 --- a/src/hydro.h +++ b/src/hydro.h @@ -51,10 +51,10 @@ #define SPH_IMPLEMENTATION \ "Pressure-Energy SPH (Hopkins 2013) with a Morris and Monaghan (1997) " \ "variable artificial viscosity." -#elif defined(DEFAULT_SPH) -#include "./hydro/Default/hydro.h" -#include "./hydro/Default/hydro_iact.h" -#define SPH_IMPLEMENTATION "Default version of SPH" +#elif defined(PHANTOM_SPH) +#include "./hydro/Phantom/hydro.h" +#include "./hydro/Phantom/hydro_iact.h" +#define SPH_IMPLEMENTATION "PHANTOM SPH reference implementation (Price 2018)" #elif defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH) #include "./hydro/Gizmo/hydro.h" #include "./hydro/Gizmo/hydro_iact.h" diff --git a/src/hydro/AnarchyPU/hydro.h b/src/hydro/AnarchyPU/hydro.h index 7a0639dfd63cbdbd3a6f2a36002f31bbae7bc40b..8e7e995780cde5d51ceb11e61a464041139db553 100644 --- a/src/hydro/AnarchyPU/hydro.h +++ b/src/hydro/AnarchyPU/hydro.h @@ -280,27 +280,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of internal energy of a particle * @@ -1064,9 +1043,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->u_full = p->u; hydro_reset_acceleration(p); diff --git a/src/hydro/AnarchyPU/hydro_io.h b/src/hydro/AnarchyPU/hydro_io.h index 181deb4d608b7d3ced6a083fcfb47f4c9dc2993e..98e7052780aee9cca94e4babe91ee50ee6d89cf2 100644 --- a/src/hydro/AnarchyPU/hydro_io.h +++ b/src/hydro/AnarchyPU/hydro_io.h @@ -84,9 +84,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -102,6 +102,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -120,8 +121,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/AnarchyPU/hydro_part.h b/src/hydro/AnarchyPU/hydro_part.h index 641ff99dd975b614f209b8c8fe50e97f7ff6764d..d55307bf9f73761c6e54eea096d6efbcd4fd4d56 100644 --- a/src/hydro/AnarchyPU/hydro_part.h +++ b/src/hydro/AnarchyPU/hydro_part.h @@ -55,9 +55,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Internal energy at the last full step. */ float u_full; diff --git a/src/hydro/Gadget2/hydro.h b/src/hydro/Gadget2/hydro.h index cf995f35f753c22bcd40c6f601d0b05cf17909cb..4f622fbbdb49ce0efa6fdcb22f1ac21344fcd535 100644 --- a/src/hydro/Gadget2/hydro.h +++ b/src/hydro/Gadget2/hydro.h @@ -252,27 +252,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of co-moving internal energy of a particle * @@ -897,9 +876,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->entropy_full = p->entropy; hydro_reset_acceleration(p); diff --git a/src/hydro/Gadget2/hydro_io.h b/src/hydro/Gadget2/hydro_io.h index 721c8ebf2038c69f2539121a90e22e140f947b1a..213556ca25474df49396f09b52be0ef525e0c90b 100644 --- a/src/hydro/Gadget2/hydro_io.h +++ b/src/hydro/Gadget2/hydro_io.h @@ -75,9 +75,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -93,6 +93,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -111,8 +112,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/Gadget2/hydro_part.h b/src/hydro/Gadget2/hydro_part.h index e45b9b7c7f48c60a8ae64fd3e5d32faebc8dab65..bb614c897588a7f7ae4a00041d070c3a0c2460f1 100644 --- a/src/hydro/Gadget2/hydro_part.h +++ b/src/hydro/Gadget2/hydro_part.h @@ -54,9 +54,6 @@ struct xpart { /* Velocity at the last full step. */ float v_full[3]; - /* Gravitational acceleration at the last full step. */ - float a_grav[3]; - /* Entropy at the last full step. */ float entropy_full; diff --git a/src/hydro/Gizmo/hydro_getters.h b/src/hydro/Gizmo/hydro_getters.h index 86aa79ab98ad13bb4d4d6e08bce255171c216daf..49cc6d7a9986f36bccbaaa6a7deba9743dd52152 100644 --- a/src/hydro/Gizmo/hydro_getters.h +++ b/src/hydro/Gizmo/hydro_getters.h @@ -281,10 +281,12 @@ __attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( v[2] = p->fluid_v[2]; } - // MATTHIEU: Bert is this correct? - v[0] += xp->a_grav[0] * dt_kick_grav; - v[1] += xp->a_grav[1] * dt_kick_grav; - v[2] += xp->a_grav[2] * dt_kick_grav; + // MATTHIEU: Bert is this correct? Also, we need to add the mesh kick! + if (p->gpart) { + v[0] += p->gpart->a_grav[0] * dt_kick_grav; + v[1] += p->gpart->a_grav[1] * dt_kick_grav; + v[2] += p->gpart->a_grav[2] * dt_kick_grav; + } } /** diff --git a/src/hydro/Gizmo/hydro_io.h b/src/hydro/Gizmo/hydro_io.h index 3fc8d78ef0bddb67262173ea0f17d2ee962efb40..6d35f90e12218ac472bef59a4a6c5bbd20eaeae7 100644 --- a/src/hydro/Gizmo/hydro_io.h +++ b/src/hydro/Gizmo/hydro_io.h @@ -118,9 +118,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct xpart* xp, double* ret) { const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; diff --git a/src/hydro/Gizmo/hydro_part.h b/src/hydro/Gizmo/hydro_part.h index c1228f576eac2c93aac5465701e6d93b89932119..3244aa1b6cc288a613db1df4a0176939b5c51dc8 100644 --- a/src/hydro/Gizmo/hydro_part.h +++ b/src/hydro/Gizmo/hydro_part.h @@ -39,9 +39,6 @@ struct xpart { /* Velocity at the last full step. */ float v_full[3]; - /* Gravitational acceleration at the last full step. */ - float a_grav[3]; - /* Additional data used to record cooling information */ struct cooling_xpart_data cooling_data; diff --git a/src/hydro/Minimal/hydro.h b/src/hydro/Minimal/hydro.h index df65d8d68e70f630d913cf90aea581a5635b7780..0ee99bf33525317128df70869ae1c5b32d87bc3b 100644 --- a/src/hydro/Minimal/hydro.h +++ b/src/hydro/Minimal/hydro.h @@ -258,27 +258,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of co-moving internal energy of a particle * @@ -598,17 +577,21 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_force( /* Compute the sound speed */ const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure); - /* Compute the "grad h" term */ - const float rho_inv = 1.f / p->rho; - float rho_dh = p->density.rho_dh; + /* Compute the "grad h" term - Note here that we have \tilde{x} + * as 1 as we use the local number density to find neighbours. This + * introduces a j-component that is considered in the force loop, + * meaning that this cached grad_h_term gives: + * + * f_ij = 1.f - grad_h_term_i / m_j */ + const float common_factor = p->h * hydro_dimension_inv / p->density.wcount; + float grad_h_term = common_factor * p->density.rho_dh / + (1.f + common_factor * p->density.wcount_dh); + /* Ignore changing-kernel effects when h ~= h_max */ if (p->h > 0.9999f * hydro_props->h_max) { - rho_dh = 0.f; + grad_h_term = 0.f; } - const float grad_h_term = - 1.f / (1.f + hydro_dimension_inv * p->h * rho_dh * rho_inv); - /* Compute the Balsara switch */ /* Pre-multiply in the AV factor; hydro_props are not passed to the iact * functions */ @@ -867,9 +850,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->u_full = p->u; hydro_reset_acceleration(p); diff --git a/src/hydro/Minimal/hydro_iact.h b/src/hydro/Minimal/hydro_iact.h index b0daa218c6a3aef855116879457631fb852803bb..0c7e136d3042980f8e34698d81a3416805bb3d92 100644 --- a/src/hydro/Minimal/hydro_iact.h +++ b/src/hydro/Minimal/hydro_iact.h @@ -235,9 +235,13 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( kernel_deval(xj, &wj, &wj_dx); const float wj_dr = hjd_inv * wj_dx; + /* Variable smoothing length term */ + const float f_ij = 1.f - pi->force.f / mj; + const float f_ji = 1.f - pj->force.f / mi; + /* Compute gradient terms */ - const float P_over_rho2_i = pressurei / (rhoi * rhoi) * pi->force.f; - const float P_over_rho2_j = pressurej / (rhoj * rhoj) * pj->force.f; + const float P_over_rho2_i = pressurei / (rhoi * rhoi) * f_ij; + const float P_over_rho2_j = pressurej / (rhoj * rhoj) * f_ji; /* Compute dv dot r. */ const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + @@ -265,7 +269,8 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float visc = -0.25f * v_sig * (balsara_i + balsara_j) * mu_ij / rho_ij; /* Convolve with the kernel */ - const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; + const float visc_acc_term = + 0.5f * visc * (wi_dr * f_ij + wj_dr * f_ji) * r_inv; /* SPH acceleration term */ const float sph_acc_term = @@ -299,8 +304,8 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( pj->u_dt += du_dt_j * mi; /* Get the time derivative for h. */ - pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr; - pj->force.h_dt -= mi * dvdr * r_inv / rhoi * wj_dr; + pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr * f_ij; + pj->force.h_dt -= mi * dvdr * r_inv / rhoi * wj_dr * f_ji; /* Update the signal velocity. */ pi->force.v_sig = max(pi->force.v_sig, v_sig); @@ -339,7 +344,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float r = r2 * r_inv; /* Recover some data */ - // const float mi = pi->mass; + const float mi = pi->mass; const float mj = pj->mass; const float rhoi = pi->rho; const float rhoj = pj->rho; @@ -362,9 +367,13 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( kernel_deval(xj, &wj, &wj_dx); const float wj_dr = hjd_inv * wj_dx; + /* Variable smoothing length term */ + const float f_ij = 1.f - pi->force.f / mj; + const float f_ji = 1.f - pj->force.f / mi; + /* Compute gradient terms */ - const float P_over_rho2_i = pressurei / (rhoi * rhoi) * pi->force.f; - const float P_over_rho2_j = pressurej / (rhoj * rhoj) * pj->force.f; + const float P_over_rho2_i = pressurei / (rhoi * rhoi) * f_ij; + const float P_over_rho2_j = pressurej / (rhoj * rhoj) * f_ji; /* Compute dv dot r. */ const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] + @@ -392,7 +401,8 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float visc = -0.25f * v_sig * (balsara_i + balsara_j) * mu_ij / rho_ij; /* Convolve with the kernel */ - const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv; + const float visc_acc_term = + 0.5f * visc * (wi_dr * f_ij + wj_dr * f_ji) * r_inv; /* SPH acceleration term */ const float sph_acc_term = @@ -419,7 +429,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( pi->u_dt += du_dt_i * mj; /* Get the time derivative for h. */ - pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr; + pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr * f_ij; /* Update the signal velocity. */ pi->force.v_sig = max(pi->force.v_sig, v_sig); diff --git a/src/hydro/Minimal/hydro_io.h b/src/hydro/Minimal/hydro_io.h index ba70e8253f467be474e86518ef3e6348f5aa2a21..dbd4d6381fadf79544d0f3536cd322d7269bc263 100644 --- a/src/hydro/Minimal/hydro_io.h +++ b/src/hydro/Minimal/hydro_io.h @@ -89,9 +89,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -107,6 +107,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -125,8 +126,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/Minimal/hydro_part.h b/src/hydro/Minimal/hydro_part.h index d08b3de0295bdf99085c0cb7e13439ce2b010fd6..158c42415e320d4f7893f8b26dd7c0296667eba0 100644 --- a/src/hydro/Minimal/hydro_part.h +++ b/src/hydro/Minimal/hydro_part.h @@ -58,9 +58,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Internal energy at the last full step. */ float u_full; diff --git a/src/hydro/Default/hydro.h b/src/hydro/Phantom/hydro.h similarity index 96% rename from src/hydro/Default/hydro.h rename to src/hydro/Phantom/hydro.h index 67c60a75e6fc460fc707a81488f70f4d80d30a02..313cac53177c7b61ff582553898d40ae8c898eb4 100644 --- a/src/hydro/Default/hydro.h +++ b/src/hydro/Phantom/hydro.h @@ -17,15 +17,18 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ -#ifndef SWIFT_DEFAULT_HYDRO_H -#define SWIFT_DEFAULT_HYDRO_H +#ifndef SWIFT_PHANTOM_HYDRO_H +#define SWIFT_PHANTOM_HYDRO_H /** - * @file Default/hydro.h + * @file Phantom/hydro.h * @brief Density-Energy conservative implementation of SPH, * with added diffusive physics (Cullen & Denhen 2011 AV, * Price 2017 (PHANTOM) diffusion) (Non-neighbour loop - * equations) + * equations). + * + * This is a base reference implementation + * similar to the one presented in Price 2018. */ #include "adiabatic_index.h" @@ -272,27 +275,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of internal energy of a particle * @@ -589,17 +571,21 @@ __attribute__((always_inline)) INLINE static void hydro_prepare_gradient( const float balsara = abs_div_v / (abs_div_v + curl_v + 0.0001f * soundspeed * fac_B / p->h); - /* Compute the "grad h" term */ - const float rho_inv = 1.f / p->rho; - float rho_dh = p->density.rho_dh; + /* Compute the "grad h" term - Note here that we have \tilde{x} + * as 1 as we use the local number density to find neighbours. This + * introduces a j-component that is considered in the force loop, + * meaning that this cached grad_h_term gives: + * + * f_ij = 1.f - grad_h_term_i / m_j */ + const float common_factor = p->h * hydro_dimension_inv / p->density.wcount; + float grad_h_term = common_factor * p->density.rho_dh / + (1.f + common_factor * p->density.wcount_dh); + /* Ignore changing-kernel effects when h ~= h_max */ if (p->h > 0.9999f * hydro_props->h_max) { - rho_dh = 0.f; + grad_h_term = 0.f; } - const float grad_h_term = - 1.f / (1.f + hydro_dimension_inv * p->h * rho_dh * rho_inv); - /* Update variables. */ p->force.f = grad_h_term; p->force.pressure = pressure; @@ -995,9 +981,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->u_full = p->u; hydro_reset_acceleration(p); @@ -1021,4 +1004,4 @@ hydro_set_init_internal_energy(struct part *p, float u_init) { p->u = u_init; } -#endif /* SWIFT_DEFAULT_HYDRO_H */ +#endif /* SWIFT_PHANTOM_HYDRO_H */ diff --git a/src/hydro/Default/hydro_debug.h b/src/hydro/Phantom/hydro_debug.h similarity index 88% rename from src/hydro/Default/hydro_debug.h rename to src/hydro/Phantom/hydro_debug.h index e9083870151feb984dc9c95d8f4cd33d1a80235f..6eeb4777b644ccc32e74109f907bf7834bee7058 100644 --- a/src/hydro/Default/hydro_debug.h +++ b/src/hydro/Phantom/hydro_debug.h @@ -18,14 +18,17 @@ * ******************************************************************************/ -#ifndef SWIFT_DEFAULT_HYDRO_DEBUG_H -#define SWIFT_DEFAULT_HYDRO_DEBUG_H +#ifndef SWIFT_PHANTOM_HYDRO_DEBUG_H +#define SWIFT_PHANTOM_HYDRO_DEBUG_H /** - * @file Default/hydro_debug.h + * @file Phantom/hydro_debug.h * @brief Density-Energy conservative implementation of SPH, * with added diffusive physics (Cullen & Denhen 2011 AV, * Price 2017 (PHANTOM) diffusion) (Debugging routines) + * + * This is a base reference implementation + * similar to the one presented in Price 2018. */ __attribute__((always_inline)) INLINE static void hydro_debug_particle( @@ -44,4 +47,4 @@ __attribute__((always_inline)) INLINE static void hydro_debug_particle( p->viscosity.alpha, p->time_bin); } -#endif /* SWIFT_DEFAULT_HYDRO_DEBUG_H */ +#endif /* SWIFT_PHANTOM_HYDRO_DEBUG_H */ diff --git a/src/hydro/Default/hydro_iact.h b/src/hydro/Phantom/hydro_iact.h similarity index 92% rename from src/hydro/Default/hydro_iact.h rename to src/hydro/Phantom/hydro_iact.h index 1bf4c216e5f8261b898e14f81362d2e93c58f84d..ba5679d49a06f26d4a2c18e4d733578aaa23c4e0 100644 --- a/src/hydro/Default/hydro_iact.h +++ b/src/hydro/Phantom/hydro_iact.h @@ -17,14 +17,17 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ -#ifndef SWIFT_DEFAULT_HYDRO_IACT_H -#define SWIFT_DEFAULT_HYDRO_IACT_H +#ifndef SWIFT_PHANTOM_HYDRO_IACT_H +#define SWIFT_PHANTOM_HYDRO_IACT_H /** - * @file Default/hydro_iact.h + * @file Phantom/hydro_iact.h * @brief Density-Energy conservative implementation of SPH, * with added diffusive physics (Cullen & Denhen 2011 AV, * Price 2017 (PHANTOM) diffusion) (interaction routines) + * + * This is a base reference implementation + * similar to the one presented in Price 2018. */ #include "adiabatic_index.h" @@ -330,6 +333,10 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float v_sig = pi->force.soundspeed + pj->force.soundspeed - const_viscosity_beta * mu_ij; + /* Variable smoothing length term */ + const float f_ij = 1.f - pi->force.f / mj; + const float f_ji = 1.f - pj->force.f / mi; + /* Balsara term */ const float balsara_i = pi->force.balsara; const float balsara_j = pj->force.balsara; @@ -340,12 +347,11 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( /* Convolve with the kernel */ const float visc_acc_term = - 0.5f * visc * (wi_dr * pi->force.f / rhoi + wj_dr * pj->force.f / rhoj) * - r_inv; + 0.5f * visc * (wi_dr * f_ij / rhoi + wj_dr * f_ji / rhoj) * r_inv; /* Compute gradient terms */ - const float P_over_rho2_i = pressurei / (rhoi * rhoi) * pi->force.f; - const float P_over_rho2_j = pressurej / (rhoj * rhoj) * pj->force.f; + const float P_over_rho2_i = pressurei / (rhoi * rhoi) * f_ij; + const float P_over_rho2_j = pressurej / (rhoj * rhoj) * f_ji; /* SPH acceleration term */ const float sph_acc_term = @@ -378,9 +384,8 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( const float alpha_diff = 0.5f * (pi->diffusion.alpha + pj->diffusion.alpha); /* wi_dx + wj_dx / 2 is F_ij */ - const float diff_du_term = - alpha_diff * v_diff * (pi->u - pj->u) * 0.5f * - (wi_dr * pi->force.f / pi->rho + wj_dr * pi->force.f / pi->rho); + const float diff_du_term = alpha_diff * v_diff * (pi->u - pj->u) * 0.5f * + (wi_dr * f_ij / pi->rho + wj_dr * f_ji / pi->rho); /* Assemble the energy equation term */ const float du_dt_i = sph_du_term_i + visc_du_term + diff_du_term; @@ -391,8 +396,8 @@ __attribute__((always_inline)) INLINE static void runner_iact_force( pj->u_dt += du_dt_j * mi; /* Get the time derivative for h. */ - pi->force.h_dt -= mj * dvdr * pi->force.f * r_inv / rhoj * wi_dr; - pj->force.h_dt -= mi * dvdr * pj->force.f * r_inv / rhoi * wj_dr; + pi->force.h_dt -= mj * dvdr * f_ij * r_inv / rhoj * wi_dr; + pj->force.h_dt -= mi * dvdr * f_ji * r_inv / rhoi * wj_dr; } /** @@ -419,7 +424,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float r_inv = 1.0f / r; /* Recover some data */ - // const float mi = pi->mass; + const float mi = pi->mass; const float mj = pj->mass; const float rhoi = pi->rho; @@ -460,6 +465,10 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float v_sig = pi->force.soundspeed + pj->force.soundspeed - const_viscosity_beta * mu_ij; + /* Variable smoothing length term */ + const float f_ij = 1.f - pi->force.f / mj; + const float f_ji = 1.f - pj->force.f / mi; + /* Balsara term */ const float balsara_i = pi->force.balsara; const float balsara_j = pj->force.balsara; @@ -470,12 +479,11 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( /* Convolve with the kernel */ const float visc_acc_term = - 0.5f * visc * (wi_dr * pi->force.f / rhoi + wj_dr * pj->force.f / rhoj) * - r_inv; + 0.5f * visc * (wi_dr * f_ij / rhoi + wj_dr * f_ji / rhoj) * r_inv; /* Compute gradient terms */ - const float P_over_rho2_i = pressurei / (rhoi * rhoi) * pi->force.f; - const float P_over_rho2_j = pressurej / (rhoj * rhoj) * pj->force.f; + const float P_over_rho2_i = pressurei / (rhoi * rhoi) * f_ij; + const float P_over_rho2_j = pressurej / (rhoj * rhoj) * f_ji; /* SPH acceleration term */ const float sph_acc_term = @@ -502,9 +510,8 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( const float alpha_diff = 0.5f * (pi->diffusion.alpha + pj->diffusion.alpha); /* wi_dx + wj_dx / 2 is F_ij */ - const float diff_du_term = - alpha_diff * v_diff * (pi->u - pj->u) * 0.5f * - (wi_dr * pi->force.f / pi->rho + wj_dr * pi->force.f / pi->rho); + const float diff_du_term = alpha_diff * v_diff * (pi->u - pj->u) * 0.5f * + (wi_dr * f_ij / pi->rho + wj_dr * f_ji / pi->rho); /* Assemble the energy equation term */ const float du_dt_i = sph_du_term_i + visc_du_term + diff_du_term; @@ -513,7 +520,7 @@ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_force( pi->u_dt += du_dt_i * mj; /* Get the time derivative for h. */ - pi->force.h_dt -= mj * dvdr * pi->force.f * r_inv / rhoj * wi_dr; + pi->force.h_dt -= mj * dvdr * f_ij * r_inv / rhoj * wi_dr; } -#endif /* SWIFT_DEFAULT_HYDRO_IACT_H */ +#endif /* SWIFT_PHANTOM_HYDRO_IACT_H */ diff --git a/src/hydro/Default/hydro_io.h b/src/hydro/Phantom/hydro_io.h similarity index 89% rename from src/hydro/Default/hydro_io.h rename to src/hydro/Phantom/hydro_io.h index eebad22f4449038a69c9168a0de675820615c560..8a6bf3952e6b53513f93540d3c56a22f653c9b7d 100644 --- a/src/hydro/Default/hydro_io.h +++ b/src/hydro/Phantom/hydro_io.h @@ -17,14 +17,16 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ -#ifndef SWIFT_DEFAULT_HYDRO_IO_H -#define SWIFT_DEFAULT_HYDRO_IO_H +#ifndef SWIFT_PHANTOM_HYDRO_IO_H +#define SWIFT_PHANTOM_HYDRO_IO_H /** - * @file Default/hydro_io.h + * @file Phantom/hydro_io.h * @brief Density-Energy conservative implementation of SPH, * with added diffusive physics (Cullen & Denhen 2011 AV, * Price 2017 (PHANTOM) diffusion) (i/o routines) + * This is a base reference implementation + * similar to the one presented in Price 2018. */ #include "adiabatic_index.h" @@ -83,9 +85,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -101,6 +103,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -119,8 +122,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; @@ -237,4 +256,4 @@ INLINE static void hydro_write_flavour(hid_t h_grpsph) { */ INLINE static int writeEntropyFlag(void) { return 0; } -#endif /* SWIFT_DEFAULT_HYDRO_IO_H */ +#endif /* SWIFT_PHANTOM_HYDRO_IO_H */ diff --git a/src/hydro/Default/hydro_parameters.h b/src/hydro/Phantom/hydro_parameters.h similarity index 97% rename from src/hydro/Default/hydro_parameters.h rename to src/hydro/Phantom/hydro_parameters.h index 1e492f4a8121dbabb73111e9139df6e8b7cbe6cb..26f0239c304d712508b6a377d99987253f49ac04 100644 --- a/src/hydro/Default/hydro_parameters.h +++ b/src/hydro/Phantom/hydro_parameters.h @@ -18,8 +18,8 @@ * ******************************************************************************/ -#ifndef SWIFT_DEFAULT_HYDRO_PARAMETERS_H -#define SWIFT_DEFAULT_HYDRO_PARAMETERS_H +#ifndef SWIFT_PHANTOM_HYDRO_PARAMETERS_H +#define SWIFT_PHANTOM_HYDRO_PARAMETERS_H /* Configuration file */ #include "config.h" @@ -35,12 +35,15 @@ #include "inline.h" /** - * @file Default/hydro_parameters.h + * @file Phantom/hydro_parameters.h * @brief Density-Energy conservative implementation of SPH, * with added diffusive physics (Cullen & Denhen 2011 AV, * Price 2017 (PHANTOM) diffusion) (default compile-time * parameters). * + * This is a base reference implementation + * similar to the one presented in Price 2018. + * * This file defines a number of things that are used in * hydro_properties.c as defaults for run-time parameters * as well as a number of compile-time parameters. @@ -253,4 +256,4 @@ static INLINE void diffusion_print_snapshot( } #endif -#endif /* SWIFT_DEFAULT_HYDRO_PARAMETERS_H */ +#endif /* SWIFT_PHANTOM_HYDRO_PARAMETERS_H */ diff --git a/src/hydro/Default/hydro_part.h b/src/hydro/Phantom/hydro_part.h similarity index 95% rename from src/hydro/Default/hydro_part.h rename to src/hydro/Phantom/hydro_part.h index fca3a9ec027c7f6a451e6ad0201057d6be27760e..170c0d9e434f65e5baaf68c31ccc16797de2f40f 100644 --- a/src/hydro/Default/hydro_part.h +++ b/src/hydro/Phantom/hydro_part.h @@ -17,14 +17,17 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ -#ifndef SWIFT_DEFAULT_HYDRO_PART_H -#define SWIFT_DEFAULT_HYDRO_PART_H +#ifndef SWIFT_PHANTOM_HYDRO_PART_H +#define SWIFT_PHANTOM_HYDRO_PART_H /** - * @file Default/hydro_part.h + * @file Phantom/hydro_part.h * @brief Density-Energy conservative implementation of SPH, * with added diffusive physics (Cullen & Denhen 2011 AV, * Price 2017 (PHANTOM) diffusion) (particle definition) + * + * This is a base reference implementation + * similar to the one presented in Price 2018. */ #include "black_holes_struct.h" @@ -53,9 +56,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Internal energy at the last full step. */ float u_full; @@ -220,4 +220,4 @@ struct part { } SWIFT_STRUCT_ALIGN; -#endif /* SWIFT_DEFAULT_HYDRO_PART_H */ +#endif /* SWIFT_PHANTOM_HYDRO_PART_H */ diff --git a/src/hydro/Planetary/hydro.h b/src/hydro/Planetary/hydro.h index 5bb9aeca2a40d0fd394c73546766bc5142ab9ef1..6b0357080527bf54065212a15516a4515df5d459 100644 --- a/src/hydro/Planetary/hydro.h +++ b/src/hydro/Planetary/hydro.h @@ -282,27 +282,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of internal energy of a particle * @@ -833,9 +812,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->u_full = p->u; hydro_reset_acceleration(p); diff --git a/src/hydro/Planetary/hydro_io.h b/src/hydro/Planetary/hydro_io.h index c1303795f7711c87126b4fc166caa697df15a136..9872441e2d5a641069e589154ed4b52600db3f45 100644 --- a/src/hydro/Planetary/hydro_io.h +++ b/src/hydro/Planetary/hydro_io.h @@ -91,9 +91,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct xpart* xp, double* ret) { const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -109,6 +109,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -127,8 +128,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/Planetary/hydro_part.h b/src/hydro/Planetary/hydro_part.h index 6325ba188bcae99ffdd3d3308da8ba4e6626cd3a..482f44288c9218fb55bf6d199978b423b84c6caa 100644 --- a/src/hydro/Planetary/hydro_part.h +++ b/src/hydro/Planetary/hydro_part.h @@ -61,9 +61,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Internal energy at the last full step. */ float u_full; diff --git a/src/hydro/PressureEnergy/hydro.h b/src/hydro/PressureEnergy/hydro.h index dd33023d5415cc4270e40fa136813071c3da5549..8ed236716853a8826f0d0c32af81b23632ee1886 100644 --- a/src/hydro/PressureEnergy/hydro.h +++ b/src/hydro/PressureEnergy/hydro.h @@ -301,27 +301,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of internal energy of a particle * @@ -917,9 +896,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->u_full = p->u; hydro_reset_acceleration(p); diff --git a/src/hydro/PressureEnergy/hydro_io.h b/src/hydro/PressureEnergy/hydro_io.h index 5b28d5a50ac7e8eae45ca2b3d6661f785c819f66..5934191a573d8cf4fb13f638daf98d4640012798 100644 --- a/src/hydro/PressureEnergy/hydro_io.h +++ b/src/hydro/PressureEnergy/hydro_io.h @@ -86,9 +86,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct xpart* xp, double* ret) { const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -104,6 +104,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -122,8 +123,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/PressureEnergy/hydro_part.h b/src/hydro/PressureEnergy/hydro_part.h index 5fd6798ff4d171a9631a703ad892c1dba3c31133..66b44d56c8818969ca10c199fe0f26bf73a38b70 100644 --- a/src/hydro/PressureEnergy/hydro_part.h +++ b/src/hydro/PressureEnergy/hydro_part.h @@ -58,9 +58,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Internal energy at the last full step. */ float u_full; diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h index d1ff15c217a76edb0f2e334298496d045e7f714a..4aacbe3b3215e293c64cc460b8a5a691bd235436 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro.h @@ -280,27 +280,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of internal energy of a particle * @@ -916,9 +895,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->u_full = p->u; hydro_reset_acceleration(p); diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_io.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_io.h index 4429227798b8a9527b1e5299e57b3aa30d8eeb41..c018626f23dfc0a553fef533eaa94cf22f70f0ba 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_io.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_io.h @@ -87,9 +87,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct xpart* xp, double* ret) { const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -105,6 +105,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -123,8 +124,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_part.h b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_part.h index db14af3a034c3b80d4f4477c7177c6906db2b9fc..30db47c9d2e94046c312f31a096033bee1c6a667 100644 --- a/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_part.h +++ b/src/hydro/PressureEnergyMorrisMonaghanAV/hydro_part.h @@ -58,9 +58,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Internal energy at the last full step. */ float u_full; diff --git a/src/hydro/PressureEntropy/hydro.h b/src/hydro/PressureEntropy/hydro.h index c98e86c93e54211b0f40f3b04c9304bdebe6e093..f1fefcf72b52c79dbf8c48b5cd51dfc35f77130d 100644 --- a/src/hydro/PressureEntropy/hydro.h +++ b/src/hydro/PressureEntropy/hydro.h @@ -301,27 +301,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of internal energy of a particle * @@ -836,9 +815,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; hydro_reset_acceleration(p); hydro_init_part(p, NULL); diff --git a/src/hydro/PressureEntropy/hydro_io.h b/src/hydro/PressureEntropy/hydro_io.h index 417698830a8ee7f822fe52ffe4d080fe81fa8b42..ed102b541431873c843b22cee32bc5514b4357b1 100644 --- a/src/hydro/PressureEntropy/hydro_io.h +++ b/src/hydro/PressureEntropy/hydro_io.h @@ -87,9 +87,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -105,6 +105,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -123,8 +124,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/PressureEntropy/hydro_part.h b/src/hydro/PressureEntropy/hydro_part.h index 9c2a1e14c48c71bf443285cf5a9930b120c1f40e..9a03c8862a491165376d16a03fe27429572ec9ab 100644 --- a/src/hydro/PressureEntropy/hydro_part.h +++ b/src/hydro/PressureEntropy/hydro_part.h @@ -50,9 +50,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Entropy at the last full step. */ float entropy_full; diff --git a/src/hydro/SPHENIX/hydro.h b/src/hydro/SPHENIX/hydro.h index 6a18624689b09fa9692c75edba94987cd5935930..ad1533fe586d855e2cbcca61d04d9b5f3f8c2eb6 100644 --- a/src/hydro/SPHENIX/hydro.h +++ b/src/hydro/SPHENIX/hydro.h @@ -272,27 +272,6 @@ __attribute__((always_inline)) INLINE static void hydro_set_mass( p->mass = m; } -/** - * @brief Returns the velocities drifted to the current time of a particle. - * - * @param p The particle of interest - * @param xp The extended data of the particle. - * @param dt_kick_hydro The time (for hydro accelerations) since the last kick. - * @param dt_kick_grav The time (for gravity accelerations) since the last kick. - * @param v (return) The velocities at the current time. - */ -__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities( - const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro, - float dt_kick_grav, float v[3]) { - - v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro + - xp->a_grav[0] * dt_kick_grav; - v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro + - xp->a_grav[1] * dt_kick_grav; - v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro + - xp->a_grav[2] * dt_kick_grav; -} - /** * @brief Returns the time derivative of internal energy of a particle * @@ -1090,9 +1069,6 @@ __attribute__((always_inline)) INLINE static void hydro_first_init_part( xp->v_full[0] = p->v[0]; xp->v_full[1] = p->v[1]; xp->v_full[2] = p->v[2]; - xp->a_grav[0] = 0.f; - xp->a_grav[1] = 0.f; - xp->a_grav[2] = 0.f; xp->u_full = p->u; hydro_reset_acceleration(p); diff --git a/src/hydro/SPHENIX/hydro_io.h b/src/hydro/SPHENIX/hydro_io.h index e16d3558b117da00c60052fadd8ced87dc3a16dd..a715976574bbb5e0dbcdfb8c7bf5eab91f4a94e1 100644 --- a/src/hydro/SPHENIX/hydro_io.h +++ b/src/hydro/SPHENIX/hydro_io.h @@ -82,9 +82,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; @@ -100,6 +100,7 @@ INLINE static void convert_part_vel(const struct engine* e, const struct cosmology* cosmo = e->cosmology; const integertime_t ti_current = e->ti_current; const double time_base = e->time_base; + const float dt_kick_grav_mesh = e->dt_kick_grav_mesh_for_io; const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin); const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin); @@ -118,8 +119,24 @@ INLINE static void convert_part_vel(const struct engine* e, dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base; } - /* Extrapolate the velocites to the current time */ - hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret); + /* Extrapolate the velocites to the current time (hydro term)*/ + ret[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro; + ret[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro; + ret[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro; + + /* Add the gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav[0] * dt_kick_grav; + ret[1] += p->gpart->a_grav[1] * dt_kick_grav; + ret[2] += p->gpart->a_grav[2] * dt_kick_grav; + } + + /* And the mesh gravity term */ + if (p->gpart != NULL) { + ret[0] += p->gpart->a_grav_mesh[0] * dt_kick_grav_mesh; + ret[1] += p->gpart->a_grav_mesh[1] * dt_kick_grav_mesh; + ret[2] += p->gpart->a_grav_mesh[2] * dt_kick_grav_mesh; + } /* Conversion from internal units to peculiar velocities */ ret[0] *= cosmo->a_inv; diff --git a/src/hydro/SPHENIX/hydro_part.h b/src/hydro/SPHENIX/hydro_part.h index 215c2b968d55acb11d62e2ced9414cb15b17fff0..4a3c2877909bcbf5a11769e6f6d30ce71a1d4010 100644 --- a/src/hydro/SPHENIX/hydro_part.h +++ b/src/hydro/SPHENIX/hydro_part.h @@ -53,9 +53,6 @@ struct xpart { /*! Velocity at the last full step. */ float v_full[3]; - /*! Gravitational acceleration at the last full step. */ - float a_grav[3]; - /*! Internal energy at the last full step. */ float u_full; diff --git a/src/hydro/Shadowswift/hydro_io.h b/src/hydro/Shadowswift/hydro_io.h index b4b352fc0151d0967778a9d75e55fb61f3bf7c6c..c099d06441840fd8755265efda400ee2e7a418ee 100644 --- a/src/hydro/Shadowswift/hydro_io.h +++ b/src/hydro/Shadowswift/hydro_io.h @@ -113,9 +113,9 @@ INLINE static void convert_part_pos(const struct engine* e, const struct xpart* xp, double* ret) { const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(p->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(p->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(p->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(p->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(p->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(p->x[2], 0.0, s->dim[2]); } else { ret[0] = p->x[0]; ret[1] = p->x[1]; diff --git a/src/hydro/Shadowswift/hydro_part.h b/src/hydro/Shadowswift/hydro_part.h index 713593003a22b27768555033279786e967ba9e53..bc374e5500c23fc3e9c6210adb1079f6c55accde 100644 --- a/src/hydro/Shadowswift/hydro_part.h +++ b/src/hydro/Shadowswift/hydro_part.h @@ -41,9 +41,6 @@ struct xpart { /* Velocity at the last full step. */ float v_full[3]; - /* Gravitational acceleration at the last full step. */ - float a_grav[3]; - /* Additional data used to record cooling information */ struct cooling_xpart_data cooling_data; diff --git a/src/hydro_io.h b/src/hydro_io.h index dc0bf3af054f2751c9a9198da8893f15bed17b69..60934acb41a7da337efc68b2f2d77de1f35533c5 100644 --- a/src/hydro_io.h +++ b/src/hydro_io.h @@ -34,8 +34,8 @@ #include "./hydro/PressureEnergy/hydro_io.h" #elif defined(HOPKINS_PU_SPH_MONAGHAN) #include "./hydro/PressureEnergyMorrisMonaghanAV/hydro_io.h" -#elif defined(DEFAULT_SPH) -#include "./hydro/Default/hydro_io.h" +#elif defined(PHANTOM_SPH) +#include "./hydro/Phantom/hydro_io.h" #elif defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH) #include "./hydro/Gizmo/hydro_io.h" #elif defined(SHADOWFAX_SPH) diff --git a/src/hydro_logger.h b/src/hydro_logger.h index 14741679d2c208861a6c76263309ffd1cee49460..fe4a3b75c80ffa0893f3f4d6fb65be11a3acc4be 100644 --- a/src/hydro_logger.h +++ b/src/hydro_logger.h @@ -39,7 +39,7 @@ #error TODO #elif defined(HOPKINS_PU_SPH_MONAGHAN) #error TODO -#elif defined(DEFAULT_SPH) +#elif defined(PHANTOM_SPH) #error TODO #elif defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH) #error TODO diff --git a/src/hydro_parameters.h b/src/hydro_parameters.h index ddc9366c74c5bda58985424d51a8616c9ddc416a..507d2fa2974963c194a901d8eea2a2ed3c1f7fca 100644 --- a/src/hydro_parameters.h +++ b/src/hydro_parameters.h @@ -42,8 +42,8 @@ #include "./hydro/PressureEnergy/hydro_parameters.h" #elif defined(HOPKINS_PU_SPH_MONAGHAN) #include "./hydro/PressureEnergyMorrisMonaghanAV/hydro_parameters.h" -#elif defined(DEFAULT_SPH) -#include "./hydro/Default/hydro_parameters.h" +#elif defined(PHANTOM_SPH) +#include "./hydro/Phantom/hydro_parameters.h" #elif defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH) #include "./hydro/Gizmo/hydro_parameters.h" #elif defined(SHADOWFAX_SPH) diff --git a/src/kick.h b/src/kick.h index c06fde595ee1a8bc264b27cd1ed2b7f2cf97b9b0..a74bfae133f35230dd5fd6e58268577998263239 100644 --- a/src/kick.h +++ b/src/kick.h @@ -30,6 +30,98 @@ #include "stars.h" #include "timeline.h" +/** + * @brief Compute the time-step length for a gravity kick. + * + * @param ti_beg Start of the time-step (on the integer time-line). + * @param ti_end End of the time-step (on the integer time-line). + * @param time_base Minimal time-step size on the time-line. + * @param with_cosmology Are we running with cosmology integration? + * @param cosmo The #cosmology object. + * + * @return The time-step size for the gravity kick (internal units). + */ +__attribute__((always_inline)) INLINE static double kick_get_grav_kick_dt( + const integertime_t ti_beg, const integertime_t ti_end, + const double time_base, const int with_cosmology, + const struct cosmology *cosmo) { + + if (with_cosmology) { + return cosmology_get_grav_kick_factor(cosmo, ti_beg, ti_end); + } else { + return (ti_end - ti_beg) * time_base; + } +} + +/** + * @brief Compute the time-step length for a hydro kick. + * + * @param ti_beg Start of the time-step (on the integer time-line). + * @param ti_end End of the time-step (on the integer time-line). + * @param time_base Minimal time-step size on the time-line. + * @param with_cosmology Are we running with cosmology integration? + * @param cosmo The #cosmology object. + * + * @return The time-step size for the hydro kick (internal units). + */ +__attribute__((always_inline)) INLINE static double kick_get_hydro_kick_dt( + const integertime_t ti_beg, const integertime_t ti_end, + const double time_base, const int with_cosmology, + const struct cosmology *cosmo) { + + if (with_cosmology) { + return cosmology_get_hydro_kick_factor(cosmo, ti_beg, ti_end); + } else { + return (ti_end - ti_beg) * time_base; + } +} + +/** + * @brief Compute the time-step length for a thermal kick. + * + * @param ti_beg Start of the time-step (on the integer time-line). + * @param ti_end End of the time-step (on the integer time-line). + * @param time_base Minimal time-step size on the time-line. + * @param with_cosmology Are we running with cosmology integration? + * @param cosmo The #cosmology object. + * + * @return The time-step size for the thermal kick (internal units). + */ +__attribute__((always_inline)) INLINE static double kick_get_therm_kick_dt( + const integertime_t ti_beg, const integertime_t ti_end, + const double time_base, const int with_cosmology, + const struct cosmology *cosmo) { + + if (with_cosmology) { + return cosmology_get_therm_kick_factor(cosmo, ti_beg, ti_end); + } else { + return (ti_end - ti_beg) * time_base; + } +} + +/** + * @brief Compute the time-step length for a gravity correction kick. + * + * @param ti_beg Start of the time-step (on the integer time-line). + * @param ti_end End of the time-step (on the integer time-line). + * @param time_base Minimal time-step size on the time-line. + * @param with_cosmology Are we running with cosmology integration? + * @param cosmo The #cosmology object. + * + * @return The time-step size for the gravity correction kick (internal units). + */ +__attribute__((always_inline)) INLINE static double kick_get_corr_kick_dt( + const integertime_t ti_beg, const integertime_t ti_end, + const double time_base, const int with_cosmology, + const struct cosmology *cosmo) { + + if (with_cosmology) { + return cosmology_get_corr_kick_factor(cosmo, ti_beg, ti_end); + } else { + return (ti_end - ti_beg) * time_base; + } +} + /** * @brief Perform the 'kick' operation on a #gpart * @@ -38,10 +130,17 @@ * @param ti_start The starting (integer) time of the kick (for debugging * checks). * @param ti_end The ending (integer) time of the kick (for debugging checks). + * @param dt_kick_mesh_grav The kick time-step for mesh gravity accelerations. + * @param ti_start_mesh The starting (integer) time of the mesh kick (for + * debugging checks). + * @param ti_end_mesh The ending (integer) time of the mesh kick (for debugging + * checks). */ __attribute__((always_inline)) INLINE static void kick_gpart( - struct gpart *restrict gp, double dt_kick_grav, integertime_t ti_start, - integertime_t ti_end) { + struct gpart *restrict gp, const double dt_kick_grav, + const integertime_t ti_start, const integertime_t ti_end, + const double dt_kick_mesh_grav, const integertime_t ti_start_mesh, + const integertime_t ti_end_mesh) { #ifdef SWIFT_DEBUG_CHECKS if (gp->ti_kick != ti_start) @@ -51,6 +150,24 @@ __attribute__((always_inline)) INLINE static void kick_gpart( gp->ti_kick, ti_start, ti_end, gp->id_or_neg_offset); gp->ti_kick = ti_end; + + if (ti_start_mesh != -1 && gp->ti_kick_mesh != ti_start_mesh) + error( + "g-particle has not been kicked (mesh) to the current time " + "gp->ti_kick_mesh=%lld, " + "ti_start_mesh=%lld, ti_end_mesh=%lld id=%lld", + gp->ti_kick_mesh, ti_start_mesh, ti_end_mesh, gp->id_or_neg_offset); + + /* Record the mesh kick if we are doing one */ + if (ti_start_mesh != -1) gp->ti_kick_mesh = ti_end_mesh; + + if (ti_start_mesh == -1 && dt_kick_mesh_grav != 0.) + error("Incorrect dt_kick for the mesh! %e (should be 0)", + dt_kick_mesh_grav); + + if (ti_start_mesh != -1 && dt_kick_mesh_grav == 0.) + error("Incorrect dt_kick for the mesh! %e (should not be 0)", + dt_kick_mesh_grav); #endif /* Kick particles in momentum space */ @@ -58,6 +175,11 @@ __attribute__((always_inline)) INLINE static void kick_gpart( gp->v_full[1] += gp->a_grav[1] * dt_kick_grav; gp->v_full[2] += gp->a_grav[2] * dt_kick_grav; + /* Same for the long-range forces */ + gp->v_full[0] += gp->a_grav_mesh[0] * dt_kick_mesh_grav; + gp->v_full[1] += gp->a_grav_mesh[1] * dt_kick_mesh_grav; + gp->v_full[2] += gp->a_grav_mesh[2] * dt_kick_mesh_grav; + /* Kick extra variables */ gravity_kick_extra(gp, dt_kick_grav); } @@ -69,6 +191,7 @@ __attribute__((always_inline)) INLINE static void kick_gpart( * @param xp The #xpart of the particle. * @param dt_kick_hydro The kick time-step for hydro accelerations. * @param dt_kick_grav The kick time-step for gravity accelerations. + * @param dt_kick_mesh_grav The kick time-step for mesh gravity accelerations. * @param dt_kick_therm The kick time-step for changes in thermal state. * @param dt_kick_corr The kick time-step for the gizmo-mfv gravity correction. * @param cosmo The cosmological model. @@ -77,13 +200,20 @@ __attribute__((always_inline)) INLINE static void kick_gpart( * @param ti_start The starting (integer) time of the kick (for debugging * checks). * @param ti_end The ending (integer) time of the kick (for debugging checks). + * @param ti_start_mesh The starting (integer) time of the mesh kick (for + * debugging checks). + * @param ti_end_mesh The ending (integer) time of the mesh kick (for debugging + * checks). */ __attribute__((always_inline)) INLINE static void kick_part( - struct part *restrict p, struct xpart *restrict xp, double dt_kick_hydro, - double dt_kick_grav, double dt_kick_therm, double dt_kick_corr, - const struct cosmology *cosmo, const struct hydro_props *hydro_props, - const struct entropy_floor_properties *floor_props, integertime_t ti_start, - integertime_t ti_end) { + struct part *restrict p, struct xpart *restrict xp, + const double dt_kick_hydro, const double dt_kick_grav, + const double dt_kick_mesh_grav, const double dt_kick_therm, + const double dt_kick_corr, const struct cosmology *cosmo, + const struct hydro_props *hydro_props, + const struct entropy_floor_properties *floor_props, + const integertime_t ti_start, const integertime_t ti_end, + const integertime_t ti_start_mesh, const integertime_t ti_end_mesh) { #ifdef SWIFT_DEBUG_CHECKS if (p->ti_kick != ti_start) @@ -94,6 +224,14 @@ __attribute__((always_inline)) INLINE static void kick_part( p->limiter_data.wakeup); p->ti_kick = ti_end; + + if (ti_start_mesh == -1 && dt_kick_mesh_grav != 0.) + error("Incorrect dt_kick for the mesh! %e (should be 0)", + dt_kick_mesh_grav); + + if (ti_start_mesh != -1 && dt_kick_mesh_grav == 0.) + error("Incorrect dt_kick for the mesh! %e (should not be 0)", + dt_kick_mesh_grav); #endif /* Kick particles in momentum space (hydro acc.) */ @@ -108,6 +246,13 @@ __attribute__((always_inline)) INLINE static void kick_part( xp->v_full[2] += p->gpart->a_grav[2] * dt_kick_grav; } + /* Kick particles in momentum space (mesh grav acc.) */ + if (p->gpart != NULL) { + xp->v_full[0] += p->gpart->a_grav_mesh[0] * dt_kick_mesh_grav; + xp->v_full[1] += p->gpart->a_grav_mesh[1] * dt_kick_mesh_grav; + xp->v_full[2] += p->gpart->a_grav_mesh[2] * dt_kick_mesh_grav; + } + /* Give the gpart friend the same velocity */ if (p->gpart != NULL) { p->gpart->v_full[0] = xp->v_full[0]; @@ -115,7 +260,7 @@ __attribute__((always_inline)) INLINE static void kick_part( p->gpart->v_full[2] = xp->v_full[2]; } - /* Extra kick work */ + /* Extra kick work (thermal quantities etc.) */ hydro_kick_extra(p, xp, dt_kick_therm, dt_kick_grav, dt_kick_hydro, dt_kick_corr, cosmo, hydro_props, floor_props); if (p->gpart != NULL) gravity_kick_extra(p->gpart, dt_kick_grav); @@ -129,10 +274,17 @@ __attribute__((always_inline)) INLINE static void kick_part( * @param ti_start The starting (integer) time of the kick (for debugging * checks). * @param ti_end The ending (integer) time of the kick (for debugging checks). + * @param dt_kick_mesh_grav The kick time-step for mesh gravity accelerations. + * @param ti_start_mesh The starting (integer) time of the mesh kick (for + * debugging checks). + * @param ti_end_mesh The ending (integer) time of the mesh kick (for debugging + * checks). */ __attribute__((always_inline)) INLINE static void kick_spart( - struct spart *restrict sp, double dt_kick_grav, integertime_t ti_start, - integertime_t ti_end) { + struct spart *restrict sp, const double dt_kick_grav, + const integertime_t ti_start, const integertime_t ti_end, + const double dt_kick_mesh_grav, const integertime_t ti_start_mesh, + const integertime_t ti_end_mesh) { #ifdef SWIFT_DEBUG_CHECKS if (sp->ti_kick != ti_start) @@ -142,6 +294,14 @@ __attribute__((always_inline)) INLINE static void kick_spart( sp->ti_kick, ti_start, ti_end, sp->id); sp->ti_kick = ti_end; + + if (ti_start_mesh == -1 && dt_kick_mesh_grav != 0.) + error("Incorrect dt_kick for the mesh! %e (should be 0)", + dt_kick_mesh_grav); + + if (ti_start_mesh != -1 && dt_kick_mesh_grav == 0.) + error("Incorrect dt_kick for the mesh! %e (should not be 0)", + dt_kick_mesh_grav); #endif /* Kick particles in momentum space */ @@ -149,6 +309,11 @@ __attribute__((always_inline)) INLINE static void kick_spart( sp->v[1] += sp->gpart->a_grav[1] * dt_kick_grav; sp->v[2] += sp->gpart->a_grav[2] * dt_kick_grav; + /* Kick particles in momentum space (mesh forces) */ + sp->v[0] += sp->gpart->a_grav_mesh[0] * dt_kick_mesh_grav; + sp->v[1] += sp->gpart->a_grav_mesh[1] * dt_kick_mesh_grav; + sp->v[2] += sp->gpart->a_grav_mesh[2] * dt_kick_mesh_grav; + /* Give the gpart friend the same velocity */ sp->gpart->v_full[0] = sp->v[0]; sp->gpart->v_full[1] = sp->v[1]; @@ -166,10 +331,17 @@ __attribute__((always_inline)) INLINE static void kick_spart( * @param ti_start The starting (integer) time of the kick (for debugging * checks). * @param ti_end The ending (integer) time of the kick (for debugging checks). + * @param dt_kick_mesh_grav The kick time-step for mesh gravity accelerations. + * @param ti_start_mesh The starting (integer) time of the mesh kick (for + * debugging checks). + * @param ti_end_mesh The ending (integer) time of the mesh kick (for debugging + * checks). */ __attribute__((always_inline)) INLINE static void kick_bpart( - struct bpart *restrict bp, double dt_kick_grav, integertime_t ti_start, - integertime_t ti_end) { + struct bpart *restrict bp, const double dt_kick_grav, + const integertime_t ti_start, const integertime_t ti_end, + const double dt_kick_mesh_grav, const integertime_t ti_start_mesh, + const integertime_t ti_end_mesh) { #ifdef SWIFT_DEBUG_CHECKS if (bp->ti_kick != ti_start) @@ -179,6 +351,14 @@ __attribute__((always_inline)) INLINE static void kick_bpart( bp->ti_kick, ti_start, ti_end, bp->id); bp->ti_kick = ti_end; + + if (ti_start_mesh == -1 && dt_kick_mesh_grav != 0.) + error("Incorrect dt_kick for the mesh! %e (should be 0)", + dt_kick_mesh_grav); + + if (ti_start_mesh != -1 && dt_kick_mesh_grav == 0.) + error("Incorrect dt_kick for the mesh! %e (should not be 0)", + dt_kick_mesh_grav); #endif /* Kick particles in momentum space */ @@ -186,6 +366,11 @@ __attribute__((always_inline)) INLINE static void kick_bpart( bp->v[1] += bp->gpart->a_grav[1] * dt_kick_grav; bp->v[2] += bp->gpart->a_grav[2] * dt_kick_grav; + /* Kick particles in momentum space (mesh forces)*/ + bp->v[0] += bp->gpart->a_grav_mesh[0] * dt_kick_mesh_grav; + bp->v[1] += bp->gpart->a_grav_mesh[1] * dt_kick_mesh_grav; + bp->v[2] += bp->gpart->a_grav_mesh[2] * dt_kick_mesh_grav; + /* Give the gpart friend the same velocity */ bp->gpart->v_full[0] = bp->v[0]; bp->gpart->v_full[1] = bp->v[1]; @@ -203,10 +388,17 @@ __attribute__((always_inline)) INLINE static void kick_bpart( * @param ti_start The starting (integer) time of the kick (for debugging * checks). * @param ti_end The ending (integer) time of the kick (for debugging checks). + * @param dt_kick_mesh_grav The kick time-step for mesh gravity accelerations. + * @param ti_start_mesh The starting (integer) time of the mesh kick (for + * debugging checks). + * @param ti_end_mesh The ending (integer) time of the mesh kick (for debugging + * checks). */ __attribute__((always_inline)) INLINE static void kick_sink( - struct sink *restrict sink, double dt_kick_grav, integertime_t ti_start, - integertime_t ti_end) { + struct sink *restrict sink, const double dt_kick_grav, + const integertime_t ti_start, const integertime_t ti_end, + const double dt_kick_mesh_grav, const integertime_t ti_start_mesh, + const integertime_t ti_end_mesh) { #ifdef SWIFT_DEBUG_CHECKS if (sink->ti_kick != ti_start) @@ -217,6 +409,15 @@ __attribute__((always_inline)) INLINE static void kick_sink( sink->ti_kick, ti_start, ti_end, sink->id); sink->ti_kick = ti_end; + + if (ti_start_mesh == -1 && dt_kick_mesh_grav != 0.) + error("Incorrect dt_kick for the mesh! %e (should be 0)", + dt_kick_mesh_grav); + + if (ti_start_mesh != -1 && dt_kick_mesh_grav == 0.) + error("Incorrect dt_kick for the mesh! %e (should not be 0)", + dt_kick_mesh_grav); + #endif /* Kick particles in momentum space */ @@ -224,6 +425,11 @@ __attribute__((always_inline)) INLINE static void kick_sink( sink->v[1] += sink->gpart->a_grav[1] * dt_kick_grav; sink->v[2] += sink->gpart->a_grav[2] * dt_kick_grav; + /* Kick particles in momentum space (mesh forces) */ + sink->v[0] += sink->gpart->a_grav_mesh[0] * dt_kick_mesh_grav; + sink->v[1] += sink->gpart->a_grav_mesh[1] * dt_kick_mesh_grav; + sink->v[2] += sink->gpart->a_grav_mesh[2] * dt_kick_mesh_grav; + /* Give the gpart friend the same velocity */ sink->gpart->v_full[0] = sink->v[0]; sink->gpart->v_full[1] = sink->v[1]; diff --git a/src/mesh_gravity.c b/src/mesh_gravity.c index 0864092b17f26a8542918449b331efb003cbf5c6..135fc68b66a45faa902d54bc93d16c94d3fed21c 100644 --- a/src/mesh_gravity.c +++ b/src/mesh_gravity.c @@ -194,8 +194,10 @@ void cell_gpart_to_mesh_CIC(const struct cell* c, double* rho, const int N, const struct gpart* gparts = c->grav.parts; /* Assign all the gpart of that cell to the mesh */ - for (int i = 0; i < gcount; ++i) + for (int i = 0; i < gcount; ++i) { + if (gparts[i].time_bin == time_bin_inhibited) continue; gpart_to_mesh_CIC(&gparts[i], rho, N, fac, dim); + } } /** @@ -205,11 +207,30 @@ void cell_gpart_to_mesh_CIC(const struct cell* c, double* rho, const int N, struct cic_mapper_data { const struct cell* cells; double* rho; + double* potential; int N; double fac; double dim[3]; + float const_G; }; +void gpart_to_mesh_CIC_mapper(void* map_data, int num, void* extra) { + + const struct cic_mapper_data* data = (struct cic_mapper_data*)extra; + double* rho = data->rho; + const int N = data->N; + const double fac = data->fac; + const double dim[3] = {data->dim[0], data->dim[1], data->dim[2]}; + + /* Pointer to the chunk to be processed */ + const struct gpart* gparts = (const struct gpart*)map_data; + + for (int i = 0; i < num; ++i) { + if (gparts[i].time_bin == time_bin_inhibited) continue; + gpart_to_mesh_CIC(&gparts[i], rho, N, fac, dim); + } +} + /** * @brief Threadpool mapper function for the mesh CIC assignment of a cell. * @@ -258,8 +279,8 @@ void cell_gpart_to_mesh_CIC_mapper(void* map_data, int num, void* extra) { * @param fac width of a mesh cell. * @param dim The dimensions of the simulation box. */ -void mesh_to_gparts_CIC(struct gpart* gp, const double* pot, const int N, - const double fac, const double dim[3]) { +void mesh_to_gpart_CIC(struct gpart* gp, const double* pot, const int N, + const double fac, const double dim[3]) { /* Box wrap the gpart's position */ const double pos_x = box_wrap(gp->x[0], 0., dim[0]); @@ -288,8 +309,10 @@ void mesh_to_gparts_CIC(struct gpart* gp, const double* pot, const int N, #endif #ifdef SWIFT_GRAVITY_FORCE_CHECKS - if (gp->a_grav_PM[0] != 0. || gp->potential_PM != 0.) - error("Particle with non-initalised stuff"); + if (gp->a_grav_mesh[0] != 0.) error("Particle with non-initalised stuff"); +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + if (gp->potential_mesh != 0.) error("Particle with non-initalised stuff"); +#endif #endif /* First, copy the necessary part of the mesh for stencil operations */ @@ -335,16 +358,111 @@ void mesh_to_gparts_CIC(struct gpart* gp, const double* pot, const int N, /* ---- */ /* Store things back */ - gp->a_grav[0] += fac * a[0]; - gp->a_grav[1] += fac * a[1]; - gp->a_grav[2] += fac * a[2]; - gravity_add_comoving_potential(gp, p); -#ifdef SWIFT_GRAVITY_FORCE_CHECKS - gp->potential_PM = p; - gp->a_grav_PM[0] = fac * a[0]; - gp->a_grav_PM[1] = fac * a[1]; - gp->a_grav_PM[2] = fac * a[2]; + gp->a_grav_mesh[0] = fac * a[0]; + gp->a_grav_mesh[1] = fac * a[1]; + gp->a_grav_mesh[2] = fac * a[2]; + gravity_add_comoving_mesh_potential(gp, p); +} + +void cell_mesh_to_gpart_CIC(const struct cell* c, const double* potential, + const int N, const double fac, const float const_G, + const double dim[3]) { + + const int gcount = c->grav.count; + struct gpart* gparts = c->grav.parts; + + /* Assign all the gpart of that cell to the mesh */ + for (int i = 0; i < gcount; ++i) { + + struct gpart* gp = &gparts[i]; + + if (gp->time_bin == time_bin_inhibited) continue; + + gp->a_grav_mesh[0] = 0.f; + gp->a_grav_mesh[1] = 0.f; + gp->a_grav_mesh[2] = 0.f; +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential_mesh = 0.f; +#endif + + mesh_to_gpart_CIC(gp, potential, N, fac, dim); + + gp->a_grav_mesh[0] *= const_G; + gp->a_grav_mesh[1] *= const_G; + gp->a_grav_mesh[2] *= const_G; +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential_mesh *= const_G; #endif + } +} + +void mesh_to_gpart_CIC_mapper(void* map_data, int num, void* extra) { + + /* Unpack the shared information */ + const struct cic_mapper_data* data = (struct cic_mapper_data*)extra; + const double* const potential = data->potential; + const int N = data->N; + const double fac = data->fac; + const double dim[3] = {data->dim[0], data->dim[1], data->dim[2]}; + const float const_G = data->const_G; + + /* Pointer to the chunk to be processed */ + struct gpart* gparts = (struct gpart*)map_data; + + /* Loop over the elements assigned to this thread */ + for (int i = 0; i < num; ++i) { + + struct gpart* gp = &gparts[i]; + if (gp->time_bin == time_bin_inhibited) continue; + + gp->a_grav_mesh[0] = 0.f; + gp->a_grav_mesh[1] = 0.f; + gp->a_grav_mesh[2] = 0.f; +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential_mesh = 0.f; +#endif + + mesh_to_gpart_CIC(gp, potential, N, fac, dim); + + gp->a_grav_mesh[0] *= const_G; + gp->a_grav_mesh[1] *= const_G; + gp->a_grav_mesh[2] *= const_G; +#ifndef SWIFT_GRAVITY_NO_POTENTIAL + gp->potential_mesh *= const_G; +#endif + } +} + +/** + * @brief Threadpool mapper function for the mesh CIC assignment of a cell. + * + * @param map_data A chunk of the list of local cells. + * @param num The number of cells in the chunk. + * @param extra The information about the mesh and cells. + */ +void cell_mesh_to_gpart_CIC_mapper(void* map_data, int num, void* extra) { + + /* Unpack the shared information */ + const struct cic_mapper_data* data = (struct cic_mapper_data*)extra; + const struct cell* cells = data->cells; + const double* const potential = data->potential; + const int N = data->N; + const double fac = data->fac; + const double dim[3] = {data->dim[0], data->dim[1], data->dim[2]}; + const float const_G = data->const_G; + + /* Pointer to the chunk to be processed */ + int* local_cells = (int*)map_data; + + /* Loop over the elements assigned to this thread */ + for (int i = 0; i < num; ++i) { + + /* Pointer to local cell */ + const struct cell* c = &cells[local_cells[i]]; + + /* Assign this cell's content to the mesh */ + cell_mesh_to_gpart_CIC(c, potential, N, fac, const_G, dim); + } } /** @@ -520,7 +638,6 @@ void pm_mesh_compute_potential(struct pm_mesh* mesh, const struct space* s, /* Use the memory allocated for the potential to temporarily store rho */ double* restrict rho = mesh->potential; if (rho == NULL) error("Error allocating memory for density mesh"); - bzero(rho, N * N * N * sizeof(double)); /* Allocates some memory for the mesh in Fourier space */ fftw_complex* restrict frho = @@ -545,17 +662,30 @@ void pm_mesh_compute_potential(struct pm_mesh* mesh, const struct space* s, struct cic_mapper_data data; data.cells = s->cells_top; data.rho = rho; + data.potential = NULL; data.N = N; data.fac = cell_fac; data.dim[0] = dim[0]; data.dim[1] = dim[1]; data.dim[2] = dim[2]; + data.const_G = 0.f; - /* Do a parallel CIC mesh assignment of the gparts but only using - the local top-level cells */ - threadpool_map(tp, cell_gpart_to_mesh_CIC_mapper, (void*)local_cells, - nr_local_cells, sizeof(int), threadpool_auto_chunk_size, - (void*)&data); + if (nr_local_cells == 0) { + + /* We don't have a cell infrastructure in place so we need to + * directly loop over the particles */ + threadpool_map(tp, gpart_to_mesh_CIC_mapper, s->gparts, s->nr_gparts, + sizeof(struct gpart), threadpool_auto_chunk_size, + (void*)&data); + + } else { /* Normal case */ + + /* Do a parallel CIC mesh assignment of the gparts but only using + * the local top-level cells */ + threadpool_map(tp, cell_gpart_to_mesh_CIC_mapper, (void*)local_cells, + nr_local_cells, sizeof(int), threadpool_auto_chunk_size, + (void*)&data); + } if (verbose) message("Gpart assignment took %.3f %s.", @@ -575,8 +705,8 @@ void pm_mesh_compute_potential(struct pm_mesh* mesh, const struct space* s, clocks_from_ticks(getticks() - tic), clocks_getunit()); #endif - /* message("\n\n\n DENSITY"); */ - /* print_array(rho, N); */ + // message("\n\n\n DENSITY"); + // print_array(rho, N); tic = getticks(); @@ -617,58 +747,46 @@ void pm_mesh_compute_potential(struct pm_mesh* mesh, const struct space* s, /* message("\n\n\n POTENTIAL"); */ /* print_array(mesh->potential, N); */ - /* Clean-up the mess */ - fftw_destroy_plan(forward_plan); - fftw_destroy_plan(inverse_plan); - memuse_log_allocation("fftw_frho", frho, 0, 0); - fftw_free(frho); - -#else - error("No FFTW library found. Cannot compute periodic long-range forces."); -#endif -} + tic = getticks(); -/** - * @brief Interpolate the forces and potential from the mesh to the #gpart. - * - * We use CIC interpolation. The resulting accelerations and potential must - * be multiplied by G_newton. - * - * @param mesh The #pm_mesh (containing the potential) to interpolate from. - * @param e The #engine (to check active status). - * @param gparts The #gpart to interpolate to. - * @param gcount The number of #gpart. - */ -void pm_mesh_interpolate_forces(const struct pm_mesh* mesh, - const struct engine* e, struct gpart* gparts, - int gcount) { + /* Gather the mesh shared information to be used by the threads */ + data.cells = s->cells_top; + data.rho = NULL; + data.potential = mesh->potential; + data.N = N; + data.fac = cell_fac; + data.dim[0] = dim[0]; + data.dim[1] = dim[1]; + data.dim[2] = dim[2]; + data.const_G = s->e->physical_constants->const_newton_G; -#ifdef HAVE_FFTW + if (nr_local_cells == 0) { - const int N = mesh->N; - const double cell_fac = mesh->cell_fac; - const double* potential = mesh->potential; - const double dim[3] = {e->s->dim[0], e->s->dim[1], e->s->dim[2]}; + /* We don't have a cell infrastructure in place so we need to + * directly loop over the particles */ + threadpool_map(tp, mesh_to_gpart_CIC_mapper, s->gparts, s->nr_gparts, + sizeof(struct gpart), threadpool_auto_chunk_size, + (void*)&data); - /* Get the potential from the mesh to the active gparts using CIC */ - for (int i = 0; i < gcount; ++i) { - struct gpart* gp = &gparts[i]; + } else { /* Normal case */ - if (gpart_is_active(gp, e)) { + /* Do a parallel CIC mesh interpolation onto the gparts but only using + the local top-level cells */ + threadpool_map(tp, cell_mesh_to_gpart_CIC_mapper, (void*)local_cells, + nr_local_cells, sizeof(int), threadpool_auto_chunk_size, + (void*)&data); + } -#ifdef SWIFT_DEBUG_CHECKS - /* Check that particles have been drifted to the current time */ - if (gp->ti_drift != e->ti_current) - error("gpart not drifted to current time"); + if (verbose) + message("Gpart mesh forces took %.3f %s.", + clocks_from_ticks(getticks() - tic), clocks_getunit()); - /* Check that the particle was initialised */ - if (gp->initialised == 0) - error("Adding forces to an un-initialised gpart."); -#endif + /* Clean-up the mess */ + fftw_destroy_plan(forward_plan); + fftw_destroy_plan(inverse_plan); + memuse_log_allocation("fftw_frho", frho, 0, 0); + fftw_free(frho); - mesh_to_gparts_CIC(gp, potential, N, cell_fac, dim); - } - } #else error("No FFTW library found. Cannot compute periodic long-range forces."); #endif @@ -747,6 +865,10 @@ void pm_mesh_init(struct pm_mesh* mesh, const struct gravity_props* props, mesh->r_cut_max = mesh->r_s * props->r_cut_max_ratio; mesh->r_cut_min = mesh->r_s * props->r_cut_min_ratio; mesh->potential = NULL; + mesh->ti_beg_mesh_last = -1; + mesh->ti_end_mesh_last = -1; + mesh->ti_beg_mesh_next = -1; + mesh->ti_end_mesh_next = -1; if (mesh->N > 1290) error( @@ -793,6 +915,10 @@ void pm_mesh_init_no_mesh(struct pm_mesh* mesh, double dim[3]) { mesh->r_s = FLT_MAX; mesh->r_cut_min = FLT_MAX; mesh->r_cut_max = FLT_MAX; + mesh->ti_beg_mesh_last = -1; + mesh->ti_end_mesh_last = -1; + mesh->ti_beg_mesh_next = -1; + mesh->ti_end_mesh_next = -1; } /** diff --git a/src/mesh_gravity.h b/src/mesh_gravity.h index 79c4d1b619cb3f73bc8aa39e97f1c5b2f6386386..7d3a3b038fcebfe949b8ab9655a0fd410bc43b7c 100644 --- a/src/mesh_gravity.h +++ b/src/mesh_gravity.h @@ -24,6 +24,7 @@ /* Local headers */ #include "gravity_properties.h" +#include "timeline.h" /* Forward declarations */ struct engine; @@ -45,6 +46,18 @@ struct pm_mesh { /*! Side-length of the mesh */ int N; + /*! Integer time-step end of the mesh force for the last step */ + integertime_t ti_end_mesh_last; + + /*! Integer time-step beginning of the mesh force for the last step */ + integertime_t ti_beg_mesh_last; + + /*! Integer time-step end of the mesh force for the next step*/ + integertime_t ti_end_mesh_next; + + /*! Integer time-step beginning of the mesh force for the next step */ + integertime_t ti_beg_mesh_next; + /*! Conversion factor between box and mesh size */ double cell_fac; @@ -72,9 +85,6 @@ void pm_mesh_init(struct pm_mesh *mesh, const struct gravity_props *props, void pm_mesh_init_no_mesh(struct pm_mesh *mesh, double dim[3]); void pm_mesh_compute_potential(struct pm_mesh *mesh, const struct space *s, struct threadpool *tp, int verbose); -void pm_mesh_interpolate_forces(const struct pm_mesh *mesh, - const struct engine *e, struct gpart *gparts, - int gcount); void pm_mesh_clean(struct pm_mesh *mesh); void pm_mesh_allocate(struct pm_mesh *mesh); diff --git a/src/parallel_io.c b/src/parallel_io.c index 5bac0214bb4791db035a2ed8ea3744ef32122c0a..4e98c24397d51da2e1a43899aa40ab22f43db96d 100644 --- a/src/parallel_io.c +++ b/src/parallel_io.c @@ -1538,8 +1538,8 @@ void write_output_parallel(struct engine* e, } /* Write the location of the particles in the arrays */ - io_write_cell_offsets(h_grp_cells, e->s->cdim, e->s->dim, e->s->pos_dithering, - e->s->cells_top, e->s->nr_cells, e->s->width, mpi_rank, + io_write_cell_offsets(h_grp_cells, e->s->cdim, e->s->dim, e->s->cells_top, + e->s->nr_cells, e->s->width, mpi_rank, /*distributed=*/0, N_total, offset, numFields, internal_units, snapshot_units); diff --git a/src/part.h b/src/part.h index 136ff23f6e1f820204541b86a7612ed5d1defdee..87dedd70df10995706ed188951862e967be5bb4b 100644 --- a/src/part.h +++ b/src/part.h @@ -61,8 +61,8 @@ struct threadpool; #elif defined(HOPKINS_PU_SPH_MONAGHAN) #include "./hydro/PressureEnergyMorrisMonaghanAV/hydro_part.h" #define hydro_need_extra_init_loop 0 -#elif defined(DEFAULT_SPH) -#include "./hydro/Default/hydro_part.h" +#elif defined(PHANTOM_SPH) +#include "./hydro/Phantom/hydro_part.h" #define EXTRA_HYDRO_LOOP #define hydro_need_extra_init_loop 0 #elif defined(GIZMO_MFV_SPH) || defined(GIZMO_MFM_SPH) @@ -91,8 +91,6 @@ struct threadpool; /* Import the right gravity particle definition */ #if defined(DEFAULT_GRAVITY) #include "./gravity/Default/gravity_part.h" -#elif defined(POTENTIAL_GRAVITY) -#include "./gravity/Potential/gravity_part.h" #elif defined(MULTI_SOFTENING_GRAVITY) #include "./gravity/MultiSoftening/gravity_part.h" #else diff --git a/src/restart.c b/src/restart.c index 91441fe51bfc97a0a93ac31834a6b39b54a17e58..63d1bee0345cb378f098218fdcd0e061bdc33bf9 100644 --- a/src/restart.c +++ b/src/restart.c @@ -128,6 +128,8 @@ void restart_locate_free(int nfiles, char **files) { */ void restart_write(struct engine *e, const char *filename) { + ticks tic = getticks(); + /* Save a backup the existing restart file, if requested. */ if (e->restart_save) restart_save_previous(filename); @@ -150,6 +152,10 @@ void restart_write(struct engine *e, const char *filename) { "endsignature", "SWIFT end signature"); fclose(stream); + + if (e->verbose) + message("took %.3f %s.", clocks_from_ticks(getticks() - tic), + clocks_getunit()); } /** diff --git a/src/rt/M1closure/rt.h b/src/rt/M1closure/rt.h index 0ab19a251fe1c1afdb30d2c2e534656c0133bb49..b99aa2009ba2ff99a167673e938ff4536172118d 100644 --- a/src/rt/M1closure/rt.h +++ b/src/rt/M1closure/rt.h @@ -24,6 +24,13 @@ * @brief Main header file for the M1 Closure radiative transfer scheme. */ +/** + * @brief Update the photon number of a particle, i.e. compute + * E^{n+1} = E^n + dt * dE_* / dt + */ +__attribute__((always_inline)) INLINE static void +rt_injection_update_photon_density(struct part* restrict p) {} + /** * @brief First initialisation of the RT extra hydro particle data. */ diff --git a/src/rt/debug/rt.h b/src/rt/debug/rt.h index e9a3a3f593bd335fcb3da96477a1862d0e9df0ae..92df9619935bd74cd42e0dadab22fa7947e4064a 100644 --- a/src/rt/debug/rt.h +++ b/src/rt/debug/rt.h @@ -25,16 +25,15 @@ */ /** - * @brief First initialisation of the RT extra hydro particle data. + * @brief Update the photon number of a particle, i.e. compute + * E^{n+1} = E^n + dt * dE_* / dt */ -__attribute__((always_inline)) INLINE static void rt_first_init_part( - struct part* restrict p) { +__attribute__((always_inline)) INLINE static void +rt_injection_update_photon_density(struct part* restrict p) { - p->rt_data.iact_stars = 0; - p->rt_data.calls_tot = 0; - p->rt_data.calls_per_step = 0; - p->rt_data.calls_self = 0; - p->rt_data.calls_pair = 0; + p->rt_data.photon_number_updated = 1; + p->rt_data.calls_tot += 1; + p->rt_data.calls_per_step += 1; } /** @@ -43,34 +42,43 @@ __attribute__((always_inline)) INLINE static void rt_first_init_part( __attribute__((always_inline)) INLINE static void rt_init_part( struct part* restrict p) { - p->rt_data.iact_stars = 0; p->rt_data.calls_per_step = 0; - p->rt_data.calls_self = 0; - p->rt_data.calls_pair = 0; + p->rt_data.iact_stars_inject = 0; + p->rt_data.calls_self_inject = 0; + p->rt_data.calls_pair_inject = 0; + p->rt_data.photon_number_updated = 0; } /** - * @brief First initialisation of the RT extra star particle data. + * @brief First initialisation of the RT extra hydro particle data. */ -__attribute__((always_inline)) INLINE static void rt_first_init_spart( +__attribute__((always_inline)) INLINE static void rt_first_init_part( + struct part* restrict p) { + + p->rt_data.calls_tot = 0; + rt_init_part(p); +} + +/** + * @brief Initialisation of the RT extra star particle data. + */ +__attribute__((always_inline)) INLINE static void rt_init_spart( struct spart* restrict sp) { - sp->rt_data.iact_hydro = 0; - sp->rt_data.calls_tot = 0; sp->rt_data.calls_per_step = 0; - sp->rt_data.calls_self = 0; - sp->rt_data.calls_pair = 0; + sp->rt_data.iact_hydro_inject = 0; + sp->rt_data.calls_self_inject = 0; + sp->rt_data.calls_pair_inject = 0; } /** * @brief First initialisation of the RT extra star particle data. */ -__attribute__((always_inline)) INLINE static void rt_init_spart( +__attribute__((always_inline)) INLINE static void rt_first_init_spart( struct spart* restrict sp) { - sp->rt_data.iact_hydro = 0; - sp->rt_data.calls_per_step = 0; - sp->rt_data.calls_self = 0; - sp->rt_data.calls_pair = 0; + sp->rt_data.calls_tot = 0; + rt_init_spart(sp); } + #endif /* SWIFT_RT_DEBUG_H */ diff --git a/src/rt/debug/rt_iact.h b/src/rt/debug/rt_iact.h index cd2ec06ca1fdacdd8334c0cda30738ae7e5faadc..c128893f5fb6aa958a4cd0833427b2f621209329 100644 --- a/src/rt/debug/rt_iact.h +++ b/src/rt/debug/rt_iact.h @@ -42,20 +42,20 @@ __attribute__((always_inline)) INLINE static void runner_iact_rt_inject( struct rt_spart_data* restrict sd = &(si->rt_data); struct rt_part_data* restrict pd = &(pj->rt_data); - sd->iact_hydro += 1; sd->calls_tot += 1; sd->calls_per_step += 1; + sd->iact_hydro_inject += 1; - pd->iact_stars += 1; pd->calls_tot += 1; pd->calls_per_step += 1; + pd->iact_stars_inject += 1; if (r2 > 0.f) { - sd->calls_self += 1; - pd->calls_self += 1; + sd->calls_self_inject += 1; + pd->calls_self_inject += 1; } else { - sd->calls_pair += 1; - pd->calls_pair += 1; + sd->calls_pair_inject += 1; + pd->calls_pair_inject += 1; } } diff --git a/src/rt/debug/rt_io.h b/src/rt/debug/rt_io.h index 1b29a16039936361c847fbfd217358d453fb999f..a31aa59ce790b41c3754f7511632f39667a32e53 100644 --- a/src/rt/debug/rt_io.h +++ b/src/rt/debug/rt_io.h @@ -33,25 +33,35 @@ INLINE static int rt_write_particles(const struct part* parts, struct io_props* list) { - list[0] = io_make_output_field("RTStarIact", INT, 1, UNIT_CONV_NO_UNITS, 0, - parts, rt_data.iact_stars, - "number of interactions between this hydro " - "particle and any star particle"); - list[1] = io_make_output_field( - "RTTotalCalls", INT, 1, UNIT_CONV_NO_UNITS, 0, parts, rt_data.calls_tot, - "total number of calls to this particle during the run"); - list[2] = io_make_output_field( - "RTCallsThisStep", INT, 1, UNIT_CONV_NO_UNITS, 0, parts, - rt_data.calls_per_step, - "number of calls to this particle during one time step"); - list[3] = io_make_output_field( - "RTCallsSelf", INT, 1, UNIT_CONV_NO_UNITS, 0, parts, rt_data.calls_self, - "number of calls to this particle during one time step in self task"); - list[4] = io_make_output_field( - "RTCallsPair", INT, 1, UNIT_CONV_NO_UNITS, 0, parts, rt_data.calls_pair, - "number of calls to this particle during one time step in self task"); + list[0] = + io_make_output_field("RTStarIact", INT, 1, UNIT_CONV_NO_UNITS, 0, parts, + rt_data.iact_stars_inject, + "number of interactions between this hydro particle" + " and any star particle during injection step"); + list[1] = io_make_output_field("RTTotalCalls", INT, 1, UNIT_CONV_NO_UNITS, 0, + parts, rt_data.calls_tot, + "total number of calls to this " + "particle during the run"); + list[2] = io_make_output_field("RTCallsThisStep", INT, 1, UNIT_CONV_NO_UNITS, + 0, parts, rt_data.calls_per_step, + "number of calls " + "to this particle during one time step"); + list[3] = + io_make_output_field("RTCallsSelfInjection", INT, 1, UNIT_CONV_NO_UNITS, + 0, parts, rt_data.calls_self_inject, + "number of calls to this particle during one time " + "step in injection self task"); + list[4] = + io_make_output_field("RTCallsPairInjection", INT, 1, UNIT_CONV_NO_UNITS, + 0, parts, rt_data.calls_pair_inject, + "number of calls to this particle during one time " + "step in injection pair task"); + list[5] = + io_make_output_field("RTPhotonsUpdated", INT, 1, UNIT_CONV_NO_UNITS, 0, + parts, rt_data.photon_number_updated, + "=1 if photon number has been updated in this step"); - return 5; + return 6; } /** @@ -62,22 +72,27 @@ INLINE static int rt_write_stars(const struct spart* sparts, struct io_props* list) { list[0] = io_make_output_field("RTHydroIact", INT, 1, UNIT_CONV_NO_UNITS, 0, - sparts, rt_data.iact_hydro, + sparts, rt_data.iact_hydro_inject, "number of interactions between this hydro " "particle and any star particle"); - list[1] = io_make_output_field( - "RTTotalCalls", INT, 1, UNIT_CONV_NO_UNITS, 0, sparts, rt_data.calls_tot, - "total number of calls to this particle during the run"); - list[2] = io_make_output_field( - "RTCallsThisStep", INT, 1, UNIT_CONV_NO_UNITS, 0, sparts, - rt_data.calls_per_step, - "number of calls to this particle during one time step"); - list[3] = io_make_output_field( - "RTCallsSelf", INT, 1, UNIT_CONV_NO_UNITS, 0, sparts, rt_data.calls_self, - "number of calls to this particle during one time step in self task"); - list[4] = io_make_output_field( - "RTCallsPair", INT, 1, UNIT_CONV_NO_UNITS, 0, sparts, rt_data.calls_pair, - "number of calls to this particle during one time step in self task"); + list[1] = io_make_output_field("RTTotalCalls", INT, 1, UNIT_CONV_NO_UNITS, 0, + sparts, rt_data.calls_tot, + "total number of calls " + "to this particle during the run"); + list[2] = io_make_output_field("RTCallsThisStep", INT, 1, UNIT_CONV_NO_UNITS, + 0, sparts, rt_data.calls_per_step, + "number of calls to " + "this particle during one time step"); + list[3] = + io_make_output_field("RTCallsSelfInjection", INT, 1, UNIT_CONV_NO_UNITS, + 0, sparts, rt_data.calls_self_inject, + "number of calls to this particle during one time " + "step in injection self task"); + list[4] = + io_make_output_field("RTCallsPairInjection", INT, 1, UNIT_CONV_NO_UNITS, + 0, sparts, rt_data.calls_pair_inject, + "number of calls to this particle during one time " + "step in injection pair task"); return 5; } diff --git a/src/rt/debug/rt_struct.h b/src/rt/debug/rt_struct.h index 7255c62c355c8c7a55b781e1bc86070153d53b2b..20aa6c8dcf7c9e438069c1262609b2dea6ded8df 100644 --- a/src/rt/debug/rt_struct.h +++ b/src/rt/debug/rt_struct.h @@ -26,20 +26,30 @@ /* Additional RT data in hydro particle struct */ struct rt_part_data { - int iact_stars; /* how many stars this particle interacted with */ - int calls_tot; /* total number of calls to this particle during entire run */ - int calls_per_step; /* calls per time step to this particle */ - int calls_self; - int calls_pair; + + /* data to store during entire run */ + int calls_tot; /* total number of calls to this particle during entire run */ + + /* data to store during one time step */ + int calls_per_step; /* calls per time step to this particle */ + int iact_stars_inject; /* how many stars this particle interacted with */ + int calls_self_inject; /* calls from self inject tasks */ + int calls_pair_inject; /* calls from pair inject tasks */ + int photon_number_updated; /* calls from ghost1 tasks */ }; /* Additional RT data in star particle struct */ struct rt_spart_data { - int iact_hydro; /* how many hydro particles this particle interacted with */ - int calls_tot; /* total number of calls to this particle during entire run */ - int calls_per_step; /* calls per time step to this particle */ - int calls_self; - int calls_pair; + + /* data to store during entire run */ + int calls_tot; /* total number of calls to this particle during entire run */ + + /* data to store during one time step */ + int calls_per_step; /* calls per time step to this particle */ + int iact_hydro_inject; /* how many hydro particles this particle interacted + with */ + int calls_self_inject; /* calls from self inject tasks */ + int calls_pair_inject; /* calls from pair inject tasks */ }; #endif /* SWIFT_RT_STRUCT_DEBUG_H */ diff --git a/src/rt/none/rt.h b/src/rt/none/rt.h index 30039d8b9d4a917cc25b983e51d3f11fee2e891b..c44819a77c247e2c68f6b96dfcfdfbbaa2360f47 100644 --- a/src/rt/none/rt.h +++ b/src/rt/none/rt.h @@ -24,6 +24,13 @@ * @brief Main header file for no radiative transfer scheme. */ +/** + * @brief Update the photon number of a particle, i.e. compute + * E^{n+1} = E^n + dt * dE_* / dt + */ +__attribute__((always_inline)) INLINE static void +rt_injection_update_photon_density(struct part* restrict p) {} + /** * @brief First initialisation of the RT extra hydro particle data. */ diff --git a/src/runner.h b/src/runner.h index 30378873d2d2195648515a0e8cc990235b0e8502..7e5b3585d8328be26dfd9fd1af57a893425991d8 100644 --- a/src/runner.h +++ b/src/runner.h @@ -41,6 +41,7 @@ struct task; #define TASK_LOOP_LIMITER 3 #define TASK_LOOP_FEEDBACK 4 #define TASK_LOOP_SWALLOW 5 +#define TASK_LOOP_SINK_FORMATION 6 /** * @brief A struct representing a runner's thread and its data. @@ -116,6 +117,7 @@ void runner_do_logger(struct runner *r, struct cell *c, int timer); void runner_do_fof_self(struct runner *r, struct cell *c, int timer); void runner_do_fof_pair(struct runner *r, struct cell *ci, struct cell *cj, int timer); +void runner_do_rt_ghost1(struct runner *r, struct cell *c, int timer); void runner_do_gas_swallow_self(struct runner *r, struct cell *c, int timer); void runner_do_bh_swallow_self(struct runner *r, struct cell *c, int timer); void runner_do_gas_swallow_pair(struct runner *r, struct cell *ci, diff --git a/src/runner_doiact_functions_rt.h b/src/runner_doiact_functions_rt.h index d05a41efdef7b15e438d9aee3e77d5593c4d67ba..d1304126065e69258db8a8dd308cc31aa81d4cae 100644 --- a/src/runner_doiact_functions_rt.h +++ b/src/runner_doiact_functions_rt.h @@ -62,7 +62,7 @@ void DOSELF1_RT(struct runner *r, struct cell *c, int timer) { (float)(si->x[1] - c->loc[1]), (float)(si->x[2] - c->loc[2])}; - /* Loop over the (x)parts in cell */ + /* Loop over the parts in cell */ for (int pid = 0; pid < count; pid++) { struct part *restrict pj = &parts[pid]; @@ -146,7 +146,13 @@ void DOPAIR1_NONSYM_RT(struct runner *r, struct cell *ci, struct cell *cj) { float dx[3] = {six[0] - pjx[0], six[1] - pjx[1], six[2] - pjx[2]}; const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; +#ifdef RT_DEBUG + /* temporary debugging checks: pass -r2 to differentiate pair/self calls + */ + if (r2 < hjg2) IACT_RT(-r2, dx, hi, hj, si, pj); +#else if (r2 < hjg2) IACT_RT(r2, dx, hi, hj, si, pj); +#endif } /* loop over the parts in cj. */ } /* loop over the parts in ci. */ diff --git a/src/runner_doiact_functions_sinks.h b/src/runner_doiact_functions_sinks.h new file mode 100644 index 0000000000000000000000000000000000000000..21876b2d88b5fd3ad2f8bbcd22b68f1f064ad139 --- /dev/null +++ b/src/runner_doiact_functions_sinks.h @@ -0,0 +1,655 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2020 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/>. + * + ******************************************************************************/ + +/* Before including this file, define FUNCTION, which is the + name of the interaction function. This creates the interaction functions + runner_dopair_FUNCTION, runner_dopair_FUNCTION_naive, runner_doself_FUNCTION, + and runner_dosub_FUNCTION calling the pairwise interaction function + runner_iact_FUNCTION. */ + +#include "active.h" +#include "runner_doiact_sinks.h" + +/** + * @brief Calculate the number density of #part around the #sink + * + * @param r runner task + * @param c cell + * @param timer 1 if the time is to be recorded. + */ +void DOSELF1_SINKS(struct runner *r, struct cell *c, int timer) { + +#ifdef SWIFT_DEBUG_CHECKS + if (c->nodeID != engine_rank) error("Should be run on a different node"); +#endif + + const struct engine *e = r->e; + const struct cosmology *cosmo = e->cosmology; + + /* Anything to do here? */ + if (c->hydro.count == 0 || c->sinks.count == 0) return; + if (!cell_is_active_sinks(c, e)) return; + + /* Cosmological terms */ + const float a = cosmo->a; + const float H = cosmo->H; + + const int scount = c->sinks.count; + const int count = c->hydro.count; + struct sink *restrict sinks = c->sinks.parts; + struct part *restrict parts = c->hydro.parts; + + /* Loop over the sinks in ci. */ + for (int sid = 0; sid < scount; sid++) { + + /* Get a hold of the ith sink in ci. */ + struct sink *restrict si = &sinks[sid]; + + /* Skip inactive particles */ + if (!sink_is_active(si, e)) continue; + + const float ri = si->r_cut; + const float ri2 = ri * ri; + const float six[3] = {(float)(si->x[0] - c->loc[0]), + (float)(si->x[1] - c->loc[1]), + (float)(si->x[2] - c->loc[2])}; + + /* Loop over the parts in cj. */ + for (int pjd = 0; pjd < count; pjd++) { + + /* Get a pointer to the jth particle. */ + struct part *restrict pj = &parts[pjd]; + const float hj = pj->h; + + /* Early abort? */ + if (part_is_inhibited(pj, e)) continue; + + /* Compute the pairwise distance. */ + const float pjx[3] = {(float)(pj->x[0] - c->loc[0]), + (float)(pj->x[1] - c->loc[1]), + (float)(pj->x[2] - c->loc[2])}; + float dx[3] = {six[0] - pjx[0], six[1] - pjx[1], six[2] - pjx[2]}; + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + + if (r2 < ri2) { + IACT_SINK(r2, dx, ri, hj, si, pj, a, H); + } + } /* loop over the parts in ci. */ + } /* loop over the sinks in ci. */ +} + +/** + * @brief Calculate the number density of cj #part around the ci #sink + * + * @param r runner task + * @param ci The first #cell + * @param cj The second #cell + */ +void DO_NONSYM_PAIR1_SINKS_NAIVE(struct runner *r, struct cell *restrict ci, + struct cell *restrict cj) { + +#ifdef SWIFT_DEBUG_CHECKS + if (ci->nodeID != engine_rank) error("Should be run on a different node"); +#endif + + const struct engine *e = r->e; + const struct cosmology *cosmo = e->cosmology; + + /* Anything to do here? */ + if (cj->hydro.count == 0 || ci->sinks.count == 0) return; + if (!cell_is_active_sinks(ci, e)) return; + + /* Cosmological terms */ + const float a = cosmo->a; + const float H = cosmo->H; + + const int scount_i = ci->sinks.count; + const int count_j = cj->hydro.count; + struct sink *restrict sinks_i = ci->sinks.parts; + struct part *restrict parts_j = cj->hydro.parts; + + /* Get the relative distance between the pairs, wrapping. */ + double shift[3] = {0.0, 0.0, 0.0}; + for (int k = 0; k < 3; k++) { + if (cj->loc[k] - ci->loc[k] < -e->s->dim[k] / 2) + shift[k] = e->s->dim[k]; + else if (cj->loc[k] - ci->loc[k] > e->s->dim[k] / 2) + shift[k] = -e->s->dim[k]; + } + + /* Loop over the sinks in ci. */ + for (int sid = 0; sid < scount_i; sid++) { + + /* Get a hold of the ith sink in ci. */ + struct sink *restrict si = &sinks_i[sid]; + + /* Skip inactive particles */ + if (!sink_is_active(si, e)) continue; + + const float ri = si->r_cut; + const float ri2 = ri * ri; + const float six[3] = {(float)(si->x[0] - (cj->loc[0] + shift[0])), + (float)(si->x[1] - (cj->loc[1] + shift[1])), + (float)(si->x[2] - (cj->loc[2] + shift[2]))}; + + /* Loop over the parts in cj. */ + for (int pjd = 0; pjd < count_j; pjd++) { + + /* Get a pointer to the jth particle. */ + struct part *restrict pj = &parts_j[pjd]; + const float hj = pj->h; + + /* Skip inhibited particles. */ + if (part_is_inhibited(pj, e)) continue; + + /* Compute the pairwise distance. */ + const float pjx[3] = {(float)(pj->x[0] - cj->loc[0]), + (float)(pj->x[1] - cj->loc[1]), + (float)(pj->x[2] - cj->loc[2])}; + float dx[3] = {six[0] - pjx[0], six[1] - pjx[1], six[2] - pjx[2]}; + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles have been drifted to the current time */ + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + + if (r2 < ri2) { + IACT_SINK(r2, dx, ri, hj, si, pj, a, H); + } + } /* loop over the parts in cj. */ + } /* loop over the parts in ci. */ +} + +/** + * @brief Compute the interactions between a cell pair. + * + * @param r The #runner. + * @param ci The first #cell. + * @param cj The second #cell. + * @param sid The direction of the pair. + * @param shift The shift vector to apply to the particles in ci. + */ +void DO_SYM_PAIR1_SINKS(struct runner *r, struct cell *ci, struct cell *cj, + const int sid, const double *shift) { + + const struct engine *e = r->e; + const struct cosmology *cosmo = e->cosmology; + + /* Cosmological terms */ + const float a = cosmo->a; + const float H = cosmo->H; + + /* Get the cutoff shift. */ + double rshift = 0.0; + for (int k = 0; k < 3; k++) rshift += shift[k] * runner_shift[sid][k]; + + const int do_ci_sinks = (ci->nodeID == e->nodeID) && (ci->sinks.count != 0) && + (cj->hydro.count != 0) && cell_is_active_sinks(ci, e); + const int do_cj_sinks = (cj->nodeID == e->nodeID) && (cj->sinks.count != 0) && + (ci->hydro.count != 0) && cell_is_active_sinks(cj, e); + + if (do_ci_sinks) { + + /* Pick-out the sorted lists. */ + const struct sort_entry *restrict sort_j = cell_get_hydro_sorts(cj, sid); + +#ifdef SWIFT_DEBUG_CHECKS + /* Some constants used to checks that the parts are in the right frame */ + const float shift_threshold_x = + 2. * ci->width[0] + + 2. * max(ci->sinks.dx_max_part, cj->hydro.dx_max_part); + const float shift_threshold_y = + 2. * ci->width[1] + + 2. * max(ci->sinks.dx_max_part, cj->hydro.dx_max_part); + const float shift_threshold_z = + 2. * ci->width[2] + + 2. * max(ci->sinks.dx_max_part, cj->hydro.dx_max_part); +#endif /* SWIFT_DEBUG_CHECKS */ + + /* Get some other useful values. */ + const int count_i = ci->sinks.count; + const int count_j = cj->hydro.count; + struct sink *restrict sinks_i = ci->sinks.parts; + struct part *restrict parts_j = cj->hydro.parts; + const double dj_min = sort_j[0].d; + const float hydro_dx_max_rshift = cj->hydro.dx_max_sort - rshift; + + /* Loop over the sinks in ci. */ + for (int i = 0; i < count_i; i++) { + + /* Get a hold of the ith part in ci. */ + struct sink *restrict spi = &sinks_i[i]; + const float ri = spi->r_cut; + + /* Skip inactive particles */ + if (!sink_is_active(spi, e)) continue; + + /* Compute distance from the other cell. */ + const double px[3] = {spi->x[0], spi->x[1], spi->x[2]}; + float dist = px[0] * runner_shift[sid][0] + px[1] * runner_shift[sid][1] + + px[2] * runner_shift[sid][2]; + + /* Is there anything we need to interact with ? */ + const double di = dist + ri + hydro_dx_max_rshift; + if (di < dj_min) continue; + + /* Get some additional information about pi */ + const float ri2 = ri * ri; + const float pix = spi->x[0] - (cj->loc[0] + shift[0]); + const float piy = spi->x[1] - (cj->loc[1] + shift[1]); + const float piz = spi->x[2] - (cj->loc[2] + shift[2]); + + /* Loop over the parts in cj. */ + for (int pjd = 0; pjd < count_j && sort_j[pjd].d < di; pjd++) { + + /* Recover pj */ + struct part *pj = &parts_j[sort_j[pjd].i]; + + /* Skip inhibited particles. */ + if (part_is_inhibited(pj, e)) continue; + + const float hj = pj->h; + const float pjx = pj->x[0] - cj->loc[0]; + const float pjy = pj->x[1] - cj->loc[1]; + const float pjz = pj->x[2] - cj->loc[2]; + + /* Compute the pairwise distance. */ + float dx[3] = {pix - pjx, piy - pjy, piz - pjz}; + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles are in the correct frame after the shifts */ + if (pix > shift_threshold_x || pix < -shift_threshold_x) + error( + "Invalid particle position in X for pi (pix=%e ci->width[0]=%e)", + pix, ci->width[0]); + if (piy > shift_threshold_y || piy < -shift_threshold_y) + error( + "Invalid particle position in Y for pi (piy=%e ci->width[1]=%e)", + piy, ci->width[1]); + if (piz > shift_threshold_z || piz < -shift_threshold_z) + error( + "Invalid particle position in Z for pi (piz=%e ci->width[2]=%e)", + piz, ci->width[2]); + if (pjx > shift_threshold_x || pjx < -shift_threshold_x) + error( + "Invalid particle position in X for pj (pjx=%e ci->width[0]=%e)", + pjx, ci->width[0]); + if (pjy > shift_threshold_y || pjy < -shift_threshold_y) + error( + "Invalid particle position in Y for pj (pjy=%e ci->width[1]=%e)", + pjy, ci->width[1]); + if (pjz > shift_threshold_z || pjz < -shift_threshold_z) + error( + "Invalid particle position in Z for pj (pjz=%e ci->width[2]=%e)", + pjz, ci->width[2]); + + /* Check that particles have been drifted to the current time */ + if (spi->ti_drift != e->ti_current) + error("Particle spi not drifted to current time"); + if (pj->ti_drift != e->ti_current) + error("Particle pj not drifted to current time"); +#endif + + /* Hit or miss? */ + if (r2 < ri2) { + IACT_SINK(r2, dx, ri, hj, spi, pj, a, H); + } + } /* loop over the parts in cj. */ + } /* loop over the parts in ci. */ + } /* do_ci_sinks */ + + if (do_cj_sinks) { + /* Pick-out the sorted lists. */ + const struct sort_entry *restrict sort_i = cell_get_hydro_sorts(ci, sid); + +#ifdef SWIFT_DEBUG_CHECKS + /* Some constants used to checks that the parts are in the right frame */ + const float shift_threshold_x = + 2. * ci->width[0] + + 2. * max(ci->hydro.dx_max_part, cj->sinks.dx_max_part); + const float shift_threshold_y = + 2. * ci->width[1] + + 2. * max(ci->hydro.dx_max_part, cj->sinks.dx_max_part); + const float shift_threshold_z = + 2. * ci->width[2] + + 2. * max(ci->hydro.dx_max_part, cj->sinks.dx_max_part); +#endif /* SWIFT_DEBUG_CHECKS */ + + /* Get some other useful values. */ + const int count_i = ci->hydro.count; + const int count_j = cj->sinks.count; + struct part *restrict parts_i = ci->hydro.parts; + struct sink *restrict sinks_j = cj->sinks.parts; + const double di_max = sort_i[count_i - 1].d - rshift; + const float hydro_dx_max_rshift = ci->hydro.dx_max_sort - rshift; + + /* Loop over the parts in cj. */ + for (int j = 0; j < count_j; j++) { + + /* Get a hold of the jth part in cj. */ + struct sink *spj = &sinks_j[j]; + const float rj = spj->r_cut; + + /* Skip inactive particles */ + if (!sink_is_active(spj, e)) continue; + + /* Compute distance from the other cell. */ + const double px[3] = {spj->x[0], spj->x[1], spj->x[2]}; + float dist = px[0] * runner_shift[sid][0] + px[1] * runner_shift[sid][1] + + px[2] * runner_shift[sid][2]; + + /* Is there anything we need to interact with ? */ + const double dj = dist - rj - hydro_dx_max_rshift; + if (dj - rshift > di_max) continue; + + /* Get some additional information about pj */ + const float rj2 = rj * rj; + const float pjx = spj->x[0] - cj->loc[0]; + const float pjy = spj->x[1] - cj->loc[1]; + const float pjz = spj->x[2] - cj->loc[2]; + + /* Loop over the parts in ci. */ + for (int pid = count_i - 1; pid >= 0 && sort_i[pid].d > dj; pid--) { + + /* Recover pi */ + struct part *pi = &parts_i[sort_i[pid].i]; + + /* Skip inhibited particles. */ + if (part_is_inhibited(pi, e)) continue; + + const float hi = pi->h; + const float pix = pi->x[0] - (cj->loc[0] + shift[0]); + const float piy = pi->x[1] - (cj->loc[1] + shift[1]); + const float piz = pi->x[2] - (cj->loc[2] + shift[2]); + + /* Compute the pairwise distance. */ + float dx[3] = {pjx - pix, pjy - piy, pjz - piz}; + const float r2 = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + +#ifdef SWIFT_DEBUG_CHECKS + /* Check that particles are in the correct frame after the shifts */ + if (pix > shift_threshold_x || pix < -shift_threshold_x) + error( + "Invalid particle position in X for pi (pix=%e ci->width[0]=%e)", + pix, ci->width[0]); + if (piy > shift_threshold_y || piy < -shift_threshold_y) + error( + "Invalid particle position in Y for pi (piy=%e ci->width[1]=%e)", + piy, ci->width[1]); + if (piz > shift_threshold_z || piz < -shift_threshold_z) + error( + "Invalid particle position in Z for pi (piz=%e ci->width[2]=%e)", + piz, ci->width[2]); + if (pjx > shift_threshold_x || pjx < -shift_threshold_x) + error( + "Invalid particle position in X for pj (pjx=%e ci->width[0]=%e)", + pjx, ci->width[0]); + if (pjy > shift_threshold_y || pjy < -shift_threshold_y) + error( + "Invalid particle position in Y for pj (pjy=%e ci->width[1]=%e)", + pjy, ci->width[1]); + if (pjz > shift_threshold_z || pjz < -shift_threshold_z) + error( + "Invalid particle position in Z for pj (pjz=%e ci->width[2]=%e)", + pjz, ci->width[2]); + + /* Check that particles have been drifted to the current time */ + if (pi->ti_drift != e->ti_current) + error("Particle pi not drifted to current time"); + if (spj->ti_drift != e->ti_current) + error("Particle spj not drifted to current time"); +#endif + + /* Hit or miss? */ + if (r2 < rj2) { + + IACT_SINK(r2, dx, rj, hi, spj, pi, a, H); + } + } /* loop over the parts in ci. */ + } /* loop over the parts in cj. */ + } /* Cell cj is active */ +} + +void DOPAIR1_SINKS_NAIVE(struct runner *r, struct cell *restrict ci, + struct cell *restrict cj, int timer) { + + const int do_ci_sinks = ci->nodeID == r->e->nodeID; + const int do_cj_sinks = cj->nodeID == r->e->nodeID; + if (do_ci_sinks && ci->sinks.count != 0 && cj->hydro.count != 0) + DO_NONSYM_PAIR1_SINKS_NAIVE(r, ci, cj); + if (do_cj_sinks && cj->sinks.count != 0 && ci->hydro.count != 0) + DO_NONSYM_PAIR1_SINKS_NAIVE(r, cj, ci); +} + +/** + * @brief Determine which version of DOSELF1_SINKS needs to be called depending + * on the optimisation level. + * + * @param r #runner + * @param c #cell c + * + */ +void DOSELF1_BRANCH_SINKS(struct runner *r, struct cell *c) { + + const struct engine *restrict e = r->e; + + /* Anything to do here? */ + if (c->sinks.count == 0) return; + + /* Anything to do here? */ + if (!cell_is_active_sinks(c, e)) return; + + /* Did we mess up the recursion? */ + if (c->sinks.r_cut_max_old > c->dmin) + error("Cell smaller than the cut off radius"); + + DOSELF1_SINKS(r, c, 1); +} + +/** + * @brief Determine which version of DOPAIR1_SINKS needs to be called depending + * on the orientation of the cells or whether DOPAIR1_SINKS needs to be called + * at all. + * + * @param r #runner + * @param ci #cell ci + * @param cj #cell cj + * + */ +void DOPAIR1_BRANCH_SINKS(struct runner *r, struct cell *ci, struct cell *cj) { + + const struct engine *restrict e = r->e; + + /* Get the sort ID. */ + double shift[3] = {0.0, 0.0, 0.0}; + const int sid = space_getsid(e->s, &ci, &cj, shift); + + const int ci_active = cell_is_active_sinks(ci, e); + const int cj_active = cell_is_active_sinks(cj, e); + const int do_ci_sinks = ci->nodeID == e->nodeID; + const int do_cj_sinks = cj->nodeID == e->nodeID; + const int do_ci = (ci->sinks.count != 0 && cj->hydro.count != 0 && + ci_active && do_ci_sinks); + const int do_cj = (cj->sinks.count != 0 && ci->hydro.count != 0 && + cj_active && do_cj_sinks); + + /* Anything to do here? */ + if (!do_ci && !do_cj) return; + + /* Check that cells are drifted. */ + if (do_ci && (!cell_are_sink_drifted(ci, e) || !cell_are_part_drifted(cj, e))) + error("Interacting undrifted cells."); + + /* Have the cells been sorted? */ + if (do_ci && (!(cj->hydro.sorted & (1 << sid)) || + cj->hydro.dx_max_sort_old > space_maxreldx * cj->dmin)) + error("Interacting unsorted cells."); + + if (do_cj && (!cell_are_part_drifted(ci, e) || !cell_are_sink_drifted(cj, e))) + error("Interacting undrifted cells."); + + /* Have the cells been sorted? */ + if (do_cj && (!(ci->hydro.sorted & (1 << sid)) || + ci->hydro.dx_max_sort_old > space_maxreldx * ci->dmin)) + error("Interacting unsorted cells."); + +#ifdef SWIFT_USE_NAIVE_INTERACTIONS_SINKS + DOPAIR1_SINKS_NAIVE(r, ci, cj, 1); +#else + DO_SYM_PAIR1_SINKS(r, ci, cj, sid, shift); +#endif +} + +/** + * @brief Compute grouped sub-cell interactions for pairs + * + * @param r The #runner. + * @param ci The first #cell. + * @param cj The second #cell. + * @param gettimer Do we have a timer ? + * + * @todo Hard-code the sid on the recursive calls to avoid the + * redundant computations to find the sid on-the-fly. + */ +void DOSUB_PAIR1_SINKS(struct runner *r, struct cell *ci, struct cell *cj, + int gettimer) { + + TIMER_TIC; + + struct space *s = r->e->s; + const struct engine *e = r->e; + + /* Should we even bother? */ + const int should_do_ci = ci->sinks.count != 0 && cj->hydro.count != 0 && + cell_is_active_sinks(ci, e); + const int should_do_cj = cj->sinks.count != 0 && ci->hydro.count != 0 && + cell_is_active_sinks(cj, e); + if (!should_do_ci && !should_do_cj) return; + + /* Get the type of pair and flip ci/cj if needed. */ + double shift[3]; + const int sid = space_getsid(s, &ci, &cj, shift); + + /* Recurse? */ + if (cell_can_recurse_in_pair_sinks_task(ci, cj) && + cell_can_recurse_in_pair_sinks_task(cj, ci)) { + struct cell_split_pair *csp = &cell_split_pairs[sid]; + for (int k = 0; k < csp->count; k++) { + const int pid = csp->pairs[k].pid; + const int pjd = csp->pairs[k].pjd; + if (ci->progeny[pid] != NULL && cj->progeny[pjd] != NULL) + DOSUB_PAIR1_SINKS(r, ci->progeny[pid], cj->progeny[pjd], 0); + } + } + + /* Otherwise, compute the pair directly. */ + else { + + const int do_ci_sinks = ci->nodeID == e->nodeID; + const int do_cj_sinks = cj->nodeID == e->nodeID; + const int do_ci = ci->sinks.count != 0 && cj->hydro.count != 0 && + cell_is_active_sinks(ci, e) && do_ci_sinks; + const int do_cj = cj->sinks.count != 0 && ci->hydro.count != 0 && + cell_is_active_sinks(cj, e) && do_cj_sinks; + + if (do_ci) { + + /* Make sure both cells are drifted to the current timestep. */ + if (!cell_are_sink_drifted(ci, e)) + error("Interacting undrifted cells (sinks)."); + + if (!cell_are_part_drifted(cj, e)) + error("Interacting undrifted cells (parts)."); + + /* Do any of the cells need to be sorted first? */ + if (!(cj->hydro.sorted & (1 << sid)) || + cj->hydro.dx_max_sort_old > cj->dmin * space_maxreldx) + error("Interacting unsorted cell (parts). %i", cj->nodeID); + } + + if (do_cj) { + + /* Make sure both cells are drifted to the current timestep. */ + if (!cell_are_part_drifted(ci, e)) + error("Interacting undrifted cells (parts)."); + + if (!cell_are_sink_drifted(cj, e)) + error("Interacting undrifted cells (sinks)."); + + /* Do any of the cells need to be sorted first? */ + if (!(ci->hydro.sorted & (1 << sid)) || + ci->hydro.dx_max_sort_old > ci->dmin * space_maxreldx) { + error("Interacting unsorted cell (parts)."); + } + } + + if (do_ci || do_cj) DOPAIR1_BRANCH_SINKS(r, ci, cj); + } +} + +/** + * @brief Compute grouped sub-cell interactions for self tasks + * + * @param r The #runner. + * @param ci The first #cell. + * @param gettimer Do we have a timer ? + */ +void DOSUB_SELF1_SINKS(struct runner *r, struct cell *ci, int gettimer) { + +#ifdef SWIFT_DEBUG_CHECKS + if (ci->nodeID != engine_rank) + error("This function should not be called on foreign cells"); +#endif + + /* Should we even bother? */ + if (ci->hydro.count == 0 || ci->sinks.count == 0 || + !cell_is_active_sinks(ci, r->e)) + return; + + /* Recurse? */ + if (cell_can_recurse_in_self_sinks_task(ci)) { + + /* Loop over all progeny. */ + for (int k = 0; k < 8; k++) + if (ci->progeny[k] != NULL) { + DOSUB_SELF1_SINKS(r, ci->progeny[k], 0); + for (int j = k + 1; j < 8; j++) + if (ci->progeny[j] != NULL) + DOSUB_PAIR1_SINKS(r, ci->progeny[k], ci->progeny[j], 0); + } + } + + /* Otherwise, compute self-interaction. */ + else { + + /* Drift the cell to the current timestep if needed. */ + if (!cell_are_sink_drifted(ci, r->e)) error("Interacting undrifted cell."); + + DOSELF1_BRANCH_SINKS(r, ci); + } +} diff --git a/src/gravity/Potential/gravity_debug.h b/src/runner_doiact_sinks.c similarity index 53% rename from src/gravity/Potential/gravity_debug.h rename to src/runner_doiact_sinks.c index 621f3ccb9c4621f44f902c37a2e03bd7575defe7..3d8169ef2cedab40ea661069ad70962dc10d4b72 100644 --- a/src/gravity/Potential/gravity_debug.h +++ b/src/runner_doiact_sinks.c @@ -1,6 +1,6 @@ /******************************************************************************* * This file is part of SWIFT. - * Coypright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk) + * Copyright (c) 2020 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 @@ -16,22 +16,23 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * ******************************************************************************/ -#ifndef SWIFT_POTENTIAL_GRAVITY_DEBUG_H -#define SWIFT_POTENTIAL_GRAVITY_DEBUG_H -__attribute__((always_inline)) INLINE static void gravity_debug_particle( - const struct gpart* p) { - printf( - "mass=%.3e time_bin=%d\n" - "x=[%.5e,%.5e,%.5e], v_full=[%.5e,%.5e,%.5e], a=[%.5e,%.5e,%.5e] " - "pot=%.5e\n", - p->mass, p->time_bin, p->x[0], p->x[1], p->x[2], p->v_full[0], - p->v_full[1], p->v_full[2], p->a_grav[0], p->a_grav[1], p->a_grav[2], - p->potential); -#ifdef SWIFT_DEBUG_CHECKS - printf("num_interacted=%lld ti_drift=%lld ti_kick=%lld\n", p->num_interacted, - p->ti_drift, p->ti_kick); -#endif -} +/* Config parameters. */ +#include "../config.h" -#endif /* SWIFT_POTENTIAL_GRAVITY_DEBUG_H */ +/* Local headers. */ +#include "active.h" +#include "cell.h" +#include "engine.h" +#include "feedback.h" +#include "runner.h" +#include "sink.h" +#include "space_getsid.h" +#include "timers.h" + +/* Import the sink compute formation loop functions. */ +#define FUNCTION compute_formation +#define FUNCTION_TASK_LOOP TASK_LOOP_FORMATION +#include "runner_doiact_functions_sinks.h" +#undef FUNCTION_TASK_LOOP +#undef FUNCTION diff --git a/src/runner_doiact_sinks.h b/src/runner_doiact_sinks.h new file mode 100644 index 0000000000000000000000000000000000000000..5c4b0eba5d2cc82ff800c71f0768f6c69610f507 --- /dev/null +++ b/src/runner_doiact_sinks.h @@ -0,0 +1,60 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2020 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/>. + * + ******************************************************************************/ + +/* Before including this file, define FUNCTION, which is the + name of the interaction function. This creates the interaction functions + runner_dopair_FUNCTION, runner_doself_FUNCTION and runner_dosub_FUNCTION + calling the pairwise interaction function runner_iact_FUNCTION. */ + +#define PASTE(x, y) x##_##y + +#define _DOSELF1_SINKS(f) PASTE(runner_doself_sinks, f) +#define DOSELF1_SINKS _DOSELF1_SINKS(FUNCTION) + +#define _DO_SYM_PAIR1_SINKS(f) PASTE(runner_do_sym_pair_sinks, f) +#define DO_SYM_PAIR1_SINK _DO_SYM_PAIR1_SINKS(FUNCTION) + +#define _DO_NONSYM_PAIR1_SINKS_NAIVE(f) \ + PASTE(runner_do_nonsym_pair_sinks_naive, f) +#define DO_NONSYM_PAIR1_SINKS_NAIVE _DO_NONSYM_PAIR1_SINKS_NAIVE(FUNCTION) + +#define _DOPAIR1_SINKS_NAIVE(f) PASTE(runner_dopair_sinks_naive, f) +#define DOPAIR1_SINKS_NAIVE _DOPAIR1_SINKS_NAIVE(FUNCTION) + +#define _DOSELF1_BRANCH_SINKS(f) PASTE(runner_doself_branch_sinks, f) +#define DOSELF1_BRANCH_SINKS _DOSELF1_BRANCH_SINKS(FUNCTION) + +#define _DOPAIR1_BRANCH_SINK(f) PASTE(runner_dopair_branch_sinks, f) +#define DOPAIR1_BRANCH_SINKS _DOPAIR1_BRANCH_SINK(FUNCTION) + +#define _DOSUB_PAIR1_SINKS(f) PASTE(runner_dosub_pair_sinks, f) +#define DOSUB_PAIR1_SINKS _DOSUB_PAIR1_SINKS(FUNCTION) + +#define _DOSUB_SELF1_SINKS(f) PASTE(runner_dosub_self_sinks, f) +#define DOSUB_SELF1_SINKS _DOSUB_SELF1_SINKS(FUNCTION) + +#define _IACT_SINK(f) PASTE(runner_iact_nonsym_sinks, f) +#define IACT_SINK _IACT_SINK(FUNCTION) + +void DOSELF1_BRANCH_SINKS(struct runner *r, struct cell *c); +void DOPAIR1_BRANCH_SINKS(struct runner *r, struct cell *ci, struct cell *cj); + +void DOSUB_SELF1_SINKS(struct runner *r, struct cell *ci, int gettimer); +void DOSUB_PAIR1_SINKS(struct runner *r, struct cell *ci, struct cell *cj, + int gettimer); diff --git a/src/runner_ghost.c b/src/runner_ghost.c index 5f89cc7fb640f4c3516c33d5b2659187db19902d..5dac1b5083f36fc22d1c13a14d7946fce195f9bc 100644 --- a/src/runner_ghost.c +++ b/src/runner_ghost.c @@ -1387,3 +1387,37 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_do_ghost); } + +/** + * @brief Intermediate task after the injection to compute the total + * photon emission rates experienced by the hydro particles. + * + * @param r The runner thread. + * @param c The cell. + * @param timer Are we timing this ? + */ +void runner_do_rt_ghost1(struct runner *r, struct cell *c, int timer) { + /* const struct engine *e = r->e; */ + int count = c->hydro.count; + + /* Anything to do here? */ + if (count == 0) return; + + TIMER_TIC; + + /* Recurse? */ + if (c->split) { + for (int k = 0; k < 8; k++) { + if (c->progeny[k] != NULL) { + runner_do_rt_ghost1(r, c->progeny[k], 0); + } + } + } + + for (int pid = 0; pid < count; pid++) { + struct part *restrict p = &(c->hydro.parts[pid]); + rt_injection_update_photon_density(p); + } + + if (timer) TIMER_TOC(timer_do_rt_ghost1); +} diff --git a/src/runner_main.c b/src/runner_main.c index a0cb3db1dd5975333db8bdcc8ea20c8737629d1b..3e163a7f3d57a6f8dd7046df3c562a66e7400119 100644 --- a/src/runner_main.c +++ b/src/runner_main.c @@ -109,6 +109,13 @@ #include "runner_doiact_rt.h" #undef FUNCTION +/* Import the sink compute formation loop functions. */ +#define FUNCTION compute_formation +#define FUNCTION_TASK_LOOP TASK_LOOP_SINK_FORMATION +#include "runner_doiact_sinks.h" +#undef FUNCTION_TASK_LOOP +#undef FUNCTION + /** * @brief The #runner main thread routine. * @@ -208,6 +215,8 @@ void *runner_main(void *data) { runner_doself_branch_bh_feedback(r, ci); else if (t->subtype == task_subtype_rt_inject) runner_doself_branch_rt_inject(r, ci, 1); + else if (t->subtype == task_subtype_sink_compute_formation) + runner_doself_branch_sinks_compute_formation(r, ci); else error("Unknown/invalid task subtype (%s).", subtaskID_names[t->subtype]); @@ -242,6 +251,8 @@ void *runner_main(void *data) { runner_dopair_branch_bh_feedback(r, ci, cj); else if (t->subtype == task_subtype_rt_inject) runner_dopair_branch_rt_inject(r, ci, cj, 1); + else if (t->subtype == task_subtype_sink_compute_formation) + runner_dopair_branch_sinks_compute_formation(r, ci, cj); else error("Unknown/invalid task subtype (%s/%s).", taskID_names[t->type], subtaskID_names[t->subtype]); @@ -274,6 +285,8 @@ void *runner_main(void *data) { runner_dosub_self_bh_feedback(r, ci, 1); else if (t->subtype == task_subtype_rt_inject) runner_dosub_self_rt_inject(r, ci, 1); + else if (t->subtype == task_subtype_sink_compute_formation) + runner_dosub_self_sinks_compute_formation(r, ci, 1); else error("Unknown/invalid task subtype (%s/%s).", taskID_names[t->type], subtaskID_names[t->subtype]); @@ -306,6 +319,8 @@ void *runner_main(void *data) { runner_dosub_pair_bh_feedback(r, ci, cj, 1); else if (t->subtype == task_subtype_rt_inject) runner_dosub_pair_rt_inject(r, ci, cj, 1); + else if (t->subtype == task_subtype_sink_compute_formation) + runner_dosub_pair_sinks_compute_formation(r, ci, cj, 1); else error("Unknown/invalid task subtype (%s/%s).", taskID_names[t->type], subtaskID_names[t->subtype]); @@ -459,9 +474,6 @@ void *runner_main(void *data) { case task_type_grav_down: runner_do_grav_down(r, t->ci, 1); break; - case task_type_grav_mesh: - runner_do_grav_mesh(r, t->ci, 1); - break; case task_type_grav_long_range: runner_do_grav_long_range(r, t->ci, 1); break; @@ -486,6 +498,9 @@ void *runner_main(void *data) { case task_type_fof_pair: runner_do_fof_pair(r, t->ci, t->cj, 1); break; + case task_type_rt_ghost1: + runner_do_rt_ghost1(r, t->ci, 1); + break; default: error("Unknown/invalid task type (%d).", t->type); } diff --git a/src/runner_others.c b/src/runner_others.c index b267e87af38d69d37a124f73df68a51072378183..d0227c95ebcf5caa3a246a55aec2250ec2d4d1c6 100644 --- a/src/runner_others.c +++ b/src/runner_others.c @@ -102,47 +102,6 @@ void runner_do_grav_external(struct runner *r, struct cell *c, int timer) { if (timer) TIMER_TOC(timer_dograv_external); } -/** - * @brief Calculate gravity accelerations from the periodic mesh - * - * @param r runner task - * @param c cell - * @param timer 1 if the time is to be recorded. - */ -void runner_do_grav_mesh(struct runner *r, struct cell *c, int timer) { - - struct gpart *restrict gparts = c->grav.parts; - const int gcount = c->grav.count; - const struct engine *e = r->e; - -#ifdef SWIFT_DEBUG_CHECKS - if (!e->s->periodic) error("Calling mesh forces in non-periodic mode."); -#endif - - TIMER_TIC; - - /* Anything to do here? */ - if (!cell_is_active_gravity(c, e)) return; - - /* Recurse? */ - if (c->split) { - for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_do_grav_mesh(r, c->progeny[k], 0); - } else { - - /* Get the forces from the gravity mesh */ -#ifndef SWIFT_TASKS_WITHOUT_ATOMICS - lock_lock(&c->grav.plock); -#endif - pm_mesh_interpolate_forces(e->mesh, e, gparts, gcount); -#ifndef SWIFT_TASKS_WITHOUT_ATOMICS - if (lock_unlock(&c->grav.plock) != 0) error("Error unlocking cell"); -#endif - } - - if (timer) TIMER_TOC(timer_dograv_mesh); -} - /** * @brief Calculate change in thermal state of particles induced * by radiative cooling and heating. diff --git a/src/runner_time_integration.c b/src/runner_time_integration.c index 16d7267fa55ccd8b7444f5c518766a4f237b4dab..656490bd3491a5166936af682623e6de668b28fc 100644 --- a/src/runner_time_integration.c +++ b/src/runner_time_integration.c @@ -46,7 +46,7 @@ * @param c The cell. * @param timer 1 if the time is to be recorded. */ -void runner_do_init_grav(struct runner *r, struct cell *c, int timer) { +void runner_do_init_grav(struct runner *r, struct cell *c, const int timer) { const struct engine *e = r->e; @@ -66,7 +66,8 @@ void runner_do_init_grav(struct runner *r, struct cell *c, int timer) { /* Recurse? */ if (c->split) { for (int k = 0; k < 8; k++) { - if (c->progeny[k] != NULL) runner_do_init_grav(r, c->progeny[k], 0); + if (c->progeny[k] != NULL) + runner_do_init_grav(r, c->progeny[k], /*timer=*/0); } } @@ -80,12 +81,13 @@ void runner_do_init_grav(struct runner *r, struct cell *c, int timer) { * @param c The cell. * @param timer Are we timing this ? */ -void runner_do_kick1(struct runner *r, struct cell *c, int timer) { +void runner_do_kick1(struct runner *r, struct cell *c, const int timer) { const struct engine *e = r->e; const struct cosmology *cosmo = e->cosmology; const struct hydro_props *hydro_props = e->hydro_properties; const struct entropy_floor_properties *entropy_floor = e->entropy_floor; + const int periodic = e->s->periodic; const int with_cosmology = (e->policy & engine_policy_cosmology); struct part *restrict parts = c->hydro.parts; struct xpart *restrict xparts = c->hydro.xparts; @@ -112,9 +114,26 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { /* Recurse? */ if (c->split) { for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_do_kick1(r, c->progeny[k], 0); + if (c->progeny[k] != NULL) runner_do_kick1(r, c->progeny[k], /*timer=*/0); } else { + integertime_t ti_begin_mesh = -1; + integertime_t ti_end_mesh = 0; + double dt_kick_mesh_grav = 0.; + + /* Are we at a step where we do mesh-gravity time-integration? */ + if (periodic && e->mesh->ti_beg_mesh_next == e->ti_current) { + + const integertime_t ti_step = + e->mesh->ti_end_mesh_next - e->mesh->ti_beg_mesh_next; + ti_begin_mesh = e->mesh->ti_beg_mesh_next; + ti_end_mesh = e->mesh->ti_beg_mesh_next + ti_step / 2; + + /* Time interval for this mesh gravity half-kick */ + dt_kick_mesh_grav = kick_get_grav_kick_dt( + ti_begin_mesh, ti_end_mesh, time_base, with_cosmology, cosmo); + } + /* Loop over the parts in this cell. */ for (int k = 0; k < count; k++) { @@ -133,10 +152,9 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(p->time_bin); const integertime_t ti_begin = get_integer_time_begin(ti_current + 1, p->time_bin); + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - const integertime_t ti_end = ti_begin + ti_step; - if (ti_begin != ti_current) error( "Particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " @@ -145,36 +163,20 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { ti_current); #endif - /* Time interval for this half-kick */ - double dt_kick_grav, dt_kick_hydro, dt_kick_therm, dt_kick_corr; - if (with_cosmology) { - dt_kick_hydro = cosmology_get_hydro_kick_factor( - cosmo, ti_begin, ti_begin + ti_step / 2); - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_begin, - ti_begin + ti_step / 2); - dt_kick_therm = cosmology_get_therm_kick_factor( - cosmo, ti_begin, ti_begin + ti_step / 2); - dt_kick_corr = cosmology_get_corr_kick_factor(cosmo, ti_begin, - ti_begin + ti_step / 2); - } else { - dt_kick_hydro = (ti_step / 2) * time_base; - dt_kick_grav = (ti_step / 2) * time_base; - dt_kick_therm = (ti_step / 2) * time_base; - dt_kick_corr = (ti_step / 2) * time_base; - } - - /* do the kick */ - kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, - dt_kick_corr, cosmo, hydro_props, entropy_floor, ti_begin, - ti_begin + ti_step / 2); - - /* Update the accelerations to be used in the drift for hydro */ - if (p->gpart != NULL) { - - xp->a_grav[0] = p->gpart->a_grav[0]; - xp->a_grav[1] = p->gpart->a_grav[1]; - xp->a_grav[2] = p->gpart->a_grav[2]; - } + /* Time intervals for this half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); + const double dt_kick_hydro = kick_get_hydro_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); + const double dt_kick_therm = kick_get_therm_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); + const double dt_kick_corr = kick_get_corr_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); + + /* Do the kick */ + kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_mesh_grav, + dt_kick_therm, dt_kick_corr, cosmo, hydro_props, + entropy_floor, ti_begin, ti_end, ti_begin_mesh, ti_end_mesh); } } @@ -184,6 +186,15 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { /* Get a handle on the part. */ struct gpart *restrict gp = &gparts[k]; +#ifdef SWIFT_DEBUG_CHECKS + if (ti_begin_mesh != -1 && !gpart_is_starting(gp, e) && + !gpart_is_inhibited(gp, e)) { + error( + "Particle on a time-step longer than the mesh synchronization " + "step!"); + } +#endif + /* If the g-particle has no counterpart and needs to be kicked */ if ((gp->type == swift_type_dark_matter || gp->type == swift_type_dark_matter_background) && @@ -192,29 +203,26 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(gp->time_bin); const integertime_t ti_begin = get_integer_time_begin(ti_current + 1, gp->time_bin); + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - const integertime_t ti_end = + const integertime_t ti_end_check = get_integer_time_end(ti_current + 1, gp->time_bin); if (ti_begin != ti_current) error( "G-particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " "ti_step=%lld time_bin=%d ti_current=%lld", - ti_end, ti_begin, ti_step, gp->time_bin, ti_current); + ti_end_check, ti_begin, ti_step, gp->time_bin, ti_current); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_begin, - ti_begin + ti_step / 2); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); - /* do the kick */ - kick_gpart(gp, dt_kick_grav, ti_begin, ti_begin + ti_step / 2); + /* Do the kick */ + kick_gpart(gp, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); } } @@ -230,29 +238,26 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(sp->time_bin); const integertime_t ti_begin = get_integer_time_begin(ti_current + 1, sp->time_bin); + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - const integertime_t ti_end = + const integertime_t ti_end_check = get_integer_time_end(ti_current + 1, sp->time_bin); if (ti_begin != ti_current) error( "S-particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " "ti_step=%lld time_bin=%d ti_current=%lld", - ti_end, ti_begin, ti_step, sp->time_bin, ti_current); + ti_end_check, ti_begin, ti_step, sp->time_bin, ti_current); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_begin, - ti_begin + ti_step / 2); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); - /* do the kick */ - kick_spart(sp, dt_kick_grav, ti_begin, ti_begin + ti_step / 2); + /* Do the kick */ + kick_spart(sp, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); } } @@ -268,29 +273,26 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(sink->time_bin); const integertime_t ti_begin = get_integer_time_begin(ti_current + 1, sink->time_bin); + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - const integertime_t ti_end = + const integertime_t ti_end_check = get_integer_time_end(ti_current + 1, sink->time_bin); if (ti_begin != ti_current) error( "Sink-particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " "ti_step=%lld time_bin=%d ti_current=%lld", - ti_end, ti_begin, ti_step, sink->time_bin, ti_current); + ti_end_check, ti_begin, ti_step, sink->time_bin, ti_current); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_begin, - ti_begin + ti_step / 2); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); - /* do the kick */ - kick_sink(sink, dt_kick_grav, ti_begin, ti_begin + ti_step / 2); + /* Do the kick */ + kick_sink(sink, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); } } @@ -306,29 +308,26 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(bp->time_bin); const integertime_t ti_begin = get_integer_time_begin(ti_current + 1, bp->time_bin); + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - const integertime_t ti_end = + const integertime_t ti_end_check = get_integer_time_end(ti_current + 1, bp->time_bin); if (ti_begin != ti_current) error( "B-particle in wrong time-bin, ti_end=%lld, ti_begin=%lld, " "ti_step=%lld time_bin=%d ti_current=%lld", - ti_end, ti_begin, ti_step, bp->time_bin, ti_current); + ti_end_check, ti_begin, ti_step, bp->time_bin, ti_current); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_begin, - ti_begin + ti_step / 2); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); - /* do the kick */ - kick_bpart(bp, dt_kick_grav, ti_begin, ti_begin + ti_step / 2); + /* Do the kick */ + kick_bpart(bp, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); } } } @@ -345,13 +344,14 @@ void runner_do_kick1(struct runner *r, struct cell *c, int timer) { * @param c The cell. * @param timer Are we timing this ? */ -void runner_do_kick2(struct runner *r, struct cell *c, int timer) { +void runner_do_kick2(struct runner *r, struct cell *c, const int timer) { const struct engine *e = r->e; const struct cosmology *cosmo = e->cosmology; const struct hydro_props *hydro_props = e->hydro_properties; const struct entropy_floor_properties *entropy_floor = e->entropy_floor; const int with_cosmology = (e->policy & engine_policy_cosmology); + const int periodic = e->s->periodic; const int count = c->hydro.count; const int gcount = c->grav.count; const int scount = c->stars.count; @@ -377,9 +377,26 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Recurse? */ if (c->split) { for (int k = 0; k < 8; k++) - if (c->progeny[k] != NULL) runner_do_kick2(r, c->progeny[k], 0); + if (c->progeny[k] != NULL) runner_do_kick2(r, c->progeny[k], /*timer=*/0); } else { + integertime_t ti_begin_mesh = -1; + integertime_t ti_end_mesh = 0; + double dt_kick_mesh_grav = 0.; + + /* Are we at a step where we do mesh-gravity time-integration? */ + if (periodic && e->mesh->ti_end_mesh_last == e->ti_current) { + + const integertime_t ti_step = + e->mesh->ti_end_mesh_next - e->mesh->ti_beg_mesh_next; + ti_begin_mesh = e->mesh->ti_beg_mesh_last + ti_step / 2; + ti_end_mesh = e->mesh->ti_end_mesh_last; + + /* Time interval for this mesh gravity half-kick */ + dt_kick_mesh_grav = kick_get_grav_kick_dt( + ti_begin_mesh, ti_end_mesh, time_base, with_cosmology, cosmo); + } + /* Loop over the particles in this cell. */ for (int k = 0; k < count; k++) { @@ -390,48 +407,39 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* If particle needs to be kicked */ if (part_is_active(p, e)) { - integertime_t ti_begin, ti_end, ti_step; - #ifdef SWIFT_DEBUG_CHECKS if (p->limiter_data.wakeup != time_bin_not_awake) error("Woken-up particle that has not been processed in kick1"); #endif - /* Time-step length on the integer timeline */ - ti_step = get_integer_timestep(p->time_bin); - ti_begin = get_integer_time_begin(ti_current, p->time_bin); - ti_end = ti_begin + ti_step; + const integertime_t ti_step = get_integer_timestep(p->time_bin); + const integertime_t ti_begin = + get_integer_time_begin(ti_current, p->time_bin) + ti_step / 2; + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - if (ti_begin + ti_step != ti_current) + if (ti_end != ti_current) error( "Particle in wrong time-bin, ti_begin=%lld, ti_step=%lld " "time_bin=%d wakeup=%d ti_current=%lld", ti_begin, ti_step, p->time_bin, p->limiter_data.wakeup, ti_current); #endif - /* Time interval for this half-kick */ - double dt_kick_grav, dt_kick_hydro, dt_kick_therm, dt_kick_corr; - if (with_cosmology) { - dt_kick_hydro = cosmology_get_hydro_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_end); - dt_kick_grav = cosmology_get_grav_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_end); - dt_kick_therm = cosmology_get_therm_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_end); - dt_kick_corr = cosmology_get_corr_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_end); - } else { - dt_kick_hydro = (ti_end - (ti_begin + ti_step / 2)) * time_base; - dt_kick_grav = (ti_end - (ti_begin + ti_step / 2)) * time_base; - dt_kick_therm = (ti_end - (ti_begin + ti_step / 2)) * time_base; - dt_kick_corr = (ti_end - (ti_begin + ti_step / 2)) * time_base; - } + + /* Time intervals for this half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); + const double dt_kick_hydro = kick_get_hydro_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); + const double dt_kick_therm = kick_get_therm_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); + const double dt_kick_corr = kick_get_corr_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); /* Finish the time-step with a second half-kick */ - kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, - dt_kick_corr, cosmo, hydro_props, entropy_floor, - ti_begin + ti_step / 2, ti_end); + kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_mesh_grav, + dt_kick_therm, dt_kick_corr, cosmo, hydro_props, + entropy_floor, ti_begin, ti_end, ti_begin_mesh, ti_end_mesh); #ifdef SWIFT_DEBUG_CHECKS /* Check that kick and the drift are synchronized */ @@ -449,6 +457,14 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { /* Get a handle on the part. */ struct gpart *restrict gp = &gparts[k]; +#ifdef SWIFT_DEBUG_CHECKS + if (ti_begin_mesh != -1 && !gpart_is_active(gp, e)) { + error( + "Particle on a time-step longer than the mesh synchronization " + "step!"); + } +#endif + /* If the g-particle has no counterpart and needs to be kicked */ if ((gp->type == swift_type_dark_matter || gp->type == swift_type_dark_matter_background) && @@ -456,25 +472,20 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(gp->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, gp->time_bin); + get_integer_time_begin(ti_current, gp->time_bin) + ti_step / 2; + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - if (ti_begin + ti_step != ti_current) - error("Particle in wrong time-bin"); + if (ti_end != ti_current) error("Particle in wrong time-bin"); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_begin + ti_step); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); /* Finish the time-step with a second half-kick */ - kick_gpart(gp, dt_kick_grav, ti_begin + ti_step / 2, - ti_begin + ti_step); + kick_gpart(gp, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); #ifdef SWIFT_DEBUG_CHECKS /* Check that kick and the drift are synchronized */ @@ -498,25 +509,20 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(sp->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, sp->time_bin); + get_integer_time_begin(ti_current, sp->time_bin) + ti_step / 2; + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - if (ti_begin + ti_step != ti_current) - error("Particle in wrong time-bin"); + if (ti_end != ti_current) error("Particle in wrong time-bin"); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_begin + ti_step); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); /* Finish the time-step with a second half-kick */ - kick_spart(sp, dt_kick_grav, ti_begin + ti_step / 2, - ti_begin + ti_step); + kick_spart(sp, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); #ifdef SWIFT_DEBUG_CHECKS /* Check that kick and the drift are synchronized */ @@ -540,25 +546,20 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(sink->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, sink->time_bin); + get_integer_time_begin(ti_current, sink->time_bin) + ti_step / 2; + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - if (ti_begin + ti_step != ti_current) - error("Particle in wrong time-bin"); + if (ti_end != ti_current) error("Particle in wrong time-bin"); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_begin + ti_step); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); /* Finish the time-step with a second half-kick */ - kick_sink(sink, dt_kick_grav, ti_begin + ti_step / 2, - ti_begin + ti_step); + kick_sink(sink, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); #ifdef SWIFT_DEBUG_CHECKS /* Check that kick and the drift are synchronized */ @@ -582,25 +583,20 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { const integertime_t ti_step = get_integer_timestep(bp->time_bin); const integertime_t ti_begin = - get_integer_time_begin(ti_current, bp->time_bin); + get_integer_time_begin(ti_current, bp->time_bin) + ti_step / 2; + const integertime_t ti_end = ti_begin + ti_step / 2; #ifdef SWIFT_DEBUG_CHECKS - if (ti_begin + ti_step != ti_current) - error("Particle in wrong time-bin"); + if (ti_end != ti_current) error("Particle in wrong time-bin"); #endif - /* Time interval for this half-kick */ - double dt_kick_grav; - if (with_cosmology) { - dt_kick_grav = cosmology_get_grav_kick_factor( - cosmo, ti_begin + ti_step / 2, ti_begin + ti_step); - } else { - dt_kick_grav = (ti_step / 2) * time_base; - } + /* Time interval for this gravity half-kick */ + const double dt_kick_grav = kick_get_grav_kick_dt( + ti_begin, ti_end, time_base, with_cosmology, cosmo); /* Finish the time-step with a second half-kick */ - kick_bpart(bp, dt_kick_grav, ti_begin + ti_step / 2, - ti_begin + ti_step); + kick_bpart(bp, dt_kick_grav, ti_begin, ti_end, dt_kick_mesh_grav, + ti_begin_mesh, ti_end_mesh); #ifdef SWIFT_DEBUG_CHECKS /* Check that kick and the drift are synchronized */ @@ -624,7 +620,7 @@ void runner_do_kick2(struct runner *r, struct cell *c, int timer) { * @param c The cell. * @param timer Are we timing this ? */ -void runner_do_timestep(struct runner *r, struct cell *c, int timer) { +void runner_do_timestep(struct runner *r, struct cell *c, const int timer) { const struct engine *e = r->e; const integertime_t ti_current = e->ti_current; @@ -1013,7 +1009,7 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { struct cell *restrict cp = c->progeny[k]; /* Recurse */ - runner_do_timestep(r, cp, 0); + runner_do_timestep(r, cp, /*timer=*/0); /* And aggregate */ updated += cp->hydro.updated; @@ -1101,7 +1097,8 @@ void runner_do_timestep(struct runner *r, struct cell *c, int timer) { * @param force Limit the particles irrespective of the #cell flags. * @param timer Are we timing this ? */ -void runner_do_limiter(struct runner *r, struct cell *c, int force, int timer) { +void runner_do_limiter(struct runner *r, struct cell *c, int force, + const int timer) { const struct engine *e = r->e; const int count = c->hydro.count; @@ -1139,7 +1136,7 @@ void runner_do_limiter(struct runner *r, struct cell *c, int force, int timer) { struct cell *restrict cp = c->progeny[k]; /* Recurse */ - runner_do_limiter(r, cp, force, 0); + runner_do_limiter(r, cp, force, /*timer=*/0); /* And aggregate */ ti_hydro_end_min = min(cp->hydro.ti_end_min, ti_hydro_end_min); @@ -1240,7 +1237,8 @@ void runner_do_limiter(struct runner *r, struct cell *c, int force, int timer) { * @param force Limit the particles irrespective of the #cell flags. * @param timer Are we timing this ? */ -void runner_do_sync(struct runner *r, struct cell *c, int force, int timer) { +void runner_do_sync(struct runner *r, struct cell *c, int force, + const int timer) { const struct engine *e = r->e; const integertime_t ti_current = e->ti_current; @@ -1280,7 +1278,7 @@ void runner_do_sync(struct runner *r, struct cell *c, int force, int timer) { struct cell *restrict cp = c->progeny[k]; /* Recurse */ - runner_do_sync(r, cp, force, 0); + runner_do_sync(r, cp, force, /*timer=*/0); /* And aggregate */ ti_hydro_end_min = min(cp->hydro.ti_end_min, ti_hydro_end_min); diff --git a/src/scheduler.c b/src/scheduler.c index 3b25220708da1346af896a67aa140ec0345f8d03..54704c4b5c086dff4069a8f77c2894b23e4ec646 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1032,8 +1032,6 @@ void scheduler_splittasks_mapper(void *map_data, int num_elements, scheduler_splittask_gravity(t, s); } else if (t->subtype == task_subtype_grav) { scheduler_splittask_gravity(t, s); - } else if (t->type == task_type_grav_mesh) { - /* For future use */ } else { #ifdef SWIFT_DEBUG_CHECKS error("Unexpected task sub-type %s/%s", taskID_names[t->type], @@ -1361,6 +1359,7 @@ void scheduler_reweight(struct scheduler *s, int verbose) { const float scount_i = (t->ci != NULL) ? t->ci->stars.count : 0.f; const float scount_j = (t->cj != NULL) ? t->cj->stars.count : 0.f; const float sink_count_i = (t->ci != NULL) ? t->ci->sinks.count : 0.f; + const float sink_count_j = (t->cj != NULL) ? t->cj->sinks.count : 0.f; const float bcount_i = (t->ci != NULL) ? t->ci->black_holes.count : 0.f; const float bcount_j = (t->cj != NULL) ? t->cj->black_holes.count : 0.f; @@ -1388,6 +1387,8 @@ void scheduler_reweight(struct scheduler *s, int verbose) { else if (t->subtype == task_subtype_stars_density || t->subtype == task_subtype_stars_feedback) cost = 1.f * wscale * scount_i * count_i; + else if (t->subtype == task_subtype_sink_compute_formation) + cost = 1.f * wscale * count_i * sink_count_i; else if (t->subtype == task_subtype_bh_density || t->subtype == task_subtype_bh_swallow || t->subtype == task_subtype_bh_feedback) @@ -1425,6 +1426,16 @@ void scheduler_reweight(struct scheduler *s, int verbose) { cost = 2.f * wscale * (scount_i * count_j + scount_j * count_i) * sid_scale[t->flags]; + } else if (t->subtype == task_subtype_sink_compute_formation) { + if (t->ci->nodeID != nodeID) + cost = 3.f * wscale * count_i * sink_count_j * sid_scale[t->flags]; + else if (t->cj->nodeID != nodeID) + cost = 3.f * wscale * sink_count_i * count_j * sid_scale[t->flags]; + else + cost = 2.f * wscale * + (sink_count_i * count_j + sink_count_j * count_i) * + sid_scale[t->flags]; + } else if (t->subtype == task_subtype_bh_density || t->subtype == task_subtype_bh_swallow || t->subtype == task_subtype_bh_feedback) { @@ -1474,6 +1485,18 @@ void scheduler_reweight(struct scheduler *s, int verbose) { sid_scale[t->flags]; } + } else if (t->subtype == task_subtype_sink_compute_formation) { + if (t->ci->nodeID != nodeID) { + cost = + 3.f * (wscale * count_i) * sink_count_j * sid_scale[t->flags]; + } else if (t->cj->nodeID != nodeID) { + cost = + 3.f * (wscale * sink_count_i) * count_j * sid_scale[t->flags]; + } else { + cost = 2.f * wscale * + (sink_count_i * count_j + sink_count_j * count_i) * + sid_scale[t->flags]; + } } else if (t->subtype == task_subtype_bh_density || t->subtype == task_subtype_bh_swallow || t->subtype == task_subtype_bh_feedback) { @@ -1513,6 +1536,8 @@ void scheduler_reweight(struct scheduler *s, int verbose) { if (t->subtype == task_subtype_stars_density || t->subtype == task_subtype_stars_feedback) { cost = 1.f * (wscale * scount_i) * count_i; + } else if (t->subtype == task_subtype_sink_compute_formation) { + cost = 1.f * (wscale * sink_count_i) * count_i; } else if (t->subtype == task_subtype_bh_density || t->subtype == task_subtype_bh_swallow || t->subtype == task_subtype_bh_feedback) { @@ -1572,9 +1597,6 @@ void scheduler_reweight(struct scheduler *s, int verbose) { case task_type_grav_long_range: cost = wscale * gcount_i; break; - case task_type_grav_mesh: - cost = wscale * gcount_i; - break; case task_type_grav_mm: cost = wscale * (gcount_i + gcount_j); break; @@ -1593,6 +1615,9 @@ void scheduler_reweight(struct scheduler *s, int verbose) { case task_type_sink_formation: cost = wscale * (count_i + sink_count_i); break; + case task_type_rt_ghost1: + cost = wscale * count_i; + break; case task_type_kick1: cost = wscale * (count_i + gcount_i + scount_i + sink_count_i + bcount_i); diff --git a/src/serial_io.c b/src/serial_io.c index 7fef6015b3c6765e77c3c0846ff8b28966569793..b734d5fa7082b059537887f3260ceafa7c1a22a6 100644 --- a/src/serial_io.c +++ b/src/serial_io.c @@ -1159,8 +1159,8 @@ void write_output_serial(struct engine* e, } /* Write the location of the particles in the arrays */ - io_write_cell_offsets(h_grp_cells, e->s->cdim, e->s->dim, e->s->pos_dithering, - e->s->cells_top, e->s->nr_cells, e->s->width, mpi_rank, + io_write_cell_offsets(h_grp_cells, e->s->cdim, e->s->dim, e->s->cells_top, + e->s->nr_cells, e->s->width, mpi_rank, /*distributed=*/0, N_total, offset, numFields, internal_units, snapshot_units); diff --git a/src/single_io.c b/src/single_io.c index 105a37efdd2ed8f1fe8c5b6833a7ecc72c5fc621..3765257f3914a0610763ad611ac2d8aef99c88cb 100644 --- a/src/single_io.c +++ b/src/single_io.c @@ -954,8 +954,8 @@ void write_output_single(struct engine* e, if (h_grp < 0) error("Error while creating cells group"); /* Write the location of the particles in the arrays */ - io_write_cell_offsets(h_grp, e->s->cdim, e->s->dim, e->s->pos_dithering, - e->s->cells_top, e->s->nr_cells, e->s->width, e->nodeID, + io_write_cell_offsets(h_grp, e->s->cdim, e->s->dim, e->s->cells_top, + e->s->nr_cells, e->s->width, e->nodeID, /*distributed=*/0, N_total, global_offsets, numFields, internal_units, snapshot_units); H5Gclose(h_grp); diff --git a/src/sink.h b/src/sink.h index 991bfd27c0b9f829359b90354864acab1d26ea23..c22a73752a23211706d4189158d4524607f6bdf1 100644 --- a/src/sink.h +++ b/src/sink.h @@ -25,6 +25,7 @@ /* Select the correct sink model */ #if defined(SINK_NONE) #include "./sink/Default/sink.h" +#include "./sink/Default/sink_iact.h" #else #error "Invalid choice of sink model" #endif diff --git a/src/sink/Default/sink.h b/src/sink/Default/sink.h index 37ef316ac1835eb247d310f6068b45fd72dba074..9f7fc3b28bacdb38441c5e6b8b5fa5f9e33571bf 100644 --- a/src/sink/Default/sink.h +++ b/src/sink/Default/sink.h @@ -60,7 +60,13 @@ __attribute__((always_inline)) INLINE static void sink_first_init_sink( * @param sp The particle to act upon */ __attribute__((always_inline)) INLINE static void sink_init_sink( - struct sink* sp) {} + struct sink* sp) { +#ifdef DEBUG_INTERACTIONS_SINKS + for (int i = 0; i < MAX_NUM_OF_NEIGHBOURS_SINKS; ++i) + sp->ids_ngbs_formation[i] = -1; + sp->num_ngb_formation = 0; +#endif +} /** * @brief Predict additional particle fields forward in time when drifting diff --git a/src/sink/Default/sink_iact.h b/src/sink/Default/sink_iact.h new file mode 100644 index 0000000000000000000000000000000000000000..188c41d1d634ad2e2835e6b4668c14a080012f25 --- /dev/null +++ b/src/sink/Default/sink_iact.h @@ -0,0 +1,51 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2020 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_DEFAULT_SINKS_IACT_H +#define SWIFT_DEFAULT_SINKS_IACT_H + +/** + * @brief Compute formation 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 ri Comoving cut off radius of particle i. + * @param hj Comoving smoothing-length of particle j. + * @param si First sink particle. + * @param pj Second particle. + * @param a Current scale factor. + * @param H Current Hubble parameter. + */ +__attribute__((always_inline)) INLINE static void +runner_iact_nonsym_sinks_compute_formation(const float r2, const float *dx, + const float hi, const float hj, + struct sink *restrict si, + const struct part *restrict pj, + const float a, const float H) { + +#ifdef DEBUG_INTERACTIONS_SINKS + /* Update ngb counters */ + if (si->num_ngb_formation < MAX_NUM_OF_NEIGHBOURS_SINKS) + si->ids_ngbs_formation[si->num_ngb_formation] = pj->id; + + /* Update ngb counters */ + ++si->num_ngb_formation; +#endif +} + +#endif diff --git a/src/sink/Default/sink_io.h b/src/sink/Default/sink_io.h index a1d4a8f8f20efdaa537a0301eb8d410094ee75be..e5227b76d484becca8ecde9b612115015ac588e9 100644 --- a/src/sink/Default/sink_io.h +++ b/src/sink/Default/sink_io.h @@ -51,9 +51,9 @@ INLINE static void convert_sink_pos(const struct engine* e, const struct space* s = e->s; if (s->periodic) { - ret[0] = box_wrap(sp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(sp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(sp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(sp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(sp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(sp->x[2], 0.0, s->dim[2]); } else { ret[0] = sp->x[0]; ret[1] = sp->x[1]; @@ -125,6 +125,20 @@ INLINE static void sink_write_particles(const struct sink* sinks, list[3] = io_make_output_field("ParticleIDs", ULONGLONG, 1, UNIT_CONV_NO_UNITS, 0.f, sinks, id, "Unique ID of the particles"); + +#ifdef DEBUG_INTERACTIONS_SINKS + + list += *num_fields; + *num_fields += 2; + + list[0] = + io_make_output_field("Num_ngb_formation", INT, 1, UNIT_CONV_NO_UNITS, 0.f, + sinks, num_ngb_formation, "Number of neighbors"); + list[1] = + io_make_output_field("Ids_ngb_formation", LONGLONG, + MAX_NUM_OF_NEIGHBOURS_SINKS, UNIT_CONV_NO_UNITS, 0.f, + sinks, ids_ngbs_formation, "IDs of the neighbors"); +#endif } #endif /* SWIFT_DEFAULT_SINK_IO_H */ diff --git a/src/sink/Default/sink_part.h b/src/sink/Default/sink_part.h index d1184563b6fb9df2d0fadf25a3e7540ca069c864..22d6c88bde456883f19c05d1b7f50474bbc10c7c 100644 --- a/src/sink/Default/sink_part.h +++ b/src/sink/Default/sink_part.h @@ -62,6 +62,13 @@ struct sink { #endif +#ifdef DEBUG_INTERACTIONS_SINKS + /*! Number of interactions in compute formation SELF and PAIR */ + int num_ngb_formation; + + /*! List of interacting particles in compute formation SELF and PAIR */ + long long ids_ngbs_formation[MAX_NUM_OF_NEIGHBOURS_SINKS]; +#endif } SWIFT_STRUCT_ALIGN; #endif /* SWIFT_DEFAULT_SINK_PART_H */ diff --git a/src/space.c b/src/space.c index fd14abc67c494bf8777583e57d5177fa5595d60a..026b4ce48ee1e51c9bc07d9133ba5f0586f1a93d 100644 --- a/src/space.c +++ b/src/space.c @@ -272,7 +272,6 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->grav.long_range = NULL; c->grav.down_in = NULL; c->grav.down = NULL; - c->grav.mesh = NULL; c->grav.end_force = NULL; c->top = c; c->super = c; @@ -300,6 +299,7 @@ void space_rebuild_recycle_mapper(void *map_data, int num_elements, c->hydro.rt_inject = NULL; c->hydro.rt_in = NULL; c->hydro.rt_out = NULL; + c->hydro.rt_ghost1 = NULL; star_formation_logger_init(&c->stars.sfh); #if defined(SWIFT_DEBUG_CHECKS) || defined(SWIFT_CELL_GRAPH) c->cellID = 0; @@ -1280,44 +1280,6 @@ void space_allocate_extras(struct space *s, int verbose) { free(local_cells); } -/** - * @brief Compute a new dithering vector to apply to all the particles - * in the simulation. - * - * @param s The #space. - * @param verbose Are we talkative? - */ -void space_dither(struct space *s, int verbose) { - - /* Store the old dithering vector */ - s->pos_dithering_old[0] = s->pos_dithering[0]; - s->pos_dithering_old[1] = s->pos_dithering[1]; - s->pos_dithering_old[2] = s->pos_dithering[2]; - - if (s->e->nodeID == 0) { - - const double dithering_ratio = s->e->gravity_properties->dithering_ratio; - - /* Compute the new dithering vector */ - const double rand_x = rand() / ((double)RAND_MAX); - const double rand_y = rand() / ((double)RAND_MAX); - const double rand_z = rand() / ((double)RAND_MAX); - - s->pos_dithering[0] = dithering_ratio * s->width[0] * rand_x; - s->pos_dithering[1] = dithering_ratio * s->width[1] * rand_y; - s->pos_dithering[2] = dithering_ratio * s->width[2] * rand_z; - } - -#ifdef WITH_MPI - /* Tell everyone what value to use */ - MPI_Bcast(s->pos_dithering, 3, MPI_DOUBLE, 0, MPI_COMM_WORLD); -#endif - - if (verbose) - message("Dithering the particle positions by [%e %e %e]", - s->pos_dithering[0], s->pos_dithering[1], s->pos_dithering[2]); -} - /** * @brief Re-build the cells as well as the tasks. * @@ -1342,10 +1304,6 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { /* Re-grid if necessary, or just re-set the cell data. */ space_regrid(s, verbose); - /* Are we dithering the particles? */ - const int with_dithering = s->e->gravity_properties->with_dithering; - if (s->with_self_gravity && with_dithering) space_dither(s, verbose); - /* Allocate extra space for particles that will be created */ if (s->with_star_formation || s->e->policy & engine_policy_sinks) space_allocate_extras(s, verbose); @@ -1488,8 +1446,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { const ticks tic2 = getticks(); /* Move non-local parts and inhibited parts to the end of the list. */ - if ((with_dithering || !repartitioned) && - (s->e->nr_nodes > 1 || count_inhibited_parts > 0)) { + if (!repartitioned && (s->e->nr_nodes > 1 || count_inhibited_parts > 0)) { for (size_t k = 0; k < nr_parts; /* void */) { @@ -1541,8 +1498,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { #endif /* SWIFT_DEBUG_CHECKS */ /* Move non-local sparts and inhibited sparts to the end of the list. */ - if ((with_dithering || !repartitioned) && - (s->e->nr_nodes > 1 || count_inhibited_sparts > 0)) { + if (!repartitioned && (s->e->nr_nodes > 1 || count_inhibited_sparts > 0)) { for (size_t k = 0; k < nr_sparts; /* void */) { @@ -1592,8 +1548,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { #endif /* SWIFT_DEBUG_CHECKS */ /* Move non-local bparts and inhibited bparts to the end of the list. */ - if ((with_dithering || !repartitioned) && - (s->e->nr_nodes > 1 || count_inhibited_bparts > 0)) { + if (!repartitioned && (s->e->nr_nodes > 1 || count_inhibited_bparts > 0)) { for (size_t k = 0; k < nr_bparts; /* void */) { @@ -1643,8 +1598,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { #endif /* SWIFT_DEBUG_CHECKS */ /* Move non-local sinks and inhibited sinks to the end of the list. */ - if ((with_dithering || !repartitioned) && - (s->e->nr_nodes > 1 || count_inhibited_sinks > 0)) { + if (!repartitioned && (s->e->nr_nodes > 1 || count_inhibited_sinks > 0)) { for (size_t k = 0; k < nr_sinks; /* void */) { @@ -1697,8 +1651,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { #endif /* SWIFT_DEBUG_CHECKS */ /* Move non-local gparts and inhibited parts to the end of the list. */ - if ((with_dithering || !repartitioned) && - (s->e->nr_nodes > 1 || count_inhibited_gparts > 0)) { + if (!repartitioned && (s->e->nr_nodes > 1 || count_inhibited_gparts > 0)) { for (size_t k = 0; k < nr_gparts; /* void */) { @@ -1709,7 +1662,8 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { nr_gparts -= 1; /* Swap the particle */ - memswap(&s->gparts[k], &s->gparts[nr_gparts], sizeof(struct gpart)); + memswap_unaligned(&s->gparts[k], &s->gparts[nr_gparts], + sizeof(struct gpart)); /* Swap the link with part/spart */ if (s->gparts[k].type == swift_type_gas) { @@ -1772,7 +1726,7 @@ void space_rebuild(struct space *s, int repartitioned, int verbose) { /* Exchange the strays, note that this potentially re-allocates the parts arrays. This can be skipped if we just repartitioned space as there should be no strays in that case */ - if (with_dithering || !repartitioned) { + if (!repartitioned) { size_t nr_parts_exchanged = s->nr_parts - nr_parts; size_t nr_gparts_exchanged = s->nr_gparts - nr_gparts; @@ -2441,14 +2395,6 @@ void space_parts_get_cell_index_mapper(void *map_data, int nr_parts, int *const ind = data->ind + (ptrdiff_t)(parts - s->parts); /* Get some constants */ - const int periodic = s->periodic; - const int dithering = s->e->gravity_properties->with_dithering; - const double delta_dithering_x = - s->pos_dithering[0] - s->pos_dithering_old[0]; - const double delta_dithering_y = - s->pos_dithering[1] - s->pos_dithering_old[1]; - const double delta_dithering_z = - s->pos_dithering[2] - s->pos_dithering_old[2]; const double dim_x = s->dim[0]; const double dim_y = s->dim[1]; const double dim_z = s->dim[2]; @@ -2478,14 +2424,8 @@ void space_parts_get_cell_index_mapper(void *map_data, int nr_parts, double old_pos_y = p->x[1]; double old_pos_z = p->x[2]; - if (periodic && dithering && p->time_bin != time_bin_not_created) { - old_pos_x += delta_dithering_x; - old_pos_y += delta_dithering_y; - old_pos_z += delta_dithering_z; - } - #ifdef SWIFT_DEBUG_CHECKS - if (!periodic && p->time_bin != time_bin_inhibited) { + if (!s->periodic && p->time_bin != time_bin_inhibited) { if (old_pos_x < 0. || old_pos_x > dim_x) error("Particle outside of volume along X."); if (old_pos_y < 0. || old_pos_y > dim_y) @@ -2582,14 +2522,6 @@ void space_gparts_get_cell_index_mapper(void *map_data, int nr_gparts, int *const ind = data->ind + (ptrdiff_t)(gparts - s->gparts); /* Get some constants */ - const int periodic = s->periodic; - const int dithering = s->e->gravity_properties->with_dithering; - const double delta_dithering_x = - s->pos_dithering[0] - s->pos_dithering_old[0]; - const double delta_dithering_y = - s->pos_dithering[1] - s->pos_dithering_old[1]; - const double delta_dithering_z = - s->pos_dithering[2] - s->pos_dithering_old[2]; const double dim_x = s->dim[0]; const double dim_y = s->dim[1]; const double dim_z = s->dim[2]; @@ -2618,14 +2550,8 @@ void space_gparts_get_cell_index_mapper(void *map_data, int nr_gparts, double old_pos_y = gp->x[1]; double old_pos_z = gp->x[2]; - if (periodic && dithering && gp->time_bin != time_bin_not_created) { - old_pos_x += delta_dithering_x; - old_pos_y += delta_dithering_y; - old_pos_z += delta_dithering_z; - } - #ifdef SWIFT_DEBUG_CHECKS - if (!periodic && gp->time_bin != time_bin_inhibited) { + if (!s->periodic && gp->time_bin != time_bin_inhibited) { if (old_pos_x < 0. || old_pos_x > dim_x) error("Particle outside of volume along X."); if (old_pos_y < 0. || old_pos_y > dim_y) @@ -2728,14 +2654,6 @@ void space_sparts_get_cell_index_mapper(void *map_data, int nr_sparts, int *const ind = data->ind + (ptrdiff_t)(sparts - s->sparts); /* Get some constants */ - const int periodic = s->periodic; - const int dithering = s->e->gravity_properties->with_dithering; - const double delta_dithering_x = - s->pos_dithering[0] - s->pos_dithering_old[0]; - const double delta_dithering_y = - s->pos_dithering[1] - s->pos_dithering_old[1]; - const double delta_dithering_z = - s->pos_dithering[2] - s->pos_dithering_old[2]; const double dim_x = s->dim[0]; const double dim_y = s->dim[1]; const double dim_z = s->dim[2]; @@ -2764,14 +2682,8 @@ void space_sparts_get_cell_index_mapper(void *map_data, int nr_sparts, double old_pos_y = sp->x[1]; double old_pos_z = sp->x[2]; - if (periodic && dithering && sp->time_bin != time_bin_not_created) { - old_pos_x += delta_dithering_x; - old_pos_y += delta_dithering_y; - old_pos_z += delta_dithering_z; - } - #ifdef SWIFT_DEBUG_CHECKS - if (!periodic && sp->time_bin != time_bin_inhibited) { + if (!s->periodic && sp->time_bin != time_bin_inhibited) { if (old_pos_x < 0. || old_pos_x > dim_x) error("Particle outside of volume along X."); if (old_pos_y < 0. || old_pos_y > dim_y) @@ -2870,14 +2782,6 @@ void space_bparts_get_cell_index_mapper(void *map_data, int nr_bparts, int *const ind = data->ind + (ptrdiff_t)(bparts - s->bparts); /* Get some constants */ - const int periodic = s->periodic; - const int dithering = s->e->gravity_properties->with_dithering; - const double delta_dithering_x = - s->pos_dithering[0] - s->pos_dithering_old[0]; - const double delta_dithering_y = - s->pos_dithering[1] - s->pos_dithering_old[1]; - const double delta_dithering_z = - s->pos_dithering[2] - s->pos_dithering_old[2]; const double dim_x = s->dim[0]; const double dim_y = s->dim[1]; const double dim_z = s->dim[2]; @@ -2906,14 +2810,8 @@ void space_bparts_get_cell_index_mapper(void *map_data, int nr_bparts, double old_pos_y = bp->x[1]; double old_pos_z = bp->x[2]; - if (periodic && dithering && bp->time_bin != time_bin_not_created) { - old_pos_x += delta_dithering_x; - old_pos_y += delta_dithering_y; - old_pos_z += delta_dithering_z; - } - #ifdef SWIFT_DEBUG_CHECKS - if (!periodic && bp->time_bin != time_bin_inhibited) { + if (!s->periodic && bp->time_bin != time_bin_inhibited) { if (old_pos_x < 0. || old_pos_x > dim_x) error("Particle outside of volume along X."); if (old_pos_y < 0. || old_pos_y > dim_y) @@ -3012,14 +2910,6 @@ void space_sinks_get_cell_index_mapper(void *map_data, int nr_sinks, int *const ind = data->ind + (ptrdiff_t)(sinks - s->sinks); /* Get some constants */ - const int periodic = s->periodic; - const int dithering = s->e->gravity_properties->with_dithering; - const double delta_dithering_x = - s->pos_dithering[0] - s->pos_dithering_old[0]; - const double delta_dithering_y = - s->pos_dithering[1] - s->pos_dithering_old[1]; - const double delta_dithering_z = - s->pos_dithering[2] - s->pos_dithering_old[2]; const double dim_x = s->dim[0]; const double dim_y = s->dim[1]; const double dim_z = s->dim[2]; @@ -3046,14 +2936,8 @@ void space_sinks_get_cell_index_mapper(void *map_data, int nr_sinks, double old_pos_y = sink->x[1]; double old_pos_z = sink->x[2]; - if (periodic && dithering && sink->time_bin != time_bin_not_created) { - old_pos_x += delta_dithering_x; - old_pos_y += delta_dithering_y; - old_pos_z += delta_dithering_z; - } - #ifdef SWIFT_DEBUG_CHECKS - if (!periodic && sink->time_bin != time_bin_inhibited) { + if (!s->periodic && sink->time_bin != time_bin_inhibited) { if (old_pos_x < 0. || old_pos_x > dim_x) error("Particle outside of volume along X."); if (old_pos_y < 0. || old_pos_y > dim_y) @@ -3665,7 +3549,7 @@ void space_gparts_sort(struct gpart *gparts, struct part *parts, while (ind[j] == target_cid) { j = offsets[target_cid] + counts[target_cid]++; } - memswap(&gparts[j], &temp_gpart, sizeof(struct gpart)); + memswap_unaligned(&gparts[j], &temp_gpart, sizeof(struct gpart)); memswap(&ind[j], &target_cid, sizeof(int)); if (gparts[j].type == swift_type_gas) { parts[-gparts[j].id_or_neg_offset].gpart = &gparts[j]; @@ -3866,9 +3750,11 @@ void space_map_cells_pre(struct space *s, int full, * c->sinks.count or @c NULL. */ void space_split_recursive(struct space *s, struct cell *c, - struct cell_buff *buff, struct cell_buff *sbuff, - struct cell_buff *bbuff, struct cell_buff *gbuff, - struct cell_buff *sink_buff) { + struct cell_buff *restrict buff, + struct cell_buff *restrict sbuff, + struct cell_buff *restrict bbuff, + struct cell_buff *restrict gbuff, + struct cell_buff *restrict sink_buff) { const int count = c->hydro.count; const int gcount = c->grav.count; @@ -3988,13 +3874,8 @@ void space_split_recursive(struct space *s, struct cell *c, } } - /* Check the depth. */ - while (depth > (maxdepth = s->maxdepth)) { - atomic_cas(&s->maxdepth, maxdepth, depth); - } - /* If the depth is too large, we have a problem and should stop. */ - if (maxdepth > space_cell_maxdepth) { + if (depth > space_cell_maxdepth) { error( "Exceeded maximum depth (%d) when splitting cells, aborting. This is " "most likely due to having too many particles at the exact same " @@ -4131,7 +4012,7 @@ void space_split_recursive(struct space *s, struct cell *c, star_formation_logger_add(&c->stars.sfh, &cp->stars.sfh); /* Increase the depth */ - if (cp->maxdepth > maxdepth) maxdepth = cp->maxdepth; + maxdepth = max(maxdepth, cp->maxdepth); } } @@ -4469,6 +4350,9 @@ void space_split_recursive(struct space *s, struct cell *c, else c->owner = 0; /* Ok, there is really nothing on this rank... */ + /* Store the global max depth */ + if (c->depth == 0) atomic_max(&s->maxdepth, maxdepth); + /* Clean up. */ if (allocate_buffer) { if (buff != NULL) swift_free("tempbuff", buff); @@ -5102,6 +4986,7 @@ void space_first_init_gparts_mapper(void *restrict map_data, int count, /* Initialise the time-integration check variables */ gp[k].ti_drift = 0; gp[k].ti_kick = 0; + gp[k].ti_kick_mesh = 0; #endif } } @@ -5792,7 +5677,7 @@ void space_init(struct space *s, struct swift_params *params, if (s->initial_spart_h != -1.f) { message("Imposing a star smoothing length of %e", s->initial_spart_h); } - /* Read in imposed star smoothing length */ + /* Read in imposed black hole smoothing length */ s->initial_bpart_h = parser_get_opt_param_float( params, "InitialConditions:black_holes_smoothing_length", -1.f); if (s->initial_bpart_h != -1.f) { @@ -7019,7 +6904,8 @@ void space_write_cell(const struct space *s, FILE *f, const struct cell *c) { fprintf(f, "%i,%i,%i,%s,%s,%g,%g,%g,%g,%g,%g, ", c->hydro.count, c->stars.count, c->grav.count, superID, hydro_superID, c->loc[0], c->loc[1], c->loc[2], c->width[0], c->width[1], c->width[2]); - fprintf(f, "%g, %g\n", c->hydro.h_max, c->stars.h_max); + fprintf(f, "%g, %g %i %i\n", c->hydro.h_max, c->stars.h_max, c->depth, + c->maxdepth); /* Write children */ for (int i = 0; i < 8; i++) { @@ -7051,7 +6937,7 @@ void space_write_cell_hierarchy(const struct space *s, int j) { fprintf(f, "hydro_count,stars_count,gpart_count,super,hydro_super," "loc1,loc2,loc3,width1,width2,width3,"); - fprintf(f, "hydro_h_max,stars_h_max\n"); + fprintf(f, "hydro_h_max,stars_h_max,depth,maxdepth\n"); /* Write root data */ fprintf(f, "%i, ,-1,", root_id); diff --git a/src/space.h b/src/space.h index b43481b062cd0e4400af26159b055f7e1b74a99b..a4db4f92f2df8173afcb612018ee41a868a8ba38 100644 --- a/src/space.h +++ b/src/space.h @@ -117,14 +117,6 @@ struct space { /*! Inverse of the top-level cell width */ double iwidth[3]; - /*! Position vector added to all the particles at rebuild - time */ - double pos_dithering[3]; - - /*! Position vector added to all the particles at rebuild - time (value at the previous rebuild) */ - double pos_dithering_old[3]; - /*! The minimum top-level cell width allowed. */ double cell_min; diff --git a/src/star_formation/EAGLE/star_formation.h b/src/star_formation/EAGLE/star_formation.h index 37637844c6d94e719a33b3bd268ece85442502e9..57f97089289d089404f13effd876ea616ed4ad8f 100644 --- a/src/star_formation/EAGLE/star_formation.h +++ b/src/star_formation/EAGLE/star_formation.h @@ -579,6 +579,7 @@ INLINE static void star_formation_copy_properties( sp->number_of_SNII_events = 0; sp->last_enrichment_time = sp->birth_time; sp->count_since_last_enrichment = -1; + sp->number_of_heating_events = 0.; } /** diff --git a/src/stars/Default/stars_io.h b/src/stars/Default/stars_io.h index 02538449191a24bf2f9dd82a928fe51d3b883245..d0fd3c5915d322d0499cce21f79282df5a902451 100644 --- a/src/stars/Default/stars_io.h +++ b/src/stars/Default/stars_io.h @@ -54,9 +54,9 @@ INLINE static void convert_spart_pos(const struct engine *e, const struct space *s = e->s; if (s->periodic) { - ret[0] = box_wrap(sp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(sp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(sp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(sp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(sp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(sp->x[2], 0.0, s->dim[2]); } else { ret[0] = sp->x[0]; ret[1] = sp->x[1]; diff --git a/src/stars/EAGLE/stars.h b/src/stars/EAGLE/stars.h index f4cbeb6b6f7121ec52cb7a8568ce09fb99158f78..e575766d2d06430fe4788f218ddbef1cebb6e8a9 100644 --- a/src/stars/EAGLE/stars.h +++ b/src/stars/EAGLE/stars.h @@ -105,6 +105,8 @@ __attribute__((always_inline)) INLINE static void stars_first_init_spart( sp->time_bin = 0; sp->f_E = -1.f; sp->count_since_last_enrichment = -1; + sp->number_of_heating_events = 0.; + sp->number_of_SNII_events = 0; if (stars_properties->overwrite_birth_time) sp->birth_time = stars_properties->spart_first_init_birth_time; diff --git a/src/stars/EAGLE/stars_io.h b/src/stars/EAGLE/stars_io.h index 21a5e08a51c4ef50eeec2c37d39bf60ae5dfa6f8..dc0d347a548d231ba09e94b1903dd864539c369c 100644 --- a/src/stars/EAGLE/stars_io.h +++ b/src/stars/EAGLE/stars_io.h @@ -64,9 +64,9 @@ INLINE static void convert_spart_pos(const struct engine *e, const struct space *s = e->s; if (s->periodic) { - ret[0] = box_wrap(sp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(sp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(sp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(sp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(sp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(sp->x[2], 0.0, s->dim[2]); } else { ret[0] = sp->x[0]; ret[1] = sp->x[1]; @@ -120,7 +120,7 @@ INLINE static void stars_write_particles(const struct spart *sparts, const int with_cosmology) { /* Say how much we want to write */ - *num_fields = 11; + *num_fields = 12; /* List what we want to write */ list[0] = io_make_output_field_convert_spart( @@ -181,6 +181,11 @@ INLINE static void stars_write_particles(const struct spart *sparts, 0.f, sparts, birth_temperature, "Temperatures at the time of birth of the gas " "particles that turned into stars"); + + list[11] = io_make_output_field( + "FeedbackNumberOfHeatingEvents", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, + sparts, number_of_heating_events, + "Expected number of particles that were heated by each star particle."); } /** diff --git a/src/stars/EAGLE/stars_part.h b/src/stars/EAGLE/stars_part.h index eee3fc38a87a040be3ce339c5b3689eca80ff2d6..07072add21eb5d8dae41afcad4da6478a0554fde 100644 --- a/src/stars/EAGLE/stars_part.h +++ b/src/stars/EAGLE/stars_part.h @@ -98,6 +98,9 @@ struct spart { /*! The birth temperature */ float birth_temperature; + /*! Total number of (expected) feedback heating events so far */ + float number_of_heating_events; + /*! Star formation struct */ struct star_formation_spart_data sf_data; diff --git a/src/stars/GEAR/stars_io.h b/src/stars/GEAR/stars_io.h index 9fd2d329fc2243cbe93c73b3eea4412bfdbc246b..974b4de0755e2e17e6fe79a34d5762dc6fe6ecd0 100644 --- a/src/stars/GEAR/stars_io.h +++ b/src/stars/GEAR/stars_io.h @@ -56,9 +56,9 @@ INLINE static void convert_spart_pos(const struct engine *e, const struct space *s = e->s; if (s->periodic) { - ret[0] = box_wrap(sp->x[0] - s->pos_dithering[0], 0.0, s->dim[0]); - ret[1] = box_wrap(sp->x[1] - s->pos_dithering[1], 0.0, s->dim[1]); - ret[2] = box_wrap(sp->x[2] - s->pos_dithering[2], 0.0, s->dim[2]); + ret[0] = box_wrap(sp->x[0], 0.0, s->dim[0]); + ret[1] = box_wrap(sp->x[1], 0.0, s->dim[1]); + ret[2] = box_wrap(sp->x[2], 0.0, s->dim[2]); } else { ret[0] = sp->x[0]; ret[1] = sp->x[1]; diff --git a/src/statistics.c b/src/statistics.c index f2b51544efa723d9c87671e883307d10dbb1dda3..711782a84f45610215f2a6fbfa50af2fe2c57053 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -33,6 +33,7 @@ #include "statistics.h" /* Local headers. */ +#include "black_holes.h" #include "black_holes_io.h" #include "chemistry.h" #include "cooling.h" @@ -80,6 +81,8 @@ void stats_add(struct statistics *a, const struct statistics *b) { a->gas_Z_mass += b->gas_Z_mass; a->star_Z_mass += b->star_Z_mass; a->bh_Z_mass += b->bh_Z_mass; + a->bh_accretion_rate += b->bh_accretion_rate; + a->bh_accreted_mass += b->bh_accreted_mass; a->mom[0] += b->mom[0]; a->mom[1] += b->mom[1]; a->mom[2] += b->mom[2]; @@ -458,6 +461,10 @@ void stats_collect_bpart_mapper(void *map_data, int nr_bparts, if (gp != NULL && with_ext_grav) stats.E_pot_ext += m * external_gravity_get_potential_energy( time, potential, phys_const, gp); + + /* Collect accretion data. */ + stats.bh_accretion_rate += black_holes_get_accretion_rate(bp); + stats.bh_accreted_mass += black_holes_get_accreted_mass(bp); } /* Now write back to memory */ @@ -736,23 +743,41 @@ void stats_write_file_header(FILE *file, const struct unit_system *restrict us, "# (26) Comoving angular momentum of the simulation (z coordinate). \n"); fprintf(file, "# Unit = %e gram * cm**2 * s**-1\n", units_cgs_conversion_factor(us, UNIT_CONV_ANGULAR_MOMENTUM)); + fprintf(file, + "# (27) Sum of instantaneous accretion rate of all black holes in " + "the simulation. \n"); + fprintf(file, "# Unit = %e gram * s**-1\n", + units_cgs_conversion_factor(us, UNIT_CONV_MASS_PER_UNIT_TIME)); + fprintf(file, "# Unit = %e Msun/yr\n", + phys_const->const_year / phys_const->const_solar_mass); + fprintf(file, + "# (28) Total mass accreted by black holes in the simulation (not " + "including mass accreted by progenitors that have merged in the " + "current BHs). \n"); + fprintf(file, "# Unit = %e gram\n", us->UnitMass_in_cgs); + fprintf(file, "# Unit = %e Msun\n", 1. / phys_const->const_solar_mass); + fprintf(file, "#\n"); fprintf( file, - "#%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s " - "%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s\n", + "#%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s " + "%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s " + "%14s\n", "(0)", "(1)", "(2)", "(3)", "(4)", "(5)", "(6)", "(7)", "(8)", "(9)", "(10)", "(11)", "(12)", "(13)", "(14)", "(15)", "(16)", "(17)", "(18)", - "(19)", "(20)", "(21)", "(22)", "(23)", "(24)", "(25)", "(26)"); + "(19)", "(20)", "(21)", "(22)", "(23)", "(24)", "(25)", "(26)", "(27)", + "(28)"); fprintf( file, - "#%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s " - "%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s\n", + "#%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s " + "%14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s %14s " + "%14s\n", "Step", "Time", "a", "z", "Total mass", "Gas mass", "DM mass", "Sink mass", "Star mass", "BH mass", "Gas Z mass", "Star Z mass", "BH Z mass", "Kin. Energy", "Int. Energy", "Pot. energy", "Rad. energy", "Gas Entropy", "CoM x", "CoM y", "CoM z", "Mom. x", "Mom. y", "Mom. z", - "Ang. mom. x", "Ang. mom. y", "Ang. mom. z"); + "Ang. mom. x", "Ang. mom. y", "Ang. mom. z", "BH acc. rate", + "BH acc. mass"); fflush(file); } @@ -774,14 +799,15 @@ void stats_write_to_file(FILE *file, const struct statistics *stats, fprintf( file, " %14d %14e %14.7f %14.7f %14e %14e %14e %14e %14e %14e %14e %14e %14e " - "%14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e\n", + "%14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e %14e " + "%14e %14e\n", step, time, a, z, stats->total_mass, stats->gas_mass, stats->dm_mass, stats->sink_mass, stats->star_mass, stats->bh_mass, stats->gas_Z_mass, stats->star_Z_mass, stats->bh_Z_mass, stats->E_kin, stats->E_int, stats->E_pot, stats->E_rad, stats->entropy, stats->centre_of_mass[0], stats->centre_of_mass[1], stats->centre_of_mass[2], stats->mom[0], stats->mom[1], stats->mom[2], stats->ang_mom[0], stats->ang_mom[1], - stats->ang_mom[2]); + stats->ang_mom[2], stats->bh_accretion_rate, stats->bh_accreted_mass); fflush(file); } diff --git a/src/statistics.h b/src/statistics.h index 0305a9c5126f2d7952c9bd89924b0e1f87167ccf..3b314338e47b7e7d421b0798ab82f3bc5dd99fc0 100644 --- a/src/statistics.h +++ b/src/statistics.h @@ -86,6 +86,12 @@ struct statistics { /*! Total metal mass in BH (internal units)*/ double bh_Z_mass; + /*! Sum of instantaneous accretion rate of all BHs (internal units)*/ + double bh_accretion_rate; + + /*! Total accreted mass of all BHs (internal units)*/ + double bh_accreted_mass; + /*! Momentum (internal units)*/ double mom[3]; diff --git a/src/task.c b/src/task.c index 0e058f41e7cfb0d0edad7f749caeec6301e308ea..84333ade0d4bb42d786ad216952b28f5f1aef8ce 100644 --- a/src/task.c +++ b/src/task.c @@ -80,7 +80,6 @@ const char *taskID_names[task_type_count] = { "grav_mm", "grav_down_in", "grav_down", - "grav_mesh", "grav_end_force", "cooling", "cooling_in", @@ -109,6 +108,7 @@ const char *taskID_names[task_type_count] = { "rt_in", "rt_out", "sink_formation", + "rt_ghost1", }; /* Sub-task type names. */ @@ -309,7 +309,6 @@ __attribute__((always_inline)) INLINE static enum task_actions task_acts_on( case task_type_drift_gpart: case task_type_grav_down: case task_type_end_grav_force: - case task_type_grav_mesh: return task_action_gpart; break; @@ -602,12 +601,6 @@ void task_unlock(struct task *t) { #endif break; - case task_type_grav_mesh: -#ifdef SWIFT_TASKS_WITHOUT_ATOMICS - cell_gunlocktree(ci); -#endif - break; - case task_type_star_formation: cell_unlocktree(ci); cell_sunlocktree(ci); @@ -875,14 +868,6 @@ int task_lock(struct task *t) { #endif break; - case task_type_grav_mesh: -#ifdef SWIFT_TASKS_WITHOUT_ATOMICS - /* Lock the gparts */ - if (ci->grav.phold) return 0; - if (cell_glocktree(ci) != 0) return 0; -#endif - break; - case task_type_star_formation: /* Lock the gas, gravity and star particles */ if (ci->hydro.hold || ci->stars.hold || ci->grav.phold) return 0; @@ -945,8 +930,7 @@ void task_print(const struct task *t) { */ void task_get_group_name(int type, int subtype, char *cluster) { - if (type == task_type_grav_long_range || type == task_type_grav_mm || - type == task_type_grav_mesh) { + if (type == task_type_grav_long_range || type == task_type_grav_mm) { strcpy(cluster, "Gravity"); return; @@ -1000,6 +984,9 @@ void task_get_group_name(int type, int subtype, char *cluster) { case task_subtype_rt_inject: strcpy(cluster, "RTinject"); break; + case task_subtype_sink_compute_formation: + strcpy(cluster, "SinkFormation"); + break; default: strcpy(cluster, "None"); break; @@ -1484,7 +1471,6 @@ enum task_categories task_get_category(const struct task *t) { case task_type_grav_long_range: case task_type_grav_mm: case task_type_grav_down: - case task_type_grav_mesh: case task_type_end_grav_force: return task_category_gravity; diff --git a/src/task.h b/src/task.h index 865dfe862f1389da55f760365d59abe2d790fb5e..81ff0d5677a88b16a2a3248f4deb19c2a9cfd5cc 100644 --- a/src/task.h +++ b/src/task.h @@ -73,7 +73,6 @@ enum task_types { task_type_grav_mm, task_type_grav_down_in, /* Implicit */ task_type_grav_down, - task_type_grav_mesh, task_type_end_grav_force, task_type_cooling, task_type_cooling_in, /* Implicit */ @@ -102,6 +101,7 @@ enum task_types { task_type_rt_in, task_type_rt_out, task_type_sink_formation, + task_type_rt_ghost1, task_type_count } __attribute__((packed)); diff --git a/src/timers.c b/src/timers.c index f4b5bd7de2dcc7e78c436755337cb7fe59104bb2..28cdee752a269fde8d3c3942611f135829d5d6b4 100644 --- a/src/timers.c +++ b/src/timers.c @@ -128,6 +128,7 @@ const char* timers_names[timer_count] = { "dopair_rt_inject", "dosub_self_rt_inject", "dosub_pair_rt_inject", + "rt_ghost1", }; /* File to store the timers */ diff --git a/src/timers.h b/src/timers.h index 3ee8625bca26008de77e13c572011dabe7963cf5..f98e4e20dcefd88e56af159bb388e048583e53ad 100644 --- a/src/timers.h +++ b/src/timers.h @@ -129,6 +129,7 @@ enum { timer_dopair_rt_inject, timer_dosub_self_rt_inject, timer_dosub_pair_rt_inject, + timer_do_rt_ghost1, timer_count, }; diff --git a/src/timestep.h b/src/timestep.h index 2ac36f6c55362ab9c302538bf6c32ccd2f0da8ec..16fb935c00783995219e82df51f949eaf744c2fa 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -256,7 +256,6 @@ __attribute__((always_inline)) INLINE static integertime_t get_spart_timestep( __attribute__((always_inline)) INLINE static integertime_t get_bpart_timestep( const struct bpart *restrict bp, const struct engine *restrict e) { - /* Stellar time-step */ /* Black hole internal time-step */ float new_dt_black_holes = black_holes_compute_timestep( bp, e->black_holes_properties, e->physical_constants); diff --git a/src/timestep_limiter.h b/src/timestep_limiter.h index 8aa081ecc46adcd91f98f7f8165590050d421530..eee7b3e6596c90f936ae432f16470129497be045 100644 --- a/src/timestep_limiter.h +++ b/src/timestep_limiter.h @@ -108,6 +108,12 @@ __attribute__((always_inline)) INLINE static integertime_t timestep_limit_part( const integertime_t ti_beg_new = ti_beg_old + (k - 1) * dti_new; + /* End of the old half step */ + const integertime_t ti_end_half_old = ti_beg_old + dti_old / 2; + + /* End of the new half step */ + const integertime_t ti_end_half_new = ti_beg_new + dti_new / 2; + #ifdef SWIFT_DEBUG_CHECKS /* Some basic safety checks */ if (ti_beg_old >= e->ti_current) @@ -131,48 +137,41 @@ __attribute__((always_inline)) INLINE static integertime_t timestep_limit_part( double dt_kick_grav = 0., dt_kick_hydro = 0., dt_kick_therm = 0., dt_kick_corr = 0.; - /* Now we need to reverse the kick1... (the dt are negative here) */ - if (with_cosmology) { - dt_kick_hydro = -cosmology_get_hydro_kick_factor( - cosmo, ti_beg_old, ti_beg_old + dti_old / 2); - dt_kick_grav = -cosmology_get_grav_kick_factor(cosmo, ti_beg_old, - ti_beg_old + dti_old / 2); - dt_kick_therm = -cosmology_get_therm_kick_factor( - cosmo, ti_beg_old, ti_beg_old + dti_old / 2); - dt_kick_corr = -cosmology_get_corr_kick_factor(cosmo, ti_beg_old, - ti_beg_old + dti_old / 2); - } else { - dt_kick_hydro = -(dti_old / 2) * time_base; - dt_kick_grav = -(dti_old / 2) * time_base; - dt_kick_therm = -(dti_old / 2) * time_base; - dt_kick_corr = -(dti_old / 2) * time_base; - } - - kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, dt_kick_corr, - e->cosmology, e->hydro_properties, e->entropy_floor, - ti_beg_old + dti_old / 2, ti_beg_old); + /* Now we need to reverse the kick1... + * Note the minus sign! (the dt are negative here) */ + dt_kick_hydro = -kick_get_hydro_kick_dt(ti_beg_old, ti_end_half_old, + time_base, with_cosmology, cosmo); + dt_kick_grav = -kick_get_grav_kick_dt(ti_beg_old, ti_end_half_old, + time_base, with_cosmology, cosmo); + dt_kick_therm = -kick_get_therm_kick_dt(ti_beg_old, ti_end_half_old, + time_base, with_cosmology, cosmo); + dt_kick_corr = -kick_get_corr_kick_dt(ti_beg_old, ti_end_half_old, + time_base, with_cosmology, cosmo); + + /* Note that there is no need to change the mesh integration as we + * can't go back more than one global step */ + kick_part(p, xp, dt_kick_hydro, dt_kick_grav, /*dt_kick_mesh_grav=*/0., + dt_kick_therm, dt_kick_corr, e->cosmology, e->hydro_properties, + e->entropy_floor, ti_end_half_old, ti_beg_old, + /*ti_start_mesh=*/-1, /*ti_end_mesh=*/-1); /* ...and apply the new one (dt is positiive). * This brings us to the current time. */ - if (with_cosmology) { - dt_kick_hydro = cosmology_get_hydro_kick_factor(cosmo, ti_beg_new, - ti_beg_new + dti_new / 2); - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_beg_new, - ti_beg_new + dti_new / 2); - dt_kick_therm = cosmology_get_therm_kick_factor(cosmo, ti_beg_new, - ti_beg_new + dti_new / 2); - dt_kick_corr = cosmology_get_corr_kick_factor(cosmo, ti_beg_new, - ti_beg_new + dti_new / 2); - } else { - dt_kick_hydro = (ti_beg_new - ti_beg_old) * time_base; - dt_kick_grav = (ti_beg_new - ti_beg_old) * time_base; - dt_kick_therm = (ti_beg_new - ti_beg_old) * time_base; - dt_kick_corr = (ti_beg_new - ti_beg_old) * time_base; - } - - kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, dt_kick_corr, - e->cosmology, e->hydro_properties, e->entropy_floor, ti_beg_old, - ti_beg_new); + dt_kick_hydro = kick_get_hydro_kick_dt(ti_beg_old, ti_beg_new, time_base, + with_cosmology, cosmo); + dt_kick_grav = kick_get_grav_kick_dt(ti_beg_old, ti_beg_new, time_base, + with_cosmology, cosmo); + dt_kick_therm = kick_get_therm_kick_dt(ti_beg_old, ti_beg_new, time_base, + with_cosmology, cosmo); + dt_kick_corr = kick_get_corr_kick_dt(ti_beg_old, ti_beg_new, time_base, + with_cosmology, cosmo); + + /* Note that there is no need to change the mesh integration as we + * can't go back more than one global step */ + kick_part(p, xp, dt_kick_hydro, dt_kick_grav, /*dt_kick_mesh_grav=*/0., + dt_kick_therm, dt_kick_corr, e->cosmology, e->hydro_properties, + e->entropy_floor, ti_beg_old, ti_beg_new, /*ti_start_mesh=*/-1, + /*ti_end_mesh=*/-1); /* The particle has now been kicked to the current time */ @@ -188,25 +187,21 @@ __attribute__((always_inline)) INLINE static integertime_t timestep_limit_part( /* Apply the missing kick1 */ - if (with_cosmology) { - dt_kick_hydro = cosmology_get_hydro_kick_factor( - cosmo, ti_beg_new, ti_beg_new + dti_new / 2); - dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_beg_new, - ti_beg_new + dti_new / 2); - dt_kick_therm = cosmology_get_therm_kick_factor( - cosmo, ti_beg_new, ti_beg_new + dti_new / 2); - dt_kick_corr = cosmology_get_corr_kick_factor(cosmo, ti_beg_new, - ti_beg_new + dti_new / 2); - } else { - dt_kick_hydro = (dti_new / 2) * time_base; - dt_kick_grav = (dti_new / 2) * time_base; - dt_kick_therm = (dti_new / 2) * time_base; - dt_kick_corr = (dti_new / 2) * time_base; - } - - kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, dt_kick_corr, - e->cosmology, e->hydro_properties, e->entropy_floor, ti_beg_new, - ti_beg_new + dti_new / 2); + dt_kick_hydro = kick_get_hydro_kick_dt(ti_beg_new, ti_end_half_new, + time_base, with_cosmology, cosmo); + dt_kick_grav = kick_get_grav_kick_dt(ti_beg_new, ti_end_half_new, + time_base, with_cosmology, cosmo); + dt_kick_therm = kick_get_therm_kick_dt(ti_beg_new, ti_end_half_new, + time_base, with_cosmology, cosmo); + dt_kick_corr = kick_get_corr_kick_dt(ti_beg_new, ti_end_half_new, + time_base, with_cosmology, cosmo); + + /* Note that there is no need to change the mesh integration as we + * can't go back more than one global step */ + kick_part(p, xp, dt_kick_hydro, dt_kick_grav, /*dt_kick_mesh_grav=*/0., + dt_kick_therm, dt_kick_corr, e->cosmology, e->hydro_properties, + e->entropy_floor, ti_beg_new, ti_end_half_new, + /*ti_start_mesh=*/-1, /*ti_end_mesh=*/-1); /* Return the new end-of-step for this particle */ return ti_beg_new + dti_new; diff --git a/src/timestep_sync.h b/src/timestep_sync.h index f40aeb580c199eba85bdee04737def819a9f5106..658e7ecae3d20480a74032b2ba908e984a336de8 100644 --- a/src/timestep_sync.h +++ b/src/timestep_sync.h @@ -56,8 +56,6 @@ INLINE static void timestep_process_sync_part(struct part *p, struct xpart *xp, return; } - // message(" Synchronizing particle! %lld old bin=%d", p->id, p->time_bin); - /* We want to make the particle finish it's time-step now. */ /* Start by recovering the start and end point of the particle's time-step. */ @@ -68,13 +66,15 @@ INLINE static void timestep_process_sync_part(struct part *p, struct xpart *xp, /* Old time-step length on the time-line */ const integertime_t old_dti = old_ti_end - old_ti_beg; + const integertime_t ti_end_half_old = old_ti_beg + old_dti / 2; /* The actual time-step size this particle will use */ const integertime_t new_ti_beg = old_ti_beg; const integertime_t new_ti_end = ti_current; - const integertime_t new_dti = new_ti_end - new_ti_beg; #ifdef SWIFT_DEBUG_CHECKS + const integertime_t new_dti = new_ti_end - new_ti_beg; + /* Some basic safety checks */ if (old_ti_beg >= ti_current) error( @@ -96,47 +96,40 @@ INLINE static void timestep_process_sync_part(struct part *p, struct xpart *xp, double dt_kick_grav = 0., dt_kick_hydro = 0., dt_kick_therm = 0., dt_kick_corr = 0.; - /* Now we need to reverse the kick1... (the dt are negative here) */ - if (with_cosmology) { - dt_kick_hydro = -cosmology_get_hydro_kick_factor(cosmo, old_ti_beg, - old_ti_beg + old_dti / 2); - dt_kick_grav = -cosmology_get_grav_kick_factor(cosmo, old_ti_beg, - old_ti_beg + old_dti / 2); - dt_kick_therm = -cosmology_get_therm_kick_factor(cosmo, old_ti_beg, - old_ti_beg + old_dti / 2); - dt_kick_corr = -cosmology_get_corr_kick_factor(cosmo, old_ti_beg, - old_ti_beg + old_dti / 2); - } else { - dt_kick_hydro = -(old_dti / 2) * time_base; - dt_kick_grav = -(old_dti / 2) * time_base; - dt_kick_therm = -(old_dti / 2) * time_base; - dt_kick_corr = -(old_dti / 2) * time_base; - } - - kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, dt_kick_corr, - e->cosmology, e->hydro_properties, e->entropy_floor, - old_ti_beg + old_dti / 2, old_ti_beg); + /* Now we need to reverse the kick1... + * Note the minus sign! (the dt are negative here) */ + dt_kick_hydro = -kick_get_hydro_kick_dt(old_ti_beg, ti_end_half_old, + time_base, with_cosmology, cosmo); + dt_kick_grav = -kick_get_grav_kick_dt(old_ti_beg, ti_end_half_old, time_base, + with_cosmology, cosmo); + dt_kick_therm = -kick_get_therm_kick_dt(old_ti_beg, ti_end_half_old, + time_base, with_cosmology, cosmo); + dt_kick_corr = -kick_get_corr_kick_dt(old_ti_beg, ti_end_half_old, time_base, + with_cosmology, cosmo); + + /* Note that there is no need to change the mesh integration as we + * can't go back more than one global step */ + kick_part(p, xp, dt_kick_hydro, dt_kick_grav, /*dt_kick_mesh_grav=*/0., + dt_kick_therm, dt_kick_corr, e->cosmology, e->hydro_properties, + e->entropy_floor, ti_end_half_old, old_ti_beg, + /*ti_start_mesh=*/-1, /*ti_end_mesh=*/-1); /* We can now produce a kick to the current point */ - if (with_cosmology) { - dt_kick_hydro = cosmology_get_hydro_kick_factor(cosmo, new_ti_beg, - new_ti_beg + new_dti); - dt_kick_grav = - cosmology_get_grav_kick_factor(cosmo, old_ti_beg, new_ti_beg + new_dti); - dt_kick_therm = cosmology_get_therm_kick_factor(cosmo, old_ti_beg, - new_ti_beg + new_dti); - dt_kick_corr = - cosmology_get_corr_kick_factor(cosmo, old_ti_beg, new_ti_beg + new_dti); - } else { - dt_kick_hydro = (new_dti)*time_base; - dt_kick_grav = (new_dti)*time_base; - dt_kick_therm = (new_dti)*time_base; - dt_kick_corr = (new_dti)*time_base; - } - - kick_part(p, xp, dt_kick_hydro, dt_kick_grav, dt_kick_therm, dt_kick_corr, - e->cosmology, e->hydro_properties, e->entropy_floor, new_ti_beg, - new_ti_beg + new_dti); + dt_kick_hydro = kick_get_hydro_kick_dt(new_ti_beg, new_ti_end, time_base, + with_cosmology, cosmo); + dt_kick_grav = kick_get_grav_kick_dt(new_ti_beg, new_ti_end, time_base, + with_cosmology, cosmo); + dt_kick_therm = kick_get_therm_kick_dt(new_ti_beg, new_ti_end, time_base, + with_cosmology, cosmo); + dt_kick_corr = kick_get_corr_kick_dt(new_ti_beg, new_ti_end, time_base, + with_cosmology, cosmo); + + /* Note that there is no need to change the mesh integration as we + * can't go back more than one global step */ + kick_part(p, xp, dt_kick_hydro, dt_kick_grav, /*dt_kick_mesh_grav=*/0., + dt_kick_therm, dt_kick_corr, e->cosmology, e->hydro_properties, + e->entropy_floor, new_ti_beg, new_ti_end, + /*ti_start_mesh=*/-1, /*ti_end_mesh=*/-1); /* The particle is now ready to compute its new time-step size and for the * next kick */ diff --git a/src/velociraptor_interface.c b/src/velociraptor_interface.c index 7c453742c24660433571e3d16e9f420f24f8ba53..231349e0d7a10d8920926e876fc09337e8633d63 100644 --- a/src/velociraptor_interface.c +++ b/src/velociraptor_interface.c @@ -905,11 +905,11 @@ void velociraptor_invoke(struct engine *e, const int linked_with_snap) { if (s->periodic) { sim_info.cell_loc[i].loc[0] = - box_wrap(cells_top[i].loc[0] - s->pos_dithering[0], 0.0, s->dim[0]); + box_wrap(cells_top[i].loc[0], 0.0, s->dim[0]); sim_info.cell_loc[i].loc[1] = - box_wrap(cells_top[i].loc[1] - s->pos_dithering[1], 0.0, s->dim[1]); + box_wrap(cells_top[i].loc[1], 0.0, s->dim[1]); sim_info.cell_loc[i].loc[2] = - box_wrap(cells_top[i].loc[2] - s->pos_dithering[2], 0.0, s->dim[2]); + box_wrap(cells_top[i].loc[2], 0.0, s->dim[2]); } else { sim_info.cell_loc[i].loc[0] = cells_top[i].loc[0]; sim_info.cell_loc[i].loc[1] = cells_top[i].loc[1]; diff --git a/src/version.c b/src/version.c index 34f89e1f9d2dd74f53b8583c0de3cb3a6ce244cc..edb227bbf4a8bd3f8d5a50f53f08411b415e341e 100644 --- a/src/version.c +++ b/src/version.c @@ -44,6 +44,10 @@ #include <gsl/gsl_version.h> #endif +#ifdef HAVE_SUNDIALS +#include <sundials/sundials_version.h> +#endif + /* Some standard headers. */ #include <stdio.h> #include <stdlib.h> @@ -372,6 +376,22 @@ const char *libgsl_version(void) { return version; } +/** + * @brief return the SUNDIALS version used when SWIFT was built. + * + * @result description of the SUNDIALS version. + */ +const char *sundials_version(void) { + + static char version[256] = {0}; +#if defined(HAVE_SUNDIALS) + SUNDIALSGetVersion(version, 256); +#else + sprintf(version, "Unknown version"); +#endif + return version; +} + /** * @brief return the thread barrier used in SWIFT. * @@ -448,21 +468,24 @@ void greetings(int fof) { printf(" CFLAGS : %s\n", compilation_cflags()); printf("\n"); #ifdef HAVE_HDF5 - printf(" HDF5 library version: %s\n", hdf5_version()); + printf(" HDF5 library version : %s\n", hdf5_version()); #endif #ifdef HAVE_FFTW - printf(" FFTW library version: %s\n", fftw3_version()); + printf(" FFTW library version : %s\n", fftw3_version()); #endif #ifdef HAVE_LIBGSL - printf(" GSL library version: %s\n", libgsl_version()); + printf(" GSL library version : %s\n", libgsl_version()); +#endif +#ifdef HAVE_SUNDIALS + printf(" SUNDIALS library version : %s\n", sundials_version()); #endif #ifdef WITH_MPI - printf(" MPI library: %s\n", mpi_version()); + printf(" MPI library version : %s\n", mpi_version()); #ifdef HAVE_METIS - printf(" METIS library version: %s\n", metis_version()); + printf(" METIS library version : %s\n", metis_version()); #endif #ifdef HAVE_PARMETIS - printf(" ParMETIS library version: %s\n", parmetis_version()); + printf(" ParMETIS library version : %s\n", parmetis_version()); #endif #endif printf("\n"); diff --git a/tests/test125cells.c b/tests/test125cells.c index 7c7734abb3a74f76ab5a53510c33288fdf8c1c2a..98a47404da2f6ac0b57a9bbdc4b4c68f759ec0e6 100644 --- a/tests/test125cells.c +++ b/tests/test125cells.c @@ -109,11 +109,11 @@ void set_energy_state(struct part *part, enum pressure_field press, float size, part->entropy = pressure / pow_gamma(density); #elif defined(HOPKINS_PE_SPH) part->entropy = pressure / pow_gamma(density); -#elif defined(DEFAULT_SPH) +#elif defined(PHANTOM_SPH) part->u = pressure / (hydro_gamma_minus_one * density); #elif defined(MINIMAL_SPH) || defined(HOPKINS_PU_SPH) || \ defined(HOPKINS_PU_SPH_MONAGHAN) || defined(ANARCHY_PU_SPH) || \ - defined(SPHENIX_SPH) || defined(DEFAULT_SPH) + defined(SPHENIX_SPH) || defined(PHANTOM_SPH) part->u = pressure / (hydro_gamma_minus_one * density); #elif defined(PLANETARY_SPH) part->u = pressure / (hydro_gamma_minus_one * density); @@ -405,7 +405,7 @@ void dump_particle_fields(char *fileName, struct cell *main_cell, defined(GIZMO_MFV_SPH) || defined(SHADOWFAX_SPH) || \ defined(HOPKINS_PU_SPH) || defined(HOPKINS_PU_SPH_MONAGHAN) 0.f, -#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(DEFAULT_SPH) +#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(PHANTOM_SPH) main_cell->hydro.parts[pid].viscosity.div_v, #else main_cell->hydro.parts[pid].density.div_v, @@ -426,7 +426,7 @@ void dump_particle_fields(char *fileName, struct cell *main_cell, defined(HOPKINS_PU_SPH_MONAGHAN) main_cell->hydro.parts[pid].force.v_sig, 0.f, main_cell->hydro.parts[pid].u_dt -#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(DEFAULT_SPH) +#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(PHANTOM_SPH) main_cell->hydro.parts[pid].viscosity.v_sig, 0.f, main_cell->hydro.parts[pid].u_dt #else diff --git a/tests/test27cells.c b/tests/test27cells.c index 4e88ef6f8a366b616544e6d66ea7a522345ff505..baafbc67622daffe3a3e5e40889c57952cd96abc 100644 --- a/tests/test27cells.c +++ b/tests/test27cells.c @@ -288,7 +288,7 @@ void dump_particle_fields(char *fileName, struct cell *main_cell, main_cell->hydro.parts[pid].density.rot_v[0], main_cell->hydro.parts[pid].density.rot_v[1], main_cell->hydro.parts[pid].density.rot_v[2] -#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(DEFAULT_SPH) +#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(PHANTOM_SPH) /* this is required because of the variable AV scheme */ main_cell->hydro.parts[pid].viscosity.div_v, main_cell->hydro.parts[pid].density.rot_v[0], @@ -333,7 +333,7 @@ void dump_particle_fields(char *fileName, struct cell *main_cell, cj->hydro.parts[pjd].density.rot_v[0], cj->hydro.parts[pjd].density.rot_v[1], cj->hydro.parts[pjd].density.rot_v[2] -#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(DEFAULT_SPH) +#elif defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) || defined(PHANTOM_SPH) /* this is required because of the variable AV scheme */ cj->hydro.parts[pjd].viscosity.div_v, cj->hydro.parts[pjd].density.rot_v[0], diff --git a/tests/testActivePair.c b/tests/testActivePair.c index e52aa4ac6624f02d6854c63d9f2b0db0ce0b84f7..e856bc66358b7c0aab6ef27239e6cfded9f5678e 100644 --- a/tests/testActivePair.c +++ b/tests/testActivePair.c @@ -113,7 +113,7 @@ struct cell *make_cell(size_t n, double *offset, double size, double h, part->entropy = 1.f; #elif defined(MINIMAL_SPH) || defined(HOPKINS_PU_SPH) || \ defined(HOPKINS_PU_SPH_MONAGHAN) || defined(ANARCHY_PU_SPH) || \ - defined(SPHENIX_SPH) || defined(DEFAULT_SPH) + defined(SPHENIX_SPH) || defined(PHANTOM_SPH) part->u = 1.f; #elif defined(HOPKINS_PE_SPH) part->entropy = 1.f; @@ -197,11 +197,12 @@ void zero_particle_fields_force(struct cell *c, const struct cosmology *cosmo, p->density.rot_v[2] = 0.f; p->density.div_v = 0.f; #endif /* GADGET-2 */ -#if defined(MINIMAL_SPH) || defined(SPHENIX_SPH) || defined(DEFAULT_SPH) +#if defined(MINIMAL_SPH) || defined(SPHENIX_SPH) || defined(PHANTOM_SPH) p->rho = 1.f; p->density.rho_dh = 0.f; p->density.wcount = 48.f / (kernel_norm * pow_dimension(p->h)); p->density.wcount_dh = 0.f; + p->viscosity.v_sig = hydro_get_comoving_soundspeed(p); #endif /* MINIMAL */ #ifdef HOPKINS_PE_SPH p->rho = 1.f; diff --git a/tests/testInteractions.c b/tests/testInteractions.c index 0881d9d27f8990b5eb67ad5b3cbfb7023ebaf5e4..2e26dde3bf9a94be75526d53ea3bad3d50f38ea5 100644 --- a/tests/testInteractions.c +++ b/tests/testInteractions.c @@ -114,7 +114,7 @@ void prepare_force(struct part *parts, size_t count) { #if !defined(GIZMO_MFV_SPH) && !defined(SHADOWFAX_SPH) && \ !defined(MINIMAL_SPH) && !defined(PLANETARY_SPH) && \ !defined(HOPKINS_PU_SPH) && !defined(HOPKINS_PU_SPH_MONAGHAN) && \ - !defined(ANARCHY_PU_SPH) && !defined(SPHENIX_SPH) && !defined(DEFAULT_SPH) + !defined(ANARCHY_PU_SPH) && !defined(SPHENIX_SPH) && !defined(PHANTOM_SPH) struct part *p; for (size_t i = 0; i < count; ++i) { p = &parts[i]; @@ -142,7 +142,7 @@ void dump_indv_particle_fields(char *fileName, struct part *p) { p->id, p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], p->h, hydro_get_comoving_density(p), #if defined(MINIMAL_SPH) || defined(PLANETARY_SPH) || \ - defined(SHADOWFAX_SPH) || defined(DEFAULT_SPH) + defined(SHADOWFAX_SPH) || defined(PHANTOM_SPH) 0.f, #else p->density.div_v, @@ -153,11 +153,11 @@ void dump_indv_particle_fields(char *fileName, struct part *p) { p->a_hydro[0], p->a_hydro[1], p->a_hydro[2], p->force.h_dt, #if defined(GADGET2_SPH) p->force.v_sig, p->entropy_dt, 0.f -#elif defined(DEFAULT_SPH) +#elif defined(PHANTOM_SPH) p->force.v_sig, 0.f, p->force.u_dt #elif defined(MINIMAL_SPH) || defined(HOPKINS_PU_SPH) || \ defined(HOPKINS_PU_SPH_MONAGHAN) || defined(ANARCHY_PU_SPH) || \ - defined(SPHENIX_SPH) || defined(DEFAULT_SPH) + defined(SPHENIX_SPH) || defined(PHANTOM_SPH) p->force.v_sig, 0.f, p->u_dt #else 0.f, 0.f, 0.f diff --git a/tests/testPeriodicBC.c b/tests/testPeriodicBC.c index cb7fd805c99f47381791df8f1f6057547751e490..13dd14cc191bbf621a15edbfbc02edafba103199 100644 --- a/tests/testPeriodicBC.c +++ b/tests/testPeriodicBC.c @@ -251,7 +251,7 @@ void dump_particle_fields(char *fileName, struct cell *main_cell, int i, int j, main_cell->hydro.parts[pid].density.rot_v[0], main_cell->hydro.parts[pid].density.rot_v[1], main_cell->hydro.parts[pid].density.rot_v[2] -#elif defined(DEFAULT_SPH) || defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) +#elif defined(PHANTOM_SPH) || defined(ANARCHY_PU_SPH) || defined(SPHENIX_SPH) main_cell->hydro.parts[pid].viscosity.div_v, main_cell->hydro.parts[pid].density.rot_v[0], main_cell->hydro.parts[pid].density.rot_v[1], diff --git a/tools/analyse_runtime.py b/tools/analyse_runtime.py index bc2addeece6947a9da4ef318db1964c32d285441..fa98511aa787bd0bf4408f5bdfa7dc04be68e9ed 100755 --- a/tools/analyse_runtime.py +++ b/tools/analyse_runtime.py @@ -55,11 +55,12 @@ num_files = len(sys.argv) - 1 labels = [ ["engine_split_gas_particles:", 1], - ["Gpart assignment", 1], - ["Mesh communication", 1], - ["Forward Fourier transform", 1], - ["Green function", 1], - ["Backwards Fourier transform", 1], + ["Gpart assignment", 4], + ["Mesh communication", 4], + ["Forward Fourier transform", 4], + ["Green function", 4], + ["Backwards Fourier transform", 4], + ["Gpart mesh forces", 4], ["engine_recompute_displacement_constraint:", 1], ["engine_exchange_top_multipoles:", 1], ["updating particle counts", 1], @@ -264,6 +265,7 @@ important_ratios = [0.0] important_is_rebuild = [0] important_is_fof = [0] important_is_VR = [0] +important_is_mesh = [0] important_labels = ["Others (all below %.1f\%%)" % (threshold * 100)] need_print = True print("Time spent in the different code sections:") @@ -274,6 +276,7 @@ for i in range(len(labels)): important_is_rebuild.append(labels[i][1] == 1) important_is_fof.append(labels[i][1] == 2) important_is_VR.append(labels[i][1] == 3) + important_is_mesh.append(labels[i][1] == 4) important_labels.append(labels[i][0]) else: if need_print: @@ -329,12 +332,17 @@ code_pie, _, _ = pie( # Use hashing for the FOF and VR wedges for i in range(len(code_pie)): if important_is_fof[i]: - code_pie[i].set_hatch("o") + code_pie[i].set_hatch("+") code_pie[i].set_edgecolor(code_pie[i].get_facecolor()) code_pie[i].set_fill(False) for i in range(len(code_pie)): if important_is_VR[i]: - code_pie[i].set_hatch("+") + code_pie[i].set_hatch("*") + code_pie[i].set_edgecolor(code_pie[i].get_facecolor()) + code_pie[i].set_fill(False) +for i in range(len(code_pie)): + if important_is_mesh[i]: + code_pie[i].set_hatch(".") code_pie[i].set_edgecolor(code_pie[i].get_facecolor()) code_pie[i].set_fill(False) diff --git a/tools/combine_ics.py b/tools/combine_ics.py index d864c67d7d44fb6550e3cd858c50bb660d6126ca..ca96cf805978fa1ed36c021551d68f28c5f76c60 100755 --- a/tools/combine_ics.py +++ b/tools/combine_ics.py @@ -63,6 +63,10 @@ tot_num_parts = tot_num_parts.astype(np.int64) for i in range(6): tot_num_parts[i] += (np.int64(tot_num_parts_high_word[i]) << 32) +tot_num_parts_swift = np.copy(tot_num_parts) +tot_num_parts_swift[2] += tot_num_parts_swift[3] +tot_num_parts_swift[3] = 0 + # Some basic information print("Reading", tot_num_parts, "particles from", num_files, "files.") @@ -85,9 +89,9 @@ output_file = h5.File(output_file_name, "w-") # Header grp = output_file.create_group("/Header") grp.attrs["NumFilesPerSnapshot"] = 1 -grp.attrs["NumPart_Total"] = tot_num_parts +grp.attrs["NumPart_Total"] = tot_num_parts_swift grp.attrs["NumPart_Total_HighWord"] = [0, 0, 0, 0, 0, 0] -grp.attrs["NumPart_ThisFile"] = tot_num_parts +grp.attrs["NumPart_ThisFile"] = tot_num_parts_swift grp.attrs["MassTable"] = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] grp.attrs["BoxSize"] = box_size grp.attrs["Flag_Entropy_ICs"] = entropy_flag @@ -98,6 +102,8 @@ if tot_num_parts[0] > 0: grp0 = output_file.create_group("/PartType0") if tot_num_parts[1] > 0: grp1 = output_file.create_group("/PartType1") +if tot_num_parts_swift[2] > 0: + grp2 = output_file.create_group("/PartType2") if tot_num_parts[4] > 0: grp4 = output_file.create_group("/PartType4") if tot_num_parts[5] > 0: @@ -147,6 +153,12 @@ if tot_num_parts[1] > 0: create_set(grp1, "Masses", tot_num_parts[1], 1, "f") create_set(grp1, "ParticleIDs", tot_num_parts[1], 1, "l") +if tot_num_parts_swift[2] > 0: + create_set(grp2, "Coordinates", tot_num_parts_swift[2], 3, "d") + create_set(grp2, "Velocities", tot_num_parts_swift[2], 3, "f") + create_set(grp2, "Masses", tot_num_parts_swift[2], 1, "f") + create_set(grp2, "ParticleIDs", tot_num_parts_swift[2], 1, "l") + if tot_num_parts[4] > 0: create_set(grp4, "Coordinates", tot_num_parts[4], 3, "d") create_set(grp4, "Velocities", tot_num_parts[4], 3, "f") @@ -188,6 +200,8 @@ for f in range(num_files): ": num_parts = [", num_parts[0], num_parts[1], + num_parts[2], + num_parts[3], num_parts[4], num_parts[5], "]", @@ -205,6 +219,14 @@ for f in range(num_files): def copy_grp_same_name(name, ptype): copy_grp(name, name, ptype) + def copy_grp_pt3(name): + full_name_new = "/PartType2/" + name + full_name_old = "/PartType3/" + name + output_file[full_name_new][ + cumul_parts[2] : cumul_parts[2] + num_parts[3] + ] = file[full_name_old] + + if num_parts[0] > 0: copy_grp_same_name("Coordinates", 0) copy_grp_same_name("Velocities", 0) @@ -220,6 +242,21 @@ for f in range(num_files): if DM_mass == 0.0: # Do not overwrite values if there was a mass table copy_grp_same_name("Masses", 1) + if num_parts[2] > 0: + copy_grp_same_name("Coordinates", 2) + copy_grp_same_name("Velocities", 2) + copy_grp_same_name("ParticleIDs", 2) + copy_grp_same_name("Masses", 2) + + # Need to update part counter for pt2 already here, so we append 3 in correct place + cumul_parts[2] += num_parts[2] + + if num_parts[3] > 0: + copy_grp_pt3("Coordinates") + copy_grp_pt3("Velocities") + copy_grp_pt3("ParticleIDs") + copy_grp_pt3("Masses") + if num_parts[4] > 0: copy_grp_same_name("Coordinates", 4) copy_grp_same_name("Velocities", 4) @@ -234,6 +271,7 @@ for f in range(num_files): cumul_parts[0] += num_parts[0] cumul_parts[1] += num_parts[1] + cumul_parts[2] += num_parts[3] # Need to adjust for added pt-3 cumul_parts[4] += num_parts[4] cumul_parts[5] += num_parts[5] file.close() diff --git a/tools/plot_task_dependencies.py b/tools/plot_task_dependencies.py index ad30b61e497e04ae94cf7e35278911e527a760f2..0d8b14c46c20110476a81176c5a03efcb20491ad 100755 --- a/tools/plot_task_dependencies.py +++ b/tools/plot_task_dependencies.py @@ -139,8 +139,7 @@ def append_single_data(data0, datai): # check number of ta->tb N = np.sum(ind) if N > 1: - raise Exception( - "Same dependency written multiple times %s->%s" % (ta, tb)) + raise Exception("Same dependency written multiple times %s->%s" % (ta, tb)) # if not present in data0 if N == 0: data0.append(row) @@ -282,6 +281,8 @@ def task_is_hydro(name): "ghost_out", "extra_ghost", "cooling", + "cooling_in", + "cooling_out", "star_formation", ] if name in task_name: @@ -470,8 +471,9 @@ def write_header(f, data, git, opt): f.write('\t label="Task dependencies for SWIFT %s";\n' % git) f.write("\t compound=true;\n") f.write("\t ratio=0.66;\n") - f.write("\t node[nodesep=0.15, fontsize=30, penwidth=5.];\n") - f.write("\t ranksep=1.2;\n") + f.write("\t node[nodesep=0.15, fontsize=18, penwidth=3.];\n") + f.write("\t edge[fontsize=12, penwidth=0.5];\n") + f.write("\t ranksep=0.8;\n") f.write("\n") # write the special task @@ -485,8 +487,7 @@ def write_header(f, data, git, opt): continue written.append(ta) - write_task(f, ta, data["implicit_in"][i], - data["mpi_in"][i], opt.with_calls) + write_task(f, ta, data["implicit_in"][i], data["mpi_in"][i], opt.with_calls) # do task out for i in range(N): @@ -495,8 +496,7 @@ def write_header(f, data, git, opt): continue written.append(tb) - write_task(f, tb, data["implicit_out"][i], - data["mpi_out"][i], opt.with_calls) + write_task(f, tb, data["implicit_out"][i], data["mpi_out"][i], opt.with_calls) f.write("\n") diff --git a/tools/task_plots/analyse_tasks.py b/tools/task_plots/analyse_tasks.py index 2de77352bbfb3a4b63e09b5dea0a4a1c7cabe60f..a17306d8ebee5ae3ed9c821421d52d96b41ac7d5 100755 --- a/tools/task_plots/analyse_tasks.py +++ b/tools/task_plots/analyse_tasks.py @@ -101,7 +101,6 @@ TASKTYPES = [ "grav_mm", "grav_down_in", "grav_down", - "grav_mesh", "grav_end_force", "cooling", "cooling_in", @@ -127,6 +126,8 @@ TASKTYPES = [ "fof_pair", "rt_in", "rt_out", + "sink_formation", + "rt_ghost1", "count", ] @@ -163,6 +164,7 @@ SUBTYPES = [ "bh_feedback", "sink", "rt_inject", + "sink_compute_formation", "count", ] diff --git a/tools/task_plots/iplot_tasks.py b/tools/task_plots/iplot_tasks.py index 2fd8e2e4000de866d992170ff60ab8a915541501..8879fa1da8ca2ceaf2bbb962ca48b34de1e74f44 100755 --- a/tools/task_plots/iplot_tasks.py +++ b/tools/task_plots/iplot_tasks.py @@ -155,7 +155,6 @@ TASKTYPES = [ "grav_mm", "grav_down_in", "grav_down", - "grav_mesh", "grav_end_force", "cooling", "cooling_in", @@ -181,6 +180,8 @@ TASKTYPES = [ "fof_pair", "rt_in", "rt_out", + "sink_formation", + "rt_ghost1", "count", ] @@ -216,6 +217,7 @@ SUBTYPES = [ "bh_feedback", "sink", "rt_inject", + "sink_compute_formation", "count", ] diff --git a/tools/task_plots/plot_tasks.py b/tools/task_plots/plot_tasks.py index 054dfe6b4f63c0fbaab32dec9f44334eb2aab300..d2473e41c604031763145d6534135639218af8e5 100755 --- a/tools/task_plots/plot_tasks.py +++ b/tools/task_plots/plot_tasks.py @@ -178,7 +178,6 @@ TASKTYPES = [ "grav_mm", "grav_down_in", "grav_down", - "grav_mesh", "grav_end_force", "cooling", "cooling_in", @@ -204,6 +203,8 @@ TASKTYPES = [ "fof_pair", "rt_in", "rt_out", + "sink_formation", + "rt_ghost1", "count", ] @@ -240,6 +241,7 @@ SUBTYPES = [ "bh_feedback", "sink", "rt_inject", + "sink_compute_formation", "count", ]