Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:31:27

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2024 UT-Battelle, LLC, and other Celeritas developers.
0003 // See the top-level COPYRIGHT file for details.
0004 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0005 //---------------------------------------------------------------------------//
0006 //! \file celeritas/optical/CerenkovOffload.hh
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  * Sample the number of Cerenkov photons to be generated.
0027  *
0028  * This populates the \c GeneratorDistributionData used by the \c
0029  * CerenkovGenerator to generate optical photons using post-step and cached
0030  * pre-step data.
0031  *
0032  * The number of photons is sampled from a Poisson distribution with a mean
0033  * \f[
0034    \langle n \rangle = \ell_\text{step} \difd{N}{x}
0035  * \f]
0036  * where \f$ \ell_\text{step} \f$ is the step length.
0037  */
0038 class CerenkovOffload
0039 {
0040   public:
0041     // Construct with optical material, Cerenkov, and step data
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     // Return a populated optical distribution data for the Cerenkov Generator
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 // INLINE DEFINITIONS
0065 //---------------------------------------------------------------------------//
0066 /*!
0067  * Construct with optical material, Cerenkov, and step information.
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  * Return an \c GeneratorDistributionData object.
0095  *
0096  * If no photons are sampled, an empty object is returned and can be verified
0097  * via its own operator bool.
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 }  // namespace celeritas