#include <G4ChordFinder.hh>
Inheritance diagram for G4ChordFinder:
Public Member Functions | |
G4ChordFinder (G4MagInt_Driver *pIntegrationDriver) | |
G4ChordFinder (G4MagneticField *itsMagField, G4double stepMinimum=1.0e-2, G4MagIntegratorStepper *pItsStepper=0) | |
virtual | ~G4ChordFinder () |
G4double | AdvanceChordLimited (G4FieldTrack &yCurrent, G4double stepInitial, G4double epsStep_Relative, const G4ThreeVector latestSafetyOrigin, G4double lasestSafetyRadius) |
G4FieldTrack | ApproxCurvePointS (const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4FieldTrack &ApproxCurveV, const G4ThreeVector ¤tEPoint, const G4ThreeVector ¤tFPoint, const G4ThreeVector &PointG, G4bool first, G4double epsStep) |
G4FieldTrack | ApproxCurvePointV (const G4FieldTrack &curveAPointVelocity, const G4FieldTrack &curveBPointVelocity, const G4ThreeVector ¤tEPoint, G4double epsStep) |
G4double | InvParabolic (const G4double xa, const G4double ya, const G4double xb, const G4double yb, const G4double xc, const G4double yc) |
G4double | GetDeltaChord () const |
void | SetDeltaChord (G4double newval) |
void | SetChargeMomentumMass (G4double pCharge, G4double pMomentum, G4double pMass) |
void | SetIntegrationDriver (G4MagInt_Driver *IntegrationDriver) |
G4MagInt_Driver * | GetIntegrationDriver () |
void | ResetStepEstimate () |
G4int | GetNoCalls () |
G4int | GetNoTrials () |
G4int | GetNoMaxTrials () |
virtual void | PrintStatistics () |
G4int | SetVerbose (G4int newvalue=1) |
void | SetFractions_Last_Next (G4double fractLast=0.90, G4double fractNext=0.95) |
void | SetFirstFraction (G4double fractFirst) |
void | TestChordPrint (G4int noTrials, G4int lastStepTrial, G4double dChordStep, G4double nextStepTrial) |
G4double | GetFirstFraction () |
G4double | GetFractionLast () |
G4double | GetFractionNextEstimate () |
G4double | GetMultipleRadius () |
Protected Member Functions | |
void | AccumulateStatistics (G4int noTrials) |
G4bool | AcceptableMissDist (G4double dChordStep) const |
G4double | NewStep (G4double stepTrialOld, G4double dChordStep, G4double &stepEstimate_Unconstrained) |
virtual G4double | FindNextChord (const G4FieldTrack &yStart, G4double stepMax, G4FieldTrack &yEnd, G4double &dyErr, G4double epsStep, G4double *pNextStepForAccuracy, const G4ThreeVector latestSafetyOrigin, G4double latestSafetyRadius) |
void | PrintDchordTrial (G4int noTrials, G4double stepTrial, G4double oldStepTrial, G4double dChordStep) |
G4double | GetLastStepEstimateUnc () |
void | SetLastStepEstimateUnc (G4double stepEst) |
Definition at line 50 of file G4ChordFinder.hh.
G4ChordFinder::G4ChordFinder | ( | G4MagInt_Driver * | pIntegrationDriver | ) |
Definition at line 44 of file G4ChordFinder.cc.
References DBL_MAX, and SetFractions_Last_Next().
00045 : fDefaultDeltaChord( 0.25 * mm ), // Parameters 00046 fDeltaChord( fDefaultDeltaChord ), // Internal parameters 00047 fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98), 00048 fMultipleRadius(15.0), 00049 fStatsVerbose(0), 00050 fDriversStepper(0), // Dependent objects 00051 fAllocatedStepper(false), 00052 fEquation(0), 00053 fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0) 00054 { 00055 // Simple constructor -- it does not create equation 00056 fIntgrDriver= pIntegrationDriver; 00057 fAllocatedStepper= false; 00058 00059 fLastStepEstimate_Unconstrained = DBL_MAX; // Should move q, p to 00060 00061 SetFractions_Last_Next( fFractionLast, fFractionNextEstimate); 00062 // check the values and set the other parameters 00063 }
G4ChordFinder::G4ChordFinder | ( | G4MagneticField * | itsMagField, | |
G4double | stepMinimum = 1.0e-2 , |
|||
G4MagIntegratorStepper * | pItsStepper = 0 | |||
) |
Definition at line 68 of file G4ChordFinder.cc.
References DBL_MAX, G4MagIntegratorStepper::GetNumberOfVariables(), and SetFractions_Last_Next().
00071 : fDefaultDeltaChord( 0.25 * mm ), // Constants 00072 fDeltaChord( fDefaultDeltaChord ), // Parameters 00073 fFirstFraction(0.999), fFractionLast(1.00), fFractionNextEstimate(0.98), 00074 fMultipleRadius(15.0), 00075 fStatsVerbose(0), 00076 fDriversStepper(0), // Dependent objects 00077 fAllocatedStepper(false), 00078 fEquation(0), 00079 fTotalNoTrials_FNC(0), fNoCalls_FNC(0), fmaxTrials_FNC(0) // State - stats 00080 { 00081 // Construct the Chord Finder 00082 // by creating in inverse order the Driver, the Stepper and EqRhs ... 00083 00084 G4Mag_EqRhs *pEquation = new G4Mag_UsualEqRhs(theMagField); 00085 fEquation = pEquation; 00086 fLastStepEstimate_Unconstrained = DBL_MAX; // Should move q, p to 00087 // G4FieldTrack ?? 00088 00089 SetFractions_Last_Next( fFractionLast, fFractionNextEstimate); 00090 // check the values and set the other parameters 00091 00092 // --->> Charge Q = 0 00093 // --->> Momentum P = 1 NOMINAL VALUES !!!!!!!!!!!!!!!!!! 00094 00095 if( pItsStepper == 0 ) 00096 { 00097 pItsStepper = fDriversStepper = new G4ClassicalRK4(pEquation); 00098 fAllocatedStepper= true; 00099 } 00100 else 00101 { 00102 fAllocatedStepper= false; 00103 } 00104 fIntgrDriver = new G4MagInt_Driver(stepMinimum, pItsStepper, 00105 pItsStepper->GetNumberOfVariables() ); 00106 }
G4ChordFinder::~G4ChordFinder | ( | ) | [virtual] |
Definition at line 111 of file G4ChordFinder.cc.
References PrintStatistics().
00112 { 00113 delete fEquation; // fIntgrDriver->pIntStepper->theEquation_Rhs; 00114 if( fAllocatedStepper) 00115 { 00116 delete fDriversStepper; 00117 } 00118 delete fIntgrDriver; 00119 00120 if( fStatsVerbose ) { PrintStatistics(); } 00121 }
Definition at line 46 of file G4ChordFinder.icc.
Referenced by G4ChordFinderSaf::FindNextChord(), and FindNextChord().
void G4ChordFinder::AccumulateStatistics | ( | G4int | noTrials | ) | [inline, protected] |
Definition at line 110 of file G4ChordFinder.icc.
Referenced by G4ChordFinderSaf::FindNextChord(), and FindNextChord().
00111 { 00112 // Statistics 00113 fTotalNoTrials_FNC += noTrials; 00114 fNoCalls_FNC++; 00115 // if( noTrials >= fmaxTrials_FNC ){ 00116 if (noTrials > fmaxTrials_FNC ) { 00117 fmaxTrials_FNC=noTrials; 00118 // fnoTimesMaxTrFNC=0; 00119 } else { 00120 // fnoTimesMaxTrFNC++; 00121 } 00122 // } 00123 }
G4double G4ChordFinder::AdvanceChordLimited | ( | G4FieldTrack & | yCurrent, | |
G4double | stepInitial, | |||
G4double | epsStep_Relative, | |||
const G4ThreeVector | latestSafetyOrigin, | |||
G4double | lasestSafetyRadius | |||
) |
Definition at line 172 of file G4ChordFinder.cc.
References G4MagInt_Driver::AccurateAdvance(), FindNextChord(), and G4FieldTrack::GetCurveLength().
Referenced by G4PropagatorInField::ComputeStep().
00177 { 00178 G4double stepPossible; 00179 G4double dyErr; 00180 G4FieldTrack yEnd( yCurrent); 00181 G4double startCurveLen= yCurrent.GetCurveLength(); 00182 G4double nextStep; 00183 // ************* 00184 stepPossible= FindNextChord(yCurrent, stepMax, yEnd, dyErr, epsStep, 00185 &nextStep, latestSafetyOrigin, latestSafetyRadius 00186 ); 00187 // ************* 00188 00189 G4bool good_advance; 00190 00191 if ( dyErr < epsStep * stepPossible ) 00192 { 00193 // Accept this accuracy. 00194 00195 yCurrent = yEnd; 00196 good_advance = true; 00197 } 00198 else 00199 { 00200 // Advance more accurately to "end of chord" 00201 // *************** 00202 good_advance = fIntgrDriver->AccurateAdvance(yCurrent, stepPossible, 00203 epsStep, nextStep); 00204 if ( ! good_advance ) 00205 { 00206 // In this case the driver could not do the full distance 00207 stepPossible= yCurrent.GetCurveLength()-startCurveLen; 00208 } 00209 } 00210 return stepPossible; 00211 }
G4FieldTrack G4ChordFinder::ApproxCurvePointS | ( | const G4FieldTrack & | curveAPointVelocity, | |
const G4FieldTrack & | curveBPointVelocity, | |||
const G4FieldTrack & | ApproxCurveV, | |||
const G4ThreeVector & | currentEPoint, | |||
const G4ThreeVector & | currentFPoint, | |||
const G4ThreeVector & | PointG, | |||
G4bool | first, | |||
G4double | epsStep | |||
) |
Definition at line 413 of file G4ChordFinder.cc.
References G4MagInt_Driver::AccurateAdvance(), ApproxCurvePointV(), G4cout, G4endl, G4FieldTrack::GetCurveLength(), G4FieldTrack::GetPosition(), and InvParabolic().
Referenced by G4BrentLocator::EstimateIntersectionPoint().
00420 { 00421 // ApproxCurvePointS is 2nd implementation of ApproxCurvePoint. 00422 // Use Brent Algorithm (or InvParabolic) when possible. 00423 // Given a starting curve point A (CurveA_PointVelocity), curve point B 00424 // (CurveB_PointVelocity), a point E which is (generally) not on the curve 00425 // and a point F which is on the curve (first approximation), find new 00426 // point S on the curve closer to point E. 00427 // While advancing towards S utilise 'eps_step' as a measure of the 00428 // relative accuracy of each Step. 00429 00430 G4FieldTrack EndPoint(CurveA_PointVelocity); 00431 if(!first){EndPoint= ApproxCurveV;} 00432 00433 G4ThreeVector Point_A,Point_B; 00434 Point_A=CurveA_PointVelocity.GetPosition(); 00435 Point_B=CurveB_PointVelocity.GetPosition(); 00436 00437 G4double xa,xb,xc,ya,yb,yc; 00438 00439 // InverseParabolic. AF Intersects (First Part of Curve) 00440 00441 if(first) 00442 { 00443 xa=0.; 00444 ya=(PointG-Point_A).mag(); 00445 xb=(Point_A-CurrentF_Point).mag(); 00446 yb=-(PointG-CurrentF_Point).mag(); 00447 xc=(Point_A-Point_B).mag(); 00448 yc=-(CurrentE_Point-Point_B).mag(); 00449 } 00450 else 00451 { 00452 xa=0.; 00453 ya=(Point_A-CurrentE_Point).mag(); 00454 xb=(Point_A-CurrentF_Point).mag(); 00455 yb=(PointG-CurrentF_Point).mag(); 00456 xc=(Point_A-Point_B).mag(); 00457 yc=-(Point_B-PointG).mag(); 00458 if(xb==0.) 00459 { 00460 EndPoint= 00461 ApproxCurvePointV(CurveA_PointVelocity, CurveB_PointVelocity, 00462 CurrentE_Point, eps_step); 00463 return EndPoint; 00464 } 00465 } 00466 00467 const G4double tolerance= 1.e-12; 00468 if(std::abs(ya)<=tolerance||std::abs(yc)<=tolerance) 00469 { 00470 ; // What to do for the moment: return the same point as at start 00471 // then PropagatorInField will take care 00472 } 00473 else 00474 { 00475 G4double test_step = InvParabolic(xa,ya,xb,yb,xc,yc); 00476 G4double curve; 00477 if(first) 00478 { 00479 curve=std::abs(EndPoint.GetCurveLength() 00480 -ApproxCurveV.GetCurveLength()); 00481 } 00482 else 00483 { 00484 test_step=(test_step-xb); 00485 curve=std::abs(EndPoint.GetCurveLength() 00486 -CurveB_PointVelocity.GetCurveLength()); 00487 xb=(CurrentF_Point-Point_B).mag(); 00488 } 00489 00490 if(test_step<=0) { test_step=0.1*xb; } 00491 if(test_step>=xb) { test_step=0.5*xb; } 00492 if(test_step>=curve){ test_step=0.5*curve; } 00493 00494 if(curve*(1.+eps_step)<xb) // Similar to ReEstimate Step from 00495 { // G4VIntersectionLocator 00496 test_step=0.5*curve; 00497 } 00498 00499 fIntgrDriver->AccurateAdvance(EndPoint,test_step, eps_step); 00500 00501 #ifdef G4DEBUG_FIELD 00502 // Printing Brent and Linear Approximation 00503 // 00504 G4cout << "G4ChordFinder::ApproxCurvePointS() - test-step ShF = " 00505 << test_step << " EndPoint = " << EndPoint << G4endl; 00506 00507 // Test Track 00508 // 00509 G4FieldTrack TestTrack( CurveA_PointVelocity); 00510 TestTrack = ApproxCurvePointV( CurveA_PointVelocity, 00511 CurveB_PointVelocity, 00512 CurrentE_Point, eps_step ); 00513 G4cout.precision(14); 00514 G4cout << "G4ChordFinder::BrentApprox = " << EndPoint << G4endl; 00515 G4cout << "G4ChordFinder::LinearApprox= " << TestTrack << G4endl; 00516 #endif 00517 } 00518 return EndPoint; 00519 }
G4FieldTrack G4ChordFinder::ApproxCurvePointV | ( | const G4FieldTrack & | curveAPointVelocity, | |
const G4FieldTrack & | curveBPointVelocity, | |||
const G4ThreeVector & | currentEPoint, | |||
G4double | epsStep | |||
) |
Definition at line 525 of file G4ChordFinder.cc.
References G4MagInt_Driver::AccurateAdvance(), FatalException, G4cerr, G4cout, G4endl, G4Exception(), G4FieldTrack::GetCurveLength(), and G4FieldTrack::GetPosition().
Referenced by ApproxCurvePointS(), G4SimpleLocator::EstimateIntersectionPoint(), G4MultiLevelLocator::EstimateIntersectionPoint(), and G4BrentLocator::EstimateIntersectionPoint().
00529 { 00530 // If r=|AE|/|AB|, and s=true path lenght (AB) 00531 // return the point that is r*s along the curve! 00532 00533 G4FieldTrack Current_PointVelocity = CurveA_PointVelocity; 00534 00535 G4ThreeVector CurveA_Point= CurveA_PointVelocity.GetPosition(); 00536 G4ThreeVector CurveB_Point= CurveB_PointVelocity.GetPosition(); 00537 00538 G4ThreeVector ChordAB_Vector= CurveB_Point - CurveA_Point; 00539 G4ThreeVector ChordAE_Vector= CurrentE_Point - CurveA_Point; 00540 00541 G4double ABdist= ChordAB_Vector.mag(); 00542 G4double curve_length; // A curve length of AB 00543 G4double AE_fraction; 00544 00545 curve_length= CurveB_PointVelocity.GetCurveLength() 00546 - CurveA_PointVelocity.GetCurveLength(); 00547 00548 G4double integrationInaccuracyLimit= std::max( perMillion, 0.5*eps_step ); 00549 if( curve_length < ABdist * (1. - integrationInaccuracyLimit) ) 00550 { 00551 #ifdef G4DEBUG_FIELD 00552 G4cerr << " Warning in G4ChordFinder::ApproxCurvePoint: " 00553 << G4endl 00554 << " The two points are further apart than the curve length " 00555 << G4endl 00556 << " Dist = " << ABdist 00557 << " curve length = " << curve_length 00558 << " relativeDiff = " << (curve_length-ABdist)/ABdist 00559 << G4endl; 00560 if( curve_length < ABdist * (1. - 10*eps_step) ) 00561 { 00562 std::ostringstream message; 00563 message << "Unphysical curve length." << G4endl 00564 << "The size of the above difference exceeds allowed limits." 00565 << G4endl 00566 << "Aborting."; 00567 G4Exception("G4ChordFinder::ApproxCurvePointV()", "GeomField0003", 00568 FatalException, message); 00569 } 00570 #endif 00571 // Take default corrective action: adjust the maximum curve length. 00572 // NOTE: this case only happens for relatively straight paths. 00573 // curve_length = ABdist; 00574 } 00575 00576 G4double new_st_length; 00577 00578 if ( ABdist > 0.0 ) 00579 { 00580 AE_fraction = ChordAE_Vector.mag() / ABdist; 00581 } 00582 else 00583 { 00584 AE_fraction = 0.5; // Guess .. ?; 00585 #ifdef G4DEBUG_FIELD 00586 G4cout << "Warning in G4ChordFinder::ApproxCurvePointV():" 00587 << " A and B are the same point!" << G4endl 00588 << " Chord AB length = " << ChordAE_Vector.mag() << G4endl 00589 << G4endl; 00590 #endif 00591 } 00592 00593 if( (AE_fraction> 1.0 + perMillion) || (AE_fraction< 0.) ) 00594 { 00595 #ifdef G4DEBUG_FIELD 00596 G4cerr << " G4ChordFinder::ApproxCurvePointV() - Warning:" 00597 << " Anomalous condition:AE > AB or AE/AB <= 0 " << G4endl 00598 << " AE_fraction = " << AE_fraction << G4endl 00599 << " Chord AE length = " << ChordAE_Vector.mag() << G4endl 00600 << " Chord AB length = " << ABdist << G4endl << G4endl; 00601 G4cerr << " OK if this condition occurs after a recalculation of 'B'" 00602 << G4endl << " Otherwise it is an error. " << G4endl ; 00603 #endif 00604 // This course can now result if B has been re-evaluated, 00605 // without E being recomputed (1 July 99). 00606 // In this case this is not a "real error" - but it is undesired 00607 // and we cope with it by a default corrective action ... 00608 // 00609 AE_fraction = 0.5; // Default value 00610 } 00611 00612 new_st_length= AE_fraction * curve_length; 00613 00614 if ( AE_fraction > 0.0 ) 00615 { 00616 fIntgrDriver->AccurateAdvance(Current_PointVelocity, 00617 new_st_length, eps_step ); 00618 // 00619 // In this case it does not matter if it cannot advance the full distance 00620 } 00621 00622 // If there was a memory of the step_length actually required at the start 00623 // of the integration Step, this could be re-used ... 00624 00625 G4cout.precision(14); 00626 00627 return Current_PointVelocity; 00628 }
G4double G4ChordFinder::FindNextChord | ( | const G4FieldTrack & | yStart, | |
G4double | stepMax, | |||
G4FieldTrack & | yEnd, | |||
G4double & | dyErr, | |||
G4double | epsStep, | |||
G4double * | pNextStepForAccuracy, | |||
const G4ThreeVector | latestSafetyOrigin, | |||
G4double | latestSafetyRadius | |||
) | [protected, virtual] |
Reimplemented in G4ChordFinderSaf.
Definition at line 217 of file G4ChordFinder.cc.
References AcceptableMissDist(), AccumulateStatistics(), G4MagInt_Driver::ComputeNewStepSize(), G4cout, G4endl, G4FieldTrack::ncompSVEC, NewStep(), and G4MagInt_Driver::QuickAdvance().
Referenced by AdvanceChordLimited().
00226 { 00227 // Returns Length of Step taken 00228 00229 G4FieldTrack yCurrent= yStart; 00230 G4double stepTrial, stepForAccuracy; 00231 G4double dydx[G4FieldTrack::ncompSVEC]; 00232 00233 // 1.) Try to "leap" to end of interval 00234 // 2.) Evaluate if resulting chord gives d_chord that is good enough. 00235 // 2a.) If d_chord is not good enough, find one that is. 00236 00237 G4bool validEndPoint= false; 00238 G4double dChordStep, lastStepLength; // stepOfLastGoodChord; 00239 00240 fIntgrDriver-> GetDerivatives( yCurrent, dydx ); 00241 00242 G4int noTrials=0; 00243 const G4double safetyFactor= fFirstFraction; // 0.975 or 0.99 ? was 0.999 00244 00245 stepTrial = std::min( stepMax, safetyFactor*fLastStepEstimate_Unconstrained ); 00246 00247 G4double newStepEst_Uncons= 0.0; 00248 do 00249 { 00250 G4double stepForChord; 00251 yCurrent = yStart; // Always start from initial point 00252 00253 // ************ 00254 fIntgrDriver->QuickAdvance( yCurrent, dydx, stepTrial, 00255 dChordStep, dyErrPos); 00256 // ************ 00257 00258 // We check whether the criterion is met here. 00259 validEndPoint = AcceptableMissDist(dChordStep); 00260 00261 lastStepLength = stepTrial; 00262 00263 // This method estimates to step size for a good chord. 00264 stepForChord = NewStep(stepTrial, dChordStep, newStepEst_Uncons ); 00265 00266 if( ! validEndPoint ) 00267 { 00268 if( stepTrial<=0.0 ) 00269 { 00270 stepTrial = stepForChord; 00271 } 00272 else if (stepForChord <= stepTrial) 00273 { 00274 // Reduce by a fraction, possibly up to 20% 00275 stepTrial = std::min( stepForChord, fFractionLast * stepTrial); 00276 } 00277 else 00278 { 00279 stepTrial *= 0.1; 00280 } 00281 } 00282 noTrials++; 00283 } 00284 while( ! validEndPoint ); // End of do-while RKD 00285 00286 if( newStepEst_Uncons > 0.0 ) 00287 { 00288 fLastStepEstimate_Unconstrained= newStepEst_Uncons; 00289 } 00290 00291 AccumulateStatistics( noTrials ); 00292 00293 if( pStepForAccuracy ) 00294 { 00295 // Calculate the step size required for accuracy, if it is needed 00296 // 00297 G4double dyErr_relative = dyErrPos/(epsStep*lastStepLength); 00298 if( dyErr_relative > 1.0 ) 00299 { 00300 stepForAccuracy = fIntgrDriver->ComputeNewStepSize( dyErr_relative, 00301 lastStepLength ); 00302 } 00303 else 00304 { 00305 stepForAccuracy = 0.0; // Convention to show step was ok 00306 } 00307 *pStepForAccuracy = stepForAccuracy; 00308 } 00309 00310 #ifdef TEST_CHORD_PRINT 00311 static int dbg=0; 00312 if( dbg ) 00313 { 00314 G4cout << "ChordF/FindNextChord: NoTrials= " << noTrials 00315 << " StepForGoodChord=" << std::setw(10) << stepTrial << G4endl; 00316 } 00317 #endif 00318 yEnd= yCurrent; 00319 return stepTrial; 00320 }
G4double G4ChordFinder::GetDeltaChord | ( | ) | const [inline] |
G4double G4ChordFinder::GetFirstFraction | ( | ) | [inline] |
G4double G4ChordFinder::GetFractionLast | ( | ) | [inline] |
G4double G4ChordFinder::GetFractionNextEstimate | ( | ) | [inline] |
G4MagInt_Driver * G4ChordFinder::GetIntegrationDriver | ( | ) | [inline] |
Definition at line 40 of file G4ChordFinder.icc.
Referenced by G4MultiLevelLocator::EstimateIntersectionPoint(), G4BrentLocator::EstimateIntersectionPoint(), G4ChordFinderSaf::FindNextChord(), G4ErrorPropagatorManager::InitFieldForBackwards(), G4VIntersectionLocator::ReEstimateEndpoint(), and G4PropagatorInField::SetVerboseLevel().
G4double G4ChordFinder::GetLastStepEstimateUnc | ( | ) | [inline, protected] |
G4double G4ChordFinder::GetMultipleRadius | ( | ) | [inline] |
G4int G4ChordFinder::GetNoCalls | ( | ) | [inline] |
G4int G4ChordFinder::GetNoMaxTrials | ( | ) | [inline] |
G4int G4ChordFinder::GetNoTrials | ( | ) | [inline] |
G4double G4ChordFinder::InvParabolic | ( | const G4double | xa, | |
const G4double | ya, | |||
const G4double | xb, | |||
const G4double | yb, | |||
const G4double | xc, | |||
const G4double | yc | |||
) | [inline] |
Definition at line 128 of file G4ChordFinder.icc.
References DBL_MAX, and DBL_MIN.
Referenced by ApproxCurvePointS().
00131 { const G4double R = yb/yc, 00132 S = yb/ya, 00133 T = ya/yc; 00134 const G4double Q = (T-1)*(R-1)*(S-1); 00135 if (std::fabs(Q) <DBL_MIN ) return DBL_MAX; 00136 00137 const G4double P = S*(T*(R-T)*(xc-xb) - (1-R)*(xb-xa)); 00138 return xb + P/Q; 00139 }
G4double G4ChordFinder::NewStep | ( | G4double | stepTrialOld, | |
G4double | dChordStep, | |||
G4double & | stepEstimate_Unconstrained | |||
) | [protected] |
Definition at line 325 of file G4ChordFinder.cc.
Referenced by G4ChordFinderSaf::FindNextChord(), and FindNextChord().
00328 { 00329 // Is called to estimate the next step size, even for successful steps, 00330 // in order to predict an accurate 'chord-sensitive' first step 00331 // which is likely to assist in more performant 'stepping'. 00332 00333 G4double stepTrial; 00334 00335 #if 1 00336 00337 if (dChordStep > 0.0) 00338 { 00339 stepEstimate_Unconstrained = 00340 stepTrialOld*std::sqrt( fDeltaChord / dChordStep ); 00341 stepTrial = fFractionNextEstimate * stepEstimate_Unconstrained; 00342 } 00343 else 00344 { 00345 // Should not update the Unconstrained Step estimate: incorrect! 00346 stepTrial = stepTrialOld * 2.; 00347 } 00348 00349 if( stepTrial <= 0.001 * stepTrialOld) 00350 { 00351 if ( dChordStep > 1000.0 * fDeltaChord ) 00352 { 00353 stepTrial= stepTrialOld * 0.03; 00354 } 00355 else 00356 { 00357 if ( dChordStep > 100. * fDeltaChord ) 00358 { 00359 stepTrial= stepTrialOld * 0.1; 00360 } 00361 else // Try halving the length until dChordStep OK 00362 { 00363 stepTrial= stepTrialOld * 0.5; 00364 } 00365 } 00366 } 00367 else if (stepTrial > 1000.0 * stepTrialOld) 00368 { 00369 stepTrial= 1000.0 * stepTrialOld; 00370 } 00371 00372 if( stepTrial == 0.0 ) 00373 { 00374 stepTrial= 0.000001; 00375 } 00376 00377 #else 00378 00379 if ( dChordStep > 1000. * fDeltaChord ) 00380 { 00381 stepTrial= stepTrialOld * 0.03; 00382 } 00383 else 00384 { 00385 if ( dChordStep > 100. * fDeltaChord ) 00386 { 00387 stepTrial= stepTrialOld * 0.1; 00388 } 00389 else // Keep halving the length until dChordStep OK 00390 { 00391 stepTrial= stepTrialOld * 0.5; 00392 } 00393 } 00394 00395 #endif 00396 00397 // A more sophisticated chord-finder could figure out a better 00398 // stepTrial, from dChordStep and the required d_geometry 00399 // e.g. 00400 // Calculate R, r_helix (eg at orig point) 00401 // if( stepTrial < 2 pi R ) 00402 // stepTrial = R arc_cos( 1 - fDeltaChord / r_helix ) 00403 // else 00404 // ?? 00405 00406 return stepTrial; 00407 }
void G4ChordFinder::PrintDchordTrial | ( | G4int | noTrials, | |
G4double | stepTrial, | |||
G4double | oldStepTrial, | |||
G4double | dChordStep | |||
) | [protected] |
void G4ChordFinder::PrintStatistics | ( | ) | [virtual] |
Reimplemented in G4ChordFinderSaf.
Definition at line 634 of file G4ChordFinder.cc.
References G4cout, and G4endl.
Referenced by G4ChordFinderSaf::PrintStatistics(), and ~G4ChordFinder().
00635 { 00636 // Print Statistics 00637 00638 G4cout << "G4ChordFinder statistics report: " << G4endl; 00639 G4cout 00640 << " No trials: " << fTotalNoTrials_FNC 00641 << " No Calls: " << fNoCalls_FNC 00642 << " Max-trial: " << fmaxTrials_FNC 00643 << G4endl; 00644 G4cout 00645 << " Parameters: " 00646 << " fFirstFraction " << fFirstFraction 00647 << " fFractionLast " << fFractionLast 00648 << " fFractionNextEstimate " << fFractionNextEstimate 00649 << G4endl; 00650 }
void G4ChordFinder::ResetStepEstimate | ( | ) | [inline] |
Definition at line 83 of file G4ChordFinder.icc.
References DBL_MAX.
Referenced by G4FieldManagerStore::ClearAllChordFindersState(), and G4CoupledTransportation::StartTracking().
00084 { 00085 fLastStepEstimate_Unconstrained = DBL_MAX; 00086 }
void G4ChordFinder::SetChargeMomentumMass | ( | G4double | pCharge, | |
G4double | pMomentum, | |||
G4double | pMass | |||
) | [inline] |
Definition at line 52 of file G4ChordFinder.icc.
Referenced by G4PropagatorInField::ComputeStep().
00055 { 00056 fIntgrDriver-> SetChargeMomentumMass(pCharge, pMomentum, pMass); 00057 }
void G4ChordFinder::SetDeltaChord | ( | G4double | newval | ) | [inline] |
void G4ChordFinder::SetFirstFraction | ( | G4double | fractFirst | ) | [inline] |
Definition at line 127 of file G4ChordFinder.cc.
References G4cerr, G4cout, and G4endl.
Referenced by G4ChordFinder().
00128 { 00129 // Use -1.0 as request for Default. 00130 if( fractLast == -1.0 ) fractLast = 1.0; // 0.9; 00131 if( fractNext == -1.0 ) fractNext = 0.98; // 0.9; 00132 00133 // fFirstFraction = 0.999; // Orig 0.999 A safe value, range: ~ 0.95 - 0.999 00134 // fMultipleRadius = 15.0; // For later use, range: ~ 2 - 20 00135 00136 if( fStatsVerbose ) 00137 { 00138 G4cout << " ChordFnd> Trying to set fractions: " 00139 << " first " << fFirstFraction 00140 << " last " << fractLast 00141 << " next " << fractNext 00142 << " and multiple " << fMultipleRadius 00143 << G4endl; 00144 } 00145 00146 if( (fractLast > 0.0) && (fractLast <=1.0) ) 00147 { 00148 fFractionLast= fractLast; 00149 } 00150 else 00151 { 00152 G4cerr << "G4ChordFinder::SetFractions_Last_Next: Invalid " 00153 << " fraction Last = " << fractLast 00154 << " must be 0 < fractionLast <= 1 " << G4endl; 00155 } 00156 if( (fractNext > 0.0) && (fractNext <1.0) ) 00157 { 00158 fFractionNextEstimate = fractNext; 00159 } 00160 else 00161 { 00162 G4cerr << "G4ChordFinder:: SetFractions_Last_Next: Invalid " 00163 << " fraction Next = " << fractNext 00164 << " must be 0 < fractionNext < 1 " << G4endl; 00165 } 00166 }
void G4ChordFinder::SetIntegrationDriver | ( | G4MagInt_Driver * | IntegrationDriver | ) | [inline] |
void G4ChordFinder::SetLastStepEstimateUnc | ( | G4double | stepEst | ) | [inline, protected] |
Definition at line 102 of file G4ChordFinder.icc.
Referenced by G4ChordFinderSaf::~G4ChordFinderSaf().
00103 { 00104 G4int oldval= fStatsVerbose; 00105 fStatsVerbose = newvalue; 00106 return oldval; 00107 }
void G4ChordFinder::TestChordPrint | ( | G4int | noTrials, | |
G4int | lastStepTrial, | |||
G4double | dChordStep, | |||
G4double | nextStepTrial | |||
) |
Definition at line 655 of file G4ChordFinder.cc.
References G4cout, and G4endl.
00659 { 00660 G4int oldprec= G4cout.precision(5); 00661 G4cout << " ChF/fnc: notrial " << std::setw( 3) << noTrials 00662 << " this_step= " << std::setw(10) << lastStepTrial; 00663 if( std::fabs( (dChordStep / fDeltaChord) - 1.0 ) < 0.001 ) 00664 { 00665 G4cout.precision(8); 00666 } 00667 else 00668 { 00669 G4cout.precision(6); 00670 } 00671 G4cout << " dChordStep= " << std::setw(12) << dChordStep; 00672 if( dChordStep > fDeltaChord ) { G4cout << " d+"; } 00673 else { G4cout << " d-"; } 00674 G4cout.precision(5); 00675 G4cout << " new_step= " << std::setw(10) 00676 << fLastStepEstimate_Unconstrained 00677 << " new_step_constr= " << std::setw(10) 00678 << lastStepTrial << G4endl; 00679 G4cout << " nextStepTrial = " << std::setw(10) << nextStepTrial << G4endl; 00680 G4cout.precision(oldprec); 00681 }