-
Notifications
You must be signed in to change notification settings - Fork 19
Description
This feature request is spurred by #52. I won't get to it for a few weeks, but I wanted to get some thoughts down.
Modelica has a new feature related to sampling and synchronous language features:
- http://book.xogeny.com/behavior/discrete/sampling/
- https://github.com/modelica/Modelica_Synchronous
- https://www.modelica.org/documents/ModelicaSpec33.pdf (chapt 16)
Instead of triggering an event, they just stop integration at the given times and update variables as needed. It has a number of advantages over using events.
We could do something similar by collecting a set of times integration stop times and attaching a Discrete input to the samplers. The tricky part might be figuring out how to add that to the model description. The DASSL and Sundials interfaces would need to be reworked to stop at the given times.
From a user interface, here is what it could look like for sampling:
x = Unknown()
d = Discrete()
Equation[
Sample(d, x, 1 // 10) # d is updated with x's value every 0.1 secs
]A more general interface could look like:
z = Unknown()
d = Discrete()
d1 = sampleon(d, z) # sampling
d2 = lift(x -> reinit(z, z + 1), d) # another operation (tricky - might need work)
Equation[
Clock(d, [0.1, 0.3, 0.8, 1.5]) # d is updated with MTime at the given times
]To implement this, define a Clock type. In elaboration.jl, collect all of the Clock instances, and generate an array of Discrete variables paired with event times. Then, create an array of tuples with (time, discretevar). In the simulation, sort the tuples along with the normal time steps. Advance the simulation to the next time step. If the time is associated with a discretevar, then reinit every discretevar associated with that time step.
The d2 = lift() operation above is tricky. We might need something like a ClockEvent() object included in the list of Equations for that sort of operation.