Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-07 10:01:46

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/track/SimData.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <vector>
0010 
0011 #include "corecel/Macros.hh"
0012 #include "corecel/Types.hh"
0013 #include "corecel/data/Collection.hh"
0014 #include "corecel/data/CollectionAlgorithms.hh"
0015 #include "corecel/data/CollectionBuilder.hh"
0016 #include "corecel/sys/ThreadId.hh"
0017 #include "celeritas/Quantities.hh"
0018 #include "celeritas/Types.hh"
0019 
0020 namespace celeritas
0021 {
0022 //---------------------------------------------------------------------------//
0023 /*!
0024  * Particle-dependent parameters for killing looping tracks.
0025  *
0026  * These threshold values are used to determine when tracks that are flagged as
0027  * looping (i.e., taking a large number of substeps in the field propagator)
0028  * should be killed.
0029  *
0030  * In Geant4, tracks are killed immediately if their energy is below the
0031  * "important energy" (equivalent to \c threshold_energy here) or after some
0032  * number of step iterations if their energy is above the threshold.
0033  *
0034  * In Celeritas, the default \c max_substeps in the field propagator is set to
0035  * a smaller value than in Geant4. Therefore, an additional parameter \c
0036  * max_subthreshold_steps is added to approximate Geant4's policy for killing
0037  * looping tracks: a track flagged as looping will be killed if its energy is
0038  * below \c threshold_energy and it has taken more then \c
0039  * max_subthreshold_steps steps, or after \c max_steps steps if its energy is
0040  * above the threshold.
0041  */
0042 struct LoopingThreshold
0043 {
0044     using Energy = units::MevEnergy;
0045 
0046     size_type max_subthreshold_steps{10};
0047     size_type max_steps{100};
0048     Energy threshold_energy{250};
0049 
0050     //! Whether the data are assigned
0051     explicit CELER_FUNCTION operator bool() const
0052     {
0053         return max_subthreshold_steps > 0 && max_steps > 0
0054                && threshold_energy >= zero_quantity();
0055     }
0056 };
0057 
0058 //---------------------------------------------------------------------------//
0059 /*!
0060  * Shared simulation data.
0061  *
0062  * These are cutoff parameters based on the number of steps a track has taken.
0063  * Currently these are global or per particle type (with a single energy cut);
0064  * we should make them [energy, particle, region] for full extensibility.
0065  *
0066  * \note These params are used both by the main tracking loop \em and the
0067  * SimTrackView in optical physics.
0068  */
0069 template<Ownership W, MemSpace M>
0070 struct SimParamsData
0071 {
0072     //// TYPES ////
0073 
0074     template<class T>
0075     using ParticleItems = Collection<T, W, M, ParticleId>;
0076 
0077     //// DATA ////
0078 
0079     ParticleItems<LoopingThreshold> looping;
0080     size_type max_steps{};
0081 
0082     //// METHODS ////
0083 
0084     //! Whether the data are assigned
0085     explicit CELER_FUNCTION operator bool() const { return max_steps > 0; }
0086 
0087     //! Assign from another set of data
0088     template<Ownership W2, MemSpace M2>
0089     SimParamsData& operator=(SimParamsData<W2, M2> const& other)
0090     {
0091         CELER_EXPECT(other);
0092         looping = other.looping;
0093         max_steps = other.max_steps;
0094         return *this;
0095     }
0096 };
0097 
0098 //---------------------------------------------------------------------------//
0099 /*!
0100  * Simulation state of a track.
0101  */
0102 struct SimTrackInitializer
0103 {
0104     TrackId track_id;  //!< Unique ID for this track
0105     TrackId parent_id;  //!< ID of parent that created it
0106     PrimaryId primary_id;  //!< ID of originating primary
0107     EventId event_id;  //!< ID of originating event
0108     real_type time{0};  //!< Time elapsed in lab frame since start of event
0109     real_type weight{1.0};
0110     //! True if assigned and valid
0111     explicit CELER_FUNCTION operator bool() const
0112     {
0113         return track_id && event_id;
0114     }
0115 };
0116 
0117 //---------------------------------------------------------------------------//
0118 /*!
0119  * Data storage/access for simulation states.
0120  *
0121  * Unless otherwise specified, units are in the native system (time = s for
0122  * CGS, step length = cm).
0123  *
0124  * \c num_looping_steps will be empty if params doesn't specify any looping
0125  * threshold.
0126  */
0127 template<Ownership W, MemSpace M>
0128 struct SimStateData
0129 {
0130     //// TYPES ////
0131 
0132     template<class T>
0133     using Items = celeritas::StateCollection<T, W, M>;
0134 
0135     //// DATA ////
0136 
0137     Items<TrackId> track_ids;  //!< Unique ID for this track
0138     Items<PrimaryId> primary_ids;  //!< ID of originating primary
0139     Items<TrackId> parent_ids;  //!< ID of parent that created it
0140     Items<EventId> event_ids;  //!< ID of originating event
0141     Items<size_type> num_steps;  //!< Total number of steps taken
0142     Items<size_type> num_looping_steps;  //!< Number of steps taken since the
0143                                          //!< track was flagged as looping
0144     Items<real_type> time;  //!< Time elapsed in lab frame since start of event
0145 
0146     Items<TrackStatus> status;
0147     Items<real_type> step_length;
0148     Items<ActionId> post_step_action;
0149     Items<ActionId> along_step_action;
0150     Items<real_type> weight;
0151 
0152     //// METHODS ////
0153 
0154     //! Check whether the interface is assigned
0155     explicit CELER_FUNCTION operator bool() const
0156     {
0157         return !track_ids.empty() && !primary_ids.empty()
0158                && !parent_ids.empty() && !event_ids.empty()
0159                && !num_steps.empty() && !time.empty() && !status.empty()
0160                && !step_length.empty() && !post_step_action.empty()
0161                && !along_step_action.empty();
0162     }
0163 
0164     //! State size
0165     CELER_FUNCTION TrackSlotId::size_type size() const
0166     {
0167         return track_ids.size();
0168     }
0169 
0170     //! Assign from another set of data
0171     template<Ownership W2, MemSpace M2>
0172     SimStateData& operator=(SimStateData<W2, M2>& other)
0173     {
0174         CELER_EXPECT(other);
0175         track_ids = other.track_ids;
0176         primary_ids = other.primary_ids;
0177         parent_ids = other.parent_ids;
0178         event_ids = other.event_ids;
0179         num_steps = other.num_steps;
0180         num_looping_steps = other.num_looping_steps;
0181         time = other.time;
0182         status = other.status;
0183         step_length = other.step_length;
0184         post_step_action = other.post_step_action;
0185         along_step_action = other.along_step_action;
0186         weight = other.weight;
0187         return *this;
0188     }
0189 };
0190 
0191 //---------------------------------------------------------------------------//
0192 /*!
0193  * Resize simulation states and set \c alive to be false.
0194  */
0195 template<MemSpace M>
0196 void resize(SimStateData<Ownership::value, M>* data,
0197             HostCRef<SimParamsData> const& params,
0198             size_type size)
0199 {
0200     CELER_EXPECT(size > 0);
0201 
0202     resize(&data->track_ids, size);
0203     resize(&data->primary_ids, size);
0204     resize(&data->parent_ids, size);
0205     resize(&data->event_ids, size);
0206     resize(&data->num_steps, size);
0207     if (!params.looping.empty())
0208     {
0209         resize(&data->num_looping_steps, size);
0210     }
0211     resize(&data->time, size);
0212 
0213     resize(&data->status, size);
0214     fill(TrackStatus::inactive, &data->status);
0215 
0216     resize(&data->step_length, size);
0217     resize(&data->post_step_action, size);
0218     resize(&data->along_step_action, size);
0219     resize(&data->weight, size);
0220 
0221     CELER_ENSURE(*data);
0222 }
0223 
0224 //---------------------------------------------------------------------------//
0225 }  // namespace celeritas