File indexing completed on 2025-09-17 08:53:43
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "corecel/random/distribution/PoissonDistribution.hh"
0012 #include "celeritas/phys/ParticleTrackView.hh"
0013 #include "celeritas/track/SimTrackView.hh"
0014
0015 #include "CherenkovData.hh"
0016 #include "CherenkovDndxCalculator.hh"
0017 #include "GeneratorDistributionData.hh"
0018 #include "MaterialView.hh"
0019 #include "OffloadData.hh"
0020
0021 namespace celeritas
0022 {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 class CherenkovOffload
0038 {
0039 public:
0040
0041 inline CELER_FUNCTION
0042 CherenkovOffload(ParticleTrackView const& particle,
0043 SimTrackView const& sim,
0044 optical::MaterialView const& mat,
0045 Real3 const& pos,
0046 NativeCRef<optical::CherenkovData> const& shared,
0047 OffloadPreStepData const& step_data);
0048
0049
0050 template<class Generator>
0051 inline CELER_FUNCTION optical::GeneratorDistributionData
0052 operator()(Generator& rng);
0053
0054 private:
0055 units::ElementaryCharge charge_;
0056 real_type step_length_;
0057 OffloadPreStepData const& pre_step_;
0058 optical::GeneratorStepData post_step_;
0059 real_type num_photons_per_len_;
0060 };
0061
0062
0063
0064
0065
0066
0067
0068 CELER_FUNCTION
0069 CherenkovOffload::CherenkovOffload(ParticleTrackView const& particle,
0070 SimTrackView const& sim,
0071 optical::MaterialView const& mat,
0072 Real3 const& pos,
0073 NativeCRef<optical::CherenkovData> const& shared,
0074 OffloadPreStepData const& step_data)
0075 : charge_(particle.charge())
0076 , step_length_(sim.step_length())
0077 , pre_step_(step_data)
0078 , post_step_({particle.speed(), pos})
0079 {
0080 CELER_EXPECT(charge_ != zero_quantity());
0081 CELER_EXPECT(step_length_ > 0);
0082 CELER_EXPECT(pre_step_);
0083
0084 units::LightSpeed beta(
0085 real_type{0.5} * (pre_step_.speed.value() + post_step_.speed.value()));
0086
0087 optical::CherenkovDndxCalculator calculate_dndx(mat, shared, charge_);
0088 num_photons_per_len_ = calculate_dndx(beta);
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098 template<class Generator>
0099 CELER_FUNCTION optical::GeneratorDistributionData
0100 CherenkovOffload::operator()(Generator& rng)
0101 {
0102 if (num_photons_per_len_ == 0)
0103 {
0104 return {};
0105 }
0106
0107 optical::GeneratorDistributionData data;
0108 data.num_photons = PoissonDistribution<real_type>(num_photons_per_len_
0109 * step_length_)(rng);
0110 if (data.num_photons > 0)
0111 {
0112 data.time = pre_step_.time;
0113 data.step_length = step_length_;
0114 data.charge = charge_;
0115 data.material = pre_step_.material;
0116 data.points[StepPoint::pre].speed = pre_step_.speed;
0117 data.points[StepPoint::pre].pos = pre_step_.pos;
0118 data.points[StepPoint::post] = post_step_;
0119 }
0120 return data;
0121 }
0122
0123
0124 }