110 G4int no_warnings = 0;
111 static G4int dbg = 1;
123 const G4int nvar = fNoVars;
133 std::ostringstream message;
134 message <<
"Proposed step is zero; hstep = " << hstep <<
" !";
135 G4Exception(
"G4OldMagIntDriver::AccurateAdvance()",
140 std::ostringstream message;
141 message <<
"Invalid run condition." <<
G4endl
142 <<
"Proposed step is negative; hstep = " << hstep <<
"." <<
G4endl
143 <<
"Requested step cannot be negative! Aborting event.";
144 G4Exception(
"G4OldMagIntDriver::AccurateAdvance()",
152 x1= startCurveLength;
155 if ( (hinitial > 0.0) && (hinitial < hstep)
156 && (hinitial > perMillion * hstep) )
167 for ( i=0; i<nvar; ++i) { y[i] = ystart[i]; }
171 G4cout <<
"IDriver::AccurAdv called. "
172 <<
" Input: hstep = " << hstep <<
" hinitial= " << hinitial <<
" , current: h = " << h <<
G4endl;
184 for (i=0; i<nvar; ++i) { ySubStepStart[i] = y[i]; }
196 if( h > fMinimumStep )
204 G4cout <<
"IntegrationDriver -- after OneGoodStep / requesting step = " << h <<
G4endl;
214 G4double dchord_step, dyerr, dyerr_len;
218 QuickAdvance( yFldTrk, dydx, h, dchord_step, dyerr_len );
225 if ( dyerr_len > fDyerr_max ) { fDyerr_max = dyerr_len; }
226 fDyerrPos_smTot += dyerr_len;
228 if (nstp<=1) { ++fNoInitialSmallSteps; }
233 if(fNoSmallSteps<2) {
PrintStatus(ySubStepStart, x1, y, x, h, -nstp); }
234 G4cout <<
"Another sub-min step, no " << fNoSmallSteps
235 <<
" of " << fNoTotalSteps <<
" this time " << nstp <<
G4endl;
237 G4cout <<
" dyerr= " << dyerr_len <<
" relative = " << dyerr_len / h
238 <<
" epsilon= " << eps <<
" hstep= " << hstep
239 <<
" h= " << h <<
" hmin= " << fMinimumStep <<
G4endl;
244 G4Exception(
"G4OldMagIntDriver::AccurateAdvance()",
246 "Integration Step became Zero!");
248 dyerr = dyerr_len / h;
261 static G4int nStpPr = 50;
262 if( (dbg>0) && (dbg<=2) && (nstp>nStpPr))
264 if( nstp==nStpPr ) {
G4cout <<
"***** Many steps ****" <<
G4endl; }
266 G4cout <<
"hdid=" << std::setw(12) << hdid <<
" "
267 <<
"hnext=" << std::setw(12) << hnext <<
" "
268 <<
"hstep=" << std::setw(12) << hstep <<
" (requested) "
270 PrintStatus( ystart, x1, y, x, h, (nstp==nStpPr) ? -nstp: nstp);
275 G4double endPointDist= (EndPos-StartPos).mag();
276 if ( endPointDist >= hdid*(1.+perMillion) )
282 if ( endPointDist >= hdid*(1.+perThousand) )
288 G4cerr <<
" Total steps: bad " << fNoBadSteps
289 <<
" current h= " << hdid <<
G4endl;
290 PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
298 if( (h < eps * hstep) || (h < fSmallestFraction * startCurveLength) )
306 if(std::fabs(hnext) <=
Hmin())
310 if( (x < x2 * (1-eps) ) &&
311 (std::fabs(hstep) >
Hmin()) )
316 PrintStatus( ystart, x1, y, x, hstep, no_warnings?nstp:-nstp);
342 int prec=
G4cout.precision(12);
343 G4cout <<
"Warning: G4MagIntegratorDriver::AccurateAdvance"
345 <<
" Integration step 'h' became "
346 << h <<
" due to roundoff. " <<
G4endl
347 <<
" Calculated as difference of x2= "<< x2 <<
" and x=" << x
348 <<
" Forcing termination of advance." <<
G4endl;
354 }
while ( ((nstp++)<=fMaxNoSteps) && (x < x2) && (!lastStep) );
362 for (i=0; i<nvar; ++i) { yEnd[i] = y[i]; }
368 if(nstp > fMaxNoSteps)
382 if( dbg && no_warnings )
384 G4cerr <<
"G4MagIntegratorDriver exit status: no-steps " << nstp <<
G4endl;
509 G4double inv_eps_vel_sq = 1.0 / (eps_rel_max*eps_rel_max);
515 const G4int max_trials=100;
519 G4bool hasSpin = (spin_mag2 > 0.0);
521 for (
G4int iter=0; iter<max_trials; ++iter)
523 pIntStepper-> Stepper(y,dydx,h,ytemp,yerr);
525 G4double eps_pos = eps_rel_max * std::max(h, fMinimumStep);
526 G4double inv_eps_pos_sq = 1.0 / (eps_pos*eps_pos);
530 errpos_sq =
sqr(yerr[0]) +
sqr(yerr[1]) +
sqr(yerr[2]) ;
531 errpos_sq *= inv_eps_pos_sq;
536 if( magvel_sq > 0.0 )
538 errvel_sq = sumerr_sq / magvel_sq;
542 std::ostringstream message;
543 message <<
"Found case of zero momentum." <<
G4endl
544 <<
"- iteration= " << iter <<
"; h= " << h;
547 errvel_sq = sumerr_sq;
549 errvel_sq *= inv_eps_vel_sq;
550 errmax_sq = std::max( errpos_sq, errvel_sq );
555 errspin_sq = (
sqr(yerr[9]) +
sqr(yerr[10]) +
sqr(yerr[11]) )
557 errspin_sq *= inv_eps_vel_sq;
558 errmax_sq = std::max( errmax_sq, errspin_sq );
561 if ( errmax_sq <= 1.0 ) {
break; }
566 if (htemp >= 0.1*h) { h = htemp; }
572 std::ostringstream message;
573 message <<
"Stepsize underflow in Stepper !" <<
G4endl
574 <<
"- Step's start x=" << x <<
" and end x= " << xnew
575 <<
" are equal !! " <<
G4endl
576 <<
" Due to step-size= " << h
577 <<
". Note that input step was " << htry;
585 if (errmax_sq > errcon*errcon)
595 for(
G4int k=0; k<fNoIntegrationVariables; ++k) { y[k] = ytemp[k]; }
629 G4double dyerr_pos_sq, dyerr_mom_rel_sq;
633 G4double dyerr_mom_sq, vel_mag_sq, inv_vel_mag_sq;
644 pIntStepper-> Stepper(yarrin, dydx, hstep, yarrout, yerr_vec) ;
647 dchord_step= pIntStepper-> DistChord();
657 PrintStatus( yarrin, s_start, yarrout, s_start+hstep, hstep, 1);
663 vel_mag_sq = (
sqr(yarrout[3])+
sqr(yarrout[4])+
sqr(yarrout[5]) );
664 inv_vel_mag_sq = 1.0 / vel_mag_sq;
665 dyerr_pos_sq = (
sqr(yerr_vec[0])+
sqr(yerr_vec[1])+
sqr(yerr_vec[2]));
666 dyerr_mom_sq = (
sqr(yerr_vec[3])+
sqr(yerr_vec[4])+
sqr(yerr_vec[5]));
667 dyerr_mom_rel_sq = dyerr_mom_sq * inv_vel_mag_sq;
673#ifdef RETURN_A_NEW_STEP_LENGTH
675 dyerr_len = std::sqrt( dyerr_len_sq );
676 dyerr_len_sq /= eps ;
685 if( dyerr_pos_sq > ( dyerr_mom_rel_sq *
sqr(hstep) ) )
687 dyerr = std::sqrt(dyerr_pos_sq);
692 dyerr = std::sqrt(dyerr_mom_rel_sq) * hstep;
698 <<
"QuickAdvance" <<
G4endl
699 <<
" Input: hstep= " << hstep <<
G4endl
700 <<
" track= " << startTrack <<
G4endl
701 <<
" Output: track= " << y_posvel <<
G4endl
702 <<
" d_chord = " << dchord_step
703 <<
" dyerr = " << dyerr <<
G4endl;
827 G4int verboseLevel= fVerboseLevel;
837 G4double DotStartCurrentVeloc= StartUnitVelocity.
dot(CurrentUnitVelocity);
842 if( (subStepNo <= 1) || (verboseLevel > 3) )
844 subStepNo = - subStepNo;
846 G4cout << std::setw( 6) <<
" " << std::setw( 25)
847 <<
" G4OldMagIntDriver: Current Position and Direction" <<
" "
849 G4cout << std::setw( 5) <<
"Step#" <<
" "
850 << std::setw( 7) <<
"s-curve" <<
" "
851 << std::setw( 9) <<
"X(mm)" <<
" "
852 << std::setw( 9) <<
"Y(mm)" <<
" "
853 << std::setw( 9) <<
"Z(mm)" <<
" "
854 << std::setw( 8) <<
" N_x " <<
" "
855 << std::setw( 8) <<
" N_y " <<
" "
856 << std::setw( 8) <<
" N_z " <<
" "
857 << std::setw( 8) <<
" N^2-1 " <<
" "
858 << std::setw(10) <<
" N(0).N " <<
" "
859 << std::setw( 7) <<
"KinEner " <<
" "
860 << std::setw(12) <<
"Track-l" <<
" "
861 << std::setw(12) <<
"Step-len" <<
" "
862 << std::setw(12) <<
"Step-len" <<
" "
863 << std::setw( 9) <<
"ReqStep" <<
" "
867 if( (subStepNo <= 0) )
873 if( verboseLevel <= 3 )
877 subStepNo, subStepSize, DotStartCurrentVeloc );
880 G4cout.precision(oldPrec);
897 G4cout << std::setw( 5) << subStepNo <<
" ";
901 G4cout << std::setw( 5) <<
"Start" <<
" ";
904 G4cout << std::setw( 7) << curveLen;
905 G4cout << std::setw( 9) << Position.x() <<
" "
906 << std::setw( 9) << Position.y() <<
" "
907 << std::setw( 9) << Position.z() <<
" "
908 << std::setw( 8) << UnitVelocity.
x() <<
" "
909 << std::setw( 8) << UnitVelocity.
y() <<
" "
910 << std::setw( 8) << UnitVelocity.
z() <<
" ";
912 G4cout << std::setw( 8) << UnitVelocity.
mag2()-1.0 <<
" ";
914 G4cout << std::setw(10) << dotVeloc_StartCurr <<
" ";
915 G4cout.precision(oldprec);
917 G4cout << std::setw(12) << step_len <<
" ";
924 if( curveLen > oldCurveLength )
926 subStep_len= curveLen - oldCurveLength;
928 else if (subStepNo == oldSubStepNo)
930 subStep_len= oldSubStepLength;
932 oldCurveLength= curveLen;
933 oldSubStepLength= subStep_len;
935 G4cout << std::setw(12) << subStep_len <<
" ";
936 G4cout << std::setw(12) << subStepSize <<
" ";
937 if( requestStep != -1.0 )
939 G4cout << std::setw( 9) << requestStep <<
" ";
943 G4cout << std::setw( 9) <<
" InitialStep " <<
" ";