View | Details | Raw Unified | Return to problem 1696
Collapse All | Expand All

(-)History (+9 lines)
Lines 16-22 Link Here
16
     ----------------------------------------------------------
16
     ----------------------------------------------------------
17
     * Reverse chronological order (last date on top), please *
17
     * Reverse chronological order (last date on top), please *
18
     ----------------------------------------------------------
18
     ----------------------------------------------------------
19
Jan 16, 2015 J.Apostolakis                - field-V10-01-02 (fixed 2)
20
--------------------------
21
- Revert uninteded development in G4MagIntegratorDriver
19
22
23
Jan 15, 2015 J.Apostolakis                - field-V10-01-00, 01 (fixed)
24
--------------------------
25
- Small refinements in G4FieldTrack - access rest mass, avoid div by 0
26
    Avoid division by zero for Unit direction in FieldTrack 
27
    Added method to get Rest Mass
28
    
20
Nov 03, 2014 G.Cosmo                      - field-V10-00-04
29
Nov 03, 2014 G.Cosmo                      - field-V10-00-04
21
--------------------
30
--------------------
22
- Moved constructors and simple methods to in line in G4ChargeState and
31
- Moved constructors and simple methods to in line in G4ChargeState and
(-)include/G4FieldTrack.icc (-1 / +2 lines)
Lines 71-77 Link Here
71
  SixVector[4] = pMomentum.y(); 
71
  SixVector[4] = pMomentum.y(); 
72
  SixVector[5] = pMomentum.z(); 
72
  SixVector[5] = pMomentum.z(); 
73
73
74
  fMomentumDir = pMomentum.unit();
74
  fMomentumDir = (pMomentum.mag2() > 0.0)  ?
75
     pMomentum.unit() : G4ThreeVector( 0.0, 0.0, 0.0 ); 
75
76
76
  fDistanceAlongCurve= s_curve;
77
  fDistanceAlongCurve= s_curve;
77
78
(-)include/G4FieldTrack.hh (+1 lines)
Lines 123-128 Link Here
123
     inline G4double       GetProperTimeOfFlight() const;
123
     inline G4double       GetProperTimeOfFlight() const;
124
     inline G4double       GetKineticEnergy() const;
124
     inline G4double       GetKineticEnergy() const;
125
     inline G4double       GetCharge() const;
125
     inline G4double       GetCharge() const;
126
     inline G4double       GetRestMass() const { return fRestMass_c2; }
126
       // Accessors.
127
       // Accessors.
127
128
128
     inline void SetPosition(G4ThreeVector nPos); 
129
     inline void SetPosition(G4ThreeVector nPos); 
(-)src/G4FieldTrack.cc (-1 / +2 lines)
Lines 42-48 Link Here
42
        << G4ThreeVector(SixV[3], SixV[4], SixV[5]).mag(); // mom magnitude
42
        << G4ThreeVector(SixV[3], SixV[4], SixV[5]).mag(); // mom magnitude
43
     os << " Ekin= " << SixVec.fKineticEnergy ;
43
     os << " Ekin= " << SixVec.fKineticEnergy ;
44
     os << " m0= " <<   SixVec.fRestMass_c2;
44
     os << " m0= " <<   SixVec.fRestMass_c2;
45
     os << " Pdir= " <<  SixVec.fMomentumDir.mag(); 
45
     os << " Pdir= " <<  SixVec.fMomentumDir.mag();
46
     os << " PolV= " << SixVec.GetPolarization(); 
46
     os << " l= " <<    SixVec.GetCurveLength();
47
     os << " l= " <<    SixVec.GetCurveLength();
47
     os << " t_lab= " << SixVec.fLabTimeOfFlight; 
48
     os << " t_lab= " << SixVec.fLabTimeOfFlight; 
48
     os << " t_proper= " << SixVec.fProperTimeOfFlight ; 
49
     os << " t_proper= " << SixVec.fProperTimeOfFlight ; 
(-)src/G4MagIntegratorDriver.cc (-54 / +4 lines)
Lines 552-581 Link Here
552
  static G4ThreadLocal G4int tot_no_trials=0; 
552
  static G4ThreadLocal G4int tot_no_trials=0; 
553
  const G4int max_trials=100; 
553
  const G4int max_trials=100; 
554
554
555
  const G4double max_reduction = 0.1 ; // Largest_reduction_factor for step size
556
  const G4double local_Pow_shrink = 0.5*GetPshrnk(); 
557
558
  // We choose to use a linear approximation of the Taylor series
559
  //       ( 1 + x ) ^ p =  1 + p * x - 0.5 * p * (1-p) x^2  + O( x^3 ) 
560
  // if the second order term is smaller than
561
  const G4double acc_limit= 0.01;
562
  
563
  // This limit is reached when
564
  //      0.5 * p * (1-p) x^2 = acc_limit
565
  // ie
566
  //            p * (1-p) x^2 = acc_limit * 2.0
567
568
  // NEW constants -- here for now only
569
  // The following value is the value of 'x' at which this limit is reached:
570
  const G4double  limit_fac = 0.5 * local_Pow_shrink * (1.0 - local_Pow_shrink) ;
571
  //  linear_limit_fac
572
  // To avoid the division here by limit_fac, we check below that
573
  //            limit_fac * x^2 < acc_limt 
574
575
  const G4double err_limit = std::pow( max_reduction / GetSafety(), 2/GetPshrnk() ); 
576
  // This is constant when the value of the 'shrink' power is constant
577
  //  TODO: These should become data members ( this one is expensive to calculate! )
578
579
  G4ThreeVector Spin(y[9],y[10],y[11]);
555
  G4ThreeVector Spin(y[9],y[10],y[11]);
580
  G4double   spin_mag2 =Spin.mag2() ;
556
  G4double   spin_mag2 =Spin.mag2() ;
581
  G4bool     hasSpin= (spin_mag2 > 0.0); 
557
  G4bool     hasSpin= (spin_mag2 > 0.0); 
Lines 616-654 Link Here
616
    }
592
    }
617
593
618
    if ( errmax_sq <= 1.0 )  { break; } // Step succeeded. 
594
    if ( errmax_sq <= 1.0 )  { break; } // Step succeeded. 
595
619
    // Step failed; compute the size of retrial Step.
596
    // Step failed; compute the size of retrial Step.
597
    htemp = GetSafety()*h* std::pow( errmax_sq, 0.5*GetPshrnk() );
620
598
621
#if 1  // NEW_METHOD
599
    if (htemp >= 0.1*h)  { h = htemp; }  // Truncation error too large,
622
    // New method of calculation - avoids power if step is very small
600
    else  { h = 0.1*h; }                 // reduce stepsize, but no more
623
    G4double hnew = 0.0; 
624
    G4double x = errmax_sq - 1.0; 
625
    if (errmax_sq >= err_limit)  { 
626
       // if( limit_fac * x * x < acc_limt ) {
627
       //   hnew = 1.0 + local_Pow_shrink * x; 
628
       // }else{
629
          hnew = GetSafety()*h* std::pow( errmax_sq, local_Pow_shrink); // 0.5*GetPshrnk() );
630
       // }
631
    }  
632
    else  { hnew = max_reduction*h; } // Truncation error was too large,
633
                                      // reduce stepsize, but no more than x10
634
#endif
635
636
#if 1  // OLD_METHOD
637
    // Old method of calculation  - always used power
638
    htemp = GetSafety()*h* std::pow( errmax_sq, local_Pow_shrink); // 0.5*GetPshrnk() );
639
640
    if (htemp >= max_reduction*h)  { h = htemp; }  // Truncation error too large,
641
    else  { h =  max_reduction*h; }                 // reduce stepsize, but no more
642
                                         // than a factor of 10
601
                                         // than a factor of 10
643
#if 1  // NEW_METHOD
644
    assert( std::fabs(hnew - h) < 0.00001 * std::fabs(hnew+h) ); 
645
#endif
646
#endif
647
648
#if 1  // NEW_METHOD
649
    h= hnew; 
650
#endif
651
652
    xnew = x + h;
602
    xnew = x + h;
653
    if(xnew == x)
603
    if(xnew == x)
