MATLAB Answers

Help with event function in ode15s

3 views (last 30 days)
Jacob Jepson
Jacob Jepson on 19 Feb 2020
Commented: Steven Lord on 19 Feb 2020
My code integrates with ode15s a function called CellODE with the parameters mentioned. I would like my event function to stop the CellODE function to stop running when any value of Y_out is larger than one. Without Event checker, My code would produce Y_out which would be a matrix of how ever many rows ode15s decided it needed, and space_steps amount of collumns. I want event checker to stop this code running the moment Y_out produces a value higher than 1. (this might happen even after the 3rd or 4th time step..). The below code is the main script Im using.
close all; clc;
P=1.2;
k=1.2;
mu_n=1;
mu_w=1;
T=5000;
space_steps=1000;
x=linspace(0,1,space_steps).';
dx=1/space_steps;
n0=0.6*(1-(x).^2);
s_0=1;
T_span=[0;T];
options = odeset('Events',@MyEvent);
[T_out,Y_out,te,ye,ie] = ode15s(@(t,y) CellODE(t,y,k,P,mu_n,mu_w,space_steps),T_span,[n0;s_0],options);
The below code is the event checker function, I'm sure that something is incorrect in the second line.
function [val, isterminal, dir] = MyEvent(~, Y)
val = (Y>=1);
isterminal = 1;
dir = 0;
end
Thanks for any help!

  0 Comments

Sign in to comment.

Answers (2)

Jacob Wood
Jacob Wood on 19 Feb 2020
The event you are looking to implement sounds quite similar to the example event Matlab uses in the documentation. We can change the example a touch to detect the point where height = 1 instead of 0 with a small edit:
function [value,isterminal,direction] = bounceEvents(t,y)
% value = y(1); % Detect height = 0
value = y(1) - 1; % Detect height = 1
isterminal = 1; % Stop the integration
direction = -1; % Negative direction only

  2 Comments

Jacob Jepson
Jacob Jepson on 19 Feb 2020
Hi Jacob, i just tried this; but matlab threw the 'Index exceeds array bounds' For this line of code:
[T_out,Y_out,te,ye,ie] = ode15s(@(t,y) CellODE(t,y,k,P,mu_n,mu_w,space_steps),T_span,[n0;s_0],options);
are you sure your modification would be correct; note that I would not have a value identically to 1 in my arrays; but values that are larger than 1.
Jacob Jepson
Jacob Jepson on 19 Feb 2020
Whoops, scratch that. I was doing Y-1 instead of Y(1)-1. However, things still aren't working my event function still doesn't catch values that are larger than 1. It will integrate until the end; and values that are above one are sitll present in it.

Sign in to comment.


Steven Lord
Steven Lord on 19 Feb 2020
function [val, isterminal, dir] = MyEvent(~, Y)
val = (Y>=1);
isterminal = 1;
dir = 0;
end
Your event function's value should not be logical true or false. It should be a value that can cross zero, so that crossing can be detected.
function [val, isterminal, dir] = MyEvent(~, Y)
val = Y-1;
isterminal = 1;
dir = 0;
end

  2 Comments

Jacob Jepson
Jacob Jepson on 19 Feb 2020
I tried your suggestion, however I got an 'Index exceeds array bounds' error
Steven Lord
Steven Lord on 19 Feb 2020
Can you show the full text of the error message (all the text displayed in red) and the exact contents of your event function?

Sign in to comment.

Sign in to answer this question.