Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 08:53:43

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/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 "GeneratorDistributionData.hh"
0018 #include "MaterialView.hh"
0019 #include "OffloadData.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 with optical material, Cherenkov, and step data
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     // Return a populated optical distribution data for the Cherenkov Generator
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 // INLINE DEFINITIONS
0064 //---------------------------------------------------------------------------//
0065 /*!
0066  * Construct with optical material, Cherenkov, and step information.
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  * Return an \c GeneratorDistributionData object.
0094  *
0095  * If no photons are sampled, an empty object is returned and can be verified
0096  * via its own operator bool.
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 }  // namespace celeritas