654
    {
604
    {
(-)History (-3 / +9 lines)
Lines 16-25 Link Here
16
     ----------------------------------------------------------
16
     ----------------------------------------------------------
17
     * Reverse chronological order (last date on top), please *
17
     * Reverse chronological order (last date on top), please *
18
     ----------------------------------------------------------
18
     ----------------------------------------------------------
19
--------------------------
19
January  15, 2015 - J.Apostolakis (geomnav-V10-01-03)
20
 Added protection in G4ReplicaNavigation::DistanceToOutRad() for potential
20
---------------------------------
21
- G4PathFinder: Pass to equation of motion relevant properties of current
22
    particle: latest charge state (electric, magnetic dipole moment),
23
    PDG spin value, momentum and rest mass of current particle
24
    Part of corrections needed for Bugzilla issue 1696.
25
	
26
- Increased maximum number of Navigators from 8 to 16.
27
    
21
 rare cases of negative value to sqrt() in equation calculation for rmin/rmax
28
 rare cases of negative value to sqrt() in equation calculation for rmin/rmax
22
 intersection.
29
 intersection.
23
 Improved warning printout in G4Navigator::GetGlobalExitNormal().
24
    
30
    
(-)include/G4PathFinder.hh (-1 / +1 lines)
Lines 216-222 Link Here
216
   G4int   fNoActiveNavigators; 
216
   G4int   fNoActiveNavigators; 
217
   G4bool  fNewTrack;               // Flag a new track (ensure first step)
217
   G4bool  fNewTrack;               // Flag a new track (ensure first step)
218
218
219
   static const G4int fMaxNav = 8;  // rename to kMaxNoNav ??
219
   static const G4int fMaxNav = 16;  // rename to kMaxNoNav ??
220
220
221
   // Global state (retained during stepping for one track)
221
   // Global state (retained during stepping for one track)
222
222
(-)include/G4MultiNavigator.hh (-1 / +1 lines)
Lines 164-170 Link Here
164
   // STATE Information 
164
   // STATE Information 
165
165
166
   G4int   fNoActiveNavigators; 
166
   G4int   fNoActiveNavigators; 
167
   static const G4int fMaxNav = 8;   // rename to kMaxNoNav ??
167
   static const G4int fMaxNav = 16;   // rename to kMaxNoNav ??
168
   G4VPhysicalVolume* fLastMassWorld; 
168
   G4VPhysicalVolume* fLastMassWorld; 
169
169
170
   // Global state (retained during stepping for one track
170
   // Global state (retained during stepping for one track
(-)src/G4PathFinder.cc (+9 lines)
Lines 1155-1160 Link Here
1155
  G4FieldTrack  fieldTrack= initialState;
1155
  G4FieldTrack  fieldTrack= initialState;
1156
  G4ThreeVector startPoint= initialState.GetPosition(); 
1156
  G4ThreeVector startPoint= initialState.GetPosition(); 
1157
1157
1158
1159
  G4EquationOfMotion* equationOfMotion = 
1160
     (fpFieldPropagator->GetChordFinder()->GetIntegrationDriver()->GetStepper())
1161
     ->GetEquationOfMotion();
1162
1163
  equationOfMotion->SetChargeMomentumMass( *(initialState.GetChargeState()), 
1164
                                           initialState.GetMomentum().mag2(),
1165
                                           initialState.GetRestMass() );
1166
  
1158
#ifdef G4DEBUG_PATHFINDER
1167
#ifdef G4DEBUG_PATHFINDER
1159
  G4int prc= G4cout.precision(9);
1168
  G4int prc= G4cout.precision(9);
1160
  if( fVerboseLevel > 2 )
1169
  if( fVerboseLevel > 2 )
(-)src/G4FieldTrackUpdator.cc (-3 / +6 lines)
Lines 61-69 Link Here
61
{
61
{
62
  const G4DynamicParticle* ptDynamicParticle= trk->GetDynamicParticle();
62
  const G4DynamicParticle* ptDynamicParticle= trk->GetDynamicParticle();
63
63
64
  // The following properties must be updated ONCE for each new track (at least)
64
  // The following properties must be updated 1) for each new track, and 
65
  ftrk->SetRestMass(ptDynamicParticle->GetMass());   
65
  ftrk->SetRestMass(ptDynamicParticle->GetMass());   
66
66
  // 2) Since ion can lose/gain electrons, this must be done at every step
67
  
67
  ftrk->UpdateState(
68
  ftrk->UpdateState(
68
    trk->GetPosition(),     
69
    trk->GetPosition(),     
69
    trk->GetGlobalTime(),
70
    trk->GetGlobalTime(),
Lines 82-88 Link Here
82
83
83
  ftrk->SetProperTimeOfFlight(trk->GetProperTime());
84
  ftrk->SetProperTimeOfFlight(trk->GetProperTime());
84
85
85
  ftrk->SetChargeAndMoments( ptDynamicParticle->GetCharge() );
86
  ftrk->SetChargeAndMoments( ptDynamicParticle->GetCharge(),
87
                             ptDynamicParticle->GetMagneticMoment()); 
88
  ftrk->SetPDGSpin(          ptDynamicParticle->GetParticleDefinition()->GetPDGSpin() ); 
86
   // The charge can change during tracking
89
   // The charge can change during tracking
87
  ftrk->SetSpin( ptDynamicParticle->GetPolarization() );
90
  ftrk->SetSpin( ptDynamicParticle->GetPolarization() );
88
}
91
}
(-)History (+4 lines)
Lines 18-24 Link Here
18
     * Reverse chronological order (last date on top), please *
18
     * Reverse chronological order (last date on top), please *
19
     ----------------------------------------------------------
19
     ----------------------------------------------------------
20
20
21
- January 15, 2015 J.Apostolakis (track-V10-01-01)
22
- Fixed FieldTrackUpdator to pass magnetic moment and PDG spin
23
  Is part of corrections needed for Bugzilla issue 1696.
24
     
21
- August 19, 2014 K. Genser (track-V10-00-04)
25
- August 19, 2014 K. Genser (track-V10-00-04)
22
- Removed non cost requirement when using G4PhysicsModelCatalog getters and moved 
26
- Removed non cost requirement when using G4PhysicsModelCatalog getters and moved 
23
   implementations to icc file (requires global-V10-00-31)
27
   implementations to icc file (requires global-V10-00-31)
24
                                 G4MagIntegratorStepper *pStepper,
28
                                 G4MagIntegratorStepper *pStepper,
25
                                 G4int                   numComponents,
29
                                 G4int                   numComponents,
26
                                 G4int                   statisticsVerbose)
30
                                 G4int                   statisticsVerbose)
27
 : fSmallestFraction( 1.0e-12 ), 
31
 : fSmallestFraction( 1.0e-12 ), 
28
   fNoIntegrationVariables(numComponents), 
32
   fNoIntegrationVariables(numComponents), 
29
   fMinNoVars(12), 
33
   fMinNoVars(12), 
30
   fNoVars( std::max( fNoIntegrationVariables, fMinNoVars )),
34
   fNoVars( std::max( fNoIntegrationVariables, fMinNoVars )),
31
   fStatisticsVerboseLevel(statisticsVerbose),
35
   fStatisticsVerboseLevel(statisticsVerbose),
32
   fNoTotalSteps(0),  fNoBadSteps(0), fNoSmallSteps(0),
36
   fNoTotalSteps(0),  fNoBadSteps(0), fNoSmallSteps(0),
33
   fNoInitialSmallSteps(0), 
37
   fNoInitialSmallSteps(0), 
34
   fDyerr_max(0.0), fDyerr_mx2(0.0), 
38
   fDyerr_max(0.0), fDyerr_mx2(0.0), 
35
   fDyerrPos_smTot(0.0), fDyerrPos_lgTot(0.0), fDyerrVel_lgTot(0.0), 
39
   fDyerrPos_smTot(0.0), fDyerrPos_lgTot(0.0), fDyerrVel_lgTot(0.0), 
36
   fSumH_sm(0.0), fSumH_lg(0.0),
40
   fSumH_sm(0.0), fSumH_lg(0.0),
37
   fVerboseLevel(0)
41
   fVerboseLevel(0)
38
 // In order to accomodate "Laboratory Time", which is [7], fMinNoVars=8
42
 // In order to accomodate "Laboratory Time", which is [7], fMinNoVars=8
39
 // is required. For proper time of flight and spin,  fMinNoVars must be 12
43
 // is required. For proper time of flight and spin,  fMinNoVars must be 12
40
 RenewStepperAndAdjust( pStepper );
44
 RenewStepperAndAdjust( pStepper );
41
 fMinimumStep= hminimum;
45
 fMinimumStep= hminimum;
42
 fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
46
 fMaxNoSteps = fMaxStepBase / pIntStepper->IntegratorOrder();
43
 fVerboseLevel=2;
47
 fVerboseLevel=2;
44
 if( (fVerboseLevel > 0) || (fStatisticsVerboseLevel > 1) )
48
 if( (fVerboseLevel > 0) || (fStatisticsVerboseLevel > 1) )
45
 {
49
 {
46
   G4cout << "MagIntDriver version: Accur-Adv: "
50
   G4cout << "MagIntDriver version: Accur-Adv: "
47
          << "invE_nS, QuickAdv-2sqrt with Statistics "
51
          << "invE_nS, QuickAdv-2sqrt with Statistics "
48
          << " enabled "
52
          << " enabled "
49
          << " disabled "
53
          << " disabled "
50
          << G4endl;
54
          << G4endl;
51
 }
55
 }
52
 if( fStatisticsVerboseLevel > 1 )
56
 if( fStatisticsVerboseLevel > 1 )
53
 {
57
 {
54
   PrintStatisticsReport();
58
   PrintStatisticsReport();
55
 }
59
 }
56
                                G4double     hstep,
60
                                G4double     hstep,
57
                                G4double     eps,
61
                                G4double     eps,
58
                                G4double hinitial )
62
                                G4double hinitial )
59
 // Runge-Kutta driver with adaptive stepsize control. Integrate starting
63
 // Runge-Kutta driver with adaptive stepsize control. Integrate starting
60
 // values at y_current over hstep x2 with accuracy eps. 
64
 // values at y_current over hstep x2 with accuracy eps. 
61
 // On output ystart is replaced by values at the end of the integration 
65
 // On output ystart is replaced by values at the end of the integration 
62
 // interval. RightHandSide is the right-hand side of ODE system. 
66
 // interval. RightHandSide is the right-hand side of ODE system. 
63
 // The source is similar to odeint routine from NRC p.721-722 .
67
 // The source is similar to odeint routine from NRC p.721-722 .
64
 G4int nstp, i, no_warnings=0;
68
 G4int nstp, i, no_warnings=0;
65
 G4double x, hnext, hdid, h;
69
 G4double x, hnext, hdid, h;
66
 static G4int dbg=1;
70
 static G4int dbg=1;
67
 static G4int nStpPr=50;   // For debug printing of long integrations
71
 static G4int nStpPr=50;   // For debug printing of long integrations
68
 G4double ySubStepStart[G4FieldTrack::ncompSVEC];
72
 G4double ySubStepStart[G4FieldTrack::ncompSVEC];
69
 G4FieldTrack  yFldTrkStart(y_current);
73
 G4FieldTrack  yFldTrkStart(y_current);
70
 G4double y[G4FieldTrack::ncompSVEC], dydx[G4FieldTrack::ncompSVEC];
74
 G4double y[G4FieldTrack::ncompSVEC], dydx[G4FieldTrack::ncompSVEC];
71
 G4double ystart[G4FieldTrack::ncompSVEC], yEnd[G4FieldTrack::ncompSVEC]; 
75
 G4double ystart[G4FieldTrack::ncompSVEC], yEnd[G4FieldTrack::ncompSVEC]; 
72
 G4double  x1, x2;
76
 G4double  x1, x2;
73
 G4bool succeeded = true, lastStepSucceeded;
77
 G4bool succeeded = true, lastStepSucceeded;
74
 G4double startCurveLength;
78
 G4double startCurveLength;
75
 G4int  noFullIntegr=0, noSmallIntegr = 0 ;
79
 G4int  noFullIntegr=0, noSmallIntegr = 0 ;
76
 static G4ThreadLocal G4int  noGoodSteps =0 ;  // Bad = chord > curve-len 
80
 static G4ThreadLocal G4int  noGoodSteps =0 ;  // Bad = chord > curve-len 
77
 const  G4int  nvar= fNoVars;
81
 const  G4int  nvar= fNoVars;
78
 G4FieldTrack yStartFT(y_current);
82
 G4FieldTrack yStartFT(y_current);
79
 //  Ensure that hstep > 0
83
 //  Ensure that hstep > 0
80
 //
84
 //
81
 if( hstep <= 0.0 )
85
 if( hstep <= 0.0 )
