Low energy secondary electron (<0.1 keV) below cutoff causes recoverable propagation error in float build
When running the OpNoviceOptical test with the float precision preset, several threads report errors involving sub-keV electrons.
The affected electrons appear to be generated below the transport cutoff and are terminated by the range-limiting action and can be reproduced.
Problem Setup :
Test: OpNoviceOptical.run
Executable: ./test/accel/TrackingManagerIntegration
Build : "float"
Error Log
G4WT3 > [4/12] error@/src/celeritas/alongstep/detail/PropagationApplier.hh:128: Propagation of step length 2.958926e-07f due to post-step action 2 leading to distance 2.958926e-07f failed to change position
G4WT3 > [4/12] error@/src/celeritas/phys/detail/TrackingCutExecutor.hh:69: Killing track {"geo":{"dir":[-0.2886227071285248,0.10393267869949341,0.951785147190094],"is_on_boundary":false,"is_outside":false,"pos":[[-7.145407199859619,-2.680811643600464,11.540878295898438],"cm"],"volume_id":"Tank"},"mat":"Water","particle":{"energy":[0.0002312585711479187,"MeV"],"particle_id":"e-"},"sim":{"event_id":0,"num_steps":0,"parent_id":36,"post_step_action":"tracking-cut","status":"errored","step_length":[2.9589264727292175e-07,"cm"],"time":[8.013262275952115e-10,"s"],"track_id":162},"thread_id":987,"track_slot_id":987}: lost 0.000231259 MeV
G4WT3 > [4/12] error@/src/celeritas/alongstep/detail/PropagationApplier.hh:128: Propagation of step length 1.749331e-07f due to post-step action 2 leading to distance 1.749331e-07f failed to change position
G4WT3 > [4/12] error@/src/celeritas/alongstep/detail/PropagationApplier.hh:128: Propagation of step length 4.414289e-07f due to post-step action 2 leading to distance 4.414289e-07f failed to change position
The post-step action 2 corresponds to limit range due to energy loss with lowest_energy set to 1 keV
The action label list from output.json looks like :
{
"internal": {
"actions": {
"description": [
"update beginning-of-step state",
"limit range due to multiple scattering",
"limit range due to energy loss",
"select a discrete interaction",
"reject by integral cross section",
"interact by Moller+Bhabha ionization",
"interact by Seltzer-Berger bremsstrahlung",
"interact by relativistic bremsstrahlung",
"interact by Livermore photoelectric effect",
"interact by Compton scattering (simple Klein-Nishina)",
"interact by Bethe-Heitler gamma conversion",
"interact by Rayleigh scattering",
"interact by positron annihilation yielding two gammas",
"mark a track that failed to sample an interaction",
"apply along-step for particles with no field",
"create track initializers from primaries",
"initialize track states",
"apply along-step for neutral particles",
"pause due to propagation misbehavior",
"cross a geometry boundary",
"kill a track and deposit its energy",
"create track initializers from secondaries",
"launch the optical stepping loop",
"gather pre-step data to generate optical distributions",
"generate Cherenkov optical distribution data",
"generate scintillation optical distribution data"
],
In our G4 physics list setup options, apply_cuts is off by default, just like with G4 option 0 and 2 (option 1 has apply_cuts=true). So we're not killing the secondaries below energy.
This capability was added in #709. It mirrors Geant4's behavior which I think is bad because it kills and deposits positrons even if the gamma cutoff is below 511 kev...
I think it would be more consistent to have secondary production cuts be the same as the tracking cut of that particle, and to always apply cuts, and to eliminate the positron secondary apply_cut (or I guess we could keep it if the user gamma tracking cut is above 511 kev). Thought @amandalund @whokion ?
The error message here is not going to show up in practice because it's from a single-precision execution, but I think it just reveals this inconsistent treatment of tracks versus their secondaries.
That sounds a lot like how we originally (incorrectly) implemented production cuts and later fixed (#295 #304)?
In principle, there is no tracking cut in the Geant4 kernel so particles are tracked down to zero energy - this is especially relevant for neutral as they do not undergo continuous energy loss. I thought that the 1 keV cut for electrons is the threshold where dedx is not calculated and is unrelated to any tracking cut. Of course, the user limiter (as a step limiter or a energy/timing cut) is a separate matter.
I've probably forgotten 🤔 but I suppose I don't intuitively understand why you would want to track a "successfully emitted" secondary electron of 20 keV while preventing emission of most other 20 keV secondaries by increasing the energy loss...
A tracking cut like we have locally deposits the secondary energy at a single point (bad and different), whereas if we always applied the cuts in the InteractionApplier we're at least smoothing the energy deposition over the step.
Energy loss-based secondary production thresholds, tracking cutoffs, and interaction-based secondary emission thresholds are all approximations to various extents, and I certainly don't understand how tracking a secondary that travels 3 nm over its lifetime is better than depositing the energy when it's created.
But that actually raises another question: we have a single energy deposition scalar that combines the energy averaged along the step with energy deposited at the end-of-step during collision. Is that wrong? Doesn't this mean that, for example, scintillation/cherenkov emission over a step will change based on what end-of-step interaction is sampled?
Linking Mihaly's talks on production/tracking cuts in Geant4, since I recall them being very detailed and helpful: https://indico.cern.ch/event/1017515/, https://indico.cern.ch/event/1017516/.