# Acausal modeling with ModelingToolkit.jl: Why does structural\_simplify not eliminate one more variable?

**URL:** <https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474>\
**Category:** Modelling & Simulations\
**Created:** [April 17, 2021, 12:43pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474 "2021-04-17T12:43:34Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![frnkcg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frnkcg/32/24037_2.png) [@frnkcg](https://discourse.julialang.org/u/frnkcg)\
**Post date:** [April 17, 2021, 12:43pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/1 "2021-04-17T12:43:34Z")

</div>

I know a little bit of Modelica so when I recently encountered ModelingToolkit.jl, I was excited to try it out. But I ran into some unexpected problems even for a very simple model.

I created an acausal model of a simple spring-damper system with one mass. At first, I get these 15 equations:

```julia
 0 ~ spring₊flange_a₊f(t) + support₊flange₊f(t)
 support₊flange₊s(t) ~ spring₊flange_a₊s(t)
 0 ~ mass₊flange₊f(t) + spring₊flange_b₊f(t)
 mass₊flange₊s(t) ~ spring₊flange_b₊s(t)
 mass₊a(t) ~ mass₊flange₊f(t)*(mass₊m^-1)
 Differential(t)(mass₊flange₊s(t)) ~ mass₊v(t)
 Differential(t)(mass₊v(t)) ~ mass₊a(t)
 spring₊s_rel(t) ~ spring₊flange_b₊s(t) - spring₊flange_a₊s(t)
 Differential(t)(spring₊s_rel(t)) ~ spring₊v_rel(t)
 spring₊flange_b₊f(t) ~ spring₊f(t)
 spring₊flange_a₊f(t) ~ -spring₊f(t)
 spring₊f_c(t) ~ spring₊c*spring₊s_rel(t)
 spring₊f_d(t) ~ spring₊d*spring₊v_rel(t)
 spring₊f(t) ~ spring₊f_c(t) + spring₊f_d(t)
 support₊flange₊s(t) ~ 0

```

Using structural\_simplify, this is reduced to three equations:

```julia
 Differential(t)(mass₊flange₊s(t)) ~ mass₊v(t)
 Differential(t)(mass₊v(t)) ~ (mass₊m^-1)*(-spring₊c*spring₊s_rel(t) - (spring₊d*mass₊v(t)))
 Differential(t)(spring₊s_rel(t)) ~ mass₊v(t)

```

This confused me. Why is the first equation not eliminated? mass.flange.s is just the same as spring.s\_rel. Is there anything other than structural\_simplify I should use for this? I would appreciate some insight from anybody with more experience in ModelingToolkit.

Also, is there anybody out there who has experience with both ModelingToolkit.jl and TinyModia.jl? They seem to have similar functionality, and TinyModia was created by the same people as Modelica. Which one do you prefer?

---

<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:** [April 17, 2021, 1:13pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/2 "2021-04-17T13:13:12Z")

</div>

> [@frnkcg](#):
>
> This confused me. Why is the first equation not eliminated? mass.flange.s is just the same as spring.s\_rel. Is there anything other than structural\_simplify I should use for this? I would appreciate some insight from anybody with more experience in ModelingToolkit.

`mass₊flange₊s` and `spring₊s_rel` are only the same if you know you have exactly the same initial condition, otherwise the two variables. In theory you could do `mass₊flange₊s ~ spring₊s_rel + (mass₊flange₊s(t0) - spring₊s_rel(t0))` but of course you can see how that’s a bit more than structural (it requires bringing in information about the initial conditions). It could be added in the future, but it’s not a transformation done right now. It would be interesting to track in an issue, but I wouldn’t expect it soon since this probably isn’t going to be the biggest source of performance gains hanging around.

---

<div class="post-metadata">

**Author:** ![frnkcg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frnkcg/32/24037_2.png) [@frnkcg](https://discourse.julialang.org/u/frnkcg)\
**Post date:** [April 17, 2021, 1:26pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/3 "2021-04-17T13:26:17Z")

</div>

You are right, in the final set of equations they are only the same if they have the same initial conditions. But the information that they are the same is also there in the original equations. You can see it better in this order:

```julia
support₊flange₊s(t) ~ 0
support₊flange₊s(t) ~ spring₊flange_a₊s(t)
spring₊s_rel(t) ~ spring₊flange_b₊s(t) - spring₊flange_a₊s(t)
mass₊flange₊s(t) ~ spring₊flange_b₊s(t)

```

structural\_simplify seems to lose this information.

---

<div class="post-metadata">

**Author:** ![YingboMa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yingboma/32/2181_2.png) [@YingboMa](https://discourse.julialang.org/u/YingboMa)\
**Post date:** [April 17, 2021, 4:02pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/4 "2021-04-17T16:02:19Z")

</div>

That’s not structural information.

---

<div class="post-metadata">

**Author:** ![frnkcg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frnkcg/32/24037_2.png) [@frnkcg](https://discourse.julialang.org/u/frnkcg)\
**Post date:** [April 17, 2021, 6:07pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/5 "2021-04-17T18:07:35Z")

</div>

What I am trying to do is obtain a minimal description of the problem with only two states (displacement and velocity of the mass point). Is there a way to do this with ModelingToolkit.jl?

---

<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:** [April 19, 2021, 7:20pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/6 "2021-04-19T19:20:39Z")

</div>

> [@frnkcg](#):
>
> Also, is there anybody out there who has experience with both ModelingToolkit.jl and TinyModia.jl? They seem to have similar functionality, and TinyModia was created by the same people as Modelica. Which one do you prefer?

The following is the reason for ModelingToolkit:

> **[ModelingToolkit, Modelica, and Modia: The Composable Modeling Future in Julia...](https://www.stochasticlifestyle.com/modelingtoolkit-modelica-and-modia-the-composable-modeling-future-in-julia/)**
>
> Let me take a bit of time here to write out a complete canonical answer to ModelingToolkit and how it relates to Modia and Modelica. This question comes up a lot: why does ModelingToolkit exist instead of building on tooling for Modelica compilers?...

---

<div class="post-metadata">

**Author:** ![Sciemon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sciemon/32/20897_2.png) [@Sciemon](https://discourse.julialang.org/u/Sciemon)\
**Post date:** [April 19, 2021, 8:10pm UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/7 "2021-04-19T20:10:20Z")

</div>

“…there are a lot of models already written in Modelica, and it would be a shame for us to not be able to connect with that ecosystem. I will hint that there is coming tooling as part of [JuliaSim](https://juliacomputing.com/products/juliasim/) for connecting to many pre-existing model libraries. In addition, we hope to make use of tooling like [Modia.jl](https://github.com/ModiaSim/Modia.jl) and [TinyModia.jl](https://github.com/ModiaSim/TinyModia.jl) will help us make a bridge.”  
 → Interesting 😀

---

<div class="post-metadata">

**Author:** ![YingboMa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yingboma/32/2181_2.png) [@YingboMa](https://discourse.julialang.org/u/YingboMa)\
**Post date:** [April 22, 2021, 12:12am UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/8 "2021-04-22T00:12:55Z")

</div>

We need more passes to simply differential equations. It should be fairly simple to write those transformations. Do you want to give that a try? We have been focusing on solving algebraic equations.

That said, solving for a minimal description of the problem is already NP-hard for algebraic equations on the structural level. I assume you mean a reasonably simplified description of the system.

---

<div class="post-metadata">

**Author:** ![frnkcg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frnkcg/32/24037_2.png) [@frnkcg](https://discourse.julialang.org/u/frnkcg)\
**Post date:** [April 24, 2021, 6:29am UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/9 "2021-04-24T06:29:29Z")

</div>

Great article. The possibility for federated modular development is one of the amazing features of Julia. A bridge to the Modelica community would definitely be a good thing.

---

<div class="post-metadata">

**Author:** ![frnkcg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frnkcg/32/24037_2.png) [@frnkcg](https://discourse.julialang.org/u/frnkcg)\
**Post date:** [April 24, 2021, 7:09am UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/10 "2021-04-24T07:09:02Z")

</div>

So far I’ve only dipped my toes into ModelingToolkit a little bit. I’ll keep playing with it. Hopefully one day I’ll understand it enough to contribute. Yeah, I guess a reasonably simplified description of the system is a good way of putting it.

My knowledge of multibody systems is somewhat rusty, I seem to remember that it is usually straightforward to express them in minimal coordinates as long as there are no kinematic loops. In the current example it’s certainly easy to see what the minimal coordinates should be just by inspection.

---

<div class="post-metadata">

**Author:** ![YingboMa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yingboma/32/2181_2.png) [@YingboMa](https://discourse.julialang.org/u/YingboMa)\
**Post date:** [April 25, 2021, 5:28am UTC](https://discourse.julialang.org/t/acausal-modeling-with-modelingtoolkit-jl-why-does-structural-simplify-not-eliminate-one-more-variable/59474/11 "2021-04-25T05:28:07Z")

</div>

If you have some Julia development experience and want to dive into MTK to write a simple pass that simplifies identical differential variables and differential equations, I’d be happy to give you a few pointers. You don’t really need to know multi-body systems. MTK analyzes systems structurally and doesn’t try to decipher the physics at all.
