Skip to content

prime

prime

PyAERMOD PRIME downwash helpers.

Utilities on top of bpip.py for building-interaction modeling:

  • gep_stack_height: EPA Good Engineering Practice stack height per 40 CFR 51.100(ii). Stacks shorter than GEP are subject to building downwash; stacks at GEP or above are exempt.

  • cavity_length: Snyder (1981) / EPA PRIME cavity length estimate used to decide whether a receptor falls inside the wake cavity.

  • in_cavity_region: True if a stack at (sx, sy, stack_height) is inside the building cavity for a given wind direction.

  • apply_bpip_to_project: compute BPIP 36-sector arrays for each point source in an AERMODProject and populate the source fields.

  • suggest_downwash_config: given a project, warn about sources that (a) are nominally "downwashed" but stack height > GEP, or (b) are below GEP but have no building data set.

DownwashAssessment dataclass

Result of evaluating a point source against nearby buildings.

gep_stack_height

gep_stack_height(building_height: float, lesser_dim: float) -> float

Return GEP stack height in meters.

lesser_dim is the lesser of building height or projected building width (also called "L"). Formula: max(65, BH + 1.5 * L).

For a complex building, use the maximum BH + 1.5 L across all relevant wind sectors, or call gep_from_building below.

gep_from_building

gep_from_building(building: Building, stack_x: float, stack_y: float) -> float

Compute GEP stack height from a Building + stack location.

Per 40 CFR 51.100(ii), GEP is the MAXIMUM over all wind directions of BH + 1.5 * L, where L is the lesser of building height and the projected building width for that direction. We compute the per-direction GEP for each of the 36 BPIP sectors and return the maximum — this is the correct formulation.

(Prior versions computed L using max projected width across all sectors and then applied min(bh, max_width) once, which underestimates GEP for buildings that are tall and narrow from some wind directions but tall and wide from others.)

cavity_length

cavity_length(building_height: float, building_width: float) -> float

Simplified PRIME cavity length, meters.

PRIME uses Lc = A * H * (W/H)^0.3 / (1 + B * (W/H)) with A=1.8, B=0.24 for a rectangular building with height H and width W (across-wind). This is an approximation sufficient for screening; AERMOD's PRIME module does the rigorous computation at runtime.

in_cavity_region

in_cavity_region(stack_x: float, stack_y: float, stack_height: float, building: Building, wind_direction_deg: float) -> bool

True if the stack sits inside the projected wake cavity.

Uses the building centroid + 36-sector width to estimate the downwind cavity extent. A stack whose (horizontal distance from building) < cavity_length AND whose height < building_height is "in cavity".

assess_source_downwash

assess_source_downwash(point_source: Any, buildings: Iterable[Building]) -> DownwashAssessment

Evaluate a source against a collection of Buildings.

Accepts PointSource, AreaSource, or VolumeSource. For non-point sources the "stack height" in the GEP rule is the release height. Returns a DownwashAssessment capturing the GEP stack height, whether the source is below it, and which building (if any) most likely influences the plume.

apply_bpip_to_project

apply_bpip_to_project(project: Any, buildings: List[Building], *, only_below_gep: bool = True) -> List[DownwashAssessment]

Compute BPIP arrays for every PointSource in the project.

For each source, pick the single building with the largest interaction (shortest distance within 5L), run BPIPCalculator, and assign the 36-value arrays to the source.

When only_below_gep=True (default), sources already at or above GEP height are left alone (per EPA guidance, they're exempt).

Returns the list of DownwashAssessments, one per source.

suggest_downwash_config

suggest_downwash_config(project: Any, buildings: List[Building]) -> List[str]

Return human-readable warnings about the project's downwash setup.

Flags: - Source below GEP with no building data assigned. - Source at/above GEP with building arrays set (wasted work). - Mixed array lengths (must be 36).