Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
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