Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2020-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/track/SimTrackView.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Macros.hh"
0011 #include "corecel/Types.hh"
0012 #include "corecel/cont/Span.hh"
0013 #include "corecel/sys/ThreadId.hh"
0014 #include "celeritas/Types.hh"
0015 #include "celeritas/phys/Secondary.hh"
0016 
0017 #include "SimData.hh"
0018 
0019 namespace celeritas
0020 {
0021 //---------------------------------------------------------------------------//
0022 /*!
0023  * Simulation properties for a single track.
0024  *
0025  * TODO: refactor "reset_step_limit" and the along/post-step action setters to
0026  * validate that setting a new action may only \c increase the ID (if it's
0027  * explicit) and can only \c reduce the step limit. See \c StatusCheckExecutor
0028  * . Maybe we also need to reconsider having separate along- and post-step
0029  * action IDs: perhaps find a way to have a "step limit action" and a "next
0030  * action"?
0031  */
0032 class SimTrackView
0033 {
0034   public:
0035     //!@{
0036     //! \name Type aliases
0037     using SimParamsRef = NativeCRef<SimParamsData>;
0038     using SimStateRef = NativeRef<SimStateData>;
0039     using Initializer_t = SimTrackInitializer;
0040     using Energy = units::MevEnergy;
0041     //!@}
0042 
0043   public:
0044     // Construct with view to state and persistent data
0045     inline CELER_FUNCTION SimTrackView(SimParamsRef const& params,
0046                                        SimStateRef const& states,
0047                                        TrackSlotId tid);
0048 
0049     // Initialize the sim state
0050     inline CELER_FUNCTION SimTrackView& operator=(Initializer_t const& other);
0051 
0052     // Add the time change over the step
0053     inline CELER_FUNCTION void add_time(real_type delta);
0054 
0055     // Increment the total number of steps
0056     inline CELER_FUNCTION void increment_num_steps();
0057 
0058     // Update the number of steps this track has been looping
0059     inline CELER_FUNCTION void update_looping(bool);
0060 
0061     // Whether the looping track should be abandoned
0062     inline CELER_FUNCTION bool is_looping(ParticleId, Energy);
0063 
0064     // Set whether the track is alive
0065     inline CELER_FUNCTION void status(TrackStatus);
0066 
0067     // Reset step limiter
0068     inline CELER_FUNCTION void reset_step_limit();
0069 
0070     // Reset step limiter to the given limit
0071     inline CELER_FUNCTION void reset_step_limit(StepLimit const& sl);
0072 
0073     // Limit the step by this distance and action
0074     inline CELER_FUNCTION bool step_limit(StepLimit const& sl);
0075 
0076     //// DYNAMIC PROPERTIES ////
0077 
0078     // Unique track identifier
0079     inline CELER_FUNCTION TrackId track_id() const;
0080 
0081     // Track ID of parent
0082     inline CELER_FUNCTION TrackId parent_id() const;
0083 
0084     // Event ID
0085     inline CELER_FUNCTION EventId event_id() const;
0086 
0087     // Total number of steps taken by the track
0088     inline CELER_FUNCTION size_type num_steps() const;
0089 
0090     // Number of steps taken by the track since it was flagged as looping
0091     inline CELER_FUNCTION size_type num_looping_steps() const;
0092 
0093     // Time elapsed in the lab frame since the start of the event
0094     inline CELER_FUNCTION real_type time() const;
0095 
0096     // Whether the track is alive or inactive or dying
0097     inline CELER_FUNCTION TrackStatus status() const;
0098 
0099     // Limiting step
0100     inline CELER_FUNCTION real_type step_length() const;
0101 
0102     // Update limiting step
0103     inline CELER_FUNCTION void step_length(real_type length);
0104 
0105     // Access post-step action to take
0106     inline CELER_FUNCTION ActionId post_step_action() const;
0107 
0108     // Force the limiting action to take
0109     inline CELER_FUNCTION void post_step_action(ActionId action);
0110 
0111     // Access along-step action to take
0112     inline CELER_FUNCTION ActionId along_step_action() const;
0113 
0114     // Update along-step action to take
0115     inline CELER_FUNCTION void along_step_action(ActionId action);
0116 
0117     //// PARAMETER DATA ////
0118 
0119     // Particle-dependent parameters for killing looping tracks
0120     inline CELER_FUNCTION LoopingThreshold const&
0121         looping_threshold(ParticleId) const;
0122 
0123   private:
0124     SimParamsRef const& params_;
0125     SimStateRef const& states_;
0126     TrackSlotId const track_slot_;
0127 };
0128 
0129 //---------------------------------------------------------------------------//
0130 // INLINE DEFINITIONS
0131 //---------------------------------------------------------------------------//
0132 /*!
0133  * Construct from persistent and local data.
0134  */
0135 CELER_FUNCTION
0136 SimTrackView::SimTrackView(SimParamsRef const& params,
0137                            SimStateRef const& states,
0138                            TrackSlotId tid)
0139     : params_(params), states_(states), track_slot_(tid)
0140 {
0141     CELER_EXPECT(track_slot_ < states_.size());
0142 }
0143 
0144 //---------------------------------------------------------------------------//
0145 /*!
0146  * \brief Initialize the particle.
0147  */
0148 CELER_FUNCTION SimTrackView& SimTrackView::operator=(Initializer_t const& other)
0149 {
0150     states_.track_ids[track_slot_] = other.track_id;
0151     states_.parent_ids[track_slot_] = other.parent_id;
0152     states_.event_ids[track_slot_] = other.event_id;
0153     states_.num_steps[track_slot_] = 0;
0154     if (!states_.num_looping_steps.empty())
0155     {
0156         states_.num_looping_steps[track_slot_] = 0;
0157     }
0158     states_.time[track_slot_] = other.time;
0159     states_.status[track_slot_] = TrackStatus::initializing;
0160     states_.step_length[track_slot_] = {};
0161     states_.post_step_action[track_slot_] = {};
0162     states_.along_step_action[track_slot_] = {};
0163     return *this;
0164 }
0165 
0166 //---------------------------------------------------------------------------//
0167 /*!
0168  * Add the time change over the step.
0169  */
0170 CELER_FUNCTION void SimTrackView::add_time(real_type delta)
0171 {
0172     CELER_EXPECT(delta >= 0);
0173     states_.time[track_slot_] += delta;
0174 }
0175 
0176 //---------------------------------------------------------------------------//
0177 /*!
0178  * Increment the total number of steps.
0179  */
0180 CELER_FORCEINLINE_FUNCTION void SimTrackView::increment_num_steps()
0181 {
0182     ++states_.num_steps[track_slot_];
0183 }
0184 
0185 //---------------------------------------------------------------------------//
0186 /*!
0187  * Update the number of steps this track has been looping.
0188  */
0189 CELER_FUNCTION void SimTrackView::update_looping(bool is_looping)
0190 {
0191     CELER_EXPECT(!params_.looping.empty());
0192     if (is_looping)
0193     {
0194         ++states_.num_looping_steps[track_slot_];
0195     }
0196     else
0197     {
0198         states_.num_looping_steps[track_slot_] = 0;
0199     }
0200 }
0201 
0202 //---------------------------------------------------------------------------//
0203 /*!
0204  * Whether the looping track should be abandoned.
0205  */
0206 CELER_FUNCTION bool SimTrackView::is_looping(ParticleId pid, Energy energy)
0207 {
0208     CELER_EXPECT(!params_.looping.empty());
0209     auto const& looping = this->looping_threshold(pid);
0210     if (energy < looping.threshold_energy)
0211     {
0212         return this->num_looping_steps() >= looping.max_subthreshold_steps;
0213     }
0214     else
0215     {
0216         return this->num_looping_steps() >= looping.max_steps;
0217     }
0218     return false;
0219 }
0220 
0221 //---------------------------------------------------------------------------//
0222 /*!
0223  * Reset step limiter at the beginning of a step.
0224  *
0225  * The action can be unset if and only if the step is infinite.
0226  */
0227 CELER_FUNCTION void SimTrackView::reset_step_limit(StepLimit const& sl)
0228 {
0229     CELER_EXPECT(sl.step >= 0);
0230     CELER_EXPECT(static_cast<bool>(sl.action)
0231                  != (sl.step == numeric_limits<real_type>::infinity()));
0232     states_.step_length[track_slot_] = sl.step;
0233     states_.post_step_action[track_slot_] = sl.action;
0234 }
0235 
0236 //---------------------------------------------------------------------------//
0237 /*!
0238  * Reset step limiter at the beginning of a step.
0239  */
0240 CELER_FUNCTION void SimTrackView::reset_step_limit()
0241 {
0242     StepLimit limit;
0243     limit.step = numeric_limits<real_type>::infinity();
0244     limit.action = {};
0245     this->reset_step_limit(limit);
0246     this->along_step_action({});
0247 }
0248 
0249 //---------------------------------------------------------------------------//
0250 /*!
0251  * Force the limiting action to take.
0252  *
0253  * This is used by intermediate kernels (such as \c discrete_select_track )
0254  * that dispatch to another kernel action before the end of the step without
0255  * changing the step itself.
0256  */
0257 CELER_FUNCTION void SimTrackView::post_step_action(ActionId action)
0258 {
0259     CELER_ASSERT(action);
0260     states_.post_step_action[track_slot_] = action;
0261 }
0262 
0263 //---------------------------------------------------------------------------//
0264 /*!
0265  * Limit the step by this distance and action.
0266  *
0267  * If the step limits are the same, the original action is retained.
0268  *
0269  * \return Whether the given limit is the new limit.
0270  */
0271 CELER_FUNCTION bool SimTrackView::step_limit(StepLimit const& sl)
0272 {
0273     CELER_ASSERT(sl.step >= 0);
0274 
0275     bool is_limiting = (sl.step < states_.step_length[track_slot_]);
0276     if (is_limiting)
0277     {
0278         states_.step_length[track_slot_] = sl.step;
0279         states_.post_step_action[track_slot_] = sl.action;
0280     }
0281     return is_limiting;
0282 }
0283 
0284 //---------------------------------------------------------------------------//
0285 /*!
0286  * Access post-step action to take.
0287  */
0288 CELER_FORCEINLINE_FUNCTION ActionId SimTrackView::post_step_action() const
0289 {
0290     return states_.post_step_action[track_slot_];
0291 }
0292 
0293 //---------------------------------------------------------------------------//
0294 /*!
0295  * Access along-step action to take.
0296  */
0297 CELER_FORCEINLINE_FUNCTION ActionId SimTrackView::along_step_action() const
0298 {
0299     return states_.along_step_action[track_slot_];
0300 }
0301 
0302 //---------------------------------------------------------------------------//
0303 /*!
0304  * Update along-step action to take.
0305  */
0306 CELER_FORCEINLINE_FUNCTION void SimTrackView::along_step_action(ActionId action)
0307 {
0308     states_.along_step_action[track_slot_] = action;
0309 }
0310 
0311 //---------------------------------------------------------------------------//
0312 /*!
0313  * Set whether the track is active, dying, or inactive.
0314  */
0315 CELER_FUNCTION void SimTrackView::status(TrackStatus status)
0316 {
0317     CELER_EXPECT(status != TrackStatus::size_);
0318     states_.status[track_slot_] = status;
0319 }
0320 
0321 //---------------------------------------------------------------------------//
0322 // DYNAMIC PROPERTIES
0323 //---------------------------------------------------------------------------//
0324 /*!
0325  * Unique track identifier.
0326  */
0327 CELER_FORCEINLINE_FUNCTION TrackId SimTrackView::track_id() const
0328 {
0329     return states_.track_ids[track_slot_];
0330 }
0331 
0332 //---------------------------------------------------------------------------//
0333 /*!
0334  * Track ID of parent.
0335  */
0336 CELER_FORCEINLINE_FUNCTION TrackId SimTrackView::parent_id() const
0337 {
0338     return states_.parent_ids[track_slot_];
0339 }
0340 
0341 //---------------------------------------------------------------------------//
0342 /*!
0343  * Event ID.
0344  */
0345 CELER_FORCEINLINE_FUNCTION EventId SimTrackView::event_id() const
0346 {
0347     return states_.event_ids[track_slot_];
0348 }
0349 
0350 //---------------------------------------------------------------------------//
0351 /*!
0352  * Total number of steps taken by the track.
0353  */
0354 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::num_steps() const
0355 {
0356     return states_.num_steps[track_slot_];
0357 }
0358 
0359 //---------------------------------------------------------------------------//
0360 /*!
0361  * Number of steps taken by the track since it was flagged as looping.
0362  */
0363 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::num_looping_steps() const
0364 {
0365     return states_.num_looping_steps[track_slot_];
0366 }
0367 
0368 //---------------------------------------------------------------------------//
0369 /*!
0370  * Time elapsed in the lab frame since the start of the event [s].
0371  */
0372 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::time() const
0373 {
0374     return states_.time[track_slot_];
0375 }
0376 
0377 //---------------------------------------------------------------------------//
0378 /*!
0379  * Whether the track is inactive, alive, or being killed.
0380  */
0381 CELER_FORCEINLINE_FUNCTION TrackStatus SimTrackView::status() const
0382 {
0383     return states_.status[track_slot_];
0384 }
0385 
0386 //---------------------------------------------------------------------------//
0387 /*!
0388  * Get the current limiting step.
0389  */
0390 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::step_length() const
0391 {
0392     return states_.step_length[track_slot_];
0393 }
0394 
0395 //---------------------------------------------------------------------------//
0396 /*!
0397  * Update the current limiting step.
0398  */
0399 CELER_FUNCTION void SimTrackView::step_length(real_type length)
0400 {
0401     CELER_EXPECT(length > 0);
0402     states_.step_length[track_slot_] = length;
0403 }
0404 
0405 //---------------------------------------------------------------------------//
0406 /*!
0407  * Particle-dependent parameters for killing looping tracks.
0408  */
0409 CELER_FORCEINLINE_FUNCTION LoopingThreshold const&
0410 SimTrackView::looping_threshold(ParticleId pid) const
0411 {
0412     return params_.looping[pid];
0413 }
0414 
0415 //---------------------------------------------------------------------------//
0416 }  // namespace celeritas