zephyrus.profiles
profiles
profiles.py
Atmosphere-profile container, interpolation, and escape working levels.
Author: Mara Attia
Profile(p, r, T, vmr, mmw, kzz=None)
dataclass
One-dimensional atmosphere profile, ordered base to top.
Attributes:
| Name | Type | Description |
|---|---|---|
p |
ndarray
|
Pressure per level [Pa], strictly decreasing with index. |
r |
ndarray
|
Radius per level [m], strictly increasing with index. |
T |
ndarray
|
Temperature per level [K]; realistic profiles are non-monotone. |
vmr |
dict
|
Species name to an array of volume mixing ratios per level. |
mmw |
ndarray
|
Mean molecular mass per level [kg per particle]. |
kzz |
ndarray or None
|
Eddy diffusion coefficient per level [m^2 s^-1], optional. |
validate()
Raise ValueError on a malformed profile.
Pressure must decrease and radius increase strictly with index; temperature is unconstrained beyond positivity. Every mixing-ratio array must share the level count, be finite, and be non-negative, and so must the eddy diffusion column when one is supplied.
Finiteness is checked before the sign comparisons, since a NaN passes
every comparison. Mixing ratios below zero by less than
VMR_NOISE_FLOOR are solver noise and pass.
Source code in src/zephyrus/profiles.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | |
isothermal_profile(M_p, R_p, T, composition, p_surf, p_top, n_levels=120)
Isothermal hydrostatic profile for a fixed molecular composition.
Integrates dr = -(k T r^2 / (G M mu)) d ln p outward from R_p at
constant temperature and composition. The integration truncates, before
reaching p_top, at the level where the local Jeans parameter
G M mu / (k T r) drops below 2.2, because an isothermal structure is
unbound beyond that point and a hydrostatic profile there would be
meaningless.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
M_p
|
float
|
Planet mass [kg] and base radius [m]. |
required |
R_p
|
float
|
Planet mass [kg] and base radius [m]. |
required |
T
|
float
|
Temperature [K]. |
required |
composition
|
dict
|
Species name to mole fraction (renormalized internally). |
required |
p_surf
|
float
|
Base and requested top pressure [Pa]. |
required |
p_top
|
float
|
Base and requested top pressure [Pa]. |
required |
n_levels
|
int
|
Number of levels in log pressure. |
120
|
Returns:
| Type | Description |
|---|---|
Profile
|
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If the structure is unbound at the surface (fewer than three bound levels), which is not a physically posed hydrostatic input. |
Source code in src/zephyrus/profiles.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | |
interp_at_pressure(profile, p_target)
Level state interpolated at a target pressure, linear in log pressure.
Returns a dict with the interpolated radius r [m], temperature T
[K], mean molecular mass mmw [kg], number density n [m^-3], mass
density rho [kg m^-3], per-species vmr, kzz (or None), and
the pressure p [Pa] itself.
Source code in src/zephyrus/profiles.py
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 | |
pressure_at_radius(profile, r_target)
Pressure interpolated at a target radius, log-linear in pressure.
Returns (p, covered). Outside the covered radius range the pressure
clamps to the nearest endpoint and covered is False, so a caller can
tell an interpolated level from a clamped one rather than receiving an
endpoint that looks like a solution.
Source code in src/zephyrus/profiles.py
199 200 201 202 203 204 205 206 207 208 209 210 | |
photospheric_level(profile, p_photo=2000.0)
The photospheric working level for the energy-limited geometric factor.
The level is placed at p_photo (default 20 mbar, the
optical-photosphere-type level of Baumeister et al. 2023, A&A 675,
A122). When the profile does not span that pressure, the nearest end
level is used and the photo_clamped flag raised.
Returns:
| Type | Description |
|---|---|
(level, flags)
|
The interpolated level dict and a flags dict. |
Source code in src/zephyrus/profiles.py
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
lopez_base_pressure(mu_kg, g)
Lopez (2017) XUV wind-base pressure, in Pa.
P_base = mu g / sigma_nu0 with the Murray-Clay et al. (2009)
photoionization cross section at 20 eV, about a nanobar for a hot
Jupiter: the pressure of the tau = 1 level for XUV photons, where the
heating is deposited and the wind is launched (Lopez 2017, MNRAS 472,
245, their Section 2). mu_kg is the local mean particle mass [kg]
and g the local gravity [m s^-2].
Source code in src/zephyrus/profiles.py
233 234 235 236 237 238 239 240 241 242 243 | |
wind_base_level(profile, M_p, method='lopez', fixed_pressure=5.0, boreas_scalars=None)
Locate the XUV wind base on the profile.
Three methods:
'lopez'(default): fixed-point iteration of the Lopez (2017) base pressureP_base = mu(P) g(r(P)) / sigma_nu0on the profile (two to four passes converge). When the physical base pressure lies above the profile top (P_base < p_top), the level clamps to the topmost level, thebase_clampedflag is raised, and the clamp distance in pressure decades is recorded; callers wanting the base on an extended upper structure evaluate it there instead. A base below the profile bottom, on an atmosphere too thin to reach unit XUV optical depth above the surface, clamps to the bottom level with the same flags.'fixed_pressure': the level atfixed_pressure[Pa].'boreas': the base radius from the BOREAS mass-loss solver (optional dependency), translated to a profile pressure; falls back to'lopez'with thebase_method_fallbackflag when BOREAS is absent or does not converge. Requiresboreas_scalarswith keysR_p[m],T_eq[K], andF_xuv[W m^-2].
Returns:
| Type | Description |
|---|---|
(level, flags)
|
The interpolated level dict and a flags dict. The level carries
|
Source code in src/zephyrus/profiles.py
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | |
atomized_element_fractions(level)
Element mole fractions of the atomized composition at a level dict.
Source code in src/zephyrus/profiles.py
398 399 400 | |