-
-
Notifications
You must be signed in to change notification settings - Fork 231
Description
Hi,
I would like to start by apologizing for a long text...
I have the following models, note these models are automatically generated based on different parameters to the following Modelica model
model Casc
parameter Integer N = 10 "Order of the system"; // This parameter can be changed to increase the number of equations
final parameter Real tau = T/N "Individual time constant";
parameter Real T = 1 "System delay";
Real x[N] (each start = 0, each fixed = true);
equation
tau*der(x[1]) = 1 - x[1];
for i in 2:N loop
tau*der(x[i]) = x[i-1] - x[i];
end for;
end Casc;
The corresponding MTK model for N = 10
(Take note that this code is automatically generated) is:
using ModelingToolkit
using DifferentialEquations
begin
begin
saved_values_Casc10 = SavedValues(Float64, Tuple{Float64,Array})
function Casc10CallbackSet(aux)
local p = aux[1]
local reals = aux[2]
nothing
return CallbackSet()
end
end
function Casc10Model(tspan = (0.0, 1.0))
@variables t #= C:\Users\johti17\Projects\Programming\JuliaPackages\OM.jl\OMBackend.jl\src\CodeGeneration\MTK_CodeGeneration.jl:219 =#
parameters = ModelingToolkit.@parameters((N, tau, T)) #= C:\Users\johti17\Projects\Programming\JuliaPackages\OM.jl\OMBackend.jl\src\CodeGeneration\MTK_CodeGeneration.jl:220 =#
vars = ModelingToolkit.@variables((
x_1(t),
x_2(t),
x_3(t),
x_4(t),
x_5(t),
x_6(t),
x_7(t),
x_8(t),
x_9(t),
x_10(t),
)) #= C:\Users\johti17\Projects\Programming\JuliaPackages\OM.jl\OMBackend.jl\src\CodeGeneration\MTK_CodeGeneration.jl:227 =#
der = Differential(t)
eqs = [
der(x_1) ~ (1.0 - x_1) / tau,
der(x_2) ~ (x_1 - x_2) / tau,
der(x_3) ~ (x_2 - x_3) / tau,
der(x_4) ~ (x_3 - x_4) / tau,
der(x_5) ~ (x_4 - x_5) / tau,
der(x_6) ~ (x_5 - x_6) / tau,
der(x_7) ~ (x_6 - x_7) / tau,
der(x_8) ~ (x_7 - x_8) / tau,
der(x_9) ~ (x_8 - x_9) / tau,
der(x_10) ~ (x_9 - x_10) / tau,
]
nonLinearSystem = ModelingToolkit.ODESystem(
eqs,
t,
vars,
parameters,
name = :($(Symbol("Casc10"))),
)
nonLinearSystem = ModelingToolkit.structural_simplify(nonLinearSystem)
pars = Dict(N => float(10), tau => float(T / 10.0), T => float(1.0))
initialValues = [
x_1 => 0.0,
x_2 => 0.0,
x_3 => 0.0,
x_4 => 0.0,
x_5 => 0.0,
x_6 => 0.0,
x_7 => 0.0,
x_8 => 0.0,
x_9 => 0.0,
x_10 => 0.0,
]
firstOrderSystem = ModelingToolkit.ode_order_lowering(nonLinearSystem)
reducedSystem = firstOrderSystem
local event_p = [10, 0, 1.0]
local discreteVars = collect(values(Dict([])))
local event_vars = vcat(
collect(
values(
Dict([
x_1 => 0.0,
x_2 => 0.0,
x_3 => 0.0,
x_4 => 0.0,
x_5 => 0.0,
x_6 => 0.0,
x_7 => 0.0,
x_8 => 0.0,
x_9 => 0.0,
x_10 => 0.0,
]),
),
),
discreteVars,
)
local aux = Array{Array{Float64}}(undef, 2)
aux[1] = event_p
aux[2] = event_vars
problem = ModelingToolkit.ODEProblem(
reducedSystem,
initialValues,
tspan,
pars,
callback = Casc10CallbackSet(aux),
cse = true,
)
return (problem, initialValues, reducedSystem, tspan, pars, vars)
end
end
(Casc10Model_problem, _, _, _, _, _) = Casc10Model()
function Casc10Simulate(tspan)
return solve(Casc10Model_problem, tspan = tspan)
end
function Casc10Simulate(tspan = (0.0, 1.0); solver = Rodas5())
return solve(Casc10Model_problem, tspan = tspan, solver)
end
A sample current timings (On my laptop) MTK compilation + Simulation
10:
0.305501 seconds (477.56 k allocations: 27.560 MiB, 90.20% compilation time)
100:
1.420337 seconds (1.56 M allocations: 80.551 MiB, 93.48% compilation time)
200:
3.867602 seconds (2.81 M allocations: 147.689 MiB, 93.44% compilation time)
400: (Up a lot from 200, memory is linear though)
26.180517 seconds (5.33 M allocations: 305.115 MiB, 1.05% gc time, 97.28% compilation time)
800:
99.175782 seconds (10.28 M allocations: 708.155 MiB, 0.21% gc time, 95.19% compilation time)
Sorry for a long post, I suppose a related issue is #1286 and #1285
Models are attached for reference. I uploaded them as txt files since the GitHub issue API do not seem to support .jl files
Casc10.txt
Casc100.txt
Casc200.txt
Casc400.txt
Casc800.txt
Casc1600.txt
It also takes quite some time just including the models, say that I have a model like the ones attached, how could I decompose the system better in order to reduce the compilation time overhead?
I suppose splitting the declarations of variables into separate functions might do something?
See JuliaLang/julia#19158
But then the question is how could I go about splitting the declaration of variables and equations to built it up in parts?
Say that I want to register 100 variables at the time using @variables
(Feel free to rework these Julia models so that they look more idiomatic and use them for benchmarking)
Cheers,
John 🚀