Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer << 3 // * DISCLAIMER * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th << 5 // * The following disclaimer summarizes all the specific disclaimers * 6 // * the Geant4 Collaboration. It is provided << 6 // * of contributors to this software. The specific disclaimers,which * 7 // * conditions of the Geant4 Software License << 7 // * govern, are listed with their locations in: * 8 // * LICENSE and available at http://cern.ch/ << 8 // * http://cern.ch/geant4/license * 9 // * include a list of copyright holders. << 10 // * 9 // * * 11 // * Neither the authors of this software syst 10 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 11 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 12 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 13 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file << 14 // * use. * 16 // * for the full disclaimer and the limitatio << 17 // * 15 // * * 18 // * This code implementation is the result << 16 // * This code implementation is the intellectual property of the * 19 // * technical work of the GEANT4 collaboratio << 17 // * GEANT4 collaboration. * 20 // * By using, copying, modifying or distri << 18 // * By copying, distributing or modifying the Program (or any work * 21 // * any work based on the software) you ag << 19 // * based on the Program) you indicate your acceptance of this * 22 // * use in resulting scientific publicati << 20 // * statement, and all its terms. * 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* 21 // ******************************************************************** 25 // 22 // 26 // G4SteppingManager class implementation << 23 // >> 24 // $Id: G4SteppingManager.cc,v 1.32 2003/11/10 08:52:33 gcosmo Exp $ >> 25 // GEANT4 tag $Name: geant4-06-00-patch-01 $ >> 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 << 48 // #define debug << 49 52 50 ////////////////////////////////////// 53 ////////////////////////////////////// 51 G4SteppingManager::G4SteppingManager() 54 G4SteppingManager::G4SteppingManager() 52 ////////////////////////////////////// 55 ////////////////////////////////////// >> 56 : fUserSteppingAction(NULL), verboseLevel(0) 53 { 57 { 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 << 86 fSelectedAtRestDoItVector = new G4SelectedAt << 87 fSelectedAlongStepDoItVector = new G4Selecte << 88 fSelectedPostStepDoItVector = new G4Selected << 89 58 90 SetNavigator(G4TransportationManager::GetTra << 59 // Construct simple 'has-a' related objects >> 60 fSecondary = new G4TrackVector(); >> 61 fStep = new G4Step(); >> 62 fPreStepPoint = fStep->GetPreStepPoint(); >> 63 fPostStepPoint = fStep->GetPostStepPoint(); >> 64 #ifdef G4VERBOSE >> 65 if(G4VSteppingVerbose::GetInstance()==0) { >> 66 fVerbose = new G4SteppingVerbose(); >> 67 G4VSteppingVerbose::SetInstance(fVerbose); >> 68 fVerbose -> SetManager(this); >> 69 KillVerbose = true; >> 70 } >> 71 else { >> 72 fVerbose = G4VSteppingVerbose::GetInstance(); >> 73 fVerbose -> SetManager(this); >> 74 KillVerbose = false; >> 75 } >> 76 #endif >> 77 SetNavigator(G4TransportationManager::GetTransportationManager() >> 78 ->GetNavigatorForTracking()); >> 79 >> 80 fSelectedAtRestDoItVector >> 81 = new G4SelectedAtRestDoItVector(SizeOfSelectedDoItVector,0); >> 82 fSelectedAlongStepDoItVector >> 83 = new G4SelectedAlongStepDoItVector(SizeOfSelectedDoItVector,0); >> 84 fSelectedPostStepDoItVector >> 85 = new G4SelectedPostStepDoItVector(SizeOfSelectedDoItVector,0); 91 86 92 physIntLength = DBL_MAX; << 87 SetNavigator(G4TransportationManager::GetTransportationManager() 93 kCarTolerance = 0.5 * G4GeometryTolerance::G << 88 ->GetNavigatorForTracking()); 94 89 95 fNoProcess = new G4NoProcess; << 90 physIntLength = DBL_MAX; >> 91 // fTouchableHandle = new G4TouchableHistory(); 96 } 92 } 97 93 98 /////////////////////////////////////// 94 /////////////////////////////////////// 99 G4SteppingManager::~G4SteppingManager() 95 G4SteppingManager::~G4SteppingManager() 100 /////////////////////////////////////// 96 /////////////////////////////////////// 101 { 97 { 102 fTouchableHandle = nullptr; << 103 98 104 // Destruct simple 'has-a' objects << 99 // Destruct simple 'has-a' objects 105 // << 100 delete fSecondary; 106 fStep->DeleteSecondaryVector(); << 101 delete fStep; 107 << 102 delete fSelectedAtRestDoItVector; 108 // delete fSecondary; << 103 delete fSelectedAlongStepDoItVector; 109 delete fStep; << 104 delete fSelectedPostStepDoItVector; 110 delete fSelectedAtRestDoItVector; << 105 if (fUserSteppingAction) delete fUserSteppingAction; 111 delete fSelectedAlongStepDoItVector; << 112 delete fSelectedPostStepDoItVector; << 113 delete fUserSteppingAction; << 114 #ifdef G4VERBOSE 106 #ifdef G4VERBOSE 115 if (KillVerbose) delete fVerbose; << 107 if(KillVerbose) delete fVerbose; 116 #endif 108 #endif 117 } 109 } 118 110 >> 111 119 ////////////////////////////////////////// 112 ////////////////////////////////////////// 120 G4StepStatus G4SteppingManager::Stepping() 113 G4StepStatus G4SteppingManager::Stepping() 121 ////////////////////////////////////////// 114 ////////////////////////////////////////// 122 { 115 { >> 116 123 //-------- 117 //-------- 124 // Prelude 118 // Prelude 125 //-------- 119 //-------- 126 #ifdef G4VERBOSE 120 #ifdef G4VERBOSE 127 if (verboseLevel > 0) { << 121 // !!!!! Verbose 128 fVerbose->NewStep(); << 122 if(verboseLevel>0) fVerbose->NewStep(); 129 } << 123 #endif 130 else if (verboseLevel == -1) { << 131 G4VSteppingVerbose::SetSilent(1); << 132 } << 133 else { << 134 G4VSteppingVerbose::SetSilent(0); << 135 } << 136 #endif << 137 124 138 // Store last PostStepPoint to PreStepPoint, << 125 // Store last PostStepPoint to PreStepPoint, and swap current and nex 139 // volume information of G4Track. Reset tota << 126 // volume information of G4Track. Reset total energy deposit in one Step. 140 // << 127 fStep->CopyPostToPreStepPoint(); 141 fStep->CopyPostToPreStepPoint(); << 128 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 129 172 #ifdef G4VERBOSE << 130 // Switch next touchable in track to current one 173 if (verboseLevel > 0) fVerbose->AtRestDo << 131 fTrack->SetTouchableHandle(fTrack->GetNextTouchableHandle()); 174 #endif << 175 } << 176 // Make sure the track is killed << 177 // << 178 fTrack->SetTrackStatus(fStopAndKill); << 179 } << 180 << 181 //--------------------------------- << 182 // AlongStep and PostStep Processes << 183 //--------------------------------- << 184 << 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 132 212 fStep->GetPostStepPoint()->SetSafety(endpo << 133 // Reset the secondary particles >> 134 fN2ndariesAtRestDoIt = 0; >> 135 fN2ndariesAlongStepDoIt = 0; >> 136 fN2ndariesPostStepDoIt = 0; 213 137 214 #ifdef G4VERBOSE << 138 //JA Set the volume before it is used (in DefineStepLength() for User Limit) 215 if (verboseLevel > 0) fVerbose->AlongStepD << 139 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 216 #endif << 217 140 218 // Invoke PostStepDoIt << 141 //----------------- 219 InvokePostStepDoItProcs(); << 142 // AtRest Processes >> 143 //----------------- 220 144 >> 145 if( fTrack->GetTrackStatus() == fStopButAlive ){ >> 146 if( MAXofAtRestLoops>0 ){ >> 147 InvokeAtRestDoItProcs(); >> 148 fStepStatus = fAtRestDoItProc; >> 149 fStep->GetPostStepPoint()->SetStepStatus( fStepStatus ); >> 150 221 #ifdef G4VERBOSE 151 #ifdef G4VERBOSE 222 if (verboseLevel > 0) fVerbose->PostStepDo << 152 // !!!!! Verbose 223 #endif << 153 if(verboseLevel>0) fVerbose->AtRestDoItInvoked(); 224 } << 154 #endif 225 << 226 //------- << 227 // Finale << 228 //------- << 229 << 230 // Update 'TrackLength' and remeber the Step << 231 // << 232 fTrack->AddTrackLength(fStep->GetStepLength( << 233 fPreviousStepSize = fStep->GetStepLength(); << 234 fStep->SetTrack(fTrack); << 235 << 236 #ifdef G4VERBOSE << 237 if (verboseLevel > 0) fVerbose->StepInfo(); << 238 #endif << 239 << 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 << 251 // User intervention process << 252 // << 253 if (fUserSteppingAction != nullptr) { << 254 fUserSteppingAction->UserSteppingAction(fS << 255 } << 256 << 257 G4UserSteppingAction* regionalAction = << 258 fCurrentVolume->GetLogicalVolume()->GetReg << 259 << 260 if (regionalAction != nullptr) regionalActio << 261 << 262 // Stepping process finish. Return the value << 263 // << 264 return fStepStatus; << 265 } << 266 << 267 ////////////////////////////////////////////// << 268 void G4SteppingManager::SetInitialStep(G4Track << 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 << 300 // If the primary track has 'zero' kinetic e << 301 // state to 'StopButAlive' << 302 // << 303 if (fTrack->GetKineticEnergy() <= 0.0) { << 304 fTrack->SetTrackStatus(fStopButAlive); << 305 } << 306 << 307 // Set Touchable to track and a private attr << 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 << 368 #ifdef G4VERBOSE << 369 if (verboseLevel > 0) fVerbose->TrackingStar << 370 #endif << 371 } << 372 << 373 ////////////////////////////////////////////// << 374 void G4SteppingManager::GetProcessNumber() << 375 ////////////////////////////////////////////// << 376 { << 377 #ifdef debug << 378 G4cout << "G4SteppingManager::GetProcessNumb << 379 #endif << 380 155 381 G4ProcessManager* pm = fTrack->GetDefinition << 156 } 382 if (pm == nullptr) { << 157 // Make sure the track is killed 383 G4cerr << "ERROR - G4SteppingManager::GetP << 158 fTrack->SetTrackStatus( fStopAndKill ); 384 << " ProcessManager is NULL << 159 } 385 << fTrack->GetDefinition()->GetPart << 386 << ", PDG_code = " << fTrack->GetDe << 387 G4Exception("G4SteppingManager::GetProcess << 388 "Process Manager is not found."); << 389 return; << 390 } << 391 160 392 // AtRestDoits << 161 //--------------------------------- 393 // << 162 // AlongStep and PostStep Processes 394 MAXofAtRestLoops = pm->GetAtRestProcessVecto << 163 //--------------------------------- 395 fAtRestDoItVector = pm->GetAtRestProcessVect << 396 fAtRestGetPhysIntVector = pm->GetAtRestProce << 397 164 398 #ifdef debug << 399 G4cout << "G4SteppingManager::GetProcessNumb << 400 #endif << 401 165 402 // AlongStepDoits << 166 else{ 403 // << 167 // Find minimum Step length demanded by active disc./cont. processes 404 MAXofAlongStepLoops = pm->GetAlongStepProces << 168 DefinePhysicalStepLength(); 405 fAlongStepDoItVector = pm->GetAlongStepProce << 406 fAlongStepGetPhysIntVector = pm->GetAlongSte << 407 169 408 #ifdef debug << 170 // Store the Step length (geometrical length) to G4Step and G4Track 409 G4cout << "G4SteppingManager::GetProcessNumb << 171 fStep->SetStepLength( PhysicalStep ); 410 #endif << 172 fTrack->SetStepLength( PhysicalStep ); >> 173 G4double GeomStepLength = PhysicalStep; 411 174 412 // PostStepDoits << 175 // Store StepStatus to PostStepPoint 413 // << 176 fStep->GetPostStepPoint()->SetStepStatus( fStepStatus ); 414 MAXofPostStepLoops = pm->GetPostStepProcessV << 415 fPostStepDoItVector = pm->GetPostStepProcess << 416 fPostStepGetPhysIntVector = pm->GetPostStepP << 417 177 418 #ifdef debug << 178 // Invoke AlongStepDoIt 419 G4cout << "G4SteppingManager::GetProcessNumb << 179 InvokeAlongStepDoItProcs(); 420 #endif << 421 180 422 if (SizeOfSelectedDoItVector < MAXofAtRestLo << 181 // Update track by taking into account all changes by AlongStepDoIt 423 SizeOfSelectedDoItVector < MAXofAlongSte << 182 fStep->UpdateTrack(); 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 183 436 // ******************************************* << 184 // Update safety after invocation of all AlongStepDoIts 437 // << 185 endpointSafOrigin= fPostStepPoint->GetPosition(); 438 // Private Member Functions << 186 endpointSafety= std::max( proposedSafety - GeomStepLength, 0.); 439 // << 440 // ******************************************* << 441 187 442 ////////////////////////////////////////////// << 188 fStep->GetPostStepPoint()->SetSafety( endpointSafety ); 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 189 451 #ifdef G4VERBOSE 190 #ifdef G4VERBOSE 452 if (verboseLevel > 0) fVerbose->DPSLStarted( << 191 // !!!!! Verbose >> 192 if(verboseLevel>0) fVerbose->AlongStepDoItAllDone(); 453 #endif 193 #endif 454 194 455 // GPIL for PostStep << 195 // Invoke PostStepDoIt 456 // << 196 InvokePostStepDoItProcs(); 457 fPostStepDoItProcTriggered = MAXofPostStepLo << 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 197 466 physIntLength = fCurrentProcess->PostStepG << 467 #ifdef G4VERBOSE 198 #ifdef G4VERBOSE 468 if (verboseLevel > 0) fVerbose->DPSLPostSt << 199 // !!!!! Verbose >> 200 if(verboseLevel>0) fVerbose->PostStepDoItAllDone(); 469 #endif 201 #endif >> 202 } 470 203 471 switch (fCondition) { << 204 //------- 472 case ExclusivelyForced: << 205 // Finale 473 (*fSelectedPostStepDoItVector)[np] = E << 206 //------- 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 207 500 if (physIntLength < PhysicalStep) { << 208 // Update 'TrackLength' and remeber the Step length of the current Step 501 PhysicalStep = physIntLength; << 209 fTrack->AddTrackLength(fStep->GetStepLength()); 502 fStepStatus = fPostStepDoItProc; << 210 fPreviousStepSize = fStep->GetStepLength(); 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 211 #ifdef G4VERBOSE 528 if (verboseLevel > 0) fVerbose->DPSLAlongS << 212 // !!!!! Verbose >> 213 if(verboseLevel>0) fVerbose->StepInfo(); 529 #endif 214 #endif 530 << 215 // Send G4Step information to Hit/Dig if the volume is sensitive 531 if (physIntLength < PhysicalStep) { << 216 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 532 PhysicalStep = physIntLength; << 217 StepControlFlag = fStep->GetControlFlag(); 533 << 218 if( fCurrentVolume != 0 && StepControlFlag != AvoidHitInvocation) { 534 // Check if the process wants to be the << 219 fSensitive = fCurrentVolume->GetLogicalVolume()-> 535 // multi-scattering proposes Step limit, << 220 GetSensitiveDetector(); 536 // << 221 if( fSensitive != 0 ) { 537 if (fGPILSelection == CandidateForSelect << 222 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 } 223 } 555 } << 224 } 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 225 577 ////////////////////////////////////////////// << 226 // User intervention process. 578 G4int G4SteppingManager::ProcessSecondariesFro << 227 fStep->SetTrack(fTrack); 579 ////////////////////////////////////////////// << 228 if( fUserSteppingAction != NULL ) { 580 { << 229 fUserSteppingAction->UserSteppingAction(fStep); 581 G4Track* tempSecondaryTrack; << 230 } 582 G4int num2ndaries; << 583 G4int pushedSecondaries = 0; << 584 << 585 num2ndaries = fParticleChange->GetNumberOfSe << 586 if (num2ndaries == 0) { << 587 return 0; << 588 } << 589 231 590 // Get the creator process. This may be diff << 232 // Stepping process finish. Return the value of the StepStatus. 591 // "combined" process such as G4GammaGeneral << 233 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 234 632 return pushedSecondaries; << 633 } 235 } 634 236 635 ////////////////////////////////////////////// << 237 /////////////////////////////////////////////////////////// 636 void G4SteppingManager::InvokeAtRestDoItProcs( << 238 void G4SteppingManager::SetInitialStep(G4Track* valueTrack) 637 ////////////////////////////////////////////// << 239 /////////////////////////////////////////////////////////// 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 { 240 { 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 241 >> 242 // Set up several local variables. >> 243 PreStepPointIsGeom = false; >> 244 FirstStep = true; >> 245 fParticleChange = NULL; >> 246 fPreviousStepSize = 0.; >> 247 fStepStatus = fUndefined; >> 248 >> 249 fTrack = valueTrack; >> 250 Mass = fTrack->GetDynamicParticle()->GetMass(); >> 251 >> 252 PhysicalStep = 0.; >> 253 GeometricalStep = 0.; >> 254 CorrectedStep = 0.; >> 255 PreStepPointIsGeom = false; >> 256 FirstStep = false; >> 257 fStepStatus = fUndefined; >> 258 >> 259 TempInitVelocity = 0.; >> 260 TempVelocity = 0.; >> 261 sumEnergyChange = 0.; >> 262 >> 263 >> 264 // If the primary track has 'Suspend' or 'PostponeToNextEvent' state, >> 265 // set the track state to 'Alive'. >> 266 if( (fTrack->GetTrackStatus()==fSuspend) || >> 267 (fTrack->GetTrackStatus()==fPostponeToNextEvent) ){ >> 268 fTrack->SetTrackStatus(fAlive); >> 269 } >> 270 >> 271 // If the primary track has 'zero' kinetic energy, set the track >> 272 // state to 'StopButAlive'. >> 273 if(fTrack->GetKineticEnergy() <= 0.0){ >> 274 fTrack->SetTrackStatus( fStopButAlive ); >> 275 } >> 276 >> 277 >> 278 // Set Touchable to track and a private attribute of G4SteppingManager >> 279 >> 280 >> 281 if ( ! fTrack->GetTouchableHandle() ) { >> 282 G4ThreeVector direction= fTrack->GetMomentumDirection(); >> 283 fNavigator->LocateGlobalPointAndSetup( fTrack->GetPosition(), >> 284 &direction, true, false ); >> 285 fTouchableHandle = fNavigator->CreateTouchableHistory(); >> 286 >> 287 fTrack->SetTouchableHandle( fTouchableHandle ); >> 288 fTrack->SetNextTouchableHandle( fTouchableHandle ); >> 289 }else{ >> 290 fTrack->SetNextTouchableHandle( fTrack->GetTouchableHandle() ); >> 291 G4VPhysicalVolume* oldTopVolume= fTrack->GetTouchableHandle()->GetVolume(); >> 292 G4VPhysicalVolume* newTopVolume= >> 293 fNavigator->ResetHierarchyAndLocate( fTrack->GetPosition(), >> 294 fTrack->GetMomentumDirection(), >> 295 *((G4TouchableHistory*)fTrack->GetTouchableHandle()()) ); >> 296 if(newTopVolume != oldTopVolume ){ >> 297 fTouchableHandle = fNavigator->CreateTouchableHistory(); >> 298 fTrack->SetTouchableHandle( fTouchableHandle ); >> 299 fTrack->SetNextTouchableHandle( fTouchableHandle ); >> 300 } >> 301 } >> 302 // Set vertex information of G4Track at here >> 303 if ( fTrack->GetCurrentStepNumber() == 0 ) { >> 304 fTrack->SetVertexPosition( fTrack->GetPosition() ); >> 305 fTrack->SetVertexMomentumDirection( fTrack->GetMomentumDirection() ); >> 306 fTrack->SetVertexKineticEnergy( fTrack->GetKineticEnergy() ); >> 307 fTrack->SetLogicalVolumeAtVertex( fTrack->GetVolume()->GetLogicalVolume() ); >> 308 } >> 309 // Initial set up for attributes of 'G4SteppingManager' >> 310 fCurrentVolume = fTouchableHandle->GetVolume(); >> 311 >> 312 // If track is already outside the world boundary, kill it >> 313 if( fCurrentVolume==0 ){ >> 314 // If the track is a primary, stop processing >> 315 if(fTrack->GetParentID()==0) >> 316 { >> 317 G4cerr << "Primary particle starting at " >> 318 << fTrack->GetPosition() >> 319 << " is outside of the world volume." << G4endl; >> 320 G4Exception("G4SteppingManager::Primary vertex outside of the world"); >> 321 } >> 322 >> 323 fTrack->SetTrackStatus( fStopAndKill ); >> 324 G4cerr << "G4SteppingManager::SetInitialStep(): warning: " >> 325 << "initial track position is outside world! " >> 326 << fTrack->GetPosition() << G4endl; >> 327 } >> 328 else { >> 329 // Initial set up for attribues of 'Step' >> 330 fStep->InitializeStep( fTrack ); >> 331 } 738 #ifdef G4VERBOSE 332 #ifdef G4VERBOSE 739 if (verboseLevel > 0) fVerbose->AlongStepD << 333 // !!!!! Verbose >> 334 if(verboseLevel>0) fVerbose->TrackingStarted(); 740 #endif 335 #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 } 336 } 765 337 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 338