If such an intersection exists, this function calculates the intersection point of the true path of the particle with the surface of the current volume (or of one of its daughters).
83{
84
85
86 G4bool found_approximate_intersection =
false;
87 G4bool there_is_no_intersection =
false;
88
89 G4FieldTrack CurrentA_PointVelocity = CurveStartPointVelocity;
90 G4FieldTrack CurrentB_PointVelocity = CurveEndPointVelocity;
92 G4bool validNormalAtE =
false;
94
95 G4FieldTrack ApproxIntersecPointV(CurveEndPointVelocity);
97 G4bool last_AF_intersection =
false;
98 G4bool final_section =
true;
99
100 recalculatedEndPoint = false;
101
102 G4bool restoredFullEndpoint =
false;
103
104 G4int substep_no = 0;
105
106
107
108 const G4int max_substeps = 100000000;
109 const G4int warn_substeps = 1000;
110
111
112
114
116
117#ifdef G4DEBUG_FIELD
119 G4ThreeVector StartPosition= CurveStartPointVelocity.GetPosition();
120 if( (TrialPoint - StartPosition).mag() < tolerance * CLHEP::mm )
121 {
122 G4Exception(
"G4SimpleLocator::EstimateIntersectionPoint()",
124 "Intersection point F is exactly at start point A." );
125 }
126#endif
127
128 do
129 {
132
133
134
135
138 CurrentB_PointVelocity,
139 CurrentE_Point,
141
142
143#ifdef G4DEBUG_FIELD
144 if( ApproxIntersecPointV.GetCurveLength() >
146 {
147 G4Exception(
"G4SimpleLocator::EstimateIntersectionPoint()",
149 "Intermediate F point is past end B point!" );
150 }
151#endif
152
153 G4ThreeVector CurrentF_Point = ApproxIntersecPointV.GetPosition();
154
155
156
157
158 G4ThreeVector ChordEF_Vector = CurrentF_Point - CurrentE_Point;
159
160 G4ThreeVector NewMomentumDir = ApproxIntersecPointV.GetMomentumDir();
161 G4double MomDir_dot_Norm = NewMomentumDir.
dot( NormalAtEntry ) ;
162
164
165#ifdef G4DEBUG_FIELD
168 NewMomentumDir, NormalAtEntry, validNormalAtE );
169#endif
170
171
172
173 G4bool adequate_angle = ( MomDir_dot_Norm >= 0.0 )
174 || (! validNormalAtE );
178 {
179 found_approximate_intersection = true;
180
181
182
183 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
184 IntersectedOrRecalculatedFT.SetPosition( CurrentE_Point );
185
187 {
188
189
191 G4ThreeVector MomentumDir= ApproxIntersecPointV.GetMomentumDirection();
193 CurrentE_Point, CurrentF_Point, MomentumDir,
194 last_AF_intersection, IP, NewSafety,
196
197 if ( goodCorrection )
198 {
199 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
200 IntersectedOrRecalculatedFT.SetPosition(IP);
201 }
202 }
203
204
205
206
207
208
209
210 }
211 else
212 {
213
214
215
216
217
219
222 G4bool usedNavigatorAF =
false;
224 CurrentF_Point,
225 NewSafety,
228 stepLengthAF,
229 PointG,
230 &usedNavigatorAF );
231 last_AF_intersection = Intersects_AF;
232 if( Intersects_AF )
233 {
234
235
236
237
238
239
240 CurrentB_PointVelocity = ApproxIntersecPointV;
241 CurrentE_Point = PointG;
242
243
244
245
246
247
248
251 validNormalAtE = validNormalLast;
252
253
254
255
256 final_section = false;
257
258#ifdef G4VERBOSE
260 {
261 G4cout <<
"G4PiF::LI> Investigating intermediate point"
262 << " at s=" << ApproxIntersecPointV.GetCurveLength()
263 << " on way to full s="
264 << CurveEndPointVelocity.GetCurveLength() <<
G4endl;
265 }
266#endif
267 }
268 else
269 {
270
271
272
273
275
278 G4bool usedNavigatorFB =
false;
279
280
281
282
286 stepLengthFB,
287 PointH, &usedNavigatorFB );
288 if( Intersects_FB )
289 {
290
291
292
293
294
295
296
297
298
299
300
301
302 CurrentA_PointVelocity = ApproxIntersecPointV;
303 CurrentE_Point = PointH;
304
305
306
307
308
309
310
313 validNormalAtE = validNormalLast;
314 }
315 else
316 {
317
318
319 if( final_section )
320 {
321
322
323
324
325
326
327 there_is_no_intersection = true;
328 }
329 else
330 {
331
332
333 CurrentA_PointVelocity = CurrentB_PointVelocity;
334 CurrentB_PointVelocity = CurveEndPointVelocity;
335 restoredFullEndpoint = true;
336 }
337 }
338 }
339
340
341
342
348
349
350
352 {
353
354
355 G4FieldTrack newEndPointFT =
357 CurrentB_PointVelocity,
358 linDistSq,
359 curveDist );
360 G4FieldTrack oldPointVelB = CurrentB_PointVelocity;
361 CurrentB_PointVelocity = newEndPointFT;
362
363 if( (final_section))
364 {
365 recalculatedEndPoint = true;
366 IntersectedOrRecalculatedFT = newEndPointFT;
367
368 }
369 }
370 if( curveDist < 0.0 )
371 {
373 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
374 -1.0, NewSafety, substep_no );
375 std::ostringstream message;
376 message <<
"Error in advancing propagation." <<
G4endl
377 << " Point A (start) is " << CurrentA_PointVelocity
379 << " Point B (end) is " << CurrentB_PointVelocity
381 <<
" Curve distance is " << curveDist <<
G4endl
383 << "The final curve point is not further along"
384 <<
" than the original!" <<
G4endl;
385
386 if( recalculatedEndPoint )
387 {
388 message << "Recalculation of EndPoint was called with fEpsStep= "
390 }
391 message.precision(20);
392 message << " Point A (Curve start) is " << CurveStartPointVelocity
394 << " Point B (Curve end) is " << CurveEndPointVelocity
396 << " Point A (Current start) is " << CurrentA_PointVelocity
398 << " Point B (Current end) is " << CurrentB_PointVelocity
400 << " Point E (Trial Point) is " << CurrentE_Point
402 << " Point F (Intersection) is " << ApproxIntersecPointV
404 << " LocateIntersection parameters are : Substep no= "
405 << substep_no;
406
407 G4Exception(
"G4SimpleLocator::EstimateIntersectionPoint()",
409 }
410
411 if ( restoredFullEndpoint )
412 {
413 final_section = restoredFullEndpoint;
414 restoredFullEndpoint = false;
415 }
416 }
417
418
419#ifdef G4DEBUG_LOCATE_INTERSECTION
420 G4int trigger_substepno_print= warn_substeps - 20;
421
422 if( substep_no >= trigger_substepno_print )
423 {
424 G4cout <<
"Difficulty in converging in "
425 << "G4SimpleLocator::EstimateIntersectionPoint():"
427 <<
" Substep no = " << substep_no <<
G4endl;
428 if( substep_no == trigger_substepno_print )
429 {
430 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
431 -1.0, NewSafety, 0);
432 }
433 G4cout <<
" State of point A: ";
434 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
435 -1.0, NewSafety, substep_no-1, 0);
436 G4cout <<
" State of point B: ";
437 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
438 -1.0, NewSafety, substep_no);
439 }
440#endif
441 ++substep_no;
442
443 } while ( ( ! found_approximate_intersection )
444 && ( ! there_is_no_intersection )
445 && ( substep_no <= max_substeps) );
446
447 if( substep_no > max_no_seen )
448 {
449 max_no_seen = substep_no;
450#ifdef G4DEBUG_LOCATE_INTERSECTION
451 if( max_no_seen > warn_substeps )
452 {
453 trigger_substepno_print = max_no_seen-20;
454 }
455#endif
456 }
457
458 if( ( substep_no >= max_substeps)
459 && !there_is_no_intersection
460 && !found_approximate_intersection )
461 {
462 G4cout <<
"ERROR - G4SimpleLocator::EstimateIntersectionPoint()" <<
G4endl
463 <<
" Start and Endpoint of Requested Step:" <<
G4endl;
464 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
465 -1.0, NewSafety, 0);
467 <<
" Start and end-point of current Sub-Step:" <<
G4endl;
468 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
469 -1.0, NewSafety, substep_no-1);
470 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
471 -1.0, NewSafety, substep_no);
472
473 std::ostringstream message;
474 message << "Convergence is requiring too many substeps: "
476 <<
" Abandoning effort to intersect." <<
G4endl
477 << " Found intersection = "
478 << found_approximate_intersection <<
G4endl
479 << " Intersection exists = "
480 << !there_is_no_intersection <<
G4endl;
481 message.precision(10);
483 G4double full_len = CurveEndPointVelocity.GetCurveLength();
484 message << " Undertaken only length: " << done_len
485 <<
" out of " << full_len <<
" required." <<
G4endl
486 << " Remaining length = " << full_len-done_len;
487
488 G4Exception(
"G4SimpleLocator::EstimateIntersectionPoint()",
490 }
491 else if( substep_no >= warn_substeps )
492 {
493 std::ostringstream message;
494 message.precision(10);
495
496 message <<
"Many substeps while trying to locate intersection." <<
G4endl
497 << " Undertaken length: "
499 <<
" - Needed: " << substep_no <<
" substeps." <<
G4endl
500 << " Warning level = " << warn_substeps
501 << " and maximum substeps = " << max_substeps;
502 G4Exception(
"G4SimpleLocator::EstimateIntersectionPoint()",
504 }
505 return !there_is_no_intersection;
506}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define fPreviousSftOrigin
CLHEP::Hep3Vector G4ThreeVector
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector ¤tEPoint, G4double epsStep)
G4double GetCurveLength() const
G4ThreeVector GetPosition() const
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
G4double fiDeltaIntersection
G4Navigator * GetNavigatorFor()
G4ChordFinder * GetChordFinderFor()
G4ThreeVector GetSurfaceNormal(const G4ThreeVector &CurrentInt_Point, G4bool &validNormal)
static void printStatus(const G4FieldTrack &startFT, const G4FieldTrack ¤tFT, G4double requestStep, G4double safety, G4int stepNum, std::ostream &oss, G4int verboseLevel)
void ReportTrialStep(G4int step_no, const G4ThreeVector &ChordAB_v, const G4ThreeVector &ChordEF_v, const G4ThreeVector &NewMomentumDir, const G4ThreeVector &NormalAtEntry, G4bool validNormal)
G4bool IntersectChord(const G4ThreeVector &StartPointA, const G4ThreeVector &EndPointB, G4double &NewSafety, G4double &PreviousSafety, G4ThreeVector &PreviousSftOrigin, G4double &LinearStepLength, G4ThreeVector &IntersectionPoint, G4bool *calledNavigator=nullptr)
G4double GetEpsilonStepFor()
G4FieldTrack ReEstimateEndpoint(const G4FieldTrack &CurrentStateA, const G4FieldTrack &EstimtdEndStateB, G4double linearDistSq, G4double curveDist)
G4bool GetAdjustementOfFoundIntersection()
G4bool AdjustmentOfFoundIntersection(const G4ThreeVector &A, const G4ThreeVector &CurrentE_Point, const G4ThreeVector &CurrentF_Point, const G4ThreeVector &MomentumDir, const G4bool IntersectAF, G4ThreeVector &IntersectionPoint, G4double &NewSafety, G4double &fPrevSafety, G4ThreeVector &fPrevSftOrigin)