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 // $Id: G4SteppingManager.cc 95198 2016-01-29 08:28:27Z gcosmo $ >> 28 // >> 29 //--------------------------------------------------------------- >> 30 // >> 31 // G4SteppingManager.cc >> 32 // >> 33 // Description: >> 34 // This class represents the manager who steers to move the give >> 35 // particle from the TrackingManger by one Step. 27 // 36 // 28 // Contact: 37 // Contact: 29 // Questions and comments to this code shoul 38 // Questions and comments to this code should be sent to 30 // Katsuya Amako (e-mail: Katsuya.Amako@k 39 // Katsuya Amako (e-mail: Katsuya.Amako@kek.jp) 31 // Takashi Sasaki (e-mail: Takashi.Sasaki@ 40 // Takashi Sasaki (e-mail: Takashi.Sasaki@kek.jp) 32 // ------------------------------------------- << 41 // >> 42 //--------------------------------------------------------------- 33 43 34 #include "G4SteppingManager.hh" 44 #include "G4SteppingManager.hh" 35 << 45 #include "G4SteppingVerbose.hh" >> 46 #include "G4UImanager.hh" 36 #include "G4ForceCondition.hh" 47 #include "G4ForceCondition.hh" 37 #include "G4GPILSelection.hh" 48 #include "G4GPILSelection.hh" 38 #include "G4GeometryTolerance.hh" << 39 #include "G4ParticleTable.hh" << 40 #include "G4SteppingControl.hh" 49 #include "G4SteppingControl.hh" 41 #include "G4SteppingVerbose.hh" << 42 #include "G4SteppingVerboseWithUnits.hh" << 43 #include "G4TransportationManager.hh" 50 #include "G4TransportationManager.hh" 44 #include "G4UImanager.hh" << 45 #include "G4UserLimits.hh" 51 #include "G4UserLimits.hh" 46 #include "G4VSensitiveDetector.hh" // Include << 52 #include "G4VSensitiveDetector.hh" // Include from 'hits/digi' 47 << 53 #include "G4GeometryTolerance.hh" 48 // #define debug << 49 54 50 ////////////////////////////////////// 55 ////////////////////////////////////// 51 G4SteppingManager::G4SteppingManager() 56 G4SteppingManager::G4SteppingManager() 52 ////////////////////////////////////// 57 ////////////////////////////////////// >> 58 : fUserSteppingAction(0), verboseLevel(0) 53 { 59 { 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 60 86 fSelectedAtRestDoItVector = new G4SelectedAt << 61 // Construct simple 'has-a' related objects 87 fSelectedAlongStepDoItVector = new G4Selecte << 62 fStep = new G4Step(); 88 fSelectedPostStepDoItVector = new G4Selected << 63 fSecondary = fStep->NewSecondaryVector(); >> 64 fPreStepPoint = fStep->GetPreStepPoint(); >> 65 fPostStepPoint = fStep->GetPostStepPoint(); >> 66 #ifdef G4VERBOSE >> 67 if(G4VSteppingVerbose::GetInstance()==0) { >> 68 fVerbose = new G4SteppingVerbose(); >> 69 G4VSteppingVerbose::SetInstance(fVerbose); >> 70 fVerbose -> SetManager(this); >> 71 KillVerbose = true; >> 72 } >> 73 else { >> 74 fVerbose = G4VSteppingVerbose::GetInstance(); >> 75 fVerbose -> SetManager(this); >> 76 KillVerbose = false; >> 77 } >> 78 #endif >> 79 SetNavigator(G4TransportationManager::GetTransportationManager() >> 80 ->GetNavigatorForTracking()); >> 81 >> 82 fSelectedAtRestDoItVector >> 83 = new G4SelectedAtRestDoItVector(SizeOfSelectedDoItVector,0); >> 84 fSelectedAlongStepDoItVector >> 85 = new G4SelectedAlongStepDoItVector(SizeOfSelectedDoItVector,0); >> 86 fSelectedPostStepDoItVector >> 87 = new G4SelectedPostStepDoItVector(SizeOfSelectedDoItVector,0); 89 88 90 SetNavigator(G4TransportationManager::GetTra << 89 SetNavigator(G4TransportationManager::GetTransportationManager() >> 90 ->GetNavigatorForTracking()); 91 91 92 physIntLength = DBL_MAX; << 92 physIntLength = DBL_MAX; 93 kCarTolerance = 0.5 * G4GeometryTolerance::G << 93 kCarTolerance = 0.5*G4GeometryTolerance::GetInstance()->GetSurfaceTolerance(); 94 << 95 fNoProcess = new G4NoProcess; << 96 } 94 } 97 95 98 /////////////////////////////////////// 96 /////////////////////////////////////// 99 G4SteppingManager::~G4SteppingManager() 97 G4SteppingManager::~G4SteppingManager() 100 /////////////////////////////////////// 98 /////////////////////////////////////// 101 { 99 { 102 fTouchableHandle = nullptr; << 100 fTouchableHandle = 0; 103 << 101 // Destruct simple 'has-a' objects 104 // Destruct simple 'has-a' objects << 102 fStep->DeleteSecondaryVector(); 105 // << 103 /////////////////////////// delete fSecondary; 106 fStep->DeleteSecondaryVector(); << 104 delete fStep; 107 << 105 delete fSelectedAtRestDoItVector; 108 // delete fSecondary; << 106 delete fSelectedAlongStepDoItVector; 109 delete fStep; << 107 delete fSelectedPostStepDoItVector; 110 delete fSelectedAtRestDoItVector; << 108 if (fUserSteppingAction) delete fUserSteppingAction; 111 delete fSelectedAlongStepDoItVector; << 112 delete fSelectedPostStepDoItVector; << 113 delete fUserSteppingAction; << 114 #ifdef G4VERBOSE 109 #ifdef G4VERBOSE 115 if (KillVerbose) delete fVerbose; << 110 if(KillVerbose) delete fVerbose; 116 #endif 111 #endif 117 } 112 } 118 113 >> 114 119 ////////////////////////////////////////// 115 ////////////////////////////////////////// 120 G4StepStatus G4SteppingManager::Stepping() 116 G4StepStatus G4SteppingManager::Stepping() 121 ////////////////////////////////////////// 117 ////////////////////////////////////////// 122 { 118 { >> 119 123 //-------- 120 //-------- 124 // Prelude 121 // Prelude 125 //-------- 122 //-------- 126 #ifdef G4VERBOSE 123 #ifdef G4VERBOSE 127 if (verboseLevel > 0) { << 124 // !!!!! Verbose 128 fVerbose->NewStep(); << 125 if(verboseLevel>0) fVerbose->NewStep(); 129 } << 126 else 130 else if (verboseLevel == -1) { << 127 if(verboseLevel==-1) { 131 G4VSteppingVerbose::SetSilent(1); << 128 G4VSteppingVerbose::SetSilent(1); 132 } << 129 } 133 else { << 130 else 134 G4VSteppingVerbose::SetSilent(0); << 131 G4VSteppingVerbose::SetSilent(0); 135 } << 132 #endif 136 #endif << 137 133 138 // Store last PostStepPoint to PreStepPoint, << 134 // Store last PostStepPoint to PreStepPoint, and swap current and nex 139 // volume information of G4Track. Reset tota << 135 // volume information of G4Track. Reset total energy deposit in one Step. 140 // << 136 fStep->CopyPostToPreStepPoint(); 141 fStep->CopyPostToPreStepPoint(); << 137 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 138 172 #ifdef G4VERBOSE << 139 // Switch next touchable in track to current one 173 if (verboseLevel > 0) fVerbose->AtRestDo << 140 fTrack->SetTouchableHandle(fTrack->GetNextTouchableHandle()); 174 #endif << 175 } << 176 // Make sure the track is killed << 177 // << 178 fTrack->SetTrackStatus(fStopAndKill); << 179 } << 180 141 181 //--------------------------------- << 142 // Reset the secondary particles 182 // AlongStep and PostStep Processes << 143 fN2ndariesAtRestDoIt = 0; 183 //--------------------------------- << 144 fN2ndariesAlongStepDoIt = 0; 184 << 145 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 146 212 fStep->GetPostStepPoint()->SetSafety(endpo << 147 //JA Set the volume before it is used (in DefineStepLength() for User Limit) >> 148 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 213 149 214 #ifdef G4VERBOSE << 150 // Reset the step's auxiliary points vector pointer 215 if (verboseLevel > 0) fVerbose->AlongStepD << 151 fStep->SetPointerToVectorOfAuxiliaryPoints(0); 216 #endif << 217 152 218 // Invoke PostStepDoIt << 153 //----------------- 219 InvokePostStepDoItProcs(); << 154 // AtRest Processes >> 155 //----------------- 220 156 >> 157 if( fTrack->GetTrackStatus() == fStopButAlive ){ >> 158 if( MAXofAtRestLoops>0 ){ >> 159 InvokeAtRestDoItProcs(); >> 160 fStepStatus = fAtRestDoItProc; >> 161 fStep->GetPostStepPoint()->SetStepStatus( fStepStatus ); >> 162 221 #ifdef G4VERBOSE 163 #ifdef G4VERBOSE 222 if (verboseLevel > 0) fVerbose->PostStepDo << 164 // !!!!! Verbose 223 #endif << 165 if(verboseLevel>0) fVerbose->AtRestDoItInvoked(); 224 } << 166 #endif 225 167 226 //------- << 168 } 227 // Finale << 169 // Make sure the track is killed 228 //------- << 170 fTrack->SetTrackStatus( fStopAndKill ); 229 << 171 } 230 // Update 'TrackLength' and remeber the Step << 231 // << 232 fTrack->AddTrackLength(fStep->GetStepLength( << 233 fPreviousStepSize = fStep->GetStepLength(); << 234 fStep->SetTrack(fTrack); << 235 172 236 #ifdef G4VERBOSE << 173 //--------------------------------- 237 if (verboseLevel > 0) fVerbose->StepInfo(); << 174 // AlongStep and PostStep Processes 238 #endif << 175 //--------------------------------- 239 176 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 177 251 // User intervention process << 178 else{ 252 // << 179 // Find minimum Step length demanded by active disc./cont. processes 253 if (fUserSteppingAction != nullptr) { << 180 DefinePhysicalStepLength(); 254 fUserSteppingAction->UserSteppingAction(fS << 255 } << 256 181 257 G4UserSteppingAction* regionalAction = << 182 // Store the Step length (geometrical length) to G4Step and G4Track 258 fCurrentVolume->GetLogicalVolume()->GetReg << 183 fStep->SetStepLength( PhysicalStep ); >> 184 fTrack->SetStepLength( PhysicalStep ); >> 185 G4double GeomStepLength = PhysicalStep; 259 186 260 if (regionalAction != nullptr) regionalActio << 187 // Store StepStatus to PostStepPoint >> 188 fStep->GetPostStepPoint()->SetStepStatus( fStepStatus ); 261 189 262 // Stepping process finish. Return the value << 190 // Invoke AlongStepDoIt 263 // << 191 InvokeAlongStepDoItProcs(); 264 return fStepStatus; << 265 } << 266 192 267 ////////////////////////////////////////////// << 193 // Update track by taking into account all changes by AlongStepDoIt 268 void G4SteppingManager::SetInitialStep(G4Track << 194 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 195 300 // If the primary track has 'zero' kinetic e << 196 // Update safety after invocation of all AlongStepDoIts 301 // state to 'StopButAlive' << 197 endpointSafOrigin= fPostStepPoint->GetPosition(); 302 // << 198 // endpointSafety= std::max( proposedSafety - GeomStepLength, 0.); 303 if (fTrack->GetKineticEnergy() <= 0.0) { << 199 endpointSafety= std::max( proposedSafety - GeomStepLength, kCarTolerance); 304 fTrack->SetTrackStatus(fStopButAlive); << 305 } << 306 200 307 // Set Touchable to track and a private attr << 201 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 202 368 #ifdef G4VERBOSE 203 #ifdef G4VERBOSE 369 if (verboseLevel > 0) fVerbose->TrackingStar << 204 // !!!!! Verbose 370 #endif << 205 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 206 #endif 411 207 412 // PostStepDoits << 208 // Invoke PostStepDoIt 413 // << 209 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 210 451 #ifdef G4VERBOSE 211 #ifdef G4VERBOSE 452 if (verboseLevel > 0) fVerbose->DPSLStarted( << 212 // !!!!! Verbose >> 213 if(verboseLevel>0) fVerbose->PostStepDoItAllDone(); 453 #endif 214 #endif >> 215 } 454 216 455 // GPIL for PostStep << 217 //------- 456 // << 218 // Finale 457 fPostStepDoItProcTriggered = MAXofPostStepLo << 219 //------- 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 220 466 physIntLength = fCurrentProcess->PostStepG << 221 // Update 'TrackLength' and remeber the Step length of the current Step >> 222 fTrack->AddTrackLength(fStep->GetStepLength()); >> 223 fPreviousStepSize = fStep->GetStepLength(); >> 224 fStep->SetTrack(fTrack); 467 #ifdef G4VERBOSE 225 #ifdef G4VERBOSE 468 if (verboseLevel > 0) fVerbose->DPSLPostSt << 226 // !!!!! Verbose 469 #endif << 470 227 471 switch (fCondition) { << 228 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 229 #endif 530 << 230 // Send G4Step information to Hit/Dig if the volume is sensitive 531 if (physIntLength < PhysicalStep) { << 231 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 532 PhysicalStep = physIntLength; << 232 StepControlFlag = fStep->GetControlFlag(); 533 << 233 if( fCurrentVolume != 0 && StepControlFlag != AvoidHitInvocation) { 534 // Check if the process wants to be the << 234 fSensitive = fStep->GetPreStepPoint()-> 535 // multi-scattering proposes Step limit, << 235 GetSensitiveDetector(); 536 // << 236 if( fSensitive != 0 ) { 537 if (fGPILSelection == CandidateForSelect << 237 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 } 238 } 555 } << 239 } 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 240 577 ////////////////////////////////////////////// << 241 // User intervention process. 578 G4int G4SteppingManager::ProcessSecondariesFro << 242 if( fUserSteppingAction != 0 ) { 579 ////////////////////////////////////////////// << 243 fUserSteppingAction->UserSteppingAction(fStep); 580 { << 244 } 581 G4Track* tempSecondaryTrack; << 245 G4UserSteppingAction* regionalAction 582 G4int num2ndaries; << 246 = fStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion() 583 G4int pushedSecondaries = 0; << 247 ->GetRegionalSteppingAction(); 584 << 248 if( regionalAction ) regionalAction->UserSteppingAction(fStep); 585 num2ndaries = fParticleChange->GetNumberOfSe << 586 if (num2ndaries == 0) { << 587 return 0; << 588 } << 589 249 590 // Get the creator process. This may be diff << 250 // Stepping process finish. Return the value of the StepStatus. 591 // "combined" process such as G4GammaGeneral << 251 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 252 632 return pushedSecondaries; << 633 } 253 } 634 254 635 ////////////////////////////////////////////// << 255 /////////////////////////////////////////////////////////// 636 void G4SteppingManager::InvokeAtRestDoItProcs( << 256 void G4SteppingManager::SetInitialStep(G4Track* valueTrack) 637 ////////////////////////////////////////////// << 257 /////////////////////////////////////////////////////////// 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 { 258 { 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 259 >> 260 // Set up several local variables. >> 261 PreStepPointIsGeom = false; >> 262 FirstStep = true; >> 263 fParticleChange = 0; >> 264 fPreviousStepSize = 0.; >> 265 fStepStatus = fUndefined; >> 266 >> 267 fTrack = valueTrack; >> 268 Mass = fTrack->GetDynamicParticle()->GetMass(); >> 269 >> 270 PhysicalStep = 0.; >> 271 GeometricalStep = 0.; >> 272 CorrectedStep = 0.; >> 273 PreStepPointIsGeom = false; >> 274 FirstStep = false; >> 275 fStepStatus = fUndefined; >> 276 >> 277 TempInitVelocity = 0.; >> 278 TempVelocity = 0.; >> 279 sumEnergyChange = 0.; >> 280 >> 281 >> 282 // If the primary track has 'Suspend' or 'PostponeToNextEvent' state, >> 283 // set the track state to 'Alive'. >> 284 if( (fTrack->GetTrackStatus()==fSuspend) || >> 285 (fTrack->GetTrackStatus()==fPostponeToNextEvent) ){ >> 286 fTrack->SetTrackStatus(fAlive); >> 287 } >> 288 >> 289 // If the primary track has 'zero' kinetic energy, set the track >> 290 // state to 'StopButAlive'. >> 291 if(fTrack->GetKineticEnergy() <= 0.0){ >> 292 fTrack->SetTrackStatus( fStopButAlive ); >> 293 } >> 294 >> 295 >> 296 // Set Touchable to track and a private attribute of G4SteppingManager >> 297 >> 298 >> 299 if ( ! fTrack->GetTouchableHandle() ) { >> 300 G4ThreeVector direction= fTrack->GetMomentumDirection(); >> 301 fNavigator->LocateGlobalPointAndSetup( fTrack->GetPosition(), >> 302 &direction, false, false ); >> 303 fTouchableHandle = fNavigator->CreateTouchableHistory(); >> 304 >> 305 fTrack->SetTouchableHandle( fTouchableHandle ); >> 306 fTrack->SetNextTouchableHandle( fTouchableHandle ); >> 307 }else{ >> 308 fTrack->SetNextTouchableHandle( fTouchableHandle = fTrack->GetTouchableHandle() ); >> 309 G4VPhysicalVolume* oldTopVolume= fTrack->GetTouchableHandle()->GetVolume(); >> 310 G4VPhysicalVolume* newTopVolume= >> 311 fNavigator->ResetHierarchyAndLocate( fTrack->GetPosition(), >> 312 fTrack->GetMomentumDirection(), >> 313 *((G4TouchableHistory*)fTrack->GetTouchableHandle()()) ); >> 314 // if(newTopVolume != oldTopVolume ){ >> 315 if(newTopVolume != oldTopVolume || oldTopVolume->GetRegularStructureId() == 1 ) { >> 316 fTouchableHandle = fNavigator->CreateTouchableHistory(); >> 317 fTrack->SetTouchableHandle( fTouchableHandle ); >> 318 fTrack->SetNextTouchableHandle( fTouchableHandle ); >> 319 } >> 320 } >> 321 // Set OriginTouchableHandle for primary track >> 322 if(fTrack->GetParentID()==0){ >> 323 fTrack->SetOriginTouchableHandle(fTrack->GetTouchableHandle()); >> 324 } >> 325 >> 326 // Set vertex information of G4Track at here >> 327 if ( fTrack->GetCurrentStepNumber() == 0 ) { >> 328 fTrack->SetVertexPosition( fTrack->GetPosition() ); >> 329 fTrack->SetVertexMomentumDirection( fTrack->GetMomentumDirection() ); >> 330 fTrack->SetVertexKineticEnergy( fTrack->GetKineticEnergy() ); >> 331 fTrack->SetLogicalVolumeAtVertex( fTrack->GetVolume()->GetLogicalVolume() ); >> 332 } >> 333 // Initial set up for attributes of 'G4SteppingManager' >> 334 fCurrentVolume = fTouchableHandle->GetVolume(); >> 335 >> 336 // If track is already outside the world boundary, kill it >> 337 if( fCurrentVolume==0 ){ >> 338 // If the track is a primary, stop processing >> 339 if(fTrack->GetParentID()==0) >> 340 { >> 341 G4cerr << "ERROR - G4SteppingManager::SetInitialStep()" << G4endl >> 342 << " Primary particle starting at - " >> 343 << fTrack->GetPosition() >> 344 << " - is outside of the world volume." << G4endl; >> 345 G4Exception("G4SteppingManager::SetInitialStep()", "Tracking0010", >> 346 FatalException, "Primary vertex outside of the world!"); >> 347 } >> 348 >> 349 fTrack->SetTrackStatus( fStopAndKill ); >> 350 G4cout << "WARNING - G4SteppingManager::SetInitialStep()" << G4endl >> 351 << " Initial track position is outside world! - " >> 352 << fTrack->GetPosition() << G4endl; >> 353 } >> 354 else { >> 355 // Initial set up for attribues of 'Step' >> 356 fStep->InitializeStep( fTrack ); >> 357 } 738 #ifdef G4VERBOSE 358 #ifdef G4VERBOSE 739 if (verboseLevel > 0) fVerbose->AlongStepD << 359 // !!!!! Verbose >> 360 if(verboseLevel>0) fVerbose->TrackingStarted(); 740 #endif 361 #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 } 362 } 765 363 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 364