ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4Scheduler.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4Scheduler.cc
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 <G4AllITFinder.hh>
36 #include <G4Scheduler.hh>
37 #include <G4SchedulerMessenger.hh>
38 
39 #include "G4SystemOfUnits.hh"
40 #include "G4ITModelProcessor.hh"
41 #include "G4ITStepProcessor.hh"
42 #include "G4IT.hh"
43 #include "G4ITReactionChange.hh"
44 #include "G4ITModelHandler.hh"
45 #include "G4VITStepModel.hh"
46 #include "G4UserTimeStepAction.hh"
47 #include "G4ITTrackingManager.hh"
49 #include "G4TrackingInformation.hh"
50 #include "G4UnitsTable.hh"
51 #include "G4ITStepStatus.hh"
52 #include "G4ITGun.hh"
53 #include "G4StateManager.hh"
54 #include "G4Timer.hh"
55 #include "G4IosFlagsSaver.hh"
56 #include <sstream>
57 
58 //#include "G4Phenomenon.hh"
59 //#include "G4MIWorkspace.hh"
60 
61 //#define DEBUG_MEM 1
62 #define DEBUG_MEM_STEPPING
63 #define DEBUG_MEM_DETAILED_STEPPING
64 //#define DEBUG_MEM_DOIT
65 
66 #ifdef DEBUG_MEM
67 #include "G4MemStat.hh"
68 using namespace G4MemStat;
69 using G4MemStat::MemStat;
70 #endif
71 
72 //COLOR FOR DEBUGING
73 //#define USE_COLOR 1
74 
75 #ifdef USE_COLOR
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"
81 #else
82 #define RED ""
83 #define LIGHT_RED ""
84 #define GREEN ""
85 #define GREEN_ON_BLUE ""
86 #define RESET_COLOR ""
87 #endif
88 
89 using namespace std;
90 
92 
93 template<typename T>
94  inline bool IsInf(T value)
95  {
96  return std::numeric_limits<T>::has_infinity
97  && value == std::numeric_limits<T>::infinity();
98  }
99 //_________________________________________________________________________
100 
102 {
103  if(fgScheduler == 0) fgScheduler = new G4Scheduler();
104  return fgScheduler;
105 }
106 //_________________________________________________________________________
107 
109 {
110  if(requestedState == G4State_Quit)
111  {
112  if(fVerbose >= 4)
113  {
114  G4cout << "G4Scheduler received G4State_Quit" << G4endl;
115  }
116  Clear();
117  //DeleteInstance();
118  }
119  return true;
120 }
121 //_________________________________________________________________________
122 
124 {
125  if(fgScheduler)
126  {
127  delete fgScheduler;
128  }
129 }
130 //_________________________________________________________________________
131 
134  fTrackContainer((G4ITTrackHolder&) *G4ITTrackHolder::Instance())
135 {
136  Create();
137 }
138 
140 {
141  fUseDefaultTimeSteps = true;
142  fUserUpperTimeLimit = -1;
143  fpGun = 0;
144  fContinue = true;
145 // fpMainList = 0;
146 // fpWaitingList = 0;
148 
150 
151  fpUserTimeSteps = 0;
152 
153  fTimeStep = DBL_MAX;
157 
158  fZeroTimeCount = 0;
160 
161  fStartTime = 0;
163  fEndTime = 1 * microsecond;
164  fGlobalTime = -1;
165  fInteractionStep = true;
166  fUsePreDefinedTimeSteps = false;
167 
169 
170  fpStepProcessor = 0;
171  fpModelProcessor = 0;
172 
173  fNbSteps = 0;
174  fMaxSteps = -1;
175 
176  fRunning = false;
177  fInitialized = false;
178 
182 
183  fVerbose = 0;
184  fWhyDoYouStop = false;
185  fDefinedMinTimeStep = -1.;
186  fReachedUserTimeLimit = false;
187  fStopTime = -1.;
188  fTmpGlobalTime = -1.;
189 
190  fpMessenger = new G4SchedulerMessenger(this);
191 
194 
196 }
197 
198 //_________________________________________________________________________
199 
201 {
202 
203  if(fpMessenger) // is used as a flag to know whether the manager was cleared
204  {
205  Clear();
206  }
207 
208  fgScheduler = 0;
209 
210 // if (fVerbose >= 1)
211 // {
212 // G4cout << "G4Scheduler is being deleted. Bye :) !" << G4endl;
213 // }
214 }
215 
217 {
218 // if (fVerbose) G4cout << "*** G4Scheduler is being cleared ***" << G4endl;
219 
220  if(fpMessenger)
221  {
222  delete fpMessenger;
223  fpMessenger = 0;
224  }
225  if(fpStepProcessor)
226  {
227  delete fpStepProcessor;
228  fpStepProcessor = 0;
229  }
230  if(fpModelProcessor)
231  {
232  delete fpModelProcessor;
233  fpModelProcessor = 0;
234  }
235 
237  ClearList();
239  {
240  delete fpTrackingManager;
241  fpTrackingManager = 0;
242  }
243 
244  if(fReactionSet)
245  {
246  delete fReactionSet;
247  fReactionSet = 0;
248  }
249 
250  if(fpModelHandler)
251  {
252  delete fpModelHandler;
253  fpModelHandler = 0;
254  }
255 
256  //* DEBUG
257  //* assert(G4StateManager::GetStateManager()->
258  //* DeregisterDependent(this) == true);
259 
260 }
261 
262 //_________________________________________________________________________
263 
265 {
266 // if (fNbTracks == 0) return;
267 
269 
271 }
272 
273 //_________________________________________________________________________
275 {
276  fpModelHandler->RegisterModel(model, time);
277 }
278 
279 //_________________________________________________________________________
280 
282 {
283  if(fpStepProcessor)
284  {
285  delete fpStepProcessor;
286  }
287  if(fpModelProcessor)
288  {
289  delete fpModelProcessor;
290  }
291  // if(fpMasterModelProcessor)
292  // {
293  // delete fpMasterModelProcessor;
294  // }
295 
296  //______________________________________________________________
297 
301 
302  // fpMasterModelProcessor = new G4ITModelProcessor();
303  // fpMasterModelProcessor->SetModelHandler(fpModelHandler);
304  // fpModelProcessor = fpMasterModelProcessor;
305 
306  //______________________________________________________________
307 
310 
312 
313  // fpMasterStepProcessor = new G4ITStepProcessor();
314  // fpMasterStepProcessor->SetTrackingManager(fpTrackingManager);
315  // fpStepProcessor = fpMasterStepProcessor ;
316  //______________________________________________________________
317 
319  {
320  if(fpUserTimeSteps == 0) // Extra checking, is it necessary ?
321  {
322  G4ExceptionDescription exceptionDescription;
323  exceptionDescription
324  << "You are asking to use user defined steps but you did not give any.";
325  G4Exception("G4Scheduler::FindUserPreDefinedTimeStep",
326  "Scheduler004",
328  exceptionDescription);
329  return; // makes coverity happy
330  }
331  }
332 
333 // if (fComputeTimeStep)
334 // {
335 // if (fpModelProcessor == 0)
336 // {
337 // G4ExceptionDescription exceptionDescription;
338 // exceptionDescription
339 // << "There is no G4ITModelProcessor to handle IT reaction. ";
340 // exceptionDescription
341 // << "You probably did not initialize the G4Scheduler. ";
342 // exceptionDescription
343 // << "Just do G4Scheduler::Instance()->Initialize(); ";
344 // exceptionDescription << " but only after initializing the run manager.";
345 // G4Exception("G4Scheduler::CalculateMinStep", "ITScheduler005",
346 // FatalErrorInArgument, exceptionDescription);
347 // return; // makes coverity happy
348 // }
349 // }
350 
351  fInitialized = true;
352 }
353 
354 //_________________________________________________________________________
355 
357 {
358  fStartTime = 0;
359  fUserUpperTimeLimit = -1;
360  fTimeStep = DBL_MAX;
364  fGlobalTime = -1;
365  fInteractionStep = true;
367  fZeroTimeCount = 0;
368 
369  fNbSteps = 0;
370  fContinue = true;
371  // fReactingTracks.clear();
373 }
374 //_________________________________________________________________________
375 
377 {
378 
379 #ifdef G4VERBOSE
380  if(fVerbose)
381  {
382  G4cout << "*** G4Scheduler starts processing " << G4endl;
383  if(fVerbose > 2)
384  G4cout << "___________________________________________"
385  "___________________________" << G4endl;
386  }
387 #endif
388 
389  if (fInitialized == false) Initialize();
390 
391  // fpTrackingManager->Initialize();
394 
395  // TODO
396  // fpMasterModelProcessor->Initialize();
397  // fpMasterStepProcessor->Initialize();
398 
399  if (fpGun) fpGun->DefineTracks();
400 
402 
403  // ___________________
404  fRunning = true;
405  Reset();
406 
408 
409 #ifdef G4VERBOSE
410  G4bool trackFound = false;
411  G4IosFlagsSaver iosfs(G4cout);
412  G4cout.precision(5);
413 #endif
414 
415  //===========================================================================
416  // By default, before the G4Scheduler is launched, the tracks are pushed to
417  // the delayed lists
418  //===========================================================================
419 
421  {
423 #ifdef G4VERBOSE
424  trackFound = true;
425  G4Timer localtimer;
426  if(fVerbose>1)
427  {
428  localtimer.Start();
429  }
430 #endif
432 #ifdef G4VERBOSE
433  if(fVerbose>1)
434  {
435  localtimer.Stop();
436  G4cout << "G4Scheduler: process time= "<< localtimer << G4endl;
437  }
438 #endif
439  }
440 
441 // //---------------------------------
442 // // TODO: This could be removed ?
443 // if(fTrackContainer.MainListsNOTEmpty()
444 // && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
445 // && fGlobalTime < fEndTime
446 // && fContinue == true)
447 //{
448 //#ifdef G4VERBOSE
449 // trackFound = true;
450 //#endif
451 // DoProcess();
452 //}
453 // //---------------------------------
454 
455 #ifdef G4VERBOSE
456  if(fVerbose)
457  {
458  if(trackFound)
459  {
460  G4cout << "*** G4Scheduler ends at time : "
461  << G4BestUnit(fGlobalTime,"Time") << G4endl;
462  G4cout << "___________________________________" << G4endl;
463  }
464  else
465  {
466  G4cout << "*** G4Scheduler did not start because no "
467  "track was found to be processed"<< G4endl;
468  G4cout << "___________________________________" << G4endl;
469  }
470  }
471 #endif
472 
473  fRunning = false;
474 
476 
477  // ___________________
478  EndTracking();
479  ClearList();
480 
481  Reset();
482 
484 }
485 
486 //_________________________________________________________________________
487 
489 {
490  std::set<double>::const_iterator up = fWatchedTimes.upper_bound(fGlobalTime);
491  if(up == fWatchedTimes.end()) return DBL_MAX;
492  return *up;
493 }
494 
495 //_________________________________________________________________________
496 
498 {
499 // if(fTrackContainer.WaitingListsNOTEmpty())
500 // {
501 // G4ExceptionDescription exceptionDescription;
502 // exceptionDescription
503 // << "There is a waiting track list (fpWaitingList != 0).";
504 // exceptionDescription
505 // << " When G4Scheduler::SynchronizeTracks() is called, ";
506 // exceptionDescription
507 // << "no more tracks should remain in the fpWaitingList.";
508 // G4Exception("G4Scheduler::SynchronizeTracks", "ITScheduler002",
509 // FatalErrorInArgument, exceptionDescription);
510 // }
511 
512  // Backup main list and time feature
513  // Reminder : the main list here, should
514  // have the biggest global time
515  // fTrackContainer.MoveMainToWaitingList();
516  // TODO: not yet supported
517 
519  //fTmpEndTime = fEndTime;
520 
522  G4double tmpGlobalTime = fGlobalTime;
523 
524  double nextWatchedTime = -1;
525  bool carryOn = true;
526 
527  while(fTrackContainer.MergeNextTimeToMainList(tmpGlobalTime) && carryOn)
528  {
529 // assert(tmpGlobalTime == fGlobalTime);
531  while((nextWatchedTime = GetNextWatchedTime()) < fTrackContainer.GetNextTime()
532  && (carryOn = CanICarryOn()))
533  {
534  fStopTime = min(nextWatchedTime, fEndTime);
535  DoProcess();
536  }
537 
538  carryOn = CanICarryOn();
539 
540  if(nextWatchedTime > fEndTime && carryOn)
541  {
543  DoProcess();
544  }
545  }
546 }
547 
548 //_________________________________________________________________________
549 
551 {
552  return fGlobalTime < fEndTime && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
553  && fContinue == true;
554 }
555 
556 //_________________________________________________________________________
557 
559 {
560 #ifdef G4VERBOSE
561  if(fWhyDoYouStop)
562  {
563  G4cout << "G4Scheduler has reached a stage: it might be"
564  " a transition or the end"
565  << G4endl;
566 
567  G4bool normalStop = false;
568 
569  if(fGlobalTime >= fStopTime)
570  {
571  G4cout << "== G4Scheduler: I stop because I reached the stop time : "
572  << G4BestUnit(fStopTime,"Time") << " =="<< G4endl;
573  normalStop = true;
574  }
575  if(fTrackContainer.MainListsNOTEmpty() == false) // is empty
576  {
577  G4cout << "G4Scheduler: I stop because the current main list of tracks "
578  "is empty"
579  << G4endl;
580  normalStop = true;
581  }
582  if(fMaxSteps == -1 ? false : fNbSteps >= fMaxSteps)
583  {
584  G4cout << "G4Scheduler: I stop because I reached the maximum allowed "
585  "number of steps=" << fMaxSteps
586  << G4endl;
587  normalStop = true;
588  }
589  if(fContinue && normalStop == false)
590  {
591  G4cout << "G4Scheduler: It might be that I stop because "
592  "I have been told so. You may check "
593  "member fContinue and usage of the method G4Scheduler::Stop()."
594  << G4endl;
595  }
596  }
597 #endif
598 }
599 
600 //_________________________________________________________________________
601 
603 // We split it from the Process() method to avoid repeating code in SynchronizeTracks
604 {
606 
607 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
608  MemStat mem_first, mem_second, mem_diff;
609 #endif
610 
611 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
612  mem_first = MemoryUsage();
613 #endif
614 
615  while (fGlobalTime < fStopTime
617  && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
618  && fContinue == true)
619  {
620 // G4cout << "Mainlist size : " << fTrackContainer.GetMainList()->size()
621 // << G4endl;
622 
623  Stepping();
624 
625 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
626  mem_second = MemoryUsage();
627  mem_diff = mem_second-mem_first;
628  G4cout << "\t || MEM || After step " << fNbSteps << ", diff is : "
629  << mem_diff << G4endl;
630 #endif
631  }
632 
634 
635 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
636  mem_second = MemoryUsage();
637  mem_diff = mem_second-mem_first;
638  G4cout << "\t || MEM || After stepping, diff is : " << mem_diff << G4endl;
639 #endif
640 
641 #ifdef G4VERBOSE
642  if(fVerbose > 2)
643  G4cout << "*** G4Scheduler has finished processing a track list at time : "
644  << G4BestUnit(fGlobalTime, "Time") << G4endl;
645 #endif
646 }
647 //_________________________________________________________________________
648 
650 {
652 
655 
656  fInteractionStep = false;
657  fReachedUserTimeLimit = false;
658 
660 
661  // Start of step
662 #ifdef G4VERBOSE
663  if (fVerbose > 2)
664  {
665 #ifdef USE_COLOR
666  G4cout << LIGHT_RED;
667 #endif
668  G4cout << "*** Start Of Step N°" << fNbSteps + 1 << " ***" << G4endl;
669  G4cout << "Current Global time : " << G4BestUnit(fGlobalTime, "Time")
670  <<G4endl;
671 #ifdef USE_COLOR
672  G4cout << RESET_COLOR;
673 #endif
674  }
675 #endif
676 
677 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
678  MemStat mem_first, mem_second, mem_diff;
679 #endif
680 
681 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
682  mem_first = MemoryUsage();
683 #endif
684 
686 
688  {
689 #ifdef G4VERBOSE
690  if (fVerbose > 2)
691  {
692 #ifdef USE_COLOR
693  G4cout << LIGHT_RED;
694 #endif
695  G4cout << "*** At time : " << G4BestUnit(fGlobalTime, "Time")
696  << " the chosen user time step is : "
697  << G4BestUnit(fDefinedMinTimeStep, "Time") << " ***" << G4endl;
698 #ifdef USE_COLOR
699  G4cout << RESET_COLOR;
700 #endif
701  }
702 #endif
703  }
704 
705  if (fpModelProcessor->GetComputeTimeStep()) // fComputeTimeStep)
706  {
709  // => at least N (N = nb of tracks) loops
710  }
711  else if(fUseDefaultTimeSteps)
712  {
714  }
715 
716 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
717  mem_second = MemoryUsage();
718  mem_diff = mem_second-mem_first;
719  G4cout << "|| MEM || After computing TS, diff is : " << mem_diff << G4endl;
720 #endif
721 
722 #ifdef G4VERBOSE
723  if (fVerbose > 2)
724  {
725 #ifdef USE_COLOR
726  G4cout << LIGHT_RED;
727 #endif
728  G4cout << "*** Time stepper returned : " << G4BestUnit(fTSTimeStep, "Time")
729  << " ***" << G4endl;
730 #ifdef USE_COLOR
731  G4cout << RESET_COLOR;
732 #endif
733  }
734 #endif
735 
736 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
737  mem_first = MemoryUsage();
738 #endif
739 
740  // Call IL even if fTSTimeStep == 0
741  // if fILTimeStep == 0 give the priority to DoIt processes
742 
743  fILTimeStep =
745  // => at least N loops
746  // All process returns the physical step of interaction
747  // The transportation process calculates the corresponding
748  // time step
749 
750 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
751  mem_second = MemoryUsage();
752  mem_diff = mem_second-mem_first;
753  G4cout << "|| MEM || After IL, diff is : " << mem_diff << G4endl;
754 #endif
755 
756 #ifdef G4VERBOSE
757  if (fVerbose > 2)
758  {
759 #ifdef USE_COLOR
760  G4cout << LIGHT_RED;
761 #endif
762  G4cout << "*** The minimum time returned by the processes is : "
763  << G4BestUnit(fILTimeStep, "Time") << " ***" << G4endl;
764 #ifdef USE_COLOR
765  G4cout << RESET_COLOR;
766 #endif
767  }
768 #endif
769 
770 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
771  mem_first = MemoryUsage();
772 #endif
773 
774  if (fILTimeStep <= fTSTimeStep)
775  // Give the priority to the IL
776  {
777  fInteractionStep = true;
782  }
783  else
784  {
785  fInteractionStep = false;
789  }
790 
792  // This check is done at every time step
793  {
795  fITStepStatus = eInteractionWithMedium; // ie: transportation
796  fInteractionStep = true;
799  }
800 
801  if (fTimeStep == 0) // < fTimeTolerance)
802  {
803  ++fZeroTimeCount;
805  {
806  G4ExceptionDescription exceptionDescription;
807 
808  exceptionDescription << "Too many zero time steps were detected. ";
809  exceptionDescription << "The simulation is probably stuck. ";
810  exceptionDescription
811  << "The maximum number of zero time steps is currently : "
813  exceptionDescription << ".";
814 
815  G4Exception("G4Scheduler::Stepping",
816  "SchedulerNullTimeSteps",
818  exceptionDescription);
819  }
820  }
821  else
822  {
823  fZeroTimeCount = 0;
824  }
825 
827  ((fTimeStep <= fDefinedMinTimeStep) || ((fTimeStep > fDefinedMinTimeStep)
829  true : false;
830 
832  // TODO: pre/post
833 
834 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
835  mem_second = MemoryUsage();
836  mem_diff = mem_second-mem_first;
837  G4cout << "|| MEM || After LeadingTracks and UserPreTimeStepAction: "
838  << mem_diff << G4endl;
839 #endif
840 
841 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
842  mem_first = MemoryUsage();
843 #endif
844 
845 
847 
848  // if fTSTimeStep > 0 => still need to call the transportation process
849  // if fILTimeStep < fTSTimeStep => call only DoIt processes, no reactions
850  // if fILTimeStep == fTSTimeStep => give the priority to the DoIt processes
851  if (fTSTimeStep > 0 || fILTimeStep <= fTSTimeStep)
852  {
853  // G4cout << "Will call DoIT" << G4endl;
855  // fTrackContainer.MergeSecondariesWithMainList();
856  // fTrackContainer.KillTracks(); // remove ?
857  }
858  // else
859  // {
860  // G4cout << "fTSTimeStep : " << fTSTimeStep << G4endl;
861  // G4cout << "fILTimeStep : " << fILTimeStep << G4endl;
862  // }
863 
864 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
865  mem_second = MemoryUsage();
866  mem_diff = mem_second-mem_first;
867  G4cout << "|| MEM || After DoIT, diff is : " << mem_diff << G4endl;
868 #endif
869 
870 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
871  mem_first = MemoryUsage();
872 #endif
873 
875  fGlobalTime,
876  fTimeStep,
881  fVerbose);
882 
883  ++fNbSteps;
884 
886  {
888  }
889 
891 
892 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
893  mem_second = MemoryUsage();
894  mem_diff = mem_second-mem_first;
895  G4cout << "|| MEM || After computing reactions + UserPostTimeStepAction, "
896  "diff is : " << mem_diff << G4endl;
897 #endif
898 
899  // End of step
900 #ifdef G4VERBOSE
901  if (fVerbose >= 2)
902  {
903 #ifdef USE_COLOR
904  G4cout << LIGHT_RED;
905 #endif
906 
907  G4String interactionType;
908  GetCollisionType(interactionType);
909 
910  std::stringstream finalOutput;
911 
912  finalOutput << "*** End of step N°" << fNbSteps
913  << "\t T_i= " << G4BestUnit(fGlobalTime-fTimeStep, "Time")
914  << "\t dt= " << G4BestUnit(fTimeStep, "Time")
915  << "\t T_f= " << G4BestUnit(fGlobalTime, "Time")
916  << "\t " << interactionType
917  << G4endl;
918 
919  if(fVerbose>2)
920  {
922  {
923  finalOutput << "It has also reached the user time limit" << G4endl;
924  }
925  finalOutput << "_______________________________________________________________"
926  "_______"<< G4endl;
927  }
928 
929  G4cout << finalOutput.str();
930 
931 #ifdef USE_COLOR
932  G4cout << RESET_COLOR;
933 #endif
934  }
935 #endif
936 
937 }
938 //_________________________________________________________________________
939 
941 {
942  if (fpUserTimeSteps == 0) return fDefaultMinTimeStep;
944  return fDefinedMinTimeStep;
945 
946  map<double, double>::const_iterator it_fpUserTimeSteps_i = fpUserTimeSteps
947  ->upper_bound(fGlobalTime);
948  map<double, double>::const_iterator it_fpUserTimeSteps_low = fpUserTimeSteps
949  ->lower_bound(fGlobalTime);
950 
951  // DEBUG
952  // G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime,"Time")
953  // << G4endl;
954  // G4cout << "fpUserTimeSteps_i : "
955  // <<"<"<<G4BestUnit(it_fpUserTimeSteps->first,"Time")
956  // <<", "<< G4BestUnit(it_fpUserTimeSteps->second,"Time")<<">"
957  // << "\t fpUserTimeSteps_low : "
958  // <<"<"<<G4BestUnit(fpUserTimeSteps_low->first,"Time")<<", "*
959  // << G4BestUnit(fpUserTimeSteps_low->second,"Time")<<">"
960  // << G4endl;
961 
962  if (it_fpUserTimeSteps_i == fpUserTimeSteps->end())
963  {
964  it_fpUserTimeSteps_i--;
966  }
967  else if (fabs(fGlobalTime - it_fpUserTimeSteps_low->first) < fTimeTolerance)
968  {
969  // Case : fGlobalTime = X picosecond
970  // and fpUserTimeSteps_low->first = X picosecond
971  // but the precision is not good enough
972  it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
973  map<double, double>::const_iterator tmp_it = it_fpUserTimeSteps_low;
974  ++tmp_it;
975  if (tmp_it == fpUserTimeSteps->end())
976  {
978  }
979  else
980  {
981  fUserUpperTimeLimit = tmp_it->first;
982  }
983  }
984  else if (it_fpUserTimeSteps_i == it_fpUserTimeSteps_low)
985  {
986  // "Normal" cases
987  fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
988 // it_fpUserTimeSteps_i++;
989 // G4cout << "Global time = " << fGlobalTime << G4endl;
990 // G4cout << "Is begin = "
991 // << (it_fpUserTimeSteps_i == fpUserTimeSteps->begin())<< G4endl;
992 
993  if(it_fpUserTimeSteps_i != fpUserTimeSteps->begin()) it_fpUserTimeSteps_i--;
994  }
995  else
996  {
997  fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
998  it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
999  }
1000 
1001  return it_fpUserTimeSteps_i->second;
1002 }
1003 
1004 //_________________________________________________________________________
1005 
1007 {
1008 
1009  if(fpUserTimeSteps == 0)
1010  {
1011  G4ExceptionDescription exceptionDescription;
1012  exceptionDescription
1013  << "You are asking to use user defined steps but you did not give any.";
1014  G4Exception("G4Scheduler::FindUserPreDefinedTimeStep",
1015  "Scheduler004",
1017  exceptionDescription);
1018  return; // makes coverity happy
1019  }
1020  map<double, double>::iterator fpUserTimeSteps_i =
1021  fpUserTimeSteps->upper_bound(fGlobalTime);
1022  map<double, double>::iterator fpUserTimeSteps_low = fpUserTimeSteps
1023  ->lower_bound(fGlobalTime);
1024 
1025  // DEBUG
1026  // G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime,"Time") << G4endl;
1027  // G4cout << "fpUserTimeSteps_i : "
1028  // <<"<"<<G4BestUnit(fpUserTimeSteps_i->first,"Time")<<", "
1029  // << G4BestUnit(fpUserTimeSteps_i->second,"Time")<<">"
1030  // << "\t fpUserTimeSteps_low : "
1031  // <<"<"<<G4BestUnit(fpUserTimeSteps_low->first,"Time")<<", "
1032  // << G4BestUnit(fpUserTimeSteps_low->second,"Time")<<">"
1033  // << G4endl;
1034 
1035  if(fpUserTimeSteps_i == fpUserTimeSteps->end())
1036  {
1037  fpUserTimeSteps_i--;
1038  }
1039  else if(fabs(fGlobalTime - fpUserTimeSteps_low->first) < fTimeTolerance)
1040  {
1041  // Case : fGlobalTime = X picosecond
1042  // and fpUserTimeSteps_low->first = X picosecond
1043  // but the precision is not good enough
1044  fpUserTimeSteps_i = fpUserTimeSteps_low;
1045  }
1046  else if(fpUserTimeSteps_i == fpUserTimeSteps_low)
1047  {
1048  // "Normal" cases
1049  fpUserTimeSteps_i--;
1050  }
1051  else
1052  {
1053  fpUserTimeSteps_i = fpUserTimeSteps_low;
1054  }
1055 
1056  fDefinedMinTimeStep = fpUserTimeSteps_i->second;
1057 }
1058 
1059 //_________________________________________________________________________
1060 
1062 {
1063  if(fRunning)
1064  {
1065  G4ExceptionDescription exceptionDescription;
1066  exceptionDescription
1067  << "End tracking is called while G4Scheduler is still running."
1068  << G4endl;
1069 
1070  G4Exception("G4Scheduler::EndTracking",
1071  "Scheduler017",
1073  exceptionDescription);
1074  }
1075 
1077 
1079  {
1081  G4TrackManyList::iterator it = mainList->begin();
1082  G4TrackManyList::iterator end = mainList->end();
1083  for (; it != end; ++it)
1084  {
1086  }
1087  }
1088 
1089  if (fTrackContainer.SecondaryListsNOTEmpty()) // should be empty
1090  {
1092  G4TrackManyList::iterator it = secondaries->begin();
1093  G4TrackManyList::iterator end = secondaries->end();
1094 
1095  for (; it != end; ++it)
1096  {
1098  }
1099  }
1100 }
1101 
1102 //_________________________________________________________________________
1104 {
1105  fpTrackingInteractivity = interactivity;
1106  if(fpTrackingManager)
1107  {
1109  }
1110 
1111  //G4MIWorkspace::GetWorldWorkspace()->SetTrackingInteractivity(interactivity);
1112 }
1113 
1114 //_________________________________________________________________________
1116 {
1117  fInitialized = false;
1118  Initialize();
1119 }
1120 
1121 //_________________________________________________________________________
1124  fTrackContainer((G4ITTrackHolder&) *G4ITTrackHolder::Instance())
1125 
1126 {
1127  Create();
1128 }
1129 
1130 //_________________________________________________________________________
1132 {
1133  if(this != &right)
1134  {
1135  Create();
1136  }
1137  return *this;
1138 }
1139 
1141 {
1142  return fTrackContainer.GetNTracks();
1143 }
1144 //_________________________________________________________________________
1145 
1147 {
1148  switch(fITStepStatus)
1149  {
1151  interactionType = "eInteractionWithMedium";
1152  break;
1154  interactionType = "eCollisionBetweenTracks";
1155  break;
1156  default:
1157  interactionType = "eCollisionBetweenTracks";
1158  break;
1159  }
1160 }