Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/phys/detail/PreStepExecutor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Config.hh"
0010 
0011 #include "corecel/Macros.hh"
0012 #include "corecel/math/Quantity.hh"
0013 #include "corecel/random/distribution/ExponentialDistribution.hh"
0014 #include "corecel/random/engine/RngEngine.hh"
0015 #include "celeritas/Types.hh"
0016 #include "celeritas/global/CoreTrackView.hh"
0017 #include "celeritas/track/SimTrackView.hh"
0018 
0019 #include "../PhysicsStepUtils.hh"  // IWYU pragma: associated
0020 #include "../PhysicsStepView.hh"
0021 #include "../PhysicsTrackView.hh"
0022 
0023 namespace celeritas
0024 {
0025 namespace detail
0026 {
0027 //---------------------------------------------------------------------------//
0028 /*!
0029  * Set up the beginning of a physics step.
0030  *
0031  * - Reset track properties (todo: move to track initialization?)
0032  * - Sample the mean free path and calculate the physics step limits.
0033  *
0034  * \note This executor applies to *all* tracks, including inactive ones. It
0035  *   \em must be run on all thread IDs to properly initialize secondaries.
0036  */
0037 struct PreStepExecutor
0038 {
0039     inline CELER_FUNCTION void
0040     operator()(celeritas::CoreTrackView const& track);
0041 };
0042 
0043 //---------------------------------------------------------------------------//
0044 CELER_FUNCTION void
0045 PreStepExecutor::operator()(celeritas::CoreTrackView const& track)
0046 {
0047     if (track.thread_id() == ThreadId{0})
0048     {
0049         // Clear secondary storage on a single thread
0050         auto alloc = track.physics_step().make_secondary_allocator();
0051         alloc.clear();
0052     }
0053 
0054     auto sim = track.sim();
0055     if (sim.status() == TrackStatus::inactive)
0056     {
0057 #if CELERITAS_DEBUG
0058         auto step = track.physics_step();
0059         step.reset_energy_deposition_debug();
0060         step.secondaries({});
0061 #endif
0062 
0063         // Clear step limit and actions for an empty track slot
0064         sim.reset_step_limit();
0065         return;
0066     }
0067 
0068     // Complete the "initializing" stage of tracks, since pre-step happens
0069     // after user initialization
0070     auto step = track.physics_step();
0071     {
0072         // Clear out energy deposition, secondary pointers, and sampled element
0073         step.reset_energy_deposition();
0074         step.secondaries({});
0075         step.element({});
0076     }
0077 
0078     if (CELER_UNLIKELY(sim.status() == TrackStatus::errored))
0079     {
0080         // Failed during initialization: don't calculate step limits
0081         return;
0082     }
0083 
0084     CELER_ASSERT(sim.status() == TrackStatus::initializing
0085                  || sim.status() == TrackStatus::alive);
0086     sim.status(TrackStatus::alive);
0087 
0088     auto phys = track.physics();
0089     if (!phys.has_interaction_mfp())
0090     {
0091         // Sample mean free path
0092         auto rng = track.rng();
0093         ExponentialDistribution<real_type> sample_exponential;
0094         phys.interaction_mfp(sample_exponential(rng));
0095     }
0096 
0097     // Calculate physics step limits and total macro xs
0098     auto mat = track.material();
0099     auto particle = track.particle();
0100     sim.reset_step_limit(calc_physics_step_limit(mat, particle, phys, step));
0101 
0102     // Initialize along-step action based on particle charge:
0103     // This should eventually be dependent on region, energy, etc.
0104     sim.along_step_action([&particle, &scalars = track.core_scalars()] {
0105         if (particle.charge() == zero_quantity())
0106         {
0107             return scalars.along_step_neutral_action;
0108         }
0109         else
0110         {
0111             return scalars.along_step_user_action;
0112         }
0113     }());
0114 }
0115 
0116 //---------------------------------------------------------------------------//
0117 }  // namespace detail
0118 }  // namespace celeritas