File indexing completed on 2025-09-17 08:53:44
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include "corecel/Assert.hh"
0011 #include "corecel/random/distribution/Selector.hh"
0012
0013 #include "ParticleTrackView.hh"
0014 #include "PhysicsTrackView.hh"
0015
0016 namespace celeritas
0017 {
0018 namespace optical
0019 {
0020
0021
0022
0023
0024
0025
0026 inline CELER_FUNCTION StepLimit calc_physics_step_limit(
0027 ParticleTrackView const& particle, PhysicsTrackView& physics)
0028 {
0029 CELER_EXPECT(physics.has_interaction_mfp());
0030
0031 real_type total_xs = 0;
0032 for (auto model : range(ModelId{physics.num_models()}))
0033 {
0034 total_xs += 1 / physics.calc_mfp(model, particle.energy());
0035 }
0036 physics.macro_xs(total_xs);
0037
0038 CELER_ASSERT(physics.macro_xs() > 0);
0039
0040 StepLimit limit;
0041 limit.action = physics.discrete_action();
0042 limit.step = physics.interaction_mfp() / total_xs;
0043
0044 return limit;
0045 }
0046
0047
0048
0049
0050
0051
0052
0053
0054 template<class Engine>
0055 CELER_FUNCTION ActionId
0056 select_discrete_interaction(ParticleTrackView const& particle,
0057 PhysicsTrackView const& physics,
0058 Engine& rng)
0059 {
0060 CELER_EXPECT(!physics.has_interaction_mfp());
0061 CELER_EXPECT(physics.macro_xs() > 0);
0062
0063 ModelId mid = celeritas::make_selector(
0064 [&physics, energy = particle.energy()](ModelId m) {
0065 return 1 / physics.calc_mfp(m, energy);
0066 },
0067 ModelId{physics.num_models()},
0068 physics.macro_xs())(rng);
0069
0070 return physics.model_to_action(mid);
0071 }
0072
0073
0074 }
0075 }