Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

NmOdeStepperRKCK Class Reference

#include <NmOdeStepperRKCK.h>

Inheritance diagram for NmOdeStepperRKCK:

NmOdeStepper List of all members.

Public Member Functions

 NmOdeStepperRKCK ()
 ~NmOdeStepperRKCK ()
void Step (double *y, const double *dydx, int n, double *x, double hTry, double eps, const double *yScale, double *hDid, double *hNext, NmOdeDerivFunc &Deriv)

Protected Member Functions

void RKCKStep (const double *y, const double *dydx, int n, double x, double h, double *yOut, double *yErr, NmOdeDerivFunc &Deriv)

Constructor & Destructor Documentation

NmOdeStepperRKCK::NmOdeStepperRKCK  ) 
 

Definition at line 22 of file NmStepperRKCK.cxx.

00022 {}

NmOdeStepperRKCK::~NmOdeStepperRKCK  ) 
 

Definition at line 26 of file NmStepperRKCK.cxx.

00026 {}


Member Function Documentation

void NmOdeStepperRKCK::RKCKStep const double *  y,
const double *  dydx,
int  n,
double  x,
double  h,
double *  yOut,
double *  yErr,
NmOdeDerivFunc Deriv
[protected]
 

Definition at line 115 of file NmStepperRKCK.cxx.

Referenced by Step().

00122                                                         {
00123 //======================================================================
00124 // Purpose: Make a single Cash-Karp Runga-Kutta step
00125 //
00126 // Inputs:    y - initial values of dependent variables
00127 //         dydx - initial values of derivatives
00128 //            n - size of y vector
00129 //            x - value of integration variable
00130 //            h - step size
00131 //       Derivs - functor to use to calculate derivatives
00132 //
00133 // Outputs: yOut - y values after step
00134 //          yErr - estimate of erros on yOut
00135 //======================================================================
00136   // These numbers come from Numerical Recipes in C, Table in section 16.2
00137   // "Cash-Karp Parameters for Embedded Runge-Kutta Method"
00138   static const double 
00139     a2=1./ 5., a3=3./10., a4=3./5., a5=1., a6=7./8.;
00140   static const double
00141     b21= 1./5.,
00142     b31= 3./40., b32= 9./40.,
00143     b41= 3./10., b42= -9./10., b43= 6./5.,
00144     b51= -11./54., b52= 5./2., b53= -70./27., b54=35./27.,
00145     b61=1631./55296., b62=175./512., b63=575./13824., b64=44275./110592., 
00146     b65=253./4096.;
00147   static const double
00148     c1 = 37./378., 
00149 //unused:    c2 = 0.,
00150     c3 = 250./621., 
00151     c4 = 125./594., 
00152     c5 = 0.0,
00153     c6 = 512./1771.;
00154   static const double
00155     dc1 = c1 - 2825./27648., 
00156 //unused:    dc2 = c2 - 0., 
00157     dc3 = c3 - 18575./48384.,
00158     dc4 = c4 - 13525./55296., 
00159     dc5 = c5 - 277./14336., 
00160     dc6 = c6 - 1./4.;
00161   register int i;
00162 
00163   double* ak2   = new double[n];
00164   double* ak3   = new double[n];
00165   double* ak4   = new double[n];
00166   double* ak5   = new double[n];
00167   double* ak6   = new double[n];
00168   double* yTemp = new double[n];
00169   
00170   for (i=0; i<n; ++i) {
00171     yTemp[i] = y[i] + h*b21*dydx[i];
00172   }
00173   Derivs(x + a2*h, yTemp, ak2);
00174   for (i=0; i<n; ++i) {
00175     yTemp[i] = y[i] + h*(b31*dydx[i] + b32*ak2[i]);
00176   }
00177   Derivs(x + a3*h, yTemp, ak3);  
00178   for (i=0; i<n; ++i) {
00179     yTemp[i] = y[i] + h*(b41*dydx[i] + b42*ak2[i] + b43*ak3[i]);
00180   }
00181   Derivs(x+a4*h, yTemp, ak4);
00182   for (i=0; i<n; ++i) {
00183     yTemp[i] = y[i] + h*(b51*dydx[i] + b52*ak2[i] + b53*ak3[i] + b54*ak4[i]);
00184   }
00185   Derivs(x + a5*h, yTemp, ak5);
00186   for (i=0; i<n; ++i) {
00187     yTemp[i] = y[i] + 
00188       h*(b61*dydx[i] + b62*ak2[i] + b63*ak3[i] + b64*ak4[i] + b65*ak5[i]);
00189   }
00190   Derivs(x+a6*h, yTemp, ak6);
00191 
00192   // Accumulate all infomation for the full step
00193   for (i=0; i<n; ++i) {
00194     yOut[i] = 
00195       y[i]+h*(c1*dydx[i] + c3*ak3[i] + c4*ak4[i] + c6*ak6[i]);
00196   }
00197   
00198   // Estimate the error by comparing 4th and 5th order estimates
00199   for (i=0; i<n; ++i) {
00200     yErr[i] = h*(dc1*dydx[i] + dc3*ak3[i] + dc4*ak4[i] + dc5*ak5[i] + 
00201                  dc6*ak6[i]);
00202   }
00203   delete []ak2;   ak2   = 0;
00204   delete []ak3;   ak3   = 0;
00205   delete []ak4;   ak4   = 0;
00206   delete []ak5;   ak5   = 0;
00207   delete []ak6;   ak6   = 0;
00208   delete []yTemp; yTemp = 0;
00209 }

