![]() |
|
|||
File indexing completed on 2025-02-22 10:31:28
0001 //----------------------------------*-C++-*----------------------------------// 0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers. 0003 // See the top-level COPYRIGHT file for details. 0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0005 //---------------------------------------------------------------------------// 0006 //! \file celeritas/optical/ScintillationData.hh 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include "corecel/Macros.hh" 0011 #include "corecel/Types.hh" 0012 #include "corecel/data/Collection.hh" 0013 #include "celeritas/Types.hh" 0014 #include "celeritas/grid/GenericGridData.hh" 0015 #include "celeritas/optical/Types.hh" 0016 0017 namespace celeritas 0018 { 0019 namespace optical 0020 { 0021 //---------------------------------------------------------------------------// 0022 /*! 0023 * Parameterized scintillation properties. 0024 * 0025 * This component represents one type of scintillation emissions, such as 0026 * prompt/fast, intermediate, or slow. It can be specific to a material or 0027 * depend on the incident particle type. 0028 */ 0029 struct ScintRecord 0030 { 0031 real_type lambda_mean{}; //!< Mean wavelength 0032 real_type lambda_sigma{}; //!< Standard deviation of wavelength 0033 real_type rise_time{}; //!< Rise time 0034 real_type fall_time{}; //!< Decay time 0035 0036 //! Whether all data are assigned and valid 0037 explicit CELER_FUNCTION operator bool() const 0038 { 0039 return lambda_mean > 0 && lambda_sigma > 0 && rise_time >= 0 0040 && fall_time > 0; 0041 } 0042 }; 0043 0044 //---------------------------------------------------------------------------// 0045 /*! 0046 * Material-dependent scintillation spectrum. 0047 * 0048 * - \c yield_per_energy is the characteristic light yield of the material in 0049 * [1/MeV] units. The total light yield per step is then 0050 * `yield_per_energy * energy_dep`, which results in a (unitless) number of 0051 * photons. 0052 * - \c yield_pdf is the probability of choosing from a given component. 0053 * - \c components stores the different scintillation components 0054 * (fast/slow/etc) for this material. 0055 */ 0056 struct MatScintSpectrumRecord 0057 { 0058 real_type yield_per_energy{}; //!< [1/MeV] 0059 ItemRange<real_type> yield_pdf; 0060 ItemRange<ScintRecord> components; 0061 0062 //! Whether all data are assigned and valid 0063 explicit CELER_FUNCTION operator bool() const 0064 { 0065 return yield_per_energy > 0 && !yield_pdf.empty() 0066 && yield_pdf.size() == components.size(); 0067 } 0068 }; 0069 0070 //---------------------------------------------------------------------------// 0071 /*! 0072 * Particle- and material-dependent scintillation spectrum. 0073 * 0074 * - \c yield_vector is the characteristic light yield for different energies. 0075 * - \c yield_pdf is the probability of choosing from a given component. 0076 * - \c components stores the fast/slow/etc scintillation components for this 0077 * particle type. 0078 */ 0079 struct ParScintSpectrumRecord 0080 { 0081 GenericGridRecord yield_per_energy; //! [MeV] -> [1/MeV] 0082 ItemRange<real_type> yield_pdf; 0083 ItemRange<ScintRecord> components; 0084 0085 //! Whether all data are assigned and valid 0086 explicit CELER_FUNCTION operator bool() const 0087 { 0088 return yield_per_energy && !yield_pdf.empty() 0089 && yield_pdf.size() == components.size(); 0090 } 0091 }; 0092 0093 //---------------------------------------------------------------------------// 0094 /*! 0095 * Data characterizing the scintillation spectrum for all particles and 0096 * materials. 0097 * 0098 * Sampling using material-only data or particle- and material-dependent data 0099 * are mutually exclusive. Therefore, either \c materials or \c particles are 0100 * loaded at the beginning of the simulation, but *never* both at the same 0101 * time. The \c scintillation_by_particle() function can be used to check that. 0102 * 0103 * - \c pid_to_scintpid returns a \c ScintillationParticleId given a 0104 * \c ParticleId . 0105 * - \c resolution_scale is indexed by \c OpticalMaterialId . 0106 * - \c materials stores material-only scintillation data. Indexed by 0107 * \c OpticalMaterialId 0108 * - \c particles stores scintillation spectrum for each particle type for each 0109 * material, being a grid of size `num_particles * num_materials`. Therefore 0110 * it is indexed by \c ParticleScintSpectrumId , which combines 0111 * \c ScintillationParticleId and \c OpticalMaterialId . Use the 0112 * \c spectrum_index() function to retrieve the correct index. 0113 */ 0114 template<Ownership W, MemSpace M> 0115 struct ScintillationData 0116 { 0117 template<class T> 0118 using Items = Collection<T, W, M>; 0119 template<class T> 0120 using OpticalMaterialItems = Collection<T, W, M, OpticalMaterialId>; 0121 template<class T> 0122 using ScintPidItems = Collection<T, W, M, ParticleScintSpectrumId>; 0123 0124 //// MEMBER DATA //// 0125 0126 //! Number of scintillation particles, used by this->spectrum_index 0127 size_type num_scint_particles{}; 0128 0129 //! Resolution scale for each material [OpticalMaterialid] 0130 OpticalMaterialItems<real_type> resolution_scale; 0131 //! Material-dependent scintillation spectrum data [OpticalMaterialid] 0132 OpticalMaterialItems<MatScintSpectrumRecord> materials; 0133 0134 //! Index between ScintillationParticleId and ParticleId 0135 Collection<ScintillationParticleId, W, M, ParticleId> pid_to_scintpid; 0136 //! Particle/material scintillation spectrum data [ParticleScintSpectrumId] 0137 ScintPidItems<ParScintSpectrumRecord> particles; 0138 0139 //! Backend storage for real values 0140 Items<real_type> reals; 0141 //! Backend storage for scintillation components 0142 Items<ScintRecord> scint_records; 0143 0144 //// MEMBER FUNCTIONS //// 0145 0146 //! Whether all data are assigned and valid 0147 explicit CELER_FUNCTION operator bool() const 0148 { 0149 return !resolution_scale.empty() 0150 && (materials.empty() != particles.empty()) 0151 && (!pid_to_scintpid.empty() == !particles.empty()) 0152 && (!pid_to_scintpid.empty() == (num_scint_particles > 0)); 0153 } 0154 0155 //! Whether sampling must happen by particle type 0156 CELER_FUNCTION bool scintillation_by_particle() const 0157 { 0158 return !particles.empty(); 0159 } 0160 0161 //! Retrieve spectrum index given optical particle and material ids 0162 ParticleScintSpectrumId 0163 spectrum_index(ScintillationParticleId pid, OpticalMaterialId mat_id) const 0164 { 0165 // Resolution scale exists independent of material-only data and it's 0166 // indexed by optical material id 0167 CELER_EXPECT(pid < num_scint_particles 0168 && mat_id < resolution_scale.size()); 0169 return ParticleScintSpectrumId{resolution_scale.size() * pid.get() 0170 + mat_id.get()}; 0171 } 0172 0173 //! Assign from another set of data 0174 template<Ownership W2, MemSpace M2> 0175 ScintillationData& operator=(ScintillationData<W2, M2> const& other) 0176 { 0177 CELER_EXPECT(other); 0178 resolution_scale = other.resolution_scale; 0179 materials = other.materials; 0180 pid_to_scintpid = other.pid_to_scintpid; 0181 num_scint_particles = other.num_scint_particles; 0182 particles = other.particles; 0183 reals = other.reals; 0184 scint_records = other.scint_records; 0185 return *this; 0186 } 0187 }; 0188 0189 //---------------------------------------------------------------------------// 0190 } // namespace optical 0191 } // 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 |
![]() ![]() |