-
-
Notifications
You must be signed in to change notification settings - Fork 27
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Robertson problem #67
Comments
Yes, I noticed this awhile ago but forgot to document it. There's a few things that can be happening. First of all, we don't actually know that the stability of the Rosenbrock methods are like when applied to DDEs. I think there's some concepts like Q-stability and nothing is fully Q-stable, so it would be an interesting analysis to see what kind of stability we actually get. It sounds like it's quite good for most "stiff DDEs" (from my tests as well), but you can break it if you try hard enough. Another thing to note is that our extrapolation method could reduce stability. Functional iteration is not used in stiff ODE solvers because of this property. Anderson acceleration can help, but Newton's method is much more stable. With our generic method of steps we cannot take into account a full Newton on every step including the extrapolation, so that is one issue we do have that RADAR5 doesn't. I'm not sure how much this matters though, and the fact that RADAR5 is solving such a large nonlinear system is a huge cost burden so there is a tradeoff. Another thing we might want to look into is the extrapolation over discontinuities. When extrapolating over a discontinuity, the calculation becomes incorrect because of that discontinuity in the interval effecting the interpolation result. I think one of the papers we've looked at before suggested doing something like:
The reason here is that then less of the estimate uses the values past the discontinuity so it gives a more accurate answer. I'm not sure if that could be affecting us here, but it would be good to open an issue to investigate it. These last two points can be eliminated with constrained stepping though. If constrained stepping still is unstable, then it is likely just a property of the Rosenbrock integrator. But the interesting thing is:
No it's not. That looks correct. You can even check it with: sol = solve(prob_dde_rober1, MethodOfSteps(Rosenbrock23()); abstol=1e-8,reltol=1e-8,initial_order = 1)
sol2 = solve(prob_dde_rober1, MethodOfSteps(Tsit5()); abstol=1e-8,reltol=1e-8,initial_order = 1)
sol2[end] - sol(sol2.t[end]) So it's just exiting early. The Runge-Kutta methods at extremely high accuracy (with bigfloats) should be able to calculate the solution correctly and not have any stability issues just by using a small prob_dde_rober2_big = DDEProblem(f_dde_rober2, big.([1.0, 0.0, 0.0]), h_dde_rober,
big.((0.0, 1e5));
constant_lags = [1e-2])
sol = solve(prob_dde_rober2_big, MethodOfSteps(Tsit5()); abstol=1e-20,reltol=1e-20,initial_order = 1)
Float64(sol.t[end])
sol = solve(prob_dde_rober2_big,
MethodOfSteps(Rosenbrock23(linsolve=LinSolveFactorize(qrfact!)));
abstol=1e-12,reltol=1e-12,initial_order = 1)
Float64(sol.t[end]) and get a definitive answer and double check that As a side note, I know that maybe a 6 months from now @YingboMa will want to do fully implicit RK methods in OrdinaryDiffEq, in which case we should make sure we get a full RADAR5 implementation to see for ourselves how well it can do. |
We should also check with autodiff=false. |
Ah, of course. Don't know why I didn't notice that |
Interestingly, RADAR5 only estimates discontinuity points if
|
Interesting. To fix the issue, they:
|
As I mentioned above, Hairer and Guglielmi computed this value for a delay of 3e-2, and not for problem function f_dde_rober3(du, u, h, p, t)
# compute repeating terms
x = 4e-2 * u[1]
y = 1e4 * h(p, t - 3e-2; idxs = 2) * u[3]
z = 3e7 * u[2] * u[2]
# compute derivatives
du[1] = y - x
du[2] = x - y - z
du[3] = z
nothing
end
prob_dde_rober3_big = DDEProblem(f_dde_rober3, big.([1.0, 0.0, 0.0]), h_dde_rober,
big.((0.0, 1e5));
constant_lags = [3e-2])
sol1 = solve(prob_dde_rober3_big, MethodOfSteps(Tsit5()); initial_order = 1,
abstol = 1e-20, reltol = 1e-20)
Float64(sol1.t[end])
sol2 = solve(prob_dde_rober3_big,
MethodOfSteps(Rosenbrock23(linsolve=LinSolveFactorize(qrfact!)));
initial_order = 1, abstol = 1e-12, reltol = 1e-12)
Float64(sol2.t[end]) |
I could reproduce the instability for constrained stepping as well: sol = solve(prob_dde_rober2, MethodOfSteps(Rosenbrock23(); constrained=true);
initial_order = 1)
plot(sol) sol = solve(prob_dde_rober2, MethodOfSteps(Rodas5(); constrained=true); initial_order = 1)
plot(sol) |
The algorithms are unstable with finite differencing as well: sol = solve(prob_dde_rober2, MethodOfSteps(Rosenbrock23(; autodiff = false));
initial_order = 1) sol = solve(prob_dde_rober2, MethodOfSteps(Rodas5(; autodiff = false)); initial_order = 1) And finite differencing with constrained stepping: sol = solve(prob_dde_rober2, MethodOfSteps(Rosenbrock23(; autodiff = false); constrained=true);
initial_order = 1) sol = solve(prob_dde_rober2, MethodOfSteps(Rodas5(; autodiff = false); constrained=true);
initial_order = 1) |
I'm running a really refined RK right now to double check some things. Can you run an SDIRK like |
Unfortunately, using TRBDF2 does not help: sol = solve(prob_dde_rober2, MethodOfSteps(TRBDF2());
initial_order = 1) sol = solve(prob_dde_rober2, MethodOfSteps(TRBDF2(); constrained = true));
initial_order = 1) sol = solve(prob_dde_rober2, MethodOfSteps(TRBDF2(; autodiff = false));
initial_order = 1) sol = solve(prob_dde_rober2, MethodOfSteps(TRBDF2(; autodiff = false); constrained = true);
initial_order = 1) |
sol1 = solve(prob_dde_rober3_big, MethodOfSteps(Tsit5()); initial_order = 1,
abstol = 1e-28, reltol = 1e-28, maxiters = 1e7,
unstable_check = (dt,u,p,t) -> abs(u[3])>1e2
)
Float64(maximum(diff(sol1.t))) # 3.750184086763931e-5
Float64(sol1.t[end]) 11.25522208749271 and exited due to stability. So there likely is an instability right around there. Hmm. |
Hmm it's really strange that we can not verify the instability around 16.8. |
Maybe it could be due to not using a residual control? |
I ran RADAR5 on this problem with a delay of 0.03 (which should explode according to Hairer and Guglielmi) and could compute a reasonable solution on the whole interval [0.0, 1e11]. So I assume the publication might be incorrect and the problem might not be unstable for this delay. However, using a delay of 0.3 RADAR5 exits at around 15.5... |
I wonder if we can save out values of the history function and plot that just to make sure those are following the true trajectory. I think there may be a bug in here. Check OrdinaryDiffEq: using OrdinaryDiffEq
function f_rober2(du, u, p, t)
# compute repeating terms
x = 4e-2 * u[1]
y = 1e4 * u[2] * u[3]
z = 3e7 * u[2] * u[2]
# compute derivatives
du[1] = y - x
du[2] = x - y - z
du[3] = z
nothing
end
prob_ode_rober2 = ODEProblem(f_rober2, [1.0, 0.0, 0.0], (0.0, 1e5))
sol = solve(prob_ode_rober2,Rosenbrock23()) which works. However, using DelayDiffEq
function f_dde_rober2(du, u, h, p, t)
# compute repeating terms
x = 4e-2 * u[1]
y = 1e4 * h(p, t-1e-16)[2] * u[3]
z = 3e7 * u[2] * u[2]
# compute derivatives
du[1] = y - x
du[2] = x - y - z
du[3] = z
nothing
end
h_dde_rober(p, t) = zeros(3)
prob_dde_rober2 = DDEProblem(f_dde_rober2, [1.0, 0.0, 0.0], h_dde_rober,
(0.0, 1e5);
constant_lags = [1e-2])
sol = solve(prob_dde_rober2,MethodOfSteps(Rosenbrock23())) fails with maxiters. Checking: function f_dde_rober4(du, u, h, p, t)
# compute repeating terms
x = 4e-2 * u[1]
y = 1e4 * h(p, t-1e-16)[2] * u[3]
z = 3e7 * u[2] * u[2]
@show h(p, t-1e-16)[2] - u[2]
# compute derivatives
du[1] = y - x
du[2] = x - y - z
du[3] = z
nothing
end
h_dde_rober(p, t) = zeros(3)
prob_dde_rober2 = DDEProblem(f_dde_rober4, [1.0, 0.0, 0.0], h_dde_rober,
(0.0, 1e5))
sol = solve(prob_dde_rober2,MethodOfSteps(Rosenbrock23(),constrained=true),maxiters=1000) gives things like: (h(p, t - 1.0e-16))[2] - u[2] = 2.2215283979943968e-5
(h(p, t - 1.0e-16))[2] - u[2] = 6.0901529403518086e-5
(h(p, t - 1.0e-16))[2] - u[2] = 0.0
(h(p, t - 1.0e-16))[2] - u[2] = 5.041613513194181e-7
(h(p, t - 1.0e-16))[2] - u[2] = -1.360253148542067e-5
(h(p, t - 1.0e-16))[2] - u[2] = 0.0
(h(p, t - 1.0e-16))[2] - u[2] = -9.044269046495332e-7
(h(p, t - 1.0e-16))[2] - u[2] = -8.82513835403601e-7 while on the ODE solution, doing stuff like So it sounds to me like there may be a problem with the history values. |
Now he's something that's interesting: function f_dde_rober4(du, u, h, p, t)
# compute repeating terms
x = 4e-2 * u[1]
y = 1e4 * h(p, t-1e-16)[2] * u[3]
z = 3e7 * u[2] * u[2]
@show h(p, t-1e-16)[2] - u[2]
# compute derivatives
du[1] = y - x
du[2] = x - y - z
du[3] = z
nothing
end
h_dde_rober(p, t) = zeros(3)
prob_dde_rober2 = DDEProblem(f_dde_rober4, [1.0, 0.0, 0.0], h_dde_rober,
(0.0, 1e5))
sol = solve(prob_dde_rober2,MethodOfSteps(Rodas5(autodiff=false)),dt=1e-2) (h(p, t - 1.0e-16))[2] - u[2] = -6.0554544523933395e-6
(h(p, t - 1.0e-16))[2] - u[2] = 6.0554544523933395e-6
(h(p, t - 1.0e-16))[2] - u[2] = 0.0
(h(p, t - 1.0e-16))[2] - u[2] = 0.0
(h(p, t - 1.0e-16))[2] - u[2] = -0.00015198844887788534
(h(p, t - 1.0e-16))[2] - u[2] = 0.001216570117719098
(h(p, t - 1.0e-16))[2] - u[2] = -0.07309512770559262
(h(p, t - 1.0e-16))[2] - u[2] = 87.69690577013398
(h(p, t - 1.0e-16))[2] - u[2] = 1.0578873888263168e10
(h(p, t - 1.0e-16))[2] - u[2] = 6.379016646395286e24
(h(p, t - 1.0e-16))[2] - u[2] = 2.3194356423743255e54
(h(p, t - 1.0e-16))[2] - u[2] = 3.0664755684963483e113
(h(p, t - 1.0e-16))[2] - u[2] = 0.0
(h(p, t - 1.0e-16))[2] - u[2] = 2.525568517554205e231
(h(p, t - 1.0e-16))[2] - u[2] = 2.5976895522572776e231
(h(p, t - 1.0e-16))[2] - u[2] = 3.348148356188627e231
(h(p, t - 1.0e-16))[2] - u[2] = NaN
(h(p, t - 1.0e-16))[2] - u[2] = NaN
(h(p, t - 1.0e-16))[2] - u[2] = NaN
(h(p, t - 1.0e-16))[2] - u[2] = NaN it goes out of control? |
I think it's highlighting that we're not handling step rejections properly? It seems we |
That might very well be the case... I already assumed something along those lines when I got |
That test case was bad because it requires using the isout handling. However, I am narrowing down a bug which is requiring isout when dt is constrained to be smaller than the delay size, and that is for sure an issue. |
On the using DelayDiffEq
function f_dde_rober4(du, u, h, p, t)
# compute repeating terms
x = 4e-2 * u[1]
y = 1e4 * h(p, t-1e-4)[2] * u[3]
z = 3e7 * u[2] * u[2]
# compute derivatives
du[1] = y - x
du[2] = x - y - z
du[3] = z
nothing
end
h_dde_rober(p, t) = zeros(3)
prob_dde_rober2 = DDEProblem(f_dde_rober4, [1.0, 0.0, 0.0], h_dde_rober,
(0.0, 1e5))
sol = solve(prob_dde_rober2,MethodOfSteps(Rodas5(autodiff=false)),dt=5e-5,dtmax=5e-5) and after quite awhile, I get that the history function goes beyond "here2" = "here2"
integrator.dt = 5.0e-5
integrator.sol.t[end] = 16.513999999986442
integrator.integrator.sol.t[end] = 16.513999999986442
"out of perform step" = "out of perform step"
"here2" = "here2"
integrator.dt = 5.0e-5
integrator.sol.t[end] = 16.514049999986444
integrator.integrator.sol.t[end] = 16.514049999986444
f.sol.t[end] = 16.514049999986444
t = 16.514050000064042 |
Nevermind. That "bug" was just because finite differencing went too far. |
I started playing around a bit more with stiff DDEs, and think www.unige.ch/~hairer/radar5-v2.1.tar and accompanying publications contain some nice examples (which should be added to DiffEqProblemLibrary as well, I guess).
However, my first tests show that there are some problems with stiff problems. The first problem is a modified Robertson problem, taken from "The numerical integration of stiff delay differential equations" by Guglielmi; I only changed the integration interval from [0.0, 1e9] to [0.0, 1e5] since otherwise
maxiters
has to be increased (maybe the number of iterations could be reduced in general by changing some defaults?):Using
Tsit5
integrations is stopped at aroundt = 627
since the maximal number of iterations is reached, and the solution is wrong as the following plot shows:Using
Rosenbrock23
a solution is computed on the whole integration interval:This solution shows the expected dynamics; moreover, it indicates that the stiff solvers work in principle and are quite performant since according to Guglielmi "RADAR5 is the only code able to correctly integrate the above very stiff problem" out of the solvers he considered.
Interestingly, both in Guglielmi and Hairer's "Implementing Radau IIA methods for stiff delay differential equations" and as example problem in the RADAR5 package a different Robertson problem is mentioned (here again on a reduced integration interval):
For this problem, however,
Rosenbrock23
computes a solution only on [0.0, 6.14] since the time steps become too small:Similar dynamics can be observed with
Rodas5
, although in this case integration stops because of instability (i.e.NaN
values):Using absolute and relative tolerances that are mentioned in Guglielmi and Hairer's publication I can provoke the same explosions as before at a slightly later time point:
According to Guglielmi and Hairer, with a delay of 3e-2 the second component of this problem oscillates and then explodes at around t = 16.8.
I managed to compile and run RADAR5 and the contained Robertson example on my computer; RADAR5 successfully computed a solution on the interval [0.0, 1e10]. Even though I have no experience with Fortran I studied the implementation of the problem to check whether the implementation corresponds to the stated DDE; hereby I noticed that Guglielmi and Hairer apparently used slightly different default parameters in their implementation (tau = 1e-3, reltol = 1e-9, abstol = 1e-14, and an integration interval of [0.0, 1e11]) but I could still compute a correct solution after changing these values to the ones stated above.
I do not know why DelayDiffEq does not compute a correct solution for the second problem. I'm also surprised that Rodas5 with default settings returns
NaN
values; I assumed this could (and should) not happen since then the time step should be decreased... I also played around with the number of fixed point iterations; settingforce_dtmin = true
in the last example resulted inNaN
values as well. Are there any settings I could tune? Do you have any ideas why RADAR5 can solve this problem whereas I could not compute a solution with DelayDiffEq?The text was updated successfully, but these errors were encountered: