Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-02 10:13:24

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/phys/PhysicsStepView.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/Assert.hh"
0010 #include "corecel/Macros.hh"
0011 #include "corecel/data/StackAllocator.hh"
0012 #include "corecel/math/NumericLimits.hh"
0013 #include "corecel/math/Quantity.hh"
0014 #include "corecel/sys/ThreadId.hh"
0015 #include "celeritas/em/interactor/AtomicRelaxationHelper.hh"
0016 
0017 #include "Interaction.hh"
0018 #include "PhysicsData.hh"
0019 #include "Secondary.hh"
0020 
0021 namespace celeritas
0022 {
0023 //---------------------------------------------------------------------------//
0024 /*!
0025  * Access step-local (non-persistent) physics track data.
0026  *
0027  * This class should be accessible to track slots that have inactive tracks so
0028  * that the temporary values can be cleared. (Once we start partitioning track
0029  * slots based on their status, this restriction might be lifted.) Unlike
0030  * \c PhysicsTrackView, this class shouldn't need any external info about the
0031  * current particle type, material, etc.
0032  *
0033  * The underlying physics data might be refactored later (and this class name
0034  * might be changed) but it separates out some of the temporary data
0035  * (interaction, macro xs, MSC step) from the persistent data (remaining MFP).
0036  */
0037 class PhysicsStepView
0038 {
0039   public:
0040     //!@{
0041     //! \name Type aliases
0042     using PhysicsParamsRef = NativeCRef<PhysicsParamsData>;
0043     using PhysicsStateRef = NativeRef<PhysicsStateData>;
0044     using SecondaryAllocator = StackAllocator<Secondary>;
0045     using Energy = units::MevEnergy;
0046     //!@}
0047 
0048   public:
0049     // Construct from shared and state data
0050     inline CELER_FUNCTION PhysicsStepView(PhysicsParamsRef const& params,
0051                                           PhysicsStateRef const& states,
0052                                           TrackSlotId tid);
0053 
0054     // Set the total (process-integrated) macroscopic xs [len^-1]
0055     inline CELER_FUNCTION void macro_xs(real_type);
0056 
0057     // Set the sampled element
0058     inline CELER_FUNCTION void element(ElementComponentId);
0059 
0060     // Save MSC step data
0061     inline CELER_FUNCTION void msc_step(MscStep const&);
0062 
0063     // Reset the energy deposition
0064     inline CELER_FUNCTION void reset_energy_deposition();
0065 
0066     // Reset the energy deposition to NaN to catch errors
0067     inline CELER_FUNCTION void reset_energy_deposition_debug();
0068 
0069     // Accumulate into local step's energy deposition
0070     inline CELER_FUNCTION void deposit_energy(Energy);
0071 
0072     // Accumulate into local step's energy deposition from particle
0073     template<class PTV>
0074     inline CELER_FUNCTION void deposit_energy_from(Energy deposited,
0075                                                    PTV&& particle);
0076 
0077     // Set secondaries during an interaction
0078     inline CELER_FUNCTION void secondaries(Span<Secondary>);
0079 
0080     // Total (process-integrated) macroscopic xs [len^-1]
0081     CELER_FORCEINLINE_FUNCTION real_type macro_xs() const;
0082 
0083     // Sampled element for discrete interaction
0084     CELER_FORCEINLINE_FUNCTION ElementComponentId element() const;
0085 
0086     // Mutable access to MSC step data (TODO: hack)
0087     inline CELER_FUNCTION MscStep& msc_step();
0088 
0089     // Retrieve MSC step data
0090     inline CELER_FUNCTION MscStep const& msc_step() const;
0091 
0092     // Access local energy deposition
0093     inline CELER_FUNCTION Energy energy_deposition() const;
0094 
0095     // Access secondaries created by an interaction
0096     inline CELER_FUNCTION Span<Secondary const> secondaries() const;
0097 
0098     // Access scratch space for particle-process cross section calculations
0099     inline CELER_FUNCTION real_type& per_process_xs(ParticleProcessId);
0100     inline CELER_FUNCTION real_type per_process_xs(ParticleProcessId) const;
0101 
0102     //// THREAD-INDEPENDENT ////
0103 
0104     // Return a secondary stack allocator
0105     inline CELER_FUNCTION SecondaryAllocator make_secondary_allocator() const;
0106 
0107     // Access atomic relaxation data
0108     inline CELER_FUNCTION AtomicRelaxationHelper make_relaxation_helper(
0109         ElementId el_id) const;
0110 
0111   private:
0112     //// DATA ////
0113 
0114     PhysicsParamsRef const& params_;
0115     PhysicsStateRef const& states_;
0116     TrackSlotId const track_slot_;
0117 
0118     //// CLASS FUNCTIONS ////
0119 
0120     CELER_FORCEINLINE_FUNCTION PhysicsTrackState& state();
0121     CELER_FORCEINLINE_FUNCTION PhysicsTrackState const& state() const;
0122 };
0123 
0124 //---------------------------------------------------------------------------//
0125 // INLINE DEFINITIONS
0126 //---------------------------------------------------------------------------//
0127 /*!
0128  * Construct from shared and state data.
0129  */
0130 CELER_FUNCTION PhysicsStepView::PhysicsStepView(PhysicsParamsRef const& params,
0131                                                 PhysicsStateRef const& states,
0132                                                 TrackSlotId tid)
0133     : params_(params), states_(states), track_slot_(tid)
0134 {
0135     CELER_EXPECT(track_slot_);
0136 }
0137 
0138 //---------------------------------------------------------------------------//
0139 /*!
0140  * Set the process-integrated total macroscopic cross section.
0141  */
0142 CELER_FUNCTION void PhysicsStepView::macro_xs(real_type inv_distance)
0143 {
0144     CELER_EXPECT(inv_distance >= 0);
0145     this->state().macro_xs = inv_distance;
0146 }
0147 
0148 //---------------------------------------------------------------------------//
0149 /*!
0150  * Set the sampled element.
0151  */
0152 CELER_FUNCTION void PhysicsStepView::element(ElementComponentId elcomp_id)
0153 {
0154     this->state().element = elcomp_id;
0155 }
0156 
0157 //---------------------------------------------------------------------------//
0158 /*!
0159  * Save MSC step limit data.
0160  */
0161 CELER_FUNCTION void PhysicsStepView::msc_step(MscStep const& limit)
0162 {
0163     states_.msc_step[track_slot_] = limit;
0164 }
0165 
0166 //---------------------------------------------------------------------------//
0167 /*!
0168  * Reset the energy deposition to zero at the beginning of a step.
0169  */
0170 CELER_FUNCTION void PhysicsStepView::reset_energy_deposition()
0171 {
0172     this->state().energy_deposition = 0;
0173 }
0174 
0175 //---------------------------------------------------------------------------//
0176 /*!
0177  * Set the energy deposition to NaN for inactive tracks to catch errors.
0178  */
0179 CELER_FUNCTION void PhysicsStepView::reset_energy_deposition_debug()
0180 {
0181 #if !CELERITAS_DEBUG
0182     CELER_ASSERT_UNREACHABLE();
0183 #endif
0184     this->state().energy_deposition = numeric_limits<real_type>::quiet_NaN();
0185 }
0186 
0187 //---------------------------------------------------------------------------//
0188 /*!
0189  * Accumulate into local step's energy deposition.
0190  */
0191 CELER_FUNCTION void PhysicsStepView::deposit_energy(Energy energy)
0192 {
0193     CELER_EXPECT(energy > zero_quantity());
0194     this->state().energy_deposition += energy.value();
0195 }
0196 
0197 //---------------------------------------------------------------------------//
0198 /*!
0199  * Deposit energy from the particle.
0200  */
0201 template<class PTV>
0202 inline CELER_FUNCTION void PhysicsStepView::deposit_energy_from(
0203     Energy deposited, PTV&& particle)
0204 {
0205     CELER_EXPECT(deposited > zero_quantity());
0206     CELER_EXPECT(deposited <= particle.energy());
0207     this->deposit_energy(deposited);
0208     particle.energy(particle.energy() - deposited);
0209 }
0210 
0211 //---------------------------------------------------------------------------//
0212 /*!
0213  * Set secondaries during an interaction, or clear them with an empty span.
0214  */
0215 CELER_FUNCTION void PhysicsStepView::secondaries(Span<Secondary> sec)
0216 {
0217     this->state().secondaries = sec;
0218 }
0219 
0220 //---------------------------------------------------------------------------//
0221 /*!
0222  * Calculated process-integrated macroscopic XS.
0223  *
0224  * This value should be calculated in the pre-step kernel, and will be used to
0225  * decrement `interaction_mfp` and for sampling a process. Units are inverse
0226  * length.
0227  */
0228 CELER_FUNCTION real_type PhysicsStepView::macro_xs() const
0229 {
0230     real_type xs = this->state().macro_xs;
0231     CELER_ENSURE(xs >= 0);
0232     return xs;
0233 }
0234 
0235 //---------------------------------------------------------------------------//
0236 /*!
0237  * Sampled element for discrete interaction.
0238  */
0239 CELER_FUNCTION ElementComponentId PhysicsStepView::element() const
0240 {
0241     return this->state().element;
0242 }
0243 
0244 //---------------------------------------------------------------------------//
0245 /*!
0246  * Mutable access to MSC step data (TODO: hack)
0247  */
0248 CELER_FUNCTION MscStep& PhysicsStepView::msc_step()
0249 {
0250     return states_.msc_step[track_slot_];
0251 }
0252 
0253 //---------------------------------------------------------------------------//
0254 /*!
0255  * Access calculated MSC step data.
0256  */
0257 CELER_FUNCTION MscStep const& PhysicsStepView::msc_step() const
0258 {
0259     return states_.msc_step[track_slot_];
0260 }
0261 
0262 //---------------------------------------------------------------------------//
0263 /*!
0264  * Access accumulated energy deposition.
0265  */
0266 CELER_FUNCTION auto PhysicsStepView::energy_deposition() const -> Energy
0267 {
0268     real_type result = this->state().energy_deposition;
0269     CELER_ENSURE(result >= 0);
0270     return Energy{result};
0271 }
0272 
0273 //---------------------------------------------------------------------------//
0274 /*!
0275  * Access secondaries created by a discrete interaction.
0276  */
0277 CELER_FUNCTION Span<Secondary const> PhysicsStepView::secondaries() const
0278 {
0279     return this->state().secondaries;
0280 }
0281 
0282 //---------------------------------------------------------------------------//
0283 /*!
0284  * Access scratch space for particle-process cross section calculations.
0285  */
0286 CELER_FUNCTION real_type& PhysicsStepView::per_process_xs(
0287     ParticleProcessId ppid)
0288 {
0289     CELER_EXPECT(ppid < params_.scalars.max_particle_processes);
0290     auto idx = track_slot_.get() * params_.scalars.max_particle_processes
0291                + ppid.get();
0292     CELER_ENSURE(idx < states_.per_process_xs.size());
0293     return states_.per_process_xs[ItemId<real_type>(idx)];
0294 }
0295 
0296 //---------------------------------------------------------------------------//
0297 /*!
0298  * Access scratch space for particle-process cross section calculations.
0299  */
0300 CELER_FUNCTION real_type PhysicsStepView::per_process_xs(
0301     ParticleProcessId ppid) const
0302 {
0303     CELER_EXPECT(ppid < params_.scalars.max_particle_processes);
0304     auto idx = track_slot_.get() * params_.scalars.max_particle_processes
0305                + ppid.get();
0306     CELER_ENSURE(idx < states_.per_process_xs.size());
0307     return states_.per_process_xs[ItemId<real_type>(idx)];
0308 }
0309 
0310 //---------------------------------------------------------------------------//
0311 /*!
0312  * Return a secondary stack allocator view.
0313  */
0314 CELER_FUNCTION auto PhysicsStepView::make_secondary_allocator() const
0315     -> SecondaryAllocator
0316 {
0317     return SecondaryAllocator{states_.secondaries};
0318 }
0319 
0320 //---------------------------------------------------------------------------//
0321 /*!
0322  * Make an atomic relaxation helper for the given element.
0323  */
0324 CELER_FUNCTION auto PhysicsStepView::make_relaxation_helper(
0325     ElementId el_id) const -> AtomicRelaxationHelper
0326 {
0327     CELER_ASSERT(el_id);
0328     return AtomicRelaxationHelper{
0329         params_.hardwired.relaxation, states_.relaxation, el_id, track_slot_};
0330 }
0331 
0332 //---------------------------------------------------------------------------//
0333 // PRIVATE CLASS FUNCTIONS
0334 //---------------------------------------------------------------------------//
0335 //! Get the thread-local state (mutable)
0336 CELER_FUNCTION PhysicsTrackState& PhysicsStepView::state()
0337 {
0338     return states_.state[track_slot_];
0339 }
0340 
0341 //! Get the thread-local state (const)
0342 CELER_FUNCTION PhysicsTrackState const& PhysicsStepView::state() const
0343 {
0344     return states_.state[track_slot_];
0345 }
0346 
0347 //---------------------------------------------------------------------------//
0348 }  // namespace celeritas