爆炸龙格库塔方法

时间:2015-01-19 02:33:52

标签: c++ bash physics projectile runge-kutta

我一直试图建立龙格库塔四阶积分器来模拟简单的抛射物运动。我的代码如下

double rc4(double initState, double (*eqn)(double,double),double now,double dt)
{
        double k1 = eqn(initState,now);
        double k2 = eqn(initState + k1*dt/2.0,now + dt/2.0);
        double k3 = eqn(initState + k2*dt/2.0,now + dt/2.0);
        double k4 = eqn(initState + k3*dt, now + dt);

        return initState + (dt/6.0) * (k1 + 2*k2 + 2*k3 + k4);
}

在while循环中调用

while (time <= duration && yPos >=0)
                {

                        xPos = updatePosX(xPos,vx,timeStep);
                        yPos = updatePosY(yPos,vy,timeStep);


                        vx = rc4(vx,updateVelX,time,timeStep);
                        vy = rc4(vy,updateVelY,time,timeStep);

                        cout << "x Pos: " << xPos <<"\t y Pos: " << yPos << endl;

                        time+=timeStep;

                        myFile << xPos << "  " << yPos << "  " << vx << "  " << vy << endl;

                }

然而,与应该发生的事情相反,我的结果只会爆炸。这里发生了什么?

1 个答案:

答案 0 :(得分:0)

您的rk4代码看起来正确。但仅适用于标量微分方程。

你最肯定的是一个大于1的耦合微分方程系统。在这里你必须以矢量形式应用积分方法。也就是说,x,y,vx,vy被组合成4维(相位)状态向量,系统函数是向量值,k1,...k4是向量等。

作为高级注释,time <= duration对于在time+=timeStep;的重复中累积的错误进行四舍五入是明智的。最好使用time <= duration-timeStep/2time在循环结束时接近duration


阅读封闭的上一个问题的代码我发现你对微分方程的想法有问题。您不应该使用Euler步骤的结果作为RK4实现中的加速。没有空气摩擦的弹道运动系统是

dotx = vx
doty = vy
dotvx = 0
dotvy = -g

你必须以矢量形式实现像

这样的东西
eqn(t, [x,y,vx,vy]) // where X = array of double of dimension 4
   { return [vx,vy,0,-g]; }