Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2021-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/em/interactor/SeltzerBergerInteractor.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Macros.hh"
0011 #include "corecel/data/StackAllocator.hh"
0012 #include "corecel/math/ArrayUtils.hh"
0013 #include "celeritas/Constants.hh"
0014 #include "celeritas/Quantities.hh"
0015 #include "celeritas/Types.hh"
0016 #include "celeritas/em/data/SeltzerBergerData.hh"
0017 #include "celeritas/em/distribution/TsaiUrbanDistribution.hh"
0018 #include "celeritas/mat/ElementView.hh"
0019 #include "celeritas/mat/MaterialView.hh"
0020 #include "celeritas/phys/CutoffView.hh"
0021 #include "celeritas/phys/Interaction.hh"
0022 #include "celeritas/phys/ParticleTrackView.hh"
0023 #include "celeritas/phys/Secondary.hh"
0024 
0025 #include "detail/BremFinalStateHelper.hh"
0026 #include "detail/PhysicsConstants.hh"
0027 #include "detail/SBEnergySampler.hh"
0028 
0029 namespace celeritas
0030 {
0031 //---------------------------------------------------------------------------//
0032 /*!
0033  * Seltzer-Berger model for electron and positron bremsstrahlung processes.
0034  *
0035  * Given an incoming electron or positron of sufficient energy (as per
0036  * CutOffView), this class provides the energy loss of these particles due to
0037  * radiation of photons in the field of a nucleus. This model improves accuracy
0038  * using cross sections based on interpolation of published tables from Seltzer
0039  * and Berger given in Nucl. Instr. and Meth. in Phys. Research B, 12(1):95–134
0040  * (1985) and Atomic Data and Nuclear Data Tables, 35():345 (1986). The cross
0041  * sections are obtained from SBEnergyDistribution and are appropriately scaled
0042  * in the case of positrons via SBPositronXsCorrector.
0043  *
0044  * \note This interactor performs an analogous sampling as in Geant4's
0045  * G4SeltzerBergerModel, documented in 10.2.1 of the Geant Physics Reference
0046  * (release 10.6). The implementation is based on Geant4 10.4.3.
0047  */
0048 class SeltzerBergerInteractor
0049 {
0050   public:
0051     //!@{
0052     //! \name Type aliases
0053     using Energy = units::MevEnergy;
0054     using Momentum = units::MevMomentum;
0055     //!@}
0056 
0057   public:
0058     //! Construct sampler from device/shared and state data
0059     inline CELER_FUNCTION
0060     SeltzerBergerInteractor(SeltzerBergerRef const& shared,
0061                             ParticleTrackView const& particle,
0062                             Real3 const& inc_direction,
0063                             CutoffView const& cutoffs,
0064                             StackAllocator<Secondary>& allocate,
0065                             MaterialView const& material,
0066                             ElementComponentId const& elcomp_id);
0067 
0068     // Sample an interaction with the given RNG
0069     template<class Engine>
0070     inline CELER_FUNCTION Interaction operator()(Engine& rng);
0071 
0072   private:
0073     //// DATA ////
0074     // Device (host CPU or GPU device) references
0075     SeltzerBergerRef const& shared_;
0076     // Incident particle energy
0077     Energy const inc_energy_;
0078     // Incident particle direction
0079     Momentum const inc_momentum_;
0080     // Incident particle direction
0081     Real3 const& inc_direction_;
0082     // Production cutoff for gammas
0083     Energy const gamma_cutoff_;
0084     // Allocate space for a secondary particle
0085     StackAllocator<Secondary>& allocate_;
0086     // Element in which interaction occurs
0087     ElementComponentId const elcomp_id_;
0088 
0089     //// HELPER CLASSES ////
0090     // A helper to sample the bremsstrahlung photon energy
0091     detail::SBEnergySampler sample_photon_energy_;
0092     // Secondary angular distribution
0093     TsaiUrbanDistribution sample_costheta_;
0094 };
0095 
0096 //---------------------------------------------------------------------------//
0097 // INLINE DEFINITIONS
0098 //---------------------------------------------------------------------------//
0099 /*!
0100  * Construct with shared/device and state data.
0101  *
0102  * The incident particle must be within the model's valid energy range. this
0103  * must be handled in code *before* the interactor is constructed.
0104  */
0105 CELER_FUNCTION SeltzerBergerInteractor::SeltzerBergerInteractor(
0106     SeltzerBergerRef const& shared,
0107     ParticleTrackView const& particle,
0108     Real3 const& inc_direction,
0109     CutoffView const& cutoffs,
0110     StackAllocator<Secondary>& allocate,
0111     MaterialView const& material,
0112     ElementComponentId const& elcomp_id)
0113     : shared_(shared)
0114     , inc_energy_(particle.energy())
0115     , inc_momentum_(particle.momentum())
0116     , inc_direction_(inc_direction)
0117     , gamma_cutoff_(cutoffs.energy(shared.ids.gamma))
0118     , allocate_(allocate)
0119     , elcomp_id_(elcomp_id)
0120     , sample_photon_energy_(shared.differential_xs,
0121                             particle,
0122                             gamma_cutoff_,
0123                             material,
0124                             elcomp_id,
0125                             particle.particle_id() == shared_.ids.electron)
0126     , sample_costheta_(inc_energy_, particle.mass())
0127 {
0128     CELER_EXPECT(particle.particle_id() == shared_.ids.electron
0129                  || particle.particle_id() == shared_.ids.positron);
0130     CELER_EXPECT(gamma_cutoff_ > zero_quantity());
0131     CELER_EXPECT(inc_energy_ > gamma_cutoff_
0132                  && inc_energy_ < detail::seltzer_berger_upper_limit());
0133 }
0134 
0135 //---------------------------------------------------------------------------//
0136 /*!
0137  * Bremsstrahlung using the Seltzer-Berger model.
0138  *
0139  * See section 10.2.1 of the Geant physics reference 10.6.
0140  */
0141 template<class Engine>
0142 CELER_FUNCTION Interaction SeltzerBergerInteractor::operator()(Engine& rng)
0143 {
0144     // Allocate space for the brems photon
0145     Secondary* secondaries = allocate_(1);
0146     if (secondaries == nullptr)
0147     {
0148         // Failed to allocate space for the secondary
0149         return Interaction::from_failure();
0150     }
0151 
0152     // Update kinematics of the final state and return this interaction
0153     return detail::BremFinalStateHelper{inc_energy_,
0154                                         inc_direction_,
0155                                         inc_momentum_,
0156                                         shared_.ids.gamma,
0157                                         sample_photon_energy_(rng),
0158                                         sample_costheta_(rng),
0159                                         secondaries}(rng);
0160 }
0161 
0162 //---------------------------------------------------------------------------//
0163 }  // namespace celeritas