Skip to main content

Module dynamic

Module dynamic 

Source
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 volumes v_i (m³/atom), thickness = sum_i A_i v_i. Atom fractions are A_i / sum_j A_j and the mass density is the total mass per area divided by the thickness. Choose v_i as the atomic volume in the phase you wish to represent; for an element in its own solid, atomic_volume_from_density gives M / (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 density n_mix (atoms/m³) for every slab, and thickness = 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; InventoryTally also 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§

CompositionGrid
A finite-slab target with per-slab species inventories, an optional immutable substrate, and a Relaxation convention.
CutThrough
Result of DynamicRun2d::run_until_cut_through.
Dynamic2dConfig
Settings of a 2-D run.
DynamicConfig
Fluence-loop settings.
DynamicRun
A fluence-stepped run. See the module docs.
DynamicRun2d
A fluence-stepped 2-D run. See the module documentation.
InventoryDelta
An inventory change for one element in one slab, atoms/m² (positive adds).
InventoryTally
A BcaTally that records the net atom count change per (slab, Z) and the Yields of a step.
PointDifference
One published point compared with the simulated profile.
ProfileCell
Accumulated tallies of one voxel, in atoms per metre of z.
ProfileComparison
A milled profile compared with published points. See compare_profile.
ProfileSnapshot
The profiles at one fluence. See the module docs.
Step2d
What one accepted step of a 2-D run did.
StepRecord
What one accepted step did.
UpdateOutcome
Result of a successful CompositionGrid::apply.
Yields
Event counts of a block of primaries (one fluence step, or a sum of steps).

Enums§

BeamProfile
Lateral beam profile (relative fluence at a lateral position).
DynamicError
Errors from building or updating a CompositionGrid.
DynamicRunError
Errors from the fluence loop.
Relaxation
Volume-relaxation convention. See the module docs.
StepPolicy
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 element z in its elemental solid, from the default density of crate::elements (conventional atomic weight, CODATA N_A). Errors if z is 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.