IAP GITLAB

`Cascade.inl` does not take into account decreasing cross sections anymore (possibly?)

While trying to understand and summarize the current Cascade.inl algorithm, I found a peculiar change.

TLDR: I believe we don't take into account that the cross section can decrease during a continuous step, due to this commit

Description:

We have already established that between two interactions, continuous losses can decrease the particle energy. This also means that the total (inelastic) cross section can change. From what I understand, CORSIKA 8 is supposed to take this into account.

When sampling the distance to the next interaction, we use the cross section calculated with the particle energy at the beginning of the step:

auto const xs_function = [&](Code const targetId) -> CrossSectionType {
    FourMomentum const targetP4{get_mass(targetId), targetMomentum};
    return sequence_.getCrossSection(particle, targetId, targetP4);
};

CrossSectionType const total_cx_pre = composition.getWeightedSum(xs_function);

where particle has the initial particle energy before any continuous steps.

After applying all continuous losses to the particle, we now re-calculate the total cross section with the updated energy, which is saved to total_cx_post:

    CrossSectionType const total_cx_post = composition.getWeightedSum(xs_function);
    interaction(secondaries, projectileP4Post, composition, total_cx_post);

Inside the interaction method, the actual interaction process is sampled. This is done by first sampling a random number between 0 and total_cx_post:

    UniformRealDistribution<CrossSectionType> uniDist(total_cx_post);
    CrossSectionType const sample_process_by_cx = uniDist(rng_);
    auto const returnCode = sequence_.selectInteraction(view, projectileP4, composition,
                                                        rng_, sample_process_by_cx);

The method selectInteraction now sums up the contributions of the individual InteractionProcesses until sample_process_by_cx has been reached, thus determining which InteractionProcess actually performs the interaction.

However, the way it is implemented right now, we will always select an interaction (because sample_process_by_cx can't be larger than the sum of all cross sections). From my understanding, we shouldn't pass total_cx_post but rather just total_cx_pre to interaction(). This way, we take the decreasing cross section into account, and therefore might end up with no interaction.

Inside the code, this was originally implemented, but has been changed with !426 (merged) in this commit. My question is: Has there been a reason for this change? Am I misunderstanding the code?

I know this is very technical, and if necessary we can talk in an upcoming (technical) call about this, but I would really like to understand this change 😅

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information