Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Dynamic composition (bookkeeping only)

Code: lindhard/src/ion/dynamic.rs (CompositionGrid, Relaxation).

Status. This is the start of milestone M3 (targets that change with fluence). Only the bookkeeping exists: a grid of slabs whose composition callers change with explicit inventory deltas. The fluence loop, and the adapter that turns transport tallies into deltas, are not written yet, so no CLI run uses it and there is no TOML key.

Model

The finite layers of a target are held as slabs. Each slab stores an areal inventory \( A_i \) (atoms/m²) per element, kept sorted by \( Z \) so every derived quantity is deterministic; a slab built from a layer of atom density \( n_i \) and thickness \( t \) starts with \( A_i = n_i t \). An optional semi-infinite substrate backs the grid and never changes.

Inventories change only through CompositionGrid::apply. A retained primary adds one atom of its species where it came to rest; a recoil subtracts an atom where it was created and adds it where it stops (an escaping recoil is a loss). The update either succeeds completely or leaves the grid untouched.

Volume relaxation

After every update each slab’s thickness is recomputed from its inventory by one of two stated conventions:

ConventionRustThickness
Ideal mixing of atomic volumesRelaxation::IdealMixing\( t = \sum_i A_i v_i \), with reference atomic volumes \( v_i \)
Fixed total number densityRelaxation::FixedNumberDensity\( t = \sum_i A_i / n_\mathrm{mix} \)

For an element in its own solid, atomic_volume_from_density gives \( v = M / (N_A \rho) \). After relaxation the slab boundaries are rebuilt from the front surface at \( x = 0 \). Swelling moves the interior interfaces and the back face. With sputter erosion on, the sputtered atoms of each element are removed from the front slabs (the loss they would otherwise cause in the slab where they were displaced is cancelled, so nothing is removed twice), the thickness they occupied under the chosen convention is the recession of that step, and the grid is re-anchored so the surface is again \( x = 0 \); a depth plus the cumulative recession is the depth in the original frame. Erosion is off by default and then changes nothing.

Retention limit

Optionally, each implanted species Z gets a saturation limit: the largest atomic fraction \( f_Z \) of a slab it may make up. Dynamic-composition codes (TRIDYN, SDTrimSP; see References) describe a saturation concentration of the implanted species above which further atoms are not retained and are released again. The update here is this crate’s own statement of that idea; no numeric limit is built in, it is always given by the caller. Per accepted step, each slab is looked at with the composition it would have after the step. With \( A_Z \) of the limited species and \( O \) atoms/m² of everything else, the slab may hold at most

\[ A_\mathrm{max} = \frac{f_Z}{1 - f_Z}, O \]

(that is \( A_Z / (A_Z + O) \le f_Z \)), and the excess \( A_Z - A_\mathrm{max} \) is re-emitted: removed from the slab through the same inventory deltas as any other change, and it leaves the target. A slab holding only the limited species loses all of it. With several limited species in one slab they are met in ascending \( Z \), each seeing the amounts left by the earlier ones, so the limit of a later species is met exactly and an earlier one can end marginally below its own after a later removal.

The atom balance of each element over a step is \( \Delta A_Z^\mathrm{total} = \text{transport net} - \text{re-emitted} \), where the transport net is the retained primaries and the moved, sputtered and transmitted recoils under the conventions above. The re-emission is a pure function of the merged integer tally and the grid and draws no random numbers, so results stay bit-identical at any thread count. The model is off by default and then changes nothing (the CLI adds no columns either).

Assumptions

  • The retention limit is a bookkeeping cap on a slab’s composition. It has no diffusion, no temperature or time dependence, no trapping chemistry and no record of where re-emitted atoms go; the saturation fraction is a free parameter, not a prediction. A limit reached within one step is applied to the step’s result, so steps small enough that no slab jumps far past the limit give a better approximation (the adaptive policy sees the removal).

  • Ideal mixing is additivity of atomic volumes (a Vegard-type rule applied to atoms); it ignores chemistry, voids and amorphisation swelling, and a compound’s real density generally differs from its prediction.

  • A fixed number density reproduces a known compound density but cannot respond to composition, and one value serves every slab.

  • Neither is an equation of state with a pressure or phase model from the literature; both are this crate’s stated conventions, and the module claims no published source for them.

Validity

Bookkeeping for compositions that stay close to the phase whose volumes or density the caller supplies. The caller must give the volume of every species that occurs (none is inferred, in particular not for gases).

Verification status

Conservation, transactional updates and the relaxation conventions are covered by lindhard/tests/dynamic.rs. The fluence stepping loop (DynamicRun, with the tally-to-delta adapter) is covered by lindhard/tests/dynamic_run.rs: the low-fluence limit equals the static engine, refining the step size converges, steps continue one global random stream, results are bit-identical on 1, 2 and 8 threads, adaptive rejection consumes no indices, and inventory follows the event conventions. The retention limit is checked for the analytic plateau (a saturated slab holds exactly \( f_Z \) and none exceeds it), for the atom balance (implanted − sputtered − re-emitted = retained), for bit-identity at 1, 2 and 8 threads, and for leaving results unchanged when off or out of reach. There is no comparison with a measured dynamic profile yet.

The fluence loop

DynamicRun delivers the beam’s primaries in steps. A step runs n primaries on the current target, scales the integer atom counts of the events by the fluence one primary stands for, applies them to the grid and relaxes it. The target is held fixed within a step, so the step must be small enough that the composition does not change much inside it: the adaptive policy bounds the largest relative change of a slab per step and retries a too-large step with fewer ions from the same first primary. The front surface stays at x = 0; the time series reports the interface depths and total thickness measured from it, not a receding surface. The step-size policy is this crate’s own design, not a published scheme. In the CLI it is the [dynamic] table (docs/cli.md).

References

  • W. Möller and W. Eckstein, Nucl. Instrum. Methods B 2, 814 (1984), and report IPP 9/64 (1988): TRIDYN, dynamic composition changes. Read for the idea of a saturation concentration only; nothing was ported.
  • A. Mutzke et al., SDTrimSP Version 6.00, report IPP 2019-02 (2019): the same, for the saturation of implanted species.

No published source is claimed for the two relaxation conventions or for the exact form of the retention update (see above). The atomic volume uses the Avogadro constant of CODATA 2022 (P. J. Mohr, D. B. Newell, B. N. Taylor, E. Tiesinga, Rev. Mod. Phys. 97, 025002 (2025)) and the element densities of lindhard/src/elements.rs, whose sources are in docs/data-provenance.md.