Version: dev

ClOxCycle

Stratospheric ClOx catalytic ozone destruction cycle (Seinfeld & Pandis 2006, Ch. 5 §5.5.1). Migrated from GasChem.jl@8c12c048 src/StratosphericChemistry.jl:272 (`ClOxCycle` @component). Implements 4 ODEs (Cl, ClO, HCl, ClONO2) coupled to 2 algebraic family sums (ClOx = Cl + ClO, Cly = Cl + ClO + HCl + ClONO2). Rate coefficients are Arrhenius (k = A·exp(C/T)) for the five binary reactions and a (T_ref/T)^3.4 form for the termolecular ClO + NO2 + M → ClONO2 channel. All upstream `@constants` are encoded as parameters with their literal SI defaults; physical-condition `@parameters` (T, M, photolysis rates, fixed-bath species O, O3, NO, NO2, OH, CH4) are also parameters so the cycle can be exercised at different atmospheric conditions.

Domain
gaschem
Subdomain
stratospheric
Type
model
.esm schema
1.0.0
Source
components/gaschem/stratospheric/clox_cycle.esm
Tags
#gaschem #stratospheric #model #ClOx #ozone-depletion #catalytic-cycle #seinfeld-pandis

Description

Stratospheric ClOx catalytic ozone destruction cycle (Seinfeld & Pandis 2006, Ch. 5 §5.5.1). Migrated from GasChem.jl@8c12c048 src/StratosphericChemistry.jl:272 (ClOxCycle @component). Implements 4 ODEs (Cl, ClO, HCl, ClONO2) coupled to 2 algebraic family sums (ClOx = Cl + ClO, Cly = Cl + ClO + HCl + ClONO2). Rate coefficients are Arrhenius (k = A·exp(C/T)) for the five binary reactions and a (T_ref/T)^3.4 form for the termolecular ClO + NO2 + M → ClONO2 channel. All upstream @constants are encoded as parameters with their literal SI defaults; physical-condition @parameters (T, M, photolysis rates, fixed-bath species O, O3, NO, NO2, OH, CH4) are also parameters so the cycle can be exercised at different atmospheric conditions.

Reference

_source_ref: GasChem.jl@8c12c048482b515fb8eb2110bf8ab4b4f4e71309:src/StratosphericChemistry.jl:272

Upstream ClOxCycle is an MTK @component with 12 @constants (Arrhenius pre-factors and activation temperatures for five binary channels plus the termolecular ClO + NO2 + M reference), 9 @parameters (T, M, j_ClONO2, and the six fixed-bath concentrations CH4, O, O3, NO, NO2, OH), and 6 @variables (4 time-indexed states Cl, ClO, HCl, ClONO2 + 2 algebraic family sums ClOx, Cly). All 6 equations preserved verbatim: 4 ODEs (D(Cl), D(ClO), D(HCl), D(ClONO2)) + 2 algebraic (ClOx ~ Cl + ClO, Cly ~ Cl + ClO + HCl + ClONO2). The upstream structural test (test/StratosphericChemistry_test.jl:71-81) asserts length(equations(sys)) == 6 and that Cl, ClO, ClONO2, ClOx appear as states — both preserved here.

Upstream @constants are encoded as parameters with their upstream SI default values, matching the convention used by sibling migrations in this rig (snow_thermal.esm encodes physical constants as parameters with default; diameter_growth.esm encodes R_gas, D_diff similarly). Rate coefficients are written inline in the equations as A * exp(C / T) (binary) and A * (T_ref / T)^3.4 (termolecular ClO + NO2 + M) per Seinfeld & Pandis Table B.1/B.2 (pp. 162-167). CGS→SI conversion factors (cm³/molec/s × 1e-6; cm⁶/molec²/s × 1e-12) are folded into the _A defaults: e.g. upstream Cl + O3 pre-factor 2.3e-11 cm³/molec/s → 2.3e-17 m³/s.

Cly conservation: the upstream Cly Conservation (ClOx Cycle) test (test/StratosphericChemistry_test.jl:266-290) asserts that Cly = Cl + ClO + HCl + ClONO2 is conserved to rtol = 1e-6 over a 1 s integration. This is structurally exact for this component — summing the four ODEs:

D(Cl)     = -k_Cl_O3·Cl·O3 + k_ClO_O·ClO·O + k_ClO_NO·ClO·NO - k_Cl_CH4·Cl·CH4 + k_OH_HCl·OH·HCl + j_ClONO2·ClONO2
D(ClO)    = +k_Cl_O3·Cl·O3 - k_ClO_O·ClO·O - k_ClO_NO·ClO·NO - k_ClO_NO2_M·ClO·NO2·M
D(HCl)    = +k_Cl_CH4·Cl·CH4 - k_OH_HCl·OH·HCl
D(ClONO2) = +k_ClO_NO2_M·ClO·NO2·M - j_ClONO2·ClONO2
Σ         = 0

so D(Cly) ≡ 0 analytically and any observed drift in Cly is integrator roundoff — this is why the upstream test uses rtol = 1e-6 over 1 s while internal solver tolerances run at abstol = 1e-12, reltol = 1e-12. The migration preserves this exact conservation structure.

ClOx (= Cl + ClO) is NOT conserved: D(ClOx) = -k_Cl_CH4·Cl·CH4 + k_OH_HCl·OH·HCl + j_ClONO2·ClONO2 - k_ClO_NO2_M·ClO·NO2·M, the four-channel exchange between the active ClOx pair and the reservoir species HCl and ClONO2. The Cl + CH4 / OH + HCl pair shuttles between ClOx and HCl; the ClO + NO2 + M / ClONO2 + hν pair shuttles between ClOx and ClONO2.

Tolerance rationale (model-level rel=1e-6): reference trajectories from upstream Julia MTK Tsit5 integration at abstol=1e-10, reltol=1e-10. 1e-6 covers Tsit5↔SciPy LSODA truncation over 3600 s plus float64 roundoff. Cly conservation runs at the same 1e-6 — it matches the upstream test tolerance (test/StratosphericChemistry_test.jl:289). Several anchors test small-fractional deltas near the initial reservoir mass (HCl, ClONO2 changing by 0.1-1% over short windows) — these use looser per-assertion abs floors derived from the variable magnitude (~1e15 m^-3 × 1e-6 = 1e9 abs floor).

