Sie sind auf Seite 1von 11

Using Runge-Kutta Methods to Solve an Engineering Model Project 3

Kansas State University, ME 400, M W 1:30pm


April 6, 2015, Manhattan, Kansas, USA

RUNGE-KUTTA METHODS AND A DOUBLE PENDULUM MODEL


Caleb Shunatona
Mechanical Engineering Student
Kansas State University
Manhattan, Kansas, USA

The Runge-Kutta method can be used to solve a system of


equations with a high accuracy. When used with a pendulum
attached to another pendulum model, this method can give you
the position and angles of each of the pendulums and there
derivatives at any time.

= (1 + 22 + 23 + 4 )

NOMENCLATURE

Slope used in Runge-Kutta.


()
Function that gives a slope with given inputs.

Time step.

Slope estimate used in Runge-Kutta.

(1)

The second slope is found at one-half of a time step away


and where the variable should be if you followed the first slope,
ki, and is given by this equation:
1

2 = ( + , + )

(2)

The third slope is also found at one-half of a time step


away and where the variable should be if you followed the
second slope from its initial position and is given by the
equation:
1

3 = ( + h, + 2 )

(5)

This slope estimate can be plugged into this equation that


will give you the new value at one time step away based on the
old value and the slope estimate we found.

INTRODUCTION
The Runge-Kutta method uses a series of equations to find
a variable at its next step size space using its derivatives and
extrapolating from an old value to a new value. The method used
here is the classical fourth-order Runge-Kutta method. Using this
method the variable at one time step difference can be found by
using four different slopes at different amount of time steps. The
first slope is found at the current position of the variable and is
given by the equation:
1 = ( , )

After all the slopes used are found, you can use these to
find a final slope estimate to be used to find the estimated new
position at one time step away. The slope estimate is given by
this equation that gives all the previous slopes a weighted
average.

+1 = +

(6)

After finding all the proper derivative functions to use


within this method and plugging in the correct variables
needed, you can repeat this method starting at some position
and continue for any amount of time steps to find an accurate
guess of any variables at that point.

THE DOUBLE PENDULUM MODEL


The pendulum model used is created by taking a
pendulum that is connected to an origin at a position of (0, 0) in
a 2-d space, and connecting a second pendulum thats origin is
connected at the end of the first pendulum. Each pendulum has
a distinguished length and mass connected at the end. Any
weight caused by anything other than the mass at the ends is
assumed negligible. Both the Pendulums have an angle from
the vertical axis that will be used later to find position, velocity,
and acceleration equations. This graphic shows these two
pendulums and variables mentioned.

(3)

The final and fourth slope is found at the whole time


step and where the variable should be if you followed the third
slope from its initial position and is given by the following
equation:
4 = ( + , + 3 )

(4)
Fig. 1. Graphical Representation of a Double Pendulum

Copyright 2015 by Caleb Shunatona

The position of the masses of the pendulums at any point


can be found using these equations.
Pendulum Mass 1
1 = 1 sin(1 )
1 = 1 cos(1 )

(7)
(8)

RESULTS
After writing an algorithm using the classical fourthorder Runge-Kutta method based on the double pendulum model
the data found can be collected and shown. The starting
parameters used for this run of the algorithm are shown here.
1 = 0.550
2 = 0.450
1 = 2 = 0.35

1 (0) = 2 (0) = 2

1 (0) = 2 (0) = 0

= 0 15
= 0.001

Pendulum Mass 2
2 = 1 + 1 sin(2 )
2 = 1 2 cos(2 )

(9)
(10)

From these equations, the equated derivative will give


you the velocity of each mass. These equations are found
assuming that the length of each pendulum will remain
constant.
1 = 1 1 cos(1 )
1 = 1 1 sin(1 )

2 = 1 + 2 2 cos(2 )
2 = 1 + 2 2 sin(2 )

(11)
(12)
(13)
(14)

The positions of both the masses throughout the entire


time at each dt are shown in this graph.

Using these derivations, the accelerations of the masses


can also be found giving these equations.
1 = 12 1 sin(1 ) + 1 1 cos(1 )
1 = 12 1 cos(1 ) + 1 1 sin(1 )

2 = 1 22 2 sin(2 ) + 2 2 cos(2 )
2 = 1 + 22 2 cos(2 ) + 2 2 sin(2 )

(15)
(16)
(17)
(18)

The forces (F) in this model can be found using the


tensions (T) in the rods and the gravity constant (g).
1 = 1 1 = 1 sin(1 ) + 2 sin(2 )
1 = 1 1 = 1 cos(1 ) 2 cos(2 ) 1
2 = 2 2 = 2 sin(2 )
2 = 2 2 = 2 cos(2 ) 2