void NmOdeStepperRKCK::Step double *  y,
const double *  dydx,
int  n,
double *  x,
double  hTry,
double  eps,
const double *  yScale,
double *  hDid,
double *  hNext,
NmOdeDerivFunc Deriv
[virtual]
 

Implements NmOdeStepper.

Definition at line 30 of file NmStepperRKCK.cxx.

References MAXMACRO, MINMACRO, MSG, and RKCKStep().

00039                                                     {
00040 //======================================================================
00041 // Purpose: Take a single quality-controled step
00042 //
00043 // Inputs: y - initial values of dependent variables. Modified on return
00044 //         dydx - initial values of derivatives
00045 //            n - size of y and dydx vectors
00046 //            x - value of integration variable. Modified on return
00047 //         hTry - suggested step size
00048 //          eps - fractional accuracy
00049 //       yScale - typical sizes of y variables
00050 //       Derivs - functor for derivative calculation
00051 // Outputs:
00052 //         hDid - size of step taken
00053 //        hNext - guess at next good step size
00054 //======================================================================
00055   register int i;                // Loop variable
00056   double* yTemp = new double[n]; // tmp values for y variables
00057   double* yErr  = new double[n]; // tmp values for calculating errors
00058   double errMax;                 // Largest parameter error after step
00059   double h;                      // Step size
00060   // constants which control guess at next good step
00061   static const double gSafety  =  0.90;
00062   static const double gPgrow   = -0.20;
00063   static const double gPshrink = -0.25;
00064   static const double gMaxGrow =  5.0;
00065   static const double gErrCon  = pow(gMaxGrow/gSafety, 1.0/gPgrow);
00066 
00067   h = hTry;
00068   for (;;) {
00069     double hTemp; // Trial step size
00070     double xNew;  // Next x position
00071     
00072     // Make a step using the proposed step size
00073     this->RKCKStep(y, dydx, n, *x, h, yTemp, yErr, Derivs);
00074 
00075     // Evaluate estimated sizes of the errors
00076     errMax = 0.0;
00077     for (i=0; i<n; i++) {
00078       if (yScale[i]!=0.0) {
00079         errMax = MAXMACRO(errMax,fabs(yErr[i]/yScale[i]));
00080       }
00081     }
00082     errMax /= eps;
00083     
00084     // If errors are acceptable then we're done
00085     if (errMax < 1.0) break; 
00086 
00087     // If errors are not acceptable shrink the step size and try again
00088     hTemp = gSafety*h*pow(errMax, gPshrink);
00089     h = (h>=0.0 ? MAXMACRO(hTemp, 0.1*h) : MINMACRO(hTemp, 0.1*h));
00090     xNew = (*x)+h;
00091     if (xNew == *x) {
00092       MSG("Nm",Msg::kFatal)
00093         << "Step underflow. eps=" << eps << "\n";
00094       abort();
00095     }
00096   }
00097 
00098   // Check if we can safely increase the step size allowing for a maximum
00099   // increase of a factor of gMaxGrow
00100   if (errMax > gErrCon) {
00101     *hNext = gSafety*h*pow(errMax, gPgrow);
00102   }
00103   else {
00104     *hNext = gMaxGrow*h;
00105   }
00106   *x += h;
00107   *hDid = h;
00108   for (i=0; i<n; ++i) y[i] = yTemp[i];
00109   delete []yTemp; yTemp = 0;
00110   delete []yErr;  yErr = 0;
00111 }


The documentation for this class was generated from the following files:
Generated on Mon Feb 15 11:09:40 2010 for loon by  doxygen 1.3.9.1