Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4PathFinder Class Reference

#include <G4PathFinder.hh>

Public Member Functions

G4double ComputeStep (const G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4int navigatorId, G4int stepNo, G4double &pNewSafety, ELimited &limitedStep, G4FieldTrack &EndState, G4VPhysicalVolume *currentVolume)
 
void Locate (const G4ThreeVector &position, const G4ThreeVector &direction, G4bool relativeSearch=true)
 
void ReLocate (const G4ThreeVector &position)
 
void PrepareNewTrack (const G4ThreeVector &position, const G4ThreeVector &direction, G4VPhysicalVolume *massStartVol=0)
 
G4TouchableHandle CreateTouchableHandle (G4int navId) const
 
G4VPhysicalVolumeGetLocatedVolume (G4int navId) const
 
void SetChargeMomentumMass (G4double charge, G4double momentum, G4double pMass)
 
G4bool IsParticleLooping () const
 
G4double GetCurrentSafety () const
 
G4double GetMinimumStep () const
 
unsigned int GetNumberGeometriesLimitingStep () const
 
G4double ComputeSafety (const G4ThreeVector &globalPoint)
 
G4double ObtainSafety (G4int navId, G4ThreeVector &globalCenterPoint)
 
void EnableParallelNavigation (G4bool enableChoice=true)
 
G4int SetVerboseLevel (G4int lev=-1)
 
G4int GetMaxLoopCount () const
 
void SetMaxLoopCount (G4int new_max)
 
void MovePoint ()
 
G4double LastPreSafety (G4int navId, G4ThreeVector &globalCenterPoint, G4double &minSafety)
 
void PushPostSafetyToPreSafety ()
 
G4StringLimitedString (ELimited lim)
 

Static Public Member Functions

static G4PathFinderGetInstance ()
 

Protected Member Functions

G4double DoNextLinearStep (const G4FieldTrack &FieldTrack, G4double proposedStepLength)
 
G4double DoNextCurvedStep (const G4FieldTrack &FieldTrack, G4double proposedStepLength, G4VPhysicalVolume *pCurrentPhysVolume)
 
void WhichLimited ()
 
void PrintLimited ()
 
G4bool UseSafetyForOptimization (G4bool)
 
void ReportMove (const G4ThreeVector &OldV, const G4ThreeVector &NewV, const G4String &Quantity) const
 
 G4PathFinder ()
 
 ~G4PathFinder ()
 
G4NavigatorGetNavigator (G4int n) const
 

Detailed Description

Definition at line 61 of file G4PathFinder.hh.

Constructor & Destructor Documentation

◆ G4PathFinder()

G4PathFinder::G4PathFinder ( )
protected

Definition at line 70 of file G4PathFinder.cc.

71 : fEndState( G4ThreeVector(), G4ThreeVector(), 0., 0., 0., 0., 0.),
72 fFieldExertedForce(false),
73 fRelocatedPoint(true),
74 fLastStepNo(-1), fCurrentStepNo(-1),
75 fVerboseLevel(0)
76{
77 fpMultiNavigator= new G4MultiNavigator();
78
80 fpFieldPropagator = fpTransportManager->GetPropagatorInField();
81
83
84 fNoActiveNavigators= 0;
85 G4ThreeVector Big3Vector( kInfinity, kInfinity, kInfinity );
86 fLastLocatedPosition= Big3Vector;
87 fSafetyLocation= Big3Vector;
88 fPreSafetyLocation= Big3Vector;
89 fPreStepLocation= Big3Vector;
90
91 fPreSafetyMinValue= -1.0;
92 fMinSafety_PreStepPt= -1.0;
93 fMinSafety_atSafLocation= -1.0;
94 fMinStep= -1.0;
95 fTrueMinStep= -1.0;
96 fPreStepCenterRenewed= false;
97 fNewTrack= false;
98 fNoGeometriesLimiting= 0;
99
100 for( register int num=0; num< fMaxNav; ++num )
101 {
102 fpNavigator[num] = 0;
103 fLimitTruth[num] = false;
104 fLimitedStep[num] = kUndefLimited;
105 fCurrentStepSize[num] = -1.0;
106 fLocatedVolume[num] = 0;
107 fPreSafetyValues[num]= -1.0;
108 fCurrentPreStepSafety[num] = -1.0;
109 fNewSafetyComputed[num]= -1.0;
110 }
111}
@ kUndefLimited
CLHEP::Hep3Vector G4ThreeVector
G4double GetSurfaceTolerance() const
static G4GeometryTolerance * GetInstance()
static G4TransportationManager * GetTransportationManager()
G4PropagatorInField * GetPropagatorInField() const

◆ ~G4PathFinder()

G4PathFinder::~G4PathFinder ( )
protected

Definition at line 116 of file G4PathFinder.cc.

117{
118 delete fpMultiNavigator;
119}

Member Function Documentation

◆ ComputeSafety()

G4double G4PathFinder::ComputeSafety ( const G4ThreeVector globalPoint)

Definition at line 732 of file G4PathFinder.cc.

733{
734 // Recompute safety for the relevant point
735
736 G4double minSafety= kInfinity;
737
738 std::vector<G4Navigator*>::iterator pNavigatorIter;
739 pNavigatorIter= fpTransportManager->GetActiveNavigatorsIterator();
740
741 for( register G4int num=0; num<fNoActiveNavigators; ++pNavigatorIter,++num )
742 {
743 G4double safety = (*pNavigatorIter)->ComputeSafety( position,true );
744 if( safety < minSafety ) { minSafety = safety; }
745 fNewSafetyComputed[num]= safety;
746 }
747
748 fSafetyLocation= position;
749 fMinSafety_atSafLocation = minSafety;
750
751#ifdef G4DEBUG_PATHFINDER
752 if( fVerboseLevel > 1 )
753 {
754 G4cout << " G4PathFinder::ComputeSafety - returns "
755 << minSafety << " at location " << position << G4endl;
756 }
757#endif
758 return minSafety;
759}
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
std::vector< G4Navigator * >::iterator GetActiveNavigatorsIterator()
#define position
Definition: xmlparse.cc:605

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength(), G4SafetyHelper::ComputeSafety(), and ReLocate().

◆ ComputeStep()

G4double G4PathFinder::ComputeStep ( const G4FieldTrack pFieldTrack,
G4double  pCurrentProposedStepLength,
G4int  navigatorId,
G4int  stepNo,
G4double pNewSafety,
ELimited limitedStep,
G4FieldTrack EndState,
G4VPhysicalVolume currentVolume 
)

Definition at line 151 of file G4PathFinder.cc.

