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