Implement Geant4 step/track onload
In Geant4, it might be necessary to "onload" tracks back to the CPU/Geant4. Reasons include:
- Unsupported detector geometry regions
- Use CPU fast simulation, or other custom physics processes
- Low number of active tracks on GPU
Geant4 tracking algorithm is detailed in the "Book For Toolkit Developers, section 2.4" (html version). In short, G4Track are transported by a "tracking manager', either the tracking manager associated to the particle definition, or a default thread-local tracking manager if there are none. Tracking manager have a single function call, HandOverOneTrack(G4track*) that is responsible to transport one track to completion through the stepping manager.
To offload a track back to Geant4, Celeritas can reconstruct G4Track at the end of a step, and push the reconstructed track back to Geant4 depending on dynamic track properties. There are a few inconvenient with this approach:
- Once the Geant4 tracking manager transports a track, there is no easy way to offload that track back to GPU. We'd probably need a custom stepping action for that
- For Celeritas secondaries that need to be pushed to Geant4, we need to assign them a new track ID as we reconstruct the
G4Track. Because Celeritas doesn't see all Geant4 track, we don't know which ids are available to use
An alternative would be to extend the Celeritas tracking manager to support hybrid CPU/GPU transport instead of pushing the track back to Geant4:
- This would required that Celeritas is initialized to transport tracks on either CPU or GPU, I'm not sure if already support that, or if that can be easily implemented
- Celeritas Tracking manager can use the Geant4 stepping manager (or G4HepEM?) to transport a step (which will take care of invoking fast simulation), at the end of the step we can decide if the track needs to be sent back to the GPU
Note that G4StackManager::PushOneTrack assumes ownership of the track pointer, so the new track reconstructor should return a unique_ptr.