82
 { 
86
 { 
83
   if(hstep==0.0)
87
   if(hstep==0.0)
84
   {
88
   {
85
     std::ostringstream message;
89
     std::ostringstream message;
86
     message << "Proposed step is zero; hstep = " << hstep << " !";
90
     message << "Proposed step is zero; hstep = " << hstep << " !";
87
     G4Exception("G4MagInt_Driver::AccurateAdvance()", 
91
     G4Exception("G4MagInt_Driver::AccurateAdvance()", 
88
                 "GeomField1001", JustWarning, message);
92
                 "GeomField1001", JustWarning, message);
89
     return succeeded; 
93
     return succeeded; 
90
   }
94
   }
91
   else
95
   else
92
   { 
96
   { 
93
     std::ostringstream message;
97
     std::ostringstream message;
94
     message << "Invalid run condition." << G4endl
98
     message << "Invalid run condition." << G4endl
95
             << "Proposed step is negative; hstep = " << hstep << "." << G4endl
99
             << "Proposed step is negative; hstep = " << hstep << "." << G4endl
96
             << "Requested step cannot be negative! Aborting event.";
100
             << "Requested step cannot be negative! Aborting event.";
97
     G4Exception("G4MagInt_Driver::AccurateAdvance()", 
101
     G4Exception("G4MagInt_Driver::AccurateAdvance()", 
98
                 "GeomField0003", EventMustBeAborted, message);
102
                 "GeomField0003", EventMustBeAborted, message);
99
     return false;
103
     return false;
100
   }
104
   }
101
 }
105
 }
102
 y_current.DumpToArray( ystart );
106
 y_current.DumpToArray( ystart );
103
 startCurveLength= y_current.GetCurveLength();
107
 startCurveLength= y_current.GetCurveLength();
104
 x1= startCurveLength; 
108
 x1= startCurveLength; 
105
 x2= x1 + hstep;
109
 x2= x1 + hstep;
106
 if ( (hinitial > 0.0) && (hinitial < hstep)
110
 if ( (hinitial > 0.0) && (hinitial < hstep)
107
   && (hinitial > perMillion * hstep) )
111
   && (hinitial > perMillion * hstep) )
108
 {
112
 {
109
    h = hinitial;
113
    h = hinitial;
110
 }
114
 }
111
 else  //  Initial Step size "h" defaults to the full interval
115
 else  //  Initial Step size "h" defaults to the full interval
112
 {
116
 {
113
    h = hstep;
117
    h = hstep;
114
 }
118
 }
115
 x = x1;
119
 x = x1;
116
 for (i=0;i<nvar;i++)  { y[i] = ystart[i]; }
120
 for (i=0;i<nvar;i++)  { y[i] = ystart[i]; }
117
 G4bool lastStep= false;
121
 G4bool lastStep= false;
118
 nstp=1;
122
 nstp=1;
119
 do
123
 do
120
 {
124
 {
121
   G4ThreeVector StartPos( y[0], y[1], y[2] );
125
   G4ThreeVector StartPos( y[0], y[1], y[2] );
122
   G4double xSubStepStart= x; 
126
   G4double xSubStepStart= x; 
123
   for (i=0;i<nvar;i++)  { ySubStepStart[i] = y[i]; }
127
   for (i=0;i<nvar;i++)  { ySubStepStart[i] = y[i]; }
124
   yFldTrkStart.LoadFromArray(y, fNoIntegrationVariables);
128
   yFldTrkStart.LoadFromArray(y, fNoIntegrationVariables);
125
   yFldTrkStart.SetCurveLength(x);
129
   yFldTrkStart.SetCurveLength(x);
126
   // Old method - inline call to Equation of Motion
130
   // Old method - inline call to Equation of Motion
127
   //   pIntStepper->RightHandSide( y, dydx );
131
   //   pIntStepper->RightHandSide( y, dydx );
128
   // New method allows to cache field, or state (eg momentum magnitude)
132
   // New method allows to cache field, or state (eg momentum magnitude)
129
   pIntStepper->ComputeRightHandSide( y, dydx );
133
   pIntStepper->ComputeRightHandSide( y, dydx );
130
   fNoTotalSteps++;
134
   fNoTotalSteps++;
131
   // Perform the Integration
135
   // Perform the Integration
132
   //      
136
   //      
133
   if( h > fMinimumStep )
137
   if( h > fMinimumStep )
134
   { 
138
   { 
135
     OneGoodStep(y,dydx,x,h,eps,hdid,hnext) ;
139
     OneGoodStep(y,dydx,x,h,eps,hdid,hnext) ;
136
     //--------------------------------------
140
     //--------------------------------------
137
     lastStepSucceeded= (hdid == h);   
141
     lastStepSucceeded= (hdid == h);   
138
     if (dbg>2) {
142
     if (dbg>2) {
139
       PrintStatus( ySubStepStart, xSubStepStart, y, x, h,  nstp); // Only
143
       PrintStatus( ySubStepStart, xSubStepStart, y, x, h,  nstp); // Only
140
     }
144
     }
141
   }
145
   }
142
   else
146
   else
143
   {
147
   {
144
     G4FieldTrack yFldTrk( G4ThreeVector(0,0,0), 
148
     G4FieldTrack yFldTrk( G4ThreeVector(0,0,0), 
145
                           G4ThreeVector(0,0,0), 0., 0., 0., 0. );
149
                           G4ThreeVector(0,0,0), 0., 0., 0., 0. );
146
     G4double dchord_step, dyerr, dyerr_len;   // What to do with these ?
150
     G4double dchord_step, dyerr, dyerr_len;   // What to do with these ?
147
     yFldTrk.LoadFromArray(y, fNoIntegrationVariables); 
151
     yFldTrk.LoadFromArray(y, fNoIntegrationVariables); 
148
     yFldTrk.SetCurveLength( x );
152
     yFldTrk.SetCurveLength( x );
149
     QuickAdvance( yFldTrk, dydx, h, dchord_step, dyerr_len ); 
153
     QuickAdvance( yFldTrk, dydx, h, dchord_step, dyerr_len ); 
150
     //-----------------------------------------------------
154
     //-----------------------------------------------------
151
     yFldTrk.DumpToArray(y);    
155
     yFldTrk.DumpToArray(y);    
152
     fNoSmallSteps++; 
156
     fNoSmallSteps++; 
153
     if ( dyerr_len > fDyerr_max)  { fDyerr_max= dyerr_len; }
157
     if ( dyerr_len > fDyerr_max)  { fDyerr_max= dyerr_len; }
154
     fDyerrPos_smTot += dyerr_len;
158
     fDyerrPos_smTot += dyerr_len;
155
     fSumH_sm += h;  // Length total for 'small' steps
159
     fSumH_sm += h;  // Length total for 'small' steps
156
     if (nstp<=1)  { fNoInitialSmallSteps++; }
160
     if (nstp<=1)  { fNoInitialSmallSteps++; }
157
     if (dbg>1)
161
     if (dbg>1)
158
     {
162
     {
159
       if(fNoSmallSteps<2) { PrintStatus(ySubStepStart, x1, y, x, h, -nstp); }
163
       if(fNoSmallSteps<2) { PrintStatus(ySubStepStart, x1, y, x, h, -nstp); }
160
       G4cout << "Another sub-min step, no " << fNoSmallSteps 
164
       G4cout << "Another sub-min step, no " << fNoSmallSteps 
161
              << " of " << fNoTotalSteps << " this time " << nstp << G4endl; 
165
              << " of " << fNoTotalSteps << " this time " << nstp << G4endl; 
162
       PrintStatus( ySubStepStart, x1, y, x, h,  nstp);   // Only this
166
       PrintStatus( ySubStepStart, x1, y, x, h,  nstp);   // Only this
163
       G4cout << " dyerr= " << dyerr_len << " relative = " << dyerr_len / h 
167
       G4cout << " dyerr= " << dyerr_len << " relative = " << dyerr_len / h 
164
              << " epsilon= " << eps << " hstep= " << hstep 
168
              << " epsilon= " << eps << " hstep= " << hstep 
165
              << " h= " << h << " hmin= " << fMinimumStep << G4endl;
169
              << " h= " << h << " hmin= " << fMinimumStep << G4endl;
166
     }
170
     }
167
     if( h == 0.0 )
171
     if( h == 0.0 )
168
     { 
172
     { 
169
       G4Exception("G4MagInt_Driver::AccurateAdvance()",
173
       G4Exception("G4MagInt_Driver::AccurateAdvance()",
170
                   "GeomField0003", FatalException,
174
                   "GeomField0003", FatalException,
171
                   "Integration Step became Zero!"); 
175
                   "Integration Step became Zero!"); 
172
     }
176
     }
173
     dyerr = dyerr_len / h;
177
     dyerr = dyerr_len / h;
174
     hdid= h;
178
     hdid= h;
175
     x += hdid;
179
     x += hdid;
176
     // Compute suggested new step
180
     // Compute suggested new step
177
     hnext= ComputeNewStepSize( dyerr/eps, h);
181
     hnext= ComputeNewStepSize( dyerr/eps, h);
178
     // .. hnext= ComputeNewStepSize_WithinLimits( dyerr/eps, h);
182
     // .. hnext= ComputeNewStepSize_WithinLimits( dyerr/eps, h);
179
     lastStepSucceeded= (dyerr<= eps);
183
     lastStepSucceeded= (dyerr<= eps);
180
   }
184
   }
181
   if (lastStepSucceeded)  { noFullIntegr++; }
185
   if (lastStepSucceeded)  { noFullIntegr++; }
182
   else                    { noSmallIntegr++; }
186
   else                    { noSmallIntegr++; }
183
   G4ThreeVector EndPos( y[0], y[1], y[2] );
187
   G4ThreeVector EndPos( y[0], y[1], y[2] );
184
   if( (dbg>0) && (dbg<=2) && (nstp>nStpPr))
188
   if( (dbg>0) && (dbg<=2) && (nstp>nStpPr))
185
   {
189
   {
186
     if( nstp==nStpPr )  { G4cout << "***** Many steps ****" << G4endl; }
190
     if( nstp==nStpPr )  { G4cout << "***** Many steps ****" << G4endl; }
187
     G4cout << "MagIntDrv: " ; 
191
     G4cout << "MagIntDrv: " ; 
188
     G4cout << "hdid="  << std::setw(12) << hdid  << " "
192
     G4cout << "hdid="  << std::setw(12) << hdid  << " "
189
            << "hnext=" << std::setw(12) << hnext << " " 
193
            << "hnext=" << std::setw(12) << hnext << " " 
190
     PrintStatus( ystart, x1, y, x, h, (nstp==nStpPr) ? -nstp: nstp); 
194
     PrintStatus( ystart, x1, y, x, h, (nstp==nStpPr) ? -nstp: nstp); 
191
   }
195
   }
192
   // Check the endpoint
196
   // Check the endpoint
193
   G4double endPointDist= (EndPos-StartPos).mag(); 
197
   G4double endPointDist= (EndPos-StartPos).mag(); 
194
   if ( endPointDist >= hdid*(1.+perMillion) )
198
   if ( endPointDist >= hdid*(1.+perMillion) )
195
   {
199
   {
196
     fNoBadSteps++;
200
     fNoBadSteps++;
197
     // Issue a warning only for gross differences -
201
     // Issue a warning only for gross differences -
198
     // we understand how small difference occur.
202
     // we understand how small difference occur.
199
     if ( endPointDist >= hdid*(1.+perThousand) )
203
     if ( endPointDist >= hdid*(1.+perThousand) )
200
     { 
204
     { 
201
       if (dbg)
205
       if (dbg)
202
       {
206
       {
203
         WarnEndPointTooFar ( endPointDist, hdid, eps, dbg ); 
207
         WarnEndPointTooFar ( endPointDist, hdid, eps, dbg ); 
204
         G4cerr << "  Total steps:  bad " << fNoBadSteps
208
         G4cerr << "  Total steps:  bad " << fNoBadSteps
205
                << " good " << noGoodSteps << " current h= " << hdid
209
                << " good " << noGoodSteps << " current h= " << hdid
206
                << G4endl;
210
                << G4endl;
207
         PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);  
211
         PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);  
208
       }
212
       }
209
       no_warnings++;
213
       no_warnings++;
210
     }
214
     }
211
   }
215
   }
