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