Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-23 09:43:55

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/detail/Utils.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Assert.hh"
0010 #include "corecel/OpaqueId.hh"
0011 #include "corecel/Types.hh"
0012 #include "corecel/data/Collection.hh"
0013 #include "corecel/math/Atomics.hh"
0014 #include "corecel/sys/ThreadId.hh"
0015 #include "celeritas/global/CoreTrackData.hh"
0016 #include "celeritas/phys/ParticleView.hh"
0017 
0018 #include "../TrackInitData.hh"
0019 
0020 namespace celeritas
0021 {
0022 namespace detail
0023 {
0024 //---------------------------------------------------------------------------//
0025 struct IsEqual
0026 {
0027     TrackSlotId value;
0028 
0029     CELER_FUNCTION bool operator()(TrackSlotId x) const { return x == value; }
0030 };
0031 
0032 //---------------------------------------------------------------------------//
0033 //! Predicate for sorting charged from neutral tracks
0034 struct IsNeutral
0035 {
0036     using ParamsPtr = CRefPtr<CoreParamsData, MemSpace::native>;
0037 
0038     ParamsPtr params;
0039 
0040     CELER_FUNCTION bool operator()(TrackInitializer const& ti) const
0041     {
0042         return ParticleView(params->particles, ti.particle.particle_id).charge()
0043                == zero_quantity();
0044     }
0045 };
0046 
0047 //---------------------------------------------------------------------------//
0048 //! Predicate for sorting charged from neutral tracks with a stencil
0049 struct IsNeutralStencil
0050 {
0051     using ParamsPtr = CRefPtr<CoreParamsData, MemSpace::native>;
0052 
0053     ParamsPtr params;
0054     TrackInitializer const* initializers;
0055 
0056     CELER_FUNCTION bool operator()(size_type i) const
0057     {
0058         CELER_EXPECT(initializers);
0059         return IsNeutral{params}(initializers[i]);
0060     }
0061 };
0062 
0063 //---------------------------------------------------------------------------//
0064 //! Indicate that a track slot is occupied by a still-alive track
0065 CELER_CONSTEXPR_FUNCTION TrackSlotId occupied()
0066 {
0067     return TrackSlotId{};
0068 }
0069 
0070 //---------------------------------------------------------------------------//
0071 //! Get an initializer index where thread 0 has the last valid element
0072 CELER_FORCEINLINE_FUNCTION size_type index_before(size_type size, ThreadId tid)
0073 {
0074     CELER_EXPECT(tid.get() + 1 <= size);
0075     return size - tid.unchecked_get() - 1;
0076 }
0077 
0078 //---------------------------------------------------------------------------//
0079 //! Get an initializer index a certain number of threads past the end
0080 CELER_FORCEINLINE_FUNCTION size_type index_after(size_type size, ThreadId tid)
0081 {
0082     CELER_EXPECT(tid);
0083     return size + tid.unchecked_get();
0084 }
0085 
0086 //---------------------------------------------------------------------------//
0087 //! Get an initializer index starting from one end or the other
0088 CELER_FORCEINLINE_FUNCTION size_type index_partitioned(size_type num_new_tracks,
0089                                                        size_type num_vacancies,
0090                                                        bool get_from_front,
0091                                                        ThreadId tid)
0092 {
0093     CELER_EXPECT(tid.get() < num_new_tracks);
0094     CELER_EXPECT(num_new_tracks <= num_vacancies);
0095 
0096     return get_from_front ? index_before(num_new_tracks, tid)
0097                           : index_before(num_vacancies, tid);
0098 }
0099 
0100 //---------------------------------------------------------------------------//
0101 /*!
0102  * Create a unique track ID for the given event.
0103  *
0104  * \todo This is nondeterministic; we need to calculate the track ID in a
0105  * reproducible way.
0106  */
0107 inline CELER_FUNCTION TrackId
0108 make_track_id(NativeCRef<TrackInitParamsData> const&,
0109               NativeRef<TrackInitStateData>& state,
0110               EventId event)
0111 {
0112     CELER_EXPECT(event < state.track_counters.size());
0113     auto result
0114         = atomic_add(&state.track_counters[event], TrackId::size_type{1});
0115     return TrackId{result};
0116 }
0117 
0118 //---------------------------------------------------------------------------//
0119 }  // namespace detail
0120 }  // namespace celeritas