Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-01-07 10:01:42

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/optical/gen/CherenkovOffload.hh
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 "GeneratorData.hh"
0018 #include "OffloadData.hh"
0019 #include "../MaterialView.hh"
0020 
0021 namespace celeritas
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Sample the number of Cherenkov photons to be generated.
0026  *
0027  * This populates the \c GeneratorDistributionData used by the \c
0028  * CherenkovGenerator to generate optical photons using post-step and cached
0029  * pre-step data.
0030  *
0031  * The number of photons is sampled from a Poisson distribution with a mean
0032  * \f[
0033    \langle n \rangle = \ell_\text{step} \difd{N}{x}
0034  * \f]
0035  * where \f$ \ell_\text{step} \f$ is the step length.
0036  */
0037 class CherenkovOffload
0038 {
0039   public:
0040     // Construct directly
0041     inline CELER_FUNCTION
0042     CherenkovOffload(units::ElementaryCharge charge,
0043                      real_type step_length,
0044                      OffloadPreStepData const& pre_step,
0045                      optical::MaterialView const& pre_mat,
0046                      units::LightSpeed post_speed,
0047                      Real3 const& post_pos,
0048                      NativeCRef<CherenkovData> const& shared);
0049 
0050     // Construct from Celeritas views
0051     inline CELER_FUNCTION
0052     CherenkovOffload(OffloadPreStepData const& pre_step,
0053                      optical::MaterialView const& pre_mat,
0054                      ParticleTrackView const& post_particle,
0055                      SimTrackView const& post_sim,
0056                      Real3 const& post_pos,
0057                      NativeCRef<CherenkovData> const& shared);
0058 
0059     // Gather the input data needed to sample Cherenkov photons
0060     template<class Generator>
0061     inline CELER_FUNCTION GeneratorDistributionData operator()(Generator& rng);
0062 
0063   private:
0064     units::ElementaryCharge charge_;
0065     real_type step_length_;
0066     OffloadPreStepData const& pre_step_;
0067     GeneratorStepData post_step_;
0068     real_type num_photons_per_len_;
0069 };
0070 
0071 //---------------------------------------------------------------------------//
0072 // INLINE DEFINITIONS
0073 //---------------------------------------------------------------------------//
0074 /*!
0075  * Construct directly from data.
0076  */
0077 CELER_FUNCTION
0078 CherenkovOffload::CherenkovOffload(units::ElementaryCharge charge,
0079                                    real_type step_length,
0080                                    OffloadPreStepData const& pre_step,
0081                                    optical::MaterialView const& pre_mat,
0082                                    units::LightSpeed post_speed,
0083                                    Real3 const& post_pos,
0084                                    NativeCRef<CherenkovData> const& shared)
0085     : charge_{charge}
0086     , step_length_(step_length)
0087     , pre_step_(pre_step)
0088     , post_step_{post_speed, post_pos}
0089 {
0090     CELER_EXPECT(charge != zero_quantity());
0091     CELER_EXPECT(step_length_ > 0);
0092     CELER_EXPECT(pre_step_);
0093 
0094     units::LightSpeed beta(
0095         real_type{0.5} * (pre_step_.speed.value() + post_step_.speed.value()));
0096 
0097     CherenkovDndxCalculator calculate_dndx(pre_mat, shared, charge_);
0098     num_photons_per_len_ = calculate_dndx(beta);
0099 }
0100 
0101 //---------------------------------------------------------------------------//
0102 /*!
0103  * Construct with optical material, Cherenkov, and step information.
0104  */
0105 CELER_FUNCTION
0106 CherenkovOffload::CherenkovOffload(OffloadPreStepData const& pre_step,
0107                                    optical::MaterialView const& pre_mat,
0108                                    ParticleTrackView const& post_particle,
0109                                    SimTrackView const& post_sim,
0110                                    Real3 const& post_pos,
0111                                    NativeCRef<CherenkovData> const& shared)
0112     : CherenkovOffload{post_particle.charge(),
0113                        post_sim.step_length(),
0114                        pre_step,
0115                        pre_mat,
0116                        post_particle.speed(),
0117                        post_pos,
0118                        shared}
0119 {
0120 }
0121 
0122 //---------------------------------------------------------------------------//
0123 /*!
0124  * Collect the distribution data needed to sample Cherenkov photons.
0125  *
0126  * If no photons are sampled an empty object is returned.
0127  */
0128 template<class Generator>
0129 CELER_FUNCTION GeneratorDistributionData
0130 CherenkovOffload::operator()(Generator& rng)
0131 {
0132     if (num_photons_per_len_ == 0)
0133     {
0134         return {};
0135     }
0136 
0137     GeneratorDistributionData data;
0138     data.num_photons = PoissonDistribution<real_type>(num_photons_per_len_
0139                                                       * step_length_)(rng);
0140     if (data.num_photons > 0)
0141     {
0142         data.time = pre_step_.time;
0143         data.step_length = step_length_;
0144         data.charge = charge_;
0145         data.material = pre_step_.material;
0146         data.points[StepPoint::pre].speed = pre_step_.speed;
0147         data.points[StepPoint::pre].pos = pre_step_.pos;
0148         data.points[StepPoint::post] = post_step_;
0149     }
0150     return data;
0151 }
0152 
0153 //---------------------------------------------------------------------------//
0154 }  // namespace celeritas