Geant4  10.01.p01
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 // $Id: G4ITModelProcessor.cc 87375 2014-12-02 08:17:28Z gcosmo $
27 //
28 // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
29 //
30 // History:
31 // -----------
32 // 10 Oct 2011 M.Karamitros created
33 //
34 // -------------------------------------------------------------------
35 
36 #include "G4ITModelProcessor.hh"
37 #include "G4VITTimeStepComputer.hh"
38 #include "G4VITReactionProcess.hh"
39 //#include "G4ITTimeStepper.hh"
40 
41 //#define DEBUG_MEM
42 
43 #ifdef DEBUG_MEM
44 #include "G4MemStat.hh"
45 using namespace G4MemStat;
46 #endif
47 
48 G4ThreadLocal std::map<const G4Track*, G4bool> *G4ITModelProcessor::fHasReacted =
49  0;
50 
52 {
53  //ctor
54  if (!fHasReacted) fHasReacted = new std::map<const G4Track*, G4bool>;
55  fpTrack = 0;
56  fpModelHandler = 0;
57  fpModel = 0;
58  fInitialized = false;
59  fpModelManager = 0;
60  fCurrentModel.assign(G4ITType::size(), std::vector<G4VITStepModel*>());
61 
62  for (int i = 0; i < (int) G4ITType::size(); i++)
63  {
64  fCurrentModel[i].assign(G4ITType::size(), 0);
65  }
66  fUserMinTimeStep = -1.;
67 }
68 
70 {
71  //dtor
72 // if(fpModelHandler) delete fpModelHandler; deleted by G4Scheduler
73  fCurrentModel.clear();
74  fReactionInfo.clear();
75 }
76 
77 // Should not be used
79 {
80  //copy ctorr
81  fpTrack = 0;
82  fpModelHandler = 0;
83  fpModel = 0;
84  fInitialized = false;
85  fpModelManager = 0;
86  fUserMinTimeStep = -1.;
87 }
88 
89 // Should not be used
91 {
92  if (this == &rhs) return *this; // handle self assignment
93  //assignment operator
94  return *this;
95 }
96 //______________________________________________________________________________
98 {
99  fpModelHandler->Initialize();
100  fInitialized = true;
101 }
102 
103 //______________________________________________________________________________
104 void G4ITModelProcessor::InitializeStepper(const G4double& currentGlobalTime,
105  const G4double& userMinTime)
106 {
107  // G4cout << "G4ITModelProcessor::InitializeStepper" << G4endl;
108  if (fpModelHandler == 0)
109  {
110  G4ExceptionDescription exceptionDescription;
111  exceptionDescription
112  << "No G4ITModelHandler was passed to the modelProcessor.";
113  G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor002",
114  FatalErrorInArgument, exceptionDescription);
115  }
116  const std::vector<std::vector<G4ITModelManager*> >* modelManager =
117  fpModelHandler->GetAllModelManager();
118 
119  if (modelManager == 0)
120  {
121  G4ExceptionDescription exceptionDescription;
122  exceptionDescription
123  << "No G4ITModelManager was register to G4ITModelHandler.";
124  G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor003",
125  FatalErrorInArgument, exceptionDescription);
126  }
127 
128  int nbModels1 = modelManager->size();
129 
130  G4VITTimeStepComputer::SetTimes(currentGlobalTime, userMinTime);
131 
132  // TODO !!!
133  // if( nbModels1 != 1 || (nbModels1 == 1 && !fpModelManager) )
134  {
135  int nbModels2 = -1;
136  G4VITStepModel* model = 0;
137  G4ITModelManager* modman = 0;
138 
139  for (int i = 0; i < nbModels1; i++)
140  {
141  nbModels2 = (*modelManager)[i].size();
142 
143  for (int j = 0; j <= i; j++)
144  {
145  modman = (*modelManager)[i][j];
146 
147  if (modman == 0) continue;
148 
149  model = modman->GetModel(currentGlobalTime);
150  G4VITTimeStepComputer* stepper = model->GetTimeStepper();
151 
152 #if defined (DEBUG_MEM)
153  MemStat mem_first, mem_second, mem_diff;
154 #endif
155 
156 #if defined (DEBUG_MEM)
157  mem_first = MemoryUsage();
158 #endif
159 
160 // stepper->PrepareForAllProcessors() ;
161  stepper->Prepare();
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  fCurrentModel[i][j] = model;
169  }
170  }
171 
172  if (nbModels1 == 1 && nbModels2 == 1)
173  {
174  fpModelManager = modman;
175  fpModel = model;
176  }
177  else fpModel = 0;
178  }
179 }
180 
181 //______________________________________________________________________________
183  const G4double userMinTimeStep)
184 {
185  // G4cout << "G4ITModelProcessor::CalculateStep" << G4endl;
186  CleanProcessor();
187  if (track == 0)
188  {
189  G4ExceptionDescription exceptionDescription;
190  exceptionDescription << "No track was passed to the method (track == 0).";
191  G4Exception("G4ITModelProcessor::CalculateStep", "ITModelProcessor004",
192  FatalErrorInArgument, exceptionDescription);
193  }
194  SetTrack(track);
195  fUserMinTimeStep = userMinTimeStep;
196 
197  DoCalculateStep();
198 }
199 
200 //______________________________________________________________________________
202 {
203  if (fpModel) // ie only one model has been declared and will be used
204  {
205  fpModel->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep);
206  }
207  else // ie many models have been declared and will be used
208  {
209  std::vector<G4VITStepModel*>& model = fCurrentModel[GetIT(fpTrack)
210  ->GetITType()];
211 
212  for (int i = 0; i < (int) model.size(); i++)
213  {
214  if (model[i] == 0) continue;
215  model[i]->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep);
216  }
217  }
218 }
219 
220 //______________________________________________________________________________
221 void G4ITModelProcessor::FindReaction(std::map<G4Track*, G4TrackVectorHandle>* tracks,
222  const double currentStepTime,
223  const double previousStepTime,
224  const bool reachedUserStepTimeLimit)
225 {
226  // DEBUG
227  // G4cout << "G4ITReactionManager::FindReaction" << G4endl;
228  if (tracks == 0) return;
229 
230  if (fpModelHandler->GetAllModelManager()->empty()) return;
231 
232  std::map<G4Track*, G4TrackVectorHandle>::iterator tracks_i = tracks->begin();
233 
234 // G4cout << "G4ITModelProcessor::FindReaction at step :" << G4ITTimeStepper::Instance()->GetNbSteps() << G4endl;
235 
236  for (tracks_i = tracks->begin(); tracks_i != tracks->end(); tracks_i++)
237  {
239  G4Track* trackA = tracks_i->first;
240 
241  if (trackA == 0) continue;
242 
243  // G4cout << "trackA is " << GetIT(trackA)->GetName() << G4endl;
244 
245  std::map<const G4Track*, G4bool>::iterator it_hasReacted =
246  fHasReacted->find(trackA);
247  if (it_hasReacted != fHasReacted->end()) continue;
248  if (trackA->GetTrackStatus() == fStopAndKill) continue;
249 
250  G4IT* ITA = GetIT(trackA);
251  G4ITType ITypeA = ITA->GetITType();
252 
253  const std::vector<G4VITStepModel*> model = fCurrentModel[ITypeA];
254 
255  G4TrackVectorHandle& trackB_vector = tracks_i->second;
256  std::vector<G4Track*>::iterator trackB_i = trackB_vector->begin();
257 
258  G4Track* trackB = 0;
259  G4ITType ITypeB(-1);
260  G4VITReactionProcess* process = 0;
261  G4ITReactionChange* changes = 0;
262 
263  for (; trackB_i != trackB_vector->end(); trackB_i++)
264  {
265  trackB = *trackB_i;
266 
267  if (trackB == 0) continue;
268  it_hasReacted = fHasReacted->find(trackB);
269  if (it_hasReacted != fHasReacted->end()) continue;
270  if (trackB->GetTrackStatus() == fStopAndKill) continue;
271 
272  // DEBUG
273  // G4cout << "Couple : " << trackA->GetParticleDefinition->GetParticleName() << " ("
274  // << trackA->GetTrackID() << ") "
275  // << trackB->GetParticleDefinition->GetParticleName() << " ("
276  // << trackB->GetTrackID() << ")"
277  // << G4endl;
278 
279  if (trackB == trackA)
280  {
281  G4ExceptionDescription exceptionDescription;
282  exceptionDescription
283  << "The IT reaction process sent back a reaction between trackA and trackB. ";
284  exceptionDescription << "The problem is trackA == trackB";
285  G4Exception("G4ITModelProcessor::FindReaction", "ITModelProcessor005",
286  FatalErrorInArgument, exceptionDescription);
287  }
288 
289  G4IT* ITB = GetIT(trackB);
290  G4ITType ITypeBtmp = ITB->GetITType();
291 
292  if (ITypeB != ITypeBtmp)
293  {
294  ITypeB = ITypeBtmp;
295 
296  if (model[ITypeB]) process = model[ITypeB]->GetReactionProcess();
297  }
298 
299  if (process && process->TestReactibility(*trackA, *trackB,
300  currentStepTime,
301  previousStepTime,
302  reachedUserStepTimeLimit))
303  {
304  changes = process->MakeReaction(*trackA, *trackB);
305  }
306 
307  if (changes)
308  {
309  (*fHasReacted)[trackA] = true;
310  (*fHasReacted)[trackB] = true;
311  changes->GetTrackA();
312  changes->GetTrackB();
313 
314  fReactionInfo.push_back(changes);
315 
316 // G4cout << "pushing reaction for trackA (" << trackA->GetTrackID() << ") and trackB ("
317 // << trackB->GetTrackID() << ")" << G4endl;
318 //
319 // G4cout << "nb of secondaries : " << changes->GetNumberOfSecondaries() << G4endl;
320 // G4cout << "with track 0 = " << changes->GetSecondary(0) << G4endl;
321 
322  process->ResetChanges();
323  changes = 0;
324 
325  break;
326  }
327  }
328  }
329 
330  fHasReacted->clear();
331 }
virtual G4bool TestReactibility(const G4Track &, const G4Track &, const double, const double, bool)=0
Similar to G4ParticleChange, but deal with two tracks rather than one.
const G4Track * GetTrackA()
The G4ITModelProcessor will call the two processes defined in G4VITModel.
static G4ThreadLocal std::map< const G4Track *, G4bool > * fHasReacted
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
Define what to do before stepping and after stepping.
G4TrackStatus GetTrackStatus() const
void CalculateTimeStep(const G4Track *, const G4double)
G4VITReactionProcess defines the reaction between two G4IT.
Tag the G4IT Should be automatically setup by G4IT using : ITDef(MyIT) and ITImp(MyIT) ...
Definition: G4ITType.hh:60
#define G4ThreadLocal
Definition: tls.hh:89
MemStat MemoryUsage()
Definition: G4MemStat.cc:55
CLHEP::shared_ptr< std::vector< G4Track * > > G4TrackVectorHandle
static void SetTimes(const G4double &, const G4double &)
G4IT * GetIT(const G4Track *track)
Definition: G4IT.cc:49
G4GLOB_DLL std::ostream G4cout
static size_t size()
Definition: G4ITType.cc:46
G4VITTimeStepComputer * GetTimeStepper()
const G4Track * GetTrackB()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4ITModelProcessor & operator=(const G4ITModelProcessor &other)
Assignment operator.
virtual const G4ITType GetITType() const =0
void FindReaction(std::map< G4Track *, G4TrackVectorHandle > *, const double currentStepTime, const double previousStepTime, const bool reachedUserStepTimeLimit)
void InitializeStepper(const G4double &currentGlobalTime, const G4double &userMinTime)
#define G4endl
Definition: G4ios.hh:61
G4VITStepModel * GetModel(const G4double globalTime)
double G4double
Definition: G4Types.hh:76
virtual G4ITReactionChange * MakeReaction(const G4Track &, const G4Track &)=0
Before stepping all tracks G4Scheduler calls all the G4VITModel which may contain a G4VITTimeStepper ...
{ Class description:
G4ITModelManager chooses which model to use according to the global simulation time.