Skip to content

Commit 85115e1

Browse files
authored
Merge pull request #721 from SciML/NonlinearSolve_tests
Add tests for NonlinearSolve and NonlinearProblem
2 parents 773d5f6 + 5e71a74 commit 85115e1

File tree

2 files changed

+104
-1
lines changed

2 files changed

+104
-1
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
### Fetch Packages ###
2+
3+
# Fetch packages.
4+
using Catalyst, NonlinearSolve, OrdinaryDiffEq, SteadyStateDiffEq
5+
using Random, Test
6+
7+
# Sets rnd number.
8+
using StableRNGs
9+
rng = StableRNG(12345)
10+
11+
### Run Tests ###
12+
13+
# Creates a simple problem and find steady states just different approaches. Compares to analytic solution.
14+
let
15+
# Model with easily computable steady states.
16+
steady_state_network_1 = @reaction_network begin
17+
(k1, k2), ∅ X1
18+
(k3, k4), ∅ 3X2
19+
(k5, k6), ∅ X3 + X4
20+
end
21+
22+
# Creates NonlinearProblem.
23+
u0 = rand(rng, length(states(steady_state_network_1)))
24+
p = rand(rng, length(parameters(steady_state_network_1)))
25+
nl_prob = NonlinearProblem(steady_state_network_1, u0, p)
26+
27+
# Solves it using standard algorithm and simulation based algorithm.
28+
sol1 = solve(nl_prob; abstol=1e-12, reltol=1e-12).u
29+
sol2 = solve(nl_prob, DynamicSS(Rosenbrock23(); abstol=1e-12, reltol=1e-12); abstol=1e-12, reltol=1e-12).u
30+
31+
# Tests solutions are correct.
32+
@test isapprox(sol1[1], p[1] / p[2]; atol=1e-10)
33+
@test isapprox(sol1[2]^3 / factorial(3), p[3] / p[4]; atol=1e-10)
34+
@test isapprox(sol1[3] * sol1[4], p[5] / p[6]; atol=1e-10)
35+
@test isapprox(sol2[1], p[1] / p[2]; atol=1e-10)
36+
@test isapprox(sol2[2]^3 / factorial(3), p[3] / p[4]; atol=1e-10)
37+
@test isapprox(sol2[3] * sol2[4], p[5] / p[6]; atol=1e-10)
38+
end
39+
40+
# Creates a system with multiple steady states.
41+
# Checks that corresponding ODEFunction return 0.0 in both cases. Checks for manually computed function as well.
42+
# Checks with SYmbol `u0` and Symbolic `p`.
43+
let
44+
# Creates steady state network, unpack the parameter values.
45+
steady_state_network_2 = @reaction_network begin
46+
v / 10 + hill(X, v, K, n), ∅ X
47+
d, X
48+
end
49+
@unpack v, K, n, d = steady_state_network_2
50+
51+
# Creates NonlinearProblem.
52+
u0 = [:X => 1.0]
53+
p = [v => 1.0 + rand(rng), K => 0.8, n => 3, d => 1.0]
54+
nl_prob = NonlinearProblem(steady_state_network_2, u0, p)
55+
56+
# Solves it using standard algorithm and simulation based algorithm.
57+
sol1 = solve(nl_prob; abstol=1e-12, reltol=1e-12).u
58+
sol2 = solve(nl_prob, DynamicSS(Rosenbrock23(); abstol=1e-12, reltol=1e-12); abstol=1e-12, reltol=1e-12).u
59+
60+
# Computes NonlinearFunction (manually and automatically).
61+
nfunc = NonlinearFunction(convert(NonlinearSystem, steady_state_network_2))
62+
function nf_manual(u,p)
63+
X = u[1]
64+
v, K, n, d = p
65+
return v/10 + v * X^n/(X^n + K^n) - d*X
66+
end
67+
68+
# Tests solutions are correct.
69+
@test isapprox(nfunc(sol1, last.(p))[1], 0.0; atol=1e-10)
70+
@test isapprox(nfunc(sol2, last.(p))[1], 0.0; atol=1e-10)
71+
@test isapprox(nf_manual(sol1, last.(p)), 0.0; atol=1e-10)
72+
@test isapprox(nf_manual(sol2, last.(p)), 0.0; atol=1e-10)
73+
end
74+
75+
# Checks for system with conservation laws.
76+
# Checks using interfacing with output solution.
77+
let
78+
# Creates steady state network, unpack the parameter values.
79+
steady_state_network_3 = complete(@reaction_network begin
80+
(p,d), 0 <--> X
81+
(k1, k2), 2Y <--> Y2
82+
(k3, k4), X + Y2 <--> XY2
83+
end)
84+
@unpack X, Y, Y2, XY2 = steady_state_network_3
85+
86+
# Creates NonlinearProblem.
87+
u0 = [steady_state_network_3.X => rand(), steady_state_network_3.Y => rand() + 1.0, steady_state_network_3.Y2 => rand() + 3.0, steady_state_network_3.XY2 => 0.0]
88+
p = [:p => rand()+1.0, :d => 0.5, :k1 => 1.0, :k2 => 2.0, :k3 => 3.0, :k4 => 4.0]
89+
nl_prob_1 = NonlinearProblem(steady_state_network_3, u0, p; remove_conserved = true)
90+
nl_prob_2 = NonlinearProblem(steady_state_network_3, u0, p)
91+
92+
# Solves it using standard algorithm and simulation based algorithm.
93+
sol1 = solve(nl_prob_1; abstol=1e-12, reltol=1e-12)
94+
sol2 = solve(nl_prob_2, DynamicSS(Rosenbrock23(); abstol=1e-12, reltol=1e-12); abstol=1e-12, reltol=1e-12)
95+
96+
# Checks output using NonlinearFunction.
97+
nfunc = NonlinearFunction(convert(NonlinearSystem, steady_state_network_3))
98+
@test isapprox(nfunc([sol1[X], sol1[Y], sol1[Y2], sol1[XY2]], last.(p)), [0.0, 0.0, 0.0, 0.0]; atol=1e-10)
99+
@test isapprox(nfunc([sol2[X], sol2[Y], sol2[Y2], sol2[XY2]], last.(p)), [0.0, 0.0, 0.0, 0.0]; atol=1e-10)
100+
end

