MATLAB 的 ode45 的意外结果

计算科学 matlab 数字 耦合
2021-12-11 05:16:52

最近在使用 MATLAB 时,我遇到了一些我无法解释的奇怪问题。我正在使用 ode45 求解器来求解两个耦合二阶 ODE 的系统。我不相信结果,所以我尝试了一些更简单的方法,只是想看看哪里出了问题。我将方程解耦,并将其中一个交换为一个简单的谐振子。

令人惊讶的是,我没有得到我所期望的。然而,当我从第二个等式中删除其中一个项(现在已解耦!)并再次运行它时,它产生了一个正确的答案。这让我大吃一惊,因为现在这两个方程之间根本没有联系。这是我修改后的代码:

主功能:

function Ord2ODE

t=0:0.0001:20;
%x,xdot,y,ydot
ainit = [0; 1; 0; 0];

[t,a] = ode45(@rhs,t,ainit);

figure;
plot(t, a(:,1));

end

和函数rhs:

function dadt = rhs(t,a)

mu = 0;

x = a(1);
xdot = a(2);
y = a(3);
ydot = a(4);

**Fy = stuff in terms of x, y (a(1), a(2))**
Fx = stuff in terms of x, y (a(1), a(2))

dadt1 = a(2);
dadt2 = -2*a(1);  
dadt3 = a(4);
dadt4 = -2*a(3) - **Fy**;

dadt = [dadt1;dadt2;dadt3;dadt4];

end

带有 ** ** 标记的问题位(dadd4 计算中的定义和出现)。您可以看到在 x 的计算中既不存在 a(3) 也不存在 a(4)。带有和不带有该术语的结果发布在下面。有谁知道为什么解耦方程中的一个项会在另一个方程的解中导致这种发散?

和 没有

Fy = -mu*y - (1-mu)*y + mu*y/(sqrt(((x+1-mu)^2 + y^2)^3)) + (1-mu)*y/(sqrt(((x-mu)^2 + y^2)^3));

Fx = -mu*(x+1-mu) - (1-mu)*(x-mu) + mu*(x+1-mu)/(sqrt(((x+1-mu)^2 + y^2)^3)) + (1-mu)*(x-mu)/(sqrt(((x-mu)^2 + y^2)^3));

Fy=μy(1μ)y+μy(((x+1μ)2+y2)3)+(1μ)y(((xμ)2+y2)3)

Fx=μ(x+1μ)(1μ)(xμ)+μ(x+1μ)(((x+1μ)2+y2)3)+(1μ)(xμ)(((xμ)2+y2)3)

3个回答

根据我从您的问题中了解到的情况,第一个情节已经变得不稳定,所以也许如果您在第一个时间段(最多 4 秒左右)使用这两种方法绘制了情节,那么您的两个解决方案将匹配(查看您的情节他们似乎匹配)。如果是这种情况,请尝试使用不同的求解器来求解问题,或缩小时间步长以确保问题与时间步长方案无关。

这是对可能发生的事情的猜测。ode45(与所有 MATLAB ode 求解器一样)根据对求解误差的估计调整步长。在此计算中考虑所有方程,无论它们是否耦合。

解决方案误差与两个参数 AbsTol 和 RelTol 进行比较。这两个都有默认值,但有时这些默认值不会产生准确的解决方案。我建议对这两个参数进行试验(例如,将它们缩小一个数量级),看看它如何影响您的解决方案。

尽管在没有 Fy 的情况下这两个方程是解耦的,但它们都是一起求解的,如果求解一个方程有问题,则可能是求解另一个方程的问题。

我复制了你的代码并运行了它。y 的方程不稳定并很快返回 NaN。但是,对我来说,无论我是否包含 Fy,x 的结果都是相同的。