36 #include "FGJSBBase.h" 37 #include "FGRungeKutta.h" 48 IDENT(IdSrc,
"$Id: FGRungeKutta.cpp,v 1.3 2014/01/13 10:46:03 ehofman Exp $");
49 IDENT(IdHdr,ID_RUNGEKUTTA);
51 const double FGRungeKutta::RealLimit = 1e30;
57 FGRungeKutta::~FGRungeKutta() { };
59 int FGRungeKutta::init(
double x_start,
double x_end,
int intervals)
63 h = (x_end - x_start)/intervals;
64 safer_x1 = x1 - h*1e-6;
69 status &= eFaultyInit;
83 bool FGRungeKutta::sane_val(
double x)
86 if ( x < RealLimit && x > -RealLimit )
return true;
92 double FGRungeKutta::evolve(
double y_0, FGRungeKuttaProblem *pf)
102 y = approximate(x,y);
103 if (!sane_val(y)) { status &= eMathError; }
109 cout << x <<
" " << y << endl;
110 y = approximate(x,y);
111 if (!sane_val(y)) { status &= eMathError; }
115 cout << x <<
" " << y << endl;
132 double FGRK4::approximate(
double x,
double y)
136 k1 = pfo->pFunc(x , y );
137 k2 = pfo->pFunc(x + h05, y + h05*k1);
138 k3 = pfo->pFunc(x + h05, y + h05*k2);
139 k4 = pfo->pFunc(x + h , y + h *k3);
141 y += h/6.0 * ( k1 + 2.0*k2 + 2.0*k3 + k4 );
152 const double FGRKFehlberg::A2[] = { 0.0, 1.0/4.0 };
153 const double FGRKFehlberg::A3[] = { 0.0, 3.0/32.0, 9.0/32.0 };
154 const double FGRKFehlberg::A4[] = { 0.0, 1932.0/2197.0, -7200.0/2197.0, 7296.0/2197.0 };
155 const double FGRKFehlberg::A5[] = { 0.0, 439.0/216.0, -8.0, 3680.0/513.0, -845.0/4104.0 };
156 const double FGRKFehlberg::A6[] = { 0.0, -8.0/27.0, 2.0, -3544.0/2565.0, 1859.0/4104.0, -11.0/40.0 };
158 const double FGRKFehlberg::C[] = { 0.0, 0.0, 1.0/4.0, 3.0/8.0, 12.0/13.0, 1.0, 1.0/2.0 };
160 const double FGRKFehlberg::B[] = { 0.0, 16.0/135.0, 0.0, 6656.0/12825.0, 28561.0/56430.0, -9.0/50.0, 2.0/55.0 };
161 const double FGRKFehlberg::Bs[] = { 0.0, 25.0/216.0, 0.0, 1408.0/2565.0, 2197.0/4104.0, -1.0/5.0, 0.0 };
166 FGRKFehlberg::~FGRKFehlberg() { };
168 double FGRKFehlberg::approximate(
double x,
double y)
171 double k1,k2,k3,k4,k5,k6, as;
184 k1 = pfo->pFunc(x , y );
187 k2 = pfo->pFunc(x + C[2]*h , y + as );
189 as = h*(A3[1]*k1 + A3[2]*k2);
190 k3 = pfo->pFunc(x + C[3]*h , y + as );
192 as = h*(A4[1]*k1 + A4[2]*k2 + A4[3]*k3);
193 k4 = pfo->pFunc(x + C[4]*h , y + as );
195 as = h*(A5[1]*k1 + A5[2]*k2 + A5[3]*k3 + A5[4]*k4);
196 k5 = pfo->pFunc(x + C[5]*h , y + as );
198 as = h*(A6[1]*k1 + A6[2]*k2 + A6[3]*k3 + A6[4]*k4 + A6[5]*k5);
199 k6 = pfo->pFunc(x + C[6]*h , y + as );
202 y5_val = y + h * ( B[1]*k1 + B[3]*k3 + B[4]*k4 + B[5]*k5 + B[6]*k6);
203 y4_val = y + h * (Bs[1]*k1 + Bs[3]*k3 + Bs[4]*k4 + Bs[5]*k5);
205 abs_err = fabs(y4_val-y5_val);
210 if (abs_err > epsilon) {
211 est_step = sqrt(sqrt(epsilon*h/abs_err));
218 if (shrink_avail>0 && est_step<h) {