212
   else
216
   else
213
   {
217
   {
214
     noGoodSteps ++;
218
     noGoodSteps ++;
215
   } 
219
   } 
216
   //  Avoid numerous small last steps
220
   //  Avoid numerous small last steps
217
   if( (h < eps * hstep) || (h < fSmallestFraction * startCurveLength) )
221
   if( (h < eps * hstep) || (h < fSmallestFraction * startCurveLength) )
218
   {
222
   {
219
     // No more integration -- the next step will not happen
223
     // No more integration -- the next step will not happen
220
     lastStep = true;  
224
     lastStep = true;  
221
   }
225
   }
222
   else
226
   else
223
   {
227
   {
224
     // Check the proposed next stepsize
228
     // Check the proposed next stepsize
225
     if(std::fabs(hnext) <= Hmin())
229
     if(std::fabs(hnext) <= Hmin())
226
     {
230
     {
227
       // If simply a very small interval is being integrated, do not warn
231
       // If simply a very small interval is being integrated, do not warn
228
       if( (x < x2 * (1-eps) ) &&        // The last step can be small: OK
232
       if( (x < x2 * (1-eps) ) &&        // The last step can be small: OK
229
           (std::fabs(hstep) > Hmin()) ) // and if we are asked, it's OK
233
           (std::fabs(hstep) > Hmin()) ) // and if we are asked, it's OK
230
       {
234
       {
231
         if(dbg>0)
235
         if(dbg>0)
232
         {
236
         {
233
           WarnSmallStepSize( hnext, hstep, h, x-x1, nstp );  
237
           WarnSmallStepSize( hnext, hstep, h, x-x1, nstp );  
234
           PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
238
           PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
235
         }
239
         }
236
         no_warnings++;
240
         no_warnings++;
237
       }
241
       }
238
       // Make sure that the next step is at least Hmin.
242
       // Make sure that the next step is at least Hmin.
239
       h = Hmin();
243
       h = Hmin();
240
     }
244
     }
241
     else
245
     else
242
     {
246
     {
243
       h = hnext;
247
       h = hnext;
244
     }
248
     }
245
     //  Ensure that the next step does not overshoot
249
     //  Ensure that the next step does not overshoot
246
     if ( x+h > x2 )
250
     if ( x+h > x2 )
247
     {                // When stepsize overshoots, decrease it!
251
     {                // When stepsize overshoots, decrease it!
248
       h = x2 - x ;   // Must cope with difficult rounding-error
252
       h = x2 - x ;   // Must cope with difficult rounding-error
249
     }                // issues if hstep << x2
253
     }                // issues if hstep << x2
250
     if ( h == 0.0 )
254
     if ( h == 0.0 )
251
     {
255
     {
252
       // Cannot progress - accept this as last step - by default
256
       // Cannot progress - accept this as last step - by default
253
       lastStep = true;
257
       lastStep = true;
254
       if (dbg>2)
258
       if (dbg>2)
255
       {
259
       {
256
         int prec= G4cout.precision(12); 
260
         int prec= G4cout.precision(12); 
257
         G4cout << "Warning: G4MagIntegratorDriver::AccurateAdvance"
261
         G4cout << "Warning: G4MagIntegratorDriver::AccurateAdvance"
258
                << G4endl
262
                << G4endl
259
                << "  Integration step 'h' became "
263
                << "  Integration step 'h' became "
260
                << h << " due to roundoff. " << G4endl
264
                << h << " due to roundoff. " << G4endl
261
                << "  Forcing termination of advance." << G4endl;
265
                << "  Forcing termination of advance." << G4endl;
262
         G4cout.precision(prec);
266
         G4cout.precision(prec);
263
       }          
267
       }          
264
     }
268
     }
265
   }
269
   }
266
 } while ( ((nstp++)<=fMaxNoSteps) && (x < x2) && (!lastStep) );
270
 } while ( ((nstp++)<=fMaxNoSteps) && (x < x2) && (!lastStep) );
267
    // Have we reached the end ?
271
    // Have we reached the end ?
268
    // --> a better test might be x-x2 > an_epsilon
272
    // --> a better test might be x-x2 > an_epsilon
269
 succeeded=  (x>=x2);  // If it was a "forced" last step
273
 succeeded=  (x>=x2);  // If it was a "forced" last step
270
 for (i=0;i<nvar;i++)  { yEnd[i] = y[i]; }
274
 for (i=0;i<nvar;i++)  { yEnd[i] = y[i]; }
271
 // Put back the values.
275
 // Put back the values.
272
 y_current.LoadFromArray( yEnd, fNoIntegrationVariables );
276
 y_current.LoadFromArray( yEnd, fNoIntegrationVariables );
273
 y_current.SetCurveLength( x );
277
 y_current.SetCurveLength( x );
274
 if(nstp > fMaxNoSteps)
278
 if(nstp > fMaxNoSteps)
275
 {
279
 {
276
   no_warnings++;
280
   no_warnings++;
277
   succeeded = false;
281
   succeeded = false;
278
   if (dbg)
282
   if (dbg)
279
   {
283
   {
280
     WarnTooManyStep( x1, x2, x );  //  Issue WARNING
284
     WarnTooManyStep( x1, x2, x );  //  Issue WARNING
281
     PrintStatus( yEnd, x1, y, x, hstep, -nstp);
285
     PrintStatus( yEnd, x1, y, x, hstep, -nstp);
282
   }
286
   }
283
 }
287
 }
284
 if( dbg && no_warnings )
288
 if( dbg && no_warnings )
285
 {
289
 {
286
   G4cerr << "G4MagIntegratorDriver exit status: no-steps " << nstp <<G4endl;
290
   G4cerr << "G4MagIntegratorDriver exit status: no-steps " << nstp <<G4endl;
287
   PrintStatus( yEnd, x1, y, x, hstep, nstp);
291
   PrintStatus( yEnd, x1, y, x, hstep, nstp);
288
 }
292
 }
289
 return succeeded;
293
 return succeeded;
290
                                   G4double h, G4double xDone,
294
                                   G4double h, G4double xDone,
291
                                   G4int nstp)
295
                                   G4int nstp)
292
 static G4ThreadLocal G4int noWarningsIssued =0;
296
 static G4ThreadLocal G4int noWarningsIssued =0;
293
 const  G4int maxNoWarnings =  10;   // Number of verbose warnings
297
 const  G4int maxNoWarnings =  10;   // Number of verbose warnings
294
 std::ostringstream message;
298
 std::ostringstream message;
295
 if( (noWarningsIssued < maxNoWarnings) || fVerboseLevel > 10 )
299
 if( (noWarningsIssued < maxNoWarnings) || fVerboseLevel > 10 )
296
 {
300
 {
297
   message << "The stepsize for the next iteration, " << hnext
301
   message << "The stepsize for the next iteration, " << hnext
298
           << ", is too small - in Step number " << nstp << "." << G4endl
302
           << ", is too small - in Step number " << nstp << "." << G4endl
299
           << "The minimum for the driver is " << Hmin()  << G4endl
303
           << "The minimum for the driver is " << Hmin()  << G4endl
300
           << "Requested integr. length was " << hstep << " ." << G4endl
304
           << "Requested integr. length was " << hstep << " ." << G4endl
301
           << "The size of this sub-step was " << h     << " ." << G4endl
305
           << "The size of this sub-step was " << h     << " ." << G4endl
302
           << "The integrations has already gone " << xDone;
306
           << "The integrations has already gone " << xDone;
303
 }
307
 }
304
 else
308
 else
305
 {
309
 {
306
   message << "Too small 'next' step " << hnext
310
   message << "Too small 'next' step " << hnext
307
           << ", step-no: " << nstp << G4endl
311
           << ", step-no: " << nstp << G4endl
308
           << ", this sub-step: " << h     
312
           << ", this sub-step: " << h     
309
           << ",  req_tot_len: " << hstep 
313
           << ",  req_tot_len: " << hstep 
310
           << ", done: " << xDone << ", min: " << Hmin();
314
           << ", done: " << xDone << ", min: " << Hmin();
311
 }
315
 }
312
 G4Exception("G4MagInt_Driver::WarnSmallStepSize()", "GeomField1001",
316
 G4Exception("G4MagInt_Driver::WarnSmallStepSize()", "GeomField1001",
313
             JustWarning, message);
317
             JustWarning, message);
314
 noWarningsIssued++;
318
 noWarningsIssued++;
315
                                 G4double x2end, 
319
                                 G4double x2end, 
316
                                 G4double xCurrent)
320
                                 G4double xCurrent)
317
   std::ostringstream message;
321
   std::ostringstream message;
318
   message << "The number of steps used in the Integration driver"
322
   message << "The number of steps used in the Integration driver"
319
           << " (Runge-Kutta) is too many." << G4endl
323
           << " (Runge-Kutta) is too many." << G4endl
320
           << "Integration of the interval was not completed !" << G4endl
324
           << "Integration of the interval was not completed !" << G4endl
321
           << "Only a " << (xCurrent-x1start)*100/(x2end-x1start)
325
           << "Only a " << (xCurrent-x1start)*100/(x2end-x1start)
322
           << " % fraction of it was done.";
326
           << " % fraction of it was done.";
323
   G4Exception("G4MagInt_Driver::WarnTooManyStep()", "GeomField1001",
327
   G4Exception("G4MagInt_Driver::WarnTooManyStep()", "GeomField1001",
324
               JustWarning, message);
328
               JustWarning, message);
325
                                    G4double   h , 
329
                                    G4double   h , 
326
                                    G4double  eps,
330
                                    G4double  eps,
327
                                    G4int     dbg)
331
                                    G4int     dbg)
328
 static G4ThreadLocal G4double maxRelError=0.0;
332
 static G4ThreadLocal G4double maxRelError=0.0;
