Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-04 09:58:03

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