diff --git a/src/feedback/AGORA/feedback.c b/src/feedback/AGORA/feedback.c index 93ca89e5af82ef7e8a5b9ec8c4bf2fc7e17c47a0..4e662b551a806b98fdfc2211f0c5a8d631457b6a 100644 --- a/src/feedback/AGORA/feedback.c +++ b/src/feedback/AGORA/feedback.c @@ -244,14 +244,18 @@ void feedback_init_spart(struct spart* sp) { } /** - * @brief Reset the feedback field when the spart is not - * in a correct state for feeedback_will_do_feedback. + * @brief Prepare the feedback fields after a star is born. * - * This function is called in the timestep task. + * This function is called in the functions sink_copy_properties_to_star() and + * star_formation_copy_properties(). + * + * @param sp The #spart to act upon. + * @param feedback_props The feedback perties to use. + * @param star_type The stellar particle type. */ void feedback_init_after_star_formation( - struct spart* sp, const struct feedback_props* feedback_props) { - feedback_init_spart(sp); + struct spart* sp, const struct feedback_props* feedback_props, + enum star_feedback_type star_type) { /* Zero the energy of supernovae */ sp->feedback_data.energy_ejected = 0; @@ -261,6 +265,10 @@ void feedback_init_after_star_formation( /* The particle is not idle */ sp->feedback_data.idle = 0; + + /* Give to the star its appropriate type: single star, continuous IMF star or + single population star */ + sp->feedback_data.star_type = star_type; } /** diff --git a/src/feedback/AGORA/feedback.h b/src/feedback/AGORA/feedback.h index c215874d4e8130968bf5192cbb2167a270c17ffb..a5b1aed331c09e5b1803282207fcd137e412c564 100644 --- a/src/feedback/AGORA/feedback.h +++ b/src/feedback/AGORA/feedback.h @@ -59,7 +59,8 @@ __attribute__((always_inline)) INLINE static void feedback_reset_part( void feedback_init_spart(struct spart* sp); void feedback_init_after_star_formation( - struct spart* sp, const struct feedback_props* feedback_props); + struct spart* sp, const struct feedback_props* feedback_props, + enum star_feedback_type star_type); /** * @brief Should we do feedback for this star? diff --git a/src/feedback/AGORA/feedback_struct.h b/src/feedback/AGORA/feedback_struct.h index 3afa74c37c3cd41d2c1ff9cc6bdbfc325b0f4e19..1d8a4de3a11a52d31395351e1b70eb16be2d557a 100644 --- a/src/feedback/AGORA/feedback_struct.h +++ b/src/feedback/AGORA/feedback_struct.h @@ -22,15 +22,16 @@ #include "chemistry_struct.h" /** - * @brief The stellar feedback type for each star type. Now, star particles can - * represent a single star ("single_star"), a stellar population without SNII - * feedback ("star_population_no_SNII") or a stellar population with SNII - * feedback ("stellar population"). + * @brief The stellar feedback type for each star type. + * + * Now, star particles can represent a single star ("single_star"), a stellar + * population from a continuous IMF or a stellar population from a whole IMF. */ enum star_feedback_type { - single_star, /* particle representing a single star */ - star_population_no_SNII, /* particle representing a population without SNII */ - star_population /* particle representing a population (with SNII) */ + single_star, /* particle representing a single star */ + star_population_continuous_IMF, /* particle representing a population of the + continuous part of the IMF */ + star_population /* particle representing a population with the whole IMF */ }; /** diff --git a/src/feedback/GEAR/feedback.c b/src/feedback/GEAR/feedback.c index 449089651d059ec7f44ef2023f45573eb6fe1fb0..a61be623f27d2e025c4a98459ee0d7b6475e1578 100644 --- a/src/feedback/GEAR/feedback.c +++ b/src/feedback/GEAR/feedback.c @@ -151,8 +151,7 @@ void compute_time(struct spart* sp, const int with_cosmology, } /** - * @brief Will this individual star want to do feedback during the next - * time-step? + * @brief Will this star particle want to do feedback during the next time-step? * * This is called in the time step task. * @@ -167,94 +166,29 @@ void compute_time(struct spart* sp, const int with_cosmology, * @param time_base The time base. * @param time The physical time in internal units. */ -void feedback_will_do_feedback_individual_star( +void feedback_will_do_feedback( struct spart* sp, const struct feedback_props* feedback_props, const int with_cosmology, const struct cosmology* cosmo, const double time, const struct unit_system* us, const struct phys_const* phys_const, const integertime_t ti_current, const double time_base) { - /* Compute the times */ - double star_age_beg_step = 0; - double dt_enrichment = 0; - integertime_t ti_begin = 0; - compute_time(sp, with_cosmology, cosmo, &star_age_beg_step, &dt_enrichment, - &ti_begin, ti_current, time_base, time); - /* Zero the energy of supernovae */ sp->feedback_data.energy_ejected = 0; sp->feedback_data.will_do_feedback = 0; -#ifdef SWIFT_DEBUG_CHECKS - if (sp->birth_time == -1.) error("Evolving a star particle that should not!"); - if (star_age_beg_step + dt_enrichment < 0) { - error("Negative age for a star"); - } -#endif - - /* Ensure that the age is positive (rounding errors) */ - const double star_age_beg_step_safe = - star_age_beg_step < 0 ? 0 : star_age_beg_step; + /* quit if the birth_scale_factor or birth_time is negative */ + if (sp->birth_scale_factor < 0.0 || sp->birth_time < 0.0) return; /* Pick the correct table. (if only one table, threshold is < 0) */ const float metal = chemistry_get_star_total_iron_mass_fraction_for_feedback(sp); const float threshold = feedback_props->metallicity_max_first_stars; + /* If metal < threshold, then sp is a first star particle. */ + const int is_first_star = metal < threshold; const struct stellar_model* model = - metal < threshold ? &feedback_props->stellar_model_first_stars - : &feedback_props->stellar_model; - - /* Compute the stellar evolution including SNe energy */ - stellar_evolution_evolve_individual_star(sp, model, cosmo, us, phys_const, - ti_begin, star_age_beg_step_safe, - dt_enrichment); - - /* apply the energy efficiency factor */ - sp->feedback_data.energy_ejected *= feedback_props->supernovae_efficiency; - - /* Set the particle as doing some feedback */ - sp->feedback_data.will_do_feedback = sp->feedback_data.energy_ejected != 0.; -} - -/** - * @brief Will this star particle want to do feedback during the next time-step? - * - * This is called in the time step task. - * - * In GEAR, we compute the full stellar evolution here. - * - * @param sp The particle to act upon - * @param feedback_props The #feedback_props structure. - * @param cosmo The current cosmological model. - * @param us The unit system. - * @param phys_const The #phys_const. - * @param ti_current The current time (in integer) - * @param time_base The time base. - * @param time The physical time in internal units. - */ -void feedback_will_do_feedback( - struct spart* sp, const struct feedback_props* feedback_props, - const int with_cosmology, const struct cosmology* cosmo, const double time, - const struct unit_system* us, const struct phys_const* phys_const, - const integertime_t ti_current, const double time_base) { - - /* quit if the birth_scale_factor or birth_time is negative */ - if (sp->birth_scale_factor < 0.0 || sp->birth_time < 0.0) return; - - /* quit if the particle contains no SNII */ - if (sp->feedback_data.star_type == star_population_no_SNII) { - sp->feedback_data.energy_ejected = 0; - sp->feedback_data.will_do_feedback = 0; - return; - } - - /* a single star */ - if (sp->feedback_data.star_type == single_star) { - feedback_will_do_feedback_individual_star( - sp, feedback_props, with_cosmology, cosmo, time, us, phys_const, - ti_current, time_base); - return; - } + is_first_star ? &feedback_props->stellar_model_first_stars + : &feedback_props->stellar_model; /* Compute the times */ double star_age_beg_step = 0; @@ -263,35 +197,33 @@ void feedback_will_do_feedback( compute_time(sp, with_cosmology, cosmo, &star_age_beg_step, &dt_enrichment, &ti_begin, ti_current, time_base, time); - /* Zero the energy of supernovae */ - sp->feedback_data.energy_ejected = 0; - sp->feedback_data.will_do_feedback = 0; - #ifdef SWIFT_DEBUG_CHECKS if (sp->birth_time == -1.) error("Evolving a star particle that should not!"); if (star_age_beg_step + dt_enrichment < 0) { error("Negative age for a star"); } #endif - /* Ensure that the age is positive (rounding errors) */ const double star_age_beg_step_safe = star_age_beg_step < 0 ? 0 : star_age_beg_step; - /* Pick the correct table. (if only one table, threshold is < 0) */ - const float metal = - chemistry_get_star_total_iron_mass_fraction_for_feedback(sp); - const float threshold = feedback_props->metallicity_max_first_stars; - - const struct stellar_model* model = - metal < threshold ? &feedback_props->stellar_model_first_stars - : &feedback_props->stellar_model; - - /* Compute the stellar evolution including SNe energy */ - stellar_evolution_evolve_spart(sp, model, cosmo, us, phys_const, ti_begin, - star_age_beg_step_safe, dt_enrichment); + /* A single star */ + if (sp->feedback_data.star_type == single_star) { + /* Now, compute the stellar evolution state for individual star particles. + */ + stellar_evolution_evolve_individual_star(sp, model, cosmo, us, phys_const, + ti_begin, star_age_beg_step_safe, + dt_enrichment); + } else { + /* Compute the stellar evolution including SNe energy. This function treats + the case of particles representing the whole IMF (star_type = + star_population) and the particles representing only the continuous part + of the IMF (star_type = star_population_continuous_IMF) */ + stellar_evolution_evolve_spart(sp, model, cosmo, us, phys_const, ti_begin, + star_age_beg_step_safe, dt_enrichment); + } - /* apply the energy efficiency factor */ + /* Apply the energy efficiency factor */ sp->feedback_data.energy_ejected *= feedback_props->supernovae_efficiency; /* Set the particle as doing some feedback */ @@ -344,13 +276,19 @@ void feedback_init_spart(struct spart* sp) { } /** - * @brief Reset the feedback field when the spart is not - * in a correct state for feeedback_will_do_feedback. + * @brief Prepare the feedback fields after a star is born. * - * This function is called in the timestep task. + * This function is called in the functions sink_copy_properties_to_star() and + * star_formation_copy_properties(). + * + * @param sp The #spart to act upon. + * @param feedback_props The feedback perties to use. + * @param star_type The stellar particle type. */ void feedback_init_after_star_formation( - struct spart* sp, const struct feedback_props* feedback_props) { + struct spart* sp, const struct feedback_props* feedback_props, + enum star_feedback_type star_type) { + feedback_init_spart(sp); /* Zero the energy of supernovae */ @@ -358,6 +296,10 @@ void feedback_init_after_star_formation( /* Activate the feedback loop for the first step */ sp->feedback_data.will_do_feedback = 1; + + /* Give to the star its appropriate type: single star, continuous IMF star or + single population star */ + sp->feedback_data.star_type = star_type; } /** diff --git a/src/feedback/GEAR/feedback.h b/src/feedback/GEAR/feedback.h index 4a81a53cc801773ddbe4bf8abcc5b7c3e08712cc..18b0a940202b5d99678404e41b634807b2701ff9 100644 --- a/src/feedback/GEAR/feedback.h +++ b/src/feedback/GEAR/feedback.h @@ -50,7 +50,8 @@ double feedback_get_enrichment_timestep(const struct spart* sp, void feedback_init_spart(struct spart* sp); void feedback_init_after_star_formation( - struct spart* sp, const struct feedback_props* feedback_props); + struct spart* sp, const struct feedback_props* feedback_props, + enum star_feedback_type star_type); void feedback_reset_feedback(struct spart* sp, const struct feedback_props* feedback_props); void feedback_first_init_spart(struct spart* sp, diff --git a/src/feedback/GEAR/feedback_struct.h b/src/feedback/GEAR/feedback_struct.h index 372033df8c45b558edfd1f196f87ce62401bfd14..00f90b1f8f8f839fa5c740ceb32995de71d64028 100644 --- a/src/feedback/GEAR/feedback_struct.h +++ b/src/feedback/GEAR/feedback_struct.h @@ -22,15 +22,16 @@ #include "chemistry_struct.h" /** - * @brief The stellar feedback type for each star type. Now, star particles can - * represent a single star ("single_star"), a stellar population without SNII - * feedback ("star_population_no_SNII") or a stellar population with SNII - * feedback ("stellar population"). + * @brief The stellar feedback type for each star type. + * + * Now, star particles can represent a single star ("single_star"), a stellar + * population from a continuous IMF or a stellar population from a whole IMF. */ enum star_feedback_type { - single_star, /* particle representing a single star */ - star_population_no_SNII, /* particle representing a population without SNII */ - star_population /* particle representing a population (with SNII) */ + single_star, /* particle representing a single star */ + star_population_continuous_IMF, /* particle representing a population of the + continuous part of the IMF */ + star_population /* particle representing a population with the whole IMF */ }; /** @@ -79,6 +80,11 @@ struct feedback_spart_data { char will_do_feedback; /* Feedback type in function of the star particle type */ + /* Note for Darwin (July 2024): Ideally, I'd like to move this to the star + module and not the feedback. The type of the stellar particle is more related + to the star than the feedback. Furthermore, this type may be used in other + modules, e.g. RT, star formation, etc. This type is already used by the sink + module. */ enum star_feedback_type star_type; }; diff --git a/src/feedback/GEAR/stellar_evolution_struct.h b/src/feedback/GEAR/stellar_evolution_struct.h index b26d7386b33e8c67ac08ebea2d3f72e1d9251600..6671bb6b2736b581a9f3d3e612f00da51dc3e5d3 100644 --- a/src/feedback/GEAR/stellar_evolution_struct.h +++ b/src/feedback/GEAR/stellar_evolution_struct.h @@ -65,7 +65,7 @@ struct initial_mass_function { float sink_Pc; /*! Stellar mass of the continous part of the IMF (in solar mass). */ - float sink_stellar_particle_mass; + float stellar_particle_mass; }; /** diff --git a/src/sink/GEAR/sink.h b/src/sink/GEAR/sink.h index 11e052b2c530905377e536109e1400c9b20b3ed9..5146349efb03d2dbfd4db12ad31168b6ab42a80b 100644 --- a/src/sink/GEAR/sink.h +++ b/src/sink/GEAR/sink.h @@ -62,30 +62,32 @@ INLINE static void sink_update_target_mass(struct sink* sink, const struct feedback_props* feedback_props = e->feedback_props; /* Pick the correct table. (if only one table, threshold is < 0) */ - const float metal = chemistry_get_sink_total_iron_mass_fraction_for_feedback(sink); const float threshold = feedback_props->metallicity_max_first_stars; + /* If metal < threshold, then the sink generates first star particles. */ + const int is_first_star = metal < threshold; const struct stellar_model* model; double minimal_discrete_mass; - if (metal >= threshold) { + /* Take the correct values if your are a first star or not. */ + if (!is_first_star) /* (metal >= threshold)*/ { model = &feedback_props->stellar_model; - minimal_discrete_mass = sink_props->minimal_discrete_mass_first_stars; + minimal_discrete_mass = sink_props->minimal_discrete_mass; } else { model = &feedback_props->stellar_model_first_stars; - minimal_discrete_mass = sink_props->minimal_discrete_mass; + minimal_discrete_mass = sink_props->minimal_discrete_mass_first_stars; } const struct initial_mass_function* imf = &model->imf; if (random_number < imf->sink_Pc) { - // we are dealing with the continous part of the IMF - sink->target_mass = imf->sink_stellar_particle_mass; - sink->target_type = star_population_no_SNII; + /* We are dealing with the continous part of the IMF. */ + sink->target_mass = imf->stellar_particle_mass; + sink->target_type = star_population_continuous_IMF; } else { - // we are dealing with the discrete part of the IMF + /* We are dealing with the discrete part of the IMF. */ random_number = random_unit_interval_part_ID_and_index( sink->id, star_counter + 1, e->ti_current, random_number_sink_formation); @@ -726,14 +728,13 @@ INLINE static void sink_copy_properties_to_star( sp->feedback_data.star_type = (enum star_feedback_type)sink->target_type; /* Initialize the feedback */ - if (sp->feedback_data.star_type == single_star) - feedback_init_after_star_formation(sp, e->feedback_props); + feedback_init_after_star_formation(sp, e->feedback_props, sink->target_type); /* sph smoothing */ sp->h = sink->r_cut; - /* mass at birth */ - sp->sf_data.birth_mass = sp->mass; + /* Note: The sink module need to be compiled with GEAR SF as we store data + in the SF struct. However, we do not need to run with --star-formation */ /* Store either the birth_scale_factor or birth_time depending */ if (with_cosmology) { diff --git a/src/sink/GEAR/sink_properties.h b/src/sink/GEAR/sink_properties.h index f88dae5ab6ec8fe67445105323802c9fa110515f..2667fa2b6ceafec03a1de8dd55e9f3f0f263ded0 100644 --- a/src/sink/GEAR/sink_properties.h +++ b/src/sink/GEAR/sink_properties.h @@ -148,7 +148,7 @@ INLINE static void sink_props_init_probabilities( /* if no continous part, return */ if (Mc == 0) { imf->sink_Pc = 0; - imf->sink_stellar_particle_mass = 0; + imf->stellar_particle_mass = 0; message("probability of the continuous part : %g", 0.); message("probability of the discrete part : %g", 1.); return; @@ -158,7 +158,7 @@ INLINE static void sink_props_init_probabilities( double Pc = 1 / (1 + Nd); double Pd = 1 - Pc; imf->sink_Pc = Pc; - imf->sink_stellar_particle_mass = Mc; + imf->stellar_particle_mass = Mc; message("probability of the continuous part : %g", Pc); message("probability of the discrete part : %g", Pd); diff --git a/src/star_formation/GEAR/star_formation.h b/src/star_formation/GEAR/star_formation.h index f3b39f136eb9fbf2e0d3af19091555b73de9569a..8568c26cd422d060a3d148ee3bb7a810c725fe46 100644 --- a/src/star_formation/GEAR/star_formation.h +++ b/src/star_formation/GEAR/star_formation.h @@ -320,7 +320,7 @@ INLINE static void star_formation_copy_properties( const int convert_part) { /* Initialize the feedback */ - feedback_init_after_star_formation(sp, e->feedback_props); + feedback_init_after_star_formation(sp, e->feedback_props, star_population); /* Store the current mass */ const float mass_gas = hydro_get_mass(p); @@ -367,9 +367,6 @@ INLINE static void star_formation_copy_properties( /* Copy the progenitor id */ sp->sf_data.progenitor_id = p->id; - - /* Feedback type */ - sp->feedback_data.star_type = star_population; } /**