Geant4_10
G4PathFinder.cc
Go to the documentation of this file.
1 //
2 // ********************************************************************
3 // * License and Disclaimer *
4 // * *
5 // * The Geant4 software is copyright of the Copyright Holders of *
6 // * the Geant4 Collaboration. It is provided under the terms and *
7 // * conditions of the Geant4 Software License, included in the file *
8 // * LICENSE and available at http://cern.ch/geant4/license . These *
9 // * include a list of copyright holders. *
10 // * *
11 // * Neither the authors of this software system, nor their employing *
12 // * institutes,nor the agencies providing financial support for this *
13 // * work make any representation or warranty, express or implied, *
14 // * regarding this software system or assume any liability for its *
15 // * use. Please see the license in the file LICENSE and URL above *
16 // * for the full disclaimer and the limitation of liability. *
17 // * *
18 // * This code implementation is the result of the scientific and *
19 // * technical work of the GEANT4 collaboration. *
20 // * By using, copying, modifying or distributing the software (or *
21 // * any work based on the software) you agree to acknowledge its *
22 // * use in resulting scientific publications, and indicate your *
23 // * acceptance of all terms of the Geant4 Software license. *
24 // ********************************************************************
25 //
26 //
27 // $Id: G4PathFinder.cc 73734 2013-09-09 15:01:46Z gcosmo $
28 // GEANT4 tag $ Name: $
29 //
30 // class G4PathFinder Implementation
31 //
32 // Original author: John Apostolakis, April 2006
33 //
34 // --------------------------------------------------------------------
35 
36 #include <iomanip>
37 
38 #include "G4PathFinder.hh"
39 
40 #include "G4SystemOfUnits.hh"
41 #include "G4GeometryTolerance.hh"
42 #include "G4Navigator.hh"
43 #include "G4PropagatorInField.hh"
45 #include "G4MultiNavigator.hh"
46 #include "G4SafetyHelper.hh"
47 
48 // Initialise the static instance of the singleton
49 //
50 G4ThreadLocal G4PathFinder* G4PathFinder::fpPathFinder=0;
51 
52 // ----------------------------------------------------------------------------
53 // GetInstance()
54 //
55 // Retrieve the static instance of the singleton
56 //
58 {
59  if( ! fpPathFinder )
60  {
61  fpPathFinder = new G4PathFinder;
62  }
63  return fpPathFinder;
64 }
65 
66 // ----------------------------------------------------------------------------
67 // Constructor
68 //
70  : fEndState( G4ThreeVector(), G4ThreeVector(), 0., 0., 0., 0., 0.),
71  fFieldExertedForce(false),
72  fRelocatedPoint(true),
73  fLastStepNo(-1), fCurrentStepNo(-1),
74  fVerboseLevel(0)
75 {
76  fpMultiNavigator= new G4MultiNavigator();
77 
79  fpFieldPropagator = fpTransportManager->GetPropagatorInField();
80 
82 
83  fNoActiveNavigators= 0;
84  G4ThreeVector Big3Vector( kInfinity, kInfinity, kInfinity );
85  fLastLocatedPosition= Big3Vector;
86  fSafetyLocation= Big3Vector;
87  fPreSafetyLocation= Big3Vector;
88  fPreStepLocation= Big3Vector;
89 
90  fPreSafetyMinValue= -1.0;
91  fMinSafety_PreStepPt= -1.0;
92  fMinSafety_atSafLocation= -1.0;
93  fMinStep= -1.0;
94  fTrueMinStep= -1.0;
95  fPreStepCenterRenewed= false;
96  fNewTrack= false;
97  fNoGeometriesLimiting= 0;
98 
99  for( register int num=0; num< fMaxNav; ++num )
100  {
101  fpNavigator[num] = 0;
102  fLimitTruth[num] = false;
103  fLimitedStep[num] = kUndefLimited;
104  fCurrentStepSize[num] = -1.0;
105  fLocatedVolume[num] = 0;
106  fPreSafetyValues[num]= -1.0;
107  fCurrentPreStepSafety[num] = -1.0;
108  fNewSafetyComputed[num]= -1.0;
109  }
110 }
111 
112 // ----------------------------------------------------------------------------
113 // Destructor
114 //
116 {
117  delete fpMultiNavigator;
118  if (fpPathFinder) { delete fpPathFinder; fpPathFinder=0; }
119 }
120 
121 // ----------------------------------------------------------------------------
122 //
123 void
125 {
126  G4Navigator *navigatorForPropagation=0, *massNavigator=0;
127 
128  massNavigator= fpTransportManager->GetNavigatorForTracking();
129  if( enableChoice )
130  {
131  navigatorForPropagation= fpMultiNavigator;
132 
133  // Enable SafetyHelper to use PF
134  //
135  fpTransportManager->GetSafetyHelper()->EnableParallelNavigation(true);
136  }
137  else
138  {
139  navigatorForPropagation= massNavigator;
140 
141  // Disable SafetyHelper to use PF
142  //
143  fpTransportManager->GetSafetyHelper()->EnableParallelNavigation(false);
144  }
145  fpFieldPropagator->SetNavigatorForPropagating(navigatorForPropagation);
146 }
147 
148 // ----------------------------------------------------------------------------
149 //
150 G4double
151 G4PathFinder::ComputeStep( const G4FieldTrack &InitialFieldTrack,
152  G4double proposedStepLength,
153  G4int navigatorNo,
154  G4int stepNo, // find next step
155  G4double &pNewSafety, // for this geom
156  ELimited &limitedStep,
157  G4FieldTrack &EndState,
158  G4VPhysicalVolume* currentVolume)
159 {
160  G4double possibleStep= -1.0;
161 
162 #ifdef G4DEBUG_PATHFINDER
163  if( fVerboseLevel > 2 )
164  {
165  G4cout << " -------------------------" << G4endl;
166  G4cout << " G4PathFinder::ComputeStep - entered " << G4endl;
167  G4cout << " - stepNo = " << std::setw(4) << stepNo << " "
168  << " navigatorId = " << std::setw(2) << navigatorNo << " "
169  << " proposed step len = " << proposedStepLength << " " << G4endl;
170  G4cout << " PF::ComputeStep requested step "
171  << " from " << InitialFieldTrack.GetPosition()
172  << " dir " << InitialFieldTrack.GetMomentumDirection() << G4endl;
173  }
174 #endif
175 #ifdef G4VERBOSE
176  if( navigatorNo >= fNoActiveNavigators )
177  {
178  std::ostringstream message;
179  message << "Bad Navigator ID !" << G4endl
180  << " Requested Navigator ID = " << navigatorNo << G4endl
181  << " Number of active navigators = " << fNoActiveNavigators;
182  G4Exception("G4PathFinder::ComputeStep()", "GeomNav0002",
183  FatalException, message);
184  }
185 #endif
186 
187  if( fNewTrack || (stepNo != fLastStepNo) )
188  {
189  // This is a new track or a new step, so we must make the step
190  // ( else we can simply retrieve its results for this Navigator Id )
191 
192  G4FieldTrack currentState= InitialFieldTrack;
193 
194  fCurrentStepNo = stepNo;
195 
196  // Check whether a process shifted the position
197  // since the last step -- by physics processes
198  //
199  G4ThreeVector newPosition = InitialFieldTrack.GetPosition();
200  G4ThreeVector moveVector= newPosition - fLastLocatedPosition;
201  G4double moveLenSq= moveVector.mag2();
202  if( moveLenSq > kCarTolerance * kCarTolerance )
203  {
204  G4ThreeVector newDirection = InitialFieldTrack.GetMomentumDirection();
205 #ifdef G4DEBUG_PATHFINDER
206  if( fVerboseLevel > 2 )
207  {
208  G4double moveLen= std::sqrt( moveLenSq );
209  G4cout << " G4PathFinder::ComputeStep : Point moved since last step "
210  << " -- at step # = " << stepNo << G4endl
211  << " by " << moveLen << " to " << newPosition << G4endl;
212  }
213 #endif
214  MovePoint(); // Unintentional changed -- ????
215 
216  // Relocate to cope with this move -- else could abort !?
217  //
218  Locate( newPosition, newDirection );
219  }
220 
221  // Check whether the particle have an (EM) field force exerting upon it
222  //
223  G4double particleCharge= currentState.GetCharge();
224 
225  G4FieldManager* fieldMgr=0;
226  G4bool fieldExertsForce = false ;
227  if( (particleCharge != 0.0) )
228  {
229  fieldMgr= fpFieldPropagator->FindAndSetFieldManager( currentVolume );
230 
231  // Protect for case where field manager has no field (= field is zero)
232  //
233  fieldExertsForce = (fieldMgr != 0)
234  && (fieldMgr->GetDetectorField() != 0);
235  }
236  fFieldExertedForce = fieldExertsForce; // Store for use in later calls
237  // referring to this 'step'.
238 
239  fNoGeometriesLimiting= -1; // At start of track, no process limited step
240  if( fieldExertsForce )
241  {
242  DoNextCurvedStep( currentState, proposedStepLength, currentVolume );
243  //--------------
244  }else{
245  DoNextLinearStep( currentState, proposedStepLength );
246  //--------------
247  }
248  fLastStepNo= stepNo;
249 
250 #ifdef G4DEBUG_PATHFINDER
251  if ( (fNoGeometriesLimiting < 0)
252  || (fNoGeometriesLimiting > fNoActiveNavigators) )
253  {
254  std::ostringstream message;
255  message << "Number of geometries limiting the step not set." << G4endl
256  << " Number of geometries limiting step = "
257  << fNoGeometriesLimiting;
258  G4Exception("G4PathFinder::ComputeStep()",
259  "GeomNav0002", FatalException, message);
260  }
261 #endif
262  }
263 #ifdef G4DEBUG_PATHFINDER
264  else
265  {
266  if( proposedStepLength < fTrueMinStep ) // For 2nd+ geometry
267  {
268  std::ostringstream message;
269  message << "Problem in step size request." << G4endl
270  << " Error can be caused by incorrect process ordering."
271  << " Being requested to make a step which is shorter"
272  << " than the minimum Step " << G4endl
273  << " already computed for any Navigator/geometry during"
274  << " this tracking-step: " << G4endl
275  << " This can happen due to an error in process ordering."
276  << G4endl
277  << " Check that all physics processes are registered"
278  << G4endl
279  << " before all processes with a navigator/geometry."
280  << G4endl
281  << " If using pre-packaged physics list and/or"
282  << G4endl
283  << " functionality, please report this error."
284  << G4endl << G4endl
285  << " Additional information for problem: " << G4endl
286  << " Steps request/proposed = " << proposedStepLength
287  << G4endl
288  << " MinimumStep (true) = " << fTrueMinStep
289  << G4endl
290  << " MinimumStep (navraw) = " << fMinStep
291  << G4endl
292  << " Navigator raw return value" << G4endl
293  << " Requested step now = " << proposedStepLength
294  << G4endl
295  << " Difference min-req = "
296  << fTrueMinStep-proposedStepLength << G4endl
297  << " -- Step info> stepNo= " << stepNo
298  << " last= " << fLastStepNo
299  << " newTr= " << fNewTrack << G4endl;
300  G4Exception("G4PathFinder::ComputeStep()",
301  "GeomNav0003", FatalException, message);
302  }
303  else
304  {
305  // This is neither a new track nor a new step -- just another
306  // client accessing information for the current track, step
307  // We will simply retrieve the results of the synchronous
308  // stepping for this Navigator Id below.
309  //
310  if( fVerboseLevel > 1 )
311  {
312  G4cout << " G4P::CS -> Not calling DoNextLinearStep: "
313  << " stepNo= " << stepNo << " last= " << fLastStepNo
314  << " new= " << fNewTrack << " Step already done" << G4endl;
315  }
316  }
317  }
318 #endif
319 
320  fNewTrack= false;
321 
322  // Prepare the information to return
323 
324  pNewSafety = fCurrentPreStepSafety[ navigatorNo ];
325  limitedStep = fLimitedStep[ navigatorNo ];
326  fRelocatedPoint= false;
327 
328  possibleStep= std::min(proposedStepLength, fCurrentStepSize[ navigatorNo ]);
329  EndState = fEndState; // now corrected for smaller step, if needed
330 
331 #ifdef G4DEBUG_PATHFINDER
332  if( fVerboseLevel > 0 )
333  {
334  G4cout << " G4PathFinder::ComputeStep returns "
335  << fCurrentStepSize[ navigatorNo ]
336  << " for Navigator " << navigatorNo
337  << " Limited step = " << limitedStep
338  << " Safety(mm) = " << pNewSafety / mm
339  << G4endl;
340  }
341 #endif
342 
343  return possibleStep;
344 }
345 
346 // ----------------------------------------------------------------------
347 
348 void
350  const G4ThreeVector& direction,
351  G4VPhysicalVolume* massStartVol)
352 {
353  // Key purposes:
354  // - Check and cache set of active navigators
355  // - Reset state for new track
356 
357  G4int num=0;
358 
360  // Switch PropagatorInField to use MultiNavigator
361 
362  fpTransportManager->GetSafetyHelper()->InitialiseHelper();
363  // Reinitialise state of safety helper -- avoid problems with overlaps
364 
365  fNewTrack= true;
366  this->MovePoint(); // Signal further that the last status is wiped
367 
368  // Message the G4NavigatorPanel / Dispatcher to find active navigators
369  //
370  std::vector<G4Navigator*>::iterator pNavigatorIter;
371 
372  fNoActiveNavigators= fpTransportManager-> GetNoActiveNavigators();
373  if( fNoActiveNavigators > fMaxNav )
374  {
375  std::ostringstream message;
376  message << "Too many active Navigators / worlds." << G4endl
377  << " Transportation Manager has "
378  << fNoActiveNavigators << " active navigators." << G4endl
379  << " This is more than the number allowed = "
380  << fMaxNav << " !";
381  G4Exception("G4PathFinder::PrepareNewTrack()", "GeomNav0002",
382  FatalException, message);
383  }
384 
385  fpMultiNavigator->PrepareNavigators();
386  //------------------------------------
387 
388  pNavigatorIter= fpTransportManager->GetActiveNavigatorsIterator();
389  for( num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
390  {
391  // Keep information in C-array ... for creating touchables - at least
392 
393  fpNavigator[num] = *pNavigatorIter;
394  fLimitTruth[num] = false;
395  fLimitedStep[num] = kDoNot;
396  fCurrentStepSize[num] = 0.0;
397  fLocatedVolume[num] = 0;
398  }
399  fNoGeometriesLimiting= 0; // At start of track, no process limited step
400 
401  // In case of one geometry, the tracking will have done the locating!!
402 
403  if( fNoActiveNavigators > 1 )
404  {
405  Locate( position, direction, false );
406  }
407  else
408  {
409  // Update state -- depending on the tracking's call to Mass Navigator
410 
411  fLastLocatedPosition= position;
412  fLocatedVolume[0]= massStartVol; // This information must be given
413  // by transportation
414  fLimitedStep[0] = kDoNot;
415  fCurrentStepSize[0] = 0.0;
416  }
417 
418  // Reset Safety Information -- as in case of overlaps this can cause
419  // inconsistencies ...
420  //
421  fMinSafety_PreStepPt= fPreSafetyMinValue= fMinSafety_atSafLocation= 0.0;
422 
423  for( num=0; num< fNoActiveNavigators; ++num )
424  {
425  fPreSafetyValues[num]= 0.0;
426  fNewSafetyComputed[num]= 0.0;
427  fCurrentPreStepSafety[num] = 0.0;
428  }
429 
430  // The first location for each Navigator must be non-relative
431  // or else call ResetStackAndState() for each Navigator
432 
433  fRelocatedPoint= false;
434 }
435 
436 void G4PathFinder::ReportMove( const G4ThreeVector& OldVector,
437  const G4ThreeVector& NewVector,
438  const G4String& Quantity ) const
439 {
440  G4ThreeVector moveVec = ( NewVector - OldVector );
441 
442  G4int prc= G4cerr.precision(12);
443  std::ostringstream message;
444  message << "Endpoint moved between value returned by ComputeStep()"
445  << " and call to Locate(). " << G4endl
446  << " Change of " << Quantity << " is "
447  << moveVec.mag() / mm << " mm long" << G4endl
448  << " and its vector is "
449  << (1.0/mm) * moveVec << " mm " << G4endl
450  << " Endpoint of ComputeStep() was " << OldVector << G4endl
451  << " and current position to locate is " << NewVector;
452  G4Exception("G4PathFinder::ReportMove()", "GeomNav1002",
453  JustWarning, message);
454  G4cerr.precision(prc);
455 }
456 
457 void
459  const G4ThreeVector& direction,
460  G4bool relative)
461 {
462  // Locate the point in each geometry
463 
464  std::vector<G4Navigator*>::iterator pNavIter=
465  fpTransportManager->GetActiveNavigatorsIterator();
466 
467  G4ThreeVector lastEndPosition= fEndState.GetPosition();
468  G4ThreeVector moveVec = (position - lastEndPosition );
469  G4double moveLenSq= moveVec.mag2();
470  if( (!fNewTrack) && (!fRelocatedPoint)
471  && ( moveLenSq> 10*kCarTolerance*kCarTolerance ) )
472  {
473  ReportMove( position, lastEndPosition, "Position" );
474  }
475  fLastLocatedPosition= position;
476 
477 #ifdef G4DEBUG_PATHFINDER
478  if( fVerboseLevel > 2 )
479  {
480  G4cout << G4endl;
481  G4cout << " G4PathFinder::Locate : entered " << G4endl;
482  G4cout << " -------------------- -------" << G4endl;
483  G4cout << " Locating at position " << position
484  << " with direction " << direction
485  << " relative= " << relative << G4endl;
486  if ( (fVerboseLevel > 1) || ( moveLenSq > 0.0) )
487  {
488  G4cout << " lastEndPosition = " << lastEndPosition
489  << " moveVec = " << moveVec
490  << " newTr = " << fNewTrack
491  << " relocated = " << fRelocatedPoint << G4endl;
492  }
493 
494  G4cout << " Located at " << position ;
495  if( fNoActiveNavigators > 1 ) { G4cout << G4endl; }
496  }
497 #endif
498 
499  for ( register G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
500  {
501  // ... who limited the step ....
502 
503  if( fLimitTruth[num] ) { (*pNavIter)->SetGeometricallyLimitedStep(); }
504 
505  G4VPhysicalVolume *pLocated=
506  (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
507  relative,
508  false);
509  // Set the state related to the location
510  //
511  fLocatedVolume[num] = pLocated;
512 
513  // Clear state related to the step
514  //
515  fLimitedStep[num] = kDoNot;
516  fCurrentStepSize[num] = 0.0;
517 
518 #ifdef G4DEBUG_PATHFINDER
519  if( fVerboseLevel > 2 )
520  {
521  G4cout << " - In world " << num << " geomLimStep= " << fLimitTruth[num]
522  << " gives volume= " << pLocated ;
523  if( pLocated )
524  {
525  G4cout << " name = '" << pLocated->GetName() << "'";
526  G4cout << " - CopyNo= " << pLocated->GetCopyNo();
527  }
528  G4cout << G4endl;
529  }
530 #endif
531  }
532 
533  fRelocatedPoint= false;
534 }
535 
537 {
538  // Locate the point in each geometry
539 
540  std::vector<G4Navigator*>::iterator pNavIter=
541  fpTransportManager->GetActiveNavigatorsIterator();
542 
543 #ifdef G4DEBUG_PATHFINDER
544 
545  // Check that this relocation does not violate safety
546  // - at endpoint (computed from start point) AND
547  // - at last safety location (likely just called)
548 
549  G4ThreeVector lastEndPosition= fEndState.GetPosition();
550 
551  // Calculate end-point safety ...
552  //
553  G4double DistanceStartEnd= (lastEndPosition - fPreStepLocation).mag();
554  G4double endPointSafety_raw = fMinSafety_PreStepPt - DistanceStartEnd;
555  G4double endPointSafety_Est1 = std::max( 0.0, endPointSafety_raw );
556 
557  // ... and check move from endpoint against this endpoint safety
558  //
559  G4ThreeVector moveVecEndPos = position - lastEndPosition;
560  G4double moveLenEndPosSq = moveVecEndPos.mag2();
561 
562  // Check that move from endpoint of last step is within safety
563  // -- or check against last location or relocation ??
564  //
565  G4ThreeVector moveVecSafety= position - fSafetyLocation;
566  G4double moveLenSafSq= moveVecSafety.mag2();
567 
568  G4double distCheckEnd_sq= ( moveLenEndPosSq - endPointSafety_Est1
569  *endPointSafety_Est1 );
570  G4double distCheckSaf_sq= ( moveLenSafSq - fMinSafety_atSafLocation
571  *fMinSafety_atSafLocation );
572 
573  G4bool longMoveEnd = distCheckEnd_sq > 0.0;
574  G4bool longMoveSaf = distCheckSaf_sq > 0.0;
575 
576  G4double revisedSafety= 0.0;
577 
578  if( (!fNewTrack) && ( longMoveEnd && longMoveSaf ) )
579  {
580  // Recompute ComputeSafety for end position
581  //
582  revisedSafety= ComputeSafety(lastEndPosition);
583 
584  const G4double kRadTolerance =
586  const G4double cErrorTolerance=1e-12;
587  // Maximum relative error from roundoff of arithmetic
588 
589  G4double distCheckRevisedEnd= moveLenEndPosSq-revisedSafety*revisedSafety;
590 
591  G4bool longMoveRevisedEnd= ( distCheckRevisedEnd > 0. ) ;
592 
593  G4double moveMinusSafety= 0.0;
594  G4double moveLenEndPosition= std::sqrt( moveLenEndPosSq );
595  moveMinusSafety = moveLenEndPosition - revisedSafety;
596 
597  if ( longMoveRevisedEnd && (moveMinusSafety > 0.0 )
598  && ( revisedSafety > 0.0 ) )
599  {
600  // Take into account possibility of roundoff error causing
601  // this apparent move further than safety
602 
603  if( fVerboseLevel > 0 )
604  {
605  G4cout << " G4PF:Relocate> Ratio to revised safety is "
606  << std::fabs(moveMinusSafety)/revisedSafety << G4endl;
607  }
608 
609  G4double absMoveMinusSafety= std::fabs(moveMinusSafety);
610  G4bool smallRatio= absMoveMinusSafety < kRadTolerance * revisedSafety ;
611  G4double maxCoordPos = std::max(
612  std::max( std::fabs(position.x()),
613  std::fabs(position.y())),
614  std::fabs(position.z()) );
615  G4bool smallValue= absMoveMinusSafety < cErrorTolerance * maxCoordPos;
616  if( ! (smallRatio || smallValue) )
617  {
618  G4cout << " G4PF:Relocate> Ratio to revised safety is "
619  << std::fabs(moveMinusSafety)/revisedSafety << G4endl;
620  G4cout << " Difference of move and safety is not very small."
621  << G4endl;
622  }
623  else
624  {
625  moveMinusSafety = 0.0;
626  longMoveRevisedEnd = false; // Numerical issue -- not too long!
627 
628  G4cout << " Difference of move & safety is very small in magnitude, "
629  << absMoveMinusSafety << G4endl;
630  if( smallRatio )
631  {
632  G4cout << " ratio to safety " << revisedSafety
633  << " is " << absMoveMinusSafety / revisedSafety
634  << "smaller than " << kRadTolerance << " of safety ";
635  }
636  else
637  {
638  G4cout << " as fraction " << absMoveMinusSafety / maxCoordPos
639  << " of position vector max-coord " << maxCoordPos
640  << " smaller than " << cErrorTolerance ;
641  }
642  G4cout << " -- reset moveMinusSafety to "
643  << moveMinusSafety << G4endl;
644  }
645  }
646 
647  if ( longMoveEnd && longMoveSaf
648  && longMoveRevisedEnd && (moveMinusSafety>0.0) )
649  {
650  G4int oldPrec= G4cout.precision(9);
651  std::ostringstream message;
652  message << "ReLocation is further than end-safety value." << G4endl
653  << " Moved from last endpoint by " << moveLenEndPosition
654  << " compared to end safety (from preStep point) = "
655  << endPointSafety_Est1 << G4endl
656  << " --> last PreSafety Location was " << fPreSafetyLocation
657  << G4endl
658  << " safety value = " << fPreSafetyMinValue << G4endl
659  << " --> last PreStep Location was " << fPreStepLocation
660  << G4endl
661  << " safety value = " << fMinSafety_PreStepPt << G4endl
662  << " --> last EndStep Location was " << lastEndPosition
663  << G4endl
664  << " safety value = " << endPointSafety_Est1
665  << " raw-value = " << endPointSafety_raw << G4endl
666  << " --> Calling again at this endpoint, we get "
667  << revisedSafety << " as safety value." << G4endl
668  << " --> last position for safety " << fSafetyLocation
669  << G4endl
670  << " its safety value = " << fMinSafety_atSafLocation
671  << G4endl
672  << " move from safety location = "
673  << std::sqrt(moveLenSafSq) << G4endl
674  << " again= " << moveVecSafety.mag() << G4endl
675  << " safety - Move-from-end= "
676  << revisedSafety - moveLenEndPosition
677  << " (negative is Bad.)" << G4endl
678  << " Debug: distCheckRevisedEnd = "
679  << distCheckRevisedEnd;
680  ReportMove( lastEndPosition, position, "Position" );
681  G4Exception("G4PathFinder::ReLocate", "GeomNav0003",
682  FatalException, message);
683  G4cout.precision(oldPrec);
684  }
685  }
686 
687  if( fVerboseLevel > 2 )
688  {
689  G4cout << G4endl;
690  G4cout << " G4PathFinder::ReLocate : entered " << G4endl;
691  G4cout << " ---------------------- -------" << G4endl;
692  G4cout << " *Re*Locating at position " << position << G4endl;
693  // << " with direction " << direction
694  // << " relative= " << relative << G4endl;
695  if ( (fVerboseLevel > -1) || ( moveLenEndPosSq > 0.0) )
696  {
697  G4cout << " lastEndPosition = " << lastEndPosition
698  << " moveVec from step-end = " << moveVecEndPos
699  << " is new Track = " << fNewTrack
700  << " relocated = " << fRelocatedPoint << G4endl;
701  }
702  }
703 #endif // G4DEBUG_PATHFINDER
704 
705  for ( register G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
706  {
707  // ... none limited the step
708 
709  (*pNavIter)->LocateGlobalPointWithinVolume( position );
710 
711  // Clear state related to the step
712  //
713  fLimitedStep[num] = kDoNot;
714  fCurrentStepSize[num] = 0.0;
715  fLimitTruth[num] = false;
716  }
717 
718  fLastLocatedPosition= position;
719  fRelocatedPoint= false;
720 
721 #ifdef G4DEBUG_PATHFINDER
722  if( fVerboseLevel > 2 )
723  {
724  G4cout << " G4PathFinder::ReLocate : exiting "
725  << " at position " << fLastLocatedPosition << G4endl << G4endl;
726  }
727 #endif
728 }
729 
730 // -----------------------------------------------------------------------------
731 
733 {
734  // Recompute safety for the relevant point
735 
736  G4double minSafety= kInfinity;
737 
738  std::vector<G4Navigator*>::iterator pNavigatorIter;
739  pNavigatorIter= fpTransportManager->GetActiveNavigatorsIterator();
740 
741  for( register G4int num=0; num<fNoActiveNavigators; ++pNavigatorIter,++num )
742  {
743  G4double safety = (*pNavigatorIter)->ComputeSafety( position,true );
744  if( safety < minSafety ) { minSafety = safety; }
745  fNewSafetyComputed[num]= safety;
746  }
747 
748  fSafetyLocation= position;
749  fMinSafety_atSafLocation = minSafety;
750 
751 #ifdef G4DEBUG_PATHFINDER
752  if( fVerboseLevel > 1 )
753  {
754  G4cout << " G4PathFinder::ComputeSafety - returns "
755  << minSafety << " at location " << position << G4endl;
756  }
757 #endif
758  return minSafety;
759 }
760 
761 
762 // -----------------------------------------------------------------------------
763 
766 {
767 #ifdef G4DEBUG_PATHFINDER
768  if( fVerboseLevel > 2 )
769  {
770  G4cout << "G4PathFinder::CreateTouchableHandle : navId = "
771  << navId << " -- " << GetNavigator(navId) << G4endl;
772  }
773 #endif
774 
775  G4TouchableHistory* touchHist;
776  touchHist= GetNavigator(navId) -> CreateTouchableHistory();
777 
778  G4VPhysicalVolume* locatedVolume= fLocatedVolume[navId];
779  if( locatedVolume == 0 )
780  {
781  // Workaround to ensure that the touchable is fixed !! // TODO: fix
782 
783  touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
784  }
785 
786 #ifdef G4DEBUG_PATHFINDER
787  if( fVerboseLevel > 2 )
788  {
789  G4String VolumeName("None");
790  if( locatedVolume ) { VolumeName= locatedVolume->GetName(); }
791  G4cout << " Touchable History created at address " << touchHist
792  << " volume = " << locatedVolume << " name= " << VolumeName
793  << G4endl;
794  }
795 #endif
796 
797  return G4TouchableHandle(touchHist);
798 }
799 
800 G4double
802  G4double proposedStepLength )
803 {
804  std::vector<G4Navigator*>::iterator pNavigatorIter;
805  G4double safety= 0.0, step=0.0;
806  G4double minSafety= kInfinity, minStep;
807 
808  const G4int IdTransport= 0; // Id of Mass Navigator !!
809  register G4int num=0;
810 
811 #ifdef G4DEBUG_PATHFINDER
812  if( fVerboseLevel > 2 )
813  {
814  G4cout << " G4PathFinder::DoNextLinearStep : entered " << G4endl;
815  G4cout << " Input field track= " << initialState << G4endl;
816  G4cout << " Requested step= " << proposedStepLength << G4endl;
817  }
818 #endif
819 
820  G4ThreeVector initialPosition= initialState.GetPosition();
821  G4ThreeVector initialDirection= initialState.GetMomentumDirection();
822 
823  G4ThreeVector OriginShift = initialPosition - fPreSafetyLocation;
824  G4double MagSqShift = OriginShift.mag2() ;
825  G4double MagShift; // Only given value if it larger than minimum safety
826 
827  // Potential optimisation using Maximum Value of safety!
828  // if( MagSqShift >= sqr(fPreSafetyMaxValue ) ){
829  // MagShift= kInfinity; // Not a useful value -- all will not use/ignore
830  // else
831  // MagShift= std::sqrt(MagSqShift) ;
832 
833  MagShift= std::sqrt(MagSqShift) ;
834 
835 #ifdef G4PATHFINDER_OPTIMISATION
836 
837  G4double fullSafety; // For all geometries, for prestep point
838 
839  if( MagSqShift >= sqr(fPreSafetyMinValue ) )
840  {
841  fullSafety = 0.0 ;
842  }
843  else
844  {
845  fullSafety = fPreSafetyMinValue - MagShift;
846  }
847  if( proposedStepLength < fullSafety )
848  {
849  // Move is smaller than all safeties
850  // -> so we do not have to move the safety center
851 
852  fPreStepCenterRenewed= false;
853 
854  for( num=0; num< fNoActiveNavigators; ++num )
855  {
856  fCurrentStepSize[num]= kInfinity;
857  safety = std::max( 0.0, fPreSafetyValues[num] - MagShift);
858  minSafety= std::min( safety, minSafety );
859  fCurrentPreStepSafety[num]= safety;
860  }
861  minStep= kInfinity;
862 
863 #ifdef G4DEBUG_PATHFINDER
864  if( fVerboseLevel > 2 )
865  {
866  G4cout << "G4PathFinder::DoNextLinearStep : Quick Stepping. " << G4endl
867  << " proposedStepLength " << proposedStepLength
868  << " < (full) safety = " << fullSafety
869  << " at " << initialPosition
870  << G4endl;
871  }
872 #endif
873  }
874  else
875 #endif // End of G4PATHFINDER_OPTIMISATION 1
876  {
877  // Move is larger than at least one of the safeties
878  // -> so we must move the safety center!
879 
880  fPreStepCenterRenewed= true;
881  pNavigatorIter= fpTransportManager-> GetActiveNavigatorsIterator();
882 
883  minStep= kInfinity; // Not proposedStepLength;
884 
885  for( num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
886  {
887  safety = std::max( 0.0, fPreSafetyValues[num] - MagShift);
888 
889 #ifdef G4PATHFINDER_OPTIMISATION
890  if( proposedStepLength <= safety ) // Should be just < safety ?
891  {
892  // The Step is guaranteed to be taken
893 
894  step= kInfinity; // ComputeStep Would return this
895 
896 #ifdef G4DEBUG_PATHFINDER
897  G4cout.precision(8);
898  G4cout << "PathFinder::ComputeStep> small proposed step = "
899  << proposedStepLength
900  << " <= safety = " << safety << " for nav " << num
901  << " Step fully taken. " << G4endl;
902 #endif
903  }
904  else
905 #endif // End of G4PATHFINDER_OPTIMISATION 2
906  {
907 #ifdef G4DEBUG_PATHFINDER
908  G4double previousSafety= safety;
909 #endif
910  step= (*pNavigatorIter)->ComputeStep( initialPosition,
911  initialDirection,
912  proposedStepLength,
913  safety );
914  minStep = std::min( step, minStep);
915 
916  // TODO: consider whether/how to reduce the proposed step
917  // to the latest minStep value - to reduce calculations
918 
919 #ifdef G4DEBUG_PATHFINDER
920  if( fVerboseLevel > 0)
921  {
922  G4cout.precision(8);
923  G4cout << "PathFinder::ComputeStep> long proposed step = "
924  << proposedStepLength
925  << " > safety = " << previousSafety
926  << " for nav " << num
927  << " . New safety = " << safety << " step= " << step
928  << G4endl;
929  }
930 #endif
931  }
932  fCurrentStepSize[num] = step;
933 
934  // Save safety value, must be done for all geometries "together"
935  // (even if not recomputed using call to ComputeStep)
936  // since they share the fPreSafetyLocation
937 
938  fPreSafetyValues[num]= safety;
939  fCurrentPreStepSafety[num]= safety;
940 
941  minSafety= std::min( safety, minSafety );
942 
943 #ifdef G4DEBUG_PATHFINDER
944  if( fVerboseLevel > 2 )
945  {
946  G4cout << "G4PathFinder::DoNextLinearStep : Navigator ["
947  << num << "] -- step size " << step << G4endl;
948  }
949 #endif
950  }
951 
952  // Only change these when safety is recalculated
953  // it is good/relevant only for safety calculations
954 
955  fPreSafetyLocation= initialPosition;
956  fPreSafetyMinValue= minSafety;
957  } // end of else for if( proposedStepLength <= fullSafety)
958 
959  // For use in Relocation, need PreStep point location, min-safety
960  //
961  fPreStepLocation= initialPosition;
962  fMinSafety_PreStepPt= minSafety;
963 
964  fMinStep= minStep;
965 
966  if( fMinStep == kInfinity )
967  {
968  minStep = proposedStepLength; // Use this below for endpoint !!
969  }
970  fTrueMinStep = minStep;
971 
972  // Set the EndState
973 
974  G4ThreeVector endPosition;
975 
976  fEndState= initialState;
977  endPosition= initialPosition + minStep * initialDirection ;
978 
979 #ifdef G4DEBUG_PATHFINDER
980  if( fVerboseLevel > 1 )
981  {
982  G4cout << "G4PathFinder::DoNextLinearStep : "
983  << " initialPosition = " << initialPosition
984  << " and endPosition = " << endPosition<< G4endl;
985  }
986 #endif
987 
988  fEndState.SetPosition( endPosition );
989  fEndState.SetProperTimeOfFlight( -1.000 ); // Not defined YET
990 
991  if( fNoActiveNavigators == 1 )
992  {
993  G4bool transportLimited = (fMinStep!= kInfinity);
994  fLimitTruth[IdTransport] = transportLimited;
995  fLimitedStep[IdTransport] = transportLimited ? kUnique : kDoNot;
996 
997  // Set fNoGeometriesLimiting - as WhichLimited does
998  fNoGeometriesLimiting = transportLimited ? 1 : 0;
999  }
1000  else
1001  {
1002  WhichLimited();
1003  }
1004 
1005 #ifdef G4DEBUG_PATHFINDER
1006  if( fVerboseLevel > 2 )
1007  {
1008  G4cout << " G4PathFinder::DoNextLinearStep : exits returning "
1009  << minStep << G4endl;
1010  G4cout << " Endpoint values = " << fEndState << G4endl;
1011  G4cout << G4endl;
1012  }
1013 #endif
1014 
1015  return minStep;
1016 }
1017 
1019 {
1020  // Flag which processes limited the step
1021 
1022  G4int num=-1, last=-1;
1023  G4int noLimited=0;
1024  ELimited shared= kSharedOther;
1025 
1026  const G4int IdTransport= 0; // Id of Mass Navigator !!
1027 
1028  // Assume that [IdTransport] is Mass / Transport
1029  //
1030  G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
1031  && ( fMinStep!= kInfinity) ;
1032 
1033  if( transportLimited ) {
1034  shared= kSharedTransport;
1035  }
1036 
1037  for ( num= 0; num < fNoActiveNavigators; num++ )
1038  {
1039  G4bool limitedStep;
1040 
1041  G4double step= fCurrentStepSize[num];
1042 
1043  limitedStep = ( std::fabs(step - fMinStep) < kCarTolerance )
1044  && ( step != kInfinity);
1045 
1046  fLimitTruth[ num ] = limitedStep;
1047  if( limitedStep )
1048  {
1049  noLimited++;
1050  fLimitedStep[num] = shared;
1051  last= num;
1052  }
1053  else
1054  {
1055  fLimitedStep[num] = kDoNot;
1056  }
1057  }
1058  fNoGeometriesLimiting= noLimited; // Save # processes limiting step
1059 
1060  if( (last > -1) && (noLimited == 1 ) )
1061  {
1062  fLimitedStep[ last ] = kUnique;
1063  }
1064 
1065 #ifdef G4DEBUG_PATHFINDER
1066  if( fVerboseLevel > 1 )
1067  {
1068  PrintLimited(); // --> for tracing
1069  if( fVerboseLevel > 4 ) {
1070  G4cout << " G4PathFinder::WhichLimited - exiting. " << G4endl;
1071  }
1072  }
1073 #endif
1074 }
1075 
1077 {
1078  // Report results -- for checking
1079 
1080  G4cout << "G4PathFinder::PrintLimited reports: " ;
1081  G4cout << " Minimum step (true)= " << fTrueMinStep
1082  << " reported min = " << fMinStep
1083  << G4endl;
1084  if( (fCurrentStepNo <= 2) || (fVerboseLevel>=2) )
1085  {
1086  G4cout << std::setw(5) << " Step#" << " "
1087  << std::setw(5) << " NavId" << " "
1088  << std::setw(12) << " step-size " << " "
1089  << std::setw(12) << " raw-size " << " "
1090  << std::setw(12) << " pre-safety " << " "
1091  << std::setw(15) << " Limited / flag" << " "
1092  << std::setw(15) << " World " << " "
1093  << G4endl;
1094  }
1095  G4int num;
1096  for ( num= 0; num < fNoActiveNavigators; num++ )
1097  {
1098  G4double rawStep = fCurrentStepSize[num];
1099  G4double stepLen = fCurrentStepSize[num];
1100  if( stepLen > fTrueMinStep )
1101  {
1102  stepLen = fTrueMinStep; // did not limit (went as far as asked)
1103  }
1104  G4int oldPrec= G4cout.precision(9);
1105 
1106  G4cout << std::setw(5) << fCurrentStepNo << " "
1107  << std::setw(5) << num << " "
1108  << std::setw(12) << stepLen << " "
1109  << std::setw(12) << rawStep << " "
1110  << std::setw(12) << fCurrentPreStepSafety[num] << " "
1111  << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
1112  G4String limitedStr= LimitedString(fLimitedStep[num]);
1113  G4cout << " " << std::setw(15) << limitedStr << " ";
1114  G4cout.precision(oldPrec);
1115 
1116  G4Navigator *pNav= GetNavigator( num );
1117  G4String WorldName( "Not-Set" );
1118  if (pNav)
1119  {
1120  G4VPhysicalVolume *pWorld= pNav->GetWorldVolume();
1121  if( pWorld )
1122  {
1123  WorldName = pWorld->GetName();
1124  }
1125  }
1126  G4cout << " " << WorldName ;
1127  G4cout << G4endl;
1128  }
1129 
1130  if( fVerboseLevel > 4 )
1131  {
1132  G4cout << " G4PathFinder::PrintLimited - exiting. " << G4endl;
1133  }
1134 }
1135 
1136 G4double
1138  G4double proposedStepLength,
1139  G4VPhysicalVolume* pCurrentPhysicalVolume )
1140 {
1141  const G4double toleratedRelativeError= 1.0e-10;
1142  G4double minStep= kInfinity, newSafety=0.0;
1143  G4int numNav;
1144  G4FieldTrack fieldTrack= initialState;
1145  G4ThreeVector startPoint= initialState.GetPosition();
1146 
1147 #ifdef G4DEBUG_PATHFINDER
1148  G4int prc= G4cout.precision(9);
1149  if( fVerboseLevel > 2 )
1150  {
1151  G4cout << " G4PathFinder::DoNextCurvedStep ****** " << G4endl;
1152  G4cout << " Initial value of field track is " << fieldTrack
1153  << " and proposed step= " << proposedStepLength << G4endl;
1154  }
1155 #endif
1156 
1157  fPreStepCenterRenewed= true; // Always update PreSafety with PreStep point
1158 
1159  if( fNoActiveNavigators > 1 )
1160  {
1161  // Calculate the safety values before making the step
1162 
1163  G4double minSafety= kInfinity, safety;
1164  for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
1165  {
1166  safety= fpNavigator[numNav]->ComputeSafety( startPoint, false );
1167  fPreSafetyValues[numNav]= safety;
1168  fCurrentPreStepSafety[numNav]= safety;
1169  minSafety = std::min( safety, minSafety );
1170  }
1171 
1172  // Save safety value, related position
1173 
1174  fPreSafetyLocation= startPoint;
1175  fPreSafetyMinValue= minSafety;
1176  fPreStepLocation= startPoint;
1177  fMinSafety_PreStepPt= minSafety;
1178  }
1179 
1180  // Allow Propagator In Field to do the hard work, calling G4MultiNavigator
1181  //
1182  minStep= fpFieldPropagator->ComputeStep( fieldTrack,
1183  proposedStepLength,
1184  newSafety,
1185  pCurrentPhysicalVolume );
1186 
1187  // fieldTrack now contains the endpoint information
1188  //
1189  fEndState= fieldTrack;
1190  fMinStep= minStep;
1191  fTrueMinStep = std::min( minStep, proposedStepLength );
1192 
1193  if( fNoActiveNavigators== 1 )
1194  {
1195  // Update the 'PreSafety' sphere - as any ComputeStep was called
1196  // (must be done anyway in field)
1197 
1198  fPreSafetyValues[0]= newSafety;
1199  fPreSafetyLocation= startPoint;
1200  fPreSafetyMinValue= newSafety;
1201 
1202  // Update the current 'PreStep' point's values - mandatory
1203  //
1204  fCurrentPreStepSafety[0]= newSafety;
1205  fPreStepLocation= startPoint;
1206  fMinSafety_PreStepPt= newSafety;
1207  }
1208 
1209 #ifdef G4DEBUG_PATHFINDER
1210  if( fVerboseLevel > 2 )
1211  {
1212  G4cout << "G4PathFinder::DoNextCurvedStep : " << G4endl
1213  << " initialState = " << initialState << G4endl
1214  << " and endState = " << fEndState << G4endl;
1215  G4cout << "G4PathFinder::DoNextCurvedStep : "
1216  << " minStep = " << minStep
1217  << " proposedStepLength " << proposedStepLength
1218  << " safety = " << newSafety << G4endl;
1219  }
1220 #endif
1221  G4double currentStepSize; // = 0.0;
1222  if( minStep < proposedStepLength ) // if == , then a boundary found at end ??
1223  {
1224  // Recover the remaining information from MultiNavigator
1225  // especially regarding which Navigator limited the step
1226 
1227  G4int noLimited= 0; // No geometries limiting step
1228  for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
1229  {
1230  G4double finalStep, lastPreSafety=0.0, minStepLast;
1231  ELimited didLimit;
1232  G4bool limited;
1233 
1234  finalStep= fpMultiNavigator->ObtainFinalStep( numNav, lastPreSafety,
1235  minStepLast, didLimit );
1236 
1237  // Calculate the step for this geometry, using the
1238  // final step (the only one which can differ.)
1239 
1240  currentStepSize = fTrueMinStep;
1241  G4double diffStep= 0.0;
1242  if( (minStepLast != kInfinity) )
1243  {
1244  diffStep = (finalStep-minStepLast);
1245  if ( std::abs(diffStep) <= toleratedRelativeError * finalStep )
1246  {
1247  diffStep = 0.0;
1248  }
1249  currentStepSize += diffStep;
1250  }
1251  fCurrentStepSize[numNav] = currentStepSize;
1252 
1253  // TODO: could refine the way to obtain safeties for > 1 geometries
1254  // - for pre step safety
1255  // notify MultiNavigator about new set of sub-steps
1256  // allow it to return this value in ObtainFinalStep
1257  // instead of lastPreSafety (or as well?)
1258  // - for final step start (available)
1259  // get final Step start from MultiNavigator
1260  // and corresponding safety values
1261  // and/or ALSO calculate ComputeSafety at endpoint
1262  // endSafety= fpNavigator[numNav]->ComputeSafety( endPoint );
1263 
1264  fLimitedStep[numNav] = didLimit;
1265  fLimitTruth[numNav] = limited = (didLimit != kDoNot );
1266  if( limited ) { noLimited++; }
1267 
1268 #ifdef G4DEBUG_PATHFINDER
1269  G4bool StepError= (currentStepSize < 0)
1270  || ( (minStepLast != kInfinity) && (diffStep < 0) ) ;
1271  if( StepError || (fVerboseLevel > 2) )
1272  {
1273  G4String limitedString= LimitedString( fLimitedStep[numNav] );
1274 
1275  G4cout << " G4PathFinder::ComputeStep. Geometry " << numNav
1276  << " step= " << fCurrentStepSize[numNav]
1277  << " from final-step= " << finalStep
1278  << " fTrueMinStep= " << fTrueMinStep
1279  << " minStepLast= " << minStepLast
1280  << " limited = " << (fLimitTruth[numNav] ? "YES" : " NO")
1281  << " ";
1282  G4cout << " status = " << limitedString << " #= " << didLimit
1283  << G4endl;
1284 
1285  if( StepError )
1286  {
1287  std::ostringstream message;
1288  message << "Incorrect calculation of step size for one navigator"
1289  << G4endl
1290  << " currentStepSize = " << currentStepSize
1291  << ", diffStep= " << diffStep << G4endl
1292  << "ERROR in computing step size for this navigator.";
1293  G4Exception("G4PathFinder::DoNextCurvedStep",
1294  "GeomNav0003", FatalException, message);
1295  }
1296  }
1297 #endif
1298  } // for num Navigators
1299 
1300  fNoGeometriesLimiting= noLimited; // Save # processes limiting step
1301  }
1302  else if ( (minStep == proposedStepLength)
1303  || (minStep == kInfinity)
1304  || ( std::abs(minStep-proposedStepLength)
1305  < toleratedRelativeError * proposedStepLength ) )
1306  {
1307  // In case the step was not limited, use default responses
1308  // --> all Navigators
1309  // Also avoid problems in case of PathFinder using safety to optimise
1310  // - it is possible that the Navigators were not called
1311  // if the safety was already satisfactory.
1312  // (In that case calling ObtainFinalStep gives invalid results.)
1313 
1314  currentStepSize= minStep;
1315  for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
1316  {
1317  fCurrentStepSize[numNav] = minStep;
1318  // Safety for endpoint ?? // Can eventuall improve it -- see TODO above
1319  fLimitedStep[numNav] = kDoNot;
1320  fLimitTruth[numNav] = false;
1321  }
1322  fNoGeometriesLimiting= 0; // Save # processes limiting step
1323  }
1324  else // (minStep > proposedStepLength) and not (minStep == kInfinity)
1325  {
1326  std::ostringstream message;
1327  message << "Incorrect calculation of step size for one navigator." << G4endl
1328  << " currentStepSize = " << minStep << " is larger than "
1329  << " proposed StepSize = " << proposedStepLength << ".";
1330  G4Exception("G4PathFinder::DoNextCurvedStep()",
1331  "GeomNav0003", FatalException, message);
1332  }
1333 
1334 #ifdef G4DEBUG_PATHFINDER
1335  if( fVerboseLevel > 2 )
1336  {
1337  G4cout << " Exiting G4PathFinder::DoNextCurvedStep " << G4endl;
1338  PrintLimited();
1339  }
1340  G4cout.precision(prc);
1341 #endif
1342 
1343  return minStep;
1344 }
1345 
1347 {
1348  static G4String StrDoNot("DoNot"),
1349  StrUnique("Unique"),
1350  StrUndefined("Undefined"),
1351  StrSharedTransport("SharedTransport"),
1352  StrSharedOther("SharedOther");
1353 
1354  G4String* limitedStr;
1355  switch ( lim )
1356  {
1357  case kDoNot: limitedStr= &StrDoNot; break;
1358  case kUnique: limitedStr = &StrUnique; break;
1359  case kSharedTransport: limitedStr= &StrSharedTransport; break;
1360  case kSharedOther: limitedStr = &StrSharedOther; break;
1361  default: limitedStr = &StrUndefined; break;
1362  }
1363  return *limitedStr;
1364 }
1365 
1367 {
1368  fPreSafetyLocation= fSafetyLocation;
1369  fPreSafetyMinValue= fMinSafety_atSafLocation;
1370  for( register G4int nav=0; nav < fNoActiveNavigators; ++nav )
1371  {
1372  fPreSafetyValues[nav]= fNewSafetyComputed[nav];
1373  }
1374 }
void PrepareNewTrack(const G4ThreeVector &position, const G4ThreeVector &direction, G4VPhysicalVolume *massStartVol=0)
G4String & LimitedString(ELimited lim)
static G4PathFinder * GetInstance()
Definition: G4PathFinder.cc:57
void SetPosition(G4ThreeVector nPos)
void Locate(const G4ThreeVector &position, const G4ThreeVector &direction, G4bool relativeSearch=true)
void SetNavigatorForPropagating(G4Navigator *SimpleOrMultiNavigator)
G4SafetyHelper * GetSafetyHelper() const
void InitialiseHelper()
void EnableParallelNavigation(G4bool enableChoice=true)
double x() const
void ReLocate(const G4ThreeVector &position)
ELimited
G4double GetSurfaceTolerance() const
G4Navigator * GetNavigatorForTracking() const
G4TouchableHandle CreateTouchableHandle(G4int navId) const
void WhichLimited()
#define G4ThreadLocal
Definition: tls.hh:52
int G4int
Definition: G4Types.hh:78
void MovePoint()
double z() const
G4double DoNextCurvedStep(const G4FieldTrack &FieldTrack, G4double proposedStepLength, G4VPhysicalVolume *pCurrentPhysVolume)
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4ThreeVector GetPosition() const
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
G4double GetRadialTolerance() const
bool G4bool
Definition: G4Types.hh:79
void EnableParallelNavigation(G4bool parallel)
G4double ComputeStep(const G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4int navigatorId, G4int stepNo, G4double &pNewSafety, ELimited &limitedStep, G4FieldTrack &EndState, G4VPhysicalVolume *currentVolume)
G4double DoNextLinearStep(const G4FieldTrack &FieldTrack, G4double proposedStepLength)
G4double ComputeSafety(const G4ThreeVector &globalPoint)
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
void PushPostSafetyToPreSafety()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
static G4TransportationManager * GetTransportationManager()
G4double GetCharge() const
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=0)
T max(const T t1, const T t2)
brief Return the largest of the two arguments
std::vector< G4Navigator * >::iterator GetActiveNavigatorsIterator()
int position
Definition: filter.cc:7
double y() const
G4double ObtainFinalStep(G4int navigatorId, G4double &pNewSafety, G4double &minStepLast, ELimited &limitedStep)
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
double mag2() const
void SetProperTimeOfFlight(G4double nTOF)
#define G4endl
Definition: G4ios.hh:61
void UpdateYourself(G4VPhysicalVolume *pPhysVol, const G4NavigationHistory *history=0)
const G4NavigationHistory * GetHistory() const
T sqr(const T &x)
Definition: templates.hh:145
double G4double
Definition: G4Types.hh:76
void PrintLimited()
const G4Field * GetDetectorField() const
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
G4PropagatorInField * GetPropagatorInField() const
double mag() const
void ReportMove(const G4ThreeVector &OldV, const G4ThreeVector &NewV, const G4String &Quantity) const
G4VPhysicalVolume * GetWorldVolume() const
G4Navigator * GetNavigator(G4int n) const
static G4GeometryTolerance * GetInstance()
G4GLOB_DLL std::ostream G4cerr
G4ThreeVector GetMomentumDirection() const