Skip to content

Commit 36d762c

Browse files
committed
Make at named more intuitive
1 parent dd721c2 commit 36d762c

File tree

2 files changed

+27
-9
lines changed

2 files changed

+27
-9
lines changed

src/systems/abstractsystem.jl

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,12 +845,21 @@ function _named(name, call, runtime = false)
845845
end
846846
end
847847

848+
is_sys_construction = Symbol("###__is_system_construction###")
848849
kws = call.args[2].args
850+
for kw in kws
851+
kw.args[2] = :($is_sys_construction ? $(kw.args[2]) :
852+
$default_to_parentscope($(kw.args[2])))
853+
end
849854

850855
if !any(kw -> (kw isa Symbol ? kw : kw.args[1]) == :name, kws) # don't overwrite `name` kwarg
851856
pushfirst!(kws, Expr(:kw, :name, runtime ? name : Meta.quot(name)))
852857
end
853-
call
858+
op = call.args[1]
859+
quote
860+
$is_sys_construction = ($op isa $DataType) && ($op <: $AbstractSystem)
861+
$call
862+
end
854863
end
855864

856865
function _named_idxs(name::Symbol, idxs, call)
@@ -877,7 +886,10 @@ end
877886
@named y[1:10] = foo(x)
878887
@named y 1:10 i -> foo(x*i) # This is not recommended
879888
880-
Pass the LHS name to the model.
889+
Pass the LHS name to the model. When it's calling anything that's not an
890+
AbstractSystem, it wraps all keyword arguments in `default_to_parentscope` so
891+
that namespacing works intuitively when passing a symbolic default into a
892+
component.
881893
882894
Examples:
883895
```julia-repl
@@ -920,6 +932,11 @@ macro named(name::Symbol, idxs, call)
920932
esc(_named_idxs(name, idxs, call))
921933
end
922934

935+
function default_to_parentscope(v)
936+
uv = unwrap(v)
937+
uv isa Symbolic && !hasmetadata(uv, SymScope) ? ParentScope(v) : v
938+
end
939+
923940
function _config(expr, namespace)
924941
cn = Base.Fix2(_config, namespace)
925942
if Meta.isexpr(expr, :.)

test/components.jl

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ using Test
22
using ModelingToolkit, OrdinaryDiffEq
33
using ModelingToolkit.BipartiteGraphs
44
using ModelingToolkit.StructuralTransformations
5+
include("../examples/rc_model.jl")
56

67
function check_contract(sys)
78
state = ModelingToolkit.get_tearing_state(sys)
@@ -74,7 +75,8 @@ let
7475
params = [param_r1 => 1.0, param_c1 => 1.0]
7576
tspan = (0.0, 10.0)
7677

77-
@test_throws Any prob=ODAEProblem(sys, u0, tspan, params)
78+
prob = ODAEProblem(sys, u0, tspan, params)
79+
@test solve(prob, Tsit5()).retcode == :Success
7880
end
7981

8082
let
@@ -96,17 +98,16 @@ let
9698
end
9799

98100
# Outer/inner connections
99-
function rc_component(; name)
100-
R = 1
101-
C = 1
101+
function rc_component(; name, R = 1, C = 1)
102+
@parameters R=R C=C
102103
@named p = Pin()
103104
@named n = Pin()
104-
@named resistor = Resistor(R = R)
105-
@named capacitor = Capacitor(C = C)
105+
@named resistor = Resistor(R = R) # test parent scope default of @named
106+
@named capacitor = Capacitor(C = ParentScope(C))
106107
eqs = [connect(p, resistor.p);
107108
connect(resistor.n, capacitor.p);
108109
connect(capacitor.n, n)]
109-
@named sys = ODESystem(eqs, t)
110+
@named sys = ODESystem(eqs, t, [], [R, C])
110111
compose(sys, [p, n, resistor, capacitor]; name = name)
111112
end
112113

0 commit comments

Comments
 (0)