Sectors, stability and the wind rose
The geometric and statistical description of the wind: how the compass is divided, how atmospheric stability is classified, and how the two are combined into a joint frequency distribution.
Sector geometry
AtmosphericDispersion.CARDINAL_16 — Constant
CARDINAL_16Names of the sixteen cardinal sectors, in the order SectorGrid(16) indexes them: clockwise from north.
AtmosphericDispersion.SectorGrid — Type
SectorGrid(n)A wind rose divided into n equal angular sectors.
Sectors are indexed 1:n clockwise from north, with sector 1 centred on north. For the usual n = 16 this reproduces the cardinal sectors: sector 1 is N and spans bearings 348.75°–11.25°, sector 2 is NNE, and so on. This is the convention of ADMS meteorological input and of the joint-frequency tables that long-term dispersion calculations are built on.
n must be even, so that every sector has an opposite (see opposite); converting a wind rose between the "blowing from" and "blowing toward" conventions is a rotation by n ÷ 2 sectors.
Centring sector 1 on north rather than starting it there is not cosmetic. It places the cardinal directions at sector centres, maximally far from a sector boundary, so binning them cannot be decided by floating-point round-off.
Examples
julia> g = SectorGrid(16);
julia> sector_of(g, deg2rad(0.0)), sector_of(g, deg2rad(90.0))
(1, 5)
julia> rad2deg(sector_bearing(g, 5))
90.0AtmosphericDispersion.bearing — Method
bearing(east, north)Compass bearing of the point (east, north) as seen from the origin, in radians clockwise from north, wrapped to [0, 2π).
The arguments are ground-plane displacements in the geographic frame, not the plume-aligned frame: east is the displacement towards the east, north towards the north. The origin returns a bearing of zero.
AtmosphericDispersion.nsectors — Method
nsectors(grid)Number of sectors in grid.
AtmosphericDispersion.opposite — Method
opposite(grid, k)Index of the sector diametrically opposite k.
Wind blowing from sector k blows towards opposite(grid, k), which is what makes this the conversion between the two wind-direction conventions.
AtmosphericDispersion.sector_bearing — Method
sector_bearing(grid, k)Bearing of the centre of sector k, in radians clockwise from north.
AtmosphericDispersion.sector_bounds — Method
sector_bounds(grid, k)Bearings of the two edges of sector k as a tuple (lower, upper), in radians clockwise from north. For sector 1 the lower edge wraps, so lower > upper.
AtmosphericDispersion.sector_name — Method
sector_name(grid, k)Cardinal name of sector k when grid has sixteen sectors, otherwise a bearing label such as "123.8°".
AtmosphericDispersion.sector_of — Method
sector_of(grid, β)
sector_of(grid, east, north)Index of the sector of grid containing the bearing β (radians clockwise from north), or containing the point (east, north).
Binning rounds to the nearest sector centre rather than truncating a ratio. A bearing at a sector centre therefore bins exactly, because the ratio is an integer and a round-off of an ulp either way still rounds to it. This is what makes the cardinal directions safe: they lie at the centres.
On a sector boundary the ratio is a half-integer, the tie rule takes the sector of higher bearing, and an ulp of round-off can place it either side. That is unavoidable — a boundary bearing is generally not representable — and harmless, since the two sectors meeting there are equally defensible. Do not build a result on which side a boundary falls.
AtmosphericDispersion.sector_width — Method
sector_width(grid)Angular width of one sector, in radians.
Stability classes
AtmosphericDispersion.PASQUILL_CLASSES — Constant
PASQUILL_CLASSESThe six Pasquill classes in order, PASQUILL_A through PASQUILL_F. Sums over stability classes iterate this tuple.
AtmosphericDispersion.PasquillClass — Type
PasquillClassPasquill–Gifford atmospheric stability class, PASQUILL_A (very unstable) through PASQUILL_F (moderately stable).
The dispersion parameters, the wind-speed profile exponent and the plume-rise correlations are all keyed by this class.
AtmosphericDispersion.classindex — Method
classindex(class)Position of class in PASQUILL_CLASSES, 1 for PASQUILL_A through 6 for PASQUILL_F. This is the index into any table keyed by stability class.
AtmosphericDispersion.letter — Method
letter(class)The letter naming a PasquillClass.
AtmosphericDispersion.pasquill — Method
pasquill(c)The Pasquill class named by the letter c, given as a Char or a single-character AbstractString, case-insensitively.
Tabulated coefficients are conventionally published against the letters, so parsing them is part of reading any input table.
Examples
julia> pasquill('D') === PASQUILL_D
true
julia> pasquill("f") === PASQUILL_F
trueWind rose
AtmosphericDispersion.BlowingFrom — Type
BlowingFrom()The direction a wind is blowing from: the meteorological convention, and what ADMS reads from the PHI field of a .met file. A westerly — 270° — blows from the west towards the east. Measured wind roses are published this way.
AtmosphericDispersion.BlowingToward — Type
BlowingToward()The direction a wind is blowing towards. This is the sense the long-term sector-averaged dispersion formula needs, because its directional weight asks how often the plume reaches the receptor's sector.
AtmosphericDispersion.WindDirectionConvention — Type
WindDirectionConventionWhich of the two mutually inverse readings a tabulated wind direction carries. Subtypes are BlowingFrom and BlowingToward.
The distinction is a 180° rotation of the entire rose. Getting it wrong rotates a long-term dispersion field by half a turn while leaving every magnitude, every sum rule and every unit intact, so nothing downstream can detect the error. The convention is therefore a required argument of the WindRose constructor, never a default.
AtmosphericDispersion.WindRose — Type
WindRose(grid, frequencies, convention; stability)Joint frequency distribution of wind direction and atmospheric stability over the sectors of grid.
frequencies[k] is the fraction of the time the wind lies in sector k, read in the sense given by convention — either BlowingFrom() or BlowingToward(). Frequencies must be non-negative and sum to one.
stability is the distribution over Pasquill classes conditional on the sector: either a 6-element vector, when the stability distribution is taken to be the same in every sector, or an nsectors(grid) × 6 matrix whose rows each sum to one. Column i corresponds to PASQUILL_CLASSES[i].
Whatever convention the input carries, a WindRose stores blowing-towards frequencies internally, so the formulae that consume it cannot be fed the wrong sense. Query either reading with frequency_toward and frequency_from.
Examples
julia> grid = SectorGrid(16);
julia> rose = WindRose(grid, fill(1/16, 16), BlowingFrom(); stability = fill(1/6, 6));
julia> frequency_toward(rose, 1) ≈ 1/16
trueAtmosphericDispersion.frequency_from — Method
frequency_from(rose, k)Fraction of the time the wind blows from sector k, the reading a measured wind rose and an ADMS .met file carry.
AtmosphericDispersion.frequency_toward — Method
frequency_toward(rose, k)Fraction of the time the wind blows towards sector k — the directional weight the long-term sector-averaged dispersion formula applies to a receptor lying in sector k.
AtmosphericDispersion.grid — Method
grid(rose)The SectorGrid the rose is defined on.
AtmosphericDispersion.stability_fraction — Method
stability_fraction(rose, k, class)Fraction of the time Pasquill class prevails, conditional on the wind blowing towards sector k.