Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Gaussian plume — forward simulation and prior predictive

Forward simulation of a steady-state Gaussian plume

This notebook exercises the forward model in plumax.gauss_plume: a steady-state Gaussian plume with Briggs-McElroy-Pooler dispersion coefficients, ground reflection, and wind-frame rotation. We’ll render a few diagnostic views (horizontal column, vertical centerline slice, crosswind Gaussian profile), sweep over the six Pasquill-Gifford stability classes to see how dispersion scales, and finish by running the NumPyro model in prior-predictive mode to visualise the range of plumes implied by our emission-rate prior.

The fit-and-infer companion notebooks (02, 03) pick up from here: 02_emission_rate_parameter_estimation inverts a downwind transect to recover Q, and 03_plume_state_estimation treats Q as a time-varying latent state recovered from a sequence of observations.

1. Run a single forward simulation

Set up a canonical scenario: a ground-level leak of 0.1 kg/s from a 2 m stack, with a 5 m/s westerly wind (meteorological convention: wind_direction = 270° means wind from the west). Neutral stability (class D) is a good default for a daylight scenario with moderate wind.

<xarray.Dataset> Size: 4MB
Dimensions:               (x: 251, y: 181, z: 21)
Coordinates:
  * x                     (x) float64 2kB -50.0 -45.0 ... 1.195e+03 1.2e+03
  * y                     (y) float64 1kB -180.0 -178.0 -176.0 ... 178.0 180.0
  * z                     (z) float64 168B 0.0 4.0 8.0 12.0 ... 72.0 76.0 80.0
Data variables:
    concentration         (x, y, z) float32 4MB 0.0 0.0 ... 4.797e-08 4.055e-08
    column_concentration  (x, y) float64 363kB 0.0 0.0 ... 1.201e-05 1.15e-05
Attributes: (12/14)
    title:                     Steady-state Gaussian plume (JAX)
    emission_rate:             0.1
    emission_rate_units:       kg/s
    source_x:                  0.0
    source_y:                  0.0
    source_z:                  2.0
    ...                        ...
    wind_direction:            270.0
    wind_direction_units:      degrees from North (meteorological)
    wind_u:                    5.0
    wind_v:                    9.184850993605148e-16
    stability_class:           D
    background_concentration:  0.0

Peak concentration:        8.606e-04 kg/m^3
Peak column concentration: 3.444e-03 kg/m^2

2. Horizontal column view

Summing the concentration along z gives the column density the satellite would retrieve. The plume is a characteristic fan: narrow near the source, broadening with downwind distance as σ_y(x) grows.

<Figure size 1000x450 with 2 Axes>

3. Vertical centerline slice and crosswind profile

A vertical slice along the plume centerline (y = 0) shows the ground-reflected vertical Gaussian — the concentration spreads upward from the stack and is reflected at z = 0, keeping all the mass in the boundary layer. The crosswind profile at a downwind distance of 500 m is a Gaussian in y, whose width is σ_y(500 m).

<Figure size 1200x430 with 3 Axes>

4. Stability-class sweep

The six Pasquill-Gifford classes span from A (very unstable, strong daytime convection) to F (very stable, clear calm nights). Unstable classes disperse pollutants aggressively, spreading the plume quickly and lowering peak concentration; stable classes produce long, thin plumes with high peak near the source. Below we plot the centerline (y = 0, z = 0) concentration as a function of downwind distance for all six classes.

<Figure size 1000x450 with 1 Axes>

5. Prior-predictive check with NumPyro

The gaussian_plume_model defined in plumax.gauss_plume.inference wraps the forward model with a LogNormal emission-rate prior and a HalfNormal background prior. Running the model forward with observations=None samples predicted concentrations for each prior draw; this is a prior-predictive check, a useful sanity test that our priors are neither far too loose nor too tight for the scenario.

Below we plot:

  1. The marginal prior over the emission rate Q (LogNormal centred on 0.1 kg/s).

  2. The induced prior over ground-level concentrations along the transect, shown as the 5–95 % envelope and the median.

<Figure size 1200x430 with 2 Axes>

Summary

We have a fully differentiable, JIT-compiled forward model for a steady-state Gaussian plume, wrapped as an xarray.Dataset for diagnostic plotting and as a NumPyro-compatible function for Bayesian workflows. In the next notebook we invert this model — given a set of downwind concentrations, recover the emission rate Q. The one after that treats Q as a time-varying state in a random-walk state-space model.