101{
102
103
104 G4bool found_approximate_intersection =
false;
105 G4bool there_is_no_intersection =
false;
106
107 G4FieldTrack CurrentA_PointVelocity = CurveStartPointVelocity;
108 G4FieldTrack CurrentB_PointVelocity = CurveEndPointVelocity;
110 G4bool validNormalAtE =
false;
112
113 G4FieldTrack ApproxIntersecPointV(CurveEndPointVelocity);
115 G4bool last_AF_intersection =
false;
116
117
118
119 G4bool first_section =
true;
120 recalculatedEndPoint = false;
121
122 G4bool restoredFullEndpoint =
false;
123
125 G4int substep_no = 0;
126
127
128
129 const G4int max_substeps= 10000;
130 const G4int warn_substeps= 1000;
131
132
133
135
136
137
139
140
141
142
143
144
145
146
147
148
149
150 const G4int param_substeps = 50;
151
153
154 G4bool Second_half =
false;
155
157
158
159
160
161
162
163
165
166#ifdef G4DEBUG_FIELD
168 G4ThreeVector StartPosition = CurveStartPointVelocity.GetPosition();
169 if( (TrialPoint - StartPosition).mag() < tolerance * CLHEP::mm )
170 {
171 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
173 "Intersection point F is exactly at start point A." );
174 }
175#endif
176
177
178
179
180
181 *ptrInterMedFT[0] = CurveEndPointVelocity;
182 for (auto idepth=1; idepth<max_depth+1; ++idepth )
183 {
184 *ptrInterMedFT[idepth] = CurveStartPointVelocity;
185 }
186
187
188 G4bool fin_section_depth[max_depth];
189 for (auto idepth=0; idepth<max_depth; ++idepth )
190 {
191 fin_section_depth[idepth] = true;
192 }
193
194
195
196 G4FieldTrack SubStart_PointVelocity = CurveStartPointVelocity;
197
198 do
199 {
200 G4int substep_no_p = 0;
201 G4bool sub_final_section =
false;
202
203 SubStart_PointVelocity = CurrentA_PointVelocity;
204
205 do
206 {
209
210
211
212
213 if(substep_no_p==0)
214 {
217 CurrentB_PointVelocity,
218 CurrentE_Point,
220
221 }
222#ifdef G4DEBUG_FIELD
223 if( ApproxIntersecPointV.GetCurveLength() >
225 {
226 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
228 "Intermediate F point is past end B point" );
229 }
230#endif
231
232 G4ThreeVector CurrentF_Point = ApproxIntersecPointV.GetPosition();
233
234
235
236
237 G4ThreeVector ChordEF_Vector = CurrentF_Point - CurrentE_Point;
238 G4ThreeVector NewMomentumDir = ApproxIntersecPointV.GetMomentumDir();
239 G4double MomDir_dot_Norm = NewMomentumDir.
dot( NormalAtEntry ) ;
240
241#ifdef G4DEBUG_FIELD
243
245 ChordEF_Vector, NewMomentumDir, NormalAtEntry, validNormalAtE );
246#endif
247
249 adequate_angle = ( MomDir_dot_Norm >= 0.0 )
250 || (! validNormalAtE );
254 {
255 found_approximate_intersection = true;
256
257
258
259 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
260 IntersectedOrRecalculatedFT.SetPosition( CurrentE_Point );
261
263 {
264
265
267 G4ThreeVector MomentumDir=ApproxIntersecPointV.GetMomentumDirection();
269 CurrentE_Point, CurrentF_Point, MomentumDir,
270 last_AF_intersection, IP, NewSafety,
272 if ( goodCorrection )
273 {
274 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
275 IntersectedOrRecalculatedFT.SetPosition(IP);
276 }
277 }
278
279
280
281
282
283
284
285 }
286 else
287 {
288
289
290
291
292
294
297 G4bool usedNavigatorAF =
false;
301 stepLengthAF,
302 PointG,
303 &usedNavigatorAF);
304 last_AF_intersection = Intersects_AF;
305 if( Intersects_AF )
306 {
307
308
309
310
311
312
315 CurrentA_PointVelocity, CurrentB_PointVelocity,
316 EndPoint,CurrentE_Point, CurrentF_Point,PointG,
318 CurrentB_PointVelocity = EndPoint;
319 CurrentE_Point = PointG;
320
321
322
323
324
327 validNormalAtE = validNormalLast;
328
329
330
331
332 fin_section_depth[depth] = false;
333#ifdef G4VERBOSE
335 {
336 G4cout <<
"G4PiF::LI> Investigating intermediate point"
337 << " at s=" << ApproxIntersecPointV.GetCurveLength()
338 << " on way to full s="
339 << CurveEndPointVelocity.GetCurveLength() <<
G4endl;
340 }
341#endif
342 }
343 else
344 {
345
346
347
348
350
353 G4bool usedNavigatorFB =
false;
354
355
356
357
361 stepLengthFB,
362 PointH,
363 &usedNavigatorFB);
364 if( Intersects_FB )
365 {
366
367
368
369
370
371
372
373
374
375
376
377
380 CurrentA_PointVelocity,CurrentB_PointVelocity,
381 InterMed,CurrentE_Point,CurrentF_Point,PointH,
383 CurrentA_PointVelocity = InterMed;
384 CurrentE_Point = PointH;
385
386
387
390 validNormalAtE = validNormalLast;
391 }
392 else
393 {
394
395
396 if( fin_section_depth[depth] )
397 {
398
399
400
401
402
403
404
405
406 if( ((Second_half)&&(depth==0)) || (first_section) )
407 {
408 there_is_no_intersection = true;
409 }
410 else
411 {
412
413
414
415 substep_no_p = param_substeps+2;
416
417
418
419
420 Second_half = true;
421 sub_final_section = true;
422 }
423 }
424 else
425 {
426 if( depth==0 )
427 {
428
429
430 CurrentA_PointVelocity = CurrentB_PointVelocity;
431 CurrentB_PointVelocity = CurveEndPointVelocity;
432 SubStart_PointVelocity = CurrentA_PointVelocity;
435 CurrentB_PointVelocity,
436 CurrentE_Point,
438
439 restoredFullEndpoint = true;
440 ++restartB;
441 }
442 else
443 {
444
445
446 CurrentA_PointVelocity = CurrentB_PointVelocity;
447 CurrentB_PointVelocity = *ptrInterMedFT[depth];
448 SubStart_PointVelocity = CurrentA_PointVelocity;
451 CurrentB_PointVelocity,
452 CurrentE_Point,
454 restoredFullEndpoint = true;
455 ++restartB;
456 }
457 }
458 }
459 }
460
461
462
463
469
470
471
473 {
474
475
478 CurrentB_PointVelocity,
479 linDistSq,
480 curveDist );
482 CurrentB_PointVelocity = newEndPointFT;
483
484 if ( (fin_section_depth[depth])
485 &&( first_section || ((Second_half)&&(depth==0)) ) )
486 {
487 recalculatedEndPoint = true;
488 IntersectedOrRecalculatedFT = newEndPointFT;
489
490 }
491 }
492 if( curveDist < 0.0 )
493 {
495 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
496 -1.0, NewSafety, substep_no );
497 std::ostringstream message;
498 message <<
"Error in advancing propagation." <<
G4endl
499 <<
" Error in advancing propagation." <<
G4endl
500 << " Point A (start) is " << CurrentA_PointVelocity
502 << " Point B (end) is " << CurrentB_PointVelocity
504 <<
" Curve distance is " << curveDist <<
G4endl
506 << "The final curve point is not further along"
507 <<
" than the original!" <<
G4endl;
508
509 if( recalculatedEndPoint )
510 {
511 message << "Recalculation of EndPoint was called with fEpsStep= "
513 }
514 oldprc =
G4cerr.precision(20);
515 message << " Point A (Curve start) is " << CurveStartPointVelocity
517 << " Point B (Curve end) is " << CurveEndPointVelocity
519 << " Point A (Current start) is " << CurrentA_PointVelocity
521 << " Point B (Current end) is " << CurrentB_PointVelocity
523 << " Point S (Sub start) is " << SubStart_PointVelocity
525 << " Point E (Trial Point) is " << CurrentE_Point
527 << " Old Point F(Intersection) is " << CurrentF_Point
529 << " New Point F(Intersection) is " << ApproxIntersecPointV
531 << " LocateIntersection parameters are : Substep no= "
533 << " Substep depth no= "<< substep_no_p << " Depth= "
535 << " Restarted no= "<< restartB << " Epsilon= "
538 G4cerr.precision( oldprc );
539
540 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
542 }
543
544 if( restoredFullEndpoint )
545 {
546 fin_section_depth[depth] = restoredFullEndpoint;
547 restoredFullEndpoint = false;
548 }
549 }
550
551
552#ifdef G4DEBUG_LOCATE_INTERSECTION
553 G4int trigger_substepno_print= warn_substeps - 20 ;
554
555 if( substep_no >= trigger_substepno_print )
556 {
557 G4cout <<
"Difficulty in converging in "
558 << "G4BrentLocator::EstimateIntersectionPoint()"
560 <<
" Substep no = " << substep_no <<
G4endl;
561 if( substep_no == trigger_substepno_print )
562 {
563 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
564 -1.0, NewSafety, 0);
565 }
566 G4cout <<
" State of point A: ";
567 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
568 -1.0, NewSafety, substep_no-1, 0);
569 G4cout <<
" State of point B: ";
570 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
571 -1.0, NewSafety, substep_no);
572 }
573#endif
574 ++substep_no;
575 ++substep_no_p;
576
577 } while ( ( ! found_approximate_intersection )
578 && ( ! there_is_no_intersection )
579 && ( substep_no_p <= param_substeps) );
580
581 first_section = false;
582
583 if( (!found_approximate_intersection) && (!there_is_no_intersection) )
584 {
589
592
593
594
595
596 if ( ( did_len < fraction_done*all_len )
597 && (depth < max_depth) && (!sub_final_section) )
598 {
599 Second_half=false;
600 ++depth;
601
602 G4double Sub_len = (all_len-did_len)/(2.);
604 auto integrDriver =
607 *ptrInterMedFT[depth] = start;
608 CurrentB_PointVelocity = *ptrInterMedFT[depth];
609
610
611
612 SubStart_PointVelocity = CurrentA_PointVelocity;
613
614
615
618
623 PointGe);
624 if( Intersects_AB )
625 {
626 last_AF_intersection = Intersects_AB;
627 CurrentE_Point = PointGe;
628 fin_section_depth[depth] = true;
629
630
631
634 validNormalAtE = validNormalAB;
635 }
636 else
637 {
638
639
640
641 Second_half = true;
642 }
643 }
644
645 if( (Second_half)&&(depth!=0) )
646 {
647
648
649
650 Second_half = true;
651
652
653
654 SubStart_PointVelocity = *ptrInterMedFT[depth];
655 CurrentA_PointVelocity = *ptrInterMedFT[depth];
656 CurrentB_PointVelocity = *ptrInterMedFT[depth-1];
657
658
659
666 {
667
668
671 CurrentB_PointVelocity,
672 linDistSq,
673 curveDist );
675 CurrentB_PointVelocity = newEndPointFT;
676 if ( depth==1 )
677 {
678 recalculatedEndPoint = true;
679 IntersectedOrRecalculatedFT = newEndPointFT;
680
681 }
682 }
683
684
691 if( Intersects_AB )
692 {
693 last_AF_intersection = Intersects_AB;
694 CurrentE_Point = PointGe;
695
698 validNormalAtE = validNormalAB;
699 }
700
701 depth--;
702 fin_section_depth[depth]=true;
703 }
704 }
705
706 } while ( ( ! found_approximate_intersection )
707 && ( ! there_is_no_intersection )
708 && ( substep_no <= max_substeps) );
709
710 if( substep_no > max_no_seen )
711 {
712 max_no_seen = substep_no;
713#ifdef G4DEBUG_LOCATE_INTERSECTION
714 if( max_no_seen > warn_substeps )
715 {
716 trigger_substepno_print = max_no_seen-20;
717 }
718#endif
719 }
720
721 if( ( substep_no >= max_substeps)
722 && !there_is_no_intersection
723 && !found_approximate_intersection )
724 {
725 G4cout <<
"ERROR - G4BrentLocator::EstimateIntersectionPoint()" <<
G4endl
726 <<
" Start and end-point of requested Step:" <<
G4endl;
727 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
728 -1.0, NewSafety, 0);
729 G4cout <<
" Start and end-point of current Sub-Step:" <<
G4endl;
730 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
731 -1.0, NewSafety, substep_no-1);
732 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
733 -1.0, NewSafety, substep_no);
734 std::ostringstream message;
735 message <<
"Too many substeps!" <<
G4endl
736 << " Convergence is requiring too many substeps: "
738 <<
" Abandoning effort to intersect. " <<
G4endl
739 << " Found intersection = "
740 << found_approximate_intersection <<
G4endl
741 << " Intersection exists = "
742 << !there_is_no_intersection <<
G4endl;
743 oldprc =
G4cout.precision( 10 );
745 G4double full_len = CurveEndPointVelocity.GetCurveLength();
746 message << " Undertaken only length: " << done_len
747 <<
" out of " << full_len <<
" required." <<
G4endl
748 << " Remaining length = " << full_len - done_len;
749 G4cout.precision( oldprc );
750
751 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
753 }
754 else if( substep_no >= warn_substeps )
755 {
756 oldprc=
G4cout.precision( 10 );
757 std::ostringstream message;
758 message << "Many substeps while trying to locate intersection."
760 << " Undertaken length: "
762 <<
" - Needed: " << substep_no <<
" substeps." <<
G4endl
763 << " Warning level = " << warn_substeps
764 << " and maximum substeps = " << max_substeps;
765 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
767 G4cout.precision( oldprc );
768 }
769 return !there_is_no_intersection;
770}
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
#define fPreviousSftOrigin
G4GLOB_DLL std::ostream G4cerr
G4GLOB_DLL std::ostream G4cout
double dot(const Hep3Vector &) const
G4FieldTrack ApproxCurvePointV(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector ¤tEPoint, G4double epsStep)
G4FieldTrack ApproxCurvePointS(const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector ¤tEPoint, const G4ThreeVector ¤tFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep)
G4VIntegrationDriver * GetIntegrationDriver()
G4double GetCurveLength() const
G4ThreeVector GetPosition() const
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
virtual G4bool AccurateAdvance(G4FieldTrack &track, G4double hstep, G4double eps, G4double hinitial=0)=0
G4double fiDeltaIntersection
G4Navigator * GetNavigatorFor()
G4ChordFinder * GetChordFinderFor()
G4ThreeVector GetSurfaceNormal(const G4ThreeVector &CurrentInt_Point, G4bool &validNormal)
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()
G4double GetDeltaIntersectionFor()
void printStatus(const G4FieldTrack &startFT, const G4FieldTrack ¤tFT, G4double requestStep, G4double safety, G4int stepNum)
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)