Main Content

odeEvent

ODE event definition

Since R2023b

Description

odeEvent objects define events that the solver detects while solving an ordinary differential equation. An event occurs when one of the event functions you specify crosses zero. You can specify the type of zero crossings to detect and what actions should be performed when an event occurs, including the use of a custom callback function. For example, you can use event functions to detect when an object hits the ground or when a planet completes an orbit.

Create an ode object to represent the ODE problem, and specify an odeEvent object as the value of the EventDefinition property to incorporate event detection into the problem.

Creation

Description

E = odeEvent creates an odeEvent object with empty properties.

E = odeEvent(Name=Value) specifies one or more property values using name-value arguments. For example, E = odeEvent(Direction="ascending") defines an event for ascending zero crossings.

example

Properties

expand all

Event function, specified as a function handle. The event function defines one or more expressions based on the current values of the solution (t,y) or, when EquationType is "fullyimplicit", (t,y,yp) from the solver. The output of the event function can be a scalar (to detect a single event) or a vector (to detect multiple events). An event occurs when the value of one or more of the outputs from the event function crosses zero.

The event function must accept two input arguments for (t,y), such as v = myEvents(t,y), or three input arguments for (t,y,yp), such as v = myEvents(t,y,yp). If the Parameters property of the ode object includes parameters to pass to the event function, then the event function also can accept three or four input arguments to receive the parameter values, v = myEvents(t,y,p) or v = myEvents(t,y,yp,p).

For example, this event function detects events whenever one of the two solution components of an ODE crosses zero.

function v = myEvents(t,y)
  v(1) = y(1);
  v(2) = y(2);
end

Use the Direction property to specify the type of zero crossings to detect. Use the Response property to define how the solver should respond when an event is triggered.

Example: E.EventFcn = @(t,y) y(1) defines an event function that triggers an event whenever the first component of the solution y(1) crosses zero.

Example: E.EventFcn = @myEvents specifies a handle to a function containing the events to detect.

Data Types: function_handle

Direction of zero crossings to detect, specified as a scalar or vector of the values in the table. If you specify a vector of values, then the length of the vector must equal the number of elements in the output from EventFcn.

ValueDescriptionExample Events
"both"All zero crossings of the event function are detected.

Event function plot with two zero crossings.

"ascending"Zero crossings where the event function has a positive slope (integrating forwards in time) are detected.

Event function plot with one zero crossing where the slope is positive.

"descending"Zero crossings where the event function has a negative slope (integrating forwards in time) are detected.

Event function plot with one zero crossing where the slope is negative.

Example: E.Direction = "both" detects all zero crossings of the event function.

Example: Integrating forwards in time, E.Direction = "ascending" detects only zero crossings where the event function is increasing.

Example: E.Direction = ["both" "ascending" "descending"] specifies different zero-crossing directions to detect for each of three outputs from EventFcn.

Solver response to triggered events, specified as a scalar or vector of the values in the table. If you specify a vector of values, then the length of the vector must equal the number of elements in the output from EventFcn.

ValueDescription
"proceed"The solver logs the event and continues integrating.
"stop"The solver logs the event and stops the integration.
"callback"The solver invokes a callback function before logging the event. The function can return up to three outputs to indicate whether to continue or stop the integration, a new value for ye (the solution at the time of the event), or new Parameters to use when restarting the integration from time te (the time of the event). Define the callback function using the CallbackFcn property.

Example: E.Response = "stop" stops the integration if an event is detected.

Example: E.Response = ["proceed" "stop" "callback"] specifies different responses to triggered events for each of three outputs from EventFcn.

Callback function, specified as a function handle. The ODE solver invokes CallbackFcn whenever an event triggers for which the value of Response is "callback".

The callback function can accept up to four inputs and return up to three outputs, but it does not need to accept all of the inputs or supply all of the outputs.

[stop,ye,Parameters] = eventCallback(te,ye,ie,Parameters)

When an event triggers for which the value of Response is "callback", the solver invokes the callback function and supplies information about the current state of the integration as inputs to the callback function:

  • te is the scalar time when the event triggered.

  • ye is the solution vector at the time of the event.

  • ie is the index of the event that triggered, and can be a vector if multiple events trigger at the same time.

  • The Parameters input is the current value of Parameters supplied to ODEFcn (or any other function that accepts the parameters). Unless it is the first callback event, then the current value of Parameters might not be the same as the Parameters property of the ode object. The difference arises because the callback function can change the value of Parameters as events trigger during the integration process.

