Files
geant4/source/geometry/navigation/src/G4MultiNavigator.cc
T
2018-12-07 15:15:39 +01:00

834 lines
26 KiB
C++

//
// ********************************************************************
// * License and Disclaimer *
// * *
// * The Geant4 software is copyright of the Copyright Holders of *
// * the Geant4 Collaboration. It is provided under the terms and *
// * conditions of the Geant4 Software License, included in the file *
// * LICENSE and available at http://cern.ch/geant4/license . These *
// * include a list of copyright holders. *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. Please see the license in the file LICENSE and URL above *
// * for the full disclaimer and the limitation of liability. *
// * *
// * This code implementation is the result of the scientific and *
// * technical work of the GEANT4 collaboration. *
// * By using, copying, modifying or distributing the software (or *
// * any work based on the software) you agree to acknowledge its *
// * use in resulting scientific publications, and indicate your *
// * acceptance of all terms of the Geant4 Software license. *
// ********************************************************************
//
//
// GEANT4 tag $ Name: $
//
// class G4PathFinder Implementation
//
// Author: John Apostolakis, November 2006
// --------------------------------------------------------------------
#include <iomanip>
#include "G4MultiNavigator.hh"
class G4FieldManager;
#include "G4SystemOfUnits.hh"
#include "G4Navigator.hh"
#include "G4PropagatorInField.hh"
#include "G4TransportationManager.hh"
// ********************************************************************
// Constructor
// ********************************************************************
//
G4MultiNavigator::G4MultiNavigator()
: G4Navigator(), fLastMassWorld(0)
{
fNoActiveNavigators= 0;
G4ThreeVector Big3Vector( kInfinity, kInfinity, kInfinity );
fLastLocatedPosition = Big3Vector;
fSafetyLocation = Big3Vector;
fPreStepLocation = Big3Vector;
fMinSafety_PreStepPt= -1.0;
fMinSafety_atSafLocation= -1.0;
fMinSafety= -kInfinity;
fTrueMinStep= fMinStep= -kInfinity;
for(G4int num=0; num< fMaxNav; ++num )
{
fpNavigator[num] = 0;
fLimitTruth[num] = false;
fLimitedStep[num] = kUndefLimited;
fCurrentStepSize[num] = fNewSafety[num] = -1.0;
fLocatedVolume[num] = 0;
}
pTransportManager= G4TransportationManager::GetTransportationManager();
G4Navigator* massNav= pTransportManager->GetNavigatorForTracking();
if( massNav )
{
G4VPhysicalVolume* pWorld= massNav->GetWorldVolume();
if( pWorld )
{
SetWorldVolume( pWorld );
fLastMassWorld = pWorld;
}
}
fNoLimitingStep= -1;
fIdNavLimiting= -1;
}
G4MultiNavigator::~G4MultiNavigator()
{
}
G4double G4MultiNavigator::ComputeStep(const G4ThreeVector &pGlobalPoint,
const G4ThreeVector &pDirection,
const G4double proposedStepLength,
G4double &pNewSafety)
{
G4double safety= 0.0, step=0.0;
G4double minSafety= kInfinity, minStep= kInfinity;
fNoLimitingStep= -1;
fIdNavLimiting= -1; // Reset for new step
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 2 )
{
G4cout << " G4MultiNavigator::ComputeStep : entered " << G4endl;
G4cout << " Input position= " << pGlobalPoint
<< " direction= " << pDirection << G4endl;
G4cout << " Requested step= " << proposedStepLength << G4endl;
}
#endif
std::vector<G4Navigator*>::iterator pNavigatorIter;
pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
G4ThreeVector initialPosition = pGlobalPoint;
G4ThreeVector initialDirection= pDirection;
for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
{
safety= kInfinity;
step= (*pNavigatorIter)->ComputeStep( initialPosition,
initialDirection,
proposedStepLength,
safety );
if( safety < minSafety ){ minSafety = safety; }
if( step < minStep ) { minStep= step; }
fCurrentStepSize[num] = step;
fNewSafety[num]= safety;
// This is currently the safety from the last sub-step
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 2 )
{
G4cout << "G4MultiNavigator::ComputeStep : Navigator ["
<< num << "] -- step size " << step
<< " safety= " << safety << G4endl;
}
#endif
}
// Save safety value, related position
//
fPreStepLocation = initialPosition;
fMinSafety_PreStepPt = minSafety;
fMinStep = minStep;
if( fMinStep == kInfinity )
{
fTrueMinStep = proposedStepLength; // Use this below for endpoint !!
}
else
{
fTrueMinStep = minStep;
}
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 1 )
{
G4ThreeVector endPosition = initialPosition+fTrueMinStep*initialDirection;
G4int oldPrec = G4cout.precision(8);
G4cout << "G4MultiNavigator::ComputeStep : "
<< " initialPosition = " << initialPosition
<< " and endPosition = " << endPosition << G4endl;
G4cout.precision( oldPrec );
}
#endif
pNewSafety = minSafety;
this->WhichLimited();
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 2 )
{
G4cout << " G4MultiNavigator::ComputeStep : exits returning "
<< minStep << G4endl;
}
#endif
return minStep; // must return kInfinity if do not limit step
}
// ----------------------------------------------------------------------
G4double
G4MultiNavigator::ObtainFinalStep( G4int navigatorId,
G4double &pNewSafety, // for this geometry
G4double &minStep,
ELimited &limitedStep)
{
if( navigatorId > fNoActiveNavigators )
{
std::ostringstream message;
message << "Bad Navigator Id!" << G4endl
<< " Navigator Id = " << navigatorId
<< " No Active = " << fNoActiveNavigators << ".";
G4Exception("G4MultiNavigator::ObtainFinalStep()", "GeomNav0002",
FatalException, message);
}
// Prepare the information to return
//
pNewSafety = fNewSafety[ navigatorId ];
limitedStep = fLimitedStep[ navigatorId ];
minStep= fMinStep;
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 1 )
{
G4cout << " G4MultiNavigator::ComputeStep returns "
<< fCurrentStepSize[ navigatorId ]
<< " for Navigator " << navigatorId
<< " Limited step = " << limitedStep
<< " Safety(mm) = " << pNewSafety / mm << G4endl;
}
#endif
return fCurrentStepSize[ navigatorId ];
}
// ----------------------------------------------------------------------
void G4MultiNavigator::PrepareNewTrack( const G4ThreeVector position,
const G4ThreeVector direction )
{
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 1 )
{
G4cout << " Entered G4MultiNavigator::PrepareNewTrack() " << G4endl;
}
#endif
G4MultiNavigator::PrepareNavigators();
LocateGlobalPointAndSetup( position, &direction, false, false );
//
// The first location for each Navigator must be non-relative
// or else call ResetStackAndState() for each Navigator
// Use direction to get correct side of boundary (ignore dir= false)
}
// ----------------------------------------------------------------------
void G4MultiNavigator::PrepareNavigators()
{
// Key purposes:
// - Check and cache set of active navigators
// - Reset state for new track
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 1 )
{
G4cout << " Entered G4MultiNavigator::PrepareNavigators() " << G4endl;
}
#endif
// Message the transportation-manager to find active navigators
std::vector<G4Navigator*>::iterator pNavigatorIter;
fNoActiveNavigators= pTransportManager-> GetNoActiveNavigators();
if( fNoActiveNavigators > fMaxNav )
{
std::ostringstream message;
message << "Too many active Navigators / worlds !" << G4endl
<< " Active Navigators (worlds): "
<< fNoActiveNavigators << G4endl
<< " which is more than the number allowed: "
<< fMaxNav << " !";
G4Exception("G4MultiNavigator::PrepareNavigators()", "GeomNav0002",
FatalException, message);
}
pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
{
fpNavigator[num] = *pNavigatorIter;
fLimitTruth[num] = false;
fLimitedStep[num] = kDoNot;
fCurrentStepSize[num] = 0.0;
fLocatedVolume[num] = 0;
}
fWasLimitedByGeometry = false;
// Check the world volume of the mass navigator
// in case a call to SetWorldVolume() changed it
G4VPhysicalVolume* massWorld = GetWorldVolume();
if( (massWorld != fLastMassWorld) && (massWorld!=0) )
{
// Pass along change to Mass Navigator
fpNavigator[0] -> SetWorldVolume( massWorld );
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 0 )
{
G4cout << " G4MultiNavigator::PrepareNavigators() changed world volume "
<< " for mass geometry to " << massWorld->GetName() << G4endl;
}
#endif
fLastMassWorld = massWorld;
}
}
// ----------------------------------------------------------------------
G4VPhysicalVolume*
G4MultiNavigator::LocateGlobalPointAndSetup(const G4ThreeVector& position,
const G4ThreeVector* pDirection,
const G4bool pRelativeSearch,
const G4bool ignoreDirection )
{
// Locate the point in each geometry
G4ThreeVector direction(0.0, 0.0, 0.0);
G4bool relative = pRelativeSearch;
std::vector<G4Navigator*>::iterator pNavIter
= pTransportManager->GetActiveNavigatorsIterator();
if( pDirection ) { direction = *pDirection; }
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 2 )
{
G4cout << " Entered G4MultiNavigator::LocateGlobalPointAndSetup() "
<< G4endl;
G4cout << " Locating at position: " << position
<< ", with direction: " << direction << G4endl
<< " Relative: " << relative
<< ", ignore direction: " << ignoreDirection << G4endl;
G4cout << " Number of active navigators: " << fNoActiveNavigators
<< G4endl;
}
#endif
for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
{
if( fWasLimitedByGeometry && fLimitTruth[num] )
{
(*pNavIter)->SetGeometricallyLimitedStep();
}
G4VPhysicalVolume *pLocated
= (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
relative, ignoreDirection );
// Set the state related to the location
//
fLocatedVolume[num] = pLocated;
// Clear state related to the step
//
fLimitedStep[num] = kDoNot;
fCurrentStepSize[num] = 0.0;
fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 2 )
{
G4cout << " Located in world: " << num << ", at: " << position << G4endl
<< " Used geomLimStp: " << fLimitTruth[num]
<< ", found in volume: " << pLocated << G4endl;
G4cout << " Name = '" ;
if( pLocated )
{
G4cout << pLocated->GetName() << "'";
G4cout << " - CopyNo= " << pLocated->GetCopyNo();
}
else
{
G4cout << "Null' Id: Not-Set ";
}
G4cout << G4endl;
}
#endif
}
fWasLimitedByGeometry = false; // Clear on locating
G4VPhysicalVolume* volMassLocated= fLocatedVolume[0];
return volMassLocated;
}
// ----------------------------------------------------------------------
void
G4MultiNavigator::LocateGlobalPointWithinVolume(const G4ThreeVector& position)
{
// Relocate the point in each geometry
std::vector<G4Navigator*>::iterator pNavIter
= pTransportManager->GetActiveNavigatorsIterator();
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 2 )
{
G4cout << " Entered G4MultiNavigator::ReLocate() " << G4endl
<< " Re-locating at position: " << position << G4endl;
}
#endif
for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
{
// ... none limited the step
(*pNavIter)->LocateGlobalPointWithinVolume( position );
// Clear state related to the step
//
fLimitedStep[num] = kDoNot;
fCurrentStepSize[num] = 0.0;
fLimitTruth[ num ] = false; // Always clear on locating (see Navigator)
}
fWasLimitedByGeometry = false; // Clear on locating
fLastLocatedPosition = position;
}
// ----------------------------------------------------------------------
G4double G4MultiNavigator::ComputeSafety( const G4ThreeVector& position,
const G4double maxDistance,
const G4bool state)
{
// Recompute safety for the relevant point
G4double minSafety = kInfinity, safety = kInfinity;
std::vector<G4Navigator*>::iterator pNavigatorIter;
pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
{
safety = (*pNavigatorIter)->ComputeSafety( position, maxDistance, state);
if( safety < minSafety ) { minSafety = safety; }
}
fSafetyLocation = position;
fMinSafety_atSafLocation = minSafety;
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 1 )
{
G4cout << " G4MultiNavigator::ComputeSafety - returns: "
<< minSafety << ", at location: " << position << G4endl;
}
#endif
return minSafety;
}
// -----------------------------------------------------------------------
G4TouchableHistoryHandle
G4MultiNavigator::CreateTouchableHistoryHandle() const
{
G4Exception( "G4MultiNavigator::CreateTouchableHistoryHandle()",
"GeomNav0001", FatalException,
"Getting a touchable from G4MultiNavigator is not defined.");
G4TouchableHistory* touchHist;
touchHist= fpNavigator[0] -> CreateTouchableHistory();
G4VPhysicalVolume* locatedVolume= fLocatedVolume[0];
if( locatedVolume == 0 )
{
// Workaround to ensure that the touchable is fixed !! // TODO: fix
//
touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
}
return G4TouchableHistoryHandle(touchHist);
}
// -----------------------------------------------------------------------
void G4MultiNavigator::WhichLimited()
{
// Flag which processes limited the step
G4int last=-1;
const G4int IdTransport= 0; // Id of Mass Navigator !!
G4int noLimited=0;
ELimited shared= kSharedOther;
#ifdef G4DEBUG_NAVIGATION
if( fVerbose > 2 )
{
G4cout << " Entered G4MultiNavigator::WhichLimited() " << G4endl;
}
#endif
// Assume that [IdTransport] is Mass / Transport
//
G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
&& ( fMinStep!= kInfinity);
if( transportLimited )
{
shared= kSharedTransport;
}
for ( G4int num= 0; num < fNoActiveNavigators; num++ )
{
G4bool limitedStep;
G4double step= fCurrentStepSize[num];
limitedStep = ( step == fMinStep ) && ( step != kInfinity);
fLimitTruth[ num ] = limitedStep;
if( limitedStep )
{
noLimited++;
fLimitedStep[num] = shared;
last= num;
}
else
{
fLimitedStep[num] = kDoNot;
}
}
if( (last > -1) && (noLimited == 1 ) )
{
fLimitedStep[ last ] = kUnique;
fIdNavLimiting = last;
}
fNoLimitingStep= noLimited;
return;
}
// -----------------------------------------------------------------------
void
G4MultiNavigator::PrintLimited()
{
// Report results -- for checking
static const G4String StrDoNot("DoNot"), StrUnique("Unique"),
StrUndefined("Undefined"),
StrSharedTransport("SharedTransport"),
StrSharedOther("SharedOther");
G4cout << "### G4MultiNavigator::PrintLimited() reports: " << G4endl;
G4cout << " Minimum step (true): " << fTrueMinStep
<< ", reported min: " << fMinStep << G4endl;
#ifdef G4DEBUG_NAVIGATION
if(fVerbose>=2)
{
G4cout << std::setw(5) << " NavId" << " "
<< std::setw(12) << " step-size " << " "
<< std::setw(12) << " raw-size " << " "
<< std::setw(12) << " pre-safety " << " "
<< std::setw(15) << " Limited / flag" << " "
<< std::setw(15) << " World " << " "
<< G4endl;
}
#endif
for ( G4int num= 0; num < fNoActiveNavigators; num++ )
{
G4double rawStep = fCurrentStepSize[num];
G4double stepLen = fCurrentStepSize[num];
if( stepLen > fTrueMinStep )
{
stepLen = fTrueMinStep; // did not limit (went as far as asked)
}
G4int oldPrec= G4cout.precision(9);
G4cout << std::setw(5) << num << " "
<< std::setw(12) << stepLen << " "
<< std::setw(12) << rawStep << " "
<< std::setw(12) << fNewSafety[num] << " "
<< std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
G4String limitedStr;
switch ( fLimitedStep[num] )
{
case kDoNot : limitedStr= StrDoNot; break;
case kUnique : limitedStr = StrUnique; break;
case kSharedTransport: limitedStr= StrSharedTransport; break;
case kSharedOther : limitedStr = StrSharedOther; break;
default : limitedStr = StrUndefined; break;
}
G4cout << " " << std::setw(15) << limitedStr << " ";
G4cout.precision(oldPrec);
G4Navigator *pNav= fpNavigator[ num ];
G4String WorldName( "Not-Set" );
if (pNav)
{
G4VPhysicalVolume *pWorld= pNav->GetWorldVolume();
if( pWorld )
{
WorldName = pWorld->GetName();
}
}
G4cout << " " << WorldName ;
G4cout << G4endl;
}
}
// -----------------------------------------------------------------------
void G4MultiNavigator::ResetState()
{
fWasLimitedByGeometry= false;
G4Exception("G4MultiNavigator::ResetState()", "GeomNav0001",
FatalException,
"Cannot reset state for navigators of G4MultiNavigator.");
std::vector<G4Navigator*>::iterator pNavigatorIter;
pNavigatorIter= pTransportManager-> GetActiveNavigatorsIterator();
for( G4int num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
{
// (*pNavigatorIter)->ResetState(); // KEEP THIS comment !!!
}
}
// -----------------------------------------------------------------------
void G4MultiNavigator::SetupHierarchy()
{
G4Exception( "G4MultiNavigator::SetupHierarchy()",
"GeomNav0001", FatalException,
"Cannot setup hierarchy for navigators of G4MultiNavigator.");
}
// -----------------------------------------------------------------------
void G4MultiNavigator::CheckMassWorld()
{
G4VPhysicalVolume* navTrackWorld=
pTransportManager->GetNavigatorForTracking()->GetWorldVolume();
if( navTrackWorld != fLastMassWorld )
{
G4Exception( "G4MultiNavigator::CheckMassWorld()",
"GeomNav0003", FatalException,
"Mass world pointer has been changed." );
}
}
// -----------------------------------------------------------------------
G4VPhysicalVolume*
G4MultiNavigator::ResetHierarchyAndLocate(const G4ThreeVector &point,
const G4ThreeVector &direction,
const G4TouchableHistory &MassHistory)
{
// Reset geometry for all -- and use the touchable for the mass history
G4VPhysicalVolume* massVolume=0;
G4Navigator* pMassNavigator= fpNavigator[0];
if( pMassNavigator )
{
massVolume= pMassNavigator->ResetHierarchyAndLocate( point, direction,
MassHistory);
}
else
{
G4Exception("G4MultiNavigator::ResetHierarchyAndLocate()",
"GeomNav0002", FatalException,
"Cannot reset hierarchy before navigators are initialised.");
}
std::vector<G4Navigator*>::iterator pNavIter=
pTransportManager->GetActiveNavigatorsIterator();
for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
{
G4bool relativeSearch, ignoreDirection;
(*pNavIter)-> LocateGlobalPointAndSetup( point,
&direction,
relativeSearch=false,
ignoreDirection=false);
}
return massVolume;
}
// ----------------- ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
G4ThreeVector
G4MultiNavigator::GetGlobalExitNormal(const G4ThreeVector &argPoint,
G4bool* argpObtained) // obtained valid
{
G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
G4bool isObtained= false;
// These default values will be used if fNoLimitingStep== 0
G4int firstNavigatorId= -1;
G4bool oneObtained= false;
if( fNoLimitingStep==1 )
{
// Only message the Navigator which limited the step!
normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetGlobalExitNormal( argPoint, &isObtained);
*argpObtained= isObtained;
}
else
{
if( fNoLimitingStep > 1 )
{
std::vector<G4Navigator*>::iterator pNavIter=
pTransportManager->GetActiveNavigatorsIterator();
for ( G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
{
G4ThreeVector oneNormal;
if( fLimitTruth[ num ] ) // Did this geometry limit the step ?
{
G4ThreeVector newNormal= (*pNavIter)-> GetGlobalExitNormal( argPoint, &oneObtained );
if( oneObtained )
{
// Keep first one - only if it is valid (ie not null)
if( !isObtained && (newNormal.mag2() != 0.0) )
{
normalGlobalCrd= newNormal;
isObtained = oneObtained;
firstNavigatorId= num;
}else{
// Check for clash
G4double dotNewPrevious= newNormal.dot( normalGlobalCrd );
G4double productMagSq= normalGlobalCrd.mag2() * newNormal.mag2();
if( productMagSq > 0.0 )
{
G4double productMag= std::sqrt( productMagSq );
dotNewPrevious /= productMag; // Normalise
if( dotNewPrevious < (1 - perThousand) )
{
*argpObtained= false;
if( fVerbose > 2 ) // dotNewPrevious <= 0.0 )
{
std::ostringstream message;
message << "Clash of Normal from different Navigators!" << G4endl
<< " Previous Navigator Id = " << firstNavigatorId << G4endl
<< " Current Navigator Id = " << num << G4endl;
message << " Dot product of 2 normals = " << dotNewPrevious << G4endl;
message << " Normal (previous) = " << normalGlobalCrd << G4endl;
message << " Normal (current) = " << newNormal << G4endl;
G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
JustWarning, message);
}
}
else
{
// Close agreement - Do not change
}
}
}
}
}
} // end for over the Navigators
// Report if no Normal was obtained
if( !oneObtained )
{
std::ostringstream message;
message << "No Normal obtained despite having " << fNoLimitingStep
<< " candidate Navigators limiting the step!" << G4endl;
G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
JustWarning, message);
}
} // end if ( fNoLimiting > 1 )
} // end else
*argpObtained= isObtained;
return normalGlobalCrd;
}
// ----------------- ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
G4ThreeVector
G4MultiNavigator::GetLocalExitNormal(G4bool* argpObtained)
{
// If it is the mass navigator, then expect
G4ThreeVector normalGlobalCrd(0.0, 0.0, 0.0);
G4bool isObtained= false;
// These default values will be used if fNoLimitingStep== 0
if( fNoLimitingStep==1 )
{
// Only message the Navigator which limited the step!
normalGlobalCrd= fpNavigator[ fIdNavLimiting ]->GetLocalExitNormal( &isObtained);
*argpObtained= isObtained;
static G4ThreadLocal G4int numberWarnings= 0;
G4int noWarningsStart= 10, noModuloWarnings=100;
numberWarnings++;
if( (numberWarnings < noWarningsStart ) || (numberWarnings%noModuloWarnings==0) )
{
std::ostringstream message;
message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
JustWarning, message);
}
}
else
{
if( fNoLimitingStep > 1 )
{
// Does not make sense - cannot obtain *local* normal in several coordinate systems
std::ostringstream message;
message << "Cannot obtain normal in local coordinates of two or more coordinate systems." << G4endl;
G4Exception("G4MultiNavigator::GetGlobalExitNormal()", "GeomNav0002",
FatalException, message);
}
}
*argpObtained= isObtained;
return normalGlobalCrd;
}
// ----------------- ooooooOOOOOOOOOOOOOOOoooooo -------------------------------------
G4ThreeVector
G4MultiNavigator::GetLocalExitNormalAndCheck(const G4ThreeVector &, // point,
G4bool* obtained)
{
return G4MultiNavigator::GetLocalExitNormal( obtained);
}