329
 G4bool isNewMax, prNewMax;
333
 G4bool isNewMax, prNewMax;
330
 isNewMax = endPointDist > (1.0 + maxRelError) * h;
334
 isNewMax = endPointDist > (1.0 + maxRelError) * h;
331
 prNewMax = endPointDist > (1.0 + 1.05 * maxRelError) * h;
335
 prNewMax = endPointDist > (1.0 + 1.05 * maxRelError) * h;
332
 if( isNewMax ) { maxRelError= endPointDist / h - 1.0; }
336
 if( isNewMax ) { maxRelError= endPointDist / h - 1.0; }
333
 if( dbg && (h > G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()) 
337
 if( dbg && (h > G4GeometryTolerance::GetInstance()->GetSurfaceTolerance()) 
334
         && ( (dbg>1) || prNewMax || (endPointDist >= h*(1.+eps) ) ) )
338
         && ( (dbg>1) || prNewMax || (endPointDist >= h*(1.+eps) ) ) )
335
 { 
339
 { 
336
   static G4ThreadLocal G4int noWarnings = 0;
340
   static G4ThreadLocal G4int noWarnings = 0;
337
   std::ostringstream message;
341
   std::ostringstream message;
338
   if( (noWarnings ++ < 10) || (dbg>2) )
342
   if( (noWarnings ++ < 10) || (dbg>2) )
339
   {
343
   {
340
     message << "The integration produced an end-point which " << G4endl
344
     message << "The integration produced an end-point which " << G4endl
341
             << "is further from the start-point than the curve length."
345
             << "is further from the start-point than the curve length."
342
             << G4endl;
346
             << G4endl;
343
   }
347
   }
344
   message << "  Distance of endpoints = " << endPointDist
348
   message << "  Distance of endpoints = " << endPointDist
345
           << ", curve length = " << h << G4endl
349
           << ", curve length = " << h << G4endl
346
           << "  Difference (curveLen-endpDist)= " << (h - endPointDist)
350
           << "  Difference (curveLen-endpDist)= " << (h - endPointDist)
347
           << ", relative = " << (h-endPointDist) / h 
351
           << ", relative = " << (h-endPointDist) / h 
348
           << ", epsilon =  " << eps;
352
           << ", epsilon =  " << eps;
349
   G4Exception("G4MagInt_Driver::WarnEndPointTooFar()", "GeomField1001",
353
   G4Exception("G4MagInt_Driver::WarnEndPointTooFar()", "GeomField1001",
350
               JustWarning, message);
354
               JustWarning, message);
351
 }
355
 }
352
                            const G4double dydx[],
356
                            const G4double dydx[],
353
                                  G4double& x,         // InOut
357
                                  G4double& x,         // InOut
354
                                  G4double htry,
358
                                  G4double htry,
355
                                  G4double eps_rel_max,
359
                                  G4double eps_rel_max,
356
                                  G4double& hdid,      // Out
360
                                  G4double& hdid,      // Out
357
                                  G4double& hnext )    // Out
361
                                  G4double& hnext )    // Out
358
 G4double errmax_sq;
362
 G4double errmax_sq;
359
 G4double h, htemp, xnew ;
363
 G4double h, htemp, xnew ;
360
 G4double yerr[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
364
 G4double yerr[G4FieldTrack::ncompSVEC], ytemp[G4FieldTrack::ncompSVEC];
361
 h = htry ; // Set stepsize to the initial trial value
365
 h = htry ; // Set stepsize to the initial trial value
362
 G4double inv_eps_vel_sq = 1.0 / (eps_rel_max*eps_rel_max);
366
 G4double inv_eps_vel_sq = 1.0 / (eps_rel_max*eps_rel_max);
363
 G4double errpos_sq=0.0;    // square of displacement error
367
 G4double errpos_sq=0.0;    // square of displacement error
364
 G4double errvel_sq=0.0;    // square of momentum vector difference
368
 G4double errvel_sq=0.0;    // square of momentum vector difference
365
 G4double errspin_sq=0.0;   // square of spin vector difference
369
 G4double errspin_sq=0.0;   // square of spin vector difference
366
 G4int iter;
370
 G4int iter;
367
 static G4ThreadLocal G4int tot_no_trials=0; 
371
 static G4ThreadLocal G4int tot_no_trials=0; 
368
 const G4int max_trials=100; 
372
 const G4int max_trials=100; 
369
 G4ThreeVector Spin(y[9],y[10],y[11]);
373
 G4ThreeVector Spin(y[9],y[10],y[11]);
370
 G4double   spin_mag2 =Spin.mag2() ;
374
 G4double   spin_mag2 =Spin.mag2() ;
371
 G4bool     hasSpin= (spin_mag2 > 0.0); 
375
 G4bool     hasSpin= (spin_mag2 > 0.0); 
372
 for (iter=0; iter<max_trials ;iter++)
376
 for (iter=0; iter<max_trials ;iter++)
373
 {
377
 {
374
   tot_no_trials++;
378
   tot_no_trials++;
375
   pIntStepper-> Stepper(y,dydx,h,ytemp,yerr); 
379
   pIntStepper-> Stepper(y,dydx,h,ytemp,yerr); 
376
   //            *******
380
   //            *******
377
   G4double eps_pos = eps_rel_max * std::max(h, fMinimumStep); 
381
   G4double eps_pos = eps_rel_max * std::max(h, fMinimumStep); 
378
   G4double inv_eps_pos_sq = 1.0 / (eps_pos*eps_pos); 
382
   G4double inv_eps_pos_sq = 1.0 / (eps_pos*eps_pos); 
379
   // Evaluate accuracy
383
   // Evaluate accuracy
380
   //
384
   //
381
   errpos_sq =  sqr(yerr[0]) + sqr(yerr[1]) + sqr(yerr[2]) ;
385
   errpos_sq =  sqr(yerr[0]) + sqr(yerr[1]) + sqr(yerr[2]) ;
382
   errpos_sq *= inv_eps_pos_sq; // Scale relative to required tolerance
386
   errpos_sq *= inv_eps_pos_sq; // Scale relative to required tolerance
383
   // Accuracy for momentum
387
   // Accuracy for momentum
384
   G4double magvel_sq=  sqr(y[3]) + sqr(y[4]) + sqr(y[5]) ;
388
   G4double magvel_sq=  sqr(y[3]) + sqr(y[4]) + sqr(y[5]) ;
385
   G4double sumerr_sq =  sqr(yerr[3]) + sqr(yerr[4]) + sqr(yerr[5]) ; 
389
   G4double sumerr_sq =  sqr(yerr[3]) + sqr(yerr[4]) + sqr(yerr[5]) ; 
386
   if( magvel_sq > 0.0 ) { 
390
   if( magvel_sq > 0.0 ) { 
387
      errvel_sq = sumerr_sq / magvel_sq; 
391
      errvel_sq = sumerr_sq / magvel_sq; 
388
   }else{
392
   }else{
389
      G4cerr << "** G4MagIntegrationDriver: found case of zero momentum." 
393
      G4cerr << "** G4MagIntegrationDriver: found case of zero momentum." 
390
             << " iteration=  " << iter << " h= " << h << G4endl; 
394
             << " iteration=  " << iter << " h= " << h << G4endl; 
391
      errvel_sq = sumerr_sq; 
395
      errvel_sq = sumerr_sq; 
392
   }
396
   }
393
   errvel_sq *= inv_eps_vel_sq;
397
   errvel_sq *= inv_eps_vel_sq;
394
   errmax_sq = std::max( errpos_sq, errvel_sq ); // Square of maximum error
398
   errmax_sq = std::max( errpos_sq, errvel_sq ); // Square of maximum error
395
   if( hasSpin )
399
   if( hasSpin )
396
   { 
400
   { 
397
     // Accuracy for spin
401
     // Accuracy for spin
398
     errspin_sq =  ( sqr(yerr[9]) + sqr(yerr[10]) + sqr(yerr[11]) )
402
     errspin_sq =  ( sqr(yerr[9]) + sqr(yerr[10]) + sqr(yerr[11]) )
399
                   /  spin_mag2; // ( sqr(y[9]) + sqr(y[10]) + sqr(y[11]) );
403
                   /  spin_mag2; // ( sqr(y[9]) + sqr(y[10]) + sqr(y[11]) );
400
     errspin_sq *= inv_eps_vel_sq;
404
     errspin_sq *= inv_eps_vel_sq;
401
     errmax_sq = std::max( errmax_sq, errspin_sq ); 
405
     errmax_sq = std::max( errmax_sq, errspin_sq ); 
402
   }
406
   }
403
   if ( errmax_sq <= 1.0 )  { break; } // Step succeeded. 
407
   if ( errmax_sq <= 1.0 )  { break; } // Step succeeded. 
404
   // Step failed; compute the size of retrial Step.
408
   // Step failed; compute the size of retrial Step.
405
   htemp = GetSafety()*h* std::pow( errmax_sq, 0.5*GetPshrnk() );
409
   htemp = GetSafety()*h* std::pow( errmax_sq, 0.5*GetPshrnk() );
406
   if (htemp >= 0.1*h)  { h = htemp; }  // Truncation error too large,
410
   if (htemp >= 0.1*h)  { h = htemp; }  // Truncation error too large,
407
   else  { h = 0.1*h; }                 // reduce stepsize, but no more
411
   else  { h = 0.1*h; }                 // reduce stepsize, but no more
408
                                        // than a factor of 10
412
                                        // than a factor of 10
409
   xnew = x + h;
413
   xnew = x + h;
410
   if(xnew == x)
414
   if(xnew == x)
411
   {
415
   {
412
     G4cerr << "G4MagIntegratorDriver::OneGoodStep:" << G4endl
416
     G4cerr << "G4MagIntegratorDriver::OneGoodStep:" << G4endl
413
            << "  Stepsize underflow in Stepper " << G4endl ;
417
            << "  Stepsize underflow in Stepper " << G4endl ;
414
     G4cerr << "  Step's start x=" << x << " and end x= " << xnew 
418
     G4cerr << "  Step's start x=" << x << " and end x= " << xnew 
415
            << " are equal !! " << G4endl
419
            << " are equal !! " << G4endl
416
            <<"  Due to step-size= " << h 
420
            <<"  Due to step-size= " << h 
417
            << " . Note that input step was " << htry << G4endl;
421
            << " . Note that input step was " << htry << G4endl;
418
     break;
422
     break;
419
   }
423
   }
420
 }
424
 }
421
 // Sum of squares of position error // and momentum dir (underestimated)
425
 // Sum of squares of position error // and momentum dir (underestimated)
422
 fSumH_lg += h; 
426
 fSumH_lg += h; 
423
 fDyerrPos_lgTot += errpos_sq;
427
 fDyerrPos_lgTot += errpos_sq;
424
 fDyerrVel_lgTot += errvel_sq * h * h; 
428
 fDyerrVel_lgTot += errvel_sq * h * h; 
425
 // Compute size of next Step
429
 // Compute size of next Step
426
 if (errmax_sq > errcon*errcon)
430
 if (errmax_sq > errcon*errcon)
427
 { 
431
 { 
428
   hnext = GetSafety()*h*std::pow(errmax_sq, 0.5*GetPgrow());
432
   hnext = GetSafety()*h*std::pow(errmax_sq, 0.5*GetPgrow());
429
 }
433
 }
430
 else
434
 else
431
 {
435
 {
432
   hnext = max_stepping_increase*h ; // No more than a factor of 5 increase
436
   hnext = max_stepping_increase*h ; // No more than a factor of 5 increase
433
 }
437
 }
434
 x += (hdid = h);
438
 x += (hdid = h);
435
 for(G4int k=0;k<fNoIntegrationVariables;k++) { y[k] = ytemp[k]; }
439
 for(G4int k=0;k<fNoIntegrationVariables;k++) { y[k] = ytemp[k]; }
436
 return;
440
 return;
437
                           G4FieldTrack& y_posvel,         // INOUT
441
                           G4FieldTrack& y_posvel,         // INOUT
438
                           const G4double     dydx[],  
442
                           const G4double     dydx[],  
439
                                 G4double     hstep,       // In
443
                                 G4double     hstep,       // In
440
                                 G4double&    dchord_step,
444
                                 G4double&    dchord_step,
441
                                 G4double&    dyerr_pos_sq,
445
                                 G4double&    dyerr_pos_sq,
442
                                 G4double&    dyerr_mom_rel_sq )  
