3a · Gas Absorption — building τ_abs
For: users who care how spectral gas-absorption optical depth is computed; HITRAN power users; retrieval developers tuning line-shape choices.
Prev: 3 · Layer Optical Properties · Next: 3b · Mie & Rayleigh
This page covers one of the four arrays the layer-optics pipeline produces:
What this page produces
For each spectral grid point
where
HITRAN line-by-line
vSmartMOM uses the HITRAN line list as the primary source for molecular absorption parameters. The Absorption module exposes:
read_hitran(...)to read aHitranTablefrom a HITRAN-format file.make_hitran_model(...)to build aHitranModelcarrying the line list, broadening selector, and complex-error-function (CEF) choice.compute_absorption_cross_section(model, grid, p, T)to evaluateon a wavenumber grid.
Each line in the HITRAN table contributes through its strength
Line-shape families
Three line shapes are supported:
| Shape | Physical regime | Form |
|---|---|---|
| Doppler (Gaussian) | low pressure, hot gas | |
| Lorentz | high pressure (collision-broadened) | |
| Voigt (convolution) | mixed |
Voigt is the universal choice for atmospheric retrievals — it covers the transition between Doppler-dominated upper atmosphere and Lorentz-dominated lower atmosphere. It is evaluated through the complex error function (Faddeyeva function w(z)); vSmartMOM provides multiple CEF implementations including a GPU-friendly Humlicek-style approximation (src/Absorption/complex_error_functions.jl).
HITRAN line list ──→ make_hitran_model ──┐
│
Spectral grid ν ▼
Layer p, T, VMR ─────────────────→ compute_absorption_cross_section
│
▼
σ(ν, T, p)
│
▼
τ_abs(ν, z) = σ · N(z)
│
▼
Layer optics (Concepts 3)The GPU line-shape kernel
Because the line-shape sum is a per-grid-point reduction over thousands of contributing lines, it parallelizes trivially across the spectral grid — exactly the workload pattern of the RT solver. The Voigt kernel from src/Absorption/compute_absorption_cross_section.jl:229–280:
@kernel function line_shape_batch!(A, @Const(grid), @Const(ν_arr), @Const(γ_d_arr),
@Const(γ_l_arr), @Const(y_arr), @Const(S_arr),
@Const(istart_arr), @Const(istop_arr),
N_lines, ::Voigt, CEF)
I = @index(Global, Linear)
FT = eltype(A)
acc = zero(FT)
ν_i = FT(grid[I])
@inbounds for j in 1:N_lines
if istart_arr[j] <= I <= istop_arr[j]
acc += FT(S_arr[j]) * FT(cSqrtLn2divSqrtPi) / FT(γ_d_arr[j]) *
real(w(CEF, FT(cSqrtLn2) / FT(γ_d_arr[j]) * (ν_i - FT(ν_arr[j]))
+ im * FT(y_arr[j])))
end
end
@inbounds A[I] += acc
end@Const(...) declares the input arrays as read-only — KernelAbstractions uses this to enable backend-specific optimizations (constant-memory caching on CUDA, etc.). @index(Global, Linear) extracts the spectral index. The kernel runs identically on CPU, CUDA, and Metal via the same KA dispatch as the RT kernels. See Concepts/07 for the backend story.
The window istart_arr[j] ... istop_arr[j] is the wavenumber sub-range where line j contributes non-negligibly — pre-computed to avoid evaluating distant lines.
Where τ_abs enters the layer-optics pipeline
After the kernel produces CoreAbsorptionOpticalProperties and added to the layer-optics build chain:
# inside compEffectiveLayerProperties.jl:58 (paraphrased)
combo = rayleigh + sum(aerosols) # τ_scat, ϖ, Z accumulated
final = combo + CoreAbsorptionOpticalProperties(τ_abs) # τ_λ = τ_abs + τ_scat,
# ϖ_λ = τ_scat·ϖ / τ_λThe + overload for (CoreScatteringOpticalProperties, CoreAbsorptionOpticalProperties) is what bumps
Code anchors
| Concept | Source |
|---|---|
| HITRAN parser | src/Absorption/read_hitran.jl |
| Absorption types | src/Absorption/types.jl |
| Cross-section computation | src/Absorption/compute_absorption_cross_section.jl:32–280 |
Line-shape kernel (@kernel) | src/Absorption/compute_absorption_cross_section.jl:229–280 |
| Complex error functions | src/Absorption/complex_error_functions.jl |
| Constants & TIPS partition function | src/Absorption/constants/ |
For practical HITRAN data management — downloading line lists, switching between HITRAN editions, caching — see the HITRAN Data Management page in Resources.
Hands-on tutorials
Runnable examples with Plotly figures:
References
Gordon et al. (2017, 2022, 2024), HITRAN database releases. JQSRT.
Humlíček (1979, 1982), Optimized computation of the Voigt and complex probability functions, JQSRT 21:309 and 27:437.
Faddeyeva, V. N. & Terentiev, N. M. (1961), Tables of the probability integral for complex argument. (Original
w(z)definition.)Crib sheet:
docs/dev_notes/theory_references.md§F.