Skip to content

ZEPHYRUS in PROTEUS

This page describes how ZEPHYRUS is wired into the PROTEUS framework as its atmospheric scape module. The source code for this coupling can be found in the wrapper. For the underlying ZEPHYRUS model itself, see the model overview. For the standalone API, see the API reference.


Selecting an escape module

PROTEUS exposes four escape backends, selected by config.escape.module:

module Behaviour
"none" Escape disabled. Bulk rate is set to zero and per-element rates are zeroed.
"dummy" Fixed user-specified bulk rate from config.escape.dummy.rate. Always unfractionating.
"zephyrus" Calls zephyrus.escape.EL_escape. Always unfractionating.
"boreas" Calls the separate BOREAS module (no longer actively used).

Any other value raises ValueError at the top of proteus.escape.wrapper.run_escape.


Configuring the ZEPHYRUS module

The PROTEUS configuration block for ZEPHYRUS lives under [escape] and [escape.zephyrus] in the input config file:

[escape]
    module     = "zephyrus"         # Which escape module to use
    reservoir  = "outgas"           # Reservoir that sets escaping composition

    [escape.zephyrus]
        Pxuv        = 5e-5          # Pressure where the atmosphere becomes XUV-opaque [bar]
        efficiency  = 0.1           # Escape efficiency factor (epsilon)
        tidal       = false         # Include tidal correction K_tide?
Key Type Units Description
escape.module str – Must be "zephyrus" to enable this backend.
escape.reservoir str – Which volatile inventory the escape rate is distributed over. See Reservoir below.
escape.zephyrus.Pxuv float bar Reference pressure at which the atmosphere is taken to become optically thick to XUV photons; used by the atmosphere module (AGNI/JANUS) to compute the corresponding \(R_\mathrm{XUV}\).
escape.zephyrus.efficiency float – Energy-limited escape efficiency \(\epsilon\).
escape.zephyrus.tidal bool – If true, include the tidal correction \(K_\mathrm{tide}\) in EL_escape.

scaling=3 is hard-coded

The PROTEUS wrapper always calls EL_escape with scaling=3, i.e. the \(R_\mathrm{XUV}^3\) form. This is not exposed as a config option. Standalone users of EL_escape can choose scaling=2 (the function default, \(R_p R_\mathrm{XUV}^2\)).


At each PROTEUS time step

flowchart TD
    Start([<b>Start of escape step</b>])

    Pull1["Pull <b>planetary state</b> from <code>hf_row</code><br/>(<code>semimajorax</code>, <code>eccentricity</code>, <code>M_planet</code>,<br/><code>R_int</code>, <code>R_xuv</code>, <code>F_xuv</code>)"]
    Pull2["Pull <b>config</b><br/>(tidal, efficiency, star mass)"]

    Call["Call <b><code>EL_escape</code></b> with scaling=3"]

    Store["1. Store <code>esc_rate_total</code> in <code>hf_row</code><br/>2. Set <code>p_xuv</code> from config<br/>3. Reset <code>R_xuv</code> to 0.0"]

    Distribute["<b><code>calc_unfract_fluxes</code></b><br/>distributes bulk rate across elements by mass mixing ratio"]

    Integrate["<b><code>calc_new_elements</code></b><br/>for each element except oxygen"]

    SkipO["Oxygen skipped<br/>(set by <code>fO2</code>)"]

    Threshold{"Updated inventory<br/>below threshold?"}

    Zero["Set inventory to 0"]
    Keep["Write updated inventory<br/>to <code>{e}_kg_total</code> in <code>hf_row</code>"]

    Done([<b>End of escape step</b>])

    Start --> Pull1
    Start --> Pull2
    Pull1 --> Call
    Pull2 --> Call
    Call --> Store
    Store --> Distribute
    Distribute --> Integrate
    Integrate -.-> SkipO
    Integrate --> Threshold
    Threshold -->|yes| Zero
    Threshold -->|no| Keep
    Zero --> Done
    Keep --> Done

The wrapper logs the bulk rate and each non-zero elemental rate to the PROTEUS log.

fO2

Oxygen is excluded from the loss calculation regardless of reservoir: the wrapper preserves it because it is set by the prescribed mantle redox state (outgas.fO2_shift_IW).


Reservoir

config.escape.reservoir selects which set of inventories defines the elemental mass mixing ratios used to partition the bulk escape rate. The match statement in calc_new_elements recognises three values:

reservoir Description
"bulk" Mass mixing ratios computed from whole-planet elemental inventories.
"outgas" Mass mixing ratios computed from outgassed atmospheric elemental inventories only.
"pxuv" Reserved for fractionation at the XUV-opaque pressure level. Currently raises ValueError: Fractionation at p_xuv is not yet supported.

Any other string raises ValueError.

After the loss step, inventories that fall below config.outgas.mass_thresh are zeroed out.


Helpfile fields written by ZEPHYRUS

The wrapper writes the following keys into hf_row at each step:

Field Units Source
esc_rate_total kg s\(^{-1}\) Return value of EL_escape
esc_rate_{e} kg s\(^{-1}\) One per element in element_list, set by calc_unfract_fluxes
p_xuv bar Copied from config.escape.zephyrus.Pxuv
R_xuv m Reset to 0.0; re-populated by the atmosphere module
{e}_kg_total kg Updated by calc_new_elements after time-integrating the loss over dt

Termination on atmosphere loss

PROTEUS can be configured to terminate a run when the surface pressure drops below a threshold, regardless of which escape module is in use:

[params.stop.escape]
    enabled = true
    p_stop  = 5.0       # Stop when surface pressure drops below this value [bar]

This works the same way for ZEPHYRUS, dummy, and BOREAS backends.


Caveats

Unit handling at the wrapper boundary

PROTEUS feeds EL_escape stellar mass in kilograms directly from config.star.mass, which sidesteps the units footgun that standalone callers can hit (see the first-run tutorial). If you bypass the wrapper and call EL_escape yourself with PROTEUS-style inputs, replicate this convention.

Fractionation is not supported by ZEPHYRUS

ZEPHYRUS is always unfractionating: the bulk rate is partitioned by mass mixing ratio in the chosen reservoir, but light and heavy elements are not preferentially separated in the outflow. This feature will be implemented in the future.