CLHEP VERSION Reference Documentation
   
CLHEP Home Page     CLHEP Documentation     CLHEP Bug Reports

StepDoublingRKStepper.cc

Go to the documentation of this file.
00001 #include "CLHEP/GenericFunctions/StepDoublingRKStepper.hh"
00002 #include <stdexcept>
00003 #include <cmath>
00004 namespace Genfun {
00005 
00006   
00007   StepDoublingRKStepper::StepDoublingRKStepper(const ButcherTableau & xtableau):tableau(xtableau) {
00008   }
00009 
00010   StepDoublingRKStepper::~StepDoublingRKStepper() {
00011   }
00012 
00013   void StepDoublingRKStepper::step   (const RKIntegrator::RKData       * data, 
00014                                       const RKIntegrator::RKData::Data & s, 
00015                                       RKIntegrator::RKData::Data       & d, 
00016                                       std::vector<double>              & errors) const {
00017     const unsigned int nvar = s.variable.size();
00018     RKIntegrator::RKData::Data d1(nvar),d2(nvar);
00019 
00020     doStep(data,s,d);
00021     double dt = (d.time - s.time);
00022     d1.time = s.time + dt/2.0;
00023     d2.time = d.time;
00024 
00025     doStep(data, s,d1);
00026     doStep(data,d1,d2);
00027 
00028     // Error estimate:
00029     errors.resize(nvar);
00030     for (size_t v=0;v<nvar;v++) errors[v]=fabs(d2.variable[v]-d.variable[v]);
00031 
00032     // Final correction:
00033     for (size_t v=0;v<nvar;v++) d.variable[v] = d2.variable[v] + ((d2.variable[v]-d.variable[v])/double(std::pow(2.,(int)(tableau.order())-1)));
00034 
00035   }
00036   
00037   void StepDoublingRKStepper::doStep(const RKIntegrator::RKData       * data, 
00038                                      const RKIntegrator::RKData::Data & s, 
00039                                      RKIntegrator::RKData::Data       & d) const {
00040     // First step:
00041     double h = (d.time - s.time);
00042     
00043     
00044     if (h<=0) throw std::runtime_error ("SimpleRKStepper:  negative stepsize");
00045     const unsigned int nvar = s.variable.size();
00046     // Compute all of the k's..:
00047     //
00048     std::vector<std::vector<double> >k(tableau.nSteps());
00049     for (unsigned int i=0;i<tableau.nSteps();i++) {
00050       k[i].resize(nvar,0);
00051       Argument arg(nvar);
00052       for (unsigned int v=0;v<nvar;v++) arg[v]=s.variable[v];
00053       for (unsigned int j=0;j<i;j++) {
00054         for (unsigned int v=0;v<nvar;v++) arg[v] += h*tableau.A(i,j)*k[j][v];
00055       }
00056       for (unsigned int v=0;v<nvar;v++) k[i][v]=(*data->_diffEqn[v])(arg);
00057     }
00058     //
00059     // Final result.
00060     //
00061     for (unsigned int v=0;v<nvar;v++) d.firstDerivative[v] = 0;
00062     for (unsigned int i=0;i<tableau.nSteps();i++) {
00063       for (unsigned int v=0;v<nvar;v++) d.firstDerivative[v] += tableau.b(i)*k[i][v];
00064     }
00065     for (unsigned int v=0;v<nvar;v++)   d.variable[v] =s.variable[v]+h*d.firstDerivative[v];
00066                                          
00067   }
00068 
00069 
00070 
00071 
00072   StepDoublingRKStepper *StepDoublingRKStepper::clone() const {
00073     return new StepDoublingRKStepper(*this);
00074   }
00075 
00076   unsigned int StepDoublingRKStepper::order() const {
00077     return tableau.order();
00078   }
00079 
00080 
00081 }

Generated on 15 Nov 2012 for CLHEP by  doxygen 1.4.7