test/runtests.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,16 @@ using SafeTestsets
1414
@time @safetestset "Custom CRN Functions" begin include("dsl/custom_functions.jl") end
1515
@time @safetestset "DSL Options" begin include("dsl/dsl_options.jl") end
1616

17-
### Non-DSL model cration and modication. ###
17+
### Non-DSL model creation and modification. ###
1818
@time @safetestset "ReactionSystem Components Based Creation" begin include("programmatic_model_creation/component_based_model_creation.jl") end
1919
@time @safetestset "Programmatic Model Expansion" begin include("programmatic_model_creation/programmatic_model_expansion.jl") end
2020

2121
# Runs various miscellaneous tests.
2222
@time @safetestset "API" begin include("miscellaneous_tests/api.jl") end
2323
@time @safetestset "Symbolic Stoichiometry" begin include("miscellaneous_tests/symbolic_stoichiometry.jl") end
24+
if VERSION >= v"1.9"
25+
@time @safetestset "NonlinearProblems and Steady State Solving" begin include("miscellaneous_tests/nonlinear_solve.jl") end
26+
end
2427
@time @safetestset "Events" begin include("miscellaneous_tests/events.jl") end
2528
@time @safetestset "Compound species" begin include("miscellaneous_tests/compound_macro.jl") end
2629
@time @safetestset "Reaction balancing" begin include("miscellaneous_tests/reaction_balancing.jl") end

0 commit comments

Comments
 (0)