Can MTK validate dimensions when using "connect" function?

I’m trying to set up a circulation model with units. Or at least allow consistency checks. So I was playing around with Model Validation and Units · ModelingToolkit.jl and set up the following:

using ModelingToolkit, Unitful

@parameters t [unit = u"s"]

@connector function Pin(; name)
    sts = @variables p(t), [unit = u"Pa"], q(t), [unit = u"m^3 * s^-1", connect = Flow]
    ODESystem(Equation[], t, sts, []; name = name)
end

function Ground(;name, P)
    @named g = Pin()
    ps = @parameters P = P [unit = u"Pa"]
    eqs = [g.p ~ P]
    compose(ODESystem(eqs, t, [], ps; name=name), g)
end

function OnePort(;name)
    @named in = Pin()
    @named out = Pin()
    sts = @variables Δp(t) [unit = u"Pa"] q(t) [unit = u"m^3 * s^-1"]
    eqs = [
           Δp ~ out.p - in.p
           0 ~ in.q + out.q
           q ~ in.q
          ]
    compose(ODESystem(eqs, t, sts, []; name=name), in, out)
end

function Resistor(;name, R)
    @named oneport = OnePort()
    @unpack Δp, q = oneport
    ps = @parameters R [unit = u"Pa * s * m^-3"]
    eqs = [
           Δp ~ - q * R
          ]
    extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end

function Capacitor(;name, C)
    @named oneport = OnePort()
    @unpack Δp, q = oneport
    ps = @parameters C [unit = u"m^3 * Pa^-1"]
    D = Differential(t)
    eqs = [
           D(Δp) ~ - q / C
          ]
    extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end


function ConstantFlow(;name, Q)
    @named oneport = OnePort()
    @unpack q = oneport
    ps = @parameters Q = Q [unit = u"m^3 * s^-1"]
    eqs = [
           q ~ Q
          ]
    extend(ODESystem(eqs, t, [], ps; name=name), oneport)
end


@named source = ConstantFlow(Q = 1u"m^3 * s^-1")
@named R = Resistor(R = 1u"Pa * s * m^-3")
@named C = Capacitor(C = 1u"m^3 * Pa^-1")
@named ground = Ground(P = 0u"Pa")

eqs = [
    connect(source.out, R.in)
    connect(R.out, C.in)
    connect(C.out, ground.g, source.in)
]

@named _model = ODESystem(eqs, t)

Which then fails with the following.

┌ Warning:  in eq. #1left: no method matching get_unit for arguments (Connection,).
└ @ ModelingToolkit ~/.julia/packages/ModelingToolkit/H0KaK/src/systems/validation.jl:144
┌ Warning:  in eq. #1right: no method matching get_unit for arguments (Connection,).
└ @ ModelingToolkit ~/.julia/packages/ModelingToolkit/H0KaK/src/systems/validation.jl:144
┌ Warning:  in eq. #2left: no method matching get_unit for arguments (Connection,).
└ @ ModelingToolkit ~/.julia/packages/ModelingToolkit/H0KaK/src/systems/validation.jl:144
┌ Warning:  in eq. #2right: no method matching get_unit for arguments (Connection,).
└ @ ModelingToolkit ~/.julia/packages/ModelingToolkit/H0KaK/src/systems/validation.jl:144
┌ Warning:  in eq. #3left: no method matching get_unit for arguments (Connection,).
└ @ ModelingToolkit ~/.julia/packages/ModelingToolkit/H0KaK/src/systems/validation.jl:144
┌ Warning:  in eq. #3right: no method matching get_unit for arguments (Connection,).
└ @ ModelingToolkit ~/.julia/packages/ModelingToolkit/H0KaK/src/systems/validation.jl:144

I am known to get my units mangled up, so that’s always an option. But it seems that there is a method missing. So the question is. Is this whole unit business compatible with the way I am using MTK?

The next two lines would be:

@named model = compose(_model, [source, R, C, ground])
sys = structural_simplify(model)

And I did quite expect structural_simplify to fail. This whole exercise was to see if I could get away with it.

So if you can tell me that this does work and I’m just stupid and am making a silly mistake - that would be awesome.

If not, then I’ll forget about units for the time being and get back to modelling :slight_smile:

Can you open an issue?

Done :+1: