Skip to main content

Module electron

Module electron 

Source
Expand description

The electron tally: energy deposition, emission yields and spectra, wired to the electron transport hooks.

FullElectronTally implements ElectronTally. Build one prototype with FullElectronTally::new and pass clones to Transport::run. The merged tally turns into a plain-data, serializable ElectronReport with FullElectronTally::report.

Units: positions and lengths in metres, energies in eV, angles in radians. Totals are summed over all histories. Divide by ElectronReport::histories for per-primary values (the yields are already per primary).

§What is tallied

  • Energy deposition. An inelastic collision deposits the energy it leaves in the solid at the collision point: its whole loss W without a secondary model, and with one only the part no secondary carries away (see the energy balance). An electron whose energy falls below the stopping threshold of its layer deposits what it has left at the point where it stopped. Both go into a per-layer total and into optional 3D grids: a Cartesian x-y-z grid (CartesianGrid) and a cylindrical r-x grid about the beam axis (CylindricalGrid). Energy deposited outside a grid is kept in that grid’s outside_ev, so every grid sums to the total deposited energy. Placing the loss at the collision point and the sub-threshold remainder at the stopping point is this crate’s bookkeeping convention for a point-collision transport loop, not a physics model. The same deposits optionally feed a radial profile in one depth slab, on log radial bins and with per-history errors (ElectronTallyConfig::psf, super::psf), which is the input of the point-spread-function fits.
  • Ionisation and lattice channels. Every deposit is also booked to one of two channels, per layer and per cell of both grids, see the channel split.
  • Emission. Every electron the escaped hook reports is counted at its face, with its energy and its polar angle from the outward surface normal. It is classed as slow (E < split, the secondary-electron class) or fast (E >= split, the backscattered class), see the split convention. The front-face counts per primary are the backscatter yield η (fast) and the secondary yield δ (slow). The energy spectrum and the polar-angle spectrum (one per class) are histograms per face.
  • Generation-volume moments. Energy-weighted mean and standard deviation of the deposition position along x, y, z and of the radial distance from the beam axis (the line y = z = 0 through the entry point), plus the energy-weighted RMS radius. See GenerationVolume.
  • Stopping points. Unweighted moments of the depth and radial distance of electrons that fell below the stopping threshold (an electron range distribution), and the same moments for the primaries alone (PrimaryStoppingPoints: the penetration depth of stopped primaries).
  • Energy balance. The incident energy plus the Fermi-sea source equals the deposited, escaped, trapped and barrier terms, see the energy balance and ElectronEnergyBudget.
  • Table coverage. A numerical diagnostic, not a physical result: per layer and channel, how many rate evaluations of the transport read the cross-section table inside its energy grid and how many used the constant continuation below or above it (super::table_coverage, ElectronReport::table_coverage). These are rate evaluations, not collisions.
  • Event-cap counts. Another numerical diagnostic: how many secondary tracks the collision cap cut off, and how many primary histories had any electron (the primary or a secondary) cut off by it (EventCapCounts, ElectronReport::event_caps). The primary’s own cap stays in FateCounts::event_capped; zero there does not mean the secondary cascades completed.

§The SE/BSE split

An electron leaving the target with energy below 50 eV is by convention a secondary electron and one at higher energy a backscattered electron: H. Chen, Y. Zou, S. Mao, M. S. S. Khan, K. Tőkési and Z. J. Ding, “Influence of energy loss function to the Monte Carlo simulated electron backscattering coefficient”, Sci. Rep. 12, 18201 (2022), doi:10.1038/s41598-022-20466-3 (open access), Introduction (“These electrons, with their energies higher than 50 eV, are defined as backscattered electrons; while the lower energy electrons are the excited secondary electrons”, citing H. Niedrig, Scanning 1, 17 (1978)) and section “Monte Carlo simulation” (“an escaped electron is counted either as a true secondary electron (< 50 eV) or a backscattered electron (> 50 eV)”). The class depends only on the energy, not on whether the electron is a primary or a secondary.

