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