[ANN] MethodOfLines v1: Symbolic Arrays => Massive Compile Speedups

MethodOfLines.jl v1.0 changes all discretizations to using symbolic arrays. If they lower to code using DAEProblem the array structure is kept intact, meaning no more scalarization and massive compile time speedups.

Timings

Earlier benchmarks comparing the pointwise symbolic representation with the new array form measured the following discretization times:

Problem Unknowns Pointwise form Array form Speedup
1D heat equation 400 47.9 s 0.23 s 201×
2D heat equation 900 7.52 s 0.14 s 52×
3D heat equation 1,331 7.78 s 0.13 s 60×

The same effect applies to nonlinear operators. For

Dt(u(t, x)) ~ Dx(u(t, x) * Dx(u(t, x)))

the results were:

Grid points Pointwise expression nodes Array expression nodes Pointwise time Array time Speedup
21 1,653 376 0.04 s 0.02 s
101 8,613 376 1.20 s 0.05 s 24×
501 43,413 376 49.4 s 0.44 s 112×

The numerical solutions agreed to within 9e-16.

I also measured the complete problem-construction path on the current v1 code. These are single warmed runs on Julia 1.12.6 using an AMD EPYC 7502 system:

Grid points New DAE path Compiled ODE path Speedup
256 0.59 s, 61 MiB 1.56 s, 165 MiB 2.7×
1,024 1.77 s, 315 MiB 12.58 s, 1.31 GiB 7.1×
4,096 17.48 s, 5.90 GiB 175.22 s, 20.63 GiB 10.0×

Caveat: Using explicit Runge–Kutta methods

The array compilation advantage currently applies to the DAE path. Explicit Runge–Kutta algorithms such as Tsit5() and SSPRK54() require an ODEProblem.

To use an explicit method, request the symbolic system directly and compile it into an ODE:

sys, tspan = symbolic_discretize(pdesys, disc)
prob = ODEProblem(mtkcompile(sys), nothing, tspan)

sol = solve(prob, Tsit5())

This path scalarizes the system during mtkcompile, so it does not have the same constant-size symbolic representation or compilation scaling as the default DAE path. We plan to address this limitation in the near future.

A kind of naive question… I am working on some problems where I make components consisting of PDEs (e.g., gas pipes). In my set-up, I need to be able to have ports for the pipes, and be able to connect several pipes to some junction. For some problems, I have gas mixtures and need to invoke thermodynamic models.

Is it feasible to use MOL for such pipes? I have currently done some discretization on my own (with AI tools…), with both method of characteristic (MOC) and FVM/Kurganov-Petrova 2nd order method. I found it really tricky to get this to work, partially because I am not an expert on numeric methods for PDEs.

I haven’t tried to use MethodOfLines.jl in a component, but that and UDEs in MOL are two next direction