File indexing completed on 2026-11-07 10:11:39
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "celeritas/optical/ParticleTrackView.hh"
0010 #include "celeritas/optical/surface/SurfacePhysicsTrackView.hh"
0011 #include "celeritas/optical/surface/SurfacePhysicsUtils.hh"
0012
0013 #include "LambertianDistribution.hh"
0014 #include "SurfaceInteraction.hh"
0015
0016 namespace celeritas
0017 {
0018 namespace optical
0019 {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 class ReflectionFormCalculator
0031 {
0032 public:
0033
0034 explicit inline CELER_FUNCTION ReflectionFormCalculator(
0035 Real3 const& direction,
0036 Real3 const& polarization,
0037 Real3 const& global_normal,
0038 Real3 const& facet_normal);
0039
0040
0041 explicit inline CELER_FUNCTION ReflectionFormCalculator(
0042 Real3 const& inc_direction,
0043 ParticleTrackView const& photon,
0044 SurfacePhysicsTrackView const& surface_physics);
0045
0046
0047 inline CELER_FUNCTION SurfaceInteraction calc_specular_spike() const;
0048
0049
0050 inline CELER_FUNCTION SurfaceInteraction calc_specular_lobe() const;
0051
0052
0053 inline CELER_FUNCTION SurfaceInteraction calc_backscatter() const;
0054
0055
0056 template<class Engine>
0057 inline CELER_FUNCTION SurfaceInteraction sample_lambertian_reflection(
0058 Engine& rng) const;
0059
0060 private:
0061 Real3 const& direction_;
0062 Real3 const& polarization_;
0063 Real3 global_normal_;
0064 Real3 const& facet_normal_;
0065
0066
0067 inline CELER_FUNCTION SurfaceInteraction calc_specular_reflection(
0068 Real3 const& normal) const;
0069 };
0070
0071
0072
0073
0074
0075 CELER_FUNCTION ReflectionFormCalculator::ReflectionFormCalculator(
0076 Real3 const& direction,
0077 Real3 const& polarization,
0078 Real3 const& global_normal,
0079 Real3 const& facet_normal)
0080 : direction_(direction)
0081 , polarization_(polarization)
0082 , global_normal_(global_normal)
0083 , facet_normal_(facet_normal)
0084 {
0085 CELER_EXPECT(is_soft_unit_vector(global_normal_));
0086 CELER_EXPECT(is_soft_unit_vector(facet_normal_));
0087 CELER_EXPECT(is_entering_surface(direction_, global_normal_));
0088 CELER_EXPECT(is_entering_surface(direction_, facet_normal_));
0089 }
0090
0091
0092
0093
0094
0095 CELER_FUNCTION ReflectionFormCalculator::ReflectionFormCalculator(
0096 Real3 const& inc_direction,
0097 ParticleTrackView const& photon,
0098 SurfacePhysicsTrackView const& surface_physics)
0099 : ReflectionFormCalculator(inc_direction,
0100 photon.polarization(),
0101 surface_physics.global_normal(),
0102 surface_physics.facet_normal())
0103 {
0104 }
0105
0106
0107
0108
0109
0110
0111
0112 CELER_FUNCTION SurfaceInteraction
0113 ReflectionFormCalculator::calc_specular_spike() const
0114 {
0115 return this->calc_specular_reflection(global_normal_);
0116 }
0117
0118
0119
0120
0121
0122
0123
0124 CELER_FUNCTION SurfaceInteraction
0125 ReflectionFormCalculator::calc_specular_lobe() const
0126 {
0127 return this->calc_specular_reflection(facet_normal_);
0128 }
0129
0130
0131
0132
0133
0134
0135
0136 CELER_FUNCTION SurfaceInteraction
0137 ReflectionFormCalculator::calc_backscatter() const
0138 {
0139 SurfaceInteraction result;
0140 result.action = SurfaceInteraction::Action::reflected;
0141 result.direction = -direction_;
0142 result.polarization = -polarization_;
0143 return result;
0144 }
0145
0146
0147
0148
0149
0150
0151
0152 template<class Engine>
0153 CELER_FUNCTION SurfaceInteraction
0154 ReflectionFormCalculator::sample_lambertian_reflection(Engine& rng) const
0155 {
0156 SurfaceInteraction result;
0157 result.action = SurfaceInteraction::Action::reflected;
0158 result.direction = LambertianDistribution{global_normal_}(rng);
0159 auto n = make_unit_vector(result.direction - direction_);
0160 result.polarization = -geometric_reflected_from(polarization_, n);
0161 return result;
0162 }
0163
0164
0165
0166
0167
0168 CELER_FUNCTION SurfaceInteraction
0169 ReflectionFormCalculator::calc_specular_reflection(Real3 const& normal) const
0170 {
0171 SurfaceInteraction result;
0172 result.action = SurfaceInteraction::Action::reflected;
0173 result.direction = geometric_reflected_from(direction_, normal);
0174 result.polarization = -geometric_reflected_from(polarization_, normal);
0175 return result;
0176 }
0177
0178
0179 }
0180 }