Skip to content

Input/Output Functions #362

@FHell

Description

@FHell

It would be very useful to have Input/Output dynamical systems based on ModelingToolkit, we intend to start developing these and use this issue as a place to discuss and gather input on them, and discuss the development. I hope this is appropriate.

The fundamental idea is a slight simplification of the notions of control theory. Every component has input variable, output variables and equations

Inputs = variables whose dynamics are not determined by the component equations
Outputs = variables whose dynamics are determined by the component equations

This is additional information that can not be extracted easily from the equations. In some cases it can be merely convention, which variable we think of as determining the other.

Now we can combine components by identifying outputs and inputs. I imagine a syntax like this, but I haven't prototyped it, so I have no idea whether this is actually a convenient interface in practice:

@variables x(t) y(t) z(t)
@derivatives D'~t

eqs1 = [D(x) ~ σ*(y-x),
       D(z) ~ x*y - β*z]

c1 = IOComponent(Inputs = [y], Outputs = [x, z], equations = eqs1)
c2 = IOComponent(Inputs = [x, z], Outputs = [y], equations = D(y) ~ x*-z)-y )

sys = IOSystem(c1, c2, [c1.x => c2.y,  c1.z => c2.z, c2.y => c1.y])

Trying to build an IOSystem should error when there are open Inputs that do not occur as Outputs (that would mean there are variables with undetermined dynamics). I believe this is straightforward to implement in ModelingToolkit, I simply haven't had the time to digest the internals of MTK enough to just implement it.

An advantage of this is that it should be possible to build complex components from simpler ones iteratively, that you can connect several inputs to an output in a straightforward manner, and that we don't turn an ODE composition into a DAE that we then need to simplify again.

Finally, for us it would be necessary to generate not just complete DEFunctions, but also incomplete IOFunctions with signature f(dx, x, p, t, u), and where u takes the unspecified inputs.


The main use case we have in mind is to use ModelingToolkit in Network Dynamics. We have iterated on the design of ND.jl a number of times now.

The interface we are working on right now (mostly to allow with dealing with different layers, and to make the fusion with MTK more straightforward) is composed of three functions, vertex dynamics, aggregator, edge dynamics. Conceptually they interact like this:

Calculate the state of each edge:

e = edge(v_s, v_d)

(v_s and v_d are the variables at the source and destination of edge e)

Aggregate the edges per vertex:

a_v = aggregate(e_s, e_d)

where e_s and e_d are arrays of edges incident on v (they have v as source or destination respectively). Taken together edge and aggregate define a network layer, that has inputs v and outputs a_v.
Define the dynamics at the vertex

vertex!(dv, v, p, t, a_v)

This has output v and input a_v, thus together with the network layer it defines a complete system.

NB: The current interface of Network Dynamics has aggregate and vertex rolled into one function vertex!(dv, v, e_s, e_d, p, t,). Thus while the above sketched version is already implemented, we want to allow for other types of layers as well. The goal is to multiple different parallel layers, which turned out to be important for our use case. One other use case is to simply pass through input/output variables along directed edges.

Aggregate function will typically be something like sum(e_s) - sum(e_d) or maximum(e_s). This is difficult to express in MTK when I last looked, and this type of terms are contained in all cases we have looked at, limiting the applicability of MTK for us.

The new interface allows a clean use of MTK. We can define vertex and edge as the IOFunctions (or variants thereof) I outlined above, and the aggregate function tells us how edges combine at nodes.


Now in this we don't build one large ODE System and compile it using MTK, but build smaller ones and combine them in a network dynamics object. If there are any suggestions for going the other way, essentially building things like aggregation among varying number of variables into MTK equations, that would be a very interesting alternative design that we would also be happy to invest in. We already saw that this is in some sense possible, you can successfully run modelingtoolkitize on a networkdynamics.jl right hand side function and get an MTK expression for the whole network.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions