Files
geant4/source/processes/electromagnetic/dna/management/src/G4Scheduler.cc
T

1162 lines
31 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
// $Id: G4Scheduler.cc 60494 2012-07-12 14:49:30Z gcosmo $
//
// Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
//
// History:
// -----------
// 10 Oct 2011 M.Karamitros created
//
// -------------------------------------------------------------------
#include <G4AllITFinder.hh>
#include <G4Scheduler.hh>
#include <G4SchedulerMessenger.hh>
#include "G4SystemOfUnits.hh"
#include "G4ITModelProcessor.hh"
#include "G4ITStepProcessor.hh"
#include "G4IT.hh"
#include "G4ITReactionChange.hh"
#include "G4ITModelHandler.hh"
#include "G4VITStepModel.hh"
#include "G4UserTimeStepAction.hh"
#include "G4ITTrackingManager.hh"
#include "G4ITTrackingInteractivity.hh"
#include "G4TrackingInformation.hh"
#include "G4UnitsTable.hh"
#include "G4ITStepStatus.hh"
#include "G4ITGun.hh"
#include "G4StateManager.hh"
#include "G4Timer.hh"
#include "G4IosFlagsSaver.hh"
#include <sstream>
//#include "G4Phenomenon.hh"
//#include "G4MIWorkspace.hh"
//#define DEBUG_MEM 1
#define DEBUG_MEM_STEPPING
#define DEBUG_MEM_DETAILED_STEPPING
//#define DEBUG_MEM_DOIT
#ifdef DEBUG_MEM
#include "G4MemStat.hh"
using namespace G4MemStat;
using G4MemStat::MemStat;
#endif
//COLOR FOR DEBUGING
//#define USE_COLOR 1
#ifdef USE_COLOR
#define RED "\033[0;31m"
#define LIGHT_RED "\33[1;31m"
#define GREEN "\033[32;40m"
#define GREEN_ON_BLUE "\033[1;32;44m"
#define RESET_COLOR "\033[0m"
#else
#define RED ""
#define LIGHT_RED ""
#define GREEN ""
#define GREEN_ON_BLUE ""
#define RESET_COLOR ""
#endif
using namespace std;
G4ThreadLocal G4Scheduler* G4Scheduler::fgScheduler(0);
template<typename T>
inline bool IsInf(T value)
{
return std::numeric_limits<T>::has_infinity
&& value == std::numeric_limits<T>::infinity();
}
//_________________________________________________________________________
G4Scheduler* G4Scheduler::Instance()
{
if(fgScheduler == 0) fgScheduler = new G4Scheduler();
return fgScheduler;
}
//_________________________________________________________________________
G4bool G4Scheduler::Notify(G4ApplicationState requestedState)
{
if(requestedState == G4State_Quit)
{
if(fVerbose >= 4)
{
G4cout << "G4Scheduler received G4State_Quit" << G4endl;
}
Clear();
//DeleteInstance();
}
return true;
}
//_________________________________________________________________________
void G4Scheduler::DeleteInstance()
{
if(fgScheduler)
{
delete fgScheduler;
}
}
//_________________________________________________________________________
G4Scheduler::G4Scheduler() :
G4VScheduler(), G4VStateDependent(),
fTrackContainer((G4ITTrackHolder&) *G4ITTrackHolder::Instance())
{
Create();
}
void G4Scheduler::Create()
{
fUseDefaultTimeSteps = true;
fUserUpperTimeLimit = -1;
fpGun = 0;
fContinue = true;
// fpMainList = 0;
// fpWaitingList = 0;
fpTrackingInteractivity = 0;
fITStepStatus = eUndefined;
fpUserTimeSteps = 0;
fTimeStep = DBL_MAX;
fTSTimeStep = DBL_MAX;
fILTimeStep = DBL_MAX;
fPreviousTimeStep = DBL_MAX;
fZeroTimeCount = 0;
fMaxNZeroTimeStepsAllowed = 10;
fStartTime = 0;
fTimeTolerance = 1 * picosecond;
fEndTime = 1 * microsecond;
fGlobalTime = -1;
fInteractionStep = true;
fUsePreDefinedTimeSteps = false;
fDefaultMinTimeStep = 1 * picosecond;
fpStepProcessor = 0;
fpModelProcessor = 0;
fNbSteps = 0;
fMaxSteps = -1;
fRunning = false;
fInitialized = false;
fpUserTimeStepAction = 0;
fpModelHandler = new G4ITModelHandler();
fpTrackingManager = new G4ITTrackingManager();
fVerbose = 0;
fWhyDoYouStop = false;
fDefinedMinTimeStep = -1.;
fReachedUserTimeLimit = false;
fStopTime = -1.;
fTmpGlobalTime = -1.;
fpMessenger = new G4SchedulerMessenger(this);
fReactionSet = G4ITReactionSet::Instance();
fMaxTimeStep = DBL_MAX;
G4ITTypeManager::Instance()->ReserveRessource();
}
//_________________________________________________________________________
G4Scheduler::~G4Scheduler()
{
if(fpMessenger) // is used as a flag to know whether the manager was cleared
{
Clear();
}
fgScheduler = 0;
// if (fVerbose >= 1)
// {
// G4cout << "G4Scheduler is being deleted. Bye :) !" << G4endl;
// }
}
void G4Scheduler::Clear()
{
// if (fVerbose) G4cout << "*** G4Scheduler is being cleared ***" << G4endl;
if(fpMessenger)
{
delete fpMessenger;
fpMessenger = 0;
}
if(fpStepProcessor)
{
delete fpStepProcessor;
fpStepProcessor = 0;
}
if(fpModelProcessor)
{
delete fpModelProcessor;
fpModelProcessor = 0;
}
G4ITTypeManager::Instance()->ReleaseRessource();
ClearList();
if(fpTrackingManager)
{
delete fpTrackingManager;
fpTrackingManager = 0;
}
if(fReactionSet)
{
delete fReactionSet;
fReactionSet = 0;
}
if(fpModelHandler)
{
delete fpModelHandler;
fpModelHandler = 0;
}
//* DEBUG
//* assert(G4StateManager::GetStateManager()->
//* DeregisterDependent(this) == true);
}
//_________________________________________________________________________
void G4Scheduler::ClearList()
{
// if (fNbTracks == 0) return;
fTrackContainer.Clear();
G4AllITFinder::DeleteInstance();
}
//_________________________________________________________________________
void G4Scheduler::RegisterModel(G4VITStepModel* model, double time)
{
fpModelHandler->RegisterModel(model, time);
}
//_________________________________________________________________________
void G4Scheduler::Initialize()
{
if(fpStepProcessor)
{
delete fpStepProcessor;
}
if(fpModelProcessor)
{
delete fpModelProcessor;
}
// if(fpMasterModelProcessor)
// {
// delete fpMasterModelProcessor;
// }
//______________________________________________________________
fpModelProcessor = new G4ITModelProcessor();
fpModelProcessor->SetModelHandler(fpModelHandler);
fpModelProcessor->SetTrackingManager(fpTrackingManager);
// fpMasterModelProcessor = new G4ITModelProcessor();
// fpMasterModelProcessor->SetModelHandler(fpModelHandler);
// fpModelProcessor = fpMasterModelProcessor;
//______________________________________________________________
fpStepProcessor = new G4ITStepProcessor();
fpStepProcessor->SetTrackingManager(fpTrackingManager);
fpTrackingManager->SetInteractivity(fpTrackingInteractivity);
// fpMasterStepProcessor = new G4ITStepProcessor();
// fpMasterStepProcessor->SetTrackingManager(fpTrackingManager);
// fpStepProcessor = fpMasterStepProcessor ;
//______________________________________________________________
if(fUsePreDefinedTimeSteps)
{
if(fpUserTimeSteps == 0) // Extra checking, is it necessary ?
{
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "You are asking to use user defined steps but you did not give any.";
G4Exception("G4Scheduler::FindUserPreDefinedTimeStep",
"Scheduler004",
FatalErrorInArgument,
exceptionDescription);
return; // makes coverity happy
}
}
// if (fComputeTimeStep)
// {
// if (fpModelProcessor == 0)
// {
// G4ExceptionDescription exceptionDescription;
// exceptionDescription
// << "There is no G4ITModelProcessor to handle IT reaction. ";
// exceptionDescription
// << "You probably did not initialize the G4Scheduler. ";
// exceptionDescription
// << "Just do G4Scheduler::Instance()->Initialize(); ";
// exceptionDescription << " but only after initializing the run manager.";
// G4Exception("G4Scheduler::CalculateMinStep", "ITScheduler005",
// FatalErrorInArgument, exceptionDescription);
// return; // makes coverity happy
// }
// }
fInitialized = true;
}
//_________________________________________________________________________
void G4Scheduler::Reset()
{
fStartTime = 0;
fUserUpperTimeLimit = -1;
fTimeStep = DBL_MAX;
fTSTimeStep = DBL_MAX;
fILTimeStep = DBL_MAX;
fPreviousTimeStep = DBL_MAX;
fGlobalTime = -1;
fInteractionStep = true;
fITStepStatus = eUndefined;
fZeroTimeCount = 0;
fNbSteps = 0;
fContinue = true;
// fReactingTracks.clear();
fReactionSet->CleanAllReaction();
}
//_________________________________________________________________________
void G4Scheduler::Process()
{
#ifdef G4VERBOSE
if(fVerbose)
{
G4cout << "*** G4Scheduler starts processing " << G4endl;
if(fVerbose > 2)
G4cout << "___________________________________________"
"___________________________" << G4endl;
}
#endif
if (fInitialized == false) Initialize();
// fpTrackingManager->Initialize();
fpModelProcessor->Initialize();
fpStepProcessor->Initialize();
// TODO
// fpMasterModelProcessor->Initialize();
// fpMasterStepProcessor->Initialize();
if (fpGun) fpGun->DefineTracks();
if (fpTrackingInteractivity) fpTrackingInteractivity->Initialize();
// ___________________
fRunning = true;
Reset();
if (fpUserTimeStepAction) fpUserTimeStepAction->StartProcessing();
#ifdef G4VERBOSE
G4bool trackFound = false;
G4IosFlagsSaver iosfs(G4cout);
G4cout.precision(5);
#endif
//===========================================================================
// By default, before the G4Scheduler is launched, the tracks are pushed to
// the delayed lists
//===========================================================================
if(fTrackContainer.DelayListsNOTEmpty())
{
fStartTime = fTrackContainer.GetNextTime();
#ifdef G4VERBOSE
trackFound = true;
G4Timer localtimer;
if(fVerbose>1)
{
localtimer.Start();
}
#endif
SynchronizeTracks();
#ifdef G4VERBOSE
if(fVerbose>1)
{
localtimer.Stop();
G4cout << "G4Scheduler: process time= "<< localtimer << G4endl;
}
#endif
}
// //---------------------------------
// // TODO: This could be removed ?
// if(fTrackContainer.MainListsNOTEmpty()
// && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
// && fGlobalTime < fEndTime
// && fContinue == true)
//{
//#ifdef G4VERBOSE
// trackFound = true;
//#endif
// DoProcess();
//}
// //---------------------------------
#ifdef G4VERBOSE
if(fVerbose)
{
if(trackFound)
{
G4cout << "*** G4Scheduler ends at time : "
<< G4BestUnit(fGlobalTime,"Time") << G4endl;
G4cout << "___________________________________" << G4endl;
}
else
{
G4cout << "*** G4Scheduler did not start because no "
"track was found to be processed"<< G4endl;
G4cout << "___________________________________" << G4endl;
}
}
#endif
fRunning = false;
if (fpUserTimeStepAction) fpUserTimeStepAction->EndProcessing();
// ___________________
EndTracking();
ClearList();
Reset();
if (fpTrackingInteractivity) fpTrackingInteractivity->Finalize();
}
//_________________________________________________________________________
double G4Scheduler::GetNextWatchedTime() const
{
std::set<double>::const_iterator up = fWatchedTimes.upper_bound(fGlobalTime);
if(up == fWatchedTimes.end()) return DBL_MAX;
return *up;
}
//_________________________________________________________________________
void G4Scheduler::SynchronizeTracks()
{
// if(fTrackContainer.WaitingListsNOTEmpty())
// {
// G4ExceptionDescription exceptionDescription;
// exceptionDescription
// << "There is a waiting track list (fpWaitingList != 0).";
// exceptionDescription
// << " When G4Scheduler::SynchronizeTracks() is called, ";
// exceptionDescription
// << "no more tracks should remain in the fpWaitingList.";
// G4Exception("G4Scheduler::SynchronizeTracks", "ITScheduler002",
// FatalErrorInArgument, exceptionDescription);
// }
// Backup main list and time feature
// Reminder : the main list here, should
// have the biggest global time
// fTrackContainer.MoveMainToWaitingList();
// TODO: not yet supported
fTmpGlobalTime = fGlobalTime;
//fTmpEndTime = fEndTime;
fGlobalTime = fTrackContainer.GetNextTime();
G4double tmpGlobalTime = fGlobalTime;
double nextWatchedTime = -1;
bool carryOn = true;
while(fTrackContainer.MergeNextTimeToMainList(tmpGlobalTime) && carryOn)
{
// assert(tmpGlobalTime == fGlobalTime);
fStopTime = min(fTrackContainer.GetNextTime(), fEndTime);
while((nextWatchedTime = GetNextWatchedTime()) < fTrackContainer.GetNextTime()
&& (carryOn = CanICarryOn()))
{
fStopTime = min(nextWatchedTime, fEndTime);
DoProcess();
}
carryOn = CanICarryOn();
if(nextWatchedTime > fEndTime && carryOn)
{
fStopTime = min(fTrackContainer.GetNextTime(), fEndTime);
DoProcess();
}
}
}
//_________________________________________________________________________
bool G4Scheduler::CanICarryOn()
{
return fGlobalTime < fEndTime && (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
&& fContinue == true;
}
//_________________________________________________________________________
void G4Scheduler::PrintWhyDoYouStop()
{
#ifdef G4VERBOSE
if(fWhyDoYouStop)
{
G4cout << "G4Scheduler has reached a stage: it might be"
" a transition or the end"
<< G4endl;
G4bool normalStop = false;
if(fGlobalTime >= fStopTime)
{
G4cout << "== G4Scheduler: I stop because I reached the stop time : "
<< G4BestUnit(fStopTime,"Time") << " =="<< G4endl;
normalStop = true;
}
if(fTrackContainer.MainListsNOTEmpty() == false) // is empty
{
G4cout << "G4Scheduler: I stop because the current main list of tracks "
"is empty"
<< G4endl;
normalStop = true;
}
if(fMaxSteps == -1 ? false : fNbSteps >= fMaxSteps)
{
G4cout << "G4Scheduler: I stop because I reached the maximum allowed "
"number of steps=" << fMaxSteps
<< G4endl;
normalStop = true;
}
if(fContinue && normalStop == false)
{
G4cout << "G4Scheduler: It might be that I stop because "
"I have been told so. You may check "
"member fContinue and usage of the method G4Scheduler::Stop()."
<< G4endl;
}
}
#endif
}
//_________________________________________________________________________
void G4Scheduler::DoProcess()
// We split it from the Process() method to avoid repeating code in SynchronizeTracks
{
if(fpUserTimeStepAction) fpUserTimeStepAction->NewStage();
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
MemStat mem_first, mem_second, mem_diff;
#endif
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
mem_first = MemoryUsage();
#endif
while (fGlobalTime < fStopTime
&& fTrackContainer.MainListsNOTEmpty()
&& (fMaxSteps == -1 ? true : fNbSteps < fMaxSteps)
&& fContinue == true)
{
// G4cout << "Mainlist size : " << fTrackContainer.GetMainList()->size()
// << G4endl;
Stepping();
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "\t || MEM || After step " << fNbSteps << ", diff is : "
<< mem_diff << G4endl;
#endif
}
PrintWhyDoYouStop();
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_STEPPING)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "\t || MEM || After stepping, diff is : " << mem_diff << G4endl;
#endif
#ifdef G4VERBOSE
if(fVerbose > 2)
G4cout << "*** G4Scheduler has finished processing a track list at time : "
<< G4BestUnit(fGlobalTime, "Time") << G4endl;
#endif
}
//_________________________________________________________________________
void G4Scheduler::Stepping()
{
fTimeStep = fMaxTimeStep;
fTSTimeStep = DBL_MAX;
fILTimeStep = DBL_MAX;
fInteractionStep = false;
fReachedUserTimeLimit = false;
fITStepStatus = eUndefined;
// Start of step
#ifdef G4VERBOSE
if (fVerbose > 2)
{
#ifdef USE_COLOR
G4cout << LIGHT_RED;
#endif
G4cout << "*** Start Of Step N°" << fNbSteps + 1 << " ***" << G4endl;
G4cout << "Current Global time : " << G4BestUnit(fGlobalTime, "Time")
<<G4endl;
#ifdef USE_COLOR
G4cout << RESET_COLOR;
#endif
}
#endif
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
MemStat mem_first, mem_second, mem_diff;
#endif
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_first = MemoryUsage();
#endif
fDefinedMinTimeStep = GetLimitingTimeStep();
if (fUsePreDefinedTimeSteps)
{
#ifdef G4VERBOSE
if (fVerbose > 2)
{
#ifdef USE_COLOR
G4cout << LIGHT_RED;
#endif
G4cout << "*** At time : " << G4BestUnit(fGlobalTime, "Time")
<< " the chosen user time step is : "
<< G4BestUnit(fDefinedMinTimeStep, "Time") << " ***" << G4endl;
#ifdef USE_COLOR
G4cout << RESET_COLOR;
#endif
}
#endif
}
if (fpModelProcessor->GetComputeTimeStep()) // fComputeTimeStep)
{
fTSTimeStep = fpModelProcessor->CalculateMinTimeStep(fGlobalTime,
fDefinedMinTimeStep);
// => at least N (N = nb of tracks) loops
}
else if(fUseDefaultTimeSteps)
{
fTSTimeStep = fDefinedMinTimeStep;
}
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "|| MEM || After computing TS, diff is : " << mem_diff << G4endl;
#endif
#ifdef G4VERBOSE
if (fVerbose > 2)
{
#ifdef USE_COLOR
G4cout << LIGHT_RED;
#endif
G4cout << "*** Time stepper returned : " << G4BestUnit(fTSTimeStep, "Time")
<< " ***" << G4endl;
#ifdef USE_COLOR
G4cout << RESET_COLOR;
#endif
}
#endif
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_first = MemoryUsage();
#endif
// Call IL even if fTSTimeStep == 0
// if fILTimeStep == 0 give the priority to DoIt processes
fILTimeStep =
fpStepProcessor->ComputeInteractionLength(fPreviousTimeStep);
// => at least N loops
// All process returns the physical step of interaction
// The transportation process calculates the corresponding
// time step
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "|| MEM || After IL, diff is : " << mem_diff << G4endl;
#endif
#ifdef G4VERBOSE
if (fVerbose > 2)
{
#ifdef USE_COLOR
G4cout << LIGHT_RED;
#endif
G4cout << "*** The minimum time returned by the processes is : "
<< G4BestUnit(fILTimeStep, "Time") << " ***" << G4endl;
#ifdef USE_COLOR
G4cout << RESET_COLOR;
#endif
}
#endif
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_first = MemoryUsage();
#endif
if (fILTimeStep <= fTSTimeStep)
// Give the priority to the IL
{
fInteractionStep = true;
fReactionSet->CleanAllReaction();
fTimeStep = fILTimeStep;
fITStepStatus = eInteractionWithMedium;
fpStepProcessor->PrepareLeadingTracks();
}
else
{
fInteractionStep = false;
fpStepProcessor->ResetLeadingTracks();
fTimeStep = fTSTimeStep;
fITStepStatus = eCollisionBetweenTracks;
}
if (fGlobalTime + fTimeStep > fStopTime)
// This check is done at every time step
{
fTimeStep = fStopTime - fGlobalTime;
fITStepStatus = eInteractionWithMedium; // ie: transportation
fInteractionStep = true;
fReactionSet->CleanAllReaction();
fpStepProcessor->ResetLeadingTracks();
}
if (fTimeStep == 0) // < fTimeTolerance)
{
++fZeroTimeCount;
if (fZeroTimeCount >= fMaxNZeroTimeStepsAllowed)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription << "Too many zero time steps were detected. ";
exceptionDescription << "The simulation is probably stuck. ";
exceptionDescription
<< "The maximum number of zero time steps is currently : "
<< fMaxNZeroTimeStepsAllowed;
exceptionDescription << ".";
G4Exception("G4Scheduler::Stepping",
"SchedulerNullTimeSteps",
FatalErrorInArgument,
exceptionDescription);
}
}
else
{
fZeroTimeCount = 0;
}
fReachedUserTimeLimit =
((fTimeStep <= fDefinedMinTimeStep) || ((fTimeStep > fDefinedMinTimeStep)
&& fabs(fTimeStep - fDefinedMinTimeStep) < fTimeTolerance)) ?
true : false;
if (fpUserTimeStepAction) fpUserTimeStepAction->UserPreTimeStepAction();
// TODO: pre/post
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "|| MEM || After LeadingTracks and UserPreTimeStepAction: "
<< mem_diff << G4endl;
#endif
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_first = MemoryUsage();
#endif
fGlobalTime += fTimeStep;
// if fTSTimeStep > 0 => still need to call the transportation process
// if fILTimeStep < fTSTimeStep => call only DoIt processes, no reactions
// if fILTimeStep == fTSTimeStep => give the priority to the DoIt processes
if (fTSTimeStep > 0 || fILTimeStep <= fTSTimeStep)
{
// G4cout << "Will call DoIT" << G4endl;
fpStepProcessor->DoIt(fTimeStep);
// fTrackContainer.MergeSecondariesWithMainList();
// fTrackContainer.KillTracks(); // remove ?
}
// else
// {
// G4cout << "fTSTimeStep : " << fTSTimeStep << G4endl;
// G4cout << "fILTimeStep : " << fILTimeStep << G4endl;
// }
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "|| MEM || After DoIT, diff is : " << mem_diff << G4endl;
#endif
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_first = MemoryUsage();
#endif
fpModelProcessor->ComputeTrackReaction(fITStepStatus,
fGlobalTime,
fTimeStep,
fPreviousTimeStep,
fReachedUserTimeLimit,
fTimeTolerance,
fpUserTimeStepAction,
fVerbose);
++fNbSteps;
if (fpUserTimeStepAction)
{
fpUserTimeStepAction->UserPostTimeStepAction();
}
fPreviousTimeStep = fTimeStep;
#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
mem_second = MemoryUsage();
mem_diff = mem_second-mem_first;
G4cout << "|| MEM || After computing reactions + UserPostTimeStepAction, "
"diff is : " << mem_diff << G4endl;
#endif
// End of step
#ifdef G4VERBOSE
if (fVerbose >= 2)
{
#ifdef USE_COLOR
G4cout << LIGHT_RED;
#endif
G4String interactionType;
GetCollisionType(interactionType);
std::stringstream finalOutput;
finalOutput << "*** End of step N°" << fNbSteps
<< "\t T_i= " << G4BestUnit(fGlobalTime-fTimeStep, "Time")
<< "\t dt= " << G4BestUnit(fTimeStep, "Time")
<< "\t T_f= " << G4BestUnit(fGlobalTime, "Time")
<< "\t " << interactionType
<< G4endl;
if(fVerbose>2)
{
if(fReachedUserTimeLimit)
{
finalOutput << "It has also reached the user time limit" << G4endl;
}
finalOutput << "_______________________________________________________________"
"_______"<< G4endl;
}
G4cout << finalOutput.str();
#ifdef USE_COLOR
G4cout << RESET_COLOR;
#endif
}
#endif
}
//_________________________________________________________________________
double G4Scheduler::GetLimitingTimeStep() const
{
if (fpUserTimeSteps == 0) return fDefaultMinTimeStep;
if (fabs(fGlobalTime - fUserUpperTimeLimit) < fTimeTolerance)
return fDefinedMinTimeStep;
map<double, double>::const_iterator it_fpUserTimeSteps_i = fpUserTimeSteps
->upper_bound(fGlobalTime);
map<double, double>::const_iterator it_fpUserTimeSteps_low = fpUserTimeSteps
->lower_bound(fGlobalTime);
// DEBUG
// G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime,"Time")
// << G4endl;
// G4cout << "fpUserTimeSteps_i : "
// <<"<"<<G4BestUnit(it_fpUserTimeSteps->first,"Time")
// <<", "<< G4BestUnit(it_fpUserTimeSteps->second,"Time")<<">"
// << "\t fpUserTimeSteps_low : "
// <<"<"<<G4BestUnit(fpUserTimeSteps_low->first,"Time")<<", "*
// << G4BestUnit(fpUserTimeSteps_low->second,"Time")<<">"
// << G4endl;
if (it_fpUserTimeSteps_i == fpUserTimeSteps->end())
{
it_fpUserTimeSteps_i--;
fUserUpperTimeLimit = fStopTime;
}
else if (fabs(fGlobalTime - it_fpUserTimeSteps_low->first) < fTimeTolerance)
{
// Case : fGlobalTime = X picosecond
// and fpUserTimeSteps_low->first = X picosecond
// but the precision is not good enough
it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
map<double, double>::const_iterator tmp_it = it_fpUserTimeSteps_low;
++tmp_it;
if (tmp_it == fpUserTimeSteps->end())
{
fUserUpperTimeLimit = fStopTime;
}
else
{
fUserUpperTimeLimit = tmp_it->first;
}
}
else if (it_fpUserTimeSteps_i == it_fpUserTimeSteps_low)
{
// "Normal" cases
fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
// it_fpUserTimeSteps_i++;
// G4cout << "Global time = " << fGlobalTime << G4endl;
// G4cout << "Is begin = "
// << (it_fpUserTimeSteps_i == fpUserTimeSteps->begin())<< G4endl;
if(it_fpUserTimeSteps_i != fpUserTimeSteps->begin()) it_fpUserTimeSteps_i--;
}
else
{
fUserUpperTimeLimit = it_fpUserTimeSteps_i->first;
it_fpUserTimeSteps_i = it_fpUserTimeSteps_low;
}
return it_fpUserTimeSteps_i->second;
}
//_________________________________________________________________________
void G4Scheduler::FindUserPreDefinedTimeStep()
{
if(fpUserTimeSteps == 0)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "You are asking to use user defined steps but you did not give any.";
G4Exception("G4Scheduler::FindUserPreDefinedTimeStep",
"Scheduler004",
FatalErrorInArgument,
exceptionDescription);
return; // makes coverity happy
}
map<double, double>::iterator fpUserTimeSteps_i =
fpUserTimeSteps->upper_bound(fGlobalTime);
map<double, double>::iterator fpUserTimeSteps_low = fpUserTimeSteps
->lower_bound(fGlobalTime);
// DEBUG
// G4cout << "fGlobalTime : " << G4BestUnit(fGlobalTime,"Time") << G4endl;
// G4cout << "fpUserTimeSteps_i : "
// <<"<"<<G4BestUnit(fpUserTimeSteps_i->first,"Time")<<", "
// << G4BestUnit(fpUserTimeSteps_i->second,"Time")<<">"
// << "\t fpUserTimeSteps_low : "
// <<"<"<<G4BestUnit(fpUserTimeSteps_low->first,"Time")<<", "
// << G4BestUnit(fpUserTimeSteps_low->second,"Time")<<">"
// << G4endl;
if(fpUserTimeSteps_i == fpUserTimeSteps->end())
{
fpUserTimeSteps_i--;
}
else if(fabs(fGlobalTime - fpUserTimeSteps_low->first) < fTimeTolerance)
{
// Case : fGlobalTime = X picosecond
// and fpUserTimeSteps_low->first = X picosecond
// but the precision is not good enough
fpUserTimeSteps_i = fpUserTimeSteps_low;
}
else if(fpUserTimeSteps_i == fpUserTimeSteps_low)
{
// "Normal" cases
fpUserTimeSteps_i--;
}
else
{
fpUserTimeSteps_i = fpUserTimeSteps_low;
}
fDefinedMinTimeStep = fpUserTimeSteps_i->second;
}
//_________________________________________________________________________
void G4Scheduler::EndTracking()
{
if(fRunning)
{
G4ExceptionDescription exceptionDescription;
exceptionDescription
<< "End tracking is called while G4Scheduler is still running."
<< G4endl;
G4Exception("G4Scheduler::EndTracking",
"Scheduler017",
FatalErrorInArgument,
exceptionDescription);
}
fTrackContainer.MergeSecondariesWithMainList();
if (fTrackContainer.MainListsNOTEmpty())
{
G4TrackManyList* mainList = fTrackContainer.GetMainList();
G4TrackManyList::iterator it = mainList->begin();
G4TrackManyList::iterator end = mainList->end();
for (; it != end; ++it)
{
fpTrackingManager->EndTrackingWOKill(*it);
}
}
if (fTrackContainer.SecondaryListsNOTEmpty()) // should be empty
{
G4TrackManyList* secondaries = fTrackContainer.GetSecondariesList();
G4TrackManyList::iterator it = secondaries->begin();
G4TrackManyList::iterator end = secondaries->end();
for (; it != end; ++it)
{
fpTrackingManager->EndTrackingWOKill(*it);
}
}
}
//_________________________________________________________________________
void G4Scheduler::SetInteractivity(G4ITTrackingInteractivity* interactivity)
{
fpTrackingInteractivity = interactivity;
if(fpTrackingManager)
{
fpTrackingManager->SetInteractivity(fpTrackingInteractivity);
}
//G4MIWorkspace::GetWorldWorkspace()->SetTrackingInteractivity(interactivity);
}
//_________________________________________________________________________
void G4Scheduler::ForceReinitialization()
{
fInitialized = false;
Initialize();
}
//_________________________________________________________________________
G4Scheduler::G4Scheduler(const G4Scheduler&) :
G4VScheduler(), G4VStateDependent(),
fTrackContainer((G4ITTrackHolder&) *G4ITTrackHolder::Instance())
{
Create();
}
//_________________________________________________________________________
G4Scheduler& G4Scheduler::operator=(const G4Scheduler& right)
{
if(this != &right)
{
Create();
}
return *this;
}
size_t G4Scheduler::GetNTracks()
{
return fTrackContainer.GetNTracks();
}
//_________________________________________________________________________
void G4Scheduler::GetCollisionType(G4String& interactionType)
{
switch(fITStepStatus)
{
case eInteractionWithMedium:
interactionType = "eInteractionWithMedium";
break;
case eCollisionBetweenTracks:
interactionType = "eCollisionBetweenTracks";
break;
default:
interactionType = "eCollisionBetweenTracks";
break;
}
}