Kernels, building downwash and OpenMP updates

Repository revision: 8 September 2026. This page covers kernels CCA1, CCA2 and CCA3, their bandwidths, and building-downwash behavior. All source-code references use omp_parallel; source and report links follow the repository directory layout.

Implemented: gradual AGELIM release

AGELIM > 0 now defines the duration of a gradual release of the horizontal grid-size cap for CCA2/3. At emission the bands are limited to min(h_nominal, abs(OUTGRID)); they approach the nominal bands as particle age approaches AGELIM. This changes smoothing without changing particle motion or replacing the kernel with cell counting.

For 0 <= age < AGELIM:
    u = max(0, min(1, age / AGELIM))
    w = u*u*(3 - 2*u)
    h_limited = min(h_nominal, abs(OUTGRID))
    h_effective = h_limited + (h_nominal - h_limited)*w
For age >= AGELIM:
    h_effective = h_nominal

The rule is applied independently to HX and HY, after BWMAX for CCA3. HZ is unchanged. Behavior for AGELIM <= 0 is preserved, including the historical grid-size cap at exactly zero age when AGELIM=0. The current input's AGELIM=0 leaves positive-age particles unaffected.

The blend keeps the original grid-size anchor. CCA2 retains the inherent concentration discontinuity at the edge of a uniform kernel even though its bandwidth release is smooth.

Illustrative horizontal band: the former cap jumps at 1800 seconds, while the cubic release approaches the nominal band continuously.
Illustration with h_nominal=20+3*sqrt(age) m, OUTGRID=50 m and AGELIM=1800 s. These values illustrate the rule; they are not new input defaults.

Implementation: code/omp_parallel/outputk.f90. The thread-private AGEW variable is computed per particle before normalization and receptor scanning. The serial implementations also restore the nominal CCA2 bands for each particle while the positive-age-limit feature is active, avoiding reuse of the previous particle's reduced bands.

Input parameter reference · Implementation report · Source patch

Documented kernels: CCA1, CCA2 and CCA3

CCAProfileNominal scalesActive routine
1Gaussian; direct support limited by SIGNUMSIGMA_H, SIGMA_ZOUTPUT
2Uniform box; experimentalBMFU, output grid and mixing heightOUTPUTK
3Parabolic ellipsoidAge-dependent H* coefficients and BWMAXOUTPUTK

Dispatch: code/omp_parallel/lapmod.for; sampling: code/omp_parallel/output.f90 and code/omp_parallel/outputk.f90.

CCA3: parabolic-kernel bands

CCA3 nominal bands, with age t in seconds:
HX = min(HXA + HXB*sqrt(t) + HXC*t, BWMAX(1))
HY = min(HYA + HYB*sqrt(t) + HYC*t, BWMAX(2))
HZ = min(HZA + HZB*sqrt(t),         BWMAX(3))

The bands are support semi-axes, not the standard deviations of the smoothing kernel. For the normalized parabolic ellipsoid in free space, the standard deviation on each axis is h/sqrt(7). Comparing kernels at equal nominal bands is therefore different from comparing them at equal smoothing variance.

Implementation limitations

  • CCA2 on discrete receptors lacks the vertical cutoff and reflection guard of its regular-grid path. The AGELIM change does not fix this issue.
  • CCA1 truncates the Gaussian without exact finite-support renormalization; its direct/reflected cutoff details differ slightly between grid and discrete paths.

Building downwash: active PRIME2 path

Buildings affect particle transport through the PRIME2 implementation. Inside a building wake the model calculates a deficit of horizontal mean wind and enhancements of lateral and vertical turbulent motion. The effect is separate from stack-tip downwash: LSTD controls stack-tip downwash, while BUILDINGS_FILE supplies the buildings for the PRIME2 path.

Set BUILDINGS_FILE = NO to disable buildings, or provide a building-geometry file. Rectangular footprints use four vertices; streamlined structures such as tanks use a width and center. See the building-file format. The theory page explains the implemented transport changes.

  1. When NBUILDINGS > 0, PMOVE samples the meteorological wind at the particle and obtains auxiliary wind/turbulence values at 30 m above ground.
  2. PRIME2 uses the local horizontal wind to orient the building/wake coordinates. It checks wake membership and applies the first matching building in file order; effects from overlapping buildings are not added. With local horizontal wind speed below 0.1 m/s the routine returns zero downwash corrections.
  3. MOVE rotates the particle fluctuations using the local wind direction, then applies the horizontal velocity deficit and lateral/vertical enhancement factors.
  4. If VELOCITY_DEFICIT > 0 while ISBUOY=1, PMOVE sets ISBUOY=0, ending that particle's explicit plume-rise phase.

Source references: code/omp_parallel/pmove.f90 and code/omp_parallel/move.f90. PRIME2, BUILDINGS_SET, BUILDINGS_CHK, WAKE_SCALES, WITHIN_WAKE and FAR_WAKE_DIM are shared routines included by the code/omp_parallel/lapmod.for build; the citations here follow the omp_parallel entry points.

Corrected separation of local and 30 m wind directions

The auxiliary interpolation now stores its direction in PSN30/PCS30. It does not overwrite PSN/PCS at the particle, which are passed to MOVE for rotating fluctuations and projecting lateral turbulence enhancement. The auxiliary values and the correction variables are private to the OpenMP particle loop.

INTERPWIND at 30 m: PWIND30, PSN30, PCS30
MOVE at the particle: PWIND, PCS, PSN

Previously, simply enabling the building branch could replace the direction used by MOVE with the 30 m direction, even outside a wake. The fix matters when wind direction changes with height. It preserves the mean local horizontal wind vector while correcting the direction used for fluctuating motion.

Verification of the direction correction

The archived REV-03 checks contain 240 cases per implementation at each of two optimization levels, comparing the actual INTERPWIND/MOVE call bindings with an independent local-wind calculation. The corrected implementations pass; the preceding reference fails 48 of 240 cases. This focused harness does not execute all of PMOVE.

The separate set of 18 complete ten-minute simulations exercises wind rotation with buildings, uniform wind with buildings and wind rotation without buildings. The two controls preserve the compared before/after outputs. With wind rotation and buildings, particle trajectories and concentrations change as expected. The checked omp_parallel particle files agree at one and four threads; concentration sums can differ by rounding. These are numerical regression checks, not a new observational validation of PRIME2.

REV-03 implementation and verification report · Recorded verification results

Verification of the implemented AGELIM change

The archived AGELIM verification includes CCA2/3 checks against independent formulas, mixed particle ages, reversed particle order, both receptor paths, the threshold and AGELIM <= 0. The checks cover the three maintained variants, the historical source tree and the serial staging routine. OpenMP was checked at 1 and 4 threads.

Before/after comparisons verify disabled AGELIM. Around 1800 s, the maximum relative L2 change in the frozen-particle CCA3 field over consecutive 0.01 s steps was 4.91e-6.

All 32 complete ten-minute fixture simulations terminated successfully. In 12 same-variant, one-thread before/after comparisons, particle files are identical; AGELIM=0 also preserves both compared concentration files, while AGELIM=300 changes concentrations as expected. These numerical regression checks are separate from validation against atmospheric observations.

The three Windows executables were rebuilt and installed. No Linux build or new serial distribution package was produced in that update. Numerical summary and source/executable hashes.

Input reference · Concentration theory · Code structure and variants · LAPMOD home