Near-Field Module
Building-wake dispersion for short stacks: a drop-in replacement for WeatherAverager for receptors close to
the release. See the near-field example and
prototyping/near_field_dispersion.tex
for the equations (tagged NF-1 to NF-12 in the code comments).
ensi_g14_calculator.near_field
Near-field (building-wake) dispersion for short stacks, see prototyping/near_field_dispersion.tex.
Classes
Building
dataclass
Rectangular building most influencing the flow near the release (SRS-19 Sec. 3.3). Only its dimensions and orientation are used; the wake is assumed to start at the source.
building = Building(height=20 * u.m, length=60 * u.m, width=25 * u.m, orientation_deg=30.0)
building.projected_area(30.0) # wind along the long axis: 20 m x 25 m = 500 m^2
Functions
crosswind_width(plume_direction_deg)
Width of the building seen by the wind, W_c(theta).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plume_direction_deg
|
float or array, direction the wind blows towards (deg clockwise from north) |
required |
Returns:
| Type | Description |
|---|---|
|
crosswind width with units (length) |
projected_area(plume_direction_deg)
Cross-sectional area A(theta) = H_B * W_c(theta) of the building facing the wind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plume_direction_deg
|
float or array, direction the wind blows towards (deg clockwise from north) |
required |
Returns:
| Type | Description |
|---|---|
|
area with units (length^2) |
with_height(height)
Return a copy with height filled in (used to default H_B to SourceParams.H_G).
NearFieldConfig
dataclass
Building and options of the near-field model, for the scenario runners (picklable, one per chimney).
near_field = NearFieldConfig(Building(length=60 * u.m, width=25 * u.m), wind_speed_factor=0.7)
evaluator = ScenarioEvaluator(source, orography, near_field=near_field)
evaluator.averager.submersion_model = "pki_surrogate"
NearFieldWeatherAverager
Bases: WeatherAverager
Drop-in replacement for WeatherAverager for receptors close to a short stack in a building wake.
building = Building(length=60 * u.m, width=25 * u.m, orientation_deg=30.0) # height: source.H_G
averager = NearFieldWeatherAverager(orography, source, building)
chi = averager.average_dispersion_at_points(x, y, z, weather)
Affects the physical dispersion chi_K (inhalation, dry deposition), the exact PKI submersion (which integrates chi_K over the cloud) and the PKI surrogate (submersion_model = "pki_surrogate", through a local power law). The washout uses the same wind speeds (NF-8) and plume height (NF-7), but keeps the G-14 sigma_y0 (no wake spreading). The G-14 submersion polynomial (chi_K,S, >= 200 m, Vogt plume) is still returned by average_dispersion, but the scenario runners refuse to use it for doses with the near-field model.
Functions
__init__(orography, source_params, building, *, low_wind_meander=False, gradual_plume_rise=True, wind_speed_factor=1.0, stretched_string=True, recorder=NULL_RECORDER)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
orography
|
Orography
|
Orography instance |
required |
source_params
|
SourceParams
|
SourceParams of the stack |
required |
building
|
Building
|
Building most influencing the flow; if its height is None, source_params.H_G is used. |
required |
low_wind_meander
|
bool
|
add the low-wind meander increments (NF-4, NF-5); lowers concentrations. |
False
|
gradual_plume_rise
|
bool
|
evaluate the momentum plume rise at min(x, 200 m) (NF-7). |
True
|
wind_speed_factor
|
float
|
f_U > 0 multiplying every wind speed, e.g. < 1 for urban slow-down (NF-8). |
1.0
|
stretched_string
|
bool
|
receptors (average_dispersion) see the ground-level component at the slant distance from the stack exit, S = sqrt(x^2 + (z - H_a)^2), instead of at x and at their height above the ground (NF-12). Not used for the PKI cloud. |
True
|
recorder
|
IntermediateRecorder
|
IntermediateRecorder for introspection. |
NULL_RECORDER
|
Functions
make_averager(orography, source_params, near_field=None, recorder=NULL_RECORDER)
WeatherAverager (plain G-14) if near_field is None, else the near-field averager it describes.
Modules
building
Classes
Building
dataclass
Rectangular building most influencing the flow near the release (SRS-19 Sec. 3.3). Only its dimensions and orientation are used; the wake is assumed to start at the source.
building = Building(height=20 * u.m, length=60 * u.m, width=25 * u.m, orientation_deg=30.0)
building.projected_area(30.0) # wind along the long axis: 20 m x 25 m = 500 m^2
crosswind_width(plume_direction_deg)
Width of the building seen by the wind, W_c(theta).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plume_direction_deg
|
float or array, direction the wind blows towards (deg clockwise from north) |
required |
Returns:
| Type | Description |
|---|---|
|
crosswind width with units (length) |
projected_area(plume_direction_deg)
Cross-sectional area A(theta) = H_B * W_c(theta) of the building facing the wind.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
plume_direction_deg
|
float or array, direction the wind blows towards (deg clockwise from north) |
required |
Returns:
| Type | Description |
|---|---|
|
area with units (length^2) |
with_height(height)
Return a copy with height filled in (used to default H_B to SourceParams.H_G).
near_field_averager
Classes
NearFieldWeatherAverager
Bases: WeatherAverager
Drop-in replacement for WeatherAverager for receptors close to a short stack in a building wake.
building = Building(length=60 * u.m, width=25 * u.m, orientation_deg=30.0) # height: source.H_G
averager = NearFieldWeatherAverager(orography, source, building)
chi = averager.average_dispersion_at_points(x, y, z, weather)
Affects the physical dispersion chi_K (inhalation, dry deposition), the exact PKI submersion (which integrates chi_K over the cloud) and the PKI surrogate (submersion_model = "pki_surrogate", through a local power law). The washout uses the same wind speeds (NF-8) and plume height (NF-7), but keeps the G-14 sigma_y0 (no wake spreading). The G-14 submersion polynomial (chi_K,S, >= 200 m, Vogt plume) is still returned by average_dispersion, but the scenario runners refuse to use it for doses with the near-field model.
__init__(orography, source_params, building, *, low_wind_meander=False, gradual_plume_rise=True, wind_speed_factor=1.0, stretched_string=True, recorder=NULL_RECORDER)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
orography
|
Orography
|
Orography instance |
required |
source_params
|
SourceParams
|
SourceParams of the stack |
required |
building
|
Building
|
Building most influencing the flow; if its height is None, source_params.H_G is used. |
required |
low_wind_meander
|
bool
|
add the low-wind meander increments (NF-4, NF-5); lowers concentrations. |
False
|
gradual_plume_rise
|
bool
|
evaluate the momentum plume rise at min(x, 200 m) (NF-7). |
True
|
wind_speed_factor
|
float
|
f_U > 0 multiplying every wind speed, e.g. < 1 for urban slow-down (NF-8). |
1.0
|
stretched_string
|
bool
|
receptors (average_dispersion) see the ground-level component at the slant distance from the stack exit, S = sqrt(x^2 + (z - H_a)^2), instead of at x and at their height above the ground (NF-12). Not used for the PKI cloud. |
True
|
recorder
|
IntermediateRecorder
|
IntermediateRecorder for introspection. |
NULL_RECORDER
|
NearFieldConfig
dataclass
Building and options of the near-field model, for the scenario runners (picklable, one per chimney).
near_field = NearFieldConfig(Building(length=60 * u.m, width=25 * u.m), wind_speed_factor=0.7)
evaluator = ScenarioEvaluator(source, orography, near_field=near_field)
evaluator.averager.submersion_model = "pki_surrogate"
Functions
make_averager(orography, source_params, near_field=None, recorder=NULL_RECORDER)
WeatherAverager (plain G-14) if near_field is None, else the near-field averager it describes.
wake
Functions
wake_sigma_increments(x, U, A)
Squared increments of sigma_y and sigma_z due to building-wake turbulence (NF-2, NF-3).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
downwind distance from the release, with units (length) |
required | |
U
|
wind speed upwind of the building at building height, with units (length/time) |
required | |
A
|
projected cross-sectional area of the building, with units (length^2) |
required |
Returns:
| Type | Description |
|---|---|
|
tuple (Delta sigma_y^2, Delta sigma_z^2), with units (length^2) |
low_wind_sigma_increments(x, U)
Squared increments of sigma_y and sigma_z due to plume meander at low wind speed (NF-4, NF-5). These always lower concentrations; off by default in NearFieldWeatherAverager.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
downwind distance from the release, with units (length) |
required | |
U
|
wind speed, with units (length/time) |
required |
Returns:
| Type | Description |
|---|---|
|
tuple (Delta sigma_y^2, Delta sigma_z^2), with units (length^2) |
apply_cavity_floor(sigma_y, sigma_z, length_scale, K=1.0 * u.m)
Enforce Sigma_y * Sigma_z >= length_scale * K (NF-6) by scaling both sigmas by the same factor.
The centreline value of the reflected ground-level plume is 1 / (pi U Sigma_y Sigma_z); SRS-19 eq. 8 bounds the concentration in the cavity zone by 1 / (pi U l_B K). The floor therefore caps the plume at the SRS-19 cavity value and is inactive wherever the Gaussian is already more dilute.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sigma_y
|
horizontal dispersion parameter, with units (length) |
required | |
sigma_z
|
vertical dispersion parameter, with units (length) |
required | |
length_scale
|
l_B = min(building height, crosswind width), with units (length) |
required | |
K
|
SRS-19 constant, 1 m |
1.0 * m
|
Returns:
| Type | Description |
|---|---|
|
tuple (sigma_y, sigma_z) after the floor, with units (length) |
wake_sigmas(sigma_y0, sigma_z0, x, U, A, length_scale, *, low_wind_meander=False)
Dispersion parameters of the ground-level plume in the building wake: (NF-1) then (NF-6).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sigma_y0
|
G-14 (Vogt) ground-level sigma_y at x, with units (length) |
required | |
sigma_z0
|
G-14 (Vogt) ground-level sigma_z at x, with units (length) |
required | |
x
|
downwind distance, with units (length) |
required | |
U
|
wind speed at building height, with units (length/time) |
required | |
A
|
projected building area, with units (length^2) |
required | |
length_scale
|
l_B = min(building height, crosswind width), with units (length) |
required | |
low_wind_meander
|
whether to add the low-wind meander increments (NF-4, NF-5) |
False
|
Returns:
| Type | Description |
|---|---|
|
tuple (Sigma_y, Sigma_z), with units (length) |