Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4MultiNavigator.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// class G4MultiNavigator Implementation
27//
28// Author: John Apostolakis, November 2006
29// --------------------------------------------------------------------
30
31#include <iomanip>
32
33#include "G4MultiNavigator.hh"
34
35class G4FieldManager;
36
37#include "G4SystemOfUnits.hh"
38#include "G4Navigator.hh"
41
42// ********************************************************************
43// Constructor
44// ********************************************************************
45//
47 : G4Navigator()
48{
49 G4ThreeVector Big3Vector( kInfinity, kInfinity, kInfinity );
50 fLastLocatedPosition = Big3Vector;
51 fSafetyLocation = Big3Vector;
52 fPreStepLocation = Big3Vector;
53
54 for(auto num=0; num< fMaxNav; ++num )
55 {
56 fpNavigator[num] = nullptr;
57 fLimitTruth[num] = false;
59 fCurrentStepSize[num] = fNewSafety[num] = -1.0;
60 fLocatedVolume[num] = nullptr;
61 }
62
64
65 G4Navigator* massNav= pTransportManager->GetNavigatorForTracking();
66 if( massNav )
67 {
68 G4VPhysicalVolume* pWorld= massNav->GetWorldVolume();
69 if( pWorld )
70 {
71 SetWorldVolume( pWorld );
72 fLastMassWorld = pWorld;
73 }
74 }
75}
76
78{
79}
80
82 const G4ThreeVector& pDirection,
83 const G4double proposedStepLength,
84 G4double& pNewSafety)
85{
86 G4double safety= 0.0, step=0.0;
87 G4double minSafety= kInfinity, minStep= kInfinity;
88
89 fNoLimitingStep= -1;
90 fIdNavLimiting= -1; // Reset for new step
91
92#ifdef G4DEBUG_NAVIGATION
93 if( fVerbose > 2 )
94 {
95 G4cout << " G4MultiNavigator::ComputeStep : entered " << G4endl;
96 G4cout << " Input position= " << pGlobalPoint
97 << " direction= " << pDirection << G4endl;
98 G4cout << " Requested step= " << proposedStepLength << G4endl;
99 }
100#endif
101
102 std::vector<G4Navigator*>::iterator pNavigatorIter;
103
104 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
105
106 G4ThreeVector initialPosition = pGlobalPoint;
107 G4ThreeVector initialDirection= pDirection;
108
109 for( auto num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
110 {
111 safety= kInfinity;
112
113 step= (*pNavigatorIter)->ComputeStep( initialPosition,
114 initialDirection,
115 proposedStepLength,
116 safety );
117 if( safety < minSafety ){ minSafety = safety; }
118 if( step < minStep ) { minStep= step; }
119
120 fCurrentStepSize[num] = step;
121 fNewSafety[num]= safety;
122 // This is currently the safety from the last sub-step
123
124#ifdef G4DEBUG_NAVIGATION
125 if( fVerbose > 2 )
126 {
127 G4cout << "G4MultiNavigator::ComputeStep : Navigator ["
128 << num << "] -- step size " << step
129 << " safety= " << safety << G4endl;
130 }
131#endif
132 }
133
134 // Save safety value, related position
135 //
136 fPreStepLocation = initialPosition;
137 fMinSafety_PreStepPt = minSafety;
138 fMinStep = minStep;
139
140 if( fMinStep == kInfinity )
141 {
142 fTrueMinStep = proposedStepLength; // Use this below for endpoint !!
143 }
144 else
145 {
146 fTrueMinStep = minStep;
147 }
148
149#ifdef G4DEBUG_NAVIGATION
150 if( fVerbose > 1 )
151 {
152 G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
153
154 G4int oldPrec = G4cout.precision(8);
155 G4cout << "G4MultiNavigator::ComputeStep : "
156 << " initialPosition = " << initialPosition
157 << " and endPosition = " << endPosition << G4endl;
158 G4cout.precision( oldPrec );
159 }
160#endif
161
162 pNewSafety = minSafety;
163
164 this->WhichLimited();
165
166#ifdef G4DEBUG_NAVIGATION
167 if( fVerbose > 2 )
168 {
169 G4cout << " G4MultiNavigator::ComputeStep : exits returning "
170 << minStep << G4endl;
171 }
172#endif
173
174 return minStep; // must return kInfinity if do not limit step
175}
176
177// ----------------------------------------------------------------------
178
181 G4double& pNewSafety, // for this geometry
182 G4double& minStep,
183 ELimited& limitedStep)
184{
185 if( navigatorId > fNoActiveNavigators )
186 {
187 std::ostringstream message;
188 message << "Bad Navigator Id!" << G4endl
189 << " Navigator Id = " << navigatorId
190 << " No Active = " << fNoActiveNavigators << ".";
191 G4Exception("G4MultiNavigator::ObtainFinalStep()", "GeomNav0002",
192 FatalException, message);
193 }
194
195 // Prepare the information to return
196 //
197 pNewSafety = fNewSafety[ navigatorId ];
198 limitedStep = fLimitedStep[ navigatorId ];
199 minStep= fMinStep;
200
201#ifdef G4DEBUG_NAVIGATION
202 if( fVerbose > 1 )
203 {
204 G4cout << " G4MultiNavigator::ComputeStep returns "
205 << fCurrentStepSize[ navigatorId ]
206 << " for Navigator " << navigatorId
207 << " Limited step = " << limitedStep
208 << " Safety(mm) = " << pNewSafety / mm << G4endl;
209 }
210#endif
211
212 return fCurrentStepSize[ navigatorId ];
213}
214
215// ----------------------------------------------------------------------
216
218 const G4ThreeVector direction )
219{
220#ifdef G4DEBUG_NAVIGATION
221 if( fVerbose > 1 )
222 {
223 G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl;
224 }
225#endif
226
228
229 LocateGlobalPointAndSetup( position, &direction, false, false );
230 //
231 // The first location for each Navigator must be non-relative
232 // or else call ResetStackAndState() for each Navigator
233 // Use direction to get correct side of boundary (ignore dir= false)
234}
235
236// ----------------------------------------------------------------------
237
239{
240 // Key purposes:
241 // - Check and cache set of active navigators
242 // - Reset state for new track
243
244#ifdef G4DEBUG_NAVIGATION
245 if( fVerbose > 1 )
246 {
247 G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl;
248 }
249#endif
250
251 // Message the transportation-manager to find active navigators
252
253 std::vector<G4Navigator*>::iterator pNavigatorIter;
254 fNoActiveNavigators= pTransportManager-> GetNoActiveNavigators();
255
256 if( fNoActiveNavigators > fMaxNav )
257 {
258 std::ostringstream message;
259 message << "Too many active Navigators / worlds !" << G4endl
260 << " Active Navigators (worlds): "
261 << fNoActiveNavigators << G4endl
262 << " which is more than the number allowed: "
263 << fMaxNav << " !";
264 G4Exception("G4MultiNavigator::PrepareNavigators()", "GeomNav0002",
265 FatalException, message);
266 }
267
268 pNavigatorIter= pTransportManager->GetActiveNavigatorsIterator();
269 for( auto num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
270 {
271 fpNavigator[num] = *pNavigatorIter;
272 fLimitTruth[num] = false;
273 fLimitedStep[num] = kDoNot;
274 fCurrentStepSize[num] = 0.0;
275 fLocatedVolume[num] = nullptr;
276 }
277 fWasLimitedByGeometry = false;
278
279 // Check the world volume of the mass navigator
280 // in case a call to SetWorldVolume() changed it
281
282 G4VPhysicalVolume* massWorld = GetWorldVolume();
283
284 if( (massWorld != fLastMassWorld) && (massWorld!=0) )
285 {
286 // Pass along change to Mass Navigator
287 fpNavigator[0] -> SetWorldVolume( massWorld );
288
289#ifdef G4DEBUG_NAVIGATION
290 if( fVerbose > 0 )
291 {
292 G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume "
293 << " for mass geometry to " << massWorld->GetName() << G4endl;
294 }
295#endif
296
297 fLastMassWorld = massWorld;
298 }
299}
300
301// ----------------------------------------------------------------------
302
305 const G4ThreeVector* pDirection,
306 const G4bool pRelativeSearch,
307 const G4bool ignoreDirection )
308{
309 // Locate the point in each geometry
310
311 G4ThreeVector direction(0.0, 0.0, 0.0);
312 G4bool relative = pRelativeSearch;
313 std::vector<G4Navigator*>::iterator pNavIter
314 = pTransportManager->GetActiveNavigatorsIterator();
315
316 if( pDirection ) { direction = *pDirection; }
317
318#ifdef G4DEBUG_NAVIGATION
319 if( fVerbose > 2 )
320 {
321 G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
322 << G4endl;
323 G4cout << " Locating at position: " << position
324 << ", with direction: " << direction << G4endl
325 << " Relative: " << relative
326 << ", ignore direction: " << ignoreDirection << G4endl;
327 G4cout << " Number of active navigators: " << fNoActiveNavigators
328 << G4endl;
329 }
330#endif
331
332 for ( auto num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
333 {
335 {
336 (*pNavIter)->SetGeometricallyLimitedStep();
337 }
338
339 G4VPhysicalVolume *pLocated
340 = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
341 relative, ignoreDirection );
342 // Set the state related to the location
343 //
344 fLocatedVolume[num] = pLocated;
345
346 // Clear state related to the step
347 //
348 fLimitedStep[num] = kDoNot;
349 fCurrentStepSize[num] = 0.0;
350 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
351
352#ifdef G4DEBUG_NAVIGATION
353 if( fVerbose > 2 )
354 {
355 G4cout << " Located in world: " << num << ", at: " << position << G4endl
356 << " Used geomLimStp: " << fLimitTruth[num]
357 << ", found in volume: " << pLocated << G4endl;
358 G4cout << " Name = '" ;
359 if( pLocated )
360 {
361 G4cout << pLocated->GetName() << "'";
362 G4cout << " - CopyNo= " << pLocated->GetCopyNo();
363 }
364 else
365 {
366 G4cout << "Null' Id: Not-Set ";
367 }
368 G4cout << G4endl;
369 }
370#endif
371 }
372
373 fWasLimitedByGeometry = false; // Clear on locating
374 G4VPhysicalVolume* volMassLocated = fLocatedVolume[0];
375
376 return volMassLocated;
377}
378
379// ----------------------------------------------------------------------
380
381void
383{
384 // Relocate the point in each geometry
385
386 std::vector<G4Navigator*>::iterator pNavIter
387 = pTransportManager->GetActiveNavigatorsIterator();
388
389#ifdef G4DEBUG_NAVIGATION
390 if( fVerbose > 2 )
391 {
392 G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl
393 << " Re-locating at position: " << position << G4endl;
394 }
395#endif
396
397 for ( auto num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
398 {
399 // ... none limited the step
400
401 (*pNavIter)->LocateGlobalPointWithinVolume( position );
402
403 // Clear state related to the step
404 //
405 fLimitedStep[num] = kDoNot;
406 fCurrentStepSize[num] = 0.0;
407
408 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
409 }
410 fWasLimitedByGeometry = false; // Clear on locating
412}
413
414// ----------------------------------------------------------------------
415
417 const G4double maxDistance,
418 const G4bool state)
419{
420 // Recompute safety for the relevant point
421
422 G4double minSafety = kInfinity, safety = kInfinity;
423
424 std::vector<G4Navigator*>::iterator pNavigatorIter;
425 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
426
427 for( auto num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
428 {
429 safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
430 if( safety < minSafety ) { minSafety = safety; }
431 }
432
434 fMinSafety_atSafLocation = minSafety;
435
436#ifdef G4DEBUG_NAVIGATION
437 if( fVerbose > 1 )
438 {
439 G4cout << " G4MultiNavigator::ComputeSafety - returns: "
440 << minSafety << ", at location: " << position << G4endl;
441 }
442#endif
443 return minSafety;
444}
445
446// -----------------------------------------------------------------------
447
450{
451 G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()",
452 "GeomNav0001", FatalException,
453 "Getting a touchable from G4MultiNavigator is not defined.");
454
455 G4TouchableHistory* touchHist;
456 touchHist= fpNavigator[0] -> CreateTouchableHistory();
457
458 G4VPhysicalVolume* locatedVolume= fLocatedVolume[0];
459 if( locatedVolume == nullptr )
460 {
461 // Workaround to ensure that the touchable is fixed !! // TODO: fix
462 //
463 touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
464 }
465
466 return G4TouchableHistoryHandle(touchHist);
467}
468
469// -----------------------------------------------------------------------
470
472{
473 // Flag which processes limited the step
474
475 G4int last=-1;
476 const G4int IdTransport= 0; // Id of Mass Navigator !!
477 G4int noLimited=0;
478 ELimited shared= kSharedOther;
479
480#ifdef G4DEBUG_NAVIGATION
481 if( fVerbose > 2 )
482 {
483 G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl;
484 }
485#endif
486
487 // Assume that [IdTransport] is Mass / Transport
488 //
489 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
490 && ( fMinStep!= kInfinity);
491 if( transportLimited )
492 {
493 shared = kSharedTransport;
494 }
495
496 for ( auto num = 0; num < fNoActiveNavigators; ++num )
497 {
498 G4bool limitedStep;
499
500 G4double step = fCurrentStepSize[num];
501
502 limitedStep = ( step == fMinStep ) && ( step != kInfinity);
503
504 fLimitTruth[ num ] = limitedStep;
505 if( limitedStep )
506 {
507 ++noLimited;
508 fLimitedStep[num] = shared;
509 last= num;
510 }
511 else
512 {
513 fLimitedStep[num] = kDoNot;
514 }
515 }
516 if( (last > -1) && (noLimited == 1 ) )
517 {
518 fLimitedStep[ last ] = kUnique;
519 fIdNavLimiting = last;
520 }
521
522 fNoLimitingStep = noLimited;
523
524 return;
525}
526
527// -----------------------------------------------------------------------
528
529void
531{
532 // Report results -- for checking
533
534 static const G4String StrDoNot("DoNot"), StrUnique("Unique"),
535 StrUndefined("Undefined"),
536 StrSharedTransport("SharedTransport"),
537 StrSharedOther("SharedOther");
538 G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl;
539 G4cout << " Minimum step (true): " << fTrueMinStep
540 << ", reported min: " << fMinStep << G4endl;
541
542#ifdef G4DEBUG_NAVIGATION
543 if(fVerbose>=2)
544 {
545 G4cout << std::setw(5) << " NavId" << " "
546 << std::setw(12) << " step-size " << " "
547 << std::setw(12) << " raw-size " << " "
548 << std::setw(12) << " pre-safety " << " "
549 << std::setw(15) << " Limited / flag" << " "
550 << std::setw(15) << " World " << " "
551 << G4endl;
552 }
553#endif
554
555 for ( auto num = 0; num < fNoActiveNavigators; ++num )
556 {
557 G4double rawStep = fCurrentStepSize[num];
558 G4double stepLen = fCurrentStepSize[num];
559 if( stepLen > fTrueMinStep )
560 {
561 stepLen = fTrueMinStep; // did not limit (went as far as asked)
562 }
563 G4int oldPrec = G4cout.precision(9);
564
565 G4cout << std::setw(5) << num << " "
566 << std::setw(12) << stepLen << " "
567 << std::setw(12) << rawStep << " "
568 << std::setw(12) << fNewSafety[num] << " "
569 << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
570 G4String limitedStr;
571 switch ( fLimitedStep[num] )
572 {
573 case kDoNot : limitedStr = StrDoNot; break;
574 case kUnique : limitedStr = StrUnique; break;
575 case kSharedTransport: limitedStr = StrSharedTransport; break;
576 case kSharedOther : limitedStr = StrSharedOther; break;
577 default : limitedStr = StrUndefined; break;
578 }
579 G4cout << " " << std::setw(15) << limitedStr << " ";
580 G4cout.precision(oldPrec);
581
582 G4Navigator *pNav = fpNavigator[ num ];
583 G4String WorldName( "Not-Set" );
584 if (pNav != nullptr)
585 {
586 G4VPhysicalVolume *pWorld = pNav->GetWorldVolume();
587 if( pWorld )
588 {
589 WorldName = pWorld->GetName();
590 }
591 }
592 G4cout << " " << WorldName ;
593 G4cout << G4endl;
594 }
595}
596
597
598// -----------------------------------------------------------------------
599
601{
602 fWasLimitedByGeometry = false;
603
604 G4Exception("G4MultiNavigator::ResetState()", "GeomNav0001",
606 "Cannot reset state for navigators of G4MultiNavigator.");
607/*
608 std::vector<G4Navigator*>::iterator pNavigatorIter;
609 pNavigatorIter = pTransportManager->GetActiveNavigatorsIterator();
610 for( auto num = 0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
611 {
612 // (*pNavigatorIter)->ResetState(); // KEEP THIS comment !!!
613 }
614*/
615}
616
617// -----------------------------------------------------------------------
618
620{
621 G4Exception( "G4MultiNavigator::SetupHierarchy()",
622 "GeomNav0001", FatalException,
623 "Cannot setup hierarchy for navigators of G4MultiNavigator.");
624}
625
626// -----------------------------------------------------------------------
627
629{
630 G4VPhysicalVolume* navTrackWorld =
631 pTransportManager->GetNavigatorForTracking()->GetWorldVolume();
632
633 if( navTrackWorld != fLastMassWorld )
634 {
635 G4Exception( "G4MultiNavigator::CheckMassWorld()",
636 "GeomNav0003", FatalException,
637 "Mass world pointer has been changed." );
638 }
639}
640
641// -----------------------------------------------------------------------
642
645 const G4ThreeVector& direction,
646 const G4TouchableHistory& MassHistory)
647{
648 // Reset geometry for all -- and use the touchable for the mass history
649
650 G4VPhysicalVolume* massVolume = nullptr;
651 G4Navigator* pMassNavigator = fpNavigator[0];
652
653 if( pMassNavigator != nullptr )
654 {
655 massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction,
656 MassHistory);
657 }
658 else
659 {
660 G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()",
661 "GeomNav0002", FatalException,
662 "Cannot reset hierarchy before navigators are initialised.");
663 }
664
665 std::vector<G4Navigator*>::iterator pNavIter=
666 pTransportManager->GetActiveNavigatorsIterator();
667
668 for ( auto num = 0; num < fNoActiveNavigators ; ++pNavIter,++num )
669 {
670 G4bool relativeSearch, ignoreDirection;
671
672 (*pNavIter)-> LocateGlobalPointAndSetup( point,
673 &direction,
674 relativeSearch=false,
675 ignoreDirection=false);
676 }
677 return massVolume;
678}
679
680// -----------------------------------------------------------------------
681
684 G4bool* argpObtained) // obtained valid
685{
686 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
687 G4bool isObtained = false;
688 // These default values will be used if fNoLimitingStep== 0
689 G4int firstNavigatorId = -1;
690 G4bool oneObtained = false;
691
692 if( fNoLimitingStep == 1 )
693 {
694 // Only message the Navigator which limited the step!
695 normalGlobalCrd = fpNavigator[ fIdNavLimiting ]
696 ->GetGlobalExitNormal( argPoint, &isObtained );
697 *argpObtained = isObtained;
698 }
699 else
700 {
701 if( fNoLimitingStep > 1 )
702 {
703 std::vector<G4Navigator*>::iterator pNavIter=
704 pTransportManager->GetActiveNavigatorsIterator();
705
706 for ( auto num = 0; num < fNoActiveNavigators ; ++pNavIter, ++num )
707 {
708 G4ThreeVector oneNormal;
709 if( fLimitTruth[ num ] ) // Did this geometry limit the step ?
710 {
711 G4ThreeVector newNormal =
712 (*pNavIter)->GetGlobalExitNormal( argPoint, &oneObtained );
713 if( oneObtained )
714 {
715 // Keep first one - only if it is valid (ie not null)
716 if( !isObtained && (newNormal.mag2() != 0.0) )
717 {
718 normalGlobalCrd = newNormal;
719 isObtained = oneObtained;
720 firstNavigatorId = num;
721 }
722 else
723 {
724 // Check for clash
725 G4double dotNewPrevious = newNormal.dot( normalGlobalCrd );
726 G4double productMagSq = normalGlobalCrd.mag2()*newNormal.mag2();
727 if( productMagSq > 0.0 )
728 {
729 G4double productMag = std::sqrt( productMagSq );
730 dotNewPrevious /= productMag; // Normalise
731 if( dotNewPrevious < (1 - perThousand) )
732 {
733 *argpObtained = false;
734
735 if( fVerbose > 2 ) // dotNewPrevious <= 0.0 )
736 {
737 std::ostringstream message;
738 message << "Clash of Normal from different Navigators!"
739 << G4endl
740 << " Previous Navigator Id = "
741 << firstNavigatorId << G4endl
742 << " Current Navigator Id = "
743 << num << G4endl;
744 message << " Dot product of 2 normals = "
745 << dotNewPrevious << G4endl;
746 message << " Normal (previous) = "
747 << normalGlobalCrd << G4endl;
748 message << " Normal (current) = " << newNormal << G4endl;
749 G4Exception("G4MultiNavigator::GetGlobalExitNormal()",
750 "GeomNav0002", JustWarning, message);
751 }
752 }
753 else
754 {
755 // Close agreement - Do not change
756 }
757 }
758 }
759 }
760 }
761 } // end for over the Navigators
762
763 // Report if no Normal was obtained
764 if( !oneObtained )
765 {
766 std::ostringstream message;
767 message << "No Normal obtained despite having " << fNoLimitingStep
768 << " candidate Navigators limiting the step!" << G4endl;
769 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
770 JustWarning, message);
771 }
772
773 } // end if ( fNoLimiting > 1 )
774 } // end else
775
776 *argpObtained = isObtained;
777 return normalGlobalCrd;
778}
779
780// -----------------------------------------------------------------------
781
784{
785 // If it is the mass navigator, then expect
786 G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
787 G4bool isObtained = false;
788 // These default values will be used if fNoLimitingStep== 0
789
790 if( fNoLimitingStep == 1 )
791 {
792 // Only message the Navigator which limited the step!
793 normalGlobalCrd = fpNavigator[ fIdNavLimiting ]
794 ->GetLocalExitNormal( &isObtained );
795 *argpObtained = isObtained;
796
797 static G4ThreadLocal G4int numberWarnings = 0;
798 G4int noWarningsStart = 10, noModuloWarnings = 100;
799 ++numberWarnings;
800 if( (numberWarnings < noWarningsStart )
801 || (numberWarnings%noModuloWarnings == 0) )
802 {
803 std::ostringstream message;
804 message << "Cannot obtain normal in local coordinates of two or more "
805 << "coordinate systems." << G4endl;
806 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
807 JustWarning, message);
808 }
809 }
810 else
811 {
812 if( fNoLimitingStep > 1 )
813 {
814 std::ostringstream message;
815 message << "Cannot obtain normal in local coordinates of two or more "
816 << "coordinate systems." << G4endl;
817 G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
818 FatalException, message);
819 }
820 }
821
822 *argpObtained = isObtained;
823 return normalGlobalCrd;
824}
825
826// -----------------------------------------------------------------------
827
830 G4bool* obtained)
831{
832 return G4MultiNavigator::GetLocalExitNormal( obtained );
833}
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
#define fMinStep
#define fLocatedVolume
#define fTrueMinStep
#define fLimitTruth
#define fIdNavLimiting
#define fNoLimitingStep
#define fMinSafety_atSafLocation
#define fNewSafety
#define fLastLocatedPosition
#define fPreStepLocation
#define fCurrentStepSize
#define fLimitedStep
#define fSafetyLocation
#define fMinSafety_PreStepPt
ELimited
@ kDoNot
@ kUndefLimited
@ kUnique
@ kSharedOther
@ kSharedTransport
G4ReferenceCountedHandle< G4TouchableHistory > G4TouchableHistoryHandle
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
double mag2() const
double dot(const Hep3Vector &) const
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &E_Pt, G4bool *obtained)
G4double ObtainFinalStep(G4int navigatorId, G4double &pNewSafety, G4double &minStepLast, ELimited &limitedStep)
void PrepareNewTrack(const G4ThreeVector position, const G4ThreeVector direction)
G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=false)
G4double ComputeStep(const G4ThreeVector &pGlobalPoint, const G4ThreeVector &pDirection, const G4double pCurrentProposedStepLength, G4double &pNewSafety)
virtual G4ThreeVector GetLocalExitNormalAndCheck(const G4ThreeVector &E_Pt, G4bool *obtained)
void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
virtual G4ThreeVector GetLocalExitNormal(G4bool *obtained)
G4TouchableHistoryHandle CreateTouchableHistoryHandle() const
G4VPhysicalVolume * LocateGlobalPointAndSetup(const G4ThreeVector &point, const G4ThreeVector *direction=nullptr, const G4bool pRelativeSearch=true, const G4bool ignoreDirection=true)
G4TouchableHistory * CreateTouchableHistory() const
G4int fVerbose
Definition: G4Navigator.hh:389
G4bool fWasLimitedByGeometry
Definition: G4Navigator.hh:402
virtual G4ThreeVector GetGlobalExitNormal(const G4ThreeVector &point, G4bool *valid)
virtual G4ThreeVector GetLocalExitNormal(G4bool *valid)
void SetWorldVolume(G4VPhysicalVolume *pWorld)
virtual G4VPhysicalVolume * ResetHierarchyAndLocate(const G4ThreeVector &point, const G4ThreeVector &direction, const G4TouchableHistory &h)
Definition: G4Navigator.cc:96
G4VPhysicalVolume * GetWorldVolume() const
void UpdateYourself(G4VPhysicalVolume *pPhysVol, const G4NavigationHistory *history=nullptr)
const G4NavigationHistory * GetHistory() const
std::vector< G4Navigator * >::iterator GetActiveNavigatorsIterator()
static G4TransportationManager * GetTransportationManager()
G4Navigator * GetNavigatorForTracking() const
virtual G4int GetCopyNo() const =0
const G4String & GetName() const
#define G4ThreadLocal
Definition: tls.hh:77
#define position
Definition: xmlparse.cc:622