1. The forward model¶
A constant-wavelength powder pattern is modelled as a background plus a triple sum over phases \(p\), source emission lines \(l\) and reflections \(k\):
Source: rietx.model.forward
Each emission line (Kα₁/Kα₂, …) diffracts at its own Bragg angle, so the doublet splitting grows with \(\tan\theta\) — it is never a fixed \(2\theta\) offset (see (2.3)). The line weight \(w_l\) is the intensity of line \(l\) relative to line 0, which is structurally locked at 1 because it is degenerate with the phase scales. \(\Omega_{lk}\) is a unit-area profile (chapter Peak profiles), so the reflection intensity \(I_{pk}\) enters purely as an area.
1.1. Three intensity models¶
Rietveld mode computes intensities from the structural model [Rie69]:
Source: rietx.model.forward
with phase scale \(S_p\), multiplicity \(m_{pk}\) (chapter Intensities), structure factor \(|F|^2\) and the Lorentz-polarisation factor Lp (chapter Intensity corrections). \(|F|^2\) depends only on \(\sin\theta/\lambda = 1/2d\) and is therefore shared across emission lines; Lp is evaluated per line.
Le Bail mode [LBDF88] treats the \(I_{pk}\) as empirical per-\(hkl\) values, updated between least-squares cycles by observed-intensity partitioning summed over lines:
Source: rietx.model.forward.CompiledModel.lebail_update
which is a fixed point when \(y_{\mathrm{obs}} = y_{\mathrm{calc}}\). The extracted intensities live outside the parameter vector and are path-dependent, so history nodes serialize them per node rather than treating them as parameters.
Pawley mode [Paw81] instead places the per-\(hkl\) intensities
inside the least-squares problem, as an off-table parameter block appended
to \(\theta\). Equation (1.3) is then used exactly once, to seed the
block before the first solve. Reflections whose primary-line centres sit
within 0.5 × their mean FWHM form an overlapped
group and receive a soft equal-split restraint, scaled so that the
split-direction esd is of order the group intensity itself — an unresolved
split is reported at ≈100 % uncertainty rather than with the spuriously
tight esd a bare pseudo-inverse of a singular \(J^\top J\) would give. Such
groups come back flagged PAWLEY_OVERLAP_UNRESOLVED.
1.2. The residual row layout¶
The least-squares residual is not just the data block. Its row layout,
Source: rietx.model.rows
is defined once, in rietx.model.rows, and every builder — the numpy
residual, the numpy Jacobian’s row offsets, and the traced jax/torch
residuals — consumes it. The data rows are
\(\sqrt{w_i}\,(y_{\mathrm{obs},i} - y_{\mathrm{calc},i})\); the remaining
blocks are described with the background models (Background) and
restraints (Parameterisation and constraints).
1.3. Discreteness is frozen per stage¶
Everything discrete about the model — the reflection list, per-atom symmetry-operator subsets, the per-(line, reflection) evaluation windows (which extend ±(30.0 · estimated FWHM + a floor + the FCJ smear extent)), and the FCJ quadrature node counts — is computed when a stage is compiled and never changes during a least-squares run. Only node positions and weights follow the parameters, smoothly. This is what keeps the residual smooth for finite-difference and autodiff Jacobians; regeneration happens between stages only.