# Event Handling and Callback Functions

ModelingToolkit provides several ways to represent system events, which enable system state or parameters to be changed when certain conditions are satisfied, or can be used to detect discontinuities. These events are ultimately converted into DifferentialEquations.jl `ContinuousCallback`

s or `DiscreteCallback`

s, or into more specialized callback types from the DiffEqCallbacks.jl library.

`ODESystem`

s and `SDESystem`

s accept keyword arguments `continuous_events`

and `discrete_events`

to symbolically encode continuous or discrete callbacks. `JumpSystem`

s currently support only `discrete_events`

. Continuous events are applied when a given condition becomes zero, with root finding used to determine the time at which a zero crossing occurred. Discrete events are applied when a condition tested after each timestep evalutes to true. See the DifferentialEquations docs for more detail.

Events involve both a *condition* function (for the zero crossing or truth test), and an *affect* function (for determining how to update the system when the event occurs). These can both be specified symbolically, but a more general functional affect representation is also allowed as described below.

## Continuous Events

The basic purely symbolic continuous event interface to encode *one* continuous event is

```
AbstractSystem(eqs, ...; continuous_events::Vector{Equation})
AbstractSystem(eqs, ...; continuous_events::Pair{Vector{Equation}, Vector{Equation}})
```

In the former, equations that evaluate to 0 will represent conditions that should be detected by the integrator, for example to force stepping to times of discontinuities. The latter allow modeling of events that have an effect on the state, where the first entry in the `Pair`

is a vector of equations describing event conditions, and the second vector of equations describe the effect on the state. Each affect equation must be of the form

`single_state_variable ~ expression_involving_any_variables_or_parameters`

or

`single_parameter ~ expression_involving_any_variables_or_parameters`

In this basic interface, multiple variables can be changed in one event, or multiple parameters, but not a mix of parameters and variables. The latter can be handled via more general functional affects.

Finally, multiple events can be encoded via a `Vector{Pair{Vector{Equation}, Vector{Equation}}}`

.

### Example: Friction

The system below illustrates how continuous events can be used to model Coulomb friction

```
using ModelingToolkit, OrdinaryDiffEq, Plots
function UnitMassWithFriction(k; name)
@variables t x(t)=0 v(t)=0
D = Differential(t)
eqs = [
D(x) ~ v
D(v) ~ sin(t) - k*sign(v) # f = ma, sinusoidal force acting on the mass, and Coulomb friction opposing the movement
]
ODESystem(eqs, t; continuous_events=[v ~ 0], name) # when v = 0 there is a discontinuity
end
@named m = UnitMassWithFriction(0.7)
prob = ODEProblem(m, Pair[], (0, 10pi))
sol = solve(prob, Tsit5())
plot(sol)
```