Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/geometry/navigation/src/G4VIntersectionLocator.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 /geometry/navigation/src/G4VIntersectionLocator.cc (Version 11.3.0) and /geometry/navigation/src/G4VIntersectionLocator.cc (Version 10.2.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: G4VIntersectionLocator.cc 102290 2017-01-20 11:19:44Z gcosmo $
                                                   >>  27 //
 26 // Class G4VIntersectionLocator implementation     28 // Class G4VIntersectionLocator implementation
 27 //                                                 29 //
 28 // 27.10.08 - John Apostolakis, Tatiana Nikiti     30 // 27.10.08 - John Apostolakis, Tatiana Nikitina.
 29 // -------------------------------------------     31 // ---------------------------------------------------------------------------
 30                                                    32  
 31 #include <iomanip>                                 33 #include <iomanip>
 32 #include <sstream>                                 34 #include <sstream>
 33                                                    35 
 34 #include "globals.hh"                              36 #include "globals.hh"
 35 #include "G4ios.hh"                                37 #include "G4ios.hh"
 36 #include "G4AutoDelete.hh"                         38 #include "G4AutoDelete.hh"
 37 #include "G4SystemOfUnits.hh"                      39 #include "G4SystemOfUnits.hh"
 38 #include "G4VIntersectionLocator.hh"               40 #include "G4VIntersectionLocator.hh"
 39 #include "G4TouchableHandle.hh"                << 
 40 #include "G4GeometryTolerance.hh"                  41 #include "G4GeometryTolerance.hh"
 41                                                    42 
 42 //////////////////////////////////////////////     43 ///////////////////////////////////////////////////////////////////////////
 43 //                                                 44 //
 44 // Constructor                                     45 // Constructor
 45 //                                                 46 //
 46 G4VIntersectionLocator::G4VIntersectionLocator <<  47 G4VIntersectionLocator:: G4VIntersectionLocator(G4Navigator *theNavigator)
 47  : fiNavigator(theNavigator)                   <<  48  : fVerboseLevel(0),
                                                   >>  49    fUseNormalCorrection(false),
                                                   >>  50    fCheckMode(false),
                                                   >>  51    fiNavigator(theNavigator),
                                                   >>  52    fiChordFinder(0),              // Not set - overridden at each step
                                                   >>  53    fiEpsilonStep(-1.0),           // Out of range - overridden at each step
                                                   >>  54    fiDeltaIntersection(-1.0),     // Out of range - overridden at each step
                                                   >>  55    fiUseSafety(false),            // Default - overridden at each step
                                                   >>  56    fpTouchable(0)           
 48 {                                                  57 {
 49   kCarTolerance = G4GeometryTolerance::GetInst     58   kCarTolerance = G4GeometryTolerance::GetInstance()->GetSurfaceTolerance();
 50                                                <<  59   fHelpingNavigator = new G4Navigator();
 51   if( fiNavigator->GetExternalNavigation() ==  << 
 52   {                                            << 
 53     fHelpingNavigator = new G4Navigator();     << 
 54   }                                            << 
 55   else // Must clone the navigator, together w << 
 56   {                                            << 
 57     fHelpingNavigator = fiNavigator->Clone();  << 
 58   }                                            << 
 59 }                                                  60 }      
 60                                                    61 
 61 //////////////////////////////////////////////     62 ///////////////////////////////////////////////////////////////////////////
 62 //                                                 63 //
 63 // Destructor.                                     64 // Destructor.
 64 //                                                 65 //
 65 G4VIntersectionLocator::~G4VIntersectionLocato     66 G4VIntersectionLocator::~G4VIntersectionLocator()
 66 {                                                  67 {
 67   delete fHelpingNavigator;                        68   delete fHelpingNavigator;
 68   delete fpTouchable;                              69   delete fpTouchable;
 69 }                                                  70 }
 70                                                    71 
 71 //////////////////////////////////////////////     72 ///////////////////////////////////////////////////////////////////////////
 72 //                                                 73 //
 73 // Dump status of propagator to cout (old meth     74 // Dump status of propagator to cout (old method)
 74 //                                                 75 //
 75 void                                               76 void
 76 G4VIntersectionLocator::printStatus( const G4F <<  77 G4VIntersectionLocator::printStatus( const G4FieldTrack&        StartFT,
 77                                      const G4F <<  78                                      const G4FieldTrack&        CurrentFT, 
 78                                            G4d <<  79                                            G4double             requestStep, 
 79                                            G4d <<  80                                            G4double             safety,
 80                                            G4i <<  81                                            G4int                stepNo)
 81 {                                                  82 {
 82   std::ostringstream os;                           83   std::ostringstream os; 
 83   printStatus( StartFT,CurrentFT,requestStep,s     84   printStatus( StartFT,CurrentFT,requestStep,safety,stepNo,os,fVerboseLevel);
 84   G4cout << os.str();                              85   G4cout << os.str();
 85 }                                                  86 }
 86                                                    87 
 87 //////////////////////////////////////////////     88 ///////////////////////////////////////////////////////////////////////////
 88 //                                                 89 //
 89 // Dumps status of propagator.                     90 // Dumps status of propagator.
 90 //                                                 91 //
 91 void                                               92 void
 92 G4VIntersectionLocator::printStatus( const G4F <<  93 G4VIntersectionLocator::printStatus( const G4FieldTrack&        StartFT,
 93                                      const G4F <<  94                                      const G4FieldTrack&        CurrentFT, 
 94                                            G4d <<  95                                            G4double             requestStep, 
 95                                            G4d <<  96                                            G4double             safety,
 96                                            G4i <<  97                                            G4int                stepNo,
 97                                            std <<  98                                            std::ostream&        os,
 98                                            G4i <<  99                                            int                  verboseLevel)
 99 {                                                 100 {
100   // const G4int verboseLevel= fVerboseLevel;     101   // const G4int verboseLevel= fVerboseLevel;
101   const G4ThreeVector StartPosition       = St    102   const G4ThreeVector StartPosition       = StartFT.GetPosition();
102   const G4ThreeVector StartUnitVelocity   = St    103   const G4ThreeVector StartUnitVelocity   = StartFT.GetMomentumDir();
103   const G4ThreeVector CurrentPosition     = Cu    104   const G4ThreeVector CurrentPosition     = CurrentFT.GetPosition();
104   const G4ThreeVector CurrentUnitVelocity = Cu    105   const G4ThreeVector CurrentUnitVelocity = CurrentFT.GetMomentumDir();
105                                                   106 
106   G4double step_len = CurrentFT.GetCurveLength    107   G4double step_len = CurrentFT.GetCurveLength() - StartFT.GetCurveLength();
107   G4long oldprc;  // cout/cerr precision setti << 108   G4int oldprc;  // cout/cerr precision settings
108                                                   109 
109   if( ((stepNo == 0) && (verboseLevel <3)) ||     110   if( ((stepNo == 0) && (verboseLevel <3)) || (verboseLevel >= 3) )
110   {                                               111   {
111     oldprc = os.precision(4);                     112     oldprc = os.precision(4);
112     os << std::setw( 6)  << " "                   113     os << std::setw( 6)  << " " 
113            << std::setw( 25) << " Current Posi    114            << std::setw( 25) << " Current Position  and  Direction" << " "
114            << G4endl;                             115            << G4endl; 
115     os << std::setw( 5) << "Step#"                116     os << std::setw( 5) << "Step#" 
116            << std::setw(10) << "  s  " << " "     117            << std::setw(10) << "  s  " << " "
117            << std::setw(10) << "X(mm)" << " "     118            << std::setw(10) << "X(mm)" << " "
118            << std::setw(10) << "Y(mm)" << " "     119            << std::setw(10) << "Y(mm)" << " "  
119            << std::setw(10) << "Z(mm)" << " "     120            << std::setw(10) << "Z(mm)" << " "
120            << std::setw( 7) << " N_x " << " "     121            << std::setw( 7) << " N_x " << " "
121            << std::setw( 7) << " N_y " << " "     122            << std::setw( 7) << " N_y " << " "
122            << std::setw( 7) << " N_z " << " "     123            << std::setw( 7) << " N_z " << " " ;
123     os << std::setw( 7) << " Delta|N|" << " "     124     os << std::setw( 7) << " Delta|N|" << " "
124            << std::setw( 9) << "StepLen" << "     125            << std::setw( 9) << "StepLen" << " "  
125            << std::setw(12) << "StartSafety" <    126            << std::setw(12) << "StartSafety" << " "  
126            << std::setw( 9) << "PhsStep" << "     127            << std::setw( 9) << "PhsStep" << " ";  
127     os << G4endl;                                 128     os << G4endl;
128     os.precision(oldprc);                         129     os.precision(oldprc);
129   }                                               130   }
130   if((stepNo == 0) && (verboseLevel <=3))         131   if((stepNo == 0) && (verboseLevel <=3))
131   {                                               132   {
132     // Recurse to print the start values          133     // Recurse to print the start values
133     //                                            134     //
134     printStatus( StartFT, StartFT, -1.0, safet    135     printStatus( StartFT, StartFT, -1.0, safety, -1, os, verboseLevel);
135   }                                               136   }
136   if( verboseLevel <= 3 )                         137   if( verboseLevel <= 3 )
137   {                                               138   {
138     if( stepNo >= 0)                              139     if( stepNo >= 0)
139     {                                             140     {
140        os << std::setw( 4) << stepNo << " ";      141        os << std::setw( 4) << stepNo << " ";
141     }                                             142     }
142     else                                          143     else
143     {                                             144     {
144        os << std::setw( 5) << "Start" ;           145        os << std::setw( 5) << "Start" ;
145     }                                             146     }
146     oldprc = os.precision(8);                     147     oldprc = os.precision(8);
147     os << std::setw(10) << CurrentFT.GetCurveL    148     os << std::setw(10) << CurrentFT.GetCurveLength() << " "; 
148     os << std::setw(10) << CurrentPosition.x()    149     os << std::setw(10) << CurrentPosition.x() << " "
149            << std::setw(10) << CurrentPosition    150            << std::setw(10) << CurrentPosition.y() << " "
150            << std::setw(10) << CurrentPosition    151            << std::setw(10) << CurrentPosition.z() << " ";
151     os.precision(4);                              152     os.precision(4);
152     os << std::setw( 7) << CurrentUnitVelocity    153     os << std::setw( 7) << CurrentUnitVelocity.x() << " "
153            << std::setw( 7) << CurrentUnitVelo    154            << std::setw( 7) << CurrentUnitVelocity.y() << " "
154            << std::setw( 7) << CurrentUnitVelo    155            << std::setw( 7) << CurrentUnitVelocity.z() << " ";
155     os.precision(3);                              156     os.precision(3); 
156     os << std::setw( 7)                           157     os << std::setw( 7)
157            << CurrentFT.GetMomentum().mag()- S    158            << CurrentFT.GetMomentum().mag()- StartFT.GetMomentum().mag()
158            << " ";                                159            << " "; 
159     os << std::setw( 9) << step_len << " ";       160     os << std::setw( 9) << step_len << " "; 
160     os << std::setw(12) << safety << " ";         161     os << std::setw(12) << safety << " ";
161     if( requestStep != -1.0 )                     162     if( requestStep != -1.0 )
162     {                                             163     {
163       os << std::setw( 9) << requestStep << "     164       os << std::setw( 9) << requestStep << " ";
164     }                                             165     }
165     else                                          166     else
166     {                                             167     {
167       os << std::setw( 9) << "Init/NotKnown" <    168       os << std::setw( 9) << "Init/NotKnown" << " "; 
168     }                                             169     }
169     os << G4endl;                                 170     os << G4endl;
170     os.precision(oldprc);                         171     os.precision(oldprc);
171   }                                               172   }
172   else // if( verboseLevel > 3 )                  173   else // if( verboseLevel > 3 )
173   {                                               174   {
174     //  Multi-line output                         175     //  Multi-line output
175                                                   176        
176     os << "Step taken was " << step_len           177     os << "Step taken was " << step_len  
177            << " out of PhysicalStep= " <<  req    178            << " out of PhysicalStep= " <<  requestStep << G4endl;
178     os << "Final safety is: " << safety << G4e    179     os << "Final safety is: " << safety << G4endl;
179     os << "Chord length = " << (CurrentPositio    180     os << "Chord length = " << (CurrentPosition-StartPosition).mag()
180            << G4endl;                             181            << G4endl;
181     os << G4endl;                                 182     os << G4endl; 
182   }                                               183   }
183 }                                                 184 }
184                                                   185 
185 //////////////////////////////////////////////    186 ///////////////////////////////////////////////////////////////////////////
186 //                                                187 //
187 // ReEstimateEndPoint.                            188 // ReEstimateEndPoint.
188 //                                                189 //
189 G4FieldTrack G4VIntersectionLocator::             190 G4FieldTrack G4VIntersectionLocator::
190 ReEstimateEndpoint( const G4FieldTrack& Curren    191 ReEstimateEndpoint( const G4FieldTrack& CurrentStateA,  
191                     const G4FieldTrack& Estima    192                     const G4FieldTrack& EstimatedEndStateB,
                                                   >> 193 //                        bool &        recalculated)
192                           G4double      , // l    194                           G4double      , // linearDistSq,  // NOT used
193                           G4double             << 195                           G4double      ) // curveDist )    // NOT used
194 #ifdef G4DEBUG_FIELD                           << 
195   curveDist                                    << 
196 #endif                                         << 
197                                    )           << 
198 {                                                 196 {  
199   G4FieldTrack newEndPoint( CurrentStateA );      197   G4FieldTrack newEndPoint( CurrentStateA );
200   auto integrDriver = GetChordFinderFor()->Get << 198   G4MagInt_Driver* integrDriver = GetChordFinderFor()->GetIntegrationDriver(); 
201                                                   199 
202   G4FieldTrack retEndPoint( CurrentStateA );      200   G4FieldTrack retEndPoint( CurrentStateA );
203   G4bool goodAdvance;                             201   G4bool goodAdvance;
204   G4int  itrial = 0;                           << 202   G4int  itrial=0;
205   const G4int no_trials = 20;                  << 203   const G4int no_trials=20;
206                                                   204 
207                                                   205 
208   G4double endCurveLen= EstimatedEndStateB.Get    206   G4double endCurveLen= EstimatedEndStateB.GetCurveLength();
209                                                   207 
210   do  // Loop checking, 07.10.2016, JA         << 208   do  // Loop checking, 07.10.2016, J.Apostolakis
211   {                                               209   {
212     G4double currentCurveLen = newEndPoint.Get << 210     G4double currentCurveLen= newEndPoint.GetCurveLength();
213     G4double advanceLength = endCurveLen - cur << 211     G4double advanceLength= endCurveLen - currentCurveLen ; 
214     if (std::abs(advanceLength)<kCarTolerance)    212     if (std::abs(advanceLength)<kCarTolerance)
215     {                                             213     {
216       goodAdvance=true;                           214       goodAdvance=true;
217     }                                             215     }
218     else                                          216     else
219     {                                             217     {
220       goodAdvance = integrDriver->AccurateAdva << 218       goodAdvance= integrDriver->AccurateAdvance(newEndPoint, advanceLength,
221                                                << 219                                      GetEpsilonStepFor());
222     }                                          << 220      }
223   }                                               221   }
224   while( !goodAdvance && (++itrial < no_trials    222   while( !goodAdvance && (++itrial < no_trials) );
225                                                   223 
226   if( goodAdvance )                               224   if( goodAdvance )
227   {                                               225   {
228     retEndPoint = newEndPoint;                    226     retEndPoint = newEndPoint; 
229   }                                               227   }
230   else                                            228   else
231   {                                               229   {
232     retEndPoint = EstimatedEndStateB; // Could    230     retEndPoint = EstimatedEndStateB; // Could not improve without major work !!
233   }                                               231   }
234                                                   232 
235   //  All the work is done                        233   //  All the work is done
236   //  below are some diagnostics only -- befor    234   //  below are some diagnostics only -- before the return!
237   //                                              235   // 
238   const G4String MethodName("G4VIntersectionLo    236   const G4String MethodName("G4VIntersectionLocator::ReEstimateEndpoint()");
239                                                   237 
240 #ifdef G4VERBOSE                                  238 #ifdef G4VERBOSE
241   G4int  latest_good_trials = 0;                  239   G4int  latest_good_trials = 0;
242   if( itrial > 1)                                 240   if( itrial > 1)
243   {                                               241   {
244     if( fVerboseLevel > 0 )                       242     if( fVerboseLevel > 0 )
245     {                                             243     {
246       G4cout << MethodName << " called - goodA    244       G4cout << MethodName << " called - goodAdv= " << goodAdvance
247              << " trials = " << itrial            245              << " trials = " << itrial
248              << " previous good= " << latest_g    246              << " previous good= " << latest_good_trials
249              << G4endl;                           247              << G4endl;
250     }                                             248     }
251     latest_good_trials = 0;                       249     latest_good_trials = 0; 
252   }                                               250   }
253   else                                            251   else
254   {                                               252   {   
255     ++latest_good_trials;                      << 253     latest_good_trials++; 
256   }                                               254   }
257 #endif                                            255 #endif
258                                                   256 
259 #ifdef G4DEBUG_FIELD                              257 #ifdef G4DEBUG_FIELD
260   G4double lengthDone = newEndPoint.GetCurveLe    258   G4double lengthDone = newEndPoint.GetCurveLength() 
261                       - CurrentStateA.GetCurve    259                       - CurrentStateA.GetCurveLength(); 
262   if( !goodAdvance )                              260   if( !goodAdvance )
263   {                                               261   {
264     if( fVerboseLevel >= 3 )                      262     if( fVerboseLevel >= 3 )
265     {                                             263     {
266       G4cout << MethodName << "> AccurateAdvan    264       G4cout << MethodName << "> AccurateAdvance failed " ;
267       G4cout << " in " << itrial << " integrat    265       G4cout << " in " << itrial << " integration trials/steps. " << G4endl;
268       G4cout << " It went only " << lengthDone    266       G4cout << " It went only " << lengthDone << " instead of " << curveDist
269              << " -- a difference of " << curv    267              << " -- a difference of " << curveDist - lengthDone  << G4endl;
270       G4cout << " ReEstimateEndpoint> Reset en    268       G4cout << " ReEstimateEndpoint> Reset endPoint to original value!"
271              << G4endl;                           269              << G4endl;
272     }                                             270     }
273   }                                               271   }
274   G4double linearDist = ( EstimatedEndStateB.G    272   G4double linearDist = ( EstimatedEndStateB.GetPosition() 
275                       - CurrentStateA.GetPosit    273                       - CurrentStateA.GetPosition() ).mag(); 
276   static G4int noInaccuracyWarnings = 0;          274   static G4int noInaccuracyWarnings = 0; 
277   G4int maxNoWarnings = 10;                       275   G4int maxNoWarnings = 10;
278   if (  (noInaccuracyWarnings < maxNoWarnings     276   if (  (noInaccuracyWarnings < maxNoWarnings ) 
279        || (fVerboseLevel > 1) )                   277        || (fVerboseLevel > 1) )
280     {                                             278     {
281       G4ThreeVector move = newEndPoint.GetPosi    279       G4ThreeVector move = newEndPoint.GetPosition()
282                          - EstimatedEndStateB.    280                          - EstimatedEndStateB.GetPosition();
283       std::ostringstream message;                 281       std::ostringstream message;
284       message.precision(12);                      282       message.precision(12);
285       message << " Integration inaccuracy requ    283       message << " Integration inaccuracy requires" 
286               << " an adjustment in the step's    284               << " an adjustment in the step's endpoint."  << G4endl
287               << "   Two mid-points are furthe    285               << "   Two mid-points are further apart than their"
288               << " curve length difference"       286               << " curve length difference"                << G4endl 
289               << "   Dist = "       << linearD    287               << "   Dist = "       << linearDist
290               << " curve length = " << curveDi    288               << " curve length = " << curveDist             << G4endl; 
291       message << " Correction applied is " <<     289       message << " Correction applied is " << move.mag() << G4endl
292               << "  Old Estimated B position=     290               << "  Old Estimated B position= "
293               << EstimatedEndStateB.GetPositio    291               << EstimatedEndStateB.GetPosition() << G4endl
294               << "  Recalculated    Position=     292               << "  Recalculated    Position= "
295               << newEndPoint.GetPosition() <<     293               << newEndPoint.GetPosition() << G4endl
296               << "   Change ( new - old )   =     294               << "   Change ( new - old )   = " << move;
297       G4Exception("G4VIntersectionLocator::ReE    295       G4Exception("G4VIntersectionLocator::ReEstimateEndpoint()",
298                   "GeomNav1002", JustWarning,     296                   "GeomNav1002", JustWarning, message);
299     }                                             297     }
300 /*                                             << 
301 #else                                             298 #else
302   // Statistics on the RMS value of the correc    299   // Statistics on the RMS value of the corrections
303                                                   300 
304   static G4ThreadLocal G4int noCorrections = 0 << 301   static G4ThreadLocal G4int    noCorrections=0;
305   ++noCorrections;                             << 302   static G4ThreadLocal G4double sumCorrectionsSq = 0;
                                                   >> 303   noCorrections++; 
306   if( goodAdvance )                               304   if( goodAdvance )
307   {                                               305   {
308     static G4ThreadLocal G4double sumCorrectio << 
309     sumCorrectionsSq += (EstimatedEndStateB.Ge    306     sumCorrectionsSq += (EstimatedEndStateB.GetPosition() - 
310                          newEndPoint.GetPositi    307                          newEndPoint.GetPosition()).mag2();
311   }                                               308   }
312 */                                             << 
313 #endif                                            309 #endif
314                                                   310 
315   return retEndPoint;                             311   return retEndPoint;
316 }                                                 312 }
317                                                   313 
318                                                   314 
319 //////////////////////////////////////////////    315 ///////////////////////////////////////////////////////////////////////////
320 //                                                316 //
321 // ReEstimateEndPoint.                            317 // ReEstimateEndPoint.
322 //                                                318 //
323 //   The following values are returned in curv    319 //   The following values are returned in curveError 
324 //       0: Normal - no problem                   320 //       0: Normal - no problem
325 //       1: Unexpected co-incidence - milder m    321 //       1: Unexpected co-incidence - milder mixup
326 //       2: Real mixup - EndB is NOT past Star    322 //       2: Real mixup - EndB is NOT past StartA  
327 //            ( ie. StartA's curve-lengh is bi    323 //            ( ie. StartA's curve-lengh is bigger than EndB's)
328                                                   324 
329                                                   325 
330 G4bool G4VIntersectionLocator::                   326 G4bool G4VIntersectionLocator::
331 CheckAndReEstimateEndpoint( const G4FieldTrack    327 CheckAndReEstimateEndpoint( const G4FieldTrack& CurrentStartA,  
332                             const G4FieldTrack    328                             const G4FieldTrack& EstimatedEndB,
333                                   G4FieldTrack    329                                   G4FieldTrack& RevisedEndPoint,
334                                   G4int&       << 330                                   G4int &       curveError)
335 {                                                 331 {
336   G4double linDistSq, curveDist;                  332   G4double linDistSq, curveDist; 
337                                                   333 
338   G4bool recalculated = false;                 << 334   G4bool recalculated= false;
339   curveError= 0;                                  335   curveError= 0;
340                                                   336 
341   linDistSq = ( EstimatedEndB.GetPosition()       337   linDistSq = ( EstimatedEndB.GetPosition() 
342               - CurrentStartA.GetPosition() ). << 338                                - CurrentStartA.GetPosition() ).mag2(); 
343   curveDist = EstimatedEndB.GetCurveLength()      339   curveDist = EstimatedEndB.GetCurveLength()
344             - CurrentStartA.GetCurveLength();  << 340                                - CurrentStartA.GetCurveLength();
345   if(  (curveDist>=0.0)                           341   if(  (curveDist>=0.0) 
346      && (curveDist*curveDist *(1.0+2.0*fiEpsil    342      && (curveDist*curveDist *(1.0+2.0*fiEpsilonStep ) < linDistSq ) )
347   {                                               343   {
348     G4FieldTrack newEndPointFT = EstimatedEndB << 344     // G4FieldTrack oldPointVelB = EstimatedEndB; 
                                                   >> 345     G4FieldTrack newEndPointFT= EstimatedEndB;  // Unused
349                                                   346 
350     if (curveDist>0.0)                            347     if (curveDist>0.0) 
351     {                                             348     {
352        // Re-integrate to obtain a new B          349        // Re-integrate to obtain a new B
353        RevisedEndPoint = ReEstimateEndpoint( C << 350        RevisedEndPoint= ReEstimateEndpoint( CurrentStartA,
354                                              E << 351                                             EstimatedEndB,
355                                              l << 352                                             linDistSq,    
356                                              c << 353                                             curveDist );
357        recalculated = true;                       354        recalculated = true;
358     }                                             355     }
359     else                                          356     else
360     {                                             357     {
361        // Zero length -> no advance!              358        // Zero length -> no advance!
362        newEndPointFT = CurrentStartA;          << 359        newEndPointFT= CurrentStartA;
363        recalculated = true;                       360        recalculated = true;
364        curveError = 1;  // Unexpected co-incid    361        curveError = 1;  // Unexpected co-incidence - milder mixup
365                                                   362 
366        G4Exception("G4MultiLevelLocator::Estim    363        G4Exception("G4MultiLevelLocator::EstimateIntersectionPoint()",
367            "GeomNav1002", JustWarning,            364            "GeomNav1002", JustWarning, 
368            "A & B are at equal distance in 2nd    365            "A & B are at equal distance in 2nd half. A & B will coincide." );
369     }                                             366     }
370   }                                               367   }
371                                                   368 
372   // Sanity check                                 369   // Sanity check
373   //                                              370   //
374   if( curveDist < 0.0 )                           371   if( curveDist < 0.0 )
375   {                                               372   {
                                                   >> 373     // clean = false;
376     curveError = 2;  //  Real mixup               374     curveError = 2;  //  Real mixup
377   }                                               375   }
378   return recalculated;                            376   return recalculated;
379 }                                                 377 }
380                                                   378 
381 //////////////////////////////////////////////    379 ///////////////////////////////////////////////////////////////////////////
382 //                                                380 //
383 // Method for finding SurfaceNormal of Interse    381 // Method for finding SurfaceNormal of Intersecting Solid 
384 //                                                382 //
385 G4ThreeVector G4VIntersectionLocator::            383 G4ThreeVector G4VIntersectionLocator::
386 GetLocalSurfaceNormal(const G4ThreeVector& Cur    384 GetLocalSurfaceNormal(const G4ThreeVector& CurrentE_Point, G4bool& validNormal)
387 {                                                 385 {
388   G4ThreeVector Normal(G4ThreeVector(0.0,0.0,0    386   G4ThreeVector Normal(G4ThreeVector(0.0,0.0,0.0));
389   G4VPhysicalVolume* located;                     387   G4VPhysicalVolume* located;
390                                                   388 
391   validNormal = false;                            389   validNormal = false;
392   fHelpingNavigator->SetWorldVolume(GetNavigat    390   fHelpingNavigator->SetWorldVolume(GetNavigatorFor()->GetWorldVolume());
393   located = fHelpingNavigator->LocateGlobalPoi    391   located = fHelpingNavigator->LocateGlobalPointAndSetup( CurrentE_Point );
394                                                   392 
395   delete fpTouchable;                             393   delete fpTouchable;
396   fpTouchable = fHelpingNavigator->CreateTouch    394   fpTouchable = fHelpingNavigator->CreateTouchableHistory();
397                                                   395 
398   // To check if we can use GetGlobalExitNorma    396   // To check if we can use GetGlobalExitNormal() 
399   //                                              397   //
400   G4ThreeVector localPosition = fpTouchable->G    398   G4ThreeVector localPosition = fpTouchable->GetHistory()
401                 ->GetTopTransform().TransformP    399                 ->GetTopTransform().TransformPoint(CurrentE_Point);
402                                                   400 
403   // Issue: in the case of coincident surfaces    401   // Issue: in the case of coincident surfaces, this version does not recognise 
404   //        which side you are located onto (c    402   //        which side you are located onto (can return vector with wrong sign.)
405   // TO-DO: use direction (of chord) to identi    403   // TO-DO: use direction (of chord) to identify volume we will be "entering"
406                                                   404 
407   if( located != nullptr)                      << 405   if( located != 0)
408   {                                               406   { 
409     G4LogicalVolume* pLogical= located->GetLog    407     G4LogicalVolume* pLogical= located->GetLogicalVolume(); 
410     G4VSolid*        pSolid;                      408     G4VSolid*        pSolid; 
411                                                   409 
412     if( (pLogical != nullptr) && ( (pSolid=pLo << 410     if( (pLogical != 0) && ( (pSolid=pLogical->GetSolid()) !=0 )  )
413     {                                             411     {
                                                   >> 412       // G4bool     goodPoint,    nearbyPoint;   
                                                   >> 413       // G4int   numGoodPoints,   numNearbyPoints;  // --> use for stats
414       if ( ( pSolid->Inside(localPosition)==kS    414       if ( ( pSolid->Inside(localPosition)==kSurface )
415         || ( pSolid->DistanceToOut(localPositi << 415            || ( pSolid->DistanceToOut(localPosition) < 1000.0 * kCarTolerance )
                                                   >> 416          )
416       {                                           417       {
417         Normal = pSolid->SurfaceNormal(localPo    418         Normal = pSolid->SurfaceNormal(localPosition);
418         validNormal = true;                       419         validNormal = true;
419                                                   420 
420 #ifdef G4DEBUG_FIELD                              421 #ifdef G4DEBUG_FIELD
421         if( std::fabs(Normal.mag2() - 1.0 ) >     422         if( std::fabs(Normal.mag2() - 1.0 ) > CLHEP::perThousand) 
422         {                                         423         {
423           G4cerr << "PROBLEM in G4VIntersectio    424           G4cerr << "PROBLEM in G4VIntersectionLocator::GetLocalSurfaceNormal."
424                  << G4endl;                       425                  << G4endl;
425           G4cerr << "  Normal is not unit - ma    426           G4cerr << "  Normal is not unit - mag=" << Normal.mag() << G4endl; 
426           G4cerr << "  at trial local point "     427           G4cerr << "  at trial local point " << CurrentE_Point << G4endl;
427           G4cerr <<  "  Solid is " << *pSolid     428           G4cerr <<  "  Solid is " << *pSolid << G4endl;
428         }                                         429         }
429 #endif                                            430 #endif
430       }                                           431       }
431     }                                             432     }
432   }                                               433   }
433   return Normal;                                  434   return Normal;
434 }                                                 435 }
435                                                   436 
436 //////////////////////////////////////////////    437 ///////////////////////////////////////////////////////////////////////////
437 //                                                438 //
438 // Adjustment of Found Intersection               439 // Adjustment of Found Intersection
439 //                                                440 //
440 G4bool G4VIntersectionLocator::                   441 G4bool G4VIntersectionLocator::
441 AdjustmentOfFoundIntersection( const G4ThreeVe    442 AdjustmentOfFoundIntersection( const G4ThreeVector& CurrentA_Point,
442                                const G4ThreeVe    443                                const G4ThreeVector& CurrentE_Point, 
443                                const G4ThreeVe    444                                const G4ThreeVector& CurrentF_Point,
444                                const G4ThreeVe    445                                const G4ThreeVector& MomentumDir,
445                                const G4bool       446                                const G4bool         IntersectAF,
446                                      G4ThreeVe    447                                      G4ThreeVector& IntersectionPoint,  // I/O
447                                      G4double&    448                                      G4double&      NewSafety,          // I/O 
448                                      G4double&    449                                      G4double&      fPreviousSafety,    // I/O
449                                      G4ThreeVe    450                                      G4ThreeVector& fPreviousSftOrigin )// I/O
450 {                                                 451 {     
451   G4double dist,lambda;                           452   G4double dist,lambda;
452   G4ThreeVector Normal, NewPoint, Point_G;        453   G4ThreeVector Normal, NewPoint, Point_G;
453   G4bool goodAdjust = false, Intersects_FP = f << 454   G4bool goodAdjust=false, Intersects_FP=false, validNormal=false;
454                                                   455 
455   // Get SurfaceNormal of Intersecting Solid      456   // Get SurfaceNormal of Intersecting Solid
456   //                                              457   //
457   Normal = GetGlobalSurfaceNormal(CurrentE_Poi    458   Normal = GetGlobalSurfaceNormal(CurrentE_Point,validNormal);
458   if(!validNormal) { return false; }              459   if(!validNormal) { return false; }
459                                                   460 
460   // Intersection between Line and Plane          461   // Intersection between Line and Plane
461   //                                              462   //
462   G4double n_d_m = Normal.dot(MomentumDir);       463   G4double n_d_m = Normal.dot(MomentumDir);
463   if ( std::abs(n_d_m)>kCarTolerance )            464   if ( std::abs(n_d_m)>kCarTolerance )
464   {                                               465   {
465 #ifdef G4VERBOSE                                  466 #ifdef G4VERBOSE
466     if ( fVerboseLevel>1 )                        467     if ( fVerboseLevel>1 )
467     {                                             468     {
468       G4Exception("G4VIntersectionLocator::Adj << 469       G4cerr << "WARNING - "
469                   "GeomNav0003", JustWarning,  << 470              << "G4VIntersectionLocator::AdjustementOfFoundIntersection()"
470                   "No intersection. Parallels  << 471              << G4endl
                                                   >> 472              << "        No intersection. Parallels lines!" << G4endl;
471     }                                             473     }
472 #endif                                            474 #endif
473     lambda =- Normal.dot(CurrentF_Point-Curren    475     lambda =- Normal.dot(CurrentF_Point-CurrentE_Point)/n_d_m;
474                                                   476 
475     // New candidate for Intersection             477     // New candidate for Intersection
476     //                                            478     //
477     NewPoint = CurrentF_Point+lambda*MomentumD    479     NewPoint = CurrentF_Point+lambda*MomentumDir;
478                                                   480 
479     // Distance from CurrentF to Calculated In    481     // Distance from CurrentF to Calculated Intersection
480     //                                            482     //
481     dist = std::abs(lambda);                      483     dist = std::abs(lambda);
482                                                   484 
483     if ( dist<kCarTolerance*0.001 )  { return     485     if ( dist<kCarTolerance*0.001 )  { return false; }
484                                                   486 
485     // Calculation of new intersection point o    487     // Calculation of new intersection point on the path.
486     //                                            488     //
487     if ( IntersectAF )  //  First part interse    489     if ( IntersectAF )  //  First part intersects
488     {                                             490     {
489       G4double stepLengthFP;                      491       G4double stepLengthFP; 
490       G4ThreeVector Point_P = CurrentA_Point;     492       G4ThreeVector Point_P = CurrentA_Point;
491       GetNavigatorFor()->LocateGlobalPointWith    493       GetNavigatorFor()->LocateGlobalPointWithinVolume(Point_P);
492       Intersects_FP = IntersectChord( Point_P,    494       Intersects_FP = IntersectChord( Point_P, NewPoint, NewSafety,
493                                       fPreviou    495                                       fPreviousSafety, fPreviousSftOrigin,
494                                       stepLeng    496                                       stepLengthFP, Point_G );
495                                                   497 
496     }                                             498     }
497     else   // Second part intersects              499     else   // Second part intersects
498     {                                             500     {      
499       G4double stepLengthFP;                      501       G4double stepLengthFP; 
500       GetNavigatorFor()->LocateGlobalPointWith    502       GetNavigatorFor()->LocateGlobalPointWithinVolume(CurrentF_Point );
501       Intersects_FP = IntersectChord( CurrentF    503       Intersects_FP = IntersectChord( CurrentF_Point, NewPoint, NewSafety,
502                                       fPreviou    504                                       fPreviousSafety, fPreviousSftOrigin,
503                                       stepLeng    505                                       stepLengthFP, Point_G );
504     }                                             506     }
505     if ( Intersects_FP )                          507     if ( Intersects_FP )
506     {                                             508     {
507       goodAdjust = true;                          509       goodAdjust = true;
508       IntersectionPoint = Point_G;                510       IntersectionPoint = Point_G;              
509     }                                             511     }
510   }                                               512   }
511                                                   513 
512   return goodAdjust;                              514   return goodAdjust;
513 }                                                 515 }
514                                                   516 
515 //////////////////////////////////////////////    517 ///////////////////////////////////////////////////////////////////////////
516 //                                                518 //
517 // GetSurfaceNormal.                              519 // GetSurfaceNormal.
518 //                                                520 //
519 G4ThreeVector G4VIntersectionLocator::            521 G4ThreeVector G4VIntersectionLocator::
520 GetSurfaceNormal(const G4ThreeVector& CurrentI    522 GetSurfaceNormal(const G4ThreeVector& CurrentInt_Point,
521                        G4bool& validNormal)    << 523                        G4bool& validNormal) // const
522 {                                                 524 {
523   G4ThreeVector NormalAtEntry; // ( -10. , -10    525   G4ThreeVector NormalAtEntry; // ( -10. , -10., -10. ); 
524                                                   526 
525   G4ThreeVector NormalAtEntryLast, NormalAtEnt    527   G4ThreeVector NormalAtEntryLast, NormalAtEntryGlobal, diffNormals;
526   G4bool validNormalLast;                         528   G4bool validNormalLast; 
527                                                   529 
528   // Relies on a call to Navigator::ComputeSte    530   // Relies on a call to Navigator::ComputeStep in IntersectChord before
529   // this call                                    531   // this call
530   //                                              532   //
531   NormalAtEntryLast = GetLastSurfaceNormal( Cu    533   NormalAtEntryLast = GetLastSurfaceNormal( CurrentInt_Point, validNormalLast );
532     // May return valid=false in cases, includ    534     // May return valid=false in cases, including
533     //  - if the candidate volume was not foun    535     //  - if the candidate volume was not found (eg exiting world), or
534     //  - a replica was involved -- determined    536     //  - a replica was involved -- determined the step size.
535     // (This list is not complete.)               537     // (This list is not complete.) 
536                                                   538 
537 #ifdef G4DEBUG_FIELD                              539 #ifdef G4DEBUG_FIELD
538   if  ( validNormalLast                           540   if  ( validNormalLast
539    && ( std::fabs(NormalAtEntryLast.mag2() - 1    541    && ( std::fabs(NormalAtEntryLast.mag2() - 1.0) > perThousand ) )
540   {                                               542   {
541     std::ostringstream message;                   543     std::ostringstream message; 
542     message << "PROBLEM: Normal is not unit -     544     message << "PROBLEM: Normal is not unit - magnitude = "
543             << NormalAtEntryLast.mag() << G4en    545             << NormalAtEntryLast.mag() << G4endl; 
544     message << "   at trial intersection point    546     message << "   at trial intersection point " << CurrentInt_Point << G4endl;
545     message << "   Obtained from Get *Last* Su    547     message << "   Obtained from Get *Last* Surface Normal."; 
546     G4Exception("G4VIntersectionLocator::GetSu    548     G4Exception("G4VIntersectionLocator::GetSurfaceNormal()",
547                 "GeomNav1002", JustWarning, me    549                 "GeomNav1002", JustWarning, message);
548   }                                               550   }
549 #endif                                            551 #endif
550                                                   552 
551   if( validNormalLast )                           553   if( validNormalLast ) 
552   {                                               554   {
553     NormalAtEntry = NormalAtEntryLast;         << 555     NormalAtEntry=NormalAtEntryLast;  
554   }                                               556   }
555   validNormal = validNormalLast;               << 557   validNormal  = validNormalLast;
556                                                   558 
557   return NormalAtEntry;                           559   return NormalAtEntry;
558 }                                                 560 }
559                                                   561 
560 //////////////////////////////////////////////    562 ///////////////////////////////////////////////////////////////////////////
561 //                                                563 //
562 // GetGlobalSurfaceNormal.                        564 // GetGlobalSurfaceNormal.
563 //                                                565 //
564 G4ThreeVector G4VIntersectionLocator::            566 G4ThreeVector G4VIntersectionLocator::
565 GetGlobalSurfaceNormal(const G4ThreeVector& Cu    567 GetGlobalSurfaceNormal(const G4ThreeVector& CurrentE_Point,
566                              G4bool& validNorm    568                              G4bool& validNormal)
567 {                                                 569 {
568   G4ThreeVector localNormal = GetLocalSurfaceN << 570   G4ThreeVector     localNormal=
569   G4AffineTransform localToGlobal =          / << 571       GetLocalSurfaceNormal( CurrentE_Point, validNormal );
                                                   >> 572   G4AffineTransform localToGlobal=           //  Must use the same Navigator !!
570       fHelpingNavigator->GetLocalToGlobalTrans    573       fHelpingNavigator->GetLocalToGlobalTransform();
571   G4ThreeVector globalNormal = localToGlobal.T << 574   G4ThreeVector     globalNormal =
                                                   >> 575     localToGlobal.TransformAxis( localNormal );
572                                                   576 
573 #ifdef G4DEBUG_FIELD                              577 #ifdef G4DEBUG_FIELD
574   if( validNormal && ( std::fabs(globalNormal.    578   if( validNormal && ( std::fabs(globalNormal.mag2() - 1.0) > perThousand ) ) 
575   {                                               579   {
576     std::ostringstream message;                   580     std::ostringstream message; 
577     message << "******************************    581     message << "**************************************************************"
578             << G4endl;                            582             << G4endl;
579     message << " Bad Normal in G4VIntersection    583     message << " Bad Normal in G4VIntersectionLocator::GetGlobalSurfaceNormal "
580             << G4endl;                            584             << G4endl;
581     message << "  * Constituents: " << G4endl;    585     message << "  * Constituents: " << G4endl;
582     message << "    Local  Normal= " << localN    586     message << "    Local  Normal= " << localNormal << G4endl;
583     message << "    Transform: " << G4endl        587     message << "    Transform: " << G4endl
584             << "      Net Translation= " << lo    588             << "      Net Translation= " << localToGlobal.NetTranslation()
585             << G4endl                             589             << G4endl
586             << "      Net Rotation   = " << lo    590             << "      Net Rotation   = " << localToGlobal.NetRotation()
587             << G4endl;                            591             << G4endl;
588     message << "  * Result: " << G4endl;          592     message << "  * Result: " << G4endl;
589     message << "     Global Normal= " << local    593     message << "     Global Normal= " << localNormal << G4endl;
590     message << "****************************** << 594     message << "**************************************************************"
                                                   >> 595             << G4endl;
591     G4Exception("G4VIntersectionLocator::GetGl    596     G4Exception("G4VIntersectionLocator::GetGlobalSurfaceNormal()",
592                 "GeomNav1002", JustWarning, me    597                 "GeomNav1002", JustWarning, message);
593   }                                               598   }
594 #endif                                            599 #endif
595                                                   600 
596   return globalNormal;                            601   return globalNormal;
597 }                                                 602 }
598                                                   603 
599 //////////////////////////////////////////////    604 ///////////////////////////////////////////////////////////////////////////
600 //                                                605 //
601 // GetLastSurfaceNormal.                          606 // GetLastSurfaceNormal.
602 //                                                607 //
603 G4ThreeVector G4VIntersectionLocator::            608 G4ThreeVector G4VIntersectionLocator::
604 GetLastSurfaceNormal( const G4ThreeVector& int    609 GetLastSurfaceNormal( const G4ThreeVector& intersectPoint,
605                             G4bool& normalIsVa    610                             G4bool& normalIsValid) const
606 {                                                 611 {
607   G4ThreeVector normalVec;                        612   G4ThreeVector normalVec;
608   G4bool validNorm;                            << 613   G4bool        validNorm;
609   normalVec = fiNavigator->GetGlobalExitNormal    614   normalVec = fiNavigator->GetGlobalExitNormal( intersectPoint, &validNorm ); 
610   normalIsValid = validNorm;                   << 615   normalIsValid= validNorm;
611                                                   616 
612   return normalVec;                               617   return normalVec;
613 }                                                 618 }
614                                                   619 
615 //////////////////////////////////////////////    620 ///////////////////////////////////////////////////////////////////////////
616 //                                                621 //
617 // ReportTrialStep.                               622 // ReportTrialStep.
618 //                                                623 //
619 void G4VIntersectionLocator::ReportTrialStep(     624 void G4VIntersectionLocator::ReportTrialStep( G4int step_no, 
620                                         const     625                                         const G4ThreeVector& ChordAB_v,
621                                         const     626                                         const G4ThreeVector& ChordEF_v,
622                                         const     627                                         const G4ThreeVector& NewMomentumDir,
623                                         const     628                                         const G4ThreeVector& NormalAtEntry,
624                                                   629                                               G4bool validNormal )
625 {                                                 630 {
626   G4double ABchord_length  = ChordAB_v.mag();  << 631   G4double       ABchord_length  = ChordAB_v.mag(); 
627   G4double MomDir_dot_Norm = NewMomentumDir.do << 632   G4double       MomDir_dot_Norm = NewMomentumDir.dot( NormalAtEntry ) ;
628   G4double MomDir_dot_ABchord;                 << 633   G4double       MomDir_dot_ABchord;
629   MomDir_dot_ABchord = (1.0 / ABchord_length)  << 634   MomDir_dot_ABchord= (1.0 / ABchord_length) * NewMomentumDir.dot( ChordAB_v );
630                                                   635 
631   std::ostringstream  outStream;                  636   std::ostringstream  outStream; 
632   outStream << std::setw(6)  << " Step# "      << 637   outStream // G4cout 
                                                   >> 638     << std::setw(6)  << " Step# "
633     << std::setw(17) << " |ChordEF|(mag)" << "    639     << std::setw(17) << " |ChordEF|(mag)" << "  "
634     << std::setw(18) << " uMomentum.Normal" <<    640     << std::setw(18) << " uMomentum.Normal" << "  "
635     << std::setw(18) << " uMomentum.ABdir " <<    641     << std::setw(18) << " uMomentum.ABdir " << "  " 
636     << std::setw(16) << " AB-dist         " <<    642     << std::setw(16) << " AB-dist         " << " " 
637     << " Chord Vector (EF) "                      643     << " Chord Vector (EF) " 
638     << G4endl;                                    644     << G4endl;
639   outStream.precision(7);                         645   outStream.precision(7); 
640   outStream << " " << std::setw(5) << step_no  << 646   outStream  // G4cout 
                                                   >> 647     << " " << std::setw(5)  << step_no           
641     << " " << std::setw(18) << ChordEF_v.mag()    648     << " " << std::setw(18) << ChordEF_v.mag() 
642     << " " << std::setw(18) << MomDir_dot_Norm    649     << " " << std::setw(18) << MomDir_dot_Norm    
643     << " " << std::setw(18) << MomDir_dot_ABch    650     << " " << std::setw(18) << MomDir_dot_ABchord 
644     << " " << std::setw(12) << ABchord_length     651     << " " << std::setw(12) << ABchord_length     
645     << " " << ChordEF_v                           652     << " " << ChordEF_v
646     << G4endl;                                    653     << G4endl;
647   outStream << " MomentumDir= " << " " << NewM << 654   outStream  // G4cout
                                                   >> 655     << " MomentumDir= " << " " << NewMomentumDir 
648     << " Normal at Entry E= " << NormalAtEntry    656     << " Normal at Entry E= " << NormalAtEntry
649     << " AB chord =   " << ChordAB_v              657     << " AB chord =   " << ChordAB_v
650     << G4endl;                                    658     << G4endl;
651   G4cout << outStream.str();                   << 659   G4cout << outStream.str();  // ostr_verbose;
652                                                   660 
653   if( ( std::fabs(NormalAtEntry.mag2() - 1.0)     661   if( ( std::fabs(NormalAtEntry.mag2() - 1.0) > perThousand ) ) 
654   {                                               662   {
655     std::ostringstream message;                << 663     G4cerr << " PROBLEM in G4VIntersectionLocator::ReportTrialStep " << G4endl
656     message << "Normal is not unit - mag= " << << 664            << "         Normal is not unit - mag=" <<  NormalAtEntry.mag() 
657             << "         ValidNormalAtE = " << << 665            << "         ValidNormalAtE = " << validNormal
658     G4Exception("G4VIntersectionLocator::Repor << 666            << G4endl; 
659                 "GeomNav1002", JustWarning, me << 
660   }                                               667   }
661   return;                                         668   return; 
662 }                                                 669 }
663                                                   670 
664 //////////////////////////////////////////////    671 ///////////////////////////////////////////////////////////////////////////
665 //                                                672 //
666 // LocateGlobalPointWithinVolumeAndCheck.         673 // LocateGlobalPointWithinVolumeAndCheck.
667 //                                                674 //
668 // Locate point using navigator: updates state    675 // Locate point using navigator: updates state of Navigator
669 // By default, it assumes that the point is in    676 // By default, it assumes that the point is inside the current volume,
670 // and returns true.                              677 // and returns true.
671 // In check mode, checks whether the point is     678 // In check mode, checks whether the point is *inside* the volume.
672 //   If it is inside, it returns true             679 //   If it is inside, it returns true
673 //   If not, issues a warning and returns fals    680 //   If not, issues a warning and returns false.
674 //                                                681 //
675 G4bool G4VIntersectionLocator::                   682 G4bool G4VIntersectionLocator::
676 LocateGlobalPointWithinVolumeAndCheck( const G    683 LocateGlobalPointWithinVolumeAndCheck( const G4ThreeVector& position )
677 {                                                 684 {
678   G4bool good = true;                          << 685   G4bool good= true;
679   G4Navigator* nav = GetNavigatorFor();        << 686   G4Navigator* nav= GetNavigatorFor();
680   const G4String                                  687   const G4String
681   MethodName("G4VIntersectionLocator::LocateGl    688   MethodName("G4VIntersectionLocator::LocateGlobalPointWithinVolumeAndCheck()");
682                                                   689 
683   if( fCheckMode )                                690   if( fCheckMode )
684   {                                               691   {
685     G4bool navCheck= nav->IsCheckModeActive();    692     G4bool navCheck= nav->IsCheckModeActive();  // Recover original value
686     nav->CheckMode(true);                         693     nav->CheckMode(true);
687                                                   694 
688     // Identify the current volume                695     // Identify the current volume
689                                                   696     
690     G4TouchableHandle startTH= nav->CreateTouc << 697     G4TouchableHistoryHandle startTH= nav->CreateTouchableHistoryHandle();
691     G4VPhysicalVolume* motherPhys = startTH->G << 698     G4VPhysicalVolume* motherPhys=  startTH->GetVolume();
692     G4VSolid*          motherSolid = startTH-> << 699     G4VSolid*          motherSolid= startTH->GetSolid();
693     G4AffineTransform transform = nav->GetGlob    700     G4AffineTransform transform = nav->GetGlobalToLocalTransform();
694     G4int motherCopyNo = motherPhys->GetCopyNo << 701     // GetLocalToGlobalTransform();
                                                   >> 702     G4int  motherCopyNo= motherPhys->GetCopyNo();
695                                                   703     
696     // Let's check that the point is inside th    704     // Let's check that the point is inside the current solid
697     G4ThreeVector  localPosition = transform.T    705     G4ThreeVector  localPosition = transform.TransformPoint(position);
698     EInside        inMother = motherSolid->Ins << 706     EInside        inMother= motherSolid->Inside( localPosition );
699     if( inMother != kInside )                     707     if( inMother != kInside )
700     {                                             708     {
701       std::ostringstream message;              << 709       G4cerr << " ERROR in " << MethodName << " Position located "
702       message << "Position located "           << 710              << ( inMother == kSurface ? " on Surface " : " outside " )
703               << ( inMother == kSurface ? " on << 711              << "expected volume" << G4endl;
704               << "expected volume" << G4endl   << 712       G4double  safetyFromOut= motherSolid->DistanceToIn(localPosition);
705               << "  Safety (from Outside) = "  << 713       G4cerr << "   Safety (from Outside) = " << safetyFromOut  << G4endl;
706               << motherSolid->DistanceToIn(loc << 
707       G4Exception("G4VIntersectionLocator::Loc << 
708                   "GeomNav1002", JustWarning,  << 
709     }                                             714     }
710                                                   715     
711     // 1. Simple next step - quick relocation     716     // 1. Simple next step - quick relocation and check result.
712     // nav->LocateGlobalPointWithinVolume( pos    717     // nav->LocateGlobalPointWithinVolume( position );
713                                                   718     
714     // 2. Full relocation - to cross-check ans    719     // 2. Full relocation - to cross-check answer !
715     G4VPhysicalVolume* nextPhysical= nav->Loca    720     G4VPhysicalVolume* nextPhysical= nav->LocateGlobalPointAndSetup(position);
716     if(    (nextPhysical != motherPhys)           721     if(    (nextPhysical != motherPhys)
717         || (nextPhysical->GetCopyNo() != mothe    722         || (nextPhysical->GetCopyNo() != motherCopyNo )
718        )                                          723        )
719     {                                             724     {
720       G4Exception("G4VIntersectionLocator::Loc << 725       G4cerr << " ERROR in " << MethodName
721                   "GeomNav1002", JustWarning,  << 726              << " Position located outside expected volume" << G4endl;
722                   "Position located outside ex << 
723     }                                             727     }
724     nav->CheckMode(navCheck);  // Recover orig    728     nav->CheckMode(navCheck);  // Recover original value
725   }                                               729   }
726   else                                            730   else
727   {                                               731   {
728     nav->LocateGlobalPointWithinVolume( positi    732     nav->LocateGlobalPointWithinVolume( position );
729   }                                               733   }
730   return good;                                    734   return good;
731 }                                                 735 }
732                                                   736 
733 //////////////////////////////////////////////    737 ///////////////////////////////////////////////////////////////////////////
734 //                                                738 //
735 // LocateGlobalPointWithinVolumeCheckAndReport    739 // LocateGlobalPointWithinVolumeCheckAndReport.
736 //                                                740 //
737 void G4VIntersectionLocator::                     741 void G4VIntersectionLocator::
738 LocateGlobalPointWithinVolumeCheckAndReport( c    742 LocateGlobalPointWithinVolumeCheckAndReport( const G4ThreeVector& position,
739                                              c    743                                              const G4String& CodeLocationInfo,
740                                              G << 744                                              G4int CheckMode )
741 {                                                 745 {
742   // Save value of Check mode first               746   // Save value of Check mode first
743   G4bool oldCheck = GetCheckMode();            << 747   G4bool oldCheck= GetCheckMode();
744                                                   748   
745   G4bool ok = LocateGlobalPointWithinVolumeAnd << 749   G4bool ok= LocateGlobalPointWithinVolumeAndCheck( position );
746   if( !ok )                                       750   if( !ok )
747   {                                               751   {
748     std::ostringstream message;                << 752     G4cerr << " ERROR occured in Intersection Locator" << G4endl;
749     message << "Failed point location." << G4e << 753     G4cerr << "       Code Location info: " << CodeLocationInfo << G4endl;
750             << "   Code Location info: " << Co << 754     if( CheckMode > 1 ) {
751     G4Exception("G4VIntersectionLocator::Locat << 755       // Additional information
752                 "GeomNav1002", JustWarning, me << 756       
                                                   >> 757     }
753   }                                               758   }
754                                                   759   
755   SetCheckMode( oldCheck );                       760   SetCheckMode( oldCheck );
756 }                                                 761 }
757                                                   762 
758 //////////////////////////////////////////////    763 ///////////////////////////////////////////////////////////////////////////
759 //                                                764 //
760 // ReportReversedPoints.                          765 // ReportReversedPoints.
761 //                                                766 //
762 void G4VIntersectionLocator::                     767 void G4VIntersectionLocator::
763 ReportReversedPoints( std::ostringstream& msg,    768 ReportReversedPoints( std::ostringstream& msg,
764                       const G4FieldTrack& Star    769                       const G4FieldTrack& StartPointVel, 
765                       const G4FieldTrack& EndP    770                       const G4FieldTrack& EndPointVel,
766                             G4double NewSafety    771                             G4double NewSafety, G4double epsStep,
767                       const G4FieldTrack& A_Pt    772                       const G4FieldTrack& A_PtVel,
768                       const G4FieldTrack& B_Pt    773                       const G4FieldTrack& B_PtVel,
769                       const G4FieldTrack& SubS    774                       const G4FieldTrack& SubStart_PtVel,
770                       const G4ThreeVector& E_P    775                       const G4ThreeVector& E_Point,
771                       const G4FieldTrack& Appr    776                       const G4FieldTrack& ApproxIntersecPointV,
772                             G4int  substep_no,    777                             G4int  substep_no, G4int substep_no_p, G4int depth )
773 {                                                 778 {
774    // Expect that 'msg' can hold the name of t    779    // Expect that 'msg' can hold the name of the calling method
775                                                   780 
776    // FieldTrack 'points' A and B have been ta    781    // FieldTrack 'points' A and B have been tangled
777    // Whereas A should be before B, it is foun    782    // Whereas A should be before B, it is found that curveLen(B) < curveLen(A)
778    G4int verboseLevel= 5;                         783    G4int verboseLevel= 5; 
779    G4double curveDist = B_PtVel.GetCurveLength    784    G4double curveDist = B_PtVel.GetCurveLength() - A_PtVel.GetCurveLength();
780    G4VIntersectionLocator::printStatus( A_PtVe    785    G4VIntersectionLocator::printStatus( A_PtVel,  B_PtVel,
781                            -1.0, NewSafety,  s    786                            -1.0, NewSafety,  substep_no, msg, verboseLevel );
782    msg << "Error in advancing propagation." <<    787    msg << "Error in advancing propagation." << G4endl
783        << "   The final curve point is NOT fur << 788        << "        Point A (start) is " << A_PtVel  << G4endl
784        << "  than the original!" << G4endl     << 789        << "        Point B (end)   is " << B_PtVel << G4endl
785        << "   Going *backwards* from len(A) =  << 790        << "        Curve distance is " << curveDist << G4endl
786        << "  to len(B) = " << B_PtVel.GetCurve << 
787        << "      Curve distance is " << curveD << 
788        << G4endl                                  791        << G4endl
789        << "      Point A' (start) is " << A_Pt << 792        << "The final curve point is not further along"
790        << "      Point B' (end)   is " << B_Pt << 793        << " than the original!" << G4endl;
791    msg << "      fEpsStep= " << epsStep << G4e << 794    msg << " Value of fEpsStep= " << epsStep << G4endl;
792                                                << 795 
793    G4long oldprc = msg.precision(20);          << 796    G4int oldprc = msg.precision(20);
794    msg << " In full precision, the position, m << 797    msg << " Point A (Curve start) is " << StartPointVel << G4endl
795        << " ... are: " << G4endl;              << 798        << " Point B (Curve   end)   is " << EndPointVel << G4endl
796    msg << " Point A[0] (Curve   start) is " << << 799        << " Point A (Current start) is " << A_PtVel << G4endl
797        << " Point S    (Sub     start) is " << << 800        << " Point B (Current end)   is " << B_PtVel << G4endl
798        << " Point A'   (Current start) is " << << 801        << " Point S (Sub start)     is " << SubStart_PtVel
799        << " Point E    (Trial Point)   is " << << 802        << " Point E (Trial Point)   is " << E_Point << G4endl
800        << " Point F    (Intersection)  is " << << 803        << " Point F (Intersection)  is " << ApproxIntersecPointV 
801        << " Point B'   (Current end)   is " << << 
802        << " Point B[0] (Curve   end)   is " << << 
803        << G4endl                                  804        << G4endl
804        << " LocateIntersection parameters are     805        << " LocateIntersection parameters are : " << G4endl
805        << "      Substep no (total) = "  << su    806        << "      Substep no (total) = "  << substep_no << G4endl
806        << "      Substep no         = "  << su << 807        << "      Substep (depth= " << depth << substep_no_p;
807    msg.precision(oldprc);                         808    msg.precision(oldprc);
808 }                                                 809 }
809                                                   810 
810 //////////////////////////////////////////////    811 ///////////////////////////////////////////////////////////////////////////
811 //                                                812 //
812 // ReportProgress.                                813 // ReportProgress.
813 //                                                814 //
814 void G4VIntersectionLocator::ReportProgress( s    815 void G4VIntersectionLocator::ReportProgress( std::ostream& oss,
815                                     const G4Fi    816                                     const G4FieldTrack& StartPointVel, 
816                                     const G4Fi    817                                     const G4FieldTrack& EndPointVel,
817                                           G4in    818                                           G4int         substep_no, 
818                                     const G4Fi    819                                     const G4FieldTrack& A_PtVel,
819                                     const G4Fi    820                                     const G4FieldTrack& B_PtVel,
820                                           G4do    821                                           G4double      safetyLast,
821                                           G4in    822                                           G4int         depth )
822                                                   823 
823 {                                                 824 {
824   oss << "ReportProgress: Current status of in    825   oss << "ReportProgress: Current status of intersection search: " << G4endl;
825   if( depth > 0 ) { oss << " Depth= " << depth << 826   if( depth > 0 ) oss << " Depth= " << depth;
826   oss << " Substep no = " << substep_no << G4e    827   oss << " Substep no = " << substep_no << G4endl;
827   G4int  verboseLevel = 5;                        828   G4int  verboseLevel = 5; 
                                                   >> 829   
                                                   >> 830   // printStatus args: (FT0, FT1, dRequestStep, dSafety, iStepNum, os, iVerb);
828   G4double safetyPrev = -1.0;  // Add as argum    831   G4double safetyPrev = -1.0;  // Add as argument ?
829                                                   832 
830   printStatus( StartPointVel, EndPointVel, -1.    833   printStatus( StartPointVel, EndPointVel, -1.0, -1.0, -1, 
831               oss, verboseLevel);                 834               oss, verboseLevel);  
832   oss << " * Start and end-point of requested     835   oss << " * Start and end-point of requested Step:" << G4endl;
833   oss << " ** State of point A: ";                836   oss << " ** State of point A: "; 
834   printStatus( A_PtVel, A_PtVel, -1.0, safetyP    837   printStatus( A_PtVel, A_PtVel, -1.0, safetyPrev, substep_no-1,
835                oss, verboseLevel);                838                oss, verboseLevel);  
836   oss << " ** State of point B: ";                839   oss << " ** State of point B: "; 
837   printStatus( A_PtVel, B_PtVel, -1.0, safetyL    840   printStatus( A_PtVel, B_PtVel, -1.0, safetyLast, substep_no, 
838                oss, verboseLevel);                841                oss, verboseLevel);
839 }                                                 842 }
840                                                   843 
841 //////////////////////////////////////////////    844 ///////////////////////////////////////////////////////////////////////////
842 //                                                845 //
843 // ReportImmediateHit.                            846 // ReportImmediateHit.
844 //                                                847 //
845 void                                              848 void
846 G4VIntersectionLocator::ReportImmediateHit( co    849 G4VIntersectionLocator::ReportImmediateHit( const char*          MethodName, 
847                                             co    850                                             const G4ThreeVector& StartPosition, 
848                                             co    851                                             const G4ThreeVector& TrialPoint, 
849                                                   852                                                   G4double       tolerance,
850                                             un    853                                             unsigned long int    numCalls )
851 {                                                 854 {
852   static G4ThreadLocal unsigned int occurredOn    855   static G4ThreadLocal unsigned int occurredOnTop= 0;
853   static G4ThreadLocal G4ThreeVector* ptrLast  << 856   static G4ThreadLocal G4ThreeVector *ptrLast= 0;
854   if( ptrLast == nullptr )                     << 857   if( !ptrLast )
855   {                                               858   {
856      ptrLast= new G4ThreeVector( DBL_MAX, DBL_    859      ptrLast= new G4ThreeVector( DBL_MAX, DBL_MAX, DBL_MAX );
857      G4AutoDelete::Register(ptrLast);             860      G4AutoDelete::Register(ptrLast);
858   }                                               861   }
859   G4ThreeVector &lastStart= *ptrLast;             862   G4ThreeVector &lastStart= *ptrLast;
860                                                   863 
861   if( (TrialPoint - StartPosition).mag2() < to    864   if( (TrialPoint - StartPosition).mag2() < tolerance*tolerance) 
862   {                                               865   {
863      static G4ThreadLocal unsigned int numUnmo << 866      static G4ThreadLocal unsigned int numUnmoved= 0;
864      static G4ThreadLocal unsigned int numStil << 867      static G4ThreadLocal unsigned int numStill= 0;    // Still at same point
865                                                   868 
866      G4cout << "Intersection F == start A in "    869      G4cout << "Intersection F == start A in " << MethodName;
867      G4cout << "Start Point: " << StartPositio    870      G4cout << "Start Point: " << StartPosition << G4endl;
868      G4cout << " Start-Trial: " << TrialPoint  << 871      // G4cout << "Trial Point: " << TrialPoint << G4endl;
                                                   >> 872      G4cout << " Start-Trial: " << TrialPoint - StartPosition; // << G4endl;
869      G4cout << " Start-last: " << StartPositio    873      G4cout << " Start-last: " << StartPosition - lastStart;
870                                                   874 
871      if( (StartPosition - lastStart).mag() < t    875      if( (StartPosition - lastStart).mag() < tolerance )
872      {                                            876      {
873         // We are at position of last 'Start'     877         // We are at position of last 'Start' position - ie unmoved
874         ++numUnmoved;                             878         ++numUnmoved;
875         ++numStill;                               879         ++numStill; 
876         G4cout << " { Unmoved: "  << " still#=    880         G4cout << " { Unmoved: "  << " still#= " << numStill
877                << " total # = " << numUnmoved     881                << " total # = " << numUnmoved << " } - ";
878      }                                            882      }
879      else                                         883      else
880      {                                            884      {
881         numStill = 0;                             885         numStill = 0; 
882      }                                            886      }
883      G4cout << " Occurred: " << ++occurredOnTo << 887      G4cout << " Occured: " << ++occurredOnTop;  
884      G4cout <<  " out of total calls= " << num    888      G4cout <<  " out of total calls= " << numCalls;
885      G4cout << G4endl;                            889      G4cout << G4endl;
886      lastStart = StartPosition;                   890      lastStart = StartPosition;
887   }                                               891   }
888 }  // End of ReportImmediateHit()                 892 }  // End of ReportImmediateHit() 
889                                                   893