File indexing completed on 2025-01-30 10:09:33
0001
0002
0003
0004
0005
0006
0007
0008 #pragma once
0009
0010 #include <VecGeom/base/Config.h>
0011 #include <VecGeom/base/Cuda.h>
0012 #include <VecGeom/base/Version.h>
0013 #include <VecGeom/navigation/NavStateFwd.h>
0014 #include <VecGeom/navigation/NavigationState.h>
0015 #include <VecGeom/volumes/LogicalVolume.h>
0016 #include <VecGeom/volumes/PlacedVolume.h>
0017
0018 #include "corecel/Macros.hh"
0019 #include "corecel/math/Algorithms.hh"
0020 #include "corecel/math/ArrayUtils.hh"
0021 #include "corecel/math/SoftEqual.hh"
0022 #include "geocel/Types.hh"
0023
0024 #include "VecgeomData.hh"
0025
0026 #include "detail/VecgeomCompatibility.hh"
0027
0028 #if VECGEOM_VERSION < 0x020000
0029 # include "detail/BVHNavigator.hh"
0030 #elif defined(VECGEOM_USE_SURF)
0031 # include "detail/SurfNavigator.hh"
0032 #else
0033 # include <VecGeom/navigation/BVHNavigator.h>
0034 #endif
0035
0036 namespace celeritas
0037 {
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 class VecgeomTrackView
0053 {
0054 public:
0055
0056
0057 using Initializer_t = GeoTrackInitializer;
0058 using ParamsRef = NativeCRef<VecgeomParamsData>;
0059 using StateRef = NativeRef<VecgeomStateData>;
0060 #if VECGEOM_VERSION < 0x020000
0061 using Navigator = celeritas::detail::BVHNavigator;
0062 #elif defined(VECGEOM_USE_SURF)
0063 using Navigator = celeritas::detail::SurfNavigator;
0064 #else
0065 using Navigator = vecgeom::BVHNavigator;
0066 #endif
0067
0068
0069
0070 struct DetailedInitializer
0071 {
0072 VecgeomTrackView const& other;
0073 Real3 const& dir;
0074 };
0075
0076 public:
0077
0078 inline CELER_FUNCTION VecgeomTrackView(ParamsRef const& data,
0079 StateRef const& stateview,
0080 TrackSlotId tid);
0081
0082
0083 inline CELER_FUNCTION VecgeomTrackView&
0084 operator=(Initializer_t const& init);
0085
0086 inline CELER_FUNCTION VecgeomTrackView&
0087 operator=(DetailedInitializer const& init);
0088
0089
0090
0091
0092 static CELER_CONSTEXPR_FUNCTION real_type extra_push() { return 1e-13; }
0093
0094
0095
0096
0097
0098 CELER_FORCEINLINE_FUNCTION Real3 const& pos() const { return pos_; }
0099 CELER_FORCEINLINE_FUNCTION Real3 const& dir() const { return dir_; }
0100
0101
0102
0103 CELER_FORCEINLINE_FUNCTION VolumeId volume_id() const;
0104 CELER_FORCEINLINE_FUNCTION int volume_physid() const;
0105
0106
0107
0108 CELER_FUNCTION SurfaceId surface_id() const { return {}; }
0109
0110
0111
0112 CELER_FORCEINLINE_FUNCTION bool is_outside() const;
0113
0114 CELER_FORCEINLINE_FUNCTION bool is_on_boundary() const;
0115
0116 CELER_FORCEINLINE_FUNCTION bool failed() const { return false; }
0117
0118
0119
0120
0121 inline CELER_FUNCTION Propagation find_next_step();
0122
0123
0124 inline CELER_FUNCTION Propagation find_next_step(real_type max_step);
0125
0126
0127 inline CELER_FUNCTION real_type find_safety();
0128
0129
0130 inline CELER_FUNCTION real_type find_safety(real_type max_step);
0131
0132
0133 inline CELER_FUNCTION void move_to_boundary();
0134
0135
0136 inline CELER_FUNCTION void move_internal(real_type step);
0137
0138
0139 inline CELER_FUNCTION void move_internal(Real3 const& pos);
0140
0141
0142 inline CELER_FUNCTION void cross_boundary();
0143
0144
0145 inline CELER_FUNCTION void set_dir(Real3 const& newdir);
0146
0147 private:
0148
0149
0150 using Volume = vecgeom::LogicalVolume;
0151 using NavState = vecgeom::NavigationState;
0152
0153
0154
0155
0156 ParamsRef const& params_;
0157
0158
0159
0160 NavState& vgstate_;
0161 NavState& vgnext_;
0162 Real3& pos_;
0163 Real3& dir_;
0164
0165
0166
0167 real_type next_step_{0};
0168
0169
0170
0171
0172 inline CELER_FUNCTION bool has_next_step() const;
0173
0174
0175 inline CELER_FUNCTION bool is_next_boundary() const;
0176
0177
0178 inline CELER_FUNCTION Volume const& volume() const;
0179 };
0180
0181
0182
0183
0184
0185
0186
0187 CELER_FUNCTION
0188 VecgeomTrackView::VecgeomTrackView(ParamsRef const& params,
0189 StateRef const& states,
0190 TrackSlotId tid)
0191 : params_(params)
0192 , vgstate_(states.vgstate.at(params_.max_depth, tid))
0193 , vgnext_(states.vgnext.at(params_.max_depth, tid))
0194 , pos_(states.pos[tid])
0195 , dir_(states.dir[tid])
0196 {
0197 }
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207 CELER_FUNCTION VecgeomTrackView&
0208 VecgeomTrackView::operator=(Initializer_t const& init)
0209 {
0210 CELER_EXPECT(is_soft_unit_vector(init.dir));
0211
0212
0213 pos_ = init.pos;
0214 dir_ = init.dir;
0215
0216
0217 vgstate_.Clear();
0218 vecgeom::VPlacedVolume const* worldvol = params_.world_volume;
0219 bool const contains_point = true;
0220
0221
0222 Navigator::LocatePointIn(
0223 worldvol, detail::to_vector(pos_), vgstate_, contains_point);
0224
0225 return *this;
0226 }
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236 CELER_FUNCTION
0237 VecgeomTrackView& VecgeomTrackView::operator=(DetailedInitializer const& init)
0238 {
0239 CELER_EXPECT(is_soft_unit_vector(init.dir));
0240
0241 if (this != &init.other)
0242 {
0243
0244 init.other.vgstate_.CopyTo(&vgstate_);
0245 pos_ = init.other.pos_;
0246 }
0247
0248
0249 dir_ = init.dir;
0250
0251 CELER_ENSURE(!this->has_next_step());
0252 return *this;
0253 }
0254
0255
0256
0257
0258
0259 CELER_FUNCTION VolumeId VecgeomTrackView::volume_id() const
0260 {
0261 CELER_EXPECT(!this->is_outside());
0262 return VolumeId{this->volume().id()};
0263 }
0264
0265
0266
0267
0268
0269 CELER_FUNCTION int VecgeomTrackView::volume_physid() const
0270 {
0271 CELER_EXPECT(!this->is_outside());
0272 return this->vgstate_.Top()->id();
0273 }
0274
0275
0276
0277
0278
0279 CELER_FUNCTION bool VecgeomTrackView::is_outside() const
0280 {
0281 return vgstate_.IsOutside();
0282 }
0283
0284
0285
0286
0287
0288 CELER_FUNCTION bool VecgeomTrackView::is_on_boundary() const
0289 {
0290 return vgstate_.IsOnBoundary();
0291 }
0292
0293
0294
0295
0296
0297
0298
0299
0300 CELER_FUNCTION Propagation VecgeomTrackView::find_next_step()
0301 {
0302 if (this->is_outside())
0303 {
0304
0305 auto* pplvol = params_.world_volume;
0306 next_step_ = pplvol->DistanceToIn(detail::to_vector(pos_),
0307 detail::to_vector(dir_),
0308 vecgeom::kInfLength);
0309
0310 vgnext_.Clear();
0311 vgnext_.Push(pplvol);
0312 vgnext_.SetBoundaryState(true);
0313 next_step_ = max(next_step_, this->extra_push());
0314
0315 Propagation result;
0316 result.distance = next_step_;
0317 result.boundary = next_step_ < vecgeom::kInfLength;
0318 return result;
0319 }
0320
0321 return this->find_next_step(vecgeom::kInfLength);
0322 }
0323
0324
0325
0326
0327
0328 CELER_FUNCTION Propagation VecgeomTrackView::find_next_step(real_type max_step)
0329 {
0330 CELER_EXPECT(!this->is_outside());
0331 CELER_EXPECT(max_step > 0);
0332
0333
0334 next_step_ = Navigator::ComputeStepAndNextVolume(detail::to_vector(pos_),
0335 detail::to_vector(dir_),
0336 max_step,
0337 vgstate_,
0338 vgnext_);
0339 next_step_ = max(next_step_, this->extra_push());
0340
0341 if (!this->is_next_boundary())
0342 {
0343
0344
0345
0346 CELER_ASSERT(soft_equal(next_step_, max_step));
0347 next_step_ = max_step;
0348 }
0349
0350 Propagation result;
0351 result.distance = next_step_;
0352 result.boundary = this->is_next_boundary();
0353
0354 CELER_ENSURE(this->has_next_step());
0355 CELER_ENSURE(result.distance > 0);
0356 CELER_ENSURE(result.distance <= max(max_step, this->extra_push()));
0357 CELER_ENSURE(result.boundary || result.distance == max_step
0358 || max_step < this->extra_push());
0359 return result;
0360 }
0361
0362
0363
0364
0365
0366 CELER_FUNCTION real_type VecgeomTrackView::find_safety()
0367 {
0368 return this->find_safety(vecgeom::kInfLength);
0369 }
0370
0371
0372
0373
0374
0375
0376
0377
0378 CELER_FUNCTION real_type VecgeomTrackView::find_safety(real_type max_radius)
0379 {
0380 CELER_EXPECT(!this->is_outside());
0381 CELER_EXPECT(!this->is_on_boundary());
0382 CELER_EXPECT(max_radius > 0);
0383
0384 real_type safety
0385 = Navigator::ComputeSafety(detail::to_vector(this->pos()), vgstate_);
0386 safety = min<real_type>(safety, max_radius);
0387
0388
0389
0390 return max<real_type>(safety, 0);
0391 }
0392
0393
0394
0395
0396
0397 CELER_FUNCTION void VecgeomTrackView::move_to_boundary()
0398 {
0399 CELER_EXPECT(this->has_next_step());
0400 CELER_EXPECT(this->is_next_boundary());
0401
0402
0403 axpy(next_step_, dir_, &pos_);
0404 next_step_ = 0;
0405 vgstate_.SetBoundaryState(true);
0406
0407 CELER_ENSURE(this->is_on_boundary());
0408 }
0409
0410
0411
0412
0413
0414
0415
0416 CELER_FUNCTION void VecgeomTrackView::cross_boundary()
0417 {
0418 CELER_EXPECT(this->is_on_boundary());
0419 CELER_EXPECT(this->is_next_boundary());
0420
0421
0422 if (vgnext_.Top() != nullptr)
0423 {
0424
0425 auto temp_pos = detail::to_vector(this->pos_);
0426 Navigator::RelocateToNextVolume(
0427 temp_pos, detail::to_vector(this->dir_), vgnext_);
0428 }
0429
0430 vgstate_ = vgnext_;
0431
0432 CELER_ENSURE(this->is_on_boundary());
0433 }
0434
0435
0436
0437
0438
0439
0440
0441
0442 CELER_FUNCTION void VecgeomTrackView::move_internal(real_type dist)
0443 {
0444 CELER_EXPECT(this->has_next_step());
0445 CELER_EXPECT(dist > 0 && dist <= next_step_);
0446 CELER_EXPECT(dist != next_step_ || !this->is_next_boundary());
0447
0448
0449 axpy(dist, dir_, &pos_);
0450 next_step_ -= dist;
0451 vgstate_.SetBoundaryState(false);
0452
0453 CELER_ENSURE(!this->is_on_boundary());
0454 }
0455
0456
0457
0458
0459
0460
0461
0462
0463 CELER_FUNCTION void VecgeomTrackView::move_internal(Real3 const& pos)
0464 {
0465 pos_ = pos;
0466 next_step_ = 0;
0467 vgstate_.SetBoundaryState(false);
0468
0469 CELER_ENSURE(!this->is_on_boundary());
0470 }
0471
0472
0473
0474
0475
0476
0477
0478
0479 CELER_FUNCTION void VecgeomTrackView::set_dir(Real3 const& newdir)
0480 {
0481 CELER_EXPECT(is_soft_unit_vector(newdir));
0482 dir_ = newdir;
0483 next_step_ = 0;
0484 }
0485
0486
0487
0488
0489
0490
0491
0492 CELER_FUNCTION bool VecgeomTrackView::has_next_step() const
0493 {
0494 return next_step_ != 0;
0495 }
0496
0497
0498
0499
0500
0501 CELER_FUNCTION bool VecgeomTrackView::is_next_boundary() const
0502 {
0503 CELER_EXPECT(this->has_next_step() || this->is_on_boundary());
0504 return vgnext_.IsOnBoundary();
0505 }
0506
0507
0508
0509
0510
0511 CELER_FUNCTION auto VecgeomTrackView::volume() const -> Volume const&
0512 {
0513 vecgeom::VPlacedVolume const* physvol_ptr = vgstate_.Top();
0514 CELER_ENSURE(physvol_ptr);
0515 return *physvol_ptr->GetLogicalVolume();
0516 }
0517
0518
0519 }