Geant4.10
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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;
57  fLastTriedStepComputation= false;
58 
60  // Initialises also all
61  // - exit / entry flags
62  // - flags & variables for exit normals
63  // - zero step counters
64  // - blocked volume
65 
66  fActionThreshold_NoZeroSteps = 10;
67  fAbandonThreshold_NoZeroSteps = 25;
68 
70  fregularNav.SetNormalNavigation( &fnormalNav );
71 
72  fStepEndPoint = G4ThreeVector( kInfinity, kInfinity, kInfinity );
73  fLastStepEndPointLocal = G4ThreeVector( kInfinity, kInfinity, kInfinity );
74 
75  fpVoxelSafety= new G4VoxelSafety();
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 
132  fLastTriedStepComputation= false;
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  {
173  fBlockedPhysicalVolume = fHistory.GetTopVolume();
174  fBlockedReplicaNo = fHistory.GetTopReplicaNo();
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  //
188  if ( fLocatedOnEdge && (VolumeType(fBlockedPhysicalVolume)!=kReplica ))
189  {
190  fExiting= false;
191  }
192  }
193  else
194  if ( fEntering )
195  {
196  switch (VolumeType(fBlockedPhysicalVolume))
197  {
198  case kNormal:
199  fHistory.NewLevel(fBlockedPhysicalVolume, kNormal,
200  fBlockedPhysicalVolume->GetCopyNo());
201  break;
202  case kReplica:
203  freplicaNav.ComputeTransformation(fBlockedReplicaNo,
204  fBlockedPhysicalVolume);
205  fHistory.NewLevel(fBlockedPhysicalVolume, kReplica,
206  fBlockedReplicaNo);
207  fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
208  break;
209  case kParameterised:
210  if( fBlockedPhysicalVolume->GetRegularStructureId() == 0 )
211  {
212  G4VSolid *pSolid;
213  G4VPVParameterisation *pParam;
214  G4TouchableHistory parentTouchable( fHistory );
215  pParam = fBlockedPhysicalVolume->GetParameterisation();
216  pSolid = pParam->ComputeSolid(fBlockedReplicaNo,
217  fBlockedPhysicalVolume);
218  pSolid->ComputeDimensions(pParam, fBlockedReplicaNo,
219  fBlockedPhysicalVolume);
220  pParam->ComputeTransformation(fBlockedReplicaNo,
221  fBlockedPhysicalVolume);
222  fHistory.NewLevel(fBlockedPhysicalVolume, kParameterised,
223  fBlockedReplicaNo);
224  fBlockedPhysicalVolume->SetCopyNo(fBlockedReplicaNo);
225  //
226  // Set the correct solid and material in Logical Volume
227  //
228  G4LogicalVolume *pLogical;
229  pLogical = fBlockedPhysicalVolume->GetLogicalVolume();
230  pLogical->SetSolid( pSolid );
231  pLogical->UpdateMaterial(pParam ->
232  ComputeMaterial(fBlockedReplicaNo,
233  fBlockedPhysicalVolume,
234  &parentTouchable));
235  }
236  break;
237  }
238  fEntering = false;
239  fBlockedPhysicalVolume = 0;
240  localPoint = fHistory.GetTopTransform().TransformPoint(globalPoint);
241  notKnownContained = false;
242  }
243  }
244  else
245  {
246  fBlockedPhysicalVolume = 0;
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  {
302  fBlockedPhysicalVolume = fHistory.GetTopVolume();
303  fBlockedReplicaNo = fHistory.GetTopReplicaNo();
305  fExiting = false;
306 
307  if( noLevelsExited > 1 )
308  {
309  // The first transformation was done by the sub-navigator
310  //
311  const G4RotationMatrix* mRot = fBlockedPhysicalVolume->GetRotation();
312  if( mRot )
313  {
314  fGrandMotherExitNormal *= (*mRot).inverse();
315  fChangedGrandMotherRefFrame= true;
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  {
356  fBlockedPhysicalVolume = fHistory.GetTopVolume();
357  fBlockedReplicaNo = fHistory.GetTopReplicaNo();
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  //
368  const G4RotationMatrix* mRot=fBlockedPhysicalVolume->GetRotation();
369  if( mRot )
370  {
371  fGrandMotherExitNormal *= (*mRot).inverse();
372  fChangedGrandMotherRefFrame= true;
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,
420  fBlockedPhysicalVolume,
421  fBlockedReplicaNo,
422  globalPoint,
423  pGlobalDirection,
424  considerDirection,
425  localPoint);
426  }
427  else // do not use optimised navigation
428  {
429  noResult = fnormalNav.LevelLocate(fHistory,
430  fBlockedPhysicalVolume,
431  fBlockedReplicaNo,
432  globalPoint,
433  pGlobalDirection,
434  considerDirection,
435  localPoint);
436  }
437  break;
438  case kReplica:
439  noResult = freplicaNav.LevelLocate(fHistory,
440  fBlockedPhysicalVolume,
441  fBlockedReplicaNo,
442  globalPoint,
443  pGlobalDirection,
444  considerDirection,
445  localPoint);
446  break;
447  case kParameterised:
448  if( GetDaughtersRegularStructureId(targetLogical) != 1 )
449  {
450  noResult = fparamNav.LevelLocate(fHistory,
451  fBlockedPhysicalVolume,
452  fBlockedReplicaNo,
453  globalPoint,
454  pGlobalDirection,
455  considerDirection,
456  localPoint);
457  }
458  else // Regular structure
459  {
460  noResult = fregularNav.LevelLocate(fHistory,
461  fBlockedPhysicalVolume,
462  fBlockedReplicaNo,
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  //
480  fBlockedPhysicalVolume = 0;
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 {
552  fLastLocatedPointLocal = ComputeLocalPoint(pGlobalpoint);
553  fLastTriedStepComputation= false;
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  {
581  fvoxelNav.VoxelLocate( pVoxelHeader, fLastLocatedPointLocal );
582  }
583  break;
584  case kParameterised:
585  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
586  {
587  // Resets state & returns voxel node
588  //
589  fparamNav.ParamVoxelLocate( pVoxelHeader, fLastLocatedPointLocal );
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  //
605  fBlockedPhysicalVolume = 0;
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 // ********************************************************************
620 //
622 {
623  fSaveState.sExitNormal = fExitNormal;
624  fSaveState.sValidExitNormal = fValidExitNormal;
625  fSaveState.sExiting = fExiting;
626  fSaveState.sEntering = fEntering;
627 
628  fSaveState.spBlockedPhysicalVolume = fBlockedPhysicalVolume;
629  fSaveState.sBlockedReplicaNo = fBlockedReplicaNo,
630 
631  fSaveState.sLastStepWasZero = fLastStepWasZero;
632 
633  fSaveState.sLocatedOutsideWorld = fLocatedOutsideWorld;
634  fSaveState.sLastLocatedPointLocal= fLastLocatedPointLocal;
635  fSaveState.sEnteredDaughter= fEnteredDaughter;
636  fSaveState.sExitedMother= fExitedMother;
637 
638  // Even the safety sphere - if you want to change it do it explicitly!
639  //
640  fSaveState.sPreviousSftOrigin= fPreviousSftOrigin;
641  fSaveState.sPreviousSafety= fPreviousSafety;
642 }
643 
644 // ********************************************************************
645 // RestoreSavedState
646 //
647 // Restore the state (in Compute Step), in case this is a parasitic call
648 // ********************************************************************
649 //
651 {
652  fExitNormal = fSaveState.sExitNormal;
653  fValidExitNormal = fSaveState.sValidExitNormal;
654  fExiting = fSaveState.sExiting;
655  fEntering = fSaveState.sEntering;
656 
657  fBlockedPhysicalVolume = fSaveState.spBlockedPhysicalVolume;
658  fBlockedReplicaNo = fSaveState.sBlockedReplicaNo,
659 
660  fLastStepWasZero = fSaveState.sLastStepWasZero;
661 
662  fLocatedOutsideWorld = fSaveState.sLocatedOutsideWorld;
663  fLastLocatedPointLocal= fSaveState.sLastLocatedPointLocal;
664  fEnteredDaughter= fSaveState.sEnteredDaughter;
665  fExitedMother= fSaveState.sExitedMother;
666  fSaveState.sPreviousSftOrigin= fPreviousSftOrigin;
667  fSaveState.sPreviousSafety= fPreviousSafety;
668 }
669 
670 // ********************************************************************
671 // ComputeStep
672 //
673 // Computes the next geometric Step: intersections with current
674 // mother and `daughter' volumes.
675 //
676 // NOTE:
677 //
678 // Flags on entry:
679 // --------------
680 // fValidExitNormal - Normal of exited volume is valid (convex, not a
681 // coincident boundary)
682 // fExitNormal - Surface normal of exited volume
683 // fExiting - True if have exited solid
684 //
685 // fBlockedPhysicalVolume - Ptr to exited volume (or 0)
686 // fBlockedReplicaNo - Replication no of exited volume
687 // fLastStepWasZero - True if last Step size was zero.
688 //
689 // Flags on exit:
690 // -------------
691 // fValidExitNormal - True if surface normal of exited volume is valid
692 // fExitNormal - Surface normal of exited volume rotated to mothers
693 // reference system
694 // fExiting - True if exiting mother
695 // fEntering - True if entering `daughter' volume (or replica)
696 // fBlockedPhysicalVolume - Ptr to candidate (entered) volume
697 // fBlockedReplicaNo - Replication no of candidate (entered) volume
698 // fLastStepWasZero - True if this Step size was zero.
699 // ********************************************************************
700 //
702  const G4ThreeVector &pDirection,
703  const G4double pCurrentProposedStepLength,
704  G4double &pNewSafety)
705 {
706  G4ThreeVector localDirection = ComputeLocalAxis(pDirection);
707  G4double Step = kInfinity;
708  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
709  G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
710 
711  // All state relating to exiting normals must be reset
712  //
713  fExitNormalGlobalFrame= G4ThreeVector( 0., 0., 0.);
714  // Reset value - to erase its memory
715  fChangedGrandMotherRefFrame= false;
716  // Reset - used for local exit normal
717  fGrandMotherExitNormal= G4ThreeVector( 0., 0., 0.);
718  fCalculatedExitNormal = false;
719  // Reset for new step
720 
721  static G4ThreadLocal G4int sNavCScalls=0;
722  sNavCScalls++;
723 
724  fLastTriedStepComputation= true;
725 
726 #ifdef G4VERBOSE
727  if( fVerbose > 0 )
728  {
729  G4cout << "*** G4Navigator::ComputeStep: ***" << G4endl;
730  G4cout << " Volume = " << motherPhysical->GetName()
731  << " - Proposed step length = " << pCurrentProposedStepLength
732  << G4endl;
733 #ifdef G4DEBUG_NAVIGATION
734  if( fVerbose >= 2 )
735  {
736  G4cout << " Called with the arguments: " << G4endl
737  << " Globalpoint = " << std::setw(25) << pGlobalpoint << G4endl
738  << " Direction = " << std::setw(25) << pDirection << G4endl;
739  if( fVerbose >= 4 )
740  {
741  G4cout << " ---- Upon entering : State" << G4endl;
742  PrintState();
743  }
744  }
745 #endif
746  }
747 #endif
748 
749  G4ThreeVector newLocalPoint = ComputeLocalPoint(pGlobalpoint);
750  if( newLocalPoint != fLastLocatedPointLocal )
751  {
752  // Check whether the relocation is within safety
753  //
754  G4ThreeVector oldLocalPoint = fLastLocatedPointLocal;
755  G4double moveLenSq = (newLocalPoint-oldLocalPoint).mag2();
756 
757  if ( moveLenSq >= kCarTolerance*kCarTolerance )
758  {
759 #ifdef G4VERBOSE
760  ComputeStepLog(pGlobalpoint, moveLenSq);
761 #endif
762  // Relocate the point within the same volume
763  //
764  LocateGlobalPointWithinVolume( pGlobalpoint );
765  fLastTriedStepComputation= true; // Ensure that this is set again !!
766  }
767  }
769  {
770  switch( CharacteriseDaughters(motherLogical) )
771  {
772  case kNormal:
773  if ( motherLogical->GetVoxelHeader() )
774  {
775  Step = fvoxelNav.ComputeStep(fLastLocatedPointLocal,
776  localDirection,
777  pCurrentProposedStepLength,
778  pNewSafety,
779  fHistory,
780  fValidExitNormal,
781  fExitNormal,
782  fExiting,
783  fEntering,
784  &fBlockedPhysicalVolume,
785  fBlockedReplicaNo);
786 
787  }
788  else
789  {
790  if( motherPhysical->GetRegularStructureId() == 0 )
791  {
792  Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
793  localDirection,
794  pCurrentProposedStepLength,
795  pNewSafety,
796  fHistory,
797  fValidExitNormal,
798  fExitNormal,
799  fExiting,
800  fEntering,
801  &fBlockedPhysicalVolume,
802  fBlockedReplicaNo);
803  }
804  else // Regular (non-voxelised) structure
805  {
806  LocateGlobalPointAndSetup( pGlobalpoint, &pDirection, true, true );
807  fLastTriedStepComputation= true; // Ensure that this is set again !!
808  //
809  // if physical process limits the step, the voxel will not be the
810  // one given by ComputeStepSkippingEqualMaterials() and the local
811  // point will be wrongly calculated.
812 
813  // There is a problem: when msc limits the step and the point is
814  // assigned wrongly to phantom in previous step (while it is out
815  // of the container volume). Then LocateGlobalPointAndSetup() has
816  // reset the history topvolume to world.
817  //
819  {
820  G4Exception("G4Navigator::ComputeStep()",
821  "GeomNav1001", JustWarning,
822  "Point is relocated in voxels, while it should be outside!");
823  Step = fnormalNav.ComputeStep(fLastLocatedPointLocal,
824  localDirection,
825  pCurrentProposedStepLength,
826  pNewSafety,
827  fHistory,
828  fValidExitNormal,
829  fExitNormal,
830  fExiting,
831  fEntering,
832  &fBlockedPhysicalVolume,
833  fBlockedReplicaNo);
834  }
835  else
836  {
837  Step = fregularNav.
838  ComputeStepSkippingEqualMaterials(fLastLocatedPointLocal,
839  localDirection,
840  pCurrentProposedStepLength,
841  pNewSafety,
842  fHistory,
843  fValidExitNormal,
844  fExitNormal,
845  fExiting,
846  fEntering,
847  &fBlockedPhysicalVolume,
848  fBlockedReplicaNo,
849  motherPhysical);
850  }
851  }
852  }
853  break;
854  case kParameterised:
855  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
856  {
857  Step = fparamNav.ComputeStep(fLastLocatedPointLocal,
858  localDirection,
859  pCurrentProposedStepLength,
860  pNewSafety,
861  fHistory,
862  fValidExitNormal,
863  fExitNormal,
864  fExiting,
865  fEntering,
866  &fBlockedPhysicalVolume,
867  fBlockedReplicaNo);
868  }
869  else // Regular structure
870  {
871  Step = fregularNav.ComputeStep(fLastLocatedPointLocal,
872  localDirection,
873  pCurrentProposedStepLength,
874  pNewSafety,
875  fHistory,
876  fValidExitNormal,
877  fExitNormal,
878  fExiting,
879  fEntering,
880  &fBlockedPhysicalVolume,
881  fBlockedReplicaNo);
882  }
883  break;
884  case kReplica:
885  G4Exception("G4Navigator::ComputeStep()", "GeomNav0001",
886  FatalException, "Not applicable for replicated volumes.");
887  break;
888  }
889  }
890  else
891  {
892  // In the case of a replica, it must handle the exiting
893  // edge/corner problem by itself
894  //
895  G4bool exitingReplica = fExitedMother;
896  G4bool calculatedExitNormal;
897  Step = freplicaNav.ComputeStep(pGlobalpoint,
898  pDirection,
899  fLastLocatedPointLocal,
900  localDirection,
901  pCurrentProposedStepLength,
902  pNewSafety,
903  fHistory,
904  fValidExitNormal,
905  calculatedExitNormal,
906  fExitNormal,
907  exitingReplica,
908  fEntering,
909  &fBlockedPhysicalVolume,
910  fBlockedReplicaNo);
911  fExiting= exitingReplica;
912  fCalculatedExitNormal= calculatedExitNormal;
913  }
914 
915  // Remember last safety origin & value.
916  //
917  fPreviousSftOrigin = pGlobalpoint;
918  fPreviousSafety = pNewSafety;
919 
920  // Count zero steps - one can occur due to changing momentum at a boundary
921  // - one, two (or a few) can occur at common edges between
922  // volumes
923  // - more than two is likely a problem in the geometry
924  // description or the Navigation
925 
926  // Rule of thumb: likely at an Edge if two consecutive steps are zero,
927  // because at least two candidate volumes must have been
928  // checked
929  //
930  fLocatedOnEdge = fLastStepWasZero && (Step==0.0);
931  fLastStepWasZero = (Step==0.0);
932  if (fPushed) { fPushed = fLastStepWasZero; }
933 
934  // Handle large number of consecutive zero steps
935  //
936  if ( fLastStepWasZero )
937  {
938  fNumberZeroSteps++;
939 #ifdef G4DEBUG_NAVIGATION
940  if( fNumberZeroSteps > 1 )
941  {
942  G4cout << "G4Navigator::ComputeStep(): another zero step, # "
943  << fNumberZeroSteps
944  << " at " << pGlobalpoint
945  << " in volume " << motherPhysical->GetName()
946  << " nav-comp-step calls # " << sNavCScalls
947  << G4endl;
948  }
949 #endif
950  if( fNumberZeroSteps > fActionThreshold_NoZeroSteps-1 )
951  {
952  // Act to recover this stuck track. Pushing it along direction
953  //
954  Step += 100*kCarTolerance;
955 #ifdef G4VERBOSE
956  if ((!fPushed) && (fWarnPush))
957  {
958  std::ostringstream message;
959  message << "Track stuck or not moving." << G4endl
960  << " Track stuck, not moving for "
961  << fNumberZeroSteps << " steps" << G4endl
962  << " in volume -" << motherPhysical->GetName()
963  << "- at point " << pGlobalpoint << G4endl
964  << " direction: " << pDirection << "." << G4endl
965  << " Potential geometry or navigation problem !"
966  << G4endl
967  << " Trying pushing it of " << Step << " mm ...";
968  G4Exception("G4Navigator::ComputeStep()", "GeomNav1002",
969  JustWarning, message, "Potential overlap in geometry!");
970  }
971 #endif
972  fPushed = true;
973  }
974  if( fNumberZeroSteps > fAbandonThreshold_NoZeroSteps-1 )
975  {
976  // Must kill this stuck track
977  //
978  std::ostringstream message;
979  message << "Stuck Track: potential geometry or navigation problem."
980  << G4endl
981  << " Track stuck, not moving for "
982  << fNumberZeroSteps << " steps" << G4endl
983  << " in volume -" << motherPhysical->GetName()
984  << "- at point " << pGlobalpoint << G4endl
985  << " direction: " << pDirection << ".";
986  motherPhysical->CheckOverlaps(5000, false);
987  G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
988  EventMustBeAborted, message);
989  }
990  }
991  else
992  {
993  if (!fPushed) fNumberZeroSteps = 0;
994  }
995 
996  fEnteredDaughter = fEntering; // I expect to enter a volume in this Step
997  fExitedMother = fExiting;
998 
999  fStepEndPoint = pGlobalpoint + Step * pDirection;
1000  fLastStepEndPointLocal = fLastLocatedPointLocal + Step * localDirection;
1001 
1002  if( fExiting )
1003  {
1004 #ifdef G4DEBUG_NAVIGATION
1005  if( fVerbose > 2 )
1006  {
1007  G4cout << " At G4Nav CompStep End - if(exiting) - fExiting= " << fExiting
1008  << " fValidExitNormal = " << fValidExitNormal << G4endl;
1009  G4cout << " fExitNormal= " << fExitNormal << G4endl;
1010  }
1011 #endif
1012 
1013  if(fValidExitNormal || fCalculatedExitNormal)
1014  {
1016  {
1017  // Convention: fExitNormal is in the 'grand-mother' coordinate system
1018  //
1019  fGrandMotherExitNormal= fExitNormal;
1020  fCalculatedExitNormal= true;
1021  }
1022  else
1023  {
1024  fGrandMotherExitNormal = fExitNormal;
1025  }
1026  }
1027  else
1028  {
1029  // We must calculate the normal anyway (in order to have it if requested)
1030  //
1031  G4ThreeVector finalLocalPoint =
1032  fLastLocatedPointLocal + localDirection*Step;
1033 
1035  {
1036  // Find normal in the 'mother' coordinate system
1037  //
1038  G4ThreeVector exitNormalMotherFrame=
1039  motherLogical->GetSolid()->SurfaceNormal(finalLocalPoint);
1040 
1041  // Transform it to the 'grand-mother' coordinate system
1042  //
1043  const G4RotationMatrix* mRot = motherPhysical->GetRotation();
1044  if( mRot )
1045  {
1046  fChangedGrandMotherRefFrame= true;
1047  fGrandMotherExitNormal = (*mRot).inverse() * exitNormalMotherFrame;
1048  }
1049  else
1050  {
1051  fGrandMotherExitNormal = exitNormalMotherFrame;
1052  }
1053 
1054  // Do not set fValidExitNormal -- this signifies
1055  // that the solid is convex!
1056  //
1057  fCalculatedExitNormal= true;
1058  }
1059  else
1060  {
1061  fCalculatedExitNormal = false;
1062  //
1063  // Nothing can be done at this stage currently - to solve this
1064  // Replica Navigation must have calculated the normal for this case
1065  // already.
1066  // Cases: mother is not convex, and exit is at previous replica level
1067 
1068 #ifdef G4DEBUG_NAVIGATION
1070 
1071  desc << "Problem in ComputeStep: Replica Navigation did not provide"
1072  << " valid exit Normal. " << G4endl;
1073  desc << " Do not know how calculate it in this case." << G4endl;
1074  desc << " Location = " << finalLocalPoint << G4endl;
1075  desc << " Volume name = " << motherPhysical->GetName()
1076  << " copy/replica No = " << motherPhysical->GetCopyNo() << G4endl;
1077  G4Exception("G4Navigator::ComputeStep()", "GeomNav0003",
1078  JustWarning, desc, "Normal not available for exiting.");
1079 #endif
1080  }
1081  }
1082 
1083  // Now transform it to the global reference frame !!
1084  //
1085  if( fValidExitNormal || fCalculatedExitNormal )
1086  {
1087  G4int depth= fHistory.GetDepth();
1088  if( depth > 0 )
1089  {
1090  G4AffineTransform GrandMotherToGlobalTransf =
1091  fHistory.GetTransform(depth-1).Inverse();
1092  fExitNormalGlobalFrame =
1093  GrandMotherToGlobalTransf.TransformAxis( fGrandMotherExitNormal );
1094  }
1095  else
1096  {
1097  fExitNormalGlobalFrame= fGrandMotherExitNormal;
1098  }
1099  }
1100  else
1101  {
1102  fExitNormalGlobalFrame= G4ThreeVector( 0., 0., 0.);
1103  }
1104  }
1105  fStepEndPoint= pGlobalpoint+Step*pDirection;
1106 
1107  if( (Step == pCurrentProposedStepLength) && (!fExiting) && (!fEntering) )
1108  {
1109  // This if Step is not really limited by the geometry.
1110  // The Navigator is obliged to return "infinity"
1111  //
1112  Step = kInfinity;
1113  }
1114 
1115 #ifdef G4VERBOSE
1116  if( fVerbose > 1 )
1117  {
1118  if( fVerbose >= 4 )
1119  {
1120  G4cout << " ----- Upon exiting :" << G4endl;
1121  PrintState();
1122  }
1123  G4cout << " Returned step= " << Step;
1124  if( fVerbose > 5 ) G4cout << G4endl;
1125  if( Step == kInfinity )
1126  {
1127  G4cout << " Requested step= " << pCurrentProposedStepLength ;
1128  if( fVerbose > 5) G4cout << G4endl;
1129  }
1130  G4cout << " Safety = " << pNewSafety << G4endl;
1131  }
1132 #endif
1133 
1134  return Step;
1135 }
1136 
1137 // ********************************************************************
1138 // CheckNextStep
1139 //
1140 // Compute the step without altering the navigator state
1141 // ********************************************************************
1142 //
1144  const G4ThreeVector& pDirection,
1145  const G4double pCurrentProposedStepLength,
1146  G4double& pNewSafety)
1147 {
1148  G4double step;
1149 
1150  // Save the state, for this parasitic call
1151  //
1152  SetSavedState();
1153 
1154  step = ComputeStep ( pGlobalpoint,
1155  pDirection,
1156  pCurrentProposedStepLength,
1157  pNewSafety );
1158 
1159  // If a parasitic call, then attempt to restore the key parts of the state
1160  //
1161  RestoreSavedState();
1162 
1163  return step;
1164 }
1165 
1166 // ********************************************************************
1167 // ResetState
1168 //
1169 // Resets stack and minimum of navigator state `machine'
1170 // ********************************************************************
1171 //
1173 {
1174  fWasLimitedByGeometry = false;
1175  fEntering = false;
1176  fExiting = false;
1177  fLocatedOnEdge = false;
1178  fLastStepWasZero = false;
1179  fEnteredDaughter = false;
1180  fExitedMother = false;
1181  fPushed = false;
1182 
1183  fValidExitNormal = false;
1184  fChangedGrandMotherRefFrame= false;
1185  fCalculatedExitNormal = false;
1186 
1187  fExitNormal = G4ThreeVector(0,0,0);
1188  fGrandMotherExitNormal = G4ThreeVector(0,0,0);
1189  fExitNormalGlobalFrame = G4ThreeVector(0,0,0);
1190 
1191  fPreviousSftOrigin = G4ThreeVector(0,0,0);
1192  fPreviousSafety = 0.0;
1193 
1194  fNumberZeroSteps = 0;
1195 
1196  fBlockedPhysicalVolume = 0;
1197  fBlockedReplicaNo = -1;
1198 
1199  fLastLocatedPointLocal = G4ThreeVector( kInfinity, -kInfinity, 0.0 );
1200  fLocatedOutsideWorld = false;
1201 }
1202 
1203 // ********************************************************************
1204 // SetupHierarchy
1205 //
1206 // Renavigates & resets hierarchy described by current history
1207 // o Reset volumes
1208 // o Recompute transforms and/or solids of replicated/parameterised volumes
1209 // ********************************************************************
1210 //
1212 {
1213  G4int i;
1214  const G4int cdepth = fHistory.GetDepth();
1215  G4VPhysicalVolume *current;
1216  G4VSolid *pSolid;
1217  G4VPVParameterisation *pParam;
1218 
1219  for ( i=1; i<=cdepth; i++ )
1220  {
1221  current = fHistory.GetVolume(i);
1222  switch ( fHistory.GetVolumeType(i) )
1223  {
1224  case kNormal:
1225  break;
1226  case kReplica:
1227  freplicaNav.ComputeTransformation(fHistory.GetReplicaNo(i), current);
1228  break;
1229  case kParameterised:
1230  G4int replicaNo;
1231  pParam = current->GetParameterisation();
1232  replicaNo = fHistory.GetReplicaNo(i);
1233  pSolid = pParam->ComputeSolid(replicaNo, current);
1234 
1235  // Set up dimensions & transform in solid/physical volume
1236  //
1237  pSolid->ComputeDimensions(pParam, replicaNo, current);
1238  pParam->ComputeTransformation(replicaNo, current);
1239 
1240  G4TouchableHistory touchable( fHistory );
1241  touchable.MoveUpHistory(); // move up to the parent level
1242 
1243  // Set up the correct solid and material in Logical Volume
1244  //
1245  G4LogicalVolume *pLogical = current->GetLogicalVolume();
1246  pLogical->SetSolid( pSolid );
1247  pLogical->UpdateMaterial( pParam ->
1248  ComputeMaterial(replicaNo, current, &touchable) );
1249  break;
1250  }
1251  }
1252 }
1253 
1254 // ********************************************************************
1255 // GetLocalExitNormal
1256 //
1257 // Obtains the Normal vector to a surface (in local coordinates)
1258 // pointing out of previous volume and into current volume
1259 // ********************************************************************
1260 //
1262 {
1263  G4ThreeVector ExitNormal(0.,0.,0.);
1264  G4VSolid *currentSolid=0;
1265  G4LogicalVolume *candidateLogical;
1266  if ( fLastTriedStepComputation )
1267  {
1268  // use fLastLocatedPointLocal and next candidate volume
1269  //
1270  G4ThreeVector nextSolidExitNormal(0.,0.,0.);
1271 
1272  if( fEntering && (fBlockedPhysicalVolume!=0) )
1273  {
1274  candidateLogical= fBlockedPhysicalVolume->GetLogicalVolume();
1275  if( candidateLogical )
1276  {
1277  // fLastStepEndPointLocal is in the coordinates of the mother
1278  // we need it in the daughter's coordinate system.
1279 
1280  // The following code should also work in case of Replica
1281  {
1282  // First transform fLastLocatedPointLocal to the new daughter
1283  // coordinates
1284  //
1285  G4AffineTransform MotherToDaughterTransform=
1286  GetMotherToDaughterTransform( fBlockedPhysicalVolume,
1287  fBlockedReplicaNo,
1288  VolumeType(fBlockedPhysicalVolume) );
1289  G4ThreeVector daughterPointOwnLocal=
1290  MotherToDaughterTransform.TransformPoint( fLastStepEndPointLocal );
1291 
1292  // OK if it is a parameterised volume
1293  //
1294  EInside inSideIt;
1295  G4bool onSurface;
1296  G4double safety= -1.0;
1297  currentSolid= candidateLogical->GetSolid();
1298  inSideIt = currentSolid->Inside(daughterPointOwnLocal);
1299  onSurface = (inSideIt == kSurface);
1300  if( ! onSurface )
1301  {
1302  if( inSideIt == kOutside )
1303  {
1304  safety = (currentSolid->DistanceToIn(daughterPointOwnLocal));
1305  onSurface = safety < 100.0 * kCarTolerance;
1306  }
1307  else if (inSideIt == kInside )
1308  {
1309  safety = (currentSolid->DistanceToOut(daughterPointOwnLocal));
1310  onSurface = safety < 100.0 * kCarTolerance;
1311  }
1312  }
1313 
1314  if( onSurface )
1315  {
1316  nextSolidExitNormal =
1317  currentSolid->SurfaceNormal(daughterPointOwnLocal);
1318 
1319  // Entering the solid ==> opposite
1320  //
1321  ExitNormal = -nextSolidExitNormal;
1322  fCalculatedExitNormal= true;
1323  }
1324  else
1325  {
1326 #ifdef G4VERBOSE
1327  if(( fVerbose == 1 ) && ( fCheck ))
1328  {
1329  std::ostringstream message;
1330  message << "Point not on surface ! " << G4endl
1331  << " Point = "
1332  << daughterPointOwnLocal << G4endl
1333  << " Physical volume = "
1334  << fBlockedPhysicalVolume->GetName() << G4endl
1335  << " Logical volume = "
1336  << candidateLogical->GetName() << G4endl
1337  << " Solid = " << currentSolid->GetName()
1338  << " Type = "
1339  << currentSolid->GetEntityType() << G4endl
1340  << *currentSolid << G4endl;
1341  if( inSideIt == kOutside )
1342  {
1343  message << "Point is Outside. " << G4endl
1344  << " Safety (from outside) = " << safety << G4endl;
1345  }
1346  else // if( inSideIt == kInside )
1347  {
1348  message << "Point is Inside. " << G4endl
1349  << " Safety (from inside) = " << safety << G4endl;
1350  }
1351  G4Exception("G4Navigator::GetLocalExitNormal()", "GeomNav1001",
1352  JustWarning, message);
1353  }
1354 #endif
1355  }
1356  *valid = onSurface; // was =true;
1357  }
1358  }
1359  }
1360  else if ( fExiting )
1361  {
1362  ExitNormal = fGrandMotherExitNormal;
1363  *valid = true;
1364  fCalculatedExitNormal= true; // Should be true already
1365  }
1366  else // i.e. ( fBlockedPhysicalVolume == 0 )
1367  {
1368  *valid = false;
1369  G4Exception("G4Navigator::GetLocalExitNormal()",
1370  "GeomNav0003", JustWarning,
1371  "Incorrect call to GetLocalSurfaceNormal." );
1372  }
1373  }
1374  else // ( ! fLastTriedStepComputation ) ie. last call was to Locate
1375  {
1376  if ( EnteredDaughterVolume() )
1377  {
1378  G4VSolid* daughterSolid =fHistory.GetTopVolume()->GetLogicalVolume()
1379  ->GetSolid();
1380  ExitNormal= -(daughterSolid->SurfaceNormal(fLastLocatedPointLocal));
1381  if( std::fabs(ExitNormal.mag2()-1.0 ) > CLHEP::perMillion )
1382  {
1384  desc << " Parameters of solid: " << *daughterSolid
1385  << " Point for surface = " << fLastLocatedPointLocal << std::endl;
1386  G4Exception("G4Navigator::GetLocalExitNormal()",
1387  "GeomNav0003", FatalException, desc,
1388  "Surface Normal returned by Solid is not a Unit Vector." );
1389  }
1390  fCalculatedExitNormal= true;
1391  *valid = true;
1392  }
1393  else
1394  {
1395  if( fExitedMother )
1396  {
1397  ExitNormal = fGrandMotherExitNormal;
1398  *valid = true;
1399  fCalculatedExitNormal= true;
1400  }
1401  else // We are not at a boundary. ExitNormal remains (0,0,0)
1402  {
1403  *valid = false;
1404  fCalculatedExitNormal= false;
1405  G4ExceptionDescription message;
1406  message << "Function called when *NOT* at a Boundary." << G4endl;
1407  G4Exception("G4Navigator::GetLocalExitNormal()",
1408  "GeomNav0003", JustWarning, message);
1409  }
1410  }
1411  }
1412  return ExitNormal;
1413 }
1414 
1415 // ********************************************************************
1416 // GetMotherToDaughterTransform
1417 //
1418 // Obtains the mother to daughter affine transformation
1419 // ********************************************************************
1420 //
1423  G4int enteringReplicaNo,
1424  EVolume enteringVolumeType )
1425 {
1426  switch (enteringVolumeType)
1427  {
1428  case kNormal: // Nothing is needed to prepare the transformation
1429  break; // It is stored already in the physical volume (placement)
1430  case kReplica: // Sets the transform in the Replica - tbc
1431  G4Exception("G4Navigator::GetMotherToDaughterTransform()",
1432  "GeomNav0001", FatalException,
1433  "Method NOT Implemented yet for replica volumes.");
1434  break;
1435  case kParameterised:
1436  if( pEnteringPhysVol->GetRegularStructureId() == 0 )
1437  {
1438  G4VPVParameterisation *pParam =
1439  pEnteringPhysVol->GetParameterisation();
1440  G4VSolid* pSolid =
1441  pParam->ComputeSolid(enteringReplicaNo, pEnteringPhysVol);
1442  pSolid->ComputeDimensions(pParam, enteringReplicaNo, pEnteringPhysVol);
1443 
1444  // Sets the transform in the Parameterisation
1445  //
1446  pParam->ComputeTransformation(enteringReplicaNo, pEnteringPhysVol);
1447 
1448  // Set the correct solid and material in Logical Volume
1449  //
1450  G4LogicalVolume* pLogical = pEnteringPhysVol->GetLogicalVolume();
1451  pLogical->SetSolid( pSolid );
1452  }
1453  break;
1454  }
1455  return G4AffineTransform(pEnteringPhysVol->GetRotation(),
1456  pEnteringPhysVol->GetTranslation()).Invert();
1457 }
1458 
1459 // ********************************************************************
1460 // GetLocalExitNormalAndCheck
1461 //
1462 // Obtains the Normal vector to a surface (in local coordinates)
1463 // pointing out of previous volume and into current volume, and
1464 // checks the current point against expected 'local' value.
1465 // ********************************************************************
1466 //
1469 #ifdef G4DEBUG_NAVIGATION
1470  const G4ThreeVector& ExpectedBoundaryPointGlobal,
1471 #else
1472  const G4ThreeVector&,
1473 #endif
1474  G4bool* pValid)
1475 {
1476 #ifdef G4DEBUG_NAVIGATION
1477  // Check Current point against expected 'local' value
1478  //
1479  if ( fLastTriedStepComputation )
1480  {
1481  G4ThreeVector ExpectedBoundaryPointLocal;
1482 
1483  const G4AffineTransform& GlobalToLocal= GetGlobalToLocalTransform();
1484  ExpectedBoundaryPointLocal =
1485  GlobalToLocal.TransformPoint( ExpectedBoundaryPointGlobal );
1486 
1487  // Add here: Comparison against expected position,
1488  // i.e. the endpoint of ComputeStep
1489  }
1490 #endif
1491 
1492  return GetLocalExitNormal( pValid);
1493 }
1494 
1495 // ********************************************************************
1496 // GetGlobalExitNormal
1497 //
1498 // Obtains the Normal vector to a surface (in global coordinates)
1499 // pointing out of previous volume and into current volume
1500 // ********************************************************************
1501 //
1504  G4bool* pNormalCalculated)
1505 {
1506  G4bool validNormal;
1507  G4ThreeVector localNormal, globalNormal;
1508 
1509  if( fLastTriedStepComputation && fExiting )
1510  {
1511  // This was computed in ComputeStep -- and only on arrival at boundary
1512  //
1513  globalNormal = fExitNormalGlobalFrame;
1514  *pNormalCalculated = true; // ComputeStep always computes it if Exiting
1515  // (fExiting==true)
1516  }
1517  else
1518  {
1519  localNormal = GetLocalExitNormalAndCheck(IntersectPointGlobal,&validNormal);
1520  *pNormalCalculated = fCalculatedExitNormal;
1521 
1522 #ifdef G4DEBUG_NAVIGATION
1523  if( (!validNormal) && !fCalculatedExitNormal)
1524  {
1526  edN << " Calculated = " << fCalculatedExitNormal << G4endl;
1527  edN << " Entering= " << fEntering << G4endl;
1528  G4int oldVerbose= this->GetVerboseLevel();
1529  this->SetVerboseLevel(4);
1530  edN << " State of Navigator: " << G4endl;
1531  edN << *this << G4endl;
1532  this->SetVerboseLevel( oldVerbose );
1533 
1534  G4Exception("G4Navigator::GetGlobalExitNormal()",
1535  "GeomNav0003", JustWarning, edN,
1536  "LocalExitNormalAndCheck() did not calculate Normal.");
1537  }
1538 #endif
1539 
1540  G4double localMag2= localNormal.mag2();
1541  if( validNormal && (std::fabs(localMag2-1.0)) > CLHEP::perMillion )
1542  {
1544 
1545  edN << "G4Navigator::GetGlobalExitNormal: "
1546  << " Using Local Normal - from call to GetLocalExitNormalAndCheck. "
1547  << G4endl
1548  << " Local Exit Normal = " << localNormal << " || = "
1549  << std::sqrt(localMag2) << G4endl
1550  << " Global Exit Normal = " << globalNormal << " || = "
1551  << globalNormal.mag() << G4endl;
1552  edN << " Calculated It = " << fCalculatedExitNormal << G4endl;
1553 
1554  G4Exception("G4Navigator::GetGlobalExitNormal()",
1555  "GeomNav0003",JustWarning, edN,
1556  "Value obtained from new local *solid* is incorrect.");
1557  localNormal = localNormal.unit(); // Should we correct it ??
1558  }
1559  G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1560  globalNormal = localToGlobal.TransformAxis( localNormal );
1561  }
1562 
1563 #ifdef G4DEBUG_NAVIGATION
1564  // Temporary extra checks
1565  if( fLastTriedStepComputation && fExiting)
1566  {
1567  localNormal = GetLocalExitNormalAndCheck( IntersectPointGlobal, &validNormal);
1568  *pNormalCalculated = fCalculatedExitNormal;
1569 
1570  G4AffineTransform localToGlobal = GetLocalToGlobalTransform();
1571  globalNormal = localToGlobal.TransformAxis( localNormal );
1572 
1573  // Check the value computed against fExitNormalGlobalFrame
1574  G4ThreeVector diffNorm = globalNormal - fExitNormalGlobalFrame;
1575  if( diffNorm.mag2() > perMillion*CLHEP::perMillion)
1576  {
1577  G4ExceptionDescription edDfn;
1578  edDfn << "Found difference in normals in case of exiting mother "
1579  << "- when Get is called after ComputingStep " << G4endl;
1580  edDfn << " Magnitude of diff = " << diffNorm.mag() << G4endl;
1581  edDfn << " Normal stored (Global) = " << fExitNormalGlobalFrame
1582  << G4endl;
1583  edDfn << " Global Computed from Local = " << globalNormal << G4endl;
1584  G4Exception("G4Navigator::GetGlobalExitNormal()", "GeomNav0003",
1585  JustWarning, edDfn);
1586  }
1587  }
1588 #endif
1589 
1590  return globalNormal;
1591 }
1592 
1593 // To make the new Voxel Safety the default, uncomment the next line
1594 #define G4NEW_SAFETY 1
1595 
1596 // ********************************************************************
1597 // ComputeSafety
1598 //
1599 // It assumes that it will be
1600 // i) called at the Point in the same volume as the EndPoint of the
1601 // ComputeStep.
1602 // ii) after (or at the end of) ComputeStep OR after the relocation.
1603 // ********************************************************************
1604 //
1606  const G4double pMaxLength,
1607  const G4bool keepState)
1608 {
1609  G4double newSafety = 0.0;
1610 
1611 #ifdef G4DEBUG_NAVIGATION
1612  G4int oldcoutPrec = G4cout.precision(8);
1613  if( fVerbose > 0 )
1614  {
1615  G4cout << "*** G4Navigator::ComputeSafety: ***" << G4endl
1616  << " Called at point: " << pGlobalpoint << G4endl;
1617 
1618  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
1619  G4cout << " Volume = " << motherPhysical->GetName()
1620  << " - Maximum length = " << pMaxLength << G4endl;
1621  if( fVerbose >= 4 )
1622  {
1623  G4cout << " ----- Upon entering Compute Safety:" << G4endl;
1624  PrintState();
1625  }
1626  }
1627 #endif
1628 
1629  if (keepState) { SetSavedState(); }
1630 
1631  G4double distEndpointSq = (pGlobalpoint-fStepEndPoint).mag2();
1632  G4bool stayedOnEndpoint = distEndpointSq < kCarTolerance*kCarTolerance;
1633  G4bool endpointOnSurface = fEnteredDaughter || fExitedMother;
1634 
1635  if( !(endpointOnSurface && stayedOnEndpoint) )
1636  {
1637  // Pseudo-relocate to this point (updates voxel information only)
1638  //
1639  LocateGlobalPointWithinVolume( pGlobalpoint );
1640  // --->> DANGER: Side effects on sub-navigator voxel information <<---
1641  // Could be replaced again by 'granular' calls to sub-navigator
1642  // locates (similar side-effects, but faster.
1643  // Solutions:
1644  // 1) Re-locate (to where?)
1645  // 2) Insure that the methods using (G4ComputeStep?)
1646  // does a relocation (if information is disturbed only ?)
1647 
1648 #ifdef G4DEBUG_NAVIGATION
1649  if( fVerbose >= 2 )
1650  {
1651  G4cout << " G4Navigator::ComputeSafety() relocates-in-volume to point: "
1652  << pGlobalpoint << G4endl;
1653  }
1654 #endif
1655  G4VPhysicalVolume *motherPhysical = fHistory.GetTopVolume();
1656  G4LogicalVolume *motherLogical = motherPhysical->GetLogicalVolume();
1657  G4SmartVoxelHeader* pVoxelHeader = motherLogical->GetVoxelHeader();
1658  G4ThreeVector localPoint = ComputeLocalPoint(pGlobalpoint);
1659 
1661  {
1662  switch(CharacteriseDaughters(motherLogical))
1663  {
1664  case kNormal:
1665  if ( pVoxelHeader )
1666  {
1667 #ifdef G4NEW_SAFETY
1668  G4double safetyTwo = fpVoxelSafety->ComputeSafety(localPoint,
1669  *motherPhysical, pMaxLength);
1670  newSafety= safetyTwo; // Faster and best available
1671 #else
1672  G4double safetyOldVoxel;
1673  safetyOldVoxel =
1674  fvoxelNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1675  newSafety= safetyOldVoxel;
1676 #endif
1677  }
1678  else
1679  {
1680  newSafety=fnormalNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1681  }
1682  break;
1683  case kParameterised:
1684  if( GetDaughtersRegularStructureId(motherLogical) != 1 )
1685  {
1686  newSafety=fparamNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1687  }
1688  else // Regular structure
1689  {
1690  newSafety=fregularNav.ComputeSafety(localPoint,fHistory,pMaxLength);
1691  }
1692  break;
1693  case kReplica:
1694  G4Exception("G4Navigator::ComputeSafety()", "GeomNav0001",
1695  FatalException, "Not applicable for replicated volumes.");
1696  break;
1697  }
1698  }
1699  else
1700  {
1701  newSafety = freplicaNav.ComputeSafety(pGlobalpoint, localPoint,
1702  fHistory, pMaxLength);
1703  }
1704  }
1705  else // if( endpointOnSurface && stayedOnEndpoint )
1706  {
1707 #ifdef G4DEBUG_NAVIGATION
1708  if( fVerbose >= 2 )
1709  {
1710  G4cout << " G4Navigator::ComputeSafety() finds that point - "
1711  << pGlobalpoint << " - is on surface " << G4endl;
1712  if( fEnteredDaughter ) { G4cout << " entered new daughter volume"; }
1713  if( fExitedMother ) { G4cout << " and exited previous volume."; }
1714  G4cout << G4endl;
1715  G4cout << " EndPoint was = " << fStepEndPoint << G4endl;
1716  }
1717 #endif
1718  newSafety = 0.0;
1719  }
1720 
1721  // Remember last safety origin & value
1722  //
1723  fPreviousSftOrigin = pGlobalpoint;
1724  fPreviousSafety = newSafety;
1725 
1726  if (keepState) { RestoreSavedState(); }
1727 
1728 #ifdef G4DEBUG_NAVIGATION
1729  if( fVerbose > 1 )
1730  {
1731  G4cout << " ---- Exiting ComputeSafety " << G4endl;
1732  if( fVerbose > 2 ) { PrintState(); }
1733  G4cout << " Returned value of Safety = " << newSafety << G4endl;
1734  }
1735  G4cout.precision(oldcoutPrec);
1736 #endif
1737 
1738  return newSafety;
1739 }
1740 
1741 // ********************************************************************
1742 // CreateTouchableHistoryHandle
1743 // ********************************************************************
1744 //
1746 {
1748 }
1749 
1750 // ********************************************************************
1751 // PrintState
1752 // ********************************************************************
1753 //
1755 {
1756  G4int oldcoutPrec = G4cout.precision(4);
1757  if( fVerbose == 4 )
1758  {
1759  G4cout << "The current state of G4Navigator is: " << G4endl;
1760  G4cout << " ValidExitNormal= " << fValidExitNormal << G4endl
1761  << " ExitNormal = " << fExitNormal << G4endl
1762  << " Exiting = " << fExiting << G4endl
1763  << " Entering = " << fEntering << G4endl
1764  << " BlockedPhysicalVolume= " ;
1765  if (fBlockedPhysicalVolume==0)
1766  G4cout << "None";
1767  else
1768  G4cout << fBlockedPhysicalVolume->GetName();
1769  G4cout << G4endl
1770  << " BlockedReplicaNo = " << fBlockedReplicaNo << G4endl
1771  << " LastStepWasZero = " << fLastStepWasZero << G4endl
1772  << G4endl;
1773  }
1774  if( ( 1 < fVerbose) && (fVerbose < 4) )
1775  {
1776  G4cout << G4endl; // Make sure to line up
1777  G4cout << std::setw(30) << " ExitNormal " << " "
1778  << std::setw( 5) << " Valid " << " "
1779  << std::setw( 9) << " Exiting " << " "
1780  << std::setw( 9) << " Entering" << " "
1781  << std::setw(15) << " Blocked:Volume " << " "
1782  << std::setw( 9) << " ReplicaNo" << " "
1783  << std::setw( 8) << " LastStepZero " << " "
1784  << G4endl;
1785  G4cout << "( " << std::setw(7) << fExitNormal.x()
1786  << ", " << std::setw(7) << fExitNormal.y()
1787  << ", " << std::setw(7) << fExitNormal.z() << " ) "
1788  << std::setw( 5) << fValidExitNormal << " "
1789  << std::setw( 9) << fExiting << " "
1790  << std::setw( 9) << fEntering << " ";
1791  if ( fBlockedPhysicalVolume==0 )
1792  G4cout << std::setw(15) << "None";
1793  else
1794  G4cout << std::setw(15)<< fBlockedPhysicalVolume->GetName();
1795  G4cout << std::setw( 9) << fBlockedReplicaNo << " "
1796  << std::setw( 8) << fLastStepWasZero << " "
1797  << G4endl;
1798  }
1799  if( fVerbose > 2 )
1800  {
1801  G4cout.precision(8);
1802  G4cout << " Current Localpoint = " << fLastLocatedPointLocal << G4endl;
1803  G4cout << " PreviousSftOrigin = " << fPreviousSftOrigin << G4endl;
1804  G4cout << " PreviousSafety = " << fPreviousSafety << G4endl;
1805  }
1806  G4cout.precision(oldcoutPrec);
1807 }
1808 
1809 // ********************************************************************
1810 // ComputeStepLog
1811 // ********************************************************************
1812 //
1813 void G4Navigator::ComputeStepLog(const G4ThreeVector& pGlobalpoint,
1814  G4double moveLenSq) const
1815 {
1816  // The following checks only make sense if the move is larger
1817  // than the tolerance.
1818 
1819  static const G4double fAccuracyForWarning = kCarTolerance,
1820  fAccuracyForException = 1000*kCarTolerance;
1821 
1822  G4ThreeVector OriginalGlobalpoint = fHistory.GetTopTransform().Inverse().
1823  TransformPoint(fLastLocatedPointLocal);
1824 
1825  G4double shiftOriginSafSq = (fPreviousSftOrigin-pGlobalpoint).mag2();
1826 
1827  // Check that the starting point of this step is
1828  // within the isotropic safety sphere of the last point
1829  // to a accuracy/precision given by fAccuracyForWarning.
1830  // If so give warning.
1831  // If it fails by more than fAccuracyForException exit with error.
1832  //
1833  if( shiftOriginSafSq >= sqr(fPreviousSafety) )
1834  {
1835  G4double shiftOrigin = std::sqrt(shiftOriginSafSq);
1836  G4double diffShiftSaf = shiftOrigin - fPreviousSafety;
1837 
1838  if( diffShiftSaf > fAccuracyForWarning )
1839  {
1840  G4int oldcoutPrec= G4cout.precision(8);
1841  G4int oldcerrPrec= G4cerr.precision(10);
1842  std::ostringstream message, suggestion;
1843  message << "Accuracy error or slightly inaccurate position shift."
1844  << G4endl
1845  << " The Step's starting point has moved "
1846  << std::sqrt(moveLenSq)/mm << " mm " << G4endl
1847  << " since the last call to a Locate method." << G4endl
1848  << " This has resulted in moving "
1849  << shiftOrigin/mm << " mm "
1850  << " from the last point at which the safety "
1851  << " was calculated " << G4endl
1852  << " which is more than the computed safety= "
1853  << fPreviousSafety/mm << " mm at that point." << G4endl
1854  << " This difference is "
1855  << diffShiftSaf/mm << " mm." << G4endl
1856  << " The tolerated accuracy is "
1857  << fAccuracyForException/mm << " mm.";
1858 
1859  suggestion << " ";
1860  static G4ThreadLocal G4int warnNow = 0;
1861  if( ((++warnNow % 100) == 1) )
1862  {
1863  message << G4endl
1864  << " This problem can be due to either " << G4endl
1865  << " - a process that has proposed a displacement"
1866  << " larger than the current safety , or" << G4endl
1867  << " - inaccuracy in the computation of the safety";
1868  suggestion << "We suggest that you " << G4endl
1869  << " - find i) what particle is being tracked, and "
1870  << " ii) through what part of your geometry " << G4endl
1871  << " for example by re-running this event with "
1872  << G4endl
1873  << " /tracking/verbose 1 " << G4endl
1874  << " - check which processes you declare for"
1875  << " this particle (and look at non-standard ones)"
1876  << G4endl
1877  << " - in case, create a detailed logfile"
1878  << " of this event using:" << G4endl
1879  << " /tracking/verbose 6 ";
1880  }
1881  G4Exception("G4Navigator::ComputeStep()",
1882  "GeomNav1002", JustWarning,
1883  message, G4String(suggestion.str()));
1884  G4cout.precision(oldcoutPrec);
1885  G4cerr.precision(oldcerrPrec);
1886  }
1887 #ifdef G4DEBUG_NAVIGATION
1888  else
1889  {
1890  G4cerr << "WARNING - G4Navigator::ComputeStep()" << G4endl
1891  << " The Step's starting point has moved "
1892  << std::sqrt(moveLenSq) << "," << G4endl
1893  << " which has taken it to the limit of"
1894  << " the current safety. " << G4endl;
1895  }
1896 #endif
1897  }
1898  G4double safetyPlus = fPreviousSafety + fAccuracyForException;
1899  if ( shiftOriginSafSq > sqr(safetyPlus) )
1900  {
1901  std::ostringstream message;
1902  message << "May lead to a crash or unreliable results." << G4endl
1903  << " Position has shifted considerably without"
1904  << " notifying the navigator !" << G4endl
1905  << " Tolerated safety: " << safetyPlus << G4endl
1906  << " Computed shift : " << shiftOriginSafSq;
1907  G4Exception("G4Navigator::ComputeStep()", "GeomNav1002",
1908  JustWarning, message);
1909  }
1910 }
1911 
1912 // ********************************************************************
1913 // Operator <<
1914 // ********************************************************************
1915 //
1916 std::ostream& operator << (std::ostream &os,const G4Navigator &n)
1917 {
1918  // Old version did only the following:
1919  // os << "Current History: " << G4endl << n.fHistory;
1920  // Old behaviour is recovered for fVerbose = 0
1921 
1922  // Adapted from G4Navigator::PrintState() const
1923 
1924  G4int oldcoutPrec = os.precision(4);
1925  if( n.fVerbose >= 4 )
1926  {
1927  os << "The current state of G4Navigator is: " << G4endl;
1928  os << " ValidExitNormal= " << n.fValidExitNormal << G4endl
1929  << " ExitNormal = " << n.fExitNormal << G4endl
1930  << " Exiting = " << n.fExiting << G4endl
1931  << " Entering = " << n.fEntering << G4endl
1932  << " BlockedPhysicalVolume= " ;
1933  if (n.fBlockedPhysicalVolume==0)
1934  os << "None";
1935  else
1936  os << n.fBlockedPhysicalVolume->GetName();
1937  os << G4endl
1938  << " BlockedReplicaNo = " << n.fBlockedReplicaNo << G4endl
1939  << " LastStepWasZero = " << n.fLastStepWasZero << G4endl
1940  << G4endl;
1941  }
1942  if( ( 1 < n.fVerbose) && (n.fVerbose < 4) )
1943  {
1944  os << G4endl; // Make sure to line up
1945  os << std::setw(30) << " ExitNormal " << " "
1946  << std::setw( 5) << " Valid " << " "
1947  << std::setw( 9) << " Exiting " << " "
1948  << std::setw( 9) << " Entering" << " "
1949  << std::setw(15) << " Blocked:Volume " << " "
1950  << std::setw( 9) << " ReplicaNo" << " "
1951  << std::setw( 8) << " LastStepZero " << " "
1952  << G4endl;
1953  os << "( " << std::setw(7) << n.fExitNormal.x()
1954  << ", " << std::setw(7) << n.fExitNormal.y()
1955  << ", " << std::setw(7) << n.fExitNormal.z() << " ) "
1956  << std::setw( 5) << n.fValidExitNormal << " "
1957  << std::setw( 9) << n.fExiting << " "
1958  << std::setw( 9) << n.fEntering << " ";
1959  if ( n.fBlockedPhysicalVolume==0 )
1960  { os << std::setw(15) << "None"; }
1961  else
1962  { os << std::setw(15)<< n.fBlockedPhysicalVolume->GetName(); }
1963  os << std::setw( 9) << n.fBlockedReplicaNo << " "
1964  << std::setw( 8) << n.fLastStepWasZero << " "
1965  << G4endl;
1966  }
1967  if( n.fVerbose > 2 )
1968  {
1969  os.precision(8);
1970  os << " Current Localpoint = " << n.fLastLocatedPointLocal << G4endl;
1971  os << " PreviousSftOrigin = " << n.fPreviousSftOrigin << G4endl;
1972  os << " PreviousSafety = " << n.fPreviousSafety << G4endl;
1973  }
1974  if( n.fVerbose > 3 || n.fVerbose == 0 )
1975  {
1976  os << "Current History: " << G4endl << n.fHistory;
1977  }
1978 
1979  os.precision(oldcoutPrec);
1980  return os;
1981 }
G4String GetName() const
G4SmartVoxelHeader * GetVoxelHeader() const
G4VPhysicalVolume * GetTopVolume() const
virtual void ResetState()
virtual G4bool LevelLocate(G4NavigationHistory &history, const G4VPhysicalVolume *blockedVol, const G4int blockedNum, const G4ThreeVector &globalPoint, const G4ThreeVector *globalDirection, const G4bool pLocatedOnEdge, G4ThreeVector &localPoint)
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)
const G4ThreeVector & GetTranslation() const
std::ostringstream G4ExceptionDescription
Definition: globals.hh:76
void UpdateMaterial(G4Material *pMaterial)
G4String GetName() const
CLHEP::Hep3Vector G4ThreeVector
double x() const
double dot(const Hep3Vector &) const
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 ComputeLocalAxis(const G4ThreeVector &pVec) const
virtual G4TouchableHistoryHandle CreateTouchableHistoryHandle() const
virtual G4VSolid * ComputeSolid(const G4int, G4VPhysicalVolume *)
const char * p
Definition: xmltok.h:285
void ResetStackAndState()
G4int GetDepth() const
G4double GetSurfaceTolerance() const
virtual G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
Definition: G4Navigator.cc:701
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)
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)
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
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
Definition: G4Navigator.cc:90
double z() const
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)
G4bool fWasLimitedByGeometry
Definition: G4Navigator.hh:367
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)
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
#define G4DEBUG_NAVIGATION
const G4int n
EVolume CharacteriseDaughters(const G4LogicalVolume *pLog) const
void SetSavedState()
Definition: G4Navigator.cc:621
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
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)
EInside
Definition: geomdefs.hh:58
Hep3Vector unit() const
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
double y() const
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
std::ostream & operator<<(std::ostream &, const BasicVector3D< float > &)
const G4RotationMatrix * GetRotation() const
double mag2() 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
G4ThreeVector fStepEndPoint
Definition: G4Navigator.hh:370
const G4NavigationHistory * GetHistory() const
T sqr(const T &x)
Definition: templates.hh:145
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)
EInside BackLocate(G4NavigationHistory &history, const G4ThreeVector &globalPoint, G4ThreeVector &localPoint, const G4bool &exiting, G4bool &notKnownInside) const
double mag() const
virtual void SetupHierarchy()
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 RestoreSavedState()
Definition: G4Navigator.cc:650
virtual ~G4Navigator()
Definition: G4Navigator.cc:82
G4GLOB_DLL std::ostream G4cerr
float perMillion
Definition: hepunit.py:241