Skip to content

Commit c0e189d

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 c4b4afe commit c0e189d

File tree

2 files changed

+44
-12
lines changed

2 files changed

+44
-12
lines changed

src/systems/model_parsing.jl

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,13 @@ function mtkmodel_macro(mod, name, expr)
217217
icon = Ref{Union{String, URI}}()
218218
vs = []
219219
ps = []
220+
sps = []
220221
kwargs = []
221222

222223
for arg in expr.args
223224
arg isa LineNumberNode && continue
224225
if arg.head == :macrocall
225-
parse_model!(exprs.args, comps, ext, eqs, icon, vs, ps,
226+
parse_model!(exprs.args, comps, ext, eqs, icon, vs, ps, sps,
226227
dict, mod, arg, kwargs)
227228
elseif arg.head == :block
228229
push!(exprs.args, arg)
@@ -249,8 +250,8 @@ function mtkmodel_macro(mod, name, expr)
249250
:($name = $Model((; name, $(kwargs...)) -> $exprs, $dict, false))
250251
end
251252

252-
function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, dict,
253-
mod, arg, kwargs)
253+
function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, sps,
254+
dict, mod, arg, kwargs)
254255
mname = arg.args[1]
255256
body = arg.args[end]
256257
if mname == Symbol("@components")
@@ -261,6 +262,8 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, dict,
261262
parse_variables!(exprs, vs, dict, mod, body, :variables, kwargs)
262263
elseif mname == Symbol("@parameters")
263264
parse_variables!(exprs, ps, dict, mod, body, :parameters, kwargs)
265+
elseif mname == Symbol("@structural_parameters")
266+
parse_structural_parameters!(exprs, sps, dict, mod, body, kwargs)
264267
elseif mname == Symbol("@equations")
265268
parse_equations!(exprs, eqs, dict, body)
266269
elseif mname == Symbol("@icon")
@@ -270,6 +273,25 @@ function parse_model!(exprs, comps, ext, eqs, icon, vs, ps, dict,
270273
end
271274
end
272275

276+
function parse_structural_parameters!(exprs, sps, dict, mod, body, kwargs)
277+
Base.remove_linenums!(body)
278+
for arg in body.args
279+
MLStyle.@match arg begin
280+
Expr(:(=), a, b) => begin
281+
push!(sps, a)
282+
push!(kwargs, Expr(:kw, a, b))
283+
dict[:kwargs][a] = b
284+
end
285+
a => begin
286+
push!(sps, a)
287+
push!(kwargs, a)
288+
dict[:kwargs][a] = nothing
289+
@info 285
290+
end
291+
end
292+
end
293+
end
294+
273295
function parse_components!(exprs, cs, dict, body, kwargs)
274296
expr = Expr(:block)
275297
varexpr = Expr(:block)

test/model_parsing.jl

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

122122
@mtkmodel RC begin
123-
@parameters begin
123+
@structural_parameters begin
124124
R_val = 10
125-
C_val = 5
125+
C_val = 10
126+
k_val = 10
126127
end
127128
@components begin
128129
resistor = Resistor(; R = R_val)
129130
capacitor = Capacitor(; C = C_val)
130131
source = Voltage()
131-
constant = Constant(; k = 1)
132+
constant = Constant(; k = k_val)
132133
ground = Ground()
133134
end
134135

@@ -140,12 +141,17 @@ end
140141
end
141142
end
142143

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

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

181191
kval = 5
182-
@named model = MockModel(; kval, cval = 1)
192+
@named model = MockModel(; kval, cval = 1, func = identity)
183193

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

0 commit comments

Comments
 (0)