Skip to content

Commit 9c2064b

Browse files
Merge pull request #1519 from Abhishek-1Bhatt/dae_jacobian
Fixed Jacobian for DAEs and added a test for it
2 parents 4a3f7d4 + cbec288 commit 9c2064b

File tree

3 files changed

+60
-3
lines changed

3 files changed

+60
-3
lines changed

src/systems/diffeqs/abstractodesystem.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ end
1919

2020
function calculate_jacobian(sys::AbstractODESystem;
2121
sparse=false, simplify=false, dvs=states(sys))
22-
22+
2323
if isequal(dvs, states(sys))
2424
cache = get_jac(sys)[]
2525
if cache isa Tuple && cache[2] == (sparse, simplify)
2626
return cache[1]
2727
end
2828
end
2929

30-
rhs = [eq.rhs for eq full_equations(sys)]
30+
rhs = [eq.rhs - eq.lhs for eq full_equations(sys)] #need du terms on rhs for differentiating wrt du
3131

3232
iv = get_iv(sys)
3333

test/dae_jacobian.jl

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using ModelingToolkit
2+
using Sundials, Test, SparseArrays
3+
4+
# Comparing solution obtained by defining explicit Jacobian function with solution obtained from
5+
# symbolically generated Jacobian
6+
7+
function testjac(res, du, u, p, t) #System of equations
8+
res[1] = du[1] - 1.5 * u[1] + 1.0 * u[1] * u[2]
9+
res[2] = du[2] + 3 * u[2] - u[1] * u[2]
10+
end
11+
12+
function testjac_jac(J, du, u, p, gamma, t) #Explicit Jacobian
13+
J[1, 1] = gamma - 1.5 + 1.0 * u[2]
14+
J[1, 2] = 1.0 * u[1]
15+
J[2, 1] = -1 * u[2]
16+
J[2, 2] = gamma + 3 - u[1]
17+
nothing
18+
end
19+
20+
testjac_f = DAEFunction(testjac, jac = testjac_jac, jac_prototype = sparse([1, 2, 1, 2], [1, 1, 2, 2], zeros(4)))
21+
22+
prob1 = DAEProblem(
23+
testjac_f,
24+
[0.5, -2.0],
25+
ones(2),
26+
(0.0, 10.0),
27+
differential_vars = [true, true],
28+
)
29+
sol1 = solve(prob1, IDA(linear_solver = :KLU))
30+
31+
# Now MTK style solution with generated Jacobian
32+
33+
@variables t u1(t) u2(t)
34+
@parameters p1 p2
35+
36+
D = Differential(t)
37+
38+
eqs = [D(u1) ~ p1*u1 - u1 * u2,
39+
D(u2) ~ u1*u2 - p2*u2]
40+
41+
@named sys = ODESystem(eqs)
42+
43+
u0 = [u1 => 1.0,
44+
u2 => 1.0]
45+
46+
tspan = (0.0, 10.0)
47+
48+
du0 = [0.5, -2.0]
49+
50+
p = [p1 => 1.5,
51+
p2 => 3.0]
52+
53+
prob = DAEProblem(sys, du0, u0, tspan, p, jac=true, sparse=true)
54+
sol = solve(prob, IDA(linear_solver= :KLU))
55+
56+
@test maximum(sol - sol1) < 1e-12

test/runtests.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ using SafeTestsets, Test
3131
@safetestset "Precompiled Modules Test" begin include("precompile_test.jl") end
3232
@testset "Distributed Test" begin include("distributed.jl") end
3333
@safetestset "Variable Utils Test" begin include("variable_utils.jl") end
34+
@safetestset "DAE Jacobians Test" begin include("dae_jacobian.jl") end
3435
@safetestset "Jacobian Sparsity" begin include("jacobiansparsity.jl") end
3536
println("Last test requires gcc available in the path!")
3637
@safetestset "C Compilation Test" begin include("ccompile.jl") end
@@ -42,4 +43,4 @@ println("Last test requires gcc available in the path!")
4243
@safetestset "state_selection" begin include("state_selection.jl") end
4344

4445
# Reference tests go Last
45-
@safetestset "Latexify recipes Test" begin include("latexify.jl") end
46+
@safetestset "Latexify recipes Test" begin include("latexify.jl") end

0 commit comments

Comments
 (0)