source: trunk/source/geometry/navigation/src/G4BrentLocator.cc @ 1020

Last change on this file since 1020 was 985, checked in by garnier, 15 years ago

fichiers manquants

File size: 30.6 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer                                           *
4// *                                                                  *
5// * The  Geant4 software  is  copyright of the Copyright Holders  of *
6// * the Geant4 Collaboration.  It is provided  under  the terms  and *
7// * conditions of the Geant4 Software License,  included in the file *
8// * LICENSE and available at  http://cern.ch/geant4/license .  These *
9// * include a list of copyright holders.                             *
10// *                                                                  *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work  make  any representation or  warranty, express or implied, *
14// * regarding  this  software system or assume any liability for its *
15// * use.  Please see the license in the file  LICENSE  and URL above *
16// * for the full disclaimer and the limitation of liability.         *
17// *                                                                  *
18// * This  code  implementation is the result of  the  scientific and *
19// * technical work of the GEANT4 collaboration.                      *
20// * By using,  copying,  modifying or  distributing the software (or *
21// * any work based  on the software)  you  agree  to acknowledge its *
22// * use  in  resulting  scientific  publications,  and indicate your *
23// * acceptance of all terms of the Geant4 Software license.          *
24// ********************************************************************
25//
26// $Id: G4BrentLocator.cc,v 1.4 2008/11/14 18:26:35 gcosmo Exp $
27// GEANT4 tag $Name: geant4-09-02-cand-01 $
28//
29// Class G4BrentLocator implementation
30//
31// 27.10.08 - Tatiana Nikitina.
32// ---------------------------------------------------------------------------
33
34#include "G4BrentLocator.hh"
35#include "G4ios.hh"
36#include <iomanip>
37
38G4BrentLocator::G4BrentLocator(G4Navigator *theNavigator)
39 : G4VIntersectionLocator(theNavigator)
40{
41  // In case of too slow progress in finding Intersection Point
42  // intermediates Points on the Track must be stored.
43  // Initialise the array of Pointers [max_depth+1] to do this 
44 
45  G4ThreeVector zeroV(0.0,0.0,0.0);
46  for (G4int idepth=0; idepth<max_depth+1; idepth++ )
47  {
48    ptrInterMedFT[ idepth ] = new G4FieldTrack( zeroV, zeroV, 0., 0., 0., 0.);
49  }
50
51  // Counters for Locator
52
53  // Counter for Maximum Number Of Trial before Intersection Found
54  //
55  maxNumberOfStepsForIntersection=0;
56
57  // Counter for Number Of Calls to ReIntegrationEndPoint Method
58  //
59  maxNumberOfCallsToReIntegration=0; 
60  maxNumberOfCallsToReIntegration_depth=0; 
61}
62
63G4BrentLocator::~G4BrentLocator()
64{
65  for ( G4int idepth=0; idepth<max_depth+1; idepth++)
66  {
67    delete ptrInterMedFT[idepth];
68  }
69#ifdef G4DEBUG_FIELD
70  if(fVerboseLevel>0)
71  {
72    G4cout << "G4BrentLocator::Location with Max Number of Steps="
73           << maxNumberOfStepsForIntersection<<G4endl;
74    G4cout << "G4BrentLocator::ReIntegrateEndPoint was called "
75           << maxNumberOfCallsToReIntegration
76           << " times and for depth algorithm "
77           << maxNumberOfCallsToReIntegration_depth << " times." << G4endl;
78  }
79#endif
80}
81
82// --------------------------------------------------------------------------
83// G4bool G4PropagatorInField::LocateIntersectionPoint(
84//        const G4FieldTrack&       CurveStartPointVelocity,   //  A
85//        const G4FieldTrack&       CurveEndPointVelocity,     //  B
86//        const G4ThreeVector&      TrialPoint,                //  E
87//              G4FieldTrack&       IntersectedOrRecalculated  // Output
88//              G4bool&             recalculated)              // Out
89// --------------------------------------------------------------------------
90//
91// Function that returns the intersection of the true path with the surface
92// of the current volume (either the external one or the inner one with one
93// of the daughters:
94//
95//     A = Initial point
96//     B = another point
97//
98// Both A and B are assumed to be on the true path:
99//
100//     E is the first point of intersection of the chord AB with
101//     a volume other than A  (on the surface of A or of a daughter)
102//
103// Convention of Use :
104//     i) If it returns "true", then IntersectionPointVelocity is set
105//        to the approximate intersection point.
106//    ii) If it returns "false", no intersection was found.
107//        The validity of IntersectedOrRecalculated depends on 'recalculated'
108//        a) if latter is false, then IntersectedOrRecalculated is invalid.
109//        b) if latter is true,  then IntersectedOrRecalculated is
110//           the new endpoint, due to a re-integration.
111// --------------------------------------------------------------------------
112// NOTE: implementation taken from G4PropagatorInField
113//       New second order locator is added
114//
115G4bool G4BrentLocator::EstimateIntersectionPoint( 
116         const  G4FieldTrack&       CurveStartPointVelocity,       // A
117         const  G4FieldTrack&       CurveEndPointVelocity,         // B
118         const  G4ThreeVector&      TrialPoint,                    // E
119                G4FieldTrack&       IntersectedOrRecalculatedFT,   // Output
120                G4bool&             recalculatedEndPoint,          // Out
121                G4double&           fPreviousSafety,               // In/Out
122                G4ThreeVector&      fPreviousSftOrigin)            // In/Out
123             
124{   
125  // Find Intersection Point ( A, B, E )  of true path AB - start at E.
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;
132  G4ThreeVector CurrentE_Point = TrialPoint;
133  G4FieldTrack  ApproxIntersecPointV(CurveEndPointVelocity); // FT-Def-Construct
134  G4double      NewSafety = 0.0;
135  G4bool        last_AF_intersection = false; 
136
137  // G4bool final_section= true;  // Shows whether current section is last
138                                  // (i.e. B=full end)
139  G4bool first_section = true;
140  recalculatedEndPoint = false; 
141
142  G4bool restoredFullEndpoint = false;
143
144  G4int substep_no = 0;
145   
146  // Limits for substep number
147  //
148  const G4int max_substeps=   10000;  // Test 120  (old value 100 )
149  const G4int warn_substeps=   1000;  //      100 
150
151  // Statistics for substeps
152  //
153  static G4int max_no_seen= -1; 
154  static G4int trigger_substepno_print= warn_substeps - 20 ;
155
156  //-------------------------------------------------------------------------- 
157  //  Algorithm for the case if progress in founding intersection is too slow.
158  //  Process is defined too slow if after N=param_substeps advances on the
159  //  path, it will be only 'fraction_done' of the total length.
160  //  In this case the remaining length is divided in two half and
161  //  the loop is restarted for each half. 
162  //  If progress is still too slow, the division in two halfs continue
163  //  until 'max_depth'.
164  //--------------------------------------------------------------------------
165
166  const G4int param_substeps=100; // Test value for the maximum number
167                                  // of substeps
168  const G4double fraction_done=0.3;
169
170  G4bool Second_half = false;     // First half or second half of divided step
171
172  // We need to know this for the 'final_section':
173  // real 'final_section' or first half 'final_section'
174  // In algorithm it is considered that the 'Second_half' is true
175  // and it becomes false only if we are in the first-half of level
176  // depthness or if we are in the first section
177
178  G4int depth=0; // Depth counts how many subdivisions of initial step made
179
180#ifdef G4DEBUG_FIELD
181  static G4double tolerance= 1.0e-8; 
182  G4ThreeVector  StartPosition= CurveStartPointVelocity.GetPosition(); 
183  if( (TrialPoint - StartPosition).mag() < tolerance * mm ) 
184  {
185     G4cerr << "WARNING - G4PropagatorInField::LocateIntersectionPoint()"
186            << G4endl
187            << "          Intermediate F point is on top of starting point A."
188            << G4endl;
189     G4Exception("G4PropagatorInField::LocateIntersectionPoint()", 
190                 "IntersectionPointIsAtStart", JustWarning,
191                 "Intersection point F is exactly at start point A." ); 
192  }
193#endif
194
195  // Intermediates Points on the Track = Subdivided Points must be stored.
196  // Give the initial values to 'InterMedFt'
197  // Important is 'ptrInterMedFT[0]', it saves the 'EndCurvePoint'
198  //
199  *ptrInterMedFT[0] = CurveEndPointVelocity;
200  for (G4int idepth=1; idepth<max_depth+1; idepth++ )
201  {
202    *ptrInterMedFT[idepth]=CurveStartPointVelocity;
203  }
204
205  //Final_section boolean store
206  G4bool fin_section_depth[max_depth];
207  for (G4int idepth=0; idepth<max_depth; idepth++ )
208  {
209    fin_section_depth[idepth]=true;
210  }
211
212  // 'SubStartPoint' is needed to calculate the length of the divided step
213  //
214  G4FieldTrack SubStart_PointVelocity = CurveStartPointVelocity;
215   
216  do
217  {
218    G4int substep_no_p = 0;
219    G4bool sub_final_section = false; // the same as final_section,
220                                      // but for 'sub_section'
221    SubStart_PointVelocity = CurrentA_PointVelocity;
222    do // REPEAT param
223    {
224      G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition(); 
225      G4ThreeVector Point_B = CurrentB_PointVelocity.GetPosition();
226       
227      // F = a point on true AB path close to point E
228      // (the closest if possible)
229      //
230      if(substep_no_p==0)
231      {
232        ApproxIntersecPointV = GetChordFinderFor()
233                               ->ApproxCurvePointV( CurrentA_PointVelocity, 
234                                                    CurrentB_PointVelocity, 
235                                                    CurrentE_Point,
236                                                    GetEpsilonStepFor());
237          //  The above method is the key & most intuitive part ...
238      }
239#ifdef G4DEBUG_FIELD
240      if( ApproxIntersecPointV.GetCurveLength() > 
241          CurrentB_PointVelocity.GetCurveLength() * (1.0 + tolerance) )
242      {
243        G4cerr << "ERROR - G4PropagatorInField::LocateIntersectionPoint()"
244               << G4endl
245               << "        Intermediate F point is more advanced than"
246               << " endpoint B." << G4endl;
247        G4Exception("G4PropagatorInField::LocateIntersectionPoint()", 
248                    "IntermediatePointConfusion", FatalException,
249                    "Intermediate F point is past end B point" ); 
250      }
251#endif
252
253      G4ThreeVector CurrentF_Point= ApproxIntersecPointV.GetPosition();
254
255      // First check whether EF is small - then F is a good approx. point
256      // Calculate the length and direction of the chord AF
257      //
258      G4ThreeVector  ChordEF_Vector = CurrentF_Point - CurrentE_Point;
259
260      if ( ChordEF_Vector.mag2() <= sqr(GetDeltaIntersectionFor()) )
261      {
262        found_approximate_intersection = true;
263   
264        // Create the "point" return value
265        //
266        IntersectedOrRecalculatedFT = ApproxIntersecPointV;
267        IntersectedOrRecalculatedFT.SetPosition( CurrentE_Point );
268       
269        if ( GetAdjustementOfFoundIntersection() )
270        {
271          // Try to Get Correction of IntersectionPoint using SurfaceNormal()
272          // 
273          G4ThreeVector IP;
274          G4ThreeVector MomentumDir=ApproxIntersecPointV.GetMomentumDirection();
275          G4bool goodCorrection = AdjustmentOfFoundIntersection( Point_A,
276                                    CurrentE_Point, CurrentF_Point, MomentumDir,
277                                    last_AF_intersection, IP, NewSafety,
278                                    fPreviousSafety, fPreviousSftOrigin );
279          if ( goodCorrection )
280          {
281            IntersectedOrRecalculatedFT = ApproxIntersecPointV;
282            IntersectedOrRecalculatedFT.SetPosition(IP);
283          }
284        }
285       
286        // Note: in order to return a point on the boundary,
287        //       we must return E. But it is F on the curve.
288        //       So we must "cheat": we are using the position at point E
289        //       and the velocity at point F !!!
290        //
291        // This must limit the length we can allow for displacement!
292      }
293      else  // E is NOT close enough to the curve (ie point F)
294      {
295        // Check whether any volumes are encountered by the chord AF
296        // ---------------------------------------------------------
297        // First relocate to restore any Voxel etc information
298        // in the Navigator before calling ComputeStep()
299        //
300        GetNavigatorFor()->LocateGlobalPointWithinVolume( Point_A );
301
302        G4ThreeVector PointG;   // Candidate intersection point
303        G4double stepLengthAF; 
304        G4bool Intersects_AF = IntersectChord( Point_A,   CurrentF_Point,
305                                               NewSafety,fPreviousSafety,
306                                               fPreviousSftOrigin,
307                                               stepLengthAF,
308                                               PointG );
309        last_AF_intersection = Intersects_AF;
310        if( Intersects_AF )
311        {
312          // G is our new Candidate for the intersection point.
313          // It replaces  "E" and we will repeat the test to see if
314          // it is a good enough approximate point for us.
315          //       B    <- F
316          //       E    <- G
317          //
318          G4FieldTrack EndPoint = ApproxIntersecPointV;
319          ApproxIntersecPointV = GetChordFinderFor()->ApproxCurvePointS(
320                                 CurrentA_PointVelocity, CurrentB_PointVelocity,
321                                 EndPoint,CurrentE_Point, CurrentF_Point,PointG,
322                                 true, GetEpsilonStepFor() );
323          CurrentB_PointVelocity = EndPoint;
324          CurrentE_Point = PointG;
325           
326          // By moving point B, must take care if current
327          // AF has no intersection to try current FB!!
328          //
329          fin_section_depth[depth] = false;
330#ifdef G4VERBOSE
331          if( fVerboseLevel > 3 )
332          {
333            G4cout << "G4PiF::LI> Investigating intermediate point"
334                   << " at s=" << ApproxIntersecPointV.GetCurveLength()
335                   << " on way to full s="
336                   << CurveEndPointVelocity.GetCurveLength() << G4endl;
337          }
338#endif
339        }
340        else  // not Intersects_AF
341        { 
342          // In this case:
343          // There is NO intersection of AF with a volume boundary.
344          // We must continue the search in the segment FB!
345          //
346          GetNavigatorFor()->LocateGlobalPointWithinVolume( CurrentF_Point );
347
348          G4double stepLengthFB;
349          G4ThreeVector PointH;
350
351          // Check whether any volumes are encountered by the chord FB
352          // ---------------------------------------------------------
353
354          G4bool Intersects_FB = IntersectChord( CurrentF_Point, Point_B, 
355                                                 NewSafety,fPreviousSafety,
356                                                 fPreviousSftOrigin,
357                                                 stepLengthFB,
358                                                 PointH );
359          if( Intersects_FB )
360          { 
361            // There is an intersection of FB with a volume boundary
362            // H <- First Intersection of Chord FB
363
364            // H is our new Candidate for the intersection point.
365            // It replaces  "E" and we will repeat the test to see if
366            // it is a good enough approximate point for us.
367
368            // Note that F must be in volume volA  (the same as A)
369            // (otherwise AF would meet a volume boundary!)
370            //   A    <- F
371            //   E    <- H
372            //
373            CurrentA_PointVelocity = ApproxIntersecPointV;
374            ApproxIntersecPointV = GetChordFinderFor()->ApproxCurvePointS(
375                          CurrentA_PointVelocity,CurrentB_PointVelocity,
376                          CurrentA_PointVelocity,CurrentE_Point,Point_A,PointH,
377                          false,GetEpsilonStepFor());
378            CurrentE_Point = PointH;
379          }
380          else  // not Intersects_FB
381          {
382            // There is NO intersection of FB with a volume boundary
383
384            if( fin_section_depth[depth]  )
385            { 
386              // If B is the original endpoint, this means that whatever
387              // volume(s) intersected the original chord, none touch the
388              // smaller chords we have used.
389              // The value of 'IntersectedOrRecalculatedFT' returned is
390              // likely not valid
391
392              // Check on real final_section or SubEndSection
393              //
394              if( ((Second_half)&&(depth==0)) || (first_section) )
395              {
396                there_is_no_intersection = true;   // real final_section
397              }
398              else
399              {
400                // end of subsection, not real final section
401                // exit from the and go to the depth-1 level
402
403                substep_no_p = param_substeps+2;  // exit from the loop
404
405                // but 'Second_half' is still true because we need to find
406                // the 'CurrentE_point' for the next loop
407                //
408                Second_half = true; 
409                sub_final_section = true;
410              }
411            }
412            else
413            {
414              if(depth==0)
415              {
416                // We must restore the original endpoint
417                //
418                CurrentA_PointVelocity = CurrentB_PointVelocity;  // Got to B
419                CurrentB_PointVelocity = CurveEndPointVelocity;
420                SubStart_PointVelocity = CurrentA_PointVelocity;
421                restoredFullEndpoint = true;
422              }
423              else
424              {
425                // We must restore the depth endpoint
426                //
427                CurrentA_PointVelocity = CurrentB_PointVelocity;  // Got to B
428                CurrentB_PointVelocity =  *ptrInterMedFT[depth];
429                SubStart_PointVelocity = CurrentA_PointVelocity;
430                restoredFullEndpoint = true;
431              }
432            }
433          } // Endif (Intersects_FB)
434        } // Endif (Intersects_AF)
435
436        // Ensure that the new endpoints are not further apart in space
437        // than on the curve due to different errors in the integration
438        //
439        G4double linDistSq, curveDist; 
440        linDistSq = ( CurrentB_PointVelocity.GetPosition() 
441                    - CurrentA_PointVelocity.GetPosition() ).mag2(); 
442        curveDist = CurrentB_PointVelocity.GetCurveLength()
443                    - CurrentA_PointVelocity.GetCurveLength();
444
445        // Change this condition for very strict parameters of propagation
446        //
447        if( curveDist*curveDist*(1+2* GetEpsilonStepFor()) < linDistSq )
448        {
449          // Re-integrate to obtain a new B
450          //
451          G4FieldTrack newEndPointFT=
452                  ReEstimateEndpoint( CurrentA_PointVelocity,
453                                      CurrentB_PointVelocity,
454                                      linDistSq,    // to avoid recalculation
455                                      curveDist );
456          G4FieldTrack oldPointVelB = CurrentB_PointVelocity; 
457          CurrentB_PointVelocity = newEndPointFT;
458         
459          if ( (fin_section_depth[depth])           // real final section
460             &&( first_section  || ((Second_half)&&(depth==0)) ) )
461          {
462            recalculatedEndPoint = true;
463            IntersectedOrRecalculatedFT = newEndPointFT;
464              // So that we can return it, if it is the endpoint!
465          }
466        }
467        if( curveDist < 0.0 )
468        {
469          G4cerr << "ERROR - G4PropagatorInField::LocateIntersectionPoint()"
470                 << G4endl
471                 << "        Error in advancing propagation." << G4endl;
472          fVerboseLevel = 5; // Print out a maximum of information
473          printStatus( CurrentA_PointVelocity,  CurrentB_PointVelocity,
474                       -1.0, NewSafety,  substep_no );
475          G4cerr << "        Point A (start) is " << CurrentA_PointVelocity
476                 << G4endl;
477          G4cerr << "        Point B (end)   is " << CurrentB_PointVelocity
478                 << G4endl;
479          G4cerr << "        Curve distance is " << curveDist << G4endl;
480          G4cerr << G4endl
481                 << "The final curve point is not further along"
482                 << " than the original!" << G4endl;
483
484          if( recalculatedEndPoint )
485          {
486            G4cerr << "Recalculation of EndPoint was called with fEpsStep= "
487                   << GetEpsilonStepFor() << G4endl;
488          }
489          G4cerr.precision(20);
490          G4cerr << " Point A (Curve start)   is " << CurveStartPointVelocity
491                 << G4endl;
492          G4cerr << " Point B (Curve   end)   is " << CurveEndPointVelocity
493                 << G4endl;
494          G4cerr << " Point A (Current start) is " << CurrentA_PointVelocity
495                 << G4endl;
496          G4cerr << " Point B (Current end)   is " << CurrentB_PointVelocity
497                 << G4endl;
498          G4cerr << " Point S (Sub start)     is " << SubStart_PointVelocity
499                 << G4endl;
500          G4cerr << " Point E (Trial Point)   is " << CurrentE_Point
501                 << G4endl;
502          G4cerr << " Point F (Intersection)  is " << ApproxIntersecPointV
503                 << G4endl;
504          G4cerr << "        LocateIntersection parameters are : Substep no= "
505                 << substep_no << G4endl;
506          G4cerr << "        Substep depth no= "<< substep_no_p  << " Depth= "
507                 << depth << G4endl;
508
509          G4Exception("G4PropagatorInField::LocateIntersectionPoint()",
510                      "FatalError", FatalException,
511                      "Error in advancing propagation.");
512        }
513
514        if(restoredFullEndpoint)
515        {
516          fin_section_depth[depth] = restoredFullEndpoint;
517          restoredFullEndpoint = false;
518        }
519      } // EndIf ( E is close enough to the curve, ie point F. )
520        // tests ChordAF_Vector.mag() <= maximum_lateral_displacement
521
522#ifdef G4DEBUG_LOCATE_INTERSECTION 
523      if( substep_no >= trigger_substepno_print )
524      {
525        G4cout << "Difficulty in converging in "
526               << "G4PropagatorInField::LocateIntersectionPoint():"
527               << G4endl
528               << "    Substep no = " << substep_no << G4endl;
529        if( substep_no == trigger_substepno_print )
530        {
531          printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
532                       -1.0, NewSafety, 0);
533        }
534        G4cout << " State of point A: "; 
535        printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
536                     -1.0, NewSafety, substep_no-1, 0);
537        G4cout << " State of point B: "; 
538        printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
539                     -1.0, NewSafety, substep_no);
540      }
541#endif
542      substep_no++; 
543      substep_no_p++;
544
545    } while (  ( ! found_approximate_intersection )
546            && ( ! there_is_no_intersection )     
547            && ( substep_no_p <= param_substeps) );  // UNTIL found or
548                                                     // failed param substep
549    first_section = false;
550
551    if( (!found_approximate_intersection) && (!there_is_no_intersection) )
552    {
553      G4double did_len = std::abs( CurrentA_PointVelocity.GetCurveLength()
554                       - SubStart_PointVelocity.GetCurveLength()); 
555      G4double all_len = std::abs( CurrentB_PointVelocity.GetCurveLength()
556                       - SubStart_PointVelocity.GetCurveLength());
557   
558      G4double stepLengthAB;
559      G4ThreeVector PointGe;
560
561      // Check if progress is too slow and if it possible to go deeper,
562      // then halve the step if so
563      //
564      if ( ( did_len < fraction_done*all_len )
565        && (depth<max_depth) && (!sub_final_section) )
566      {
567        Second_half=false;
568        depth++;
569
570        G4double Sub_len = (all_len-did_len)/(2.);
571        G4FieldTrack start = CurrentA_PointVelocity;
572        G4MagInt_Driver* integrDriver =
573                         GetChordFinderFor()->GetIntegrationDriver();
574        integrDriver->AccurateAdvance(start, Sub_len, GetEpsilonStepFor());
575        *ptrInterMedFT[depth] = start;
576        CurrentB_PointVelocity = *ptrInterMedFT[depth];
577 
578        // Adjust 'SubStartPoint' to calculate the 'did_length' in next loop
579        //
580        SubStart_PointVelocity = CurrentA_PointVelocity;
581
582        // Find new trial intersection point needed at start of the loop
583        //
584        G4ThreeVector Point_A = CurrentA_PointVelocity.GetPosition();
585        G4ThreeVector SubE_point = CurrentB_PointVelocity.GetPosition();   
586     
587        GetNavigatorFor()->LocateGlobalPointWithinVolume(Point_A);
588        G4bool Intersects_AB = IntersectChord(Point_A, SubE_point,
589                                              NewSafety, fPreviousSafety,
590                                              fPreviousSftOrigin,stepLengthAB,
591                                              PointGe);
592        if( Intersects_AB )
593        {
594          last_AF_intersection = Intersects_AB;
595          CurrentE_Point = PointGe;
596          fin_section_depth[depth]=true;
597        }
598        else
599        {
600          // No intersection found for first part of curve
601          // (CurrentA,InterMedPoint[depth]). Go to the second part
602          //
603          Second_half = true;
604        }
605      } // if did_len
606
607      if( (Second_half)&&(depth!=0) )
608      {
609        // Second part of curve (InterMed[depth],Intermed[depth-1])                       )
610        // On the depth-1 level normally we are on the 'second_half'
611
612        Second_half = true;
613
614        //  Find new trial intersection point needed at start of the loop
615        //
616        SubStart_PointVelocity = *ptrInterMedFT[depth];
617        CurrentA_PointVelocity = *ptrInterMedFT[depth];
618        CurrentB_PointVelocity = *ptrInterMedFT[depth-1];
619         // Ensure that the new endpoints are not further apart in space
620        // than on the curve due to different errors in the integration
621        //
622        G4double linDistSq, curveDist; 
623        linDistSq = ( CurrentB_PointVelocity.GetPosition() 
624                    - CurrentA_PointVelocity.GetPosition() ).mag2(); 
625        curveDist = CurrentB_PointVelocity.GetCurveLength()
626                    - CurrentA_PointVelocity.GetCurveLength();
627        if( curveDist*curveDist*(1+2*GetEpsilonStepFor() ) < linDistSq )
628        {
629          // Re-integrate to obtain a new B
630          //
631          G4FieldTrack newEndPointFT=
632                  ReEstimateEndpoint( CurrentA_PointVelocity,
633                                      CurrentB_PointVelocity,
634                                      linDistSq,    // to avoid recalculation
635                                      curveDist );
636          G4FieldTrack oldPointVelB = CurrentB_PointVelocity; 
637          CurrentB_PointVelocity = newEndPointFT;
638          if (depth==1)
639          {
640            recalculatedEndPoint = true;
641            IntersectedOrRecalculatedFT = newEndPointFT;
642            // So that we can return it, if it is the endpoint!
643          }
644        }
645
646
647        G4ThreeVector Point_A    = CurrentA_PointVelocity.GetPosition();
648        G4ThreeVector SubE_point = CurrentB_PointVelocity.GetPosition();   
649        GetNavigatorFor()->LocateGlobalPointWithinVolume(Point_A);
650        G4bool Intersects_AB = IntersectChord(Point_A, SubE_point, NewSafety,
651                                              fPreviousSafety,
652                                               fPreviousSftOrigin,stepLengthAB, PointGe);
653        if( Intersects_AB )
654        {
655          last_AF_intersection = Intersects_AB;
656          CurrentE_Point = PointGe;
657        }
658       
659        depth--;
660        fin_section_depth[depth]=true;
661      }
662    }  // if(!found_aproximate_intersection)
663
664  } while ( ( ! found_approximate_intersection )
665            && ( ! there_is_no_intersection )     
666            && ( substep_no <= max_substeps) ); // UNTIL found or failed
667
668  if( substep_no > max_no_seen )
669  {
670    max_no_seen = substep_no; 
671    if( max_no_seen > warn_substeps )
672    {
673      trigger_substepno_print = max_no_seen-20; // Want to see last 20 steps
674    } 
675  }
676
677  if(  ( substep_no >= max_substeps)
678      && !there_is_no_intersection
679      && !found_approximate_intersection )
680  {
681    G4cerr << "WARNING - G4PropagatorInField::LocateIntersectionPoint()"
682           << G4endl
683           << "          Convergence is requiring too many substeps: "
684           << substep_no << G4endl;
685    G4cerr << "          Abandoning effort to intersect. " << G4endl;
686    G4cerr << "          Information on start & current step follows in cout."
687           << G4endl;
688    G4cout << "WARNING - G4PropagatorInField::LocateIntersectionPoint()"
689           << G4endl
690           << "          Convergence is requiring too many substeps: "
691           << substep_no << G4endl;
692    G4cout << "          Found intersection = "
693           << found_approximate_intersection << G4endl
694           << "          Intersection exists = "
695           << !there_is_no_intersection << G4endl;
696    G4cout << "          Start and Endpoint of Requested Step:" << G4endl;
697    printStatus( CurveStartPointVelocity, CurveEndPointVelocity,
698                 -1.0, NewSafety, 0);
699    G4cout << G4endl;
700    G4cout << "          'Bracketing' starting and endpoint of current Sub-Step"
701           << G4endl;
702    printStatus( CurrentA_PointVelocity, CurrentA_PointVelocity,
703                 -1.0, NewSafety, substep_no-1);
704    printStatus( CurrentA_PointVelocity, CurrentB_PointVelocity,
705                 -1.0, NewSafety, substep_no);
706    G4cout << G4endl;
707    G4cout.precision( 10 ); 
708    G4double done_len = CurrentA_PointVelocity.GetCurveLength(); 
709    G4double full_len = CurveEndPointVelocity.GetCurveLength();
710    G4cout << "ERROR - G4PropagatorInField::LocateIntersectionPoint()"
711           << G4endl
712           << "        Undertaken only length: " << done_len
713           << " out of " << full_len << " required." << G4endl;
714    G4cout << "        Remaining length = " << full_len - done_len << G4endl; 
715
716    G4Exception("G4PropagatorInField::LocateIntersectionPoint()",
717                "UnableToLocateIntersection", FatalException,
718                "Too many substeps while trying to locate intersection.");
719  }
720  else if( substep_no >= warn_substeps )
721  { 
722    G4int oldprc= G4cout.precision( 10 ); 
723    G4cout << "WARNING - G4PropagatorInField::LocateIntersectionPoint()"
724           << G4endl
725           << "          Undertaken length: " 
726           << CurrentB_PointVelocity.GetCurveLength(); 
727    G4cout << " - Needed: "  << substep_no << " substeps." << G4endl
728           << "          Warning level = " << warn_substeps
729           << " and maximum substeps = " << max_substeps << G4endl;
730    G4Exception("G4PropagatorInField::LocateIntersectionPoint()",
731                "DifficultyToLocateIntersection", JustWarning,
732                "Many substeps while trying to locate intersection.");
733    G4cout.precision( oldprc ); 
734  }
735  return  !there_is_no_intersection; //  Success or failure
736}
Note: See TracBrowser for help on using the repository browser.