# The T-matrix method
The **transition matrix** (or T-matrix) method is the standard tool for
computing electromagnetic scattering by nonspherical particles whose
shape is a rotationally-symmetric surface of revolution — the regime
that covers essentially every meteorological hydrometeor except the
fully tumbling snowflake. It was introduced by Waterman
{cite}`Waterman1971` under the name *extended boundary condition
method*, and reached its modern, numerically-robust formulation in
Mishchenko's FORTRAN implementation {cite}`MishchenkoTravis1998` —
the reference code whose orientation-averaging kernel `rustmatrix`
re-implements in Rust.
## What the T-matrix is
For a single scatterer illuminated by an incident field expanded in
vector spherical harmonics with coefficients $\{a_{mn}, b_{mn}\}$, the
scattered field has expansion coefficients $\{p_{mn}, q_{mn}\}$ given
by the linear map
$$
\begin{pmatrix} p \\ q \end{pmatrix} =
\mathbf{T}\begin{pmatrix} a \\ b \end{pmatrix}.
$$
The matrix $\mathbf{T}$ is a property of the particle alone — its
shape, size, refractive index, and wavelength — and is independent of
the incident direction. Once $\mathbf{T}$ is known, *any* scattering
quantity (amplitude matrix, phase matrix, cross sections, polarimetric
observables) at any incident / scattered geometry follows from a cheap
rotation and contraction. The expensive step is computing
$\mathbf{T}$ itself.
For an axisymmetric particle, $\mathbf{T}$ is block-diagonal in the
azimuthal index $m$, and each block is found by inverting a matrix
built from surface integrals of spherical Bessel / Hankel functions
over the generating curve of the particle (a spheroid in the
rustmatrix case). This is the kernel that `rustmatrix` ports to Rust.
## The spheroidal approximation
Every hydrometeor model in `rustmatrix` — raindrops, oriented ice
columns, aggregates, graupel, hail — is a **spheroid** (oblate or
prolate) parameterised by
* an equivalent-volume radius $r_\mathrm{eq}$,
* an axis ratio $h/v$ (horizontal over vertical), and
* a complex refractive index $m$ at the radar wavelength.
For rain, the axis ratio is a function of equivolume diameter
(see [polarimetry](polarimetry) and [drop-shape relations in the
tutorials](../tutorials/02_raindrop_zdr)); the canonical choice in
`rustmatrix` is {cite}`Thurai2007`, with
{cite}`PruppacherBeard1970` and {cite}`BeardChuang1987` also tabulated
in `rustmatrix.tmatrix_aux`.
The spheroidal approximation is exact in the Mie limit (sphere) and
accurate for pristine columnar / plate ice; it becomes progressively
less faithful for aggregates. {cite}`Honeyager2013` argues that a
single well-parameterised spheroid still captures the bulk dual-
frequency signatures of aggregates, graupel, and dense ice, and the
[hydrometeor-class tutorial](../tutorials/11_honeyager_hydrometeor_classes)
reproduces that result with `rustmatrix`.
## Orientation averaging
Real populations of hydrometeors are not a single fixed orientation.
Raindrops flutter; ice columns cant around a mean orientation with a
Gaussian distribution of canting angles; tumbling aggregates approach
random orientation. `rustmatrix` supports
* **fixed orientation** (direct T-matrix at a specified canting angle),
* **Gaussian canting** around a mean (numerical quadrature over the
canting PDF), and
* **full random orientation** (closed-form averaging of $\mathbf{T}$).
The Rust kernel parallelises the Gaussian-canting quadrature across
cores via `rayon`, which is where the ~6–430× speedups over
`pytmatrix` come from — orientation averaging is the hot loop in
nearly every PSD tabulation.
## PSD integration
A radar echo is not a single particle. It is an integral over the
particle size distribution (PSD):
$$
Z_{hh} = \frac{\lambda^4}{\pi^5 |K_w|^2}
\int |S_{hh}(D)|^2 \, N(D)\, dD.
$$
`rustmatrix.psd.PSDIntegrator` precomputes the amplitude matrix
$\mathbf{S}(D)$ and phase matrix $\mathbf{Z}(D)$ on a grid of
diameters (done once per scatterer, in parallel Rust), then evaluates
arbitrary PSD shapes against the cached table — so changing a gamma
shape parameter is free after the first integration. See
{cite}`BringiChandrasekar2001` for the observable definitions and
[the PSD background page](psd.md) for the analytical forms.
## What rustmatrix inherits from pytmatrix
The numerical T-matrix core is a faithful port of the
Mishchenko/Leinonen FORTRAN implementation
{cite}`MishchenkoTravis1998` that `pytmatrix` also wraps — same
quadrature scheme, same orientation-averaging formulation, same drop-
shape tables. What changes is *how* the core is executed: Rust +
`rayon` in place of Fortran + GIL-bound Python glue. The
[parity tutorial](../tutorials/01_sphere_mie) shows the
T-matrix-at-sphere agreement with closed-form Mie to ~1e-4.
## Further reading
* {cite}`MishchenkoBook2002` — the canonical monograph; chapters 5–6
cover the T-matrix in depth.
* {cite}`BringiChandrasekar2001` — the polarimetric-radar textbook
that connects T-matrix outputs to every observable in
`rustmatrix.radar`.
* {cite}`RauberNesbitt2018` — undergraduate-level radar meteorology
treatment, the textbook `rustmatrix` was built to support.
```{bibliography}
:filter: docname in docnames
```