Skip to content

couple2 for NEI2016InlineEmis (elevated point sources) - #233

Open
xk-y wants to merge 12 commits into
EarthSciML:mainfrom
xk-y:pr/inline-couple2
Open

couple2 for NEI2016InlineEmis (elevated point sources)#233
xk-y wants to merge 12 commits into
EarthSciML:mainfrom
xk-y:pr/inline-couple2

Conversation

@xk-y

@xk-y xk-y commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

opt-in · non-breaking

Change

Maps the inline point-source variables (SO2/NO/NO2/CO/NH3, already a mixing-ratio rate at the plume-injection layer) into SuperFast and GEOS-Chem with the same uconv/MW pattern as the surface NEI coupling. Layer-agnostic — vertical placement lives entirely in the emissions System's wrapper. Pure addition: two new couple2 methods, no existing code or defaults touched.

Dependencies

EarthSciData NEI2016InlineEmisEarthSciML/EarthSciData.jl#218 (closes EarthSciData#211) merged + tagged; the GasChem SuperFast-aerosol-species PR (#231) for the SF SO2/NH3 targets and — via its stack — the GasChem ISORROPIA PR (#230) for the GEOS-Chem NH3 species (which also inherits the Aerosol 0.4.2 gate).


Review order - part of the coordinated train (#225)

Base = main. Stacked on SuperFast (#231); net-new = the couple2-wiring commit. CI is red until the EarthSciData NEI-inline PR (EarthSciML/EarthSciData.jl#218) merges + EarthSciData tags (and, inherited via the parent stack, the Aerosol 0.4.2 gate).

Part of the coordinated cross-repo update tracked in #225.

xk-y and others added 4 commits July 8, 2026 01:23
Restore the disabled het/cloud sinks as parameter coupling seams (default 0 =
inert, mirroring k_cld/k_mt) and wire them to Aerosol.jl through a new AerosolExt:

- geoschem_fullchem.jl: expose k_het_N2O5/HO2/NO2/NO3 (s^-1) and enable the
  first-order het uptake reactions N2O5->2HNO3, HO2->(sink), NO2->0.5HNO3+0.5HNO2,
  NO3->HNO3 (the dominant nighttime NOx / HOx heterogeneous sinks).
- ext/AerosolExt.jl: couple2(GEOSChemGasPhase, AerosolDistribution) sets each
  k_het = S_t*c_bar*gamma/4 (GEOS-Chem Ars_L1k kinetic limit); couple2(
  GEOSChemGasPhase, CloudChemistryFixedpH) sets k_cld1 from the in-cloud H2O2
  S(IV) oxidation rate (S&P Eq. 7.75).
- Project.toml: Aerosol weak dependency + AerosolExt extension; add Aerosol and
  OrdinaryDiffEqNonlinearSolve to the test target.
- test/AerosolExt_test.jl: het params/reaction present, het rates driven by S_t,
  in-cloud SO2+H2O2->SO4 with sulfur conserved.

Defaults are no-ops, so base GEOSChemGasPhase behaviour is unchanged (the existing
mechanism sensitivity tests pass unmodified). Requires an Aerosol.jl providing the
AerosolDistributionCoupler / CloudChemistryFixedpHCoupler types.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
FC=1.0 (100% cloud everywhere) over-depleted H2O2.
0.15 is a prescribed climatological mean; interim until coupled from GEOSFP
A3cld CLOUD.

GC cloud-couple2 FC hunk only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The O1D finite-difference sensitivity is a near-cancellation quantity: at the
default tolerance + 10% perturbation the signal sat below the solver accuracy
floor (reltol * O3 ~ 2e-9) and drifted with structural changes such as the new
(default-off) het uptake reactions. Tight tolerances (abstol=reltol=1e-10) and
a 50% perturbation make it a converged, reproducible value; rtol=0.01.

This is the O1D hunk only — the OH/HO2 hunks are already in upstream main via
PR EarthSciML#222.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- NH3/NH4 species in GEOSChemGasPhase + NEI ammonia emission coupling
  (NH3 + NH3_FERT sectors; Vector-of-pairs translate table so duplicate LHS
  species are preserved)
- IsorropiaOp (src/isorropia_operator.jl): k_mt = 1/300 s^-1 mass-transfer
  relaxation toward the NH4-SO4-NO3 metastable equilibrium (matches the common
  300 s Strang step)
- AerosolExt get_odefunction: faithful ISORROPIA II regime split + bisection
  solve (_iso_ternary, robust across all composition regimes), per-cell met
  read with tri-level H2O resolution (observed / state / constant-species
  parameter), convergence-gated graceful fallback, condensed-phase
  electroneutrality anion cap on aerosol NH4
- fixes swapped sulfate/nitrate totals in the solver call; documents k_mt*dt
  semantics and the per-cell pressure source
- tests: isorropia_op_test.jl (regimes, conservation, met-coupled RH
  sensitivity, robustness) + NEI-NH3 coupled invariants

The tri-level H2O read is written so this coupling is independent of merge
order with respect to the met-driven H2O change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
xk-y and others added 8 commits July 10, 2026 21:50
Also exempt 'Strang' (Gilbert Strang, operator splitting) in _typos.toml.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Species: re-enable SO2, add SO4/NH3/NH4/NIT/N2O5/NO3 (7 new states). Hooks
k_cld1/k_het_{N2O5,HO2,NO2,NO3} default 0 => bare SuperFast chemistry unchanged.
Couplings (ext/AerosolExt.jl, mirroring the GEOS-Chem templates):
  * SuperFast<->CloudChemistryFixedpH: aqueous S(IV)+H2O2 -> k_cld1 (SO2+H2O2->SO4);
    p_NH3 now fed from the mechanism's real NH3.
  * SuperFast<->AerosolDistribution: S_t-driven k_het_* (kinetic-limit uptake).

SF<->NEI coupling gains SO2/SULF->SO4/NH3/NH3_FERT emissions (MW_SULF=98.079e-3),
Vector-of-pairs translate table (duplicate left species preserved).

H2O treatment: H2O stays a met-coupled isconstantspecies PARAMETER (the
GEOS-Chem met-driven fixed-species design); SuperFast<->GEOSFP couple2 keeps
param_to_var(:T,:P,:H2O) + RH-driven c.H2O; IsorropiaOp reads it through its
tri-level path (already on this base).

IsorropiaOp perf + diagnostics: cell loop Threads.@threads :static with per-thread
obscaches (du bitwise-identical regardless of thread count), skip gate
(<1e-4 ppb combined inorganic N), _iso_ternary nbisect 60->30 + warm +-1.5-decade
bracket + width break (equivalence vs the exact solve <=6.4e-6
rel at trace extremes = <2e-6 ppb absolute; physically negligible vs k_mt), and a
per-sim-hour non-convergence counter (@info).

N2O5/NO3 are dead-by-construction in reduced SuperFast (no gas-phase production;
IC=0 stays 0) — uptake channels wired but inert until a nighttime-NOx
mini-mechanism lands.

Tests: new superfast_aerosol_test.jl (inert defaults, bare-SuperFast O3
equivalence [baseline filled next commit], cloud S conservation, S_t/k_het
observed exposure, triple-coupling compile).

The GC<->NEI Dict->Vector hunk and the tri-level H2O read slice are submitted
with the NEI-31-pair and ISORROPIA PRs respectively.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ory checkpoints)

Measured on the reduced SuperFast baseline: hourly bare-SF box O3. The additions
are inert (zero-rate/constant with defaults) so bare-SuperFast chemistry is
unchanged. Checkpoints at h2/h4/h8 replace the 24h endpoint, which decays to
~1e-7 ppb where adaptive-step noise dominates relative comparisons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ip gate

* SuperFast cloud-couple2 FC 1.0 -> 0.15: same interim climatological-mean fix
  as the GEOS-Chem block (FC=1.0 over-depleted H2O2).
* ISORROPIA skip gate (b): compositions with no aerosol-forming anion material
  (SO4 + total nitrate + existing NH4 < 1e-3 ppb) have a trivial all-gas
  equilibrium and are exactly the degenerate compositions where the
  activity/water fixed point burned all 40 outer iterations without converging
  (a large fraction of early solves in these cells); their |du| bound is
  k_mt*1e-3 ~ 3e-6 ppb/s ~ 0.

The GC cloud FC hunk is in the het/cloud coupling PR.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…olver

The SuperFast aerosol-species addition grows the state vector 12->19; update the
two coupled-system unknowns-count assertions accordingly (breaking, minor bump).
superfast_aerosol_test.jl used the OrdinaryDiffEq umbrella (not a declared test
dep); it only needs Rosenbrock23, which OrdinaryDiffEqRosenbrock (already in
[extras]/[targets]) provides.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cloud/het couple2s reference SuperFast's T/P in variable form by design
(they are bound by the met coupling in production; see the NOTE in
ext/AerosolExt.jl), so coupling them WITHOUT a met source is intentionally
unbalanced — newer MTK correctly rejects it. Add SFTestMet, a minimal met
stand-in mirroring the production GEOSFP binding (param_to_var(c,:T,:P) +
connector equations), to the three standalone-couple testitems. The added testitems assert all three couples compile (19 unknowns) and check in-cloud S conservation.

Two MTK v11 compat fixes in the same tests: convert(System, csys) already
compiles (an outer mtkcompile now raises 'double simplification'); positional
prob.u0 indexing is no longer guaranteed to match unknowns(sys) ordering, so
u0 overrides and readouts use symbolic indexing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…uperFast + GEOS-Chem

Maps the inline (elevated) point-source emission variables (SO2/NO/NO2/CO/NH3,
already in kg/kg/s mixing-ratio rate at the plume-injection layer) into both
mechanisms with the same uconv/MW pattern as the surface NEI coupling. The
vertical placement lives entirely in the emissions System's wrapper, so these
couplings are layer-agnostic. Companion to the NEI2016InlineEmis feature in
EarthSciData (feature + validation details there).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@xk-y
xk-y force-pushed the pr/inline-couple2 branch from 9ee6599 to 0f2a94c Compare July 11, 2026 02:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant