Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/electromagnetic/dna/management/src/G4ITTransportation.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 ]

Diff markup

Differences between /processes/electromagnetic/dna/management/src/G4ITTransportation.cc (Version 11.3.0) and /processes/electromagnetic/dna/management/src/G4ITTransportation.cc (Version 10.4.p3)


  1 //                                                  1 //
  2 // *******************************************      2 // ********************************************************************
  3 // * License and Disclaimer                         3 // * License and Disclaimer                                           *
  4 // *                                                4 // *                                                                  *
  5 // * The  Geant4 software  is  copyright of th      5 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
  6 // * the Geant4 Collaboration.  It is provided      6 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
  7 // * conditions of the Geant4 Software License      7 // * conditions of the Geant4 Software License,  included in the file *
  8 // * LICENSE and available at  http://cern.ch/      8 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
  9 // * include a list of copyright holders.           9 // * include a list of copyright holders.                             *
 10 // *                                               10 // *                                                                  *
 11 // * Neither the authors of this software syst     11 // * Neither the authors of this software system, nor their employing *
 12 // * institutes,nor the agencies providing fin     12 // * institutes,nor the agencies providing financial support for this *
 13 // * work  make  any representation or  warran     13 // * work  make  any representation or  warranty, express or implied, *
 14 // * regarding  this  software system or assum     14 // * regarding  this  software system or assume any liability for its *
 15 // * use.  Please see the license in the file      15 // * use.  Please see the license in the file  LICENSE  and URL above *
 16 // * for the full disclaimer and the limitatio     16 // * for the full disclaimer and the limitation of liability.         *
 17 // *                                               17 // *                                                                  *
 18 // * This  code  implementation is the result      18 // * This  code  implementation is the result of  the  scientific and *
 19 // * technical work of the GEANT4 collaboratio     19 // * technical work of the GEANT4 collaboration.                      *
 20 // * By using,  copying,  modifying or  distri     20 // * By using,  copying,  modifying or  distributing the software (or *
 21 // * any work based  on the software)  you  ag     21 // * any work based  on the software)  you  agree  to acknowledge its *
 22 // * use  in  resulting  scientific  publicati     22 // * use  in  resulting  scientific  publications,  and indicate your *
 23 // * acceptance of all terms of the Geant4 Sof     23 // * acceptance of all terms of the Geant4 Software license.          *
 24 // *******************************************     24 // ********************************************************************
 25 //                                                 25 //
                                                   >>  26 // $Id$
 26 //                                                 27 //
 27 /// \brief This class is a slightly modified v     28 /// \brief This class is a slightly modified version of G4Transportation
 28 ///        initially written by John Apostolak     29 ///        initially written by John Apostolakis and colleagues
 29 ///        But it should use the exact same al     30 ///        But it should use the exact same algorithm
 30 //                                                 31 //
 31 // Contact : Mathieu Karamitros (kara (AT) cen     32 // Contact : Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr)
 32 //                                                 33 //
 33 // History :                                       34 // History :
 34 // -----------                                     35 // -----------
 35 // ===========================================     36 // =======================================================================
 36 // Modified:                                       37 // Modified:
 37 //   28 Oct  2011, P.Gumpl./J.Ap: Detect gravi     38 //   28 Oct  2011, P.Gumpl./J.Ap: Detect gravity field, use magnetic moment
 38 //   20 Nov  2008, J.Apostolakis: Push safety      39 //   20 Nov  2008, J.Apostolakis: Push safety to helper - after ComputeSafety
 39 //    9 Nov  2007, J.Apostolakis: Flag for sho     40 //    9 Nov  2007, J.Apostolakis: Flag for short steps, push safety to helper
 40 //   19 Jan  2006, P.MoraDeFreitas: Fix for su     41 //   19 Jan  2006, P.MoraDeFreitas: Fix for suspended tracks (StartTracking)
 41 //   11 Aug  2004, M.Asai: Add G4VSensitiveDet     42 //   11 Aug  2004, M.Asai: Add G4VSensitiveDetector* for updating stepPoint.
 42 //   21 June 2003, J.Apostolakis: Calling fiel     43 //   21 June 2003, J.Apostolakis: Calling field manager with
 43 //                     track, to enable it to      44 //                     track, to enable it to configure its accuracy
 44 //   13 May  2003, J.Apostolakis: Zero field a     45 //   13 May  2003, J.Apostolakis: Zero field areas now taken into
 45 //                     account correclty in al     46 //                     account correclty in all cases (thanks to W Pokorski).
 46 //   29 June 2001, J.Apostolakis, D.Cote-Ahern     47 //   29 June 2001, J.Apostolakis, D.Cote-Ahern, P.Gumplinger:
 47 //                     correction for spin tra     48 //                     correction for spin tracking
 48 //   20 Febr 2001, J.Apostolakis:  update for      49 //   20 Febr 2001, J.Apostolakis:  update for new FieldTrack
 49 //   22 Sept 2000, V.Grichine:     update of K     50 //   22 Sept 2000, V.Grichine:     update of Kinetic Energy
 50 //  ------------------------------------------     51 //  ---------------------------------------------------
 51 //   10 Oct  2011, M.Karamitros:   G4ITTranspo     52 //   10 Oct  2011, M.Karamitros:   G4ITTransportation created
 52 // Created:  19 March 1997, J. Apostolakis         53 // Created:  19 March 1997, J. Apostolakis
 53 // ===========================================     54 // =======================================================================
 54 //                                                 55 //
 55 // -------------------------------------------     56 // -------------------------------------------------------------------
 56                                                    57 
 57 #include "G4ITTransportation.hh"                   58 #include "G4ITTransportation.hh"
 58                                                << 
 59 #include "G4ChordFinder.hh"                    << 
 60 #include "G4FieldManager.hh"                   << 
 61 #include "G4FieldManagerStore.hh"              << 
 62 #include "G4IT.hh"                                 59 #include "G4IT.hh"
 63 #include "G4ITNavigator.hh"                    <<  60 #include "G4TrackingInformation.hh"
 64 #include "G4ITSafetyHelper.hh"                 <<  61 #include "G4SystemOfUnits.hh"
                                                   >>  62 #include "G4TransportationManager.hh"
 65 #include "G4ITTransportationManager.hh"            63 #include "G4ITTransportationManager.hh"
 66 #include "G4LowEnergyEmProcessSubType.hh"      << 
 67 #include "G4ParticleTable.hh"                  << 
 68 #include "G4ProductionCutsTable.hh"                64 #include "G4ProductionCutsTable.hh"
                                                   >>  65 #include "G4ParticleTable.hh"
                                                   >>  66 #include "G4ITNavigator.hh"
 69 #include "G4PropagatorInField.hh"                  67 #include "G4PropagatorInField.hh"
 70 #include "G4ReferenceCast.hh"                  <<  68 #include "G4FieldManager.hh"
 71 #include "G4SystemOfUnits.hh"                  <<  69 #include "G4ChordFinder.hh"
 72 #include "G4TrackingInformation.hh"            <<  70 #include "G4ITSafetyHelper.hh"
 73 #include "G4TransportationManager.hh"          <<  71 #include "G4FieldManagerStore.hh"
 74 #include "G4UnitsTable.hh"                     << 
 75                                                    72 
 76 #include <memory>                              <<  73 #include "G4UnitsTable.hh"
                                                   >>  74 #include "G4ReferenceCast.hh"
 77                                                    75 
 78 class G4VSensitiveDetector;                        76 class G4VSensitiveDetector;
 79                                                    77 
 80 #ifndef PrepareState                               78 #ifndef PrepareState
 81 #  define PrepareState()                       <<  79 #define PrepareState() G4ITTransportationState* __state = this->GetState<G4ITTransportationState>();
 82     G4ITTransportationState* __state = this->G << 
 83 #endif                                             80 #endif
 84                                                    81 
 85 #ifndef State                                      82 #ifndef State
 86 #define State(theXInfo) (__state->theXInfo)        83 #define State(theXInfo) (__state->theXInfo)
 87 #endif                                             84 #endif
 88                                                    85 
 89 //#define DEBUG_MEM                                86 //#define DEBUG_MEM
 90                                                    87 
 91 #ifdef DEBUG_MEM                                   88 #ifdef DEBUG_MEM
 92 #include "G4MemStat.hh"                            89 #include "G4MemStat.hh"
 93 using namespace G4MemStat;                         90 using namespace G4MemStat;
 94 using G4MemStat::MemStat;                          91 using G4MemStat::MemStat;
 95 #endif                                             92 #endif
 96                                                    93 
 97 //#define G4DEBUG_TRANSPORT 1                      94 //#define G4DEBUG_TRANSPORT 1
 98                                                    95 
 99 G4ITTransportation::G4ITTransportation(const G     96 G4ITTransportation::G4ITTransportation(const G4String& aName, int verbose) :
100     G4VITProcess(aName, fTransportation),          97     G4VITProcess(aName, fTransportation),
101     fThreshold_Warning_Energy(100 * MeV),          98     fThreshold_Warning_Energy(100 * MeV),
102     fThreshold_Important_Energy(250 * MeV),        99     fThreshold_Important_Energy(250 * MeV),
103                                                << 100     fThresholdTrials(10),
104     fUnimportant_Energy(1 * MeV),  // Old defa << 101     fUnimportant_Energy(1 * MeV), // Not used
                                                   >> 102     fSumEnergyKilled(0.0),
                                                   >> 103     fMaxEnergyKilled(0.0),
                                                   >> 104     fShortStepOptimisation(false), // Old default: true (=fast short steps)
105     fVerboseLevel(verbose)                        105     fVerboseLevel(verbose)
106 {                                                 106 {
107   pParticleChange = &fParticleChange;             107   pParticleChange = &fParticleChange;
108   G4TransportationManager* transportMgr;          108   G4TransportationManager* transportMgr;
109   transportMgr = G4TransportationManager::GetT    109   transportMgr = G4TransportationManager::GetTransportationManager();
110   G4ITTransportationManager* ITtransportMgr;      110   G4ITTransportationManager* ITtransportMgr;
111   ITtransportMgr = G4ITTransportationManager::    111   ITtransportMgr = G4ITTransportationManager::GetTransportationManager();
112   fLinearNavigator = ITtransportMgr->GetNaviga    112   fLinearNavigator = ITtransportMgr->GetNavigatorForTracking();
113   fFieldPropagator = transportMgr->GetPropagat    113   fFieldPropagator = transportMgr->GetPropagatorInField();
114   fpSafetyHelper = ITtransportMgr->GetSafetyHe    114   fpSafetyHelper = ITtransportMgr->GetSafetyHelper(); // New
115                                                   115 
116   // Cannot determine whether a field exists h    116   // Cannot determine whether a field exists here, as it would
117   //  depend on the relative order of creating    117   //  depend on the relative order of creating the detector's
118   //  field and this process. That order is no    118   //  field and this process. That order is not guaranted.
119   // Instead later the method DoesGlobalFieldE    119   // Instead later the method DoesGlobalFieldExist() is called
120                                                   120 
121   enableAtRestDoIt = false;                       121   enableAtRestDoIt = false;
122   enableAlongStepDoIt = true;                     122   enableAlongStepDoIt = true;
123   enablePostStepDoIt = true;                      123   enablePostStepDoIt = true;
124   SetProcessSubType(fLowEnergyTransportation); << 124   SetProcessSubType(60);
125   SetInstantiateProcessState(true);               125   SetInstantiateProcessState(true);
126   G4VITProcess::SetInstantiateProcessState(fal    126   G4VITProcess::SetInstantiateProcessState(false);
127   fInstantiateProcessState = true;                127   fInstantiateProcessState = true;
128                                                   128 
129   G4VITProcess::fpState = std::make_shared<G4I << 129   G4VITProcess::fpState.reset(new G4ITTransportationState());
130   /*                                              130   /*
131    if(fTransportationState == 0)                  131    if(fTransportationState == 0)
132    {                                              132    {
133    G4cout << "KILL in G4ITTransportation::G4IT    133    G4cout << "KILL in G4ITTransportation::G4ITTransportation" << G4endl;
134    abort();                                       134    abort();
135    }                                              135    }
136    */                                             136    */
137 }                                                 137 }
138                                                   138 
139 G4ITTransportation::G4ITTransportation(const G    139 G4ITTransportation::G4ITTransportation(const G4ITTransportation& right) :
140     G4VITProcess(right)                           140     G4VITProcess(right)
141 {                                                 141 {
142   // Copy attributes                              142   // Copy attributes
143   fVerboseLevel = right.fVerboseLevel;            143   fVerboseLevel = right.fVerboseLevel;
144   fThreshold_Warning_Energy = right.fThreshold    144   fThreshold_Warning_Energy = right.fThreshold_Warning_Energy;
145   fThreshold_Important_Energy = right.fThresho    145   fThreshold_Important_Energy = right.fThreshold_Important_Energy;
146   fThresholdTrials = right.fThresholdTrials;      146   fThresholdTrials = right.fThresholdTrials;
147   fUnimportant_Energy = right.fUnimportant_Ene    147   fUnimportant_Energy = right.fUnimportant_Energy;
148   fSumEnergyKilled = right.fSumEnergyKilled;      148   fSumEnergyKilled = right.fSumEnergyKilled;
149   fMaxEnergyKilled = right.fMaxEnergyKilled;      149   fMaxEnergyKilled = right.fMaxEnergyKilled;
150   fShortStepOptimisation = right.fShortStepOpt    150   fShortStepOptimisation = right.fShortStepOptimisation;
151                                                   151 
152   // Setup Navigators                             152   // Setup Navigators
153   G4TransportationManager* transportMgr;          153   G4TransportationManager* transportMgr;
154   transportMgr = G4TransportationManager::GetT    154   transportMgr = G4TransportationManager::GetTransportationManager();
155   G4ITTransportationManager* ITtransportMgr;      155   G4ITTransportationManager* ITtransportMgr;
156   ITtransportMgr = G4ITTransportationManager::    156   ITtransportMgr = G4ITTransportationManager::GetTransportationManager();
157   fLinearNavigator = ITtransportMgr->GetNaviga    157   fLinearNavigator = ITtransportMgr->GetNavigatorForTracking();
158   fFieldPropagator = transportMgr->GetPropagat    158   fFieldPropagator = transportMgr->GetPropagatorInField();
159   fpSafetyHelper = ITtransportMgr->GetSafetyHe    159   fpSafetyHelper = ITtransportMgr->GetSafetyHelper(); // New
160                                                   160 
161   // Cannot determine whether a field exists h    161   // Cannot determine whether a field exists here, as it would
162   //  depend on the relative order of creating    162   //  depend on the relative order of creating the detector's
163   //  field and this process. That order is no    163   //  field and this process. That order is not guaranted.
164   // Instead later the method DoesGlobalFieldE    164   // Instead later the method DoesGlobalFieldExist() is called
165                                                   165 
166   enableAtRestDoIt = false;                       166   enableAtRestDoIt = false;
167   enableAlongStepDoIt = true;                     167   enableAlongStepDoIt = true;
168   enablePostStepDoIt = true;                      168   enablePostStepDoIt = true;
169                                                   169 
170   pParticleChange = &fParticleChange;             170   pParticleChange = &fParticleChange;
171   SetInstantiateProcessState(true);               171   SetInstantiateProcessState(true);
172   G4VITProcess::SetInstantiateProcessState(fal    172   G4VITProcess::SetInstantiateProcessState(false);
173   fInstantiateProcessState = right.fInstantiat    173   fInstantiateProcessState = right.fInstantiateProcessState;
174 }                                                 174 }
175                                                   175 
176 G4ITTransportation& G4ITTransportation::operat    176 G4ITTransportation& G4ITTransportation::operator=(const G4ITTransportation& /*right*/)
177 {                                                 177 {
178 //  if (this == &right) return *this;             178 //  if (this == &right) return *this;
179   return *this;                                   179   return *this;
180 }                                                 180 }
181                                                   181 
182 //////////////////////////////////////////////    182 //////////////////////////////////////////////////////////////////////////////
183 /// Process State                                 183 /// Process State
184 //////////////////////////////////////////////    184 //////////////////////////////////////////////////////////////////////////////
185 G4ITTransportation::G4ITTransportationState::G    185 G4ITTransportation::G4ITTransportationState::G4ITTransportationState() :
186      fCurrentTouchableHandle(nullptr)          << 186     G4ProcessState(), fCurrentTouchableHandle(0)
187 {                                                 187 {
188   fTransportEndPosition = G4ThreeVector(0, 0,     188   fTransportEndPosition = G4ThreeVector(0, 0, 0);
189   fTransportEndMomentumDir = G4ThreeVector(0,     189   fTransportEndMomentumDir = G4ThreeVector(0, 0, 0);
190   fTransportEndKineticEnergy = -1;                190   fTransportEndKineticEnergy = -1;
191   fTransportEndSpin = G4ThreeVector(0, 0, 0);     191   fTransportEndSpin = G4ThreeVector(0, 0, 0);
192   fMomentumChanged = false;                       192   fMomentumChanged = false;
193   fEnergyChanged = false;                         193   fEnergyChanged = false;
194   fEndGlobalTimeComputed = false;                 194   fEndGlobalTimeComputed = false;
195   fCandidateEndGlobalTime = -1;                   195   fCandidateEndGlobalTime = -1;
196   fParticleIsLooping = false;                     196   fParticleIsLooping = false;
197                                                   197 
198   static G4ThreadLocal G4TouchableHandle *null << 198   static G4ThreadLocal G4TouchableHandle *nullTouchableHandle = 0;
199   if (nullTouchableHandle == nullptr) nullTouc << 199   if (!nullTouchableHandle) nullTouchableHandle = new G4TouchableHandle;
200   // Points to (G4VTouchable*) 0                  200   // Points to (G4VTouchable*) 0
201                                                   201 
202   fCurrentTouchableHandle = *nullTouchableHand    202   fCurrentTouchableHandle = *nullTouchableHandle;
203   fGeometryLimitedStep = false;                   203   fGeometryLimitedStep = false;
204   fPreviousSftOrigin = G4ThreeVector(0, 0, 0);    204   fPreviousSftOrigin = G4ThreeVector(0, 0, 0);
205   fPreviousSafety = 0.0;                          205   fPreviousSafety = 0.0;
206   fNoLooperTrials = 0;                         << 206   fNoLooperTrials = false;
207   fEndPointDistance = -1;                         207   fEndPointDistance = -1;
208 }                                                 208 }
209                                                   209 
210 G4ITTransportation::G4ITTransportationState::~    210 G4ITTransportation::G4ITTransportationState::~G4ITTransportationState()
211 {                                                 211 {
212   ;                                               212   ;
213 }                                                 213 }
214                                                   214 
215 G4ITTransportation::~G4ITTransportation()         215 G4ITTransportation::~G4ITTransportation()
216 {                                                 216 {
217 #ifdef G4VERBOSE                                  217 #ifdef G4VERBOSE
218   if ((fVerboseLevel > 0) && (fSumEnergyKilled    218   if ((fVerboseLevel > 0) && (fSumEnergyKilled > 0.0))
219   {                                               219   {
220     G4cout << " G4ITTransportation: Statistics    220     G4cout << " G4ITTransportation: Statistics for looping particles "
221            << G4endl;                             221            << G4endl;
222     G4cout << "   Sum of energy of loopers kil    222     G4cout << "   Sum of energy of loopers killed: "
223            << fSumEnergyKilled << G4endl;         223            << fSumEnergyKilled << G4endl;
224     G4cout << "   Max energy of loopers killed    224     G4cout << "   Max energy of loopers killed: "
225            << fMaxEnergyKilled << G4endl;         225            << fMaxEnergyKilled << G4endl;
226   }                                               226   }
227 #endif                                            227 #endif
228 }                                                 228 }
229                                                   229 
230 void G4ITTransportation::BuildPhysicsTable(con    230 void G4ITTransportation::BuildPhysicsTable(const G4ParticleDefinition&)
231 {                                                 231 {
232   fpSafetyHelper->InitialiseHelper();             232   fpSafetyHelper->InitialiseHelper();
233 }                                                 233 }
234                                                   234 
235 G4bool G4ITTransportation::DoesGlobalFieldExis    235 G4bool G4ITTransportation::DoesGlobalFieldExist()
236 {                                                 236 {
237   G4TransportationManager* transportMgr;          237   G4TransportationManager* transportMgr;
238   transportMgr = G4TransportationManager::GetT    238   transportMgr = G4TransportationManager::GetTransportationManager();
239                                                   239 
240   // fFieldExists= transportMgr->GetFieldManag    240   // fFieldExists= transportMgr->GetFieldManager()->DoesFieldExist();
241   // return fFieldExists;                         241   // return fFieldExists;
242   return transportMgr->GetFieldManager()->Does    242   return transportMgr->GetFieldManager()->DoesFieldExist();
243 }                                                 243 }
244                                                   244 
245 //////////////////////////////////////////////    245 //////////////////////////////////////////////////////////////////////////
246 //                                                246 //
247 // Responsibilities:                              247 // Responsibilities:
248 //    Find whether the geometry limits the Ste    248 //    Find whether the geometry limits the Step, and to what length
249 //    Calculate the new value of the safety an    249 //    Calculate the new value of the safety and return it.
250 //    Store the final time, position and momen    250 //    Store the final time, position and momentum.
251 G4double                                          251 G4double
252 G4ITTransportation::                              252 G4ITTransportation::
253 AlongStepGetPhysicalInteractionLength(const G4    253 AlongStepGetPhysicalInteractionLength(const G4Track& track,
254                                       G4double    254                                       G4double,
255                                       G4double    255                                       G4double currentMinimumStep,
256                                       G4double    256                                       G4double& currentSafety,
257                                       G4GPILSe    257                                       G4GPILSelection* selection)
258 {                                                 258 {
259   PrepareState();                              << 259   PrepareState()
260   G4double geometryStepLength(-1.0), newSafety    260   G4double geometryStepLength(-1.0), newSafety(-1.0);
261                                                   261 
262   State(fParticleIsLooping) = false;              262   State(fParticleIsLooping) = false;
263   State(fEndGlobalTimeComputed) = false;          263   State(fEndGlobalTimeComputed) = false;
264   State(fGeometryLimitedStep) = false;            264   State(fGeometryLimitedStep) = false;
265                                                   265 
266   // Initial actions moved to  StartTrack()       266   // Initial actions moved to  StartTrack()
267   // --------------------------------------       267   // --------------------------------------
268   // Note: in case another process changes tou    268   // Note: in case another process changes touchable handle
269   //    it will be necessary to add here (for     269   //    it will be necessary to add here (for all steps)
270   // State(fCurrentTouchableHandle) = track.Ge    270   // State(fCurrentTouchableHandle) = track.GetTouchableHandle();
271                                                   271 
272   // GPILSelection is set to defaule value of     272   // GPILSelection is set to defaule value of CandidateForSelection
273   // It is a return value                         273   // It is a return value
274   //                                              274   //
275   *selection = CandidateForSelection;             275   *selection = CandidateForSelection;
276                                                   276 
277   // Get initial Energy/Momentum of the track     277   // Get initial Energy/Momentum of the track
278   //                                              278   //
279   const G4DynamicParticle* pParticle = track.G    279   const G4DynamicParticle* pParticle = track.GetDynamicParticle();
280 //    const G4ParticleDefinition* pParticleDef    280 //    const G4ParticleDefinition* pParticleDef   = pParticle->GetDefinition() ;
281   G4ThreeVector startMomentumDir = pParticle->    281   G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection();
282   G4ThreeVector startPosition = track.GetPosit    282   G4ThreeVector startPosition = track.GetPosition();
283                                                   283 
284   // G4double   theTime        = track.GetGlob    284   // G4double   theTime        = track.GetGlobalTime() ;
285                                                   285 
286   // The Step Point safety can be limited by o    286   // The Step Point safety can be limited by other geometries and/or the
287   // assumptions of any process - it's not alw    287   // assumptions of any process - it's not always the geometrical safety.
288   // We calculate the starting point's isotrop    288   // We calculate the starting point's isotropic safety here.
289   //                                              289   //
290   G4ThreeVector OriginShift = startPosition -     290   G4ThreeVector OriginShift = startPosition - State(fPreviousSftOrigin);
291   G4double MagSqShift = OriginShift.mag2();       291   G4double MagSqShift = OriginShift.mag2();
292   if (MagSqShift >= sqr(State(fPreviousSafety)    292   if (MagSqShift >= sqr(State(fPreviousSafety)))
293   {                                               293   {
294     currentSafety = 0.0;                          294     currentSafety = 0.0;
295   }                                               295   }
296   else                                            296   else
297   {                                               297   {
298     currentSafety = State(fPreviousSafety) - s    298     currentSafety = State(fPreviousSafety) - std::sqrt(MagSqShift);
299   }                                               299   }
300                                                   300 
301   // Is the particle charged ?                    301   // Is the particle charged ?
302   //                                              302   //
303   G4double particleCharge = pParticle->GetChar    303   G4double particleCharge = pParticle->GetCharge();
304                                                   304 
305   // There is no need to locate the current vo    305   // There is no need to locate the current volume. It is Done elsewhere:
306   //   On track construction                      306   //   On track construction
307   //   By the tracking, after all AlongStepDoI    307   //   By the tracking, after all AlongStepDoIts, in "Relocation"
308                                                   308 
309   // Check whether the particle have an (EM) f    309   // Check whether the particle have an (EM) field force exerting upon it
310   //                                              310   //
311   G4FieldManager* fieldMgr = nullptr;          << 311   G4FieldManager* fieldMgr = 0;
312   G4bool fieldExertsForce = false;                312   G4bool fieldExertsForce = false;
313   if ((particleCharge != 0.0))                    313   if ((particleCharge != 0.0))
314   {                                               314   {
315     fieldMgr = fFieldPropagator->FindAndSetFie    315     fieldMgr = fFieldPropagator->FindAndSetFieldManager(track.GetVolume());
316     if (fieldMgr != nullptr)                   << 316     if (fieldMgr != 0)
317     {                                             317     {
318       // Message the field Manager, to configu    318       // Message the field Manager, to configure it for this track
319       fieldMgr->ConfigureForTrack(&track);        319       fieldMgr->ConfigureForTrack(&track);
320       // Moved here, in order to allow a trans    320       // Moved here, in order to allow a transition
321       //   from a zero-field  status (with fie    321       //   from a zero-field  status (with fieldMgr->(field)0
322       //   to a finite field  status              322       //   to a finite field  status
323                                                   323 
324       // If the field manager has no field, th    324       // If the field manager has no field, there is no field !
325       fieldExertsForce = (fieldMgr->GetDetecto << 325       fieldExertsForce = (fieldMgr->GetDetectorField() != 0);
326     }                                             326     }
327   }                                               327   }
328                                                   328 
329   // G4cout << " G4Transport:  field exerts fo    329   // G4cout << " G4Transport:  field exerts force= " << fieldExertsForce
330   //   << "  fieldMgr= " << fieldMgr << G4endl    330   //   << "  fieldMgr= " << fieldMgr << G4endl;
331                                                   331 
332   // Choose the calculation of the transportat    332   // Choose the calculation of the transportation: Field or not
333   //                                              333   //
334   if (!fieldExertsForce)                          334   if (!fieldExertsForce)
335   {                                               335   {
336     G4double linearStepLength;                    336     G4double linearStepLength;
337     if (fShortStepOptimisation && (currentMini    337     if (fShortStepOptimisation && (currentMinimumStep <= currentSafety))
338     {                                             338     {
339       // The Step is guaranteed to be taken       339       // The Step is guaranteed to be taken
340       //                                          340       //
341       geometryStepLength = currentMinimumStep;    341       geometryStepLength = currentMinimumStep;
342       State(fGeometryLimitedStep) = false;        342       State(fGeometryLimitedStep) = false;
343     }                                             343     }
344     else                                          344     else
345     {                                             345     {
346       //  Find whether the straight path inter    346       //  Find whether the straight path intersects a volume
347       //                                          347       //
348       // fLinearNavigator->SetNavigatorState(G    348       // fLinearNavigator->SetNavigatorState(GetIT(track)->GetTrackingInfo()->GetNavigatorState());
349       linearStepLength = fLinearNavigator->Com    349       linearStepLength = fLinearNavigator->ComputeStep(startPosition,
350                                                   350                                                        startMomentumDir,
351                                                   351                                                        currentMinimumStep,
352                                                   352                                                        newSafety);
353                                                   353 
354 //      G4cout << "linearStepLength : " <<  G4    354 //      G4cout << "linearStepLength : " <<  G4BestUnit(linearStepLength,"Length")
355 //          << " | currentMinimumStep: " << cu    355 //          << " | currentMinimumStep: " << currentMinimumStep
356 //          << " | trackID: " << track.GetTrac    356 //          << " | trackID: " << track.GetTrackID() << G4endl;
357                                                   357 
358       // Remember last safety origin & value.     358       // Remember last safety origin & value.
359       //                                          359       //
360       State(fPreviousSftOrigin) = startPositio    360       State(fPreviousSftOrigin) = startPosition;
361       State(fPreviousSafety) = newSafety;         361       State(fPreviousSafety) = newSafety;
362                                                   362       
363       G4TrackStateManager& trackStateMan = Get    363       G4TrackStateManager& trackStateMan = GetIT(track)->GetTrackingInfo()
364           ->GetTrackStateManager();               364           ->GetTrackStateManager();
365       fpSafetyHelper->LoadTrackState(trackStat    365       fpSafetyHelper->LoadTrackState(trackStateMan);
366       // fpSafetyHelper->SetTrackState(state);    366       // fpSafetyHelper->SetTrackState(state);
367       fpSafetyHelper->SetCurrentSafety(newSafe    367       fpSafetyHelper->SetCurrentSafety(newSafety,
368                                        State(f    368                                        State(fTransportEndPosition));
369       fpSafetyHelper->ResetTrackState();          369       fpSafetyHelper->ResetTrackState();
370                                                   370       
371       // The safety at the initial point has b    371       // The safety at the initial point has been re-calculated:
372       //                                          372       //
373       currentSafety = newSafety;                  373       currentSafety = newSafety;
374                                                   374 
375       State(fGeometryLimitedStep) = (linearSte    375       State(fGeometryLimitedStep) = (linearStepLength <= currentMinimumStep);
376       if (State(fGeometryLimitedStep))            376       if (State(fGeometryLimitedStep))
377       {                                           377       {
378         // The geometry limits the Step size (    378         // The geometry limits the Step size (an intersection was found.)
379         geometryStepLength = linearStepLength;    379         geometryStepLength = linearStepLength;
380       }                                           380       }
381       else                                        381       else
382       {                                           382       {
383         // The full Step is taken.                383         // The full Step is taken.
384         geometryStepLength = currentMinimumSte    384         geometryStepLength = currentMinimumStep;
385       }                                           385       }
386     }                                             386     }
387     State(fEndPointDistance) = geometryStepLen    387     State(fEndPointDistance) = geometryStepLength;
388                                                   388 
389     // Calculate final position                   389     // Calculate final position
390     //                                            390     //
391     State(fTransportEndPosition) = startPositi    391     State(fTransportEndPosition) = startPosition
392         + geometryStepLength * startMomentumDi    392         + geometryStepLength * startMomentumDir;
393                                                   393 
394     // Momentum direction, energy and polarisa    394     // Momentum direction, energy and polarisation are unchanged by transport
395     //                                            395     //
396     State(fTransportEndMomentumDir) = startMom    396     State(fTransportEndMomentumDir) = startMomentumDir;
397     State(fTransportEndKineticEnergy) = track.    397     State(fTransportEndKineticEnergy) = track.GetKineticEnergy();
398     State(fTransportEndSpin) = track.GetPolari    398     State(fTransportEndSpin) = track.GetPolarization();
399     State(fParticleIsLooping) = false;            399     State(fParticleIsLooping) = false;
400     State(fMomentumChanged) = false;              400     State(fMomentumChanged) = false;
401     State(fEndGlobalTimeComputed) = true;         401     State(fEndGlobalTimeComputed) = true;
402     State(theInteractionTimeLeft) = State(fEnd    402     State(theInteractionTimeLeft) = State(fEndPointDistance)
403         / track.GetVelocity();                    403         / track.GetVelocity();
404     State(fCandidateEndGlobalTime) = State(the    404     State(fCandidateEndGlobalTime) = State(theInteractionTimeLeft)
405         + track.GetGlobalTime();                  405         + track.GetGlobalTime();
406 /*                                                406 /*
407     G4cout << "track.GetVelocity() : "            407     G4cout << "track.GetVelocity() : "
408            << track.GetVelocity() << G4endl;      408            << track.GetVelocity() << G4endl;
409     G4cout << "State(endpointDistance) : "        409     G4cout << "State(endpointDistance) : "
410            << G4BestUnit(State(endpointDistanc    410            << G4BestUnit(State(endpointDistance),"Length") << G4endl;
411     G4cout << "State(theInteractionTimeLeft) :    411     G4cout << "State(theInteractionTimeLeft) : "
412            << G4BestUnit(State(theInteractionT    412            << G4BestUnit(State(theInteractionTimeLeft),"Time") << G4endl;
413     G4cout << "track.GetGlobalTime() : "          413     G4cout << "track.GetGlobalTime() : "
414            << G4BestUnit(track.GetGlobalTime()    414            << G4BestUnit(track.GetGlobalTime(),"Time") << G4endl;
415 */                                                415 */
416   }                                               416   }
417   else //  A field exerts force                   417   else //  A field exerts force
418   {                                               418   {
419                                                   419 
420     G4ExceptionDescription exceptionDescriptio    420     G4ExceptionDescription exceptionDescription;
421     exceptionDescription                          421     exceptionDescription
422         << "ITTransportation does not support     422         << "ITTransportation does not support external fields.";
423     exceptionDescription                          423     exceptionDescription
424         << " If you are dealing with a tradiat    424         << " If you are dealing with a tradiational MC simulation, ";
425     exceptionDescription << "please use G4Tran    425     exceptionDescription << "please use G4Transportation.";
426                                                   426 
427     G4Exception("G4ITTransportation::AlongStep    427     G4Exception("G4ITTransportation::AlongStepGetPhysicalInteractionLength",
428                 "NoExternalFieldSupport", Fata    428                 "NoExternalFieldSupport", FatalException, exceptionDescription);
429     /*                                            429     /*
430      G4double       momentumMagnitude = pParti    430      G4double       momentumMagnitude = pParticle->GetTotalMomentum() ;
431      //        G4ThreeVector  EndUnitMomentum     431      //        G4ThreeVector  EndUnitMomentum ;
432      G4double       lengthAlongCurve ;            432      G4double       lengthAlongCurve ;
433      G4double       restMass = pParticleDef->G    433      G4double       restMass = pParticleDef->GetPDGMass() ;
434                                                   434 
435      fFieldPropagator->SetChargeMomentumMass(     435      fFieldPropagator->SetChargeMomentumMass( particleCharge,    // in e+ units
436      momentumMagnitude, // in Mev/c               436      momentumMagnitude, // in Mev/c
437      restMass           ) ;                       437      restMass           ) ;
438                                                   438 
439      G4ThreeVector spin        = track.GetPola    439      G4ThreeVector spin        = track.GetPolarization() ;
440      G4FieldTrack  aFieldTrack = G4FieldTrack(    440      G4FieldTrack  aFieldTrack = G4FieldTrack( startPosition,
441      track.GetMomentumDirection(),                441      track.GetMomentumDirection(),
442      0.0,                                         442      0.0,
443      track.GetKineticEnergy(),                    443      track.GetKineticEnergy(),
444      restMass,                                    444      restMass,
445      track.GetVelocity(),                         445      track.GetVelocity(),
446      track.GetGlobalTime(), // Lab.               446      track.GetGlobalTime(), // Lab.
447      track.GetProperTime(), // Part.              447      track.GetProperTime(), // Part.
448      &spin                  ) ;                   448      &spin                  ) ;
449      if( currentMinimumStep > 0 )                 449      if( currentMinimumStep > 0 )
450      {                                            450      {
451      // Do the Transport in the field (non rec    451      // Do the Transport in the field (non recti-linear)
452      //                                           452      //
453      lengthAlongCurve = fFieldPropagator->Comp    453      lengthAlongCurve = fFieldPropagator->ComputeStep( aFieldTrack,
454      currentMinimumStep,                          454      currentMinimumStep,
455      currentSafety,                               455      currentSafety,
456      track.GetVolume() ) ;                        456      track.GetVolume() ) ;
457      State(fGeometryLimitedStep)= lengthAlongC    457      State(fGeometryLimitedStep)= lengthAlongCurve < currentMinimumStep;
458      if( State(fGeometryLimitedStep) )            458      if( State(fGeometryLimitedStep) )
459      {                                            459      {
460      geometryStepLength   = lengthAlongCurve ;    460      geometryStepLength   = lengthAlongCurve ;
461      }                                            461      }
462      else                                         462      else
463      {                                            463      {
464      geometryStepLength   = currentMinimumStep    464      geometryStepLength   = currentMinimumStep ;
465      }                                            465      }
466                                                   466 
467      // Remember last safety origin & value.      467      // Remember last safety origin & value.
468      //                                           468      //
469      State(fPreviousSftOrigin) = startPosition    469      State(fPreviousSftOrigin) = startPosition ;
470      State(fPreviousSafety)    = currentSafety    470      State(fPreviousSafety)    = currentSafety ;
471      fpSafetyHelper->SetCurrentSafety( newSafe    471      fpSafetyHelper->SetCurrentSafety( newSafety, startPosition);
472      }                                            472      }
473      else                                         473      else
474      {                                            474      {
475      geometryStepLength   = lengthAlongCurve=     475      geometryStepLength   = lengthAlongCurve= 0.0 ;
476      State(fGeometryLimitedStep) = false ;        476      State(fGeometryLimitedStep) = false ;
477      }                                            477      }
478                                                   478 
479      // Get the End-Position and End-Momentum     479      // Get the End-Position and End-Momentum (Dir-ection)
480      //                                           480      //
481      State(fTransportEndPosition) = aFieldTrac    481      State(fTransportEndPosition) = aFieldTrack.GetPosition() ;
482                                                   482 
483      // Momentum:  Magnitude and direction can    483      // Momentum:  Magnitude and direction can be changed too now ...
484      //                                           484      //
485      State(fMomentumChanged)         = true ;     485      State(fMomentumChanged)         = true ;
486      State(fTransportEndMomentumDir) = aFieldT    486      State(fTransportEndMomentumDir) = aFieldTrack.GetMomentumDir() ;
487                                                   487 
488      State(fTransportEndKineticEnergy)  = aFie    488      State(fTransportEndKineticEnergy)  = aFieldTrack.GetKineticEnergy() ;
489                                                   489 
490      if( fFieldPropagator->GetCurrentFieldMana    490      if( fFieldPropagator->GetCurrentFieldManager()->DoesFieldChangeEnergy() )
491      {                                            491      {
492      // If the field can change energy, then t    492      // If the field can change energy, then the time must be integrated
493      //    - so this should have been updated     493      //    - so this should have been updated
494      //                                           494      //
495      State(fCandidateEndGlobalTime)   = aField    495      State(fCandidateEndGlobalTime)   = aFieldTrack.GetLabTimeOfFlight();
496      State(fEndGlobalTimeComputed)    = true;     496      State(fEndGlobalTimeComputed)    = true;
497                                                   497 
498      State(theInteractionTimeLeft) = State(fCa    498      State(theInteractionTimeLeft) = State(fCandidateEndGlobalTime) -
499                                          track    499                                          track.GetGlobalTime() ;
500                                                   500 
501      // was ( State(fCandidateEndGlobalTime) !    501      // was ( State(fCandidateEndGlobalTime) != track.GetGlobalTime() );
502      // a cleaner way is to have FieldTrack kn    502      // a cleaner way is to have FieldTrack knowing whether time is updated.
503      }                                            503      }
504      else                                         504      else
505      {                                            505      {
506      // The energy should be unchanged by fiel    506      // The energy should be unchanged by field transport,
507      //    - so the time changed will be calcu    507      //    - so the time changed will be calculated elsewhere
508      //                                           508      //
509      State(fEndGlobalTimeComputed) = false;       509      State(fEndGlobalTimeComputed) = false;
510                                                   510 
511      // Check that the integration preserved t    511      // Check that the integration preserved the energy
512      //     -  and if not correct this!           512      //     -  and if not correct this!
513      G4double  startEnergy= track.GetKineticEn    513      G4double  startEnergy= track.GetKineticEnergy();
514      G4double  endEnergy= State(fTransportEndK    514      G4double  endEnergy= State(fTransportEndKineticEnergy);
515                                                   515 
516      static G4int no_inexact_steps=0, no_large    516      static G4int no_inexact_steps=0, no_large_ediff;
517      G4double absEdiff = std::fabs(startEnergy    517      G4double absEdiff = std::fabs(startEnergy- endEnergy);
518      if( absEdiff > perMillion * endEnergy )      518      if( absEdiff > perMillion * endEnergy )
519      {                                            519      {
520      no_inexact_steps++;                          520      no_inexact_steps++;
521      // Possible statistics keeping here ...      521      // Possible statistics keeping here ...
522      }                                            522      }
523      #ifdef G4VERBOSE                             523      #ifdef G4VERBOSE
524      if( fVerboseLevel > 1 )                      524      if( fVerboseLevel > 1 )
525      {                                            525      {
526      if( std::fabs(startEnergy- endEnergy) > p    526      if( std::fabs(startEnergy- endEnergy) > perThousand * endEnergy )
527      {                                            527      {
528      static G4int no_warnings= 0, warnModulo=1    528      static G4int no_warnings= 0, warnModulo=1,  moduloFactor= 10;
529      no_large_ediff ++;                           529      no_large_ediff ++;
530      if( (no_large_ediff% warnModulo) == 0 )      530      if( (no_large_ediff% warnModulo) == 0 )
531      {                                            531      {
532      no_warnings++;                               532      no_warnings++;
533      G4cout << "WARNING - G4Transportation::Al    533      G4cout << "WARNING - G4Transportation::AlongStepGetPIL() "
534      << "   Energy change in Step is above 1^-    534      << "   Energy change in Step is above 1^-3 relative value. " << G4endl
535      << "   Relative change in 'tracking' step    535      << "   Relative change in 'tracking' step = "
536      << std::setw(15) << (endEnergy-startEnerg    536      << std::setw(15) << (endEnergy-startEnergy)/startEnergy << G4endl
537      << "     Starting E= " << std::setw(12) <    537      << "     Starting E= " << std::setw(12) << startEnergy / MeV << " MeV "
538      << G4endl                                    538      << G4endl
539      << "     Ending   E= " << std::setw(12) <    539      << "     Ending   E= " << std::setw(12) << endEnergy   / MeV << " MeV "
540      << G4endl;                                   540      << G4endl;
541      G4cout << " Energy has been corrected --     541      G4cout << " Energy has been corrected -- however, review"
542      << " field propagation parameters for acc    542      << " field propagation parameters for accuracy."  << G4endl;
543      if( (fVerboseLevel > 2 ) || (no_warnings<    543      if( (fVerboseLevel > 2 ) || (no_warnings<4) ||
544          (no_large_ediff == warnModulo * modul    544          (no_large_ediff == warnModulo * moduloFactor) )
545      {                                            545      {
546      G4cout << " These include EpsilonStepMax(    546      G4cout << " These include EpsilonStepMax(/Min) in G4FieldManager "
547      << " which determine fractional error per    547      << " which determine fractional error per step for integrated quantities. "
548      << G4endl                                    548      << G4endl
549      << " Note also the influence of the permi    549      << " Note also the influence of the permitted number of integration steps."
550      << G4endl;                                   550      << G4endl;
551      }                                            551      }
552      G4cerr << "ERROR - G4Transportation::Alon    552      G4cerr << "ERROR - G4Transportation::AlongStepGetPIL()" << G4endl
553      << "        Bad 'endpoint'. Energy change    553      << "        Bad 'endpoint'. Energy change detected"
554      << " and corrected. "                        554      << " and corrected. "
555      << " Has occurred already "                  555      << " Has occurred already "
556      << no_large_ediff << " times." << G4endl;    556      << no_large_ediff << " times." << G4endl;
557      if( no_large_ediff == warnModulo * modulo    557      if( no_large_ediff == warnModulo * moduloFactor )
558      {                                            558      {
559      warnModulo *= moduloFactor;                  559      warnModulo *= moduloFactor;
560      }                                            560      }
561      }                                            561      }
562      }                                            562      }
563      }  // end of if (fVerboseLevel)              563      }  // end of if (fVerboseLevel)
564      #endif                                       564      #endif
565      // Correct the energy for fields that con    565      // Correct the energy for fields that conserve it
566      //  This - hides the integration error       566      //  This - hides the integration error
567      //       - but gives a better physical an    567      //       - but gives a better physical answer
568      State(fTransportEndKineticEnergy)= track.    568      State(fTransportEndKineticEnergy)= track.GetKineticEnergy();
569      }                                            569      }
570                                                   570 
571      State(fTransportEndSpin) = aFieldTrack.Ge    571      State(fTransportEndSpin) = aFieldTrack.GetSpin();
572      State(fParticleIsLooping) = fFieldPropaga    572      State(fParticleIsLooping) = fFieldPropagator->IsParticleLooping() ;
573      State(endpointDistance)   = (State(fTrans    573      State(endpointDistance)   = (State(fTransportEndPosition) -
574                                   startPositio    574                                   startPosition).mag() ;
575      // State(theInteractionTimeLeft) =           575      // State(theInteractionTimeLeft) =
576                        track.GetVelocity()/Sta    576                        track.GetVelocity()/State(endpointDistance) ;
577      */                                           577      */
578   }                                               578   }
579                                                   579 
580   // If we are asked to go a step length of 0,    580   // If we are asked to go a step length of 0, and we are on a boundary
581   // then a boundary will also limit the step     581   // then a boundary will also limit the step -> we must flag this.
582   //                                              582   //
583   if (currentMinimumStep == 0.0)                  583   if (currentMinimumStep == 0.0)
584   {                                               584   {
585     if (currentSafety == 0.0)                     585     if (currentSafety == 0.0)
586     {                                             586     {
587       State(fGeometryLimitedStep) = true;         587       State(fGeometryLimitedStep) = true;
588 //            G4cout << "!!!! Safety is NULL,     588 //            G4cout << "!!!! Safety is NULL, on the Boundary !!!!!" << G4endl;
589 //            G4cout << " Track position : " <    589 //            G4cout << " Track position : " << track.GetPosition() /nanometer
590 //                   << G4endl;                   590 //                   << G4endl;
591     }                                             591     }
592   }                                               592   }
593                                                   593 
594   // Update the safety starting from the end-p    594   // Update the safety starting from the end-point,
595   // if it will become negative at the end-poi    595   // if it will become negative at the end-point.
596   //                                              596   //
597   if (currentSafety < State(fEndPointDistance)    597   if (currentSafety < State(fEndPointDistance))
598   {                                               598   {
599     // if( particleCharge == 0.0 )                599     // if( particleCharge == 0.0 )
600     //    G4cout  << "  Avoiding call to Compu    600     //    G4cout  << "  Avoiding call to ComputeSafety : charge = 0.0 " << G4endl;
601                                                   601 
602     if (particleCharge != 0.0)                    602     if (particleCharge != 0.0)
603     {                                             603     {
604                                                   604 
605       G4double endSafety = fLinearNavigator->C    605       G4double endSafety = fLinearNavigator->ComputeSafety(
606           State(fTransportEndPosition));          606           State(fTransportEndPosition));
607       currentSafety = endSafety;                  607       currentSafety = endSafety;
608       State(fPreviousSftOrigin) = State(fTrans    608       State(fPreviousSftOrigin) = State(fTransportEndPosition);
609       State(fPreviousSafety) = currentSafety;     609       State(fPreviousSafety) = currentSafety;
610                                                   610       
611       /*                                          611       /*
612        G4VTrackStateHandle state =                612        G4VTrackStateHandle state =
613        GetIT(track)->GetTrackingInfo()->GetTra    613        GetIT(track)->GetTrackingInfo()->GetTrackState(fpSafetyHelper);
614        */                                         614        */
615       G4TrackStateManager& trackStateMan = Get    615       G4TrackStateManager& trackStateMan = GetIT(track)->GetTrackingInfo()
616           ->GetTrackStateManager();               616           ->GetTrackStateManager();
617       fpSafetyHelper->LoadTrackState(trackStat    617       fpSafetyHelper->LoadTrackState(trackStateMan);
618       // fpSafetyHelper->SetTrackState(state);    618       // fpSafetyHelper->SetTrackState(state);
619       fpSafetyHelper->SetCurrentSafety(current    619       fpSafetyHelper->SetCurrentSafety(currentSafety,
620                                        State(f    620                                        State(fTransportEndPosition));
621       fpSafetyHelper->ResetTrackState();          621       fpSafetyHelper->ResetTrackState();
622                                                   622 
623       // Because the Stepping Manager assumes     623       // Because the Stepping Manager assumes it is from the start point,
624       //  add the StepLength                      624       //  add the StepLength
625       //                                          625       //
626       currentSafety += State(fEndPointDistance    626       currentSafety += State(fEndPointDistance);
627                                                   627 
628 #ifdef G4DEBUG_TRANSPORT                          628 #ifdef G4DEBUG_TRANSPORT
629       G4cout.precision(12);                       629       G4cout.precision(12);
630       G4cout << "***G4Transportation::AlongSte    630       G4cout << "***G4Transportation::AlongStepGPIL ** " << G4endl;
631       G4cout << "  Called Navigator->ComputeSa    631       G4cout << "  Called Navigator->ComputeSafety at "
632           << State(fTransportEndPosition)         632           << State(fTransportEndPosition)
633           << "    and it returned safety= " <<    633           << "    and it returned safety= " << endSafety << G4endl;
634       G4cout << "  Adding endpoint distance "     634       G4cout << "  Adding endpoint distance " << State(fEndPointDistance)
635              << "   to obtain pseudo-safety= "    635              << "   to obtain pseudo-safety= " << currentSafety << G4endl;
636 #endif                                            636 #endif
637     }                                             637     }
638   }                                               638   }
639                                                   639 
640   // fParticleChange.ProposeTrueStepLength(geo    640   // fParticleChange.ProposeTrueStepLength(geometryStepLength) ;
641                                                   641 
642 //  G4cout << "G4ITTransportation::AlongStepGe    642 //  G4cout << "G4ITTransportation::AlongStepGetPhysicalInteractionLength = "
643 //         << G4BestUnit(geometryStepLength,"L    643 //         << G4BestUnit(geometryStepLength,"Length") << G4endl;
644                                                   644 
645   return geometryStepLength;                      645   return geometryStepLength;
646 }                                                 646 }
647                                                   647 
648 void G4ITTransportation::ComputeStep(const G4T    648 void G4ITTransportation::ComputeStep(const G4Track& track,
649                                      const G4S    649                                      const G4Step& /*step*/,
650                                      const dou    650                                      const double timeStep,
651                                      double& o    651                                      double& oPhysicalStep)
652 {                                                 652 {
653   PrepareState();                              << 653   PrepareState()
654   const G4DynamicParticle* pParticle = track.G    654   const G4DynamicParticle* pParticle = track.GetDynamicParticle();
655   G4ThreeVector startMomentumDir = pParticle->    655   G4ThreeVector startMomentumDir = pParticle->GetMomentumDirection();
656   G4ThreeVector startPosition = track.GetPosit    656   G4ThreeVector startPosition = track.GetPosition();
657                                                   657 
658   track.CalculateVelocity();                      658   track.CalculateVelocity();
659   G4double initialVelocity = track.GetVelocity    659   G4double initialVelocity = track.GetVelocity();
660                                                   660 
661   State(fGeometryLimitedStep) = false;            661   State(fGeometryLimitedStep) = false;
662                                                   662 
663   /////////////////////////                       663   /////////////////////////
664   // !!! CASE NO FIELD !!!                        664   // !!! CASE NO FIELD !!!
665   /////////////////////////                       665   /////////////////////////
666   State(fCandidateEndGlobalTime) = timeStep +     666   State(fCandidateEndGlobalTime) = timeStep + track.GetGlobalTime();
667   State(fEndGlobalTimeComputed) = true;           667   State(fEndGlobalTimeComputed) = true;
668                                                   668 
669   // Choose the calculation of the transportat    669   // Choose the calculation of the transportation: Field or not
670   //                                              670   //
671   if (!State(fMomentumChanged))                   671   if (!State(fMomentumChanged))
672   {                                               672   {
673     //        G4cout << "Momentum has not chan    673     //        G4cout << "Momentum has not changed" << G4endl;
674     fParticleChange.ProposeVelocity(initialVel    674     fParticleChange.ProposeVelocity(initialVelocity);
675     oPhysicalStep = initialVelocity * timeStep    675     oPhysicalStep = initialVelocity * timeStep;
676                                                   676 
677     // Calculate final position                   677     // Calculate final position
678     //                                            678     //
679     State(fTransportEndPosition) = startPositi    679     State(fTransportEndPosition) = startPosition
680         + oPhysicalStep * startMomentumDir;       680         + oPhysicalStep * startMomentumDir;
681   }                                               681   }
682 }                                                 682 }
683                                                   683 
684 //////////////////////////////////////////////    684 //////////////////////////////////////////////////////////////////////////
685 //                                                685 //
686 //   Initialize ParticleChange  (by setting al    686 //   Initialize ParticleChange  (by setting all its members equal
687 //                               to correspond    687 //                               to corresponding members in G4Track)
688 #include "G4ParticleTable.hh"                     688 #include "G4ParticleTable.hh"
689 G4VParticleChange* G4ITTransportation::AlongSt    689 G4VParticleChange* G4ITTransportation::AlongStepDoIt(const G4Track& track,
690                                                   690                                                      const G4Step& stepData)
691 {                                                 691 {
692                                                   692 
693 #if defined (DEBUG_MEM)                           693 #if defined (DEBUG_MEM)
694   MemStat mem_first, mem_second, mem_diff;        694   MemStat mem_first, mem_second, mem_diff;
695 #endif                                            695 #endif
696                                                   696 
697 #if defined (DEBUG_MEM)                           697 #if defined (DEBUG_MEM)
698   mem_first = MemoryUsage();                      698   mem_first = MemoryUsage();
699 #endif                                            699 #endif
700                                                   700 
701   PrepareState();                              << 701   PrepareState()
702                                                << 702   
703   // G4cout << "G4ITTransportation::AlongStepD    703   // G4cout << "G4ITTransportation::AlongStepDoIt" << G4endl;
704   // set  pdefOpticalPhoton                       704   // set  pdefOpticalPhoton
705   // Andrea Dotti: the following statement sho    705   // Andrea Dotti: the following statement should be in a single line:
706   // G4-MT transformation tools get confused i    706   // G4-MT transformation tools get confused if statement spans two lines
707   // If needed contact: adotti@slac.stanford.e    707   // If needed contact: adotti@slac.stanford.edu
708   static G4ThreadLocal G4ParticleDefinition* p << 708   static G4ThreadLocal G4ParticleDefinition* pdefOpticalPhoton = 0;
709   if (pdefOpticalPhoton == nullptr) pdefOptica << 709   if (!pdefOpticalPhoton) pdefOpticalPhoton =
710       G4ParticleTable::GetParticleTable()->Fin    710       G4ParticleTable::GetParticleTable()->FindParticle("opticalphoton");
711                                                   711 
712   static G4ThreadLocal G4int noCalls = 0;         712   static G4ThreadLocal G4int noCalls = 0;
713   noCalls++;                                      713   noCalls++;
714                                                   714 
715   fParticleChange.Initialize(track);              715   fParticleChange.Initialize(track);
716                                                   716 
717   //  Code for specific process                   717   //  Code for specific process
718   //                                              718   //
719   fParticleChange.ProposePosition(State(fTrans    719   fParticleChange.ProposePosition(State(fTransportEndPosition));
720   fParticleChange.ProposeMomentumDirection(Sta    720   fParticleChange.ProposeMomentumDirection(State(fTransportEndMomentumDir));
721   fParticleChange.ProposeEnergy(State(fTranspo    721   fParticleChange.ProposeEnergy(State(fTransportEndKineticEnergy));
722   fParticleChange.SetMomentumChanged(State(fMo    722   fParticleChange.SetMomentumChanged(State(fMomentumChanged));
723                                                   723 
724   fParticleChange.ProposePolarization(State(fT    724   fParticleChange.ProposePolarization(State(fTransportEndSpin));
725                                                   725 
726   G4double deltaTime = 0.0;                       726   G4double deltaTime = 0.0;
727                                                   727 
728   // Calculate  Lab Time of Flight (ONLY if fi    728   // Calculate  Lab Time of Flight (ONLY if field Equations used it!)
729   // G4double endTime   = State(fCandidateEndG    729   // G4double endTime   = State(fCandidateEndGlobalTime);
730   // G4double delta_time = endTime - startTime    730   // G4double delta_time = endTime - startTime;
731                                                   731 
732   G4double startTime = track.GetGlobalTime();     732   G4double startTime = track.GetGlobalTime();
733   ///_________________________________________    733   ///___________________________________________________________________________
734   /// !!!!!!!                                     734   /// !!!!!!!
735   /// A REVOIR !!!!                               735   /// A REVOIR !!!!
736   if (State(fEndGlobalTimeComputed) == 0)      << 736   if (State(fEndGlobalTimeComputed) == false)
737   {                                               737   {
738     // The time was not integrated .. make the    738     // The time was not integrated .. make the best estimate possible
739     //                                            739     //
740     G4double initialVelocity = stepData.GetPre    740     G4double initialVelocity = stepData.GetPreStepPoint()->GetVelocity();
741     G4double stepLength = track.GetStepLength(    741     G4double stepLength = track.GetStepLength();
742                                                   742 
743     deltaTime = 0.0; // in case initialVelocit    743     deltaTime = 0.0; // in case initialVelocity = 0
744     if (track.GetParticleDefinition() == pdefO    744     if (track.GetParticleDefinition() == pdefOpticalPhoton)
745     {                                             745     {
746       // For only Optical Photon, final veloci    746       // For only Optical Photon, final velocity is used
747       double finalVelocity = track.CalculateVe    747       double finalVelocity = track.CalculateVelocityForOpticalPhoton();
748       fParticleChange.ProposeVelocity(finalVel    748       fParticleChange.ProposeVelocity(finalVelocity);
749       deltaTime = stepLength / finalVelocity;     749       deltaTime = stepLength / finalVelocity;
750     }                                             750     }
751     else if (initialVelocity > 0.0)               751     else if (initialVelocity > 0.0)
752     {                                             752     {
753       deltaTime = stepLength / initialVelocity    753       deltaTime = stepLength / initialVelocity;
754     }                                             754     }
755                                                   755 
756     State(fCandidateEndGlobalTime) = startTime    756     State(fCandidateEndGlobalTime) = startTime + deltaTime;
757   }                                               757   }
758   else                                            758   else
759   {                                               759   {
760     deltaTime = State(fCandidateEndGlobalTime)    760     deltaTime = State(fCandidateEndGlobalTime) - startTime;
761   }                                               761   }
762                                                   762 
763   fParticleChange.ProposeGlobalTime(State(fCan    763   fParticleChange.ProposeGlobalTime(State(fCandidateEndGlobalTime));
764   fParticleChange.ProposeLocalTime(track.GetLo    764   fParticleChange.ProposeLocalTime(track.GetLocalTime() + deltaTime);
765   /*                                              765   /*
766    // Now Correct by Lorentz factor to get del    766    // Now Correct by Lorentz factor to get delta "proper" Time
767                                                   767 
768    G4double  restMass       = track.GetDynamic    768    G4double  restMass       = track.GetDynamicParticle()->GetMass() ;
769    G4double deltaProperTime = deltaTime*( rest    769    G4double deltaProperTime = deltaTime*( restMass/track.GetTotalEnergy() ) ;
770                                                   770 
771    fParticleChange.ProposeProperTime(track.Get    771    fParticleChange.ProposeProperTime(track.GetProperTime() + deltaProperTime) ;
772    */                                             772    */
773                                                   773 
774   fParticleChange.ProposeTrueStepLength(track.    774   fParticleChange.ProposeTrueStepLength(track.GetStepLength());
775                                                   775 
776   ///_________________________________________    776   ///___________________________________________________________________________
777   ///                                             777   ///
778                                                   778 
779   // If the particle is caught looping or is s    779   // If the particle is caught looping or is stuck (in very difficult
780   // boundaries) in a magnetic field (doing ma    780   // boundaries) in a magnetic field (doing many steps)
781   //   THEN this kills it ...                     781   //   THEN this kills it ...
782   //                                              782   //
783   if (State(fParticleIsLooping))                  783   if (State(fParticleIsLooping))
784   {                                               784   {
785     G4double endEnergy = State(fTransportEndKi    785     G4double endEnergy = State(fTransportEndKineticEnergy);
786                                                   786 
787     if ((endEnergy < fThreshold_Important_Ener    787     if ((endEnergy < fThreshold_Important_Energy) || (State(fNoLooperTrials)
788         >= fThresholdTrials))                     788         >= fThresholdTrials))
789     {                                             789     {
790       // Kill the looping particle                790       // Kill the looping particle
791       //                                          791       //
792       // G4cout << "G4ITTransportation will ki    792       // G4cout << "G4ITTransportation will killed the molecule"<< G4endl;
793       fParticleChange.ProposeTrackStatus(fStop    793       fParticleChange.ProposeTrackStatus(fStopAndKill);
794                                                   794 
795       // 'Bare' statistics                        795       // 'Bare' statistics
796       fSumEnergyKilled += endEnergy;              796       fSumEnergyKilled += endEnergy;
797       if (endEnergy > fMaxEnergyKilled)           797       if (endEnergy > fMaxEnergyKilled)
798       {                                           798       {
799         fMaxEnergyKilled = endEnergy;             799         fMaxEnergyKilled = endEnergy;
800       }                                           800       }
801                                                   801 
802 #ifdef G4VERBOSE                                  802 #ifdef G4VERBOSE
803       if ((fVerboseLevel > 1) || (endEnergy >     803       if ((fVerboseLevel > 1) || (endEnergy > fThreshold_Warning_Energy))
804       {                                           804       {
805         G4cout                                    805         G4cout
806             << " G4ITTransportation is killing    806             << " G4ITTransportation is killing track that is looping or stuck "
807             << G4endl<< "   This track has " <    807             << G4endl<< "   This track has " << track.GetKineticEnergy() / MeV
808         << " MeV energy." << G4endl;              808         << " MeV energy." << G4endl;
809         G4cout << "   Number of trials = " <<     809         G4cout << "   Number of trials = " << State(fNoLooperTrials)
810         << "   No of calls to AlongStepDoIt =     810         << "   No of calls to AlongStepDoIt = " << noCalls
811         << G4endl;                                811         << G4endl;
812       }                                           812       }
813 #endif                                            813 #endif
814       State(fNoLooperTrials) = 0;                 814       State(fNoLooperTrials) = 0;
815     }                                             815     }
816     else                                          816     else
817     {                                             817     {
818       State(fNoLooperTrials)++;                   818       State(fNoLooperTrials)++;
819 #ifdef G4VERBOSE                                  819 #ifdef G4VERBOSE
820       if ((fVerboseLevel > 2))                    820       if ((fVerboseLevel > 2))
821       {                                           821       {
822         G4cout << "   G4ITTransportation::Alon    822         G4cout << "   G4ITTransportation::AlongStepDoIt(): Particle looping -  "
823                << "   Number of trials = " <<     823                << "   Number of trials = " << State(fNoLooperTrials)
824                << "   No of calls to  = " << n    824                << "   No of calls to  = " << noCalls << G4endl;
825       }                                           825       }
826 #endif                                            826 #endif
827     }                                             827     }
828   }                                               828   }
829   else                                            829   else
830   {                                               830   {
831     State(fNoLooperTrials)=0;                     831     State(fNoLooperTrials)=0;
832   }                                               832   }
833                                                   833 
834   // Another (sometimes better way) is to use     834   // Another (sometimes better way) is to use a user-limit maximum Step size
835   // to alleviate this problem ..                 835   // to alleviate this problem ..
836                                                   836 
837   // Introduce smooth curved trajectories to p    837   // Introduce smooth curved trajectories to particle-change
838   //                                              838   //
839   fParticleChange.SetPointerToVectorOfAuxiliar    839   fParticleChange.SetPointerToVectorOfAuxiliaryPoints(
840       fFieldPropagator->GimmeTrajectoryVectorA    840       fFieldPropagator->GimmeTrajectoryVectorAndForgetIt());
841                                                   841 
842 #if defined (DEBUG_MEM)                           842 #if defined (DEBUG_MEM)
843   mem_second = MemoryUsage();                     843   mem_second = MemoryUsage();
844   mem_diff = mem_second-mem_first;                844   mem_diff = mem_second-mem_first;
845   G4cout << "\t || MEM || End of G4ITTransport    845   G4cout << "\t || MEM || End of G4ITTransportation::AlongStepDoIt, diff is: "
846       << mem_diff << G4endl;                      846       << mem_diff << G4endl;
847 #endif                                            847 #endif
848                                                   848 
849   return &fParticleChange;                        849   return &fParticleChange;
850 }                                                 850 }
851                                                   851 
852 //////////////////////////////////////////////    852 //////////////////////////////////////////////////////////////////////////
853 //                                                853 //
854 //  This ensures that the PostStep action is a    854 //  This ensures that the PostStep action is always called,
855 //  so that it can do the relocation if it is     855 //  so that it can do the relocation if it is needed.
856 //                                                856 //
857                                                   857 
858 G4double                                          858 G4double
859 G4ITTransportation::                              859 G4ITTransportation::
860 PostStepGetPhysicalInteractionLength(const G4T    860 PostStepGetPhysicalInteractionLength(const G4Track&, // track
861                                      G4double,    861                                      G4double, // previousStepSize
862                                      G4ForceCo    862                                      G4ForceCondition* pForceCond)
863 {                                                 863 {
864   *pForceCond = Forced;                           864   *pForceCond = Forced;
865   return DBL_MAX; // was kInfinity ; but conve    865   return DBL_MAX; // was kInfinity ; but convention now is DBL_MAX
866 }                                                 866 }
867                                                   867 
868 //////////////////////////////////////////////    868 /////////////////////////////////////////////////////////////////////////////
869 //                                                869 //
870                                                   870 
871 G4VParticleChange* G4ITTransportation::PostSte    871 G4VParticleChange* G4ITTransportation::PostStepDoIt(const G4Track& track,
872                                                   872                                                     const G4Step&)
873 {                                                 873 {
874   //    G4cout << "G4ITTransportation::PostSte    874   //    G4cout << "G4ITTransportation::PostStepDoIt" << G4endl;
875                                                << 875  
876   PrepareState();                              << 876   PrepareState()
877   G4TouchableHandle retCurrentTouchable; // Th    877   G4TouchableHandle retCurrentTouchable; // The one to return
878   G4bool isLastStep = false;                      878   G4bool isLastStep = false;
879                                                   879 
880   // Initialize ParticleChange  (by setting al    880   // Initialize ParticleChange  (by setting all its members equal
881   //                             to correspond    881   //                             to corresponding members in G4Track)
882   fParticleChange.Initialize(track); // To ini    882   fParticleChange.Initialize(track); // To initialise TouchableChange
883                                                   883 
884   fParticleChange.ProposeTrackStatus(track.Get    884   fParticleChange.ProposeTrackStatus(track.GetTrackStatus());
885                                                   885 
886   // If the Step was determined by the volume     886   // If the Step was determined by the volume boundary,
887   // logically relocate the particle              887   // logically relocate the particle
888                                                   888 
889   if (State(fGeometryLimitedStep))                889   if (State(fGeometryLimitedStep))
890   {                                               890   {
891                                                   891 
892     if(fVerboseLevel != 0)                     << 892     if(fVerboseLevel)
893     {                                             893     {
894      G4cout << "Step is limited by geometry "     894      G4cout << "Step is limited by geometry "
895             <<  "track ID : " << track.GetTrac    895             <<  "track ID : " << track.GetTrackID() << G4endl;
896     }                                             896     }
897                                                   897 
898     // fCurrentTouchable will now become the p    898     // fCurrentTouchable will now become the previous touchable,
899     // and what was the previous will be freed    899     // and what was the previous will be freed.
900     // (Needed because the preStepPoint can po    900     // (Needed because the preStepPoint can point to the previous touchable)
901                                                   901 
902     if ( State(fCurrentTouchableHandle)->GetVo << 902     if ( State(fCurrentTouchableHandle)->GetVolume() == 0)
903     {                                             903     {
904       G4ExceptionDescription exceptionDescript    904       G4ExceptionDescription exceptionDescription;
905       exceptionDescription << "No current touc    905       exceptionDescription << "No current touchable found ";
906       G4Exception(" G4ITTransportation::PostSt    906       G4Exception(" G4ITTransportation::PostStepDoIt", "G4ITTransportation001",
907                   FatalErrorInArgument, except    907                   FatalErrorInArgument, exceptionDescription);
908     }                                             908     }
909                                                   909 
910     fLinearNavigator->SetGeometricallyLimitedS    910     fLinearNavigator->SetGeometricallyLimitedStep();
911     fLinearNavigator->LocateGlobalPointAndUpda    911     fLinearNavigator->LocateGlobalPointAndUpdateTouchableHandle(
912         track.GetPosition(), track.GetMomentum    912         track.GetPosition(), track.GetMomentumDirection(),
913         State(fCurrentTouchableHandle), true);    913         State(fCurrentTouchableHandle), true);
914     // Check whether the particle is out of th    914     // Check whether the particle is out of the world volume
915     // If so it has exited and must be killed.    915     // If so it has exited and must be killed.
916     //                                            916     //
917     if ( State(fCurrentTouchableHandle)->GetVo << 917     if ( State(fCurrentTouchableHandle)->GetVolume() == 0)
918     {                                             918     {
919     //  abort();                                  919     //  abort();
920 #ifdef G4VERBOSE                                  920 #ifdef G4VERBOSE
921       if (fVerboseLevel > 0)                      921       if (fVerboseLevel > 0)
922       {                                           922       {
923         G4cout << "Track position : " << track    923         G4cout << "Track position : " << track.GetPosition() / nanometer
924                << " [nm]" << " Track ID : " <<    924                << " [nm]" << " Track ID : " << track.GetTrackID() << G4endl;
925         G4cout << "G4ITTransportation will kil    925         G4cout << "G4ITTransportation will killed the track because "
926             "State(fCurrentTouchableHandle)->G    926             "State(fCurrentTouchableHandle)->GetVolume() == 0"<< G4endl;
927       }                                           927       }
928 #endif                                            928 #endif
929       fParticleChange.ProposeTrackStatus( fSto    929       fParticleChange.ProposeTrackStatus( fStopAndKill );
930     }                                             930     }
931                                                   931 
932     retCurrentTouchable = State(fCurrentToucha    932     retCurrentTouchable = State(fCurrentTouchableHandle);
933                                                   933 
934 //        G4cout << "Current volume : " << tra    934 //        G4cout << "Current volume : " << track.GetVolume()->GetName()
935 //               << " Next volume : "             935 //               << " Next volume : "
936 //               << (State(fCurrentTouchableHa    936 //               << (State(fCurrentTouchableHandle)->GetVolume() ?
937 //    State(fCurrentTouchableHandle)->GetVolum    937 //    State(fCurrentTouchableHandle)->GetVolume()->GetName():"OutWorld")
938 //               << " Position : " << track.Ge    938 //               << " Position : " << track.GetPosition() / nanometer
939 //               << " track ID : " << track.Ge    939 //               << " track ID : " << track.GetTrackID()
940 //               << G4endl;                       940 //               << G4endl;
941                                                   941 
942     fParticleChange.SetTouchableHandle(State(f    942     fParticleChange.SetTouchableHandle(State(fCurrentTouchableHandle));
943                                                   943 
944     // Update the Step flag which identifies t    944     // Update the Step flag which identifies the Last Step in a volume
945     isLastStep = fLinearNavigator->ExitedMothe    945     isLastStep = fLinearNavigator->ExitedMotherVolume()
946                || fLinearNavigator->EnteredDau << 946         | fLinearNavigator->EnteredDaughterVolume();
947                                                   947 
948 #ifdef G4DEBUG_TRANSPORT                          948 #ifdef G4DEBUG_TRANSPORT
949     //  Checking first implementation of flagg    949     //  Checking first implementation of flagging Last Step in Volume
950     G4bool exiting = fLinearNavigator->ExitedM    950     G4bool exiting = fLinearNavigator->ExitedMotherVolume();
951     G4bool entering = fLinearNavigator->Entere    951     G4bool entering = fLinearNavigator->EnteredDaughterVolume();
952                                                   952 
953     if( ! (exiting || entering) )                 953     if( ! (exiting || entering) )
954     {                                             954     {
955       G4cout << " Transport> :  Proposed isLas    955       G4cout << " Transport> :  Proposed isLastStep= " << isLastStep
956       << " Exiting " << fLinearNavigator->Exit    956       << " Exiting " << fLinearNavigator->ExitedMotherVolume()
957       << " Entering " << fLinearNavigator->Ent    957       << " Entering " << fLinearNavigator->EnteredDaughterVolume()
958       << " Track position : " << track.GetPosi    958       << " Track position : " << track.GetPosition() /nanometer << " [nm]"
959       << G4endl;                                  959       << G4endl;
960       G4cout << " Track position : " << track.    960       G4cout << " Track position : " << track.GetPosition() /nanometer
961           << G4endl;                              961           << G4endl;
962     }                                             962     }
963 #endif                                            963 #endif
964   }                                               964   }
965   else // fGeometryLimitedStep  is false          965   else // fGeometryLimitedStep  is false
966   {                                               966   {
967     // This serves only to move the Navigator'    967     // This serves only to move the Navigator's location
968     //                                            968     //
969 //    abort();                                    969 //    abort();
970     fLinearNavigator->LocateGlobalPointWithinV    970     fLinearNavigator->LocateGlobalPointWithinVolume(track.GetPosition());
971                                                   971 
972     // The value of the track's current Toucha    972     // The value of the track's current Touchable is retained.
973     // (and it must be correct because we must    973     // (and it must be correct because we must use it below to
974     // overwrite the (unset) one in particle c    974     // overwrite the (unset) one in particle change)
975     //  It must be fCurrentTouchable too ??       975     //  It must be fCurrentTouchable too ??
976     //                                            976     //
977     fParticleChange.SetTouchableHandle(track.G    977     fParticleChange.SetTouchableHandle(track.GetTouchableHandle());
978     retCurrentTouchable = track.GetTouchableHa    978     retCurrentTouchable = track.GetTouchableHandle();
979                                                   979 
980     isLastStep = false;                           980     isLastStep = false;
981 #ifdef G4DEBUG_TRANSPORT                          981 #ifdef G4DEBUG_TRANSPORT
982     //  Checking first implementation of flagg    982     //  Checking first implementation of flagging Last Step in Volume
983     G4cout << " Transport> Proposed isLastStep    983     G4cout << " Transport> Proposed isLastStep= " << isLastStep
984     << " Geometry did not limit step. Position    984     << " Geometry did not limit step. Position : "
985     << track.GetPosition()/ nanometer << G4end    985     << track.GetPosition()/ nanometer << G4endl;
986 #endif                                            986 #endif
987   } // endif ( fGeometryLimitedStep )             987   } // endif ( fGeometryLimitedStep )
988                                                   988 
989   fParticleChange.ProposeLastStepInVolume(isLa    989   fParticleChange.ProposeLastStepInVolume(isLastStep);
990                                                   990 
991   const G4VPhysicalVolume* pNewVol = retCurren    991   const G4VPhysicalVolume* pNewVol = retCurrentTouchable->GetVolume();
992   const G4Material* pNewMaterial = nullptr;    << 992   const G4Material* pNewMaterial = 0;
993   G4VSensitiveDetector* pNewSensitiveDetector  << 993   const G4VSensitiveDetector* pNewSensitiveDetector = 0;
994                                                   994 
995   if (pNewVol != nullptr)                      << 995   if (pNewVol != 0)
996   {                                               996   {
997     pNewMaterial = pNewVol->GetLogicalVolume()    997     pNewMaterial = pNewVol->GetLogicalVolume()->GetMaterial();
998     pNewSensitiveDetector = pNewVol->GetLogica    998     pNewSensitiveDetector = pNewVol->GetLogicalVolume()->GetSensitiveDetector();
999   }                                               999   }
1000                                                  1000 
1001   // ( <const_cast> pNewMaterial ) ;             1001   // ( <const_cast> pNewMaterial ) ;
                                                   >> 1002   // ( <const_cast> pNewSensitiveDetector) ;
1002                                                  1003 
1003   fParticleChange.SetMaterialInTouchable((G4M    1004   fParticleChange.SetMaterialInTouchable((G4Material *) pNewMaterial);
1004   fParticleChange.SetSensitiveDetectorInTouch << 1005   fParticleChange.SetSensitiveDetectorInTouchable(
                                                   >> 1006       (G4VSensitiveDetector *) pNewSensitiveDetector);
1005                                                  1007 
1006   const G4MaterialCutsCouple* pNewMaterialCut << 1008   const G4MaterialCutsCouple* pNewMaterialCutsCouple = 0;
1007   if (pNewVol != nullptr)                     << 1009   if (pNewVol != 0)
1008   {                                              1010   {
1009     pNewMaterialCutsCouple =                     1011     pNewMaterialCutsCouple =
1010         pNewVol->GetLogicalVolume()->GetMater    1012         pNewVol->GetLogicalVolume()->GetMaterialCutsCouple();
1011   }                                              1013   }
1012                                                  1014 
1013   if (pNewVol != nullptr && pNewMaterialCutsC << 1015   if (pNewVol != 0 && pNewMaterialCutsCouple != 0
1014       && pNewMaterialCutsCouple->GetMaterial(    1016       && pNewMaterialCutsCouple->GetMaterial() != pNewMaterial)
1015   {                                              1017   {
1016     // for parametrized volume                   1018     // for parametrized volume
1017     //                                           1019     //
1018     pNewMaterialCutsCouple = G4ProductionCuts    1020     pNewMaterialCutsCouple = G4ProductionCutsTable::GetProductionCutsTable()
1019         ->GetMaterialCutsCouple(pNewMaterial,    1021         ->GetMaterialCutsCouple(pNewMaterial,
1020                                 pNewMaterialC    1022                                 pNewMaterialCutsCouple->GetProductionCuts());
1021   }                                              1023   }
1022   fParticleChange.SetMaterialCutsCoupleInTouc    1024   fParticleChange.SetMaterialCutsCoupleInTouchable(pNewMaterialCutsCouple);
1023                                                  1025 
1024   // temporarily until Get/Set Material of Pa    1026   // temporarily until Get/Set Material of ParticleChange,
1025   // and StepPoint can be made const.            1027   // and StepPoint can be made const.
1026   // Set the touchable in ParticleChange         1028   // Set the touchable in ParticleChange
1027   // this must always be done because the par    1029   // this must always be done because the particle change always
1028   // uses this value to overwrite the current    1030   // uses this value to overwrite the current touchable pointer.
1029   //                                             1031   //
1030   fParticleChange.SetTouchableHandle(retCurre    1032   fParticleChange.SetTouchableHandle(retCurrentTouchable);
1031                                                  1033 
1032   return &fParticleChange;                       1034   return &fParticleChange;
1033 }                                                1035 }
1034                                                  1036 
1035 // New method takes over the responsibility t    1037 // New method takes over the responsibility to reset the state of
1036 // G4Transportation object at the start of a     1038 // G4Transportation object at the start of a new track or the resumption of
1037 // a suspended track.                            1039 // a suspended track.
1038                                                  1040 
1039 void G4ITTransportation::StartTracking(G4Trac    1041 void G4ITTransportation::StartTracking(G4Track* track)
1040 {                                                1042 {
1041   G4VProcess::StartTracking(track);              1043   G4VProcess::StartTracking(track);
1042   if (fInstantiateProcessState)                  1044   if (fInstantiateProcessState)
1043   {                                              1045   {
1044 //        G4VITProcess::fpState = new G4ITTra    1046 //        G4VITProcess::fpState = new G4ITTransportationState();
1045     G4VITProcess::fpState = std::make_shared< << 1047     G4VITProcess::fpState.reset(new G4ITTransportationState());
1046     // Will set in the same time fTransportat    1048     // Will set in the same time fTransportationState
1047   }                                              1049   }
1048                                                  1050 
1049   fpSafetyHelper->NewTrackState();               1051   fpSafetyHelper->NewTrackState();
1050   fpSafetyHelper->SaveTrackState(                1052   fpSafetyHelper->SaveTrackState(
1051       GetIT(track)->GetTrackingInfo()->GetTra    1053       GetIT(track)->GetTrackingInfo()->GetTrackStateManager());
1052                                                  1054 
1053   // The actions here are those that were tak    1055   // The actions here are those that were taken in AlongStepGPIL
1054   //   when track.GetCurrentStepNumber()==1      1056   //   when track.GetCurrentStepNumber()==1
1055                                                  1057 
1056   // reset safety value and center               1058   // reset safety value and center
1057   //                                             1059   //
1058   //    State(fPreviousSafety)    = 0.0 ;        1060   //    State(fPreviousSafety)    = 0.0 ;
1059   //    State(fPreviousSftOrigin) = G4ThreeVe    1061   //    State(fPreviousSftOrigin) = G4ThreeVector(0.,0.,0.) ;
1060                                                  1062 
1061   // reset looping counter -- for motion in f    1063   // reset looping counter -- for motion in field
1062   //    State(fNoLooperTrials)= 0;               1064   //    State(fNoLooperTrials)= 0;
1063   // Must clear this state .. else it depends    1065   // Must clear this state .. else it depends on last track's value
1064   //  --> a better solution would set this fr    1066   //  --> a better solution would set this from state of suspended track TODO ?
1065   // Was if( aTrack->GetCurrentStepNumber()==    1067   // Was if( aTrack->GetCurrentStepNumber()==1 ) { .. }
1066                                                  1068 
1067   // ChordFinder reset internal state            1069   // ChordFinder reset internal state
1068   //                                             1070   //
1069   if (DoesGlobalFieldExist())                    1071   if (DoesGlobalFieldExist())
1070   {                                              1072   {
1071     fFieldPropagator->ClearPropagatorState();    1073     fFieldPropagator->ClearPropagatorState();
1072     // Resets all state of field propagator c    1074     // Resets all state of field propagator class (ONLY)
1073     // including safety values (in case of ov    1075     // including safety values (in case of overlaps and to wipe for first track).
1074                                                  1076 
1075     // G4ChordFinder* chordF= fFieldPropagato    1077     // G4ChordFinder* chordF= fFieldPropagator->GetChordFinder();
1076     // if( chordF ) chordF->ResetStepEstimate    1078     // if( chordF ) chordF->ResetStepEstimate();
1077   }                                              1079   }
1078                                                  1080 
1079   // Make sure to clear the chord finders of     1081   // Make sure to clear the chord finders of all fields (ie managers)
1080   static G4ThreadLocal G4FieldManagerStore* f << 1082   static G4ThreadLocal G4FieldManagerStore* fieldMgrStore = 0;
1081   if (fieldMgrStore == nullptr) fieldMgrStore << 1083   if (!fieldMgrStore) fieldMgrStore = G4FieldManagerStore::GetInstance();
1082   fieldMgrStore->ClearAllChordFindersState();    1084   fieldMgrStore->ClearAllChordFindersState();
1083                                                  1085 
1084   // Update the current touchable handle  (fr    1086   // Update the current touchable handle  (from the track's)
1085   //                                             1087   //
1086   PrepareState();                             << 1088   PrepareState()
1087   State(fCurrentTouchableHandle) = track->Get    1089   State(fCurrentTouchableHandle) = track->GetTouchableHandle();
1088                                                  1090 
1089   G4VITProcess::StartTracking(track);            1091   G4VITProcess::StartTracking(track);
1090 }                                                1092 }
1091                                                  1093 
1092 #undef State                                     1094 #undef State
1093 #undef PrepareState                              1095 #undef PrepareState
1094                                                  1096