hexaeder/BlockSystems.jl

Derivatives of Inputs are removed when not used as an Output

AnnaBuettner opened this issue · 0 comments

Hey,

When I calculate the derivative of an input i(t) BlockSystem automatically reduces the derivative idi(t). I think we should have a look at this! I have set up an MWE, which simply contains a block that squares the input and a derivative block:

using Pkg
Pkg.activate(@__DIR__)

using ModelingToolkit
using BlockSystems

@parameters t
dt = Differential(t)

@parameters x(t) i(t)
@variables x2(t) o(t) ii(t) idi(t)

square_block = IOBlock([x2 ~ x^2], [x], [x2], name = :square_block) 
derivative_block = IOBlock([o ~ idi, ii ~ i, dt(ii) ~ idi], [i], [o, idi, ii], name = :derivative_block)

test = IOSystem([square_block.x2 => derivative_block.i], 
                [square_block, derivative_block],
                outputs=[derivative_block.o], 
                name = :test)

connect_system(test, verbose=true)

This results in the following error. The internal states are incorrectly reduced which you can quickly see in the debugger.

ERROR: ArgumentError: inputs must be parameters
  (Set(inputs) ⊆ Set(parameters(odes))) == false
   ├ (Set(inputs)) = Set(Term{Real, Base.ImmutableDict{DataType, Any}}[x(t)])
   └ (Set(parameters(odes))) = Set{Any}()

But there is a workaround by explicitly using the derivative idi(t) and the internal state ii(t) so that it is not reduced. It works but becomes very messy once the IOSystem becomes bigger!

test = IOSystem([square_block.x2 => derivative_block.i], 
                [square_block, derivative_block],
                outputs=[derivative_block.o, derivative_block.idi, derivative_block.ii], 
                name = :test)