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