File indexing completed on 2026-11-07 10:11:38
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/data/StackAllocator.hh"
0012 #include "corecel/random/distribution/ExponentialDistribution.hh"
0013 #include "corecel/random/distribution/IsotropicDistribution.hh"
0014 #include "corecel/random/distribution/UniformRealDistribution.hh"
0015 #include "celeritas/Types.hh"
0016 #include "celeritas/grid/NonuniformGridCalculator.hh"
0017 #include "celeritas/optical/Interaction.hh"
0018 #include "celeritas/optical/ParticleTrackView.hh"
0019 #include "celeritas/optical/TrackInitializer.hh"
0020 #include "celeritas/optical/WavelengthShiftData.hh"
0021 #include "celeritas/phys/InteractionUtils.hh"
0022
0023 namespace celeritas
0024 {
0025 namespace optical
0026 {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 class WavelengthShiftGenerator
0045 {
0046 public:
0047
0048 inline CELER_FUNCTION WavelengthShiftGenerator(
0049 NativeCRef<WavelengthShiftData> const& shared,
0050 WlsDistributionData const& distribution);
0051
0052
0053 template<class Engine>
0054 inline CELER_FUNCTION TrackInitializer operator()(Engine& rng);
0055
0056 private:
0057
0058
0059 using Energy = units::MevEnergy;
0060
0061
0062
0063 WlsDistributionData const& distribution_;
0064 real_type time_constant_;
0065 WlsDistribution time_profile_;
0066 NonuniformGridCalculator calc_cdf_;
0067 };
0068
0069
0070
0071
0072
0073
0074
0075 CELER_FUNCTION WavelengthShiftGenerator::WavelengthShiftGenerator(
0076 NativeCRef<WavelengthShiftData> const& shared,
0077 WlsDistributionData const& distribution)
0078 : distribution_(distribution)
0079 , time_constant_(shared.wls_record[distribution_.material].time_constant)
0080 , time_profile_(shared.time_profile)
0081 , calc_cdf_(shared.energy_cdf[distribution_.material], shared.reals)
0082 {
0083 CELER_EXPECT(distribution_);
0084 CELER_EXPECT(distribution_.energy.value() > calc_cdf_.grid().front());
0085 }
0086
0087
0088
0089
0090
0091
0092
0093 template<class Engine>
0094 CELER_FUNCTION TrackInitializer WavelengthShiftGenerator::operator()(
0095 Engine& rng)
0096 {
0097 using namespace celeritas::literals;
0098
0099
0100 TrackInitializer result;
0101
0102
0103
0104
0105 NonuniformGridCalculator calc_energy = calc_cdf_.make_inverse();
0106 real_type energy = calc_energy(generate_canonical(rng));
0107 if (CELER_UNLIKELY(energy >= value_as<Energy>(distribution_.energy)))
0108 {
0109
0110 real_type cdf_max = calc_cdf_(value_as<Energy>(distribution_.energy));
0111 UniformRealDistribution<real_type> sample_cdf(0, cdf_max);
0112 energy = calc_energy(sample_cdf(rng));
0113 }
0114 CELER_ENSURE(energy < value_as<Energy>(distribution_.energy));
0115 result.energy = Energy{energy};
0116
0117
0118 result.position = distribution_.position;
0119
0120
0121 result.direction = IsotropicDistribution{}(rng);
0122 result.polarization = TransversePolarizationSampler{result.direction}(rng);
0123
0124
0125 result.time = distribution_.time
0126 + (time_profile_ == WlsDistribution::delta
0127 ? time_constant_
0128 : ExponentialDistribution(1_r / time_constant_)(rng));
0129 result.primary = distribution_.primary;
0130
0131 return result;
0132 }
0133
0134
0135 }
0136 }