CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
AdaptiveRKStepper.cc
Go to the documentation of this file.
1#include "CLHEP/GenericFunctions/AdaptiveRKStepper.hh"
2#include "CLHEP/GenericFunctions/EmbeddedRKStepper.hh"
3
4#include <cmath>
5#include <stdexcept>
6#include <vector>
7
8namespace Genfun {
9
11 eeStepper(stepper ? stepper->clone():new EmbeddedRKStepper()),
12 T(1.0E-6),
13 sStepsize(0.01),
14 S(0.9),
15 Rmin(0.0),
16 Rmax(5.0),
17 stepsize(sStepsize)
18 {
19 }
20
22 RKStepper(right),
23 eeStepper(right.eeStepper->clone()),
24 T(right.T),
25 sStepsize(right.sStepsize),
26 S(right.S),
27 Rmin(right.Rmin),
28 Rmax(right.Rmax),
29 stepsize(right.sStepsize)
30 {
31 }
32
33
37 double timeLimit) const {
38 //
39 // Adaptive stepsize control
40 //
41 if (s.time==0.0) {
42 stepsize=sStepsize;
43 }
44 const unsigned int p = eeStepper->order(); // Order of the stepper
45 const double deltaMax = T*std::pow(S/Rmax, (int)(p+1)); // Maximum error 4 adjustment.
46 const double TINY = 1.0E-30; // Denominator regularization
47 double hnext;
48 //
49 // Time limited step ?
50 //
51 d.time= timeLimit==0? s.time+stepsize : timeLimit;
52
53 //--------------------------------------//
54 // Take one step, from s to d: //
55 //--------------------------------------//
56 double h = d.time-s.time;
57 while (1) {
58 std::vector<double> errors;
59 eeStepper->step(data, s, d, errors);
60 if (timeLimit!=0.0) return;
61
62 // Take absolute value:
63 for (size_t e=0;e<errors.size();e++) errors[e] = fabs(errors[e]);
64
65 // Select the largest:
66 double delta = (*std::max_element(errors.begin(),errors.end()));
67 if (delta > T) {
68 //
69 // Bail out and try a smaller step.
70 //
71 h = std::max(S*h*std::pow(T/(delta + TINY), 1.0/(p+1)),Rmin*h);
72 if (!(((double) (s.time+h) - (double) s.time) > 0) ) {
73 throw std::runtime_error("Warning, RK Integrator step underflow");
74 }
75 d.time = s.time+h;
76 hnext=h;
77 continue;
78 }
79 else {
80 if (delta < deltaMax) {
81 hnext = S*h*std::pow(T/(delta + TINY),1.0/(p+1));
82 // stepsize is supposed to increase;
83 if (hnext<h) hnext=h;
84 }
85 else {
86 hnext = Rmax*h;
87 }
88 }
89 break;
90 }
91 stepsize=hnext;
92 return;
93 }
94
95
96
98 delete eeStepper;
99 }
100
102 return new AdaptiveRKStepper(*this);
103 }
104
106 }
107
109 return T;
110 }
111
112 const double & AdaptiveRKStepper::tolerance() const{
113 return T;
114 }
115
117 return sStepsize;
118 }
120 return sStepsize;
121 }
122
124 return S;
125 }
126
127 const double & AdaptiveRKStepper::safetyFactor() const{
128 return S;
129 }
130
132 return Rmin;
133 }
134 const double & AdaptiveRKStepper::rmin() const{
135 return Rmin;
136 }
137
139 return Rmax;
140 }
141 const double & AdaptiveRKStepper::rmax() const{
142 return Rmax;
143 }
144
145}
virtual void step(const RKIntegrator::RKData *data, const RKIntegrator::RKData::Data &sdata, RKIntegrator::RKData::Data &ddata, std::vector< double > &errors) const =0
virtual unsigned int order() const =0
virtual void step(const RKIntegrator::RKData *data, const RKIntegrator::RKData::Data &sdata, RKIntegrator::RKData::Data &ddata, double timeLimit) const
AdaptiveRKStepper(const EEStepper *eeStepper=NULL)
virtual AdaptiveRKStepper * clone() const
Definition: Abs.hh:14