(19)
(20)
(21)
(22)

Fig. 2. Position of the Two Masses

The angles of each mass relative to the horizontal are


shown in this graph.

By plugging the acceleration of the masses into the force


equations the angular accelerations can be found.

1 =

(21 +2 ) sin(1 )2 (1 22 )2 sin(1 2 )2 (22 2 +12 1 cos(1 2 ))


1 (21 +2 2 cos(21 22 ))

2 =

2sin(1 2 )(12 1 (1 +2 )+(1 +2 ) cos(1 )+22 2 2 cos(1 2 ))


2 (21 +2 2 cos(21 22 ))

23)

(24)

After all these equations have been found then they can be
used as the f ( ) slope functions in a Runge-Kutta algorithm to
find all of the positions, velocities, angles, and angular velocity
of both of the masses for any point in time after an initial time
and a known initial set up.
Fig. 3. Angle of Each Mass

Copyright 2015 by Caleb Shunatona

The angular velocity of the angle associated with each mass is


shown in this graph.

Fig. 4. Angular Velocity of the Mass Angles

After the entire algorithm had been run, the outcomes at 15


seconds are shown here.
1 = 0.349362
1 = 0.021126
2 = 0.722013
2 = 0.121672
1 = 1.63119
2 = 1.37473
1 = 1.11276

2 = 0.268493

CONCLUSIONS
The Runge-Kutta methods are a convenient and
advantageous way to solve difficult engineering models. They
give an accurate representation of true solutions and work in
conjunction with algorithms very effectively.
ACKNOWLEDGMENTS
I would like to thank the instructors Richard McCulloch and
Aaron Schmidt for all their help.

Copyright 2015 by Caleb Shunatona

APPENDIX

Fig.1 came from this website:


