Acausal modeling with ModelingToolkit.jl: Why does structural_simplify not eliminate one more variable?

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:

 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:

 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?

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.

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:

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.

That’s not structural information.

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?

The following is the reason for ModelingToolkit:

1 Like

“…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 for connecting to many pre-existing model libraries. In addition, we hope to make use of tooling like Modia.jl and TinyModia.jl will help us make a bridge.”
→ Interesting :grinning:

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.

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.

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.

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.