Skip to content

Commit 1f07daa

Browse files
committed
feat: adds @structural_parameters to @mtkmodel
- This will allow to provide arguments that aren't parameters/variables like int, function... - Adds tests for the same
1 parent 0076490 commit 1f07daa

File tree

2 files changed

+43
-15
lines changed

2 files changed

+43
-15
lines changed

src/systems/model_parsing.jl

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,13 @@ function _model_macro(mod, name, expr, isconnector)
2222
ext = Ref{Any}(nothing)
2323
eqs = Expr[]
2424
icon = Ref{Union{String, URI}}()
25-
vs = []
26-
ps = []
27-
kwargs = []
25+
kwargs, ps, sps, vs, = [], [], [], []
2826

2927
for arg in expr.args
3028
arg isa LineNumberNode && continue
3129
if arg.head == :macrocall
3230
parse_model!(exprs.args, comps, ext, eqs, icon, vs, ps,
33-
dict, mod, arg, kwargs)
31+
sps, dict, mod, arg, kwargs)
3432
elseif arg.head == :block
3533
push!(exprs.args, arg)
3634
elseif isconnector
@@ -213,8 +211,8 @@ function get_var(mod::Module, b)
213211
end
214212
end
215213

216-
function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, dict,
217-
mod, arg, kwargs)
214+
function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps,
215+
dict, mod, arg, kwargs)
218216
mname = arg.args[1]
219217
body = arg.args[end]
220218
if mname == Symbol("@components")
@@ -225,6 +223,8 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, dict,
225223
parse_variables!(exprs, vs, dict, mod, body, :variables, kwargs)
226224
elseif mname == Symbol("@parameters")
227225
parse_variables!(exprs, ps, dict, mod, body, :parameters, kwargs)
226+
elseif mname == Symbol("@structural_parameters")
227+
parse_structural_parameters!(exprs, sps, dict, mod, body, kwargs)
228228
elseif mname == Symbol("@equations")
229229
parse_equations!(exprs, eqs, dict, body)
230230
elseif mname == Symbol("@icon")
@@ -234,6 +234,24 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, dict,
234234
end
235235
end
236236

237+
function parse_structural_parameters!(exprs, sps, dict, mod, body, kwargs)
238+
Base.remove_linenums!(body)
239+
for arg in body.args
240+
MLStyle.@match arg begin
241+
Expr(:(=), a, b) => begin
242+
push!(sps, a)
243+
push!(kwargs, Expr(:kw, a, b))
244+
dict[:kwargs][a] = b
245+
end
246+
a => begin
247+
push!(sps, a)
248+
push!(kwargs, a)
249+
dict[:kwargs][a] = nothing
250+
end
251+
end
252+
end
253+
end
254+
237255
function parse_components!(exprs, cs, dict, body, kwargs)
238256
expr = Expr(:block)
239257
varexpr = Expr(:block)

test/model_parsing.jl

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,16 @@ end
121121
end
122122

123123
@mtkmodel RC begin
124-
@parameters begin
124+
@structural_parameters begin
125125
R_val = 10
126-
C_val = 5
126+
C_val = 10
127+
k_val = 10
127128
end
128129
@components begin
129130
resistor = Resistor(; R = R_val)
130131
capacitor = Capacitor(; C = C_val)
131132
source = Voltage()
132-
constant = Constant(; k = 1)
133+
constant = Constant(; k = k_val)
133134
ground = Ground()
134135
end
135136

@@ -141,12 +142,17 @@ end
141142
end
142143
end
143144

144-
@named rc = RC(; R_val = 20)
145-
params = ModelingToolkit.get_ps(rc)
146-
@test isequal(getdefault(rc.resistor.R), params[1])
147-
@test isequal(getdefault(rc.capacitor.C), params[2])
145+
C_val = 20
146+
R_val = 20
147+
res__R = 100
148+
@named rc = RC(; C_val, R_val, resistor.R = res__R)
149+
# Test that `resistor.R` overrides `R_val` in the argument.
150+
@test getdefault(rc.resistor.R) == res__R != R_val
151+
# Test that `C_val` passed via argument is set as default of C.
152+
@test getdefault(rc.capacitor.C) == C_val
153+
# Test that `k`'s default value is unchanged.
154+
@test getdefault(rc.constant.k) == RC.structure[:kwargs][:k_val]
148155
@test getdefault(rc.capacitor.v) == 0.0
149-
@test getdefault(rc.constant.k) == 1
150156

151157
@test get_gui_metadata(rc.resistor).layout == Resistor.structure[:icon] ==
152158
read(joinpath(ENV["MTK_ICONS_DIR"], "resistor.svg"), String)
@@ -177,10 +183,14 @@ params = ModelingToolkit.get_ps(rc)
177183
j(t) = jval, [description = "j(t)"]
178184
k = kval, [description = "k"]
179185
end
186+
@structural_parameters begin
187+
l = 1
188+
func
189+
end
180190
end
181191

182192
kval = 5
183-
@named model = MockModel(; kval, cval = 1)
193+
@named model = MockModel(; kval, cval = 1, func = identity)
184194

185195
@test hasmetadata(model.e, VariableDescription)
186196
@test hasmetadata(model.f, VariableDescription)

0 commit comments

Comments
 (0)