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 // G4StackManager class implementation 26 // G4StackManager class implementation 27 // 27 // 28 // Author: Makoto Asai, 1996 28 // Author: Makoto Asai, 1996 29 // Adding sub-event parallelism << 30 // 23/Aug/2023 << 31 // ------------------------------------------- 29 // -------------------------------------------------------------------- 32 30 33 #include "G4StackManager.hh" 31 #include "G4StackManager.hh" 34 #include "G4StackingMessenger.hh" 32 #include "G4StackingMessenger.hh" 35 #include "G4VTrajectory.hh" 33 #include "G4VTrajectory.hh" 36 #include "G4Event.hh" << 37 #include "G4ios.hh" 34 #include "G4ios.hh" 38 35 39 #include "G4ParticleDefinition.hh" 36 #include "G4ParticleDefinition.hh" 40 #include "G4VProcess.hh" 37 #include "G4VProcess.hh" 41 38 42 // Needed for temporal service 39 // Needed for temporal service 43 // 40 // 44 #include "G4ParticleTable.hh" 41 #include "G4ParticleTable.hh" 45 #include "G4ProcessManager.hh" 42 #include "G4ProcessManager.hh" 46 #include "G4ProcessVector.hh" 43 #include "G4ProcessVector.hh" 47 44 48 G4StackManager::G4StackManager() 45 G4StackManager::G4StackManager() 49 { 46 { 50 theMessenger = new G4StackingMessenger(this) 47 theMessenger = new G4StackingMessenger(this); 51 #ifdef G4_USESMARTSTACK 48 #ifdef G4_USESMARTSTACK 52 urgentStack = new G4SmartTrackStack; 49 urgentStack = new G4SmartTrackStack; 53 // G4cout << "+++ G4StackManager uses G4Smar 50 // G4cout << "+++ G4StackManager uses G4SmartTrackStack. +++" << G4endl; 54 #else 51 #else 55 urgentStack = new G4TrackStack(5000); 52 urgentStack = new G4TrackStack(5000); 56 // G4cout << "+++ G4StackManager uses ordina 53 // G4cout << "+++ G4StackManager uses ordinary G4TrackStack. +++" << G4endl; 57 #endif 54 #endif 58 waitingStack = new G4TrackStack(1000); 55 waitingStack = new G4TrackStack(1000); 59 postponeStack = new G4TrackStack(1000); 56 postponeStack = new G4TrackStack(1000); 60 } 57 } 61 58 62 G4StackManager::~G4StackManager() 59 G4StackManager::~G4StackManager() 63 { 60 { 64 delete userStackingAction; << 61 if(userStackingAction) { delete userStackingAction; } 65 62 66 #ifdef G4VERBOSE 63 #ifdef G4VERBOSE 67 if(verboseLevel>0) 64 if(verboseLevel>0) 68 { 65 { 69 G4cout << "+++++++++++++++++++++++++++++++ 66 G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl; 70 G4cout << " Maximum number of tracks in th 67 G4cout << " Maximum number of tracks in the urgent stack : " << urgentStack->GetMaxNTrack() << G4endl; 71 G4cout << "+++++++++++++++++++++++++++++++ 68 G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl; 72 } 69 } 73 #endif 70 #endif 74 delete urgentStack; 71 delete urgentStack; 75 delete waitingStack; 72 delete waitingStack; 76 delete postponeStack; 73 delete postponeStack; 77 delete theMessenger; 74 delete theMessenger; 78 if(numberOfAdditionalWaitingStacks>0) 75 if(numberOfAdditionalWaitingStacks>0) 79 { 76 { 80 for(G4int i=0; i<numberOfAdditionalWaiting 77 for(G4int i=0; i<numberOfAdditionalWaitingStacks; ++i) 81 { 78 { 82 delete additionalWaitingStacks[i]; 79 delete additionalWaitingStacks[i]; 83 } 80 } 84 } 81 } 85 } 82 } 86 83 87 G4int G4StackManager:: 84 G4int G4StackManager:: 88 PushOneTrack(G4Track* newTrack, G4VTrajectory* 85 PushOneTrack(G4Track* newTrack, G4VTrajectory* newTrajectory) 89 { 86 { 90 const G4ParticleDefinition* pd = newTrack->G 87 const G4ParticleDefinition* pd = newTrack->GetParticleDefinition(); 91 if(pd->GetParticleDefinitionID() < 0) 88 if(pd->GetParticleDefinitionID() < 0) 92 { 89 { 93 G4ExceptionDescription ED; 90 G4ExceptionDescription ED; 94 ED << "A track without proper process mana 91 ED << "A track without proper process manager is pushed \ 95 into the track stack.\n" 92 into the track stack.\n" 96 << " Particle name : " << pd->GetPartic 93 << " Particle name : " << pd->GetParticleName() << " -- "; 97 if(newTrack->GetParentID()==0) << 94 if(newTrack->GetParentID()<0) 98 { 95 { 99 ED << "created by a primary particle gen 96 ED << "created by a primary particle generator."; 100 } 97 } 101 else 98 else 102 { 99 { 103 const G4VProcess* vp = newTrack->GetCrea 100 const G4VProcess* vp = newTrack->GetCreatorProcess(); 104 if(vp != nullptr) << 101 if(vp) 105 { 102 { 106 ED << "created by " << vp->GetProcessN 103 ED << "created by " << vp->GetProcessName() << "."; 107 } 104 } 108 else 105 else 109 { 106 { 110 ED << "creaded by unknown process."; 107 ED << "creaded by unknown process."; 111 } 108 } 112 } 109 } 113 G4Exception("G4StackManager::PushOneTrack" 110 G4Exception("G4StackManager::PushOneTrack","Event10051", 114 FatalException,ED); 111 FatalException,ED); 115 delete newTrack; 112 delete newTrack; 116 return GetNUrgentTrack(); 113 return GetNUrgentTrack(); 117 } 114 } 118 115 119 DefineDefaultClassification( newTrack ); << 116 G4ClassificationOfNewTrack classification = DefaultClassification( newTrack ); 120 G4ClassificationOfNewTrack classification = << 117 if(userStackingAction != nullptr) 121 if(userStackingAction!=nullptr) << 122 { 118 { 123 classification = userStackingAction->Class 119 classification = userStackingAction->ClassifyNewTrack( newTrack ); 124 if(classification != fDefaultClassificatio << 125 { << 126 if(fExceptionSeverity!=G4ExceptionSeveri << 127 { << 128 G4ExceptionDescription ed; << 129 ed << "UserStackingAction has changed << 130 << fDefaultClassification << " to " << 131 G4Exception("G4StackManager::PushOneTr << 132 fExceptionSeverity,ed); << 133 } << 134 } << 135 } 120 } 136 if(newTrack->GetTrackStatus() == fSuspendAnd << 137 // to avoid this track sent to Waiting stack << 138 { newTrack->SetTrackStatus( fSuspend ); } << 139 121 >> 122 if(classification==fKill) // delete newTrack without stacking >> 123 { 140 #ifdef G4VERBOSE 124 #ifdef G4VERBOSE 141 if( verboseLevel > 1 ) << 125 if( verboseLevel > 1 ) >> 126 { >> 127 G4cout << " ---> G4Track " << newTrack << " (trackID " >> 128 << newTrack->GetTrackID() << ", parentID " >> 129 << newTrack->GetParentID() << ") is not to be stored." << G4endl; >> 130 } >> 131 #endif >> 132 delete newTrack; >> 133 delete newTrajectory; >> 134 } >> 135 else 142 { 136 { 143 G4cout << "### Storing a track (" << 137 G4StackedTrack newStackedTrack( newTrack, newTrajectory ); 144 << newTrack->GetParticleDefinition( << 138 switch (classification) 145 << ",trackID=" << newTrack->GetTrac << 139 { 146 << ",parentID=" << newTrack->GetPar << 140 case fUrgent: 147 if(newTrack->GetParentID()==0) << 141 urgentStack->PushToStack( newStackedTrack ); 148 { G4cout << "created by a primary particle << 142 break; 149 else << 143 case fWaiting: 150 { << 144 waitingStack->PushToStack( newStackedTrack ); 151 const G4VProcess* vp = newTrack->GetCrea << 145 break; 152 if(vp != nullptr) << 146 case fPostpone: 153 { G4cout << "created by " << vp->GetProc << 147 postponeStack->PushToStack( newStackedTrack ); 154 else << 148 break; 155 { G4cout << "creaded by unknown process << 149 default: >> 150 G4int i = classification - 10; >> 151 if(i<1 || i>numberOfAdditionalWaitingStacks) >> 152 { >> 153 G4ExceptionDescription ED; >> 154 ED << "invalid classification " << classification << G4endl; >> 155 G4Exception("G4StackManager::PushOneTrack", "Event0051", >> 156 FatalException,ED); >> 157 } >> 158 else >> 159 { >> 160 additionalWaitingStacks[i-1]->PushToStack( newStackedTrack ); >> 161 } >> 162 break; 156 } 163 } 157 G4cout << "into stack #" << classification << 158 } 164 } 159 #endif << 160 G4StackedTrack newStackedTrack( newTrack, ne << 161 SortOut(newStackedTrack,classification); << 162 << 163 return GetNUrgentTrack(); 165 return GetNUrgentTrack(); 164 } 166 } 165 167 >> 168 166 G4Track* G4StackManager::PopNextTrack(G4VTraje 169 G4Track* G4StackManager::PopNextTrack(G4VTrajectory** newTrajectory) 167 { 170 { 168 #ifdef G4VERBOSE 171 #ifdef G4VERBOSE 169 if( verboseLevel > 1 ) 172 if( verboseLevel > 1 ) 170 { 173 { 171 G4cout << "### pop requested out of " 174 G4cout << "### pop requested out of " 172 << GetNUrgentTrack() << " stacked t 175 << GetNUrgentTrack() << " stacked tracks." << G4endl; 173 } 176 } 174 #endif 177 #endif 175 178 176 while( GetNUrgentTrack() == 0 ) 179 while( GetNUrgentTrack() == 0 ) 177 { 180 { 178 #ifdef G4VERBOSE 181 #ifdef G4VERBOSE 179 if( verboseLevel > 1 ) 182 if( verboseLevel > 1 ) 180 { 183 { 181 G4cout << "### " << GetNWaitingTrack() 184 G4cout << "### " << GetNWaitingTrack() 182 << " waiting tracks are re-classi 185 << " waiting tracks are re-classified to" << G4endl; 183 } 186 } 184 #endif 187 #endif 185 waitingStack->TransferTo(urgentStack); 188 waitingStack->TransferTo(urgentStack); 186 if(numberOfAdditionalWaitingStacks>0) 189 if(numberOfAdditionalWaitingStacks>0) 187 { 190 { 188 for(G4int i=0; i<numberOfAdditionalWaiti 191 for(G4int i=0; i<numberOfAdditionalWaitingStacks; ++i) 189 { 192 { 190 if(i==0) 193 if(i==0) 191 { 194 { 192 additionalWaitingStacks[0]->Transfer 195 additionalWaitingStacks[0]->TransferTo(waitingStack); 193 } 196 } 194 else 197 else 195 { 198 { 196 additionalWaitingStacks[i]->Transfer 199 additionalWaitingStacks[i]->TransferTo(additionalWaitingStacks[i-1]); 197 } 200 } 198 } 201 } 199 } 202 } 200 if(userStackingAction != nullptr) 203 if(userStackingAction != nullptr) 201 { 204 { 202 userStackingAction->NewStage(); 205 userStackingAction->NewStage(); 203 } 206 } 204 207 205 #ifdef G4VERBOSE 208 #ifdef G4VERBOSE 206 if( verboseLevel > 1 ) 209 if( verboseLevel > 1 ) 207 G4cout << " " << GetNUrgentTrack() 210 G4cout << " " << GetNUrgentTrack() 208 << " urgent tracks and " << GetNW 211 << " urgent tracks and " << GetNWaitingTrack() 209 << " waiting tracks." << G4endl; 212 << " waiting tracks." << G4endl; 210 #endif 213 #endif 211 if( ( GetNUrgentTrack()==0 ) && ( GetNWait 214 if( ( GetNUrgentTrack()==0 ) && ( GetNWaitingTrack()==0 ) ) 212 return nullptr; << 215 return 0; 213 } 216 } 214 217 215 G4StackedTrack selectedStackedTrack = urgent 218 G4StackedTrack selectedStackedTrack = urgentStack->PopFromStack(); 216 G4Track * selectedTrack = selectedStackedTra 219 G4Track * selectedTrack = selectedStackedTrack.GetTrack(); 217 *newTrajectory = selectedStackedTrack.GetTra 220 *newTrajectory = selectedStackedTrack.GetTrajectory(); 218 221 219 #ifdef G4VERBOSE 222 #ifdef G4VERBOSE 220 if( verboseLevel > 2 ) 223 if( verboseLevel > 2 ) 221 { 224 { 222 G4cout << "Selected G4StackedTrack : " << 225 G4cout << "Selected G4StackedTrack : " << &selectedStackedTrack 223 << " with G4Track " << selectedStac 226 << " with G4Track " << selectedStackedTrack.GetTrack() 224 << " (trackID " << selectedStackedT 227 << " (trackID " << selectedStackedTrack.GetTrack()->GetTrackID() 225 << ", parentID " << selectedStacked 228 << ", parentID " << selectedStackedTrack.GetTrack()->GetParentID() 226 << ")" << G4endl; 229 << ")" << G4endl; 227 } 230 } 228 #endif 231 #endif 229 232 230 return selectedTrack; 233 return selectedTrack; 231 } 234 } 232 235 233 void G4StackManager::ReClassify() 236 void G4StackManager::ReClassify() 234 { 237 { 235 G4StackedTrack aStackedTrack; 238 G4StackedTrack aStackedTrack; 236 G4TrackStack tmpStack; 239 G4TrackStack tmpStack; 237 240 238 if( userStackingAction == nullptr ) return; 241 if( userStackingAction == nullptr ) return; 239 if( GetNUrgentTrack() == 0 ) return; 242 if( GetNUrgentTrack() == 0 ) return; 240 243 241 urgentStack->TransferTo(&tmpStack); 244 urgentStack->TransferTo(&tmpStack); 242 while( tmpStack.GetNTrack() > 0 ) 245 while( tmpStack.GetNTrack() > 0 ) 243 { 246 { 244 aStackedTrack=tmpStack.PopFromStack(); 247 aStackedTrack=tmpStack.PopFromStack(); 245 DefineDefaultClassification( aStackedTrack << 248 G4ClassificationOfNewTrack classification = 246 G4ClassificationOfNewTrack classification << 249 userStackingAction->ClassifyNewTrack( aStackedTrack.GetTrack() ); 247 if(userStackingAction!=nullptr) << 250 switch (classification) 248 { 251 { 249 classification = userStackingAction->Cla << 252 case fKill: 250 if(classification != fDefaultClassificat << 253 delete aStackedTrack.GetTrack(); 251 { << 254 delete aStackedTrack.GetTrajectory(); 252 if(fExceptionSeverity!=G4ExceptionSeve << 255 break; >> 256 case fUrgent: >> 257 urgentStack->PushToStack( aStackedTrack ); >> 258 break; >> 259 case fWaiting: >> 260 waitingStack->PushToStack( aStackedTrack ); >> 261 break; >> 262 case fPostpone: >> 263 postponeStack->PushToStack( aStackedTrack ); >> 264 break; >> 265 default: >> 266 G4int i = classification - 10; >> 267 if(i<1||i>numberOfAdditionalWaitingStacks) >> 268 { >> 269 G4ExceptionDescription ED; >> 270 ED << "invalid classification " << classification << G4endl; >> 271 G4Exception("G4StackManager::ReClassify", "Event0052", >> 272 FatalException, ED); >> 273 } >> 274 else 253 { 275 { 254 G4ExceptionDescription ed; << 276 additionalWaitingStacks[i-1]->PushToStack( aStackedTrack ); 255 ed << "UserStackingAction has change << 256 << fDefaultClassification << " to << 257 G4Exception("G4StackManager::PushOne << 258 fExceptionSeverity,ed); << 259 } 277 } 260 } << 278 break; 261 } 279 } 262 if(aStackedTrack.GetTrack()->GetTrackStatu << 263 // to avoid this track sent to Waiting sta << 264 { aStackedTrack.GetTrack()->SetTrackStatus << 265 << 266 SortOut(aStackedTrack,classification); << 267 } 280 } 268 } 281 } 269 282 270 G4int G4StackManager::PrepareNewEvent(G4Event* << 283 G4int G4StackManager::PrepareNewEvent() 271 { 284 { 272 if(userStackingAction != nullptr) << 285 if(userStackingAction) 273 { 286 { 274 userStackingAction->PrepareNewEvent(); 287 userStackingAction->PrepareNewEvent(); 275 } 288 } 276 289 277 // Set the urgentStack in a defined state. N 290 // Set the urgentStack in a defined state. Not doing it would 278 // affect reproducibility 291 // affect reproducibility 279 // 292 // 280 urgentStack->clearAndDestroy(); 293 urgentStack->clearAndDestroy(); 281 294 282 G4int n_passedFromPrevious = 0; 295 G4int n_passedFromPrevious = 0; 283 296 284 if( GetNPostponedTrack() > 0 ) 297 if( GetNPostponedTrack() > 0 ) 285 { 298 { 286 #ifdef G4VERBOSE 299 #ifdef G4VERBOSE 287 if( verboseLevel > 1 ) 300 if( verboseLevel > 1 ) 288 { 301 { 289 G4cout << GetNPostponedTrack() 302 G4cout << GetNPostponedTrack() 290 << " postponed tracked are now sh 303 << " postponed tracked are now shifted to the stack." << G4endl; 291 } 304 } 292 #endif 305 #endif 293 306 294 G4StackedTrack aStackedTrack; 307 G4StackedTrack aStackedTrack; 295 G4TrackStack tmpStack; 308 G4TrackStack tmpStack; 296 309 297 postponeStack->TransferTo(&tmpStack); 310 postponeStack->TransferTo(&tmpStack); 298 311 299 while( tmpStack.GetNTrack() > 0 ) 312 while( tmpStack.GetNTrack() > 0 ) 300 { 313 { 301 aStackedTrack=tmpStack.PopFromStack(); 314 aStackedTrack=tmpStack.PopFromStack(); 302 G4Track* aTrack = aStackedTrack.GetTrack 315 G4Track* aTrack = aStackedTrack.GetTrack(); 303 DefineDefaultClassification( aTrack ); << 316 aTrack->SetParentID(-1); 304 G4ClassificationOfNewTrack classificatio << 317 G4ClassificationOfNewTrack classification; 305 if(userStackingAction!=nullptr) << 318 if(userStackingAction) 306 { 319 { 307 classification = userStackingAction->C 320 classification = userStackingAction->ClassifyNewTrack( aTrack ); 308 if(classification != fDefaultClassific << 309 { << 310 if(fExceptionSeverity!=G4ExceptionSe << 311 { << 312 G4ExceptionDescription ed; << 313 ed << "UserStackingAction has chan << 314 << fDefaultClassification << " << 315 G4Exception("G4StackManager::PushO << 316 fExceptionSeverity,ed) << 317 } << 318 } << 319 } 321 } 320 if(classification!=fKill) << 322 else 321 { 323 { 322 aTrack->SetParentID(-1); << 324 classification = DefaultClassification( aTrack ); 323 aTrack->SetTrackID(-(++n_passedFromPre << 324 } 325 } 325 else if(aTrack->GetTrackStatus() == fSus << 326 326 // to avoid this track sent to Waiting s << 327 if(classification==fKill) 327 { aTrack->SetTrackStatus( fSuspend ); } << 328 { 328 << 329 delete aTrack; 329 SortOut(aStackedTrack,classification); << 330 delete aStackedTrack.GetTrajectory(); 330 } << 331 } 331 } << 332 else 332 << 333 { 333 // Reset sub-event stacks for a new event << 334 aTrack->SetTrackID(-(++n_passedFromPrevious)); 334 for(auto& ses : subEvtStackMap) << 335 switch (classification) 335 { ses.second->PrepareNewEvent(currentEvent); << 336 << 337 return n_passedFromPrevious; << 338 } << 339 << 340 void G4StackManager::SortOut(G4StackedTrack& a << 341 { << 342 if(classification==fKill) // delete the wi << 343 { << 344 G4Track* newTrack = aStackedTrack.GetTrack << 345 G4VTrajectory* newTrajectory = aStackedTra << 346 #ifdef G4VERBOSE << 347 if( verboseLevel > 1 ) << 348 { << 349 G4cout << " ---> G4Track " << newTrack << 350 << newTrack->GetTrackID() << ", p << 351 << newTrack->GetParentID() << ") << 352 } << 353 #endif << 354 delete newTrack; << 355 delete newTrajectory; << 356 } << 357 else << 358 { << 359 switch (classification) << 360 { << 361 case fUrgent: << 362 urgentStack->PushToStack( aStackedTrac << 363 break; << 364 case fWaiting: << 365 waitingStack->PushToStack( aStackedTra << 366 break; << 367 case fPostpone: << 368 postponeStack->PushToStack( aStackedTr << 369 break; << 370 default: << 371 if(classification < 100) << 372 { << 373 // pushing to additional waiting sta << 374 G4int i = classification - 10; << 375 if(i<1 || i>numberOfAdditionalWaitin << 376 { << 377 G4ExceptionDescription ED; << 378 ED << "invalid classification " << << 379 G4Exception("G4StackManager::SortO << 380 FatalException,ED); << 381 } << 382 else << 383 { << 384 additionalWaitingStacks[i-1]->Push << 385 } << 386 } << 387 else << 388 { 336 { 389 // pushing to sub-event stack << 337 case fUrgent: 390 G4int ty = classification - 100; << 338 urgentStack->PushToStack( aStackedTrack ); 391 auto ses = subEvtStackMap.find(ty); << 339 break; 392 if(ses==subEvtStackMap.end()) << 340 case fWaiting: 393 { << 341 waitingStack->PushToStack( aStackedTrack ); 394 G4ExceptionDescription ED; << 342 break; 395 ED << "invalid classification " << << 343 case fPostpone: 396 G4Exception("G4StackManager::SortO << 344 postponeStack->PushToStack( aStackedTrack ); 397 FatalException,ED); << 345 break; 398 } << 346 default: 399 else << 347 G4int i = classification - 10; 400 { << 348 if(i<1||i>numberOfAdditionalWaitingStacks) 401 ses->second->PushToStack( aStacked << 349 { 402 } << 350 G4ExceptionDescription ED; >> 351 ED << "invalid classification " << classification << G4endl; >> 352 G4Exception("G4StackManager::PrepareNewEvent", "Event0053", >> 353 FatalException, ED); >> 354 } >> 355 else >> 356 { >> 357 additionalWaitingStacks[i-1]->PushToStack( aStackedTrack ); >> 358 } >> 359 break; 403 } 360 } 404 break; << 361 } 405 } 362 } 406 } 363 } >> 364 return n_passedFromPrevious; 407 } 365 } 408 366 409 void G4StackManager::SetNumberOfAdditionalWait 367 void G4StackManager::SetNumberOfAdditionalWaitingStacks(G4int iAdd) 410 { 368 { 411 if(iAdd > numberOfAdditionalWaitingStacks) 369 if(iAdd > numberOfAdditionalWaitingStacks) 412 { 370 { 413 for(G4int i=numberOfAdditionalWaitingStack 371 for(G4int i=numberOfAdditionalWaitingStacks; i<iAdd; ++i) 414 { 372 { 415 auto* newStack = new G4TrackStack; << 373 G4TrackStack* newStack = new G4TrackStack; 416 additionalWaitingStacks.push_back(newSta 374 additionalWaitingStacks.push_back(newStack); 417 } 375 } 418 numberOfAdditionalWaitingStacks = iAdd; 376 numberOfAdditionalWaitingStacks = iAdd; 419 } 377 } 420 else if (iAdd < numberOfAdditionalWaitingSta 378 else if (iAdd < numberOfAdditionalWaitingStacks) 421 { 379 { 422 for(G4int i=numberOfAdditionalWaitingStack 380 for(G4int i=numberOfAdditionalWaitingStacks; i>iAdd; --i) 423 { 381 { 424 delete additionalWaitingStacks[i]; 382 delete additionalWaitingStacks[i]; 425 } 383 } 426 } 384 } 427 } 385 } 428 386 429 void G4StackManager:: 387 void G4StackManager:: 430 TransferStackedTracks(G4ClassificationOfNewTra 388 TransferStackedTracks(G4ClassificationOfNewTrack origin, 431 G4ClassificationOfNewTra 389 G4ClassificationOfNewTrack destination) 432 { 390 { 433 if(origin==destination) return; 391 if(origin==destination) return; 434 if(origin==fKill) return; 392 if(origin==fKill) return; 435 G4TrackStack* originStack = nullptr; 393 G4TrackStack* originStack = nullptr; 436 switch(origin) 394 switch(origin) 437 { 395 { 438 case fUrgent: 396 case fUrgent: 439 originStack = nullptr; 397 originStack = nullptr; 440 break; 398 break; 441 case fWaiting: 399 case fWaiting: 442 originStack = waitingStack; 400 originStack = waitingStack; 443 break; 401 break; 444 case fPostpone: 402 case fPostpone: 445 originStack = postponeStack; 403 originStack = postponeStack; 446 break; 404 break; 447 default: 405 default: 448 G4int i = origin - 10; 406 G4int i = origin - 10; 449 if(i<=numberOfAdditionalWaitingStacks) 407 if(i<=numberOfAdditionalWaitingStacks) 450 { 408 { 451 originStack = additionalWaitingStacks[ 409 originStack = additionalWaitingStacks[i-1]; 452 } 410 } 453 else << 454 { << 455 G4ExceptionDescription ED; << 456 ED << "Invalid origin stack ID " << or << 457 G4Exception("G4StackManager::TransferS << 458 FatalException, ED); << 459 } << 460 break; 411 break; 461 } 412 } 462 413 463 if(destination==fKill) 414 if(destination==fKill) 464 { 415 { 465 if(originStack != nullptr) 416 if(originStack != nullptr) 466 { 417 { 467 originStack->clearAndDestroy(); 418 originStack->clearAndDestroy(); 468 } 419 } 469 else 420 else 470 { 421 { 471 urgentStack->clearAndDestroy(); 422 urgentStack->clearAndDestroy(); 472 } 423 } 473 } 424 } 474 else 425 else 475 { 426 { 476 G4TrackStack* targetStack = nullptr; 427 G4TrackStack* targetStack = nullptr; 477 switch(destination) 428 switch(destination) 478 { 429 { 479 case fUrgent: 430 case fUrgent: 480 targetStack = nullptr; 431 targetStack = nullptr; 481 break; 432 break; 482 case fWaiting: 433 case fWaiting: 483 targetStack = waitingStack; 434 targetStack = waitingStack; 484 break; 435 break; 485 case fPostpone: 436 case fPostpone: 486 targetStack = postponeStack; 437 targetStack = postponeStack; 487 break; 438 break; 488 default: 439 default: 489 G4int i = destination - 10; 440 G4int i = destination - 10; 490 if(i<=numberOfAdditionalWaitingStacks) 441 if(i<=numberOfAdditionalWaitingStacks) 491 { 442 { 492 targetStack = additionalWaitingStack 443 targetStack = additionalWaitingStacks[i-1]; 493 } 444 } 494 else << 495 { << 496 G4ExceptionDescription ED; << 497 ED << "Invalid origin stack ID " << << 498 G4Exception("G4StackManager::Transfe << 499 FatalException, ED); << 500 } << 501 break; 445 break; 502 } 446 } 503 if(originStack != nullptr) 447 if(originStack != nullptr) 504 { 448 { 505 if(targetStack != nullptr) 449 if(targetStack != nullptr) 506 { 450 { 507 originStack->TransferTo(targetStack); 451 originStack->TransferTo(targetStack); 508 } 452 } 509 else 453 else 510 { 454 { 511 originStack->TransferTo(urgentStack); 455 originStack->TransferTo(urgentStack); 512 } 456 } 513 } 457 } 514 else 458 else 515 { 459 { 516 urgentStack->TransferTo(targetStack); 460 urgentStack->TransferTo(targetStack); 517 } 461 } 518 } 462 } 519 return; 463 return; 520 } 464 } 521 465 522 void G4StackManager:: 466 void G4StackManager:: 523 TransferOneStackedTrack(G4ClassificationOfNewT 467 TransferOneStackedTrack(G4ClassificationOfNewTrack origin, 524 G4ClassificationOfNewT 468 G4ClassificationOfNewTrack destination) 525 { 469 { 526 if(origin==destination) return; 470 if(origin==destination) return; 527 if(origin==fKill) return; 471 if(origin==fKill) return; 528 G4TrackStack* originStack = nullptr; 472 G4TrackStack* originStack = nullptr; 529 switch(origin) 473 switch(origin) 530 { 474 { 531 case fUrgent: 475 case fUrgent: 532 originStack = nullptr; 476 originStack = nullptr; 533 break; 477 break; 534 case fWaiting: 478 case fWaiting: 535 originStack = waitingStack; 479 originStack = waitingStack; 536 break; 480 break; 537 case fPostpone: 481 case fPostpone: 538 originStack = postponeStack; 482 originStack = postponeStack; 539 break; 483 break; 540 default: 484 default: 541 G4int i = origin - 10; 485 G4int i = origin - 10; 542 if(i<=numberOfAdditionalWaitingStacks) 486 if(i<=numberOfAdditionalWaitingStacks) 543 { 487 { 544 originStack = additionalWaitingStacks[ 488 originStack = additionalWaitingStacks[i-1]; 545 } 489 } 546 else << 547 { << 548 G4ExceptionDescription ED; << 549 ED << "Invalid origin stack ID " << or << 550 G4Exception("G4StackManager::TransferS << 551 FatalException, ED); << 552 } << 553 break; 490 break; 554 } 491 } 555 492 556 G4StackedTrack aStackedTrack; 493 G4StackedTrack aStackedTrack; 557 if(destination==fKill) 494 if(destination==fKill) 558 { 495 { 559 if( originStack != nullptr && (originStack << 496 if( originStack != nullptr && originStack->GetNTrack() ) 560 { 497 { 561 aStackedTrack = originStack->PopFromStac 498 aStackedTrack = originStack->PopFromStack(); 562 delete aStackedTrack.GetTrack(); 499 delete aStackedTrack.GetTrack(); 563 delete aStackedTrack.GetTrajectory(); 500 delete aStackedTrack.GetTrajectory(); 564 } 501 } 565 else if (urgentStack->GetNTrack() != 0u ) << 502 else if (urgentStack->GetNTrack() ) 566 { 503 { 567 aStackedTrack = urgentStack->PopFromStac 504 aStackedTrack = urgentStack->PopFromStack(); 568 delete aStackedTrack.GetTrack(); 505 delete aStackedTrack.GetTrack(); 569 delete aStackedTrack.GetTrajectory(); 506 delete aStackedTrack.GetTrajectory(); 570 } 507 } 571 } 508 } 572 else 509 else 573 { 510 { 574 G4TrackStack* targetStack = nullptr; 511 G4TrackStack* targetStack = nullptr; 575 switch(destination) 512 switch(destination) 576 { 513 { 577 case fUrgent: 514 case fUrgent: 578 targetStack = nullptr; 515 targetStack = nullptr; 579 break; 516 break; 580 case fWaiting: 517 case fWaiting: 581 targetStack = waitingStack; 518 targetStack = waitingStack; 582 break; 519 break; 583 case fPostpone: 520 case fPostpone: 584 targetStack = postponeStack; 521 targetStack = postponeStack; 585 break; 522 break; 586 default: 523 default: 587 G4int i = destination - 10; 524 G4int i = destination - 10; 588 if(i<=numberOfAdditionalWaitingStacks) 525 if(i<=numberOfAdditionalWaitingStacks) 589 { 526 { 590 targetStack = additionalWaitingStack 527 targetStack = additionalWaitingStacks[i-1]; 591 } 528 } 592 else << 593 { << 594 G4ExceptionDescription ED; << 595 ED << "Invalid destination stack ID << 596 G4Exception("G4StackManager::Transfe << 597 FatalException, ED); << 598 } << 599 break; 529 break; 600 } 530 } 601 if((originStack != nullptr) && (originStac << 531 if(originStack && originStack->GetNTrack()) 602 { 532 { 603 aStackedTrack = originStack->PopFromStac 533 aStackedTrack = originStack->PopFromStack(); 604 if(targetStack != nullptr) { targetStack << 534 if(targetStack) { targetStack->PushToStack(aStackedTrack); } 605 else { urgentStack->PushToSta 535 else { urgentStack->PushToStack(aStackedTrack); } 606 } 536 } 607 else if(urgentStack->GetNTrack() != 0u) << 537 else if(urgentStack->GetNTrack()) 608 { 538 { 609 aStackedTrack = urgentStack->PopFromStac 539 aStackedTrack = urgentStack->PopFromStack(); 610 if(targetStack != nullptr) { targetStack << 540 if(targetStack) { targetStack->PushToStack(aStackedTrack); } 611 else { urgentStack->PushToSta 541 else { urgentStack->PushToStack(aStackedTrack); } 612 } 542 } 613 } 543 } 614 return; 544 return; 615 } 545 } 616 546 617 void G4StackManager::clear() 547 void G4StackManager::clear() 618 { 548 { 619 ClearUrgentStack(); 549 ClearUrgentStack(); 620 ClearWaitingStack(); 550 ClearWaitingStack(); 621 for(G4int i=1; i<=numberOfAdditionalWaitingS 551 for(G4int i=1; i<=numberOfAdditionalWaitingStacks; ++i) 622 { 552 { 623 ClearWaitingStack(i); 553 ClearWaitingStack(i); 624 } 554 } 625 } 555 } 626 556 627 void G4StackManager::ClearUrgentStack() 557 void G4StackManager::ClearUrgentStack() 628 { 558 { 629 urgentStack->clearAndDestroy(); 559 urgentStack->clearAndDestroy(); 630 } 560 } 631 561 632 void G4StackManager::ClearWaitingStack(G4int i 562 void G4StackManager::ClearWaitingStack(G4int i) 633 { 563 { 634 if(i==0) 564 if(i==0) 635 { 565 { 636 waitingStack->clearAndDestroy(); 566 waitingStack->clearAndDestroy(); 637 } 567 } 638 else 568 else 639 { 569 { 640 if(i<=numberOfAdditionalWaitingStacks) 570 if(i<=numberOfAdditionalWaitingStacks) 641 { 571 { 642 additionalWaitingStacks[i-1]->clearAndDe 572 additionalWaitingStacks[i-1]->clearAndDestroy(); 643 } 573 } 644 } 574 } 645 } 575 } 646 576 647 void G4StackManager::ClearPostponeStack() 577 void G4StackManager::ClearPostponeStack() 648 { 578 { 649 postponeStack->clearAndDestroy(); 579 postponeStack->clearAndDestroy(); 650 } 580 } 651 581 652 G4int G4StackManager::GetNTotalTrack() const 582 G4int G4StackManager::GetNTotalTrack() const 653 { 583 { 654 std::size_t n = urgentStack->GetNTrack() << 584 G4int n = urgentStack->GetNTrack() 655 + waitingStack->GetNTrack() << 585 + waitingStack->GetNTrack() 656 + postponeStack->GetNTrack(); << 586 + postponeStack->GetNTrack(); 657 for(G4int i=1; i<=numberOfAdditionalWaitingS 587 for(G4int i=1; i<=numberOfAdditionalWaitingStacks; ++i) 658 { 588 { 659 n += additionalWaitingStacks[i-1]->GetNTra 589 n += additionalWaitingStacks[i-1]->GetNTrack(); 660 } 590 } 661 return G4int(n); << 591 return n; 662 } 592 } 663 593 664 G4int G4StackManager::GetNUrgentTrack() const 594 G4int G4StackManager::GetNUrgentTrack() const 665 { 595 { 666 return (G4int)urgentStack->GetNTrack(); << 596 return urgentStack->GetNTrack(); 667 } 597 } 668 598 669 G4int G4StackManager::GetNWaitingTrack(int i) 599 G4int G4StackManager::GetNWaitingTrack(int i) const 670 { 600 { 671 if(i==0) 601 if(i==0) 672 { 602 { 673 return (G4int)waitingStack->GetNTrack(); << 603 return waitingStack->GetNTrack(); 674 } 604 } 675 << 605 else 676 if(i<=numberOfAdditionalWaitingStacks) << 677 { 606 { 678 return (G4int)additionalWaitingStacks[i-1] << 607 if(i<=numberOfAdditionalWaitingStacks) >> 608 { >> 609 return additionalWaitingStacks[i-1]->GetNTrack(); >> 610 } 679 } 611 } 680 << 681 return 0; 612 return 0; 682 } 613 } 683 614 684 G4int G4StackManager::GetNPostponedTrack() con 615 G4int G4StackManager::GetNPostponedTrack() const 685 { 616 { 686 return (G4int)postponeStack->GetNTrack(); << 617 return postponeStack->GetNTrack(); 687 } 618 } 688 619 689 void G4StackManager::SetVerboseLevel( G4int co 620 void G4StackManager::SetVerboseLevel( G4int const value ) 690 { 621 { 691 verboseLevel = value; 622 verboseLevel = value; 692 for(auto& sets : subEvtStackMap) << 693 { sets.second->SetVerboseLevel(value); } << 694 } 623 } 695 624 696 void G4StackManager::SetUserStackingAction(G4U 625 void G4StackManager::SetUserStackingAction(G4UserStackingAction* value) 697 { 626 { 698 userStackingAction = value; 627 userStackingAction = value; 699 if(userStackingAction != nullptr) << 628 if(userStackingAction) 700 { 629 { 701 userStackingAction->SetStackManager(this); 630 userStackingAction->SetStackManager(this); 702 } 631 } 703 } 632 } 704 633 705 void G4StackManager::DefineDefaultClassificati << 634 G4ClassificationOfNewTrack G4StackManager:: >> 635 DefaultClassification(G4Track* aTrack) 706 { 636 { 707 fDefaultClassification = fUrgent; << 637 G4ClassificationOfNewTrack classification = fUrgent; 708 fExceptionSeverity = G4ExceptionSeverity::Ig << 638 if( aTrack->GetTrackStatus() == fPostponeToNextEvent ) 709 << 710 if(defClassPartDef.size()>0) << 711 { << 712 auto pdm = defClassPartDef.find(aTrack->Ge << 713 if(pdm!=defClassPartDef.end()) << 714 { << 715 fDefaultClassification = pdm->second.fir << 716 fExceptionSeverity = pdm->second.second; << 717 } << 718 } << 719 else if(defClassTrackStatus.size()>0) << 720 { << 721 auto tsm = defClassTrackStatus.find(aTrack << 722 if(tsm!=defClassTrackStatus.end()) << 723 { << 724 fDefaultClassification = tsm->second.fir << 725 fExceptionSeverity = tsm->second.second; << 726 } << 727 } << 728 else if( aTrack->GetTrackStatus() == fSuspen << 729 { fDefaultClassification = fWaiting; } << 730 else if( aTrack->GetTrackStatus() == fPostpo << 731 { fDefaultClassification = fPostpone; } << 732 } << 733 << 734 void G4StackManager::SetDefaultClassification( << 735 G4ClassificationOfNewTrack val, G << 736 { << 737 auto tsm = defClassTrackStatus.find(ts); << 738 if(tsm==defClassTrackStatus.end()) << 739 { defClassTrackStatus[ts] = std::pair(val,es << 740 else << 741 { 639 { 742 if(tsm->second.first!=val) << 640 classification = fPostpone; 743 { // alternating default classification << 744 G4ExceptionDescription ed; << 745 ed << "Default classification for track << 746 << " is changed from " << tsm->second << 747 << val << "."; << 748 G4Exception("G4StackManager::SetDefaultC << 749 "Event11051",JustWarning,ed) << 750 tsm->second.first = val; << 751 } << 752 // Change severity if needed. << 753 if(tsm->second.second>es) tsm->second.seco << 754 } 641 } >> 642 return classification; 755 } 643 } 756 << 757 void G4StackManager::SetDefaultClassification( << 758 G4ClassificationOfNewTrack val, G << 759 { << 760 auto pdm = defClassPartDef.find(pd); << 761 if(pdm==defClassPartDef.end()) << 762 { defClassPartDef[pd] = std::pair(val,es); } << 763 else << 764 { << 765 if(pdm->second.first!=val) << 766 { // alternating default classification << 767 G4ExceptionDescription ed; << 768 ed << "Default classification for partic << 769 << " is changed from " << pdm->second << 770 << val << "."; << 771 G4Exception("G4StackManager::SetDefaultC << 772 "Event11052", JustWarning,ed << 773 pdm->second.first = val; << 774 } << 775 // Change severity if needed. << 776 if(pdm->second.second>es) pdm->second.seco << 777 } << 778 } << 779 << 780 void G4StackManager::RegisterSubEventType(G4in << 781 { << 782 if(subEvtStackMap.find(ty)==subEvtStackMap.e << 783 { << 784 subEvtStackMap[ty] = new G4SubEventTrackSt << 785 subEvtTypes.push_back(ty); << 786 #ifdef G4VERBOSE << 787 subEvtStackMap[ty]->SetVerboseLevel(verbos << 788 if( verboseLevel > 0 ) << 789 { << 790 G4cout << " ---> New sub-event stack f << 791 << ty << " is created. Classifica << 792 << subEvtTypes.size() + 99 << "." << 793 } << 794 } << 795 else << 796 { << 797 if( verboseLevel > 1 ) << 798 { << 799 G4cout << " ---> Sub-event stack for s << 800 << ty << " already registered." < << 801 } << 802 #endif << 803 } << 804 } << 805 << 806 void G4StackManager::ReleaseSubEvent(G4int ty) << 807 { << 808 auto ses = subEvtStackMap.find(ty); << 809 if(ses==subEvtStackMap.end()) << 810 { << 811 G4ExceptionDescription ED; << 812 ED << "Un-registered sub-event type " << t << 813 G4Exception("G4StackManager::PopSubEvent", << 814 FatalException,ED); << 815 return; // NOLINT: Required to silence Cov << 816 } << 817 << 818 ses->second->ReleaseSubEvent(); << 819 } << 820 << 821 << 822 644