如何在Scilab上求解二阶微分方程?

时间:2018-10-03 21:01:38

标签: numerical-methods differential-equations scilab numerical-integration runge-kutta

我需要在Scilab上使用Runge-Kytta 4(5)解决这个微分方程:

enter image description here

上面的初始条件。间隔和h步是:

enter image description here

enter image description here

我不需要实现Runge-Kutta。我只需要解决这个问题并在平面上绘制结果即可:

enter image description here

我尝试按照官方的“ Scilab帮助”中的说明进行操作:

https://x-engineer.org/graduate-engineering/programming-languages/scilab/solve-second-order-ordinary-differential-equation-ode-scilab/

建议的代码是:

// Import the diagram and set the ending time
loadScicos();
loadXcosLibs();
importXcosDiagram("SCI/modules/xcos/examples/solvers/ODE_Example.zcos");
scs_m.props.tf = 5000;

// Select the solver Runge-Kutta and set the precision
scs_m.props.tol(6) = 6;
scs_m.props.tol(7) = 10^-2;

// Start the timer, launch the simulation and display time
tic();
try xcos_simulate(scs_m, 4); catch disp(lasterror()); end
t = toc();
disp(t, "Time for Runge-Kutta:");

但是,对于我上面显示的特定微分方程,我不清楚如何更改它。我对Scilab非常了解。

最终情节应该类似于下面的椭圆形:

enter image description here

仅提供一些数学上下文,这是描述摆问题的微分方程。

有人可以帮我吗?

=========

更新

基于@luizpauloml的评论,我正在更新此帖子。 我需要将二阶ODE转换为一阶ODE的系统,然后我需要编写一个函数来表示这样的系统。

所以,我知道该如何在纸和笔上做到这一点。因此,使用z作为变量:

enter image description here

确定,但是我该如何编写普通脚本?

Xcos非常易于使用。我之所以保留它,是因为我试图模仿Scilab官方页面上的示例。

1 个答案:

答案 0 :(得分:2)

要解决此问题,您需要使用ode(),它可以采用许多方法,包括Runge-Kutta。首先,您需要定义一个表示ODE系统的函数,并且您提供的链接中的步骤1 向您展示了如何做:

function z = f(t,y)
    //f(t,z) represents the sysmte of ODEs:
    //    -the first argument should always be the independe variable
    //    -the second argument should always be the dependent variables
    //    -it may have more than two arguments
    //    -y is a vector 2x1: y(1) = theta, y(2) = theta'
    //    -z is a vector 2x1: z(1) = z    , z(2) = z'

    z(1) = y(2)         //first equation:  z  = theta'
    z(2) = 10*sin(y(1)) //second equation: z' = 10*sin(theta)
endfunction

请注意,即使t(自变量)未在ODE系统中显式出现,它仍然需要作为f()的参数。现在,您只需使用ode(),将标志'rk''rkf'设置为使用可用的Runge-Kutta方法之一:

ts = linspace(0,3,200);
theta0  = %pi/4;
dtheta0 = 0;
y0 = [theta0; dtheta0];
t0 = 0;
thetas = ode('rk',y0, t0, ts, f); //the output have the same order
                                  //as the argument `y` of f()

scf(1); clf();
plot2d(thetas(2,:),thetas(1,:),-5);
xtitle('Phase portrait', 'theta''(t)','theta(t)');
xgrid();

输出:

Phase portrait of a gravity pendulum