Geant4 11.2.2
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4ITModelProcessor.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 "G4ITModelProcessor.hh"
38#include "G4ITReaction.hh"
39#include "G4ITTrackHolder.hh"
41#include "G4VITStepModel.hh"
43#include "G4UnitsTable.hh"
44#include "G4Scheduler.hh"
45#include "G4SystemOfUnits.hh"
46#include <vector>
47
48//#define DEBUG_MEM
49
50#ifdef DEBUG_MEM
51#include "G4MemStat.hh"
52using namespace G4MemStat;
53#endif
54
56{
57 fpTrack = nullptr;
58 fInitialized = false;
59 fUserMinTimeStep = -1.;
61 fpTrackingManager = nullptr;
62 fReactionSet = nullptr;
63 fpTrackContainer = nullptr;
64 fpModelHandler = nullptr;
66 fComputeTimeStep = false;
67 fComputeReaction = false;
68}
69
71
73{
74 fpModelHandler->RegisterModel(model, time);
75}
76
94
96 G4double definedMinTimeStep)
97{
98
99#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
100 MemStat mem_first, mem_second, mem_diff;
101 mem_first = MemoryUsage();
102#endif
103
106
107 InitializeStepper(currentGlobalTime, definedMinTimeStep);
108
109#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
110 mem_second = MemoryUsage();
111 mem_diff = mem_second-mem_first;
112 G4cout << "\t || MEM || G4Scheduler::CalculateMinTimeStep || After "
113 "computing fpModelProcessor -> InitializeStepper, diff is : "
114 << mem_diff
115 << G4endl;
116#endif
117
118 for (auto& pStepModel : fActiveModels)
119 {
121 pStepModel->GetTimeStepper()->CalculateMinTimeStep(
122 currentGlobalTime,
123 definedMinTimeStep);
124
125 fpActiveModelWithMinTimeStep = pStepModel;
126
127 if(fTSTimeStep == -1){
129 if(fReactionSet->Empty()) return DBL_MAX;
130 auto fReactionSetInTime = fReactionSet->GetReactionsPerTime();
131 fTSTimeStep = fReactionSetInTime.begin()->get()->GetTime() - currentGlobalTime;
132 }
133 }
134
135#if defined (DEBUG_MEM) && defined (DEBUG_MEM_DETAILED_STEPPING)
136 mem_second = MemoryUsage();
137 mem_diff = mem_second-mem_first;
138 G4cout << "\t || MEM || G4Scheduler::CalculateMinTimeStep || "
139 "After looping on tracks, diff is : " << mem_diff << G4endl;
140#endif
141 return fTSTimeStep;
142}
143
144//______________________________________________________________________________
145
147 G4double userMinTime)
148{
149 G4VITTimeStepComputer::SetTimes(currentGlobalTime, userMinTime);
150
151#if defined (DEBUG_MEM)
152 MemStat mem_first, mem_second, mem_diff;
153 mem_first = MemoryUsage();
154#endif
155
156 fActiveModels = fpModelHandler->GetActiveModels(currentGlobalTime);
157
158 for (auto& pModel : fActiveModels)
159 {
160 pModel->PrepareNewTimeStep();
161 }
162
163#if defined (DEBUG_MEM)
164 mem_second = MemoryUsage();
165 mem_diff = mem_second-mem_first;
166 G4cout << "\t || MEM || G4ITModelProcessor::InitializeStepper || After computing stepper -> Prepare(), diff is : " << mem_diff << G4endl;
167#endif
168
169}
170
171//_________________________________________________________________________
172
174 G4double fGlobalTime,
175 G4double currentTimeStep,
176 G4double /*previousTimeStep*/,
177 G4bool reachedUserTimeLimit,
178 G4double fTimeTolerance,
179 G4UserTimeStepAction* fpUserTimeStepAction,
180 G4int
181#ifdef G4VERBOSE
182fVerbose
183#endif
184)
185{
186 if (fReactionSet->Empty())
187 {
188 return;
189 }
190
191 if (fITStepStatus == eCollisionBetweenTracks)
192 {
194 fReactionInfo = pReactionProcess->FindReaction(fReactionSet,
195 currentTimeStep,
196 fGlobalTime,
197 reachedUserTimeLimit);
198
199 // TODO
200 // A ne faire uniquement si le temps choisis est celui calculé par le time stepper
201 // Sinon utiliser quelque chose comme : fModelProcessor->FindReaction(&fMainList);
202
203 for (auto& pChanges : fReactionInfo)
204 {
205 auto pTrackA = const_cast<G4Track*>(pChanges->GetTrackA());
206 auto pTrackB = const_cast<G4Track*>(pChanges->GetTrackB());
207
208 if (pTrackA == nullptr
209 || pTrackB == nullptr
210 || pTrackA->GetTrackStatus() == fStopAndKill
211 || pTrackB->GetTrackStatus() == fStopAndKill)
212 {
213 continue;
214 }
215
216 G4int nbSecondaries = pChanges->GetNumberOfSecondaries();
217 const std::vector<G4Track*>* productsVector = pChanges->GetfSecondary();
218
219 if (fpUserTimeStepAction != nullptr)
220 {
221 fpUserTimeStepAction->UserReactionAction(*pTrackA,
222 *pTrackB,
223 productsVector);
224 }
225
226#ifdef G4VERBOSE
227 if (fVerbose != 0)
228 {
229 G4cout << "At time : " << std::setw(7) << G4BestUnit(fGlobalTime, "Time")
230 << " Reaction : " << GetIT(pTrackA)->GetName() << " ("
231 << pTrackA->GetTrackID() << ") + " << GetIT(pTrackB)->GetName() << " ("
232 << pTrackB->GetTrackID() << ") -> ";
233 }
234#endif
235
236 if (nbSecondaries > 0)
237 {
238 for (int i = 0; i < nbSecondaries; ++i)
239 {
240#ifdef G4VERBOSE
241 if ((fVerbose != 0) && i != 0)
242 {
243 G4cout << " + ";
244 }
245#endif
246
247 G4Track* secondary = (*productsVector)[i]; //changes->GetSecondary(i);
248// fpTrackContainer->_PushTrack(secondary);
249 GetIT(secondary)->SetParentID(pTrackA->GetTrackID(),
250 pTrackB->GetTrackID());
251
252 if (secondary->GetGlobalTime() - fGlobalTime > fTimeTolerance)
253 {
254 G4ExceptionDescription exceptionDescription;
255 exceptionDescription << "The time of the secondary should not be bigger than the"
256 " current global time."
257 << " This may cause synchronization problem. If the process you"
258 " are using required "
259 << "such feature please contact the developers." << G4endl
260 << "The global time in the step manager : "
261 << G4BestUnit(fGlobalTime, "Time")
262 << G4endl
263 << "The global time of the track : "
264 << G4BestUnit(secondary->GetGlobalTime(), "Time")
265 << G4endl;
266
267 G4Exception("G4Scheduler::ComputeInteractionBetweenTracks",
268 "ITScheduler010",
270 exceptionDescription);
271 }
272
273#ifdef G4VERBOSE
274 if (fVerbose != 0)
275 {
276 G4cout << GetIT(secondary)->GetName() << " ("
277 << secondary->GetTrackID() << ")";
278 }
279#endif
280 }
281 }
282 else
283 {
284#ifdef G4VERBOSE
285 if (fVerbose != 0)
286 {
287 G4cout << "No product";
288 }
289#endif
290 }
291#ifdef G4VERBOSE
292 if (fVerbose != 0)
293 {
294 G4cout << G4endl;
295 }
296#endif
297 if (pTrackA->GetTrackID() == 0 || pTrackB->GetTrackID() == 0)
298 {
299 G4Track* pTrack = nullptr;
300 if (pTrackA->GetTrackID() == 0)
301 {
302 pTrack = pTrackA;
303 }
304 else
305 {
306 pTrack = pTrackB;
307 }
308
309 G4ExceptionDescription exceptionDescription;
310 exceptionDescription
311 << "The problem was found for the reaction between tracks :"
312 << pTrackA->GetParticleDefinition()->GetParticleName() << " ("
313 << pTrackA->GetTrackID() << ") & "
314 << pTrackB->GetParticleDefinition()->GetParticleName() << " ("
315 << pTrackB->GetTrackID() << "). \n";
316
317 if (pTrack->GetStep() == nullptr)
318 {
319 exceptionDescription << "Also no step was found"
320 << " ie track->GetStep() == 0 \n";
321 }
322
323 exceptionDescription << "Parent ID of trackA : "
324 << pTrackA->GetParentID() << "\n";
325 exceptionDescription << "Parent ID of trackB : "
326 << pTrackB->GetParentID() << "\n";
327
328 exceptionDescription
329 << "The ID of one of the reaction track was not setup.";
330 G4Exception("G4Scheduler::ComputeInteractionBetweenTracks",
331 "ITScheduler011",
333 exceptionDescription);
334 }
335
336 if (pChanges->WereParentsKilled())
337 {
338 pTrackA->SetTrackStatus(fStopAndKill);
339 pTrackB->SetTrackStatus(fStopAndKill);
340
343 }
344
345 pChanges.reset(nullptr);
346 }
347
348 fReactionInfo.clear();
349 }
350
351// fReactionSet->CleanAllReaction();
352
355}
356
358{
359 fpTrack = track;
360}
361
363{
364 if (fInitialized)
365 {
366 G4ExceptionDescription exceptionDescription;
367 exceptionDescription
368 << "You are trying to set a new model while the model processor has alreaday be initialized";
369 G4Exception("G4ITModelProcessor::SetModelHandler", "ITModelProcessor001",
370 FatalErrorInArgument, exceptionDescription);
371 }
372 fpModelHandler = pModelHandler;
373}
374
376{
377 fpTrack = nullptr;
378}
379
384
386{
387 return fpTrack;
388}
389
391{
392 fpTrackingManager = pTrackingManager;
393}
394
@ FatalErrorInArgument
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
std::ostringstream G4ExceptionDescription
G4ITStepStatus
@ eCollisionBetweenTracks
G4IT * GetIT(const G4Track *track)
Definition G4IT.cc:48
#define G4BestUnit(a, b)
@ fStopAndKill
double G4double
Definition G4Types.hh:83
bool G4bool
Definition G4Types.hh:86
int G4int
Definition G4Types.hh:85
#define G4endl
Definition G4ios.hh:67
G4GLOB_DLL std::ostream G4cout
void RegisterModel(G4VITStepModel *pModel, G4double globalTime)
std::vector< G4VITStepModel * > GetActiveModels(G4double globalTime) const
void SetModelHandler(G4ITModelHandler *)
G4ITTrackHolder * fpTrackContainer
G4ITReactionSet * fReactionSet
void InitializeStepper(G4double currentGlobalTime, G4double userMinTime)
void SetTrackingManager(G4ITTrackingManager *trackingManager)
G4VITStepModel * fpActiveModelWithMinTimeStep
const G4Track * GetTrack() const
std::vector< G4VITStepModel * > fActiveModels
void RegisterModel(double time, G4VITStepModel *)
std::vector< std::unique_ptr< G4ITReactionChange > > fReactionInfo
void SetTrack(const G4Track *)
G4ITTrackingManager * fpTrackingManager
G4double CalculateMinTimeStep(G4double currentGlobalTime, G4double definedMinTimeStep)
void ComputeTrackReaction(G4ITStepStatus fITStepStatus, G4double fGlobalTime, G4double currentTimeStep, G4double previousTimeStep, G4bool reachedUserTimeLimit, G4double fTimeTolerance, G4UserTimeStepAction *fpUserTimeStepAction, G4int fVerbose)
G4ITModelHandler * fpModelHandler
virtual ~G4ITModelProcessor()
bool GetComputeTimeStep() const
static G4ITReactionSet * Instance()
G4ITReactionPerTime & GetReactionsPerTime()
void MergeSecondariesWithMainList()
static G4ITTrackHolder * Instance()
void EndTracking(G4Track *)
void SetParentID(int, int)
Definition G4IT.hh:228
virtual const G4String & GetName() const =0
const G4String & GetParticleName() const
G4int GetTrackID() const
const G4ParticleDefinition * GetParticleDefinition() const
G4double GetGlobalTime() const
const G4Step * GetStep() const
virtual void UserReactionAction(const G4Track &, const G4Track &, const std::vector< G4Track * > *)
virtual std::vector< std::unique_ptr< G4ITReactionChange > > FindReaction(G4ITReactionSet *, const double, const double, const bool)=0
G4VITReactionProcess * GetReactionProcess()
static void SetTimes(const G4double &, const G4double &)
#define DBL_MAX
Definition templates.hh:62