Skip to content

Commit 672e42c

Browse files
committed
refactor: pass the symbolic vals for kwargs of sub components instead of depending on the numerical value of it
- this change allows user to set a parameter with initial value and pass that as default value of kwargs of sub components.
1 parent bc0033a commit 672e42c

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

src/systems/model_parsing.jl

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,8 @@ end
236236

237237
function parse_components!(exprs, cs, dict, body, kwargs)
238238
expr = Expr(:block)
239-
push!(exprs, expr)
239+
varexpr = Expr(:block)
240+
push!(exprs, varexpr)
240241
comps = Vector{Symbol}[]
241242
for arg in body.args
242243
arg isa LineNumberNode && continue
@@ -247,23 +248,25 @@ function parse_components!(exprs, cs, dict, body, kwargs)
247248
arg = deepcopy(arg)
248249
b = deepcopy(arg.args[2])
249250

250-
component_args!(a, b, expr, kwargs)
251+
component_args!(a, b, dict, expr, varexpr, kwargs)
251252

252-
push!(b.args, Expr(:kw, :name, Meta.quot(a)))
253253
arg.args[2] = b
254254
push!(expr.args, arg)
255255
end
256256
_ => error("`@components` only takes assignment expressions. Got $arg")
257257
end
258258
end
259+
260+
push!(exprs, :(@named $expr))
261+
259262
dict[:components] = comps
260263
end
261264

262265
function _rename(compname, varname)
263266
compname = Symbol(compname, :__, varname)
264267
end
265268

266-
function component_args!(a, b, expr, kwargs)
269+
function component_args!(a, b, dict, expr, varexpr, kwargs)
267270
# Whenever `b` is a function call, skip the first arg aka the function name.
268271
# Whenever it is a kwargs list, include it.
269272
start = b.head == :call ? 2 : 1
@@ -274,15 +277,19 @@ function component_args!(a, b, expr, kwargs)
274277
x::Symbol || Expr(:kw, x) => begin
275278
_v = _rename(a, x)
276279
b.args[i] = Expr(:kw, x, _v)
280+
push!(varexpr.args, :((@isdefined $x) && ($_v = $x)))
277281
push!(kwargs, Expr(:kw, _v, nothing))
282+
dict[:kwargs][_v] = nothing
278283
end
279284
Expr(:parameters, x...) => begin
280-
component_args!(a, arg, expr, kwargs)
285+
component_args!(a, arg, dict, expr, varexpr, kwargs)
281286
end
282287
Expr(:kw, x, y) => begin
283288
_v = _rename(a, x)
284289
b.args[i] = Expr(:kw, x, _v)
285-
push!(kwargs, Expr(:kw, _v, y))
290+
push!(varexpr.args, :($_v = $_v === nothing ? $y : $_v))
291+
push!(kwargs, Expr(:kw, _v, nothing))
292+
dict[:kwargs][_v] = nothing
286293
end
287294
_ => error("Could not parse $arg of component $a")
288295
end

test/model_parsing.jl

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using ModelingToolkit, Test
2-
using ModelingToolkit: get_gui_metadata, VariableDescription, getdefault, RegularConnector
2+
using ModelingToolkit: get_gui_metadata,
3+
VariableDescription, getdefault, RegularConnector, get_ps
34
using URIs: URI
45
using Distributions
56
using Unitful
@@ -120,9 +121,13 @@ end
120121
end
121122

122123
@mtkmodel RC begin
124+
@parameters begin
125+
R_val = 10
126+
C_val = 5
127+
end
123128
@components begin
124-
resistor = Resistor(; R)
125-
capacitor = Capacitor(; C = 10)
129+
resistor = Resistor(; R = R_val)
130+
capacitor = Capacitor(; C = C_val)
126131
source = Voltage()
127132
constant = Constant(; k = 1)
128133
ground = Ground()
@@ -135,9 +140,10 @@ end
135140
end
136141
end
137142

138-
@named rc = RC(; resistor.R = 20)
139-
@test getdefault(rc.resistor.R) == 20
140-
@test getdefault(rc.capacitor.C) == 10
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])
141147
@test getdefault(rc.capacitor.v) == 0.0
142148
@test getdefault(rc.constant.k) == 1
143149

@@ -210,14 +216,15 @@ end
210216
end
211217

212218
@named a = A(p = 10)
213-
getdefault(a.b.i) == 10
214-
getdefault(a.b.j) == 0.1
215-
getdefault(a.b.k) == 1
219+
params = get_ps(a)
220+
@test isequal(getdefault(a.b.i), params[1])
221+
@test isequal(getdefault(a.b.j), 1 / params[1])
222+
@test getdefault(a.b.k) == 1
216223

217224
@named a = A(p = 10, b.i = 20, b.j = 30, b.k = 40)
218-
getdefault(a.b.i) == 20
219-
getdefault(a.b.j) == 30
220-
getdefault(a.b.k) == 40
225+
@test getdefault(a.b.i) == 20
226+
@test getdefault(a.b.j) == 30
227+
@test getdefault(a.b.k) == 40
221228

222229
metadata = Dict(:description => "Variable to test metadata in the Model.structure",
223230
:input => true, :bounds => (-1, 1), :connection_type => :Flow, :integer => true,

0 commit comments

Comments
 (0)