Help with event function in ode15s

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!

回答 (2 件)

Jacob Wood
Jacob Wood 2020 年 2 月 19 日

0 投票

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 件のコメント

Jacob Jepson
Jacob Jepson 2020 年 2 月 19 日
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 2020 年 2 月 19 日
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.

サインインしてコメントする。

Steven Lord
Steven Lord 2020 年 2 月 19 日

0 投票

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 件のコメント

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

サインインしてコメントする。

カテゴリ

タグ

質問済み:

2020 年 2 月 19 日

コメント済み:

2020 年 2 月 19 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by