四阶龙格-库塔和谐波振荡器

计算科学 龙格库塔
2021-12-04 11:33:52

我正在尝试使用 4 阶 runge kutta 方法求解谐振子的运动方程,但结果我得到几乎恒定的速度和位置;我觉得问题是我没有完全理解这个方法。

这是我正在使用的代码(在 C++ 中)

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

using namespace std;

ofstream output;

void rk(double,double*,double*, double*,double*, int);
void print_file(double*, double*,double*,int n);

int main(int argc, char* argv[]){
    double *t,*x,*v,*ic;

    double h,in=0,fin=2*M_PI;
    int n=10000;

    char* file=argv[1];
    output.open(file);

    h=(fin-in)/n;

    t=new double[n];
    x=new double[n];
    v=new double[n];
    ic=new double[2];

    ic[0]=1;//in. cond. pos.
    ic[1]=0;//in. cond. vel.

    rk(fun,h,ic,t,v,x,n);
    for(int i=0;i<n;i+=500){cout << x[i] << "  " << v[i] << endl;}

    print_file(t,x,v,n);

    delete[] t;
    delete[] x;
    delete[] v;
    delete[] ic;
}

void rk(double step,double *ic,double* t, double* v, double* x, int n){
    double k1,k2,k3,k4;
    for(int i=1;i<n;i++){
        t[i]=i*step;

        x[0]=ic[0];
        v[0]=ic[1];

        k1=step*(-x[i-1]);
        k2=step*(-x[i-1]+step/2);
        k3=step*(-x[i-1]+step/2);
        k4=step*(-x[i-1]+step);
        v[i]=v[i-1]+(k1+2*k2+2*k3+k4)*step/6;

        k1=step*(v[i-1]);
        k2=step*(v[i-1]+step/2);
        k3=step*(v[i-1]+step/2);
        k4=step*(v[i-1]+step);
        x[i]=x[i-1]+(k1+2*k2+2*k3+k4)*step/6;
}}

void print_file(double* t, double* x, double* v, int n){
    int i;
    for(i=0; i<=n; i++)
    output<<setw(15)<<t[i]<<setw(15)<<x[i]<<setw(15)<<v[i]<<endl;
    return;}

我的错误在哪里?

1个回答
    k1=step*(-x[i-1]);
    k2=step*(-x[i-1]+step/2);
    k3=step*(-x[i-1]+step/2);
    k4=step*(-x[i-1]+step);

那不是RK4的形式。每个k都有一个使用先前导数估计的导数计算。第一个应该是step*f(x[i-1]),然后下一个应该是step*f(x[i-1] + step/2 * k1), ... (写成非同质的)。然后我看不到f任何地方定义了你的导数,然后你还需要让它适用于矢量方程(可能使它就位等),因为你必须同时更新xand v我强烈建议您只使用已经制作完成的软件,因为最终,RK4 甚至不是处理此问题的最有效方法,即使您投入工作对其进行了一些测试。