124{
125
126
127 G4bool found_approximate_intersection =
false;
128 G4bool there_is_no_intersection =
false;
129
130 G4FieldTrack CurrentA_PointVelocity = CurveStartPointVelocity;
131 G4FieldTrack CurrentB_PointVelocity = CurveEndPointVelocity;
133 G4bool validNormalAtE =
false;
135
136 G4FieldTrack ApproxIntersecPointV(CurveEndPointVelocity);
138 G4bool last_AF_intersection =
false;
139
140
141
142 G4bool first_section =
true;
143 recalculatedEndPoint = false;
144
145 G4bool restoredFullEndpoint =
false;
146
148 G4int substep_no = 0;
149
150
151
152 const G4int max_substeps= 10000;
153 const G4int warn_substeps= 1000;
154
155
156
157 static G4int max_no_seen= -1;
158
159
160
162
163
164
165
166
167
168
169
170
171
172
173 const G4int param_substeps=50;
174
176
177 G4bool Second_half =
false;
178
180
181
182
183
184
185
186
188
189#ifdef G4DEBUG_FIELD
191 G4ThreeVector StartPosition= CurveStartPointVelocity.GetPosition();
192 if( (TrialPoint - StartPosition).mag() < tolerance * mm )
193 {
194 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
196 "Intersection point F is exactly at start point A." );
197 }
198#endif
199
200
201
202
203
204 *ptrInterMedFT[0] = CurveEndPointVelocity;
205 for (
G4int idepth=1; idepth<max_depth+1; idepth++ )
206 {
207 *ptrInterMedFT[idepth]=CurveStartPointVelocity;
208 }
209
210
211 G4bool fin_section_depth[max_depth];
212 for (
G4int idepth=0; idepth<max_depth; idepth++ )
213 {
214 fin_section_depth[idepth]=true;
215 }
216
217
218
219 G4FieldTrack SubStart_PointVelocity = CurveStartPointVelocity;
220
221 do
222 {
223 G4int substep_no_p = 0;
224 G4bool sub_final_section =
false;
225
226 SubStart_PointVelocity = CurrentA_PointVelocity;
227 do
228 {
231
232
233
234
235 if(substep_no_p==0)
236 {
239 CurrentB_PointVelocity,
240 CurrentE_Point,
242
243 }
244#ifdef G4DEBUG_FIELD
245 if( ApproxIntersecPointV.GetCurveLength() >
247 {
248 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
250 "Intermediate F point is past end B point" );
251 }
252#endif
253
254 G4ThreeVector CurrentF_Point= ApproxIntersecPointV.GetPosition();
255
256
257
258
259 G4ThreeVector ChordEF_Vector = CurrentF_Point - CurrentE_Point;
260 G4ThreeVector NewMomentumDir= ApproxIntersecPointV.GetMomentumDir();
261 G4double MomDir_dot_Norm= NewMomentumDir.
dot( NormalAtEntry ) ;
262
263#ifdef G4DEBUG_FIELD
265
267 ChordEF_Vector, NewMomentumDir, NormalAtEntry, validNormalAtE );
268#endif
269
271 adequate_angle = ( MomDir_dot_Norm >= 0.0 )
272 || (! validNormalAtE );
276 {
277 found_approximate_intersection = true;
278
279
280
281 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
282 IntersectedOrRecalculatedFT.SetPosition( CurrentE_Point );
283
285 {
286
287
289 G4ThreeVector MomentumDir=ApproxIntersecPointV.GetMomentumDirection();
291 CurrentE_Point, CurrentF_Point, MomentumDir,
292 last_AF_intersection, IP, NewSafety,
293 fPreviousSafety, fPreviousSftOrigin );
294 if ( goodCorrection )
295 {
296 IntersectedOrRecalculatedFT = ApproxIntersecPointV;
297 IntersectedOrRecalculatedFT.SetPosition(IP);
298 }
299 }
300
301
302
303
304
305
306
307 }
308 else
309 {
310
311
312
313
314
316
319 G4bool usedNavigatorAF =
false;
321 NewSafety,fPreviousSafety,
322 fPreviousSftOrigin,
323 stepLengthAF,
324 PointG,
325 &usedNavigatorAF);
326 last_AF_intersection = Intersects_AF;
327 if( Intersects_AF )
328 {
329
330
331
332
333
334
337 CurrentA_PointVelocity, CurrentB_PointVelocity,
338 EndPoint,CurrentE_Point, CurrentF_Point,PointG,
340 CurrentB_PointVelocity = EndPoint;
341 CurrentE_Point = PointG;
342
343
344
345
346
349 validNormalAtE = validNormalLast;
350
351
352
353
354 fin_section_depth[depth] = false;
355#ifdef G4VERBOSE
357 {
358 G4cout <<
"G4PiF::LI> Investigating intermediate point"
359 << " at s=" << ApproxIntersecPointV.GetCurveLength()
360 << " on way to full s="
361 << CurveEndPointVelocity.GetCurveLength() <<
G4endl;
362 }
363#endif
364 }
365 else
366 {
367
368
369
370
372
375 G4bool usedNavigatorFB =
false;
376
377
378
379
381 NewSafety,fPreviousSafety,
382 fPreviousSftOrigin,
383 stepLengthFB,
384 PointH,
385 &usedNavigatorFB);
386 if( Intersects_FB )
387 {
388
389
390
391
392
393
394
395
396
397
398
399
402 CurrentA_PointVelocity,CurrentB_PointVelocity,
403 InterMed,CurrentE_Point,CurrentF_Point,PointH,
405 CurrentA_PointVelocity = InterMed;
406 CurrentE_Point = PointH;
407
408
409
412 validNormalAtE= validNormalLast;
413 }
414 else
415 {
416
417
418 if( fin_section_depth[depth] )
419 {
420
421
422
423
424
425
426
427
428 if( ((Second_half)&&(depth==0)) || (first_section) )
429 {
430 there_is_no_intersection = true;
431 }
432 else
433 {
434
435
436
437 substep_no_p = param_substeps+2;
438
439
440
441
442 Second_half = true;
443 sub_final_section = true;
444 }
445 }
446 else
447 {
448 if(depth==0)
449 {
450
451
452 CurrentA_PointVelocity = CurrentB_PointVelocity;
453 CurrentB_PointVelocity = CurveEndPointVelocity;
454 SubStart_PointVelocity = CurrentA_PointVelocity;
457 CurrentB_PointVelocity,
458 CurrentE_Point,
460
461 restoredFullEndpoint = true;
462 restartB++;
463 }
464 else
465 {
466
467
468 CurrentA_PointVelocity = CurrentB_PointVelocity;
469 CurrentB_PointVelocity = *ptrInterMedFT[depth];
470 SubStart_PointVelocity = CurrentA_PointVelocity;
473 CurrentB_PointVelocity,
474 CurrentE_Point,
476 restoredFullEndpoint = true;
477 restartB++;
478 }
479 }
480 }
481 }
482
483
484
485
491
492
493
495 {
496
497
500 CurrentB_PointVelocity,
501 linDistSq,
502 curveDist );
504 CurrentB_PointVelocity = newEndPointFT;
505
506 if ( (fin_section_depth[depth])
507 &&( first_section || ((Second_half)&&(depth==0)) ) )
508 {
509 recalculatedEndPoint = true;
510 IntersectedOrRecalculatedFT = newEndPointFT;
511
512 }
513 }
514 if( curveDist < 0.0 )
515 {
517 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
518 -1.0, NewSafety, substep_no );
519 std::ostringstream message;
520 message <<
"Error in advancing propagation." <<
G4endl
521 <<
" Error in advancing propagation." <<
G4endl
522 << " Point A (start) is " << CurrentA_PointVelocity
524 << " Point B (end) is " << CurrentB_PointVelocity
526 <<
" Curve distance is " << curveDist <<
G4endl
528 << "The final curve point is not further along"
529 <<
" than the original!" <<
G4endl;
530
531 if( recalculatedEndPoint )
532 {
533 message << "Recalculation of EndPoint was called with fEpsStep= "
535 }
536 oldprc =
G4cerr.precision(20);
537 message << " Point A (Curve start) is " << CurveStartPointVelocity
539 << " Point B (Curve end) is " << CurveEndPointVelocity
541 << " Point A (Current start) is " << CurrentA_PointVelocity
543 << " Point B (Current end) is " << CurrentB_PointVelocity
545 << " Point S (Sub start) is " << SubStart_PointVelocity
547 << " Point E (Trial Point) is " << CurrentE_Point
549 << " Old Point F(Intersection) is " << CurrentF_Point
551 << " New Point F(Intersection) is " << ApproxIntersecPointV
553 << " LocateIntersection parameters are : Substep no= "
555 << " Substep depth no= "<< substep_no_p << " Depth= "
557 << " Restarted no= "<< restartB << " Epsilon= "
560 G4cerr.precision( oldprc );
561
562 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
564 }
565
566 if(restoredFullEndpoint)
567 {
568 fin_section_depth[depth] = restoredFullEndpoint;
569 restoredFullEndpoint = false;
570 }
571 }
572
573
574#ifdef G4DEBUG_LOCATE_INTERSECTION
575 static G4int trigger_substepno_print= warn_substeps - 20 ;
576
577 if( substep_no >= trigger_substepno_print )
578 {
579 G4cout <<
"Difficulty in converging in "
580 << "G4BrentLocator::EstimateIntersectionPoint()"
582 <<
" Substep no = " << substep_no <<
G4endl;
583 if( substep_no == trigger_substepno_print )
584 {
585 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
586 -1.0, NewSafety, 0);
587 }
588 G4cout <<
" State of point A: ";
589 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
590 -1.0, NewSafety, substep_no-1, 0);
591 G4cout <<
" State of point B: ";
592 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
593 -1.0, NewSafety, substep_no);
594 }
595#endif
596 substep_no++;
597 substep_no_p++;
598
599 } while ( ( ! found_approximate_intersection )
600 && ( ! there_is_no_intersection )
601 && ( substep_no_p <= param_substeps) );
602
603 first_section = false;
604
605 if( (!found_approximate_intersection) && (!there_is_no_intersection) )
606 {
611
614
615
616
617
618 if ( ( did_len < fraction_done*all_len )
619 && (depth<max_depth) && (!sub_final_section) )
620 {
621 Second_half=false;
622 depth++;
623
624 G4double Sub_len = (all_len-did_len)/(2.);
629 *ptrInterMedFT[depth] = start;
630 CurrentB_PointVelocity = *ptrInterMedFT[depth];
631
632
633
634 SubStart_PointVelocity = CurrentA_PointVelocity;
635
636
637
640
643 NewSafety, fPreviousSafety,
644 fPreviousSftOrigin,stepLengthAB,
645 PointGe);
646 if( Intersects_AB )
647 {
648 last_AF_intersection = Intersects_AB;
649 CurrentE_Point = PointGe;
650 fin_section_depth[depth]=true;
651
652
653
656 validNormalAtE= validNormalAB;
657 }
658 else
659 {
660
661
662
663 Second_half = true;
664 }
665 }
666
667 if( (Second_half)&&(depth!=0) )
668 {
669
670
671
672 Second_half = true;
673
674
675
676 SubStart_PointVelocity = *ptrInterMedFT[depth];
677 CurrentA_PointVelocity = *ptrInterMedFT[depth];
678 CurrentB_PointVelocity = *ptrInterMedFT[depth-1];
679
680
681
688 {
689
690
693 CurrentB_PointVelocity,
694 linDistSq,
695 curveDist );
697 CurrentB_PointVelocity = newEndPointFT;
698 if (depth==1)
699 {
700 recalculatedEndPoint = true;
701 IntersectedOrRecalculatedFT = newEndPointFT;
702
703 }
704 }
705
706
711 fPreviousSafety,
712 fPreviousSftOrigin,stepLengthAB, PointGe);
713 if( Intersects_AB )
714 {
715 last_AF_intersection = Intersects_AB;
716 CurrentE_Point = PointGe;
717
720 validNormalAtE = validNormalAB;
721 }
722
723 depth--;
724 fin_section_depth[depth]=true;
725 }
726 }
727
728 } while ( ( ! found_approximate_intersection )
729 && ( ! there_is_no_intersection )
730 && ( substep_no <= max_substeps) );
731
732 if( substep_no > max_no_seen )
733 {
734 max_no_seen = substep_no;
735#ifdef G4DEBUG_LOCATE_INTERSECTION
736 if( max_no_seen > warn_substeps )
737 {
738 trigger_substepno_print = max_no_seen-20;
739 }
740#endif
741 }
742
743 if( ( substep_no >= max_substeps)
744 && !there_is_no_intersection
745 && !found_approximate_intersection )
746 {
747 G4cout <<
"ERROR - G4BrentLocator::EstimateIntersectionPoint()" <<
G4endl
748 <<
" Start and end-point of requested Step:" <<
G4endl;
749 printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
750 -1.0, NewSafety, 0);
751 G4cout <<
" Start and end-point of current Sub-Step:" <<
G4endl;
752 printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
753 -1.0, NewSafety, substep_no-1);
754 printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
755 -1.0, NewSafety, substep_no);
756 std::ostringstream message;
757 message <<
"Too many substeps!" <<
G4endl
758 << " Convergence is requiring too many substeps: "
760 <<
" Abandoning effort to intersect. " <<
G4endl
761 << " Found intersection = "
762 << found_approximate_intersection <<
G4endl
763 << " Intersection exists = "
764 << !there_is_no_intersection <<
G4endl;
765 oldprc =
G4cout.precision( 10 );
767 G4double full_len = CurveEndPointVelocity.GetCurveLength();
768 message << " Undertaken only length: " << done_len
769 <<
" out of " << full_len <<
" required." <<
G4endl
770 << " Remaining length = " << full_len - done_len;
771 G4cout.precision( oldprc );
772
773 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
775 }
776 else if( substep_no >= warn_substeps )
777 {
778 oldprc=
G4cout.precision( 10 );
779 std::ostringstream message;
780 message << "Many substeps while trying to locate intersection."
782 << " Undertaken length: "
784 <<
" - Needed: " << substep_no <<
" substeps." <<
G4endl
785 << " Warning level = " << warn_substeps
786 << " and maximum substeps = " << max_substeps;
787 G4Exception(
"G4BrentLocator::EstimateIntersectionPoint()",
789 G4cout.precision( oldprc );
790 }
791 return !there_is_no_intersection;
792}
G4DLLIMPORT std::ostream G4cerr
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)
G4MagInt_Driver * GetIntegrationDriver()
G4double GetCurveLength() const
G4ThreeVector GetPosition() const
G4bool AccurateAdvance(G4FieldTrack &y_current, G4double hstep, G4double eps, G4double hinitial=0.0)
virtual void LocateGlobalPointWithinVolume(const G4ThreeVector &position)
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=0)
G4double GetEpsilonStepFor()
G4FieldTrack ReEstimateEndpoint(const G4FieldTrack &CurrentStateA, const G4FieldTrack &EstimtdEndStateB, G4double linearDistSq, G4double curveDist)
G4bool GetAdjustementOfFoundIntersection()
G4double GetDeltaIntersectionFor()
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)
void printStatus(const G4FieldTrack &startFT, const G4FieldTrack ¤tFT, G4double requestStep, G4double safety, G4int step)
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)