Skip to content

Commit 754b504

Browse files
ChrisRackauckas-ClaudeChrisRackauckasclaude
authored
Add Rodas3d: L-stable stiffly accurate Rosenbrock method for steady-state DAE integration (#3931)
Adds the 4-stage 3rd-order (2nd-order embedded) stiffly accurate Rosenbrock method from Yu et al., arXiv:2312.02809, constructed for the semi-implicit Continuous Newton method (SciML/NonlinearSolve.jl#330). The damping parameter γ = 0.57281606 gives R(±∞) = 0 so both stable and unstable modes are damped, and is a root of the 4th-order linear order condition, so the method is additionally 4th order on linear problems. Coefficients come from the authors' reference implementation (github.com/rzyu45/MATPOWER-SICNM) and were verified against all order conditions stated in the paper; the transformation to the RodasTableau convention was computed in BigFloat and cross-checked against an independent implementation of the paper's untransformed scheme. The companion SciML/SteadyStateDiffEq.jl PR adds the SICNM nonlinear solver that uses this method. Claude-Session: https://claude.ai/code/session_01NNigabD3sZaUKvDZ1NVQgv Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent 081bf79 commit 754b504

17 files changed

Lines changed: 100 additions & 12 deletions

docs/src/massmatrixdae/Rosenbrock.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ Rosenbrock23
129129
Rosenbrock32
130130
ROS3P
131131
Rodas3
132+
Rodas3d
132133
Rodas23W
133134
Rodas3P
134135
Rodas4

docs/src/semiimplicit/Rosenbrock.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ Rosenbrock23
7272
Rosenbrock32
7373
ROS3P
7474
Rodas3
75+
Rodas3d
7576
Rodas23W
7677
Rodas3P
7778
Rodas4

lib/OrdinaryDiffEqRosenbrock/Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "OrdinaryDiffEqRosenbrock"
22
uuid = "43230ef6-c299-4910-a778-202eb28ce4ce"
3-
version = "2.4.2"
3+
version = "2.5.0"
44
authors = ["ParamThakkar123 <paramthakkar864@gmail.com>"]
55

66
[deps]

lib/OrdinaryDiffEqRosenbrock/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ While completely independent and usable on its own, users wanting the full ODE s
1515
- `Rosenbrock32`
1616
- `RosShamp4`
1717
- `Rodas3`
18+
- `Rodas3d`
1819
- `Rodas4`
1920
- `Rodas4P`
2021
- `Rodas5`

lib/OrdinaryDiffEqRosenbrock/src/OrdinaryDiffEqRosenbrock.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ using OrdinaryDiffEqRosenbrockTableaus: OrdinaryDiffEqRosenbrockTableaus,
4040
ROS2SRodasTableau, ROS34PRwRodasTableau, ROS34PW1aRodasTableau,
4141
ROS34PW1bRodasTableau, ROS34PW2RodasTableau, ROS3PRL2RodasTableau,
4242
ROS3PRLRodasTableau, ROS3PRRodasTableau, ROS3PRodasTableau, ROS3RodasTableau,
43-
Rodas3PRodasTableau, Rodas3RodasTableau, Rodas42Tableau, Rodas4P2Tableau,
43+
Rodas3PRodasTableau, Rodas3RodasTableau, Rodas3dRodasTableau, Rodas42Tableau, Rodas4P2Tableau,
4444
Rodas4PTableau, Rodas4PWTableau, Rodas4Tableau, Rodas5Tableau, RodasTableau,
4545
Ros4LStabRodasTableau, RosShamp4RodasTableau, RosenbrockW6S4OSRodasTableau,
4646
Scholz4_7RodasTableau, Veldd4RodasTableau, Velds4RodasTableau
@@ -209,7 +209,7 @@ PrecompileTools.@compile_workload begin
209209
end
210210

211211
export Rosenbrock23, Rosenbrock32, RosShamp4, Veldd4, Velds4, GRK4T, GRK4A,
212-
Ros4LStab, ROS3P, Rodas3, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2,
212+
Ros4LStab, ROS3P, Rodas3, Rodas3d, Rodas23W, Rodas3P, Rodas4, Rodas42, Rodas4P, Rodas4P2,
213213
Rodas4PW, Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, Rodas6P, HybridExplicitImplicitRK,
214214
Tsit5DA, RosenbrockW6S4OS, ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3, ROS34PRw,
215215
ROS3PRL, ROS3PRL2, ROK4a,

lib/OrdinaryDiffEqRosenbrock/src/alg_utils.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ alg_order(alg::ROS3PRL) = 3
66
alg_order(alg::ROS3PRL2) = 3
77
alg_order(alg::ROS3P) = 3
88
alg_order(alg::Rodas3) = 3
9+
alg_order(alg::Rodas3d) = 3
910
alg_order(alg::Rodas23W) = 3
1011
alg_order(alg::ROS2) = 2
1112
alg_order(alg::ROS2PR) = 2

lib/OrdinaryDiffEqRosenbrock/src/algorithms.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ for (Alg, desc, refs, is_W) in [
2626
"- Sandu, Verwer, Van Loon, Carmichael, Potra, Dabdub, Seinfeld, Benchmarking stiff ode solvers for atmospheric chemistry problems-I. \n implicit vs explicit, Atmospheric Environment, 31(19), 3151-3166, 1997.",
2727
false,
2828
),
29+
(
30+
:Rodas3d,
31+
"3rd order L-stable stiffly accurate Rosenbrock method with a 2nd order embedded method,\nconstructed with damping parameter γ = 0.57281606 so that R(±∞) = 0 (damps both stable and\nunstable modes). Since this γ is a root of the 4th-order linear order condition, the method\nis 4th order on linear problems. Designed for steady-state focused DAE integration such as\nthe semi-implicit continuous Newton method, where fast damping toward the equilibrium\nmatters more than trajectory accuracy.",
32+
"- Yu, R., Gu, W., Xu, Y., Lu, S. (2024). Semi-implicit Continuous Newton Method\n for Power Flow Analysis. arXiv:2312.02809. https://arxiv.org/abs/2312.02809",
33+
false,
34+
),
2935
(
3036
:Rodas23W,
3137
"An Order 2/3 L-Stable Rosenbrock-W method for stiff ODEs and DAEs in mass matrix form. 2nd order stiff-aware interpolation and additional error test for interpolation.",

lib/OrdinaryDiffEqRosenbrock/src/rosenbrock_caches.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ end
408408
_get_step_limiter(alg) = trivial_limiter!
409409
_get_stage_limiter(alg) = trivial_limiter!
410410
for Alg in (
411-
:Rosenbrock23, :Rosenbrock32, :ROS3P, :Rodas3, :Rodas23W, :Rodas3P,
411+
:Rosenbrock23, :Rosenbrock32, :ROS3P, :Rodas3, :Rodas3d, :Rodas23W, :Rodas3P,
412412
:Rodas4, :Rodas42, :Rodas4P, :Rodas4P2, :Rodas4PW, :Rodas5,
413413
:Rodas5P, :Rodas5Pe, :Rodas5Pr, :Rodas6P,
414414
)
@@ -431,6 +431,7 @@ tabtype(::Rodas6P) = Rodas6PTableau
431431
# Consolidated methods: tableau type dispatch
432432
tabtype(::ROS3P) = ROS3PRodasTableau
433433
tabtype(::Rodas3) = Rodas3RodasTableau
434+
tabtype(::Rodas3d) = Rodas3dRodasTableau
434435
tabtype(::Rodas3P) = Rodas3PRodasTableau
435436
tabtype(::Rodas23W) = Rodas23WRodasTableau
436437
tabtype(::ROS2) = ROS2RodasTableau
@@ -459,7 +460,7 @@ tabtype(::RosenbrockW6S4OS) = RosenbrockW6S4OSRodasTableau
459460
const RodasTableauAlgorithms = Union{
460461
Rodas4, Rodas42, Rodas4P, Rodas4P2, Rodas4PW,
461462
Rodas5, Rodas5P, Rodas5Pe, Rodas5Pr, Rodas6P,
462-
ROS3P, Rodas3, Rodas3P, Rodas23W,
463+
ROS3P, Rodas3, Rodas3d, Rodas3P, Rodas23W,
463464
ROS2, ROS2PR, ROS2S, ROS3, ROS3PR, Scholz4_7,
464465
ROS34PW1a, ROS34PW1b, ROS34PW2, ROS34PW3,
465466
ROS34PRw, ROS3PRL, ROS3PRL2, ROK4a,

lib/OrdinaryDiffEqRosenbrock/test/ode_rosenbrock_tests.jl

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,38 @@ end
159159
end
160160

161161

162+
println("Rodas3d")
163+
164+
# Rodas3d's damping parameter γ = 0.57281606 is a root of the 4th-order
165+
# linear order condition (an endpoint of the L-stability interval in
166+
# Hairer & Wanner Table 6.4), so the method superconverges at order 4 on
167+
# linear problems; the design order 3 is checked on a nonlinear problem below.
168+
prob = prob_ode_linear
169+
170+
sim = test_convergence(dts, prob, Rodas3d())
171+
@test sim.𝒪est[:final] 4 atol = testTol
172+
173+
sol = solve(prob, Rodas3d())
174+
@test length(sol.t) < 20
175+
@test SciMLBase.successful_retcode(sol)
176+
177+
prob = prob_ode_2Dlinear
178+
179+
sim = test_convergence(dts, prob, Rodas3d())
180+
@test sim.𝒪est[:final] 4 atol = testTol
181+
182+
sol = solve(prob, Rodas3d())
183+
@test length(sol.t) < 20
184+
@test SciMLBase.successful_retcode(sol)
185+
186+
prob = ODEProblem(
187+
(u, p, t) -> [-2u[1] + u[2]^2, -u[2] + sin(u[1]) + 0.1t],
188+
[1.0, 0.5], (0.0, 1.0)
189+
)
190+
test_setup = Dict(:alg => Rodas4(), :reltol => 1.0e-13, :abstol => 1.0e-13)
191+
sim = analyticless_test_convergence((1 / 2) .^ (7:-1:4), prob, Rodas3d(), test_setup)
192+
@test sim.𝒪est[:final] 3 atol = testTol
193+
162194
println("Rodas5P")
163195

164196
prob = prob_ode_linear
@@ -418,7 +450,7 @@ end
418450
# interpolation errors orders of magnitude larger than the knot errors.
419451
for (method, expected_interp) in (
420452
(Rodas4P, 1.0e-10), (ROS34PW2, 5.0e-2),
421-
(ROS34PW3, 5.0e-2), (Rodas3, 5.0e-2),
453+
(ROS34PW3, 5.0e-2), (Rodas3, 5.0e-2), (Rodas3d, 5.0e-2),
422454
)
423455
sol = solve(prob, method(); dense = true, reltol = 1.0e-4, abstol = 1.0e-4)
424456
err_knot = maximum(abs.(sol[1, :] .- anasol(sol.t, p)))

lib/OrdinaryDiffEqRosenbrock/test/qa/Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
AllocCheck = "9b6a8646-10ed-4001-bbdc-1d2f46dfbb1a"
33
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
44
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
5+
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
56
OrdinaryDiffEqCore = "bbf590c4-e513-4bbe-9b18-05decba2e5d8"
67
OrdinaryDiffEqRosenbrock = "43230ef6-c299-4910-a778-202eb28ce4ce"
78
SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
89
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
910
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
1011

11-
[sources.OrdinaryDiffEqCore]
12-
path = "../../../OrdinaryDiffEqCore"
12+
[sources]
13+
OrdinaryDiffEqCore = {path = "../../../OrdinaryDiffEqCore"}
1314

1415
[compat]
1516
AllocCheck = "0.2"

0 commit comments

Comments
 (0)