Domain validity: this is a stratospheric component. Defaults match the upstream component (T = 227 K and M = 3.1e23 m^-3 are ~30 km conditions; CH4 = 1e19 m^-3, O3 = 3e18 m^-3 are typical stratospheric values). All bath species (O, O3, NO, NO2, OH, CH4) are parameters here because the upstream component treats them as such — this cycle is a sub-model that runs against externally-prescribed environmental conditions, not a self-contained chemistry box. Coupling with the larger StratosphericOzoneSystem (test/StratosphericChemistry_test.jl:94+) is what promotes these to dynamical species; that integration is out of scope for this single-component migration._

Variables

NameUnitsDefaultDescription
Clm^-310000000000.0Cl atom number density (upstream default initial value 1e4 molec/cm^3 × 1e6 → 1e10 m^-3).
ClOm^-310000000000000.0ClO number density (upstream default initial value 1e7 molec/cm^3 × 1e6 → 1e13 m^-3).
HClm^-31000000000000000.0HCl reservoir number density (upstream default initial value 1e9 molec/cm^3 × 1e6 → 1e15 m^-3).
ClONO2m^-31000000000000000.0ClONO2 reservoir number density (upstream default initial value 1e9 molec/cm^3 × 1e6 → 1e15 m^-3).

Parameters

NameUnitsDefaultDescription
TK227.0Temperature. Default 227 K matches the upstream component and is the canonical 30 km stratospheric value (Seinfeld & Pandis Table 5.1).
j_ClONO2s^-10.0001ClONO2 photolysis rate (ClONO2 + hν → Cl + NO3).
CH4m^-31e+19Methane number density (1e13 molec/cm^3 × 1e6 → 1e19 m^-3). Drives the Cl + CH4 → HCl reservoir-formation channel.
Mm^-33.1e+23Air number density at 30 km (3.1e17 molec/cm^3 × 1e6 → 3.1e23 m^-3). Third body for the ClO + NO2 + M → ClONO2 termolecular channel.
Om^-310000000000000.0Atomic oxygen number density (1e7 molec/cm^3 × 1e6 → 1e13 m^-3). Drives the ClO + O → Cl + O2 catalytic-cycle closing step.
O3m^-33e+18Ozone number density (3e12 molec/cm^3 × 1e6 → 3e18 m^-3). Drives the Cl + O3 → ClO + O2 catalytic-cycle initiating step.
NOm^-31000000000000000.0NO number density (1e9 molec/cm^3 × 1e6 → 1e15 m^-3). Drives the ClO + NO → Cl + NO2 alternative recycling channel.
NO2m^-31000000000000000.0NO2 number density (1e9 molec/cm^3 × 1e6 → 1e15 m^-3). Reactant in the ClO + NO2 + M → ClONO2 reservoir-formation channel.
OHm^-31000000000000.0OH number density (1e6 molec/cm^3 × 1e6 → 1e12 m^-3). Drives the OH + HCl → Cl + H2O reservoir-release channel.
k_Cl_O3_Am^3/s2.3e-17Arrhenius pre-factor for Cl + O3 → ClO + O2 (upstream constant: 2.3e-11 cm^3/molec/s × 1e-6 → 2.3e-17 m^3/s, Seinfeld & Pandis Table B.1, p. 162).
C_Cl_O3K-200.0Activation temperature (C = -E_a/R) for Cl + O3 (upstream constant: -200 K, Seinfeld & Pandis p. 162).
k_ClO_O_Am^3/s3e-17Arrhenius pre-factor for ClO + O → Cl + O2 (upstream constant: 3.0e-11 cm^3/molec/s × 1e-6 → 3.0e-17 m^3/s, Seinfeld & Pandis Table B.1, p. 162).
C_ClO_OK70.0Activation temperature for ClO + O (upstream constant: 70 K, Seinfeld & Pandis p. 162). Positive C means the reaction speeds up at low T (catalytic cycle is more efficient in the cold stratosphere).
k_ClO_NO_Am^3/s6.4e-18Arrhenius pre-factor for ClO + NO → Cl + NO2 (upstream constant: 6.4e-12 cm^3/molec/s × 1e-6 → 6.4e-18 m^3/s, Seinfeld & Pandis Table B.1, p. 163).
C_ClO_NOK290.0Activation temperature for ClO + NO (upstream constant: 290 K).
k_Cl_CH4_Am^3/s9.6e-18Arrhenius pre-factor for Cl + CH4 → HCl + CH3 (upstream constant: 9.6e-12 cm^3/molec/s × 1e-6 → 9.6e-18 m^3/s, Seinfeld & Pandis Table B.1, p. 168).
C_Cl_CH4K-1360.0Activation temperature for Cl + CH4 (upstream constant: -1360 K — strongly endothermic, slow in the cold stratosphere).
k_OH_HCl_Am^3/s2.6e-18Arrhenius pre-factor for OH + HCl → Cl + H2O (upstream constant: 2.6e-12 cm^3/molec/s × 1e-6 → 2.6e-18 m^3/s, Seinfeld & Pandis p. 168).
C_OH_HClK-350.0Activation temperature for OH + HCl (upstream constant: -350 K).
k_ClO_NO2_M_Am^6/s1.8e-43Pre-factor for the termolecular ClO + NO2 + M → ClONO2 reaction at T_ref = 300 K (upstream constant: 1.8e-31 cm^6/molec^2/s × 1e-12 → 1.8e-43 m^6/s, Seinfeld & Pandis p. 165). Rate is k = A · (T_ref/T)^3.4, not Arrhenius.
T_ref_ClOK300.0Reference temperature for the ClO + NO2 + M rate law k = k_A · (T_ref/T)^3.4.

Observed

NameUnitsDefaultDescription
ClOxm^-3Active chlorine family ClOx = Cl + ClO (algebraic). Catalytically destroys O3 via the Cl + O3 / ClO + O cycle.
Clym^-3Total inorganic chlorine Cly = Cl + ClO + HCl + ClONO2 (algebraic). Conserved by the four ODEs (D(Cly) ≡ 0).