446
                                 G4double&    dyerr_mom_rel_sq )  
443
 G4Exception("G4MagInt_Driver::QuickAdvance()", "GeomField0001",
447
 G4Exception("G4MagInt_Driver::QuickAdvance()", "GeomField0001",
444
             FatalException, "Not yet implemented."); 
448
             FatalException, "Not yet implemented."); 
445
 // Use the parameters of this method, to please compiler
449
 // Use the parameters of this method, to please compiler
446
 dchord_step = dyerr_pos_sq = hstep * hstep * dydx[0]; 
450
 dchord_step = dyerr_pos_sq = hstep * hstep * dydx[0]; 
447
 dyerr_mom_rel_sq = y_posvel.GetPosition().mag2();
451
 dyerr_mom_rel_sq = y_posvel.GetPosition().mag2();
448
 return true;
452
 return true;
449
                           G4FieldTrack& y_posvel,         // INOUT
453
                           G4FieldTrack& y_posvel,         // INOUT
450
                           const G4double     dydx[],  
454
                           const G4double     dydx[],  
451
                                 G4double     hstep,       // In
455
                                 G4double     hstep,       // In
452
                                 G4double&    dchord_step,
456
                                 G4double&    dchord_step,
453
                                 G4double&    dyerr )
457
                                 G4double&    dyerr )
454
 G4double dyerr_pos_sq, dyerr_mom_rel_sq;  
458
 G4double dyerr_pos_sq, dyerr_mom_rel_sq;  
455
 G4double yerr_vec[G4FieldTrack::ncompSVEC],
459
 G4double yerr_vec[G4FieldTrack::ncompSVEC],
456
          yarrin[G4FieldTrack::ncompSVEC], yarrout[G4FieldTrack::ncompSVEC]; 
460
          yarrin[G4FieldTrack::ncompSVEC], yarrout[G4FieldTrack::ncompSVEC]; 
457
 G4double s_start;
461
 G4double s_start;
458
 G4double dyerr_mom_sq, vel_mag_sq, inv_vel_mag_sq;
462
 G4double dyerr_mom_sq, vel_mag_sq, inv_vel_mag_sq;
459
 static G4ThreadLocal G4int no_call=0; 
463
 static G4ThreadLocal G4int no_call=0; 
460
 no_call ++; 
464
 no_call ++; 
461
 // Move data into array
465
 // Move data into array
462
 y_posvel.DumpToArray( yarrin );      //  yarrin  <== y_posvel 
466
 y_posvel.DumpToArray( yarrin );      //  yarrin  <== y_posvel 
463
 s_start = y_posvel.GetCurveLength();
467
 s_start = y_posvel.GetCurveLength();
464
 // Do an Integration Step
468
 // Do an Integration Step
465
 pIntStepper-> Stepper(yarrin, dydx, hstep, yarrout, yerr_vec) ; 
469
 pIntStepper-> Stepper(yarrin, dydx, hstep, yarrout, yerr_vec) ; 
466
 //            *******
470
 //            *******
467
 // Estimate curve-chord distance
471
 // Estimate curve-chord distance
468
 dchord_step= pIntStepper-> DistChord();
472
 dchord_step= pIntStepper-> DistChord();
469
 //                         *********
473
 //                         *********
470
 // Put back the values.  yarrout ==> y_posvel
474
 // Put back the values.  yarrout ==> y_posvel
471
 y_posvel.LoadFromArray( yarrout, fNoIntegrationVariables );
475
 y_posvel.LoadFromArray( yarrout, fNoIntegrationVariables );
472
 y_posvel.SetCurveLength( s_start + hstep );
476
 y_posvel.SetCurveLength( s_start + hstep );
473
 if(fVerboseLevel>2)
477
 if(fVerboseLevel>2)
474
 {
478
 {
475
   G4cout << "G4MagIntDrv: Quick Advance" << G4endl;
479
   G4cout << "G4MagIntDrv: Quick Advance" << G4endl;
476
   PrintStatus( yarrin, s_start, yarrout, s_start+hstep, hstep,  1); 
480
   PrintStatus( yarrin, s_start, yarrout, s_start+hstep, hstep,  1); 
477
 }
481
 }
478
 // A single measure of the error   
482
 // A single measure of the error   
479
 //      TO-DO :  account for  energy,  spin, ... ? 
483
 //      TO-DO :  account for  energy,  spin, ... ? 
480
 vel_mag_sq   = ( sqr(yarrout[3])+sqr(yarrout[4])+sqr(yarrout[5]) );
484
 vel_mag_sq   = ( sqr(yarrout[3])+sqr(yarrout[4])+sqr(yarrout[5]) );
481
 inv_vel_mag_sq = 1.0 / vel_mag_sq; 
485
 inv_vel_mag_sq = 1.0 / vel_mag_sq; 
482
 dyerr_pos_sq = ( sqr(yerr_vec[0])+sqr(yerr_vec[1])+sqr(yerr_vec[2]));
486
 dyerr_pos_sq = ( sqr(yerr_vec[0])+sqr(yerr_vec[1])+sqr(yerr_vec[2]));
483
 dyerr_mom_sq = ( sqr(yerr_vec[3])+sqr(yerr_vec[4])+sqr(yerr_vec[5]));
487
 dyerr_mom_sq = ( sqr(yerr_vec[3])+sqr(yerr_vec[4])+sqr(yerr_vec[5]));
484
 dyerr_mom_rel_sq = dyerr_mom_sq * inv_vel_mag_sq;
488
 dyerr_mom_rel_sq = dyerr_mom_sq * inv_vel_mag_sq;
485
 // Calculate also the change in the momentum squared also ???
489
 // Calculate also the change in the momentum squared also ???
486
 // G4double veloc_square = y_posvel.GetVelocity().mag2();
490
 // G4double veloc_square = y_posvel.GetVelocity().mag2();
487
 // ...
491
 // ...
488
 // The following step cannot be done here because "eps" is not known.
492
 // The following step cannot be done here because "eps" is not known.
489
 dyerr_len = std::sqrt( dyerr_len_sq ); 
493
 dyerr_len = std::sqrt( dyerr_len_sq ); 
490
 dyerr_len_sq /= eps ;
494
 dyerr_len_sq /= eps ;
491
 // Look at the velocity deviation ?
495
 // Look at the velocity deviation ?
492
 //  sqr(yerr_vec[3])+sqr(yerr_vec[4])+sqr(yerr_vec[5]));
496
 //  sqr(yerr_vec[3])+sqr(yerr_vec[4])+sqr(yerr_vec[5]));
493
 // Set suggested new step
497
 // Set suggested new step
494
 hstep= ComputeNewStepSize( dyerr_len, hstep);
498
 hstep= ComputeNewStepSize( dyerr_len, hstep);
495
 if( dyerr_pos_sq > ( dyerr_mom_rel_sq * sqr(hstep) ) )
499
 if( dyerr_pos_sq > ( dyerr_mom_rel_sq * sqr(hstep) ) )
496
 {
500
 {
497
   dyerr = std::sqrt(dyerr_pos_sq);
501
   dyerr = std::sqrt(dyerr_pos_sq);
498
 }
502
 }
499
 else
503
 else
500
 {
504
 {
501
   // Scale it to the current step size - for now
505
   // Scale it to the current step size - for now
502
   dyerr = std::sqrt(dyerr_mom_rel_sq) * hstep;
506
   dyerr = std::sqrt(dyerr_mom_rel_sq) * hstep;
503
 }
507
 }
504
 return true;
508
 return true;
505
                                 G4double     yarrin[],    // In
509
                                 G4double     yarrin[],    // In
506
                           const G4double     dydx[],  
510
                           const G4double     dydx[],  
507
                                 G4double     hstep,       // In
511
                                 G4double     hstep,       // In
508
                                 G4double     yarrout[],
512
                                 G4double     yarrout[],
509
                                 G4double&    dchord_step,
513
                                 G4double&    dchord_step,
510
                                 G4double&    dyerr )      // In length
514
                                 G4double&    dyerr )      // In length
511
 G4Exception("G4MagInt_Driver::QuickAdvance()", "GeomField0001",
515
 G4Exception("G4MagInt_Driver::QuickAdvance()", "GeomField0001",
512
             FatalException, "Not yet implemented.");
516
             FatalException, "Not yet implemented.");
513
 dyerr = dchord_step = hstep * yarrin[0] * dydx[0];
517
 dyerr = dchord_step = hstep * yarrin[0] * dydx[0];
514
 yarrout[0]= yarrin[0];
518
 yarrout[0]= yarrin[0];
515
                         G4double  errMaxNorm,    // max error  (normalised)
519
                         G4double  errMaxNorm,    // max error  (normalised)
516
                         G4double  hstepCurrent)  // current step size
520
                         G4double  hstepCurrent)  // current step size
517
 G4double hnew;
521
 G4double hnew;
518
 // Compute size of next Step for a failed step
522
 // Compute size of next Step for a failed step
519
 if(errMaxNorm > 1.0 )
523
 if(errMaxNorm > 1.0 )