159{
160 G4double possibleStep= -1.0;
161
162#ifdef G4DEBUG_PATHFINDER
163 if( fVerboseLevel > 2 )
164 {
165 G4cout << " -------------------------" << G4endl;
166 G4cout << " G4PathFinder::ComputeStep - entered " << G4endl;
167 G4cout << " - stepNo = " << std::setw(4) << stepNo << " "
168 << " navigatorId = " << std::setw(2) << navigatorNo << " "
169 << " proposed step len = " << proposedStepLength << " " << G4endl;
170 G4cout << " PF::ComputeStep requested step "
171 << " from " << InitialFieldTrack.GetPosition()
172 << " dir " << InitialFieldTrack.GetMomentumDirection() << G4endl;
173 }
174#endif
175#ifdef G4VERBOSE
176 if( navigatorNo >= fNoActiveNavigators )
177 {
178 std::ostringstream message;
179 message << "Bad Navigator ID !" << G4endl
180 << " Requested Navigator ID = " << navigatorNo << G4endl
181 << " Number of active navigators = " << fNoActiveNavigators;
182 G4Exception("G4PathFinder::ComputeStep()", "GeomNav0002",
183 FatalException, message);
184 }
185#endif
186
187 if( fNewTrack || (stepNo != fLastStepNo) )
188 {
189 // This is a new track or a new step, so we must make the step
190 // ( else we can simply retrieve its results for this Navigator Id )
191
192 G4FieldTrack currentState= InitialFieldTrack;
193
194 fCurrentStepNo = stepNo;
195
196 // Check whether a process shifted the position
197 // since the last step -- by physics processes
198 //
199 G4ThreeVector newPosition = InitialFieldTrack.GetPosition();
200 G4ThreeVector moveVector= newPosition - fLastLocatedPosition;
201 G4double moveLenSq= moveVector.mag2();
202 if( moveLenSq > kCarTolerance * kCarTolerance )
203 {
204 G4ThreeVector newDirection = InitialFieldTrack.GetMomentumDirection();
205#ifdef G4DEBUG_PATHFINDER
206 if( fVerboseLevel > 2 )
207 {
208 G4double moveLen= std::sqrt( moveLenSq );
209 G4cout << " G4PathFinder::ComputeStep : Point moved since last step "
210 << " -- at step # = " << stepNo << G4endl
211 << " by " << moveLen << " to " << newPosition << G4endl;
212 }
213#endif
214 MovePoint(); // Unintentional changed -- ????
215
216 // Relocate to cope with this move -- else could abort !?
217 //
218 Locate( newPosition, newDirection );
219 }
220
221 // Check whether the particle have an (EM) field force exerting upon it
222 //
223 G4double particleCharge= currentState.GetCharge();
224
225 G4FieldManager* fieldMgr=0;
226 G4bool fieldExertsForce = false ;
227 if( (particleCharge != 0.0) )
228 {
229 fieldMgr= fpFieldPropagator->FindAndSetFieldManager( currentVolume );
230
231 // Protect for case where field manager has no field (= field is zero)
232 //
233 fieldExertsForce = (fieldMgr != 0)
234 && (fieldMgr->GetDetectorField() != 0);
235 }
236 fFieldExertedForce = fieldExertsForce; // Store for use in later calls
237 // referring to this 'step'.
238
239 fNoGeometriesLimiting= -1; // At start of track, no process limited step
240 if( fieldExertsForce )
241 {
242 DoNextCurvedStep( currentState, proposedStepLength, currentVolume );
243 //--------------
244 }else{
245 DoNextLinearStep( currentState, proposedStepLength );
246 //--------------
247 }
248 fLastStepNo= stepNo;
249
250#ifdef G4DEBUG_PATHFINDER
251 if ( (fNoGeometriesLimiting < 0)
252 || (fNoGeometriesLimiting > fNoActiveNavigators) )
253 {
254 std::ostringstream message;
255 message << "Number of geometries limiting the step not set." << G4endl
256 << " Number of geometries limiting step = "
257 << fNoGeometriesLimiting;
258 G4Exception("G4PathFinder::ComputeStep()",
259 "GeomNav0002", FatalException, message);
260 }
261#endif
262 }
263#ifdef G4DEBUG_PATHFINDER
264 else
265 {
266 if( proposedStepLength < fTrueMinStep ) // For 2nd+ geometry
267 {
268 std::ostringstream message;
269 message << "Problem in step size request." << G4endl
270 << " Error can be caused by incorrect process ordering."
271 << " Being requested to make a step which is shorter"
272 << " than the minimum Step " << G4endl
273 << " already computed for any Navigator/geometry during"
274 << " this tracking-step: " << G4endl
275 << " This can happen due to an error in process ordering."
276 << G4endl
277 << " Check that all physics processes are registered"
278 << G4endl
279 << " before all processes with a navigator/geometry."
280 << G4endl
281 << " If using pre-packaged physics list and/or"
282 << G4endl
283 << " functionality, please report this error."
284 << G4endl << G4endl
285 << " Additional information for problem: " << G4endl
286 << " Steps request/proposed = " << proposedStepLength
287 << G4endl
288 << " MinimumStep (true) = " << fTrueMinStep
289 << G4endl
290 << " MinimumStep (navraw) = " << fMinStep
291 << G4endl
292 << " Navigator raw return value" << G4endl
293 << " Requested step now = " << proposedStepLength
294 << G4endl
295 << " Difference min-req = "
296 << fTrueMinStep-proposedStepLength << G4endl
297 << " -- Step info> stepNo= " << stepNo
298 << " last= " << fLastStepNo
299 << " newTr= " << fNewTrack << G4endl;
300 G4Exception("G4PathFinder::ComputeStep()",
301 "GeomNav0003", FatalException, message);
302 }
303 else
304 {
305 // This is neither a new track nor a new step -- just another
306 // client accessing information for the current track, step
307 // We will simply retrieve the results of the synchronous
308 // stepping for this Navigator Id below.
309 //
310 if( fVerboseLevel > 1 )
311 {
312 G4cout << " G4P::CS -> Not calling DoNextLinearStep: "
313 << " stepNo= " << stepNo << " last= " << fLastStepNo
314 << " new= " << fNewTrack << " Step already done" << G4endl;
315 }
316 }
317 }
318#endif
319
320 fNewTrack= false;
321
322 // Prepare the information to return
323
324 pNewSafety = fCurrentPreStepSafety[ navigatorNo ];
325 limitedStep = fLimitedStep[ navigatorNo ];
326 fRelocatedPoint= false;
327
328 possibleStep= std::min(proposedStepLength, fCurrentStepSize[ navigatorNo ]);
329 EndState = fEndState; // now corrected for smaller step, if needed
330
331#ifdef G4DEBUG_PATHFINDER
332 if( fVerboseLevel > 0 )
333 {
334 G4cout << " G4PathFinder::ComputeStep returns "
335 << fCurrentStepSize[ navigatorNo ]
336 << " for Navigator " << navigatorNo
337 << " Limited step = " << limitedStep
338 << " Safety(mm) = " << pNewSafety / mm
339 << G4endl;
340 }
341#endif
342
343 return possibleStep;
344}
@ FatalException
bool G4bool
Definition: G4Types.hh:67
double mag2() const
const G4Field * GetDetectorField() const
G4double GetCharge() const
G4double DoNextLinearStep(const G4FieldTrack &FieldTrack, G4double proposedStepLength)
G4double DoNextCurvedStep(const G4FieldTrack &FieldTrack, G4double proposedStepLength, G4VPhysicalVolume *pCurrentPhysVolume)
void Locate(const G4ThreeVector &position, const G4ThreeVector &direction, G4bool relativeSearch=true)
void MovePoint()
G4FieldManager * FindAndSetFieldManager(G4VPhysicalVolume *pCurrentPhysVol)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
Definition: G4Exception.cc:41

Referenced by G4ImportanceProcess::AlongStepGetPhysicalInteractionLength(), G4WeightCutOffProcess::AlongStepGetPhysicalInteractionLength(), G4WeightWindowProcess::AlongStepGetPhysicalInteractionLength(), G4ParallelWorldProcess::AlongStepGetPhysicalInteractionLength(), G4ParallelWorldScoringProcess::AlongStepGetPhysicalInteractionLength(), G4CoupledTransportation::AlongStepGetPhysicalInteractionLength(), and G4FastSimulationManagerProcess::AlongStepGetPhysicalInteractionLength().

◆ CreateTouchableHandle()

G4TouchableHandle G4PathFinder::CreateTouchableHandle ( G4int  navId) const

Definition at line 765 of file G4PathFinder.cc.

