From 83b3429f5cd067aed36cb72f49c894bcbfc8cc60 Mon Sep 17 00:00:00 2001 From: Matthieu Schaller <schaller@strw.leidenuniv.nl> Date: Sun, 8 Dec 2019 12:07:51 +0100 Subject: [PATCH] Store the last redshift at which a BH has had its last minor or major merger. --- examples/EAGLE_ICs/EAGLE_12/eagle_12.yml | 4 ++- examples/EAGLE_ICs/EAGLE_25/eagle_25.yml | 4 ++- examples/EAGLE_ICs/EAGLE_50/eagle_50.yml | 2 ++ examples/EAGLE_low_z/EAGLE_12/eagle_12.yml | 4 ++- examples/EAGLE_low_z/EAGLE_25/eagle_25.yml | 4 ++- examples/EAGLE_low_z/EAGLE_50/eagle_50.yml | 4 ++- examples/EAGLE_low_z/EAGLE_6/eagle_6.yml | 4 ++- examples/parameter_example.yml | 2 ++ src/black_holes/Default/black_holes.h | 7 +++- src/black_holes/EAGLE/black_holes.h | 29 ++++++++++++++++- src/black_holes/EAGLE/black_holes_io.h | 32 ++++++++++++++++--- src/black_holes/EAGLE/black_holes_part.h | 20 ++++++++++++ .../EAGLE/black_holes_properties.h | 20 ++++++++++-- src/runner_black_holes.c | 5 ++- 14 files changed, 126 insertions(+), 15 deletions(-) diff --git a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml index b460d5eb9e..05fbb5b3df 100644 --- a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml @@ -182,4 +182,6 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml index f117f59278..494c198e76 100644 --- a/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_ICs/EAGLE_25/eagle_25.yml @@ -183,4 +183,6 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml index 2668aae341..72652be8f6 100644 --- a/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_ICs/EAGLE_50/eagle_50.yml @@ -184,3 +184,5 @@ EAGLEAGN: AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml index da94c654c1..40d4aeaec0 100644 --- a/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml +++ b/examples/EAGLE_low_z/EAGLE_12/eagle_12.yml @@ -177,4 +177,6 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml index b1594e1d06..6969a99381 100644 --- a/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml +++ b/examples/EAGLE_low_z/EAGLE_25/eagle_25.yml @@ -185,4 +185,6 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml index 58e24bfb94..3c709c3875 100644 --- a/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml +++ b/examples/EAGLE_low_z/EAGLE_50/eagle_50.yml @@ -176,4 +176,6 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml index 67e46fa9a6..cae4b4313f 100644 --- a/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml +++ b/examples/EAGLE_low_z/EAGLE_6/eagle_6.yml @@ -186,4 +186,6 @@ EAGLEAGN: coupling_efficiency: 0.15 # Fraction of the radiated energy that couples to the gas in feedback events. AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. - max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. \ No newline at end of file + max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 427f067c2f..a605a80468 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -435,3 +435,5 @@ EAGLEAGN: AGN_delta_T_K: 3.16228e8 # Change in temperature to apply to the gas particle in an AGN feedback event in Kelvin. AGN_num_ngb_to_heat: 1. # Target number of gas neighbours to heat in an AGN feedback event. max_reposition_mass: 2e8 # Maximal BH mass considered for BH repositioning in solar masses. + 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' diff --git a/src/black_holes/Default/black_holes.h b/src/black_holes/Default/black_holes.h index 24c2fd5cd8..64360ec2b9 100644 --- a/src/black_holes/Default/black_holes.h +++ b/src/black_holes/Default/black_holes.h @@ -163,9 +163,14 @@ __attribute__((always_inline)) INLINE static void black_holes_swallow_part( * @param bpi The #bpart to update. * @param bpj The #bpart that is swallowed. * @param cosmo The current cosmological model. + * @param time Time since the start of the simulation (non-cosmo mode). + * @param with_cosmology Are we running with cosmology? + * @param props The properties of the black hole scheme. */ __attribute__((always_inline)) INLINE static void black_holes_swallow_bpart( - struct bpart* bpi, const struct bpart* bpj, const struct cosmology* cosmo) { + struct bpart* bpi, const struct bpart* bpj, const struct cosmology* cosmo, + const double time, const int with_cosmology, + const struct black_holes_props* props) { /* Nothing to do here: No merging in the default model */ } diff --git a/src/black_holes/EAGLE/black_holes.h b/src/black_holes/EAGLE/black_holes.h index 4cf4572c01..60f3d7a0cc 100644 --- a/src/black_holes/EAGLE/black_holes.h +++ b/src/black_holes/EAGLE/black_holes.h @@ -63,6 +63,8 @@ __attribute__((always_inline)) INLINE static void black_holes_first_init_bpart( bp->cumulative_number_seeds = 1; bp->number_of_mergers = 0; bp->last_high_Eddington_fraction_scale_factor = -1.f; + bp->last_minor_merger_time = -1.; + bp->last_major_merger_time = -1.; black_holes_mark_bpart_as_not_swallowed(&bp->merger_data); } @@ -280,14 +282,35 @@ __attribute__((always_inline)) INLINE static void black_holes_swallow_part( * @param bpi The #bpart to update. * @param bpj The #bpart that is swallowed. * @param cosmo The current cosmological model. + * @param time Time since the start of the simulation (non-cosmo mode). + * @param with_cosmology Are we running with cosmology? + * @param props The properties of the black hole scheme. */ __attribute__((always_inline)) INLINE static void black_holes_swallow_bpart( - struct bpart* bpi, const struct bpart* bpj, const struct cosmology* cosmo) { + struct bpart* bpi, const struct bpart* bpj, const struct cosmology* cosmo, + const double time, const int with_cosmology, + const struct black_holes_props* props) { /* Get the current dynamical masses */ const float bpi_dyn_mass = bpi->mass; const float bpj_dyn_mass = bpj->mass; + /* Is this merger ratio above the threshold for recording? */ + const double merger_ratio = bpj->subgrid_mass / bpi->subgrid_mass; + if (merger_ratio > props->major_merger_threshold) { + if (with_cosmology) { + bpi->last_major_merger_scale_factor = cosmo->a; + } else { + bpi->last_major_merger_time = time; + } + } else if (merger_ratio > props->minor_merger_threshold) { + if (with_cosmology) { + bpi->last_minor_merger_scale_factor = cosmo->a; + } else { + bpi->last_minor_merger_time = time; + } + } + /* Increase the masses of the BH. */ bpi->mass += bpj->mass; bpi->gpart->mass += bpj->mass; @@ -573,6 +596,10 @@ INLINE static void black_holes_create_from_gas( /* Last time this BH had a high Eddington fraction */ bp->last_high_Eddington_fraction_scale_factor = -1.f; + /* Last time of mergers */ + bp->last_minor_merger_time = -1.; + bp->last_major_merger_time = -1.; + /* First initialisation */ black_holes_init_bpart(bp); diff --git a/src/black_holes/EAGLE/black_holes_io.h b/src/black_holes/EAGLE/black_holes_io.h index 2bddfd52be..578ca13381 100644 --- a/src/black_holes/EAGLE/black_holes_io.h +++ b/src/black_holes/EAGLE/black_holes_io.h @@ -114,7 +114,7 @@ INLINE static void black_holes_write_particles(const struct bpart* bparts, int with_cosmology) { /* Say how much we want to write */ - *num_fields = 15; + *num_fields = 17; /* List what we want to write */ list[0] = io_make_output_field_convert_bpart( @@ -191,16 +191,40 @@ INLINE static void black_holes_write_particles(const struct bpart* bparts, list[14] = io_make_output_field( "LastHighEddingtonFractionScaleFactors", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, bparts, last_high_Eddington_fraction_scale_factor, - "Scale-factors at which the black holes last reached an Eddington " - "ratio > 0.1. -1 if never reached."); + "Scale-factors at which the black holes last reached a large Eddington " + "ratio. -1 if never reached."); } else { list[14] = io_make_output_field( "LastHighEddingtonFractionTimes", FLOAT, 1, UNIT_CONV_TIME, 0.f, bparts, last_high_Eddington_fraction_time, - "Times at which the black holes last reached an Eddington ratio > 0.1. " + "Times at which the black holes last reached a large Eddington ratio. " "-1 if never reached."); } + if (with_cosmology) { + list[15] = io_make_output_field( + "LastMinorMergerScaleFactors", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, + bparts, last_minor_merger_scale_factor, + "Scale-factors at which the black holes last had a minor merger."); + } else { + list[15] = io_make_output_field( + "LastMinorMergerScaleTimes", FLOAT, 1, UNIT_CONV_TIME, 0.f, bparts, + last_minor_merger_time, + "Times at which the black holes last had a minor merger."); + } + + if (with_cosmology) { + list[16] = io_make_output_field( + "LastMajorMergerScaleFactors", FLOAT, 1, UNIT_CONV_NO_UNITS, 0.f, + bparts, last_major_merger_scale_factor, + "Scale-factors at which the black holes last had a major merger."); + } else { + list[16] = io_make_output_field( + "LastMajorMergerScaleTimes", FLOAT, 1, UNIT_CONV_TIME, 0.f, bparts, + last_major_merger_time, + "Times at which the black holes last had a major merger."); + } + #ifdef DEBUG_INTERACTIONS_BLACK_HOLES list += *num_fields; diff --git a/src/black_holes/EAGLE/black_holes_part.h b/src/black_holes/EAGLE/black_holes_part.h index 1216365794..cd25e6b4a4 100644 --- a/src/black_holes/EAGLE/black_holes_part.h +++ b/src/black_holes/EAGLE/black_holes_part.h @@ -121,6 +121,26 @@ struct bpart { float last_high_Eddington_fraction_scale_factor; }; + /*! Union for the last minor merger point in time */ + union { + + /*! Last time the BH had a a high Eddington fraction */ + float last_minor_merger_time; + + /*! Last scale factor the BH had a a high Eddington fraction */ + float last_minor_merger_scale_factor; + }; + + /*! Union for the last major merger point in time */ + union { + + /*! Last time the BH had a a high Eddington fraction */ + float last_major_merger_time; + + /*! Last scale factor the BH had a a high Eddington fraction */ + float last_major_merger_scale_factor; + }; + /*! Properties used in the feedback loop to distribute to gas neighbours. */ struct { diff --git a/src/black_holes/EAGLE/black_holes_properties.h b/src/black_holes/EAGLE/black_holes_properties.h index dc343ae2e8..b238294a5c 100644 --- a/src/black_holes/EAGLE/black_holes_properties.h +++ b/src/black_holes/EAGLE/black_holes_properties.h @@ -82,6 +82,14 @@ struct black_holes_props { /*! Maximal mass of BH to reposition */ float max_reposition_mass; + /* ---- Properties of the merger model ---------- */ + + /*! Mass ratio above which a merger is considered 'minor' */ + float minor_merger_threshold; + + /*! Mass ratio above which a merger is considered 'major' */ + float major_merger_threshold; + /* ---- Common conversion factors --------------- */ /*! Conversion factor from temperature to internal energy */ @@ -151,8 +159,8 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, /* Accretion parameters ---------------------------------- */ bp->f_Edd = parser_get_param_float(params, "EAGLEAGN:max_eddington_fraction"); - bp->f_Edd_recording = - parser_get_param_float(params, "EAGLEAGN:eddington_fraction_for_recording"); + bp->f_Edd_recording = parser_get_param_float( + params, "EAGLEAGN:eddington_fraction_for_recording"); bp->epsilon_r = parser_get_param_float(params, "EAGLEAGN:radiative_efficiency"); bp->epsilon_f = @@ -175,6 +183,14 @@ INLINE static void black_holes_props_init(struct black_holes_props *bp, /* Convert to internal units */ bp->max_reposition_mass *= phys_const->const_solar_mass; + /* Merger parameters ------------------------------------- */ + + bp->minor_merger_threshold = + parser_get_param_float(params, "EAGLEAGN:threshold_minor_merger"); + + bp->major_merger_threshold = + parser_get_param_float(params, "EAGLEAGN:threshold_major_merger"); + /* Common conversion factors ----------------------------- */ /* Calculate temperature to internal energy conversion factor (all internal diff --git a/src/runner_black_holes.c b/src/runner_black_holes.c index d9bb62201d..354b01e2e0 100644 --- a/src/runner_black_holes.c +++ b/src/runner_black_holes.c @@ -275,6 +275,8 @@ void runner_do_bh_swallow(struct runner *r, struct cell *c, int timer) { struct engine *e = r->e; struct space *s = e->s; + const int with_cosmology = (e->policy & engine_policy_cosmology); + const struct black_holes_props *props = e->black_holes_properties; struct bpart *bparts = s->bparts; const size_t nr_bpart = s->nr_bparts; #ifdef WITH_MPI @@ -349,7 +351,8 @@ void runner_do_bh_swallow(struct runner *r, struct cell *c, int timer) { lock_lock(&s->lock); /* Swallow the gas particle (i.e. update the BH properties) */ - black_holes_swallow_bpart(bp, cell_bp, e->cosmology); + black_holes_swallow_bpart(bp, cell_bp, e->cosmology, e->time, + with_cosmology, props); /* Release the space as we are done updating the bpart */ if (lock_unlock(&s->lock) != 0) -- GitLab