Warning, file /include/celeritas/user/StepData.hh was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009 #include "corecel/Macros.hh"
0010 #include "corecel/cont/EnumArray.hh"
0011 #include "corecel/cont/Range.hh"
0012 #include "corecel/data/Collection.hh"
0013 #include "corecel/data/CollectionBuilder.hh"
0014 #include "celeritas/Quantities.hh"
0015 #include "celeritas/Types.hh"
0016 #include "celeritas/Units.hh"
0017
0018 namespace celeritas
0019 {
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 struct StepPointSelection
0030 {
0031 bool time{false};
0032 bool pos{false};
0033 bool dir{false};
0034 bool energy{false};
0035
0036 bool volume_id{false};
0037 bool volume_instance_ids{false};
0038
0039
0040 static constexpr StepPointSelection all()
0041 {
0042 return StepPointSelection{true, true, true, true, true, true};
0043 }
0044
0045
0046 explicit CELER_FUNCTION operator bool() const
0047 {
0048 return time || pos || dir || energy || volume_id || volume_instance_ids;
0049 }
0050
0051
0052 StepPointSelection& operator|=(StepPointSelection const& other)
0053 {
0054 this->time |= other.time;
0055 this->pos |= other.pos;
0056 this->dir |= other.dir;
0057 this->energy |= other.energy;
0058 this->volume_id |= other.volume_id;
0059 this->volume_instance_ids |= other.volume_instance_ids;
0060 return *this;
0061 }
0062 };
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 struct StepSelection
0073 {
0074 EnumArray<StepPoint, StepPointSelection> points;
0075
0076 bool event_id{false};
0077 bool parent_id{false};
0078 bool primary_id{false};
0079 bool track_step_count{false};
0080 bool action_id{false};
0081 bool step_length{false};
0082 bool weight{false};
0083 bool particle{false};
0084 bool energy_deposition{false};
0085
0086
0087 static constexpr StepSelection all()
0088 {
0089 return StepSelection{
0090 {StepPointSelection::all(), StepPointSelection::all()},
0091 true,
0092 true,
0093 true,
0094 true,
0095 true,
0096 true,
0097 true,
0098 true};
0099 }
0100
0101
0102 explicit CELER_FUNCTION operator bool() const
0103 {
0104 return points[StepPoint::pre] || points[StepPoint::post] || event_id
0105 || parent_id || track_step_count || action_id || step_length
0106 || weight || particle || energy_deposition;
0107 }
0108
0109
0110 StepSelection& operator|=(StepSelection const& other)
0111 {
0112 for (auto sp : range(StepPoint::size_))
0113 {
0114 points[sp] |= other.points[sp];
0115 }
0116
0117 this->event_id |= other.event_id;
0118 this->parent_id |= other.parent_id;
0119 this->track_step_count |= other.track_step_count;
0120 this->action_id |= other.action_id;
0121 this->step_length |= other.step_length;
0122 this->weight |= other.weight;
0123 this->particle |= other.particle;
0124 this->energy_deposition |= other.energy_deposition;
0125 return *this;
0126 }
0127 };
0128
0129
0130
0131
0132
0133
0134
0135 template<Ownership W, MemSpace M>
0136 struct StepParamsData
0137 {
0138
0139
0140
0141 StepSelection selection;
0142
0143
0144 Collection<DetectorId, W, M, VolumeId> detector;
0145
0146
0147 bool nonzero_energy_deposition{false};
0148
0149
0150 size_type volume_instance_depth{0};
0151
0152
0153
0154
0155 explicit CELER_FUNCTION operator bool() const
0156 {
0157 return static_cast<bool>(selection);
0158 }
0159
0160
0161 template<Ownership W2, MemSpace M2>
0162 StepParamsData& operator=(StepParamsData<W2, M2> const& other)
0163 {
0164 CELER_EXPECT(other);
0165 selection = other.selection;
0166 detector = other.detector;
0167 nonzero_energy_deposition = other.nonzero_energy_deposition;
0168 volume_instance_depth = other.volume_instance_depth;
0169 return *this;
0170 }
0171 };
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183 template<Ownership W, MemSpace M>
0184 struct StepPointStateData
0185 {
0186
0187
0188 template<class T>
0189 using StateItems = celeritas::StateCollection<T, W, M>;
0190 template<class T>
0191 using Items = celeritas::Collection<T, W, M>;
0192 using Energy = units::MevEnergy;
0193
0194
0195 StateItems<real_type> time;
0196
0197
0198 StateItems<Real3> pos;
0199 StateItems<Real3> dir;
0200 StateItems<VolumeId> volume_id;
0201 Items<VolumeInstanceId> volume_instance_ids;
0202
0203
0204 StateItems<Energy> energy;
0205
0206
0207
0208
0209 explicit CELER_FUNCTION operator bool() const { return true; }
0210
0211
0212 template<Ownership W2, MemSpace M2>
0213 StepPointStateData& operator=(StepPointStateData<W2, M2>& other)
0214 {
0215 CELER_EXPECT(other);
0216 time = other.time;
0217 pos = other.pos;
0218 dir = other.dir;
0219 volume_id = other.volume_id;
0220 volume_instance_ids = other.volume_instance_ids;
0221 energy = other.energy;
0222 return *this;
0223 }
0224 };
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 template<Ownership W, MemSpace M>
0240 struct StepStateDataImpl
0241 {
0242
0243
0244 using StepPointData = StepPointStateData<W, M>;
0245 template<class T>
0246 using StateItems = celeritas::StateCollection<T, W, M>;
0247 using Energy = units::MevEnergy;
0248
0249
0250
0251
0252 EnumArray<StepPoint, StepPointData> points;
0253
0254
0255 StateItems<TrackId> track_id;
0256
0257
0258 StateItems<DetectorId> detector;
0259
0260
0261 StateItems<EventId> event_id;
0262 StateItems<TrackId> parent_id;
0263 StateItems<PrimaryId> primary_id;
0264 StateItems<ActionId> action_id;
0265 StateItems<size_type> track_step_count;
0266 StateItems<real_type> step_length;
0267 StateItems<real_type> weight;
0268
0269
0270 StateItems<ParticleId> particle;
0271 StateItems<Energy> energy_deposition;
0272
0273
0274
0275
0276 explicit CELER_FUNCTION operator bool() const
0277 {
0278 auto right_sized = [this](auto const& t) {
0279 return (t.size() == this->size()) || t.empty();
0280 };
0281
0282 return !track_id.empty() && right_sized(detector)
0283 && right_sized(event_id) && right_sized(parent_id)
0284 && right_sized(primary_id) && right_sized(track_step_count)
0285 && right_sized(action_id) && right_sized(step_length)
0286 && right_sized(weight) && right_sized(particle)
0287 && right_sized(energy_deposition);
0288 }
0289
0290
0291 CELER_FUNCTION TrackSlotId::size_type size() const
0292 {
0293 return track_id.size();
0294 }
0295
0296
0297 template<Ownership W2, MemSpace M2>
0298 StepStateDataImpl& operator=(StepStateDataImpl<W2, M2>& other)
0299 {
0300
0301
0302 CELER_EXPECT(other || (M == MemSpace::host && other.size() == 0));
0303
0304 for (auto sp : range(StepPoint::size_))
0305 {
0306 points[sp] = other.points[sp];
0307 }
0308
0309 track_id = other.track_id;
0310 parent_id = other.parent_id;
0311 primary_id = other.primary_id;
0312 detector = other.detector;
0313 event_id = other.event_id;
0314 track_step_count = other.track_step_count;
0315 action_id = other.action_id;
0316 step_length = other.step_length;
0317 weight = other.weight;
0318 particle = other.particle;
0319 energy_deposition = other.energy_deposition;
0320 return *this;
0321 }
0322 };
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336 template<Ownership W, MemSpace M>
0337 struct StepStateData
0338 {
0339
0340
0341 using StepDataImpl = StepStateDataImpl<W, M>;
0342 template<class T>
0343 using StateItems = celeritas::StateCollection<T, W, M>;
0344
0345
0346
0347
0348 StepDataImpl data;
0349
0350
0351 StepDataImpl scratch;
0352
0353
0354 StateItems<size_type> valid_id;
0355
0356
0357 size_type volume_instance_depth{0};
0358
0359
0360 StreamId stream_id;
0361
0362
0363
0364
0365 explicit CELER_FUNCTION operator bool() const
0366 {
0367 auto right_sized = [this](auto const& t) {
0368 return (t.size() == this->size())
0369 || (t.size() == 0 && M == MemSpace::host);
0370 };
0371
0372 return data.size() > 0 && right_sized(scratch) && right_sized(valid_id)
0373 && stream_id;
0374 }
0375
0376
0377 CELER_FUNCTION TrackSlotId::size_type size() const { return data.size(); }
0378
0379
0380 template<Ownership W2, MemSpace M2>
0381 StepStateData& operator=(StepStateData<W2, M2>& other)
0382 {
0383 CELER_EXPECT(other);
0384
0385 data = other.data;
0386 scratch = other.scratch;
0387 valid_id = other.valid_id;
0388 volume_instance_depth = other.volume_instance_depth;
0389 stream_id = other.stream_id;
0390 return *this;
0391 }
0392 };
0393
0394
0395
0396
0397
0398
0399
0400 template<MemSpace M>
0401 inline void resize(StepPointStateData<Ownership::value, M>* state,
0402 StepPointSelection selection,
0403 HostCRef<StepParamsData> const& params,
0404 size_type size)
0405 {
0406 CELER_EXPECT(size > 0);
0407 #define SD_RESIZE_IF_SELECTED(ATTR) \
0408 do \
0409 { \
0410 if (selection.ATTR) \
0411 { \
0412 resize(&state->ATTR, size); \
0413 } \
0414 } while (0)
0415
0416 SD_RESIZE_IF_SELECTED(time);
0417 SD_RESIZE_IF_SELECTED(pos);
0418 SD_RESIZE_IF_SELECTED(dir);
0419 SD_RESIZE_IF_SELECTED(volume_id);
0420 if (selection.volume_instance_ids)
0421 {
0422 size_type const vi_depth = params.volume_instance_depth;
0423 CELER_ASSERT(vi_depth > 0);
0424 resize(&state->volume_instance_ids, size * vi_depth);
0425 }
0426 SD_RESIZE_IF_SELECTED(energy);
0427
0428 #undef SD_RESIZE_IF_SELECTED
0429 }
0430
0431
0432
0433
0434
0435 template<MemSpace M>
0436 inline void resize(StepStateDataImpl<Ownership::value, M>* state,
0437 HostCRef<StepParamsData> const& params,
0438 size_type size)
0439 {
0440 CELER_EXPECT(state->size() == 0);
0441 CELER_EXPECT(size > 0);
0442
0443 for (auto sp : range(StepPoint::size_))
0444 {
0445 resize(&state->points[sp], params.selection.points[sp], params, size);
0446 }
0447
0448 #define SD_RESIZE_IF_SELECTED(ATTR) \
0449 do \
0450 { \
0451 if (params.selection.ATTR) \
0452 { \
0453 resize(&state->ATTR, size); \
0454 } \
0455 } while (0)
0456
0457 resize(&state->track_id, size);
0458 if (!params.detector.empty())
0459 {
0460 resize(&state->detector, size);
0461 }
0462
0463 SD_RESIZE_IF_SELECTED(event_id);
0464 SD_RESIZE_IF_SELECTED(parent_id);
0465 SD_RESIZE_IF_SELECTED(track_step_count);
0466 SD_RESIZE_IF_SELECTED(step_length);
0467 SD_RESIZE_IF_SELECTED(weight);
0468 SD_RESIZE_IF_SELECTED(action_id);
0469 SD_RESIZE_IF_SELECTED(particle);
0470 SD_RESIZE_IF_SELECTED(energy_deposition);
0471 }
0472
0473
0474
0475
0476
0477 template<MemSpace M>
0478 inline void resize(StepStateData<Ownership::value, M>* state,
0479 HostCRef<StepParamsData> const& params,
0480 StreamId stream_id,
0481 size_type size)
0482 {
0483 CELER_EXPECT(state->size() == 0);
0484 CELER_EXPECT(size > 0);
0485
0486 state->volume_instance_depth = params.volume_instance_depth;
0487 state->stream_id = stream_id;
0488
0489 resize(&state->data, params, size);
0490
0491 if constexpr (M == MemSpace::device)
0492 {
0493
0494 resize(&state->scratch, params, size);
0495 resize(&state->valid_id, size);
0496 }
0497 }
0498
0499
0500 }