Is it possible to use structural_parameters as an argument of `System` in ModelingToolkit?

Hello everyone. When building a model in ModelingToolkit, there is the option of doing it with the macro @mtkmodel. Inside the macro, we can define structural parameters for defining numerical variables. For example,

const me = 0.511
@mtkmodel MyModel begin
    @structural_parameters begin
        mass = me
    end
    @variables begin
         y(t)
    end
    @equations begin
        y ~ exp(- 1 / t) * mass
    end
end

Is it possible to do the same with the System constructor? It doesn’t have a structural_parameters keyword argument. From reading the docs, I haven’t found anything else yet.

I’m interested in knowing this because for the equations I need to define, it’s simpler to do so with the System approach. However, such equations depend on some parameters that are not symbolic, just constants, and some fixed matrices.

I think that structural parameters are not stored in System. Eg.

julia> @mtkmodel Foo begin
       @structural_parameters begin
       x
       end
       end;

julia> @named f = Foo(x=3)
Model f:

julia> f.x
ERROR: ArgumentError: System f: variable x does not exist

Have a look at eg.ModelingToolkitStandardLibrary.jl/src/Hydraulic/IsothermalCompressible/components.jl at main · SciML/ModelingToolkitStandardLibrary.jl. The structural parameters like add_inertia are not stored.

You are right, they are not stored. I’ve created two simple examples, one with @mtkmodel

@mtkmodel Foo1 begin
    @structural_parameters begin
        λ = 4.5
    end
    @variables begin
        y(x)
    end
    @equations begin
        y ~ - λ * x
    end
end

@named foo1 = Foo1()

and one with the System constructor

function Foo2(; name)
    λ = 4.5

    vars = @variables begin
        y(x)
    end
    eqs = [
        y ~ - λ * x
    ]

    return System(eqs, x; name = name)
end

foo2 = Foo2(name = :foo2)

In both cases I get the same equation when calling to equations(foo1) or equations(foo2):

1-element Vector{Equation}:
 y(x) ~ -4.5x

I guess what is happening is that @structural_parameters are stored directly in the equations via their numerical variables, and there is no need to store them since they won’t change, they are not symbolic. Does it make sense?

Yeah. In general the point of structural parameters is generally to change the structure (the number of components, the number of variables, the presence of some equations). I don’t see why they couldn’t be stored, though. Would be useful and consistent.

1 Like

Thanks a lot!

They could be stored, but the issue is that they are structural, and so changing them would change the number of equations and such… so remake wouldn’t necessarily be possible on them. So there would need to be other safe-guards and such which make them essentially different from other parameters. I think @cryptic.ax had ideas of saving them though? But it would need to be done right as the naive way would be really buggy.

I see. Knowing that I can use any numerical variable inside the definition of the equations and then pass that to the System constructor is good enough for me. Those variables will not change once the model is built, so there is no problem with that.