diff --git a/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml b/examples/EAGLE_ICs/EAGLE_12/eagle_12.yml index b460d5eb9ef708eb395c90d5de34e01cd9c9fa94..05fbb5b3df0d0503e19f34d97c8b4c16db05310e 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 f117f592781d4e00af6a65bc58e3920402c94ad6..494c198e76a543eb0418aac3912cd819a62b2017 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 2668aae341723c99ed7b6ab689101f6291497baa..72652be8f68ecbf1285a8f3c8c900f262284e4f8 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 da94c654c178b39e8d401d924e9426ba9d4ffd99..40d4aeaec0fc621b40081e810ce22696fcbed8f8 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 b1594e1d06b6f818e418aa84650809e0c0797113..6969a993816263b47c744bdcc84b4dba09e8de71 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 58e24bfb94e60114a4121f38c42e1d821fdeede0..3c709c3875168a015358b17fa8772c3296b968bf 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 67e46fa9a6a32242acb06fcf1e34c35e6740b537..cae4b4313f4d34726115e1060e9f20ff2ba303fa 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 427f067c2f186e6b6706510455e4ab5b60704256..a605a804681770530bf77bfefffdf02655f6ebe8 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 24c2fd5cd835cd937c89027be64b10f185cc5bce..64360ec2b94cd45728ddc7cb825376d39bfe961b 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 4cf4572c01fddde18281b3b775f884bf34379576..60f3d7a0cc0681e90d504e68f2cbb8370530cf81 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 2bddfd52bedb819b7413a62b48bb65311651d609..578ca13381e160f1f3543ef9a0e266d8e5aabcee 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 1216365794e8ae270ce894011885039a256ace48..cd25e6b4a42676b9600347e6047bd4fbc3cd4034 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 dc343ae2e811098ec77797ec79b659db29e08e4a..b238294a5c8ead519767b52130a4ac4ced24956a 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 d9bb62201d7b087670aef0ce2346a51bf61a3868..354b01e2e00fc0985a25bc958c0ec13af929f5b4 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)