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