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