Skip to main content

Module voxel

Module voxel 

Source
Expand description

Sparse 3D voxel tallies of implanted atoms, damage and deposited energy, with CSV and VTK export.

VoxelTally implements BcaTally. It bins events by position on its own regular grid (VoxelTallyGrid), so it works with any crate::geometry::Geometry (a crate::geometry::VoxelGrid, a mesh or a CSG solid), not only with a voxel grid; use VoxelTallyGrid::from_voxel_grid to tally on the voxels of a grid target. Build one prototype with VoxelTally::new, hand clones to crate::ion::bca::Bca::run, and turn the merged tally into a plain-data VoxelReport with VoxelTally::report.

Units: positions and lengths in metres, energies in eV. x is the depth.

§What is tallied per voxel

  • implanted: beam particles that came to rest in the voxel (the voxel counterpart of crate::tally::ion::RangeReport::stopped).
  • displacements: target atoms displaced in the voxel, counted where the recoil is created (transfer above E_d), the simulated cascade count of crate::tally::ion::CascadeDefects::displacements. This is the damage measure of the tally. The NRT / Kinchin-Pease model estimate (crate::ion::damage) needs a per-material Lindhard partition and is not tallied per voxel; the two are never conflated (see crate::ion::damage for the convention and its sources, Norgett, Robinson and Torrens, Nucl. Eng. Des. 33 (1975) 50, and Lindhard et al., Mat. Fys. Medd. Dan. Vid. Selsk. 33 (1963) no. 10).
  • Per-element defects, when the tally knows the species of the run (see VoxelTally::with_species): for every species index of the engine (crate::ion::bca::Bca::species_z), the vacancies at the displacement site, the interstitials where a displaced atom came to rest without filling a site, and the replacements. These use the definitions of crate::tally::ion::CascadeDefects and its replacement rule (one shared implementation), so summed over voxels (and VoxelReport::outside) and species they equal that struct’s totals exactly. A replacement is attributed to the species of the atom it replaced, at the site of that atom, so vacancies = displacements - replacements holds per species and voxel. Beam particles are not interstitials here (they are implanted).
  • Deposited energy, split by channel so each can be checked against the engine’s crate::ion::bca::EnergyBudget: electronic_ev (nonlocal and local electronic loss), lattice_ev (nuclear energy left in the lattice: subthreshold and weak transfers and the binding energy of displaced atoms) and rest_ev (the kinetic energy of a particle when it stops below its cutoff). VoxelCell::deposited_ev is their sum. The work done against the planar surface barrier and the energy carried out of the target are not deposited in any voxel and are not tallied here.

The nonlocal electronic loss of a free flight is spread uniformly along the straight segment (the engine’s convention, see crate::ion::bca::BcaTally::electronic), so a segment that crosses voxel faces is split between the voxels in proportion to the length in each. Everything else is a point event and goes to the voxel containing it. Voxels own the half-open box [o + i h, o + (i + 1) h) on each axis; events outside the grid are summed in VoxelReport::outside.

§Sparse storage

Only voxels that received an event are stored, in a BTreeMap keyed on the flat index i + nx (j + ny k), so empty voxels cost no memory and iteration, merging and export follow one fixed order.

§Determinism

Counts are integers and energies are f64 sums, merged voxel by voxel in the order crate::rng::run_particles calls merge (chunk order). For a fixed chunk_size the result is bit-identical at any thread count (lindhard/tests/voxel_tally.rs).

§Export formats

VoxelReport::write_csv writes one row per occupied voxel after a # key = value header that carries the grid, so the file reads back (VoxelReport::read_csv) exactly: floats are written in the shortest form that parses back to the same bits. VoxelReport::write_vtk writes a legacy ASCII VTK 3.0 UNSTRUCTURED_GRID of VTK_VOXEL cells, one per occupied voxel (so the file is as sparse as the tally), with the tallies as cell scalars; format: Kitware, The VTK User’s Guide, 11th ed. (2006), “VTK File Formats”. The VTK file does not carry the outside sums. A tally built with VoxelTally::with_species writes format version 2: the species are named in the header and each adds vacancies, interstitials and replacements columns (scalars). A tally without species writes version 1 exactly as before, and both readers accept both versions. VoxelReport::read_vtk reads back what write_vtk writes.

Structs§

ExportProvenance
Where a damage-export file came from: the header keys beyond the grid and the tallies. The CSV is an exchange format; these fields let a reader tie a file to the run that made it.
SpeciesDefects
Defects of one species in one voxel (or summed), as defined by crate::tally::ion::CascadeDefects.
VoxelCell
The tallies of one voxel (or of the whole grid, for totals).
VoxelRecord
One occupied voxel of a VoxelReport.
VoxelReport
A VoxelTally as plain data. Voxels are in increasing flat-index order (i + nx (j + ny k)).
VoxelTally
A sparse voxel tally; see the module docs.
VoxelTallyGrid
The regular grid a VoxelTally bins on: dims voxels of edge spacing_m starting at origin_m. Voxel (i, j, k) has the flat index i + nx (j + ny k) (x fastest, as in VoxelGrid).

Enums§

VoxelTallyError
Errors from building a VoxelTallyGrid or reading an exported file.

Constants§

EXPORT_BANNER
The banner line of a damage-export file (see docs/damage-export-format.md).
EXPORT_FORMAT_VERSION
Version of the damage-export format, the format_version header key.