Skip to content

Commit 7f30cb1

Browse files
feat: add symbolic jacobian benchmark to ThermalFluid
1 parent 58e54e7 commit 7f30cb1

File tree

1 file changed

+69
-3
lines changed

1 file changed

+69
-3
lines changed

benchmarks/ModelingToolkit/ThermalFluid.jmd

Lines changed: 69 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ using Pkg
1010
# Rev fixes precompilation https://github.com/hzgzh/XSteam.jl/pull/2
1111
Pkg.add(Pkg.PackageSpec(;name="XSteam", rev="f2a1c589054cfd6bba307985a3a534b6f5a1863b"))
1212

13-
using ModelingToolkit, JuliaSimCompiler, Symbolics, XSteam, Polynomials, BenchmarkTools, CairoMakie, OrdinaryDiffEq
13+
using ModelingToolkit, JuliaSimCompiler, Symbolics, XSteam, Polynomials, BenchmarkTools, OrdinaryDiffEq
1414
using OMJulia
15+
16+
using ModelingToolkit: t_nounits as t, D_nounits as D
1517
```
1618

1719
## Setup Julia Code
@@ -24,8 +26,6 @@ using OMJulia
2426
#Source -> o--o--o--o--o--o--o -> Sink
2527
# advection diff source PDE
2628

27-
@variables t
28-
D = Differential(t)
2929
m_flow_source(t) = 2.75
3030
T_source(t) = (t > 12 * 3600) * 56.0 + 12.0
3131
@register_symbolic m_flow_source(t)
@@ -410,6 +410,72 @@ Legend(f2[1,2], _lines, names)
410410
f2
411411
```
412412

413+
## Symbolic jacobian timings
414+
415+
To avoid scaling issues with `structural_simplify` on ModelingToolkit.jl models, we will
416+
compile functions using JuliaSimCompiler.jl and trace through the resultant functions.
417+
418+
```julia
419+
function run_and_time_jacobian!(mtk_times, mtk_no_hashconsing_times, N)
420+
@named testbench = TestBenchPreinsulated(L=470, N=N, dn=0.3127, t_layer=[0.0056, 0.058])
421+
sys = structural_simplify(IRSystem(testbench), loop=false)
422+
# tspan doesn't matter
423+
prob = ODEProblem(sys, [], (0.0, 1.0); sparse = true)
424+
425+
t = ModelingToolkit.t_nounits
426+
n_states = length(prob.u0)
427+
@variables x(t)[1:n_states]
428+
n_params = length(prob.p)
429+
@variables p[1:n_params]
430+
431+
x = collect(x)
432+
p = collect(p)
433+
expr = zeros(Num, n_states)
434+
prob.f.f(expr, x, p, t)
435+
436+
expr = map(Symbolics.unwrap, expr)
437+
x = map(Symbolics.unwrap, x)
438+
mtk_time = @elapsed jac1 = Symbolics.jacobian(expr, x)
439+
push!(mtk_times, mtk_time)
440+
441+
SymbolicUtils.ENABLE_HASHCONSING[] = false
442+
@variables x(t)[1:n_states]
443+
@variables p[1:n_params]
444+
x = collect(x)
445+
p = collect(p)
446+
expr = zeros(Num, n_states)
447+
prob.f.f(expr, x, p, t)
448+
expr = map(Symbolics.unwrap, expr)
449+
no_hashconsing_time = @elapsed jac2 = Symbolics.jacobian(expr, x)
450+
push!(mtk_no_hashconsing_times, no_hashconsing_time)
451+
SymbolicUtils.ENABLE_HASHCONSING[] = true
452+
453+
@assert all(isequal.(jac1, jac2))
454+
end
455+
```
456+
457+
458+
```julia
459+
@time run_and_time_jacobian!(Float64[], Float64[], 4) # precompile
460+
mtk_times = Float64[]
461+
mtk_no_hashconsing_times = Float64[]
462+
for n in N
463+
run_and_time_jacobian!(Float64[], Float64[], n)
464+
end
465+
```
466+
467+
## Generate Plots
468+
469+
```julia
470+
f3 = Figure(size=(800,1200));
471+
ss_names = ["MTK", "JSIR"];
472+
let ax = Axis(f3[1, 1]; yscale = log10, xscale = log10, title = "Jacobian Time")
473+
_lines = [lines!(N, mtk_times), lines!(N, mtk_no_hashconsing_times)]
474+
Legend(f3[1, 2], _lines, ["With Hashconsing", "Without Hashconsing"])
475+
end
476+
f3
477+
```
478+
413479
## Appendix
414480

415481
```julia, echo = false

0 commit comments

Comments
 (0)