|
70 | 70 | end |
71 | 71 |
|
72 | 72 | @inline function interpolant!( |
73 | | - z::AbstractArray, id, cache::MIRKCache, t, mesh, mesh_dt, T::Type{Val{0}} |
| 73 | + z::AbstractArray, id::MIRKInterpolation, cache::MIRKCache, t, mesh, mesh_dt, T::Type{Val{0}} |
74 | 74 | ) |
75 | 75 | i = interval(mesh, t) |
76 | 76 | dt = mesh_dt[i] |
@@ -199,342 +199,3 @@ end |
199 | 199 | end |
200 | 200 |
|
201 | 201 | @inline __build_interpolation(cache::MIRKCache, u::AbstractVector) = MIRKInterpolation(cache.mesh, u, cache) |
202 | | - |
203 | | -# Intermediate solution for evaluating boundary conditions |
204 | | -# basically simplified version of the interpolation for MIRK |
205 | | -function (s::EvalSol{C})(tval::Number) where {C <: MIRKCache} |
206 | | - (; t, u, cache) = s |
207 | | - (; alg, stage, k_discrete, M) = cache |
208 | | - # Quick handle for the case where tval is at the boundary |
209 | | - (tval == t[1]) && return first(u) |
210 | | - (tval == t[end]) && return last(u) |
211 | | - z = zero(last(u)) |
212 | | - has_control = !isnothing(cache.prob.f.f_prototype) |
213 | | - length_z = has_control ? length(cache.prob.f.f_prototype) : length(z) |
214 | | - ii = interval(t, tval) |
215 | | - dt = cache.mesh_dt[ii] |
216 | | - τ = (tval - t[ii]) / dt |
217 | | - w, _ = evalsol_interp_weights(τ, alg) |
218 | | - K = __needs_diffcache(alg.jac_alg) ? @view(k_discrete[ii].du[:, 1:stage]) : |
219 | | - @view(k_discrete[ii][:, 1:stage]) |
220 | | - __maybe_matmul!(z[1:length_z], K, @view(w[1:stage])) |
221 | | - |
222 | | - # control variable just use linear interpolation |
223 | | - if has_control |
224 | | - inc = τ / dt .* (u[ii + 1] .- u[ii]) |
225 | | - copyto!(z, (length_z + 1):M, inc, (length_z + 1):M) |
226 | | - end |
227 | | - |
228 | | - z .= z .* dt .+ u[ii] |
229 | | - |
230 | | - return z |
231 | | -end |
232 | | - |
233 | | -# Interpolate intermediate solution at multiple points |
234 | | -function (s::EvalSol{C})(tvals::AbstractArray{<:Number}) where {C <: MIRKCache} |
235 | | - (; t, u, cache) = s |
236 | | - (; alg, stage, k_discrete, mesh_dt, M) = cache |
237 | | - # Quick handle for the case where tval is at the boundary |
238 | | - zvals = [zero(last(u)) for _ in tvals] |
239 | | - has_control = !isnothing(cache.prob.f.f_prototype) |
240 | | - length_z = has_control ? length(cache.prob.f.f_prototype) : length(first(zvals)) |
241 | | - for (i, tval) in enumerate(tvals) |
242 | | - (tval == t[1]) && return first(u) |
243 | | - (tval == t[end]) && return last(u) |
244 | | - ii = interval(t, tval) |
245 | | - dt = mesh_dt[ii] |
246 | | - τ = (tval - t[ii]) / dt |
247 | | - w, _ = evalsol_interp_weights(τ, alg) |
248 | | - K = __needs_diffcache(alg.jac_alg) ? @view(k_discrete[ii].du[:, 1:stage]) : |
249 | | - @view(k_discrete[ii][:, 1:stage]) |
250 | | - __maybe_matmul!(zvals[i][1:length_z], K, @view(w[1:stage])) |
251 | | - |
252 | | - # control variable just use linear interpolation |
253 | | - if has_control |
254 | | - inc = τ / dt .* (u[ii + 1] .- u[ii]) |
255 | | - copyto!(zvals[i], (length_z + 1):M, inc, (length_z + 1):M) |
256 | | - end |
257 | | - zvals[i] .= zvals[i] .* dt .+ u[ii] |
258 | | - end |
259 | | - return zvals |
260 | | -end |
261 | | - |
262 | | -# Intermediate derivative solution for evaluating boundary conditions |
263 | | -function (s::EvalSol{C})(tval::Number, ::Type{Val{1}}) where {C <: MIRKCache} |
264 | | - (; t, u, cache) = s |
265 | | - (; alg, stage, k_discrete, mesh_dt) = cache |
266 | | - z′ = zeros(typeof(tval), 2) |
267 | | - ii = interval(t, tval) |
268 | | - dt = mesh_dt[ii] |
269 | | - τ = (tval - t[ii]) / dt |
270 | | - _, w′ = interp_weights(τ, alg) |
271 | | - __maybe_matmul!(z′, @view(k_discrete[ii].du[:, 1:stage]), @view(w′[1:stage])) |
272 | | - return z′ |
273 | | -end |
274 | | - |
275 | | -""" |
276 | | -Construct n root-finding problems and solve them to find the critical points with continuous derivative polynomials |
277 | | -""" |
278 | | -function __construct_then_solve_root_problem(sol::EvalSol{C}, tspan::Tuple) where { |
279 | | - C <: |
280 | | - MIRKCache, |
281 | | - } |
282 | | - (; alg) = sol.cache |
283 | | - n = first(size(sol)) |
284 | | - nlprobs = Vector{SciMLBase.NonlinearProblem}(undef, n) |
285 | | - nlsols = Vector{SciMLBase.NonlinearSolution}(undef, length(nlprobs)) |
286 | | - nlsolve_alg = __FastShortcutNonlinearPolyalg(eltype(sol.cache)) |
287 | | - for i in 1:n |
288 | | - f = @closure (t, p) -> sol(t, Val{1})[i] |
289 | | - nlprob = NonlinearProblem(f, sol.cache.prob.u0[i], tspan) |
290 | | - nlsols[i] = solve(nlprob, nlsolve_alg) |
291 | | - end |
292 | | - return nlsols |
293 | | -end |
294 | | - |
295 | | -# It turns out the critical points can't cover all possible maximum/minimum values |
296 | | -# especially when the solution are monotonic, we still need to compare the extremes with |
297 | | -# value at critical points to find the maximum/minimum |
298 | | - |
299 | | -""" |
300 | | - maxsol(sol::EvalSol, tspan::Tuple) |
301 | | -
|
302 | | -Find the maximum of the solution over the time span `tspan`. |
303 | | -""" |
304 | | -function maxsol(sol::EvalSol{C}, tspan::Tuple) where {C <: MIRKCache} |
305 | | - nlsols = __construct_then_solve_root_problem(sol, tspan) |
306 | | - tvals = map(nlsol -> (SciMLBase.successful_retcode(nlsol); return nlsol.u), nlsols) |
307 | | - u = sol(tvals) |
308 | | - return max(maximum(sol), maximum(Iterators.flatten(u))) |
309 | | -end |
310 | | - |
311 | | -""" |
312 | | - minsol(sol::EvalSol, tspan::Tuple) |
313 | | -
|
314 | | -Find the minimum of the solution over the time span `tspan`. |
315 | | -""" |
316 | | -function minsol(sol::EvalSol{C}, tspan::Tuple) where {C <: MIRKCache} |
317 | | - nlsols = __construct_then_solve_root_problem(sol, tspan) |
318 | | - tvals = map(nlsol -> (SciMLBase.successful_retcode(nlsol); return nlsol.u), nlsols) |
319 | | - u = sol(tvals) |
320 | | - return min(minimum(sol), minimum(Iterators.flatten(u))) |
321 | | -end |
322 | | - |
323 | | -@inline function evalsol_interp_weights(τ::T, ::MIRK2) where {T} |
324 | | - w = [0, τ * (1 - τ / 2), τ^2 / 2] |
325 | | - |
326 | | - # Derivative polynomials. |
327 | | - |
328 | | - wp = [0, 1 - τ, τ] |
329 | | - return T.(w), T.(wp) |
330 | | -end |
331 | | -@inline function evalsol_interp_weights(τ::T, ::MIRK3) where {T} |
332 | | - w = [ |
333 | | - τ / 4.0 * (2.0 * τ^2 - 5.0 * τ + 4.0), -3.0 / 4.0 * τ^2 * (2.0 * τ - 3.0), τ^2 * |
334 | | - ( |
335 | | - τ - |
336 | | - 1.0 |
337 | | - ), |
338 | | - ] |
339 | | - |
340 | | - # Derivative polynomials. |
341 | | - |
342 | | - wp = [ |
343 | | - 3.0 / 2.0 * (τ - 2.0 / 3.0) * (τ - 1.0), |
344 | | - -9.0 / 2.0 * τ * (τ - 1.0), 3.0 * τ * (τ - 2.0 / 3.0), |
345 | | - ] |
346 | | - return T.(w), T.(wp) |
347 | | -end |
348 | | -@inline function evalsol_interp_weights(τ::T, ::MIRK4) where {T} |
349 | | - t2 = τ * τ |
350 | | - tm1 = τ - 1.0 |
351 | | - t4m3 = τ * 4.0 - 3.0 |
352 | | - t2m1 = τ * 2.0 - 1.0 |
353 | | - |
354 | | - w = [ |
355 | | - -τ * (2.0 * τ - 3.0) * (2.0 * t2 - 3.0 * τ + 2.0) / 6.0, |
356 | | - t2 * (12.0 * t2 - 20.0 * τ + 9.0) / 6.0, |
357 | | - 2.0 * t2 * (6.0 * t2 - 14.0 * τ + 9.0) / 3.0, -16.0 * t2 * tm1 * tm1 / 3.0, |
358 | | - ] |
359 | | - |
360 | | - # Derivative polynomials |
361 | | - |
362 | | - wp = [ |
363 | | - -tm1 * t4m3 * t2m1 / 3.0, τ * t2m1 * t4m3, |
364 | | - 4.0 * τ * t4m3 * tm1, -32.0 * τ * t2m1 * tm1 / 3.0, |
365 | | - ] |
366 | | - return T.(w), T.(wp) |
367 | | -end |
368 | | -@inline function evalsol_interp_weights(τ::T, ::MIRK5) where {T} |
369 | | - w = [ |
370 | | - τ * (22464.0 - 83910.0 * τ + 143041.0 * τ^2 - 113808.0 * τ^3 + 33256.0 * τ^4) / |
371 | | - 22464.0, |
372 | | - τ^2 * (-2418.0 + 12303.0 * τ - 19512.0 * τ^2 + 10904.0 * τ^3) / 3360.0, |
373 | | - -8 / 81 * τ^2 * (-78.0 + 209.0 * τ - 204.0 * τ^2 + 8.0 * τ^3), |
374 | | - -25 / 1134 * τ^2 * (-390.0 + 1045.0 * τ - 1020.0 * τ^2 + 328.0 * τ^3), |
375 | | - -25 / 5184 * τ^2 * (390.0 + 255.0 * τ - 1680.0 * τ^2 + 2072.0 * τ^3), |
376 | | - 279841 / 168480 * τ^2 * (-6.0 + 21.0 * τ - 24.0 * τ^2 + 8.0 * τ^3), |
377 | | - ] |
378 | | - |
379 | | - # Derivative polynomials |
380 | | - |
381 | | - wp = [ |
382 | | - 1.0 - 13985 // 1872 * τ + 143041 // 7488 * τ^2 - 2371 // 117 * τ^3 + |
383 | | - 20785 // 2808 * τ^4, |
384 | | - -403 // 280 * τ + 12303 // 1120 * τ^2 - 813 // 35 * τ^3 + 1363 // 84 * τ^4, |
385 | | - 416 // 27 * τ - 1672 // 27 * τ^2 + 2176 // 27 * τ^3 - 320 // 81 * τ^4, |
386 | | - 3250 // 189 * τ - 26125 // 378 * τ^2 + 17000 // 189 * τ^3 - 20500 // 567 * τ^4, |
387 | | - -1625 // 432 * τ - 2125 // 576 * τ^2 + 875 // 27 * τ^3 - 32375 // 648 * τ^4, |
388 | | - -279841 // 14040 * τ + 1958887 // 18720 * τ^2 - 279841 // 1755 * τ^3 + |
389 | | - 279841 // 4212 * τ^4, |
390 | | - ] |
391 | | - return T.(w), T.(wp) |
392 | | -end |
393 | | -@inline function evalsol_interp_weights(τ::T, ::MIRK6) where {T} |
394 | | - w = [ |
395 | | - τ - 28607 // 7434 * τ^2 - 166210 // 33453 * τ^3 + 334780 // 11151 * τ^4 - |
396 | | - 1911296 // 55755 * τ^5 + 406528 // 33453 * τ^6, |
397 | | - 777 // 590 * τ^2 - 2534158 // 234171 * τ^3 + 2088580 // 78057 * τ^4 - |
398 | | - 10479104 // 390285 * τ^5 + 11328512 // 1170855 * τ^6, |
399 | | - -1008 // 59 * τ^2 + 222176 // 1593 * τ^3 - 180032 // 531 * τ^4 + |
400 | | - 876544 // 2655 * τ^5 - 180224 // 1593 * τ^6, |
401 | | - -1008 // 59 * τ^2 + 222176 // 1593 * τ^3 - 180032 // 531 * τ^4 + |
402 | | - 876544 // 2655 * τ^5 - 180224 // 1593 * τ^6, |
403 | | - -378 // 59 * τ^2 + 27772 // 531 * τ^3 - 22504 // 177 * τ^4 + 109568 // 885 * τ^5 - |
404 | | - 22528 // 531 * τ^6, |
405 | | - -95232 // 413 * τ^2 + 62384128 // 33453 * τ^3 - 49429504 // 11151 * τ^4 + |
406 | | - 46759936 // 11151 * τ^5 - 46661632 // 33453 * τ^6, |
407 | | - 896 // 5 * τ^2 - 4352 // 3 * τ^3 + 3456 * τ^4 - 16384 // 5 * τ^5 + |
408 | | - 16384 // 15 * τ^6, |
409 | | - 50176 // 531 * τ^2 - 179554304 // 234171 * τ^3 + 143363072 // 78057 * τ^4 - |
410 | | - 136675328 // 78057 * τ^5 + 137363456 // 234171 * τ^6, |
411 | | - 16384 // 441 * τ^3 - 16384 // 147 * τ^4 + 16384 // 147 * τ^5 - 16384 // 441 * τ^6, |
412 | | - ] |
413 | | - |
414 | | - # Derivative polynomials. |
415 | | - |
416 | | - wp = [ |
417 | | - 1 - 28607 // 3717 * τ - 166210 // 11151 * τ^2 + 1339120 // 11151 * τ^3 - |
418 | | - 1911296 // 11151 * τ^4 + 813056 // 11151 * τ^5, |
419 | | - 777 // 295 * τ - 2534158 // 78057 * τ^2 + 8354320 // 78057 * τ^3 - |
420 | | - 10479104 // 78057 * τ^4 + 22657024 // 390285 * τ^5, |
421 | | - -2016 // 59 * τ + 222176 // 531 * τ^2 - 720128 // 531 * τ^3 + 876544 // 531 * τ^4 - |
422 | | - 360448 // 531 * τ^5, |
423 | | - -2016 // 59 * τ + 222176 // 531 * τ^2 - 720128 // 531 * τ^3 + 876544 // 531 * τ^4 - |
424 | | - 360448 // 531 * τ^5, |
425 | | - -756 // 59 * τ + 27772 // 177 * τ^2 - 90016 // 177 * τ^3 + 109568 // 177 * τ^4 - |
426 | | - 45056 // 177 * τ^5, |
427 | | - -190464 // 413 * τ + 62384128 // 11151 * τ^2 - 197718016 // 11151 * τ^3 + |
428 | | - 233799680 // 11151 * τ^4 - 93323264 // 11151 * τ^5, |
429 | | - 1792 // 5 * τ - 4352 * τ^2 + 13824 * τ^3 - 16384 * τ^4 + 32768 // 5 * τ^5, |
430 | | - 100352 // 531 * τ - 179554304 // 78057 * τ^2 + 573452288 // 78057 * τ^3 - |
431 | | - 683376640 // 78057 * τ^4 + 274726912 // 78057 * τ^5, |
432 | | - 16384 // 147 * τ^2 - 65536 // 147 * τ^3 + 81920 // 147 * τ^4 - 32768 // 147 * τ^5, |
433 | | - ] |
434 | | - return T.(w), T.(wp) |
435 | | -end |
436 | | - |
437 | | -@inline function evalsol_interp_weights(τ::T, ::MIRK6I) where {T} |
438 | | - w = [ |
439 | | - -(12233 + 1450 * sqrt(7)) * |
440 | | - ( |
441 | | - 800086000 * τ^5 + 63579600 * sqrt(7) * τ^4 - 2936650584 * τ^4 + 4235152620 * τ^3 - |
442 | | - 201404565 * sqrt(7) * τ^3 + 232506630 * sqrt(7) * τ^2 - 3033109390 * τ^2 + |
443 | | - 1116511695 * τ - 116253315 * sqrt(7) * τ + 22707000 * sqrt(7) - 191568780 |
444 | | - ) * |
445 | | - τ / 2112984835740, |
446 | | - -(-10799 + 650 * sqrt(7)) * |
447 | | - ( |
448 | | - 24962000 * τ^4 + 473200 * sqrt(7) * τ^3 - 67024328 * τ^3 - 751855 * sqrt(7) * τ^2 + |
449 | | - 66629600 * τ^2 - 29507250 * τ + |
450 | | - 236210 * sqrt(7) * τ + |
451 | | - 5080365 + |
452 | | - 50895 * sqrt(7) |
453 | | - ) * |
454 | | - τ^2 / 29551834260, |
455 | | - 7 / 1274940 * |
456 | | - (259 + 50 * sqrt(7)) * |
457 | | - ( |
458 | | - 14000 * τ^4 - 48216 * τ^3 + 1200 * sqrt(7) * τ^3 - 3555 * sqrt(7) * τ^2 + |
459 | | - 62790 * τ^2 + |
460 | | - 3610 * sqrt(7) * τ - 37450 * τ + 9135 - 1305 * sqrt(7) |
461 | | - ) * |
462 | | - τ^2, |
463 | | - 7 / 1274940 * |
464 | | - (259 + 50 * sqrt(7)) * |
465 | | - ( |
466 | | - 14000 * τ^4 - 48216 * τ^3 + 1200 * sqrt(7) * τ^3 - 3555 * sqrt(7) * τ^2 + |
467 | | - 62790 * τ^2 + |
468 | | - 3610 * sqrt(7) * τ - 37450 * τ + 9135 - 1305 * sqrt(7) |
469 | | - ) * |
470 | | - τ^2, |
471 | | - 16 / 2231145 * |
472 | | - (259 + 50 * sqrt(7)) * |
473 | | - ( |
474 | | - 14000 * τ^4 - 48216 * τ^3 + 1200 * sqrt(7) * τ^3 - 3555 * sqrt(7) * τ^2 + |
475 | | - 62790 * τ^2 + |
476 | | - 3610 * sqrt(7) * τ - 37450 * τ + 9135 - 1305 * sqrt(7) |
477 | | - ) * |
478 | | - τ^2, |
479 | | - 4 / 1227278493 * |
480 | | - (740 * sqrt(7) - 6083) * |
481 | | - (1561000 * τ^2 - 2461284 * τ - 109520 * sqrt(7) * τ + 979272 + 86913 * sqrt(7)) * |
482 | | - (τ - 1)^2 * |
483 | | - τ^2, |
484 | | - -49 / 63747 * sqrt(7) * (20000 * τ^2 - 20000 * τ + 3393) * (τ - 1)^2 * τ^2, |
485 | | - -1250000000 / 889206903 * (28 * τ^2 - 28 * τ + 9) * (τ - 1)^2 * τ^2, |
486 | | - ] |
487 | | - |
488 | | - # Derivative polynomials. |
489 | | - |
490 | | - wp = [ |
491 | | - (1450 * sqrt(7) + 12233) * |
492 | | - (14 * τ - 7 + sqrt(7)) * |
493 | | - (τ - 1) * |
494 | | - (-400043 * τ + 75481 + 2083 * sqrt(7)) * |
495 | | - (100 * τ - 87) * |
496 | | - (2 * τ - 1) / 493029795006, |
497 | | - -(650 * sqrt(7) - 10799) * |
498 | | - (14 * τ - 7 + sqrt(7)) * |
499 | | - (37443 * τ - 13762 - 2083 * sqrt(7)) * |
500 | | - (100 * τ - 87) * |
501 | | - (2 * τ - 1) * |
502 | | - τ / 20686283982, |
503 | | - 7 / 42498 * |
504 | | - (259 + 50 * sqrt(7)) * |
505 | | - (14 * τ - 7 + sqrt(7)) * |
506 | | - (τ - 1) * |
507 | | - (100 * τ - 87) * |
508 | | - (2 * τ - 1) * |
509 | | - τ, |
510 | | - 7 / 42498 * |
511 | | - (259 + 50 * sqrt(7)) * |
512 | | - (14 * τ - 7 + sqrt(7)) * |
513 | | - (τ - 1) * |
514 | | - (100 * τ - 87) * |
515 | | - (2 * τ - 1) * |
516 | | - τ, |
517 | | - 32 / 148743 * |
518 | | - (259 + 50 * sqrt(7)) * |
519 | | - (14 * τ - 7 + sqrt(7)) * |
520 | | - (τ - 1) * |
521 | | - (100 * τ - 87) * |
522 | | - (2 * τ - 1) * |
523 | | - τ, |
524 | | - 4 / 1227278493 * |
525 | | - (740 * sqrt(7) - 6083) * |
526 | | - (14 * τ - 7 + sqrt(7)) * |
527 | | - (τ - 1) * |
528 | | - (100 * τ - 87) * |
529 | | - (6690 * τ - 4085 - 869 * sqrt(7)) * |
530 | | - τ, |
531 | | - -98 / 21249 * sqrt(7) * (τ - 1) * (100 * τ - 13) * (100 * τ - 87) * (2 * τ - 1) * τ, |
532 | | - -1250000000 / 2074816107 * |
533 | | - (14 * τ - 7 + sqrt(7)) * |
534 | | - (τ - 1) * |
535 | | - (14 * τ - 7 - sqrt(7)) * |
536 | | - (2 * τ - 1) * |
537 | | - τ, |
538 | | - ] |
539 | | - return T.(w), T.(wp) |
540 | | -end |
0 commit comments