520
 {
524
 {
521
   // Step failed; compute the size of retrial Step.
525
   // Step failed; compute the size of retrial Step.
522
   hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPshrnk()) ;
526
   hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPshrnk()) ;
523
 } else if(errMaxNorm > 0.0 ) {
527
 } else if(errMaxNorm > 0.0 ) {
524
   // Compute size of next Step for a successful step
528
   // Compute size of next Step for a successful step
525
   hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPgrow()) ;
529
   hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPgrow()) ;
526
 } else {
530
 } else {
527
   // if error estimate is zero (possible) or negative (dubious)
531
   // if error estimate is zero (possible) or negative (dubious)
528
   hnew = max_stepping_increase * hstepCurrent; 
532
   hnew = max_stepping_increase * hstepCurrent; 
529
 }
533
 }
530
 return hnew;
534
 return hnew;
531
                         G4double  errMaxNorm,    // max error  (normalised)
535
                         G4double  errMaxNorm,    // max error  (normalised)
532
                         G4double  hstepCurrent)  // current step size
536
                         G4double  hstepCurrent)  // current step size
533
 G4double hnew;
537
 G4double hnew;
534
 // Compute size of next Step for a failed step
538
 // Compute size of next Step for a failed step
535
 if (errMaxNorm > 1.0 )
539
 if (errMaxNorm > 1.0 )
536
 {
540
 {
537
   // Step failed; compute the size of retrial Step.
541
   // Step failed; compute the size of retrial Step.
538
   hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPshrnk()) ;
542
   hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPshrnk()) ;
539
 
543
 
540
   if (hnew < max_stepping_decrease*hstepCurrent)
544
   if (hnew < max_stepping_decrease*hstepCurrent)
541
   {
545
   {
542
     hnew = max_stepping_decrease*hstepCurrent ;
546
     hnew = max_stepping_decrease*hstepCurrent ;
543
                        // reduce stepsize, but no more
547
                        // reduce stepsize, but no more
544
                        // than this factor (value= 1/10)
548
                        // than this factor (value= 1/10)
545
   }
549
   }
546
 }
550
 }
547
 else
551
 else
548
 {
552
 {
549
   // Compute size of next Step for a successful step
553
   // Compute size of next Step for a successful step
550
   if (errMaxNorm > errcon)
554
   if (errMaxNorm > errcon)
551
    { hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPgrow()); }
555
    { hnew = GetSafety()*hstepCurrent*std::pow(errMaxNorm,GetPgrow()); }
552
   else  // No more than a factor of 5 increase
556
   else  // No more than a factor of 5 increase
553
    { hnew = max_stepping_increase * hstepCurrent; }
557
    { hnew = max_stepping_increase * hstepCurrent; }
554
 }
558
 }
555
 return hnew;
559
 return hnew;
556
                                  G4double          xstart,
560
                                  G4double          xstart,
557
                                  const G4double*   CurrentArr, 
561
                                  const G4double*   CurrentArr, 
558
                                  G4double          xcurrent,
562
                                  G4double          xcurrent,
559
                                  G4double          requestStep, 
563
                                  G4double          requestStep, 
560
                                  G4int             subStepNo)
564
                                  G4int             subStepNo)
561
 // Potentially add as arguments:  
565
 // Potentially add as arguments:  
562
 //                                 <dydx>           - as Initial Force
566
 //                                 <dydx>           - as Initial Force
563
 //                                 stepTaken(hdid)  - last step taken
567
 //                                 stepTaken(hdid)  - last step taken
564
 //                                 nextStep (hnext) - proposal for size
568
 //                                 nextStep (hnext) - proposal for size
565
  G4FieldTrack  StartFT(G4ThreeVector(0,0,0),
569
  G4FieldTrack  StartFT(G4ThreeVector(0,0,0),
566
                G4ThreeVector(0,0,0), 0., 0., 0., 0. );
570
                G4ThreeVector(0,0,0), 0., 0., 0., 0. );
567
  G4FieldTrack  CurrentFT (StartFT);
571
  G4FieldTrack  CurrentFT (StartFT);
568
  StartFT.LoadFromArray( StartArr, fNoIntegrationVariables); 
572
  StartFT.LoadFromArray( StartArr, fNoIntegrationVariables); 
569
  StartFT.SetCurveLength( xstart);
573
  StartFT.SetCurveLength( xstart);
570
  CurrentFT.LoadFromArray( CurrentArr, fNoIntegrationVariables); 
574
  CurrentFT.LoadFromArray( CurrentArr, fNoIntegrationVariables); 
571
  CurrentFT.SetCurveLength( xcurrent );
575
  CurrentFT.SetCurveLength( xcurrent );
572
  PrintStatus(StartFT, CurrentFT, requestStep, subStepNo ); 
576
  PrintStatus(StartFT, CurrentFT, requestStep, subStepNo ); 
573
                 const G4FieldTrack&  StartFT,
577
                 const G4FieldTrack&  StartFT,
574
                 const G4FieldTrack&  CurrentFT, 
578
                 const G4FieldTrack&  CurrentFT, 
575
                 G4double             requestStep, 
579
                 G4double             requestStep, 
576
                 G4int                subStepNo)
580
                 G4int                subStepNo)
577
   G4int verboseLevel= fVerboseLevel;
581
   G4int verboseLevel= fVerboseLevel;
578
   static G4ThreadLocal G4int noPrecision= 5;
582
   static G4ThreadLocal G4int noPrecision= 5;
579
   G4int oldPrec= G4cout.precision(noPrecision);
583
   G4int oldPrec= G4cout.precision(noPrecision);
580
   // G4cout.setf(ios_base::fixed,ios_base::floatfield);
584
   // G4cout.setf(ios_base::fixed,ios_base::floatfield);
581
   const G4ThreeVector StartPosition=       StartFT.GetPosition();
585
   const G4ThreeVector StartPosition=       StartFT.GetPosition();
582
   const G4ThreeVector StartUnitVelocity=   StartFT.GetMomentumDir();
586
   const G4ThreeVector StartUnitVelocity=   StartFT.GetMomentumDir();
583
   const G4ThreeVector CurrentPosition=     CurrentFT.GetPosition();
587
   const G4ThreeVector CurrentPosition=     CurrentFT.GetPosition();
584
   const G4ThreeVector CurrentUnitVelocity= CurrentFT.GetMomentumDir();
588
   const G4ThreeVector CurrentUnitVelocity= CurrentFT.GetMomentumDir();
585
   G4double  DotStartCurrentVeloc= StartUnitVelocity.dot(CurrentUnitVelocity);
589
   G4double  DotStartCurrentVeloc= StartUnitVelocity.dot(CurrentUnitVelocity);
586
   G4double step_len= CurrentFT.GetCurveLength() - StartFT.GetCurveLength();
590
   G4double step_len= CurrentFT.GetCurveLength() - StartFT.GetCurveLength();
587
   G4double subStepSize = step_len;
591
   G4double subStepSize = step_len;
588
    
592
    
589
   if( (subStepNo <= 1) || (verboseLevel > 3) )
593
   if( (subStepNo <= 1) || (verboseLevel > 3) )
590
   {
594
   {
591
      subStepNo = - subStepNo;        // To allow printing banner
595
      subStepNo = - subStepNo;        // To allow printing banner
592
      G4cout << std::setw( 6)  << " " << std::setw( 25)
596
      G4cout << std::setw( 6)  << " " << std::setw( 25)
593
             << " G4MagInt_Driver: Current Position  and  Direction" << " "
597
             << " G4MagInt_Driver: Current Position  and  Direction" << " "
594
             << G4endl; 
598
             << G4endl; 
595
      G4cout << std::setw( 5) << "Step#" << " "
599
      G4cout << std::setw( 5) << "Step#" << " "
596
             << std::setw( 7) << "s-curve" << " "
600
             << std::setw( 7) << "s-curve" << " "
597
             << std::setw( 9) << "X(mm)" << " "
601
             << std::setw( 9) << "X(mm)" << " "
598
             << std::setw( 9) << "Y(mm)" << " "  
602
             << std::setw( 9) << "Y(mm)" << " "  
599
             << std::setw( 9) << "Z(mm)" << " "
603
             << std::setw( 9) << "Z(mm)" << " "
600
             << std::setw( 8) << " N_x " << " "
604
             << std::setw( 8) << " N_x " << " "
601
             << std::setw( 8) << " N_y " << " "
605
             << std::setw( 8) << " N_y " << " "
602
             << std::setw( 8) << " N_z " << " "
606
             << std::setw( 8) << " N_z " << " "
603
             << std::setw( 8) << " N^2-1 " << " "
607
             << std::setw( 8) << " N^2-1 " << " "
604
             << std::setw(10) << " N(0).N " << " "
608
             << std::setw(10) << " N(0).N " << " "
605
             << std::setw( 7) << "KinEner " << " "
609
             << std::setw( 7) << "KinEner " << " "
606
             << std::setw(12) << "Track-l" << " "   // Add the Sub-step ??
610
             << std::setw(12) << "Track-l" << " "   // Add the Sub-step ??
607
             << std::setw(12) << "Step-len" << " " 
611
             << std::setw(12) << "Step-len" << " " 
608
             << std::setw(12) << "Step-len" << " " 
612
             << std::setw(12) << "Step-len" << " " 
609
             << std::setw( 9) << "ReqStep" << " "  
613
             << std::setw( 9) << "ReqStep" << " "  
610
             << G4endl;
614
             << G4endl;
611
   }
615
   }
612
   if( (subStepNo <= 0) )
616
   if( (subStepNo <= 0) )
613
   {
617
   {
614
     PrintStat_Aux( StartFT,  requestStep, 0., 
618
     PrintStat_Aux( StartFT,  requestStep, 0., 
615
                      0,        0.0,         1.0);
619
                      0,        0.0,         1.0);
616
     //*************
620
     //*************
617
   }
621
   }
618
   if( verboseLevel <= 3 )
622
   if( verboseLevel <= 3 )
619
   {
623
   {
620
     G4cout.precision(noPrecision);
624
     G4cout.precision(noPrecision);
621
     PrintStat_Aux( CurrentFT, requestStep, step_len, 
625
     PrintStat_Aux( CurrentFT, requestStep, step_len, 
622
                    subStepNo, subStepSize, DotStartCurrentVeloc );
626
                    subStepNo, subStepSize, DotStartCurrentVeloc );
623
     //*************
627
     //*************
624
   }
628
   }
625
   else // if( verboseLevel > 3 )
629
   else // if( verboseLevel > 3 )
