Refactor physics tables for correct material-dependent bounds
The physics cross section data and applicability model was implemented very early in our project: the cross section construction uses some very awkward classes, the physics "construct host data" is super complicated, and most importantly the applicability doesn't allow us to limit correctly the lower energy of models based on their production cutoff, so we end up sampling inapplicable discrete models (most seriously in the case of stopped positrons).
Priority ordering for implementation parts:
- [x] Use one dE/dx grid per particle rather than per process (#253)
- [x] Composite multiple grids (or use generic grid) for Geant4 11.1 support (#588)
- [ ] Replace applicability to support correct model bounds per material as a function of energy (so that we can correctly treat positrons when slowing down, for example)
- [ ] Replace material lookup with a
{material, region} -> PhysMaterialmapping (see #983) - [ ] Combine secondary production/range cutoffs into physics
- [ ] ~~Possibly integrate "MSC model" into physics? (not the same type as other physics processes though)~~
Replace applicability:
- Model selection: grid of
[particle][material][energy bin] -> model - Physics lists should be the same "per region", so process/models should be a function of [region][particle][energy]
- Energy grid structure can be different for each material (and of course for each particle type)
- Energy grid will live on
[0, ∞)where zero is applicable to at-rest processes
Replace cross section construction:
- Define different energy grid input classes (log, log+scaled, nonuniform) and use variants for the CPU interface
- Define visitors that construct the data on device (emplacing a grid type + sub-grid ID)
Build order:
- User supplies processes
- Process provides a set of materials (for now require all processes in all materials since that's true for EM)
- Process creates models (models are same for all materials but may have material-dependent parameters)
- Each model provides a set of applicable particles and energy range for each {particle type, material}: for 'imported' data, these ranges should be exactly the range of the existing cross sections
- Process+model detail construction ensures no gaps or overlaps between model ranges
If we do our own cross section generation...
- Model micro XS calculation: depends on secondary cutoff, loop over
{material, element, particle} -> {{slowing down, micro XS}, energy} - Model macro XS calculation + element CDF: integrate micros over elements for each material (and discard micros for models that don't need them, e.g. Compton), and normalize
- Process macro XS calculation: combine non-overlapping energy grids from models for XS and slowing down
- Accumulate slowing-down over all processes into a
{particle, material, energy}-dependent field - Numerically integrate dE/dx to get range
- MSC can do this in whatever order it needs (since currently it's embedded into the along-step action) except that maybe it needs slowing down cross sections?
- User input to a process determines the energy transition point between a process's models (?)
If pulling from Geant4/imported data:
- Issue: how do we ensure lifetime of cross section data from process construction to physics construction? Probably have to use
shared_ptr<ImportData const>. - Geant already combines per-model energy ranges: we will also need to export energy midpoints (e.g. "high energy limit" for brems model)
- Some models may be inapplicable in certain regions (e.g. 50m production cut in CMS)
Transition plan from imported data to generating our own?
- We use our own EM parameters?
- Use the G4HepEm approach of extracting cross sections from geant4 (looping over our own energy points to construct tables, rather than loading directly the pre-generated tables)
Restrictions on processes and models:
- Models should allow different parameters for different regions
Along-step data refactor:
- Goal is to allow multiple along-step kernels and change their applicability based on material, particle type, energy range?
- Do inside pre-step action (replacing simple "neutral" switch)
- "Along-step" could be another interface that gives applicability ranges (particle types, energy)
- Combination of components:
- MSC step limit (hopefully differences in step limit can be simply represented as cross sections? unless we're doing a detailed boundary treatment)
- propagation
- slowing down treatment (energy fluctuations)
- MSC model
- Maybe we need a separate along-step physics manager?
Also should probably refactor
the applicability doesn't allow us to limit correctly the lower energy of models based on their production cutoff, so we end up sampling inapplicable discrete models (most seriously in the case of stopped positrons)
Is this because of the applicability, or because the process is sampled from the cross sections calculated at the pre-step energy and the particle might lose energy over the step (possibly making the sampled process/model inapplicable at the post-step energy)?
It's because the way I implemented applicability requires the same lower bound for all materials. If we could do material-dependent, then we would be able to select the actually applicable models from the post-slowing-down energy.
But won't we still be sampling the (possibly now inapplicable) process from the pre-step energy?
Right: we calculated the process cross sections using pre-step energies. Well, perhaps we could adjust the logic at the end of select_discrete_interaction so that if the model finder returns "no model" (which it can do with the post-step energy), the associated per-process xs is set to zero (and the macro xs reduced accordingly) and we return to the top of the function to resample a process? Unless there are processes with upper energy bounds, this will allow us to always sample a process that has a valid model.
Currently the model finder always returns a valid model: using the integral approach, the process xs is recalculated at the post-step energy and if it's zero (no applicable process) then no model is returned before actually trying to select a model. We might be able to use your suggestion if the post-step process xs is zero and resample a process, but I don't think we would need material-dependent model applicabilities.
See also #1391