Geant4 Cross Reference |
>> 1 // This code implementation is the intellectual property of >> 2 // the GEANT4 collaboration. 1 // 3 // 2 // ******************************************* << 4 // By copying, distributing or modifying the Program (or any work 3 // * License and Disclaimer << 5 // based on the Program) you indicate your acceptance of this statement, 4 // * << 6 // and all its terms. 5 // * The Geant4 software is copyright of th << 6 // * the Geant4 Collaboration. It is provided << 7 // * conditions of the Geant4 Software License << 8 // * LICENSE and available at http://cern.ch/ << 9 // * include a list of copyright holders. << 10 // * << 11 // * Neither the authors of this software syst << 12 // * institutes,nor the agencies providing fin << 13 // * work make any representation or warran << 14 // * regarding this software system or assum << 15 // * use. Please see the license in the file << 16 // * for the full disclaimer and the limitatio << 17 // * << 18 // * This code implementation is the result << 19 // * technical work of the GEANT4 collaboratio << 20 // * By using, copying, modifying or distri << 21 // * any work based on the software) you ag << 22 // * use in resulting scientific publicati << 23 // * acceptance of all terms of the Geant4 Sof << 24 // ******************************************* << 25 // 7 // 26 // G4SteppingManager class implementation << 8 // $Id: G4SteppingManager.cc,v 1.10 2000/06/02 09:53:29 kurasige Exp $ >> 9 // GEANT4 tag $Name: geant4-03-00 $ >> 10 // >> 11 // >> 12 //--------------------------------------------------------------- >> 13 // >> 14 // G4SteppingManager.cc >> 15 // >> 16 // Description: >> 17 // This class represents the manager who steers to move the give >> 18 // particle from the TrackingManger by one Step. 27 // 19 // 28 // Contact: 20 // Contact: 29 // Questions and comments to this code shoul 21 // Questions and comments to this code should be sent to 30 // Katsuya Amako (e-mail: Katsuya.Amako@k 22 // Katsuya Amako (e-mail: Katsuya.Amako@kek.jp) 31 // Takashi Sasaki (e-mail: Takashi.Sasaki@ 23 // Takashi Sasaki (e-mail: Takashi.Sasaki@kek.jp) 32 // ------------------------------------------- << 24 // >> 25 //--------------------------------------------------------------- 33 26 34 #include "G4SteppingManager.hh" 27 #include "G4SteppingManager.hh" 35 << 28 #include "G4SteppingVerbose.hh" >> 29 #include "G4UImanager.hh" 36 #include "G4ForceCondition.hh" 30 #include "G4ForceCondition.hh" 37 #include "G4GPILSelection.hh" 31 #include "G4GPILSelection.hh" 38 #include "G4GeometryTolerance.hh" << 39 #include "G4ParticleTable.hh" << 40 #include "G4SteppingControl.hh" 32 #include "G4SteppingControl.hh" 41 #include "G4SteppingVerbose.hh" << 42 #include "G4SteppingVerboseWithUnits.hh" << 43 #include "G4TransportationManager.hh" 33 #include "G4TransportationManager.hh" 44 #include "G4UImanager.hh" << 45 #include "G4UserLimits.hh" 34 #include "G4UserLimits.hh" 46 #include "G4VSensitiveDetector.hh" // Include << 35 #include "G4VSensitiveDetector.hh" // Include from 'hits/digi' 47 << 48 // #define debug << 49 36 50 ////////////////////////////////////// 37 ////////////////////////////////////// 51 G4SteppingManager::G4SteppingManager() 38 G4SteppingManager::G4SteppingManager() 52 ////////////////////////////////////// 39 ////////////////////////////////////// >> 40 : verboseLevel(0), fUserSteppingAction(NULL) 53 { 41 { 54 // Construct simple 'has-a' related objects << 55 42 56 fStep = new G4Step(); << 43 // Construct simple 'has-a' related objects 57 fSecondary = fStep->NewSecondaryVector(); << 44 fSecondary = new G4TrackVector(); 58 fPreStepPoint = fStep->GetPreStepPoint(); << 45 fStep = new G4Step(); 59 fPostStepPoint = fStep->GetPostStepPoint(); << 46 fPreStepPoint = fStep->GetPreStepPoint(); >> 47 fPostStepPoint = fStep->GetPostStepPoint(); >> 48 #ifdef G4VERBOSE >> 49 if(G4VSteppingVerbose::GetInstance()==0) { >> 50 fVerbose = new G4SteppingVerbose(); >> 51 G4VSteppingVerbose::SetInstance(fVerbose); >> 52 fVerbose -> SetManager(this); >> 53 KillVerbose = true; >> 54 } >> 55 else { >> 56 fVerbose = G4VSteppingVerbose::GetInstance(); >> 57 fVerbose -> SetManager(this); >> 58 KillVerbose = false; >> 59 } >> 60 #endif >> 61 fSelectedAtRestDoItVector >> 62 = new G4SelectedAtRestDoItVector(SIZEofSelectedDoIt); >> 63 fSelectedAlongStepDoItVector >> 64 = new G4SelectedAlongStepDoItVector(SIZEofSelectedDoIt); >> 65 fSelectedPostStepDoItVector >> 66 = new G4SelectedPostStepDoItVector(SIZEofSelectedDoIt); >> 67 SetNavigator(G4TransportationManager::GetTransportationManager() >> 68 ->GetNavigatorForTracking()); 60 69 61 #ifdef G4VERBOSE << 70 fTouchable1 = new G4TouchableHistory(); 62 fVerbose = G4VSteppingVerbose::GetInstance() << 71 fTouchable2 = new G4TouchableHistory(); 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 << 90 SetNavigator(G4TransportationManager::GetTra << 91 << 92 physIntLength = DBL_MAX; << 93 kCarTolerance = 0.5 * G4GeometryTolerance::G << 94 << 95 fNoProcess = new G4NoProcess; << 96 } 72 } 97 73 98 /////////////////////////////////////// 74 /////////////////////////////////////// 99 G4SteppingManager::~G4SteppingManager() 75 G4SteppingManager::~G4SteppingManager() 100 /////////////////////////////////////// 76 /////////////////////////////////////// 101 { 77 { 102 fTouchableHandle = nullptr; << 103 78 104 // Destruct simple 'has-a' objects << 79 // Destruct simple 'has-a' objects 105 // << 80 delete fSecondary; 106 fStep->DeleteSecondaryVector(); << 81 delete fStep; 107 << 82 delete fSelectedAtRestDoItVector; 108 // delete fSecondary; << 83 delete fSelectedAlongStepDoItVector; 109 delete fStep; << 84 delete fSelectedPostStepDoItVector; 110 delete fSelectedAtRestDoItVector; << 85 delete (G4VTouchable*)(fTouchable1); 111 delete fSelectedAlongStepDoItVector; << 86 delete (G4VTouchable*)(fTouchable2); 112 delete fSelectedPostStepDoItVector; << 87 if (fUserSteppingAction) delete fUserSteppingAction; 113 delete fUserSteppingAction; << 114 #ifdef G4VERBOSE 88 #ifdef G4VERBOSE 115 if (KillVerbose) delete fVerbose; << 89 if(KillVerbose) delete fVerbose; 116 #endif 90 #endif 117 } 91 } 118 92 >> 93 119 ////////////////////////////////////////// 94 ////////////////////////////////////////// 120 G4StepStatus G4SteppingManager::Stepping() 95 G4StepStatus G4SteppingManager::Stepping() 121 ////////////////////////////////////////// 96 ////////////////////////////////////////// 122 { 97 { >> 98 123 //-------- 99 //-------- 124 // Prelude 100 // Prelude 125 //-------- 101 //-------- 126 #ifdef G4VERBOSE 102 #ifdef G4VERBOSE 127 if (verboseLevel > 0) { << 103 // !!!!! Verbose 128 fVerbose->NewStep(); << 104 if(verboseLevel>0) fVerbose->NewStep(); 129 } << 105 #endif 130 else if (verboseLevel == -1) { << 131 G4VSteppingVerbose::SetSilent(1); << 132 } << 133 else { << 134 G4VSteppingVerbose::SetSilent(0); << 135 } << 136 #endif << 137 106 138 // Store last PostStepPoint to PreStepPoint, << 107 // Store last PostStepPoint to PreStepPoint, and swap current and nex 139 // volume information of G4Track. Reset tota << 108 // volume information of G4Track. Reset total energy deposit in one Step. 140 // << 109 fStep->CopyPostToPreStepPoint(); 141 fStep->CopyPostToPreStepPoint(); << 110 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 111 172 #ifdef G4VERBOSE << 112 // Switch next touchable in track to current one 173 if (verboseLevel > 0) fVerbose->AtRestDo << 113 fTrack->SetTouchable(fTrack->GetNextTouchable()); 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 114 212 fStep->GetPostStepPoint()->SetSafety(endpo << 115 // Free the touchable which is not used >> 116 SetAnotherTouchableFree(fPostStepPoint->GetTouchable()); 213 117 214 #ifdef G4VERBOSE << 118 // Reset the secondary particles 215 if (verboseLevel > 0) fVerbose->AlongStepD << 119 fN2ndariesAtRestDoIt = 0; 216 #endif << 120 fN2ndariesAlongStepDoIt = 0; 217 << 121 fN2ndariesPostStepDoIt = 0; 218 // Invoke PostStepDoIt << 219 InvokePostStepDoItProcs(); << 220 << 221 #ifdef G4VERBOSE << 222 if (verboseLevel > 0) fVerbose->PostStepDo << 223 #endif << 224 } << 225 122 226 //------- << 123 //JA Set the volume before it is used (in DefineStepLength() for User Limit) 227 // Finale << 124 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 228 //------- << 229 << 230 // Update 'TrackLength' and remeber the Step << 231 // << 232 fTrack->AddTrackLength(fStep->GetStepLength( << 233 fPreviousStepSize = fStep->GetStepLength(); << 234 fStep->SetTrack(fTrack); << 235 125 236 #ifdef G4VERBOSE << 126 //----------------- 237 if (verboseLevel > 0) fVerbose->StepInfo(); << 127 // AtRest Processes 238 #endif << 128 //----------------- 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 129 >> 130 if( fTrack->GetTrackStatus() == fStopButAlive ){ >> 131 if( MAXofAtRestLoops>0 ){ >> 132 InvokeAtRestDoItProcs(); >> 133 fStepStatus = fAtRestDoItProc; >> 134 fStep->GetPostStepPoint()->SetStepStatus( fStepStatus ); >> 135 368 #ifdef G4VERBOSE 136 #ifdef G4VERBOSE 369 if (verboseLevel > 0) fVerbose->TrackingStar << 137 // !!!!! Verbose 370 #endif << 138 if(verboseLevel>0) fVerbose->AtRestDoItInvoked(); 371 } << 139 #endif 372 140 373 ////////////////////////////////////////////// << 141 } 374 void G4SteppingManager::GetProcessNumber() << 142 // Make sure the track is killed 375 ////////////////////////////////////////////// << 143 fTrack->SetTrackStatus( fStopAndKill ); 376 { << 144 } 377 #ifdef debug << 378 G4cout << "G4SteppingManager::GetProcessNumb << 379 #endif << 380 145 381 G4ProcessManager* pm = fTrack->GetDefinition << 146 //--------------------------------- 382 if (pm == nullptr) { << 147 // AlongStep and PostStep Processes 383 G4cerr << "ERROR - G4SteppingManager::GetP << 148 //--------------------------------- 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 149 398 #ifdef debug << 399 G4cout << "G4SteppingManager::GetProcessNumb << 400 #endif << 401 150 402 // AlongStepDoits << 151 else{ 403 // << 152 // Find minimum Step length demanded by active disc./cont. processes 404 MAXofAlongStepLoops = pm->GetAlongStepProces << 153 DefinePhysicalStepLength(); 405 fAlongStepDoItVector = pm->GetAlongStepProce << 406 fAlongStepGetPhysIntVector = pm->GetAlongSte << 407 154 408 #ifdef debug << 155 // Store the Step length (geometrical length) to G4Step and G4Track 409 G4cout << "G4SteppingManager::GetProcessNumb << 156 fStep->SetStepLength( PhysicalStep ); 410 #endif << 157 fTrack->SetStepLength( PhysicalStep ); >> 158 G4double GeomStepLength = PhysicalStep; 411 159 412 // PostStepDoits << 160 // Store StepStatus to PostStepPoint 413 // << 161 fStep->GetPostStepPoint()->SetStepStatus( fStepStatus ); 414 MAXofPostStepLoops = pm->GetPostStepProcessV << 415 fPostStepDoItVector = pm->GetPostStepProcess << 416 fPostStepGetPhysIntVector = pm->GetPostStepP << 417 162 418 #ifdef debug << 163 // Invoke AlongStepDoIt 419 G4cout << "G4SteppingManager::GetProcessNumb << 164 InvokeAlongStepDoItProcs(); 420 #endif << 421 165 422 if (SizeOfSelectedDoItVector < MAXofAtRestLo << 166 // Update track by taking into account all changes by AlongStepDoIt 423 SizeOfSelectedDoItVector < MAXofAlongSte << 167 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 168 436 // ******************************************* << 169 // Update safety after invocation of all AlongStepDoIts 437 // << 170 endpointSafOrigin= fPostStepPoint->GetPosition(); 438 // Private Member Functions << 171 endpointSafety= G4std::max( proposedSafety - GeomStepLength, 0.); 439 // << 440 // ******************************************* << 441 172 442 ////////////////////////////////////////////// << 173 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 174 451 #ifdef G4VERBOSE 175 #ifdef G4VERBOSE 452 if (verboseLevel > 0) fVerbose->DPSLStarted( << 176 // !!!!! Verbose >> 177 if(verboseLevel>0) fVerbose->AlongStepDoItAllDone(); 453 #endif 178 #endif 454 179 455 // GPIL for PostStep << 180 // Invoke PostStepDoIt 456 // << 181 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 182 466 physIntLength = fCurrentProcess->PostStepG << 467 #ifdef G4VERBOSE 183 #ifdef G4VERBOSE 468 if (verboseLevel > 0) fVerbose->DPSLPostSt << 184 // !!!!! Verbose >> 185 if(verboseLevel>0) fVerbose->PostStepDoItAllDone(); 469 #endif 186 #endif >> 187 } 470 188 471 switch (fCondition) { << 189 //------- 472 case ExclusivelyForced: << 190 // Finale 473 (*fSelectedPostStepDoItVector)[np] = E << 191 //------- 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 192 525 physIntLength = fCurrentProcess->AlongStep << 193 // Update 'TrackLength' and remeber the Step length of the current Step 526 *fTrack, fPreviousStepSize, PhysicalStep << 194 fTrack->AddTrackLength(fStep->GetStepLength()); >> 195 fPreviousStepSize = fStep->GetStepLength(); 527 #ifdef G4VERBOSE 196 #ifdef G4VERBOSE 528 if (verboseLevel > 0) fVerbose->DPSLAlongS << 197 // !!!!! Verbose >> 198 if(verboseLevel>0) fVerbose->StepInfo(); 529 #endif 199 #endif 530 << 200 // Send G4Step information to Hit/Dig if the volume is sensitive 531 if (physIntLength < PhysicalStep) { << 201 fCurrentVolume = fStep->GetPreStepPoint()->GetPhysicalVolume(); 532 PhysicalStep = physIntLength; << 202 StepControlFlag = fStep->GetControlFlag(); 533 << 203 if( fCurrentVolume != 0 && StepControlFlag != AvoidHitInvocation) { 534 // Check if the process wants to be the << 204 fSensitive = fCurrentVolume->GetLogicalVolume()-> 535 // multi-scattering proposes Step limit, << 205 GetSensitiveDetector(); 536 // << 206 if( fSensitive != 0 ) { 537 if (fGPILSelection == CandidateForSelect << 207 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 } 208 } >> 209 } 546 210 547 // Transportation is assumed to be the l << 211 // User intervention process. 548 // Transportation is winning << 212 fStep->SetTrack(fTrack); 549 if (kp == MAXofAlongStepLoops - 1) { << 213 if( fUserSteppingAction != NULL ) { 550 // This used to set fStepStatus = fGeo << 214 fUserSteppingAction->UserSteppingAction(fStep); 551 // G4Transportation::AlongStepDoIt whe << 215 } 552 // decide if there is a volume boundar << 553 delegateToTransportation = false; << 554 } << 555 } << 556 216 557 // Make sure to check the safety, even if << 217 // Stepping process finish. Return the value of the StepStatus. 558 // by this process << 218 return fStepStatus; 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 219 577 ////////////////////////////////////////////// << 578 G4int G4SteppingManager::ProcessSecondariesFro << 579 ////////////////////////////////////////////// << 580 { << 581 G4Track* tempSecondaryTrack; << 582 G4int num2ndaries; << 583 G4int pushedSecondaries = 0; << 584 << 585 num2ndaries = fParticleChange->GetNumberOfSe << 586 if (num2ndaries == 0) { << 587 return 0; << 588 } << 589 << 590 // Get the creator process. This may be diff << 591 // "combined" process such as G4GammaGeneral << 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 << 632 return pushedSecondaries; << 633 } << 634 << 635 ////////////////////////////////////////////// << 636 void G4SteppingManager::InvokeAtRestDoItProcs( << 637 ////////////////////////////////////////////// << 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 } 220 } 714 221 715 ////////////////////////////////////////////// << 222 /////////////////////////////////////////////////////////// 716 void G4SteppingManager::InvokeAlongStepDoItPro << 223 void G4SteppingManager::SetInitialStep(G4Track* valueTrack) 717 ////////////////////////////////////////////// << 224 /////////////////////////////////////////////////////////// 718 { << 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 << 738 #ifdef G4VERBOSE << 739 if (verboseLevel > 0) fVerbose->AlongStepD << 740 #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 } << 765 << 766 ////////////////////////////////////////////// << 767 void G4SteppingManager::InvokePostStepDoItProc << 768 ////////////////////////////////////////////// << 769 { 225 { 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 226 792 // Exit from PostStepLoop if the track has << 227 // Set up several local variables. 793 // but extra treatment for processes with << 228 PreStepPointIsGeom = false; 794 // << 229 FirstStep = true; 795 if (fTrack->GetTrackStatus() == fStopAndKi << 230 fParticleChange = NULL; 796 for (std::size_t np1 = np + 1; np1 < MAX << 231 fPreviousStepSize = 0.; 797 G4int Cond2 = (*fSelectedPostStepDoItV << 232 fStepStatus = fUndefined; 798 if (Cond2 == StronglyForced) { << 233 799 InvokePSDIP(np1); << 234 fTrack = valueTrack; 800 } << 235 Mass = fTrack->GetDynamicParticle()->GetMass(); 801 } << 236 802 break; << 237 fIsTouchable1Free = TRUE; 803 } << 238 fIsTouchable2Free = TRUE; 804 } << 239 >> 240 // If the primary track has 'Suspend' or 'PostponeToNextEvent' state, >> 241 // set the track state to 'Alive'. >> 242 if( (fTrack->GetTrackStatus()==fSuspend) || >> 243 (fTrack->GetTrackStatus()==fPostponeToNextEvent) ){ >> 244 fTrack->SetTrackStatus(fAlive); >> 245 } >> 246 >> 247 // If the primary track has 'zero' kinetic energy, set the track >> 248 // state to 'StopButAlive'. >> 249 if(fTrack->GetKineticEnergy() <= 0.0){ >> 250 fTrack->SetTrackStatus( fStopButAlive ); >> 251 } >> 252 >> 253 // Initialize VTouchable using the point in the global coordinate >> 254 // system. >> 255 G4VTouchable* pTouchableFree = (G4VTouchable*)(GetFreeTouchable()); >> 256 fNavigator->LocateGlobalPointAndUpdateTouchable( >> 257 fTrack->GetPosition(), >> 258 pTouchableFree, >> 259 true ); >> 260 >> 261 // Set Touchable to track and a private attribute of G4SteppingManager >> 262 fTrack->SetTouchable( pTouchableFree ); >> 263 fTrack->SetNextTouchable( pTouchableFree ); >> 264 >> 265 // Set vertex information of G4Track at here >> 266 fTrack->SetVertexPosition( fTrack->GetPosition() ); >> 267 fTrack->SetVertexMomentumDirection( fTrack->GetMomentumDirection() ); >> 268 fTrack->SetVertexKineticEnergy( fTrack->GetKineticEnergy() ); >> 269 >> 270 // Initial set up for attributes of 'G4SteppingManager' >> 271 fCurrentVolume = pTouchableFree->GetVolume(); >> 272 >> 273 // Initial set up for attribues of 'Step' >> 274 fStep->InitializeStep( fTrack ); >> 275 #ifdef G4VERBOSE >> 276 // !!!!! Verbose >> 277 if(verboseLevel>0) fVerbose->TrackingStarted(); >> 278 #endif >> 279 // If track is already outside the world boundary, kill it >> 280 if( fTrack->GetVolume()==0 ){ >> 281 fTrack->SetTrackStatus( fStopAndKill ); >> 282 } 805 } 283 } 806 284 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 285