Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/management/src/G4ITStepProcessor2.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  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 "G4ITStepProcessor.hh"
 36 #include "G4LossTableManager.hh"
 37 #include "G4EnergyLossTables.hh"
 38 #include "G4ProductionCuts.hh"
 39 #include "G4ProductionCutsTable.hh"
 40 #include "G4VITProcess.hh"
 41 #include "G4TrackingInformation.hh"
 42 #include "G4IT.hh"
 43 #include "G4ITTrackingManager.hh"
 44 #include "G4ITTransportation.hh"
 45 
 46 #include "G4ITNavigator.hh"             // Include from 'geometry'
 47 
 48 #include "G4ITSteppingVerbose.hh"
 49 #include "G4VITSteppingVerbose.hh"
 50 
 51 #include "G4ITTrackHolder.hh"
 52 #include "G4ITReaction.hh"
 53 
 54 
 55 //#define DEBUG_MEM 1
 56 
 57 #ifdef DEBUG_MEM
 58 #include "G4MemStat.hh"
 59 using namespace G4MemStat;
 60 using G4MemStat::MemStat;
 61 #endif
 62 
 63 void G4ITStepProcessor::DealWithSecondaries(G4int& counter)
 64 {
 65   // Now Store the secondaries from ParticleChange to SecondaryList
 66   G4Track* tempSecondaryTrack;
 67 
 68   for(G4int DSecLoop = 0; DSecLoop < fpParticleChange->GetNumberOfSecondaries();
 69       DSecLoop++)
 70   {
 71     tempSecondaryTrack = fpParticleChange->GetSecondary(DSecLoop);
 72 
 73     if(tempSecondaryTrack->GetDefinition()->GetApplyCutsFlag())
 74     {
 75       ApplyProductionCut(tempSecondaryTrack);
 76     }
 77 
 78     // Set parentID
 79     tempSecondaryTrack->SetParentID(fpTrack->GetTrackID());
 80 
 81     // Set the process pointer which created this track
 82     tempSecondaryTrack->SetCreatorProcess(fpCurrentProcess);
 83 
 84     // If this 2ndry particle has 'zero' kinetic energy, make sure
 85     // it invokes a rest process at the beginning of the tracking
 86     if(tempSecondaryTrack->GetKineticEnergy() <= DBL_MIN)
 87     {
 88       G4ProcessManager* pm = tempSecondaryTrack->GetDefinition()->GetProcessManager();
 89       if (pm->GetAtRestProcessVector()->entries()>0)
 90       {
 91         tempSecondaryTrack->SetTrackStatus( fStopButAlive );
 92         fpSecondary->push_back( tempSecondaryTrack );
 93         fN2ndariesAtRestDoIt++;
 94       }
 95       else
 96       {
 97         delete tempSecondaryTrack;
 98       }
 99     }
100     else
101     {
102       fpSecondary->push_back( tempSecondaryTrack );
103       counter++;
104     }
105   } //end of loop on secondary
106 }
107 
108 //_________________________________________________________________________
109 
110 void G4ITStepProcessor::DoIt(double timeStep)
111 
112 // Call the process having the min step length or just propagate the track on the given time step
113 
114 // If the track is "leading the step" (ie one of its process has been selected
115 // as the one having the minimum time step over all tracks and processes),
116 // it will undergo its selected processes. Otherwise, it will just propagate the track
117 // on the given time step.
118 
119 {
120   if(fpVerbose != nullptr) fpVerbose->DoItStarted();
121 
122   G4TrackManyList* mainList = fpTrackContainer->GetMainList();
123   G4TrackManyList::iterator it = mainList->end();
124   it--;
125   std::size_t initialSize = mainList->size();
126 
127 //    G4cout << "initialSize = " << initialSize << G4endl;
128 
129   for(std::size_t i = 0 ; i < initialSize ; ++i)
130   {
131 
132 //      G4cout << "i = " << i << G4endl;
133 
134     G4Track* track = *it;
135     if (track == nullptr)
136     {
137       G4ExceptionDescription exceptionDescription;
138       exceptionDescription << "No track was pop back the main track list.";
139       G4Exception("G4ITStepProcessor::DoIt", "NO_TRACK",
140                   FatalException, exceptionDescription);
141     }
142     // G4TrackManyList::iterator next_it (it);
143     // next_it--;
144     // it = next_it;
145 
146     it--;
147     // Must be called before EndTracking(track)
148     // Otherwise the iterator will point to the list of killed tracks
149 
150     if(track->GetTrackStatus() == fStopAndKill)
151     {
152       fpTrackingManager->EndTracking(track);
153 //      G4cout << GetIT(track)->GetName() << G4endl;
154 //      G4cout << " ************************ CONTINUE ********************" << G4endl;
155       continue;
156     }
157 
158 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DOIT)
159     MemStat mem_first, mem_second, mem_diff;
160     mem_first = MemoryUsage();
161 #endif
162 
163     Stepping(track, timeStep);
164 
165 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DOIT)
166     MemStat mem_intermediaire = MemoryUsage();
167     mem_diff = mem_intermediaire-mem_first;
168     G4cout << "\t\t >> || MEM || In DoIT with track "
169         << track->GetTrackID() << ", diff is : " << mem_diff << G4endl;
170 #endif
171 
172     ExtractDoItData();
173 
174 #if defined (DEBUG_MEM) && defined (DEBUG_MEM_DOIT)
175     mem_second = MemoryUsage();
176     mem_diff = mem_second-mem_first;
177     G4cout << "\t >> || MEM || In DoIT with track "
178         << track->GetTrackID()
179         << ", diff is : " << mem_diff << G4endl;
180 #endif
181   }
182 
183 
184   fpTrackContainer->MergeSecondariesWithMainList();
185   fpTrackContainer->KillTracks(); // (18-06-15 : MK) Remove it ?
186   fLeadingTracks.Reset();
187 }
188 
189 //_________________________________________________________________________
190 
191 void G4ITStepProcessor::ExtractDoItData()
192 {
193   if (fpTrack == nullptr)
194   {
195     CleanProcessor();
196     return;
197   }
198 
199   G4TrackStatus status = fpTrack->GetTrackStatus();
200 
201   switch (status)
202   {
203     case fAlive:
204     case fStopButAlive:
205     case fSuspend:
206     case fPostponeToNextEvent:
207     default:
208       PushSecondaries();
209       break;
210 
211     case fStopAndKill:
212       G4ITReactionSet::Instance()->RemoveReactionSet(fpTrack);
213       PushSecondaries();
214 //      G4TrackList::Pop(fpTrack);
215       fpTrackingManager->EndTracking(fpTrack);
216 //      fTrackContainer->PushToKill(fpTrack);
217       break;
218 
219     case fKillTrackAndSecondaries:
220       G4ITReactionSet::Instance()->RemoveReactionSet(fpTrack);
221       if (fpSecondary != nullptr)
222       {
223         for (auto & i : *fpSecondary)
224         {
225           delete i;
226         }
227         fpSecondary->clear();
228       }
229 //      G4TrackList::Pop(fpTrack);
230       fpTrackingManager->EndTracking(fpTrack);
231 //      fTrackContainer->PushToKill(fpTrack);
232       break;
233   }
234 
235   CleanProcessor();
236 }
237 
238 //_________________________________________________________________________
239 
240 void G4ITStepProcessor::PushSecondaries()
241 {
242   if ((fpSecondary == nullptr) || fpSecondary->empty())
243   {
244     // DEBUG
245     //      G4cout << "NO SECONDARIES !!! " << G4endl;
246     return;
247   }
248 
249   // DEBUG
250   //    G4cout << "There are secondaries : "<< secondaries -> size() << G4endl ;
251 
252   auto secondaries_i = fpSecondary->begin();
253 
254   for (; secondaries_i != fpSecondary->end(); ++secondaries_i)
255   {
256     G4Track* secondary = *secondaries_i;
257     fpTrackContainer->_PushTrack(secondary);
258   }
259 }
260 
261 //______________________________________________________________________________
262 
263 void G4ITStepProcessor::Stepping(G4Track* track, const double & timeStep)
264 {
265 
266 #ifdef DEBUG_MEM
267   MemStat mem_first, mem_second, mem_diff;
268 #endif
269 
270 #ifdef DEBUG_MEM
271   mem_first = MemoryUsage();
272 #endif
273 
274   CleanProcessor();
275 
276 #ifdef DEBUG_MEM
277   MemStat mem_intermediaire = MemoryUsage();
278   mem_diff = mem_intermediaire-mem_first;
279   G4cout << "\t\t\t >> || MEM || After CleanProcessor " << track->GetTrackID() << ", diff is : " << mem_diff << G4endl;
280 #endif
281 
282   if(track == nullptr) return; // maybe put an exception here
283   fTimeStep = timeStep;
284   SetTrack(track);
285   DoStepping();
286 }
287 //______________________________________________________________________________
288 
289 // ************************************************************************
290 //  Stepping
291 // ************************************************************************
292 void G4ITStepProcessor::DoStepping()
293 {
294   SetupMembers();
295 
296 #ifdef DEBUG_MEM
297   MemStat mem_first, mem_second, mem_diff;
298 #endif
299 
300 #ifdef DEBUG_MEM
301   mem_first = MemoryUsage();
302 #endif
303 
304 #ifdef G4VERBOSE
305     if(fpVerbose != nullptr) fpVerbose->PreStepVerbose(fpTrack);
306 #endif
307 
308   if(fpProcessInfo == nullptr)
309   {
310     G4ExceptionDescription exceptionDescription;
311     exceptionDescription << "No process info found for particle :"
312                          << fpTrack->GetDefinition()->GetParticleName();
313     G4Exception("G4ITStepProcessor::DoStepping",
314                 "ITStepProcessor0012",
315                 FatalErrorInArgument,
316                 exceptionDescription);
317     return;
318   }
319 //  else if(fpTrack->GetTrackStatus() == fStopAndKill)
320 //  {
321 //    fpState->fStepStatus = fUndefined;
322 //    return;
323 //  }
324 
325   if(fpProcessInfo->MAXofPostStepLoops == 0 &&
326       fpProcessInfo->MAXofAlongStepLoops == 0
327      && fpProcessInfo->MAXofAtRestLoops == 0)
328   {/*
329     G4ExceptionDescription exceptionDescription;
330     exceptionDescription << "No process was found for particle :"
331                          << fpTrack->GetDefinition()->GetParticleName();
332     G4Exception("G4ITStepProcessor::DoStepping",
333                 "ITStepProcessorNoProcess",
334                 JustWarning,
335                 exceptionDescription);
336 
337     fpTrack->SetTrackStatus(fStopAndKill);
338     fpState->fStepStatus = fUndefined;*/
339     return;
340   }
341 
342   //--------
343   // Prelude
344   //--------
345 #ifdef G4VERBOSE
346   // !!!!! Verbose
347   if(fpVerbose != nullptr) fpVerbose->NewStep();
348 #endif
349 
350   //---------------------------------
351   // AtRestStep, AlongStep and PostStep Processes
352   //---------------------------------
353 
354   fpNavigator->SetNavigatorState(fpITrack->GetTrackingInfo()->GetNavigatorState());
355 //        fpNavigator->ResetHierarchyAndLocate( fpTrack->GetPosition(),
356 //                                              fpTrack->GetMomentumDirection(),
357 //                                              *((G4TouchableHistory*)fpTrack->GetTouchableHandle()()) );
358 //        fpNavigator->SetNavigatorState(fpITrack->GetTrackingInfo()->GetNavigatorState());
359   // We reset the navigator state before checking for AtRest
360   // in case a AtRest processe would use a navigator info
361 
362 #ifdef DEBUG_MEM
363   MemStat mem_intermediaire = MemoryUsage();
364   mem_diff = mem_intermediaire-mem_first;
365   G4cout << "\t\t\t >> || MEM || G4ITStepProcessor::DoStepping || After dealing with navigator with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
366 #endif
367 
368   if(fpTrack->GetTrackStatus() == fStopButAlive)
369   {
370     if(fpProcessInfo->MAXofAtRestLoops > 0 && fpProcessInfo->fpAtRestDoItVector
371         != nullptr) // second condition to make coverity happy
372     {
373       //-----------------
374       // AtRestStepDoIt
375       //-----------------
376       InvokeAtRestDoItProcs();
377       fpState->fStepStatus = fAtRestDoItProc;
378       fpStep->GetPostStepPoint()->SetStepStatus(fpState->fStepStatus);
379 
380 #ifdef G4VERBOSE
381             // !!!!! Verbose
382       if(fpVerbose != nullptr) fpVerbose->AtRestDoItInvoked();
383 #endif
384 
385     }
386     // Make sure the track is killed
387     // fpTrack->SetTrackStatus(fStopAndKill);
388   }
389   else // if(fTimeStep > 0.) // Bye, because PostStepIL can return 0 => time =0
390   {
391     if(fpITrack == nullptr)
392     {
393       G4ExceptionDescription exceptionDescription;
394       exceptionDescription << " !!! TrackID : " << fpTrack->GetTrackID()
395                            << G4endl<< " !!! Track status : "<< fpTrack->GetTrackStatus() << G4endl
396       << " !!! Particle Name : "<< fpTrack -> GetDefinition() -> GetParticleName() << G4endl
397       << "No G4ITStepProcessor::fpITrack found" << G4endl;
398 
399       G4Exception("G4ITStepProcessor::DoStepping",
400                   "ITStepProcessor0013",
401                   FatalErrorInArgument,
402                   exceptionDescription);
403       return; // to make coverity happy
404     }
405 
406     if(!fpITrack->GetTrackingInfo()->IsLeadingStep())
407     {
408       // In case the track has NOT the minimum step length
409       // Given the final step time, the transportation
410       // will compute the final position of the particle
411       fpState->fStepStatus = fPostStepDoItProc;
412       fpStep->GetPostStepPoint()->SetProcessDefinedStep(fpTransportation);
413       FindTransportationStep();
414     }
415 
416 #ifdef DEBUG_MEM
417     mem_intermediaire = MemoryUsage();
418     mem_diff = mem_intermediaire-mem_first;
419     G4cout << "\t\t\t >> || MEM || G4ITStepProcessor::DoStepping || After FindTransportationStep() with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
420 #endif
421 
422     // Store the Step length (geometrical length) to G4Step and G4Track
423     fpTrack->SetStepLength(fpState->fPhysicalStep);
424     fpStep->SetStepLength(fpState->fPhysicalStep);
425 
426     G4double GeomStepLength = fpState->fPhysicalStep;
427 
428     // Store StepStatus to PostStepPoint
429     fpStep->GetPostStepPoint()->SetStepStatus(fpState->fStepStatus);
430 
431     // Invoke AlongStepDoIt
432     InvokeAlongStepDoItProcs();
433 
434 #ifdef DEBUG_MEM
435     mem_intermediaire = MemoryUsage();
436     mem_diff = mem_intermediaire-mem_first;
437     G4cout << "\t\t\t >> || MEM || G4ITStepProcessor::DoStepping || After InvokeAlongStepDoItProcs() with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
438 #endif
439 
440 #ifdef G4VERBOSE
441     // !!!!! Verbose
442     if(fpVerbose != nullptr) fpVerbose->AlongStepDoItAllDone();
443 #endif
444 
445     // Update track by taking into account all changes by AlongStepDoIt
446     // fpStep->UpdateTrack(); // done in InvokeAlongStepDoItProcs
447 
448     // Update safety after invocation of all AlongStepDoIts
449     fpState->fEndpointSafOrigin = fpPostStepPoint->GetPosition();
450 
451     fpState->fEndpointSafety =
452         std::max(fpState->fProposedSafety - GeomStepLength, kCarTolerance);
453 
454     fpStep->GetPostStepPoint()->SetSafety(fpState->fEndpointSafety);
455 
456     if(GetIT(fpTrack)->GetTrackingInfo()->IsLeadingStep())
457     {
458       // Invoke PostStepDoIt including G4ITTransportation::PSDI
459       InvokePostStepDoItProcs();
460 
461 #ifdef DEBUG_MEM
462       mem_intermediaire = MemoryUsage();
463       mem_diff = mem_intermediaire-mem_first;
464       G4cout << "\t\t\t >> || MEM || G4ITStepProcessor::DoStepping || After InvokePostStepDoItProcs() with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
465 #endif
466 #ifdef G4VERBOSE
467     // !!!!! Verbose
468     if(fpVerbose != nullptr) fpVerbose->StepInfoForLeadingTrack();
469 #endif
470     }
471     else
472     {
473       // Only invoke transportation and all other forced processes
474       InvokeTransportationProc();
475       fpStep->GetPostStepPoint()->SetProcessDefinedStep(fpTransportation);
476 
477 #ifdef DEBUG_MEM
478       mem_intermediaire = MemoryUsage();
479       mem_diff = mem_intermediaire-mem_first;
480       G4cout << "\t\t\t >> || MEM || G4ITStepProcessor::DoStepping || After InvokeTransportationProc() with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
481 #endif
482     }
483 
484 #ifdef G4VERBOSE
485     // !!!!! Verbose
486     if(fpVerbose != nullptr) fpVerbose->PostStepDoItAllDone();
487 #endif
488   }
489 
490   fpNavigator->ResetNavigatorState();
491 
492 #ifdef DEBUG_MEM
493   mem_intermediaire = MemoryUsage();
494   mem_diff = mem_intermediaire-mem_first;
495   G4cout << "\t\t\t >> || MEM || G4ITStepProcessor::DoStepping || After fpNavigator->SetNavigatorState with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
496 #endif
497 
498   //-------
499   // Finale
500   //-------
501 
502   // Update 'TrackLength' and remeber the Step length of the current Step
503   fpTrack->AddTrackLength(fpStep->GetStepLength());
504   fpTrack->IncrementCurrentStepNumber();
505 
506 //#ifdef G4VERBOSE
507 // //    !!!!! Verbose
508 //  if(fpVerbose) fpVerbose->StepInfo();
509 //#endif
510 
511 #ifdef G4VERBOSE
512     if(fpVerbose != nullptr) fpVerbose->PostStepVerbose(fpTrack);
513 #endif
514 
515 //    G4cout << " G4ITStepProcessor::DoStepping  -- " <<fpTrack->GetTrackID() << " tps = " << fpTrack->GetGlobalTime() << G4endl;
516 
517   // Send G4Step information to Hit/Dig if the volume is sensitive
518   /***
519    fpCurrentVolume = fpStep->GetPreStepPoint()->GetPhysicalVolume();
520    StepControlFlag =  fpStep->GetControlFlag();
521 
522    if( fpCurrentVolume != 0 && StepControlFlag != AvoidHitInvocation)
523    {
524    fpSensitive = fpStep->GetPreStepPoint()->
525    GetSensitiveDetector();
526    if( fpSensitive != 0 )
527    {
528    fpSensitive->Hit(fpStep);
529    }
530    }
531 
532    User intervention process.
533    if( fpUserSteppingAction != 0 )
534    {
535    fpUserSteppingAction->UserSteppingAction(fpStep);
536    }
537    G4UserSteppingAction* regionalAction
538    = fpStep->GetPreStepPoint()->GetPhysicalVolume()->GetLogicalVolume()->GetRegion()
539    ->GetRegionalSteppingAction();
540    if( regionalAction ) regionalAction->UserSteppingAction(fpStep);
541    ***/
542   fpTrackingManager->AppendStep(fpTrack, fpStep);
543   // Stepping process finish. Return the value of the StepStatus.
544 
545 #ifdef DEBUG_MEM
546   MemStat mem_intermediaire = MemoryUsage();
547   mem_diff = mem_intermediaire-mem_first;
548   G4cout << "\t\t\t >> || MEM || End of DoStepping() with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
549 #endif
550 
551   //    return fpState->fStepStatus;
552 }
553 
554 //______________________________________________________________________________
555 
556 // ************************************************************************
557 //  AtRestDoIt
558 // ************************************************************************
559 
560 void G4ITStepProcessor::InvokeAtRestDoItProcs()
561 {
562   fpStep->SetStepLength(0.);  //the particle has stopped
563   fpTrack->SetStepLength(0.);
564 
565   G4SelectedAtRestDoItVector& selectedAtRestDoItVector =
566       fpState->fSelectedAtRestDoItVector;
567 
568   // invoke selected process
569   for(std::size_t np = 0; np < fpProcessInfo->MAXofAtRestLoops; ++np)
570   {
571     //
572     // Note: DoItVector has inverse order against GetPhysIntVector
573     //       and SelectedAtRestDoItVector.
574     //
575     if(selectedAtRestDoItVector[fpProcessInfo->MAXofAtRestLoops - np - 1] != InActivated)
576     {
577       fpCurrentProcess =
578           (G4VITProcess*) (*fpProcessInfo->fpAtRestDoItVector)[(G4int)np];
579 
580 //      G4cout << " Invoke : "
581 //             << fpCurrentProcess->GetProcessName()
582 //             << G4endl;
583 
584       //  if(fpVerbose)
585       //  {
586       //    fpVerbose->AtRestDoItOneByOne();
587       //  }
588 
589       fpCurrentProcess->SetProcessState(fpTrackingInfo->GetProcessState(fpCurrentProcess
590           ->GetProcessID()));
591       fpParticleChange = fpCurrentProcess->AtRestDoIt(*fpTrack, *fpStep);
592       fpCurrentProcess->ResetProcessState();
593 
594       // Set the current process as a process which defined this Step length
595       fpStep->GetPostStepPoint()->SetProcessDefinedStep(fpCurrentProcess);
596 
597       // Update Step
598       fpParticleChange->UpdateStepForAtRest(fpStep);
599 
600       // Now Store the secondaries from ParticleChange to SecondaryList
601       DealWithSecondaries(fN2ndariesAtRestDoIt);
602 
603       // Set the track status according to what the process defined
604       // if kinetic energy >0, otherwise set  fStopButAlive
605       fpTrack->SetTrackStatus(fpParticleChange->GetTrackStatus());
606 
607       // clear ParticleChange
608       fpParticleChange->Clear();
609 
610     } //if(fSelectedAtRestDoItVector[np] != InActivated){
611   } //for(std::size_t np=0; np < MAXofAtRestLoops; ++np){
612   fpStep->UpdateTrack();
613 
614   // Modification par rapport au transport standard :
615   // fStopAndKill doit etre propose par le modele
616   // sinon d autres processus AtRest seront appeles
617   // au pas suivant
618   // fpTrack->SetTrackStatus(fStopAndKill);
619 }
620 
621 //______________________________________________________________________________
622 
623 // ************************************************************************
624 //  AlongStepDoIt
625 // ************************************************************************
626 
627 void G4ITStepProcessor::InvokeAlongStepDoItProcs()
628 {
629 
630 #ifdef DEBUG_MEM
631   MemStat mem_first, mem_second, mem_diff;
632 #endif
633 
634 #ifdef DEBUG_MEM
635   mem_first = MemoryUsage();
636 #endif
637 
638   // If the current Step is defined by a 'ExclusivelyForced'
639   // PostStepDoIt, then don't invoke any AlongStepDoIt
640   if(fpState->fStepStatus == fExclusivelyForcedProc)
641   {
642     return;               // Take note 'return' at here !!!
643   }
644 
645   // Invoke the all active continuous processes
646   for(std::size_t ci = 0; ci < fpProcessInfo->MAXofAlongStepLoops; ++ci)
647   {
648     fpCurrentProcess =
649         (G4VITProcess*) (*fpProcessInfo->fpAlongStepDoItVector)[(G4int)ci];
650     if(fpCurrentProcess == nullptr) continue;
651     // NULL means the process is inactivated by a user on fly.
652 
653     fpCurrentProcess->SetProcessState(fpTrackingInfo->GetProcessState(fpCurrentProcess
654         ->GetProcessID()));
655     fpParticleChange = fpCurrentProcess->AlongStepDoIt(*fpTrack, *fpStep);
656 
657 #ifdef DEBUG_MEM
658     MemStat mem_intermediaire = MemoryUsage();
659     mem_diff = mem_intermediaire-mem_first;
660     G4cout << "\t\t\t >> || MEM || After calling AlongStepDoIt for " << fpCurrentProcess->GetProcessName() << " and track "<< fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
661 #endif
662 
663 //        fpCurrentProcess->SetProcessState(0);
664     fpCurrentProcess->ResetProcessState();
665     // Update the PostStepPoint of Step according to ParticleChange
666 
667     fpParticleChange->UpdateStepForAlongStep(fpStep);
668 
669 #ifdef G4VERBOSE
670     // !!!!! Verbose
671     if(fpVerbose != nullptr) fpVerbose->AlongStepDoItOneByOne();
672 #endif
673 
674     // Now Store the secondaries from ParticleChange to SecondaryList
675     DealWithSecondaries(fN2ndariesAlongStepDoIt);
676 
677     // Set the track status according to what the process defined
678     // if kinetic energy >0, otherwise set  fStopButAlive
679     fpTrack->SetTrackStatus(fpParticleChange->GetTrackStatus());
680 
681     // clear ParticleChange
682     fpParticleChange->Clear();
683   }
684 
685 #ifdef DEBUG_MEM
686   MemStat mem_intermediaire = MemoryUsage();
687   mem_diff = mem_intermediaire-mem_first;
688   G4cout << "\t\t\t >> || MEM || After looping on processes with " << fpTrack->GetTrackID() << ", diff is : " << mem_diff << G4endl;
689 #endif
690 
691   fpStep->UpdateTrack();
692 
693   G4TrackStatus fNewStatus = fpTrack->GetTrackStatus();
694 
695   if(fNewStatus == fAlive && fpTrack->GetKineticEnergy() <= DBL_MIN)
696   {
697     //        G4cout << "G4ITStepProcessor::InvokeAlongStepDoItProcs : Track will be killed" << G4endl;
698     if(fpProcessInfo->MAXofAtRestLoops>0) fNewStatus = fStopButAlive;
699     else fNewStatus = fStopAndKill;
700     fpTrack->SetTrackStatus( fNewStatus );
701   }
702 
703 }
704 
705 //______________________________________________________________________________
706 
707 // ************************************************************************
708 //  PostStepDoIt
709 // ************************************************************************
710 
711 void G4ITStepProcessor::InvokePostStepDoItProcs()
712 {
713   std::size_t _MAXofPostStepLoops = fpProcessInfo->MAXofPostStepLoops;
714   G4SelectedPostStepDoItVector& selectedPostStepDoItVector = fpState
715       ->fSelectedPostStepDoItVector;
716   G4StepStatus& stepStatus = fpState->fStepStatus;
717 
718   // Invoke the specified discrete processes
719   for(std::size_t np = 0; np < _MAXofPostStepLoops; ++np)
720   {
721     //
722     // Note: DoItVector has inverse order against GetPhysIntVector
723     //       and SelectedPostStepDoItVector.
724     //
725     G4int Cond = selectedPostStepDoItVector[_MAXofPostStepLoops
726                                             - np - 1];
727     if(Cond != InActivated)
728     {
729       if(((Cond == NotForced) && (stepStatus == fPostStepDoItProc)) ||
730           ((Cond == Forced) && (stepStatus != fExclusivelyForcedProc))
731          ||
732          // ((Cond == Conditionally) && (stepStatus == fAlongStepDoItProc)) ||
733          ((Cond == ExclusivelyForced) && (stepStatus == fExclusivelyForcedProc))
734          || ((Cond == StronglyForced)))
735       {
736 
737         InvokePSDIP(np);
738       }
739     } //if(*fSelectedPostStepDoItVector(np)........
740 
741     // Exit from PostStepLoop if the track has been killed,
742     // but extra treatment for processes with Strongly Forced flag
743     if(fpTrack->GetTrackStatus() == fStopAndKill)
744     {
745       for(std::size_t np1 = np + 1; np1 < _MAXofPostStepLoops; ++np1)
746       {
747         G4int Cond2 = selectedPostStepDoItVector[_MAXofPostStepLoops
748                                                  - np1 - 1];
749         if(Cond2 == StronglyForced)
750         {
751           InvokePSDIP(np1);
752         }
753       }
754       break;
755     }
756   } //for(std::size_t np=0; np < MAXofPostStepLoops; ++np){
757 }
758 
759 //______________________________________________________________________________
760 
761 void G4ITStepProcessor::InvokePSDIP(std::size_t np)
762 {
763   fpCurrentProcess = (G4VITProcess*) (*fpProcessInfo->fpPostStepDoItVector)[(G4int)np];
764 
765   fpCurrentProcess->SetProcessState(fpTrackingInfo->GetProcessState(fpCurrentProcess
766       ->GetProcessID()));
767   fpParticleChange = fpCurrentProcess->PostStepDoIt(*fpTrack, *fpStep);
768 //    fpCurrentProcess->SetProcessState(0);
769   fpCurrentProcess->ResetProcessState();
770 
771   // Update PostStepPoint of Step according to ParticleChange
772   fpParticleChange->UpdateStepForPostStep(fpStep);
773 
774 #ifdef G4VERBOSE
775   // !!!!! Verbose
776   if(fpVerbose != nullptr) fpVerbose->PostStepDoItOneByOne();
777 #endif
778 
779   // Update G4Track according to ParticleChange after each PostStepDoIt
780   fpStep->UpdateTrack();
781 
782   // Update safety after each invocation of PostStepDoIts
783   fpStep->GetPostStepPoint()->SetSafety(CalculateSafety());
784 
785   // Now Store the secondaries from ParticleChange to SecondaryList
786   DealWithSecondaries(fN2ndariesPostStepDoIt);
787 
788   // Set the track status according to what the process defined
789   fpTrack->SetTrackStatus(fpParticleChange->GetTrackStatus());
790 
791   // clear ParticleChange
792   fpParticleChange->Clear();
793 }
794 
795 //______________________________________________________________________________
796 
797 // ************************************************************************
798 //  Transport on a given time
799 // ************************************************************************
800 
801 void G4ITStepProcessor::FindTransportationStep()
802 {
803   double physicalStep(0.);
804 
805   fpTransportation = fpProcessInfo->fpTransportation;
806   // dynamic_cast<G4ITTransportation*>((fpProcessInfo->fpAlongStepGetPhysIntVector)[MAXofAlongStepLoops-1]);
807 
808   if(fpTrack == nullptr)
809   {
810     G4ExceptionDescription exceptionDescription;
811     exceptionDescription << "No G4ITStepProcessor::fpTrack found";
812     G4Exception("G4ITStepProcessor::FindTransportationStep",
813                 "ITStepProcessor0013",
814                 FatalErrorInArgument,
815                 exceptionDescription);
816     return;
817 
818   }
819   if(fpITrack == nullptr)
820   {
821     G4ExceptionDescription exceptionDescription;
822     exceptionDescription << "No G4ITStepProcessor::fITrack";
823     G4Exception("G4ITStepProcessor::FindTransportationStep",
824                 "ITStepProcessor0014",
825                 FatalErrorInArgument,
826                 exceptionDescription);
827     return;
828   }
829   if((fpITrack->GetTrack()) == nullptr)
830   {
831     G4ExceptionDescription exceptionDescription;
832     exceptionDescription << "No G4ITStepProcessor::fITrack->GetTrack()";
833     G4Exception("G4ITStepProcessor::FindTransportationStep",
834                 "ITStepProcessor0015",
835                 FatalErrorInArgument,
836                 exceptionDescription);
837     return;
838   }
839 
840   if(fpTransportation != nullptr)
841   {
842     fpTransportation->SetProcessState(fpTrackingInfo->GetProcessState(fpTransportation
843         ->GetProcessID()));
844     fpTransportation->ComputeStep(*fpTrack, *fpStep, fTimeStep, physicalStep);
845 
846 //        fpTransportation->SetProcessState(0);
847     fpTransportation->ResetProcessState();
848   }
849 
850   if(physicalStep >= DBL_MAX)
851   {
852 //    G4cout << "---- 2) Setting stop and kill for " << GetIT(fpTrack)->GetName() << G4endl;
853     fpTrack -> SetTrackStatus(fStopAndKill);
854     return;
855   }
856 
857   fpState->fPhysicalStep = physicalStep;
858 }
859 
860 //______________________________________________________________________________
861 
862 void G4ITStepProcessor::InvokeTransportationProc()
863 {
864   std::size_t _MAXofPostStepLoops = fpProcessInfo->MAXofPostStepLoops;
865   G4SelectedPostStepDoItVector& selectedPostStepDoItVector = fpState
866       ->fSelectedPostStepDoItVector;
867   G4StepStatus& stepStatus = fpState->fStepStatus;
868 
869   // Invoke the specified discrete processes
870   for(std::size_t np = 0; np < _MAXofPostStepLoops; ++np)
871   {
872     //
873     // Note: DoItVector has inverse order against GetPhysIntVector
874     //       and SelectedPostStepDoItVector.
875     //
876     G4int Cond = selectedPostStepDoItVector[_MAXofPostStepLoops - np - 1];
877     if(Cond != InActivated)
878     {
879       if(((Cond == Forced) && (stepStatus != fExclusivelyForcedProc)) ||
880       // ((Cond == Conditionally) && (stepStatus == fAlongStepDoItProc)) ||
881       ((Cond == ExclusivelyForced) && (stepStatus == fExclusivelyForcedProc))
882          || ((Cond == StronglyForced)))
883       {
884 
885         InvokePSDIP(np);
886       }
887     } //if(Cond != InActivated)
888 
889     // Exit from PostStepLoop if the track has been killed,
890     // but extra treatment for processes with Strongly Forced flag
891     if(fpTrack->GetTrackStatus() == fStopAndKill)
892     {
893       for(std::size_t np1 = np + 1; np1 < _MAXofPostStepLoops; ++np1)
894       {
895         G4int Cond2 = selectedPostStepDoItVector[_MAXofPostStepLoops - np1 - 1];
896         if(Cond2 == StronglyForced)
897         {
898           InvokePSDIP(np1);
899         }
900       }
901       break;
902     }
903   }
904 }
905 
906 //______________________________________________________________________________
907 
908 // ************************************************************************
909 //  Apply cuts
910 // ************************************************************************
911 
912 void G4ITStepProcessor::ApplyProductionCut(G4Track* aSecondary)
913 {
914   G4bool tBelowCutEnergyAndSafety = false;
915   G4int tPtclIdx = G4ProductionCuts::GetIndex(aSecondary->GetDefinition());
916   if(tPtclIdx < 0)
917   {
918     return;
919   }
920   G4ProductionCutsTable* tCutsTbl =
921       G4ProductionCutsTable::GetProductionCutsTable();
922   G4int tCoupleIdx = tCutsTbl->GetCoupleIndex(fpPreStepPoint
923       ->GetMaterialCutsCouple());
924   G4double tProdThreshold =
925       (*(tCutsTbl->GetEnergyCutsVector(tPtclIdx)))[tCoupleIdx];
926   if(aSecondary->GetKineticEnergy() < tProdThreshold)
927   {
928     tBelowCutEnergyAndSafety = true;
929     if(std::abs(aSecondary->GetDynamicParticle()->GetCharge()) > DBL_MIN)
930     {
931       G4double currentRange
932       = G4LossTableManager::Instance()->GetRange(aSecondary->GetDefinition(),
933           aSecondary->GetKineticEnergy(),
934           fpPreStepPoint->GetMaterialCutsCouple());
935       tBelowCutEnergyAndSafety = (currentRange < CalculateSafety() );
936     }
937   }
938 
939   if(tBelowCutEnergyAndSafety)
940   {
941     if(!(aSecondary->IsGoodForTracking()))
942     {
943       // Add kinetic energy to the total energy deposit
944       fpStep->AddTotalEnergyDeposit(aSecondary->GetKineticEnergy());
945       aSecondary->SetKineticEnergy(0.0);
946     }
947   }
948 }
949