Skip to content

Commit 8ee272c

Browse files
authored
Merge pull request #81 from sirus20x6/feat/cold-giant-metallicity-gate
feat(accrete): metallicity-dependent giant-formation gate (fix cold-giant over-production)
2 parents 094cf6e + b4dcca6 commit 8ee272c

5 files changed

Lines changed: 743 additions & 631 deletions

File tree

accrete.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -885,6 +885,31 @@ auto accrete::dist_planetary_masses(sun &the_sun, long double inner_dust,
885885

886886
// std::cout << planet_inner_bound << " " << planet_outer_bound << std::endl;
887887

888+
// --- Metallicity-dependent giant-formation gate (default-on; see const.h) -----
889+
// Decide ONCE whether this star can form gas giants, from a per-star [Fe/H] draw
890+
// and the observed giant-frequency-metallicity relation. Three fixed draws in a
891+
// fixed order (Box-Muller [Fe/H] = 2 draws, then the acceptance draw) -> no
892+
// rejection loops, serial == parallel byte-identical. If not giant-capable, gas
893+
// runaway is suppressed below (crit_mass made unreachable) so bodies stay cores.
894+
bool giant_capable = true;
895+
{
896+
const long double u1 = random_ctx->randDouble(1.0e-12L, 1.0L); // avoid log(0)
897+
const long double u2 = random_ctx->randDouble(0.0L, 1.0L);
898+
const long double feh =
899+
GIANT_METALLICITY_MEAN +
900+
GIANT_METALLICITY_SIGMA * sqrt(-2.0L * log(u1)) * cos(2.0L * PI * u2);
901+
long double p_giant = GIANT_FORMATION_NORM * stell_mass_ratio *
902+
std::pow(10.0L, GIANT_FORMATION_FEH_SLOPE * feh);
903+
if (stell_mass_ratio > GIANT_FORMATION_MASS_TURNOVER_MSUN) { // steep drop for A-stars
904+
p_giant *= GIANT_FORMATION_MASS_TURNOVER_MSUN / stell_mass_ratio;
905+
}
906+
if (p_giant > GIANT_FORMATION_PROB_CAP) {
907+
p_giant = GIANT_FORMATION_PROB_CAP;
908+
}
909+
const long double u_giant = random_ctx->randDouble(0.0L, 1.0L);
910+
giant_capable = (u_giant < p_giant);
911+
}
912+
888913
// while there's still dust left...
889914
while (dust_left) {
890915
if (seeds != nullptr) {
@@ -952,6 +977,9 @@ auto accrete::dist_planetary_masses(sun &the_sun, long double inner_dust,
952977
dust_density = dust_density_coeff * sqrt(stell_mass_ratio) *
953978
exp(-ALPHA * std::pow(a, 1.0 / NDENSITY));
954979
crit_mass = critical_limit(a, e, stell_luminosity_ratio);
980+
if (!giant_capable) {
981+
crit_mass = INCREDIBLY_LARGE_NUMBER; // metallicity gate: suppress gas runaway -> rocky/ice core
982+
}
955983
if (total_mass == PROTOPLANET_MASS && is_seed == false) {
956984
// std::cout << "test1\n";
957985
// std::cout << total_mass << " " << dust_mass << " " << gas_mass << " " << a
@@ -1009,6 +1037,9 @@ auto accrete::dist_planetary_masses(sun &the_sun, long double inner_dust,
10091037
r_inner = inner_effect_limit(a, e, reduced_mass);
10101038
r_outer = outer_effect_limit(a, e, reduced_mass);
10111039
crit_mass = critical_limit(a, e, stell_luminosity_ratio);
1040+
if (!giant_capable) {
1041+
crit_mass = INCREDIBLY_LARGE_NUMBER; // metallicity gate: suppress gas runaway -> rocky/ice core
1042+
}
10121043
if (planet_inner_bound > a) {
10131044
planet_inner_bound = a;
10141045
}

const.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,29 @@ constexpr double MIGRATION_MIN_MASS_MJUP = 0.1; // only bodies > 0.1 M_Jup m
201201
constexpr double MIGRATION_GAP_MASS_MJUP = 0.5; // Type II gap-opening threshold (per M_star)
202202
constexpr double MIGRATION_TYPE1_NORM_YR = 1.1E5; // Tanaka 2002 Type I normalization (yr)
203203
constexpr double MIGRATION_TYPE2_NORM_YR = 7.0E5; // Type II viscous normalization at 1 AU (yr)
204-
constexpr double MIGRATION_EFFICIENCY = 0.0001; // overall rate multiplier (primary calibration knob)
204+
constexpr double MIGRATION_EFFICIENCY = 0.0005; // overall rate multiplier (primary calibration knob)
205205
constexpr double MIGRATION_INNER_EDGE_AU = 0.05; // inner trap a_stop (disk edge / cavity)
206206
constexpr double MIGRATION_CIRC_AU = 0.05; // tidal circularization locus (hot -> e=0)
207207
constexpr double GIANT_ECC_SIGMA = 0.215; // Rayleigh sigma -> <e>~0.27 for cold giants
208208
constexpr double GIANT_ECC_MAX = 0.80; // eccentricity cap
209209

210+
/* Metallicity-dependent giant-formation gate (default-on). StarGen's accretion
211+
* forms a gas giant in ~84% of systems (crit_mass is low everywhere); the observed
212+
* giant frequency is ~10-20% and rises steeply with stellar [Fe/H]. We draw a
213+
* per-star [Fe/H] ~ N(mean,sigma) -- solar-neighborhood FGK metallicity distribution
214+
* is ~Gaussian, mean ~0, sigma ~0.20 dex (Casagrande 2011; Nordstrom 2004) -- and
215+
* accept the star as giant-capable with probability
216+
* P = NORM * (Mstar/Msun) * 10^(SLOPE*[Fe/H]) (Fischer & Valenti 2005 slope ~2.0),
217+
* NORM calibrated so the population integrates to ~10-20% (closed form
218+
* <P> = NORM*10^(SLOPE*mean)*exp((SLOPE*ln10)^2*sigma^2/2)). A non-giant-capable
219+
* star has gas runaway suppressed (crit_mass made unreachable) -> rocky/ice cores. */
220+
constexpr double GIANT_METALLICITY_MEAN = 0.0; // dex (solar-centered FGK MDF)
221+
constexpr double GIANT_METALLICITY_SIGMA = 0.20; // dex (Casagrande 2011 / Nordstrom 2004)
222+
constexpr double GIANT_FORMATION_NORM = 0.10; // calibration knob (-> ~12% integrated)
223+
constexpr double GIANT_FORMATION_FEH_SLOPE = 2.0; // Fischer & Valenti 2005
224+
constexpr double GIANT_FORMATION_PROB_CAP = 0.90; // cap (relation validated to [Fe/H]~+0.5)
225+
constexpr double GIANT_FORMATION_MASS_TURNOVER_MSUN = 2.0; // occurrence drops above ~2 Msun (Reffert 2015)
226+
210227
// SI-unit physical constants used by the enviro.cpp acceleration helpers. These
211228
// are the EXACT values those functions previously redefined locally, kept
212229
// verbatim so generated output stays byte-identical. They intentionally differ

0 commit comments

Comments
 (0)