diff --git a/doc/RTD/source/AnalysisTools/index.rst b/doc/RTD/source/AnalysisTools/index.rst index 52783719b593ce08ea20a8a2c32ec140750da2ba..4b86b1689b7c7c1f18df2cc73c6964d6a56ff4b3 100644 --- a/doc/RTD/source/AnalysisTools/index.rst +++ b/doc/RTD/source/AnalysisTools/index.rst @@ -12,7 +12,7 @@ Task dependencies At the beginning of each simulation the file ``dependency_graph.csv`` is generated and can be transformed into a ``dot`` and a ``png`` file with the script ``tools/plot_task_dependencies.py``. It requires the ``dot`` package that is available in the library graphviz. -This script has also the possibility to generate a list of function calls for each task with the option ``--with-calls`` (this list may be incomplete). +This script has also the possibility to generate a list of function calls for each task with the option ``--with-calls`` (this list may be incomplete) and to describe at which level each task are run ``--with-levels`` (a larger simulation will provide more accurate levels). You can convert the ``dot`` file into a ``png`` with the following command ``dot -Tpng dependency_graph.dot -o dependency_graph.png`` or directly read it with the python module ``xdot`` with ``python -m xdot dependency_graph.dot``. diff --git a/doc/RTD/source/Task/adding_to_dependency_plotting_tool.rst b/doc/RTD/source/Task/adding_to_dependency_plotting_tool.rst index 0b1e6fbe3fb554a6a505eb08832bf64ea88d0ee9..fa2915a0d40ae7679f3a5bb837878aca7bd4fd60 100644 --- a/doc/RTD/source/Task/adding_to_dependency_plotting_tool.rst +++ b/doc/RTD/source/Task/adding_to_dependency_plotting_tool.rst @@ -21,14 +21,19 @@ need to modify the ``tools/plot_task_dependencies.py`` script. Colouring in the Task Nodes --------------------------- -First, the script needs to identify the task types with which it is working. +First, decide on a colour. If you want to use the same colour as already existing +task types, find its key in the ``task_colours`` dict, which is defined at the +top of the file. If you want to add a new colour, add it to the ``task_colours`` +dict with a new key. + +Then the script needs to identify the task types with which it is working. To do so, it will check the task names, which are generated following the scheme ``taskname_subtaskname``, where ``taskname`` is defined in ``taskID_names`` and ``subtasknbame`` is defined in ``subtaskID_names`` in ``task.c``. In ``tools/plot_task_dependencies.py``, you'll have to write a function that recognizes your task by its name, like is done for example for gravity:: - def taskIsGravity(name): + def task_is_gravity(name): """ Does the task concern the gravity? @@ -44,10 +49,10 @@ task by its name, like is done for example for gravity:: return True return False -and add the check to the function ``writeTask()``:: +You'll need to add the check to the function ``get_task_colour()``:: if taskIsGravity(name): - txt += "color=red3," + colour = task_colours["gravity"] Feel free to pick out a `nice color <http://graphviz.org/doc/info/colors.html>`_ for it :) diff --git a/doc/RTD/source/Task/adding_your_own.rst b/doc/RTD/source/Task/adding_your_own.rst index 6d815b99655ae498314bdc7963f9fdf1be908931..4d4025916f12a7ca7d163df2d24407cd2ccf6e95 100644 --- a/doc/RTD/source/Task/adding_your_own.rst +++ b/doc/RTD/source/Task/adding_your_own.rst @@ -67,12 +67,12 @@ Adding it to the Cells Each cell contains a list to its tasks and therefore you need to provide a link for it. -In ``cell.h``, add a pointer to a task in the structure. -In order to stay clean, please put the new task in the same group than the other -tasks. +In ``cell_<particle_type>.h``, add a pointer to a task in the structure. For +example, cooling couples to the hydro particles, so we'll be adding our task +to ``cell_hydro.h``. For example:: - struct cell { + struct cell_hydro { /* Lot of stuff before. */ /*! Task for the cooling */ @@ -245,7 +245,7 @@ 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``. +``space_rebuild_recycle_mapper`` in ``space_recycle.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 18e0687066f4a79643dba1900f9a65e0d2251182..1fb120bf8aa800db79bc38b99f9788815859246c 100644 --- a/doc/RTD/source/Task/adding_your_own_neighbour_loop.rst +++ b/doc/RTD/source/Task/adding_your_own_neighbour_loop.rst @@ -67,39 +67,37 @@ Adding it to the Cells Each cell contains a list to its tasks and therefore you need to provide a link for it. -In ``cell.h``, add a pointer to a task in the ``struct cell``. In order to stay clean, -please put the new task in the same group (e.g. ``struct hydro{...}`` inside ``struct cell``) -than the other tasks. +In ``cell_<particle_type>.h``, add a pointer to a task in the structure. For +example, cooling couples to the hydro particles, so we'll be adding our task +to ``cell_hydro.h``. + We won't be adding just one task though, but an entire (linked) list of them, since we're going to need a ``self`` type task and multiple ``pair`` type tasks to have a complete neighbour loop. So instead of pointing to a single task, we store a struct ``link`` in the cell struct. For example:: - struct cell { - /* Lot of stuff before. */ - - /*! Hydro variables */ - struct { - /*! Pointer to the #part data. */ - struct part *parts; - - /*! Pointer to the #xpart data. */ - struct xpart *xparts; + /** + * @brief Hydro-related cell variables. + */ + struct cell_hydro { - /* Lot of stuff */ + /*! Pointer to the #part data. */ + struct part *parts; - /*! Task for sorting the stars again after a SF event */ - struct task *stars_resort; + /*! Pointer to the #xpart data. */ + struct xpart *xparts; - /*! My new interaction task */ - struct link *new_iact; + /* Lot of stuff */ - /* Lot of stuff after */ + /*! Task for sorting the stars again after a SF event */ + struct task *stars_resort; - } hydro; + /*! My new interaction task */ + struct link *new_iact; /* Lot of stuff after */ - } + + }; Adding a new Timer @@ -333,7 +331,7 @@ the number of tasks that you will be adding, e.g. 1 self + (3^3-1)/2 = 13 pair tasks + 1 ghost, etc... All these numbers can be overwritten at run time by the user anyway in the parameter file (``Scheduler: tasks_per_cell``). -and give the task an estimate of the computational cost that it will have in +Then give the task an estimate of the computational cost that it will have in ``scheduler_reweight`` in ``scheduler.c``:: case task_type_self: @@ -354,7 +352,8 @@ 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``. +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 @@ -364,8 +363,8 @@ you need to add the unskipping manually to ``engine_do_unskip_mapper()`` in Finally, you also need to initialize your new variables and pointers in -``space_rebuild_recycle_mapper`` in ``space.c``. Additionally, you need to -initialize the ``link`` structs in ``cell_clean_links`` in ``cell.c``. +``space_rebuild_recycle_mapper`` in ``space_recycle.c``. Additionally, you need +to initialize the ``link`` structs in ``cell_clean_links`` in ``cell.c``. diff --git a/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml b/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml index 094f76f5d2045d8a5d7c9d26f74fc64bf8092480..7af692c8cd2f6ffdc84d301ebbd3975f57fdcd79 100644 --- a/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml +++ b/examples/EAGLE_ICs/EAGLE_100/eagle_100.yml @@ -139,20 +139,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -177,6 +178,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. @@ -208,41 +210,43 @@ EAGLEFeedback: # EAGLE AGN model EAGLEAGN: - subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. - multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? - subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? - with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? - viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term - with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? - boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. - boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. - boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). - radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. - use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? - 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. - max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. - eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. - coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. - 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_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? - 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_threshold 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_threshold is 1. - set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? - 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). - merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. + subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. + use_multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + use_subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? + viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term + with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? + boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. + boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. + boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). + radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. + use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? + 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. + max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. + eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. + coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 1 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? + 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_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). + 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? + 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_threshold 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_threshold is 1. + set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? + 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). + merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. diff --git a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml index fdb3ed3d4b4dc6815124353bf538b9625700687b..6f262128a62416caae171ace110aa1dd5757094b 100644 --- a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml @@ -138,20 +138,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -176,6 +177,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. @@ -207,41 +209,43 @@ EAGLEFeedback: # EAGLE AGN model EAGLEAGN: - subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. - multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? - subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? - with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? - viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term - with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? - boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. - boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. - boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). - radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. - use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? - 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. - max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. - eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. - coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. - 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_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? - 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_threshold 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_threshold is 1. - set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? - 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). - merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. + subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. + use_multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + use_subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? + viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term + with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? + boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. + boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. + boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). + radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. + use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? + 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. + max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. + eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. + coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 1 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? + 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_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). + 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? + 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_threshold 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_threshold is 1. + set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? + 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). + merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. diff --git a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml index eaae1ef4f871c159e35e80a23f8e79ffa32990dc..2f03249cfd99876ba64270f313ec803586f9eb86 100644 --- a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml @@ -138,20 +138,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -176,6 +177,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. @@ -207,41 +209,43 @@ EAGLEFeedback: # EAGLE AGN model EAGLEAGN: - subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. - multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? - subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? - with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? - viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term - with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? - boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. - boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. - boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). - radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. - use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? - 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. - max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. - eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. - coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. - 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_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? - 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_threshold 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_threshold is 1. - set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? - 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). - merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. + subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. + use_multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + use_subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? + viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term + with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? + boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. + boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. + boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). + radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. + use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? + 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. + max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. + eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. + coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 1 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? + 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_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). + 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? + 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_threshold 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_threshold is 1. + set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? + 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). + merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. diff --git a/examples/EAGLE_ICs/EAGLE_25_low_res/README b/examples/EAGLE_ICs/EAGLE_25_low_res/README new file mode 100644 index 0000000000000000000000000000000000000000..38e99d1fe74f30912633c7f609f20cbadcf8bee6 --- /dev/null +++ b/examples/EAGLE_ICs/EAGLE_25_low_res/README @@ -0,0 +1,8 @@ +Initial conditions corresponding to the 25 Mpc volume +of the EAGLE suite at 8x lower resolution. +The ICs only contain DM particles. The gas particles will be generated in SWIFT. + +This resolution corresponds to: EAGLE low res. (m_B = 1.45e7 Msol) + +MD5 hash: +62e7ec93a1b0b4c57ff0c63ad0da2028 EAGLE_L0025N0188_ICs.hdf5 diff --git a/examples/EAGLE_ICs/EAGLE_25_low_res/eagle_25.yml b/examples/EAGLE_ICs/EAGLE_25_low_res/eagle_25.yml new file mode 100644 index 0000000000000000000000000000000000000000..e37450795a9847fbb1a89d0ae92220372873094a --- /dev/null +++ b/examples/EAGLE_ICs/EAGLE_25_low_res/eagle_25.yml @@ -0,0 +1,244 @@ +# Define some meta-data about the simulation +MetaData: + run_name: EAGLE-L0025N0188-Ref + +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98841e43 # 10^10 M_sun in grams + UnitLength_in_cgs: 3.08567758e24 # Mpc in centimeters + UnitVelocity_in_cgs: 1e5 # km/s in centimeters per second + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Cosmological parameters +Cosmology: + h: 0.6777 # Reduced Hubble constant + a_begin: 0.0078125 # Initial scale-factor of the simulation + a_end: 1.0 # Final scale factor of the simulation + Omega_m: 0.307 # Matter density parameter + Omega_lambda: 0.693 # Dark-energy density parameter + Omega_b: 0.0482519 # Baryon density parameter + +# Parameters governing the time integration +TimeIntegration: + dt_min: 1e-10 # The minimal time-step size of the simulation (in internal units). + dt_max: 1e-2 # The maximal time-step size of the simulation (in internal units). + +# Parameters governing the snapshots +Snapshots: + basename: eagle # Common part of the name of output files + output_list_on: 1 + output_list: ./output_list.txt + +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1.01 + scale_factor_first: 0.01 + +# Parameters for the self-gravity scheme +Gravity: + eta: 0.025 # Constant dimensionless multiplier for time integration. + MAC: geometric # Use the geometric opening angle condition + theta_cr: 0.7 # Opening angle (Multipole acceptance criterion) + use_tree_below_softening: 0 + mesh_side_length: 128 + comoving_DM_softening: 0.006640 # Comoving softening for DM (6.67 ckpc) + max_physical_DM_softening: 0.002600 # Physical softening for DM (2.60 pkpc) + comoving_baryon_softening: 0.003580 # Comoving softening for baryons (3.58 ckpc) + max_physical_baryon_softening: 0.001400 # Physical softening for baryons (1.40 pkpc) + +# Parameters for the hydrodynamics scheme +SPH: + resolution_eta: 1.2348 # Target smoothing length in units of the mean inter-particle separation (1.2348 == 48Ngbs with the cubic spline kernel). + h_min_ratio: 0.1 # Minimal smoothing length in units of softening. + h_max: 0.5 # Maximal smoothing length in co-moving internal units. + CFL_condition: 0.2 # Courant-Friedrich-Levy condition for time integration. + minimal_temperature: 100.0 # (internal units) + initial_temperature: 268.7 # (internal units) + particle_splitting: 1 # Particle splitting is ON + particle_splitting_mass_threshold: 5.6e-3 # (internal units, i.e. 5.6e7 Msun ~ 4x initial gas particle mass) + +# Parameters of the stars neighbour search +Stars: + resolution_eta: 1.1642 # Target smoothing length in units of the mean inter-particle separation + h_tolerance: 7e-3 + +# Parameters for the Friends-Of-Friends algorithm +FOF: + basename: fof_output # Filename for the FOF outputs. + min_group_size: 32 # The minimum no. of particles required for a group. + linking_length_ratio: 0.2 # Linking length in units of the main inter-particle separation. + black_hole_seed_halo_mass_Msun: 1.0e10 # Minimal halo mass in which to seed a black hole (in solar masses). + scale_factor_first: 0.05 # Scale-factor of first FoF black hole seeding calls. + delta_time: 1.00751 # Scale-factor ratio between consecutive FoF black hole seeding calls. + +Scheduler: + max_top_level_cells: 16 + cell_split_size: 200 + +Restarts: + onexit: 1 + delta_hours: 6.0 + +# Parameters related to the initial conditions +InitialConditions: + file_name: EAGLE_L0025N0188_ICs.hdf5 + periodic: 1 + cleanup_h_factors: 1 # Remove the h-factors inherited from Gadget + cleanup_velocity_factors: 1 # Remove the sqrt(a) factor in the velocities inherited from Gadget + generate_gas_in_ics: 1 # Generate gas particles from the DM-only ICs + cleanup_smoothing_lengths: 1 # Since we generate gas, make use of the (expensive) cleaning-up procedure. + remap_ids: 1 # Re-map the IDs to [1, N] to avoid collision problems when splitting + +# Parameters of the line-of-sight outputs +LineOfSight: + basename: eagle_los + num_along_x: 0 + num_along_y: 0 + num_along_z: 100 + scale_factor_first: 0.1 + delta_time: 1.1 + +# Impose primoridal metallicity +EAGLEChemistry: + init_abundance_metal: 0. + init_abundance_Hydrogen: 0.752 + init_abundance_Helium: 0.248 + init_abundance_Carbon: 0.0 + init_abundance_Nitrogen: 0.0 + init_abundance_Oxygen: 0.0 + init_abundance_Neon: 0.0 + init_abundance_Magnesium: 0.0 + init_abundance_Silicon: 0.0 + init_abundance_Iron: 0.0 + +# EAGLE cooling parameters +EAGLECooling: + dir_name: ./coolingtables/ + H_reion_z: 7.5 # Planck 2018 + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 + He_reion_z_sigma: 0.5 + He_reion_eV_p_H: 2.0 + +# COLIBRE cooling parameters +COLIBRECooling: + dir_name: ./UV_dust1_CR1_G1_shield1.hdf5 # Location of the cooling tables + H_reion_z: 7.5 # Redshift of Hydrogen re-ionization (Planck 2018) + H_reion_eV_p_H: 2.0 + He_reion_z_centre: 3.5 # Redshift of the centre of the Helium re-ionization Gaussian + He_reion_z_sigma: 0.5 # Spread in redshift of the Helium re-ionization Gaussian + He_reion_eV_p_H: 2.0 # Energy inject by Helium re-ionization in electron-volt per Hydrogen atom + delta_logTEOS_subgrid_properties: 0.3 # delta log T above the EOS below which the subgrid properties use Teq assumption + rapid_cooling_threshold: 0.333333 # Switch to rapid cooling regime for dt / t_cool above this threshold. + +# EAGLE star formation parameters +EAGLEStarFormation: + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. + +# Parameters for the EAGLE "equation of state" +EAGLEEntropyFloor: + Jeans_density_threshold_H_p_cm3: 1e-4 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Jeans_over_density_threshold: 10. # Overdensity above which the EAGLE Jeans limiter entropy floor can kick in. + Jeans_temperature_norm_K: 800 # Temperature of the EAGLE Jeans limiter entropy floor at the density threshold expressed in Kelvin. + Jeans_gamma_effective: 1.3333333 # Slope the of the EAGLE Jeans limiter entropy floor + Cool_density_threshold_H_p_cm3: 1e-5 # Physical density above which the EAGLE Cool limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. + Cool_over_density_threshold: 10. # Overdensity above which the EAGLE Cool limiter entropy floor can kick in. + Cool_temperature_norm_K: 10. # Temperature of the EAGLE Cool limiter entropy floor at the density threshold expressed in Kelvin. (NOTE: This is below the min T and hence this floor does nothing) + Cool_gamma_effective: 1. # Slope the of the EAGLE Cool limiter entropy floor + +# EAGLE feedback model +EAGLEFeedback: + use_SNII_feedback: 1 # Global switch for SNII thermal (stochastic) feedback. + use_SNIa_feedback: 1 # Global switch for SNIa thermal (continuous) feedback. + use_AGB_enrichment: 1 # Global switch for enrichement from AGB stars. + use_SNII_enrichment: 1 # Global switch for enrichement from SNII stars. + use_SNIa_enrichment: 1 # Global switch for enrichement from SNIa stars. + filename: ./yieldtables/ # Path to the directory containing the EAGLE yield tables. + IMF_min_mass_Msun: 0.1 # Minimal stellar mass considered for the Chabrier IMF in solar masses. + IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. + SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. + SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. + SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. + SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. + SNII_energy_fraction_min: 0.5 # Minimal fraction of energy applied in a SNII feedback event. + SNII_energy_fraction_max: 5.0 # Maximal fraction of energy applied in a SNII feedback event. + SNII_energy_fraction_Z_0: 0.0012663729 # Pivot point for the metallicity dependance of the SNII energy fraction (metal mass fraction). + 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_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. + SNIa_DTD_exp_norm_p_Msun: 0.002 # Normalisation of the SNIa rates in inverse solar masses. + SNIa_energy_erg: 1.0e51 # Energy of one SNIa explosion in ergs. + AGB_ejecta_velocity_km_p_s: 10.0 # Velocity of the AGB ejectas in km/s. + stellar_evolution_age_cut_Gyr: 0.1 # Stellar age in Gyr above which the enrichment is down-sampled. + stellar_evolution_sampling_rate: 10 # Number of time-steps in-between two enrichment events for a star above the age threshold. + SNII_yield_factor_Hydrogen: 1.0 # (Optional) Correction factor to apply to the Hydrogen yield from the SNII channel. + SNII_yield_factor_Helium: 1.0 # (Optional) Correction factor to apply to the Helium yield from the SNII channel. + SNII_yield_factor_Carbon: 0.5 # (Optional) Correction factor to apply to the Carbon yield from the SNII channel. + SNII_yield_factor_Nitrogen: 1.0 # (Optional) Correction factor to apply to the Nitrogen yield from the SNII channel. + SNII_yield_factor_Oxygen: 1.0 # (Optional) Correction factor to apply to the Oxygen yield from the SNII channel. + SNII_yield_factor_Neon: 1.0 # (Optional) Correction factor to apply to the Neon yield from the SNII channel. + SNII_yield_factor_Magnesium: 2.0 # (Optional) Correction factor to apply to the Magnesium yield from the SNII channel. + SNII_yield_factor_Silicon: 1.0 # (Optional) Correction factor to apply to the Silicon yield from the SNII channel. + SNII_yield_factor_Iron: 0.5 # (Optional) Correction factor to apply to the Iron yield from the SNII channel. + +# EAGLE AGN model +EAGLEAGN: + subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. + multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? + viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term + with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? + boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. + boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. + boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). + radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. + use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? + min_gas_mass_for_nibbling: 7.2e6 # Minimum mass for a gas particle to be nibbled from [M_Sun]. Only used if use_nibbling is 1. + max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. + eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. + coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. + 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_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). + 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? + 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_threshold 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_threshold is 1. + set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? + 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). + merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. diff --git a/examples/EAGLE_ICs/EAGLE_25_low_res/getIC.sh b/examples/EAGLE_ICs/EAGLE_25_low_res/getIC.sh new file mode 100755 index 0000000000000000000000000000000000000000..fe3ae0d395d008b5811465da14ce38a367b19fb5 --- /dev/null +++ b/examples/EAGLE_ICs/EAGLE_25_low_res/getIC.sh @@ -0,0 +1,2 @@ +#!/bin/bash +wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/EAGLE_ICs/EAGLE_L0025N0188_ICs.hdf5 diff --git a/examples/EAGLE_ICs/EAGLE_25_low_res/run.sh b/examples/EAGLE_ICs/EAGLE_25_low_res/run.sh new file mode 100755 index 0000000000000000000000000000000000000000..fa2655fe295b76960311b78cbfe0fb47bb372f41 --- /dev/null +++ b/examples/EAGLE_ICs/EAGLE_25_low_res/run.sh @@ -0,0 +1,35 @@ +#!/bin/bash + + # Generate the initial conditions if they are not present. +if [ ! -e EAGLE_L0025N0188_ICs.hdf5 ] +then + echo "Fetching initial conditions for the EAGLE 25Mpc low-res. example..." + ./getIC.sh +fi + +# Grab the cooling and yield tables if they are not present. +if [ ! -e yieldtables ] +then + echo "Fetching EAGLE yield tables..." + ../getEagleYieldTable.sh +fi + +if [ ! -e coolingtables ] +then + echo "Fetching EAGLE cooling tables..." + ../getEagleCoolingTable.sh +fi + +# The following run-time options are broken down by line as: +# Basic run-time options +# Create and run with stars +# Radiative options - run with cooling and stellar feedback +# Run with the time-step limiter required to capture feedback +# Run with black holes - fof is needed for the seeding +# Threading options - run with threads and pinning (latter not required but improves performance) +# The corresponding parameter file for this run + +../../swift \ + --cosmology --eagle \ + --threads=16 --pin \ + eagle_25.yml diff --git a/examples/EAGLE_ICs/EAGLE_25_low_res/vrconfig_3dfof_subhalos_SO_hydro.cfg b/examples/EAGLE_ICs/EAGLE_25_low_res/vrconfig_3dfof_subhalos_SO_hydro.cfg new file mode 100644 index 0000000000000000000000000000000000000000..2c190e870ab5e2c1af92efe7c13ec2df891aa65b --- /dev/null +++ b/examples/EAGLE_ICs/EAGLE_25_low_res/vrconfig_3dfof_subhalos_SO_hydro.cfg @@ -0,0 +1,213 @@ +#Configuration file for analysing Hydro +#runs 6DFOF + substructure algorithm, demands subhalos and FOF halos be self-bound, calculates many properties +#Units currently set to take in as input, Mpc, 1e10 solar masses, km/s, output in same units +#To set temporally unique halo ids, alter Snapshot_value=SNAP to appropriate value. Ie: for snapshot 12, change SNAP to 12 + +################################ +#input options +#set up to use SWIFT HDF input, load gas, star, bh and dark matter +################################ +HDF_name_convention=6 #HDF SWIFT naming convention +Input_includes_dm_particle=1 #include dark matter particles in hydro input +Input_includes_gas_particle=1 #include gas particles in hydro input +Input_includes_star_particle=1 #include star particles in hydro input +Input_includes_bh_particle=1 #include bh particles in hydro input +Input_includes_wind_particle=0 #include wind particles in hydro input (used by Illustris and moves particle type 0 to particle type 3 when decoupled from hydro forces). Here shown as example +Input_includes_tracer_particle=0 #include tracer particles in hydro input (used by Illustris). Here shown as example +Input_includes_extradm_particle=0 #include extra dm particles stored in particle type 2 and type 3, useful for zooms + +Particle_type_for_reference_frames=1 #use DM particles to define reference frame +Halo_core_phase_merge_dist=0.25 #merge substructures if difference in dispersion normalised distance is < this value +Apply_phase_merge_to_host=1 #merge substructures with background if centrally located and phase-distance is small + +#units conversion from input input to desired internal unit +Length_input_unit_conversion_to_output_unit=1.0 #default code unit, +Velocity_input_unit_conversion_to_output_unit=1.0 #default velocity unit, +Mass_input_unit_conversion_to_output_unit=1.0 #default mass unit, +#assumes input is in 1e10 msun, Mpc and km/s and output units are the same +Gravity=43.00918 #for 1e10 Msun, km/s and Mpc +Hubble_unit=100.0 # assuming units are km/s and Mpc, then value of Hubble in km/s/Mpc + +#converting hydro quantities +Stellar_age_input_is_cosmological_scalefactor=1 +Metallicity_input_unit_conversion_to_output_unit=1.0 +Stellar_age_input_unit_conversion_to_output_unit=1.0 +Star_formation_rate_input_unit_conversion_to_output_unit=1.0 +Stellar_age_to_yr=9.778134136e11 +Stellar_age_input_unit_conversion_to_output_unit=1.022690e-12 # year in units of Mpc / (km / s) + +#set the units of the output by providing conversion to a defined unit +#conversion of output length units to kpc +Length_unit_to_kpc=1000.0 +#conversion of output velocity units to km/s +Velocity_to_kms=1.0 +#conversion of output mass units to solar masses +Mass_to_solarmass=1.0e10 + +Metallicity_to_solarmetallicity=83.33 #1 / 0.012 +Star_formation_rate_to_solarmassperyear=97.78 +Stellar_age_to_yr=1.0 +#ensures that output is physical and not comoving distances per little h +Comoving_units=0 + +#sets the total buffer size in bytes used to store temporary particle information +#of mpi read threads before they are broadcast to the appropriate waiting non-read threads +#if not set, default value is equivalent to 1e6 particles per mpi process, quite large +#but significantly minimises the number of send/receives +#in this example the buffer size is roughly that for a send/receive of 10000 particles +#for 100 mpi processes +MPI_particle_total_buf_size=100000000 + +################################ +#search related options +################################ + +#how to search a simulation +Particle_search_type=1 #search dark matter particles only +#for baryon search +Baryon_searchflag=2 #if 1 search for baryons separately using phase-space search when identifying substructures, 2 allows special treatment in field FOF linking and phase-space substructure search, 0 treat the same as dark matter particles +#for search for substruture +Search_for_substructure=1 #if 0, end search once field objects are found +#also useful for zoom simulations or simulations of individual objects, setting this flag means no field structure search is run +Singlehalo_search=0 #if file is single halo in which one wishes to search for substructure. Here disabled. +#additional option for field haloes +Keep_FOF=0 #if field 6DFOF search is done, allows to keep structures found in 3DFOF (can be interpreted as the inter halo stellar mass when only stellar search is used).\n + +#minimum size for structures +Minimum_size=20 #min 20 particles +Minimum_halo_size=32 #if field halos have different minimum sizes, otherwise set to -1. + +#for field fof halo search +FoF_Field_search_type=5 #5 3DFOF search for field halos, 4 for 6DFOF clean up of field halos, 3 for 6DFOF with velocity scale distinct for each initial 3D FOF candidate +Halo_3D_linking_length=0.20 + +#for mean field estimates and local velocity density distribution funciton estimator related quantiites, rarely need to change this +Local_velocity_density_approximate_calculation=1 #calculates velocity density using approximative (and quicker) near neighbour search +Cell_fraction = 0.01 #fraction of field fof halo used to determine mean velocity distribution function. Typical values are ~0.005-0.02 +Grid_type=1 #normal entropy based grid, shouldn't have to change +Nsearch_velocity=32 #number of velocity neighbours used to calculate local velocity distribution function. Typial values are ~32 +Nsearch_physical=256 #numerof physical neighbours from which the nearest velocity neighbour set is based. Typical values are 128-512 + +#for substructure search, rarely ever need to change this +FoF_search_type=1 #default phase-space FOF search. Don't really need to change +Iterative_searchflag=1 #iterative substructure search, for substructure find initial candidate substructures with smaller linking lengths then expand search region +Outlier_threshold=2.5 #outlier threshold for a particle to be considered residing in substructure, that is how dynamically distinct a particle is. Typical values are >2 +Substructure_physical_linking_length=0.10 +Velocity_ratio=2.0 #ratio of speeds used in phase-space FOF +Velocity_opening_angle=0.10 #angle between velocities. 18 degrees here, typical values are ~10-30 +Velocity_linking_length=0.20 #where scaled by structure dispersion +Significance_level=1.0 #how significant a substructure is relative to Poisson noise. Values >= 1 are fine. + +#for iterative substructure search, rarely ever need to change this +Iterative_threshold_factor=1.0 #change in threshold value when using iterative search. Here no increase in threshold if iterative or not +Iterative_linking_length_factor=2.0 #increase in final linking final iterative substructure search +Iterative_Vratio_factor=1.0 #change in Vratio when using iterative search. no change in vratio +Iterative_ThetaOp_factor=1.0 #change in velocity opening angle. no change in velocity opening angle + +#for checking for halo merger remnants, which are defined as large, well separated phase-space density maxima +Halo_core_search=2 # searches for separate 6dfof cores in field haloes, and then more than just flags halo as merging, assigns particles to each merging "halo". 2 is full separation, 1 is flagging, 0 is off +#if searching for cores, linking lengths. likely does not need to change much +Use_adaptive_core_search=0 #calculate dispersions in configuration & vel space to determine linking lengths +Use_phase_tensor_core_growth=2 #use full stepped phase-space tensor assignment +Halo_core_ellx_fac=0.7 #how linking lengths are changed when searching for local 6DFOF cores, +Halo_core_ellv_fac=2.0 #how velocity lengths based on dispersions are changed when searching for local 6DFOF cores +Halo_core_ncellfac=0.005 #fraction of total halo particle number setting min size of a local 6DFOF core +Halo_core_num_loops=8 #number of loops to iteratively search for cores +Halo_core_loop_ellx_fac=0.75 #how much to change the configuration space linking per iteration +Halo_core_loop_ellv_fac=1.0 #how much to change the velocity space linking per iteration +Halo_core_loop_elln_fac=1.2 #how much to change the min number of particles per iteration +Halo_core_phase_significance=5.0 #how significant a core must be in terms of dispersions (sigma) significance + +################################ +#Unbinding options (VELOCIraptor is able to accurately identify tidal debris so particles need not be bound to a structure) +################################ + +#unbinding related items +Unbind_flag=1 #run unbinding +#objects must have particles that meet the allowed kinetic to potential ratio AND also have some total fraction that are completely bound. +Unbinding_type=0 +#alpha factor used to determine whether particle is "bound" alaph*T+W<0. For standard subhalo catalogues use >0.9 but if interested in tidal debris 0.2-0.5 +Allowed_kinetic_potential_ratio=0.95 +Min_bound_mass_frac=0.65 #minimum bound mass fraction +#run unbinding of field structures, aka halos. This is useful for sams and 6DFOF halos but may not be useful if interested in 3DFOF mass functions. +Bound_halos=0 +#don't keep background potential when unbinding +Keep_background_potential=1 +#use all particles to determine velocity frame for unbinding +Frac_pot_ref=1.0 +Min_npot_ref=20 +#reference frame only meaningful if calculating velocity frame using subset of particles in object. Can use radially sorted fraction of particles about minimum potential or centre of mass +Kinetic_reference_frame_type=0 +#extra options in new unbinding optimisation +Unbinding_max_unbound_removal_fraction_per_iteration=0.5 +Unbinding_max_unbound_fraction=0.95 +Unbinding_max_unbound_fraction_allowed=0.005 + +################################ +#Calculation of properties related options +################################ + +Number_of_overdensities=5 +Overdensity_values_in_critical_density=100,200,500,1000,2500, +#when calculating properties, for field objects calculate inclusive masses +Inclusive_halo_masses=3 #calculate inclusive masses for halos using full Spherical overdensity apertures +#ensures that output is physical and not comoving distances per little h +Comoving_units=0 +#calculate more (sub)halo properties (like angular momentum in spherical overdensity apertures, both inclusive and exclusive) +Extensive_halo_properties_output=1 +Extensive_gas_properties_output=1 +Extensive_star_properties_output=1 +#calculate aperture masses +Calculate_aperture_quantities=1 +Number_of_apertures=5 +Aperture_values_in_kpc=5,10,30,50,100, +Number_of_projected_apertures=5 +Projected_aperture_values_in_kpc=5,10,30,50,100, +#calculate radial profiles +Calculate_radial_profiles=1 +Number_of_radial_profile_bin_edges=20 +#default radial normalisation log rad bins, normed by R200crit, Integer flag of 0 is log bins and R200crit norm. +Radial_profile_norm=0 +Radial_profile_bin_edges=-2.,-1.87379263,-1.74758526,-1.62137789,-1.49517052,-1.36896316,-1.24275579,-1.11654842,-0.99034105,-0.86413368,-0.73792631,-0.61171894,-0.48551157,-0.3593042,-0.23309684,-0.10688947,0.0193179,0.14552527,0.27173264,0.39794001, +Iterate_cm_flag=0 #do not interate to determine centre-of-mass +Sort_by_binding_energy=1 #sort particles by binding energy +Reference_frame_for_properties=2 #use the minimum potential as reference frame about which to calculate properties + +################################ +#Extra fields +################################ + +# Also compute the H abundance as well as the HI, HII and H_2 fractions +Gas_internal_property_names=ElementMassFractions,SpeciesFractions,SpeciesFractions,SpeciesFractions, +Gas_internal_property_index_in_file=0,0,1,2, +Gas_internal_property_input_output_unit_conversion_factors=1.0,1.0,1.0,1.0 +Gas_internal_property_calculation_type =averagemassweighted,averagemassweighted,averagemassweighted,averagemassweighted, +Gas_internal_property_output_units=unitless,unitless,unitless,unitless, + +# Collect the BH subgrid masses and compute the max, min, average and total mass in apertures +BH_internal_property_names=SubgridMasses,SubgridMasses,SubgridMasses,SubgridMasses, +BH_internal_property_input_output_unit_conversion_factors=1.0e10,1.0e10,1.0e10,1.0e10, +BH_internal_property_calculation_type=max,min,average,aperture_total, +BH_internal_property_output_units=solar_mass,solar_mass,solar_mass,solar_mass, + +################################ +#output related +################################ + +Write_group_array_file=0 #do not write a group array file +Separate_output_files=0 #do not separate output into field and substructure files similar to subfind +Binary_output=2 #Use HDF5 output (binary output 1, ascii 0, and HDF 2) +#output particles residing in the spherical overdensity apertures of halos, only the particles exclusively belonging to halos +Spherical_overdensity_halo_particle_list_output=1 + +#halo ids are adjusted by this value * 1000000000000 (or 1000000 if code compiled with the LONGINTS option turned off) +#to ensure that halo ids are temporally unique. So if you had 100 snapshots, for snap 100 set this to 100 and 100*1000000000000 will +#be added to the halo id as set for this snapshot, so halo 1 becomes halo 100*1000000000000+1 and halo 1 of snap 0 would just have ID=1 + +#ALTER THIS as part of a script to get temporally unique ids +Snapshot_value=SNAP + +################################ +#other options +################################ +Verbose=1 #how talkative do you want the code to be, 0 not much, 1 a lot, 2 chatterbox diff --git a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml index ff5c3db47696e81ff9a8bb3e7313c2012873631a..a2a240711f31f3f6a6bc6eb37058e0e7f7d2c558 100644 --- a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml @@ -136,21 +136,22 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. + # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: Jeans_density_threshold_H_p_cm3: 1e-4 # Physical density above which the EAGLE Jeans limiter entropy floor kicks in expressed in Hydrogen atoms per cm^3. @@ -174,6 +175,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. @@ -205,41 +207,43 @@ EAGLEFeedback: # EAGLE AGN model EAGLEAGN: - subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. - multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? - subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? - with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? - viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term - with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? - boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. - boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. - boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). - radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. - use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? - 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. - max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. - eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. - coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. - 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_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? - 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_threshold 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_threshold is 1. - set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? - 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). - merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. + subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. + use_multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + use_subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? + viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term + with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? + boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. + boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. + boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). + radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. + use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? + 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. + max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. + eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. + coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 1 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? + 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_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). + 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? + 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_threshold 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_threshold is 1. + set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? + 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). + merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. 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 be06d1f9b28f035e92f4f2274a916b8ccd5840d8..3e411e450273117267652b328dc10a82470a53be 100644 --- a/examples/EAGLE_ICs/EAGLE_50_low_res/eagle_50.yml +++ b/examples/EAGLE_ICs/EAGLE_50_low_res/eagle_50.yml @@ -135,20 +135,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -173,6 +174,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. @@ -204,41 +206,43 @@ EAGLEFeedback: # EAGLE AGN model EAGLEAGN: - subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. - multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? - subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? - with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? - viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term - with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? - boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. - boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. - boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). - radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. - use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? - min_gas_mass_for_nibbling: 7.2e6 # Minimum mass for a gas particle to be nibbled from [M_Sun]. Only used if use_nibbling is 1. - max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. - eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. - coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. - 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_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? - 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_threshold 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_threshold is 1. - set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? - 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). - merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. + subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. + use_multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + use_subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? + viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term + with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? + boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. + boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. + boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). + radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. + use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? + 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. + max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. + eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. + coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 1 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? + 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_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). + 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? + 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_threshold 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_threshold is 1. + set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? + 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). + merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. diff --git a/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml b/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml index 413e78ca3cd22ca7646de1e90d993776d2d419f9..41747fbb01c24d97e51cd1d93d7b9ce1a7fd57c9 100644 --- a/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml +++ b/examples/EAGLE_ICs/EAGLE_6/eagle_6.yml @@ -138,20 +138,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -176,6 +177,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. @@ -207,41 +209,43 @@ EAGLEFeedback: # EAGLE AGN model EAGLEAGN: - subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. - multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? - subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? - with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? - viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term - with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? - boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. - boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. - boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). - use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? - 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. - radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. - max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. - eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. - coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. - 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_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? - 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_threshold 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_threshold is 1. - set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? - 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). - merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. + subgrid_seed_mass_Msun: 1.0e4 # Black hole subgrid mass at creation time in solar masses. + use_multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + use_subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + with_angmom_limiter: 0 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? + viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term + with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? + boost_alpha: 1. # Lowest value for the accretion effeciency for the Booth & Schaye 2009 accretion model. + boost_beta: 2. # Slope of the power law for the Booth & Schaye 2009 model, set beta to zero for constant alpha models. + boost_n_h_star_H_p_cm3: 0.1 # Normalization of the power law for the Booth & Schaye 2009 model in cgs (cm^-3). + radiative_efficiency: 0.1 # Fraction of the accreted mass that gets radiated. + use_nibbling: 1 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? + 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. + max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. + eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. + coupling_efficiency: 0.1 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 1 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? + 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_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). + 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? + 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_threshold 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_threshold is 1. + set_reposition_speed: 0 # Should we reposition black holes with (at most) a prescribed speed towards the potential minimum? + 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). + merger_max_distance_ratio: 3.0 # Maximal distance over which two BHs can merge, in units of the softening length. diff --git a/examples/EAGLE_ICs/README b/examples/EAGLE_ICs/README index dc6cbec94aa2b3cbb45143a29edc845656432571..77a900d7a8c1a09e9dda4509bc77cae146dfb6ad 100644 --- a/examples/EAGLE_ICs/README +++ b/examples/EAGLE_ICs/README @@ -35,14 +35,19 @@ the following changes have been made (at standard resolution): been removed as the new cooling tables handle this correctly. The gamma=4/3 floor has been extended to lower densities (i.e. 800K at n_H = 10^-4 cm^-3) as a fail-safe. - - Particles can be star-forming if they are within 0.3 dex of the - entropy floor (was 0.5 dex). These particles also get their - subgrid properties (rho, T as well as the HI and H_2 frac) computed. + - Particles within 0.3 dex of the entropy floor get their + subgrid properties (rho, T as well as the HI and H_2 frac) computed + assuming pressure equilibrium. + - Particles are star-forming if their subgrid temperature is below + 10^3 K OR if they are both colder than 10^4.5 K and have a subgrid + number density above 10 cm^-3. - Particles can be star-forming if they are in an over-density of at least 100 (was 57.7). - Particles with a density above 10^5 cm^-3 are not turned into stars instantaneously any more. - The minimal mass of SNII stars has been raised to 8 Msun (from 6). + - The SNII feedback heats the particle closest to the star particle + (was a random set of particles in the kernel). - The SNII feedback delay is done by sampling the stellar age distribution and not using a fixed delay of 30 Myr any more. - The energy range for the SNII variable f_th is now 0.5 - 5.0 @@ -73,6 +78,11 @@ the following changes have been made (at standard resolution): - The angular momentum term in the BH accretion model of Rosas-Guevara et al. (2015) is now switched off. - The coupling efficency of the BH feedback is now 0.1 (was 0.15). + - The AGN feedback heats the particles closest to the BH particle + (was a random set of particles in the kernel). + - The AGN does not use a combination of probability and reservoir + any more. Energy is accumulated and then used in a deterministic + way once the threshold for feedback is reached. - The AGN feedback temperature jump is now a function of the BH subgrid mass (was a constant at 10^8.5K). The temperature varies between 10^7 and 3*10^9 K with a power-law of the subgrid mass diff --git a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml index e7967b30f4703b705ffb49466d01674c601e9e40..4db4228d3ec8aa01ec608f66d58805a4993e5071 100644 --- a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml @@ -122,20 +122,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Zdep # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -160,6 +161,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 6.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 0 # Sample the SNII lifetimes to do feedback. SNII_wind_delay_Gyr: 0.03 # Time in Gyr between a star's birth and the SNII thermal feedback event when not sampling. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. @@ -206,9 +208,11 @@ EAGLEAGN: max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 0 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? 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 or AGN_use_nheat_with_fixed_dT is 1). + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). 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). diff --git a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml index 367113258c0f73a91ca44d92d676d98042b0fb39..f37a52ff03093f085115f30322cb579877d87ca9 100644 --- a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml @@ -130,20 +130,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Zdep # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -168,6 +169,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 6.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 0 # Sample the SNII lifetimes to do feedback. SNII_wind_delay_Gyr: 0.03 # Time in Gyr between a star's birth and the SNII thermal feedback event when not sampling. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. @@ -214,9 +216,11 @@ EAGLEAGN: max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 0 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? 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 or AGN_use_nheat_with_fixed_dT is 1). + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). 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). diff --git a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml index 91952e4c9ea2fc4dfca95e3a3a10228c83abeb32..e1ce6362e88a110a615f617bf568ec62d544fea2 100644 --- a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml @@ -121,20 +121,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Zdep # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -159,6 +160,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 6.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 0 # Sample the SNII lifetimes to do feedback. SNII_wind_delay_Gyr: 0.03 # Time in Gyr between a star's birth and the SNII thermal feedback event when not sampling. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. @@ -205,9 +207,11 @@ EAGLEAGN: max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 0 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? 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 or AGN_use_nheat_with_fixed_dT is 1). + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). 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). diff --git a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml index 9905c814334797704772c3867e3c1fb87ad1d6f1..3cb8c288ca6b508efe76be8ec1a9767b5c2f8c7f 100644 --- a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml +++ b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml @@ -133,20 +133,21 @@ COLIBRECooling: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Zdep # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -171,6 +172,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 6.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 0 # Sample the SNII lifetimes to do feedback. SNII_wind_delay_Gyr: 0.03 # Time in Gyr between a star's birth and the SNII thermal feedback event when not sampling. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. @@ -217,9 +219,11 @@ EAGLEAGN: max_eddington_fraction: 1. # Maximal allowed accretion rate in units of the Eddington rate. eddington_fraction_for_recording: 0.1 # Record the last time BHs reached an Eddington ratio above this threshold. coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. + AGN_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 0 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? 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 or AGN_use_nheat_with_fixed_dT is 1). + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event [K] (used if use_variable_delta_T is 0 or AGN_use_nheat_with_fixed_dT is 1 AND to initialise the BHs). 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). diff --git a/examples/HydroTests/BlobTest_3D/run.sh b/examples/HydroTests/BlobTest_3D/run.sh index 94aa5ba7bc3afe7aff84ad62e448d1f346848a2c..15c87c734e239a120863fc5b12c87a8b7f2d5ecc 100755 --- a/examples/HydroTests/BlobTest_3D/run.sh +++ b/examples/HydroTests/BlobTest_3D/run.sh @@ -8,6 +8,6 @@ then fi # Run SWIFT -../../swift --hydro --threads=4 blob.yml +../../swift --hydro --threads=2 blob.yml -python makeMovie.py +python3 makeMovie.py diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml index 17c87266c646b9a1b4e866210e0f911ccae4cd90..a0e0317e87f532b1169d13322735de9fb78e5356 100644 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/isolated_galaxy.yml @@ -111,20 +111,21 @@ HernquistPotential: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Zdep # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: @@ -149,6 +150,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 8.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: MinimumDistance # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. SNII_energy_erg: 1.0e51 # Energy of one SNII explosion in ergs. diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/plotSolution.py b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/plotSolution.py index 7d1dd624586d814eac4242f95b5130ecbe2b95e8..9c2f09b732adda3088778882ae82bfcb373cd2ce 100644 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/plotSolution.py +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_feedback/plotSolution.py @@ -1,3 +1,23 @@ +#!/usr/bin/env python3 +################################################################################ +# This file is part of SWIFT. +# Copyright (c) 2019 Folkert Nobels (nobels@strw.leidenuniv.nl) +# Matthieu Schaller (schaller@strw.leidenuniv.nl) +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +################################################################################ import matplotlib matplotlib.use("Agg") @@ -131,6 +151,7 @@ stars_pos = f["/PartType4/Coordinates"][:, :] stars_BirthDensity = f["/PartType4/BirthDensities"][:] stars_BirthTime = f["/PartType4/BirthTimes"][:] stars_XH = f["/PartType4/ElementMassFractions"][:, 0] +stars_BirthTemperature = f["/PartType4/BirthTemperatures"][:] # Centre the box gas_pos[:, 0] -= centre[0] @@ -144,6 +165,9 @@ stars_pos[:, 2] -= centre[2] # Turn the mass into better units gas_mass *= unit_mass_in_cgs / Msun_in_cgs +# Calculate the median gas mass +median_gas_mass = np.median(gas_mass) + # Turn the SFR into better units gas_SFR = np.maximum(gas_SFR, np.zeros(np.size(gas_SFR))) gas_SFR /= unit_time_in_cgs / year_in_cgs @@ -206,19 +230,6 @@ savefig("rhoT_SF.png", dpi=200) ########################################################################3 -# 3D Density vs SFR -figure() -subplot(111, xscale="log", yscale="log") -scatter(gas_nH, gas_SFR, s=0.2) -plot([1, 100], 2e-5 * np.array([1, 100]) ** 0.266667, "k--", lw=1) -xlabel("${\\rm Density}~n_{\\rm H}~[{\\rm cm^{-3}}]$", labelpad=0) -ylabel("${\\rm SFR}~[{\\rm M_\\odot~\\cdot~yr^{-1}}]$", labelpad=-7) -xlim(1e-4, 3e3) -ylim(8e-6, 2.5e-4) -savefig("rho_SFR.png", dpi=200) - -########################################################################3 - star_mask = ( (stars_pos[:, 0] > -15) & (stars_pos[:, 0] < 15) @@ -237,9 +248,17 @@ figure() subplot(111, xscale="linear", yscale="linear") hist(np.log10(stars_BirthDensity), density=True, bins=20, range=[-2, 5]) xlabel("${\\rm Stellar~birth~density}~n_{\\rm H}~[{\\rm cm^{-3}}]$", labelpad=0) -ylabel("${\\rm Probability}$", labelpad=-7) +ylabel("${\\rm Probability}$", labelpad=3) savefig("BirthDensity.png", dpi=200) +# Histogram of the birth temperature +figure() +subplot(111, xscale="linear", yscale="linear") +hist(np.log10(stars_BirthTemperature), density=True, bins=20, range=[3.5, 5.0]) +xlabel("${\\rm Stellar~birth~temperature}~[{\\rm K}]$", labelpad=0) +ylabel("${\\rm Probability}$", labelpad=3) +savefig("BirthTemperature.png", dpi=200) + # Plot of the specific star formation rate in the galaxy rhos = 10 ** np.linspace(-1, np.log10(KS_high_den_thresh), 100) rhoshigh = 10 ** np.linspace(np.log10(KS_high_den_thresh), 5, 100) @@ -288,6 +307,26 @@ xlim(-1.4, 4.9) ylim(-0.5, 2.2) savefig("density-sSFR.png", dpi=200) +SFR_low = 10 ** (np.log10(sSFR) + np.log10(year_in_cgs) + np.log10(median_gas_mass)) +SFR_high = 10 ** ( + np.log10(sSFR_high_den) + np.log10(year_in_cgs) + np.log10(median_gas_mass) +) +SFR_low_min = np.floor(np.log10(0.75 * np.min(SFR_low))) +SFR_high_max = np.ceil(np.log10(1.25 * np.max(SFR_high))) + +# 3D Density vs SFR +rcParams.update({"figure.subplot.left": 0.18}) +figure() +subplot(111, xscale="log", yscale="log") +scatter(gas_nH, gas_SFR, s=0.2) +plot(rhos, SFR_low, "k--", lw=1, label="SFR low density EAGLE") +plot(rhoshigh, SFR_high, "k--", lw=1, label="SFR high density EAGLE") +xlabel("${\\rm Density}~n_{\\rm H}~[{\\rm cm^{-3}}]$", labelpad=0) +ylabel("${\\rm SFR}~[{\\rm M_\\odot~\\cdot~yr^{-1}}]$", labelpad=2) +xlim(1e-2, 1e5) +ylim(10 ** SFR_low_min, 10 ** (SFR_high_max + 0.1)) +savefig("rho_SFR.png", dpi=200) +rcParams.update({"figure.subplot.left": 0.15}) ########################################################################3 # Select gas in a pillow box around the galaxy diff --git a/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/isolated_galaxy.yml b/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/isolated_galaxy.yml index 983d185c9089fae93253d2859dba3050497d2d51..af334ff7d4f2834c18c3af97d8b01259e559ebed 100644 --- a/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/isolated_galaxy.yml +++ b/examples/IsolatedGalaxy/IsolatedGalaxy_starformation/isolated_galaxy.yml @@ -103,21 +103,22 @@ HernquistPotential: # EAGLE star formation parameters EAGLEStarFormation: - SF_model: PressureLaw - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EOS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EOS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EOS assumed for the star-forming gas. - gas_fraction: 0.3 # The gas fraction used internally by the model. - KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. - KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. - min_over_density: 100.0 # The over-density above which star-formation is allowed. - KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. - KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. - EOS_entropy_margin_dex: 0.3 # Logarithm base 10 of the maximal entropy above the EOS at which stars can form. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + SF_threshold: Zdep # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw + gas_fraction: 0.3 # The gas fraction used internally by the model. + KS_normalisation: 1.515e-4 # The normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. + KS_exponent: 1.4 # The exponent of the Kennicutt-Schmidt law. + min_over_density: 100.0 # The over-density above which star-formation is allowed. + KS_high_density_threshold_H_p_cm3: 1e3 # Hydrogen number density above which the Kennicut-Schmidt law changes slope in Hydrogen atoms per cm^3. + KS_high_density_exponent: 2.0 # Slope of the Kennicut-Schmidt law above the high-density threshold. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Parameters for the EAGLE "equation of state" EAGLEEntropyFloor: diff --git a/examples/Logger/SimpleOrbits/README b/examples/Logger/SimpleOrbits/README new file mode 100644 index 0000000000000000000000000000000000000000..70ab1370584c6f45f776f4ccf554b4f61ff88866 --- /dev/null +++ b/examples/Logger/SimpleOrbits/README @@ -0,0 +1,5 @@ +This example simulates a planet orbiting around the Sun and then compares +the solutions given by the snapshots to those read from the logger. + +It requires compilation with the logger, python and the external point mass potential +(./configure --with-python=/usr --enable-logger --with-ext-potential=point-mass). \ No newline at end of file diff --git a/examples/Logger/SimpleOrbits/plotSolution.py b/examples/Logger/SimpleOrbits/plotSolution.py index b160e24964240b7a8a89fc03594aa4fb149b65bc..a2d216c035dc53e65a29c34b937c143b908f326f 100644 --- a/examples/Logger/SimpleOrbits/plotSolution.py +++ b/examples/Logger/SimpleOrbits/plotSolution.py @@ -143,75 +143,40 @@ def doLogger(): """ Read the logfile and plot the corresponding variables. """ - basename = "index" + basename = "index_0000" N = 1000 - verbose = 0 # Get time limits - t_min, t_max = logger.getTimeLimits(basename, verbose) - times = np.linspace(t_min, t_max, N) - - # Create output arrays - E = np.zeros((N, makeIC.num_part)) - E_parts = np.zeros((N, makeIC.num_part)) - p = np.zeros((N, 3)) - v = np.zeros((N, 3)) - t_parts = np.zeros((N, makeIC.num_part)) - p_parts = np.zeros((N, 3)) - v_parts = np.zeros((N, 3)) - - # Read the particles - parts = logger.loadSnapshotAtTime( - basename, times[0], verbose) - - for i, t in enumerate(times): - # Get the next particles - interp = logger.moveForwardInTime( - basename, parts, t, verbose) - ids = interp["ids"] - sort = np.argsort(ids) - ids = ids[sort] - rel_pos = interp["positions"][sort, :] - center - vel = interp["velocities"][sort, :] - - rel_pos_parts = parts["positions"][sort, :] - center - vel_parts = parts["velocities"][sort, :] - - # Compute the interpolated variables - r = np.sum(rel_pos**2, axis=1)**0.5 - v2 = np.sum(vel**2, axis=1) - E[i, :] = 0.5 * v2 - G * M / r - ind = ids == id_focus - p[i, :] = rel_pos[ind, :] - v[i, :] = vel[ind, :] - - # Compute the variables of the last record - r = np.sum(rel_pos_parts**2, axis=1)**0.5 - v2 = np.sum(vel_parts**2, axis=1) - E_parts[i, :] = 0.5 * v2 - G * M / r - t_parts[i, :] = parts["times"][sort] - ind = ids == id_focus - p_parts[i, :] = rel_pos_parts[ind, :] - v_parts[i, :] = vel_parts[ind, :] + with logger.Reader(basename, verbose=0) as reader: + t_min, t_max = reader.get_time_limits() + times = np.linspace(t_min, t_max, N) + + # Create output arrays + E = np.zeros((N, makeIC.num_part)) + p = np.zeros((N, 3)) + v = np.zeros((N, 3)) + + for i, t in enumerate(times): + # Get the next particles + pos, vel, ids = reader.get_particle_data( + ["Coordinates", "Velocities", "ParticleIDs"], t) + sort = np.argsort(ids) + ids = ids[sort] + rel_pos = pos[sort, :] - center + vel = vel[sort, :] + + # Compute the derived values + r = np.sum(rel_pos**2, axis=1)**0.5 + v2 = np.sum(vel**2, axis=1) + E[i, :] = 0.5 * v2 - G * M / r + ind = ids == id_focus + p[i, :] = rel_pos[ind, :] + v[i, :] = vel[ind, :] # compute the plotting variables plt.figure(fig_1.number) - plotRelative(t_parts, E_parts, "x", label="Logger") plotRelative(times, E, "--", label="Logger (Interpolation)") - # Compute the solution - y0 = np.zeros(4) - y0[:2] = p[0, :2] - y0[2:] = v[0, :2] - t_parts, ind = np.unique(t_parts[:, 0], return_index=True) - - # plot the solution - plt.figure(fig_2.number) - plt.plot(p_parts[:, 0], p_parts[:, 1], "x", label="Logger") - - plt.figure(fig_3.number) - plt.plot(v_parts[:, 0], v_parts[:, 1], "x", label="Logger") - # Compute the solution y0 = np.zeros(4) y0[:2] = p[0, :2] diff --git a/examples/Logger/SimpleOrbits/run.sh b/examples/Logger/SimpleOrbits/run.sh index e1742c357d445faf5fc92330c47300fe2dcff602..944a19c0a4791b72d8a106d770abd5aae6df3ad2 100644 --- a/examples/Logger/SimpleOrbits/run.sh +++ b/examples/Logger/SimpleOrbits/run.sh @@ -5,7 +5,7 @@ echo "Generating initial conditions for the Simple Orbits example..." python makeIC.py # Run SWIFT -../../swift --external-gravity --threads=1 simple_orbits.yml 2>&1 | tee output.log +../../swift --logger --external-gravity --threads=1 simple_orbits.yml 2>&1 | tee output.log # Plot the solution python3 plotSolution.py diff --git a/examples/PMillennium/PMillennium-1536/output_list.txt b/examples/PMillennium/PMillennium-1536/output_list.txt new file mode 100644 index 0000000000000000000000000000000000000000..70928da260fadbc0b0b11ef7bebb75a8f6c91e8b --- /dev/null +++ b/examples/PMillennium/PMillennium-1536/output_list.txt @@ -0,0 +1,9 @@ +# Redshift +10.0 +5.0 +3.0 +2.0 +1.0 +0.5 +0.1 +0. diff --git a/examples/PMillennium/PMillennium-1536/p-mill-1536.yml b/examples/PMillennium/PMillennium-1536/p-mill-1536.yml index e2e8439a71dac106b6f4fe0128805a96ff48f796..9bae5e555cc3cc918ea634b3c5f4331a8e57b3b4 100644 --- a/examples/PMillennium/PMillennium-1536/p-mill-1536.yml +++ b/examples/PMillennium/PMillennium-1536/p-mill-1536.yml @@ -26,13 +26,13 @@ TimeIntegration: Scheduler: max_top_level_cells: 32 - cell_split_size: 100 + cell_split_size: 200 # Parameters governing the snapshots Snapshots: basename: PMill - delta_time: 1.02 - scale_factor_first: 0.02 + output_list_on: 1 + output_list: ./output_list.txt # Parameters governing the conserved quantities statistics Statistics: diff --git a/examples/PMillennium/PMillennium-3072/getIC.sh b/examples/PMillennium/PMillennium-3072/getIC.sh new file mode 100755 index 0000000000000000000000000000000000000000..1797a8014b3a991458352335009a37e90b551e42 --- /dev/null +++ b/examples/PMillennium/PMillennium-3072/getIC.sh @@ -0,0 +1,2 @@ +#!/bin/bash +wget http://virgodb.cosma.dur.ac.uk/swift-webstorage/ICs/PMillennium/PMill-3072.hdf5 diff --git a/examples/PMillennium/PMillennium-3072/output_list.txt b/examples/PMillennium/PMillennium-3072/output_list.txt new file mode 100644 index 0000000000000000000000000000000000000000..70928da260fadbc0b0b11ef7bebb75a8f6c91e8b --- /dev/null +++ b/examples/PMillennium/PMillennium-3072/output_list.txt @@ -0,0 +1,9 @@ +# Redshift +10.0 +5.0 +3.0 +2.0 +1.0 +0.5 +0.1 +0. diff --git a/examples/PMillennium/PMillennium-3072/p-mill-3072.yml b/examples/PMillennium/PMillennium-3072/p-mill-3072.yml new file mode 100644 index 0000000000000000000000000000000000000000..ef42de068f3550af863c0aa03f0c7544de0e17fe --- /dev/null +++ b/examples/PMillennium/PMillennium-3072/p-mill-3072.yml @@ -0,0 +1,57 @@ +# Define some meta-data about the simulation +MetaData: + run_name: Planck-Millennium simulation - 3072^3 + +# Define the system of units to use internally. +InternalUnitSystem: + UnitMass_in_cgs: 1.98848e43 # 10^10 M_sun + UnitLength_in_cgs: 3.08567758e24 # 1 Mpc + UnitVelocity_in_cgs: 1e5 # 1 km/s + UnitCurrent_in_cgs: 1 # Amperes + UnitTemp_in_cgs: 1 # Kelvin + +# Planck-13 cosmology +Cosmology: + h: 0.6777 + a_begin: 0.02 # z_ini = 49 + a_end: 1.0 # z_end = 0 + Omega_m: 0.307 + Omega_lambda: 0.693 + Omega_b: 0.0455 + +# Parameters governing the time integration +TimeIntegration: + dt_min: 1e-6 + dt_max: 1e-2 + +Scheduler: + max_top_level_cells: 64 + cell_split_size: 200 + +# Parameters governing the snapshots +Snapshots: + basename: PMill + output_list_on: 1 + output_list: ./output_list.txt + +# Parameters governing the conserved quantities statistics +Statistics: + delta_time: 1.02 + scale_factor_first: 0.02 + +# Parameters for the self-gravity scheme +Gravity: + eta: 0.025 + MAC: adaptive + theta_cr: 0.7 + epsilon_fmm: 0.001 + comoving_DM_softening: 0.01041667 # 10.41667 kpc = 1/25 mean inter-particle separation + max_physical_DM_softening: 0.01041667 # 10.41667 kpc = 1/25 mean inter-particle separation + mesh_side_length: 1024 + +# Parameters related to the initial conditions +InitialConditions: + file_name: PMill-3072.hdf5 + periodic: 1 + cleanup_h_factors: 1 + cleanup_velocity_factors: 1 diff --git a/examples/PMillennium/PMillennium-384/output_list.txt b/examples/PMillennium/PMillennium-384/output_list.txt new file mode 100644 index 0000000000000000000000000000000000000000..70928da260fadbc0b0b11ef7bebb75a8f6c91e8b --- /dev/null +++ b/examples/PMillennium/PMillennium-384/output_list.txt @@ -0,0 +1,9 @@ +# Redshift +10.0 +5.0 +3.0 +2.0 +1.0 +0.5 +0.1 +0. diff --git a/examples/PMillennium/PMillennium-384/p-mill-384.yml b/examples/PMillennium/PMillennium-384/p-mill-384.yml index 0e058b5b83f81de967be34c3237d1cf7060e1e4a..7095f7deccc7061f4b58a6d8fd6133738e4b7107 100644 --- a/examples/PMillennium/PMillennium-384/p-mill-384.yml +++ b/examples/PMillennium/PMillennium-384/p-mill-384.yml @@ -26,13 +26,13 @@ TimeIntegration: Scheduler: max_top_level_cells: 16 - cell_split_size: 100 + cell_split_size: 200 # Parameters governing the snapshots Snapshots: basename: PMill - delta_time: 1.02 - scale_factor_first: 0.02 + output_list_on: 1 + output_list: ./output_list.txt # Parameters governing the conserved quantities statistics Statistics: diff --git a/examples/PMillennium/PMillennium-768/output_list.txt b/examples/PMillennium/PMillennium-768/output_list.txt new file mode 100644 index 0000000000000000000000000000000000000000..70928da260fadbc0b0b11ef7bebb75a8f6c91e8b --- /dev/null +++ b/examples/PMillennium/PMillennium-768/output_list.txt @@ -0,0 +1,9 @@ +# Redshift +10.0 +5.0 +3.0 +2.0 +1.0 +0.5 +0.1 +0. diff --git a/examples/PMillennium/PMillennium-768/p-mill-768.yml b/examples/PMillennium/PMillennium-768/p-mill-768.yml index 3a058c2db9f2a0e171c8f7a56dec0b03e593c081..e3116681f8354a838a930f850b8e945ea41f2800 100644 --- a/examples/PMillennium/PMillennium-768/p-mill-768.yml +++ b/examples/PMillennium/PMillennium-768/p-mill-768.yml @@ -26,13 +26,13 @@ TimeIntegration: Scheduler: max_top_level_cells: 16 - cell_split_size: 100 + cell_split_size: 200 # Parameters governing the snapshots Snapshots: basename: PMill - delta_time: 1.02 - scale_factor_first: 0.02 + output_list_on: 1 + output_list: ./output_list.txt # Parameters governing the conserved quantities statistics Statistics: diff --git a/examples/PMillennium/README b/examples/PMillennium/README index e4755bc214d438a282521b77a34ad853d0f36871..3bbbfea18fa8127f857de2110905eb26212936cc 100644 --- a/examples/PMillennium/README +++ b/examples/PMillennium/README @@ -7,3 +7,17 @@ volume with the cosmology given by Planck-13: The ICs exist at different resolution. The Millennium simulation (Springel 2005) has a resolution in between the 1536^3 and 3072^3 examples given here. + +The ICs sizes are: + +PMill-384 - 1.1 GB +PMill-768 - 8.3 GB +PMill-1536 - 163 GB +PMill-3072 - 1.3 TB + +The ICs' md5 checksums are: + +c6134185aaa536d695d290e7b7a75f6f PMill-384.hdf5 +f20a8c446e24444df55daaea2163f233 PMill-768.hdf5 +bfaad140062f475c120002a76dd83f01 PMill-1536.hdf5 +59bd72f821e5f5a117a5c2ed23056f9e PMill-3072.hdf5 diff --git a/examples/main.c b/examples/main.c index 718ec881d36d9503dd781367b7de7424fe33d9a0..005adf125891e88689eb5a42db93a537a11ebf08 100644 --- a/examples/main.c +++ b/examples/main.c @@ -985,7 +985,8 @@ int main(int argc, char *argv[]) { /* Initialise the feedback properties */ if (with_feedback) { #ifdef FEEDBACK_NONE - error("ERROR: Running with feedback but compiled without it."); + if (!with_rt) + error("ERROR: Running with feedback but compiled without it."); #endif feedback_props_init(&feedback_properties, &prog_const, &us, params, &hydro_properties, &cosmo); @@ -1034,8 +1035,8 @@ int main(int argc, char *argv[]) { #ifdef STAR_FORMATION_NONE error("ERROR: Running with star formation but compiled without it!"); #endif - starformation_init(params, &prog_const, &us, &hydro_properties, - &starform); + starformation_init(params, &prog_const, &us, &hydro_properties, &cosmo, + &entropy_floor, &starform); } if (with_star_formation && myrank == 0) starformation_print(&starform); diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 8a3d17986968cb5577a36f82d166c493434ed997..66bcfefc8d0eb1b9e603bec0c39ffd8272ed80d2 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -460,7 +460,8 @@ GEARChemistry: # EAGLE star formation model (Schaye and Dalla Vecchia 2008) EAGLEStarFormation: - SF_model: SchmidtLaw # "SchmidtLaw" or "PressureLaw". + SF_threshold: Subgrid # Zdep (Schaye 2004) or Subgrid + SF_model: PressureLaw # PressureLaw (Schaye et al. 2008) or SchmidtLaw star_formation_efficiency: 0.01 # In the SchmidtLaw model this regulates the star formation efficiency per free-fall time. KS_normalisation: 1.515e-4 # In the PressureLaw model, normalization of the Kennicutt-Schmidt law in Msun / kpc^2 / yr. KS_exponent: 1.4 # In the PressureLaw model, exponent of the Kennicutt-Schmidt law. @@ -468,15 +469,14 @@ EAGLEStarFormation: KS_high_density_exponent: 2.0 # In the PressureLaw model, Slope of the Kennicut-Schmidt law above the high-density threshold. gas_fraction: 0.25 # (Optional) In the PressureLaw model, The gas fraction used internally by the model (Defaults to 1). density_direct_H_p_cm3: 1e5 # (Optional) Density above which a gas particle gets automatically turned into a star in Hydrogen atoms per cm^3 (Defaults to FLT_MAX). - EOS_density_norm_H_p_cm3: 0.1 # Physical density used for the normalisation of the EoS assumed for the star-forming gas in Hydrogen atoms per cm^3. - EOS_temperature_norm_K: 8000 # Temperature om the polytropic EoS assumed for star-forming gas at the density normalisation in Kelvin. - EOS_gamma_effective: 1.3333333 # Slope the of the polytropic EoS assumed for the star-forming gas. - EOS_entropy_margin_dex: 0.5 # (Optional) Logarithm base 10 of the maximal entropy above the EoS at which stars can form. - min_over_density: 57.7 # Over-density above which star-formation is allowed. - threshold_norm_H_p_cm3: 0.1 # Normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. - threshold_Z0: 0.002 # Reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. - threshold_slope: -0.64 # Slope of the metal-dependant star formation threshold - threshold_max_density_H_p_cm3: 10.0 # Maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + EOS_entropy_margin_dex: 0.3 # When using Z-based SF threshold, logarithm base 10 of the maximal entropy above the EOS at which stars can form. + threshold_norm_H_p_cm3: 0.1 # When using Z-based SF threshold, normalisation of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_Z0: 0.002 # When using Z-based SF threshold, reference metallicity (metal mass fraction) for the metal-dependant threshold for star formation. + threshold_slope: -0.64 # When using Z-based SF threshold, slope of the metal-dependant star formation threshold + threshold_max_density_H_p_cm3: 10.0 # When using Z-based SF threshold, maximal density of the metal-dependant density threshold for star formation in Hydrogen atoms per cm^3. + threshold_temperature1_K: 1000 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming. + threshold_temperature2_K: 31622 # When using subgrid-based SF threshold, subgrid temperature below which gas is star-forming if also above the density limit. + threshold_number_density_H_p_cm3: 10 # When using subgrid-based SF threshold, subgrid number density above which gas is star-forming if also below the second temperature limit. # Quick Lyman-alpha star formation parameters QLAStarFormation: @@ -504,6 +504,7 @@ EAGLEFeedback: IMF_max_mass_Msun: 100.0 # Maximal stellar mass considered for the Chabrier IMF in solar masses. SNII_min_mass_Msun: 6.0 # Minimal mass considered for SNII stars in solar masses. SNII_max_mass_Msun: 100.0 # Maximal mass considered for SNII stars in solar masses. + SNII_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity SNII_sampled_delay: 1 # Sample the SNII lifetimes to do feedback. SNII_wind_delay_Gyr: 0.03 # Time in Gyr between a star's birth and the SNII thermal feedback event when not sampling. SNII_delta_T_K: 3.16228e7 # Change in temperature to apply to the gas particle in a SNII thermal feedback event in Kelvin. @@ -552,8 +553,8 @@ EAGLEAGN: subgrid_seed_mass_Msun: 1.5e5 # Black hole subgrid mass at creation time in solar masses. use_subgrid_mass_from_ics: 1 # (Optional) Use subgrid masses specified in ICs [1, default], or initialise them to particle masses [0]? with_subgrid_mass_check: 1 # (Optional) Verify that initial black hole subgrid masses are positive [1, default]. Only used if use_subgrid_mass_from_ics is 1. - multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? - subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? + use_multi_phase_bondi: 0 # Compute Bondi rates per neighbour particle? + use_subgrid_bondi: 0 # Compute Bondi rates using the subgrid extrapolation of the gas properties around the BH? with_angmom_limiter: 1 # Are we applying the Rosas-Guevara et al. (2015) viscous time-scale reduction term? viscous_alpha: 1e6 # Normalisation constant of the viscous time-scale in the accretion reduction term with_boost_factor: 0 # Are we using the model from Booth & Schaye (2009)? @@ -566,7 +567,9 @@ EAGLEAGN: use_nibbling: 0 # Continuously transfer small amounts of mass from all gas neighbours to a black hole [1] or stochastically swallow whole gas particles [0]? 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. + AGN_feedback_model: Random # Feedback modes: Random, Isotropic, MinimumDistance, MinimumDensity + AGN_use_deterministic_feedback: 0 # Deterministic (reservoir) [1] or stochastic [0] AGN feedback? + AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin, this is used for the constant AGN model, for the mass dependend heating model we use this as an initialization value for the IC and birth properties of the BHs 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). diff --git a/logger/logger_tools.h b/logger/logger_tools.h index 968fc41a81f27cc8f8a0aece897bf0fcc73fcc67..1b5a031019d2cd0dbdf05d46fc56d52615588ec7 100644 --- a/logger/logger_tools.h +++ b/logger/logger_tools.h @@ -79,7 +79,7 @@ float logger_tools_cubic_hermite_spline(double t0, float v0, float a0, double t); #ifndef HAVE_PYTHON -#define error_python(...) error(##__VA_ARGS__); +#define error_python(s, ...) error(s, ##__VA_ARGS__); #else /** * @brief Print the python trace back diff --git a/src/Makefile.am b/src/Makefile.am index b75d8cf5bde1779539002c9f398309472c9857bc..f1558a1504b352752f57c1b1946e3ab380ace12d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -61,6 +61,8 @@ include_HEADERS += velociraptor_struct.h velociraptor_io.h random.h memuse.h mpi include_HEADERS += black_holes.h black_holes_io.h black_holes_properties.h black_holes_struct.h include_HEADERS += feedback.h feedback_struct.h feedback_properties.h include_HEADERS += space_unique_id.h line_of_sight.h io_compression.h +include_HEADERS += rays.h rays_struct.h +include_HEADERS += logger_history.h # source files for EAGLE cooling QLA_COOLING_SOURCES = @@ -125,7 +127,7 @@ AM_SOURCES += gravity_properties.c gravity.c multipole.c AM_SOURCES += collectgroup.c hydro_space.c equation_of_state.c io_compression.c AM_SOURCES += chemistry.c cosmology.c mesh_gravity.c velociraptor_interface.c AM_SOURCES += output_list.c velociraptor_dummy.c logger_io.c memuse.c mpiuse.c memuse_rnodes.c fof.c -AM_SOURCES += hashmap.c pressure_floor.c +AM_SOURCES += hashmap.c pressure_floor.c logger_history.c AM_SOURCES += $(QLA_COOLING_SOURCES) AM_SOURCES += $(EAGLE_COOLING_SOURCES) $(EAGLE_FEEDBACK_SOURCES) AM_SOURCES += $(GRACKLE_COOLING_SOURCES) $(GEAR_FEEDBACK_SOURCES) diff --git a/src/atomic.h b/src/atomic.h index 164b73a5b169fa621a1f4192882a87f686808479..d5f2da40595d2896eb43934bca2409df4f73d15f 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -179,7 +179,7 @@ __attribute__((always_inline)) INLINE static void atomic_max( __attribute__((always_inline)) INLINE static void atomic_max_ll( volatile long long *const address, const long long y) { - int test_val, old_val, new_val; + long long test_val, old_val, new_val; old_val = *address; do { diff --git a/src/black_holes/Default/black_holes.h b/src/black_holes/Default/black_holes.h index 726d9e0db2d8ad7d709535cf22184cd569ca14a7..cab7aa70c744881f0bd54b759005a5a824800c37 100644 --- a/src/black_holes/Default/black_holes.h +++ b/src/black_holes/Default/black_holes.h @@ -38,7 +38,7 @@ */ __attribute__((always_inline)) INLINE static float black_holes_compute_timestep( const struct bpart* const bp, const struct black_holes_props* props, - const struct phys_const* constants) { + const struct phys_const* constants, const struct cosmology* cosmo) { return FLT_MAX; } @@ -224,7 +224,7 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( const struct phys_const* constants, const struct cosmology* cosmo, const struct cooling_function_data* cooling, const struct entropy_floor_properties* floor_props, const double time, - const int with_cosmology, const double dt) {} + const int with_cosmology, const double dt, const integertime_t ti_begin) {} /** * @brief Finish the calculation of the new BH position. diff --git a/src/black_holes/EAGLE/black_holes.h b/src/black_holes/EAGLE/black_holes.h index 13483ec4ad048a7dd920c5142d3f25cbc57f66bf..c94f8bb0d8bfa687809c9842d28ab28bc9a10781 100644 --- a/src/black_holes/EAGLE/black_holes.h +++ b/src/black_holes/EAGLE/black_holes.h @@ -29,6 +29,8 @@ #include "kernel_hydro.h" #include "minmax.h" #include "physical_constants.h" +#include "random.h" +#include "rays.h" /* Standard includes */ #include <float.h> @@ -43,7 +45,7 @@ */ __attribute__((always_inline)) INLINE static float black_holes_compute_timestep( const struct bpart* const bp, const struct black_holes_props* props, - const struct phys_const* constants) { + const struct phys_const* constants, const struct cosmology* cosmo) { /* Gather some physical constants (in internal units) */ const double c = constants->const_speed_light_c; @@ -61,9 +63,12 @@ __attribute__((always_inline)) INLINE static float black_holes_compute_timestep( /* Average particle mass in BH's kernel */ const double mean_ngb_mass = bp->ngb_mass / ((double)bp->num_ngbs); + + /* Get the AGN heating temperature that is tored in this BH */ + const double AGN_delta_T = bp->AGN_delta_T; + /* Without multiplying by mean_ngb_mass we'd get energy per unit mass */ - const double E_heat = - props->AGN_delta_T_desired * props->temp_to_u_factor * mean_ngb_mass; + const double E_heat = AGN_delta_T * props->temp_to_u_factor * mean_ngb_mass; /* Compute average time between heating events for the given accretion * rate. The time is multiplied by the number of Ngbs to heat because @@ -127,6 +132,13 @@ __attribute__((always_inline)) INLINE static void black_holes_first_init_bpart( 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 */ + bp->dt_heat = 0.f; + bp->AGN_number_of_AGN_events = 0; + bp->AGN_number_of_energy_injections = 0; + + /* Set the initial targetted heating temperature, used for the + * BH time step determination */ + bp->AGN_delta_T = props->AGN_delta_T_desired; black_holes_mark_bpart_as_not_swallowed(&bp->merger_data); } @@ -169,6 +181,9 @@ __attribute__((always_inline)) INLINE static void black_holes_init_bpart( 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 */ + + /* Reset the rays carried by this BH */ + ray_init(bp->rays, eagle_blackhole_number_of_rays); } /** @@ -403,6 +418,9 @@ __attribute__((always_inline)) INLINE static void black_holes_swallow_part( /* This BH lost a neighbour */ bp->num_ngbs--; bp->ngb_mass -= gas_mass; + + /* The ray(s) should not point to the no-longer existing particle */ + ray_reset_part_id(bp->rays, eagle_blackhole_number_of_rays, p->id); } /** @@ -593,7 +611,7 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( const struct phys_const* constants, const struct cosmology* cosmo, const struct cooling_function_data* cooling, const struct entropy_floor_properties* floor_props, const double time, - const int with_cosmology, const double dt) { + const int with_cosmology, const double dt, const integertime_t ti_begin) { /* Record that the black hole has another active time step */ bp->number_of_time_steps++; @@ -611,6 +629,7 @@ __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) */ @@ -634,7 +653,7 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( /* We can now compute the Bondi accretion rate (internal units) */ double Bondi_rate; - if (props->multi_phase_bondi) { + if (props->use_multi_phase_bondi) { /* In this case, we are in 'multi-phase-Bondi' mode -- otherwise, * the accretion_rate is still zero (was initialised to this) */ @@ -657,7 +676,7 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( gas_v_phys[1] * gas_v_phys[1] + gas_v_phys[2] * gas_v_phys[2]; - if (props->subgrid_bondi) { + if (props->use_subgrid_bondi) { /* Use subgrid rho and c for Bondi model */ @@ -834,61 +853,169 @@ __attribute__((always_inline)) INLINE static void black_holes_prepare_feedback( bp->accreted_angular_momentum[2] += bp->circular_velocity_gas[2] * mass_rate * dt / bp->h; + /* Below we compute energy required to have a feedback event(s) + * Note that we have subtracted the particles we swallowed from the ngb_mass + * and num_ngbs accumulators. */ + /* Now find the temperature increase for a possible feedback event */ 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; + double delta_u = delta_T * props->temp_to_u_factor; 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); + /* 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 mean_ngb_mass = bp->ngb_mass / ((double)bp->num_ngbs); const double E_feedback_event = num_ngbs_to_heat * delta_u_ref * mean_ngb_mass; + /* Compute and store BH accretion-limited time-step */ + if (luminosity > 0.) { + const float dt_acc = delta_u * mean_ngb_mass * props->num_ngbs_to_heat / + (luminosity * props->epsilon_f); + bp->dt_heat = max(dt_acc, props->time_step_min); + } else { + bp->dt_heat = FLT_MAX; + } + /* Are we doing some feedback? */ if (bp->energy_reservoir > E_feedback_event) { - /* Default probability of heating */ - double target_prob = bp->energy_reservoir / (delta_u * bp->ngb_mass); + int number_of_energy_injections; - /* Calculate the change in internal energy of the gas particles that get - * heated. Adjust the prbability if needed. */ - double gas_delta_u; - double prob; - if (target_prob <= 1.) { + /* How are we doing feedback? */ + if (props->AGN_deterministic) { - /* Normal case */ - prob = target_prob; - gas_delta_u = delta_u; + number_of_energy_injections = + (int)(bp->energy_reservoir / (delta_u * mean_ngb_mass)); } else { - /* Special case: we need to adjust the energy irrespective of the - * desired deltaT to ensure we inject all the available energy. */ + /* Probability of heating. */ + const double prob = bp->energy_reservoir / (delta_u * bp->ngb_mass); + + /* Compute the number of energy injections based on probability */ + if (prob < 1.) { + + /* Initialise counter of energy injections */ + number_of_energy_injections = 0; + + /* How many AGN energy injections will we get? + * + * Note that we use the particles here to draw random numbers. This does + * not mean that the 'lucky' particles here are the ones that will be + * heated. If we get N lucky particles, we will use the first N random + * ray directions in the isotropic case or the first N closest particles + * in the other modes. */ + for (int i = 0; i < bp->num_ngbs; i++) { + const double rand = random_unit_interval_part_ID_and_ray_idx( + bp->id, i, ti_begin, random_number_BH_feedback); + + /* Increase the counter if we are lucky */ + if (rand < prob) number_of_energy_injections++; + } + + } else { - prob = 1.; - gas_delta_u = bp->energy_reservoir / bp->ngb_mass; + /* We want to use up all energy avaliable in the reservoir. Therefore, + * number_of_energy_injections is > or = props->num_ngbs_to_heat */ + number_of_energy_injections = + (int)(bp->energy_reservoir / (delta_u * mean_ngb_mass)); + } } - /* Store all of this in the black hole for delivery onto the gas. */ - bp->to_distribute.AGN_heating_probability = prob; - bp->to_distribute.AGN_delta_u = gas_delta_u; + /* Maximum number of energy injections allowed */ + const int N_energy_injections_allowed = + min(eagle_blackhole_number_of_rays, bp->num_ngbs); + + /* If there are more energy-injection events than min(the number of Ngbs in + * the kernel, maximum number of rays) then lower the number of events & + * proportionally increase the energy per event */ + if (number_of_energy_injections > N_energy_injections_allowed) { + + /* Increase the thermal energy per event */ + const double alpha_thermal = (double)number_of_energy_injections / + (double)N_energy_injections_allowed; + + delta_u *= alpha_thermal; + + /* Lower the maximum number of events to the max allowed value */ + number_of_energy_injections = N_energy_injections_allowed; + } - /* Decrement the energy in the reservoir by the mean expected energy */ - const double energy_used = bp->energy_reservoir / max(prob, 1.); - bp->energy_reservoir -= energy_used; + /* Compute how much energy will be deposited onto the gas */ + /* Note that it will in general be different from E_feedback_event if + * gas particles are of different mass. */ + double Energy_deposited = 0.0; + + /* Count the number of unsuccessful energy injections (e.g., if the particle + * that the BH wants to heat has been swallowed and thus no longer exists) + */ + int N_unsuccessful_energy_injections = 0; + + for (int i = 0; i < number_of_energy_injections; i++) { + + /* If the gas particle that the BH wants to heat has just been swallowed + * by the same BH, increment the counter of unsuccessful injections. If + * the particle has not been swallowed by the BH, increase the energy that + * will later be subtracted from the BH's energy reservoir. */ + if (bp->rays[i].id_min_length != -1) + Energy_deposited += delta_u * bp->rays[i].mass; + else + N_unsuccessful_energy_injections++; + } + + /* Store all of this in the black hole for delivery onto the gas. */ + bp->to_distribute.AGN_delta_u = delta_u; + bp->to_distribute.AGN_number_of_energy_injections = + number_of_energy_injections; + + /* Subtract the deposited energy from the BH energy reservoir. Note + * that in the stochastic case, the resulting value might be negative. + * This happens when (due to the probabilistic nature of the model) the + * BH injects more energy than it actually has in the reservoir. */ + bp->energy_reservoir -= Energy_deposited; + + /* Total number successful energy injections at this time-step. In each + * energy injection, a certain gas particle from the BH's kernel gets + * heated. (successful = the particle(s) that is going to get heated by + * this BH has not been swallowed by the same BH). */ + const int N_successful_energy_injections = + number_of_energy_injections - N_unsuccessful_energy_injections; + + /* Increase the number of energy injections the black hole has heated so + * far. Note that in the isotropic model, a gas particle may receive AGN + * energy several times at the same time-step. In this case, the number of + * particles heated at this time-step for this BH will be smaller than the + * total number of energy injections for this BH. */ + bp->AGN_number_of_energy_injections += N_successful_energy_injections; + + /* Increase the number of AGN events the black hole has had so far. + * If the BH does feedback, the number of AGN events is incremented by one. + */ + bp->AGN_number_of_AGN_events += N_successful_energy_injections > 0; + + /* Update the total (cumulative) energy used for gas heating in AGN feedback + * by this BH */ + bp->AGN_cumulative_energy += Energy_deposited; + + /* Store the time/scale factor when the BH last did AGN feedback */ + if (N_successful_energy_injections) { + if (with_cosmology) { + bp->last_AGN_event_scale_factor = cosmo->a; + } else { + bp->last_AGN_event_time = time; + } + } } else { /* Flag that we don't want to heat anyone */ - bp->to_distribute.AGN_heating_probability = 0.f; + bp->to_distribute.AGN_number_of_energy_injections = 0; bp->to_distribute.AGN_delta_u = 0.f; } } @@ -1012,8 +1139,8 @@ __attribute__((always_inline)) INLINE static void black_holes_end_reposition( __attribute__((always_inline)) INLINE static void black_holes_reset_feedback( struct bpart* restrict bp) { - bp->to_distribute.AGN_heating_probability = 0.f; bp->to_distribute.AGN_delta_u = 0.f; + bp->to_distribute.AGN_number_of_energy_injections = 0; #ifdef DEBUG_INTERACTIONS_BLACK_HOLES for (int i = 0; i < MAX_NUM_OF_NEIGHBOURS_STARS; ++i) @@ -1111,6 +1238,10 @@ INLINE static void black_holes_create_from_gas( bp->last_minor_merger_time = -1.; bp->last_major_merger_time = -1.; + /* Set the initial targetted heating temperature, used for the + * BH time step determination */ + bp->AGN_delta_T = props->AGN_delta_T_desired; + /* First initialisation */ black_holes_init_bpart(bp); diff --git a/src/black_holes/EAGLE/black_holes_iact.h b/src/black_holes/EAGLE/black_holes_iact.h index 4f060428ae6f926be2e4d614b5b90fc5caa68e30..1cf60a80d00490afd67d0363d50f3c54edc4128c 100644 --- a/src/black_holes/EAGLE/black_holes_iact.h +++ b/src/black_holes/EAGLE/black_holes_iact.h @@ -24,6 +24,7 @@ #include "gravity.h" #include "hydro.h" #include "random.h" +#include "rays.h" #include "space.h" #include "timestep_sync_part.h" #include "tracers.h" @@ -108,7 +109,7 @@ runner_iact_nonsym_bh_gas_density( bi->circular_velocity_gas[1] += mj * wi * (dx[2] * dv[0] - dx[0] * dv[2]); bi->circular_velocity_gas[2] += mj * wi * (dx[0] * dv[1] - dx[1] * dv[0]); - if (bh_props->multi_phase_bondi) { + if (bh_props->use_multi_phase_bondi) { /* Contribution to BH accretion rate * * i) Calculate denominator in Bondi formula */ @@ -149,6 +150,88 @@ runner_iact_nonsym_bh_gas_density( /* Update ngb counters */ ++si->num_ngb_density; #endif + + /* Gas particle id */ + const long long gas_id = pj->id; + + /* Choose AGN feedback model */ + switch (bh_props->feedback_model) { + case AGN_isotropic_model: { + /* Compute arc lengths in AGN isotropic feedback and collect + * relevant data for later use in the feedback_apply loop */ + + /* Loop over rays */ + for (int i = 0; i < eagle_blackhole_number_of_rays; i++) { + + /* We generate two random numbers that we use + to randomly select the direction of the ith ray */ + + /* Random number in [0, 1[ */ + const double rand_theta = random_unit_interval_part_ID_and_ray_idx( + bi->id, i, ti_current, + random_number_isotropic_AGN_feedback_ray_theta); + + /* Random number in [0, 1[ */ + const double rand_phi = random_unit_interval_part_ID_and_ray_idx( + bi->id, i, ti_current, + random_number_isotropic_AGN_feedback_ray_phi); + + /* Compute arc length */ + ray_minimise_arclength(dx, r, bi->rays + i, /*switch=*/-1, gas_id, + rand_theta, rand_phi, pj->mass, /*ray_ext=*/NULL, + /*v=*/NULL); + } + break; + } + case AGN_minimum_distance_model: { + /* Compute the size of the array that we want to sort. If the current + * function is called for the first time (at this time-step for this BH), + * then bi->num_ngbs = 1 and there is nothing to sort. Note that the + * maximum size of the sorted array cannot be larger then the maximum + * number of rays. */ + const int arr_size = min(bi->num_ngbs, eagle_blackhole_number_of_rays); + + /* Minimise separation between the gas particles and the BH. The rays + * structs with smaller ids in the ray array will refer to the particles + * with smaller distances to the BH. */ + ray_minimise_distance(r, bi->rays, arr_size, gas_id, pj->mass); + break; + } + case AGN_minimum_density_model: { + /* Compute the size of the array that we want to sort. If the current + * function is called for the first time (at this time-step for this BH), + * then bi->num_ngbs = 1 and there is nothing to sort. Note that the + * maximum size of the sorted array cannot be larger then the maximum + * number of rays. */ + const int arr_size = min(bi->num_ngbs, eagle_blackhole_number_of_rays); + + /* Minimise separation between the gas particles and the BH. The rays + * structs with smaller ids in the ray array will refer to the particles + * with smaller distances to the BH. */ + ray_minimise_distance(pj->rho, bi->rays, arr_size, gas_id, pj->mass); + break; + } + case AGN_random_ngb_model: { + /* Compute the size of the array that we want to sort. If the current + * function is called for the first time (at this time-step for this BH), + * then bi->num_ngbs = 1 and there is nothing to sort. Note that the + * maximum size of the sorted array cannot be larger then the maximum + * number of rays. */ + const int arr_size = min(bi->num_ngbs, eagle_blackhole_number_of_rays); + + /* To mimic a random draw among all the particles in the kernel, we + * draw random distances in [0,1) and then pick the particle(s) with + * the smallest of these 'fake' distances */ + const float dist = random_unit_interval_two_IDs( + bi->id, pj->id, ti_current, random_number_BH_feedback); + + /* Minimise separation between the gas particles and the BH. The rays + * structs with smaller ids in the ray array will refer to the particles + * with smaller 'fake' distances to the BH. */ + ray_minimise_distance(dist, bi->rays, arr_size, gas_id, pj->mass); + break; + } + } } /** @@ -288,6 +371,11 @@ runner_iact_nonsym_bh_gas_swallow(const float r2, const float *dx, excess_fraction; } + /* Correct for nibbling the particle mass that is stored in rays */ + for (int i = 0; i < eagle_blackhole_number_of_rays; i++) { + if (bi->rays[i].id_min_length == pj->id) bi->rays[i].mass = new_gas_mass; + } + /* Transfer (dynamical) mass from the gas particle to the BH */ bi->mass += nibble_mass; hydro_set_mass(pj, new_gas_mass); @@ -551,22 +639,34 @@ runner_iact_nonsym_bh_gas_feedback(const float r2, const float *dx, const integertime_t ti_current, const double time) { - /* Get the heating probability */ - const float prob = bi->to_distribute.AGN_heating_probability; + /* Number of energy injections per BH per time-step */ + const int num_energy_injections_per_BH = + bi->to_distribute.AGN_number_of_energy_injections; /* Are we doing some feedback? */ - if (prob > 0.f) { + if (num_energy_injections_per_BH > 0) { - /* Draw a random number (Note mixing both IDs) */ - const float rand = random_unit_interval(bi->id + pj->id, ti_current, - random_number_BH_feedback); + /* Number of energy injections that have reached this gas particle */ + int num_of_energy_inj_received_by_gas = 0; - /* Are we lucky? */ - if (rand < prob) { + /* Find out how many rays (= energy injections) this gas particle + * has received */ + for (int i = 0; i < num_energy_injections_per_BH; i++) { + if (pj->id == bi->rays[i].id_min_length) + num_of_energy_inj_received_by_gas++; + } + + /* If the number of received rays is non-zero, inject + * AGN energy in thermal form */ + if (num_of_energy_inj_received_by_gas > 0) { - /* Compute new energy per unit mass of this particle */ + /* Compute new energy per unit mass of this particle + * The energy the particle receives is proportional to the number of rays + * (num_of_energy_inj_received_by_gas) to which the particle was found to + * be closest. */ const double u_init = hydro_get_physical_internal_energy(pj, xpj, cosmo); - const float delta_u = bi->to_distribute.AGN_delta_u; + const float delta_u = bi->to_distribute.AGN_delta_u * + (float)num_of_energy_inj_received_by_gas; const double u_new = u_init + delta_u; hydro_set_physical_internal_energy(pj, xpj, cosmo, u_new); @@ -583,7 +683,7 @@ runner_iact_nonsym_bh_gas_feedback(const float r2, const float *dx, /* message( */ /* "We did some AGN heating! id %llu BH id %llu probability " */ /* " %.5e random_num %.5e du %.5e du/ini %.5e", */ - /* pj->id, bi->id, prob, rand, delta_u, delta_u / u_init); */ + /* pj->id, bi->id, 0.f, 0.f, delta_u, delta_u / u_init); */ /* Synchronize the particle on the timeline */ timestep_sync_part(pj); diff --git a/src/black_holes/EAGLE/black_holes_io.h b/src/black_holes/EAGLE/black_holes_io.h index 2ad9232d2756e4f6ff9900e969063510f89fb680..4e788cd677d70740e8388c9e6aeb2b3ef614e3ec 100644 --- a/src/black_holes/EAGLE/black_holes_io.h +++ b/src/black_holes/EAGLE/black_holes_io.h @@ -152,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 = 38; + *num_fields = 42; /* List what we want to write */ list[0] = io_make_output_field_convert_bpart( @@ -374,25 +374,59 @@ INLINE static void black_holes_write_particles(const struct bpart* bparts, "simulation has been run without prescribed repositioning speed."); list[34] = io_make_output_field( + "NumberOfHeatingEvents", INT, 1, UNIT_CONV_NO_UNITS, 0.f, bparts, + AGN_number_of_energy_injections, + "Integer number of (thermal) energy injections the black hole has had " + "so far"); + + list[35] = io_make_output_field( + "NumberOfAGNEvents", INT, 1, UNIT_CONV_NO_UNITS, 0.f, bparts, + AGN_number_of_AGN_events, + "Integer number of AGN events the black hole has had so far" + " (the number of times the BH did AGN feedback)"); + + if (with_cosmology) { + list[36] = io_make_output_field( + "LastAGNFeedbackScaleFactors", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, + bparts, last_AGN_event_scale_factor, + "Scale-factors at which the black holes last had an AGN event."); + } else { + list[36] = io_make_output_field( + "LastAGNFeedbackTimes", FLOAT, 1, UNIT_CONV_TIME, 0.f, bparts, + last_AGN_event_time, + "Times at which the black holes last had an AGN event."); + } + + list[37] = io_make_output_field( + "AccretionLimitedTimeSteps", FLOAT, 1, UNIT_CONV_TIME, 0.f, bparts, + dt_heat, "Accretion-limited time-steps of black holes."); + + list[38] = io_make_output_field( + "AGNTotalInjectedEnergies", FLOAT, 1, UNIT_CONV_ENERGY, 0.f, bparts, + AGN_cumulative_energy, + "Total (cumulative) physical energies injected into gas particles " + "in AGN feedback."); + + list[39] = 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( + list[40] = 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( + list[41] = 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( + list[42] = 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. " diff --git a/src/black_holes/EAGLE/black_holes_part.h b/src/black_holes/EAGLE/black_holes_part.h index 0be3e8fc86f81af77d103a8f88e674e95a89cb89..93c9b813a3de97e9436630e267d319539590becc 100644 --- a/src/black_holes/EAGLE/black_holes_part.h +++ b/src/black_holes/EAGLE/black_holes_part.h @@ -19,6 +19,9 @@ #ifndef SWIFT_EAGLE_BLACK_HOLE_PART_H #define SWIFT_EAGLE_BLACK_HOLE_PART_H +/*! The total number of rays used in AGN feedback */ +#define eagle_blackhole_number_of_rays 50 + #include "black_holes_struct.h" #include "chemistry_struct.h" #include "timeline.h" @@ -175,6 +178,33 @@ struct bpart { /*! Eddington fractions */ float eddington_fraction; + /*! Integer (cumulative) number of energy injections in AGN feedback. At a + * given time-step, an AGN-active BH may produce multiple energy injections. + * The number of energy injections is equal to or more than the number of + * particles heated by the BH during this time-step. */ + int AGN_number_of_energy_injections; + + /*! Integer (cumulative) number of AGN events. If a BH does feedback at a + * given time-step, the number of its AGN events is incremented by 1. Each + * AGN event may have multiple energy injections. */ + int AGN_number_of_AGN_events; + + /* Total energy injected into the gas in AGN feedback by this BH */ + float AGN_cumulative_energy; + + /*! BH accretion-limited time-step */ + float dt_heat; + + /*! Union for the last AGN event time and the last AGN event scale factor */ + union { + + /*! Last AGN event time */ + float last_AGN_event_time; + + /*! Last AGN event scale-factor */ + float last_AGN_event_scale_factor; + }; + /*! Union for the last high Eddington ratio point in time */ union { @@ -208,8 +238,8 @@ struct bpart { /*! Properties used in the feedback loop to distribute to gas neighbours. */ struct { - /*! Probability of heating neighbouring gas particles for AGN feedback */ - float AGN_heating_probability; + /*! Number of energy injections per time-step */ + int AGN_number_of_energy_injections; /*! Change in energy from SNII feedback energy injection */ float AGN_delta_u; @@ -236,6 +266,9 @@ struct bpart { /*! Black holes merger information (e.g. merging ID) */ struct black_holes_bpart_data merger_data; + /*! Isotropic AGN feedback information */ + struct ray_data rays[eagle_blackhole_number_of_rays]; + #ifdef SWIFT_DEBUG_CHECKS /* Time of the last drift */ diff --git a/src/black_holes/EAGLE/black_holes_properties.h b/src/black_holes/EAGLE/black_holes_properties.h index 5060cad4ae950ecbac3b75beba73beb121ef999d..5f86bedf34d2bdab0ab66a785c0565e5710d08e1 100644 --- a/src/black_holes/EAGLE/black_holes_properties.h +++ b/src/black_holes/EAGLE/black_holes_properties.h @@ -19,9 +19,26 @@ #ifndef SWIFT_EAGLE_BLACK_HOLES_PROPERTIES_H #define SWIFT_EAGLE_BLACK_HOLES_PROPERTIES_H +/* Config parameters. */ +#include "../config.h" + +/* Local includes. */ #include "chemistry.h" #include "hydro_properties.h" +/* Includes. */ +#include <string.h> + +/** + * @brief Modes of energy injection for AGN feedback + */ +enum AGN_feedback_models { + AGN_random_ngb_model, /*< Random neighbour model for AGN feedback */ + AGN_isotropic_model, /*< Isotropic model of AGN feedback */ + AGN_minimum_distance_model, /*< Minimum-distance model of AGN feedback */ + AGN_minimum_density_model /*< Minimum-density model of AGN feedback */ +}; + /** * @brief Properties of black holes and AGN feedback in the EAGEL model. */ @@ -61,10 +78,10 @@ struct black_holes_props { /* ----- Properties of the accretion model ------ */ /*! Calculate Bondi accretion rate for individual neighbours? */ - int multi_phase_bondi; + int use_multi_phase_bondi; /*! Are we using the subgrid gas properties in the Bondi model? */ - int subgrid_bondi; + int use_subgrid_bondi; /*! Are we applying the angular-momentum-based multiplicative term from * Rosas-Guevara et al. (2015)? */ @@ -106,10 +123,18 @@ struct black_holes_props { /* ---- Properties of the feedback model ------- */ + /*! AGN feedback model: random, isotropic or minimum distance */ + enum AGN_feedback_models feedback_model; + + /*! Is the AGN feedback model deterministic or stochastic? */ + int AGN_deterministic; + /*! Feedback coupling efficiency of the black holes. */ float epsilon_f; - /*! (Constant) temperature increase induced by AGN feedback [Kelvin] */ + /*! (Constant) temperature increase induced by AGN feedback [Kelvin], if we + * use a model with a variable temperature increase than we use this value + * to initialize a BH that just has formed */ float AGN_delta_T_desired; /*! Switch on adaptive heating temperature scheme? */ @@ -292,12 +317,13 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, /* Accretion parameters ---------------------------------- */ - bp->multi_phase_bondi = - parser_get_param_int(params, "EAGLEAGN:multi_phase_bondi"); + bp->use_multi_phase_bondi = + parser_get_param_int(params, "EAGLEAGN:use_multi_phase_bondi"); - bp->subgrid_bondi = parser_get_param_int(params, "EAGLEAGN:subgrid_bondi"); + bp->use_subgrid_bondi = + parser_get_param_int(params, "EAGLEAGN:use_subgrid_bondi"); - if (bp->multi_phase_bondi && bp->subgrid_bondi) + if (bp->use_multi_phase_bondi && bp->use_subgrid_bondi) error( "Cannot run with both the multi-phase Bondi and subgrid Bondi models " "at the same time!"); @@ -345,12 +371,37 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, /* Feedback parameters ---------------------------------- */ + char temp[40]; + parser_get_param_string(params, "EAGLEAGN:AGN_feedback_model", temp); + if (strcmp(temp, "Random") == 0) + bp->feedback_model = AGN_random_ngb_model; + else if (strcmp(temp, "Isotropic") == 0) + bp->feedback_model = AGN_isotropic_model; + else if (strcmp(temp, "MinimumDistance") == 0) + bp->feedback_model = AGN_minimum_distance_model; + else if (strcmp(temp, "MinimumDensity") == 0) + bp->feedback_model = AGN_minimum_density_model; + else + error( + "The AGN feedback model must be either 'Random', 'MinimumDistance', " + "'MinimumDensity' or 'Isotropic', not %s", + temp); + + bp->AGN_deterministic = + parser_get_param_int(params, "EAGLEAGN:AGN_use_deterministic_feedback"); + bp->epsilon_f = parser_get_param_float(params, "EAGLEAGN:coupling_efficiency"); const double T_K_to_int = 1. / units_cgs_conversion_factor(us, UNIT_CONV_TEMPERATURE); + /* Read the constant AGN heating temperature or the the initial value + * for the IC or new BH that formed from gas */ + bp->AGN_delta_T_desired = + parser_get_param_float(params, "EAGLEAGN:AGN_delta_T_K"); + + /* Read the properties of the variable heating temperature model */ bp->use_variable_delta_T = parser_get_param_int(params, "EAGLEAGN:use_variable_delta_T"); if (bp->use_variable_delta_T) { @@ -378,16 +429,7 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, 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) { diff --git a/src/cell_drift.c b/src/cell_drift.c index 91292a8742924302b115931968b3ae4e86707b04..2eeb84c7ab066ac7806e6933dd873d37ceb2b520 100644 --- a/src/cell_drift.c +++ b/src/cell_drift.c @@ -182,9 +182,8 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) { #ifdef WITH_LOGGER if (e->policy & engine_policy_logger) { /* Log the particle one last time. */ - logger_log_part( - e->logger, p, xp, e, /* log_all */ 1, - logger_pack_flags_and_data(logger_flag_delete, 0)); + logger_log_part(e->logger, p, xp, e, /* log_all */ 1, + logger_flag_delete, /* data */ 0); } #endif @@ -233,6 +232,7 @@ void cell_drift_part(struct cell *c, const struct engine *e, int force) { with_cosmology, e->cosmology, e->hydro_properties, e->cooling_func, e->time); rt_init_part(p); + rt_reset_part(p); } } @@ -363,9 +363,8 @@ void cell_drift_gpart(struct cell *c, const struct engine *e, int force) { #ifdef WITH_LOGGER if (e->policy & engine_policy_logger) { /* Log the particle one last time. */ - logger_log_gpart( - e->logger, gp, e, /* log_all */ 1, - logger_pack_flags_and_data(logger_flag_delete, 0)); + logger_log_gpart(e->logger, gp, e, /* log_all */ 1, + logger_flag_delete, /* data */ 0); } #endif @@ -514,9 +513,8 @@ void cell_drift_spart(struct cell *c, const struct engine *e, int force) { #ifdef WITH_LOGGER if (e->policy & engine_policy_logger) { /* Log the particle one last time. */ - logger_log_spart( - e->logger, sp, e, /* log_all */ 1, - logger_pack_flags_and_data(logger_flag_delete, 0)); + logger_log_spart(e->logger, sp, e, /* log_all */ 1, + logger_flag_delete, /* data */ 0); } #endif diff --git a/src/chemistry/EAGLE/chemistry.h b/src/chemistry/EAGLE/chemistry.h index 4d7c37800d7d578c0ce7501e9c8f9a5ae447ff21..cab8916bce17fb5beda5f01ef679bf2fdbdaf0ad 100644 --- a/src/chemistry/EAGLE/chemistry.h +++ b/src/chemistry/EAGLE/chemistry.h @@ -603,7 +603,7 @@ chemistry_get_total_metal_mass_for_stats(const struct part* restrict p) { * @brief Returns the total metallicity (metal mass fraction) of the * star particle to be used in the stats related routines. * - * @param p Pointer to the particle data. + * @param sp Pointer to the star particle data. */ __attribute__((always_inline)) INLINE static float chemistry_get_star_total_metal_mass_for_stats(const struct spart* restrict sp) { @@ -615,7 +615,7 @@ chemistry_get_star_total_metal_mass_for_stats(const struct spart* restrict sp) { * @brief Returns the total metallicity (metal mass fraction) of the * black hole particle to be used in the stats related routines. * - * @param p Pointer to the particle data. + * @param bp Pointer to the BH particle data. */ __attribute__((always_inline)) INLINE static float chemistry_get_bh_total_metal_mass_for_stats(const struct bpart* restrict bp) { diff --git a/src/chemistry/GEAR/chemistry.h b/src/chemistry/GEAR/chemistry.h index ef3f0e999c59efbffaa9f03867ef461b189a6943..754d1636ddf9ecf30931e3ecf2db7ad3025822b0 100644 --- a/src/chemistry/GEAR/chemistry.h +++ b/src/chemistry/GEAR/chemistry.h @@ -415,7 +415,7 @@ chemistry_get_metal_mass_fraction_for_feedback(const struct part* restrict p) { * * This is unused in GEAR. --> return 0 * - * @param sp Pointer to the particle data. + * @param p Pointer to the particle data. */ __attribute__((always_inline)) INLINE static float chemistry_get_total_metal_mass_fraction_for_feedback( @@ -519,7 +519,7 @@ chemistry_get_total_metal_mass_for_stats(const struct part* restrict p) { * @brief Returns the total metallicity (metal mass fraction) of the * star particle to be used in the stats related routines. * - * @param p Pointer to the particle data. + * @param sp Pointer to the star particle data. */ __attribute__((always_inline)) INLINE static float chemistry_get_star_total_metal_mass_for_stats(const struct spart* restrict sp) { @@ -533,7 +533,7 @@ chemistry_get_star_total_metal_mass_for_stats(const struct spart* restrict sp) { * @brief Returns the total metallicity (metal mass fraction) of the * black hole particle to be used in the stats related routines. * - * @param p Pointer to the particle data. + * @param bp Pointer to the BH particle data. */ __attribute__((always_inline)) INLINE static float chemistry_get_bh_total_metal_mass_for_stats(const struct bpart* restrict bp) { diff --git a/src/cooling/COLIBRE/cooling.c b/src/cooling/COLIBRE/cooling.c index b4bb935d62cd6c972c90c6c0d4d93e29244fbb2b..0109baf3ea51e08a79a1a29d9ab0709b8f57a074 100644 --- a/src/cooling/COLIBRE/cooling.c +++ b/src/cooling/COLIBRE/cooling.c @@ -1072,6 +1072,30 @@ void cooling_set_particle_subgrid_properties( cooling_compute_subgrid_density); } +/** + * @brief Returns the subgrid temperature of a particle. + * + * @param p The particle. + * @param xp The extended particle data. + * @return The subgrid temperature in internal units. + */ +float cooling_get_subgrid_temperature(const struct part *p, + const struct xpart *xp) { + return p->cooling_data.subgrid_temp; +} + +/** + * @brief Returns the subgrid density of a particle. + * + * @param p The particle. + * @param xp The extended particle data. + * @return The subgrid density in physical internal units. + */ +float cooling_get_subgrid_density(const struct part *p, + const struct xpart *xp) { + return p->cooling_data.subgrid_dens; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/cooling/COLIBRE/cooling.h b/src/cooling/COLIBRE/cooling.h index 94d3e2bdb225737f392e1f154fc7c207581d650a..52208601fdb7c855ee3ad2b9c345970b80fa3de1 100644 --- a/src/cooling/COLIBRE/cooling.h +++ b/src/cooling/COLIBRE/cooling.h @@ -134,6 +134,11 @@ double compute_subgrid_property( const float abundance_ratio[colibre_cooling_N_elementtypes], const double log_u_cgs, const enum cooling_subgrid_properties isub); +float cooling_get_subgrid_temperature(const struct part *p, + const struct xpart *xp); + +float cooling_get_subgrid_density(const struct part *p, const struct xpart *xp); + float cooling_get_radiated_energy(const struct xpart *xp); void cooling_split_part(struct part *p, struct xpart *xp, double n); diff --git a/src/cooling/Compton/cooling.h b/src/cooling/Compton/cooling.h index ca8b428d94324703e3c253ff92faa61fdb3082b5..7b2530c04590e9257f96e8b15c78e0c2915c72a0 100644 --- a/src/cooling/Compton/cooling.h +++ b/src/cooling/Compton/cooling.h @@ -302,6 +302,34 @@ INLINE static float cooling_get_temperature( return T_transition; } +/** + * @brief Returns the subgrid temperature of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_temperature(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + +/** + * @brief Returns the subgrid density of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_density(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/cooling/EAGLE/cooling.c b/src/cooling/EAGLE/cooling.c index 22ff25442496ee4e74b72fd5c46e078def370190..481eca2842ad3056551efe632fe0488b743a1152 100644 --- a/src/cooling/EAGLE/cooling.c +++ b/src/cooling/EAGLE/cooling.c @@ -709,6 +709,34 @@ double compute_subgrid_density( return rho_phys; } +/** + * @brief Returns the subgrid temperature of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +float cooling_get_subgrid_temperature(const struct part *p, + const struct xpart *xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + +/** + * @brief Returns the subgrid density of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +float cooling_get_subgrid_density(const struct part *p, + const struct xpart *xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/cooling/EAGLE/cooling.h b/src/cooling/EAGLE/cooling.h index a851019aeaa23520f42ca060bfedb82840d88e55..960d22d25ba07ddb390804aab1103f9b05cdb238 100644 --- a/src/cooling/EAGLE/cooling.h +++ b/src/cooling/EAGLE/cooling.h @@ -26,6 +26,7 @@ /* Local includes. */ #include "cooling_properties.h" +#include "error.h" struct part; struct xpart; @@ -87,6 +88,11 @@ double compute_subgrid_property( const float *abundance_ratio, const double log_u_cgs, const enum cooling_subgrid_properties isub); +float cooling_get_subgrid_temperature(const struct part *p, + const struct xpart *xp); + +float cooling_get_subgrid_density(const struct part *p, const struct xpart *xp); + float cooling_get_radiated_energy(const struct xpart *restrict xp); void cooling_split_part(struct part *p, struct xpart *xp, double n); diff --git a/src/cooling/QLA/cooling.c b/src/cooling/QLA/cooling.c index 7f321b4d270f8b8395d8daa9ac35e5d7e18fe5de..ebf9d32135e09c006a4db9a9d6bdf290f5b9483d 100644 --- a/src/cooling/QLA/cooling.c +++ b/src/cooling/QLA/cooling.c @@ -685,6 +685,34 @@ __attribute__((always_inline)) INLINE void cooling_first_init_part( const struct cooling_function_data *cooling, struct part *p, struct xpart *xp) {} +/** + * @param Returns the subgrid temperature of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +float cooling_get_subgrid_temperature(const struct part *p, + const struct xpart *xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + +/** + * @param Returns the subgrid density of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +float cooling_get_subgrid_density(const struct part *p, + const struct xpart *xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/cooling/QLA/cooling.h b/src/cooling/QLA/cooling.h index b11acc51f8530d1e03a6bbb4f245ba0af1e68c5b..f62756064ed98214fb586d51c6fd94253f905541 100644 --- a/src/cooling/QLA/cooling.h +++ b/src/cooling/QLA/cooling.h @@ -76,6 +76,11 @@ float cooling_get_temperature(const struct phys_const *phys_const, const struct cooling_function_data *cooling, const struct part *p, const struct xpart *xp); +float cooling_get_subgrid_temperature(const struct part *p, + const struct xpart *xp); + +float cooling_get_subgrid_density(const struct part *p, const struct xpart *xp); + float cooling_get_radiated_energy(const struct xpart *xp); void cooling_split_part(struct part *p, struct xpart *xp, double n); diff --git a/src/cooling/const_du/cooling.h b/src/cooling/const_du/cooling.h index 399db01cf290c3511e0fac63079c401622b1152f..c5b4f4ee28cd12c1267b4298c670e4ae0ad8bef6 100644 --- a/src/cooling/const_du/cooling.h +++ b/src/cooling/const_du/cooling.h @@ -218,6 +218,34 @@ INLINE static float cooling_get_temperature( return T_transition; } +/** + * @brief Returns the subgrid temperature of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_temperature(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + +/** + * @brief Returns the subgrid density of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_density(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/cooling/const_lambda/cooling.h b/src/cooling/const_lambda/cooling.h index 92d11067c5dac5ca2b40b9e68eadc18fed0dae3c..7659177ef797bc2ff3294c8c3af338e647daaea8 100644 --- a/src/cooling/const_lambda/cooling.h +++ b/src/cooling/const_lambda/cooling.h @@ -296,6 +296,34 @@ INLINE static float cooling_get_temperature( return T_transition; } +/** + * @brief Returns the subgrid temperature of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_temperature(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + +/** + * @brief Returns the subgrid density of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_density(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/cooling/grackle/cooling.c b/src/cooling/grackle/cooling.c index 84b9fa4457f5cce15ea0cdb61f530d8548c43ae0..7d4f88a013a0dd7172d126faa2f8e215675a977b 100644 --- a/src/cooling/grackle/cooling.c +++ b/src/cooling/grackle/cooling.c @@ -256,6 +256,34 @@ void cooling_first_init_part(const struct phys_const* restrict phys_const, #endif } +/** + * @brief Returns the subgrid temperature of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_temperature(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + +/** + * @brief Returns the subgrid density of a particle. + * + * This model has no subgrid quantity. We return an error. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_density(const struct part* p, + const struct xpart* xp) { + error("This cooling model does not use subgrid quantities!"); + return -1.f; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/cooling/grackle/cooling.h b/src/cooling/grackle/cooling.h index bdaf0654dd7cd63c9a0e7e320adc07c086a0a3e1..4c58ef8fb1b2cddcfd965cf7a6c90aed2cbbe82d 100644 --- a/src/cooling/grackle/cooling.h +++ b/src/cooling/grackle/cooling.h @@ -68,6 +68,11 @@ void cooling_first_init_part(const struct phys_const* restrict phys_const, const struct part* restrict p, struct xpart* restrict xp); +float cooling_get_subgrid_temperature(const struct part* p, + const struct xpart* xp); + +float cooling_get_subgrid_density(const struct part* p, const struct xpart* xp); + float cooling_get_radiated_energy(const struct xpart* restrict xp); void cooling_print_backend(const struct cooling_function_data* cooling); diff --git a/src/cooling/none/cooling.h b/src/cooling/none/cooling.h index 92cf1fd75855a938b22368ccde2777907b1253fa..518e5f435b49e751a7bd6f0635921479248412ab 100644 --- a/src/cooling/none/cooling.h +++ b/src/cooling/none/cooling.h @@ -167,6 +167,32 @@ INLINE static float cooling_get_temperature( return T_transition; } +/** + * @param Returns the subgrid temperature of a particle. + * + * This model has no subgrid quantity. We return -1. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_temperature(const struct part* p, + const struct xpart* xp) { + return -1.f; +} + +/** + * @param Returns the subgrid density of a particle. + * + * This model has no subgrid quantity. We return -1. + * + * @param p The particle. + * @param xp The extended particle data. + */ +INLINE static float cooling_get_subgrid_density(const struct part* p, + const struct xpart* xp) { + return -1.f; +} + /** * @brief Returns the total radiated energy by this particle. * diff --git a/src/distributed_io.c b/src/distributed_io.c index 3ab6d39a9a519e3fa9440fb275fbc6c868692dd8..f5cf8b3d3ce64a2c7a085fca544b31cb129cdccf 100644 --- a/src/distributed_io.c +++ b/src/distributed_io.c @@ -74,6 +74,7 @@ * the HDF5 file. * @param props The #io_props of the field to read * @param N The number of particles to write. + * @param lossy_compression Level of lossy compression to use for this field. * @param internal_units The #unit_system used internally * @param snapshot_units The #unit_system used in the snapshots * diff --git a/src/dump.c b/src/dump.c index 37b570e68bfcc9685491d45d50254d75d8ab8744..5d2c1ae69194f76e5ebd70e873f7064f0d6e5b33 100644 --- a/src/dump.c +++ b/src/dump.c @@ -173,8 +173,17 @@ void dump_restart(struct dump *d, const char *filename) { error("Failed to open dump file '%s' (%s).", filename, strerror(errno)); } + /* Adjust the size to be at least the page size. */ + const size_t page_mask = ~(sysconf(_SC_PAGE_SIZE) - 1); + size_t size = (d->size + ~page_mask) & page_mask; + + /* Pre-allocate the file size. */ + if (posix_fallocate(d->fd, 0, size) != 0) { + error("Failed to pre-allocate the dump file."); + } + /* Map memory to the created file. */ - if ((d->data = mmap(NULL, d->size, PROT_WRITE, MAP_SHARED, d->fd, + if ((d->data = mmap(NULL, size, PROT_WRITE, MAP_SHARED, d->fd, d->file_offset)) == MAP_FAILED) { error("Failed to allocate map of size %zi bytes (%s).", d->size, strerror(errno)); diff --git a/src/engine.c b/src/engine.c index 71258a75d0da60504dfaf4514ba2d1efc418eca2..de4ca0fe86a72729d37574629599adde34d01410 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1823,6 +1823,11 @@ void engine_init_particles(struct engine *e, int flag_entropy_ICs, engine_launch(e, "tasks"); TIMER_TOC2(timer_runners); + /* Initialise additional RT data now that time bins are set */ + if (e->policy & engine_policy_rt) { + space_convert_rt_quantities(e->s, e->verbose); + } + /* Since the time-steps may have changed because of the limiter's * action, we need to communicate the new time-step sizes */ if ((e->policy & engine_policy_timestep_sync) || @@ -2611,72 +2616,6 @@ void engine_unpin(void) { #endif } -#ifdef SWIFT_DUMPER_THREAD -/** - * @brief dumper thread action, checks got the existence of the .dump file - * every 5 seconds and does the dump if found. - * - * @param p the #engine - */ -static void *engine_dumper_poll(void *p) { - struct engine *e = (struct engine *)p; - while (1) { - if (access(".dump", F_OK) == 0) { - - /* OK, do our work. */ - message("Dumping engine tasks in step: %d", e->step); - task_dump_active(e); - -#ifdef SWIFT_MEMUSE_REPORTS - /* Dump the currently logged memory. */ - message("Dumping memory use report"); - memuse_log_dump_error(e->nodeID); -#endif - -#if defined(SWIFT_MPIUSE_REPORTS) && defined(WITH_MPI) - /* Dump the MPI interactions in the step. */ - mpiuse_log_dump_error(e->nodeID); -#endif - - /* Add more interesting diagnostics. */ - scheduler_dump_queues(e); - - /* Delete the file. */ - unlink(".dump"); - message("Dumping completed"); - fflush(stdout); - } - - /* Take a breath. */ - sleep(5); - } - return NULL; -} -#endif /* SWIFT_DUMPER_THREAD */ - -#ifdef SWIFT_DUMPER_THREAD -/** - * @brief creates the dumper thread. - * - * This watches for the creation of a ".dump" file in the current directory - * and if found dumps the current state of the tasks and memory use (if also - * configured). - * - * @param e the #engine - * - */ -static void engine_dumper_init(struct engine *e) { - pthread_t dumper; - - /* Make sure the .dump file is not present, that is bad when starting up. */ - struct stat buf; - if (stat(".dump", &buf) == 0) unlink(".dump"); - - /* Thread does not exit, so nothing to do but create it. */ - pthread_create(&dumper, NULL, &engine_dumper_poll, e); -} -#endif /* SWIFT_DUMPER_THREAD */ - /** * @brief init an engine struct with the necessary properties for the * simulation. @@ -2926,6 +2865,7 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params, engine_init_output_lists(e, params); } + /** * @brief Prints the current policy of an engine * diff --git a/src/engine_config.c b/src/engine_config.c index d769f99cf5a9a42f4af97006c80618d711fbbf55..e5bdff2572a3498569c0e684a7885548a9fcc6a0 100644 --- a/src/engine_config.c +++ b/src/engine_config.c @@ -35,6 +35,7 @@ /* Local headers. */ #include "fof.h" +#include "mpiuse.h" #include "part.h" #include "proxy.h" #include "star_formation_logger.h" @@ -49,6 +50,72 @@ extern int engine_max_parts_per_cooling; /* Particle cache size. */ #define CACHE_SIZE 512 +#ifdef SWIFT_DUMPER_THREAD +/** + * @brief dumper thread action, checks got the existence of the .dump file + * every 5 seconds and does the dump if found. + * + * @param p the #engine + */ +static void *engine_dumper_poll(void *p) { + struct engine *e = (struct engine *)p; + while (1) { + if (access(".dump", F_OK) == 0) { + + /* OK, do our work. */ + message("Dumping engine tasks in step: %d", e->step); + task_dump_active(e); + +#ifdef SWIFT_MEMUSE_REPORTS + /* Dump the currently logged memory. */ + message("Dumping memory use report"); + memuse_log_dump_error(e->nodeID); +#endif + +#if defined(SWIFT_MPIUSE_REPORTS) && defined(WITH_MPI) + /* Dump the MPI interactions in the step. */ + mpiuse_log_dump_error(e->nodeID); +#endif + + /* Add more interesting diagnostics. */ + scheduler_dump_queues(e); + + /* Delete the file. */ + unlink(".dump"); + message("Dumping completed"); + fflush(stdout); + } + + /* Take a breath. */ + sleep(5); + } + return NULL; +} +#endif /* SWIFT_DUMPER_THREAD */ + +#ifdef SWIFT_DUMPER_THREAD +/** + * @brief creates the dumper thread. + * + * This watches for the creation of a ".dump" file in the current directory + * and if found dumps the current state of the tasks and memory use (if also + * configured). + * + * @param e the #engine + * + */ +static void engine_dumper_init(struct engine *e) { + pthread_t dumper; + + /* Make sure the .dump file is not present, that is bad when starting up. */ + struct stat buf; + if (stat(".dump", &buf) == 0) unlink(".dump"); + + /* Thread does not exit, so nothing to do but create it. */ + pthread_create(&dumper, NULL, &engine_dumper_poll, e); +} +#endif /* SWIFT_DUMPER_THREAD */ + /** * @brief configure an engine with the given number of threads, queues * and core affinity. Also initialises the scheduler and opens various @@ -496,7 +563,7 @@ void engine_config(int restart, int fof, struct engine *e, if ((e->policy & engine_policy_logger) && e->nodeID == 0) message( "WARNING: There is currently no way of predicting the output " - "size, please use it carefully"); + "size, please use the logger carefully"); #endif /* Find the time of the first snapshot output */ diff --git a/src/engine_io.c b/src/engine_io.c index 7d961a96374fa4bec8d0ffaea5ea6a90bbd779aa..12e4d2f8f9be75aed7e3579bb5d97b7dead1f3f4 100644 --- a/src/engine_io.c +++ b/src/engine_io.c @@ -58,8 +58,16 @@ void engine_check_for_index_dump(struct engine *e) { const size_t index_file_size = total_nr_parts * sizeof(struct logger_part_data); + size_t number_part_history = 0; + for (int i = 0; i < swift_type_count; i++) { + number_part_history += + log->history_new[i].size + log->history_removed[i].size; + } + const int history_too_large = number_part_history > log->maximal_size_history; + /* Check if we should write a file */ - if (mem_frac * (dump_size - old_dump_size) > index_file_size) { + if (mem_frac * (dump_size - old_dump_size) > index_file_size || + history_too_large) { /* Write an index file */ engine_dump_index(e); diff --git a/src/engine_maketasks.c b/src/engine_maketasks.c index cb41018a11d228f26cb0516b6bcecffbc369d3ed..88efaa3a3a8c8e71e323ef6f18d85600acc5c2c4 100644 --- a/src/engine_maketasks.c +++ b/src/engine_maketasks.c @@ -3612,10 +3612,17 @@ void engine_maketasks(struct engine *e) { /* Run through the tasks and make force tasks for each density task. Each force task depends on the cell ghosts and unlocks the kick task of its super-cell. */ - if (e->policy & engine_policy_hydro) - threadpool_map(&e->threadpool, engine_make_extra_hydroloop_tasks_mapper, - sched->tasks, sched->nr_tasks, sizeof(struct task), - threadpool_auto_chunk_size, e); + if (e->policy & engine_policy_hydro) { + + /* Note that this does not scale well at all so we do not use the + * threadpool version here until the reason for this is found. + * We call the mapper function directly as if there was only 1 thread + * in the pool. */ + engine_make_extra_hydroloop_tasks_mapper(sched->tasks, sched->nr_tasks, e); + /* threadpool_map(&e->threadpool, engine_make_extra_hydroloop_tasks_mapper, + * sched->tasks, sched->nr_tasks, sizeof(struct task), + * threadpool_auto_chunk_size, e); */ + } if (e->verbose) message("Making extra hydroloop tasks took %.3f %s.", diff --git a/src/engine_redistribute.c b/src/engine_redistribute.c index ddd86886c16af16395d972b040e28386cb356ad0..0e0ea2ad186d27e81c37a2b15bcb6545d0498a6a 100644 --- a/src/engine_redistribute.c +++ b/src/engine_redistribute.c @@ -984,7 +984,8 @@ void engine_redistribute(struct engine *e) { nr_bparts_new += b_counts[k * nr_nodes + nodeID]; #ifdef WITH_LOGGER - if (e->policy & engine_policy_logger) { + const int initial_redistribute = e->ti_current == 0; + if (!initial_redistribute && e->policy & engine_policy_logger) { /* Log the particles before sending them out */ size_t part_offset = 0; size_t spart_offset = 0; @@ -1002,19 +1003,19 @@ void engine_redistribute(struct engine *e) { bpart_offset += b_counts[c_ind]; continue; } - const uint32_t flag = logger_pack_flags_and_data(logger_flag_mpi_exit, i); /* Log the hydro parts. */ logger_log_parts(e->logger, &parts[part_offset], &xparts[part_offset], - counts[c_ind], e, /* log_all_fields */ 1, flag); + counts[c_ind], e, /* log_all_fields */ 1, + logger_flag_mpi_exit, i); /* Log the stellar parts. */ logger_log_sparts(e->logger, &sparts[spart_offset], s_counts[c_ind], e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_exit, i); /* Log the gparts */ logger_log_gparts(e->logger, &gparts[gpart_offset], g_counts[c_ind], e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_exit, i); /* Log the bparts */ if (b_counts[c_ind] > 0) { @@ -1083,7 +1084,7 @@ void engine_redistribute(struct engine *e) { stuff we just received */ #ifdef WITH_LOGGER - if (e->policy & engine_policy_logger) { + if (!initial_redistribute && e->policy & engine_policy_logger) { size_t part_offset = 0; size_t spart_offset = 0; size_t gpart_offset = 0; @@ -1101,21 +1102,18 @@ void engine_redistribute(struct engine *e) { continue; } - const uint32_t flag = - logger_pack_flags_and_data(logger_flag_mpi_enter, i); - /* Log the hydro parts. */ logger_log_parts(e->logger, &s->parts[part_offset], &s->xparts[part_offset], counts[c_ind], e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_enter, i); /* Log the stellar parts. */ logger_log_sparts(e->logger, &s->sparts[spart_offset], s_counts[c_ind], e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_enter, i); /* Log the gparts */ logger_log_gparts(e->logger, &s->gparts[gpart_offset], g_counts[c_ind], e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_enter, i); /* Log the bparts */ if (b_counts[c_ind] > 0) { diff --git a/src/engine_strays.c b/src/engine_strays.c index c096b2d671ca01d9c0b73ebb57b751b6e48fa785..6330ee0bde28597cd137fb4f9d3d9872d7a1cf0e 100644 --- a/src/engine_strays.c +++ b/src/engine_strays.c @@ -120,10 +120,9 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts, #ifdef WITH_LOGGER if (e->policy & engine_policy_logger) { /* Log the particle when leaving a rank. */ - logger_log_part( - e->logger, &s->parts[offset_parts + k], &s->xparts[offset_parts + k], - e, /* log_all_fields */ 1, - logger_pack_flags_and_data(logger_flag_mpi_exit, node_id)); + logger_log_part(e->logger, &s->parts[offset_parts + k], + &s->xparts[offset_parts + k], e, /* log_all_fields */ 1, + logger_flag_mpi_exit, node_id); } #endif } @@ -165,10 +164,8 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts, #ifdef WITH_LOGGER if (e->policy & engine_policy_logger) { /* Log the particle when leaving a rank. */ - logger_log_spart( - e->logger, &s->sparts[offset_sparts + k], e, - /* log_all_fields */ 1, - logger_pack_flags_and_data(logger_flag_mpi_exit, node_id)); + logger_log_spart(e->logger, &s->sparts[offset_sparts + k], e, + /* log_all_fields */ 1, logger_flag_mpi_exit, node_id); } #endif } @@ -248,10 +245,8 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts, s->gparts[offset_gparts + k].type == swift_type_dark_matter) { /* Log the particle when leaving a rank. */ - logger_log_gpart( - e->logger, &s->gparts[offset_gparts + k], e, - /* log_all_fields */ 1, - logger_pack_flags_and_data(logger_flag_mpi_exit, node_id)); + logger_log_gpart(e->logger, &s->gparts[offset_gparts + k], e, + /* log_all_fields */ 1, logger_flag_mpi_exit, node_id); } #endif } @@ -476,9 +471,6 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts, #ifdef WITH_LOGGER if (e->policy & engine_policy_logger) { - const uint32_t flag = - logger_pack_flags_and_data(logger_flag_mpi_enter, prox->nodeID); - struct part *parts = &s->parts[offset_parts + count_parts]; struct xpart *xparts = &s->xparts[offset_parts + count_parts]; struct spart *sparts = &s->sparts[offset_sparts + count_sparts]; @@ -486,15 +478,18 @@ void engine_exchange_strays(struct engine *e, const size_t offset_parts, /* Log the gas particles */ logger_log_parts(e->logger, parts, xparts, prox->nr_parts_in, e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_enter, + prox->nodeID); /* Log the stellar particles */ logger_log_sparts(e->logger, sparts, prox->nr_sparts_in, e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_enter, + prox->nodeID); /* Log the gparts */ logger_log_gparts(e->logger, gparts, prox->nr_gparts_in, e, - /* log_all_fields */ 1, flag); + /* log_all_fields */ 1, logger_flag_mpi_enter, + prox->nodeID); /* Log the bparts */ if (prox->nr_bparts_in > 0) { diff --git a/src/entropy_floor/EAGLE/entropy_floor.h b/src/entropy_floor/EAGLE/entropy_floor.h index 32e3828a7fa20b70630906fdb2c2a9c37f8f4c80..739f18ccdf0c3bb9a095c8583f37a1c78f617a9e 100644 --- a/src/entropy_floor/EAGLE/entropy_floor.h +++ b/src/entropy_floor/EAGLE/entropy_floor.h @@ -87,24 +87,21 @@ struct entropy_floor_properties { }; /** - * @brief Compute the entropy floor of a given #part. + * @brief Compute the pressure from the entropy floor at a given density * - * Note that the particle is not updated!! + * This is the pressure exactly corresponding to the imposed EoS shape. + * It only matches the entropy returned by the entropy_floor() function + * for a neutral gas with primoridal abundance. * - * @param p The #part. + * @param rho_phys The physical density (internal units). + * @param rho_com The comoving density (internal units). * @param cosmo The cosmological model. * @param props The properties of the entropy floor. */ -static INLINE float entropy_floor( - const struct part *p, const struct cosmology *cosmo, +static INLINE float entropy_floor_gas_pressure( + const float rho_phys, const float rho_com, const struct cosmology *cosmo, const struct entropy_floor_properties *props) { - /* Comoving density in internal units */ - const float rho_com = hydro_get_comoving_density(p); - - /* Physical density in internal units */ - const float rho_phys = hydro_get_physical_density(p, cosmo); - /* Mean baryon density in co-moving internal units for over-density condition * (Recall cosmo->critical_density_0 is 0 in a non-cosmological run, * making the over-density condition a no-op) */ @@ -138,8 +135,33 @@ static INLINE float entropy_floor( pressure = max(pressure, pressure_Cool); } + return pressure; +} + +/** + * @brief Compute the entropy floor of a given #part. + * + * Note that the particle is not updated!! + * + * @param p The #part. + * @param cosmo The cosmological model. + * @param props The properties of the entropy floor. + */ +static INLINE float entropy_floor( + const struct part *p, const struct cosmology *cosmo, + const struct entropy_floor_properties *props) { + + /* Comoving density in internal units */ + const float rho_com = hydro_get_comoving_density(p); + + /* Physical density in internal units */ + const float rho_phys = hydro_get_physical_density(p, cosmo); + + const float pressure = + entropy_floor_gas_pressure(rho_phys, rho_com, cosmo, props); + /* Convert to an entropy. - * (Recall that the entropy is the same in co-moving and phycial frames) */ + * (Recall that the entropy is the same in co-moving and physical frames) */ return gas_entropy_from_pressure(rho_phys, pressure); } diff --git a/src/entropy_floor/none/entropy_floor.h b/src/entropy_floor/none/entropy_floor.h index 7269ee59f490ed154c6b3c1ca40df4601b64f076..80eef1b3f010899274028163a184efad2d30f25c 100644 --- a/src/entropy_floor/none/entropy_floor.h +++ b/src/entropy_floor/none/entropy_floor.h @@ -37,6 +37,22 @@ struct phys_const; */ struct entropy_floor_properties {}; +/** + * @brief Compute the pressure from the entropy floor at a given density + * + * Simply return 0 (no floor). + * + * @param rho_phys The physical density (internal units). + * @param rho_com The comoving density (internal units). + * @param cosmo The cosmological model. + * @param props The properties of the entropy floor. + */ +static INLINE float entropy_floor_gas_pressure( + const float rho_phys, const float rho_com, const struct cosmology *cosmo, + const struct entropy_floor_properties *props) { + return 0.f; +} + /** * @brief Compute the entropy floor of a given #part. * @@ -53,6 +69,23 @@ static INLINE float entropy_floor( return 0.f; } +/** + * @brief Compute the temperature from the entropy floor at a given density + * + * Simply return 0 (no floor). + * + * @param rho_phys The physical density (internal units). + * @param rho_com The comoving density (internal units). + * @param cosmo The cosmological model. + * @param props The properties of the entropy floor. + */ +static INLINE float entropy_floor_gas_temperature( + const float rho_phys, const float rho_com, const struct cosmology *cosmo, + const struct entropy_floor_properties *props) { + + return 0.f; +} + /** * @brief Compute the temperature from the entropy floor for a given #part * diff --git a/src/feedback/EAGLE/feedback.c b/src/feedback/EAGLE/feedback.c index df01c1ddddfc4a53e4308a5eb7ce97e72995ea68..8046de77262a49d3b250359d3861dc1e8f09e58f 100644 --- a/src/feedback/EAGLE/feedback.c +++ b/src/feedback/EAGLE/feedback.c @@ -25,6 +25,7 @@ #include "imf.h" #include "inline.h" #include "interpolate.h" +#include "random.h" #include "timers.h" #include "yield_tables.h" @@ -287,9 +288,10 @@ 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 int num_gas_ngbs, const double ngb_nH_cgs, + const int ngb_gas_N, const float ngb_gas_mass, 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) { + const double min_dying_mass_Msun, const double max_dying_mass_Msun, + const integertime_t ti_begin) { /* Are we sampling the delay function or using a fixed delay? */ const int SNII_sampled_delay = feedback_props->SNII_sampled_delay; @@ -343,18 +345,29 @@ INLINE static void compute_SNII_feedback( /* Calculate the change in internal energy of the gas particles that get * heated */ double delta_u; + + /* Number of SNII events for this stellar particle */ + int number_of_SN_events = 0; + if (prob <= 1.) { /* Normal case */ delta_u = delta_T * conv_factor; + for (int i = 0; i < ngb_gas_N; i++) { + const double rand_thermal = random_unit_interval_part_ID_and_ray_idx( + sp->id, i, ti_begin, random_number_stellar_feedback_3); + if (rand_thermal < prob) number_of_SN_events++; + } + } else { /* Special case: we need to adjust the energy irrespective of the desired deltaT to ensure we inject all the available energy. */ - - prob = 1.; delta_u = f_E * E_SNe * N_SNe / ngb_gas_mass; + + /* Number of SNIa events is equal to the number of Ngbs */ + number_of_SN_events = ngb_gas_N; } #ifdef SWIFT_DEBUG_CHECKS @@ -362,6 +375,18 @@ INLINE static void compute_SNII_feedback( error("f_E is not in the valid range! f_E=%f sp->id=%lld", f_E, sp->id); #endif + /* If we have more heating events than the maximum number of + * rays (eagle_feedback_number_of_rays), then we cannot + * distribute all of the heating events (since 1 event = 1 ray), so we need + * to increase the thermal energy per ray and make the number of events + * equal to the number of rays */ + if (number_of_SN_events > eagle_SNII_feedback_num_of_rays) { + const double alpha_thermal = + (double)number_of_SN_events / (double)eagle_SNII_feedback_num_of_rays; + delta_u *= alpha_thermal; + number_of_SN_events = eagle_SNII_feedback_num_of_rays; + } + /* Current total f_E for this star */ double star_f_E = sp->f_E * sp->number_of_SNII_events; @@ -371,9 +396,9 @@ INLINE static void compute_SNII_feedback( /* Store all of this in the star for delivery onto the gas and recording */ sp->f_E = star_f_E; 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); + sp->feedback_data.to_distribute.SNII_num_of_thermal_energy_inj = + number_of_SN_events; } } @@ -853,17 +878,19 @@ INLINE static void evolve_AGB(const double log10_min_mass, * functions to calculate feedback due to SNIa, SNII and AGB * * @param feedback_props feedback_props data structure + * @param phys_const The physical constants in internal units. * @param cosmo The cosmological model. * @param sp spart that we're evolving * @param us unit_system data structure * @param age age of spart at beginning of step * @param dt length of current timestep + * @param ti_begin The current integer time (for random number hashing). */ 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) { + const double dt, const integertime_t ti_begin) { TIMER_TIC; @@ -893,8 +920,8 @@ void compute_stellar_evolution(const struct feedback_props* feedback_props, chemistry_get_star_metal_mass_fraction_for_feedback(sp); /* Properties collected in the stellar density loop. */ + const int ngb_Number = sp->feedback_data.to_collect.ngb_N; 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 = @@ -947,9 +974,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, num_gas_ngbs, + compute_SNII_feedback(sp, age, dt, ngb_Number, ngb_gas_mass, ngb_gas_phys_nH_cgs, ngb_gas_Z, feedback_props, - min_dying_mass_Msun, max_dying_mass_Msun); + min_dying_mass_Msun, max_dying_mass_Msun, ti_begin); } /* Integration interval is zero - this can happen if minimum and maximum @@ -1057,6 +1084,22 @@ void feedback_props_init(struct feedback_props* fp, /* Properties of the SNII energy feedback model ------------------------- */ + char model[64]; + parser_get_param_string(params, "EAGLEFeedback:SNII_feedback_model", model); + if (strcmp(model, "Random") == 0) + fp->feedback_model = SNII_random_ngb_model; + else if (strcmp(model, "Isotropic") == 0) + fp->feedback_model = SNII_isotropic_model; + else if (strcmp(model, "MinimumDistance") == 0) + fp->feedback_model = SNII_minimum_distance_model; + else if (strcmp(model, "MinimumDensity") == 0) + fp->feedback_model = SNII_minimum_density_model; + else + error( + "The SNII feedback model must be either 'Random', 'MinimumDistance', " + "'MinimumDensity' or 'Isotropic', not %s", + model); + /* Are we sampling the SNII lifetimes for feedback or using a fixed delay? */ fp->SNII_sampled_delay = parser_get_param_int(params, "EAGLEFeedback:SNII_sampled_delay"); diff --git a/src/feedback/EAGLE/feedback.h b/src/feedback/EAGLE/feedback.h index a5530bb9518db929d0154d751699c608c8d004e4..51294394e625f88a0cf41cafbbf83a1634b537fd 100644 --- a/src/feedback/EAGLE/feedback.h +++ b/src/feedback/EAGLE/feedback.h @@ -24,6 +24,7 @@ #include "feedback_properties.h" #include "hydro_properties.h" #include "part.h" +#include "rays.h" #include "units.h" #include <strings.h> @@ -32,7 +33,7 @@ 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); + const double dt, const integertime_t ti_begin); /** * @brief Update the properties of a particle fue to feedback effects after @@ -72,10 +73,13 @@ __attribute__((always_inline)) INLINE static void feedback_init_spart( struct spart* sp) { sp->feedback_data.to_collect.enrichment_weight_inv = 0.f; + sp->feedback_data.to_collect.ngb_N = 0; 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; + + /* Reset all ray structs carried by this star particle */ + ray_init(sp->feedback_data.SNII_rays, eagle_SNII_feedback_num_of_rays); } /** @@ -131,11 +135,11 @@ __attribute__((always_inline)) INLINE static void feedback_reset_feedback( /* Zero the energy to inject */ sp->feedback_data.to_distribute.energy = 0.f; - /* Zero the SNII feedback probability */ - sp->feedback_data.to_distribute.SNII_heating_probability = 0.f; - /* Zero the SNII feedback energy */ sp->feedback_data.to_distribute.SNII_delta_u = 0.f; + + /* Zero the SNII feedback properties */ + sp->feedback_data.to_distribute.SNII_num_of_thermal_energy_inj = 0; } /** @@ -206,7 +210,7 @@ __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, phys_const, cosmo, sp, us, - star_age_beg_step, dt); + star_age_beg_step, dt, ti_begin); /* 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 1684e910512ffcf5cb8a9561e376b4c5e2f1c173..ac2fe0dc0c8d5430a431e20f4e3af7e409f1e9d8 100644 --- a/src/feedback/EAGLE/feedback_iact.h +++ b/src/feedback/EAGLE/feedback_iact.h @@ -21,6 +21,7 @@ /* Local includes */ #include "random.h" +#include "rays.h" #include "timestep_sync_part.h" #include "tracers.h" @@ -35,6 +36,7 @@ * @param pj Second particle (not updated). * @param xpj Extra particle data (not updated). * @param cosmo The cosmological model. + * @param fb_props Properties of the feedback scheme. * @param ti_current Current integer time value */ __attribute__((always_inline)) INLINE static void @@ -43,6 +45,7 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, struct spart *si, const struct part *pj, const struct xpart *xpj, const struct cosmology *cosmo, + const struct feedback_props *fb_props, const integertime_t ti_current) { /* Get the gas mass. */ @@ -57,6 +60,9 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, float wi; kernel_eval(ui, &wi); + /* We found a neighbour! */ + si->feedback_data.to_collect.ngb_N++; + /* Add mass of pj to neighbour mass of si */ si->feedback_data.to_collect.ngb_mass += mj; @@ -74,10 +80,94 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, /* Add contribution of pj to normalisation of density weighted fraction * which determines how much mass to distribute to neighbouring * gas particles */ - const float rho = hydro_get_comoving_density(pj); if (rho != 0.f) si->feedback_data.to_collect.enrichment_weight_inv += wi / rho; + + /* Choose SNII feedback model */ + switch (fb_props->feedback_model) { + case SNII_isotropic_model: { + + /* Compute arc lengths in stellar isotropic feedback and collect + * relevant data for later use in the feedback_apply loop */ + + /* Loop over rays */ + for (int i = 0; i < eagle_SNII_feedback_num_of_rays; i++) { + + /* We generate two random numbers that we use + * to randomly select the direction of the ith ray */ + + /* Two random numbers in [0, 1[ */ + const double rand_theta_SNII = random_unit_interval_part_ID_and_ray_idx( + si->id, i, ti_current, + random_number_isotropic_SNII_feedback_ray_theta); + const double rand_phi_SNII = random_unit_interval_part_ID_and_ray_idx( + si->id, i, ti_current, + random_number_isotropic_SNII_feedback_ray_phi); + + /* Compute arclength */ + ray_minimise_arclength(dx, r, si->feedback_data.SNII_rays + i, + /*switch=*/-1, pj->id, rand_theta_SNII, + rand_phi_SNII, pj->mass, /*ray_ext=*/NULL, + /*v=*/NULL); + } + break; + } + case SNII_minimum_distance_model: { + /* Compute the size of the array that we want to sort. If the current + * function is called for the first time (at this time-step for this + * star), then bi->num_ngbs = 1 and there is nothing to sort. Note that + * the maximum size of the sorted array cannot be larger then the maximum + * number of rays. */ + const int arr_size = min(si->feedback_data.to_collect.ngb_N, + eagle_SNII_feedback_num_of_rays); + + /* Minimise separation between the gas particles and the star. The rays + * structs with smaller ids in the ray array will refer to the particles + * with smaller distances to the star. */ + ray_minimise_distance(r, si->feedback_data.SNII_rays, arr_size, pj->id, + pj->mass); + break; + } + case SNII_minimum_density_model: { + /* Compute the size of the array that we want to sort. If the current + * function is called for the first time (at this time-step for this + * star), then bi->num_ngbs = 1 and there is nothing to sort. Note that + * the maximum size of the sorted array cannot be larger then the maximum + * number of rays. */ + const int arr_size = min(si->feedback_data.to_collect.ngb_N, + eagle_SNII_feedback_num_of_rays); + + /* Minimise separation between the gas particles and the star. The rays + * structs with smaller ids in the ray array will refer to the particles + * with smaller distances to the star. */ + ray_minimise_distance(rho, si->feedback_data.SNII_rays, arr_size, pj->id, + pj->mass); + break; + } + case SNII_random_ngb_model: { + /* Compute the size of the array that we want to sort. If the current + * function is called for the first time (at this time-step for this + * star), then bi->num_ngbs = 1 and there is nothing to sort. Note that + * the maximum size of the sorted array cannot be larger then the maximum + * number of rays. */ + const int arr_size = min(si->feedback_data.to_collect.ngb_N, + eagle_SNII_feedback_num_of_rays); + + /* To mimic a random draw among all the particles in the kernel, we + * draw random distances in [0,1) and then pick the particle(s) with + * the smallest of these 'fake' distances */ + const float dist = random_unit_interval_two_IDs( + si->id, pj->id, ti_current, random_number_stellar_feedback_1); + + /* Minimise separation between the gas particles and the BH. The rays + * structs with smaller ids in the ray array will refer to the particles + * with smaller 'fake' distances to the BH. */ + ray_minimise_distance(dist, si->feedback_data.SNII_rays, arr_size, pj->id, + pj->mass); + break; + } + } } /** @@ -92,6 +182,7 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, * @param pj Second (gas) particle. * @param xpj Extra particle data * @param cosmo The cosmological model. + * @param fb_props Properties of the feedback scheme. * @param ti_current Current integer time used value for seeding random number * generator */ @@ -101,6 +192,7 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx, const struct spart *si, struct part *pj, struct xpart *xpj, const struct cosmology *cosmo, + const struct feedback_props *fb_props, const integertime_t ti_current) { #ifdef SWIFT_DEBUG_CHECKS @@ -283,22 +375,30 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx, /* Finally, SNII stochastic feedback */ - /* Get the SNII feedback properties */ - const float prob = si->feedback_data.to_distribute.SNII_heating_probability; + /* Get the total number of SNIa thermal energy injections per stellar + * particle at this time-step */ + const int N_of_SNII_thermal_energy_inj = + si->feedback_data.to_distribute.SNII_num_of_thermal_energy_inj; + + /* Are we doing some SNII feedback? */ + if (N_of_SNII_thermal_energy_inj > 0) { - /* Are we doing some SNII (big boys) feedback? */ - if (prob > 0.f) { + int N_of_SNII_energy_inj_received_by_gas = 0; + + /* Find out how many rays this gas particle has received. */ + for (int i = 0; i < N_of_SNII_thermal_energy_inj; i++) { + if (pj->id == si->feedback_data.SNII_rays[i].id_min_length) + N_of_SNII_energy_inj_received_by_gas++; + } - /* Draw a random number (Note mixing both IDs) */ - const float rand = random_unit_interval(si->id + pj->id, ti_current, - random_number_stellar_feedback_1); - /* Are we lucky? */ - if (rand < prob) { + /* If the number of SNII energy injections > 0, do SNII feedback */ + if (N_of_SNII_energy_inj_received_by_gas > 0) { /* Compute new energy of this particle */ const double u_init = hydro_get_physical_internal_energy(pj, xpj, cosmo); const float delta_u = si->feedback_data.to_distribute.SNII_delta_u; - const double u_new = u_init + delta_u; + const double u_new = + u_init + delta_u * (float)N_of_SNII_energy_inj_received_by_gas; /* Inject energy into the particle */ hydro_set_physical_internal_energy(pj, xpj, cosmo, u_new); @@ -313,7 +413,7 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx, /* message( */ /* "We did some heating! id %llu star id %llu probability %.5e " */ /* "random_num %.5e du %.5e du/ini %.5e", */ - /* pj->id, si->id, prob, rand, delta_u, delta_u / u_init); */ + /* pj->id, si->id, 0., 0., delta_u, delta_u / u_init); */ /* Synchronize the particle on the timeline */ timestep_sync_part(pj); diff --git a/src/feedback/EAGLE/feedback_properties.h b/src/feedback/EAGLE/feedback_properties.h index 2a75e8f42d24902f79acc01199f6f091add55b74..83db5e1114926b869dd596515598eb1eac08406d 100644 --- a/src/feedback/EAGLE/feedback_properties.h +++ b/src/feedback/EAGLE/feedback_properties.h @@ -19,9 +19,23 @@ #ifndef SWIFT_EAGLE_FEEDBACK_PROPERTIES_H #define SWIFT_EAGLE_FEEDBACK_PROPERTIES_H +/* Config parameters. */ +#include "../config.h" + +/* Local includes. */ #include "chemistry.h" #include "hydro_properties.h" +/** + * @brief Modes of energy injection for SNII feedback + */ +enum SNII_feedback_models { + SNII_random_ngb_model, /*< Random neighbour model for SNII feedback */ + SNII_isotropic_model, /*< Isotropic model of SNII feedback */ + SNII_minimum_distance_model, /*< Minimum-distance model of SNII feedback */ + SNII_minimum_density_model /*< Minimum-density model of SNII feedback */ +}; + /** * @brief Stores AGB and SNII yield tables */ @@ -212,6 +226,9 @@ struct feedback_props { /* ------------ SNe feedback properties ------------ */ + /*! SNII feedback model: random, isotropic or minimum distance */ + enum SNII_feedback_models feedback_model; + /*! Minimal stellar mass considered for SNII feedback (in solar masses) */ double SNII_min_mass_msun; diff --git a/src/feedback/EAGLE/feedback_struct.h b/src/feedback/EAGLE/feedback_struct.h index bc3a2d44d71e5e48060b0c8e6d05d753a2866a9d..44e39f31525043c512285f25fe70b9c2ed79b1e1 100644 --- a/src/feedback/EAGLE/feedback_struct.h +++ b/src/feedback/EAGLE/feedback_struct.h @@ -20,6 +20,10 @@ #define SWIFT_FEEDBACK_STRUCT_EAGLE_H #include "chemistry_struct.h" +#include "rays_struct.h" + +/*! The total number of rays used in stellar feedback */ +#define eagle_SNII_feedback_num_of_rays 1 /** * @brief Feedback fields carried by each hydro particles @@ -55,6 +59,9 @@ struct feedback_spart_data { * (dimensionless) */ float ngb_Z; + /*! Total (unweighted) number gas neighbours in the stellar kernel */ + int ngb_N; + } to_collect; /** @@ -100,14 +107,17 @@ struct feedback_spart_data { /*! Energy change due to thermal and kinetic energy of ejecta */ float energy; - /*! Probability to heating neighbouring gas particle for SNII feedback */ - float SNII_heating_probability; + /*! Number of SNII energy injections in thermal form */ + int SNII_num_of_thermal_energy_inj; /*! Change in energy from SNII feedback energy injection */ float SNII_delta_u; } to_distribute; }; + + /* Instantiate ray structs for SNII isotropic feedback */ + struct ray_data SNII_rays[eagle_SNII_feedback_num_of_rays]; }; #endif /* SWIFT_FEEDBACK_STRUCT_EAGLE_H */ diff --git a/src/feedback/GEAR/feedback_iact.h b/src/feedback/GEAR/feedback_iact.h index a11c2bf53b45fd601c67c2ee10d72666bd4936bb..be07e5d3508f52523f8ffcbe00598432e152ff29 100644 --- a/src/feedback/GEAR/feedback_iact.h +++ b/src/feedback/GEAR/feedback_iact.h @@ -35,15 +35,16 @@ * @param pj Second particle (not updated). * @param xpj Extra particle data (not updated). * @param cosmo The cosmological model. + * @param fb_props Properties of the feedback scheme. * @param ti_current Current integer time value */ __attribute__((always_inline)) INLINE static void runner_iact_nonsym_feedback_density(const float r2, const float *dx, const float hi, const float hj, - struct spart *restrict si, - const struct part *restrict pj, - const struct xpart *restrict xpj, - const struct cosmology *restrict cosmo, + struct spart *si, const struct part *pj, + const struct xpart *xpj, + const struct cosmology *cosmo, + const struct feedback_props *fb_props, const integertime_t ti_current) { /* Get the gas mass. */ @@ -79,6 +80,7 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, * @param pj Second (gas) particle. * @param xpj Extra particle data * @param cosmo The cosmological model. + * @param fb_props Properties of the feedback scheme. * @param ti_current Current integer time used value for seeding random number * generator */ @@ -88,6 +90,7 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx, struct spart *si, struct part *pj, struct xpart *xpj, const struct cosmology *cosmo, + const struct feedback_props *fb_props, const integertime_t ti_current) { const double e_sn = si->feedback_data.energy_ejected; diff --git a/src/feedback/none/feedback_iact.h b/src/feedback/none/feedback_iact.h index fe8e19eca7af1543a5716ad9e0ac03779913d488..593b6a6981e68511feedb23f0d63ba1faeab44b9 100644 --- a/src/feedback/none/feedback_iact.h +++ b/src/feedback/none/feedback_iact.h @@ -32,6 +32,7 @@ * @param pj Second particle (not updated). * @param xp Extra particle data (not updated). * @param cosmo The cosmological model. + * @param fb_props Properties of the feedback scheme. * @param ti_current Current integer time value */ __attribute__((always_inline)) INLINE static void @@ -40,6 +41,7 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, struct spart *si, const struct part *pj, const struct xpart *xp, const struct cosmology *cosmo, + const struct feedback_props *fb_props, const integertime_t ti_current) {} /** @@ -56,6 +58,7 @@ runner_iact_nonsym_feedback_density(const float r2, const float *dx, * @param pj Second (gas) particle. * @param xp Extra particle data * @param cosmo The cosmological model. + * @param fb_props Properties of the feedback scheme. * @param ti_current Current integer time used value for seeding random number * generator */ @@ -65,6 +68,7 @@ runner_iact_nonsym_feedback_apply(const float r2, const float *dx, const struct spart *si, struct part *pj, struct xpart *xp, const struct cosmology *cosmo, + const struct feedback_props *fb_props, const integertime_t ti_current) {} #endif /* SWIFT_NONE_FEEDBACK_IACT_H */ diff --git a/src/gravity/MultiSoftening/gravity_part.h b/src/gravity/MultiSoftening/gravity_part.h index 9183637c7940b63ec3576ecb8665feacb448f0d2..8cf8e241a5cb3b5427e6138b65738fdb7c180a2c 100644 --- a/src/gravity/MultiSoftening/gravity_part.h +++ b/src/gravity/MultiSoftening/gravity_part.h @@ -20,6 +20,7 @@ #define SWIFT_MULTI_SOFTENING_GRAVITY_PART_H #include "fof_struct.h" +#include "logger.h" /* Gravity particle. */ struct gpart { diff --git a/src/hydro/Gadget2/hydro_logger.h b/src/hydro/Gadget2/hydro_logger.h index 6d70f32601cb6194e5d9be457e4fcbd873c315e4..e7a12a5b0b3defec623aca3101ef879e6fba5ba6 100644 --- a/src/hydro/Gadget2/hydro_logger.h +++ b/src/hydro/Gadget2/hydro_logger.h @@ -180,9 +180,9 @@ INLINE static char *hydro_logger_write_particle( /* Compute the acceleration due to hydro and gravity */ float *acc = (float *)buff; - acc[0] = p->a_hydro[0] + xp->a_grav[0]; - acc[1] = p->a_hydro[1] + xp->a_grav[1]; - acc[2] = p->a_hydro[2] + xp->a_grav[2]; + acc[0] = p->a_hydro[0] + p->gpart->a_grav[0]; + acc[1] = p->a_hydro[1] + p->gpart->a_grav[1]; + acc[2] = p->a_hydro[2] + p->gpart->a_grav[2]; memcpy(buff, acc, 3 * sizeof(float)); buff += 3 * sizeof(float); diff --git a/src/hydro_logger.h b/src/hydro_logger.h index fe4a3b75c80ffa0893f3f4d6fb65be11a3acc4be..503a3b4acab6dae349694009943088e4056945b0 100644 --- a/src/hydro_logger.h +++ b/src/hydro_logger.h @@ -28,7 +28,7 @@ #include "part_type.h" #include "timeline.h" -/* Import the right functloggerns */ +/* Import the right function */ #if defined(MINIMAL_SPH) #error TODO #elif defined(GADGET2_SPH) diff --git a/src/logger.c b/src/logger.c index a5d88a96b929d0145c845deed49f59788f20837e..be462bcfe58bf78c3f571bb1c03648604789cbd6 100644 --- a/src/logger.c +++ b/src/logger.c @@ -1,6 +1,7 @@ /******************************************************************************* * This file is part of SWIFT. - * Copyright (c) 2017 Pedro Gonnet (pedro.gonnet@durham.ac.uk) + * Copyright (c) 2020 Loic Hausammann (loic.hausammann@epfl.ch) + * 2017 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 @@ -140,15 +141,17 @@ void logger_log_all_particles(struct logger_writer *log, /* log the parts. */ logger_log_parts(log, s->parts, s->xparts, s->nr_parts, e, - /* log_all_fields */ 1, /* Special flags */ 0); + /* log_all_fields= */ 1, /* flag= */ 0, /* flag_data= */ 0); /* log the gparts */ logger_log_gparts(log, s->gparts, s->nr_gparts, e, - /* log_all_fields */ 1, /* Special flags */ 0); + /* log_all_fields= */ 1, /* flag= */ 0, + /* flag_data= */ 0); /* log the parts */ logger_log_sparts(log, s->sparts, s->nr_sparts, e, - /* log_all_fields */ 1, /* Special flags */ 0); + /* log_all_fields= */ 1, /* flag= */ 0, + /* flag_data= */ 0); if (e->total_nr_bparts > 0) error("Not implemented"); } @@ -208,13 +211,17 @@ void logger_copy_part_fields(const struct logger_writer *log, * @param xp The #xpart to dump. * @param e The #engine. * @param log_all_fields Should we log all the fields? - * @param special_flags The value of the special flag. + * @param flag The value of the special flags. + * @param flag_data The data to write for the flag. */ void logger_log_part(struct logger_writer *log, const struct part *p, struct xpart *xp, const struct engine *e, - const int log_all_fields, const uint32_t special_flags) { + const int log_all_fields, + const enum logger_special_flags flag, + const int flag_data) { - logger_log_parts(log, p, xp, /* count */ 1, e, log_all_fields, special_flags); + logger_log_parts(log, p, xp, /* count= */ 1, e, log_all_fields, flag, + flag_data); } /** @@ -226,11 +233,17 @@ void logger_log_part(struct logger_writer *log, const struct part *p, * @param count The number of particle to dump. * @param e The #engine. * @param log_all_fields Should we log all the fields? - * @param special_flags The value of the special flags. + * @param flag The value of the special flags. + * @param flag_data The data to write for the flag. */ void logger_log_parts(struct logger_writer *log, const struct part *p, struct xpart *xp, int count, const struct engine *e, - const int log_all_fields, const uint32_t special_flags) { + const int log_all_fields, + const enum logger_special_flags flag, + const int flag_data) { + + /* Build the special flag */ + const uint32_t special_flags = logger_pack_flags_and_data(flag, flag_data); /* Compute the size of the buffer. */ size_t size_total = 0; @@ -268,6 +281,17 @@ void logger_log_parts(struct logger_writer *log, const struct part *p, &xp[i].logger_data.last_offset, offset_new, buff, special_flags); + /* Write the particle into the history if needed. */ + if (flag & logger_flag_create || flag & logger_flag_mpi_enter) { + logger_history_log(&log->history_new[swift_type_gas], p->id, + xp->logger_data.last_offset); + + } else if (flag & logger_flag_change_type || flag & logger_flag_delete || + flag & logger_flag_mpi_exit) { + logger_history_log(&log->history_removed[swift_type_gas], p->id, + xp->logger_data.last_offset); + } + /* Update the pointers */ xp[i].logger_data.last_offset = offset_new; xp[i].logger_data.steps_since_last_output = 0; @@ -329,13 +353,15 @@ void logger_copy_spart_fields(const struct logger_writer *log, * @param sp The #spart to dump. * @param e The #engine. * @param log_all_fields Should we log all the fields? - * @param special_flags The value of the special flag. + * @param flag The value of the special flags. + * @param flag_data The data to write for the flag. */ void logger_log_spart(struct logger_writer *log, struct spart *sp, const struct engine *e, const int log_all_fields, - const uint32_t special_flags) { + const enum logger_special_flags flag, + const int flag_data) { - logger_log_sparts(log, sp, /* count */ 1, e, log_all_fields, special_flags); + logger_log_sparts(log, sp, /* count */ 1, e, log_all_fields, flag, flag_data); } /** @@ -346,11 +372,15 @@ void logger_log_spart(struct logger_writer *log, struct spart *sp, * @param e The #engine. * @param log_all_fields Should we log all the fields? * @param count The number of particle to dump. - * @param special_flags The value of the special flags. + * @param flag The value of the special flags. + * @param flag_data The data to write for the flag. */ void logger_log_sparts(struct logger_writer *log, struct spart *sp, int count, const struct engine *e, const int log_all_fields, - const uint32_t special_flags) { + const enum logger_special_flags flag, + const int flag_data) { + /* Build the special flag */ + const uint32_t special_flags = logger_pack_flags_and_data(flag, flag_data); /* Compute the size of the buffer. */ size_t size_total = 0; @@ -387,6 +417,17 @@ void logger_log_sparts(struct logger_writer *log, struct spart *sp, int count, &sp[i].logger_data.last_offset, offset_new, buff, special_flags); + /* Write the particle into the history if needed. */ + if (flag & logger_flag_create || flag & logger_flag_mpi_enter) { + logger_history_log(&log->history_new[swift_type_stars], sp->id, + sp->logger_data.last_offset); + + } else if (flag & logger_flag_change_type || flag & logger_flag_delete || + flag & logger_flag_mpi_exit) { + logger_history_log(&log->history_removed[swift_type_stars], sp->id, + sp->logger_data.last_offset); + } + /* Update the pointers */ sp[i].logger_data.last_offset = offset_new; sp[i].logger_data.steps_since_last_output = 0; @@ -448,12 +489,14 @@ void logger_copy_gpart_fields(const struct logger_writer *log, * @param p The #gpart to dump. * @param e The #engine. * @param log_all_fields Should we log all the fields? - * @param special_flags The value of the special flags. + * @param flag The value of the special flags. + * @param flag_data The data to write for the flag. */ void logger_log_gpart(struct logger_writer *log, struct gpart *p, const struct engine *e, const int log_all_fields, - const uint32_t special_flags) { - logger_log_gparts(log, p, /* count */ 1, e, log_all_fields, special_flags); + const enum logger_special_flags flag, + const int flag_data) { + logger_log_gparts(log, p, /* count */ 1, e, log_all_fields, flag, flag_data); } /** @@ -464,11 +507,15 @@ void logger_log_gpart(struct logger_writer *log, struct gpart *p, * @param count The number of particle to dump. * @param e The #engine. * @param log_all_fields Should we log all the fields? - * @param special_flags The value of the special flags. + * @param flag The value of the special flags. + * @param flag_data The data to write for the flag. */ void logger_log_gparts(struct logger_writer *log, struct gpart *p, int count, const struct engine *e, const int log_all_fields, - const uint32_t special_flags) { + const enum logger_special_flags flag, + const int flag_data) { + /* Build the special flag */ + const uint32_t special_flags = logger_pack_flags_and_data(flag, flag_data); /* Compute the size of the buffer. */ size_t size_total = 0; @@ -510,6 +557,17 @@ void logger_log_gparts(struct logger_writer *log, struct gpart *p, int count, logger_copy_gpart_fields(log, &p[i], e, mask, &p[i].logger_data.last_offset, offset_new, buff, special_flags); + /* Write the particle into the history if needed. */ + if (flag & logger_flag_create || flag & logger_flag_mpi_enter) { + logger_history_log(&log->history_new[swift_type_dark_matter], + p->id_or_neg_offset, p->logger_data.last_offset); + + } else if (flag & logger_flag_change_type || flag & logger_flag_delete || + flag & logger_flag_mpi_exit) { + logger_history_log(&log->history_removed[swift_type_dark_matter], + p->id_or_neg_offset, p->logger_data.last_offset); + } + /* Update the pointers */ p[i].logger_data.last_offset = offset_new; p[i].logger_data.steps_since_last_output = 0; @@ -790,6 +848,7 @@ void logger_init(struct logger_writer *log, const struct engine *e, /* set initial value of parameters. */ log->timestamp_offset = 0; log->index.dump_size_last_output = 0; + log->index_file_number = 0; /* generate dump filename. */ char logger_name_file[PARSER_MAX_LINE_SIZE]; @@ -809,6 +868,23 @@ void logger_init(struct logger_writer *log, const struct engine *e, /* init dump. */ dump_init(&log->dump, logger_name_file, buffer_size); + + /* Read the maximal size of the history. */ + const float max_memory_size = + parser_get_opt_param_float(params, "Logger:maximal_memory_size", 1.); + log->maximal_size_history = + max_memory_size / sizeof(struct logger_index_data); + + if (e->nodeID == 0) { + message("Maximal memory size for the logger history: %g GB", + max_memory_size); + } + + /* initialize the history */ + for (int i = 0; i < swift_type_count; i++) { + logger_history_init(&log->history_removed[i]); + logger_history_init(&log->history_new[i]); + } } /** @@ -822,6 +898,11 @@ void logger_free(struct logger_writer *log) { free(log->logger_mask_data); log->logger_mask_data = NULL; log->logger_count_mask = 0; + + for (int i = 0; i < swift_type_count; i++) { + logger_history_free(&log->history_new[i]); + logger_history_free(&log->history_removed[i]); + } } /** @@ -1094,6 +1175,12 @@ void logger_struct_dump(const struct logger_writer *log, FILE *stream) { restart_write_blocks((void *)log->logger_mask_data, sizeof(struct mask_data), log->logger_count_mask, stream, "logger_masks", "logger_masks"); + + /* Dump the logger mpi history */ + for (int i = 0; i < swift_type_count; i++) { + logger_history_dump(&log->history_new[i], stream); + logger_history_dump(&log->history_removed[i], stream); + } } /** @@ -1109,17 +1196,35 @@ void logger_struct_restore(struct logger_writer *log, FILE *stream) { NULL, "logger"); /* Read the masks */ + const struct mask_data *old_logger_mask_data = log->logger_mask_data; log->logger_mask_data = (struct mask_data *)malloc(sizeof(struct mask_data) * log->logger_count_mask); restart_read_blocks((void *)log->logger_mask_data, sizeof(struct mask_data), log->logger_count_mask, stream, NULL, "logger_masks"); - /* generate dump filename */ + /* Restore the pointers */ + log->mask_data_pointers.hydro = + log->logger_mask_data + + (log->mask_data_pointers.hydro - old_logger_mask_data); + log->mask_data_pointers.gravity = + log->logger_mask_data + + (log->mask_data_pointers.gravity - old_logger_mask_data); + log->mask_data_pointers.stars = + log->logger_mask_data + + (log->mask_data_pointers.stars - old_logger_mask_data); + + /* Restart the dump file. */ char logger_name_file[PARSER_MAX_LINE_SIZE]; logger_get_dump_name(log, logger_name_file); dump_restart(&log->dump, logger_name_file); + + /* Restore the logger mpi history */ + for (int i = 0; i < swift_type_count; i++) { + logger_history_restore(&log->history_new[i], stream); + logger_history_restore(&log->history_removed[i], stream); + } } #endif /* WITH_LOGGER */ diff --git a/src/logger.h b/src/logger.h index 78d8bbeabeaca191de1ec3dc928f5a7cc1a2a96f..c2810219f7f8dc4ba695ab1df6edf433a442be65 100644 --- a/src/logger.h +++ b/src/logger.h @@ -29,6 +29,7 @@ #include "dump.h" #include "error.h" #include "inline.h" +#include "logger_history.h" #include "timeline.h" #include "units.h" @@ -39,7 +40,7 @@ struct part; struct engine; #define logger_major_version 0 -#define logger_minor_version 4 +#define logger_minor_version 5 /* Size of the strings. */ #define logger_string_length 200 @@ -108,6 +109,18 @@ struct logger_writer { size_t dump_size_last_output; } index; + /* Index file number for the filename. */ + int index_file_number; + + /* History of the new particles since the last index file. */ + struct logger_history history_new[swift_type_count]; + + /* History of the particles removed since the last index file. */ + struct logger_history history_removed[swift_type_count]; + + /* Maximal number of particle stored in the history. */ + size_t maximal_size_history; + /* Dump file (In the reader, the dump is cleaned, therefore it is renamed * logfile). */ struct dump dump; @@ -164,22 +177,29 @@ void logger_log_all_particles(struct logger_writer *log, const struct engine *e); void logger_log_part(struct logger_writer *log, const struct part *p, struct xpart *xp, const struct engine *e, - const int log_all_fields, const uint32_t special_flags); + const int log_all_fields, + const enum logger_special_flags flag, const int flag_data); void logger_log_parts(struct logger_writer *log, const struct part *p, struct xpart *xp, int count, const struct engine *e, - const int log_all_fields, const uint32_t special_flags); + const int log_all_fields, + const enum logger_special_flags flag, + const int flag_data); void logger_log_spart(struct logger_writer *log, struct spart *p, const struct engine *e, const int log_all_fields, - const uint32_t special_flags); + const enum logger_special_flags flag, + const int flag_data); void logger_log_sparts(struct logger_writer *log, struct spart *sp, int count, const struct engine *e, const int log_all_fields, - const uint32_t special_flags); + const enum logger_special_flags flag, + const int flag_data); void logger_log_gpart(struct logger_writer *log, struct gpart *p, const struct engine *e, const int log_all_fields, - const uint32_t special_flags); + const enum logger_special_flags flag, + const int flag_data); void logger_log_gparts(struct logger_writer *log, struct gpart *gp, int count, const struct engine *e, const int log_all_fields, - const uint32_t special_flags); + const enum logger_special_flags flag, + const int flag_data); void logger_init(struct logger_writer *log, const struct engine *e, struct swift_params *params); void logger_free(struct logger_writer *log); @@ -202,23 +222,23 @@ void logger_struct_restore(struct logger_writer *log, FILE *stream); * @brief Generate the data for the special flags. * * @param flag The special flag to use. - * @param data The data to write in the . + * @param flag_data The data to write in the record. */ INLINE static uint32_t logger_pack_flags_and_data( - enum logger_special_flags flag, int data) { + enum logger_special_flags flag, int flag_data) { #ifdef SWIFT_DEBUG_CHECKS if (flag & 0xFFFFFF00) { error( "The special flag in the particle logger cannot be larger than 1 " "byte."); } - if (data & ~0xFFFFFF) { + if (flag_data & ~0xFFFFFF) { error( "The data for the special flag in the particle logger cannot be larger " "than 3 bytes."); } #endif - return ((uint32_t)flag << (3 * 8)) | (data & 0xFFFFFF); + return ((uint32_t)flag << (3 * 8)) | (flag_data & 0xFFFFFF); } /** diff --git a/src/logger_history.c b/src/logger_history.c new file mode 100644 index 0000000000000000000000000000000000000000..6ae10d4aa0f655a9db9241c6764e37a3d7a97cad --- /dev/null +++ b/src/logger_history.c @@ -0,0 +1,176 @@ +/******************************************************************************* + * 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/>. + * + ******************************************************************************/ + +/* Include header */ +#include "logger_history.h" + +/* Standard includes */ +#include <string.h> + +/* Local include */ +#include "logger_io.h" +#include "part.h" + +#if defined(WITH_LOGGER) + +#define LOGGER_HISTORY_INIT_SIZE 1024 + +/** + * @brief Initialize the structure for the first time. + * + * @param hist The #logger_history. + */ +void logger_history_init(struct logger_history *hist) { + + /* Set the counters to their initial value */ + hist->size = 0; + hist->capacity = LOGGER_HISTORY_INIT_SIZE; + + hist->data = (struct logger_index_data *)swift_malloc( + "logger_history", + sizeof(struct logger_index_data) * LOGGER_HISTORY_INIT_SIZE); + if (hist->data == NULL) { + error("Failed to allocate memory for the logger_history."); + } +} + +/** + * @brief Reset the structure (for example just after a dump). + * + * @param hist The #logger_history. + * @param params The #swift_params. + * @param already_allocated Are the data already allocated? (Need to free it?) + */ +void logger_history_reset(struct logger_history *hist) { + + swift_free("logger_history", hist->data); + + logger_history_init(hist); +} + +/** + * @brief Free the structure (e.g. just before exiting). + * + * @param hist The #logger_history. + */ +void logger_history_free(struct logger_history *hist) { + /* Set the counters to 0 */ + hist->size = 0; + hist->capacity = 0; + + /* Free the memory */ + if (hist->data != NULL) { + swift_free("logger_history", hist->data); + hist->data = NULL; + } +} + +/** + * @brief Log a the particle information into the #logger_history. + * + * @param hist The #logger_history. + * @param data The data from the particle. + */ +void logger_history_log(struct logger_history *hist, const long long id, + const uint64_t last_offset) { + +#ifdef SWIFT_DEBUG_CHECKS + if (id < 0) { + error( + "Negative ID for a particle. " + "Are you trying to log a gpart linked to another type of particles?"); + } +#endif + const struct logger_index_data data = {id, last_offset}; + + /* Check if enough space is left */ + if (hist->size == hist->capacity) { + /* Compute the previous amount of memory */ + const size_t memsize = sizeof(struct logger_index_data) * hist->capacity; + + /* Increase the capacity of the array */ + hist->capacity *= 2; + + /* Allocate the new array and copy the content of the previous one */ + struct logger_index_data *tmp = + (struct logger_index_data *)swift_malloc("logger_history", 2 * memsize); + + memcpy(tmp, hist->data, memsize); + + /* Free the previous array and switch the pointers */ + swift_free("logger_history", hist->data); + hist->data = tmp; + } + + /* Save the new particle */ + hist->data[hist->size] = data; + + /* Increase the element counter */ + hist->size += 1; +} + +/** + * @brief Write the history into an index file. + * + * @param hist The #logger_history. + * @param e The #engine. + * @param f The file where to write the history. + */ +void logger_history_write(struct logger_history *hist, struct engine *e, + FILE *f) { + /* Generate the structures for writing the index file */ + const int num_fields = 2; + struct io_props list[2]; + list[0] = + io_make_output_field("ParticleIDs", ULONGLONG, 1, UNIT_CONV_NO_UNITS, 0.f, + hist->data, id, "Field not used"); + list[1] = io_make_output_field("Offset", UINT64, 1, UNIT_CONV_NO_UNITS, 0.f, + hist->data, offset, "Field not used"); + + write_index_array(e, f, list, num_fields, hist->size); + + /* Reset the logger history */ + logger_history_reset(hist); +} + +void logger_history_dump(const struct logger_history *hist, FILE *stream) { + restart_write_blocks((void *)hist, sizeof(struct logger_history), 1, stream, + "logger_history", "logger_history"); + + if (hist->size != 0) + restart_write_blocks((void *)hist->data, sizeof(struct logger_index_data), + hist->size, stream, "logger_history_data", + "logger_history_data"); +} + +void logger_history_restore(struct logger_history *hist, FILE *stream) { + restart_read_blocks((void *)hist, sizeof(struct logger_history), 1, stream, + NULL, "logger_history"); + + hist->data = malloc(hist->capacity * sizeof(struct logger_index_data)); + if (hist->data == NULL) { + error("Failed to allocate array for logger history"); + } + + if (hist->size != 0) + restart_read_blocks((void *)hist->data, sizeof(struct logger_index_data), + hist->size, stream, NULL, "logger_history_data"); +} + +#endif // WITH_LOGGER diff --git a/src/logger_history.h b/src/logger_history.h new file mode 100644 index 0000000000000000000000000000000000000000..cee7db5b4ad6c1b9baac559157f5059190c5702d --- /dev/null +++ b/src/logger_history.h @@ -0,0 +1,82 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2019 Loic Hausammann (loic.hausammann@epfl.ch) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_LOGGER_HISTORY_H +#define SWIFT_LOGGER_HISTORY_H + +#include "../config.h" + +/* Standard includes */ +#include <stdint.h> + +/* Local include */ +#include "error.h" +#include "part_type.h" + +#if defined(WITH_LOGGER) + +/* Forward declaration */ +struct xpart; +struct part; +struct gpart; +struct spart; +struct bpart; +struct engine; +struct swift_params; + +/** + * @brief Contains the information concerning + * a particle for the index files. + */ +struct logger_index_data { + /* Id of the particle. */ + int64_t id; + + /* Offset of the particle in the file. */ + uint64_t offset; +}; + +/** + * @brief Structure dealing with the changes in the number + * of particles (e.g. creation, deletion, transformation). + */ +struct logger_history { + + /* Number of elements currently stored */ + uint64_t size; + + /* Size of the current buffer */ + size_t capacity; + + /* Buffer containing the particles */ + struct logger_index_data *data; +}; + +void logger_history_init(struct logger_history *hist); +void logger_history_reset(struct logger_history *hist); +void logger_history_free(struct logger_history *hist); +void logger_history_log(struct logger_history *hist, const long long id, + const uint64_t last_offset); +void logger_history_write(struct logger_history *hist, struct engine *e, + FILE *f); + +void logger_history_dump(const struct logger_history *hist, FILE *stream); +void logger_history_restore(struct logger_history *hist, FILE *stream); + +#endif // WITH_LOGGER +#endif // SWIFT_LOGGER_HISTORY_H diff --git a/src/logger_io.c b/src/logger_io.c index cd97be44133baf105f9006e17218207a5765a445..178df2a9b7384c8e64f789368390ffdf4a005a02 100644 --- a/src/logger_io.c +++ b/src/logger_io.c @@ -26,12 +26,15 @@ /* Some standard headers. */ #include "common_io.h" +#include <errno.h> #include <hdf5.h> #include <math.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/mman.h> +#include <unistd.h> /* This object's header. */ #include "logger_io.h" @@ -60,37 +63,6 @@ #include "version.h" #include "xmf.h" -/** - * @brief Mapper function to copy #part or #gpart fields into a buffer. - * WARNING Assumes two io_props in extra_data. - */ -void logger_io_copy_mapper(void* restrict temp, int N, - void* restrict extra_data) { - - /* Get the io_props */ - const struct io_props* props = (const struct io_props*)(extra_data); - const struct io_props props1 = props[0]; - const struct io_props props2 = props[1]; - - /* Get the sizes */ - const size_t typeSize1 = io_sizeof_type(props1.type); - const size_t copySize1 = typeSize1 * props1.dimension; - const size_t typeSize2 = io_sizeof_type(props2.type); - const size_t copySize2 = typeSize2 * props2.dimension; - const size_t copySize = copySize1 + copySize2; - - /* How far are we with this chunk? */ - char* restrict temp_c = (char*)temp; - const ptrdiff_t delta = (temp_c - props1.start_temp_c) / copySize; - - /* Copy the memory to the buffer */ - for (int k = 0; k < N; k++) { - memcpy(&temp_c[k * copySize], props1.field + (delta + k) * props1.partSize, - copySize1); - memcpy(&temp_c[k * copySize + copySize1], - props2.field + (delta + k) * props2.partSize, copySize2); - } -} /** * @brief Writes the data array in the index file. * @@ -100,42 +72,80 @@ void logger_io_copy_mapper(void* restrict temp, int N, * @param n_props The number of element in @props. * @param N The number of particles to write. */ -void writeIndexArray(const struct engine* e, FILE* f, struct io_props* props, - size_t n_props, size_t N) { +void write_index_array(const struct engine* e, FILE* f, struct io_props* props, + size_t n_props, size_t N) { /* Check that the assumptions are corrects */ if (n_props != 2) error("Not implemented: The index file can only write two props."); - if (props[0].dimension != 1 || props[1].dimension != 1) - error("Not implemented: cannot use multidimensional data"); - /* Get a few variables */ - const size_t typeSize = - io_sizeof_type(props[0].type) + io_sizeof_type(props[1].type); + const size_t type_size0 = io_sizeof_type(props[0].type) * props[0].dimension; + const size_t type_size1 = io_sizeof_type(props[1].type) * props[1].dimension; + const size_t type_size = type_size0 + type_size1; + + /* Convert FILE to int */ + int fd = fileno(f); + if (fd == -1) { + error("Failed to get the integer descriptor"); + } - const size_t num_elements = N; + /* Get a few variables for the mapping */ + char* data; + const size_t offset = ftell(f); + const size_t count = N * type_size + offset; + + /* Truncate the file to the correct length. */ + if (ftruncate(fd, count) != 0) { + error("Failed to truncate dump file (%s).", strerror(errno)); + } + + /* Map the file */ + if ((data = mmap(NULL, count, PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) { + error("Failed to allocate map of size %zi bytes (%s).", count, + strerror(errno)); + } + + /* Copy the data into the file */ + char* first = data + offset; + char* second = data + type_size0 + offset; + for (size_t i = 0; i < N; i++) { + memcpy(first + i * type_size, props[0].field + i * props[0].partSize, + type_size0); + memcpy(second + i * type_size, props[1].field + i * props[1].partSize, + type_size1); + } - /* Allocate temporary buffer */ - void* temp = NULL; - if (posix_memalign((void**)&temp, IO_BUFFER_ALIGNMENT, - num_elements * typeSize) != 0) - error("Unable to allocate temporary i/o buffer"); + /* Unmap the data in memory. */ + if (munmap(data, count) != 0) { + error("Failed to unmap dump data (%s).", strerror(errno)); + } - /* Copy the particle data to the temporary buffer */ - /* Set initial buffer position */ - props[0].start_temp_c = temp; - props[1].start_temp_c = temp; + /* Move the file position */ + fseek(f, count, SEEK_SET); +} - /* Copy the whole thing into a buffer */ - threadpool_map((struct threadpool*)&e->threadpool, logger_io_copy_mapper, - temp, N, typeSize, threadpool_auto_chunk_size, props); +/** + * @brief Write the history (created or deleted) for all the particles type. + * + * @param history The list of history to write. + * @param e The #engine. + * @param f The opened file to use. + */ +void logger_write_history(struct logger_history* history, struct engine* e, + FILE* f) { - /* Write data to file */ - fwrite(temp, typeSize, num_elements, f); + /* Write the number of particles. */ + uint64_t size[swift_type_count]; + for (int i = 0; i < swift_type_count; i++) { + size[i] = history[i].size; + } + fwrite(size, sizeof(uint64_t), swift_type_count, f); - /* Free everything */ - free(temp); + /* Write the data */ + for (int i = 0; i < swift_type_count; i++) { + logger_history_write(&history[i], e, f); + } } /** @@ -161,7 +171,6 @@ void logger_write_index_file(struct logger_writer* log, struct engine* e) { struct xpart* xparts = e->s->xparts; struct gpart* gparts = e->s->gparts; struct spart* sparts = e->s->sparts; - static int outputCount = 0; /* Number of particles currently in the arrays */ const size_t Ntot = e->s->nr_gparts; @@ -191,11 +200,12 @@ void logger_write_index_file(struct logger_writer* log, struct engine* e) { /* File name */ char fileName[FILENAME_BUFFER_SIZE]; snprintf(fileName, FILENAME_BUFFER_SIZE, "%.100s_%04i_%04i.index", - e->logger->base_name, engine_rank, outputCount); + e->logger->base_name, engine_rank, log->index_file_number); + log->index_file_number++; - /* Open file */ + /* Open file (include reading for mmap) */ FILE* f = NULL; - f = fopen(fileName, "wb"); + f = fopen(fileName, "w+b"); if (f == NULL) { error("Failed to open file %s", fileName); @@ -341,7 +351,7 @@ void logger_write_index_file(struct logger_writer* log, struct engine* e) { } /* Write ids */ - writeIndexArray(e, f, list, num_fields, N); + write_index_array(e, f, list, num_fields, N); /* Free temporary arrays */ if (parts_written) swift_free("parts_written", parts_written); @@ -353,10 +363,14 @@ void logger_write_index_file(struct logger_writer* log, struct engine* e) { if (bparts_written) swift_free("bparts_written", bparts_written); } + /* Write the particles created */ + logger_write_history(log->history_new, e, f); + + /* Write the particles removed */ + logger_write_history(log->history_removed, e, f); + /* Close file */ fclose(f); - - ++outputCount; } /** diff --git a/src/logger_io.h b/src/logger_io.h index 0a11de5ca9d0acbb650e4ef4fc305dc5266b5a9f..2c0cfd5a800ce72c75e5dc69e765c712a4768922 100644 --- a/src/logger_io.h +++ b/src/logger_io.h @@ -65,6 +65,8 @@ struct mask_data { } reader; }; +void write_index_array(const struct engine* e, FILE* f, struct io_props* props, + size_t n_props, size_t N); /** * @brief Initialize the mask_data with a given field. * diff --git a/src/mpiuse.c b/src/mpiuse.c index 84ca2a03a0100afe68ba75ac8066fc8e305ccfcf..b50bdc3458341bbd951012a0bf15047cae64644c 100644 --- a/src/mpiuse.c +++ b/src/mpiuse.c @@ -222,7 +222,7 @@ void mpiuse_log_dump(const char *filename, ticks stepticks) { struct memuse_rnode *child = memuse_rnode_find_child( memuse_rnode_root, 0, mpiuse_log[k].vptr, sizeof(uintptr_t)); - if (child != NULL && child->ptr != NULL) { + if (child != NULL && child->value != -1) { /* Should be the handoff. Check that. */ if (mpiuse_log[k].activation) { @@ -240,7 +240,7 @@ void mpiuse_log_dump(const char *filename, ticks stepticks) { } /* Free, update the missing fields, size of request is removed. */ - struct mpiuse_log_entry *oldlog = (struct mpiuse_log_entry *)child->ptr; + struct mpiuse_log_entry *oldlog = (struct mpiuse_log_entry *)child->value; mpiuse_log[k].size = -oldlog->size; mpiuse_log[k].otherrank = oldlog->otherrank; mpiuse_log[k].tag = oldlog->tag; @@ -249,7 +249,7 @@ void mpiuse_log_dump(const char *filename, ticks stepticks) { mpiuse_log[k].acttic = mpiuse_log[k].tic - oldlog->tic; /* And deactivate this key. */ - child->ptr = NULL; + child->value = -1; /* And mark this as handed off. */ mpiuse_log[k].active = 0; @@ -260,7 +260,7 @@ void mpiuse_log_dump(const char *filename, ticks stepticks) { /* Not found, so new send/recv which we store the log against the * address. */ memuse_rnode_insert_child(memuse_rnode_root, 0, mpiuse_log[k].vptr, - sizeof(uintptr_t), &mpiuse_log[k]); + sizeof(uintptr_t), (int64_t)&mpiuse_log[k]); } else if (child == NULL && !mpiuse_log[k].activation) { @@ -279,7 +279,7 @@ void mpiuse_log_dump(const char *filename, ticks stepticks) { /* Must be previously released request with the same address, so we * store. */ memuse_rnode_insert_child(memuse_rnode_root, 0, mpiuse_log[k].vptr, - sizeof(uintptr_t), &mpiuse_log[k]); + sizeof(uintptr_t), (int64_t)&mpiuse_log[k]); } else { message("Weird MPI log record found: (%s/%s: %d->%d: %zd/%d/%d/%p)", diff --git a/src/output_options.c b/src/output_options.c index 50cd088c05aac1ccfb3a10abc954832153944dbd..f5e1a10575a016d9f4e845f8856fdcb715191fda 100644 --- a/src/output_options.c +++ b/src/output_options.c @@ -134,7 +134,7 @@ void output_options_struct_restore(struct output_options* output_options, * output (i.e. top level section in the yaml). * @param field_name pointer to a char array containing the name of the * relevant field. - * @param part_type integer particle type + * @param ptype integer particle type * @param compression_level_current_default The default output strategy *. based on the snapshot_type and part_type. * @@ -143,13 +143,13 @@ void output_options_struct_restore(struct output_options* output_options, **/ enum lossy_compression_schemes output_options_get_field_compression( const struct output_options* output_options, const char* snapshot_type, - const char* field_name, const enum part_type part_type, + const char* field_name, const enum part_type ptype, const enum lossy_compression_schemes compression_level_current_default) { /* Full name for the field path */ char field[PARSER_MAX_LINE_SIZE]; sprintf(field, "%.*s:%.*s_%s", FIELD_BUFFER_SIZE, snapshot_type, - FIELD_BUFFER_SIZE, field_name, part_type_names[part_type]); + FIELD_BUFFER_SIZE, field_name, part_type_names[ptype]); char compression_level[FIELD_BUFFER_SIZE]; parser_get_opt_param_string( @@ -178,16 +178,16 @@ enum lossy_compression_schemes output_options_get_field_compression( * * @param output_params The parsed select output file. * @param snapshot_type The type of snapshot we are writing - * @param part_type The #part_type we are considering. + * @param ptype The #part_type we are considering. */ enum lossy_compression_schemes output_options_get_ptype_default_compression( struct swift_params* output_params, const char* snapshot_type, - const enum part_type part_type) { + const enum part_type ptype) { /* Full name for the default path */ char field[PARSER_MAX_LINE_SIZE]; sprintf(field, "%.*s:Standard_%s", FIELD_BUFFER_SIZE, snapshot_type, - part_type_names[part_type]); + part_type_names[ptype]); char compression_level[FIELD_BUFFER_SIZE]; parser_get_opt_param_string( @@ -210,7 +210,7 @@ enum lossy_compression_schemes output_options_get_ptype_default_compression( "A lossy default compression strategy was specified for snapshot " "type %s and particle type %d. This is not allowed, lossy " "compression must be set on a field-by-field basis.", - snapshot_type, part_type); + snapshot_type, ptype); #ifdef SWIFT_DEBUG_CHECKS /* Check whether we could translate the level string to a known entry. */ @@ -218,13 +218,12 @@ enum lossy_compression_schemes output_options_get_ptype_default_compression( error( "Could not resolve compression level \"%s\" as default compression " "level of particle type %s in snapshot type %s.", - compression_level, part_type_names[part_type], snapshot_type); + compression_level, part_type_names[ptype], snapshot_type); message( "Determined default compression level of %s in snapshot type %s " "as \"%s\", corresponding to level code %d", - part_type_names[part_type], snapshot_type, compression_level, - level_index); + part_type_names[ptype], snapshot_type, compression_level, level_index); #endif return (enum lossy_compression_schemes)level_index; diff --git a/src/part.c b/src/part.c index cfc5338a69ee0f85483b8b26591f3f9d0c7d6475..f3744e931dad6cad7dedaac9ba4a0a58a8e1939f 100644 --- a/src/part.c +++ b/src/part.c @@ -450,21 +450,21 @@ void part_verify_links(struct part *parts, struct gpart *gparts, /* Check the link */ if (sparts[k].gpart->id_or_neg_offset != -(ptrdiff_t)k) { error("Linking problem !"); + } - /* Check that the particles are at the same place */ - if (sparts[k].x[0] != sparts[k].gpart->x[0] || - sparts[k].x[1] != sparts[k].gpart->x[1] || - sparts[k].x[2] != sparts[k].gpart->x[2]) - error("Linked particles are not at the same position !"); + /* Check that the particles are at the same place */ + if (sparts[k].x[0] != sparts[k].gpart->x[0] || + sparts[k].x[1] != sparts[k].gpart->x[1] || + sparts[k].x[2] != sparts[k].gpart->x[2]) + error("Linked particles are not at the same position !"); - /* Check that the particles have the same mass */ - if (sparts[k].mass != sparts[k].gpart->mass) - error("Linked particles do not have the same mass!\n"); + /* Check that the particles have the same mass */ + if (sparts[k].mass != sparts[k].gpart->mass) + error("Linked particles do not have the same mass!\n"); - /* Check that the particles are at the same time */ - if (sparts[k].time_bin != sparts[k].gpart->time_bin) - error("Linked particles are not at the same time !"); - } + /* Check that the particles are at the same time */ + if (sparts[k].time_bin != sparts[k].gpart->time_bin) + error("Linked particles are not at the same time !"); } } @@ -477,21 +477,21 @@ void part_verify_links(struct part *parts, struct gpart *gparts, /* Check the link */ if (bparts[k].gpart->id_or_neg_offset != -(ptrdiff_t)k) { error("Linking problem !"); + } - /* Check that the particles are at the same place */ - if (bparts[k].x[0] != bparts[k].gpart->x[0] || - bparts[k].x[1] != bparts[k].gpart->x[1] || - bparts[k].x[2] != bparts[k].gpart->x[2]) - error("Linked particles are not at the same position !"); + /* Check that the particles are at the same place */ + if (bparts[k].x[0] != bparts[k].gpart->x[0] || + bparts[k].x[1] != bparts[k].gpart->x[1] || + bparts[k].x[2] != bparts[k].gpart->x[2]) + error("Linked particles are not at the same position !"); - /* Check that the particles have the same mass */ - if (bparts[k].mass != bparts[k].gpart->mass) - error("Linked particles do not have the same mass!\n"); + /* Check that the particles have the same mass */ + if (bparts[k].mass != bparts[k].gpart->mass) + error("Linked particles do not have the same mass!\n"); - /* Check that the particles are at the same time */ - if (bparts[k].time_bin != bparts[k].gpart->time_bin) - error("Linked particles are not at the same time !"); - } + /* Check that the particles are at the same time */ + if (bparts[k].time_bin != bparts[k].gpart->time_bin) + error("Linked particles are not at the same time !"); } } @@ -504,21 +504,21 @@ void part_verify_links(struct part *parts, struct gpart *gparts, /* Check the link */ if (sinks[k].gpart->id_or_neg_offset != -(ptrdiff_t)k) { error("Linking problem !"); + } - /* Check that the particles are at the same place */ - if (sinks[k].x[0] != sinks[k].gpart->x[0] || - sinks[k].x[1] != sinks[k].gpart->x[1] || - sinks[k].x[2] != sinks[k].gpart->x[2]) - error("Linked particles are not at the same position !"); + /* Check that the particles are at the same place */ + if (sinks[k].x[0] != sinks[k].gpart->x[0] || + sinks[k].x[1] != sinks[k].gpart->x[1] || + sinks[k].x[2] != sinks[k].gpart->x[2]) + error("Linked particles are not at the same position !"); - /* Check that the particles have the same mass */ - if (sinks[k].mass != sinks[k].gpart->mass) - error("Linked particles do not have the same mass!\n"); + /* Check that the particles have the same mass */ + if (sinks[k].mass != sinks[k].gpart->mass) + error("Linked particles do not have the same mass!\n"); - /* Check that the particles are at the same time */ - if (sinks[k].time_bin != sinks[k].gpart->time_bin) - error("Linked particles are not at the same time !"); - } + /* Check that the particles are at the same time */ + if (sinks[k].time_bin != sinks[k].gpart->time_bin) + error("Linked particles are not at the same time !"); } } diff --git a/src/random.h b/src/random.h index d3432f3ff2edeb6931bbab6173d31af31f74cbde..1ecb2683f558df319bdbb216511aa4ab14a1d9b5 100644 --- a/src/random.h +++ b/src/random.h @@ -56,9 +56,14 @@ enum random_number_type { random_number_sink_formation = 5947309451LL, random_number_stellar_feedback_1 = 3947008991LL, random_number_stellar_feedback_2 = 6977309513LL, + random_number_stellar_feedback_3 = 9762399103LL, + random_number_isotropic_SNII_feedback_ray_theta = 3298327511LL, + random_number_isotropic_SNII_feedback_ray_phi = 6311114273LL, + random_number_isotropic_AGN_feedback_ray_theta = 8899891613LL, + random_number_isotropic_AGN_feedback_ray_phi = 10594523341LL, random_number_stellar_enrichment = 2936881973LL, random_number_BH_feedback = 1640531371LL, - random_number_BH_swallow = 4947009007LL + random_number_BH_swallow = 4947009007LL, }; #ifndef __APPLE__ @@ -184,4 +189,27 @@ INLINE static double random_unit_interval(int64_t id, return inl_erand48(seed48); } +INLINE static double random_unit_interval_two_IDs( + int64_t id_star, int64_t id_gas, const integertime_t ti_current, + const enum random_number_type type) { + + /* We need to combine the gas and star IDs such that we do not get correlation + * for same id_star + id_gas pairs, because of this we combine everything + * nonlinearly */ + int64_t input_id = (id_star * id_gas + id_star * ti_current + + id_gas * ti_current * ti_current) % + INT64_MAX; + + return random_unit_interval(input_id, ti_current, type); +} + +INLINE static double random_unit_interval_part_ID_and_ray_idx( + int64_t id_star, const int ray_idx, const integertime_t ti_current, + const enum random_number_type type) { + + /* For better mixing, we apply a non-linear transformation y=x^3 */ + const long long ray_idx_3 = ray_idx * ray_idx * ray_idx; + return random_unit_interval_two_IDs(id_star, ray_idx_3, ti_current, type); +} + #endif /* SWIFT_RANDOM_H */ diff --git a/src/rays.h b/src/rays.h new file mode 100644 index 0000000000000000000000000000000000000000..174ce74a0c45500cdf9c0bd4c59c83b9b9ee855e --- /dev/null +++ b/src/rays.h @@ -0,0 +1,479 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Evgenii Chaikin (chaikin@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_RAYS_H +#define SWIFT_RAYS_H + +/** + * @brief For a given feedback scheme, sets all fields in the ray struct + * array at their default values + * + * @param rays An array of ray structs + * @param max_number_of_rays Maximum number of rays in the feedback scheme + */ +__attribute__((always_inline)) INLINE static void ray_init( + struct ray_data *rays, const int max_number_of_rays) { + + /* Set all fields in the ray struct at their default values */ + for (int i = 0; i < max_number_of_rays; i++) { + rays[i].id_min_length = -1; + rays[i].min_length = FLT_MAX; + rays[i].mass = 0.f; + } +} + +/** + * @brief Reset the ray(s) that point to the particle with a given id + * + * @param rays An array of ray structs + * @param max_number_of_rays Maximum number of rays in the feedback scheme + * @param gas_part_id The id of the gas particle the ray is pointing to + */ +__attribute__((always_inline)) INLINE static void ray_reset_part_id( + struct ray_data *rays, const int max_number_of_rays, + const long long gas_part_id) { + + /* Loop over all rays the provided stellar/BH particle has */ + for (int i = 0; i < max_number_of_rays; i++) { + + /* Find the ray carrying the gas-partile id equal to gas_part_id */ + if (rays[i].id_min_length == gas_part_id) { + + /* Reset all fields in this ray */ + rays[i].id_min_length = -1; + rays[i].min_length = FLT_MAX; + rays[i].mass = 0.f; + } + } +} + +/** + * @brief For a given feedback scheme, sets all fields in the ray_extra + * struct array at their default values + * + * @param rays_ext An array of ray_extra structs + * @param max_number_of_rays Maximum number of rays in the feedback scheme + */ +__attribute__((always_inline)) INLINE static void ray_extra_init( + struct ray_data_extra *rays_ext, const int max_number_of_rays) { + + /* Set all fields in the ray struct at their default values */ + for (int i = 0; i < max_number_of_rays; i++) { + for (int j = 0; j < 3; j++) { + rays_ext[i].x[j] = 0.f; + rays_ext[i].v[j] = 0.f; + } + } +} + +/** + * @brief Returns the arc length on a sphere of radius r_sphere + * between two points with angular coordinates (theta_1, phi_1) and (theta_2, + * phi_2) + * + * @param theta_1 Polar angle of point 1; \theta \in [-\pi/2, \pi/2] + * @param phi_1 Azimuthal angle of point 1; \phi \in [-\pi, \pi) + * @param theta_2 Polar angle of point 2; \theta \in [-\pi/2, \pi/2] + * @param phi_2 Azimuthal angle of point 2; \phi \in [-\pi, \pi) + * @param r_sphere Radius of the sphere on which the arc length between the two + * points is computed + */ +__attribute__((always_inline)) INLINE static float ray_arclength( + const double theta_1, const double phi_1, const double theta_2, + const double phi_2, const float r_sphere) { + + const double delta_theta = theta_2 - theta_1; + const double delta_phi = phi_2 - phi_1; + + const double sine_theta = sin(delta_theta / 2.0); + const double sine_phi = sin(delta_phi / 2.0); + + const float arc_length = + asin(sqrt(sine_theta * sine_theta + + cos(theta_1) * cos(theta_2) * sine_phi * sine_phi)); + + return 2.f * r_sphere * arc_length; +} + +/** + * @brief For a given ray, minimise the arc length between the stellar/BH + * particle and the gas neighbours in the isotropic feedback and store relevant + * properties of the gas particle that has the minimum arc length with the ray + * + * @param dx Comoving vector separating both particles (si - pj) + * @param r Comoving distance between the two particles + * @param ray Ray data + * @param mirror_particle_switch Mirror particle switch + * @param gas_part_id ID of the gas particle + * @param rand_theta_gen Random number to generate \theta_ray + * @param rand_phi_gen Random number to generate \phi_ray + * @param m Gas particle mass + * @param ray_ext Extra ray data + * @param v Gas particle velocity + */ +__attribute__((always_inline)) INLINE static void ray_minimise_arclength( + const float *dx, const float r, struct ray_data *ray, + const int mirror_particle_switch, const long long gas_part_id, + const double rand_theta_gen, const double rand_phi_gen, const float m, + struct ray_data_extra *ray_ext, const float *v) { + + /* Angular coordinates of the particle with respect to the star/BH */ + const double theta_j = acos(-dx[2] / r); + const double phi_j = atan2(-dx[1], -dx[0]); + + /* Transform the random number from [0,1[ to [-1, 1[ */ + const double cos_theta_ray = 2. * rand_theta_gen - 1.; + + /* Get the \theta angle */ + double theta_ray = acos(cos_theta_ray); + + /* Transform the random number from [0,1[ to [-pi, pi[ */ + double phi_ray = 2.0 * M_PI * rand_phi_gen - M_PI; + + /* Flip the angles if it is a mirror particle */ + if (mirror_particle_switch == 1) { + theta_ray = M_PI - theta_ray; + phi_ray = phi_ray - copysign(M_PI, phi_ray); + } + + /* Calculate the arc length on a unit sphere between the gas particle + * and this ray. Note that shift by -\pi/2 is required for the \theta's */ + const float new_length = ray_arclength( + theta_ray - M_PI_2, phi_ray, theta_j - M_PI_2, phi_j, /*r_sphere=*/1.f); + + /* If the new arc length is smaller than the older value, store + * the new one alongside the particle id and its other relevant + * properties that will be used later */ + if (new_length < ray->min_length) { + + ray->min_length = new_length; + ray->id_min_length = gas_part_id; + ray->mass = m; + + /* In stellar feedback, we do kicks so we need to store additional data */ + if (mirror_particle_switch != -1) { + + /* Position and velocities are neIf prob <1. and we are running with eded + * in SNII kinetic feedback to exactly conserve momentum and energy. + * That's because in a pair of two particles, the first one needs to know + * the properties of the other one, and vice versa */ + + ray_ext->x[0] = -dx[0]; + ray_ext->x[1] = -dx[1]; + ray_ext->x[2] = -dx[2]; + + ray_ext->v[0] = v[0]; + ray_ext->v[1] = v[1]; + ray_ext->v[2] = v[2]; + } + } +} + +/** + * @brief Compute the kick velocity in stellar kinetic feedback + * + * @param v_kick The kick velocty vector to be computed + * @param v_kick_abs Modulus of the kick velocity vector + * @param ray_ext_true Extra ray data of the true gas particle + * @param ray_ext_mirr Extra ray data of the mirror gas particle + * @param mirror_particle_switch Mirror particle switch + * @param energy_pair SN energy per pair + * @param cosmo The cosmological model + * @param current_mass Current mass of the gas particle + * @param v_star Velocity of the stellar particle + * @param rand_theta_gen Random number to generate \theta_ray + * @param rand_phi_gen Random number to generate \phi_ray + * @param mass_true Unaffected mass of the true particle + * @param mass_mirror Unaffected mass of the mirror particle + */ +__attribute__((always_inline)) INLINE static void +ray_kinetic_feedback_compute_kick_velocity( + float *v_kick, float *v_kick_abs, const struct ray_data_extra *ray_ext_true, + const struct ray_data_extra *ray_ext_mirr, const int mirror_particle_switch, + const double energy_pair, const struct cosmology *cosmo, + const double current_mass, const float *v_star, const double rand_theta_gen, + const double rand_phi_gen, const double mass_true, + const double mass_mirror) { + + /* Transform the random number from [0,1[ to [-1, 1[ */ + const double cos_theta_ray = 2. * rand_theta_gen - 1.; + + /* Transform the random number from [0,1[ to [-pi, pi[ */ + const double phi_ray = 2.0 * M_PI * rand_phi_gen - M_PI; + + /* To conserve angular momentum -- along with linear momentum and energy + * -- we need to kick the two particles in the pair along the line that + * connects these two particles. In the code below, we start with + * finding the equation defining this line. The line equation(-s) reads: + * (x-x_0)/a = (y-y_0)/b = (z-z_0)/c . We thus need to find the + * coefficients a, b and c. Since we already know two points on this + * line, which are the particles' positions, this is a straightforward + * exercise to do. */ + + /* Coefficients defining the line connecting the two particles */ + double a, b, c; + + /* Modulus of the vector {a, b, c} that defines the line + * connecting the original particle with the mirror particle */ + double normalisation; + + /* The kick angles (with respect to the stellar particle) */ + double phi_kick, theta_kick; + + /* If we have no degeneracy along the x coordinate, we can divide + * by (x_2 - x_1) to compute the coefficients b and c */ + if (ray_ext_true->x[0] != ray_ext_mirr->x[0]) { + + /* Due to the freedom in normalisation, the coefficient a can be + * set to unity */ + a = 1.0; + + /* Compute b = b/1.0 = b/a = (y_2 - y_1) / (x_2 - x_1) */ + b = (ray_ext_true->x[1] - ray_ext_mirr->x[1]) / + (ray_ext_true->x[0] - ray_ext_mirr->x[0]); + + /* Compute c = c/1.0 = c/a = (z_2 - z_1) / (x_2 - x_1) */ + c = (ray_ext_true->x[2] - ray_ext_mirr->x[2]) / + (ray_ext_true->x[0] - ray_ext_mirr->x[0]); + + /* Compute the modulus of {a, b, c} and the kick angles */ + normalisation = sqrt(1.0 + b * b + c * c); + phi_kick = atan2(b, 1.0); + theta_kick = acos(c / normalisation); + } + + /* If x2 and x1 are the same, we cannot divide by (x_2 - x_1) + * If we have no degeneracy along the y coordinate, we can divide + * by (y_2 - y_1) to compute the coefficient c */ + else if (ray_ext_true->x[1] != ray_ext_mirr->x[1]) { + + /* Since x_2 = x_1, the line is perpendicular to the x axis so + * that a = 0 and \phi_kick = \pi/2 */ + a = 0.0; + + /* Due to the freedom in normalisation, the coefficient b can be + * set to unity */ + b = 1.0; + + /* Compute c = c/1.0 = c/b = (z_2 - z_1) / (y_2 - y_1) */ + c = (ray_ext_true->x[2] - ray_ext_mirr->x[2]) / + (ray_ext_true->x[1] - ray_ext_mirr->x[1]); + + /* Compute the modulus of {a ,b ,c} and the kick angles */ + normalisation = sqrt(1.0 + c * c); + phi_kick = M_PI_2; + theta_kick = acos(c / normalisation); + } + + /* y_2 - y_1 = 0 as well as x_2 - x_1 = 0 */ + else { + + /* The line is parallel to the z axis, the coefficients a and b + * are zero. The angles \phi_kick = 0.0, and \theta_kick = 0.0 */ + a = 0.0; + b = 0.0; + + /* Due to the freedom in normalisation, the coefficient c can be + * set to unity */ + c = 1.0; + + /* Compute the modulus of {a ,b ,c} and the kick angles */ + normalisation = 1.0; + phi_kick = 0.0; + theta_kick = 0.0; + } + + /* By now, by computing the equation of the line connecting the two + * particles in the pair, we have found the direction of the kick. + * However, for a given particle in the pair, we know this direction + * only up to a sign, i.e. we as of yet do not know whether we should + * kick the particle "up" or "down" the line. In order to get the sign + * right we need to do some additional calculations. Namely, we need + * to compare the direction of the line we found with that of the + * original and mirror rays. In total, we have four cases: + * + * 1 and 2: IF the (theta_kick, phi_kick) direction is closest to the + * direction of the original (mirror) ray AND we have caught the + * original (mirror) particle THEN kick along the (theta_kick, + * phi_kick) direction. 3 and 4: IF the (theta_kick, phi_kick) + * direction is closest to the direction of the original (mirror) ray + * BUT we have caught the mirror (original) particle THEN kick along + * the opposite (\pi - theta_kick, phi_kick - pi*sign(phi_kick)) + * direction */ + + /* Thus far we've only got cos\theta. But in order to compute arc + lengths used in the algorithm described above we need \theta */ + const double theta_ray = acos(cos_theta_ray); + + /* Compute the arc lengh between the original ray and the line + * defining the direction of the kicks. We shift \theta coordinates + * by -\pi/2 because we have \theta \in [0, \pi[ while the function + * wants \theta \in [-\pi/2, \pi/2[*/ + const double arclength_true = + ray_arclength(theta_kick - M_PI_2, phi_kick, theta_ray - M_PI_2, phi_ray, + /*r_sphere=*/1.f); + + /* \theta and \phi angles of the mirror ray, pointing in the + * direction opposite to the original one. We need those to compute + * the arc length below */ + const double theta_ray_mirror = M_PI - theta_ray; + const double phi_ray_mirror = phi_ray - copysign(M_PI, phi_ray); + + /* Compute the arc lengh between the mirror ray and the line defining + * the direction of the kicks */ + const double arclength_mirror = + ray_arclength(theta_kick - M_PI_2, phi_kick, theta_ray_mirror - M_PI_2, + phi_ray_mirror, /*r_sphere=*/1.f); + + /* Find the minimum arc length between the two arc lengths computed + * above */ + const double arclength_min = min(arclength_true, arclength_mirror); + + /* Find out whether the minimal arc length is that with the original + ray or the mirror ray */ + const int mirror_ray_switch = (arclength_min == arclength_mirror); + + /* Compute the sign of the kick depending on which case we are in: 1, + * 2, 3 or 4 */ + const double kick_sign = + (mirror_particle_switch == mirror_ray_switch) ? 1.0 : -1.0; + + /* Compute the normal vector of the kick */ + const double n_kick[3] = {kick_sign * a / normalisation, // x, + kick_sign * b / normalisation, // y + kick_sign * c / normalisation}; // z + + /* Compute mass weights that are used below */ + /* Note that mass_true and current_mass may differ if, for example, + * at this time-step the considered here gas particle has already + * received some ejecta mass from another star. To compute the weights, + * we need to use the "unaffected" mass, mass_true, because it does not + * change when viewed from either of the particles in the pair. At the + * same time, in the definition of mass_weight, we do divide by + * current_mass and not by mass_true since this is the weight for the + * velocity v, which -- for the considered gas particle -- is related to + * the momentum p as p = current_mass * v and not via mass_true. The + * differences between current_mass and mass_true, if ever exist, are + * obviously very minor. Nonetheless, these are not negligible because + * we require the exact conservation of linear momentum. */ + const double m_alpha = + sqrt(mass_true * mass_mirror) / (mass_true + mass_mirror); + const double mass_weight = sqrt(mass_true * mass_mirror) / current_mass; + + /* Relative velocity between the gas particle and the stellar particle + */ + double v_gas_star[3] = {ray_ext_true->v[0] - v_star[0], + ray_ext_true->v[1] - v_star[1], + ray_ext_true->v[2] - v_star[2]}; + + /* Relative velocity between the mirror gas particle and the stellar + * particle */ + double v_gas_mirror_star[3] = {ray_ext_mirr->v[0] - v_star[0], + ray_ext_mirr->v[1] - v_star[1], + ray_ext_mirr->v[2] - v_star[2]}; + + /* Divide the velocities by the cosmic scale factor + to get peculiar velocities in proper coordinates */ + for (int j = 0; j < 3; j++) { + v_gas_star[j] /= cosmo->a; + v_gas_mirror_star[j] /= cosmo->a; + } + + /* Compute scalar product between v_gas_star and n */ + const double v_cos_theta = v_gas_star[0] * n_kick[0] + + v_gas_star[1] * n_kick[1] + + v_gas_star[2] * n_kick[2]; + + /* Compute scalar product between v_gas_mirror_star and n */ + const double v_mirror_cos_theta = v_gas_mirror_star[0] * n_kick[0] + + v_gas_mirror_star[1] * n_kick[1] + + v_gas_mirror_star[2] * n_kick[2]; + + /* Compute the characteristic kick velocity corresponding to the kinetic + * energy per pair. */ + const double SNII_delta_v = + sqrt(2.0 * energy_pair / (mass_true + mass_mirror)); + + /* Compute the correction to the energy and momentum due to relative + * star-gas motion. If it is the mirror particle multiply by the minus + * sign. If there is no correction then alpha = 0 and beta = 1 */ + const double correction_sign = (mirror_particle_switch) ? -1.0 : 1.0; + + const double alpha = correction_sign * m_alpha * + (v_cos_theta - v_mirror_cos_theta) / SNII_delta_v; + const double beta = sqrt(alpha * alpha + 1.0) - alpha; + + /* Compute the physical kick velocity in internal units */ + (*v_kick_abs) = SNII_delta_v * mass_weight * beta; + + /* The kick velocity vector */ + v_kick[0] = (*v_kick_abs) * n_kick[0]; + v_kick[1] = (*v_kick_abs) * n_kick[1]; + v_kick[2] = (*v_kick_abs) * n_kick[2]; +} + +/** + * @brief Minimises the distance between the stellar/BH particle and + * its neighbours. In the resulting ray array, the gas neighbours will + * be sorted based on their separation from the star/BH. The left-most + * element will store the information of the particle with the smallest + * distance to the star/BH, and the right-most with the largest. + * + * @param r Comoving distance between the two particles + * @param ray Ray data + * @param N_ray_arr Size of ray array + * @param gas_part_id ID of the gas particle + * @param m Gas particle mass + */ +__attribute__((always_inline)) INLINE static void ray_minimise_distance( + const float r, struct ray_data *ray, const int N_ray_arr, + const long long gas_part_id, const float m) { + + /* Id of the element of the ray array that we want to update */ + int elem_update_id = -1; + + /* Loop from left to right. Find the left-most element whose + * current min length is larger than r. Note that N_ray_arr is + * equal to min(how many times this function has been called + * at this time-step, the maximum number of rays per particle) */ + for (int i = 0; i < N_ray_arr; i++) { + if (r < ray[i].min_length) { + elem_update_id = i; + break; + } + } + + /* If found something to update */ + if (elem_update_id != -1) { + + /* Loop from right to left. Before updating elem_update_id, move + * everything to the right by one element. */ + for (int i = N_ray_arr - 2; i >= elem_update_id; i--) { + ray[i + 1].min_length = ray[i].min_length; + ray[i + 1].id_min_length = ray[i].id_min_length; + ray[i + 1].mass = ray[i].mass; + } + + /* Update elem_update_id */ + ray[elem_update_id].min_length = r; + ray[elem_update_id].id_min_length = gas_part_id; + ray[elem_update_id].mass = m; + } +} + +#endif /* SWIFT_RAYS_H */ diff --git a/src/rays_struct.h b/src/rays_struct.h new file mode 100644 index 0000000000000000000000000000000000000000..5e8c97ecc28ab4529fb23bd8b51695643e8f4d5a --- /dev/null +++ b/src/rays_struct.h @@ -0,0 +1,52 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Coypright (c) 2020 Evgenii Chaikin (chaikin@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_RAYS_STRUCT_H +#define SWIFT_RAYS_STRUCT_H + +/** + * @brief Fields used in isotropic thermal SN/AGN feedback + */ +struct ray_data { + + /*! The mininum length (arc length or distance) between this + ray and the gas neighbours in the stellar/BH kernel */ + float min_length; + + /*! The gas particle ID that has the minimal length + * (arc length or distance) with respect to this ray !*/ + long long id_min_length; + + /*! Gas-particle mass in code units */ + float mass; +}; + +/** + * @brief Additional fields used in isotropic kinetic SN feedback + */ +struct ray_data_extra { + + /*! Gas particle's comoving position in + code units with respect to the star/BH */ + float x[3]; + + /*! Gas particle's internal velocity in code units */ + float v[3]; +}; + +#endif /* SWIFT_RAYS_STRUCT_H */ diff --git a/src/rt/M1closure/rt.h b/src/rt/M1closure/rt.h index b99aa2009ba2ff99a167673e938ff4536172118d..07bd3c945796f180c198b9c6c8a9d8203920b7b1 100644 --- a/src/rt/M1closure/rt.h +++ b/src/rt/M1closure/rt.h @@ -25,11 +25,16 @@ */ /** - * @brief Update the photon number of a particle, i.e. compute - * E^{n+1} = E^n + dt * dE_* / dt + * @brief Initialisation of the RT density loop related particle data. */ -__attribute__((always_inline)) INLINE static void -rt_injection_update_photon_density(struct part* restrict p) {} +__attribute__((always_inline)) INLINE static void rt_init_part( + struct part* restrict p) {} + +/** + * @brief Reset of the RT extra hydro particle data. + */ +__attribute__((always_inline)) INLINE static void rt_reset_part( + struct part* restrict p) {} /** * @brief First initialisation of the RT extra hydro particle data. @@ -38,21 +43,43 @@ __attribute__((always_inline)) INLINE static void rt_first_init_part( struct part* restrict p) {} /** - * @brief Initialisation of the RT extra hydro particle data. + * @brief Initialisation of the RT density loop related particle data. */ -__attribute__((always_inline)) INLINE static void rt_init_part( - struct part* restrict p) {} +__attribute__((always_inline)) INLINE static void rt_init_spart( + struct spart* restrict sp) {} /** - * @brief First initialisation of the RT extra star particle data. + * @brief Reset of the RT extra star particle data. */ -__attribute__((always_inline)) INLINE static void rt_first_init_spart( +__attribute__((always_inline)) INLINE static void rt_reset_spart( struct spart* restrict sp) {} /** * @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) {} +/** + * @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 Compute the photon emission rates for this stellar particle + * This function is called every time the spart is initialized + * and assumes that the photon emission rate is an intrinsic + * stellar property, i.e. doesn't depend on the environment. + * + * @param sp star particle to work on + * @param time current system time + * @param star_age age of the star *at the end of the step* + * @param dt star time step + */ +__attribute__((always_inline)) INLINE static void +rt_compute_stellar_emission_rate(struct spart* restrict sp, double time, + double star_age, double dt) {} + #endif /* SWIFT_RT_M1_H */ diff --git a/src/rt/debug/rt.h b/src/rt/debug/rt.h index 92df9619935bd74cd42e0dadab22fa7947e4064a..97a74cf0ccdb8c993d9e7b9f0d1df917fc329097 100644 --- a/src/rt/debug/rt.h +++ b/src/rt/debug/rt.h @@ -25,21 +25,15 @@ */ /** - * @brief Update the photon number of a particle, i.e. compute - * E^{n+1} = E^n + dt * dE_* / dt + * @brief Initialisation of the RT density loop related particle data. */ -__attribute__((always_inline)) INLINE static void -rt_injection_update_photon_density(struct part* restrict p) { - - p->rt_data.photon_number_updated = 1; - p->rt_data.calls_tot += 1; - p->rt_data.calls_per_step += 1; -} +__attribute__((always_inline)) INLINE static void rt_init_part( + struct part* restrict p) {} /** - * @brief Initialisation of the RT extra hydro particle data. + * @brief Reset of the RT extra hydro particle data. */ -__attribute__((always_inline)) INLINE static void rt_init_part( +__attribute__((always_inline)) INLINE static void rt_reset_part( struct part* restrict p) { p->rt_data.calls_per_step = 0; @@ -57,18 +51,27 @@ __attribute__((always_inline)) INLINE static void rt_first_init_part( p->rt_data.calls_tot = 0; rt_init_part(p); + rt_reset_part(p); } /** - * @brief Initialisation of the RT extra star particle data. + * @brief Initialisation of the RT density loop related particle data. */ __attribute__((always_inline)) INLINE static void rt_init_spart( + struct spart* restrict sp) {} + +/** + * @brief Reset of the RT extra star particle data. + */ +__attribute__((always_inline)) INLINE static void rt_reset_spart( struct spart* restrict sp) { + /* reset everything */ sp->rt_data.calls_per_step = 0; sp->rt_data.iact_hydro_inject = 0; sp->rt_data.calls_self_inject = 0; sp->rt_data.calls_pair_inject = 0; + sp->rt_data.emission_rate_set = 0; } /** @@ -79,6 +82,52 @@ __attribute__((always_inline)) INLINE static void rt_first_init_spart( sp->rt_data.calls_tot = 0; rt_init_spart(sp); + rt_reset_spart(sp); +} + +/** + * @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) { + + p->rt_data.photon_number_updated = 1; + p->rt_data.calls_tot += 1; + p->rt_data.calls_per_step += 1; +} + +/** + * @brief Compute the photon emission rates for this stellar particle + * This function is called every time the spart is initialized + * and assumes that the photon emission rate is an intrinsic + * stellar property, i.e. doesn't depend on the environment. + * + * @param sp star particle to work on + * @param time current system time + * @param star_age age of the star *at the end of the step* + * @param dt star time step + */ +__attribute__((always_inline)) INLINE static void +rt_compute_stellar_emission_rate(struct spart* restrict sp, double time, + double star_age, double dt) { + + /* first reset old values */ + rt_reset_spart(sp); + + if (time == 0.) { + /* if this is the zeroth step, time is still at zero. + * Do some bogus stuff for now. */ + star_age += 2 * dt; + } + if (star_age - dt >= 0.) { + sp->rt_data.emission_rate_set += 1; + } else { + error( + "Got negative time when setting emission rates?" + " %10.3g %10.3g", + star_age, dt); + } } #endif /* SWIFT_RT_DEBUG_H */ diff --git a/src/rt/debug/rt_io.h b/src/rt/debug/rt_io.h index a31aa59ce790b41c3754f7511632f39667a32e53..098caa26e8c4d6e0933edd8e61801a34cecdcd3e 100644 --- a/src/rt/debug/rt_io.h +++ b/src/rt/debug/rt_io.h @@ -94,6 +94,9 @@ INLINE static int rt_write_stars(const struct spart* sparts, "number of calls to this particle during one time " "step in injection pair task"); - return 5; + list[5] = io_make_output_field( + "RTEmissionRateSet", INT, 1, UNIT_CONV_NO_UNITS, 0, sparts, + rt_data.emission_rate_set, "Stellar photon emission rates set?"); + return 6; } #endif /* SWIFT_RT_IO_DEBUG_H */ diff --git a/src/rt/debug/rt_struct.h b/src/rt/debug/rt_struct.h index 20aa6c8dcf7c9e438069c1262609b2dea6ded8df..3ce246f61eba48eb7a765cfcae29013188b859f7 100644 --- a/src/rt/debug/rt_struct.h +++ b/src/rt/debug/rt_struct.h @@ -50,6 +50,7 @@ struct rt_spart_data { with */ int calls_self_inject; /* calls from self inject tasks */ int calls_pair_inject; /* calls from pair inject tasks */ + int emission_rate_set; /* stellar photon emisison rate has been computed */ }; #endif /* SWIFT_RT_STRUCT_DEBUG_H */ diff --git a/src/rt/none/rt.h b/src/rt/none/rt.h index c44819a77c247e2c68f6b96dfcfdfbbaa2360f47..69a7eeb3c6498eea3ca640660184bf87d6cd7606 100644 --- a/src/rt/none/rt.h +++ b/src/rt/none/rt.h @@ -25,11 +25,16 @@ */ /** - * @brief Update the photon number of a particle, i.e. compute - * E^{n+1} = E^n + dt * dE_* / dt + * @brief Initialisation of the RT density loop related particle data. */ -__attribute__((always_inline)) INLINE static void -rt_injection_update_photon_density(struct part* restrict p) {} +__attribute__((always_inline)) INLINE static void rt_init_part( + struct part* restrict p) {} + +/** + * @brief Reset of the RT extra hydro particle data. + */ +__attribute__((always_inline)) INLINE static void rt_reset_part( + struct part* restrict p) {} /** * @brief First initialisation of the RT extra hydro particle data. @@ -38,21 +43,43 @@ __attribute__((always_inline)) INLINE static void rt_first_init_part( struct part* restrict p) {} /** - * @brief Initialisation of the RT extra hydro particle data. + * @brief Initialisation of the RT density loop related particle data. */ -__attribute__((always_inline)) INLINE static void rt_init_part( - struct part* restrict p) {} +__attribute__((always_inline)) INLINE static void rt_init_spart( + struct spart* restrict sp) {} /** - * @brief First initialisation of the RT extra star particle data. + * @brief Reset of the RT extra star particle data. */ -__attribute__((always_inline)) INLINE static void rt_first_init_spart( +__attribute__((always_inline)) INLINE static void rt_reset_spart( struct spart* restrict sp) {} /** * @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) {} +/** + * @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 Compute the photon emission rates for this stellar particle + * This function is called every time the spart is initialized + * and assumes that the photon emission rate is an intrinsic + * stellar property, i.e. doesn't depend on the environment. + * + * @param sp star particle to work on + * @param time current system time + * @param star_age age of the star *at the end of the step* + * @param dt star time step + */ +__attribute__((always_inline)) INLINE static void +rt_compute_stellar_emission_rate(struct spart* restrict sp, double time, + double star_age, double dt) {} + #endif /* SWIFT_RT_NONE_H */ diff --git a/src/runner_doiact_functions_stars.h b/src/runner_doiact_functions_stars.h index 50ac49802d3ee11455dbb9be6de85a8d44ab5a76..7e802d6f4afd885697c3915d475d38a4e5da7a73 100644 --- a/src/runner_doiact_functions_stars.h +++ b/src/runner_doiact_functions_stars.h @@ -110,10 +110,10 @@ void DOSELF1_STARS(struct runner *r, struct cell *c, int timer) { IACT_STARS(r2, dx, hi, hj, si, pj, a, H); #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hi, hj, si, pj, NULL, cosmo, - ti_current); + e->feedback_props, ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) runner_iact_nonsym_feedback_apply(r2, dx, hi, hj, si, pj, xpj, cosmo, - ti_current); + e->feedback_props, ti_current); #endif } } /* loop over the parts in ci. */ @@ -219,10 +219,10 @@ void DO_NONSYM_PAIR1_STARS_NAIVE(struct runner *r, struct cell *restrict ci, #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hi, hj, si, pj, NULL, cosmo, - ti_current); + e->feedback_props, ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) runner_iact_nonsym_feedback_apply(r2, dx, hi, hj, si, pj, xpj, cosmo, - ti_current); + e->feedback_props, ti_current); #endif } } /* loop over the parts in cj. */ @@ -391,10 +391,11 @@ void DO_SYM_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj, #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hi, hj, spi, pj, NULL, - cosmo, ti_current); + cosmo, e->feedback_props, + ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) runner_iact_nonsym_feedback_apply(r2, dx, hi, hj, spi, pj, xpj, cosmo, - ti_current); + e->feedback_props, ti_current); #endif } } /* loop over the parts in cj. */ @@ -420,7 +421,7 @@ void DO_SYM_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj, #endif /* SWIFT_DEBUG_CHECKS */ /* Get some other useful values. */ - const double hj_max = cj->hydro.h_max * kernel_gamma; + const double hj_max = cj->stars.h_max * kernel_gamma; const int count_i = ci->hydro.count; const int count_j = cj->stars.count; struct part *restrict parts_i = ci->hydro.parts; @@ -519,10 +520,11 @@ void DO_SYM_PAIR1_STARS(struct runner *r, struct cell *ci, struct cell *cj, #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hj, hi, spj, pi, xpi, - cosmo, ti_current); + cosmo, e->feedback_props, + ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) runner_iact_nonsym_feedback_apply(r2, dx, hj, hi, spj, pi, xpi, cosmo, - ti_current); + e->feedback_props, ti_current); #endif } } /* loop over the parts in ci. */ @@ -640,7 +642,8 @@ void DOPAIR1_SUBSET_STARS(struct runner *r, struct cell *restrict ci, #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hi, hj, spi, pj, NULL, - cosmo, e->ti_current); + cosmo, e->feedback_props, + e->ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) error("No subset feedback iact functions do (or should) exist!"); /* runner_iact_nonsym_feedback_apply(r2, dx, hi, hj, spi, pj, xpj, @@ -700,7 +703,8 @@ void DOPAIR1_SUBSET_STARS(struct runner *r, struct cell *restrict ci, #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hi, hj, spi, pj, NULL, - cosmo, e->ti_current); + cosmo, e->feedback_props, + e->ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) error("No subset feedback iact functions do (or should) exist!"); /* runner_iact_nonsym_feedback_apply(r2, dx, hi, hj, spi, pj, xpj, @@ -795,7 +799,8 @@ void DOPAIR1_SUBSET_STARS_NAIVE(struct runner *r, struct cell *restrict ci, #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hi, hj, spi, pj, NULL, - cosmo, e->ti_current); + cosmo, e->feedback_props, + e->ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) error("No subset feedback iact functions do (or should) exist! ."); /* runner_iact_nonsym_feedback_apply(r2, dx, hi, hj, spi, pj, xpj, @@ -879,7 +884,8 @@ void DOSELF1_SUBSET_STARS(struct runner *r, struct cell *restrict ci, IACT_STARS(r2, dx, hi, pj->h, spi, pj, a, H); #if (FUNCTION_TASK_LOOP == TASK_LOOP_DENSITY) runner_iact_nonsym_feedback_density(r2, dx, hi, pj->h, spi, pj, NULL, - cosmo, e->ti_current); + cosmo, e->feedback_props, + e->ti_current); #elif (FUNCTION_TASK_LOOP == TASK_LOOP_FEEDBACK) error("No subset feedback iact functions do (or should) exist!"); /* runner_iact_nonsym_feedback_apply(r2, dx, hi, pj->h, spi, pj, xpj, */ diff --git a/src/runner_ghost.c b/src/runner_ghost.c index 5dac1b5083f36fc22d1c13a14d7946fce195f9bc..8ef7214d80f375cfdd6ace1fcd521c085231e256 100644 --- a/src/runner_ghost.c +++ b/src/runner_ghost.c @@ -77,6 +77,7 @@ void runner_do_stars_ghost(struct runner *r, struct cell *c, int timer) { const struct unit_system *us = e->internal_units; const struct phys_const *phys_const = e->physical_constants; const int with_cosmology = (e->policy & engine_policy_cosmology); + const int with_rt = (e->policy & engine_policy_rt); const struct cosmology *cosmo = e->cosmology; const struct feedback_props *feedback_props = e->feedback_props; const float stars_h_max = e->hydro_properties->h_max; @@ -398,6 +399,35 @@ void runner_do_stars_ghost(struct runner *r, struct cell *c, int timer) { /* Reset the feedback fields of the star particle */ feedback_reset_feedback(sp, feedback_props); } + + if (with_rt) { + + /* get star's age and time step for stellar emission rates */ + const integertime_t ti_begin = + get_integer_time_begin(e->ti_current - 1, sp->time_bin); + const integertime_t ti_step = get_integer_timestep(sp->time_bin); + + /* Get particle time-step */ + double dt_star; + if (with_cosmology) { + dt_star = cosmology_get_delta_time(e->cosmology, ti_begin, + ti_begin + ti_step); + } else { + dt_star = get_timestep(sp->time_bin, e->time_base); + } + + /* Calculate age of the star at current time */ + double star_age_end_of_step; + if (with_cosmology) { + star_age_end_of_step = cosmology_get_delta_time_from_scale_factors( + e->cosmology, (double)sp->birth_scale_factor, e->cosmology->a); + } else { + star_age_end_of_step = e->time - (double)sp->birth_time; + } + + rt_compute_stellar_emission_rate(sp, e->time, star_age_end_of_step, + dt_star); + } } /* We now need to treat the particles whose smoothing length had not @@ -847,9 +877,10 @@ void runner_do_black_holes_swallow_ghost(struct runner *r, struct cell *c, e->physical_constants, e->cosmology, dt); /* Compute variables required for the feedback loop */ - black_holes_prepare_feedback( - bp, e->black_holes_properties, e->physical_constants, e->cosmology, - e->cooling_func, e->entropy_floor, e->time, with_cosmology, dt); + black_holes_prepare_feedback(bp, e->black_holes_properties, + e->physical_constants, e->cosmology, + e->cooling_func, e->entropy_floor, e->time, + with_cosmology, dt, e->ti_current); } } } @@ -1224,6 +1255,7 @@ void runner_do_ghost(struct runner *r, struct cell *c, int timer) { tracers_after_init(p, xp, e->internal_units, e->physical_constants, with_cosmology, e->cosmology, e->hydro_properties, e->cooling_func, e->time); + rt_init_part(p); /* Off we go ! */ continue; diff --git a/src/runner_others.c b/src/runner_others.c index d0227c95ebcf5caa3a246a55aec2250ec2d4d1c6..7efb403213f15c7ad8a539cc30047d4b053e8912 100644 --- a/src/runner_others.c +++ b/src/runner_others.c @@ -283,8 +283,7 @@ void runner_do_star_formation(struct runner *r, struct cell *c, int timer) { /* Logs all the fields request by the user */ // TODO select only the requested fields logger_log_part(e->logger, p, xp, e, /* log_all */ 1, - logger_pack_flags_and_data(logger_flag_change_type, - swift_type_stars)); + logger_flag_change_type, swift_type_stars); #endif /* Convert the gas particle to a star particle */ @@ -348,9 +347,8 @@ void runner_do_star_formation(struct runner *r, struct cell *c, int timer) { sp->logger_data = xp->logger_data; /* Write the s-particle */ - logger_log_spart(e->logger, sp, e, - /* log_all */ 1, - /* special flags */ 0); + logger_log_spart(e->logger, sp, e, /* log_all */ 1, + logger_flag_create, /* data */ 0); #endif } else if (swift_star_formation_model_creates_stars) { @@ -743,8 +741,8 @@ void runner_do_logger(struct runner *r, struct cell *c, int timer) { if (logger_should_write(&xp->logger_data, e->logger)) { /* Write particle */ /* Currently writing everything, should adapt it through time */ - logger_log_part(e->logger, p, xp, e, /* log_all */ 0, - /* special flags */ 0); + logger_log_part(e->logger, p, xp, e, /* log_all_fields= */ 0, + /* flag= */ 0, /* flag_data= */ 0); } else /* Update counter */ xp->logger_data.steps_since_last_output += 1; @@ -766,8 +764,8 @@ void runner_do_logger(struct runner *r, struct cell *c, int timer) { if (logger_should_write(&gp->logger_data, e->logger)) { /* Write particle */ /* Currently writing everything, should adapt it through time */ - logger_log_gpart(e->logger, gp, e, /* log_all */ 0, - /* Special flags */ 0); + logger_log_gpart(e->logger, gp, e, /* log_all_fields= */ 0, + /* flag= */ 0, /* flag_data= */ 0); } else /* Update counter */ @@ -787,8 +785,8 @@ void runner_do_logger(struct runner *r, struct cell *c, int timer) { if (logger_should_write(&sp->logger_data, e->logger)) { /* Write particle */ /* Currently writing everything, should adapt it through time */ - logger_log_spart(e->logger, sp, e, /* Log_all */ 0, - /* Special flags */ 0); + logger_log_spart(e->logger, sp, e, /* Log_all_fields= */ 0, + /* flag= */ 0, /* flag_data= */ 0); } else /* Update counter */ sp->logger_data.steps_since_last_output += 1; diff --git a/src/scheduler.c b/src/scheduler.c index 54704c4b5c086dff4069a8f77c2894b23e4ec646..2dac28da747822a2e2974d60a8331cfa36a10acf 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -166,6 +166,19 @@ int scheduler_get_number_relation(const struct scheduler *s, /* Conservative number of dependencies per task type */ #define MAX_NUMBER_DEP 128 +/** + * @brief Describe the level at which the task are done. + * WARNING: the order is supposed to be sorted from the root + * to the leaf. + */ +enum task_dependency_level { + task_dependency_level_top = 0, + task_dependency_level_super, + task_dependency_level_super_hydro, + task_dependency_level_super_grav, + task_dependency_level_none, +}; + /** * @brief Informations about all the task dependencies of * a single task. @@ -181,6 +194,15 @@ struct task_dependency { /* Is the task implicit */ int implicit_in; + /* Is the taks_in at the top level? */ + int task_in_is_top; + + /* Is the taks_in at the grav.super level? */ + int task_in_is_grav_super; + + /* Is the taks_in at the hydro.super level? */ + int task_in_is_hydro_super; + /* Dependent task */ /* ID of the dependent task */ int type_out[MAX_NUMBER_DEP]; @@ -191,6 +213,15 @@ struct task_dependency { /* Is the dependent task implicit */ int implicit_out[MAX_NUMBER_DEP]; + /* Is the taks_out at the top level? */ + int task_out_is_top[MAX_NUMBER_DEP]; + + /* Is the taks_out at the grav.super level? */ + int task_out_is_grav_super[MAX_NUMBER_DEP]; + + /* Is the taks_out at the hydro.super level? */ + int task_out_is_hydro_super[MAX_NUMBER_DEP]; + /* Statistics */ /* number of link between the two task type */ int number_link[MAX_NUMBER_DEP]; @@ -208,7 +239,7 @@ struct task_dependency { */ void task_dependency_define(MPI_Datatype *tstype) { /* Define the variables */ - const int count = 8; + const int count = 14; int blocklens[count]; MPI_Datatype types[count]; MPI_Aint disps[count]; @@ -225,20 +256,32 @@ void task_dependency_define(MPI_Datatype *tstype) { blocklens[1] = 1; disps[2] = offsetof(struct task_dependency, implicit_in); blocklens[2] = 1; + disps[3] = offsetof(struct task_dependency, task_in_is_top); + blocklens[3] = 1; + disps[4] = offsetof(struct task_dependency, task_in_is_hydro_super); + blocklens[4] = 1; + disps[5] = offsetof(struct task_dependency, task_in_is_grav_super); + blocklens[5] = 1; /* Task out */ - disps[3] = offsetof(struct task_dependency, type_out); - blocklens[3] = MAX_NUMBER_DEP; - disps[4] = offsetof(struct task_dependency, subtype_out); - blocklens[4] = MAX_NUMBER_DEP; - disps[5] = offsetof(struct task_dependency, implicit_out); - blocklens[5] = MAX_NUMBER_DEP; - - /* statistics */ - disps[6] = offsetof(struct task_dependency, number_link); + disps[6] = offsetof(struct task_dependency, type_out); blocklens[6] = MAX_NUMBER_DEP; - disps[7] = offsetof(struct task_dependency, number_rank); + disps[7] = offsetof(struct task_dependency, subtype_out); blocklens[7] = MAX_NUMBER_DEP; + disps[8] = offsetof(struct task_dependency, implicit_out); + blocklens[8] = MAX_NUMBER_DEP; + disps[9] = offsetof(struct task_dependency, task_out_is_top); + blocklens[9] = MAX_NUMBER_DEP; + disps[10] = offsetof(struct task_dependency, task_out_is_hydro_super); + blocklens[10] = MAX_NUMBER_DEP; + disps[11] = offsetof(struct task_dependency, task_out_is_grav_super); + blocklens[11] = MAX_NUMBER_DEP; + + /* statistics */ + disps[12] = offsetof(struct task_dependency, number_link); + blocklens[12] = MAX_NUMBER_DEP; + disps[13] = offsetof(struct task_dependency, number_rank); + blocklens[13] = MAX_NUMBER_DEP; /* define it for MPI */ MPI_Type_create_struct(count, blocklens, disps, types, tstype); @@ -328,10 +371,24 @@ void task_dependency_sum(void *in_p, void *out_p, int *len, error("Tasks do not correspond"); } #endif - /* sum the contributions */ out[i].number_link[k] += in[i].number_link[j]; out[i].number_rank[k] += in[i].number_rank[j]; + + /* Get the task in level */ + out[i].task_in_is_top = min(out[i].task_in_is_top, in[i].task_in_is_top); + out[i].task_in_is_hydro_super = + min(out[i].task_in_is_hydro_super, in[i].task_in_is_hydro_super); + out[i].task_in_is_grav_super = + min(out[i].task_in_is_grav_super, in[i].task_in_is_grav_super); + + /* Get the task out level */ + out[i].task_out_is_top[j] = + min(out[i].task_out_is_top[j], in[i].task_out_is_top[j]); + out[i].task_out_is_hydro_super[j] = min(out[i].task_out_is_hydro_super[j], + in[i].task_out_is_hydro_super[j]); + out[i].task_out_is_grav_super[j] = min(out[i].task_out_is_grav_super[j], + in[i].task_out_is_grav_super[j]); } } @@ -341,7 +398,7 @@ void task_dependency_sum(void *in_p, void *out_p, int *len, #endif // WITH_MPI /** - * @brief Write a dot file with the task dependencies. + * @brief Write a csv file with the task dependencies. * * Run plot_task_dependencies.sh for an example of how to use it * to generate the figure. @@ -367,9 +424,19 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { /* Reset counter */ for (int i = 0; i < nber_tasks; i++) { + /* Assume that the tasks are at all levels and correct later. */ + task_dep[i].task_in_is_top = 1; + task_dep[i].task_in_is_grav_super = 1; + task_dep[i].task_in_is_hydro_super = 1; + for (int j = 0; j < MAX_NUMBER_DEP; j++) { /* Use number_link as indicator of the existance of a relation */ task_dep[i].number_link[j] = -1; + + /* Assume that the tasks are at all levels and correct later. */ + task_dep[i].task_out_is_top[j] = 1; + task_dep[i].task_out_is_grav_super[j] = 1; + task_dep[i].task_out_is_hydro_super[j] = 1; } } @@ -387,10 +454,48 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { cur->subtype_in = ta->subtype; cur->implicit_in = ta->implicit; + /* Set the task level. */ + const struct cell *ci = ta->ci; + const struct cell *cj = ta->cj; + const int is_ci_top = ci == NULL || (ci != NULL && ci == ci->top); + const int is_cj_top = cj == NULL || (cj != NULL && cj == cj->top); + const int is_hydro_super = + (cj == NULL || (cj != NULL && cj == cj->hydro.super)) && + (ci == NULL || (ci != NULL && ci == ci->hydro.super)); + const int is_grav_super = + (cj == NULL || (cj != NULL && cj == cj->grav.super)) && + (ci == NULL || (ci != NULL && ci == ci->grav.super)); + + /* Are we dealing with a task at the top level? */ + if (!(is_ci_top && is_cj_top)) { + cur->task_in_is_top = 0; + } + /* At the hydro level? */ + if (!is_hydro_super) { + cur->task_in_is_hydro_super = 0; + } + /* At the gravity level? */ + if (!is_grav_super) { + cur->task_in_is_grav_super = 0; + } + /* and their dependencies */ for (int j = 0; j < ta->nr_unlock_tasks; j++) { const struct task *tb = ta->unlock_tasks[j]; + const struct cell *ci_b = tb->ci; + const struct cell *cj_b = tb->cj; + const int is_ci_b_top = + ci_b == NULL || (ci_b != NULL && ci_b == ci_b->top); + const int is_cj_b_top = + cj_b == NULL || (cj_b != NULL && cj_b == cj_b->top); + const int is_b_hydro_super = + (cj_b == NULL || (cj_b != NULL && cj_b == cj_b->hydro.super)) && + (ci_b == NULL || (ci_b != NULL && ci_b == ci_b->hydro.super)); + const int is_b_grav_super = + (cj_b == NULL || (cj_b != NULL && cj_b == cj_b->grav.super)) && + (ci_b == NULL || (ci_b != NULL && ci_b == ci_b->grav.super)); + int k = 0; while (k < MAX_NUMBER_DEP) { /* not written yet */ @@ -405,12 +510,38 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { cur->number_link[k] = count; cur->number_rank[k] = 1; + /* Are we dealing with a task at the top level? */ + if (!(is_ci_b_top && is_cj_b_top)) { + cur->task_out_is_top[k] = 0; + } + /* At the hydro level? */ + if (!is_b_hydro_super) { + cur->task_out_is_hydro_super[k] = 0; + } + /* At the gravity level? */ + if (!is_b_grav_super) { + cur->task_out_is_grav_super[k] = 0; + } + break; } /* already written */ if (cur->type_out[k] == tb->type && cur->subtype_out[k] == tb->subtype) { + + /* Are we dealing with a task at the top level? */ + if (!(is_ci_b_top && is_cj_b_top)) { + cur->task_out_is_top[k] = 0; + } + /* At the hydro level? */ + if (!is_b_hydro_super) { + cur->task_out_is_hydro_super[k] = 0; + } + /* At the gravity level? */ + if (!is_b_grav_super) { + cur->task_out_is_grav_super[k] = 0; + } break; } @@ -470,7 +601,9 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { fprintf( f, "task_in,task_out,implicit_in,implicit_out,mpi_in,mpi_out,cluster_in," - "cluster_out,number_link,number_rank\n"); + "cluster_out,number_link,number_rank,task_in_is_top,task_in_is_hydro_" + "super,task_in_is_grav_super,task_out_is_top,task_out_is_hydro_super," + "task_out_is_grav_super\n"); for (int i = 0; i < nber_tasks; i++) { for (int j = 0; j < MAX_NUMBER_DEP; j++) { @@ -491,6 +624,16 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { const int count = task_dep[i].number_link[j]; const int number_rank = task_dep[i].number_rank[j]; + const int task_in_is_top = task_dep[i].task_in_is_top; + const int task_in_is_grav_super = task_dep[i].task_in_is_grav_super; + const int task_in_is_hydro_super = task_dep[i].task_in_is_hydro_super; + + const int task_out_is_top = task_dep[i].task_out_is_top[j]; + const int task_out_is_grav_super = + task_dep[i].task_out_is_grav_super[j]; + const int task_out_is_hydro_super = + task_dep[i].task_out_is_hydro_super[j]; + /* text to write */ char ta_name[200]; char tb_name[200]; @@ -512,9 +655,11 @@ void scheduler_write_dependencies(struct scheduler *s, int verbose) { task_get_group_name(ta_type, ta_subtype, ta_cluster); task_get_group_name(tb_type, tb_subtype, tb_cluster); - fprintf(f, "%s,%s,%d,%d,%d,%d,%s,%s,%d,%d\n", ta_name, tb_name, - ta_implicit, tb_implicit, ta_mpi, tb_mpi, ta_cluster, - tb_cluster, count, number_rank); + fprintf(f, "%s,%s,%d,%d,%d,%d,%s,%s,%d,%d,%d,%d,%d,%d,%d,%d\n", ta_name, + tb_name, ta_implicit, tb_implicit, ta_mpi, tb_mpi, ta_cluster, + tb_cluster, count, number_rank, task_in_is_top, + task_in_is_hydro_super, task_in_is_grav_super, task_out_is_top, + task_out_is_hydro_super, task_out_is_grav_super); } } /* Close the file */ diff --git a/src/space.c b/src/space.c index 0d1c6ed164669e83ee3dc344932f356cf6af2089..9c8afa141aed1d638c94da3fea4ac5d390074cfd 100644 --- a/src/space.c +++ b/src/space.c @@ -50,6 +50,7 @@ #include "minmax.h" #include "proxy.h" #include "restart.h" +#include "rt.h" #include "sort_part.h" #include "space_unique_id.h" #include "star_formation.h" @@ -743,6 +744,67 @@ void space_synchronize_particle_positions(struct space *s) { clocks_getunit()); } +void space_convert_rt_quantities_mapper(void *restrict map_data, int scount, + void *restrict extra_data) { + + struct spart *restrict sparts = (struct spart *)map_data; + const struct engine *restrict e = (struct engine *)extra_data; + const int with_cosmology = (e->policy & engine_policy_cosmology); + + for (int k = 0; k < scount; k++) { + + struct spart *restrict sp = &sparts[k]; + + /* get star's age and time step for stellar emission rates */ + const integertime_t ti_begin = + get_integer_time_begin(e->ti_current - 1, sp->time_bin); + const integertime_t ti_step = get_integer_timestep(sp->time_bin); + + /* Get particle time-step */ + double dt_star; + if (with_cosmology) { + dt_star = + cosmology_get_delta_time(e->cosmology, ti_begin, ti_begin + ti_step); + } else { + dt_star = get_timestep(sp->time_bin, e->time_base); + } + + /* Calculate age of the star at current time */ + double star_age_end_of_step; + if (with_cosmology) { + star_age_end_of_step = cosmology_get_delta_time_from_scale_factors( + e->cosmology, (double)sp->birth_scale_factor, e->cosmology->a); + } else { + star_age_end_of_step = e->time - (double)sp->birth_time; + } + + rt_compute_stellar_emission_rate(sp, e->time, star_age_end_of_step, + dt_star); + } +} + +/** + * @brief Calls the first radiative transfer additional data + * initialisation function on all star particles in the space. + * This function requires that the time bins for star particles + * have been set already and is called after the 0-th time step. + * + * @param s The #space. + * @param verbose Are we talkative? + */ +void space_convert_rt_quantities(struct space *s, int verbose) { + + const ticks tic = getticks(); + + if (s->nr_sparts > 0) + threadpool_map(&s->e->threadpool, space_convert_rt_quantities_mapper, + s->sparts, s->nr_sparts, sizeof(struct spart), + threadpool_auto_chunk_size, /*extra_data=*/s->e); + if (verbose) + message("took %.3f %s.", clocks_from_ticks(getticks() - tic), + clocks_getunit()); +} + void space_convert_quantities_mapper(void *restrict map_data, int count, void *restrict extra_data) { struct space *s = (struct space *)extra_data; diff --git a/src/space.h b/src/space.h index 5af6783dfe2c99d2f2da01906ec9c646e3f9a380..17949392f46f63ff8d980a5fcc8da1236dad1c45 100644 --- a/src/space.h +++ b/src/space.h @@ -390,6 +390,7 @@ void space_init_gparts(struct space *s, int verbose); void space_init_sparts(struct space *s, int verbose); void space_init_bparts(struct space *s, int verbose); void space_init_sinks(struct space *s, int verbose); +void space_convert_rt_quantities(struct space *s, int verbose); void space_convert_quantities(struct space *s, int verbose); void space_link_cleanup(struct space *s); void space_check_drift_point(struct space *s, integertime_t ti_drift, diff --git a/src/space_init.c b/src/space_init.c index b0e710ca7308bd04db0585aad84c214b1c50d9d9..4f2b05596b7290323a9df316f02869f8691a95e7 100644 --- a/src/space_init.c +++ b/src/space_init.c @@ -55,6 +55,7 @@ void space_init_parts_mapper(void *restrict map_data, int count, chemistry_init_part(&parts[k], e->chemistry); pressure_floor_init_part(&parts[k], &xparts[k]); rt_init_part(&parts[k]); + rt_reset_part(&parts[k]); star_formation_init_part(&parts[k], e->star_formation); tracers_after_init(&parts[k], &xparts[k], e->internal_units, e->physical_constants, with_cosmology, e->cosmology, diff --git a/src/star_formation.c b/src/star_formation.c index 60cff1e2e68feaf7e71705b5079294ec478fad42..c0e8dfc2049c62ff827c7caa945bb08ee46e92e8 100644 --- a/src/star_formation.c +++ b/src/star_formation.c @@ -35,16 +35,21 @@ * @param phys_const Physical constants in internal units * @param us the current internal system of units * @param hydro_props The propoerties of the hydro scheme. + * @param cosmo The cosmology model. + * @param entropy_floor The properties of the entropy floor used in this + * simulation. * @param starform the properties of the star formation law */ void starformation_init(struct swift_params* parameter_file, const struct phys_const* phys_const, const struct unit_system* us, const struct hydro_props* hydro_props, + const struct cosmology* cosmo, + const struct entropy_floor_properties* entropy_floor, struct star_formation* starform) { - starformation_init_backend(parameter_file, phys_const, us, hydro_props, - starform); + starformation_init_backend(parameter_file, phys_const, us, hydro_props, cosmo, + entropy_floor, starform); } /** diff --git a/src/star_formation.h b/src/star_formation.h index 3ac28ad02b557aa06ba03e9c43da0d6f511a56f7..cd21c8aa43c5c6a0a6747c3bd1e7c3544e3cc4e9 100644 --- a/src/star_formation.h +++ b/src/star_formation.h @@ -52,6 +52,8 @@ void starformation_init(struct swift_params* parameter_file, const struct phys_const* phys_const, const struct unit_system* us, const struct hydro_props* hydro_props, + const struct cosmology* cosmo, + const struct entropy_floor_properties* entropy_floor, struct star_formation* starform); void starformation_print(const struct star_formation* starform); diff --git a/src/star_formation/EAGLE/star_formation.h b/src/star_formation/EAGLE/star_formation.h index 57f97089289d089404f13effd876ea616ed4ad8f..318c2610e12c8d4c6561b8f81de22aa5e27f4e9a 100644 --- a/src/star_formation/EAGLE/star_formation.h +++ b/src/star_formation/EAGLE/star_formation.h @@ -51,11 +51,23 @@ enum star_formation_law { eagle_star_formation_pressure_law /*<! Pressure law */ }; +/** + * @brief Choice of star formation threshold + */ +enum star_formation_threshold { + eagle_star_formation_threshold_Z_dep, /*<! SF threshold based on Schaye+2004 + Z-dependence */ + eagle_star_formation_threshold_subgrid /*<! SF threshold based on subgrid + properties */ +}; + /** * @brief Properties of the EAGLE star formation model. */ struct star_formation { + /* SF law ------------------------------------------------------------*/ + /*! Which SF law are we using? */ enum star_formation_law SF_law; @@ -112,141 +124,177 @@ struct star_formation { } pressure_law; - /* SF threshold properties -------------------------------------------- */ - - /*! Critical overdensity */ - double min_over_den; + /* Density for direct conversion to star -------------------------------- */ - /*! Density threshold to form stars (internal units) */ - double density_threshold; + /*! Max physical density (H atoms per cm^3)*/ + double gas_density_direct_HpCM3; - /*! Density threshold to form stars in user units */ - double density_threshold_HpCM3; + /*! Max physical density (internal units) */ + double gas_density_direct; - /*! Maximum density threshold to form stars (internal units) */ - double density_threshold_max; + /* SF threshold --------------------------------------------------------- */ - /*! Maximum density threshold to form stars (H atoms per cm^3) */ - double density_threshold_max_HpCM3; + enum star_formation_threshold SF_threshold; - /*! Reference metallicity for metal-dependant threshold */ - double Z0; + /*! Critical overdensity above which SF is allowed */ + double min_over_den; - /*! Inverse of reference metallicity */ - double Z0_inv; + struct { - /*! critical density Metallicity power law (internal units) */ - double n_Z0; + /*! Density threshold to form stars (internal units) */ + double density_threshold; - /* Internal EoS properties ----------------------------------------------- */ + /*! Density threshold to form stars in user units */ + double density_threshold_HpCM3; - /*! Polytropic index */ - double EOS_polytropic_index; + /*! Maximum density threshold to form stars (internal units) */ + double density_threshold_max; - /*! EOS density norm (H atoms per cm^3) */ - double EOS_density_norm_HpCM3; + /*! Maximum density threshold to form stars (H atoms per cm^3) */ + double density_threshold_max_HpCM3; - /*! EOS Temperature norm (Kelvin) */ - double EOS_temperature_norm_K; + /*! Reference metallicity for metal-dependant threshold */ + double Z0; - /*! EOS pressure norm, eq. 13 of Schaye & Dalla Vecchia 2008 (internal units) - */ - double EOS_pressure_c; + /*! Inverse of reference metallicity */ + double Z0_inv; - /*! EOS Temperarure norm, eq. 13 of Schaye & Dalla Vecchia 2008 (internal - * units) */ - double EOS_temperature_c; + /*! critical density Metallicity power law (internal units) */ + double n_Z0; - /*! EOS density norm, eq. 13 of Schaye & Dalla Vecchia 2008 (internal units) - */ - double EOS_density_c; + /*! Dalla Vecchia & Schaye entropy differnce criterion */ + double entropy_margin_threshold_dex; - /*! Inverse of EOS density norm (internal units) */ - double EOS_density_c_inv; + /*! 10^Tdex of Dalla Vecchia & Schaye entropy difference criterion */ + double ten_to_entropy_margin_threshold_dex; - /* Maximal offset from entropy floor allowed for SF --------------------- */ + } Z_dep_thresh; - /*! Dalla Vecchia & Schaye entropy differnce criterion */ - double entropy_margin_threshold_dex; + struct { - /*! 10^Tdex of Dalla Vecchia & Schaye entropy difference criterion */ - double ten_to_entropy_margin_threshold_dex; + /*! (Subgrid) temperature threshold for SF to use on its own */ + double T_threshold1; - /* Density for direct conversion to star -------------------------------- */ + /*! (Subgrid) temperature threshold for SF to use combined with the density + * threshold */ + double T_threshold2; - /*! Max physical density (H atoms per cm^3)*/ - double gas_density_direct_HpCM3; + /*! (Subgrid) Hydrogen number density threshold for SF */ + double nH_threshold; - /*! Max physical density (internal units) */ - double gas_density_direct; + } subgrid_thresh; }; /** - * @brief Computes the density threshold for star-formation fo a given total - * metallicity. - * - * Follows Schaye (2004) eq. 19 and 24 (see also Schaye et al. 2015, eq. 2). + * @brief Calculate if the satisfies the conditions for star formation. * - * @param Z The metallicity (metal mass fraction). - * @param starform The properties of the star formation model. - * @param phys_const The physical constants. - * @return The physical density threshold for star formation in internal units. + * @param starform the star formation law properties to use. + * @param p the gas particles. + * @param xp the additional properties of the gas particles. + * @param phys_const the physical constants in internal units. + * @param cosmo the cosmological parameters and properties. + * @param hydro_props The properties of the hydro scheme. + * @param us The internal system of units. + * @param cooling The cooling data struct. + * @param entropy_floor_props The entropy floor assumed in this run. */ -INLINE static double star_formation_threshold( - const double Z, const struct star_formation* starform, - const struct phys_const* phys_const) { +INLINE static int star_formation_is_star_forming_Z_dep( + const struct part* p, const struct xpart* xp, + const struct star_formation* starform, const struct phys_const* phys_const, + const struct cosmology* cosmo, const struct hydro_props* hydro_props, + const struct unit_system* us, const struct cooling_function_data* cooling, + const struct entropy_floor_properties* entropy_floor_props) { + + /* Physical density of the particle */ + const double physical_density = hydro_get_physical_density(p, cosmo); + + /* Get the Hydrogen number density (assuming primordial H abundance) */ + const double n_H = physical_density * hydro_props->hydrogen_mass_fraction; + + /* Get the density threshold for star formation */ + const double Z = + chemistry_get_total_metal_mass_fraction_for_star_formation(p); double density_threshold; /* Schaye (2004), eq. 19 and 24 */ if (Z > 0.) { - density_threshold = starform->density_threshold * - powf(Z * starform->Z0_inv, starform->n_Z0); - density_threshold = min(density_threshold, starform->density_threshold_max); + density_threshold = + starform->Z_dep_thresh.density_threshold * + powf(Z * starform->Z_dep_thresh.Z0_inv, starform->Z_dep_thresh.n_Z0); + density_threshold = + min(density_threshold, starform->Z_dep_thresh.density_threshold_max); } else { - density_threshold = starform->density_threshold_max; + density_threshold = starform->Z_dep_thresh.density_threshold_max; } /* Convert to mass density */ - return density_threshold * phys_const->const_proton_mass; -} + density_threshold *= phys_const->const_proton_mass; -/** - * @brief Compute the pressure on the polytropic equation of state for a given - * Hydrogen number density. - * - * Schaye & Dalla Vecchia 2008, eq. 13. - * - * @param n_H The Hydrogen number density in internal units. - * @param starform The properties of the star formation model. - * @return The pressure on the equation of state in internal units. - */ -INLINE static double EOS_pressure(const double n_H, - const struct star_formation* starform) { + /* Check if it exceeded the minimum density */ + if (n_H < density_threshold) return 0; - return starform->EOS_pressure_c * - pow(n_H * starform->EOS_density_c_inv, starform->EOS_polytropic_index); + /* Calculate the entropy of the particle */ + const double entropy = hydro_get_physical_entropy(p, xp, cosmo); + + /* Calculate the entropy that will be used to calculate + * the off-set from the EoS */ + const double entropy_eos = entropy_floor(p, cosmo, entropy_floor_props); + + /* Check the Schaye & Dalla Vecchia 2012 EOS-based temperature criterion */ + return (entropy < + entropy_eos * + starform->Z_dep_thresh.ten_to_entropy_margin_threshold_dex); } /** - * @brief Compute the entropy of the polytropic equation of state for a given - * Hydrogen number density. + * @brief Calculate if the satisfies the conditions for star formation. * - * @param n_H The Hydrogen number density in internal units. - * @param starform The properties of the star formation model. - * @param rho The physical density - * @return The pressure on the equation of state in internal units. + * @param starform the star formation law properties to use. + * @param p the gas particles. + * @param xp the additional properties of the gas particles. + * @param phys_const the physical constants in internal units. + * @param cosmo the cosmological parameters and properties. + * @param hydro_props The properties of the hydro scheme. + * @param us The internal system of units. + * @param cooling The cooling data struct. + * @param entropy_floor_props The entropy floor assumed in this run. */ -INLINE static double EOS_entropy(const double n_H, - const struct star_formation* starform, - const double rho) { - - return gas_entropy_from_pressure(rho, EOS_pressure(n_H, starform)); +INLINE static int star_formation_is_star_forming_subgrid( + const struct part* p, const struct xpart* xp, + const struct star_formation* starform, const struct phys_const* phys_const, + const struct cosmology* cosmo, const struct hydro_props* hydro_props, + const struct unit_system* us, const struct cooling_function_data* cooling, + const struct entropy_floor_properties* entropy_floor_props) { + + const double number_density_to_cgs = + units_cgs_conversion_factor(us, UNIT_CONV_NUMBER_DENSITY); + + /* Get the Hydrogen mass fraction */ + const double XH = chemistry_get_metal_mass_fraction_for_star_formation( + p)[chemistry_element_H]; + + /* Get the subgrid properties + * Note these are both in physical frame already */ + const double subgrid_T_cgs = cooling_get_subgrid_temperature(p, xp); + const double subgrid_rho = cooling_get_subgrid_density(p, xp); + const double subgrid_n_H = subgrid_rho * XH / phys_const->const_proton_mass; + const double subgrid_n_H_cgs = subgrid_n_H * number_density_to_cgs; + + /* Now, determine whether we are very cold or (cold and dense) enough + * + * This would typically be (T < 10^3 OR (T < 10^4.5 AND n_H > 10)) + * with T and n_H subgrid properties. + * + * Recall that particles above the EoS have T_sub = T and rho_sub = rho. + */ + return ((subgrid_T_cgs < starform->subgrid_thresh.T_threshold1) || + (subgrid_T_cgs < starform->subgrid_thresh.T_threshold2 && + subgrid_n_H_cgs > starform->subgrid_thresh.nH_threshold)); } /** - * @brief Calculate if the gas has the potential of becoming - * a star. + * @brief Calculate if the satisfies the conditions for star formation. * * @param starform the star formation law properties to use. * @param p the gas particles. @@ -259,58 +307,44 @@ INLINE static double EOS_entropy(const double n_H, * @param entropy_floor_props The entropy floor assumed in this run. */ INLINE static int star_formation_is_star_forming( - const struct part* restrict p, const struct xpart* restrict xp, + const struct part* p, const struct xpart* xp, const struct star_formation* starform, const struct phys_const* phys_const, - const struct cosmology* cosmo, - const struct hydro_props* restrict hydro_props, - const struct unit_system* restrict us, - const struct cooling_function_data* restrict cooling, - const struct entropy_floor_properties* restrict entropy_floor_props) { + const struct cosmology* cosmo, const struct hydro_props* hydro_props, + const struct unit_system* us, const struct cooling_function_data* cooling, + const struct entropy_floor_properties* entropy_floor_props) { - /* Minimal density (converted from mean baryonic density) for star formation - */ + /* Minimal density (converted from mean baryonic density) + * for star formation */ const double rho_mean_b_times_min_over_den = cosmo->mean_density_Omega_b * starform->min_over_den; /* Physical density of the particle */ const double physical_density = hydro_get_physical_density(p, cosmo); - /* Deside whether we should form stars or not, - * first we deterime if we have the correct over density - * if that is true we calculate if either the maximum density - * threshold is reached or if the metallicity dependent - * threshold is reached, after this we calculate if the - * temperature is appropriate */ - if (physical_density < rho_mean_b_times_min_over_den) return 0; - - /* In this case there are actually multiple possibilities - * because we also need to check if the physical density exceeded - * the appropriate limit */ - - /* Get the Hydrogen number density (assuming primordial H abundance) */ - const double n_H = physical_density * hydro_props->hydrogen_mass_fraction; + /* Deside whether we should form stars or not */ - /* Get the density threshold for star formation */ - const double Z = - chemistry_get_total_metal_mass_fraction_for_star_formation(p); - const double density_threshold = - star_formation_threshold(Z, starform, phys_const); + /* First, deterime if we have the correct over density */ + if (physical_density < rho_mean_b_times_min_over_den) return 0; - /* Check if it exceeded the minimum density */ - if (n_H < density_threshold) return 0; + /* Determine which star formation model to use */ + switch (starform->SF_threshold) { - /* Calculate the entropy of the particle */ - const double entropy = hydro_get_physical_entropy(p, xp, cosmo); + case eagle_star_formation_threshold_Z_dep: + return star_formation_is_star_forming_Z_dep(p, xp, starform, phys_const, + cosmo, hydro_props, us, + cooling, entropy_floor_props); + break; - /* Calculate the entropy that will be used to calculate - * the off-set, this is the maximum between the entropy - * floor and the star formation polytropic EOS. */ - const double entropy_eos = max(entropy_floor(p, cosmo, entropy_floor_props), - EOS_entropy(n_H, starform, physical_density)); + case eagle_star_formation_threshold_subgrid: + return star_formation_is_star_forming_subgrid( + p, xp, starform, phys_const, cosmo, hydro_props, us, cooling, + entropy_floor_props); + break; - /* Check the Schaye & Dalla Vecchia 2012 EOS-based temperature criterion */ - return (entropy < - entropy_eos * starform->ten_to_entropy_margin_threshold_dex); + default: + error("Invalid star formation threshold model!!!"); + return 0; + } } /** @@ -370,15 +404,12 @@ INLINE static void star_formation_compute_SFR_pressure_law( /* Hydrogen number density of this particle (assuming primordial H abundance) */ const double physical_density = hydro_get_physical_density(p, cosmo); - const double n_H = physical_density * hydro_props->hydrogen_mass_fraction; /* Get the pressure used for the star formation, this is - * the maximum of the star formation EOS pressure, - * the physical pressure of the particle and the + * the maximum the physical pressure of the particle and the * floor pressure. The floor pressure is used implicitly * when getting the physical pressure. */ - const double pressure = - max(EOS_pressure(n_H, starform), hydro_get_physical_pressure(p, cosmo)); + const double pressure = hydro_get_physical_pressure(p, cosmo); /* Calculate the specific star formation rate */ double SFRpergasmass; @@ -411,7 +442,7 @@ INLINE static void star_formation_compute_SFR_pressure_law( * @param dt_star The time-step of this particle. */ INLINE static void star_formation_compute_SFR( - const struct part* restrict p, struct xpart* restrict xp, + const struct part* p, struct xpart* xp, const struct star_formation* starform, const struct phys_const* phys_const, const struct hydro_props* hydro_props, const struct cosmology* cosmo, const double dt_star) { @@ -542,10 +573,8 @@ INLINE static void star_formation_copy_properties( const struct part* p, const struct xpart* xp, struct spart* sp, const struct engine* e, const struct star_formation* starform, const struct cosmology* cosmo, const int with_cosmology, - const struct phys_const* phys_const, - const struct hydro_props* restrict hydro_props, - const struct unit_system* restrict us, - const struct cooling_function_data* restrict cooling, + const struct phys_const* phys_const, const struct hydro_props* hydro_props, + const struct unit_system* us, const struct cooling_function_data* cooling, const int convert_part) { /* Store the current mass */ @@ -589,22 +618,21 @@ INLINE static void star_formation_copy_properties( * @param phys_const Physical constants in internal units * @param us The current internal system of units. * @param hydro_props The propertis of the hydro model. + * @param cosmo The current cosmological model. + * @param entropy_floor The properties of the entropy floor used in this + * simulation. * @param starform the star formation law properties to initialize */ INLINE static void starformation_init_backend( struct swift_params* parameter_file, const struct phys_const* phys_const, const struct unit_system* us, const struct hydro_props* hydro_props, + const struct cosmology* cosmo, + const struct entropy_floor_properties* entropy_floor, struct star_formation* starform) { /* Get the Gravitational constant */ const double G_newton = phys_const->const_newton_G; - /* Initial Hydrogen abundance (mass fraction) */ - const double X_H = hydro_props->hydrogen_mass_fraction; - - /* Mean molecular weight assuming neutral gas */ - const double mean_molecular_weight = hydro_props->mu_neutral; - /* Get the surface density unit Msun / pc^2 in internal units */ const double Msun_per_pc2 = phys_const->const_solar_mass / @@ -619,28 +647,6 @@ INLINE static void starformation_init_backend( const double number_density_from_cgs = 1. / units_cgs_conversion_factor(us, UNIT_CONV_NUMBER_DENSITY); - /* Load the equation of state for this model */ - starform->EOS_polytropic_index = parser_get_param_double( - parameter_file, "EAGLEStarFormation:EOS_gamma_effective"); - starform->EOS_temperature_norm_K = parser_get_param_double( - parameter_file, "EAGLEStarFormation:EOS_temperature_norm_K"); - starform->EOS_density_norm_HpCM3 = parser_get_param_double( - parameter_file, "EAGLEStarFormation:EOS_density_norm_H_p_cm3"); - starform->EOS_density_c = - starform->EOS_density_norm_HpCM3 * number_density_from_cgs; - starform->EOS_density_c_inv = 1. / starform->EOS_density_c; - - /* Calculate the EOS pressure normalization */ - starform->EOS_pressure_c = - starform->EOS_density_c * starform->EOS_temperature_norm_K * - phys_const->const_boltzmann_k / mean_molecular_weight / X_H; - - /* Normalisation of the temperature in the EOS calculatio */ - starform->EOS_temperature_c = - starform->EOS_pressure_c / phys_const->const_boltzmann_k; - starform->EOS_temperature_c *= - pow(starform->EOS_density_c, starform->EOS_polytropic_index); - /* Check if we are using the Schmidt law for the star formation rate, * defaults to pressure law if is not explicitely set to a Schmidt law */ char temp[32]; @@ -715,9 +721,15 @@ INLINE static void starformation_init_backend( starform->pressure_law.KS_high_den_thresh_HpCM3 * number_density_from_cgs; - /* Pressure at the high-density threshold */ + /* Pressure on the entropy floor at the high-density threshold + * + * Note that we use FLT_MAX as the comoving density to make sure + * the floor is applied no matter what redshift we are at. This will + * always be a density above the comoving density threashold for the floor + * to be used.*/ const double EOS_high_den_pressure = - EOS_pressure(starform->pressure_law.KS_high_den_thresh, starform); + entropy_floor_gas_pressure(starform->pressure_law.KS_high_den_thresh, + FLT_MAX, cosmo, entropy_floor); /* Calculate the KS high density normalization * We want the SF law to be continous so the normalisation of the second @@ -756,37 +768,70 @@ INLINE static void starformation_init_backend( starform->gas_density_direct = starform->gas_density_direct_HpCM3 * number_density_from_cgs; - starform->entropy_margin_threshold_dex = parser_get_opt_param_double( - parameter_file, "EAGLEStarFormation:EOS_entropy_margin_dex", FLT_MAX); + /* Check if we are using the Schmidt law for the star formation rate, + * defaults to pressure law if is not explicitely set to a Schmidt law */ + char temp_SF[32]; + parser_get_param_string(parameter_file, "EAGLEStarFormation:SF_threshold", + temp_SF); + + if (strcmp(temp_SF, "Zdep") == 0) { + + /* Z-dep (Schaye+2004) model */ + starform->SF_threshold = eagle_star_formation_threshold_Z_dep; + + starform->Z_dep_thresh.entropy_margin_threshold_dex = + parser_get_opt_param_double(parameter_file, + "EAGLEStarFormation:EOS_entropy_margin_dex", + FLT_MAX); - starform->ten_to_entropy_margin_threshold_dex = - exp10(starform->entropy_margin_threshold_dex); + starform->Z_dep_thresh.ten_to_entropy_margin_threshold_dex = + exp10(starform->Z_dep_thresh.entropy_margin_threshold_dex); - /* Read the normalization of the metallicity dependent critical - * density*/ - starform->density_threshold_HpCM3 = parser_get_param_double( - parameter_file, "EAGLEStarFormation:threshold_norm_H_p_cm3"); + /* Read the normalization of the metallicity dependent critical + * density*/ + starform->Z_dep_thresh.density_threshold_HpCM3 = parser_get_param_double( + parameter_file, "EAGLEStarFormation:threshold_norm_H_p_cm3"); - /* Convert to internal units */ - starform->density_threshold = - starform->density_threshold_HpCM3 * number_density_from_cgs; + /* Convert to internal units */ + starform->Z_dep_thresh.density_threshold = + starform->Z_dep_thresh.density_threshold_HpCM3 * + number_density_from_cgs; + + /* Read the scale metallicity Z0 */ + starform->Z_dep_thresh.Z0 = parser_get_param_double( + parameter_file, "EAGLEStarFormation:threshold_Z0"); + starform->Z_dep_thresh.Z0_inv = 1. / starform->Z_dep_thresh.Z0; + + /* Read the power law of the critical density scaling */ + starform->Z_dep_thresh.n_Z0 = parser_get_param_double( + parameter_file, "EAGLEStarFormation:threshold_slope"); + + /* Read the maximum allowed density for star formation */ + starform->Z_dep_thresh.density_threshold_max_HpCM3 = + parser_get_param_double( + parameter_file, "EAGLEStarFormation:threshold_max_density_H_p_cm3"); + + /* Convert to internal units */ + starform->Z_dep_thresh.density_threshold_max = + starform->Z_dep_thresh.density_threshold_max_HpCM3 * + number_density_from_cgs; - /* Read the scale metallicity Z0 */ - starform->Z0 = parser_get_param_double(parameter_file, - "EAGLEStarFormation:threshold_Z0"); - starform->Z0_inv = 1. / starform->Z0; + } else if (strcmp(temp_SF, "Subgrid") == 0) { - /* Read the power law of the critical density scaling */ - starform->n_Z0 = parser_get_param_double( - parameter_file, "EAGLEStarFormation:threshold_slope"); + /* Subgrid quantities based model */ + starform->SF_threshold = eagle_star_formation_threshold_subgrid; - /* Read the maximum allowed density for star formation */ - starform->density_threshold_max_HpCM3 = parser_get_param_double( - parameter_file, "EAGLEStarFormation:threshold_max_density_H_p_cm3"); + /* Read threshold properties */ + starform->subgrid_thresh.T_threshold1 = parser_get_param_double( + parameter_file, "EAGLEStarFormation:threshold_temperature1_K"); + starform->subgrid_thresh.T_threshold2 = parser_get_param_double( + parameter_file, "EAGLEStarFormation:threshold_temperature2_K"); + starform->subgrid_thresh.nH_threshold = parser_get_param_double( + parameter_file, "EAGLEStarFormation:threshold_number_density_H_p_cm3"); - /* Convert to internal units */ - starform->density_threshold_max = - starform->density_threshold_max_HpCM3 * number_density_from_cgs; + } else { + error("Invalid SF threshold model: '%s'", temp_SF); + } } /** @@ -797,7 +842,41 @@ INLINE static void starformation_init_backend( INLINE static void starformation_print_backend( const struct star_formation* starform) { - message("Star formation law is EAGLE"); + message("Star formation model is EAGLE"); + + switch (starform->SF_threshold) { + case eagle_star_formation_threshold_Z_dep: + + message("Density threshold follows Schaye (2004)"); + message( + "the normalization of the density threshold is given by" + " %e #/cm^3, with metallicity slope of %e, and metallicity " + "normalization" + " of %e, the maximum density threshold is given by %e #/cm^3", + starform->Z_dep_thresh.density_threshold_HpCM3, + starform->Z_dep_thresh.n_Z0, starform->Z_dep_thresh.Z0, + starform->Z_dep_thresh.density_threshold_max_HpCM3); + message( + "Temperature threshold is given by Dalla Vecchia and Schaye (2012)"); + message( + "The temperature threshold offset from the EOS is given by: %e dex", + starform->Z_dep_thresh.entropy_margin_threshold_dex); + + break; + case eagle_star_formation_threshold_subgrid: + + message("Density threshold uses subgrid quantities"); + message( + "Particles are star-forming if their properties obey (T_sub < %e K " + "OR (T_sub < %e K AND n_H,sub > %e cm^-3))", + starform->subgrid_thresh.T_threshold1, + starform->subgrid_thresh.T_threshold2, + starform->subgrid_thresh.nH_threshold); + + break; + default: + error("Invalid star formation threshold!!!"); + } switch (starform->SF_law) { case eagle_star_formation_schmidt_law: @@ -819,25 +898,9 @@ INLINE static void starformation_print_backend( starform->pressure_law.KS_high_den_power_law); break; default: - error("Invalid star formation model!!!"); + error("Invalid star formation law!!!"); } - message( - "The effective equation of state is given by: polytropic " - "index = %e , normalization density = %e #/cm^3 and normalization " - "temperature = %e K", - starform->EOS_polytropic_index, starform->EOS_density_norm_HpCM3, - starform->EOS_temperature_norm_K); - message("Density threshold follows Schaye (2004)"); - message( - "the normalization of the density threshold is given by" - " %e #/cm^3, with metallicity slope of %e, and metallicity normalization" - " of %e, the maximum density threshold is given by %e #/cm^3", - starform->density_threshold_HpCM3, starform->n_Z0, starform->Z0, - starform->density_threshold_max_HpCM3); - message("Temperature threshold is given by Dalla Vecchia and Schaye (2012)"); - message("The temperature threshold offset from the EOS is given by: %e dex", - starform->entropy_margin_threshold_dex); message("Running with a direct conversion density of: %e #/cm^3", starform->gas_density_direct_HpCM3); } @@ -854,8 +917,8 @@ INLINE static void starformation_print_backend( * @param cosmo The current cosmological model. */ __attribute__((always_inline)) INLINE static void star_formation_end_density( - struct part* restrict p, struct xpart* restrict xp, - const struct star_formation* cd, const struct cosmology* cosmo) {} + struct part* p, struct xpart* xp, const struct star_formation* cd, + const struct cosmology* cosmo) {} /** * @brief Sets all particle fields to sensible values when the #part has 0 ngbs. @@ -869,8 +932,7 @@ __attribute__((always_inline)) INLINE static void star_formation_end_density( * @param cosmo The current cosmological model. */ __attribute__((always_inline)) INLINE static void -star_formation_part_has_no_neighbours(struct part* restrict p, - struct xpart* restrict xp, +star_formation_part_has_no_neighbours(struct part* p, struct xpart* xp, const struct star_formation* cd, const struct cosmology* cosmo) {} @@ -885,7 +947,7 @@ star_formation_part_has_no_neighbours(struct part* restrict p, * @param p Pointer to the particle data. */ __attribute__((always_inline)) INLINE static void star_formation_init_part( - struct part* restrict p, const struct star_formation* data) {} + struct part* p, const struct star_formation* data) {} /** * @brief Sets the star_formation properties of the (x-)particles to a valid @@ -901,12 +963,11 @@ __attribute__((always_inline)) INLINE static void star_formation_init_part( * @param xp Pointer to the extended particle data. */ __attribute__((always_inline)) INLINE static void -star_formation_first_init_part(const struct phys_const* restrict phys_const, - const struct unit_system* restrict us, - const struct cosmology* restrict cosmo, +star_formation_first_init_part(const struct phys_const* phys_const, + const struct unit_system* us, + const struct cosmology* cosmo, const struct star_formation* data, - const struct part* restrict p, - struct xpart* restrict xp) {} + const struct part* p, struct xpart* xp) {} /** * @brief Split the star formation content of a particle into n pieces diff --git a/src/star_formation/GEAR/star_formation_io.h b/src/star_formation/GEAR/star_formation_io.h index 46ac7c6e3de567fab148b08a62d8d88e1e8113da..e5a7231d9678e0b5b8396e87d85789551719231b 100644 --- a/src/star_formation/GEAR/star_formation_io.h +++ b/src/star_formation/GEAR/star_formation_io.h @@ -104,12 +104,16 @@ star_formation_write_sparticles(const struct spart* sparts, * @param phys_const Physical constants in internal units * @param us The current internal system of units * @param hydro_props The #hydro_props. + * @param cosmo The current cosmological model. + * @param entropy_floor The properties of the entropy floor used in this + * simulation. * @param starform the star formation law properties to initialize - * */ INLINE static void starformation_init_backend( struct swift_params* parameter_file, const struct phys_const* phys_const, const struct unit_system* us, const struct hydro_props* hydro_props, + const struct cosmology* cosmo, + const struct entropy_floor_properties* entropy_floor, struct star_formation* starform) { /* Star formation efficiency */ diff --git a/src/star_formation/QLA/star_formation.h b/src/star_formation/QLA/star_formation.h index 5f8a36f2103256464d7a3f469da09fc43a4b5b2a..dd0244bf7731c7809a3003502e8b6e9c75f6b370 100644 --- a/src/star_formation/QLA/star_formation.h +++ b/src/star_formation/QLA/star_formation.h @@ -94,7 +94,7 @@ INLINE static int star_formation_is_star_forming( * @param dt_star The time-step of this particle. */ INLINE static void star_formation_compute_SFR( - const struct part* restrict p, struct xpart* restrict xp, + const struct part* p, struct xpart* xp, const struct star_formation* starform, const struct phys_const* phys_const, const struct hydro_props* hydro_props, const struct cosmology* cosmo, const double dt_star) { @@ -159,10 +159,8 @@ INLINE static void star_formation_copy_properties( const struct part* p, const struct xpart* xp, struct spart* sp, const struct engine* e, const struct star_formation* starform, const struct cosmology* cosmo, const int with_cosmology, - const struct phys_const* phys_const, - const struct hydro_props* restrict hydro_props, - const struct unit_system* restrict us, - const struct cooling_function_data* restrict cooling, + const struct phys_const* phys_const, const struct hydro_props* hydro_props, + const struct unit_system* us, const struct cooling_function_data* cooling, const int convert_part) { /* Store the current mass */ @@ -183,11 +181,16 @@ INLINE static void star_formation_copy_properties( * @param phys_const Physical constants in internal units * @param us The current internal system of units. * @param hydro_props The propertis of the hydro model. + * @param cosmo The current cosmological model. + * @param entropy_floor The properties of the entropy floor used in this + * simulation. * @param starform the star formation law properties to initialize */ INLINE static void starformation_init_backend( struct swift_params* parameter_file, const struct phys_const* phys_const, const struct unit_system* us, const struct hydro_props* hydro_props, + const struct cosmology* cosmo, + const struct entropy_floor_properties* entropy_floor, struct star_formation* starform) { /* Read the critical density contrast from the parameter file*/ @@ -219,8 +222,8 @@ INLINE static void starformation_print_backend( * @param cosmo The current cosmological model. */ __attribute__((always_inline)) INLINE static void star_formation_end_density( - struct part* restrict p, struct xpart* restrict xp, - const struct star_formation* cd, const struct cosmology* cosmo) {} + struct part* p, struct xpart* xp, const struct star_formation* cd, + const struct cosmology* cosmo) {} /** * @brief Sets all particle fields to sensible values when the #part has 0 ngbs. @@ -234,8 +237,7 @@ __attribute__((always_inline)) INLINE static void star_formation_end_density( * @param cosmo The current cosmological model. */ __attribute__((always_inline)) INLINE static void -star_formation_part_has_no_neighbours(struct part* restrict p, - struct xpart* restrict xp, +star_formation_part_has_no_neighbours(struct part* p, struct xpart* xp, const struct star_formation* cd, const struct cosmology* cosmo) {} @@ -250,7 +252,7 @@ star_formation_part_has_no_neighbours(struct part* restrict p, * @param p Pointer to the particle data. */ __attribute__((always_inline)) INLINE static void star_formation_init_part( - struct part* restrict p, const struct star_formation* data) {} + struct part* p, const struct star_formation* data) {} /** * @brief Sets the star_formation properties of the (x-)particles to a valid @@ -266,12 +268,11 @@ __attribute__((always_inline)) INLINE static void star_formation_init_part( * @param xp Pointer to the extended particle data. */ __attribute__((always_inline)) INLINE static void -star_formation_first_init_part(const struct phys_const* restrict phys_const, - const struct unit_system* restrict us, - const struct cosmology* restrict cosmo, +star_formation_first_init_part(const struct phys_const* phys_const, + const struct unit_system* us, + const struct cosmology* cosmo, const struct star_formation* data, - const struct part* restrict p, - struct xpart* restrict xp) { + const struct part* p, struct xpart* xp) { xp->sf_data.convert_to_star = 0; } diff --git a/src/star_formation/none/star_formation.h b/src/star_formation/none/star_formation.h index e88dfefe4c65c7258e90aa0dd812a49a45236b18..57544c837368cb0c4290f2dbdbaedebd369d971d 100644 --- a/src/star_formation/none/star_formation.h +++ b/src/star_formation/none/star_formation.h @@ -55,13 +55,11 @@ struct star_formation {}; * */ INLINE static int star_formation_is_star_forming( - const struct part* restrict p, const struct xpart* restrict xp, + const struct part* p, const struct xpart* xp, const struct star_formation* starform, const struct phys_const* phys_const, - const struct cosmology* cosmo, - const struct hydro_props* restrict hydro_props, - const struct unit_system* restrict us, - const struct cooling_function_data* restrict cooling, - const struct entropy_floor_properties* restrict entropy_floor) { + const struct cosmology* cosmo, const struct hydro_props* hydro_props, + const struct unit_system* us, const struct cooling_function_data* cooling, + const struct entropy_floor_properties* entropy_floor) { return 0; } @@ -81,7 +79,7 @@ INLINE static int star_formation_is_star_forming( * @param dt_star The time-step of this particle. */ INLINE static void star_formation_compute_SFR( - const struct part* restrict p, struct xpart* restrict xp, + const struct part* p, struct xpart* xp, const struct star_formation* starform, const struct phys_const* phys_const, const struct hydro_props* hydro_props, const struct cosmology* cosmo, const double dt_star) {} @@ -157,10 +155,8 @@ INLINE static void star_formation_copy_properties( const struct part* p, const struct xpart* xp, struct spart* sp, const struct engine* e, const struct star_formation* starform, const struct cosmology* cosmo, const int with_cosmology, - const struct phys_const* phys_const, - const struct hydro_props* restrict hydro_props, - const struct unit_system* restrict us, - const struct cooling_function_data* restrict cooling, + const struct phys_const* phys_const, const struct hydro_props* hydro_props, + const struct unit_system* us, const struct cooling_function_data* cooling, const int convert_part) {} /** @@ -169,12 +165,17 @@ INLINE static void star_formation_copy_properties( * @param parameter_file The parsed parameter file * @param phys_const Physical constants in internal units * @param us The current internal system of units + * @param hydro_props The propertis of the hydro model. + * @param cosmo The current cosmological model. + * @param entropy_floor The properties of the entropy floor used in this + * simulation. * @param starform the star formation law properties to initialize - * */ INLINE static void starformation_init_backend( struct swift_params* parameter_file, const struct phys_const* phys_const, const struct unit_system* us, const struct hydro_props* hydro_props, + const struct cosmology* cosmo, + const struct entropy_floor_properties* entropy_floor, const struct star_formation* starform) {} /** @@ -199,8 +200,8 @@ INLINE static void starformation_print_backend( * @param cosmo The current cosmological model. */ __attribute__((always_inline)) INLINE static void star_formation_end_density( - struct part* restrict p, struct xpart* restrict xp, - const struct star_formation* cd, const struct cosmology* cosmo) {} + struct part* p, struct xpart* xp, const struct star_formation* cd, + const struct cosmology* cosmo) {} /** * @brief Sets all particle fields to sensible values when the #part has 0 ngbs. @@ -213,8 +214,7 @@ __attribute__((always_inline)) INLINE static void star_formation_end_density( * @param cosmo The current cosmological model. */ __attribute__((always_inline)) INLINE static void -star_formation_part_has_no_neighbours(struct part* restrict p, - struct xpart* restrict xp, +star_formation_part_has_no_neighbours(struct part* p, struct xpart* xp, const struct star_formation* cd, const struct cosmology* cosmo) {} @@ -228,7 +228,7 @@ star_formation_part_has_no_neighbours(struct part* restrict p, * @param p Pointer to the particle data. */ __attribute__((always_inline)) INLINE static void star_formation_init_part( - struct part* restrict p, const struct star_formation* data) {} + struct part* p, const struct star_formation* data) {} /** * @brief Sets the star_formation properties of the (x-)particles to a valid @@ -244,12 +244,11 @@ __attribute__((always_inline)) INLINE static void star_formation_init_part( * @param xp Pointer to the extended particle data. */ __attribute__((always_inline)) INLINE static void -star_formation_first_init_part(const struct phys_const* restrict phys_const, - const struct unit_system* restrict us, - const struct cosmology* restrict cosmo, +star_formation_first_init_part(const struct phys_const* phys_const, + const struct unit_system* us, + const struct cosmology* cosmo, const struct star_formation* data, - const struct part* restrict p, - struct xpart* restrict xp) {} + const struct part* p, struct xpart* xp) {} /** * @brief Split the star formation content of a particle into n pieces diff --git a/src/stars/Default/stars_logger.h b/src/stars/Default/stars_logger.h index 891e274048c482659d08826f14658fe40a983124..2637cef126fa2ce4b8980b7f22265c80c463f7be 100644 --- a/src/stars/Default/stars_logger.h +++ b/src/stars/Default/stars_logger.h @@ -21,6 +21,8 @@ #ifdef WITH_LOGGER +#include "logger_io.h" + /* * List of all possible mask. * Outside the module, only stars_logger_field_count is used. diff --git a/src/statistics.c b/src/statistics.c index 711782a84f45610215f2a6fbfa50af2fe2c57053..edaaf94002115442f2bfafe46a0b95d8e93a7641 100644 --- a/src/statistics.c +++ b/src/statistics.c @@ -209,7 +209,7 @@ void stats_collect_part_mapper(void *map_data, int nr_parts, void *extra_data) { * @brief The #threadpool mapper function used to collect statistics for #spart. * * @param map_data Pointer to the particles. - * @param nr_parts The number of particles in this chunk + * @param nr_sparts The number of particles in this chunk * @param extra_data The #statistics aggregator. */ void stats_collect_spart_mapper(void *map_data, int nr_sparts, @@ -298,7 +298,7 @@ void stats_collect_spart_mapper(void *map_data, int nr_sparts, * @brief The #threadpool mapper function used to collect statistics for #sink. * * @param map_data Pointer to the particles. - * @param nr_parts The number of particles in this chunk + * @param nr_sinks The number of particles in this chunk * @param extra_data The #statistics aggregator. */ void stats_collect_sink_mapper(void *map_data, int nr_sinks, void *extra_data) { @@ -383,7 +383,7 @@ void stats_collect_sink_mapper(void *map_data, int nr_sinks, void *extra_data) { * @brief The #threadpool mapper function used to collect statistics for #bpart. * * @param map_data Pointer to the particles. - * @param nr_parts The number of particles in this chunk + * @param nr_bparts The number of particles in this chunk * @param extra_data The #statistics aggregator. */ void stats_collect_bpart_mapper(void *map_data, int nr_bparts, diff --git a/src/timestep.h b/src/timestep.h index 16fb935c00783995219e82df51f949eaf744c2fa..780183753073efa6a55f890cf37ff7600e72ea04 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -258,7 +258,7 @@ __attribute__((always_inline)) INLINE static integertime_t get_bpart_timestep( /* Black hole internal time-step */ float new_dt_black_holes = black_holes_compute_timestep( - bp, e->black_holes_properties, e->physical_constants); + bp, e->black_holes_properties, e->physical_constants, e->cosmology); /* Gravity time-step */ float new_dt_self = FLT_MAX, new_dt_ext = FLT_MAX; diff --git a/tools/plot_task_dependencies.py b/tools/plot_task_dependencies.py index 0d8b14c46c20110476a81176c5a03efcb20491ad..61b7aae41fe50a12d142e8a7a2afc6daebbac7e7 100755 --- a/tools/plot_task_dependencies.py +++ b/tools/plot_task_dependencies.py @@ -19,6 +19,7 @@ task_colours = { "hydro": "blue3", "gravity": "red3", "RT": "springgreen", + "sink": "lightseagreen", } @@ -54,6 +55,14 @@ def parse_args(): action="store_true", ) + parser.add_argument( + "-l", + "--with-levels", + dest="with_levels", + help="Write the number of each task at each level for each task individually", + action="store_true", + ) + parser.add_argument( "files", nargs="+", @@ -69,6 +78,12 @@ def parse_args(): if not path.exists(f): raise FileNotFoundError("You need to provide one file") + if args.with_calls and args.with_levels: + raise ValueError( + "I can't run with --with-calls and", + " --with-levels simultaneously. Pick one!", + ) + return args, files @@ -122,6 +137,7 @@ def append_single_data(data0, datai): datai: DataFrame The second dataframe + Returns ------- @@ -162,6 +178,7 @@ def append_data(data): data: list List containing all the dataframe to append together + Returns ------- @@ -170,6 +187,7 @@ def append_data(data): """ N = len(data) if N == 1: + # set default color data[0]["task_colour"] = "black" return data[0] @@ -178,6 +196,7 @@ def append_data(data): i += 1 data[0] = append_single_data(data[0], data[i]) + # set default color data[0]["task_colour"] = "black" return data[0] @@ -214,6 +233,8 @@ def get_task_colour(taskname): colour = task_colours["gravity"] elif task_is_RT(taskname): colour = task_colours["RT"] + elif task_is_sink(taskname): + colour = task_colours["sink"] return colour @@ -395,7 +416,17 @@ def get_function_calls(name): return pre + txt + app -def write_task(f, name, implicit, mpi, with_calls): +def write_task( + f, + name, + implicit, + mpi, + task_is_in_top, + task_is_in_hydro_super, + task_is_in_grav_super, + with_calls, + with_levels, +): """ Write the special task (e.g. implicit and mpi) @@ -414,8 +445,20 @@ def write_task(f, name, implicit, mpi, with_calls): mpi: int Is the task MPI related + task_is_in_hydro_super: bool + whether task is in top level cell + + task_is_in_hydro_super: bool + whether task is in hydro super cell + + task_is_in_grav_super: bool + whether task is in grav super cell + with_calls: bool - if true, write down the function calls + if True, write down the function calls + + with_levels: bool + if True, write down level at which tasks are called """ # generate text txt = "\t " + name + "[" @@ -424,14 +467,49 @@ def write_task(f, name, implicit, mpi, with_calls): txt += "style=filled,fillcolor=grey90," if mpi: txt += "shape=diamond,style=filled,fillcolor=azure," + if with_levels: + levelstr = "" + if task_is_in_top: + levelstr = "top" + if task_is_in_hydro_super and not task_is_in_grav_super: + if len(levelstr) > 0: + levelstr += " / " + levelstr += "hydro super" + if task_is_in_grav_super and not task_is_in_hydro_super: + if len(levelstr) > 0: + levelstr += " / " + levelstr += "grav super" + if task_is_in_grav_super and task_is_in_hydro_super: + if len(levelstr) > 0: + levelstr += " / " + levelstr += "super" + + if ( + (not task_is_in_top) + and (not task_is_in_grav_super) + and (not task_is_in_hydro_super) + ): + levelstr = "below super" + + txt += "\n\t\tlabel=<\n" + txt += '\t\t\t<TABLE BORDER="0" CELLBORDER="0" CELLSPACING="0">\n' + txt += ( + '\t\t\t\t<TR> <TD> <B> <FONT POINT-SIZE="18">' + + name + + " </FONT> </B> </TD> </TR> <!-- task name -->\n" + ) + txt += ( + '\t\t\t\t<TR> <TD> <FONT POINT-SIZE="18">' + + levelstr + + "</FONT> </TD> </TR> <!-- task level -->\n" + ) + txt += "\t\t\t</TABLE>\n" + txt += "\t\t\t>,\n\t\t" col = get_task_colour(name) txt += "color=%s," % col - if task_is_sink(name): - txt += "color=lightseagreen," - if with_calls: func = get_function_calls(name) if func is not None: @@ -487,7 +565,17 @@ 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], + data["task_in_is_top"][i] == 1, + data["task_in_is_hydro_super"][i] == 1, + data["task_in_is_grav_super"][i] == 1, + opt.with_calls, + opt.with_levels, + ) # do task out for i in range(N): @@ -496,7 +584,17 @@ 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], + data["task_out_is_top"][i] == 1, + data["task_out_is_hydro_super"][i] == 1, + data["task_out_is_grav_super"][i] == 1, + opt.with_calls, + opt.with_levels, + ) f.write("\n") diff --git a/tools/plot_task_level.py b/tools/plot_task_level.py index 23e3ec878a2b8ef0f4d3c56d91ef75026e012de8..2fbe55c025db7f400aa009e488412475c9259630 100755 --- a/tools/plot_task_level.py +++ b/tools/plot_task_level.py @@ -1,47 +1,284 @@ -#!/usr/bin/python -""" +#!/usr/bin/env python3 +description = """ +Plot the number of tasks for each depth level and each type of task. + Usage: ./plot_task_level.py task_level.txt -Description: - Plot the number of tasks for each depth level and each type of task. """ import pandas as pd +import numpy as np import matplotlib.pyplot as plt import sys +import argparse +from os import path + + +def parse_args(): + """ + Parses command line arguments. + + Returns + ------- + + args: Namespace + Namespace returned by argparse.ArgumentParser.parse_args() + containing all arguments + + files: + List of files parsed from the command line. + + Raises + ------ + + FileNotFoundError + If the required filename provided on the command line doesn't exist + """ -# get filename -filename = sys.argv[-1] - -# Column names -names = ["type", "subtype", "depth", "count"] - -# read file -data = pd.read_csv(filename, sep=" ", comment="#", names=names) - -# generate color map -cmap = plt.get_cmap("hsv") -N = data["depth"].max() + 5 - -# plot data -for i in range(data["depth"].max()): - ind = data["depth"] == i - label = "depth = %i" % i - c = cmap(i / N) - plt.plot( - data["type"][ind] + "_" + data["subtype"][ind], - data["count"][ind], - ".", - label=label, - color=c, + # description is string at the top of this file. + parser = argparse.ArgumentParser(description=description) + + parser.add_argument( + "-c", + "--count", + dest="count_levels", + help="count on how many different levels the tasks can be found" + " and add it to the label", + action="store_true", + ) + + parser.add_argument( + "-d", + "--displace", + dest="displace", + help="attempt to displace overlapping point on the plot a bit" + " and try to make them visible", + action="store_true", + ) + + parser.add_argument( + "file", + type=str, + help="Required file name of .csv file(s) of the task levels " + "generated by swift.", ) -# modify figure parameters and show it -plt.gca().set_yscale("log") -plt.xticks(rotation=45) -plt.ylabel("Number of Tasks") -plt.gcf().subplots_adjust(bottom=0.15) -plt.legend() -plt.show() + args = parser.parse_args() + filename = args.file + print(filename) + + if not path.exists(filename): + raise FileNotFoundError("File not found:'" + filename + "'") + + return args, filename + + +def read_data(filename): + """ + Reads in data from the csv file. + + Parameters + ---------- + + filename: str + filename to be read from + + + Returns + ------- + + data: pandas dataset + dataset containing read in data + """ + + # Column names + names = ["type", "subtype", "depth", "count"] + + # read file + data = pd.read_csv(filename, sep=" ", comment="#", names=names) + + return data + + +def get_discrete_cmap(nentries): + """ + Returns a discrete colormap. + + Parameters + ---------- + + nentries: int + how many entries you want for your colormap + + + Returns + ------- + + cmap: list + list of colors + + + Raises + ------ + + IndexError: + When you want more entries than there are available. + Current maximum is 21. + """ + + fullcolorlist = [ + "red", + "green", + "blue", + "gold", + "magenta", + "cyan", + "lime", + "saddlebrown", + "darkolivegreen", + "cornflowerblue", + "orange", + "dimgrey", + "navajowhite", + "darkslategray", + "mediumpurple", + "lightpink", + "mediumseagreen", + "maroon", + "midnightblue", + "silver", + "black", + ] + + if nentries >= len(fullcolorlist) - 1: + raise IndexError( + "I can't handle more than 21 different colors." + "Add more manually in get_discrete_cmap() function" + ) + + return fullcolorlist[: nentries + 1] + + +def add_levelcounts(data): + """ + Adds a column to the data with the counts on how many levels a given task + is executed on. + + Parameters + ---------- + + data: pandas dataframe + The dataframe to use + + Returns + ------- + + data: pandas dataframe + the modified dataframe + """ + + # add new column + data["nlevels"] = ["1" for _ in range(data.shape[0])] + + # count on how many levels each task exists + for i, (ttype, tsubtype) in enumerate(zip(data["type"], data["subtype"])): + istype = data["type"] == ttype + issubtype = data["subtype"] == tsubtype + isthis = np.logical_and(istype, issubtype) + count = np.count_nonzero(isthis) + data.at[i, "nlevels"] = str(count) + + return data + + +def add_displacement(data): + """ + Add small displacements to the task number counts and try + to make them better visible + + Parameters + ---------- + + data: pandas dataframe + the data to be modified + + + Returns + ------- + + data: pandas dataframe + the modified data + """ + # add new column + data["yvals"] = data["count"] * 1.0 + data["yval_modified"] = False + inds = np.arange(0, data.shape[0]) + + # count on how many levels each task exists + for i, (ttype, tsubtype) in enumerate(zip(data["type"], data["subtype"])): + if data["yval_modified"][i]: + continue + istype = data["type"] == ttype + issubtype = data["subtype"] == tsubtype + isthis = np.logical_and(istype, issubtype) + uniques = np.unique(data["count"][isthis]) + for u in uniques: + occurances = np.count_nonzero(data["count"][isthis] == u) + for o in range(occurances): + thisind = inds[isthis][o] + step = 0.05 * max(int(np.log10(u) + 0.5), 1) * o * (-1) ** o + data.at[thisind, "yvals"] += step + data.at[thisind, "yval_modified"] = True + + return data + + +if __name__ == "__main__": + + args, filename = parse_args() + + data = read_data(filename) + cmap = get_discrete_cmap(data["depth"].max()) + + # are we counting the levels? + if args.count_levels: + data = add_levelcounts(data) + + # are we displacing the particles on the y axis? + if args.displace: + data = add_displacement(data) + + # plot data + for i in range(data["depth"].max() + 1): + ind = data["depth"] == i + label = "depth = {0:d}".format(i) + + if args.count_levels: + xvals = ( + data["type"][ind] + + "_" + + data["subtype"][ind] + + "[" + + data["nlevels"][ind] + + "]" + ) + else: + xvals = data["type"][ind] + "_" + data["subtype"][ind] + + if args.displace: + yvals = data["yvals"][ind] + else: + yvals = data["count"][ind] + c = cmap[i] + plt.plot(xvals, yvals, "o", label=label, color=c, alpha=0.7) + + # modify figure parameters and show it + plt.gca().set_yscale("log") + plt.xticks(rotation=90) + plt.ylabel("Number of Tasks") + plt.gcf().subplots_adjust(bottom=0.225) + plt.legend() + plt.grid() + plt.show() diff --git a/tools/read_index_file.py b/tools/read_index_file.py new file mode 100644 index 0000000000000000000000000000000000000000..96ab1df2e7e8426b5c84e3822b8fb6a05aabfd46 --- /dev/null +++ b/tools/read_index_file.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 + +import sys +import numpy as np + +filename = sys.argv[-1] +n_type = 6 + + +# dtype for the particle's data +dt = np.dtype([("ids", np.ulonglong), + ("offset", np.uint64)]) + +# Read the file +with open(filename, "rb") as f: + # read the time + time = np.fromfile(f, dtype=float, count=1) + time_int = np.fromfile(f, dtype=np.longlong, count=1) + print("Time: {}, integer time: {}".format( + time[0], time_int[0])) + + # read the number of particles + nparts = np.fromfile(f, dtype=np.uint64, count=n_type) + + print("Number of particles:", nparts) + + # read if the file is sorted + sort = np.fromfile(f, dtype=np.bool, count=1) + print("File is sorted?", sort[0]) + + # read the memory alignment garbage + n = ((f.tell() + 7) & ~7) - f.tell() + f.read(n) + + # read the particles + print("Particles data (ids / offset):") + for n in nparts: + if n == 0: + continue + + data = np.fromfile(f, dtype=dt, count=n) + + print("\t", data) + + # print the history of new particles + n_new = np.fromfile(f, dtype=np.uint64, count=n_type) + print("New particles: ", n_new) + + for n in n_new: + if n == 0: + continue + + data = np.fromfile(f, dtype=dt, count=n) + + print("\t", data) + + # print the history of particles removed + n_rem = np.fromfile(f, dtype=np.uint64, count=n_type) + print("Particles removed: ", n_rem) + + for n in n_rem: + if n == 0: + continue + + data = np.fromfile(f, dtype=dt, count=n) + + print("\t", data)