766{
767#ifdef G4DEBUG_PATHFINDER
768 if( fVerboseLevel > 2 )
769 {
770 G4cout << "G4PathFinder::CreateTouchableHandle : navId = "
771 << navId << " -- " << GetNavigator(navId) << G4endl;
772 }
773#endif
774
775 G4TouchableHistory* touchHist;
776 touchHist= GetNavigator(navId) -> CreateTouchableHistory();
777
778 G4VPhysicalVolume* locatedVolume= fLocatedVolume[navId];
779 if( locatedVolume == 0 )
780 {
781 // Workaround to ensure that the touchable is fixed !! // TODO: fix
782
783 touchHist->UpdateYourself( locatedVolume, touchHist->GetHistory() );
784 }
785
786#ifdef G4DEBUG_PATHFINDER
787 if( fVerboseLevel > 2 )
788 {
789 G4String VolumeName("None");
790 if( locatedVolume ) { VolumeName= locatedVolume->GetName(); }
791 G4cout << " Touchable History created at address " << touchHist
792 << " volume = " << locatedVolume << " name= " << VolumeName
793 << G4endl;
794 }
795#endif
796
797 return G4TouchableHandle(touchHist);
798}
G4ReferenceCountedHandle< G4VTouchable > G4TouchableHandle
G4Navigator * GetNavigator(G4int n) const
const G4NavigationHistory * GetHistory() const
void UpdateYourself(G4VPhysicalVolume *pPhysVol, const G4NavigationHistory *history=0)
const G4String & GetName() const

Referenced by G4ImportanceProcess::PostStepDoIt(), G4WeightCutOffProcess::PostStepDoIt(), G4WeightWindowProcess::PostStepDoIt(), G4ParallelWorldProcess::PostStepDoIt(), G4ParallelWorldScoringProcess::PostStepDoIt(), G4CoupledTransportation::PostStepDoIt(), G4ImportanceProcess::StartTracking(), G4WeightCutOffProcess::StartTracking(), G4WeightWindowProcess::StartTracking(), G4ParallelWorldProcess::StartTracking(), and G4ParallelWorldScoringProcess::StartTracking().

◆ DoNextCurvedStep()

G4double G4PathFinder::DoNextCurvedStep ( const G4FieldTrack FieldTrack,
G4double  proposedStepLength,
G4VPhysicalVolume pCurrentPhysVolume 
)
protected

Definition at line 1137 of file G4PathFinder.cc.

1140{
1141 const G4double toleratedRelativeError= 1.0e-10;
1142 G4double minStep= kInfinity, newSafety=0.0;
1143 G4int numNav;
1144 G4FieldTrack fieldTrack= initialState;
1145 G4ThreeVector startPoint= initialState.GetPosition();
1146
1147#ifdef G4DEBUG_PATHFINDER
1148 G4int prc= G4cout.precision(9);
1149 if( fVerboseLevel > 2 )
1150 {
1151 G4cout << " G4PathFinder::DoNextCurvedStep ****** " << G4endl;
1152 G4cout << " Initial value of field track is " << fieldTrack
1153 << " and proposed step= " << proposedStepLength << G4endl;
1154 }
1155#endif
1156
1157 fPreStepCenterRenewed= true; // Always update PreSafety with PreStep point
1158
1159 if( fNoActiveNavigators > 1 )
1160 {
1161 // Calculate the safety values before making the step
1162
1163 G4double minSafety= kInfinity, safety;
1164 for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
1165 {
1166 safety= fpNavigator[numNav]->ComputeSafety( startPoint, false );
1167 fPreSafetyValues[numNav]= safety;
1168 fCurrentPreStepSafety[numNav]= safety;
1169 minSafety = std::min( safety, minSafety );
1170 }
1171
1172 // Save safety value, related position
1173
1174 fPreSafetyLocation= startPoint;
1175 fPreSafetyMinValue= minSafety;
1176 fPreStepLocation= startPoint;
1177 fMinSafety_PreStepPt= minSafety;
1178 }
1179
1180 // Allow Propagator In Field to do the hard work, calling G4MultiNavigator
1181 //
1182 minStep= fpFieldPropagator->ComputeStep( fieldTrack,
1183 proposedStepLength,
1184 newSafety,
1185 pCurrentPhysicalVolume );
1186
1187 // fieldTrack now contains the endpoint information
1188 //
1189 fEndState= fieldTrack;
1190 fMinStep= minStep;
1191 fTrueMinStep = std::min( minStep, proposedStepLength );
1192
1193 if( fNoActiveNavigators== 1 )
1194 {
1195 // Update the 'PreSafety' sphere - as any ComputeStep was called
1196 // (must be done anyway in field)
1197
1198 fPreSafetyValues[0]= newSafety;
1199 fPreSafetyLocation= startPoint;
1200 fPreSafetyMinValue= newSafety;
1201
1202 // Update the current 'PreStep' point's values - mandatory
1203 //
1204 fCurrentPreStepSafety[0]= newSafety;
1205 fPreStepLocation= startPoint;
1206 fMinSafety_PreStepPt= newSafety;
1207 }
1208
1209#ifdef G4DEBUG_PATHFINDER
1210 if( fVerboseLevel > 2 )
1211 {
1212 G4cout << "G4PathFinder::DoNextCurvedStep : " << G4endl
1213 << " initialState = " << initialState << G4endl
1214 << " and endState = " << fEndState << G4endl;
1215 G4cout << "G4PathFinder::DoNextCurvedStep : "
1216 << " minStep = " << minStep
1217 << " proposedStepLength " << proposedStepLength
1218 << " safety = " << newSafety << G4endl;
1219 }
1220#endif
1221 G4double currentStepSize; // = 0.0;
1222 if( minStep < proposedStepLength ) // if == , then a boundary found at end ??
1223 {
1224 // Recover the remaining information from MultiNavigator
1225 // especially regarding which Navigator limited the step
1226
1227 G4int noLimited= 0; // No geometries limiting step
1228 for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
1229 {
1230 G4double finalStep, lastPreSafety=0.0, minStepLast;
1231 ELimited didLimit;
1232 G4bool limited;
1233
1234 finalStep= fpMultiNavigator->ObtainFinalStep( numNav, lastPreSafety,
1235 minStepLast, didLimit );
1236
1237 // Calculate the step for this geometry, using the
1238 // final step (the only one which can differ.)
1239
1240 currentStepSize = fTrueMinStep;
1241 G4double diffStep= 0.0;
1242 if( (minStepLast != kInfinity) )
1243 {
1244 diffStep = (finalStep-minStepLast);
1245 if ( std::abs(diffStep) <= toleratedRelativeError * finalStep )
1246 {
1247 diffStep = 0.0;
1248 }
1249 currentStepSize += diffStep;
1250 }
1251 fCurrentStepSize[numNav] = currentStepSize;
1252
1253 // TODO: could refine the way to obtain safeties for > 1 geometries
1254 // - for pre step safety
1255 // notify MultiNavigator about new set of sub-steps
1256 // allow it to return this value in ObtainFinalStep
1257 // instead of lastPreSafety (or as well?)
1258 // - for final step start (available)
1259 // get final Step start from MultiNavigator
1260 // and corresponding safety values
1261 // and/or ALSO calculate ComputeSafety at endpoint
1262 // endSafety= fpNavigator[numNav]->ComputeSafety( endPoint );
1263
1264 fLimitedStep[numNav] = didLimit;
1265 fLimitTruth[numNav] = limited = (didLimit != kDoNot );
1266 if( limited ) { noLimited++; }
1267
1268#ifdef G4DEBUG_PATHFINDER
1269 G4bool StepError= (currentStepSize < 0)
1270 || ( (minStepLast != kInfinity) && (diffStep < 0) ) ;
1271 if( StepError || (fVerboseLevel > 2) )
1272 {
1273 G4String limitedString= LimitedString( fLimitedStep[numNav] );
1274
1275 G4cout << " G4PathFinder::ComputeStep. Geometry " << numNav
1276 << " step= " << fCurrentStepSize[numNav]
1277 << " from final-step= " << finalStep
1278 << " fTrueMinStep= " << fTrueMinStep
1279 << " minStepLast= " << minStepLast
1280 << " limited = " << (fLimitTruth[numNav] ? "YES" : " NO")
1281 << " ";
1282 G4cout << " status = " << limitedString << " #= " << didLimit
1283 << G4endl;
1284
1285 if( StepError )
1286 {
1287 std::ostringstream message;
1288 message << "Incorrect calculation of step size for one navigator"
1289 << G4endl
1290 << " currentStepSize = " << currentStepSize
1291 << ", diffStep= " << diffStep << G4endl
1292 << "ERROR in computing step size for this navigator.";
1293 G4Exception("G4PathFinder::DoNextCurvedStep",
1294 "GeomNav0003", FatalException, message);
1295 }
1296 }
1297#endif
1298 } // for num Navigators
1299
1300 fNoGeometriesLimiting= noLimited; // Save # processes limiting step
1301 }
1302 else if ( (minStep == proposedStepLength)
1303 || (minStep == kInfinity)
1304 || ( std::abs(minStep-proposedStepLength)
1305 < toleratedRelativeError * proposedStepLength ) )
1306 {
1307 // In case the step was not limited, use default responses
1308 // --> all Navigators
1309 // Also avoid problems in case of PathFinder using safety to optimise
1310 // - it is possible that the Navigators were not called
1311 // if the safety was already satisfactory.
1312 // (In that case calling ObtainFinalStep gives invalid results.)
1313
1314 currentStepSize= minStep;
1315 for( numNav=0; numNav < fNoActiveNavigators; ++numNav )
1316 {
1317 fCurrentStepSize[numNav] = minStep;
1318 // Safety for endpoint ?? // Can eventuall improve it -- see TODO above
1319 fLimitedStep[numNav] = kDoNot;
1320 fLimitTruth[numNav] = false;
1321 }
1322 fNoGeometriesLimiting= 0; // Save # processes limiting step
1323 }
1324 else // (minStep > proposedStepLength) and not (minStep == kInfinity)
1325 {
1326 std::ostringstream message;
1327 message << "Incorrect calculation of step size for one navigator." << G4endl
1328 << " currentStepSize = " << minStep << " is larger than "
1329 << " proposed StepSize = " << proposedStepLength << ".";
1330 G4Exception("G4PathFinder::DoNextCurvedStep()",
1331 "GeomNav0003", FatalException, message);
1332 }
1333
1334#ifdef G4DEBUG_PATHFINDER
1335 if( fVerboseLevel > 2 )
1336 {
1337 G4cout << " Exiting G4PathFinder::DoNextCurvedStep " << G4endl;
1338 PrintLimited();
1339 }
1340 G4cout.precision(prc);
1341#endif
1342
1343 return minStep;
1344}
ELimited
@ kDoNot
G4double ObtainFinalStep(G4int navigatorId, G4double &pNewSafety, G4double &minStepLast, ELimited &limitedStep)
virtual G4double ComputeSafety(const G4ThreeVector &globalpoint, const G4double pProposedMaxLength=DBL_MAX, const G4bool keepState=true)
G4String & LimitedString(ELimited lim)
void PrintLimited()
G4double ComputeStep(G4FieldTrack &pFieldTrack, G4double pCurrentProposedStepLength, G4double &pNewSafety, G4VPhysicalVolume *pPhysVol=0)

