Concentration C(x,t) in the stream follows the 1-D advection–dispersion–reaction equation used for surface-water solute transport:
∂C/∂t = -u·∂C/∂x + D·∂²C/∂x² - k·C
u = stream velocity, D = dispersion coefficient
k = first-order degradation/removal rate
Rain that falls on the treated field washes a fraction of the applied dose into surface runoff. Only some of that mass reaches the channel — a vegetative buffer strip intercepts and infiltrates the rest, following a saturating exponential:
f_runoff = clamp(rain/50, 0, 1) × 0.15
Retention(w) = 1 - e^(-w / 10 m)
Mass entering stream = applied mass × f_runoff × (1 - Retention)
That mass is injected as a loading pulse at the field edge (x=0) and solved forward explicitly on a 60-cell grid (drag the top channel view to scroll along its 600 m length), advecting and spreading downstream while decaying at each fungicide class's own rate. Risk to aquatic life is read as a Hazard Quotient against a 72 h algal LC50:
HQ = C_peak / LC50
HQ ≥ 1 → acutely toxic exposure at the monitoring station
- Triazoles degrade slowly (weeks-scale half-life) but are only moderately toxic to algae.
- Strobilurins degrade faster but are markedly more algicidal per unit concentration.
- Copper-based fungicides don't biodegrade — they're removed mainly by binding to sediment — and are toxic to algae at very low concentrations, since copper is itself an algicide.
Numerics note: the explicit upwind-advection / central-diffusion scheme needs the combined stability bound courant + 2·diffusion-number ≤ 1, not the two checked separately — verified in a standalone script that the separate-limit guard alone drifts into a growing checkerboard and eventually overflows once the per-step time exceeds ~0.0036 h. This engine's substepper enforces the combined bound directly.