numerical methods - Using ode45 in Matlab -
i'm trying simulate time behavior physical process governed system of odes. when switch width
of input pulse 20
19
, there no depletion of y(1)
state, doesn't make sense physically. doing wrong? using ode45
incorrectly?
function test width = 20; center = 100; tspan = 0:0.1:center+50*(width/2); [t,y] = ode45(@odesystem,tspan,[1 0 0 0]); plot(t,y(:,1),'k*',t,y(:,2),'k:',t,y(:,3),'k--',t,y(:,4),'k'); hold on; axis([center-3*(width/2) center+50*(width/2) -0.1 1.1]) xlabel('time') ylabel('relative values') legend({'y1','y2','y3','y4'}); function dy = odesystem(t,y) k1 = 0.1; k2 = 0.000333; k3 = 0.1; dy = zeros(size(y)); % rectangular pulse = rectpuls(t-center,width); % ode system dy(1) = -k1*i*y(1); dy(2) = k1*i*y(1) - k2*y(2); dy(3) = k2*y(2) - k3*i*y(3); dy(4) = k3*i*y(3); end end
you changing parameters of your odes discontinuously in time. results in stiff system , less accurate, or wrong, results. in case, because ode simple when i = 0
, adaptive solver ode45
take large steps. thus, there's high probability step right on region inject impulse , never see it. see my answer here if you're confused why code in question misses pulse though you've specified tspan
have (output) steps of 0.1
.
in general bad idea have discontinuities (if
statements, abs
, min
/max
, functions rectpuls
, etc.) in integration function. instead, need break integration , calculate results piecewise in time. here's modified version of code implements this:
function test_fixed width = 19; center = 100; t = 0:0.1:center+50*(width/2); = rectpuls(t-center,width); % removed ode function, kept if wanted plotting % before pulse tspan = t(t<=center-width/2); y0 = [1 0 0 0]; [~,out] = ode45(@(t,y)odesystem(t,y,0),tspan,y0); % t pre-calculated, no need return y = out; % pulse tspan = t(t>=center-width/2&t<=center+width/2); y0 = out(end,:); % initial conditions same last stage previous integration [~,out] = ode45(@(t,y)odesystem(t,y,1),tspan,y0); y = [y;out(2:end,:)]; % append new data removing identical initial condition % after pulse tspan = t(t>=center+width/2); y0 = out(end,:); [~,out] = ode45(@(t,y)odesystem(t,y,0),tspan,y0); y = [y;out(2:end,:)]; plot(t,y(:,1),'k*',t,y(:,2),'k:',t,y(:,3),'k--',t,y(:,4),'k'); hold on; axis([center-3*(width/2) center+50*(width/2) -0.1 1.1]) xlabel('time') ylabel('relative values') legend({'y1','y2','y3','y4'}); function dy = odesystem(t,y,i) k1 = 0.1; k2 = 0.000333; k3 = 0.1; dy = zeros(size(y)); % ode system dy(1) = -k1*i*y(1); dy(2) = k1*i*y(1) - k2*y(2); dy(3) = k2*y(2) - k3*i*y(3); dy(4) = k3*i*y(3); end end
Comments
Post a Comment