That paper leaves E = 50 eV itself unassigned. This tally puts it in the fast (backscattered) class, as Nebula’s detector flags do: DETECTOR_LT50 (“if energy < 50 eV”) and DETECTOR_GE50 (“if energy >= 50 eV”) in source/core/cpu_material_manager.h, Nebula commit a50a8e8 (https://github.com/Nebula-simulator/Nebula, BSD-3-Clause). Only the convention is taken from there; no code is ported.

The split is configurable (ElectronTallyConfig::se_bse_split_ev, default SE_BSE_SPLIT_EV) and is recorded, with its source, in ElectronTallyMetadata.

§Event kinds and how later channels slot in

The tally reads only the hooks of ElectronTally and does not depend on how many electrons a history contains:

  • Emission is counted per escaped call, so secondaries that escape are counted with the primaries, as the convention requires.
  • stopped is classified by energy against the stopping threshold of the electron’s layer (Transport::stopping_thresholds_ev: the cutoff, or U + cutoff under CutoffReference::VacuumLevel): below it the electron stopped and its energy is a deposit, at or above it the electron is trapped (the loop calls stopped for Fate::Trapped too, and a trapped electron always has at least the threshold energy, because the loop checks the threshold after every energy change, a primary starts above it and a secondary below it is not created).
  • absorbed (the back face under EscapeRule::FrontOnly) counts as trapped energy.
  • Fate::EventCap has no hook of its own, so the energy of the last state seen for the capped electron is counted as trapped: at end_secondary for a secondary, at end_history for the primary. The last state is kept per electron; the primary’s is set aside when the first secondary begins, so a secondary cannot overwrite it. Each capped secondary is also counted once in EventCapCounts::secondary_tracks, and a history with any capped electron once in EventCapCounts::affected_histories; these counts do not touch the energy accounting.

§The energy balance

Inside a layer, kinetic energies are measured from the band bottom, and with BoundaryModel::StepBarrier an electron gains or loses the step ΔU = U' - U in inner potential at every face it gets through (crate::electron::boundary; U = E_F + Φ in a metal, Verduin’s thesis Eq. 3.136, cited there). The primary’s incident energy is its energy where it starts, its vacuum energy with the step barrier. Summed over all histories:

incident + fermi_sea = deposited + escaped + trapped + barrier
  • barrier is the sum of -ΔU over every face transmission (the barrier hook): kinetic energy taken by the potential steps. It is -U for a primary that enters (its vacuum energy becomes E + U inside), +U for any electron that leaves through a surface, and -(U' - U) at an interface. A primary reflected at entry changes nothing and is counted as escaped with its incident energy.

  • With a secondary model, an inelastic event takes W from the electron and liberates, if anything, an electron of kinetic energy E_SE = E_F + W - B (Verduin Eq. 3.86, see crate::electron::secondary), which the tally follows like any other electron until it stops, escapes or is trapped. Per event (SecondaryEvent) W = secondary + binding + deposited, with binding = B - E_F. Only deposited, plus binding where it is positive (an initial state below the band bottom), stays in the solid at the event and is deposited there. Where binding is negative (a conduction electron, as in a metal, which already had E_F - B above the band bottom), the liberated electron brings -binding of its own: that is the fermi_sea source term. So W + fermi_sea = secondary + deposit event by event, and the secondary’s energy is counted once, where it ends.

  • With the opt-in insulator channels of a layer (crate::electron::phonon), an LO-phonon emission gives ħω to the lattice (deposited where it happens), an absorption takes ħω from it (the phonon_absorbed source, added to the left side of the balance), and an electron trapped as a polaron deposits its whole remaining energy where it is trapped (the polaron deposit). The balance is then incident + fermi_sea + phonon_absorbed = deposited + escaped + trapped + barrier, with deposited including phonon_emitted and polaron. Polaron traps are not counted in the stopping points, which are electrons that fell below the stopping threshold.

Without a secondary model and without the step barrier, fermi_sea and barrier are zero and the balance is incident = deposited + escaped + trapped.

§Deposits and the energy imparted

Deposits (deposited, the per-layer totals and every grid cell) are measured from the band bottom. With a secondary model in a layer with a Fermi energy, a liberated conduction electron’s kinetic energy includes the -binding it already had (the fermi_sea source), and wherever that electron stops, its whole remaining energy above the band bottom is deposited. So deposits include Fermi-sea energy the beam never supplied, and deposited can exceed the energy the beam imparted to the target. Moving the sources of the balance above to the right side gives the net energy imparted:

incident - escaped = deposited + trapped + barrier - fermi_sea - phonon_absorbed

Without a secondary model and without the insulator channels the two source terms are zero.

§The ionisation and lattice channels

The kind of a deposit is known at the call site and carried with it, not reconstructed from totals. Two channels, with ionisation + lattice = deposited per layer, per grid cell and in the budget (to floating-point rounding; each is its own accumulator):

  • Ionisation (electronic excitation, the source of electron-hole pairs): the part of an inelastic event left in the solid (W without a secondary model; deposited + max(binding, 0) with one, from the secondary hook), and the residual energy of electrons that fell below the stopping threshold (ElectronEnergyBudget::residual_ev).
  • Lattice: LO-phonon emission (phonon_emitted) and the whole remaining energy of an electron trapped as a polaron (polaron).

The residual is the cutoff-dependent term. It is placed in the ionisation channel by convention: a sub-cutoff electron is below the range where this engine follows collisions, and its energy goes into further electronic excitation as it thermalises. This is a bookkeeping convention, not a computed split; the lattice channel is the lower bound of heating, and the ionisation channel includes the residual and, like all deposits, Fermi-sea energy (see the energy imparted). Elastic nuclear recoil energy is not tallied by the electron engine and is in neither channel.

§Determinism

Counts are integers, histograms have integer bins, and the grids, totals and weighted moments are f64 accumulators merged field by field in the order crate::rng::run_particles calls merge (chunk order). For a fixed chunk_size the report is bit-identical at any thread count (lindhard/tests/electron_tally.rs). Nothing is stored in a hash map.

Structs§

CartesianCharge
Charge on the Cartesian grid, in CartesianGrid::index order.
CartesianDeposition
Deposited energy on a CartesianGrid.
CartesianGrid
A Cartesian deposition grid over x (depth), y and z, m.
ChargeCells
Charge counts per cell (or per layer) with the data for the standard error of the net charge per primary.
ChargeCounts
Electron counts at one place, split by the generation of the electron: charge in units of the electron’s, per ChargeReport’s convention.
ChargeReport
Where the electrons of a run came to rest and where holes were left, as integer counts, and the balance against the incident electrons.
CylindricalCharge
Charge on the cylindrical (r, depth) grid, in CylindricalGrid::index order.
CylindricalDeposition
Deposited energy on a CylindricalGrid.
CylindricalGrid
A cylindrical deposition grid about the beam axis (the line y = z = 0 through the entry point, along x): radial distance r = (y² + z²)^(1/2) and depth x, m.
DepositionReport
Deposited energy by layer and on the configured grids, eV.
ElectronEnergyBudget
The energy balance, eV, summed over all histories and every electron of them (see the module docs): incident + fermi_sea + phonon_absorbed = deposited + escaped + trapped + barrier, with
ElectronReport
Everything a FullElectronTally measured, as plain data.
ElectronTallyConfig
Settings of a FullElectronTally.
ElectronTallyMetadata
The settings and conventions a report was made with.
EmissionClass
One energy class of the electrons leaving through a face.
EscapedCharge
Electrons that left through one face, by generation.
EventCapCounts
Electrons cut off by the collision cap (Fate::EventCap), a numerical truncation diagnostic rather than a physical fate. The primaries’ own caps are FateCounts::event_capped (one fate per primary); these counts add the secondaries. Both are plain counts (tracks, histories), not energies; the energy the capped electrons still carried is ElectronEnergyBudget::event_cap_ev.
FaceEmission
Electrons leaving through one face.
FateCounts
How the primary histories ended (one per history, from its Fate).
FullElectronTally
Deposition, emission and energy-balance tally for the electron transport loop. See the module docs.
GenerationVolume
Energy-weighted moments of the deposition position (weights: the energy of each deposit). Lengths in metres.
PrimaryStoppingPoints
Where the primaries fell below the stopping threshold (unweighted, one sample per stopped primary): the penetration depth of stopped primaries, as compared with other codes in docs/validation.md.
StoppingPoints
Where electrons fell below the stopping threshold (unweighted, one sample each).
Yields
Emission yields per primary.

Enums§

ElectronTallyError
Errors from building a FullElectronTally.

Constants§

SE_BSE_SPLIT_EV
Default SE/BSE energy split, eV: an escaping electron below this energy is in the secondary (slow) class, at or above it in the backscattered (fast) class. Chen et al., Sci. Rep. 12, 18201 (2022), doi:10.1038/s41598-022-20466-3, Introduction and section “Monte Carlo simulation”; the assignment of the boundary itself follows Nebula’s DETECTOR_GE50 flag. See the module docs.
SE_BSE_SPLIT_RULE
The classification rule, as recorded in ElectronTallyMetadata.
SE_BSE_SPLIT_SOURCE
The source of the default split, as recorded in ElectronTallyMetadata.

Functions§

net_mean_se
Mean and standard error of a per-history integer quantity from its sum and sum of squares.