The callback function can return up to three outputs:

  • stop must be a logical value.

    • If stop is true, then the integration stops at time te.

    • If stop is false, then the integration restarts from time te and proceeds. Use F.SolverOptions.InitialStep to control the size of the initial step when the integration restarts.

  • ye is the new value of the solution vector at time te. Use this output to modify the value of ye supplied to the callback function as an input. This output is useful for modeling discontinuities at unknown points. This change is local to the currently running integration and does not affect the stored InitialTime and InitialValue properties of the ode object.

  • Parameters is the new value of Parameters supplied to ODEFcn (or any other function that accepts the parameters). Use this output to modify the value of Parameters supplied to the callback function as an input. If stop is false and the integration restarts from time te, then the new value of Parameters is supplied to all functions that accept it. This change is local to the currently running integration and does not affect the Parameters property of the ode object.

Example: E.CallbackFcn = @eventCallback specifies a handle to a function named eventCallback as the callback function.

Data Types: function_handle

Examples

collapse all

Consider a ball thrown upward with an initial velocity dy/dt. The ball is subject to acceleration due to gravity aimed downward, so its acceleration is

d2ydt2=-g.

Rewriting the equation as a first-order system of equations with the substitutions y1=y and y2=dydt yields

y1=y2y2=-g.

Solve the equations for the position y1 and velocity y2 of the ball over time.

Define Equations and Initial Conditions

Create a function handle for the first-order system of equations that accepts two inputs for (t,y). Use the value g=9.8 for the acceleration due to gravity.

dydt = @(t,y) [y(2); -9.8];

Next, create a vector with the initial conditions. The ball starts at position y1=3 at t=0 as it is thrown upward with initial velocity y2=20.

y0 = [3 20];

Model Ball Bounces as Events

The ball initially travels upward until the force due to gravity causes it to change direction and head back down to the ground. If you solve the equations without more consideration, then the ball falls back downward forever without striking the ground. Instead, you can use an event function to detect when the position of the ball goes to zero where the ground is located. Because the solution component y1=y is the position of the ball, the event function tracks the value of y1 so that an event triggers whenever y1=0.

Create a function handle for the event function that accepts two inputs for (t,y).

bounceEvent = @(t,y) y(1);

When the ball strikes the ground, its direction changes again as it heads back upwards with a new (smaller) initial velocity. To model this situation, use a callback function along with the event function. When an event triggers, the ODE solver invokes the callback function. The callback function resets the position and initial velocity of the ball so that the integration can restart with the correct initial conditions. When an event occurs, the callback function sets the position y1=0 and attenuates the velocity by a factor of 0.9 while reversing its direction back upward. Define a callback function that performs these actions.

function [stop,y] = bounceResponse(t,y)
stop = false;
y(1) = 0;
y(2) = -0.9*y(2);
end

(The callback function is included as a local function at the end of the example.)

Create an odeEvent object to represent the bouncing ball events. Specify Direction="descending" so that only events where the position is decreasing are detected. Also, specify Response="callback" so that the solver invokes the callback function when an event occurs.

E = odeEvent(EventFcn=bounceEvent, ...
             Direction="descending", ...
             Response="callback", ...
             CallbackFcn=@bounceResponse)
E = 
  odeEvent with properties:

       EventFcn: @(t,y)y(1)
      Direction: descending
       Response: callback
    CallbackFcn: @bounceResponse

Solve Equations

Create an ode object for the problem, specifying the equations dydt, initial conditions y0, and events E as property values.

F = ode(ODEFcn=dydt,InitialValue=y0,EventDefinition=E);

Integrate the equations over the time interval [0 30] by using the solve method. Specify Refine=8 to generate 8 points per step. The resulting object has properties for the time and solution, and because events are being tracked, the object also displays properties related to the events that triggered during the integration.

S = solve(F,0,30,Refine=8)
S = 
  ODEResults with properties:

             Time: [0 0.0038 0.0075 0.0113 0.0151 0.0188 0.0226 0.0264 0.0301 0.0490 0.0678 0.0867 0.1055 0.1243 0.1432 0.1620 0.1809 0.2751 0.3692 0.4634 0.5576 0.6518 0.7460 0.8402 0.9344 1.3094 1.6844 2.0594 2.4344 2.8094 3.1844 ... ] (1x468 double)
         Solution: [2x468 double]
        EventTime: [4.2265 8.1607 11.7015 14.8882 17.7563 20.3375 22.6606 24.7514 26.6331 28.3267 29.8509]
    EventSolution: [2x11 double]
       EventIndex: [1 1 1 1 1 1 1 1 1 1 1]

Plot Results

Plot the position y1 of the ball over time, marking the initial position with a green circle and events with red circles.

plot(S.Time,S.Solution(1,:),"--")
hold on
plot(S.EventTime,S.EventSolution(1,:),"ro")
plot(0,y0(1),"go")
hold off
ylim([0 25])
xlabel("Time")
ylabel("Position y_1")

Figure contains an axes object. The axes object with xlabel Time, ylabel Position y indexOf 1 baseline Position y_1 contains 3 objects of type line. One or more of the lines displays its values using only markers

Local Functions

function [stop,y] = bounceResponse(t,y)
stop = false;
y(1) = 0;
y(2) = -0.9*y(2);
end

Version History

Introduced in R2023b

expand all