-
-
Notifications
You must be signed in to change notification settings - Fork 245
Description
Summary
collect_scoped_vars! in ModelingToolkitBase/src/utils.jl:607 uses symtype(eq.lhs) <: Number to filter equations. This silently skips any equation whose LHS has an array symtype (e.g. ArrayMaker, ArrayOp). Variables in these equations are never collected/registered, causing downstream compilation failures.
MWE
using ModelingToolkit
using SymbolicUtils
using SymbolicUtils: SymReal, ArrayOp
@variables t
@variables x(t)[1:5]
# Create a simple ArrayOp expression (simplified from what MethodOfLines produces)
ix = SymbolicUtils.Sym{SymReal}(:i_x)
x_unwrap = Symbolics.unwrap(x)
# Build an array equation: Dt(x) ~ some_array_expression
# When this is passed to System(), collect_scoped_vars! will skip it
# because symtype(array_expr) <: AbstractArray, not <: Number
# The issue manifests when any system with ArrayMaker/ArrayOp equations
# goes through mtkcompile → complete() → discover_globalscoped() →
# collect_scoped_vars!Realistic reproduction (requires MethodOfLines.jl):
using ModelingToolkit, MethodOfLines, DomainSets
@parameters t x
@variables u(..) v(..)
Dx = Differential(x)
Dt = Differential(t)
# Two-variable coupled system with interface boundaries
# produces ArrayMaker equations that hit this code path
eq = [Dt(u(t,x)) ~ Dx(v(t,x) * Dx(u(t,x))),
Dt(v(t,x)) ~ Dx(u(t,x) * Dx(v(t,x)))]
bcs = [u(0,x) ~ sin(x), u(t,0) ~ 0.0, u(t,1) ~ 0.0,
v(0,x) ~ cos(x), v(t,0) ~ 1.0, v(t,1) ~ 1.0]
domains = [t ∈ Interval(0.0, 1.0), x ∈ Interval(0.0, 1.0)]
@named sys = PDESystem(eq, bcs, domains, [t,x], [u(t,x), v(t,x)])
disc = MOLFiniteDifference([x => 0.1], t)
prob = discretize(sys, disc)
# Fails during mtkcompile when collect_scoped_vars! skips array equationsRoot cause
In ModelingToolkitBase/src/utils.jl:602-624:
function collect_scoped_vars!(unknowns, parameters, sys, iv, ::Type{op} = Differential; depth = 1) where {op}
if has_eqs(sys)
for eq in equations(sys)
eqtype_supports_collect_vars(eq) || continue
if eq isa Equation
symtype(eq.lhs) <: Number || continue # ← THIS LINE
end
collect_vars!(unknowns, parameters, eq, iv, op; depth)
end
end
...
endLine 607 checks symtype(eq.lhs) <: Number. For array-valued equations (where symtype returns AbstractArray{<:Real} or similar), this check fails and the equation is silently skipped via continue. The variables referenced in these equations are never registered with the system.
Suggested fix
ModelingToolkitBase already has is_numeric_symtype at utils.jl:968-969:
function is_numeric_symtype(T::Type)
return T <: Number || T <: AbstractArray && is_numeric_symtype(eltype(T))
endThis correctly handles array types with numeric element types. Replace line 607:
- symtype(eq.lhs) <: Number || continue
+ is_numeric_symtype(symtype(eq.lhs)) || continueThis would allow array-valued equations through while still filtering non-numeric types.
Impact
This blocks ~3 tests in MethodOfLines.jl where mtkcompile is called on systems containing ArrayMaker equations (the array-based discretization path). The equations are valid — they represent bulk array operations over discretized PDE grids — but their array symtype causes them to be silently dropped during system completion.
Environment
- ModelingToolkit v10.x (latest)
- ModelingToolkitBase v3.x
- SymbolicUtils v4.18.1
- MethodOfLines.jl stencils branch