|
|
|||
File indexing completed on 2026-11-09 10:15:02
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/action/detail/DetectorExecutor.hh 0006 //---------------------------------------------------------------------------// 0007 #pragma once 0008 0009 #include "celeritas/Types.hh" 0010 #include "celeritas/optical/CoreTrackView.hh" 0011 #include "celeritas/optical/DetectorData.hh" 0012 #include "celeritas/optical/SimTrackView.hh" 0013 0014 namespace celeritas 0015 { 0016 namespace optical 0017 { 0018 namespace detail 0019 { 0020 //---------------------------------------------------------------------------// 0021 /*! 0022 * Populate detector state buffer at the end of a step. 0023 * 0024 * All tracks have hits copied into the state buffer. If the track is not alive 0025 * or is not in a detector region, an invalid hit is set in the corresponding 0026 * buffer track slot. 0027 * 0028 * Detection can occur after a surface crossing \em or (for coupled EM 0029 * problems) if an optical photon is emitted inside a detector region. 0030 * 0031 * When a track generates a valid hit, it is killed (absorbed by the detector). 0032 * 0033 * \note This is called by \em all track slots, which is necessary to clear the 0034 * outgoing detector hits. We could break this into a "reset" kernel that 0035 * applies to all slots, and a "fill" kernel that applies only to valid slots. 0036 */ 0037 struct DetectorExecutor 0038 { 0039 NativeRef<DetectorStateData> detector_state_; 0040 0041 // Copy track hit into the state buffer 0042 inline CELER_FUNCTION void operator()(CoreTrackView const&) const; 0043 }; 0044 0045 //---------------------------------------------------------------------------// 0046 // INLINE DEFINITIONS 0047 //---------------------------------------------------------------------------// 0048 /*! 0049 * Copy track hit into the state buffer. 0050 */ 0051 CELER_FUNCTION void DetectorExecutor::operator()( 0052 CoreTrackView const& track) const 0053 { 0054 auto& hit = detector_state_.detector_hits[track.track_slot_id()]; 0055 // Clear the hit if inactive, errored, or not detected 0056 hit.detector = {}; 0057 0058 auto sim = track.sim(); 0059 0060 if (!is_track_valid(sim.status())) 0061 { 0062 // Inactive or errored 0063 return; 0064 } 0065 if (track.surface_physics().is_crossing_boundary()) 0066 { 0067 // Boundary crossing not yet completed, so not yet detected! 0068 return; 0069 } 0070 0071 auto geometry = track.geometry(); 0072 if (geometry.is_outside()) 0073 { 0074 // Killed by leaving geometry; no detection 0075 return; 0076 } 0077 0078 auto const detectors = track.detectors(); 0079 auto const volume_id = geometry.volume_id(); 0080 auto const detector_id = detectors.detector_id(volume_id); 0081 0082 if (!detector_id) 0083 { 0084 // Not in a detector 0085 return; 0086 } 0087 0088 // Score a valid hit 0089 hit.detector = detector_id; 0090 hit.primary = sim.primary_id(); 0091 hit.energy = track.particle().energy(); 0092 hit.time = sim.time(); 0093 hit.position = geometry.pos(); 0094 hit.volume_instance = geometry.volume_instance_id(); 0095 hit.num_steps = sim.num_steps(); 0096 hit.path_length = sim.step_length(); 0097 0098 // Construct unique instance ID from geometry volume path 0099 auto accum = track.volumes().path_accumulator(); 0100 hit.unique_instance = {}; 0101 geometry.foreach_volume_path([&](VolumeLevelId, VolumeInstanceId vi) { 0102 hit.unique_instance = accum(hit.unique_instance, vi); 0103 }); 0104 0105 // Kill the track 0106 sim.status(TrackStatus::killed); 0107 } 0108 0109 //---------------------------------------------------------------------------// 0110 } // namespace detail 0111 } // namespace optical 0112 } // namespace celeritas
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|