0

This is the updated version of Runge Kutta (RK4) 2nd order DE in C++ ERROR CODE

I am still experiencing difficulties with the code. Maybe this has to do with my limited knowledge of Runge-Kutta but when I run this code it doesn't produce an output.

#include <iostream> 
#include <cmath>

    //dvdt=-(g/L)*sin(theta)
    //v=dxdt

double dxdt( double timepassed, double theta )
        {
            return theta/timepassed;
        }

    double L;   
    double g=9.8;
    double coeff=-1*(g/L);

double dvdt( double timepassed,  double x, double v)
        {
            return coeff*sin(x);
        }

int main(){

// Standard Variables   
    double theta;
    double theta1;
    double h = 0.1;
    double L;
    double timepassed;
    double time1;

// Input and Output Printing
    std::cout << "Please input initial angle (in decimal radians), length of the pendulum (in meters) and the time desired (in seconds). Click ENTER key after each value."<<"\n";
    std::cin >> theta1;
    std::cin >> L;  
    std::cin >> timepassed;

// Specific Variable Declarations
    double coeff=-1*(g/L);
    double v = dxdt(theta1, timepassed);
    double x = theta1;
    double d2xdt2 = dvdt(timepassed, theta1, v);

// Defining K Values in Runge Kutta
    double kx1,kv1;
    double kx2, kv2;
    double kx3, kv3;
    double kx4, kv4;
    double dt;

kx1=dt*dxdt(timepassed,x);
kv1=dt*dvdt(timepassed,x,v);
kx2=dt*dxdt(timepassed+dt/2,x+kx1/2);
kv2=dt*dvdt(timepassed+dt/2,x+kx1/2,v+kv1/2);
kx3=dt*dxdt(timepassed+dt/2,x+kx2/2);
kv3=dt*dvdt(timepassed+dt/2,x+kx2/2,v+kv2/2);
kx4=dt*dxdt(timepassed+dt,x+kx3);
kv4=dt*dvdt(timepassed+dt,x+kx3,v+kv3);
x = x + (1.0/6.0)*(kx1 + 2*kx2 + 2*kx3 + kx4);
v = v + (1.0/6.0)*(kx1 + 2*kv2 + 2*kv3 + kv4);


std::cout << "The angle is" << x; "\n"; 
std::cout << "The velocity is" << v;

}

  • The above code does not compile. So _"... it doesn't produce an output...."_ is it compile or runtime errors you want us to look at? – Richard Critten Nov 19 '19 at 16:43
  • Do you mean compile @RichardCritten ? It does compile, I am just not receiving an output. – Danielle Winckler Nov 19 '19 at 16:45
  • 1
    Live link: https://godbolt.org/z/RVtSjJ (perhaps increase your warning level) – Richard Critten Nov 19 '19 at 16:47
  • Your local variables mask the global ones. So that you read into the local variables of `main` and leave the global ones (that are used in the function calls) unchanged, esp. `L` undefined and thus `coeff` too. If the compiler is nice and initializes not to random but to zero, you get a division-by-zero error at compilation time. – Lutz Lehmann Nov 19 '19 at 17:00
  • Please compile with option `-Wall` and reduce the trivial errors to a minimum (one exception is that `v` in `dvdt(t,x,v)` is unused but present due to some idea of a more general interface). Please explain what you think `dxdx(t,theta)` computes. And why it does not share the interface `dxdt(t,x,v)`. – Lutz Lehmann Nov 19 '19 at 17:06
  • I fixed the universal variables issue. However I don't understand what you mean by dvdt is not being used and where you are reading dxdx from. Can you please ellaborate @Dr.LutzLehmann ? – Danielle Winckler Nov 19 '19 at 19:56
  • @DanielleWinckler Lutz said that `v` isn't used in `dvdt`. Neither is `timepassed`. – Ted Lyngmo Nov 19 '19 at 20:06
  • @DanielleWinckler as you have fixed the issues you need to update the question so we can see what you need an answer to. – Richard Critten Nov 19 '19 at 20:31
  • I meant `dxdt` in both of the last two function names. – Lutz Lehmann Nov 19 '19 at 21:11

1 Answers1

0

Your system equations should be, as it is announced in the comment before it, as

//v=dx/dt
//dv/dt=d2x/dt2=-(g/L)*sin(x), where x=theta
double coeff;
double dxdt( double t, double x, double v) { return v; }
double dvdt( double t, double x, double v) { return coeff*sin(x); }

After the input of the parameters, the number coeff gets computed but not declared anew.

// Specific Variable Declarations
    coeff = -(g/L);

Your step size appears to be 0.1. You need to decide what variable name to use, h or dt, and then stay with it.

It is almost certain that you need to perform more than one RK4 step, thus you need to frame them with a loop. What that loop contains in addition to the RK4 stages depends on what the output of the program is supposed to be. Also, you need to adapt the last step if the target time is not a multiple of the time step.

    while(t < timepassed) {
        kx1=dt*dxdt(t,x,v);
        kv1=dt*dvdt(t,x,v);
        kx2=dt*dxdt(t+dt/2,x+kx1/2,v+kv1/2);
        kv2=dt*dvdt(t+dt/2,x+kx1/2,v+kv1/2);
        kx3=dt*dxdt(t+dt/2,x+kx2/2,v+kv2/2);
        kv3=dt*dvdt(t+dt/2,x+kx2/2,v+kv2/2);
        kx4=dt*dxdt(t+dt,x+kx3,v+kv3);
        kv4=dt*dvdt(t+dt,x+kx3,v+kv3);
        t = t + dt;
        x = x + (1.0/6.0)*(kx1 + 2*kx2 + 2*kx3 + kx4);
        v = v + (1.0/6.0)*(kx1 + 2*kv2 + 2*kv3 + kv4);
        // output for the step? Depending on the time?
    }
Lutz Lehmann
  • 25,219
  • 2
  • 22
  • 51