Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new “boundary” interior option (0D parameterised mantle evolution) and wires it into the PROTEUS coupler/interior wrapper, alongside a broad set of example/config updates intended to exercise updated stellar-spectrum and condensation settings.
Changes:
- Introduces
src/proteus/interior/boundary.pyand addsinterior.module = "boundary"support in the interior wrapper/config. - Adjusts atmosphere wrapper logic so
T_surfcan be driven by the boundary interior module. - Updates many example planet/demo/CHILI/ensemble TOMLs (stellar spectrum fields, condensation/rainout naming, and various parameter tweaks).
Reviewed changes
Copilot reviewed 35 out of 35 changed files in this pull request and generated 24 comments.
Show a summary per file
| File | Description |
|---|---|
| src/proteus/proteus.py | Adds boundary-specific first-loop initialization/outgassing before interior evolution. |
| src/proteus/interior/wrapper.py | Adds boundary module routing, structure-handling special cases, and atmos_o parameter. |
| src/proteus/interior/boundary.py | New boundary-layer interior evolution implementation (ODE integration + diagnostics). |
| src/proteus/config/_interior.py | Adds InteriorBoundary config section and extends interior.module allowed values. |
| src/proteus/atmos_clim/wrapper.py | Skips T_surf update when boundary interior is responsible for surface temperature. |
| src/proteus/atmos_clim/dummy.py | Uses hf_row["T_surf"] for dummy atmosphere when boundary interior is enabled. |
| input/planets/trappist1c.toml | Updates stellar spectrum settings and AGNI options. |
| input/planets/toi6255.toml | Updates stellar spectrum settings. |
| input/planets/l9859d.toml | Updates stellar spectrum settings and AGNI condensation/rainout option naming. |
| input/planets/l9859c.toml | Updates stellar spectrum settings and AGNI condensation/rainout option naming. |
| input/planets/l9859b.toml | Updates stellar spectrum settings and AGNI condensation/rainout option naming. |
| input/planets/hd63433d.toml | Updates stellar spectrum settings and AGNI condensation/rainout option naming. |
| input/planets/gj9827d.toml | Updates stellar spectrum settings and AGNI condensation/rainout option naming. |
| input/planets/fiducial_sub_Neptune.toml | Updates stellar spectrum settings, AGNI condensation/rainout naming, and other parameters. |
| input/planets/earth.toml | Updates timestep params and changes stellar spectrum + AGNI condensation/rainout naming. |
| input/planets/GDSP_fiducial.toml | Adds a new fiducial planet config used by new ensemble grids. |
| input/minimal.toml | Updates minimal config stellar spectrum field. |
| input/ensembles/stellar_spectra_test_mors.toml | Adds a new ensemble config intended to sweep stellar spectra for MORS. |
| input/ensembles/stellar_spectra_test_bb.toml | Adds a new ensemble config sweeping dummy-star Teff (blackbody-like). |
| input/ensembles/solubility_test.toml | Adds a new outgassing solubility toggle ensemble. |
| input/ensembles/ocean_formation_grid.toml | Adds a new ensemble config for initial-inventory sweeps. |
| input/ensembles/example.infer.toml | Updates example inference settings/targets and BO hyperparameters. |
| input/ensembles/boundary_interior_test.toml | Adds a new ensemble config intended to exercise the boundary interior with dummy atmosphere. |
| input/ensembles/SNS_0.5%_sweep.toml | Adds a new ensemble config for parameter sweeps. |
| input/ensembles/SNS_0.5%_sanity_check.toml | Adds a new ensemble config for sanity checks across instellation. |
| input/ensembles/GDSP_initial_grid_2.toml | Adds another GDSP initial grid ensemble config. |
| input/demos/sat_physical.toml | Updates AGNI condensation/rainout option naming. |
| input/demos/escape.toml | Updates stellar spectrum field and AGNI condensation/rainout option naming. |
| input/demos/aragog.toml | Updates AGNI condensation/rainout option naming. |
| input/chili/readme.md | Removes an outdated CHILI GitHub link line. |
| input/chili/protocol/tr1b.toml | Updates stellar spectrum field and AGNI condensation/rainout option naming; adds several extra tables. |
| input/chili/protocol/earth.toml | Updates stellar spectrum field and AGNI condensation/rainout option naming; adds several extra tables. |
| input/chili/intercomp/_base.toml | Updates stellar spectrum field, AGNI condensation/rainout naming, and several parameter defaults. |
| input/chili/intercomp/_base.grid.toml | Updates grid settings and sampled values for CHILI intercomparison runs. |
| input/all_options.toml | Adds an [interior.boundary] example block and tweaks various comment/option defaults. |
| solution_rtol = 1e-1 # solver relative tolerance | ||
| overlap_method = "ee" # gas overlap method | ||
| rainout = true # volatile condensation | ||
| condensation = true # volatile condensation |
| solution_rtol = 0.13 | ||
| overlap_method = "ee" | ||
| rainout = false | ||
| condensation = false |
| # Set up CSV logging for step diagnostics. | ||
| output_dir = dirs.get('output', '.') | ||
| csv_log_file = f"{output_dir}/boundary_solver_debug.csv" | ||
| self._run_solver_call_count = self.iteration |
| phi = self.melt_fraction(T_p) | ||
| q_m_val = self.q_m(T_p, T_surf, phi) | ||
|
|
||
| delta = self.thermal_conductivity * (T_p - T_surf) / q_m_val | ||
|
|
||
| numerator = 4 * np.pi * self.planet_radius**2 * (q_m_val - self.f_atm) | ||
| denominator = self.atmosphere_heat_capacity * self.m_atm + \ | ||
| (4/3) * np.pi * self.silicate_heat_capacity * self.bulk_density * (self.planet_radius**3 - (self.planet_radius-delta)**3) | ||
|
|
| class BoundaryRunner(): | ||
|
|
||
| def __init__(self, config: Config, dirs: dict, hf_row: dict, hf_all: | ||
| pd.DataFrame, interior_o: Interior_t, atmos_o: Atmos_t): | ||
|
|
||
| self.curr_time = hf_row["Time"] * secs_per_year | ||
| self.dt = self.compute_time_step(config, dirs, hf_row, hf_all, interior_o) * secs_per_year | ||
| self.iteration = 1 if hf_all is None else len(hf_all) | ||
|
|
||
| self.planet_radius = hf_row["R_int"] | ||
| self.planet_mass = config.struct.mass_tot * M_earth | ||
| self.core_mass = hf_row["M_core"] | ||
| self.m_atm = hf_row["M_atm"] | ||
| self.f_atm = hf_row["F_atm"] | ||
|
|
||
| cp_layer = getattr(getattr(atmos_o, "_atm", None), "layer_cp", None) | ||
| if cp_layer is not None and len(cp_layer) > 2 and not pd.isna(cp_layer[2]): | ||
| self.atmosphere_heat_capacity = cp_layer[2] # J/kg/K | ||
| else: | ||
| self.atmosphere_heat_capacity = 1.7e4 # J/kg/K for H2 at 2000K | ||
|
|
||
| self.core_radius = config.struct.corefrac * self.planet_radius | ||
|
|
||
| self.mantle_radius = self.planet_radius - self.core_radius | ||
| self.mantle_volume = (4/3) * np.pi * (self.planet_radius**3 - self.core_radius**3) | ||
| self.mantle_mass = (self.planet_mass - self.core_mass) | ||
| self.bulk_density = self.mantle_mass / self.mantle_volume | ||
|
|
| symlink = "" | ||
|
|
||
| # Path to base (reference) config file relative to PROTEUS root folder | ||
| ref_config = "input/planets/nogit_fiducial_sub_Neptune_MORS.toml" |
| else: | ||
| # *** will change this once interior module works with zalmoxis *** | ||
| hf_row["R_int"] = R_earth | ||
| hf_row["M_tot"] = M_target | ||
| calculate_core_mass(hf_row, config) | ||
| hf_row["gravity"] = 9.81 |
| K_term = self.K_abun * K_heat_production * np.exp( | ||
| K_decay_constant * (self.radio_tref * secs_per_year - t) | ||
| ) | ||
| Ur_term = self.U_abun * Ur_heat_production * np.exp( | ||
| Ur_decay_constant * (self.radio_tref * secs_per_year - t) | ||
| ) | ||
| Th_term = self.Th_abun * Th_heat_production * np.exp( | ||
| Th_decay_constant * (self.radio_tref * secs_per_year - t) | ||
| ) |
| "F_int": q_m_final, | ||
| "Phi_global": phi_final, | ||
| "Phi_global_vol": phi_final, | ||
| "F_radio": f_radio_final/(4*np.pi*self.planet_radius**2), | ||
| "RF_depth": r_s_final/self.planet_radius, |
| age_now = 4.567 # Current age of star used for scaling [Gyr] | ||
| star_name = "sun" | ||
| spectrum_source = "solar" | ||
| spec = "stellar_spectra/Named/sun.txt" # Stellar spectrum |
Codecov Report❌ Patch coverage is ❌ Your patch check has failed because the patch coverage (14.13%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #668 +/- ##
==========================================
- Coverage 69.12% 68.07% -1.05%
==========================================
Files 98 99 +1
Lines 10214 10469 +255
Branches 1422 1448 +26
==========================================
+ Hits 7060 7127 +67
- Misses 2814 3025 +211
+ Partials 340 317 -23
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
As mentioned earlier today, @rdc49, one potential option to avoid taking too-large timesteps is to incorporate 'callback' events. We already do this in SPIDER and Aragog, where the time-integration of the interior is stopped prematurely if the You can do this with https://docs.scipy.org/doc/scipy/reference/generated/scipy.integrate.solve_ivp.html |
This pull request is for the current iteration of the boundary interior module. This is a 0D, parameterised mantle evolution model, based on the model in Schaefer et. al. (2016). The key differences between this model and the Schaefer model are as follows:
-The viscosity treatment from Bower et. al. (2018) is used instead of that in the Schaefer paper.
-The radius of solidification (r_s) and rate of change of r_s are determined analytically assuming r_s is simply a function of the melt fraction.
-The second term on the LHS of equation 14 is corrected to use the heat capacity of the boundary layer (r_p^3-(r_-delta)^3).
The module currently works with the dummy atmosphere module (without radiogenic heating). The main issue it has when trying to operate alongside AGNI is time-stepping: large atmospheric fluxes result in too steep a decrease in surface temperature for a given time step. In theory, this could be overcome by playing with the adaptive time-stepping parameters, but this is fiddly, and results in the model taking a very long time to run.
I also need to update the module to work alongside Zalmoxis: currently the mass and radius need to be passed manually.