221{
223
224 const G4double physStepLimit = currentMinimumStep;
225
226 switch(fType)
227 {
229
234 if(physStepLimit > kGeomMin)
235 {
238 if(pdgMass > CLHEP::GeV)
239 {
240 ekinForSelection *= proton_mass_c2 / pdgMass;
241 }
242
243 if(ekinForSelection >= kLowestKinEnergy)
244 {
246 fModelManager->
SelectModel(ekinForSelection, couple->GetIndex()));
247 if(mscModel == nullptr)
248 {
249 G4Exception(
"G4TransportationWithMsc::AlongStepGPIL",
"em0052",
251 }
252 if(!mscModel->
IsActive(ekinForSelection))
253 {
254 mscModel = nullptr;
255 }
256 }
257 }
258
259
260
261 if(mscModel != nullptr)
262 {
264
265
266 const G4Track* currentTrackPtr = &track;
267
268 G4double currentSafety = proposedSafety;
270
271 G4double stepLimitLeft = physStepLimit;
272 G4double totalGeometryStepLength = 0, totalTruePathLength = 0;
273 G4bool firstStep =
true, continueStepping = fMultipleSteps;
274
275 do
276 {
277 G4double gPathLength = stepLimitLeft;
280 G4bool mscLimitsStep = (tPathLength < stepLimitLeft);
281 if(!fMultipleSteps && mscLimitsStep)
282 {
283
285 }
286
287 if(!firstStep)
288 {
289
292 }
293
297 *currentTrackPtr, previousStepSize, gPathLength, currentSafety,
298 &transportSelection);
299 if(geometryStepLength < gPathLength)
300 {
301
303 continueStepping = false;
304 }
306 {
307
308
309 continueStepping = false;
310 }
311
312 if(firstStep)
313 {
314 proposedSafety = currentSafety;
315 }
316 totalGeometryStepLength += geometryStepLength;
317
318
320 mscModel->
GetRange(particleDefinition, currentEnergy, couple);
321
323
324
325 tPathLength = std::min(tPathLength, stepLimitLeft);
326
327 totalTruePathLength += tPathLength;
329 {
330
331
332 continueStepping = false;
333 }
334 else if(tPathLength >= range)
335 {
336
337 continueStepping = false;
338 }
339 else
340 {
341 stepLimitLeft -= tPathLength;
342 }
343
344
345 if(tPathLength < range && tPathLength > kGeomMin)
346 {
347 static constexpr G4double minSafety = 1.20 * CLHEP::nm;
348 static constexpr G4double sFact = 0.99;
349
350
351
352
354
357
360
362 if(r2 > kMinDisplacement2)
363 {
364 G4bool positionChanged =
true;
368
369
370 if(postSafety > 0.0 && dispR <= postSafety)
371 {
373
374
375 }
376 else
377 {
378
379 if(dispR < postSafety)
380 {
382
383
384 }
385 else if(postSafety > kGeomMin)
386 {
388
389
390 }
391 else
392 {
393 positionChanged = false;
394 }
395 }
396 if(positionChanged)
397 {
399 }
400 }
401 }
402
403 if(continueStepping)
404 {
405
407 {
408 currentSafety = 0;
409 }
410 else
411 {
413 }
414
415
416 currentEnergy = mscModel->
GetEnergy(particleDefinition,
417 range - tPathLength, couple);
418
419
420 currentTrackPtr = fSubStepTrack;
421
426
430 subPreStepPoint.
SetSafety(currentSafety);
432 }
433 firstStep = false;
434 } while(continueStepping);
435
436
437
438
439
440 if(currentEnergy != ekin)
441 {
442
443
444
446
447
448
449 (void) mscModel->
GetRange(particleDefinition, ekin, couple);
450 }
451
453
454 return totalGeometryStepLength;
455 }
456 }
457 }
458
459
461 track, previousStepSize, currentMinimumStep, proposedSafety, selection);
462}
@ NotCandidateForSelection
void SetMomentumDirection(const G4ThreeVector &aDirection)
void SetKineticEnergy(G4double aEnergy)
G4VEmModel * SelectModel(G4double energy, std::size_t index)
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
const G4ThreeVector * GetMomentumDirection() const
void ProposeMomentumDirection(G4double Px, G4double Py, G4double Pz)
G4double GetPDGMass() const
G4double ComputeSafety(const G4ThreeVector &pGlobalPoint, G4double maxRadius=DBL_MAX)
void ReLocateWithinVolume(const G4ThreeVector &pGlobalPoint)
void SetSafety(const G4double aValue)
void SetStepStatus(const G4StepStatus aValue)
void SetMaterialCutsCouple(const G4MaterialCutsCouple *)
void SetPosition(const G4ThreeVector &aValue)
G4StepPoint * GetPreStepPoint() const
void SetPosition(const G4ThreeVector &aValue)
const G4ParticleDefinition * GetParticleDefinition() const
G4double GetKineticEnergy() const
const G4MaterialCutsCouple * GetMaterialCutsCouple() const
G4double AlongStepGetPhysicalInteractionLength(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double ¤tSafety, G4GPILSelection *selection)
G4double fTransportEndKineticEnergy
G4ThreeVector fTransportEndPosition
G4double fEndPointDistance
G4Navigator * fLinearNavigator
G4ThreeVector fTransportEndMomentumDir
G4SafetyHelper * fpSafetyHelper
void SetCurrentCouple(const G4MaterialCutsCouple *)
G4bool IsActive(G4double kinEnergy) const
virtual G4double ComputeTruePathLengthLimit(const G4Track &track, G4double &stepLimit)=0
virtual G4double ComputeTrueStepLength(G4double geomPathLength)=0
G4double GetEnergy(const G4ParticleDefinition *part, G4double range, const G4MaterialCutsCouple *couple)
G4double GetRange(const G4ParticleDefinition *part, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
virtual G4ThreeVector & SampleScattering(const G4ThreeVector &, G4double safety)=0
void ProposeTrueStepLength(G4double truePathLength)