Event function with multiple events

Hi,
I'm calling a events function as below for ode45:
option2 = odeset('Events', @comp);
[time, Y] = ode45(dYdt, tspan, y0, option2);
The function looks as follow:
function [position, isterminal, direction] = comp(t, Y)
x = Y(1); %x-coordinate
y = Y(2); %y-coordinate
xL = x*cos(Par.theta) + y*sin(Par.theta);
xL1 = Par.x1*cos(Par.theta); %[m]
xL2 = Par.x2*cos(Par.theta); %[m]
position = [xL1-xL; xL2-xL; Par.S-Y(end,1)];
isterminal = [0; 0; 1];
direction = [1; 1; -1];
end
I keep getting the error "Undefined variable "Par" or class "Par.theta"." When I substitute the variables with other variables not in a structure I then get the error "Not enough input arguments", but I've checked each variable is accounted for.
Anyone one with a suggestion on how to correctly call a structure variables' values in a function would be appreciated.
Thanks

1 comentario

Christo van Rensburg
Christo van Rensburg el 16 de Sept. de 2019
So when I call the structure as such,
function [position, isterminal, direction] = comp(t, Y, Par)
it still gives the error of not enough input arguments. I cannot understand what input argument is missing?

Iniciar sesión para comentar.

 Respuesta aceptada

Steven Lord
Steven Lord el 16 de Sept. de 2019
When you define your options structure with:
option2 = odeset('Events', @comp);
the ODE solver will call your Events function comp with two input arguments. Changing the definition of comp to accept a third input argument is one of the steps you need to follow to call your Events function comp with three inputs. The easiest way to complete the next step is to change your odeset call. Assuming Par is defined before you call odeset and does not change during the ODE solution process, specify your Events function as an anonymous function.
% Par is defined at this point
option2 = odeset('Events', @(t, y) comp(t, y, Par));
Ther are other techniques for passing additional parameters into one of the function (the ODE function, Events functions, etc.) that you pass into the ODE solvers. See this documentation page for more information.

4 comentarios

Christo van Rensburg
Christo van Rensburg el 16 de Sept. de 2019
Hi
Cool I understand now, I also changed the ode45 command to the following in a attempt to find where the events occurred:
[time, Y, TE, YE, IE] = ode45(dYdt, tspan, y0, option2);
But I keep getting empty arrays for TE, YE & IE. For me this means that the event doesn't occur?
Thanks
oski89
oski89 el 21 de Nov. de 2019
Sorry for hijacking this thread, but my issue is similar to this question and instead of starting a new post with almost the same question I'll ask mine here...
So, my event function takes "Par" as a parameter, but "Par" is computed by the ode solver. That is, it changes during the solution process and is not defined before calling the ode solver.
Furthermore, I would like to terminate the solution process as soon as "Par" reaches a certain value "Par_stop". "Par_stop" is actually dependent on x = y(1) and is calculated inside the ode function file using the interp1 function as below.
Par_stop is
How can I make this happen using event functions?
I have tried this approach, but it doesn't work.
ode_func.m
% Ode function file
function [dydt, Par, Par_stop] = ode_func(t, y, Par_x, Par_y)
x = y(:, 1);
Par_stop = interp1(Par_x, Par_y, y(1));
end
main.m
% Main file
t_span = [0 1]; i_c = [0 0];
options = odeset('Events', @(t, y) ode_event(y, Par, Par_stop));
[t, Y, te, ye, ie] = ode45(@(t, y) ode_func(t, y.', Par_x, Par_y), t_span, i_c, options);
ode_event.m
% Event file
function [value, isterminal, direction] = ca_ode_event_p_m(t, y, Par, Par_stop)
value = Par_stop - Par;
isterminal = 1;
direction = 0;
end
Steven Lord
Steven Lord el 21 de Nov. de 2019
There's enough differences from the original question (and enough potential complications, like how to handle the ODE solver trying a step that it chooses to reject) that you may want to break this off into a separate question. When you do, I recommend not only showing your code but the underlying differential equations and the problem that you're trying to solve.
Subhadeep Kumar
Subhadeep Kumar el 10 de Dic. de 2019
@oski89 define Par as a global variable. Initialize Par in the main script. That will do the job unless you are using parallel computing for solving your problem. Global variable have its own demerits.

Iniciar sesión para comentar.

Más respuestas (0)

Preguntada:

el 16 de Sept. de 2019

Comentada:

el 10 de Dic. de 2019

Community Treasure Hunt

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

Start Hunting!

Translated by