Skip to content

Commit 71683da

Browse files
Mark a track's survival more explicit
Adds a lambda function survive() which pushes the track back into the active queue.
1 parent f8d6af1 commit 71683da

File tree

2 files changed

+36
-25
lines changed

2 files changed

+36
-25
lines changed

examples/Example19/electrons.cu

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,15 @@ static __device__ __forceinline__ void TransportElectrons(Track *electrons, cons
4747
for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < activeSize; i += blockDim.x * gridDim.x) {
4848
const int globalSlot = (*active)[i];
4949
Track &currentTrack = electrons[globalSlot];
50-
auto volume = currentTrack.navState.Top();
51-
int volumeID = volume->id();
50+
const auto volume = currentTrack.navState.Top();
51+
const int volumeID = volume->id();
5252
// the MCC vector is indexed by the logical volume id
53-
int lvolID = volume->GetLogicalVolume()->id();
54-
int theMCIndex = MCIndex[lvolID];
53+
const int lvolID = volume->GetLogicalVolume()->id();
54+
const int theMCIndex = MCIndex[lvolID];
55+
56+
auto survive = [&](bool push = true) {
57+
if (push) activeQueue->push_back(globalSlot);
58+
};
5559

5660
// Signal that this globalSlot doesn't undergo an interaction (yet)
5761
soaData.nextInteraction[i] = -1;
@@ -252,21 +256,21 @@ static __device__ __forceinline__ void TransportElectrons(Track *electrons, cons
252256

253257
// Kill the particle if it left the world.
254258
if (nextState.Top() != nullptr) {
255-
activeQueue->push_back(globalSlot);
256259
BVHNavigator::RelocateToNextVolume(currentTrack.pos, currentTrack.dir, nextState);
257260

258261
// Move to the next boundary.
259262
currentTrack.navState = nextState;
263+
survive();
260264
}
261265
continue;
262266
} else if (!propagated || restrictedPhysicalStepLength) {
263267
// Did not yet reach the interaction point due to error in the magnetic
264268
// field propagation. Try again next time.
265-
activeQueue->push_back(globalSlot);
269+
survive();
266270
continue;
267271
} else if (winnerProcessIndex < 0) {
268272
// No discrete process, move on.
269-
activeQueue->push_back(globalSlot);
273+
survive();
270274
continue;
271275
}
272276

@@ -277,11 +281,13 @@ static __device__ __forceinline__ void TransportElectrons(Track *electrons, cons
277281
// Check if a delta interaction happens instead of the real discrete process.
278282
if (G4HepEmElectronManager::CheckDelta(&g4HepEmData, theTrack, currentTrack.Uniform())) {
279283
// A delta interaction happened, move on.
280-
activeQueue->push_back(globalSlot);
284+
survive();
281285
continue;
282286
}
283287

284288
soaData.nextInteraction[i] = winnerProcessIndex;
289+
290+
survive(false);
285291
}
286292
}
287293

