Back to home page

EIC code displayed by LXR

 
 

    


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

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