Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-09 10:15:05

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/optical/CoreTrackView.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/math/Atomics.hh"
0010 #include "corecel/random/engine/RngEngine.hh"
0011 #include "corecel/sys/ThreadId.hh"
0012 #include "geocel/AllVolumesView.hh"
0013 #include "geocel/DetectorView.hh"
0014 #include "geocel/VolumeSurfaceView.hh"
0015 #include "celeritas/geo/CoreGeoTrackView.hh"
0016 
0017 #include "CoreTrackData.hh"
0018 #include "MaterialView.hh"
0019 #include "ParticleTrackView.hh"
0020 #include "PhysicsTrackView.hh"
0021 #include "SimTrackView.hh"
0022 #include "TrackInitializer.hh"
0023 #include "surface/SurfacePhysicsTrackView.hh"
0024 
0025 #if !CELER_DEVICE_COMPILE
0026 #    include "corecel/io/Logger.hh"
0027 #endif
0028 
0029 namespace celeritas
0030 {
0031 namespace optical
0032 {
0033 //---------------------------------------------------------------------------//
0034 /*!
0035  * Access all core properties of a physics track.
0036  */
0037 class CoreTrackView
0038 {
0039   public:
0040     //!@{
0041     //! \name Type aliases
0042     using ParamsRef = NativeCRef<CoreParamsData>;
0043     using StateRef = NativeRef<CoreStateData>;
0044     //!@}
0045 
0046   public:
0047     // Construct directly from a track slot ID
0048     inline CELER_FUNCTION CoreTrackView(
0049         ParamsRef const& params, StateRef const& states, TrackSlotId slot);
0050 
0051     // Initialize the track states
0052     inline CELER_FUNCTION CoreTrackView& operator=(TrackInitializer const&);
0053 
0054     // Return a geometry view
0055     inline CELER_FUNCTION GeoTrackView geometry() const;
0056 
0057     // Return a material view
0058     inline CELER_FUNCTION MaterialView material_record() const;
0059 
0060     // Return a material view (using an existing geo view)
0061     inline CELER_FUNCTION MaterialView material_record(
0062         GeoTrackView const&) const;
0063 
0064     // Return a material view for a specific optical material
0065     inline CELER_FUNCTION MaterialView material_record(OptMatId) const;
0066 
0067     // Return a simulation management view
0068     inline CELER_FUNCTION SimTrackView sim() const;
0069 
0070     // Return a particle view
0071     inline CELER_FUNCTION ParticleTrackView particle() const;
0072 
0073     // Return a physics view
0074     inline CELER_FUNCTION PhysicsTrackView physics() const;
0075 
0076     // Return a volume surface view
0077     inline CELER_FUNCTION VolumeSurfaceView surface() const;
0078 
0079     // Return a volume surface view from volume ID
0080     inline CELER_FUNCTION VolumeSurfaceView surface(VolumeId) const;
0081 
0082     // Return a surface physics view
0083     inline CELER_FUNCTION SurfacePhysicsTrackView surface_physics() const;
0084 
0085     // Return a sensitive detector view
0086     inline CELER_FUNCTION DetectorView detectors() const;
0087 
0088     // Return a device-compatible view of all volumes
0089     inline CELER_FUNCTION AllVolumesView volumes() const;
0090 
0091     // Return an RNG engine
0092     inline CELER_FUNCTION RngEngine rng() const;
0093 
0094     // Get the track's index among the states
0095     inline CELER_FUNCTION TrackSlotId track_slot_id() const;
0096 
0097     // Flag a track for deletion
0098     inline CELER_FUNCTION void apply_errored();
0099 
0100     // Apply a tracking cut without setting the error state
0101     inline CELER_FUNCTION void apply_cut();
0102 
0103     // Access global step counters (mutable for atomic operations)
0104     inline CELER_FUNCTION CoreStateCounters& counters();
0105     inline CELER_FUNCTION CoreStateCounters const& counters() const;
0106 
0107   private:
0108     ParamsRef const& params_;
0109     StateRef const& states_;
0110     TrackSlotId const track_slot_id_;
0111 };
0112 
0113 //---------------------------------------------------------------------------//
0114 // INLINE DEFINITIONS
0115 //---------------------------------------------------------------------------//
0116 /*!
0117  * Construct with comprehensive param/state data and track slot.
0118  *
0119  * For optical tracks, the value of the track slot is the same as the track ID.
0120  */
0121 CELER_FUNCTION CoreTrackView::CoreTrackView(
0122     ParamsRef const& params, StateRef const& states, TrackSlotId track_slot)
0123     : params_(params), states_(states), track_slot_id_(track_slot)
0124 {
0125     CELER_EXPECT(track_slot_id_ < states_.size());
0126 }
0127 
0128 //---------------------------------------------------------------------------//
0129 /*!
0130  * Initialize the track states.
0131  */
0132 CELER_FUNCTION CoreTrackView& CoreTrackView::operator=(
0133     TrackInitializer const& init)
0134 {
0135     // Initialiize the sim state
0136     this->sim() = SimTrackView::Initializer{init.primary, init.time};
0137 
0138     // Initialize the geometry state
0139     auto geo = this->geometry();
0140     geo = GeoTrackInitializer{init.position, init.direction, {}};
0141     if (CELER_UNLIKELY(geo.failed() || geo.is_outside()))
0142     {
0143 #if !CELER_DEVICE_COMPILE
0144         if (geo.is_outside())
0145         {
0146             // Print an error message if initialization was "successful" but
0147             // track is outside
0148             CELER_LOG_LOCAL(error) << "Track started outside the geometry";
0149         }
0150 #endif
0151         this->apply_errored();
0152         return *this;
0153     }
0154 
0155     // Initialize the particle state
0156     this->particle()
0157         = ParticleTrackView::Initializer{init.energy, init.polarization};
0158 
0159     // Initialize the physics state
0160     this->physics() = PhysicsTrackView::Initializer{};
0161 
0162     // Initialize the surface state
0163     this->surface_physics().reset();
0164 
0165     return *this;
0166 }
0167 
0168 //---------------------------------------------------------------------------//
0169 /*!
0170  * Return a geometry view.
0171  */
0172 CELER_FUNCTION auto CoreTrackView::geometry() const -> GeoTrackView
0173 {
0174     return GeoTrackView{
0175         params_.geometry, states_.geometry, this->track_slot_id()};
0176 }
0177 
0178 //---------------------------------------------------------------------------//
0179 /*!
0180  * Return a material view.
0181  */
0182 CELER_FORCEINLINE_FUNCTION auto CoreTrackView::material_record() const
0183     -> MaterialView
0184 {
0185     return this->material_record(this->geometry());
0186 }
0187 
0188 //---------------------------------------------------------------------------//
0189 /*!
0190  * Return a material view using an existing geo track view.
0191  */
0192 CELER_FUNCTION auto CoreTrackView::material_record(
0193     GeoTrackView const& geo) const -> MaterialView
0194 {
0195     CELER_EXPECT(!geo.is_outside());
0196     return MaterialView{params_.material, geo.impl_volume_id()};
0197 }
0198 
0199 //---------------------------------------------------------------------------//
0200 /*!
0201  * Return a material view for a specific optical material ID.
0202  */
0203 CELER_FUNCTION auto CoreTrackView::material_record(OptMatId opt_mat) const
0204     -> MaterialView
0205 {
0206     auto material = MaterialView{params_.material, opt_mat};
0207     CELER_ENSURE(material);
0208     return material;
0209 }
0210 
0211 //---------------------------------------------------------------------------//
0212 /*!
0213  * Return a particle view.
0214  */
0215 CELER_FUNCTION auto CoreTrackView::particle() const -> ParticleTrackView
0216 {
0217     return ParticleTrackView{states_.particle, this->track_slot_id()};
0218 }
0219 
0220 //---------------------------------------------------------------------------//
0221 /*!
0222  * Return a physics view.
0223  */
0224 CELER_FUNCTION auto CoreTrackView::physics() const -> PhysicsTrackView
0225 {
0226     OptMatId mat_id = this->material_record().material_id();
0227     CELER_ASSERT(mat_id);
0228     return PhysicsTrackView{
0229         params_.physics, states_.physics, mat_id, this->track_slot_id()};
0230 }
0231 
0232 //---------------------------------------------------------------------------//
0233 /*!
0234  * Return a volume surface view into the track's current volume.
0235  */
0236 CELER_FUNCTION auto CoreTrackView::surface() const -> VolumeSurfaceView
0237 {
0238     return this->surface(this->geometry().volume_id());
0239 }
0240 
0241 //---------------------------------------------------------------------------//
0242 /*!
0243  * Return a volume surface view from volume ID.
0244  */
0245 CELER_FUNCTION auto CoreTrackView::surface(VolumeId vol) const
0246     -> VolumeSurfaceView
0247 {
0248     CELER_EXPECT(vol);
0249     return VolumeSurfaceView{params_.surface, vol};
0250 }
0251 
0252 //---------------------------------------------------------------------------//
0253 /*!
0254  * Return a surface physics view.
0255  */
0256 CELER_FUNCTION auto CoreTrackView::surface_physics() const
0257     -> SurfacePhysicsTrackView
0258 {
0259     return SurfacePhysicsTrackView{params_.surface_physics,
0260                                    states_.surface_physics,
0261                                    this->track_slot_id()};
0262 }
0263 
0264 //---------------------------------------------------------------------------//
0265 /*!
0266  * Return a sensitive detector view.
0267  */
0268 CELER_FUNCTION auto CoreTrackView::detectors() const -> DetectorView
0269 {
0270     return DetectorView{params_.detectors};
0271 }
0272 
0273 //---------------------------------------------------------------------------//
0274 /*!
0275  * Return a device-compatible view of all volumes.
0276  */
0277 CELER_FUNCTION AllVolumesView CoreTrackView::volumes() const
0278 {
0279     return AllVolumesView{params_.volumes};
0280 }
0281 
0282 //---------------------------------------------------------------------------//
0283 /*!
0284  * Return the RNG engine.
0285  */
0286 CELER_FUNCTION auto CoreTrackView::rng() const -> RngEngine
0287 {
0288     return RngEngine{params_.rng, states_.rng, this->track_slot_id()};
0289 }
0290 
0291 //---------------------------------------------------------------------------//
0292 /*!
0293  * Return a simulation management view.
0294  */
0295 CELER_FUNCTION SimTrackView CoreTrackView::sim() const
0296 {
0297     return SimTrackView{params_.sim, states_.sim, this->track_slot_id()};
0298 }
0299 
0300 //---------------------------------------------------------------------------//
0301 /*!
0302  * Get the track's index among the states.
0303  */
0304 CELER_FORCEINLINE_FUNCTION TrackSlotId CoreTrackView::track_slot_id() const
0305 {
0306     return track_slot_id_;
0307 }
0308 
0309 //---------------------------------------------------------------------------//
0310 /*!
0311  * Access the global step counters.
0312  */
0313 CELER_FUNCTION CoreStateCounters& CoreTrackView::counters()
0314 {
0315     return *states_.init.counters.data().get();
0316 }
0317 
0318 //---------------------------------------------------------------------------//
0319 //! \cond
0320 CELER_FUNCTION CoreStateCounters const& CoreTrackView::counters() const
0321 {
0322     return *states_.init.counters.data().get();
0323 }
0324 //! \endcond
0325 
0326 //---------------------------------------------------------------------------//
0327 /*!
0328  * Set the 'errored' flag and tracking cut post-step action.
0329  *
0330  * \pre This cannot be applied if the current action is *after* post-step. (You
0331  * can't guarantee for example that sensitive detectors will pick up the energy
0332  * deposition.)
0333  *
0334  * \todo Add a tracking cut action? Currently the track is simply killed.
0335  */
0336 CELER_FUNCTION void CoreTrackView::apply_errored()
0337 {
0338     using namespace celeritas::literals;
0339     auto sim = this->sim();
0340     CELER_EXPECT(is_track_valid(sim.status()));
0341     sim.status(TrackStatus::errored);
0342     sim.post_step_action(params_.scalars.tracking_cut_action);
0343     atomic_add(&this->counters().num_errored, 1_sz);
0344 }
0345 
0346 //---------------------------------------------------------------------------//
0347 /*!
0348  * Apply a tracking cut without setting the error state.
0349  */
0350 CELER_FUNCTION void CoreTrackView::apply_cut()
0351 {
0352     using namespace celeritas::literals;
0353     auto sim = this->sim();
0354     CELER_EXPECT(is_track_valid(sim.status()));
0355     sim.post_step_action(params_.scalars.tracking_cut_action);
0356     atomic_add(&this->counters().num_cut, 1_sz);
0357 }
0358 
0359 //---------------------------------------------------------------------------//
0360 }  // namespace optical
0361 }  // namespace celeritas