http://scienceworld.wolfram.com/physics/DoublePendulum.html
#include <iostream>
#include<math.h>
using namespace std;
//DERIVATIVE FUNCTIONS TO BE USED IN RK
double fx1(double l1,double ang1,double dang1)
{
return l1*dang1*cos(ang1);
}
double fdx1 (double l1,double ang1,double dang1,double ddang1)
{
return -dang1*dang1*l1*sin(ang1)+ddang1*l1*cos(ang1);
}
double fx2(double l2,double ang2,double dang2,double dx1)
{
return dx1+l2*dang2*cos(ang2);
}
double fdx2(double l2,double ang2,double dang2, double ddang2, double ddx1)
{
return ddx1-dang2*dang2*l2*sin(ang2)+ddang2*l2*cos(ang2);
}
double fy1(double l1,double ang1,double dang1)
{
return l1*dang1*sin(ang1);
}
double fdy1(double l1,double ang1,double dang1,double ddang1)
{
return dang1*dang1*l1*cos(ang1)+ddang1*l1*sin(ang1);
}
double fy2(double l2,double ang2,double dang2,double dy1)
{
return dy1+l2*dang2*sin(ang2);
}
double fdy2(double l2,double ang2,double dang2,double ddang2,double ddy1)
{
return ddy1+dang2*dang2*l2*cos(ang2)+ddang2*l2*sin(ang2);
}
double fang1(double dang1)
{
return dang1;

Copyright 2015 by Caleb Shunatona

}
double fdang1(double g,double m1,double m2,double l1,double l2,double ang1,double dang1,double ang2,double dang2)
{
return(-g*(2.0*m1+m2)*sin(ang1)-m2*g*sin(ang1-2.0*ang2)-2.0*sin(ang1ang2)*m2*(dang2*dang2*l2+dang1*dang1*l1*cos(ang1-ang2)))/(l1*(2.0*m1+m2-m2*cos(2.0*ang1-2.0*ang2)));
}
double fang2(double dang2)
{
return dang2;
}
double fdang2(double g,double m1,double m2,double l1,double l2,double ang1,double dang1,double ang2,double dang2)
{
return (2.0*sin(ang1-ang2)*(dang1*dang1*l1*(m1+m2)+g*(m1+m2)*cos(ang1)+dang2*dang2*l2*m2*cos(ang1ang2)))/(l2*(2.0*m1+m2-m2*cos(2.0*ang1-2.0*ang2)));
}
int main ()
{
//INITATE VARIABLES
//PARAMETERS
//SECONDS
double t=15.0,dt=0.001;
//KILOGRAMS
double m1=0.550,m2=0.450;
//METERS PER SECONDS SQUARED
double g=9.81;
//METERS
double l1=0.35,l2=0.35;
//INITIAL VARIABLES
double
x1_0,dx1_0,ddx1_0,x2_0,dx2_0,ddx2_0,y1_0,dy1_0,ddy1_0,y2_0,dy2_0,ddy2_0,ang1_0,dang1_0,ddang1_0,ang2_0,dang2_0,ddang2
_0;
//CURRENT VARIABLES
double x1,dx1,ddx1,x2,dx2,ddx2,y1,dy1,ddy1,y2,dy2,ddy2,ang1,dang1,ddang1,ang2,dang2,ddang2;
//RK VARIABLES
double k1x1,k1dx1,k1x2,k1dx2,k1y1,k1dy1,k1y2,k1dy2,k1ang1,k1dang1,k1ang2,k1dang2;
double k2x1,k2dx1,k2x2,k2dx2,k2y1,k2dy1,k2y2,k2dy2,k2ang1,k2dang1,k2ang2,k2dang2;
double k3x1,k3dx1,k3x2,k3dx2,k3y1,k3dy1,k3y2,k3dy2,k3ang1,k3dang1,k3ang2,k3dang2;
double k4x1,k4dx1,k4x2,k4dx2,k4y1,k4dy1,k4y2,k4dy2,k4ang1,k4dang1,k4ang2,k4dang2;
//FINDING INITAL VARIABLES
//ALL ANGLES AND DERIVATIVES FROM ANGELS IN RADIANS, RADIANS PER SECONDS, AND RADIANS PER
SECONDS SQUARED
ang1=3.141592/2.0;
dang1=0.0;
ang2=3.141592/2.0;
dang2=0.0;

Copyright 2015 by Caleb Shunatona

ddang1=fdang1(g,m1,m2,l1,l2,ang1,dang1,ang2,dang2);
ddang2=fdang2(g,m1,m2,l1,l2,ang1,dang1,ang2,dang2);
x1=l1*sin(ang1);
dx1=fx1(l1,ang1,dang1);
ddx1=fdx1(l1,ang1,dang1,ddang1);
x2=x1+l1*sin(ang2);
dx2=fx2(l2,ang2,dang2,dx1);
ddx2=fdx2(l2,ang2,dang2,ddang2,ddx1);
y1=-l1*cos(ang1);
dy1=fy1(l1,ang1,dang1);
ddy1=fdy1(l1,ang1,dang1,ddang1);
y2=y1-l2*cos(ang2);
dy2=fy2(l2,ang2,dang2,dy1);
ddy2=fdy2(l2,ang2,dang2,ddang2,ddy1);
//CHECK INITIAL OUTPUTS
/*
cout << 0.0 << " " << ang1 << endl;
cout << 0.0 << " " << dang1 << endl;
cout << 0.0 << " " << ddang1 << endl;
cout << 0.0 << " " << ang2 << endl;
cout << 0.0 << " " << dang2 << endl;
cout << 0.0 << " " << ddang2 << endl;
cout << 0.0 << " " << x1 << endl;
cout << 0.0 << " " << dx1 << endl;
cout << 0.0 << " " << ddx1 << endl;
cout << 0.0 << " " << x2 << endl;
cout << 0.0 << " " << dx2 << endl;
cout << 0.0 << " " << ddx2 << endl;
cout << 0.0 << " " << y1 << endl;
cout << 0.0 << " " << dy1 << endl;
cout << 0.0 << " " << ddy1 << endl;
cout << 0.0 << " " << y2 << endl;
cout << 0.0 << " " << dy2 << endl;
cout << 0.0 << " " << ddy2 << endl;
*/
//OUTPUTS AT TIME 0
//cout << x1 << " " << y1 << endl;
//cout << x2 << " " << y2 << endl;
//cout << 0.0 << " " << ang1 << endl;
//cout << 0.0 << " " << ang2 << endl;
//cout << 0.0 << " " << dang1 << endl;
//cout << 0.0 << " " << dang2 << endl;
for (double tm=0.0;tm<=t;tm+=dt)
{
//SET VALUES TO VALUES FOUND LAST ITTERATION
x1_0=x1;
dx1_0=dx1;
ddx1_0=ddx1;
x2_0=x2;
dx2_0=dx2;

Copyright 2015 by Caleb Shunatona

ddx2_0=ddx2;
y1_0=y1;
dy1_0=dy1;
ddy1_0=ddy1;
y2_0=y2;
dy2_0=dy2;
ddy2_0=ddy2;
ang1_0=ang1;
dang1_0=dang1;
ddang1_0=ddang1;
ang2_0=ang2;
dang2_0=dang2;
ddang2_0=ddang2;
//RK ON ALL VARIABLES EXCEPT DOUBLE DERIVATIVES
k1ang1=fang1(dang1);
k1dang1=fdang1(g,m1,m2,l1,l2,ang1,dang1,ang2,dang2);
k1ang2=fang2(dang2);
k1dang2=fdang2(g,m1,m2,l1,l2,ang1,dang1,ang2,dang2);
k1x1=fx1(l1,ang1,dang1);
k1dx1=fdx1(l1,ang1,dang1,ddang1);
k1x2=fx2(l2,ang2,dang2,dx1);
k1dx2=fdx2(l2,ang2,dang2,ddang2,ddx1);
k1y1=fy1(l1,ang1,dang1);
k1dy1=fdy1(l1,ang1,dang1,ddang1);
k1y2=fy2(l2,ang2,dang2,dy1);
k1dy2=fdy2(l2,ang2,dang2,ddang2,ddy1);
k2ang1=fang1(dang1+k1dang1*dt/2.0);
k2dang1=fdang1(g,m1,m2,l1,l2,ang1+k1ang1*dt/2.0,dang1+k1dang1*dt/2.0,ang2+k1ang2*dt/2.0,dang2+k1dang2*dt/2.0);
k2ang2=fang2(dang2+k1dang2*dt/2.0);
k2dang2=fdang2(g,m1,m2,l1,l2,ang1+k1ang1*dt/2.0,dang1+k1dang1*dt/2.0,ang2+k1ang2*dt/2.0,dang2+k1dang2*dt/2.0);
k2x1=fx1(l1,ang1+k1ang1*dt/2.0,dang1+k1dang1*dt/2.0);
k2dx1=fdx1(l1,ang1+k1ang1*dt/2.0,dang1+k1dang1*dt/2.0,ddang1);
k2x2=fx2(l2,ang2+k1ang2*dt/2.0,dang2+k1dang2*dt/2.0,dx1+k1dx1*dt/2.0);
k2dx2=fdx2(l2,ang2+k1ang2*dt/2.0,dang2+k1dang2*dt/2.0,ddang2,ddx1);
k2y1=fy1(l1,ang1+k1ang1*dt/2.0,dang1+k1dang1*dt/2.0);
k2dy1=fdy1(l1,ang1+k1ang1*dt/2.0,dang1+k1dang1*dt/2.0,ddang1);
k2y2=fy2(l2,ang2+k1ang2*dt/2.0,dang2+k1dang2*dt/2.0,dy1+k1dy1*dt/2.0);
k2dy2=fdy2(l2,ang2+k1ang2*dt/2.0,dang2+k1dang2*dt/2.0,ddang2,ddy1);
k3ang1=fang1(dang1+k2dang1*dt/2.0);
k3dang1=fdang1(g,m1,m2,l1,l2,ang1+k2ang1*dt/2.0,dang1+k2dang1*dt/2.0,ang2+k2ang2*dt/2.0,dang2+k2dang2*dt/2.0);
k3ang2=fang2(dang2+k2dang2*dt/2.0);
k3dang2=fdang2(g,m1,m2,l1,l2,ang1+k2ang1*dt/2.0,dang1+k2dang1*dt/2.0,ang2+k2ang2*dt/2.0,dang2+k2dang2*dt/2.0);
k3x1=fx1(l1,ang1+k2ang1*dt/2.0,dang1+k2dang1*dt/2.0);
k3dx1=fdx1(l1,ang1+k2ang1*dt/2.0,dang1+k2dang1*dt/2.0,ddang1);
k3x2=fx2(l2,ang2+k2ang2*dt/2.0,dang2+k2dang2*dt/2.0,dx1+k2dx1*dt/2.0);
k3dx2=fdx2(l2,ang2+k2ang2*dt/2.0,dang2+k2dang2*dt/2.0,ddang2,ddx1);
k3y1=fy1(l1,ang1+k2ang1*dt/2.0,dang1+k2dang1*dt/2.0);
k3dy1=fdy1(l1,ang1+k2ang1*dt/2.0,dang1+k2dang1*dt/2.0,ddang1);
k3y2=fy2(l2,ang2+k2ang2*dt/2.0,dang2+k2dang2*dt/2.0,dy1+k2dy1*dt/2.0);
k3dy2=fdy2(l2,ang2+k2ang2*dt/2.0,dang2+k2dang2*dt/2.0,ddang2,ddy1);
k4ang1=fang1(dang1+k3dang1*dt);
k4dang1=fdang1(g,m1,m2,l1,l2,ang1+k3ang1*dt,dang1+k3dang1*dt,ang2+k3ang2*dt,dang2+k3dang2*dt);

Copyright 2015 by Caleb Shunatona

k4ang2=fang2(dang2+k3dang2*dt);
k4dang2=fdang2(g,m1,m2,l1,l2,ang1+k3ang1*dt,dang1+k3dang1*dt,ang2+k3ang2*dt,dang2+k3dang2*dt);
k4x1=fx1(l1,ang1+k3ang1*dt,dang1+k3dang1*dt);
k4dx1=fdx1(l1,ang1+k3ang1*dt,dang1+k3dang1*dt,ddang1);
k4x2=fx2(l2,ang2+k3ang2*dt,dang2+k3dang2*dt,dx1+k3dx1*dt);
k4dx2=fdx2(l2,ang2+k3ang2*dt,dang2+k3dang2*dt,ddang2,ddx1);
k4y1=fy1(l1,ang1+k3ang1*dt,dang1+k3dang1*dt);
k4dy1=fdy1(l1,ang1+k3ang1*dt,dang1+k3dang1*dt,ddang1);
k4y2=fy2(l2,ang2+k3ang2*dt,dang2+k3dang2*dt,dy1+k3dy1*dt);
k4dy2=fdy2(l2,ang2+k3ang2*dt,dang2+k3dang2*dt,ddang2,ddy1);
//FINDING ALL VALUES GIVEN FROM RK
ang1=ang1_0+1.0/6.0*(k1ang1+2.0*k2ang1+2.0*k3ang1+k4ang1)*dt;
dang1=dang1_0+1.0/6.0*(k1dang1+2.0*k2dang1+2.0*k3dang1+k4dang1)*dt;
ang2=ang2_0+1.0/6.0*(k1ang2+2.0*k2ang2+2.0*k3ang2+k4ang2)*dt;
dang2=dang2_0+1.0/6.0*(k1dang2+2.0*k2dang2+2.0*k3dang2+k4dang2)*dt;
x1=x1_0+1.0/6.0*(k1x1+2.0*k2x1+2.0*k3x1+k4x1)*dt;
dx1=dx1_0+1.0/6.0*(k1dx1+2.0*k2dx1+2.0*k3dx1+k4dx1)*dt;
x2=x2_0+1.0/6.0*(k1x2+2.0*k2x2+2.0*k3x2+k4x2)*dt;
dx2=dx2_0+1.0/6.0*(k1dx2+2.0*k2dx2+2.0*k3dx2+k4dx2)*dt;
y1=y1_0+1.0/6.0*(k1y1+2.0*k2y1+2.0*k3y1+k4y1)*dt;
dy1=dy2_0+1.0/6.0*(k1dy1+2.0*k2dy1+2.0*k3dy1+k4dy1)*dt;
y2=y2_0+1.0/6.0*(k1y2+2.0*k2y2+2.0*k3y2+k4y2)*dt;
dy2=dy2_0+1.0/6.0*(k1dy2+2.0*k2dy2+2.0*k3dy2+k4dy2)*dt;
//FIND THE VALUES FOR DOUBLE DERIVATIVE VALUES AT TM+DT USING VALUES FOUND FROM RK
ddang1=fdang1(g,m1,m2,l1,l2,ang1,dang1,ang2,dang2);
ddang2=fdang2(g,m1,m2,l1,l2,ang1,dang1,ang2,dang2);
ddx1=fdx1(l1,ang1,dang1,ddang1);
ddx2=fdx2(l2,ang2,dang2,ddang2,ddx1);
ddy1=fdy1(l1,ang1,dang1,ddang1);
ddy2=fdy2(l2,ang2,dang2,ddang2,ddy1);
//OUTPUT FOR VALUES AT TM+DT
//cout << x1 << " " << y1 << endl;
//cout << x2 << " " << y2 << endl;
//cout << tm+dt << " " << ang1 << endl;
//cout << tm+dt << " " << ang2 << endl;
//cout << tm+dt << " " << dang1 << endl;
//cout << tm+dt << " " << dang2 << endl;
}
//OUTPUT FOR VALUES AT 15 SECONDS
cout << x1 << endl;
cout << y1 << endl;
cout << x2 << endl;
cout << y2 << endl;
cout << ang1 << endl;
cout << ang2 << endl;
cout << dang1 << endl;
cout << dang2 << endl;
return 0;
}

Copyright 2015 by Caleb Shunatona

Copyright 2015 by Caleb Shunatona

10

Copyright 2015 by Caleb Shunatona

11

Copyright 2015 by Caleb Shunatona

Das könnte Ihnen auch gefallen