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