# Structural\_simplify fails if differential term is on the Right Hand Side of an equation

**URL:** <https://discourse.julialang.org/t/structural-simplify-fails-if-differential-term-is-on-the-right-hand-side-of-an-equation/69302>\
**Category:** Modelling & Simulations\
**Tags:** modelingtoolkit\
**Created:** [October 6, 2021, 12:46pm UTC](https://discourse.julialang.org/t/structural-simplify-fails-if-differential-term-is-on-the-right-hand-side-of-an-equation/69302 "2021-10-06T12:46:58Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![SCher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scher/32/20477_2.png) [@SCher](https://discourse.julialang.org/u/SCher)\
**Post date:** [October 6, 2021, 12:46pm UTC](https://discourse.julialang.org/t/structural-simplify-fails-if-differential-term-is-on-the-right-hand-side-of-an-equation/69302/1 "2021-10-06T12:46:58Z")

</div>

I am working on ModelingToolkit.jl using the RC circuit example at [https://mtk.sciml.ai/stable/tutorials/acausal\_components/](https://mtk.sciml.ai/stable/tutorials/acausal_components/). It appears that as long as the Differential(t) terms in the equations are on the Left Hand Side, things work as expected. However, when the left and right hand sides of an equation are swapped (with no other changes), there is some trouble with finding the right state variables after alias elimination. Details are provided below:

I started with the flattened system of 20 equations and 20 variables:

```julia
 eqs = [0 ~ resistor₊p₊i + source₊p₊i,
 source₊p₊v ~ resistor₊p₊v,
 0 ~ capacitor₊p₊i + resistor₊n₊i,
 resistor₊n₊v ~ capacitor₊p₊v,
 0 ~ capacitor₊n₊i + ground₊g₊i + source₊n₊i,
 capacitor₊n₊v ~ source₊n₊v,
 source₊n₊v ~ ground₊g₊v,
 resistor₊v ~ resistor₊p₊v - resistor₊n₊v,
 0 ~ resistor₊n₊i + resistor₊p₊i,
 resistor₊i ~ resistor₊p₊i,
 resistor₊v ~ resistorR*resistor₊i,
 capacitor₊v ~ capacitor₊p₊v - capacitor₊n₊v,
 0 ~ capacitor₊n₊i + capacitor₊p₊i,
 capacitor₊i ~ capacitor₊p₊i,
 Differential(t)(capacitor₊v) ~ capacitor₊i*(capacitorC^-1),
 source₊v ~ source₊p₊v - source₊n₊v,
 0 ~ source₊n₊i + source₊p₊i,
 source₊i ~ source₊p₊i,
 sourceV ~ source₊v,
 ground₊g₊v ~ 0]

```

I created an ODESystem:

> @named rc\_model = ODESystem(eqs,t)

I did alias elimination on the system:

> sys\_alias = alias\_elimination(rc\_model)

```julia
Differential(t)(capacitor₊v(t)) ~ resistor₊i(t) / capacitorC
0 ~ source₊v(t) - capacitor₊v(t) - resistor₊v(t)
0 ~ resistorR*resistor₊i(t) - resistor₊v(t)
0 ~ source₊v(t) - sourceV

```

Following are the state variables after alias elimination:

> states(sys\_alias)

```julia
 capacitor₊v(t)
 resistor₊v(t)
 resistor₊i(t)
 source₊v(t)

```

I then performed structural simplification on the system:

> sys = structural\_simplify(rc\_model)

Following are now the equations:

```julia
Differential(t)(capacitor₊v(t)) ~ resistor₊i(t) / capacitorC
0 ~ resistorR*resistor₊i(t) + capacitor₊v(t) - sourceV

```

And the states are:

> states(sys)

```julia
 capacitor₊v(t)
 resistor₊i(t)

```

So far everything as worked perfectly and as expected.

Now observe what happens when I swap the left and right sides of the differential equation, all other equations remaining exactly the same as before:

> capacitor₊i\*(capacitorC^-1) ~ Differential(t)(capacitor₊v)

Here is the full equation set:

```julia
eqs2 = [0 ~ resistor₊p₊i + source₊p₊i,
 source₊p₊v ~ resistor₊p₊v,
 0 ~ capacitor₊p₊i + resistor₊n₊i,
 resistor₊n₊v ~ capacitor₊p₊v,
 0 ~ capacitor₊n₊i + ground₊g₊i + source₊n₊i,
 capacitor₊n₊v ~ source₊n₊v,
 source₊n₊v ~ ground₊g₊v,
 resistor₊v ~ resistor₊p₊v - resistor₊n₊v,
 0 ~ resistor₊n₊i + resistor₊p₊i,
 resistor₊i ~ resistor₊p₊i,
 resistor₊v ~ resistorR*resistor₊i,
 capacitor₊v ~ capacitor₊p₊v - capacitor₊n₊v,
 0 ~ capacitor₊n₊i + capacitor₊p₊i,
 capacitor₊i ~ capacitor₊p₊i,
 capacitor₊i*(capacitorC^-1) ~ Differential(t)(capacitor₊v),
 source₊v ~ source₊p₊v - source₊n₊v,
 0 ~ source₊n₊i + source₊p₊i,
 source₊i ~ source₊p₊i,
 sourceV ~ source₊v,
 ground₊g₊v ~ 0]

```

I created another model with this equation set:

> @named rc\_model2 = ODESystem(eqs2,t)

Now I perform alias elimination:

> sys2\_alias = alias\_elimination(rc\_model2)

Here are the resulting equations:

```julia
0 ~ source₊v(t) - capacitor₊v(t) - resistor₊v(t)
0 ~ resistorR*resistor₊i(t) - resistor₊v(t)
capacitor₊i(t) / capacitorC ~ Differential(t)(capacitor₊v(t))
0 ~ source₊v(t) - sourceV

```

And here are the states:

> states(sys2\_alias)

```julia
 capacitor₊v(t)
 resistor₊v(t)
 resistor₊i(t)
 source₊v(t)

```

Observe how there are only four state variables identified, however there is one more variable in the equations , `capacitor₊i(t)`.

Now when I perform structural simplification, it throws an error:

> structural\_simplify(sys2\_alias)

```julia
ExtraVariablesSystemException: The system is unbalanced. There are 5 highest order derivative variables and 4 equations.
More variables than equations, here are the potential extra variable(s):
 capacitor₊v(t)
 capacitor₊i(t)

Stacktrace:
 [1] error_reporting(sys::ODESystem, bad_idxs::Vector{Int64}, n_highest_vars::Int64, iseqs::Bool)
   @ ModelingToolkit.StructuralTransformations C:\Users\Sushil\.julia\packages\ModelingToolkit\eSpDL\src\structural_transformation\utils.jl:72
 [2] check_consistency(sys::ODESystem)
   @ ModelingToolkit.StructuralTransformations C:\Users\Sushil\.julia\packages\ModelingToolkit\eSpDL\src\structural_transformation\utils.jl:103
 [3] structural_simplify(sys::ODESystem; simplify::Bool)
   @ ModelingToolkit C:\Users\Sushil\.julia\packages\ModelingToolkit\eSpDL\src\systems\abstractsystem.jl:815
 [4] structural_simplify(sys::ODESystem)
   @ ModelingToolkit C:\Users\Sushil\.julia\packages\ModelingToolkit\eSpDL\src\systems\abstractsystem.jl:814
 [5] top-level scope
   @ In[82]:1
 [6] eval
   @ .\boot.jl:360 [inlined]
 [7] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
   @ Base .\loading.jl:1116

```

The variables `resistor₊i(t)` and `capacitor₊i(t) ` are redundant. If I manually replace one of these variables with the other, then it works - there are 4 equations and 4 variables.

So the question is: why does alias\_elimination not correctly identify the state variables when the Differential(t) term is on the right side? Am I missing something?

Thanks for any feedback and comments in resolving this puzzle. ModelingToolkit.jl is a great package and so far it has been of great help in my work.

Below is the full code which throws error:

```julia
using ModelingToolkit

@parameters t resistorR capacitorC sourceV
@variables resistor₊p₊i(t) source₊p₊i(t) source₊p₊v(t) resistor₊p₊v(t) capacitor₊p₊i(t) resistor₊n₊i(t)
@variables resistor₊n₊v(t) capacitor₊p₊v(t) capacitor₊n₊i(t) ground₊g₊i(t) source₊n₊i(t) source₊v(t) source₊i(t)
@variables capacitor₊n₊v(t) source₊n₊v(t) ground₊g₊v(t) resistor₊v(t) resistor₊i(t) capacitor₊v(t) capacitor₊i(t)

eqs2 = [0 ~ resistor₊p₊i + source₊p₊i,
 source₊p₊v ~ resistor₊p₊v,
 0 ~ capacitor₊p₊i + resistor₊n₊i,
 resistor₊n₊v ~ capacitor₊p₊v,
 0 ~ capacitor₊n₊i + ground₊g₊i + source₊n₊i,
 capacitor₊n₊v ~ source₊n₊v,
 source₊n₊v ~ ground₊g₊v,
 resistor₊v ~ resistor₊p₊v - resistor₊n₊v,
 0 ~ resistor₊n₊i + resistor₊p₊i,
 resistor₊i ~ resistor₊p₊i,
 resistor₊v ~ resistorR*resistor₊i,
 capacitor₊v ~ capacitor₊p₊v - capacitor₊n₊v,
 0 ~ capacitor₊n₊i + capacitor₊p₊i,
 capacitor₊i ~ capacitor₊p₊i,
 capacitor₊i*(capacitorC^-1) ~ Differential(t)(capacitor₊v),
 source₊v ~ source₊p₊v - source₊n₊v,
 0 ~ source₊n₊i + source₊p₊i,
 source₊i ~ source₊p₊i,
 sourceV ~ source₊v,
 ground₊g₊v ~ 0]

@named rc_model2 = ODESystem(eqs2,t)

sys2_alias = alias_elimination(rc_model2)

structural_simplify(sys2_alias)

```

---

<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:** [October 6, 2021, 5:25pm UTC](https://discourse.julialang.org/t/structural-simplify-fails-if-differential-term-is-on-the-right-hand-side-of-an-equation/69302/2 "2021-10-06T17:25:42Z")

</div>

It’s a known issue. I even had a PR: [https://github.com/SciML/ModelingToolkit.jl/pull/1164](https://github.com/SciML/ModelingToolkit.jl/pull/1164) but @YingboMa had a better solution. He just needs to implement it 😅 . Hopefully it’s done in the next month.

---

<div class="post-metadata">

**Author:** ![SCher](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/scher/32/20477_2.png) [@SCher](https://discourse.julialang.org/u/SCher)\
**Post date:** [October 7, 2021, 8:58am UTC](https://discourse.julialang.org/t/structural-simplify-fails-if-differential-term-is-on-the-right-hand-side-of-an-equation/69302/3 "2021-10-07T08:58:07Z")

</div>

Thanks for the info.
