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