Geant4  10.00.p02
G4Navigator.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: G4Navigator.cc 2012-11-01 japost Exp $
28 // GEANT4 tag $ Name: $
29 //
30 // class G4Navigator Implementation
31 //
32 // Original author: Paul Kent, July 95/96
33 // Responsible 1996-present: John Apostolakis
34 // Co-maintainer: Gabriele Cosmo
35 // Additional revisions by: Pedro Arce, Vladimir Grichine
36 // --------------------------------------------------------------------
37 
38 #include <iomanip>
39 
40 #include "G4Navigator.hh"
41 #include "G4ios.hh"
42 #include "G4SystemOfUnits.hh"
43 #include "G4GeometryTolerance.hh"
44 #include "G4VPhysicalVolume.hh"
45 
46 #include "G4VoxelSafety.hh"
47 
48 // ********************************************************************
49 // Constructor
50 // ********************************************************************
51 //
53  : fWasLimitedByGeometry(false), fVerbose(0),
54  fTopPhysical(0), fCheck(false), fPushed(false), fWarnPush(true)
55 {
56  fActive= false;
58 
60  // Initialises also all
61  // - exit / entry flags
62  // - flags & variables for exit normals
63  // - zero step counters
64  // - blocked volume
65 
68 
71 
74 
76 }
77 
78 // ********************************************************************
79 // Destructor
80 // ********************************************************************
81 //
83 { delete fpVoxelSafety; }
84 
85 // ********************************************************************
86 // ResetHierarchyAndLocate
87 // ********************************************************************
88 //
91  const G4ThreeVector &direction,
92  const G4TouchableHistory &h)
93 {
94  ResetState();
95  fHistory = *h.GetHistory();
97  fLastTriedStepComputation= false; // Redundant, but best
98  return LocateGlobalPointAndSetup(p, &direction, true, false);
99 }
100 
101 // ********************************************************************
102 // LocateGlobalPointAndSetup
103 //
104 // Locate the point in the hierarchy return 0 if outside
105 // The direction is required
106 // - if on an edge shared by more than two surfaces
107 // (to resolve likely looping in tracking)
108 // - at initial location of a particle
109 // (to resolve potential ambiguity at boundary)
110 //
111 // Flags on exit: (comments to be completed)
112 // fEntering - True if entering `daughter' volume (or replica)
113 // whether daughter of last mother directly
114 // or daughter of that volume's ancestor.
115 // ********************************************************************
116 //
119  const G4ThreeVector* pGlobalDirection,
120  const G4bool relativeSearch,
121  const G4bool ignoreDirection )
122 {
123  G4bool notKnownContained=true, noResult;
124  G4VPhysicalVolume *targetPhysical;
125  G4LogicalVolume *targetLogical;
126  G4VSolid *targetSolid=0;
127  G4ThreeVector localPoint, globalDirection;
128  EInside insideCode;
129 
130  G4bool considerDirection = (!ignoreDirection) || fLocatedOnEdge;
131 
133  fChangedGrandMotherRefFrame= false; // For local exit normal
134 
135  if( considerDirection && pGlobalDirection != 0 )
136  {
137  globalDirection=*pGlobalDirection;
138  }
139 
140 
141 #ifdef G4VERBOSE
142  if( fVerbose > 2 )
143  {
144  G4int oldcoutPrec = G4cout.precision(8);
145  G4cout << "*** G4Navigator::LocateGlobalPointAndSetup: ***" << G4endl;
146  G4cout << " Called with arguments: " << G4endl
147  << " Globalpoint = " << globalPoint << G4endl
148  << " RelativeSearch = " << relativeSearch << G4endl;
149  if( fVerbose == 4 )
150  {
151  G4cout << " ----- Upon entering:" << G4endl;
152  PrintState();
153  }
154  G4cout.precision(oldcoutPrec);
155  }
156 #endif
157 
158  if ( !relativeSearch )
159  {
161  }
162  else
163  {
164  if ( fWasLimitedByGeometry )
165  {
166  fWasLimitedByGeometry = false;
167  fEnteredDaughter = fEntering; // Remember
168  fExitedMother = fExiting; // Remember
169  if ( fExiting )
170  {
171  if ( fHistory.GetDepth() )
172  {
176  }
177  else
178  {
179  fLastLocatedPointLocal = localPoint;
180  fLocatedOutsideWorld = true;
181  return 0; // Have exited world volume
182  }
183  // A fix for the case where a volume is "entered" at an edge
184  // and a coincident surface exists outside it.
185  // - This stops it from exiting further volumes and cycling
186  // - However ReplicaNavigator treats this case itself
187  //
189  {
190  fExiting= false;
191  }
192  }
193  else
194  if ( fEntering )
195  {
197  {
198  case kNormal:
201  break;
202  case kReplica:
208  break;
209  case kParameterised:
211  {
212  G4VSolid *pSolid;
213  G4VPVParameterisation *pParam;
214  G4TouchableHistory parentTouchable( fHistory );
216  pSolid = pParam->ComputeSolid(fBlockedReplicaNo,
218  pSolid->ComputeDimensions(pParam, fBlockedReplicaNo,
225  //
226  // Set the correct solid and material in Logical Volume
227  //
228  G4LogicalVolume *pLogical;
230  pLogical->SetSolid( pSolid );
231  pLogical->UpdateMaterial(pParam ->
232  ComputeMaterial(fBlockedReplicaNo,
234  &parentTouchable));
235  }
236  break;
237  }
238  fEntering = false;
240  localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
241  notKnownContained = false;
242  }
243  }
244  else
245  {
247  fEntering = false;
248  fEnteredDaughter = false; // Full Step was not taken, did not enter
249  fExiting = false;
250  fExitedMother = false; // Full Step was not taken, did not exit
251  }
252  }
253  //
254  // Search from top of history up through geometry until
255  // containing volume found:
256  // If on
257  // o OUTSIDE - Back up level, not/no longer exiting volumes
258  // o SURFACE and EXITING - Back up level, setting new blocking no.s
259  // else
260  // o containing volume found
261  //
262  G4int noLevelsExited=0 ;
263 
264  while (notKnownContained)
265  {
267  {
268  targetSolid = fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
269  localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
270  insideCode = targetSolid->Inside(localPoint);
271 #ifdef G4VERBOSE
272  if(( fVerbose == 1 ) && ( fCheck ))
273  {
274  G4String solidResponse = "-kInside-";
275  if (insideCode == kOutside)
276  solidResponse = "-kOutside-";
277  else if (insideCode == kSurface)
278  solidResponse = "-kSurface-";
279  G4cout << "*** G4Navigator::LocateGlobalPointAndSetup(): ***" << G4endl
280  << " Invoked Inside() for solid: " << targetSolid->GetName()
281  << ". Solid replied: " << solidResponse << G4endl
282  << " For local point p: " << localPoint << G4endl;
283  }
284 #endif
285  }
286  else
287  {
288  insideCode = freplicaNav.BackLocate(fHistory, globalPoint, localPoint,
289  fExiting, notKnownContained);
290  // !CARE! if notKnownContained returns false then the point is within
291  // the containing placement volume of the replica(s). If insidecode
292  // will result in the history being backed up one level, then the
293  // local point returned is the point in the system of this new level
294  }
295 
296 
297  if ( insideCode==kOutside )
298  {
299  noLevelsExited++;
300  if ( fHistory.GetDepth() )
301  {
305  fExiting = false;
306 
307  if( noLevelsExited > 1 )
308  {
309  // The first transformation was done by the sub-navigator
310  //
312  if( mRot )
313  {
314  fGrandMotherExitNormal *= (*mRot).inverse();
316  }
317  }
318  }
319  else
320  {
321  fLastLocatedPointLocal = localPoint;
322  fLocatedOutsideWorld = true;
323  // No extra transformation for ExitNormal - is in frame of Top Volume
324  return 0; // Have exited world volume
325  }
326  }
327  else
328  if ( insideCode==kSurface )
329  {
330  G4bool isExiting = fExiting;
331  if( (!fExiting)&&considerDirection )
332  {
333  // Figure out whether we are exiting this level's volume
334  // by using the direction
335  //
336  G4bool directionExiting = false;
337  G4ThreeVector localDirection =
338  fHistory.GetTopTransform().TransformAxis(globalDirection);
339 
340  // Make sure localPoint in correct reference frame
341  // ( Was it already correct ? How ? )
342  //
343  localPoint= fHistory.GetTopTransform().TransformPoint(globalPoint);
345  {
346  G4ThreeVector normal = targetSolid->SurfaceNormal(localPoint);
347  directionExiting = normal.dot(localDirection) > 0.0;
348  isExiting = isExiting || directionExiting;
349  }
350  }
351  if( isExiting )
352  {
353  noLevelsExited++;
354  if ( fHistory.GetDepth() )
355  {
359  //
360  // Still on surface but exited volume not necessarily convex
361  //
362  fValidExitNormal = false;
363 
364  if( noLevelsExited > 1 )
365  {
366  // The first transformation was done by the sub-navigator
367  //
369  if( mRot )
370  {
371  fGrandMotherExitNormal *= (*mRot).inverse();
373  }
374  }
375  }
376  else
377  {
378  fLastLocatedPointLocal = localPoint;
379  fLocatedOutsideWorld = true;
380  // No extra transformation for ExitNormal, is in frame of Top Vol
381  return 0; // Have exited world volume
382  }
383  }
384  else
385  {
386  notKnownContained=false;
387  }
388  }
389  else
390  {
391  notKnownContained=false;
392  }
393  } // END while (notKnownContained)
394  //
395  // Search downwards until deepest containing volume found,
396  // blocking fBlockedPhysicalVolume/BlockedReplicaNum
397  //
398  // 3 Cases:
399  //
400  // o Parameterised daughters
401  // =>Must be one G4PVParameterised daughter & voxels
402  // o Positioned daughters & voxels
403  // o Positioned daughters & no voxels
404 
405  noResult = true; // noResult should be renamed to
406  // something like enteredLevel, as that is its meaning.
407  do
408  {
409  // Determine `type' of current mother volume
410  //
411  targetPhysical = fHistory.GetTopVolume();
412  if (!targetPhysical) { break; }
413  targetLogical = targetPhysical->GetLogicalVolume();
414  switch( CharacteriseDaughters(targetLogical) )
415  {
416  case kNormal:
417  if ( targetLogical->GetVoxelHeader() ) // use optimised navigation
418  {
419  noResult = fvoxelNav.LevelLocate(fHistory,
422  globalPoint,
423  pGlobalDirection,
424  considerDirection,
425  localPoint);
426  }
427  else // do not use optimised navigation
428  {
429  noResult = fnormalNav.LevelLocate(fHistory,
432  globalPoint,
433  pGlobalDirection,
434  considerDirection,
435  localPoint);
436  }
437  break;
438  case kReplica:
439  noResult = freplicaNav.LevelLocate(fHistory,
442  globalPoint,
443  pGlobalDirection,
444  considerDirection,
445  localPoint);
446  break;
447  case kParameterised:
448  if( GetDaughtersRegularStructureId(targetLogical) != 1 )
449  {
450  noResult = fparamNav.LevelLocate(fHistory,
453  globalPoint,
454  pGlobalDirection,
455  considerDirection,
456  localPoint);
457  }
458  else // Regular structure
459  {
460  noResult = fregularNav.LevelLocate(fHistory,
463  globalPoint,
464  pGlobalDirection,
465  considerDirection,
466  localPoint);
467  }
468  break;
469  }
470 
471  // LevelLocate returns true if it finds a daughter volume
472  // in which globalPoint is inside (or on the surface).
473 
474  if ( noResult )
475  {
476  // Entering a daughter after ascending
477  //
478  // The blocked volume is no longer valid - it was for another level
479  //
481  fBlockedReplicaNo = -1;
482 
483  // fEntering should be false -- else blockedVolume is assumed good.
484  // fEnteredDaughter is used for ExitNormal
485  //
486  fEntering = false;
487  fEnteredDaughter = true;
488 
489  if( fExitedMother )
490  {
491  G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
492  const G4RotationMatrix* mRot = enteredPhysical->GetRotation();
493  if( mRot )
494  {
495  fGrandMotherExitNormal *= (*mRot).inverse();
496  }
497  }
498 
499 #ifdef G4DEBUG_NAVIGATION
500  if( fVerbose > 2 )
501  {
502  G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
503  G4cout << "*** G4Navigator::LocateGlobalPointAndSetup() ***" << G4endl;
504  G4cout << " Entering volume: " << enteredPhysical->GetName()
505  << G4endl;
506  }
507 #endif
508  }
509  } while (noResult);
510 
511  fLastLocatedPointLocal = localPoint;
512 
513 #ifdef G4VERBOSE
514  if( fVerbose >= 4 )
515  {
516  G4int oldcoutPrec = G4cout.precision(8);
517  G4String curPhysVol_Name("None");
518  if (targetPhysical) { curPhysVol_Name = targetPhysical->GetName(); }
519  G4cout << " Return value = new volume = " << curPhysVol_Name << G4endl;
520  G4cout << " ----- Upon exiting:" << G4endl;
521  PrintState();
522  if( fVerbose == 5 )
523  {
524  G4cout << "Upon exiting LocateGlobalPointAndSetup():" << G4endl;
525  G4cout << " History = " << G4endl << fHistory << G4endl << G4endl;
526  }
527  G4cout.precision(oldcoutPrec);
528  }
529 #endif
530 
531  fLocatedOutsideWorld= false;
532 
533  return targetPhysical;
534 }
535 
536 // ********************************************************************
537 // LocateGlobalPointWithinVolume
538 //
539 // -> the state information of this Navigator and its subNavigators
540 // is updated in order to start the next step at pGlobalpoint
541 // -> no check is performed whether pGlobalpoint is inside the
542 // original volume (this must be the case).
543 //
544 // Note: a direction could be added to the arguments, to aid in future
545 // optional checking (via the old code below, flagged by OLD_LOCATE).
546 // [ This would be done only in verbose mode ]
547 // ********************************************************************
548 //
549 void
551 {
554  fChangedGrandMotherRefFrame= false; // Frame for Exit Normal
555 
556 #ifdef G4DEBUG_NAVIGATION
557  if( fVerbose > 2 )
558  {
559  G4cout << "Entering LocateGlobalWithinVolume(): History = " << G4endl;
560  G4cout << fHistory << G4endl;
561  }
562 #endif
563 
564  // For the case of Voxel (or Parameterised) volume the respective
565  // Navigator must be messaged to update its voxel information etc
566 
567  // Update the state of the Sub Navigators
568  // - in particular any voxel information they store/cache
569  //
570  G4VPhysicalVolume* motherPhysical = fHistory.GetTopVolume();
571  G4LogicalVolume* motherLogical = motherPhysical->GetLogicalVolume();
572  G4SmartVoxelHeader* pVoxelHeader = motherLogical->GetVoxelHeader();
573 
575  {
576  switch( CharacteriseDaughters(motherLogical) )
577  {
578  case kNormal:
579  if ( pVoxelHeader )
580  {
582  }
583  break;
584  case kParameterised:
585  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
586  {
587  // Resets state & returns voxel node
588  //
590  }
591  break;
592  case kReplica:
593  G4Exception("G4Navigator::LocateGlobalPointWithinVolume()",
594  "GeomNav0001", FatalException,
595  "Not applicable for replicated volumes.");
596  break;
597  }
598  }
599 
600  // Reset the state variables
601  // - which would have been affected
602  // by the 'equivalent' call to LocateGlobalPointAndSetup
603  // - who's values have been invalidated by the 'move'.
604  //
606  fBlockedReplicaNo = -1;
607  fEntering = false;
608  fEnteredDaughter = false; // Boundary not encountered, did not enter
609  fExiting = false;
610  fExitedMother = false; // Boundary not encountered, did not exit
611 }
612 
613 // ********************************************************************
614 // SetSavedState
615 //
616 // Save the state, in case this is a parasitic call
617 // Save fValidExitNormal, fExitNormal, fExiting, fEntering,
618 // fBlockedPhysicalVolume, fBlockedReplicaNo, fLastStepWasZero;
619 // Note: the state of dependent objects is not currently saved.
620 // This means that the full state is changed by calls between
621 // SetSavedState() and RestoreSavedState();
622 // ********************************************************************
623 //
625 {
630 
633 
635 
641 
642  // Even the safety sphere - if you want to change it do it explicitly!
643  //
646 }
647 
648 // ********************************************************************
649 // RestoreSavedState
650 //
651 // Restore the state (in Compute Step), in case this is a parasitic call
652 // ********************************************************************
653 //
655 {
660 
663 
665 
671 
674 }
675 
676 // ********************************************************************
677 // ComputeStep
678 //
679 // Computes the next geometric Step: intersections with current
680 // mother and `daughter' volumes.
681 //
682 // NOTE:
683 //
684 // Flags on entry:
685 // --------------
686 // fValidExitNormal - Normal of exited volume is valid (convex, not a
687 // coincident boundary)
688 // fExitNormal - Surface normal of exited volume
689 // fExiting - True if have exited solid
690 //
691 // fBlockedPhysicalVolume - Ptr to exited volume (or 0)
692 // fBlockedReplicaNo - Replication no of exited volume
693 // fLastStepWasZero - True if last Step size was zero.
694 //
695 // Flags on exit:
696 // -------------
697 // fValidExitNormal - True if surface normal of exited volume is valid
698 // fExitNormal - Surface normal of exited volume rotated to mothers
699 // reference system
700 // fExiting - True if exiting mother
701 // fEntering - True if entering `daughter' volume (or replica)
702 // fBlockedPhysicalVolume - Ptr to candidate (entered) volume
703 // fBlockedReplicaNo - Replication no of candidate (entered) volume
704 // fLastStepWasZero - True if this Step size was zero.
705 // ********************************************************************
706 //
708  const G4ThreeVector &pDirection,
709  const G4double pCurrentProposedStepLength,
710  G4double &pNewSafety)
711 {
712  G4ThreeVector localDirection = ComputeLocalAxis(pDirection);
714  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
715  G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
716 
717  // All state relating to exiting normals must be reset
718  //
720  // Reset value - to erase its memory
722  // Reset - used for local exit normal
723  fGrandMotherExitNormal= G4ThreeVector( 0., 0., 0.);
724  fCalculatedExitNormal = false;
725  // Reset for new step
726 
727  static G4ThreadLocal G4int sNavCScalls=0;
728  sNavCScalls++;
729 
731 
732 #ifdef G4VERBOSE
733  if( fVerbose > 0 )
734  {
735  G4cout << "*** G4Navigator::ComputeStep: ***" << G4endl;
736  G4cout << " Volume = " << motherPhysical->GetName()
737  << " - Proposed step length = " << pCurrentProposedStepLength
738  << G4endl;
739 #ifdef G4DEBUG_NAVIGATION
740  if( fVerbose >= 2 )
741  {
742  G4cout << " Called with the arguments: " << G4endl
743  << " Globalpoint = " << std::setw(25) << pGlobalpoint << G4endl
744  << " Direction = " << std::setw(25) << pDirection << G4endl;
745  if( fVerbose >= 4 )
746  {
747  G4cout << " ---- Upon entering : State" << G4endl;
748  PrintState();
749  }
750  }
751 #endif
752  }
753 #endif
754 
755  G4ThreeVector newLocalPoint = ComputeLocalPoint(pGlobalpoint);
756  if( newLocalPoint != fLastLocatedPointLocal )
757  {
758  // Check whether the relocation is within safety
759  //
760  G4ThreeVector oldLocalPoint = fLastLocatedPointLocal;
761  G4double moveLenSq = (newLocalPoint-oldLocalPoint).mag2();
762 
763  if ( moveLenSq >= kCarTolerance*kCarTolerance )
764  {
765 #ifdef G4VERBOSE
766  ComputeStepLog(pGlobalpoint, moveLenSq);
767 #endif
768  // Relocate the point within the same volume
769  //
770  LocateGlobalPointWithinVolume( pGlobalpoint );
771  fLastTriedStepComputation= true; // Ensure that this is set again !!
772  }
773  }
775  {
776  switch( CharacteriseDaughters(motherLogical) )
777  {
778  case kNormal:
779  if ( motherLogical->GetVoxelHeader() )
780  {
782  localDirection,
783  pCurrentProposedStepLength,
784  pNewSafety,
785  fHistory,
787  fExitNormal,
788  fExiting,
789  fEntering,
792 
793  }
794  else
795  {
796  if( motherPhysical->GetRegularStructureId() == 0 )
797  {
799  localDirection,
800  pCurrentProposedStepLength,
801  pNewSafety,
802  fHistory,
804  fExitNormal,
805  fExiting,
806  fEntering,
809  }
810  else // Regular (non-voxelised) structure
811  {
812  LocateGlobalPointAndSetup( pGlobalpoint, &pDirection, true, true );
813  fLastTriedStepComputation= true; // Ensure that this is set again !!
814  //
815  // if physical process limits the step, the voxel will not be the
816  // one given by ComputeStepSkippingEqualMaterials() and the local
817  // point will be wrongly calculated.
818 
819  // There is a problem: when msc limits the step and the point is
820  // assigned wrongly to phantom in previous step (while it is out
821  // of the container volume). Then LocateGlobalPointAndSetup() has
822  // reset the history topvolume to world.
823  //
825  {
826  G4Exception("G4Navigator::ComputeStep()",
827  "GeomNav1001", JustWarning,
828  "Point is relocated in voxels, while it should be outside!");
830  localDirection,
831  pCurrentProposedStepLength,
832  pNewSafety,
833  fHistory,
835  fExitNormal,
836  fExiting,
837  fEntering,
840  }
841  else
842  {
843  Step = fregularNav.
844  ComputeStepSkippingEqualMaterials(fLastLocatedPointLocal,
845  localDirection,
846  pCurrentProposedStepLength,
847  pNewSafety,
848  fHistory,
850  fExitNormal,
851  fExiting,
852  fEntering,
855  motherPhysical);
856  }
857  }
858  }
859  break;
860  case kParameterised:
861  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
862  {
864  localDirection,
865  pCurrentProposedStepLength,
866  pNewSafety,
867  fHistory,
869  fExitNormal,
870  fExiting,
871  fEntering,
874  }
875  else // Regular structure
876  {
878  localDirection,
879  pCurrentProposedStepLength,
880  pNewSafety,
881  fHistory,
883  fExitNormal,
884  fExiting,
885  fEntering,
888  }
889  break;
890  case kReplica:
891  G4Exception("G4Navigator::ComputeStep()", "GeomNav0001",
892  FatalException, "Not applicable for replicated volumes.");
893  break;
894  }
895  }
896  else
897  {
898  // In the case of a replica, it must handle the exiting
899  // edge/corner problem by itself
900  //
901  G4bool exitingReplica = fExitedMother;
902  G4bool calculatedExitNormal;
903  Step = freplicaNav.ComputeStep(pGlobalpoint,
904  pDirection,
906  localDirection,
907  pCurrentProposedStepLength,
908  pNewSafety,
909  fHistory,
911  calculatedExitNormal,
912  fExitNormal,
913  exitingReplica,
914  fEntering,
917  fExiting= exitingReplica;
918  fCalculatedExitNormal= calculatedExitNormal;
919  }
920 
921  // Remember last safety origin & value.
922  //
923  fPreviousSftOrigin = pGlobalpoint;
924  fPreviousSafety = pNewSafety;
925 
926  // Count zero steps - one can occur due to changing momentum at a boundary
927  // - one, two (or a few) can occur at common edges between
928  // volumes
929  // - more than two is likely a problem in the geometry
930  // description or the Navigation
931 
932  // Rule of thumb: likely at an Edge if two consecutive steps are zero,
933  // because at least two candidate volumes must have been
934  // checked
935  //
936  fLocatedOnEdge = fLastStepWasZero && (Step==0.0);
937  fLastStepWasZero = (Step==0.0);
938  if (fPushed) { fPushed = fLastStepWasZero; }
939 
940  // Handle large number of consecutive zero steps
941  //
942  if ( fLastStepWasZero )
943  {
945 #ifdef G4DEBUG_NAVIGATION
946  if( fNumberZeroSteps > 1 )
947  {
948  G4cout << "G4Navigator::ComputeStep(): another zero step, # "
950  << " at " << pGlobalpoint
951  << " in volume " << motherPhysical->GetName()
952  << " nav-comp-step calls # " << sNavCScalls
953  << G4endl;
954  }
955 #endif
957  {
958  // Act to recover this stuck track. Pushing it along direction
959  //
960  Step += 100*kCarTolerance;
961 #ifdef G4VERBOSE
962  if ((!fPushed) && (fWarnPush))
963  {
964  std::ostringstream message;
965  message << "Track stuck or not moving." << G4endl
966  << " Track stuck, not moving for "
967  << fNumberZeroSteps << " steps" << G4endl
968  << " in volume -" << motherPhysical->GetName()
969  << "- at point " << pGlobalpoint << G4endl
970  << " direction: " << pDirection << "." << G4endl
971  << " Potential geometry or navigation problem !"
972  << G4endl
973  << " Trying pushing it of " << Step << " mm ...";
974  G4Exception("G4Navigator::ComputeStep()", "GeomNav1002",
975  JustWarning, message, "Potential overlap in geometry!");
976  }
977 #endif
978  fPushed = true;
979  }
981  {
982  // Must kill this stuck track
983  //
984  std::ostringstream message;
985  message << "Stuck Track: potential geometry or navigation problem."
986  << G4endl
987  << " Track stuck, not moving for "
988  << fNumberZeroSteps << " steps" << G4endl
989  << " in volume -" << motherPhysical->GetName()
990  << "- at point " << pGlobalpoint << G4endl
991  << " direction: " << pDirection << ".";
992  motherPhysical->CheckOverlaps(5000, false);
993  G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
994  EventMustBeAborted, message);
995  }
996  }
997  else
998  {
999  if (!fPushed) fNumberZeroSteps = 0;
1000  }
1001 
1002  fEnteredDaughter = fEntering; // I expect to enter a volume in this Step
1004 
1005  fStepEndPoint = pGlobalpoint + Step * pDirection;
1006  fLastStepEndPointLocal = fLastLocatedPointLocal + Step * localDirection;
1007 
1008  if( fExiting )
1009  {
1010 #ifdef G4DEBUG_NAVIGATION
1011  if( fVerbose > 2 )
1012  {
1013  G4cout << " At G4Nav CompStep End - if(exiting) - fExiting= " << fExiting
1014  << " fValidExitNormal = " << fValidExitNormal << G4endl;
1015  G4cout << " fExitNormal= " << fExitNormal << G4endl;
1016  }
1017 #endif
1018 
1020  {
1022  {
1023  // Convention: fExitNormal is in the 'grand-mother' coordinate system
1024  //
1026  fCalculatedExitNormal= true;
1027  }
1028  else
1029  {
1031  }
1032  }
1033  else
1034  {
1035  // We must calculate the normal anyway (in order to have it if requested)
1036  //
1037  G4ThreeVector finalLocalPoint =
1038  fLastLocatedPointLocal + localDirection*Step;
1039 
1041  {
1042  // Find normal in the 'mother' coordinate system
1043  //
1044  G4ThreeVector exitNormalMotherFrame=
1045  motherLogical->GetSolid()->SurfaceNormal(finalLocalPoint);
1046 
1047  // Transform it to the 'grand-mother' coordinate system
1048  //
1049  const G4RotationMatrix* mRot = motherPhysical->GetRotation();
1050  if( mRot )
1051  {
1053  fGrandMotherExitNormal = (*mRot).inverse() * exitNormalMotherFrame;
1054  }
1055  else
1056  {
1057  fGrandMotherExitNormal = exitNormalMotherFrame;
1058  }
1059 
1060  // Do not set fValidExitNormal -- this signifies
1061  // that the solid is convex!
1062  //
1063  fCalculatedExitNormal= true;
1064  }
1065  else
1066  {
1067  fCalculatedExitNormal = false;
1068  //
1069  // Nothing can be done at this stage currently - to solve this
1070  // Replica Navigation must have calculated the normal for this case
1071  // already.
1072  // Cases: mother is not convex, and exit is at previous replica level
1073 
1074 #ifdef G4DEBUG_NAVIGATION
1076 
1077  desc << "Problem in ComputeStep: Replica Navigation did not provide"
1078  << " valid exit Normal. " << G4endl;
1079  desc << " Do not know how calculate it in this case." << G4endl;
1080  desc << " Location = " << finalLocalPoint << G4endl;
1081  desc << " Volume name = " << motherPhysical->GetName()
1082  << " copy/replica No = " << motherPhysical->GetCopyNo() << G4endl;
1083  G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
1084  JustWarning, desc, "Normal not available for exiting.");
1085 #endif
1086  }
1087  }
1088 
1089  // Now transform it to the global reference frame !!
1090  //
1092  {
1093  G4int depth= fHistory.GetDepth();
1094  if( depth > 0 )
1095  {
1096  G4AffineTransform GrandMotherToGlobalTransf =
1097  fHistory.GetTransform(depth-1).Inverse();
1099  GrandMotherToGlobalTransf.TransformAxis( fGrandMotherExitNormal );
1100  }
1101  else
1102  {
1104  }
1105  }
1106  else
1107  {
1108  fExitNormalGlobalFrame= G4ThreeVector( 0., 0., 0.);
1109  }
1110  }
1111 
1112  if( (Step == pCurrentProposedStepLength) && (!fExiting) && (!fEntering) )
1113  {
1114  // This if Step is not really limited by the geometry.
1115  // The Navigator is obliged to return "infinity"
1116  //
1117  Step = kInfinity;
1118  }
1119 
1120 #ifdef G4VERBOSE
1121  if( fVerbose > 1 )
1122  {
1123  if( fVerbose >= 4 )
1124  {
1125  G4cout << " ----- Upon exiting :" << G4endl;
1126  PrintState();
1127  }
1128  G4cout << " Returned step= " << Step;
1129  if( fVerbose > 5 ) G4cout << G4endl;
1130  if( Step == kInfinity )
1131  {
1132  G4cout << " Requested step= " << pCurrentProposedStepLength ;
1133  if( fVerbose > 5) G4cout << G4endl;
1134  }
1135  G4cout << " Safety = " << pNewSafety << G4endl;
1136  }
1137 #endif
1138 
1139  return Step;
1140 }
1141 
1142 // ********************************************************************
1143 // CheckNextStep
1144 //
1145 // Compute the step without altering the navigator state
1146 // ********************************************************************
1147 //
1149  const G4ThreeVector& pDirection,
1150  const G4double pCurrentProposedStepLength,
1151  G4double& pNewSafety)
1152 {
1153  G4double step;
1154 
1155  // Save the state, for this parasitic call
1156  //
1157  SetSavedState();
1158 
1159  step = ComputeStep ( pGlobalpoint,
1160  pDirection,
1161  pCurrentProposedStepLength,
1162  pNewSafety );
1163 
1164  // It is a parasitic call, so attempt to restore the key parts of the state
1165  //
1166  RestoreSavedState();
1167  // NOTE: the state of the current subnavigator is NOT restored.
1168  // ***> TODO: restore subnavigator state
1169  // if( last_located) Need Position of last location
1170  // if( last_computed step) Need Endposition of last step
1171 
1172  return step;
1173 }
1174 
1175 // ********************************************************************
1176 // ResetState
1177 //
1178 // Resets stack and minimum of navigator state `machine'
1179 // ********************************************************************
1180 //
1182 {
1183  fWasLimitedByGeometry = false;
1184  fEntering = false;
1185  fExiting = false;
1186  fLocatedOnEdge = false;
1187  fLastStepWasZero = false;
1188  fEnteredDaughter = false;
1189  fExitedMother = false;
1190  fPushed = false;
1191 
1192  fValidExitNormal = false;
1194  fCalculatedExitNormal = false;
1195 
1196  fExitNormal = G4ThreeVector(0,0,0);
1199 
1201  fPreviousSafety = 0.0;
1202 
1203  fNumberZeroSteps = 0;
1204 
1206  fBlockedReplicaNo = -1;
1207 
1209  fLocatedOutsideWorld = false;
1210 }
1211 
1212 // ********************************************************************
1213 // SetupHierarchy
1214 //
1215 // Renavigates & resets hierarchy described by current history
1216 // o Reset volumes
1217 // o Recompute transforms and/or solids of replicated/parameterised volumes
1218 // ********************************************************************
1219 //
1221 {
1222  G4int i;
1223  const G4int cdepth = fHistory.GetDepth();
1224  G4VPhysicalVolume *current;
1225  G4VSolid *pSolid;
1226  G4VPVParameterisation *pParam;
1227 
1228  for ( i=1; i<=cdepth; i++ )
1229  {
1230  current = fHistory.GetVolume(i);
1231  switch ( fHistory.GetVolumeType(i) )
1232  {
1233  case kNormal:
1234  break;
1235  case kReplica:
1237  break;
1238  case kParameterised:
1239  G4int replicaNo;
1240  pParam = current->GetParameterisation();
1241  replicaNo = fHistory.GetReplicaNo(i);
1242  pSolid = pParam->ComputeSolid(replicaNo, current);
1243 
1244  // Set up dimensions & transform in solid/physical volume
1245  //
1246  pSolid->ComputeDimensions(pParam, replicaNo, current);
1247  pParam->ComputeTransformation(replicaNo, current);
1248 
1249  G4TouchableHistory *pTouchable= 0;
1250  if( pParam->IsNested() ) {
1251  pTouchable= new G4TouchableHistory( fHistory );
1252  pTouchable->MoveUpHistory(); // move up to the parent level
1253  // Adequate only if Nested at the Branch level (last)
1254  // To extend to other cases:
1255  // pTouchable->MoveUpHistory(cdepth-i-1); // move to the parent level of *Current* level // Could replace this line and constructor with a revised c-tor for History( levels to drop)
1256  }
1257  // Set up the correct solid and material in Logical Volume
1258  //
1259  G4LogicalVolume *pLogical = current->GetLogicalVolume();
1260  pLogical->SetSolid( pSolid );
1261  pLogical->UpdateMaterial( pParam ->
1262  ComputeMaterial(replicaNo, current, pTouchable) );
1263  delete pTouchable;
1264  break;
1265  }
1266  }
1267 }
1268 
1269 // ********************************************************************
1270 // GetLocalExitNormal
1271 //
1272 // Obtains the Normal vector to a surface (in local coordinates)
1273 // pointing out of previous volume and into current volume
1274 // ********************************************************************
1275 //
1277 {
1278  G4ThreeVector ExitNormal(0.,0.,0.);
1279  G4VSolid *currentSolid=0;
1280  G4LogicalVolume *candidateLogical;
1282  {
1283  // use fLastLocatedPointLocal and next candidate volume
1284  //
1285  G4ThreeVector nextSolidExitNormal(0.,0.,0.);
1286 
1287  if( fEntering && (fBlockedPhysicalVolume!=0) )
1288  {
1289  candidateLogical= fBlockedPhysicalVolume->GetLogicalVolume();
1290  if( candidateLogical )
1291  {
1292  // fLastStepEndPointLocal is in the coordinates of the mother
1293  // we need it in the daughter's coordinate system.
1294 
1295  // The following code should also work in case of Replica
1296  {
1297  // First transform fLastLocatedPointLocal to the new daughter
1298  // coordinates
1299  //
1300  G4AffineTransform MotherToDaughterTransform=
1304  G4ThreeVector daughterPointOwnLocal=
1305  MotherToDaughterTransform.TransformPoint( fLastStepEndPointLocal );
1306 
1307  // OK if it is a parameterised volume
1308  //
1309  EInside inSideIt;
1310  G4bool onSurface;
1311  G4double safety= -1.0;
1312  currentSolid= candidateLogical->GetSolid();
1313  inSideIt = currentSolid->Inside(daughterPointOwnLocal);
1314  onSurface = (inSideIt == kSurface);
1315  if( ! onSurface )
1316  {
1317  if( inSideIt == kOutside )
1318  {
1319  safety = (currentSolid->DistanceToIn(daughterPointOwnLocal));
1320  onSurface = safety < 100.0 * kCarTolerance;
1321  }
1322  else if (inSideIt == kInside )
1323  {
1324  safety = (currentSolid->DistanceToOut(daughterPointOwnLocal));
1325  onSurface = safety < 100.0 * kCarTolerance;
1326  }
1327  }
1328 
1329  if( onSurface )
1330  {
1331  nextSolidExitNormal =
1332  currentSolid->SurfaceNormal(daughterPointOwnLocal);
1333 
1334  // Entering the solid ==> opposite
1335  //
1336  ExitNormal = -nextSolidExitNormal;
1337  fCalculatedExitNormal= true;
1338  }
1339  else
1340  {
1341 #ifdef G4VERBOSE
1342  if(( fVerbose == 1 ) && ( fCheck ))
1343  {
1344  std::ostringstream message;
1345  message << "Point not on surface ! " << G4endl
1346  << " Point = "
1347  << daughterPointOwnLocal << G4endl
1348  << " Physical volume = "
1350  << " Logical volume = "
1351  << candidateLogical->GetName() << G4endl
1352  << " Solid = " << currentSolid->GetName()
1353  << " Type = "
1354  << currentSolid->GetEntityType() << G4endl
1355  << *currentSolid << G4endl;
1356  if( inSideIt == kOutside )
1357  {
1358  message << "Point is Outside. " << G4endl
1359  << " Safety (from outside) = " << safety << G4endl;
1360  }
1361  else // if( inSideIt == kInside )
1362  {
1363  message << "Point is Inside. " << G4endl
1364  << " Safety (from inside) = " << safety << G4endl;
1365  }
1366  G4Exception("G4Navigator::GetLocalExitNormal()", "GeomNav1001",
1367  JustWarning, message);
1368  }
1369 #endif
1370  }
1371  *valid = onSurface; // was =true;
1372  }
1373  }
1374  }
1375  else if ( fExiting )
1376  {
1377  ExitNormal = fGrandMotherExitNormal;
1378  *valid = true;
1379  fCalculatedExitNormal= true; // Should be true already
1380  }
1381  else // i.e. ( fBlockedPhysicalVolume == 0 )
1382  {
1383  *valid = false;
1384  G4Exception("G4Navigator::GetLocalExitNormal()",
1385  "GeomNav0003", JustWarning,
1386  "Incorrect call to GetLocalSurfaceNormal." );
1387  }
1388  }
1389  else // ( ! fLastTriedStepComputation ) ie. last call was to Locate
1390  {
1391  if ( EnteredDaughterVolume() )
1392  {
1393  G4VSolid* daughterSolid =fHistory.GetTopVolume()->GetLogicalVolume()
1394  ->GetSolid();
1395  ExitNormal= -(daughterSolid->SurfaceNormal(fLastLocatedPointLocal));
1396  if( std::fabs(ExitNormal.mag2()-1.0 ) > CLHEP::perMillion )
1397  {
1399  desc << " Parameters of solid: " << *daughterSolid
1400  << " Point for surface = " << fLastLocatedPointLocal << std::endl;
1401  G4Exception("G4Navigator::GetLocalExitNormal()",
1402  "GeomNav0003", FatalException, desc,
1403  "Surface Normal returned by Solid is not a Unit Vector." );
1404  }
1405  fCalculatedExitNormal= true;
1406  *valid = true;
1407  }
1408  else
1409  {
1410  if( fExitedMother )
1411  {
1412  ExitNormal = fGrandMotherExitNormal;
1413  *valid = true;
1414  fCalculatedExitNormal= true;
1415  }
1416  else // We are not at a boundary. ExitNormal remains (0,0,0)
1417  {
1418  *valid = false;
1419  fCalculatedExitNormal= false;
1420  G4ExceptionDescription message;
1421  message << "Function called when *NOT* at a Boundary." << G4endl;
1422  G4Exception("G4Navigator::GetLocalExitNormal()",
1423  "GeomNav0003", JustWarning, message);
1424  }
1425  }
1426  }
1427  return ExitNormal;
1428 }
1429 
1430 // ********************************************************************
1431 // GetMotherToDaughterTransform
1432 //
1433 // Obtains the mother to daughter affine transformation
1434 // ********************************************************************
1435 //
1438  G4int enteringReplicaNo,
1439  EVolume enteringVolumeType )
1440 {
1441  switch (enteringVolumeType)
1442  {
1443  case kNormal: // Nothing is needed to prepare the transformation
1444  break; // It is stored already in the physical volume (placement)
1445  case kReplica: // Sets the transform in the Replica - tbc
1446  G4Exception("G4Navigator::GetMotherToDaughterTransform()",
1447  "GeomNav0001", FatalException,
1448  "Method NOT Implemented yet for replica volumes.");
1449  break;
1450  case kParameterised:
1451  if( pEnteringPhysVol->GetRegularStructureId() == 0 )
1452  {
1453  G4VPVParameterisation *pParam =
1454  pEnteringPhysVol->GetParameterisation();
1455  G4VSolid* pSolid =
1456  pParam->ComputeSolid(enteringReplicaNo, pEnteringPhysVol);
1457  pSolid->ComputeDimensions(pParam, enteringReplicaNo, pEnteringPhysVol);
1458 
1459  // Sets the transform in the Parameterisation
1460  //
1461  pParam->ComputeTransformation(enteringReplicaNo, pEnteringPhysVol);
1462 
1463  // Set the correct solid and material in Logical Volume
1464  //
1465  G4LogicalVolume* pLogical = pEnteringPhysVol->GetLogicalVolume();
1466  pLogical->SetSolid( pSolid );
1467  }
1468  break;
1469  }
1470  return G4AffineTransform(pEnteringPhysVol->GetRotation(),
1471  pEnteringPhysVol->GetTranslation()).Invert();
1472 }
1473 
1474 // ********************************************************************
1475 // GetLocalExitNormalAndCheck
1476 //
1477 // Obtains the Normal vector to a surface (in local coordinates)
1478 // pointing out of previous volume and into current volume, and
1479 // checks the current point against expected 'local' value.
1480 // ********************************************************************
1481 //
1484 #ifdef G4DEBUG_NAVIGATION
1485  const G4ThreeVector& ExpectedBoundaryPointGlobal,
1486 #else
1487  const G4ThreeVector&,
1488 #endif
1489  G4bool* pValid)
1490 {
1491 #ifdef G4DEBUG_NAVIGATION
1492  // Check Current point against expected 'local' value
1493  //
1495  {
1496  G4ThreeVector ExpectedBoundaryPointLocal;
1497 
1498  const G4AffineTransform& GlobalToLocal= GetGlobalToLocalTransform();
1499  ExpectedBoundaryPointLocal =
1500  GlobalToLocal.TransformPoint( ExpectedBoundaryPointGlobal );
1501 
1502  // Add here: Comparison against expected position,
1503  // i.e. the endpoint of ComputeStep
1504  }
1505 #endif
1506 
1507  return GetLocalExitNormal( pValid);
1508 }
1509 
1510 // ********************************************************************
1511 // GetGlobalExitNormal
1512 //
1513 // Obtains the Normal vector to a surface (in global coordinates)
1514 // pointing out of previous volume and into current volume
1515 // ********************************************************************
1516 //
1519  G4bool* pNormalCalculated)
1520 {
1521  G4bool validNormal;
1522  G4ThreeVector localNormal, globalNormal;
1523 
1525  {
1526  // This was computed in ComputeStep -- and only on arrival at boundary
1527  //
1528  globalNormal = fExitNormalGlobalFrame;
1529  *pNormalCalculated = true; // ComputeStep always computes it if Exiting
1530  // (fExiting==true)
1531  }
1532  else
1533  {
1534  localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,&validNormal);
1535  *pNormalCalculated = fCalculatedExitNormal;
1536 
1537 #ifdef G4DEBUG_NAVIGATION
1538  if( (!validNormal) && !fCalculatedExitNormal)
1539  {
1541  edN << " Calculated = " << fCalculatedExitNormal << G4endl;
1542  edN << " Entering= " << fEntering << G4endl;
1543  G4int oldVerbose= this->GetVerboseLevel();
1544  this->SetVerboseLevel(4);
1545  edN << " State of Navigator: " << G4endl;
1546  edN << *this << G4endl;
1547  this->SetVerboseLevel( oldVerbose );
1548 
1549  G4Exception("G4Navigator::GetGlobalExitNormal()",
1550  "GeomNav0003", JustWarning, edN,
1551  "LocalExitNormalAndCheck() did not calculate Normal.");
1552  }
1553 #endif
1554 
1555  G4double localMag2= localNormal.mag2();
1556  if( validNormal && (std::fabs(localMag2-1.0)) > CLHEP::perMillion )
1557  {
1559 
1560  edN << "G4Navigator::GetGlobalExitNormal: "
1561  << " Using Local Normal - from call to GetLocalExitNormalAndCheck. "
1562  << G4endl
1563  << " Local Exit Normal = " << localNormal << " || = "
1564  << std::sqrt(localMag2) << G4endl
1565  << " Global Exit Normal = " << globalNormal << " || = "
1566  << globalNormal.mag() << G4endl;
1567  edN << " Calculated It = " << fCalculatedExitNormal << G4endl;
1568 
1569  G4Exception("G4Navigator::GetGlobalExitNormal()",
1570  "GeomNav0003",JustWarning, edN,
1571  "Value obtained from new local *solid* is incorrect.");
1572  localNormal = localNormal.unit(); // Should we correct it ??
1573  }
1574  G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1575  globalNormal = localToGlobal.TransformAxis( localNormal );
1576  }
1577 
1578 #ifdef G4DEBUG_NAVIGATION
1579  // Temporary extra checks
1581  {
1582  localNormal = GetLocalExitNormalAndCheck( IntersectPointGlobal, &validNormal);
1583  *pNormalCalculated = fCalculatedExitNormal;
1584 
1585  G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1586  globalNormal = localToGlobal.TransformAxis( localNormal );
1587 
1588  // Check the value computed against fExitNormalGlobalFrame
1589  G4ThreeVector diffNorm = globalNormal - fExitNormalGlobalFrame;
1590  if( diffNorm.mag2() > perMillion*CLHEP::perMillion)
1591  {
1592  G4ExceptionDescription edDfn;
1593  edDfn << "Found difference in normals in case of exiting mother "
1594  << "- when Get is called after ComputingStep " << G4endl;
1595  edDfn << " Magnitude of diff = " << diffNorm.mag() << G4endl;
1596  edDfn << " Normal stored (Global) = " << fExitNormalGlobalFrame
1597  << G4endl;
1598  edDfn << " Global Computed from Local = " << globalNormal << G4endl;
1599  G4Exception("G4Navigator::GetGlobalExitNormal()", "GeomNav0003",
1600  JustWarning, edDfn);
1601  }
1602  }
1603 #endif
1604 
1605  return globalNormal;
1606 }
1607 
1608 // To make the new Voxel Safety the default, uncomment the next line
1609 #define G4NEW_SAFETY 1
1610 
1611 // ********************************************************************
1612 // ComputeSafety
1613 //
1614 // It assumes that it will be
1615 // i) called at the Point in the same volume as the EndPoint of the
1616 // ComputeStep.
1617 // ii) after (or at the end of) ComputeStep OR after the relocation.
1618 // ********************************************************************
1619 //
1621  const G4double pMaxLength,
1622  const G4bool keepState)
1623 {
1624  G4double newSafety = 0.0;
1625 
1626 #ifdef G4DEBUG_NAVIGATION
1627  G4int oldcoutPrec = G4cout.precision(8);
1628  if( fVerbose > 0 )
1629  {
1630  G4cout << "*** G4Navigator::ComputeSafety: ***" << G4endl
1631  << " Called at point: " << pGlobalpoint << G4endl;
1632 
1633  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
1634  G4cout << " Volume = " << motherPhysical->GetName()
1635  << " - Maximum length = " << pMaxLength << G4endl;
1636  if( fVerbose >= 4 )
1637  {
1638  G4cout << " ----- Upon entering Compute Safety:" << G4endl;
1639  PrintState();
1640  }
1641  }
1642 #endif
1643 
1644  if (keepState) { SetSavedState(); }
1645 
1646  G4double distEndpointSq = (pGlobalpoint-fStepEndPoint).mag2();
1647  G4bool stayedOnEndpoint = distEndpointSq < kCarTolerance*kCarTolerance;
1648  G4bool endpointOnSurface = fEnteredDaughter || fExitedMother;
1649 
1650  if( !(endpointOnSurface && stayedOnEndpoint) )
1651  {
1652  // Pseudo-relocate to this point (updates voxel information only)
1653  //
1654  LocateGlobalPointWithinVolume( pGlobalpoint );
1655  // --->> DANGER: Side effects on sub-navigator voxel information <<---
1656  // Could be replaced again by 'granular' calls to sub-navigator
1657  // locates (similar side-effects, but faster.
1658  // Solutions:
1659  // 1) Re-locate (to where?)
1660  // 2) Insure that the methods using (G4ComputeStep?)
1661  // does a relocation (if information is disturbed only ?)
1662 
1663 #ifdef G4DEBUG_NAVIGATION
1664  if( fVerbose >= 2 )
1665  {
1666  G4cout << " G4Navigator::ComputeSafety() relocates-in-volume to point: "
1667  << pGlobalpoint << G4endl;
1668  }
1669 #endif
1670  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
1671  G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
1672  G4SmartVoxelHeader* pVoxelHeader = motherLogical->GetVoxelHeader();
1673  G4ThreeVector localPoint = ComputeLocalPoint(pGlobalpoint);
1674 
1676  {
1677  switch(CharacteriseDaughters(motherLogical))
1678  {
1679  case kNormal:
1680  if ( pVoxelHeader )
1681  {
1682 #ifdef G4NEW_SAFETY
1683  G4double safetyTwo = fpVoxelSafety->ComputeSafety(localPoint,
1684  *motherPhysical, pMaxLength);
1685  newSafety= safetyTwo; // Faster and best available
1686 #else
1687  G4double safetyOldVoxel;
1688  safetyOldVoxel =
1689  fvoxelNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1690  newSafety= safetyOldVoxel;
1691 #endif
1692  }
1693  else
1694  {
1695  newSafety=fnormalNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1696  }
1697  break;
1698  case kParameterised:
1699  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
1700  {
1701  newSafety=fparamNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1702  }
1703  else // Regular structure
1704  {
1705  newSafety=fregularNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1706  }
1707  break;
1708  case kReplica:
1709  G4Exception("G4Navigator::ComputeSafety()", "GeomNav0001",
1710  FatalException, "Not applicable for replicated volumes.");
1711  break;
1712  }
1713  }
1714  else
1715  {
1716  newSafety = freplicaNav.ComputeSafety(pGlobalpoint, localPoint,
1717  fHistory, pMaxLength);
1718  }
1719  }
1720  else // if( endpointOnSurface && stayedOnEndpoint )
1721  {
1722 #ifdef G4DEBUG_NAVIGATION
1723  if( fVerbose >= 2 )
1724  {
1725  G4cout << " G4Navigator::ComputeSafety() finds that point - "
1726  << pGlobalpoint << " - is on surface " << G4endl;
1727  if( fEnteredDaughter ) { G4cout << " entered new daughter volume"; }
1728  if( fExitedMother ) { G4cout << " and exited previous volume."; }
1729  G4cout << G4endl;
1730  G4cout << " EndPoint was = " << fStepEndPoint << G4endl;
1731  }
1732 #endif
1733  newSafety = 0.0;
1734  }
1735 
1736  if (keepState)
1737  {
1739  // This now overwrites the values of the Safety 'sphere' (correction)
1740  }
1741 
1742  // Remember last safety origin & value
1743  //
1744  // We overwrite the Safety 'sphere' - keeping old behaviour
1745  fPreviousSftOrigin = pGlobalpoint;
1746  fPreviousSafety = newSafety;
1747 
1748 #ifdef G4DEBUG_NAVIGATION
1749  if( fVerbose > 1 )
1750  {
1751  G4cout << " ---- Exiting ComputeSafety " << G4endl;
1752  if( fVerbose > 2 ) { PrintState(); }
1753  G4cout << " Returned value of Safety = " << newSafety << G4endl;
1754  }
1755  G4cout.precision(oldcoutPrec);
1756 #endif
1757 
1758  return newSafety;
1759 }
1760 
1761 // ********************************************************************
1762 // CreateTouchableHistoryHandle
1763 // ********************************************************************
1764 //
1766 {
1768 }
1769 
1770 // ********************************************************************
1771 // PrintState
1772 // ********************************************************************
1773 //
1775 {
1776  G4int oldcoutPrec = G4cout.precision(4);
1777  if( fVerbose == 4 )
1778  {
1779  G4cout << "The current state of G4Navigator is: " << G4endl;
1780  G4cout << " ValidExitNormal= " << fValidExitNormal << G4endl
1781  << " ExitNormal = " << fExitNormal << G4endl
1782  << " Exiting = " << fExiting << G4endl
1783  << " Entering = " << fEntering << G4endl
1784  << " BlockedPhysicalVolume= " ;
1785  if (fBlockedPhysicalVolume==0)
1786  G4cout << "None";
1787  else
1789  G4cout << G4endl
1790  << " BlockedReplicaNo = " << fBlockedReplicaNo << G4endl
1791  << " LastStepWasZero = " << fLastStepWasZero << G4endl
1792  << G4endl;
1793  }
1794  if( ( 1 < fVerbose) && (fVerbose < 4) )
1795  {
1796  G4cout << G4endl; // Make sure to line up
1797  G4cout << std::setw(30) << " ExitNormal " << " "
1798  << std::setw( 5) << " Valid " << " "
1799  << std::setw( 9) << " Exiting " << " "
1800  << std::setw( 9) << " Entering" << " "
1801  << std::setw(15) << " Blocked:Volume " << " "
1802  << std::setw( 9) << " ReplicaNo" << " "
1803  << std::setw( 8) << " LastStepZero " << " "
1804  << G4endl;
1805  G4cout << "( " << std::setw(7) << fExitNormal.x()
1806  << ", " << std::setw(7) << fExitNormal.y()
1807  << ", " << std::setw(7) << fExitNormal.z() << " ) "
1808  << std::setw( 5) << fValidExitNormal << " "
1809  << std::setw( 9) << fExiting << " "
1810  << std::setw( 9) << fEntering << " ";
1811  if ( fBlockedPhysicalVolume==0 )
1812  G4cout << std::setw(15) << "None";
1813  else
1814  G4cout << std::setw(15)<< fBlockedPhysicalVolume->GetName();
1815  G4cout << std::setw( 9) << fBlockedReplicaNo << " "
1816  << std::setw( 8) << fLastStepWasZero << " "
1817  << G4endl;
1818  }
1819  if( fVerbose > 2 )
1820  {
1821  G4cout.precision(8);
1822  G4cout << " Current Localpoint = " << fLastLocatedPointLocal << G4endl;
1823  G4cout << " PreviousSftOrigin = " << fPreviousSftOrigin << G4endl;
1824  G4cout << " PreviousSafety = " << fPreviousSafety << G4endl;
1825  }
1826  G4cout.precision(oldcoutPrec);
1827 }
1828 
1829 // ********************************************************************
1830 // ComputeStepLog
1831 // ********************************************************************
1832 //
1834  G4double moveLenSq) const
1835 {
1836  // The following checks only make sense if the move is larger
1837  // than the tolerance.
1838 
1839  static const G4double fAccuracyForWarning = kCarTolerance,
1840  fAccuracyForException = 1000*kCarTolerance;
1841 
1842  G4ThreeVector OriginalGlobalpoint = fHistory.GetTopTransform().Inverse().
1843  TransformPoint(fLastLocatedPointLocal);
1844 
1845  G4double shiftOriginSafSq = (fPreviousSftOrigin-pGlobalpoint).mag2();
1846 
1847  // Check that the starting point of this step is
1848  // within the isotropic safety sphere of the last point
1849  // to a accuracy/precision given by fAccuracyForWarning.
1850  // If so give warning.
1851  // If it fails by more than fAccuracyForException exit with error.
1852  //
1853  if( shiftOriginSafSq >= sqr(fPreviousSafety) )
1854  {
1855  G4double shiftOrigin = std::sqrt(shiftOriginSafSq);
1856  G4double diffShiftSaf = shiftOrigin - fPreviousSafety;
1857 
1858  if( diffShiftSaf > fAccuracyForWarning )
1859  {
1860  G4int oldcoutPrec= G4cout.precision(8);
1861  G4int oldcerrPrec= G4cerr.precision(10);
1862  std::ostringstream message, suggestion;
1863  message << "Accuracy error or slightly inaccurate position shift."
1864  << G4endl
1865  << " The Step's starting point has moved "
1866  << std::sqrt(moveLenSq)/mm << " mm " << G4endl
1867  << " since the last call to a Locate method." << G4endl
1868  << " This has resulted in moving "
1869  << shiftOrigin/mm << " mm "
1870  << " from the last point at which the safety "
1871  << " was calculated " << G4endl
1872  << " which is more than the computed safety= "
1873  << fPreviousSafety/mm << " mm at that point." << G4endl
1874  << " This difference is "
1875  << diffShiftSaf/mm << " mm." << G4endl
1876  << " The tolerated accuracy is "
1877  << fAccuracyForException/mm << " mm.";
1878 
1879  suggestion << " ";
1880  static G4ThreadLocal G4int warnNow = 0;
1881  if( ((++warnNow % 100) == 1) )
1882  {
1883  message << G4endl
1884  << " This problem can be due to either " << G4endl
1885  << " - a process that has proposed a displacement"
1886  << " larger than the current safety , or" << G4endl
1887  << " - inaccuracy in the computation of the safety";
1888  suggestion << "We suggest that you " << G4endl
1889  << " - find i) what particle is being tracked, and "
1890  << " ii) through what part of your geometry " << G4endl
1891  << " for example by re-running this event with "
1892  << G4endl
1893  << " /tracking/verbose 1 " << G4endl
1894  << " - check which processes you declare for"
1895  << " this particle (and look at non-standard ones)"
1896  << G4endl
1897  << " - in case, create a detailed logfile"
1898  << " of this event using:" << G4endl
1899  << " /tracking/verbose 6 ";
1900  }
1901  G4Exception("G4Navigator::ComputeStep()",
1902  "GeomNav1002", JustWarning,
1903  message, G4String(suggestion.str()));
1904  G4cout.precision(oldcoutPrec);
1905  G4cerr.precision(oldcerrPrec);
1906  }
1907 #ifdef G4DEBUG_NAVIGATION
1908  else
1909  {
1910  G4cerr << "WARNING - G4Navigator::ComputeStep()" << G4endl
1911  << " The Step's starting point has moved "
1912  << std::sqrt(moveLenSq) << "," << G4endl
1913  << " which has taken it to the limit of"
1914  << " the current safety. " << G4endl;
1915  }
1916 #endif
1917  }
1918  G4double safetyPlus = fPreviousSafety + fAccuracyForException;
1919  if ( shiftOriginSafSq > sqr(safetyPlus) )
1920  {
1921  std::ostringstream message;
1922  message << "May lead to a crash or unreliable results." << G4endl
1923  << " Position has shifted considerably without"
1924  << " notifying the navigator !" << G4endl
1925  << " Tolerated safety: " << safetyPlus << G4endl
1926  << " Computed shift : " << shiftOriginSafSq;
1927  G4Exception("G4Navigator::ComputeStep()", "GeomNav1002",
1928  JustWarning, message);
1929  }
1930 }
1931 
1932 // ********************************************************************
1933 // Operator <<
1934 // ********************************************************************
1935 //
1936 std::ostream& operator << (std::ostream &os,const G4Navigator &n)
1937 {
1938  // Old version did only the following:
1939  // os << "Current History: " << G4endl << n.fHistory;
1940  // Old behaviour is recovered for fVerbose = 0
1941 
1942  // Adapted from G4Navigator::PrintState() const
1943 
1944  G4int oldcoutPrec = os.precision(4);
1945  if( n.fVerbose >= 4 )
1946  {
1947  os << "The current state of G4Navigator is: " << G4endl;
1948  os << " ValidExitNormal= " << n.fValidExitNormal << G4endl
1949  << " ExitNormal = " << n.fExitNormal << G4endl
1950  << " Exiting = " << n.fExiting << G4endl
1951  << " Entering = " << n.fEntering << G4endl
1952  << " BlockedPhysicalVolume= " ;
1953  if (n.fBlockedPhysicalVolume==0)
1954  os << "None";
1955  else
1956  os << n.fBlockedPhysicalVolume->GetName();
1957  os << G4endl
1958  << " BlockedReplicaNo = " << n.fBlockedReplicaNo << G4endl
1959  << " LastStepWasZero = " << n.fLastStepWasZero << G4endl
1960  << G4endl;
1961  }
1962  if( ( 1 < n.fVerbose) && (n.fVerbose < 4) )
1963  {
1964  os << G4endl; // Make sure to line up
1965  os << std::setw(30) << " ExitNormal " << " "
1966  << std::setw( 5) << " Valid " << " "
1967  << std::setw( 9) << " Exiting " << " "
1968  << std::setw( 9) << " Entering" << " "
1969  << std::setw(15) << " Blocked:Volume " << " "
1970  << std::setw( 9) << " ReplicaNo" << " "
1971  << std::setw( 8) << " LastStepZero " << " "
1972  << G4endl;
1973  os << "( " << std::setw(7) << n.fExitNormal.x()
1974  << ", " << std::setw(7) << n.fExitNormal.y()
1975  << ", " << std::setw(7) << n.fExitNormal.z() << " ) "
1976  << std::setw( 5) << n.fValidExitNormal << " "
1977  << std::setw( 9) << n.fExiting << " "
1978  << std::setw( 9) << n.fEntering << " ";
1979  if ( n.fBlockedPhysicalVolume==0 )
1980  { os << std::setw(15) << "None"; }
1981  else
1982  { os << std::setw(15)<< n.fBlockedPhysicalVolume->GetName(); }
1983  os << std::setw( 9) << n.fBlockedReplicaNo << " "
1984  << std::setw( 8) << n.fLastStepWasZero << " "
1985  << G4endl;
1986  }
1987  if( n.fVerbose > 2 )
1988  {
1989  os.precision(8);
1990  os << " Current Localpoint = " << n.fLastLocatedPointLocal << G4endl;
1991  os << " PreviousSftOrigin = " << n.fPreviousSftOrigin << G4endl;
1992  os << " PreviousSafety = " << n.fPreviousSafety << G4endl;
1993  }
1994  if( n.fVerbose > 3 || n.fVerbose == 0 )
1995  {
1996  os << "Current History: " << G4endl << n.fHistory;
1997  }
1998 
1999  os.precision(oldcoutPrec);
2000  return os;
2001 }
G4String GetName() const
G4ReplicaNavigation freplicaNav
Definition: G4Navigator.hh:488
G4bool fWarnPush
Definition: G4Navigator.hh:480
G4ParameterisedNavigation fparamNav
Definition: G4Navigator.hh:487
G4SmartVoxelHeader * GetVoxelHeader() const
G4bool fValidExitNormal
Definition: G4Navigator.hh:408
G4VPhysicalVolume * GetTopVolume() const
G4VoxelNavigation fvoxelNav
Definition: G4Navigator.hh:486
G4VPhysicalVolume * fBlockedPhysicalVolume
Definition: G4Navigator.hh:400
virtual void ResetState()
G4bool fLastTriedStepComputation
Definition: G4Navigator.hh:385
virtual G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
G4VoxelSafety * fpVoxelSafety
Definition: G4Navigator.hh:490
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4bool fCheck
Definition: G4Navigator.hh:478
const G4ThreeVector & GetTranslation() const
static const G4double kInfinity
Definition: geomdefs.hh:42
virtual G4bool IsNested() const
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void UpdateMaterial(G4Material *pMaterial)
G4String GetName() const
CLHEP::Hep3Vector G4ThreeVector
CLHEP::HepRotation G4RotationMatrix
G4ThreeVector fLastStepEndPointLocal
Definition: G4Navigator.hh:373
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4VSolid.cc:137
G4AffineTransform Inverse() const
G4int GetVerboseLevel() const
G4ThreeVector fGrandMotherExitNormal
Definition: G4Navigator.hh:412
G4ThreeVector ComputeLocalAxis(const G4ThreeVector &pVec) const
G4bool fPushed
Definition: G4Navigator.hh:480
virtual G4TouchableHistoryHandle CreateTouchableHistoryHandle() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
void ResetStackAndState()
G4int GetDepth() const
G4int fNumberZeroSteps
Definition: G4Navigator.hh:432
G4double GetSurfaceTolerance() const
G4VPhysicalVolume * spBlockedPhysicalVolume
Definition: G4Navigator.hh:456
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
Definition: G4Navigator.cc:707
G4int fVerbose
Definition: G4Navigator.hh:377
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4VPhysicalVolume &currentPhysical, G4double maxLength=DBL_MAX)
void PrintState() const
void SetSolid(G4VSolid *pSolid)
G4int fAbandonThreshold_NoZeroSteps
Definition: G4Navigator.hh:436
G4SmartVoxelNode * ParamVoxelLocate(G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
G4bool fEnteredDaughter
Definition: G4Navigator.hh:357
EVolume GetVolumeType(G4int n) const
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4bool &calculatedExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4bool fLocatedOnEdge
Definition: G4Navigator.hh:430
const G4AffineTransform GetLocalToGlobalTransform() const
virtual G4GeometryType GetEntityType() const =0
#define G4ThreadLocal
Definition: tls.hh:52
G4ReferenceCountedHandle< G4TouchableHistory > G4TouchableHistoryHandle
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
void ComputeTransformation(const G4int replicaNo, G4VPhysicalVolume *pVol, G4ThreeVector &point) const
int G4int
Definition: G4Types.hh:78
G4bool fLastStepWasZero
Definition: G4Navigator.hh:427
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
Definition: G4Navigator.cc:90
G4ThreeVector fExitNormalGlobalFrame
Definition: G4Navigator.hh:416
virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &point, G4bool *valid)
G4int GetTopReplicaNo() const
void SetVerboseLevel(G4int level)
G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4NavigationHistory &history, const G4double pMaxLength=DBL_MAX)
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
G4bool fWasLimitedByGeometry
Definition: G4Navigator.hh:367
G4NormalNavigation fnormalNav
Definition: G4Navigator.hh:485
G4bool fEntering
Definition: G4Navigator.hh:391
void SetNormalNavigation(G4NormalNavigation *fnormnav)
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
virtual EInside Inside(const G4ThreeVector &p) const =0
virtual G4ThreeVector GetLocalExitNormal(G4bool *valid)
G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4ThreeVector fPreviousSftOrigin
Definition: G4Navigator.hh:439
G4double CheckNextStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
bool G4bool
Definition: G4Types.hh:79
EVolume GetTopVolumeType() const
virtual G4int GetRegularStructureId() const =0
G4NavigationHistory fHistory
Definition: G4Navigator.hh:353
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4NavigationHistory &history, const G4double pMaxLength=DBL_MAX)
virtual G4ThreeVector SurfaceNormal(const G4ThreeVector &p) const =0
virtual G4VPVParameterisation * GetParameterisation() const =0
virtual void SetCopyNo(G4int CopyNo)=0
G4int GetReplicaNo(G4int n) const
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
G4bool fExitedMother
Definition: G4Navigator.hh:363
G4bool EnteredDaughterVolume() const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
G4int fBlockedReplicaNo
Definition: G4Navigator.hh:401
#define G4DEBUG_NAVIGATION
const G4int n
EVolume CharacteriseDaughters(const G4LogicalVolume *pLog) const
G4ThreeVector fLastLocatedPointLocal
Definition: G4Navigator.hh:403
G4double fPreviousSafety
Definition: G4Navigator.hh:440
G4bool fLocatedOutsideWorld
Definition: G4Navigator.hh:405
void SetSavedState()
Definition: G4Navigator.cc:624
G4bool fActive
Definition: G4Navigator.hh:382
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &rGlobPoint) const
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
G4double kCarTolerance
Definition: G4Navigator.hh:346
static const double perMillion
Definition: G4SIunits.hh:298
void NewLevel(G4VPhysicalVolume *pNewMother, EVolume vType=kNormal, G4int nReplica=-1)
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
G4TouchableHistory * CreateTouchableHistory() const
G4double ComputeStep(const G4ThreeVector &localPoint, const G4ThreeVector &localDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4AffineTransform GetMotherToDaughterTransform(G4VPhysicalVolume *dVolume, G4int dReplicaNo, EVolume dVolumeType)
G4LogicalVolume * GetLogicalVolume() const
const G4AffineTransform & GetTransform(G4int n) const
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
G4bool fExiting
Definition: G4Navigator.hh:391
EInside
Definition: geomdefs.hh:58
G4int GetDaughtersRegularStructureId(const G4LogicalVolume *pLog) const
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
virtual G4int GetCopyNo() const =0
const G4AffineTransform & GetGlobalToLocalTransform() const
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=0, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
Definition: G4Navigator.cc:118
struct G4Navigator::G4SaveNavigatorState fSaveState
const G4RotationMatrix * GetRotation() const
Definition: Step.hh:41
G4SmartVoxelNode * VoxelLocate(G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
#define G4endl
Definition: G4ios.hh:61
const G4AffineTransform & GetTopTransform() const
std::ostream & operator<<(std::ostream &os, const G4Navigator &n)
G4bool fCalculatedExitNormal
Definition: G4Navigator.hh:418
G4ThreeVector fStepEndPoint
Definition: G4Navigator.hh:370
const G4NavigationHistory * GetHistory() const
G4ThreeVector fExitNormal
Definition: G4Navigator.hh:409
G4int fActionThreshold_NoZeroSteps
Definition: G4Navigator.hh:434
T sqr(const T &x)
Definition: templates.hh:145
G4bool fChangedGrandMotherRefFrame
Definition: G4Navigator.hh:414
EVolume
Definition: geomdefs.hh:68
G4int MoveUpHistory(G4int num_levels=1)
G4double ComputeSafety(const G4ThreeVector &globalPoint, const G4ThreeVector &localPoint, G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
double G4double
Definition: G4Types.hh:76
G4VPhysicalVolume * GetVolume(G4int n) const
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
virtual G4double ComputeStep(const G4ThreeVector &globalPoint, const G4ThreeVector &globalDirection, const G4double currentProposedStepLength, G4double &newSafety, G4NavigationHistory &history, G4bool &validExitNormal, G4ThreeVector &exitNormal, G4bool &exiting, G4bool &entering, G4VPhysicalVolume *(*pBlockedPhysical), G4int &blockedReplicaNo)
G4RegularNavigation fregularNav
Definition: G4Navigator.hh:489
EInside BackLocate(G4NavigationHistory &history, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint, const G4bool &exiting, G4bool &notKnownInside) const
virtual void SetupHierarchy()
static const double mm
Definition: G4SIunits.hh:102
virtual G4bool CheckOverlaps(G4int res=1000, G4double tol=0., G4bool verbose=true, G4int errMax=1)
EVolume VolumeType(const G4VPhysicalVolume *pVol) const
static G4GeometryTolerance * GetInstance()
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
Definition: G4Navigator.cc:550
G4VSolid * GetSolid() const
void ComputeStepLog(const G4ThreeVector &pGlobalpoint, G4double moveLenSq) const
void RestoreSavedState()
Definition: G4Navigator.cc:654
virtual ~G4Navigator()
Definition: G4Navigator.cc:82
G4GLOB_DLL std::ostream G4cerr