forked from SciML/ModelingToolkit.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmass_matrix.jl
44 lines (36 loc) · 1.31 KB
/
mass_matrix.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using OrdinaryDiffEq, ModelingToolkit, Test, LinearAlgebra
@parameters t
@variables y(t)[1:3]
@parameters k[1:3]
D = Differential(t)
eqs = [D(y[1]) ~ -k[1] * y[1] + k[3] * y[2] * y[3],
D(y[2]) ~ k[1] * y[1] - k[3] * y[2] * y[3] - k[2] * y[2]^2,
0 ~ y[1] + y[2] + y[3] - 1]
@named sys = ODESystem(eqs, t, y, k)
@test_throws ArgumentError ODESystem(eqs, y[1])
M = calculate_massmatrix(sys)
@test M == [1 0 0
0 1 0
0 0 0]
f = ODEFunction(sys)
prob_mm = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4))
sol = solve(prob_mm, Rodas5(), reltol = 1e-8, abstol = 1e-8)
function rober(du, u, p, t)
y₁, y₂, y₃ = u
k₁, k₂, k₃ = p
du[1] = -k₁ * y₁ + k₃ * y₂ * y₃
du[2] = k₁ * y₁ - k₃ * y₂ * y₃ - k₂ * y₂^2
du[3] = y₁ + y₂ + y₃ - 1
nothing
end
f = ODEFunction(rober, mass_matrix = M)
prob_mm2 = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1e5), (0.04, 3e7, 1e4))
sol2 = solve(prob_mm2, Rodas5(), reltol = 1e-8, abstol = 1e-8, tstops = sol.t,
adaptive = false)
# MTK expression are canonicalized, so the floating point numbers are slightly
# different
@test Array(sol) ≈ Array(sol2)
# Test mass matrix in the identity case
eqs = [D(y[1]) ~ y[1], D(y[2]) ~ y[2], D(y[3]) ~ y[3]]
@named sys = ODESystem(eqs, t, y, k)
@test calculate_massmatrix(sys) === I