Skip to content

Commit 1c939fe

Browse files
committed
feat: allow users to set array length via args in @mtkmodel
1 parent f4d4faf commit 1c939fe

File tree

2 files changed

+66
-36
lines changed

2 files changed

+66
-36
lines changed

src/systems/model_parsing.jl

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,12 @@ function parse_variable_def!(dict, mod, arg, varclass, kwargs, where_types;
269269
return var, def, Dict()
270270
end
271271
Expr(:ref, a, b...) => begin
272-
indices = map(i -> UnitRange(i.args[2], i.args[end]), b)
273-
parse_variable_def!(dict, mod, a, varclass, kwargs, where_types;
274-
def, indices, type, meta)
272+
if varclass == :parameters
273+
var = :($a = $first(@parameters $a[$(b...)]))
274+
else
275+
var = :($a = $first(@variables $a[$(b...)]))
276+
end
277+
(:($a...), var), nothing, Dict()
275278
end
276279
_ => error("$arg cannot be parsed")
277280
end
@@ -674,47 +677,51 @@ end
674677
function parse_variable_arg(dict, mod, arg, varclass, kwargs, where_types)
675678
vv, def, metadata_with_exprs = parse_variable_def!(
676679
dict, mod, arg, varclass, kwargs, where_types)
677-
name = getname(vv)
680+
if vv isa Tuple
681+
return vv
682+
else
683+
name = getname(vv[1])
678684

679-
varexpr = if haskey(metadata_with_exprs, VariableUnit)
680-
unit = metadata_with_exprs[VariableUnit]
681-
quote
682-
$name = if $name === nothing
683-
$setdefault($vv, $def)
684-
else
685-
try
686-
$setdefault($vv, $convert_units($unit, $name))
687-
catch e
688-
if isa(e, $(DynamicQuantities.DimensionError)) ||
689-
isa(e, $(Unitful.DimensionError))
690-
error("Unable to convert units for \'" * string(:($$vv)) * "\'")
691-
elseif isa(e, MethodError)
692-
error("No or invalid units provided for \'" * string(:($$vv)) *
693-
"\'")
694-
else
695-
rethrow(e)
685+
varexpr = if haskey(metadata_with_exprs, VariableUnit)
686+
unit = metadata_with_exprs[VariableUnit]
687+
quote
688+
$name = if $name === nothing
689+
$setdefault($vv, $def)
690+
else
691+
try
692+
$setdefault($vv, $convert_units($unit, $name))
693+
catch e
694+
if isa(e, $(DynamicQuantities.DimensionError)) ||
695+
isa(e, $(Unitful.DimensionError))
696+
error("Unable to convert units for \'" * string(:($$vv)) * "\'")
697+
elseif isa(e, MethodError)
698+
error("No or invalid units provided for \'" * string(:($$vv)) *
699+
"\'")
700+
else
701+
rethrow(e)
702+
end
696703
end
697704
end
698705
end
699-
end
700-
else
701-
quote
702-
$name = if $name === nothing
703-
$setdefault($vv, $def)
704-
else
705-
$setdefault($vv, $name)
706+
else
707+
quote
708+
$name = if $name === nothing
709+
$setdefault($vv, $def)
710+
else
711+
$setdefault($vv, $name)
712+
end
706713
end
707714
end
708-
end
709715

710-
metadata_expr = Expr(:block)
711-
for (k, v) in metadata_with_exprs
712-
push!(metadata_expr.args,
713-
:($name = $wrap($set_scalar_metadata($unwrap($name), $k, $v))))
714-
end
716+
metadata_expr = Expr(:block)
717+
for (k, v) in metadata_with_exprs
718+
push!(metadata_expr.args,
719+
:($name = $wrap($set_scalar_metadata($unwrap($name), $k, $v))))
720+
end
715721

716-
push!(varexpr.args, metadata_expr)
717-
return vv isa Num ? name : :($name...), varexpr
722+
push!(varexpr.args, metadata_expr)
723+
return vv isa Num ? name : :($name...), varexpr
724+
end
718725
end
719726

720727
function handle_conditional_vars!(

test/model_parsing.jl

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -876,3 +876,26 @@ end
876876
end),
877877
false)
878878
end
879+
880+
@testset "Array Length as an Input" begin
881+
@mtkmodel VaryingLengthArray begin
882+
@structural_parameters begin
883+
N
884+
M
885+
end
886+
@parameters begin
887+
p1[1:N]
888+
p2[1:N, 1:M]
889+
end
890+
@variables begin
891+
v1(t)[1:N]
892+
v2(t)[1:N, 1:M]
893+
end
894+
end
895+
896+
@named model = VaryingLengthArray(N = 2, M = 3)
897+
@test length(model.p1) == 2
898+
@test size(model.p2) == (2, 3)
899+
@test length(model.v1) == 2
900+
@test size(model.v2) == (2, 3)
901+
end

0 commit comments

Comments
 (0)