Referenced by ComputeStep().

◆ DoNextLinearStep()

G4double G4PathFinder::DoNextLinearStep ( const G4FieldTrack FieldTrack,
G4double  proposedStepLength 
)
protected

Definition at line 801 of file G4PathFinder.cc.

803{
804 std::vector<G4Navigator*>::iterator pNavigatorIter;
805 G4double safety= 0.0, step=0.0;
806 G4double minSafety= kInfinity, minStep;
807
808 const G4int IdTransport= 0; // Id of Mass Navigator !!
809 register G4int num=0;
810
811#ifdef G4DEBUG_PATHFINDER
812 if( fVerboseLevel > 2 )
813 {
814 G4cout << " G4PathFinder::DoNextLinearStep : entered " << G4endl;
815 G4cout << " Input field track= " << initialState << G4endl;
816 G4cout << " Requested step= " << proposedStepLength << G4endl;
817 }
818#endif
819
820 G4ThreeVector initialPosition= initialState.GetPosition();
821 G4ThreeVector initialDirection= initialState.GetMomentumDirection();
822
823 G4ThreeVector OriginShift = initialPosition - fPreSafetyLocation;
824 G4double MagSqShift = OriginShift.mag2() ;
825 G4double MagShift; // Only given value if it larger than minimum safety
826
827 // Potential optimisation using Maximum Value of safety!
828 // if( MagSqShift >= sqr(fPreSafetyMaxValue ) ){
829 // MagShift= kInfinity; // Not a useful value -- all will not use/ignore
830 // else
831 // MagShift= std::sqrt(MagSqShift) ;
832
833 MagShift= std::sqrt(MagSqShift) ;
834
835#ifdef G4PATHFINDER_OPTIMISATION
836
837 G4double fullSafety; // For all geometries, for prestep point
838
839 if( MagSqShift >= sqr(fPreSafetyMinValue ) )
840 {
841 fullSafety = 0.0 ;
842 }
843 else
844 {
845 fullSafety = fPreSafetyMinValue - MagShift;
846 }
847 if( proposedStepLength < fullSafety )
848 {
849 // Move is smaller than all safeties
850 // -> so we do not have to move the safety center
851
852 fPreStepCenterRenewed= false;
853
854 for( num=0; num< fNoActiveNavigators; ++num )
855 {
856 fCurrentStepSize[num]= kInfinity;
857 safety = std::max( 0.0, fPreSafetyValues[num] - MagShift);
858 minSafety= std::min( safety, minSafety );
859 fCurrentPreStepSafety[num]= safety;
860 }
861 minStep= kInfinity;
862
863#ifdef G4DEBUG_PATHFINDER
864 if( fVerboseLevel > 2 )
865 {
866 G4cout << "G4PathFinder::DoNextLinearStep : Quick Stepping. " << G4endl
867 << " proposedStepLength " << proposedStepLength
868 << " < (full) safety = " << fullSafety
869 << " at " << initialPosition
870 << G4endl;
871 }
872#endif
873 }
874 else
875#endif // End of G4PATHFINDER_OPTIMISATION 1
876 {
877 // Move is larger than at least one of the safeties
878 // -> so we must move the safety center!
879
880 fPreStepCenterRenewed= true;
881 pNavigatorIter= fpTransportManager-> GetActiveNavigatorsIterator();
882
883 minStep= kInfinity; // Not proposedStepLength;
884
885 for( num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
886 {
887 safety = std::max( 0.0, fPreSafetyValues[num] - MagShift);
888
889#ifdef G4PATHFINDER_OPTIMISATION
890 if( proposedStepLength <= safety ) // Should be just < safety ?
891 {
892 // The Step is guaranteed to be taken
893
894 step= kInfinity; // ComputeStep Would return this
895
896#ifdef G4DEBUG_PATHFINDER
897 G4cout.precision(8);
898 G4cout << "PathFinder::ComputeStep> small proposed step = "
899 << proposedStepLength
900 << " <= safety = " << safety << " for nav " << num
901 << " Step fully taken. " << G4endl;
902#endif
903 }
904 else
905#endif // End of G4PATHFINDER_OPTIMISATION 2
906 {
907#ifdef G4DEBUG_PATHFINDER
908 G4double previousSafety= safety;
909#endif
910 step= (*pNavigatorIter)->ComputeStep( initialPosition,
911 initialDirection,
912 proposedStepLength,
913 safety );
914 minStep = std::min( step, minStep);
915
916 // TODO: consider whether/how to reduce the proposed step
917 // to the latest minStep value - to reduce calculations
918
919#ifdef G4DEBUG_PATHFINDER
920 if( fVerboseLevel > 0)
921 {
922 G4cout.precision(8);
923 G4cout << "PathFinder::ComputeStep> long proposed step = "
924 << proposedStepLength
925 << " > safety = " << previousSafety
926 << " for nav " << num
927 << " . New safety = " << safety << " step= " << step
928 << G4endl;
929 }
930#endif
931 }
932 fCurrentStepSize[num] = step;
933
934 // Save safety value, must be done for all geometries "together"
935 // (even if not recomputed using call to ComputeStep)
936 // since they share the fPreSafetyLocation
937
938 fPreSafetyValues[num]= safety;
939 fCurrentPreStepSafety[num]= safety;
940
941 minSafety= std::min( safety, minSafety );
942
943#ifdef G4DEBUG_PATHFINDER
944 if( fVerboseLevel > 2 )
945 {
946 G4cout << "G4PathFinder::DoNextLinearStep : Navigator ["
947 << num << "] -- step size " << step << G4endl;
948 }
949#endif
950 }
951
952 // Only change these when safety is recalculated
953 // it is good/relevant only for safety calculations
954
955 fPreSafetyLocation= initialPosition;
956 fPreSafetyMinValue= minSafety;
957 } // end of else for if( proposedStepLength <= fullSafety)
958
959 // For use in Relocation, need PreStep point location, min-safety
960 //
961 fPreStepLocation= initialPosition;
962 fMinSafety_PreStepPt= minSafety;
963
964 fMinStep= minStep;
965
966 if( fMinStep == kInfinity )
967 {
968 minStep = proposedStepLength; // Use this below for endpoint !!
969 }
970 fTrueMinStep = minStep;
971
972 // Set the EndState
973
974 G4ThreeVector endPosition;
975
976 fEndState= initialState;
977 endPosition= initialPosition + minStep * initialDirection ;
978
979#ifdef G4DEBUG_PATHFINDER
980 if( fVerboseLevel > 1 )
981 {
982 G4cout << "G4PathFinder::DoNextLinearStep : "
983 << " initialPosition = " << initialPosition
984 << " and endPosition = " << endPosition<< G4endl;
985 }
986#endif
987
988 fEndState.SetPosition( endPosition );
989 fEndState.SetProperTimeOfFlight( -1.000 ); // Not defined YET
990
991 if( fNoActiveNavigators == 1 )
992 {
993 G4bool transportLimited = (fMinStep!= kInfinity);
994 fLimitTruth[IdTransport] = transportLimited;
995 fLimitedStep[IdTransport] = transportLimited ? kUnique : kDoNot;
996
997 // Set fNoGeometriesLimiting - as WhichLimited does
998 fNoGeometriesLimiting = transportLimited ? 1 : 0;
999 }
1000 else
1001 {
1002 WhichLimited();
1003 }
1004
1005#ifdef G4DEBUG_PATHFINDER
1006 if( fVerboseLevel > 2 )
1007 {
1008 G4cout << " G4PathFinder::DoNextLinearStep : exits returning "
1009 << minStep << G4endl;
1010 G4cout << " Endpoint values = " << fEndState << G4endl;
1011 G4cout << G4endl;
1012 }
1013#endif
1014
1015 return minStep;
1016}
@ kUnique
void SetProperTimeOfFlight(G4double nTOF)
void SetPosition(G4ThreeVector nPos)
void WhichLimited()
T sqr(const T &x)
Definition: templates.hh:145

Referenced by ComputeStep().

◆ EnableParallelNavigation()

void G4PathFinder::EnableParallelNavigation ( G4bool  enableChoice = true)

Definition at line 124 of file G4PathFinder.cc.

125{
126 G4Navigator *navigatorForPropagation=0, *massNavigator=0;
127
128 massNavigator= fpTransportManager->GetNavigatorForTracking();
129 if( enableChoice )
130 {
131 navigatorForPropagation= fpMultiNavigator;
132
133 // Enable SafetyHelper to use PF
134 //
135 fpTransportManager->GetSafetyHelper()->EnableParallelNavigation(true);
136 }
137 else
138 {
139 navigatorForPropagation= massNavigator;
140
141 // Disable SafetyHelper to use PF
142 //
143 fpTransportManager->GetSafetyHelper()->EnableParallelNavigation(false);
144 }
145 fpFieldPropagator->SetNavigatorForPropagating(navigatorForPropagation);
146}
void SetNavigatorForPropagating(G4Navigator *SimpleOrMultiNavigator)
void EnableParallelNavigation(G4bool parallel)
G4SafetyHelper * GetSafetyHelper() const
G4Navigator * GetNavigatorForTracking() const

Referenced by PrepareNewTrack().

◆ GetCurrentSafety()

G4double G4PathFinder::GetCurrentSafety ( ) const
inline

Definition at line 298 of file G4PathFinder.hh.

299{
300 return fMinSafety_PreStepPt;
301}

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength().

◆ GetInstance()

◆ GetLocatedVolume()

G4VPhysicalVolume * G4PathFinder::GetLocatedVolume ( G4int  navId) const
inline

Definition at line 275 of file G4PathFinder.hh.

276{
277 G4VPhysicalVolume* vol=0;
278 if( (navId < fMaxNav) && (navId >=0) ) { vol= fLocatedVolume[navId]; }
279 return vol;
280}

Referenced by G4FastSimulationManagerProcess::AtRestGetPhysicalInteractionLength(), and G4FastSimulationManagerProcess::PostStepGetPhysicalInteractionLength().

◆ GetMaxLoopCount()

G4int G4PathFinder::GetMaxLoopCount ( ) const
inline

◆ GetMinimumStep()

G4double G4PathFinder::GetMinimumStep ( ) const
inline

Definition at line 287 of file G4PathFinder.hh.

288{
289 return fMinStep;
290}

◆ GetNavigator()

G4Navigator * G4PathFinder::GetNavigator ( G4int  n) const
inlineprotected

Definition at line 308 of file G4PathFinder.hh.

309{
310 if( (n>fNoActiveNavigators)||(n<0)) { n=0; }
311 return fpNavigator[n];
312}

Referenced by CreateTouchableHandle(), and PrintLimited().

◆ GetNumberGeometriesLimitingStep()

unsigned int G4PathFinder::GetNumberGeometriesLimitingStep ( ) const
inline

Definition at line 292 of file G4PathFinder.hh.

293{
294 unsigned int noGeometries=fNoGeometriesLimiting;
295 return noGeometries;
296}

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength().

◆ IsParticleLooping()

G4bool G4PathFinder::IsParticleLooping ( ) const
inline

◆ LastPreSafety()

G4double G4PathFinder::LastPreSafety ( G4int  navId,
G4ThreeVector globalCenterPoint,
G4double minSafety 
)
inline

Definition at line 321 of file G4PathFinder.hh.

324{
325 globalCenterPoint= fPreSafetyLocation;
326 minSafety= fPreSafetyMinValue;
327 // navId = std::min( navId, fMaxNav-1 );
328 return fPreSafetyValues[ navId ];
329}

◆ LimitedString()

G4String & G4PathFinder::LimitedString ( ELimited  lim)

Definition at line 1346 of file G4PathFinder.cc.

1347{
1348 static G4String StrDoNot("DoNot"),
1349 StrUnique("Unique"),
1350 StrUndefined("Undefined"),
1351 StrSharedTransport("SharedTransport"),
1352 StrSharedOther("SharedOther");
1353
1354 G4String* limitedStr;
1355 switch ( lim )
1356 {
1357 case kDoNot: limitedStr= &StrDoNot; break;
1358 case kUnique: limitedStr = &StrUnique; break;
1359 case kSharedTransport: limitedStr= &StrSharedTransport; break;
1360 case kSharedOther: limitedStr = &StrSharedOther; break;
1361 default: limitedStr = &StrUndefined; break;
1362 }
1363 return *limitedStr;
1364}
@ kSharedOther
@ kSharedTransport

Referenced by DoNextCurvedStep(), and PrintLimited().

◆ Locate()

void G4PathFinder::Locate ( const G4ThreeVector position,
const G4ThreeVector direction,
G4bool  relativeSearch = true 
)

Definition at line 458 of file G4PathFinder.cc.

461{
462 // Locate the point in each geometry
463
464 std::vector<G4Navigator*>::iterator pNavIter=
465 fpTransportManager->GetActiveNavigatorsIterator();
466
467 G4ThreeVector lastEndPosition= fEndState.GetPosition();
468 G4ThreeVector moveVec = (position - lastEndPosition );
469 G4double moveLenSq= moveVec.mag2();
470 if( (!fNewTrack) && (!fRelocatedPoint)
471 && ( moveLenSq> kCarTolerance*kCarTolerance ) )
472 {
473 ReportMove( position, lastEndPosition, "Position" );
474 }
475 fLastLocatedPosition= position;
476
477#ifdef G4DEBUG_PATHFINDER
478 if( fVerboseLevel > 2 )
479 {
480 G4cout << G4endl;
481 G4cout << " G4PathFinder::Locate : entered " << G4endl;
482 G4cout << " -------------------- -------" << G4endl;
483 G4cout << " Locating at position " << position
484 << " with direction " << direction
485 << " relative= " << relative << G4endl;
486 if ( (fVerboseLevel > 1) || ( moveLenSq > 0.0) )
487 {
488 G4cout << " lastEndPosition = " << lastEndPosition
489 << " moveVec = " << moveVec
490 << " newTr = " << fNewTrack
491 << " relocated = " << fRelocatedPoint << G4endl;
492 }
493
494 G4cout << " Located at " << position ;
495 if( fNoActiveNavigators > 1 ) { G4cout << G4endl; }
496 }
497#endif
498
499 for ( register G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
500 {
501 // ... who limited the step ....
502
503 if( fLimitTruth[num] ) { (*pNavIter)->SetGeometricallyLimitedStep(); }
504
505 G4VPhysicalVolume *pLocated=
506 (*pNavIter)->LocateGlobalPointAndSetup( position, &direction,
507 relative,
508 false);
509 // Set the state related to the location
510 //
511 fLocatedVolume[num] = pLocated;
512
513 // Clear state related to the step
514 //
515 fLimitedStep[num] = kDoNot;
516 fCurrentStepSize[num] = 0.0;
517
518#ifdef G4DEBUG_PATHFINDER
519 if( fVerboseLevel > 2 )
520 {
521 G4cout << " - In world " << num << " geomLimStep= " << fLimitTruth[num]
522 << " gives volume= " << pLocated ;
523 if( pLocated )
524 {
525 G4cout << " name = '" << pLocated->GetName() << "'";
526 G4cout << " - CopyNo= " << pLocated->GetCopyNo();
527 }
528 G4cout << G4endl;
529 }
530#endif
531 }
532
533 fRelocatedPoint= false;
534}
G4ThreeVector GetPosition() const
void ReportMove(const G4ThreeVector &OldV, const G4ThreeVector &NewV, const G4String &Quantity) const

Referenced by ComputeStep(), G4SafetyHelper::Locate(), G4CoupledTransportation::PostStepDoIt(), and PrepareNewTrack().

◆ MovePoint()

void G4PathFinder::MovePoint ( )
inline

Definition at line 303 of file G4PathFinder.hh.

304{
305 fRelocatedPoint= true;
306}

Referenced by ComputeStep(), and PrepareNewTrack().

◆ ObtainSafety()

G4double G4PathFinder::ObtainSafety ( G4int  navId,
G4ThreeVector globalCenterPoint 
)
inline

Definition at line 314 of file G4PathFinder.hh.

315{
316 globalCenterPoint= fSafetyLocation;
317 // navId = std::min( navId, fMaxNav-1 );
318 return fNewSafetyComputed[ navId ];
319}

Referenced by G4CoupledTransportation::AlongStepGetPhysicalInteractionLength().

◆ PrepareNewTrack()

void G4PathFinder::PrepareNewTrack ( const G4ThreeVector position,
const G4ThreeVector direction,
G4VPhysicalVolume massStartVol = 0 
)

Definition at line 349 of file G4PathFinder.cc.

352{
353 // Key purposes:
354 // - Check and cache set of active navigators
355 // - Reset state for new track
356
357 G4int num=0;
358
360 // Switch PropagatorInField to use MultiNavigator
361
362 fpTransportManager->GetSafetyHelper()->InitialiseHelper();
363 // Reinitialise state of safety helper -- avoid problems with overlaps
364
365 fNewTrack= true;
366 this->MovePoint(); // Signal further that the last status is wiped
367
368 // Message the G4NavigatorPanel / Dispatcher to find active navigators
369 //
370 std::vector<G4Navigator*>::iterator pNavigatorIter;
371
372 fNoActiveNavigators= fpTransportManager-> GetNoActiveNavigators();
373 if( fNoActiveNavigators > fMaxNav )
374 {
375 std::ostringstream message;
376 message << "Too many active Navigators / worlds." << G4endl
377 << " Transportation Manager has "
378 << fNoActiveNavigators << " active navigators." << G4endl
379 << " This is more than the number allowed = "
380 << fMaxNav << " !";
381 G4Exception("G4PathFinder::PrepareNewTrack()", "GeomNav0002",
382 FatalException, message);
383 }
384
385 fpMultiNavigator->PrepareNavigators();
386 //------------------------------------
387
388 pNavigatorIter= fpTransportManager->GetActiveNavigatorsIterator();
389 for( num=0; num< fNoActiveNavigators; ++pNavigatorIter,++num )
390 {
391 // Keep information in C-array ... for creating touchables - at least
392
393 fpNavigator[num] = *pNavigatorIter;
394 fLimitTruth[num] = false;
395 fLimitedStep[num] = kDoNot;
396 fCurrentStepSize[num] = 0.0;
397 fLocatedVolume[num] = 0;
398 }
399 fNoGeometriesLimiting= 0; // At start of track, no process limited step
400
401 // In case of one geometry, the tracking will have done the locating!!
402
403 if( fNoActiveNavigators > 1 )
404 {
405 Locate( position, direction, false );
406 }
407 else
408 {
409 // Update state -- depending on the tracking's call to Mass Navigator
410
411 fLastLocatedPosition= position;
412 fLocatedVolume[0]= massStartVol; // This information must be given
413 // by transportation
414 fLimitedStep[0] = kDoNot;
415 fCurrentStepSize[0] = 0.0;
416 }
417
418 // Reset Safety Information -- as in case of overlaps this can cause
419 // inconsistencies ...
420 //
421 fMinSafety_PreStepPt= fPreSafetyMinValue= fMinSafety_atSafLocation= 0.0;
422
423 for( num=0; num< fNoActiveNavigators; ++num )
424 {
425 fPreSafetyValues[num]= 0.0;
426 fNewSafetyComputed[num]= 0.0;
427 fCurrentPreStepSafety[num] = 0.0;
428 }
429
430 // The first location for each Navigator must be non-relative
431 // or else call ResetStackAndState() for each Navigator
432
433 fRelocatedPoint= false;
434}
void EnableParallelNavigation(G4bool enableChoice=true)
void InitialiseHelper()

Referenced by G4ImportanceProcess::StartTracking(), G4WeightCutOffProcess::StartTracking(), G4WeightWindowProcess::StartTracking(), G4FastSimulationManagerProcess::StartTracking(), G4ParallelWorldProcess::StartTracking(), G4ParallelWorldScoringProcess::StartTracking(), and G4CoupledTransportation::StartTracking().

◆ PrintLimited()

void G4PathFinder::PrintLimited ( )
protected

Definition at line 1076 of file G4PathFinder.cc.

1077{
1078 // Report results -- for checking
1079
1080 G4cout << "G4PathFinder::PrintLimited reports: " ;
1081 G4cout << " Minimum step (true)= " << fTrueMinStep
1082 << " reported min = " << fMinStep
1083 << G4endl;
1084 if( (fCurrentStepNo <= 2) || (fVerboseLevel>=2) )
1085 {
1086 G4cout << std::setw(5) << " Step#" << " "
1087 << std::setw(5) << " NavId" << " "
1088 << std::setw(12) << " step-size " << " "
1089 << std::setw(12) << " raw-size " << " "
1090 << std::setw(12) << " pre-safety " << " "
1091 << std::setw(15) << " Limited / flag" << " "
1092 << std::setw(15) << " World " << " "
1093 << G4endl;
1094 }
1095 G4int num;
1096 for ( num= 0; num < fNoActiveNavigators; num++ )
1097 {
1098 G4double rawStep = fCurrentStepSize[num];
1099 G4double stepLen = fCurrentStepSize[num];
1100 if( stepLen > fTrueMinStep )
1101 {
1102 stepLen = fTrueMinStep; // did not limit (went as far as asked)
1103 }
1104 G4int oldPrec= G4cout.precision(9);
1105
1106 G4cout << std::setw(5) << fCurrentStepNo << " "
1107 << std::setw(5) << num << " "
1108 << std::setw(12) << stepLen << " "
1109 << std::setw(12) << rawStep << " "
1110 << std::setw(12) << fCurrentPreStepSafety[num] << " "
1111 << std::setw(5) << (fLimitTruth[num] ? "YES" : " NO") << " ";
1112 G4String limitedStr= LimitedString(fLimitedStep[num]);
1113 G4cout << " " << std::setw(15) << limitedStr << " ";
1114 G4cout.precision(oldPrec);
1115
1116 G4Navigator *pNav= GetNavigator( num );
1117 G4String WorldName( "Not-Set" );
1118 if (pNav)
1119 {
1120 G4VPhysicalVolume *pWorld= pNav->GetWorldVolume();
1121 if( pWorld )
1122 {
1123 WorldName = pWorld->GetName();
1124 }
1125 }
1126 G4cout << " " << WorldName ;
1127 G4cout << G4endl;
1128 }
1129
1130 if( fVerboseLevel > 4 )
1131 {
1132 G4cout << " G4PathFinder::PrintLimited - exiting. " << G4endl;
1133 }
1134}
G4VPhysicalVolume * GetWorldVolume() const

Referenced by DoNextCurvedStep(), and WhichLimited().

◆ PushPostSafetyToPreSafety()

void G4PathFinder::PushPostSafetyToPreSafety ( )

Definition at line 1366 of file G4PathFinder.cc.

1367{
1368 fPreSafetyLocation= fSafetyLocation;
1369 fPreSafetyMinValue= fMinSafety_atSafLocation;
1370 for( register G4int nav=0; nav < fNoActiveNavigators; ++nav )
1371 {
1372 fPreSafetyValues[nav]= fNewSafetyComputed[nav];
1373 }
1374}

◆ ReLocate()

void G4PathFinder::ReLocate ( const G4ThreeVector position)

Definition at line 536 of file G4PathFinder.cc.

537{
538 // Locate the point in each geometry
539
540 std::vector<G4Navigator*>::iterator pNavIter=
541 fpTransportManager->GetActiveNavigatorsIterator();
542
543#ifdef G4DEBUG_PATHFINDER
544
545 // Check that this relocation does not violate safety
546 // - at endpoint (computed from start point) AND
547 // - at last safety location (likely just called)
548
549 G4ThreeVector lastEndPosition= fEndState.GetPosition();
550
551 // Calculate end-point safety ...
552 //
553 G4double DistanceStartEnd= (lastEndPosition - fPreStepLocation).mag();
554 G4double endPointSafety_raw = fMinSafety_PreStepPt - DistanceStartEnd;
555 G4double endPointSafety_Est1 = std::max( 0.0, endPointSafety_raw );
556
557 // ... and check move from endpoint against this endpoint safety
558 //
559 G4ThreeVector moveVecEndPos = position - lastEndPosition;
560 G4double moveLenEndPosSq = moveVecEndPos.mag2();
561
562 // Check that move from endpoint of last step is within safety
563 // -- or check against last location or relocation ??
564 //
565 G4ThreeVector moveVecSafety= position - fSafetyLocation;
566 G4double moveLenSafSq= moveVecSafety.mag2();
567
568 G4double distCheckEnd_sq= ( moveLenEndPosSq - endPointSafety_Est1
569 *endPointSafety_Est1 );
570 G4double distCheckSaf_sq= ( moveLenSafSq - fMinSafety_atSafLocation
571 *fMinSafety_atSafLocation );
572
573 G4bool longMoveEnd = distCheckEnd_sq > 0.0;
574 G4bool longMoveSaf = distCheckSaf_sq > 0.0;
575
576 G4double revisedSafety= 0.0;
577
578 if( (!fNewTrack) && ( longMoveEnd && longMoveSaf ) )
579 {
580 // Recompute ComputeSafety for end position
581 //
582 revisedSafety= ComputeSafety(lastEndPosition);
583
584 const G4double kRadTolerance =
586 const G4double cErrorTolerance=1e-12;
587 // Maximum relative error from roundoff of arithmetic
588
589 G4double distCheckRevisedEnd= moveLenEndPosSq-revisedSafety*revisedSafety;
590
591 G4bool longMoveRevisedEnd= ( distCheckRevisedEnd > 0. ) ;
592
593 G4double moveMinusSafety= 0.0;
594 G4double moveLenEndPosition= std::sqrt( moveLenEndPosSq );
595 moveMinusSafety = moveLenEndPosition - revisedSafety;
596
597 if ( longMoveRevisedEnd && (moveMinusSafety > 0.0 )
598 && ( revisedSafety > 0.0 ) )
599 {
600 // Take into account possibility of roundoff error causing
601 // this apparent move further than safety
602
603 if( fVerboseLevel > 0 )
604 {
605 G4cout << " G4PF:Relocate> Ratio to revised safety is "
606 << std::fabs(moveMinusSafety)/revisedSafety << G4endl;
607 }
608
609 G4double absMoveMinusSafety= std::fabs(moveMinusSafety);
610 G4bool smallRatio= absMoveMinusSafety < kRadTolerance * revisedSafety ;
611 G4double maxCoordPos = std::max(
612 std::max( std::fabs(position.x()),
613 std::fabs(position.y())),
614 std::fabs(position.z()) );
615 G4bool smallValue= absMoveMinusSafety < cErrorTolerance * maxCoordPos;
616 if( ! (smallRatio || smallValue) )
617 {
618 G4cout << " G4PF:Relocate> Ratio to revised safety is "
619 << std::fabs(moveMinusSafety)/revisedSafety << G4endl;
620 G4cout << " Difference of move and safety is not very small."
621 << G4endl;
622 }
623 else
624 {
625 moveMinusSafety = 0.0;
626 longMoveRevisedEnd = false; // Numerical issue -- not too long!
627
628 G4cout << " Difference of move & safety is very small in magnitude, "
629 << absMoveMinusSafety << G4endl;
630 if( smallRatio )
631 {
632 G4cout << " ratio to safety " << revisedSafety
633 << " is " << absMoveMinusSafety / revisedSafety
634 << "smaller than " << kRadTolerance << " of safety ";
635 }
636 else
637 {
638 G4cout << " as fraction " << absMoveMinusSafety / maxCoordPos
639 << " of position vector max-coord " << maxCoordPos
640 << " smaller than " << cErrorTolerance ;
641 }
642 G4cout << " -- reset moveMinusSafety to "
643 << moveMinusSafety << G4endl;
644 }
645 }
646
647 if ( longMoveEnd && longMoveSaf
648 && longMoveRevisedEnd && (moveMinusSafety>0.0) )
649 {
650 G4int oldPrec= G4cout.precision(9);
651 std::ostringstream message;
652 message << "ReLocation is further than end-safety value." << G4endl
653 << " Moved from last endpoint by " << moveLenEndPosition
654 << " compared to end safety (from preStep point) = "
655 << endPointSafety_Est1 << G4endl
656 << " --> last PreSafety Location was " << fPreSafetyLocation
657 << G4endl
658 << " safety value = " << fPreSafetyMinValue << G4endl
659 << " --> last PreStep Location was " << fPreStepLocation
660 << G4endl
661 << " safety value = " << fMinSafety_PreStepPt << G4endl
662 << " --> last EndStep Location was " << lastEndPosition
663 << G4endl
664 << " safety value = " << endPointSafety_Est1
665 << " raw-value = " << endPointSafety_raw << G4endl
666 << " --> Calling again at this endpoint, we get "
667 << revisedSafety << " as safety value." << G4endl
668 << " --> last position for safety " << fSafetyLocation
669 << G4endl
670 << " its safety value = " << fMinSafety_atSafLocation
671 << G4endl
672 << " move from safety location = "
673 << std::sqrt(moveLenSafSq) << G4endl
674 << " again= " << moveVecSafety.mag() << G4endl
675 << " safety - Move-from-end= "
676 << revisedSafety - moveLenEndPosition
677 << " (negative is Bad.)" << G4endl
678 << " Debug: distCheckRevisedEnd = "
679 << distCheckRevisedEnd;
680 ReportMove( lastEndPosition, position, "Position" );
681 G4Exception("G4PathFinder::ReLocate", "GeomNav0003",
682 FatalException, message);
683 G4cout.precision(oldPrec);
684 }
685 }
686
687 if( fVerboseLevel > 2 )
688 {
689 G4cout << G4endl;
690 G4cout << " G4PathFinder::ReLocate : entered " << G4endl;
691 G4cout << " ---------------------- -------" << G4endl;
692 G4cout << " *Re*Locating at position " << position << G4endl;
693 // << " with direction " << direction
694 // << " relative= " << relative << G4endl;
695 if ( (fVerboseLevel > -1) || ( moveLenEndPosSq > 0.0) )
696 {
697 G4cout << " lastEndPosition = " << lastEndPosition
698 << " moveVec from step-end = " << moveVecEndPos
699 << " is new Track = " << fNewTrack
700 << " relocated = " << fRelocatedPoint << G4endl;
701 }
702 }
703#endif // G4DEBUG_PATHFINDER
704
705 for ( register G4int num=0; num< fNoActiveNavigators ; ++pNavIter,++num )
706 {
707 // ... none limited the step
708
709 (*pNavIter)->LocateGlobalPointWithinVolume( position );
710
711 // Clear state related to the step
712 //
713 fLimitedStep[num] = kDoNot;
714 fCurrentStepSize[num] = 0.0;
715 fLimitTruth[num] = false;
716 }
717
718 fLastLocatedPosition= position;
719 fRelocatedPoint= false;
720
721#ifdef G4DEBUG_PATHFINDER
722 if( fVerboseLevel > 2 )
723 {
724 G4cout << " G4PathFinder::ReLocate : exiting "
725 << " at position " << fLastLocatedPosition << G4endl << G4endl;
726 }
727#endif
728}
double mag() const
G4double GetRadialTolerance() const
G4double ComputeSafety(const G4ThreeVector &globalPoint)

Referenced by G4CoupledTransportation::PostStepDoIt(), and G4SafetyHelper::ReLocateWithinVolume().

◆ ReportMove()

void G4PathFinder::ReportMove ( const G4ThreeVector OldV,
const G4ThreeVector NewV,
const G4String Quantity 
) const
protected

Definition at line 436 of file G4PathFinder.cc.

439{
440 G4ThreeVector moveVec = ( NewVector - OldVector );
441
442 G4int prc= G4cerr.precision(12);
443 std::ostringstream message;
444 message << "Endpoint moved between value returned by ComputeStep()"
445 << " and call to Locate(). " << G4endl
446 << " Change of " << Quantity << " is "
447 << moveVec.mag() / mm << " mm long" << G4endl
448 << " and its vector is "
449 << (1.0/mm) * moveVec << " mm " << G4endl
450 << " Endpoint of ComputeStep() was " << OldVector << G4endl
451 << " and current position to locate is " << NewVector;
452 G4Exception("G4PathFinder::ReportMove()", "GeomNav1002",
453 JustWarning, message);
454 G4cerr.precision(prc);
455}
@ JustWarning
G4DLLIMPORT std::ostream G4cerr

Referenced by Locate(), and ReLocate().

◆ SetChargeMomentumMass()

void G4PathFinder::SetChargeMomentumMass ( G4double  charge,
G4double  momentum,
G4double  pMass 
)
inline

◆ SetMaxLoopCount()

void G4PathFinder::SetMaxLoopCount ( G4int  new_max)
inline

◆ SetVerboseLevel()

G4int G4PathFinder::SetVerboseLevel ( G4int  lev = -1)
inline

Definition at line 282 of file G4PathFinder.hh.

283{
284 G4int old= fVerboseLevel; fVerboseLevel= newLevel; return old;
285}

◆ UseSafetyForOptimization()

G4bool G4PathFinder::UseSafetyForOptimization ( G4bool  )
inlineprotected

◆ WhichLimited()

void G4PathFinder::WhichLimited ( )
protected

Definition at line 1018 of file G4PathFinder.cc.

1019{
1020 // Flag which processes limited the step
1021
1022 G4int num=-1, last=-1;
1023 G4int noLimited=0;
1024 ELimited shared= kSharedOther;
1025
1026 const G4int IdTransport= 0; // Id of Mass Navigator !!
1027
1028 // Assume that [IdTransport] is Mass / Transport
1029 //
1030 G4bool transportLimited = (fCurrentStepSize[IdTransport] == fMinStep)
1031 && ( fMinStep!= kInfinity) ;
1032
1033 if( transportLimited ) {
1034 shared= kSharedTransport;
1035 }
1036
1037 for ( num= 0; num < fNoActiveNavigators; num++ )
1038 {
1039 G4bool limitedStep;
1040
1041 G4double step= fCurrentStepSize[num];
1042
1043 limitedStep = ( std::fabs(step - fMinStep) < kCarTolerance )
1044 && ( step != kInfinity);
1045
1046 fLimitTruth[ num ] = limitedStep;
1047 if( limitedStep )
1048 {
1049 noLimited++;
1050 fLimitedStep[num] = shared;
1051 last= num;
1052 }
1053 else
1054 {
1055 fLimitedStep[num] = kDoNot;
1056 }
1057 }
1058 fNoGeometriesLimiting= noLimited; // Save # processes limiting step
1059
1060 if( (last > -1) && (noLimited == 1 ) )
1061 {
1062 fLimitedStep[ last ] = kUnique;
1063 }
1064
1065#ifdef G4DEBUG_PATHFINDER
1066 if( fVerboseLevel > 1 )
1067 {
1068 PrintLimited(); // --> for tracing
1069 if( fVerboseLevel > 4 ) {
1070 G4cout << " G4PathFinder::WhichLimited - exiting. " << G4endl;
1071 }
1072 }
1073#endif
1074}

Referenced by DoNextLinearStep().


The documentation for this class was generated from the following files: