File indexing completed on 2026-11-05 10:28:00
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include <cmath>
0010
0011 #include "corecel/Assert.hh"
0012 #include "corecel/Macros.hh"
0013 #include "corecel/Types.hh"
0014 #include "corecel/math/Algorithms.hh"
0015 #include "corecel/sys/ThreadId.hh"
0016 #include "celeritas/Quantities.hh"
0017
0018 #include "ParticleData.hh"
0019 #include "ParticleView.hh"
0020
0021 namespace celeritas
0022 {
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 class ParticleTrackView
0035 {
0036 public:
0037
0038
0039 using ParamsRef = celeritas::NativeCRef<ParticleParamsData>;
0040 using StateRef = celeritas::NativeRef<ParticleStateData>;
0041 using Initializer_t = ParticleTrackInitializer;
0042
0043 using Charge = units::ElementaryCharge;
0044 using Energy = units::MevEnergy;
0045 using Mass = units::MevMass;
0046 using Momentum = units::MevMomentum;
0047 using MomentumSq = units::MevMomentumSq;
0048 using Speed = units::LightSpeed;
0049
0050
0051 public:
0052
0053 inline CELER_FUNCTION ParticleTrackView(
0054 ParamsRef const& params, StateRef const& states, TrackSlotId id);
0055
0056
0057 inline CELER_FUNCTION ParticleTrackView& operator=(
0058 Initializer_t const& other);
0059
0060
0061 inline CELER_FUNCTION void energy(Energy);
0062
0063
0064
0065
0066 CELER_FORCEINLINE_FUNCTION ParticleId particle_id() const;
0067
0068
0069 CELER_FORCEINLINE_FUNCTION Energy energy() const;
0070
0071
0072 CELER_FORCEINLINE_FUNCTION bool is_stopped() const;
0073
0074
0075
0076 CELER_FORCEINLINE_FUNCTION ParticleView particle_view() const;
0077
0078
0079 CELER_FORCEINLINE_FUNCTION Mass mass() const;
0080
0081
0082 CELER_FORCEINLINE_FUNCTION Charge charge() const;
0083
0084
0085 CELER_FORCEINLINE_FUNCTION real_type decay_constant() const;
0086
0087
0088 CELER_FORCEINLINE_FUNCTION bool is_antiparticle() const;
0089
0090
0091 CELER_FORCEINLINE_FUNCTION bool is_stable() const;
0092
0093
0094 CELER_FORCEINLINE_FUNCTION bool is_heavy() const;
0095
0096
0097
0098
0099 inline CELER_FUNCTION Energy total_energy() const;
0100
0101
0102 inline CELER_FUNCTION real_type beta_sq() const;
0103
0104
0105 inline CELER_FUNCTION Speed speed() const;
0106
0107
0108 inline CELER_FUNCTION real_type lorentz_factor() const;
0109
0110
0111 inline CELER_FUNCTION Momentum momentum() const;
0112
0113
0114 inline CELER_FUNCTION MomentumSq momentum_sq() const;
0115
0116 private:
0117 ParamsRef const& params_;
0118 StateRef const& states_;
0119 TrackSlotId const track_slot_;
0120 };
0121
0122
0123
0124
0125
0126
0127
0128 CELER_FUNCTION ParticleTrackView::ParticleTrackView(
0129 ParamsRef const& params, StateRef const& states, TrackSlotId tid)
0130 : params_(params), states_(states), track_slot_(tid)
0131 {
0132 CELER_EXPECT(track_slot_ < states_.size());
0133 }
0134
0135
0136
0137
0138
0139 CELER_FUNCTION ParticleTrackView& ParticleTrackView::operator=(
0140 Initializer_t const& other)
0141 {
0142 CELER_EXPECT(other.particle_id < params_.size());
0143 CELER_EXPECT(other.energy >= zero_quantity());
0144 states_.particle_id[track_slot_] = other.particle_id;
0145 states_.particle_energy[track_slot_] = other.energy.value();
0146 return *this;
0147 }
0148
0149
0150
0151
0152
0153
0154
0155
0156 CELER_FUNCTION void ParticleTrackView::energy(Energy quantity)
0157 {
0158 CELER_EXPECT(this->particle_id());
0159 CELER_EXPECT(quantity >= zero_quantity());
0160 states_.particle_energy[track_slot_] = quantity.value();
0161 }
0162
0163
0164
0165
0166
0167
0168
0169 CELER_FUNCTION ParticleId ParticleTrackView::particle_id() const
0170 {
0171 return states_.particle_id[track_slot_];
0172 }
0173
0174
0175
0176
0177
0178 CELER_FUNCTION auto ParticleTrackView::energy() const -> Energy
0179 {
0180 return Energy{states_.particle_energy[track_slot_]};
0181 }
0182
0183
0184
0185
0186
0187 CELER_FUNCTION bool ParticleTrackView::is_stopped() const
0188 {
0189 return this->energy() == zero_quantity();
0190 }
0191
0192
0193
0194
0195
0196
0197
0198 CELER_FUNCTION ParticleView ParticleTrackView::particle_view() const
0199 {
0200 return ParticleView(params_, states_.particle_id[track_slot_]);
0201 }
0202
0203
0204
0205
0206
0207 CELER_FUNCTION auto ParticleTrackView::mass() const -> Mass
0208 {
0209 return this->particle_view().mass();
0210 }
0211
0212
0213
0214
0215
0216 CELER_FUNCTION auto ParticleTrackView::charge() const -> Charge
0217 {
0218 return this->particle_view().charge();
0219 }
0220
0221
0222
0223
0224
0225 CELER_FUNCTION real_type ParticleTrackView::decay_constant() const
0226 {
0227 return this->particle_view().decay_constant();
0228 }
0229
0230
0231
0232
0233
0234 CELER_FUNCTION bool ParticleTrackView::is_antiparticle() const
0235 {
0236 return this->particle_view().is_antiparticle();
0237 }
0238
0239
0240
0241
0242
0243 CELER_FUNCTION bool ParticleTrackView::is_stable() const
0244 {
0245 return this->decay_constant() == constants::stable_decay_constant;
0246 }
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 CELER_FUNCTION bool ParticleTrackView::is_heavy() const
0257 {
0258 return this->mass() > units::MevMass{1};
0259 }
0260
0261
0262
0263
0264
0265
0266
0267 CELER_FUNCTION auto ParticleTrackView::total_energy() const -> Energy
0268 {
0269 return Energy(
0270 value_as<Energy>(this->energy()) + value_as<Mass>(this->mass()));
0271 }
0272
0273
0274
0275
0276
0277 CELER_FUNCTION real_type ParticleTrackView::beta_sq() const
0278 {
0279 return ipow<2>(value_as<Speed>(this->speed()));
0280 }
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308 CELER_FUNCTION auto ParticleTrackView::speed() const -> Speed
0309 {
0310
0311 real_type const mcsq = value_as<Mass>(this->mass());
0312
0313 real_type const energy = value_as<Energy>(this->energy());
0314
0315 return Speed{std::sqrt(energy * (energy + 2 * mcsq)) / (energy + mcsq)};
0316 }
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341 CELER_FUNCTION real_type ParticleTrackView::lorentz_factor() const
0342 {
0343 CELER_EXPECT(this->mass() > zero_quantity());
0344
0345 real_type k_over_mc2 = this->energy().value() / this->mass().value();
0346 return 1 + k_over_mc2;
0347 }
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370 CELER_FUNCTION auto ParticleTrackView::momentum_sq() const -> MomentumSq
0371 {
0372 real_type const energy = this->energy().value();
0373 real_type result = ipow<2>(energy) + 2 * this->mass().value() * energy;
0374 CELER_ENSURE(result >= 0);
0375 return MomentumSq{result};
0376 }
0377
0378
0379
0380
0381
0382
0383
0384 CELER_FUNCTION auto ParticleTrackView::momentum() const -> Momentum
0385 {
0386 return Momentum{std::sqrt(this->momentum_sq().value())};
0387 }
0388
0389
0390 }