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