Skip to content

Commit 37b8cd1

Browse files
test: add tests for SCCNonlinearProblem codegen
1 parent ab32baa commit 37b8cd1

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed

test/runtests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ end
7575
@safetestset "SDESystem Test" include("sdesystem.jl")
7676
@safetestset "DDESystem Test" include("dde.jl")
7777
@safetestset "NonlinearSystem Test" include("nonlinearsystem.jl")
78+
@safetestset "SCCNonlinearProblem Test" include("scc_nonlinear_problem.jl")z
7879
@safetestset "PDE Construction Test" include("pde.jl")
7980
@safetestset "JumpSystem Test" include("jumpsystem.jl")
8081
@safetestset "print_tree" include("print_tree.jl")

test/scc_nonlinear_problem.jl

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using ModelingToolkit
2+
using NonlinearSolve, SCCNonlinearSolve
3+
using SciMLBase, Symbolics
4+
using LinearAlgebra, Test
5+
6+
@testset "Trivial case" begin
7+
function f!(du, u, p)
8+
du[1] = cos(u[2]) - u[1]
9+
du[2] = sin(u[1] + u[2]) + u[2]
10+
du[3] = 2u[4] + u[3] + 1.0
11+
du[4] = u[5]^2 + u[4]
12+
du[5] = u[3]^2 + u[5]
13+
du[6] = u[1] + u[2] + u[3] + u[4] + u[5] + 2.0u[6] + 2.5u[7] + 1.5u[8]
14+
du[7] = u[1] + u[2] + u[3] + 2.0u[4] + u[5] + 4.0u[6] - 1.5u[7] + 1.5u[8]
15+
du[8] = u[1] + 2.0u[2] + 3.0u[3] + 5.0u[4] + 6.0u[5] + u[6] - u[7] - u[8]
16+
end
17+
prob = NonlinearProblem(f!, zeros(8))
18+
@variables u[1:8] [irreducible = true]
19+
eqs = Any[0 for _ in 1:8]
20+
f!(eqs, u, nothing)
21+
eqs = 0 .~ eqs
22+
@named model = NonlinearSystem(eqs)
23+
@test_throws ["simplified", "required"] SCCNonlinearProblem(model, [])
24+
_model = structural_simplify(model; split = false)
25+
@test_throws ["not compatible"] SCCNonlinearProblem(_model, [])
26+
model = structural_simplify(model)
27+
sccprob = SCCNonlinearProblem(model, [u => zeros(8)])
28+
sol1 = solve(prob, NewtonRaphson())
29+
sol2 = solve(sccprob, NewtonRaphson())
30+
@test SciMLBase.successful_retcode(sol1)
31+
@test SciMLBase.successful_retcode(sol2)
32+
@test sol1.u sol2.u
33+
end
34+
35+
@testset "With parameters" begin
36+
function f!(du, u, (p1, p2), t)
37+
x = (*)(p1[4], u[1])
38+
y = (*)(p1[4], (+)(0.1016, (*)(-1, u[1])))
39+
z1 = ifelse((<)(p2[1], 0),
40+
(*)((*)(457896.07999999996, p1[2]), sqrt((*)(1.1686468413521012e-5, p1[3]))),
41+
0)
42+
z2 = ifelse((>)(p2[1], 0),
43+
(*)((*)((*)(0.58, p1[2]), sqrt((*)(1//86100, p1[3]))), u[4]),
44+
0)
45+
z3 = ifelse((>)(p2[1], 0),
46+
(*)((*)(457896.07999999996, p1[2]), sqrt((*)(1.1686468413521012e-5, p1[3]))),
47+
0)
48+
z4 = ifelse((<)(p2[1], 0),
49+
(*)((*)((*)(0.58, p1[2]), sqrt((*)(1//86100, p1[3]))), u[5]),
50+
0)
51+
du[1] = p2[1]
52+
du[2] = (+)(z1, (*)(-1, z2))
53+
du[3] = (+)(z3, (*)(-1, z4))
54+
du[4] = (+)((*)(-1, u[2]), (*)((*)(1//86100, y), u[4]))
55+
du[5] = (+)((*)(-1, u[3]), (*)((*)(1//86100, x), u[5]))
56+
end
57+
p = ([0.04864391799335977, 7.853981633974484e-5, 1.4034843205574914, 0.018241469247509915, 300237.05, 9.226186337232914], [0.0508])
58+
u0 = [0.0, 0.0, 0.0, 789476.0, 101325.0]
59+
tspan = (0.0, 1.0)
60+
mass_matrix = [1.0 0.0 0.0 0.0 0.0; 0.0 1.0 0.0 0.0 0.0; 0.0 0.0 1.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0]
61+
62+
function nlf(u1, (u0, p))
63+
resid = Any[0 for _ in u0]
64+
f!(resid, u1, p, 0.0)
65+
return mass_matrix*(u1 - u0) - dt*resid
66+
end
67+
68+
prob = NonlinearProblem(nlf, u0, (u0, p))
69+
@test_throws Exception solve(prob, SimpleNewtonRaphson(), abstol = 1e-9)
70+
sol = solve(prob, TrustRegion(); abstol = 1e-9)
71+
72+
@variables u[1:5] [irreducible = true]
73+
@parameters p1[1:6] p2
74+
eqs = 0 .~ collect(nlf(u, (u0, (p1, p2))))
75+
@mtkbuild sys = NonlinearSystem(eqs, [u], [p1, p2])
76+
sccprob = SCCNonlinearProblem(sys, [u => u0], [p1 => p[1], p2 => p[2][]])
77+
sccsol = solve(sccprob, SimpleNewtonRaphson(); abstol = 1e-9)
78+
@test SciMLBase.successful_retcode(sccsol)
79+
@test norm(sccsol.resid) < norm(sol.resid)
80+
end
81+
82+
@testset "Transistor amplifier" begin
83+
C = [k * 1e-6 for k in 1:5]
84+
Ub = 6
85+
UF = 0.026
86+
α = 0.99
87+
β = 1e-6
88+
R0 = 1000
89+
R = 9000
90+
Ue(t) = 0.1 * sin(200 * π * t)
91+
92+
function transamp(out, du, u, p, t)
93+
g(x) = 1e-6 * (exp(x / 0.026) - 1)
94+
y1, y2, y3, y4, y5, y6, y7, y8 = u
95+
out[1] = -Ue(t) / R0 + y1 / R0 + C[1] * du[1] - C[1] * du[2]
96+
out[2] = -Ub / R + y2 * 2 / R -- 1) * g(y2 - y3) - C[1] * du[1] + C[1] * du[2]
97+
out[3] = -g(y2 - y3) + y3 / R + C[2] * du[3]
98+
out[4] = -Ub / R + y4 / R + α * g(y2 - y3) + C[3] * du[4] - C[3] * du[5]
99+
out[5] = -Ub / R + y5 * 2 / R -- 1) * g(y5 - y6) - C[3] * du[4] + C[3] * du[5]
100+
out[6] = -g(y5 - y6) + y6 / R + C[4] * du[6]
101+
out[7] = -Ub / R + y7 / R + α * g(y5 - y6) + C[5] * du[7] - C[5] * du[8]
102+
out[8] = y8 / R - C[5] * du[7] + C[5] * du[8]
103+
end
104+
105+
u0 = [0, Ub / 2, Ub / 2, Ub, Ub / 2, Ub / 2, Ub, 0]
106+
du0 = [
107+
51.338775,
108+
51.338775,
109+
-Ub / (2 * (C[2] * R)),
110+
-24.9757667,
111+
-24.9757667,
112+
-Ub / (2 * (C[4] * R)),
113+
-10.00564453,
114+
-10.00564453
115+
]
116+
daeprob = DAEProblem(transamp, du0, u0, (0.0, 0.1))
117+
daesol = solve(daeprob, DImplicitEuler())
118+
119+
t0 = daesol.t[5]
120+
t1 = daesol.t[6]
121+
u0 = daesol.u[5]
122+
u1 = daesol.u[6]
123+
dt = t1 - t0
124+
125+
@variables y(t)[1:8]
126+
eqs = Any[0 for _ in 1:8]
127+
transamp(eqs, collect(D(y)), y, nothing, t)
128+
eqs = 0 .~ eqs
129+
subrules = Dict(Symbolics.unwrap(D(y[i])) => ((y[i] - u0[i]) / dt) for i in 1:8)
130+
eqs = substitute.(eqs, (subrules,))
131+
@mtkbuild sys = NonlinearSystem(eqs)
132+
prob = NonlinearProblem(sys, [y => u0], [t => t0])
133+
sol = solve(prob, NewtonRaphson(); abstol = 1e-12)
134+
135+
sccprob = SCCNonlinearProblem(sys, [y => u0], [t => t0]);
136+
sccsol = solve(sccprob, NewtonRaphson(); abstol = 1e-12)
137+
138+
@test sol.u sccsol.u atol = 1e-10
139+
end
140+

0 commit comments

Comments
 (0)