API Reference — gcm3d¶
Reusable imports live under src.framework.gcm and src.framework.physics.
Mars forcing, maps, datasets, and seasonal components live under
src.celestials.planets.mars. There is no top-level src.gcm3d package.
BodyConstants/EARTH are always available; dynamics and physics kernels require
the gcm3d extra. Dataset adapters may require xarray or the arco extra.
The entries below summarize interfaces; full signatures are available in source.
Body abstraction — body.py¶
BodyConstants¶
Purpose: frozen SI constants a planet/moon supplies to the dry dynamical core.
Location: package/src/framework/gcm/body.py
| Field | Type | Description |
|---|---|---|
name |
str | Body name |
radius_m |
float | Mean radius (m) |
gravity_m_s2 |
float | Surface gravity (m s⁻²) |
rotation_period_s |
float | Sidereal rotation period (s) → Ω |
gas_constant_j_kg_k |
float | Specific gas constant R = R_univ/M |
cp_j_kg_k |
float | Isobaric heat capacity (sets κ = R/cp) |
reference_temperature_k |
float | Semi-implicit linearisation anchor (default 250) |
reference_surface_pressure_pa |
float | Reference p_s |
Properties: angular_velocity_s (2π/period), kappa (R/cp), surface_area_m2
(4πR²). Validates all quantities positive in __post_init__. EARTH is a
standard dry-air instance used to prove the core is planet-agnostic in tests.
Discretisation — coordinates.py, specs.py¶
grid(truncation="T42") -> spherical_harmonic.Grid¶
Named triangular truncations: T21(64×32), T31, T42(default), T85, T106, T170.
coordinate_system(truncation="T42", n_layers=25) -> CoordinateSystem¶
Spectral grid × n_layers equidistant terrain-following sigma (p/pₛ) levels.
physics_specs(body) -> units.SimUnits¶
Body-anchored dinosaur SimUnits; Raises if the body's radius ≠ 1 under the scale.
nondimensionalization_scale(body) -> scales.Scale¶
Length = radius, time = 1/(2Ω), mass = 1 kg, temperature = 1 K.
Dry dynamics — dynamics.py¶
primitive_equations(coords, body, specs=None, orography=None) -> PrimitiveEquationsSigma— dryImplicitExplicitODE; flat orography by default.reference_temperature(coords, body) -> np.ndarray[n_layers]— constant linearisation profile (nondimensional).stepper(equation, dt_seconds, specs, *, coords=None, hyperdiffusion_tau_seconds=None) -> step_fn— semi-implicit IMEX-RK-SIL3; nondimensionalisesdt. Optional eighth-order wind/temperature damping requirescoords; it leaves pressure, tracers and surface reservoirs untouched.integrate(step_fn, state, n_steps) -> state—jax.lax.scanrollout; differentiable. RaisesValueErrorifn_steps < 1.
Column physics — framework/physics/gcm.py¶
RadiativeForcing (dataclass) / Mars radiative_forcing(...) -> RadiativeForcing¶
Radiative + orbital + surface-scheme constants for the per-column energy balance.
src.celestials.planets.mars.gcm.radiative_forcing supplies Mars's
obliquity/precession/orbit/emissivity/thermal-inertia. Key toggles: diurnal, co2_radiation_enabled,
ames_correlated_k_enabled (default True, used only with resolved radiation), regolith_enabled,
stability_exchange_enabled, pbl_diffusion_enabled,
convective_adjustment_enabled, dust fields (dust_visible_optical_depth,
dust_longwave_optical_depth, dust_top_height_km, dust_conrath_parameter).
The advanced surface flags and co2_radiation_enabled default to False in the
generic forcing. Use dataclasses.replace for fields outside the Mars factory's
arguments. Calibration fields are ames_co2_longwave_opacity_scale,
ames_dust_longwave_opacity_scale and surface_exchange_multiplier (all 1.0).
solar_slant_path_enabled=True applies solar air-mass correction. Seasonal dust
uses dust_climatology_ls_deg, dust_visible_climatology and
dust_longwave_climatology. See configuration examples.
CO2Forcing (dataclass) / Mars co2_forcing(...) -> CO2Forcing¶
Constants for the 3-D CO₂ condensation/sublimation cycle. energy_limited=True
drives phase change off the surface-energy residual (no tunable relaxation rate);
use_pressure_frost uses the Clausius–Clapeyron frost point; escape_rate_kg_s
is a uniform non-thermal mass sink.
The Mars factory defaults to energy_limited=True; the generic dataclass defaults
to False. These defaults are distinct.
State & tendency containers¶
ColumnPhysicsState(dynamics, surface_temperature, co2_ice, ground_temperature)— JAX pytree.ColumnPhysicsTendencies(vorticity, divergence, temperature_variation, log_surface_pressure, surface_temperature, co2_ice, ground_temperature, tracers).SurfaceEnergyDiagnostics,RadiativeFluxDiagnostics— NamedTuples of diagnostic fields.
Equation builders¶
forced_primitive_equations(coords, body, forcing, specs=None, orography=None) -> ImplicitExplicitODE— dry dynamics + radiative energy balance.forced_co2_primitive_equations(coords, body, forcing, co2_forcing, specs=None, orography=None) -> ImplicitExplicitODE— the above + CO₂ cycle.column_primitive_equations(base, parameterization) -> ImplicitExplicitODE— the generic dynamics⊕physics seam (conventional or learned).compose_column_parameterizations(*parameterizations)— sum matching tendency trees.- Both forced equation builders accept
radiation_component=Noneandneural_tendency=None; these bind replacement radiation and additive heating. initial_column_state(dyn_state, coords, surface_temperature_k, specs, ice_pa=0.0, forcing=None) -> ColumnPhysicsState— pass the run'sRadiativeForcingwhen using a custom regolith layer layout.
Physics functions¶
two_stream_radiative_fluxes(state, coords, specs, body, f, *, air_temperature_k=None, surface_pressure_pa=None) -> RadiativeFluxDiagnostics.surface_energy_tendencies(state, coords, specs, body, f, …) -> (atm_modal, surface_nd, diagnostics).radiative_heating_tendency(state, coords, specs, body, f)— atmospheric-only accessor; requires aColumnPhysicsState.project_co2_reservoirs(state, coords, specs)— repair frost while balancing the local pressure deficit.positivity_preserving_co2_step(step_fn, coords, specs, *, body=None, co2_forcing=None, dt_seconds=None, external_co2_mass_change_kg=None, return_diagnostics=False)— restore global CO₂ inventory including declared external CO₂ changes, less configured escape.bodyand positive finitedt_secondsare required for external sources/sinks or nonzero escape.
external_co2_mass_change_kg(state_before, dt_seconds) is a pure JAX-compatible
callback returning one global scalar mass for the whole step, in kg, with
positive injection and negative removal. It excludes the already-configured
escape. The underlying step must apply the physical source/sink and its
thermal/momentum effects; declaring the budget does not inject it again. Derive
schedules from the persisted simulation clock (Dinosaur sim_time is
nondimensional), not Python counters, so restarts retain the same schedule.
Setting return_diagnostics=True requires body and returns
(state, CO2ProjectionDiagnostics) from each step. Diagnostics contain SI raw,
target and corrected total masses, declared external/escape amounts, negative
frost transfers, global atmospheric rescale, pressure factor and inventory
validity. Accumulate these explicitly in a scan or experiment ledger; the default
state-only return remains compatible with integrate. Impossible/non-finite
targets return non-finite pressure and a false validity flag instead of silently
creating a minimum positive atmosphere. Host runners must reject such states.
This interface supports CO₂ bookkeeping, not arbitrary gas mixtures or particle loading. Numerical repair masses are not physical sources, and their diagnostics do not establish energy/momentum closure. Full experiment-ledger persistence and mixture thermodynamics remain separate work.
Orbit / geometry helpers¶
cos_zenith_nodal(t_s, lat_rad, lon_rad, f)— cos(zenith) on the(n_lon, n_lat)grid; diurnal terminator or daily-mean.orbital_distance(t_s, f),mean_anomaly_for_ls(ls_rad, f),co2_frost_point_k(pressure_pa).
Correlated-k radiation — framework/physics/ames_radiation.py¶
load_ames_co2_tables()/load_ames_co2_tables_jax()— the bundled 12-band correlated-k asset.correlated_k_optical_depths(temperature_k, pressure_mid_pa, delta_pressure_pa) -> (sw_tau, lw_tau).channel_weights(clear_fraction),planck_band_fractions(temperature_k).- Fixed-dust optics constants:
DUST_SW_EXTINCTION,DUST_IR_EXTINCTION, etc. (Reff=1.5 µm).
3-D maps — maps.py¶
run_maps(body=None, truncation="T42", n_layers=25, dt_seconds=600.0, n_steps=200, ..., forcing=None, co2_forcing=None, initial_state=None, return_final_state=False, hyperdiffusion_tau_seconds="auto", radiation_component=None, neural_tendency=None)returnsMarsMapFieldsor(fields, final_state). These options are not keyword-only in the current API.MarsMapFields— lat/lon fields (surface_pressure_pa,temperature_k,u_ms,v_ms,co2_ice_pa,elevation_m) + provenance; propertieswind_speed_ms,duration_sols,is_transient,approximate_wind_height_m.save_netcdf(fields, path),plot_maps(fields, outdir, prefix="mars"),save_maps(fields, outdir, prefix="mars").- Scale presets:
MAP_SCALES(fast/balanced/high/ultra),DEFAULT_SCALE,resolve_scale(name). forcing_with_surface_properties,forcing_with_ames_dustandforcing_with_ames_dust_climatologyattach boundary data. The climatology helper retains separate visible/IR fields throughout evolving seasons.state_to_comparison_datasetandsave_comparison_netcdfexport full-state comparison fields, coordinates and forcing provenance.
Map metadata includes temperature_kind, insolation_sampling and solar
longitude; full-state comparison exports also retain forcing controls.
Map output also records the resolved hyperdiffusion_tau_seconds and Laplacian
order. Automatic damping uses 0.1 rotations at T42, scaled by 42/truncation;
pass a positive time in seconds to override it or None to disable it.
Forced temperature maps are surface temperature;
dry maps are lowest-layer air temperature. Lowest-layer winds are not fixed-height
10 m diagnostics. is_transient is a duration heuristic, not equilibrium acceptance.
Raises: ValueError for a diurnal timestep coarser than the terminator CFL; FloatingPointError if the state becomes non-finite.
0-D seasonal ODE — celestials/planets/mars/seasonal.py¶
SeasonalForcing(dataclass),initial_seasonal_state(T, P, ice_north, ice_south, t0_s=0.0).seasonal_tendency(y, f),seasonal_ode(f),solar_flux(t, f),solar_longitude(t, f).run_seasonal(f, y0, dt_seconds, n_steps, sample_every=1) -> SeasonalTrajectory— Raises ifdt_seconds > rotation_period/8(diurnal aliasing) or bad sampling.SeasonalTrajectory— Ls-indexed arrays;.write_csv(path)matches the torch Mars exports.
Restart / averaging — restart.py¶
RESTART_FORMAT_VERSION,save_restart(state, path),load_restart(path)— NPZ+JSON, version-checked, no pickle.integrate_with_averaging(step_fn, initial_state, spinup_steps, average_steps, sample_every=1, diagnostic_fn=…) -> (final, time_mean).
Keep the associated grid, forcing, units, diffusion and precision configuration with the restart; serialization stores state rather than experiment settings.
Parameterized integration and neural interfaces¶
make_parameterized_step(equation_fn, dt_seconds, specs)fromframework.gcm.learningcreatesstep(params, state).rollout(step_fn, params, initial_state, n_steps, save_every=None, *, remat=False)returns final state, sampled trajectory and step indices.framework.neuralprovidesColumnMLP,NeuralRadiation,NeuralTendency, train-only normalization and NPZ inference checkpoint helpers.
See neural experiments for shape, feature, flux and checkpoint contracts, and temperature-only for the separate cached postprocessing workflow.
Topography — topography.py¶
load_mola_meg(path=None) -> (elevation_m, lats_deg, lons_deg)— SHA-256-verified MEGDR raster.regrid_to_nodal(coords, elevation_m=None, mola_path=None),mola_modal_orography(coords, specs, …).
Benchmarks — benchmarks.py¶
Dycore acceptance + conservation diagnostics: run_resting_atmosphere,
run_solid_body_tracer, run_balanced_jet, run_held_suarez,
dry_conserved_quantities, conservation_drift, dry_drift_diagnostics,
resting_convergence_matrix, and their *Diagnostics dataclasses.
MCD validation client — mcd.py¶
query_url, fetch_ascii, parse_ascii, interpolate_periodic,
weighted_metrics — fetch Mars Climate Database v6.1 reference maps and compute
area-weighted bias/RMSE/correlation against a gcm3d run.