|
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 |
} |