File indexing completed on 2026-01-09 10:08:05
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(ParamsRef const& params,
0054 StateRef const& states,
0055 TrackSlotId id);
0056
0057
0058 inline CELER_FUNCTION ParticleTrackView&
0059 operator=(Initializer_t const& other);
0060
0061
0062 inline CELER_FUNCTION void energy(Energy);
0063
0064
0065 inline CELER_FUNCTION void subtract_energy(Energy);
0066
0067
0068
0069
0070 CELER_FORCEINLINE_FUNCTION ParticleId particle_id() const;
0071
0072
0073 CELER_FORCEINLINE_FUNCTION Energy energy() const;
0074
0075
0076 CELER_FORCEINLINE_FUNCTION bool is_stopped() const;
0077
0078
0079
0080 CELER_FORCEINLINE_FUNCTION ParticleView particle_view() const;
0081
0082
0083 CELER_FORCEINLINE_FUNCTION Mass mass() const;
0084
0085
0086 CELER_FORCEINLINE_FUNCTION Charge charge() const;
0087
0088
0089 CELER_FORCEINLINE_FUNCTION real_type decay_constant() const;
0090
0091
0092 CELER_FORCEINLINE_FUNCTION bool is_antiparticle() const;
0093
0094
0095 CELER_FORCEINLINE_FUNCTION bool is_stable() const;
0096
0097
0098 CELER_FORCEINLINE_FUNCTION bool is_heavy() const;
0099
0100
0101
0102
0103 inline CELER_FUNCTION Energy total_energy() const;
0104
0105
0106 inline CELER_FUNCTION real_type beta_sq() const;
0107
0108
0109 inline CELER_FUNCTION Speed speed() const;
0110
0111
0112 inline CELER_FUNCTION real_type lorentz_factor() const;
0113
0114
0115 inline CELER_FUNCTION Momentum momentum() const;
0116
0117
0118 inline CELER_FUNCTION MomentumSq momentum_sq() const;
0119
0120 private:
0121 ParamsRef const& params_;
0122 StateRef const& states_;
0123 TrackSlotId const track_slot_;
0124 };
0125
0126
0127
0128
0129
0130
0131
0132 CELER_FUNCTION
0133 ParticleTrackView::ParticleTrackView(ParamsRef const& params,
0134 StateRef const& states,
0135 TrackSlotId tid)
0136 : params_(params), states_(states), track_slot_(tid)
0137 {
0138 CELER_EXPECT(track_slot_ < states_.size());
0139 }
0140
0141
0142
0143
0144
0145 CELER_FUNCTION ParticleTrackView&
0146 ParticleTrackView::operator=(Initializer_t const& other)
0147 {
0148 CELER_EXPECT(other.particle_id < params_.size());
0149 CELER_EXPECT(other.energy >= zero_quantity());
0150 states_.particle_id[track_slot_] = other.particle_id;
0151 states_.particle_energy[track_slot_] = other.energy.value();
0152 return *this;
0153 }
0154
0155
0156
0157
0158
0159
0160
0161
0162 CELER_FUNCTION
0163 void ParticleTrackView::energy(Energy quantity)
0164 {
0165 CELER_EXPECT(this->particle_id());
0166 CELER_EXPECT(quantity >= zero_quantity());
0167 states_.particle_energy[track_slot_] = quantity.value();
0168 }
0169
0170
0171
0172
0173
0174 CELER_FUNCTION void ParticleTrackView::subtract_energy(Energy eloss)
0175 {
0176 CELER_EXPECT(eloss >= zero_quantity());
0177 CELER_EXPECT(eloss <= this->energy());
0178
0179 states_.particle_energy[track_slot_] -= eloss.value();
0180 }
0181
0182
0183
0184
0185
0186
0187
0188 CELER_FUNCTION ParticleId ParticleTrackView::particle_id() const
0189 {
0190 return states_.particle_id[track_slot_];
0191 }
0192
0193
0194
0195
0196
0197 CELER_FUNCTION auto ParticleTrackView::energy() const -> Energy
0198 {
0199 return Energy{states_.particle_energy[track_slot_]};
0200 }
0201
0202
0203
0204
0205
0206 CELER_FUNCTION bool ParticleTrackView::is_stopped() const
0207 {
0208 return this->energy() == zero_quantity();
0209 }
0210
0211
0212
0213
0214
0215
0216
0217 CELER_FUNCTION ParticleView ParticleTrackView::particle_view() const
0218 {
0219 return ParticleView(params_, states_.particle_id[track_slot_]);
0220 }
0221
0222
0223
0224
0225
0226 CELER_FUNCTION auto ParticleTrackView::mass() const -> Mass
0227 {
0228 return this->particle_view().mass();
0229 }
0230
0231
0232
0233
0234
0235 CELER_FUNCTION auto ParticleTrackView::charge() const -> Charge
0236 {
0237 return this->particle_view().charge();
0238 }
0239
0240
0241
0242
0243
0244 CELER_FUNCTION real_type ParticleTrackView::decay_constant() const
0245 {
0246 return this->particle_view().decay_constant();
0247 }
0248
0249
0250
0251
0252
0253 CELER_FUNCTION bool ParticleTrackView::is_antiparticle() const
0254 {
0255 return this->particle_view().is_antiparticle();
0256 }
0257
0258
0259
0260
0261
0262 CELER_FUNCTION bool ParticleTrackView::is_stable() const
0263 {
0264 return this->decay_constant() == constants::stable_decay_constant;
0265 }
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275 CELER_FUNCTION bool ParticleTrackView::is_heavy() const
0276 {
0277 return this->mass() > units::MevMass{1};
0278 }
0279
0280
0281
0282
0283
0284
0285
0286 CELER_FUNCTION auto ParticleTrackView::total_energy() const -> Energy
0287 {
0288 return Energy(value_as<Energy>(this->energy())
0289 + value_as<Mass>(this->mass()));
0290 }
0291
0292
0293
0294
0295
0296 CELER_FUNCTION real_type ParticleTrackView::beta_sq() const
0297 {
0298 return ipow<2>(value_as<Speed>(this->speed()));
0299 }
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327 CELER_FUNCTION auto ParticleTrackView::speed() const -> Speed
0328 {
0329
0330 real_type const mcsq = value_as<Mass>(this->mass());
0331
0332 real_type const energy = value_as<Energy>(this->energy());
0333
0334 return Speed{std::sqrt(energy * (energy + 2 * mcsq)) / (energy + mcsq)};
0335 }
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360 CELER_FUNCTION real_type ParticleTrackView::lorentz_factor() const
0361 {
0362 CELER_EXPECT(this->mass() > zero_quantity());
0363
0364 real_type k_over_mc2 = this->energy().value() / this->mass().value();
0365 return 1 + k_over_mc2;
0366 }
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386
0387
0388
0389 CELER_FUNCTION auto ParticleTrackView::momentum_sq() const -> MomentumSq
0390 {
0391 real_type const energy = this->energy().value();
0392 real_type result = ipow<2>(energy) + 2 * this->mass().value() * energy;
0393 CELER_ENSURE(result >= 0);
0394 return MomentumSq{result};
0395 }
0396
0397
0398
0399
0400
0401
0402
0403 CELER_FUNCTION auto ParticleTrackView::momentum() const -> Momentum
0404 {
0405 return Momentum{std::sqrt(this->momentum_sq().value())};
0406 }
0407
0408
0409 }