0

My problem is, frankly, that I'm unsure how this works.

I need to modify the double f() function to solve an arbitrary differential equation d2θ/dt2 = −ω2sinθ, but as it is I am unsure how to proceed.

The rk4 function runge4() itself I understand; What I don't understand is how the f() function returns the correct values for the harmonic oscillator.

Would someone please at least explain the logic behind the f() function?

Original code is below.

/* 
************************************************************************
*  rk4.c: 4th order Runge-Kutta solution for harmonic oscillator       *
*                      *
* From: "A SURVEY OF COMPUTATIONAL PHYSICS" 
   by RH Landau, MJ Paez, and CC BORDEIANU 
   Copyright Princeton University Press, Princeton, 2008.
   Electronic Materials copyright: R Landau, Oregon State Univ, 2008;
   MJ Paez, Univ Antioquia, 2008; & CC BORDEIANU, Univ Bucharest, 2008
   Support by National Science Foundation                              
*
************************************************************************
*/

#include <stdio.h>

#define N 2                                   /* number of equations */
#define dist 0.1                              /* stepsize */
#define MIN 0.0                               /* minimum x */
#define MAX 10.0                              /* maximum x */

void runge4(double x, double y[], double step);
double f(double x, double y[], int i);

int main()
{

   double x, y[N];
   int j;

   FILE *output;                              /* save data in rk4.dat */
   output = fopen("rk4.dat","w");

   y[0] = 1.0;                                /* initial position  */
   y[1] = 0.0;                                /* initial velocity  */

   fprintf(output, "%f\t%f\n", x, y[0]);

   for(x = MIN; x <= MAX ; x += dist)
   {
      runge4(x, y, dist);
      fprintf(output, "%f\t%f\n", x, y[0]);   /* position vs. time */
   }
   printf("data stored in rk4.dat\n");
   fclose(output);
}
/*-----------------------end of main program--------------------------*/

/* Runge-Kutta subroutine */
void runge4(double x, double y[], double step)
{
   double h=step/2.0,                         /* the midpoint */
          t1[N], t2[N], t3[N],                /* temporary storage */
          k1[N], k2[N], k3[N],k4[N];          /* for Runge-Kutta  */
   int i;

   for (i=0; i<N; i++) t1[i] = y[i]+0.5*(k1[i]=step*f(x, y, i));
   for (i=0; i<N; i++) t2[i] = y[i]+0.5*(k2[i]=step*f(x+h, t1, i));
   for (i=0; i<N; i++) t3[i] = y[i]+    (k3[i]=step*f(x+h, t2, i));
   for (i=0; i<N; i++) k4[i] =                 step*f(x + step, t3, i);

   for (i=0; i<N; i++) y[i] += (k1[i]+2*k2[i]+2*k3[i]+k4[i])/6.0;
}
/*--------------------------------------------------------------------*/

/* definition of equations - this is the harmonic oscillator */
double  f(double x, double y[], int i)
{
   if (i == 0) return(y[1]);               /* RHS of first equation */
   if (i == 1) return(-y[0]);              /* RHS of second equation */
}

2 Answers 2

3

Start from Hooke's law:

F = -kx

Combine this with Newton's second law to get the differential equation for a linear harmonic oscillator:

ma = F = -kx
mx'' = -kx
x'' = -k/m x

Arbitrarily chose our units so that k/m == 1, and the equation becomes just:

x'' = -x

Now, introduce a dummy variable y = x', and write this second-order differential equation as a two-dimensional first-order system:

x' = y
y' = -x

The function f in your code encodes exactly this system; I'm going to change the variable names for clarity:

double  f(double t, double v[], int i)
{
   if (i == 0) return(v[1]);
   if (i == 1) return(-v[0]);
}

v is the vector [x,y] from the two dimensional system above. Given i, t, and v, the function f returns the derivative with respect to t of the ith component of v. Re-writing the 2d system using these names, we get:

dv[0]/dt =  v[1]
dv[1]/dt = -v[0]

Which is exactly what the function f does.

0

N is defined as a constant 2. This means those loops are going to be doing 2 iterations, i = 0 and i = 1

The f() function will return the second element of the polynomial passed in if i == 0 and the negative of the first element of that polynomial if i == 1.

I don't know the formula for acquiring the harmonic oscillator (it sounds like something Geordi LaForge would say needs recalibrating or something, honestly) but I would assume that's it.

1
  • Note: I'm assuming the y parameter is a polynomial. I could be mistaken.
    – corsiKa
    Commented Apr 29, 2011 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.