626
   {
630
   {
627
      //  Multi-line output
631
      //  Multi-line output
628
      
632
      
629
      // G4cout << "Current  Position is " << CurrentPosition << G4endl 
633
      // G4cout << "Current  Position is " << CurrentPosition << G4endl 
630
      //    << " and UnitVelocity is " << CurrentUnitVelocity << G4endl;
634
      //    << " and UnitVelocity is " << CurrentUnitVelocity << G4endl;
631
      // G4cout << "Step taken was " << step_len  
635
      // G4cout << "Step taken was " << step_len  
632
      //    << " out of PhysicalStep= " <<  requestStep << G4endl;
636
      //    << " out of PhysicalStep= " <<  requestStep << G4endl;
633
      // G4cout << "Final safety is: " << safety << G4endl;
637
      // G4cout << "Final safety is: " << safety << G4endl;
634
      // G4cout << "Chord length = " << (CurrentPosition-StartPosition).mag()
638
      // G4cout << "Chord length = " << (CurrentPosition-StartPosition).mag()
635
      //        << G4endl << G4endl; 
639
      //        << G4endl << G4endl; 
636
   }
640
   }
637
   G4cout.precision(oldPrec);
641
   G4cout.precision(oldPrec);
638
                 const G4FieldTrack&  aFieldTrack,
642
                 const G4FieldTrack&  aFieldTrack,
639
                 G4double             requestStep, 
643
                 G4double             requestStep, 
640
                 G4double             step_len,
644
                 G4double             step_len,
641
                 G4int                subStepNo,
645
                 G4int                subStepNo,
642
                 G4double             subStepSize,
646
                 G4double             subStepSize,
643
                 G4double             dotVeloc_StartCurr)
647
                 G4double             dotVeloc_StartCurr)
644
   const G4ThreeVector Position=      aFieldTrack.GetPosition();
648
   const G4ThreeVector Position=      aFieldTrack.GetPosition();
645
   const G4ThreeVector UnitVelocity=  aFieldTrack.GetMomentumDir();
649
   const G4ThreeVector UnitVelocity=  aFieldTrack.GetMomentumDir();
646
650
647
   if( subStepNo >= 0)
651
   if( subStepNo >= 0)
648
   {
652
   {
649
      G4cout << std::setw( 5) << subStepNo << " ";
653
      G4cout << std::setw( 5) << subStepNo << " ";
650
   }
654
   }
651
   else
655
   else
652
   {
656
   {
653
      G4cout << std::setw( 5) << "Start" << " ";
657
      G4cout << std::setw( 5) << "Start" << " ";
654
   }
658
   }
655
   G4double curveLen= aFieldTrack.GetCurveLength();
659
   G4double curveLen= aFieldTrack.GetCurveLength();
656
   G4cout << std::setw( 7) << curveLen;
660
   G4cout << std::setw( 7) << curveLen;
657
   G4cout << std::setw( 9) << Position.x() << " "
661
   G4cout << std::setw( 9) << Position.x() << " "
658
          << std::setw( 9) << Position.y() << " "
662
          << std::setw( 9) << Position.y() << " "
659
          << std::setw( 9) << Position.z() << " "
663
          << std::setw( 9) << Position.z() << " "
660
          << std::setw( 8) << UnitVelocity.x() << " "
664
          << std::setw( 8) << UnitVelocity.x() << " "
661
          << std::setw( 8) << UnitVelocity.y() << " "
665
          << std::setw( 8) << UnitVelocity.y() << " "
662
          << std::setw( 8) << UnitVelocity.z() << " ";
666
          << std::setw( 8) << UnitVelocity.z() << " ";
663
   G4int oldprec= G4cout.precision(3);
667
   G4int oldprec= G4cout.precision(3);
664
   G4cout << std::setw( 8) << UnitVelocity.mag2()-1.0 << " ";
668
   G4cout << std::setw( 8) << UnitVelocity.mag2()-1.0 << " ";
665
   G4cout.precision(6);
669
   G4cout.precision(6);
666
   G4cout << std::setw(10) << dotVeloc_StartCurr << " ";
670
   G4cout << std::setw(10) << dotVeloc_StartCurr << " ";
667
   G4cout.precision(oldprec);
671
   G4cout.precision(oldprec);
668
   G4cout << std::setw( 7) << aFieldTrack.GetKineticEnergy();
672
   G4cout << std::setw( 7) << aFieldTrack.GetKineticEnergy();
669
   G4cout << std::setw(12) << step_len << " ";
673
   G4cout << std::setw(12) << step_len << " ";
670
   static G4ThreadLocal G4double oldCurveLength= 0.0;
674
   static G4ThreadLocal G4double oldCurveLength= 0.0;
671
   static G4ThreadLocal G4double oldSubStepLength= 0.0;
675
   static G4ThreadLocal G4double oldSubStepLength= 0.0;
672
   static G4ThreadLocal G4int oldSubStepNo= -1;
676
   static G4ThreadLocal G4int oldSubStepNo= -1;
673
   G4double subStep_len=0.0;
677
   G4double subStep_len=0.0;
674
   if( curveLen > oldCurveLength )
678
   if( curveLen > oldCurveLength )
675
   {
679
   {
676
     subStep_len= curveLen - oldCurveLength;
680
     subStep_len= curveLen - oldCurveLength;
677
   }
681
   }
678
   else if (subStepNo == oldSubStepNo)
682
   else if (subStepNo == oldSubStepNo)
679
   {
683
   {
680
     subStep_len= oldSubStepLength;
684
     subStep_len= oldSubStepLength;
681
   }
685
   }
682
   oldCurveLength= curveLen;
686
   oldCurveLength= curveLen;
683
   oldSubStepLength= subStep_len;
687
   oldSubStepLength= subStep_len;
684
   G4cout << std::setw(12) << subStep_len << " "; 
688
   G4cout << std::setw(12) << subStep_len << " "; 
685
   G4cout << std::setw(12) << subStepSize << " "; 
689
   G4cout << std::setw(12) << subStepSize << " "; 
686
   if( requestStep != -1.0 )
690
   if( requestStep != -1.0 )
687
   {
691
   {
688
     G4cout << std::setw( 9) << requestStep << " ";
692
     G4cout << std::setw( 9) << requestStep << " ";
689
   }
693
   }
690
   else
694
   else
691
   {
695
   {
692
      G4cout << std::setw( 9) << " InitialStep " << " ";
696
      G4cout << std::setw( 9) << " InitialStep " << " ";
693
   }
697
   }
694
   G4cout << G4endl;
698
   G4cout << G4endl;
695
 G4int noPrecBig= 6;
699
 G4int noPrecBig= 6;
696
 G4int oldPrec= G4cout.precision(noPrecBig);
700
 G4int oldPrec= G4cout.precision(noPrecBig);
697
 G4cout << "G4MagInt_Driver Statistics of steps undertaken. " << G4endl;
701
 G4cout << "G4MagInt_Driver Statistics of steps undertaken. " << G4endl;
698
 G4cout << "G4MagInt_Driver: Number of Steps: "
702
 G4cout << "G4MagInt_Driver: Number of Steps: "
699
        << " Total= " <<  fNoTotalSteps
703
        << " Total= " <<  fNoTotalSteps
700
        << " Bad= "   <<  fNoBadSteps 
704
        << " Bad= "   <<  fNoBadSteps 
701
        << " Small= " <<  fNoSmallSteps 
705
        << " Small= " <<  fNoSmallSteps 
702
        << " Non-initial small= " << (fNoSmallSteps-fNoInitialSmallSteps)
706
        << " Non-initial small= " << (fNoSmallSteps-fNoInitialSmallSteps)
703
        << G4endl;
707
        << G4endl;
704
 G4cout << "MID dyerr: " 
708
 G4cout << "MID dyerr: " 
705
        << " maximum= " << fDyerr_max 
709
        << " maximum= " << fDyerr_max 
706
        << " Sum small= " << fDyerrPos_smTot 
710
        << " Sum small= " << fDyerrPos_smTot 
707
        << " std::sqrt(Sum large^2): pos= " << std::sqrt(fDyerrPos_lgTot)
711
        << " std::sqrt(Sum large^2): pos= " << std::sqrt(fDyerrPos_lgTot)
708
        << " vel= " << std::sqrt( fDyerrVel_lgTot )
712
        << " vel= " << std::sqrt( fDyerrVel_lgTot )
709
        << " Total h-distance: small= " << fSumH_sm 
713
        << " Total h-distance: small= " << fSumH_sm 
710
        << " large= " << fSumH_lg
714
        << " large= " << fSumH_lg
711
        << G4endl;
715
        << G4endl;
712
 G4int noPrecSmall=4; 
716
 G4int noPrecSmall=4; 
713
 // Single line precis of statistics ... optional
717
 // Single line precis of statistics ... optional
714
 G4cout.precision(noPrecSmall);
718
 G4cout.precision(noPrecSmall);
715
 G4cout << "MIDnums: " << fMinimumStep
719
 G4cout << "MIDnums: " << fMinimumStep
716
        << "   " << fNoTotalSteps 
720
        << "   " << fNoTotalSteps 
717
        << "  "  <<  fNoSmallSteps
721
        << "  "  <<  fNoSmallSteps
718
        << "  "  << fNoSmallSteps-fNoInitialSmallSteps
722
        << "  "  << fNoSmallSteps-fNoInitialSmallSteps
719
        << "  "  << fNoBadSteps         
723
        << "  "  << fNoBadSteps         
720
        << "   " << fDyerr_max
724
        << "   " << fDyerr_max
721
        << "   " << fDyerr_mx2 
725
        << "   " << fDyerr_mx2 
722
        << "   " << fDyerrPos_smTot 
726
        << "   " << fDyerrPos_smTot 
723
        << "   " << fSumH_sm
727
        << "   " << fSumH_sm
724
        << "   " << fDyerrPos_lgTot
728
        << "   " << fDyerrPos_lgTot
725
        << "   " << fDyerrVel_lgTot
729
        << "   " << fDyerrVel_lgTot
726
        << "   " << fSumH_lg
730
        << "   " << fSumH_lg
727
        << G4endl;
731
        << G4endl;
728
G4cout.precision(oldPrec);
732
G4cout.precision(oldPrec);
729
733
730
 if( (newFraction > 1.e-16) && (newFraction < 1e-8) )
734
 if( (newFraction > 1.e-16) && (newFraction < 1e-8) )
731
 {
735
 {
732
   fSmallestFraction= newFraction;
736
   fSmallestFraction= newFraction;
733
 }
737
 }
734
 else
738
 else
735
 { 
739
 { 
736
   G4cerr << "Warning: SmallestFraction not changed. " << G4endl
740
   G4cerr << "Warning: SmallestFraction not changed. " << G4endl
737
          << "  Proposed value was " << newFraction << G4endl
741
          << "  Proposed value was " << newFraction << G4endl
738
          << "  Value must be between 1.e-8 and 1.e-16" << G4endl;
742
          << "  Value must be between 1.e-8 and 1.e-16" << G4endl;
739
 }
743
 }

Return to problem 1696