Observed expressions

$$ ClOx = Cl + ClO $$

Active chlorine family ClOx = Cl + ClO (algebraic). Catalytically destroys O3 via the Cl + O3 / ClO + O cycle.

$$ Cly = Cl + ClO + HCl + ClONO2 $$

Total inorganic chlorine Cly = Cl + ClO + HCl + ClONO2 (algebraic). Conserved by the four ODEs (D(Cly) ≡ 0).

Equations

$$ \mathrm{D}\left(Cl\right) = \left(-1\right) \cdot k_{Cl\,O3\,A} \cdot e^{\frac{C_{Cl\,O3}}{T}} \cdot Cl \cdot O3 - k_{Cl\,CH4\,A} \cdot e^{\frac{C_{Cl\,CH4}}{T}} \cdot Cl \cdot CH4 + k_{ClO\,O\,A} \cdot e^{\frac{C_{ClO\,O}}{T}} \cdot ClO \cdot O + k_{ClO\,NO\,A} \cdot e^{\frac{C_{ClO\,NO}}{T}} \cdot ClO \cdot NO + k_{OH\,HCl\,A} \cdot e^{\frac{C_{OH\,HCl}}{T}} \cdot OH \cdot HCl + j_{ClONO2} \cdot ClONO2 $$ $$ \mathrm{D}\left(ClO\right) = k_{Cl\,O3\,A} \cdot e^{\frac{C_{Cl\,O3}}{T}} \cdot Cl \cdot O3 - \left(k_{ClO\,O\,A} \cdot e^{\frac{C_{ClO\,O}}{T}} \cdot ClO \cdot O + k_{ClO\,NO\,A} \cdot e^{\frac{C_{ClO\,NO}}{T}} \cdot ClO \cdot NO + k_{ClO\,NO2\,M\,A} \cdot \frac{T_{ref\,ClO}}{T}^{3.4} \cdot ClO \cdot NO2 \cdot M\right) $$ $$ \mathrm{D}\left(HCl\right) = k_{Cl\,CH4\,A} \cdot e^{\frac{C_{Cl\,CH4}}{T}} \cdot Cl \cdot CH4 - k_{OH\,HCl\,A} \cdot e^{\frac{C_{OH\,HCl}}{T}} \cdot OH \cdot HCl $$ $$ \mathrm{D}\left(ClONO2\right) = k_{ClO\,NO2\,M\,A} \cdot \frac{T_{ref\,ClO}}{T}^{3.4} \cdot ClO \cdot NO2 \cdot M - j_{ClONO2} \cdot ClONO2 $$

Analyses

clox_cycle_default_one_hour

Default 30 km stratospheric run (T = 227 K, M = 3.1e23 m^-3, upstream initial conditions) over 1 hour. Surfaces the canonical ClOx-cycle behavior: ClO grows by ~18x as Cl + O3 drives the catalytic cycle, while HCl slowly accumulates and ClONO2 partially photolyzes. Reproduces the upstream ClOx Cycle Integration reference run (test/StratosphericChemistry_test.jl:182).

Time span: 0.0 → 3600.0

Active ClOx species (Cl, ClO) vs time at 30 km defaults. Cl tracks ClO via the quasi-steady Cl/ClO ratio set by Eq. 5.30; both grow as Cl + O3 outpaces the reservoir-formation channels in the first hour.

Reservoir species (HCl, ClONO2) vs time at 30 km defaults. HCl grows slowly via Cl + CH4, while ClONO2 partially photolyzes — the two reservoirs equilibrate on different timescales because the formation/loss rate constants differ.

Total inorganic chlorine Cly = Cl + ClO + HCl + ClONO2 vs time at 30 km defaults. Should remain constant at the initial value 2.01001e15 m^-3 — the upstream Cly Conservation test reference plot.

clox_cycle_temperature_sweep

Sweep T over the stratospheric range [200, 270] K at otherwise-default conditions. Surfaces the temperature dependence of the ClOx cycle: ClO at t = 3600 s rises with T (the positive-C Arrhenius channels — ClO + O, ClO + NO, OH + HCl — speed up faster than the negative-C channels — Cl + O3, Cl + CH4 — slow down). The termolecular ClO + NO2 + M → ClONO2 also slows at higher T (k ∝ (T_ref/T)^3.4), shifting the partition away from the ClONO2 reservoir.

Time span: 0.0 → 3600.0

Swept over: T

Final ClO at t = 3600 s vs temperature: shows the temperature-dependent saturation of the ClOx cycle as the relative weight of Arrhenius positive-C / negative-C / termolecular channels shifts.

Raw .esm

