Skip to content

Commit 483d62a

Browse files
committed
Fix incorrect interpolant evaluation
1 parent e1ee0a9 commit 483d62a

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

lib/BoundaryValueDiffEqMIRK/src/adaptivity.jl

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ After we construct an interpolant, we use interp_eval to evaluate it.
77
i = interval(mesh, t)
88
dt = mesh_dt[i]
99
τ = (t - mesh[i]) / dt
10-
w, w′ = interp_weights(τ, cache.alg)
10+
w, _ = interp_weights(τ, cache.alg)
1111
sum_stages!(y, cache, w, i, dt)
1212
return y
1313
end
@@ -626,32 +626,35 @@ function sum_stages!(cache::MIRKCache{iip, T, use_both, NoDiffCacheNeeded}, w,
626626
sum_stages!(cache.fᵢ_cache, cache.fᵢ₂_cache, cache, w, w′, i, dt)
627627
end
628628

629+
# Here we should not directly in-place change z in several steps
630+
# because in final step we actually need to use the original z(which is cache.y₀.u[i])
631+
# we use fᵢ₂_cache to avoid additional allocations.
629632
function sum_stages!(z::AbstractArray, cache::MIRKCache{iip, T, use_both, DiffCacheNeeded},
630633
w, i::Int, dt = cache.mesh_dt[i]) where {iip, T, use_both}
631-
(; stage, k_discrete, k_interp) = cache
634+
(; stage, k_discrete, k_interp, fᵢ₂_cache) = cache
632635
(; s_star) = cache.ITU
633636

634-
z .= zero(z)
635-
__maybe_matmul!(z, k_discrete[i].du[:, 1:stage], w[1:stage])
637+
fᵢ₂_cache .= zero(z)
638+
__maybe_matmul!(fᵢ₂_cache, k_discrete[i].du[:, 1:stage], w[1:stage])
636639
__maybe_matmul!(
637-
z, k_interp.u[i][:, 1:(s_star - stage)], w[(stage + 1):s_star], true, true)
638-
z .= z .* dt .+ cache.y₀.u[i]
640+
fᵢ₂_cache, k_interp.u[i][:, 1:(s_star - stage)], w[(stage + 1):s_star], true, true)
641+
z .= fᵢ₂_cache .* dt .+ cache.y₀.u[i]
639642

640-
return z
643+
return nothing
641644
end
642645
function sum_stages!(
643646
z::AbstractArray, cache::MIRKCache{iip, T, use_both, NoDiffCacheNeeded},
644647
w, i::Int, dt = cache.mesh_dt[i]) where {iip, T, use_both}
645-
(; stage, k_discrete, k_interp) = cache
648+
(; stage, k_discrete, k_interp, fᵢ₂_cache) = cache
646649
(; s_star) = cache.ITU
647650

648-
z .= zero(z)
649-
__maybe_matmul!(z, k_discrete[i][:, 1:stage], w[1:stage])
651+
fᵢ₂_cache .= zero(z)
652+
__maybe_matmul!(fᵢ₂_cache, k_discrete[i][:, 1:stage], w[1:stage])
650653
__maybe_matmul!(
651-
z, k_interp.u[i][:, 1:(s_star - stage)], w[(stage + 1):s_star], true, true)
652-
z .= z .* dt .+ cache.y₀.u[i]
654+
fᵢ₂_cache, k_interp.u[i][:, 1:(s_star - stage)], w[(stage + 1):s_star], true, true)
655+
z .= fᵢ₂_cache .* dt .+ cache.y₀.u[i]
653656

654-
return z
657+
return nothing
655658
end
656659

657660
@views function sum_stages!(z, z′, cache::MIRKCache{iip, T, use_both, DiffCacheNeeded}, w,

lib/BoundaryValueDiffEqMIRK/test/mirk_basic_tests.jl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,23 @@ end
381381
prob, MIRK4(), dt = 0.05, abstol = 1e-5, controller = error_control)
382382
end
383383
end
384+
385+
# https://github.com/SciML/BoundaryValueDiffEq.jl/issues/319
386+
@testitem "Test interpolant evaluation with big defect" setup=[MIRKConvergenceTests] begin
387+
function lotka!(du, u, p, t)
388+
x = u[1]
389+
y = u[2]
390+
du[1] = p[1] * x - p[2] * x * y
391+
du[2] = -p[3] * y + p[4] * x * y
392+
end
393+
394+
function bc!(resid, u, p, t)
395+
resid[1] = u(0.0)[1] - 1.0
396+
resid[2] = u(0.0)[2] - 2.0
397+
end
398+
bvp = BVProblem(lotka!, bc!, [1.0, 2.0], (0, 10), [7.5, 4.0, 8, 5])
399+
for order in (4, 5, 6)
400+
sol = solve(bvp, mirk_solver(Val(order)), dt = 0.01)
401+
@test SciMLBase.successful_retcode(sol)
402+
end
403+
end

0 commit comments

Comments
 (0)