# Mixing time-discrete and time-continuous systems in a simulation

**URL:** https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277
**Category:** Modelling & Simulations
**Tags:** question
**Created:** [January 9, 2022, 11:44am UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277 "2022-01-09T11:44:17Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![tqml](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tqml/32/22710_2.png) [@tqml](https://discourse.julialang.org/u/tqml)
#### Post date: [January 9, 2022, 11:44am UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/1 "2022-01-09T11:44:17Z")

</div>

Hello all!

Does anyone what’s currently the best way in the Julia ecosystem to mix time-continuous and time-discrete systems in one simulation? (e.g. I want to simulate a continuous system regulated by time-discrete controller). I managed to implement it using DifferentialEquations.jl and Callbacks that modify the parameter struct that is passed to the equation.  
However it is not the most efficient way (in terms of implementation effort) and I was wondering if there are better ways to do that.

Thanks in advance!

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 9, 2022, 11:50am UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/2 "2022-01-09T11:50:40Z")

</div>

DiffEq+Callbacks is what it would all lower to. The easier way to do it would be ModelingToolkit.jl, but the capability is still quite fresh and not too documented right now (also still a bit buggy). That will definitely be the future, but I would probably still recommend manual writing of callbacks for now unless you’re looking for an adventure.

---

<div class="post-metadata">

### Author: ![tqml](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tqml/32/22710_2.png) [@tqml](https://discourse.julialang.org/u/tqml)
#### Post date: [January 9, 2022, 12:13pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/3 "2022-01-09T12:13:24Z")

</div>

Thank you for the quick response!

Ah, I’m looking forward when this is implemented in ModelingToolkit; then I can hopefully drop MATLAB/Simulink for good.

---

<div class="post-metadata">

### Author: ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)
#### Post date: [January 9, 2022, 12:35pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/4 "2022-01-09T12:35:52Z")

</div>

