Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:44

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file celeritas/optical/PhysicsStepUtils.hh
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  * Calculate the discrete physics step limit for the given track.
0023  *
0024  * The total cross section is cached in the \c PhysicsTrackView.
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  * Randomly sample a discrete interaction by their cross sections.
0050  *
0051  * Should be performed after discrete select action has reset the MFP,
0052  * and the macroscopic cross sections have been built.
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 }  // namespace optical
0075 }  // namespace celeritas