source: trunk/source/geometry/navigation/src/G4MultiNavigator.cc@ 1188

Last change on this file since 1188 was 921, checked in by garnier, 17 years ago

en test de gl2ps. Problemes de libraries

File size: 21.1 KB
Line 
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: G4MultiNavigator.cc,v 1.8 2008/10/24 14:00:03 gcosmo Exp $
28// GEANT4 tag $ Name: $
29//
30// class G4PathFinder Implementation
31//
32// Author: John Apostolakis, November 2006
33// --------------------------------------------------------------------
34
35#include "G4MultiNavigator.hh"
36
37class G4FieldManager;
38
39#include "G4Navigator.hh"
40#include "G4PropagatorInField.hh"
41#include "G4TransportationManager.hh"
42
43#include <iomanip>
44
45// ********************************************************************
46// Constructor
47// ********************************************************************
48//
49G4MultiNavigator::G4MultiNavigator()
50 : G4Navigator()
51{
52 fNoActiveNavigators= 0;
53 G4ThreeVector Big3Vector( DBL_MAX, DBL_MAX, DBL_MAX );
54 fLastLocatedPosition = Big3Vector;
55 fSafetyLocation = Big3Vector;
56 fPreStepLocation = Big3Vector;
57
58 fMinSafety_PreStepPt= -1.0;
59 fMinSafety_atSafLocation= -1.0;
60 fMinSafety= -DBL_MAX;
61 fMinStep= -DBL_MAX;
62
63 for(register int num=0; num<= fMaxNav; ++num )
64 {
65 fpNavigator[num] = 0;
66 fLimitTruth[num] = false;
67 fLimitedStep[num] = kUndefLimited;
68 fCurrentStepSize[num] = -1.0;
69 fLocatedVolume[num] = 0;
70 }
71
72 pTransportManager= G4TransportationManager::GetTransportationManager();
73
74 G4Navigator* massNav= pTransportManager->GetNavigatorForTracking();
75 if( massNav )
76 {
77 G4VPhysicalVolume* pWorld= massNav->GetWorldVolume();
78 if( pWorld )
79 {
80 SetWorldVolume( pWorld );
81 fLastMassWorld = pWorld;
82 }
83 }
84}
85
86G4MultiNavigator::~G4MultiNavigator()
87{
88}
89
90G4double G4MultiNavigator::ComputeStep(const G4ThreeVector &pGlobalPoint,
91 const G4ThreeVector &pDirection,
92 const G4double proposedStepLength,
93 G4double &pNewSafety)
94{
95 G4double safety= 0.0, step=0.0;
96 G4double minSafety= DBL_MAX, minStep= DBL_MAX;
97
98#ifdef G4DEBUG_NAVIGATION
99 if( fVerbose > 2 )
100 {
101 G4cout << " G4MultiNavigator::ComputeStep : entered " << G4endl;
102 G4cout << " Input position= " << pGlobalPoint
103 << " direction= " << pDirection << G4endl;
104 G4cout << " Requested step= " << proposedStepLength << G4endl;
105 }
106#endif
107
108 std::vector<G4Navigator*>::iterator pNavigatorIter;
109
110 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
111
112 G4ThreeVector initialPosition = pGlobalPoint;
113 G4ThreeVector initialDirection= pDirection;
114
115 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
116 {
117 safety= DBL_MAX;
118
119 step= (*pNavigatorIter)->ComputeStep( initialPosition,
120 initialDirection,
121 proposedStepLength,
122 safety );
123 if( safety < minSafety ){ minSafety = safety; }
124 if( step < minStep ) { minStep= step; }
125
126 fCurrentStepSize[num] = step;
127 fNewSafety[num]= safety;
128 // This is currently the safety from the last sub-step
129
130#ifdef G4DEBUG_NAVIGATION
131 if( fVerbose > 2 )
132 {
133 G4cout << "G4MultiNavigator::ComputeStep : Navigator ["
134 << num << "] -- step size " << step
135 << " safety= " << safety << G4endl;
136 }
137#endif
138 }
139
140 // Save safety value, related position
141 //
142 fPreStepLocation = initialPosition;
143 fMinSafety_PreStepPt = minSafety;
144 fMinStep = minStep;
145
146 if( fMinStep == kInfinity )
147 {
148 fTrueMinStep = proposedStepLength; // Use this below for endpoint !!
149 }
150 else
151 {
152 fTrueMinStep = minStep;
153 }
154
155#ifdef G4DEBUG_NAVIGATION
156 if( fVerbose > 1 )
157 {
158 G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
159
160 G4int oldPrec = G4cout.precision(8);
161 G4cout << "G4MultiNavigator::ComputeStep : "
162 << " initialPosition = " << initialPosition
163 << " and endPosition = " << endPosition << G4endl;
164 G4cout.precision( oldPrec );
165 }
166#endif
167
168 pNewSafety = minSafety;
169
170 this->WhichLimited();
171
172#ifdef G4DEBUG_NAVIGATION
173 if( fVerbose > 2 )
174 {
175 G4cout << " G4MultiNavigator::ComputeStep : exits returning "
176 << minStep << G4endl;
177 }
178#endif
179
180 return minStep; // must return kInfinity if do not limit step
181}
182
183// ----------------------------------------------------------------------
184
185G4double
186G4MultiNavigator::ObtainFinalStep( G4int navigatorId,
187 G4double &pNewSafety, // for this geometry
188 G4double &minStep,
189 ELimited &limitedStep)
190{
191 G4int navigatorNo=-1;
192
193 if( navigatorId <= fNoActiveNavigators )
194 {
195 navigatorNo= navigatorId;
196 }
197 else
198 {
199 G4cerr << "ERROR - G4MultiNavigator::ObtainFinalStep()"
200 << " Navigator Id = " << navigatorId
201 << " No Active = " << fNoActiveNavigators << " . "
202 << G4endl;
203 G4Exception("G4MultiNavigator::ObtainFinalStep()", "InvalidSetup",
204 FatalException, "Bad Navigator Id" );
205 }
206
207 // Prepare the information to return
208 pNewSafety = fNewSafety[ navigatorNo ];
209 limitedStep = fLimitedStep[ navigatorNo ];
210 minStep= fMinStep;
211
212 // if( (minStep==kInfinity) || (fVerbose > 1) ){
213#ifdef G4DEBUG_NAVIGATION
214 if( fVerbose > 1 ){
215 G4cout << " G4MultiNavigator::ComputeStep returns " << fCurrentStepSize[ navigatorNo ]
216 << " for Navigator " << navigatorNo << " Limited step = " << limitedStep
217 << " Safety(mm) = " << pNewSafety / mm << G4endl;
218 }
219#endif
220
221 return fCurrentStepSize[ navigatorNo ];
222}
223
224// ----------------------------------------------------------------------
225
226void G4MultiNavigator::PrepareNewTrack( const G4ThreeVector position,
227 const G4ThreeVector direction )
228{
229#ifdef G4DEBUG_NAVIGATION
230 if( fVerbose > 1 )
231 {
232 G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl;
233 }
234#endif
235
236 G4MultiNavigator::PrepareNavigators();
237
238 LocateGlobalPointAndSetup( position, &direction, false, false );
239 //
240 // The first location for each Navigator must be non-relative
241 // or else call ResetStackAndState() for each Navigator
242 // Use direction to get correct side of boundary (ignore dir= false)
243}
244
245// ----------------------------------------------------------------------
246
247void G4MultiNavigator::PrepareNavigators()
248{
249 // Key purposes:
250 // - Check and cache set of active navigators
251 // - Reset state for new track
252
253#ifdef G4DEBUG_NAVIGATION
254 if( fVerbose > 1 )
255 {
256 G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl;
257 }
258#endif
259
260 // Message the transportation-manager to find active navigators
261
262 std::vector<G4Navigator*>::iterator pNavigatorIter;
263 fNoActiveNavigators= pTransportManager-> GetNoActiveNavigators();
264
265 if( fNoActiveNavigators > fMaxNav )
266 {
267 G4cerr << "ERROR - G4MultiNavigator::PrepareNavigators()"
268 << " Too many active Navigators (worlds): "
269 << fNoActiveNavigators << G4endl
270 << " which is more than the number allowed: "
271 << fMaxNav << " !" << G4endl;
272 G4Exception("G4MultiNavigator::PrepareNavigators()", "InvalidSetup",
273 FatalException, "Too many active Navigators / worlds !");
274 }
275
276 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
277 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
278 {
279 fpNavigator[num] = *pNavigatorIter;
280 fLimitTruth[num] = false;
281 fLimitedStep[num] = kDoNot;
282 fCurrentStepSize[num] = 0.0;
283 fLocatedVolume[num] = 0;
284 }
285 fWasLimitedByGeometry = false;
286
287 // Check the world volume of the mass navigator
288 // in case a call to SetWorldVolume() changed it
289
290 G4VPhysicalVolume* massWorld = GetWorldVolume();
291
292 if( (massWorld != fLastMassWorld) && (massWorld!=0) )
293 {
294 // Pass along change to Mass Navigator
295 fpNavigator[0] -> SetWorldVolume( massWorld );
296
297#ifdef G4DEBUG_NAVIGATION
298 if( fVerbose > 0 )
299 {
300 G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume "
301 << " for mass geometry to " << massWorld->GetName() << G4endl;
302 }
303#endif
304
305 fLastMassWorld = massWorld;
306 }
307}
308
309// ----------------------------------------------------------------------
310
311G4VPhysicalVolume*
312G4MultiNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& position,
313 const G4ThreeVector* pDirection,
314 const G4bool pRelativeSearch,
315 const G4bool ignoreDirection )
316{
317 // Locate the point in each geometry
318
319 G4ThreeVector direction(0.0, 0.0, 0.0);
320 G4bool relative = pRelativeSearch;
321 std::vector<G4Navigator*>::iterator pNavIter
322 = pTransportManager->GetActiveNavigatorsIterator();
323
324 if( pDirection ) { direction = *pDirection; }
325
326#ifdef G4DEBUG_NAVIGATION
327 if( fVerbose > 2 )
328 {
329 G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
330 << G4endl;
331 G4cout << " Locating at position: " << position
332 << ", with direction: " << direction << G4endl
333 << " Relative: " << relative
334 << ", ignore direction: " << ignoreDirection << G4endl;
335 G4cout << " Number of active navigators: " << fNoActiveNavigators
336 << G4endl;
337 }
338#endif
339
340 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
341 {
342 if( fWasLimitedByGeometry && fLimitTruth[num] )
343 {
344 (*pNavIter)->SetGeometricallyLimitedStep();
345 }
346
347 G4VPhysicalVolume *pLocated
348 = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
349 relative, ignoreDirection );
350 // Set the state related to the location
351 //
352 fLocatedVolume[num] = pLocated;
353
354 // Clear state related to the step
355 //
356 fLimitedStep[num] = kDoNot;
357 fCurrentStepSize[num] = 0.0;
358 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
359
360#ifdef G4DEBUG_NAVIGATION
361 if( fVerbose > 2 )
362 {
363 G4cout << " Located in world: " << num << ", at: " << position << G4endl
364 << " Used geomLimStp: " << fLimitTruth[num]
365 << ", found in volume: " << pLocated << G4endl;
366 G4cout << " Name = '" ;
367 if( pLocated )
368 {
369 G4cout << pLocated->GetName() << "'";
370 G4cout << " - CopyNo= " << pLocated->GetCopyNo();
371 }
372 else
373 {
374 G4cout << "Null' Id: Not-Set ";
375 }
376 G4cout << G4endl;
377 }
378#endif
379 }
380
381 fWasLimitedByGeometry = false; // Clear on locating
382 G4VPhysicalVolume* volMassLocated= fLocatedVolume[0];
383
384 return volMassLocated;
385}
386
387// ----------------------------------------------------------------------
388
389void
390G4MultiNavigator::LocateGlobalPointWithinVolume(const G4ThreeVector& position)
391{
392 // Relocate the point in each geometry
393
394 std::vector<G4Navigator*>::iterator pNavIter
395 = pTransportManager->GetActiveNavigatorsIterator();
396
397#ifdef G4DEBUG_NAVIGATION
398 if( fVerbose > 2 )
399 {
400 G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl
401 << " Re-locating at position: " << position << G4endl;
402 }
403#endif
404
405 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
406 {
407 // ... none limited the step
408
409 (*pNavIter)->LocateGlobalPointWithinVolume( position );
410
411 // Clear state related to the step
412 //
413 fLimitedStep[num] = kDoNot;
414 fCurrentStepSize[num] = 0.0;
415
416 fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
417 }
418 fWasLimitedByGeometry = false; // Clear on locating
419 fLastLocatedPosition = position;
420}
421
422// ----------------------------------------------------------------------
423
424G4double G4MultiNavigator::ComputeSafety( const G4ThreeVector& position,
425 const G4double maxDistance,
426 const G4bool state)
427{
428 // Recompute safety for the relevant point
429
430 G4double minSafety = DBL_MAX, safety = DBL_MAX;
431
432 std::vector<G4Navigator*>::iterator pNavigatorIter;
433 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
434
435 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
436 {
437 safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
438 if( safety < minSafety ) { minSafety = safety; }
439 }
440
441 fSafetyLocation = position;
442 fMinSafety_atSafLocation = minSafety;
443
444#ifdef G4DEBUG_NAVIGATION
445 if( fVerbose > 1 )
446 {
447 G4cout << " G4MultiNavigator::ComputeSafety - returns: "
448 << minSafety << ", at location: " << position << G4endl;
449 }
450#endif
451 return minSafety;
452}
453
454// -----------------------------------------------------------------------
455
456G4TouchableHistoryHandle
457G4MultiNavigator::CreateTouchableHistoryHandle() const
458{
459 G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()",
460 "215-TouchableFromWrongNavigator", FatalException,
461 "Getting a touchable from G4MultiNavigator is not defined.");
462
463 G4TouchableHistory* touchHist;
464 touchHist= fpNavigator[0] -> CreateTouchableHistory();
465
466 G4VPhysicalVolume* locatedVolume= fLocatedVolume[0];
467 if( locatedVolume == 0 )
468 {
469 // Workaround to ensure that the touchable is fixed !! // TODO: fix
470 //
471 touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
472 }
473
474 return G4TouchableHistoryHandle(touchHist);
475}
476
477// -----------------------------------------------------------------------
478
479void G4MultiNavigator::WhichLimited()
480{
481 // Flag which processes limited the step
482
483 G4int last=-1;
484 const G4int IdTransport= 0; // Id of Mass Navigator !!
485 G4int noLimited=0;
486 ELimited shared= kSharedOther;
487
488#ifdef G4DEBUG_NAVIGATION
489 if( fVerbose > 2 )
490 {
491 G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl;
492 }
493#endif
494
495 // Assume that [IdTransport] is Mass / Transport
496 //
497 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
498 && ( fMinStep!= kInfinity);
499 if( transportLimited )
500 {
501 shared= kSharedTransport;
502 }
503
504 for ( register int num= 0; num < fNoActiveNavigators; num++ )
505 {
506 G4bool limitedStep;
507
508 G4double step= fCurrentStepSize[num];
509
510 limitedStep = ( step == fMinStep ) && ( step != kInfinity);
511
512 fLimitTruth[ num ] = limitedStep;
513 if( limitedStep )
514 {
515 noLimited++;
516 fLimitedStep[num] = shared;
517 last= num;
518 }
519 else
520 {
521 fLimitedStep[num] = kDoNot;
522 }
523 }
524 if( (last > -1) && (noLimited == 1 ) )
525 {
526 fLimitedStep[ last ] = kUnique;
527 }
528}
529
530// -----------------------------------------------------------------------
531
532void
533G4MultiNavigator::PrintLimited()
534{
535 // Report results -- for checking
536
537 static G4String StrDoNot("DoNot"), StrUnique("Unique"),
538 StrUndefined("Undefined"),
539 StrSharedTransport("SharedTransport"),
540 StrSharedOther("SharedOther");
541 G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl;
542 G4cout << " Minimum step (true): " << fTrueMinStep
543 << ", reported min: " << fMinStep << G4endl;
544
545#ifdef G4DEBUG_NAVIGATION
546 if(fVerbose>=2)
547 {
548 G4cout << std::setw(5) << " NavId" << " "
549 << std::setw(12) << " step-size " << " "
550 << std::setw(12) << " raw-size " << " "
551 << std::setw(12) << " pre-safety " << " "
552 << std::setw(15) << " Limited / flag" << " "
553 << std::setw(15) << " World " << " "
554 << G4endl;
555 }
556#endif
557
558 for ( register int num= 0; num < fNoActiveNavigators; num++ )
559 {
560 G4double rawStep = fCurrentStepSize[num];
561 G4double stepLen = fCurrentStepSize[num];
562 if( stepLen > fTrueMinStep )
563 {
564 stepLen = fTrueMinStep; // did not limit (went as far as asked)
565 }
566 G4int oldPrec= G4cout.precision(9);
567
568 G4cout << std::setw(5) << num << " "
569 << std::setw(12) << stepLen << " "
570 << std::setw(12) << rawStep << " "
571 << std::setw(12) << fNewSafety[num] << " "
572 << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
573 G4String limitedStr;
574 switch ( fLimitedStep[num] )
575 {
576 case kDoNot : limitedStr= StrDoNot; break;
577 case kUnique : limitedStr = StrUnique; break;
578 case kSharedTransport: limitedStr= StrSharedTransport; break;
579 case kSharedOther : limitedStr = StrSharedOther; break;
580 default : limitedStr = StrUndefined; break;
581 }
582 G4cout << " " << std::setw(15) << limitedStr << " ";
583 G4cout.precision(oldPrec);
584
585 G4Navigator *pNav= fpNavigator[ num ];
586 G4String WorldName( "Not-Set" );
587 if (pNav)
588 {
589 G4VPhysicalVolume *pWorld= pNav->GetWorldVolume();
590 if( pWorld )
591 {
592 WorldName = pWorld->GetName();
593 }
594 }
595 G4cout << " " << WorldName ;
596 G4cout << G4endl;
597 }
598}
599
600
601// -----------------------------------------------------------------------
602
603void G4MultiNavigator::ResetState()
604{
605 fWasLimitedByGeometry= false;
606
607 G4Exception("G4MultiNavigator::ResetState()", "217-NotImplemented",
608 FatalException,
609 "Cannot call ResetState() for navigators of G4MultiNavigator.");
610
611 std::vector<G4Navigator*>::iterator pNavigatorIter;
612 pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
613 for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
614 {
615 // (*pNavigatorIter)->ResetState(); // KEEP THIS comment !!!
616 }
617}
618
619// -----------------------------------------------------------------------
620
621void G4MultiNavigator::SetupHierarchy()
622{
623 G4Exception( "G4MultiNavigator::SetupHierarchy()",
624 "217-NotImplemented", FatalException,
625 "Cannot call SetupHierarchy() for navigators of G4MultiNavigator.");
626}
627
628// -----------------------------------------------------------------------
629
630void G4MultiNavigator::CheckMassWorld()
631{
632 G4VPhysicalVolume* navTrackWorld=
633 pTransportManager->GetNavigatorForTracking()->GetWorldVolume();
634
635 if( navTrackWorld != fLastMassWorld )
636 {
637 G4Exception( "G4MultiNavigator::CheckMassWorld()",
638 "220-InvalidSetup", FatalException,
639 "Mass world pointer has been changed." );
640 }
641}
642
643// -----------------------------------------------------------------------
644
645G4VPhysicalVolume*
646G4MultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point,
647 const G4ThreeVector &direction,
648 const G4TouchableHistory &MassHistory)
649{
650 // Reset geometry for all -- and use the touchable for the mass history
651
652 G4VPhysicalVolume* massVolume=0;
653 G4Navigator* pMassNavigator= fpNavigator[0];
654
655 if( pMassNavigator )
656 {
657 massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction,
658 MassHistory);
659 }
660 else
661 {
662 G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()",
663 "218-TooEarlyToReset", FatalException,
664 "Cannot reset hierarchy before navigators are initialised.");
665 }
666
667 std::vector<G4Navigator*>::iterator pNavIter=
668 pTransportManager->GetActiveNavigatorsIterator();
669
670 for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
671 {
672 G4bool relativeSearch, ignoreDirection;
673
674 (*pNavIter)-> LocateGlobalPointAndSetup( point,
675 &direction,
676 relativeSearch=false,
677 ignoreDirection=false);
678 }
679 return massVolume;
680}
Note: See TracBrowser for help on using the repository browser.