Geant4  10.01.p03
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 90769 2015-06-09 10:33:41Z 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 #include "G4ITReaction.hh"
41 
42 //#define DEBUG_MEM
43 
44 #ifdef DEBUG_MEM
45 #include "G4MemStat.hh"
46 using namespace G4MemStat;
47 #endif
48 
49 G4ThreadLocal std::map<const G4Track*, G4bool> *G4ITModelProcessor::fHasReacted =
50  0;
51 
53 {
54  //ctor
55  if (!fHasReacted) fHasReacted = new std::map<const G4Track*, G4bool>;
56  fpTrack = 0;
57  fpModelHandler = 0;
58  fpModel = 0;
59  fInitialized = false;
60  fpModelManager = 0;
61  fCurrentModel.assign(G4ITType::size(), std::vector<G4VITStepModel*>());
62 
63  for (int i = 0; i < (int) G4ITType::size(); i++)
64  {
65  fCurrentModel[i].assign(G4ITType::size(), 0);
66  }
67  fUserMinTimeStep = -1.;
68 }
69 
71 {
72  //dtor
73  // if(fpModelHandler) delete fpModelHandler; deleted by G4Scheduler
74  fCurrentModel.clear();
75  fReactionInfo.clear();
76 }
77 
78 // Should not be used
80 {
81  //copy ctorr
82  fpTrack = 0;
83  fpModelHandler = 0;
84  fpModel = 0;
85  fInitialized = false;
86  fpModelManager = 0;
87  fUserMinTimeStep = -1.;
88 }
89 
90 // Should not be used
92 {
93  if (this == &rhs) return *this; // handle self assignment
94  //assignment operator
95  return *this;
96 }
97 //______________________________________________________________________________
99 {
100  fpModelHandler->Initialize();
101  fInitialized = true;
102 }
103 
104 //______________________________________________________________________________
105 void G4ITModelProcessor::InitializeStepper(const G4double& currentGlobalTime,
106  const G4double& userMinTime)
107 {
108  // G4cout << "G4ITModelProcessor::InitializeStepper" << G4endl;
109  if (fpModelHandler == 0)
110  {
111  G4ExceptionDescription exceptionDescription;
112  exceptionDescription
113  << "No G4ITModelHandler was passed to the modelProcessor.";
114  G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor002",
115  FatalErrorInArgument, exceptionDescription);
116  }
117  const std::vector<std::vector<G4ITModelManager*> >* modelManager =
118  fpModelHandler->GetAllModelManager();
119 
120  if (modelManager == 0)
121  {
122  G4ExceptionDescription exceptionDescription;
123  exceptionDescription
124  << "No G4ITModelManager was register to G4ITModelHandler.";
125  G4Exception("G4ITModelProcessor::InitializeStepper", "ITModelProcessor003",
126  FatalErrorInArgument, exceptionDescription);
127  }
128 
129  int nbModels1 = modelManager->size();
130 
131  G4VITTimeStepComputer::SetTimes(currentGlobalTime, userMinTime);
132 
133  // TODO !!!
134  // if( nbModels1 != 1 || (nbModels1 == 1 && !fpModelManager) )
135  {
136  int nbModels2 = -1;
137  G4VITStepModel* model = 0;
138  G4ITModelManager* modman = 0;
139 
140  for (int i = 0; i < nbModels1; i++)
141  {
142  nbModels2 = (*modelManager)[i].size();
143 
144  for (int j = 0; j <= i; j++)
145  {
146  modman = (*modelManager)[i][j];
147 
148  if (modman == 0) continue;
149 
150  model = modman->GetModel(currentGlobalTime);
151  G4VITTimeStepComputer* stepper = model->GetTimeStepper();
152 
153 #if defined (DEBUG_MEM)
154  MemStat mem_first, mem_second, mem_diff;
155 #endif
156 
157 #if defined (DEBUG_MEM)
158  mem_first = MemoryUsage();
159 #endif
160 
161  // stepper->PrepareForAllProcessors() ;
162  stepper->Prepare();
163 
164 #if defined (DEBUG_MEM)
165  mem_second = MemoryUsage();
166  mem_diff = mem_second-mem_first;
167  G4cout << "\t || MEM || G4ITModelProcessor::InitializeStepper || After computing stepper -> Prepare(), diff is : " << mem_diff << G4endl;
168 #endif
169  fCurrentModel[i][j] = model;
170  }
171  }
172 
173  if (nbModels1 == 1 && nbModels2 == 1)
174  {
175  fpModelManager = modman;
176  fpModel = model;
177  }
178  else fpModel = 0;
179  }
180 }
181 
182 //______________________________________________________________________________
184  const G4double userMinTimeStep)
185 {
186  // G4cout << "G4ITModelProcessor::CalculateStep" << G4endl;
187  CleanProcessor();
188  if (track == 0)
189  {
190  G4ExceptionDescription exceptionDescription;
191  exceptionDescription << "No track was passed to the method (track == 0).";
192  G4Exception("G4ITModelProcessor::CalculateStep", "ITModelProcessor004",
193  FatalErrorInArgument, exceptionDescription);
194  }
195  SetTrack(track);
196  fUserMinTimeStep = userMinTimeStep;
197 
198  DoCalculateStep();
199 }
200 
201 //______________________________________________________________________________
203 {
204  if (fpModel) // ie only one model has been declared and will be used
205  {
206  fpModel->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep);
207  }
208  else // ie many models have been declared and will be used
209  {
210  std::vector<G4VITStepModel*>& model = fCurrentModel[GetIT(fpTrack)
211  ->GetITType()];
212 
213  for (int i = 0; i < (int) model.size(); i++)
214  {
215  if (model[i] == 0) continue;
216  model[i]->GetTimeStepper()->CalculateStep(*fpTrack, fUserMinTimeStep);
217  }
218  }
219 }
220 
221 //______________________________________________________________________________
223  G4ITReactionSet* reactionSet,
224  const double currentStepTime,
225  const double previousStepTime,
226  const bool reachedUserStepTimeLimit)
227 {
228  // DEBUG
229  // G4cout << "G4ITReactionManager::FindReaction" << G4endl;
230  //if (tracks == 0) return;
231  if(reactionSet == 0) return;
232  if (fpModelHandler->GetAllModelManager()->empty()) return;
233 
234  G4ITReactionPerTrackMap& reactionPerTrackMap = reactionSet->GetReactionMap();
235 
236  std::map<G4Track*, G4ITReactionPerTrackPtr, compTrackPerID>::iterator tracks_i = reactionPerTrackMap.begin();
237 
238  //std::map<G4Track*, G4TrackVectorHandle, compTrackPerID>::iterator tracks_i = tracks->begin();
239 
240  // G4cout << "G4ITModelProcessor::FindReaction at step :" << G4ITTimeStepper::Instance()->GetNbSteps() << G4endl;
241 
242  // for (tracks_i = tracks->begin(); tracks_i != tracks->end(); tracks_i++)
243  for (tracks_i = reactionPerTrackMap.begin();
244  tracks_i != reactionPerTrackMap.end() ;
245  tracks_i = reactionPerTrackMap.begin())
246  {
247  //G4cout << "here" << G4endl;
248  G4Track* trackA = tracks_i->first;
249  if (trackA->GetTrackStatus() == fStopAndKill)
250  {
251  //G4cout << "continue 1" << G4endl;
252  continue;
253  }
254 
255  G4ITReactionPerTrackPtr reactionPerTrack = tracks_i->second;
256  G4ITReactionList& reactionList = reactionPerTrack->GetReactionList();
257 
258  G4IT* ITA = GetIT(trackA);
259  G4ITType ITypeA = ITA->GetITType();
260 
261  const std::vector<G4VITStepModel*> model = fCurrentModel[ITypeA];
262 
263  G4Track* trackB = 0;
264  G4ITType ITypeB(-1);
265  G4VITReactionProcess* process = 0;
266  G4ITReactionChange* changes = 0;
267 
268  assert(reactionList.begin() != reactionList.end());
269 
270  for(G4ITReactionList::iterator it = reactionList.begin() ;
271  it != reactionList.end() ; it = reactionList.begin() )
272  {
273  G4ITReactionPtr reaction(*it);
274  trackB = reaction->GetReactant(trackA);
275  if(trackB->GetTrackStatus() == fStopAndKill)
276  {
277  //G4cout << "continue 2" << G4endl;
278  continue;
279  }
280 
281  if (trackB == trackA)
282  {
283  G4ExceptionDescription exceptionDescription;
284  exceptionDescription
285  << "The IT reaction process sent back a reaction between trackA and trackB. ";
286  exceptionDescription << "The problem is trackA == trackB";
287  G4Exception("G4ITModelProcessor::FindReaction", "ITModelProcessor005",
288  FatalErrorInArgument, exceptionDescription);
289  }
290 
291  G4IT* ITB = GetIT(trackB);
292  G4ITType ITypeBtmp = ITB->GetITType();
293 
294  if (ITypeB != ITypeBtmp)
295  {
296  ITypeB = ITypeBtmp;
297 
298  if (model[ITypeB]) process = model[ITypeB]->GetReactionProcess();
299  }
300 
301  reactionSet->SelectThisReaction(reaction);
302 
303  if (process && process->TestReactibility(*trackA, *trackB,
304  currentStepTime,
305  previousStepTime,
306  reachedUserStepTimeLimit))
307  {
308  changes = process->MakeReaction(*trackA, *trackB);
309  }
310 
311  if (changes)
312  {
313  fReactionInfo.push_back(changes);
314 
315  // G4cout << "pushing reaction for trackA (" << trackA->GetTrackID() << ") and trackB ("
316  // << trackB->GetTrackID() << ")" << G4endl;
317  //
318  // G4cout << "nb of secondaries : " << changes->GetNumberOfSecondaries() << G4endl;
319  // G4cout << "with track 0 = " << changes->GetSecondary(0) << G4endl;
320 
321  process->ResetChanges();
322  changes = 0;
323 
324  break;
325  }
326  }
327  }
328 
329  //assert(G4ITReaction::gAll->empty() == true);
330 }
virtual G4bool TestReactibility(const G4Track &, const G4Track &, const double, const double, bool)=0
Similar to G4ParticleChange, but deal with two tracks rather than one.
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
G4shared_ptr< G4ITReaction > G4ITReactionPtr
Definition: G4ITReaction.hh:34
#define G4ThreadLocal
Definition: tls.hh:89
MemStat MemoryUsage()
Definition: G4MemStat.cc:55
std::map< G4Track *, G4ITReactionPerTrackPtr, compTrackPerID > G4ITReactionPerTrackMap
Definition: G4ITReaction.hh:41
G4ITReactionPerTrackMap & GetReactionMap()
static void SetTimes(const G4double &, const G4double &)
void SelectThisReaction(G4ITReactionPtr reaction)
void FindReaction(G4ITReactionSet *reactionSet, const double currentStepTime, const double previousStepTime, const bool reachedUserStepTimeLimit)
G4IT * GetIT(const G4Track *track)
Definition: G4IT.cc:49
std::list< G4ITReactionPtr > G4ITReactionList
Definition: G4ITReaction.hh:38
G4GLOB_DLL std::ostream G4cout
static size_t size()
Definition: G4ITType.cc:46
G4VITTimeStepComputer * GetTimeStepper()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4ITModelProcessor & operator=(const G4ITModelProcessor &other)
Assignment operator.
G4shared_ptr< G4ITReactionPerTrack > G4ITReactionPerTrackPtr
Definition: G4ITReaction.hh:36
virtual const G4ITType GetITType() const =0
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.