2

I want two limitations to my ode45 calculation of a movement equation: position and time. I have already got the time event to work but I am not sure if and how I can add another event for limiting the position. EDIT: I also have many different particles coupled together in one ODE equation and need them to stop individually once they reach a 'roof' as they all travel at different speeds... would I be able to achieve this through events? I have an idea on how I would do this but its very complicated and would probably be very slow...

horchler
  • 18,384
  • 4
  • 37
  • 73
user1878019
  • 65
  • 1
  • 6
  • 1
    Not sure what your question is. You implemented an event with odeset to limit the time? You can also check for the position in this same event function? – mmumboss Dec 07 '12 at 13:04
  • What do you mean by an event? Can't you just use some 'if's in the function you are integrating? – julietKiloRomeo Dec 13 '12 at 12:01
  • 1
    @julietKiloRomeo: `if` statements in the integration function are usually a bad idea. First, they can slow things down -from both a basic computer science perspective (branching) and because they can make the system ODEs "stiffer" and thus will result in more failed steps and smaller step sizes from the adaptive algorithm. Second, you can't force the solver to hit specific point in time or point in solution space via the integration function. You can only do this with events. If you don't care about exact points, then use the `>` and `<` logical operators in your ODEs. – horchler May 22 '13 at 14:22

1 Answers1

0

I'm not sure if you can do exactly what you want, but it is possible to do quite a lot with events. First, this sounds like some sort of numerical calculation of first passage time (a.k.a. first hitting time). If these "particles" are stochastic, stop and don't use ode45 but instead use a pmethod appropriate for SDEs.

As far as I know there is no limit on how many event functions you can have - or rather the dimension of the event function (similar to the dimension of your ODE function) - and their number is not tied to how many ODE equations you have. The events function receives both the current time and the current state vector. You can use any or all of the elements of those to create each event. You are correct that more events functions and more complex events will slow down integration. The performance also depends on how often events are detected. If each of your particles reaches the "roof," as you call it, and triggers just a single event then that won't be too bad.

In terms of implementation, here a simple example based on Matlab's ballode example, that simulates N ballistic particles in the vertical axis alone. There are N non-terminating events to catch the time and speed of each particle as it passes through y = 0. One additional terminating event is added to check if all of the particles have passed through y = 0 (if we knew which particle this would be, as we do here, we could just make that event a terminating one).

function eventsdemo

% Initial conditions for n balls
n = 10;
y0(2*n,1) = 0;
y0(n+1:end) = linspace(20,40,n);

% Specify events function
options = odeset('Events',@(t,y)efun(t,y,n));

% Integrate
[t,y,te,ye,ie] = ode45(@(t,y)f(t,y,n),[0 10],y0,options);

figure;
plot(t,y(:,1:n),'b',te(1:n),ye(sub2ind(size(ye),ie(1:n),(1:n).')),'r.');

function dydt = f(t,y,n)
% Differential equations for ballistic motion
dydt = [y(n+1:end);zeros(n,1)-9.8];

function [value,isterminal,direction] = efun(t,y,n)
% Last event checks that all balls have hit ground and terminates integration
yn = y(1:n);
value = [yn;all(yn < 0)];
zn = zeros(n,1);
isterminal = [zn;1];
direction = [zn-1;1];

In some ways this is slightly inefficient because we keep simulating all N systems even after some of them have passed through y = 0. However, it is simple and the output arrays are rectangular rather than ragged.

I'm not clear what you mean precisely by "coupled together" and needing the particles to "stop." If you need to do more than just record the event data, such as change system parameters or change the differential equation(s) in some other way, then you'll need to terminate after each event and restart the integration. Look at the ballode example (type edit ballode in the Matlab command window) to see some suggestions on to make this a bit more efficient.

horchler
  • 18,384
  • 4
  • 37
  • 73