Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // G4SteppingManager class implementation 26 // G4SteppingManager class implementation 27 // 27 // 28 // Contact: 28 // Contact: 29 // Questions and comments to this code shoul 29 // Questions and comments to this code should be sent to 30 // Katsuya Amako (e-mail: Katsuya.Amako@k 30 // Katsuya Amako (e-mail: Katsuya.Amako@kek.jp) 31 // Takashi Sasaki (e-mail: Takashi.Sasaki@ 31 // Takashi Sasaki (e-mail: Takashi.Sasaki@kek.jp) 32 // ------------------------------------------- 32 // -------------------------------------------------------------------- 33 33 34 #include "G4SteppingManager.hh" 34 #include "G4SteppingManager.hh" 35 35 36 #include "G4ForceCondition.hh" 36 #include "G4ForceCondition.hh" 37 #include "G4GPILSelection.hh" 37 #include "G4GPILSelection.hh" 38 #include "G4GeometryTolerance.hh" 38 #include "G4GeometryTolerance.hh" 39 #include "G4ParticleTable.hh" 39 #include "G4ParticleTable.hh" >> 40 #include "G4Profiler.hh" 40 #include "G4SteppingControl.hh" 41 #include "G4SteppingControl.hh" 41 #include "G4SteppingVerbose.hh" 42 #include "G4SteppingVerbose.hh" 42 #include "G4SteppingVerboseWithUnits.hh" 43 #include "G4SteppingVerboseWithUnits.hh" >> 44 #include "G4TiMemory.hh" 43 #include "G4TransportationManager.hh" 45 #include "G4TransportationManager.hh" 44 #include "G4UImanager.hh" 46 #include "G4UImanager.hh" 45 #include "G4UserLimits.hh" 47 #include "G4UserLimits.hh" 46 #include "G4VSensitiveDetector.hh" // Include 48 #include "G4VSensitiveDetector.hh" // Include from 'hits/digi' 47 49 48 // #define debug 50 // #define debug 49 51 50 ////////////////////////////////////// 52 ////////////////////////////////////// 51 G4SteppingManager::G4SteppingManager() 53 G4SteppingManager::G4SteppingManager() 52 ////////////////////////////////////// 54 ////////////////////////////////////// 53 { 55 { 54 // Construct simple 'has-a' related objects 56 // Construct simple 'has-a' related objects 55 57 56 fStep = new G4Step(); 58 fStep = new G4Step(); 57 fSecondary = fStep->NewSecondaryVector(); 59 fSecondary = fStep->NewSecondaryVector(); 58 fPreStepPoint = fStep->GetPreStepPoint(); 60 fPreStepPoint = fStep->GetPreStepPoint(); 59 fPostStepPoint = fStep->GetPostStepPoint(); 61 fPostStepPoint = fStep->GetPostStepPoint(); 60 62 61 #ifdef G4VERBOSE 63 #ifdef G4VERBOSE 62 fVerbose = G4VSteppingVerbose::GetInstance() 64 fVerbose = G4VSteppingVerbose::GetInstance(); 63 if (fVerbose == nullptr) { 65 if (fVerbose == nullptr) { 64 if (G4VSteppingVerbose::GetMasterInstance( 66 if (G4VSteppingVerbose::GetMasterInstance() == nullptr) { 65 G4int prec = G4SteppingVerbose::BestUnit 67 G4int prec = G4SteppingVerbose::BestUnitPrecision(); 66 if (prec > 0) { 68 if (prec > 0) { 67 fVerbose = new G4SteppingVerboseWithUn 69 fVerbose = new G4SteppingVerboseWithUnits(prec); 68 } 70 } 69 else { 71 else { 70 fVerbose = new G4SteppingVerbose(); 72 fVerbose = new G4SteppingVerbose(); 71 } 73 } 72 } 74 } 73 else { 75 else { 74 fVerbose = G4VSteppingVerbose::GetMaster 76 fVerbose = G4VSteppingVerbose::GetMasterInstance()->Clone(); 75 } 77 } 76 KillVerbose = true; 78 KillVerbose = true; 77 } 79 } 78 else { 80 else { 79 KillVerbose = false; 81 KillVerbose = false; 80 } 82 } 81 fVerbose->SetManager(this); 83 fVerbose->SetManager(this); 82 #endif 84 #endif 83 85 84 SetNavigator(G4TransportationManager::GetTra 86 SetNavigator(G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()); 85 87 86 fSelectedAtRestDoItVector = new G4SelectedAt 88 fSelectedAtRestDoItVector = new G4SelectedAtRestDoItVector(SizeOfSelectedDoItVector, 0); 87 fSelectedAlongStepDoItVector = new G4Selecte 89 fSelectedAlongStepDoItVector = new G4SelectedAlongStepDoItVector(SizeOfSelectedDoItVector, 0); 88 fSelectedPostStepDoItVector = new G4Selected 90 fSelectedPostStepDoItVector = new G4SelectedPostStepDoItVector(SizeOfSelectedDoItVector, 0); 89 91 90 SetNavigator(G4TransportationManager::GetTra 92 SetNavigator(G4TransportationManager::GetTransportationManager()->GetNavigatorForTracking()); 91 93 92 physIntLength = DBL_MAX; 94 physIntLength = DBL_MAX; 93 kCarTolerance = 0.5 * G4GeometryTolerance::G 95 kCarTolerance = 0.5 * G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); 94 96 95 fNoProcess = new G4NoProcess; 97 fNoProcess = new G4NoProcess; 96 } 98 } 97 99 98 /////////////////////////////////////// 100 /////////////////////////////////////// 99 G4SteppingManager::~G4SteppingManager() 101 G4SteppingManager::~G4SteppingManager() 100 /////////////////////////////////////// 102 /////////////////////////////////////// 101 { 103 { 102 fTouchableHandle = nullptr; 104 fTouchableHandle = nullptr; 103 105 104 // Destruct simple 'has-a' objects 106 // Destruct simple 'has-a' objects 105 // 107 // 106 fStep->DeleteSecondaryVector(); 108 fStep->DeleteSecondaryVector(); 107 109 108 // delete fSecondary; 110 // delete fSecondary; 109 delete fStep; 111 delete fStep; 110 delete fSelectedAtRestDoItVector; 112 delete fSelectedAtRestDoItVector; 111 delete fSelectedAlongStepDoItVector; 113 delete fSelectedAlongStepDoItVector; 112 delete fSelectedPostStepDoItVector; 114 delete fSelectedPostStepDoItVector; 113 delete fUserSteppingAction; 115 delete fUserSteppingAction; 114 #ifdef G4VERBOSE 116 #ifdef G4VERBOSE 115 if (KillVerbose) delete fVerbose; 117 if (KillVerbose) delete fVerbose; 116 #endif 118 #endif 117 } 119 } 118 120 119 ////////////////////////////////////////// 121 ////////////////////////////////////////// 120 G4StepStatus G4SteppingManager::Stepping() 122 G4StepStatus G4SteppingManager::Stepping() 121 ////////////////////////////////////////// 123 ////////////////////////////////////////// 122 { 124 { >> 125 #ifdef GEANT4_USE_TIMEMORY >> 126 ProfilerConfig profiler{fStep}; >> 127 #endif >> 128 123 //-------- 129 //-------- 124 // Prelude 130 // Prelude 125 //-------- 131 //-------- 126 #ifdef G4VERBOSE 132 #ifdef G4VERBOSE 127 if (verboseLevel > 0) { 133 if (verboseLevel > 0) { 128 fVerbose->NewStep(); 134 fVerbose->NewStep(); 129 } 135 } 130 else if (verboseLevel == -1) { 136 else if (verboseLevel == -1) { 131 G4VSteppingVerbose::SetSilent(1); 137 G4VSteppingVerbose::SetSilent(1); 132 } 138 } 133 else { 139 else { 134 G4VSteppingVerbose::SetSilent(0); 140 G4VSteppingVerbose::SetSilent(0); 135 } 141 } 136 #endif 142 #endif 137 143 138 // Store last PostStepPoint to PreStepPoint, 144 // Store last PostStepPoint to PreStepPoint, and swap current and nex 139 // volume information of G4Track. Reset tota 145 // volume information of G4Track. Reset total energy deposit in one Step. 140 // 146 // 141 fStep->CopyPostToPreStepPoint(); 147 fStep->CopyPostToPreStepPoint(); 142 fStep->ResetTotalEnergyDeposit(); 148 fStep->ResetTotalEnergyDeposit(); 143 149 144 // Switch next touchable in track to current 150 // Switch next touchable in track to current one 145 // 151 // 146 fTrack->SetTouchableHandle(fTrack->GetNextTo 152 fTrack->SetTouchableHandle(fTrack->GetNextTouchableHandle()); 147 153 148 // Reset the secondary particles 154 // Reset the secondary particles 149 // 155 // 150 fN2ndariesAtRestDoIt = 0; 156 fN2ndariesAtRestDoIt = 0; 151 fN2ndariesAlongStepDoIt = 0; 157 fN2ndariesAlongStepDoIt = 0; 152 fN2ndariesPostStepDoIt = 0; 158 fN2ndariesPostStepDoIt = 0; 153 159 154 // Set the volume before it is used (in Defi 160 // Set the volume before it is used (in DefineStepLength() for User Limit) 155 // 161 // 156 fCurrentVolume = fStep->GetPreStepPoint()->G 162 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 157 163 158 // Reset the step's auxiliary points vector 164 // Reset the step's auxiliary points vector pointer 159 // 165 // 160 fStep->SetPointerToVectorOfAuxiliaryPoints(n 166 fStep->SetPointerToVectorOfAuxiliaryPoints(nullptr); 161 167 162 //----------------- 168 //----------------- 163 // AtRest Processes 169 // AtRest Processes 164 //----------------- 170 //----------------- 165 171 166 if (fTrack->GetTrackStatus() == fStopButAliv 172 if (fTrack->GetTrackStatus() == fStopButAlive) { 167 if (MAXofAtRestLoops > 0) { 173 if (MAXofAtRestLoops > 0) { 168 InvokeAtRestDoItProcs(); 174 InvokeAtRestDoItProcs(); 169 fStepStatus = fAtRestDoItProc; 175 fStepStatus = fAtRestDoItProc; 170 fStep->GetPostStepPoint()->SetStepStatus 176 fStep->GetPostStepPoint()->SetStepStatus(fStepStatus); 171 177 172 #ifdef G4VERBOSE 178 #ifdef G4VERBOSE 173 if (verboseLevel > 0) fVerbose->AtRestDo 179 if (verboseLevel > 0) fVerbose->AtRestDoItInvoked(); 174 #endif 180 #endif 175 } 181 } 176 // Make sure the track is killed 182 // Make sure the track is killed 177 // 183 // 178 fTrack->SetTrackStatus(fStopAndKill); 184 fTrack->SetTrackStatus(fStopAndKill); 179 } 185 } 180 186 181 //--------------------------------- 187 //--------------------------------- 182 // AlongStep and PostStep Processes 188 // AlongStep and PostStep Processes 183 //--------------------------------- 189 //--------------------------------- 184 190 185 else { 191 else { 186 // Find minimum Step length demanded by ac 192 // Find minimum Step length demanded by active disc./cont. processes 187 DefinePhysicalStepLength(); 193 DefinePhysicalStepLength(); 188 194 189 // Store the Step length (geometrical leng 195 // Store the Step length (geometrical length) to G4Step and G4Track 190 fStep->SetStepLength(PhysicalStep); 196 fStep->SetStepLength(PhysicalStep); 191 fTrack->SetStepLength(PhysicalStep); 197 fTrack->SetStepLength(PhysicalStep); 192 G4double GeomStepLength = PhysicalStep; 198 G4double GeomStepLength = PhysicalStep; 193 199 194 // Store StepStatus to PostStepPoint 200 // Store StepStatus to PostStepPoint 195 fStep->GetPostStepPoint()->SetStepStatus(f 201 fStep->GetPostStepPoint()->SetStepStatus(fStepStatus); 196 202 197 // Invoke AlongStepDoIt 203 // Invoke AlongStepDoIt 198 InvokeAlongStepDoItProcs(); 204 InvokeAlongStepDoItProcs(); 199 205 200 // Get StepStatus from PostStepPoint - a p 206 // Get StepStatus from PostStepPoint - a process such as transportation 201 // might have changed it. 207 // might have changed it. 202 fStepStatus = fStep->GetPostStepPoint()->G 208 fStepStatus = fStep->GetPostStepPoint()->GetStepStatus(); 203 209 204 // Update track by taking into account all 210 // Update track by taking into account all changes by AlongStepDoIt 205 fStep->UpdateTrack(); 211 fStep->UpdateTrack(); 206 212 207 // Update safety after invocation of all A 213 // Update safety after invocation of all AlongStepDoIts 208 endpointSafOrigin = fPostStepPoint->GetPos 214 endpointSafOrigin = fPostStepPoint->GetPosition(); 209 // endpointSafety= std::max( proposedSafe 215 // endpointSafety= std::max( proposedSafety - GeomStepLength, 0.); 210 endpointSafety = std::max(proposedSafety - 216 endpointSafety = std::max(proposedSafety - GeomStepLength, kCarTolerance); 211 217 212 fStep->GetPostStepPoint()->SetSafety(endpo 218 fStep->GetPostStepPoint()->SetSafety(endpointSafety); 213 219 214 #ifdef G4VERBOSE 220 #ifdef G4VERBOSE 215 if (verboseLevel > 0) fVerbose->AlongStepD 221 if (verboseLevel > 0) fVerbose->AlongStepDoItAllDone(); 216 #endif 222 #endif 217 223 218 // Invoke PostStepDoIt 224 // Invoke PostStepDoIt 219 InvokePostStepDoItProcs(); 225 InvokePostStepDoItProcs(); 220 226 221 #ifdef G4VERBOSE 227 #ifdef G4VERBOSE 222 if (verboseLevel > 0) fVerbose->PostStepDo 228 if (verboseLevel > 0) fVerbose->PostStepDoItAllDone(); 223 #endif 229 #endif 224 } 230 } 225 231 226 //------- 232 //------- 227 // Finale 233 // Finale 228 //------- 234 //------- 229 235 230 // Update 'TrackLength' and remeber the Step 236 // Update 'TrackLength' and remeber the Step length of the current Step 231 // 237 // 232 fTrack->AddTrackLength(fStep->GetStepLength( 238 fTrack->AddTrackLength(fStep->GetStepLength()); 233 fPreviousStepSize = fStep->GetStepLength(); 239 fPreviousStepSize = fStep->GetStepLength(); 234 fStep->SetTrack(fTrack); 240 fStep->SetTrack(fTrack); 235 241 236 #ifdef G4VERBOSE 242 #ifdef G4VERBOSE 237 if (verboseLevel > 0) fVerbose->StepInfo(); 243 if (verboseLevel > 0) fVerbose->StepInfo(); 238 #endif 244 #endif 239 245 240 // Send G4Step information to Hit/Dig if the 246 // Send G4Step information to Hit/Dig if the volume is sensitive 241 // 247 // 242 fCurrentVolume = fStep->GetPreStepPoint()->G 248 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 243 StepControlFlag = fStep->GetControlFlag(); 249 StepControlFlag = fStep->GetControlFlag(); 244 if (fCurrentVolume != nullptr && StepControl 250 if (fCurrentVolume != nullptr && StepControlFlag != AvoidHitInvocation) { 245 fSensitive = fStep->GetPreStepPoint()->Get 251 fSensitive = fStep->GetPreStepPoint()->GetSensitiveDetector(); 246 if (fSensitive != nullptr) { 252 if (fSensitive != nullptr) { 247 fSensitive->Hit(fStep); 253 fSensitive->Hit(fStep); 248 } 254 } 249 } 255 } 250 256 251 // User intervention process 257 // User intervention process 252 // 258 // 253 if (fUserSteppingAction != nullptr) { 259 if (fUserSteppingAction != nullptr) { 254 fUserSteppingAction->UserSteppingAction(fS 260 fUserSteppingAction->UserSteppingAction(fStep); 255 } 261 } 256 262 257 G4UserSteppingAction* regionalAction = 263 G4UserSteppingAction* regionalAction = 258 fCurrentVolume->GetLogicalVolume()->GetReg 264 fCurrentVolume->GetLogicalVolume()->GetRegion()->GetRegionalSteppingAction(); 259 265 260 if (regionalAction != nullptr) regionalActio 266 if (regionalAction != nullptr) regionalAction->UserSteppingAction(fStep); 261 267 262 // Stepping process finish. Return the value 268 // Stepping process finish. Return the value of the StepStatus 263 // 269 // 264 return fStepStatus; 270 return fStepStatus; 265 } 271 } 266 272 267 ////////////////////////////////////////////// 273 /////////////////////////////////////////////////////////// 268 void G4SteppingManager::SetInitialStep(G4Track 274 void G4SteppingManager::SetInitialStep(G4Track* valueTrack) 269 ////////////////////////////////////////////// 275 /////////////////////////////////////////////////////////// 270 { 276 { 271 // Set up several local variables 277 // Set up several local variables 272 // 278 // 273 PreStepPointIsGeom = false; 279 PreStepPointIsGeom = false; 274 FirstStep = true; 280 FirstStep = true; 275 fParticleChange = nullptr; 281 fParticleChange = nullptr; 276 fPreviousStepSize = 0.; 282 fPreviousStepSize = 0.; 277 fStepStatus = fUndefined; 283 fStepStatus = fUndefined; 278 284 279 fTrack = valueTrack; 285 fTrack = valueTrack; 280 Mass = fTrack->GetDynamicParticle()->GetMass 286 Mass = fTrack->GetDynamicParticle()->GetMass(); 281 287 282 PhysicalStep = 0.; 288 PhysicalStep = 0.; 283 GeometricalStep = 0.; 289 GeometricalStep = 0.; 284 CorrectedStep = 0.; 290 CorrectedStep = 0.; 285 PreStepPointIsGeom = false; 291 PreStepPointIsGeom = false; 286 FirstStep = false; 292 FirstStep = false; 287 293 288 TempInitVelocity = 0.; 294 TempInitVelocity = 0.; 289 TempVelocity = 0.; 295 TempVelocity = 0.; 290 sumEnergyChange = 0.; 296 sumEnergyChange = 0.; 291 297 292 // If the primary track has 'Suspend' or 'Po 298 // If the primary track has 'Suspend' or 'PostponeToNextEvent' state, 293 // set the track state to 'Alive' 299 // set the track state to 'Alive' 294 // 300 // 295 if ((fTrack->GetTrackStatus() == fSuspend) | 301 if ((fTrack->GetTrackStatus() == fSuspend) || (fTrack->GetTrackStatus() == fPostponeToNextEvent)) 296 { 302 { 297 fTrack->SetTrackStatus(fAlive); 303 fTrack->SetTrackStatus(fAlive); 298 } 304 } 299 305 300 // If the primary track has 'zero' kinetic e 306 // If the primary track has 'zero' kinetic energy, set the track 301 // state to 'StopButAlive' 307 // state to 'StopButAlive' 302 // 308 // 303 if (fTrack->GetKineticEnergy() <= 0.0) { 309 if (fTrack->GetKineticEnergy() <= 0.0) { 304 fTrack->SetTrackStatus(fStopButAlive); 310 fTrack->SetTrackStatus(fStopButAlive); 305 } 311 } 306 312 307 // Set Touchable to track and a private attr 313 // Set Touchable to track and a private attribute of G4SteppingManager 308 314 309 if (! fTrack->GetTouchableHandle()) { 315 if (! fTrack->GetTouchableHandle()) { 310 G4ThreeVector direction = fTrack->GetMomen 316 G4ThreeVector direction = fTrack->GetMomentumDirection(); 311 fNavigator->LocateGlobalPointAndSetup(fTra 317 fNavigator->LocateGlobalPointAndSetup(fTrack->GetPosition(), &direction, false, false); 312 fTouchableHandle = fNavigator->CreateTouch 318 fTouchableHandle = fNavigator->CreateTouchableHistory(); 313 fTrack->SetTouchableHandle(fTouchableHandl 319 fTrack->SetTouchableHandle(fTouchableHandle); 314 fTrack->SetNextTouchableHandle(fTouchableH 320 fTrack->SetNextTouchableHandle(fTouchableHandle); 315 } 321 } 316 else { 322 else { 317 fTrack->SetNextTouchableHandle(fTouchableH 323 fTrack->SetNextTouchableHandle(fTouchableHandle = fTrack->GetTouchableHandle()); 318 G4VPhysicalVolume* oldTopVolume = fTrack-> 324 G4VPhysicalVolume* oldTopVolume = fTrack->GetTouchableHandle()->GetVolume(); 319 G4VPhysicalVolume* newTopVolume = fNavigat 325 G4VPhysicalVolume* newTopVolume = fNavigator->ResetHierarchyAndLocate(fTrack->GetPosition(), 320 fTrack->GetMomentumDirection(), *((G4Tou 326 fTrack->GetMomentumDirection(), *((G4TouchableHistory*)fTrack->GetTouchableHandle()())); 321 if (newTopVolume != oldTopVolume || oldTop 327 if (newTopVolume != oldTopVolume || oldTopVolume->GetRegularStructureId() == 1) { 322 fTouchableHandle = fNavigator->CreateTou 328 fTouchableHandle = fNavigator->CreateTouchableHistory(); 323 fTrack->SetTouchableHandle(fTouchableHan 329 fTrack->SetTouchableHandle(fTouchableHandle); 324 fTrack->SetNextTouchableHandle(fTouchabl 330 fTrack->SetNextTouchableHandle(fTouchableHandle); 325 } 331 } 326 } 332 } 327 333 328 // Set OriginTouchableHandle for primary tra 334 // Set OriginTouchableHandle for primary track 329 // 335 // 330 if (fTrack->GetParentID() == 0) { 336 if (fTrack->GetParentID() == 0) { 331 fTrack->SetOriginTouchableHandle(fTrack->G 337 fTrack->SetOriginTouchableHandle(fTrack->GetTouchableHandle()); 332 } 338 } 333 339 334 // Set vertex information of G4Track at here 340 // Set vertex information of G4Track at here 335 // 341 // 336 if (fTrack->GetCurrentStepNumber() == 0) { 342 if (fTrack->GetCurrentStepNumber() == 0) { 337 fTrack->SetVertexPosition(fTrack->GetPosit 343 fTrack->SetVertexPosition(fTrack->GetPosition()); 338 fTrack->SetVertexMomentumDirection(fTrack- 344 fTrack->SetVertexMomentumDirection(fTrack->GetMomentumDirection()); 339 fTrack->SetVertexKineticEnergy(fTrack->Get 345 fTrack->SetVertexKineticEnergy(fTrack->GetKineticEnergy()); 340 fTrack->SetLogicalVolumeAtVertex(fTrack->G 346 fTrack->SetLogicalVolumeAtVertex(fTrack->GetVolume()->GetLogicalVolume()); 341 } 347 } 342 348 343 // Initial set up for attributes of 'G4Stepp 349 // Initial set up for attributes of 'G4SteppingManager' 344 fCurrentVolume = fTouchableHandle->GetVolume 350 fCurrentVolume = fTouchableHandle->GetVolume(); 345 351 346 // If track is already outside the world bou 352 // If track is already outside the world boundary, kill it 347 // 353 // 348 if (fCurrentVolume == nullptr) { 354 if (fCurrentVolume == nullptr) { 349 // If the track is a primary, stop process 355 // If the track is a primary, stop processing 350 if (fTrack->GetParentID() == 0) { 356 if (fTrack->GetParentID() == 0) { 351 G4cerr << "ERROR - G4SteppingManager::Se 357 G4cerr << "ERROR - G4SteppingManager::SetInitialStep()" << G4endl 352 << " Primary particle star 358 << " Primary particle starting at - " << fTrack->GetPosition() 353 << " - is outside of the world vo 359 << " - is outside of the world volume." << G4endl; 354 G4Exception("G4SteppingManager::SetIniti 360 G4Exception("G4SteppingManager::SetInitialStep()", "Tracking0010", FatalException, 355 "Primary vertex outside of the world!" 361 "Primary vertex outside of the world!"); 356 } 362 } 357 363 358 fTrack->SetTrackStatus(fStopAndKill); 364 fTrack->SetTrackStatus(fStopAndKill); 359 G4cout << "WARNING - G4SteppingManager::Se 365 G4cout << "WARNING - G4SteppingManager::SetInitialStep()" << G4endl 360 << " Initial track positio 366 << " Initial track position is outside world! - " << fTrack->GetPosition() 361 << G4endl; 367 << G4endl; 362 } 368 } 363 else { 369 else { 364 // Initial set up for attributes of 'Step' 370 // Initial set up for attributes of 'Step' 365 fStep->InitializeStep(fTrack); 371 fStep->InitializeStep(fTrack); 366 } 372 } 367 373 368 #ifdef G4VERBOSE 374 #ifdef G4VERBOSE 369 if (verboseLevel > 0) fVerbose->TrackingStar 375 if (verboseLevel > 0) fVerbose->TrackingStarted(); 370 #endif 376 #endif 371 } 377 } 372 378 373 ////////////////////////////////////////////// 379 ///////////////////////////////////////////////// 374 void G4SteppingManager::GetProcessNumber() 380 void G4SteppingManager::GetProcessNumber() 375 ////////////////////////////////////////////// 381 ///////////////////////////////////////////////// 376 { 382 { 377 #ifdef debug 383 #ifdef debug 378 G4cout << "G4SteppingManager::GetProcessNumb 384 G4cout << "G4SteppingManager::GetProcessNumber: is called track=" << fTrack << G4endl; 379 #endif 385 #endif 380 386 381 G4ProcessManager* pm = fTrack->GetDefinition 387 G4ProcessManager* pm = fTrack->GetDefinition()->GetProcessManager(); 382 if (pm == nullptr) { 388 if (pm == nullptr) { 383 G4cerr << "ERROR - G4SteppingManager::GetP 389 G4cerr << "ERROR - G4SteppingManager::GetProcessNumber()" << G4endl 384 << " ProcessManager is NULL 390 << " ProcessManager is NULL for particle = " 385 << fTrack->GetDefinition()->GetPart 391 << fTrack->GetDefinition()->GetParticleName() 386 << ", PDG_code = " << fTrack->GetDe 392 << ", PDG_code = " << fTrack->GetDefinition()->GetPDGEncoding() << G4endl; 387 G4Exception("G4SteppingManager::GetProcess 393 G4Exception("G4SteppingManager::GetProcessNumber()", "Tracking0011", FatalException, 388 "Process Manager is not found."); 394 "Process Manager is not found."); 389 return; 395 return; 390 } 396 } 391 397 392 // AtRestDoits 398 // AtRestDoits 393 // 399 // 394 MAXofAtRestLoops = pm->GetAtRestProcessVecto 400 MAXofAtRestLoops = pm->GetAtRestProcessVector()->entries(); 395 fAtRestDoItVector = pm->GetAtRestProcessVect 401 fAtRestDoItVector = pm->GetAtRestProcessVector(typeDoIt); 396 fAtRestGetPhysIntVector = pm->GetAtRestProce 402 fAtRestGetPhysIntVector = pm->GetAtRestProcessVector(typeGPIL); 397 403 398 #ifdef debug 404 #ifdef debug 399 G4cout << "G4SteppingManager::GetProcessNumb 405 G4cout << "G4SteppingManager::GetProcessNumber: #ofAtRest=" << MAXofAtRestLoops << G4endl; 400 #endif 406 #endif 401 407 402 // AlongStepDoits 408 // AlongStepDoits 403 // 409 // 404 MAXofAlongStepLoops = pm->GetAlongStepProces 410 MAXofAlongStepLoops = pm->GetAlongStepProcessVector()->entries(); 405 fAlongStepDoItVector = pm->GetAlongStepProce 411 fAlongStepDoItVector = pm->GetAlongStepProcessVector(typeDoIt); 406 fAlongStepGetPhysIntVector = pm->GetAlongSte 412 fAlongStepGetPhysIntVector = pm->GetAlongStepProcessVector(typeGPIL); 407 413 408 #ifdef debug 414 #ifdef debug 409 G4cout << "G4SteppingManager::GetProcessNumb 415 G4cout << "G4SteppingManager::GetProcessNumber:#ofAlongStp=" << MAXofAlongStepLoops << G4endl; 410 #endif 416 #endif 411 417 412 // PostStepDoits 418 // PostStepDoits 413 // 419 // 414 MAXofPostStepLoops = pm->GetPostStepProcessV 420 MAXofPostStepLoops = pm->GetPostStepProcessVector()->entries(); 415 fPostStepDoItVector = pm->GetPostStepProcess 421 fPostStepDoItVector = pm->GetPostStepProcessVector(typeDoIt); 416 fPostStepGetPhysIntVector = pm->GetPostStepP 422 fPostStepGetPhysIntVector = pm->GetPostStepProcessVector(typeGPIL); 417 423 418 #ifdef debug 424 #ifdef debug 419 G4cout << "G4SteppingManager::GetProcessNumb 425 G4cout << "G4SteppingManager::GetProcessNumber: #ofPostStep=" << MAXofPostStepLoops << G4endl; 420 #endif 426 #endif 421 427 422 if (SizeOfSelectedDoItVector < MAXofAtRestLo 428 if (SizeOfSelectedDoItVector < MAXofAtRestLoops || 423 SizeOfSelectedDoItVector < MAXofAlongSte 429 SizeOfSelectedDoItVector < MAXofAlongStepLoops || 424 SizeOfSelectedDoItVector < MAXofPostStep 430 SizeOfSelectedDoItVector < MAXofPostStepLoops) 425 { 431 { 426 G4cerr << "ERROR - G4SteppingManager::GetP 432 G4cerr << "ERROR - G4SteppingManager::GetProcessNumber()" << G4endl 427 << " SizeOfSelectedDoItVecto 433 << " SizeOfSelectedDoItVector= " << SizeOfSelectedDoItVector 428 << " ; is smaller then one of MAXof 434 << " ; is smaller then one of MAXofAtRestLoops= " << MAXofAtRestLoops << G4endl 429 << " or MAXofAlongStepLoops= 435 << " or MAXofAlongStepLoops= " << MAXofAlongStepLoops 430 << " or MAXofPostStepLoops= " << MA 436 << " or MAXofPostStepLoops= " << MAXofPostStepLoops << G4endl; 431 G4Exception("G4SteppingManager::GetProcess 437 G4Exception("G4SteppingManager::GetProcessNumber()", "Tracking0012", FatalException, 432 "The array size is smaller than the actu 438 "The array size is smaller than the actual No of processes."); 433 } 439 } 434 } 440 } 435 441 436 // ******************************************* 442 // ************************************************************************ 437 // 443 // 438 // Private Member Functions 444 // Private Member Functions 439 // 445 // 440 // ******************************************* 446 // ************************************************************************ 441 447 442 ////////////////////////////////////////////// 448 ///////////////////////////////////////////////////////// 443 void G4SteppingManager::DefinePhysicalStepLeng 449 void G4SteppingManager::DefinePhysicalStepLength() 444 ////////////////////////////////////////////// 450 ///////////////////////////////////////////////////////// 445 { 451 { 446 // ReSet the counter etc. 452 // ReSet the counter etc. 447 // 453 // 448 PhysicalStep = DBL_MAX; // Initialize by a 454 PhysicalStep = DBL_MAX; // Initialize by a huge number 449 physIntLength = DBL_MAX; // Initialize by a 455 physIntLength = DBL_MAX; // Initialize by a huge number 450 456 451 #ifdef G4VERBOSE 457 #ifdef G4VERBOSE 452 if (verboseLevel > 0) fVerbose->DPSLStarted( 458 if (verboseLevel > 0) fVerbose->DPSLStarted(); 453 #endif 459 #endif 454 460 455 // GPIL for PostStep 461 // GPIL for PostStep 456 // 462 // 457 fPostStepDoItProcTriggered = MAXofPostStepLo 463 fPostStepDoItProcTriggered = MAXofPostStepLoops; 458 464 459 for (std::size_t np = 0; np < MAXofPostStepL 465 for (std::size_t np = 0; np < MAXofPostStepLoops; ++np) { 460 fCurrentProcess = (*fPostStepGetPhysIntVec 466 fCurrentProcess = (*fPostStepGetPhysIntVector)((G4int)np); 461 if (fCurrentProcess == nullptr) { 467 if (fCurrentProcess == nullptr) { 462 (*fSelectedPostStepDoItVector)[np] = InA 468 (*fSelectedPostStepDoItVector)[np] = InActivated; 463 continue; 469 continue; 464 } // NULL means the process is inactivate 470 } // NULL means the process is inactivated by a user on fly 465 471 466 physIntLength = fCurrentProcess->PostStepG 472 physIntLength = fCurrentProcess->PostStepGPIL(*fTrack, fPreviousStepSize, &fCondition); 467 #ifdef G4VERBOSE 473 #ifdef G4VERBOSE 468 if (verboseLevel > 0) fVerbose->DPSLPostSt 474 if (verboseLevel > 0) fVerbose->DPSLPostStep(); 469 #endif 475 #endif 470 476 471 switch (fCondition) { 477 switch (fCondition) { 472 case ExclusivelyForced: 478 case ExclusivelyForced: 473 (*fSelectedPostStepDoItVector)[np] = E 479 (*fSelectedPostStepDoItVector)[np] = ExclusivelyForced; 474 fStepStatus = fExclusivelyForcedProc; 480 fStepStatus = fExclusivelyForcedProc; 475 fStep->GetPostStepPoint()->SetProcessD 481 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess); 476 break; 482 break; 477 case Conditionally: 483 case Conditionally: 478 // (*fSelectedPostStepDoItVector)[np] 484 // (*fSelectedPostStepDoItVector)[np] = Conditionally; 479 G4Exception("G4SteppingManager::Define 485 G4Exception("G4SteppingManager::DefinePhysicalStepLength()", "Tracking1001", FatalException, 480 "This feature no more supported"); 486 "This feature no more supported"); 481 break; 487 break; 482 case Forced: 488 case Forced: 483 (*fSelectedPostStepDoItVector)[np] = F 489 (*fSelectedPostStepDoItVector)[np] = Forced; 484 break; 490 break; 485 case StronglyForced: 491 case StronglyForced: 486 (*fSelectedPostStepDoItVector)[np] = S 492 (*fSelectedPostStepDoItVector)[np] = StronglyForced; 487 break; 493 break; 488 default: 494 default: 489 (*fSelectedPostStepDoItVector)[np] = I 495 (*fSelectedPostStepDoItVector)[np] = InActivated; 490 break; 496 break; 491 } 497 } 492 498 493 if (fCondition == ExclusivelyForced) { 499 if (fCondition == ExclusivelyForced) { 494 for (std::size_t nrest = np + 1; nrest < 500 for (std::size_t nrest = np + 1; nrest < MAXofPostStepLoops; ++nrest) { 495 (*fSelectedPostStepDoItVector)[nrest] 501 (*fSelectedPostStepDoItVector)[nrest] = InActivated; 496 } 502 } 497 return; // Take note the 'return' at he 503 return; // Take note the 'return' at here !!! 498 } 504 } 499 505 500 if (physIntLength < PhysicalStep) { 506 if (physIntLength < PhysicalStep) { 501 PhysicalStep = physIntLength; 507 PhysicalStep = physIntLength; 502 fStepStatus = fPostStepDoItProc; 508 fStepStatus = fPostStepDoItProc; 503 fPostStepDoItProcTriggered = G4int(np); 509 fPostStepDoItProcTriggered = G4int(np); 504 fStep->GetPostStepPoint()->SetProcessDef 510 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess); 505 } 511 } 506 } 512 } 507 513 508 if (fPostStepDoItProcTriggered < MAXofPostSt 514 if (fPostStepDoItProcTriggered < MAXofPostStepLoops) { 509 if ((*fSelectedPostStepDoItVector)[fPostSt 515 if ((*fSelectedPostStepDoItVector)[fPostStepDoItProcTriggered] == InActivated) { 510 (*fSelectedPostStepDoItVector)[fPostStep 516 (*fSelectedPostStepDoItVector)[fPostStepDoItProcTriggered] = NotForced; 511 } 517 } 512 } 518 } 513 519 514 // GPIL for AlongStep 520 // GPIL for AlongStep 515 // 521 // 516 proposedSafety = DBL_MAX; 522 proposedSafety = DBL_MAX; 517 G4double safetyProposedToAndByProcess = prop 523 G4double safetyProposedToAndByProcess = proposedSafety; 518 G4bool delegateToTransportation = false; 524 G4bool delegateToTransportation = false; 519 525 520 for (std::size_t kp = 0; kp < MAXofAlongStep 526 for (std::size_t kp = 0; kp < MAXofAlongStepLoops; ++kp) { 521 fCurrentProcess = (*fAlongStepGetPhysIntVe 527 fCurrentProcess = (*fAlongStepGetPhysIntVector)[(G4int)kp]; 522 if (fCurrentProcess == nullptr) continue; 528 if (fCurrentProcess == nullptr) continue; 523 // NULL means the process is inactivated b 529 // NULL means the process is inactivated by a user on fly 524 530 525 physIntLength = fCurrentProcess->AlongStep 531 physIntLength = fCurrentProcess->AlongStepGPIL( 526 *fTrack, fPreviousStepSize, PhysicalStep 532 *fTrack, fPreviousStepSize, PhysicalStep, safetyProposedToAndByProcess, &fGPILSelection); 527 #ifdef G4VERBOSE 533 #ifdef G4VERBOSE 528 if (verboseLevel > 0) fVerbose->DPSLAlongS 534 if (verboseLevel > 0) fVerbose->DPSLAlongStep(); 529 #endif 535 #endif 530 536 531 if (physIntLength < PhysicalStep) { 537 if (physIntLength < PhysicalStep) { 532 PhysicalStep = physIntLength; 538 PhysicalStep = physIntLength; 533 539 534 // Check if the process wants to be the 540 // Check if the process wants to be the GPIL winner. For example, 535 // multi-scattering proposes Step limit, 541 // multi-scattering proposes Step limit, but won't be the winner 536 // 542 // 537 if (fGPILSelection == CandidateForSelect 543 if (fGPILSelection == CandidateForSelection) { 538 fStepStatus = fAlongStepDoItProc; 544 fStepStatus = fAlongStepDoItProc; 539 fStep->GetPostStepPoint()->SetProcessD 545 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess); 540 } 546 } 541 else if (fCurrentProcess->GetProcessType 547 else if (fCurrentProcess->GetProcessType() == fParallel) 542 { // a parallel world is proposing the 548 { // a parallel world is proposing the shortest but expecting Transportation 543 // to win. 549 // to win. 544 delegateToTransportation = true; 550 delegateToTransportation = true; 545 } 551 } 546 552 547 // Transportation is assumed to be the l 553 // Transportation is assumed to be the last process in the vector 548 // Transportation is winning 554 // Transportation is winning 549 if (kp == MAXofAlongStepLoops - 1) { 555 if (kp == MAXofAlongStepLoops - 1) { 550 // This used to set fStepStatus = fGeo 556 // This used to set fStepStatus = fGeomBoundary, but it was moved to 551 // G4Transportation::AlongStepDoIt whe 557 // G4Transportation::AlongStepDoIt where the process can actually 552 // decide if there is a volume boundar 558 // decide if there is a volume boundary. 553 delegateToTransportation = false; 559 delegateToTransportation = false; 554 } 560 } 555 } 561 } 556 562 557 // Make sure to check the safety, even if 563 // Make sure to check the safety, even if Step is not limited 558 // by this process 564 // by this process 559 // 565 // 560 if (safetyProposedToAndByProcess < propose 566 if (safetyProposedToAndByProcess < proposedSafety) { 561 // proposedSafety keeps the smallest val 567 // proposedSafety keeps the smallest value 562 // 568 // 563 proposedSafety = safetyProposedToAndByPr 569 proposedSafety = safetyProposedToAndByProcess; 564 } 570 } 565 else { 571 else { 566 // safetyProposedToAndByProcess always p 572 // safetyProposedToAndByProcess always proposes a valid safety 567 // 573 // 568 safetyProposedToAndByProcess = proposedS 574 safetyProposedToAndByProcess = proposedSafety; 569 } 575 } 570 } 576 } 571 if (delegateToTransportation) { 577 if (delegateToTransportation) { 572 fStepStatus = fGeomBoundary; 578 fStepStatus = fGeomBoundary; 573 fStep->GetPostStepPoint()->SetProcessDefin 579 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess); 574 } 580 } 575 } 581 } 576 582 577 ////////////////////////////////////////////// 583 ////////////////////////////////////////////////////// 578 G4int G4SteppingManager::ProcessSecondariesFro 584 G4int G4SteppingManager::ProcessSecondariesFromParticleChange() 579 ////////////////////////////////////////////// 585 ////////////////////////////////////////////////////// 580 { 586 { 581 G4Track* tempSecondaryTrack; 587 G4Track* tempSecondaryTrack; 582 G4int num2ndaries; 588 G4int num2ndaries; 583 G4int pushedSecondaries = 0; 589 G4int pushedSecondaries = 0; 584 590 585 num2ndaries = fParticleChange->GetNumberOfSe 591 num2ndaries = fParticleChange->GetNumberOfSecondaries(); 586 if (num2ndaries == 0) { 592 if (num2ndaries == 0) { 587 return 0; 593 return 0; 588 } 594 } 589 595 590 // Get the creator process. This may be diff 596 // Get the creator process. This may be different from fCurrentProcess for a 591 // "combined" process such as G4GammaGeneral 597 // "combined" process such as G4GammaGeneralProcess. 592 const G4VProcess* creatorProcess = fCurrentP 598 const G4VProcess* creatorProcess = fCurrentProcess->GetCreatorProcess(); 593 599 594 for (G4int DSecLoop = 0; DSecLoop < num2ndar 600 for (G4int DSecLoop = 0; DSecLoop < num2ndaries; ++DSecLoop) { 595 tempSecondaryTrack = fParticleChange->GetS 601 tempSecondaryTrack = fParticleChange->GetSecondary(DSecLoop); 596 602 597 // Set parentID 603 // Set parentID 598 tempSecondaryTrack->SetParentID(fTrack->Ge 604 tempSecondaryTrack->SetParentID(fTrack->GetTrackID()); 599 605 600 // Set the process pointer which created t 606 // Set the process pointer which created this track 601 tempSecondaryTrack->SetCreatorProcess(crea 607 tempSecondaryTrack->SetCreatorProcess(creatorProcess); 602 608 603 // If this 2ndry particle has 'zero' kinet 609 // If this 2ndry particle has 'zero' kinetic energy, make sure 604 // it invokes a rest process at the beginn 610 // it invokes a rest process at the beginning of the tracking 605 // 611 // 606 if (tempSecondaryTrack->GetKineticEnergy() 612 if (tempSecondaryTrack->GetKineticEnergy() <= DBL_MIN) { 607 G4ProcessManager* pm = tempSecondaryTrac 613 G4ProcessManager* pm = tempSecondaryTrack->GetDefinition()->GetProcessManager(); 608 if (pm == nullptr) { 614 if (pm == nullptr) { 609 G4ExceptionDescription ED; 615 G4ExceptionDescription ED; 610 ED << "A track without proper process 616 ED << "A track without proper process manager is pushed\n" 611 << "into the track stack.\n" 617 << "into the track stack.\n" 612 << " Particle name : " << tempSecon 618 << " Particle name : " << tempSecondaryTrack->GetDefinition()->GetParticleName() 613 << " -- created by " << creatorProc 619 << " -- created by " << creatorProcess->GetProcessName() << "."; 614 G4Exception("G4SteppingManager::Proces 620 G4Exception("G4SteppingManager::ProcessSecondariesFromParticleChange()", "Tracking10051", 615 FatalException, ED); 621 FatalException, ED); 616 } 622 } 617 if (pm->GetAtRestProcessVector()->entrie 623 if (pm->GetAtRestProcessVector()->entries() > 0) { 618 tempSecondaryTrack->SetTrackStatus(fSt 624 tempSecondaryTrack->SetTrackStatus(fStopButAlive); 619 fSecondary->push_back(tempSecondaryTra 625 fSecondary->push_back(tempSecondaryTrack); 620 ++pushedSecondaries; 626 ++pushedSecondaries; 621 } 627 } 622 else { 628 else { 623 delete tempSecondaryTrack; 629 delete tempSecondaryTrack; 624 } 630 } 625 } 631 } 626 else { 632 else { 627 fSecondary->push_back(tempSecondaryTrack 633 fSecondary->push_back(tempSecondaryTrack); 628 ++pushedSecondaries; 634 ++pushedSecondaries; 629 } 635 } 630 } // end of loop on secondary 636 } // end of loop on secondary 631 637 632 return pushedSecondaries; 638 return pushedSecondaries; 633 } 639 } 634 640 635 ////////////////////////////////////////////// 641 ////////////////////////////////////////////////////// 636 void G4SteppingManager::InvokeAtRestDoItProcs( 642 void G4SteppingManager::InvokeAtRestDoItProcs() 637 ////////////////////////////////////////////// 643 ////////////////////////////////////////////////////// 638 { 644 { 639 // Select the rest process which has the sho 645 // Select the rest process which has the shortest time before 640 // it is invoked. In rest processes, GPIL() 646 // it is invoked. In rest processes, GPIL() 641 // returns the time before a process occurs 647 // returns the time before a process occurs 642 648 643 G4double lifeTime, shortestLifeTime; 649 G4double lifeTime, shortestLifeTime; 644 650 645 fAtRestDoItProcTriggered = 0; 651 fAtRestDoItProcTriggered = 0; 646 shortestLifeTime = DBL_MAX; 652 shortestLifeTime = DBL_MAX; 647 653 648 for (std::size_t ri = 0; ri < MAXofAtRestLoo 654 for (std::size_t ri = 0; ri < MAXofAtRestLoops; ++ri) { 649 fCurrentProcess = (*fAtRestGetPhysIntVecto 655 fCurrentProcess = (*fAtRestGetPhysIntVector)[(G4int)ri]; 650 if (fCurrentProcess == nullptr) { 656 if (fCurrentProcess == nullptr) { 651 (*fSelectedAtRestDoItVector)[ri] = InAct 657 (*fSelectedAtRestDoItVector)[ri] = InActivated; 652 continue; 658 continue; 653 } // nullptr means the process is inactiv 659 } // nullptr means the process is inactivated by a user on fly 654 660 655 lifeTime = fCurrentProcess->AtRestGPIL(*fT 661 lifeTime = fCurrentProcess->AtRestGPIL(*fTrack, &fCondition); 656 662 657 if (fCondition == Forced) { 663 if (fCondition == Forced) { 658 (*fSelectedAtRestDoItVector)[ri] = Force 664 (*fSelectedAtRestDoItVector)[ri] = Forced; 659 } 665 } 660 else { 666 else { 661 (*fSelectedAtRestDoItVector)[ri] = InAct 667 (*fSelectedAtRestDoItVector)[ri] = InActivated; 662 if (lifeTime < shortestLifeTime) { 668 if (lifeTime < shortestLifeTime) { 663 shortestLifeTime = lifeTime; 669 shortestLifeTime = lifeTime; 664 fAtRestDoItProcTriggered = G4int(ri); 670 fAtRestDoItProcTriggered = G4int(ri); 665 fStep->GetPostStepPoint()->SetProcessD 671 fStep->GetPostStepPoint()->SetProcessDefinedStep(fCurrentProcess); 666 } 672 } 667 } 673 } 668 } 674 } 669 675 670 (*fSelectedAtRestDoItVector)[fAtRestDoItProc 676 (*fSelectedAtRestDoItVector)[fAtRestDoItProcTriggered] = NotForced; 671 677 672 fStep->SetStepLength(0.); // the particle h 678 fStep->SetStepLength(0.); // the particle has stopped 673 fTrack->SetStepLength(0.); 679 fTrack->SetStepLength(0.); 674 680 675 // Condition to avoid that stable ions are h 681 // Condition to avoid that stable ions are handled by Radioactive Decay. 676 // We use a very large time threshold (many 682 // We use a very large time threshold (many orders of magnitude bigger than 677 // the universe's age) but not DBL_MAX becau 683 // the universe's age) but not DBL_MAX because shortestLifeTime can be 678 // sometimes slightly smaller for stable ion 684 // sometimes slightly smaller for stable ions. 679 if (shortestLifeTime < 1.0e+100) // Unstabl 685 if (shortestLifeTime < 1.0e+100) // Unstable ion at rest: Radioactive Decay will decay it 680 { 686 { 681 // invoke selected process 687 // invoke selected process 682 // 688 // 683 for (std::size_t np = 0; np < MAXofAtRestL 689 for (std::size_t np = 0; np < MAXofAtRestLoops; ++np) { 684 // 690 // 685 // Note: DoItVector has inverse order ag 691 // Note: DoItVector has inverse order against GetPhysIntVector 686 // and SelectedAtRestDoItVector. 692 // and SelectedAtRestDoItVector. 687 // 693 // 688 if ((*fSelectedAtRestDoItVector)[MAXofAt 694 if ((*fSelectedAtRestDoItVector)[MAXofAtRestLoops - np - 1] != InActivated) { 689 fCurrentProcess = (*fAtRestDoItVector) 695 fCurrentProcess = (*fAtRestDoItVector)[(G4int)np]; 690 fParticleChange = fCurrentProcess->AtR 696 fParticleChange = fCurrentProcess->AtRestDoIt(*fTrack, *fStep); 691 697 692 // Update Step 698 // Update Step 693 // 699 // 694 fParticleChange->UpdateStepForAtRest(f 700 fParticleChange->UpdateStepForAtRest(fStep); 695 701 696 // Now Store the secondaries from Part 702 // Now Store the secondaries from ParticleChange to SecondaryList 697 fN2ndariesAtRestDoIt += ProcessSeconda 703 fN2ndariesAtRestDoIt += ProcessSecondariesFromParticleChange(); 698 704 699 // clear ParticleChange 705 // clear ParticleChange 700 fParticleChange->Clear(); 706 fParticleChange->Clear(); 701 707 702 } // if(fSelectedAtRestDoItVector[np] ! 708 } // if(fSelectedAtRestDoItVector[np] != InActivated){ 703 } // for(std::size_t np=0; np<MAXofAtRest 709 } // for(std::size_t np=0; np<MAXofAtRestLoops; ++np){ 704 } 710 } 705 else // Stable ion at rest 711 else // Stable ion at rest 706 { 712 { 707 fStep->GetPostStepPoint()->SetProcessDefin 713 fStep->GetPostStepPoint()->SetProcessDefinedStep(fNoProcess); 708 } // if(shortestLifeTime < 1.0e+100) 714 } // if(shortestLifeTime < 1.0e+100) 709 715 710 fStep->UpdateTrack(); 716 fStep->UpdateTrack(); 711 717 712 fTrack->SetTrackStatus(fStopAndKill); 718 fTrack->SetTrackStatus(fStopAndKill); 713 } 719 } 714 720 715 ////////////////////////////////////////////// 721 ///////////////////////////////////////////////////////// 716 void G4SteppingManager::InvokeAlongStepDoItPro 722 void G4SteppingManager::InvokeAlongStepDoItProcs() 717 ////////////////////////////////////////////// 723 ///////////////////////////////////////////////////////// 718 { 724 { 719 // If the current Step is defined by a 'Excl 725 // If the current Step is defined by a 'ExclusivelyForced' 720 // PostStepDoIt, then don't invoke any Along 726 // PostStepDoIt, then don't invoke any AlongStepDoIt 721 // 727 // 722 if (fStepStatus == fExclusivelyForcedProc) { 728 if (fStepStatus == fExclusivelyForcedProc) { 723 return; // Take note 'return' is here !!! 729 return; // Take note 'return' is here !!! 724 } 730 } 725 731 726 // Invoke all active continuous processes 732 // Invoke all active continuous processes 727 // 733 // 728 for (std::size_t ci = 0; ci < MAXofAlongStep 734 for (std::size_t ci = 0; ci < MAXofAlongStepLoops; ++ci) { 729 fCurrentProcess = (*fAlongStepDoItVector)[ 735 fCurrentProcess = (*fAlongStepDoItVector)[(G4int)ci]; 730 if (fCurrentProcess == nullptr) continue; 736 if (fCurrentProcess == nullptr) continue; 731 // NULL means the process is inactivated b 737 // NULL means the process is inactivated by a user on fly. 732 738 733 fParticleChange = fCurrentProcess->AlongSt 739 fParticleChange = fCurrentProcess->AlongStepDoIt(*fTrack, *fStep); 734 740 735 // Update the PostStepPoint of Step accord 741 // Update the PostStepPoint of Step according to ParticleChange 736 fParticleChange->UpdateStepForAlongStep(fS 742 fParticleChange->UpdateStepForAlongStep(fStep); 737 743 738 #ifdef G4VERBOSE 744 #ifdef G4VERBOSE 739 if (verboseLevel > 0) fVerbose->AlongStepD 745 if (verboseLevel > 0) fVerbose->AlongStepDoItOneByOne(); 740 #endif 746 #endif 741 747 742 // Now Store the secondaries from Particle 748 // Now Store the secondaries from ParticleChange to SecondaryList 743 fN2ndariesAlongStepDoIt += ProcessSecondar 749 fN2ndariesAlongStepDoIt += ProcessSecondariesFromParticleChange(); 744 750 745 // Set the track status according to what 751 // Set the track status according to what the process defined 746 // if kinetic energy >0, otherwise set fS 752 // if kinetic energy >0, otherwise set fStopButAlive 747 // 753 // 748 fTrack->SetTrackStatus(fParticleChange->Ge 754 fTrack->SetTrackStatus(fParticleChange->GetTrackStatus()); 749 755 750 // clear ParticleChange 756 // clear ParticleChange 751 fParticleChange->Clear(); 757 fParticleChange->Clear(); 752 } 758 } 753 759 754 fStep->UpdateTrack(); 760 fStep->UpdateTrack(); 755 G4TrackStatus fNewStatus = fTrack->GetTrackS 761 G4TrackStatus fNewStatus = fTrack->GetTrackStatus(); 756 762 757 if (fNewStatus == fAlive && fTrack->GetKinet 763 if (fNewStatus == fAlive && fTrack->GetKineticEnergy() <= DBL_MIN) { 758 if (MAXofAtRestLoops > 0) 764 if (MAXofAtRestLoops > 0) 759 fNewStatus = fStopButAlive; 765 fNewStatus = fStopButAlive; 760 else 766 else 761 fNewStatus = fStopAndKill; 767 fNewStatus = fStopAndKill; 762 fTrack->SetTrackStatus(fNewStatus); 768 fTrack->SetTrackStatus(fNewStatus); 763 } 769 } 764 } 770 } 765 771 766 ////////////////////////////////////////////// 772 //////////////////////////////////////////////////////// 767 void G4SteppingManager::InvokePostStepDoItProc 773 void G4SteppingManager::InvokePostStepDoItProcs() 768 ////////////////////////////////////////////// 774 //////////////////////////////////////////////////////// 769 { 775 { 770 // Invoke the specified discrete processes 776 // Invoke the specified discrete processes 771 // 777 // 772 for (std::size_t np = 0; np < MAXofPostStepL 778 for (std::size_t np = 0; np < MAXofPostStepLoops; ++np) { 773 // 779 // 774 // Note: DoItVector has inverse order agai 780 // Note: DoItVector has inverse order against GetPhysIntVector 775 // and SelectedPostStepDoItVector. 781 // and SelectedPostStepDoItVector. 776 // 782 // 777 G4int Cond = (*fSelectedPostStepDoItVector 783 G4int Cond = (*fSelectedPostStepDoItVector)[MAXofPostStepLoops - np - 1]; 778 if (Cond != InActivated) { 784 if (Cond != InActivated) { 779 if (((Cond == NotForced) && (fStepStatus 785 if (((Cond == NotForced) && (fStepStatus == fPostStepDoItProc)) || 780 ((Cond == Forced) && (fStepStatus != 786 ((Cond == Forced) && (fStepStatus != fExclusivelyForcedProc)) || 781 ((Cond == ExclusivelyForced) && (fSt 787 ((Cond == ExclusivelyForced) && (fStepStatus == fExclusivelyForcedProc)) || 782 ((Cond == StronglyForced))) 788 ((Cond == StronglyForced))) 783 { 789 { 784 InvokePSDIP(np); 790 InvokePSDIP(np); 785 if ((np == 0) && (fTrack->GetNextVolum 791 if ((np == 0) && (fTrack->GetNextVolume() == nullptr)) { 786 fStepStatus = fWorldBoundary; 792 fStepStatus = fWorldBoundary; 787 fStep->GetPostStepPoint()->SetStepSt 793 fStep->GetPostStepPoint()->SetStepStatus(fStepStatus); 788 } 794 } 789 } 795 } 790 } 796 } 791 797 792 // Exit from PostStepLoop if the track has 798 // Exit from PostStepLoop if the track has been killed, 793 // but extra treatment for processes with 799 // but extra treatment for processes with Strongly Forced flag 794 // 800 // 795 if (fTrack->GetTrackStatus() == fStopAndKi 801 if (fTrack->GetTrackStatus() == fStopAndKill) { 796 for (std::size_t np1 = np + 1; np1 < MAX 802 for (std::size_t np1 = np + 1; np1 < MAXofPostStepLoops; ++np1) { 797 G4int Cond2 = (*fSelectedPostStepDoItV 803 G4int Cond2 = (*fSelectedPostStepDoItVector)[MAXofPostStepLoops - np1 - 1]; 798 if (Cond2 == StronglyForced) { 804 if (Cond2 == StronglyForced) { 799 InvokePSDIP(np1); 805 InvokePSDIP(np1); 800 } 806 } 801 } 807 } 802 break; 808 break; 803 } 809 } 804 } 810 } 805 } 811 } 806 812 807 ////////////////////////////////////////////// 813 //////////////////////////////////////////////////////// 808 void G4SteppingManager::InvokePSDIP(size_t np) 814 void G4SteppingManager::InvokePSDIP(size_t np) 809 ////////////////////////////////////////////// 815 //////////////////////////////////////////////////////// 810 { 816 { 811 fCurrentProcess = (*fPostStepDoItVector)[(G4 817 fCurrentProcess = (*fPostStepDoItVector)[(G4int)np]; 812 fParticleChange = fCurrentProcess->PostStepD 818 fParticleChange = fCurrentProcess->PostStepDoIt(*fTrack, *fStep); 813 819 814 // Update PostStepPoint of Step according to 820 // Update PostStepPoint of Step according to ParticleChange 815 fParticleChange->UpdateStepForPostStep(fStep 821 fParticleChange->UpdateStepForPostStep(fStep); 816 822 817 #ifdef G4VERBOSE 823 #ifdef G4VERBOSE 818 if (verboseLevel > 0) fVerbose->PostStepDoIt 824 if (verboseLevel > 0) fVerbose->PostStepDoItOneByOne(); 819 #endif 825 #endif 820 826 821 // Update G4Track according to ParticleChang 827 // Update G4Track according to ParticleChange after each PostStepDoIt 822 fStep->UpdateTrack(); 828 fStep->UpdateTrack(); 823 829 824 // Update safety after each invocation of Po 830 // Update safety after each invocation of PostStepDoIts 825 fStep->GetPostStepPoint()->SetSafety(Calcula 831 fStep->GetPostStepPoint()->SetSafety(CalculateSafety()); 826 832 827 // Now Store the secondaries from ParticleCh 833 // Now Store the secondaries from ParticleChange to SecondaryList 828 fN2ndariesPostStepDoIt += ProcessSecondaries 834 fN2ndariesPostStepDoIt += ProcessSecondariesFromParticleChange(); 829 835 830 // Set the track status according to what th 836 // Set the track status according to what the process defined 831 fTrack->SetTrackStatus(fParticleChange->GetT 837 fTrack->SetTrackStatus(fParticleChange->GetTrackStatus()); 832 838 833 // clear ParticleChange 839 // clear ParticleChange 834 fParticleChange->Clear(); 840 fParticleChange->Clear(); 835 } 841 } 836 842