Refactor physics to have a single combined energy loss/range "process"
In Geant4, the dE/dx table is created by summing the contribution from each process that provides energy loss for a given particle. The range table is then calculated from this total energy loss. Our current implementation assumes per-process dE/dx and range tables, though what we are actually importing is a combination of process and total dE/dx and range.
It's been a while since we had our discussion, but what I recall is that the only per-process "value grid" we should be storing is cross section; and we should have one "range table" and one "energy loss table" in the ProcessGroup (corresponding to the process-integrated values for that single particle type).
This is related to the discussion @amandalund, @whokion, @paulromano and I had last week. As we start implementing MSC, we should consider refactoring the Physics/Process with these considerations:
- A single (optional) runtime "energy loss" process; so eliminate the generic eloss/range tables for discrete processes. Possibly rename the device data to reflect that "discrete processes" are exclusively for end-of-step interactions where exactly one is selected if the step is limited by the (exponential-sampled) physics interaction length.
- Generalize and separate the components of
calc_step_limitto step limiters: discrete cross section calculation, range (from the energy loss process), and MSC step limiter. As we add hadronics, "decay" will probably be a step limiter as well. - The
Processhost class is responsible for setting up the on-device data but doesn't necessarily have to be mirrored in on-device data. So it might be OK to haveenergy_lossandmscaccessors with a setup check that no more than one process is MSC and no more than one is energy loss.
Sketching out some ideas:
- Make an XsGridType enum for the various grid types (EM grid, generic grid, ...)
- XsGridId for indexing into the various grids
New XsParamsData:
- ids and types to index into them
- reals for dynamic storage
XsView maybe to create XS calculators?
- Delete ValueGridInserter: instead just build stuff in XsParamsData
- Delete ValueGridType, ValueGridArray
- ValueGridBuilder could just be helper functions for constructing in XsParamsData
- Model::micro_xs returns a range of XsGridId?
- Process::step_limits should become macro_xs (and should we have an option for calculating by summing the elemental cross sections?) and build a new xs/XsGridId
Ideally the processes could create de/dx tables which we'd then sum into a single energy loss term and then integrate to create range: but for now just take an extra little class that builds eloss/range values for each particle type?
- ProcessGroup::tables should just be macro cross sections (XsGridId)
- eloss_ppid should just be the XsGridId of the energy loss, add a range id?
Maybe we should allow processes to provide energy loss tables? In practice both energy loss and cross sections are derived from the cutoff values. So we should really also be providing the material- and particle-dependent cutoffs as input to the cross section calculation routines. 🤔 And I think we can at this point calculate the range tables ourselves since it's pretty simple (see G4LossTableBuilder::BuildRangeTable though it looks like to "match" Geant4 we'll have to add the usual fudge factors).
The data we export from Geant4 has (apparently?) already combined all energy loss processes into the "ionization" energy loss table, but we should ideally be able to do the same ourselves.