Raw .esm JSON (this component)
{
  "reference": {
    "notes": "source_ref: GasChem.jl@8c12c048482b515fb8eb2110bf8ab4b4f4e71309:src/StratosphericChemistry.jl:272\n\nUpstream `ClOxCycle` is an MTK `@component` with 12 `@constants` (Arrhenius pre-factors and activation temperatures for five binary channels plus the termolecular ClO + NO2 + M reference), 9 `@parameters` (T, M, j_ClONO2, and the six fixed-bath concentrations CH4, O, O3, NO, NO2, OH), and 6 `@variables` (4 time-indexed states Cl, ClO, HCl, ClONO2 + 2 algebraic family sums ClOx, Cly). All 6 equations preserved verbatim: 4 ODEs (D(Cl), D(ClO), D(HCl), D(ClONO2)) + 2 algebraic (ClOx ~ Cl + ClO, Cly ~ Cl + ClO + HCl + ClONO2). The upstream structural test (test/StratosphericChemistry_test.jl:71-81) asserts `length(equations(sys)) == 6` and that Cl, ClO, ClONO2, ClOx appear as states — both preserved here.\n\nUpstream `@constants` are encoded as parameters with their upstream SI default values, matching the convention used by sibling migrations in this rig (snow_thermal.esm encodes physical constants as parameters with default; diameter_growth.esm encodes R_gas, D_diff similarly). Rate coefficients are written inline in the equations as `A * exp(C / T)` (binary) and `A * (T_ref / T)^3.4` (termolecular ClO + NO2 + M) per Seinfeld & Pandis Table B.1/B.2 (pp. 162-167). CGS→SI conversion factors (cm³/molec/s × 1e-6; cm⁶/molec²/s × 1e-12) are folded into the `_A` defaults: e.g. upstream Cl + O3 pre-factor 2.3e-11 cm³/molec/s → 2.3e-17 m³/s.\n\nCly conservation: the upstream `Cly Conservation (ClOx Cycle)` test (test/StratosphericChemistry_test.jl:266-290) asserts that Cly = Cl + ClO + HCl + ClONO2 is conserved to rtol = 1e-6 over a 1 s integration. This is structurally exact for this component — summing the four ODEs:\n\n    D(Cl)     = -k_Cl_O3·Cl·O3 + k_ClO_O·ClO·O + k_ClO_NO·ClO·NO - k_Cl_CH4·Cl·CH4 + k_OH_HCl·OH·HCl + j_ClONO2·ClONO2\n    D(ClO)    = +k_Cl_O3·Cl·O3 - k_ClO_O·ClO·O - k_ClO_NO·ClO·NO - k_ClO_NO2_M·ClO·NO2·M\n    D(HCl)    = +k_Cl_CH4·Cl·CH4 - k_OH_HCl·OH·HCl\n    D(ClONO2) = +k_ClO_NO2_M·ClO·NO2·M - j_ClONO2·ClONO2\n    Σ         = 0\n\nso D(Cly) ≡ 0 analytically and any observed drift in Cly is integrator roundoff — this is why the upstream test uses rtol = 1e-6 over 1 s while internal solver tolerances run at abstol = 1e-12, reltol = 1e-12. The migration preserves this exact conservation structure.\n\nClOx (= Cl + ClO) is NOT conserved: D(ClOx) = -k_Cl_CH4·Cl·CH4 + k_OH_HCl·OH·HCl + j_ClONO2·ClONO2 - k_ClO_NO2_M·ClO·NO2·M, the four-channel exchange between the active ClOx pair and the reservoir species HCl and ClONO2. The Cl + CH4 / OH + HCl pair shuttles between ClOx and HCl; the ClO + NO2 + M / ClONO2 + hν pair shuttles between ClOx and ClONO2.\n\nTolerance rationale (model-level rel=1e-6): reference trajectories from upstream Julia MTK Tsit5 integration at abstol=1e-10, reltol=1e-10. 1e-6 covers Tsit5↔SciPy LSODA truncation over 3600 s plus float64 roundoff. Cly conservation runs at the same 1e-6 — it matches the upstream test tolerance (test/StratosphericChemistry_test.jl:289). Several anchors test small-fractional deltas near the initial reservoir mass (HCl, ClONO2 changing by 0.1-1% over short windows) — these use looser per-assertion abs floors derived from the variable magnitude (~1e15 m^-3 × 1e-6 = 1e9 abs floor).\n\nDomain validity: this is a stratospheric component. Defaults match the upstream component (T = 227 K and M = 3.1e23 m^-3 are ~30 km conditions; CH4 = 1e19 m^-3, O3 = 3e18 m^-3 are typical stratospheric values). All bath species (O, O3, NO, NO2, OH, CH4) are parameters here because the upstream component treats them as such — this cycle is a sub-model that runs against externally-prescribed environmental conditions, not a self-contained chemistry box. Coupling with the larger StratosphericOzoneSystem (test/StratosphericChemistry_test.jl:94+) is what promotes these to dynamical species; that integration is out of scope for this single-component migration."
  },
  "tolerance": {
    "rel": 1e-06
  },
  "variables": {
    "T": {
      "type": "parameter",
      "units": "K",
      "default": 227.0,
      "description": "Temperature. Default 227 K matches the upstream component and is the canonical 30 km stratospheric value (Seinfeld & Pandis Table 5.1)."
    },
    "j_ClONO2": {
      "type": "parameter",
      "units": "s^-1",
      "default": 0.0001,
      "description": "ClONO2 photolysis rate (ClONO2 + hν → Cl + NO3)."
    },
    "CH4": {
      "type": "parameter",
      "units": "m^-3",
      "default": 1e+19,
      "description": "Methane number density (1e13 molec/cm^3 × 1e6 → 1e19 m^-3). Drives the Cl + CH4 → HCl reservoir-formation channel."
    },
    "M": {
      "type": "parameter",
      "units": "m^-3",
      "default": 3.1e+23,
      "description": "Air number density at 30 km (3.1e17 molec/cm^3 × 1e6 → 3.1e23 m^-3). Third body for the ClO + NO2 + M → ClONO2 termolecular channel."
    },
    "O": {
      "type": "parameter",
      "units": "m^-3",
      "default": 10000000000000.0,
      "description": "Atomic oxygen number density (1e7 molec/cm^3 × 1e6 → 1e13 m^-3). Drives the ClO + O → Cl + O2 catalytic-cycle closing step."
    },
    "O3": {
      "type": "parameter",
      "units": "m^-3",
      "default": 3e+18,
      "description": "Ozone number density (3e12 molec/cm^3 × 1e6 → 3e18 m^-3). Drives the Cl + O3 → ClO + O2 catalytic-cycle initiating step."
    },
    "NO": {
      "type": "parameter",
      "units": "m^-3",
      "default": 1000000000000000.0,
      "description": "NO number density (1e9 molec/cm^3 × 1e6 → 1e15 m^-3). Drives the ClO + NO → Cl + NO2 alternative recycling channel."
    },
    "NO2": {
      "type": "parameter",
      "units": "m^-3",
      "default": 1000000000000000.0,
      "description": "NO2 number density (1e9 molec/cm^3 × 1e6 → 1e15 m^-3). Reactant in the ClO + NO2 + M → ClONO2 reservoir-formation channel."
    },
    "OH": {
      "type": "parameter",
      "units": "m^-3",
      "default": 1000000000000.0,
      "description": "OH number density (1e6 molec/cm^3 × 1e6 → 1e12 m^-3). Drives the OH + HCl → Cl + H2O reservoir-release channel."
    },
    "k_Cl_O3_A": {
      "type": "parameter",
      "units": "m^3/s",
      "default": 2.3e-17,
      "description": "Arrhenius pre-factor for Cl + O3 → ClO + O2 (upstream constant: 2.3e-11 cm^3/molec/s × 1e-6 → 2.3e-17 m^3/s, Seinfeld & Pandis Table B.1, p. 162)."
    },
    "C_Cl_O3": {
      "type": "parameter",
      "units": "K",
      "default": -200.0,
      "description": "Activation temperature (C = -E_a/R) for Cl + O3 (upstream constant: -200 K, Seinfeld & Pandis p. 162)."
    },
    "k_ClO_O_A": {
      "type": "parameter",
      "units": "m^3/s",
      "default": 3e-17,
      "description": "Arrhenius pre-factor for ClO + O → Cl + O2 (upstream constant: 3.0e-11 cm^3/molec/s × 1e-6 → 3.0e-17 m^3/s, Seinfeld & Pandis Table B.1, p. 162)."
    },
    "C_ClO_O": {
      "type": "parameter",
      "units": "K",
      "default": 70.0,
      "description": "Activation temperature for ClO + O (upstream constant: 70 K, Seinfeld & Pandis p. 162). Positive C means the reaction speeds up at low T (catalytic cycle is more efficient in the cold stratosphere)."
    },
    "k_ClO_NO_A": {
      "type": "parameter",
      "units": "m^3/s",
      "default": 6.4e-18,
      "description": "Arrhenius pre-factor for ClO + NO → Cl + NO2 (upstream constant: 6.4e-12 cm^3/molec/s × 1e-6 → 6.4e-18 m^3/s, Seinfeld & Pandis Table B.1, p. 163)."
    },
    "C_ClO_NO": {
      "type": "parameter",
      "units": "K",
      "default": 290.0,
      "description": "Activation temperature for ClO + NO (upstream constant: 290 K)."
    },
    "k_Cl_CH4_A": {
      "type": "parameter",
      "units": "m^3/s",
      "default": 9.6e-18,
      "description": "Arrhenius pre-factor for Cl + CH4 → HCl + CH3 (upstream constant: 9.6e-12 cm^3/molec/s × 1e-6 → 9.6e-18 m^3/s, Seinfeld & Pandis Table B.1, p. 168)."
    },
    "C_Cl_CH4": {
      "type": "parameter",
      "units": "K",
      "default": -1360.0,
      "description": "Activation temperature for Cl + CH4 (upstream constant: -1360 K — strongly endothermic, slow in the cold stratosphere)."
    },
    "k_OH_HCl_A": {
      "type": "parameter",
      "units": "m^3/s",
      "default": 2.6e-18,
      "description": "Arrhenius pre-factor for OH + HCl → Cl + H2O (upstream constant: 2.6e-12 cm^3/molec/s × 1e-6 → 2.6e-18 m^3/s, Seinfeld & Pandis p. 168)."
    },
    "C_OH_HCl": {
      "type": "parameter",
      "units": "K",
      "default": -350.0,
      "description": "Activation temperature for OH + HCl (upstream constant: -350 K)."
    },
    "k_ClO_NO2_M_A": {
      "type": "parameter",
      "units": "m^6/s",
      "default": 1.8e-43,
      "description": "Pre-factor for the termolecular ClO + NO2 + M → ClONO2 reaction at T_ref = 300 K (upstream constant: 1.8e-31 cm^6/molec^2/s × 1e-12 → 1.8e-43 m^6/s, Seinfeld & Pandis p. 165). Rate is k = A · (T_ref/T)^3.4, not Arrhenius."
    },
    "T_ref_ClO": {
      "type": "parameter",
      "units": "K",
      "default": 300.0,
      "description": "Reference temperature for the ClO + NO2 + M rate law k = k_A · (T_ref/T)^3.4."
    },
    "Cl": {
      "type": "unknown",
      "units": "m^-3",
      "default": 10000000000.0,
      "description": "Cl atom number density (upstream default initial value 1e4 molec/cm^3 × 1e6 → 1e10 m^-3)."
    },
    "ClO": {
      "type": "unknown",
      "units": "m^-3",
      "default": 10000000000000.0,
      "description": "ClO number density (upstream default initial value 1e7 molec/cm^3 × 1e6 → 1e13 m^-3)."
    },
    "HCl": {
      "type": "unknown",
      "units": "m^-3",
      "default": 1000000000000000.0,
      "description": "HCl reservoir number density (upstream default initial value 1e9 molec/cm^3 × 1e6 → 1e15 m^-3)."
    },
    "ClONO2": {
      "type": "unknown",
      "units": "m^-3",
      "default": 1000000000000000.0,
      "description": "ClONO2 reservoir number density (upstream default initial value 1e9 molec/cm^3 × 1e6 → 1e15 m^-3)."
    },
    "ClOx": {
      "type": "unknown",
      "units": "m^-3",
      "description": "Active chlorine family ClOx = Cl + ClO (algebraic). Catalytically destroys O3 via the Cl + O3 / ClO + O cycle."
    },
    "Cly": {
      "type": "unknown",
      "units": "m^-3",
      "description": "Total inorganic chlorine Cly = Cl + ClO + HCl + ClONO2 (algebraic). Conserved by the four ODEs (D(Cly) ≡ 0)."
    }
  },
  "equations": [
    {
      "lhs": {
        "op": "D",
        "wrt": "t",
        "args": [
          "Cl"
        ]
      },
      "rhs": {
        "op": "+",
        "args": [
          {
            "op": "-",
            "args": [
              {
                "op": "*",
                "args": [
                  -1,
                  {
                    "op": "*",
                    "args": [
                      "k_Cl_O3_A",
                      {
                        "op": "exp",
                        "args": [
                          {
                            "op": "/",
                            "args": [
                              "C_Cl_O3",
                              "T"
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  "Cl",
                  "O3"
                ]
              },
              {
                "op": "*",
                "args": [
                  {
                    "op": "*",
                    "args": [
                      "k_Cl_CH4_A",
                      {
                        "op": "exp",
                        "args": [
                          {
                            "op": "/",
                            "args": [
                              "C_Cl_CH4",
                              "T"
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  "Cl",
                  "CH4"
                ]
              }
            ]
          },
          {
            "op": "*",
            "args": [
              {
                "op": "*",
                "args": [
                  "k_ClO_O_A",
                  {
                    "op": "exp",
                    "args": [
                      {
                        "op": "/",
                        "args": [
                          "C_ClO_O",
                          "T"
                        ]
                      }
                    ]
                  }
                ]
              },
              "ClO",
              "O"
            ]
          },
          {
            "op": "*",
            "args": [
              {
                "op": "*",
                "args": [
                  "k_ClO_NO_A",
                  {
                    "op": "exp",
                    "args": [
                      {
                        "op": "/",
                        "args": [
                          "C_ClO_NO",
                          "T"
                        ]
                      }
                    ]
                  }
                ]
              },
              "ClO",
              "NO"
            ]
          },
          {
            "op": "*",
            "args": [
              {
                "op": "*",
                "args": [
                  "k_OH_HCl_A",
                  {
                    "op": "exp",
                    "args": [
                      {
                        "op": "/",
                        "args": [
                          "C_OH_HCl",
                          "T"
                        ]
                      }
                    ]
                  }
                ]
              },
              "OH",
              "HCl"
            ]
          },
          {
            "op": "*",
            "args": [
              "j_ClONO2",
              "ClONO2"
            ]
          }
        ]
      }
    },
    {
      "lhs": {
        "op": "D",
        "wrt": "t",
        "args": [
          "ClO"
        ]
      },
      "rhs": {
        "op": "-",
        "args": [
          {
            "op": "*",
            "args": [
              {
                "op": "*",
                "args": [
                  "k_Cl_O3_A",
                  {
                    "op": "exp",
                    "args": [
                      {
                        "op": "/",
                        "args": [
                          "C_Cl_O3",
                          "T"
                        ]
                      }
                    ]
                  }
                ]
              },
              "Cl",
              "O3"
            ]
          },
          {
            "op": "+",
            "args": [
              {
                "op": "*",
                "args": [
                  {
                    "op": "*",
                    "args": [
                      "k_ClO_O_A",
                      {
                        "op": "exp",
                        "args": [
                          {
                            "op": "/",
                            "args": [
                              "C_ClO_O",
                              "T"
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  "ClO",
                  "O"
                ]
              },
              {
                "op": "*",
                "args": [
                  {
                    "op": "*",
                    "args": [
                      "k_ClO_NO_A",
                      {
                        "op": "exp",
                        "args": [
                          {
                            "op": "/",
                            "args": [
                              "C_ClO_NO",
                              "T"
                            ]
                          }
                        ]
                      }
                    ]
                  },
                  "ClO",
                  "NO"
                ]
              },
              {
                "op": "*",
                "args": [
                  {
                    "op": "*",
                    "args": [
                      "k_ClO_NO2_M_A",
                      {
                        "op": "^",
                        "args": [
                          {
                            "op": "/",
                            "args": [
                              "T_ref_ClO",
                              "T"
                            ]
                          },
                          3.4
                        ]
                      }
                    ]
                  },
                  "ClO",
                  "NO2",
                  "M"
                ]
              }
            ]
          }
        ]
      }
    },
    {
      "lhs": {
        "op": "D",
        "wrt": "t",
        "args": [
          "HCl"
        ]
      },
      "rhs": {
        "op": "-",
        "args": [
          {
            "op": "*",
            "args": [
              {
                "op": "*",
                "args": [
                  "k_Cl_CH4_A",
                  {
                    "op": "exp",
                    "args": [
                      {
                        "op": "/",
                        "args": [
                          "C_Cl_CH4",
                          "T"
                        ]
                      }
                    ]
                  }
                ]
              },
              "Cl",
              "CH4"
            ]
          },
          {
            "op": "*",
            "args": [
              {
                "op": "*",
                "args": [
                  "k_OH_HCl_A",
                  {
                    "op": "exp",
                    "args": [
                      {
                        "op": "/",
                        "args": [
                          "C_OH_HCl",
                          "T"
                        ]
                      }
                    ]
                  }
                ]
              },
              "OH",
              "HCl"
            ]
          }
        ]
      }
    },
    {
      "lhs": {
        "op": "D",
        "wrt": "t",
        "args": [
          "ClONO2"
        ]
      },
      "rhs": {
        "op": "-",
        "args": [
          {
            "op": "*",
            "args": [
              {
                "op": "*",
                "args": [
                  "k_ClO_NO2_M_A",
                  {
                    "op": "^",
                    "args": [
                      {
                        "op": "/",
                        "args": [
                          "T_ref_ClO",
                          "T"
                        ]
                      },
                      3.4
                    ]
                  }
                ]
              },
              "ClO",
              "NO2",
              "M"
            ]
          },
          {
            "op": "*",
            "args": [
              "j_ClONO2",
              "ClONO2"
            ]
          }
        ]
      }
    },
    {
      "lhs": "ClOx",
      "rhs": {
        "op": "+",
        "args": [
          "Cl",
          "ClO"
        ]
      }
    },
    {
      "lhs": "Cly",
      "rhs": {
        "op": "+",
        "args": [
          "Cl",
          "ClO",
          "HCl",
          "ClONO2"
        ]
      }
    }
  ],
  "tests": [
    {
      "id": "default_30km_short_window",
      "description": "Reference trajectory at upstream default conditions (T = 227 K, M = 3.1e23 m^-3 — 30 km, defaults for all bath species, initial Cl = 1e10, ClO = 1e13, HCl = 1e15, ClONO2 = 1e15). Samples Cl, ClO, HCl, ClONO2, and the algebraic family sums ClOx and Cly at t = 0, 1, 60, 600 s. Pinned from upstream Julia MTK Tsit5 integration at abstol=1e-10, reltol=1e-10. Exercises all four ODE channels (Cl + O3, ClO + O, ClO + NO, Cl + CH4, OH + HCl, ClO + NO2 + M, j_ClONO2) and both algebraic family sums simultaneously.",
      "time_span": {
        "start": 0.0,
        "end": 600.0
      },
      "assertions": [
        {
          "variable": "Cl",
          "time": 0.0,
          "expected": 10000000000.0
        },
        {
          "variable": "ClO",
          "time": 0.0,
          "expected": 10000000000000.0
        },
        {
          "variable": "HCl",
          "time": 0.0,
          "expected": 1000000000000000.0
        },
        {
          "variable": "ClONO2",
          "time": 0.0,
          "expected": 1000000000000000.0
        },
        {
          "variable": "ClOx",
          "time": 0.0,
          "expected": 10010000000000.0
        },
        {
          "variable": "Cly",
          "time": 0.0,
          "expected": 2010010000000000.0
        },
        {
          "variable": "Cl",
          "time": 1.0,
          "expected": 11667854808.897636
        },
        {
          "variable": "ClO",
          "time": 1.0,
          "expected": 10094658379034.93
        },
        {
          "variable": "HCl",
          "time": 1.0,
          "expected": 1000002222141430.2,
          "tolerance": {
            "abs": 1000000000.0
          }
        },
        {
          "variable": "ClONO2",
          "time": 1.0,
          "expected": 999901451624726.2,
          "tolerance": {
            "abs": 1000000000.0
          }
        },
        {
          "variable": "ClOx",
          "time": 1.0,
          "expected": 10106326233843.828
        },
        {
          "variable": "Cl",
          "time": 60.0,
          "expected": 16190275896.757105
        },
        {
          "variable": "ClO",
          "time": 60.0,
          "expected": 15698213820352.043
        },
        {
          "variable": "ClOx",
          "time": 60.0,
          "expected": 15714404096248.8
        },
        {
          "variable": "Cl",
          "time": 600.0,
          "expected": 52499282405.076584
        },
        {
          "variable": "ClO",
          "time": 600.0,
          "expected": 60699774240375.87
        },
        {
          "variable": "HCl",
          "time": 600.0,
          "expected": 1004412905738617.2
        },
        {
          "variable": "ClONO2",
          "time": 600.0,
          "expected": 944844820738602.4
        },
        {
          "variable": "ClOx",
          "time": 600.0,
          "expected": 60752273522780.945
        }
      ]
    },
    {
      "id": "default_30km_long_window_one_hour",
      "description": "Same upstream-default conditions extended to t = 3600 s (1 hour) — the exact window of the upstream `ClOx Cycle Integration` test (test/StratosphericChemistry_test.jl:182-202). At this point HCl has grown ~8% (~1.08e15) and ClONO2 has dropped ~25% (~7.5e14), as ClO + NO2 + M / ClONO2 + hν has not yet reached steady state and the Cl + CH4 / OH + HCl channel slowly transfers Cl into HCl. Exercises long-window numerical agreement and verifies positivity-preservation (all species ≥ 0) as the upstream test asserts.",
      "time_span": {
        "start": 0.0,
        "end": 3600.0
      },
      "assertions": [
        {
          "variable": "Cl",
          "time": 3600.0,
          "expected": 145917563476.57654
        },
        {
          "variable": "ClO",
          "time": 3600.0,
          "expected": 176769411036707.2
        },
        {
          "variable": "HCl",
          "time": 3600.0,
          "expected": 1082448634324647.6
        },
        {
          "variable": "ClONO2",
          "time": 3600.0,
          "expected": 750646037075181.4
        },
        {
          "variable": "ClOx",
          "time": 3600.0,
          "expected": 176915328600183.75
        }
      ]
    },
    {
      "id": "cly_conservation_short_window",
      "description": "Reproduces the upstream `Cly Conservation (ClOx Cycle)` test (test/StratosphericChemistry_test.jl:266-290): integrating 1 s under defaults, total inorganic chlorine Cly = Cl + ClO + HCl + ClONO2 must remain at its initial value 2.01001e15 m^-3 to rtol = 1e-6. Analytically D(Cly) = D(Cl) + D(ClO) + D(HCl) + D(ClONO2) ≡ 0, so any deviation is integrator roundoff. Samples Cly at three points spanning the integration window.",
      "time_span": {
        "start": 0.0,
        "end": 1.0
      },
      "assertions": [
        {
          "variable": "Cly",
          "time": 0.0,
          "expected": 2010010000000000.0
        },
        {
          "variable": "Cly",
          "time": 0.1,
          "expected": 2010010000000000.5
        },
        {
          "variable": "Cly",
          "time": 0.5,
          "expected": 2010010000000000.5
        },
        {
          "variable": "Cly",
          "time": 1.0,
          "expected": 2010010000000000.5
        }
      ]
    },
    {
      "id": "warm_temperature_40km",
      "description": "Reference trajectory at T = 251 K (40 km conditions, Seinfeld & Pandis Table 5.1) with all other parameters at defaults. Warmer T accelerates the Arrhenius positive-C channels (ClO + O, ClO + NO, OH + HCl) and slows the negative-C channels (Cl + O3, Cl + CH4) — net effect is faster ClOx cycling (ClO at 1 hour ≈ 1.63e14, vs ~1.77e14 at 30 km). Exercises the temperature-dependent rate-law branch at a textbook-relevant altitude. Reference values pinned from upstream Tsit5 integration.",
      "time_span": {
        "start": 0.0,
        "end": 3600.0
      },
      "parameter_overrides": {
        "T": 251.0
      },
      "assertions": [
        {
          "variable": "Cl",
          "time": 600.0,
          "expected": 42172605375.89072
        },
        {
          "variable": "ClO",
          "time": 600.0,
          "expected": 59592773138181.42
        },
        {
          "variable": "HCl",
          "time": 600.0,
          "expected": 1006449594334760.8
        },
        {
          "variable": "ClONO2",
          "time": 600.0,
          "expected": 943925459921681.9
        },
        {
          "variable": "Cl",
          "time": 3600.0,
          "expected": 109484925766.25302
        },
        {
          "variable": "ClO",
          "time": 3600.0,
          "expected": 163039344052707.62
        },
        {
          "variable": "HCl",
          "time": 3600.0,
          "expected": 1113523856447711.2
        },
        {
          "variable": "ClONO2",
          "time": 3600.0,
          "expected": 733337314573806.8
        }
      ]
    },
    {
      "id": "no_methane_channel",
      "description": "Methane-free scenario (CH4 = 0). Eliminates the Cl + CH4 → HCl reservoir-formation channel, so HCl can only decrease (OH + HCl → Cl is the only HCl term). After 1 hour HCl has dropped ~0.2% (vs growing ~8% at default CH4) because the only HCl source is the externally-prescribed OH + HCl reaction. Exercises the parameter-sweep behavior of the CH4 channel; reference values pinned from upstream Tsit5 integration.",
      "time_span": {
        "start": 0.0,
        "end": 3600.0
      },
      "parameter_overrides": {
        "CH4": 0.0
      },
      "assertions": [
        {
          "variable": "Cl",
          "time": 60.0,
          "expected": 16488836255.480213
        },
        {
          "variable": "ClO",
          "time": 60.0,
          "expected": 15897307817018.953
        },
        {
          "variable": "HCl",
          "time": 600.0,
          "expected": 999666239397679.0,
          "tolerance": {
            "abs": 10000000000.0
          }
        },
        {
          "variable": "HCl",
          "time": 3600.0,
          "expected": 997999106584768.9,
          "tolerance": {
            "abs": 10000000000.0
          }
        },
        {
          "variable": "ClO",
          "time": 3600.0,
          "expected": 247575679957642.84
        }
      ]
    },
    {
      "id": "no_no2_channel",
      "description": "NO2-free scenario (NO2 = 0). Eliminates the ClO + NO2 + M → ClONO2 reservoir-formation channel, so ClONO2 can only decrease (ClONO2 + hν → Cl is the only ClONO2 term). After 1 hour ClONO2 has dropped ~30% (vs ~25% at default NO2) because the photolysis loss is no longer balanced by formation. Exercises the parameter-sweep behavior of the termolecular ClO + NO2 + M channel; reference values pinned from upstream Tsit5 integration.",
      "time_span": {
        "start": 0.0,
        "end": 3600.0
      },
      "parameter_overrides": {
        "NO2": 0.0
      },
      "assertions": [
        {
          "variable": "Cl",
          "time": 60.0,
          "expected": 16279100182.742704
        },
        {
          "variable": "ClO",
          "time": 60.0,
          "expected": 15808340135467.223
        },
        {
          "variable": "ClONO2",
          "time": 600.0,
          "expected": 941764533584252.1
        },
        {
          "variable": "ClONO2",
          "time": 3600.0,
          "expected": 697676326071035.1
        },
        {
          "variable": "ClO",
          "time": 3600.0,
          "expected": 217428446195968.0
        }
      ]
    }
  ],
  "analyses": [
    {
      "id": "clox_cycle_default_one_hour",
      "description": "Default 30 km stratospheric run (T = 227 K, M = 3.1e23 m^-3, upstream initial conditions) over 1 hour. Surfaces the canonical ClOx-cycle behavior: ClO grows by ~18x as Cl + O3 drives the catalytic cycle, while HCl slowly accumulates and ClONO2 partially photolyzes. Reproduces the upstream `ClOx Cycle Integration` reference run (test/StratosphericChemistry_test.jl:182).",
      "initial_state": {
        "Cl": 10000000000.0,
        "ClO": 10000000000000.0,
        "HCl": 1000000000000000.0,
        "ClONO2": 1000000000000000.0
      },
      "time_span": {
        "start": 0.0,
        "end": 3600.0
      },
      "plots": [
        {
          "id": "active_clox_vs_time",
          "type": "line",
          "description": "Active ClOx species (Cl, ClO) vs time at 30 km defaults. Cl tracks ClO via the quasi-steady Cl/ClO ratio set by Eq. 5.30; both grow as Cl + O3 outpaces the reservoir-formation channels in the first hour.",
          "x": {
            "variable": "t",
            "label": "time (s)"
          },
          "y": {
            "variable": "ClO",
            "label": "ClO (m^-3)"
          }
        },
        {
          "id": "reservoir_species_vs_time",
          "type": "line",
          "description": "Reservoir species (HCl, ClONO2) vs time at 30 km defaults. HCl grows slowly via Cl + CH4, while ClONO2 partially photolyzes — the two reservoirs equilibrate on different timescales because the formation/loss rate constants differ.",
          "x": {
            "variable": "t",
            "label": "time (s)"
          },
          "y": {
            "variable": "ClONO2",
            "label": "ClONO2 (m^-3)"
          }
        },
        {
          "id": "cly_conservation_vs_time",
          "type": "line",
          "description": "Total inorganic chlorine Cly = Cl + ClO + HCl + ClONO2 vs time at 30 km defaults. Should remain constant at the initial value 2.01001e15 m^-3 — the upstream Cly Conservation test reference plot.",
          "x": {
            "variable": "t",
            "label": "time (s)"
          },
          "y": {
            "variable": "Cly",
            "label": "Cly (m^-3)"
          }
        }
      ]
    },
    {
      "id": "clox_cycle_temperature_sweep",
      "description": "Sweep T over the stratospheric range [200, 270] K at otherwise-default conditions. Surfaces the temperature dependence of the ClOx cycle: ClO at t = 3600 s rises with T (the positive-C Arrhenius channels — ClO + O, ClO + NO, OH + HCl — speed up faster than the negative-C channels — Cl + O3, Cl + CH4 — slow down). The termolecular ClO + NO2 + M → ClONO2 also slows at higher T (k ∝ (T_ref/T)^3.4), shifting the partition away from the ClONO2 reservoir.",
      "initial_state": {
        "Cl": 10000000000.0,
        "ClO": 10000000000000.0,
        "HCl": 1000000000000000.0,
        "ClONO2": 1000000000000000.0
      },
      "time_span": {
        "start": 0.0,
        "end": 3600.0
      },
      "parameter_sweep": {
        "type": "cartesian",
        "dimensions": [
          {
            "parameter": "T",
            "range": {
              "start": 200.0,
              "stop": 270.0,
              "count": 8,
              "scale": "linear"
            }
          }
        ]
      },
      "plots": [
        {
          "id": "ClO_final_vs_T",
          "type": "line",
          "description": "Final ClO at t = 3600 s vs temperature: shows the temperature-dependent saturation of the ClOx cycle as the relative weight of Arrhenius positive-C / negative-C / termolecular channels shifts.",
          "x": {
            "variable": "T",
            "label": "T (K)"
          },
          "y": {
            "variable": "ClO",
            "label": "ClO at t=3600 s (m^-3)"
          }
        }
      ]
    }
  ]
}