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.

Puff — forward simulation

Gaussian puff — forward simulation

This notebook exercises the time-resolved Gaussian-puff forward model in plumax.gauss_puff. Unlike the steady plume, the puff model releases a sequence of instantaneous puffs at fixed cadence; each puff travels with the (possibly time-varying) wind and spreads as a 3-D Gaussian. The total concentration field is the superposition of all active puffs.

We’ll cover: (1) a constant-wind scenario with ground-level snapshots, (2) a vertical cross-section, (3) a downwind transect evolving over time, (4) a stability-class sweep, and (5) a time-varying wind scenario that the steady plume cannot represent. Refer to 00_gaussian_puff_derivation.md for the mathematical background.

1. Constant wind — ground-level snapshots

Steady 5 m/s wind from the west, stability class C (slightly unstable), emission rate 0.1 kg/s, 2-Hz puff release. We pick a domain tight around the downwind plume so the plots aren’t dominated by empty space.

<xarray.Dataset> Size: 40MB
Dimensions:               (time: 61, x: 151, y: 61, z: 16)
Coordinates:
  * time                  (time) float32 244B 0.0 2.0 4.0 ... 116.0 118.0 120.0
  * x                     (x) float64 1kB -30.0 -25.13 -20.27 ... 695.1 700.0
  * y                     (y) float64 488B -120.0 -116.0 -112.0 ... 116.0 120.0
  * z                     (z) float64 128B 0.0 4.0 8.0 12.0 ... 52.0 56.0 60.0
Data variables:
    concentration         (time, x, y, z) float32 36MB 0.0 0.0 ... 6.588e-09
    column_concentration  (time, x, y) float64 4MB 0.0 0.0 ... 1.022e-06
    wind_speed            (time) float32 244B 5.0 5.0 5.0 5.0 ... 5.0 5.0 5.0
    wind_direction        (time) float32 244B 270.0 270.0 270.0 ... 270.0 270.0
Attributes:
    title:                     Gaussian puff dispersion (JAX + diffrax)
    source_x:                  0.0
    source_y:                  0.0
    source_z:                  2.0
    stability_class:           C
    dispersion_scheme:         pg
    release_frequency:         2.0
    release_interval:          0.5
    n_puffs:                   240
    background_concentration:  0.0
    ou_sigma_fluctuations:     0.0
    ou_correlation_time:       0.0

The dataset holds the full 4-D concentration(time, x, y, z) field plus a 3-D column_concentration(time, x, y). The attrs block records the scenario metadata (source, stability class, dispersion scheme).

Ground-level evolution

<Figure size 1680x400 with 5 Axes>

Each snapshot shows a lumpy “trail” of puffs stretching downwind — near the source the individual puff peaks are still resolved (release interval 0.5 s, puff-width growing from ~0.5 m), but by a few hundred metres the puffs overlap into a smooth plume.

Column integral

The column-integrated concentration ∫ C dz [kg/m²] — what a remote-sensing instrument in the vertical would see — smooths over the z-structure.

<Figure size 1680x400 with 5 Axes>

2. Vertical cross-section along the plume centreline

Slice at y = 0 showing how mass spreads vertically as it travels downwind. Ground reflection keeps the concentration highest near z = 0 for a low-elevated source.

<Figure size 900x350 with 2 Axes>

3. Downwind transect vs. time

Following the concentration at a fixed downwind receptor over the simulation window gives the arrival-and-decay curve every in-situ sensor sees. The puff field builds up as successive puffs pass the receptor, and approaches a steady value once the source has been running long enough for puffs born “outside” the domain of interest.

<Figure size 900x400 with 1 Axes>

4. Stability-class sweep

For the same wind and emission rate, stability class controls how aggressively puffs spread. Class A (very unstable) has the widest puffs and lowest centreline concentration; class F (very stable) keeps the plume narrow and hot.

<Figure size 1300x700 with 6 Axes>

5. Time-varying wind

Diffrax-driven cumulative integration lets us advect puffs under arbitrary wind histories. Here the wind direction sweeps 30° during the simulation — a “wind shift” event — and the plume bends accordingly. The steady plume model cannot represent this scenario at all.

<Figure size 1650x400 with 5 Axes>

Older puffs were advected under the earlier (more westerly) wind and sit at lower y; newer puffs track the rotated direction. The bent trail is a signature diagnostic of non-stationarity and motivates the state-estimation workflow in Puff — state estimation.

What next?