Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4Scheduler.cc
Go to the documentation of this file.
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>
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"
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"
68using namespace G4MemStat;
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
89using namespace std;
90
91G4ThreadLocal G4Scheduler* G4Scheduler::fgScheduler(0);
92
93template<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
132G4Scheduler::G4Scheduler() :
134 fTrackContainer((G4ITTrackHolder&) *G4ITTrackHolder::Instance())
135{
136 Create();
137}
138
139void G4Scheduler::Create()
140{
141 fUseDefaultTimeSteps = true;
142 fUserUpperTimeLimit = -1;
143 fpGun = 0;
144 fContinue = true;
145// fpMainList = 0;
146// fpWaitingList = 0;
147 fpTrackingInteractivity = 0;
148
149 fITStepStatus = eUndefined;
150
151 fpUserTimeSteps = 0;
152
153 fTimeStep = DBL_MAX;
154 fTSTimeStep = DBL_MAX;
155 fILTimeStep = DBL_MAX;
156 fPreviousTimeStep = DBL_MAX;
157
158 fZeroTimeCount = 0;
159 fMaxNZeroTimeStepsAllowed = 10;
160
161 fStartTime = 0;
162 fTimeTolerance = 1 * picosecond;
163 fEndTime = 1 * microsecond;
164 fGlobalTime = -1;
165 fInteractionStep = true;
166 fUsePreDefinedTimeSteps = false;
167
168 fDefaultMinTimeStep = 1 * picosecond;
169
170 fpStepProcessor = 0;
171 fpModelProcessor = 0;
172
173 fNbSteps = 0;
174 fMaxSteps = -1;
175
176 fRunning = false;
177 fInitialized = false;
178
179 fpUserTimeStepAction = 0;
180 fpModelHandler = new G4ITModelHandler();
181 fpTrackingManager = new G4ITTrackingManager();
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
192 fReactionSet = G4ITReactionSet::Instance();
193 fMaxTimeStep = DBL_MAX;
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();
238 if(fpTrackingManager)
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
268 fTrackContainer.Clear();
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
298 fpModelProcessor = new G4ITModelProcessor();
299 fpModelProcessor->SetModelHandler(fpModelHandler);
300 fpModelProcessor->SetTrackingManager(fpTrackingManager);
301
302 // fpMasterModelProcessor = new G4ITModelProcessor();
303 // fpMasterModelProcessor->SetModelHandler(fpModelHandler);
304 // fpModelProcessor = fpMasterModelProcessor;
305
306 //______________________________________________________________
307
308 fpStepProcessor = new G4ITStepProcessor();
309 fpStepProcessor->SetTrackingManager(fpTrackingManager);
310
311 fpTrackingManager->SetInteractivity(fpTrackingInteractivity);
312
313 // fpMasterStepProcessor = new G4ITStepProcessor();
314 // fpMasterStepProcessor->SetTrackingManager(fpTrackingManager);
315 // fpStepProcessor = fpMasterStepProcessor ;
316 //______________________________________________________________
317
318 if(fUsePreDefinedTimeSteps)
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;
361 fTSTimeStep = DBL_MAX;
362 fILTimeStep = DBL_MAX;
363 fPreviousTimeStep = DBL_MAX;
364 fGlobalTime = -1;
365 fInteractionStep = true;
366 fITStepStatus = eUndefined;
367 fZeroTimeCount = 0;
368
369 fNbSteps = 0;
370 fContinue = true;
371 // fReactingTracks.clear();
372 fReactionSet->CleanAllReaction();
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();
392 fpModelProcessor->Initialize();
393 fpStepProcessor->Initialize();
394
395 // TODO
396 // fpMasterModelProcessor->Initialize();
397 // fpMasterStepProcessor->Initialize();
398
399 if (fpGun) fpGun->DefineTracks();
400
401 if (fpTrackingInteractivity) fpTrackingInteractivity->Initialize();
402
403 // ___________________
404 fRunning = true;
405 Reset();
406
407 if (fpUserTimeStepAction) fpUserTimeStepAction->StartProcessing();
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
420 if(fTrackContainer.DelayListsNOTEmpty())
421 {
422 fStartTime = fTrackContainer.GetNextTime();
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
475 if (fpUserTimeStepAction) fpUserTimeStepAction->EndProcessing();
476
477 // ___________________
478 EndTracking();
479 ClearList();
480
481 Reset();
482
483 if (fpTrackingInteractivity) fpTrackingInteractivity->Finalize();
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
518 fTmpGlobalTime = fGlobalTime;
519 //fTmpEndTime = fEndTime;
520
521 fGlobalTime = fTrackContainer.GetNextTime();
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);
530 fStopTime = min(fTrackContainer.GetNextTime(), fEndTime);
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 {
542 fStopTime = min(fTrackContainer.GetNextTime(), fEndTime);
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{
605 if(fpUserTimeStepAction) fpUserTimeStepAction->NewStage();
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
616 && fTrackContainer.MainListsNOTEmpty()
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{
651 fTimeStep = fMaxTimeStep;
652
653 fTSTimeStep = DBL_MAX;
654 fILTimeStep = DBL_MAX;
655
656 fInteractionStep = false;
657 fReachedUserTimeLimit = false;
658
659 fITStepStatus = eUndefined;
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
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
685 fDefinedMinTimeStep = GetLimitingTimeStep();
686
687 if (fUsePreDefinedTimeSteps)
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
700#endif
701 }
702#endif
703 }
704
705 if (fpModelProcessor->GetComputeTimeStep()) // fComputeTimeStep)
706 {
707 fTSTimeStep = fpModelProcessor->CalculateMinTimeStep(fGlobalTime,
708 fDefinedMinTimeStep);
709 // => at least N (N = nb of tracks) loops
710 }
711 else if(fUseDefaultTimeSteps)
712 {
713 fTSTimeStep = fDefinedMinTimeStep;
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
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 =
744 fpStepProcessor->ComputeInteractionLength(fPreviousTimeStep);
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
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;
778 fReactionSet->CleanAllReaction();
779 fTimeStep = fILTimeStep;
780 fITStepStatus = eInteractionWithMedium;
781 fpStepProcessor->PrepareLeadingTracks();
782 }
783 else
784 {
785 fInteractionStep = false;
786 fpStepProcessor->ResetLeadingTracks();
787 fTimeStep = fTSTimeStep;
788 fITStepStatus = eCollisionBetweenTracks;
789 }
790
791 if (fGlobalTime + fTimeStep > fStopTime)
792 // This check is done at every time step
793 {
794 fTimeStep = fStopTime - fGlobalTime;
795 fITStepStatus = eInteractionWithMedium; // ie: transportation
796 fInteractionStep = true;
797 fReactionSet->CleanAllReaction();
798 fpStepProcessor->ResetLeadingTracks();
799 }
800
801 if (fTimeStep == 0) // < fTimeTolerance)
802 {
803 ++fZeroTimeCount;
804 if (fZeroTimeCount >= fMaxNZeroTimeStepsAllowed)
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 : "
812 << fMaxNZeroTimeStepsAllowed;
813 exceptionDescription << ".";
814
815 G4Exception("G4Scheduler::Stepping",
816 "SchedulerNullTimeSteps",
818 exceptionDescription);
819 }
820 }
821 else
822 {
823 fZeroTimeCount = 0;
824 }
825
826 fReachedUserTimeLimit =
827 ((fTimeStep <= fDefinedMinTimeStep) || ((fTimeStep > fDefinedMinTimeStep)
828 && fabs(fTimeStep - fDefinedMinTimeStep) < fTimeTolerance)) ?
829 true : false;
830
831 if (fpUserTimeStepAction) fpUserTimeStepAction->UserPreTimeStepAction();
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
846 fGlobalTime += fTimeStep;
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;
854 fpStepProcessor->DoIt(fTimeStep);
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
874 fpModelProcessor->ComputeTrackReaction(fITStepStatus,
875 fGlobalTime,
876 fTimeStep,
877 fPreviousTimeStep,
878 fReachedUserTimeLimit,
879 fTimeTolerance,
880 fpUserTimeStepAction,
881 fVerbose);
882
883 ++fNbSteps;
884
885 if (fpUserTimeStepAction)
886 {
887 fpUserTimeStepAction->UserPostTimeStepAction();
888 }
889
890 fPreviousTimeStep = fTimeStep;
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 {
921 if(fReachedUserTimeLimit)
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
933#endif
934 }
935#endif
936
937}
938//_________________________________________________________________________
939
941{
942 if (fpUserTimeSteps == 0) return fDefaultMinTimeStep;
943 if (fabs(fGlobalTime - fUserUpperTimeLimit) < fTimeTolerance)
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--;
965 fUserUpperTimeLimit = fStopTime;
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 {
977 fUserUpperTimeLimit = fStopTime;
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
1076 fTrackContainer.MergeSecondariesWithMainList();
1077
1078 if (fTrackContainer.MainListsNOTEmpty())
1079 {
1080 G4TrackManyList* mainList = fTrackContainer.GetMainList();
1081 G4TrackManyList::iterator it = mainList->begin();
1082 G4TrackManyList::iterator end = mainList->end();
1083 for (; it != end; ++it)
1084 {
1085 fpTrackingManager->EndTrackingWOKill(*it);
1086 }
1087 }
1088
1089 if (fTrackContainer.SecondaryListsNOTEmpty()) // should be empty
1090 {
1091 G4TrackManyList* secondaries = fTrackContainer.GetSecondariesList();
1092 G4TrackManyList::iterator it = secondaries->begin();
1093 G4TrackManyList::iterator end = secondaries->end();
1094
1095 for (; it != end; ++it)
1096 {
1097 fpTrackingManager->EndTrackingWOKill(*it);
1098 }
1099 }
1100}
1101
1102//_________________________________________________________________________
1104{
1105 fpTrackingInteractivity = interactivity;
1106 if(fpTrackingManager)
1107 {
1108 fpTrackingManager->SetInteractivity(fpTrackingInteractivity);
1109 }
1110
1111 //G4MIWorkspace::GetWorldWorkspace()->SetTrackingInteractivity(interactivity);
1112}
1113
1114//_________________________________________________________________________
1116{
1117 fInitialized = false;
1118 Initialize();
1119}
1120
1121//_________________________________________________________________________
1122G4Scheduler::G4Scheduler(const G4Scheduler&) :
1124 fTrackContainer((G4ITTrackHolder&) *G4ITTrackHolder::Instance())
1125
1126{
1127 Create();
1128}
1129
1130//_________________________________________________________________________
1131G4Scheduler& G4Scheduler::operator=(const G4Scheduler& right)
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}
G4ApplicationState
@ G4State_Quit
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
@ eInteractionWithMedium
@ eCollisionBetweenTracks
@ eUndefined
bool IsInf(T value)
Definition: G4Scheduler.cc:94
#define LIGHT_RED
Definition: G4Scheduler.cc:83
#define RESET_COLOR
Definition: G4Scheduler.cc:86
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
static void DeleteInstance()
virtual void DefineTracks()
Definition: G4ITGun.hh:56
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 CleanAllReaction()
void SetTrackingManager(G4ITTrackingManager *trackMan)
G4double ComputeInteractionLength(double previousTimeStep)
void DoIt(double timeStep)
virtual void Initialize()
virtual size_t GetNTracks()
G4TrackList * GetMainList(Key)
void MergeSecondariesWithMainList()
G4TrackManyList * GetSecondariesList()
bool SecondaryListsNOTEmpty()
bool MergeNextTimeToMainList(double &time)
void EndTrackingWOKill(G4Track *)
void SetInteractivity(G4ITTrackingInteractivity *)
void ReserveRessource()
Definition: G4ITType.cc:76
static G4ITTypeManager * Instance()
Definition: G4ITType.cc:57
void ReleaseRessource()
Definition: G4ITType.cc:82
void Clear()
Definition: G4Scheduler.cc:216
void SynchronizeTracks()
Definition: G4Scheduler.cc:497
virtual void RegisterModel(G4VITStepModel *, double)
Definition: G4Scheduler.cc:274
virtual G4bool Notify(G4ApplicationState requestedState)
Definition: G4Scheduler.cc:108
void EndTracking()
void FindUserPreDefinedTimeStep()
void ForceReinitialization()
void Reset()
Definition: G4Scheduler.cc:356
void SetInteractivity(G4ITTrackingInteractivity *)
double GetNextWatchedTime() const
Definition: G4Scheduler.cc:488
void Stepping()
Definition: G4Scheduler.cc:649
virtual ~G4Scheduler()
Definition: G4Scheduler.cc:200
static G4Scheduler * Instance()
Definition: G4Scheduler.cc:101
void Process()
Definition: G4Scheduler.cc:376
void ClearList()
Definition: G4Scheduler.cc:264
virtual size_t GetNTracks()
double GetLimitingTimeStep() const
Definition: G4Scheduler.cc:940
void Initialize()
Definition: G4Scheduler.cc:281
bool CanICarryOn()
Definition: G4Scheduler.cc:550
void GetCollisionType(G4String &interactionType)
void DoProcess()
Definition: G4Scheduler.cc:602
void PrintWhyDoYouStop()
Definition: G4Scheduler.cc:558
static void DeleteInstance()
Definition: G4Scheduler.cc:123
void Stop()
void Start()
virtual void UserPostTimeStepAction()
virtual void StartProcessing()
virtual void UserPreTimeStepAction()
#define DBL_MAX
Definition: templates.hh:62
#define G4ThreadLocal
Definition: tls.hh:77