@@ -307,11 +313,13 @@ __device__ void ElectronInteraction(int const globalSlot, SOAData const & /*soaD
307313
GlobalScoring *globalScoring, ScoringPerVolume *scoringPerVolume)
308314
{
309315
Track &currentTrack = particles[globalSlot];
310-
auto volume = currentTrack.navState.Top();
316+
const auto volume = currentTrack.navState.Top();
311317
// the MCC vector is indexed by the logical volume id
312318
const int lvolID = volume->GetLogicalVolume()->id();
313319
const int theMCIndex = MCIndex[lvolID];
314320

321+
auto survive = [&] { activeQueue->push_back(globalSlot); };
322+
315323
const double energy = currentTrack.energy;
316324
const double theElCut = g4HepEmData.fTheMatCutData->fMatCutData[theMCIndex].fSecElProdCutE;
317325

@@ -337,8 +345,7 @@ __device__ void ElectronInteraction(int const globalSlot, SOAData const & /*soaD
337345

338346
currentTrack.energy = energy - deltaEkin;
339347
currentTrack.dir.Set(dirPrimary[0], dirPrimary[1], dirPrimary[2]);
340-
// The current track continues to live.
341-
activeQueue->push_back(globalSlot);
348+
survive();
342349
} else if constexpr (ProcessIndex == 1) {
343350
// Invoke model for Bremsstrahlung: either SB- or Rel-Brem.
344351
double logEnergy = std::log(energy);
@@ -362,8 +369,7 @@ __device__ void ElectronInteraction(int const globalSlot, SOAData const & /*soaD
362369

363370
currentTrack.energy = energy - deltaEkin;
364371
currentTrack.dir.Set(dirPrimary[0], dirPrimary[1], dirPrimary[2]);
365-
// The current track continues to live.
366-
activeQueue->push_back(globalSlot);
372+
survive();
367373
} else if constexpr (ProcessIndex == 2) {
368374
// Invoke annihilation (in-flight) for e+
369375
double dirPrimary[] = {currentTrack.dir.x(), currentTrack.dir.y(), currentTrack.dir.z()};

examples/Example19/gammas.cu

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,15 @@ __global__ void TransportGammas(Track *gammas, const adept::MParray *active, Sec
3232
for (int i = blockIdx.x * blockDim.x + threadIdx.x; i < activeSize; i += blockDim.x * gridDim.x) {
3333
const int slot = (*active)[i];
3434
Track &currentTrack = gammas[slot];
35-
auto volume = currentTrack.navState.Top();
36-
int volumeID = volume->id();
35+
const auto volume = currentTrack.navState.Top();
36+
const int volumeID = volume->id();
3737
// the MCC vector is indexed by the logical volume id
38-
int lvolID = volume->GetLogicalVolume()->id();
39-
int theMCIndex = MCIndex[lvolID];
38+
const int lvolID = volume->GetLogicalVolume()->id();
39+
const int theMCIndex = MCIndex[lvolID];
40+
41+
auto survive = [&](bool push = true) {
42+
if (push) activeQueue->push_back(slot);
43+
};
4044

4145
// Signal that this slot doesn't undergo an interaction (yet)
4246
soaData.nextInteraction[i] = -1;
@@ -95,16 +99,16 @@ __global__ void TransportGammas(Track *gammas, const adept::MParray *active, Sec
9599

96100
// Kill the particle if it left the world.
97101
if (nextState.Top() != nullptr) {
98-
activeQueue->push_back(slot);
99102
BVHNavigator::RelocateToNextVolume(currentTrack.pos, currentTrack.dir, nextState);
100103

101104
// Move to the next boundary.
102105
currentTrack.navState = nextState;
106+
survive();
103107
}
104108
continue;
105109
} else if (winnerProcessIndex < 0) {
106110
// No discrete process, move on.
107-
activeQueue->push_back(slot);
111+
survive();
108112
continue;
109113
}
110114

@@ -114,6 +118,7 @@ __global__ void TransportGammas(Track *gammas, const adept::MParray *active, Sec
114118

115119
soaData.nextInteraction[i] = winnerProcessIndex;
116120
soaData.gamma_PEmxSec[i] = gammaTrack.GetPEmxSec();
121+
survive(false);
117122
}
118123
}
119124

@@ -123,20 +128,22 @@ __device__ void GammaInteraction(int const globalSlot, SOAData const &soaData, i
123128
ScoringPerVolume *scoringPerVolume)
124129
{
125130
Track &currentTrack = particles[globalSlot];
126-
auto volume = currentTrack.navState.Top();
131+
const auto volume = currentTrack.navState.Top();
127132
const int volumeID = volume->id();
128133
// the MCC vector is indexed by the logical volume id
129134
const int lvolID = volume->GetLogicalVolume()->id();
130135
const int theMCIndex = MCIndex[lvolID];
131136
const auto energy = currentTrack.energy;
132137

138+
auto survive = [&] { activeQueue->push_back(globalSlot); };
139+
133140
RanluxppDouble newRNG{currentTrack.rngState.Branch()};
134141
G4HepEmRandomEngine rnge{&currentTrack.rngState};
135142

136143
if constexpr (ProcessIndex == 0) {
137144
// Invoke gamma conversion to e-/e+ pairs, if the energy is above the threshold.
138145
if (energy < 2 * copcore::units::kElectronMassC2) {
139-
activeQueue->push_back(globalSlot);
146+
survive();
140147
return;
141148
}
142149

@@ -171,7 +178,7 @@ __device__ void GammaInteraction(int const globalSlot, SOAData const &soaData, i
171178
// Invoke Compton scattering of gamma.
172179
constexpr double LowEnergyThreshold = 100 * copcore::units::eV;
173180
if (energy < LowEnergyThreshold) {
174-
activeQueue->push_back(globalSlot);
181+
survive();
175182
return;
176183
}
177184
const double origDirPrimary[] = {currentTrack.dir.x(), currentTrack.dir.y(), currentTrack.dir.z()};
@@ -200,9 +207,7 @@ __device__ void GammaInteraction(int const globalSlot, SOAData const &soaData, i
200207
if (newEnergyGamma > LowEnergyThreshold) {
201208
currentTrack.energy = newEnergyGamma;
202209
currentTrack.dir = newDirGamma;
203-
204-
// The current track continues to live.
205-
activeQueue->push_back(globalSlot);
210+
survive();
206211
} else {
207212
atomicAdd(&globalScoring->energyDeposit, newEnergyGamma);
208213
atomicAdd(&scoringPerVolume->energyDeposit[volumeID], newEnergyGamma);

0 commit comments

Comments
 (0)