Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //----------------------------------*-C++-*----------------------------------//
0002 // Copyright 2022-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/phys/PhysicsStepView.hh
0007 //---------------------------------------------------------------------------//
0008 #pragma once
0009 
0010 #include "corecel/Assert.hh"
0011 #include "corecel/Macros.hh"
0012 #include "corecel/data/StackAllocator.hh"
0013 #include "corecel/math/NumericLimits.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     // Set secondaries during an interaction
0073     inline CELER_FUNCTION void secondaries(Span<Secondary>);
0074 
0075     // Total (process-integrated) macroscopic xs [len^-1]
0076     CELER_FORCEINLINE_FUNCTION real_type macro_xs() const;
0077 
0078     // Sampled element for discrete interaction
0079     CELER_FORCEINLINE_FUNCTION ElementComponentId element() const;
0080 
0081     // Mutable access to MSC step data (TODO: hack)
0082     inline CELER_FUNCTION MscStep& msc_step();
0083 
0084     // Retrieve MSC step data
0085     inline CELER_FUNCTION MscStep const& msc_step() const;
0086 
0087     // Access local energy deposition
0088     inline CELER_FUNCTION Energy energy_deposition() const;
0089 
0090     // Access secondaries created by an interaction
0091     inline CELER_FUNCTION Span<Secondary const> secondaries() const;
0092 
0093     // Access scratch space for particle-process cross section calculations
0094     inline CELER_FUNCTION real_type& per_process_xs(ParticleProcessId);
0095     inline CELER_FUNCTION real_type per_process_xs(ParticleProcessId) const;
0096 
0097     //// THREAD-INDEPENDENT ////
0098 
0099     // Return a secondary stack allocator
0100     inline CELER_FUNCTION SecondaryAllocator make_secondary_allocator() const;
0101 
0102     // Access atomic relaxation data
0103     inline CELER_FUNCTION AtomicRelaxationHelper
0104     make_relaxation_helper(ElementId el_id) const;
0105 
0106   private:
0107     //// DATA ////
0108 
0109     PhysicsParamsRef const& params_;
0110     PhysicsStateRef const& states_;
0111     TrackSlotId const track_slot_;
0112 
0113     //// CLASS FUNCTIONS ////
0114 
0115     CELER_FORCEINLINE_FUNCTION PhysicsTrackState& state();
0116     CELER_FORCEINLINE_FUNCTION PhysicsTrackState const& state() const;
0117 };
0118 
0119 //---------------------------------------------------------------------------//
0120 // INLINE DEFINITIONS
0121 //---------------------------------------------------------------------------//
0122 /*!
0123  * Construct from shared and state data.
0124  */
0125 CELER_FUNCTION PhysicsStepView::PhysicsStepView(PhysicsParamsRef const& params,
0126                                                 PhysicsStateRef const& states,
0127                                                 TrackSlotId tid)
0128     : params_(params), states_(states), track_slot_(tid)
0129 {
0130     CELER_EXPECT(track_slot_);
0131 }
0132 
0133 //---------------------------------------------------------------------------//
0134 /*!
0135  * Set the process-integrated total macroscopic cross section.
0136  */
0137 CELER_FUNCTION void PhysicsStepView::macro_xs(real_type inv_distance)
0138 {
0139     CELER_EXPECT(inv_distance >= 0);
0140     this->state().macro_xs = inv_distance;
0141 }
0142 
0143 //---------------------------------------------------------------------------//
0144 /*!
0145  * Set the sampled element.
0146  */
0147 CELER_FUNCTION void PhysicsStepView::element(ElementComponentId elcomp_id)
0148 {
0149     this->state().element = elcomp_id;
0150 }
0151 
0152 //---------------------------------------------------------------------------//
0153 /*!
0154  * Save MSC step limit data.
0155  */
0156 CELER_FUNCTION void PhysicsStepView::msc_step(MscStep const& limit)
0157 {
0158     states_.msc_step[track_slot_] = limit;
0159 }
0160 
0161 //---------------------------------------------------------------------------//
0162 /*!
0163  * Reset the energy deposition to zero at the beginning of a step.
0164  */
0165 CELER_FUNCTION void PhysicsStepView::reset_energy_deposition()
0166 {
0167     this->state().energy_deposition = 0;
0168 }
0169 
0170 //---------------------------------------------------------------------------//
0171 /*!
0172  * Set the energy deposition to NaN for inactive tracks to catch errors.
0173  */
0174 CELER_FUNCTION void PhysicsStepView::reset_energy_deposition_debug()
0175 {
0176 #if !CELERITAS_DEBUG
0177     CELER_ASSERT_UNREACHABLE();
0178 #endif
0179     this->state().energy_deposition = numeric_limits<real_type>::quiet_NaN();
0180 }
0181 
0182 //---------------------------------------------------------------------------//
0183 /*!
0184  * Accumulate into local step's energy deposition.
0185  */
0186 CELER_FUNCTION void PhysicsStepView::deposit_energy(Energy energy)
0187 {
0188     CELER_EXPECT(energy >= zero_quantity());
0189     // TODO: save a memory read/write by skipping if energy is zero?
0190     this->state().energy_deposition += energy.value();
0191 }
0192 
0193 //---------------------------------------------------------------------------//
0194 /*!
0195  * Set secondaries during an interaction, or clear them with an empty span.
0196  */
0197 CELER_FUNCTION void PhysicsStepView::secondaries(Span<Secondary> sec)
0198 {
0199     this->state().secondaries = sec;
0200 }
0201 
0202 //---------------------------------------------------------------------------//
0203 /*!
0204  * Calculated process-integrated macroscopic XS.
0205  *
0206  * This value should be calculated in the pre-step kernel, and will be used to
0207  * decrement `interaction_mfp` and for sampling a process. Units are inverse
0208  * length.
0209  */
0210 CELER_FUNCTION real_type PhysicsStepView::macro_xs() const
0211 {
0212     real_type xs = this->state().macro_xs;
0213     CELER_ENSURE(xs >= 0);
0214     return xs;
0215 }
0216 
0217 //---------------------------------------------------------------------------//
0218 /*!
0219  * Sampled element for discrete interaction.
0220  */
0221 CELER_FUNCTION ElementComponentId PhysicsStepView::element() const
0222 {
0223     return this->state().element;
0224 }
0225 
0226 //---------------------------------------------------------------------------//
0227 /*!
0228  * Mutable access to MSC step data (TODO: hack)
0229  */
0230 CELER_FUNCTION MscStep& PhysicsStepView::msc_step()
0231 {
0232     return states_.msc_step[track_slot_];
0233 }
0234 
0235 //---------------------------------------------------------------------------//
0236 /*!
0237  * Access calculated MSC step data.
0238  */
0239 CELER_FUNCTION MscStep const& PhysicsStepView::msc_step() const
0240 {
0241     return states_.msc_step[track_slot_];
0242 }
0243 
0244 //---------------------------------------------------------------------------//
0245 /*!
0246  * Access accumulated energy deposition.
0247  */
0248 CELER_FUNCTION auto PhysicsStepView::energy_deposition() const -> Energy
0249 {
0250     real_type result = this->state().energy_deposition;
0251     CELER_ENSURE(result >= 0);
0252     return Energy{result};
0253 }
0254 
0255 //---------------------------------------------------------------------------//
0256 /*!
0257  * Access secondaries created by a discrete interaction.
0258  */
0259 CELER_FUNCTION Span<Secondary const> PhysicsStepView::secondaries() const
0260 {
0261     return this->state().secondaries;
0262 }
0263 
0264 //---------------------------------------------------------------------------//
0265 /*!
0266  * Access scratch space for particle-process cross section calculations.
0267  */
0268 CELER_FUNCTION real_type&
0269 PhysicsStepView::per_process_xs(ParticleProcessId ppid)
0270 {
0271     CELER_EXPECT(ppid < params_.scalars.max_particle_processes);
0272     auto idx = track_slot_.get() * params_.scalars.max_particle_processes
0273                + ppid.get();
0274     CELER_ENSURE(idx < states_.per_process_xs.size());
0275     return states_.per_process_xs[ItemId<real_type>(idx)];
0276 }
0277 
0278 //---------------------------------------------------------------------------//
0279 /*!
0280  * Access scratch space for particle-process cross section calculations.
0281  */
0282 CELER_FUNCTION
0283 real_type PhysicsStepView::per_process_xs(ParticleProcessId ppid) const
0284 {
0285     CELER_EXPECT(ppid < params_.scalars.max_particle_processes);
0286     auto idx = track_slot_.get() * params_.scalars.max_particle_processes
0287                + ppid.get();
0288     CELER_ENSURE(idx < states_.per_process_xs.size());
0289     return states_.per_process_xs[ItemId<real_type>(idx)];
0290 }
0291 
0292 //---------------------------------------------------------------------------//
0293 /*!
0294  * Return a secondary stack allocator view.
0295  */
0296 CELER_FUNCTION auto
0297 PhysicsStepView::make_secondary_allocator() const -> SecondaryAllocator
0298 {
0299     return SecondaryAllocator{states_.secondaries};
0300 }
0301 
0302 //---------------------------------------------------------------------------//
0303 /*!
0304  * Make an atomic relaxation helper for the given element.
0305  */
0306 CELER_FUNCTION auto PhysicsStepView::make_relaxation_helper(
0307     ElementId el_id) const -> AtomicRelaxationHelper
0308 {
0309     CELER_ASSERT(el_id);
0310     return AtomicRelaxationHelper{params_.hardwired.relaxation_data,
0311                                   states_.relaxation,
0312                                   el_id,
0313                                   track_slot_};
0314 }
0315 
0316 //---------------------------------------------------------------------------//
0317 // PRIVATE CLASS FUNCTIONS
0318 //---------------------------------------------------------------------------//
0319 //! Get the thread-local state (mutable)
0320 CELER_FUNCTION PhysicsTrackState& PhysicsStepView::state()
0321 {
0322     return states_.state[track_slot_];
0323 }
0324 
0325 //! Get the thread-local state (const)
0326 CELER_FUNCTION PhysicsTrackState const& PhysicsStepView::state() const
0327 {
0328     return states_.state[track_slot_];
0329 }
0330 
0331 //---------------------------------------------------------------------------//
0332 }  // namespace celeritas