File indexing completed on 2026-11-02 10:13:24
0001
0002
0003
0004
0005
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
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 class PhysicsStepView
0038 {
0039 public:
0040
0041
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
0050 inline CELER_FUNCTION PhysicsStepView(PhysicsParamsRef const& params,
0051 PhysicsStateRef const& states,
0052 TrackSlotId tid);
0053
0054
0055 inline CELER_FUNCTION void macro_xs(real_type);
0056
0057
0058 inline CELER_FUNCTION void element(ElementComponentId);
0059
0060
0061 inline CELER_FUNCTION void msc_step(MscStep const&);
0062
0063
0064 inline CELER_FUNCTION void reset_energy_deposition();
0065
0066
0067 inline CELER_FUNCTION void reset_energy_deposition_debug();
0068
0069
0070 inline CELER_FUNCTION void deposit_energy(Energy);
0071
0072
0073 template<class PTV>
0074 inline CELER_FUNCTION void deposit_energy_from(Energy deposited,
0075 PTV&& particle);
0076
0077
0078 inline CELER_FUNCTION void secondaries(Span<Secondary>);
0079
0080
0081 CELER_FORCEINLINE_FUNCTION real_type macro_xs() const;
0082
0083
0084 CELER_FORCEINLINE_FUNCTION ElementComponentId element() const;
0085
0086
0087 inline CELER_FUNCTION MscStep& msc_step();
0088
0089
0090 inline CELER_FUNCTION MscStep const& msc_step() const;
0091
0092
0093 inline CELER_FUNCTION Energy energy_deposition() const;
0094
0095
0096 inline CELER_FUNCTION Span<Secondary const> secondaries() const;
0097
0098
0099 inline CELER_FUNCTION real_type& per_process_xs(ParticleProcessId);
0100 inline CELER_FUNCTION real_type per_process_xs(ParticleProcessId) const;
0101
0102
0103
0104
0105 inline CELER_FUNCTION SecondaryAllocator make_secondary_allocator() const;
0106
0107
0108 inline CELER_FUNCTION AtomicRelaxationHelper make_relaxation_helper(
0109 ElementId el_id) const;
0110
0111 private:
0112
0113
0114 PhysicsParamsRef const& params_;
0115 PhysicsStateRef const& states_;
0116 TrackSlotId const track_slot_;
0117
0118
0119
0120 CELER_FORCEINLINE_FUNCTION PhysicsTrackState& state();
0121 CELER_FORCEINLINE_FUNCTION PhysicsTrackState const& state() const;
0122 };
0123
0124
0125
0126
0127
0128
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
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
0151
0152 CELER_FUNCTION void PhysicsStepView::element(ElementComponentId elcomp_id)
0153 {
0154 this->state().element = elcomp_id;
0155 }
0156
0157
0158
0159
0160
0161 CELER_FUNCTION void PhysicsStepView::msc_step(MscStep const& limit)
0162 {
0163 states_.msc_step[track_slot_] = limit;
0164 }
0165
0166
0167
0168
0169
0170 CELER_FUNCTION void PhysicsStepView::reset_energy_deposition()
0171 {
0172 this->state().energy_deposition = 0;
0173 }
0174
0175
0176
0177
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
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
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
0214
0215 CELER_FUNCTION void PhysicsStepView::secondaries(Span<Secondary> sec)
0216 {
0217 this->state().secondaries = sec;
0218 }
0219
0220
0221
0222
0223
0224
0225
0226
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
0238
0239 CELER_FUNCTION ElementComponentId PhysicsStepView::element() const
0240 {
0241 return this->state().element;
0242 }
0243
0244
0245
0246
0247
0248 CELER_FUNCTION MscStep& PhysicsStepView::msc_step()
0249 {
0250 return states_.msc_step[track_slot_];
0251 }
0252
0253
0254
0255
0256
0257 CELER_FUNCTION MscStep const& PhysicsStepView::msc_step() const
0258 {
0259 return states_.msc_step[track_slot_];
0260 }
0261
0262
0263
0264
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
0276
0277 CELER_FUNCTION Span<Secondary const> PhysicsStepView::secondaries() const
0278 {
0279 return this->state().secondaries;
0280 }
0281
0282
0283
0284
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
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
0313
0314 CELER_FUNCTION auto PhysicsStepView::make_secondary_allocator() const
0315 -> SecondaryAllocator
0316 {
0317 return SecondaryAllocator{states_.secondaries};
0318 }
0319
0320
0321
0322
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
0334
0335
0336 CELER_FUNCTION PhysicsTrackState& PhysicsStepView::state()
0337 {
0338 return states_.state[track_slot_];
0339 }
0340
0341
0342 CELER_FUNCTION PhysicsTrackState const& PhysicsStepView::state() const
0343 {
0344 return states_.state[track_slot_];
0345 }
0346
0347
0348 }