File indexing completed on 2026-11-08 10:11:27
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& looping_threshold(
0123 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 SimTrackView::SimTrackView(
0141 SimParamsRef const& params, SimStateRef const& states, TrackSlotId tid)
0142 : params_(params), states_(states), track_slot_(tid)
0143 {
0144 CELER_EXPECT(track_slot_ < states_.size());
0145 }
0146
0147
0148
0149
0150
0151 CELER_FUNCTION SimTrackView& SimTrackView::operator=(Initializer_t const& other)
0152 {
0153 states_.track_ids[track_slot_] = other.track_id;
0154 states_.primary_ids[track_slot_] = other.primary_id;
0155 states_.parent_ids[track_slot_] = other.parent_id;
0156 states_.event_ids[track_slot_] = other.event_id;
0157 states_.num_steps[track_slot_] = 0;
0158 states_.weight[track_slot_] = other.weight;
0159 if (!states_.num_looping_steps.empty())
0160 {
0161 states_.num_looping_steps[track_slot_] = 0;
0162 }
0163 states_.time[track_slot_] = other.time;
0164 states_.status[track_slot_] = TrackStatus::initializing;
0165 states_.step_length[track_slot_] = {};
0166 states_.post_step_action[track_slot_] = {};
0167 states_.along_step_action[track_slot_] = {};
0168 return *this;
0169 }
0170
0171
0172
0173
0174
0175 CELER_FUNCTION void SimTrackView::add_time(real_type delta)
0176 {
0177 CELER_EXPECT(delta >= 0);
0178 states_.time[track_slot_] += delta;
0179 }
0180
0181
0182
0183
0184
0185 CELER_FORCEINLINE_FUNCTION void SimTrackView::increment_num_steps()
0186 {
0187 ++states_.num_steps[track_slot_];
0188 }
0189
0190
0191
0192
0193
0194 CELER_FUNCTION void SimTrackView::update_looping(bool is_looping)
0195 {
0196 CELER_EXPECT(!params_.looping.empty());
0197 if (is_looping)
0198 {
0199 ++states_.num_looping_steps[track_slot_];
0200 }
0201 else
0202 {
0203 states_.num_looping_steps[track_slot_] = 0;
0204 }
0205 }
0206
0207
0208
0209
0210
0211 CELER_FUNCTION bool SimTrackView::is_looping(ParticleId pid, Energy energy)
0212 {
0213 CELER_EXPECT(!params_.looping.empty());
0214 auto const& looping = this->looping_threshold(pid);
0215 if (energy < looping.threshold_energy)
0216 {
0217 return this->num_looping_steps() >= looping.max_subthreshold_steps;
0218 }
0219 else
0220 {
0221 return this->num_looping_steps() >= looping.max_steps;
0222 }
0223 return false;
0224 }
0225
0226
0227
0228
0229
0230
0231
0232 CELER_FUNCTION void SimTrackView::reset_step_limit(StepLimit const& sl)
0233 {
0234 CELER_EXPECT(sl.step >= 0);
0235 CELER_EXPECT(static_cast<bool>(sl.action)
0236 != (sl.step == numeric_limits<real_type>::infinity()));
0237 states_.step_length[track_slot_] = sl.step;
0238 states_.post_step_action[track_slot_] = sl.action;
0239 }
0240
0241
0242
0243
0244
0245 CELER_FUNCTION void SimTrackView::reset_step_limit()
0246 {
0247 StepLimit limit;
0248 limit.step = numeric_limits<real_type>::infinity();
0249 limit.action = {};
0250 this->reset_step_limit(limit);
0251 this->along_step_action({});
0252 }
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262 CELER_FUNCTION void SimTrackView::post_step_action(ActionId action)
0263 {
0264 CELER_ASSERT(action);
0265 states_.post_step_action[track_slot_] = action;
0266 }
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276 CELER_FUNCTION bool SimTrackView::step_limit(StepLimit const& sl)
0277 {
0278 CELER_ASSERT(sl.step >= 0);
0279
0280 bool is_limiting = (sl.step < states_.step_length[track_slot_]);
0281 if (is_limiting)
0282 {
0283 states_.step_length[track_slot_] = sl.step;
0284 states_.post_step_action[track_slot_] = sl.action;
0285 }
0286 return is_limiting;
0287 }
0288
0289
0290
0291
0292
0293 CELER_FORCEINLINE_FUNCTION ActionId SimTrackView::post_step_action() const
0294 {
0295 return states_.post_step_action[track_slot_];
0296 }
0297
0298
0299
0300
0301
0302 CELER_FORCEINLINE_FUNCTION ActionId SimTrackView::along_step_action() const
0303 {
0304 return states_.along_step_action[track_slot_];
0305 }
0306
0307
0308
0309
0310
0311 CELER_FORCEINLINE_FUNCTION void SimTrackView::along_step_action(ActionId action)
0312 {
0313 states_.along_step_action[track_slot_] = action;
0314 }
0315
0316
0317
0318
0319
0320 CELER_FUNCTION void SimTrackView::status(TrackStatus status)
0321 {
0322 CELER_EXPECT(status != TrackStatus::size_);
0323 states_.status[track_slot_] = status;
0324 }
0325
0326
0327
0328
0329
0330
0331
0332 CELER_FORCEINLINE_FUNCTION TrackId SimTrackView::track_id() const
0333 {
0334 return states_.track_ids[track_slot_];
0335 }
0336
0337
0338
0339
0340 CELER_FORCEINLINE_FUNCTION PrimaryId SimTrackView::primary_id() const
0341 {
0342 return states_.primary_ids[track_slot_];
0343 }
0344
0345
0346
0347
0348
0349 CELER_FORCEINLINE_FUNCTION TrackId SimTrackView::parent_id() const
0350 {
0351 return states_.parent_ids[track_slot_];
0352 }
0353
0354
0355
0356
0357
0358 CELER_FORCEINLINE_FUNCTION EventId SimTrackView::event_id() const
0359 {
0360 return states_.event_ids[track_slot_];
0361 }
0362
0363
0364
0365
0366
0367 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::num_steps() const
0368 {
0369 return states_.num_steps[track_slot_];
0370 }
0371
0372
0373
0374
0375
0376 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::num_looping_steps() const
0377 {
0378 return states_.num_looping_steps[track_slot_];
0379 }
0380
0381
0382
0383
0384
0385 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::time() const
0386 {
0387 return states_.time[track_slot_];
0388 }
0389
0390
0391
0392
0393
0394 CELER_FORCEINLINE_FUNCTION TrackStatus SimTrackView::status() const
0395 {
0396 return states_.status[track_slot_];
0397 }
0398
0399
0400
0401
0402
0403 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::step_length() const
0404 {
0405 return states_.step_length[track_slot_];
0406 }
0407
0408
0409
0410
0411 CELER_FORCEINLINE_FUNCTION real_type SimTrackView::weight() const
0412 {
0413 return states_.weight[track_slot_];
0414 }
0415
0416
0417
0418
0419
0420 CELER_FUNCTION void SimTrackView::step_length(real_type length)
0421 {
0422 CELER_EXPECT(length > 0);
0423 states_.step_length[track_slot_] = length;
0424 }
0425
0426
0427
0428
0429
0430 CELER_FORCEINLINE_FUNCTION LoopingThreshold const&
0431 SimTrackView::looping_threshold(ParticleId pid) const
0432 {
0433 return params_.looping[pid];
0434 }
0435
0436
0437
0438
0439
0440 CELER_FORCEINLINE_FUNCTION size_type SimTrackView::max_steps() const
0441 {
0442 return params_.max_steps;
0443 }
0444
0445
0446 }