# MTK & Standard Library & Analysis points

I’m trying to figure out how to define “analysis points” in my MTK models, and how to use such to linearize the model.

Initial questions:

• Is the “analysis points” facility part of the standard library, or of MTK?
• It seems like “analysis points” can be inserted in between two causal blocks. I assume this means that one can use blocks from the standard library to do this?

Here is what I have tried…

``````using ModelingToolkit, ModelingToolkitStandardLibrary.Blocks
using DifferentialEquations

@variables t
Dt = Differential(t)

@mtkmodel Tank_m begin
# Model parameters
@parameters begin
ρ=1,    [description = "Liquid density"]
A=5,    [description = "Cross sectional tank area"]
K=5,    [description = "Effluent valve constant"]
h_ς=3,  [description = "Scaling level in valve model"]
end
# Model variables, with initial values needed
@variables begin
m(t)=1.5*ρ*A,   [description = "Liquid mass"]
# ṁ_i(t),         [description = "Influent mass flow rate"]
ṁ_e(t),         [description = "Effluent mass flow rate"]
V(t),           [description = "Liquid volume"]
h(t),           [description = "level"]
end
# Components from ModelingToolkitStandardLibrary
@components begin
# We move ṁ_i from "variables" to "components"
ṁ_i = RealInput()   # Influent mass flow rate
y_ṁ_e = RealOutput()
end
# Providing model equations
@equations begin
Dt(m) ~ ṁ_i.u - ṁ_e
m ~ ρ*V
V ~ A*h
ṁ_e ~ K*sqrt(h/h_ς)
y_ṁ_e.u ~ ṁ_e
end
end

@mtkmodel Sys2Tank_m begin
# Components used
@components begin
ṁ = Constant(k=2)
tank_1 = Tank_m()
tank_2 = Tank_m()
end
# Equations for connecting components
@equations begin
connect(ṁ.output, :u1, tank_1.ṁ_i)
connect(tank_1.y_ṁ_e, :u2, tank_2.ṁ_i)
end
end

@mtkbuild s2t = Sys2Tank_m()
``````

This code works for standard simulation, e.g.,

``````tspan = (0,10)
prob = ODEProblem(s2t,[],tspan)
sol = solve(prob)
``````

My attempt of “analysis points” is `:u1` and `:u2` inserted in the `@equations` block of the `Sys2Tank_m` model/connect statements.

I have then assumed that…

• Specifying `ṁ = Constant(k=2)` in the `Sys2Tank_m` model qualifies as making `ṁ` output from a causal block (i.e., from `Constant`).
• Specifying `ṁ_i = RealInput()` in the `Tank_m` model qualifies as making `Tank_m` a “causal block” with `ṁ_i ` as input.

In other words, that it is correct to define `:u1` and `:u2` as analysis points via the statements:

`````` @equations begin
connect(ṁ.output, :u1, tank_1.ṁ_i)
connect(tank_1.y_ṁ_e, :u2, tank_2.ṁ_i)
end
``````

Question 1: Is my understand correct so far, or is it horribly wrong? [If wrong, what is wrong?]

Question 2: If correct so far, what method can I use to linearize the model? Is there some function `linearize` in `ModelingToolkit` or `ControlSystems` or `ControlSystemsMTK`, etc. that can be used?

[I tried with:

``````linsys = linearize(s2t, :u1, tank_2.m)
``````

but am told that `tank_2` doesn’t exist. Still:

``````states(s2t)
``````

responds with

``````linsys = linearize(s2t, :u1, s2t.tank_2.m)
``````

I’m told:

Any tips on where to go from here?]

The standard library, you can only find this in the documentation of the stdlib and not the documentation of MTK?

Yes, the analysis points relies on you placing them between connectors of type `RealOutput` and `RealInput`

It’s correct

You use the function `ModelingToolkit.linearize`, in particular, the last method documented here

In ControlSystemsMTK, there’s a function called `named_ss` which does the same thing, but returns a linear statespace system from ControlSystemsBase with signal names attached, rather than returning the matrices alone like `linearize` does.

That’s probably a namespacing problem. All linearization functions expect the non-simplified system.

OK, so I cannot use `@mtkbuild s2t = Sys2Tank_m()` for linearization.

Instead, I try the following, where both `sys` below and `csys` should be non-simplified.

``````using ControlSystemsMTK
@named sys = Sys2Tank_m()
csys = complete(sys)
named_ss(sys, :u2, csys.tank_2.m)
``````

gives the following error message:

If I use (MTK) `linearize` instead, i.e., `linearize(sys,:u2, csys.tank_2.m)`, I get exactly the same error message.

Ah… found the error. I need to use:

``````named_ss(sys, :u2, [csys.tank_2.m])
``````

Then it works.

No, unfortunately not, at least not at the moment.

Try

``````named_ss(sys, :u2, [csys.tank_2.m])
``````
1 Like

It is not quite clear to me why I need to distinguish between `sys` and `csys` in the calling of `named_ss`, etc.

• Is there a reason for this?

It’s related to the namespacing issue that `@mtkbuild` was supposed to solve, but `@mtkbuild` currently doesn’t take functions that perform custom simplification (i.e., require an unsimplified system as input) into account, and the user thus has to deal with the namespacing issue for those functions until we have a better solution. `complete` makes it so that `sys.x` produces a symbol `x` instead of a symbol namespaced like `sys.x`, and MTK requires the `x` version rather than the `sys.x` version.

By the way, you could have used `csys` in both places as well

``````named_ss(csys, :u2, [csys.tank_2.m])
``````
1 Like

Great to know.

One more thing: I assume that in a “library perspective”, my model `Tank_m` above would be a unit in a library, while `Sys2Tank_m` could be automatically generated using a GUI tool, where I drag the “components” of `Sys2Tank_m` [two instances of `Tank_m` and one instance of a `Constant` source] onto the palette, and connect them by drawing lines between the blocks [thereby producing the `connect` statements].

If so – if I have a “vector” of inputs and outputs from a model (a la `Tank_m` with `RealInput` and `RealOutput` instantiations), what would be the order of the inputs and outputs in GUI connectors? Would it be the order in which they are listed in the `@component` part of `Tank_m`? I mean, in the case that I have more than one `RealInput` and `RealOutput` in a model? [I guess MTK SL comes with some standard descriptors a la “Flow”, etc…] Is there a documentation page on this that is valid for the new `@mtkmodel` macro style?

Configurable. The GUI aspects are still under active development so I cannot quite answer exactly how this will look and feel yet.

I’m not quite sure what “this” refers to here. There are several connectors in MTKstdlib, usually at least one for each submodule. For example, `Mechanical.Rotational.Flange` is the fundamental connector in the Rotational mechanics module. “Flow” is a property of a variable in a connector, it’s not a connector by itself. The current in an electrical pin connector has the property “flow”, so does the `dm` variable (mass flow) in the `HydraulicPort` connector in the Hydraulic submodule.

1 Like