Expand description
Dynamic composition: a finite-slab target whose per-slab composition can change, with volume relaxation.
This is the stateful target model for fluence-dependent runs. The
CompositionGrid itself is only the bookkeeping: callers supply explicit
per-slab, per-element inventory deltas. Two submodule layers sit on top of
it: InventoryTally turns the transport events of a block of primaries
into those deltas (it is a BcaTally), and
DynamicRun is the fluence stepping loop (fixed or adaptive steps,
deterministic at any thread count; see its module docs). DynamicRun2d
is the two-dimensional variant (a laterally finite beam on a surface that
recedes non-uniformly, with redeposition); see its module docs.
§Inventory and units
Each slab stores an areal inventory A_i in atoms/m² per atomic number
(kept sorted by Z, so every derived quantity is deterministic). Thickness
is in metres. A slab built from an existing layer gets
A_i = n_i * thickness, with n_i the layer’s atom number density
(Material::number_density_of).
§Coordinates
As in crate::geometry: depth x = 0 is the front surface and grows into
the target. After every relaxation the cumulative boundaries are rebuilt
from the front surface by Stack::new, so layers are contiguous. The
front surface is fixed at x = 0: swelling moves the interior interfaces
and the back face, never the front surface. With sputter erosion on
(DynamicConfig::erosion) the lost material is removed from the front
and the grid is re-anchored, so the new surface is again x = 0; the
cumulative recession R (m, reported per step) maps a depth back to the
original frame as x + R. With erosion off the surface never moves. Only
finite slabs are mutable. An optional semi-infinite substrate is an
immutable backing material and is never part of the inventory.
§Volume relaxation
After an update, each slab’s thickness is recomputed from its inventory so
atomic densities stay consistent with a stated convention
(Relaxation). The convention is applied to every slab on every
update, including untouched ones, so a zero update is the identity if and
only if the grid is already consistent with the convention.
Relaxation::IdealMixing: additive atomic volumes (Vegard-type additivity applied to atoms). With reference atomic volumesv_i(m³/atom),thickness = sum_i A_i v_i. Atom fractions areA_i / sum_j A_jand the mass density is the total mass per area divided by the thickness. Choosev_ias the atomic volume in the phase you wish to represent; for an element in its own solid,atomic_volume_from_densitygivesM / (N_A rho). The caller must supply the volume of every species that occurs: none is inferred, in particular not for gases with no elemental solid density. A compound’s real density generally differs from the ideal-mixture prediction, and so does the first relaxation of a grid built from a layer of such a compound; the grid’s initial thicknesses are kept as given until the first update. Tradeoff: simple and parameter-light, but ignores chemistry, voids and amorphization swelling.Relaxation::FixedNumberDensity: the caller specifies one total atom number densityn_mix(atoms/m³) for every slab, andthickness = sum_i A_i / n_mix. Needs no per-species data and reproduces a known compound density, but the density cannot respond to composition: a slab that goes from Si to mostly implanted species keeps the same atoms per volume, and a single value serves all slabs, which suits compositions that stay near one phase.
Neither option is an equation of state with a literature-backed pressure or phase model; both are stated conventions.
§Conservation and update semantics
A slab inventory changes only by the deltas passed to
CompositionGrid::apply. How a caller derives them:
- A retained primary adds one atom of its species at its rest slab. A primary that is transmitted or backscattered without retention removes no target atom and adds nothing.
- A recoil moves an existing atom: subtract at recoil creation, add where it
comes to rest. An internal relocation therefore cancels in the global
total of that species (
CompositionGrid::total_inventory); a recoil that escapes the target is a loss, with no addition after escape. - Beam and target atoms of the same element are the same species in the inventory; the roles differ only in how the deltas are produced.
- Aggregate front/back escape counts cannot say which slab an escaped atom
came from; loss deltas need the origin slab from the transport events,
not the exit position. The default tally gets it by subtracting at the
recoil event;
InventoryTallyalso counts sputtered atoms per origin slab (Particle::origin_layer). - With erosion on, the loss of a sputtered atom is not taken at its origin
slab but from the front of the target, element by element, the origin
loss being cancelled so nothing is removed twice (see
DynamicRun, “Erosion”).
§Transactions
CompositionGrid::apply either succeeds completely or returns an error
and leaves the grid untouched. It rejects non-finite deltas, unknown slabs
or elements, results below zero, missing or invalid reference volumes and
overflow to non-finite thickness or density. A result a few ulps below zero
(within 4 eps of the larger of the inventory and the delta) from removing
exactly what was there is rounded to zero. A species at exactly zero is
dropped from its slab; a slab with no species left is removed, and its
index is reported in UpdateOutcome::removed_slabs (indices of the grid
before the update). If every slab disappears the update is an error unless
a substrate backs the grid, in which case the grid is the bare substrate.
§Energies
Displacement, lattice-binding and surface-binding energies given on the
initial materials are remembered per slab and per element, including
explicitly overridden values, and re-applied when materials are rebuilt.
An element new to a slab gets the defaults of crate::elements.
Structs§
- Composition
Grid - A finite-slab target with per-slab species inventories, an optional
immutable substrate, and a
Relaxationconvention. - CutThrough
- Result of
DynamicRun2d::run_until_cut_through. - Dynamic2d
Config - Settings of a 2-D run.
- Dynamic
Config - Fluence-loop settings.
- Dynamic
Run - A fluence-stepped run. See the module docs.
- Dynamic
Run2d - A fluence-stepped 2-D run. See the module documentation.
- Inventory
Delta - An inventory change for one element in one slab, atoms/m² (positive adds).
- Inventory
Tally - A
BcaTallythat records the net atom count change per(slab, Z)and theYieldsof a step. - Point
Difference - One published point compared with the simulated profile.
- Profile
Cell - Accumulated tallies of one voxel, in atoms per metre of
z. - Profile
Comparison - A milled profile compared with published points. See
compare_profile. - Profile
Snapshot - The profiles at one fluence. See the module docs.
- Step2d
- What one accepted step of a 2-D run did.
- Step
Record - What one accepted step did.
- Update
Outcome - Result of a successful
CompositionGrid::apply. - Yields
- Event counts of a block of primaries (one fluence step, or a sum of steps).
Enums§
- Beam
Profile - Lateral beam profile (relative fluence at a lateral position).
- Dynamic
Error - Errors from building or updating a
CompositionGrid. - Dynamic
RunError - Errors from the fluence loop.
- Relaxation
- Volume-relaxation convention. See the module docs.
- Step
Policy - How the primaries are divided into fluence steps.
Constants§
- PROFILE_
CUTOFF - Columns whose relative fluence is below this are not illuminated.
Functions§
- atomic_
volume_ from_ density - Atomic volume
M / (N_A rho)in m³/atom of elementzin its elemental solid, from the default density ofcrate::elements(conventional atomic weight, CODATAN_A). Errors ifzis unknown or has no tabulated density (for example a gas): no volume is invented for those. - compare_
profile - Compare a simulated profile with published points.