Some discussion here [DiffEqs: Hybrid (continuous+discrete) system / periodic callback - #39 by Ronis\_BR](https://discourse.julialang.org/t/diffeqs-hybrid-continuous-discrete-system-periodic-callback/23791/39)

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [January 10, 2022, 12:09pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/5 "2022-01-10T12:09:49Z")

</div>

Hi @tqml !

I wrote two tutorials about how we are doing this:

[https://ronanarraes.com/tutorials/julia/ordinarydiffeq-simulating-continuous-discrete-systems/](https://ronanarraes.com/tutorials/julia/ordinarydiffeq-simulating-continuous-discrete-systems/)

[https://ronanarraes.com/tutorials/julia/extending-ode-solutions-custom-data-arrays/](https://ronanarraes.com/tutorials/julia/extending-ode-solutions-custom-data-arrays/)

This idea is being used in the AOCS simulator of the Amazonia-1, a satellite built by the National Institute of Space Research (INPE). The data obtained after launch showed that the accuracy is superb, and the execution time is amazingly small given how many things are simulated.

---

<div class="post-metadata">

### Author: ![mschauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mschauer/32/13946_2.png) [@mschauer](https://discourse.julialang.org/u/mschauer)
#### Post date: [January 10, 2022, 12:11pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/6 "2022-01-10T12:11:49Z")

</div>

Is it a stochastic or deterministic system?

---

<div class="post-metadata">

### Author: ![tqml](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tqml/32/22710_2.png) [@tqml](https://discourse.julialang.org/u/tqml)
#### Post date: [January 10, 2022, 12:37pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/7 "2022-01-10T12:37:57Z")

</div>

its deterministic

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [January 10, 2022, 1:00pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/8 "2022-01-10T13:00:13Z")

</div>

For each timestep of my discrete controller I run one continues time simulation. See: [https://github.com/ufechner7/KiteViewer/blob/main/src/RTSim.jl](https://github.com/ufechner7/KiteViewer/blob/main/src/RTSim.jl)  
I tried with callbacks, but when I tried that it was way too slow, might be different nowadays…

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 10, 2022, 1:21pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/9 "2022-01-10T13:21:34Z")

</div>

> [@ufechner7](#):
>
> I tried with callbacks, but when I tried that it was way too slow, might be different nowadays…

DiscreteCallbacks should have no overhead in that case. It would be good to get an MWE if that isn’t the case. ContinuousCallbacks on the other hand have a lot more to calculate of course.

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [January 10, 2022, 1:56pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/10 "2022-01-10T13:56:41Z")

</div>

But would you expect any disadvantage of not using callbacks and running

```julia
 step!(integrator, dt, true)

```

on every time step of the discrete controller as I do it?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 10, 2022, 2:00pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/11 "2022-01-10T14:00:35Z")

</div>

The adjoint won’t be defined using the integrator interface, and that won’t compose with automated ensemble parallelism. Otherwise it’s fine.

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [January 11, 2022, 9:52am UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/12 "2022-01-11T09:52:10Z")

</div>

What is the meaning of “adjoint” in this context?

---

<div class="post-metadata">

### Author: ![tqml](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tqml/32/22710_2.png) [@tqml](https://discourse.julialang.org/u/tqml)
#### Post date: [January 11, 2022, 11:10am UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/13 "2022-01-11T11:10:23Z")

</div>

Thanks for the nice examples, they really help!

For now I solved it by modifying the integrator parameter struct, and using it to keep track of the time-discrete control state (which is in turn modified each PeriodicCallback Interval).

Are there any (obvious or non-obvious) problems with this approach, which might lead to wrong results (e.g. like not using `full_cache`)? I currently see a slight discrepancy between the result I get in Simulink and the one I get in Julia (where the Julia solution has more noise/variation around the steady state).

A little bit more details about the problem: The continuous system is actuated via a PWM where the duty cycle is controlled via time-discrete controller. The PWM therefore produces a discontinuity at each iteration and to make sure, that the solver doesn’t skip it, I use a fixed step size of 1/512 of the switching period.

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [January 11, 2022, 12:42pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/14 "2022-01-11T12:42:03Z")

</div>

> [@ufechner7](#):
>
> What is the meaning of “adjoint” in this context?

The continuous adjoint of the ODE, used in reverse mode AD. See

> **[Sensitivity Analysis of Hybrid Differential Equations | FS](https://frankschae.github.io/post/bouncing_ball/)**
>
> In this post, we discuss sensitivity analysis of differential equations with state changes caused by events triggered at defined moments, for example reflections, bounces off a wall or other sudden forces.

It’s always the same adjoint, just used for different things.

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [January 11, 2022, 1:43pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/15 "2022-01-11T13:43:52Z")

</div>

> [@tqml](#):
>
> Are there any (obvious or non-obvious) problems with this approach, which might lead to wrong results (e.g. like not using `full_cache` )? I currently see a slight discrepancy between the result I get in Simulink and the one I get in Julia (where the Julia solution has more noise/variation around the steady state).

This kind of behavior seems more likely related to the solver configurations in Simulink. AFAIK, MATLAB uses by default some automatic algorithm for absolute or relative tolerances. Did you configure MATLAB with the same parameters and solver you used in Julia?

---

<div class="post-metadata">

### Author: ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)
#### Post date: [April 7, 2025, 7:10pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/16 "2025-04-07T19:10:43Z")

</div>

@Ronis_BR the links are dead: could you please bring them back to life? I am trying to solve a similar problem and I could not find other relevant material.

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [April 16, 2025, 10:23pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/17 "2025-04-16T22:23:52Z")

</div>

Hi @mzaffalon !

Sorry for the delay. I removed the tutorials because they use a feature that is now deprecated and I am not sure it is still working.

---

<div class="post-metadata">

### Author: ![mzaffalon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mzaffalon/32/214168_2.png) [@mzaffalon](https://discourse.julialang.org/u/mzaffalon)
#### Post date: [April 17, 2025, 6:07am UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/18 "2025-04-17T06:07:37Z")

</div>

OK, thank you for your reply.  
Would you have a suggestion on how to tackle the problem?

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [April 17, 2025, 6:51am UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/19 "2025-04-17T06:51:22Z")

</div>

What stops you from using the integrator interface?

---

<div class="post-metadata">

### Author: ![Ronis\_BR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ronis_br/32/50999_2.png) [@Ronis\_BR](https://discourse.julialang.org/u/Ronis_BR)
#### Post date: [April 17, 2025, 12:39pm UTC](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277/20 "2025-04-17T12:39:26Z")

</div>

> [@mzaffalon](#):
>
> Would you have a suggestion on how to tackle the problem?

Yes! If you need to simulate a dual system (discrete / continuous), my suggestion is to use the following recipe (we are using this exactly design in our satellite simulator):

1. Identify all the continuous variables and integrate them in the dynamics function.
2. Use discrete callbacks to call the discrete part of the system. Those functions will perform some calculations and save the output inside a mutable variable that must be passed using the parameter argument of the solver.
3. In the dynamics part, use the information in the parameters that were modified inside the callback to modify the continuous part.

So, let’s say you have a system that controls the position of a car. In this system, the acceleration control is performed in a discrete system.

1. The dynamics part will have the integration of the velocity and position using the acceleration value inside the parameter vector.
2. The discrete callback will be called every sampling step. It will read the current position and velocity and obtain the correct acceleration to control the car position.
3. The acceleration computed in the last step will be saved in the parameter vector, which will then be used in the dynamics part.

Please, let me know if you need more details!

[Next page](https://discourse.julialang.org/t/mixing-time-discrete-and-time-continuous-systems-in-a-simulation/74277.md?page=2)
