Home > database >  Euler method in c ; Values getting too big too fast
Euler method in c ; Values getting too big too fast

Time:10-29

i am trying to solve the equation of motion for a particle with mass m attached to a spring with a spring constant k. Both are set to 1 however. The algorithm looks like this:

enter image description here

My (attempted) solution, written in c , looks like this:

#include <iostream>
#include <iomanip>
#include <math.h>
#include <stdlib.h>
#include <fstream>

// Initialise file to write series of values in
std::ofstream output("Eulermethod.txt");

// Define Euler algorithm
void euler(double x_0, double v_0, double delta, double t_max) {
    double x_prev = x_0;
    double v_prev = v_0;
    double x_new, v_new;
    for (double t = 0; t < t_max; t = t   delta) {
        x_new = x_prev   t * v_prev;
        v_new = v_prev - t * x_prev;
        // Writes time, position and velocity into a csv file
        output << std::fixed << std::setprecision(3) << t << "," << x_prev << "," << v_prev << std::endl;
        x_prev = x_new;
        v_prev = v_new;
        // Breaks loop if values get to big
        if ((x_new != x_new) || (v_new != v_new) || (std::isinf(x_new) == true) || (std::isinf(v_new) == true)) {
            break;
        }
    }
}

int main() {
    // Initialize with user input 
    double x_0, v_0, t_max, delta;
    std::cout << "Initial position x0?: ";
    std::cin >> x_0;
    std::cout << "Intial velocity v0?: ";
    std::cin >> v_0;
    std::cout << "Up to what time t_max?: ";
    std::cin >> t_max;
    std::cout << "Step size delta?: ";
    std::cin >> delta;
    // Runs the function
    euler(x_0, v_0, delta, t_max);
}

I know that the solution will grow indefinitely but for smaller values of t it should resemble the analytical solution while growing slowly. The values i get are blowing out of proportions after ca. 10 iterations and i can not find out why. When i plot the position as a function of the time i get the plot below, which is obviously wrong.

enter image description here

CodePudding user response:

Your equation implementation is wrong. You are usint t instead of dt. Correct variant:

x_new = x_prev   delta * v_prev;
v_new = v_prev - delta * x_prev;

And a side note if you plan to develop your code further: common approach to implementation of ODE solver is to have a method with signature similar to

Output = solveOde(System, y0, t);

Where System is method that describes the ODE dy/dx = f(x,t), e.g.

std::vector<double> yourSystem(std::vector<double> y, double /*t unused*/)
{
    return {y[1], -y[0]};
}

y0 are initial conditions, and t is a time vector (delta is calculated internally). Take a look at boost odeint or more compact and transparent python documentation.

  • Related