Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:28

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