diff --git a/src/rungekutta.cpp b/src/rungekutta.cpp
new file mode 100644
--- /dev/null
+++ b/src/rungekutta.cpp
@@ -0,0 +1,205 @@
+/*
+ *
+ * This file is part of the Virtual Leaf.
+ *
+ * The Virtual Leaf is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * The Virtual Leaf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with the Virtual Leaf. If not, see .
+ *
+ * Copyright 2010 Roeland Merks.
+ *
+ */
+
+#include
+#include
+#include
+#include "rungekutta.h"
+#include "warning.h"
+#include "maxmin.h"
+
+static const std::string _module_id("$Id$");
+
+// The value Errcon equals (5/Safety) raised to the power (1/PGrow), see use below.
+
+/*
+static float maxarg1,maxarg2;
+#define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
+(maxarg1) : (maxarg2))
+static float minarg1,minarg2;
+#define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\
+(minarg1) : (minarg2))
+#define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
+*/
+
+const double RungeKutta::Safety = 0.9;
+const double RungeKutta::PGrow = -0.2;
+const double RungeKutta::Pshrnk = -0.25;
+const double RungeKutta::Errcon = 1.89e-4;
+const double RungeKutta::Maxstp = 10000;
+const double RungeKutta::Tiny = 1.0e-30;
+
+void RungeKutta::rkqs(double *y, double *dydx, int n, double *x, double htry, double eps,
+ double *yscal, double *hdid, double *hnext)
+/* Fifth-order Runge-Kutta step with monitoring of local truncation error to ensure accuracy and
+ adjust stepsize. Input are the dependent variable vector y[1..n] and its derivative dydx[1..n]
+ at the starting value of the independent variable x. Also input are the stepsize to be attempted
+ htry, the required accuracy eps, and the vector yscal[1..n] against which the error is
+ scaled. On output, y and x are replaced by their new values, hdid is the stepsize that was
+ actuallyac complished, and hnext is the estimated next stepsize. derivs is the user-supplied
+ routine that computes the right-hand side derivatives. */
+{
+ int i;
+ double errmax,h,htemp,xnew,*yerr,*ytemp;
+ yerr=new double[n];
+ ytemp=new double[n];
+
+ h=htry; // Set stepsize to the initial trial value.
+ for (;;) {
+ rkck(y,dydx,n,*x,h,ytemp,yerr); // Take a step.
+ errmax=0.0; //Evaluate accuracy.
+ for (i=0;i= 0.0 ? FMAX(htemp,0.1*h) : FMIN(htemp,0.1*h));
+ //No more than a factor of 10.
+ xnew=(*x)+h;
+ if (xnew == *x) MyWarning::error("stepsize underflow in rkqs, with h = %f and htry = %f",h, htry);
+ }
+ if (errmax > Errcon) {
+ *hnext=Safety*h*pow(errmax,PGrow);
+ //std::cerr << "hnext = " << *hnext << std::endl;
+ }
+ else *hnext=5.0*h; //No more than a factor of 5 increase.
+ *x += (*hdid=h);
+ for (i=0;i 0) xsav=x-dxsav*2.0; //Assures storage of first step.
+ for (nstp=0;nstp 0 && kount < kmax-1 && fabs(x-xsav) > fabs(dxsav)) {
+ xp[kount]=x; //Store intermediate results.
+ for (i=0;i 0.0) h=x2-x;// If stepsize can overshoot, decrease.
+
+ rkqs(y,dydx,nvar,&x,h,eps,yscal,&hdid,&hnext);
+ if (hdid == h) ++(*nok); else ++(*nbad);
+ if ((x-x2)*(x2-x1) >= 0.0) { //Are we done?
+ for (i=0;i