File indexing completed on 2026-11-07 10:11:39
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/random/distribution/Selector.hh"
0010
0011 #include "DielectricInteractionData.hh"
0012 #include "ReflectionFormCalculator.hh"
0013
0014 namespace celeritas
0015 {
0016 namespace optical
0017 {
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 class ReflectionModeSampler
0028 {
0029 public:
0030
0031
0032 using DataRef = NativeCRef<UnifiedReflectionData>;
0033 using Energy = units::MevEnergy;
0034
0035
0036 public:
0037
0038 explicit inline CELER_FUNCTION ReflectionModeSampler(
0039 DataRef const&, SubModelId, Energy);
0040
0041
0042 inline CELER_FUNCTION real_type operator()(ReflectionMode) const;
0043
0044 private:
0045 DataRef const& data_;
0046 SubModelId surface_;
0047 Energy energy_;
0048 };
0049
0050
0051
0052
0053
0054 class ReflectionFormSampler
0055 {
0056 public:
0057
0058 inline CELER_FUNCTION ReflectionFormSampler(
0059 ReflectionModeSampler sample_mode,
0060 ReflectionFormCalculator const& calc_reflection);
0061
0062
0063 template<class Engine>
0064 inline CELER_FUNCTION SurfaceInteraction operator()(Engine&) const;
0065
0066 private:
0067 Selector<ReflectionModeSampler, ReflectionMode> sample_mode_;
0068 ReflectionFormCalculator const& calc_reflection_;
0069 };
0070
0071
0072
0073
0074
0075
0076
0077 CELER_FUNCTION ReflectionModeSampler::ReflectionModeSampler(
0078 DataRef const& data, SubModelId surface, Energy energy)
0079 : data_(data), surface_(surface), energy_(energy)
0080 {
0081 CELER_EXPECT(surface_ < data_.size());
0082 }
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092 CELER_FUNCTION real_type ReflectionModeSampler::operator()(
0093 ReflectionMode mode) const
0094 {
0095 NonuniformGridCalculator calc{data_.reflection_grids[mode][surface_],
0096 data_.reals};
0097 real_type result = calc(value_as<Energy>(energy_));
0098 CELER_ENSURE(result >= 0 && result <= 1);
0099 return result;
0100 }
0101
0102
0103
0104
0105
0106 CELER_FUNCTION ReflectionFormSampler::ReflectionFormSampler(
0107 ReflectionModeSampler sample_mode,
0108 ReflectionFormCalculator const& calc_reflection)
0109 : sample_mode_{make_unnormalized_selector(
0110 std::move(sample_mode), ReflectionMode::size_, real_type{1})}
0111 , calc_reflection_(calc_reflection)
0112 {
0113 }
0114
0115
0116
0117
0118
0119 template<class Engine>
0120 inline CELER_FUNCTION SurfaceInteraction ReflectionFormSampler::operator()(
0121 Engine& rng) const
0122 {
0123 switch (sample_mode_(rng))
0124 {
0125 case ReflectionMode::specular_spike:
0126 return calc_reflection_.calc_specular_spike();
0127 case ReflectionMode::specular_lobe:
0128 return calc_reflection_.calc_specular_lobe();
0129 case ReflectionMode::backscatter:
0130 return calc_reflection_.calc_backscatter();
0131 case ReflectionMode::diffuse_lobe:
0132
0133
0134 return calc_reflection_.sample_lambertian_reflection(rng);
0135 default:
0136 CELER_ASSERT_UNREACHABLE();
0137 }
0138 }
0139
0140 }
0141 }