A further refinement of the Runge-Kutta approach uses
derivatives at the beginning of the interval, at the end of the
interval and twice at the midpoint.
Using the conventional k#
variable names, we obtain the following increments in the variable
xn
with :
Then the new increment in variable x
is calculated as a weighted average of these estimated increments
with k2
and k3
, the two midpoint values, given double weights.
The code below shows a class created to carry out the 4th order
Runge-Kutta algorithm.
RungeKutta4th.java
|
/**
* Provides a static method to calculate the
4th order
* Runge-Kutta integration calculation.
**/
public class RungeKutta4th
{
/**
* Calculated a step of the integration
of an ODE with
* 4th order RK.
*
* @param t independent
variable
* @param dt step in the independent
variable
* @param var array holding the dependent
variable
* @param vel array holding the first
derivative
*
**/
public static void step (double t, double dt,
double [] var,
double [] vel,
Derivable func ) {
double k1_var, k1_vel;
double k2_var, k2_vel;
double k3_var, k3_vel;
double k4_var, k4_vel;
for (int i=0; i < var.length; i++)
{
k1_var = vel[i] * dt;
k1_vel = func.deriv
(i,var[i],vel[i],t)*dt;
k2_var = (vel[i]
+ 0.5*k1_vel)*dt;
k2_vel = func.deriv
(i,var[i] + 0.5*k1_var,
vel[i] + 0.5*k1_vel,
t+0.5*dt)*dt;
k3_var = (vel[i]
+ 0.5*k2_vel)*dt;
k3_vel = func.deriv
(i,var[i] + 0.5*k2_var,
vel[i] + 0.5*k2_vel,
t+0.5*dt)*dt;
k4_var = (vel[i]
+ k3_vel)*dt;
k4_vel = func.deriv
(i,var[i] + k3_var,
vel[i]
+ k3_vel,
t+dt)*dt;
var[i] = var[i] +
(k1_var + 2.0*k2_var
+ 2.0*k3_var + k4_var)/6.0;
vel[i] = vel[i] +
(k1_vel + 2.0*k2_vel
+ 2.0*k3_vel + k4_vel)/6.0;
}
t += dt;
} // step
} // RungeKutta4th
|
The example below is the same as previously except that the above
code for the 4th order Runge-Kutta is used to the step calculation.
RK4thApplet6.java
(Output goes to browser's Java
console.)
|
/** Program
using the second order Runge-Kutta method
* to solve for the landing point of a projectile.**/
public class RK4thApplet extends java.applet.Applet
implements Derivable
{
// Constants
double g = 9.80;// meter per sec**2
double x0 = 0.0;
double y0 = 0.0;
double v0 = 100.0;// initial vel, m/s
double angle = Math.PI/4.0;
// Instance variables
double [] pos = new double[2];
double [] vel = new double[2];
/** Set up for the algorithm. **/
public void init () {
double t;
double totalT;
int n;
double dt = 0.01;
int nSteps = 100000;
pos[0] = x0;
pos[1] = y0;
vel[0] = v0 * Math.cos (angle);
vel[1] = v0 * Math.sin (angle);
t = 0.0;
for ( n=0; n< nSteps; n++) {
RungeKutta4th.step (t,dt,pos,vel,this);
if (pos[1] <= 0.0) break;
}
System.out.println ("After steps
= " + n);
System.out.println (" x = " + pos[0]);
} // init
/** Implement the interface method for the derivative
* of the variables. **/
public double deriv (int i, double var, double
vel, double t) {
if (i == 0) { // x variable
return 0.0;
} else {// y variable
return -g;
}
} // deriv
/** Paint message in Applet window. **/
public void paint (java.awt.Graphics g) {
g.drawString ("RK4thApplet",20,20);
} // paint
/** Run optionally as a application. **/
public static void main (String [] args) {
RK4thApplet obj = new RK4thApplet
();
obj.init ();
} // main
} // RK4thApplet
|
The output shows
After steps
=1443
x = 1021.0621920333822 |
This is the same as for the previous example since
constant term for the acceleration results in the same increment
to x as with the 2nd order code.
Most recent update: Oct. 21, 2005
|