|
1 | 1 | using OrdinaryDiffEqBDF, OrdinaryDiffEqSDIRK |
2 | 2 | using OrdinaryDiffEqNonlinearSolve |
3 | 3 | using OrdinaryDiffEqNonlinearSolve: NonlinearSolveAlg |
4 | | -using NonlinearSolve: NewtonRaphson |
| 4 | +using NonlinearSolve: NewtonRaphson, TrustRegion |
5 | 5 | using ADTypes, LinearAlgebra, SciMLBase |
6 | 6 | using Test |
7 | 7 |
|
@@ -48,3 +48,30 @@ refsol = solve(prob, FBDF(); reltol = 1.0e-12, abstol = 1.0e-14) |
48 | 48 | @test JAC_CALLS[] >= 1 |
49 | 49 | end |
50 | 50 | end |
| 51 | + |
| 52 | +@testset "globalized inner solver does not converge on a rejected step" begin |
| 53 | + # A TrustRegion step that is rejected/truncated leaves the iterate nearly |
| 54 | + # unmoved, which the outer displacement test alone reads as convergence — the |
| 55 | + # stage is then accepted with no correction applied (#3817). Driven at a dt |
| 56 | + # that is far too coarse for the Robertson transient, so the inner solves |
| 57 | + # genuinely cannot converge and the failure must be reported rather than |
| 58 | + # silently absorbed. |
| 59 | + nsa_tr = NonlinearSolveAlg(TrustRegion(; autodiff = AutoForwardDiff())) |
| 60 | + nsa_nr = NonlinearSolveAlg(NewtonRaphson(; autodiff = AutoForwardDiff())) |
| 61 | + hard = ODEProblem(f, [1.0, 0.0, 0.0], (0.0, 1.0e3), [0.04, 3.0e7, 1.0e4]) |
| 62 | + |
| 63 | + sol_tr = solve(hard, FBDF(nlsolve = nsa_tr); dt = 1.0, adaptive = false) |
| 64 | + sol_nr = solve(hard, FBDF(nlsolve = nsa_nr); dt = 1.0, adaptive = false) |
| 65 | + |
| 66 | + # The state must not be reported as a successful solve while frozen at u0. |
| 67 | + @test !(SciMLBase.successful_retcode(sol_tr) && sol_tr.u[end] == hard.u0) |
| 68 | + # TrustRegion must reach the same verdict as the non-globalized inner solver. |
| 69 | + @test SciMLBase.successful_retcode(sol_tr) == SciMLBase.successful_retcode(sol_nr) |
| 70 | +end |
| 71 | + |
| 72 | +@testset "TrustRegion matches NewtonRaphson when the solves do converge" begin |
| 73 | + nsa_tr = NonlinearSolveAlg(TrustRegion(; autodiff = AutoForwardDiff())) |
| 74 | + sol = solve(prob, FBDF(nlsolve = nsa_tr); reltol = 1.0e-8, abstol = 1.0e-10) |
| 75 | + @test SciMLBase.successful_retcode(sol) |
| 76 | + @test norm(sol.u[end] .- refsol.u[end]) / norm(refsol.u[end]) < 1.0e-4 |
| 77 | +end |
0 commit comments