Backward Euler + Quasi Newton(Broyden) 方法无法求解 Van der Pol 方程 (Stiff ODE)

计算科学 matlab 牛顿法 刚性
2021-12-02 12:39:23

第一个猜测是使用前向欧拉方法。第一个雅可比使用有限差分。然后使用 NR 方法求解下一次迭代,并使用 Broyden 方法更新雅可比,直到满足容差。该图显示了我得到的结果与正确结果的比较。我可以对我的代码进行哪些改进,以便我朝着正确的方向前进(至少)。这是MATLAB代码。

function [t,y] = bdf1_qn_broyden(fcn,tspan,Y0,h,tol)

t = (tspan(1):h:tspan(2))';     %timestep vector
n = length(t);                  %no of steps
y = zeros(n,length(Y0));        %creting output array
y(1,:) = Y0;                    %first row of o/p is initial condition
i = 2;                              
jac = zeros(length(Y0));
unity = eye(length(Y0));

while i <= n 
    H = h*unity;
    for j = 1:1:length(Y0)
        jac(:,j) = fcn(t(i),y(i-1,:)' + H(:,j)) - fcn(t(i),y(i-1,:)');
    end
    iterate = (unity - jac)\unity;
    jac = (1/h)*jac;
    ycurr = y(i-1,:)' + h*fcn(t(i-1),y(i-1,:)');
    count = 0;
    diff = 1;
    while any(diff > tol) && (count < 25)
        curreval = fcn(t(i),ycurr);
        ynext = ycurr - iterate*(ycurr - y(i-1,:)' - h*curreval);
        delta = ynext - ycurr;
        deltaeval = fcn(t(i),ynext) - curreval;
        jac = jac + (1/dot(delta,delta))*(deltaeval - jac*delta)*delta';
        iterate = (unity - h*jac)\unity;
        diff = abs(delta);
        ycurr = ynext;
        count = count +1;
    end
    if count >= 25
    disp('Iterative method failed to converge within 25 steps');
    end
    y(i,:) = ynext';
    i = i+1;    
end
end

结果

正如您可能已经猜到的那样,我是新手,我的代码效率很低。但是,如果我要慢一点,我希望至少是准确和慢的。如果不使用自适应步长,这是不可能的吗?BDF1 是否无法解决此类问题?我应该选择不同的方法吗?还是我应该更好地解决我的隐式函数?我的实施中有错误吗?我不知道该走哪条路。请指出我正确的方向。非常感谢!

2个回答

这并不奇怪。一方面,对于高度病态的非线性系统,Broyden 不是很稳定,并且具有刚性 ODE 意味着非线性系统将是病态的。这就是为什么刚性 ODE 求解器不使用 Broyden 而是使用牛顿迭代(好吧,一种特殊形式的准牛顿,它是牛顿迭代,但有时根据收敛性重用雅可比矩阵几个时间步)。

但其次,僵硬的 ODE 求解器知道非线性求解有可能因多种原因而发散(主要是对迭代的错误初始猜测),这就是为什么生产质量代码中使用的所有求解都是时间自适应的。如果非线性求解发散,则减小并重试,因为知道你有ΔtΔt0un+1un,所以对于任何稳定的外推,你的初始猜测会越来越好。如果您没有使用时间步进自适应性,那么这些代码中的大多数将无法正常工作。如果您查看诸如 CVODE 的 BDF 方法或 ode15s 之类的东西,您会发现在如此高刚性的问题上,它们可以有几个时间步长,采取微小的步骤:这对于该方法至关重要。

有关如何编写刚性 ODE 求解器的更多信息,请参阅https://mitmath.github.io/18337/lecture9/stiff_odes和 Hairer II 第 8 章中的讨论。

由于性能不是主要关注点,因此只需及时使用反向欧拉有限差分逼近、在每个时间步使用直接求解器的全牛顿法以及雅可比行列式的中心差分逼近。

由于雅可比矩阵只是一个 2x2 矩阵,因此准牛顿解法没有用处。