使用ODE事件位置并将事件中的解决方案用作ode45的输入

时间:2016-12-04 02:48:05

标签: matlab ode

我一直试图重新创建以下论文中的情节:

http://iopscience.iop.org/article/10.1088/0964-1726/4/4/006/meta

我试图重新创建的情节在第267页的右上角,具体来说,$ x(t)$ vs. $ t $。

论文中使用的ODE是 $$米\ DDOT {X}(T)+ k_0x(T)+ K_1(X(t)的-x_s)= 0 $$ 其中$ x_s $是$ x_s = x(t_r)$定义的分段常量函数,只要$ \ dot {x}(t_r)= 0 $。

使用值$ m = 1,k_0 = 150,$和$ k_1 = 50生成绘图。$

解决此问题的代码如下:

tstart = 0;
tfinal = 2;

tspan = [tstart tfinal];
u0 = [1; 0];
refine = 4;
options = odeset('Events', @resetevent , 'OutputSel' , 1, 'Refine', refine);

tout = tstart;
uout = u0';
teout = [];
ueout = [];
ieout = [];
ue = [];
while tout(end) < tfinal

% Solve until the first terminal event.
[t, u, te, ue, ie] = ode45(@(t,u) sys(t, u, ue), [tstart tfinal] , u0, options);

% Accumulate output.  This could be passed out as output arguments.

nt = length(t);
tout = [tout; t(2:nt)];
uout = [uout; u(2:nt,:)];
teout = [teout; te];          % Events at tstart are never reported.
ueout = [ueout; ue];
ieout = [ieout; ie];


% Set the new initial conditions, with .9 attenuation (??).

u0 = [u(nt,1) ; u(nt,2)];

% A good guess of a valid first timestep is the length of the last valid
% timestep, so use it for faster computation.  'refine' is 4 by default.
options = odeset(options,'InitialStep',t(nt)-t(nt-refine),...
    'MaxStep',t(nt)-t(1));

tstart = t(nt);
end

figure(1)
set(gcf,'units','normalized','outerposition',[0 0 1 1])

subplot(2,1,1);
plot(tout,uout(:,1));
title(['Time history of $x(t)$'],'interpreter','latex','fontsize',20)
ylabel('$x$','interpreter','latex','fontsize',15)
xlabel('$t$','interpreter','latex','fontsize',15)
xlim(tspan)

grid on
hold on

subplot(2,1,2);
plot(tout,uout(:,2))
title('Time history of $\dot{x}(t)$','interpreter','latex','fontsize',20)
ylabel('$\dot{x}$','interpreter','latex','fontsize',15)
xlabel('$t$','interpreter','latex','fontsize',15)
xlim(tspan)

grid on
hold on

subplot(2,1,1);
stairs(teout,ueout(:,1))
title('Time history of $x_s(t)$','interpreter','latex','fontsize',20)
xlabel('$t$','interpreter','latex','fontsize',15)
xlim(tspan)

grid on
hold on

% 
function dz = sys(t, z , us)
dz = zeros(2,1);
if isempty(us) == 1
    us = 0;
else
    us;
end

% if isempty(us) == 1
%     us = 0;
% elseif us(1) == 1
%     us(1) = -1;
% else
%     us;
% end

m = 1;
k0 = 150;
k1 = 50;

dz(1) = z(2);
dz(2) = - ((k0 + k1)/m)*z(1) + (k1/m)*us(1);
end


% Reset Event Function
function [lookfor, stop, direction] = resetevent(t, z)
% Locate the time when xdot passes through zero in any direction
% and stop integration.
lookfor = z(2);  % when xdot = 0
stop = 1;        % stop the integration
direction = 0;   % any direction
end

使用u0=[1 ; 0]生成的情节是 enter image description here

使用u0=[1 ; -eps]生成的情节是 enter image description here

使用u0=[u(nt,1) ; 0]作为重启初始条件生成的图是 enter image description here 我有几个与此相关的问题:

  1. 让我感到困惑的是,由于某种原因,Matlab确实找到了 $ \ dot {x} $的第一个零并输入到函数中,但是 关于ODE Event Location的文档说它跳过了第一个 终端事件。这可能是我做错的事情,但我无法做到 看看它是什么。

  2. 如果你看一下$ \ dot {x}(t)$的情节,在它经过零的点上,我的初始条件是从 它结束的最后一个值,它在图中给出了一个扭结,这意味着衍生物不匹配。我试过了 使用0作为初始值,这对我来说很有意义,但它会导致求解器发散。然而,似乎衍生品匹配稍好一些。 我不确定0.9衰减是什么,我试着搞砸了 那无济于事。

  3. 如果您在函数sys中使用注释代码,它将强制us的值,并且该图将看起来像文章中的那个,但它太具体而不是我想要做的是什么,因为我想将重置的想法扩展到不同的ODE。

    我还注意到,如果我将初始条件设置为u0 = [1 ; -eps],它实际上将从零开始,但不会精确归零,从而生成正确的图。

    感谢您的帮助!

0 个答案:

没有答案