G4MultiNavigator.cc

Go to the documentation of this file.
00001 //
00002 // ********************************************************************
00003 // * License and Disclaimer                                           *
00004 // *                                                                  *
00005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
00006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
00007 // * conditions of the Geant4 Software License,  included in the file *
00008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
00009 // * include a list of copyright holders.                             *
00010 // *                                                                  *
00011 // * Neither the authors of this software system, nor their employing *
00012 // * institutes,nor the agencies providing financial support for this *
00013 // * work  make  any representation or  warranty, express or implied, *
00014 // * regarding  this  software system or assume any liability for its *
00015 // * use.  Please see the license in the file  LICENSE  and URL above *
00016 // * for the full disclaimer and the limitation of liability.         *
00017 // *                                                                  *
00018 // * This  code  implementation is the result of  the  scientific and *
00019 // * technical work of the GEANT4 collaboration.                      *
00020 // * By using,  copying,  modifying or  distributing the software (or *
00021 // * any work based  on the software)  you  agree  to acknowledge its *
00022 // * use  in  resulting  scientific  publications,  and indicate your *
00023 // * acceptance of all terms of the Geant4 Software license.          *
00024 // ********************************************************************
00025 //
00026 //
00027 // $Id$
00028 // GEANT4 tag $ Name:  $
00029 // 
00030 // class G4PathFinder Implementation
00031 //
00032 // Author:  John Apostolakis, November 2006
00033 // --------------------------------------------------------------------
00034 
00035 #include <iomanip>
00036 
00037 #include "G4MultiNavigator.hh"
00038 
00039 class G4FieldManager;
00040 
00041 #include "G4SystemOfUnits.hh"
00042 #include "G4Navigator.hh"
00043 #include "G4PropagatorInField.hh"
00044 #include "G4TransportationManager.hh"
00045 
00046 // ********************************************************************
00047 // Constructor
00048 // ********************************************************************
00049 //
00050 G4MultiNavigator::G4MultiNavigator() 
00051   : G4Navigator(), fLastMassWorld(0)
00052 {
00053   fNoActiveNavigators= 0; 
00054   G4ThreeVector Big3Vector( kInfinity, kInfinity, kInfinity ); 
00055   fLastLocatedPosition = Big3Vector;
00056   fSafetyLocation  = Big3Vector;
00057   fPreStepLocation = Big3Vector;
00058 
00059   fMinSafety_PreStepPt=  -1.0; 
00060   fMinSafety_atSafLocation= -1.0; 
00061   fMinSafety= -kInfinity;  
00062   fTrueMinStep= fMinStep= -kInfinity;  
00063 
00064   for(register int num=0; num< fMaxNav; ++num )
00065   {
00066     fpNavigator[num] =  0;   
00067     fLimitTruth[num] = false;
00068     fLimitedStep[num] = kUndefLimited;
00069     fCurrentStepSize[num] = fNewSafety[num] = -1.0; 
00070     fLocatedVolume[num] = 0; 
00071   }
00072 
00073   pTransportManager= G4TransportationManager::GetTransportationManager();
00074 
00075   G4Navigator* massNav= pTransportManager->GetNavigatorForTracking();
00076   if( massNav )
00077   { 
00078     G4VPhysicalVolume* pWorld= massNav->GetWorldVolume(); 
00079     if( pWorld )
00080     { 
00081       SetWorldVolume( pWorld ); 
00082       fLastMassWorld = pWorld; 
00083     }
00084   }
00085 
00086   fNoLimitingStep= -1; 
00087   fIdNavLimiting= -1; 
00088 }
00089 
00090 G4MultiNavigator::~G4MultiNavigator() 
00091 {
00092 }
00093 
00094 G4double G4MultiNavigator::ComputeStep(const G4ThreeVector &pGlobalPoint,
00095                                        const G4ThreeVector &pDirection,
00096                                        const G4double       proposedStepLength,
00097                                              G4double      &pNewSafety)
00098 {
00099   G4double safety= 0.0, step=0.0;
00100   G4double minSafety= kInfinity, minStep= kInfinity;
00101 
00102   fNoLimitingStep= -1; 
00103   fIdNavLimiting= -1;     // Reset for new step
00104 
00105 #ifdef G4DEBUG_NAVIGATION
00106   if( fVerbose > 2 )
00107   {
00108     G4cout << " G4MultiNavigator::ComputeStep : entered " << G4endl;
00109     G4cout << "   Input position= " << pGlobalPoint
00110            << "   direction= "      << pDirection         << G4endl;
00111     G4cout << "   Requested step= " << proposedStepLength << G4endl;
00112   }
00113 #endif
00114 
00115   std::vector<G4Navigator*>::iterator pNavigatorIter;
00116 
00117   pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00118 
00119   G4ThreeVector initialPosition = pGlobalPoint;
00120   G4ThreeVector initialDirection= pDirection;
00121 
00122   for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00123   {
00124      safety= kInfinity;
00125 
00126      step= (*pNavigatorIter)->ComputeStep( initialPosition, 
00127                                            initialDirection,
00128                                            proposedStepLength,
00129                                            safety ); 
00130      if( safety < minSafety ){ minSafety = safety; } 
00131      if( step < minStep )    { minStep= step; } 
00132 
00133      fCurrentStepSize[num] = step; 
00134      fNewSafety[num]= safety; 
00135       // This is currently the safety from the last sub-step
00136 
00137 #ifdef G4DEBUG_NAVIGATION
00138      if( fVerbose > 2 )
00139      {
00140        G4cout << "G4MultiNavigator::ComputeStep : Navigator ["
00141               << num << "] -- step size " << step
00142               << " safety= " << safety << G4endl;
00143      }
00144 #endif
00145   } 
00146 
00147   // Save safety value, related position
00148   //
00149   fPreStepLocation     = initialPosition; 
00150   fMinSafety_PreStepPt = minSafety;
00151   fMinStep = minStep; 
00152 
00153   if( fMinStep == kInfinity )
00154   {
00155      fTrueMinStep = proposedStepLength;   //  Use this below for endpoint !!
00156   }
00157   else
00158   {
00159      fTrueMinStep = minStep;
00160   }
00161 
00162 #ifdef G4DEBUG_NAVIGATION
00163   if( fVerbose > 1 )
00164   {
00165     G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
00166 
00167     G4int oldPrec = G4cout.precision(8); 
00168     G4cout << "G4MultiNavigator::ComputeStep : "
00169            << " initialPosition = " << initialPosition 
00170            << " and endPosition = " << endPosition << G4endl;
00171     G4cout.precision( oldPrec );
00172   }
00173 #endif
00174 
00175   pNewSafety = minSafety; 
00176 
00177   this->WhichLimited(); 
00178 
00179 #ifdef G4DEBUG_NAVIGATION
00180   if( fVerbose > 2 )
00181   {
00182     G4cout << " G4MultiNavigator::ComputeStep : exits returning "
00183            << minStep << G4endl;
00184   }
00185 #endif
00186 
00187   return minStep;  // must return kInfinity if do not limit step
00188 }
00189 
00190 // ----------------------------------------------------------------------
00191 
00192 G4double 
00193 G4MultiNavigator::ObtainFinalStep( G4int     navigatorId, 
00194                                    G4double &pNewSafety,  // for this geometry
00195                                    G4double &minStep,
00196                                    ELimited &limitedStep) 
00197 {
00198   if( navigatorId > fNoActiveNavigators )
00199   { 
00200      std::ostringstream message;
00201      message << "Bad Navigator Id!" << G4endl
00202              << "        Navigator Id = " << navigatorId 
00203              << "        No Active = " << fNoActiveNavigators << ".";
00204      G4Exception("G4MultiNavigator::ObtainFinalStep()", "GeomNav0002",
00205                  FatalException, message); 
00206   }
00207 
00208   // Prepare the information to return
00209   //
00210   pNewSafety  = fNewSafety[ navigatorId ]; 
00211   limitedStep = fLimitedStep[ navigatorId ];
00212   minStep= fMinStep; 
00213 
00214 #ifdef G4DEBUG_NAVIGATION
00215   if( fVerbose > 1 )
00216   { 
00217      G4cout << " G4MultiNavigator::ComputeStep returns "
00218             << fCurrentStepSize[ navigatorId ]
00219             << " for Navigator " << navigatorId
00220             << " Limited step = " << limitedStep 
00221             << " Safety(mm) = " << pNewSafety / mm << G4endl; 
00222   }
00223 #endif
00224 
00225   return fCurrentStepSize[ navigatorId ];
00226 }
00227 
00228 // ----------------------------------------------------------------------
00229 
00230 void G4MultiNavigator::PrepareNewTrack( const G4ThreeVector position, 
00231                                         const G4ThreeVector direction )
00232 {
00233 #ifdef G4DEBUG_NAVIGATION
00234   if( fVerbose > 1 )
00235   {
00236     G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl;
00237   }
00238 #endif
00239 
00240   G4MultiNavigator::PrepareNavigators(); 
00241 
00242   LocateGlobalPointAndSetup( position, &direction, false, false );   
00243   //
00244   // The first location for each Navigator must be non-relative
00245   // or else call ResetStackAndState() for each Navigator
00246   // Use direction to get correct side of boundary (ignore dir= false)
00247 }
00248 
00249 // ----------------------------------------------------------------------
00250 
00251 void G4MultiNavigator::PrepareNavigators()
00252 {
00253   // Key purposes:
00254   //   - Check and cache set of active navigators
00255   //   - Reset state for new track
00256 
00257 #ifdef G4DEBUG_NAVIGATION
00258   if( fVerbose > 1 )
00259   {
00260     G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl;
00261   }
00262 #endif
00263 
00264   // Message the transportation-manager to find active navigators
00265 
00266   std::vector<G4Navigator*>::iterator pNavigatorIter; 
00267   fNoActiveNavigators=  pTransportManager-> GetNoActiveNavigators();
00268 
00269   if( fNoActiveNavigators > fMaxNav )
00270   {
00271     std::ostringstream message;
00272     message << "Too many active Navigators / worlds !" << G4endl
00273             << "        Active Navigators (worlds): "
00274             << fNoActiveNavigators << G4endl
00275             << "        which is more than the number allowed: "
00276             << fMaxNav << " !";
00277     G4Exception("G4MultiNavigator::PrepareNavigators()", "GeomNav0002",  
00278                 FatalException, message); 
00279   }
00280 
00281   pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00282   for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00283   {
00284      fpNavigator[num] =  *pNavigatorIter;   
00285      fLimitTruth[num] = false;
00286      fLimitedStep[num] = kDoNot;
00287      fCurrentStepSize[num] = 0.0; 
00288      fLocatedVolume[num] = 0; 
00289   }
00290   fWasLimitedByGeometry = false; 
00291 
00292   // Check the world volume of the mass navigator
00293   // in case a call to SetWorldVolume() changed it
00294 
00295   G4VPhysicalVolume* massWorld = GetWorldVolume();
00296 
00297   if( (massWorld != fLastMassWorld) && (massWorld!=0) )
00298   { 
00299      // Pass along change to Mass Navigator
00300      fpNavigator[0] -> SetWorldVolume( massWorld );
00301 
00302 #ifdef G4DEBUG_NAVIGATION
00303      if( fVerbose > 0 )
00304      { 
00305        G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume " 
00306               << " for mass geometry to " << massWorld->GetName() << G4endl; 
00307      }
00308 #endif
00309 
00310      fLastMassWorld = massWorld;
00311   }
00312 }
00313 
00314 // ----------------------------------------------------------------------
00315 
00316 G4VPhysicalVolume* 
00317 G4MultiNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& position,
00318                                             const G4ThreeVector* pDirection,
00319                                             const G4bool pRelativeSearch,
00320                                             const G4bool ignoreDirection )
00321 {
00322   // Locate the point in each geometry
00323 
00324   G4ThreeVector direction(0.0, 0.0, 0.0);
00325   G4bool relative = pRelativeSearch; 
00326   std::vector<G4Navigator*>::iterator pNavIter
00327     = pTransportManager->GetActiveNavigatorsIterator(); 
00328 
00329   if( pDirection ) { direction = *pDirection; }
00330 
00331 #ifdef G4DEBUG_NAVIGATION
00332   if( fVerbose > 2 )
00333   {
00334     G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
00335            << G4endl;
00336     G4cout << "   Locating at position: " << position
00337            << ", with direction: " << direction << G4endl
00338            << "   Relative: " << relative 
00339            << ", ignore direction: " << ignoreDirection << G4endl;
00340     G4cout << "   Number of active navigators: " << fNoActiveNavigators
00341            << G4endl;
00342   }
00343 #endif
00344 
00345   for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00346   {
00347      if( fWasLimitedByGeometry && fLimitTruth[num] )
00348      { 
00349         (*pNavIter)->SetGeometricallyLimitedStep(); 
00350      }
00351 
00352      G4VPhysicalVolume *pLocated
00353        = (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
00354                                                  relative, ignoreDirection );   
00355      // Set the state related to the location
00356      //
00357      fLocatedVolume[num] = pLocated; 
00358 
00359      // Clear state related to the step
00360      //
00361      fLimitedStep[num]   = kDoNot; 
00362      fCurrentStepSize[num] = 0.0;      
00363      fLimitTruth[ num ] = false;   // Always clear on locating (see Navigator)
00364     
00365 #ifdef G4DEBUG_NAVIGATION
00366      if( fVerbose > 2 )
00367      {
00368        G4cout << " Located in world: " << num << ", at: " << position << G4endl
00369               << " Used geomLimStp: " << fLimitTruth[num]
00370               << ", found in volume: " << pLocated << G4endl; 
00371        G4cout << " Name = '" ;       
00372        if( pLocated )
00373        { 
00374          G4cout << pLocated->GetName() << "'"; 
00375          G4cout << " - CopyNo= " << pLocated->GetCopyNo(); 
00376        }
00377        else
00378        { 
00379          G4cout <<  "Null'   Id: Not-Set "; 
00380        }
00381        G4cout << G4endl; 
00382      }
00383 #endif
00384   }
00385 
00386   fWasLimitedByGeometry = false;   // Clear on locating
00387   G4VPhysicalVolume* volMassLocated= fLocatedVolume[0]; 
00388 
00389   return volMassLocated;
00390 }
00391 
00392 // ----------------------------------------------------------------------
00393 
00394 void
00395 G4MultiNavigator::LocateGlobalPointWithinVolume(const G4ThreeVector& position)
00396 {
00397   // Relocate the point in each geometry
00398 
00399   std::vector<G4Navigator*>::iterator pNavIter
00400     = pTransportManager->GetActiveNavigatorsIterator(); 
00401 
00402 #ifdef G4DEBUG_NAVIGATION
00403   if( fVerbose > 2 )
00404   {
00405     G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl
00406            << "  Re-locating at position: " << position  << G4endl; 
00407   }
00408 #endif
00409 
00410   for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00411   {
00412      //  ... none limited the step
00413 
00414      (*pNavIter)->LocateGlobalPointWithinVolume( position ); 
00415 
00416      // Clear state related to the step
00417      //
00418      fLimitedStep[num]     = kDoNot; 
00419      fCurrentStepSize[num] = 0.0;      
00420 
00421      fLimitTruth[ num ] = false;   // Always clear on locating (see Navigator)
00422   }
00423   fWasLimitedByGeometry = false;   // Clear on locating
00424   fLastLocatedPosition  = position; 
00425 }
00426 
00427 // ----------------------------------------------------------------------
00428 
00429 G4double G4MultiNavigator::ComputeSafety( const G4ThreeVector& position,
00430                                           const G4double       maxDistance,
00431                                           const G4bool         state)
00432 {
00433     // Recompute safety for the relevant point
00434 
00435     G4double minSafety = kInfinity, safety = kInfinity;
00436   
00437     std::vector<G4Navigator*>::iterator pNavigatorIter;
00438     pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00439 
00440     for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00441     {
00442        safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
00443        if( safety < minSafety ) { minSafety = safety; } 
00444     } 
00445 
00446     fSafetyLocation = position;
00447     fMinSafety_atSafLocation = minSafety;
00448 
00449 #ifdef G4DEBUG_NAVIGATION
00450     if( fVerbose > 1 )
00451     { 
00452       G4cout << " G4MultiNavigator::ComputeSafety - returns: " 
00453              << minSafety << ", at location: " << position << G4endl;
00454     }
00455 #endif
00456     return minSafety; 
00457 }
00458 
00459 // -----------------------------------------------------------------------
00460 
00461 G4TouchableHistoryHandle 
00462 G4MultiNavigator::CreateTouchableHistoryHandle() const
00463 {
00464   G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()", 
00465                "GeomNav0001", FatalException,  
00466                "Getting a touchable from G4MultiNavigator is not defined."); 
00467 
00468   G4TouchableHistory* touchHist;
00469   touchHist= fpNavigator[0] -> CreateTouchableHistory(); 
00470 
00471   G4VPhysicalVolume* locatedVolume= fLocatedVolume[0]; 
00472   if( locatedVolume == 0 )
00473   {
00474     // Workaround to ensure that the touchable is fixed !! // TODO: fix
00475     //
00476     touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
00477   }
00478     
00479   return G4TouchableHistoryHandle(touchHist); 
00480 }
00481 
00482 // -----------------------------------------------------------------------
00483 
00484 void G4MultiNavigator::WhichLimited()
00485 {
00486   // Flag which processes limited the step
00487 
00488   G4int last=-1; 
00489   const G4int IdTransport= 0;  // Id of Mass Navigator !!
00490   G4int noLimited=0; 
00491   ELimited shared= kSharedOther; 
00492 
00493 #ifdef G4DEBUG_NAVIGATION
00494   if( fVerbose > 2 )
00495   {
00496     G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl;
00497   }
00498 #endif
00499 
00500   // Assume that [IdTransport] is Mass / Transport
00501   // 
00502   G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
00503                          && ( fMinStep!= kInfinity); 
00504   if( transportLimited )
00505   { 
00506      shared= kSharedTransport;
00507   }
00508 
00509   for ( register int num= 0; num < fNoActiveNavigators; num++ )
00510   { 
00511     G4bool limitedStep;
00512 
00513     G4double step= fCurrentStepSize[num]; 
00514 
00515     limitedStep = ( step == fMinStep ) && ( step != kInfinity); 
00516    
00517     fLimitTruth[ num ] = limitedStep; 
00518     if( limitedStep )
00519     {
00520       noLimited++;  
00521       fLimitedStep[num] = shared;
00522       last= num; 
00523     }
00524     else
00525     {
00526       fLimitedStep[num] = kDoNot;
00527     }
00528   }
00529   if( (last > -1) && (noLimited == 1 ) )
00530   {
00531     fLimitedStep[ last ] = kUnique; 
00532   }
00533 
00534   fNoLimitingStep= noLimited;  
00535 
00536   return;
00537 }
00538 
00539 // -----------------------------------------------------------------------
00540 
00541 void
00542 G4MultiNavigator::PrintLimited()
00543 {
00544   // Report results -- for checking   
00545 
00546   static G4String StrDoNot("DoNot"), StrUnique("Unique"),
00547                   StrUndefined("Undefined"),
00548                   StrSharedTransport("SharedTransport"),
00549                   StrSharedOther("SharedOther");
00550   G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl;
00551   G4cout << "    Minimum step (true): " << fTrueMinStep 
00552          << ", reported min: " << fMinStep << G4endl; 
00553 
00554 #ifdef G4DEBUG_NAVIGATION
00555   if(fVerbose>=2)
00556   {
00557     G4cout << std::setw(5) << " NavId"  << " "
00558            << std::setw(12) << " step-size " << " "
00559            << std::setw(12) << " raw-size "  << " "
00560            << std::setw(12) << " pre-safety " << " " 
00561            << std::setw(15) << " Limited / flag"  << " "
00562            << std::setw(15) << "  World "  << " "
00563            << G4endl;  
00564   }
00565 #endif
00566 
00567   for ( register int num= 0; num < fNoActiveNavigators; num++ )
00568   { 
00569     G4double rawStep = fCurrentStepSize[num]; 
00570     G4double stepLen = fCurrentStepSize[num]; 
00571     if( stepLen > fTrueMinStep )
00572     { 
00573       stepLen = fTrueMinStep;     // did not limit (went as far as asked)
00574     }
00575     G4int oldPrec= G4cout.precision(9); 
00576 
00577     G4cout << std::setw(5) << num  << " "
00578            << std::setw(12) << stepLen << " "
00579            << std::setw(12) << rawStep << " "
00580            << std::setw(12) << fNewSafety[num] << " "
00581            << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
00582     G4String limitedStr;
00583     switch ( fLimitedStep[num] )
00584     {
00585       case kDoNot          : limitedStr= StrDoNot; break;
00586       case kUnique         : limitedStr = StrUnique; break; 
00587       case kSharedTransport: limitedStr= StrSharedTransport; break; 
00588       case kSharedOther    : limitedStr = StrSharedOther; break;
00589       default              : limitedStr = StrUndefined; break;
00590     }
00591     G4cout << " " << std::setw(15) << limitedStr << " ";  
00592     G4cout.precision(oldPrec); 
00593 
00594     G4Navigator *pNav= fpNavigator[ num ]; 
00595     G4String  WorldName( "Not-Set" ); 
00596     if (pNav)
00597     {
00598        G4VPhysicalVolume *pWorld= pNav->GetWorldVolume(); 
00599        if( pWorld )
00600        {
00601            WorldName = pWorld->GetName(); 
00602        }
00603     }
00604     G4cout << " " << WorldName ; 
00605     G4cout << G4endl;
00606   }
00607 }
00608  
00609 
00610 // -----------------------------------------------------------------------
00611 
00612 void G4MultiNavigator::ResetState()
00613 {
00614    fWasLimitedByGeometry= false; 
00615 
00616    G4Exception("G4MultiNavigator::ResetState()", "GeomNav0001",  
00617                FatalException,  
00618                "Cannot reset state for navigators of G4MultiNavigator.");
00619    
00620    std::vector<G4Navigator*>::iterator pNavigatorIter;
00621    pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
00622    for( register int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
00623    {
00624        //  (*pNavigatorIter)->ResetState();  // KEEP THIS comment !!!
00625    } 
00626 }
00627 
00628 // -----------------------------------------------------------------------
00629 
00630 void G4MultiNavigator::SetupHierarchy()
00631 {
00632   G4Exception( "G4MultiNavigator::SetupHierarchy()", 
00633                "GeomNav0001", FatalException,  
00634                "Cannot setup hierarchy for navigators of G4MultiNavigator."); 
00635 }
00636 
00637 // -----------------------------------------------------------------------
00638 
00639 void G4MultiNavigator::CheckMassWorld()
00640 {
00641    G4VPhysicalVolume* navTrackWorld=
00642      pTransportManager->GetNavigatorForTracking()->GetWorldVolume();
00643 
00644    if( navTrackWorld != fLastMassWorld )
00645    { 
00646       G4Exception( "G4MultiNavigator::CheckMassWorld()",
00647                    "GeomNav0003", FatalException, 
00648                    "Mass world pointer has been changed." ); 
00649    }
00650 }
00651 
00652 // -----------------------------------------------------------------------
00653 
00654 G4VPhysicalVolume*
00655 G4MultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point,
00656                                           const G4ThreeVector &direction,
00657                                           const G4TouchableHistory &MassHistory)
00658 {
00659    // Reset geometry for all -- and use the touchable for the mass history
00660 
00661    G4VPhysicalVolume* massVolume=0; 
00662    G4Navigator* pMassNavigator= fpNavigator[0]; 
00663 
00664    if( pMassNavigator )
00665    {
00666       massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction,
00667                                                            MassHistory); 
00668    }
00669    else
00670    {
00671       G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()",
00672                   "GeomNav0002", FatalException,
00673                   "Cannot reset hierarchy before navigators are initialised.");
00674    }
00675 
00676    std::vector<G4Navigator*>::iterator pNavIter= 
00677        pTransportManager->GetActiveNavigatorsIterator(); 
00678 
00679    for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00680    {
00681       G4bool relativeSearch, ignoreDirection; 
00682 
00683       (*pNavIter)-> LocateGlobalPointAndSetup( point, 
00684                                                &direction, 
00685                                                relativeSearch=false,
00686                                                ignoreDirection=false);
00687    }
00688    return massVolume; 
00689 }
00690 
00691 // -----------------  ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
00692 
00693 G4ThreeVector 
00694 G4MultiNavigator::GetGlobalExitNormal(const G4ThreeVector &argPoint,
00695                                       G4bool* argpObtained)  //  obtained valid
00696 {
00697   G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0); 
00698   G4bool isObtained= false; 
00699   // These default values will be used if fNoLimitingStep== 0
00700   G4int  firstNavigatorId= -1;
00701   G4bool        oneObtained= false;
00702     
00703   if( fNoLimitingStep==1 )
00704   { 
00705     // Only message the Navigator which limited the step!
00706     normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetGlobalExitNormal( argPoint, &isObtained); 
00707     *argpObtained= isObtained; 
00708   }
00709   else 
00710   {
00711     if( fNoLimitingStep > 1 )
00712     { 
00713       std::vector<G4Navigator*>::iterator pNavIter= 
00714         pTransportManager->GetActiveNavigatorsIterator(); 
00715 
00716       for ( register int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
00717       {
00718         G4ThreeVector oneNormal;
00719         if( fLimitedStep[ num ] ) 
00720         { 
00721           G4ThreeVector newNormal= (*pNavIter)-> GetGlobalExitNormal( argPoint, &oneObtained );
00722           if( oneObtained )
00723           {
00724             // Keep first one - only if it is valid (ie not null)
00725             if( !isObtained && (newNormal.mag2() != 0.0) )
00726             {
00727               normalGlobalCrd= newNormal; 
00728               isObtained =     oneObtained;
00729               firstNavigatorId= num; 
00730             }else{
00731               // Check for clash
00732               G4double dotNewPrevious= newNormal.dot( normalGlobalCrd );
00733               G4double productMagSq= normalGlobalCrd.mag2() * newNormal.mag2(); 
00734               if( productMagSq > 0.0 ) 
00735               {
00736                 G4double productMag= std::sqrt( productMagSq ); 
00737                 dotNewPrevious /= productMag; // Normalise
00738                 if( dotNewPrevious < (1 - perThousand) ) 
00739                 {
00740                   *argpObtained= false; 
00741 
00742                   if( fVerbose > 2 )  //  dotNewPrevious <= 0.0 )
00743                   {
00744                     std::ostringstream message;
00745                     message << "Clash of Normal from different Navigators!" << G4endl
00746                             << "        Previous Navigator Id = " << firstNavigatorId << G4endl
00747                             << "        Current  Navigator Id = " << num << G4endl;
00748                     message << "  Dot product of 2 normals = " << dotNewPrevious << G4endl;
00749                     message << "        Normal (previous) = " << normalGlobalCrd << G4endl;
00750                     message << "        Normal (current)  = " << newNormal       << G4endl;
00751                     G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00752                                 JustWarning, message); 
00753                   }
00754                 }
00755                 else
00756                 {
00757                   // Close agreement - Do not change 
00758                 }
00759               }
00760             }
00761           }
00762         }
00763       } // end for over the Navigators
00764 
00765       // Report if no Normal was obtained
00766       if( !oneObtained ) 
00767       {
00768         std::ostringstream message;
00769         message << "No Normal obtained despite having " << fNoLimitingStep
00770                 << " candidate Navigators limiting the step!" << G4endl;
00771         G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00772                     JustWarning, message); 
00773       }
00774 
00775     } // end if ( fNoLimiting > 1 ) 
00776   } // end else
00777 
00778   *argpObtained= isObtained;
00779   return normalGlobalCrd;
00780 }
00781 
00782 // -----------------  ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
00783 
00784 G4ThreeVector 
00785 G4MultiNavigator::GetLocalExitNormal(G4bool* argpObtained)
00786 {
00787   // If it is the mass navigator, then expect
00788   G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0); 
00789   G4bool isObtained= false; 
00790   // These default values will be used if fNoLimitingStep== 0
00791 
00792   if( fNoLimitingStep==1 )
00793   { 
00794     // Only message the Navigator which limited the step!
00795     normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetLocalExitNormal( &isObtained); 
00796     *argpObtained= isObtained;
00797 
00798     G4int static numberWarnings= 0;
00799     G4int noWarningsStart= 10, noModuloWarnings=100; 
00800     numberWarnings++; 
00801     if( (numberWarnings < noWarningsStart ) || (numberWarnings%noModuloWarnings==0) ) 
00802     {
00803     std::ostringstream message;
00804     message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
00805     G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00806                 JustWarning, message);       
00807     }
00808   }
00809   else
00810   {
00811     if( fNoLimitingStep > 1 ) 
00812     {
00813         // Does not make sense - cannot obtain *local* normal in several coordinate systems
00814         std::ostringstream message;
00815         message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
00816         G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
00817                     FatalException, message);       
00818     }
00819   }
00820     
00821   *argpObtained= isObtained;
00822   return normalGlobalCrd; 
00823 }
00824 
00825 
00826 // -----------------  ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
00827 
00828 G4ThreeVector 
00829 G4MultiNavigator::GetLocalExitNormalAndCheck(const G4ThreeVector &, // point,
00830                                                    G4bool* obtained)
00831 {
00832   return G4MultiNavigator::GetLocalExitNormal( obtained);
00833 }

Generated on Mon May 27 17:48:54 2013 for Geant4 by  doxygen 1.4.7