Bug Summary

File:scratch/gluex/scan-build-work/hdgeant4/src/G4fixes/G4SteppingManager2.cc
Location:line 384, column 9
Description:Called C++ object pointer is null

Annotated Source Code

1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26//
27// $Id: G4SteppingManager2.cc 106991 2017-10-31 10:13:42Z gcosmo $
28//
29//---------------------------------------------------------------
30//
31// G4SteppingManager2.cc
32//
33// Description:
34// This class represents the manager who steers to move the give
35// particle from the TrackingManger by one Step.
36//
37// Contact:
38// Questions and comments to this code should be sent to
39// Katsuya Amako (e-mail: Katsuya.Amako@kek.jp)
40// Takashi Sasaki (e-mail: Takashi.Sasaki@kek.jp)
41//
42//---------------------------------------------------------------
43
44//#define debug
45
46#include "G4UImanager.hh"
47#include "G4ForceCondition.hh"
48#include "G4GPILSelection.hh"
49#include "G4SteppingControl.hh"
50#include "G4TransportationManager.hh"
51#include "G4SteppingManager.hh"
52#include "G4LossTableManager.hh"
53#include "G4ParticleTable.hh"
54
55/////////////////////////////////////////////////
56void G4SteppingManager::GetProcessNumber()
57/////////////////////////////////////////////////
58{
59#ifdef debug
60 G4cout(*G4cout_p)<<"G4SteppingManager::GetProcessNumber: is called track="
61 <<fTrack<<G4endlstd::endl;
62#endif
63
64 G4ProcessManager* pm= fTrack->GetDefinition()->GetProcessManager();
65 if(!pm)
66 {
67 G4cerr(*G4cerr_p) << "ERROR - G4SteppingManager::GetProcessNumber()" << G4endlstd::endl
68 << " ProcessManager is NULL for particle = "
69 << fTrack->GetDefinition()->GetParticleName() << ", PDG_code = "
70 << fTrack->GetDefinition()->GetPDGEncoding() << G4endlstd::endl;
71 G4Exception("G4SteppingManager::GetProcessNumber()", "Tracking0011",
72 FatalException, "Process Manager is not found.");
73 return;
74 }
75
76// AtRestDoits
77 MAXofAtRestLoops = pm->GetAtRestProcessVector()->entries();
78 fAtRestDoItVector = pm->GetAtRestProcessVector(typeDoIt);
79 fAtRestGetPhysIntVector = pm->GetAtRestProcessVector(typeGPIL);
80#ifdef debug
81 G4cout(*G4cout_p) << "G4SteppingManager::GetProcessNumber: #ofAtRest="
82 << MAXofAtRestLoops << G4endlstd::endl;
83#endif
84
85// AlongStepDoits
86 MAXofAlongStepLoops = pm->GetAlongStepProcessVector()->entries();
87 fAlongStepDoItVector = pm->GetAlongStepProcessVector(typeDoIt);
88 fAlongStepGetPhysIntVector = pm->GetAlongStepProcessVector(typeGPIL);
89#ifdef debug
90 G4cout(*G4cout_p) << "G4SteppingManager::GetProcessNumber:#ofAlongStp="
91 << MAXofAlongStepLoops << G4endlstd::endl;
92#endif
93
94// PostStepDoits
95 MAXofPostStepLoops = pm->GetPostStepProcessVector()->entries();
96 fPostStepDoItVector = pm->GetPostStepProcessVector(typeDoIt);
97 fPostStepGetPhysIntVector = pm->GetPostStepProcessVector(typeGPIL);
98#ifdef debug
99 G4cout(*G4cout_p) << "G4SteppingManager::GetProcessNumber: #ofPostStep="
100 << MAXofPostStepLoops << G4endlstd::endl;
101#endif
102
103 if (SizeOfSelectedDoItVector<MAXofAtRestLoops ||
104 SizeOfSelectedDoItVector<MAXofAlongStepLoops ||
105 SizeOfSelectedDoItVector<MAXofPostStepLoops )
106 {
107 G4cerr(*G4cerr_p) << "ERROR - G4SteppingManager::GetProcessNumber()" << G4endlstd::endl
108 << " SizeOfSelectedDoItVector= " << SizeOfSelectedDoItVector
109 << " ; is smaller then one of MAXofAtRestLoops= "
110 << MAXofAtRestLoops << G4endlstd::endl
111 << " or MAXofAlongStepLoops= " << MAXofAlongStepLoops
112 << " or MAXofPostStepLoops= " << MAXofPostStepLoops << G4endlstd::endl;
113 G4Exception("G4SteppingManager::GetProcessNumber()",
114 "Tracking0012", FatalException,
115 "The array size is smaller than the actual No of processes.");
116 }
117}
118
119
120// ************************************************************************
121//
122// Private Member Functions
123//
124// ************************************************************************
125
126
127/////////////////////////////////////////////////////////
128 void G4SteppingManager::DefinePhysicalStepLength()
129/////////////////////////////////////////////////////////
130{
131
132// ReSet the counter etc.
133 PhysicalStep = DBL_MAXstd::numeric_limits<double>::max(); // Initialize by a huge number
134 physIntLength = DBL_MAXstd::numeric_limits<double>::max(); // Initialize by a huge number
135#ifdef G4VERBOSE1
136 // !!!!! Verbose
137 if(verboseLevel>0) fVerbose->DPSLStarted();
138#endif
139
140// Obtain the user defined maximum allowed Step in the volume
141// 1997.12.13 adds argument for GetMaxAllowedStep by K.Kurashige
142// 2004.01.20 This block will be removed by Geant4 7.0
143// G4UserLimits* ul= fCurrentVolume->GetLogicalVolume()->GetUserLimits();
144// if (ul) {
145// physIntLength = ul->GetMaxAllowedStep(*fTrack);
146//#ifdef G4VERBOSE
147// // !!!!! Verbose
148// if(verboseLevel>0) fVerbose->DPSLUserLimit();
149//#endif
150// }
151//
152// if(physIntLength < PhysicalStep ){
153// PhysicalStep = physIntLength;
154// fStepStatus = fUserDefinedLimit;
155// fStep->GetPostStepPoint()
156// ->SetProcessDefinedStep(0);
157// // Take note that the process pointer is 'NULL' if the Step
158// // is defined by the user defined limit.
159// }
160// 2004.01.20 This block will be removed by Geant4 7.0
161
162// GPIL for PostStep
163 fPostStepDoItProcTriggered = MAXofPostStepLoops;
164
165 for(size_t np=0; np < MAXofPostStepLoops; np++){
166 fCurrentProcess = (*fPostStepGetPhysIntVector)(np);
167 if (fCurrentProcess== 0) {
168 (*fSelectedPostStepDoItVector)[np] = InActivated;
169 continue;
170 } // NULL means the process is inactivated by a user on fly.
171
172 physIntLength = fCurrentProcess->
173 PostStepGPIL( *fTrack,
174 fPreviousStepSize,
175 &fCondition );
176#ifdef G4VERBOSE1
177 // !!!!! Verbose
178 if(verboseLevel>0) fVerbose->DPSLPostStep();
179#endif
180
181 switch (fCondition) {
182 case ExclusivelyForced:
183 (*fSelectedPostStepDoItVector)[np] = ExclusivelyForced;
184 fStepStatus = fExclusivelyForcedProc;
185 fStep->GetPostStepPoint()
186 ->SetProcessDefinedStep(fCurrentProcess);
187 break;
188 case Conditionally:
189 // (*fSelectedPostStepDoItVector)[np] = Conditionally;
190 G4Exception("G4SteppingManager::DefinePhysicalStepLength()", "Tracking1001", FatalException, "This feature no more supported");
191
192 break;
193 case Forced:
194 (*fSelectedPostStepDoItVector)[np] = Forced;
195 break;
196 case StronglyForced:
197 (*fSelectedPostStepDoItVector)[np] = StronglyForced;
198 break;
199 default:
200 (*fSelectedPostStepDoItVector)[np] = InActivated;
201 break;
202 }
203
204
205
206 if (fCondition==ExclusivelyForced) {
207 for(size_t nrest=np+1; nrest < MAXofPostStepLoops; nrest++){
208 (*fSelectedPostStepDoItVector)[nrest] = InActivated;
209 }
210 return; // Take note the 'return' at here !!!
211 }
212 else{
213 if(physIntLength < PhysicalStep ){
214 PhysicalStep = physIntLength;
215 fStepStatus = fPostStepDoItProc;
216 fPostStepDoItProcTriggered = G4int(np);
217 fStep->GetPostStepPoint()
218 ->SetProcessDefinedStep(fCurrentProcess);
219 }
220 }
221
222
223 }
224
225 if (fPostStepDoItProcTriggered<MAXofPostStepLoops) {
226 if ((*fSelectedPostStepDoItVector)[fPostStepDoItProcTriggered] ==
227 InActivated) {
228 (*fSelectedPostStepDoItVector)[fPostStepDoItProcTriggered] =
229 NotForced;
230 }
231 }
232
233// GPIL for AlongStep
234 proposedSafety = DBL_MAXstd::numeric_limits<double>::max();
235 G4double safetyProposedToAndByProcess = proposedSafety;
236
237 for(size_t kp=0; kp < MAXofAlongStepLoops; kp++){
238 fCurrentProcess = (*fAlongStepGetPhysIntVector)[kp];
239 if (fCurrentProcess== 0) continue;
240 // NULL means the process is inactivated by a user on fly.
241
242 physIntLength = fCurrentProcess->
243 AlongStepGPIL( *fTrack, fPreviousStepSize,
244 PhysicalStep,
245 safetyProposedToAndByProcess,
246 &fGPILSelection );
247#ifdef G4VERBOSE1
248 // !!!!! Verbose
249 if(verboseLevel>0) fVerbose->DPSLAlongStep();
250#endif
251 if(physIntLength < PhysicalStep){
252 PhysicalStep = physIntLength;
253
254 // Check if the process wants to be the GPIL winner. For example,
255 // multi-scattering proposes Step limit, but won't be the winner.
256 if(fGPILSelection==CandidateForSelection){
257 fStepStatus = fAlongStepDoItProc;
258 fStep->GetPostStepPoint()
259 ->SetProcessDefinedStep(fCurrentProcess);
260 }
261
262 // Transportation is assumed to be the last process in the vector
263 // This is a bad assumption, should actually check! -rtj-
264 //if(kp == MAXofAlongStepLoops-1)
265 // fStepStatus = fGeomBoundary;
266 G4ProcessType ptype = fCurrentProcess->GetProcessType();
267 if (ptype == fTransportation || ptype == fParallel)
268 fStepStatus = fGeomBoundary;
269 }
270
271 // Make sure to check the safety, even if Step is not limited
272 // by this process. J. Apostolakis, June 20, 1998
273 //
274 if (safetyProposedToAndByProcess < proposedSafety)
275 // proposedSafety keeps the smallest value:
276 proposedSafety = safetyProposedToAndByProcess;
277 else
278 // safetyProposedToAndByProcess always proposes a valid safety:
279 safetyProposedToAndByProcess = proposedSafety;
280
281 }
282} // void G4SteppingManager::DefinePhysicalStepLength() //
283
284
285//////////////////////////////////////////////////////
286void G4SteppingManager::InvokeAtRestDoItProcs()
287//////////////////////////////////////////////////////
288{
289// Select the rest process which has the shortest time before
290// it is invoked. In rest processes, GPIL()
291// returns the time before a process occurs.
292 G4double lifeTime, shortestLifeTime;
293
294 fAtRestDoItProcTriggered = 0;
295 shortestLifeTime = DBL_MAXstd::numeric_limits<double>::max();
296
297 unsigned int NofInactiveProc=0;
298 for( size_t ri=0 ; ri < MAXofAtRestLoops ; ri++ ){
1
Loop condition is true. Entering loop body
4
Loop condition is false. Execution continues on line 323
299 fCurrentProcess = (*fAtRestGetPhysIntVector)[ri];
300 if (fCurrentProcess== 0) {
2
Taking false branch
301 (*fSelectedAtRestDoItVector)[ri] = InActivated;
302 NofInactiveProc++;
303 continue;
304 } // NULL means the process is inactivated by a user on fly.
305
306 lifeTime =
307 fCurrentProcess->AtRestGPIL( *fTrack, &fCondition );
308
309
310
311 if(fCondition==Forced && fCurrentProcess){
312 (*fSelectedAtRestDoItVector)[ri] = Forced;
313 }
314 else{
315 (*fSelectedAtRestDoItVector)[ri] = InActivated;
316 if(lifeTime < shortestLifeTime ){
3
Taking false branch
317 shortestLifeTime = lifeTime;
318 fAtRestDoItProcTriggered = G4int(ri);
319 }
320 }
321 }
322
323 (*fSelectedAtRestDoItVector)[fAtRestDoItProcTriggered] = NotForced;
324
325// at least one process is necessary to destroy the particle
326// exit with warning
327 if(NofInactiveProc==MAXofAtRestLoops){
5
Taking false branch
328 G4Exception("G4SteppingManager::InvokeAtRestDoItProcs()", "Tracking0013",
329 JustWarning, "No AtRestDoIt process is active!" );
330 }
331
332 fStep->SetStepLength( 0. ); //the particle has stopped
333 fTrack->SetStepLength( 0. );
334
335// invoke selected process
336 for(size_t np=0; np < MAXofAtRestLoops; np++){
6
Loop condition is true. Entering loop body
337 //
338 // Note: DoItVector has inverse order against GetPhysIntVector
339 // and SelectedAtRestDoItVector.
340 //
341 if( (*fSelectedAtRestDoItVector)[MAXofAtRestLoops-np-1] != InActivated){
7
Taking true branch
342
343 fCurrentProcess = (*fAtRestDoItVector)[np];
344 fParticleChange
345 = fCurrentProcess->AtRestDoIt( *fTrack, *fStep);
346
347 // Set the current process as a process which defined this Step length
348 // Do not select a ParallelWorld process as the defining AtRestProc
349 if (fCurrentProcess->GetProcessType() != fParallel)
8
Taking false branch
350 fStep->GetPostStepPoint()
351 ->SetProcessDefinedStep(fCurrentProcess);
352
353 // Update Step
354 fParticleChange->UpdateStepForAtRest(fStep);
355
356 // Now Store the secondaries from ParticleChange to SecondaryList
357 G4Track* tempSecondaryTrack;
358 G4int num2ndaries;
359
360 num2ndaries = fParticleChange->GetNumberOfSecondaries();
361
362 for(G4int DSecLoop=0 ; DSecLoop< num2ndaries; DSecLoop++){
9
Assuming 'DSecLoop' is < 'num2ndaries'
10
Loop condition is true. Entering loop body
13
Assuming 'DSecLoop' is < 'num2ndaries'
14
Loop condition is true. Entering loop body
17
Assuming 'DSecLoop' is < 'num2ndaries'
18
Loop condition is true. Entering loop body
21
Assuming 'DSecLoop' is < 'num2ndaries'
22
Loop condition is true. Entering loop body
363 tempSecondaryTrack = fParticleChange->GetSecondary(DSecLoop);
364
365 if(tempSecondaryTrack->GetDefinition()->GetApplyCutsFlag())
11
Taking false branch
15
Taking false branch
19
Taking false branch
23
Taking false branch
366 { ApplyProductionCut(tempSecondaryTrack); }
367
368 // Set parentID
369 tempSecondaryTrack->SetParentID( fTrack->GetTrackID() );
370
371 // Set the process pointer which created this track
372 tempSecondaryTrack->SetCreatorProcess( fCurrentProcess );
373
374 // If this 2ndry particle has 'zero' kinetic energy, make sure
375 // it invokes a rest process at the beginning of the tracking
376 if(tempSecondaryTrack->GetKineticEnergy() <= DBL_MINstd::numeric_limits<double>::min()){
12
Taking false branch
16
Taking false branch
20
Taking false branch
24
Taking true branch
377 G4ProcessManager* pm = tempSecondaryTrack->GetDefinition()->GetProcessManager();
25
'pm' initialized here
378 if(!pm && tempSecondaryTrack->GetDefinition()->IsGeneralIon())
26
Assuming 'pm' is null
27
Taking false branch
379 { pm = G4ParticleTable::GetParticleTable()->GetGenericIon()->GetProcessManager(); }
380#ifdef G4MUATOMS_INUSE
381 if(!pm && tempSecondaryTrack->GetDefinition()->IsMuonicAtom())
382 { pm = G4ParticleTable::GetParticleTable()->GetGenericMuonicAtom()->GetProcessManager(); }
383#endif
384 if (pm->GetAtRestProcessVector()->entries()>0){
28
Called C++ object pointer is null
385 tempSecondaryTrack->SetTrackStatus( fStopButAlive );
386 fSecondary->push_back( tempSecondaryTrack );
387 fN2ndariesAtRestDoIt++;
388 } else {
389 delete tempSecondaryTrack;
390 }
391 } else {
392 fSecondary->push_back( tempSecondaryTrack );
393 fN2ndariesAtRestDoIt++;
394 }
395 } //end of loop on secondary
396
397
398 // clear ParticleChange
399 fParticleChange->Clear();
400
401 } //if(fSelectedAtRestDoItVector[np] != InActivated){
402 } //for(size_t np=0; np < MAXofAtRestLoops; np++){
403 fStep->UpdateTrack();
404
405 fTrack->SetTrackStatus( fStopAndKill );
406}
407
408
409/////////////////////////////////////////////////////////
410void G4SteppingManager::InvokeAlongStepDoItProcs()
411/////////////////////////////////////////////////////////
412{
413
414// If the current Step is defined by a 'ExclusivelyForced'
415// PostStepDoIt, then don't invoke any AlongStepDoIt
416 if(fStepStatus == fExclusivelyForcedProc){
417 return; // Take note 'return' at here !!!
418 }
419
420// Invoke the all active continuous processes
421 for( size_t ci=0 ; ci<MAXofAlongStepLoops ; ci++ ){
422 fCurrentProcess = (*fAlongStepDoItVector)[ci];
423 if (fCurrentProcess== 0) continue;
424 // NULL means the process is inactivated by a user on fly.
425
426 fParticleChange
427 = fCurrentProcess->AlongStepDoIt( *fTrack, *fStep );
428
429 // Update the PostStepPoint of Step according to ParticleChange
430 fParticleChange->UpdateStepForAlongStep(fStep);
431#ifdef G4VERBOSE1
432 // !!!!! Verbose
433 if(verboseLevel>0) fVerbose->AlongStepDoItOneByOne();
434#endif
435
436 // Now Store the secondaries from ParticleChange to SecondaryList
437 G4Track* tempSecondaryTrack;
438 G4int num2ndaries;
439
440 num2ndaries = fParticleChange->GetNumberOfSecondaries();
441
442 for(G4int DSecLoop=0 ; DSecLoop< num2ndaries; DSecLoop++){
443 tempSecondaryTrack = fParticleChange->GetSecondary(DSecLoop);
444
445 if(tempSecondaryTrack->GetDefinition()->GetApplyCutsFlag())
446 { ApplyProductionCut(tempSecondaryTrack); }
447
448 // Set parentID
449 tempSecondaryTrack->SetParentID( fTrack->GetTrackID() );
450
451 // Set the process pointer which created this track
452 tempSecondaryTrack->SetCreatorProcess( fCurrentProcess );
453
454 // If this 2ndry particle has 'zero' kinetic energy, make sure
455 // it invokes a rest process at the beginning of the tracking
456 if(tempSecondaryTrack->GetKineticEnergy() <= DBL_MINstd::numeric_limits<double>::min()){
457 G4ProcessManager* pm = tempSecondaryTrack->GetDefinition()->GetProcessManager();
458 if(!pm && tempSecondaryTrack->GetDefinition()->IsGeneralIon())
459 { pm = G4ParticleTable::GetParticleTable()->GetGenericIon()->GetProcessManager(); }
460#ifdef G4MUATOMS_INUSE
461 if(!pm && tempSecondaryTrack->GetDefinition()->IsMuonicAtom())
462 { pm = G4ParticleTable::GetParticleTable()->GetGenericMuonicAtom()->GetProcessManager(); }
463#endif
464 if (pm->GetAtRestProcessVector()->entries()>0){
465 tempSecondaryTrack->SetTrackStatus( fStopButAlive );
466 fSecondary->push_back( tempSecondaryTrack );
467 fN2ndariesAlongStepDoIt++;
468 } else {
469 delete tempSecondaryTrack;
470 }
471 } else {
472 fSecondary->push_back( tempSecondaryTrack );
473 fN2ndariesAlongStepDoIt++;
474 }
475 } //end of loop on secondary
476
477 // Set the track status according to what the process defined
478 // if kinetic energy >0, otherwise set fStopButAlive
479 fTrack->SetTrackStatus( fParticleChange->GetTrackStatus() );
480
481 // clear ParticleChange
482 fParticleChange->Clear();
483 }
484
485 fStep->UpdateTrack();
486 G4TrackStatus fNewStatus = fTrack->GetTrackStatus();
487
488 if ( fNewStatus == fAlive && fTrack->GetKineticEnergy() <= DBL_MINstd::numeric_limits<double>::min() ) {
489 if(MAXofAtRestLoops>0) fNewStatus = fStopButAlive;
490 else fNewStatus = fStopAndKill;
491 fTrack->SetTrackStatus( fNewStatus );
492 }
493
494}
495
496////////////////////////////////////////////////////////
497void G4SteppingManager::InvokePostStepDoItProcs()
498////////////////////////////////////////////////////////
499{
500
501// Invoke the specified discrete processes
502 for(size_t np=0; np < MAXofPostStepLoops; np++){
503 //
504 // Note: DoItVector has inverse order against GetPhysIntVector
505 // and SelectedPostStepDoItVector.
506 //
507 G4int Cond = (*fSelectedPostStepDoItVector)[MAXofPostStepLoops-np-1];
508 if(Cond != InActivated){
509 if( ((Cond == NotForced) && (fStepStatus == fPostStepDoItProc)) ||
510 ((Cond == Forced) && (fStepStatus != fExclusivelyForcedProc)) ||
511 // ((Cond == Conditionally) && (fStepStatus == fAlongStepDoItProc)) ||
512 ((Cond == ExclusivelyForced) && (fStepStatus == fExclusivelyForcedProc)) ||
513 ((Cond == StronglyForced) )
514 ) {
515
516 InvokePSDIP(np);
517 if ((np==0) && (fTrack->GetNextVolume() == 0)){
518 fStepStatus = fWorldBoundary;
519 fStep->GetPostStepPoint()->SetStepStatus( fStepStatus );
520 }
521 }
522 } //if(*fSelectedPostStepDoItVector(np)........
523
524 // Exit from PostStepLoop if the track has been killed,
525 // but extra treatment for processes with Strongly Forced flag
526 if(fTrack->GetTrackStatus() == fStopAndKill) {
527 for(size_t np1=np+1; np1 < MAXofPostStepLoops; np1++){
528 G4int Cond2 = (*fSelectedPostStepDoItVector)[MAXofPostStepLoops-np1-1];
529 if (Cond2 == StronglyForced) {
530 InvokePSDIP(np1);
531 }
532 }
533 break;
534 }
535 } //for(size_t np=0; np < MAXofPostStepLoops; np++){
536}
537
538
539
540void G4SteppingManager::InvokePSDIP(size_t np)
541{
542 fCurrentProcess = (*fPostStepDoItVector)[np];
543 fParticleChange
544 = fCurrentProcess->PostStepDoIt( *fTrack, *fStep);
545
546 // Update PostStepPoint of Step according to ParticleChange
547 fParticleChange->UpdateStepForPostStep(fStep);
548#ifdef G4VERBOSE1
549 // !!!!! Verbose
550 if(verboseLevel>0) fVerbose->PostStepDoItOneByOne();
551#endif
552 // Update G4Track according to ParticleChange after each PostStepDoIt
553 fStep->UpdateTrack();
554
555 // Update safety after each invocation of PostStepDoIts
556 fStep->GetPostStepPoint()->SetSafety( CalculateSafety() );
557
558 // Now Store the secondaries from ParticleChange to SecondaryList
559 G4Track* tempSecondaryTrack;
560 G4int num2ndaries;
561
562 num2ndaries = fParticleChange->GetNumberOfSecondaries();
563
564 for(G4int DSecLoop=0 ; DSecLoop< num2ndaries; DSecLoop++){
565 tempSecondaryTrack = fParticleChange->GetSecondary(DSecLoop);
566
567 if(tempSecondaryTrack->GetDefinition()->GetApplyCutsFlag())
568 { ApplyProductionCut(tempSecondaryTrack); }
569
570 // Set parentID
571 tempSecondaryTrack->SetParentID( fTrack->GetTrackID() );
572
573 // Set the process pointer which created this track
574 tempSecondaryTrack->SetCreatorProcess( fCurrentProcess );
575
576 // If this 2ndry particle has 'zero' kinetic energy, make sure
577 // it invokes a rest process at the beginning of the tracking
578 if(tempSecondaryTrack->GetKineticEnergy() <= DBL_MINstd::numeric_limits<double>::min()){
579 G4ProcessManager* pm = tempSecondaryTrack->GetDefinition()->GetProcessManager();
580 if(!pm && tempSecondaryTrack->GetDefinition()->IsGeneralIon())
581 { pm = G4ParticleTable::GetParticleTable()->GetGenericIon()->GetProcessManager(); }
582#ifdef G4MUATOMS_INUSE
583 if(!pm && tempSecondaryTrack->GetDefinition()->IsMuonicAtom())
584 { pm = G4ParticleTable::GetParticleTable()->GetGenericMuonicAtom()->GetProcessManager(); }
585#endif
586 if (pm->GetAtRestProcessVector()->entries()>0){
587 tempSecondaryTrack->SetTrackStatus( fStopButAlive );
588 fSecondary->push_back( tempSecondaryTrack );
589 fN2ndariesPostStepDoIt++;
590 } else {
591 delete tempSecondaryTrack;
592 }
593 } else {
594 fSecondary->push_back( tempSecondaryTrack );
595 fN2ndariesPostStepDoIt++;
596 }
597 } //end of loop on secondary
598
599 // Set the track status according to what the process defined
600 fTrack->SetTrackStatus( fParticleChange->GetTrackStatus() );
601
602 // clear ParticleChange
603 fParticleChange->Clear();
604}
605
606#include "G4EnergyLossTables.hh"
607#include "G4ProductionCuts.hh"
608#include "G4ProductionCutsTable.hh"
609
610void G4SteppingManager::ApplyProductionCut(G4Track* aSecondary)
611{
612 G4bool tBelowCutEnergyAndSafety = false;
613 G4int tPtclIdx
614 = G4ProductionCuts::GetIndex(aSecondary->GetDefinition());
615 if (tPtclIdx<0) { return; }
616 G4ProductionCutsTable* tCutsTbl
617 = G4ProductionCutsTable::GetProductionCutsTable();
618 G4int tCoupleIdx
619 = tCutsTbl->GetCoupleIndex(fPreStepPoint->GetMaterialCutsCouple());
620 G4double tProdThreshold
621 = (*(tCutsTbl->GetEnergyCutsVector(tPtclIdx)))[tCoupleIdx];
622 if( aSecondary->GetKineticEnergy()<tProdThreshold )
623 {
624 tBelowCutEnergyAndSafety = true;
625 if(std::abs(aSecondary->GetDynamicParticle()->GetCharge()) > DBL_MINstd::numeric_limits<double>::min())
626 {
627 G4double currentRange
628 = G4LossTableManager::Instance()->GetRange(aSecondary->GetDefinition(),
629 aSecondary->GetKineticEnergy(),
630 fPreStepPoint->GetMaterialCutsCouple());
631 tBelowCutEnergyAndSafety = (currentRange < CalculateSafety() );
632 }
633 }
634
635 if( tBelowCutEnergyAndSafety )
636 {
637 if( !(aSecondary->IsGoodForTracking()) )
638 {
639//G4cout << "!! Warning - G4SteppingManager:" << G4endl
640//<< " This physics process generated a secondary"
641//<< " of which energy is below cut but"
642//<< " GoodForTracking is off !!!!!" << G4endl;
643 // Add kinetic energy to the total energy deposit
644 fStep->AddTotalEnergyDeposit(
645 aSecondary->GetKineticEnergy() );
646 aSecondary->SetKineticEnergy(0.0);
647 }
648 }
649}
650