00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "G4SafetyHelper.hh"
00036 #include "G4PathFinder.hh"
00037 #include "G4TransportationManager.hh"
00038 #include "G4Navigator.hh"
00039
00040 #include "globals.hh"
00041
00042 G4SafetyHelper::G4SafetyHelper()
00043 : fUseParallelGeometries(false),
00044 fFirstCall(true),
00045 fVerbose(0),
00046 fLastSafetyPosition(0.0,0.0,0.0),
00047 fLastSafety(0.0),
00048 fRecomputeFactor(0.0)
00049 {
00050 fpPathFinder= 0;
00051
00052
00053
00054
00055 fpMassNavigator= 0;
00056 fMassNavigatorId= -1;
00057 }
00058
00059 void G4SafetyHelper::InitialiseNavigator()
00060 {
00061 fpPathFinder= G4PathFinder::GetInstance();
00062
00063 G4TransportationManager* pTransportMgr=
00064 G4TransportationManager::GetTransportationManager();
00065
00066 fpMassNavigator = pTransportMgr->GetNavigatorForTracking();
00067
00068
00069
00070 G4VPhysicalVolume* worldPV = fpMassNavigator->GetWorldVolume();
00071 if( worldPV == 0 )
00072 {
00073 G4Exception("G4SafetyHelper::InitialiseNavigator",
00074 "InvalidNavigatorWorld", FatalException,
00075 "Found that existing tracking Navigator has NULL world");
00076 }
00077
00078 fMassNavigatorId = pTransportMgr->ActivateNavigator( fpMassNavigator );
00079 }
00080
00081 void G4SafetyHelper::InitialiseHelper()
00082 {
00083 fLastSafetyPosition = G4ThreeVector(0.0,0.0,0.0);
00084 fLastSafety = 0.0;
00085 if (fFirstCall) { InitialiseNavigator(); }
00086 fFirstCall = false;
00087 }
00088
00089 G4SafetyHelper::~G4SafetyHelper()
00090 {
00091 }
00092
00093 G4double
00094 G4SafetyHelper::CheckNextStep(const G4ThreeVector &position,
00095 const G4ThreeVector &direction,
00096 const G4double currentMaxStep,
00097 G4double& newSafety )
00098 {
00099
00100
00101 G4double linstep = fpMassNavigator->CheckNextStep( position,
00102 direction,
00103 currentMaxStep,
00104 newSafety);
00105 fLastSafetyPosition = position;
00106 fLastSafety = newSafety;
00107
00108
00109
00110
00111 return linstep;
00112 }
00113
00114 G4double G4SafetyHelper::ComputeSafety( const G4ThreeVector& position, G4double maxLength )
00115 {
00116 G4double newSafety;
00117
00118
00119
00120
00121 G4double moveLengthSq = (position-fLastSafetyPosition).mag2();
00122 G4double safeDistance = fRecomputeFactor*fLastSafety;
00123 if( (moveLengthSq > 0.0 )
00124 && (moveLengthSq >= safeDistance*safeDistance))
00125 {
00126 fLastSafetyPosition = position;
00127
00128 if( !fUseParallelGeometries )
00129 {
00130
00131 fLastSafety = fpMassNavigator->ComputeSafety(position, maxLength, true);
00132 }
00133 else
00134 {
00135
00136 fLastSafety = fpPathFinder->ComputeSafety(position);
00137 }
00138 newSafety = fLastSafety;
00139 }
00140 else
00141 {
00142
00143
00144 G4double moveLength = 0;
00145 if( moveLengthSq > 0.0 )
00146 {
00147 moveLength= std::sqrt(moveLengthSq);
00148 }
00149 newSafety = fLastSafety-moveLength;
00150 }
00151 return newSafety;
00152 }
00153
00154 void G4SafetyHelper::ReLocateWithinVolume( const G4ThreeVector &newPosition )
00155 {
00156 #ifdef G4VERBOSE
00157 if( fVerbose > 0 ) {
00158
00159 G4ThreeVector moveVec= newPosition - fLastSafetyPosition;
00160 if( moveVec.mag2() > sqr(fLastSafety) )
00161 {
00162
00163 G4ExceptionDescription ed;
00164 ed << " Safety Sphere: Radius = " << fLastSafety;
00165 ed << " Center = " << fLastSafetyPosition << G4endl;
00166 ed << " New Location : Move = " << moveVec.mag2();
00167 ed << " Position = " << newPosition << G4endl;
00168 G4Exception("G4SafetyHelper::ReLocateWithinVolume", "GeomNav999", JustWarning,
00169 "Unsafe Move> Asked to relocate beyond 'Safety sphere'.");
00170 }
00171 }
00172 #endif
00173
00174 if( !fUseParallelGeometries )
00175 {
00176 fpMassNavigator->LocateGlobalPointWithinVolume( newPosition );
00177 }
00178 else
00179 {
00180 fpPathFinder->ReLocate( newPosition );
00181 }
00182 }
00183
00184 void G4SafetyHelper::Locate( const G4ThreeVector& newPosition,
00185 const G4ThreeVector& newDirection)
00186 {
00187 if( !fUseParallelGeometries)
00188 {
00189 fpMassNavigator->LocateGlobalPointAndSetup(newPosition, &newDirection,
00190 true, false);
00191 }
00192 else
00193 {
00194 fpPathFinder->Locate( newPosition, newDirection );
00195 }
00196 }