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 // 27 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr) 28 // 29 // History: 30 // ----------- 31 // 10 Oct 2011 M.Karamitros created 32 // 33 // ------------------------------------------------------------------- 34 35 #include "G4ITGun.hh" 36 #include "G4ITModelHandler.hh" 37 #include "G4ITModelProcessor.hh" 38 #include "G4ITStepProcessor.hh" 39 #include "G4ITStepStatus.hh" 40 #include "G4ITTrackingInteractivity.hh" 41 #include "G4ITTrackingManager.hh" 42 #include "G4IosFlagsSaver.hh" 43 #include "G4StateManager.hh" 44 #include "G4SystemOfUnits.hh" 45 #include "G4Timer.hh" 46 #include "G4TrackingInformation.hh" 47 #include "G4UnitsTable.hh" 48 #include "G4UserTimeStepAction.hh" 49 #include "G4VITStepModel.hh" 50 51 #include <G4AllITFinder.hh> 52 #include <G4Scheduler.hh> 53 #include <G4SchedulerMessenger.hh> 54 55 #include <sstream> 56 57 #define DEBUG_MEM_STEPPING 58 #define DEBUG_MEM_DETAILED_STEPPING 59 60 #ifdef DEBUG_MEM 61 # include "G4MemStat.hh" 62 using namespace G4MemStat; 63 using G4MemStat::MemStat; 64 #endif 65 66 #ifdef USE_COLOR 67 # define RED "\033[0;31m" 68 # define LIGHT_RED "\33[1;31m" 69 # define GREEN "\033[32;40m" 70 # define GREEN_ON_BLUE "\033[1;32;44m" 71 # define RESET_COLOR "\033[0m" 72 #else 73 # define RED "" 74 # define LIGHT_RED "" 75 # define GREEN "" 76 # define GREEN_ON_BLUE "" 77 # define RESET_COLOR "" 78 #endif 79 80 using namespace std; 81 82 G4ThreadLocal G4Scheduler* G4Scheduler::fgScheduler(nullptr); 83 84 template<typename T> 85 inline G4bool IsInf(T value) 86 { 87 return std::numeric_limits<T>::has_infinity && value == std::numeric_limits<T>::infinity(); 88 } 89 //_________________________________________________________________________ 90 91 G4Scheduler* G4Scheduler::Instance() 92 { 93 if (fgScheduler == nullptr) fgScheduler = new G4Scheduler(); 94 return fgScheduler; 95 } 96 //_________________________________________________________________________ 97 98 G4bool G4Scheduler::Notify(G4ApplicationState requestedState) 99 { 100 if (requestedState == G4State_Quit) { 101 if (fVerbose >= 4) { 102 G4cout << "G4Scheduler received G4State_Quit" << G4endl; 103 } 104 Clear(); 105 } 106 return true; 107 } 108 //_________________________________________________________________________ 109 110 void G4Scheduler::DeleteInstance() 111 { 112 delete fgScheduler; 113 } 114 //_________________________________________________________________________ 115 116 G4Scheduler::G4Scheduler() : fTrackContainer((G4ITTrackHolder&)*G4ITTrackHolder::Instance()) 117 { 118 Create(); 119 } 120 121 void G4Scheduler::Create() 122 { 123 fUseDefaultTimeSteps = true; 124 fUserUpperTimeLimit = -1; 125 fpGun = nullptr; 126 fContinue = true; 127 fpTrackingInteractivity = nullptr; 128 fITStepStatus = eUndefined; 129 fpUserTimeSteps = nullptr; 130 fTimeStep = DBL_MAX; 131 fTSTimeStep = DBL_MAX; 132 fILTimeStep = DBL_MAX; 133 fPreviousTimeStep = DBL_MAX; 134 fZeroTimeCount = 0; 135 fMaxNZeroTimeStepsAllowed = 10000; 136 fStartTime = 0; 137 fTimeTolerance = 1 * picosecond; 138 fEndTime = 1 * microsecond; 139 fGlobalTime = -1; 140 fInteractionStep = true; 141 fUsePreDefinedTimeSteps = false; 142 143 fDefaultMinTimeStep = 1 * picosecond; 144 fpStepProcessor = nullptr; 145 fpModelProcessor = nullptr; 146 fNbSteps = 0; 147 fMaxSteps = -1; 148 fRunning = false; 149 fInitialized = false; 150 fpUserTimeStepAction = nullptr; 151 fpModelHandler = new G4ITModelHandler(); 152 fpTrackingManager = new G4ITTrackingManager(); 153 fVerbose = 0; 154 fWhyDoYouStop = false; 155 fDefinedMinTimeStep = -1.; 156 fReachedUserTimeLimit = false; 157 fStopTime = -1.; 158 fpMessenger = new G4SchedulerMessenger(this); 159 fReactionSet = G4ITReactionSet::Instance(); 160 fMaxTimeStep = DBL_MAX; 161 // hoang add 162 fResetScavenger = true; // true by default 163 G4ITTypeManager::Instance()->ReserveRessource(); 164 } 165 166 //_________________________________________________________________________ 167 168 G4Scheduler::~G4Scheduler() 169 { 170 if (fpMessenger != nullptr) // is used as a flag to know whether the manager was cleared 171 { 172 Clear(); 173 } 174 fgScheduler = nullptr; 175 } 176 177 void G4Scheduler::Clear() 178 { 179 if (fpMessenger != nullptr) { 180 delete fpMessenger; 181 fpMessenger = nullptr; 182 } 183 if (fpStepProcessor != nullptr) { 184 delete fpStepProcessor; 185 fpStepProcessor = nullptr; 186 } 187 if (fpModelProcessor != nullptr) { 188 delete fpModelProcessor; 189 fpModelProcessor = nullptr; 190 } 191 192 G4ITTypeManager::Instance()->ReleaseRessource(); 193 ClearList(); 194 if (fpTrackingManager != nullptr) { 195 delete fpTrackingManager; 196 fpTrackingManager = nullptr; 197 } 198 199 if (fReactionSet != nullptr) { 200 delete fReactionSet; 201 fReactionSet = nullptr; 202 } 203 204 if (fpModelHandler != nullptr) { 205 delete fpModelHandler; 206 fpModelHandler = nullptr; 207 } 208 } 209 210 //_________________________________________________________________________ 211 212 void G4Scheduler::ClearList() 213 { 214 fTrackContainer.Clear(); 215 G4AllITFinder::DeleteInstance(); 216 } 217 218 //_________________________________________________________________________ 219 void G4Scheduler::RegisterModel(G4VITStepModel* model, G4double time) 220 { 221 fpModelHandler->RegisterModel(model, time); 222 } 223 224 //_________________________________________________________________________ 225 226 void G4Scheduler::Initialize() 227 { 228 delete fpStepProcessor; 229 delete fpModelProcessor; 230 231 fpModelProcessor = new G4ITModelProcessor(); 232 fpModelProcessor->SetModelHandler(fpModelHandler); 233 fpModelProcessor->SetTrackingManager(fpTrackingManager); 234 fpStepProcessor = new G4ITStepProcessor(); 235 fpStepProcessor->SetTrackingManager(fpTrackingManager); 236 fpTrackingManager->SetInteractivity(fpTrackingInteractivity); 237 if (fUsePreDefinedTimeSteps) { 238 if (fpUserTimeSteps == nullptr) // Extra checking, is it necessary ? 239 { 240 G4ExceptionDescription exceptionDescription; 241 exceptionDescription << "You are asking to use user defined steps but you did not give any."; 242 G4Exception("G4Scheduler::FindUserPreDefinedTimeStep", "Scheduler004", FatalErrorInArgument, 243 exceptionDescription); 244 return; // makes coverity happy 245 } 246 } 247 248 fInitialized = true; 249 } 250 251 //_________________________________________________________________________ 252 253 void G4Scheduler::Reset() 254 { 255 fStartTime = 0; 256 fUserUpperTimeLimit = -1; 257 fTimeStep = DBL_MAX; 258 fTSTimeStep = DBL_MAX; 259 fILTimeStep = DBL_MAX; 260 fPreviousTimeStep = DBL_MAX; 261 fGlobalTime = -1; 262 fInteractionStep = true; 263 fITStepStatus = eUndefined; 264 fZeroTimeCount = 0; 265 266 fNbSteps = 0; 267 fContinue = true; 268 fReactionSet->CleanAllReaction(); 269 } 270 //_________________________________________________________________________ 271 272 void G4Scheduler::Process() 273 { 274 #ifdef G4VERBOSE 275 if (fVerbose != 0) { 276 G4cout << "*** G4Scheduler starts processing " << G4endl; 277 if (fVerbose > 2) 278 G4cout << "___________________________________________" 279 "___________________________" 280 << G4endl; 281 } 282 #endif 283 284 if (!fInitialized) { 285 Initialize(); 286 } 287 fpModelProcessor->Initialize(); 288 fpStepProcessor->Initialize(); 289 290 if (fpGun != nullptr) fpGun->DefineTracks(); 291 292 if (fpTrackingInteractivity != nullptr) fpTrackingInteractivity->Initialize(); 293 294 // ___________________ 295 fRunning = true; 296 Reset(); 297 298 if (fResetScavenger) { 299 if (fpUserScavenger != nullptr) { 300 fpUserScavenger->Reset(); 301 } 302 } 303 304 if (fpUserTimeStepAction != nullptr) { 305 fpUserTimeStepAction->StartProcessing(); 306 } 307 308 #ifdef G4VERBOSE 309 G4bool trackFound = false; 310 G4IosFlagsSaver iosfs(G4cout); 311 G4cout.precision(5); 312 #endif 313 314 //=========================================================================== 315 // By default, before the G4Scheduler is launched, the tracks are pushed to 316 // the delayed lists 317 //=========================================================================== 318 319 if (fTrackContainer.DelayListsNOTEmpty()) { 320 fStartTime = fTrackContainer.GetNextTime(); 321 #ifdef G4VERBOSE 322 trackFound = true; 323 G4Timer localtimer; 324 if (fVerbose > 1) { 325 localtimer.Start(); 326 } 327 #endif 328 SynchronizeTracks(); 329 #ifdef G4VERBOSE 330 if (fVerbose > 1) { 331 localtimer.Stop(); 332 G4cout << "G4Scheduler: process time= " << localtimer << G4endl; 333 } 334 #endif 335 } 336 #ifdef G4VERBOSE 337 if (fVerbose != 0) { 338 if (trackFound) { 339 G4cout << "*** G4Scheduler ends at time : " << G4BestUnit(fGlobalTime, "Time") << G4endl; 340 G4cout << "___________________________________" << G4endl; 341 } 342 else { 343 G4cout << "*** G4Scheduler did not start because no " 344 "track was found to be processed" 345 << G4endl; 346 G4cout << "___________________________________" << G4endl; 347 } 348 } 349 #endif 350 351 fRunning = false; 352 353 if (fpUserTimeStepAction != nullptr) { 354 fpUserTimeStepAction->EndProcessing(); 355 } 356 // ___________________ 357 EndTracking(); 358 ClearList(); 359 Reset(); 360 361 if (fpTrackingInteractivity != nullptr) { 362 fpTrackingInteractivity->Finalize(); 363 } 364 } 365 366 //_________________________________________________________________________ 367 368 G4double G4Scheduler::GetNextWatchedTime() const 369 { 370 auto up = fWatchedTimes.upper_bound(fGlobalTime); 371 if (up == fWatchedTimes.end()) { 372 return DBL_MAX; 373 } 374 return *up; 375 } 376 377 //_________________________________________________________________________ 378 379 void G4Scheduler::SynchronizeTracks() 380 { 381 fGlobalTime = fTrackContainer.GetNextTime(); 382 G4double tmpGlobalTime = fGlobalTime; 383 G4double nextWatchedTime = -1; 384 G4bool carryOn = true; 385 while (fTrackContainer.MergeNextTimeToMainList(tmpGlobalTime) && carryOn) { 386 if (tmpGlobalTime != fGlobalTime) { 387 fGlobalTime = tmpGlobalTime; 388 }; 389 fStopTime = min(fTrackContainer.GetNextTime(), fEndTime); 390 while ((nextWatchedTime = GetNextWatchedTime()) < fTrackContainer.GetNextTime() 391 && (carryOn = CanICarryOn())) 392 { 393 fStopTime = min(nextWatchedTime, fEndTime); 394 DoProcess(); 395 } 396 397 carryOn = CanICarryOn(); 398 399 if (nextWatchedTime > fEndTime && carryOn) { 400 fStopTime = min(fTrackContainer.GetNextTime(), fEndTime); 401 DoProcess(); 402 } 403 } 404 } 405 406 //_________________________________________________________________________ 407 408 G4bool G4Scheduler::CanICarryOn() 409 { 410 return fGlobalTime < fEndTime && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps) && fContinue; 411 } 412 413 //_________________________________________________________________________ 414 415 void G4Scheduler::PrintWhyDoYouStop() 416 { 417 #ifdef G4VERBOSE 418 if (fWhyDoYouStop) { 419 G4cout << "G4Scheduler has reached a stage: it might be" 420 " a transition or the end" 421 << G4endl; 422 423 G4bool normalStop = false; 424 425 if (fGlobalTime >= fStopTime) { 426 G4cout << "== G4Scheduler: I stop because I reached the stop time : " 427 << G4BestUnit(fStopTime, "Time") << " ==" << G4endl; 428 normalStop = true; 429 } 430 if (!fTrackContainer.MainListsNOTEmpty()) // is empty 431 { 432 G4cout << "G4Scheduler: I stop because the current main list of tracks " 433 "is empty" 434 << G4endl; 435 normalStop = true; 436 } 437 if (fMaxSteps == -1 ? false : fNbSteps >= fMaxSteps) { 438 G4cout << "G4Scheduler: I stop because I reached the maximum allowed " 439 "number of steps=" 440 << fMaxSteps << G4endl; 441 normalStop = true; 442 } 443 if (fContinue && !normalStop) { 444 G4cout << "G4Scheduler: It might be that I stop because " 445 "I have been told so. You may check " 446 "member fContinue and usage of the method G4Scheduler::Stop()." 447 << G4endl; 448 } 449 } 450 #endif 451 } 452 453 //_________________________________________________________________________ 454 455 void G4Scheduler::DoProcess() 456 { 457 if (fpUserTimeStepAction != nullptr) fpUserTimeStepAction->NewStage(); 458 459 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_STEPPING) 460 MemStat mem_first, mem_second, mem_diff; 461 #endif 462 463 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_STEPPING) 464 mem_first = MemoryUsage(); 465 #endif 466 467 while (fGlobalTime < fStopTime && fTrackContainer.MainListsNOTEmpty() 468 && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps) && fContinue) 469 { 470 Stepping(); 471 472 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_STEPPING) 473 mem_second = MemoryUsage(); 474 mem_diff = mem_second - mem_first; 475 G4cout << "\t || MEM || After step " << fNbSteps << ", diff is : " << mem_diff << G4endl; 476 #endif 477 } 478 479 PrintWhyDoYouStop(); 480 481 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_STEPPING) 482 mem_second = MemoryUsage(); 483 mem_diff = mem_second - mem_first; 484 G4cout << "\t || MEM || After stepping, diff is : " << mem_diff << G4endl; 485 #endif 486 487 #ifdef G4VERBOSE 488 if (fVerbose > 2) 489 G4cout << "*** G4Scheduler has finished processing a track list at time : " 490 << G4BestUnit(fGlobalTime, "Time") << G4endl; 491 #endif 492 } 493 //_________________________________________________________________________ 494 495 void G4Scheduler::Stepping() 496 { 497 fTimeStep = fMaxTimeStep; 498 499 fTSTimeStep = DBL_MAX; 500 fILTimeStep = DBL_MAX; 501 502 fInteractionStep = false; 503 fReachedUserTimeLimit = false; 504 505 fITStepStatus = eUndefined; 506 507 // Start of step 508 #ifdef G4VERBOSE 509 if (fVerbose > 2) { 510 # ifdef USE_COLOR 511 G4cout << LIGHT_RED; 512 # endif 513 G4cout << "*** Start Of Step N°" << fNbSteps + 1 << " species number : " << GetNTracks() 514 << " ***" << G4endl; 515 G4cout << "Current Global time : " << G4BestUnit(fGlobalTime, "Time") << G4endl; 516 # ifdef USE_COLOR 517 G4cout << RESET_COLOR; 518 # endif 519 } 520 #endif 521 522 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 523 MemStat mem_first, mem_second, mem_diff; 524 #endif 525 526 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 527 mem_first = MemoryUsage(); 528 #endif 529 530 fDefinedMinTimeStep = GetLimitingTimeStep(); 531 532 if (fUsePreDefinedTimeSteps) { 533 #ifdef G4VERBOSE 534 if (fVerbose > 2) { 535 # ifdef USE_COLOR 536 G4cout << LIGHT_RED; 537 # endif 538 G4cout << "*** At time : " << G4BestUnit(fGlobalTime, "Time") 539 << " the chosen user time step is : " << G4BestUnit(fDefinedMinTimeStep, "Time") 540 << " ***" << G4endl; 541 # ifdef USE_COLOR 542 G4cout << RESET_COLOR; 543 # endif 544 } 545 #endif 546 } 547 548 if (fpModelProcessor->GetComputeTimeStep()) // fComputeTimeStep) 549 { 550 fTSTimeStep = fpModelProcessor->CalculateMinTimeStep(fGlobalTime, fDefinedMinTimeStep); 551 // => at least N (N = nb of tracks) loops 552 } 553 else if (fUseDefaultTimeSteps) { 554 fTSTimeStep = fDefinedMinTimeStep; 555 } 556 557 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 558 mem_second = MemoryUsage(); 559 mem_diff = mem_second - mem_first; 560 G4cout << "|| MEM || After computing TS, diff is : " << mem_diff << G4endl; 561 #endif 562 563 #ifdef G4VERBOSE 564 if (fVerbose > 2) { 565 # ifdef USE_COLOR 566 G4cout << LIGHT_RED; 567 # endif 568 G4cout << "*** Time stepper returned : " << G4BestUnit(fTSTimeStep, "Time") << " ***" << G4endl; 569 # ifdef USE_COLOR 570 G4cout << RESET_COLOR; 571 # endif 572 } 573 #endif 574 575 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 576 mem_first = MemoryUsage(); 577 #endif 578 579 // Call IL even if fTSTimeStep == 0 580 // if fILTimeStep == 0 give the priority to DoIt processes 581 582 fILTimeStep = fpStepProcessor->ComputeInteractionLength(fPreviousTimeStep); 583 // => at least N loops 584 // All process returns the physical step of interaction 585 // The transportation process calculates the corresponding 586 // time step 587 588 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 589 mem_second = MemoryUsage(); 590 mem_diff = mem_second - mem_first; 591 G4cout << "|| MEM || After IL, diff is : " << mem_diff << G4endl; 592 #endif 593 594 #ifdef G4VERBOSE 595 if (fVerbose > 2) { 596 # ifdef USE_COLOR 597 G4cout << LIGHT_RED; 598 # endif 599 G4cout << "*** The minimum time returned by the processes is : " 600 << G4BestUnit(fILTimeStep, "Time") << " ***" << G4endl; 601 # ifdef USE_COLOR 602 G4cout << RESET_COLOR; 603 # endif 604 } 605 #endif 606 607 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 608 mem_first = MemoryUsage(); 609 #endif 610 611 if (fILTimeStep <= fTSTimeStep) 612 // Give the priority to the IL 613 { 614 fInteractionStep = true; 615 fReactionSet->CleanAllReaction(); 616 fTimeStep = fILTimeStep; 617 fITStepStatus = eInteractionWithMedium; 618 fpStepProcessor->PrepareLeadingTracks(); 619 } 620 else { 621 fInteractionStep = false; 622 fpStepProcessor->ResetLeadingTracks(); 623 fTimeStep = fTSTimeStep; 624 fITStepStatus = eCollisionBetweenTracks; 625 } 626 627 if (fGlobalTime + fTimeStep > fStopTime) 628 // This check is done at every time step 629 { 630 fTimeStep = fStopTime - fGlobalTime; 631 fITStepStatus = eInteractionWithMedium; // ie: transportation 632 fInteractionStep = true; 633 fReactionSet->CleanAllReaction(); 634 fpStepProcessor->ResetLeadingTracks(); 635 } 636 637 if (fTimeStep == 0) // < fTimeTolerance) 638 { 639 ++fZeroTimeCount; 640 if (fZeroTimeCount >= fMaxNZeroTimeStepsAllowed) { 641 G4ExceptionDescription exceptionDescription; 642 643 exceptionDescription << "Too many zero time steps were detected. "; 644 exceptionDescription << "The simulation is probably stuck. "; 645 exceptionDescription << "The maximum number of zero time steps is currently : " 646 << fMaxNZeroTimeStepsAllowed; 647 exceptionDescription << "."; 648 649 G4Exception("G4Scheduler::Stepping", "SchedulerNullTimeSteps", FatalErrorInArgument, 650 exceptionDescription); 651 } 652 } 653 else { 654 fZeroTimeCount = 0; 655 } 656 657 fReachedUserTimeLimit = (fTimeStep <= fDefinedMinTimeStep) 658 || ((fTimeStep > fDefinedMinTimeStep) 659 && fabs(fTimeStep - fDefinedMinTimeStep) < fTimeTolerance); 660 661 if (fpUserTimeStepAction != nullptr) fpUserTimeStepAction->UserPreTimeStepAction(); 662 // TODO: pre/post 663 664 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 665 mem_second = MemoryUsage(); 666 mem_diff = mem_second - mem_first; 667 G4cout << "|| MEM || After LeadingTracks and UserPreTimeStepAction: " << mem_diff << G4endl; 668 #endif 669 670 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 671 mem_first = MemoryUsage(); 672 #endif 673 674 fGlobalTime += fTimeStep; 675 676 // if fTSTimeStep > 0 => still need to call the transportation process 677 // if fILTimeStep < fTSTimeStep => call only DoIt processes, no reactions 678 // if fILTimeStep == fTSTimeStep => give the priority to the DoIt processes 679 if (fTSTimeStep > 0 || fILTimeStep <= fTSTimeStep) { 680 fpStepProcessor->DoIt(fTimeStep); 681 } 682 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 683 mem_second = MemoryUsage(); 684 mem_diff = mem_second - mem_first; 685 G4cout << "|| MEM || After DoIT, diff is : " << mem_diff << G4endl; 686 #endif 687 688 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 689 mem_first = MemoryUsage(); 690 #endif 691 692 fpModelProcessor->ComputeTrackReaction(fITStepStatus, fGlobalTime, fTimeStep, fPreviousTimeStep, 693 fReachedUserTimeLimit, fTimeTolerance, 694 fpUserTimeStepAction, fVerbose); 695 696 ++fNbSteps; 697 698 if (fpUserTimeStepAction != nullptr) { 699 fpUserTimeStepAction->UserPostTimeStepAction(); 700 } 701 702 fPreviousTimeStep = fTimeStep; 703 704 #if defined(DEBUG_MEM) && defined(DEBUG_MEM_DETAILED_STEPPING) 705 mem_second = MemoryUsage(); 706 mem_diff = mem_second - mem_first; 707 G4cout << "|| MEM || After computing reactions + UserPostTimeStepAction, " 708 "diff is : " 709 << mem_diff << G4endl; 710 #endif 711 712 // End of step 713 #ifdef G4VERBOSE 714 if (fVerbose >= 2) { 715 # ifdef USE_COLOR 716 G4cout << LIGHT_RED; 717 # endif 718 719 G4String interactionType; 720 GetCollisionType(interactionType); 721 722 std::stringstream finalOutput; 723 724 finalOutput << "*** End of step N°" << fNbSteps 725 << "\t T_i= " << G4BestUnit(fGlobalTime - fTimeStep, "Time") 726 << "\t dt= " << G4BestUnit(fTimeStep, "Time") 727 << "\t T_f= " << G4BestUnit(fGlobalTime, "Time") << "\t " << interactionType 728 << G4endl; 729 730 if (fVerbose > 2) { 731 if (fReachedUserTimeLimit) { 732 finalOutput << "It has also reached the user time limit" << G4endl; 733 } 734 finalOutput << "_______________________________________________________________" 735 "_______" 736 << G4endl; 737 } 738 739 G4cout << finalOutput.str(); 740 741 # ifdef USE_COLOR 742 G4cout << RESET_COLOR; 743 # endif 744 } 745 #endif 746 } 747 //_________________________________________________________________________ 748 749 G4double G4Scheduler::GetLimitingTimeStep() const 750 { 751 if (fpUserTimeSteps == nullptr) return fDefaultMinTimeStep; 752 if (fabs(fGlobalTime - fUserUpperTimeLimit) < fTimeTolerance) return fDefinedMinTimeStep; 753 754 auto it_fpUserTimeSteps_i = fpUserTimeSteps->upper_bound(fGlobalTime); 755 auto it_fpUserTimeSteps_low = fpUserTimeSteps->lower_bound(fGlobalTime); 756 757 if (it_fpUserTimeSteps_i == fpUserTimeSteps->end()) { 758 it_fpUserTimeSteps_i--; 759 fUserUpperTimeLimit = fStopTime; 760 } 761 else if (fabs(fGlobalTime - it_fpUserTimeSteps_low->first) < fTimeTolerance) { 762 it_fpUserTimeSteps_i = it_fpUserTimeSteps_low; 763 auto tmp_it = it_fpUserTimeSteps_low; 764 ++tmp_it; 765 if (tmp_it == fpUserTimeSteps->end()) { 766 fUserUpperTimeLimit = fStopTime; 767 } 768 else { 769 fUserUpperTimeLimit = tmp_it->first; 770 } 771 } 772 else if (it_fpUserTimeSteps_i == it_fpUserTimeSteps_low) { 773 fUserUpperTimeLimit = it_fpUserTimeSteps_i->first; 774 if (it_fpUserTimeSteps_i != fpUserTimeSteps->begin()) it_fpUserTimeSteps_i--; 775 } 776 else { 777 fUserUpperTimeLimit = it_fpUserTimeSteps_i->first; 778 it_fpUserTimeSteps_i = it_fpUserTimeSteps_low; 779 } 780 return it_fpUserTimeSteps_i->second; 781 } 782 783 //_________________________________________________________________________ 784 785 void G4Scheduler::FindUserPreDefinedTimeStep() 786 { 787 if (fpUserTimeSteps == nullptr) { 788 G4ExceptionDescription exceptionDescription; 789 exceptionDescription << "You are asking to use user defined steps but you did not give any."; 790 G4Exception("G4Scheduler::FindUserPreDefinedTimeStep", "Scheduler004", FatalErrorInArgument, 791 exceptionDescription); 792 return; // makes coverity happy 793 } 794 auto fpUserTimeSteps_i = fpUserTimeSteps->upper_bound(fGlobalTime); 795 auto fpUserTimeSteps_low = fpUserTimeSteps->lower_bound(fGlobalTime); 796 797 if (fpUserTimeSteps_i == fpUserTimeSteps->end()) { 798 fpUserTimeSteps_i--; 799 } 800 else if (fabs(fGlobalTime - fpUserTimeSteps_low->first) < fTimeTolerance) { 801 // Case : fGlobalTime = X picosecond 802 // and fpUserTimeSteps_low->first = X picosecond 803 // but the precision is not good enough 804 fpUserTimeSteps_i = fpUserTimeSteps_low; 805 } 806 else if (fpUserTimeSteps_i == fpUserTimeSteps_low) { 807 // "Normal" cases 808 fpUserTimeSteps_i--; 809 } 810 else { 811 fpUserTimeSteps_i = fpUserTimeSteps_low; 812 } 813 814 fDefinedMinTimeStep = fpUserTimeSteps_i->second; 815 } 816 817 //_________________________________________________________________________ 818 819 void G4Scheduler::EndTracking() 820 { 821 if (fRunning) { 822 G4ExceptionDescription exceptionDescription; 823 exceptionDescription << "End tracking is called while G4Scheduler is still running." << G4endl; 824 825 G4Exception("G4Scheduler::EndTracking", "Scheduler017", FatalErrorInArgument, 826 exceptionDescription); 827 } 828 829 while (fTrackContainer.DelayListsNOTEmpty()) { 830 auto nextTime = fTrackContainer.GetNextTime(); 831 fTrackContainer.MergeNextTimeToMainList(nextTime); 832 } 833 834 fTrackContainer.MergeSecondariesWithMainList(); 835 836 if (fTrackContainer.MainListsNOTEmpty()) { 837 G4TrackManyList* mainList = fTrackContainer.GetMainList(); 838 G4TrackManyList::iterator it = mainList->begin(); 839 G4TrackManyList::iterator end = mainList->end(); 840 for (; it != end; ++it) { 841 fpTrackingManager->EndTrackingWOKill(*it); 842 } 843 } 844 845 if (fTrackContainer.SecondaryListsNOTEmpty()) // should be empty 846 { 847 G4TrackManyList* secondaries = fTrackContainer.GetSecondariesList(); 848 G4TrackManyList::iterator it = secondaries->begin(); 849 G4TrackManyList::iterator end = secondaries->end(); 850 851 for (; it != end; ++it) { 852 fpTrackingManager->EndTrackingWOKill(*it); 853 } 854 } 855 } 856 857 //_________________________________________________________________________ 858 void G4Scheduler::SetInteractivity(G4ITTrackingInteractivity* interactivity) 859 { 860 fpTrackingInteractivity = interactivity; 861 if (fpTrackingManager != nullptr) { 862 fpTrackingManager->SetInteractivity(fpTrackingInteractivity); 863 } 864 } 865 866 //_________________________________________________________________________ 867 void G4Scheduler::ForceReinitialization() 868 { 869 fInitialized = false; 870 Initialize(); 871 } 872 873 size_t G4Scheduler::GetNTracks() 874 { 875 return fTrackContainer.GetNTracks(); 876 } 877 //_________________________________________________________________________ 878 879 void G4Scheduler::GetCollisionType(G4String& interactionType) 880 { 881 switch (fITStepStatus) { 882 case eInteractionWithMedium: 883 interactionType = "eInteractionWithMedium"; 884 break; 885 case eCollisionBetweenTracks: 886 interactionType = "eCollisionBetweenTracks"; 887 break; 888 default: 889 interactionType = "eCollisionBetweenTracks"; 890 break; 891 } 892 } 893