Geant4  10.03.p03
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4ITNavigator2.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 // $Id: G4ITNavigator2.cc 79045 2014-02-12 13:57:26Z matkara $
27 //
28 // class G4ITNavigator2 Implementation
29 //
30 // Original author: Paul Kent, July 95/96
31 //
32 // G4ITNavigator2 is a duplicate version of G4Navigator starting from Geant4.9.5
33 // initially written by Paul Kent and colleagues.
34 // The only difference resides in the way the information is saved and managed
35 //
36 // History:
37 // - Created. Paul Kent, Jul 95/96
38 // - Zero step protections J.A. / G.C., Nov 2004
39 // - Added check mode G. Cosmo, Mar 2004
40 // - Made Navigator Abstract G. Cosmo, Nov 2003
41 // - G4ITNavigator2 created M.K., Nov 2012
42 // --------------------------------------------------------------------
43 
44 #include <iomanip>
45 
46 //#include "G4ITNavigator2.hh"
47 #include "G4ITNavigator.hh"
48 #include "G4ios.hh"
49 #include "G4SystemOfUnits.hh"
50 #include "G4GeometryTolerance.hh"
51 #include "G4VPhysicalVolume.hh"
52 
53 //#define G4DEBUG_NAVIGATION 1
54 #include "G4VoxelSafety.hh"
55 #include "Randomize.hh"
56 #include "G4VoxelLimits.hh"
57 
58 #define fHistory fpNavigatorState->fHistory
59 #define fLastTriedStepComputation fpNavigatorState->fLastTriedStepComputation
60 #define fEnteredDaughter fpNavigatorState->fEnteredDaughter
61 #define fExitedMother fpNavigatorState->fExitedMother
62 #define fWasLimitedByGeometry fpNavigatorState->fWasLimitedByGeometry
63 #define fStepEndPoint fpNavigatorState->fStepEndPoint
64 #define fLastStepEndPointLocal fpNavigatorState->fLastStepEndPointLocal
65 #define fPushed fpNavigatorState->fPushed
66 #define fLastTriedStepComputation fpNavigatorState->fLastTriedStepComputation
67 #define fEntering fpNavigatorState->fEntering
68 #define fExiting fpNavigatorState->fExiting
69 #define fBlockedPhysicalVolume fpNavigatorState->fBlockedPhysicalVolume
70 #define fBlockedReplicaNo fpNavigatorState->fBlockedReplicaNo
71 #define fLastLocatedPointLocal fpNavigatorState->fLastLocatedPointLocal
72 #define fLocatedOutsideWorld fpNavigatorState->fLocatedOutsideWorld
73 #define fValidExitNormal fpNavigatorState->fValidExitNormal
74 #define fExitNormal fpNavigatorState->fExitNormal
75 #define fGrandMotherExitNormal fpNavigatorState->fGrandMotherExitNormal
76 #define fChangedGrandMotherRefFrame fpNavigatorState->fChangedGrandMotherRefFrame
77 #define fExitNormalGlobalFrame fpNavigatorState->fExitNormalGlobalFrame
78 #define fCalculatedExitNormal fpNavigatorState->fCalculatedExitNormal
79 #define fLastStepWasZero fpNavigatorState->fLastStepWasZero
80 #define fLocatedOnEdge fpNavigatorState->fLocatedOnEdge
81 #define fNumberZeroSteps fpNavigatorState->fNumberZeroSteps
82 #define fPreviousSftOrigin fpNavigatorState->fPreviousSftOrigin
83 #define fPreviousSafety fpNavigatorState->fPreviousSafety
84 
85 //------------------------------------------------------------------------------
86 
87 namespace BoundingBox
88 {
90 {
93 };
94 }
95 
96 // ********************************************************************
97 // Constructor
98 // ********************************************************************
99 //
101  : fVerbose(0),
102  fTopPhysical(0), fCheck(false),
103  fWarnPush(true)
104 {
105  fActive= false;
106  fActionThreshold_NoZeroSteps = 1000;
107  fAbandonThreshold_NoZeroSteps = 2500;
110 
111  fpNavigatorState = 0;
112 // fSaveState = 0;
114 
115  // this->SetVerboseLevel(3);
116  // this->CheckMode(true);
117 }
118 
119 // ********************************************************************
120 // Destructor
121 // ********************************************************************
122 //
124 { delete fpVoxelSafety; }
125 
126 // ********************************************************************
127 // ResetHierarchyAndLocate
128 // ********************************************************************
129 //
132  const G4ThreeVector &direction,
133  const G4TouchableHistory &h)
134 {
135 // ResetState();
136  fHistory = *h.GetHistory();
137  SetupHierarchy();
138  fLastTriedStepComputation= false; // Redundant, but best
139  return LocateGlobalPointAndSetup(p, &direction, true, false);
140 }
141 
142 // ********************************************************************
143 // LocateGlobalPointAndSetup
144 //
145 // Locate the point in the hierarchy return 0 if outside
146 // The direction is required
147 // - if on an edge shared by more than two surfaces
148 // (to resolve likely looping in tracking)
149 // - at initial location of a particle
150 // (to resolve potential ambiguity at boundary)
151 //
152 // Flags on exit: (comments to be completed)
153 // fEntering - True if entering `daughter' volume (or replica)
154 // whether daughter of last mother directly
155 // or daughter of that volume's ancestor.
156 // ********************************************************************
157 //
160  const G4ThreeVector* pGlobalDirection,
161  const G4bool relativeSearch,
162  const G4bool ignoreDirection )
163 {
165  G4bool notKnownContained=true, noResult;
166  G4VPhysicalVolume *targetPhysical;
167  G4LogicalVolume *targetLogical;
168  G4VSolid *targetSolid=0;
169  G4ThreeVector localPoint, globalDirection;
170  EInside insideCode;
171 
172  G4bool considerDirection = (!ignoreDirection) || fLocatedOnEdge;
173 
175  fChangedGrandMotherRefFrame= false; // For local exit normal
176 
177  if( considerDirection && pGlobalDirection != 0 )
178  {
179  globalDirection=*pGlobalDirection;
180  }
181 
182 
183 #ifdef G4VERBOSE
184  if( fVerbose > 2 )
185  {
186  static int nCalls = 0;
187  G4int oldcoutPrec = G4cout.precision(8);
188  G4cout << "*** G4ITNavigator2::LocateGlobalPointAndSetup: ***" << G4endl;
189  G4cout << " Called with arguments: " << G4endl
190  << " Globalpoint = " << globalPoint << G4endl
191  << " RelativeSearch = " << relativeSearch << G4endl;
192  if( fVerbose == 4 )
193  {
194  G4cout << " ----- Upon entering:" << G4endl;
195  PrintState();
196  }
197  G4cout.precision(oldcoutPrec);
198  nCalls++;
199 // if(nCalls == 2) abort();
200  }
201 #endif
202 
203  G4int noLevelsExited=0 ;
204  G4int noLevelsEntered= 0;
205 
206  if ( !relativeSearch )
207  {
209  }
210  else
211  {
212  if ( fWasLimitedByGeometry )
213  {
214  fWasLimitedByGeometry = false;
215  fEnteredDaughter = fEntering; // Remember
216  fExitedMother = fExiting; // Remember
217  if ( fExiting )
218  {
219  noLevelsExited++; // count this first level entered too
220 
221  if ( fHistory.GetDepth() )
222  {
223  fBlockedPhysicalVolume = fHistory.GetTopVolume();
224  fBlockedReplicaNo = fHistory.GetTopReplicaNo();
225  fHistory.BackLevel();
226  }
227  else
228  {
229  fLastLocatedPointLocal = localPoint;
230  fLocatedOutsideWorld = true;
231  fBlockedPhysicalVolume = 0; // to be sure
232  fBlockedReplicaNo = -1;
233  fEntering = false; // No longer
234  fEnteredDaughter = false;
235  fExitedMother = true; // ??
236 
237  return 0; // Have exited world volume
238  }
239  // A fix for the case where a volume is "entered" at an edge
240  // and a coincident surface exists outside it.
241  // - This stops it from exiting further volumes and cycling
242  // - However ReplicaNavigator treats this case itself
243  //
244  // assert( fBlockedPhysicalVolume!=0 );
245 
246  // Expect to be on edge => on surface
247  //
249  {
250  fExiting= false;
251  // Consider effect on Exit Normal !?
252  }
253  }
254  else
255  if ( fEntering )
256  {
257  // assert( fBlockedPhysicalVolume!=0 );
258 
259  noLevelsEntered++; // count the first level entered too
260 
262  {
263  case kNormal:
265  fBlockedPhysicalVolume->GetCopyNo());
266  break;
267  case kReplica:
273  break;
274  case kParameterised:
275  if( fBlockedPhysicalVolume->GetRegularStructureId() == 0 )
276  {
277  G4VSolid *pSolid;
278  G4VPVParameterisation *pParam;
279  G4TouchableHistory parentTouchable( fHistory );
280  pParam = fBlockedPhysicalVolume->GetParameterisation();
281  pSolid = pParam->ComputeSolid(fBlockedReplicaNo,
283  pSolid->ComputeDimensions(pParam, fBlockedReplicaNo,
290  //
291  // Set the correct solid and material in Logical Volume
292  //
293  G4LogicalVolume *pLogical;
294  pLogical = fBlockedPhysicalVolume->GetLogicalVolume();
295  pLogical->SetSolid( pSolid );
296  pLogical->UpdateMaterial(pParam ->
297  ComputeMaterial(fBlockedReplicaNo,
299  &parentTouchable));
300  }
301  break;
302  }
303  fEntering = false;
305  localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
306  notKnownContained = false;
307  }
308  }
309  else
310  {
312  fEntering = false;
313  fEnteredDaughter = false; // Full Step was not taken, did not enter
314  fExiting = false;
315  fExitedMother = false; // Full Step was not taken, did not exit
316  }
317  }
318  //
319  // Search from top of history up through geometry until
320  // containing volume found:
321  // If on
322  // o OUTSIDE - Back up level, not/no longer exiting volumes
323  // o SURFACE and EXITING - Back up level, setting new blocking no.s
324  // else
325  // o containing volume found
326  //
327 
328  while (notKnownContained)
329  {
330  if ( fHistory.GetTopVolumeType()!=kReplica )
331  {
332  targetSolid = fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
333  localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
334  insideCode = targetSolid->Inside(localPoint);
335 #ifdef G4VERBOSE
336  if(( fVerbose == 1 ) && ( fCheck ))
337  {
338  G4String solidResponse = "-kInside-";
339  if (insideCode == kOutside)
340  solidResponse = "-kOutside-";
341  else if (insideCode == kSurface)
342  solidResponse = "-kSurface-";
343  G4cout << "*** G4ITNavigator2::LocateGlobalPointAndSetup(): ***" << G4endl
344  << " Invoked Inside() for solid: " << targetSolid->GetName()
345  << ". Solid replied: " << solidResponse << G4endl
346  << " For local point p: " << localPoint << G4endl;
347  }
348 #endif
349  }
350  else
351  {
352  insideCode = freplicaNav.BackLocate(fHistory, globalPoint, localPoint,
353  fExiting, notKnownContained);
354  // !CARE! if notKnownContained returns false then the point is within
355  // the containing placement volume of the replica(s). If insidecode
356  // will result in the history being backed up one level, then the
357  // local point returned is the point in the system of this new level
358  }
359 
360 
361  if ( insideCode==kOutside )
362  {
363  noLevelsExited++;
364  if ( fHistory.GetDepth() )
365  {
366  fBlockedPhysicalVolume = fHistory.GetTopVolume();
367  fBlockedReplicaNo = fHistory.GetTopReplicaNo();
368  fHistory.BackLevel();
369  fExiting = false;
370 
371  if( noLevelsExited > 1 )
372  {
373  // The first transformation was done by the sub-navigator
374  //
375  const G4RotationMatrix* mRot = fBlockedPhysicalVolume->GetRotation();
376  if( mRot )
377  {
378  fGrandMotherExitNormal *= (*mRot).inverse();
380  }
381  }
382  }
383  else
384  {
385  fLastLocatedPointLocal = localPoint;
386  fLocatedOutsideWorld = true;
387  // No extra transformation for ExitNormal - is in frame of Top Volume
388  return 0; // Have exited world volume
389  }
390  }
391  else
392  if ( insideCode==kSurface )
393  {
394  G4bool isExiting = fExiting;
395  if( (!fExiting)&&considerDirection )
396  {
397  // Figure out whether we are exiting this level's volume
398  // by using the direction
399  //
400  G4bool directionExiting = false;
401  G4ThreeVector localDirection =
402  fHistory.GetTopTransform().TransformAxis(globalDirection);
403 
404  // Make sure localPoint in correct reference frame
405  // ( Was it already correct ? How ? )
406  //
407  localPoint= fHistory.GetTopTransform().TransformPoint(globalPoint);
408  if ( fHistory.GetTopVolumeType()!=kReplica )
409  {
410  G4ThreeVector normal = targetSolid->SurfaceNormal(localPoint);
411  directionExiting = normal.dot(localDirection) > 0.0;
412  isExiting = isExiting || directionExiting;
413  }
414  }
415  if( isExiting )
416  {
417  noLevelsExited++;
418  if ( fHistory.GetDepth() )
419  {
420  fBlockedPhysicalVolume = fHistory.GetTopVolume();
421  fBlockedReplicaNo = fHistory.GetTopReplicaNo();
422  fHistory.BackLevel();
423  //
424  // Still on surface but exited volume not necessarily convex
425  //
426  fValidExitNormal = false;
427 
428  if( noLevelsExited > 1 )
429  {
430  // The first transformation was done by the sub-navigator
431  //
432  const G4RotationMatrix* mRot =
433  fBlockedPhysicalVolume->GetRotation();
434  if( mRot )
435  {
436  fGrandMotherExitNormal *= (*mRot).inverse();
438  }
439  }
440  }
441  else
442  {
443  fLastLocatedPointLocal = localPoint;
444  fLocatedOutsideWorld = true;
445  // No extra transformation for ExitNormal, is in frame of Top Vol
446  return 0; // Have exited world volume
447  }
448  }
449  else
450  {
451  notKnownContained=false;
452  }
453  }
454  else
455  {
456  notKnownContained=false;
457  }
458  } // END while (notKnownContained)
459  //
460  // Search downwards until deepest containing volume found,
461  // blocking fBlockedPhysicalVolume/BlockedReplicaNum
462  //
463  // 3 Cases:
464  //
465  // o Parameterised daughters
466  // =>Must be one G4PVParameterised daughter & voxels
467  // o Positioned daughters & voxels
468  // o Positioned daughters & no voxels
469 
470  noResult = true; // noResult should be renamed to
471  // something like enteredLevel, as that is its meaning.
472  do
473  {
474  // Determine `type' of current mother volume
475  //
476  targetPhysical = fHistory.GetTopVolume();
477  if (!targetPhysical) { break; }
478  targetLogical = targetPhysical->GetLogicalVolume();
479  switch( CharacteriseDaughters(targetLogical) )
480  {
481  case kNormal:
482  if ( targetLogical->GetVoxelHeader() ) // use optimised navigation
483  {
484  noResult = fvoxelNav.LevelLocate(fHistory,
487  globalPoint,
488  pGlobalDirection,
489  considerDirection,
490  localPoint);
491  }
492  else // do not use optimised navigation
493  {
494  noResult = fnormalNav.LevelLocate(fHistory,
497  globalPoint,
498  pGlobalDirection,
499  considerDirection,
500  localPoint);
501  }
502  break;
503  case kReplica:
504  noResult = freplicaNav.LevelLocate(fHistory,
507  globalPoint,
508  pGlobalDirection,
509  considerDirection,
510  localPoint);
511  break;
512  case kParameterised:
513  if( GetDaughtersRegularStructureId(targetLogical) != 1 )
514  {
515  noResult = fparamNav.LevelLocate(fHistory,
518  globalPoint,
519  pGlobalDirection,
520  considerDirection,
521  localPoint);
522  }
523  else // Regular structure
524  {
525  noResult = fregularNav.LevelLocate(fHistory,
528  globalPoint,
529  pGlobalDirection,
530  considerDirection,
531  localPoint);
532  }
533  break;
534  }
535 
536  // LevelLocate returns true if it finds a daughter volume
537  // in which globalPoint is inside (or on the surface).
538 
539  if ( noResult )
540  {
541  noLevelsEntered++;
542 
543  // Entering a daughter after ascending
544  //
545  // The blocked volume is no longer valid - it was for another level
546  //
548  fBlockedReplicaNo = -1;
549 
550  // fEntering should be false -- else blockedVolume is assumed good.
551  // fEnteredDaughter is used for ExitNormal
552  //
553  fEntering = false;
554  fEnteredDaughter = true;
555 
556  if( fExitedMother )
557  {
558  G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
559  const G4RotationMatrix* mRot = enteredPhysical->GetRotation();
560  if( mRot )
561  {
562  // Go deeper, i.e. move 'down' in the hierarchy
563  // Apply direct rotation, not inverse
564  //
565  fGrandMotherExitNormal *= (*mRot);
567  }
568  }
569 
570 #ifdef G4DEBUG_NAVIGATION
571  if( fVerbose > 2 )
572  {
573  G4VPhysicalVolume* enteredPhysical = fHistory.GetTopVolume();
574  G4cout << "*** G4ITNavigator2::LocateGlobalPointAndSetup() ***" << G4endl;
575  G4cout << " Entering volume: " << enteredPhysical->GetName()
576  << G4endl;
577  }
578 #endif
579  }
580  } while (noResult);
581 
582  fLastLocatedPointLocal = localPoint;
583 
584 #ifdef G4VERBOSE
585  if( fVerbose >= 4 )
586  {
587  G4int oldcoutPrec = G4cout.precision(8);
588  G4String curPhysVol_Name("None");
589  if (targetPhysical) { curPhysVol_Name = targetPhysical->GetName(); }
590  G4cout << " Return value = new volume = " << curPhysVol_Name << G4endl;
591  G4cout << " ----- Upon exiting:" << G4endl;
592  PrintState();
593  if( fVerbose >= 5 )
594  {
595  G4cout << "Upon exiting LocateGlobalPointAndSetup():" << G4endl;
596  G4cout << " History = " << G4endl << fHistory << G4endl << G4endl;
597  }
598  G4cout.precision(oldcoutPrec);
599  }
600 #endif
601 
602  fLocatedOutsideWorld= false;
603 
604  return targetPhysical;
605 }
606 
607 // ********************************************************************
608 // LocateGlobalPointWithinVolume
609 //
610 // -> the state information of this Navigator and its subNavigators
611 // is updated in order to start the next step at pGlobalpoint
612 // -> no check is performed whether pGlobalpoint is inside the
613 // original volume (this must be the case).
614 //
615 // Note: a direction could be added to the arguments, to aid in future
616 // optional checking (via the old code below, flagged by OLD_LOCATE).
617 // [ This would be done only in verbose mode ]
618 // ********************************************************************
619 //
620 void
622 {
624 
625 #ifdef G4DEBUG_NAVIGATION
626  // Check: Either step was not limited by a boundary
627  // or else the full step is no longer being taken
628  assert( !fWasLimitedByGeometry );
629 #endif
630 
633  fChangedGrandMotherRefFrame= false; // Frame for Exit Normal
634 
635 #ifdef G4DEBUG_NAVIGATION
636  if( fVerbose > 2 )
637  {
638  G4cout << "Entering LocateGlobalWithinVolume(): History = " << G4endl;
639  G4cout << fHistory << G4endl;
640  }
641 #endif
642 
643  // For the case of Voxel (or Parameterised) volume the respective
644  // Navigator must be messaged to update its voxel information etc
645 
646  // Update the state of the Sub Navigators
647  // - in particular any voxel information they store/cache
648  //
649  G4VPhysicalVolume* motherPhysical = fHistory.GetTopVolume();
650  G4LogicalVolume* motherLogical = motherPhysical->GetLogicalVolume();
651  G4SmartVoxelHeader* pVoxelHeader = motherLogical->GetVoxelHeader();
652 
653  if ( fHistory.GetTopVolumeType()!=kReplica )
654  {
655  switch( CharacteriseDaughters(motherLogical) )
656  {
657  case kNormal:
658  if ( pVoxelHeader )
659  {
661  }
662  break;
663  case kParameterised:
664  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
665  {
666  // Resets state & returns voxel node
667  //
669  }
670  break;
671  case kReplica:
672  G4Exception("G4ITNavigator2::LocateGlobalPointWithinVolume()",
673  "GeomNav0001", FatalException,
674  "Not applicable for replicated volumes.");
675  break;
676  }
677  }
678 
679  // Reset the state variables
680  // - which would have been affected
681  // by the 'equivalent' call to LocateGlobalPointAndSetup
682  // - who's values have been invalidated by the 'move'.
683  //
685  fBlockedReplicaNo = -1;
686  fEntering = false;
687  fEnteredDaughter = false; // Boundary not encountered, did not enter
688  fExiting = false;
689  fExitedMother = false; // Boundary not encountered, did not exit
690 }
691 
692 // !>
693 
695 {
696  if(fpNavigatorState == 0)
697  {
698  G4ExceptionDescription exceptionDescription;
699  exceptionDescription << "The navigator state is NULL. ";
700  exceptionDescription << "Either NewNavigatorStateAndLocate was not called ";
701  exceptionDescription << "or the provided navigator state was already NULL.";
702 
703  G4Exception("G4ITNavigator::CheckNavigatorStateIsValid",
704  "NavigatorStateNotValid",FatalException,exceptionDescription);
705  return;
706  }
707 }
708 
710 {
711  return fpNavigatorState;
712 }
713 
715 {
716  fpNavigatorState = (G4NavigatorState*) navState;
717  if(fpNavigatorState) SetupHierarchy(); // ?
718 // fpSaveState = (G4SaveNavigatorState*) navState;
719 // if(navState) RestoreSavedState();
720 }
721 
723 {
724  fpNavigatorState = 0;
725 }
726 
728 {
730  if(fTopPhysical == 0)
731  {
732  G4ExceptionDescription exceptionDescription;
733  exceptionDescription << "No World Volume";
734 
735  G4Exception("G4ITNavigator::NewNavigatorState",
736  "NoWorldVolume",FatalException,exceptionDescription);
737  return;
738  }
739 
740  fHistory.SetFirstEntry(fTopPhysical );
741  SetupHierarchy();
742 }
743 
745 {
747  if(fTopPhysical == 0)
748  {
749  G4ExceptionDescription exceptionDescription;
750  exceptionDescription << "No World Volume";
751 
752  G4Exception("G4ITNavigator::NewNavigatorState",
753  "NoWorldVolume",FatalException,exceptionDescription);
754  return;
755  }
756 
757  fHistory = *h.GetHistory();
758  fLastTriedStepComputation= false; // Redundant, but best
759  SetupHierarchy();
760 }
761 
763  const G4ThreeVector &direction)
764 {
766 
767  if(fTopPhysical == 0)
768  {
769  G4ExceptionDescription exceptionDescription;
770  exceptionDescription << "No World Volume";
771 
772  G4Exception("G4ITNavigator::NewNavigatorStateAndLocate",
773  "NoWorldVolume",FatalException,exceptionDescription);
774  return 0;
775  }
776 
777  fHistory.SetFirstEntry(fTopPhysical );
778  SetupHierarchy();
779  return LocateGlobalPointAndSetup(p, &direction, false, false);
780 }
781 
782 // ********************************************************************
783 // SetSavedState
784 //
785 // Save the state, in case this is a parasitic call
786 // Save fValidExitNormal, fExitNormal, fExiting, fEntering,
787 // fBlockedPhysicalVolume, fBlockedReplicaNo, fLastStepWasZero;
788 // ********************************************************************
789 //
790 /*
791 void G4ITNavigator2::SetSavedState()
792 {
793  fSaveState = *fpNavigatorState;
794 }
795 */
796 
797 /*
798 void G4ITNavigator2::SetSavedState()
799 {
800  // !>
801  // This check can be avoid if instead, at every first step of a track,
802  // the IT tracking uses NewNavigatorSate
803  // The normal tracking would just call once NewNavigatorState() before tracking
804 
805 // if(fpSaveState == 0)
806 // fpSaveState = new G4SaveNavigatorState;
807  // <!
808 
809  // fSaveExitNormal = fExitNormal;
810  fpSaveState->sExitNormal = fExitNormal;
811  fpSaveState->sValidExitNormal = fValidExitNormal;
812  fpSaveState->sExiting = fExiting;
813  fpSaveState->sEntering = fEntering;
814 
815  fpSaveState->spBlockedPhysicalVolume = fBlockedPhysicalVolume;
816  fpSaveState->sBlockedReplicaNo = fBlockedReplicaNo,
817 
818  fpSaveState->sLastStepWasZero = fLastStepWasZero;
819 
820  // !>
821  fpSaveState->sPreviousSftOrigin = fPreviousSftOrigin;
822  fpSaveState->sPreviousSafety = fPreviousSafety;
823  fpSaveState->sNumberZeroSteps = fNumberZeroSteps;
824  fpSaveState->sLocatedOnEdge = fLocatedOnEdge;
825  fpSaveState->sWasLimitedByGeometry= fWasLimitedByGeometry;
826  fpSaveState->sPushed=fPushed;
827  fpSaveState->sNumberZeroSteps=fNumberZeroSteps;
828  fpSaveState->sEnteredDaughter = fEnteredDaughter;
829  fpSaveState->sExitedMother = fExitedMother;
830 
831  fpSaveState->sLastLocatedPointLocal = fLastLocatedPointLocal;
832  fpSaveState->sLocatedOutsideWorld = fLocatedOutsideWorld;
833  // <!
834 }
835 */
836 // ********************************************************************
837 // RestoreSavedState
838 //
839 // Restore the state (in Compute Step), in case this is a parasitic call
840 // ********************************************************************
841 //
842 /*
843 void G4ITNavigator2::RestoreSavedState()
844 {
845  *fpNavigatorState = fSaveState;
846 }
847 */
848 /*
849 void G4ITNavigator2::RestoreSavedState()
850 {
851  fExitNormal = fpSaveState->sExitNormal;
852  fValidExitNormal = fpSaveState->sValidExitNormal;
853  fExiting = fpSaveState->sExiting;
854  fEntering = fpSaveState->sEntering;
855 
856  fBlockedPhysicalVolume = fpSaveState->spBlockedPhysicalVolume;
857  fBlockedReplicaNo = fpSaveState->sBlockedReplicaNo,
858 
859  fLastStepWasZero = fpSaveState->sLastStepWasZero;
860 
861  // !>
862  fPreviousSftOrigin = fpSaveState->sPreviousSftOrigin ;
863  fPreviousSafety = fpSaveState->sPreviousSafety ;
864  fNumberZeroSteps = fpSaveState->sNumberZeroSteps ;
865  fLocatedOnEdge = fpSaveState->sLocatedOnEdge ;
866  fWasLimitedByGeometry = fpSaveState->sWasLimitedByGeometry;
867  fPushed = fpSaveState->sPushed;
868  fNumberZeroSteps = fpSaveState->sNumberZeroSteps;
869  fEnteredDaughter= fpSaveState->sEnteredDaughter ;
870  fExitedMother = fpSaveState->sExitedMother ;
871 
872  fLastLocatedPointLocal = fpSaveState->sLastLocatedPointLocal ;
873  fLocatedOutsideWorld = fpSaveState->sLocatedOutsideWorld;
874  // <!
875 }
876 */
877 // <!
878 
879 // ********************************************************************
880 // ComputeStep
881 //
882 // Computes the next geometric Step: intersections with current
883 // mother and `daughter' volumes.
884 //
885 // NOTE:
886 //
887 // Flags on entry:
888 // --------------
889 // fValidExitNormal - Normal of exited volume is valid (convex, not a
890 // coincident boundary)
891 // fExitNormal - Surface normal of exited volume
892 // fExiting - True if have exited solid
893 //
894 // fBlockedPhysicalVolume - Ptr to exited volume (or 0)
895 // fBlockedReplicaNo - Replication no of exited volume
896 // fLastStepWasZero - True if last Step size was zero.
897 //
898 // Flags on exit:
899 // -------------
900 // fValidExitNormal - True if surface normal of exited volume is valid
901 // fExitNormal - Surface normal of exited volume rotated to mothers
902 // reference system
903 // fExiting - True if exiting mother
904 // fEntering - True if entering `daughter' volume (or replica)
905 // fBlockedPhysicalVolume - Ptr to candidate (entered) volume
906 // fBlockedReplicaNo - Replication no of candidate (entered) volume
907 // fLastStepWasZero - True if this Step size was zero.
908 // ********************************************************************
909 //
911  const G4ThreeVector &pDirection,
912  const G4double pCurrentProposedStepLength,
913  G4double &pNewSafety)
914 {
916  G4ThreeVector localDirection = ComputeLocalAxis(pDirection);
918  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
919  G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
920 
921  // All state relating to exiting normals must be reset
922  //
924  // Reset value - to erase its memory
926  // Reset - used for local exit normal
927  fGrandMotherExitNormal= G4ThreeVector( 0., 0., 0.);
928  fCalculatedExitNormal = false;
929  // Reset for new step
930 
931  static G4ThreadLocal G4int sNavCScalls=0;
932  sNavCScalls++;
933 
935 
936 #ifdef G4VERBOSE
937  if( fVerbose > 0 )
938  {
939  G4cout << "*** G4ITNavigator2::ComputeStep: ***" << G4endl;
940  G4cout << " Volume = " << motherPhysical->GetName()
941  << " - Proposed step length = " << pCurrentProposedStepLength
942  << G4endl;
943 #ifdef G4DEBUG_NAVIGATION
944  if( fVerbose >= 2 )
945  {
946  G4cout << " Called with the arguments: " << G4endl
947  << " Globalpoint = " << std::setw(25) << pGlobalpoint << G4endl
948  << " Direction = " << std::setw(25) << pDirection << G4endl;
949  if( fVerbose >= 4 )
950  {
951  G4cout << " ---- Upon entering : State" << G4endl;
952  PrintState();
953  }
954  }
955 #endif
956  }
957 #endif
958 
959  G4ThreeVector newLocalPoint = ComputeLocalPoint(pGlobalpoint);
960  if( newLocalPoint != fLastLocatedPointLocal )
961  {
962  // Check whether the relocation is within safety
963  //
964  G4ThreeVector oldLocalPoint = fLastLocatedPointLocal;
965  G4double moveLenSq = (newLocalPoint-oldLocalPoint).mag2();
966 
967  if ( moveLenSq >= kCarTolerance*kCarTolerance )
968  {
969 #ifdef G4VERBOSE
970  ComputeStepLog(pGlobalpoint, moveLenSq);
971 #endif
972  // Relocate the point within the same volume
973  //
974  LocateGlobalPointWithinVolume( pGlobalpoint );
975  fLastTriedStepComputation= true; // Ensure that this is set again !!
976  }
977  }
978  if ( fHistory.GetTopVolumeType()!=kReplica )
979  {
980  switch( CharacteriseDaughters(motherLogical) )
981  {
982  case kNormal:
983  if ( motherLogical->GetVoxelHeader() )
984  {
985  LocateGlobalPointWithinVolume(pGlobalpoint);
987  localDirection,
988  pCurrentProposedStepLength,
989  pNewSafety,
990  fHistory,
992  fExitNormal,
993  fExiting,
994  fEntering,
997 
998  }
999  else
1000  {
1001  if( motherPhysical->GetRegularStructureId() == 0 )
1002  {
1004  localDirection,
1005  pCurrentProposedStepLength,
1006  pNewSafety,
1007  fHistory,
1009  fExitNormal,
1010  fExiting,
1011  fEntering,
1014  }
1015  else // Regular (non-voxelised) structure
1016  {
1017  LocateGlobalPointAndSetup( pGlobalpoint, &pDirection, true, true );
1018  fLastTriedStepComputation= true; // Ensure that this is set again !!
1019  //
1020  // if physical process limits the step, the voxel will not be the
1021  // one given by ComputeStepSkippingEqualMaterials() and the local
1022  // point will be wrongly calculated.
1023 
1024  // There is a problem: when msc limits the step and the point is
1025  // assigned wrongly to phantom in previous step (while it is out
1026  // of the container volume). Then LocateGlobalPointAndSetup() has
1027  // reset the history topvolume to world.
1028  //
1029  if(fHistory.GetTopVolume()->GetRegularStructureId() == 0 )
1030  {
1031  G4Exception("G4ITNavigator2::ComputeStep()",
1032  "GeomNav1001", JustWarning,
1033  "Point is relocated in voxels, while it should be outside!");
1035  localDirection,
1036  pCurrentProposedStepLength,
1037  pNewSafety,
1038  fHistory,
1040  fExitNormal,
1041  fExiting,
1042  fEntering,
1045  }
1046  else
1047  {
1048  Step = fregularNav.
1049  ComputeStepSkippingEqualMaterials(fLastLocatedPointLocal,
1050  localDirection,
1051  pCurrentProposedStepLength,
1052  pNewSafety,
1053  fHistory,
1055  fExitNormal,
1056  fExiting,
1057  fEntering,
1060  motherPhysical);
1061  }
1062  }
1063  }
1064  break;
1065  case kParameterised:
1066  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
1067  {
1069  localDirection,
1070  pCurrentProposedStepLength,
1071  pNewSafety,
1072  fHistory,
1074  fExitNormal,
1075  fExiting,
1076  fEntering,
1079  }
1080  else // Regular structure
1081  {
1083  localDirection,
1084  pCurrentProposedStepLength,
1085  pNewSafety,
1086  fHistory,
1088  fExitNormal,
1089  fExiting,
1090  fEntering,
1093  }
1094  break;
1095  case kReplica:
1096  G4Exception("G4ITNavigator2::ComputeStep()", "GeomNav0001",
1097  FatalException, "Not applicable for replicated volumes.");
1098  break;
1099  }
1100  }
1101  else
1102  {
1103  // In the case of a replica, it must handle the exiting
1104  // edge/corner problem by itself
1105  //
1106  G4bool exitingReplica = fExitedMother;
1107  G4bool calculatedExitNormal;
1108  Step = freplicaNav.ComputeStep(pGlobalpoint,
1109  pDirection,
1111  localDirection,
1112  pCurrentProposedStepLength,
1113  pNewSafety,
1114  fHistory,
1116  calculatedExitNormal,
1117  fExitNormal,
1118  exitingReplica,
1119  fEntering,
1122  fExiting= exitingReplica;
1123  fCalculatedExitNormal= calculatedExitNormal;
1124  }
1125 
1126 
1127 // G4cout << " !!!! Step = " << Step << G4endl;
1128 
1129  // Remember last safety origin & value.
1130  //
1131  fPreviousSftOrigin = pGlobalpoint;
1132  fPreviousSafety = pNewSafety;
1133 
1134  // Count zero steps - one can occur due to changing momentum at a boundary
1135  // - one, two (or a few) can occur at common edges between
1136  // volumes
1137  // - more than two is likely a problem in the geometry
1138  // description or the Navigation
1139 
1140  // Rule of thumb: likely at an Edge if two consecutive steps are zero,
1141  // because at least two candidate volumes must have been
1142  // checked
1143  //
1144  fLocatedOnEdge = fLastStepWasZero && (Step==0.0);
1145  fLastStepWasZero = (Step==0.0);
1146  if (fPushed) { fPushed = fLastStepWasZero; }
1147 
1148  // Handle large number of consecutive zero steps
1149  //
1150  if ( fLastStepWasZero )
1151  {
1152  fNumberZeroSteps++;
1153 #ifdef G4DEBUG_NAVIGATION
1154  if( fNumberZeroSteps > 1 )
1155  {
1156  G4cout << "G4ITNavigator2::ComputeStep(): another zero step, # "
1157  << fNumberZeroSteps
1158  << " at " << pGlobalpoint
1159  << " in volume " << motherPhysical->GetName()
1160  << " nav-comp-step calls # " << sNavCScalls
1161  << G4endl;
1162  }
1163 #endif
1164  if( fNumberZeroSteps > fActionThreshold_NoZeroSteps-1 )
1165  {
1166  // Act to recover this stuck track. Pushing it along direction
1167  //
1168  Step += 100*kCarTolerance;
1169 #ifdef G4VERBOSE
1170  if ((!fPushed) && (fWarnPush))
1171  {
1172  std::ostringstream message;
1173  message << "Track stuck or not moving." << G4endl
1174  << " Track stuck, not moving for "
1175  << fNumberZeroSteps << " steps" << G4endl
1176  << " in volume -" << motherPhysical->GetName()
1177  << "- at point " << pGlobalpoint << G4endl
1178  << " direction: " << pDirection << "." << G4endl
1179  << " Potential geometry or navigation problem !"
1180  << G4endl
1181  << " Trying pushing it of " << Step << " mm ...";
1182  G4Exception("G4ITNavigator2::ComputeStep()", "GeomNav1002",
1183  JustWarning, message, "Potential overlap in geometry!");
1184  }
1185 #endif
1186  fPushed = true;
1187  }
1188  if( fNumberZeroSteps > fAbandonThreshold_NoZeroSteps-1 )
1189  {
1190  // Must kill this stuck track
1191  //
1192  std::ostringstream message;
1193  message << "Stuck Track: potential geometry or navigation problem."
1194  << G4endl
1195  << " Track stuck, not moving for "
1196  << fNumberZeroSteps << " steps" << G4endl
1197  << " in volume -" << motherPhysical->GetName()
1198  << "- at point " << pGlobalpoint << G4endl
1199  << " direction: " << pDirection << ".";
1200  motherPhysical->CheckOverlaps(5000, false);
1201  G4Exception("G4ITNavigator2::ComputeStep()", "GeomNav0003",
1202  EventMustBeAborted, message);
1203  }
1204  }
1205  else
1206  {
1207  if (!fPushed) fNumberZeroSteps = 0;
1208  }
1209 
1210  fEnteredDaughter = fEntering; // I expect to enter a volume in this Step
1212 
1213  fStepEndPoint = pGlobalpoint
1214  + std::min(Step,pCurrentProposedStepLength) * pDirection;
1215  fLastStepEndPointLocal = fLastLocatedPointLocal + Step * localDirection;
1216 
1217  if( fExiting )
1218  {
1219 #ifdef G4DEBUG_NAVIGATION
1220  if( fVerbose > 2 )
1221  {
1222  G4cout << " At G4Nav CompStep End - if(exiting) - fExiting= " << fExiting
1223  << " fValidExitNormal = " << fValidExitNormal << G4endl;
1224  G4cout << " fExitNormal= " << fExitNormal << G4endl;
1225  }
1226 #endif
1227 
1229  {
1230  if ( fHistory.GetTopVolumeType()!=kReplica )
1231  {
1232  // Convention: fExitNormal is in the 'grand-mother' coordinate system
1233  //
1235  fCalculatedExitNormal= true;
1236  }
1237  else
1238  {
1240  }
1241  }
1242  else
1243  {
1244  // We must calculate the normal anyway (in order to have it if requested)
1245  //
1246  G4ThreeVector finalLocalPoint =
1247  fLastLocatedPointLocal + localDirection*Step;
1248 
1249  if ( fHistory.GetTopVolumeType()!=kReplica )
1250  {
1251  // Find normal in the 'mother' coordinate system
1252  //
1253  G4ThreeVector exitNormalMotherFrame=
1254  motherLogical->GetSolid()->SurfaceNormal(finalLocalPoint);
1255 
1256  // Transform it to the 'grand-mother' coordinate system
1257  //
1258  const G4RotationMatrix* mRot = motherPhysical->GetRotation();
1259  if( mRot )
1260  {
1262  fGrandMotherExitNormal = (*mRot).inverse() * exitNormalMotherFrame;
1263  }
1264  else
1265  {
1266  fGrandMotherExitNormal = exitNormalMotherFrame;
1267  }
1268 
1269  // Do not set fValidExitNormal -- this signifies
1270  // that the solid is convex!
1271  //
1272  fCalculatedExitNormal= true;
1273  }
1274  else
1275  {
1276  fCalculatedExitNormal = false;
1277  //
1278  // Nothing can be done at this stage currently - to solve this
1279  // Replica Navigation must have calculated the normal for this case
1280  // already.
1281  // Cases: mother is not convex, and exit is at previous replica level
1282 
1283 #ifdef G4DEBUG_NAVIGATION
1285 
1286  desc << "Problem in ComputeStep: Replica Navigation did not provide"
1287  << " valid exit Normal. " << G4endl;
1288  desc << " Do not know how calculate it in this case." << G4endl;
1289  desc << " Location = " << finalLocalPoint << G4endl;
1290  desc << " Volume name = " << motherPhysical->GetName()
1291  << " copy/replica No = " << motherPhysical->GetCopyNo() << G4endl;
1292  G4Exception("G4ITNavigator2::ComputeStep()", "GeomNav0003",
1293  JustWarning, desc, "Normal not available for exiting.");
1294 #endif
1295  }
1296  }
1297 
1298  // Now transform it to the global reference frame !!
1299  //
1301  {
1302  G4int depth= fHistory.GetDepth();
1303  if( depth > 0 )
1304  {
1305  G4AffineTransform GrandMotherToGlobalTransf =
1306  fHistory.GetTransform(depth-1).Inverse();
1308  GrandMotherToGlobalTransf.TransformAxis( fGrandMotherExitNormal );
1309  }
1310  else
1311  {
1313  }
1314  }
1315  else
1316  {
1317  fExitNormalGlobalFrame= G4ThreeVector( 0., 0., 0.);
1318  }
1319  }
1320 
1321  if( (Step == pCurrentProposedStepLength) && (!fExiting) && (!fEntering) )
1322  {
1323  // This if Step is not really limited by the geometry.
1324  // The Navigator is obliged to return "infinity"
1325  //
1326  Step = kInfinity;
1327  }
1328 
1329 #ifdef G4VERBOSE
1330  if( fVerbose > 1 )
1331  {
1332  if( fVerbose >= 4 )
1333  {
1334  G4cout << " ----- Upon exiting :" << G4endl;
1335  PrintState();
1336  }
1337  G4cout << " Returned step= " << Step;
1338  if( fVerbose > 5 ) G4cout << G4endl;
1339  if( Step == kInfinity )
1340  {
1341  G4cout << " Requested step= " << pCurrentProposedStepLength ;
1342  if( fVerbose > 5) G4cout << G4endl;
1343  }
1344  G4cout << " Safety = " << pNewSafety << G4endl;
1345  }
1346 #endif
1347 
1348  return Step;
1349 }
1350 
1351 // ********************************************************************
1352 // CheckNextStep
1353 //
1354 // Compute the step without altering the navigator state
1355 // ********************************************************************
1356 //
1358  const G4ThreeVector& pDirection,
1359  const G4double pCurrentProposedStepLength,
1360  G4double& pNewSafety)
1361 {
1363  G4double step;
1364 
1365  // Save the state, for this parasitic call
1366  //
1367  //SetSavedState();
1368 // G4SaveNavigatorState savedState(fpNavigatorState);
1369  G4NavigatorState savedState(*fpNavigatorState);
1370 
1371  step = ComputeStep ( pGlobalpoint,
1372  pDirection,
1373  pCurrentProposedStepLength,
1374  pNewSafety );
1375 
1376  // If a parasitic call, then attempt to restore the key parts of the state
1377  //
1378  *fpNavigatorState = savedState;
1379  //RestoreSavedState();
1380  // NOTE: the state of the current subnavigator is NOT restored.
1381  // ***> TODO: restore subnavigator state
1382  // if( last_located) Need Position of last location
1383  // if( last_computed step) Need Endposition of last step
1384 
1385 
1386  return step;
1387 }
1388 
1389 // ********************************************************************
1390 // ResetState
1391 //
1392 // Resets stack and minimum of navigator state `machine'
1393 // ********************************************************************
1394 //
1396 {
1397  fWasLimitedByGeometry = false;
1398  fEntering = false;
1399  fExiting = false;
1400  fLocatedOnEdge = false;
1401  fLastStepWasZero = false;
1402  fEnteredDaughter = false;
1403  fExitedMother = false;
1404  fPushed = false;
1405 
1406  fValidExitNormal = false;
1408  fCalculatedExitNormal = false;
1409 
1410  fExitNormal = G4ThreeVector(0,0,0);
1413 
1415  fPreviousSafety = 0.0;
1416 
1417  fNumberZeroSteps = 0;
1418 
1420  fBlockedReplicaNo = -1;
1421 
1423  fLocatedOutsideWorld = false;
1424 }
1425 
1426 // ********************************************************************
1427 // SetupHierarchy
1428 //
1429 // Renavigates & resets hierarchy described by current history
1430 // o Reset volumes
1431 // o Recompute transforms and/or solids of replicated/parameterised volumes
1432 // ********************************************************************
1433 //
1435 {
1436  G4int i;
1437  const G4int cdepth = fHistory.GetDepth();
1438  G4VPhysicalVolume *current;
1439  G4VSolid *pSolid;
1440  G4VPVParameterisation *pParam;
1441 
1442  for ( i=1; i<=cdepth; i++ )
1443  {
1444  current = fHistory.GetVolume(i);
1445  switch ( fHistory.GetVolumeType(i) )
1446  {
1447  case kNormal:
1448  break;
1449  case kReplica:
1450  freplicaNav.ComputeTransformation(fHistory.GetReplicaNo(i), current);
1451  break;
1452  case kParameterised:
1453  G4int replicaNo;
1454  pParam = current->GetParameterisation();
1455  replicaNo = fHistory.GetReplicaNo(i);
1456  pSolid = pParam->ComputeSolid(replicaNo, current);
1457 
1458  // Set up dimensions & transform in solid/physical volume
1459  //
1460  pSolid->ComputeDimensions(pParam, replicaNo, current);
1461  pParam->ComputeTransformation(replicaNo, current);
1462 
1463  G4TouchableHistory *pTouchable= 0;
1464  if( pParam->IsNested() )
1465  {
1466  pTouchable= new G4TouchableHistory( fHistory );
1467  pTouchable->MoveUpHistory(); // Move up to the parent level
1468  // Adequate only if Nested at the Branch level (last)
1469  // To extend to other cases:
1470  // pTouchable->MoveUpHistory(cdepth-i-1);
1471  // Move to the parent level of *Current* level
1472  // Could replace this line and constructor with a revised
1473  // c-tor for History(levels to drop)
1474  }
1475  // Set up the correct solid and material in Logical Volume
1476  //
1477  G4LogicalVolume *pLogical = current->GetLogicalVolume();
1478  pLogical->SetSolid( pSolid );
1479  pLogical->UpdateMaterial( pParam ->
1480  ComputeMaterial(replicaNo, current, pTouchable) );
1481  delete pTouchable;
1482  break;
1483  }
1484  }
1485 }
1486 
1487 // ********************************************************************
1488 // GetLocalExitNormal
1489 //
1490 // Obtains the Normal vector to a surface (in local coordinates)
1491 // pointing out of previous volume and into current volume
1492 // ********************************************************************
1493 //
1495 {
1497  G4ThreeVector ExitNormal(0.,0.,0.);
1498  G4VSolid *currentSolid=0;
1499  G4LogicalVolume *candidateLogical;
1501  {
1502  // use fLastLocatedPointLocal and next candidate volume
1503  //
1504  G4ThreeVector nextSolidExitNormal(0.,0.,0.);
1505 
1506  if( fEntering && (fBlockedPhysicalVolume!=0) )
1507  {
1508  candidateLogical= fBlockedPhysicalVolume->GetLogicalVolume();
1509  if( candidateLogical )
1510  {
1511  // fLastStepEndPointLocal is in the coordinates of the mother
1512  // we need it in the daughter's coordinate system.
1513 
1514  // The following code should also work in case of Replica
1515  {
1516  // First transform fLastLocatedPointLocal to the new daughter
1517  // coordinates
1518  //
1519  G4AffineTransform MotherToDaughterTransform=
1523  G4ThreeVector daughterPointOwnLocal=
1524  MotherToDaughterTransform.TransformPoint( fLastStepEndPointLocal );
1525 
1526  // OK if it is a parameterised volume
1527  //
1528  EInside inSideIt;
1529  G4bool onSurface;
1530  G4double safety= -1.0;
1531  currentSolid= candidateLogical->GetSolid();
1532  inSideIt = currentSolid->Inside(daughterPointOwnLocal);
1533  onSurface = (inSideIt == kSurface);
1534  if( ! onSurface )
1535  {
1536  if( inSideIt == kOutside )
1537  {
1538  safety = (currentSolid->DistanceToIn(daughterPointOwnLocal));
1539  onSurface = safety < 100.0 * kCarTolerance;
1540  }
1541  else if (inSideIt == kInside )
1542  {
1543  safety = (currentSolid->DistanceToOut(daughterPointOwnLocal));
1544  onSurface = safety < 100.0 * kCarTolerance;
1545  }
1546  }
1547 
1548  if( onSurface )
1549  {
1550  nextSolidExitNormal =
1551  currentSolid->SurfaceNormal(daughterPointOwnLocal);
1552 
1553  // Entering the solid ==> opposite
1554  //
1555  ExitNormal = -nextSolidExitNormal;
1556  fCalculatedExitNormal= true;
1557  }
1558  else
1559  {
1560 #ifdef G4VERBOSE
1561  if(( fVerbose == 1 ) && ( fCheck ))
1562  {
1563  std::ostringstream message;
1564  message << "Point not on surface ! " << G4endl
1565  << " Point = "
1566  << daughterPointOwnLocal << G4endl
1567  << " Physical volume = "
1568  << fBlockedPhysicalVolume->GetName() << G4endl
1569  << " Logical volume = "
1570  << candidateLogical->GetName() << G4endl
1571  << " Solid = " << currentSolid->GetName()
1572  << " Type = "
1573  << currentSolid->GetEntityType() << G4endl
1574  << *currentSolid << G4endl;
1575  if( inSideIt == kOutside )
1576  {
1577  message << "Point is Outside. " << G4endl
1578  << " Safety (from outside) = " << safety << G4endl;
1579  }
1580  else // if( inSideIt == kInside )
1581  {
1582  message << "Point is Inside. " << G4endl
1583  << " Safety (from inside) = " << safety << G4endl;
1584  }
1585  G4Exception("G4ITNavigator2::GetLocalExitNormal()", "GeomNav1001",
1586  JustWarning, message);
1587  }
1588 #endif
1589  }
1590  *valid = onSurface; // was =true;
1591  }
1592  }
1593  }
1594  else if ( fExiting )
1595  {
1596  ExitNormal = fGrandMotherExitNormal;
1597  *valid = true;
1598  fCalculatedExitNormal= true; // Should be true already
1599  }
1600  else // i.e. ( fBlockedPhysicalVolume == 0 )
1601  {
1602  *valid = false;
1603  G4Exception("G4ITNavigator2::GetLocalExitNormal()",
1604  "GeomNav0003", JustWarning,
1605  "Incorrect call to GetLocalSurfaceNormal." );
1606  }
1607  }
1608  else // ( ! fLastTriedStepComputation ) ie. last call was to Locate
1609  {
1610  if ( EnteredDaughterVolume() )
1611  {
1612  G4VSolid* daughterSolid =fHistory.GetTopVolume()->GetLogicalVolume()
1613  ->GetSolid();
1614  ExitNormal= -(daughterSolid->SurfaceNormal(fLastLocatedPointLocal));
1615  if( std::fabs(ExitNormal.mag2()-1.0 ) > CLHEP::perMillion )
1616  {
1618  desc << " Parameters of solid: " << *daughterSolid
1619  << " Point for surface = " << fLastLocatedPointLocal << std::endl;
1620  G4Exception("G4ITNavigator2::GetLocalExitNormal()",
1621  "GeomNav0003", FatalException, desc,
1622  "Surface Normal returned by Solid is not a Unit Vector." );
1623  }
1624  fCalculatedExitNormal= true;
1625  *valid = true;
1626  }
1627  else
1628  {
1629  if( fExitedMother )
1630  {
1631  ExitNormal = fGrandMotherExitNormal;
1632  *valid = true;
1633  fCalculatedExitNormal= true;
1634  }
1635  else // We are not at a boundary. ExitNormal remains (0,0,0)
1636  {
1637  *valid = false;
1638  fCalculatedExitNormal= false;
1639  G4ExceptionDescription message;
1640  message << "Function called when *NOT* at a Boundary." << G4endl;
1641  G4Exception("G4ITNavigator2::GetLocalExitNormal()",
1642  "GeomNav0003", JustWarning, message);
1643  }
1644  }
1645  }
1646  return ExitNormal;
1647 }
1648 
1649 // ********************************************************************
1650 // GetMotherToDaughterTransform
1651 //
1652 // Obtains the mother to daughter affine transformation
1653 // ********************************************************************
1654 //
1657  G4int enteringReplicaNo,
1658  EVolume enteringVolumeType )
1659 {
1661  switch (enteringVolumeType)
1662  {
1663  case kNormal: // Nothing is needed to prepare the transformation
1664  break; // It is stored already in the physical volume (placement)
1665  case kReplica: // Sets the transform in the Replica - tbc
1666  G4Exception("G4ITNavigator2::GetMotherToDaughterTransform()",
1667  "GeomNav0001", FatalException,
1668  "Method NOT Implemented yet for replica volumes.");
1669  break;
1670  case kParameterised:
1671  if( pEnteringPhysVol->GetRegularStructureId() == 0 )
1672  {
1673  G4VPVParameterisation *pParam =
1674  pEnteringPhysVol->GetParameterisation();
1675  G4VSolid* pSolid =
1676  pParam->ComputeSolid(enteringReplicaNo, pEnteringPhysVol);
1677  pSolid->ComputeDimensions(pParam, enteringReplicaNo, pEnteringPhysVol);
1678 
1679  // Sets the transform in the Parameterisation
1680  //
1681  pParam->ComputeTransformation(enteringReplicaNo, pEnteringPhysVol);
1682 
1683  // Set the correct solid and material in Logical Volume
1684  //
1685  G4LogicalVolume* pLogical = pEnteringPhysVol->GetLogicalVolume();
1686  pLogical->SetSolid( pSolid );
1687  }
1688  break;
1689  }
1690  return G4AffineTransform(pEnteringPhysVol->GetRotation(),
1691  pEnteringPhysVol->GetTranslation()).Invert();
1692 }
1693 
1694 // ********************************************************************
1695 // GetLocalExitNormalAndCheck
1696 //
1697 // Obtains the Normal vector to a surface (in local coordinates)
1698 // pointing out of previous volume and into current volume, and
1699 // checks the current point against expected 'local' value.
1700 // ********************************************************************
1701 //
1704 #ifdef G4DEBUG_NAVIGATION
1705  const G4ThreeVector& ExpectedBoundaryPointGlobal,
1706 #else
1707  const G4ThreeVector&,
1708 #endif
1709  G4bool* pValid)
1710 {
1712 #ifdef G4DEBUG_NAVIGATION
1713  // Check Current point against expected 'local' value
1714  //
1716  {
1717  G4ThreeVector ExpectedBoundaryPointLocal;
1718 
1719  const G4AffineTransform& GlobalToLocal= GetGlobalToLocalTransform();
1720  ExpectedBoundaryPointLocal =
1721  GlobalToLocal.TransformPoint( ExpectedBoundaryPointGlobal );
1722 
1723  // Add here: Comparison against expected position,
1724  // i.e. the endpoint of ComputeStep
1725  }
1726 #endif
1727 
1728  return GetLocalExitNormal( pValid);
1729 }
1730 
1731 // ********************************************************************
1732 // GetGlobalExitNormal
1733 //
1734 // Obtains the Normal vector to a surface (in global coordinates)
1735 // pointing out of previous volume and into current volume
1736 // ********************************************************************
1737 //
1740  G4bool* pNormalCalculated)
1741 {
1743  G4bool validNormal;
1744  G4ThreeVector localNormal, globalNormal;
1745  G4bool usingStored;
1746 
1747  usingStored=
1749  ( ( fLastTriedStepComputation && fExiting) // Just calculated it
1750  || // No locate in between
1752  && (IntersectPointGlobal-fStepEndPoint).mag2()
1753  < (10.0*kCarTolerance*kCarTolerance)
1754  ) // Calculated it 'just' before & then called locate
1755  // but it did not move position
1756  );
1757 
1758  if( usingStored )
1759  {
1760  // This was computed in ComputeStep -- and only on arrival at boundary
1761  //
1762  globalNormal = fExitNormalGlobalFrame;
1763  G4double normMag2 = globalNormal.mag2();
1764  if( std::fabs ( normMag2 - 1.0 ) < perMillion ) // Value is good
1765  {
1766  *pNormalCalculated = true; // ComputeStep always computes it if Exiting
1767  // (fExiting==true)
1768  }
1769  else
1770  {
1771  G4ExceptionDescription message;
1772 
1773  message << " ERROR> Expected normal-global-frame to valid (unit vector) "
1774  << " - but |normal| = " << std::sqrt(normMag2)
1775  << " - and |normal|^ = " << normMag2
1776  << " which differs from 1.0 by " << normMag2 - 1.0 << G4endl
1777  << " n = " << fExitNormalGlobalFrame << G4endl;
1778  message << "============================================================"
1779  << G4endl;
1780  G4int oldVerbose = fVerbose;
1781  fVerbose=4;
1782  message << " State of Navigator: " << G4endl;
1783  message << *this << G4endl;
1784  fVerbose = oldVerbose;
1785  message << "============================================================"
1786  << G4endl;
1787 
1788  G4Exception("G4ITNavigator2::GetGlobalExitNormal()",
1789  "GeomNav0003",JustWarning, message,
1790  "Value obtained from stored global-normal is not a unit vector.");
1791 
1792  // (Re)Compute it now -- as either it was not computed, or it is wrong.
1793  //
1794  localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,
1795  &validNormal);
1796  *pNormalCalculated = fCalculatedExitNormal;
1797 
1798  G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1799  globalNormal = localToGlobal.TransformAxis( localNormal );
1800  }
1801  }
1802  else
1803  {
1804  localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,&validNormal);
1805  *pNormalCalculated = fCalculatedExitNormal;
1806 
1807 #ifdef G4DEBUG_NAVIGATION
1808  usingStored= false;
1809 
1810  if( (!validNormal) && !fCalculatedExitNormal)
1811  {
1813  edN << " Calculated = " << fCalculatedExitNormal << G4endl;
1814  edN << " Entering= " << fEntering << G4endl;
1815  G4int oldVerbose= this->GetVerboseLevel();
1816  this->SetVerboseLevel(4);
1817  edN << " State of Navigator: " << G4endl;
1818  edN << *this << G4endl;
1819  this->SetVerboseLevel( oldVerbose );
1820 
1821  G4Exception("G4ITNavigator2::GetGlobalExitNormal()",
1822  "GeomNav0003", JustWarning, edN,
1823  "LocalExitNormalAndCheck() did not calculate Normal.");
1824  }
1825 #endif
1826 
1827  G4double localMag2= localNormal.mag2();
1828  if( validNormal && (std::fabs(localMag2-1.0)) > CLHEP::perMillion )
1829  {
1831 
1832  edN << "G4ITNavigator2::GetGlobalExitNormal: "
1833  << " Using Local Normal - from call to GetLocalExitNormalAndCheck. "
1834  << G4endl
1835  << " Local Exit Normal : " << " || = " << std::sqrt(localMag2)
1836  << " vec = " << localNormal << G4endl
1837  << " Global Exit Normal : " << " || = " << globalNormal.mag()
1838  << " vec = " << globalNormal << G4endl;
1839  edN << " Calculated It = " << fCalculatedExitNormal << G4endl;
1840 
1841  G4Exception("G4ITNavigator2::GetGlobalExitNormal()",
1842  "GeomNav0003",JustWarning, edN,
1843  "Value obtained from new local *solid* is incorrect.");
1844  localNormal = localNormal.unit(); // Should we correct it ??
1845  }
1846  G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1847  globalNormal = localToGlobal.TransformAxis( localNormal );
1848  }
1849 
1850 #ifdef G4DEBUG_NAVIGATION
1851  if( usingStored )
1852  {
1853  G4ThreeVector globalNormAgn;
1854 
1855  localNormal= GetLocalExitNormalAndCheck(IntersectPointGlobal, &validNormal);
1856 
1857  G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1858  globalNormAgn = localToGlobal.TransformAxis( localNormal );
1859 
1860  // Check the value computed against fExitNormalGlobalFrame
1861  G4ThreeVector diffNorm = globalNormAgn - fExitNormalGlobalFrame;
1862  if( diffNorm.mag2() > perMillion*CLHEP::perMillion)
1863  {
1864  G4ExceptionDescription edDfn;
1865  edDfn << "Found difference in normals in case of exiting mother "
1866  << "- when Get is called after ComputingStep " << G4endl;
1867  edDfn << " Magnitude of diff = " << diffNorm.mag() << G4endl;
1868  edDfn << " Normal stored (Global) = " << fExitNormalGlobalFrame
1869  << G4endl;
1870  edDfn << " Global Computed from Local = " << globalNormAgn << G4endl;
1871  G4Exception("G4ITNavigator::GetGlobalExitNormal()", "GeomNav0003",
1872  JustWarning, edDfn);
1873  }
1874  }
1875 #endif
1876 
1877  return globalNormal;
1878 }
1879 
1880 // To make the new Voxel Safety the default, uncomment the next line
1881 #define G4NEW_SAFETY 1
1882 
1883 // ********************************************************************
1884 // ComputeSafety
1885 //
1886 // It assumes that it will be
1887 // i) called at the Point in the same volume as the EndPoint of the
1888 // ComputeStep.
1889 // ii) after (or at the end of) ComputeStep OR after the relocation.
1890 // ********************************************************************
1891 //
1893  const G4double pMaxLength,
1894  const G4bool keepState)
1895 {
1897  G4double newSafety = 0.0;
1898 
1899 #ifdef G4DEBUG_NAVIGATION
1900  G4int oldcoutPrec = G4cout.precision(8);
1901  if( fVerbose > 0 )
1902  {
1903  G4cout << "*** G4ITNavigator2::ComputeSafety: ***" << G4endl
1904  << " Called at point: " << pGlobalpoint << G4endl;
1905 
1906  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
1907  G4cout << " Volume = " << motherPhysical->GetName()
1908  << " - Maximum length = " << pMaxLength << G4endl;
1909  if( fVerbose >= 4 )
1910  {
1911  G4cout << " ----- Upon entering Compute Safety:" << G4endl;
1912  PrintState();
1913  }
1914  }
1915 #endif
1916 
1917  G4SaveNavigatorState* savedState(0);
1918 
1919  G4double distEndpointSq = (pGlobalpoint-fStepEndPoint).mag2();
1920  G4bool stayedOnEndpoint = distEndpointSq < kCarTolerance*kCarTolerance;
1921  G4bool endpointOnSurface = fEnteredDaughter || fExitedMother;
1922 
1923  if( endpointOnSurface && stayedOnEndpoint )
1924  {
1925 #ifdef G4DEBUG_NAVIGATION
1926  if( fVerbose >= 2 )
1927  {
1928  G4cout << " G4Navigator::ComputeSafety() finds that point - "
1929  << pGlobalpoint << " - is on surface " << G4endl;
1930  if( fEnteredDaughter ) { G4cout << " entered new daughter volume"; }
1931  if( fExitedMother ) { G4cout << " and exited previous volume."; }
1932  G4cout << G4endl;
1933  G4cout << " EndPoint was = " << fStepEndPoint << G4endl;
1934  }
1935 #endif
1936  newSafety = 0.0;
1937  // return newSafety;
1938  }
1939  else // if( !(endpointOnSurface && stayedOnEndpoint) )
1940  {
1941 
1942  if (keepState)
1943  {
1944 // SetSavedState();
1945  savedState = new G4SaveNavigatorState(fpNavigatorState);
1946  }
1947 
1948  // Pseudo-relocate to this point (updates voxel information only)
1949  //
1950  LocateGlobalPointWithinVolume( pGlobalpoint );
1951  // --->> DANGER: Side effects on sub-navigator voxel information <<---
1952  // Could be replaced again by 'granular' calls to sub-navigator
1953  // locates (similar side-effects, but faster.
1954  // Solutions:
1955  // 1) Re-locate (to where?)
1956  // 2) Insure that the methods using (G4ComputeStep?)
1957  // does a relocation (if information is disturbed only ?)
1958 
1959 #ifdef G4DEBUG_NAVIGATION
1960  if( fVerbose >= 2 )
1961  {
1962  G4cout << " G4ITNavigator2::ComputeSafety() relocates-in-volume to point: "
1963  << pGlobalpoint << G4endl;
1964  }
1965 #endif
1966  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
1967  G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
1968  G4SmartVoxelHeader* pVoxelHeader = motherLogical->GetVoxelHeader();
1969  G4ThreeVector localPoint = ComputeLocalPoint(pGlobalpoint);
1970 
1971  if ( fHistory.GetTopVolumeType()!=kReplica )
1972  {
1973  switch(CharacteriseDaughters(motherLogical))
1974  {
1975  case kNormal:
1976  if ( pVoxelHeader )
1977  {
1978 #ifdef G4NEW_SAFETY
1979  G4double safetyTwo = fpVoxelSafety->ComputeSafety(localPoint,
1980  *motherPhysical, pMaxLength);
1981  newSafety= safetyTwo; // Faster and best available
1982 #else
1983  G4double safetyOldVoxel;
1984  LocateGlobalPointWithinVolume(pGlobalpoint);
1985  safetyOldVoxel =
1986  fvoxelNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1987  newSafety= safetyOldVoxel;
1988 #endif
1989  }
1990  else
1991  {
1992  newSafety=fnormalNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1993  }
1994  break;
1995  case kParameterised:
1996  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
1997  {
1998  newSafety=fparamNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1999  }
2000  else // Regular structure
2001  {
2002  newSafety=fregularNav.ComputeSafety(localPoint,fHistory,pMaxLength);
2003  }
2004  break;
2005  case kReplica:
2006  G4Exception("G4ITNavigator2::ComputeSafety()", "GeomNav0001",
2007  FatalException, "Not applicable for replicated volumes.");
2008  break;
2009  }
2010  }
2011  else
2012  {
2013  newSafety = freplicaNav.ComputeSafety(pGlobalpoint, localPoint,
2014  fHistory, pMaxLength);
2015  }
2016 
2017  if (keepState)
2018  {
2019  *fpNavigatorState = *savedState;
2020  delete savedState;
2021  // RestoreSavedState();
2022  // This now overwrites the values of the Safety 'sphere' (correction)
2023  }
2024 
2025  // Remember last safety origin & value
2026  //
2027  // We overwrite the Safety 'sphere' - keeping old behaviour
2028  fPreviousSftOrigin = pGlobalpoint;
2029  fPreviousSafety = newSafety;
2030  }
2031 
2032 #ifdef G4DEBUG_NAVIGATION
2033  if( fVerbose > 1 )
2034  {
2035  G4cout << " ---- Exiting ComputeSafety " << G4endl;
2036  if( fVerbose > 2 ) { PrintState(); }
2037  G4cout << " Returned value of Safety = " << newSafety << G4endl;
2038  }
2039  G4cout.precision(oldcoutPrec);
2040 #endif
2041 
2042  return newSafety;
2043 }
2044 
2045 
2046 // ********************************************************************
2047 // RecheckDistanceToCurrentBoundary
2048 //
2049 // Trial method for checking potential displacement for MS
2050 // Check position aDisplacedGlobalpoint, to see whether it is in the
2051 // current volume (mother).
2052 // If in mother, check distance to boundary along aNewDirection.
2053 // If in entering daughter, check distance back to boundary.
2054 // NOTE:
2055 // Can be called only after ComputeStep() is called - before ReLocation
2056 // Deals only with current volume (and potentially entered)
2057 // Caveats
2058 // First VERSION: Does not consider daughter volumes if it remained in mother
2059 // neither for checking whether it has exited current (mother) volume,
2060 // nor for determining distance to exit this (mother) volume.
2061 // ********************************************************************
2062 //
2064  const G4ThreeVector &aDisplacedGlobalPoint,
2065  const G4ThreeVector &aNewDirection,
2066  const G4double ProposedMove,
2067  G4double *prDistance,
2068  G4double *prNewSafety) const
2069 {
2070  G4ThreeVector localPosition = ComputeLocalPoint(aDisplacedGlobalPoint);
2071  G4ThreeVector localDirection = ComputeLocalAxis(aNewDirection);
2072  // G4double Step = kInfinity;
2073 
2074  G4bool validExitNormal;
2075  G4ThreeVector exitNormal;
2076  // Check against mother solid
2077  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
2078  G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
2079 
2080 #ifdef CHECK_ORDER_OF_METHODS
2082  {
2083  G4Exception("G4Navigator::RecheckDistanceToCurrentBoundary()",
2084  "GeomNav0001", FatalException,
2085  "Method must be called after ComputeStep(), before call to LocateMethod.");
2086  }
2087 #endif
2088 
2089  EInside locatedDaug; // = kUndefined;
2090  G4double daughterStep= DBL_MAX;
2091  G4double daughterSafety= DBL_MAX;
2092 
2093  if( fEnteredDaughter )
2094  {
2095  if( motherLogical->CharacteriseDaughters() ==kReplica ) { return false; }
2096 
2097  // Track arrived at boundary of a daughter volume at
2098  // the last call of ComputeStep().
2099  // In case the proposed displaced point is inside this daughter,
2100  // it must backtrack at least to the entry point.
2101  // NOTE: No check is made against other daughter volumes. It is
2102  // assumed that the proposed displacement is small enough that
2103  // this is not needed.
2104 
2105  // Must check boundary of current daughter
2106  //
2107  G4VPhysicalVolume *candPhysical= fBlockedPhysicalVolume;
2108  G4LogicalVolume *candLogical= candPhysical->GetLogicalVolume();
2109  G4VSolid *candSolid= candLogical->GetSolid();
2110 
2111  G4AffineTransform nextLevelTrf(candPhysical->GetRotation(),
2112  candPhysical->GetTranslation());
2113 
2114  G4ThreeVector dgPosition= nextLevelTrf.TransformPoint(localPosition);
2115  G4ThreeVector dgDirection= nextLevelTrf.TransformAxis(localDirection);
2116  locatedDaug = candSolid->Inside(dgPosition);
2117 
2118  if( locatedDaug == kInside )
2119  {
2120  // Reverse direction - and find first exit. ( Is it valid?)
2121  // Must backtrack
2122  G4double distanceBackOut =
2123  candSolid->DistanceToOut(dgPosition,
2124  - dgDirection, // Reverse direction
2125  true, &validExitNormal, &exitNormal);
2126  daughterStep= - distanceBackOut;
2127  // No check is made whether the particle could have arrived at
2128  // at this location without encountering another volume or
2129  // a different psurface of the current volume
2130  if( prNewSafety )
2131  {
2132  daughterSafety= candSolid->DistanceToOut(dgPosition);
2133  }
2134  }
2135  else
2136  {
2137  if( locatedDaug == kOutside )
2138  {
2139  // See whether it still intersects it
2140  //
2141  daughterStep= candSolid->DistanceToIn(dgPosition,
2142  dgDirection);
2143  if( prNewSafety )
2144  {
2145  daughterSafety= candSolid->DistanceToIn(dgPosition);
2146  }
2147  }
2148  else
2149  {
2150  // The point remains on the surface of candidate solid
2151  //
2152  daughterStep= 0.0;
2153  daughterSafety= 0.0;
2154  }
2155  }
2156 
2157  // If trial point is in daughter (or on its surface) we have the
2158  // answer, the rest is not relevant
2159  //
2160  if( locatedDaug != kOutside )
2161  {
2162  *prDistance= daughterStep;
2163  if( prNewSafety ) { *prNewSafety= daughterSafety; }
2164  return true;
2165  }
2166  // If ever extended, so that some type of mother cut daughter,
2167  // this would change
2168  }
2169 
2170  G4VSolid *motherSolid= motherLogical->GetSolid();
2171 
2172  G4double motherStep= DBL_MAX, motherSafety= DBL_MAX;
2173 
2174  // Check distance to boundary of mother
2175  //
2176  if ( fHistory.GetTopVolumeType()!=kReplica )
2177  {
2178  EInside locatedMoth = motherSolid->Inside(localPosition);
2179 
2180  if( locatedMoth == kInside )
2181  {
2182  motherSafety= motherSolid->DistanceToOut(localPosition);
2183  if( ProposedMove >= motherSafety )
2184  {
2185  motherStep= motherSolid->DistanceToOut(localPosition,
2186  localDirection,
2187  true, &validExitNormal, &exitNormal);
2188  }
2189  else
2190  {
2191  motherStep= ProposedMove;
2192  }
2193  }
2194  else if( locatedMoth == kOutside)
2195  {
2196  motherSafety= motherSolid->DistanceToIn(localPosition);
2197  if( ProposedMove >= motherSafety )
2198  {
2199  motherStep= - motherSolid->DistanceToIn(localPosition,
2200  -localDirection);
2201  }
2202  }
2203  else
2204  {
2205  motherSafety= 0.0;
2206  *prDistance= 0.0; // On surface - no move // motherStep;
2207  if( prNewSafety ) { *prNewSafety= motherSafety; }
2208  return false;
2209  }
2210  }
2211  else
2212  {
2213  return false;
2214  }
2215 
2216  *prDistance= std::min( motherStep, daughterStep );
2217  if( prNewSafety )
2218  {
2219  *prNewSafety= std::min( motherSafety, daughterSafety );
2220  }
2221  return true;
2222 }
2223 
2224 
2225 // ********************************************************************
2226 // CreateTouchableHistoryHandle
2227 // ********************************************************************
2228 //
2230 {
2233 }
2234 
2235 // ********************************************************************
2236 // PrintState
2237 // ********************************************************************
2238 //
2240 {
2242  G4int oldcoutPrec = G4cout.precision(4);
2243  if( fVerbose >= 4 )
2244  {
2245  G4cout << "The current state of G4Navigator is: " << G4endl;
2246  G4cout << " ValidExitNormal= " << fValidExitNormal // << G4endl
2247  << " ExitNormal = " << fExitNormal // << G4endl
2248  << " Exiting = " << fExiting // << G4endl
2249  << " Entering = " << fEntering // << G4endl
2250  << " BlockedPhysicalVolume= " ;
2251  if (fBlockedPhysicalVolume==0)
2252  G4cout << "None";
2253  else
2254  G4cout << fBlockedPhysicalVolume->GetName();
2255  G4cout << G4endl
2256  << " BlockedReplicaNo = " << fBlockedReplicaNo // << G4endl
2257  << " LastStepWasZero = " << fLastStepWasZero // << G4endl
2258  << G4endl;
2259  }
2260  if( ( 1 < fVerbose) && (fVerbose < 4) )
2261  {
2262  G4cout << G4endl; // Make sure to line up
2263  G4cout << std::setw(30) << " ExitNormal " << " "
2264  << std::setw( 5) << " Valid " << " "
2265  << std::setw( 9) << " Exiting " << " "
2266  << std::setw( 9) << " Entering" << " "
2267  << std::setw(15) << " Blocked:Volume " << " "
2268  << std::setw( 9) << " ReplicaNo" << " "
2269  << std::setw( 8) << " LastStepZero " << " "
2270  << G4endl;
2271  G4cout << "( " << std::setw(7) << fExitNormal.x()
2272  << ", " << std::setw(7) << fExitNormal.y()
2273  << ", " << std::setw(7) << fExitNormal.z() << " ) "
2274  << std::setw( 5) << fValidExitNormal << " "
2275  << std::setw( 9) << fExiting << " "
2276  << std::setw( 9) << fEntering << " ";
2277  if ( fBlockedPhysicalVolume==0 )
2278  {
2279  G4cout << std::setw(15) << "None";
2280  }
2281  else
2282  {
2283  G4cout << std::setw(15)<< fBlockedPhysicalVolume->GetName();
2284  }
2285  G4cout << std::setw( 9) << fBlockedReplicaNo << " "
2286  << std::setw( 8) << fLastStepWasZero << " "
2287  << G4endl;
2288  }
2289  if( fVerbose > 2 )
2290  {
2291  G4cout.precision(8);
2292  G4cout << " Current Localpoint = " << fLastLocatedPointLocal << G4endl;
2293  G4cout << " PreviousSftOrigin = " << fPreviousSftOrigin << G4endl;
2294  G4cout << " PreviousSafety = " << fPreviousSafety << G4endl;
2295  }
2296  G4cout.precision(oldcoutPrec);
2297 }
2298 
2299 // ********************************************************************
2300 // ComputeStepLog
2301 // ********************************************************************
2302 //
2303 void G4ITNavigator2::ComputeStepLog(const G4ThreeVector& pGlobalpoint,
2304  G4double moveLenSq) const
2305 {
2307  // The following checks only make sense if the move is larger
2308  // than the tolerance.
2309 
2310  static const G4double fAccuracyForWarning = kCarTolerance,
2311  fAccuracyForException = 1000*kCarTolerance;
2312 
2313  G4ThreeVector OriginalGlobalpoint = fHistory.GetTopTransform().Inverse().
2314  TransformPoint(fLastLocatedPointLocal);
2315 
2316  G4double shiftOriginSafSq = (fPreviousSftOrigin-pGlobalpoint).mag2();
2317 
2318  // Check that the starting point of this step is
2319  // within the isotropic safety sphere of the last point
2320  // to a accuracy/precision given by fAccuracyForWarning.
2321  // If so give warning.
2322  // If it fails by more than fAccuracyForException exit with error.
2323  //
2324  if( shiftOriginSafSq >= sqr(fPreviousSafety) )
2325  {
2326  G4double shiftOrigin = std::sqrt(shiftOriginSafSq);
2327  G4double diffShiftSaf = shiftOrigin - fPreviousSafety;
2328 
2329  if( diffShiftSaf > fAccuracyForWarning )
2330  {
2331  G4int oldcoutPrec= G4cout.precision(8);
2332  G4int oldcerrPrec= G4cerr.precision(10);
2333  std::ostringstream message, suggestion;
2334  message << "Accuracy error or slightly inaccurate position shift."
2335  << G4endl
2336  << " The Step's starting point has moved "
2337  << std::sqrt(moveLenSq)/mm << " mm " << G4endl
2338  << " since the last call to a Locate method." << G4endl
2339  << " This has resulted in moving "
2340  << shiftOrigin/mm << " mm "
2341  << " from the last point at which the safety "
2342  << " was calculated " << G4endl
2343  << " which is more than the computed safety= "
2344  << fPreviousSafety/mm << " mm at that point." << G4endl
2345  << " This difference is "
2346  << diffShiftSaf/mm << " mm." << G4endl
2347  << " The tolerated accuracy is "
2348  << fAccuracyForException/mm << " mm.";
2349 
2350  suggestion << " ";
2351  static G4ThreadLocal G4int warnNow = 0;
2352  if( ((++warnNow % 100) == 1) )
2353  {
2354  message << G4endl
2355  << " This problem can be due to either " << G4endl
2356  << " - a process that has proposed a displacement"
2357  << " larger than the current safety , or" << G4endl
2358  << " - inaccuracy in the computation of the safety";
2359  suggestion << "We suggest that you " << G4endl
2360  << " - find i) what particle is being tracked, and "
2361  << " ii) through what part of your geometry " << G4endl
2362  << " for example by re-running this event with "
2363  << G4endl
2364  << " /tracking/verbose 1 " << G4endl
2365  << " - check which processes you declare for"
2366  << " this particle (and look at non-standard ones)"
2367  << G4endl
2368  << " - in case, create a detailed logfile"
2369  << " of this event using:" << G4endl
2370  << " /tracking/verbose 6 ";
2371  }
2372  G4Exception("G4ITNavigator2::ComputeStep()",
2373  "GeomNav1002", JustWarning,
2374  message, G4String(suggestion.str()));
2375  G4cout.precision(oldcoutPrec);
2376  G4cerr.precision(oldcerrPrec);
2377  }
2378 #ifdef G4DEBUG_NAVIGATION
2379  else
2380  {
2381  G4cerr << "WARNING - G4ITNavigator2::ComputeStep()" << G4endl
2382  << " The Step's starting point has moved "
2383  << std::sqrt(moveLenSq) << "," << G4endl
2384  << " which has taken it to the limit of"
2385  << " the current safety. " << G4endl;
2386  }
2387 #endif
2388  }
2389  G4double safetyPlus = fPreviousSafety + fAccuracyForException;
2390  if ( shiftOriginSafSq > sqr(safetyPlus) )
2391  {
2392  std::ostringstream message;
2393  message << "May lead to a crash or unreliable results." << G4endl
2394  << " Position has shifted considerably without"
2395  << " notifying the navigator !" << G4endl
2396  << " Tolerated safety: " << safetyPlus << G4endl
2397  << " Computed shift : " << shiftOriginSafSq;
2398  G4Exception("G4ITNavigator2::ComputeStep()", "GeomNav1002",
2399  JustWarning, message);
2400  }
2401 }
2402 
2403 // ********************************************************************
2404 // Operator <<
2405 // ********************************************************************
2406 //
2407 std::ostream& operator << (std::ostream &os,const G4ITNavigator2 &n)
2408 {
2409  // Old version did only the following:
2410  // os << "Current History: " << G4endl << n.fHistory;
2411  // Old behaviour is recovered for fVerbose = 0
2412 
2413  // Adapted from G4ITNavigator2::PrintState() const
2414 
2415  G4int oldcoutPrec = os.precision(4);
2416  if( n.fVerbose >= 4 )
2417  {
2418  os << "The current state of G4ITNavigator2 is: " << G4endl;
2419  os << " ValidExitNormal= " << n.fValidExitNormal << G4endl
2420  << " ExitNormal = " << n.fExitNormal << G4endl
2421  << " Exiting = " << n.fExiting << G4endl
2422  << " Entering = " << n.fEntering << G4endl
2423  << " BlockedPhysicalVolume= " ;
2424 
2425  if (n.fBlockedPhysicalVolume==0)
2426  {
2427  os << "None";
2428  }
2429  else
2430  {
2431  os << n.fBlockedPhysicalVolume->GetName();
2432  }
2433 
2434  os << G4endl
2435  << " BlockedReplicaNo = " << n.fBlockedReplicaNo << G4endl
2436  << " LastStepWasZero = " << n.fLastStepWasZero << G4endl
2437  << G4endl;
2438  }
2439  if( ( 1 < n.fVerbose) && (n.fVerbose < 4) )
2440  {
2441  os << G4endl; // Make sure to line up
2442  os << std::setw(30) << " ExitNormal " << " "
2443  << std::setw( 5) << " Valid " << " "
2444  << std::setw( 9) << " Exiting " << " "
2445  << std::setw( 9) << " Entering" << " "
2446  << std::setw(15) << " Blocked:Volume " << " "
2447  << std::setw( 9) << " ReplicaNo" << " "
2448  << std::setw( 8) << " LastStepZero " << " "
2449  << G4endl;
2450  os << "( " << std::setw(7) << n.fExitNormal.x()
2451  << ", " << std::setw(7) << n.fExitNormal.y()
2452  << ", " << std::setw(7) << n.fExitNormal.z() << " ) "
2453  << std::setw( 5) << n.fValidExitNormal << " "
2454  << std::setw( 9) << n.fExiting << " "
2455  << std::setw( 9) << n.fEntering << " ";
2456 
2457  if ( n.fBlockedPhysicalVolume==0 )
2458  { os << std::setw(15) << "None"; }
2459  else
2460  { os << std::setw(15)<< n.fBlockedPhysicalVolume->GetName(); }
2461 
2462  os << std::setw( 9) << n.fBlockedReplicaNo << " "
2463  << std::setw( 8) << n.fLastStepWasZero << " "
2464  << G4endl;
2465  }
2466  if( n.fVerbose > 2 )
2467  {
2468  os.precision(8);
2469  os << " Current Localpoint = " << n.fLastLocatedPointLocal << G4endl;
2470  os << " PreviousSftOrigin = " << n.fPreviousSftOrigin << G4endl;
2471  os << " PreviousSafety = " << n.fPreviousSafety << G4endl;
2472  }
2473  if( n.fVerbose > 3 || n.fVerbose == 0 )
2474  {
2475  os << "Current History: " << G4endl << n.fHistory;
2476  }
2477 
2478  os.precision(oldcoutPrec);
2479  return os;
2480 }
2481 
2482 //------------------------------------------------------------------------------
2483 
2484 EInside
2486 {
2487  const G4AffineTransform& transform = GetGlobalToLocalTransform();
2488  G4ThreeVector localPoint(transform.TransformPoint(globalPoint));
2489 
2490  G4VSolid* solid = fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
2491 
2492  return solid->Inside(localPoint);
2493 }
2494 
2495 //------------------------------------------------------------------------------
2496 
2498 {
2499  const G4AffineTransform& local2Global = GetLocalToGlobalTransform();
2500  G4VSolid* solid = fHistory.GetTopVolume()->GetLogicalVolume()->GetSolid();
2501 
2502  G4VoxelLimits voxelLimits; // Defaults to "infinite" limits.
2503  G4double vmin, vmax;
2504  G4AffineTransform dummy;
2505  std::vector<std::vector<double> > fExtend;
2506 
2507  solid->CalculateExtent(kXAxis,voxelLimits,dummy,vmin,vmax);
2508  fExtend[kXAxis][BoundingBox::kMin] = vmin;
2509  fExtend[kXAxis][BoundingBox::kMax] = vmax;
2510 
2511  solid->CalculateExtent(kYAxis,voxelLimits,dummy,vmin,vmax);
2512  fExtend[kYAxis][BoundingBox::kMin] = vmin;
2513  fExtend[kYAxis][BoundingBox::kMax] = vmax;
2514 
2515  solid->CalculateExtent(kZAxis,voxelLimits,dummy,vmin,vmax);
2516  fExtend[kZAxis][BoundingBox::kMin] = vmin;
2517  fExtend[kZAxis][BoundingBox::kMax] = vmax;
2518 
2519  G4ThreeVector rndmPos;
2520 
2521  while(1)
2522  {
2523  for(size_t i = 0 ; i < 3 ; ++i)
2524  {
2525  double min = fExtend[i][BoundingBox::kMin];
2526  double max = fExtend[i][BoundingBox::kMax];
2527  rndmPos[i] = G4UniformRand()*(max-min)+min;
2528  }
2529 
2530  if(solid->Inside(rndmPos) == kInside) break;
2531  }
2532 
2533  _rndmPoint = local2Global.TransformPoint(rndmPos);
2534 }
2535 
G4String GetName() const
static constexpr double perMillion
Definition: G4SIunits.hh:334
#define fBlockedPhysicalVolume
G4SmartVoxelHeader * GetVoxelHeader() const
#define fValidExitNormal
virtual G4bool CalculateExtent(const EAxis pAxis, const G4VoxelLimits &pVoxelLimit, const G4AffineTransform &pTransform, G4double &pMin, G4double &pMax) const =0
G4ITNavigatorState_Lock2 * GetNavigatorState()
virtual G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
#define fLastStepEndPointLocal
static constexpr double mm
Definition: G4SIunits.hh:115
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)
static const G4double kInfinity
Definition: geomdefs.hh:42
virtual G4bool IsNested() const
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
#define fExiting
virtual void SetupHierarchy()
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void UpdateMaterial(G4Material *pMaterial)
CLHEP::Hep3Vector G4ThreeVector
#define fLocatedOnEdge
double dot(const Hep3Vector &) const
virtual void ComputeDimensions(G4VPVParameterisation *p, const G4int n, const G4VPhysicalVolume *pRep)
Definition: G4VSolid.cc:138
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
const char * p
Definition: xmltok.h:285
void CheckNavigatorState() const
G4VoxelSafety * fpVoxelSafety
G4double GetSurfaceTolerance() const
void ResetNavigatorState()
void ResetStackAndState()
G4VSolid * GetSolid() const
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4VPhysicalVolume &currentPhysical, G4double maxLength=DBL_MAX)
G4TouchableHistory * CreateTouchableHistory() const
G4VPhysicalVolume * fTopPhysical
G4double CheckNextStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
#define fLastTriedStepComputation
void SetSolid(G4VSolid *pSolid)
G4NavigatorState * fpNavigatorState
G4SmartVoxelNode * ParamVoxelLocate(G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
const G4RotationMatrix * GetRotation() 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)
virtual G4GeometryType GetEntityType() const =0
#define fWasLimitedByGeometry
#define G4ThreadLocal
Definition: tls.hh:89
G4VPhysicalVolume * NewNavigatorStateAndLocate(const G4ThreeVector &p, const G4ThreeVector &direction)
#define fExitNormalGlobalFrame
virtual ~G4ITNavigator2()
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
#define fExitNormal
#define fPushed
#define fLastStepWasZero
G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4NavigationHistory &history, const G4double pMaxLength=DBL_MAX)
static double normal(HepRandomEngine *eptr)
Definition: RandPoisson.cc:77
G4ThreeVector ComputeLocalAxis(const G4ThreeVector &pVec) const
void SetNormalNavigation(G4NormalNavigation *fnormnav)
void GetRandomInCurrentVolume(G4ThreeVector &rndmPoint) const
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
#define G4UniformRand()
Definition: Randomize.hh:97
G4GLOB_DLL std::ostream G4cout
const G4String & GetName() const
virtual EInside Inside(const G4ThreeVector &p) const =0
#define fEnteredDaughter
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)
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
#define fEntering
bool G4bool
Definition: G4Types.hh:79
virtual G4int GetRegularStructureId() const =0
virtual G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=0, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
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
#define fChangedGrandMotherRefFrame
G4RegularNavigation fregularNav
G4NormalNavigation fnormalNav
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
EVolume CharacteriseDaughters() const
virtual G4double DistanceToIn(const G4ThreeVector &p, const G4ThreeVector &v) const =0
#define fCalculatedExitNormal
EVolume VolumeType(const G4VPhysicalVolume *pVol) const
G4ReplicaNavigation freplicaNav
G4double kCarTolerance
static constexpr double perMillion
#define G4DEBUG_NAVIGATION
const G4int n
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
#define CheckNavigatorStateIsValid()
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41
#define fStepEndPoint
const G4ThreeVector & GetTranslation() const
G4ParameterisedNavigation fparamNav
#define fHistory
virtual G4bool RecheckDistanceToCurrentBoundary(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double CurrentProposedStepLength, G4double *prDistance, G4double *prNewSafety=0) const
#define fGrandMotherExitNormal
#define fBlockedReplicaNo
EInside InsideCurrentVolume(const G4ThreeVector &globalPoint) const
G4ThreeVector TransformPoint(const G4ThreeVector &vec) const
void PrintState() 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)
G4LogicalVolume * GetLogicalVolume() const
G4ThreeVector ComputeLocalPoint(const G4ThreeVector &rGlobPoint) const
G4VoxelNavigation fvoxelNav
#define fPreviousSftOrigin
T max(const T t1, const T t2)
brief Return the largest of the two arguments
EInside
Definition: geomdefs.hh:58
virtual G4ThreeVector GetLocalExitNormal(G4bool *valid)
Hep3Vector unit() const
virtual void ComputeTransformation(const G4int, G4VPhysicalVolume *) const =0
#define fPreviousSafety
G4ThreeVector TransformAxis(const G4ThreeVector &axis) const
void SetNavigatorState(G4ITNavigatorState_Lock2 *)
virtual G4int GetCopyNo() const =0
const G4AffineTransform & GetGlobalToLocalTransform() const
std::ostream & operator<<(std::ostream &, const BasicVector3D< float > &)
G4int GetDaughtersRegularStructureId(const G4LogicalVolume *pLog) const
T min(const T t1, const T t2)
brief Return the smallest of the two arguments
double mag2() const
Definition: Step.hh:41
G4SmartVoxelNode * VoxelLocate(G4SmartVoxelHeader *pHead, const G4ThreeVector &localPoint)
#define fExitedMother
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
G4int GetVerboseLevel() const
G4bool EnteredDaughterVolume() const
G4double ComputeSafety(const G4ThreeVector &localPoint, const G4NavigationHistory &history, const G4double pProposedMaxLength=DBL_MAX)
#define G4endl
Definition: G4ios.hh:61
#define fLocatedOutsideWorld
virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &point, G4bool *valid)
const G4NavigationHistory * GetHistory() const
T sqr(const T &x)
Definition: templates.hh:145
virtual void ResetState()
EVolume
Definition: geomdefs.hh:69
G4int MoveUpHistory(G4int num_levels=1)
const G4String & GetName() const
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
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)
#define fLastLocatedPointLocal
double G4double
Definition: G4Types.hh:76
G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
void NewNavigatorState()
virtual G4double DistanceToOut(const G4ThreeVector &p, const G4ThreeVector &v, const G4bool calcNorm=false, G4bool *validNorm=0, G4ThreeVector *n=0) const =0
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)
void SetVerboseLevel(G4int level)
EInside BackLocate(G4NavigationHistory &history, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint, const G4bool &exiting, G4bool &notKnownInside) const
double mag() const
#define DBL_MAX
Definition: templates.hh:83
const G4AffineTransform GetLocalToGlobalTransform() const
virtual G4bool CheckOverlaps(G4int res=1000, G4double tol=0., G4bool verbose=true, G4int errMax=1)
static G4GeometryTolerance * GetInstance()
#define fNumberZeroSteps
virtual G4TouchableHistoryHandle CreateTouchableHistoryHandle() const
G4GLOB_DLL std::ostream G4cerr
EVolume CharacteriseDaughters(const G4LogicalVolume *pLog) const
G4AffineTransform GetMotherToDaughterTransform(G4VPhysicalVolume *dVolume, G4int dReplicaNo, EVolume dVolumeType)