// rk4_fixed.cpp /* Function to advance set of coupled first-order o.d.e.s by single step using fixed step-length fourth-order Runge-Kutta scheme x ... independent variable y ... array of dependent variables h ... fixed step-length Requires right-hand side routine void rhs_eval (double x, Array<double,1> y, Array<double,1>& dydx) which evaluates derivatives of y (w.r.t. x) in array dydx */ #include <blitz/array.h> using namespace blitz; void rk4_fixed (double& x, Array<double,1>& y, void (*rhs_eval)(double, Array<double,1>, Array<double,1>&), double h) { // Array y assumed to be of extent n, where n is no. of coupled // equations int n = y.extent(0); // Declare local arrays Array<double,1> k1(n), k2(n), k3(n), k4(n), f(n), dydx(n); // Zeroth intermediate step (*rhs_eval) (x, y, dydx); for (int j = 0; j < n; j++) { k1(j) = h * dydx(j); f(j) = y(j) + k1(j) / 2.; } // First intermediate step (*rhs_eval) (x + h / 2., f, dydx); for (int j = 0; j < n; j++) { k2(j) = h * dydx(j); f(j) = y(j) + k2(j) / 2.; } // Second intermediate step (*rhs_eval) (x + h / 2., f, dydx); for (int j = 0; j < n; j++) { k3(j) = h * dydx(j); f(j) = y(j) + k3(j); } // Third intermediate step (*rhs_eval) (x + h, f, dydx); for (int j = 0; j < n; j++) { k4(j) = h * dydx(j); } // Actual step for (int j = 0; j < n; j++) { y(j) += k1(j) / 6. + k2(j) / 3. + k3(j) / 3. + k4(j) / 6.; } x += h; return; }