# MTK & Standard Library & Analysis points

**URL:** <https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853>\
**Category:** Modelling & Simulations\
**Created:** [October 11, 2023, 1:45pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853 "2023-10-11T13:45:44Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 11, 2023, 1:45pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/1 "2023-10-11T13:45:44Z")

</div>

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…

```julia
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.,

```julia
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:

```julia
 @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:

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

```

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

```julia
states(s2t)

```

responds with  
 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/6/d697eee5fb7a4c579d08d9cb9f2afd6dd765b71a.png)  
If I instead try with:

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

```

I’m told:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/f/7f601f9c1c6c682d54189202b748cbefaf8263d9.png)  
Any tips on where to go from here?]

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2023, 2:18pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/2 "2023-10-11T14:18:55Z")

</div>

> [@BLI](#):
>
> Is the “analysis points” facility part of the _standard library_, or of MTK?

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

> [@BLI](#):
>
> 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?

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

> [@BLI](#):
>
> **Question 1:** Is my understand correct so far, or is it horribly wrong? [If wrong, what is wrong?]

It’s correct

> [@BLI](#):
>
> **Question 2:** If correct so far, what method can I use to linearize the model? Is there some function

You use the function `ModelingToolkit.linearize`, in particular, the last method [documented here](https://docs.sciml.ai/ModelingToolkitStandardLibrary/stable/API/linear_analysis/#ModelingToolkit.linearize)

 ![image](https://global.discourse-cdn.com/julialang/original/3X/d/f/dff63e0fbcfe67f9a3a9c68d6f4d3ff09ac09fb1.png)

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.

> [@BLI](#):
>
> but am told that `tank_2` doesn’t exist.

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

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 11, 2023, 3:00pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/3 "2023-10-11T15:00:40Z")

</div>

> [@baggepinnen](#):
>
> 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.

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

```

gives the following error message:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/e/3e5e7123a4b7ea3b8510f512a10e34ad6baaaa08.png)

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:

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

```

Then it works.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2023, 3:02pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/4 "2023-10-11T15:02:28Z")

</div>

> [@BLI](#):
>
> OK, so I cannot use `@mtkbuild s2t = Sys2Tank_m()` for linearization.

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

Try

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

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 11, 2023, 3:06pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/5 "2023-10-11T15:06:00Z")

</div>

> [@baggepinnen](#):
>
> No, unfortunately not, at least not at the moment.

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?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2023, 3:10pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/6 "2023-10-11T15:10:25Z")

</div>

> [@BLI](#):
>
> 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.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 11, 2023, 3:57pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/7 "2023-10-11T15:57:45Z")

</div>

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

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

```

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [October 11, 2023, 6:00pm UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/8 "2023-10-11T18:00:48Z")

</div>

> [@baggepinnen](#):
>
> By the way, you could have used `csys` in both places as well

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?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [October 12, 2023, 6:15am UTC](https://discourse.julialang.org/t/mtk-standard-library-analysis-points/104853/9 "2023-10-12T06:15:28Z")

</div>

> [@BLI](#):
>
> what would be the order of the inputs and outputs in GUI connectors?

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

> [@BLI](#):
>
> Is there a documentation page on this

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.
