MTK & units: how to specify unit for time?

I’ve started to experiments with units for models. My question is probably related to how I can specify units for time when I do:

using ModelingToolkit: t_nounits as t, D_nounits as Dt
  • How can I specify unit for t so that this unit is also used in possible components from, e.g., ModelingToolkitStandardLibrary?
  • How can I ensure that the same time unit is used for the time derivative Dt?

More concretely – consider the following case:

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as Dt
using DynamicQuantities
using OrdinaryDiffEq: solve
#
@mtkmodel Pendulum_8 begin
    @constants begin
        g = 9.81,   [unit = u"m/s^2", description = "Gravity"]
    end
    @parameters begin
        ℓ = 2,      [unit = u"m", description = "Pendulum length"]
    end
    @variables begin
        θ(t) = 1,   [unit=u"rad", description="Angle"]
        ω(t) = 1,   [unit=u"rad/s", description="Angular velocity"]
    end
    @equations begin
        Dt(θ) ~ ω
        Dt(ω) ~ -g/ℓ*sin(θ)
    end
end
#
@mtkbuild pen_8 = Pendulum_8()

This gives warnings on:

  • eq.#1: units [1.0] for lhs, units [1.0/s] for rhs
  • eq.#2: units [1.0/s] for lhs, units [1/s^2] for rhs.

This must be related to no unit defined for time.

Question: how do I define unit for time when I import time etc. from ModelingToolkit.jl as in

using ModelingToolkit: t_nounits as t, D_nounits as Dt

?
There is an example in the documentation:

@independent_variables t [unit = u"ms"]

but this example is for a case where time and derivative are not imported from ModelingToolkit…

There are also options with units you can import:

So using ModelingToolkit: t_unitful as t or using ModelingToolkit: t might do the trick depending on your unit package. Analogous for D.

1 Like

This partially solved my problem. Now, I do:

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as Dt
using ModelingToolkit: t as tu, D as Dtu
using DynamicQuantities

I import both nounits and DynamicQuantities versions, and simply give different names to the two cases. This allows me to have models without and with units in the same file…

So, now:

@mtkmodel Pendulum_8 begin
    @constants begin
        g = 9.81,   [unit = u"m/s^2", description = "Gravity"]
    end
    @parameters begin
        ℓ = 2,      [unit = u"m", description = "Pendulum length"]
    end
    @variables begin
        θ(t) = 1,   [unit=u"rad", description="Angle"]
        ω(t) = 1,   [unit=u"rad/s", description="Angular velocity"]
    end
    @equations begin
        Dtu(θ) ~ ω
        Dtu(ω) ~ -g/ℓ*sin(θ)
    end
end

@mtkbuild pen_8 = Pendulum_8()

builds the model, and there is no warning wrt. units. NOTE: if I use time variable name tu in the variable definition, e.g., θ(tu) = 1, ..., I get an error message when I apply @mtkbuild.

HOWEVER, if I explicitly validate the model, the “old” warnings reappear…???

julia> ModelingToolkit.validate(equations(pen_8))
Warning:  in eq. #1: units [1.0 ] for left and [1.0 s⁻¹] for right do not match.
└ @ ModelingToolkit C:\Users\Bernt_Lie\.julia\packages\ModelingToolkit\OYoU3\src\systems\unit_check.jl:209
┌ Warning:  in eq. #2: units [1.0 s⁻¹] for left and [1.0 s⁻²] for right do not match.
└ @ ModelingToolkit C:\Users\Bernt_Lie\.julia\packages\ModelingToolkit\OYoU3\src\systems\unit_check.jl:209

NOTE: if I only import the DynamicQuantities version, validate works.