137 G4int nstp, i, no_warnings=0;
142 static G4int nStpPr=50;
150 G4bool succeeded =
true, lastStepSucceeded;
154 G4int noFullIntegr=0, noSmallIntegr = 0 ;
156 const G4int nvar= fNoVars;
166 std::ostringstream message;
167 message <<
"Proposed step is zero; hstep = " << hstep <<
" !";
168 G4Exception(
"G4FSALIntegrationDriver::AccurateAdvance()",
174 std::ostringstream message;
175 message <<
"Invalid run condition." <<
G4endl
176 <<
"Proposed step is negative; hstep = " << hstep <<
"." <<
G4endl
177 <<
"Requested step cannot be negative! Aborting event.";
178 G4Exception(
"G4FSALIntegrationDriver::AccurateAdvance()",
187 x1= startCurveLength;
190 if ( (hinitial > 0.0) && (hinitial < hstep)
202 for (i=0;i<nvar;i++) { y[i] = ystart[i]; }
216 for (i=0;i<nvar;i++) { ySubStepStart[i] = y[i]; }
217 yFldTrkStart.LoadFromArray(y, fNoIntegrationVariables);
218 yFldTrkStart.SetCurveLength(x);
228 if( h > fMinimumStep )
232 lastStepSucceeded= (hdid == h);
235 PrintStatus( ySubStepStart, xSubStepStart, y, x, h, nstp);
243 G4double dchord_step, dyerr, dyerr_len;
244 yFldTrk.LoadFromArray(y, fNoIntegrationVariables);
245 yFldTrk.SetCurveLength( x );
247 QuickAdvance( yFldTrk, dydx, h, dchord_step, dyerr_len );
250 yFldTrk.DumpToArray(y);
254 if ( dyerr_len > fDyerr_max) { fDyerr_max= dyerr_len; }
255 fDyerrPos_smTot += dyerr_len;
257 if (nstp<=1) { fNoInitialSmallSteps++; }
262 if(fNoSmallSteps<2) {
PrintStatus(ySubStepStart, x1, y, x, h, -nstp); }
263 G4cout <<
"Another sub-min step, no " << fNoSmallSteps
264 <<
" of " << fNoTotalSteps <<
" this time " << nstp <<
G4endl;
266 G4cout <<
" dyerr= " << dyerr_len <<
" relative = " << dyerr_len / h
267 <<
" epsilon= " <<
eps <<
" hstep= " << hstep
268 <<
" h= " << h <<
" hmin= " << fMinimumStep <<
G4endl;
273 G4Exception(
"G4FSALIntegrationDriver::AccurateAdvance()",
275 "Integration Step became Zero!");
277 dyerr = dyerr_len / h;
285 lastStepSucceeded= (dyerr<=
eps);
288 if (lastStepSucceeded) { noFullIntegr++; }
289 else { noSmallIntegr++; }
294 if( (dbg>0) && (dbg<=2) && (nstp>nStpPr))
296 if( nstp==nStpPr ) {
G4cout <<
"***** Many steps ****" <<
G4endl; }
298 G4cout <<
"hdid=" << std::setw(12) << hdid <<
" "
299 <<
"hnext=" << std::setw(12) << hnext <<
" "
300 <<
"hstep=" << std::setw(12) << hstep <<
" (requested) "
302 PrintStatus( ystart, x1, y, x, h, (nstp==nStpPr) ? -nstp: nstp);
307 G4double endPointDist= (EndPos-StartPos).mag();
320 G4cerr <<
" Total steps: bad " << fNoBadSteps
321 <<
" good " << noGoodSteps <<
" current h= " << hdid
323 PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
336 if( (h <
eps * hstep) || (h < fSmallestFraction * startCurveLength) )
344 if(std::fabs(hnext) <=
Hmin())
348 if( (x < x2 * (1-
eps) ) &&
349 (std::fabs(hstep) >
Hmin()) )
354 PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
381 G4cout <<
"Warning: FSALMagIntegratorDriver::AccurateAdvance"
383 <<
" Integration step 'h' became "
384 << h <<
" due to roundoff. " << G4endl
385 <<
" Calculated as difference of x2= "<< x2 <<
" and x=" << x
386 <<
" Forcing termination of advance." <<
G4endl;
392 }
while ( ((nstp++)<=fMaxNoSteps) && (x < x2) && (!lastStep) );
400 for (i=0;i<nvar;i++) { yEnd[i] = y[i]; }
406 if(nstp > fMaxNoSteps)
420 if( dbg && no_warnings )
422 G4cerr <<
"FSALMagIntegratorDriver exit status: no-steps " << nstp <<
G4endl;
static constexpr double perMillion
void WarnEndPointTooFar(G4double endPointDist, G4double hStepSize, G4double epsilonRelative, G4int debugFlag)
G4double GetCurveLength() const
CLHEP::Hep3Vector G4ThreeVector
void WarnSmallStepSize(G4double hnext, G4double hstep, G4double h, G4double xDone, G4int noSteps)
void SetCurveLength(G4double nCurve_s)
static const G4double eps
void WarnTooManyStep(G4double x1start, G4double x2end, G4double xCurrent)
G4GLOB_DLL std::ostream G4cout
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *comments)
void OneGoodStep(G4double ystart[], G4double dydx[], G4double &x, G4double htry, G4double eps, G4double &hdid, G4double &hnext)
void DumpToArray(G4double valArr[ncompSVEC]) const
G4double ComputeNewStepSize(G4double errMaxNorm, G4double hstepCurrent)
void LoadFromArray(const G4double valArr[ncompSVEC], G4int noVarsIntegrated)
G4bool QuickAdvance(G4FieldTrack &y_val, G4double dydx[], G4double hstep, G4double &dchord_step, G4double &dyerr)
static constexpr double perThousand
virtual void ComputeRightHandSide(const G4double y[], G4double dydx[])
void PrintStatus(const G4double *StartArr, G4double xstart, const G4double *CurrentArr, G4double xcurrent, G4double requestStep, G4int subStepNo)
G4GLOB_DLL std::ostream G4cerr