Back to home page

EIC code displayed by LXR

 
 

    


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

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/em/interactor/CombinedBremInteractor.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/data/StackAllocator.hh"
0012 #include "corecel/math/Algorithms.hh"
0013 #include "corecel/math/ArrayUtils.hh"
0014 #include "celeritas/Constants.hh"
0015 #include "celeritas/Quantities.hh"
0016 #include "celeritas/Types.hh"
0017 #include "celeritas/em/data/CombinedBremData.hh"
0018 #include "celeritas/em/distribution/TsaiUrbanDistribution.hh"
0019 #include "celeritas/mat/ElementView.hh"
0020 #include "celeritas/mat/MaterialView.hh"
0021 #include "celeritas/phys/CutoffView.hh"
0022 #include "celeritas/phys/Interaction.hh"
0023 #include "celeritas/phys/ParticleTrackView.hh"
0024 #include "celeritas/phys/Secondary.hh"
0025 
0026 #include "detail/BremFinalStateHelper.hh"
0027 #include "detail/PhysicsConstants.hh"
0028 #include "detail/RBEnergySampler.hh"
0029 #include "detail/SBEnergySampler.hh"
0030 
0031 namespace celeritas
0032 {
0033 //---------------------------------------------------------------------------//
0034 /*!
0035  * Apply either Seltzer-Berger or Relativistic depending on energy.
0036  *
0037  * This is a combined bremsstrahlung interactor consisted of the Seltzer-Berger
0038  * interactor at the low energy (< 1 GeV) and the relativistic bremsstrahlung
0039  * interactor at the high energy for the e-/e+ bremsstrahlung process.
0040  *
0041  * \todo See if there's any occupancy/performance difference by defining the
0042  * samplers *inside* the conditional on "is_relativistic".
0043  */
0044 class CombinedBremInteractor
0045 {
0046     //!@{
0047     //! \name Type aliases
0048     using Energy = units::MevEnergy;
0049     using Momentum = units::MevMomentum;
0050     using ElementData = RelBremElementData;
0051     using ItemIdT = celeritas::ItemId<unsigned int>;
0052     //!@}
0053 
0054   public:
0055     // Construct with shared and state data
0056     inline CELER_FUNCTION
0057     CombinedBremInteractor(CombinedBremRef const& shared,
0058                            ParticleTrackView const& particle,
0059                            Real3 const& direction,
0060                            CutoffView const& cutoffs,
0061                            StackAllocator<Secondary>& allocate,
0062                            MaterialView const& material,
0063                            ElementComponentId const& elcomp_id);
0064 
0065     // Sample an interaction with the given RNG
0066     template<class Engine>
0067     inline CELER_FUNCTION Interaction operator()(Engine& rng);
0068 
0069   private:
0070     //// DATA ////
0071 
0072     // SB and relativistic data
0073     CombinedBremRef const& shared_;
0074     // Incident particle
0075     ParticleTrackView const& particle_;
0076     // Incident particle direction
0077     Real3 const& inc_direction_;
0078     // Energy cutoffs
0079     CutoffView const& cutoffs_;
0080     // Production cutoff for gammas
0081     Energy const gamma_cutoff_;
0082     // Allocate space for a secondary particle
0083     StackAllocator<Secondary>& allocate_;
0084     // Material properties
0085     MaterialView const& material_;
0086     // Element in which interaction occurs
0087     ElementComponentId const elcomp_id_;
0088     // Secondary angular distribution
0089     TsaiUrbanDistribution sample_costheta_;
0090 };
0091 
0092 //---------------------------------------------------------------------------//
0093 // INLINE DEFINITIONS
0094 //---------------------------------------------------------------------------//
0095 /*!
0096  * Construct with shared and state data.
0097  */
0098 CELER_FUNCTION
0099 CombinedBremInteractor::CombinedBremInteractor(
0100     CombinedBremRef const& shared,
0101     ParticleTrackView const& particle,
0102     Real3 const& direction,
0103     CutoffView const& cutoffs,
0104     StackAllocator<Secondary>& allocate,
0105     MaterialView const& material,
0106     ElementComponentId const& elcomp_id)
0107     : shared_(shared)
0108     , particle_(particle)
0109     , inc_direction_(direction)
0110     , cutoffs_(cutoffs)
0111     , gamma_cutoff_(cutoffs.energy(shared.rb_data.ids.gamma))
0112     , allocate_(allocate)
0113     , material_(material)
0114     , elcomp_id_(elcomp_id)
0115     , sample_costheta_(particle.energy(), particle.mass())
0116 {
0117     CELER_EXPECT(particle.particle_id() == shared.rb_data.ids.electron
0118                  || particle.particle_id() == shared.rb_data.ids.positron);
0119     CELER_EXPECT(gamma_cutoff_ > zero_quantity());
0120 }
0121 
0122 //---------------------------------------------------------------------------//
0123 /*!
0124  * Sample the production of bremsstrahlung photons using a combined model.
0125  */
0126 template<class Engine>
0127 CELER_FUNCTION Interaction CombinedBremInteractor::operator()(Engine& rng)
0128 {
0129     if (particle_.energy() <= gamma_cutoff_)
0130     {
0131         /*!
0132          * \todo Remove and replace with an assertion once material-dependent
0133          * model bounds are supported
0134          */
0135         return Interaction::from_unchanged();
0136     }
0137 
0138     // Allocate space for the brems photon
0139     Secondary* secondaries = allocate_(1);
0140     if (secondaries == nullptr)
0141     {
0142         // Failed to allocate space for the secondary
0143         return Interaction::from_failure();
0144     }
0145 
0146     // Sample the bremsstrahlung photon energy
0147     Energy gamma_energy;
0148     if (particle_.energy() >= shared_.rb_data.low_energy_limit)
0149     {
0150         detail::RBEnergySampler sample_energy{
0151             shared_.rb_data, particle_, cutoffs_, material_, elcomp_id_};
0152         gamma_energy = sample_energy(rng);
0153     }
0154     else
0155     {
0156         detail::SBEnergySampler sample_energy{
0157             shared_.sb_differential_xs,
0158             particle_,
0159             gamma_cutoff_,
0160             material_,
0161             elcomp_id_,
0162             particle_.particle_id() == shared_.rb_data.ids.electron};
0163         gamma_energy = sample_energy(rng);
0164     }
0165 
0166     // Update kinematics of the final state and return this interaction
0167     return detail::BremFinalStateHelper(particle_.energy(),
0168                                         inc_direction_,
0169                                         particle_.momentum(),
0170                                         shared_.rb_data.ids.gamma,
0171                                         gamma_energy,
0172                                         sample_costheta_(rng),
0173                                         secondaries)(rng);
0174 }
0175 
0176 //---------------------------------------------------------------------------//
0177 }  // namespace celeritas