File indexing completed on 2026-05-12 08:36:33
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Macros.hh"
0010 #include "corecel/Types.hh"
0011 #include "corecel/cont/Span.hh"
0012 #include "corecel/sys/ThreadId.hh"
0013 #include "celeritas/Types.hh"
0014 #include "celeritas/phys/Secondary.hh"
0015
0016 #include "SimData.hh"
0017
0018 namespace celeritas
0019 {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 class SimTrackView
0032 {
0033 public:
0034
0035
0036 using SimParamsRef = NativeCRef<SimParamsData>;
0037 using SimStateRef = NativeRef<SimStateData>;
0038 using Initializer_t = SimTrackInitializer;
0039 using Energy = units::MevEnergy;
0040
0041
0042 public:
0043
0044 inline CELER_FUNCTION SimTrackView(SimParamsRef const& params,
0045 SimStateRef const& states,
0046 TrackSlotId tid);
0047
0048
0049 inline CELER_FUNCTION SimTrackView& operator=(Initializer_t const& other);
0050
0051
0052 inline CELER_FUNCTION void add_time(real_type delta);
0053
0054
0055 inline CELER_FUNCTION void increment_num_steps();
0056
0057
0058 inline CELER_FUNCTION void update_looping(bool);
0059
0060
0061 inline CELER_FUNCTION bool is_looping(ParticleId, Energy);
0062
0063
0064 inline CELER_FUNCTION void status(TrackStatus);
0065
0066
0067 inline CELER_FUNCTION void reset_step_limit();
0068
0069
0070 inline CELER_FUNCTION void reset_step_limit(StepLimit const& sl);
0071
0072
0073 inline CELER_FUNCTION bool step_limit(StepLimit const& sl);
0074
0075
0076 inline CELER_FUNCTION TrackId track_id() const;
0077
0078
0079 inline CELER_FUNCTION PrimaryId primary_id() const;
0080
0081
0082 inline CELER_FUNCTION TrackId parent_id() const;
0083
0084
0085 inline CELER_FUNCTION EventId event_id() const;
0086
0087
0088 inline CELER_FUNCTION size_type num_steps() const;
0089
0090
0091 inline CELER_FUNCTION size_type num_looping_steps() const;
0092
0093
0094 inline CELER_FUNCTION real_type time() const;
0095
0096
0097 inline CELER_FUNCTION TrackStatus status() const;
0098
0099
0100 inline CELER_FUNCTION real_type step_length() const;
0101
0102 inline CELER_FUNCTION real_type weight() const;
0103
0104
0105 inline CELER_FUNCTION void step_length(real_type length);
0106
0107
0108 inline CELER_FUNCTION ActionId post_step_action() const;
0109
0110
0111 inline CELER_FUNCTION void post_step_action(ActionId action);
0112
0113
0114 inline CELER_FUNCTION ActionId along_step_action() const;
0115
0116
0117 inline CELER_FUNCTION void along_step_action(ActionId action);
0118
0119
0120
0121
0122 inline CELER_FUNCTION LoopingThreshold const&
0123 looping_threshold(ParticleId) const;
0124
0125
0126 inline CELER_FUNCTION size_type max_steps() const;
0127
0128 private:
0129 SimParamsRef const& params_;
0130 SimStateRef const& states_;
0131 TrackSlotId const track_slot_;
0132 };
0133
0134
0135
0136
0137
0138
0139
0140 CELER_FUNCTION
0141 SimTrackView::SimTrackView(SimParamsRef const& params,
0142 SimStateRef const& states,
0143 TrackSlotId tid)
0144 : params_(params), states_(states), track_slot_(tid)
0145 {
0146 CELER_EXPECT(track_slot_ < states_.size());
0147 }
0148
0149
0150
0151
0152
0153 CELER_FUNCTION SimTrackView& SimTrackView::operator=(Initializer_t const& other)
0154 {
0155 states_.track_ids[track_slot_] = other.track_id;
0156 states_.primary_ids[track_slot_] = other.primary_id;
0157 states_.parent_ids[track_slot_] = other.parent_id;
0158 states_.event_ids[track_slot_] = other.event_id;
0159 states_.num_steps[track_slot_] = 0;
0160 states_.weight[track_slot_] = other.weight;
0161 if (!states_.num_looping_steps.empty())
0162 {
0163 states_.num_looping_steps[track_slot_] = 0;
0164 }
0165 states_.time[track_slot_] = other.time;
0166 states_.status[track_slot_] = TrackStatus::initializing;
0167 states_.step_length[track_slot_] = {};
0168 states_.post_step_action[track_slot_] = {};
0169 states_.along_step_action[track_slot_] = {};
0170 return *this;
0171 }
0172
0173
0174
0175
0176
0177 CELER_FUNCTION void SimTrackView::add_time(real_type delta)
0178 {
0179 CELER_EXPECT(delta >= 0);
0180 states_.time[track_slot_] += delta;
0181 }
0182
0183
0184
0185
0186
0187 CELER_FORCEINLINE_FUNCTION void SimTrackView::increment_num_steps()
0188 {
0189 ++states_.num_steps[track_slot_];
0190 }
0191
0192
0193
0194
0195
0196 CELER_FUNCTION void SimTrackView::update_looping(bool is_looping)
0197 {
0198 CELER_EXPECT(!params_.looping.empty());
0199 if (is_looping)
0200 {
0201 ++states_.num_looping_steps[track_slot_];
0202 }
0203 else
0204 {
0205 states_.num_looping_steps[track_slot_] = 0;
0206 }
0207 }
0208
0209
0210
0211
0212
0213 CELER_FUNCTION bool SimTrackView::is_looping(ParticleId pid, Energy energy)
0214 {
0215 CELER_EXPECT(!params_.looping.empty());
0216 auto const& looping = this->looping_threshold(pid);
0217 if (energy < looping.threshold_energy)
0218 {
0219 return this->num_looping_steps() >= looping.max_subthreshold_steps;
0220 }
0221 else
0222 {
0223 return this->num_looping_steps() >= looping.max_steps;
0224 }
0225 return false;
0226 }
0227
0228
0229
0230
0231
0232
0233
0234 CELER_FUNCTION void SimTrackView::reset_step_limit(StepLimit const& sl)
0235 {
0236 CELER_EXPECT(sl.step >= 0);
0237 CELER_EXPECT(static_cast<bool>(sl.action)
0238 != (sl.step == numeric_limits<real_type>::infinity()));
0239 states_.step_length[track_slot_] = sl.step;
0240 states_.post_step_action[track_slot_] = sl.action;
0241 }
0242
0243
0244
0245
0246
0247 CELER_FUNCTION void SimTrackView::reset_step_limit()
0248 {
0249 StepLimit limit;
0250 limit.step = numeric_limits<real_type>::infinity();
0251 limit.action = {};
0252 this->reset_step_limit(limit);
0253 this->along_step_action({});
0254 }
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264 CELER_FUNCTION void SimTrackView::post_step_action(ActionId action)
0265 {
0266 CELER_ASSERT(action);
0267 states_.post_step_action[track_slot_] = action;
0268 }
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278 CELER_FUNCTION bool SimTrackView::step_limit(StepLimit const& sl)
0279 {
0280 CELER_ASSERT(sl.step >= 0);
0281
0282 bool is_limiting = (sl.step < states_.step_length[track_slot_]);
0283 if (is_limiting)
0284 {
0285 states_.step_length[track_slot_] = sl.step;
0286 states_.post_step_action[track_slot_] = sl.action;
0287 }
0288 return is_limiting;
0289 }
0290
0291
0292
0293
0294
0295 CELER_FORCEINLINE_FUNCTION ActionId SimTrackView::post_step_action() const
0296 {
0297 return states_.post_step_action[track_slot_];
0298 }
0299
0300
0301
0302
0303
0304 CELER_FORCEINLINE_FUNCTION ActionId SimTrackView::along_step_action() const
0305 {
0306 return states_.along_step_action[track_slot_];
0307 }
0308
0309
0310
0311
0312
0313 CELER_FORCEINLINE_FUNCTION void SimTrackView::along_step_action(ActionId action)
0314 {
0315 states_.along_step_action[track_slot_] = action;
0316 }
0317
0318
0319
0320
0321
0322 CELER_FUNCTION void SimTrackView::status(TrackStatus status)
0323 {
0324 CELER_EXPECT(status != TrackStatus::size_);
0325 states_.status[track_slot_] = status;
0326 }
0327
0328
0329
0330
0331
0332
0333
0334 CELER_FORCEINLINE_FUNCTION TrackId SimTrackView::track_id() const
0335 {
0336 return states_.track_ids[track_slot_];
0337 }
0338
0339
0340
0341
0342 CELER_FORCEINLINE_FUNCTION PrimaryId SimTrackView::primary_id() const
0343 {
0344 return states_.primary_ids[track_slot_];
0345 }
0346
0347
0348
0349
0350
0351 CELER_FORCEINLINE_FUNCTION TrackId SimTrackView::parent_id() const
0352 {
0353 return states_.parent_ids[track_slot_];
0354 }
0355
0356
0357
0358
0359
0360 CELER_FORCEINLINE_FUNCTION EventId SimTrackView::event_id() const
0361 {
0362 return states_.event_ids[track_slot_];
0363 }
0364
0365
0366
0367
0368
0369 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::num_steps() const
0370 {
0371 return states_.num_steps[track_slot_];
0372 }
0373
0374
0375
0376
0377
0378 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::num_looping_steps() const
0379 {
0380 return states_.num_looping_steps[track_slot_];
0381 }
0382
0383
0384
0385
0386
0387 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::time() const
0388 {
0389 return states_.time[track_slot_];
0390 }
0391
0392
0393
0394
0395
0396 CELER_FORCEINLINE_FUNCTION TrackStatus SimTrackView::status() const
0397 {
0398 return states_.status[track_slot_];
0399 }
0400
0401
0402
0403
0404
0405 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::step_length() const
0406 {
0407 return states_.step_length[track_slot_];
0408 }
0409
0410
0411
0412
0413 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::weight() const
0414 {
0415 return states_.weight[track_slot_];
0416 }
0417
0418
0419
0420
0421
0422 CELER_FUNCTION void SimTrackView::step_length(real_type length)
0423 {
0424 CELER_EXPECT(length > 0);
0425 states_.step_length[track_slot_] = length;
0426 }
0427
0428
0429
0430
0431
0432 CELER_FORCEINLINE_FUNCTION LoopingThreshold const&
0433 SimTrackView::looping_threshold(ParticleId pid) const
0434 {
0435 return params_.looping[pid];
0436 }
0437
0438
0439
0440
0441
0442 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::max_steps() const
0443 {
0444 return params_.max_steps;
0445 }
0446
0447
0448 }