62#define DEBUG_MEM_STEPPING
63#define DEBUG_MEM_DETAILED_STEPPING
76#define RED "\033[0;31m"
77#define LIGHT_RED "\33[1;31m"
78#define GREEN "\033[32;40m"
79#define GREEN_ON_BLUE "\033[1;32;44m"
80#define RESET_COLOR "\033[0m"
85#define GREEN_ON_BLUE ""
96 return std::numeric_limits<T>::has_infinity
97 && value == std::numeric_limits<T>::infinity();
103 if(fgScheduler ==
nullptr) fgScheduler =
new G4Scheduler();
114 G4cout <<
"G4Scheduler received G4State_Quit" <<
G4endl;
132G4Scheduler::G4Scheduler() :
139void G4Scheduler::Create()
141 fUseDefaultTimeSteps =
true;
142 fUserUpperTimeLimit = -1;
147 fpTrackingInteractivity =
nullptr;
151 fpUserTimeSteps =
nullptr;
159 fMaxNZeroTimeStepsAllowed = 10000;
162 fTimeTolerance = 1 * picosecond;
163 fEndTime = 1 * microsecond;
165 fInteractionStep =
true;
166 fUsePreDefinedTimeSteps =
false;
168 fDefaultMinTimeStep = 1 * picosecond;
170 fpStepProcessor =
nullptr;
171 fpModelProcessor =
nullptr;
177 fInitialized =
false;
179 fpUserTimeStepAction =
nullptr;
184 fWhyDoYouStop =
false;
185 fDefinedMinTimeStep = -1.;
186 fReachedUserTimeLimit =
false;
188 fTmpGlobalTime = -1.;
196 fResetScavenger =
true;
206 if(fpMessenger !=
nullptr)
211 fgScheduler =
nullptr;
223 if(fpMessenger !=
nullptr)
226 fpMessenger =
nullptr;
228 if(fpStepProcessor !=
nullptr)
230 delete fpStepProcessor;
231 fpStepProcessor =
nullptr;
233 if(fpModelProcessor !=
nullptr)
235 delete fpModelProcessor;
236 fpModelProcessor =
nullptr;
241 if(fpTrackingManager !=
nullptr)
243 delete fpTrackingManager;
244 fpTrackingManager =
nullptr;
247 if(fReactionSet !=
nullptr)
250 fReactionSet =
nullptr;
253 if(fpModelHandler !=
nullptr)
255 delete fpModelHandler;
256 fpModelHandler =
nullptr;
271 fTrackContainer.
Clear();
288 delete fpStepProcessor;
292 delete fpModelProcessor;
321 if(fUsePreDefinedTimeSteps)
323 if(fpUserTimeSteps ==
nullptr)
327 <<
"You are asking to use user defined steps but you did not give any.";
328 G4Exception(
"G4Scheduler::FindUserPreDefinedTimeStep",
331 exceptionDescription);
362 fUserUpperTimeLimit = -1;
368 fInteractionStep =
true;
385 G4cout <<
"*** G4Scheduler starts processing " <<
G4endl;
387 G4cout <<
"___________________________________________"
388 "___________________________" <<
G4endl;
404 if (fpTrackingInteractivity !=
nullptr) fpTrackingInteractivity->
Initialize();
412 if(fResetScavenger) {
413 if (fpUserScavenger !=
nullptr) {
414 fpUserScavenger->Reset();
418 if (fpUserTimeStepAction !=
nullptr)
424 G4bool trackFound =
false;
450 G4cout <<
"G4Scheduler: process time= "<< localtimer <<
G4endl;
474 G4cout <<
"*** G4Scheduler ends at time : "
476 G4cout <<
"___________________________________" <<
G4endl;
480 G4cout <<
"*** G4Scheduler did not start because no "
481 "track was found to be processed"<<
G4endl;
482 G4cout <<
"___________________________________" <<
G4endl;
489 if (fpUserTimeStepAction !=
nullptr) fpUserTimeStepAction->
EndProcessing();
497 if (fpTrackingInteractivity !=
nullptr) fpTrackingInteractivity->
Finalize();
504 auto up = fWatchedTimes.upper_bound(fGlobalTime);
505 if(up == fWatchedTimes.end())
return DBL_MAX;
532 fTmpGlobalTime = fGlobalTime;
536 G4double tmpGlobalTime = fGlobalTime;
543 if(tmpGlobalTime != fGlobalTime)
545 fGlobalTime = tmpGlobalTime;
547 fStopTime = min(fTrackContainer.
GetNextTime(), fEndTime);
551 fStopTime = min(nextWatchedTime, fEndTime);
557 if(nextWatchedTime > fEndTime && carryOn)
559 fStopTime = min(fTrackContainer.
GetNextTime(), fEndTime);
569 return fGlobalTime < fEndTime && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
580 G4cout <<
"G4Scheduler has reached a stage: it might be"
581 " a transition or the end"
584 G4bool normalStop =
false;
586 if(fGlobalTime >= fStopTime)
588 G4cout <<
"== G4Scheduler: I stop because I reached the stop time : "
594 G4cout <<
"G4Scheduler: I stop because the current main list of tracks "
599 if(fMaxSteps == -1 ?
false : fNbSteps >= fMaxSteps)
601 G4cout <<
"G4Scheduler: I stop because I reached the maximum allowed "
602 "number of steps=" << fMaxSteps
606 if(fContinue && !normalStop)
608 G4cout <<
"G4Scheduler: It might be that I stop because "
609 "I have been told so. You may check "
610 "member fContinue and usage of the method G4Scheduler::Stop()."
622 if(fpUserTimeStepAction !=
nullptr) fpUserTimeStepAction->
NewStage();
624#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
625 MemStat mem_first, mem_second, mem_diff;
628#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
629 mem_first = MemoryUsage();
632 while (fGlobalTime < fStopTime
634 && (fMaxSteps == -1 ?
true : fNbSteps < fMaxSteps)
642#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
643 mem_second = MemoryUsage();
644 mem_diff = mem_second-mem_first;
645 G4cout <<
"\t || MEM || After step " << fNbSteps <<
", diff is : "
652#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
653 mem_second = MemoryUsage();
654 mem_diff = mem_second-mem_first;
655 G4cout <<
"\t || MEM || After stepping, diff is : " << mem_diff <<
G4endl;
660 G4cout <<
"*** G4Scheduler has finished processing a track list at time : "
668 fTimeStep = fMaxTimeStep;
673 fInteractionStep =
false;
674 fReachedUserTimeLimit =
false;
685 G4cout <<
"*** Start Of Step N°" << fNbSteps + 1 <<
" ***" <<
G4endl;
694#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
695 MemStat mem_first, mem_second, mem_diff;
698#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
699 mem_first = MemoryUsage();
704 if (fUsePreDefinedTimeSteps)
713 <<
" the chosen user time step is : "
725 fDefinedMinTimeStep);
728 else if(fUseDefaultTimeSteps)
730 fTSTimeStep = fDefinedMinTimeStep;
733#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
734 mem_second = MemoryUsage();
735 mem_diff = mem_second-mem_first;
736 G4cout <<
"|| MEM || After computing TS, diff is : " << mem_diff <<
G4endl;
753#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
754 mem_first = MemoryUsage();
766#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
767 mem_second = MemoryUsage();
768 mem_diff = mem_second-mem_first;
769 G4cout <<
"|| MEM || After IL, diff is : " << mem_diff <<
G4endl;
778 G4cout <<
"*** The minimum time returned by the processes is : "
786#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
787 mem_first = MemoryUsage();
790 if (fILTimeStep <= fTSTimeStep)
793 fInteractionStep =
true;
795 fTimeStep = fILTimeStep;
801 fInteractionStep =
false;
803 fTimeStep = fTSTimeStep;
807 if (fGlobalTime + fTimeStep > fStopTime)
810 fTimeStep = fStopTime - fGlobalTime;
812 fInteractionStep =
true;
820 if (fZeroTimeCount >= fMaxNZeroTimeStepsAllowed)
824 exceptionDescription <<
"Too many zero time steps were detected. ";
825 exceptionDescription <<
"The simulation is probably stuck. ";
827 <<
"The maximum number of zero time steps is currently : "
828 << fMaxNZeroTimeStepsAllowed;
829 exceptionDescription <<
".";
832 "SchedulerNullTimeSteps",
834 exceptionDescription);
842 fReachedUserTimeLimit =
843 (fTimeStep <= fDefinedMinTimeStep) || ((fTimeStep > fDefinedMinTimeStep)
844 && fabs(fTimeStep - fDefinedMinTimeStep) < fTimeTolerance);
849#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
850 mem_second = MemoryUsage();
851 mem_diff = mem_second-mem_first;
852 G4cout <<
"|| MEM || After LeadingTracks and UserPreTimeStepAction: "
856#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
857 mem_first = MemoryUsage();
861 fGlobalTime += fTimeStep;
866 if (fTSTimeStep > 0 || fILTimeStep <= fTSTimeStep)
869 fpStepProcessor->
DoIt(fTimeStep);
879#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
880 mem_second = MemoryUsage();
881 mem_diff = mem_second-mem_first;
882 G4cout <<
"|| MEM || After DoIT, diff is : " << mem_diff <<
G4endl;
885#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
886 mem_first = MemoryUsage();
893 fReachedUserTimeLimit,
895 fpUserTimeStepAction,
900 if (fpUserTimeStepAction !=
nullptr)
905 fPreviousTimeStep = fTimeStep;
907#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
908 mem_second = MemoryUsage();
909 mem_diff = mem_second-mem_first;
910 G4cout <<
"|| MEM || After computing reactions + UserPostTimeStepAction, "
911 "diff is : " << mem_diff <<
G4endl;
925 std::stringstream finalOutput;
927 finalOutput <<
"*** End of step N°" << fNbSteps
928 <<
"\t T_i= " <<
G4BestUnit(fGlobalTime-fTimeStep,
"Time")
930 <<
"\t T_f= " <<
G4BestUnit(fGlobalTime,
"Time")
931 <<
"\t " << interactionType
936 if(fReachedUserTimeLimit)
938 finalOutput <<
"It has also reached the user time limit" <<
G4endl;
940 finalOutput <<
"_______________________________________________________________"
944 G4cout << finalOutput.str();
957 if (fpUserTimeSteps ==
nullptr)
return fDefaultMinTimeStep;
958 if (fabs(fGlobalTime - fUserUpperTimeLimit) < fTimeTolerance)
959 return fDefinedMinTimeStep;
961 auto it_fpUserTimeSteps_i = fpUserTimeSteps
962 ->upper_bound(fGlobalTime);
963 auto it_fpUserTimeSteps_low = fpUserTimeSteps
964 ->lower_bound(fGlobalTime);
977 if (it_fpUserTimeSteps_i == fpUserTimeSteps->end())
979 it_fpUserTimeSteps_i--;
980 fUserUpperTimeLimit = fStopTime;
982 else if (fabs(fGlobalTime - it_fpUserTimeSteps_low->first) < fTimeTolerance)
987 it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
988 auto tmp_it = it_fpUserTimeSteps_low;
990 if (tmp_it == fpUserTimeSteps->end())
992 fUserUpperTimeLimit = fStopTime;
996 fUserUpperTimeLimit = tmp_it->first;
999 else if (it_fpUserTimeSteps_i == it_fpUserTimeSteps_low)
1002 fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
1008 if(it_fpUserTimeSteps_i != fpUserTimeSteps->begin()) it_fpUserTimeSteps_i--;
1012 fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
1013 it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
1016 return it_fpUserTimeSteps_i->second;
1024 if(fpUserTimeSteps ==
nullptr)
1027 exceptionDescription
1028 <<
"You are asking to use user defined steps but you did not give any.";
1029 G4Exception(
"G4Scheduler::FindUserPreDefinedTimeStep",
1032 exceptionDescription);
1035 auto fpUserTimeSteps_i =
1036 fpUserTimeSteps->upper_bound(fGlobalTime);
1037 auto fpUserTimeSteps_low = fpUserTimeSteps
1038 ->lower_bound(fGlobalTime);
1050 if(fpUserTimeSteps_i == fpUserTimeSteps->end())
1052 fpUserTimeSteps_i--;
1054 else if(fabs(fGlobalTime - fpUserTimeSteps_low->first) < fTimeTolerance)
1059 fpUserTimeSteps_i = fpUserTimeSteps_low;
1061 else if(fpUserTimeSteps_i == fpUserTimeSteps_low)
1064 fpUserTimeSteps_i--;
1068 fpUserTimeSteps_i = fpUserTimeSteps_low;
1071 fDefinedMinTimeStep = fpUserTimeSteps_i->second;
1081 exceptionDescription
1082 <<
"End tracking is called while G4Scheduler is still running."
1088 exceptionDescription);
1098 for (; it != end; ++it)
1110 for (; it != end; ++it)
1120 fpTrackingInteractivity = interactivity;
1121 if(fpTrackingManager !=
nullptr)
1132 fInitialized =
false;
1144 switch(fITStepStatus)
1147 interactionType =
"eInteractionWithMedium";
1150 interactionType =
"eCollisionBetweenTracks";
1153 interactionType =
"eCollisionBetweenTracks";
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
@ eCollisionBetweenTracks
G4GLOB_DLL std::ostream G4cout
static void DeleteInstance()
virtual void DefineTracks()
void RegisterModel(G4VITStepModel *pModel, G4double globalTime)
void SetModelHandler(G4ITModelHandler *)
void SetTrackingManager(G4ITTrackingManager *trackingManager)
G4double CalculateMinTimeStep(G4double currentGlobalTime, G4double definedMinTimeStep)
void ComputeTrackReaction(G4ITStepStatus fITStepStatus, G4double fGlobalTime, G4double currentTimeStep, G4double previousTimeStep, G4bool reachedUserTimeLimit, G4double fTimeTolerance, G4UserTimeStepAction *fpUserTimeStepAction, G4int fVerbose)
bool GetComputeTimeStep() const
static G4ITReactionSet * Instance()
void ResetLeadingTracks()
void SetTrackingManager(G4ITTrackingManager *trackMan)
void PrepareLeadingTracks()
G4double ComputeInteractionLength(double previousTimeStep)
void DoIt(double timeStep)
virtual void Initialize()
size_t GetNTracks() override
G4TrackList * GetMainList(Key)
void MergeSecondariesWithMainList()
G4TrackManyList * GetSecondariesList()
bool SecondaryListsNOTEmpty()
bool MergeNextTimeToMainList(double &time)
bool DelayListsNOTEmpty()
virtual void Initialize()
void EndTrackingWOKill(G4Track *)
void SetInteractivity(G4ITTrackingInteractivity *)
static G4ITTypeManager * Instance()
void FindUserPreDefinedTimeStep()
void ForceReinitialization()
G4bool Notify(G4ApplicationState requestedState) override
G4double GetNextWatchedTime() const
static G4Scheduler * Instance()
void Initialize() override
virtual size_t GetNTracks()
void GetCollisionType(G4String &interactionType)
void SetInteractivity(G4ITTrackingInteractivity *) override
G4double GetLimitingTimeStep() const override
void RegisterModel(G4VITStepModel *, G4double) override
static void DeleteInstance()
virtual void UserPostTimeStepAction()
virtual void StartProcessing()
virtual void EndProcessing()
virtual void UserPreTimeStepAction()