celeritas icon indicating copy to clipboard operation
celeritas copied to clipboard

Unify and simplify importing of particles/processes to offload

Open stognini opened this issue 3 months ago • 1 comments

Issue

The existing GeantImporter uses a small set of GeantImportDataSelection::Flags for importing particles and physics. This leads to inconsistencies between SetupOptions / FrameworkInput and the actually imported data: we may only have one process and one particle (e.g. Rayleigh scattering for gammas), but GeantImporter will still likely follow the ::em_basic data selection for importing particles and processes.

Requirement

Celeritas should allow for user-defined physics and particles and maintain consistency with the data loaded into memory for offloading. I.e. not load unused particles/processes.

Implementation

First step is to update or remove existing DataSelection flags. Since the physics should come from the registered Geant4 physics list, we could loop over the offloaded list of particles and import any available process. The outer loop in ::import_processes is already over particles, and thus updating/refactoring DataSelection/ParticleFilter may work already.

Breaking down GeantImporter into separate helpers, one for inp::Problem::Model and one for inp::Problem::Physics may make more sense for code logic (but is probably another issue).

Caveats

Geant4 does not allow the creation of a given process without the minimum required particles (primary + secondaries) used by said process. Celeritas during offload could allow for the production of said secondary and not physically transport it. E.g. Geant4 has a set of processes for gammas, and only bremsstrahlung for electrons. If the only particle in the offload list is the electron: can the electron still undergo bremsstrahlung and produce a gamma, which is not offloaded, by

  • killing the gamma and depositing the energy locally; or
  • sending the gamma back to Geant4 for transport?

Another option is to require the offload of secondaries produced, but import the process data based on inp::Physics (which would be equivalent and likely supersede GeantPhysicsOptions). In this case, reusing the example above:

  • Geant4: would have gamma (and its processes), e- with bremsstrahlung.
  • Celeritas: would also have both particles, but could enable only bremsstrahlung through its physics options. In this case the produced gamma would have no processes attached to it and only be raytraced out of the geometry.

stognini avatar Sep 15 '25 20:09 stognini

Some follow-on thoughts.

Guiding principles

I think we want first and foremost, Enabling Celeritas maintains consistent physics with Geant4. Less important but still worth considering, as you mentioned is, Minimize overhead by not converting data that's unnecessary at runtime.

Requirements

I think in your description we're missing the desired data flow:

  • [In standalone mode only: JSON input determines Geant4 physics list]
  • Inputs: Geant4 in-memory particles and processes; and user offload list [which in standalone mode is auto-set]
  • Output: Celeritas particles and process list+data, and offload list (which may be a subset of particles Celeritas understands)

Finally we need a method to manage processes that we don't have implemented:

  • Maybe we can import the cross sections for materials, then "onload" particles that undergo unsupported processes. (If processes are rare but important, like photonuclear, this will preserve the physics but decrease the amount of offloaded work.)
  • Or for unsupported processes we warn or error so that the user that the physics will be wrong
  • Or even more strict, we require the user turn off physics from their list if unsupported, which would guarantee consistency

Implementation

We need to assume Geant4 can run on its own with the user setup (aka, Celeritas won't work with a broken Geant4 app). Since we're trying to run with the same behavior, we want to do the same thing: not crash, transport particles to the boundary (which is usually the same as killing it instantly, unless we've got diagnostics for non-depositing particles).

(As an aside, it might be useful to define a custom "instant local absorption" G4 process that takes a particle and deposits its energy as soon as it's created. This approximation is used in nuclear engineering, for example.)

Since Celeritas processes refuse to be built unless they can identify the secondary particle IDs, that means we have to pull over gamma particle properties if we're doing pure electron+brems, including offloading only gammas. So do we need a map of process -> possible secondaries? (Does Geant4 provide this?)

By default, even with EM only physics, Geant4 creates a bunch of particles that we don't need to handle. If we import all such particles we'll greatly increase the size of some data structures.

As a medium-term solution I think we want a second user input: a vector of "known particles". We can hard-code some defaults to allow the typical case (standard EM only, optical) and let the user specify (and get setup-time errors if they choose poorly) for advanced cases.

These options would go into the inp::GeantImport setup structure and completely replace GeantImportDataSelection. The "offload particles" would replace the "processes" flag, and "known particles" would replace the "particles" flag.

Decisions to make

  • Should the physics in Celeritas always mirror the Geant4 physics list, or can they diverge?
  • What should happen if the user requests physics that Celeritas does not support: error or warning?
  • Should users be required to disable unsupported processes in Geant4 before running with Celeritas, or do we continue to provide a list of "ignore" processes?
  • How should secondary particles from offloaded processes be handled: killed and deposited locally, sent back to Geant4, or required for offload?
  • Must all secondary particles for a process be imported into Celeritas even if they are not transported? (I think so, since many of the secondary properties determine the interaction physics.)
  • Where does the process-to-secondary mapping come from: Geant4 introspection, a Celeritas-maintained map, ...?
  • Should particles without attached processes be allowed? (Do we default to "infinite distance to collsion" or error?)
  • What defaults for known_particles should be provided for common use cases (EM, optical)?

@stognini @amandalund

sethrj avatar Sep 16 '25 13:09 sethrj