Geant4 Cross Reference |
1 // 2 // ******************************************************************** 3 // * License and Disclaimer * 4 // * * 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. * 10 // * * 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitation of liability. * 17 // * * 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************************************** 25 // 26 // G4StackManager class implementation 27 // 28 // Author: Makoto Asai, 1996 29 // Adding sub-event parallelism 30 // 23/Aug/2023 31 // -------------------------------------------------------------------- 32 33 #include "G4StackManager.hh" 34 #include "G4StackingMessenger.hh" 35 #include "G4VTrajectory.hh" 36 #include "G4Event.hh" 37 #include "G4ios.hh" 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() 49 { 50 theMessenger = new G4StackingMessenger(this); 51 #ifdef G4_USESMARTSTACK 52 urgentStack = new G4SmartTrackStack; 53 // G4cout << "+++ G4StackManager uses G4SmartTrackStack. +++" << G4endl; 54 #else 55 urgentStack = new G4TrackStack(5000); 56 // G4cout << "+++ G4StackManager uses ordinary G4TrackStack. +++" << G4endl; 57 #endif 58 waitingStack = new G4TrackStack(1000); 59 postponeStack = new G4TrackStack(1000); 60 } 61 62 G4StackManager::~G4StackManager() 63 { 64 delete userStackingAction; 65 66 #ifdef G4VERBOSE 67 if(verboseLevel>0) 68 { 69 G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl; 70 G4cout << " Maximum number of tracks in the urgent stack : " << urgentStack->GetMaxNTrack() << G4endl; 71 G4cout << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << G4endl; 72 } 73 #endif 74 delete urgentStack; 75 delete waitingStack; 76 delete postponeStack; 77 delete theMessenger; 78 if(numberOfAdditionalWaitingStacks>0) 79 { 80 for(G4int i=0; i<numberOfAdditionalWaitingStacks; ++i) 81 { 82 delete additionalWaitingStacks[i]; 83 } 84 } 85 } 86 87 G4int G4StackManager:: 88 PushOneTrack(G4Track* newTrack, G4VTrajectory* newTrajectory) 89 { 90 const G4ParticleDefinition* pd = newTrack->GetParticleDefinition(); 91 if(pd->GetParticleDefinitionID() < 0) 92 { 93 G4ExceptionDescription ED; 94 ED << "A track without proper process manager is pushed \ 95 into the track stack.\n" 96 << " Particle name : " << pd->GetParticleName() << " -- "; 97 if(newTrack->GetParentID()==0) 98 { 99 ED << "created by a primary particle generator."; 100 } 101 else 102 { 103 const G4VProcess* vp = newTrack->GetCreatorProcess(); 104 if(vp != nullptr) 105 { 106 ED << "created by " << vp->GetProcessName() << "."; 107 } 108 else 109 { 110 ED << "creaded by unknown process."; 111 } 112 } 113 G4Exception("G4StackManager::PushOneTrack","Event10051", 114 FatalException,ED); 115 delete newTrack; 116 return GetNUrgentTrack(); 117 } 118 119 DefineDefaultClassification( newTrack ); 120 G4ClassificationOfNewTrack classification = fDefaultClassification; 121 if(userStackingAction!=nullptr) 122 { 123 classification = userStackingAction->ClassifyNewTrack( newTrack ); 124 if(classification != fDefaultClassification) 125 { 126 if(fExceptionSeverity!=G4ExceptionSeverity::IgnoreTheIssue) 127 { 128 G4ExceptionDescription ed; 129 ed << "UserStackingAction has changed the track classification from " 130 << fDefaultClassification << " to " << classification << ". "; 131 G4Exception("G4StackManager::PushOneTrack","Event10052", 132 fExceptionSeverity,ed); 133 } 134 } 135 } 136 if(newTrack->GetTrackStatus() == fSuspendAndWait && classification > 0) 137 // to avoid this track sent to Waiting stack again 138 { newTrack->SetTrackStatus( fSuspend ); } 139 140 #ifdef G4VERBOSE 141 if( verboseLevel > 1 ) 142 { 143 G4cout << "### Storing a track (" 144 << newTrack->GetParticleDefinition()->GetParticleName() 145 << ",trackID=" << newTrack->GetTrackID() 146 << ",parentID=" << newTrack->GetParentID() << ") "; 147 if(newTrack->GetParentID()==0) 148 { G4cout << "created by a primary particle generator "; } 149 else 150 { 151 const G4VProcess* vp = newTrack->GetCreatorProcess(); 152 if(vp != nullptr) 153 { G4cout << "created by " << vp->GetProcessName() << " "; } 154 else 155 { G4cout << "creaded by unknown process "; } 156 } 157 G4cout << "into stack #" << classification << G4endl; 158 } 159 #endif 160 G4StackedTrack newStackedTrack( newTrack, newTrajectory ); 161 SortOut(newStackedTrack,classification); 162 163 return GetNUrgentTrack(); 164 } 165 166 G4Track* G4StackManager::PopNextTrack(G4VTrajectory** newTrajectory) 167 { 168 #ifdef G4VERBOSE 169 if( verboseLevel > 1 ) 170 { 171 G4cout << "### pop requested out of " 172 << GetNUrgentTrack() << " stacked tracks." << G4endl; 173 } 174 #endif 175 176 while( GetNUrgentTrack() == 0 ) 177 { 178 #ifdef G4VERBOSE 179 if( verboseLevel > 1 ) 180 { 181 G4cout << "### " << GetNWaitingTrack() 182 << " waiting tracks are re-classified to" << G4endl; 183 } 184 #endif 185 waitingStack->TransferTo(urgentStack); 186 if(numberOfAdditionalWaitingStacks>0) 187 { 188 for(G4int i=0; i<numberOfAdditionalWaitingStacks; ++i) 189 { 190 if(i==0) 191 { 192 additionalWaitingStacks[0]->TransferTo(waitingStack); 193 } 194 else 195 { 196 additionalWaitingStacks[i]->TransferTo(additionalWaitingStacks[i-1]); 197 } 198 } 199 } 200 if(userStackingAction != nullptr) 201 { 202 userStackingAction->NewStage(); 203 } 204 205 #ifdef G4VERBOSE 206 if( verboseLevel > 1 ) 207 G4cout << " " << GetNUrgentTrack() 208 << " urgent tracks and " << GetNWaitingTrack() 209 << " waiting tracks." << G4endl; 210 #endif 211 if( ( GetNUrgentTrack()==0 ) && ( GetNWaitingTrack()==0 ) ) 212 return nullptr; 213 } 214 215 G4StackedTrack selectedStackedTrack = urgentStack->PopFromStack(); 216 G4Track * selectedTrack = selectedStackedTrack.GetTrack(); 217 *newTrajectory = selectedStackedTrack.GetTrajectory(); 218 219 #ifdef G4VERBOSE 220 if( verboseLevel > 2 ) 221 { 222 G4cout << "Selected G4StackedTrack : " << &selectedStackedTrack 223 << " with G4Track " << selectedStackedTrack.GetTrack() 224 << " (trackID " << selectedStackedTrack.GetTrack()->GetTrackID() 225 << ", parentID " << selectedStackedTrack.GetTrack()->GetParentID() 226 << ")" << G4endl; 227 } 228 #endif 229 230 return selectedTrack; 231 } 232 233 void G4StackManager::ReClassify() 234 { 235 G4StackedTrack aStackedTrack; 236 G4TrackStack tmpStack; 237 238 if( userStackingAction == nullptr ) return; 239 if( GetNUrgentTrack() == 0 ) return; 240 241 urgentStack->TransferTo(&tmpStack); 242 while( tmpStack.GetNTrack() > 0 ) 243 { 244 aStackedTrack=tmpStack.PopFromStack(); 245 DefineDefaultClassification( aStackedTrack.GetTrack() ); 246 G4ClassificationOfNewTrack classification = fDefaultClassification; 247 if(userStackingAction!=nullptr) 248 { 249 classification = userStackingAction->ClassifyNewTrack( aStackedTrack.GetTrack() ); 250 if(classification != fDefaultClassification) 251 { 252 if(fExceptionSeverity!=G4ExceptionSeverity::IgnoreTheIssue) 253 { 254 G4ExceptionDescription ed; 255 ed << "UserStackingAction has changed the track classification from " 256 << fDefaultClassification << " to " << classification << ". "; 257 G4Exception("G4StackManager::PushOneTrack","Event10052", 258 fExceptionSeverity,ed); 259 } 260 } 261 } 262 if(aStackedTrack.GetTrack()->GetTrackStatus() == fSuspendAndWait && classification > 0) 263 // to avoid this track sent to Waiting stack again 264 { aStackedTrack.GetTrack()->SetTrackStatus( fSuspend ); } 265 266 SortOut(aStackedTrack,classification); 267 } 268 } 269 270 G4int G4StackManager::PrepareNewEvent(G4Event* currentEvent) 271 { 272 if(userStackingAction != nullptr) 273 { 274 userStackingAction->PrepareNewEvent(); 275 } 276 277 // Set the urgentStack in a defined state. Not doing it would 278 // affect reproducibility 279 // 280 urgentStack->clearAndDestroy(); 281 282 G4int n_passedFromPrevious = 0; 283 284 if( GetNPostponedTrack() > 0 ) 285 { 286 #ifdef G4VERBOSE 287 if( verboseLevel > 1 ) 288 { 289 G4cout << GetNPostponedTrack() 290 << " postponed tracked are now shifted to the stack." << G4endl; 291 } 292 #endif 293 294 G4StackedTrack aStackedTrack; 295 G4TrackStack tmpStack; 296 297 postponeStack->TransferTo(&tmpStack); 298 299 while( tmpStack.GetNTrack() > 0 ) 300 { 301 aStackedTrack=tmpStack.PopFromStack(); 302 G4Track* aTrack = aStackedTrack.GetTrack(); 303 DefineDefaultClassification( aTrack ); 304 G4ClassificationOfNewTrack classification = fDefaultClassification; 305 if(userStackingAction!=nullptr) 306 { 307 classification = userStackingAction->ClassifyNewTrack( aTrack ); 308 if(classification != fDefaultClassification) 309 { 310 if(fExceptionSeverity!=G4ExceptionSeverity::IgnoreTheIssue) 311 { 312 G4ExceptionDescription ed; 313 ed << "UserStackingAction has changed the track classification from " 314 << fDefaultClassification << " to " << classification << ". "; 315 G4Exception("G4StackManager::PushOneTrack","Event10052", 316 fExceptionSeverity,ed); 317 } 318 } 319 } 320 if(classification!=fKill) 321 { 322 aTrack->SetParentID(-1); 323 aTrack->SetTrackID(-(++n_passedFromPrevious)); 324 } 325 else if(aTrack->GetTrackStatus() == fSuspendAndWait && classification > 0) 326 // to avoid this track sent to Waiting stack again 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& aStackedTrack, G4ClassificationOfNewTrack classification) 341 { 342 if(classification==fKill) // delete the without stacking 343 { 344 G4Track* newTrack = aStackedTrack.GetTrack(); 345 G4VTrajectory* newTrajectory = aStackedTrack.GetTrajectory(); 346 #ifdef G4VERBOSE 347 if( verboseLevel > 1 ) 348 { 349 G4cout << " ---> G4Track " << newTrack << " (trackID " 350 << newTrack->GetTrackID() << ", parentID " 351 << newTrack->GetParentID() << ") is not to be stored." << G4endl; 352 } 353 #endif 354 delete newTrack; 355 delete newTrajectory; 356 } 357 else 358 { 359 switch (classification) 360 { 361 case fUrgent: 362 urgentStack->PushToStack( aStackedTrack ); 363 break; 364 case fWaiting: 365 waitingStack->PushToStack( aStackedTrack ); 366 break; 367 case fPostpone: 368 postponeStack->PushToStack( aStackedTrack ); 369 break; 370 default: 371 if(classification < 100) 372 { 373 // pushing to additional waiting stack 374 G4int i = classification - 10; 375 if(i<1 || i>numberOfAdditionalWaitingStacks) 376 { 377 G4ExceptionDescription ED; 378 ED << "invalid classification " << classification << G4endl; 379 G4Exception("G4StackManager::SortOut", "Event0051", 380 FatalException,ED); 381 } 382 else 383 { 384 additionalWaitingStacks[i-1]->PushToStack( aStackedTrack ); 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 " << classification << G4endl; 396 G4Exception("G4StackManager::SortOut", "Event0051", 397 FatalException,ED); 398 } 399 else 400 { 401 ses->second->PushToStack( aStackedTrack ); 402 } 403 } 404 break; 405 } 406 } 407 } 408 409 void G4StackManager::SetNumberOfAdditionalWaitingStacks(G4int iAdd) 410 { 411 if(iAdd > numberOfAdditionalWaitingStacks) 412 { 413 for(G4int i=numberOfAdditionalWaitingStacks; i<iAdd; ++i) 414 { 415 auto* newStack = new G4TrackStack; 416 additionalWaitingStacks.push_back(newStack); 417 } 418 numberOfAdditionalWaitingStacks = iAdd; 419 } 420 else if (iAdd < numberOfAdditionalWaitingStacks) 421 { 422 for(G4int i=numberOfAdditionalWaitingStacks; i>iAdd; --i) 423 { 424 delete additionalWaitingStacks[i]; 425 } 426 } 427 } 428 429 void G4StackManager:: 430 TransferStackedTracks(G4ClassificationOfNewTrack origin, 431 G4ClassificationOfNewTrack destination) 432 { 433 if(origin==destination) return; 434 if(origin==fKill) return; 435 G4TrackStack* originStack = nullptr; 436 switch(origin) 437 { 438 case fUrgent: 439 originStack = nullptr; 440 break; 441 case fWaiting: 442 originStack = waitingStack; 443 break; 444 case fPostpone: 445 originStack = postponeStack; 446 break; 447 default: 448 G4int i = origin - 10; 449 if(i<=numberOfAdditionalWaitingStacks) 450 { 451 originStack = additionalWaitingStacks[i-1]; 452 } 453 else 454 { 455 G4ExceptionDescription ED; 456 ED << "Invalid origin stack ID " << origin; 457 G4Exception("G4StackManager::TransferStackedTracks","Stack0911", 458 FatalException, ED); 459 } 460 break; 461 } 462 463 if(destination==fKill) 464 { 465 if(originStack != nullptr) 466 { 467 originStack->clearAndDestroy(); 468 } 469 else 470 { 471 urgentStack->clearAndDestroy(); 472 } 473 } 474 else 475 { 476 G4TrackStack* targetStack = nullptr; 477 switch(destination) 478 { 479 case fUrgent: 480 targetStack = nullptr; 481 break; 482 case fWaiting: 483 targetStack = waitingStack; 484 break; 485 case fPostpone: 486 targetStack = postponeStack; 487 break; 488 default: 489 G4int i = destination - 10; 490 if(i<=numberOfAdditionalWaitingStacks) 491 { 492 targetStack = additionalWaitingStacks[i-1]; 493 } 494 else 495 { 496 G4ExceptionDescription ED; 497 ED << "Invalid origin stack ID " << origin; 498 G4Exception("G4StackManager::TransferStackedTracks","Stack0911", 499 FatalException, ED); 500 } 501 break; 502 } 503 if(originStack != nullptr) 504 { 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 } 519 return; 520 } 521 522 void G4StackManager:: 523 TransferOneStackedTrack(G4ClassificationOfNewTrack origin, 524 G4ClassificationOfNewTrack destination) 525 { 526 if(origin==destination) return; 527 if(origin==fKill) return; 528 G4TrackStack* originStack = nullptr; 529 switch(origin) 530 { 531 case fUrgent: 532 originStack = nullptr; 533 break; 534 case fWaiting: 535 originStack = waitingStack; 536 break; 537 case fPostpone: 538 originStack = postponeStack; 539 break; 540 default: 541 G4int i = origin - 10; 542 if(i<=numberOfAdditionalWaitingStacks) 543 { 544 originStack = additionalWaitingStacks[i-1]; 545 } 546 else 547 { 548 G4ExceptionDescription ED; 549 ED << "Invalid origin stack ID " << origin; 550 G4Exception("G4StackManager::TransferStackedTracks","Stack0911", 551 FatalException, ED); 552 } 553 break; 554 } 555 556 G4StackedTrack aStackedTrack; 557 if(destination==fKill) 558 { 559 if( originStack != nullptr && (originStack->GetNTrack() != 0u) ) 560 { 561 aStackedTrack = originStack->PopFromStack(); 562 delete aStackedTrack.GetTrack(); 563 delete aStackedTrack.GetTrajectory(); 564 } 565 else if (urgentStack->GetNTrack() != 0u ) 566 { 567 aStackedTrack = urgentStack->PopFromStack(); 568 delete aStackedTrack.GetTrack(); 569 delete aStackedTrack.GetTrajectory(); 570 } 571 } 572 else 573 { 574 G4TrackStack* targetStack = nullptr; 575 switch(destination) 576 { 577 case fUrgent: 578 targetStack = nullptr; 579 break; 580 case fWaiting: 581 targetStack = waitingStack; 582 break; 583 case fPostpone: 584 targetStack = postponeStack; 585 break; 586 default: 587 G4int i = destination - 10; 588 if(i<=numberOfAdditionalWaitingStacks) 589 { 590 targetStack = additionalWaitingStacks[i-1]; 591 } 592 else 593 { 594 G4ExceptionDescription ED; 595 ED << "Invalid destination stack ID " << destination; 596 G4Exception("G4StackManager::TransferStackedTracks","Stack0911", 597 FatalException, ED); 598 } 599 break; 600 } 601 if((originStack != nullptr) && (originStack->GetNTrack() != 0u)) 602 { 603 aStackedTrack = originStack->PopFromStack(); 604 if(targetStack != nullptr) { targetStack->PushToStack(aStackedTrack); } 605 else { urgentStack->PushToStack(aStackedTrack); } 606 } 607 else if(urgentStack->GetNTrack() != 0u) 608 { 609 aStackedTrack = urgentStack->PopFromStack(); 610 if(targetStack != nullptr) { targetStack->PushToStack(aStackedTrack); } 611 else { urgentStack->PushToStack(aStackedTrack); } 612 } 613 } 614 return; 615 } 616 617 void G4StackManager::clear() 618 { 619 ClearUrgentStack(); 620 ClearWaitingStack(); 621 for(G4int i=1; i<=numberOfAdditionalWaitingStacks; ++i) 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]->clearAndDestroy(); 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<=numberOfAdditionalWaitingStacks; ++i) 658 { 659 n += additionalWaitingStacks[i-1]->GetNTrack(); 660 } 661 return G4int(n); 662 } 663 664 G4int G4StackManager::GetNUrgentTrack() const 665 { 666 return (G4int)urgentStack->GetNTrack(); 667 } 668 669 G4int G4StackManager::GetNWaitingTrack(int i) const 670 { 671 if(i==0) 672 { 673 return (G4int)waitingStack->GetNTrack(); 674 } 675 676 if(i<=numberOfAdditionalWaitingStacks) 677 { 678 return (G4int)additionalWaitingStacks[i-1]->GetNTrack(); 679 } 680 681 return 0; 682 } 683 684 G4int G4StackManager::GetNPostponedTrack() const 685 { 686 return (G4int)postponeStack->GetNTrack(); 687 } 688 689 void G4StackManager::SetVerboseLevel( G4int const value ) 690 { 691 verboseLevel = value; 692 for(auto& sets : subEvtStackMap) 693 { sets.second->SetVerboseLevel(value); } 694 } 695 696 void G4StackManager::SetUserStackingAction(G4UserStackingAction* value) 697 { 698 userStackingAction = value; 699 if(userStackingAction != nullptr) 700 { 701 userStackingAction->SetStackManager(this); 702 } 703 } 704 705 void G4StackManager::DefineDefaultClassification(const G4Track* aTrack) 706 { 707 fDefaultClassification = fUrgent; 708 fExceptionSeverity = G4ExceptionSeverity::IgnoreTheIssue; 709 710 if(defClassPartDef.size()>0) 711 { 712 auto pdm = defClassPartDef.find(aTrack->GetParticleDefinition()); 713 if(pdm!=defClassPartDef.end()) 714 { 715 fDefaultClassification = pdm->second.first; 716 fExceptionSeverity = pdm->second.second; 717 } 718 } 719 else if(defClassTrackStatus.size()>0) 720 { 721 auto tsm = defClassTrackStatus.find(aTrack->GetTrackStatus()); 722 if(tsm!=defClassTrackStatus.end()) 723 { 724 fDefaultClassification = tsm->second.first; 725 fExceptionSeverity = tsm->second.second; 726 } 727 } 728 else if( aTrack->GetTrackStatus() == fSuspendAndWait ) 729 { fDefaultClassification = fWaiting; } 730 else if( aTrack->GetTrackStatus() == fPostponeToNextEvent ) 731 { fDefaultClassification = fPostpone; } 732 } 733 734 void G4StackManager::SetDefaultClassification(G4TrackStatus ts, 735 G4ClassificationOfNewTrack val, G4ExceptionSeverity es) 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 status " << ts 746 << " is changed from " << tsm->second.first << " to " 747 << val << "."; 748 G4Exception("G4StackManager::SetDefaultClassification", 749 "Event11051",JustWarning,ed); 750 tsm->second.first = val; 751 } 752 // Change severity if needed. 753 if(tsm->second.second>es) tsm->second.second = es; 754 } 755 } 756 757 void G4StackManager::SetDefaultClassification(const G4ParticleDefinition* pd, 758 G4ClassificationOfNewTrack val, G4ExceptionSeverity es) 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 particle " << pd->GetParticleName() 769 << " is changed from " << pdm->second.first << " to " 770 << val << "."; 771 G4Exception("G4StackManager::SetDefaultClassification", 772 "Event11052", JustWarning,ed); 773 pdm->second.first = val; 774 } 775 // Change severity if needed. 776 if(pdm->second.second>es) pdm->second.second = es; 777 } 778 } 779 780 void G4StackManager::RegisterSubEventType(G4int ty, G4int maxEnt) 781 { 782 if(subEvtStackMap.find(ty)==subEvtStackMap.end()) 783 { 784 subEvtStackMap[ty] = new G4SubEventTrackStack(ty,maxEnt); 785 subEvtTypes.push_back(ty); 786 #ifdef G4VERBOSE 787 subEvtStackMap[ty]->SetVerboseLevel(verboseLevel); 788 if( verboseLevel > 0 ) 789 { 790 G4cout << " ---> New sub-event stack for sub-event type " 791 << ty << " is created. Classification id for this stack is " 792 << subEvtTypes.size() + 99 << "." << G4endl; 793 } 794 } 795 else 796 { 797 if( verboseLevel > 1 ) 798 { 799 G4cout << " ---> Sub-event stack for sub-event type " 800 << ty << " already registered." << G4endl; 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 " << ty << " requested."; 813 G4Exception("G4StackManager::PopSubEvent", "SubEvt8001", 814 FatalException,ED); 815 return; // NOLINT: Required to silence Coverity, which does not recognize G4Exception as exit point 816 } 817 818 ses->second->ReleaseSubEvent(); 819 } 820 821 822