Geant4 11.1.1
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 G4bool 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 = 10000;
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
195 //hoang add
196 fResetScavenger = true;//true by default
197
199}
200
201//_________________________________________________________________________
202
204{
205
206 if(fpMessenger) // is used as a flag to know whether the manager was cleared
207 {
208 Clear();
209 }
210
211 fgScheduler = 0;
212
213// if (fVerbose >= 1)
214// {
215// G4cout << "G4Scheduler is being deleted. Bye :) !" << G4endl;
216// }
217}
218
220{
221// if (fVerbose) G4cout << "*** G4Scheduler is being cleared ***" << G4endl;
222
223 if(fpMessenger)
224 {
225 delete fpMessenger;
226 fpMessenger = 0;
227 }
228 if(fpStepProcessor)
229 {
230 delete fpStepProcessor;
231 fpStepProcessor = 0;
232 }
233 if(fpModelProcessor)
234 {
235 delete fpModelProcessor;
236 fpModelProcessor = 0;
237 }
238
240 ClearList();
241 if(fpTrackingManager)
242 {
243 delete fpTrackingManager;
244 fpTrackingManager = 0;
245 }
246
247 if(fReactionSet)
248 {
249 delete fReactionSet;
250 fReactionSet = 0;
251 }
252
253 if(fpModelHandler)
254 {
255 delete fpModelHandler;
256 fpModelHandler = 0;
257 }
258
259 //* DEBUG
260 //* assert(G4StateManager::GetStateManager()->
261 //* DeregisterDependent(this) == true);
262
263}
264
265//_________________________________________________________________________
266
268{
269// if (fNbTracks == 0) return;
270
271 fTrackContainer.Clear();
272
274}
275
276//_________________________________________________________________________
278{
279 fpModelHandler->RegisterModel(model, time);
280}
281
282//_________________________________________________________________________
283
285{
286 if(fpStepProcessor)
287 {
288 delete fpStepProcessor;
289 }
290 if(fpModelProcessor)
291 {
292 delete fpModelProcessor;
293 }
294 // if(fpMasterModelProcessor)
295 // {
296 // delete fpMasterModelProcessor;
297 // }
298
299 //______________________________________________________________
300
301 fpModelProcessor = new G4ITModelProcessor();
302 fpModelProcessor->SetModelHandler(fpModelHandler);
303 fpModelProcessor->SetTrackingManager(fpTrackingManager);
304
305 // fpMasterModelProcessor = new G4ITModelProcessor();
306 // fpMasterModelProcessor->SetModelHandler(fpModelHandler);
307 // fpModelProcessor = fpMasterModelProcessor;
308
309 //______________________________________________________________
310
311 fpStepProcessor = new G4ITStepProcessor();
312 fpStepProcessor->SetTrackingManager(fpTrackingManager);
313
314 fpTrackingManager->SetInteractivity(fpTrackingInteractivity);
315
316 // fpMasterStepProcessor = new G4ITStepProcessor();
317 // fpMasterStepProcessor->SetTrackingManager(fpTrackingManager);
318 // fpStepProcessor = fpMasterStepProcessor ;
319 //______________________________________________________________
320
321 if(fUsePreDefinedTimeSteps)
322 {
323 if(fpUserTimeSteps == 0) // Extra checking, is it necessary ?
324 {
325 G4ExceptionDescription exceptionDescription;
326 exceptionDescription
327 << "You are asking to use user defined steps but you did not give any.";
328 G4Exception("G4Scheduler::FindUserPreDefinedTimeStep",
329 "Scheduler004",
331 exceptionDescription);
332 return; // makes coverity happy
333 }
334 }
335
336// if (fComputeTimeStep)
337// {
338// if (fpModelProcessor == 0)
339// {
340// G4ExceptionDescription exceptionDescription;
341// exceptionDescription
342// << "There is no G4ITModelProcessor to handle IT reaction. ";
343// exceptionDescription
344// << "You probably did not initialize the G4Scheduler. ";
345// exceptionDescription
346// << "Just do G4Scheduler::Instance()->Initialize(); ";
347// exceptionDescription << " but only after initializing the run manager.";
348// G4Exception("G4Scheduler::CalculateMinStep", "ITScheduler005",
349// FatalErrorInArgument, exceptionDescription);
350// return; // makes coverity happy
351// }
352// }
353
354 fInitialized = true;
355}
356
357//_________________________________________________________________________
358
360{
361 fStartTime = 0;
362 fUserUpperTimeLimit = -1;
363 fTimeStep = DBL_MAX;
364 fTSTimeStep = DBL_MAX;
365 fILTimeStep = DBL_MAX;
366 fPreviousTimeStep = DBL_MAX;
367 fGlobalTime = -1;
368 fInteractionStep = true;
369 fITStepStatus = eUndefined;
370 fZeroTimeCount = 0;
371
372 fNbSteps = 0;
373 fContinue = true;
374 // fReactingTracks.clear();
375 fReactionSet->CleanAllReaction();
376}
377//_________________________________________________________________________
378
380{
381
382#ifdef G4VERBOSE
383 if(fVerbose)
384 {
385 G4cout << "*** G4Scheduler starts processing " << G4endl;
386 if(fVerbose > 2)
387 G4cout << "___________________________________________"
388 "___________________________" << G4endl;
389 }
390#endif
391
392 if (fInitialized == false) Initialize();
393
394 // fpTrackingManager->Initialize();
395 fpModelProcessor->Initialize();
396 fpStepProcessor->Initialize();
397
398 // TODO
399 // fpMasterModelProcessor->Initialize();
400 // fpMasterStepProcessor->Initialize();
401
402 if (fpGun) fpGun->DefineTracks();
403
404 if (fpTrackingInteractivity) fpTrackingInteractivity->Initialize();
405
406 // ___________________
407 fRunning = true;
408 Reset();
409
410 //hoang 7/12/2020
411
412 if(fResetScavenger) {
413 if (fpUserScavenger != nullptr) {
414 fpUserScavenger->Reset();
415 }
416 }
417
418 if (fpUserTimeStepAction)
419 {
420 fpUserTimeStepAction->StartProcessing();
421 }
422
423#ifdef G4VERBOSE
424 G4bool trackFound = false;
425 G4IosFlagsSaver iosfs(G4cout);
426 G4cout.precision(5);
427#endif
428
429 //===========================================================================
430 // By default, before the G4Scheduler is launched, the tracks are pushed to
431 // the delayed lists
432 //===========================================================================
433
434 if(fTrackContainer.DelayListsNOTEmpty())
435 {
436 fStartTime = fTrackContainer.GetNextTime();
437#ifdef G4VERBOSE
438 trackFound = true;
439 G4Timer localtimer;
440 if(fVerbose>1)
441 {
442 localtimer.Start();
443 }
444#endif
446#ifdef G4VERBOSE
447 if(fVerbose>1)
448 {
449 localtimer.Stop();
450 G4cout << "G4Scheduler: process time= "<< localtimer << G4endl;
451 }
452#endif
453 }
454
455// //---------------------------------
456// // TODO: This could be removed ?
457// if(fTrackContainer.MainListsNOTEmpty()
458// && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
459// && fGlobalTime < fEndTime
460// && fContinue == true)
461//{
462//#ifdef G4VERBOSE
463// trackFound = true;
464//#endif
465// DoProcess();
466//}
467// //---------------------------------
468
469#ifdef G4VERBOSE
470 if(fVerbose)
471 {
472 if(trackFound)
473 {
474 G4cout << "*** G4Scheduler ends at time : "
475 << G4BestUnit(fGlobalTime,"Time") << G4endl;
476 G4cout << "___________________________________" << G4endl;
477 }
478 else
479 {
480 G4cout << "*** G4Scheduler did not start because no "
481 "track was found to be processed"<< G4endl;
482 G4cout << "___________________________________" << G4endl;
483 }
484 }
485#endif
486
487 fRunning = false;
488
489 if (fpUserTimeStepAction) fpUserTimeStepAction->EndProcessing();
490
491 // ___________________
492 EndTracking();
493 ClearList();
494
495 Reset();
496
497 if (fpTrackingInteractivity) fpTrackingInteractivity->Finalize();
498}
499
500//_________________________________________________________________________
501
503{
504 std::set<G4double>::const_iterator up = fWatchedTimes.upper_bound(fGlobalTime);
505 if(up == fWatchedTimes.end()) return DBL_MAX;
506 return *up;
507}
508
509//_________________________________________________________________________
510
512{
513// if(fTrackContainer.WaitingListsNOTEmpty())
514// {
515// G4ExceptionDescription exceptionDescription;
516// exceptionDescription
517// << "There is a waiting track list (fpWaitingList != 0).";
518// exceptionDescription
519// << " When G4Scheduler::SynchronizeTracks() is called, ";
520// exceptionDescription
521// << "no more tracks should remain in the fpWaitingList.";
522// G4Exception("G4Scheduler::SynchronizeTracks", "ITScheduler002",
523// FatalErrorInArgument, exceptionDescription);
524// }
525
526 // Backup main list and time feature
527 // Reminder : the main list here, should
528 // have the biggest global time
529 // fTrackContainer.MoveMainToWaitingList();
530 // TODO: not yet supported
531
532 fTmpGlobalTime = fGlobalTime;
533 //fTmpEndTime = fEndTime;
534
535 fGlobalTime = fTrackContainer.GetNextTime();
536 G4double tmpGlobalTime = fGlobalTime;
537
538 G4double nextWatchedTime = -1;
539 G4bool carryOn = true;
540
541 while(fTrackContainer.MergeNextTimeToMainList(tmpGlobalTime) && carryOn)
542 {
543// assert(tmpGlobalTime == fGlobalTime);
544 fStopTime = min(fTrackContainer.GetNextTime(), fEndTime);
545 while((nextWatchedTime = GetNextWatchedTime()) < fTrackContainer.GetNextTime()
546 && (carryOn = CanICarryOn()))
547 {
548 fStopTime = min(nextWatchedTime, fEndTime);
549 DoProcess();
550 }
551
552 carryOn = CanICarryOn();
553
554 if(nextWatchedTime > fEndTime && carryOn)
555 {
556 fStopTime = min(fTrackContainer.GetNextTime(), fEndTime);
557 DoProcess();
558 }
559 }
560}
561
562//_________________________________________________________________________
563
565{
566 return fGlobalTime < fEndTime && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
567 && fContinue == true;
568}
569
570//_________________________________________________________________________
571
573{
574#ifdef G4VERBOSE
575 if(fWhyDoYouStop)
576 {
577 G4cout << "G4Scheduler has reached a stage: it might be"
578 " a transition or the end"
579 << G4endl;
580
581 G4bool normalStop = false;
582
583 if(fGlobalTime >= fStopTime)
584 {
585 G4cout << "== G4Scheduler: I stop because I reached the stop time : "
586 << G4BestUnit(fStopTime,"Time") << " =="<< G4endl;
587 normalStop = true;
588 }
589 if(fTrackContainer.MainListsNOTEmpty() == false) // is empty
590 {
591 G4cout << "G4Scheduler: I stop because the current main list of tracks "
592 "is empty"
593 << G4endl;
594 normalStop = true;
595 }
596 if(fMaxSteps == -1 ? false : fNbSteps >= fMaxSteps)
597 {
598 G4cout << "G4Scheduler: I stop because I reached the maximum allowed "
599 "number of steps=" << fMaxSteps
600 << G4endl;
601 normalStop = true;
602 }
603 if(fContinue && normalStop == false)
604 {
605 G4cout << "G4Scheduler: It might be that I stop because "
606 "I have been told so. You may check "
607 "member fContinue and usage of the method G4Scheduler::Stop()."
608 << G4endl;
609 }
610 }
611#endif
612}
613
614//_________________________________________________________________________
615
617// We split it from the Process() method to avoid repeating code in SynchronizeTracks
618{
619 if(fpUserTimeStepAction) fpUserTimeStepAction->NewStage();
620
621#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
622 MemStat mem_first, mem_second, mem_diff;
623#endif
624
625#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
626 mem_first = MemoryUsage();
627#endif
628
629 while (fGlobalTime < fStopTime
630 && fTrackContainer.MainListsNOTEmpty()
631 && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
632 && fContinue == true)
633 {
634// G4cout << "Mainlist size : " << fTrackContainer.GetMainList()->size()
635// << G4endl;
636
637 Stepping();
638
639#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
640 mem_second = MemoryUsage();
641 mem_diff = mem_second-mem_first;
642 G4cout << "\t || MEM || After step " << fNbSteps << ", diff is : "
643 << mem_diff << G4endl;
644#endif
645 }
646
648
649#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
650 mem_second = MemoryUsage();
651 mem_diff = mem_second-mem_first;
652 G4cout << "\t || MEM || After stepping, diff is : " << mem_diff << G4endl;
653#endif
654
655#ifdef G4VERBOSE
656 if(fVerbose > 2)
657 G4cout << "*** G4Scheduler has finished processing a track list at time : "
658 << G4BestUnit(fGlobalTime, "Time") << G4endl;
659#endif
660}
661//_________________________________________________________________________
662
664{
665 fTimeStep = fMaxTimeStep;
666
667 fTSTimeStep = DBL_MAX;
668 fILTimeStep = DBL_MAX;
669
670 fInteractionStep = false;
671 fReachedUserTimeLimit = false;
672
673 fITStepStatus = eUndefined;
674
675 // Start of step
676#ifdef G4VERBOSE
677 if (fVerbose > 2)
678 {
679#ifdef USE_COLOR
680 G4cout << LIGHT_RED;
681#endif
682 G4cout << "*** Start Of Step N°" << fNbSteps + 1 << " ***" << G4endl;
683 G4cout << "Current Global time : " << G4BestUnit(fGlobalTime, "Time")
684 <<G4endl;
685#ifdef USE_COLOR
687#endif
688 }
689#endif
690
691#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
692 MemStat mem_first, mem_second, mem_diff;
693#endif
694
695#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
696 mem_first = MemoryUsage();
697#endif
698
699 fDefinedMinTimeStep = GetLimitingTimeStep();
700
701 if (fUsePreDefinedTimeSteps)
702 {
703#ifdef G4VERBOSE
704 if (fVerbose > 2)
705 {
706#ifdef USE_COLOR
707 G4cout << LIGHT_RED;
708#endif
709 G4cout << "*** At time : " << G4BestUnit(fGlobalTime, "Time")
710 << " the chosen user time step is : "
711 << G4BestUnit(fDefinedMinTimeStep, "Time") << " ***" << G4endl;
712#ifdef USE_COLOR
714#endif
715 }
716#endif
717 }
718
719 if (fpModelProcessor->GetComputeTimeStep()) // fComputeTimeStep)
720 {
721 fTSTimeStep = fpModelProcessor->CalculateMinTimeStep(fGlobalTime,
722 fDefinedMinTimeStep);
723 // => at least N (N = nb of tracks) loops
724 }
725 else if(fUseDefaultTimeSteps)
726 {
727 fTSTimeStep = fDefinedMinTimeStep;
728 }
729
730#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
731 mem_second = MemoryUsage();
732 mem_diff = mem_second-mem_first;
733 G4cout << "|| MEM || After computing TS, diff is : " << mem_diff << G4endl;
734#endif
735
736#ifdef G4VERBOSE
737 if (fVerbose > 2)
738 {
739#ifdef USE_COLOR
740 G4cout << LIGHT_RED;
741#endif
742 G4cout << "*** Time stepper returned : " << G4BestUnit(fTSTimeStep, "Time")
743 << " ***" << G4endl;
744#ifdef USE_COLOR
746#endif
747 }
748#endif
749
750#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
751 mem_first = MemoryUsage();
752#endif
753
754 // Call IL even if fTSTimeStep == 0
755 // if fILTimeStep == 0 give the priority to DoIt processes
756
757 fILTimeStep = fpStepProcessor->ComputeInteractionLength(fPreviousTimeStep);
758 // => at least N loops
759 // All process returns the physical step of interaction
760 // The transportation process calculates the corresponding
761 // time step
762
763#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
764 mem_second = MemoryUsage();
765 mem_diff = mem_second-mem_first;
766 G4cout << "|| MEM || After IL, diff is : " << mem_diff << G4endl;
767#endif
768
769#ifdef G4VERBOSE
770 if (fVerbose > 2)
771 {
772#ifdef USE_COLOR
773 G4cout << LIGHT_RED;
774#endif
775 G4cout << "*** The minimum time returned by the processes is : "
776 << G4BestUnit(fILTimeStep, "Time") << " ***" << G4endl;
777#ifdef USE_COLOR
779#endif
780 }
781#endif
782
783#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
784 mem_first = MemoryUsage();
785#endif
786
787 if (fILTimeStep <= fTSTimeStep)
788 // Give the priority to the IL
789 {
790 fInteractionStep = true;
791 fReactionSet->CleanAllReaction();
792 fTimeStep = fILTimeStep;
793 fITStepStatus = eInteractionWithMedium;
794 fpStepProcessor->PrepareLeadingTracks();
795 }
796 else
797 {
798 fInteractionStep = false;
799 fpStepProcessor->ResetLeadingTracks();
800 fTimeStep = fTSTimeStep;
801 fITStepStatus = eCollisionBetweenTracks;
802 }
803
804 if (fGlobalTime + fTimeStep > fStopTime)
805 // This check is done at every time step
806 {
807 fTimeStep = fStopTime - fGlobalTime;
808 fITStepStatus = eInteractionWithMedium; // ie: transportation
809 fInteractionStep = true;
810 fReactionSet->CleanAllReaction();
811 fpStepProcessor->ResetLeadingTracks();
812 }
813
814 if (fTimeStep == 0) // < fTimeTolerance)
815 {
816 ++fZeroTimeCount;
817 if (fZeroTimeCount >= fMaxNZeroTimeStepsAllowed)
818 {
819 G4ExceptionDescription exceptionDescription;
820
821 exceptionDescription << "Too many zero time steps were detected. ";
822 exceptionDescription << "The simulation is probably stuck. ";
823 exceptionDescription
824 << "The maximum number of zero time steps is currently : "
825 << fMaxNZeroTimeStepsAllowed;
826 exceptionDescription << ".";
827
828 G4Exception("G4Scheduler::Stepping",
829 "SchedulerNullTimeSteps",
831 exceptionDescription);
832 }
833 }
834 else
835 {
836 fZeroTimeCount = 0;
837 }
838
839 fReachedUserTimeLimit =
840 ((fTimeStep <= fDefinedMinTimeStep) || ((fTimeStep > fDefinedMinTimeStep)
841 && fabs(fTimeStep - fDefinedMinTimeStep) < fTimeTolerance)) ?
842 true : false;
843
844 if (fpUserTimeStepAction) fpUserTimeStepAction->UserPreTimeStepAction();
845 // TODO: pre/post
846
847#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
848 mem_second = MemoryUsage();
849 mem_diff = mem_second-mem_first;
850 G4cout << "|| MEM || After LeadingTracks and UserPreTimeStepAction: "
851 << mem_diff << G4endl;
852#endif
853
854#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
855 mem_first = MemoryUsage();
856#endif
857
858
859 fGlobalTime += fTimeStep;
860
861 // if fTSTimeStep > 0 => still need to call the transportation process
862 // if fILTimeStep < fTSTimeStep => call only DoIt processes, no reactions
863 // if fILTimeStep == fTSTimeStep => give the priority to the DoIt processes
864 if (fTSTimeStep > 0 || fILTimeStep <= fTSTimeStep)
865 {
866 // G4cout << "Will call DoIT" << G4endl;
867 fpStepProcessor->DoIt(fTimeStep);
868 // fTrackContainer.MergeSecondariesWithMainList();
869 // fTrackContainer.KillTracks(); // remove ?
870 }
871 // else
872 // {
873 // G4cout << "fTSTimeStep : " << fTSTimeStep << G4endl;
874 // G4cout << "fILTimeStep : " << fILTimeStep << G4endl;
875 // }
876
877#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
878 mem_second = MemoryUsage();
879 mem_diff = mem_second-mem_first;
880 G4cout << "|| MEM || After DoIT, diff is : " << mem_diff << G4endl;
881#endif
882
883#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
884 mem_first = MemoryUsage();
885#endif
886
887 fpModelProcessor->ComputeTrackReaction(fITStepStatus,
888 fGlobalTime,
889 fTimeStep,
890 fPreviousTimeStep,
891 fReachedUserTimeLimit,
892 fTimeTolerance,
893 fpUserTimeStepAction,
894 fVerbose);
895
896 ++fNbSteps;
897
898 if (fpUserTimeStepAction)
899 {
900 fpUserTimeStepAction->UserPostTimeStepAction();
901 }
902
903 fPreviousTimeStep = fTimeStep;
904
905#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
906 mem_second = MemoryUsage();
907 mem_diff = mem_second-mem_first;
908 G4cout << "|| MEM || After computing reactions + UserPostTimeStepAction, "
909 "diff is : " << mem_diff << G4endl;
910#endif
911
912 // End of step
913#ifdef G4VERBOSE
914 if (fVerbose >= 2)
915 {
916#ifdef USE_COLOR
917 G4cout << LIGHT_RED;
918#endif
919
920 G4String interactionType;
921 GetCollisionType(interactionType);
922
923 std::stringstream finalOutput;
924
925 finalOutput << "*** End of step N°" << fNbSteps
926 << "\t T_i= " << G4BestUnit(fGlobalTime-fTimeStep, "Time")
927 << "\t dt= " << G4BestUnit(fTimeStep, "Time")
928 << "\t T_f= " << G4BestUnit(fGlobalTime, "Time")
929 << "\t " << interactionType
930 << G4endl;
931
932 if(fVerbose>2)
933 {
934 if(fReachedUserTimeLimit)
935 {
936 finalOutput << "It has also reached the user time limit" << G4endl;
937 }
938 finalOutput << "_______________________________________________________________"
939 "_______"<< G4endl;
940 }
941
942 G4cout << finalOutput.str();
943
944#ifdef USE_COLOR
946#endif
947 }
948#endif
949
950}
951//_________________________________________________________________________
952
954{
955 if (fpUserTimeSteps == 0) return fDefaultMinTimeStep;
956 if (fabs(fGlobalTime - fUserUpperTimeLimit) < fTimeTolerance)
957 return fDefinedMinTimeStep;
958
959 map<G4double, G4double>::const_iterator it_fpUserTimeSteps_i = fpUserTimeSteps
960 ->upper_bound(fGlobalTime);
961 map<G4double, G4double>::const_iterator it_fpUserTimeSteps_low = fpUserTimeSteps
962 ->lower_bound(fGlobalTime);
963
964 // DEBUG
965 // G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime,"Time")
966 // << G4endl;
967 // G4cout << "fpUserTimeSteps_i : "
968 // <<"<"<<G4BestUnit(it_fpUserTimeSteps->first,"Time")
969 // <<", "<< G4BestUnit(it_fpUserTimeSteps->second,"Time")<<">"
970 // << "\t fpUserTimeSteps_low : "
971 // <<"<"<<G4BestUnit(fpUserTimeSteps_low->first,"Time")<<", "*
972 // << G4BestUnit(fpUserTimeSteps_low->second,"Time")<<">"
973 // << G4endl;
974
975 if (it_fpUserTimeSteps_i == fpUserTimeSteps->end())
976 {
977 it_fpUserTimeSteps_i--;
978 fUserUpperTimeLimit = fStopTime;
979 }
980 else if (fabs(fGlobalTime - it_fpUserTimeSteps_low->first) < fTimeTolerance)
981 {
982 // Case : fGlobalTime = X picosecond
983 // and fpUserTimeSteps_low->first = X picosecond
984 // but the precision is not good enough
985 it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
986 map<G4double, G4double>::const_iterator tmp_it = it_fpUserTimeSteps_low;
987 ++tmp_it;
988 if (tmp_it == fpUserTimeSteps->end())
989 {
990 fUserUpperTimeLimit = fStopTime;
991 }
992 else
993 {
994 fUserUpperTimeLimit = tmp_it->first;
995 }
996 }
997 else if (it_fpUserTimeSteps_i == it_fpUserTimeSteps_low)
998 {
999 // "Normal" cases
1000 fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
1001// it_fpUserTimeSteps_i++;
1002// G4cout << "Global time = " << fGlobalTime << G4endl;
1003// G4cout << "Is begin = "
1004// << (it_fpUserTimeSteps_i == fpUserTimeSteps->begin())<< G4endl;
1005
1006 if(it_fpUserTimeSteps_i != fpUserTimeSteps->begin()) it_fpUserTimeSteps_i--;
1007 }
1008 else
1009 {
1010 fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
1011 it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
1012 }
1013
1014 return it_fpUserTimeSteps_i->second;
1015}
1016
1017//_________________________________________________________________________
1018
1020{
1021
1022 if(fpUserTimeSteps == 0)
1023 {
1024 G4ExceptionDescription exceptionDescription;
1025 exceptionDescription
1026 << "You are asking to use user defined steps but you did not give any.";
1027 G4Exception("G4Scheduler::FindUserPreDefinedTimeStep",
1028 "Scheduler004",
1030 exceptionDescription);
1031 return; // makes coverity happy
1032 }
1033 map<G4double, G4double>::iterator fpUserTimeSteps_i =
1034 fpUserTimeSteps->upper_bound(fGlobalTime);
1035 map<G4double, G4double>::iterator fpUserTimeSteps_low = fpUserTimeSteps
1036 ->lower_bound(fGlobalTime);
1037
1038 // DEBUG
1039 // G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime,"Time") << G4endl;
1040 // G4cout << "fpUserTimeSteps_i : "
1041 // <<"<"<<G4BestUnit(fpUserTimeSteps_i->first,"Time")<<", "
1042 // << G4BestUnit(fpUserTimeSteps_i->second,"Time")<<">"
1043 // << "\t fpUserTimeSteps_low : "
1044 // <<"<"<<G4BestUnit(fpUserTimeSteps_low->first,"Time")<<", "
1045 // << G4BestUnit(fpUserTimeSteps_low->second,"Time")<<">"
1046 // << G4endl;
1047
1048 if(fpUserTimeSteps_i == fpUserTimeSteps->end())
1049 {
1050 fpUserTimeSteps_i--;
1051 }
1052 else if(fabs(fGlobalTime - fpUserTimeSteps_low->first) < fTimeTolerance)
1053 {
1054 // Case : fGlobalTime = X picosecond
1055 // and fpUserTimeSteps_low->first = X picosecond
1056 // but the precision is not good enough
1057 fpUserTimeSteps_i = fpUserTimeSteps_low;
1058 }
1059 else if(fpUserTimeSteps_i == fpUserTimeSteps_low)
1060 {
1061 // "Normal" cases
1062 fpUserTimeSteps_i--;
1063 }
1064 else
1065 {
1066 fpUserTimeSteps_i = fpUserTimeSteps_low;
1067 }
1068
1069 fDefinedMinTimeStep = fpUserTimeSteps_i->second;
1070}
1071
1072//_________________________________________________________________________
1073
1075{
1076 if(fRunning)
1077 {
1078 G4ExceptionDescription exceptionDescription;
1079 exceptionDescription
1080 << "End tracking is called while G4Scheduler is still running."
1081 << G4endl;
1082
1083 G4Exception("G4Scheduler::EndTracking",
1084 "Scheduler017",
1086 exceptionDescription);
1087 }
1088
1089 fTrackContainer.MergeSecondariesWithMainList();
1090
1091 if (fTrackContainer.MainListsNOTEmpty())
1092 {
1093 G4TrackManyList* mainList = fTrackContainer.GetMainList();
1094 G4TrackManyList::iterator it = mainList->begin();
1095 G4TrackManyList::iterator end = mainList->end();
1096 for (; it != end; ++it)
1097 {
1098 fpTrackingManager->EndTrackingWOKill(*it);
1099 }
1100 }
1101
1102 if (fTrackContainer.SecondaryListsNOTEmpty()) // should be empty
1103 {
1104 G4TrackManyList* secondaries = fTrackContainer.GetSecondariesList();
1105 G4TrackManyList::iterator it = secondaries->begin();
1106 G4TrackManyList::iterator end = secondaries->end();
1107
1108 for (; it != end; ++it)
1109 {
1110 fpTrackingManager->EndTrackingWOKill(*it);
1111 }
1112 }
1113}
1114
1115//_________________________________________________________________________
1117{
1118 fpTrackingInteractivity = interactivity;
1119 if(fpTrackingManager)
1120 {
1121 fpTrackingManager->SetInteractivity(fpTrackingInteractivity);
1122 }
1123
1124 //G4MIWorkspace::GetWorldWorkspace()->SetTrackingInteractivity(interactivity);
1125}
1126
1127//_________________________________________________________________________
1129{
1130 fInitialized = false;
1131 Initialize();
1132}
1133
1134//_________________________________________________________________________
1135G4Scheduler::G4Scheduler(const G4Scheduler&) :
1137 fTrackContainer((G4ITTrackHolder&) *G4ITTrackHolder::Instance())
1138
1139{
1140 Create();
1141}
1142
1143//_________________________________________________________________________
1144G4Scheduler& G4Scheduler::operator=(const G4Scheduler& right)
1145{
1146 if(this != &right)
1147 {
1148 Create();
1149 }
1150 return *this;
1151}
1152
1154{
1155 return fTrackContainer.GetNTracks();
1156}
1157//_________________________________________________________________________
1158
1160{
1161 switch(fITStepStatus)
1162 {
1164 interactionType = "eInteractionWithMedium";
1165 break;
1167 interactionType = "eCollisionBetweenTracks";
1168 break;
1169 default:
1170 interactionType = "eCollisionBetweenTracks";
1171 break;
1172 }
1173}
G4ApplicationState
@ G4State_Quit
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
@ eInteractionWithMedium
@ eCollisionBetweenTracks
@ eUndefined
G4bool 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:219
void SynchronizeTracks()
Definition: G4Scheduler.cc:511
G4bool CanICarryOn()
Definition: G4Scheduler.cc:564
virtual G4bool Notify(G4ApplicationState requestedState)
Definition: G4Scheduler.cc:108
void EndTracking()
void FindUserPreDefinedTimeStep()
void ForceReinitialization()
virtual void RegisterModel(G4VITStepModel *, G4double)
Definition: G4Scheduler.cc:277
G4double GetNextWatchedTime() const
Definition: G4Scheduler.cc:502
void Reset()
Definition: G4Scheduler.cc:359
void SetInteractivity(G4ITTrackingInteractivity *)
G4double GetLimitingTimeStep() const
Definition: G4Scheduler.cc:953
void Stepping()
Definition: G4Scheduler.cc:663
virtual ~G4Scheduler()
Definition: G4Scheduler.cc:203
static G4Scheduler * Instance()
Definition: G4Scheduler.cc:101
void Process()
Definition: G4Scheduler.cc:379
void ClearList()
Definition: G4Scheduler.cc:267
virtual size_t GetNTracks()
void Initialize()
Definition: G4Scheduler.cc:284
void GetCollisionType(G4String &interactionType)
void DoProcess()
Definition: G4Scheduler.cc:616
void PrintWhyDoYouStop()
Definition: G4Scheduler.cc:572
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