Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4SteppingManager.cc
Go to the documentation of this file.
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// G4SteppingManager class implementation
27//
28// Contact:
29// Questions and comments to this code should be sent to
30// Katsuya Amako (e-mail: [email protected])
31// Takashi Sasaki (e-mail: [email protected])
32// --------------------------------------------------------------------
33
34#include "G4SteppingManager.hh"
35
36#include "G4ForceCondition.hh"
37#include "G4GPILSelection.hh"
39#include "G4ParticleTable.hh"
40#include "G4Profiler.hh"
41#include "G4SteppingControl.hh"
42#include "G4SteppingVerbose.hh"
44#include "G4TiMemory.hh"
46#include "G4UImanager.hh"
47#include "G4UserLimits.hh"
48#include "G4VSensitiveDetector.hh" // Include from 'hits/digi'
49
50// #define debug
51
52//////////////////////////////////////
54//////////////////////////////////////
55{
56 // Construct simple 'has-a' related objects
57
58 fStep = new G4Step();
59 fSecondary = fStep->NewSecondaryVector();
60 fPreStepPoint = fStep->GetPreStepPoint();
61 fPostStepPoint = fStep->GetPostStepPoint();
62
63#ifdef G4VERBOSE
65 if (fVerbose == nullptr) {
68 if (prec > 0) {
69 fVerbose = new G4SteppingVerboseWithUnits(prec);
70 }
71 else {
72 fVerbose = new G4SteppingVerbose();
73 }
74 }
75 else {
77 }
78 KillVerbose = true;
79 }
80 else {
81 KillVerbose = false;
82 }
83 fVerbose->SetManager(this);
84#endif
85
87
88 fSelectedAtRestDoItVector = new G4SelectedAtRestDoItVector(SizeOfSelectedDoItVector, 0);
89 fSelectedAlongStepDoItVector = new G4SelectedAlongStepDoItVector(SizeOfSelectedDoItVector, 0);
90 fSelectedPostStepDoItVector = new G4SelectedPostStepDoItVector(SizeOfSelectedDoItVector, 0);
91
93
94 physIntLength = DBL_MAX;
96
97 fNoProcess = new G4NoProcess;
98}
99
100///////////////////////////////////////
102///////////////////////////////////////
103{
104 fTouchableHandle = nullptr;
105
106 // Destruct simple 'has-a' objects
107 //
108 fStep->DeleteSecondaryVector();
109
110 // delete fSecondary;
111 delete fStep;
112 delete fSelectedAtRestDoItVector;
113 delete fSelectedAlongStepDoItVector;
114 delete fSelectedPostStepDoItVector;
115 delete fUserSteppingAction;
116#ifdef G4VERBOSE
117 if (KillVerbose) delete fVerbose;
118#endif
119}
120
121//////////////////////////////////////////
123//////////////////////////////////////////
124{
125#ifdef GEANT4_USE_TIMEMORY
126 ProfilerConfig profiler{fStep};
127#endif
128
129//--------
130// Prelude
131//--------
132#ifdef G4VERBOSE
133 if (verboseLevel > 0) {
134 fVerbose->NewStep();
135 }
136 else if (verboseLevel == -1) {
138 }
139 else {
141 }
142#endif
143
144 // Store last PostStepPoint to PreStepPoint, and swap current and nex
145 // volume information of G4Track. Reset total energy deposit in one Step.
146 //
147 fStep->CopyPostToPreStepPoint();
149
150 // Switch next touchable in track to current one
151 //
153
154 // Reset the secondary particles
155 //
156 fN2ndariesAtRestDoIt = 0;
157 fN2ndariesAlongStepDoIt = 0;
158 fN2ndariesPostStepDoIt = 0;
159
160 // Set the volume before it is used (in DefineStepLength() for User Limit)
161 //
162 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume();
163
164 // Reset the step's auxiliary points vector pointer
165 //
167
168 //-----------------
169 // AtRest Processes
170 //-----------------
171
172 if (fTrack->GetTrackStatus() == fStopButAlive) {
173 if (MAXofAtRestLoops > 0) {
174 InvokeAtRestDoItProcs();
175 fStepStatus = fAtRestDoItProc;
176 fStep->GetPostStepPoint()->SetStepStatus(fStepStatus);
177
178#ifdef G4VERBOSE
179 if (verboseLevel > 0) fVerbose->AtRestDoItInvoked();
180#endif
181 }
182 // Make sure the track is killed
183 //
185 }
186
187 //---------------------------------
188 // AlongStep and PostStep Processes
189 //---------------------------------
190
191 else {
192 // Find minimum Step length demanded by active disc./cont. processes
193 DefinePhysicalStepLength();
194
195 // Store the Step length (geometrical length) to G4Step and G4Track
196 fStep->SetStepLength(PhysicalStep);
197 fTrack->SetStepLength(PhysicalStep);
198 G4double GeomStepLength = PhysicalStep;
199
200 // Store StepStatus to PostStepPoint
201 fStep->GetPostStepPoint()->SetStepStatus(fStepStatus);
202
203 // Invoke AlongStepDoIt
204 InvokeAlongStepDoItProcs();
205
206 // Get StepStatus from PostStepPoint - a process such as transportation
207 // might have changed it.
208 fStepStatus = fStep->GetPostStepPoint()->GetStepStatus();
209
210 // Update track by taking into account all changes by AlongStepDoIt
211 fStep->UpdateTrack();
212
213 // Update safety after invocation of all AlongStepDoIts
214 endpointSafOrigin = fPostStepPoint->GetPosition();
215 // endpointSafety= std::max( proposedSafety - GeomStepLength, 0.);
216 endpointSafety = std::max(proposedSafety - GeomStepLength, kCarTolerance);
217
218 fStep->GetPostStepPoint()->SetSafety(endpointSafety);
219
220#ifdef G4VERBOSE
221 if (verboseLevel > 0) fVerbose->AlongStepDoItAllDone();
222#endif
223
224 // Invoke PostStepDoIt
225 InvokePostStepDoItProcs();
226
227#ifdef G4VERBOSE
228 if (verboseLevel > 0) fVerbose->PostStepDoItAllDone();
229#endif
230 }
231
232 //-------
233 // Finale
234 //-------
235
236 // Update 'TrackLength' and remeber the Step length of the current Step
237 //
238 fTrack->AddTrackLength(fStep->GetStepLength());
239 fPreviousStepSize = fStep->GetStepLength();
240 fStep->SetTrack(fTrack);
241
242#ifdef G4VERBOSE
243 if (verboseLevel > 0) fVerbose->StepInfo();
244#endif
245
246 // Send G4Step information to Hit/Dig if the volume is sensitive
247 //
248 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume();
249 StepControlFlag = fStep->GetControlFlag();
250 if (fCurrentVolume != nullptr && StepControlFlag != AvoidHitInvocation) {
251 fSensitive = fStep->GetPreStepPoint()->GetSensitiveDetector();
252 if (fSensitive != nullptr) {
253 fSensitive->Hit(fStep);
254 }
255 }
256
257 // User intervention process
258 //
259 if (fUserSteppingAction != nullptr) {
260 fUserSteppingAction->UserSteppingAction(fStep);
261 }
262
263 G4UserSteppingAction* regionalAction =
265
266 if (regionalAction != nullptr) regionalAction->UserSteppingAction(fStep);
267
268 // Stepping process finish. Return the value of the StepStatus
269 //
270 return fStepStatus;
271}
272
273///////////////////////////////////////////////////////////
275///////////////////////////////////////////////////////////
276{
277 // Set up several local variables
278 //
279 PreStepPointIsGeom = false;
280 FirstStep = true;
281 fParticleChange = nullptr;
282 fPreviousStepSize = 0.;
283 fStepStatus = fUndefined;
284
285 fTrack = valueTrack;
286 Mass = fTrack->GetDynamicParticle()->GetMass();
287
288 PhysicalStep = 0.;
289 GeometricalStep = 0.;
290 CorrectedStep = 0.;
291 PreStepPointIsGeom = false;
292 FirstStep = false;
293
294 TempInitVelocity = 0.;
295 TempVelocity = 0.;
296 sumEnergyChange = 0.;
297
298 // If the primary track has 'Suspend' or 'PostponeToNextEvent' state,
299 // set the track state to 'Alive'
300 //
301 if ((fTrack->GetTrackStatus() == fSuspend) || (fTrack->GetTrackStatus() == fPostponeToNextEvent))
302 {
303 fTrack->SetTrackStatus(fAlive);
304 }
305
306 // If the primary track has 'zero' kinetic energy, set the track
307 // state to 'StopButAlive'
308 //
309 if (fTrack->GetKineticEnergy() <= 0.0) {
311 }
312
313 // Set Touchable to track and a private attribute of G4SteppingManager
314
315 if (! fTrack->GetTouchableHandle()) {
316 G4ThreeVector direction = fTrack->GetMomentumDirection();
317 fNavigator->LocateGlobalPointAndSetup(fTrack->GetPosition(), &direction, false, false);
318 fTouchableHandle = fNavigator->CreateTouchableHistory();
319 fTrack->SetTouchableHandle(fTouchableHandle);
320 fTrack->SetNextTouchableHandle(fTouchableHandle);
321 }
322 else {
323 fTrack->SetNextTouchableHandle(fTouchableHandle = fTrack->GetTouchableHandle());
324 G4VPhysicalVolume* oldTopVolume = fTrack->GetTouchableHandle()->GetVolume();
325 G4VPhysicalVolume* newTopVolume = fNavigator->ResetHierarchyAndLocate(fTrack->GetPosition(),
327 if (newTopVolume != oldTopVolume || oldTopVolume->GetRegularStructureId() == 1) {
328 fTouchableHandle = fNavigator->CreateTouchableHistory();
329 fTrack->SetTouchableHandle(fTouchableHandle);
330 fTrack->SetNextTouchableHandle(fTouchableHandle);
331 }
332 }
333
334 // Set OriginTouchableHandle for primary track
335 //
336 if (fTrack->GetParentID() == 0) {
338 }
339
340 // Set vertex information of G4Track at here
341 //
342 if (fTrack->GetCurrentStepNumber() == 0) {
343 fTrack->SetVertexPosition(fTrack->GetPosition());
345 fTrack->SetVertexKineticEnergy(fTrack->GetKineticEnergy());
347 }
348
349 // Initial set up for attributes of 'G4SteppingManager'
350 fCurrentVolume = fTouchableHandle->GetVolume();
351
352 // If track is already outside the world boundary, kill it
353 //
354 if (fCurrentVolume == nullptr) {
355 // If the track is a primary, stop processing
356 if (fTrack->GetParentID() == 0) {
357 G4cerr << "ERROR - G4SteppingManager::SetInitialStep()" << G4endl
358 << " Primary particle starting at - " << fTrack->GetPosition()
359 << " - is outside of the world volume." << G4endl;
360 G4Exception("G4SteppingManager::SetInitialStep()", "Tracking0010", FatalException,
361 "Primary vertex outside of the world!");
362 }
363
365 G4cout << "WARNING - G4SteppingManager::SetInitialStep()" << G4endl
366 << " Initial track position is outside world! - " << fTrack->GetPosition()
367 << G4endl;
368 }
369 else {
370 // Initial set up for attributes of 'Step'
371 fStep->InitializeStep(fTrack);
372 }
373
374#ifdef G4VERBOSE
375 if (verboseLevel > 0) fVerbose->TrackingStarted();
376#endif
377}
378
379/////////////////////////////////////////////////
381/////////////////////////////////////////////////
382{
383#ifdef debug
384 G4cout << "G4SteppingManager::GetProcessNumber: is called track=" << fTrack << G4endl;
385#endif
386
388 if (pm == nullptr) {
389 G4cerr << "ERROR - G4SteppingManager::GetProcessNumber()" << G4endl
390 << " ProcessManager is NULL for particle = "
391 << fTrack->GetDefinition()->GetParticleName()
392 << ", PDG_code = " << fTrack->GetDefinition()->GetPDGEncoding() << G4endl;
393 G4Exception("G4SteppingManager::GetProcessNumber()", "Tracking0011", FatalException,
394 "Process Manager is not found.");
395 return;
396 }
397
398 // AtRestDoits
399 //
400 MAXofAtRestLoops = pm->GetAtRestProcessVector()->entries();
401 fAtRestDoItVector = pm->GetAtRestProcessVector(typeDoIt);
402 fAtRestGetPhysIntVector = pm->GetAtRestProcessVector(typeGPIL);
403
404#ifdef debug
405 G4cout << "G4SteppingManager::GetProcessNumber: #ofAtRest=" << MAXofAtRestLoops << G4endl;
406#endif
407
408 // AlongStepDoits
409 //
410 MAXofAlongStepLoops = pm->GetAlongStepProcessVector()->entries();
411 fAlongStepDoItVector = pm->GetAlongStepProcessVector(typeDoIt);
412 fAlongStepGetPhysIntVector = pm->GetAlongStepProcessVector(typeGPIL);
413
414#ifdef debug
415 G4cout << "G4SteppingManager::GetProcessNumber:#ofAlongStp=" << MAXofAlongStepLoops << G4endl;
416#endif
417
418 // PostStepDoits
419 //
420 MAXofPostStepLoops = pm->GetPostStepProcessVector()->entries();
421 fPostStepDoItVector = pm->GetPostStepProcessVector(typeDoIt);
422 fPostStepGetPhysIntVector = pm->GetPostStepProcessVector(typeGPIL);
423
424#ifdef debug
425 G4cout << "G4SteppingManager::GetProcessNumber: #ofPostStep=" << MAXofPostStepLoops << G4endl;
426#endif
427
428 if (SizeOfSelectedDoItVector < MAXofAtRestLoops ||
429 SizeOfSelectedDoItVector < MAXofAlongStepLoops ||
430 SizeOfSelectedDoItVector < MAXofPostStepLoops)
431 {
432 G4cerr << "ERROR - G4SteppingManager::GetProcessNumber()" << G4endl
433 << " SizeOfSelectedDoItVector= " << SizeOfSelectedDoItVector
434 << " ; is smaller then one of MAXofAtRestLoops= " << MAXofAtRestLoops << G4endl
435 << " or MAXofAlongStepLoops= " << MAXofAlongStepLoops
436 << " or MAXofPostStepLoops= " << MAXofPostStepLoops << G4endl;
437 G4Exception("G4SteppingManager::GetProcessNumber()", "Tracking0012", FatalException,
438 "The array size is smaller than the actual No of processes.");
439 }
440}
441
442// ************************************************************************
443//
444// Private Member Functions
445//
446// ************************************************************************
447
448/////////////////////////////////////////////////////////
449void G4SteppingManager::DefinePhysicalStepLength()
450/////////////////////////////////////////////////////////
451{
452 // ReSet the counter etc.
453 //
454 PhysicalStep = DBL_MAX; // Initialize by a huge number
455 physIntLength = DBL_MAX; // Initialize by a huge number
456
457#ifdef G4VERBOSE
458 if (verboseLevel > 0) fVerbose->DPSLStarted();
459#endif
460
461 // GPIL for PostStep
462 //
463 fPostStepDoItProcTriggered = MAXofPostStepLoops;
464
465 for (std::size_t np = 0; np < MAXofPostStepLoops; ++np) {
466 fCurrentProcess = (*fPostStepGetPhysIntVector)((G4int)np);
467 if (fCurrentProcess == nullptr) {
468 (*fSelectedPostStepDoItVector)[np] = InActivated;
469 continue;
470 } // NULL means the process is inactivated by a user on fly
471
472 physIntLength = fCurrentProcess->PostStepGPIL(*fTrack, fPreviousStepSize, &fCondition);
473#ifdef G4VERBOSE
474 if (verboseLevel > 0) fVerbose->DPSLPostStep();
475#endif
476
477 switch (fCondition) {
479 (*fSelectedPostStepDoItVector)[np] = ExclusivelyForced;
480 fStepStatus = fExclusivelyForcedProc;
481 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess);
482 break;
483 case Conditionally:
484 // (*fSelectedPostStepDoItVector)[np] = Conditionally;
485 G4Exception("G4SteppingManager::DefinePhysicalStepLength()", "Tracking1001", FatalException,
486 "This feature no more supported");
487 break;
488 case Forced:
489 (*fSelectedPostStepDoItVector)[np] = Forced;
490 break;
491 case StronglyForced:
492 (*fSelectedPostStepDoItVector)[np] = StronglyForced;
493 break;
494 default:
495 (*fSelectedPostStepDoItVector)[np] = InActivated;
496 break;
497 }
498
499 if (fCondition == ExclusivelyForced) {
500 for (std::size_t nrest = np + 1; nrest < MAXofPostStepLoops; ++nrest) {
501 (*fSelectedPostStepDoItVector)[nrest] = InActivated;
502 }
503 return; // Take note the 'return' at here !!!
504 }
505
506 if (physIntLength < PhysicalStep) {
507 PhysicalStep = physIntLength;
508 fStepStatus = fPostStepDoItProc;
509 fPostStepDoItProcTriggered = G4int(np);
510 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess);
511 }
512 }
513
514 if (fPostStepDoItProcTriggered < MAXofPostStepLoops) {
515 if ((*fSelectedPostStepDoItVector)[fPostStepDoItProcTriggered] == InActivated) {
516 (*fSelectedPostStepDoItVector)[fPostStepDoItProcTriggered] = NotForced;
517 }
518 }
519
520 // GPIL for AlongStep
521 //
522 proposedSafety = DBL_MAX;
523 G4double safetyProposedToAndByProcess = proposedSafety;
524 G4bool delegateToTransportation = false;
525
526 for (std::size_t kp = 0; kp < MAXofAlongStepLoops; ++kp) {
527 fCurrentProcess = (*fAlongStepGetPhysIntVector)[(G4int)kp];
528 if (fCurrentProcess == nullptr) continue;
529 // NULL means the process is inactivated by a user on fly
530
531 physIntLength = fCurrentProcess->AlongStepGPIL(
532 *fTrack, fPreviousStepSize, PhysicalStep, safetyProposedToAndByProcess, &fGPILSelection);
533#ifdef G4VERBOSE
534 if (verboseLevel > 0) fVerbose->DPSLAlongStep();
535#endif
536
537 if (physIntLength < PhysicalStep) {
538 PhysicalStep = physIntLength;
539
540 // Check if the process wants to be the GPIL winner. For example,
541 // multi-scattering proposes Step limit, but won't be the winner
542 //
543 if (fGPILSelection == CandidateForSelection) {
544 fStepStatus = fAlongStepDoItProc;
545 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess);
546 }
547 else if (fCurrentProcess->GetProcessType() == fParallel)
548 { // a parallel world is proposing the shortest but expecting Transportation
549 // to win.
550 delegateToTransportation = true;
551 }
552
553 // Transportation is assumed to be the last process in the vector
554 // Transportation is winning
555 if (kp == MAXofAlongStepLoops - 1) {
556 // This used to set fStepStatus = fGeomBoundary, but it was moved to
557 // G4Transportation::AlongStepDoIt where the process can actually
558 // decide if there is a volume boundary.
559 delegateToTransportation = false;
560 }
561 }
562
563 // Make sure to check the safety, even if Step is not limited
564 // by this process
565 //
566 if (safetyProposedToAndByProcess < proposedSafety) {
567 // proposedSafety keeps the smallest value
568 //
569 proposedSafety = safetyProposedToAndByProcess;
570 }
571 else {
572 // safetyProposedToAndByProcess always proposes a valid safety
573 //
574 safetyProposedToAndByProcess = proposedSafety;
575 }
576 }
577 if (delegateToTransportation) {
578 fStepStatus = fGeomBoundary;
579 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess);
580 }
581}
582
583//////////////////////////////////////////////////////
584G4int G4SteppingManager::ProcessSecondariesFromParticleChange()
585//////////////////////////////////////////////////////
586{
587 G4Track* tempSecondaryTrack;
588 G4int num2ndaries;
589 G4int pushedSecondaries = 0;
590
591 num2ndaries = fParticleChange->GetNumberOfSecondaries();
592 if (num2ndaries == 0) {
593 return 0;
594 }
595
596 // Get the creator process. This may be different from fCurrentProcess for a
597 // "combined" process such as G4GammaGeneralProcess.
598 const G4VProcess* creatorProcess = fCurrentProcess->GetCreatorProcess();
599
600 for (G4int DSecLoop = 0; DSecLoop < num2ndaries; ++DSecLoop) {
601 tempSecondaryTrack = fParticleChange->GetSecondary(DSecLoop);
602
603 // Set parentID
604 tempSecondaryTrack->SetParentID(fTrack->GetTrackID());
605
606 // Set the process pointer which created this track
607 tempSecondaryTrack->SetCreatorProcess(creatorProcess);
608
609 // If this 2ndry particle has 'zero' kinetic energy, make sure
610 // it invokes a rest process at the beginning of the tracking
611 //
612 if (tempSecondaryTrack->GetKineticEnergy() <= DBL_MIN) {
613 G4ProcessManager* pm = tempSecondaryTrack->GetDefinition()->GetProcessManager();
614 if (pm == nullptr) {
616 ED << "A track without proper process manager is pushed\n"
617 << "into the track stack.\n"
618 << " Particle name : " << tempSecondaryTrack->GetDefinition()->GetParticleName()
619 << " -- created by " << creatorProcess->GetProcessName() << ".";
620 G4Exception("G4SteppingManager::ProcessSecondariesFromParticleChange()", "Tracking10051",
621 FatalException, ED);
622 }
623 if (pm->GetAtRestProcessVector()->entries() > 0) {
624 tempSecondaryTrack->SetTrackStatus(fStopButAlive);
625 fSecondary->push_back(tempSecondaryTrack);
626 ++pushedSecondaries;
627 }
628 else {
629 delete tempSecondaryTrack;
630 }
631 }
632 else {
633 fSecondary->push_back(tempSecondaryTrack);
634 ++pushedSecondaries;
635 }
636 } // end of loop on secondary
637
638 return pushedSecondaries;
639}
640
641//////////////////////////////////////////////////////
642void G4SteppingManager::InvokeAtRestDoItProcs()
643//////////////////////////////////////////////////////
644{
645 // Select the rest process which has the shortest time before
646 // it is invoked. In rest processes, GPIL()
647 // returns the time before a process occurs
648
649 G4double lifeTime, shortestLifeTime;
650
651 fAtRestDoItProcTriggered = 0;
652 shortestLifeTime = DBL_MAX;
653
654 for (std::size_t ri = 0; ri < MAXofAtRestLoops; ++ri) {
655 fCurrentProcess = (*fAtRestGetPhysIntVector)[(G4int)ri];
656 if (fCurrentProcess == nullptr) {
657 (*fSelectedAtRestDoItVector)[ri] = InActivated;
658 continue;
659 } // nullptr means the process is inactivated by a user on fly
660
661 lifeTime = fCurrentProcess->AtRestGPIL(*fTrack, &fCondition);
662
663 if (fCondition == Forced) {
664 (*fSelectedAtRestDoItVector)[ri] = Forced;
665 }
666 else {
667 (*fSelectedAtRestDoItVector)[ri] = InActivated;
668 if (lifeTime < shortestLifeTime) {
669 shortestLifeTime = lifeTime;
670 fAtRestDoItProcTriggered = G4int(ri);
671 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess);
672 }
673 }
674 }
675
676 (*fSelectedAtRestDoItVector)[fAtRestDoItProcTriggered] = NotForced;
677
678 fStep->SetStepLength(0.); // the particle has stopped
679 fTrack->SetStepLength(0.);
680
681 // Condition to avoid that stable ions are handled by Radioactive Decay.
682 // We use a very large time threshold (many orders of magnitude bigger than
683 // the universe's age) but not DBL_MAX because shortestLifeTime can be
684 // sometimes slightly smaller for stable ions.
685 if (shortestLifeTime < 1.0e+100) // Unstable ion at rest: Radioactive Decay will decay it
686 {
687 // invoke selected process
688 //
689 for (std::size_t np = 0; np < MAXofAtRestLoops; ++np) {
690 //
691 // Note: DoItVector has inverse order against GetPhysIntVector
692 // and SelectedAtRestDoItVector.
693 //
694 if ((*fSelectedAtRestDoItVector)[MAXofAtRestLoops - np - 1] != InActivated) {
695 fCurrentProcess = (*fAtRestDoItVector)[(G4int)np];
696 fParticleChange = fCurrentProcess->AtRestDoIt(*fTrack, *fStep);
697
698 // Update Step
699 //
700 fParticleChange->UpdateStepForAtRest(fStep);
701
702 // Now Store the secondaries from ParticleChange to SecondaryList
703 fN2ndariesAtRestDoIt += ProcessSecondariesFromParticleChange();
704
705 // clear ParticleChange
706 fParticleChange->Clear();
707
708 } // if(fSelectedAtRestDoItVector[np] != InActivated){
709 } // for(std::size_t np=0; np<MAXofAtRestLoops; ++np){
710 }
711 else // Stable ion at rest
712 {
713 fStep->GetPostStepPoint()->SetProcessDefinedStep(fNoProcess);
714 } // if(shortestLifeTime < 1.0e+100)
715
716 fStep->UpdateTrack();
717
719}
720
721/////////////////////////////////////////////////////////
722void G4SteppingManager::InvokeAlongStepDoItProcs()
723/////////////////////////////////////////////////////////
724{
725 // If the current Step is defined by a 'ExclusivelyForced'
726 // PostStepDoIt, then don't invoke any AlongStepDoIt
727 //
728 if (fStepStatus == fExclusivelyForcedProc) {
729 return; // Take note 'return' is here !!!
730 }
731
732 // Invoke all active continuous processes
733 //
734 for (std::size_t ci = 0; ci < MAXofAlongStepLoops; ++ci) {
735 fCurrentProcess = (*fAlongStepDoItVector)[(G4int)ci];
736 if (fCurrentProcess == nullptr) continue;
737 // NULL means the process is inactivated by a user on fly.
738
739 fParticleChange = fCurrentProcess->AlongStepDoIt(*fTrack, *fStep);
740
741 // Update the PostStepPoint of Step according to ParticleChange
742 fParticleChange->UpdateStepForAlongStep(fStep);
743
744#ifdef G4VERBOSE
745 if (verboseLevel > 0) fVerbose->AlongStepDoItOneByOne();
746#endif
747
748 // Now Store the secondaries from ParticleChange to SecondaryList
749 fN2ndariesAlongStepDoIt += ProcessSecondariesFromParticleChange();
750
751 // Set the track status according to what the process defined
752 // if kinetic energy >0, otherwise set fStopButAlive
753 //
754 fTrack->SetTrackStatus(fParticleChange->GetTrackStatus());
755
756 // clear ParticleChange
757 fParticleChange->Clear();
758 }
759
760 fStep->UpdateTrack();
761 G4TrackStatus fNewStatus = fTrack->GetTrackStatus();
762
763 if (fNewStatus == fAlive && fTrack->GetKineticEnergy() <= DBL_MIN) {
764 if (MAXofAtRestLoops > 0)
765 fNewStatus = fStopButAlive;
766 else
767 fNewStatus = fStopAndKill;
768 fTrack->SetTrackStatus(fNewStatus);
769 }
770}
771
772////////////////////////////////////////////////////////
773void G4SteppingManager::InvokePostStepDoItProcs()
774////////////////////////////////////////////////////////
775{
776 // Invoke the specified discrete processes
777 //
778 for (std::size_t np = 0; np < MAXofPostStepLoops; ++np) {
779 //
780 // Note: DoItVector has inverse order against GetPhysIntVector
781 // and SelectedPostStepDoItVector.
782 //
783 G4int Cond = (*fSelectedPostStepDoItVector)[MAXofPostStepLoops - np - 1];
784 if (Cond != InActivated) {
785 if (((Cond == NotForced) && (fStepStatus == fPostStepDoItProc)) ||
786 ((Cond == Forced) && (fStepStatus != fExclusivelyForcedProc)) ||
787 ((Cond == ExclusivelyForced) && (fStepStatus == fExclusivelyForcedProc)) ||
788 ((Cond == StronglyForced)))
789 {
790 InvokePSDIP(np);
791 if ((np == 0) && (fTrack->GetNextVolume() == nullptr)) {
792 fStepStatus = fWorldBoundary;
793 fStep->GetPostStepPoint()->SetStepStatus(fStepStatus);
794 }
795 }
796 }
797
798 // Exit from PostStepLoop if the track has been killed,
799 // but extra treatment for processes with Strongly Forced flag
800 //
801 if (fTrack->GetTrackStatus() == fStopAndKill) {
802 for (std::size_t np1 = np + 1; np1 < MAXofPostStepLoops; ++np1) {
803 G4int Cond2 = (*fSelectedPostStepDoItVector)[MAXofPostStepLoops - np1 - 1];
804 if (Cond2 == StronglyForced) {
805 InvokePSDIP(np1);
806 }
807 }
808 break;
809 }
810 }
811}
812
813////////////////////////////////////////////////////////
814void G4SteppingManager::InvokePSDIP(size_t np)
815////////////////////////////////////////////////////////
816{
817 fCurrentProcess = (*fPostStepDoItVector)[(G4int)np];
818 fParticleChange = fCurrentProcess->PostStepDoIt(*fTrack, *fStep);
819
820 // Update PostStepPoint of Step according to ParticleChange
821 fParticleChange->UpdateStepForPostStep(fStep);
822
823#ifdef G4VERBOSE
824 if (verboseLevel > 0) fVerbose->PostStepDoItOneByOne();
825#endif
826
827 // Update G4Track according to ParticleChange after each PostStepDoIt
828 fStep->UpdateTrack();
829
830 // Update safety after each invocation of PostStepDoIts
831 fStep->GetPostStepPoint()->SetSafety(CalculateSafety());
832
833 // Now Store the secondaries from ParticleChange to SecondaryList
834 fN2ndariesPostStepDoIt += ProcessSecondariesFromParticleChange();
835
836 // Set the track status according to what the process defined
837 fTrack->SetTrackStatus(fParticleChange->GetTrackStatus());
838
839 // clear ParticleChange
840 fParticleChange->Clear();
841}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
@ InActivated
@ StronglyForced
@ NotForced
@ Conditionally
@ ExclusivelyForced
@ Forced
@ CandidateForSelection
@ typeGPIL
@ typeDoIt
@ fParallel
G4StepStatus
@ fGeomBoundary
@ fWorldBoundary
@ fUndefined
@ fPostStepDoItProc
@ fAtRestDoItProc
@ fAlongStepDoItProc
@ fExclusivelyForcedProc
@ AvoidHitInvocation
std::vector< G4int > G4SelectedPostStepDoItVector
std::vector< G4int > G4SelectedAtRestDoItVector
std::vector< G4int > G4SelectedAlongStepDoItVector
Definition of the G4SteppingVerboseWithUnits class.
G4TrackStatus
@ fSuspend
@ fAlive
@ fStopAndKill
@ fStopButAlive
@ fPostponeToNextEvent
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
G4GLOB_DLL std::ostream G4cerr
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
G4double GetMass() const
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
G4Region * GetRegion() const
G4TouchableHistory * CreateTouchableHistory() const
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
G4ProcessManager * GetProcessManager() const
const G4String & GetParticleName() const
G4ProcessVector * GetAlongStepProcessVector(G4ProcessVectorTypeIndex typ=typeGPIL) const
G4ProcessVector * GetPostStepProcessVector(G4ProcessVectorTypeIndex typ=typeGPIL) const
G4ProcessVector * GetAtRestProcessVector(G4ProcessVectorTypeIndex typ=typeGPIL) const
std::size_t entries() const
G4UserSteppingAction * GetRegionalSteppingAction() const
Definition G4Region.cc:158
G4StepStatus GetStepStatus() const
void SetSafety(const G4double aValue)
void SetStepStatus(const G4StepStatus aValue)
void SetProcessDefinedStep(const G4VProcess *aValue)
const G4ThreeVector & GetPosition() const
G4VSensitiveDetector * GetSensitiveDetector() const
G4VPhysicalVolume * GetPhysicalVolume() const
void DeleteSecondaryVector()
void SetPointerToVectorOfAuxiliaryPoints(std::vector< G4ThreeVector > *vec)
void InitializeStep(G4Track *aValue)
G4SteppingControl GetControlFlag() const
void UpdateTrack()
void ResetTotalEnergyDeposit()
void SetStepLength(G4double value)
void CopyPostToPreStepPoint()
G4StepPoint * GetPreStepPoint() const
G4double GetStepLength() const
G4TrackVector * NewSecondaryVector()
G4StepPoint * GetPostStepPoint() const
void SetTrack(G4Track *value)
G4StepStatus Stepping()
void SetNavigator(G4Navigator *value)
void SetInitialStep(G4Track *valueTrack)
static G4int BestUnitPrecision()
virtual G4VPhysicalVolume * GetVolume(G4int depth=0) const
G4TrackStatus GetTrackStatus() const
void SetTrackStatus(const G4TrackStatus aTrackStatus)
void SetStepLength(G4double value)
G4int GetTrackID() const
G4VPhysicalVolume * GetVolume() const
void SetVertexPosition(const G4ThreeVector &aValue)
const G4TouchableHandle & GetNextTouchableHandle() const
void SetVertexMomentumDirection(const G4ThreeVector &aValue)
G4VPhysicalVolume * GetNextVolume() const
void SetNextTouchableHandle(const G4TouchableHandle &apValue)
const G4ThreeVector & GetPosition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4int GetCurrentStepNumber() const
void SetOriginTouchableHandle(const G4TouchableHandle &apValue)
G4ParticleDefinition * GetDefinition() const
void AddTrackLength(const G4double aValue)
const G4DynamicParticle * GetDynamicParticle() const
const G4TouchableHandle & GetTouchableHandle() const
const G4ThreeVector & GetMomentumDirection() const
G4double GetKineticEnergy() const
void SetVertexKineticEnergy(const G4double aValue)
G4int GetParentID() const
void SetLogicalVolumeAtVertex(const G4LogicalVolume *)
void SetParentID(const G4int aValue)
void SetCreatorProcess(const G4VProcess *aValue)
static G4TransportationManager * GetTransportationManager()
virtual void UserSteppingAction(const G4Step *)
virtual G4Step * UpdateStepForAlongStep(G4Step *Step)
virtual G4Step * UpdateStepForAtRest(G4Step *Step)
virtual G4Step * UpdateStepForPostStep(G4Step *Step)
G4int GetNumberOfSecondaries() const
G4Track * GetSecondary(G4int anIndex) const
G4LogicalVolume * GetLogicalVolume() const
virtual G4int GetRegularStructureId() const =0
virtual G4VParticleChange * AtRestDoIt(const G4Track &track, const G4Step &stepData)=0
G4ProcessType GetProcessType() const
virtual G4VParticleChange * PostStepDoIt(const G4Track &track, const G4Step &stepData)=0
G4double PostStepGPIL(const G4Track &track, G4double previousStepSize, G4ForceCondition *condition)
G4double AtRestGPIL(const G4Track &track, G4ForceCondition *condition)
virtual G4VParticleChange * AlongStepDoIt(const G4Track &track, const G4Step &stepData)=0
G4double AlongStepGPIL(const G4Track &track, G4double previousStepSize, G4double currentMinimumStep, G4double &proposedSafety, G4GPILSelection *selection)
virtual const G4VProcess * GetCreatorProcess() const
const G4String & GetProcessName() const
G4bool Hit(G4Step *aStep)
static G4VSteppingVerbose * GetInstance()
virtual void AlongStepDoItAllDone()=0
virtual G4VSteppingVerbose * Clone()
virtual void AlongStepDoItOneByOne()=0
virtual void DPSLPostStep()=0
virtual void PostStepDoItAllDone()=0
virtual void AtRestDoItInvoked()=0
virtual void DPSLAlongStep()=0
virtual void StepInfo()=0
virtual void PostStepDoItOneByOne()=0
virtual void DPSLStarted()=0
static void SetSilent(G4int fSilent)
virtual void TrackingStarted()=0
virtual void NewStep()=0
static G4VSteppingVerbose * GetMasterInstance()
virtual void SetManager(G4SteppingManager *const)
#define DBL_MIN
Definition templates.hh:54
#define DBL_MAX
Definition templates.hh:62