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

**URL:** <https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974>\
**Category:** Package Announcements\
**Tags:** diffeq, mtk, methodoflines\
**Created:** [August 21, 2026, 4:41pm UTC](https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974 "2026-08-21T16:41:49Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 21, 2026, 4:41pm UTC](https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974/1 "2026-08-21T16:41:50Z")

</div>

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

```julia
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 | 2× |
| 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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [August 21, 2026, 8:02pm UTC](https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974/2 "2026-08-21T20:02:12Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 21, 2026, 8:56pm UTC](https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974/3 "2026-08-21T20:56:18Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [August 22, 2026, 11:34am UTC](https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974/4 "2026-08-22T11:34:43Z")

</div>

Two experiences I had with implementing PDE discretization and one general experience…

1. One tricky part I found was to choose proper boundary conditions that made the port/connector work.
2. I also struggled quite a bit with making the problem well scaled. I like to write PDEs in the “original”/“balance equation” variables, so I prefer to use mass per length as differential variable (vector) in a 1D formulation of the mass balance, and momentum per length. Then add AEs. Reason: I find it easier to debug the model. Google AI Studio insisted I should use pressure and velocity (?) because it thought that made the problem better posed. (I have started to experiment with Claude now).
3. A recurrent problem I have had with MTK, and even more when I started to work with components, is that of properly initializing the problem … to avoid over specified or under specified initialization. I think I have found a solution to this, and I also think this solution (or a similar one) would be very useful to MTK users in general, see example below.

```julia-auto
u0_map, guess_map = build_mtk_maps(csys, sys)
update_mtk_map(u0_map)
update_mtk_map(guess_map)
prob = ODEProblem(csys, u0_map, tspan; guesses=guess_map)

```

assumes the compiled system `csys` is index 1 DAE. `build_mtk_maps` pulls out unknowns from `csys` and uses `equations` to check which unknown is differential. The differential variables `u0_map` are then set equal to the specified initial condition or guess value (initial condition is prioritized), and all algebraic variables are set to `nothing`. Similar for the `guess_map` wrt. initial conditions/guess values (`nothing` is of course not introduced here). Second argument `sys` is used to detect extra variables introduced in the index reduction process, and these are set to `0.0` for lack of something better.

If some of the unknowns lack initial conditions or initial guesses, they are set to `missing`.

Function `update_mtk_map` with one argument lists variables that have value `missing`– the user needs to specify these; this is done by adding a map as a the second argument of `update_mtk_map`.

Anyways, I find these functions highly useful, and since I developed them (with Google AI Studio, and improved with Claude), there is no more problem with overdetermined or underdetermined initial conditions. I also have a twin `build_mtk_maps` which uses a solution as the second argument instead of `sys` – this is used to re-start the system from the final value of a previous solution.

The only problem that remains is to select good initial guesss for algebraic variables…

---

<div class="post-metadata">

**Author:** ![mark.garnett](https://avatars.discourse-cdn.com/v4/letter/m/b9bd4f/32.png) [@mark.garnett](https://discourse.julialang.org/u/mark.garnett)\
**Post date:** [August 24, 2026, 4:49pm UTC](https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974/5 "2026-08-24T16:49:38Z")

</div>

If I just create an MTK component, not using MethodOfLines at all, and write my equation in array form, will they still be automatically scalarized (this is what was happening if I understand correctly) or will they be handled as array equation?

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [August 24, 2026, 4:50pm UTC](https://discourse.julialang.org/t/ann-methodoflines-v1-symbolic-arrays-massive-compile-speedups/138974/6 "2026-08-24T16:50:34Z")

</div>

If using DAEProblem and no index reduction, then it will not scalarize
